diff --git a/.gitignore b/.gitignore index 558848c08..37c54960f 100755 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,7 @@ - +x64 *.o - - - - - agents/iguana.exe +Debug/* iguana/pnacl/Release/iguana_unstripped.pexe @@ -37,3 +33,220 @@ agents/* iguana/confs/BTC_hdrs.txt + +deprecated/.DS_Store + +.DS_Store + + +iguana/help/.tmpmarker + +iguana/genesis/.tmpmarker + +iguana/help.json + +iguana/autoAPI.md + +iguana/basilisk.o-2ad8cb38 +======= +*.pbxproj + +iguana/tmp/.tmpmarker + +iguana/SVM/rawfeatures/.tmpmarker + +iguana/DB/.tmpmarker + +iguana/DB/TRANSACTIONS/.tmpmarker + +iguana/DB/purgeable/.tmpmarker + +iguana/DB/purgeable/BTCD/.tmpmarker + +iguana/DB/purgeable/BTC/.tmpmarker + +iguana/DB/ECB/.tmpmarker + +iguana/genesis/.tmpmarker + +iguana/help/.tmpmarker + +iguana/SVM/.tmpmarker + +iguana/SVM/models/.tmpmarker + +SuperNET.xcodeproj/xcuserdata/mac.xcuserdatad/xcschemes/xcschememanagement.plist + +SuperNET.xcodeproj/xcuserdata/mac.xcuserdatad/xcschemes/SuperNET.xcscheme + +iguana/DB/BTC/.tmpmarker + +*.vouts + +iguana/DB/BTC/vouts/.tmpmarker + +iguana/DB/BTC/accounts/.tmpmarker + +iguana/DB/BTC/spends/.tmpmarker + +iguana/DB/BTC/validated/.tmpmarker + +iguana/DB/KMD/.tmpmarker + +iguana/DB/KMD/accounts/.tmpmarker + +iguana/DB/KMD/spends/.tmpmarker + +iguana/DB/KMD/validated/.tmpmarker + +iguana/DB/KMD/vouts/.tmpmarker + +iguana/DB/purgeable/KMD/.tmpmarker + +iguana/DB/ro/.tmpmarker + +iguana/DB/ro/BTC/.tmpmarker + +iguana/DB/ro/KMD/.tmpmarker + +iguana/confs/682c279f7b01b96aee50f11b327bf6c0a3d3481a23a9a265f0796e9bb3765b24 + +iguana/confs/682c279f7b01b96aee50f11b327bf6c0a3d3481a23a9a265f0796e9bb3765b24.old + +iguana/confs/83cb074c13289a91a0cd50a8e6932b2237d1533ec1cbff56ab3d9b1d37f8df35 + +iguana/confs/83cb074c13289a91a0cd50a8e6932b2237d1533ec1cbff56ab3d9b1d37f8df35.old + +iguana/tmp/BTC/.tmpmarker + +iguana/tmp/BTC/0/.tmpmarker + +iguana/tmp/BTC/0/0/.tmpmarker + +iguana/tmp/BTC/peers.txt + +iguana/tmp/BTC/RT/.tmpmarker + +iguana/tmp/KMD/.tmpmarker + +iguana/tmp/KMD/0/.tmpmarker + +iguana/tmp/KMD/0/0/.tmpmarker + +iguana/tmp/KMD/peers.txt + +iguana/tmp/KMD/RT/.tmpmarker + +*.xcworkspacedata + +*.xcuserstate + +includes/iguana_apideclares copy.h + +iguana/iguana_tx.o-4b5de8fe + +iguana/confs/c6faccf6b625bbb826f47b77c3274e985db7b0a47d435f32bea2f7f3724cdd17 + +iguana/confs/c6faccf6b625bbb826f47b77c3274e985db7b0a47d435f32bea2f7f3724cdd17.old + +iguana/marketmaker + +iguana/secp256k1.o-501dfbfe + +iguana/confs/cc577d22ca76351d495f147b470103392b5f2ab0948e45608623a7d9728e2c6f + +iguana/confs/cc577d22ca76351d495f147b470103392b5f2ab0948e45608623a7d9728e2c6f.old + +iguana/DB/DEX.log + +iguana/iguana_notary.o-54f98cc3 + +iguana/basilisk.o-2ad8cb38 +iguana/pangea_hand.o-02d25ec3 + +iguana/confs/4dfa301d0adf61f0ec08e4d4cb4444f4fc377f45f5d6b1da0814033920d72353 + +iguana/help.json + +iguana/index7778.html + + +iguana/DB/KMD/utxo.dat + +iguana/unparsed.txt + +iguana/unparsed.txt + +iguana/unparsed.txt + +iguana/DB/SWAPS/.tmpmarker + +iguana/DB/SWAPS/list + +iguana/DB/SWAPS/15974209-4014252807 + +iguana/iguana777.o-0cc60f50 + +iguana/DB/SWAPS/667293271-3414303895 + +iguana/DB/SWAPS/667293271-3414303895.swap + +iguana/DB/SWAPS/548227681-1452262678.swap + +iguana/DB/SWAPS/548227681-1452262678 + +*.bobdeposit + +*.bobpayment + +*.bobreclaim + +*.bobrefund + +*.swap + +iguana/DB/SWAPS/1268007736-526212866 + +iguana/DB/SWAPS/3111936786-3185288772 + +iguana/DB/SWAPS/3368214189-2405641584 + +iguana/DB/SWAPS/1133671270-1840176506 + +iguana/DB/SWAPS/467927158-3437055573 + +iguana/DB/SWAPS/270159951-1269722638 + +iguana/DB/SWAPS/244991424-1008712592 + +iguana/confs/1cc0270abba7f4463a3dcb9908b9d875691a6773fe3cc1b4302233ed76665300 + +iguana/autoAPI.md + +iguana/confs/5228bcea7ae2515a29c3844673de6ee2acba53bf45724744a00ff4306f192912 + +iguana/confs/630929d976025fafde221c7358eb5805f4359bad3c6b8bd50ad3f6e0a9b5ce78 + +iguana/confs/5f3283a017c31e52443d61cb43944e2157f7c03eb12d701ebf4a35a695688e1f + +iguana/marketmaker.dSYM/Contents/Resources/DWARF/marketmaker + +iguana/marketmaker.dSYM/Contents/Info.plist + +iguana/confs/97f18454bb61e9eb7a827cfbefe42fbf7ae2832dc74c4812bdaef8bcf5c10474 + +iguana/DB/PRICES/.tmpmarker + +iguana/DB/KMD/0/.tmpmarker + +*.swp + +iguana/myipaddr + +iguana/DB/UNSPENTS/.tmpmarker + +*.RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg + +iguana/DB/instantdex_RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg_append.json + +iguana/DB/instantdex_RQ4z6KrMZeEnCSCsChv1ZoR9ExQitHjbpg.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..20c9e805a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C++ Launch (Windows)", + "type": "cppvsdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceRoot}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceRoot}", + "environment": [], + "externalConsole": false + }, + { + "name": "C++ Attach (Windows)", + "type": "cppvsdbg", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/MyTemplate.vstemplate b/MyTemplate.vstemplate new file mode 100644 index 000000000..7dd0fb0dc --- /dev/null +++ b/MyTemplate.vstemplate @@ -0,0 +1,22 @@ + + + iguana_template + <No description available> + VC + + + 1000 + true + iguana_template + true + Enabled + true + __TemplateIcon.ico + + + + ConsoleApplication3.vcxproj.filters + ReadMe.txt + + + \ No newline at end of file diff --git a/OSlibs/android/lib/libcrypto.so b/OSlibs/android/lib/libcrypto.so deleted file mode 100755 index 8fa44cee8..000000000 Binary files a/OSlibs/android/lib/libcrypto.so and /dev/null differ diff --git a/OSlibs/android/lib/libcurl.a b/OSlibs/android/lib/libcurl.a deleted file mode 100755 index bbc4fa4f0..000000000 Binary files a/OSlibs/android/lib/libcurl.a and /dev/null differ diff --git a/OSlibs/android/lib/libssl.so b/OSlibs/android/lib/libssl.so deleted file mode 100755 index 8c270c350..000000000 Binary files a/OSlibs/android/lib/libssl.so and /dev/null differ diff --git a/OSlibs/ios/lib/libcrypto.a b/OSlibs/ios/lib/libcrypto.a deleted file mode 100644 index 3e9849e14..000000000 Binary files a/OSlibs/ios/lib/libcrypto.a and /dev/null differ diff --git a/OSlibs/ios/lib/libcurl.a b/OSlibs/ios/lib/libcurl.a deleted file mode 100644 index 07109972f..000000000 Binary files a/OSlibs/ios/lib/libcurl.a and /dev/null differ diff --git a/OSlibs/ios/lib/libssl.a b/OSlibs/ios/lib/libssl.a deleted file mode 100644 index 646b0ad20..000000000 Binary files a/OSlibs/ios/lib/libssl.a and /dev/null differ diff --git a/OSlibs/osx/libcrypto.a b/OSlibs/osx/libcrypto.a deleted file mode 100644 index 4d3f97915..000000000 Binary files a/OSlibs/osx/libcrypto.a and /dev/null differ diff --git a/OSlibs/osx/libcurl.a b/OSlibs/osx/libcurl.a deleted file mode 100644 index 41192abb7..000000000 Binary files a/OSlibs/osx/libcurl.a and /dev/null differ diff --git a/OSlibs/osx/libgmp.a b/OSlibs/osx/libgmp.a deleted file mode 100644 index 3ed321825..000000000 Binary files a/OSlibs/osx/libgmp.a and /dev/null differ diff --git a/OSlibs/osx/libsecp256k1.a b/OSlibs/osx/libsecp256k1.a deleted file mode 100644 index 5b2034911..000000000 Binary files a/OSlibs/osx/libsecp256k1.a and /dev/null differ diff --git a/OSlibs/osx/libssl.a b/OSlibs/osx/libssl.a deleted file mode 100644 index badeb5f21..000000000 Binary files a/OSlibs/osx/libssl.a and /dev/null differ diff --git a/OSlibs/win/libcrypto.a b/OSlibs/win/libcrypto.a deleted file mode 100755 index 62f2adfc8..000000000 Binary files a/OSlibs/win/libcrypto.a and /dev/null differ diff --git a/OSlibs/win/libcurl.a b/OSlibs/win/libcurl.a deleted file mode 100755 index 768133dde..000000000 Binary files a/OSlibs/win/libcurl.a and /dev/null differ diff --git a/OSlibs/win/libcurl.exp b/OSlibs/win/libcurl.exp new file mode 100644 index 000000000..a2b9da989 Binary files /dev/null and b/OSlibs/win/libcurl.exp differ diff --git a/OSlibs/win/libcurl.lib b/OSlibs/win/libcurl.lib new file mode 100644 index 000000000..c2b00f3c8 Binary files /dev/null and b/OSlibs/win/libcurl.lib differ diff --git a/OSlibs/win/libcurldll.a b/OSlibs/win/libcurldll.a deleted file mode 100755 index 15cf86362..000000000 Binary files a/OSlibs/win/libcurldll.a and /dev/null differ diff --git a/OSlibs/win/libpthreadGC2.a b/OSlibs/win/libpthreadGC2.a deleted file mode 100755 index ff267089b..000000000 Binary files a/OSlibs/win/libpthreadGC2.a and /dev/null differ diff --git a/OSlibs/win/libpthreadGC2_64.a b/OSlibs/win/libpthreadGC2_64.a deleted file mode 100755 index 430162364..000000000 Binary files a/OSlibs/win/libpthreadGC2_64.a and /dev/null differ diff --git a/OSlibs/win/libsecp256k1.a b/OSlibs/win/libsecp256k1.a deleted file mode 100644 index 778d5d980..000000000 Binary files a/OSlibs/win/libsecp256k1.a and /dev/null differ diff --git a/OSlibs/win/libssl.a b/OSlibs/win/libssl.a deleted file mode 100755 index ac3e692a7..000000000 Binary files a/OSlibs/win/libssl.a and /dev/null differ diff --git a/OSlibs/win/mingw.h b/OSlibs/win/mingw.h index 1a80c56dc..2c35aa78c 100755 --- a/OSlibs/win/mingw.h +++ b/OSlibs/win/mingw.h @@ -1,12 +1,17 @@ #ifndef MINGW_H #define MINGW_H +#define ssize_t __int32 #include #define _USE_W32_SOCKETS 1 +#define WIN32_LEAN_AND_MEAN +#include #include +#define PTW32_STATIC_LIB #include "pthread.h" +#ifndef NATIVE_WINDOWS #define ENOTCONN WSAENOTCONN #define EWOULDBLOCK WSAEWOULDBLOCK #define ENOBUFS WSAENOBUFS @@ -18,25 +23,67 @@ #define EISCONN WSAEISCONN #define ECONNREFUSED WSAECONNREFUSED #define EHOSTUNREACH WSAEHOSTUNREACH - +#endif /* winsock doesn't feature poll(), so there is a version implemented * in terms of select() in mingw.c. The following definitions * are copied from linux man pages. A poll() macro is defined to * call the version in mingw.c. */ -#define POLLIN 0x0001 /* There is data to read */ + #define POLLPRI 0x0002 /* There is urgent data to read */ +#if defined(_M_X64) + /* + * when we are using WSAPoll() with window's struct pollfd struct + * we need to update the value for POLLIN and POLLOUT according to window's + * WSAPoll() return values + * @author - fadedreamz@gmail.com + */ +//TODO: need to update other values to match with WSAPoll() function +#define POLLRDNORM 0x0100 +#define POLLRDBAND 0x0200 +#define POLLWRNORM 0x0010 +#define POLLIN POLLRDNORM | POLLRDBAND /* There is data to read */ +#define POLLOUT POLLWRNORM /* Writing now will not block */ +#else +#define POLLIN 0x0001 /* There is data to read */ #define POLLOUT 0x0004 /* Writing now will not block */ +#endif #define POLLERR 0x0008 /* Error condition */ #define POLLHUP 0x0010 /* Hung up */ #define POLLNVAL 0x0020 /* Invalid request: fd not open */ -struct pollfd { - SOCKET fd; /* file descriptor */ - short events; /* requested events */ - short revents; /* returned events */ -}; + + /** + * we want to use mingw provided pollfd if and only if we are compiling this + * in windows 32bit but exclude it when we are compiling it in win 64 + * + * @author - fadedreamz@gmail.com + * @remarks - #if (defined(_M_X64) || defined(__amd64__)) && defined(WIN32) + * is equivalent to #if defined(_M_X64) as _M_X64 is defined for MSVC only + */ + + +// [Decker] pollfs is already defined in winsock2.h + +//#if !defined(_M_X64) +//struct pollfd { + //SOCKET fd; /* file descriptor */ + //short events; /* requested events */ + //short revents; /* returned events */ +//}; +//#endif + + +#if defined(_M_X64) +/* +* we want to use the window's poll function if poll() is invoked in win64 +* as we are using window's pollfd struct when we are using x64 +* @author - fadedreamz@gmail.com +*/ +#define poll(x, y, z) WSAPoll(x, y, z) +#else #define poll(x, y, z) win32_poll(x, y, z) +#endif /* These wrappers do nothing special except set the global errno variable if * an error occurs (winsock doesn't do this by default). They set errno diff --git a/OSlibs/win/nanomsg.lib b/OSlibs/win/nanomsg.lib new file mode 100644 index 000000000..f0fdac6fb Binary files /dev/null and b/OSlibs/win/nanomsg.lib differ diff --git a/OSlibs/win/pthreadGC2.dll b/OSlibs/win/pthreadGC2.dll deleted file mode 100755 index 67b9289df..000000000 Binary files a/OSlibs/win/pthreadGC2.dll and /dev/null differ diff --git a/OSlibs/win/pthreadGC2_64.dll b/OSlibs/win/pthreadGC2_64.dll deleted file mode 100755 index 841d4a216..000000000 Binary files a/OSlibs/win/pthreadGC2_64.dll and /dev/null differ diff --git a/OSlibs/win/release/nanomsg.lib b/OSlibs/win/release/nanomsg.lib new file mode 100644 index 000000000..082e2cf03 Binary files /dev/null and b/OSlibs/win/release/nanomsg.lib differ diff --git a/OSlibs/win/release/pthreadVC2.lib b/OSlibs/win/release/pthreadVC2.lib new file mode 100644 index 000000000..d793e7144 Binary files /dev/null and b/OSlibs/win/release/pthreadVC2.lib differ diff --git a/OSlibs/win/x64/libcurl.lib b/OSlibs/win/x64/libcurl.lib new file mode 100644 index 000000000..92f23798c Binary files /dev/null and b/OSlibs/win/x64/libcurl.lib differ diff --git a/OSlibs/win/x64/libpthreadGC2.a b/OSlibs/win/x64/libpthreadGC2.a deleted file mode 100644 index 96f31306b..000000000 Binary files a/OSlibs/win/x64/libpthreadGC2.a and /dev/null differ diff --git a/OSlibs/win/x64/nanomsg.lib b/OSlibs/win/x64/nanomsg.lib new file mode 100644 index 000000000..9e15cde27 Binary files /dev/null and b/OSlibs/win/x64/nanomsg.lib differ diff --git a/OSlibs/win/x64/release/libcurl.exp b/OSlibs/win/x64/release/libcurl.exp new file mode 100644 index 000000000..fc2bcb28c Binary files /dev/null and b/OSlibs/win/x64/release/libcurl.exp differ diff --git a/OSlibs/win/x64/release/libcurl.lib b/OSlibs/win/x64/release/libcurl.lib new file mode 100644 index 000000000..92f23798c Binary files /dev/null and b/OSlibs/win/x64/release/libcurl.lib differ diff --git a/OSlibs/win/x64/release/nanomsg.lib b/OSlibs/win/x64/release/nanomsg.lib new file mode 100644 index 000000000..0a9a4a694 Binary files /dev/null and b/OSlibs/win/x64/release/nanomsg.lib differ diff --git a/README.md b/README.md index 98dda7232..57e2376e8 100755 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -#SuperNET Client "iguana" +# SuperNET Client "iguana" OS | Build Status -------------|------ -Unix (Ubuntu 14.04) | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=Unix-jl777)](https://jenkinsmaster.sprnt.pw/job/Unix-jl777) -Chrome | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=PNaCl-jl777)](https://jenkinsmaster.sprnt.pw/job/PNaCl-jl777/) -Android | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=Android)](https://jenkinsmaster.sprnt.pw/job/Android/) -iOS | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=iOS)](https://jenkinsmaster.sprnt.pw/job/iOS/) -Windows 32 Bit | [![Build Status](https://jenkinsmaster.sprnt.pw/job/Win32/badge/icon)](https://jenkinsmaster.sprnt.pw/job/Win32/) -Windows 64 Bit | [![Build Status](https://jenkinsmaster.sprnt.pw/job/Win64-jl777/badge/icon)](https://jenkinsmaster.sprnt.pw/job/Win64-jl777/) +Unix (Ubuntu 14.04) | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=iguana-unix-jl777-release-v0.1)](https://jenkinsmaster.sprnt.pw/job/iguana-unix-jl777-release-v0.1) +Chrome | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=iguana-pnacl-jl777-release-v0.1)](https://jenkinsmaster.sprnt.pw/job/iguana-pnacl-jl777-release-v0.1/) +Android | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=iguana-android-jl777-release-v0.1)](https://jenkinsmaster.sprnt.pw/job/iguana-android-jl777-release-v0.1/) +iOS | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=iguana-ios-jl777-release-v0.1)](https://jenkinsmaster.sprnt.pw/job/iguana-ios-jl777-release-v0.1/) +Windows 32 Bit | [![Build Status](https://jenkinsmaster.sprnt.pw/job/iguana-win32-jl777-release-v0.1/badge/icon)](https://jenkinsmaster.sprnt.pw/job/iguana-win32-jl777-release-v0.1/) +Windows 64 Bit | [![Build Status](https://jenkinsmaster.sprnt.pw/job/iguana-win64-jl777-release-v0.1/badge/icon)](https://jenkinsmaster.sprnt.pw/job/iguana-win64-jl777-release-v0.1/) docs.supernet.org | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=docs.supernet.org-updating)](https://jenkinsmaster.sprnt.pw/job/docs.supernet.org-updating/) --- @@ -22,12 +22,12 @@ iguana: most efficient bitcoin core implementation that can simultaneously be fu komodo: this is the top secret project I cant talk about publicly yet -> #TL;DR# -> -> ```sudo apt-get update; sudo apt-get install git build-essential; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix;``` -> -> The above one line gets SuperNET installed, built and launched for unix. -> +> # TL;DR +> +> ```sudo apt-get update; sudo apt-get install git libcurl4-openssl-dev build-essential libnanomsg-dev; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix;``` +> +> The above one line gets SuperNET installed, built and launched for unix. +> > After that ```./m_unix``` updates to latest. > *Continue below at "Running".* @@ -40,12 +40,14 @@ TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin MINGW := i586-mingw32 The above two definitions need to be changed to match the mingw install on your system. m_win32 and m_win64 just invokes the makefile in mingw32 and mingw64 -##For chrome app## +## For chrome app You need to make sure the nacl sdk is properly installed and you are able to build the examples. Now you will need to get the external libs, which can be built from scratch using naclports or there use the reference builds of libcurl.a and libz.a in the SuperNET/crypto777/pnacl_libs. You can just copy those over into $(NACL_SDK_ROOT)//lib/pnacl. +## For android +You have to build a native libnanomsg for android. This section is work in progress. Contact ca333@protonmail.ch for assistance on building latest iguana for android. -#ONETIME# +# ONETIME Now you are ready to build. I try to make the build process as simple as possible, so there are no `autoconf`, `autoreconf`, `configure`, `cmake`, `make`, to get properly installed and running and run, etc. You do need a C compiler, like gcc. @@ -80,12 +82,12 @@ To build just iguana, you can ```cd``` into SuperNET/iguana and do ```./m_unix`` ```./m_clean``` will remove the files created from the building -#RUNNING# +# RUNNING The native versions are command line applications: agents/iguana {JSON} The chrome app pexe requires that the chrome is launched with a command line parameter (tools/chrome.localhost) and then browse to *http://127.0.0.1:7777* to see the pexe -#SUPERUGLYGUI# +# SUPERUGLYGUI Once iguana is running, you can see the superuglyGUI at *http://127.0.0.1:7778/?method* by submitting API calls using the forms, you will see it go to some specific URL. You can also do a programmatic GET request to ```http://127.0.0.1:7778/api/``` @@ -103,14 +105,14 @@ Internally, all paths convert the request into a standard SuperNET JSON request. Another approach is to use the bitcoin RPC syntax via: curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"getinfo\",\"params\":[]}" the params:[] array is where the standard bitcoin parameters go, the only change that is needed is to specify the coin -alternatively {"agent":"SuperNET","method":"bitcoinrpc","coin":"BTCD"} will set the coin +alternatively {"agent":"SuperNET","method":"bitcoinrpc","coin":"BTCD"} will set the coin to use for bitcoin RPC calls. this will suffice in single coin environments curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana",\"method\":\"test\"}" curl --url "http://127.0.0.1:7778/iguana/test" -> html page with results curl --url "http://127.0.0.1:7778/api/iguana/test" -> just json text http://127.0.0.1:7778 -> superugly GUI -http://127.0.0.1:7778/iguana/test +http://127.0.0.1:7778/iguana/test http://127.0.0.1:7778/api/iguana/test postCall('{"agent":"iguana","method":"test"}'} iguana_JSON("{\"agent\":\"iguana",\"method\":\"test\"}"); -> direct C function call @@ -124,7 +126,7 @@ iguana can be invoked with a command line argument. if it is a name of a file, i "exchanges" -> { "name":"", ... } "apikey", "apisecret", "userid", "tradepassword" these are as expected "pollgap" -> gap between each access to exchange for getting prices - + on OSX mksquashfs is not native, you will need to install fuse: https://osxfuse.github.io/ and a squashfs for mac: https://github.com/vasi/squashfuse ********** @@ -132,9 +134,9 @@ on OSX mksquashfs is not native, you will need to install fuse: https://osxfuse. A Note on Installation from pebwindkraft at bitco.in ======================= Though I had xcode installed, aclocal didn’t work. I installed homebrew, and then: -# brew install autoconf -# brew install automake -# brew install gmp +`brew install autoconf` +`brew install automake` +`brew install gmp` 2.) libsecp256 it complained, that libsecp256 was not there in includes, so I linked it. @@ -156,3 +158,100 @@ once jsoncmp is built, then ./test shows how to use it the idea is to issue a curl command into a /tmp/file and then use jsoncmp to verify the exact value of one or more fields. it will print to stdout JSON with "error" or "result" and to stderr if there is an error +##### ../agents/iguana notary +0.Have iguana installed at http://wiki.supernet.org/wiki/How_To_Install_Iguana_on_Linux +also install nanomsg: sudo apt-get install libnanomsg-dev +ports 7775 will be used + +cd Supernet/iguana --> + +../agents/iguana + +#In another SSH window: + +cd Supernet/iguana/coins --> + +./basilisk + +1. Create an iguana wallet with encryptwallet and importprivkey into both komodod and bitcoind using the KMDwif and BTCwif in the encryptwallet result + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"insert very secure password here\"}" + +2. Go to SuperNET/iguana/ + +pico wp + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"walletpassphrase\",\"params\":[\"same passphrase as above\", 9999999]}" + +#Save the file then run the following command: + +chmod +x wp + +#Run the file + +./wp + +#Get the btcpubkey key from the output and give it to James. + +3. create a text file SuperNET/iguana/myip.txt with just your ip address in it: + +pico myip.txt + +#Put your WAN IP of your node + +4. create a text file with the user home dir in it: + +pico userhome.txt +root + +5. make a copy of SuperNET/iguana/wp -> SuperNET/iguana/wp_7776 and change port 7778 to port 7776 + +cp wp wp_7776 +pico wp_7776 + +#Then change the port to 7776 from within the new file. + +6. make a copy of SuperNET/iguana/tests/dpow_7776 to SuperNET/iguana/dpow_7776 and edit the pubkey to match your btcpubkey from above + +cp dpow_7776 ../ +pico dpow_7776 + +7. make sure system clock is synchronized +sudo service ntp stop +sudo ntpdate -s time.nist.gov +sudo service ntp start + +Now things should be ready. To update and run notary node: +pkill iguana; ./m_LP; tests/notaryinit + + + +##Build for OSX distribution## +Get OSX SDK 10.6 from https://github.com/ca333/MacOSX-SDKs/releases/tag/10.6 + +Unpack & move the .sdk folder to Xcodes SDK folder: + +```cd DownloadDirectory``` + +```mv MacOSX10.6.sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/.``` + +If you are using Xcode > 7.3 add the new SDK to XCode by changing MinimumSDKVersion in your Info.plist: + +```vi /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Info.plist``` + +Change the value to: + +``` +MinimumSDKVersion +10.6 +``` +Build crypto777 library and agents with OSX release makefile: + +```./m_onetime m_osx_release``` + +Execute the OSX deploy script: + +``` +./osx_deploy.sh +``` +The iguana binary and its linked libraries are in ```$HOME/tmp/iguana```. diff --git a/README_decker.md b/README_decker.md new file mode 100644 index 000000000..a9cccd878 --- /dev/null +++ b/README_decker.md @@ -0,0 +1,25 @@ +## What's this? + +This is a first build of **MarketMaker** app from barterDEX for Windows (64-bit) platform. This branch includes all that you need to build marketmaker for Windows. 64-bit build uses MSVC 2015 as a default C/C++ compiler, to build - simply open *marketmaker.sln* project file via File -> Open -> Project/Solution ... next choose Release / x64 configuration and build solution. Your binaries will be placed x64\Release folder. To run marketmaker you also need following dll libraries: + +- libcurl.dll +- nanomsg.dll +- curl.exe (win64 curl binary, used is scripts) + +It already included in this branch. + +## How to use? + +Please, refer to original barterDEX documentation and Komodo Platform + SuperNET resources to learn how to work this it. Later i will add some examples and useful links here. + +Important, coins.json on Windows shouldn't contain coins which haven't running daemons. Add to coins.json only coins that you plan to use, in other case starting marketmaker will too long: about 4 seconds on each not-running coin. + +Get the latest binary release from release section and step-by-step run cmd files: + +- 1-client.cmd - this runs marketmaker with passphrase taken from a passphrase file. +- 2-getuserpass.cmd - this will save and output your userpass in userpass file for future use. +- 3-orderbook.cmd - to get an orderbook (if u downloaded binary release from release section - it's have only REVS in coins.json and orderbook will be shown at KMD/REVS coins pair). + +Other scripts will be post later ... this is just for example that it works. + + \ No newline at end of file diff --git a/ReadMe.txt b/ReadMe.txt new file mode 100644 index 000000000..3d1d8f0c5 --- /dev/null +++ b/ReadMe.txt @@ -0,0 +1,40 @@ +======================================================================== + CONSOLE APPLICATION : ConsoleApplication3 Project Overview +======================================================================== + +AppWizard has created this ConsoleApplication3 application for you. + +This file contains a summary of what you will find in each of the files that +make up your ConsoleApplication3 application. + + +ConsoleApplication3.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +ConsoleApplication3.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +ConsoleApplication3.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named ConsoleApplication3.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/__TemplateIcon.ico b/__TemplateIcon.ico new file mode 100644 index 000000000..aae70d3b8 Binary files /dev/null and b/__TemplateIcon.ico differ diff --git a/basilisk/basilisk copy.c b/basilisk/basilisk copy.c deleted file mode 100755 index 5b9a88c04..000000000 --- a/basilisk/basilisk copy.c +++ /dev/null @@ -1,1160 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "../iguana/iguana777.h" - -typedef char *basilisk_coinfunc(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen); -typedef char *basilisk_servicefunc(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk); -typedef struct basilisk_item *basilisk_requestfunc(struct basilisk_item *Lptr,struct supernet_info *myinfo,bits256 hash,cJSON *valsobj,uint8_t *data,int32_t datalen); - -uint32_t basilisk_calcnonce(struct supernet_info *myinfo,uint8_t *data,int32_t datalen,uint32_t nBits) -{ - int32_t i,numiters = 0; bits256 hash,hash2,threshold; uint32_t basilisktag; - vcalc_sha256(0,hash.bytes,data,datalen); - threshold = bits256_from_compact(nBits); - for (i=0; i 0 ) - break; - } - iguana_rwnum(0,(void *)hash.uints,sizeof(basilisktag),&basilisktag); - iguana_rwnum(1,&data[-sizeof(basilisktag)],sizeof(basilisktag),&basilisktag); - char str[65],str2[65]; printf("found hash after numiters.%d %s vs %s basilisktag.%u\n",numiters,bits256_str(str,threshold),bits256_str(str2,hash2),basilisktag); - return(basilisktag); -} - -char *basilisk_addhexstr(char **ptrp,cJSON *valsobj,char *strbuf,int32_t strsize,uint8_t *data,int32_t datalen) -{ - *ptrp = 0; - if ( data != 0 && datalen > 0 ) - { - if ( valsobj != 0 && jobj(valsobj,"data") != 0 ) - { - printf("basilisk_addhexstr warning: already have data object\n"); - jdelete(valsobj,"data"); - } - if ( (datalen<<1)+1 > strsize ) - { - strbuf = calloc(1,(datalen << 1) + 1); - *ptrp = (void *)strbuf; - } - init_hexbytes_noT(strbuf,data,datalen); - if ( valsobj != 0 ) - jaddstr(valsobj,"data",strbuf); - } else return(0); - return(strbuf); -} - -uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t *space,int32_t spacesize,char *hexstr) -{ - *ptrp = 0; uint8_t *data = 0; - if ( hexstr != 0 && (*datalenp= is_hexstr(hexstr,0)) > 0 ) - { - *datalenp >>= 1; - if ( (*datalenp+hdroffset) <= spacesize ) - { - memset(space,0,hdroffset); - data = &space[hdroffset]; - } else *ptrp = data = calloc(1,*datalenp + hdroffset); - decode_hex(&data[hdroffset],*datalenp,hexstr); - } - if ( data != 0 ) - return(&data[hdroffset]); - else return(data); -} - -uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int32_t spacesize,int32_t *datalenp,char *symbol,cJSON *sendjson,uint32_t basilisktag) -{ - char *sendstr,*hexstr=0; uint8_t *data,hexspace[8192],*allocptr=0,*hexdata; int32_t datalen,hexlen=0; - if ( jobj(sendjson,"symbol") == 0 ) - jaddstr(sendjson,"symbol",symbol); - if ( (hexstr= jstr(sendjson,"data")) != 0 ) - { - hexdata = get_dataptr(0,&allocptr,&hexlen,hexspace,sizeof(hexspace),hexstr); - //printf("delete data.%s from sendjson\n",hexstr); - jdelete(sendjson,"data"); - } - *ptrp = 0; - sendstr = jprint(sendjson,0); - datalen = (int32_t)strlen(sendstr) + 1; - if ( (datalen + extraoffset + BASILISK_HDROFFSET + hexlen) <= spacesize ) - data = space; - else - { - data = calloc(1,datalen + extraoffset + BASILISK_HDROFFSET + hexlen); - *ptrp = data; - } - data += extraoffset + BASILISK_HDROFFSET; - memcpy(data,sendstr,datalen); - //printf("jsondata.(%s) + hexlen.%d\n",sendstr,hexlen); - free(sendstr); - if ( hexlen > 0 ) - { - memcpy(&data[datalen],hexdata,hexlen); - datalen += hexlen; - } - *datalenp = datalen; - if ( allocptr != 0 ) - free(allocptr); - return(data); -} - -char *basilisk_finish(struct basilisk_item *ptr,int32_t besti,char *errstr) -{ - char *retstr = 0; struct basilisk_item *parent; - if ( ptr->retstr != 0 ) - return(ptr->retstr); - if ( besti >= 0 && besti < ptr->numresults ) - { - retstr = ptr->results[besti]; - ptr->results[besti] = 0; - } else printf("besti.%d vs numresults.%d retstr.%p\n",besti,ptr->numresults,retstr); - if ( retstr == 0 ) - retstr = clonestr(errstr); - ptr->retstr = retstr; - ptr->finished = (uint32_t)time(NULL); - if ( (parent= ptr->parent) != 0 ) - { - ptr->parent = 0; - parent->childrendone++; - } - return(retstr); -} - -struct basilisk_item *basilisk_itemcreate(struct supernet_info *myinfo,char *CMD,char *symbol,uint32_t basilisktag,int32_t minresults,cJSON *vals,int32_t timeoutmillis,void *metricfunc) -{ - struct basilisk_item *ptr; - ptr = calloc(1,sizeof(*ptr)); - ptr->basilisktag = basilisktag; - if ( (ptr->numrequired= minresults) == 0 ) - ptr->numrequired = 1; - if ( (ptr->metricfunc= metricfunc) != 0 ) - ptr->vals = jduplicate(vals); - strcpy(ptr->CMD,CMD); - safecopy(ptr->symbol,symbol,sizeof(ptr->symbol)); - ptr->expiration = OS_milliseconds() + timeoutmillis; - return(ptr); -} - -int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *type,uint32_t *basilisktagp,int32_t encryptflag,int32_t delaymillis,uint8_t *data,int32_t datalen,int32_t fanout,uint32_t nBits) // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) -{ - int32_t i,r,l,s,val,n=0,retval = -1; char cmd[12]; struct iguana_info *coin,*tmp; struct iguana_peer *addr; bits256 hash; uint32_t *alreadysent; - if ( fanout <= 0 ) - fanout = BASILISK_MINFANOUT; - else if ( fanout > BASILISK_MAXFANOUT ) - fanout = BASILISK_MAXFANOUT; - if ( type == 0 ) - type = "BTCD"; - if ( strlen(type) > 3 ) - { - printf("basilisk_sendcmd illegal type(%s)\n",type); - return(-1); - } - if ( destipaddr != 0 ) - { - if ( destipaddr[0] == 0 ) - destipaddr = 0; // broadcast - else if ( strcmp(destipaddr,"127.0.0.1") == 0 ) - { - printf("return after locally basilisk_msgprocess\n"); - hash = GENESIS_PUBKEY; - basilisk_msgprocess(myinfo,0,0,type,*basilisktagp,data,datalen); - return(0); - } - } - alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); - iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); - if ( *basilisktagp == 0 ) - { - if ( nBits != 0 ) - *basilisktagp = basilisk_calcnonce(myinfo,data,datalen,nBits); - else *basilisktagp = rand(); - iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); - } - data -= sizeof(*basilisktagp), datalen += sizeof(*basilisktagp); - memset(cmd,0,sizeof(cmd)); - sprintf(cmd,"SuperNET%s",type); - r = rand(); - //portable_mutex_lock(&Allcoins_mutex); - HASH_ITER(hh,myinfo->allcoins,coin,tmp) - { - if ( coin->peers == 0 ) - continue; - if ( coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 ) - cmd[0] = 's'; - else cmd[0] = 'S'; - for (l=0; lpeers->active[i]; - if ( addr->usock >= 0 ) - { - for (s=0; sipbits ) - break; - //printf("%s s.%d vs n.%d\n",addr->ipaddr,s,n); - if ( s == n && (addr->supernet != 0 || addr->basilisk != 0) && (destipaddr == 0 || strcmp(addr->ipaddr,destipaddr) == 0) ) - { - //printf("[%s].tag%d send %s.(%s) [%x] datalen.%d addr->supernet.%u basilisk.%u to (%s).%d destip.%s\n",cmd,*(uint32_t *)data,type,(char *)&data[4],*(int32_t *)&data[datalen-4],datalen,addr->supernet,addr->basilisk,addr->ipaddr,addr->A.port,destipaddr!=0?destipaddr:"broadcast"); - if ( encryptflag != 0 && bits256_nonz(addr->pubkey) != 0 ) - { - void *ptr; uint8_t *cipher,space[8192]; int32_t cipherlen; bits256 privkey; - cmd[6] = 'e', cmd[7] = 't'; - memset(privkey.bytes,0,sizeof(privkey)); - if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&addr->pubkey,data,datalen,space,sizeof(space))) != 0 ) - { - if ( (val= iguana_queue_send(addr,delaymillis,&cipher[-sizeof(struct iguana_msghdr)],cmd,cipherlen)) >= cipherlen ) - n++; - if ( ptr != 0 ) - free(ptr); - } - } - else - { - cmd[6] = 'E', cmd[7] = 'T'; - if ( (val= iguana_queue_send(addr,delaymillis,&data[-sizeof(struct iguana_msghdr)],cmd,datalen)) >= datalen ) - { - alreadysent[n++] = (uint32_t)addr->ipbits; - if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) - break; - } - } - if ( destipaddr != 0 || (fanout > 0 && n >= fanout) ) - { - free(alreadysent); - return(val); - } - else if ( val > retval ) - retval = val; - } - } - } - if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) - break; - } - //portable_mutex_unlock(&Allcoins_mutex); - free(alreadysent); - return(n); -} - -void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t datalen,char *type,int32_t encrypted) -{ - uint32_t ipbits,basilisktag; int32_t msglen,len=0; void *ptr = 0; uint8_t space[8192]; bits256 senderpub; struct supernet_info *myinfo = _myinfo; - if ( encrypted != 0 ) - { - printf("encrypted p2p\n"); - memset(senderpub.bytes,0,sizeof(senderpub)); - if ( (data= SuperNET_deciphercalc(&ptr,&msglen,myinfo->privkey,senderpub,data,datalen,space,sizeof(space))) == 0 ) - { - printf("basilisk_p2p decrytion error\n"); - return; - } else datalen = msglen; - } - if ( senderip != 0 && senderip[0] != 0 && strcmp(senderip,"127.0.0.1") != 0 ) - ipbits = (uint32_t)calc_ipbits(senderip); - else ipbits = 0; - len += iguana_rwnum(0,data,sizeof(basilisktag),&basilisktag); - //int32_t i; for (i=0; ireceived.%d basilisk_p2p.(%s) from %s tag.%d\n",datalen,type,senderip!=0?senderip:"?",basilisktag); - basilisk_msgprocess(myinfo,_addr,ipbits,type,basilisktag,&data[len],datalen - len); - if ( ptr != 0 ) - free(ptr); -} - -void basilisk_sendback(struct supernet_info *myinfo,char *origCMD,char *symbol,char *remoteaddr,uint32_t basilisktag,char *retstr) -{ - uint8_t *data,space[4096],*allocptr; struct iguana_info *virt; cJSON *valsobj; int32_t datalen,encryptflag=0,delaymillis=0; - //printf("%s retstr.(%s) -> remote.(%s) basilisktag.%u\n",origCMD,retstr,remoteaddr,basilisktag); - if ( retstr != 0 && remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 ) - { - if ( (valsobj= cJSON_Parse(retstr)) != 0 ) - { - jaddstr(valsobj,"origcmd",origCMD); - jaddstr(valsobj,"symbol",symbol); - if ( (virt= iguana_coinfind(symbol)) != 0 ) - { - jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); - jaddbits256(valsobj,"chaintip",virt->blocks.hwmchain.RO.hash2); - } - data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); - basilisk_sendcmd(myinfo,remoteaddr,"RET",&basilisktag,encryptflag,delaymillis,data,datalen,0,0); - if ( allocptr != 0 ) - free(allocptr); - free_json(valsobj); - } - } -} - -char *basilisk_waitresponse(struct supernet_info *myinfo,char *CMD,char *symbol,char *remoteaddr,struct basilisk_item *Lptr,struct basilisk_item *ptr) -{ - char *retstr = 0; - if ( ptr == Lptr ) - { - if ( (retstr= Lptr->retstr) == 0 ) - retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}"); - ptr = basilisk_itemcreate(myinfo,CMD,symbol,Lptr->basilisktag,Lptr->numrequired,Lptr->vals,OS_milliseconds() - Lptr->expiration,Lptr->metricfunc); - queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - } - else - { - queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - while ( OS_milliseconds() < ptr->expiration ) - { - //if ( (retstr= basilisk_iscomplete(ptr)) != 0 ) - if ( (retstr= ptr->retstr) != 0 ) - break; - usleep(50000); - } - if ( retstr == 0 ) - retstr = basilisk_finish(ptr,-1,"{\"error\":\"basilisk timeout\"}"); - } - basilisk_sendback(myinfo,CMD,symbol,remoteaddr,ptr->basilisktag,retstr); - return(retstr); -} - -struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,int32_t *numsentp,char *CMD,char *symbol,int32_t blockflag,cJSON *valsobj,int32_t fanout,int32_t minresults,uint32_t basilisktag,int32_t timeoutmillis,void *_metricfunc,char *retstr,int32_t encryptflag,int32_t delaymillis,uint32_t nBits) -{ - struct basilisk_item *ptr; uint8_t *allocptr,*data,space[4096]; int32_t datalen; basilisk_metricfunc metricfunc = _metricfunc; - ptr = basilisk_itemcreate(myinfo,CMD,symbol,basilisktag,minresults,valsobj,timeoutmillis,metricfunc); - ptr->nBits = nBits; - *numsentp = 0; - if ( retstr != 0 ) - { - ptr->results[0] = ptr->retstr = retstr; - ptr->numresults = ptr->numrequired; - ptr->metrics[0] = (*metricfunc)(myinfo,ptr,retstr); - ptr->finished = (uint32_t)time(NULL); - } - else - { - data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); - *numsentp = ptr->numsent = basilisk_sendcmd(myinfo,0,CMD,&ptr->basilisktag,encryptflag,delaymillis,data,datalen,1,ptr->nBits); - if ( blockflag != 0 ) - queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - else ptr->finished = (uint32_t)time(NULL); - if ( allocptr != 0 ) - free(allocptr); - } - return(ptr); -} - -struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char *CMD,int32_t blockflag,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits) -{ - int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag,fanout; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt,*btcd; - if ( (btcd= iguana_coinfind("BTCD")) != 0 && btcd->RELAYNODE != 0 ) - jaddnum(valsobj,"iamrelay",1); - basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen); - if ( bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0 ) - { - if ( jobj(valsobj,"hash") != 0 ) - jdelete(valsobj,"hash"); - jaddbits256(valsobj,"hash",hash); - } - if ( (minresults= jint(valsobj,"minresults")) <= 0 ) - minresults = 1; - if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( jobj(valsobj,"fanout") == 0 ) - fanout = 1; - else fanout = jint(valsobj,"fanout"); - if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) - { - if ( (virt= iguana_coinfind(symbol)) != 0 ) - { - jaddstr(valsobj,"symbol",symbol); - jaddnum(valsobj,"longest",virt->longestchain); - jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); - } - } - encryptflag = jint(valsobj,"encrypt"); - delaymillis = jint(valsobj,"delay"); - ptr = basilisk_issueremote(myinfo,&numsent,CMD,"BTCD",blockflag,valsobj,fanout,minresults,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); - return(ptr); -} - -char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag) // client side -{ - uint32_t nBits = 0; uint8_t space[8192],*allocptr=0,*data = 0; struct basilisk_item *ptr,Lptr; int32_t datalen = 0; cJSON *retjson; - retjson = cJSON_CreateObject(); - data = get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr); - ptr = basilisk_requestservice(myinfo,CMD,blockflag,valsobj,hash,data,datalen,nBits); - if ( allocptr != 0 ) - free(allocptr); - if ( ptr != 0 ) - { - if ( blockflag != 0 ) - { - if ( ptr->expiration <= OS_milliseconds() ) - ptr->expiration = OS_milliseconds() + BASILISK_TIMEOUT; - ptr->vals = jduplicate(valsobj); - strcpy(ptr->symbol,"BTCD"); - strcpy(ptr->CMD,CMD); - return(basilisk_waitresponse(myinfo,CMD,"BTCD",0,&Lptr,ptr)); - } - else if ( ptr->numsent > 0 ) - { - queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"numsent",ptr->numsent); - } else jaddstr(retjson,"error","didnt find any nodes to send to"); - } else jaddstr(retjson,"error","couldnt create basilisk item"); - return(jprint(retjson,1)); -} - -#include "basilisk_bitcoin.c" -#include "basilisk_nxt.c" -#include "basilisk_ether.c" -#include "basilisk_waves.c" -#include "basilisk_lisk.c" -#include "basilisk_CMD.c" - -void basilisk_functions(struct iguana_info *coin,int32_t protocol) -{ - coin->protocol = protocol; - switch ( protocol ) - { - case IGUANA_PROTOCOL_BITCOIN: - coin->basilisk_balances = basilisk_bitcoinbalances; - coin->basilisk_rawtx = basilisk_bitcoinrawtx; - coin->basilisk_rawtxmetric = basilisk_bitcoin_rawtxmetric; - coin->basilisk_value = basilisk_bitcoinvalue; - coin->basilisk_valuemetric = basilisk_bitcoin_valuemetric; - break; - /*case IGUANA_PROTOCOL_IOTA: - coin->basilisk_balances = basilisk_iotabalances; - coin->basilisk_rawtx = basilisk_iotarawtx; - break; - case IGUANA_PROTOCOL_NXT: - coin->basilisk_balances = basilisk_nxtbalances; - coin->basilisk_rawtx = basilisk_nxtrawtx; - break; - case IGUANA_PROTOCOL_ETHER: - coin->basilisk_balances = basilisk_etherbalances; - coin->basilisk_rawtx = basilisk_etherrawtx; - break; - case IGUANA_PROTOCOL_WAVES: - coin->basilisk_balances = basilisk_wavesbalances; - coin->basilisk_rawtx = basilisk_wavesrawtx; - break; - case IGUANA_PROTOCOL_LISK: - coin->basilisk_balances = basilisk_liskbalances; - coin->basilisk_rawtx = basilisk_liskrawtx; - break;*/ - } -} - -int32_t basilisk_besti(struct basilisk_item *ptr) -{ - int32_t i,besti = -1; double metric,bestmetric=-1.; - for (i=0; inumresults; i++) - { - if ( (metric= ptr->metrics[i]) > 0. ) - { - if ( (ptr->metricdir < 0 && (bestmetric < 0. || metric < bestmetric)) || (ptr->metricdir > 0 && (bestmetric < 0. || metric > bestmetric)) || (ptr->metricdir == 0 && bestmetric < 0.) ) - { - bestmetric = metric; - besti = i; - } - } - } - if ( besti >= 0 ) - { - for (ptr->numexact=i=0; inumresults; i++) - if ( fabs(ptr->metrics[i] - bestmetric) < SMALLVAL ) - ptr->numexact++; - } - return(besti); -} - -char *basilisk_iscomplete(struct basilisk_item *ptr) -{ - int32_t i,numvalid,besti=-1; char *errstr = 0,*retstr = 0; - if ( ptr->childrendone < ptr->numchildren ) - return(0); - if ( ptr->retstr != 0 || ptr->finished != 0 ) - return(ptr->retstr); - if ( (numvalid= ptr->numresults) >= ptr->numrequired ) - { - for (i=numvalid=0; inumresults; i++) - { - if ( ptr->metrics[i] != 0. ) - numvalid++; - } - } - if ( numvalid < ptr->numrequired ) - { - //printf("%u: numvalid.%d < required.%d m %f\n",ptr->basilisktag,numvalid,ptr->numrequired,ptr->metrics[0]); - return(0); - } - if ( ptr->uniqueflag == 0 && ptr->numexact != ptr->numresults && ptr->numexact < (ptr->numresults >> 1) ) - besti = -1, errstr = "{\"error\":\"basilisk non-consensus results\"}"; - else besti = basilisk_besti(ptr), errstr = "{\"error\":\"basilisk no valid results\"}"; - //printf("%u complete besti.%d\n",ptr->basilisktag,besti); - retstr = basilisk_finish(ptr,besti,errstr); - //printf("%u besti.%d numexact.%d numresults.%d -> (%s)\n",ptr->basilisktag,besti,ptr->numexact,ptr->numresults,retstr); - return(retstr); -} - -struct basilisk_item *basilisk_issuecmd(struct basilisk_item *Lptr,basilisk_func func,basilisk_metricfunc metricfunc,struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,int32_t timeoutmillis,cJSON *vals) -{ - struct iguana_info *coin; struct basilisk_item *ptr; - memset(Lptr,0,sizeof(*Lptr)); - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - if ( func != 0 ) - { - if ( (ptr= (*func)(Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) - { - if ( (ptr->metricfunc= metricfunc) != 0 ) - ptr->vals = jduplicate(vals); - strcpy(ptr->symbol,symbol); - ptr->basilisktag = basilisktag; - ptr->expiration = OS_milliseconds() + timeoutmillis; - return(ptr); - } else Lptr->retstr = clonestr("{\"error\":\"error issuing basilisk command\"}"); - } else Lptr->retstr = clonestr("{\"error\":\"null basilisk function\"}"); - } else Lptr->retstr = clonestr("{\"error\":\"error missing coin\"}"); - return(Lptr); -} - -char *basilisk_check(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) -{ - if ( symbol != 0 && symbol[0] != 0 && vals != 0 ) - { - if ( *basilisktagp == 0 ) - *basilisktagp = rand(); - if ( (*timeoutmillisp= jint(vals,"timeout")) < 0 ) - *timeoutmillisp = BASILISK_TIMEOUT; - return(0); - } else return(clonestr("{\"error\":\"missing activecoin or vals\"}")); -} - -char *basilisk_standardcmd(struct supernet_info *myinfo,char *CMD,char *activecoin,char *remoteaddr,uint32_t basilisktag,cJSON *vals,basilisk_func func,basilisk_metricfunc metric) -{ - char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; struct iguana_info *coin; - if ( (retstr= basilisk_check(&timeoutmillis,&basilisktag,activecoin,vals)) == 0 ) - { - if ( (coin= iguana_coinfind(activecoin)) != 0 ) - { - if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) - { - return(basilisk_waitresponse(myinfo,CMD,coin->symbol,remoteaddr,&Lptr,ptr)); - } - else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}")); - } else return(clonestr("{\"error\":\"couldnt get coin\"}")); - } else return(retstr); -} - -char *_basilisk_value(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) -{ - return(basilisk_standardcmd(myinfo,"VAL",coin->symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_value,coin->basilisk_valuemetric)); -} - -char *_basilisk_balances(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) -{ - return(basilisk_standardcmd(myinfo,"BAL",coin->symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_balances,coin->basilisk_balancesmetric)); -} - -char *_basilisk_rawtx(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) -{ - char *retstr,strbuf[4096],*str = 0; - printf("remote rawtx.(%s)\n",jprint(valsobj,0)); - basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); - retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - if ( str != 0 ) - free(str); - return(retstr); -} - -char *_basilisk_result(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) -{ - char strbuf[4096],*str = 0; - basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); - return(basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj)); -} - -char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) -{ - cJSON *addresses=0; char *changeaddr,*spendscriptstr; int32_t i,n; - *timeoutmillisp = -1; - changeaddr = jstr(vals,"changeaddr"); - spendscriptstr = jstr(vals,"spendscript"); - addresses = jarray(&n,vals,"addresses"); - if ( addresses == 0 || changeaddr == 0 || changeaddr[0] == 0 ) - return(clonestr("{\"error\":\"invalid addresses[] or changeaddr\"}")); - else - { - for (i=0; isymbol); - if ( (retstr= basilisk_standardservice(CMD,myinfo,hash,vals,hexstr,0)) != 0 ) - free(retstr); - free_json(vals); - if ( allocptr != 0 ) - free(allocptr); - } - return(0); - } else return(-1); -} - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -INT_ARRAY_STRING(basilisk,balances,basilisktag,vals,activecoin) -{ - return(basilisk_standardcmd(myinfo,"BAL",activecoin,remoteaddr,basilisktag,vals,coin->basilisk_balances,coin->basilisk_balancesmetric)); -} - -INT_ARRAY_STRING(basilisk,value,basilisktag,vals,activecoin) -{ - return(basilisk_standardcmd(myinfo,"VAL",activecoin,remoteaddr,basilisktag,vals,coin->basilisk_value,coin->basilisk_valuemetric)); -} - -INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin) -{ - char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; - if ( (retstr= basilisk_checkrawtx(&timeoutmillis,(uint32_t *)&basilisktag,activecoin,vals)) == 0 ) - { - coin = iguana_coinfind(activecoin); - if ( coin != 0 && (ptr= basilisk_issuecmd(&Lptr,coin->basilisk_rawtx,coin->basilisk_rawtxmetric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) - { - if ( (ptr->numrequired= juint(vals,"numrequired")) == 0 ) - ptr->numrequired = 1; - ptr->uniqueflag = 1; - ptr->metricdir = -1; - return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,ptr)); - } else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}")); - } else return(retstr); -} - -INT_AND_ARRAY(basilisk,result,basilisktag,vals) -{ - struct basilisk_item *ptr; - if ( vals != 0 ) - { - ptr = calloc(1,sizeof(*ptr)); - ptr->retstr = jprint(vals,0); - ptr->basilisktag = basilisktag; - strcpy(ptr->remoteaddr,remoteaddr); - safecopy(ptr->CMD,jstr(vals,"origcmd"),sizeof(ptr->CMD)); - printf("(%s) -> Q.%u results vals.(%s)\n",ptr->CMD,basilisktag,ptr->retstr); - queue_enqueue("resultsQ",&myinfo->basilisks.resultsQ,&ptr->DL,0); - return(clonestr("{\"result\":\"queued basilisk return\"}")); - } else printf("null vals.(%s) or no hexmsg.%p\n",jprint(vals,0),vals); - return(clonestr("{\"error\":\"no hexmsg to return\"}")); -} - -HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr) -{ - return(basilisk_standardservice("ADD",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,relays,hash,vals,hexstr) -{ - return(basilisk_standardservice("RLY",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr) -{ - return(basilisk_standardservice("RUN",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,publish,hash,vals,hexstr) -{ - return(basilisk_standardservice("PUB",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,subscribe,hash,vals,hexstr) -{ - return(basilisk_standardservice("SUB",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,forward,hash,vals,hexstr) -{ - return(basilisk_standardservice("HOP",myinfo,hash,vals,hexstr,0)); -} - -HASH_ARRAY_STRING(basilisk,mailbox,hash,vals,hexstr) -{ - return(basilisk_standardservice("BOX",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr) -{ - return(basilisk_standardservice("VPN",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,VPNjoin,hash,vals,hexstr) -{ - return(basilisk_standardservice("ARC",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,VPNmessage,hash,vals,hexstr) -{ - return(basilisk_standardservice("GAB",myinfo,hash,vals,hexstr,0)); -} - -HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr) -{ - return(basilisk_standardservice("SAY",myinfo,hash,vals,hexstr,0)); -} - -HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr) -{ - return(basilisk_standardservice("EAR",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr) -{ - return(basilisk_standardservice("END",myinfo,hash,vals,hexstr,0)); -} - -#include "../includes/iguana_apiundefs.h" - -// set hwm, get headers, then blocks - -void basilisk_geckoresult(struct supernet_info *myinfo,struct basilisk_item *ptr) -{ - uint8_t *data,space[16384],*allocptr = 0; struct iguana_info *virt; char *symbol,*str,*type; int32_t datalen; cJSON *retjson; bits256 hash2; - if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) - { - if ( (symbol= jstr(retjson,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) - { - if ( (data= get_dataptr(0,&allocptr,&datalen,space,sizeof(space),jstr(retjson,"data"))) != 0 ) - { - str = 0; - if ( (type= jstr(retjson,"type")) != 0 ) - { - hash2 = jbits256(retjson,"hash"); - if ( strcmp(type,"HDR") == 0 ) - str = gecko_headersarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); - else if ( strcmp(type,"MEM") == 0 ) - str = gecko_mempoolarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); - else if ( strcmp(type,"BLK") == 0 ) - str = gecko_blockarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); - else if ( strcmp(type,"GTX") == 0 ) - str = gecko_txarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); - } - if ( str != 0 ) - free(str); - if ( allocptr != 0 ) - free(allocptr); - } - } - free_json(retjson); - } -} - -void basilisk_pending_result(struct supernet_info *myinfo,struct basilisk_item *ptr,struct basilisk_item *pending) -{ - int32_t n; struct basilisk_item *parent; basilisk_metricfunc metricfunc; - if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) ) - { - pending->numresults++; - if ( (metricfunc= pending->metricfunc) == 0 ) - pending->metrics[n] = n + 1; - else if ( (pending->metrics[n]= (*metricfunc)(myinfo,pending,ptr->retstr)) != 0. ) - pending->childrendone++; - printf("%s.%u Add results[%d] <- metric %f\n",pending->CMD,pending->basilisktag,n,pending->metrics[n]); - pending->results[n] = ptr->retstr, ptr->retstr = 0; - /*if ( strcmp(ptr->CMD,"SEQ") == 0 ) - { - if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) - { - gecko_seqresult(myinfo,ptr->retstr); - free_json(retjson); - } - } - else*/ - if ( strcmp(ptr->CMD,"RET") == 0 || strcmp(ptr->CMD,"GET") == 0 ) - { - printf("got return for tag.%d parent.%p\n",pending->basilisktag,pending->parent); - if ( (parent= pending->parent) != 0 ) - { - pending->parent = 0; - parent->childrendone++; - } - if ( strcmp(ptr->CMD,"GET") == 0 ) - basilisk_geckoresult(myinfo,ptr); - } - } -} - -int32_t basilisk_issued_iteration(struct supernet_info *myinfo,struct basilisk_item *pending) -{ - basilisk_metricfunc metricfunc; struct basilisk_item *parent; int32_t i,flag = 0; - //printf("pending.%u numresults.%d m %f func.%p\n",pending->basilisktag,pending->numresults,pending->metrics[0],pending->metricfunc); - if ( (metricfunc= pending->metricfunc) != 0 ) - { - for (i=0; inumresults; i++) - if ( pending->metrics[i] == 0. && pending->results[i] != 0 ) - { - if ( (pending->metrics[i]= (*metricfunc)(myinfo,pending,pending->results[i])) != 0 ) - pending->childrendone++; - // printf("iter.%d %p.[%d] poll metrics.%u metric %f\n",iter,pending,i,pending->basilisktag,pending->metrics[i]); - flag++; - } - } - basilisk_iscomplete(pending); - if ( OS_milliseconds() > pending->expiration ) - { - if ( pending->finished == 0 ) - { - if ( (parent= pending->parent) != 0 ) - { - pending->parent = 0; - parent->childrendone++; - } - pending->finished = (uint32_t)time(NULL); - if ( pending->retstr == 0 ) - pending->retstr = clonestr("{\"error\":\"basilisk timeout\"}"); - fprintf(stderr,"timeout.%s call metrics.%u lag %f - %f\n",pending->CMD,pending->basilisktag,OS_milliseconds(),pending->expiration); - for (i=0; inumresults; i++) - if ( (metricfunc= pending->metricfunc) != 0 && pending->metrics[i] == 0. ) - pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); - flag++; - } - } - //fprintf(stderr,"c"); - if ( pending->finished != 0 && time(NULL) > pending->finished+60 ) - { - if ( pending->dependents == 0 || pending->childrendone >= pending->numchildren ) - { - HASH_DELETE(hh,myinfo->basilisks.issued,pending); - if ( pending->dependents != 0 ) - free(pending->dependents); - fprintf(stderr,"HASH_DELETE free ptr.%u refcount.%d\n",pending->basilisktag,pending->refcount); - for (i=0; inumresults; i++) - if ( pending->results[i] != 0 ) - free(pending->results[i]), pending->results[i] = 0; - if ( pending->vals != 0 ) - free_json(pending->vals), pending->vals = 0; - free(pending); - flag++; - } - } - return(flag); -} - -void basilisks_loop(void *arg) -{ - struct iguana_info *btcd,*virt,*hhtmp; struct basilisk_item *ptr,*tmp,*pending; int32_t iter,maxmillis,flag; struct supernet_info *myinfo = arg; - iter = 0; - while ( 1 ) - { - iter++; - if ( (ptr= queue_dequeue(&myinfo->basilisks.submitQ,0)) != 0 ) - HASH_ADD(hh,myinfo->basilisks.issued,basilisktag,sizeof(ptr->basilisktag),ptr); - //fprintf(stderr,"A"); - else if ( (ptr= queue_dequeue(&myinfo->basilisks.resultsQ,0)) != 0 ) - { - HASH_FIND(hh,myinfo->basilisks.issued,&ptr->basilisktag,sizeof(ptr->basilisktag),pending); - if ( pending != 0 ) - basilisk_pending_result(myinfo,ptr,pending); - else printf("couldnt find issued.%u\n",ptr->basilisktag); - free(ptr); - } - else - { - flag = 0; - HASH_ITER(hh,myinfo->basilisks.issued,pending,tmp) - { - flag += basilisk_issued_iteration(myinfo,pending); - } - if ( flag == 0 && myinfo->allcoins_numvirts > 0 && (btcd= iguana_coinfind("BTCD")) != 0 ) - { - maxmillis = (1000 / myinfo->allcoins_numvirts) + 1; - //portable_mutex_lock(&Allcoins_mutex); - HASH_ITER(hh,myinfo->allcoins,virt,hhtmp) - { - if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) - { - //fprintf(stderr,"h"); - gecko_iteration(myinfo,btcd,virt,maxmillis); - flag++; - } - } - //portable_mutex_unlock(&Allcoins_mutex); - } - } - //fprintf(stderr,"i "); - //for (i=0; iRELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 && coin->MAXPEERS == 1 ) - // basilisk_bitcoinscan(coin,blockspace,&RAWMEM); - if ( flag == 0 ) - usleep(10000); - } -} - -void basilisks_init(struct supernet_info *myinfo) -{ - iguana_initQ(&myinfo->basilisks.submitQ,"submitQ"); - iguana_initQ(&myinfo->basilisks.resultsQ,"resultsQ"); - portable_mutex_init(&myinfo->allcoins_mutex); - portable_mutex_init(&myinfo->basilisk_mutex); - portable_mutex_init(&myinfo->gecko_mutex); - myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD); -} - -void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin) -{ - if ( coin != 0 ) - { - while ( coin->basilisk_busy != 0 ) - usleep(1000); - } - else - { - while ( myinfo->basilisk_busy != 0 ) - usleep(1000); - } -} - -void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen) -{ - cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t height,origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0; bits256 hash; struct iguana_peer *addr = _addr; - static basilisk_servicefunc *basilisk_services[][2] = - { - { (void *)"RUN", &basilisk_respond_dispatch }, // higher level protocol handler, pass through - { (void *)"BYE", &basilisk_respond_goodbye }, // disconnect - - // gecko chains - { (void *)"NEW", &basilisk_respond_newgeckochain }, // creates new virtual gecko chain - { (void *)"GEN", &basilisk_respond_geckogenesis }, // returns genesis list - { (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx - { (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers - { (void *)"BLK", &basilisk_respond_geckoblock }, // reports block - { (void *)"MEM", &basilisk_respond_mempool }, // reports mempool - { (void *)"GTX", &basilisk_respond_geckotx }, // reports tx - //{ (void *)"SEQ", &basilisk_respond_hashstamps }, // BTCD and BTC recent hashes from timestamp - - // unencrypted low level functions, used by higher level protocols and virtual network funcs - { (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus - { (void *)"RLY", &basilisk_respond_relays }, - { (void *)"DEX", &basilisk_respond_instantdex }, - - // encrypted data for jumblr - { (void *)"HOP", &basilisk_respond_forward }, // message forwarding - { (void *)"BOX", &basilisk_respond_mailbox }, // create/send/check mailbox pubkey - - // small virtual private network - { (void *)"VPN", &basilisk_respond_VPNcreate }, // create virtual network's hub via privkey - { (void *)"ARC", &basilisk_respond_VPNjoin }, // join - { (void *)"GAB", &basilisk_respond_VPNmessage }, // private message - { (void *)"SAY", &basilisk_respond_VPNbroadcast }, // broadcast - { (void *)"EAR", &basilisk_respond_VPNreceive }, // network receive (via poll) - { (void *)"END", &basilisk_respond_VPNlogout }, // logout - - // coin services - { (void *)"RAW", &_basilisk_rawtx }, - { (void *)"VAL", &_basilisk_value }, - }; - /*static basilisk_coinfunc *basilisk_coinservices[][2] = - { - { (void *)"RAW", &_basilisk_rawtx }, - { (void *)"VAL", &_basilisk_value }, - { (void *)"BAL", &_basilisk_balances }, - };*/ - symbol = "BTCD"; - if ( (valsobj= cJSON_Parse((char *)data)) != 0 ) - { - //printf("MSGVALS.(%s)\n",(char *)data); - if ( jobj(valsobj,"coin") != 0 ) - coin = iguana_coinfind(jstr(valsobj,"coin")); - else if ( jobj(valsobj,"symbol") != 0 ) - coin = iguana_coinfind(jstr(valsobj,"symbol")); - if ( coin != 0 ) - { - if ( (height= juint(valsobj,"hwm")) > 0 ) - { - if ( height > addr->height ) - addr->height = height; - if ( height > coin->longestchain ) - coin->longestchain = height; - } - } - if ( strcmp(type,"RET") == 0 ) - { - if ( (retstr= _basilisk_result(myinfo,coin,addr,remoteaddr,basilisktag,valsobj,data,datalen)) != 0 ) - free(retstr); - return; - } - } else return; - for (i=flag=0; ibasilisk_busy = 1; - if ( valsobj != 0 ) - { - jsonlen = (int32_t)strlen((char *)data) + 1; - if ( datalen > jsonlen ) - data += jsonlen, datalen -= jsonlen; - else data = 0, datalen = 0; - if ( coin == 0 ) - coin = iguana_coinfind("BTCD"); - if ( coin != 0 ) - { - symbol = coin->symbol; - coin->basilisk_busy = 1; - } - hash = jbits256(valsobj,"hash"); - timeoutmillis = jint(valsobj,"timeout"); - if ( (numrequired= jint(valsobj,"numrequired")) == 0 ) - numrequired = 1; - if ( senderipbits != 0 ) - expand_ipbits(remoteaddr,senderipbits); - else remoteaddr[0] = 0; - /*if ( valsobj != 0 && remoteaddr != 0 ) - { - if ( from_basilisk == 0 ) - { - if ( strcmp(CMD,"RLY") == 0 ) - { - printf("add relay path\n"); - if ( juint(valsobj,"iamrelay") != 0 ) - { - retstr = basilisk_respond_relays(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk); - } - free_json(valsobj); - if ( coin != 0 ) - coin->basilisk_busy = 0; - myinfo->basilisk_busy = 0; - return; - } - else if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(remoteaddr),GENESIS_PUBKEY)) != 0 ) - free(retstr); - } - }*/ - for (i=0; iIAMRELAY != 0 ) // iguana node - { - if ( 0 && from_basilisk != 0 ) - { - printf("echo to other relays\n"); - basilisk_sendcmd(myinfo,0,cmd,&basilisktag,0,0,origdata,origlen,-1,0); // to other iguanas - } - if ( (retstr= (*basilisk_services[i][1])(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk)) != 0 ) - { - //printf("from_basilisk.%d ret.(%s)\n",from_basilisk,retstr); - if ( from_basilisk != 0 || strcmp(CMD,"GET") == 0 ) - basilisk_sendback(myinfo,CMD,symbol,remoteaddr,basilisktag,retstr); - if ( retstr != 0 ) - free(retstr); - } //else printf("services null return\n"); - } else printf("non-relay got unexpected.(%s)\n",type); - /*free_json(valsobj); - if ( coin != 0 ) - coin->basilisk_busy = 0; - myinfo->basilisk_busy = 0; - return;*/ - } - } - /*if ( coin != 0 ) - { - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node - { - if ( 0 && from_basilisk != 0 ) - { - printf("echo to other relays\n"); - basilisk_sendcmd(myinfo,0,cmd,&basilisktag,0,0,origdata,origlen,-1,0); // to other iguanas - } - for (i=0; ibasilisk_busy = 0; - myinfo->basilisk_busy = 0; -} - - diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index 28c03de01..a2a6d2200 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,13 +14,14 @@ ******************************************************************************/ #include "../iguana/iguana777.h" +#include "../iguana/exchanges777.h" typedef char *basilisk_servicefunc(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk); -int32_t basilisk_specialcmd(char *cmd) +int32_t basilisk_notarycmd(char *cmd) { //&& strcmp(cmd,"DEX") != 0 && strcmp(cmd,"ACC") != 0 && strcmp(cmd,"RID") != 0 && - if ( strcmp(cmd,"PIN") != 0 && strcmp(cmd,"OUT") != 0 && strcmp(cmd,"MSG") != 0 ) + if ( strcmp(cmd,"PIN") != 0 && strcmp(cmd,"OUT") != 0 && strcmp(cmd,"MSG") != 0 && strcmp(cmd,"VOT") != 0 ) return(0); else return(1); } @@ -32,6 +33,55 @@ int32_t basilisk_specialcmd(char *cmd) else return(0); }*/ +cJSON *basilisk_utxosweep(struct supernet_info *myinfo,char *symbol,int64_t *satoshis,uint64_t limit,int32_t maxvins,char *coinaddr) +{ + int32_t i,n,numvins = 0; char *retstr; uint64_t value,biggest = 0; struct iguana_info *coin=0; cJSON *item,*biggestitem=0,*array,*utxos = 0; + coin = iguana_coinfind(symbol); + if ( (retstr= dex_listunspent(myinfo,coin,0,0,symbol,coinaddr)) != 0 ) + { + //printf("(%s)\n",retstr); + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + n = cJSON_GetArraySize(array); + for (i=0; i biggest ) + { + //fprintf(stderr,"biggest! "); + if ( biggestitem != 0 ) + free_json(biggestitem); + biggestitem = jduplicate(item); + *satoshis = biggest = value; + } //else fprintf(stderr,"> "); + } + } + free_json(array); + if ( utxos == 0 && biggestitem != 0 ) + { + fprintf(stderr,"add biggest.(%s)\n",jprint(biggestitem,0)); + jaddi(utxos,biggestitem); + } + } + free(retstr); + } + return(utxos); +} + uint32_t basilisk_calcnonce(struct supernet_info *myinfo,uint8_t *data,int32_t datalen,uint32_t nBits) { int32_t i,numiters = 0; bits256 hash,hash2,threshold; uint32_t basilisktag; @@ -48,8 +98,8 @@ uint32_t basilisk_calcnonce(struct supernet_info *myinfo,uint8_t *data,int32_t d break; } iguana_rwnum(0,(void *)hash.uints,sizeof(basilisktag),&basilisktag); - iguana_rwnum(1,&data[-sizeof(basilisktag)],sizeof(basilisktag),&basilisktag); - char str[65],str2[65]; printf("found hash after numiters.%d %s vs %s basilisktag.%u\n",numiters,bits256_str(str,threshold),bits256_str(str2,hash2),basilisktag); + iguana_rwnum(1,&data[-(int32_t)sizeof(basilisktag)],sizeof(basilisktag),&basilisktag); + //char str[65],str2[65]; printf("found hash after numiters.%d %s vs %s basilisktag.%u\n",numiters,bits256_str(str,threshold),bits256_str(str2,hash2),basilisktag); return(basilisktag); } @@ -95,7 +145,7 @@ uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int32_t spacesize,int32_t *datalenp,char *symbol,cJSON *sendjson,uint32_t basilisktag) { - char *sendstr,*hexstr=0; uint8_t *data,hexspace[4096],*allocptr=0,*hexdata; int32_t datalen,hexlen=0; + char *sendstr,*hexstr=0; uint8_t *data,hexspace[4096],*allocptr=0,*hexdata=0; int32_t datalen,hexlen=0; if ( jobj(sendjson,"symbol") == 0 ) jaddstr(sendjson,"symbol",symbol); if ( (hexstr= jstr(sendjson,"data")) != 0 ) @@ -118,7 +168,7 @@ uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int memcpy(data,sendstr,datalen); //printf("jsondata.(%s) + hexlen.%d\n",sendstr,hexlen); free(sendstr); - if ( hexlen > 0 ) + if ( hexlen > 0 && hexdata != 0 ) { //int32_t i; for (i=0; ibasilisktag = basilisktag; - if ( (ptr->numrequired= minresults) == 0 ) + if ( (ptr->numrequired= numrequired) == 0 ) ptr->numrequired = 1; strcpy(ptr->CMD,CMD); safecopy(ptr->symbol,symbol,sizeof(ptr->symbol)); + ptr->duration = timeoutmillis; ptr->expiration = OS_milliseconds() + timeoutmillis; + //printf("itemcreate.%p %s %f timeout.%d\n",ptr,CMD,OS_milliseconds(),timeoutmillis); return(ptr); } int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *type,uint32_t *basilisktagp,int32_t encryptflag,int32_t delaymillis,uint8_t *data,int32_t datalen,int32_t fanout,uint32_t nBits) // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) { - int32_t i,l,s,valid,val,n=0,retval = -1; char cmd[12]; struct iguana_info *coin,*tmp; struct iguana_peer *addr; bits256 hash; uint32_t *alreadysent,r,r2; + int32_t i,l,s,valid,val,n=0,retval = -1; char cmd[12]; struct iguana_info *coin,*tmp; struct iguana_peer *addr; bits256 hash; uint32_t *alreadysent,r; if ( fanout <= 0 ) - fanout = sqrt(NUMRELAYS) + 1; + fanout = sqrt(myinfo->NOTARY.NUMRELAYS) + 1; else if ( fanout > BASILISK_MAXFANOUT ) fanout = BASILISK_MAXFANOUT; if ( type == 0 ) - type = "BTCD"; + type = "INF"; if ( strlen(type) > 3 ) { printf("basilisk_sendcmd illegal type(%s)\n",type); @@ -162,7 +214,9 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ if ( destipaddr != 0 ) { if ( destipaddr[0] == 0 ) + { destipaddr = 0; // broadcast + } else if ( strcmp(destipaddr,"127.0.0.1") == 0 || strcmp(destipaddr,myinfo->ipaddr) == 0 ) { printf("return after locally basilisk_msgprocess\n"); @@ -171,27 +225,56 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ return(0); } } - alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); - iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); + iguana_rwnum(1,&data[-(int32_t)sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); if ( *basilisktagp == 0 ) { if ( nBits != 0 ) *basilisktagp = basilisk_calcnonce(myinfo,data,datalen,nBits); else *basilisktagp = rand(); - iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); + iguana_rwnum(1,&data[-(int32_t)sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); } data -= sizeof(*basilisktagp), datalen += sizeof(*basilisktagp); memset(cmd,0,sizeof(cmd)); sprintf(cmd,"SuperNET%s",type); + if ( destipaddr != 0 ) + { + cmd[6] = 'E', cmd[7] = 'T'; + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->peers == 0 ) + continue; + if ( coin->FULLNODE == 0 && coin->VALIDATENODE == 0 ) + cmd[0] = 's'; + else cmd[0] = 'S'; + for (i=0; ipeers->active[i]; + if ( addr->usock >= 0 && strcmp(addr->ipaddr,destipaddr) == 0 ) + { + return(iguana_queue_send(addr,delaymillis,&data[-(int32_t)sizeof(struct iguana_msghdr)],cmd,datalen)); + } + } + } + return(-1); + } + if ( basilisk_notarycmd(type) != 0 && myinfo->NOTARY.NUMRELAYS == 0 ) + { + //printf("no notary nodes to send (%s) to\n",type); + return(-1); + } //portable_mutex_lock(&myinfo->allcoins_mutex); + //dex_reqsend(myinfo,&data[-(int32_t)sizeof(struct iguana_msghdr)],datalen); + alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); HASH_ITER(hh,myinfo->allcoins,coin,tmp) { if ( coin->peers == 0 ) continue; + if ( basilisk_notarycmd(type) != 0 && strcmp(coin->symbol,"RELAY") != 0 ) + continue; if ( coin->FULLNODE == 0 && coin->VALIDATENODE == 0 ) cmd[0] = 's'; else cmd[0] = 'S'; - r = rand() % (coin->peers->numranked+1); + r = rand() % IGUANA_MAXPEERS; for (l=0; lusock >= 0 ) { s = 0; - if ( NUMRELAYS > 0 && basilisk_specialcmd(type) != 0 ) + valid = (addr->supernet != 0); + if ( basilisk_notarycmd(type) != 0 || (strcmp(type,"INF") == 0 && strcmp(coin->symbol,"RELAY") == 0) ) { - OS_randombytes((void *)&r2,sizeof(r2)); - if ( (r2 % NUMRELAYS) >= sqrt(NUMRELAYS) ) + valid = 0; + /*OS_randombytes((void *)&r2,sizeof(r2)); + if ( (r2 % myinfo->NOTARY.NUMRELAYS) >= sqrt(myinfo->NOTARY.NUMRELAYS) ) { - //printf("fanout.%d s.%d n.%d skip %s\n",fanout,s,n,addr->ipaddr); + printf("fanout.%d s.%d n.%d skip %s\n",fanout,s,n,addr->ipaddr); continue; - } - for (s=0; sipbits != myinfo->myaddr.myipbits && RELAYS[s].ipbits == addr->ipbits ) + }*/ + for (s=0; sNOTARY.NUMRELAYS; s++) + if ( addr->ipbits != myinfo->myaddr.myipbits && myinfo->NOTARY.RELAYS[s].ipbits == addr->ipbits ) break; - if ( s == NUMRELAYS ) + if ( s == myinfo->NOTARY.NUMRELAYS ) { //printf("skip non-relay.(%s)\n",addr->ipaddr); continue; } - //printf("send to other relay.(%s)\n",addr->ipaddr); valid = 1; + //printf("send to other relay.(%s)\n",addr->ipaddr); } for (s=0; sipbits ) { - printf("already sent to %s\n",addr->ipaddr); + //printf("already sent to %s\n",addr->ipaddr); continue; } if ( s == n && valid == 1 && (destipaddr == 0 || strcmp(addr->ipaddr,destipaddr) == 0) ) { - //printf("n.%d/fanout.%d i.%d l.%d [%s].tag%d send %s.(%s) [%x] datalen.%d addr->supernet.%u basilisk.%u to (%s).%d destip.%s\n",n,fanout,i,l,cmd,*(uint32_t *)data,type,(char *)&data[4],*(int32_t *)&data[datalen-4],datalen,addr->supernet,addr->basilisk,addr->ipaddr,addr->A.port,destipaddr!=0?destipaddr:"broadcast"); + val = 0; + //fprintf(stderr,">>> (%s).%u ",addr->ipaddr,coin->chain->portp2p); + //printf("n.%d/fanout.%d i.%d l.%d [%s].tag%u send %s [%x] datalen.%d addr->supernet.%u basilisk.%u to (%s).%d destip.%s\n",n,fanout,i,l,cmd,*(uint32_t *)data,type,*(int32_t *)&data[datalen-4],datalen,addr->supernet,addr->basilisk,addr->ipaddr,addr->A.port,destipaddr!=0?destipaddr:"broadcast"); if ( encryptflag != 0 && bits256_nonz(addr->pubkey) != 0 ) { void *ptr; uint8_t *cipher,space[8192]; int32_t cipherlen; bits256 privkey; @@ -237,7 +324,7 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ memset(privkey.bytes,0,sizeof(privkey)); if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&addr->pubkey,data,datalen,space,sizeof(space))) != 0 ) { - if ( (val= iguana_queue_send(addr,delaymillis,&cipher[-sizeof(struct iguana_msghdr)],cmd,cipherlen)) >= cipherlen ) + if ( (val= iguana_queue_send(addr,delaymillis,&cipher[-(int32_t)sizeof(struct iguana_msghdr)],cmd,cipherlen)) >= cipherlen ) alreadysent[n++] = (uint32_t)addr->ipbits; if ( ptr != 0 ) free(ptr); @@ -246,7 +333,7 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ else { cmd[6] = 'E', cmd[7] = 'T'; - if ( (val= iguana_queue_send(addr,delaymillis,&data[-sizeof(struct iguana_msghdr)],cmd,datalen)) >= datalen ) + if ( (val= iguana_queue_send(addr,delaymillis,&data[-(int32_t)sizeof(struct iguana_msghdr)],cmd,datalen)) >= datalen ) { alreadysent[n++] = (uint32_t)addr->ipbits; if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) @@ -287,7 +374,8 @@ void basilisk_sendback(struct supernet_info *myinfo,char *origCMD,char *symbol,c if ( (virt= iguana_coinfind(symbol)) != 0 ) { jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); - jaddbits256(valsobj,"chaintip",virt->blocks.hwmchain.RO.hash2); + if ( bits256_nonz(virt->blocks.hwmchain.RO.hash2) != 0 ) + jaddbits256(valsobj,"chaintip",virt->blocks.hwmchain.RO.hash2); } data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); //printf("sendback.%d -> %s\n",datalen,remoteaddr); @@ -299,10 +387,10 @@ void basilisk_sendback(struct supernet_info *myinfo,char *origCMD,char *symbol,c } } -struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,struct iguana_peer *addr,int32_t *numsentp,char *CMD,char *symbol,int32_t blockflag,cJSON *valsobj,int32_t fanout,int32_t minresults,uint32_t basilisktag,int32_t timeoutmillis,void *deprecated_dontuse,char *retstr,int32_t encryptflag,int32_t delaymillis,uint32_t nBits) +struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,struct iguana_peer *addr,int32_t *numsentp,char *CMD,char *symbol,int32_t blockflag,cJSON *valsobj,int32_t fanout,int32_t numrequired,uint32_t basilisktag,int32_t timeoutmillis,void *deprecated_dontuse,char *retstr,int32_t encryptflag,int32_t delaymillis,uint32_t nBits) { - struct basilisk_item *pending; uint8_t *allocptr,*data,space[4096]; int32_t datalen; cJSON *retarray; - pending = basilisk_itemcreate(myinfo,CMD,symbol,basilisktag,minresults,valsobj,timeoutmillis,0); + struct basilisk_item *pending; uint8_t *allocptr,*data,space[4096]; int32_t datalen; + pending = basilisk_itemcreate(myinfo,CMD,symbol,basilisktag,numrequired,valsobj,timeoutmillis,0); pending->nBits = nBits; *numsentp = 0; if ( retstr != 0 ) @@ -319,32 +407,26 @@ struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,struct i if ( blockflag != 0 ) { portable_mutex_lock(&myinfo->basilisk_mutex); - //printf("HASH_ADD.%p\n",pending); HASH_ADD(hh,myinfo->basilisks.issued,basilisktag,sizeof(basilisktag),pending); portable_mutex_unlock(&myinfo->basilisk_mutex); - //queue_enqueue("issuedQ",&myinfo->basilisks.issued,&pending->DL,0); if ( pending->expiration <= OS_milliseconds() ) - pending->expiration = OS_milliseconds() + BASILISK_TIMEOUT; - //ptr->vals = jduplicate(valsobj); - strcpy(pending->symbol,"BTCD"); + pending->expiration = OS_milliseconds() + pending->duration; + strcpy(pending->symbol,"RELAY"); strcpy(pending->CMD,CMD); + //printf("block for %f\n",pending->expiration - OS_milliseconds()); while ( OS_milliseconds() < pending->expiration ) { - if ( pending->numresults >= pending->numrequired )//|| (retstr= pending->retstr) != 0 ) + portable_mutex_lock(&myinfo->basilisk_mutex); + if ( pending->numresults >= pending->numrequired ) { - //printf("numresults.%d vs numrequired.%d\n",pending->numresults,pending->numrequired); + portable_mutex_unlock(&myinfo->basilisk_mutex); + //printf("%p <<<<<<<<<<<<< numresults.%d vs numrequired.%d\n",pending,pending->numresults,pending->numrequired); break; } + portable_mutex_unlock(&myinfo->basilisk_mutex); usleep(10000); } - if ( (retarray= pending->retarray) != 0 ) - { - pending->retstr = jprint(retarray,0); - pending->retarray = 0; - free_json(retarray); - } - //return(basilisk_waitresponse(myinfo,CMD,"BTCD",0,&Lptr,valsobj,ptr)); - } else free(pending), pending = 0; //ptr->finished = (uint32_t)time(NULL); + } if ( allocptr != 0 ) free(allocptr); } @@ -356,22 +438,26 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struc int32_t minfanout,numrequired,timeoutmillis,numsent,delaymillis,encryptflag,fanout; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt; //printf("request.(%s)\n",jprint(valsobj,0)); basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen); - if ( bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0 ) + if ( str != 0 ) + free(str); + if ( bits256_nonz(hash) == 0 || (bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0) ) { if ( jobj(valsobj,"hash") != 0 ) jdelete(valsobj,"hash"); jaddbits256(valsobj,"hash",hash); } - if ( (numrequired= jint(valsobj,"numrequired")) <= 0 ) - numrequired = sqrt(NUMRELAYS); if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) timeoutmillis = BASILISK_TIMEOUT; - minfanout = sqrt(NUMRELAYS)+1; + minfanout = sqrt(myinfo->NOTARY.NUMRELAYS)+1; + if ( minfanout < 8 ) + minfanout = 8; if ( jobj(valsobj,"fanout") == 0 ) fanout = minfanout; else fanout = jint(valsobj,"fanout"); if ( fanout < minfanout ) fanout = minfanout; + if ( (numrequired= jint(valsobj,"numrequired")) <= 0 ) + numrequired = MIN(fanout/2,sqrt(myinfo->NOTARY.NUMRELAYS)+1); if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) { if ( (virt= iguana_coinfind(symbol)) != 0 ) @@ -382,7 +468,7 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struc } } if ( symbol == 0 ) - symbol = "BTCD"; + symbol = "RELAY"; encryptflag = jint(valsobj,"encrypt"); delaymillis = jint(valsobj,"delay"); ptr = basilisk_issueremote(myinfo,addr,&numsent,CMD,symbol,blockflag,valsobj,fanout,numrequired,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); @@ -391,31 +477,42 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struc char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,void *_addr,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag) // client side { - uint32_t nBits = 0; uint8_t space[4096],*allocptr=0,*data = 0; struct basilisk_item *ptr; int32_t datalen = 0; cJSON *retjson; char *retstr=0; - if ( RELAYID >= 0 && basilisk_specialcmd(CMD) == 0 ) + uint32_t nBits = 0; uint8_t space[4096],*allocptr=0,*data = 0; struct basilisk_item *ptr; int32_t i,datalen = 0; cJSON *retjson; char *retstr=0; + if ( myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0 && (strcmp(CMD,"INF") != 0 && basilisk_notarycmd(CMD) == 0) ) return(clonestr("{\"error\":\"unsupported special relay command\"}")); data = get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr); +//printf("request.(%s)\n",jprint(valsobj,0)); ptr = basilisk_requestservice(myinfo,_addr,CMD,blockflag,valsobj,hash,data,datalen,nBits); if ( allocptr != 0 ) free(allocptr); if ( ptr != 0 ) { - if ( ptr->retstr != 0 ) - retstr = ptr->retstr, ptr->retstr = 0; + if ( (retstr= ptr->retstr) != 0 ) + ptr->retstr = 0; else { - retjson = cJSON_CreateObject(); - if ( ptr->numsent > 0 ) + if ( ptr->numresults > 0 ) { - //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"numsent",ptr->numsent); - } else jaddstr(retjson,"error","didnt find any nodes to send to"); + retjson = cJSON_CreateArray(); + for (i=0; inumresults; i++) + jaddi(retjson,ptr->results[i]), ptr->results[i] = 0; + //printf("numresults.%d (%p)\n",ptr->numresults,ptr); + } + else + { + retjson = cJSON_CreateObject(); + if ( ptr->numsent > 0 ) + { + //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + jaddstr(retjson,"result","error"); + jaddnum(retjson,"packetsize",ptr->numsent); + } else jaddstr(retjson,"error","didnt find any nodes to send to"); + } retstr = jprint(retjson,1); } - ptr->finished = (uint32_t)time(NULL); + ptr->finished = OS_milliseconds() + 10000; } - if ( 1 && strcmp("RID",CMD) != 0 && strcmp("BAL",CMD) != 0 && strcmp("MSG",CMD) != 0 ) + if ( (0) && strcmp("MSG",CMD) == 0 ) printf("%s.(%s) -> (%s)\n",CMD,jprint(valsobj,0),retstr!=0?retstr:""); return(retstr); } @@ -423,8 +520,8 @@ char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,void *_add int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits) { int32_t j; - for (j=0; jNOTARY.NUMRELAYS; j++) + if ( myinfo->NOTARY.RELAYS[j].ipbits == ipbits ) return(j); return(-1); } @@ -434,13 +531,18 @@ int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits) #include "basilisk_ether.c" #include "basilisk_waves.c" #include "basilisk_lisk.c" +#include "smartaddress.c" #include "basilisk_MSG.c" +#include "tradebots_marketmaker.c" +#include "tradebots_liquidity.c" #include "basilisk_tradebot.c" #include "basilisk_swap.c" #include "basilisk_DEX.c" #include "basilisk_ping.c" +#include "basilisk_vote.c" #include "basilisk_CMD.c" +#include "jumblr.c" void basilisk_functions(struct iguana_info *coin,int32_t protocol) { @@ -479,7 +581,7 @@ void basilisk_functions(struct iguana_info *coin,int32_t protocol) int32_t basilisk_hashes_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,char *CMD,bits256 *hashes,int32_t num) { - bits256 hash; uint8_t *serialized; int32_t i,len = 0; char *str=0,*retstr,*hexstr,*allocptr=0,space[4096]; bits256 txid; cJSON *vals; + bits256 hash; uint8_t *serialized; int32_t i,len = 0; char *str=0,*retstr,*hexstr,space[4096]; bits256 txid; cJSON *vals; if ( virt != 0 && addr != 0 ) { memset(hash.bytes,0,sizeof(hash)); @@ -496,8 +598,8 @@ int32_t basilisk_hashes_send(struct supernet_info *myinfo,struct iguana_info *vi if ( (retstr= basilisk_standardservice(CMD,myinfo,addr,hash,vals,hexstr,0)) != 0 ) free(retstr); free_json(vals); - if ( allocptr != 0 ) - free(allocptr); + if ( str != 0 ) + free(str); } return(0); } else return(-1); @@ -540,29 +642,30 @@ void basilisk_result(struct supernet_info *myinfo,char *remoteaddr,uint32_t basi { retstr = jprint(vals,0); safecopy(CMD,jstr(vals,"origcmd"),sizeof(CMD)); - if ( 0 && strcmp("RID",CMD) != 0 ) - printf("(%s) -> Q.%u results vals.(%s)\n",CMD,basilisktag,retstr); + //if ( 0 && strcmp("RID",CMD) != 0 ) + //printf("(%s) -> Q.%u results vals.(%s)\n",CMD,basilisktag,retstr);//(int32_t)strlen(retstr)); if ( strcmp(CMD,"GET") == 0 ) basilisk_geckoresult(myinfo,remoteaddr,retstr,data,datalen); else { portable_mutex_lock(&myinfo->basilisk_mutex); HASH_FIND(hh,myinfo->basilisks.issued,&basilisktag,sizeof(basilisktag),pending); - //printf("HASH_FIND.%p\n",pending); portable_mutex_unlock(&myinfo->basilisk_mutex); if ( pending != 0 && retstr != 0 ) { if ( (item= cJSON_Parse(retstr)) != 0 ) { - if ( pending->retarray == 0 ) - pending->retarray = cJSON_CreateArray(); if ( jobj(item,"myip") == 0 ) - jaddstr(item,"myip",myinfo->ipaddr); - jaddi(pending->retarray,item); + jaddstr(item,"myip",remoteaddr); + if ( pending->numresults < sizeof(pending->results)/sizeof(*pending->results) ) + { + //printf("%p.(%s).%d\n",pending,jprint(item,0),pending->numresults); + pending->results[pending->numresults++] = item; + } } else printf("couldnt parse.(%s)\n",retstr); - pending->numresults++; } //else printf("couldnt find issued.%u\n",basilisktag); } + free(retstr); } } @@ -588,7 +691,9 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende { (void *)"OUT", &basilisk_respond_OUT }, // send MSG to hash/id/num { (void *)"MSG", &basilisk_respond_MSG }, // get MSG (hash, id, num) { (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus + { (void *)"VOT", &basilisk_respond_VOT }, // VOTE handler for something //{ (void *)"PIN", &basilisk_respond_PIN }, + // encrypted data for jumblr { (void *)"HOP", &basilisk_respond_forward }, // message forwarding { (void *)"BOX", &basilisk_respond_mailbox }, // create/send/check mailbox pubkey @@ -616,6 +721,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende // coin services { (void *)"VAL", &basilisk_respond_value }, { (void *)"BAL", &basilisk_respond_balances }, + { (void *)"INF", &basilisk_respond_getinfo }, }; strncpy(CMD,type,3), CMD[3] = cmd[3] = 0; if ( isupper((int32_t)CMD[0]) != 0 && isupper((int32_t)CMD[1]) != 0 && isupper((int32_t)CMD[2]) != 0 ) @@ -628,22 +734,18 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende CMD[i] = toupper((int32_t)CMD[i]); cmd[i] = tolower((int32_t)CMD[i]); } - //origcmd[0] = 0; - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 )//RELAYID >= 0 ) { - if ( basilisk_specialcmd(CMD) == 0 ) + if ( basilisk_notarycmd(CMD) == 0 && strcmp(CMD,"INF") != 0 ) return; - //printf("MSGPROCESS %s.(%s) tag.%d\n",CMD,(char *)data,basilisktag); - } - symbol = "BTCD"; + } else if ( basilisk_notarycmd(CMD) != 0 ) + return; + symbol = "RELAY"; if ( senderipbits == 0 ) expand_ipbits(remoteaddr,myinfo->myaddr.myipbits); else expand_ipbits(remoteaddr,senderipbits); if ( (valsobj= cJSON_Parse((char *)data)) != 0 ) { - //if ( origcmd[0] != 0 ) - // jaddstr(valsobj,"origcmd",origcmd); - //printf("MSGVALS.(%s)\n",(char *)data); if ( jobj(valsobj,"coin") != 0 ) coin = iguana_coinfind(jstr(valsobj,"coin")); else if ( jobj(valsobj,"symbol") != 0 ) @@ -685,7 +787,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende data += jsonlen, datalen -= jsonlen; else data = 0, datalen = 0; if ( coin == 0 ) - coin = iguana_coinfind("BTCD"); + coin = iguana_coinfind(symbol); if ( coin != 0 ) { symbol = coin->symbol; @@ -694,7 +796,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende hash = jbits256(valsobj,"hash"); timeoutmillis = jint(valsobj,"timeout"); if ( (numrequired= jint(valsobj,"numrequired")) == 0 ) - numrequired = sqrt(NUMRELAYS); + numrequired = sqrt(myinfo->NOTARY.NUMRELAYS)+1; if ( senderipbits != 0 ) expand_ipbits(remoteaddr,senderipbits); else remoteaddr[0] = 0; @@ -702,19 +804,19 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende { if ( strcmp((char *)basilisk_services[i][0],type) == 0 ) { - if ( coin->FULLNODE != 0 || RELAYID >= 0 ) // iguana node + if ( (coin != 0 && coin->FULLNODE > 0) || myinfo->NOTARY.RELAYID >= 0 ) // iguana node { - //printf("services %s\n",type); + //printf("\n call %s from_basilisk.%d (%s)\n",addr->ipaddr,from_basilisk,type); if ( (retstr= (*basilisk_services[i][1])(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk)) != 0 ) { - //printf("from_basilisk.%d ret.(%s)\n",from_basilisk,retstr); + //printf("%s from_basilisk.%d ret.(%s)\n",addr->ipaddr,from_basilisk,retstr); //if ( from_basilisk != 0 || strcmp(CMD,"GET") == 0 ) basilisk_sendback(myinfo,CMD,symbol,remoteaddr,basilisktag,retstr); if ( retstr != 0 ) free(retstr); break; } else printf("services null return\n"); - } else printf("non-relay got unhandled.(%s)\n",type); + } else printf("non-relay got %s unhandled.(%s)\n",coin!=0?coin->symbol:"",type); } } free_json(valsobj); @@ -724,9 +826,55 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende myinfo->basilisk_busy = 0; } -void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t datalen,char *type,int32_t encrypted) +int32_t basilisk_p2pQ_process(struct supernet_info *myinfo,int32_t maxiters) +{ + struct basilisk_p2pitem *ptr; char senderip[64]; uint32_t n=0,basilisktag,len; + while ( n < maxiters && (ptr= queue_dequeue(&myinfo->p2pQ)) != 0 ) + { + len = 0; + expand_ipbits(senderip,ptr->ipbits); + //printf("p2p.%d from.(%s) %c%c%c datalen.%d\n",n,senderip,ptr->type[0],ptr->type[1],ptr->type[2],ptr->datalen); + if ( ptr->type[0] == 'P' && ptr->type[1] == 'I' && ptr->type[2] == 'N' ) + { + if ( myinfo->NOTARY.RELAYID >= 0 ) + { + //printf("process ping\n"); + basilisk_ping_process(myinfo,ptr->addr,ptr->ipbits,ptr->data,ptr->datalen); + //printf("done process ping\n"); + } + } + else + { + len += iguana_rwnum(0,ptr->data,sizeof(basilisktag),&basilisktag); + if ( (0) && myinfo->IAMLP == 0 ) + printf("RELAYID.%d ->received.%d basilisk_p2p.(%s) from %s tag.%u\n",myinfo->NOTARY.RELAYID,ptr->datalen,ptr->type,senderip,basilisktag); + basilisk_msgprocess(myinfo,ptr->addr,ptr->ipbits,ptr->type,basilisktag,&ptr->data[len],ptr->datalen - len); + if ( (0) && myinfo->IAMLP == 0 ) + printf("processed.%s from %s\n",ptr->type,senderip); + } + free(ptr); + n++; + } + return(n); +} + +struct basilisk_p2pitem *basilisk_p2pitem_create(struct iguana_info *coin,struct iguana_peer *addr,char *type,uint32_t ipbits,uint8_t *data,int32_t datalen) +{ + struct basilisk_p2pitem *ptr; + ptr = calloc(1,sizeof(*ptr) + datalen + 16); + ptr->coin = coin; + ptr->addr = addr; + ptr->ipbits = ipbits; + ptr->datalen = datalen; + safecopy(ptr->type,type,sizeof(ptr->type)); + memcpy(ptr->data,data,datalen); + return(ptr); +} + +void basilisk_p2p(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *senderip,uint8_t *data,int32_t datalen,char *type,int32_t encrypted) { - uint32_t ipbits,basilisktag; int32_t msglen,len=0; void *ptr = 0; uint8_t space[4096]; bits256 senderpub; struct supernet_info *myinfo = _myinfo; + uint32_t ipbits; int32_t msglen; void *ptr = 0; uint8_t space[4096]; bits256 senderpub; + ipbits = (uint32_t)calc_ipbits(senderip); if ( encrypted != 0 ) { printf("encrypted p2p\n"); @@ -736,141 +884,116 @@ void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t printf("basilisk_p2p decrytion error\n"); return; } else datalen = msglen; + if ( ptr != 0 ) + free(ptr); } if ( senderip != 0 && senderip[0] != 0 && strcmp(senderip,"127.0.0.1") != 0 ) ipbits = (uint32_t)calc_ipbits(senderip); else ipbits = myinfo->myaddr.myipbits; - if ( type[0] == 'P' && type[1] == 'I' && type[2] == 'N' ) - { - if ( strcmp(type,"PIN") == 0 && RELAYID >= 0 ) - { - basilisk_ping_process(myinfo,_addr,ipbits,data,datalen); - } - } - else - { - len += iguana_rwnum(0,data,sizeof(basilisktag),&basilisktag); - //int32_t i; for (i=0; i= 0 ) - printf(" ->received.%d basilisk_p2p.(%s) from %s tag.%d\n",datalen,type,senderip!=0?senderip:"?",basilisktag); - basilisk_msgprocess(myinfo,_addr,ipbits,type,basilisktag,&data[len],datalen - len); - } - if ( ptr != 0 ) - free(ptr); + ptr = basilisk_p2pitem_create(coin,addr,type,ipbits,data,datalen); + queue_enqueue("p2pQ",&myinfo->p2pQ,ptr); } -void basilisk_requests_poll(struct supernet_info *myinfo) +int32_t basilisk_issued_purge(struct supernet_info *myinfo,int32_t timepad) { - char *retstr; cJSON *outerarray; int32_t i,n; struct basilisk_request issueR; double hwm = 0.; - memset(&issueR,0,sizeof(issueR)); - if ( (retstr= InstantDEX_incoming(myinfo,0,0,0,0)) != 0 ) - { - //printf("poll.(%s)\n",retstr); - if ( (outerarray= cJSON_Parse(retstr)) != 0 ) - { - if ( is_cJSON_Array(outerarray) != 0 ) - { - n = cJSON_GetArraySize(outerarray); - for (i=0; i 0. ) + struct basilisk_item *tmp,*pending; cJSON *item; int32_t i,n = 0; double startmilli = OS_milliseconds(); + portable_mutex_lock(&myinfo->basilisk_mutex); + HASH_ITER(hh,myinfo->basilisks.issued,pending,tmp) { - if ( bits256_cmp(myinfo->myaddr.persistent,issueR.hash) == 0 ) // my request + if ( pending != 0 && ((pending->finished > 0 && startmilli > pending->finished) || startmilli > pending->expiration+timepad) ) { - printf("my req hwm %f\n",hwm); - if ( (retstr= InstantDEX_accept(myinfo,0,0,0,issueR.requestid,issueR.quoteid)) != 0 ) - free(retstr); - if ( (retstr= basilisk_start(myinfo,&issueR,1)) != 0 ) - free(retstr); + HASH_DELETE(hh,myinfo->basilisks.issued,pending); + //printf("%f > %f (%d) clear pending.%p numresults.%d %p\n",startmilli,pending->expiration+timepad,timepad,pending,pending->numresults,pending->retstr); + for (i=0; inumresults; i++) + if ( (item= pending->results[i]) != 0 ) + free_json(item); + if ( pending->retstr != 0 ) + free(pending->retstr); + memset(pending,0,sizeof(*pending)); + free(pending); + n++; } - else //if ( issueR.quoteid == 0 ) - { - printf("other req hwm %f\n",hwm); - issueR.quoteid = basilisk_quoteid(&issueR); - issueR.desthash = myinfo->myaddr.persistent; - if ( (retstr= basilisk_start(myinfo,&issueR,0)) != 0 ) - free(retstr); - } //else printf("basilisk_requests_poll unexpected hwm issueR\n"); } + portable_mutex_unlock(&myinfo->basilisk_mutex); + return(n); } void basilisks_loop(void *arg) { - struct iguana_info *virt,*tmpcoin,*coin,*btcd; struct basilisk_message *msg,*tmpmsg; struct basilisk_item *tmp,*pending; uint32_t now; int32_t iter,maxmillis,flag=0; struct supernet_info *myinfo = arg; + static uint32_t counter; + struct iguana_info *relay; struct supernet_info *myinfo = arg; int32_t i,iter; double startmilli,endmilli; struct dpow_info *dp; iter = 0; + relay = iguana_coinfind("RELAY"); + printf("start basilisk loop\n"); while ( 1 ) { - portable_mutex_lock(&myinfo->basilisk_mutex); - HASH_ITER(hh,myinfo->basilisks.issued,pending,tmp) + if ( relay == 0 ) + relay = iguana_coinfind("RELAY"); + startmilli = OS_milliseconds(); + endmilli = startmilli + 1000; + //fprintf(stderr,"A "); + basilisk_issued_purge(myinfo,600000); + //fprintf(stderr,"B "); + basilisk_p2pQ_process(myinfo,777); + //fprintf(stderr,"C "); + if ( myinfo->IAMNOTARY != 0 ) { - if ( pending != 0 && (pending->finished != 0 || OS_milliseconds() > pending->expiration+600000) ) + if ( relay != 0 ) { - //printf("enable free for HASH_DELETE.(%p)\n",pending); - HASH_DELETE(hh,myinfo->basilisks.issued,pending); - memset(pending,0,sizeof(*pending)); - free(pending); + //fprintf(stderr,"D "); + basilisk_ping_send(myinfo,relay); } - } - portable_mutex_unlock(&myinfo->basilisk_mutex); - if ( (btcd= iguana_coinfind("BTCD")) != 0 ) - { - maxmillis = (1000 / (myinfo->allcoins_numvirts + 1)) + 1; - //portable_mutex_lock(&myinfo->allcoins_mutex); - HASH_ITER(hh,myinfo->allcoins,virt,tmpcoin) + counter++; + //fprintf(stderr,"E "); + if ( myinfo->numdpows == 1 ) { - if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) - { - gecko_iteration(myinfo,btcd,virt,maxmillis), flag++; - } + iguana_dPoWupdate(myinfo,&myinfo->DPOWS[0]); + endmilli = startmilli + 100; } - //portable_mutex_unlock(&myinfo->allcoins_mutex); - if ( RELAYID >= 0 ) + else if ( myinfo->numdpows > 1 ) { - basilisk_ping_send(myinfo,btcd); + dp = &myinfo->DPOWS[counter % myinfo->numdpows]; + iguana_dPoWupdate(myinfo,dp); + //if ( (counter % myinfo->numdpows) != 0 ) + { + //fprintf(stderr,"F "); + iguana_dPoWupdate(myinfo,&myinfo->DPOWS[0]); + } + endmilli = startmilli + 30; } + //fprintf(stderr,"F "); } - HASH_ITER(hh,myinfo->allcoins,coin,tmpcoin) + else { - if ( time(NULL) > coin->lastunspentsupdate+10 ) - { - //printf(">>>>>>>>>>>>> update\n"); - basilisk_unspents_update(myinfo,coin); - coin->lastunspentsupdate = (uint32_t)time(NULL); - } + //fprintf(stderr,"G "); + dex_updateclient(myinfo); + if ( myinfo->IAMLP != 0 ) + endmilli = startmilli + 500; + else endmilli = startmilli + 1000; } - if ( RELAYID < 0 ) - basilisk_requests_poll(myinfo); - now = (uint32_t)time(NULL); - portable_mutex_lock(&myinfo->messagemutex); - HASH_ITER(hh,myinfo->messagetable,msg,tmpmsg) + if ( myinfo->expiration != 0 && (myinfo->dexsock >= 0 || myinfo->IAMLP != 0 || myinfo->DEXactive > time(NULL)) ) { - if ( now > msg->expiration ) - { - printf("delete expired message.%p QUEUEITEMS.%d\n",msg,QUEUEITEMS); - HASH_DELETE(hh,myinfo->messagetable,msg); - QUEUEITEMS--; - free(msg); - } + //fprintf(stderr,"H "); + for (i=0; i<100; i++) + if ( basilisk_requests_poll(myinfo) <= 0 ) + break; } - portable_mutex_unlock(&myinfo->messagemutex); - if ( RELAYID >= 0 ) - usleep(100000); - else sleep(1); + //printf("RELAYID.%d endmilli %f vs now %f\n",myinfo->NOTARY.RELAYID,endmilli,startmilli); + while ( OS_milliseconds() < endmilli ) + usleep(10000); + //printf("finished waiting numdpow.%d\n",myinfo->numdpows); + iter++; } } void basilisks_init(struct supernet_info *myinfo) { + iguana_initQ(&myinfo->p2pQ,"p2pQ"); iguana_initQ(&myinfo->msgQ,"messageQ"); portable_mutex_init(&myinfo->bu_mutex); portable_mutex_init(&myinfo->allcoins_mutex); portable_mutex_init(&myinfo->basilisk_mutex); + portable_mutex_init(&myinfo->smart_mutex); portable_mutex_init(&myinfo->DEX_mutex); portable_mutex_init(&myinfo->DEX_swapmutex); portable_mutex_init(&myinfo->DEX_reqmutex); @@ -882,46 +1005,519 @@ void basilisks_init(struct supernet_info *myinfo) #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" -HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr) +#include "../includes/iguana_apideclares2.h" + +TWO_STRINGS(tradebot,gensvm,base,rel) { - char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; - if ( RELAYID >= 0 ) - return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); +#ifdef _WIN + return(clonestr("{\"error\":\"windows doesnt support SVM\"}")); +#else + int32_t numfeatures = 317*61; + struct tradebot_arbpair *pair; + if ( base[0] != 0 && rel[0] != 0 && (pair= tradebots_arbpair_find(base,rel)) != 0 && pair->fp != 0 ) + { + tradebots_calcanswers(pair); + ocas_gen(pair->refc,numfeatures,0,(int32_t)(ftell(pair->fp) / sizeof(pair->rawfeatures))); + return(clonestr("{\"result\":\"success\"}")); + } else return(clonestr("{\"error\":\"cant find arbpair\"}")); +#endif +} + +ZERO_ARGS(tradebot,openliquidity) +{ + int32_t i; cJSON *array = cJSON_CreateArray(); + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + if ( myinfo->linfos[i].base[0] != 0 ) + jaddi(array,linfo_json(&myinfo->linfos[i])); + } + return(jprint(array,1)); +} + +ZERO_ARGS(tradebot,allbalances) +{ + int32_t i,n; double value,pending; char *base; cJSON *item,*balances = cJSON_CreateObject(); + if ( myinfo->liquidity_currencies == 0 ) + myinfo->liquidity_currencies = cJSON_Parse("[\"KMD\", \"BTC\"]"); + if ( myinfo->liquidity_currencies != 0 && (n= cJSON_GetArraySize(myinfo->liquidity_currencies)) > 0 ) + { + for (i=0; iliquidity_currencies,i); + value = tradebot_balance(myinfo,base); + pending = tradebot_pending(myinfo,base); + item = cJSON_CreateObject(); + jaddnum(item,"value",value); + jaddnum(item,"pending",pending); + jadd(balances,base,item); + } + } + return(jprint(balances,1)); +} + +ZERO_ARGS(tradebot,anchor) +{ + FILE *fp; char *anchorstr,fname[512]; cJSON *anchor; int32_t retval = -1; + if ( (anchorstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) + { + if ( (anchor= cJSON_Parse(anchorstr)) != 0 ) + { + if ( jobj(anchor,"error") == 0 ) + { + sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(anchorstr,1,strlen(anchorstr)+1,fp) == strlen(anchorstr)+1 ) + retval = 0; + fclose(fp); + } + } + } + free(anchorstr); + } + if ( retval == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(clonestr("{\"error\":\"couldnt make anchor file\"}")); +} + +ZERO_ARGS(tradebot,portfolio) +{ + char *currentstr,*anchorstr,fname[512]; long fsize; cJSON *current,*anchor=0,*portfolio=0; + if ( (currentstr= tradebot_allbalances(myinfo,0,0,0)) != 0 ) + { + if ( (current= cJSON_Parse(currentstr)) != 0 ) + { + sprintf(fname,"%s/anchor",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (anchorstr= OS_filestr(&fsize,fname)) != 0 ) + { + anchor = cJSON_Parse(anchorstr); + free(anchorstr); + } + if ( anchor == 0 ) + anchor = cJSON_Parse("{}"); + portfolio = tradebot_balancesdiff(myinfo,current,anchor); + free_json(current); + } + free(currentstr); + } + if ( portfolio == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(jprint(portfolio,1)); +} + +ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime) +{ + static bits256 zero; char *targetcoin; int32_t i,n; + if ( currencies != 0 && vals != 0 ) + { + // init things so automatically updates refli.bid and refli.ask + // volume range with margin + // currency percentage value in BTC? target distribution, max percentage, min percentage` + // min price to sell, max price to buy, max volume + n = cJSON_GetArraySize(currencies); + for (i=0; imyaddr.persistent); + if ( (msgid= juint(vals,"msgid")) == 0 ) + { + msgid = (uint32_t)time(NULL); + jdelete(vals,"msgid"); + jaddnum(vals,"msgid",msgid); + } + if ( myinfo->NOTARY.RELAYID >= 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) + { + channel = juint(vals,"channel"); + width = juint(vals,"width"); + retstr = basilisk_iterate_MSG(myinfo,channel,msgid,jbits256(vals,"srchash"),jbits256(vals,"desthash"),width); + //printf("getmessage.(%s)\n",retstr); + return(retstr); + } + //printf("getmessage not relay.%d dexsock.%d subsock.%d\n",myinfo->NOTARY.RELAYID,myinfo->dexsock,myinfo->subsock); + return(basilisk_standardservice("MSG",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) +{ + int32_t keylen,datalen,allocsize = 65536; uint8_t key[BASILISK_KEYSIZE],*space,*space2,*data,*ptr = 0; char *retstr=0; + space = calloc(1,allocsize); + space2 = calloc(1,allocsize); + data = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,&space[BASILISK_KEYSIZE],allocsize-BASILISK_KEYSIZE,hexstr); + if ( myinfo->subsock >= 0 || myinfo->dexsock >= 0 || (myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0) ) + { + keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"srchash"),jbits256(vals,"desthash")); + if ( data != 0 ) + { + retstr = basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration")); + } else printf("no get_dataptr\n"); + if ( retstr != 0 ) + free(retstr); + } //else printf("not notary.%d relayid.%d\n",myinfo->IAMNOTARY,myinfo->NOTARY.RELAYID); + if ( vals != 0 && juint(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+2)); + if ( BASILISK_KEYSIZE+datalen < allocsize ) + { + memcpy(space2,key,BASILISK_KEYSIZE); + if ( data != 0 && datalen != 0 ) + memcpy(&space2[BASILISK_KEYSIZE],data,datalen); + dex_reqsend(myinfo,"DEX",space2,datalen+BASILISK_KEYSIZE,1,""); + } else printf("sendmessage space too small error for %d\n",datalen); + free(space); + free(space2); + if ( ptr != 0 ) + free(ptr); + return(basilisk_standardservice("OUT",myinfo,0,jbits256(vals,"desthash"),vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) +{ + char *retstr=0,*symbol,*coinaddr,*infostr; cJSON *retjson,*sobj,*info,*addrs,*txoutjson,*txjson,*array; uint32_t basilisktag,blocktime,numtx=0; bits256 txid,blockhash; struct basilisk_item *ptr,Lptr; uint64_t value; int32_t timeoutmillis,vout,height,n,m; if ( vals == 0 ) - return(clonestr("{\"error\":\"need vals object\"}")); + return(clonestr("{\"error\":\"null valsobj\"}")); + //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) + // return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); //if ( coin == 0 ) { if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) coin = iguana_coinfind(symbol); } if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",(int32_t)sqrt(NUMRELAYS)+1); - if ( jobj(vals,"numrequired") == 0 ) - jaddnum(vals,"numrequired",sqrt(NUMRELAYS)); + jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + txid = jbits256(vals,"txid"); + vout = jint(vals,"vout"); if ( coin != 0 ) { - if ( jobj(vals,"addresses") == 0 ) + if ( coin->FULLNODE < 0 ) + { + if ( (txoutjson= dpow_gettxout(myinfo,coin,txid,vout)) != 0 ) + { + if ( (value= SATOSHIDEN*jdouble(txoutjson,"value")) == 0 ) + value = SATOSHIDEN*jdouble(txoutjson,"amount"); + if ( (coinaddr= jstr(txoutjson,"address")) == 0 ) + { + if ( (sobj= jobj(txoutjson,"scriptPubKey")) != 0 && (addrs= jarray(&n,sobj,"addresses")) != 0 && n > 0 ) + coinaddr = jstri(addrs,0); + printf("no address, check addrs %p coinaddr.%p\n",sobj,coinaddr); + } + if ( coinaddr != 0 && value != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",coinaddr); + jadd64bits(retjson,"satoshis",value); + jaddnum(retjson,"value",dstr(value)); + jaddnum(retjson,"amount",dstr(value)); + height = dpow_getchaintip(myinfo,&blockhash,&blocktime,0,&numtx,coin); + jaddnum(retjson,"height",height); + jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + jaddstr(retjson,"coin",coin->symbol); + } + else + { + printf("missing fields.(%s)\n",jprint(txoutjson,0)); + free_json(txoutjson); + return(clonestr("{\"error\":\"return from gettxout missing fields\"}")); + } + free_json(txoutjson); + return(jprint(retjson,1)); + } //else return(clonestr("{\"error\":\"null return from gettxout\"}")); + } + else + { + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( coin->FULLNODE > 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + retstr = ptr->retstr, ptr->retstr = 0; + ptr->finished = OS_milliseconds() + 10000; + return(retstr); + } + } + } + if ( myinfo->reqsock >= 0 ) + { + if ( (retstr= _dex_getrawtransaction(myinfo,symbol,txid)) != 0 ) { - jadd(vals,"addresses",iguana_getaddressesbyaccount(myinfo,coin,"*")); - //printf("added all addresses: %s\n",jprint(vals,0)); - } //else printf("have addresses.(%s)\n",jprint(jobj(vals,"addresses"),0)); + if ( (txoutjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("TX.(%s)\n",jprint(txoutjson,0)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"numconfirms",jint(txoutjson,"confirmations")); + if ( (height= jint(txoutjson,"height")) == 0 && coin != 0 ) + height = coin->longestchain - jint(txoutjson,"confirmations"); + jaddnum(retjson,"height",height); + if ( (array= jarray(&n,txoutjson,"vout")) != 0 && vout < n && (txjson= jitem(array,vout)) != 0 ) + { + //printf("txjson.(%s)\n",jprint(txjson,0)); + if ( (value= jdouble(txjson,"value") * SATOSHIDEN) != 0 ) + { + if ( (sobj= jobj(txjson,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 && (coinaddr= jstri(addrs,0)) != 0 ) + jaddstr(retjson,"address",coinaddr); + jadd64bits(retjson,"satoshis",value); + jaddnum(retjson,"value",dstr(value)); + if ( (infostr= _dex_getinfo(myinfo,symbol)) != 0 ) + { + if ( (info= cJSON_Parse(infostr)) != 0 ) + { + if ( (height= jint(info,"blocks")) > 0 ) + { + height -= jint(txoutjson,"confirmations"); + jaddnum(retjson,"height",height); + } + free_json(info); + } + free(infostr); + } + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + jaddstr(retjson,"coin",symbol); + free(retstr); + free_json(txoutjson); + return(jprint(retjson,1)); + } + } + free_json(txoutjson); + return(jprint(retjson,1)); + } + return(retstr); + } + } + return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) +{ + char *retstr=0,*symbol; uint32_t basilisktag; int32_t timeoutmillis,i,retval = -1; uint64_t amount,txfee; cJSON *retarray; + if ( vals == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( jobj(vals,"numrequired") == 0 ) + jaddnum(vals,"numrequired",MIN(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(3,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + if ( coin != 0 ) + { + //if ( juint(vals,"burn") == 0 ) + // jaddnum(vals,"burn",0.0001); if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) basilisktag = rand(); if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) timeoutmillis = BASILISK_TIMEOUT; - if ( (coin->FULLNODE != 0 || coin->VALIDATENODE != 0) && (ptr= basilisk_bitcoinbalances(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + if ( (retstr= basilisk_bitcoinrawtx(myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals,0)) != 0 ) { - retstr = ptr->retstr, ptr->retstr = 0; - ptr->finished = (uint32_t)time(NULL); - return(retstr); + printf("rawtx.(%s)\n",retstr); + if ( (amount= j64bits(vals,"satoshis")) == 0 ) + amount = jdouble(vals,"value") * SATOSHIDEN; + if ( (txfee= j64bits(vals,"txfee")) == 0 ) + txfee = coin->chain->txfee; + if ( txfee == 0 ) + txfee = 10000; + retval = -1; + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(retarray) != 0 ) + { + for (i=0; iFULLNODE >= 0 ) + return(clonestr("{\"error\":\"no passphrase or no native komodod\"}")); + else + { + safecopy(myinfo->jumblr_passphrase,passphrase,sizeof(myinfo->jumblr_passphrase)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + privkey = jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,JUMBLR_DEPOSITPREFIX); + smartaddress_add(myinfo,privkey,"deposit","KMD",0.,0.); + myinfo->jumblr_depositkey = curve25519(privkey,curve25519_basepoint9()); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + if ( coin->FULLNODE < 0 ) + jumblr_importprivkey(myinfo,coin,wifstr); + jaddstr(retjson,"KMDdeposit",KMDaddr); + jaddstr(retjson,"BTCdeposit",BTCaddr); + if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) + { + bitcoin_priv2wif(wifstr,privkey,coinbtc->chain->wiftype); + if ( coinbtc->FULLNODE < 0 ) + jumblr_importprivkey(myinfo,coinbtc,wifstr); + jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + } + privkey = jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,""); + smartaddress_add(myinfo,privkey,"jumblr","KMD",0.,0.); + myinfo->jumblr_pubkey = curve25519(privkey,curve25519_basepoint9()); + jaddstr(retjson,"KMDjumblr",KMDaddr); + jaddstr(retjson,"BTCjumblr",BTCaddr); + if ( coinbtc != 0 ) + jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + if ( (smartaddrs= InstantDEX_smartaddresses(myinfo,0,0,0)) != 0 ) + { + if ( (tmp= cJSON_Parse(smartaddrs)) != 0 ) + jadd(retjson,"smartaddresses",tmp); + free(smartaddrs); + } + return(jprint(retjson,1)); + } +} + +ZERO_ARGS(jumblr,runsilent) +{ + myinfo->runsilent = 1; + return(clonestr("{\"result\":\"success\",\"mode\":\"runsilent\"}")); +} + +ZERO_ARGS(jumblr,totransparent) +{ + myinfo->runsilent = 0; + return(clonestr("{\"result\":\"success\",\"mode\":\"totransparent\"}")); +} + +ZERO_ARGS(jumblr,status) +{ + cJSON *retjson; char KMDaddr[64],BTCaddr[64]; struct jumblr_item *ptr,*tmp; struct iguana_info *coinbtc; int64_t received,deposited,jumblred,step_t2z,step_z2z,step_z2t,finished,pending,maxval,minval; + if ( strcmp(coin->symbol,"KMD") == 0 && coin->FULLNODE < 0 && myinfo->jumblr_passphrase[0] != 0 ) + { + jumblr_opidsupdate(myinfo,coin); + retjson = cJSON_CreateObject(); + step_t2z = step_z2z = step_z2t = deposited = finished = pending = 0; + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,JUMBLR_DEPOSITPREFIX); + jaddstr(retjson,"mode",myinfo->runsilent == 0 ? "totransparent" : "runsilent"); + jaddstr(retjson,"KMDdeposit",KMDaddr); + jaddstr(retjson,"BTCdeposit",BTCaddr); + if ( (coinbtc= iguana_coinfind("BTC")) != 0 ) + jaddnum(retjson,"BTCdeposits",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + received = jumblr_receivedby(myinfo,coin,KMDaddr); + deposited = jumblr_balance(myinfo,coin,KMDaddr); + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,""); + jaddstr(retjson,"KMDjumblr",KMDaddr); + jaddstr(retjson,"BTCjumblr",BTCaddr); + if ( coinbtc != 0 ) + jaddnum(retjson,"BTCjumbled",dstr(jumblr_balance(myinfo,coinbtc,BTCaddr))); + finished = jumblr_receivedby(myinfo,coin,KMDaddr); + jumblred = jumblr_balance(myinfo,coin,KMDaddr); + HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) + { + if ( strlen(ptr->src) >= 40 ) + { + if ( strlen(ptr->dest) >= 40 ) + step_z2z += ptr->amount; + else step_z2t += ptr->amount; + } else step_t2z += ptr->amount; + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"deposits",dstr(deposited)); + jaddnum(retjson,"t_to_z",dstr(step_t2z)); + jaddnum(retjson,"z_to_z",dstr(step_z2z)); + jaddnum(retjson,"z_to_t",dstr(step_z2t)); + maxval = MAX(step_t2z,MAX(step_z2z,step_z2t)); + minval = MIN(step_t2z,MIN(step_z2z,step_z2t)); + if ( maxval > minval ) + { + pending = (maxval - minval); + if ( pending < finished*.1 ) + pending = 0; + } + jaddnum(retjson,"pending",dstr(pending)); + jaddnum(retjson,"jumbled",dstr(jumblred)); + jaddnum(retjson,"received",dstr(received)); + jaddnum(retjson,"finished",dstr(finished)); + return(jprint(retjson,1)); + } + else + { + printf("(%s) (%s) %d\n",coin->symbol,myinfo->jumblr_passphrase,coin->FULLNODE); + return(clonestr("{\"error\":\"jumblr status no passphrase or no native komodod\"}")); + } +} + +HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr) +{ + char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; + if ( myinfo->NOTARY.RELAYID >= 0 ) + return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); + if ( vals == 0 ) + return(clonestr("{\"error\":\"need vals object\"}")); + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + if ( jobj(vals,"history") == 0 ) + jaddnum(vals,"history",3); + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + if ( jobj(vals,"numrequired") == 0 ) + jaddnum(vals,"numrequired",MIN(juint(vals,"fanout")/2,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS))); + if ( jobj(vals,"addresses") == 0 ) + { + jadd(vals,"addresses",iguana_getaddressesbyaccount(myinfo,coin,"*")); + //printf("added all %s addresses: %s\n",coin->symbol,jprint(vals,0)); + } //else printf("have addresses.(%s)\n",jprint(jobj(vals,"addresses"),0)); + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( coin != 0 ) + { + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 || coin->notarychain >= 0 ) + { + if ( (ptr= basilisk_bitcoinbalances(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + retstr = ptr->retstr, ptr->retstr = 0; + ptr->finished = OS_milliseconds() + 10000; + return(retstr); + } + return(clonestr("{\"error\":\"no result\"}")); } } else printf("no coin\n"); - return(basilisk_standardservice("BAL",myinfo,0,hash,vals,hexstr,1)); + if ( (retstr= basilisk_standardservice("BAL",myinfo,0,hash,vals,hexstr,1)) != 0 ) + { + basilisk_unspents_process(myinfo,coin,retstr); + } + return(retstr); } HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr) { - struct basilisk_unspent *bu; int32_t i; int64_t totalspent=0,total = 0; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; char *symbol; cJSON *retjson,*array; struct basilisk_spend *s; + int64_t total = 0; int32_t i,n; char *symbol; cJSON *retjson,*unspents,*spends,*array; //struct basilisk_spend *s; struct basilisk_unspent *bu; int32_t i; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; if ( vals == 0 ) return(clonestr("{\"error\":\"need vals object\"}")); //if ( coin == 0 ) @@ -931,44 +1527,461 @@ HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr) } if ( coin == 0 ) return(clonestr("{\"error\":\"couldnt find coin\"}")); - //printf("history for (%s)\n",coin->symbol); - basilisk_unspents_update(myinfo,coin); - array = cJSON_CreateArray(); + unspents = cJSON_CreateArray(); + spends = cJSON_CreateArray(); portable_mutex_lock(&myinfo->bu_mutex); - HASH_ITER(hh,myinfo->wallet,wacct,tmp) + //HASH_ITER(hh,myinfo->wallet,wacct,tmp) { - HASH_ITER(hh,wacct->waddr,waddr,tmp2) + //HASH_ITER(hh,wacct->waddr,waddr,tmp2) { - for (i=0; inumunspents; i++) + if ( myinfo->Cunspents != 0 ) { - bu = &waddr->unspents[i]; - if ( strcmp(bu->symbol,coin->symbol) == 0 ) + //printf("Cunspents.(%s)\n",jprint(waddr->Cunspents,0)); + if ( (array= jobj(myinfo->Cunspents,coin->symbol)) != 0 ) { - bitcoin_address(waddr->coinaddr,coin->chain->pubtype,waddr->rmd160,sizeof(waddr->rmd160)); - jaddi(array,basilisk_history_item(coin,&total,waddr->coinaddr,bu->value,bu->timestamp,bu->txid,"vout",bu->vout,bu->height,"spentheight",bu->spentheight,bu->relaymask,-1)); - //printf("%s %s i.%d numunspents.%d\n",coin->symbol,waddr->coinaddr,i,waddr->numunspents); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; inumspends > 0 ) - { - //spends = cJSON_CreateArray(); - for (i=0; inumspends; i++) - { - s = &myinfo->spends[i]; - //struct basilisk_spend { bits256 txid; uint64_t relaymask,value; uint32_t timestamp; int32_t vini,height,unspentheight,ismine; char destaddr[64]; }; - if ( strcmp(s->symbol,coin->symbol) == 0 ) - jaddi(array,basilisk_history_item(coin,&totalspent,s->destaddr,s->value,s->timestamp,s->txid,"vin",s->vini,s->height,"unspentheight",s->unspentheight,s->relaymask,s->ismine)); + if ( myinfo->Cspends != 0 ) + { + //printf("Cspends.(%s)\n",jprint(waddr->Cspends,0)); + if ( (array= jobj(myinfo->Cspends,coin->symbol)) != 0 ) + jaddi(spends,jduplicate(array)); + } } } portable_mutex_unlock(&myinfo->bu_mutex); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); - jadd(retjson,"history",array); + jadd(retjson,"unspents",unspents); + jadd(retjson,"spends",spends); jaddstr(retjson,"coin",coin->symbol); jaddnum(retjson,"balance",dstr(total)); + //printf("return history balance %s %.8f\n",coin->symbol,dstr(total)); + return(jprint(retjson,1)); +} + +INT_ARG(passthru,paxfiats,mask) +{ + if ( mask == 0 ) + mask = -1; + komodo_assetcoins(-1,mask); + return(clonestr("{\"result\":\"success\"}")); +} + +INT_ARG(basilisk,paxfiats,mask) +{ + if ( mask == 0 ) + mask = -1; + komodo_assetcoins(0,mask); + return(clonestr("{\"result\":\"success\"}")); +} + +INT_ARG(iguana,paxfiats,mask) +{ + if ( mask == 0 ) + mask = -1; + komodo_assetcoins(1,mask); + return(clonestr("{\"result\":\"success\"}")); +} + +int32_t utxocmp(cJSON *utxo,cJSON *utxo2) +{ + bits256 txid,txid2; int32_t vout=-1,vout2=-1; + //printf("cmp (%s) vs (%s)\n",jprint(utxo,0),jprint(utxo2,0)); + txid = jbits256(utxo,"txid"); + vout = jint(utxo,"vout"); + txid2 = jbits256(utxo2,"txid"); + vout2 = jint(utxo2,"vout"); + if ( bits256_cmp(txid,txid2) == 0 && vout == vout2 ) + return(0); + else return(-1); +} + +ZERO_ARGS(basilisk,cancelrefresh) +{ + myinfo->cancelrefresh = 1; + return(clonestr("{\"result\":\"refresh cancel started\"}")); +} + +TWO_STRINGS(basilisk,refresh,symbol,address) +{ + cJSON *array=0,*array2=0,*array3,*item,*item2; char *retstr; int32_t i,j,n,m,vout; bits256 txid; + myinfo->cancelrefresh = 0; + if ( symbol != 0 && iguana_isnotarychain(symbol) >= 0 && address != 0 && address[0] != 0 ) + { + if ( (retstr= _dex_listunspent(myinfo,symbol,address)) != 0 ) + { + array = cJSON_Parse(retstr); + free(retstr); + } + if ( (retstr= _dex_listunspent2(myinfo,symbol,address)) != 0 ) + { + if ( array == 0 ) + array = cJSON_Parse(retstr); + else array2 = cJSON_Parse(retstr); + free(retstr); + } + if ( array != 0 && array2 != 0 ) // merge + { + m = cJSON_GetArraySize(array2); + array3 = jduplicate(array); + n = cJSON_GetArraySize(array3); + //printf("MERGE %s and %s\n",jprint(array,0),jprint(array2,0)); + for (j=0; jcancelrefresh != 0 ) + break; + item2 = jitem(array2,j); + for (i=0; icancelrefresh != 0 ) + break; + item = jitem(array,i); + txid = jbits256(item,"txid"); + vout = jint(item,"vout"); + if ( (retstr= _dex_gettxout(myinfo,symbol,txid,vout)) != 0 ) + { + if ( (item2= cJSON_Parse(retstr)) != 0 ) + { + if ( jdouble(item2,"value") > 0 ) + { + jaddbits256(item2,"txid",txid); + jaddnum(item2,"vout",vout); + jaddnum(item2,"amount",jdouble(item2,"value")); + //printf("%s\n",jprint(item2,0)); + jaddi(array3,item2); + } + else free_json(item2); + } + free(retstr); + } + } + free_json(array); + myinfo->cancelrefresh = 0; + return(jprint(array3,1)); + } else return(clonestr("[]")); + } + myinfo->cancelrefresh = 0; + return(clonestr("{\"error\":\"invalid coin or address specified\"}")); +} + +STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore) +{ + char *destaddr,*changeaddr; int64_t satoshis,txfee; int32_t completed,sendflag,timelock; + timelock = jint(vals,"timelock"); + sendflag = jint(vals,"sendflag"); + satoshis = jdouble(vals,"amount") * SATOSHIDEN; + destaddr = jstr(vals,"destaddr"); + changeaddr = jstr(vals,"changeaddr"); + if ( destaddr != 0 && changeaddr != 0 && symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + txfee = jdouble(vals,"txfee") * SATOSHIDEN; + return(iguana_utxorawtx(myinfo,coin,timelock,destaddr,changeaddr,&satoshis,1,txfee,&completed,sendflag,utxos,0)); + } + return(clonestr("{\"error\":\"invalid coin or address specified\"}")); +} + +HASH_ARRAY_STRING(basilisk,utxocombine,ignore,vals,symbol) +{ + char *coinaddr,*retstr=0; cJSON *utxos; int64_t satoshis,limit,txfee; int32_t maxvins,completed,sendflag,timelock; + timelock = 0; + if ( (maxvins= jint(vals,"maxvins")) == 0 ) + maxvins = 20; + sendflag = jint(vals,"sendflag"); + coinaddr = jstr(vals,"coinaddr"); + limit = jdouble(vals,"maxamount") * SATOSHIDEN; + if ( limit > 0 && symbol != 0 && symbol[0] != 0 && (utxos= basilisk_utxosweep(myinfo,symbol,&satoshis,limit,maxvins,coinaddr)) != 0 && cJSON_GetArraySize(utxos) > 0 ) + { + if ( coinaddr != 0 && symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + txfee = jdouble(vals,"txfee") * SATOSHIDEN; + retstr = iguana_utxorawtx(myinfo,coin,timelock,coinaddr,coinaddr,&satoshis,1,txfee,&completed,sendflag,utxos,0); + } + free_json(utxos); + } + if ( retstr == 0 ) + return(clonestr("{\"error\":\"invalid coin or address specified or no available utxos\"}")); + return(retstr); +} + +//int64_t iguana_verifytimelock(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t timelocked,char *destaddr,bits256 txid,int32_t vout) +THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) +{ + double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); + aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"aveprice",aveprice); + jaddnum(retjson,"avebid",retvals[0]); + jaddnum(retjson,"bidvol",retvals[1]); + jaddnum(retjson,"aveask",retvals[2]); + jaddnum(retjson,"askvol",retvals[3]); + return(jprint(retjson,1)); +} + +ZERO_ARGS(InstantDEX,allcoins) +{ + struct iguana_info *tmp; cJSON *native,*notarychains,*basilisk,*virtual,*full,*retjson = cJSON_CreateObject(); + full = cJSON_CreateArray(); + native = cJSON_CreateArray(); + basilisk = cJSON_CreateArray(); + virtual = cJSON_CreateArray(); + notarychains = cJSON_CreateArray(); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->FULLNODE < 0 ) + jaddistr(native,coin->symbol); + //else if ( coin->virtualchain != 0 ) + // jaddistr(virtual,coin->symbol); + else if ( coin->FULLNODE > 0 )//|| coin->VALIDATENODE > 0 ) + jaddistr(full,coin->symbol); + //else if ( coin->notarychain >= 0 ) + // jaddistr(notarychains,coin->symbol); + else jaddistr(basilisk,coin->symbol); + } + jadd(retjson,"native",native); + jadd(retjson,"basilisk",basilisk); + jadd(retjson,"full",full); + //jadd(retjson,"virtual",virtual); + //jadd(retjson,"notarychains",notarychains); + return(jprint(retjson,1)); +} + +STRING_ARG(InstantDEX,available,source) +{ + uint64_t total = 0; int32_t i,n=0; char coinaddr[64]; cJSON *item,*unspents,*retjson = 0; + if ( source != 0 && source[0] != 0 && (coin= iguana_coinfind(source)) != 0 ) + { + if ( myinfo->expiration != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + if ( (unspents= basilisk_unspents(myinfo,coin,coinaddr)) != 0 ) + { + //printf("available.(%s)\n",jprint(unspents,0)); + if ( (n= cJSON_GetArraySize(unspents)) > 0 ) + { + for (i=0; i %.8f\n",jprint(item,0),dstr(total)); + } + } + free_json(unspents); + } + retjson = cJSON_CreateObject(); + jaddnum(retjson,"result",dstr(total)); + printf(" n.%d total %.8f (%s)\n",n,dstr(total),jprint(retjson,0)); + return(jprint(retjson,1)); + } + printf("InstantDEX_available: need to unlock wallet\n"); + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + } + printf("InstantDEX_available: %s is not active\n",source!=0?source:""); + return(clonestr("{\"error\":\"specified coin is not active\"}")); +} + +HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) +{ + uint8_t serialized[512]; bits256 privkey; char buf[512],BTCaddr[64],KMDaddr[64]; struct basilisk_request R; int32_t jumblr,iambob,optionhours; cJSON *reqjson; uint32_t datalen=0,DEX_channel; struct iguana_info *bobcoin,*alicecoin; + myinfo->DEXactive = (uint32_t)time(NULL) + 3*BASILISK_TIMEOUT + 60; + jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN); + if ( jobj(vals,"desthash") == 0 ) + jaddbits256(vals,"desthash",hash); + jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN); + jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN); + jaddnum(vals,"timestamp",time(NULL)); + if ( (jumblr= jint(vals,"usejumblr")) != 0 ) + privkey = jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,jumblr == 1 ? JUMBLR_DEPOSITPREFIX : ""); + else privkey = myinfo->persistent_priv; + hash = curve25519(privkey,curve25519_basepoint9()); + if ( jobj(vals,"srchash") == 0 ) + jaddbits256(vals,"srchash",hash); + printf("service.(%s)\n",jprint(vals,0)); + memset(&R,0,sizeof(R)); + if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp"),juint(vals,"DEXselector")) == 0 ) + { + iambob = bitcoin_coinptrs(hash,&bobcoin,&alicecoin,R.src,R.dest,privkey,GENESIS_PUBKEY); + if ( (optionhours= jint(vals,"optionhours")) != 0 ) + { + printf("iambob.%d optionhours.%d R.requestid.%u vs calc %u, q.%u\n",iambob,R.optionhours,R.requestid,basilisk_requestid(&R),R.quoteid); + if ( iambob != 0 && optionhours > 0 ) + { + sprintf(buf,"{\"error\":\"illegal call option request hours.%d when iambob.%d\"}",optionhours,iambob); + printf("ERROR.(%s)\n",buf); + return(clonestr(buf)); + } + else if ( iambob == 0 && optionhours < 0 ) + { + sprintf(buf,"{\"error\":\"illegal put option request hours.%d when iambob.%d\"}",optionhours,iambob); + printf("ERROR.(%s)\n",buf); + return(clonestr(buf)); + } + } + //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) + // R.relaybits = myinfo->myaddr.myipbits; + if ( (reqjson= basilisk_requestjson(&R)) != 0 ) + free_json(reqjson); + datalen = basilisk_rwDEXquote(1,serialized,&R); + //int32_t i; for (i=0; i 0 ) + { + uint32_t msgid;//,crc=0,crcs[2],numiters = 0; uint8_t buf[4096]; + memset(hash.bytes,0,sizeof(hash)); + msgid = (uint32_t)time(NULL); + DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + myinfo->DEXtrades++; // not exact but allows a one side initiated self-trade + basilisk_channelsend(myinfo,hash,hash,DEX_channel,msgid,serialized,datalen,60); + sleep(3); + /*while ( numiters < 10 && (crc= basilisk_crcsend(myinfo,0,buf,sizeof(buf),hash,myinfo->myaddr.persistent,DEX_channel,msgid,serialized,datalen,crcs)) == 0 ) + { + //printf("didnt get back what was sent\n"); + sleep(3); + basilisk_channelsend(myinfo,myinfo->myaddr.persistent,hash,DEX_channel,msgid,serialized,datalen,60); + numiters++; + }*/ + //if ( crc != 0 )//basilisk_channelsend(myinfo,R.srchash,R.desthash,DEX_channel,(uint32_t)time(NULL),serialized,datalen,30) == 0 ) + return(clonestr("{\"result\":\"DEX message sent\"}")); + //else return(clonestr("{\"error\":\"DEX message couldnt be sent\"}")); + } + return(clonestr("{\"error\":\"DEX message not sent\"}")); +} + +INT_ARG(InstantDEX,automatched,requestid) +{ + // return quoteid + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + return(clonestr("{\"result\":\"automatched not yet\"}")); +} + +int32_t InstantDEX_incoming_func(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + //int32_t i; + //for (i=0; inumsmartaddrs+1; int32_t retval,width,drift=3; bits256 pubkey; uint8_t data[32768]; + now = (uint32_t)time(NULL); + memset(&zero,0,sizeof(zero)); + width = (now - myinfo->DEXpoll) + 2*drift; + if ( width < (drift+1) ) + width = 2*drift+1; + else if ( width > 64 ) + width = 64; + if ( (counter % n) == n-1 ) + pubkey = myinfo->myaddr.persistent; + else pubkey = myinfo->smartaddrs[counter % n].pubkey; + counter++; + myinfo->DEXpoll = now; + retjson = cJSON_CreateObject(); + DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + msgid = (uint32_t)time(NULL) + drift; + if ( (retarray= basilisk_channelget(myinfo,zero,pubkey,DEX_channel,msgid,width)) != 0 ) + { + //printf("GOT.(%s)\n",jprint(retarray,0)); + if ( (retval= basilisk_process_retarray(myinfo,0,InstantDEX_process_channelget,data,sizeof(data),DEX_channel,msgid,retarray,InstantDEX_incoming_func)) > 0 ) + { + jaddstr(retjson,"result","success"); + } else jaddstr(retjson,"error","cant process InstantDEX retarray"); + jadd(retjson,"responses",retarray); + } + else + { + jaddstr(retjson,"error","cant do InstantDEX channelget"); + //char str[65]; printf("error channelget %s %x\n",bits256_str(str,pubkey),msgid); + } return(jprint(retjson,1)); } +/*TWO_INTS(InstantDEX,swapstatus,requestid,quoteid) + { + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + //if ( myinfo->IAMLP != 0 ) + // return(basilisk_respond_swapstatus(myinfo,myinfo->myaddr.persistent,requestid,quoteid)); + //else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"requestid",(uint32_t)requestid); + jaddnum(vals,"quoteid",(uint32_t)quoteid); + jaddbits256(vals,"hash",myinfo->myaddr.persistent); + retstr = basilisk_standardservice("SWP",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } + }*/ + +TWO_INTS(InstantDEX,accept,requestid,quoteid) +{ + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + if ( myinfo->IAMLP != 0 || myinfo->dexsock >= 0 || myinfo->subsock >= 0 ) + return(basilisk_respond_accept(myinfo,myinfo->persistent_priv,requestid,quoteid,&myinfo->DEXaccept)); + else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"quoteid",(uint32_t)quoteid); + jaddnum(vals,"requestid",(uint32_t)requestid); + retstr = basilisk_standardservice("ACC",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } +} + +ZERO_ARGS(InstantDEX,init) +{ + basilisk_swaps_init(myinfo); + return(clonestr("{\"result\":\"success\"}")); +} + +ZERO_ARGS(InstantDEX,getswaplist) +{ + return(basilisk_swaplist(myinfo)); +} + +DOUBLE_ARG(InstantDEX,DEXratio,ratio) +{ + if ( ratio < 0.95 || ratio > 1.01 ) + return(clonestr("{\"result\":\"error\",\"description\":\"DEXratio must be between 0.95 and 1.01\"}")); + myinfo->DEXratio = ratio; + return(clonestr("{\"result\":\"success\"}")); +} #include "../includes/iguana_apiundefs.h" diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h index 3576eee12..8d0c3da9d 100755 --- a/basilisk/basilisk.h +++ b/basilisk/basilisk.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,20 +16,20 @@ #ifndef H_BASILISK_H #define H_BASILISK_H -#define BASILISK_DISABLETX +//#define BASILISK_DISABLESENDTX +//#define BASILISK_DISABLEWAITTX #include "../iguana/iguana777.h" -#define BASILISK_TIMEOUT 30000 +#define BASILISK_TIMEOUT 3000 #define BASILISK_MINFANOUT 8 #define BASILISK_MAXFANOUT 64 #define BASILISK_DEFAULTDIFF 0x1effffff -#define BASILISK_MAXRELAYS 64 -#define BASILISK_DEXDURATION 180 -#define BASILISK_MSGDURATION 60 +#define BASILISK_DEXDURATION 300 +#define BASILISK_MSGDURATION 30 +#define BASILISK_AUCTION_DURATION 5 #define BASILISK_MAXFUTUREBLOCK 60 -//#define BASILISK_MAXBLOCKLAG 600 #define BASILISK_HDROFFSET ((int32_t)(sizeof(bits256)+sizeof(struct iguana_msghdr)+sizeof(uint32_t))) #define INSTANTDEX_DECKSIZE 1000 @@ -37,38 +37,58 @@ #define INSTANTDEX_INSURANCEDIV 777 #define INSTANTDEX_PUBKEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" #define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" +#define JUMBLR_RMD160 "5177f8b427e5f47342a4b8ab5dac770815d4389e" #define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" #define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" #define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" -struct basilisk_rawtx +#define JUMBLR_INCR 99.65 +#define JUMBLR_FEE 0.001 +#define JUMBLR_TXFEE 0.01 + +struct basilisk_swap; + +struct basilisk_rawtxinfo { + char destaddr[64],coinstr[16]; bits256 txid,signedtxid,actualtxid; - struct iguana_msgtx msgtx; - struct iguana_info *coin; uint64_t amount,change,inputsum; int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; - uint32_t locktime; - char destaddr[64],name[32]; - uint8_t addrtype,pubkey33[33],spendscript[512],redeemscript[1024],rmd160[20]; - uint8_t *txbytes,extraspace[1024]; + uint32_t locktime,crcs[2]; + uint8_t addrtype,pubkey33[33],rmd160[20]; +}; + +struct basilisk_rawtx +{ + char name[32]; + struct iguana_msgtx msgtx; + struct basilisk_rawtxinfo I; + struct iguana_info *coin; + char vinstr[8192],p2shaddr[64]; + cJSON *vins; + uint8_t txbytes[16384],spendscript[512],redeemscript[1024],extraspace[4096]; }; -struct basilisk_swap +struct basilisk_swapinfo { struct basilisk_request req; - struct supernet_info *myinfo; bits256 myhash,otherhash; - uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,locktime; - struct iguana_info *bobcoin,*alicecoin; char bobstr[64],alicestr[64]; - int32_t bobconfirms,aliceconfirms,iambob,reclaimed; + char bobstr[64],alicestr[64]; + bits256 myhash,otherhash,orderhash; + uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; + int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad; uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance; - bits256 privkeys[INSTANTDEX_DECKSIZE],myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; - uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; - int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate; + bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; + uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2]; + int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate,pad2; uint8_t secretAm[20],secretBn[20]; - - struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; + uint8_t secretAm256[32],secretBn256[32]; + uint8_t userdata_aliceclaim[256],userdata_aliceclaimlen; + uint8_t userdata_alicereclaim[256],userdata_alicereclaimlen; + uint8_t userdata_alicespend[256],userdata_alicespendlen; + uint8_t userdata_bobspend[256],userdata_bobspendlen; + uint8_t userdata_bobreclaim[256],userdata_bobreclaimlen; + uint8_t userdata_bobrefund[256],userdata_bobrefundlen; }; struct basilisk_value { bits256 txid; int64_t value; int32_t height; int16_t vout; char coinaddr[64]; }; @@ -76,8 +96,8 @@ struct basilisk_value { bits256 txid; int64_t value; int32_t height; int16_t vou struct basilisk_item { struct queueitem DL; UT_hash_handle hh; - double expiration; cJSON *retarray; - uint32_t submit,finished,basilisktag,numresults,numsent,numrequired,nBits; + double expiration,finished; cJSON *results[64]; + uint32_t submit,basilisktag,numresults,numsent,numrequired,nBits,duration; char symbol[32],CMD[4],remoteaddr[64],*retstr; }; @@ -85,8 +105,8 @@ struct basilisk_item struct basilisk_message { struct queueitem DL; UT_hash_handle hh; - uint32_t datalen,expiration,duration; - uint8_t key[BASILISK_KEYSIZE],keylen; + uint32_t expiration,duration,datalen; + uint8_t keylen,broadcast,key[BASILISK_KEYSIZE]; uint8_t data[]; }; @@ -102,7 +122,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *type,uint32_t *basilisktagp,int32_t encryptflag,int32_t delaymillis,uint8_t *data,int32_t datalen,int32_t fanout,uint32_t nBits); // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) void basilisks_init(struct supernet_info *myinfo); -void basilisk_p2p(void *myinfo,void *_addr,char *ipaddr,uint8_t *data,int32_t datalen,char *type,int32_t encrypted); +void basilisk_p2p(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *senderip,uint8_t *data,int32_t datalen,char *type,int32_t encrypted); uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int32_t spacesize,int32_t *datalenp,char *symbol,cJSON *sendjson,uint32_t basilisktag); uint8_t *SuperNET_ciphercalc(void **ptrp,int32_t *cipherlenp,bits256 *privkeyp,bits256 *destpubkeyp,uint8_t *data,int32_t datalen,uint8_t *space2,int32_t space2size); @@ -117,8 +137,15 @@ void basilisk_request_goodbye(struct supernet_info *myinfo); int32_t basilisk_update(char *symbol,uint32_t reftimestamp); void basilisk_seqresult(struct supernet_info *myinfo,char *retstr); struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbol,char *chainname,cJSON *valsobj); -void basilisk_alicepayment(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn); -void basilisk_rawtx_setparms(char *name,struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33); +void basilisk_alicepayment(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn); +void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33,int32_t jumblrflag); void basilisk_setmyid(struct supernet_info *myinfo); +int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp); +cJSON *basilisk_requestjson(struct basilisk_request *rp); +int32_t basilisk_bobscripts_set(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t depositflag,int32_t genflag); +void basilisk_txlog(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t delay); +int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash); +cJSON *basilisk_unspents(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); +char *basilisk_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx); #endif diff --git a/basilisk/basilisk_CMD.c b/basilisk/basilisk_CMD.c index 695ee1c83..5696addc9 100755 --- a/basilisk/basilisk_CMD.c +++ b/basilisk/basilisk_CMD.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -24,28 +24,33 @@ return(-1); }*/ -struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *btcd,uint32_t ipbits) +void basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *notaries,uint32_t ipbits) { + char ipaddr[64]; + expand_ipbits(ipaddr,ipbits); +//#if ISNOTARYNODE + //dpow_nanomsginit(myinfo,ipaddr); +//#else struct iguana_peer *addr; int32_t i; - if ( btcd == 0 ) - return(0); - if ( (addr= iguana_peerfindipbits(btcd,ipbits,0)) == 0 ) + if ( notaries == 0 || ipbits == myinfo->myaddr.myipbits ) + return; + if ( (addr= iguana_peerfindipbits(notaries,ipbits,0)) == 0 ) { - if ( (addr= iguana_peerslot(btcd,ipbits,0)) != 0 ) + if ( (addr= iguana_peerslot(notaries,ipbits,0)) != 0 && addr->isrelay == 0 ) { - printf("launch peer for relay\n"); + printf("launch peer.%s for relay vs (%s)\n",ipaddr,myinfo->ipaddr); addr->isrelay = 1; - RELAYID = -1; - for (i=0; imyaddr.myipbits ) + myinfo->NOTARY.RELAYID = -1; + for (i=0; iNOTARY.NUMRELAYS; i++) + if ( myinfo->NOTARY.RELAYS[i].ipbits == myinfo->myaddr.myipbits ) { - RELAYID = i; + myinfo->NOTARY.RELAYID = i; break; } - iguana_launch(btcd,"addrelay",iguana_startconnection,addr,IGUANA_CONNTHREAD); + iguana_launch(notaries,"addrelay",iguana_startconnection,addr,IGUANA_CONNTHREAD); } else printf("error getting peerslot\n"); } else addr->isrelay = 1; - return(addr); +//#endif } static int _increasing_ipbits(const void *a,const void *b) @@ -65,58 +70,59 @@ void basilisk_relay_remap(struct supernet_info *myinfo,struct basilisk_relay *rp { int32_t i; struct basilisk_relaystatus tmp[BASILISK_MAXRELAYS]; // need to verify this works - for (i=0; iNOTARY.NUMRELAYS; i++) tmp[i] = rp->reported[i]; - for (i=0; ireported[RELAYS[i].relayid] = tmp[RELAYS[i].oldrelayid]; + for (i=0; iNOTARY.NUMRELAYS; i++) + rp->reported[myinfo->NOTARY.RELAYS[i].relayid] = tmp[myinfo->NOTARY.RELAYS[i].oldrelayid]; } void basilisk_setmyid(struct supernet_info *myinfo) { - int32_t i; char ipaddr[64]; struct iguana_info *btcd = iguana_coinfind("BTCD"); - for (i=0; iNOTARY.NUMRELAYS; i++) { - expand_ipbits(ipaddr,RELAYS[i].ipbits); - if ( myinfo->myaddr.myipbits == RELAYS[i].ipbits ) - RELAYID = i; - basilisk_ensurerelay(myinfo,btcd,RELAYS[i].ipbits); + expand_ipbits(ipaddr,myinfo->NOTARY.RELAYS[i].ipbits); + if ( myinfo->myaddr.myipbits == myinfo->NOTARY.RELAYS[i].ipbits ) + myinfo->NOTARY.RELAYID = i; + basilisk_ensurerelay(myinfo,notaries,myinfo->NOTARY.RELAYS[i].ipbits); } } char *basilisk_addrelay_info(struct supernet_info *myinfo,uint8_t *pubkey33,uint32_t ipbits,bits256 pubkey) { int32_t i; struct basilisk_relay *rp; - for (i=0; iNOTARY.NUMRELAYS; i++) { - rp = &RELAYS[i]; + rp = &myinfo->NOTARY.RELAYS[i]; if ( ipbits == rp->ipbits ) { if ( bits256_cmp(GENESIS_PUBKEY,pubkey) != 0 && bits256_nonz(pubkey) != 0 ) rp->pubkey = pubkey; if ( pubkey33 != 0 && pubkey33[0] != 0 ) memcpy(rp->pubkey33,pubkey33,33); - //printf("updated relay[%d] %x\n",i,ipbits); + basilisk_setmyid(myinfo); + //printf("updated relay[%d] %x vs mine.%x\n",i,ipbits,myinfo->myaddr.myipbits); return(clonestr("{\"error\":\"relay already there\"}")); } } - if ( i >= sizeof(RELAYS)/sizeof(*RELAYS) ) - i = (rand() % (sizeof(RELAYS)/sizeof(*RELAYS))); + if ( i >= sizeof(myinfo->NOTARY.RELAYS)/sizeof(*myinfo->NOTARY.RELAYS) ) + i = (rand() % (sizeof(myinfo->NOTARY.RELAYS)/sizeof(*myinfo->NOTARY.RELAYS))); printf("add relay[%d] <- %x\n",i,ipbits); - for (i=0; iNOTARY.NUMRELAYS; i++) + myinfo->NOTARY.RELAYS[i].oldrelayid = i; + rp = &myinfo->NOTARY.RELAYS[i]; rp->ipbits = ipbits; - rp->relayid = NUMRELAYS; - basilisk_ensurerelay(myinfo,iguana_coinfind("BTCD"),rp->ipbits); - if ( NUMRELAYS < sizeof(RELAYS)/sizeof(*RELAYS) ) - NUMRELAYS++; - qsort(RELAYS,NUMRELAYS,sizeof(RELAYS[0]),_increasing_ipbits); - for (i=0; irelayid = myinfo->NOTARY.NUMRELAYS; + basilisk_ensurerelay(myinfo,iguana_coinfind("RELAY"),rp->ipbits); + if ( myinfo->NOTARY.NUMRELAYS < sizeof(myinfo->NOTARY.RELAYS)/sizeof(*myinfo->NOTARY.RELAYS) ) + myinfo->NOTARY.NUMRELAYS++; + qsort(myinfo->NOTARY.RELAYS,myinfo->NOTARY.NUMRELAYS,sizeof(myinfo->NOTARY.RELAYS[0]),_increasing_ipbits); + for (i=0; iNOTARY.NUMRELAYS; i++) + myinfo->NOTARY.RELAYS[i].relayid = i; basilisk_setmyid(myinfo); - printf("sorted MYRELAYID.%d\n",RELAYID); - for (i=0; iNOTARY.RELAYID); + for (i=0; iNOTARY.NUMRELAYS; i++) + basilisk_relay_remap(myinfo,&myinfo->NOTARY.RELAYS[i]); return(clonestr("{\"result\":\"relay added\"}")); } @@ -140,6 +146,8 @@ void basilisk_request_goodbye(struct supernet_info *myinfo) char *basilisk_respond_addrelay(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) { char *ipaddr,*retstr=0; + if ( valsobj == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); if ( (ipaddr= jstr(valsobj,"ipaddr")) != 0 ) retstr = basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(ipaddr),jbits256(valsobj,"pubkey")); else retstr = clonestr("{\"error\":\"need rmd160, address and ipaddr\"}"); @@ -203,7 +211,7 @@ char *basilisk_respond_VPNmessage(struct supernet_info *myinfo,char *CMD,void *a if ( coin != 0 && (ptr= basilisk_bitcoinrawtx(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,valsobj)) != 0 ) { retstr = ptr->retstr; - ptr->finished = (uint32_t)time(NULL); + ptr->finished = OS_milliseconds() + 10000; } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoinrawtx\"}"); return(retstr); }*/ @@ -217,8 +225,8 @@ char *basilisk_respond_value(struct supernet_info *myinfo,char *CMD,void *addr,c if ( coin != 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,valsobj)) != 0 ) { retstr = ptr->retstr; - ptr->finished = (uint32_t)time(NULL); - } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoinrawtx\"}"); + ptr->finished = OS_milliseconds() + 10000; + } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoin value\"}"); return(retstr); } @@ -231,14 +239,34 @@ char *basilisk_respond_balances(struct supernet_info *myinfo,char *CMD,void *add if ( coin != 0 && (ptr= basilisk_bitcoinbalances(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,valsobj)) != 0 ) { retstr = ptr->retstr; - ptr->finished = (uint32_t)time(NULL); - } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoinrawtx\"}"); + ptr->finished = OS_milliseconds() + 10000; + } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoin balances\"}"); + return(retstr); +} + +char *basilisk_respond_getinfo(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *symbol,*retstr=0; struct basilisk_item Lptr,*ptr; int32_t timeoutmillis; struct iguana_info *coin = 0; + if ( (timeoutmillis= jint(valsobj,"timeout")) <= 0 ) + timeoutmillis = 5000; + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + coin = iguana_coinfind(symbol); + if ( coin != 0 && (ptr= basilisk_getinfo(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,valsobj)) != 0 ) + { + retstr = ptr->retstr; + ptr->finished = OS_milliseconds() + 10000; + } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoin getinfo\"}"); return(retstr); } #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" +HASH_ARRAY_STRING(basilisk,vote,hash,vals,hexstr) +{ + return(basilisk_standardservice("VOT",myinfo,0,hash,vals,hexstr,0)); +} + HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr) { return(basilisk_standardservice("ADD",myinfo,0,hash,vals,hexstr,1)); diff --git a/basilisk/basilisk_DEX.c b/basilisk/basilisk_DEX.c index 4921dee2a..17ed0816e 100755 --- a/basilisk/basilisk_DEX.c +++ b/basilisk/basilisk_DEX.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -34,7 +34,7 @@ int32_t basilisk_ping_processDEX(struct supernet_info *myinfo,uint32_t senderipb if ( relay->numrequests < relay->maxrequests ) { memcpy(serialized,&data[len],clen); - //printf("ping processDEX\n"); + printf("ping processDEX\n"); n = basilisk_rwDEXquote(0,serialized,&R); if ( n != clen ) printf("n.%d clen.%d\n",n,clen); @@ -100,10 +100,10 @@ int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_r len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->timestamp),&rp->timestamp); // must be 2nd len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quoteid),&rp->quoteid); len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quotetime),&rp->quotetime); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->relaybits),&rp->relaybits); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->optionhours),&rp->optionhours); len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->srcamount),&rp->srcamount); len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->minamount),&rp->minamount); - len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->hash),rp->hash.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->srchash),rp->srchash.bytes); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->desthash),rp->desthash.bytes); len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->destamount),&rp->destamount); if ( rwflag != 0 ) @@ -116,16 +116,19 @@ int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_r memcpy(rp->src,&serialized[len],sizeof(rp->src)), len += sizeof(rp->src); memcpy(rp->dest,&serialized[len],sizeof(rp->dest)), len += sizeof(rp->dest); } + //len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->DEXselector),&rp->DEXselector); + //len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->extraspace),&rp->extraspace); if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) - printf("basilisk_rwDEXquote.%d: quoteid.%u mismatch calc %u\n",rwflag,rp->quoteid,basilisk_quoteid(rp)); + printf(" basilisk_rwDEXquote.%d: quoteid.%u mismatch calc %u rp.%p\n",rwflag,rp->quoteid,basilisk_quoteid(rp),rp); if ( basilisk_requestid(rp) != rp->requestid ) - printf("basilisk_rwDEXquote.%d: requestid.%u mismatch calc %u\n",rwflag,rp->requestid,basilisk_requestid(rp)); + printf(" basilisk_rwDEXquote.%d: requestid.%u mismatch calc %u rp.%p\n",rwflag,rp->requestid,basilisk_requestid(rp),rp); return(len); } uint32_t basilisk_request_enqueue(struct supernet_info *myinfo,struct basilisk_request *rp) { uint8_t serialized[256]; int32_t len; struct queueitem *item; + //printf(" basilisk_request_enqueue\n"); len = basilisk_rwDEXquote(1,serialized+1,rp); if ( (item= calloc(1,sizeof(*item) + len + 1)) != 0 ) { @@ -134,7 +137,7 @@ uint32_t basilisk_request_enqueue(struct supernet_info *myinfo,struct basilisk_r portable_mutex_lock(&myinfo->DEX_mutex); DL_APPEND(myinfo->DEX_quotes,item); portable_mutex_unlock(&myinfo->DEX_mutex); - printf("ENQUEUE.%u calc.%u\n",rp->requestid,basilisk_requestid(rp)); + //printf("ENQUEUE.%u calc.%u\n",rp->requestid,basilisk_requestid(rp)); return(rp->requestid); } return(0); @@ -142,13 +145,13 @@ uint32_t basilisk_request_enqueue(struct supernet_info *myinfo,struct basilisk_r cJSON *basilisk_requestjson(struct basilisk_request *rp) { - char ipaddr[64]; cJSON *item = cJSON_CreateObject(); - if ( rp->relaybits != 0 ) + cJSON *item = cJSON_CreateObject(); + /*if ( rp->relaybits != 0 ) { expand_ipbits(ipaddr,rp->relaybits); jaddstr(item,"relay",ipaddr); - } - jaddbits256(item,"hash",rp->hash); + }*/ + jaddbits256(item,"srchash",rp->srchash); if ( bits256_nonz(rp->desthash) != 0 ) jaddbits256(item,"desthash",rp->desthash); jaddstr(item,"src",rp->src); @@ -158,11 +161,18 @@ cJSON *basilisk_requestjson(struct basilisk_request *rp) jadd64bits(item,"minamount",rp->minamount); jaddstr(item,"dest",rp->dest); if ( rp->destamount != 0 ) - jadd64bits(item,"destamount",rp->destamount); + { + //jadd64bits(item,"destamount",rp->destamount); + jadd64bits(item,"destsatoshis",rp->destamount); + //printf("DESTSATOSHIS.%llu\n",(long long)rp->destamount); + } jaddnum(item,"quotetime",rp->quotetime); jaddnum(item,"timestamp",rp->timestamp); jaddnum(item,"requestid",rp->requestid); jaddnum(item,"quoteid",rp->quoteid); + //jaddnum(item,"DEXselector",rp->DEXselector); + jaddnum(item,"optionhours",rp->optionhours); + jaddnum(item,"profit",(double)rp->profitmargin / 1000000.); if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) printf("quoteid mismatch %u vs %u\n",basilisk_quoteid(rp),rp->quoteid); if ( basilisk_requestid(rp) != rp->requestid ) @@ -171,11 +181,11 @@ cJSON *basilisk_requestjson(struct basilisk_request *rp) int32_t i; struct basilisk_request R; if ( basilisk_parsejson(&R,item) != 0 ) { - if ( memcmp(&R,rp,sizeof(*rp)) != 0 ) + if ( memcmp(&R,rp,sizeof(*rp)-sizeof(uint32_t)) != 0 ) { for (i=0; idestamount= j64bits(valsobj,"destsatoshis")) != 0 ) { - rp->desthash = jbits256(valsobj,"desthash"); + rp->desthash = desthash; for (i=0; i<4; i++) if ( rp->desthash.ulongs[i] != 0 ) break; @@ -206,14 +216,20 @@ int32_t basilisk_request_create(struct basilisk_request *rp,cJSON *valsobj,bits2 } rp->minamount = j64bits(valsobj,"minamount"); rp->timestamp = timestamp; - rp->hash = hash; + rp->srchash = jbits256(valsobj,"srchash"); + rp->optionhours = jint(valsobj,"optionhours"); + rp->profitmargin = jdouble(valsobj,"profit") * 1000000; + //rp->DEXselector = DEXselector; strncpy(rp->src,src,sizeof(rp->src)-1); strncpy(rp->dest,dest,sizeof(rp->dest)-1); + //if ( jstr(valsobj,"relay") != 0 ) + // rp->relaybits = (uint32_t)calc_ipbits(jstr(valsobj,"relay")); rp->requestid = basilisk_requestid(rp); + //printf("set requestid <- %u\n",rp->requestid); if ( rp->destamount != 0 && bits256_nonz(rp->desthash) != 0 ) { rp->quoteid = basilisk_quoteid(rp); - printf("set quoteid.%u\n",rp->quoteid); + //printf("set quoteid.%u\n",rp->quoteid); } //printf("create.%u calc.%u\n",rp->requestid,basilisk_requestid(rp)); return(0); @@ -221,18 +237,42 @@ int32_t basilisk_request_create(struct basilisk_request *rp,cJSON *valsobj,bits2 return(-1); } -char *basilisk_start(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t statebits) +char *basilisk_start(struct supernet_info *myinfo,bits256 privkey,struct basilisk_request *_rp,uint32_t statebits,int32_t optionduration) { - cJSON *retjson; - if ( (bits256_cmp(rp->hash,myinfo->myaddr.persistent) == 0 || bits256_cmp(rp->desthash,myinfo->myaddr.persistent) == 0) ) + cJSON *retjson; char typestr[64]; bits256 tmpprivkey; double bidasks[2]; struct basilisk_request *rp=0; int32_t i,srcmatch,destmatch; + if ( _rp->requestid == myinfo->lastdexrequestid ) + { + printf("filter duplicate r%u\n",_rp->requestid); + return(clonestr("{\"error\":\"filter duplicate requestid\"}")); + } + srcmatch = smartaddress_pubkey(myinfo,typestr,bidasks,&tmpprivkey,_rp->src,_rp->srchash) >= 0; + destmatch = smartaddress_pubkey(myinfo,typestr,bidasks,&tmpprivkey,_rp->dest,_rp->desthash) >= 0; + char str[65],str2[65]; printf("%s srcmatch.%d %s destmatch.%d\n",bits256_str(str,_rp->srchash),srcmatch,bits256_str(str2,_rp->desthash),destmatch); + if ( srcmatch != 0 || destmatch != 0 ) { - printf("START thread to complete %u/%u for (%s %.8f) <-> (%s %.8f) q.%u\n",rp->requestid,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount),rp->quoteid); - if ( basilisk_thread_start(myinfo,rp) != 0 ) + for (i=0; inumswaps; i++) + if ( myinfo->swaps[i]->I.req.requestid == _rp->requestid ) + { + printf("basilisk_thread_start error trying to start requestid.%u which is already started\n",rp->requestid); + break; + } + if ( i == myinfo->numswaps ) + { + rp = calloc(1,sizeof(*rp)); + *rp = *_rp; + printf("START thread to complete %u/%u for (%s %.8f) <-> (%s %.8f) q.%u\n",rp->requestid,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount),rp->quoteid); + myinfo->lastdexrequestid = rp->requestid; + if ( basilisk_thread_start(myinfo,privkey,rp,statebits,optionduration,0) != 0 ) + { + basilisk_request_enqueue(myinfo,rp); + return(clonestr("{\"result\":\"started atomic swap thread\"}")); + } else return(clonestr("{\"error\":\"couldnt atomic swap thread\"}")); + } + else { - basilisk_request_enqueue(myinfo,rp); - return(clonestr("{\"result\":\"started atomic swap thread\"}")); + printf("trying to start already pending swap.r%u\n",rp->requestid); + return(clonestr("{\"error\":\"cant start pending swap\"}")); } - else return(clonestr("{\"error\":\"couldnt atomic swap thread\"}")); } else if ( myinfo->IAMLP != 0 ) { @@ -242,12 +282,69 @@ char *basilisk_start(struct supernet_info *myinfo,struct basilisk_request *rp,ui } else return(clonestr("{\"error\":\"unexpected basilisk_start not mine and amrelay\"}")); } +int32_t basilisk_requests_poll(struct supernet_info *myinfo) +{ + static uint32_t lastpoll; + char *retstr,typestr[64]; uint8_t data[32768]; cJSON *outerarray,*retjson; uint32_t msgid,channel; int32_t datalen,i,n,retval = 0; struct basilisk_request issueR; bits256 privkey; double bidasks[2],hwm = 0.; + if ( myinfo->IAMNOTARY != 0 || time(NULL) < lastpoll+5 || (myinfo->IAMLP == 0 && myinfo->DEXactive < time(NULL)) ) + return(retval); + lastpoll = (uint32_t)time(NULL); + memset(&issueR,0,sizeof(issueR)); + memset(&myinfo->DEXaccept,0,sizeof(myinfo->DEXaccept)); + //printf("Call incoming\n"); + if ( (retstr= InstantDEX_incoming(myinfo,0,0,0,0)) != 0 ) + { + //printf("poll.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (outerarray= jarray(&n,retjson,"responses")) != 0 ) + { + retval++; + for (i=0; i 0. ) + { + myinfo->DEXaccept = issueR; + if ( smartaddress_pubkey(myinfo,typestr,bidasks,&privkey,issueR.src,issueR.srchash) >= 0 ) + { + if ( myinfo->DEXtrades > 0 ) + { + dex_channelsend(myinfo,issueR.srchash,issueR.desthash,channel,0x4000000,(void *)&issueR.requestid,sizeof(issueR.requestid)); // 60 + dpow_nanomsg_update(myinfo); + dex_updateclient(myinfo); + if ( (retstr= basilisk_start(myinfo,privkey,&issueR,1,issueR.optionhours * 3600)) != 0 ) + free(retstr); + } + } + else if ( myinfo->IAMLP != 0 && issueR.requestid != myinfo->lastdexrequestid )//if ( issueR.quoteid == 0 ) + { + issueR.quoteid = basilisk_quoteid(&issueR); + issueR.desthash = myinfo->myaddr.persistent; + datalen = basilisk_rwDEXquote(1,data,&issueR); + msgid = (uint32_t)time(NULL); + printf("other req hwm %f >>>>>>>>>>> send response (%llx -> %llx) last.%u r.%u quoteid.%u\n",hwm,(long long)issueR.desthash.txid,(long long)issueR.srchash.txid,myinfo->lastdexrequestid,issueR.requestid,issueR.quoteid); + dex_channelsend(myinfo,issueR.desthash,issueR.srchash,channel,msgid,data,datalen); //INSTANTDEX_LOCKTIME*2 + dpow_nanomsg_update(myinfo); + dex_updateclient(myinfo); + if ( (retstr= basilisk_start(myinfo,myinfo->persistent_priv,&issueR,0,issueR.optionhours * 3600)) != 0 ) + free(retstr); + } //else printf("basilisk_requests_poll unexpected hwm issueR\n"); + } + return(retval); +} + struct basilisk_relay *basilisk_request_ensure(struct supernet_info *myinfo,uint32_t senderipbits,int32_t numrequests) { int32_t j; struct basilisk_relay *relay = 0; if ( (j= basilisk_relayid(myinfo,senderipbits)) >= 0 ) { - relay = &RELAYS[j]; + relay = &myinfo->NOTARY.RELAYS[j]; if ( numrequests > relay->maxrequests ) { relay->maxrequests = numrequests; @@ -281,17 +378,30 @@ static int _cmp_requests(const void *a,const void *b) #undef uint32_b } -struct basilisk_request *_basilisk_requests_uniq(struct supernet_info *myinfo,int32_t *nump,uint8_t *space,int32_t spacesize) +struct basilisk_request *_basilisk_requests_uniq(struct supernet_info *myinfo,int32_t *nump,uint8_t *space,int32_t spacesize,struct basilisk_request *refrp) { int32_t i,j,n,k,m; struct basilisk_relay *relay; struct basilisk_request *requests,*rp; - for (j=m=0; jNOTARY.NUMRELAYS; j++) + m += myinfo->NOTARY.RELAYS[j].numrequests; if ( m*sizeof(*requests) <= spacesize ) requests = (void *)space; else requests = calloc(m,sizeof(*requests)); - for (j=m=0; jNOTARY.NUMRELAYS; j++) + { + relay = &myinfo->NOTARY.RELAYS[j]; if ( (n= relay->numrequests) > 0 ) { for (i=0; iipbits; + //requests[m].relaybits = relay->ipbits; requests[m++] = *rp; } } @@ -322,20 +432,22 @@ struct basilisk_request *_basilisk_requests_uniq(struct supernet_info *myinfo,in return(jprint(retjson,1)); }*/ -char *basilisk_respond_requests(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint32_t quoteid) +char *basilisk_respond_requests(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint32_t quoteid,struct basilisk_request *refrp) { int32_t i,qflag,num=0; cJSON *retjson,*array; struct basilisk_request *requests,*rp; uint8_t space[4096]; array = cJSON_CreateArray(); portable_mutex_lock(&myinfo->DEX_reqmutex); - if ( (requests= _basilisk_requests_uniq(myinfo,&num,space,sizeof(space))) != 0 ) + if ( (requests= _basilisk_requests_uniq(myinfo,&num,space,sizeof(space),refrp)) != 0 ) { - //printf("numrequests.%d r.%u q.%u\n",num,requestid,quoteid); for (i=0; iquoteid && (bits256_cmp(hash,rp->hash) == 0 || bits256_cmp(hash,rp->desthash) == 0)) ) + if ( quoteid == 0 || (quoteid == rp->quoteid && (bits256_cmp(hash,rp->srchash) == 0 || bits256_cmp(hash,rp->desthash) == 0)) ) qflag = 1; else qflag = 0; + //int32_t j; for (j=0; jrequestid == requestid && qflag != 0) ) jaddi(array,basilisk_requestjson(rp)); } @@ -348,11 +460,11 @@ char *basilisk_respond_requests(struct supernet_info *myinfo,bits256 hash,uint32 return(jprint(retjson,1)); } -char *basilisk_respond_accept(struct supernet_info *myinfo,uint32_t requestid,uint32_t quoteid) +char *basilisk_respond_accept(struct supernet_info *myinfo,bits256 privkey,uint32_t requestid,uint32_t quoteid,struct basilisk_request *refrp) { int32_t i,num=0; char *retstr=0; struct basilisk_request *requests,*rp; uint8_t space[4096]; portable_mutex_lock(&myinfo->DEX_reqmutex); - if ( (requests= _basilisk_requests_uniq(myinfo,&num,space,sizeof(space))) != 0 ) + if ( (requests= _basilisk_requests_uniq(myinfo,&num,space,sizeof(space),refrp)) != 0 ) { for (i=0; irequestid == requestid && rp->quoteid == quoteid ) { printf("start from accept\n"); - retstr = basilisk_start(myinfo,rp,1); + retstr = basilisk_start(myinfo,privkey,rp,1,0); break; } } @@ -373,181 +485,54 @@ char *basilisk_respond_accept(struct supernet_info *myinfo,uint32_t requestid,ui return(retstr); } -// respond to incoming RID, ACC, DEX, QST - -/*char *basilisk_respond_RID(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) -{ - return(basilisk_respond_requests(myinfo,hash,juint(valsobj,"requestid"),0)); -} - -char *basilisk_respond_SWP(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) -{ -return(basilisk_respond_swapstatus(myinfo,hash,juint(valsobj,"requestid"),juint(valsobj,"quoteid"))); -} - -char *basilisk_respond_ACC(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) -{ - uint32_t requestid,quoteid; - if ( (requestid= juint(valsobj,"requestid")) != 0 && (quoteid= juint(valsobj,"quoteid")) != 0 ) - return(basilisk_respond_accept(myinfo,requestid,quoteid)); - else return(clonestr("{\"error\":\"need nonzero requestid and quoteid\"}")); -} - -char *basilisk_respond_DEX(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +cJSON *basilisk_unspents(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) { - char *retstr=0,buf[256]; struct basilisk_request R; - if ( basilisk_request_create(&R,valsobj,hash,juint(valsobj,"timestamp")) == 0 ) + cJSON *unspents=0,*array=0,*json,*ismine; char *retstr; int32_t valid = 0; + if ( coin->FULLNODE > 0 ) { - char str[65]; printf("DEX.(%s %.8f) -> %s %s\n",R.src,dstr(R.srcamount),R.dest,bits256_str(str,hash)); - if ( basilisk_request_enqueue(myinfo,&R) != 0 ) - { - sprintf(buf,"{\"result\":\"DEX request added\",\"requestid\":%u}",R.requestid); - retstr = clonestr(buf); - } else retstr = clonestr("{\"error\":\"DEX quote couldnt be created\"}"); - } else retstr = clonestr("{\"error\":\"missing or invalid fields\"}"); - return(retstr); -}*/ - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) -{ - double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); - aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"aveprice",aveprice); - jaddnum(retjson,"avebid",retvals[0]); - jaddnum(retjson,"bidvol",retvals[1]); - jaddnum(retjson,"aveask",retvals[2]); - jaddnum(retjson,"askvol",retvals[3]); - return(jprint(retjson,1)); -} - -ZERO_ARGS(InstantDEX,allcoins) -{ - struct iguana_info *tmp; cJSON *basilisk,*virtual,*full,*retjson = cJSON_CreateObject(); - full = cJSON_CreateArray(); - basilisk = cJSON_CreateArray(); - virtual = cJSON_CreateArray(); - HASH_ITER(hh,myinfo->allcoins,coin,tmp) - { - if ( coin->virtualchain != 0 ) - jaddistr(virtual,coin->symbol); - if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) - jaddistr(full,coin->symbol); - else jaddistr(basilisk,coin->symbol); + array = cJSON_CreateArray(); + jaddistr(array,coinaddr); + unspents = iguana_listunspents(myinfo,coin,array,0,0,""); + free_json(array); } - jadd(retjson,"basilisk",basilisk); - jadd(retjson,"full",full); - jadd(retjson,"virtual",virtual); - return(jprint(retjson,1)); -} - -STRING_ARG(InstantDEX,available,source) -{ - if ( source != 0 && source[0] != 0 && (coin= iguana_coinfind(source)) != 0 ) - { - if ( myinfo->expiration != 0 ) - return(bitcoinrpc_getbalance(myinfo,coin,json,remoteaddr,"*",coin->chain->minconfirms,1,1<<30)); - else return(clonestr("{\"error\":\"need to unlock wallet\"}")); - } else return(clonestr("{\"error\":\"specified coin is not active\"}")); -} - -HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) -{ - uint8_t serialized[512]; struct basilisk_request R; cJSON *reqjson; uint32_t datalen=0,DEX_channel; - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN); - if ( jobj(vals,"desthash") == 0 ) - jaddbits256(vals,"desthash",hash); - jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN); - jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN); - jaddnum(vals,"timestamp",time(NULL)); - hash = myinfo->myaddr.persistent; - printf("service.(%s)\n",jprint(vals,0)); + else { - memset(&R,0,sizeof(R)); - if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp")) == 0 ) + if ( coin->FULLNODE < 0 && (retstr= dpow_validateaddress(myinfo,coin,coinaddr)) != 0 ) { - printf("R.requestid.%u vs calc %u, q.%u\n",R.requestid,basilisk_requestid(&R),R.quoteid); - if ( RELAYID >= 0 ) - R.relaybits = myinfo->myaddr.myipbits; - if ( (reqjson= basilisk_requestjson(&R)) != 0 ) - free_json(reqjson); - datalen = basilisk_rwDEXquote(1,serialized,&R); - printf("R.requestid.%u vs calc %u, q.%u datalen.%d\n",R.requestid,basilisk_requestid(&R),R.quoteid,datalen); - basilisk_rwDEXquote(0,serialized,&R); - } else printf("error creating request\n"); - } - if ( datalen > 0 ) - { - memset(hash.bytes,0,sizeof(hash)); - DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); - if ( basilisk_channelsend(myinfo,hash,DEX_channel,(uint32_t)time(NULL),serialized,datalen,30) == 0 ) - return(clonestr("{\"result\":\"DEX message sent\"}")); - else return(clonestr("{\"error\":\"DEX message couldnt be sent\"}")); - } - return(clonestr("{\"error\":\"DEX message not sent\"}")); - //return(basilisk_standardservice("DEX",myinfo,0,myinfo->myaddr.persistent,vals,"",1)); -} - -INT_ARG(InstantDEX,automatched,requestid) -{ - // return quoteid - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - return(clonestr("{\"result\":\"automatched not yet\"}")); -} - -INT_ARG(InstantDEX,incoming,requestid) -{ - cJSON *vals; char *retstr; - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - //if ( myinfo->IAMLP != 0 ) - // return(basilisk_respond_requests(myinfo,myinfo->myaddr.persistent,requestid,0)); - //else - { - vals = cJSON_CreateObject(); - jaddnum(vals,"requestid",(uint32_t)requestid); - jaddbits256(vals,"hash",myinfo->myaddr.persistent); - retstr = basilisk_standardservice("RID",myinfo,0,myinfo->myaddr.persistent,vals,"",1); - free_json(vals); - return(retstr); + json = cJSON_Parse(retstr); + if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) + valid = 1; + free(retstr); + } + if ( coin->FULLNODE == 0 || valid == 0 ) + { + if ( (retstr= dex_listunspent(myinfo,coin,0,0,coin->symbol,coinaddr)) != 0 ) + { + unspents = cJSON_Parse(retstr); + free(retstr); + } + } else unspents = dpow_listunspent(myinfo,coin,coinaddr); } + return(unspents); } -/*TWO_INTS(InstantDEX,swapstatus,requestid,quoteid) +char *basilisk_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx) { - cJSON *vals; char *retstr; - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - //if ( myinfo->IAMLP != 0 ) - // return(basilisk_respond_swapstatus(myinfo,myinfo->myaddr.persistent,requestid,quoteid)); - //else + char *retstr,buf[65]; bits256 txid; + if ( coin->FULLNODE > 0 ) { - vals = cJSON_CreateObject(); - jaddnum(vals,"requestid",(uint32_t)requestid); - jaddnum(vals,"quoteid",(uint32_t)quoteid); - jaddbits256(vals,"hash",myinfo->myaddr.persistent); - retstr = basilisk_standardservice("SWP",myinfo,0,myinfo->myaddr.persistent,vals,"",1); - free_json(vals); - return(retstr); + txid = iguana_sendrawtransaction(myinfo,coin,signedtx); + if ( bits256_nonz(txid) ) + { + bits256_str(buf,txid); + retstr = clonestr(buf); + } else retstr = clonestr("{\"error\":\"couldnt validate or send signedtx\"}"); } -}*/ - -TWO_INTS(InstantDEX,accept,requestid,quoteid) -{ - cJSON *vals; char *retstr; - myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; - //if ( myinfo->IAMLP != 0 ) - // return(basilisk_respond_accept(myinfo,requestid,quoteid)); - //else + else if ( coin->FULLNODE == 0 ) { - vals = cJSON_CreateObject(); - jaddnum(vals,"quoteid",(uint32_t)quoteid); - jaddnum(vals,"requestid",(uint32_t)requestid); - retstr = basilisk_standardservice("ACC",myinfo,0,myinfo->myaddr.persistent,vals,"",1); - free_json(vals); - return(retstr); + retstr = _dex_sendrawtransaction(myinfo,coin->symbol,signedtx); } + else retstr = dpow_sendrawtransaction(myinfo,coin,signedtx); + return(retstr); } -#include "../includes/iguana_apiundefs.h" + diff --git a/basilisk/basilisk_MSG.c b/basilisk/basilisk_MSG.c index c64269041..0fba54c91 100755 --- a/basilisk/basilisk_MSG.c +++ b/basilisk/basilisk_MSG.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -15,68 +15,16 @@ // included from basilisk.c -char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping,uint32_t duration) +int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp) { - struct basilisk_message *msg; int32_t i; - HASH_FIND(hh,myinfo->messagetable,key,keylen,msg); - if ( msg == 0 && keylen == BASILISK_KEYSIZE ) - { - msg = calloc(1,sizeof(*msg) + datalen); - if ( duration == 0 ) - duration = BASILISK_MSGDURATION; - else if ( duration > INSTANTDEX_LOCKTIME*2 ) - duration = INSTANTDEX_LOCKTIME*2; - msg->duration = duration; - msg->expiration = (uint32_t)time(NULL) + duration; - msg->keylen = keylen; - memcpy(msg->key,key,keylen); - msg->datalen = datalen; - memcpy(msg->data,data,datalen); - portable_mutex_lock(&myinfo->messagemutex); - HASH_ADD_KEYPTR(hh,myinfo->messagetable,msg->key,msg->keylen,msg); - for (i=0; imessagemutex); - if ( sendping != 0 ) - { - queue_enqueue("basilisk_message",&myinfo->msgQ,&msg->DL,0); - return(clonestr("{\"result\":\"message added to hashtable\"}")); - } else return(0); - } else return(0); -} - -cJSON *basilisk_respond_getmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen) -{ - cJSON *msgjson=0; struct basilisk_message *msg; char *ptr = 0,strbuf[32768]; - portable_mutex_lock(&myinfo->messagemutex); - HASH_FIND(hh,myinfo->messagetable,key,keylen,msg); - if ( msg != 0 ) - { - msgjson = cJSON_CreateObject(); - if ( basilisk_addhexstr(&ptr,msgjson,strbuf,sizeof(strbuf),msg->data,msg->datalen) != 0 ) - { - //retjson = cJSON_CreateObject(); - jaddnum(msgjson,"expiration",msg->expiration); - jaddnum(msgjson,"duration",msg->duration); - //jadd(retjson,"message",msgjson); - printf("havemessage len.%d\n",msg->datalen); - } - else - { - //jaddstr(retjson,"error","couldnt add message"); - printf("couldnt add message\n"); - free_json(msgjson); - msgjson = 0; - } - } - portable_mutex_unlock(&myinfo->messagemutex); - return(msgjson); + int32_t keylen = 0; + keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),channelp); + keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),msgidp); + keylen += iguana_rwbignum(0,&key[keylen],sizeof(*srchashp),srchashp->bytes); + keylen += iguana_rwbignum(0,&key[keylen],sizeof(*desthashp),desthashp->bytes); + return(keylen); } -// respond to incoming OUT, MSG - int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash) { int32_t keylen = 0; @@ -87,116 +35,291 @@ int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 return(keylen); } -char *basilisk_respond_OUT(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +cJSON *basilisk_msgjson(struct basilisk_message *msg,uint8_t *key,int32_t keylen) { - int32_t keylen,duration; uint8_t key[BASILISK_KEYSIZE]; bits256 senderhash; - senderhash = jbits256(valsobj,"sender"); - duration = juint(valsobj,"duration"); - keylen = basilisk_messagekey(key,juint(valsobj,"channel"),juint(valsobj,"msgid"),senderhash,hash); - if( bits256_nonz(senderhash) == 0 && bits256_nonz(hash) == 0 && duration > BASILISK_MSGDURATION ) - duration = BASILISK_MSGDURATION; - // printf("OUT keylen.%d datalen.%d\n",keylen,datalen); - // char str[65]; printf("add message.[%d] channel.%u msgid.%x %s\n",datalen,juint(valsobj,"channel"),juint(valsobj,"msgid"),bits256_str(str,hash)); - return(basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,1,duration)); + cJSON *msgjson=0; char *str = 0,strbuf[32768],keystr[BASILISK_KEYSIZE*2+1]; + msgjson = cJSON_CreateObject(); + if ( basilisk_addhexstr(&str,msgjson,strbuf,sizeof(strbuf),msg->data,msg->datalen) != 0 ) + { + init_hexbytes_noT(keystr,key,keylen); + jaddstr(msgjson,"key",keystr); + jaddnum(msgjson,"expiration",msg->expiration); + jaddnum(msgjson,"duration",msg->duration); + if ( str != 0 ) + free(str); + } + else + { + printf("basilisk_respond_getmessage: couldnt basilisk_addhexstr data.[%d]\n",msg->datalen); + free_json(msgjson); + msgjson = 0; + } + return(msgjson); } -char *basilisk_iterate_MSG(struct supernet_info *myinfo,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash,int32_t width) +cJSON *_basilisk_respond_getmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen) { - uint8_t key[BASILISK_KEYSIZE]; int32_t i,keylen; cJSON *item,*retjson,*array; bits256 zero; + cJSON *msgjson = 0; struct basilisk_message *msg; + HASH_FIND(hh,myinfo->messagetable,key,keylen,msg); + if ( msg != 0 && msg->broadcast == 0 ) + msgjson = basilisk_msgjson(msg,key,keylen); + return(msgjson); +} + +int32_t basilisk_msgcmp(struct basilisk_message *msg,int32_t width,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash) +{ + uint32_t keychannel,keymsgid,n=0; bits256 keysrc,keydest; + basilisk_messagekeyread(msg->key,&keychannel,&keymsgid,&keysrc,&keydest); + if ( bits256_nonz(srchash) == 0 || bits256_cmp(srchash,keysrc) == 0 ) + { + if ( bits256_nonz(desthash) == 0 || bits256_cmp(desthash,keydest) == 0 ) + { + while ( width >= 0 && n < 60 ) + { + if ( (keymsgid == 0 || msgid == keymsgid) && (keychannel == 0 || keychannel == channel) ) + return(0); + msgid--; + n++; + } + return(-1); + } else return(-2); + } else return(-3); +} + +char *basilisk_iterate_MSG(struct supernet_info *myinfo,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash,int32_t origwidth) +{ + uint8_t key[BASILISK_KEYSIZE]; int32_t i,keylen,width; cJSON *msgjson,*item,*retjson,*array; bits256 zero; struct basilisk_message *msg,*tmpmsg; uint32_t origmsgid,now = (uint32_t)time(NULL); + origmsgid = msgid; memset(zero.bytes,0,sizeof(zero)); - array = cJSON_CreateArray(); - if ( width > 3600 ) + if ( (width= origwidth) > 3600 ) width = 3600; else if ( width < 1 ) width = 1; + // char str[65],str2[65]; printf("MSGiterate (%s) -> (%s)\n",bits256_str(str,srchash),bits256_str(str2,desthash)); + array = cJSON_CreateArray(); + portable_mutex_lock(&myinfo->messagemutex); + //printf("iterate_MSG width.%d channel.%d msgid.%d src.%llx -> %llx\n",origwidth,channel,msgid,(long long)srchash.txid,(long long)desthash.txid); for (i=0; i 0 ) + } + //keylen = basilisk_messagekey(key,channel,msgid,desthash,srchash); + //if ( (item= _basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + // jaddi(array,item);//, printf("gotmsg0.(%s)\n",jprint(item,0)); + if ( origwidth > 0 ) { if ( bits256_nonz(srchash) != 0 ) { keylen = basilisk_messagekey(key,channel,msgid,zero,desthash); - if ( (item= basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + if ( (item= _basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + { + jaddbits256(item,"src",srchash); + jaddbits256(item,"dest",desthash); jaddi(array,item); + } + //keylen = basilisk_messagekey(key,channel,msgid,desthash,zero); + //if ( (item= _basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + // jaddi(array,item);//, printf("gotmsg1.(%s)\n",jprint(item,0)); } if ( bits256_nonz(desthash) != 0 ) { keylen = basilisk_messagekey(key,channel,msgid,srchash,zero); - if ( (item= basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + if ( (item= _basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + { + jaddbits256(item,"src",srchash); + jaddbits256(item,"dest",desthash); jaddi(array,item); + } + //keylen = basilisk_messagekey(key,channel,msgid,zero,srchash); + //if ( (item= _basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + // jaddi(array,item);//, printf("gotmsg2.(%s)\n",jprint(item,0)); } - if ( bits256_nonz(srchash) != 0 || bits256_nonz(desthash) != 0 ) + if ( bits256_nonz(srchash) != 0 && bits256_nonz(desthash) != 0 ) { keylen = basilisk_messagekey(key,channel,msgid,zero,zero); - if ( (item= basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + if ( (item= _basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + { + jaddbits256(item,"src",srchash); + jaddbits256(item,"dest",desthash); jaddi(array,item); + } } } msgid--; - iguana_rwnum(1,&key[0],sizeof(uint32_t),&msgid); } + HASH_ITER(hh,myinfo->messagetable,msg,tmpmsg) + { + if ( bits256_nonz(srchash) == 0 ) + { + if ( basilisk_msgcmp(msg,origwidth,channel,origmsgid,zero,zero) == 0 ) + { + if ( (msgjson= basilisk_msgjson(msg,msg->key,msg->keylen)) != 0 ) + { + jaddbits256(msgjson,"src",srchash); + jaddbits256(msgjson,"dest",desthash); + jaddi(array,msgjson); + } + } + } + if ( now > msg->expiration+60 ) + { + printf("delete expired message.%p QUEUEITEMS.%d\n",msg,QUEUEITEMS); + HASH_DELETE(hh,myinfo->messagetable,msg); + QUEUEITEMS--; + free(msg); + } + } + portable_mutex_unlock(&myinfo->messagemutex); if ( cJSON_GetArraySize(array) > 0 ) { retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jadd(retjson,"messages",array); + //printf("MESSAGES.(%s)\n",jprint(array,0)); return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no messages\"}")); + } + //printf("no matching messages\n"); + return(clonestr("{\"error\":\"no messages\"}")); } -char *basilisk_respond_MSG(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping,uint32_t duration) { - int32_t width; uint32_t msgid,channel; - width = juint(valsobj,"width"); - msgid = juint(valsobj,"msgid"); - channel = juint(valsobj,"channel"); - char str[65]; printf("%s channel.%u msgid.%x datalen.%d width.%d\n",bits256_str(str,hash),juint(valsobj,"channel"),msgid,datalen,width); - return(basilisk_iterate_MSG(myinfo,channel,msgid,jbits256(valsobj,"sender"),hash,width)); + struct basilisk_message *msg; bits256 desthash; + if ( keylen != BASILISK_KEYSIZE ) + { + printf("basilisk_respond_addmessage keylen.%d != %d\n",keylen,BASILISK_KEYSIZE); + return(0); + } + if ( duration == 0 ) + duration = BASILISK_MSGDURATION; + else if ( duration > INSTANTDEX_LOCKTIME*2 ) + duration = INSTANTDEX_LOCKTIME*2; + portable_mutex_lock(&myinfo->messagemutex); + HASH_FIND(hh,myinfo->messagetable,key,keylen,msg); + if ( msg != 0 ) + { + if ( msg->datalen != datalen ) + { + //printf("overwrite delete of msg.[%d]\n",msg->datalen); + HASH_DELETE(hh,myinfo->messagetable,msg); + QUEUEITEMS--; + free(msg); + msg = 0; + } + else + { + if ( memcmp(msg->data,data,datalen) != 0 ) + { + //printf("overwrite update of msg.[%d] <- datalen.%d\n",msg->datalen,datalen); + memcpy(msg->data,data,datalen); + if ( sendping != 0 ) + queue_enqueue("basilisk_message",&myinfo->msgQ,&msg->DL); + } + portable_mutex_unlock(&myinfo->messagemutex); + return(clonestr("{\"result\":\"message updated\"}")); + } + } + msg = calloc(1,sizeof(*msg) + datalen + 16); + msg->keylen = keylen; + memcpy(msg->key,key,keylen); + msg->datalen = datalen; + memcpy(msg->data,data,datalen); + memcpy(desthash.bytes,&key[BASILISK_KEYSIZE - sizeof(desthash)],sizeof(desthash)); + if ( bits256_nonz(desthash) == 0 ) + msg->broadcast = 1; + msg->duration = duration; + msg->expiration = (uint32_t)time(NULL) + duration; + HASH_ADD_KEYPTR(hh,myinfo->messagetable,msg->key,msg->keylen,msg); + QUEUEITEMS++; + portable_mutex_unlock(&myinfo->messagemutex); + { + bits256 srchash,desthash; uint32_t channel,msgid; + basilisk_messagekeyread(key,&channel,&msgid,&srchash,&desthash); + //printf("add message keylen.%d [%d] msgid.%x channel.%x\n",msg->keylen,datalen,msgid,channel); + } + //if ( myinfo->NOTARY.RELAYID >= 0 ) + // dpow_handler(myinfo,msg); + if ( sendping != 0 ) + queue_enqueue("basilisk_message",&myinfo->msgQ,&msg->DL); + return(clonestr("{\"result\":\"message added to hashtable\"}")); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" +// respond to incoming OUT, MSG -HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr) +char *basilisk_respond_OUT(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) { - uint32_t msgid,width,channel; - if ( (msgid= juint(vals,"msgid")) == 0 ) + int32_t keylen,duration; uint8_t key[BASILISK_KEYSIZE]; bits256 desthash,senderhash; char *retstr; + senderhash = jbits256(valsobj,"srchash"); + desthash = jbits256(valsobj,"desthash"); + duration = juint(valsobj,"duration"); + keylen = basilisk_messagekey(key,juint(valsobj,"channel"),juint(valsobj,"msgid"),senderhash,desthash); + if ( bits256_nonz(hash) == 0 ) { - msgid = (uint32_t)time(NULL); - jdelete(vals,"msgid"); - jaddnum(vals,"msgid",msgid); + if ( duration > BASILISK_MSGDURATION ) + duration = BASILISK_MSGDURATION; } - if ( RELAYID >= 0 ) + //char str[65]; printf("add message.[%d] %s from.%s\n",datalen,bits256_str(str,hash),remoteaddr); + retstr = basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,duration); + // printf("OUT keylen.%d datalen.%d\n",keylen,datalen); + return(retstr); +} + +char *basilisk_respond_MSG(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + int32_t width; uint32_t msgid,channel; char *retstr=0; + if ( valsobj != 0 ) { - channel = juint(vals,"channel"); - width = juint(vals,"width"); - return(basilisk_iterate_MSG(myinfo,channel,msgid,hash,myinfo->myaddr.persistent,width)); - } else return(basilisk_standardservice("MSG",myinfo,0,myinfo->myaddr.persistent,vals,hexstr,1)); + width = juint(valsobj,"width"); + msgid = juint(valsobj,"msgid"); + channel = juint(valsobj,"channel"); + //char str[65],str2[65]; printf("%s -> %s channel.%u msgid.%x width.%d from.%s\n",bits256_str(str,jbits256(valsobj,"sender")),bits256_str(str2,jbits256(valsobj,"desthash")),juint(valsobj,"channel"),msgid,width,remoteaddr); + retstr = basilisk_iterate_MSG(myinfo,channel,msgid,jbits256(valsobj,"srchash"),jbits256(valsobj,"desthash"),width); + } + return(retstr); } -HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) +cJSON *dpow_getmessage(struct supernet_info *myinfo,char *jsonstr) { - int32_t keylen,datalen; uint8_t key[BASILISK_KEYSIZE],space[16384],*data,*ptr = 0; char *retstr=0; - if ( RELAYID >= 0 ) + cJSON *valsobj,*retjson = 0; char *retstr; + if ( (valsobj= cJSON_Parse(jsonstr)) != 0 ) { - keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"sender"),hash); - if ( (data= get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,space,sizeof(space),hexstr)) != 0 ) - retstr = basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration")); - if ( ptr != 0 ) - free(ptr); + retstr = basilisk_iterate_MSG(myinfo,juint(valsobj,"channel"),juint(valsobj,"msgid"),jbits256(valsobj,"srchash"),jbits256(valsobj,"desthash"),juint(valsobj,"width")); + retjson = cJSON_Parse(retstr); + free(retstr); + } + return(retjson); +} + +cJSON *dpow_addmessage(struct supernet_info *myinfo,char *jsonstr) +{ + cJSON *vals,*retjson=0; char *retstr=0,*datastr; int32_t datalen,keylen; uint8_t *data=0,key[BASILISK_KEYSIZE]; + if ( (vals= cJSON_Parse(jsonstr)) != 0 ) + { + keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"srchash"),jbits256(vals,"desthash")); + if ( (datastr= jstr(vals,"data")) != 0 ) + { + datalen = (int32_t)strlen(datastr) >> 1; + data = malloc(datalen); + decode_hex(data,datalen,datastr); + if ( (retstr= basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration"))) != 0 ) + retjson = cJSON_Parse(retstr); + } if ( retstr != 0 ) free(retstr); + if ( data != 0 ) + free(data); } - if ( vals != 0 && juint(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",(int32_t)sqrt(NUMRELAYS)+2); - return(basilisk_standardservice("OUT",myinfo,0,hash,vals,hexstr,0)); + if ( retjson == 0 ) + retjson = cJSON_Parse("{\"error\":\"couldnt add message\"}"); + return(retjson); } -#include "../includes/iguana_apiundefs.h" -int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 hash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t duration) +int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t duration) { char *retstr,*hexstr,strbuf[4096],*ptr = 0; int32_t retval = -1; cJSON *valsobj; if ( (hexstr= basilisk_addhexstr(&ptr,0,strbuf,sizeof(strbuf),data,datalen)) != 0 ) @@ -205,12 +328,14 @@ int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 hash,uint32_t jaddnum(valsobj,"channel",channel); if ( msgid == 0 ) msgid = (uint32_t)time(NULL); - jaddnum(valsobj,"fanout",(int32_t)sqrt(NUMRELAYS)+2); + jaddnum(valsobj,"fanout",1);//MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+2)); jaddnum(valsobj,"msgid",msgid); jaddnum(valsobj,"duration",duration); - jaddbits256(valsobj,"sender",myinfo->myaddr.persistent); - char str[65]; printf("sendmessage.[%d] channel.%u msgid.%x -> %s numrelays.%d:%d\n",datalen,channel,msgid,bits256_str(str,hash),NUMRELAYS,juint(valsobj,"fanout")); - if ( (retstr= basilisk_sendmessage(myinfo,0,0,0,hash,valsobj,hexstr)) != 0 ) + jaddnum(valsobj,"timeout",1000); + jaddbits256(valsobj,"srchash",srchash); + jaddbits256(valsobj,"desthash",desthash); + //char str[65]; printf("sendmessage.[%d] channel.%u msgid.%x -> %s numrelays.%d\n",datalen,channel,msgid,bits256_str(str,desthash),myinfo->NOTARY.NUMRELAYS); + if ( (retstr= basilisk_sendmessage(myinfo,0,0,0,desthash,valsobj,hexstr)) != 0 ) free(retstr); free_json(valsobj); if ( ptr != 0 ) @@ -220,26 +345,31 @@ int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 hash,uint32_t return(retval); } -int32_t basilisk_message_returned(uint8_t *data,int32_t maxlen,cJSON *item) +int32_t basilisk_message_returned(uint8_t *key,uint8_t *data,int32_t maxlen,cJSON *json) { - char *hexstr=0; cJSON *msgobj; int32_t datalen=0,retval = -1; - if ( (msgobj= jobj(item,"message")) != 0 ) + char *keystr=0,*hexstr=0; int32_t i,n,datalen=0,retval = -1; cJSON *item,*msgobj; + if ( (msgobj= jarray(&n,json,"messages")) != 0 ) { - if ( (hexstr= jstr(msgobj,"data")) != 0 && (datalen= is_hexstr(hexstr,0)) > 0 ) + for (i=0; i>= 1; - if ( datalen < maxlen ) + item = jitem(msgobj,i); + if ( (keystr= jstr(item,"key")) != 0 && is_hexstr(keystr,0) == BASILISK_KEYSIZE*2 && (hexstr= jstr(item,"data")) != 0 && (datalen= is_hexstr(hexstr,0)) > 0 ) { - decode_hex(data,datalen,hexstr); - //printf("decoded hexstr.[%d]\n",datalen); - retval = datalen; - } else printf("datalen.%d < maxlen.%d\n",datalen,maxlen); - } else printf("no hexstr.%p or datalen.%d\n",hexstr,datalen); - } //else printf("no msgobj\n"); + decode_hex(key,BASILISK_KEYSIZE,keystr); + datalen >>= 1; + if ( datalen <= maxlen ) + { + decode_hex(data,datalen,hexstr); + //printf("decoded hexstr.[%d]\n",datalen); + retval = datalen; + } else printf("datalen.%d >= maxlen.%d\n",datalen,maxlen); + } + } + } //else printf("no hexstr.%p or datalen.%d (%s)\n",hexstr,datalen,jprint(json,0)); return(retval); } -cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 hash,uint32_t channel,uint32_t msgid,int32_t width) +cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,int32_t width) { char *retstr; cJSON *valsobj,*retarray=0,*item; valsobj = cJSON_CreateObject(); @@ -248,10 +378,21 @@ cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 hash,uint32_t ch msgid = (uint32_t)time(NULL); jaddnum(valsobj,"msgid",msgid); jaddnum(valsobj,"width",width); - jaddnum(valsobj,"fanout",1); - if ( (retstr= basilisk_getmessage(myinfo,0,0,0,hash,valsobj,0)) != 0 ) + jaddnum(valsobj,"timeout",BASILISK_TIMEOUT); + jaddnum(valsobj,"fanout",1);//MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + jaddnum(valsobj,"numrequired",1); + jaddbits256(valsobj,"srchash",srchash); + jaddbits256(valsobj,"desthash",desthash); + if ( myinfo->IAMNOTARY != 0 ) + retstr = basilisk_getmessage(myinfo,0,0,0,desthash,valsobj,0); + else + { + //char str[65],str2[65]; + retstr = _dex_getmessage(myinfo,jprint(valsobj,0)); + //printf("channel.%u msgid.%u gotmessage.(%d) %s %s %s\n",channel,msgid,(int32_t)strlen(retstr),strlen(retstr) < 100 ? retstr : "(too long)",bits256_str(str,srchash),bits256_str(str2,desthash)); + } + if ( retstr != 0 ) { - printf("channel.%u msgid.%u gotmessage.(%s)\n",channel,msgid,retstr); if ( (retarray= cJSON_Parse(retstr)) != 0 ) { if ( is_cJSON_Array(retarray) == 0 ) @@ -269,22 +410,153 @@ cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 hash,uint32_t ch int32_t basilisk_process_retarray(struct supernet_info *myinfo,void *ptr,int32_t (*process_func)(struct supernet_info *myinfo,void *ptr,int32_t (*internal_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration),uint8_t *data,int32_t maxlen,uint32_t channel,uint32_t msgid,cJSON *retarray,int32_t (*internal_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen)) { - cJSON *item; uint32_t duration,expiration; int32_t i,n,datalen,errs = 0; + cJSON *item; uint32_t duration,expiration; char *retstr; uint8_t key[BASILISK_KEYSIZE]; int32_t i,n,datalen,havedata = 0,errs = 0; if ( (n= cJSON_GetArraySize(retarray)) > 0 ) { for (i=0; i 0 ) + if ( jobj(item,"error") != 0 ) + continue; + //printf("(%s).%d ",jprint(item,0),i); + if ( (datalen= basilisk_message_returned(key,data,maxlen,item)) > 0 ) { duration = juint(item,"duration"); expiration = juint(item,"expiration"); - if ( (*process_func)(myinfo,ptr,internal_func,channel,msgid,data,datalen,expiration,duration) < 0 ) - errs++; + if ( (retstr= basilisk_respond_addmessage(myinfo,key,BASILISK_KEYSIZE,data,datalen,0,duration)) != 0 ) + { + if ( (*process_func)(myinfo,ptr,internal_func,channel,msgid,data,datalen,expiration,duration) < 0 ) + errs++; + else havedata++; + free(retstr); + } // else printf("duplicate.%d skipped\n",datalen); } } + //printf("n.%d maxlen.%d\n",n,maxlen); } - if ( errs > 0 ) + if ( havedata == 0 ) + return(-1); + else if ( errs > 0 ) return(-errs); - else return(n); + else return(havedata); +} + +uint32_t basilisk_majority32(int32_t *datalenp,uint32_t rawcrcs[64],int32_t datalens[64],int32_t numcrcs) +{ + int32_t tally[64],candlens[64],i,j,mintally,numcandidates = 0; uint32_t candidates[64]; + *datalenp = 0; + mintally = (numcrcs >> 1) + 1; + memset(tally,0,sizeof(tally)); + memset(candlens,0,sizeof(candlens)); + memset(candidates,0,sizeof(candidates)); + if ( numcrcs > 0 ) + { + for (i=0; i numcandidates.%d\n",i,numcandidates); + if ( numcandidates > 0 ) + { + for (j=0; j= mintally ) + { + *datalenp = candlens[j]; + //printf("tally[%d] %d >= mintally.%d numcrcs.%d crc %08x datalen.%d\n",j,tally[j],mintally,numcrcs,candidates[j],*datalenp); + return(candidates[j]); + } + } + } + return(0); +} + +uint32_t basilisk_crcrecv(struct supernet_info *myinfo,int32_t width,uint8_t *verifybuf,int32_t maxlen,int32_t *datalenp,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgbits) +{ + cJSON *retarray,*obj,*item,*msgarray; char *hexstr,*keystr,*retstr; uint32_t rawcrcs[64],crc=0; int32_t numcrcs=0,i,j,m,n,datalen,datalens[64]; uint8_t key[BASILISK_KEYSIZE]; + *datalenp = 0; + memset(rawcrcs,0,sizeof(rawcrcs)); + memset(datalens,0,sizeof(datalens)); + if ( (retarray= basilisk_channelget(myinfo,srchash,desthash,channel,msgbits,width)) != 0 ) + { + //printf("retarray.(%s)\n",jprint(retarray,0)); + if ( (n= cJSON_GetArraySize(retarray)) > 0 ) + { + for (i=0; i 0 ) + { + decode_hex(key,BASILISK_KEYSIZE,keystr); + datalen >>= 1; + if ( datalen < maxlen ) + { + decode_hex(verifybuf,datalen,hexstr); + if ( (retstr= basilisk_respond_addmessage(myinfo,key,BASILISK_KEYSIZE,verifybuf,datalen,juint(item,"expiration"),juint(item,"duration"))) != 0 ) + { + if ( numcrcs < sizeof(rawcrcs)/sizeof(*rawcrcs) ) + { + rawcrcs[numcrcs] = calc_crc32(0,verifybuf,datalen); + datalens[numcrcs] = datalen; + numcrcs++; + } + free(retstr); + } + } else printf("datalen.%d >= maxlen.%d\n",datalen,maxlen); + } else printf("not keystr.%p or no data.%p or bad datalen.%d\n",keystr,hexstr,datalen); + } + } + } + //printf("n.%d maxlen.%d\n",n,maxlen); + } + free_json(retarray); + if ( (crc= basilisk_majority32(datalenp,rawcrcs,datalens,numcrcs)) != 0 ) + { + //printf("have majority crc.%08x\n",crc); + } + //else printf("no majority from rawcrcs.%d\n",numcrcs); + } + return(crc); +} + +uint32_t basilisk_crcsend(struct supernet_info *myinfo,int32_t width,uint8_t *verifybuf,int32_t maxlen,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t crcs[2]) +{ + uint32_t crc; int32_t recvlen=0; + if ( crcs != 0 ) + { + crc = calc_crc32(0,data,datalen); + if ( crcs[0] != crc ) + crcs[0] = crc, crcs[1] = 0; + else + { + if ( crcs[1] == 0 ) + crcs[1] = basilisk_crcrecv(myinfo,width,verifybuf,maxlen,&recvlen,srchash,desthash,channel,msgbits); + if ( crcs[0] == crcs[1] && datalen == recvlen ) + return(crcs[0]); + } + } + return(0); } diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index 159e972c1..942539260 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -22,36 +22,6 @@ };*/ #ifdef bitcoincancalculatebalances -int64_t bitcoin_value(struct iguana_info *coin,bits256 txid,int16_t vout,char *coinaddr) -{ - char params[512],str[65]; char *curlstr; cJSON *txobj,*vouts,*item,*sobj,*addrs; int32_t j,m,n; int64_t value = 0; - sprintf(params,"[\"%s\", 1]",bits256_str(str,txid)); - if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 ) - { - if ( (txobj= cJSON_Parse(curlstr)) != 0 ) - { - if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) - { - item = jitem(vouts,vout); - if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 ) - { - for (j=0; jsymbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 ) + { + if ( (txobj= cJSON_Parse(curlstr)) != 0 ) + { + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) + { + item = jitem(vouts,vout); + if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 ) + { + for (j=0; jVALIDATENODE != 0 || coin->FULLNODE != 0 ) + if ( coin->VALIDATENODE > 0 || coin->FULLNODE > 0 ) return(1); //else if ( coin->chain->serverport[0] != 0 ) // return(1); @@ -299,7 +299,7 @@ int32_t basilisk_bitcoinavail(struct iguana_info *coin) void *basilisk_bitcoinbalances(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals) { - int64_t balance,total = 0; int32_t i,n,hist; cJSON *spends,*unspents,*retjson,*item,*addresses,*array = cJSON_CreateArray(); + int64_t balance,total = 0; int32_t i,j,n,hist; char *str; cJSON *spends,*unspents,*retjson,*item,*addresses,*array = cJSON_CreateArray(); spends = unspents = 0; if ( (hist= juint(vals,"history")) != 0 ) { @@ -313,13 +313,20 @@ void *basilisk_bitcoinbalances(struct basilisk_item *Lptr,struct supernet_info * { for (i=0; iRTheight > 0 ) - balance = iguana_addressreceived(myinfo,coin,vals,remoteaddr,0,0,unspents,spends,jstri(addresses,i),juint(vals,"minconf"),juint(vals,"firstheight")); - //else balance = 0; - item = cJSON_CreateObject(); - jaddnum(item,jstri(addresses,i),dstr(balance)); - jaddi(array,item); - total += balance; + if ( (str= jstri(addresses,i)) != 0 ) + { + for (j=0; jipaddr); jaddnum(retjson,"total",dstr(total)); + jaddnum(retjson,"balance",dstr(total)); jadd(retjson,"addresses",array); if ( unspents != 0 ) jadd(retjson,"unspents",unspents); @@ -335,6 +343,7 @@ void *basilisk_bitcoinbalances(struct basilisk_item *Lptr,struct supernet_info * jaddnum(retjson,"RTheight",coin->RTheight); jaddnum(retjson,"longest",coin->longestchain); jaddnum(retjson,"lag",coin->longestchain- coin->RTheight); +//printf("BAL.(%s)\n",jprint(retjson,0)); Lptr->retstr = jprint(retjson,1); return(Lptr); } @@ -345,6 +354,7 @@ char *basilisk_valuestr(struct iguana_info *coin,char *coinaddr,uint64_t value,i jaddstr(retjson,"result","success"); jaddstr(retjson,"address",coinaddr); jadd64bits(retjson,"satoshis",value); + jaddnum(retjson,"amount",dstr(value)); jaddnum(retjson,"value",dstr(value)); jaddnum(retjson,"height",height); jaddnum(retjson,"numconfirms",coin->blocks.hwmchain.height - height + 1); @@ -374,16 +384,18 @@ double basilisk_bitcoin_valuemetric(struct supernet_info *myinfo,struct basilisk void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) { - int32_t i,height,vout,numsent; struct basilisk_item *ptr; char coinaddr[64],str[64]; struct basilisk_value *v; uint64_t value = 0; bits256 txid; - if ( RELAYID >= 0 ) + int32_t i,j,height,vout,numsent; cJSON *retjson; struct basilisk_item *ptr; char coinaddr[64],str[65]; struct basilisk_value *v; uint64_t value = 0; bits256 txid; struct iguana_outpoint outpt; + if ( valsobj == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); + if ( myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0 ) return(0); txid = jbits256(valsobj,"txid"); vout = jint(valsobj,"vout"); if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 ) { - if ( (coin->VALIDATENODE != 0 || coin->FULLNODE != 0) )//&& coinaddr != 0 && coinaddr[0] != 0 ) + if ( (coin->VALIDATENODE > 0 || coin->FULLNODE > 0) )//&& coinaddr != 0 && coinaddr[0] != 0 ) { - if ( iguana_RTunspentindfind(myinfo,coin,coinaddr,0,0,&value,&height,txid,vout,coin->bundlescount,0) > 0 ) + if ( iguana_RTunspentindfind(myinfo,coin,&outpt,coinaddr,0,0,&value,&height,txid,vout,coin->bundlescount,0) == 0 ) { //printf("bitcoinvalue found iguana\n"); Lptr->retstr = basilisk_valuestr(coin,coinaddr,value,height,txid,vout); @@ -401,18 +413,83 @@ void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myi if ( v->vout == vout && bits256_cmp(txid,v->txid) == 0 && strcmp(v->coinaddr,coinaddr) == 0 ) { printf("bitcoinvalue local ht.%d %s %.8f\n",v->height,v->coinaddr,dstr(v->value)); - ptr = basilisk_issueremote(myinfo,0,&numsent,"VAL",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,0,basilisk_valuestr(coin,v->coinaddr,v->value,v->height,txid,vout),0,0,BASILISK_DEFAULTDIFF); // this completes immediate + ptr = basilisk_issueremote(myinfo,0,&numsent,"VAL",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"numrequired"),basilisktag,timeoutmillis,0,basilisk_valuestr(coin,v->coinaddr,v->value,v->height,txid,vout),0,0,BASILISK_DEFAULTDIFF); // this completes immediate //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + if ( ptr->numresults > 0 ) + { + retjson = cJSON_CreateArray(); + for (j=0; jnumresults; j++) + jaddi(retjson,ptr->results[j]), ptr->results[j] = 0; + ptr->retstr = jprint(retjson,1); + //printf("numresults.%d (%p)\n",ptr->numresults,ptr); + } return(ptr); } } } printf("bitcoinvalue issue remote tag.%u\n",basilisktag); - ptr = basilisk_issueremote(myinfo,0,&numsent,"VAL",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,0,0,0,0,BASILISK_DEFAULTDIFF); + ptr = basilisk_issueremote(myinfo,0,&numsent,"VAL",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"numrequired"),basilisktag,timeoutmillis,0,0,0,0,BASILISK_DEFAULTDIFF); + if ( ptr->numresults > 0 ) + { + retjson = cJSON_CreateArray(); + for (j=0; jnumresults; j++) + jaddi(retjson,ptr->results[j]), ptr->results[j] = 0; + ptr->retstr = jprint(retjson,1); + //printf("numresults.%d (%p)\n",ptr->numresults,ptr); + } //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); return(ptr); } +void *basilisk_getinfo(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) +{ + struct basilisk_item *ptr; cJSON *infojson,*retjson; int32_t j,numsent,fanout,numrequired; + if ( valsobj == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); + if ( (myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0) && strcmp(coin->symbol,"RELAY") != 0 ) + return(0); + if ( coin->VALIDATENODE > 0 || coin->FULLNODE > 0 || coin->notarychain >= 0 ) + { + infojson = iguana_getinfo(myinfo,coin); + Lptr->retstr = jprint(infojson,1); + return(Lptr); + } + if ( (fanout= juint(valsobj,"fanout")) < 8 ) + fanout = 8; + if ( (numrequired= juint(valsobj,"numrequired")) < fanout ) + { + jaddnum(valsobj,"numrequired",fanout); + numrequired = 1; + } + ptr = basilisk_issueremote(myinfo,0,&numsent,"INF",coin->symbol,1,valsobj,fanout,numrequired,basilisktag,timeoutmillis,0,0,0,0,BASILISK_DEFAULTDIFF); + if ( ptr->numresults > 0 ) + { + retjson = cJSON_CreateArray(); + for (j=0; jnumresults; j++) + jaddi(retjson,ptr->results[j]), ptr->results[j] = 0; + ptr->retstr = jprint(retjson,1); + //printf("numresults.%d (%p)\n",ptr->numresults,ptr); + } + return(ptr); +} + +int64_t iguana_getestimatedfee(struct supernet_info *myinfo,struct iguana_info *coin) +{ + char *retstr; cJSON *retjson; double x; int64_t txfeeperbyte = 200; + if ( (retstr= _dex_getinfo(myinfo,coin->symbol)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (x= jdouble(retjson,"estimatefee")) > SMALLVAL ) + txfeeperbyte = 1 + (x * SATOSHIDEN) / 1024; + printf("SET txfeeperbyte %lld (%s)\n",(long long)txfeeperbyte,retstr); + free(retjson); + } + free(retstr); + } + return(txfeeperbyte); +} + int32_t basilisk_voutvin_validate(struct iguana_info *coin,char *rawtx,uint64_t inputsum,uint64_t amount,uint64_t txfee) { //static int counter; @@ -483,19 +560,219 @@ int32_t basilisk_vins_validate(struct supernet_info *myinfo,struct iguana_info * return(retval); } -char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) +int64_t iguana_esttxfee(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,char *signedtx,int32_t numvins) +{ + int64_t txfee = 0; + if ( coin->estimatedfee == 0 ) + coin->estimatedfee = iguana_getestimatedfee(myinfo,coin); + if ( signedtx != 0 ) + { + txfee = coin->estimatedfee * (strlen(signedtx)/2 + numvins); + free(signedtx); + } + else if ( rawtx != 0 ) + { + txfee = coin->estimatedfee * (strlen(rawtx)/2 + numvins * 110); + free(rawtx); + } + return(txfee); +} + +char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *pubkey33,uint64_t satoshis,int32_t duplicates,int32_t *completedp,bits256 *signedtxidp,int32_t sendflag,cJSON *addresses) +{ + uint8_t script[35]; int64_t txfee; int32_t i,spendlen; cJSON *txobj=0,*vins=0; char *rawtx=0,*signedtx=0,changeaddr[64]; + *completedp = 0; + if ( signedtxidp != 0 ) + memset(signedtxidp,0,sizeof(*signedtxidp)); + bitcoin_address(changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + txfee = (coin->txfee + duplicates*coin->txfee*2); + if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 ) + { + if ( duplicates <= 0 ) + duplicates = 1; + spendlen = bitcoin_pubkeyspend(script,0,pubkey33); + for (i=0; ichain->symbol,"BTC") == 0 && cJSON_GetArraySize(vins) > duplicates/2 ) + { + free(rawtx); + rawtx = 0; + fprintf(stderr,"No point to recycle utxo when trying to create utxo duplicates, numvins.%d vs duplicates.%d\n",cJSON_GetArraySize(vins),duplicates); + free_json(vins); + return(rawtx); + } + printf("%s splitfunds tx.(%s) vins.(%s)\n",coin->symbol,rawtx,jprint(vins,0)); + if ( signedtxidp != 0 ) + { + if ( (signedtx= iguana_signrawtx(myinfo,coin,0,signedtxidp,completedp,vins,rawtx,0,0)) != 0 ) + { + if ( *completedp != 0 ) + { + printf("splitfunds signedtx.(%s)\n",signedtx); + if ( sendflag != 0 ) + iguana_sendrawtransaction(myinfo,coin,signedtx); + free(rawtx); + rawtx = signedtx, signedtx = 0; + } + } else printf("error signing raw %s utxoduplicates tx\n",coin->symbol); + } + } + if ( vins != 0 ) + free_json(vins); + if ( txobj != 0 ) + free_json(txobj); + return(rawtx); +} + +int64_t iguana_verifytimelock(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t timelocked,char *destaddr,bits256 txid,int32_t vout) +{ + uint8_t script[35],script2[35],p2shscript[128],rmd160[20],addrtype; char *retstr,*spendscriptstr; int32_t p2shlen,spendlen; cJSON *sobj,*txout=0; int64_t value = 0; + bitcoin_addr2rmd160(&addrtype,rmd160,destaddr); + if ( addrtype != coin->chain->pubtype ) + return(-1); + p2shlen = bitcoin_timelockspend(p2shscript,0,rmd160,timelocked); + calc_rmd160(0,rmd160,p2shscript,p2shlen); + spendlen = bitcoin_p2shspend(script,0,rmd160); + if ( coin->FULLNODE != 0 ) + txout = dpow_gettxout(myinfo,coin,txid,vout); + else if ( (retstr= _dex_gettxout(myinfo,coin->symbol,txid,vout)) != 0 ) + { + txout = cJSON_Parse(retstr); + free(retstr); + } + if ( txout != 0 ) + { + if ( (sobj= jobj(txout,"scriptPubKey")) != 0 && (spendscriptstr= jstr(sobj,"hex")) == 0 ) + { + if ( strlen(spendscriptstr) == spendlen*2 ) + { + decode_hex(script2,spendlen,spendscriptstr); + if ( memcmp(script,script2,spendlen) != 0 ) + return(-2); + value = SATOSHIDEN * jdouble(txout,"value"); + } else return(-4); + } + free_json(txout); + return(value); + } return(-2); +} + +char *iguana_utxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t timelock,char *destaddr,char *changeaddr,int64_t *satoshis,int32_t numoutputs,uint64_t txfee,int32_t *completedp,int32_t sendflag,cJSON *utxos,cJSON *privkeys) +{ + uint8_t script[35],p2shscript[128],rmd160[20],addrtype; bits256 txid; int32_t i,p2shlen,iter,spendlen; cJSON *retjson,*txcopy,*txobj=0,*vins=0; char *rawtx=0,*signedtx=0; uint32_t timelocked = 0; + *completedp = 0; + if ( iguana_addressvalidate(coin,&addrtype,destaddr) < 0 || iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) + return(clonestr("{\"error\":\"invalid coin address\"}")); + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); + if ( addrtype != coin->chain->pubtype ) + return(clonestr("{\"error\":\"invalid changeaddr type\"}")); + bitcoin_addr2rmd160(&addrtype,rmd160,destaddr); + if ( addrtype != coin->chain->pubtype ) + return(clonestr("{\"error\":\"invalid dest address type\"}")); + if ( txfee == 0 && strcmp(coin->symbol,"BTC") != 0 && (txfee= coin->txfee) == 0 ) + txfee = coin->chain->txfee; + retjson = cJSON_CreateObject(); + if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 ) + { + if ( timelock == 0 ) + spendlen = bitcoin_standardspend(script,0,rmd160); + else + { + timelocked = (uint32_t)(time(NULL)+timelock); + if ( (timelocked % 3600) != 0 ) + timelocked += (3600 - (timelocked % 3600)); + p2shlen = bitcoin_timelockspend(p2shscript,0,rmd160,timelocked); + calc_rmd160(0,rmd160,p2shscript,p2shlen); + spendlen = bitcoin_p2shspend(script,0,rmd160); + printf("timelock.%d spend timelocked %u\n",timelock,timelocked); + } + for (i=0; i 0 ) + bitcoin_txoutput(txobj,script,spendlen,satoshis[i]); + for (iter=0; iter<2; iter++) + { + txcopy = jduplicate(txobj); + if ( (rawtx= iguana_calcutxorawtx(myinfo,coin,&vins,txobj,satoshis,numoutputs,changeaddr,txfee,utxos,"",0,0)) != 0 ) + { + if ( iter == 1 || txfee != 0 ) + jaddstr(retjson,"rawtx",rawtx); + if ( (signedtx= iguana_signrawtx(myinfo,coin,0,&txid,completedp,vins,rawtx,privkeys,0)) != 0 ) + { + if ( (iter == 1 || txfee != 0) && *completedp != 0 ) + { + jaddbits256(retjson,"txid",txid); + jaddstr(retjson,"signedtx",signedtx); + if ( sendflag != 0 ) + { + txid = iguana_sendrawtransaction(myinfo,coin,signedtx); + jaddbits256(retjson,"sent",txid); + } else printf("dont send signedtx.(%s)\n",signedtx); + } + } else printf("error signing raw utxorawtx tx\n"); + } else printf("null rawtx from calcutxorawtx\n"); + if ( txfee != 0 ) + { + free_json(txcopy); + break; + } + else // must be BTC and txfee == 0 + { + txfee = iguana_esttxfee(myinfo,coin,rawtx,signedtx,cJSON_GetArraySize(vins)); + free_json(vins); + rawtx = signedtx = 0; + vins = 0; + *completedp = 0; + txobj = txcopy; + } + } + } + if ( timelock != 0 ) + { + jaddnum(retjson,"timelock",timelock); + jaddnum(retjson,"timelocked",timelocked); + } + jaddstr(retjson,"result","success"); + if ( *completedp != 0 ) + jadd(retjson,"completed",jtrue()); + else jadd(retjson,"completed",jfalse()); + if ( vins != 0 ) + free_json(vins); + if ( txobj != 0 ) + free_json(txobj); + if ( rawtx != 0 ) + { + jaddstr(retjson,"rawtx",rawtx); + free(rawtx); + } + if ( signedtx != 0 ) + { + jaddstr(retjson,"signedtx",signedtx); + free(signedtx); + } + return(jprint(retjson,1)); +} + +char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj,struct vin_info *V) { uint8_t buf[4096]; int32_t oplen,offset,minconf,spendlen; cJSON *vins,*addresses,*txobj = 0; uint32_t locktime; char *opreturn,*spendscriptstr,*changeaddr,*rawtx = 0; int64_t amount,txfee,burnamount; - if ( RELAYID >= 0 ) - return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); + if ( valsobj == 0 ) + return(clonestr("{\"error\":\"null valsobj\"}")); + //if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) + // return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); vins = 0; changeaddr = jstr(valsobj,"changeaddr"); if ( (amount= j64bits(valsobj,"satoshis")) == 0 ) amount = jdouble(valsobj,"value") * SATOSHIDEN; if ( (txfee= j64bits(valsobj,"txfee")) == 0 ) - txfee = coin->chain->txfee; - if ( txfee == 0 ) - txfee = 10000; + { + //if ( strcmp(coin->symbol,"BTC") != 0 ) + { + txfee = coin->chain->txfee; + if ( txfee < 50000 ) + txfee = 50000; + } + } spendscriptstr = jstr(valsobj,"spendscript"); minconf = juint(valsobj,"minconf"); locktime = jint(valsobj,"locktime"); @@ -504,13 +781,13 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi addresses = iguana_getaddressesbyaccount(myinfo,coin,"*"); jadd(valsobj,"addresses",addresses); } - //printf("use addresses.(%s)\n",jprint(addresses,0)); + printf("use addresses.(%s) (%s)\n",jprint(addresses,0),spendscriptstr!=0?spendscriptstr:"no script"); //printf("(%s) vals.(%s) change.(%s) spend.%s\n",coin->symbol,jprint(valsobj,0),changeaddr,spendscriptstr); if ( changeaddr == 0 || changeaddr[0] == 0 || spendscriptstr == 0 || spendscriptstr[0] == 0 ) return(clonestr("{\"error\":\"invalid changeaddr or spendscript or addresses\"}")); - if ( coin != 0 )//&& basilisk_bitcoinavail(coin) != 0 ) + if ( coin != 0 ) { - if ( (txobj= bitcoin_txcreate(coin->chain->isPoS,locktime,locktime==0?coin->chain->normal_txversion:coin->chain->locktime_txversion)) != 0 ) + if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,locktime,locktime==0?coin->chain->normal_txversion:coin->chain->locktime_txversion,juint(valsobj,"timestamp"))) != 0 ) { spendlen = (int32_t)strlen(spendscriptstr) >> 1; decode_hex(buf,spendlen,spendscriptstr); @@ -519,17 +796,28 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi if ( (opreturn= jstr(valsobj,"opreturn")) != 0 && (oplen= is_hexstr(opreturn,0)) > 0 ) { oplen >>= 1; - if ( (strcmp("BTC",coin->symbol) == 0 && oplen < 77) || coin->chain->do_opreturn == 0 ) + if ( (strcmp("BTC",coin->symbol) == 0 && oplen < 76) || coin->chain->do_opreturn == 0 ) { decode_hex(&buf[sizeof(buf) - oplen],oplen,opreturn); spendlen = datachain_datascript(coin,buf,&buf[sizeof(buf) - oplen],oplen); if ( (burnamount= SATOSHIDEN * jdouble(valsobj,"burn")) < 10000 ) - burnamount = 10000; + { + //burnamount = 10000; + printf("low burnamount %.8f\n",dstr(burnamount)); + } bitcoin_txoutput(txobj,buf,spendlen,burnamount); oplen = 0; } else oplen = datachain_opreturnscript(coin,buf,opreturn,oplen); } - rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,amount,changeaddr,txfee,addresses,minconf,oplen!=0?buf:0,oplen+offset,burnamount,remoteaddr); + rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,amount,changeaddr,txfee,addresses,minconf,oplen!=0?buf:0,oplen+offset,burnamount,remoteaddr,V,1); + if ( txfee == 0 ) + { + txfee = iguana_esttxfee(myinfo,coin,rawtx,0,vins != 0 ? cJSON_GetArraySize(vins): 0); + if ( vins != 0 ) + free_json(vins), vins = 0; + rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,amount,changeaddr,txfee,addresses,minconf,oplen!=0?buf:0,oplen+offset,burnamount,remoteaddr,V,1); + printf("new txfee %.8f (%s)\n",dstr(txfee),rawtx); + } //printf("generated.(%s) vins.(%s)\n",rawtx!=0?rawtx:"",vins!=0?jprint(vins,0):""); } if ( rawtx != 0 ) @@ -552,7 +840,6 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi return(clonestr("{\"error\":\"couldnt create rawtx\"}")); } return(clonestr("{\"error\":\"dont have coin to create rawtx\"}")); - //return(basilisk_issueremote(myinfo,0,&numsent,"RAW",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,0,0,0,0,BASILISK_DEFAULTDIFF)); } /* @@ -585,7 +872,7 @@ char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coi */ -#ifdef later +#ifdef oldway int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_swap *swap,cJSON *argjson) { @@ -776,131 +1063,9 @@ cJSON *BTC_makeclaimfunc(struct supernet_info *myinfo,struct exchange_info *exch } #endif - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) -{ - char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; - if ( RELAYID >= 0 ) - return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); - //if ( coin == 0 ) - { - if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) - coin = iguana_coinfind(symbol); - } - if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",(int32_t)sqrt(NUMRELAYS)+1); - if ( coin != 0 ) - { - if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) - basilisktag = rand(); - if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( coin->FULLNODE != 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) - { - retstr = ptr->retstr, ptr->retstr = 0; - ptr->finished = (uint32_t)time(NULL); - return(retstr); - } - } - return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1)); -} - -/*HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) -{ - char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis,i,retval = -1; uint64_t amount,txfee; cJSON *retarray; - //if ( coin == 0 ) - { - if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) - coin = iguana_coinfind(symbol); - } - if ( jobj(vals,"numrequired") == 0 ) - jaddnum(vals,"numrequired",myinfo->numrelays); - if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",(int32_t)sqrt(myinfo->numrelays)); - if ( coin != 0 ) - { - if ( juint(vals,"burn") == 0 ) - jaddnum(vals,"burn",0.0001); - if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) - basilisktag = rand(); - if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( (ptr= basilisk_bitcoinrawtx(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) - { - if ( (retstr= ptr->retstr) != 0 ) - { - if ( (amount= j64bits(vals,"satoshis")) == 0 ) - amount = jdouble(vals,"value") * SATOSHIDEN; - if ( (txfee= j64bits(vals,"txfee")) == 0 ) - txfee = coin->chain->txfee; - if ( txfee == 0 ) - txfee = 10000; - retval = -1; - if ( (retarray= cJSON_Parse(retstr)) != 0 ) - { - if ( is_cJSON_Array(retarray) != 0 ) - { - for (i=0; iretstr = 0; - ptr->finished = (uint32_t)time(NULL); - } - } - } - return(retstr); -}*/ - -cJSON *basilisk_history_item(struct iguana_info *coin,int64_t *totalp,char *coinaddr,int64_t value,uint32_t timestamp,bits256 txid,char *vinvoutstr,int32_t vinvout,int32_t height,char *otherheightstr,int32_t otherheight,uint64_t relaymask,int32_t ismine) -{ - cJSON *item,*details; - item = cJSON_CreateObject(); - jaddstr(item,"address",coinaddr); - jaddnum(item,"amount",dstr(value)); - jaddnum(item,"numseconds",time(NULL) - timestamp); - details = cJSON_CreateObject(); - if ( ismine > 0 ) - { - jaddnum(details,"ismine",ismine); - if ( strcmp(vinvoutstr,"spentheight") == 0 ) - jaddstr(details,"category","sent"); - else jaddstr(details,"category","received"); - } - jaddbits256(details,"txid",txid); - jaddnum(details,vinvoutstr,vinvout); - jaddnum(details,"height",height); - if ( coin->blocks.hwmchain.height > 0 ) - jaddnum(details,"confirms",coin->blocks.hwmchain.height - height); - jaddnum(details,"height",height); - if ( otherheight != 0 ) - jaddnum(details,otherheightstr,otherheight); - else *totalp += value; - jaddnum(details,"relays",bitweight(relaymask)); - jadd(item,"details",details); - return(item); -} - -#include "../includes/iguana_apiundefs.h" - int32_t basilisk_unspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,struct iguana_outpoint outpt,int64_t value) { - struct basilisk_unspent *bu; int32_t i,spendlen; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; char str[65]; + struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; memset(txidp,0,sizeof(*txidp)); *voutp = -1; portable_mutex_lock(&myinfo->bu_mutex); @@ -908,223 +1073,115 @@ int32_t basilisk_unspentfind(struct supernet_info *myinfo,struct iguana_info *co { HASH_ITER(hh,wacct->waddr,waddr,tmp2) { - for (i=0; inumunspents; i++) - { - bu = &waddr->unspents[i]; - if ( bu->hdrsi == outpt.hdrsi && bu->unspentind == outpt.unspentind && bu->value == value ) - { - if ( bu->status == 0 ) - { - *txidp = bu->txid; - *voutp = bu->vout; - memcpy(spendscript,bu->script,bu->spendlen); - spendlen = bu->spendlen; - portable_mutex_unlock(&myinfo->bu_mutex); - return(spendlen); - } else printf("unspentfind skip %s/v%d\n",bits256_str(str,bu->txid),bu->vout); - } - } + printf("need to port basilisk_unspentfind\n"); } } portable_mutex_unlock(&myinfo->bu_mutex); return(-1); } -struct basilisk_spend *basilisk_addspend(struct supernet_info *myinfo,char *symbol,bits256 txid,uint16_t vout,int32_t addflag) +cJSON *basilisk_jsonmerge(char *symbol,cJSON *array) { - int32_t i; struct basilisk_spend *s; - // mutex - if ( myinfo->numspends > 0 ) + int32_t i,j,n,m; cJSON *jobj,*iobj,*dest = cJSON_CreateArray(); + if ( dest != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { - for (i=0; inumspends; i++) + for (i=0; ispends[i].vout == vout && bits256_cmp(txid,myinfo->spends[i].txid) == 0 ) + m = cJSON_GetArraySize(dest); + iobj = jitem(array,i); + for (j=0; jspends[i]); + jobj = jitem(dest,j); + if ( bits256_cmp(jbits256(jobj,"txid"),jbits256(iobj,"txid")) == 0 && jint(jobj,"vout") == jint(iobj,"vout") ) + { + //printf("(%s) == (%s)\n",jprint(iobj,0),jprint(jobj,0)); + break; + } } + if ( j == m ) + { + jaddi(dest,jduplicate(iobj)); + //printf("add.(%s) ",jprint(iobj,0)); + } //else printf("j.%d != m.%d\n",j,m); } } - if ( addflag != 0 && i == myinfo->numspends ) - { - printf("realloc spends.[%d] %p\n",myinfo->numspends,myinfo->spends); - myinfo->spends = realloc(myinfo->spends,sizeof(*myinfo->spends) * (myinfo->numspends+1)); - printf("allocated spends.[%d] %p\n",myinfo->numspends+1,myinfo->spends); - s = &myinfo->spends[myinfo->numspends++]; - memset(s,0,sizeof(*s)); - s->txid = txid; - s->vout = vout; - strcpy(s->symbol,symbol); - //char str[65]; printf("ADDSPEND.%s %s/v%d\n",symbol,bits256_str(str,txid),vout); - // mutex - return(s); - } - // mutex - return(0); + return(dest); } -void basilisk_unspent_update(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *item,int32_t spentheight,int32_t relayid,int32_t RTheight) +void basilisk_unspent_update(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json) { - //{"txid":"4814dc8a357f93f16271eb43806a69416ec41ab1956b128d170402b0a1b37c7f","vout":2,"address":"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm","scriptPubKey":"76a914c210f6711e98fe9971757ede2b2dcb0507f3f25e88ac","amount":9.99920000,"timestamp":1466684518,"height":1160306,"confirmations":22528,"checkind":1157,"spent":{"hdrsi":2320,"pkind":168,"unspentind":1157,"prevunspentind":0,"satoshis":"999920000","txidind":619,"vout":2,"type":2,"fileid":0,"scriptpos":0,"scriptlen":25},"spentheight":1161800,"dest":{"error":"couldnt find spent info"}} - int32_t i,n,j,m,already_spent=0; struct basilisk_unspent bu,bu2; char *address,*script=0,*destaddr; struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; cJSON *dest,*vouts,*vitem; double ratio; - if ( (address= jstr(item,"address")) != 0 && (script= jstr(item,"scriptPubKey")) != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,address)) != 0 ) + cJSON *unspents,*spends,*item; int32_t n; char *address; //struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; + if ( (spends= jarray(&n,json,"spends")) != 0 && n > 0 ) { - if ( relayid >= 64 ) - relayid = 0; - memset(&bu,0,sizeof(bu)); - bu.spendlen = (int32_t)strlen(script) >> 1; - if ( bu.spendlen > sizeof(bu.script) ) + item = jitem(spends,0); + if ( (address= jstr(item,"address")) != 0 )//&& (waddr= iguana_waddresssearch(myinfo,&wacct,address)) != 0 ) { - printf("spendscript too big.%d\n",bu.spendlen); - return; - } - strcpy(bu.symbol,coin->symbol); - bu.txid = jbits256(item,"txid"); - bu.vout = jint(item,"vout"); - bu.value = jdouble(item,"amount") * SATOSHIDEN; - bu.height = jint(item,"height"); - bu.hdrsi = (bu.height / coin->chain->bundlesize); - bu.unspentind = juint(item,"checkind"); - bu.timestamp = juint(item,"timestamp"); - decode_hex(bu.script,bu.spendlen,script); - //printf("unspentupdate.(%s)\n",jprint(item,0)); - n = waddr->numunspents; - for (i=0; iunspents[i]; - bu2.status = 0; - bu2.RTheight = bu2.spentheight = 0; - bu2.relaymask = 0; - if ( memcmp(&bu,&bu2,sizeof(bu)) == 0 ) - { - if ( waddr->unspents[i].RTheight > RTheight ) - RTheight = waddr->unspents[i].RTheight; - already_spent = waddr->unspents[i].spentheight; - bu.relaymask = waddr->unspents[i].relaymask; - if ( (bu.status= waddr->unspents[i].status) != 0 ) - { - //printf("mempool spend for %s/%d\n",bits256_str(str,bu.txid),bu.vout); - } - break; - } - } - bu.RTheight = RTheight; - bu.relaymask |= ((uint64_t)1 << relayid); - //printf("relayid.%d -> %llx wt.%d\n",relayid,(long long)bu.relaymask,bitweight(bu.relaymask)); - if ( spentheight != 0 ) - already_spent = spentheight; - if ( (bu.spentheight= already_spent) != 0 ) - bu.status = 1; - //printf("i.%d n.%d\n",i,n); - if ( i == n ) - { - if ( i >= waddr->maxunspents ) - { - waddr->maxunspents += 16; - waddr->unspents = realloc(waddr->unspents,sizeof(*waddr->unspents) * waddr->maxunspents); - //printf("allocate max.%d for %s\n",waddr->maxunspents,waddr->coinaddr); - } - waddr->numunspents++; - //printf("new unspent.%s %d script.%p [%d]\n",waddr->coinaddr,waddr->numunspents,bu.script,bu.spendlen); + if ( myinfo->Cspends == 0 ) + myinfo->Cspends = cJSON_CreateObject(); + if ( jobj(myinfo->Cspends,coin->symbol) != 0 ) + jdelete(myinfo->Cspends,coin->symbol); + jadd(myinfo->Cspends,coin->symbol,basilisk_jsonmerge(coin->symbol,spends)); + //printf("S.(%s)\n",jprint(waddr->Cspends,0)); } - waddr->unspents[i] = bu; - //PREVENT DOUBLE SPENDS!!! and use p2sh - if ( i == n && bu.spentheight != 0 && (dest= jobj(item,"dest")) != 0 ) + //printf("merge spends.(%s)\n",jprint(spends,0)); + } + if ( (unspents= jarray(&n,json,"unspents")) != 0 && n > 0 ) + { + item = jitem(unspents,0); + if ( (address= jstr(item,"address")) != 0 )//&& (waddr= iguana_waddresssearch(myinfo,&wacct,address)) != 0 ) { - struct basilisk_spend *s; - //{"txid":"cd4fb72f871d481c534f15d7f639883958936d49e965f58276f0925798e762df","vin":1,"height":,"unspentheight":,"relays":2}}, - if ( (s= basilisk_addspend(myinfo,coin->symbol,bu.txid,bu.vout,1)) != 0 ) - { - s->spentfrom = jbits256(dest,"spentfrom"); - s->vini = jint(dest,"vin"); - s->height = bu.spentheight; - s->timestamp = juint(dest,"timestamp"); - s->unspentheight = bu.height; - s->relaymask = bu.relaymask; - ratio = jdouble(dest,"ratio"); - if ( (vouts= jobj(dest,"vouts")) != 0 && (m= cJSON_GetArraySize(vouts)) > 0 ) - { - for (j=0; jdestaddr,destaddr,sizeof(s->destaddr)); - s->ismine = (iguana_waddresssearch(myinfo,&wacct,destaddr) != 0); - s->value = jdouble(vitem,jfieldname(vitem)) * SATOSHIDEN; - //printf("(%s %.8f) ",s->destaddr,dstr(s->value)); - } - } - //char str[65]; printf("SPEND dest.(%s) ratio %.8f (%s/v%d)\n",jprint(dest,0),ratio,bits256_str(str,s->txid),s->vini); - } - } + if ( myinfo->Cunspents == 0 ) + myinfo->Cunspents = cJSON_CreateObject(); + if ( jobj(myinfo->Cunspents,coin->symbol) != 0 ) + jdelete(myinfo->Cunspents,coin->symbol); + jadd(myinfo->Cunspents,coin->symbol,basilisk_jsonmerge(coin->symbol,unspents)); + //printf("U.(%s)\n",jprint(myinfo->Cunspents,0)); } - } else printf("waddr.%p script.%p address.%p %s\n",waddr,script,address,address!=0?address:""); + //printf("merge unspents.(%s)\n",jprint(unspents,0)); + } } -void basilisk_relay_unspentsprocess(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *relayjson) +void basilisk_unspents_process(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr) { - int32_t RTheight,relayid,num,j; cJSON *unspents,*spends; - RTheight = jint(relayjson,"RTheight"); - if ( (relayid= basilisk_relayid(myinfo,(uint32_t)calc_ipbits(jstr(relayjson,"relay")))) < BASILISK_MAXRELAYS ) - { - coin->relay_RTheights[relayid] = RTheight; - } - //printf("basilisk_relay_unspentsprocess relayid.%d RT.%d (%s)\n",relayid,RTheight,jprint(relayjson,0)); - if ( (unspents= jarray(&num,relayjson,"unspents")) != 0 ) - { - for (j=0; jbu_mutex); + if ( myinfo->Cspends != 0 ) + free_json(myinfo->Cspends), myinfo->Cspends = 0; + if ( myinfo->Cunspents != 0 ) + free_json(myinfo->Cunspents), myinfo->Cunspents = 0; + if ( (retarray= cJSON_Parse(retstr)) != 0 ) { - for (j=0; jbu_mutex); +} + +cJSON *basilisk_balance_valsobj(struct supernet_info *myinfo,struct iguana_info *coin) +{ + int32_t oldest,i,RTheight; cJSON *vals; + for (i=oldest=0; irelay_RTheights[i]) != 0 && (oldest == 0 || RTheight < oldest) ) + oldest = RTheight; + vals = cJSON_CreateObject(); + jaddnum(vals,"firstheight",oldest); + jaddnum(vals,"history",3); + jaddstr(vals,"coin",coin->symbol); + return(vals); } void basilisk_unspents_update(struct supernet_info *myinfo,struct iguana_info *coin) { - char *retstr; cJSON *retarray,*vals; int32_t oldest,i,n,RTheight; - //if ( coin->FULLNODE == 0 && coin->VALIDATENODE == 0 ) + char *retstr; cJSON *vals; + if ( (vals= basilisk_balance_valsobj(myinfo,coin)) != 0 && (retstr= basilisk_balances(myinfo,coin,0,0,GENESIS_PUBKEY,vals,"")) != 0 ) { - vals = cJSON_CreateObject(); - for (i=oldest=0; irelay_RTheights[i]) != 0 && (oldest == 0 || RTheight < oldest) ) - oldest = RTheight; - jaddnum(vals,"firstheight",oldest); - jaddnum(vals,"history",3); - jaddstr(vals,"coin",coin->symbol); - if ( (retstr= basilisk_balances(myinfo,coin,0,0,GENESIS_PUBKEY,vals,"")) != 0 ) - { - portable_mutex_lock(&myinfo->bu_mutex); - if ( (retarray= cJSON_Parse(retstr)) != 0 ) - { - //printf("%s UNSPENTS_UPDATE.(%s)\n",coin->symbol,retstr); - if ( jobj(retarray,"error") == 0 ) - { - if ( (jstr(retarray,"ipaddr") == 0 || strcmp(jstr(retarray,"ipaddr"),myinfo->ipaddr) != 0) && (n= cJSON_GetArraySize(retarray)) > 0 ) - { - for (i=0; ibu_mutex); - } - free_json(vals); + basilisk_unspents_process(myinfo,coin,retstr); + free(retstr); } + free_json(vals); } diff --git a/basilisk/basilisk_ping.c b/basilisk/basilisk_ping.c index 404bb7095..7533cd2cd 100755 --- a/basilisk/basilisk_ping.c +++ b/basilisk/basilisk_ping.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,7 +16,7 @@ // included from basilisk.c #ifdef ENABLE_VIRTPING -int32_t basilisk_blocksend(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,struct iguana_peer *addr,int32_t height) +int32_t basilisk_blocksend(struct supernet_info *myinfo,struct iguana_info *notary,struct iguana_info *virt,struct iguana_peer *addr,int32_t height) { int32_t blocklen; bits256 hash2; uint8_t *data = 0; char str[65],strbuf[4096],*blockstr,*allocptr = 0; struct iguana_block *block; hash2 = iguana_blockhash(virt,height); @@ -42,7 +42,7 @@ int32_t basilisk_blocksend(struct supernet_info *myinfo,struct iguana_info *btcd { blockstr = basilisk_addhexstr(&allocptr,0,strbuf,sizeof(strbuf),data,blocklen); printf("RELAYID.%d send block.%d %s -> (%s) %s\n",myinfo->RELAYID,height,blockstr,addr->ipaddr,bits256_str(str,hash2)); - basilisk_blocksubmit(myinfo,btcd,virt,addr,blockstr,hash2,height); + basilisk_blocksubmit(myinfo,notary,virt,addr,blockstr,hash2,height); if ( allocptr != 0 ) free(allocptr); return(0); @@ -50,7 +50,7 @@ int32_t basilisk_blocksend(struct supernet_info *myinfo,struct iguana_info *btcd return(-1); } -int32_t basilisk_ping_processvirts(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_peer *addr,uint8_t *data,int32_t datalen) +int32_t basilisk_ping_processvirts(struct supernet_info *myinfo,struct iguana_info *notary,struct iguana_peer *addr,uint8_t *data,int32_t datalen) { int32_t diff,i,j,len = 0; struct iguana_info *virt; char symbol[7]; uint32_t numvirts,height; len += iguana_rwvarint32(0,&data[len],&numvirts); @@ -72,7 +72,7 @@ int32_t basilisk_ping_processvirts(struct supernet_info *myinfo,struct iguana_in if ( (rand() % diff) == 0 ) { for (j=1; height+jblocks.hwmchain.height && j<3; j++) - basilisk_blocksend(myinfo,btcd,virt,addr,height+j); + basilisk_blocksend(myinfo,notary,virt,addr,height+j); } } } @@ -107,7 +107,7 @@ int32_t basilisk_ping_genvirts(struct supernet_info *myinfo,uint8_t *data,int32_ int32_t basilisk_ping_processMSG(struct supernet_info *myinfo,uint32_t senderipbits,uint8_t *data,int32_t datalen) { - int32_t i,msglen,len=0; uint8_t num,keylen,*msg,*key; uint32_t duration; + int32_t i,msglen=0,len=0; uint8_t num,keylen,*message,*key; uint32_t duration; if ( (num= data[len++]) > 0 ) { //printf("processMSG num.%d datalen.%d\n",num,datalen); @@ -127,14 +127,14 @@ int32_t basilisk_ping_processMSG(struct supernet_info *myinfo,uint32_t senderipb } len += iguana_rwnum(0,&data[len],sizeof(msglen),&msglen); len += iguana_rwnum(0,&data[len],sizeof(duration),&duration); - msg = &data[len], len += msglen; + message = &data[len], len += msglen; if ( msglen <= 0 || len > datalen ) { printf("illegal msglen.%d or len.%d > %d\n",msglen,len,datalen); return(0); } //printf("i.%d: keylen.%d msglen.%d\n",i,keylen,msglen); - basilisk_respond_addmessage(myinfo,key,keylen,msg,msglen,0,duration); + basilisk_respond_addmessage(myinfo,key,keylen,message,msglen,0,duration); } } return(len); @@ -143,7 +143,7 @@ int32_t basilisk_ping_processMSG(struct supernet_info *myinfo,uint32_t senderipb int32_t basilisk_ping_genMSG(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) { struct basilisk_message *msg; int32_t datalen = 0; - if ( maxlen > sizeof(msg->key) && (msg= queue_dequeue(&myinfo->msgQ,0)) != 0 ) // oneshot ping + if ( maxlen > sizeof(msg->key) && (msg= queue_dequeue(&myinfo->msgQ)) != 0 ) // oneshot ping { data[datalen++] = 1; data[datalen++] = msg->keylen; @@ -188,7 +188,7 @@ int32_t baslisk_relay_report(struct supernet_info *myinfo,uint8_t *data,int32_t int32_t basilisk_ping_processrelay(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relay *rp,int32_t i) { - uint8_t pingdelay; int32_t j,datalen = 0; uint32_t ipbits; + uint8_t pingdelay; int32_t j,datalen = 0; uint32_t ipbits; char ipaddr[64]; ipbits = rp->ipbits; if ( maxlen < sizeof(ipbits)+1 ) { @@ -202,19 +202,21 @@ int32_t basilisk_ping_processrelay(struct supernet_info *myinfo,uint8_t *data,in datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,&rp->reported[j],pingdelay); return(datalen); } - printf("notified about unknown relay\n"); // parse it to match bytes sent datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,0,pingdelay); + expand_ipbits(ipaddr,ipbits); + printf("notified about unknown relay (%s)\n",ipaddr); // parse it to match bytes sent + basilisk_addrelay_info(myinfo,0,ipbits,GENESIS_PUBKEY); return(datalen); } void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr,uint32_t senderipbits,uint8_t *data,int32_t datalen) { - int32_t diff,i,n,len = 0; struct iguana_info *btcd; char ipbuf[64]; struct basilisk_relay *rp; uint8_t numrelays; uint16_t sn; uint32_t now = (uint32_t)time(NULL); + int32_t diff,i,n,len = 0; struct iguana_info *notary; char ipbuf[64]; struct basilisk_relay *rp; uint8_t numrelays; uint16_t sn; uint32_t now = (uint32_t)time(NULL); expand_ipbits(ipbuf,senderipbits); - btcd = iguana_coinfind("BTCD"); - for (i=0; iNOTARY.NUMRELAYS; i++) { - rp = &RELAYS[i]; + rp = &myinfo->NOTARY.RELAYS[i]; rp->direct.pingdelay = 0; if ( rp->ipbits == senderipbits ) rp->lastping = now; @@ -228,9 +230,10 @@ void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr } } numrelays = data[len++]; - //len += basilisk_ping_processvirts(myinfo,btcd,addr,&data[len],datalen - len); + //len += basilisk_ping_processvirts(myinfo,notary,addr,&data[len],datalen - len); for (i=0; iNOTARY.RELAYS[i]; if ( len > datalen ) break; if ( (n= basilisk_ping_processrelay(myinfo,&data[len],datalen-len,rp,i)) < 0 ) @@ -246,54 +249,58 @@ void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr //else printf("\n"); //for (i=0; iRELAYID,QUEUEITEMS); + //printf("<<<<<<<<<<< input ping from.(%s) rel.%d numrelays.%d datalen.%d relay.%d Q.%d\n",ipbuf,basilisk_relayid(myinfo,(uint32_t)calc_ipbits(ipbuf)),numrelays,datalen,myinfo->NOTARY.RELAYID,QUEUEITEMS); + //basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(ipbuf),GENESIS_PUBKEY); } int32_t basilisk_ping_gen(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) { int32_t i,datalen = 0; - data[datalen++] = NUMRELAYS; + data[datalen++] = myinfo->NOTARY.NUMRELAYS; //datalen += basilisk_ping_genvirts(myinfo,&data[datalen],maxlen - datalen); - for (i=0; iNOTARY.NUMRELAYS; i++) + datalen += basilisk_ping_genrelay(myinfo,&data[datalen],maxlen - datalen,&myinfo->NOTARY.RELAYS[i]); //datalen += basilisk_ping_genDEX(myinfo,&data[datalen],maxlen - datalen); datalen += basilisk_ping_genMSG(myinfo,&data[datalen],maxlen - datalen); //for (i=0; i>>>>>>>>> Q.%d\n",datalen,myinfo->RELAYID,QUEUEITEMS); + //printf(" output ping datalen.%d relay.%d >>>>>>>>>> Q.%d\n",datalen,myinfo->NOTARY.RELAYID,QUEUEITEMS); return(datalen); } // encapsulate other messages inside msgQ for onetime ping // filter out duplicates -void basilisk_ping_send(struct supernet_info *myinfo,struct iguana_info *btcd) +void basilisk_ping_send(struct supernet_info *myinfo,struct iguana_info *notary) { struct iguana_peer *addr; char ipaddr[64]; struct basilisk_relay *rp; uint32_t r; int32_t i,j,incr,datalen=0; uint64_t alreadysent; - if ( btcd == 0 || NUMRELAYS <= 0 ) + if ( notary == 0 || myinfo->NOTARY.NUMRELAYS <= 0 || myinfo->IAMNOTARY == 0 ) + { + printf("skip ping send %p %d %d\n",notary,myinfo->NOTARY.NUMRELAYS,myinfo->IAMNOTARY); return; + } if ( myinfo->pingbuf == 0 ) myinfo->pingbuf = malloc(IGUANA_MAXPACKETSIZE); datalen = basilisk_ping_gen(myinfo,&myinfo->pingbuf[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE-sizeof(struct iguana_msghdr)); - incr = sqrt(NUMRELAYS) + 1; + incr = sqrt(myinfo->NOTARY.NUMRELAYS) + 1; + OS_randombytes((void *)&r,sizeof(r)); for (alreadysent=j=0; j<=incr; j++) { - OS_randombytes((void *)&r,sizeof(r)); - i = (j == 0) ? RELAYID : (r % NUMRELAYS); - if ( j != 0 && i == RELAYID ) - i = (RELAYID + 1) % NUMRELAYS; + i = (j == 0) ? myinfo->NOTARY.RELAYID : ((r+j) % myinfo->NOTARY.NUMRELAYS); + if ( j != 0 && i == myinfo->NOTARY.RELAYID ) + i = (myinfo->NOTARY.RELAYID + 1) % myinfo->NOTARY.NUMRELAYS; if ( (((uint64_t)1 << i) & alreadysent) != 0 ) { j--; - continue; + break; } alreadysent |= ((uint64_t)1 << i); - rp = &RELAYS[i]; + rp = &myinfo->NOTARY.RELAYS[i]; addr = 0; expand_ipbits(ipaddr,rp->ipbits); if ( rp->ipbits == myinfo->myaddr.myipbits ) basilisk_ping_process(myinfo,0,myinfo->myaddr.myipbits,&myinfo->pingbuf[sizeof(struct iguana_msghdr)],datalen); - else if ( (addr= iguana_peerfindipbits(btcd,rp->ipbits,1)) != 0 && addr->usock >= 0 ) + else if ( (addr= iguana_peerfindipbits(notary,rp->ipbits,1)) != 0 && addr->usock >= 0 ) { if ( iguana_queue_send(addr,0,myinfo->pingbuf,"SuperNETPIN",datalen) <= 0 ) printf("error sending %d to (%s)\n",datalen,addr->ipaddr); @@ -301,6 +308,7 @@ void basilisk_ping_send(struct supernet_info *myinfo,struct iguana_info *btcd) fprintf(stderr,"+(%s).%d ",ipaddr,i); } //else fprintf(stderr,"-(%s).%d ",ipaddr,i); } - //printf("my RELAYID.%d of %d\n",myinfo->RELAYID,NUMRELAYS); + if ( 0 && datalen > 200 ) + printf("my RELAYID.%d of %d\n",myinfo->NOTARY.RELAYID,myinfo->NOTARY.NUMRELAYS); } diff --git a/basilisk/basilisk_swap.c b/basilisk/basilisk_swap.c index 625e9d4f0..a142f8a12 100755 --- a/basilisk/basilisk_swap.c +++ b/basilisk/basilisk_swap.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,35 +13,71 @@ * * ******************************************************************************/ +/* + resume handling: list of tx broadcast, tx pending + required items, reconnect state machine or have statemachine assume off by one or state/otherstate specific handling +make sure to broadcast deposit before claiming refund, or to just skip it if neither is done +*/ + +#define DEX_SLEEP 10 +#define BASILISK_DEFAULT_NUMCONFIRMS 5 + +// Todo: monitor blockchains, ie complete extracting scriptsig +// mode to autocreate required outputs +// more better LP commands + +// depends on just three external functions: +// - basilisk_sendrawtransaction(myinfo,coin,signedtx); +// - basilisk_value(myinfo,rawtx->coin,0,0,myinfo->myaddr.persistent,argjson,0) +// basilisk_bitcoinrawtx(myinfo,rawtx->coin,"",basilisktag,jint(valsobj,"timeout"),valsobj,V) + + // included from basilisk.c /* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 https://bitcointalk.org/index.php?topic=1364951 Tier Nolan's approach is followed with the following changes: a) instead of cutting 1000 keypairs, only INSTANTDEX_DECKSIZE are a b) instead of sending the entire 256 bits, it is truncated to 64 bits. With odds of collision being so low, it is dwarfed by the ~0.1% insurance factor. - c) D is set to 100x the insurance rate of 1/777 12.87% + BTC amount + c) D is set to ~100x the insurance rate of 1/777 12.87% + BTC amount d) insurance is added to Bob's payment, which is after the deposit and bailin e) BEFORE Bob broadcasts deposit, Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed */ +//#define DISABLE_CHECKSIG // unsolved MITM (evil peer) + /* both fees are standard payments: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG Alice altpayment: OP_2 OP_2 OP_CHECKMULTISIG Bob deposit: + #ifndef DISABLE_CHECKSIG OP_IF OP_CLTV OP_DROP OP_CHECKSIG OP_ELSE OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF + #else + OP_IF + OP_CLTV OP_DROP OP_SHA256 OP_EQUAL + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_SHA256 OP_EQUAL + OP_ENDIF +#endif Bob paytx: + #ifndef DISABLE_CHECKSIG OP_IF OP_CLTV OP_DROP OP_CHECKSIG OP_ELSE OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF + #else + OP_IF + OP_CLTV OP_DROP OP_SHA256 OP_EQUAL + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_SHA256 OP_EQUAL + OP_ENDIF + #endif Naming convention are pubAi are alice's pubkeys (seems only pubA0 and not pubA1) pubBi are Bob's pubkeys @@ -53,31 +89,118 @@ Alice timeout event is triggered if INSTANTDEX_LOCKTIME elapses from the start of a FSM instance. Bob timeout event is triggered after INSTANTDEX_LOCKTIME*2 */ +/* +Bob sends bobdeposit and waits for alicepayment to confirm before sending bobpayment +Alice waits for bobdeposit to confirm and sends alicepayment + +Alice spends bobpayment immediately divulging privAm +Bob spends alicepayment immediately after getting privAm and divulges privBn + +Bob will spend bobdeposit after end of trade or INSTANTDEX_LOCKTIME, divulging privBn +Alice spends alicepayment as soon as privBn is seen + +Bob will spend bobpayment after INSTANTDEX_LOCKTIME +Alice spends bobdeposit in 2*INSTANTDEX_LOCKTIME +*/ + +//Bobdeposit includes a covered put option for alicecoin, duration INSTANTDEX_LOCKTIME +//alicepayment includes a covered call option for alicecoin, duration (2*INSTANTDEX_LOCKTIME - elapsed) + + +/* in case of following states, some funds remain unclaimable, but all identified cases are due to one or both sides not spending when they were the only eligible party: + + Bob failed to claim deposit during exclusive period and since alice put in the claim, the alicepayment is unspendable. if alice is nice, she can send privAm to Bob. +Apaymentspent.(0000000000000000000000000000000000000000000000000000000000000000) alice.0 bob.0 +paymentspent.(f91da4e001360b95276448e7b01904d9ee4d15862c5af7f5c7a918df26030315) alice.0 bob.1 +depositspent.(f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add) alice.1 bob.0 + + */ + +int32_t basilisk_istrustedbob(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + // for BTC and if trusted LP + return(0); +} + +int32_t basilisk_priviextract(struct supernet_info *myinfo,struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout) +{ + bits256 txid,privkey; char str[65]; int32_t i,vini,scriptlen; uint8_t rmd160[20],scriptsig[IGUANA_MAXSCRIPTSIZE]; + memset(privkey.bytes,0,sizeof(privkey)); + // use dex_listtransactions! + if ( (vini= iguana_vinifind(myinfo,coin,&txid,srctxid,srcvout)) >= 0 ) + { + if ( (scriptlen= iguana_scriptsigextract(myinfo,coin,scriptsig,sizeof(scriptsig),txid,vini)) > 32 ) + { + for (i=0; i<32; i++) + privkey.bytes[i] = scriptsig[scriptlen - 33 + i]; + revcalc_rmd160_sha256(rmd160,privkey);//.bytes,sizeof(privkey)); + if ( memcmp(secret160,rmd160,sizeof(rmd160)) == sizeof(rmd160) ) + { + *destp = privkey; + printf("basilisk_priviextract found privi %s (%s)\n",name,bits256_str(str,privkey)); + return(0); + } + } + } + return(-1); +} + +void revcalc_rmd160_sha256(uint8_t rmd160[20],bits256 revhash) +{ + bits256 hash; int32_t i; + for (i=0; i<32; i++) + hash.bytes[i] = revhash.bytes[31-i]; + calc_rmd160_sha256(rmd160,hash.bytes,sizeof(hash)); +} + +bits256 revcalc_sha256(bits256 revhash) +{ + bits256 hash,dest; int32_t i; + for (i=0; i<32; i++) + hash.bytes[i] = revhash.bytes[31-i]; + vcalc_sha256(0,dest.bytes,hash.bytes,sizeof(hash)); + return(dest); +} + #define SCRIPT_OP_IF 0x63 #define SCRIPT_OP_ELSE 0x67 #define SCRIPT_OP_ENDIF 0x68 -int32_t basilisk_bobscript(uint8_t *rmd160,uint8_t *redeemscript,int32_t *redeemlenp,uint8_t *script,int32_t n,uint32_t *locktimep,int32_t *secretstartp,struct basilisk_swap *swap,int32_t depositflag) +bits256 basilisk_revealkey(bits256 privkey,bits256 pubkey) +{ + bits256 reveal; +#ifdef DISABLE_CHECKSIG + vcalc_sha256(0,reveal.bytes,privkey.bytes,sizeof(privkey)); + //reveal = revcalc_sha256(privkey); + char str[65],str2[65]; printf("priv.(%s) -> reveal.(%s)\n",bits256_str(str,privkey),bits256_str(str2,reveal)); +#else + reveal = pubkey; +#endif + return(reveal); +} + +int32_t basilisk_swap_bobredeemscript(int32_t depositflag,int32_t *secretstartp,uint8_t *redeemscript,uint32_t locktime,bits256 pubA0,bits256 pubB0,bits256 pubB1,bits256 privAm,bits256 privBn,uint8_t *secretAm,uint8_t *secretAm256,uint8_t *secretBn,uint8_t *secretBn256) { - uint8_t pubkeyA[33],pubkeyB[33],*secret160; bits256 cltvpub,destpub; int32_t i; - *locktimep = swap->locktime; + int32_t i,n=0; bits256 cltvpub,destpub,privkey; uint8_t pubkeyA[33],pubkeyB[33],secret160[20],secret256[32]; if ( depositflag != 0 ) { - *locktimep += INSTANTDEX_LOCKTIME; - cltvpub = swap->pubA0; - destpub = swap->pubB0; - secret160 = swap->secretBn; - pubkeyA[0] = 0x02; - pubkeyB[0] = 0x03; + pubkeyA[0] = 0x02, cltvpub = pubA0; + pubkeyB[0] = 0x03, destpub = pubB0; + privkey = privBn; + memcpy(secret160,secretBn,20); + memcpy(secret256,secretBn256,32); } else { - cltvpub = swap->pubB1; - destpub = swap->pubA0; - secret160 = swap->secretAm; - pubkeyA[0] = 0x03; - pubkeyB[0] = 0x02; + pubkeyA[0] = 0x03, cltvpub = pubB1; + pubkeyB[0] = 0x02, destpub = pubA0; + privkey = privAm; + memcpy(secret160,secretAm,20); + memcpy(secret256,secretAm256,32); } + //for (i=0; i<32; i++) + // printf("%02x",secret256[i]); + //printf(" <- secret256 depositflag.%d nonz.%d\n",depositflag,bits256_nonz(privkey)); if ( bits256_nonz(cltvpub) == 0 || bits256_nonz(destpub) == 0 ) return(-1); for (i=0; i<20; i++) @@ -88,26 +211,73 @@ int32_t basilisk_bobscript(uint8_t *rmd160,uint8_t *redeemscript,int32_t *redeem memcpy(pubkeyA+1,cltvpub.bytes,sizeof(cltvpub)); memcpy(pubkeyB+1,destpub.bytes,sizeof(destpub)); redeemscript[n++] = SCRIPT_OP_IF; - n = bitcoin_checklocktimeverify(redeemscript,n,*locktimep); + n = bitcoin_checklocktimeverify(redeemscript,n,locktime); +#ifdef DISABLE_CHECKSIG + n = bitcoin_secret256spend(redeemscript,n,cltvpub); +#else n = bitcoin_pubkeyspend(redeemscript,n,pubkeyA); +#endif redeemscript[n++] = SCRIPT_OP_ELSE; if ( secretstartp != 0 ) *secretstartp = n + 2; - n = bitcoin_revealsecret160(redeemscript,n,secret160); + if ( 1 ) + { + if ( 1 && bits256_nonz(privkey) != 0 ) + { + uint8_t bufA[20],bufB[20]; + revcalc_rmd160_sha256(bufA,privkey); + calc_rmd160_sha256(bufB,privkey.bytes,sizeof(privkey)); + /*if ( memcmp(bufA,secret160,sizeof(bufA)) == 0 ) + printf("MATCHES BUFA\n"); + else if ( memcmp(bufB,secret160,sizeof(bufB)) == 0 ) + printf("MATCHES BUFB\n"); + else printf("secret160 matches neither\n"); + for (i=0; i<20; i++) + printf("%02x",bufA[i]); + printf(" <- revcalc\n"); + for (i=0; i<20; i++) + printf("%02x",bufB[i]); + printf(" <- calc\n");*/ + memcpy(secret160,bufB,20); + } + n = bitcoin_secret160verify(redeemscript,n,secret160); + } + else + { + redeemscript[n++] = 0xa8;//IGUANA_OP_SHA256; + redeemscript[n++] = 0x20; + memcpy(&redeemscript[n],secret256,0x20), n += 0x20; + redeemscript[n++] = 0x88; //SCRIPT_OP_EQUALVERIFY; + } +#ifdef DISABLE_CHECKSIG + n = bitcoin_secret256spend(redeemscript,n,destpub); +#else n = bitcoin_pubkeyspend(redeemscript,n,pubkeyB); +#endif redeemscript[n++] = SCRIPT_OP_ENDIF; - *redeemlenp = n; - calc_rmd160_sha256(rmd160,redeemscript,n); - n = bitcoin_p2shspend(script,0,rmd160); - for (i=0; istarted + swap->putduration + swap->callduration; + else *locktimep = swap->started + swap->putduration; + *redeemlenp = n = basilisk_swap_bobredeemscript(depositflag,secretstartp,redeemscript,*locktimep,swap->pubA0,swap->pubB0,swap->pubB1,swap->privAm,swap->privBn,swap->secretAm,swap->secretAm256,swap->secretBn,swap->secretBn256); + if ( n > 0 ) + { + calc_rmd160_sha256(rmd160,redeemscript,n); + n = bitcoin_p2shspend(script,0,rmd160); + //for (i=0; i 0 && numconfirms >= 0 ) return(numconfirms); + printf("basilisk_confirmsobj height.%d numconfirms.%d (%s)\n",height,numconfirms,jprint(item,0)); return(-1); } -int32_t basilisk_numconfirms(struct supernet_info *myinfo,struct basilisk_rawtx *rawtx) +int32_t basilisk_numconfirms(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) { cJSON *argjson,*valuearray=0; char *valstr; int32_t i,n,retval = -1; -#ifdef BASILISK_DISABLETX - return(10); +#ifdef BASILISK_DISABLEWAITTX + return(100); #endif argjson = cJSON_CreateObject(); - jaddbits256(argjson,"txid",rawtx->actualtxid); + jaddbits256(argjson,"txid",rawtx->I.actualtxid); jaddnum(argjson,"vout",0); jaddstr(argjson,"coin",rawtx->coin->symbol); - if ( (valstr= basilisk_value(myinfo,rawtx->coin,0,0,myinfo->myaddr.persistent,argjson,0)) != 0 ) + if ( (valstr= basilisk_value(myinfo,rawtx->coin,0,0,swap->persistent_pubkey,argjson,0)) != 0 ) { - //char str[65]; printf("%s %s valstr.(%s)\n",rawtx->name,bits256_str(str,rawtx->actualtxid),valstr); + char str[65]; printf("basilisk_numconfirms required.%d %s %s valstr.(%s)\n",rawtx->I.numconfirms,rawtx->name,bits256_str(str,rawtx->I.actualtxid),valstr); + //basilisk_numconfirms required.0 alicespend 29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85 valstr.({"result":"success","numconfirms":0,"address":"1JGvZ67oTdM7kCya4J8kj1uErbSRAoq3wH","satoshis":"1413818","value":0.01413818,"height":462440,"txid":"29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85","vout":0,"coin":"BTC"}) + if ( (valuearray= cJSON_Parse(valstr)) != 0 ) { - if ( is_cJSON_Array(valuearray) != 0 ) + if ( valstr[0] == '[' && is_cJSON_Array(valuearray) != 0 ) { n = cJSON_GetArraySize(valuearray); for (i=0; i= 0 ) break; } @@ -160,109 +334,313 @@ int32_t basilisk_numconfirms(struct supernet_info *myinfo,struct basilisk_rawtx free(valstr); } free_json(argjson); + printf("numconfirms.%d returned\n",retval); return(retval); } bits256 basilisk_swap_broadcast(char *name,struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,uint8_t *data,int32_t datalen) { - bits256 txid; char *signedtx; + bits256 txid; char *signedtx,*retstr; int32_t i; memset(txid.bytes,0,sizeof(txid)); if ( data != 0 && datalen != 0 ) { char str[65]; -#ifdef BASILISK_DISABLETX +#ifdef BASILISK_DISABLESENDTX txid = bits256_doublesha256(0,data,datalen); printf("%s <- dont sendrawtransaction (%s)\n",name,bits256_str(str,txid)); return(txid); #endif signedtx = malloc(datalen*2 + 1); init_hexbytes_noT(signedtx,data,datalen); - txid = iguana_sendrawtransaction(myinfo,coin,signedtx); - printf("%s <- sendrawtransaction %s.(%s)\n",name,signedtx,bits256_str(str,txid)); + for (i=0; i<3; i++) + { + if ( (retstr= basilisk_sendrawtransaction(myinfo,coin,signedtx)) != 0 ) + { + if ( is_hexstr(retstr,0) == 64 ) + { + decode_hex(txid.bytes,32,retstr); + free(retstr); + printf("sendrawtransaction %s.(%s)\n",name,bits256_str(str,txid)); + break; + } + else + { + printf("sendrawtransaction %s error.(%s)\n",name,retstr); + free(retstr); + } + } else printf("sendrawtransaction %s got null return\n",name); + } free(signedtx); } return(txid); } -int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen) +int32_t _basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,uint32_t timestamp,uint32_t locktime,uint32_t sequenceid,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr) { - char *rawtxbytes,*signedtx,hexstr[999],wifstr[128]; cJSON *txobj,*vins,*item,*sobj,*privkeys; int32_t retval = -1; struct vin_info V; uint32_t locktime=0; - memset(&V,0,sizeof(V)); - if ( dest == &swap->aliceclaim ) - locktime = swap->locktime + INSTANTDEX_LOCKTIME; - V.signers[0].privkey = privkey; - bitcoin_pubkey33(myinfo->ctx,V.signers[0].pubkey,privkey); + char *rawtxbytes=0,*signedtx=0,hexstr[999],wifstr[128]; cJSON *txobj,*vins,*item,*sobj,*privkeys; int32_t needsig=1,retval = -1; struct vin_info *V; + V = calloc(256,sizeof(*V)); + V[0].signers[0].privkey = privkey; + bitcoin_pubkey33(myinfo->ctx,V[0].signers[0].pubkey,privkey); privkeys = cJSON_CreateArray(); bitcoin_priv2wif(wifstr,privkey,rawtx->coin->chain->wiftype); jaddistr(privkeys,wifstr); if ( privkey2 != 0 ) { - V.signers[1].privkey = *privkey2; - bitcoin_pubkey33(myinfo->ctx,V.signers[1].pubkey,*privkey2); + V[0].signers[1].privkey = *privkey2; + bitcoin_pubkey33(myinfo->ctx,V[0].signers[1].pubkey,*privkey2); bitcoin_priv2wif(wifstr,*privkey2,rawtx->coin->chain->wiftype); jaddistr(privkeys,wifstr); - V.N = V.M = 2; - char str[65]; printf("add second privkey.(%s) %s\n",jprint(privkeys,0),bits256_str(str,*privkey2)); - } else V.N = V.M = 1; - V.suppress_pubkeys = dest->suppress_pubkeys; - if ( dest->redeemlen != 0 ) - memcpy(V.p2shscript,dest->redeemscript,dest->redeemlen), V.p2shlen = dest->redeemlen; - txobj = bitcoin_txcreate(rawtx->coin->chain->isPoS,locktime,rawtx->coin->chain->locktime_txversion); + V[0].N = V[0].M = 2; + //char str[65]; printf("add second privkey.(%s) %s\n",jprint(privkeys,0),bits256_str(str,*privkey2)); + } else V[0].N = V[0].M = 1; + V[0].suppress_pubkeys = dest->I.suppress_pubkeys; + V[0].ignore_cltverr = ignore_cltverr; + if ( dest->I.redeemlen != 0 ) + memcpy(V[0].p2shscript,dest->redeemscript,dest->I.redeemlen), V[0].p2shlen = dest->I.redeemlen; + txobj = bitcoin_txcreate(rawtx->coin->symbol,rawtx->coin->chain->isPoS,locktime,userdata == 0 ? 1 : 1,timestamp);//rawtx->coin->chain->locktime_txversion); vins = cJSON_CreateArray(); item = cJSON_CreateObject(); if ( userdata != 0 && userdatalen > 0 ) { - memcpy(V.userdata,userdata,userdatalen); - V.userdatalen = userdatalen; + memcpy(V[0].userdata,userdata,userdatalen); + V[0].userdatalen = userdatalen; init_hexbytes_noT(hexstr,userdata,userdatalen); jaddstr(item,"userdata",hexstr); +#ifdef DISABLE_CHECKSIG + needsig = 0; +#endif } - if ( bits256_nonz(rawtx->actualtxid) != 0 ) - jaddbits256(item,"txid",rawtx->actualtxid); - else jaddbits256(item,"txid",rawtx->signedtxid); + //printf("rawtx B\n"); + if ( bits256_nonz(rawtx->I.actualtxid) != 0 ) + jaddbits256(item,"txid",rawtx->I.actualtxid); + else jaddbits256(item,"txid",rawtx->I.signedtxid); jaddnum(item,"vout",0); sobj = cJSON_CreateObject(); - init_hexbytes_noT(hexstr,rawtx->spendscript,rawtx->spendlen); + init_hexbytes_noT(hexstr,rawtx->spendscript,rawtx->I.spendlen); jaddstr(sobj,"hex",hexstr); jadd(item,"scriptPubKey",sobj); - jaddnum(item,"suppress",dest->suppress_pubkeys); - if ( locktime != 0 ) - jaddnum(item,"sequence",0); - if ( (dest->redeemlen= rawtx->redeemlen) != 0 ) + jaddnum(item,"suppress",dest->I.suppress_pubkeys); + jaddnum(item,"sequence",sequenceid); + if ( (dest->I.redeemlen= rawtx->I.redeemlen) != 0 ) { - init_hexbytes_noT(hexstr,rawtx->redeemscript,rawtx->redeemlen); - memcpy(dest->redeemscript,rawtx->redeemscript,rawtx->redeemlen); + init_hexbytes_noT(hexstr,rawtx->redeemscript,rawtx->I.redeemlen); + memcpy(dest->redeemscript,rawtx->redeemscript,rawtx->I.redeemlen); jaddstr(item,"redeemScript",hexstr); } jaddi(vins,item); jdelete(txobj,"vin"); jadd(txobj,"vin",vins); - printf("basilisk_rawtx_sign locktime.%u/%u for %s spendscript.%s -> %s, suppress.%d\n",rawtx->locktime,dest->locktime,rawtx->name,hexstr,dest->name,dest->suppress_pubkeys); - txobj = bitcoin_txoutput(txobj,dest->spendscript,dest->spendlen,dest->amount); - if ( (rawtxbytes= bitcoin_json2hex(myinfo,rawtx->coin,&dest->txid,txobj,&V)) != 0 ) + //printf("basilisk_rawtx_sign locktime.%u/%u for %s spendscript.%s -> %s, suppress.%d\n",rawtx->I.locktime,dest->I.locktime,rawtx->name,hexstr,dest->name,dest->I.suppress_pubkeys); + txobj = bitcoin_txoutput(txobj,dest->spendscript,dest->I.spendlen,dest->I.amount); + if ( (rawtxbytes= bitcoin_json2hex(myinfo,rawtx->coin,&dest->I.txid,txobj,V)) != 0 ) { - printf("(%s) spend.%s rawtx.(%s) userdatalen.%d p2shlen.%d\n",jprint(txobj,0),rawtx->name,rawtxbytes,userdatalen,dest->redeemlen); - if ( (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&dest->signedtxid,&dest->completed,vins,rawtxbytes,privkeys,&V)) != 0 ) + //printf("rawtx.(%s) vins.%p\n",rawtxbytes,vins); + if ( needsig == 0 ) + signedtx = rawtxbytes; + if ( signedtx != 0 || (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&dest->I.signedtxid,&dest->I.completed,vins,rawtxbytes,privkeys,V)) != 0 ) { - printf("rawtx spend signedtx.(%s)\n",signedtx); - dest->datalen = (int32_t)strlen(signedtx) >> 1; - dest->txbytes = calloc(1,dest->datalen); - decode_hex(dest->txbytes,dest->datalen,signedtx); - free(signedtx); - retval = 0; + dest->I.datalen = (int32_t)strlen(signedtx) >> 1; + if ( dest->I.datalen <= sizeof(dest->txbytes) ) + decode_hex(dest->txbytes,dest->I.datalen,signedtx); + else printf("DEX tx is too big %d vs %d\n",dest->I.datalen,(int32_t)sizeof(dest->txbytes)); + if ( signedtx != rawtxbytes ) + free(signedtx); + if ( dest->I.completed != 0 ) + retval = 0; + else printf("couldnt complete sign transaction %s\n",rawtx->name); } else printf("error signing\n"); free(rawtxbytes); } else printf("error making rawtx\n"); free_json(privkeys); free_json(txobj); + free(V); + return(retval); +} + +int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr) +{ + uint32_t timestamp,locktime=0,sequenceid = 0xffffffff; + timestamp = swap->I.started; + if ( dest == &swap->aliceclaim ) + locktime = swap->bobdeposit.I.locktime + 1, sequenceid = 0; + else if ( dest == &swap->bobreclaim ) + locktime = swap->bobpayment.I.locktime + 1, sequenceid = 0; + return(_basilisk_rawtx_sign(myinfo,height,timestamp,locktime,sequenceid,dest,rawtx,privkey,privkey2,userdata,userdatalen,ignore_cltverr)); +} + +cJSON *basilisk_privkeyarray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) +{ + cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],typestr[64],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid,privkey; double bidasks[2]; + privkeyarray = cJSON_CreateArray(); + //printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr); + if ( (n= cJSON_GetArraySize(vins)) > 0 ) + { + for (i=0; i= 0 ) + { + iguana_txidcategory(myinfo,coin,account,coinaddr,txid,vout); + if ( coinaddr[0] == 0 && (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 ) + { + len = (int32_t)strlen(hexstr) >> 1; + if ( len < (sizeof(script) << 1) ) + { + decode_hex(script,len,hexstr); + if ( len == 25 && script[0] == 0x76 && script[1] == 0xa9 && script[2] == 0x14 ) + bitcoin_address(coinaddr,coin->chain->pubtype,script+3,20); + } + } + if ( coinaddr[0] != 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype); + jaddistr(privkeyarray,waddr->wifstr); + } + else if ( smartaddress(myinfo,typestr,bidasks,&privkey,coin->symbol,coinaddr) >= 0 ) + { + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + jaddistr(privkeyarray,wifstr); + } + else printf("cant find (%s) in wallet\n",coinaddr); + } else printf("cant coinaddr from (%s).v%d\n",bits256_str(str,txid),vout); + } else printf("invalid txid/vout %d of %d\n",i,n); + } + } + return(privkeyarray); +} + +int32_t basilisk_rawtx_return(struct supernet_info *myinfo,int32_t height,struct basilisk_rawtx *rawtx,cJSON *item,int32_t lockinputs,struct vin_info *V) +{ + char *signedtx,*txbytes; cJSON *vins,*privkeyarray; int32_t i,n,retval = -1; + if ( (txbytes= jstr(item,"rawtx")) != 0 && (vins= jobj(item,"vins")) != 0 ) + { + privkeyarray = basilisk_privkeyarray(myinfo,rawtx->coin,vins); + if ( (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&rawtx->I.signedtxid,&rawtx->I.completed,vins,txbytes,privkeyarray,V)) != 0 ) + { + if ( lockinputs != 0 ) + { + //printf("lockinputs\n"); + iguana_RTunspentslock(myinfo,rawtx->coin,vins); + if ( (n= cJSON_GetArraySize(vins)) != 0 ) + { + bits256 txid; int32_t vout; + for (i=0; iI.datalen = (int32_t)strlen(signedtx) >> 1; + //rawtx->txbytes = calloc(1,rawtx->I.datalen); + decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); + //printf("%s SIGNEDTX.(%s)\n",rawtx->name,signedtx); + free(signedtx); + retval = 0; + } else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll + free_json(privkeyarray); + } + return(retval); +} + +int32_t _basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay) +{ + char *retstr,*jsonstr,scriptstr[1024],coinaddr[64]; uint32_t basilisktag; int32_t flag,i,n,retval = -1; cJSON *addresses,*valsobj,*retarray=0; struct vin_info *V; + //bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); + if ( rawtx->coin->changeaddr[0] == 0 ) + { + bitcoin_address(rawtx->coin->changeaddr,rawtx->coin->chain->pubtype,pubkey33,33); + printf("set change address.(%s)\n",rawtx->coin->changeaddr); + } + init_hexbytes_noT(scriptstr,script,scriptlen); + basilisktag = (uint32_t)rand(); + valsobj = cJSON_CreateObject(); + jaddstr(valsobj,"coin",rawtx->coin->symbol); + jaddstr(valsobj,"spendscript",scriptstr); + jaddstr(valsobj,"changeaddr",rawtx->coin->changeaddr); + jadd64bits(valsobj,"satoshis",rawtx->I.amount); + if ( strcmp(rawtx->coin->symbol,"BTC") == 0 && txfee > 0 && txfee < 50000 ) + txfee = 50000; + jadd64bits(valsobj,"txfee",txfee); + jaddnum(valsobj,"minconf",minconf); + if ( locktime == 0 ) + locktime = (uint32_t)time(NULL) - 777; + jaddnum(valsobj,"locktime",locktime); + jaddnum(valsobj,"timeout",30000); + jaddnum(valsobj,"timestamp",swapstarted+delay); + addresses = cJSON_CreateArray(); + bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,pubkey33,33); + jaddistr(addresses,coinaddr); + jadd(valsobj,"addresses",addresses); + rawtx->I.locktime = locktime; + printf("%s locktime.%u\n",rawtx->name,locktime); + V = calloc(256,sizeof(*V)); + if ( (retstr= basilisk_bitcoinrawtx(myinfo,rawtx->coin,"",basilisktag,jint(valsobj,"timeout"),valsobj,V)) != 0 ) + { + printf("%s %s basilisk_bitcoinrawtx.(%s) txfee %.8f\n",rawtx->name,str,retstr,dstr(txfee)); + flag = 0; + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(retarray) != 0 ) + { + n = cJSON_GetArraySize(retarray); + for (i=0; icoin->longestchain,rawtx,jitem(retarray,i),lockinputs,V)) == 0 ) + { + rawtx->vins = jduplicate(jobj(jitem(retarray,i),"vins")); + jsonstr = jprint(rawtx->vins,0); + safecopy(rawtx->vinstr,jsonstr,sizeof(rawtx->vinstr)); + free(jsonstr); + break; + } + } + } + else + { + retval = basilisk_rawtx_return(myinfo,rawtx->coin->longestchain,rawtx,retarray,lockinputs,V); + rawtx->vins = jduplicate(jobj(retarray,"vins")); + jsonstr = jprint(rawtx->vins,0); + safecopy(rawtx->vinstr,jsonstr,sizeof(rawtx->vinstr)); + free(jsonstr); + } + free(retarray); + } else printf("error parsing.(%s)\n",retstr); + free(retstr); + } else printf("error creating %s %s\n",iambob != 0 ? "BOB" : "ALICE",rawtx->name); + free_json(valsobj); + free(V); + return(retval); +} + +int32_t basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay) +{ + int32_t retval,len; uint64_t newtxfee; struct iguana_info *coin; + if ( (coin= rawtx->coin) == 0 || strcmp(coin->symbol,"BTC") != 0 ) + return(_basilisk_rawtx_gen(str,myinfo,swapstarted,pubkey33,iambob,lockinputs,rawtx,locktime,script,scriptlen,txfee,minconf,delay)); + retval = _basilisk_rawtx_gen(str,myinfo,swapstarted,pubkey33,iambob,0,rawtx,locktime,script,scriptlen,txfee,minconf,delay); + len = rawtx->I.datalen; + if ( coin->estimatedfee == 0 ) + coin->estimatedfee = iguana_getestimatedfee(myinfo,coin); + newtxfee = coin->estimatedfee * len; + if ( newtxfee > txfee ) + { + retval = _basilisk_rawtx_gen(str,myinfo,swapstarted,pubkey33,iambob,lockinputs,rawtx,locktime,script,scriptlen,newtxfee,minconf,delay); + printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee)); + } return(retval); } struct basilisk_rawtx *basilisk_swapdata_rawtx(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx) { - if ( rawtx->txbytes != 0 && rawtx->datalen <= maxlen ) + if ( rawtx->I.datalen != 0 && rawtx->I.datalen <= maxlen ) { - memcpy(data,rawtx->txbytes,rawtx->datalen); + memcpy(data,rawtx->txbytes,rawtx->I.datalen); return(rawtx); } return(0); @@ -271,41 +649,65 @@ struct basilisk_rawtx *basilisk_swapdata_rawtx(struct supernet_info *myinfo,stru int32_t basilisk_verify_otherfee(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { struct basilisk_swap *swap = ptr; - // add verification - swap->otherfee.txbytes = calloc(1,datalen); + // add verification and broadcast + //swap->otherfee.txbytes = calloc(1,datalen); memcpy(swap->otherfee.txbytes,data,datalen); - swap->otherfee.actualtxid = swap->otherfee.signedtxid = bits256_doublesha256(0,data,datalen); + swap->otherfee.I.datalen = datalen; + swap->otherfee.I.actualtxid = swap->otherfee.I.signedtxid = bits256_doublesha256(0,data,datalen); + basilisk_txlog(myinfo,swap,&swap->otherfee,-1); return(0); } -int32_t basilisk_rawtx_spendscript(struct supernet_info *myinfo,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *data,int32_t datalen,int32_t suppress_pubkeys) +int32_t basilisk_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys) { - int32_t retval=-1,hexlen,n; cJSON *txobj,*skey,*vouts,*vout; char *hexstr; - if ( rawtx->txbytes == 0 ) + int32_t datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr; bits256 txid; + datalen = recvbuf[0]; + datalen += (int32_t)recvbuf[1] << 8; + if ( datalen > 65536 ) + return(-1); + rawtx->I.redeemlen = recvbuf[2]; + data = &recvbuf[3]; + if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 ) + memcpy(rawtx->redeemscript,&data[datalen],rawtx->I.redeemlen); + //printf("recvlen.%d datalen.%d redeemlen.%d\n",recvlen,datalen,rawtx->redeemlen); + if ( rawtx->I.datalen == 0 ) { - rawtx->txbytes = calloc(1,datalen); + //rawtx->txbytes = calloc(1,datalen); memcpy(rawtx->txbytes,data,datalen); - rawtx->datalen = datalen; + rawtx->I.datalen = datalen; } - else if ( datalen != rawtx->datalen || memcmp(rawtx->txbytes,data,datalen) != 0 ) + else if ( datalen != rawtx->I.datalen || memcmp(rawtx->txbytes,data,datalen) != 0 ) { - printf("%s rawtx data compare error, len %d vs %d\n",rawtx->name,rawtx->datalen,datalen); + int32_t i; for (i=0; iI.datalen; i++) + printf("%02x",rawtx->txbytes[i]); + printf(" <- rawtx\n"); + printf("%s rawtx data compare error, len %d vs %d <<<<<<<<<< warning\n",rawtx->name,rawtx->I.datalen,datalen); return(-1); } - if ( (txobj= bitcoin_data2json(rawtx->coin,height,&rawtx->signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),rawtx->txbytes,rawtx->datalen,0,suppress_pubkeys)) != 0 ) + txid = bits256_doublesha256(0,data,datalen); + char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid)); + if ( bits256_cmp(txid,rawtx->I.actualtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) + rawtx->I.actualtxid = txid; + if ( (txobj= bitcoin_data2json(rawtx->coin,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys)) != 0 ) { - rawtx->actualtxid = rawtx->signedtxid; - char str[65]; printf("got txid.%s\n",bits256_str(str,rawtx->signedtxid)); - rawtx->locktime = rawtx->msgtx.lock_time; + rawtx->I.actualtxid = rawtx->I.signedtxid; + //char str[65]; printf("got txid.%s (%s)\n",bits256_str(str,rawtx->signedtxid),jprint(txobj,0)); + rawtx->I.locktime = rawtx->msgtx.lock_time; if ( (vouts= jarray(&n,txobj,"vout")) != 0 && v < n ) { vout = jitem(vouts,v); - if ( j64bits(vout,"satoshis") == rawtx->amount && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) + if ( j64bits(vout,"satoshis") == rawtx->I.amount && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) { if ( (hexlen= (int32_t)strlen(hexstr) >> 1) < sizeof(rawtx->spendscript) ) { decode_hex(rawtx->spendscript,hexlen,hexstr); - rawtx->spendlen = hexlen; + rawtx->I.spendlen = hexlen; + bitcoin_address(rawtx->p2shaddr,rawtx->coin->chain->p2shtype,rawtx->spendscript,hexlen); + if ( swap != 0 ) + basilisk_txlog(swap->myinfoptr,swap,rawtx,-1); // bobdeposit, bobpayment or alicepayment retval = 0; } } else printf("%s ERROR.(%s)\n",rawtx->name,jprint(txobj,0)); @@ -315,21 +717,44 @@ int32_t basilisk_rawtx_spendscript(struct supernet_info *myinfo,int32_t height,s return(retval); } -int32_t basilisk_swapuserdata(uint8_t *userdata,int32_t pushpriv,bits256 privkey,uint8_t addrtype,bits256 pubkey,int32_t ifpath) +void basilisk_swap_coinaddr(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,char *coinaddr,uint8_t *data,int32_t datalen) { - int32_t i,len = 0; - if ( 0 ) + cJSON *txobj,*vouts,*vout,*addresses,*item,*skey; uint8_t extraspace[8192]; bits256 signedtxid; struct iguana_msgtx msgtx; char *addr; int32_t n,m,suppress_pubkeys = 0; + if ( (txobj= bitcoin_data2json(coin,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys)) != 0 ) { - userdata[len++] = 33; - userdata[len++] = addrtype; - for (i=0; i 0 ) + { + vout = jitem(vouts,0); + //printf("VOUT.(%s)\n",jprint(vout,0)); + if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) + { + item = jitem(addresses,0); + //printf("item.(%s)\n",jprint(item,0)); + if ( (addr= jstr(item,0)) != 0 ) + { + safecopy(coinaddr,addr,64); + //printf("extracted.(%s)\n",coinaddr); + } + } + } + free_json(txobj); } - if ( pushpriv != 0 ) +} + +int32_t basilisk_swapuserdata(uint8_t *userdata,bits256 privkey,int32_t ifpath,bits256 signpriv,uint8_t *redeemscript,int32_t redeemlen) +{ + int32_t i,len = 0; +#ifdef DISABLE_CHECKSIG + userdata[len++] = sizeof(signpriv); + for (i=0; i if path, 0 -> else path return(len); @@ -342,25 +767,246 @@ int32_t basilisk_swapuserdata(uint8_t *userdata,int32_t pushpriv,bits256 privkey OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF*/ +void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen) +{ + int32_t i; char scriptstr[513]; + if ( scriptlen != 0 ) + { + for (i=0; iI.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname); + coinaddr[0] = secretAmstr[0] = secretAm256str[0] = secretBnstr[0] = secretBn256str[0] = 0; + memset(zeroes,0,sizeof(zeroes)); + if ( rawtx != 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->coin->symbol); + if ( rawtx->I.datalen > 0 ) + { + fprintf(fp,",\"tx\":\""); + for (i=0; iI.datalen; i++) + fprintf(fp,"%02x",rawtx->txbytes[i]); + fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_doublesha256(0,rawtx->txbytes,rawtx->I.datalen))); + if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment ) + { + basilisk_swap_coinaddr(myinfo,swap,swap->bobcoin,coinaddr,rawtx->txbytes,rawtx->I.datalen); + if ( coinaddr[0] != 0 ) + { + if ( swap->bobcoin != 0 && swap->bobcoin->FULLNODE < 0 ) + { + if ( (tmp= dpow_importaddress(myinfo,swap->bobcoin,coinaddr)) != 0 ) + free(tmp); + } + if ( rawtx == &swap->bobdeposit ) + safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit)); + else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment)); + } + } + } + if ( swap->Bdeposit[0] != 0 ) + fprintf(fp,",\"%s\":\"%s\"","Bdeposit",swap->Bdeposit); + if ( swap->Bpayment[0] != 0 ) + fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment); + fprintf(fp,",\"expiration\":%u",swap->I.expiration); + fprintf(fp,",\"iambob\":%d",swap->I.iambob); + fprintf(fp,",\"bobcoin\":\"%s\"",swap->bobcoin->symbol); + fprintf(fp,",\"alicecoin\":\"%s\"",swap->alicecoin->symbol); + fprintf(fp,",\"lock\":%u",locktime); + fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount)); + if ( bits256_nonz(triggertxid) != 0 ) + fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid)); + if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 ) + { + basilisk_alicescript(redeemscript,&len,script,0,coinaddr,swap->alicecoin->chain->p2shtype,swap->I.pubAm,swap->I.pubBn); + if ( swap->alicecoin != 0 && swap->alicecoin->FULLNODE < 0 ) + { + if ( (tmp= dpow_importaddress(myinfo,swap->alicecoin,coinaddr)) != 0 ) + free(tmp); + } + fprintf(fp,",\"Apayment\":\"%s\"",coinaddr); + } + /*basilisk_dontforget_userdata("Aclaim",fp,swap->I.userdata_aliceclaim,swap->I.userdata_aliceclaimlen); + basilisk_dontforget_userdata("Areclaim",fp,swap->I.userdata_alicereclaim,swap->I.userdata_alicereclaimlen); + basilisk_dontforget_userdata("Aspend",fp,swap->I.userdata_alicespend,swap->I.userdata_alicespendlen); + basilisk_dontforget_userdata("Bspend",fp,swap->I.userdata_bobspend,swap->I.userdata_bobspendlen); + basilisk_dontforget_userdata("Breclaim",fp,swap->I.userdata_bobreclaim,swap->I.userdata_bobreclaimlen); + basilisk_dontforget_userdata("Brefund",fp,swap->I.userdata_bobrefund,swap->I.userdata_bobrefundlen);*/ + fprintf(fp,"}\n"); + fclose(fp); + } + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fprintf(fp,"{\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u",swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime); + if ( memcmp(zeroes,swap->I.secretAm,20) != 0 ) + { + init_hexbytes_noT(secretAmstr,swap->I.secretAm,20); + fprintf(fp,",\"secretAm\":\"%s\"",secretAmstr); + } + if ( memcmp(zeroes,swap->I.secretAm256,32) != 0 ) + { + init_hexbytes_noT(secretAm256str,swap->I.secretAm256,32); + fprintf(fp,",\"secretAm256\":\"%s\"",secretAm256str); + } + if ( memcmp(zeroes,swap->I.secretBn,20) != 0 ) + { + init_hexbytes_noT(secretBnstr,swap->I.secretBn,20); + fprintf(fp,",\"secretBn\":\"%s\"",secretBnstr); + } + if ( memcmp(zeroes,swap->I.secretBn256,32) != 0 ) + { + init_hexbytes_noT(secretBn256str,swap->I.secretBn256,32); + fprintf(fp,",\"secretBn256\":\"%s\"",secretBn256str); + } + for (i=0; i<2; i++) + if ( bits256_nonz(swap->I.myprivs[i]) != 0 ) + fprintf(fp,",\"myprivs%d\":\"%s\"",i,bits256_str(str,swap->I.myprivs[i])); + if ( bits256_nonz(swap->I.privAm) != 0 ) + fprintf(fp,",\"privAm\":\"%s\"",bits256_str(str,swap->I.privAm)); + if ( bits256_nonz(swap->I.privBn) != 0 ) + fprintf(fp,",\"privBn\":\"%s\"",bits256_str(str,swap->I.privBn)); + if ( bits256_nonz(swap->I.pubA0) != 0 ) + fprintf(fp,",\"pubA0\":\"%s\"",bits256_str(str,swap->I.pubA0)); + if ( bits256_nonz(swap->I.pubB0) != 0 ) + fprintf(fp,",\"pubB0\":\"%s\"",bits256_str(str,swap->I.pubB0)); + if ( bits256_nonz(swap->I.pubB1) != 0 ) + fprintf(fp,",\"pubB1\":\"%s\"",bits256_str(str,swap->I.pubB1)); + if ( bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 ) + fprintf(fp,",\"Bdeposit\":\"%s\"",bits256_str(str,swap->bobdeposit.I.actualtxid)); + if ( bits256_nonz(swap->bobrefund.I.actualtxid) != 0 ) + fprintf(fp,",\"Brefund\":\"%s\"",bits256_str(str,swap->bobrefund.I.actualtxid)); + if ( bits256_nonz(swap->aliceclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Aclaim\":\"%s\"",bits256_str(str,swap->aliceclaim.I.actualtxid)); + + if ( bits256_nonz(swap->bobpayment.I.actualtxid) != 0 ) + fprintf(fp,",\"Bpayment\":\"%s\"",bits256_str(str,swap->bobpayment.I.actualtxid)); + if ( bits256_nonz(swap->alicespend.I.actualtxid) != 0 ) + fprintf(fp,",\"Aspend\":\"%s\"",bits256_str(str,swap->alicespend.I.actualtxid)); + if ( bits256_nonz(swap->bobreclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Breclaim\":\"%s\"",bits256_str(str,swap->bobreclaim.I.actualtxid)); + + if ( bits256_nonz(swap->alicepayment.I.actualtxid) != 0 ) + fprintf(fp,",\"Apayment\":\"%s\"",bits256_str(str,swap->alicepayment.I.actualtxid)); + if ( bits256_nonz(swap->bobspend.I.actualtxid) != 0 ) + fprintf(fp,",\"Bspend\":\"%s\"",bits256_str(str,swap->bobspend.I.actualtxid)); + if ( bits256_nonz(swap->alicereclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Areclaim\":\"%s\"",bits256_str(str,swap->alicereclaim.I.actualtxid)); + + if ( bits256_nonz(swap->otherfee.I.actualtxid) != 0 ) + fprintf(fp,",\"otherfee\":\"%s\"",bits256_str(str,swap->otherfee.I.actualtxid)); + if ( bits256_nonz(swap->myfee.I.actualtxid) != 0 ) + fprintf(fp,",\"myfee\":\"%s\"",bits256_str(str,swap->myfee.I.actualtxid)); + fprintf(fp,",\"dest33\":\""); + for (i=0; i<33; i++) + fprintf(fp,"%02x",swap->persistent_pubkey33[i]); + fprintf(fp,"\"}\n"); + fclose(fp); + } +} + +void basilisk_dontforget_update(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) +{ + bits256 triggertxid; + memset(triggertxid.bytes,0,sizeof(triggertxid)); + if ( rawtx == 0 ) + { + basilisk_dontforget(myinfo,swap,0,0,triggertxid); + return; + } + if ( rawtx == &swap->myfee ) + basilisk_dontforget(myinfo,swap,&swap->myfee,0,triggertxid); + else if ( rawtx == &swap->otherfee ) + basilisk_dontforget(myinfo,swap,&swap->otherfee,0,triggertxid); + else if ( rawtx == &swap->bobdeposit ) + { + basilisk_dontforget(myinfo,swap,&swap->bobdeposit,0,triggertxid); + basilisk_dontforget(myinfo,swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid); + } + else if ( rawtx == &swap->bobrefund ) + basilisk_dontforget(myinfo,swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid); + else if ( rawtx == &swap->aliceclaim ) + { + basilisk_dontforget(myinfo,swap,&swap->bobrefund,0,triggertxid); + basilisk_dontforget(myinfo,swap,&swap->aliceclaim,0,swap->bobrefund.I.actualtxid); + } + else if ( rawtx == &swap->alicepayment ) + { + basilisk_dontforget(myinfo,swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + } + else if ( rawtx == &swap->bobspend ) + { + basilisk_dontforget(myinfo,swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + basilisk_dontforget(myinfo,swap,&swap->bobspend,0,swap->alicepayment.I.actualtxid); + } + else if ( rawtx == &swap->alicereclaim ) + { + basilisk_dontforget(myinfo,swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + basilisk_dontforget(myinfo,swap,&swap->alicereclaim,0,swap->bobrefund.I.actualtxid); + } + else if ( rawtx == &swap->bobpayment ) + { + basilisk_dontforget(myinfo,swap,&swap->bobpayment,0,triggertxid); + basilisk_dontforget(myinfo,swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); + } + else if ( rawtx == &swap->alicespend ) + { + basilisk_dontforget(myinfo,swap,&swap->bobpayment,0,triggertxid); + basilisk_dontforget(myinfo,swap,&swap->alicespend,0,triggertxid); + } + else if ( rawtx == &swap->bobreclaim ) + basilisk_dontforget(myinfo,swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); +} + int32_t basilisk_verify_bobdeposit(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { - uint8_t userdata[512]; int32_t len = 0; struct basilisk_swap *swap = ptr; - if ( basilisk_rawtx_spendscript(myinfo,swap->bobcoin->blocks.hwmchain.height,&swap->bobdeposit,0,data,datalen,0) == 0 ) + uint8_t userdata[512]; int32_t i,retval,len = 0; static bits256 zero; struct basilisk_swap *swap = ptr; + if ( basilisk_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) { - //len = basilisk_swapuserdata(userdata,0,GENESIS_PRIVKEY,0x02,swap->pubA0,1); - userdata[len++] = 0x51; - return(basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->aliceclaim,&swap->bobdeposit,swap->myprivs[0],0,userdata,len)); + swap->bobdeposit.I.signedtxid = basilisk_swap_broadcast(swap->bobdeposit.name,myinfo,swap,swap->bobdeposit.coin,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); + if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 ) + swap->depositunconf = 1; + basilisk_dontforget_update(myinfo,swap,&swap->bobdeposit); + len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + memcpy(swap->I.userdata_aliceclaim,userdata,len); + swap->I.userdata_aliceclaimlen = len; + if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1)) == 0 ) + { + for (i=0; ibobdeposit.I.datalen; i++) + printf("%02x",swap->bobdeposit.txbytes[i]); + printf(" <- bobdeposit\n"); + for (i=0; ialiceclaim.I.datalen; i++) + printf("%02x",swap->aliceclaim.txbytes[i]); + printf(" <- aliceclaim\n"); + basilisk_txlog(myinfo,swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); + return(retval); + } } printf("error with bobdeposit\n"); return(-1); } -int32_t basilisk_bobdeposit_refund(struct supernet_info *myinfo,struct basilisk_swap *swap) +int32_t basilisk_bobdeposit_refund(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t delay) { - uint8_t userdata[512]; int32_t len = 0; - printf("basilisk_bobdeposit_refund\n"); - len = basilisk_swapuserdata(userdata,1,swap->privBn,0x03,swap->pubB0,0); - return(basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->bobrefund,&swap->bobdeposit,swap->myprivs[0],0,userdata,len)); + uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; + len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + memcpy(swap->I.userdata_bobrefund,userdata,len); + swap->I.userdata_bobrefundlen = len; + if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0)) == 0 ) + { + for (i=0; ibobrefund.I.datalen; i++) + printf("%02x",swap->bobrefund.txbytes[i]); + printf(" <- bobrefund.(%s)\n",bits256_str(str,swap->bobrefund.I.txid)); + basilisk_txlog(myinfo,swap,&swap->bobrefund,delay); + return(retval); + } + return(-1); } /*Bob paytx: @@ -370,55 +1016,108 @@ int32_t basilisk_bobdeposit_refund(struct supernet_info *myinfo,struct basilisk_ OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF*/ -int32_t basilisk_bobpayment_reclaim(struct supernet_info *myinfo,struct basilisk_swap *swap) +int32_t basilisk_bobpayment_reclaim(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t delay) { - uint8_t userdata[512]; int32_t len = 0; + uint8_t userdata[512]; int32_t i,retval,len = 0; static bits256 zero; printf("basilisk_bobpayment_reclaim\n"); - userdata[len++] = 0x51; - //len = basilisk_swapuserdata(userdata,0,GENESIS_PRIVKEY,0x03,swap->pubB1,1); - return(basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->bobreclaim,&swap->bobpayment,swap->myprivs[1],0,userdata,len)); + len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + memcpy(swap->I.userdata_bobreclaim,userdata,len); + swap->I.userdata_bobreclaimlen = len; + if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1)) == 0 ) + { + for (i=0; ibobreclaim.I.datalen; i++) + printf("%02x",swap->bobreclaim.txbytes[i]); + printf(" <- bobreclaim\n"); + basilisk_txlog(myinfo,swap,&swap->bobreclaim,delay); + return(retval); + } + return(-1); } int32_t basilisk_verify_bobpaid(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { - uint8_t userdata[512]; int32_t len = 0; struct basilisk_swap *swap = ptr; - if ( basilisk_rawtx_spendscript(myinfo,swap->bobcoin->blocks.hwmchain.height,&swap->bobpayment,0,data,datalen,0) == 0 ) + uint8_t userdata[512]; int32_t i,retval,len = 0; bits256 revAm; struct basilisk_swap *swap = ptr; + memset(revAm.bytes,0,sizeof(revAm)); + if ( basilisk_rawtx_spendscript(swap,swap->bobcoin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) { - len = basilisk_swapuserdata(userdata,1,swap->privAm,0x02,swap->pubA0,0); - char str[65]; printf("bobpaid.(%s)\n",bits256_str(str,swap->privAm)); - return(basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->alicespend,&swap->bobpayment,swap->myprivs[0],0,userdata,len)); - } else return(-1); + swap->bobpayment.I.signedtxid = basilisk_swap_broadcast(swap->bobpayment.name,myinfo,swap,swap->bobpayment.coin,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); + if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 ) + swap->paymentunconf = 1; + basilisk_dontforget_update(myinfo,swap,&swap->bobpayment); + for (i=0; i<32; i++) + revAm.bytes[i] = swap->I.privAm.bytes[31-i]; + len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + memcpy(swap->I.userdata_alicespend,userdata,len); + swap->I.userdata_alicespendlen = len; + char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0])); + if ( (retval= basilisk_rawtx_sign(myinfo,swap->bobcoin->longestchain,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1)) == 0 ) + { + for (i=0; ibobpayment.I.datalen; i++) + printf("%02x",swap->bobpayment.txbytes[i]); + printf(" <- bobpayment\n"); + for (i=0; ialicespend.I.datalen; i++) + printf("%02x",swap->alicespend.txbytes[i]); + printf(" <- alicespend\n\n"); + swap->I.alicespent = 1; + basilisk_txlog(myinfo,swap,&swap->alicespend,-1); + return(retval); + } + } + return(-1); +} + +void basilisk_alicepayment(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn) +{ + alicepayment->I.spendlen = basilisk_alicescript(alicepayment->redeemscript,&alicepayment->I.redeemlen,alicepayment->spendscript,0,alicepayment->I.destaddr,coin->chain->p2shtype,pubAm,pubBn); + basilisk_rawtx_gen("alicepayment",myinfo,swap->I.started,swap->persistent_pubkey33,0,1,alicepayment,alicepayment->I.locktime,alicepayment->spendscript,alicepayment->I.spendlen,coin->chain->txfee,1,0); } int32_t basilisk_alicepayment_spend(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *dest) { + int32_t i,retval; printf("alicepayment_spend\n"); - return(basilisk_rawtx_sign(myinfo,swap->alicecoin->blocks.hwmchain.height,swap,dest,&swap->alicepayment,swap->privAm,&swap->privBn,0,0)); + swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,swap->alicecoin->chain->p2shtype,swap->I.pubAm,swap->I.pubBn); + printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen); + if ( swap->I.iambob == 0 ) + { + memcpy(swap->I.userdata_alicereclaim,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); + swap->I.userdata_alicereclaimlen = swap->alicepayment.I.spendlen; + } + else + { + memcpy(swap->I.userdata_bobspend,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); + swap->I.userdata_bobspendlen = swap->alicepayment.I.spendlen; + } + if ( (retval= basilisk_rawtx_sign(myinfo,swap->alicecoin->longestchain,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1)) == 0 ) + { + for (i=0; iI.datalen; i++) + printf("%02x",dest->txbytes[i]); + printf(" <- msigspend\n\n"); + if ( dest == &swap->bobspend ) + swap->I.bobspent = 1; + basilisk_txlog(myinfo,swap,dest,0); // bobspend or alicereclaim + return(retval); + } + return(-1); } int32_t basilisk_verify_alicepaid(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { struct basilisk_swap *swap = ptr; - if ( basilisk_rawtx_spendscript(myinfo,swap->alicecoin->blocks.hwmchain.height,&swap->alicepayment,0,data,datalen,0) == 0 ) - return(0); - else return(-1); -} - -int32_t basilisk_privAm_extract(struct supernet_info *myinfo,struct basilisk_swap *swap) -{ - // need to scan blockchain for alicespend of bobpayment - // search for swap->bobpayment.actualtxid in spends - if ( bits256_nonz(swap->privAm) != 0 && swap->bobspend.txbytes == 0 ) + if ( basilisk_rawtx_spendscript(swap,swap->alicecoin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) { - char str[65]; printf("have privAm.%s\n",bits256_str(str,swap->privAm)); - return(basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend)); + swap->alicepayment.I.signedtxid = basilisk_swap_broadcast(swap->alicepayment.name,myinfo,swap,swap->alicepayment.coin,swap->alicepayment.txbytes,swap->alicepayment.I.datalen); + if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) + swap->aliceunconf = 1; + basilisk_dontforget_update(myinfo,swap,&swap->alicepayment); + return(0); } - return(-1); + else return(-1); } int32_t basilisk_verify_pubpair(int32_t *wrongfirstbytep,struct basilisk_swap *swap,int32_t ind,uint8_t pub0,bits256 pubi,uint64_t txid) { - if ( pub0 != (swap->iambob ^ 1) + 0x02 ) + if ( pub0 != (swap->I.iambob ^ 1) + 0x02 ) { (*wrongfirstbytep)++; printf("wrongfirstbyte[%d] %02x\n",ind,pub0); @@ -437,21 +1136,113 @@ int32_t basilisk_verify_pubpair(int32_t *wrongfirstbytep,struct basilisk_swap *s return(0); } +int32_t basilisk_bobscripts_set(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t depositflag,int32_t genflag) +{ + int32_t i,j; //char str[65]; + if ( genflag != 0 && swap->I.iambob == 0 ) + printf("basilisk_bobscripts_set WARNING: alice generating BOB tx\n"); + if ( depositflag == 0 ) + { + swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0); + bitcoin_address(swap->bobpayment.p2shaddr,swap->bobcoin->chain->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + //for (i=0; ibobpayment.redeemlen; i++) + // printf("%02x",swap->bobpayment.redeemscript[i]); + //printf(" <- bobpayment.%d\n",i); + if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.I.datalen == 0 ) + { + for (i=0; i<3; i++) + { + //if ( swap->bobpayment.txbytes != 0 && swap->bobpayment.I.spendlen != 0 ) + // break; + basilisk_rawtx_gen("payment",myinfo,swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,swap->bobpayment.coin->chain->txfee,1,0); + if ( swap->bobpayment.I.spendlen == 0 || swap->bobpayment.I.datalen == 0 ) + { + printf("error bob generating %p payment.%d\n",swap->bobpayment.txbytes,swap->bobpayment.I.spendlen); + sleep(DEX_SLEEP); + } + else + { + for (j=0; jbobpayment.I.datalen; j++) + printf("%02x",swap->bobpayment.txbytes[j]); + //printf(" <- bobpayment.%d\n",swap->bobpayment.datalen); + //for (j=0; jbobpayment.redeemlen; j++) + // printf("%02x",swap->bobpayment.redeemscript[j]); + //printf(" <- redeem.%d\n",swap->bobpayment.redeemlen); + printf(" <- GENERATED BOB PAYMENT.%d\n",swap->bobpayment.I.datalen); + iguana_unspents_mark(myinfo,swap->bobcoin,swap->bobpayment.vins); + basilisk_bobpayment_reclaim(myinfo,swap,swap->I.callduration); + printf("bobscripts set completed\n"); + return(0); + } + } + } + } + else + { + swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); + bitcoin_address(swap->bobdeposit.p2shaddr,swap->bobcoin->chain->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) ) + { + for (i=0; i<3; i++) + { + //if ( swap->bobdeposit.txbytes != 0 && swap->bobdeposit.I.spendlen != 0 ) + // break; + basilisk_rawtx_gen("deposit",myinfo,swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,swap->bobdeposit.coin->chain->txfee,1,0); + if ( swap->bobdeposit.I.datalen == 0 || swap->bobdeposit.I.spendlen == 0 ) + { + printf("error bob generating %p deposit.%d\n",swap->bobdeposit.txbytes,swap->bobdeposit.I.spendlen); + sleep(DEX_SLEEP); + } + else + { + for (j=0; jbobdeposit.I.datalen; j++) + printf("%02x",swap->bobdeposit.txbytes[j]); + printf(" <- GENERATED BOB DEPOSIT.%d\n",swap->bobdeposit.I.datalen); + //for (j=0; jbobdeposit.redeemlen; j++) + // printf("%02x",swap->bobdeposit.redeemscript[j]); + //printf(" <- redeem.%d\n",swap->bobdeposit.redeemlen); + //printf("GENERATED BOB DEPOSIT\n"); + iguana_unspents_mark(myinfo,swap->bobcoin,swap->bobdeposit.vins); + basilisk_bobdeposit_refund(myinfo,swap,swap->I.putduration); + printf("bobscripts set completed\n"); + return(0); + } + } + } + //for (i=0; ibobdeposit.redeemlen; i++) + // printf("%02x",swap->bobdeposit.redeemscript[i]); + //printf(" <- bobdeposit.%d\n",i); + } + return(0); +} + int32_t basilisk_verify_privi(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { - int32_t j,wrongfirstbyte,len = 0; bits256 privkey,pubi; uint8_t secret160[20],pubkey33[33]; uint64_t txid; struct basilisk_swap *swap = ptr; + int32_t j,wrongfirstbyte,len = 0; bits256 privkey,pubi; char str[65],str2[65]; uint8_t secret160[20],pubkey33[33]; uint64_t txid; struct basilisk_swap *swap = ptr; + memset(privkey.bytes,0,sizeof(privkey)); if ( datalen == sizeof(bits256) ) { for (j=0; j<32; j++) privkey.bytes[j] = data[len++]; - calc_rmd160_sha256(secret160,privkey.bytes,sizeof(privkey)); + revcalc_rmd160_sha256(secret160,privkey);//.bytes,sizeof(privkey)); memcpy(&txid,secret160,sizeof(txid)); pubi = bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); - if ( basilisk_verify_pubpair(&wrongfirstbyte,swap,swap->choosei,pubkey33[0],pubi,txid) == 0 ) + if ( basilisk_verify_pubpair(&wrongfirstbyte,swap,swap->I.choosei,pubkey33[0],pubi,txid) == 0 ) { - if ( swap->iambob != 0 ) - swap->privAm = privkey; - else swap->privBn = privkey; + if ( swap->I.iambob != 0 ) + { + swap->I.privAm = privkey; + vcalc_sha256(0,swap->I.secretAm256,privkey.bytes,sizeof(privkey)); + printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); + basilisk_bobscripts_set(myinfo,swap,0,1); + } + else + { + swap->I.privBn = privkey; + vcalc_sha256(0,swap->I.secretBn256,privkey.bytes,sizeof(privkey)); + printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); + } + basilisk_dontforget_update(myinfo,swap,0); char str[65]; printf("privi verified.(%s)\n",bits256_str(str,privkey)); return(0); } @@ -459,390 +1250,626 @@ int32_t basilisk_verify_privi(struct supernet_info *myinfo,void *ptr,uint8_t *da return(-1); } -int32_t basilisk_process_swapget(struct supernet_info *myinfo,void *ptr,int32_t (*internal_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration) +int32_t basilisk_process_swapverify(struct supernet_info *myinfo,void *ptr,int32_t (*internal_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration) { struct basilisk_swap *swap = ptr; - return((*internal_func)(myinfo,swap,data,datalen)); + if ( internal_func != 0 ) + return((*internal_func)(myinfo,swap,data,datalen)); + else return(0); +} + +void basilisk_swapgotdata(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit) +{ + int32_t i; struct basilisk_swapmessage *mp; + for (i=0; inummessages; i++) + if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 ) + return; + //printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data); + swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1)); + mp = &swap->messages[swap->nummessages++]; + mp->crc32 = crc32; + mp->srchash = srchash; + mp->desthash = desthash; + mp->msgbits = msgbits; + mp->quoteid = quoteid; + mp->data = malloc(datalen); + mp->datalen = datalen; + memcpy(mp->data,data,datalen); + if ( reinit == 0 && swap->fp != 0 ) + { + fwrite(mp,1,sizeof(*mp),swap->fp); + fwrite(data,1,datalen,swap->fp); + fflush(swap->fp); + } +} + +FILE *basilisk_swap_save(struct supernet_info *myinfo,struct basilisk_swap *swap,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit) +{ + FILE *fp=0; /*char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,rp->requestid,rp->quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) == 0 ) + { + if ( (fp= fopen(fname,"wb+")) != 0 ) + { + fwrite(privkey.bytes,1,sizeof(privkey),fp); + fwrite(rp,1,sizeof(*rp),fp); + fwrite(&statebits,1,sizeof(statebits),fp); + fwrite(&optionduration,1,sizeof(optionduration),fp); + fflush(fp); + } + } + else if ( reinit != 0 ) + { + }*/ + return(fp); +} + +int32_t basilisk_swap_load(uint32_t requestid,uint32_t quoteid,bits256 *privkeyp,struct basilisk_request *rp,uint32_t *statebitsp,int32_t *optiondurationp) +{ + FILE *fp=0; char fname[512]; int32_t retval = -1; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) != 0 ) + { + if ( fread(privkeyp,1,sizeof(*privkeyp),fp) == sizeof(*privkeyp) && + fread(rp,1,sizeof(*rp),fp) == sizeof(*rp) && + fread(statebitsp,1,sizeof(*statebitsp),fp) == sizeof(*statebitsp) && + fread(optiondurationp,1,sizeof(*optiondurationp),fp) == sizeof(*optiondurationp) ) + retval = 0; + fclose(fp); + } + return(retval); +} + +struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit); + +void basilisk_swaps_init(struct supernet_info *myinfo) +{ + char fname[512]; uint32_t iter,swapcompleted,requestid,quoteid,optionduration,statebits; FILE *fp; bits256 privkey;struct basilisk_request R; struct basilisk_swapmessage M; struct basilisk_swap *swap = 0; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (myinfo->swapsfp= fopen(fname,"rb+")) != 0 ) + { + while ( fread(&requestid,1,sizeof(requestid),myinfo->swapsfp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),myinfo->swapsfp) == sizeof(quoteid) ) + { + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + printf("%s\n",fname); + if ( (fp= fopen(fname,"rb+")) != 0 ) // check to see if completed + { + memset(&M,0,sizeof(M)); + swapcompleted = 1; + for (iter=0; iter<2; iter++) + { + if ( fread(privkey.bytes,1,sizeof(privkey),fp) == sizeof(privkey) && + fread(&R,1,sizeof(R),fp) == sizeof(R) && + fread(&statebits,1,sizeof(statebits),fp) == sizeof(statebits) && + fread(&optionduration,1,sizeof(optionduration),fp) == sizeof(optionduration) ) + { + while ( 0 && fread(&M,1,sizeof(M),fp) == sizeof(M) ) + { + M.data = 0; + //printf("entry iter.%d crc32.%x datalen.%d\n",iter,M.crc32,M.datalen); + if ( M.datalen < 100000 ) + { + M.data = malloc(M.datalen); + if ( fread(M.data,1,M.datalen,fp) == M.datalen ) + { + if ( calc_crc32(0,M.data,M.datalen) == M.crc32 ) + { + if ( iter == 1 ) + { + if ( swap == 0 ) + { + swap = basilisk_thread_start(myinfo,privkey,&R,statebits,optionduration,1); + swap->I.choosei = swap->I.otherchoosei = -1; + } + if ( swap != 0 ) + basilisk_swapgotdata(myinfo,swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1); + } + } else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32); + } else printf("error reading M.datalen %d\n",M.datalen); + free(M.data), M.data = 0; + } + } + } + if ( swapcompleted != 0 ) + break; + rewind(fp); + } + } + } + } else myinfo->swapsfp = fopen(fname,"wb+"); } +void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t amlp); + int32_t basilisk_swapget(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen)) { - int32_t retval; cJSON *retarray; - if ( (retarray= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,msgbits,0)) != 0 ) + uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0; + while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,0)) >= 0 ) { - retval = basilisk_process_retarray(myinfo,swap,basilisk_process_swapget,data,maxlen,swap->req.quoteid,msgbits,retarray,basilisk_verify_func); - if ( retval > 0 ) - return(0); - //return((*basilisk_verify_func)(myinfo,swap,data,datalen)); + swap->lasttime = (uint32_t)time(NULL); + memset(srchash.bytes,0,sizeof(srchash)); + memset(desthash.bytes,0,sizeof(desthash)); + //printf("gotmsg.[%d] crc.%x\n",size,crc32); + offset = 0; + for (i=0; i<32; i++) + srchash.bytes[i] = ptr[offset++]; + for (i=0; i<32; i++) + desthash.bytes[i] = ptr[offset++]; + offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),"eid); + offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits); + if ( size > offset ) + { + crc32 = calc_crc32(0,&ptr[offset],size-offset); + if ( size > offset ) + { + //printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset); + basilisk_swapgotdata(myinfo,swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0); + } + } + else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 ) + { + if ( swap->aborted == 0 ) + { + swap->aborted = (uint32_t)time(NULL); + printf("got abort signal from other side\n"); + } + } else printf("basilisk_swapget: got strange packet\n"); + if ( ptr != 0 ) + nn_freemsg(ptr), ptr = 0; } - return(-1); + //char str[65],str2[65]; + for (i=0; inummessages; i++) + { + //printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash)); + if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 ) + { + if ( swap->messages[i].msgbits == msgbits ) + { + if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 ) + { + printf("nothing received for a while from Bob, try new sockets\n"); + if ( swap->pushsock >= 0 ) // + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) // + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); + } + mp = &swap->messages[i]; + if ( msgbits != 0x80000000 ) + break; + } + } + } + if ( mp != 0 ) + retval = (*basilisk_verify_func)(myinfo,swap,mp->data,mp->datalen); + //printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash)); + return(retval); } -int32_t basilisk_privBn_extract(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +uint32_t basilisk_swapsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2]) +{ + uint8_t *buf; int32_t sentbytes,offset=0,i; + buf = malloc(datalen + sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2); + for (i=0; i<32; i++) + buf[offset++] = swap->I.myhash.bytes[i]; + for (i=0; i<32; i++) + buf[offset++] = swap->I.otherhash.bytes[i]; + offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); + if ( datalen > 0 ) + memcpy(&buf[offset],data,datalen), offset += datalen; + if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset ) + { + printf("sentbytes.%d vs offset.%d\n",sentbytes,offset); + if ( sentbytes < 0 ) + { + if ( swap->pushsock >= 0 ) + nn_close(swap->pushsock), swap->pushsock = -1; //, + if ( swap->subsock >= 0 ) // + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = swap->I.iambob != 0 ? -1 : 0; + swap->aborted = (uint32_t)time(NULL); + } + } + //else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data); + free(buf); + return(nextbits); +} + +void basilisk_swap_sendabort(struct supernet_info *myinfo,struct basilisk_swap *swap) { - // need to scan blockchain for bobrefund - // search for swap->bobrefund.actualtxid in spends - if ( basilisk_swapget(myinfo,swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) + uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0; + memset(buf,0,sizeof(buf)); + offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); + if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset ) { - if ( bits256_nonz(swap->privBn) != 0 && swap->alicereclaim.txbytes == 0 ) + if ( sentbytes < 0 ) { - char str[65]; printf("have privBn.%s\n",bits256_str(str,swap->privBn)); - return(basilisk_alicepayment_spend(myinfo,swap,&swap->alicereclaim)); + if ( swap->pushsock >= 0 ) // + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) // + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; } + } else printf("basilisk_swap_sendabort\n"); +} + +int32_t basilisk_privBn_extract(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + if ( basilisk_priviextract(myinfo,swap->bobcoin,"privBn",&swap->I.privBn,swap->I.secretBn,swap->bobrefund.I.actualtxid,0) == 0 ) + { + printf("extracted privBn from blockchain\n"); + } + else if ( basilisk_swapget(myinfo,swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) + { + } + if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.I.datalen == 0 ) + { + char str[65]; printf("got privBn.%s\n",bits256_str(str,swap->I.privBn)); + return(basilisk_alicepayment_spend(myinfo,swap,&swap->alicereclaim)); + } + return(-1); +} + +int32_t basilisk_privAm_extract(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + if ( basilisk_priviextract(myinfo,swap->bobcoin,"privAm",&swap->I.privAm,swap->I.secretAm,swap->bobpayment.I.actualtxid,0) == 0 ) + { + printf("extracted privAm from blockchain\n"); + } + if ( bits256_nonz(swap->I.privAm) != 0 && swap->bobspend.I.datalen == 0 ) + { + char str[65]; printf("got privAm.%s\n",bits256_str(str,swap->I.privAm)); + return(basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend)); } return(-1); } -// end of coin protocol dependent -bits256 instantdex_derivekeypair(struct supernet_info *myinfo,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) +bits256 instantdex_derivekeypair(void *ctx,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) { bits256 sharedsecret; sharedsecret = curve25519_shared(privkey,orderhash); vcalc_sha256cat(newprivp->bytes,orderhash.bytes,sizeof(orderhash),sharedsecret.bytes,sizeof(sharedsecret)); - return(bitcoin_pubkey33(myinfo->ctx,pubkey,*newprivp)); + return(bitcoin_pubkey33(ctx,pubkey,*newprivp)); } -int32_t instantdex_pubkeyargs(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) +int32_t instantdex_pubkeyargs(void *ctx,struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) { - char buf[3]; int32_t i,n,m,len=0; bits256 pubi; uint64_t txid; uint8_t secret160[20],pubkey[33]; + char buf[3]; int32_t i,n,m,len=0; bits256 pubi,reveal; uint64_t txid; uint8_t secret160[20],pubkey[33]; sprintf(buf,"%c0",'A' - 0x02 + firstbyte); if ( numpubs > 2 ) { - if ( swap->numpubs+2 >= numpubs ) + if ( swap->I.numpubs+2 >= numpubs ) return(numpubs); - printf(">>>>>> start generating %s\n",buf); + //fprintf(stderr,">>>>>> start generating %s\n",buf); } for (i=n=m=0; imypubs[n]) == 0 ) + if ( bits256_nonz(swap->I.mypubs[n]) == 0 ) { - swap->myprivs[n] = privkey; - memcpy(swap->mypubs[n].bytes,pubkey+1,sizeof(bits256)); - if ( swap->iambob != 0 ) + swap->I.myprivs[n] = privkey; + memcpy(swap->I.mypubs[n].bytes,pubkey+1,sizeof(bits256)); + reveal = basilisk_revealkey(privkey,swap->I.mypubs[n]); + if ( swap->I.iambob != 0 ) { if ( n == 0 ) - swap->pubB0 = swap->mypubs[n]; + swap->I.pubB0 = reveal; else if ( n == 1 ) - swap->pubB1 = swap->mypubs[n]; + swap->I.pubB1 = reveal; } - else if ( swap->iambob == 0 ) + else if ( swap->I.iambob == 0 ) { if ( n == 0 ) - swap->pubA0 = swap->mypubs[n]; + swap->I.pubA0 = reveal; else if ( n == 1 ) - swap->pubA1 = swap->mypubs[n]; + swap->I.pubA1 = reveal; } } } if ( m < INSTANTDEX_DECKSIZE ) { swap->privkeys[m] = privkey; - calc_rmd160_sha256(secret160,privkey.bytes,sizeof(privkey)); + revcalc_rmd160_sha256(secret160,privkey);//.bytes,sizeof(privkey)); memcpy(&txid,secret160,sizeof(txid)); len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][0],sizeof(txid),&txid); len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][1],sizeof(pubi.txid),&pubi.txid); m++; - if ( m > swap->numpubs ) - swap->numpubs = m; + if ( m > swap->I.numpubs ) + swap->I.numpubs = m; } n++; } if ( n > 2 || m > 2 ) - printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->numpubs); + printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->I.numpubs); return(n); } -int32_t basilisk_rawtx_return(struct supernet_info *myinfo,int32_t height,struct basilisk_rawtx *rawtx,cJSON *item,cJSON *privkeyarray,int32_t lockinputs) +void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33,int32_t jumblrflag) { - char *signedtx,*txbytes; cJSON *vins; int32_t i,n,retval = -1; - if ( (txbytes= jstr(item,"rawtx")) != 0 && (vins= jobj(item,"vins")) != 0 ) + strcpy(rawtx->name,name); + rawtx->coin = coin; + strcpy(rawtx->I.coinstr,coin->symbol); + rawtx->I.numconfirms = numconfirms; + if ( (rawtx->I.amount= satoshis) < 50000 ) + rawtx->I.amount = 50000; + rawtx->I.vintype = vintype; // 0 -> std, 2 -> 2of2, 3 -> spend bobpayment, 4 -> spend bobdeposit + rawtx->I.vouttype = vouttype; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit + if ( rawtx->I.vouttype == 0 ) { - if ( (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&rawtx->signedtxid,&rawtx->completed,vins,txbytes,privkeyarray,0)) != 0 ) - { - if ( lockinputs != 0 ) - { - iguana_RTunspentslock(myinfo,rawtx->coin,vins); - if ( (n= cJSON_GetArraySize(vins)) != 0 ) - { - bits256 txid; int32_t vout; - for (i=0; icoin->symbol,txid,vout,1); - } - } - } - } - rawtx->datalen = (int32_t)strlen(signedtx) >> 1; - rawtx->txbytes = calloc(1,rawtx->datalen); - decode_hex(rawtx->txbytes,rawtx->datalen,signedtx); - //printf("SIGNEDTX.(%s)\n",signedtx); - free(signedtx); - retval = 0; - } else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll + if ( strcmp(coin->symbol,"BTC") == 0 && (quoteid % 10) == 0 ) + decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160); + else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160); + bitcoin_address(rawtx->I.destaddr,rawtx->coin->chain->pubtype,rawtx->I.rmd160,20); } - return(retval); + if ( pubkey33 != 0 ) + { + memcpy(rawtx->I.pubkey33,pubkey33,33); + bitcoin_address(rawtx->I.destaddr,rawtx->coin->chain->pubtype,rawtx->I.pubkey33,33); + bitcoin_addr2rmd160(&rawtx->I.addrtype,rawtx->I.rmd160,rawtx->I.destaddr); + } + if ( rawtx->I.vouttype <= 1 && rawtx->I.destaddr[0] != 0 ) + { + rawtx->I.spendlen = bitcoin_standardspend(rawtx->spendscript,0,rawtx->I.rmd160); + printf("%s spendlen.%d %s <- %.8f\n",name,rawtx->I.spendlen,rawtx->I.destaddr,dstr(rawtx->I.amount)); + } else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr); } -int32_t basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf) +int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct iguana_info **alicecoinp,char *src,char *dest,bits256 srchash,bits256 desthash) { - struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],wifstr[64],*retstr,scriptstr[1024]; uint32_t basilisktag; int32_t flag,i,n,retval = -1; cJSON *valsobj,*retarray=0,*privkeyarray,*addresses; - //if ( (waddr= iguana_getaccountaddress(myinfo,rawtx->coin,0,0,rawtx->coin->changeaddr,"change")) == 0 ) - if ( rawtx->coin->changeaddr[0] == 0 ) + struct iguana_info *coin = iguana_coinfind(src); + if ( coin == 0 || iguana_coinfind(dest) == 0 ) + return(0); + *bobcoinp = *alicecoinp = 0; + *bobcoinp = iguana_coinfind(dest); + *alicecoinp = iguana_coinfind(src); + if ( bits256_cmp(pubkey,srchash) == 0 ) { - bitcoin_address(rawtx->coin->changeaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); - printf("set change address.(%s)\n",rawtx->coin->changeaddr); + if ( strcmp(src,(*bobcoinp)->symbol) == 0 ) + return(1); + else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 ) + return(-1); + else return(0); } - init_hexbytes_noT(scriptstr,script,scriptlen); - privkeyarray = cJSON_CreateArray(); - addresses = cJSON_CreateArray(); - bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); - //printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr); - if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) + else if ( bits256_cmp(pubkey,desthash) == 0 ) { - bitcoin_priv2wif(wifstr,waddr->privkey,rawtx->coin->chain->wiftype); - jaddistr(privkeyarray,waddr->wifstr); + if ( strcmp(src,(*bobcoinp)->symbol) == 0 ) + return(-1); + else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 ) + return(1); + else return(0); } - basilisktag = (uint32_t)rand(); - jaddistr(addresses,coinaddr); - valsobj = cJSON_CreateObject(); - //jadd(valsobj,"addresses",addresses); - jaddstr(valsobj,"coin",rawtx->coin->symbol); - jaddstr(valsobj,"spendscript",scriptstr); - jaddstr(valsobj,"changeaddr",rawtx->coin->changeaddr); - jadd64bits(valsobj,"satoshis",rawtx->amount); - jadd64bits(valsobj,"txfee",txfee); - jaddnum(valsobj,"minconf",minconf); - jaddnum(valsobj,"locktime",locktime); - jaddnum(valsobj,"timeout",30000); - rawtx->locktime = locktime; - printf("%s locktime.%u\n",rawtx->name,locktime); - if ( (retstr= basilisk_bitcoinrawtx(myinfo,rawtx->coin,"",basilisktag,jint(valsobj,"timeout"),valsobj)) != 0 ) - { - printf("%s got.(%s)\n",str,retstr); - flag = 0; - if ( (retarray= cJSON_Parse(retstr)) != 0 ) - { - if ( is_cJSON_Array(retarray) != 0 ) - { - n = cJSON_GetArraySize(retarray); - for (i=0; icoin->blocks.hwmchain.height,rawtx,jitem(retarray,i),privkeyarray,lockinputs)) == 0 ) - break; - } - } else retval = basilisk_rawtx_return(myinfo,rawtx->coin->blocks.hwmchain.height,rawtx,retarray,privkeyarray,lockinputs); - free(retarray); - } else printf("error parsing.(%s)\n",retstr); - free(retstr); - } else printf("error creating %s feetx\n",iambob != 0 ? "BOB" : "ALICE"); - free_json(privkeyarray); - free_json(valsobj); - printf("rawtx retval.%d\n",retval); - return(retval); + return(0); } -void basilisk_rawtx_setparms(char *name,struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33) +void basilisk_swap_saveupdate(struct supernet_info *myinfo,struct basilisk_swap *swap) { - strcpy(rawtx->name,name); - rawtx->coin = coin; - rawtx->numconfirms = numconfirms; - if ( (rawtx->amount= satoshis) < 10000 ) - rawtx->amount = 10000; - rawtx->vintype = vintype; // 0 -> std, 2 -> 2of2, 3 -> spend bobpayment, 4 -> spend bobdeposit - rawtx->vouttype = vouttype; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit - if ( rawtx->vouttype == 0 ) - { - if ( strcmp(coin->symbol,"BTC") == 0 && (swap->req.quoteid % 10) == 0 ) - decode_hex(rawtx->rmd160,20,TIERNOLAN_RMD160); - else decode_hex(rawtx->rmd160,20,INSTANTDEX_RMD160); - bitcoin_address(rawtx->destaddr,rawtx->coin->chain->pubtype,rawtx->rmd160,20); - } - if ( pubkey33 != 0 ) + FILE *fp; char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) { - memcpy(rawtx->pubkey33,pubkey33,33); - bitcoin_address(rawtx->destaddr,rawtx->coin->chain->pubtype,rawtx->pubkey33,33); - bitcoin_addr2rmd160(&rawtx->addrtype,rawtx->rmd160,rawtx->destaddr); + fwrite(&swap->I,1,sizeof(swap->I),fp); + /*fwrite(&swap->bobdeposit,1,sizeof(swap->bobdeposit),fp); + fwrite(&swap->bobpayment,1,sizeof(swap->bobpayment),fp); + fwrite(&swap->alicepayment,1,sizeof(swap->alicepayment),fp); + fwrite(&swap->myfee,1,sizeof(swap->myfee),fp); + fwrite(&swap->otherfee,1,sizeof(swap->otherfee),fp); + fwrite(&swap->aliceclaim,1,sizeof(swap->aliceclaim),fp); + fwrite(&swap->alicespend,1,sizeof(swap->alicespend),fp); + fwrite(&swap->bobreclaim,1,sizeof(swap->bobreclaim),fp); + fwrite(&swap->bobspend,1,sizeof(swap->bobspend),fp); + fwrite(&swap->bobrefund,1,sizeof(swap->bobrefund),fp); + fwrite(&swap->alicereclaim,1,sizeof(swap->alicereclaim),fp);*/ + fwrite(swap->privkeys,1,sizeof(swap->privkeys),fp); + fwrite(swap->otherdeck,1,sizeof(swap->otherdeck),fp); + fwrite(swap->deck,1,sizeof(swap->deck),fp); + fclose(fp); } - if ( rawtx->vouttype <= 1 && rawtx->destaddr[0] != 0 ) - { - rawtx->spendlen = bitcoin_standardspend(rawtx->spendscript,0,rawtx->rmd160); - printf("%s spendlen.%d %s <- %.8f\n",name,rawtx->spendlen,rawtx->destaddr,dstr(rawtx->amount)); - } else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->vouttype,rawtx->destaddr); } -struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,struct basilisk_swap *swap) +int32_t basilisk_swap_loadtx(struct basilisk_rawtx *rawtx,FILE *fp,char *bobcoinstr,char *alicecoinstr) { - struct iguana_info *coin; uint8_t *alicepub33=0,*bobpub33=0; int32_t x = -1; - if ( strcmp("BTC",swap->req.src) == 0 ) + if ( fread(rawtx,1,sizeof(*rawtx),fp) == sizeof(*rawtx) ) { - swap->bobcoin = iguana_coinfind("BTC"); - swap->bobsatoshis = swap->req.srcamount; - swap->bobconfirms = (1 + sqrt(dstr(swap->bobsatoshis) * .1)); - swap->alicecoin = iguana_coinfind(swap->req.dest); - swap->alicesatoshis = swap->req.destamount; - swap->aliceconfirms = swap->bobconfirms * 3; + rawtx->coin = 0; + rawtx->vins = 0; + if ( strcmp(rawtx->I.coinstr,bobcoinstr) == 0 || strcmp(rawtx->I.coinstr,alicecoinstr) == 0 ) + { + rawtx->coin = iguana_coinfind(rawtx->I.coinstr); + if ( rawtx->vinstr[0] != 0 ) + rawtx->vins = cJSON_Parse(rawtx->vinstr); + printf("loaded.%s len.%d\n",rawtx->name,rawtx->I.datalen); + return(0); + } } - else if ( strcmp("BTC",swap->req.dest) == 0 ) + return(-1); +} + +struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,int32_t reinit) +{ + FILE *fp; char fname[512]; uint8_t *alicepub33=0,*bobpub33=0; int32_t errs=0,jumblrflag,x = -1; + if ( reinit != 0 ) { - swap->bobcoin = iguana_coinfind("BTC"); - swap->bobsatoshis = swap->req.destamount; - swap->bobconfirms = (1 + sqrt(dstr(swap->bobsatoshis) * .1)); - swap->alicecoin = iguana_coinfind(swap->req.src); - swap->alicesatoshis = swap->req.srcamount; - swap->aliceconfirms = swap->bobconfirms * 3; + sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); + printf("reinit.(%s)\n",fname); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + if ( fread(&swap->I,1,sizeof(swap->I),fp) != sizeof(swap->I) ) + errs++; + if ( swap->bobcoin == 0 ) + swap->bobcoin = iguana_coinfind(swap->I.req.dest); + if ( swap->alicecoin == 0 ) + swap->alicecoin = iguana_coinfind(swap->I.req.src); + if ( swap->alicecoin != 0 && swap->bobcoin != 0 ) + { + /*basilisk_swap_loadtx(&swap->bobdeposit,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->bobpayment,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->alicepayment,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->myfee,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->otherfee,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->aliceclaim,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->alicespend,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->bobreclaim,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->bobspend,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->bobrefund,fp,swap->bobcoin->symbol,swap->alicecoin->symbol); + basilisk_swap_loadtx(&swap->alicereclaim,fp,swap->bobcoin->symbol,swap->alicecoin->symbol);*/ + } else printf("missing coins (%p %p)\n",swap->bobcoin,swap->alicecoin); + if ( fread(swap->privkeys,1,sizeof(swap->privkeys),fp) != sizeof(swap->privkeys) ) + errs++; + if ( fread(swap->otherdeck,1,sizeof(swap->otherdeck),fp) != sizeof(swap->otherdeck) ) + errs++; + if ( fread(swap->deck,1,sizeof(swap->deck),fp) != sizeof(swap->deck) ) + errs++; + fclose(fp); + } else printf("cant find.(%s)\n",fname); } else { - if ( (coin= iguana_coinfind(swap->req.src)) != 0 ) + swap->I.putduration = swap->I.callduration = INSTANTDEX_LOCKTIME; + if ( optionduration < 0 ) + swap->I.putduration -= optionduration; + else if ( optionduration > 0 ) + swap->I.callduration += optionduration; + swap->I.bobsatoshis = swap->I.req.destamount; + swap->I.alicesatoshis = swap->I.req.srcamount; + if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < 50000 ) + swap->I.bobinsurance = 50000; + if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < 50000 ) + swap->I.aliceinsurance = 50000; + strcpy(swap->I.bobstr,swap->I.req.dest); + strcpy(swap->I.alicestr,swap->I.req.src); + swap->I.started = (uint32_t)time(NULL); + swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration; + OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei)); + if ( swap->I.choosei < 0 ) + swap->I.choosei = -swap->I.choosei; + swap->I.choosei %= INSTANTDEX_DECKSIZE; + swap->I.otherchoosei = -1; + swap->I.myhash = pubkey25519; + if ( statebits != 0 ) { - if ( coin->chain->havecltv != 0 ) - { - swap->bobcoin = coin; - swap->bobsatoshis = swap->req.srcamount; - swap->alicecoin = iguana_coinfind(swap->req.dest); - swap->alicesatoshis = swap->req.destamount; - } - else if ( (coin= iguana_coinfind(swap->req.dest)) != 0 ) - { - if ( coin->chain->havecltv != 0 ) - { - swap->bobcoin = coin; - swap->bobsatoshis = swap->req.destamount; - swap->alicecoin = iguana_coinfind(swap->req.src); - swap->alicesatoshis = swap->req.srcamount; - } - } + swap->I.iambob = 0; + swap->I.otherhash = swap->I.req.desthash; + } + else + { + swap->I.iambob = 1; + swap->I.otherhash = swap->I.req.srchash; + } + if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(myinfo->ctx,swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE ) + { + char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey)); + return(0); } } + swap->bobcoin = iguana_coinfind(swap->I.req.dest); + swap->alicecoin = iguana_coinfind(swap->I.req.src); if ( swap->bobcoin == 0 || swap->alicecoin == 0 ) { - printf("missing BTC.%p or missing alicecoin.%p\n",swap->bobcoin,swap->alicecoin); + printf("missing bobcoin.%p or missing alicecoin.%p src.%p dest.%p\n",swap->bobcoin,swap->alicecoin,iguana_coinfind(swap->I.req.src),iguana_coinfind(swap->I.req.dest)); free(swap); return(0); } - if ( swap->bobconfirms == 0 ) - swap->bobconfirms = swap->bobcoin->chain->minconfirms; - if ( swap->aliceconfirms == 0 ) - swap->aliceconfirms = swap->alicecoin->chain->minconfirms; - if ( (swap->bobinsurance= (swap->bobsatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) - swap->bobinsurance = 10000; - if ( (swap->aliceinsurance= (swap->alicesatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) - swap->aliceinsurance = 10000; - strcpy(swap->bobstr,swap->bobcoin->symbol); - strcpy(swap->alicestr,swap->alicecoin->symbol); - swap->started = (uint32_t)time(NULL); - swap->expiration = swap->req.timestamp + INSTANTDEX_LOCKTIME*2; - swap->locktime = swap->req.timestamp + INSTANTDEX_LOCKTIME; - OS_randombytes((uint8_t *)&swap->choosei,sizeof(swap->choosei)); - if ( swap->choosei < 0 ) - swap->choosei = -swap->choosei; - swap->choosei %= INSTANTDEX_DECKSIZE; - swap->otherchoosei = -1; - swap->myhash = myinfo->myaddr.persistent; - if ( bits256_cmp(swap->myhash,swap->req.hash) == 0 ) - { - swap->otherhash = swap->req.desthash; - if ( strcmp(swap->req.src,swap->bobstr) == 0 ) - swap->iambob = 1; - else if ( strcmp(swap->req.dest,swap->alicestr) == 0 ) - { - printf("neither bob nor alice error\n"); - return(0); - } - } - else if ( bits256_cmp(swap->myhash,swap->req.desthash) == 0 ) + if ( strcmp("BTC",swap->bobcoin->symbol) == 0 ) { - swap->otherhash = swap->req.hash; - if ( strcmp(swap->req.dest,swap->bobstr) == 0 ) - swap->iambob = 1; - else if ( strcmp(swap->req.src,swap->alicestr) != 0 ) - { - printf("neither alice nor bob error\n"); - return(0); - } + swap->I.bobconfirms = (1*0 + sqrt(dstr(swap->I.bobsatoshis) * .1)); + swap->I.aliceconfirms = MIN(BASILISK_DEFAULT_NUMCONFIRMS,swap->I.bobconfirms * 3); } - else + else if ( strcmp("BTC",swap->alicecoin->symbol) == 0 ) { - printf("neither src nor dest error\n"); - return(0); + swap->I.aliceconfirms = (1*0 + sqrt(dstr(swap->I.alicesatoshis) * .1)); + swap->I.bobconfirms = MIN(BASILISK_DEFAULT_NUMCONFIRMS,swap->I.bobconfirms * 3); } - if ( bits256_nonz(myinfo->persistent_priv) == 0 || (x= instantdex_pubkeyargs(myinfo,swap,2 + INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->myhash,0x02+swap->iambob)) != 2 + INSTANTDEX_DECKSIZE ) + else { - printf("couldnt generate privkeys %d\n",x); - return(0); + swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; } - if ( swap->iambob != 0 ) + /*if ( swap->I.bobconfirms == 0 ) + swap->I.bobconfirms = swap->bobcoin->chain->minconfirms; + if ( swap->I.aliceconfirms == 0 ) + swap->I.aliceconfirms = swap->alicecoin->chain->minconfirms;*/ + jumblrflag = (bits256_cmp(pubkey25519,myinfo->jumblr_pubkey) == 0 || bits256_cmp(pubkey25519,myinfo->jumblr_depositkey) == 0); + printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< use smart address, %.8f bobconfs.%d, %.8f aliceconfs.%d\n",jumblrflag,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms); + if ( swap->I.iambob != 0 ) { - basilisk_rawtx_setparms("myfee",myinfo,swap,&swap->myfee,swap->bobcoin,0,0,swap->bobsatoshis/INSTANTDEX_DECKSIZE,0,0); - basilisk_rawtx_setparms("otherfee",myinfo,swap,&swap->otherfee,swap->alicecoin,0,0,swap->alicesatoshis/INSTANTDEX_DECKSIZE,0,0); - bobpub33 = myinfo->persistent_pubkey33; + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_INSURANCEDIV,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_INSURANCEDIV,0,0,jumblrflag); + bobpub33 = pubkey33; } else { - basilisk_rawtx_setparms("otherfee",myinfo,swap,&swap->otherfee,swap->bobcoin,0,0,swap->bobsatoshis/INSTANTDEX_DECKSIZE,0,0); - basilisk_rawtx_setparms("myfee",myinfo,swap,&swap->myfee,swap->alicecoin,0,0,swap->alicesatoshis/INSTANTDEX_DECKSIZE,0,0); - alicepub33 = myinfo->persistent_pubkey33; - } - basilisk_rawtx_setparms("bobdeposit",myinfo,swap,&swap->bobdeposit,swap->bobcoin,swap->bobconfirms,0,swap->bobsatoshis*1.1,4,0); - basilisk_rawtx_setparms("bobrefund",myinfo,swap,&swap->bobrefund,swap->bobcoin,1,4,swap->bobsatoshis*1.1-swap->bobcoin->txfee,1,bobpub33); - swap->bobrefund.suppress_pubkeys = 1; - basilisk_rawtx_setparms("aliceclaim",myinfo,swap,&swap->aliceclaim,swap->bobcoin,1,4,swap->bobsatoshis*1.1-swap->bobcoin->txfee,1,alicepub33); - swap->aliceclaim.suppress_pubkeys = 1; - - basilisk_rawtx_setparms("bobpayment",myinfo,swap,&swap->bobpayment,swap->bobcoin,swap->bobconfirms,0,swap->bobsatoshis,3,0); - basilisk_rawtx_setparms("alicespend",myinfo,swap,&swap->alicespend,swap->bobcoin,swap->bobconfirms,3,swap->bobsatoshis - swap->bobcoin->txfee,1,alicepub33); - swap->alicespend.suppress_pubkeys = 1; - basilisk_rawtx_setparms("bobreclaim",myinfo,swap,&swap->bobreclaim,swap->bobcoin,swap->bobconfirms,3,swap->bobsatoshis - swap->bobcoin->txfee,1,bobpub33); - swap->bobreclaim.suppress_pubkeys = 1; - - basilisk_rawtx_setparms("alicepayment",myinfo,swap,&swap->alicepayment,swap->alicecoin,swap->aliceconfirms,0,swap->alicesatoshis,2,0); - basilisk_rawtx_setparms("bobspend",myinfo,swap,&swap->bobspend,swap->alicecoin,swap->aliceconfirms,2,swap->alicesatoshis-swap->alicecoin->txfee,1,bobpub33); - swap->bobspend.suppress_pubkeys = 1; - basilisk_rawtx_setparms("alicereclaim",myinfo,swap,&swap->alicereclaim,swap->alicecoin,swap->aliceconfirms,2,swap->alicesatoshis-swap->alicecoin->txfee,1,alicepub33); - swap->alicereclaim.suppress_pubkeys = 1; + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,swap->bobcoin,0,0,swap->I.bobsatoshis/INSTANTDEX_INSURANCEDIV,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,swap->alicecoin,0,0,swap->I.alicesatoshis/INSTANTDEX_INSURANCEDIV,0,0,jumblrflag); + alicepub33 = pubkey33; + } + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3) + swap->bobcoin->txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,swap->bobcoin,1,4,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3),1,bobpub33,jumblrflag); + swap->bobrefund.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,swap->bobcoin,1,4,swap->I.bobsatoshis + (swap->I.bobsatoshis>>3),1,alicepub33,jumblrflag); + swap->aliceclaim.I.suppress_pubkeys = 1; + swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; + + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,swap->bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + swap->bobcoin->txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); + swap->alicespend.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,swap->bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); + swap->bobreclaim.I.suppress_pubkeys = 1; + swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,swap->alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis+swap->alicecoin->txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); + swap->bobspend.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,swap->alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); + swap->alicereclaim.I.suppress_pubkeys = 1; + printf("IAMBOB.%d\n",swap->I.iambob); + return(swap); } // end of alice/bob code void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) { - if ( rawtx->txbytes != 0 ) - free(rawtx->txbytes), rawtx->txbytes = 0; + if ( rawtx->vins != 0 ) + free_json(rawtx->vins); + //if ( rawtx->txbytes != 0 ) + // free(rawtx->txbytes), rawtx->txbytes = 0; } void basilisk_swap_finished(struct supernet_info *myinfo,struct basilisk_swap *swap) { - swap->finished = (uint32_t)time(NULL); + int32_t i; + swap->I.finished = (uint32_t)time(NULL); // save to permanent storage basilisk_rawtx_purge(&swap->bobdeposit); basilisk_rawtx_purge(&swap->bobpayment); basilisk_rawtx_purge(&swap->alicepayment); basilisk_rawtx_purge(&swap->myfee); basilisk_rawtx_purge(&swap->otherfee); - basilisk_rawtx_purge(&swap->alicereclaim); + basilisk_rawtx_purge(&swap->aliceclaim); basilisk_rawtx_purge(&swap->alicespend); basilisk_rawtx_purge(&swap->bobreclaim); basilisk_rawtx_purge(&swap->bobspend); basilisk_rawtx_purge(&swap->bobrefund); + basilisk_rawtx_purge(&swap->alicereclaim); + for (i=0; inummessages; i++) + if ( swap->messages[i].data != 0 ) + free(swap->messages[i].data), swap->messages[i].data = 0; + free(swap->messages), swap->messages = 0; + swap->nummessages = 0; } void basilisk_swap_purge(struct supernet_info *myinfo,struct basilisk_swap *swap) { int32_t i,n; // while still in orderbook, wait - return; + //return; portable_mutex_lock(&myinfo->DEX_swapmutex); n = myinfo->numswaps; for (i=0; iotherstatebits) ) - return(iguana_rwnum(0,data,sizeof(swap->otherstatebits),&swap->otherstatebits)); - else return(-1); + int32_t retval; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(swap->I.otherstatebits) ) + { + retval = iguana_rwnum(0,data,sizeof(swap->I.otherstatebits),&swap->I.otherstatebits); + return(retval); + } else return(-1); } - -int32_t basilisk_verify_choosei(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) + +int32_t basilisk_verify_statebits(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { - int32_t otherchoosei=-1,i,len = 0; struct basilisk_swap *swap = ptr; - if ( datalen == sizeof(otherchoosei)+sizeof(bits256)*2 ) + int32_t retval = -1; uint32_t statebits; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(swap->I.statebits) ) { - len += iguana_rwnum(0,data,sizeof(otherchoosei),&otherchoosei); - if ( otherchoosei >= 0 && otherchoosei < INSTANTDEX_DECKSIZE ) + retval = iguana_rwnum(0,data,sizeof(swap->I.statebits),&statebits); + if ( statebits != swap->I.statebits ) { - printf("otherchoosei.%d\n",otherchoosei); - swap->otherchoosei = otherchoosei; - if ( swap->iambob != 0 ) - { + printf("statebits.%x != %x\n",statebits,swap->I.statebits); + return(-1); + } + } + return(retval); +} + +int32_t basilisk_verify_choosei(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t otherchoosei=-1,i,len = 0; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(otherchoosei)+sizeof(bits256)*2 ) + { + len += iguana_rwnum(0,data,sizeof(otherchoosei),&otherchoosei); + if ( otherchoosei >= 0 && otherchoosei < INSTANTDEX_DECKSIZE ) + { + //printf("otherchoosei.%d\n",otherchoosei); + swap->I.otherchoosei = otherchoosei; + if ( swap->I.iambob != 0 ) + { for (i=0; i<32; i++) - swap->pubA0.bytes[i] = data[len++]; + swap->I.pubA0.bytes[i] = data[len++]; for (i=0; i<32; i++) - swap->pubA1.bytes[i] = data[len++]; - char str[65]; printf("GOT pubA0/1 %s\n",bits256_str(str,swap->pubA0)); + swap->I.pubA1.bytes[i] = data[len++]; + char str[65]; printf("GOT pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); } else { for (i=0; i<32; i++) - swap->pubB0.bytes[i] = data[len++]; + swap->I.pubB0.bytes[i] = data[len++]; for (i=0; i<32; i++) - swap->pubB1.bytes[i] = data[len++]; + swap->I.pubB1.bytes[i] = data[len++]; } return(0); } @@ -915,62 +1959,91 @@ int32_t basilisk_verify_otherdeck(struct supernet_info *myinfo,void *ptr,uint8_t int32_t basilisk_verify_privkeys(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) { int32_t i,j,wrongfirstbyte=0,errs=0,len = 0; bits256 otherpriv,pubi; uint8_t secret160[20],otherpubkey[33]; uint64_t txid; struct basilisk_swap *swap = ptr; - printf("verify privkeys choosei.%d otherchoosei.%d datalen.%d vs %d\n",swap->choosei,swap->otherchoosei,datalen,(int32_t)sizeof(swap->privkeys)+20+32); - if ( swap->cutverified == 0 && swap->otherchoosei >= 0 && datalen == sizeof(swap->privkeys)+20+32 ) + //printf("verify privkeys choosei.%d otherchoosei.%d datalen.%d vs %d\n",swap->choosei,swap->otherchoosei,datalen,(int32_t)sizeof(swap->privkeys)+20+32); + memset(otherpriv.bytes,0,sizeof(otherpriv)); + if ( swap->I.cutverified == 0 && swap->I.otherchoosei >= 0 && datalen == sizeof(swap->privkeys)+20+2*32 ) { for (i=errs=0; iprivkeys)/sizeof(*swap->privkeys); i++) { for (j=0; j<32; j++) otherpriv.bytes[j] = data[len++]; - if ( i != swap->choosei ) + if ( i != swap->I.choosei ) { pubi = bitcoin_pubkey33(myinfo->ctx,otherpubkey,otherpriv); - calc_rmd160_sha256(secret160,otherpriv.bytes,sizeof(otherpriv)); + revcalc_rmd160_sha256(secret160,otherpriv);//.bytes,sizeof(otherpriv)); memcpy(&txid,secret160,sizeof(txid)); errs += basilisk_verify_pubpair(&wrongfirstbyte,swap,i,otherpubkey[0],pubi,txid); } } if ( errs == 0 && wrongfirstbyte == 0 ) { - swap->cutverified = 1, printf("CUT VERIFIED\n"); - if ( swap->iambob != 0 ) + swap->I.cutverified = 1, printf("CUT VERIFIED\n"); + if ( swap->I.iambob != 0 ) { for (i=0; i<32; i++) - swap->pubAm.bytes[i] = data[len++]; + swap->I.pubAm.bytes[i] = data[len++]; for (i=0; i<20; i++) - swap->secretAm[i] = data[len++]; + swap->I.secretAm[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.secretAm256[i] = data[len++]; + basilisk_bobscripts_set(myinfo,swap,1,1); } else { for (i=0; i<32; i++) - swap->pubBn.bytes[i] = data[len++]; + swap->I.pubBn.bytes[i] = data[len++]; for (i=0; i<20; i++) - swap->secretBn[i] = data[len++]; + swap->I.secretBn[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.secretBn256[i] = data[len++]; + //basilisk_bobscripts_set(myinfo,swap,0); } } else printf("failed verification: wrong firstbyte.%d errs.%d\n",wrongfirstbyte,errs); } - printf("privkeys errs.%d wrongfirstbyte.%d\n",errs,wrongfirstbyte); + //printf("privkeys errs.%d wrongfirstbyte.%d\n",errs,wrongfirstbyte); return(errs); } -uint32_t basilisk_swapsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits) -{ - if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,msgbits,data,datalen,INSTANTDEX_LOCKTIME*2) == 0 ) - return(nextbits); - printf("ERROR basilisk_channelsend\n"); - return(0); -} - -uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits) +uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend) { + uint8_t sendbuf[32768]; int32_t sendlen; if ( basilisk_swapdata_rawtx(myinfo,swap,data,maxlen,rawtx) != 0 ) { - rawtx->actualtxid = basilisk_swap_broadcast(rawtx->name,myinfo,swap,rawtx->coin,rawtx->txbytes,rawtx->datalen); - char str[65],str2[65]; printf("rawtxsend %s vs %s\n",bits256_str(str,rawtx->signedtxid),bits256_str(str2,rawtx->actualtxid)); - if ( bits256_nonz(rawtx->actualtxid) != 0 && msgbits != 0 ) - return(basilisk_swapsend(myinfo,swap,msgbits,rawtx->txbytes,rawtx->datalen,nextbits)); - else return(nextbits); - } else printf("error from basilisk_swapdata_rawtx %p len.%d\n",rawtx->txbytes,rawtx->datalen); + if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) + { + char str[65],str2[65]; + rawtx->I.actualtxid = basilisk_swap_broadcast(rawtx->name,myinfo,swap,rawtx->coin,rawtx->txbytes,rawtx->I.datalen); + if ( bits256_cmp(rawtx->I.actualtxid,rawtx->I.signedtxid) != 0 ) + { + printf("%s rawtxsend %s vs %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),bits256_str(str2,rawtx->I.actualtxid)); + rawtx->I.actualtxid = rawtx->I.signedtxid; + } + if ( bits256_nonz(rawtx->I.actualtxid) != 0 && msgbits != 0 ) + { + sendlen = 0; + sendbuf[sendlen++] = rawtx->I.datalen & 0xff; + sendbuf[sendlen++] = (rawtx->I.datalen >> 8) & 0xff; + sendbuf[sendlen++] = rawtx->I.redeemlen; + memcpy(&sendbuf[sendlen],rawtx->txbytes,rawtx->I.datalen), sendlen += rawtx->I.datalen; + if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 ) + { + memcpy(&sendbuf[sendlen],rawtx->redeemscript,rawtx->I.redeemlen); + sendlen += rawtx->I.redeemlen; + } + basilisk_dontforget_update(myinfo,swap,rawtx); + //printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen); + if ( suppress_swapsend == 0 ) + return(basilisk_swapsend(myinfo,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs)); + else + { + printf("suppress swapsend %x\n",msgbits); + return(0); + } + } + } + return(nextbits); + } else if ( swap->I.iambob == 0 ) + printf("error from basilisk_swapdata_rawtx.%s %p len.%d\n",rawtx->name,rawtx->txbytes,rawtx->I.datalen); return(0); } @@ -979,78 +2052,84 @@ void basilisk_sendpubkeys(struct supernet_info *myinfo,struct basilisk_swap *swa int32_t datalen; datalen = basilisk_swapdata_deck(myinfo,swap,data,maxlen); printf("send deck.%d\n",datalen); - swap->statebits |= basilisk_swapsend(myinfo,swap,0x02,data,datalen,0x01); + swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x02,data,datalen,0x01,swap->I.crcs_mypub); } -void basilisk_checkdeck(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +int32_t basilisk_checkdeck(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - if ( (swap->statebits & 0x02) == 0 ) + if ( (swap->I.statebits & 0x02) == 0 ) { - printf("check for other deck\n"); + //printf("check for other deck\n"); if ( basilisk_swapget(myinfo,swap,0x02,data,maxlen,basilisk_verify_otherdeck) == 0 ) - swap->statebits |= 0x02; + swap->I.statebits |= 0x02; + else return(-1); } + return(0); } void basilisk_sendstate(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - int32_t datalen; - datalen = iguana_rwnum(1,data,sizeof(swap->statebits),&swap->statebits); - basilisk_swapsend(myinfo,swap,0x80000000,data,datalen,0); + int32_t datalen=0; + datalen = iguana_rwnum(1,data,sizeof(swap->I.statebits),&swap->I.statebits); + basilisk_swapsend(myinfo,swap,0x80000000,data,datalen,0,0); } void basilisk_sendchoosei(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { int32_t i,datalen; char str[65]; - datalen = iguana_rwnum(1,data,sizeof(swap->choosei),&swap->choosei); - if ( swap->iambob != 0 ) + datalen = iguana_rwnum(1,data,sizeof(swap->I.choosei),&swap->I.choosei); + if ( swap->I.iambob != 0 ) { for (i=0; i<32; i++) - data[datalen++] = swap->pubB0.bytes[i]; + data[datalen++] = swap->I.pubB0.bytes[i]; for (i=0; i<32; i++) - data[datalen++] = swap->pubB1.bytes[i]; - printf("SEND pubB0/1 %s\n",bits256_str(str,swap->pubB0)); + data[datalen++] = swap->I.pubB1.bytes[i]; + printf("SEND pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); } else { for (i=0; i<32; i++) - data[datalen++] = swap->pubA0.bytes[i]; + data[datalen++] = swap->I.pubA0.bytes[i]; for (i=0; i<32; i++) - data[datalen++] = swap->pubA1.bytes[i]; - printf("SEND pubA0/1 %s\n",bits256_str(str,swap->pubA0)); + data[datalen++] = swap->I.pubA1.bytes[i]; + printf("SEND pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); } - swap->statebits |= basilisk_swapsend(myinfo,swap,0x08,data,datalen,0x04); + swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x08,data,datalen,0x04,swap->I.crcs_mychoosei); } void basilisk_waitchoosei(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - uint8_t pubkey33[33]; char str[65]; - printf("check otherchoosei\n"); + uint8_t pubkey33[33]; char str[65],str2[65]; + //printf("check otherchoosei\n"); if ( basilisk_swapget(myinfo,swap,0x08,data,maxlen,basilisk_verify_choosei) == 0 ) { - if ( swap->iambob != 0 ) + if ( swap->I.iambob != 0 ) { - if ( bits256_nonz(swap->privBn) == 0 ) + if ( bits256_nonz(swap->I.privBn) == 0 ) { - swap->privBn = swap->privkeys[swap->otherchoosei]; - memset(&swap->privkeys[swap->otherchoosei],0,sizeof(swap->privkeys[swap->otherchoosei])); - calc_rmd160_sha256(swap->secretBn,swap->privBn.bytes,sizeof(swap->privBn)); - swap->pubBn = bitcoin_pubkey33(myinfo->ctx,pubkey33,swap->privBn); - printf("set privBn.%s\n",bits256_str(str,swap->privBn)); - } + swap->I.privBn = swap->privkeys[swap->I.otherchoosei]; + memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei])); + revcalc_rmd160_sha256(swap->I.secretBn,swap->I.privBn);//.bytes,sizeof(swap->privBn)); + vcalc_sha256(0,swap->I.secretBn256,swap->I.privBn.bytes,sizeof(swap->I.privBn)); + swap->I.pubBn = bitcoin_pubkey33(myinfo->ctx,pubkey33,swap->I.privBn); + printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); + basilisk_bobscripts_set(myinfo,swap,1,1); + } } else { - if ( bits256_nonz(swap->privAm) == 0 ) + if ( bits256_nonz(swap->I.privAm) == 0 ) { - swap->privAm = swap->privkeys[swap->otherchoosei]; - memset(&swap->privkeys[swap->otherchoosei],0,sizeof(swap->privkeys[swap->otherchoosei])); - calc_rmd160_sha256(swap->secretAm,swap->privAm.bytes,sizeof(swap->privAm)); - swap->pubAm = bitcoin_pubkey33(myinfo->ctx,pubkey33,swap->privAm); - printf("set privAm.%s\n",bits256_str(str,swap->privAm)); + swap->I.privAm = swap->privkeys[swap->I.otherchoosei]; + memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei])); + revcalc_rmd160_sha256(swap->I.secretAm,swap->I.privAm);//.bytes,sizeof(swap->privAm)); + vcalc_sha256(0,swap->I.secretAm256,swap->I.privAm.bytes,sizeof(swap->I.privAm)); + swap->I.pubAm = bitcoin_pubkey33(myinfo->ctx,pubkey33,swap->I.privAm); + char str[65],str2[65]; printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); + //basilisk_bobscripts_set(myinfo,swap,0); } } - swap->statebits |= 0x08; + swap->I.statebits |= 0x08; } } @@ -1061,379 +2140,1898 @@ void basilisk_sendmostprivs(struct supernet_info *myinfo,struct basilisk_swap *s for (i=0; iprivkeys)/sizeof(*swap->privkeys); i++) { for (j=0; j<32; j++) - data[datalen++] = (i == swap->otherchoosei) ? 0 : swap->privkeys[i].bytes[j]; + data[datalen++] = (i == swap->I.otherchoosei) ? 0 : swap->privkeys[i].bytes[j]; } - if ( swap->iambob != 0 ) + if ( swap->I.iambob != 0 ) { for (i=0; i<32; i++) - data[datalen++] = swap->pubBn.bytes[i]; + data[datalen++] = swap->I.pubBn.bytes[i]; for (i=0; i<20; i++) - data[datalen++] = swap->secretBn[i]; + data[datalen++] = swap->I.secretBn[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.secretBn256[i]; } else { for (i=0; i<32; i++) - data[datalen++] = swap->pubAm.bytes[i]; + data[datalen++] = swap->I.pubAm.bytes[i]; for (i=0; i<20; i++) - data[datalen++] = swap->secretAm[i]; + data[datalen++] = swap->I.secretAm[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.secretAm256[i]; } - printf("send privkeys.%d\n",datalen); - swap->statebits |= basilisk_swapsend(myinfo,swap,0x20,data,datalen,0x10); -} - -void basilisk_alicepayment(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn) -{ - alicepayment->spendlen = basilisk_alicescript(alicepayment->redeemscript,&alicepayment->redeemlen,alicepayment->spendscript,0,alicepayment->destaddr,coin->chain->p2shtype,pubAm,pubBn); - basilisk_rawtx_gen("alicepayment",myinfo,0,1,alicepayment,alicepayment->locktime,alicepayment->spendscript,alicepayment->spendlen,coin->chain->txfee,1); + //printf("send privkeys.%d\n",datalen); + swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x20,data,datalen,0x10,swap->I.crcs_myprivs); } -// detect insufficient funds/inputs -// mode to autocreate required outputs - -void basilisk_swaploop(void *_swap) +int32_t basilisk_swapiteration(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - uint8_t *data; uint32_t expiration; int32_t retval=0,i,j,maxlen,datalen; struct supernet_info *myinfo; struct basilisk_swap *swap = _swap; - myinfo = swap->myinfo; - fprintf(stderr,"start swap\n"); - maxlen = 1024*1024 + sizeof(*swap); - data = malloc(maxlen); - expiration = (uint32_t)time(NULL) + 300; - while ( time(NULL) < expiration ) - { - printf("A r%u/q%u swapstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits); - basilisk_sendpubkeys(myinfo,swap,data,maxlen); // send pubkeys - basilisk_checkdeck(myinfo,swap,data,maxlen); // check for other deck 0x02 - //if ( (swap->statebits & 0x02) != 0 ) - basilisk_sendchoosei(myinfo,swap,data,maxlen); - basilisk_waitchoosei(myinfo,swap,data,maxlen); // wait for choosei 0x08 - if ( (swap->statebits & (0x08|0x02)) == (0x08|0x02) ) - break; - sleep(3); - } - while ( time(NULL) < expiration ) - { - printf("B r%u/q%u swapstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits); - basilisk_sendmostprivs(myinfo,swap,data,maxlen); - if ( basilisk_swapget(myinfo,swap,0x20,data,maxlen,basilisk_verify_privkeys) == 0 ) - { - swap->statebits |= 0x20; - break; - } - sleep(3 + (swap->iambob == 0)*10); - } - if ( time(NULL) >= expiration ) - retval = -1; - printf("C r%u/q%u swapstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits); - if ( retval == 0 && (swap->statebits & 0x40) == 0 ) // send fee - { - basilisk_sendstate(myinfo,swap,data,maxlen); - basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); - if ( swap->myfee.txbytes == 0 ) - { - for (i=0; i<20; i++) - printf("%02x",swap->secretAm[i]); - printf(" <- secretAm\n"); - for (i=0; i<32; i++) - printf("%02x",swap->pubAm.bytes[i]); - printf(" <- pubAm\n"); - for (i=0; i<20; i++) - printf("%02x",swap->secretBn[i]); - printf(" <- secretBn\n"); - for (i=0; i<32; i++) - printf("%02x",swap->pubBn.bytes[i]); - printf(" <- pubBn\n"); - for (i=0; i<32; i++) - printf("%02x",swap->pubA0.bytes[i]); - printf(" <- pubA0\n"); - for (i=0; i<32; i++) - printf("%02x",swap->pubA1.bytes[i]); - printf(" <- pubA1\n"); - for (i=0; i<32; i++) - printf("%02x",swap->pubB0.bytes[i]); - printf(" <- pubB0\n"); - for (i=0; i<32; i++) - printf("%02x",swap->pubB1.bytes[i]); - printf(" <- pubB1\n"); - swap->bobpayment.spendlen = basilisk_bobscript(swap->bobpayment.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.locktime,&swap->bobpayment.secretstart,swap,0); - swap->bobdeposit.spendlen = basilisk_bobscript(swap->bobdeposit.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.locktime,&swap->bobdeposit.secretstart,swap,1); - for (i=0; ibobpayment.redeemlen; i++) - printf("%02x",swap->bobpayment.redeemscript[i]); - printf(" <- bobpayment.%d\n",i); - for (i=0; ibobdeposit.redeemlen; i++) - printf("%02x",swap->bobdeposit.redeemscript[i]); - printf(" <- bobdeposit.%d\n",i); - if ( swap->iambob != 0 ) - { - basilisk_rawtx_gen("deposit",myinfo,1,1,&swap->bobdeposit,swap->bobdeposit.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.spendlen,swap->bobdeposit.coin->chain->txfee,1); - basilisk_rawtx_gen("payment",myinfo,1,1,&swap->bobpayment,swap->bobpayment.locktime,swap->bobpayment.spendscript,swap->bobpayment.spendlen,swap->bobpayment.coin->chain->txfee,1); - if ( swap->bobdeposit.txbytes == 0 || swap->bobdeposit.spendlen == 0 || swap->bobpayment.txbytes == 0 || swap->bobpayment.spendlen == 0 ) - { - printf("error bob generating deposit.%d or payment.%d\n",swap->bobdeposit.spendlen,swap->bobpayment.spendlen); - retval = -2; - } - /*if ( basilisk_bobpayment_reclaim(myinfo,swap) < 0 || basilisk_bobdeposit_refund(myinfo,swap) < 0 ) - { - printf("error bob reclaiming\n"); - retval = -3; - }*/ - } - else - { - basilisk_alicepayment(myinfo,swap->alicepayment.coin,&swap->alicepayment,swap->pubAm,swap->pubBn); - if ( swap->alicepayment.txbytes == 0 || swap->alicepayment.spendlen == 0 ) - { - printf("error alice generating payment.%d\n",swap->alicepayment.spendlen); - retval = -4; - } - } - if ( basilisk_rawtx_gen("myfee",myinfo,swap->iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.spendlen,swap->myfee.coin->chain->txfee,1) == 0 ) - swap->statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40); - else - { - printf("error creating myfee\n"); - retval = -6; - } - } - } - while ( retval == 0 && time(NULL) < swap->expiration ) + int32_t j,datalen,retval = 0; uint32_t savestatebits=0,saveotherbits=0; + if ( swap->I.iambob != 0 ) + swap->I.statebits |= 0x80; + while ( swap->aborted == 0 && ((swap->I.otherstatebits & 0x80) == 0 || (swap->I.statebits & 0x80) == 0) && retval == 0 && time(NULL) < swap->I.expiration ) { - printf("D r%u/q%u swapstate.%x otherstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits,swap->otherstatebits); - if ( (swap->statebits & 0x80) == 0 ) // wait for fee + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); + printf("D r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); + if ( swap->I.iambob != 0 && (swap->I.statebits & 0x80) == 0 ) // wait for fee { if ( basilisk_swapget(myinfo,swap,0x80,data,maxlen,basilisk_verify_otherfee) == 0 ) { // verify and submit otherfee - swap->statebits |= 0x80; + swap->I.statebits |= 0x80; basilisk_sendstate(myinfo,swap,data,maxlen); } } + else if ( swap->I.iambob == 0 ) + swap->I.statebits |= 0x80; basilisk_sendstate(myinfo,swap,data,maxlen); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); - if ( (swap->otherstatebits & 0x80) != 0 && (swap->statebits & 0x80) != 0 ) + if ( (swap->I.otherstatebits & 0x80) != 0 && (swap->I.statebits & 0x80) != 0 ) break; - sleep(3 + (swap->iambob == 0)*10); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); basilisk_sendstate(myinfo,swap,data,maxlen); - if ( (swap->otherstatebits & 0x80) == 0 ) - basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40); + if ( (swap->I.otherstatebits & 0x80) == 0 ) + basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40,0); } - while ( retval == 0 && time(NULL) < swap->expiration ) // both sides have setup required data and paid txfee + basilisk_swap_saveupdate(myinfo,swap); + while ( swap->aborted == 0 && retval == 0 && time(NULL) < swap->I.expiration ) // both sides have setup required data and paid txfee { - printf("E r%u/q%u swapstate.%x otherstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits,swap->otherstatebits); - if ( swap->iambob != 0 ) + basilisk_swap_saveupdate(myinfo,swap); + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); + //if ( (rand() % 30) == 0 ) + printf("E r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); + if ( swap->I.iambob != 0 ) { - printf("BOB\n"); - if ( (swap->statebits & 0x100) == 0 ) + //printf("BOB\n"); + if ( (swap->I.statebits & 0x100) == 0 ) { printf("send bobdeposit\n"); - swap->statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x200,data,maxlen,&swap->bobdeposit,0x100); + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0); } // [BLOCKING: altfound] make sure altpayment is confirmed and send payment - else if ( (swap->statebits & 0x1000) == 0 ) + else if ( (swap->I.statebits & 0x1000) == 0 ) { printf("check alicepayment\n"); if ( basilisk_swapget(myinfo,swap,0x1000,data,maxlen,basilisk_verify_alicepaid) == 0 ) { - swap->statebits |= 0x1000; - printf("got alicepayment\n"); + swap->I.statebits |= 0x1000; + printf("got alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); } } - else if ( (swap->statebits & 0x2000) == 0 ) + else if ( (swap->I.statebits & 0x2000) == 0 ) { - if ( basilisk_numconfirms(myinfo,&swap->alicepayment) >= swap->aliceconfirms ) + if ( (swap->I.aliceconfirms == 0 && swap->aliceunconf != 0) || basilisk_numconfirms(myinfo,swap,&swap->alicepayment) >= swap->I.aliceconfirms ) { - swap->statebits |= 0x2000; + swap->I.statebits |= 0x2000; printf("alicepayment confirmed\n"); } } - else if ( (swap->statebits & 0x4000) == 0 ) + else if ( (swap->I.statebits & 0x4000) == 0 ) { + basilisk_bobscripts_set(myinfo,swap,0,1); printf("send bobpayment\n"); - swap->statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000); + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0); } // [BLOCKING: privM] Bob waits for privAm either from Alice or alice blockchain - else if ( (swap->statebits & 0x40000) == 0 ) + else if ( (swap->I.statebits & 0xc0000) != 0xc0000 ) { if ( basilisk_swapget(myinfo,swap,0x40000,data,maxlen,basilisk_verify_privi) == 0 || basilisk_privAm_extract(myinfo,swap) == 0 ) // divulges privAm { - printf("got privi spend alicepayment\n"); - swap->statebits |= 0x40000; + //printf("got privi spend alicepayment, dont divulge privBn until bobspend propagated\n"); basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobspend,0x40000) == 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobspend,0x40000,1) == 0 ) printf("Bob error spending alice payment\n"); else { - basilisk_swap_balancingtrade(myinfo,swap,1); - printf("Bob spends alicepayment\n"); + tradebot_swap_balancingtrade(myinfo,swap,1); + printf("Bob spends alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); + swap->I.statebits |= 0x40000; + if ( basilisk_numconfirms(myinfo,swap,&swap->bobspend) >= swap->I.aliceconfirms ) + { + printf("bobspend confirmed\n"); + swap->I.statebits |= 0x80000; + printf("Bob confirming spend of Alice's payment\n"); + sleep(DEX_SLEEP); + } + retval = 1; } - break; - } - else if ( swap->bobpayment.locktime != 0 && time(NULL) > swap->bobpayment.locktime ) - { - // submit reclaim of payment - printf("bob reclaims bobpayment\n"); - swap->statebits |= (0x40000 | 0x80000); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobreclaim,0) == 0 ) - printf("Bob error reclaiming own payment after alice timed out\n"); - else printf("Bob reclaimed own payment\n"); - break; - } - } - else if ( (swap->statebits & 0x80000) == 0 ) - { - if ( basilisk_numconfirms(myinfo,&swap->bobspend) >= swap->aliceconfirms ) - { - printf("bobspend confirmed\n"); - swap->statebits |= 0x80000 | 0x100000; - printf("Bob confirms spend of Alice's payment\n"); - break; } } - else if ( (swap->statebits & 0x100000) == 0 ) + if ( swap->bobpayment.I.locktime != 0 && time(NULL) > swap->bobpayment.I.locktime ) { - if ( basilisk_numconfirms(myinfo,&swap->bobreclaim) >= 1 ) + // submit reclaim of payment + printf("bob reclaims bobpayment\n"); + swap->I.statebits |= (0x40000 | 0x80000); + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobreclaim,0,0) == 0 ) + printf("Bob error reclaiming own payment after alice timed out\n"); + else { - printf("bobreclaim confirmed\n"); - swap->statebits |= 0x100000; - printf("Bob confirms reclain of payment\n"); - break; + printf("Bob reclaimed own payment\n"); + while ( 0 && (swap->I.statebits & 0x100000) == 0 ) // why wait for own tx? + { + if ( basilisk_numconfirms(myinfo,swap,&swap->bobreclaim) >= 1 ) + { + printf("bobreclaim confirmed\n"); + swap->I.statebits |= 0x100000; + printf("Bob confirms reclain of payment\n"); + break; + } + } + retval = 1; } } } else { - printf("ALICE\n"); + //printf("ALICE\n"); // [BLOCKING: depfound] Alice waits for deposit to confirm and sends altpayment - if ( (swap->statebits & 0x200) == 0 ) + if ( (swap->I.statebits & 0x200) == 0 ) { printf("checkfor deposit\n"); if ( basilisk_swapget(myinfo,swap,0x200,data,maxlen,basilisk_verify_bobdeposit) == 0 ) { // verify deposit and submit, set confirmed height printf("got bobdeposit\n"); - swap->statebits |= 0x200; + swap->I.statebits |= 0x200; } else printf("no valid deposit\n"); } - else if ( (swap->statebits & 0x400) == 0 ) + else if ( (swap->I.statebits & 0x400) == 0 ) { - if ( basilisk_numconfirms(myinfo,&swap->bobdeposit) >= swap->bobconfirms ) + if ( basilisk_istrustedbob(myinfo,swap) != 0 || (swap->I.bobconfirms == 0 && swap->depositunconf != 0) || basilisk_numconfirms(myinfo,swap,&swap->bobdeposit) >= swap->I.bobconfirms ) { printf("bobdeposit confirmed\n"); - swap->statebits |= 0x400; + swap->I.statebits |= 0x400; } } - else if ( (swap->statebits & 0x800) == 0 ) + else if ( (swap->I.statebits & 0x800) == 0 ) { printf("send alicepayment\n"); - swap->statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x1000,data,maxlen,&swap->alicepayment,0x800); + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0); } // [BLOCKING: payfound] make sure payment is confrmed and send in spend or see bob's reclaim and claim - else if ( (swap->statebits & 0x8000) == 0 ) + else if ( (swap->I.statebits & 0x8000) == 0 ) { if ( basilisk_swapget(myinfo,swap,0x8000,data,maxlen,basilisk_verify_bobpaid) == 0 ) { printf("got bobpayment\n"); + tradebot_swap_balancingtrade(myinfo,swap,0); // verify payment and submit, set confirmed height - swap->statebits |= 0x8000; + swap->I.statebits |= 0x8000; } } - else if ( (swap->statebits & 0x10000) == 0 ) + else if ( (swap->I.statebits & 0x10000) == 0 ) { - if ( basilisk_numconfirms(myinfo,&swap->bobpayment) >= swap->bobconfirms ) + if ( basilisk_istrustedbob(myinfo,swap) != 0 || (swap->I.bobconfirms == 0 && swap->paymentunconf != 0) || basilisk_numconfirms(myinfo,swap,&swap->bobpayment) >= swap->I.bobconfirms ) { printf("bobpayment confirmed\n"); - swap->statebits |= 0x10000; + swap->I.statebits |= 0x10000; } } - else if ( (swap->statebits & 0x20000) == 0 ) + else if ( (swap->I.statebits & 0x20000) == 0 ) { printf("alicespend bobpayment\n"); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicespend,0x20000) != 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicespend,0x20000,0) != 0 )//&& (swap->aliceunconf != 0 || basilisk_numconfirms(myinfo,swap,&swap->alicespend) > 0) ) { - // maybe wait for alicespend to be confirmed - for (j=datalen=0; j<32; j++) - data[datalen++] = swap->privAm.bytes[j]; - printf("send privAm\n"); - swap->statebits |= basilisk_swapsend(myinfo,swap,0x40000,data,datalen,0x20000); - basilisk_swap_balancingtrade(myinfo,swap,0); + swap->I.statebits |= 0x20000; } } - else if ( (swap->statebits & 0x40000) == 0 ) + else if ( (swap->I.statebits & 0x40000) == 0 ) { - if ( basilisk_numconfirms(myinfo,&swap->alicespend) >= swap->bobconfirms ) + int32_t numconfs; + if ( (numconfs= basilisk_numconfirms(myinfo,swap,&swap->alicespend)) >= swap->I.bobconfirms ) { - swap->statebits |= 0x40000; + for (j=datalen=0; j<32; j++) + data[datalen++] = swap->I.privAm.bytes[j]; + printf("send privAm %x\n",swap->I.statebits); + swap->I.statebits |= basilisk_swapsend(myinfo,swap,0x40000,data,datalen,0x20000,swap->I.crcs_mypriv); printf("Alice confirms spend of Bob's payment\n"); - break; - } + retval = 1; + } else printf("alicespend numconfs.%d < %d\n",numconfs,swap->I.bobconfirms); } - if ( swap->bobdeposit.locktime != 0 && time(NULL) > swap->bobdeposit.locktime ) + if ( swap->bobdeposit.I.locktime != 0 && time(NULL) > swap->bobdeposit.I.locktime ) { printf("Alice claims deposit\n"); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->aliceclaim,0) == 0 ) + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->aliceclaim,0,0) == 0 ) printf("Alice couldnt claim deposit\n"); - else printf("Alice claimed deposit\n"); - break; + else + { + printf("Alice claimed deposit\n"); + retval = 1; + } } - else if ( basilisk_privBn_extract(myinfo,swap,data,maxlen) == 0 ) + else if ( swap->aborted != 0 || basilisk_privBn_extract(myinfo,swap,data,maxlen) == 0 ) { printf("Alice reclaims her payment\n"); - swap->statebits |= 0x40000000; - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicereclaim,0x40000000) == 0 ) + swap->I.statebits |= 0x40000000; + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicereclaim,0x40000000,0) == 0 ) printf("Alice error sending alicereclaim\n"); - else printf("Alice reclaimed her payment\n"); - break; + else + { + printf("Alice reclaimed her payment\n"); + retval = 1; + } } } - printf("finished swapstate.%x other.%x\n",swap->statebits,swap->otherstatebits); - sleep(3 + (swap->iambob == 0)*10); + if ( (rand() % 30) == 0 ) + printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; basilisk_sendstate(myinfo,swap,data,maxlen); basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); } - printf("end of atomic swap\n"); - if ( swap->iambob != 0 )//&& bits256_nonz(swap->bobdeposit.txid) != 0 ) + return(retval); +} + +int32_t swapcompleted(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + if ( swap->I.iambob != 0 ) + return(swap->I.bobspent); + else return(swap->I.alicespent); +} + +cJSON *swapjson(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + cJSON *retjson = cJSON_CreateObject(); + return(retjson); +} + +void basilisk_psockinit(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t amlp) +{ + char keystr[64],databuf[1024],pubkeystr[128],*retstr,*retstr2,*datastr,*pushaddr=0,*subaddr=0; cJSON *retjson,*addrjson; uint8_t data[512]; int32_t datalen,timeout,pushsock = -1,subsock = -1; + if ( swap->connected == 1 ) + return; + if ( swap->pushsock < 0 && swap->subsock < 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) { - printf("BOB reclaims refund\n"); - basilisk_bobdeposit_refund(myinfo,swap); - if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobrefund,0x40000000) == 0 ) // use secretBn + timeout = 1000; + nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + timeout = 1; + nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + swap->pushsock = pushsock; + swap->subsock = subsock; + } + if ( (subsock= swap->subsock) < 0 || (pushsock= swap->pushsock) < 0 ) + { + printf("error getting nn_sockets\n"); + return; + } + sprintf(keystr,"%08x-%08x",swap->I.req.requestid,swap->I.req.quoteid); + if ( swap->connected == 0 && (retstr= _dex_kvsearch(myinfo,"KV",keystr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - printf("Bob submit error getting refund of deposit\n"); + if ( (datastr= jstr(retjson,"value")) != 0 ) + { + datalen = (int32_t)strlen(datastr) >> 1; + decode_hex((uint8_t *)databuf,datalen,datastr); + if ( (addrjson= cJSON_Parse(databuf)) != 0 ) + { + pushaddr = jstr(addrjson,"push"); + subaddr = jstr(addrjson,"sub"); + if ( pushaddr != 0 && subaddr != 0 ) + { + printf("KV decoded (%s and %s) %d %d\n",pushaddr,subaddr,swap->pushsock,swap->subsock); + if ( nn_connect(swap->pushsock,pushaddr) >= 0 && nn_connect(swap->subsock,subaddr) >= 0 ) + swap->connected = 1; + } + free_json(addrjson); + } + } + free_json(retjson); } - // maybe wait for bobrefund to be confirmed - for (j=datalen=0; j<32; j++) - data[datalen++] = swap->privBn.bytes[j]; - basilisk_swapsend(myinfo,swap,0x40000000,data,datalen,0x40000000); + printf("KVsearch.(%s) -> (%s) connected.%d socks.(%d %d) amlp.%d\n",keystr,retstr,swap->connected,swap->pushsock,swap->subsock,amlp); + free(retstr); + } + printf("connected.%d amlp.%d subsock.%d pushsock.%d\n",swap->connected,amlp,subsock,pushsock); + if ( swap->connected <= 0 && amlp != 0 && subsock >= 0 && pushsock >= 0 ) + { + if ( (retstr= _dex_psock(myinfo,"{}")) != 0 ) + { + printf("psock returns.(%s)\n",retstr); + // {"result":"success","pushaddr":"tcp://5.9.102.210:30002","subaddr":"tcp://5.9.102.210:30003","randipbits":3606291758,"coin":"KMD","tag":"6952562460568228137"} + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + pushaddr = jstr(retjson,"pushaddr"); + subaddr = jstr(retjson,"subaddr"); + if ( pushaddr != 0 && subaddr != 0 ) + { + if ( nn_connect(pushsock,pushaddr) >= 0 ) + { + printf("connected to %d pushaddr.(%s)\n",pushsock,pushaddr); + if ( nn_connect(subsock,subaddr) >= 0 ) + { + swap->connected = 1; + init_hexbytes_noT(pubkeystr,myinfo->persistent_pubkey33,33); + sprintf((char *)data,"{\"push\":\"%s\",\"sub\":\"%s\",\"trade\":[\"%s\", %.8f, \"%s\", %.8f],\"pub\":\"%s\"}",pushaddr,subaddr,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),pubkeystr); + datalen = (int32_t)strlen((char *)data) + 1; + printf("datalen.%d (%s)\n",datalen,(char *)data); + init_hexbytes_noT(databuf,data,datalen); + printf("%s -> %s\n",keystr,databuf); + if ( (retstr2= _dex_kvupdate(myinfo,"KV",keystr,databuf,1)) != 0 ) + { + printf("KVupdate.(%s)\n",retstr2); + free(retstr2); + } + } else printf("nn_connect error to %d subaddr.(%s)\n",subsock,subaddr); + } else printf("nn_connect error to %d pushaddr.(%s)\n",pushsock,pushaddr); + } + else printf("missing addr (%p) (%p) (%s)\n",pushaddr,subaddr,jprint(retjson,0)); + free_json(retjson); + } else printf("Error parsing psock.(%s)\n",retstr); + free(retstr); + } else printf("error issuing _dex_psock\n"); } - printf("%s swap finished statebits %x\n",swap->iambob!=0?"BOB":"ALICE",swap->statebits); - basilisk_swap_purge(myinfo,swap); } -struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,struct basilisk_request *rp) +int32_t basilisk_alicetxs(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) { - int32_t i; struct basilisk_swap *swap = 0; - portable_mutex_lock(&myinfo->DEX_swapmutex); - for (i=0; inumswaps; i++) - if ( myinfo->swaps[i]->req.requestid == rp->requestid ) + int32_t i,retval = -1; + printf("alicetxs\n"); + for (i=0; i<3; i++) + { + if ( swap->alicepayment.I.datalen == 0 ) + basilisk_alicepayment(myinfo,swap,swap->alicepayment.coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); + if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 ) { - printf("basilisk_thread_start error trying to start requestid.%u which is already started\n",rp->requestid); + printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); + sleep(20); + } + else + { + retval = 0; + for (i=0; ialicepayment.I.datalen; i++) + printf("%02x",swap->alicepayment.txbytes[i]); + printf(" ALICE PAYMENT created\n"); + iguana_unspents_mark(myinfo,swap->alicecoin,swap->alicepayment.vins); + basilisk_txlog(myinfo,swap,&swap->alicepayment,-1); break; } - if ( i == myinfo->numswaps && i < sizeof(myinfo->swaps)/sizeof(*myinfo->swaps) ) + } + if ( swap->myfee.I.datalen == 0 ) { - swap = calloc(1,sizeof(*swap)); - swap->req = *rp; - swap->myinfo = myinfo; - printf("START swap requestid.%u\n",rp->requestid); - if ( bitcoin_swapinit(myinfo,swap) != 0 ) + printf("generate fee\n"); + if ( basilisk_rawtx_gen("myfee",myinfo,swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.I.spendlen,swap->myfee.coin->chain->txfee,1,0) == 0 ) + { + swap->I.statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40,0); + iguana_unspents_mark(myinfo,swap->I.iambob!=0?swap->bobcoin:swap->alicecoin,swap->myfee.vins); + basilisk_txlog(myinfo,swap,&swap->myfee,-1); + for (i=0; imyfee.I.spendlen; i++) + printf("%02x",swap->myfee.txbytes[i]); + printf(" fee %p %x\n",swap->myfee.txbytes,swap->I.statebits); + swap->I.statebits |= 0x40; + } + else + { + printf("error creating myfee\n"); + return(-2); + } + } + if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 ) + return(0); + return(-1); +} + +void basilisk_swaploop(void *_swap) +{ + uint8_t *data; uint32_t expiration,savestatebits=0,saveotherbits=0; uint32_t channel; int32_t iters,retval=0,j,datalen,maxlen; struct supernet_info *myinfo; struct basilisk_swap *swap = _swap; + myinfo = swap->myinfoptr; + fprintf(stderr,"start swap\n"); + maxlen = 1024*1024 + sizeof(*swap); + data = malloc(maxlen); + expiration = (uint32_t)time(NULL) + 300; + myinfo->DEXactive = expiration; + channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + while ( swap->aborted == 0 && (swap->I.statebits & (0x08|0x02)) != (0x08|0x02) && time(NULL) < expiration ) + { + dex_channelsend(myinfo,swap->I.req.srchash,swap->I.req.desthash,channel,0x4000000,(void *)&swap->I.req.requestid,sizeof(swap->I.req.requestid)); //,60); + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); + if ( swap->connected > 0 ) + { + printf("A r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); + basilisk_sendstate(myinfo,swap,data,maxlen); + basilisk_sendpubkeys(myinfo,swap,data,maxlen); // send pubkeys + if ( basilisk_checkdeck(myinfo,swap,data,maxlen) == 0) // check for other deck 0x02 + basilisk_sendchoosei(myinfo,swap,data,maxlen); + basilisk_waitchoosei(myinfo,swap,data,maxlen); // wait for choosei 0x08 + if ( (swap->I.statebits & (0x08|0x02)) == (0x08|0x02) ) + break; + } + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + } + if ( swap->connected == 0 ) + { + printf("couldnt establish connection\n"); + retval = -1; + } + while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x20) == 0 ) + { + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); + printf("B r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); + basilisk_sendstate(myinfo,swap,data,maxlen); + basilisk_sendchoosei(myinfo,swap,data,maxlen); + basilisk_sendmostprivs(myinfo,swap,data,maxlen); + if ( basilisk_swapget(myinfo,swap,0x20,data,maxlen,basilisk_verify_privkeys) == 0 ) + { + swap->I.statebits |= 0x20; + break; + } + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + if ( time(NULL) > expiration ) + break; + } + myinfo->DEXactive = swap->I.expiration; + if ( time(NULL) >= expiration ) + { + retval = -1; + myinfo->DEXactive = 0; + } + if ( swap->aborted != 0 ) + { + printf("swap aborted before tx sent\n"); + retval = -1; + } + printf("C r%u/q%u swapstate.%x retval.%d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,retval); + iters = 0; + while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x40) == 0 && iters++ < 10 ) // send fee + { + if ( swap->connected == 0 ) + basilisk_psockinit(myinfo,swap,swap->I.iambob != 0); + //printf("sendstate.%x\n",swap->I.statebits); + basilisk_sendstate(myinfo,swap,data,maxlen); + //printf("swapget\n"); + basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + //printf("after swapget\n"); + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) + { + printf("bobscripts set\n"); + if ( basilisk_bobscripts_set(myinfo,swap,1,1) < 0 ) + { + sleep(DEX_SLEEP); + printf("bobscripts set error\n"); + continue; + } + } + if ( swap->I.iambob == 0 ) { - fprintf(stderr,"launch.%d %d\n",myinfo->numswaps,(int32_t)(sizeof(myinfo->swaps)/sizeof(*myinfo->swaps))); - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) + /*for (i=0; i<20; i++) + printf("%02x",swap->secretAm[i]); + printf(" <- secretAm\n"); + for (i=0; i<32; i++) + printf("%02x",swap->secretAm256[i]); + printf(" <- secretAm256\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubAm.bytes[i]); + printf(" <- pubAm\n"); + for (i=0; i<20; i++) + printf("%02x",swap->secretBn[i]); + printf(" <- secretBn\n"); + for (i=0; i<32; i++) + printf("%02x",swap->secretBn256[i]); + printf(" <- secretBn256\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubBn.bytes[i]); + printf(" <- pubBn\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubA0.bytes[i]); + printf(" <- pubA0\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubA1.bytes[i]); + printf(" <- pubA1\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubB0.bytes[i]); + printf(" <- pubB0\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubB1.bytes[i]); + printf(" <- pubB1\n");*/ + if ( (retval= basilisk_alicetxs(myinfo,swap,data,maxlen)) != 0 ) { - + printf("basilisk_alicetxs error\n"); + break; } - myinfo->swaps[myinfo->numswaps++] = swap; } } - portable_mutex_unlock(&myinfo->DEX_swapmutex); - return(swap); -} + if ( swap->I.iambob == 0 && (swap->I.statebits & 0x40) == 0 ) + { + printf("couldnt send fee\n"); + retval = -8; + } + if ( retval == 0 ) + { + if ( swap->I.iambob == 0 && (swap->myfee.I.datalen == 0 || swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.datalen == 0) ) + { + printf("ALICE's error %d %d %d\n",swap->myfee.I.datalen,swap->alicepayment.I.datalen,swap->alicepayment.I.datalen); + retval = -7; + } + else if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) //swap->bobpayment.I.datalen == 0 + { + printf("BOB's error %d %d %d\n",swap->myfee.I.datalen,swap->bobpayment.I.datalen,swap->bobdeposit.I.datalen); + retval = -7; + } + } + while ( swap->aborted == 0 && retval == 0 && basilisk_swapiteration(myinfo,swap,data,maxlen) == 0 ) + { + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + basilisk_sendstate(myinfo,swap,data,maxlen); + basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + basilisk_swap_saveupdate(myinfo,swap); + if ( time(NULL) > swap->I.expiration ) + break; + } + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen != 0 && bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 ) + { + printf("BOB waiting for confirm state.%x\n",swap->I.statebits); + sleep(60); // wait for confirm/propagation of msig + printf("BOB reclaims refund\n"); + basilisk_bobdeposit_refund(myinfo,swap,0); + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobrefund,0x40000000,0) == 0 ) // use secretBn + { + printf("Bob submit error getting refund of deposit\n"); + } + else + { + // maybe wait for bobrefund to be confirmed + for (j=datalen=0; j<32; j++) + data[datalen++] = swap->I.privBn.bytes[j]; + basilisk_swapsend(myinfo,swap,0x40000000,data,datalen,0x40000000,swap->I.crcs_mypriv); + } + basilisk_swap_saveupdate(myinfo,swap); + } + if ( retval != 0 ) + basilisk_swap_sendabort(myinfo,swap); + printf("end of atomic swap\n"); + if ( swapcompleted(myinfo,swap) > 0 ) // only if swap completed + { + if ( swap->I.iambob != 0 ) + tradebot_pendingadd(myinfo,swapjson(myinfo,swap),swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount)); + else tradebot_pendingadd(myinfo,swapjson(myinfo,swap),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.src,dstr(swap->I.req.srcamount)); + } + printf("%s swap finished statebits %x\n",swap->I.iambob!=0?"BOB":"ALICE",swap->I.statebits); + basilisk_swap_purge(myinfo,swap); + free(data); +} + +cJSON *basilisk_swapjson(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + cJSON *item = cJSON_CreateObject(); + jaddnum(item,"requestid",swap->I.req.requestid); + jaddnum(item,"quoteid",swap->I.req.quoteid); + jaddnum(item,"state",swap->I.statebits); + jaddnum(item,"otherstate",swap->I.otherstatebits); + jadd(item,"request",basilisk_requestjson(&swap->I.req)); + return(item); +} + +struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit) +{ + int32_t i,m,n,iter; uint8_t pubkey33[33]; bits256 pubkey25519; uint32_t channel,starttime; cJSON *retarray,*item,*msgobj; struct iguana_info *coin; double pending=0.; struct basilisk_swap *swap = 0; + // statebits 1 -> client, 0 -> LP + if ( myinfo->numswaps > 0 ) + { + if ( (coin= iguana_coinfind(rp->src)) == 0 || coin->FULLNODE >= 0 ) + { + printf("dont have SRC coin.%s or not native and already swap pending\n",rp->src); + return(0); + } + if ( (coin= iguana_coinfind(rp->dest)) == 0 || coin->FULLNODE >= 0 ) + { + printf("dont have DEST coin.%s or not native and already swap pending\n",rp->dest); + return(0); + } + } + portable_mutex_lock(&myinfo->DEX_swapmutex); + for (i=0; inumswaps; i++) + if ( myinfo->swaps[i]->I.req.requestid == rp->requestid ) + { + printf("basilisk_thread_start error trying to start requestid.%u which is already started\n",rp->requestid); + break; + } + if ( i == myinfo->numswaps && i < sizeof(myinfo->swaps)/sizeof(*myinfo->swaps) ) + { + swap = calloc(1,sizeof(*swap)); + swap->subsock = swap->pushsock = -1; + vcalc_sha256(0,swap->I.orderhash.bytes,(uint8_t *)rp,sizeof(*rp)); + swap->I.req = *rp; + swap->myinfoptr = myinfo; + printf("basilisk_thread_start request.%u statebits.%d (%s/%s) reinit.%d\n",rp->requestid,statebits,rp->src,rp->dest,reinit); + bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); + pubkey25519 = curve25519(privkey,curve25519_basepoint9()); + swap->persistent_pubkey = pubkey25519; + swap->persistent_privkey = privkey; + memcpy(swap->persistent_pubkey33,pubkey33,33); + m = n = 0; + if ( bitcoin_swapinit(myinfo,privkey,pubkey33,pubkey25519,swap,optionduration,statebits,reinit) != 0 ) + { + for (iter=0; iter<16; iter++) + { + basilisk_psockinit(myinfo,swap,statebits == 0); + sleep(3); + if ( swap->connected > 0 ) + break; + sleep(10); + /*basilisk_sendstate(myinfo,swap,data,sizeof(data)); + basilisk_swapget(myinfo,swap,0x80000000,data,sizeof(data),basilisk_verify_statebits); + if ( swap->connected > 0 ) + break; + printf("loopback didntwork with %d %d\n",swap->pushsock,swap->subsock);*/ + } + if ( reinit != 0 ) + { + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) + { + + } + myinfo->swaps[myinfo->numswaps++] = swap; + } + else + { + starttime = (uint32_t)time(NULL); + printf("statebits.%x m.%d n.%d\n",statebits,m,n); + while ( statebits == 0 && m <= n/2 && time(NULL) < starttime+7*BASILISK_MSGDURATION ) + { + uint32_t msgid; uint8_t data[1024]; int32_t datalen; + m = n = 0; + sleep(DEX_SLEEP); + printf("waiting for offer to be accepted\n"); + channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + datalen = basilisk_rwDEXquote(1,data,rp); + msgid = (uint32_t)time(NULL); + printf("other req.%d >>>>>>>>>>> send response (%llx -> %llx) last.%u r.%u quoteid.%u\n",i,(long long)rp->desthash.txid,(long long)rp->srchash.txid,myinfo->lastdexrequestid,rp->requestid,rp->quoteid); + dex_channelsend(myinfo,rp->desthash,rp->srchash,channel,msgid,data,datalen); + if ( (retarray= basilisk_channelget(myinfo,rp->srchash,rp->desthash,channel,0x4000000,30)) != 0 ) + { + if ( is_cJSON_Array(retarray) != 0 && (n= cJSON_GetArraySize(retarray)) > 0 ) + { + for (i=0; i 0 ) + { + item = jitem(msgobj,0); + if ( jobj(item,"data") != 0 && jobj(item,"key") != 0 ) + m++; + else printf("(%s)\n",jprint(item,0)); + } //else printf("msgobj.%p m.%d n.%d\n",msgobj,m,n); + } + } + } else printf("no retarray\n"); + } + printf("LAUNCH check.%d m.%d\n",statebits,m); + if ( statebits != 0 || m > 0 )//n/2 ) + { + //for (i=0; iI.req); i++) + // fprintf(stderr,"%02x",((uint8_t *)&swap->I.req)[i]); + fprintf(stderr," M.%d N.%d launch.%d %d %p reinit.%d\n",m,n,myinfo->numswaps,(int32_t)(sizeof(myinfo->swaps)/sizeof(*myinfo->swaps)),&swap->I.req,reinit); + if ( (swap->fp= basilisk_swap_save(myinfo,swap,privkey,rp,statebits,optionduration,reinit)) != 0 ) + { + } + if ( reinit == 0 ) + { + if ( myinfo->swapsfp == 0 ) + { + char fname[512]; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (myinfo->swapsfp= fopen(fname,"rb+")) == 0 ) + myinfo->swapsfp = fopen(fname,"wb+"); + else fseek(myinfo->swapsfp,0,SEEK_END); + printf("LIST fp.%p\n",myinfo->swapsfp); + } + if ( myinfo->swapsfp != 0 ) + { + fwrite(&rp->requestid,1,sizeof(rp->requestid),myinfo->swapsfp); + fwrite(&rp->quoteid,1,sizeof(rp->quoteid),myinfo->swapsfp); + fflush(myinfo->swapsfp); + } + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) + { + + } + myinfo->swaps[myinfo->numswaps++] = swap; + } + else + { + if ( statebits != 0 ) + { + if ( (coin= iguana_coinfind(rp->src)) != 0 ) + { + + } + } + printf("%u/%u offer wasnt accepted statebits.%d m.%d n.%d pending %.8f\n",rp->requestid,rp->quoteid,statebits,m,n,pending); + } + } + } + } + portable_mutex_unlock(&myinfo->DEX_swapmutex); + return(swap); +} + +/////////////// remember functions + +cJSON *basilisk_nullretjson(cJSON *retjson) +{ + char *outstr; + if ( retjson != 0 ) + { + outstr = jprint(retjson,0); + if ( strcmp(outstr,"{}") == 0 ) + { + free_json(retjson); + retjson = 0; + } + free(outstr); + } + return(retjson); +} + +cJSON *basilisk_swapgettxout(struct supernet_info *myinfo,char *symbol,bits256 trigger,int32_t vout) +{ + char *retstr; cJSON *retjson=0; struct iguana_info *coin; + if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 ) + { + if ( (retstr= dex_gettxout(myinfo,0,0,0,trigger,symbol,vout)) != 0 ) + { + //printf("dexgettxout.(%s)\n",retstr); + retjson = cJSON_Parse(retstr); + free(retstr); + } + if ( 0 && strcmp("BTC",symbol) == 0 ) + printf("%s gettxout.(%s)\n",symbol,jprint(retjson,0)); + } + else + { + retjson = dpow_gettxout(myinfo,coin,trigger,vout); + //printf("need to verify passthru has this info\n"); + //printf("dpowgettxout.(%s)\n",jprint(retjson,0)); + } + return(basilisk_nullretjson(retjson)); +} + +cJSON *basilisk_swapgettx(struct supernet_info *myinfo,char *symbol,bits256 txid) +{ + char *retstr; cJSON *retjson=0; struct iguana_info *coin; + if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 ) + { + if ( (retstr= dex_gettransaction(myinfo,0,0,0,txid,symbol)) != 0 ) + { + retjson = cJSON_Parse(retstr); + free(retstr); + } + //if ( strcmp("BTC",symbol) == 0 ) + // printf("%s gettx.(%s)\n",symbol,jprint(retjson,0)); + } else retjson = dpow_gettransaction(myinfo,coin,txid); + return(basilisk_nullretjson(retjson)); +} + +int32_t basilisk_swap_txdestaddr(char *destaddr,bits256 txid,int32_t vout,cJSON *txobj) +{ + int32_t n,m,retval = -1; cJSON *vouts,*item,*addresses,*skey; char *addr; + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) + { + item = jitem(vouts,vout); + if ( (skey= jobj(item,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) + { + item = jitem(addresses,0); + if ( (addr= jstr(item,0)) != 0 ) + { + safecopy(destaddr,addr,64); + retval = 0; + } + //printf("item.(%s) -> dest.(%s)\n",jprint(item,0),destaddr); + } + } + return(retval); +} + +int32_t basilisk_swap_getcoinaddr(struct supernet_info *myinfo,char *symbol,char *coinaddr,bits256 txid,int32_t vout) +{ + cJSON *retjson; + coinaddr[0] = 0; + if ( (retjson= basilisk_swapgettx(myinfo,symbol,txid)) != 0 ) + { + basilisk_swap_txdestaddr(coinaddr,txid,vout,retjson); + free_json(retjson); + } + return(coinaddr[0] != 0); +} + +int32_t basilisk_swap_getsigscript(struct supernet_info *myinfo,char *symbol,uint8_t *script,int32_t maxlen,bits256 txid,int32_t vini) +{ + cJSON *retjson,*vins,*item,*skey; int32_t n,scriptlen = 0; char *hexstr; + if ( (retjson= basilisk_swapgettx(myinfo,symbol,txid)) != 0 ) + { + if ( (vins= jarray(&n,retjson,"vin")) != 0 && vini < n ) + { + item = jitem(vins,vini); + if ( (skey= jobj(item,"scriptSig")) != 0 && (hexstr= jstr(skey,"hex")) != 0 && (scriptlen= (int32_t)strlen(hexstr)) < maxlen*2 ) + { + scriptlen >>= 1; + decode_hex(script,scriptlen,hexstr); + //char str[65]; printf("%s/v%d sigscript.(%s)\n",bits256_str(str,txid),vini,hexstr); + } + } + free_json(retjson); + } + return(scriptlen); +} + +int64_t basilisk_txvalue(struct supernet_info *myinfo,char *symbol,bits256 txid,int32_t vout) +{ + cJSON *txobj,*vouts,*item; int32_t n; int64_t value = 0; + //char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid)); + if ( (txobj= basilisk_swapgettx(myinfo,symbol,txid)) != 0 ) + { + //printf("txobj.(%s)\n",jprint(txobj,0)); + if ( (vouts= jarray(&n,txobj,"vout")) != 0 ) + { + item = jitem(vouts,vout); + if ( (value= jdouble(item,"amount") * SATOSHIDEN) == 0 ) + value = jdouble(item,"value") * SATOSHIDEN; + } + free_json(txobj); + } + return(value); +} + +bits256 dex_swap_spendtxid(struct supernet_info *myinfo,char *symbol,char *destaddr,char *coinaddr,bits256 utxotxid,int32_t vout) +{ + char *retstr,*addr; cJSON *array,*item,*array2; int32_t i,n,m; bits256 spendtxid,txid; + memset(&spendtxid,0,sizeof(spendtxid)); + if ( (retstr= dex_listtransactions(myinfo,0,0,0,symbol,coinaddr,100,0)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i %s\n",bits256_str(str,spendtxid),destaddr); + break; + } + } + } + } + free_json(array); + } + free(retstr); + } + return(spendtxid); +} + +bits256 basilisk_swap_spendtxid(struct supernet_info *myinfo,char *symbol,char *destaddr,bits256 utxotxid,int32_t vout) +{ + bits256 spendtxid,txid; char *catstr,*addr; cJSON *array,*item,*item2,*txobj,*vins; int32_t i,n,m; char coinaddr[64],str[65]; struct iguana_info *coin = iguana_coinfind(symbol); + // listtransactions or listspents + destaddr[0] = 0; + coinaddr[0] = 0; + memset(&spendtxid,0,sizeof(spendtxid)); + //char str[65]; printf("swap %s spendtxid.(%s)\n",symbol,bits256_str(str,utxotxid)); + if ( (coin == 0 || coin->FULLNODE >= 0) && iguana_isnotarychain(symbol) >= 0 ) + { + //[{"type":"sent","confirmations":379,"height":275311,"timestamp":1492084664,"txid":"8703c5517bc57db38134058370a14e99b8e662b99ccefa2061dea311bbd02b8b","vout":0,"amount":117.50945263,"spendtxid":"cf2509e076fbb9b22514923df916b7aacb1391dce9c7e1460b74947077b12510","vin":0,"paid":{"type":"paid","txid":"cf2509e076fbb9b22514923df916b7aacb1391dce9c7e1460b74947077b12510","height":275663,"timestamp":1492106024,"vouts":[{"RUDpN6PEBsE7ZFbGjUxk1W3QVsxnjBLYw6":117.50935263}]}}] + basilisk_swap_getcoinaddr(myinfo,symbol,coinaddr,utxotxid,vout); + if ( coinaddr[0] != 0 ) + spendtxid = dex_swap_spendtxid(myinfo,symbol,destaddr,coinaddr,utxotxid,vout); + } + else if ( coin != 0 ) + { + if ( (array= dpow_listtransactions(myinfo,coin,destaddr,1000,0)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 ) + { + for (i=0; i jint(item,"vout") ) + { + item2 = jitem(vins,jint(item,"vout")); + if ( bits256_cmp(utxotxid,jbits256(item2,"txid")) == 0 && vout == jint(item2,"vout") ) + { + spendtxid = txid; + break; + } + } + } + } + } + if ( i == n ) + printf("dpowlist: native couldnt find spendtxid for %s\n",bits256_str(str,utxotxid)); + } + free_json(array); + } + if ( bits256_nonz(spendtxid) != 0 ) + return(spendtxid); + } + if ( iguana_isnotarychain(symbol) >= 0 ) + { + basilisk_swap_getcoinaddr(myinfo,symbol,coinaddr,utxotxid,vout); + printf("fallback use DEX for native (%s) (%s)\n",coinaddr,bits256_str(str,utxotxid)); + if ( coinaddr[0] != 0 ) + { + spendtxid = dex_swap_spendtxid(myinfo,symbol,destaddr,coinaddr,utxotxid,vout); + printf("spendtxid.(%s)\n",bits256_str(str,spendtxid)); + } + } + } + return(spendtxid); +} + +bits256 basilisk_swap_sendrawtransaction(struct supernet_info *myinfo,char *txname,char *symbol,char *txbytes) +{ + char *retstr; bits256 txid; int32_t i,sentflag = 0; + memset(&txid,0,sizeof(txid)); + for (i=0; i<3; i++) + { + if ( (retstr= _dex_sendrawtransaction(myinfo,symbol,txbytes)) != 0 ) + { + if ( is_hexstr(retstr,0) == 64 ) + { + decode_hex(txid.bytes,32,retstr); + sentflag = 1; + } + char str[65]; printf("[%s] %s RETSTR.(%s) %s.%s\n",txname,txbytes,retstr,symbol,bits256_str(str,txid)); + free(retstr); + } + if ( sentflag != 0 ) + break; + } + return(txid); +} + +char *basilisk_swap_bobtxspend(char *name,struct supernet_info *myinfo,char *symbol,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t vout,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp) +{ + char *rawtxbytes=0,*signedtx=0,str[65],hexstr[999],wifstr[128],destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *utxoobj,*txobj,*vins,*item,*sobj,*privkeys; int32_t height,completed,spendlen,ignore_cltverr=1,suppress_pubkeys=1; struct vin_info *V; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; struct iguana_info *coin; bits256 txid,signedtxid; uint64_t destamount; + *destamountp = 0; + if ( finalseqid == 0 ) + locktime = expiration; + //printf("bobtxspend.%s redeem.[%d]\n",symbol,redeemlen); + if ( redeemlen < 0 || (coin= iguana_coinfind(symbol)) == 0 ) + return(0); + if ( (utxoobj= basilisk_swapgettxout(myinfo,symbol,utxotxid,vout)) == 0 ) + { + printf("basilisk_swap_bobtxspend.%s utxo already spent or doesnt exist\n",name); + return(0); + } + if ( (destamount= jdouble(utxoobj,"amount")*SATOSHIDEN) == 0 && (destamount= jdouble(utxoobj,"value")*SATOSHIDEN) == 0 ) + { + printf("%s %s basilisk_swap_bobtxspend.%s strange utxo.(%s)\n",symbol,bits256_str(str,utxotxid),name,jprint(utxoobj,0)); + free_json(utxoobj); + return(0); + } else free_json(utxoobj); + *destamountp = destamount; + if ( destamount > 10000 ) + destamount -= 10000; + if ( strcmp(symbol,"BTC") == 0 ) + { + if ( destamount > 40000 ) + destamount -= 40000; + } + height = coin->longestchain; + timestamp = (uint32_t)time(NULL); + V = calloc(256,sizeof(*V)); + privkeys = cJSON_CreateArray(); + if ( privkey2p != 0 ) + { + V[0].signers[1].privkey = *privkey2p; + bitcoin_pubkey33(myinfo->ctx,V[0].signers[1].pubkey,*privkey2p); + bitcoin_priv2wif(wifstr,*privkey2p,coin->chain->wiftype); + jaddistr(privkeys,wifstr); + V[0].N = V[0].M = 2; + } else V[0].N = V[0].M = 1; + V[0].signers[0].privkey = privkey; + bitcoin_pubkey33(myinfo->ctx,V[0].signers[0].pubkey,privkey); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + jaddistr(privkeys,wifstr); + V[0].suppress_pubkeys = suppress_pubkeys; + V[0].ignore_cltverr = ignore_cltverr; + if ( redeemlen != 0 ) + memcpy(V[0].p2shscript,redeemscript,redeemlen), V[0].p2shlen = redeemlen; + txobj = bitcoin_txcreate(coin->symbol,coin->chain->isPoS,locktime,1,timestamp); + vins = cJSON_CreateArray(); + item = cJSON_CreateObject(); + if ( userdata != 0 && userdatalen > 0 ) + { + memcpy(V[0].userdata,userdata,userdatalen); + V[0].userdatalen = userdatalen; + init_hexbytes_noT(hexstr,userdata,userdatalen); + jaddstr(item,"userdata",hexstr); + } + jaddbits256(item,"txid",utxotxid); + jaddnum(item,"vout",vout); + sobj = cJSON_CreateObject(); + bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33); + bitcoin_addr2rmd160(&addrtype,rmd160,destaddr); + /*int32_t i; + for (i=0; i<33; i++) + printf("%02x",pubkey33[i]); + printf(" pubkey33 ->\n"); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" destaddr.(%s)\n",destaddr); + calc_rmd160_sha256(rmd160,pubkey33,33); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- vs direct calc\n");*/ + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + init_hexbytes_noT(hexstr,spendscript,spendlen); + jaddstr(sobj,"hex",hexstr); + jadd(item,"scriptPubKey",sobj); + jaddnum(item,"suppress",suppress_pubkeys); + jaddnum(item,"sequence",sequenceid); + if ( redeemlen != 0 ) + { + init_hexbytes_noT(hexstr,redeemscript,redeemlen); + jaddstr(item,"redeemScript",hexstr); + } + jaddi(vins,item); + jdelete(txobj,"vin"); + jadd(txobj,"vin",vins); + txobj = bitcoin_txoutput(txobj,spendscript,spendlen,destamount); + if ( (rawtxbytes= bitcoin_json2hex(myinfo,coin,&txid,txobj,V)) != 0 ) + { + //printf("locktime.%u sequenceid.%x rawtx.(%s) vins.(%s)\n",locktime,sequenceid,rawtxbytes,jprint(vins,0)); + if ( (signedtx= iguana_signrawtx(myinfo,coin,height,&signedtxid,&completed,vins,rawtxbytes,privkeys,V)) == 0 ) + printf("couldnt sign transaction\n"); + else if ( completed == 0 ) + printf("incomplete signing\n"); + else printf("%s -> %s\n",name,bits256_str(str,signedtxid)); + free(rawtxbytes); + } else printf("error making rawtx\n"); + free_json(privkeys); + free_json(txobj); + free(V); + return(signedtx); +} + +char *basilisk_swap_Aspend(char *name,struct supernet_info *myinfo,char *symbol,bits256 privAm,bits256 privBn,bits256 utxotxid,int32_t vout,uint8_t pubkey33[33],uint32_t expiration,int64_t *destamountp) +{ + char msigaddr[64],*signedtx = 0; int32_t spendlen,redeemlen; uint8_t tmp33[33],redeemscript[512],spendscript[128]; bits256 pubAm,pubBn; struct iguana_info *coin = iguana_coinfind(symbol); + if ( coin != 0 && bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) + { + pubAm = bitcoin_pubkey33(myinfo->ctx,tmp33,privAm); + pubBn = bitcoin_pubkey33(myinfo->ctx,tmp33,privBn); + //char str[65]; + //printf("pubAm.(%s)\n",bits256_str(str,pubAm)); + //printf("pubBn.(%s)\n",bits256_str(str,pubBn)); + spendlen = basilisk_alicescript(redeemscript,&redeemlen,spendscript,0,msigaddr,coin->chain->p2shtype,pubAm,pubBn); + //char str[65]; printf("%s utxo.(%s) redeemlen.%d spendlen.%d\n",msigaddr,bits256_str(str,utxotxid),redeemlen,spendlen); + /*rev = privAm; + for (i=0; i<32; i++) + privAm.bytes[i] = rev.bytes[31 - i]; + rev = privBn; + for (i=0; i<32; i++) + privBn.bytes[i] = rev.bytes[31 - i];*/ + signedtx = basilisk_swap_bobtxspend(name,myinfo,symbol,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,vout,pubkey33,1,expiration,destamountp); + } + return(signedtx); +} + +bits256 basilisk_swap_privbob_extract(struct supernet_info *myinfo,char *symbol,bits256 spendtxid,int32_t vini,int32_t revflag) +{ + bits256 privkey; int32_t i,scriptlen,siglen; uint8_t script[1024]; // from Bob refund of Bob deposit + memset(&privkey,0,sizeof(privkey)); + if ( (scriptlen= basilisk_swap_getsigscript(myinfo,symbol,script,(int32_t)sizeof(script),spendtxid,vini)) > 0 ) + { + siglen = script[0]; + for (i=0; i<32; i++) + { + if ( revflag != 0 ) + privkey.bytes[31 - i] = script[siglen+2+i]; + else privkey.bytes[i] = script[siglen+2+i]; + } + char str[65]; printf("extracted privbob.(%s)\n",bits256_str(str,privkey)); + } + return(privkey); +} + +bits256 basilisk_swap_privBn_extract(struct supernet_info *myinfo,bits256 *bobrefundp,char *bobcoin,bits256 bobdeposit,bits256 privBn) +{ + char destaddr[64]; + if ( bits256_nonz(privBn) == 0 ) + { + if ( bits256_nonz(bobdeposit) != 0 ) + *bobrefundp = basilisk_swap_spendtxid(myinfo,bobcoin,destaddr,bobdeposit,0); + if ( bits256_nonz(*bobrefundp) != 0 ) + privBn = basilisk_swap_privbob_extract(myinfo,bobcoin,*bobrefundp,0,0); + } + return(privBn); +} + +bits256 basilisk_swap_spendupdate(struct supernet_info *myinfo,char *symbol,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t vout,char *aliceaddr,char *bobaddr) +{ + bits256 spendtxid,txid; char destaddr[64]; + txid = txids[utxoind]; + memset(&spendtxid,0,sizeof(spendtxid)); + /*if ( aliceaddr != 0 ) + printf("aliceaddr.(%s)\n",aliceaddr); + if ( bobaddr != 0 ) + printf("bobaddr.(%s)\n",bobaddr);*/ + if ( bits256_nonz(txid) != 0 ) + { + //char str[65]; + spendtxid = basilisk_swap_spendtxid(myinfo,symbol,destaddr,txid,vout); + if ( bits256_nonz(spendtxid) != 0 ) + { + sentflags[utxoind] = 1; + if ( aliceaddr != 0 && strcmp(destaddr,aliceaddr) == 0 ) + { + //printf("ALICE spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + sentflags[alicespent] = 1; + txids[alicespent] = spendtxid; + } + else if ( bobaddr != 0 && strcmp(destaddr,bobaddr) == 0 ) + { + //printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + sentflags[bobspent] = 1; + txids[bobspent] = spendtxid; + } + else + { + //printf("OTHER dest spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + if ( aliceaddr != 0 ) + { + sentflags[bobspent] = 1; + txids[bobspent] = spendtxid; + } + else if ( bobaddr != 0 ) + { + sentflags[alicespent] = 1; + txids[alicespent] = spendtxid; + } + } + } + } else printf("utxoind.%d null txid\n",utxoind); + return(spendtxid); +} + +#define BASILISK_ALICESPEND 0 +#define BASILISK_BOBSPEND 1 +#define BASILISK_BOBPAYMENT 2 +#define BASILISK_ALICEPAYMENT 3 +#define BASILISK_BOBDEPOSIT 4 +#define BASILISK_OTHERFEE 5 +#define BASILISK_MYFEE 6 +#define BASILISK_BOBREFUND 7 +#define BASILISK_BOBRECLAIM 8 +#define BASILISK_ALICERECLAIM 9 +#define BASILISK_ALICECLAIM 10 +//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 +char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; + +int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind) +{ + switch ( ind ) + { + case BASILISK_MYFEE: return(iambob); break; + case BASILISK_OTHERFEE: return(!iambob); break; + case BASILISK_BOBSPEND: + case BASILISK_ALICEPAYMENT: + case BASILISK_ALICERECLAIM: + case BASILISK_ALICECLAIM: return(0); + break; + case BASILISK_BOBDEPOSIT: + case BASILISK_ALICESPEND: + case BASILISK_BOBPAYMENT: + case BASILISK_BOBREFUND: + case BASILISK_BOBRECLAIM: return(1); + break; + default: return(-1); break; + } +} + +// add blocktrail presence requirement for BTC +int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflags,bits256 paymentspent,bits256 Apaymentspent,bits256 depositspent) +{ + int32_t i,n = 0; + for (i=0; i (%s)\n",fname,fstr); + if ( (txobj= cJSON_Parse(fstr)) != 0 ) + { + paymentspent = jbits256(txobj,"paymentspent"); + Apaymentspent = jbits256(txobj,"Apaymentspent"); + depositspent = jbits256(txobj,"depositspent"); + if ( (array= jarray(&n,txobj,"values")) != 0 ) + for (i=0; i (%s)\n",fname,fstr); + if ( (txobj= cJSON_Parse(fstr)) != 0 ) + { + //printf("TXOBJ.(%s)\n",jprint(txobj,0)); + iambob = jint(txobj,"iambob"); + txid = jbits256(txobj,"txid"); + if ( bits256_nonz(txid) == 0 ) + continue; + txids[i] = txid; + if ( jobj(txobj,"tx") != 0 ) + { + txbytes[i] = clonestr(jstr(txobj,"tx")); + //printf("[%s] TX.(%s)\n",txnames[i],txbytes[i]); + } + if ( (value= jdouble(txobj,"amount") * SATOSHIDEN) == 0 ) + value = jdouble(txobj,"value") * SATOSHIDEN; + values[i] = value; + if ( (symbol= jstr(txobj,"coin")) != 0 ) + { + if ( i == BASILISK_ALICESPEND || i == BASILISK_BOBPAYMENT || i == BASILISK_BOBDEPOSIT || i == BASILISK_BOBREFUND || i == BASILISK_BOBRECLAIM || i == BASILISK_ALICECLAIM ) + safecopy(bobcoin,symbol,sizeof(bobcoin)); + else if ( i == BASILISK_BOBSPEND || i == BASILISK_ALICEPAYMENT || i == BASILISK_ALICERECLAIM ) + safecopy(alicecoin,symbol,sizeof(alicecoin)); + if ( finishedflag == 0 ) + { + if ( (sentobj= basilisk_swapgettx(myinfo,symbol,txid)) == 0 ) + { + //printf("%s %s ready to broadcast\n",symbol,bits256_str(str2,txid)); + } + else + { + checktxid = jbits256(sentobj,"txid"); + if ( bits256_nonz(checktxid) == 0 ) + checktxid = jbits256(sentobj,"hash"); + if ( bits256_cmp(checktxid,txid) == 0 ) + { + //printf(">>>>>> %s txid %s\n",jprint(sentobj,0),bits256_str(str,txid)); + sentflags[i] = 1; + } + free_json(sentobj); + } + printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value)); + } + } + } //else printf("no symbol\n"); + free(fstr); + } else if ( finishedflag == 0 ) + printf("%s not finished\n",fname); + } + //printf("iambob.%d src.%s dest.%s bob.%s alice.%s pubA0.(%s)\n",iambob,src,dest,bobcoin,alicecoin,bits256_str(str,pubA0)); + Adestaddr[0] = destaddr[0] = 0; + Adest = Bdest = AAdest = ABdest = 0; + if ( bobcoin[0] == 0 || alicecoin[0] == 0 ) + return(0); + //printf("privAm.(%s) %p/%p\n",bits256_str(str,privAm),Adest,AAdest); + //printf("privBn.(%s) %p/%p\n",bits256_str(str,privBn),Bdest,ABdest); + if ( finishedflag == 0 && bobcoin[0] != 0 && alicecoin[0] != 0 ) + { + if ( iambob == 0 ) + { + if ( (coin= iguana_coinfind(alicecoin)) != 0 ) + { + bitcoin_address(Adestaddr,coin->chain->pubtype,pubkey33,33); + AAdest = Adestaddr; + } + if ( (coin= iguana_coinfind(bobcoin)) != 0 ) + { + bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33); + Adest = destaddr; + } + } + else + { + if ( (coin= iguana_coinfind(bobcoin)) != 0 ) + { + bitcoin_address(destaddr,coin->chain->pubtype,pubkey33,33); + Bdest = destaddr; + } + if ( (coin= iguana_coinfind(alicecoin)) != 0 ) + { + bitcoin_address(Adestaddr,coin->chain->pubtype,pubkey33,33); + ABdest = Adestaddr; + } + } + if ( sentflags[BASILISK_ALICEPAYMENT] == 0 && bits256_nonz(txids[BASILISK_ALICEPAYMENT]) != 0 ) + { + printf("txbytes.%p Apayment.%s\n",txbytes[BASILISK_ALICEPAYMENT],bits256_str(str,txids[BASILISK_ALICEPAYMENT])); + if ( txbytes[BASILISK_ALICEPAYMENT] != 0 ) + sentflags[BASILISK_ALICEPAYMENT] = 1; + else if ( (sentobj= basilisk_swapgettx(myinfo,alicecoin,txids[BASILISK_ALICEPAYMENT])) != 0 ) + { + sentflags[BASILISK_ALICEPAYMENT] = 1; + free_json(sentobj); + } + } + paymentspent = basilisk_swap_spendupdate(myinfo,bobcoin,sentflags,txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,Adest,Bdest); + Apaymentspent = basilisk_swap_spendupdate(myinfo,alicecoin,sentflags,txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,AAdest,ABdest); + depositspent = basilisk_swap_spendupdate(myinfo,bobcoin,sentflags,txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,Adest,Bdest); + finishedflag = basilisk_swap_isfinished(iambob,txids,sentflags,paymentspent,Apaymentspent,depositspent); + if ( iambob == 0 ) + { + if ( sentflags[BASILISK_ALICESPEND] == 0 ) + { + if ( sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(paymentspent) == 0 ) + { + //if ( txbytes[BASILISK_ALICESPEND] == 0 ) + { + if ( bits256_nonz(txids[BASILISK_BOBPAYMENT]) != 0 ) + { + // alicespend + for (j=0; j<32; j++) + rev.bytes[j] = privAm.bytes[31 - j]; + revcalc_rmd160_sha256(secretAm,rev);//privAm); + vcalc_sha256(0,secretAm256,rev.bytes,sizeof(rev)); + redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,plocktime,pubA0,pubB0,pubB1,rev,privBn,secretAm,secretAm256,secretBn,secretBn256); + len = basilisk_swapuserdata(userdata,rev,0,myprivs[0],redeemscript,redeemlen); + printf("alicespend len.%d redeemlen.%d\n",len,redeemlen); + if ( (txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend("alicespend",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,1,expiration,&values[BASILISK_ALICESPEND])) != 0 ) + printf("alicespend.(%s)\n",txbytes[BASILISK_ALICESPEND]); + } + } + if ( txbytes[BASILISK_ALICESPEND] != 0 ) + { + txids[BASILISK_ALICESPEND] = basilisk_swap_sendrawtransaction(myinfo,"alicespend",bobcoin,txbytes[BASILISK_ALICESPEND]); + if ( bits256_nonz(txids[BASILISK_ALICESPEND]) != 0 ) // tested + { + sentflags[BASILISK_ALICESPEND] = 1; + paymentspent = txids[BASILISK_ALICESPEND]; + } + } + } + } + if ( sentflags[BASILISK_ALICECLAIM] == 0 && sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(depositspent) == 0 ) + { + if ( time(NULL) > expiration ) + { + //if ( txbytes[BASILISK_ALICECLAIM] == 0 ) + { + redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,dlocktime,pubA0,pubB0,pubB1,privAm,zero,secretAm,secretAm256,secretBn,secretBn256); + if ( redeemlen > 0 ) + { + len = basilisk_swapuserdata(userdata,zero,1,myprivs[0],redeemscript,redeemlen); + if ( (txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend("aliceclaim",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,0,expiration,&values[BASILISK_ALICECLAIM])) != 0 ) + printf("privBn.(%s) aliceclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICECLAIM]); + } + } + if ( txbytes[BASILISK_ALICECLAIM] != 0 ) + { + txids[BASILISK_ALICECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"aliceclaim",bobcoin,txbytes[BASILISK_ALICECLAIM]); + if ( bits256_nonz(txids[BASILISK_ALICECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_ALICECLAIM] = 1; + depositspent = txids[BASILISK_ALICECLAIM]; + } + } + } else printf("now %u before expiration %u\n",(uint32_t)time(NULL),expiration); + } + if ( sentflags[BASILISK_ALICEPAYMENT] != 0 && bits256_nonz(Apaymentspent) == 0 && sentflags[BASILISK_ALICECLAIM] == 0 ) + { + //if ( txbytes[BASILISK_ALICERECLAIM] == 0 ) + { + privBn = basilisk_swap_privBn_extract(myinfo,&txids[BASILISK_BOBREFUND],bobcoin,txids[BASILISK_BOBDEPOSIT],privBn); + if ( bits256_nonz(txids[BASILISK_ALICEPAYMENT]) != 0 && bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) + { + if ( (txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",myinfo,alicecoin,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_ALICERECLAIM])) != 0 ) + printf("privBn.(%s) alicereclaim.(%s)\n",bits256_str(str,privBn),txbytes[BASILISK_ALICERECLAIM]); + } + } + if ( txbytes[BASILISK_ALICERECLAIM] != 0 ) + { + txids[BASILISK_ALICERECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"alicereclaim",alicecoin,txbytes[BASILISK_ALICERECLAIM]); + if ( bits256_nonz(txids[BASILISK_ALICERECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_ALICERECLAIM] = 1; + Apaymentspent = txids[BASILISK_ALICERECLAIM]; + } + } + } + } + else if ( iambob == 1 ) + { + if ( sentflags[BASILISK_BOBSPEND] == 0 && bits256_nonz(Apaymentspent) == 0 ) + { + printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,txids[BASILISK_ALICESPEND]),bits256_nonz(privAm)); + if ( bits256_nonz(txids[BASILISK_ALICESPEND]) != 0 || bits256_nonz(privAm) != 0 ) + { + //if ( txbytes[BASILISK_BOBSPEND] == 0 ) + { + if ( bits256_nonz(privAm) == 0 ) + { + privAm = basilisk_swap_privbob_extract(myinfo,bobcoin,txids[BASILISK_ALICESPEND],0,1); + } + if ( bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) + { + if ( (txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",myinfo,alicecoin,privAm,privBn,txids[BASILISK_ALICEPAYMENT],0,pubkey33,expiration,&values[BASILISK_BOBSPEND])) != 0 ) + printf("bobspend.(%s)\n",txbytes[BASILISK_BOBSPEND]); + } + } + if ( txbytes[BASILISK_BOBSPEND] != 0 ) + { + txids[BASILISK_BOBSPEND] = basilisk_swap_sendrawtransaction(myinfo,"bobspend",alicecoin,txbytes[BASILISK_BOBSPEND]); + if ( bits256_nonz(txids[BASILISK_BOBSPEND]) != 0 ) // tested + { + sentflags[BASILISK_BOBSPEND] = 1; + Apaymentspent = txids[BASILISK_BOBSPEND]; + } + } + } + } + if ( sentflags[BASILISK_BOBRECLAIM] == 0 && sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(txids[BASILISK_BOBPAYMENT]) != 0 && time(NULL) > expiration && bits256_nonz(paymentspent) == 0 ) + { + //if ( txbytes[BASILISK_BOBRECLAIM] == 0 ) + { + // bobreclaim + redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,plocktime,pubA0,pubB0,pubB1,zero,privBn,secretAm,secretAm256,secretBn,secretBn256); + if ( redeemlen > 0 ) + { + len = basilisk_swapuserdata(userdata,zero,1,myprivs[1],redeemscript,redeemlen); + if ( (txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend("bobrefund",myinfo,bobcoin,myprivs[1],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBPAYMENT],0,pubkey33,0,expiration,&values[BASILISK_BOBRECLAIM])) != 0 ) + { + int32_t z; + for (z=0; z<20; z++) + printf("%02x",secretAm[z]); + printf(" secretAm, myprivs[1].(%s) bobreclaim.(%s)\n",bits256_str(str,myprivs[1]),txbytes[BASILISK_BOBRECLAIM]); + } + } + } + if ( txbytes[BASILISK_BOBRECLAIM] != 0 ) + { + txids[BASILISK_BOBRECLAIM] = basilisk_swap_sendrawtransaction(myinfo,"bobreclaim",bobcoin,txbytes[BASILISK_BOBRECLAIM]); + if ( bits256_nonz(txids[BASILISK_BOBRECLAIM]) != 0 ) // tested + { + sentflags[BASILISK_BOBRECLAIM] = 1; + paymentspent = txids[BASILISK_BOBRECLAIM]; + } + } + } + if ( sentflags[BASILISK_BOBREFUND] == 0 && sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(depositspent) == 0 ) + { + if ( bits256_nonz(paymentspent) != 0 || time(NULL) > expiration ) + { + printf("do the refund!\n"); + //if ( txbytes[BASILISK_BOBREFUND] == 0 ) + { + revcalc_rmd160_sha256(secretBn,privBn); + vcalc_sha256(0,secretBn256,privBn.bytes,sizeof(privBn)); + redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,dlocktime,pubA0,pubB0,pubB1,privAm,privBn,secretAm,secretAm256,secretBn,secretBn256); + len = basilisk_swapuserdata(userdata,privBn,0,myprivs[0],redeemscript,redeemlen); + if ( (txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend("bobrefund",myinfo,bobcoin,myprivs[0],0,redeemscript,redeemlen,userdata,len,txids[BASILISK_BOBDEPOSIT],0,pubkey33,1,expiration,&values[BASILISK_BOBREFUND])) != 0 ) + printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,pubB1),txbytes[BASILISK_BOBREFUND]); + } + if ( txbytes[BASILISK_BOBREFUND] != 0 ) + { + txids[BASILISK_BOBREFUND] = basilisk_swap_sendrawtransaction(myinfo,"bobrefund",bobcoin,txbytes[BASILISK_BOBREFUND]); + if ( bits256_nonz(txids[BASILISK_BOBREFUND]) != 0 ) // tested + { + sentflags[BASILISK_BOBREFUND] = 1; + depositspent = txids[BASILISK_BOBREFUND]; + } + } + } else printf("time %u vs expiration %u\n",(uint32_t)time(NULL),expiration); + } + } + } + //printf("finish.%d iambob.%d REFUND %d %d %d %d\n",finishedflag,iambob,sentflags[BASILISK_BOBREFUND] == 0,sentflags[BASILISK_BOBDEPOSIT] != 0,bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0,bits256_nonz(depositspent) == 0); + if ( sentflags[BASILISK_ALICESPEND] != 0 || sentflags[BASILISK_BOBRECLAIM] != 0 ) + sentflags[BASILISK_BOBPAYMENT] = 1; + if ( sentflags[BASILISK_ALICERECLAIM] != 0 || sentflags[BASILISK_BOBSPEND] != 0 ) + sentflags[BASILISK_ALICEPAYMENT] = 1; + if ( sentflags[BASILISK_ALICECLAIM] != 0 || sentflags[BASILISK_BOBREFUND] != 0 ) + sentflags[BASILISK_BOBDEPOSIT] = 1; + for (i=0; inumswaps; i++) + if ( (swap= myinfo->swaps[i]) != 0 && swap->I.req.requestid == requestid && swap->I.req.quoteid == quoteid ) + { + jaddi(array,basilisk_swapjson(myinfo,swap)); + flag = 1; + break; + } + if ( flag == 0 ) + { + if ( (item= basilisk_remember(myinfo,KMDtotals,BTCtotals,requestid,quoteid)) != 0 ) + { + jaddi(array,item); + if ( 1 && (status= jstr(item,"status")) != 0 && strcmp(status,"pending") == 0 ) + break; + } + } + } + fclose(fp); + } + jaddstr(retjson,"result","success"); + jadd(retjson,"swaps",array); + if ( cJSON_GetArraySize(array) > 0 ) + { + totalsobj = cJSON_CreateObject(); + for (Btotal=i=0; i 0 && Btotal < 0 ) + jaddnum(retjson,"avebuy",(double)-Btotal/Ktotal); + else if ( Ktotal < 0 && Btotal > 0 ) + jaddnum(retjson,"avesell",(double)-Btotal/Ktotal); + } + array = cJSON_CreateArray(); + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + if ( myinfo->linfos[i].base[0] != 0 && myinfo->linfos[i].rel[0] != 0 ) + jaddi(array,linfo_json(&myinfo->linfos[i])); + } + jadd(retjson,"quotes",array); + return(jprint(retjson,1)); +} + + diff --git a/basilisk/basilisk_tradebot.c b/basilisk/basilisk_tradebot.c index f7d5dca16..2635cde97 100755 --- a/basilisk/basilisk_tradebot.c +++ b/basilisk/basilisk_tradebot.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -15,13 +15,191 @@ // included from basilisk.c +cJSON *basilisk_rawtxobj(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) +{ + char hexstr[sizeof(rawtx->I)*2+1+4096]; cJSON *obj = cJSON_CreateObject(); + jaddstr(obj,"name",rawtx->name); + init_hexbytes_noT(hexstr,(void *)&rawtx->I,sizeof(rawtx->I)); + jaddstr(obj,"info",hexstr); + if ( rawtx->I.datalen < sizeof(hexstr)/2 ) + { + init_hexbytes_noT(hexstr,(void *)rawtx->txbytes,rawtx->I.datalen); + jaddstr(obj,"txbytes",hexstr); + } + return(obj); +} + +struct basilisk_rawtx *basilisk_nameconv(struct supernet_info *myinfo,struct basilisk_swap *swap,char *name) +{ + if ( strcmp("myfee",name) == 0 ) + return(&swap->myfee); + else if ( strcmp("otherfee",name) == 0 ) + return(&swap->otherfee); + else if ( strcmp("bobdeposit",name) == 0 ) + return(&swap->bobdeposit); + else if ( strcmp("bobrefund",name) == 0 ) + return(&swap->bobrefund); + else if ( strcmp("aliceclaim",name) == 0 ) + return(&swap->aliceclaim); + else if ( strcmp("bobpayment",name) == 0 ) + return(&swap->bobpayment); + else if ( strcmp("alicespend",name) == 0 ) + return(&swap->alicespend); + else if ( strcmp("bobreclaim",name) == 0 ) + return(&swap->bobreclaim); + else if ( strcmp("alicepayment",name) == 0 ) + return(&swap->alicepayment); + else if ( strcmp("bobspend",name) == 0 ) + return(&swap->bobspend); + else if ( strcmp("alicereclaim",name) == 0 ) + return(&swap->alicereclaim); + else return(0); +} + +int32_t basilisk_txitem(struct supernet_info *myinfo,struct basilisk_swap *swap,cJSON *obj) +{ + char *hexstr,*name; struct basilisk_rawtx *rawtx = 0; + if ( (name= jstr(obj,"name")) == 0 || (rawtx= basilisk_nameconv(myinfo,swap,name)) == 0 ) + { + printf("basilisk_txitem illegal name.(%s)\n",name); + return(-1); + } + if ( rawtx != 0 && (hexstr= jstr(obj,"info")) != 0 && strlen(hexstr) == sizeof(rawtx->I)*2 ) + { + decode_hex((void *)&rawtx->I,sizeof(rawtx->I),hexstr); + if ( (hexstr= jstr(obj,"txbytes")) != 0 && strlen(hexstr) == rawtx->I.datalen*2 ) + { + /*if ( rawtx->txbytes == 0 ) + { + printf("free (%s) txbytes\n",name); + free(rawtx->txbytes); + } + rawtx->txbytes = calloc(1,rawtx->I.datalen);*/ + decode_hex((void *)rawtx->txbytes,rawtx->I.datalen,hexstr); + } + printf("PROCESS.(%s)\n",jprint(obj,0)); + return(0); + } + return(-1); +} + +cJSON *basilisk_swapobj(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + char hexstr[sizeof(swap->I)*2+1]; cJSON *obj = cJSON_CreateObject(); + init_hexbytes_noT(hexstr,(void *)&swap->I,sizeof(swap->I)); + jaddstr(obj,"name","swap"); + jaddnum(obj,"requestid",swap->I.req.requestid); + jaddnum(obj,"quoteid",swap->I.req.quoteid); + jadd(obj,"req",basilisk_requestjson(&swap->I.req)); + jaddstr(obj,"info",hexstr); + //printf("strlen(hexstr) swap->I %d vs %d\n",(int32_t)strlen(hexstr),(int32_t)sizeof(swap->I)*2); + return(obj); +} + +int32_t basilisk_swapconv(struct supernet_info *myinfo,struct basilisk_swap *swap,cJSON *obj) +{ + char *hexstr; + if ( (hexstr= jstr(obj,"info")) != 0 && strlen(hexstr) == sizeof(swap->I)*2 ) + { + decode_hex((void *)&swap->I,sizeof(swap->I),hexstr); + if ( juint(obj,"requestid") == swap->I.req.requestid && juint(obj,"quoteid") == swap->I.req.quoteid ) + return(0); + printf("swapconv mismatched req/quote %d %d, %d %d\n",juint(obj,"requestid"),swap->I.req.requestid,juint(obj,"quoteid"),swap->I.req.quoteid); + } //else printf("no info field in swap obj.(%s) len.%d vs %d\n",jprint(obj,0),(int32_t)strlen(hexstr),(int32_t)sizeof(swap->I)*2); + return(-1); +} + +struct basilisk_swap *basilisk_swapstore(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + // save based on requestid/quoteid + return(swap); +} + +struct basilisk_swap *basilisk_swapload(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t requestid,uint32_t quoteid) +{ + // set swap fields and return it if found + return(0); +} + +void basilisk_swapstart(struct supernet_info *myinfo) // scan saved tmpswap, purge if complete, else Q +{ + // for resuming pending swaps +} + +void basilisk_txlog(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,int32_t delay) +{ + char fname[1024],*jsonstr; long filesize; cJSON *item,*dexobj = 0; int32_t i,n,pending; struct basilisk_swap tmpswap,*swapptr; + sprintf(fname,"%s/DEX.log",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( myinfo->dexfp == 0 ) + { + if ( (jsonstr= OS_filestr(&filesize,fname)) != 0 ) + { + jsonstr[strlen(jsonstr)-1] = ']'; + if ( jsonstr[strlen(jsonstr)-2] == ',' ) + jsonstr[strlen(jsonstr)-2] = ' '; + if ( jsonstr[strlen(jsonstr)-3] == ',' ) + jsonstr[strlen(jsonstr)-3] = ' '; + if ( (dexobj= cJSON_Parse(jsonstr)) != 0 ) + { + if ( is_cJSON_Array(dexobj) != 0 && (n= cJSON_GetArraySize(dexobj)) > 0 ) + { + pending = 0; + memset(&tmpswap,0,sizeof(tmpswap)); + swapptr = 0; + for (i=0; iI.req.requestid == juint(item,"requestid") && swapptr->I.req.quoteid == juint(item,"quoteid") ) + basilisk_txitem(myinfo,swapptr,item); + } + else if ( (swapptr= basilisk_swapload(myinfo,&tmpswap,juint(item,"requestid"),juint(item,"quoteid"))) != 0 ) + basilisk_txitem(myinfo,swapptr,item); + } + basilisk_swapstart(myinfo); + } + free_json(dexobj); + dexobj = 0; + } else printf("basilisk_txlog error parsing.(%s)\n",jsonstr); + free(jsonstr); + } + if ( (myinfo->dexfp= fopen(fname,"rb+")) != 0 ) + fseek(myinfo->dexfp,0,SEEK_END); + else if ( (myinfo->dexfp= fopen(fname,"wb")) != 0 ) + fprintf(myinfo->dexfp,"[\n"); + } + if ( rawtx != 0 ) + { + // delay -1 -> dont issue, else submit after block timestamp is delay after swap->started + dexobj = basilisk_rawtxobj(myinfo,swap,rawtx); + } + else if ( swap != 0 ) + dexobj = basilisk_swapobj(myinfo,swap); + if ( dexobj != 0 && (jsonstr= jprint(dexobj,1)) != 0 ) + { + //printf("%s\n",jsonstr); + if ( myinfo->dexfp != 0 ) + { + fprintf(myinfo->dexfp,"%s,\n",jsonstr); + fflush(myinfo->dexfp); + } + free(jsonstr); + } +} + uint32_t basilisk_requestid(struct basilisk_request *rp) { struct basilisk_request R; R = *rp; R.requestid = R.quoteid = R.quotetime = 0; - R.destamount = 0; - R.relaybits = 0; + R.destamount = R.profitmargin = 0; + //R.relaybits = 0; memset(R.desthash.bytes,0,sizeof(R.desthash.bytes)); if ( 0 ) { @@ -29,7 +207,7 @@ uint32_t basilisk_requestid(struct basilisk_request *rp) for (i=0; i %s %.8f %s crc.%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.hash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R))); + char str[65],str2[65]; printf("B REQUESTID: t.%u r.%u q.%u %s %.8f %s -> %s %.8f %s crc.%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.srchash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R))); } return(calc_crc32(0,(void *)&R,sizeof(R))); } @@ -38,7 +216,7 @@ uint32_t basilisk_quoteid(struct basilisk_request *rp) { struct basilisk_request R; R = *rp; - R.requestid = R.quoteid = R.relaybits = 0; + R.requestid = R.quoteid = R.profitmargin = 0; //R.relaybits = return(calc_crc32(0,(void *)&R,sizeof(R))); } @@ -46,15 +224,17 @@ struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *r { uint32_t requestid,quoteid; memset(rp,0,sizeof(*rp)); - rp->hash = jbits256(reqjson,"hash"); + rp->srchash = jbits256(reqjson,"srchash"); rp->desthash = jbits256(reqjson,"desthash"); rp->srcamount = j64bits(reqjson,"srcamount"); rp->minamount = j64bits(reqjson,"minamount"); - rp->destamount = j64bits(reqjson,"destamount"); + //rp->destamount = j64bits(reqjson,"destamount"); + rp->destamount = j64bits(reqjson,"destsatoshis"); + //printf("parse DESTSATOSHIS.%llu (%s)\n",(long long)rp->destamount,jprint(reqjson,0)); requestid = juint(reqjson,"requestid"); quoteid = juint(reqjson,"quoteid"); - if ( jstr(reqjson,"relay") != 0 ) - rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay")); + //if ( jstr(reqjson,"relay") != 0 ) + // rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay")); rp->timestamp = juint(reqjson,"timestamp"); rp->quotetime = juint(reqjson,"quotetime"); safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src)); @@ -67,30 +247,20 @@ struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *r } rp->requestid = basilisk_requestid(rp); if ( requestid != rp->requestid ) - printf("basilisk_parsejson requestid.%u != %u error\n",requestid,rp->requestid); - return(rp); -} - -void basilisk_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob) -{ - // update balance, compare to target balance, issue balancing trade via central exchanges, if needed - if ( iambob != 0 ) - { - - } - else { - + int32_t i; for (i=0; irequestid); } + return(rp); } - struct basilisk_swap *basilisk_request_started(struct supernet_info *myinfo,uint32_t requestid) { int32_t i; struct basilisk_swap *active = 0; portable_mutex_lock(&myinfo->DEX_swapmutex); for (i=0; inumswaps; i++) - if ( myinfo->swaps[i]->req.requestid == requestid ) + if ( myinfo->swaps[i]->I.req.requestid == requestid ) { //printf("REQUEST STARTED.[%d] <- req.%u\n",i,requestid); active = myinfo->swaps[i]; @@ -102,67 +272,26 @@ struct basilisk_swap *basilisk_request_started(struct supernet_info *myinfo,uint int32_t basilisk_request_cmpref(struct basilisk_request *ref,struct basilisk_request *rp) { - if ( bits256_cmp(rp->hash,ref->hash) != 0 || memcmp(rp->src,ref->src,sizeof(ref->src)) != 0 || memcmp(rp->dest,ref->dest,sizeof(ref->dest)) != 0 || rp->srcamount != ref->srcamount || rp->timestamp != ref->timestamp ) + if ( bits256_cmp(rp->srchash,ref->srchash) != 0 || memcmp(rp->src,ref->src,sizeof(ref->src)) != 0 || memcmp(rp->dest,ref->dest,sizeof(ref->dest)) != 0 || rp->srcamount != ref->srcamount || rp->timestamp != ref->timestamp ) { printf("basilisk_request_listprocess mismatched hash\n"); return(-1); } else return(0); } -void tradebot_liquidity_command(struct supernet_info *myinfo,char *base,bits256 hash,cJSON *vals) -{ - struct liquidity_info li,refli; int32_t i; - memset(&li,0,sizeof(li)); - strcpy(li.base,base), strcpy(li.rel,"BTC"); - li.profit = jdouble(vals,"profit"); - li.refprice = jdouble(vals,"refprice"); - for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) - { - refli = myinfo->linfos[i]; - if ( strcmp(li.rel,refli.base) == 0 && strcmp(li.base,refli.rel) == 0 ) - { - strcpy(li.base,refli.base); - strcpy(li.rel,refli.rel); - li.refprice = (1. / li.refprice); - printf("Set rev linfo[%d] (%s/%s) %.6f %.8f\n",i,li.base,li.rel,li.profit,li.refprice); - myinfo->linfos[i] = li; - return; - } - else if ( refli.base[0] == 0 || (strcmp(li.base,refli.base) == 0 && strcmp(li.rel,refli.rel) == 0) ) - { - myinfo->linfos[i] = li; - printf("Set linfo[%d] (%s/%s) %.6f %.8f\n",i,li.base,li.rel,li.profit,li.refprice); - return; - } - } - printf("ERROR: too many linfos %d\n",i); -} - -double tradebot_liquidity_active(struct supernet_info *myinfo,double *refpricep,char *base,char *rel) -{ - int32_t i; struct liquidity_info refli; - *refpricep = 0.; - for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) - { - refli = myinfo->linfos[i]; - if ( (strcmp(base,refli.base) == 0 && strcmp(rel,refli.rel) == 0) || (strcmp(rel,refli.base) == 0 && strcmp(base,refli.rel) == 0 )) - { - *refpricep = refli.refprice; - return(refli.profit); - } - } - return(0.); -} - double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk_request *issueR,struct basilisk_request *list,int32_t n) { - int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; uint64_t destamount,minamount = 0,maxamount = 0; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.; + int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; int64_t balance=0,destamount,minamount = 0,maxamount = 0; bits256 privkey; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.,bidasks[2]; char typestr[64]; memset(issueR,0,sizeof(*issueR)); minamount = list[0].minamount; - printf("need to verify null quoteid is list[0] requestid.%u quoteid.%u\n",list[0].requestid,list[0].quoteid); + //printf("need to verify null quoteid is list[0] requestid.%u quoteid.%u\n",list[0].requestid,list[0].quoteid); if ( (active= basilisk_request_started(myinfo,list[0].requestid)) != 0 ) - pendingid = active->req.quoteid; - if ( bits256_cmp(myinfo->myaddr.persistent,list[0].hash) == 0 ) // my request + { + if ( active->I.req.quoteid != 0 ) + return(0.); + pendingid = active->I.req.quoteid; + } + if ( smartaddress_pubkey(myinfo,typestr,bidasks,&privkey,list[0].src,list[0].srchash) >= 0 ) myrequest = 1; for (i=0; imyaddr.persistent,list[i].desthash) == 0 ) // my quoteid + if ( smartaddress_pubkey(myinfo,typestr,bidasks,&privkey,list[i].dest,list[i].desthash) >= 0 ) myrequest |= 2; havequoteflag++; if ( pendingid == 0 ) @@ -178,6 +307,7 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk if ( list[i].destamount > maxamount ) { maxamount = list[i].destamount; + //printf("set maxamount %llu\n",(long long)maxamount); maxi = i; } } @@ -186,38 +316,65 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk } } else noquoteflag++; } - printf("myrequest.%d pendingid.%u noquoteflag.%d havequoteflag.%d maxi.%d %.8f\n",myrequest,pendingid,noquoteflag,havequoteflag,maxi,dstr(maxamount)); - double retvals[4],refprice,profitmargin,aveprice,balance=0.; cJSON *retjson; char *retstr; - if ( myinfo->IAMLP != 0 && myrequest == 0 && pendingid == 0 && noquoteflag != 0 && (profitmargin= tradebot_liquidity_active(myinfo,&refprice,list[0].src,list[0].dest)) > 0. ) + struct iguana_info *coin; char coinaddr[64]; double retvals[4],refprice=0.,profitmargin,aveprice,destvolume; + destvolume = dstr(maxamount); + //printf("destvolume <- %.8f\n",dstr(destvolume)); + if ( fabs(destvolume) < SMALLVAL ) + { + if ( (destvolume= dstr(minamount)) == 0 ) + { + aveprice = instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,1.3 * dstr(list[0].srcamount)); + destvolume = aveprice * dstr(list[0].srcamount); + printf("set destvolume %.8f\n",destvolume); + } // else printf("destvolume %.8f <- minamount\n",destvolume); + } + printf("<<<<<<< %s -> %s myrequest.%d pendingid.%u noquoteflag.%d havequoteflag.%d maxi.%d %.8f destvol %.8f\n",list[0].src,list[0].dest,myrequest,pendingid,noquoteflag,havequoteflag,maxi,dstr(maxamount),destvolume); + if ( myinfo->IAMLP != 0 && myrequest == 0 && pendingid == 0 && noquoteflag != 0 && ((profitmargin= tradebot_liquidity_active(myinfo,&refprice,"DEX",list[0].src,list[0].dest,destvolume)) > 0. || refprice != 0.) ) { - if ( (aveprice= instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,1.3 * dstr(list[0].srcamount))) == 0. || refprice > aveprice ) + if ( profitmargin == 0. || (aveprice= instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,.1 * dstr(list[0].srcamount))) == 0. || refprice > aveprice ) aveprice = refprice; + if ( fabs(aveprice) < SMALLVAL ) + return(0); + if ( strcmp("BTC",list[0].src) == 0 ) + aveprice = (1. / aveprice); + //retvals[0] = avebid, retvals[1] = bidvol, retvals[2] = aveask, retvals[3] = askvol; destamount = (1.0 - profitmargin) * aveprice * list[0].srcamount; - if ( (retstr= InstantDEX_available(myinfo,iguana_coinfind(list[0].dest),0,0,list[0].dest)) != 0 ) + if ( destamount > minamount ) + destamount = minamount + ((destamount - minamount) * (1 + (rand() % 100))) / 100.; + printf("%s/%s pm %f aveprice %f src %.8f dest %.8f avebid %f bidvol %f, aveask %f askvol %f\n",list[0].src,list[0].dest,profitmargin,aveprice,dstr(list[0].srcamount),dstr(destamount),retvals[0],retvals[1],retvals[2],retvals[3]); + if ( (coin= iguana_coinfind(list[0].dest)) != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + balance = jumblr_balance(myinfo,coin,coinaddr); + printf("%s %s balance %.8f destamount %.8f aveprice %.8f maxamount %.8f minamount %.8f\n",list[0].dest,coinaddr,dstr(balance),dstr(destamount),aveprice,dstr(maxamount),dstr(minamount)); + } + /*if ( (retstr= InstantDEX_available(myinfo,iguana_coinfind(list[0].dest),0,0,list[0].dest)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - balance = jdouble(retjson,"result"); + balance = jdouble(retjson,"result") * SATOSHIDEN; free_json(retjson); } free(retstr); - } - printf("balance %.8f destamount %.8f aveprice %.8f minamount %.8f\n",balance,dstr(destamount),aveprice,dstr(minamount)); - if ( balance > destamount && destamount > 0 && destamount >= maxamount && destamount >= minamount ) + }*/ + if ( balance > destamount && (int64_t)destamount > 0 && destamount >= minamount ) // max? { metric = 1.; *issueR = list[0]; issueR->desthash = myinfo->myaddr.persistent; issueR->destamount = destamount; issueR->quotetime = (uint32_t)time(NULL); + issueR->profitmargin = (uint32_t)(profitmargin * 1000000); } } else if ( myrequest != 0 && pendingid == 0 && maxi >= 0 ) // automatch best quote { - if ( minamount != 0 && maxamount > minamount && time(NULL) > BASILISK_DEXDURATION/2 ) + if ( minamount != 0 && maxamount >= minamount )//&& time(NULL) > list[0].timestamp+BASILISK_AUCTION_DURATION ) { - printf("automatch quoteid.%u triggered %.8f > %.8f\n",list[maxi].quoteid,dstr(maxamount),dstr(minamount)); *issueR = list[maxi]; + for (i=0; i= %.8f\n",maxi,list[maxi].requestid,list[maxi].quoteid,dstr(maxamount),dstr(minamount)); if ( minamount > 0 ) metric = (dstr(maxamount) / dstr(minamount)) - 1.; else metric = 1.; @@ -228,31 +385,61 @@ double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk double basilisk_process_results(struct supernet_info *myinfo,struct basilisk_request *issueR,cJSON *retjson,double hwm) { - cJSON *array,*item; int32_t i,n,m; struct basilisk_request tmpR,R,refR,list[BASILISK_MAXRELAYS]; double metric=0.; - //printf("process_results.(%s)\n",jprint(retjson,0)); - if ( (array= jarray(&n,retjson,"result")) != 0 ) + cJSON *array,*item; uint8_t *hexdata,*allocptr,hexspace[32768]; char *hexstr; int32_t i,hexlen,n,m,nonz; struct basilisk_request tmpR,R,refR,list[BASILISK_MAXRELAYS]; double metric=0.; + memset(&refR,0,sizeof(refR)); + memset(&R,0,sizeof(R)); +//printf("process.(%s)\n",jprint(retjson,0)); + if ( (array= jarray(&n,retjson,"messages")) != 0 ) { - for (i=m=0; i hwm ) - *issueR = tmpR, hwm = metric; - m = 0; + if ( refR.requestid == R.requestid ) + list[m++] = R; + else + { + if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm ) + { + *issueR = tmpR; + hwm = metric; + refR = tmpR; + printf("SET HWM\n"); + } + m = 0; + } + } + nonz++; + if ( m < sizeof(list)/sizeof(*list) ) + { + //basilisk_parsejson(&list[m++],item); + list[m++] = R; } } - if ( m < sizeof(list)/sizeof(*list) ) - basilisk_parsejson(&list[m++],item); } + //printf("process_results n.%d m.%d nonz.%d\n",n,m,nonz); if ( m > 0 && m < sizeof(list)/sizeof(*list) ) if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm ) + { *issueR = tmpR, hwm = metric; + //printf("set hwm\n"); + //for (i=0; ichain->pubtype,pubkey,33); + // get stake of address + return(stake); +} + +int32_t basilisk_voter_process(struct supernet_info *myinfo,uint8_t *rmd160,struct iguana_info *coin,struct election_info *ep,struct vote_info *vp) +{ + int32_t i; + if ( vp->stake == 0 ) + vp->stake = 1; + if ( bits256_nonz(vp->vote) != 0 ) + { + for (i=1; i<8; i++) + if ( vp->vote.uints[i] != 0 ) + break; + if ( i == 8 ) + return(vp->vote.uints[0]); + else + { + for (i=0; i<20; i++) + rmd160[i] = vp->vote.bytes[i + 4]; + return(ep->numcandidates); + } + } + return(-1); +} + +int32_t basilisk_election_process(struct supernet_info *myinfo,int64_t *tally,struct iguana_info *coin,struct election_info *ep) +{ + int32_t i,j,pending = 0; struct vote_info *vp; uint8_t rmd160[20]; + for (i=0; inumvotes; i++) + ep->votes[i].repstake = 0; + for (i=0; inumvotes; i++) + { + vp = &ep->votes[i]; + if ( basilisk_voter_process(myinfo,rmd160,coin,ep,vp) == ep->numcandidates && vp->repid < 0 ) + { + for (j=0; jnumvotes; j++) + { + if ( i != j && memcmp(rmd160,ep->votes[j].rmd160,20) == 0 ) + { + vp->repid = j; + ep->votes[j].repstake += vp->stake; + break; + } + } + } + } + if ( tally != 0 ) + { + memset(tally,0,ep->numcandidates*sizeof(*tally)); + for (i=0; inumvotes; i++) + { + vp = &ep->votes[i]; + if ( vp->repid < 0 && vp->vote.uints[0] > 0 && vp->vote.uints[0] <= ep->numcandidates ) + tally[vp->vote.uints[0]] += (vp->stake + vp->repstake); + else if ( vp->repid < 0 ) + pending++; + } + } + return(pending); +} + +cJSON *basilisk_voterjson(struct supernet_info *myinfo,struct iguana_info *coin,struct election_info *ep,struct vote_info *vp) +{ + char coinaddr[64],sigstr[74*2+1]; int32_t i; uint8_t rmd160[20]; cJSON *item; + item = cJSON_CreateObject(); + basilisk_voter_process(myinfo,rmd160,coin,ep,vp); + bitcoin_address(coinaddr,5,vp->pubkey,sizeof(vp->pubkey)); + jaddstr(item,"coinaddr",coinaddr); + jaddnum(item,"stake",dstr(vp->stake)); + if ( vp->repstake != 0 ) + jaddnum(item,"repstake",dstr(vp->repstake)); + if ( bits256_nonz(vp->vote) != 0 ) + { + for (i=1; i<8; i++) + if ( vp->vote.uints[i] != 0 ) + break; + if ( i == 8 ) + { + if ( vp->vote.uints[0] <= ep->numcandidates ) + jaddnum(item,"vote",vp->vote.uints[0]); + else jaddstr(item,"error","illegal vote"); + } + else + { + for (i=0; i<20; i++) + rmd160[i] = vp->vote.bytes[i + 4]; + bitcoin_address(coinaddr,5,rmd160,20); + jaddstr(item,"delegated",coinaddr); + } + } + else if ( bits256_nonz(vp->commit) != 0 ) + jaddbits256(item,"commit",vp->commit); + init_hexbytes_noT(sigstr,vp->sig,vp->siglen); + jaddstr(item,"sig",sigstr); + return(item); +} + +cJSON *basilisk_electionjson(struct supernet_info *myinfo,struct iguana_info *coin,struct election_info *ep) +{ + int32_t i; cJSON *array,*obj = cJSON_CreateObject(); + jaddstr(obj,"name",ep->name); + jaddbits256(obj,"hash",ep->hash); + jaddnum(obj,"expiration",ep->expiration); + jaddnum(obj,"numcandidates",ep->numcandidates); + jaddnum(obj,"numvotes",ep->numvotes); + jadd(obj,"ballot",jduplicate(ep->ballot)); + array = cJSON_CreateArray(); + for (i=0; inumvotes; i++) + jaddi(array,basilisk_voterjson(myinfo,coin,ep,&ep->votes[i])); + jadd(obj,"votes",array); + return(obj); +} + +int32_t basilisk_electionsave(struct election_info *ep) +{ + char fname[512],str[65],*ballotstr; int32_t n; FILE *fp; + OS_ensure_directory("elections"); + sprintf(fname,"elections/%s",bits256_str(str,ep->hash)); + OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(ep,1,sizeof(*ep),fp) != sizeof(*ep) ) + printf("error saving election.(%s) to %s\n",ep->name,fname); + else + { + if ( fwrite(&ep->numvotes,1,sizeof(ep->numvotes),fp) != sizeof(ep->numvotes) ) + printf("error saving numvotes.%d to %s\n",ep->numvotes,fname); + else if ( ep->numvotes > 0 ) + { + if ( fwrite(ep->votes,sizeof(*ep->votes),ep->numvotes,fp) != ep->numvotes ) + printf("error saving votes.%d for %s to %s\n",ep->numvotes,ep->name,fname); + else + { + if ( (ballotstr= jprint(ep->ballot,0)) != 0 ) + { + n = (int32_t)strlen(ballotstr) + 1; + if ( fwrite(&n,1,sizeof(n),fp) != sizeof(n) ) + printf("error saving n.%d for (%s) to %s\n",n,ballotstr,fname); + else if ( fwrite(ballotstr,1,n,fp) != n ) + printf("error saving election.(%s) to %s\n",ballotstr,fname); + free(ballotstr); + } + } + } + } + fclose(fp); + return(0); + } + return(-1); +} + +struct vote_info *basilisk_vote_find(struct election_info *ep,struct vote_info *vote) +{ + int32_t i; + for (i=0; inumvotes; i++) + { + if ( memcmp(ep->votes[i].pubkey,vote->pubkey,33) == 0 ) + return(&ep->votes[i]); + } + return(0); +} + +struct election_info *basilisk_election_find(int32_t createflag,bits256 hash) +{ + int32_t i; uint32_t now = (uint32_t)time(NULL); + for (i=0; i Elections[i].expiration ) + { + basilisk_electionsave(&Elections[i]); + memset(&Elections[i],0,sizeof(Elections[i])); + } + if ( bits256_nonz(hash) != 0 ) + { + if ( bits256_nonz(Elections[i].hash) == 0 ) + return(&Elections[i]); + else if ( bits256_cmp(Elections[i].hash,hash) == 0 ) + return(0); + } + } + return(0); +} + +int32_t basilisk_vote_extract(struct supernet_info *myinfo,char *coinaddr,struct vote_info *vote,cJSON *item) +{ + char str[65],str2[65],str3[65]; uint8_t *sig,*pubkey; int32_t action,siglen,plen; bits256 data,hash; + memset(vote,0,sizeof(*vote)); + if ( get_dataptr(0,&sig,&siglen,vote->sig,sizeof(vote->sig),jstr(item,"sig")) != 0 ) + { + vote->siglen = siglen; + action = juint(item,"action"); + if ( get_dataptr(0,&pubkey,&plen,vote->pubkey,sizeof(vote->pubkey),jstr(item,"pubkey")) != 0 ) + { + bitcoin_address(coinaddr,5,pubkey,33); + data = jbits256(item,"data"); + if ( bitcoin_verify(myinfo->ctx,vote->sig,vote->siglen,data,vote->pubkey,33) == 0 ) + { + if ( (action & 0xff) == 'c' ) + { + vote->commit = data; + printf("%s commits to %s\n",coinaddr,bits256_str(str,data)); + return(action); + } + else if ( (action & 0xff) == 'r' ) + { + if ( bits256_nonz(vote->commit) != 0 ) + { + vcalc_sha256(0,hash.bytes,data.bytes,sizeof(data)); + if ( bits256_cmp(hash,vote->commit) == 0 ) + { + printf("%s vote %s -> %s matches commit %s\n",coinaddr,bits256_str(str,data),bits256_str(str2,hash),bits256_str(str3,vote->commit)); + vote->vote = data; + // error check vote + return(action); + } + else + { + printf("%s vote %s -> %s doesnt match commit %s\n",coinaddr,bits256_str(str,data),bits256_str(str2,hash),bits256_str(str3,vote->commit)); + return(-2); + } + } + } + } else return(-1); + } + } + return(-1); +} + +char *basilisk_respond_VOT(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + int32_t i,duration,winner,pending,action,numcandidates; char coinaddr[64],*symbol,*votemethod,*ballotstr; cJSON *item,*array,*electionobj,*ballot,*retjson; struct election_info *ep; struct vote_info vote,*vp; struct iguana_info *coin; int64_t *tally,max; + retjson = cJSON_CreateObject(); + if ( (symbol= jstr(valsobj,"coin")) == 0 ) + symbol = "BTCD"; + coin = iguana_coinfind(symbol); + if ( (votemethod= jstr(valsobj,"votemethod")) != 0 ) + { + if ( strcmp(votemethod,"create") == 0 ) + { + if ( (ballot= jarray(&numcandidates,valsobj,"ballot")) != 0 && numcandidates > 0 ) + { + if ( (duration= juint(valsobj,"duration")) == 0 ) + duration = 3600; + ballotstr = jprint(ballot,0); + vcalc_sha256(0,hash.bytes,(uint8_t *)ballotstr,(int32_t)strlen(ballotstr)); + free(ballotstr); + if ( (ep= basilisk_election_find(1,hash)) != 0 ) + { + ep->hash = hash; + ep->duration = duration; + ep->expiration = (uint32_t)time(NULL) + duration; + ep->ballot = jduplicate(ballot); + ep->numcandidates = numcandidates; + safecopy(ep->name,jstr(valsobj,"name"),sizeof(ep->name)); + if ( (electionobj= basilisk_electionjson(myinfo,coin,ep)) != 0 ) + { + jaddstr(retjson,"result","success"); + jadd(retjson,"election",electionobj); + } else jaddstr(retjson,"error","couldnt create election object"); + } else jaddstr(retjson,"error","couldnt allocate election slot"); + } + } + else if ( strcmp(votemethod,"list") == 0 ) + { + array = cJSON_CreateArray(); + for (i=0; inumcandidates+1,sizeof(*tally)); + pending = basilisk_election_process(myinfo,tally,coin,ep); + if ( pending != 0 ) + jaddnum(retjson,"pending",pending); + jadd(retjson,"election",basilisk_electionjson(myinfo,coin,ep)); + array = cJSON_CreateArray(); + max = 0; + winner = -1; + for (i=1; i<=ep->numcandidates; i++) + { + if ( tally[i] > max ) + { + max = tally[i]; + winner = i; + } + jaddinum(array,dstr(tally[i])); + } + jadd(retjson,"tally",array); + if ( winner > 0 ) + { + item = jitem(ep->ballot,winner-1); + jadd(retjson,"winner",item); + } + free(tally); + } + else if ( strcmp(votemethod,"ratify") == 0 ) + { + // record ratification of tally + } + else if ( (action= basilisk_vote_extract(myinfo,coinaddr,&vote,valsobj)) > 0 ) + { + vp = basilisk_vote_find(ep,&vote); + if ( strcmp(votemethod,"vote") == 0 ) + { + if ( vp == 0 ) + { + ep->votes = realloc(ep->votes,sizeof(*ep->votes) + (ep->numvotes + 1)); + vote.repid = -1; + vote.stake = basilisk_voter_stake(myinfo,vote.rmd160,coin,vote.pubkey); + ep->votes[ep->numvotes++] = vote; + jaddstr(retjson,"result","success"); + } + else if ( action == 'c' ) + { + *vp = vote; + jaddstr(retjson,"result","success"); + } + else if ( action == 'r' ) + { + *vp = vote; + jaddstr(retjson,"result","success"); + } else jaddstr(retjson,"error","illegal vote action"); + } + else if ( strcmp(votemethod,"verify") == 0 ) + { + if ( vp == 0 ) + jaddstr(retjson,"error","cant find voter"); + else if ( action == 'c' ) + { + if ( bits256_cmp(vote.commit,vp->commit) == 0 ) + jaddstr(retjson,"result","success"); + else jaddstr(retjson,"error","mismatched commit"); + jaddbits256(retjson,"oldcommit",vp->commit); + jaddbits256(retjson,"newcommit",vote.commit); + } + else if ( action == 'r' ) + { + if ( bits256_cmp(vote.vote,vp->vote) == 0 ) + jaddstr(retjson,"result","success"); + else jaddstr(retjson,"error","mismatched vote"); + jaddbits256(retjson,"oldvote",vp->vote); + jaddbits256(retjson,"newvote",vote.vote); + } else jaddstr(retjson,"error","illegal vote action"); + } else jaddstr(retjson,"error","illegal vote method"); + } else jaddstr(retjson,"error","couldnt extract vote info"); + } + } + return(jprint(retjson,1)); +} + + diff --git a/basilisk/jumblr.c b/basilisk/jumblr.c new file mode 100755 index 000000000..9618a9421 --- /dev/null +++ b/basilisk/jumblr.c @@ -0,0 +1,772 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c +// connect DEX to jumblr-core + +/* + z_exportkey "zaddr" + z_exportwallet "filename" + z_getoperationstatus (["operationid", ... ]) + z_gettotalbalance ( minconf ) + z_importkey "zkey" ( rescan ) + z_importwallet "filename" + z_listaddresses + z_sendmany "fromaddress" [{"address":... ,"amount":..., "memo":""},...] ( minconf ) ( fee ) + */ + +#define JUMBLR_ADDR "RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t" +#define JUMBLR_BTCADDR "18RmTJe9qMech8siuhYfMtHo8RtcN1obC6" + +int32_t jumblr_addresstype(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + if ( addr[0] == 'z' && addr[1] == 'c' && strlen(addr) >= 40 ) + return('z'); + else if ( strlen(addr) < 40 ) + return('t'); + else return(-1); + } else return('t'); +} + +struct jumblr_item *jumblr_opidfind(struct supernet_info *myinfo,char *opid) +{ + struct jumblr_item *ptr; + HASH_FIND(hh,myinfo->jumblrs,opid,(int32_t)strlen(opid),ptr); + return(ptr); +} + +struct jumblr_item *jumblr_opidadd(struct supernet_info *myinfo,struct iguana_info *coin,char *opid) +{ + struct jumblr_item *ptr; + if ( (ptr= jumblr_opidfind(myinfo,opid)) == 0 ) + { + ptr = calloc(1,sizeof(*ptr)); + safecopy(ptr->opid,opid,sizeof(ptr->opid)); + HASH_ADD_KEYPTR(hh,myinfo->jumblrs,ptr->opid,(int32_t)strlen(ptr->opid),ptr); + if ( ptr != jumblr_opidfind(myinfo,opid) ) + printf("jumblr_opidadd.(%s) ERROR, couldnt find after add\n",opid); + } + return(ptr); +} + +char *jumblr_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char params[1024]; + if ( coin->FULLNODE < 0 ) + { + sprintf(params,"[\"%s\"]",addr); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"validateaddress",params)); + } else return(_dex_validateaddress(myinfo,coin->symbol,addr)); +} + +int32_t jumblr_ismine(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char params[1024],*retstr; cJSON *retjson,*obj; int32_t retval = -1; + sprintf(params,"[\"%s\"]",addr); + if ( (retstr= jumblr_validateaddress(myinfo,coin,addr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (obj= jobj(retjson,"ismine")) != 0 && is_cJSON_True(obj) != 0 ) + retval = 1; + else retval = 0; + free_json(retjson); + } + free(retstr); + } + return(retval); +} + +char *jumblr_zgetnewaddress(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_getnewaddress","")); +} + +char *jumblr_zlistoperationids(struct supernet_info *myinfo,struct iguana_info *coin) +{ + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_listoperationids","")); +} + +char *jumblr_zgetoperationresult(struct supernet_info *myinfo,struct iguana_info *coin,char *opid) +{ + char params[1024]; + sprintf(params,"[[\"%s\"]]",opid); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_getoperationresult",params)); +} + +char *jumblr_zgetoperationstatus(struct supernet_info *myinfo,struct iguana_info *coin,char *opid) +{ + char params[1024]; + sprintf(params,"[[\"%s\"]]",opid); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_getoperationstatus",params)); +} + +char *jumblr_sendt_to_z(struct supernet_info *myinfo,struct iguana_info *coin,char *taddr,char *zaddr,double amount) +{ + char params[1024]; double fee = (amount-3*JUMBLR_TXFEE) * JUMBLR_FEE; + if ( jumblr_addresstype(myinfo,coin,zaddr) != 'z' || jumblr_addresstype(myinfo,coin,taddr) != 't' ) + return(clonestr("{\"error\":\"illegal address in t to z\"}")); + sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",taddr,zaddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_sendmany",params)); +} + +char *jumblr_sendz_to_z(struct supernet_info *myinfo,struct iguana_info *coin,char *zaddrS,char *zaddrD,double amount) +{ + char params[1024]; double fee = (amount-2*JUMBLR_TXFEE) * JUMBLR_FEE; + if ( jumblr_addresstype(myinfo,coin,zaddrS) != 'z' || jumblr_addresstype(myinfo,coin,zaddrD) != 'z' ) + return(clonestr("{\"error\":\"illegal address in z to z\"}")); + sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddrS,zaddrD,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_sendmany",params)); +} + +char *jumblr_sendz_to_t(struct supernet_info *myinfo,struct iguana_info *coin,char *zaddr,char *taddr,double amount) +{ + char params[1024]; double fee = (amount-JUMBLR_TXFEE) * JUMBLR_FEE; + if ( jumblr_addresstype(myinfo,coin,zaddr) != 'z' || jumblr_addresstype(myinfo,coin,taddr) != 't' ) + return(clonestr("{\"error\":\"illegal address in z to t\"}")); + sprintf(params,"[\"%s\", [{\"address\":\"%s\",\"amount\":%.8f}, {\"address\":\"%s\",\"amount\":%.8f}], 1, %.8f]",zaddr,taddr,amount-fee-JUMBLR_TXFEE,JUMBLR_ADDR,fee,JUMBLR_TXFEE); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_sendmany",params)); +} + +char *jumblr_zlistreceivedbyaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char params[1024]; + sprintf(params,"[\"%s\", 1]",addr); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_listreceivedbyaddress",params)); +} + +char *jumblr_getreceivedbyaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char params[1024]; + sprintf(params,"[\"%s\", 1]",addr); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getreceivedbyaddress",params)); +} + +char *jumblr_importprivkey(struct supernet_info *myinfo,struct iguana_info *coin,char *wifstr) +{ + char params[1024]; + sprintf(params,"[\"%s\", \"\", false]",wifstr); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"importprivkey",params)); +} + +char *jumblr_zgetbalance(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char params[1024]; + sprintf(params,"[\"%s\", 1]",addr); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"z_getbalance",params)); +} + +char *jumblr_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) +{ + char params[1024]; + if ( coin->FULLNODE == 0 ) + return(dex_listunspent(myinfo,coin,0,0,coin->symbol,coinaddr)); + sprintf(params,"[1, 99999999, [\"%s\"]]",coinaddr); + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)); +} + +int64_t jumblr_receivedby(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char *retstr; int64_t total = 0; + if ( (retstr= jumblr_getreceivedbyaddress(myinfo,coin,addr)) != 0 ) + { + total = atof(retstr) * SATOSHIDEN; + free(retstr); + } + return(total); +} + +int64_t jumblr_balance(struct supernet_info *myinfo,struct iguana_info *coin,char *addr) +{ + char *retstr; double val; cJSON *retjson; int32_t i,n; int64_t balance = 0; + if ( jumblr_addresstype(myinfo,coin,addr) == 't' ) + { + if ( coin->FULLNODE < 0 && iguana_isnotarychain(coin->symbol) < 0 ) + { + if ( (retstr= jumblr_listunspent(myinfo,coin,addr)) != 0 ) + { + printf("jumblr.[%s].(%s)\n",coin->symbol,retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retjson)) > 0 ) + for (i=0; isymbol,addr)) != 0 ) + { + //printf("DEX retstr.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + balance = jdouble(retjson,"balance") * SATOSHIDEN; + //printf("GOT BALANCE %s %.8f\n",coin->symbol,dstr(balance)); + free_json(retjson); + } + free(retstr); + } + } + else if ( (retstr= jumblr_zgetbalance(myinfo,coin,addr)) != 0 ) + { + if ( (val= atof(retstr)) > SMALLVAL ) + balance = val * SATOSHIDEN; + free(retstr); + } + return(balance); +} + +int32_t jumblr_itemset(struct jumblr_item *ptr,cJSON *item,char *status) +{ + cJSON *params,*amounts,*dest; char *from,*addr; int32_t i,n; int64_t amount; + /*"params" : { + "fromaddress" : "RDhEGYScNQYetCyG75Kf8Fg61UWPdwc1C5", + "amounts" : [ + { + "address" : "zc9s3UdkDFTnnwHrMCr1vYy2WmkjhmTxXNiqC42s7BjeKBVUwk766TTSsrRPKfnX31Bbu8wbrTqnjDqskYGwx48FZMPHvft", + "amount" : 3.00000000 + } + ], + "minconf" : 1, + "fee" : 0.00010000 + }*/ + if ( (params= jobj(item,"params")) != 0 ) + { + //printf("params.(%s)\n",jprint(params,0)); + if ( (from= jstr(params,"fromaddress")) != 0 ) + { + safecopy(ptr->src,from,sizeof(ptr->src)); + } + if ( (amounts= jarray(&n,params,"amounts")) != 0 ) + { + for (i=0; i 0 ) + { + if ( strcmp(addr,JUMBLR_ADDR) == 0 ) + ptr->fee = amount; + else + { + ptr->amount = amount; + safecopy(ptr->dest,addr,sizeof(ptr->dest)); + } + } + } + } + ptr->txfee = jdouble(params,"fee") * SATOSHIDEN; + } + return(1); +} + +void jumblr_opidupdate(struct supernet_info *myinfo,struct iguana_info *coin,struct jumblr_item *ptr) +{ + char *retstr,*status,KMDjumblr[64],KMDdeposit[64],BTCaddr[64]; cJSON *retjson,*item; + if ( ptr->status == 0 ) + { + if ( (retstr= jumblr_zgetoperationstatus(myinfo,coin,ptr->opid)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( cJSON_GetArraySize(retjson) == 1 ) + { + item = jitem(retjson,0); + //printf("%s\n",jprint(item,0)); + if ( (status= jstr(item,"status")) != 0 ) + { + if ( strcmp(status,"success") == 0 ) + { + ptr->status = jumblr_itemset(ptr,item,status); + jumblr_privkey(myinfo,BTCaddr,0,KMDdeposit,JUMBLR_DEPOSITPREFIX); + jumblr_privkey(myinfo,BTCaddr,0,KMDjumblr,""); + if ( (jumblr_addresstype(myinfo,coin,ptr->src) == 't' && jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && strcmp(ptr->src,KMDdeposit) != 0) || (jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && jumblr_addresstype(myinfo,coin,ptr->src) == 't' && strcmp(ptr->dest,KMDjumblr) != 0) ) + { + printf("a non-jumblr t->z pruned\n"); + free(jumblr_zgetoperationresult(myinfo,coin,ptr->opid)); + ptr->status = -1; + } + + } + else if ( strcmp(status,"failed") == 0 ) + { + printf("%s failed\n",ptr->opid); + free(jumblr_zgetoperationresult(myinfo,coin,ptr->opid)); + ptr->status = -1; + } + } + } + free_json(retjson); + } + free(retstr); + } + } +} + +void jumblr_prune(struct supernet_info *myinfo,struct iguana_info *coin,struct jumblr_item *ptr) +{ + struct jumblr_item *tmp; char oldsrc[128]; int32_t flag = 1; + printf("PRUNE %s\n",ptr->opid); + strcpy(oldsrc,ptr->src); + free(jumblr_zgetoperationresult(myinfo,coin,ptr->opid)); + while ( flag != 0 ) + { + flag = 0; + HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) + { + if ( strcmp(oldsrc,ptr->dest) == 0 ) + { + printf("prune %s (%s -> %s) matched oldsrc\n",ptr->opid,ptr->src,ptr->dest); + free(jumblr_zgetoperationresult(myinfo,coin,ptr->opid)); + strcpy(oldsrc,ptr->src); + flag = 1; + break; + } + } + } +} + +void jumblr_opidsupdate(struct supernet_info *myinfo,struct iguana_info *coin) +{ + char *retstr; cJSON *array; int32_t i,n; struct jumblr_item *ptr; + if ( (retstr= jumblr_zlistoperationids(myinfo,coin)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; istatus == 0 ) + jumblr_opidupdate(myinfo,coin,ptr); + //printf("%d: %s -> %s %.8f\n",ptr->status,ptr->src,ptr->dest,dstr(ptr->amount)); + if ( jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && jumblr_addresstype(myinfo,coin,ptr->dest) == 't' ) + jumblr_prune(myinfo,coin,ptr); + } + } + } + free_json(array); + } + free(retstr); + } +} + +int64_t jumblr_DEXsplit(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *splittxidp,char *coinaddr,bits256 txid,int32_t vout,int64_t remaining,double bigprice,double middleprice,double smallprice,double fees[4],cJSON *privkeys,double esttxfee) +{ + int64_t values[4],outputs[64],value,total,estfee; int32_t i,n,success=0,completed,sendflag,numoutputs = 0; char *retstr; cJSON *retjson,*utxo,*item; + total = 0; + estfee = SATOSHIDEN * esttxfee; + memset(values,0,sizeof(values)); + memset(outputs,0,sizeof(outputs)); + if ( bigprice > SMALLVAL ) + values[0] = SATOSHIDEN * bigprice; + if ( middleprice > SMALLVAL ) + values[1] = SATOSHIDEN * middleprice; + if ( smallprice > SMALLVAL ) + values[2] = SATOSHIDEN * smallprice; + for (i=0; i<4; i++) + { + if ( fees[i] > SMALLVAL ) + values[3+i] = SATOSHIDEN * fees[i]; + } + for (i=0; i<7; i++) + { + if ( (value= values[i]) != 0 ) + { + n = 0; + while ( n < 10 && remaining > value && numoutputs < sizeof(outputs)/sizeof(*outputs) ) + { + outputs[numoutputs++] = value; + remaining -= value; + total += value; + printf("%.8f ",dstr(value)); + n++; + } + } + } + char str[65]; printf("numoutputs.%d total %.8f %s/v%d\n",numoutputs,dstr(total),bits256_str(str,txid),vout); + if ( numoutputs > 1 ) // no point to make just one + { + if ( (retstr= _dex_gettxout(myinfo,coin->symbol,txid,vout)) != 0 ) + { + item = cJSON_Parse(retstr); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + free(retstr); + if ( item != 0 ) + { + utxo = cJSON_CreateArray(); + jaddi(utxo,item); + sendflag = 0; + ///printf("jitem.(%s)\n",jprint(utxo,0)); + if ( (retstr= iguana_utxorawtx(myinfo,coin,0,coinaddr,coinaddr,outputs,numoutputs,0,&completed,sendflag,utxo,privkeys)) != 0 ) + { + if ( completed != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"error") == 0 && jobj(retjson,"sent") != 0 ) + { + *splittxidp = jbits256(retjson,"sent"); + success = 1; + printf("DEXsplit success %.8f\n",dstr(total)); + } + free_json(retjson); + } + } + free(retstr); + } + free_json(utxo); + } + } + } + return(success * total); +} + +double jumblr_DEXutxosize(double *targetvolBp,double *targetvolMp,double *targetvolSp,int32_t isbob,double kmdprice) +{ + double fee,depositfactor = (isbob == 0) ? 1. : 1.2; + fee = JUMBLR_INCR * JUMBLR_FEE; + *targetvolBp = depositfactor * kmdprice * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE); + *targetvolMp = depositfactor * kmdprice * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE); + *targetvolSp = depositfactor * kmdprice * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE); + return(depositfactor); +} + +int32_t jumblr_DEXutxoind(int32_t *shouldsplitp,double targetvolB,double targetvolM,double targetvolS,double amount,double margin,double dexfeeratio,double esttxfee) +{ + *shouldsplitp = 0; + if ( amount >= targetvolB ) + { + if ( amount > margin * (targetvolB + targetvolS) ) + *shouldsplitp = 1; + return(0); + } + else + { + if ( amount >= targetvolM ) + { + if ( amount > margin * (targetvolM + targetvolS) ) + *shouldsplitp = 1; + return(1); + } + else + { + if ( amount >= targetvolS ) + { + if ( amount > margin * targetvolS ) + *shouldsplitp = 1; + return(2); + } + else if ( amount >= targetvolB/dexfeeratio ) + { + if ( amount > margin * targetvolB/dexfeeratio ) + *shouldsplitp = 1; + return(3); + } + else if ( amount >= targetvolM/dexfeeratio ) + { + if ( amount > margin * targetvolM/dexfeeratio ) + *shouldsplitp = 1; + return(4); + } + else if ( amount >= targetvolS/dexfeeratio ) + { + if ( amount > margin * targetvolS/dexfeeratio ) + *shouldsplitp = 1; + return(5); + } + else if ( amount >= esttxfee ) + { + if ( amount > esttxfee*4 ) + *shouldsplitp = 1; + return(6); + } + else return(-1); + } + } +} + +int32_t jumblr_DEXutxoupdate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *shouldsplitp,bits256 *splittxidp,char *coinaddr,bits256 privkey,bits256 txid,int32_t vout,uint64_t value,int32_t isbob,double kmdprice,double estfee) +{ + double fees[4],targetvolB,amount,targetvolM,targetvolS,depositfactor,dexfeeratio,margin; int32_t ind = -1,i; cJSON *privkeys; char wifstr[128]; + *shouldsplitp = 0; + margin = 1.1; + depositfactor = (isbob == 0) ? 1. : 1.2; + dexfeeratio = 500.; + amount = dstr(value); + memset(splittxidp,0,sizeof(*splittxidp)); + depositfactor = jumblr_DEXutxosize(&targetvolB,&targetvolM,&targetvolS,isbob,kmdprice); + printf("depositfactor %.8f targetvols %.8f %.8f %.8f\n",depositfactor,targetvolB,targetvolM,targetvolS); + fees[0] = (margin * targetvolB) / dexfeeratio; + fees[1] = (margin * targetvolM) / dexfeeratio; + fees[2] = (margin * targetvolS) / dexfeeratio; + fees[3] = (strcmp("BTC",coin->symbol) == 0) ? 50000 : 10000; + for (i=0; i<4; i++) + if ( fees[i] < 10000 ) + fees[i] = 10000; + if ( (ind= jumblr_DEXutxoind(shouldsplitp,targetvolB,targetvolM,targetvolS,amount,margin,dexfeeratio,fees[3])) >= 0 ) + { + printf("shouldsplit.%d ind.%d\n",*shouldsplitp,ind); + if ( *shouldsplitp != 0 ) + { + privkeys = cJSON_CreateArray(); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + jaddistr(privkeys,wifstr); + if ( jumblr_DEXsplit(myinfo,coin,splittxidp,coinaddr,txid,vout,value,margin * targetvolB,margin * targetvolM,margin * targetvolS,fees,privkeys,estfee) > 0 ) + ind = -1; + else *shouldsplitp = 0; + free_json(privkeys); + } + } // else printf("negative ind\n"); + return(ind); +} + +/*struct DEXcoin_info + { + bits256 deposit_privkey,jumblr_privkey; + struct iguana_info *coin; + cJSON *utxos,*spentutxos,*bigutxos,*normalutxos,*smallutxos,*feeutxos,*otherutxos; + double btcprice,USD_average,DEXpending,maxbid,minask,avail,KMDavail; + uint32_t lasttime; + char CMCname[32],symbol[16],depositaddr[64],KMDdepositaddr[64],KMDjumblraddr[64],jumblraddr[64]; + };*/ + +int32_t jumblr_utxotxidpending(struct supernet_info *myinfo,bits256 *splittxidp,int32_t *indp,struct iguana_info *coin,bits256 txid,int32_t vout) +{ + int32_t i; + memset(splittxidp,0,sizeof(*splittxidp)); + for (i=0; iDEXinfo.numpending; i++) + { + if ( coin->DEXinfo.pending[i].vout == vout && bits256_cmp(coin->DEXinfo.pending[i].txid,txid) == 0 ) + { + *indp = coin->DEXinfo.pending[i].ind; + *splittxidp = coin->DEXinfo.pending[i].splittxid; + // printf("jumblr_utxotxidpending found txid in slot.%d\n",i); + return(i); + } + } + // printf("jumblr_utxotxidpending cant find txid\n"); + return(-1); +} + +void jumblr_utxotxidpendingadd(struct supernet_info *myinfo,char *dest,struct iguana_info *coin,bits256 txid,int32_t vout,uint64_t value,bits256 splittxid,int32_t ind,double price,double estfee,int32_t shouldsplit) +{ + struct jumblr_pending pend; cJSON *vals,*retjson; bits256 hash; char *retstr; + memset(&pend,0,sizeof(pend)); + pend.splittxid = splittxid; + pend.txid = txid; + pend.vout = vout; + pend.ind = ind; + if ( 0 && myinfo->IAMLP == 0 && shouldsplit == 0 && ind < 3 ) + { + static uint32_t num; + if ( num == 0 && price > SMALLVAL ) + { + num++; + vals = cJSON_CreateObject(); + jaddstr(vals,"source",coin->symbol); + jaddstr(vals,"dest",dest); + jaddnum(vals,"amount",price * 100);//dstr(value) - estfee); + jaddnum(vals,"minprice",price); + jaddnum(vals,"usejumblr",1); + memset(hash.bytes,0,sizeof(hash)); + if ( (retstr= InstantDEX_request(myinfo,coin,0,0,hash,vals,"")) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free_json(retjson); + } + free(retstr); + } + free_json(vals); + } + } + coin->DEXinfo.pending = realloc(coin->DEXinfo.pending,sizeof(*coin->DEXinfo.pending) * (1 + coin->DEXinfo.numpending)); + coin->DEXinfo.pending[coin->DEXinfo.numpending++] = pend; +} + +void jumblr_utxoupdate(struct supernet_info *myinfo,char *dest,struct iguana_info *coin,double price,char *coinaddr,bits256 privkey,double estfee) +{ + char *retstr; cJSON *array,*item; int32_t shouldsplit,i,n,vout,ind; bits256 txid,splittxid; uint64_t value; + if ( (retstr= jumblr_listunspent(myinfo,coin,coinaddr)) != 0 ) + { + //printf("%s.(%s)\n",coin->symbol,retstr); + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; iIAMLP,price,estfee); + jumblr_utxotxidpendingadd(myinfo,dest,coin,txid,vout,value,splittxid,ind,price,estfee,shouldsplit); + } + else + { + // update status of utxo + } + } + } + free_json(array); + } + free(retstr); + } +} + +void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int32_t selector,int32_t modval) +{ + //static uint32_t lasttime; + char BTCaddr[64],KMDaddr[64],*zaddr,*retstr; int32_t iter,counter,chosen_one,n; bits256 privkey; uint64_t amount=0,total=0; double fee; struct jumblr_item *ptr,*tmp; uint8_t r,s; + if ( myinfo->IAMNOTARY != 0 ) + return; + fee = JUMBLR_INCR * JUMBLR_FEE; + OS_randombytes(&r,sizeof(r)); +//r = 0; + // randomize size chosen and order of chunks + if ( strcmp(coin->symbol,"KMD") == 0 && coin->FULLNODE < 0 ) + { + s = (selector + (r>>1)) % 3; + //printf("JUMBLR selector.%d modval.%d r.%d\n",selector,modval,r&7); + switch ( s ) + { + case 0: // public -> z, need to importprivkey + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,JUMBLR_DEPOSITPREFIX); + if ( (total= jumblr_balance(myinfo,coin,KMDaddr)) >= (JUMBLR_INCR + 3*(fee+JUMBLR_TXFEE))*SATOSHIDEN ) + { + if ( (r & 1) == 0 ) + { + if ( (zaddr= jumblr_zgetnewaddress(myinfo,coin)) != 0 ) + { + amount = 0; + if ( total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE) ) + amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*100 + 3*JUMBLR_TXFEE); + if ( (r & 2) != 0 && total >= SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE) ) + amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee)*10 + 3*JUMBLR_TXFEE); + if ( (r & 4) != 0 ) + amount = SATOSHIDEN * ((JUMBLR_INCR + 3*fee) + 3*JUMBLR_TXFEE); + if ( amount > 0 && (retstr= jumblr_sendt_to_z(myinfo,coin,KMDaddr,zaddr,dstr(amount))) != 0 ) + { + printf("sendt_to_z.(%s)\n",retstr); + free(retstr); + } + free(zaddr); + } else printf("no zaddr from jumblr_zgetnewaddress\n"); + } + } else printf("%s total %.8f vs %.8f\n",KMDaddr,dstr(total),(JUMBLR_INCR + 3*(fee+JUMBLR_TXFEE))); + break; + case 1: // z -> z + jumblr_opidsupdate(myinfo,coin); + chosen_one = -1; + for (iter=counter=0; iter<2; iter++) + { + counter = n = 0; + HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) + { + if ( jumblr_addresstype(myinfo,coin,ptr->src) == 't' && jumblr_addresstype(myinfo,coin,ptr->dest) == 'z' ) + { + if ( (r & 1) == 0 && ptr->spent == 0 && (total= jumblr_balance(myinfo,coin,ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) + { + if ( iter == 1 && counter == chosen_one ) + { + if ( (zaddr= jumblr_zgetnewaddress(myinfo,coin)) != 0 ) + { + if ( (retstr= jumblr_sendz_to_z(myinfo,coin,ptr->dest,zaddr,dstr(total))) != 0 ) + { + printf("n.%d counter.%d chosen_one.%d sendz_to_z.(%s)\n",n,counter,chosen_one,retstr); + free(retstr); + } + ptr->spent = (uint32_t)time(NULL); + free(zaddr); + break; + } + } + counter++; + } + } + n++; + } + if ( counter == 0 ) + break; + if ( iter == 0 ) + { + OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one)); + if ( chosen_one < 0 ) + chosen_one = -chosen_one; + chosen_one %= counter; + printf("jumblr z->z chosen_one.%d of %d, from %d\n",chosen_one,counter,n); + } + } + break; + case 2: // z -> public + if ( myinfo->runsilent == 0 ) + { + jumblr_opidsupdate(myinfo,coin); + chosen_one = -1; + for (iter=0; iter<2; iter++) + { + counter = n = 0; + HASH_ITER(hh,myinfo->jumblrs,ptr,tmp) + { + if ( jumblr_addresstype(myinfo,coin,ptr->src) == 'z' && jumblr_addresstype(myinfo,coin,ptr->dest) == 'z' ) + { + if ( (r & 1) == 0 && ptr->spent == 0 && (total= jumblr_balance(myinfo,coin,ptr->dest)) >= (fee + JUMBLR_FEE)*SATOSHIDEN ) + { + if ( iter == 1 && n == chosen_one ) + { + privkey = jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,""); + if ( (retstr= jumblr_sendz_to_t(myinfo,coin,ptr->dest,KMDaddr,dstr(total))) != 0 ) + { + printf("sendz_to_t.(%s)\n",retstr); + free(retstr); + } + ptr->spent = (uint32_t)time(NULL); + break; + } + counter++; + } + } + n++; + } + if ( counter == 0 ) + break; + if ( iter == 0 ) + { + OS_randombytes((uint8_t *)&chosen_one,sizeof(chosen_one)); + if ( chosen_one < 0 ) + chosen_one = -chosen_one; + chosen_one %= counter; + printf("jumblr z->t chosen_one.%d of %d, from %d\n",chosen_one,counter,n); + } + } + } + break; + } + } +} + diff --git a/basilisk/smartaddress.c b/basilisk/smartaddress.c new file mode 100755 index 000000000..727a54709 --- /dev/null +++ b/basilisk/smartaddress.c @@ -0,0 +1,685 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c + +// deposit address -> corresponding KMD address, if KMD deposit starts JUMBLR +// jumblr address is the destination of JUMBLR and JUMBLR BTC (would need tracking to map back to non-BTC) +// address is DEX'ed for + +// return value convention: -1 error, 0 partial match, >= 1 exact match + +int32_t smartaddress_type(char *typestr) +{ + char upper[64]; + if ( strcmp(typestr,"deposit") != 0 && strcmp(typestr,"jumblr") != 0 && strcmp(typestr,"dividend") != 0 && strcmp(typestr,"pangea") != 0 ) + { + upper[sizeof(upper)-1] = 0; + strncpy(upper,typestr,sizeof(upper)-1); + touppercase(upper); + if ( iguana_coinfind(upper) != 0 ) + return(0); + else return(-1); + } + return(1); +} + +bits256 jumblr_privkey(struct supernet_info *myinfo,char *coinaddr,uint8_t pubtype,char *KMDaddr,char *prefix) +{ + bits256 privkey,pubkey; uint8_t pubkey33[33]; char passphrase[sizeof(myinfo->jumblr_passphrase) + 64]; + sprintf(passphrase,"%s%s",prefix,myinfo->jumblr_passphrase); + if ( myinfo->jumblr_passphrase[0] == 0 ) + strcpy(myinfo->jumblr_passphrase,"password"); + conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); + bitcoin_address(coinaddr,pubtype,pubkey33,33); + bitcoin_address(KMDaddr,60,pubkey33,33); + //printf("(%s) -> (%s %s)\n",passphrase,coinaddr,KMDaddr); + return(privkey); +} + +cJSON *smartaddress_extrajson(struct smartaddress *ap) +{ + cJSON *retjson = cJSON_CreateObject(); + if ( strcmp(ap->typestr,"dividend") == 0 ) + { + + } + return(retjson); +} + +cJSON *smartaddress_json(struct smartaddress *ap) +{ + char coinaddr[64],symbol[64]; uint8_t desttype,tmp,rmd160[20]; int32_t j,n; struct iguana_info *coin,*dest; cJSON *array,*item,*retjson; double amount; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"type",ap->typestr); + strcpy(symbol,ap->typestr), touppercase(symbol); + if ( (dest= iguana_coinfind(symbol)) != 0 ) + desttype = dest->chain->pubtype; + else desttype = 60; + if ( (n= ap->numsymbols) > 0 ) + { + array = cJSON_CreateArray(); + for (j=0; jsymbols[j].symbol)) != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,ap->pubkey33,33); + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddstr(item,"address",coinaddr); + if ( (amount= ap->symbols[j].srcavail) != 0 ) + jaddnum(item,"sourceamount",amount); + if ( dest != 0 ) + { + bitcoin_addr2rmd160(&tmp,rmd160,coinaddr); + bitcoin_address(coinaddr,desttype,rmd160,20); + jaddstr(item,"dest",coinaddr); + if ( (amount= ap->symbols[j].destamount) != 0 ) + jaddnum(item,"destamount",amount); + if ( coin->DEXinfo.depositaddr[0] != 0 ) + { + jaddstr(item,"jumblr_deposit",coin->DEXinfo.depositaddr); + jaddnum(item,"deposit_avail",coin->DEXinfo.avail); + } + if ( coin->DEXinfo.jumblraddr[0] != 0 ) + { + jaddstr(item,"jumblr",coin->DEXinfo.jumblraddr); + jaddnum(item,"jumblr_avail",coin->DEXinfo.jumblravail); + } + if ( ap->symbols[j].maxbid != 0. ) + jaddnum(item,"maxbid",ap->symbols[j].maxbid); + if ( ap->symbols[j].minask != 0. ) + jaddnum(item,"minask",ap->symbols[j].minask); + } + jadd(item,"extra",smartaddress_extrajson(ap)); + jaddi(array,item); + } + } + jadd(retjson,"coins",array); + } + return(retjson); +} + +void smartaddress_symboladd(struct smartaddress *ap,char *symbol,double maxbid,double minask) +{ + char tmp[64]; struct smartaddress_symbol *sp; + strcpy(tmp,ap->typestr), touppercase(tmp); + if ( strcmp(tmp,symbol) != 0 ) + { + ap->symbols = realloc(ap->symbols,(ap->numsymbols+1) * sizeof(*ap->symbols)); + sp = &ap->symbols[ap->numsymbols++]; + memset(sp,0,sizeof(*sp)); + safecopy(sp->symbol,symbol,sizeof(sp->symbol)); + sp->maxbid = maxbid; + sp->minask = minask; + printf("symboladd.%d (%s) <- (%s %f %f)\n",ap->numsymbols,ap->typestr,symbol,maxbid,minask); + } +} + +struct smartaddress *smartaddressptr(struct smartaddress_symbol **ptrp,struct supernet_info *myinfo,char *_type,char *_symbol) +{ + char type[64],symbol[64]; int32_t i,j,n; struct smartaddress *ap; + if ( ptrp != 0 ) + *ptrp = 0; + strcpy(type,_type), tolowercase(type); + strcpy(symbol,_symbol), touppercase(symbol); + for (i=0; inumsmartaddrs; i++) + { + ap = &myinfo->smartaddrs[i]; + if ( strcmp(type,ap->typestr) == 0 ) + { + n = ap->numsymbols; + for (j=0; jsymbols[j].symbol,symbol) == 0 ) + { + if ( ptrp != 0 ) + *ptrp = &ap->symbols[j]; + return(ap); + } + } + } + } + return(0); +} + +void smartaddress_minmaxupdate(struct supernet_info *myinfo,char *_type,char *_symbol,double maxbid,double minask) +{ + struct smartaddress *ap; struct smartaddress_symbol *sp; + if ( (ap= smartaddressptr(&sp,myinfo,_type,_symbol)) != 0 && sp != 0 ) + { + dxblend(&sp->maxbid,maxbid,0.5); + dxblend(&sp->minask,minask,0.5); + } +} + +void smartaddress_availupdate(struct supernet_info *myinfo,char *_type,char *_symbol,double srcavail,double destamount) +{ + struct smartaddress *ap; struct smartaddress_symbol *sp; + if ( (ap= smartaddressptr(&sp,myinfo,_type,_symbol)) != 0 && sp != 0 ) + { + if ( srcavail > SMALLVAL ) + sp->srcavail = srcavail; + if ( destamount > SMALLVAL ) + sp->destamount = destamount; + } +} + +int32_t _smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *type,char *symbol,double maxbid,double minask) +{ + char coinaddr[64]; uint8_t addrtype,rmd160[20]; struct smartaddress *ap; int32_t i,j,n; + if ( myinfo->numsmartaddrs < sizeof(myinfo->smartaddrs)/sizeof(*myinfo->smartaddrs) ) + { + for (i=0; inumsmartaddrs; i++) + { + ap = &myinfo->smartaddrs[i]; + if ( strcmp(type,ap->typestr) == 0 && bits256_cmp(ap->privkey,privkey) == 0 ) + { + n = ap->numsymbols; + for (j=0; jsymbols[j].symbol,symbol) == 0 ) + { + ap->symbols[j].maxbid = maxbid; + ap->symbols[j].minask = minask; + if ( maxbid > SMALLVAL && minask > SMALLVAL && smartaddress_type(type) == 0 ) + smartaddress_minmaxupdate(myinfo,symbol,type,1./minask,1./maxbid); + return(0); + } + } + smartaddress_symboladd(ap,symbol,maxbid,minask); + return(i+1); + } + } + ap = &myinfo->smartaddrs[myinfo->numsmartaddrs]; + if ( smartaddress_type(symbol) < 0 ) + return(-1); + strcpy(ap->typestr,type); + smartaddress_symboladd(ap,"KMD",0.,0.); + smartaddress_symboladd(ap,"BTC",0.,0.); + ap->privkey = privkey; + bitcoin_pubkey33(myinfo->ctx,ap->pubkey33,privkey); + calc_rmd160_sha256(ap->rmd160,ap->pubkey33,33); + ap->pubkey = curve25519(privkey,curve25519_basepoint9()); + char str[65]; printf("pubkey.(%s) ",bits256_str(str,ap->pubkey)); + bitcoin_address(coinaddr,0,ap->pubkey33,33); + for (i=0; i<20; i++) + printf("%02x",ap->rmd160[i]); + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + printf(", "); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf (" <- rmd160 for %d %s\n",myinfo->numsmartaddrs,coinaddr); + return(++myinfo->numsmartaddrs + 1); + } + printf("too many smartaddresses %d vs %d\n",myinfo->numsmartaddrs,(int32_t)(sizeof(myinfo->smartaddrs)/sizeof(*myinfo->smartaddrs))); + return(-1); +} + +int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *type,char *symbol,double maxbid,double minask) +{ + int32_t retval; + portable_mutex_lock(&myinfo->smart_mutex); + retval = _smartaddress_add(myinfo,privkey,type,symbol,maxbid,minask); + portable_mutex_unlock(&myinfo->smart_mutex); + return(retval); +} + +int32_t smartaddress_symbolmatch(char *typestr,double *bidaskp,struct smartaddress *ap,char *symbol) +{ + int32_t j,n; + strcpy(typestr,ap->typestr); + if ( (n= ap->numsymbols) > 0 ) + { + for (j=0; jsymbols[j].symbol,symbol) == 0 ) + { + bidaskp[0] = ap->symbols[j].maxbid; + bidaskp[1] = ap->symbols[j].minask; + return(j); + } + } + } + return(-1); +} + +int32_t smartaddress(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,char *coinaddr) +{ + int32_t i,j,retval = -1; uint8_t addrtype,rmd160[20]; struct smartaddress *ap; + memset(privkeyp,0,sizeof(*privkeyp)); + memset(bidaskp,0,sizeof(*bidaskp) * 2); + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + portable_mutex_lock(&myinfo->smart_mutex); + for (i=0; inumsmartaddrs; i++) + if ( memcmp(myinfo->smartaddrs[i].rmd160,rmd160,20) == 0 ) + { + ap = &myinfo->smartaddrs[i]; + *privkeyp = ap->privkey; + if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 ) + retval = 0; + else retval = (i+1); + break; + } + portable_mutex_unlock(&myinfo->smart_mutex); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 smartaddress cant find (%s) of %d\n",coinaddr,myinfo->numsmartaddrs); + return(retval); +} + +int32_t smartaddress_pubkey(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,bits256 pubkey) +{ + int32_t i,j,retval = -1; struct smartaddress *ap; + memset(privkeyp,0,sizeof(*privkeyp)); + memset(bidaskp,0,sizeof(*bidaskp) * 2); + if ( bits256_cmp(myinfo->myaddr.persistent,pubkey) == 0 ) + { + *privkeyp = myinfo->persistent_priv; + return(myinfo->numsmartaddrs); + } + portable_mutex_lock(&myinfo->smart_mutex); + for (i=0; inumsmartaddrs; i++) + if ( bits256_cmp(myinfo->smartaddrs[i].pubkey,pubkey) == 0 ) + { + ap = &myinfo->smartaddrs[i]; + *privkeyp = ap->privkey; + if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 ) + retval = 0; + else retval = (i+1); + break; + } + portable_mutex_unlock(&myinfo->smart_mutex); + //char str[65]; if ( retval < 0 ) + // printf("smartaddress_pubkey no match for %s\n",bits256_str(str,pubkey)); + return(retval); +} + +int32_t smartaddress_pubkey33(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,uint8_t *pubkey33) +{ + int32_t i,j,retval = -1; struct smartaddress *ap; + memset(privkeyp,0,sizeof(*privkeyp)); + memset(bidaskp,0,sizeof(*bidaskp) * 2); + portable_mutex_lock(&myinfo->smart_mutex); + for (i=0; inumsmartaddrs; i++) + if ( memcmp(myinfo->smartaddrs[i].pubkey33,pubkey33,33) == 0 ) + { + ap = &myinfo->smartaddrs[i]; + *privkeyp = ap->privkey; + if ( (j= smartaddress_symbolmatch(typestr,bidaskp,ap,symbol)) >= 0 ) + retval = 0; + else retval = (i+1); + break; + } + portable_mutex_unlock(&myinfo->smart_mutex); + return(retval); +} + +void smartaddress_CMCname(char *CMCname,char *symbol) +{ + if ( strcmp(symbol,"KMD") == 0 ) + strcpy(CMCname,"komodo"); + else if ( strcmp(symbol,"BTC") == 0 ) + strcpy(CMCname,"bitcoin"); +} + +void smartaddress_coinupdate(struct supernet_info *myinfo,char *symbol,double BTC2KMD,double KMDavail,double KMD2USD) +{ + int32_t r; double avebid,aveask,highbid,lowask,CMC_average,changes[3]; struct iguana_info *coin; struct DEXcoin_info *ptr; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + ptr = &coin->DEXinfo; + ptr->coin = coin; + if ( coin->CMCname[0] == 0 ) + smartaddress_CMCname(coin->CMCname,symbol); + r = (((symbol[0]^symbol[1]^symbol[2])&0x7f) % 15) - 7; // 53 to 67 seconds + if ( time(NULL) > (ptr->lasttime + 60 + r) ) + { + if ( strcmp(symbol,ptr->symbol) != 0 ) + { + safecopy(ptr->symbol,symbol,sizeof(ptr->symbol)); + safecopy(ptr->CMCname,coin->CMCname,sizeof(ptr->CMCname)); + } + ptr->deposit_privkey = jumblr_privkey(myinfo,ptr->depositaddr,coin->chain->pubtype,ptr->KMDdepositaddr,JUMBLR_DEPOSITPREFIX); + ptr->jumblr_privkey = jumblr_privkey(myinfo,ptr->jumblraddr,coin->chain->pubtype,ptr->KMDjumblraddr,""); + ptr->avail = dstr(jumblr_balance(myinfo,coin,ptr->depositaddr)); + ptr->jumblravail = dstr(jumblr_balance(myinfo,ptr->coin,ptr->jumblraddr)); + if ( strcmp(symbol,"USD") == 0 ) + { + if ( KMD2USD > SMALLVAL ) + { + ptr->kmdprice = 1./ KMD2USD; + if ( (ptr->BTC2KMD= BTC2KMD) > SMALLVAL ) + ptr->btcprice = ptr->kmdprice * BTC2KMD; + } + printf("USD btcprice %.8f kmdprice %.8f\n",ptr->btcprice,ptr->kmdprice); + } + else + { + if ( strcmp(symbol,"BTC") == 0 ) + ptr->btcprice = 1.; + else if ( coin->CMCname[0] != 0 && (ptr->btcprice == 0. || (ptr->counter++ % 10) == 0) ) + ptr->btcprice = get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,coin->CMCname,symbol,"BTC",&ptr->USD_average); + if ( strcmp("KMD",symbol) == 0 ) + ptr->kmdprice = 1.; + else if ( (ptr->BTC2KMD= BTC2KMD) > SMALLVAL ) + ptr->kmdprice = ptr->btcprice / BTC2KMD; + } + ptr->lasttime = (uint32_t)time(NULL); + printf("%s avail %.8f KMDavail %.8f btcprice %.8f deposit.(%s %s) -> jumblr.(%s %s)\n",symbol,ptr->avail,KMDavail,ptr->btcprice,ptr->depositaddr,ptr->KMDdepositaddr,ptr->jumblraddr,ptr->KMDjumblraddr); + } + } // else printf("skip\n"); +} + +void smartaddress_dex(struct supernet_info *myinfo,char *type,int32_t selector,struct iguana_info *basecoin,char *coinaddr,double maxavail,struct iguana_info *relcoin,double maxbid,double minask,cJSON *extraobj,double maxvol) +{ + double minamount,minbtc,price,avail,vol,btc2kmd,basebtc,relbtc,baseusd,relusd; char *retstr; cJSON *vals; bits256 hash; struct smartaddress *ap; + basebtc = basecoin->DEXinfo.btcprice; + relbtc = relcoin->DEXinfo.btcprice; + baseusd = basecoin->DEXinfo.USD_average; + relusd = relcoin->DEXinfo.USD_average; + if ( (btc2kmd= basecoin->DEXinfo.BTC2KMD) < SMALLVAL && (btc2kmd= relcoin->DEXinfo.BTC2KMD) < SMALLVAL ) + return; + minamount = price = 0.; + if ( basebtc < SMALLVAL && relbtc < SMALLVAL ) + return; + if ( myinfo->DEXratio < .95 || myinfo->DEXratio > 1.01 ) + myinfo->DEXratio = 0.995; + if ( basebtc < SMALLVAL || relbtc < SMALLVAL ) + { + if ( (price= maxbid) > SMALLVAL ) + { + if ( basebtc < SMALLVAL ) + basebtc = price * relbtc, printf("calculated basebtc %.8f from (%.8f * %.8f)\n",basebtc,price,relbtc); + else if ( relbtc < SMALLVAL ) + relbtc = basebtc / price, printf("calculated relbtc %.8f from (%.8f / %.8f)\n",relbtc,basebtc,price); // price * relbtc == basebtc + } + } else price = myinfo->DEXratio * (basebtc / relbtc); + minbtc = btc2kmd * (JUMBLR_INCR + 3*(JUMBLR_INCR * JUMBLR_FEE + JUMBLR_TXFEE)); + if ( minamount == 0. && basebtc > SMALLVAL ) + minamount = (minbtc / basebtc); + printf("DEX %s/%s maxavail %.8f minbtc %.8f btcprice %.8f -> minamount %.8f price %.8f vs maxbid %.8f DEXratio %.5f DEXpending %.8f\n",basecoin->symbol,relcoin->symbol,maxavail,minbtc,basecoin->DEXinfo.btcprice,minamount,price,maxbid,myinfo->DEXratio,basecoin->DEXinfo.DEXpending); + if ( minamount > SMALLVAL && maxavail > minamount + basecoin->DEXinfo.DEXpending && (maxbid == 0. || price <= maxbid) ) + { + avail = (maxavail - basecoin->DEXinfo.DEXpending); + /*if ( avail >= (100. * minamount) ) + vol = (100. * minamount); + else if ( avail >= (10. * minamount) ) + vol = (10. * minamount); + else*/ if ( avail >= minamount ) + vol = minamount; + else vol = 0.; + if ( vol > 0. ) + { + vals = cJSON_CreateObject(); + jaddstr(vals,"source",basecoin->symbol); + jaddstr(vals,"dest",relcoin->symbol); + jaddnum(vals,"amount",vol); + jaddnum(vals,"minprice",price); + if ( (ap= smartaddressptr(0,myinfo,type,basecoin->symbol)) != 0 ) + jaddbits256(vals,"srchash",ap->pubkey); + if ( selector != 0 ) + { + jaddnum(vals,"usejumblr",selector); + jaddnum(vals,"DEXselector",selector); + } + memset(hash.bytes,0,sizeof(hash)); + basecoin->DEXinfo.DEXpending += vol; + if ( (retstr= InstantDEX_request(myinfo,basecoin,0,0,hash,vals,"")) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free(retstr); + } + free_json(vals); + } else printf("avail %.8f < minamount %.8f\n",avail,minamount); + } //else printf("failed if check %d %d %d %d\n",minamount > SMALLVAL,maxavail > minamount + basecoin->DEXinfo.DEXpending,maxbid == 0,price <= maxbid); + /* + minbtc = (basecoin->DEXinfo.btcprice * 1.2) * (JUMBLR_INCR + 3*(JUMBLR_INCR * JUMBLR_FEE + JUMBLR_TXFEE)); + btcavail = dstr(jumblr_balance(myinfo,coinbtc,kmdcoin->DEXinfo.depositaddr)); + avail = (btcavail - coinbtc->DEXinfo.DEXpending); + printf("BTC.%d deposits %.8f, min %.8f avail %.8f pending %.8f\n",toKMD,btcavail,minbtc,avail,coinbtc->DEXinfo.DEXpending); + if ( toKMD == 0 && coinbtc != 0 && btcavail > (minbtc + coinbtc->DEXinfo.DEXpending) ) + { + if ( vol > 0. ) + { + vals = cJSON_CreateObject(); + jaddstr(vals,"source","BTC"); + jaddstr(vals,"dest","KMD"); + jaddnum(vals,"amount",vol); + jaddnum(vals,"minprice",0.985/kmdcoin->DEXinfo.btcprice); + jaddnum(vals,"usejumblr",1); + jaddnum(vals,"DEXselector",1); + memset(hash.bytes,0,sizeof(hash)); + coinbtc->DEXinfo.DEXpending += vol; + if ( (retstr= InstantDEX_request(myinfo,coinbtc,0,0,hash,vals,"")) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free(retstr); + } + free_json(vals); + // curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"KMD\",\"amount\":20,\"dest\":\"USD\",\"minprice\":0.08}}" + } + } //else printf("btcavail %.8f pending %.8f\n",btcavail,pending); + minkmd = 100.; + avail = (kmdcoin->DEXinfo.KMDavail - kmdcoin->DEXinfo.DEXpending); + printf("KMD.%d deposits %.8f, min %.8f, avail %.8f pending %.8f\n",toKMD,kmdcoin->DEXinfo.KMDavail,minkmd,avail,kmdcoin->DEXinfo.DEXpending); + if ( toKMD != 0 && coinbtc != 0 && kmdcoin->DEXinfo.KMDavail > (minkmd + kmdcoin->DEXinfo.DEXpending) ) + { + if ( avail > 100.*JUMBLR_INCR ) + vol = 100.*JUMBLR_INCR; + else if ( avail > 10.*JUMBLR_INCR ) + vol = 10.*JUMBLR_INCR; + else if ( avail >= JUMBLR_INCR ) + vol = JUMBLR_INCR; + else vol = 0.; + if ( vol > 0. ) + { + vals = cJSON_CreateObject(); + jaddstr(vals,"source","KMD"); + jaddstr(vals,"dest","BTC"); + jaddnum(vals,"amount",vol); + //jaddnum(vals,"destamount",JUMBLR_INCR*kmdcoin->DEXinfo.btcprice); + jaddnum(vals,"minprice",0.985 * kmdcoin->DEXinfo.btcprice); + jaddnum(vals,"usejumblr",2); + memset(hash.bytes,0,sizeof(hash)); + kmdcoin->DEXinfo.DEXpending += vol; + jaddnum(vals,"DEXselector",2); + if ( (retstr= InstantDEX_request(myinfo,coinbtc,0,0,hash,vals,"")) != 0 ) + { + printf("request.(%s) -> (%s)\n",jprint(vals,0),retstr); + free(retstr); + } + free_json(vals); + } + } else printf("kmdavail %.8f pending %.8f\n",kmdcoin->DEXinfo.avail,kmdcoin->DEXinfo.DEXpending);*/ +} + +void smartaddress_depositjumblr(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + struct iguana_info *basecoin,*relcoin; + if ( (basecoin= iguana_coinfind(symbol)) != 0 && (relcoin= iguana_coinfind("KMD")) != 0 ) + { + if ( strcmp(coinaddr,basecoin->DEXinfo.depositaddr) == 0 ) + smartaddress_dex(myinfo,"deposit",1,basecoin,coinaddr,basecoin->DEXinfo.avail,relcoin,maxbid,minask,extraobj,0.); + else printf("smartaddress_jumblr.%s: mismatch deposit address (%s) vs (%s)\n",symbol,coinaddr,basecoin->DEXinfo.depositaddr); + } +} + +double smartaddress_jumblrcredit(struct supernet_info *myinfo,char *symbol) +{ + return(0.); // default to BTC conversion for now +} + +void smartaddress_jumblr(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + struct iguana_info *basecoin,*relcoin; double credits = 0.; + if ( strcmp("BTC",symbol) != 0 ) + { + if ( (credits= smartaddress_jumblrcredit(myinfo,symbol)) <= 0. ) + return; + } + if ( (basecoin= iguana_coinfind("KMD")) != 0 && (relcoin= iguana_coinfind(symbol)) != 0 ) + { + if ( strcmp(coinaddr,basecoin->DEXinfo.jumblraddr) == 0 ) + smartaddress_dex(myinfo,"jumblr",2,basecoin,coinaddr,basecoin->DEXinfo.jumblravail,relcoin,maxbid,minask,extraobj,credits); + else printf("smartaddress_jumblr.%s: mismatch jumblr address (%s) vs (%s)\n",symbol,coinaddr,basecoin->DEXinfo.jumblraddr); + } +} + +void smartaddress_dividend(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + // support list of weighted addresses, including snapshots +} + +void smartaddress_pangea(struct supernet_info *myinfo,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + // table deposit +} + +void smartaddress_action(struct supernet_info *myinfo,int32_t selector,char *typestr,char *symbol,char *coinaddr,double maxbid,double minask,cJSON *extraobj) +{ + char rel[64]; struct iguana_info *basecoin,*relcoin; double avail; + if ( strcmp(typestr,"deposit") == 0 && selector == 0 ) + smartaddress_depositjumblr(myinfo,symbol,coinaddr,maxbid,minask,extraobj); + else if ( strcmp(typestr,"jumblr") == 0 && selector == 0 ) + smartaddress_jumblr(myinfo,symbol,coinaddr,maxbid,minask,extraobj); + else if ( strcmp(typestr,"dividend") == 0 && selector == 0 ) + smartaddress_dividend(myinfo,symbol,coinaddr,maxbid,minask,extraobj); + else if ( strcmp(typestr,"pangea") == 0 && selector == 0 ) + smartaddress_pangea(myinfo,symbol,coinaddr,maxbid,minask,extraobj); + else + { + safecopy(rel,typestr,sizeof(rel)); + touppercase(rel); + if ( (relcoin= iguana_coinfind(rel)) != 0 && (basecoin= iguana_coinfind(symbol)) != 0 ) + { + if ( myinfo->numswaps == 0 )//|| (basecoin->FULLNODE < 0 && relcoin->FULLNODE < 0) ) + { + if ( (avail= dstr(jumblr_balance(myinfo,basecoin,coinaddr))) > SMALLVAL ) + { + smartaddress_availupdate(myinfo,typestr,symbol,avail,SMALLVAL*0.99); + smartaddress_dex(myinfo,typestr,0,basecoin,coinaddr,avail,relcoin,maxbid,minask,extraobj,0.); + } + } + } + } +} + +void smartaddress_update(struct supernet_info *myinfo,int32_t selector) +{ + double maxbid,minask; uint8_t addrtype,rmd160[20]; char *smartstr,*typestr,*symbol,*address,coinaddr[64]; cJSON *smartarray,*extraobj,*item,*array,*coinitem; int32_t iter,i,n,j,m; struct iguana_info *kmdcoin,*coinbtc = 0; + //printf("smartaddress_update numswaps.%d notary.%d IAMLP.%d %p %p %f\n",myinfo->numswaps,myinfo->IAMNOTARY,myinfo->IAMLP,kmdcoin,coinbtc,kmdcoin->DEXinfo.btcprice); + if ( myinfo->IAMNOTARY != 0 || myinfo->IAMLP != 0 || myinfo->secret[0] == 0 ) + return; + kmdcoin = iguana_coinfind("KMD"); + coinbtc = iguana_coinfind("BTC"); + if ( kmdcoin == 0 || coinbtc == 0 ) + return; + smartaddress_coinupdate(myinfo,"KMD",0.,0.,0.); // must be first + if ( kmdcoin->DEXinfo.btcprice > SMALLVAL ) + { + if ( (smartstr= InstantDEX_smartaddresses(myinfo,0,0,0)) != 0 ) + { + if ( (smartarray= cJSON_Parse(smartstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(smartarray)) > 0 ) + { + for (iter=0; iter<2; iter++) + { + for (i=0; iDEXinfo.btcprice,kmdcoin->DEXinfo.avail,kmdcoin->DEXinfo.USD_average); + else + { + printf("Action.%s (%s)\n",typestr,jprint(coinitem,0)); + if ( (address= jstr(coinitem,"address")) != 0 ) + { + if ( strcmp(typestr,"jumblr") == 0 ) + { + bitcoin_addr2rmd160(&addrtype,rmd160,address); + bitcoin_address(coinaddr,kmdcoin->chain->pubtype,rmd160,20); + } else strcpy(coinaddr,address); + maxbid = jdouble(coinitem,"maxbid"); + minask = jdouble(coinitem,"minask"); + extraobj = jobj(coinitem,"extra"); + smartaddress_action(myinfo,selector,typestr,symbol,coinaddr,maxbid,minask,extraobj); + } + } + } + } + } + } + } + free_json(smartarray); + } + free(smartstr); + } + } +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" + +ZERO_ARGS(InstantDEX,smartaddresses) +{ + int32_t i; cJSON *retjson = cJSON_CreateArray(); + portable_mutex_lock(&myinfo->smart_mutex); + for (i=0; inumsmartaddrs; i++) + jaddi(retjson,smartaddress_json(&myinfo->smartaddrs[i])); + portable_mutex_unlock(&myinfo->smart_mutex); + return(jprint(retjson,1)); +} + +TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,smartaddress,type,symbol,maxbid,minask) +{ + char prefix[64],coinaddr[64],KMDaddr[64],typestr[64]; double bidask[2]; uint8_t pubkey33[33]; bits256 privkey; + if ( smartaddress_type(type) < 0 ) + return(clonestr("{\"error\":\"non-supported smartaddress type\"}")); + if ( iguana_coinfind(symbol) == 0 ) + return(clonestr("{\"error\":\"non-supported smartaddress symbol\"}")); + if ( strcmp(type,"deposit") == 0 || strcmp(type,"jumblr") == 0 ) + { + if ( smartaddress_pubkey(myinfo,typestr,bidask,&privkey,symbol,strcmp(type,"deposit") == 0 ? myinfo->jumblr_depositkey : myinfo->jumblr_pubkey) < 0 ) + return(clonestr("{\"error\":\"unexpected missing smartaddress deposit/jumblr\"}")); + } + else + { + strcpy(prefix,type); + tolowercase(prefix); + if ( strcmp(prefix,"btc") == 0 || strcmp(prefix,"kmd") == 0 ) + return(clonestr("{\"success\":\"no need add BTC or KMD to smartaddress\"}")); + strcat(prefix," "); + privkey = jumblr_privkey(myinfo,coinaddr,0,KMDaddr,prefix); + } + if ( (coin= iguana_coinfind(symbol)) == 0 ) + return(clonestr("{\"error\":\"non-supported smartaddress symbol\"}")); + bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); + bitcoin_address(coinaddr,coin->chain->pubtype,pubkey33,33); + smartaddress_add(myinfo,privkey,type,symbol,maxbid,minask); + return(InstantDEX_smartaddresses(myinfo,0,0,0)); +} + +#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/tradebots_SVM.h b/basilisk/tradebots_SVM.h new file mode 100755 index 000000000..a7a0b7d3b --- /dev/null +++ b/basilisk/tradebots_SVM.h @@ -0,0 +1,1072 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +/* + requires *vals and *vars to be initialized + external calls: OS_milliseconds(), get_jfp_features(), get_yval(), set_ocas_model(), update_ocas_preds(), ocasCL_glue() + */ +//#include + +typedef float svmtype; + +// fadedreamz@gmail.com - added for successful compilation, however, for MSVC probably require a particular OpenCL SDK +// to work with it (e,g nvidia or amd SDK) +typedef struct fake_opencl_double { //use a struct for double2 typedefinition on all OS - ca333@protonmail.ch + double x; + double y; +}double2; + +#define MAX_VECTORS (1440 * 365 * 5) +#define MAIN_MAXCORES 16 +#define c_to_refc(c) (c) +#define refc_to_c(refc) (refc) + +#define CONDITION(feature) (feature) +#define FEATURE_THRESHOLD 10. +#define HWMPERC_THRESHOLD 101 +#define HWMPERC_THRESHOLD0 HWMPERC_THRESHOLD + +#ifdef INSIDE_OPENCL +#pragma OPENCL EXTENSION cl_khr_fp64: enable +#define local_barrier() barrier(CLK_LOCAL_MEM_FENCE) +#define global_barrier() barrier(CLK_GLOBAL_MEM_FENCE) +#else +//double get_features(register struct ocas_ptrs *PTRS,register int c,register int weekind,register int numfeatures,register double *features,register double *model,register double *addptr,register struct baserel_info *BR,register double wt); +svmtype *get_jfp_features(register int selector,register int numfeatures,register int c,register int weekind); + +#endif + +#define OCAS_INFINITY (-log(0.0)) +#define OCAS_NEGINFINITY (log(0.0)) +#define OCAS_DECAY .1 +#define OCAS_BIAS 1. +#define OCAS_INDEX(ROW,COL,NUM_ROWS) ((COL)*(NUM_ROWS)+(ROW)) +#define QPSOLVER_MAXITER 1000000 +#define QPSOLVER_MINITER (QPSOLVER_MAXITER * .1) +//#define NUM_CUDA_GROUPS 14 +//#define NUM_BUNDLE_ANSWERS 64 +//#define NUM_TOPCOEFFIS 558 +//#define SMALLVAL .00000000000001 +//#define NUM_PRIMARY_FEATURES 4096 +#ifdef __APPLE__ +#define MAX_OCAS_LHS 512 +#else +#define MAX_OCAS_LHS 2000 +#endif +#define MAX_OCAS_FEATURES (1024 * 1024) + +struct ptrhdr { long allocsize; void *ptr; int devid; char str[64]; }; + +struct ocas_lhsbuffers +{ + double H[MAX_OCAS_LHS * MAX_OCAS_LHS]; + double alpha[MAX_OCAS_LHS],b[MAX_OCAS_LHS],diag_H[MAX_OCAS_LHS],A0[MAX_OCAS_LHS],d[MAX_OCAS_LHS]; + double full_A[]; +}; + +struct ocas_CLtmpspace +{ + double2 hpfb[MAX_VECTORS]; + int poslist[MAX_VECTORS],neglist[MAX_VECTORS]; +}; + +struct ocas_CLbuffers +{ + double output_pred[MAX_VECTORS],old_output[MAX_VECTORS]; + double W[MAX_OCAS_FEATURES+4],oldW[MAX_OCAS_FEATURES+4],new_a[MAX_OCAS_FEATURES+4]; +}; + +struct ocas_vars +{ + struct ptrhdr pH[256]; + double Q_P[TRADEBOTS_NUMANSWERS],Q_D[TRADEBOTS_NUMANSWERS]; + double netcuts[TRADEBOTS_NUMANSWERS],perc[TRADEBOTS_NUMANSWERS],hwmperc[TRADEBOTS_NUMANSWERS],lastmetrics[TRADEBOTS_NUMANSWERS][2]; + double learningrates[TRADEBOTS_NUMANSWERS][2],maxiters[TRADEBOTS_NUMANSWERS],dot_prod_WoldW[TRADEBOTS_NUMANSWERS],cutsum[TRADEBOTS_NUMANSWERS]; + double sq_norm_oldW[TRADEBOTS_NUMANSWERS],oldW0[TRADEBOTS_NUMANSWERS],W0[TRADEBOTS_NUMANSWERS],sq_norm_W[TRADEBOTS_NUMANSWERS]; + double predabs[TRADEBOTS_NUMANSWERS],predsum[TRADEBOTS_NUMANSWERS],dist[TRADEBOTS_NUMANSWERS]; + double xi[TRADEBOTS_NUMANSWERS],pratio[TRADEBOTS_NUMANSWERS],errperc[TRADEBOTS_NUMANSWERS],hwmdist[TRADEBOTS_NUMANSWERS]; + double answerabsaves[TRADEBOTS_NUMANSWERS],answeraves[TRADEBOTS_NUMANSWERS]; + int answercounts,firstweekinds[TRADEBOTS_NUMANSWERS]; + int posA[TRADEBOTS_NUMANSWERS],negA[TRADEBOTS_NUMANSWERS]; + int numIt[TRADEBOTS_NUMANSWERS],numlhs[TRADEBOTS_NUMANSWERS],nNZAlpha[TRADEBOTS_NUMANSWERS],trn_err[TRADEBOTS_NUMANSWERS]; + int qp_exitflag[TRADEBOTS_NUMANSWERS],exitflag[TRADEBOTS_NUMANSWERS],len[TRADEBOTS_NUMANSWERS]; + int have_pendingmodel[TRADEBOTS_NUMANSWERS],cutlen[TRADEBOTS_NUMANSWERS],good[TRADEBOTS_NUMANSWERS],bad[TRADEBOTS_NUMANSWERS]; + int nohwm[TRADEBOTS_NUMANSWERS],numposcuts[TRADEBOTS_NUMANSWERS],numnegcuts[TRADEBOTS_NUMANSWERS]; + struct ocas_CLbuffers *CLspaces[TRADEBOTS_NUMANSWERS]; + struct ocas_lhsbuffers *lhs[TRADEBOTS_NUMANSWERS]; + int *weekinds[TRADEBOTS_NUMANSWERS]; + float *answers,**features; + //unsigned long CLallocsize,tmpallocsize,tmpCLallocsize; + double C,TolRel,TolAbs,MaxTime,QPBound,QPSolverTolAbs,QPSolverTolRel; + double output_time,sort_time,add_time,w_time,qp_solver_time,ocas_time; // total time spent in svm_ocas_solver + int selector,numthreads,starti,modelind,c,refc,maxlen,numfeatures,firstweekind,startweekind,endweekind,numptrs,maxlhs; +}; + +/////////////////////////// Most of runtime is in the add/dot functions +#ifdef INSIDE_OPENCL +typedef double svmtype; + +// numCLthreads: NUM_CUDA_CORES, numgroups: (numdocs + NUM_CUDA_CORES-1)/NUM_CUDA_CORES +__kernel void dot_featuresCL(__local void *lp,__global double *preds,int numfeatures,__global double *W,double W0,__global svmtype *matrix,int numdocs) +{ + register int i,j,docid; + register double sum; + register __global svmtype *features; + if ( (docid = (int)get_global_id(0)) < numdocs ) + { + sum = 0.; + features = &matrix[docid * numfeatures]; + for (i=0; i>= 1; + if ( docid < numdocs ) + { + features = &matrix[docid * numfeatures]; + if ( dir == 0 ) + sum += CONDITION(features[j]); + else sum -= CONDITION(features[j]); + } + } + new_a[j] = sum; + } +} + +#else + +void ocas_purge(struct ocas_vars *vars) +{ + int32_t i; + free(vars->answers); + for (i=0; imaxlen; i++) + if ( vars->features[i] != 0 ) + free(vars->features[i]); + free(vars->features); + for (i=0; iCLspaces[i] != 0 ) + myaligned_free(vars->CLspaces[i],sizeof(*vars->CLspaces[i])); + if ( vars->lhs[i] != 0 ) + myaligned_free(vars->lhs[i],sizeof(*vars->lhs[i]) + vars->numfeatures*vars->maxlhs*sizeof(double)); + if ( vars->weekinds[i] != 0 ) + free(vars->weekinds[i]); + } + free(vars); +} + +/*static inline double dot_expanded_features(register double *W,register int c,register int selector,register int numfeatures) + { + fatal("dot_expanded_features not implemented"); + return(0); + } + + static inline void add_expanded_features(register double *W,register double y,register int c,register int selector,register int numfeatures) + { + fatal("add_expanded_features not implemented"); + }*/ + +static inline double calc_ocas_output(register struct ocas_vars *vars,register int selector,register int c,register int weekind,register int answerind,register double *W,register double W0,register int numfeatures) +{ + register svmtype *features; + register double feature,y,sum = 0.; + register int coeffi; + if ( (y= vars->answers[(weekind-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0.f ) + { + if ( (features= vars->features[weekind-vars->starti]) != 0 )//get_jfp_features(vars->selector,numfeatures,c,weekind)) != 0 ) + { +#ifdef OCAS_USE_TOPCOEFFIS + for (int i=0; iselector,numfeatures); + sum = y * (W0 + sum); + } + // printf("%f ",sum); + return(sum); +} + +static inline void add_ocas_output(register double y,register struct ocas_vars *vars,register int selector,register int c,register int weekind,register int answerind,register double *W,register double *new_a,register int numfeatures) +{ + register int coeffi; + register svmtype *features,feature; + if ( y != 0 ) + { + if ( (features= vars->features[weekind-vars->starti]) != 0 )//get_jfp_features(vars->selector,numfeatures,c,weekind)) != 0 ) + { + //features = get_jfp_features(vars->selector,numfeatures,c,weekind); +#ifdef OCAS_USE_TOPCOEFFIS + int32_t i; + for (i=0; iselector,numfeatures); + } +} + +static inline void STocas_calc_outputs(register struct ocas_vars *vars,register int c,register int answerind,register double *output,register double *old_output,register double *W,register double W0,register int numfeatures,register int *weekinds,register int numdocs) +{ + register int i,j; + //vars->good[answerind] = vars->bad[answerind] = 0; + //printf("start STocas_calc_outputs.(%p %s.A%d %p) %p %p %p\n",vars,CONTRACTS[c],answerind,weekinds,output,old_output,W); + for (i=0; iselector,c,weekinds[i],answerind,W,W0,numfeatures); + if ( 1 && isnan(output[i]) != 0 ) + { + svmtype *features = vars->features[weekinds[i]-vars->starti];//get_jfp_features(vars->selector,numfeatures,c,weekinds[i]); + if ( features != 0 ) + { + for (j=0; janswers[(i-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]*output[i] <= 0 ) + { + if ( vars->answers[(i-vars->starti)*TRADEBOTS_NUMANSWERS + answerind] != 0.f ) + printf("(%f %f) ",vars->answers[(i-vars->starti)*TRADEBOTS_NUMANSWERS + answerind],output[i]); + } + //printf("[%f %f] ",vars->answers[(i-vars->starti)*TRADEBOTS_NUMANSWERS + answerind],output[i]); + } + } + //printf("finish STocas_calc_outputs\n"); +} + +static inline void STocas_add_newcuts(register struct ocas_vars *vars,register int answerind,register int numfeatures,register int *weekinds,register int *new_cut,register int numcuts,register double *W,register double *new_a) +{ + register int weekind,dir,i,c = vars->c; + memset(new_a,0,sizeof(*new_a) * numfeatures); + //printf("STocas_add_newcuts numcuts.%d numfeatures.%d\n",numcuts,numfeatures); + for (i=0; i>= 1; + add_ocas_output(dir==0?1:-1,vars,vars->selector,c,weekind,answerind,W,new_a,numfeatures); + } +} +//////////////////////////// end of add/dot functions +static inline double _dbufave(register double *buf,register int len) +{ + register int i,n; + register double sum; + sum = 0.; + n = 0; + for (i=0; i 0.0000000001 ) + { + n++; + sum += buf[i]; + } + } + if ( n != 0 ) + sum /= n; + if ( fabs(sum) <= 0.0000000001 ) + sum = 0.; + return(sum); +} + +static inline void add_newcut_entry(register struct ocas_vars *vars,register int answerind,register int *new_cut,register int i,register int weekind,register double y) +{ + weekind <<= 1; + if ( y > 0 ) vars->numposcuts[answerind]++; + else if ( y < 0 ) vars->numnegcuts[answerind]++, weekind |= 1; + new_cut[vars->cutlen[answerind]++] = weekind; +} + +static inline double validate_ocas_model(register struct ocas_vars *vars,register int answerind,register double *output_pred,register double *old_output,register int *weekinds,register int numdocs,register double *W,register double W0,register int numfeatures,register int paranoid) +{ + register svmtype *features; + register double y,pred,perc,answer=0.,feature; + register int i,j,pos,neg,good,bad,oldcuts,training_errors,weekind,nonz=0,posA,negA; + for (i=pos=neg=good=bad=oldcuts=training_errors=posA=negA=0; ianswers[(weekind-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0. ) + { + if ( y > 0 ) posA++; + else if ( y < 0 ) negA++; + if ( paranoid != 0 ) + { + pred = 0.; + if ( (features= vars->features[weekind-vars->starti]) != 0 )//get_jfp_features(vars->selector,numfeatures,vars->c,weekind)) != 0 ) + { + for (j=nonz=0; j SMALLVAL ) + pred += W0; + } + else pred = 0;//dot_expanded_features(W,c,selector,numfeatures); + if ( output_pred[i] != 0 && fabs(pred - output_pred[i]) > .000001 ) + // if ( (rand() % 10000) == 0 ) + printf("i.%d A %9.6f pred %9.6f != output_pred %9.6f [%14.10f]\n",i,answer,pred,output_pred[i],pred-output_pred[i]); + } + else pred = output_pred[i], nonz = numfeatures; + if ( nonz != 0 ) + { + if ( pred > 0 ) pos++; + else if ( pred < 0 ) neg++; + if ( pred*y > 0 ) good++; + else if ( pred*y < 0 ) bad++; + } + if ( old_output[i] <= 1. ) + { + oldcuts++; + if ( old_output[i] <= 0. ) + training_errors++; + } + } + } + nonz = 0; + for (i=0; i>>>>> %d.A%02d.(+%-6d -%-6d oc.%-6d | good.%-6d bad.%-6d >>>>> %6.2f%% <<<<<).%-6d | W0 %9.6f W[%d] %9.6f | A +%-6d -%-6d | paranoid.%d numdocs.%d\n",c_to_refc(vars->c),answerind,pos,neg,oldcuts,good,bad,perc,training_errors,W0,nonz,_dbufave(W,numfeatures),posA,negA,paranoid,numdocs); + return(perc); +} + +static int _increasing_double(const void *a,const void *b) +{ +#define double_a (*(double *)a) +#define double_b (*(double *)b) + if ( double_b > double_a ) + return(-1); + else if ( double_b < double_a ) + return(1); + return(0); +#undef double_a +#undef double_b +} + +static inline void calc_ocas_strategy(register struct ocas_vars *vars,register int answerind,register double C,register int numfeatures,register int len,register int *weekinds,register int *new_cut,register double *W,register double *oldW,register double *output,register double *old_output,register double2 *hpfb) +{ + double answermag; + register int i,j,num_hp,good,bad,zero; + register double Bval,Cval,newoutput,W0,oldW0,sq_norm_W,A0val,B0,dist,GradVal,t,t1,t2,t_new,val,GradVal_new,y,starttime,*preds = output; + num_hp = 0; + W0 = vars->W0[answerind]; oldW0 = vars->oldW0[answerind]; + A0val = vars->sq_norm_W[answerind] - (2. * vars->dot_prod_WoldW[answerind]) + vars->sq_norm_oldW[answerind]; + B0 = (vars->dot_prod_WoldW[answerind] - vars->sq_norm_oldW[answerind]); + GradVal = B0; + for (i=0; ianswers[(weekinds[i]-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0.f ) + { + svmtype *features = vars->features[weekinds[i]-vars->starti];//get_jfp_features(vars->selector,numfeatures,vars->c,weekinds[i]); + //printf("i.%d weekind.%d starti.%d y %f %p\n",i,weekinds[i],vars->starti,y,features); + if ( 0 && features != 0 ) + { + double oldsum=oldW0,sum=W0; + for (j=0; j .000001 ) + { + printf("A%d numIt.%d docid.%-6d sum %11.7f * y%2.0f %11.7f != %11.7f output [%11.7f] W0 %11.7f oldW0 %11.7f\n",answerind,vars->numIt[answerind],i,sum,y,sum*y,output[i],output[i]-sum*y,W0,oldW0); + //output[i] = sum*y; + } + if ( fabs(oldsum*y - old_output[i]) > .000001 ) + { + if ( old_output[i] != 0 && oldW0 != 0 && (rand() % 1000) == 0 ) + printf("A%d numIt.%d docid.%-6d oldsum %11.7f * y%2.0f %11.7f != %11.7f oldoutput [%11.7f] W0 %11.7f oldW0 %11.7f\n",answerind,vars->numIt[answerind],i,oldsum,y,oldsum*y,old_output[i],old_output[i]-oldsum*y,W0,oldW0); + old_output[i] = oldsum*y; + } + } + Cval = C * (1. - old_output[i]); + Bval = C * (old_output[i] - output[i]); + if ( Bval != 0 ) + val = -(Cval / Bval); + else val = OCAS_NEG_INF; + if ( val > 0 ) + { + hpfb[num_hp].y = Bval; + hpfb[num_hp].x = val; + num_hp++; + } + if ( (Bval < 0 && val > 0) || (Bval > 0 && val <= 0) ) + GradVal += Bval; + } + } + //printf("num_hp.%d\n",num_hp); + t = 0; + if ( GradVal < 0 ) + { + starttime = OS_milliseconds(); + qsort(hpfb,num_hp,sizeof(double2),_increasing_double); + //ocas_sort(hpfb,num_hp); + i = 0; + while ( GradVal < 0 && i < num_hp ) + { + t_new = hpfb[i].x; + GradVal_new = GradVal + fabs(hpfb[i].y) + A0val*(t_new - t); + if ( GradVal_new >= 0 ) + t = t + GradVal * (t - t_new) / (GradVal_new - GradVal); + else t = t_new, i++; + GradVal = GradVal_new; + } + vars->sort_time += OS_milliseconds() - starttime; + } + t = MAX(t,0.); // just sanity check; t < 0 should not occur + t1 = t; // new (best so far) W + t2 = t + OCAS_DECAY*(1. - t); // new cutting plane + W0 = oldW0 * (1. - t) + (t * W0); + sq_norm_W = W0 * W0; + for (j=0; jW0[answerind] = W0; vars->sq_norm_W[answerind] = sq_norm_W; + vars->trn_err[answerind] = 0; dist = 0.; + for (i=good=bad=zero=0; ianswers[(weekinds[i]-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0.f ) + { + answermag = fabs(y); // 1.; + if ( (old_output[i] * (1. - t2) + t2*output[i]) <= answermag ) //1. + add_newcut_entry(vars,answerind,new_cut,i,weekinds[i],y); + newoutput = (old_output[i] * (1. - t1)) + (t1 * output[i]); + if ( 0 ) // won't match unless old_output corresponds with features*oldW + { + double sum=W0; + svmtype *features = vars->features[weekinds[i]-vars->starti];//get_jfp_features(vars->selector,numfeatures,vars->c,weekinds[i]); + if ( features != 0 ) + { + for (j=0; j .0000001 ) + printf("numIt.%d docid.%-6d w%-6d sum %11.7f * y%2.0f %11.7f != %11.7f newoutput [%11.7f] W0 %11.7f oldW0 %11.7f\n",vars->numIt[answerind],i,weekinds[i],sum,y,sum*y,newoutput,newoutput-sum*y,W0,oldW0); + newoutput = sum*y; + } + } + if ( newoutput <= answermag ) + { + vars->xi[answerind] += (answermag - newoutput); + if ( newoutput <= 0. ) + vars->trn_err[answerind]++; + } + preds[i] = y * newoutput; + dist += fabs(preds[i] - y); + old_output[i] = newoutput; + if ( newoutput > 0. ) good++; + else if ( newoutput < 0. ) + { + bad++; + //printf("(%f %f) ",y,newoutput); + } + } else zero++;//,printf("i.%d -> w%d | zeroes.%d good.%d bad.%d of len.%d\n",i,weekinds[i],zero,good,bad,len); + } + //printf("finished strategy\n"); + vars->good[answerind] = good; vars->bad[answerind] = bad; vars->dist[answerind] = dist / MAX(1,good+bad); + vars->perc[answerind] = (100. * (double)vars->good[answerind]) / MAX(1,good+bad); + if ( vars->perc[answerind] > vars->hwmperc[answerind] || (vars->perc[answerind] == vars->hwmperc[answerind] && (vars->hwmdist[answerind] == 0 || vars->dist[answerind] < vars->hwmdist[answerind])) ) + { + double set_ocas_model(int refc,int answerind,double *W,double W0,int numfeatures,int firstweekind,int len,int bad,double dist,double predabs,int posA,int negA,double answerabs,double aveanswer); + vars->W0[answerind] = set_ocas_model(vars->refc,answerind,vars->CLspaces[answerind]->W,vars->W0[answerind],vars->numfeatures,vars->firstweekind,vars->len[answerind],vars->trn_err[answerind],vars->dist[answerind],vars->predabs[answerind],vars->posA[answerind],vars->negA[answerind],vars->answerabsaves[answerind],0.); + vars->nohwm[answerind] = 0; + vars->hwmperc[answerind] = vars->perc[answerind]; vars->hwmdist[answerind] = vars->dist[answerind]; + } + else vars->nohwm[answerind]++; + //printf("good.%d bad.%d zero.%d errors.%d | selector.%d\n",good,bad,zero,vars->trn_err[answerind],vars->selector); +} + +static inline double ocas_splx_solver(register int *nonzalphap,register int maxlhs,register double *d,register double *activeH,register double *diag_H,register double *f,register double C,register double *alpha,register int n,register int MaxIter,register double TolAbs,register double TolRel,register double QP_TH) +{ + register double *col_u=0,*col_v=0; + register double QP,QD,lastQD,tmp,diff,distA,distB,etaA,etaB,improv,tmp_num,delta,x_neq0,xval,dval,diagval=0.,tmp_den,tau=0.; + register int u=0,v=0,i,j,iter,nonzalpha=0,unlikely = 0; + QP = distA = distB = OCAS_PLUS_INF; lastQD = QD = OCAS_NEG_INF; + x_neq0 = C; + etaA = etaB = 0.; + for (i=0; i 0. ) + { + col_u = &activeH[maxlhs * i]; + for (j=0; j 10*(MaxIter-iter) && etaB > 10*(MaxIter-iter) ) + unlikely++; + else unlikely = 0; + } else unlikely = 0; + diff = (QP - QD); + if ( 0 && (diff <= fabs(QP)*TolRel || diff <= TolAbs || QP <= QP_TH || unlikely > 100) ) + { + if ( 0 ) + { + if ( diff <= fabs(QP)*TolRel ) + printf("caseA %f | ",diff - fabs(QP)*TolRel); + else if ( diff <= TolAbs ) + printf("caseB %f | ",diff - TolAbs); + else if ( etaA > 2*(MaxIter-iter) && etaB > 2*(MaxIter-iter) ) + printf("caseC etas %f %f | ",etaA,etaB); + printf("%d: QP %f QD %f diff %f n.%d d0 %9.6f dA %9.6f %9.6f dB %9.6f %9.6f\n",iter,QP,QD,QP-QD,n,d[0],distA,etaA,distB,etaB); + } + break; + } + distA = (diff - fabs(QP)*TolRel); + distB = (diff - TolAbs); + lastQD = QD; + if ( d[u] > 0 ) + u = -1; + else delta -= C * d[u]; + // if satisfied then k-th block of variables needs update + if ( delta > TolAbs && delta > (TolRel * fabs(QP)) ) + { + // for fixed u select v = argmax_{i in I_k} Improvement(i) + improv = OCAS_NEG_INF; + for (i=0; i<=n; i++) + { + if ( i == u || (xval = ((i 0 ) + { + tmp_num = xval * dval; + if ( tmp_num < tmp_den ) + tmp = tmp_num*tmp_num / tmp_den; + else tmp = tmp_num - .5 * tmp_den; + if ( 0 && i < n ) // jimbo tweak + { + tmp = alpha[i] * MIN(1.,tmp_num/tmp_den); + alpha[i] -= tmp; + if ( u == -1 ) + x_neq0 += tmp; + else alpha[u] += tmp; + } + if ( tmp > improv ) + { + improv = tmp; + tau = MIN(1.,tmp_num/tmp_den); + v = i; + } + } + } + // update d = H*x + f + if ( v < n ) + { + tau *= alpha[v]; + alpha[v] -= tau; + if ( u != -1 ) + { + alpha[u] += tau; + col_v = &activeH[maxlhs * v]; + for (i=0; isq_norm_oldW[answerind] = vars->sq_norm_W[answerind]; + oldW0 = vars->oldW0[answerind] = vars->W0[answerind]; + W0 = 0.; + for (i=0; ialpha[i]) > 0 ) + { + //printf("%9.6f ",alpha); + for (j=0; jfull_A[OCAS_INDEX(j,i,numfeatures)]; + W0 += lhs->A0[i] * alpha; + } + } + vars->W0[answerind] = W0; + sq_norm_W = W0 * W0; + dot_prod_WoldW = W0 * oldW0; + for (j=0; jalpha,numlhs),W0,sq_norm_W,answerind); + vars->dot_prod_WoldW[answerind] = dot_prod_WoldW; + vars->sq_norm_W[answerind] = sq_norm_W; +} + +static inline void ocas_update_Lspace(register struct ocas_vars *vars,register int answerind,register double netcuts,register double cut_length,register int numfeatures,register double C,register double QPSolverTolAbs,register double QPSolverTolRel) +{ + register struct ocas_CLbuffers *ptr = vars->CLspaces[answerind]; + register struct ocas_lhsbuffers *lhs = vars->lhs[answerind]; + register double *new_col_H; + register double sq_norm_a,maxiters,metric,tmp; + register int i,j,iters,numlhs,maxlhs = vars->maxlhs; + numlhs = vars->numlhs[answerind]; + new_col_H = &lhs->H[OCAS_INDEX(0,numlhs,maxlhs)]; + lhs->A0[numlhs] = netcuts; + lhs->b[numlhs] = -cut_length; + sq_norm_a = lhs->A0[numlhs] * lhs->A0[numlhs]; + for (j=0; jfull_A[OCAS_INDEX(j,numlhs,numfeatures)] = ptr->new_a[j]; + if ( fabs(ptr->new_a[j]) > 1000 ) + { + //printf("(%d %9.6f %f) ",j,ptr->new_a[j],sq_norm_a); + ptr->new_a[j] = 0.; + } + else + sq_norm_a += ptr->new_a[j] * ptr->new_a[j]; + ptr->oldW[j] = ptr->W[j]; ptr->W[j] = 0.; + } + new_col_H[numlhs] = sq_norm_a; + //printf("QPsolver.A%02d: ABS %f Rel %.11f numlhs.%d cutlen.%f netcuts.%f sq_norm_a %f netcuts.%f\n",answerind,QPSolverTolAbs,QPSolverTolRel,vars->numlhs[answerind],cut_length,lhs->A0[numlhs],sq_norm_a,netcuts); + for (i=0; iA0[numlhs] * lhs->A0[i]; + for (j=0; jnew_a[j] * lhs->full_A[OCAS_INDEX(j,i,numfeatures)]; + new_col_H[i] = tmp; + } + lhs->d[numlhs] = lhs->alpha[numlhs] = 0.; + lhs->diag_H[numlhs] = lhs->H[OCAS_INDEX(numlhs,numlhs,maxlhs)]; + for (i=0; i H[OCAS_INDEX(numlhs,i,maxlhs)] = lhs->H[OCAS_INDEX(i,numlhs,maxlhs)]; + numlhs = ++vars->numlhs[answerind]; + iters = vars->numIt[answerind]; + if ( vars->nohwm[answerind] > 3 ) + vars->maxiters[answerind] *= 1 + sqrt(vars->nohwm[answerind])/100; + else if ( vars->nohwm[answerind] == 0 ) + vars->maxiters[answerind] *= .5; + if ( vars->maxiters[answerind] > QPSOLVER_MAXITER ) + vars->maxiters[answerind] = QPSOLVER_MAXITER; + if ( vars->maxiters[answerind] < QPSOLVER_MINITER ) + vars->maxiters[answerind] = QPSOLVER_MINITER; + maxiters = MAX(QPSOLVER_MINITER,vars->maxiters[answerind]); + vars->Q_D[answerind] = ocas_splx_solver(&vars->nNZAlpha[answerind],maxlhs,lhs->d,lhs->H,lhs->diag_H,lhs->b,C,lhs->alpha,vars->numlhs[answerind],MIN(maxiters,QPSOLVER_MAXITER),QPSolverTolAbs,QPSolverTolRel,OCAS_NEG_INF); + metric = ((double)vars->len[answerind] / MAX(1,vars->trn_err[answerind])) / 1.; + vars->lastmetrics[answerind][iters & 1] = metric; + update_ocas_model(ptr->W,ptr->oldW,vars,numfeatures,answerind,lhs,numlhs); +} + +static inline void start_ocas_iter(register struct ocas_vars *vars,register int c,register int answerind) +{ + if ( vars->pratio[answerind] == 0. ) + vars->pratio[answerind] = vars->answerabsaves[answerind]; + vars->good[answerind] = -1; + vars->bad[answerind] = vars->trn_err[answerind] = vars->cutlen[answerind] = vars->numposcuts[answerind] = vars->numnegcuts[answerind] = 0; + vars->xi[answerind] = vars->predsum[answerind] = vars->dist[answerind] = vars->cutsum[answerind] = vars->netcuts[answerind] = 0.; +} + +static void ocas_print(struct ocas_vars *vars,int answerind,int ishwm,double C) +{ + int i; + double dispvals[4]; + //printf("ocas_print.A%d\n",answerind); + //printf("%s.A%02d %4d %8.2f | QP %9.3f QD %9.3f [%9.4f %7.3f] SV.%d %4d | M%9.6f (%9.6f max %8.1f %9.6f) %s.A%02d %9.6f%%\n", + dispvals[0] = vars->Q_P[answerind]/1000000000.; dispvals[1] = (C * vars->Q_D[answerind])/1000000000.; + dispvals[2] = (vars->Q_P[answerind]-C * vars->Q_D[answerind]) / 1000000000; + dispvals[3] = (vars->Q_P[answerind]-C * vars->Q_D[answerind]) / MAX(1,fabs(vars->Q_P[answerind])); + printf("%3d %d.A%02d +%d -%d",vars->nohwm[answerind],vars->refc,answerind,vars->good[answerind],vars->bad[answerind]); + printf(" %4d %8.2f |QP %9.3f QD %10.2f [%11.2f %9.1f] SV.%3d %3d |M%9.3f errs.%-6d %-8.0f %5.2f%% errs %6.5f A%9.6f W0%9.6f D%11.9f\n",//[%7.4f%%]\n", + vars->numIt[answerind],vars->ocas_time/1000,dispvals[0],dispvals[1],dispvals[2],dispvals[3], + vars->nNZAlpha[answerind], vars->numlhs[answerind], + // PTRS->lastmetrics[answerind],PTRS->learningrates[answerind][0],PTRS->maxiters[answerind],PTRS->learningrates[answerind][1], + vars->lastmetrics[answerind][0],vars->trn_err[answerind],vars->maxiters[answerind],vars->perc[answerind], + vars->errperc[answerind]/100,_dbufave(vars->CLspaces[answerind]->new_a,vars->numfeatures),vars->W0[answerind], + vars->dist[answerind]/vars->answerabsaves[answerind]);//_dbufave(vars->hwmperc,81));//,vars->errperc+vars->perc); + for (i=0; i<4; i++) + if ( isnan(dispvals[i]) != 0 ) + break; + if ( vars->lastmetrics[answerind][0] > 10 ) + usleep(vars->lastmetrics[answerind][0] * vars->lastmetrics[answerind][0]); + /*if ( 0 && i < 4 )//|| (vars->answerind >= 32 && fabs(vars->W0) > .9) ) + { + int save_model(int refc,int answerind,double *W,int numfeatures,double W0,double perc,int posA,int negA); + memset(&vars->CLspaces[answerind],0,sizeof(vars->CLspaces[answerind])); + vars->W0[answerind] = vars->oldW0[answerind] = 0.; + vars->numIt[answerind] = 0; + vars->perc[answerind] = vars->hwmperc[answerind] = 0.; + printf("reset model %s.A%02d\n",CONTRACTS[vars->selector!=3?vars->refc:NUM_COMBINED],answerind); + save_model(vars->refc,answerind,vars->CLspaces[answerind]->W,vars->numfeatures,vars->W0[answerind],vars->perc[answerind]); + }*/ +} + +static inline void finish_ocasiter(register int answerind,register struct ocas_vars *vars,register double C) +{ + register double den; + vars->have_pendingmodel[answerind] = 0; + if ( vars->good[answerind] == 0 && vars->bad[answerind] == 0 ) + { + vars->bad[answerind] = vars->trn_err[answerind]; + vars->good[answerind] = (vars->len[answerind] - vars->trn_err[answerind]); + } + den = MAX(1.,vars->good[answerind]+vars->bad[answerind]); + if ( (vars->predabs[answerind] = (vars->predsum[answerind] / den)) != 0. ) + vars->pratio[answerind] = (vars->answerabsaves[answerind] / vars->predabs[answerind]); + else vars->pratio[answerind] = 0.; + vars->dist[answerind] = sqrt(vars->dist[answerind] / den); + //printf("W0 %9.6f pred sum %f %f | pratio %f distsum %f (%f vs hwm %f)\n",vars->W0[answerind],vars->predsum[answerind],vars->predabs[answerind],vars->pratio[answerind],vars->dist[answerind],vars->perc[answerind],vars->hwmperc[answerind]); + vars->errperc[answerind] = (100 * (double)vars->trn_err[answerind])/(double)MAX(1,vars->len[answerind]); + vars->Q_P[answerind] = 0.5*vars->sq_norm_W[answerind] + (C * vars->xi[answerind]); + vars->ocas_time = (vars->output_time + vars->w_time + vars->add_time + vars->sort_time + vars->qp_solver_time); + ocas_print(vars,answerind,0,C); +} + +static inline int ocas_iter(struct ocas_vars *vars,int max_nohwm) +{ + int Method = 1; + int min_nohwm = 1; + int skipflags[84]; + static int new_cut[MAX_VECTORS]; + static double2 hpfb[MAX_VECTORS]; + int inactives[81]; + register struct ocas_CLbuffers *ptr; + register double netcuts,startmilli,y,psum,pcount,nosum; + register int i,numfeatures,cutlen,lastanswerind,lwm=(1<<20),numactive,numthreads,answerind,*weekinds; + numactive = 0; + if ( (numfeatures= vars->numfeatures) > MAX_OCAS_FEATURES ) + { + printf("numfeatures > MAX_OCAS_FEATURES\n"); + exit(-1); + } + psum = pcount = nosum = 0; + { + //printf("c.%d mask %lx %p\n",c,contractmask,PTRS->ocas[c]); + memset(inactives,0,sizeof(inactives)); + lastanswerind = TRADEBOTS_NUMANSWERS; + numfeatures = vars->numfeatures; + answerind = 0; + //printf("numIt.%d ocas iter.%s A.mask%lx len.%d CLspace.%p lhs.%p | vars.%p\n",vars->numIt[answerind],CONTRACTS[c_to_refc(c)],answerindmask,vars->len[answerind],vars->CLspaces[answerind],vars->lhs[answerind],vars); + memset(skipflags,0,sizeof(skipflags)); + for (answerind=0; answerindCLspaces[answerind],vars->weekinds[answerind],vars->nohwm[answerind],max_nohwm); + if ( vars->hwmperc[answerind] != 0 ) + { + nosum += vars->nohwm[answerind]; + pcount++, psum += vars->hwmperc[answerind]; + } + //printf("answerind.%d\n",answerind); + if ( vars->len[answerind] == 0 || vars->CLspaces[answerind] == 0 || (vars->nohwm[answerind] > min_nohwm && vars->hwmperc[answerind] > ((answerind==0) ? HWMPERC_THRESHOLD0 : HWMPERC_THRESHOLD)) ) + { + inactives[answerind] = 1; + continue; + } + if ( vars->nohwm[answerind] < max_nohwm ) + { + numactive++; + if ( vars->numIt[answerind]++ == 0 ) + { + for (i=0; iCLspaces[answerind]->W[i] != 0 ) + break; + if ( i == numfeatures ) + skipflags[answerind] = 1; + } + ptr = vars->CLspaces[answerind]; + weekinds = vars->weekinds[answerind]; + //printf("start iter %p %p\n",ptr,weekinds); + start_ocas_iter(vars,vars->c,answerind); + numthreads = vars->numthreads; + if ( skipflags[answerind] != 0 ) + { + for (i=0; ilen[answerind]; i++) + { + if ( (y= vars->answers[(weekinds[i]-vars->starti)*TRADEBOTS_NUMANSWERS + answerind]) != 0.f ) + { + ptr->output_pred[i] = 0; + add_newcut_entry(vars,answerind,new_cut,i,weekinds[i],y); + } + } + fprintf(stderr,"skip %d.A%02d cuts +%d -%d, ",c_to_refc(vars->c),answerind,vars->numposcuts[answerind],vars->numnegcuts[answerind]); + } + else + { + startmilli = OS_milliseconds(); + //printf("%s ocas_calc_outputs.A%d len.%d | numthreads.%d\n",CONTRACTS[c_to_refc(c)],answerind,vars->len[answerind],numthreads); + STocas_calc_outputs(vars,vars->c,answerind,ptr->output_pred,ptr->old_output,ptr->W,vars->W0[answerind],numfeatures,weekinds,vars->len[answerind]); + //ocas_calc_outputs(PTRS,numthreads,vars,c,answerind,ptr->output_pred,ptr->old_output,ptr->W,vars->W0[answerind],numfeatures,weekinds,vars->len[answerind]); + vars->output_time += (OS_milliseconds() - startmilli); + if ( Method != 0 ) + { + startmilli = OS_milliseconds(); + //printf("%d calc_ocas_strategy.A%d len.%d | numthreads.%d\n",c_to_refc(vars->c),answerind,vars->len[answerind],numthreads); + calc_ocas_strategy(vars,answerind,vars->C,numfeatures,vars->maxlen,weekinds,new_cut,ptr->W,ptr->oldW,ptr->output_pred,ptr->old_output,hpfb); + vars->w_time += (OS_milliseconds() - startmilli); + } + finish_ocasiter(answerind,vars,vars->C); + } + //printf("%s calc ocas_add_newcuts.A%d poscuts.%d negcuts.%d | numthreads.%d\n",CONTRACTS[c_to_refc(c)],answerind,vars->numposcuts[answerind],vars->numnegcuts[answerind],vars->numthreads); + startmilli = OS_milliseconds(); + //if ( vars->nohwm[answerind] > 13 ) + // numthreads = vars->numthreads;///MAIN_MAXCORES; + memset(ptr->new_a,0,sizeof(ptr->new_a)); + //ocas_add_newcuts(PTRS,numthreads,vars,answerind,numfeatures,weekinds,new_cut,vars->numposcuts[answerind]+vars->numnegcuts[answerind],ptr->W,ptr->new_a); + STocas_add_newcuts(vars,answerind,numfeatures,weekinds,new_cut,vars->numposcuts[answerind]+vars->numnegcuts[answerind],ptr->W,ptr->new_a); + vars->add_time += (OS_milliseconds() - startmilli); +//printf("done %d calc ocas_add_newcuts.A%d poscuts.%d negcuts.%d | good.%d bad.%d\n",c_to_refc(vars->c),answerind,vars->numposcuts[answerind],vars->numnegcuts[answerind],vars->good[answerind],vars->bad[answerind]); + } else inactives[answerind] = 1;//, printf("maxnohwm.%d\n",max_nohwm); + } + startmilli = OS_milliseconds(); + for (answerind=0; answerindnumposcuts[answerind] - vars->numnegcuts[answerind]); + cutlen = (vars->numposcuts[answerind] + vars->numnegcuts[answerind]); + if ( vars->nohwm[answerind] < lwm ) + lwm = vars->nohwm[answerind]; + ocas_update_Lspace(vars,answerind,netcuts,cutlen,numfeatures,vars->C,0.,vars->QPSolverTolRel); + } + vars->qp_solver_time += (OS_milliseconds() - startmilli); + } + if ( pcount != 0 ) + printf("numactive.%d %.0f | ave perf %f%% | ave nohwm %.1f\n",numactive,pcount,psum/pcount,nosum/pcount); + return(numactive); +} + +static inline int init_ocas_vars(int numthreads,int selector,long answerindmask,struct ocas_vars *vars,int c,double C,int numfeatures,int maxlhs,int maxlen,int len,double *answerabsave,int *posA,int *negA) +{ + int answerind,lastanswerind,retval = 0; + lastanswerind = TRADEBOTS_NUMANSWERS; + vars->maxlen = maxlen; + vars->numthreads = numthreads; + vars->selector = selector; + //printf("init_ocas_vars lastanswerind.%d\n",lastanswerind); + for (answerind=0; answerindlen[answerind]); + if ( vars->len[answerind] > 0 )//&& (answerindmask == -1L || ((1L<refc = c_to_refc(c); vars->c = c; vars->C = C; + vars->numfeatures = numfeatures; vars->maxlhs = maxlhs; + if ( vars->CLspaces[answerind] == 0 ) + vars->CLspaces[answerind] = myaligned_alloc(sizeof(*vars->CLspaces[answerind])); + vars->answerabsaves[answerind] = answerabsave[answerind]; + vars->posA[answerind] = posA[answerind]; vars->negA[answerind] = negA[answerind]; + if ( vars->lhs[answerind] == 0 ) + vars->lhs[answerind] = myaligned_alloc(sizeof(*vars->lhs[answerind]) + numfeatures*maxlhs*sizeof(double)); + vars->maxiters[answerind] = QPSOLVER_MINITER; vars->trn_err[answerind] = vars->len[answerind]; vars->Q_P[answerind] = 0.5*vars->sq_norm_W[answerind] + C*vars->len[answerind]; + vars->perc[answerind] = vars->hwmperc[answerind] = vars->dist[answerind] = vars->hwmdist[answerind] = 0.; vars->numIt[answerind] = 0; + //printf("init.A%d %d | %p %p weekinds.%p\n",answerind,vars->len[answerind],vars->CLspaces[answerind],vars->lhs[answerind],vars->weekinds[answerind]); + } + } + //printf("mask.%lx init_ocas_vars selector.%d weekinds[0].%p\n",answerindmask,selector,vars->weekinds[0]); + return(retval); +} + +void ocas_init(struct ocas_vars *vars,int32_t c,int32_t numfeatures,int32_t starti,int32_t endi) +{ + struct ocas_CLbuffers *ptr; struct ocas_lhsbuffers *lhs; + int32_t nonz,weekind,answerind; double answer,y; + if ( numfeatures < 0 ) + return; + vars->maxlhs = MAX_OCAS_LHS; + vars->numfeatures = numfeatures; + vars->maxlen = (endi - starti + 1); + vars->C = 1.; + vars->c = c; + vars->TolRel = 0.01; + vars->TolAbs = 0.0; + vars->QPSolverTolRel = vars->TolRel*0.5; + vars->QPSolverTolAbs = vars->TolAbs*0.5; + vars->MaxTime = OCAS_INFINITY; + vars->QPBound = 0.0; + memset(vars->posA,0,sizeof(vars->posA)); + memset(vars->negA,0,sizeof(vars->negA)); + memset(vars->answeraves,0,sizeof(vars->answeraves)); + memset(vars->answerabsaves,0,sizeof(vars->answerabsaves)); + memset(vars->firstweekinds,0,sizeof(vars->firstweekinds)); + vars->starti = starti; + vars->answers = calloc(TRADEBOTS_NUMANSWERS,sizeof(vars->answers)*vars->maxlen); + vars->features = calloc(vars->maxlen,sizeof(*vars->features)); + for (answerind=0; answerindweekinds[answerind] = calloc(vars->maxlen,sizeof(*vars->weekinds[answerind])); + for (weekind=starti; weekind<=endi; weekind++) + { + if ( (vars->features[weekind - starti]= get_features(numfeatures,c,weekind)) == 0 ) + continue; + for (answerind=0; answerindposA[answerind]+vars->negA[answerind]) >= vars->maxlen ) + continue; + if ( (y= get_yval(&answer,0,weekind,c,answerind)) != 0.f ) + { + vars->answers[(weekind-starti)*TRADEBOTS_NUMANSWERS + answerind] = y; + vars->weekinds[answerind][vars->len[answerind]++] = weekind; + if ( vars->posA[answerind]+vars->negA[answerind] == 0 ) + vars->firstweekinds[answerind] = weekind; + vars->answeraves[answerind] += answer; + if ( answer > 0 ) + { + vars->posA[answerind]++; + vars->answerabsaves[answerind] += answer; + } + else if ( answer < 0 ) + { + vars->negA[answerind]++; + vars->answerabsaves[answerind] -= answer; + } + } + } + } + for (answerind=0; answerindposA[answerind]+vars->negA[answerind])) != 0 ) + { + vars->answerabsaves[answerind] /= nonz; + vars->answeraves[answerind] /= nonz; + printf("A%02d.(%9.6f %d %d) ",answerind,vars->answerabsaves[answerind],vars->posA[answerind],vars->negA[answerind]); + } + init_ocas_vars(1,0,-1,vars,c,vars->C,numfeatures,MAX_OCAS_LHS,vars->maxlen,vars->maxlen,vars->answerabsaves,vars->posA,vars->negA); + for (answerind=0; answerindlen[answerind]); + lhs = vars->lhs[answerind]; + ptr = vars->CLspaces[answerind]; + //printf("%d.A%d call init ocas vars weekinds[0] %p numfeatures.%d (%p %p)\n",c_to_refc(vars->c),answerind,vars->weekinds[0],numfeatures,lhs,ptr); + if ( lhs == 0 || ptr == 0 ) + continue; + vars->numlhs[answerind] = 0;//init_full_A(lhs->full_A,vars->numfeatures,c,answerind,models); + memset(ptr->W,0,sizeof(*ptr->W) * numfeatures); + memset(ptr->oldW,0,sizeof(*ptr->oldW) * numfeatures); + vars->W0[answerind] = vars->oldW0[answerind] = 0; +#ifndef DISABLE_EXISTINGMODEL + double init_model(double *percp,double *W,double *oldW,int c,int answerind,int numfeatures); + vars->W0[answerind] = init_model(&vars->hwmperc[answerind],ptr->W,ptr->oldW,c,answerind,vars->numfeatures); + if ( _dbufave(ptr->W,numfeatures) != 0 ) + validate_ocas_model(vars,answerind,ptr->output_pred,ptr->old_output,vars->weekinds[answerind],vars->len[answerind],ptr->W,vars->W0[answerind],numfeatures,1); +#endif + //printf("%s.A%d call init ocas vars weekinds[0] %p\n",CONTRACTS[c_to_refc(c)],answerind,vars->weekinds[0]); + } + vars->output_time = vars->sort_time = vars->w_time = vars->qp_solver_time = vars->ocas_time = vars->add_time = 0; + vars->startweekind = starti; vars->endweekind = endi; +} + +int32_t ocas_gen(int32_t c,int32_t numfeatures,int32_t starti,int32_t endi) +{ + int32_t i; struct ocas_vars *vars = calloc(1,sizeof(*vars)); + ocas_init(vars,c,numfeatures,starti,endi); + for (i=0; i<10; i++) + ocas_iter(vars,3); + ocas_purge(vars); + return(0); +} +#endif diff --git a/basilisk/tradebots_liquidity.c b/basilisk/tradebots_liquidity.c new file mode 100755 index 000000000..b044accd4 --- /dev/null +++ b/basilisk/tradebots_liquidity.c @@ -0,0 +1,1237 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c +/* + In order to provide liquidity from central exchanges, we need to issue balancing trades, however to do this properly, we need to know what the desired balance is. If unspecified, then a neutral balance is assumed. + The liquidity_info interface is quite flexible, there is a single function liquidity_active() which returns non-zero if the LP node should respond. The model is that the liquidity_command() is used to configure the liquidity_active()'s response. + In order for dynamic adaptiveness to work, the liquidity_command/liquidity_active needs to interact with the balancing. + A simplistic default trio of functions are provided, but any level of complexity is possible with the liquidity interface. + */ + +#define TRADEBOTS_NUMANSWERS 8 +#define TRADEBOTS_NUMDECAYS 8 +#define TRADEBOTS_RAWFEATURESINCR 7 +#define TRADEBOTS_MAXPAIRS 1024 + +#define _OCAS_PLUS_INF (-log(0.0)) +double OCAS_PLUS_INF,OCAS_NEG_INF; + +double Tradebots_decays[TRADEBOTS_NUMDECAYS] = { 0.5, 0.666, 0.8, 0.9, 0.95, 0.99, 0.995, 0.999 }; +int32_t Tradebots_answergaps[TRADEBOTS_NUMANSWERS] = { 60, 60, 120, 120, 240, 240, 720, 720 }; + +struct tradebot_arbentry +{ + char exchange[16]; + double price,volume,profitmargin; + uint32_t timestamp; +}; + +struct tradebot_arbexchange +{ + char name[16]; + struct tradebot_arbentry trades[2]; +}; + +struct tradebot_arbpair +{ + char base[32],rel[32]; + uint32_t lasttime,lastanswertime; FILE *fp; + int32_t numexchanges,counter,btccounter,usdcounter,cnycounter,refc; + double highbid,lowask,hblavolume,btcbid,btcask,btcvol,usdbid,usdask,usdvol,cnybid,cnyask,cnyvol; + double bidaves[TRADEBOTS_NUMDECAYS],askaves[TRADEBOTS_NUMDECAYS]; + double bidslopes[TRADEBOTS_NUMDECAYS],askslopes[TRADEBOTS_NUMDECAYS]; + struct tradebot_arbexchange exchanges[16]; + uint8_t dirmasks[2],slopedirs[2]; + char *svmpairs[TRADEBOTS_MAXPAIRS][2]; + int32_t RTgood[TRADEBOTS_NUMANSWERS],RTbad[TRADEBOTS_NUMANSWERS],numrawfeatures,numsvmfeatures,numpairs; + float rawfeatures[TRADEBOTS_NUMANSWERS+64],prevrawfeatures[60 * TRADEBOTS_NUMANSWERS+64],*svms; // svms is coeffs vector[TRADEBOTS_NUMANSWERS] + float RTpreds[TRADEBOTS_NUMANSWERS],svmpreds[TRADEBOTS_NUMANSWERS],answers[TRADEBOTS_NUMANSWERS]; +}; +struct tradebot_arbpair Arbpairs[TRADEBOTS_MAXPAIRS],*Pair_NXTBTC,*Pair_BTCUSD,*Pair_BTCCNY; +int32_t Tradebot_numarbpairs; + +struct tradebot_arbpair *tradebots_arbpair_find(char *base,char *rel) +{ + int32_t i; + for (i=0; i0; i--) + memcpy(&pair->prevrawfeatures[i*72],&pair->prevrawfeatures[(i-1)*72],sizeof(pair->rawfeatures)); + memcpy(pair->prevrawfeatures,pair->rawfeatures,sizeof(pair->rawfeatures)); + memset(pair->rawfeatures,0,sizeof(pair->rawfeatures)); + if ( fabs(pair->highbid) < SMALLVAL || fabs(pair->lowask) < SMALLVAL ) + return(-1); + ave = _pairaved(pair->highbid,pair->lowask); + timestamp = (uint32_t)time(NULL); + n = TRADEBOTS_NUMANSWERS; + memcpy(&pair->rawfeatures[TRADEBOTS_NUMANSWERS],×tamp,sizeof(*pair->rawfeatures)), n++; + pair->rawfeatures[n++] = pair->highbid; + pair->rawfeatures[n++] = pair->lowask; + pair->rawfeatures[n++] = pair->hblavolume / ave; + n = TRADEBOTS_RAWFEATURESINCR + TRADEBOTS_NUMANSWERS; + for (i=0; ibidaves[i]) < SMALLVAL || fabs(pair->askaves[i]) < SMALLVAL ) + return(-1); + starti = n; + pair->rawfeatures[n++] = (pair->bidaves[i] / ave) - 1.; + pair->rawfeatures[n++] = (pair->askaves[i] / ave) - 1.; + pair->rawfeatures[n++] = 10000. * (pair->bidslopes[i] / ave); + pair->rawfeatures[n++] = 10000. * (pair->askslopes[i] / ave); + if ( n < starti+TRADEBOTS_RAWFEATURESINCR ) + n = starti+TRADEBOTS_RAWFEATURESINCR; + } + if ( pair->fp != 0 ) + { + if ( fwrite(pair->rawfeatures,1,sizeof(pair->rawfeatures),pair->fp) != sizeof(pair->rawfeatures) ) + printf("fwrite error for %s/%s rawfeatures[%d]\n",pair->base,pair->rel,n); + else fflush(pair->fp); + } + if ( n > sizeof(pair->rawfeatures)/sizeof(*pair->rawfeatures) ) + { + printf("n.%d too many for rawfeatures %d\n",n,(int32_t)(sizeof(pair->rawfeatures)/sizeof(*pair->rawfeatures))); + exit(-1); + } + return(n); +} + +uint32_t tradebots_featureset(double *highbidp,double *lowaskp,double *avep,double *volp,double *bidaves,double *askaves,double *bidslopes,double *askslopes,float *rawfeatures) +{ + uint32_t timestamp; int32_t i,n,starti; + memcpy(×tamp,&rawfeatures[TRADEBOTS_NUMANSWERS],sizeof(timestamp)); + n = TRADEBOTS_NUMANSWERS + 1; + *highbidp = rawfeatures[n++]; + *lowaskp = rawfeatures[n++]; + *avep = _pairaved(*highbidp,*lowaskp); + *volp = rawfeatures[n++]; + //printf("[%9.6f %9.6f] vol %f t.%u\n",*highbidp,*lowaskp,*volp,timestamp); + n = TRADEBOTS_RAWFEATURESINCR + TRADEBOTS_NUMANSWERS; + for (i=0; irefc = Tradebot_numarbpairs++; + strcpy(pair->rel,rel); + strcpy(pair->base,base); + if ( strcmp(base,"NXT") == 0 && strcmp(rel,"BTC") == 0 ) + Pair_NXTBTC = pair, printf("Pair_NXTBTC <- %p\n",pair); + else if ( strcmp(base,"BTC") == 0 && strcmp(rel,"USD") == 0 ) + Pair_BTCUSD = pair; + else if ( strcmp(base,"BTC") == 0 && strcmp(rel,"CNY") == 0 ) + Pair_BTCCNY = pair; + sprintf(fname,"SVM/rawfeatures/%s_%s",base,rel); + pair->fp = OS_appendfile(fname); + if ( (ftell(pair->fp) % sizeof(pair->rawfeatures)) != 0 ) + { + printf("misalinged rawfeatures %d %d\n",(uint32_t)ftell(pair->fp),(uint32_t)(ftell(pair->fp) % sizeof(pair->rawfeatures))); + } + fseek(pair->fp,(ftell(pair->fp) / sizeof(pair->rawfeatures)) * sizeof(pair->rawfeatures) - sizeof(pair->rawfeatures),SEEK_SET); + if ( fread(pair->rawfeatures,1,sizeof(pair->rawfeatures),pair->fp) == sizeof(pair->rawfeatures) ) + { + pair->lasttime = tradebots_featureset(&pair->highbid,&pair->lowask,&ave,&pair->hblavolume,pair->bidaves,pair->askaves,pair->bidslopes,pair->askslopes,pair->rawfeatures); + printf("%s/%s [%.8f %.8f] %u\n",pair->base,pair->rel,pair->highbid,pair->lowask,pair->lasttime); + } + return(pair); + } else return(0); +} + +int32_t tradebots_expandrawfeatures(double *svmfeatures,float *rawfeatures,uint32_t reftimestamp,float *refrawfeatures) +{ + double factor,highbid,lowask,ave,vol,bidaves[TRADEBOTS_NUMDECAYS],askaves[TRADEBOTS_NUMDECAYS],bidslopes[TRADEBOTS_NUMDECAYS],askslopes[TRADEBOTS_NUMDECAYS]; + double refhighbid,reflowask,refave,refvol,refbidaves[TRADEBOTS_NUMDECAYS],refaskaves[TRADEBOTS_NUMDECAYS],refbidslopes[TRADEBOTS_NUMDECAYS],refaskslopes[TRADEBOTS_NUMDECAYS]; + uint32_t timestamp; int32_t i,j,starti,n = 0; + tradebots_featureset(&refhighbid,&reflowask,&refave,&refvol,refbidaves,refaskaves,refbidslopes,refaskslopes,refrawfeatures); + timestamp = tradebots_featureset(&highbid,&lowask,&ave,&vol,bidaves,askaves,bidslopes,askslopes,rawfeatures); + if ( timestamp == 0 || reftimestamp == 0 || timestamp >= reftimestamp+60 ) + { + //printf("tradebots_expandrawfeatures: timestamp.%u vs reftimestamp.%u\n",timestamp,reftimestamp); + return(-1); + } + factor = sqrt(reftimestamp - timestamp); + if ( factor > 60. ) + factor = 60.; + else if ( factor < 1. ) + factor = 1.; + factor = 1. / factor; + if ( refhighbid == 0. || highbid == 0. || lowask == 0. || reflowask == 0. ) + { + //printf("tradebots_expandrawfeatures: (%f %f) ref (%f %f)\n",highbid,lowask,refhighbid,reflowask); + return(-1); + } + svmfeatures[n++] = highbid; + svmfeatures[n++] = (highbid / ave) - 1.; + svmfeatures[n++] = lowask; + svmfeatures[n++] = (lowask / ave) - 1.; + svmfeatures[n++] = (lowask - highbid); + svmfeatures[n++] = (lowask - highbid) / ave; + svmfeatures[n++] = vol; + starti = n; + svmfeatures[n++] = refhighbid; + svmfeatures[n++] = (refhighbid / refave) - 1.; + svmfeatures[n++] = reflowask; + svmfeatures[n++] = (reflowask / refave) - 1.; + svmfeatures[n++] = (reflowask - refhighbid); + svmfeatures[n++] = (reflowask - refhighbid) / refave; + svmfeatures[n++] = refvol; + for (i=0; i SMALLVAL ) + { + for (i=starti; i 0. ) + svmfeatures[i] = cbrt(svmfeatures[i]); + else svmfeatures[i] = -cbrt(-svmfeatures[i]); + } + } + return(n); +} + +int32_t tradebots_calcsvmfeatures(double *svmfeatures,struct tradebot_arbpair *pair,float *rawfeatures,float *prevrawfeatures) +{ + int32_t i,j,n,numpairfeatures,flag; struct tradebot_arbpair *ptr; uint32_t reftimestamp; + memcpy(&reftimestamp,&rawfeatures[TRADEBOTS_NUMANSWERS],sizeof(reftimestamp)); + if ( reftimestamp == 0 ) + { + printf("reftimestamp.%u is illegal\n",reftimestamp); + return(-1); + } + numpairfeatures = n = tradebots_expandrawfeatures(svmfeatures,prevrawfeatures,reftimestamp,rawfeatures); + if ( n <= 0 ) + return(-1); + for (i=0; i<60; i++,n+=numpairfeatures) + tradebots_expandrawfeatures(&svmfeatures[n],&prevrawfeatures[i*72],reftimestamp,rawfeatures); + if ( 0 && pair->numsvmfeatures != (1+pair->numpairs)*n ) + { + for (i=0; inumpairs; i++) // need to do lookups + { + flag = -1; + if ( (ptr= tradebots_arbpair_find(pair->svmpairs[i][0],pair->svmpairs[i][1])) != 0 ) + flag = tradebots_expandrawfeatures(&svmfeatures[n],ptr->rawfeatures,reftimestamp,rawfeatures); + if ( flag < 0 ) + { + for (j=0; jsvms != 0 ) + { + for (i=n=0; inumsvmfeatures; i++) + { + feature = svmfeatures[i]; + for (j=0; jsvms[n++]; + } + } + return(n); +} + +void tradebots_calcanswers(struct tradebot_arbpair *pair) +{ + double highbid,lowask,futurebid,futureask,ave,vol,bidaves[TRADEBOTS_NUMDECAYS],askaves[TRADEBOTS_NUMDECAYS],bidslopes[TRADEBOTS_NUMDECAYS],askslopes[TRADEBOTS_NUMDECAYS]; + float rawfeatures[sizeof(pair->rawfeatures)/sizeof(*pair->rawfeatures)],futuremin=0,futuremax=0,minval=0,maxval=0,*hblas = 0; + uint32_t timestamp,firsttime = 0; long fpos,savepos; int32_t flag,i,iter,j,ind,maxi=0; + OCAS_PLUS_INF = _OCAS_PLUS_INF; OCAS_NEG_INF = -_OCAS_PLUS_INF; + if ( pair->fp != 0 ) + { + for (iter=0; iter<2; iter++) + { + rewind(pair->fp); + fpos = 0; + while ( fread(rawfeatures,1,sizeof(pair->rawfeatures),pair->fp) == sizeof(pair->rawfeatures) ) + { + savepos = ftell(pair->fp); + timestamp = tradebots_featureset(&highbid,&lowask,&ave,&vol,bidaves,askaves,bidslopes,askslopes,rawfeatures); + //printf("timestamp.%u firsttime.%u\n",timestamp,firsttime); + if ( timestamp == 0 ) + continue; + if ( firsttime == 0 ) + { + firsttime = timestamp; + maxi = (int32_t)((time(NULL) - firsttime) / 60 + 1); + hblas = calloc(maxi,sizeof(*hblas)*2); + printf("HBLAS[%d] allocated\n",maxi); + } + if ( (i= (timestamp - firsttime)/60) >= 0 && i < maxi ) + { + if ( iter == 0 ) + { + if ( hblas[i << 1] == 0 ) + { + hblas[i << 1] = highbid; + hblas[(i << 1) + 1] = lowask; + } + else + { + _xblend(&hblas[i << 1],highbid,0.5); + _xblend(&hblas[(i << 1) + 1],lowask,0.5); + } + } + else + { + highbid = hblas[i << 1]; + lowask = hblas[(i << 1) + 1]; + if ( fabs(highbid) > SMALLVAL && fabs(lowask) > SMALLVAL ) + { + memset(pair->answers,0,sizeof(pair->answers)); + flag = 0; + for (j=0; janswers[j] = _pairaved(futuremax,futuremin) - _pairaved(minval,maxval); + else + { + futurebid = hblas[ind << 1]; + futureask = hblas[(ind << 1) + 1]; + minval = MIN(highbid,lowask); + maxval = MAX(highbid,lowask); + futuremin = MIN(futurebid,futureask); + futuremax = MAX(futurebid,futureask); + if ( futuremin > maxval ) + { + if ( futuremax < minval ) + printf("%s/%s A%d: highly volatile minmax.(%f %f) -> (%f %f) %d of %d\n",pair->base,pair->rel,j,minval,maxval,futuremin,futuremax,i,maxi); + else + { + pair->answers[j] = (futuremin - maxval); + flag++; + } + } + else if ( futuremax < minval ) + pair->answers[j] = (futuremax - minval), flag++; + //printf("i.%d j.%d gap.%d ind.%d answer %9.6f (%f %f) -> (%f %f)\n",i,j,Tradebots_answergaps[j],ind,pair->answers[j],minval,maxval,futuremin,futuremax); + } + } + } + if ( flag != 0 ) + { + fseek(pair->fp,fpos,SEEK_SET); + if ( fwrite(pair->answers,1,sizeof(pair->answers),pair->fp) != sizeof(pair->answers) ) + printf("error writing answers for %s/%s t%u i.%d of %d\n",pair->base,pair->rel,timestamp,i,maxi); + else if ( 0 ) + { + for (j=0; janswers[j]); + printf("%s/%s answers %d of %d\n",pair->base,pair->rel,i,maxi); + } + fseek(pair->fp,savepos,SEEK_SET); + } + } + } + } + fpos = ftell(pair->fp); + } + if ( iter == 0 ) + { + if ( hblas == 0 ) + break; + highbid = hblas[0]; + lowask = hblas[1]; + for (i=1; i SMALLVAL && fabs(hblas[(i << 1) + 1]) > SMALLVAL ) + { + highbid = hblas[i << 1]; + lowask = hblas[(i << 1) + 1]; + } + else + { + hblas[i << 1] = highbid; + hblas[(i << 1) + 1] = lowask; + } + //printf("%9.6f ",_pairaved(highbid,lowask)); + } + //printf("maxi.%d\n",maxi); + } + } + if ( hblas != 0 ) + free(hblas); + } + if ( pair->fp != 0 && (ftell(pair->fp) % sizeof(pair->rawfeatures)) != 0 ) + printf("ERROR: %s/%s not on feature boundary\n",pair->base,pair->rel); +} + +double get_yval(double *answerp,int32_t selector,int32_t ind,int32_t refc,int32_t answerind) +{ + float answer; struct tradebot_arbpair *pair; long savepos; + pair = &Arbpairs[refc]; + if ( pair->fp != 0 ) + { + savepos = ftell(pair->fp); + fseek(pair->fp,ind*sizeof(pair->rawfeatures)+answerind*sizeof(*pair->rawfeatures),SEEK_SET); + if ( fread(&answer,1,sizeof(answer),pair->fp) != sizeof(answer) ) + answer = 0; + fseek(pair->fp,savepos,SEEK_SET); + if ( isnan(answer) != 0 ) + return(0); + answer /= 10.; + /*if ( answer > .01 ) + answer = .01; + else if ( answer < -.01 ) + answer = -.01; + if ( answerp != 0 ) + *answerp = answer; + */ + if ( answer > 0. ) + answer = sqrt(answer); + else answer = -sqrt(-answer); + *answerp = answer; + /*if ( answer > 0. ) + return(1.); + else if ( answer < 0. ) + return(-1.);*/ + return(answer); + } + return(0.); +} + +float *get_features(int32_t numfeatures,int32_t refc,int32_t ind) +{ + struct tradebot_arbpair *pair; long savepos; int32_t i,n; double svmfeatures[32768]; + float rawfeatures[sizeof(pair->rawfeatures)],prevrawfeatures[60 * sizeof(pair->rawfeatures)],*svmf=0; + pair = &Arbpairs[refc]; + pair->numsvmfeatures = numfeatures; + if ( pair->fp != 0 && ind > 61 ) + { + savepos = ftell(pair->fp); + fseek(pair->fp,(ind-60)*sizeof(pair->rawfeatures),SEEK_SET); + if ( fread(prevrawfeatures,60,sizeof(pair->rawfeatures),pair->fp) == sizeof(pair->rawfeatures) && fread(&rawfeatures,1,sizeof(pair->rawfeatures),pair->fp) == sizeof(pair->rawfeatures) ) + { + n = tradebots_calcsvmfeatures(svmfeatures,pair,rawfeatures,prevrawfeatures); + //int32_t nonz; for (i=nonz=0; i %d\n",ind,n); + if ( n != pair->numsvmfeatures ) + { + //printf("unexpected numsvmfeatures refc.%d ind.%d %d vs %d\n",refc,ind,n,pair->numsvmfeatures); + return(0); + } + svmf = calloc(n,sizeof(*svmf)); + for (i=0; ifp,savepos,SEEK_SET); + } + return(svmf); +} + +/*double set_ocas_model(int refc,int answerind,double *W,double W0,int numfeatures,int firstweekind,int len,int bad,double dist,double predabs,int posA,int negA,double answerabs,double aveanswer) +{ + int32_t i,nonz=0; + for (i=0; i 0 ) + { + bestmodel = W; + if ( bestmodel != 0 ) + { + for (j=0; j<=numfeatures; j++) + { + if ( bestmodel[j] != 0 ) + nonz++; + oldW[j] = W[j]; + } + if ( nonz != 0 ) + return(bestmodel[numfeatures]); + } + } + return(0.); +} + +double set_ocas_model(int refc,int answerind,double *W,double W0,int numfeatures,int firstweekind,int len,int bad,double dist,double predabs,int posA,int negA,double answerabs,double aveanswer) +{ + double perc = (100. * (double)(len - bad)) / len; +#ifndef DISABLE_EXISTINGMODEL + int32_t _posA,_negA; double *tmpW,fileperc; + tmpW = calloc(numfeatures+2,sizeof(*tmpW)); + if ( (fileperc= load_model(&_posA,&_negA,tmpW,refc,answerind,numfeatures)) > perc ) + { + if ( (_posA+_negA) != 0 && _posA >= posA && _negA >= negA ) + { + memcpy(W,tmpW,sizeof(*W)*numfeatures); + printf("%s/%s.A%02d numfeatures.%d posA.%d negA.%d saved model %f is better than %f +A%d -A%d\n",Arbpairs[refc].base,Arbpairs[refc].rel,answerind,numfeatures,_posA,_negA,fileperc,perc,posA,negA); + W0 = tmpW[numfeatures]; + free(tmpW); + return(tmpW[numfeatures]); + } + } + free(tmpW); +#endif + save_model(refc,answerind,W,numfeatures,W0,perc,posA,negA); + return(W0); +} + +#ifndef _WIN +#include "tradebots_SVM.h" +#endif + +static char *assetids[][2] = +{ + { "12071612744977229797", "UNITY" }, + { "15344649963748848799", "DEX" }, + { "6883271355794806507", "PANGEA" }, + { "17911762572811467637", "JUMBLR" }, + { "17083334802666450484", "BET" }, + { "13476425053110940554", "CRYPTO" }, + { "6932037131189568014", "HODL" }, + { "3006420581923704757", "SHARK" }, + { "17571711292785902558", "BOTS" }, + { "10524562908394749924", "MGW" }, +}; + +uint64_t NXT_assetidfind(char *base) +{ + int32_t i; + for (i=0; iexchange[0] == 0 ) + strcpy(arb->exchange,exchange); + if ( strcmp(arb->exchange,exchange) == 0 ) + { + arb->price = price; + arb->volume = volume; + arb->timestamp = timestamp; + arb->profitmargin = profitmargin; + } else printf("mismatched arbexchange? (%s vs %s)\n",arb->exchange,exchange); +} + +struct tradebot_arbexchange *tradebots_arbexchange_find(struct tradebot_arbpair *pair,char *exchange) +{ + int32_t i; + if ( pair->numexchanges > sizeof(pair->exchanges)/sizeof(*pair->exchanges) ) + { + printf("data corruption pair.%p %s %s/%s numexchanges.%d\n",pair,exchange,pair->base,pair->rel,pair->numexchanges); + return(0); + } + for (i=0; inumexchanges; i++) + if ( strcmp(pair->exchanges[i].name,exchange) == 0 ) + return(&pair->exchanges[i]); + return(0); +} + +struct tradebot_arbexchange *tradebots_arbexchange_create(struct tradebot_arbpair *pair,char *exchange) +{ + if ( pair->numexchanges < sizeof(pair->exchanges)/sizeof(*pair->exchanges) ) + { + strcpy(pair->exchanges[pair->numexchanges].name,exchange); + return(&pair->exchanges[pair->numexchanges++]); + } else return(0); +} + +void tradebot_arbcandidate(struct supernet_info *myinfo,char *exchange,int32_t tradedir,char *base,char *rel,double price,double volume,uint32_t timestamp,double profitmargin) +{ + int32_t i,offset,flag; double highbid,lowask,lastbid,lastask,arbval; uint32_t now; + struct tradebot_arbentry *bid,*ask; struct tradebot_arbexchange *arbex; struct tradebot_arbpair *pair = 0; + if ( strcmp(rel,"BTC") != 0 && strcmp(rel,"NXT") != 0 && strcmp(rel,"USD") != 0 && strcmp(rel,"CNY") != 0 ) + { + printf("reject non-BTC arbcandidate (%s/%s)\n",base,rel); + return; + } + offset = (tradedir > 0) ? 0 : 1; + if ( (pair= tradebots_arbpair_find(base,rel)) == 0 ) + pair = tradebots_arbpair_create(base,rel); + if ( pair == 0 ) + { + printf("cant get pair for %s %s/%s\n",exchange,base,rel); + return; + } + if ( (arbex= tradebots_arbexchange_find(pair,exchange)) == 0 ) + arbex = tradebots_arbexchange_create(pair,exchange); + if ( arbex != 0 ) + { + //printf("cand.%d %16s %s %12.6f (%5s/%-5s) at %12.8f profit %.03f\n",pair->numexchanges,exchange,tradedir<0?"ask":"bid",volume,base,rel,price,profitmargin); + tradebot_arbentry(&arbex->trades[offset],exchange,price,volume,timestamp,profitmargin); + bid = ask = 0; + pair->highbid = pair->lowask = highbid = lowask = 0.; + now = (uint32_t)time(NULL); + //if ( pair->numexchanges >= 2 ) + { + for (i=0; inumexchanges; i++) + { + arbex = &pair->exchanges[i]; + if ( arbex->trades[0].price != 0. && (highbid == 0. || arbex->trades[0].price >= highbid) ) + { + bid = &arbex->trades[0]; + if ( now > bid->timestamp+30 ) + bid->price = 0.; + else highbid = bid->price; + } + if ( arbex->trades[1].price != 0. && (lowask == 0. || arbex->trades[1].price <= lowask) ) + { + ask = &arbex->trades[1]; + if ( now > ask->timestamp+30 ) + ask->price = 0.; + else lowask = ask->price; + } + //printf("%p %s %s %f %f -> %p %p %f %f (%f %f)\n",pair,pair->base,arbex->name,arbex->trades[0].price,arbex->trades[1].price,bid,ask,highbid,lowask,pair->highbid,pair->lowask); + } + flag = 0; + if ( Pair_NXTBTC != 0 && pair->btccounter != Pair_NXTBTC->counter ) + flag |= 1; + if ( Pair_BTCUSD != 0 && pair->usdcounter != Pair_BTCUSD->counter ) + flag |= 2; + if ( Pair_BTCCNY != 0 && pair->cnycounter != Pair_BTCCNY->counter ) + flag |= 4; + //printf("%s %s/%s flag.%d (%d %d) %p %p\n",exchange,base,rel,flag,pair->btccounter,Pair_NXTBTC!=0?Pair_NXTBTC->counter:-1,bid,ask); + if ( bid != 0 && ask != 0 && bid->price != 0. && ask->price != 0 && (now - bid->timestamp) < 30 && (now - ask->timestamp) < 30 && (fabs(bid->price - pair->highbid) > SMALLVAL || fabs(ask->price - pair->lowask) > SMALLVAL || (strcmp(pair->rel,"NXT") == 0 && flag != 0)) ) + { + pair->counter++; + pair->hblavolume = volume = MIN(bid->volume,ask->volume); + arbval = lastbid = lastask = 0.; + memset(pair->dirmasks,0,sizeof(pair->dirmasks)); + memset(pair->slopedirs,0,sizeof(pair->slopedirs)); + if ( strcmp(pair->rel,"NXT") == 0 ) + { + if ( Pair_NXTBTC != 0 && Pair_NXTBTC->highbid != 0. && Pair_NXTBTC->lowask != 0. ) + { + pair->btccounter = Pair_NXTBTC->counter; + pair->btcbid = highbid * Pair_NXTBTC->highbid; + pair->btcask = lowask * Pair_NXTBTC->lowask; + pair->btcvol = volume * _pairaved(pair->btcbid,pair->btcask); + } + } + else if ( strcmp(pair->rel,"BTC") == 0 ) + { + pair->btcbid = highbid; + pair->btcask = lowask; + pair->btcvol = volume; + } + if ( strcmp(pair->rel,"USD") == 0 ) + { + pair->usdbid = highbid; + pair->usdask = lowask; + pair->usdvol = volume; + } + if ( strcmp(pair->rel,"CNY") == 0 ) + { + pair->cnybid = highbid; + pair->cnyask = lowask; + pair->cnyvol = volume; + } + if ( pair->btcbid != 0. && pair->btcask != 0. ) + { + if ( strcmp(pair->rel,"USD") != 0 && Pair_BTCUSD != 0 && Pair_BTCUSD->highbid != 0. && Pair_BTCUSD->lowask != 0. ) + { + pair->usdcounter = Pair_BTCUSD->counter; + pair->usdbid = pair->btcbid * Pair_BTCUSD->highbid; + pair->usdask = pair->btcask * Pair_BTCUSD->lowask; + pair->usdvol = pair->btcvol * _pairaved(pair->usdbid,pair->usdask); + } + if ( strcmp(pair->rel,"CNY") != 0 && Pair_BTCCNY != 0 && Pair_BTCCNY->highbid != 0. && Pair_BTCCNY->lowask != 0. ) + { + pair->cnycounter = Pair_BTCCNY->counter; + pair->cnybid = pair->btcbid * Pair_BTCCNY->highbid; + pair->cnyask = pair->btcask * Pair_BTCCNY->lowask; + pair->cnyvol = pair->btcvol * _pairaved(pair->cnybid,pair->cnyask); + } + } + for (i=0; ibidslopes[i]= dxblend(&pair->bidaves[i],highbid,Tradebots_decays[i])) > 0. ) + pair->slopedirs[0] |= (1 << i); + if ( (pair->askslopes[i]= dxblend(&pair->askaves[i],lowask,Tradebots_decays[i])) > 0. ) + pair->slopedirs[1] |= (1 << i); + lastbid = pair->bidaves[i]; + lastask = pair->askaves[i]; + //printf("(%.8f %.8f) ",lastbid,lastask); + } + for (i=0; i lastbid ) + pair->dirmasks[0] |= (1 << i); + if ( lowask > lastask ) + pair->dirmasks[1] |= (1 << i); + } + else + { + if ( pair->bidaves[i-1] > lastbid ) + pair->dirmasks[0] |= (1 << i); + if ( pair->askaves[i-1] > lastask ) + pair->dirmasks[1] |= (1 << i); + } + } + //printf("%12.6f %7s/%-3s %8s %14.8f %8s %14.8f spread %6.2f%% %02x:%02x %02x:%02x %d\n",volume,base,rel,bid->exchange,highbid,ask->exchange,lowask,100.*(lowask-highbid)/_pairaved(highbid,lowask),pair->dirmasks[0],pair->slopedirs[0],pair->dirmasks[1],pair->slopedirs[1],pair->counter); + //printf("BTC.(%.8f %.8f) %.8f %.8f USD.(%.4f %.4f) CNY.(%.3f %.3f)\n",pair->btcbid,pair->btcask,Pair_BTCUSD!=0?Pair_BTCUSD->highbid:0,Pair_BTCUSD!=0?Pair_BTCUSD->lowask:0,pair->usdbid,pair->usdask,pair->cnybid,pair->cnyask); + } + if ( highbid != 0 ) + pair->highbid = highbid; + if ( lowask != 0 ) + pair->lowask = lowask; + //printf(">>>>>>> %s (%s/%s) BTC %.8f %.8f v%f counter.%d btc.%d (%d)\n",exchange,pair->base,pair->rel,pair->btcbid,pair->btcask,pair->btcvol,pair->counter,pair->btccounter,Pair_NXTBTC!=0?Pair_NXTBTC->counter:-1); + if ( bid != 0 && ask != 0 && highbid != 0. && lowask != 0. && highbid > lowask && strcmp(bid->exchange,ask->exchange) != 0 && strcmp(rel,"BTC") == 0 ) + { + volume = MIN(bid->volume,ask->volume); + if ( volume*_pairaved(highbid,lowask) > 0.1 ) + volume = 0.1 / _pairaved(highbid,lowask); + if ( highbid * (1. - bid->profitmargin) > lowask * (1. + ask->profitmargin) ) + { + arbval = highbid * (1. - bid->profitmargin) - lowask * (1. + ask->profitmargin); + printf(">>>>>>>> FOUND ARB %s/%s highbid.%s %.8f lowask.%s %.8f volume %f (%.8f %.8f) %.4f%%\n",pair->base,pair->rel,bid->exchange,bid->price,ask->exchange,ask->price,volume,highbid,lowask,100.*(highbid-lowask)/_pairaved(highbid,lowask)); + InstantDEX_buy(myinfo,0,0,0,ask->exchange,pair->base,"BTC",ask->price,volume,1); + InstantDEX_sell(myinfo,0,0,0,bid->exchange,pair->base,"BTC",bid->price,volume,1); + printf("finished trades %s/%s volume %f\n",pair->base,pair->rel,volume); + } + } + if ( pair->counter > TRADEBOTS_NUMDECAYS ) + { + if ( pair->lasttime != time(NULL) ) + { + if ( (pair->numrawfeatures= tradebots_calcrawfeatures(pair)) > 0 ) + { + if ( pair->numsvmfeatures != 0 ) + { + if ( myinfo->svmfeatures == 0 ) + myinfo->svmfeatures = calloc(sizeof(*myinfo->svmfeatures),pair->numsvmfeatures); + if ( tradebots_calcsvmfeatures(myinfo->svmfeatures,pair,pair->rawfeatures,pair->prevrawfeatures) > 0 ) + tradebots_calcpreds(pair->RTpreds,pair,myinfo->svmfeatures); + } + } + pair->lasttime = (uint32_t)time(NULL); + } + if ( 0 && time(NULL) > pair->lastanswertime+3600 ) + { + tradebots_calcanswers(pair); + pair->lastanswertime = (uint32_t)time(NULL); + } + } + } + } +} + +cJSON *linfo_json(struct liquidity_info *li) +{ + cJSON *item = cJSON_CreateObject(); + jaddstr(item,"base",li->base); + jaddstr(item,"rel",li->rel); + if ( li->exchange[0] != 0 ) + jaddstr(item,"exchange",li->exchange); + if ( li->assetid != 0 ) + jadd64bits(item,"assetid",li->assetid); + if ( li->profit != 0. ) + jaddnum(item,"profitmargin",li->profit); + if ( li->refprice != 0. ) + jaddnum(item,"refprice",li->refprice); + if ( li->bid != 0. ) + jaddnum(item,"bid",li->bid); + if ( li->ask != 0. ) + jaddnum(item,"ask",li->ask); + if ( li->minvol != 0. ) + jaddnum(item,"minvol",li->minvol); + if ( li->maxvol != 0. ) + jaddnum(item,"maxvol",li->maxvol); + if ( li->totalvol != 0. ) + jaddnum(item,"totalvol",li->totalvol); + return(item); +} + +void _default_liquidity_command(struct supernet_info *myinfo,char *base,bits256 hash,cJSON *vals) +{ + struct liquidity_info li,refli; int32_t i; char *exchange,*relstr,numstr[32]; + if ( (exchange= jstr(vals,"exchange")) == 0 ) + exchange = "DEX"; + else if ( strcmp(exchange,"*") == 0 ) + exchange = ""; + else if ( exchanges777_find(exchange) == 0 ) + { + printf("cant find exchange.(%s)\n",exchange); + return; + } + if ( (relstr= jstr(vals,"rel")) == 0 ) + relstr = "BTC"; + if ( base == 0 || base[0] == 0 ) + base = jstr(vals,"base"); + if ( base == 0 || base[0] == 0 ) + return; + memset(&li,0,sizeof(li)); + safecopy(li.base,base,sizeof(li.base)); + safecopy(li.rel,relstr,sizeof(li.rel)); + strncpy(li.exchange,exchange,sizeof(li.exchange)); + li.profit = jdouble(vals,"profit"); + li.refprice = jdouble(vals,"refprice"); + li.bid = jdouble(vals,"bid"); + li.ask = jdouble(vals,"ask"); + if ( (li.minvol= jdouble(vals,"minvol")) <= 0. ) + li.minvol = (strcmp("BTC",base) == 0) ? 0.0001 : 0.001; + if ( strcmp(li.base,"KMD") == 0 && strcmp(li.rel,"BTC") == 0 && li.minvol >= 100. ) + li.minvol = 100.; + if ( (li.maxvol= jdouble(vals,"maxvol")) < li.minvol ) + li.maxvol = li.minvol; + if ( (li.totalvol= jdouble(vals,"total")) < li.maxvol ) + li.totalvol = li.maxvol; + if ( strcmp("NXT",li.rel) == 0 ) + li.assetid = NXT_assetidfind(base); + else if ( strcmp("UNITY",base) == 0 ) + li.assetid = NXT_assetidfind(base); + if ( strcmp(li.base,"BTC") == 0 && strcmp("USD",li.rel) != 0 && strcmp("CNY",li.rel) != 0 ) + { + printf("unsupported base BTC (%s/%s)\n",li.base,li.rel); + return; + } + if ( strcmp(li.base,"BTC") != 0 && strcmp("BTC",li.rel) != 0 && + strcmp(li.base,"NXT") != 0 && strcmp("NXT",li.rel) != 0 && + strcmp(li.base,"USD") != 0 && strcmp("USD",li.rel) != 0 && + strcmp(li.base,"CNY") != 0 && strcmp("CNY",li.rel) != 0 && + strcmp(li.exchange,"DEX") != 0 ) // filter out most invalids + { + printf("unsupported base/rel %s/%s\n",li.base,li.rel); + return; + } + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + refli = myinfo->linfos[i]; + if ( strcmp(li.rel,refli.base) == 0 && strcmp(li.base,refli.rel) == 0 ) + { + /*li = refli; + strcpy(li.base,refli.base); + strcpy(li.rel,refli.rel); + if ( fabs(li.refprice) > SMALLVAL ) + li.refprice = (1. / li.refprice); + else li.refprice = 0.; + li.dir = -li.dir; + myinfo->linfos[i] = li;*/ + printf("cant Set rev linfo[%d] (%s/%s) %.6f %.8f already have (%s/%s)\n",i,li.rel,li.base,li.profit,li.refprice,refli.base,refli.rel); + return; + } + else if ( refli.base[0] == 0 || (strcmp(li.base,refli.base) == 0 && strcmp(li.rel,refli.rel) == 0 && strcmp(li.exchange,refli.exchange) == 0) ) + { + if ( refli.base[0] == 0 && li.exchange[0] != 0 && strcmp(li.exchange,"DEX") != 0 ) + { + if ( strcmp("NXT",li.rel) == 0 && li.assetid != 0 ) + { + sprintf(numstr,"%llu",(long long)li.assetid); + printf("monitor %s %s\n",li.rel,numstr); + tradebot_monitor(myinfo,0,0,0,li.exchange,numstr,li.rel,0.); + } else tradebot_monitor(myinfo,0,0,0,li.exchange,li.base,li.rel,0.); + } + myinfo->linfos[i] = li; + //printf("Set linfo[%d] %s (%s/%s) profitmargin %.6f bid %.8f ask %.8f minvol %.6f maxvol %.6f ref %.8f <- (%s)\n",i,li.exchange,li.base,li.rel,li.profit,li.bid,li.ask,li.minvol,li.maxvol,li.refprice,jprint(vals,0)); + return; + } + } + printf("ERROR: too many linfos %d\n",i); +} + +int32_t _default_volume_ok(struct supernet_info *myinfo,struct liquidity_info *li,int32_t dir,double volume,double price) +{ + double minvol,maxvol; + if ( dir < 0 ) + { + minvol = li->minvol; + maxvol = li->maxvol; + } + else + { + minvol = price * li->minvol; + maxvol = price * li->maxvol; + } + printf("dir.%d minvol %f maxvol %f vs (%f %f) volume %f price %.8f\n",dir,li->minvol,li->maxvol,minvol,maxvol,volume,price); + if ( (minvol == 0. || volume >= minvol) && (maxvol == 0. || volume <= maxvol) ) + return(0); + else return(-1); +} + +double _default_liquidity_active(struct supernet_info *myinfo,double *refpricep,char *exchange,char *base,char *rel,double destvolume) +{ + int32_t i,dir; struct liquidity_info refli; + *refpricep = 0.; + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + refli = myinfo->linfos[i]; + if ( refli.base[0] == 0 ) + continue; + if ( strcmp(base,refli.base) == 0 && strcmp(rel,refli.rel) == 0 ) + dir = 1; + else if ( strcmp(rel,refli.base) == 0 && strcmp(base,refli.rel) == 0 ) + dir = -1; + else continue; + if ( exchange[0] != 0 && refli.exchange[0] != 0 && strcmp(exchange,refli.exchange) != 0 ) + { + printf("continue %s %s/%s [%d] dir.%d vs %s %s/%s\n",exchange,base,rel,i,dir,refli.exchange,refli.base,refli.rel); + continue; + } + if ( _default_volume_ok(myinfo,&refli,dir,destvolume,dir > 0 ? refli.bid : refli.ask) == 0 ) + { + if ( refli.profit != 0. ) + *refpricep = refli.refprice; + else if ( dir > 0 ) + *refpricep = refli.bid; + else if ( dir < 0 ) + *refpricep = refli.ask; + printf(">>>>>>>> %s %s/%s [%d] dir.%d vs %s/%s -> %.8f margin %f\n",exchange,base,rel,i,dir,refli.base,refli.rel,*refpricep,refli.profit); + return(refli.profit); + } + break; + } + return(0.); +} + +struct liquidity_info *_default_lifind(struct supernet_info *myinfo,int32_t *dirp,char *base,char *rel) +{ + struct liquidity_info *li; int32_t i; + *dirp = 0; + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + li = &myinfo->linfos[i]; + if ( strcmp(li->base,base) == 0 && strcmp(li->rel,rel) == 0 ) + { + *dirp = 1; + return(li); + } + else if ( strcmp(li->base,rel) == 0 && strcmp(li->rel,base) == 0 ) + { + *dirp = -1; + return(li); + } + } + return(0); +} + +void _default_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob) +{ + // update balance, compare to target balance, issue balancing trade via central exchanges, if needed + struct liquidity_info *li; double vol,price,volume,srcamount,destamount,profitmargin,dir=0.,dotrade=1.; char base[64],rel[64]; int32_t idir; char *tradestr=0; cJSON *tradejson; + srcamount = swap->I.req.srcamount; + destamount = swap->I.req.destamount; + profitmargin = (double)swap->I.req.profitmargin / 1000000.; + if ( srcamount <= SMALLVAL || destamount <= SMALLVAL ) + { + printf("illegal amount for balancing %f %f\n",srcamount,destamount); + return; + } + if ( (li= _default_lifind(myinfo,&idir,swap->I.req.src,swap->I.req.dest)) != 0 ) + { + if ( idir < 0 ) + vol = 1. / ((double)destamount / SATOSHIDEN); + else vol = ((double)srcamount / SATOSHIDEN); + li->totalvol -= vol; + if ( li->totalvol <= 0. || (li->minvol != 0. && li->totalvol < li->minvol) ) + li->minvol = li->maxvol = li->totalvol = 0.; + printf("li.(%s/%s) totalvol %f after -= %f minmax.(%f %f)\n",li->base,li->rel,li->totalvol,vol,li->minvol,li->maxvol); + } + strcpy(rel,"BTC"); + if ( strcmp(swap->I.req.src,"BTC") == 0 ) + { + strcpy(base,swap->I.req.dest); + price = (srcamount / destamount); + volume = destamount / SATOSHIDEN; + dir = -1.; + } + else if ( strcmp(swap->I.req.dest,"BTC") == 0 ) + { + strcpy(base,swap->I.req.src); + price = (destamount / srcamount); + volume = srcamount / SATOSHIDEN; + dir = 1.; + } + else + { + printf("only BTC trades can be balanced, not (%s/%s)\n",swap->I.req.src,swap->I.req.dest); + return; + } + if ( iambob != 0 ) + { + if ( myinfo->IAMLP != 0 ) + { + printf("BOB: price %f * vol %f -> %s newprice %f margin %.2f%%\n",price,volume,dir < 0. ? "buy" : "sell",price + dir * price * profitmargin,100*profitmargin); + if ( dir < 0. ) + tradestr = InstantDEX_buy(myinfo,0,0,0,"bittrex",base,rel,price,volume,dotrade); + else tradestr = InstantDEX_sell(myinfo,0,0,0,"bittrex",base,rel,price,volume,dotrade); + } + } + else + { + if ( myinfo->IAMLP != 0 ) + { + printf("ALICE: price %f * vol %f -> %s newprice %f margin %.2f%%\n",price,volume,dir > 0. ? "buy" : "sell",price - dir * price * profitmargin,100*profitmargin); + if ( dir > 0. ) + tradestr = InstantDEX_buy(myinfo,0,0,0,"bittrex",base,rel,price,volume,dotrade); + else tradestr = InstantDEX_sell(myinfo,0,0,0,"bittrex",base,rel,price,volume,dotrade); + } + } + if ( tradestr != 0 ) + { + if ( (tradejson= cJSON_Parse(tradestr)) != 0 ) + { + if ( jobj(tradejson,"error") == 0 ) // balancing is opposite trade + tradebot_pendingadd(myinfo,tradejson,swap->I.req.dest,destamount,swap->I.req.src,srcamount); + else free_json(tradejson); + } + free(tradestr); + } +} + +void tradebot_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob) +{ + if ( swap->bobcoin != 0 && swap->alicecoin != 0 ) + { + if ( iambob != 0 ) + { + if ( strcmp(swap->I.req.src,swap->bobcoin->symbol) == 0 ) + swap->bobcoin->DEXinfo.DEXpending -= swap->I.req.srcamount; + else if ( strcmp(swap->I.req.dest,swap->bobcoin->symbol) == 0 ) + swap->bobcoin->DEXinfo.DEXpending -= swap->I.req.destamount; + } + else + { + if ( strcmp(swap->I.req.src,swap->alicecoin->symbol) == 0 ) + swap->alicecoin->DEXinfo.DEXpending -= swap->I.req.srcamount; + else if ( strcmp(swap->I.req.dest,swap->alicecoin->symbol) == 0 ) + swap->alicecoin->DEXinfo.DEXpending -= swap->I.req.destamount; + } + } + printf(">>>>>>>>>>>>>>>>>> balancing trade done by marketmaker\n"); + return; + if ( swap->balancingtrade == 0 ) + _default_swap_balancingtrade(myinfo,swap,iambob); + else (*swap->balancingtrade)(myinfo,swap,iambob); +} + +void tradebot_liquidity_command(struct supernet_info *myinfo,char *base,bits256 hash,cJSON *vals) +{ + // processed in LIFO manner which allows to override existing command + if ( myinfo->liquidity_command == 0 ) + _default_liquidity_command(myinfo,base,hash,vals); + else (*myinfo->liquidity_command)(myinfo,base,hash,vals); +} + +double tradebot_liquidity_active(struct supernet_info *myinfo,double *refpricep,char *exchange,char *base,char *rel,double destvolume) +{ + if ( myinfo->liquidity_active == 0 ) + return(_default_liquidity_active(myinfo,refpricep,exchange,base,rel,destvolume)); + else return((*myinfo->liquidity_active)(myinfo,refpricep,exchange,base,rel,destvolume)); +} + +// struct exchange_quote { uint64_t satoshis,orderid,offerNXT,exchangebits; double price,volume; uint32_t timestamp,val; }; + +void tradebots_processprices(struct supernet_info *myinfo,struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t numbids,int32_t numasks) +{ + double price,profitmargin=0.,volume; struct tradebot_arbpair *pair; + if ( strcmp(rel,"NXT") == 0 && strcmp(base,"BTC") != 0 && (base= NXT_assetnamefind(base)) == 0 ) + { + //printf("reject %s %s/%s\n",exchange,base,rel); + return; + } + else if ( strcmp(base,"NXT") == 0 && strcmp(rel,"BTC") != 0 && (rel= NXT_assetnamefind(rel)) == 0 ) + { + //printf("reject %s %s/%s\n",exchange,base,rel); + return; + } + printf("%s %s/%s bids.%d asks.%d\n",exchange->name,base,rel,numbids,numasks); + if ( numbids > 0 && (volume= bidasks[0].volume) > 0. && (profitmargin= + tradebot_liquidity_active(myinfo,&price,exchange->name,base,rel,volume)) > 0. ) + { + if ( price == 0. ) + price = bidasks[0].price; + tradebot_arbcandidate(myinfo,exchange->name,1,base,rel,price,volume,(uint32_t)time(NULL),profitmargin); + } + if ( numasks > 0 && (volume= bidasks[1].volume) > 0. && (profitmargin= + tradebot_liquidity_active(myinfo,&price,exchange->name,rel,base,volume)) > 0. ) + { + if ( price == 0. ) + price = bidasks[1].price; + tradebot_arbcandidate(myinfo,exchange->name,-1,base,rel,price,volume,(uint32_t)time(NULL),profitmargin); + } + if ( (pair= tradebots_arbpair_find(base,rel)) == 0 ) + pair = tradebots_arbpair_create(base,rel); + if ( pair != 0 ) + { + if ( strcmp(rel,"NXT") == 0 ) + { + if ( pair->btcbid != 0. && pair->btcask != 0. ) + { + tradebot_arbcandidate(myinfo,"arb",1,base,"BTC",pair->btcbid,pair->btcvol,(uint32_t)time(NULL),profitmargin); + tradebot_arbcandidate(myinfo,"arb",-1,base,"BTC",pair->btcask,pair->btcvol,(uint32_t)time(NULL),profitmargin); + } + } + if ( strcmp(rel,"USD") != 0 && pair->usdbid != 0. && pair->usdask != 0. ) + { + tradebot_arbcandidate(myinfo,"arb",1,base,"USD",pair->usdbid,pair->usdvol,(uint32_t)time(NULL),profitmargin); + tradebot_arbcandidate(myinfo,"arb",-1,base,"USD",pair->usdask,pair->usdvol,(uint32_t)time(NULL),profitmargin); + } + if ( strcmp(rel,"CNY") != 0 && pair->cnybid != 0. && pair->cnyask != 0. ) + { + tradebot_arbcandidate(myinfo,"arb",1,base,"CNY",pair->cnybid,pair->cnyvol,(uint32_t)time(NULL),profitmargin); + tradebot_arbcandidate(myinfo,"arb",-1,base,"CNY",pair->cnyask,pair->cnyvol,(uint32_t)time(NULL),profitmargin); + } + } +} diff --git a/basilisk/tradebots_marketmaker.c b/basilisk/tradebots_marketmaker.c new file mode 100755 index 000000000..575861fa6 --- /dev/null +++ b/basilisk/tradebots_marketmaker.c @@ -0,0 +1,108 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c + +// "currency":{"value":%.8f, "pending":%.8f} + +cJSON *tradebot_balancediff(cJSON *item,cJSON *anchoritem) // only item might be null +{ + double current[2],past[2]; int32_t i; cJSON *diffitem = jduplicate(anchoritem); + memset(current,0,sizeof(current)); + memset(past,0,sizeof(past)); + if ( jobj(diffitem,"value") != 0 ) + jdelete(diffitem,"value"); + if ( jobj(diffitem,"pending") != 0 ) + jdelete(diffitem,"pending"); + for (i=0; i<2; i++) + { + if ( current[i] != 0. || past[i] != 0. ) + jaddnum(diffitem,i == 0 ? "value" : "pending",current[i] - past[i]); + } + return(diffitem); +} + +cJSON *tradebot_balancesdiff(struct supernet_info *myinfo,cJSON *current,cJSON *anchor) +{ + cJSON *item,*anchoritem,*diffitem,*array; int32_t i,n; char *field; + if ( anchor == 0 ) + return(jduplicate(current)); + array = cJSON_CreateObject(); + n = cJSON_GetArraySize(current); + for (i=0; inumexchanges; i++) + { + value += 0;//InstantDEX_balance(myinfo,0,0,0,exchange,base); + } + return(value); +} + +void tradebot_pendingadd(struct supernet_info *myinfo,cJSON *tradejson,char *base,double basevolume,char *rel,double relvolume) +{ + portable_mutex_lock(&myinfo->pending_mutex); + // add to myinfo->trades + portable_mutex_unlock(&myinfo->pending_mutex); +} + +void tradebot_pendingremove(struct supernet_info *myinfo,char *base,double basevolume,char *rel,double relvolume) +{ + portable_mutex_lock(&myinfo->pending_mutex); + // remove from myinfo->trades + portable_mutex_unlock(&myinfo->pending_mutex); +} + +double tradebot_pending(struct supernet_info *myinfo,char *base) +{ + double pending = 0.; struct pending_trade *tp,*tmp; + portable_mutex_lock(&myinfo->pending_mutex); + HASH_ITER(hh,myinfo->trades,tp,tmp) + { + if ( strcmp(base,tp->base) == 0 ) + pending += tp->dir * tp->basevolume; + else if ( strcmp(base,tp->rel) == 0 ) + pending -= tp->dir * tp->relvolume; + } + portable_mutex_unlock(&myinfo->pending_mutex); + return(pending); +} + diff --git a/crypto777/OS_nonportable.c b/crypto777/OS_nonportable.c index 7d148ff76..87e167afb 100755 --- a/crypto777/OS_nonportable.c +++ b/crypto777/OS_nonportable.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,7 +13,24 @@ * * ******************************************************************************/ - + /** + * - we need to include WinSock2.h header to correctly use windows structure + * as the application is still using 32bit structure from mingw so, we need to + * add the include based on checking + * + * @author - fadedreamz@gmail.com + * @remarks - #if (defined(_M_X64) || defined(__amd64__)) && defined(WIN32) + * is equivalent to #if defined(_M_X64) as _M_X64 is defined for MSVC only + * + * @remarks - we need this because in win64 we are using windows provided pollfd structure + * not from the mingw header, so we need to include the windows header + * if we are compiling in windows 64bit + */ +//#if defined(_M_X64) +//#define WIN32_LEAN_AND_MEAN +//#include +//#endif + #include "OS_portable.h" @@ -47,6 +64,85 @@ void *OS_nonportable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,l #include #include +/*#include +static uint32_t __inline __builtin_clzll(uint64_t x) { + unsigned long r = 0; + _BitScanReverse64(&r, x); + return (63-r); +}*/ + +void usleep(int32_t micros) +{ + if ( micros < 1000 ) + Sleep(1); + else Sleep(micros / 1000); +} + +int +mkstemp (template) +char *template; +{ + static const char letters[] + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static uint64_t value; +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; +#endif + char *XXXXXX; + size_t len; + int count; + + len = strlen (template); + + if ((int) len < 6 + || strncmp (&template[len - 6], "XXXXXX", 6)) + { + return -1; + } + + XXXXXX = &template[len - 6]; + +#ifdef HAVE_GETTIMEOFDAY + /* Get some more or less random data. */ + gettimeofday (&tv, NULL); + value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); +#else + value += getpid (); +#endif + + for (count = 0; count < TMP_MAX; ++count) + { + uint64_t v = value; + int fd; + + /* Fill in the random bits. */ + XXXXXX[0] = letters[v % 62]; + v /= 62; + XXXXXX[1] = letters[v % 62]; + v /= 62; + XXXXXX[2] = letters[v % 62]; + v /= 62; + XXXXXX[3] = letters[v % 62]; + v /= 62; + XXXXXX[4] = letters[v % 62]; + v /= 62; + XXXXXX[5] = letters[v % 62]; + + fd = open (template, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600); + if (fd >= 0) + /* The file does not exist. */ + return fd; + + /* This is a random value. It is only necessary that the next + TMP_MAX values generated by adding 7777 to VALUE are different + with (module 2^32). */ + value += 7777; + } + + /* We return the null string if we can't find a unique file name. */ + template[0] = '\0'; + return -1; +} #include "../OSlibs/win/mman.h" @@ -496,10 +592,10 @@ char *OS_nonportable_path(char *str) return(str); } -void *OS_nonportable_mapfile(char *fname,uint64_t *filesizep,int32_t enablewrite) +void *OS_nonportable_mapfile(char *fname,long *filesizep,int32_t enablewrite) { int32_t fd,rwflags,flags = MAP_FILE|MAP_SHARED; - uint64_t filesize; + long filesize; void *ptr = 0; *filesizep = 0; if ( enablewrite != 0 ) @@ -511,7 +607,7 @@ void *OS_nonportable_mapfile(char *fname,uint64_t *filesizep,int32_t enablewrite return(0); } if ( *filesizep == 0 ) - filesize = (uint64_t)lseek(fd,0,SEEK_END); + filesize = (long)lseek(fd,0,SEEK_END); else filesize = *filesizep; rwflags = PROT_READ; if ( enablewrite != 0 ) @@ -528,15 +624,23 @@ void *OS_nonportable_mapfile(char *fname,uint64_t *filesizep,int32_t enablewrite return(ptr); } -int32_t OS_nonportable_renamefile(char *fname,char *newfname) +int32_t OS_nonportable_removefile(char *fname) { - char cmdstr[1024],tmp[512]; + char tmp[512]; strcpy(tmp,fname); - OS_nonportable_path(tmp); - sprintf(cmdstr,"del %s",tmp); - if ( system(cmdstr) != 0 ) - printf("error deleting file.(%s)\n",cmdstr); - else return(1); + OS_portable_path(tmp); + return((DeleteFileA(tmp) == 0) ? -1 : 0); +} + +int32_t OS_nonportable_renamefile(char *fname,char *newfname) +{ + char tmp[1024],tmp2[1024]; int32_t retval,retvaldel; + strcpy(tmp,fname), strcpy(tmp2,newfname); + OS_nonportable_path(tmp), OS_nonportable_path(tmp2); + retvaldel = OS_nonportable_removefile(tmp2); + retval = MoveFileA(tmp,tmp2); + //printf("call Movefile(%s -> %s) retval.%d retvaldel.%d %d\n",tmp,tmp2,retval,retvaldel,GetLastError()); + return((retval == 0) ? -1 : 0); } int32_t OS_nonportable_launch(char *args[]) diff --git a/crypto777/OS_portable.c b/crypto777/OS_portable.c index d59c1b1e9..422b51427 100755 --- a/crypto777/OS_portable.c +++ b/crypto777/OS_portable.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -30,7 +30,7 @@ void OS_portable_init() void OS_portable_randombytes(unsigned char *x,long xlen) { #ifdef _WIN32 - return(OS_nonportable_randombytes(x,xlen)); + OS_nonportable_randombytes(x,xlen); #else static int fd = -1; int32_t i; @@ -48,7 +48,7 @@ void OS_portable_randombytes(unsigned char *x,long xlen) sleep(1); continue; } - if ( 0 ) + if ( (0) ) { int32_t j; for (j=0; jtotalsize > origsize ) size = mem->totalsize; else size = origsize; - fprintf(stderr,"filealloc.(%s) -> ",fname); + printf("filealloc.(%s) -> ",fname); if ( OS_filealloc(&mem->M,fname,mem,size) == 0 ) { printf("couldnt map tmpfile %s\n",fname); return(0); } - fprintf(stderr,"created\n"); + printf("created\n"); } ptr = iguana_memalloc(mem,origsize,1); if ( mem->threadsafe != 0 ) diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index d1b6e579e..8c109e5d0 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -17,11 +17,21 @@ // iguana_OS has functions that invoke system calls. Whenever possible stdio and similar functions are use and most functions are fully portable and in this file. For things that require OS specific, the call is routed to iguana_OS_portable_* Usually, all but one OS can be handled with the same code, so iguana_OS_portable.c has most of this shared logic and an #ifdef iguana_OS_nonportable.c +#ifdef __APPLE__ +//#define LIQUIDITY_PROVIDER 1 +#endif + +#ifdef NATIVE_WINDOWS +//#define uint64_t unsigned __int64 +#define PACKED +#else +#define PACKED __attribute__((packed)) +#endif + #include #include #include #define HAVE_STRUCT_TIMESPEC -#include #include #include #include @@ -30,28 +40,30 @@ #include #include -#ifdef __MINGW +#ifdef _WIN32 #define sleep(x) Sleep(1000*(x)) #include "../OSlibs/win/mingw.h" #include "../OSlibs/win/mman.h" +#define PTW32_STATIC_LIB #include "../OSlibs/win/pthread.h" +#ifndef NATIVE_WINDOWS #define EADDRINUSE WSAEADDRINUSE +#endif #else -//#include +#include #include #include #include #define HAVE_STRUCT_TIMESPEC #include -//#include -//#include "in.h" #include #include -//#include +#include #define closesocket close #endif + #ifndef MIN #define MIN(x, y) ( ((x)<(y))?(x):(y) ) #endif @@ -117,10 +129,13 @@ int32_t hseek(HUFF *hp,int32_t offset,int32_t mode); #define portable_mutex_unlock pthread_mutex_unlock #define OS_thread_create pthread_create -#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0) +#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0,0) +#define issue_curlt(cmdstr,timeout) bitcoind_RPC(0,"curl",cmdstr,0,0,0,timeout) + +struct allocitem { uint32_t allocsize,type; } PACKED; +struct queueitem { struct queueitem *next,*prev; uint32_t allocsize,type; } PACKED; +struct stritem { struct queueitem DL; void **retptrp; uint32_t expiration; char str[]; }; -struct allocitem { uint32_t allocsize,type; } __attribute__((packed)); -struct queueitem { struct queueitem *next,*prev; uint32_t allocsize,type; } __attribute__((packed)); typedef struct queue { struct queueitem *list; @@ -128,6 +143,15 @@ typedef struct queue char name[64],initflag; } queue_t; +struct rpcrequest_info +{ + struct rpcrequest_info *next,*prev; + pthread_t T; + int32_t sock; + uint32_t ipbits; + uint16_t port,pad; +}; + struct OS_mappedptr { char fname[512]; @@ -183,6 +207,8 @@ int32_t OS_nonportable_init(); void OS_portable_init(); void OS_init(); +int32_t sortds(double *buf,uint32_t num,int32_t size); +int32_t revsortds(double *buf,uint32_t num,int32_t size); double OS_portable_milliseconds(); void OS_portable_randombytes(uint8_t *x,long xlen); @@ -192,8 +218,8 @@ void OS_remove_directory(char *dirname); int32_t OS_portable_renamefile(char *fname,char *newfname); int32_t OS_portable_removefile(char *fname); void *OS_portable_mapfile(char *fname,long *filesizep,int32_t enablewrite); -int32_t OS_portable_syncmap(struct OS_mappedptr *mp,long len); -void *OS_portable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,long origsize); +//int32_t OS_portable_syncmap(struct OS_mappedptr *mp,long len); +//void *OS_portable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,long origsize); int32_t is_DST(int32_t datenum); int32_t extract_datenum(int32_t *yearp,int32_t *monthp,int32_t *dayp,int32_t datenum); @@ -203,47 +229,54 @@ int32_t ecb_decrdate(int32_t *yearp,int32_t *monthp,int32_t *dayp,char *date,int int32_t conv_date(int32_t *secondsp,char *buf); uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t second); int32_t OS_conv_unixtime(struct tai *t,int32_t *secondsp,time_t timestamp); -double OS_milliseconds(); - -void OS_randombytes(uint8_t *x,long xlen); -int32_t OS_truncate(char *fname,long filesize); char *OS_compatible_path(char *str); -int32_t OS_renamefile(char *fname,char *newfname); -int32_t OS_removefile(char *fname,int32_t scrubflag); -void OS_ensure_directory(char *dirname); -int64_t OS_filesize(char *fname); +FILE *OS_appendfile(char *origfname); + int32_t OS_compare_files(char *fname,char *fname2); int64_t OS_copyfile(char *src,char *dest,int32_t cmpflag); -int32_t OS_releasemap(void *ptr,uint64_t filesize); void _OS_closemap(struct OS_mappedptr *mp); +void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep); +void *OS_filestr(long *allocsizep,char *fname); void OS_closemap(struct OS_mappedptr *mp); -long OS_ensurefilesize(char *fname,long filesize,int32_t truncateflag); int32_t OS_openmap(struct OS_mappedptr *mp); -void *OS_mappedptr(void **ptrp,struct OS_mappedptr *mp,uint64_t allocsize,int32_t rwflag,char *fname); +void *OS_mappedptr(void **ptrp,struct OS_mappedptr *mp,unsigned long allocsize,int32_t rwflag,char *fname); void *OS_filealloc(struct OS_mappedptr *M,char *fname,struct OS_memspace *mem,long size); +void *OS_nonportable_mapfile(char *fname,long *filesizep,int32_t enablewrite); +int32_t OS_nonportable_removefile(char *fname); + +unsigned long OS_filesize(char *fname); +void OS_ensure_directory(char *dirname); +long OS_ensurefilesize(char *fname,long filesize,int32_t truncateflag); +int32_t OS_truncate(char *fname,long filesize); +int32_t OS_renamefile(char *fname,char *newfname); +int32_t OS_removefile(char *fname,int32_t scrubflag); + void *OS_mapfile(char *fname,long *filesizep,int32_t enablewrite); -void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep); -void *OS_filestr(long *allocsizep,char *fname); +int32_t OS_releasemap(void *ptr,unsigned long filesize); -int32_t OS_syncmap(struct OS_mappedptr *mp,long len); -void *OS_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,long origsize); +double OS_milliseconds(); +void OS_randombytes(uint8_t *x,long xlen); + +//int32_t OS_syncmap(struct OS_mappedptr *mp,long len); +//void *OS_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,long origsize); long myallocated(uint8_t type,long change); void *mycalloc(uint8_t type,int32_t n,long itemsize); void myfree(void *_ptr,long allocsize); -void free_queueitem(void *itemdata); +//void free_queueitem(void *itemdata); void *myrealloc(uint8_t type,void *oldptr,long oldsize,long newsize); void *myaligned_alloc(uint64_t allocsize); int32_t myaligned_free(void *ptr,long size); -void *queueitem(char *str); -void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem,int32_t offsetflag); -void *queue_dequeue(queue_t *queue,int32_t offsetflag); +struct queueitem *queueitem(char *str); +void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem);//,int32_t offsetflag); +void *queue_dequeue(queue_t *queue);//,int32_t offsetflag); void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_t freeitem); void *queue_free(queue_t *queue); void *queue_clone(queue_t *clone,queue_t *queue,int32_t size); int32_t queue_size(queue_t *queue); +char *mbstr(char *str,double n); void iguana_memreset(struct OS_memspace *mem); void iguana_mempurge(struct OS_memspace *mem); @@ -293,6 +326,7 @@ int32_t btc_convaddr(char *hexaddr,char *addr58); uint64_t RS_decode(char *rs); int32_t RS_encode(char *rsaddr,uint64_t id); +char *cmc_ticker(char *base); void calc_sha1(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_md2(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); @@ -327,7 +361,7 @@ char *hmac_tiger_str(char *dest,char *key,int32_t key_size,char *message); char *hmac_whirlpool_str(char *dest,char *key,int32_t key_size,char *message); int nn_base64_encode(const uint8_t *in,size_t in_len,char *out,size_t out_len); int nn_base64_decode(const char *in,size_t in_len,uint8_t *out,size_t out_len); - +void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); void sha256_sha256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void rmd160ofsha256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_md5str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); @@ -338,6 +372,8 @@ void calc_base64_encodestr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_base64_decodestr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_hexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); void calc_unhexstr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); +int32_t safecopy(char *dest,char *src,long len); +double dxblend(double *destp,double val,double decay); uint64_t calc_ipbits(char *ip_port); void expand_ipbits(char *ipaddr,uint64_t ipbits); @@ -345,9 +381,13 @@ void escape_code(char *escaped,char *str); void SaM_PrepareIndices(); // iguana_serdes.c -#define IGUANA_LOG2PACKETSIZE 21 +#ifndef IGUANA_LOG2PACKETSIZE +#define IGUANA_LOG2PACKETSIZE 22 +#endif +#ifndef IGUANA_MAXPACKETSIZE #define IGUANA_MAXPACKETSIZE (1 << IGUANA_LOG2PACKETSIZE) -struct iguana_msghdr { uint8_t netmagic[4]; char command[12]; uint8_t serdatalen[4],hash[4]; } __attribute__((packed)); +#endif +struct iguana_msghdr { uint8_t netmagic[4]; char command[12]; uint8_t serdatalen[4],hash[4]; } PACKED; int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H); @@ -360,6 +400,7 @@ int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p); int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p); int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp); int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); +#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) bits256 bits256_ave(bits256 a,bits256 b); bits256 bits256_doublesha256(char *hashstr,uint8_t *data,int32_t datalen); @@ -380,6 +421,7 @@ int32_t revsort32(uint32_t *buf,uint32_t num,int32_t size); bits256 bits256_sha256(bits256 data); void bits256_rmd160(uint8_t rmd160[20],bits256 data); void bits256_rmd160_sha256(uint8_t rmd160[20],bits256 data); +double get_theoretical(double *avebidp,double *aveaskp,double *highbidp,double *lowaskp,double *CMC_averagep,double changes[3],char *name,char *base,char *rel,double *USD_averagep); extern char *Iguana_validcommands[]; extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY; diff --git a/crypto777/OS_time.c b/crypto777/OS_time.c index 0782c3f2a..2a1279730 100755 --- a/crypto777/OS_time.c +++ b/crypto777/OS_time.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -21,7 +21,7 @@ #define TAI_PACK 8 #define TAI_UTC_DIFF ((uint64_t)4611686018427387914ULL) -//#define UTC_ADJUST -36 +//#define UTC_ADJUST -37 #define tai_approx(t) ((double) ((t)->x)) #define tai_less(t,u) ((t)->x < (u)->x) @@ -56,7 +56,7 @@ struct tm *gmtime_r(const time_t *timep,struct tm *result) /*typedef struct timeval { long tv_sec; long tv_usec; -} timeval; +} timeval;*/ int gettimeofday(struct timeval * tp, struct timezone * tzp) { @@ -75,7 +75,7 @@ int gettimeofday(struct timeval * tp, struct timezone * tzp) tp->tv_sec = (long) ((time - EPOCH) / 10000000L); tp->tv_usec = (long) (system_time.wMilliseconds * 1000); return 0; -}*/ +} #endif double OS_portable_milliseconds() @@ -300,7 +300,7 @@ void tai_add(struct tai *t,struct tai *u,struct tai *v) { t->x = u->x + v->x; } void tai_sub(struct tai *t,struct tai *u,struct tai *v) { t->x = u->x - v->x; } // {"leapseconds":["+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30"]} -char *leapseconds[] = { "+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30" }; +char *leapseconds[] = { "+1972-06-30", "+1972-12-31", "+1973-12-31", "+1974-12-31", "+1975-12-31", "+1976-12-31", "+1977-12-31", "+1982-06-30", "+1983-06-30", "+1985-06-30", "+1987-12-31", "+1989-12-31", "+1990-12-31", "+1992-06-30", "+1993-06-30", "+1994-06-30", "+1995-12-31", "+1997-06-30", "+1998-12-31", "+2005-12-31", "+2008-12-31", "+2012-06-30", "+2015-06-30", "+2016-12-31" }; struct tai leaptais[sizeof(leapseconds)/sizeof(*leapseconds)]; char *dayname[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } ; @@ -355,9 +355,9 @@ struct tai tai_now() { First_TAI = t, First_utc = (uint32_t)now; #ifndef DISABLE_LEAPS - UTC_ADJUST = -36; + UTC_ADJUST = -37; #endif - printf("TAINOW.%llu %03.3f UTC.%u vs %u [diff %d]\n",(long long)t.x,t.millis,First_utc,tai2utc(t),UTC_ADJUST); + //printf("TAINOW.%llu %03.3f UTC.%u vs %u [diff %d]\n",(long long)t.x,t.millis,First_utc,tai2utc(t),UTC_ADJUST); } return(t); } @@ -536,7 +536,7 @@ uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t sec } return(0); } - else + /*else { #ifdef __PNACL return(0); @@ -547,12 +547,12 @@ uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t sec t.tm_hour = hour, t.tm_min = minute, t.tm_sec = second; return((uint32_t)timegm(&t)); #endif - } + }*/ } int32_t OS_conv_unixtime(struct tai *tp,int32_t *secondsp,time_t timestamp) // gmtime -> datenum + number of seconds { - struct tm tm,*ptr; int32_t datenum; uint32_t checktime; char buf[64]; struct tai t; struct taitime ct; + struct tai t; struct taitime ct; if ( 1 ) { *tp = t = utc2tai((uint32_t)timestamp); @@ -560,8 +560,9 @@ int32_t OS_conv_unixtime(struct tai *tp,int32_t *secondsp,time_t timestamp) // g *secondsp = (ct.hour*3600 + ct.minute*60 + ct.second); return(calc_datenum(ct.date.year,ct.date.month,ct.date.day)); } - else + /*else { + struct tm tm,*ptr; int32_t datenum; uint32_t checktime; char buf[64]; if ( (ptr= gmtime(×tamp)) != 0 ) tm = *ptr;; strftime(buf,sizeof(buf), "%Y-%m-%dT%H:%M:%SZ",&tm); //printf("%s\n",buf); @@ -572,13 +573,13 @@ int32_t OS_conv_unixtime(struct tai *tp,int32_t *secondsp,time_t timestamp) // g return(-1); } return(datenum); - } + }*/ } int32_t conv_date(int32_t *secondsp,char *date) { - char origdate[64],tmpdate[64]; int32_t year,month,day,hour,min,sec,len; - strcpy(origdate,date), strcpy(tmpdate,date), tmpdate[8 + 2] = 0; + char origdate[512],tmpdate[512]; int32_t year,month,day,hour,min,sec,len; + safecopy(origdate,date,sizeof(origdate)), safecopy(tmpdate,date,sizeof(tmpdate)), tmpdate[8 + 2] = 0; year = atoi(tmpdate), month = atoi(tmpdate+5), day = atoi(tmpdate+8); *secondsp = 0; if ( (len= (int32_t)strlen(date)) <= 10 ) @@ -590,8 +591,8 @@ int32_t conv_date(int32_t *secondsp,char *date) if ( hour >= 0 && hour < 24 && min >= 0 && min < 60 && sec >= 0 && sec < 60 ) *secondsp = (3600*hour + 60*min + sec); else printf("ERROR: seconds.%d %d %d %d, len.%d\n",*secondsp,hour,min,sec,len); - } - //printf("(%s) -> Y.%d M.%d D.%d %d:%d:%d\n",date,year,month,day,hour,min,sec); + //printf("(%s) -> Y.%d M.%d D.%d %d:%d:%d\n",date,year,month,day,hour,min,sec); + } //else printf("short len.(%s) from (%s)\n",date,origdate); sprintf(origdate,"%d-%02d-%02d",year,month,day); //2015-07-25T22:34:31Z if ( strcmp(tmpdate,origdate) != 0 ) { diff --git a/crypto777/SaM.c b/crypto777/SaM.c index 068862a67..e82802cea 100755 --- a/crypto777/SaM.c +++ b/crypto777/SaM.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -46,7 +46,7 @@ struct SaM_info { bits384 bits; TRIT trits[SAM_STATE_SIZE],hash[SAM_HASH_SIZE]; struct SaMhdr { bits384 sig; uint32_t timestamp,nonce; uint8_t numrounds,leverage; }; void SaM_Initialize(struct SaM_info *state); -int32_t SaM_Absorb(struct SaM_info *state,const uint8_t *input,const uint32_t inputSize,const uint8_t *input2,const uint32_t inputSize2); +int32_t SaM_Absorb(struct SaM_info *state,const uint8_t *input,uint32_t inputSize,const uint8_t *input2,uint32_t inputSize2); bits384 SaM_emit(struct SaM_info *state); bits384 SaM_encrypt(uint8_t *dest,uint8_t *src,int32_t len,bits384 password,uint32_t timestamp); uint64_t SaM_threshold(int32_t leverage); @@ -285,7 +285,7 @@ int32_t SaM_test() memset(histo,0,sizeof(histo)); for (i=0; i<5; i++) { - if ( 0 && (i % 100) == 99 ) + if ( (0) && (i % 100) == 99 ) { for (j=0; j<32; j++) seed.bytes[j] = rand() >> 8; @@ -340,6 +340,7 @@ bits384 SaM_encrypt(uint8_t *dest,uint8_t *src,int32_t len,bits384 password,uint { bits384 xorpad; int32_t i; struct SaM_info XORpad; SaM_Initialize(&XORpad), SaM_Absorb(&XORpad,password.bytes,sizeof(password),(void *)×tamp,sizeof(timestamp)); + memset(xorpad.bytes,0,sizeof(xorpad)); while ( len >= 0 ) { SaM_emit(&XORpad); diff --git a/crypto777/bitcoind_RPC.c b/crypto777/bitcoind_RPC.c index f292f68db..775ec5f66 100755 --- a/crypto777/bitcoind_RPC.c +++ b/crypto777/bitcoind_RPC.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,20 +13,28 @@ * * ******************************************************************************/ -#include "OS_portable.h" -#ifdef __APPLE__ + +#ifndef FROM_JS +#include "OS_portable.h" #define LIQUIDITY_PROVIDER 1 -#endif + +/*#define malloc(n) LP_alloc(n) +#define realloc(ptr,n) LP_realloc(ptr,n) +#define calloc(a,b) LP_alloc((uint64_t)(a) * (b)) +#define free(ptr) LP_free(ptr) +#define clonestr(str) LP_clonestr(str) + +void *LP_realloc(void *ptr,uint64_t len); +void *LP_alloc(uint64_t len); +void LP_free(void *ptr); +char *LP_clonestr(char *str);*/ + +int32_t bitcoind_RPC_inittime; #if LIQUIDITY_PROVIDER -#ifdef _WIN32 -#include -#include -#else #include #include -#endif // return data from the server #define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) @@ -38,8 +46,11 @@ struct return_string { size_t len; }; +struct MemoryStruct { char *memory; size_t size,allocsize; }; + size_t accumulate(void *ptr, size_t size, size_t nmemb, struct return_string *s); void init_string(struct return_string *s); +static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data); /************************************************************************ @@ -62,16 +73,20 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * long i,j,len; char *retstr = 0; cJSON *json,*result,*error; +#ifdef FROM_MARKETMAKER + //usleep(500); +#endif //printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); if ( command == 0 || rpcstr == 0 || rpcstr[0] == 0 ) { - printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,rpcstr); + if ( strcmp(command,"signrawtransaction") != 0 && strcmp(command,"getrawtransaction") != 0 ) + printf("<<<<<<<<<<< A bitcoind_RPC: %s post_process_bitcoind_RPC.%s.[%s]\n",debugstr,command,params); return(rpcstr); } json = cJSON_Parse(rpcstr); if ( json == 0 ) { - printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC.%s can't parse.(%s) params.(%s)\n",debugstr,command,rpcstr,params); + printf("<<<<<<<<<<< B bitcoind_RPC: %s post_process_bitcoind_RPC.%s can't parse.(%s) params.(%s)\n",debugstr,command,rpcstr,params); free(rpcstr); return(0); } @@ -81,7 +96,8 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * { if ( (error->type&0xff) == cJSON_NULL && (result->type&0xff) != cJSON_NULL ) { - retstr = cJSON_Print(result); + retstr = jprint(result,0); + //printf("%s %s rpc retstr.%p\n",command,params,retstr); len = strlen(retstr); if ( retstr[0] == '"' && retstr[len-1] == '"' ) { @@ -91,8 +107,17 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * } } else if ( (error->type&0xff) != cJSON_NULL || (result->type&0xff) != cJSON_NULL ) - printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC (%s) error.%s\n",debugstr,command,rpcstr); - free(rpcstr); + { + if ( strcmp(command,"getrawtransaction") != 0 && strcmp(command,"signrawtransaction") != 0 && strcmp(command,"sendrawtransaction") != 0 ) + printf("<<<<<<<<<<< bitcoind_RPC: %s post_process_bitcoind_RPC (%s) error.%s\n",debugstr,command,rpcstr); + retstr = rpcstr; + rpcstr = 0; + } + if ( rpcstr != 0 ) + { + //printf("free rpcstr.%p\n",rpcstr); + free(rpcstr); + } } else retstr = rpcstr; free_json(json); //fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: postprocess returns.(%s)\n",retstr); @@ -106,6 +131,8 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char * * ************************************************************************/ +static int32_t USE_JAY; + char *Jay_NXTrequest(char *command,char *params) { char *retstr = 0; @@ -114,17 +141,18 @@ char *Jay_NXTrequest(char *command,char *params) return(retstr); } -char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params) +char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout) { static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY; + struct MemoryStruct chunk; struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle; - char *bracket0,*bracket1,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; + char *bracket0,*bracket1,*retstr,*databuf = 0; long len; int32_t specialcase,numretries; double starttime; if ( didinit == 0 ) { didinit = 1; curl_global_init(CURL_GLOBAL_ALL); //init the curl session } - if ( USE_JAY != 0 && (strncmp(url,"http://127.0.0.1:7876/nxt",strlen("http://127.0.0.1:7876/nxt")) == 0 || strncmp(url,"https://127.0.0.1:7876/nxt",strlen("https://127.0.0.1:7876/nxt")) == 0) ) + if ( (0) && (USE_JAY != 0 && (strncmp(url,"http://127.0.0.1:7876/nxt",strlen("http://127.0.0.1:7876/nxt")) == 0 || strncmp(url,"https://127.0.0.1:7876/nxt",strlen("https://127.0.0.1:7876/nxt")) == 0)) ) { if ( (databuf= Jay_NXTrequest(command,params)) != 0 ) return(databuf); @@ -134,24 +162,45 @@ char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char * specialcase = 1; else specialcase = 0; if ( url[0] == 0 ) - strcpy(url,"http://127.0.0.1:7876/nxt"); - if ( specialcase != 0 && 0 ) - printf("<<<<<<<<<<< bitcoind_RPC: debug.(%s) url.(%s) command.(%s) params.(%s)\n",debugstr,url,command,params); + strcpy(url,"http://127.0.0.1:7776"); + if ( specialcase != 0 && (0) ) + printf("<<<<<<<<<<< bitcoind_RPC: userpass.(%s) url.(%s) command.(%s) params.(%s)\n",userpass,url,command,params); try_again: if ( retstrp != 0 ) *retstrp = 0; starttime = OS_milliseconds(); curl_handle = curl_easy_init(); - init_string(&s); headers = curl_slist_append(0,"Expect:"); curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl_handle,CURLOPT_URL, url); - curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function - curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback + if ( (0) ) + { + init_string(&s); + curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION, (void *)accumulate); // send all data to this function + curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA, &s); // we pass our 's' struct to the callback + } + else + { + memset(&chunk,0,sizeof(chunk)); + curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback); + curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void *)&chunk); + + } curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback + if ( timeout > 0 ) + { + if ( bitcoind_RPC_inittime != 0 ) + { +#ifndef _WIN32 + curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,1); +#else + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, timeout*100); +#endif + } else curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,timeout); // causes problems with iguana timeouts + } if ( strncmp(url,"https",5) == 0 ) { curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0); @@ -173,9 +222,12 @@ try_again: bracket0 = (char *)"["; bracket1 = (char *)"]"; } - + char agentstr[64]; databuf = (char *)malloc(256 + strlen(command) + strlen(params)); - sprintf(databuf,"{\"id\":\"jl777\",\"method\":\"%s\",\"params\":%s%s%s}",command,bracket0,params,bracket1); + if ( debugstr[0] != 0 ) + sprintf(agentstr,"\"agent\":\"%s\",",debugstr); + else agentstr[0] = 0; + sprintf(databuf,"{\"id\":\"jl777\",%s\"method\":\"%s\",\"params\":%s%s%s}",agentstr,command,bracket0,params,bracket1); //printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf); // } //else if ( specialcase != 0 ) fprintf(stderr,"databuf.(%s)\n",params); @@ -193,23 +245,24 @@ try_again: free(databuf); databuf = 0; } + retstr = chunk.memory; // retstr = s.ptr; if ( res != CURLE_OK ) { numretries++; - if ( specialcase != 0 ) + if ( specialcase != 0 || timeout != 0 ) { - printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res); - free(s.ptr); + //printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,retstr,res); + free(retstr); return(0); } - else if ( numretries >= 5 ) + else if ( numretries >= 4 ) { - printf("Maximum number of retries exceeded!\n"); - free(s.ptr); + printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); + //printf("Maximum number of retries exceeded!\n"); + free(retstr); return(0); } - printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries); - free(s.ptr); + free(retstr); sleep((1< (%s)\n",params,s.ptr); + if ( (0) && specialcase != 0 ) + fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: BTCD.(%s) -> (%s)\n",params,retstr); count2++; elapsedsum2 += (OS_milliseconds() - starttime); if ( (count2 % 10000) == 0) printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command); - return(s.ptr); + return(retstr); } } - printf("bitcoind_RPC: impossible case\n"); - free(s.ptr); - return(0); } /************************************************************************ @@ -284,13 +335,24 @@ size_t accumulate(void *ptr,size_t size,size_t nmemb,struct return_string *s) return(size * nmemb); } -struct MemoryStruct { char *memory; size_t size; }; - static size_t WriteMemoryCallback(void *ptr,size_t size,size_t nmemb,void *data) { - size_t realsize = (size * nmemb); + size_t needed,realsize = (size * nmemb); struct MemoryStruct *mem = (struct MemoryStruct *)data; - mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1); + needed = mem->size + realsize + 1; + if ( ptr == 0 && needed < 256 ) + { + mem->allocsize = 256; + mem->memory = malloc(mem->allocsize); + } + if ( mem->allocsize < needed ) + { + //printf("curl needs %d more\n",(int32_t)realsize); + mem->memory = (ptr != 0) ? realloc(mem->memory,needed) : malloc(needed); + //printf("mem->memory.%p len.%d\n",mem->memory,(int32_t)needed); + mem->allocsize = needed; + } + //mem->memory = (ptr != 0) ? realloc(mem->memory,mem->size + realsize + 1) : malloc(mem->size + realsize + 1); if ( mem->memory != 0 ) { if ( ptr != 0 ) @@ -365,3 +427,4 @@ void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char * return(clonestr("{\"error\":\"curl is disabled\"}")); } #endif +#endif diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index 5035f9a9b..54df964f5 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -54,8 +54,43 @@ static int32_t cJSON_strcasecmp(const char *s1,const char *s2) return tolower((int32_t)(*(const unsigned char *)s1)) - tolower((int32_t)(*(const unsigned char *)s2)); } -static void *(*cJSON_malloc)(size_t sz) = malloc; -static void (*cJSON_free)(void *ptr) = free; +void *LP_alloc(uint64_t len); +void LP_free(void *ptr); +static void *(*cJSON_malloc)(size_t sz) = (void *)malloc;//LP_alloc; +static void (*cJSON_free)(void *ptr) = free;//LP_free; + +static void *cJSON_mallocstr(int32_t len) +{ + return(cJSON_malloc(len)); +} + +static char **cJSON_mallocptrs(int32_t num,char **space,int32_t max) +{ + if ( num < max ) + return(space); + else return(cJSON_malloc(num * sizeof(char *))); +} + +static void *cJSON_mallocnode() +{ + return(cJSON_malloc(sizeof(cJSON))); +} + +static void cJSON_freeptrs(char **ptrs,int32_t num,char **space) +{ + if ( ptrs != space ) + cJSON_free(ptrs); +} + +static void cJSON_freestr(char *str) +{ + cJSON_free(str); +} + +static void cJSON_freenode(cJSON *item) +{ + cJSON_free(item); +} static char* cJSON_strdup(const char* str) { @@ -63,7 +98,7 @@ static char* cJSON_strdup(const char* str) char* copy; len = strlen(str) + 1; - if (!(copy = (char*)cJSON_malloc(len+1))) return 0; + if (!(copy = (char*)cJSON_mallocstr((int32_t)len+1))) return 0; memcpy(copy,str,len); return copy; } @@ -76,14 +111,14 @@ void cJSON_InitHooks(cJSON_Hooks* hooks) return; } - cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; - cJSON_free = (hooks->free_fn)?hooks->free_fn:free; + cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; + cJSON_free = (hooks->free_fn)?hooks->free_fn:free; } /* Internal constructor. */ static cJSON *cJSON_New_Item(void) { - cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); + cJSON* node = (cJSON*)cJSON_mallocnode(); if (node) memset(node,0,sizeof(cJSON)); return node; } @@ -96,9 +131,9 @@ void cJSON_Delete(cJSON *c) { next=c->next; if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); - if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); - if (c->string) cJSON_free(c->string); - cJSON_free(c); + if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_freestr(c->valuestring); + if (c->string) cJSON_freestr(c->string); + cJSON_freenode(c); c=next; } } @@ -132,13 +167,13 @@ static char *print_number(cJSON *item) double d = item->valuedouble; if ( fabs(((double)item->valueint) - d) <= DBL_EPSILON && d >= (1. - DBL_EPSILON) && d < (1LL << 62) )//d <= INT_MAX && d >= INT_MIN ) { - str = (char *)cJSON_malloc(24); /* 2^64+1 can be represented in 21 chars + sign. */ + str = (char *)cJSON_mallocstr(24); /* 2^64+1 can be represented in 21 chars + sign. */ if ( str != 0 ) sprintf(str,"%lld",(long long)item->valueint); } else { - str = (char *)cJSON_malloc(66); /* This is a nice tradeoff. */ + str = (char *)cJSON_mallocstr(66); /* This is a nice tradeoff. */ if ( str != 0 ) { if ( fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60 ) @@ -173,7 +208,7 @@ static const char *parse_string(cJSON *item,const char *str) while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; // Skip escaped quotes - out=(char*)cJSON_malloc(len+2); /* This is how long we need for the string, roughly. */ + out=(char*)cJSON_mallocstr(len+2); /* This is how long we need for the string, roughly. */ if (!out) return 0; ptr=str+1;ptr2=out; @@ -238,7 +273,7 @@ static char *print_string_ptr(const char *str) if (!str) return cJSON_strdup(""); ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} - out=(char*)cJSON_malloc(len+3+1); + out=(char*)cJSON_mallocstr(len+3+1); if (!out) return 0; ptr2=out;ptr=str; @@ -372,7 +407,7 @@ static const char *parse_array(cJSON *item,const char *value) /* Render an array to text */ static char *print_array(cJSON *item,int32_t depth,int32_t fmt) { - char **entries; + char **entries,*space_entries[512]; char *out=0,*ptr,*ret;int32_t len=5; cJSON *child=item->child; int32_t numentries=0,i=0,fail=0; @@ -382,12 +417,12 @@ static char *print_array(cJSON *item,int32_t depth,int32_t fmt) /* Explicitly handle numentries==0 */ if (!numentries) { - out=(char*)cJSON_malloc(3+1); + out=(char*)cJSON_mallocstr(3+1); if (out) strcpy(out,"[]"); return out; } /* Allocate an array to hold the values for each */ - entries=(char**)cJSON_malloc((1+numentries)*sizeof(char*)); + entries=cJSON_mallocptrs(1+numentries,space_entries,sizeof(space_entries)/sizeof(*space_entries)); if (!entries) return 0; memset(entries,0,numentries*sizeof(char*)); /* Retrieve all the results: */ @@ -401,15 +436,15 @@ static char *print_array(cJSON *item,int32_t depth,int32_t fmt) } /* If we didn't fail, try to malloc the output string */ - if (!fail) out=(char*)cJSON_malloc(len+1); + if (!fail) out=(char*)cJSON_mallocstr(len+1); /* If that fails, we fail. */ if (!out) fail=1; /* Handle failure. */ if (fail) { - for (i=0;ichild,*firstchild; int32_t numentries=0,fail=0; @@ -485,7 +520,7 @@ static char *print_object(cJSON *item,int32_t depth,int32_t fmt) /* Explicitly handle empty object case */ if (!numentries) { - out=(char*)cJSON_malloc(fmt?depth+4+1:3+1); + out=(char*)cJSON_mallocstr(fmt?depth+4+1:3+1); if (!out) return 0; ptr=out;*ptr++='{'; if (fmt) {*ptr++='\n';for (i=0;ichild;int32_t i=0;while(c)i++,c=c->next;return i;} cJSON *cJSON_GetArrayItem(cJSON *array,int32_t item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} -cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} +cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) { if ( object == 0 ) return(0); cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} /* Utility for array list handling. */ static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} @@ -578,8 +615,6 @@ cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->t cJSON *cJSON_CreateBool(int32_t b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int64_t)num;}return item;} cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} -cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} -cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} /* Create Arrays: */ cJSON *cJSON_CreateIntArray(int64_t *numbers,int32_t count) {int32_t i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} @@ -634,7 +669,7 @@ void cJSON_Minify(char *json) // the following written by jl777 /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -837,7 +872,7 @@ char *jprint(cJSON *json,int32_t freeflag) initflag = 1; }*/ if ( json == 0 ) - return(clonestr("{}")); + return(clonestr((char *)"{}")); //portable_mutex_lock(&mutex); //usleep(5000); str = cJSON_Print(json), _stripwhite(str,' '); @@ -858,7 +893,7 @@ bits256 get_API_bits256(cJSON *obj) } return(hash); } -bits256 jbits256(cJSON *json,char *field) { if ( field == 0 ) return(get_API_bits256(json)); return(get_API_bits256(cJSON_GetObjectItem(json,field))); } +bits256 jbits256(cJSON *json,char *field) { if ( field == 0 ) return(get_API_bits256(json)); return(get_API_bits256(json != 0 ? cJSON_GetObjectItem(json,field) : 0)); } bits256 jbits256i(cJSON *json,int32_t i) { return(get_API_bits256(cJSON_GetArrayItem(json,i))); } void jaddbits256(cJSON *json,char *field,bits256 hash) { char str[65]; bits256_str(str,hash), jaddstr(json,field,str); } void jaddibits256(cJSON *json,bits256 hash) { char str[65]; bits256_str(str,hash), jaddistr(json,str); } @@ -896,10 +931,14 @@ int32_t jnum(cJSON *obj,char *field) void ensure_jsonitem(cJSON *json,char *field,char *value) { - cJSON *obj = cJSON_GetObjectItem(json,field); - if ( obj == 0 ) - cJSON_AddItemToObject(json,field,cJSON_CreateString(value)); - else cJSON_ReplaceItemInObject(json,field,cJSON_CreateString(value)); + cJSON *obj; + if ( json != 0 ) + { + obj = cJSON_GetObjectItem(json,field); + if ( obj == 0 ) + cJSON_AddItemToObject(json,field,cJSON_CreateString(value)); + else cJSON_ReplaceItemInObject(json,field,cJSON_CreateString(value)); + } } int32_t in_jsonarray(cJSON *array,char *value) @@ -1092,12 +1131,12 @@ uint64_t calc_nxt64bits(const char *NXTaddr) c = NXTaddr[i]; if ( c < '0' || c > '9' ) { - printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i); + //printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i); #ifdef __APPLE__ //while ( 1 ) { //sleep(60); - printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i); + //printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i); } #endif return(0); @@ -1125,4 +1164,33 @@ cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num) return(array); } -void free_json(cJSON *json) { if ( json != 0 ) cJSON_Delete(json); } +cJSON *cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(); + if ( item ) + item->type = cJSON_Array; +//#ifdef CJSON_GARBAGECOLLECTION +// cJSON_register(item); +//#endif + return(item); +} + +cJSON *cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(); + if ( item ) + item->type = cJSON_Object; +//#ifdef CJSON_GARBAGECOLLECTION +// cJSON_register(item); +//#endif + return item; +} + +void free_json(cJSON *item) +{ +//#ifdef CJSON_GARBAGECOLLECTION +// cJSON_unregister(item); +//#endif + if ( item != 0 ) + cJSON_Delete(item); +} diff --git a/crypto777/crypto777.sources b/crypto777/crypto777.sources index da4353e99..3d5142a01 100755 --- a/crypto777/crypto777.sources +++ b/crypto777/crypto777.sources @@ -36,11 +36,11 @@ TRANSPORTS_TCPMUX = $(NANOSRC)/transports/tcpmux/atcpmux.c $(NANOSRC)/transports NANOMSG_PROTOCOLS = $(PROTOCOLS_UTILS) $(PROTOCOLS_PUBSUB) $(PROTOCOLS_PAIR) $(PROTOCOLS_REQREP) $(PROTOCOLS_BUS) $(PROTOCOLS_PIPELINE) $(PROTOCOLS_SURVEY) -NANOMSG_TRANSPORTS = $(TRANSPORTS_UTILS) $(TRANSPORTS_TCP) $(TRANSPORTS_IPC) $(TRANSPORTS_INPROC) +NANOMSG_TRANSPORTS = $(TRANSPORTS_UTILS) $(TRANSPORTS_TCP) $(TRANSPORTS_IPC) $(TRANSPORTS_INPROC) $(TRANSPORTS_WS) NANOMSG = $(NANOMSG_CORE) $(NANOMSG_AIO) $(NANOMSG_UTILS) $(NANOMSG_DEVICES) $(NANOMSG_TRANSPORTS) $(NANOMSG_PROTOCOLS) -JPEG_SRCS := ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c ../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c ../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c ../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c ../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c ../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c ../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c ../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/misc/jmemnobs.c ../crypto777/jpeg/jmemmgr.c +JPEG_SRCS = ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c ../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c ../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c ../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c ../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c ../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c ../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c ../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/misc/jmemnobs.c ../crypto777/jpeg/jmemmgr.c -CRYPTO777_SRCS := ../crypto777/tweetnacl.c ../crypto777/scrypt.c ../crypto777/bitcoind_RPC.c ../crypto777/cJSON.c ../crypto777/iguana_utils.c ../crypto777/OS_nonportable.c ../crypto777/curve25519-donna.c ../crypto777/inet.c ../crypto777/OS_portable.c ../crypto777/curve25519.c ../crypto777/OS_time.c ../crypto777/hmac_sha512.c ../crypto777/ramcoder.c ../crypto777/SaM.c ../crypto777/iguana_OS.c ../crypto777/iguana_serdes.c $(JPEG_SRCS) # $(NANOMSG) +CRYPTO777_SRCS = ../crypto777/tweetnacl.c ../crypto777/scrypt.c ../crypto777/bitcoind_RPC.c ../crypto777/cJSON.c ../crypto777/iguana_utils.c ../crypto777/OS_nonportable.c ../crypto777/curve25519-donna.c ../crypto777/inet.c ../crypto777/OS_portable.c ../crypto777/curve25519.c ../crypto777/OS_time.c ../crypto777/hmac_sha512.c ../crypto777/ramcoder.c ../crypto777/SaM.c ../crypto777/iguana_OS.c ../crypto777/iguana_serdes.c $(JPEG_SRCS) $(NANOMSG) diff --git a/crypto777/curve25519.c b/crypto777/curve25519.c index ec23175f8..264d59952 100755 --- a/crypto777/curve25519.c +++ b/crypto777/curve25519.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,11 +16,11 @@ #include "../includes/curve25519.h" -#undef force_inline -#define force_inline __attribute__((always_inline)) +//#undef force_inline +//#define force_inline __attribute__((always_inline)) // Sum two numbers: output += in -static inline bits320 force_inline fsum(bits320 output,bits320 in) +static inline bits320 fsum(bits320 output,bits320 in) { int32_t i; for (i=0; i<5; i++) @@ -28,7 +28,7 @@ static inline bits320 force_inline fsum(bits320 output,bits320 in) return(output); } -static inline void force_inline fdifference_backwards(uint64_t *out,const uint64_t *in) +static inline void fdifference_backwards(uint64_t *out,const uint64_t *in) { static const uint64_t two54m152 = (((uint64_t)1) << 54) - 152; // 152 is 19 << 3 static const uint64_t two54m8 = (((uint64_t)1) << 54) - 8; @@ -38,14 +38,14 @@ static inline void force_inline fdifference_backwards(uint64_t *out,const uint64 out[i] = in[i] + two54m8 - out[i]; } -inline void force_inline store_limb(uint8_t *out,uint64_t in) +void store_limb(uint8_t *out,uint64_t in) { int32_t i; for (i=0; i<8; i++,in>>=8) out[i] = (in & 0xff); } -static inline uint64_t force_inline load_limb(uint8_t *in) +static inline uint64_t load_limb(uint8_t *in) { return ((uint64_t)in[0]) | @@ -75,7 +75,7 @@ bits320 fexpand(bits256 basepoint) typedef unsigned uint128_t __attribute__((mode(TI))); // Multiply a number by a scalar: output = in * scalar -static inline bits320 force_inline fscalar_product(const bits320 in,const uint64_t scalar) +static inline bits320 fscalar_product(const bits320 in,const uint64_t scalar) { int32_t i; uint128_t a = 0; bits320 output; a = ((uint128_t)in.ulongs[0]) * scalar; @@ -119,7 +119,7 @@ bits320 fmul(const bits320 in2,const bits320 in) return(out); } -inline bits320 force_inline fsquare_times(const bits320 in,uint64_t count) +bits320 fsquare_times(const bits320 in,uint64_t count) { uint128_t t[5]; uint64_t r0,r1,r2,r3,r4,c,d0,d1,d2,d4,d419; bits320 out; r0 = in.ulongs[0], r1 = in.ulongs[1], r2 = in.ulongs[2], r3 = in.ulongs[3], r4 = in.ulongs[4]; @@ -149,7 +149,7 @@ inline bits320 force_inline fsquare_times(const bits320 in,uint64_t count) return(out); } -static inline void force_inline fcontract_iter(uint128_t t[5],int32_t flag) +static inline void fcontract_iter(uint128_t t[5],int32_t flag) { int32_t i; uint64_t mask = 0x7ffffffffffffLL; for (i=0; i<4; i++) @@ -711,7 +711,7 @@ bits320 bits320_limbs(limb limbs[10]) return(output); } -static inline bits320 force_inline fscalar_product(const bits320 in,const uint64_t scalar) +static inline bits320 fscalar_product(const bits320 in,const uint64_t scalar) { limb output[10],input[10]; int32_t i; for (i=0; i<10; i++) @@ -720,7 +720,7 @@ static inline bits320 force_inline fscalar_product(const bits320 in,const uint64 return(bits320_limbs(output)); } -static inline bits320 force_inline fsquare_times(const bits320 in,uint64_t count) +static inline bits320 fsquare_times(const bits320 in,uint64_t count) { limb output[10],input[10]; int32_t i; for (i=0; i<10; i++) @@ -776,7 +776,7 @@ bits256 curve25519(bits256 mysecret,bits256 theirpublic) // x2 z2: long form && x3 z3: long form // x z: short form, destroyed && xprime zprime: short form, destroyed // qmqp: short form, preserved -static inline void force_inline +static inline void fmonty(bits320 *x2, bits320 *z2, // output 2Q bits320 *x3, bits320 *z3, // output Q + Q' bits320 *x, bits320 *z, // input Q @@ -804,7 +804,7 @@ fmonty(bits320 *x2, bits320 *z2, // output 2Q // long. Perform the swap iff @swap is non-zero. // This function performs the swap without leaking any side-channel information. // ----------------------------------------------------------------------------- -static inline void force_inline swap_conditional(bits320 *a,bits320 *b,uint64_t iswap) +static inline void swap_conditional(bits320 *a,bits320 *b,uint64_t iswap) { int32_t i; const uint64_t swap = -iswap; for (i=0; i<5; ++i) @@ -846,7 +846,7 @@ void cmult(bits320 *resultx,bits320 *resultz,bits256 secret,const bits320 q) } // Shamelessly copied from donna's code that copied djb's code, changed a little -inline bits320 force_inline crecip(const bits320 z) +inline bits320 crecip(const bits320 z) { bits320 a,t0,b,c; /* 2 */ a = fsquare_times(z, 1); // a = 2 @@ -1792,7 +1792,7 @@ void acct777_rwsig(int32_t rwflag,uint8_t *serialized,struct acct777_sig *sig) int32_t acct777_sigcheck(struct acct777_sig *sig) { #define IGUANA_GENESIS 1453075200 -#define IGUANA_MAXPACKETSIZE (1024 * 1024 * 2) +#define IGUANA_MAXPACKETSIZE (1024 * 1024 * 4) #define TEN_YEARS (10 * 365 * 24 * 3600) if ( sig->allocsize < sizeof(*sig) || sig->allocsize > IGUANA_MAXPACKETSIZE ) { @@ -1839,7 +1839,11 @@ uint64_t acct777_validate(struct acct777_sig *sig,bits256 privkey,bits256 pubkey struct acct777_sig checksig; uint64_t signerbits; int32_t datalen; uint8_t *serialized; datalen = (int32_t)(sig->allocsize - sizeof(*sig)); checksig = *sig; +#if defined(_M_X64) + serialized = (uint8_t *)((unsigned char *)sig + sizeof(*sig)); +#else serialized = (uint8_t *)((long)sig + sizeof(*sig)); +#endif //{ int32_t i; for (i=0; itimestamp,serialized,datalen); if ( memcmp(checksig.sigbits.bytes,sig->sigbits.bytes,sizeof(checksig.sigbits)) != 0 ) @@ -1888,4 +1892,4 @@ uint8_t *_SuperNET_decipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher return(0); } -#undef force_inline +//#undef force_inline diff --git a/crypto777/hmac/sha224.c b/crypto777/hmac/sha224.c index 78a0bfb84..683440d70 100755 --- a/crypto777/hmac/sha224.c +++ b/crypto777/hmac/sha224.c @@ -26,7 +26,7 @@ const struct ltc_hash_descriptor sha224_desc = 9, &sha224_init, - &sha256_process, + &sha256i_process, &sha224_done, &sha224_test, NULL @@ -69,7 +69,7 @@ int sha224_done(hash_state * md, unsigned char *out) LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); - err = sha256_done(md, buf); + err = sha256i_done(md, buf); XMEMCPY(out, buf, 28); #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); diff --git a/crypto777/hmac/sha256.c b/crypto777/hmac/sha256.c index 29dceaa2e..e3b6a27b9 100755 --- a/crypto777/hmac/sha256.c +++ b/crypto777/hmac/sha256.c @@ -17,24 +17,6 @@ //#ifdef LTC_SHA256 -const struct ltc_hash_descriptor sha256_desc = -{ - "sha256", - 0, - 32, - 64, - - /* OID */ - { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, - 9, - - &sha256_init, - &sha256_process, - &sha256_done, - &sha256_test, - NULL -}; - #ifdef LTC_SMALL_CODE /* the K array */ static const ulong32 K[64] = { @@ -203,7 +185,7 @@ static int sha256_compress(hash_state * md, unsigned char *buf) @param md The hash state you wish to initialize @return CRYPT_OK if successful */ -int sha256_init(hash_state * md) +int sha256i_init(hash_state * md) { LTC_ARGCHK(md != NULL); @@ -227,7 +209,7 @@ int sha256_init(hash_state * md) @param inlen The length of the data (octets) @return CRYPT_OK if successful */ -HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) +HASH_PROCESS(sha256i_process, sha256_compress, sha256, 64) /** Terminate the hash to get the digest @@ -235,7 +217,7 @@ HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) @param out [out] The destination of the hash (32 bytes) @return CRYPT_OK if successful */ -int sha256_done(hash_state * md, unsigned char *out) +int sha256i_done(hash_state * md, unsigned char *out) { int i; @@ -287,9 +269,9 @@ int sha256_done(hash_state * md, unsigned char *out) void calc_sha256(char hashstr[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len) { hash_state md; - sha256_init(&md); - sha256_process(&md,src,len); - sha256_done(&md,hash); + sha256i_init(&md); + sha256i_process(&md,src,len); + sha256i_done(&md,hash); if ( hashstr != 0 ) { int32_t init_hexbytes_noT(char *hexbytes,uint8_t *message,long len); @@ -300,11 +282,11 @@ void calc_sha256(char hashstr[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t void calc_sha256cat(uint8_t hash[256 >> 3],uint8_t *src,int32_t len,uint8_t *src2,int32_t len2) { hash_state md; - sha256_init(&md); - sha256_process(&md,src,len); + sha256i_init(&md); + sha256i_process(&md,src,len); if ( src2 != 0 ) - sha256_process(&md,src2,len2); - sha256_done(&md,hash); + sha256i_process(&md,src2,len2); + sha256i_done(&md,hash); } void update_sha256(uint8_t hash[256 >> 3],struct sha256_state *state,uint8_t *src,int32_t len) @@ -312,14 +294,14 @@ void update_sha256(uint8_t hash[256 >> 3],struct sha256_state *state,uint8_t *sr hash_state md; memset(&md,0,sizeof(md)); if ( src == 0 ) - sha256_init(&md); + sha256i_init(&md); else { md.sha256 = *state; - sha256_process(&md,src,len); + sha256i_process(&md,src,len); } *state = md.sha256; - sha256_done(&md,hash); + sha256i_done(&md,hash); } /*void calc_OP_HASH160(char hexstr[41],uint8_t hash160[20],char *pubkey) @@ -334,9 +316,9 @@ void update_sha256(uint8_t hash[256 >> 3],struct sha256_state *state,uint8_t *sr return; } decode_hex(buf,len,pubkey); - sha256_init(&md); - sha256_process(&md,buf,len); - sha256_done(&md,sha256); + sha256i_init(&md); + sha256i_process(&md,buf,len); + sha256i_done(&md,sha256); rmd160_init(&md); rmd160_process(&md,sha256,256 >> 3); @@ -389,9 +371,9 @@ int sha256_test(void) char *str; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { - sha256_init(&md); - sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); - sha256_done(&md, tmp); + sha256i_init(&md); + sha256i_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha256i_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 32) != 0) { for (j=0; j<32; j++) printf("%02x",tmp[j]); @@ -400,16 +382,16 @@ int sha256_test(void) strcpy(str,(char*)tests[i].msg); reverse_hexstr(str); printf("reversed.(%s)\n",str); - sha256_init(&md); - sha256_process(&md, (unsigned char*)str, (unsigned long)strlen(str)); - sha256_done(&md, tmp); + sha256i_init(&md); + sha256i_process(&md, (unsigned char*)str, (unsigned long)strlen(str)); + sha256i_done(&md, tmp); for (j=0; j<32; j++) printf("%02x",tmp[j]); printf(" <- sha256(%s)\n",str); decode_hex(buf,(int)strlen(tests[i].msg),tests[i].msg); - sha256_init(&md); - sha256_process(&md, (unsigned char*)buf, (unsigned long)strlen(tests[i].msg)/2); - sha256_done(&md, tmp); + sha256i_init(&md); + sha256i_process(&md, (unsigned char*)buf, (unsigned long)strlen(tests[i].msg)/2); + sha256i_done(&md, tmp); for (j=0; j<32; j++) printf("%02x",tmp[j]); printf(" <- sha256(binary %s)\n",tests[i].msg); @@ -436,6 +418,24 @@ int sha256_test(void) #undef Maj +const struct ltc_hash_descriptor sha256_desc = +{ + "sha256", + 0, + 32, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, + 9, + + &sha256i_init, + &sha256i_process, + &sha256i_done, + &sha256_test, + NULL +}; + /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha256.c,v $ */ /* $Revision: 1.11 $ */ diff --git a/crypto777/hmac/tomcrypt_hash.h b/crypto777/hmac/tomcrypt_hash.h index b596c6a37..de5977437 100755 --- a/crypto777/hmac/tomcrypt_hash.h +++ b/crypto777/hmac/tomcrypt_hash.h @@ -228,9 +228,9 @@ extern const struct ltc_hash_descriptor sha384_desc; #endif #ifdef LTC_SHA256 -int sha256_init(hash_state * md); -int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); -int sha256_done(hash_state * md, unsigned char *hash); +int sha256i_init(hash_state * md); +int sha256i_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha256i_done(hash_state * md, unsigned char *hash); int sha256_test(void); extern const struct ltc_hash_descriptor sha256_desc; @@ -239,7 +239,7 @@ extern const struct ltc_hash_descriptor sha256_desc; #error LTC_SHA256 is required for LTC_SHA224 #endif int sha224_init(hash_state * md); -#define sha224_process sha256_process +#define sha224_process sha256i_process int sha224_done(hash_state * md, unsigned char *hash); int sha224_test(void); extern const struct ltc_hash_descriptor sha224_desc; diff --git a/crypto777/hmac_sha512.c b/crypto777/hmac_sha512.c index 68c428189..7df6d978f 100755 --- a/crypto777/hmac_sha512.c +++ b/crypto777/hmac_sha512.c @@ -506,7 +506,7 @@ char *hmac_sha512_str(char *dest,char *key,int32_t key_size,char *message) hmac_memory(&sha512_desc,(void *)key,key_size,(void *)message,strlen(message),checkbuf,&size); init_hexbytes_noT(dest,mac,SHA512_DIGEST_SIZE); init_hexbytes_noT(dest2,checkbuf,SHA512_DIGEST_SIZE); - //if ( memcmp(checkbuf,mac,SHA512_DIGEST_SIZE) != 0 ) + if ( memcmp(checkbuf,mac,SHA512_DIGEST_SIZE) != 0 ) printf("hmac_512 : %s vs %s\n",dest,dest2); return(dest); } @@ -621,4 +621,28 @@ char *hmac_whirlpool_str(char *dest,char *key,int32_t key_size,char *message) return(dest); } +void calc_md2str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) +{ + bits128 x; + calc_md2(hexstr,buf,msg,len); + decode_hex(buf,sizeof(x),hexstr); + //memcpy(buf,x.bytes,sizeof(x)); +} + +void calc_md4str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) +{ + bits128 x; + calc_md4(hexstr,buf,msg,len); + decode_hex(buf,sizeof(x),hexstr); + //memcpy(buf,x.bytes,sizeof(x)); +} + +void calc_md5str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) +{ + bits128 x; + calc_md5(hexstr,msg,len); + decode_hex(buf,sizeof(x),hexstr); + //memcpy(buf,x.bytes,sizeof(x)); +} + diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index 342402e53..d08756752 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -30,7 +30,7 @@ char *OS_mvstr() { -#ifdef __WIN32 +#ifdef _WIN32 return("rename"); #else return("mv"); @@ -41,7 +41,7 @@ void OS_randombytes(unsigned char *x,long xlen) { OS_portable_randombytes(x,xlen); } - + static double _kb(double n) { return(n / 1024.); } static double _mb(double n) { return(n / (1024.*1024.)); } static double _gb(double n) { return(n / (1024.*1024.*1024.)); } @@ -94,6 +94,7 @@ long myallocated(uint8_t type,long change) void *mycalloc(uint8_t type,int32_t n,long itemsize) { +#ifdef USE_MYCALLOC //static portable_mutex_t MEMmutex; struct allocitem *item; int64_t allocsize = ((uint64_t)n * itemsize); if ( type == 0 && n == 0 && itemsize == 0 ) @@ -107,38 +108,47 @@ void *mycalloc(uint8_t type,int32_t n,long itemsize) while ( (item= calloc(1,sizeof(struct allocitem) + allocsize + 16)) == 0 ) { char str[65]; - printf("mycalloc: need to wait for memory.(%d,%ld) %s to be available\n",n,itemsize,mbstr(str,allocsize)); + printf("mycalloc.%c: need to wait for memory.(%d,%ld) %s to be available\n",type,n,itemsize,mbstr(str,allocsize)); sleep(1); } //printf("calloc origptr.%p retptr.%p size.%ld\n",item,(void *)(long)item + sizeof(*item),allocsize); item->allocsize = (uint32_t)allocsize; item->type = type; //portable_mutex_unlock(&MEMmutex); - return((void *)(long)item + sizeof(*item)); + return((void *)((long)item + sizeof(*item))); +#else + return(calloc(n,itemsize)); +#endif } -void *queueitem(char *str) +struct queueitem *queueitem(char *str) { - struct queueitem *item; int32_t n,allocsize; char *data; uint8_t type = 'y'; - //portable_mutex_lock(&MEMmutex); - n = (uint32_t)strlen(str) + 1; - allocsize = (uint32_t)(sizeof(struct queueitem) + n); - myallocated(type,allocsize); - while ( (item= calloc(1,allocsize)) == 0 ) - { - char str[65]; - printf("queueitem: need to wait for memory.(%d,%ld) %s to be available\n",n,(long)sizeof(*item),mbstr(str,allocsize)); - sleep(1); - } - item->allocsize = (uint32_t)allocsize; - item->type = type; - data = (void *)(long)((long)item + sizeof(*item)); - memcpy(data,str,n); - //printf("(%c) queueitem.%p itemdata.%p n.%d allocsize.%d\n",type,item,data,n,allocsize); - //portable_mutex_unlock(&MEMmutex); - return(data); + /*struct queueitem *item; int32_t n,allocsize; char *data; uint8_t type = 'y'; + //portable_mutex_lock(&MEMmutex); + n = (uint32_t)strlen(str) + 1; + allocsize = (uint32_t)(sizeof(struct queueitem) + n); + myallocated(type,allocsize); + while ( (item= calloc(1,allocsize)) == 0 ) + { + char str[65]; + printf("queueitem: need to wait for memory.(%d,%ld) %s to be available\n",n,(long)sizeof(*item),mbstr(str,allocsize)); + sleep(1); + } + item->allocsize = (uint32_t)allocsize; + item->type = type; + data = (void *)(long)((long)item + sizeof(*item)); + memcpy(data,str,n); + //printf("(%c) queueitem.%p itemdata.%p n.%d allocsize.%d\n",type,item,data,n,allocsize); + //portable_mutex_unlock(&MEMmutex); + return(data);*/ + struct stritem *sitem; int32_t len; + len = (int32_t)strlen(str); + sitem = calloc(1,sizeof(*sitem) + len + 16); + memcpy(sitem->str,str,len); + return(&sitem->DL); } +#ifdef USE_MYCALLOC void _myfree(uint8_t type,int32_t origallocsize,void *origptr,int32_t allocsize) { //portable_mutex_lock(&MEMmutex); @@ -171,12 +181,12 @@ void myfree(void *_ptr,long allocsize) _myfree(item->type,item->allocsize,item,(uint32_t)allocsize); } -void free_queueitem(void *itemdata) -{ - struct queueitem *item = (void *)((long)itemdata - sizeof(struct queueitem)); - //printf("freeq item.%p itemdata.%p size.%d\n",item,itemdata,item->allocsize); - _myfree(item->type,item->allocsize,item,item->allocsize); -} +/*void free_queueitem(void *itemdata) + { + struct queueitem *item = (void *)((long)itemdata - sizeof(struct queueitem)); + //printf("freeq item.%p itemdata.%p size.%d\n",item,itemdata,item->allocsize); + _myfree(item->type,item->allocsize,item,item->allocsize); + }*/ void *myrealloc(uint8_t type,void *oldptr,long oldsize,long newsize) { @@ -190,16 +200,35 @@ void *myrealloc(uint8_t type,void *oldptr,long oldsize,long newsize) } return(newptr); } +#else +void myfree(void *_ptr,long allocsize) +{ + free(_ptr); +} + +void *myrealloc(uint8_t type,void *oldptr,long oldsize,long newsize) +{ + return(realloc(oldptr,newsize)); +} +#endif static uint64_t _align16(uint64_t ptrval) { if ( (ptrval & 15) != 0 ) ptrval += 16 - (ptrval & 15); return(ptrval); } void *myaligned_alloc(uint64_t allocsize) { void *ptr,*realptr; uint64_t tmp; +#if defined(_M_X64) + realptr = mycalloc('A', 1, (uint64_t)(allocsize + 16 + sizeof(realptr))); +#else realptr = mycalloc('A',1,(long)(allocsize + 16 + sizeof(realptr))); +#endif tmp = _align16((long)realptr + sizeof(ptr)); memcpy(&ptr,&tmp,sizeof(ptr)); +#if defined(_M_X64) + memcpy((void *)((unsigned char *)ptr - sizeof(realptr)), &realptr, sizeof(realptr)); +#else memcpy((void *)((long)ptr - sizeof(realptr)),&realptr,sizeof(realptr)); +#endif //printf("aligned_alloc(%llu) realptr.%p -> ptr.%p, diff.%ld\n",(long long)allocsize,realptr,ptr,((long)ptr - (long)realptr)); return(ptr); } @@ -235,25 +264,20 @@ void lock_queue(queue_t *queue) portable_mutex_lock(&queue->mutex); } -void queue_enqueue(char *name,queue_t *queue,struct queueitem *origitem,int32_t offsetflag) +void queue_enqueue(char *name,queue_t *queue,struct queueitem *item)//,int32_t offsetflag) { - struct queueitem *item; + //struct queueitem *item; if ( queue->name[0] == 0 && name != 0 && name[0] != 0 ) strcpy(queue->name,name);//,sizeof(queue->name)); - if ( origitem == 0 ) - { - printf("FATAL type error: queueing empty value\n");//, getchar(); - return; - } - //fprintf(stderr,"enqueue.(%s) %p offset.%d\n",queue->name,origitem,offsetflag); + //fprintf(stderr,"enqueue.(%s) %p\n",queue->name,item); lock_queue(queue); - item = (struct queueitem *)((long)origitem - offsetflag*sizeof(struct queueitem)); + //item = (struct queueitem *)((long)origitem - offsetflag*sizeof(struct queueitem)); DL_APPEND(queue->list,item); portable_mutex_unlock(&queue->mutex); //printf("queue_enqueue name.(%s) origitem.%p append.%p list.%p\n",name,origitem,item,queue->list); } -void *queue_dequeue(queue_t *queue,int32_t offsetflag) +void *queue_dequeue(queue_t *queue)//,int32_t offsetflag) { struct queueitem *item = 0; lock_queue(queue); @@ -264,19 +288,20 @@ void *queue_dequeue(queue_t *queue,int32_t offsetflag) DL_DELETE(queue->list,item); } portable_mutex_unlock(&queue->mutex); - if ( item != 0 && offsetflag != 0 ) - return((void *)((long)item + sizeof(struct queueitem))); - else return(item); + //if ( item != 0 && offsetflag != 0 ) + // return((void *)((long)item + sizeof(struct queueitem))); + //else + return(item); } void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_t freeitem) { struct allocitem *ptr; - struct queueitem *item = 0; + struct queueitem *tmp,*item = 0; lock_queue(queue); if ( queue->list != 0 ) { - DL_FOREACH(queue->list,item) + DL_FOREACH_SAFE(queue->list,item,tmp) { ptr = (void *)((long)item - sizeof(struct allocitem)); if ( item == copy || (ptr->allocsize == copysize && memcmp((void *)((long)item + sizeof(struct queueitem)),(void *)((long)item + sizeof(struct queueitem)),copysize) == 0) ) @@ -284,8 +309,8 @@ void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_ DL_DELETE(queue->list,item); portable_mutex_unlock(&queue->mutex); //printf("name.(%s) deleted item.%p list.%p\n",queue->name,item,queue->list); - if ( freeitem != 0 ) - myfree(item,copysize); + //if ( freeitem != 0 ) + // myfree(item,copysize); return(item); } } @@ -296,11 +321,11 @@ void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize,int32_ void *queue_free(queue_t *queue) { - struct queueitem *item = 0; + struct queueitem *tmp,*item = 0; lock_queue(queue); if ( queue->list != 0 ) { - DL_FOREACH(queue->list,item) + DL_FOREACH_SAFE(queue->list,item,tmp) { DL_DELETE(queue->list,item); myfree(item,sizeof(struct queueitem)); @@ -313,15 +338,15 @@ void *queue_free(queue_t *queue) void *queue_clone(queue_t *clone,queue_t *queue,int32_t size) { - struct queueitem *ptr,*item = 0; + struct queueitem *ptr,*tmp,*item = 0; lock_queue(queue); if ( queue->list != 0 ) { - DL_FOREACH(queue->list,item) + DL_FOREACH_SAFE(queue->list,item,tmp) { ptr = mycalloc('c',1,sizeof(*ptr)); memcpy(ptr,item,size); - queue_enqueue(queue->name,clone,ptr,0); + queue_enqueue(queue->name,clone,ptr); } //printf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list); } @@ -354,8 +379,11 @@ void iguana_memreset(struct OS_memspace *mem) void iguana_mempurge(struct OS_memspace *mem) { - if ( mem->allocated > 0 && mem->ptr != 0 && mem->totalsize > 0 ) + if ( mem->allocated != 0 && mem->ptr != 0 )//&& mem->totalsize > 0 ) + { + //printf("mempurge.(%s) %ld\n",mem->name,(long)mem->totalsize); myfree(mem->ptr,mem->totalsize), mem->ptr = 0; + } iguana_memreset(mem); mem->totalsize = 0; } @@ -375,7 +403,7 @@ void *iguana_meminit(struct OS_memspace *mem,char *name,void *ptr,int64_t totals { //static long alloc; //alloc += totalsize; - //char str[65]; printf("iguana_meminit alloc %s\n",mbstr(str,alloc)); + //char str[65]; printf("iguana_meminit.(%s) alloc %s\n",name,mbstr(str,totalsize)); if ( (mem->ptr= mycalloc('d',1,totalsize)) == 0 ) { printf("iguana_meminit: cant get %d bytes\n",(int32_t)totalsize); @@ -394,6 +422,7 @@ void *iguana_meminit(struct OS_memspace *mem,char *name,void *ptr,int64_t totals mem->totalsize = totalsize; } mem->threadsafe = threadsafe; + mem->alignflag = 4; iguana_memreset(mem); if ( mem->totalsize == 0 ) printf("meminit.%s ILLEGAL STATE null size\n",mem->name), getchar(); @@ -426,7 +455,16 @@ void *iguana_memalloc(struct OS_memspace *mem,long size,int32_t clearflag) #endif if ( (mem->used + size) <= mem->totalsize ) { - ptr = (void *)(long)((long)(mem->ptr + mem->used)); + /* + * solution to calculate memory address in a portable way + * in all platform sizeof(char) / sizeof(uchar) == 1 + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + ptr = (void *)((unsigned char *)mem->ptr + mem->used); +#else + ptr = (void *)(long)(((long)mem->ptr + mem->used)); +#endif mem->used += size; if ( size*clearflag != 0 ) memset(ptr,0,size); @@ -536,10 +574,12 @@ void OS_remove_directory(char *dirname) FILE *fp; char buf[1024]; sprintf(buf,"%s/.tmpmarker",dirname); if ( (fp= fopen(OS_compatible_path(buf),"rb")) != 0 ) + { OS_removefile(buf,0); - else fclose(fp); -//printf("skip rmdir.(%s)\n",dirname); -return; + fclose(fp); + } + //printf("skip rmdir.(%s)\n",dirname); + return; sprintf(buf,"rmdir %s",dirname); if ( system(buf) != 0 ) { @@ -549,16 +589,13 @@ return; { //printf("error doing (%s)\n",buf); } - //sprintf(buf,"rmdir %s",dirname); - //if ( system(buf) != 0 ) - // printf("second error doing (%s)\n",buf); } } void OS_ensure_directory(char *dirname) { FILE *fp; int32_t retval; char fname[512]; - if ( 0 && OS_removefile(dirname,0) < 0 ) + if ( (0) && OS_removefile(dirname,0) < 0 ) { sprintf(fname,"tmp/%d",rand()); OS_renamefile(dirname,fname); @@ -581,9 +618,9 @@ void OS_ensure_directory(char *dirname) } else fclose(fp);//, printf("%s exists\n",fname); } -int64_t OS_filesize(char *fname) +unsigned long OS_filesize(char *fname) { - FILE *fp; uint64_t fsize = 0; + FILE *fp; unsigned long fsize = 0; if ( (fp= fopen(fname,"rb")) != 0 ) { fseek(fp,0,SEEK_END); @@ -622,7 +659,11 @@ int64_t OS_copyfile(char *src,char *dest,int32_t cmpflag) { if ( (destfp= fopen(OS_compatible_path(dest),"wb")) != 0 ) { +#ifdef _WIN32 + allocsize = 1024 * 1024 * 8L; +#else allocsize = 1024 * 1024 * 128L; +#endif buf = mycalloc('F',1,allocsize); while ( (len= fread(buf,1,allocsize,srcfp)) > 0 ) if ( (long)fwrite(buf,1,len,destfp) != len ) @@ -638,7 +679,7 @@ int64_t OS_copyfile(char *src,char *dest,int32_t cmpflag) return(len); } -int32_t OS_releasemap(void *ptr,uint64_t filesize) +int32_t OS_releasemap(void *ptr,unsigned long filesize) { int32_t retval; if ( ptr == 0 ) @@ -725,7 +766,7 @@ long OS_ensurefilesize(char *fname,long filesize,int32_t truncateflag) int32_t OS_openmap(struct OS_mappedptr *mp) { - uint64_t allocsize = mp->allocsize; + unsigned long allocsize = mp->allocsize; if ( mp->actually_allocated != 0 ) { if ( mp->fileptr == 0 ) @@ -754,9 +795,9 @@ int32_t OS_openmap(struct OS_mappedptr *mp) return(0); } -void *OS_mappedptr(void **ptrp,struct OS_mappedptr *mp,uint64_t allocsize,int32_t rwflag,char *fname) +void *OS_mappedptr(void **ptrp,struct OS_mappedptr *mp,unsigned long allocsize,int32_t rwflag,char *fname) { - uint64_t filesize; + unsigned long filesize; mp->actually_allocated = 0;//!os_supports_mappedfiles(); if ( fname != 0 ) { @@ -836,7 +877,7 @@ void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep) { fclose(fp); *lenp = 0; - printf("OS_loadfile null size.(%s)\n",fname); + //printf("OS_loadfile null size.(%s)\n",fname); return(0); } if ( filesize > buflen-1 ) @@ -860,11 +901,15 @@ void *OS_loadfile(char *fname,char **bufp,long *lenp,long *allocsizep) return(buf); } -void *OS_filestr(long *allocsizep,char *fname) +void *OS_filestr(long *allocsizep,char *_fname) { - long filesize = 0; char *buf = 0; + long filesize = 0; char *fname,*buf = 0; void *retptr; *allocsizep = 0; - return(OS_loadfile(fname,&buf,&filesize,allocsizep)); + fname = malloc(strlen(_fname)+1); + strcpy(fname,_fname); + retptr = OS_loadfile(fname,&buf,&filesize,allocsizep); + free(fname); + return(retptr); } // following functions cant be fully implemented in one or more OS @@ -873,15 +918,15 @@ void *OS_mapfile(char *fname,long *filesizep,int32_t enablewrite) // win and pna return(OS_portable_mapfile(fname,filesizep,enablewrite)); } -int32_t OS_syncmap(struct OS_mappedptr *mp,long len) // pnacl doesnt implement sync -{ - return(OS_portable_syncmap(mp,len)); -} - -void *OS_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,long origsize) // no syncmap no tmpalloc -{ - return(OS_portable_tmpalloc(dirname,name,mem,origsize)); -} +/*int32_t OS_syncmap(struct OS_mappedptr *mp,long len) // pnacl doesnt implement sync + { + return(OS_portable_syncmap(mp,len)); + } + + void *OS_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,long origsize) // no syncmap no tmpalloc + { + return(OS_portable_tmpalloc(dirname,name,mem,origsize)); + }*/ void OS_init() { @@ -890,7 +935,7 @@ void OS_init() decode_hex(GENESIS_PUBKEY.bytes,sizeof(GENESIS_PUBKEY),GENESIS_PUBKEYSTR); decode_hex(GENESIS_PRIVKEY.bytes,sizeof(GENESIS_PRIVKEY),GENESIS_PRIVKEYSTR); SaM_PrepareIndices(); - return(OS_portable_init()); + OS_portable_init(); } int32_t OS_getline(int32_t waitflag,char *line,int32_t max,char *dispstr) @@ -928,3 +973,108 @@ int32_t OS_getline(int32_t waitflag,char *line,int32_t max,char *dispstr) line[strlen(line)-1] = 0; return((int32_t)strlen(line)); } + + +//////////// test suite for: +/* + int64_t OS_filesize(char *fname); + void OS_ensure_directory(char *dirname); + long OS_ensurefilesize(char *fname,long filesize,int32_t truncateflag); + int32_t OS_truncate(char *fname,long filesize); + int32_t OS_renamefile(char *fname,char *newfname); + int32_t OS_removefile(char *fname,int32_t scrubflag); + + void *OS_mapfile(char *fname,long *filesizep,int32_t enablewrite); + int32_t OS_releasemap(void *ptr,uint64_t filesize); + + double OS_milliseconds(); + void OS_randombytes(uint8_t *x,long xlen); + */ + +int32_t iguana_OStests() +{ + static uint16_t pairs[0x100][0x100],mappairs[0x100][0x100]; + uint8_t buf[4096],*bufptr; int32_t val,min,minij,maxij,max,i,j,histo[0x100],retval = 0,n=0; double startmilli,endmilli; FILE *fp; char *name,*name2,*dirname; long filesize; void *fileptr; + startmilli = OS_milliseconds(); + printf("\n>>>>>>>>>> starting tests. Please count the seconds (or use stopwatch)\n"); + name = "OStests"; + name2 = "OStests2"; + dirname = "tmp"; + fp = fopen(name,"wb"); + memset(histo,0,sizeof(histo)); + memset(pairs,0,sizeof(pairs)); + memset(mappairs,0,sizeof(mappairs)); + for (i=0; i<4096; i++) + { + OS_randombytes(buf,sizeof(buf)); + for (j=0; j 0 ) + pairs[buf[j-1]][buf[j]]++; + } + } + fclose(fp); + printf("\nend of random bytes\n\n"); + if ( OS_filesize(name) != n ) + printf("FAIL OS_filesize %lld != %d error and if OS_filesize doesnt work, nothing else will work\n",(long long)OS_filesize(name),n), retval--; + else + { + printf("PASS OS_filesize.(%s) matches %d\n",name,n); + OS_renamefile(name,name2); + if ( OS_filesize(name2) != n ) + printf("FAIL OS_renamefile returns filesize %lld != %d\n",(long long)OS_filesize(name2),n), retval--; + else printf("PASS OS_renamefile (%s) -> (%s) worked\n",name,name2); + if ( (fileptr= OS_mapfile(name2,&filesize,0)) == 0 ) + printf("FAIL OS_mapfile.(%s) returns null\n",name2), retval--; + else if ( filesize != n ) + printf("FAIL OS_mapfile.(%s) returns %ld != %d\n",name2,filesize,n), retval--; + else + { + bufptr = fileptr; + for (i=0; i<4096; i++) + { + memcpy(buf,bufptr,sizeof(buf)); + bufptr += sizeof(buf); + for (j=1; j max ) + max = val; + else if ( val < min ) + min = val; + for (j=0; j<0x100; j++) + { + if ( (val= pairs[i][j]) > maxij ) + maxij = val; + else if ( val < minij ) + minij = val; + } + } + endmilli = OS_milliseconds(); + printf("\n\nDid that take %.3f seconds? If not, there is a problem with OS_milliseconds\n\nMake sure above numbers look random and the min/max are within specified range:\n<3%% %.2f%% min %d max %d | <75%% %.3f%% minij %d maxij %d\n",(endmilli - startmilli)/1000.,100*(double)max/min - 100.,min,max,100*(double)maxij/minij - 100.,minij,maxij); + return(retval); +} diff --git a/crypto777/iguana_serdes.c b/crypto777/iguana_serdes.c index eff6f3e5f..f4ff2b923 100755 --- a/crypto777/iguana_serdes.c +++ b/crypto777/iguana_serdes.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,10 +13,11 @@ * * ******************************************************************************/ +#ifndef FROM_JS #include "OS_portable.h" #include "../includes/curve25519.h" -// threadsafe +// threadsafe int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp) { int32_t i; uint64_t x; @@ -79,7 +80,7 @@ int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *co iguana_rwnum(1,H->serdatalen,sizeof(int32_t),&datalen); if ( data != 0 ) { - hash2 = bits256_doublesha256(0,data,datalen); + hash2 = bits256_doublesha256(0,data,datalen); // GRS? iguana_rwbignum(1,tmp.bytes,sizeof(tmp),hash2.bytes); for (i=0; i<4; i++) H->hash[i] = tmp.bytes[i]; @@ -213,3 +214,4 @@ int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endian else memcpy(serialized,endianedp,len); return(len); } +#endif diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 3f963393a..5f978e305 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -182,7 +182,7 @@ void calc_OP_HASH160(char hexstr[41],uint8_t rmd160[20],char *pubkey) } decode_hex(buf,len,pubkey); calc_rmd160_sha256(rmd160,buf,len); - if ( 0 ) + if ( (0) ) { int i; for (i=0; i<20; i++) @@ -193,6 +193,14 @@ void calc_OP_HASH160(char hexstr[41],uint8_t rmd160[20],char *pubkey) init_hexbytes_noT(hexstr,rmd160,20); } +double _xblend(float *destp,double val,double decay) +{ + double oldval; + if ( (oldval = *destp) != 0. ) + return((oldval * decay) + ((1. - decay) * val)); + else return(val); +} + double _dxblend(double *destp,double val,double decay) { double oldval; @@ -263,12 +271,12 @@ int32_t iguana_numthreads(struct iguana_info *coin,int32_t mask) void iguana_launcher(void *ptr) { - struct iguana_thread *t = ptr; struct iguana_info *coin; - coin = t->coin; + struct iguana_thread *t = ptr; //struct iguana_info *coin; + //coin = t->coin; t->funcp(t->arg); - if ( coin != 0 ) - coin->Terminated[t->type % (sizeof(coin->Terminated)/sizeof(*coin->Terminated))]++; - queue_enqueue("TerminateQ",&TerminateQ,&t->DL,0); + //if ( coin != 0 ) + // coin->Terminated[t->type % (sizeof(coin->Terminated)/sizeof(*coin->Terminated))]++; + queue_enqueue("TerminateQ",&TerminateQ,&t->DL); } void iguana_terminate(struct iguana_thread *t) @@ -295,8 +303,8 @@ struct iguana_thread *iguana_launch(struct iguana_info *coin,char *name,iguana_f coin->Launched[t->type]++; retval = OS_thread_create(&t->handle,NULL,(void *)iguana_launcher,(void *)t); if ( retval != 0 ) - printf("error launching %s\n",t->name); - while ( (t= queue_dequeue(&TerminateQ,0)) != 0 ) + printf("error launching %s retval.%d errno.%d\n",t->name,retval,errno); + while ( (t= queue_dequeue(&TerminateQ)) != 0 ) { if ( (rand() % 100000) == 0 && coin != 0 ) printf("terminated.%d launched.%d terminate.%p\n",coin->Terminated[t->type],coin->Launched[t->type],t); @@ -359,11 +367,15 @@ int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex) { int32_t adjust,i = 0; //printf("decode.(%s)\n",hex); - if ( is_hexstr(hex,n) == 0 ) + if ( is_hexstr(hex,n) <= 0 ) { memset(bytes,0,n); return(n); } + if ( hex[n-1] == '\n' || hex[n-1] == '\r' ) + hex[--n] = 0; + if ( hex[n-1] == '\n' || hex[n-1] == '\r' ) + hex[--n] = 0; if ( n == 0 || (hex[n*2+1] == 0 && hex[n*2] != 0) ) { if ( n > 0 ) @@ -424,9 +436,9 @@ char *clonestr(char *str) if ( str == 0 || str[0] == 0 ) { printf("warning cloning nullstr.%p\n",str); -#ifdef __APPLE__ - while ( 1 ) sleep(1); -#endif +//#ifdef __APPLE__ +// while ( 1 ) sleep(1); +//#endif str = (char *)""; } clone = (char *)malloc(strlen(str)+16); @@ -434,7 +446,6 @@ char *clonestr(char *str) return(clone); } - int32_t safecopy(char *dest,char *src,long len) { int32_t i = -1; @@ -447,6 +458,7 @@ int32_t safecopy(char *dest,char *src,long len) if ( i == len ) { printf("safecopy: %s too long %ld\n",src,len); + //printf("divide by zero! %d\n",1/zeroval()); #ifdef __APPLE__ //getchar(); #endif @@ -510,11 +522,24 @@ static int _increasing_double(const void *a,const void *b) { #define double_a (*(double *)a) #define double_b (*(double *)b) - if ( double_b > double_a ) - return(-1); - else if ( double_b < double_a ) - return(1); - return(0); + if ( double_b > double_a ) + return(-1); + else if ( double_b < double_a ) + return(1); + return(0); +#undef double_a +#undef double_b +} + +static int _decreasing_double(const void *a,const void *b) +{ +#define double_a (*(double *)a) +#define double_b (*(double *)b) + if ( double_b > double_a ) + return(1); + else if ( double_b < double_a ) + return(-1); + return(0); #undef double_a #undef double_b } @@ -560,8 +585,14 @@ static int _decreasing_uint32(const void *a,const void *b) int32_t sortds(double *buf,uint32_t num,int32_t size) { - qsort(buf,num,size,_increasing_double); - return(0); + qsort(buf,num,size,_increasing_double); + return(0); +} + +int32_t revsortds(double *buf,uint32_t num,int32_t size) +{ + qsort(buf,num,size,_decreasing_double); + return(0); } int32_t sort64s(uint64_t *buf,uint32_t num,int32_t size) @@ -961,6 +992,7 @@ int32_t RS_encode(char *rsaddr,uint64_t id) rsaddr[j++] = '-'; } rsaddr[j] = 0; + //printf("%llu -> NXT RS (%s)\n",(long long)id,rsaddr); return(0); } @@ -1074,30 +1106,6 @@ void rmd160ofsha256(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) calc_rmd160(hexstr,buf,sha256,sizeof(sha256)); } -void calc_md2str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) -{ - bits128 x; - calc_md2(hexstr,buf,msg,len); - decode_hex(buf,sizeof(x),hexstr); - memcpy(buf,x.bytes,sizeof(x)); -} - -void calc_md4str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) -{ - bits128 x; - calc_md4(hexstr,buf,msg,len); - decode_hex(buf,sizeof(x),hexstr); - memcpy(buf,x.bytes,sizeof(x)); -} - -void calc_md5str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) -{ - bits128 x; - calc_md5(hexstr,msg,len); - decode_hex(buf,sizeof(x),hexstr); - memcpy(buf,x.bytes,sizeof(x)); -} - void calc_crc32str(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) { uint32_t crc; uint8_t serialized[sizeof(crc)]; @@ -1115,6 +1123,7 @@ void calc_NXTaddr(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len) { uint8_t mysecret[32]; uint64_t nxt64bits; nxt64bits = conv_NXTpassword(mysecret,buf,msg,len); + //printf("call RSencode with %llu\n",(long long)nxt64bits); RS_encode(hexstr,nxt64bits); } @@ -1134,3 +1143,145 @@ void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen) vcalc_sha256(0,hash.bytes,data,datalen); calc_rmd160(0,rmd160,hash.bytes,sizeof(hash)); } + +char *cmc_ticker(char *base) +{ + char url[512]; + sprintf(url,"https://api.coinmarketcap.com/v1/ticker/%s/",base); + return(issue_curl(url)); +} + +char *bittrex_orderbook(char *base,char *rel,int32_t maxdepth) +{ + char market[64],url[512]; + sprintf(market,"%s-%s",rel,base); + sprintf(url,"http://bittrex.com/api/v1.1/public/getorderbook?market=%s&type=both&depth=%d",market,maxdepth); + return(issue_curl(url)); +} + +double calc_theoretical(double weighted,double CMC_average,double changes[3]) +{ + double theoretical = 0.; //adjusted = 0., + if ( weighted > SMALLVAL && CMC_average > SMALLVAL ) + { + theoretical = (weighted + CMC_average) * 0.5; + /*if ( changes[0] > SMALLVAL && changes[1] > SMALLVAL && changes[2] > SMALLVAL ) + { + if ( changes[0] > changes[1] && changes[1] > changes[2] ) // breakout + { + adjusted = theoretical * (1. - (changes[0] + changes[1]) * .005); + } + } + else if ( changes[0] < -SMALLVAL && changes[1] < -SMALLVAL && changes[2] < -SMALLVAL ) // + { + if ( changes[0] < changes[1] && changes[1] < changes[2] ) // waterfall + { + adjusted = theoretical * (1. - (changes[0] + changes[1]) * .005); + } + } + if ( adjusted != 0. && theoretical != 0. ) + theoretical = (theoretical + adjusted) * 0.5;*/ + } + //printf("adjusted %.8f theoretical %.8f (%.8f + wt %.8f)\n",adjusted,theoretical,CMC_average,weighted); + return(theoretical); +} + +double calc_weighted(double *avebidp,double *aveaskp,double *bids,double *bidvols,int32_t numbids,double *asks,double *askvols,int32_t numasks,double limit) +{ + int32_t i; double weighted = 0.,bidsum = 0., asksum = 0.,totalbids = 0.,totalasks = 0.; + bidsum = bids[0] * bidvols[0], totalbids = bidvols[0]; + asksum = asks[0] * askvols[0], totalasks = askvols[0]; + for (i=1; i limit ) + break; + bidsum += bids[i] * bidvols[i]; + totalbids += bidvols[i]; + } + for (i=1; i limit ) + break; + asksum += asks[i] * askvols[i]; + totalasks += askvols[i]; + } + if ( totalbids != 0. && totalasks != 0. ) + { + *avebidp = (bidsum / totalbids); + *aveaskp = (asksum / totalasks); + weighted = (*avebidp + *aveaskp) * 0.5; + } + //printf("weighted %f\n",weighted); + return(weighted); +} + +double weighted_orderbook(double *avebidp,double *aveaskp,double *highbidp,double *lowaskp,char *orderbookstr,double limit) +{ + cJSON *bookjson,*bid,*ask,*resobj,*item; int32_t i,numbids,numasks; double bidvols[50],bids[50],askvols[50],asks[50],weighted = 0.; + if ( orderbookstr != 0 ) + { + if ( (bookjson= cJSON_Parse(orderbookstr)) != 0 ) + { + if ( (resobj= jobj(bookjson,"result")) != 0 ) + { + bid = jarray(&numbids,resobj,"buy"); + if ( numbids > sizeof(bids)/sizeof(*bids) ) + numbids = (int32_t)(sizeof(bids)/sizeof(*bids)); + ask = jarray(&numasks,resobj,"sell"); + if ( numasks > sizeof(asks)/sizeof(*asks) ) + numasks = (int32_t)(sizeof(asks)/sizeof(*asks)); + if ( bid != 0 && ask != 0 ) + { + for (i=0; i SMALLVAL && weighted > SMALLVAL ) + theoretical = calc_theoretical(weighted,*CMC_averagep,changes); + if ( (0) && counter++ < 100 ) + printf("HBLA.[%.8f %.8f] AVE.[%.8f %.8f] (%s) CMC %f %f %f %f\n",*highbidp,*lowaskp,*avebidp,*aveaskp,jprint(item,0),*CMC_averagep,changes[0],changes[1],changes[2]); + free_json(cmcjson); + } + free(cmcstr); + } + return(theoretical); +} + diff --git a/crypto777/inet.c b/crypto777/inet.c index 6579bd6be..6d3555e89 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -24,7 +24,9 @@ #ifdef _WIN32 #define in6_addr sockaddr #define in_addr_t struct sockaddr_storage +#ifndef NATIVE_WINDOWS #define EAFNOSUPPORT WSAEAFNOSUPPORT +#endif struct sockaddr_in6 { short sin6_family; @@ -371,7 +373,7 @@ uint64_t _calc_ipbits(char *ip_port) port = parse_ipaddr(ipaddr,ip_port); memset(&addr,0,sizeof(addr)); portable_pton(ip_port[0] == '[' ? AF_INET6 : AF_INET,ipaddr,&addr); - if ( 0 ) + if ( (0) ) { int i; for (i=0; i<16; i++) @@ -470,7 +472,7 @@ uint32_t conv_domainname(char *ipaddr,char *domain) int32_t ipv4only = 1; uint32_t ipbits; struct sockaddr_in ss; - if ( 0 && conv_domain((struct sockaddr_storage *)&ss,(const char *)domain,ipv4only) == 0 ) + if ( (0) && conv_domain((struct sockaddr_storage *)&ss,(const char *)domain,ipv4only) == 0 ) { ipbits = *(uint32_t *)&ss.sin_addr; expand_ipbits(ipaddr,ipbits); @@ -603,7 +605,10 @@ uint16_t parse_endpoint(int32_t *ip6flagp,char *transport,char *ipbuf,char *retb ipbits = calc_ipbits(ipaddr); expand_ipbits(tmp,ipbits); if ( strcmp(tmp,ipaddr) != 0 ) - ipaddr = 0, sprintf(retbuf,"{\"result\":\"illegal ipaddr\",\"endpoint\":\"%s\",\"ipaddr\":\"%s\",\"checkaddr\":\"%s\"}",endpoint,ipaddr,tmp); + { + sprintf(retbuf,"{\"result\":\"illegal ipaddr\",\"endpoint\":\"%s\",\"ipaddr\":\"%s\",\"checkaddr\":\"%s\"}",endpoint,ipaddr,tmp); + ipaddr = 0; + } } if ( inet != 0 && ipaddr != 0 && port != 0 ) { diff --git a/crypto777/jpeg/jconfig.h b/crypto777/jpeg/jconfig.h index 966b1d514..98cf6a54d 100755 --- a/crypto777/jpeg/jconfig.h +++ b/crypto777/jpeg/jconfig.h @@ -20,6 +20,7 @@ /* Define "boolean" as unsigned char, not int, on Windows systems. */ #ifdef _WIN32 +#define USE_MSDOS_MEMMGR #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ typedef unsigned char boolean; #endif @@ -29,7 +30,11 @@ typedef unsigned char boolean; #ifdef JPEG_INTERNALS /* #undef RIGHT_SHIFT_IS_UNSIGNED */ +#ifdef WIN32 +#define INLINE +#else #define INLINE __inline__ +#endif /* These are for configuring the JPEG memory manager. */ /* #undef DEFAULT_MAX_MEM */ /* #undef NO_MKTEMP */ diff --git a/crypto777/jpeg/jmemsys.h b/crypto777/jpeg/jmemsys.h index 6c3c6d348..5da67ae30 100755 --- a/crypto777/jpeg/jmemsys.h +++ b/crypto777/jpeg/jmemsys.h @@ -154,6 +154,7 @@ typedef struct backing_store_struct { /* For the MS-DOS manager (jmemdos.c), we need: */ handle_union handle; /* reference to backing-store storage object */ char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ + FILE *temp_file; #else #ifdef USE_MAC_MEMMGR /* For the Mac manager (jmemmac.c), we need: */ diff --git a/crypto777/jpeg/unix/jmemname.c b/crypto777/jpeg/unix/jmemname.c index 4bcd66290..b738d4f21 100755 --- a/crypto777/jpeg/unix/jmemname.c +++ b/crypto777/jpeg/unix/jmemname.c @@ -11,7 +11,9 @@ * Also, the problem of determining the amount of memory available * is shoved onto the user. */ +#ifndef _WIN32 #include +#endif #define JPEG_INTERNALS #include "../jinclude.h" @@ -68,7 +70,11 @@ extern void free JPP((void *ptr)); */ #ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */ -#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */ +#ifdef _WIN32 +#define TEMP_DIRECTORY "" /* recommended setting for Unix */ +#else +#define TEMP_DIRECTORY "/tmp/" /* recommended setting for Unix */ +#endif #endif static int next_file_num; /* to distinguish among several temp files */ diff --git a/crypto777/m_LP b/crypto777/m_LP index 259846c31..bc143b523 100755 --- a/crypto777/m_LP +++ b/crypto777/m_LP @@ -1,4 +1,4 @@ git pull rm *.o gcc -c -DLIQUIDITY_PROVIDER=1 -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/lib/x86_64-linux-gnu/curl -rm -f ../agents/libcrypto777.a; ar rcu ../agents/libcrypto777.a *.o +rm -f ../agents/libcrypto777.a; ar rc ../agents/libcrypto777.a *.o diff --git a/crypto777/m_LP_StaticNanoMsg b/crypto777/m_LP_StaticNanoMsg new file mode 100755 index 000000000..f6487bc1d --- /dev/null +++ b/crypto777/m_LP_StaticNanoMsg @@ -0,0 +1,30 @@ +# Very basic makefile for compiling iguana in Linux with StaticNanoMsg +# derived from m_LP (used to compile iguana for linux) +# author: fadedreamz + +SRCS=$(wildcard *.c) +SRCS+=$(wildcard jpeg/*.c) +SRCS+=$(wildcard jpeg/unix/*.c) + +OBJS=$(SRCS:%.c=%.o) + +INCLUDE_DIRS+=-I/usr/lib/x86_64-linux-gnu/curl +PREPROCESSORS+=-DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG + +CFLAGS+=-O2 $(PREPROCESSORS) $(INCLUDE_DIRS) + +update_repo: + git pull + +clean: + -rm $(OBJS) + +all: update_repo $(OBJS) static + @echo ' ================' + @echo '| crypto777 [OK] |' + @echo ' ================' + +static: $(OBJS) + ar rc ../agents/libcrypto777.a $(OBJS) + +.PHONY: update_repo clean all static \ No newline at end of file diff --git a/crypto777/m_osx_release b/crypto777/m_osx_release new file mode 100755 index 000000000..1cdb05957 --- /dev/null +++ b/crypto777/m_osx_release @@ -0,0 +1,4 @@ +git pull +rm *.o +gcc -mmacosx-version-min=10.6 -c -DLIQUIDITY_PROVIDER=1 -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/lib/x86_64-linux-gnu/curl +rm -f ../agents/libcrypto777.a; ar rc ../agents/libcrypto777.a *.o diff --git a/crypto777/nanosrc/aio/usock_posix.c b/crypto777/nanosrc/aio/usock_posix.c index 44a8acb65..2f85e559c 100755 --- a/crypto777/nanosrc/aio/usock_posix.c +++ b/crypto777/nanosrc/aio/usock_posix.c @@ -167,7 +167,7 @@ int nn_usock_start (struct nn_usock *self, int domain, int type, int protocol) s = socket (domain, type, protocol); if (nn_slow (s < 0)) return -errno; - //PNACL_message("got socket s.%d\n",s); + //printf("got socket s.%d\n",s); nn_usock_init_from_fd (self, s); /* Start the state machine. */ @@ -286,11 +286,14 @@ int nn_usock_bind (struct nn_usock *self, const struct sockaddr *addr, /* Allow re-using the address. */ opt = 1; + printf("call setsockopt %d SOL_SOCKET.%d SO_REUSEADDR.%d in nn_usock_bind\n",self->s,SOL_SOCKET,SO_REUSEADDR); rc = setsockopt (self->s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); - errno_assert (rc == 0); + printf("called setsockopt in nn_usock_bind returns %d\n",rc); + // ignore SO_REUSEADDR failures + //errno_assert (rc == 0); rc = bind (self->s, addr, (socklen_t) addrlen); - //printf("usock.%d -> bind rc.%d errno.%d %s\n",self->s,rc,errno,nn_strerror(errno)); + printf("usock.%d -> bind rc.%d errno.%d %s\n",self->s,rc,errno,nn_strerror(errno)); if (nn_slow (rc != 0)) return -errno; @@ -306,7 +309,7 @@ int nn_usock_listen (struct nn_usock *self, int backlog) /* Start listening for incoming connections. */ rc = listen (self->s, backlog); - //printf("usock.%d -> listen rc.%d errno.%d %s\n",self->s,rc,errno,nn_strerror(errno)); + printf("usock.%d -> listen rc.%d errno.%d %s\n",self->s,rc,errno,nn_strerror(errno)); if (nn_slow (rc != 0)) return -errno; @@ -333,7 +336,7 @@ void nn_usock_accept (struct nn_usock *self, struct nn_usock *listener) #else s = accept (listener->s, NULL, NULL); #endif - //printf("usock.%d -> accept errno.%d s.%d %s\n",self->s,errno,s,nn_strerror(errno)); + printf("usock.%d -> accept errno.%d s.%d %s\n",self->s,errno,s,nn_strerror(errno)); /* Immediate success. */ if (nn_fast (s >= 0)) { @@ -366,7 +369,7 @@ void nn_usock_accept (struct nn_usock *self, struct nn_usock *listener) and allow processing other events in the meantime */ if (nn_slow (errno != EAGAIN && errno != EWOULDBLOCK && errno != ECONNABORTED && errno != listener->errnum)) { - PNACL_message("listen errno.%d\n",errno); + printf("listen errno.%d\n",errno); listener->errnum = errno; listener->state = NN_USOCK_STATE_ACCEPTING_ERROR; nn_fsm_raise (&listener->fsm, @@ -393,7 +396,7 @@ void nn_usock_connect (struct nn_usock *self, const struct sockaddr *addr, /* Do the connect itself. */ rc = connect(self->s,addr,(socklen_t)addrlen); - //printf("usock.%d <- connect (%llx) rc.%d errno.%d %s\n",self->s,*(long long *)addr,rc,errno,nn_strerror(errno)); + printf("usock.%d <- connect (%llx) rc.%d errno.%d %s\n",self->s,*(long long *)addr,rc,errno,nn_strerror(errno)); /* Immediate success. */ if ( nn_fast(rc == 0) ) { @@ -404,7 +407,7 @@ void nn_usock_connect (struct nn_usock *self, const struct sockaddr *addr, if ( nn_slow(errno != EINPROGRESS) ) { self->errnum = errno; - PNACL_message("error.%d not EINPROGRESS\n",errno); + printf("error.%d not EINPROGRESS\n",errno); nn_fsm_action (&self->fsm, NN_USOCK_ACTION_ERROR); return; } @@ -433,13 +436,13 @@ void nn_usock_send (struct nn_usock *self, const struct nn_iovec *iov, self->out.iov [out].iov_base = iov [i].iov_base; self->out.iov [out].iov_len = iov [i].iov_len; out++; - //PNACL_message("{%d} ",(int)iov [i].iov_len); + printf("{%d} ",(int)iov [i].iov_len); } - //PNACL_message("iov[%d]\n",out); self->out.hdr.msg_iovlen = out; /* Try to send the data immediately. */ rc = nn_usock_send_raw (self, &self->out.hdr); + printf("iov[%d] nn_usock_send_raw -> rc.%d\n",out,rc); /* Success. */ if (nn_fast (rc == 0)) { @@ -472,17 +475,17 @@ void nn_usock_recv (struct nn_usock *self, void *buf, size_t len, int *fd) rc = nn_usock_recv_raw (self, buf, &nbytes); if (nn_slow (rc < 0)) { errnum_assert (rc == -ECONNRESET, -rc); - //PNACL_message("rc.%d vs ECONNRESET\n",rc,ECONNRESET); + //printf("rc.%d vs ECONNRESET\n",rc,ECONNRESET); nn_fsm_action (&self->fsm, NN_USOCK_ACTION_ERROR); return; } //int i; //for (i=0; i<16&&ifsm, &self->event_received, NN_USOCK_RECEIVED); return; } @@ -1021,19 +1024,19 @@ int32_t nn_getiovec_size(uint8_t *buf,int32_t maxlen,struct msghdr *hdr) if ( nn_slow(iov->iov_len == NN_MSG) ) { errno = EINVAL; - PNACL_message("ERROR: iov->iov_len == NN_MSG\n"); + printf("ERROR: iov->iov_len == NN_MSG\n"); return(-1); } if ( nn_slow(!iov->iov_base && iov->iov_len) ) { errno = EFAULT; - PNACL_message("ERROR: !iov->iov_base && iov->iov_len\n"); + printf("ERROR: !iov->iov_base && iov->iov_len\n"); return(-1); } if ( maxlen > 0 && nn_slow(size + iov->iov_len > maxlen) ) { errno = EINVAL; - PNACL_message("ERROR: sz.%d + iov->iov_len.%d < maxlen.%d\n",(int32_t)size,(int32_t)iov->iov_len,maxlen); + printf("ERROR: sz.%d + iov->iov_len.%d < maxlen.%d\n",(int32_t)size,(int32_t)iov->iov_len,maxlen); return(-1); } if ( iov->iov_len > 0 ) @@ -1054,7 +1057,7 @@ ssize_t mysendmsg(int32_t usock,struct msghdr *hdr,int32_t flags) clen = hdr->msg_controllen; if ( hdr->msg_control == 0 ) clen = 0; - nn_assert(clen == 0); // no supporty control messagies + nn_assert(clen == 0); // no support control messagies if ( veclen > sizeof(_buf) ) // - clen - 5) ) buf = malloc(veclen);// + clen + 5); else buf = _buf; @@ -1069,10 +1072,10 @@ ssize_t mysendmsg(int32_t usock,struct msghdr *hdr,int32_t flags) if ( nn_getiovec_size(&buf[offset],veclen,hdr) == veclen ) { nbytes = send(usock,buf,offset + veclen,0); - //PNACL_message(">>>>>>>>> send.[%d %d %d %d] (n.%d v.%d c.%d)-> usock.%d nbytes.%d\n",buf[offset],buf[offset+1],buf[offset+2],buf[offset+3],(int32_t)offset+veclen,veclen,clen,usock,(int32_t)nbytes); + printf(">>>>>>>>> send.[%d %d %d %d] (n.%d v.%d c.%d)-> usock.%d nbytes.%d\n",buf[offset],buf[offset+1],buf[offset+2],buf[offset+3],(int32_t)offset+veclen,veclen,clen,usock,(int32_t)nbytes); if ( nbytes != offset + veclen ) { - //PNACL_message("nbytes.%d != offset.%d veclen.%d errno.%d usock.%d\n",(int32_t)nbytes,(int32_t)offset,veclen,errno,usock); + printf("nbytes.%d != offset.%d veclen.%d errno.%d usock.%d\n",(int32_t)nbytes,(int32_t)offset,veclen,errno,usock); } if ( nbytes >= offset ) nbytes -= offset; @@ -1080,19 +1083,19 @@ ssize_t mysendmsg(int32_t usock,struct msghdr *hdr,int32_t flags) else { err = -errno; - PNACL_message("mysendmsg: unexpected nn_getiovec_size error %d\n",err); + printf("mysendmsg: unexpected nn_getiovec_size error %d\n",err); } if ( buf != _buf ) free(buf); if ( err != 0 ) { - PNACL_message("nn_usock_send_raw errno.%d err.%d\n",errno,err); + printf("nn_usock_send_raw errno.%d err.%d\n",errno,err); return(-errno); } } else { - PNACL_message("nn_usock_send_raw errno.%d invalid iovec size\n",errno); + printf("nn_usock_send_raw errno.%d invalid iovec size\n",errno); return(-errno); } return(nbytes); @@ -1104,32 +1107,32 @@ ssize_t myrecvmsg(int32_t usock,struct msghdr *hdr,int32_t flags,int32_t len) iov = hdr->msg_iov; /*if ( (n= (int32_t)recv(usock,lens,sizeof(lens),0)) != sizeof(lens) ) { - PNACL_message("error getting veclen/clen n.%d vs %d from usock.%d\n",n,(int32_t)sizeof(lens),usock); + printf("error getting veclen/clen n.%d vs %d from usock.%d\n",n,(int32_t)sizeof(lens),usock); return(0); - } else PNACL_message("GOT %d bytes from usock.%d\n",n,usock); + } else printf("GOT %d bytes from usock.%d\n",n,usock); offset = 0; veclen = lens[offset++]; veclen |= ((int32_t)lens[offset++] << 8); veclen |= ((int32_t)lens[offset++] << 16); clen = lens[offset++]; clen |= ((int32_t)lens[offset++] << 8); - PNACL_message("veclen.%d clen.%d waiting in usock.%d\n",veclen,clen,usock); + printf("veclen.%d clen.%d waiting in usock.%d\n",veclen,clen,usock); if ( clen > 0 ) { if ( (cbytes= (int32_t)recv(usock,hdr->msg_control,clen,0)) != clen ) { - PNACL_message("myrecvmsg: unexpected cbytes.%d vs clen.%d\n",cbytes,clen); + printf("myrecvmsg: unexpected cbytes.%d vs clen.%d\n",cbytes,clen); } } else cbytes = 0;*/ hdr->msg_controllen = 0; if ( (nbytes= (int32_t)recv(usock,iov->iov_base,len,0)) != len ) { - //PNACL_message("myrecvmsg: partial nbytes.%d vs veclen.%d\n",(int32_t)nbytes,len); + //printf("myrecvmsg: partial nbytes.%d vs veclen.%d\n",(int32_t)nbytes,len); } - //PNACL_message("GOT nbytes.%d of len.%d from usock.%d\n",(int32_t)nbytes,len,usock); + //printf("GOT nbytes.%d of len.%d from usock.%d\n",(int32_t)nbytes,len,usock); if ( 0 && nbytes > 0 ) { - PNACL_message("got nbytes.%d from usock.%d [%d %d %d %d]\n",(int32_t)nbytes,usock,((uint8_t *)iov->iov_base)[0],((uint8_t *)iov->iov_base)[1],((uint8_t *)iov->iov_base)[2],((uint8_t *)iov->iov_base)[3]); + printf("got nbytes.%d from usock.%d [%d %d %d %d]\n",(int32_t)nbytes,usock,((uint8_t *)iov->iov_base)[0],((uint8_t *)iov->iov_base)[1],((uint8_t *)iov->iov_base)[2],((uint8_t *)iov->iov_base)[3]); } return(nbytes); } @@ -1144,7 +1147,7 @@ static int nn_usock_send_raw (struct nn_usock *self, struct msghdr *hdr) nbytes = sendmsg(self->s,hdr,MSG_NOSIGNAL); #else nbytes = sendmsg(self->s,hdr,0); - //printf("sendmsg nbytes.%d\n",(int32_t)nbytes); + printf("nn_usock_send_raw nbytes.%d\n",(int32_t)nbytes); #endif #endif /* Handle errors. */ @@ -1199,13 +1202,13 @@ int32_t nn_process_cmsg(struct nn_usock *self,struct msghdr *hdr) memcpy(&retval,(int32_t *)CMSG_DATA(cmsg),sizeof(int32_t)); if ( self->in.pfd ) { - PNACL_message("CMSG set self->in.pfd (%d)\n",retval); + printf("CMSG set self->in.pfd (%d)\n",retval); *self->in.pfd = retval; self->in.pfd = NULL; } else { - PNACL_message("CMSG nn_closefd(%d)\n",retval); + printf("CMSG nn_closefd(%d)\n",retval); nn_closefd(retval); } break; @@ -1257,7 +1260,7 @@ static int nn_usock_recv_raw(struct nn_usock *self, void *buf, size_t *len) if (!length) return 0; } -#ifdef NN_USE_MYMSG +#if NN_USE_MYMSG usebuf = (length >= NN_USOCK_BATCH_SIZE); #else usebuf = (length >= NN_USOCK_BATCH_SIZE); @@ -1286,7 +1289,7 @@ static int nn_usock_recv_raw(struct nn_usock *self, void *buf, size_t *len) #if NN_USE_MYMSG nbytes = myrecvmsg(self->s,&hdr,0,(int32_t)iov.iov_len); - //printf("got nbytes.%d from recvmsg errno.%d %s\n",(int32_t)nbytes,errno,nn_strerror(errno)); + printf("got nbytes.%d from recvmsg errno.%d %s\n",(int32_t)nbytes,errno,nn_strerror(errno)); #else nbytes = recvmsg (self->s, &hdr, 0); #endif @@ -1310,7 +1313,7 @@ static int nn_usock_recv_raw(struct nn_usock *self, void *buf, size_t *len) } } else if ( hdr.msg_controllen > 0 ) nn_process_cmsg(self,&hdr); - //PNACL_message("nbytes.%d length.%d *len %d\n",(int)nbytes,(int)length,(int)*len); + printf("nbytes.%d length.%d *len %d\n",(int)nbytes,(int)length,(int)*len); // If the data were received directly into the place we can return straight away if ( usebuf != 0 ) diff --git a/crypto777/nanosrc/aio/usock_posix.c_dev b/crypto777/nanosrc/aio/usock_posix.c_dev index 954b3045f..244b0753c 100755 --- a/crypto777/nanosrc/aio/usock_posix.c_dev +++ b/crypto777/nanosrc/aio/usock_posix.c_dev @@ -31,11 +31,11 @@ #include #include #include -#ifndef __PNACL +//#ifndef __PNACL #include -#else -#include -#endif +//#else +//#include +//#endif #define NN_USOCK_STATE_IDLE 1 #define NN_USOCK_STATE_STARTING 2 @@ -287,7 +287,8 @@ int nn_usock_bind (struct nn_usock *self, const struct sockaddr *addr, /* Allow re-using the address. */ opt = 1; rc = setsockopt (self->s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); - errno_assert (rc == 0); + // ignore SO_REUSEADDR failures + //errno_assert (rc == 0); rc = bind (self->s, addr, (socklen_t) addrlen); if (nn_slow (rc != 0)) @@ -999,7 +1000,7 @@ static int32_t nn_usock_send_raw(struct nn_usock *self,struct msghdr *hdr) #else nbytes = sendmsg(self->s,hdr,0); #endif - PostMessage("nn_usock_send_raw nbytes.%d for sock.%d\n",(int32_t)nbytes,self->s); + printf("nn_usock_send_raw nbytes.%d for sock.%d\n",(int32_t)nbytes,self->s); if ( nn_slow(nbytes < 0) ) // Handle errors { if ( nn_fast(errno == EAGAIN || errno == EWOULDBLOCK) ) diff --git a/crypto777/nanosrc/aio/usock_posix.h b/crypto777/nanosrc/aio/usock_posix.h index 4a189a2bb..9286dcf24 100755 --- a/crypto777/nanosrc/aio/usock_posix.h +++ b/crypto777/nanosrc/aio/usock_posix.h @@ -25,11 +25,7 @@ #include #include -#ifndef __PNACL #include -#else -#include -#endif struct nn_usock { diff --git a/crypto777/nanosrc/aio/usock_win.c b/crypto777/nanosrc/aio/usock_win.c index 5eedfb60f..6e9f92427 100755 --- a/crypto777/nanosrc/aio/usock_win.c +++ b/crypto777/nanosrc/aio/usock_win.c @@ -126,7 +126,7 @@ int nn_usock_start (struct nn_usock *self, int domain, int type, int protocol) #if defined HANDLE_FLAG_INHERIT BOOL brc; #endif - +printf("nn_usock_start protocol %d\n",protocol); /* NamedPipes aren't sockets. They don't need all the socket initialisation stuff. */ if (domain != AF_UNIX) { diff --git a/crypto777/nanosrc/aio/worker_posix.c b/crypto777/nanosrc/aio/worker_posix.c index a2662d078..550aa31f4 100755 --- a/crypto777/nanosrc/aio/worker_posix.c +++ b/crypto777/nanosrc/aio/worker_posix.c @@ -102,29 +102,28 @@ void nn_worker_task_term (struct nn_worker_task *self) int nn_worker_init(struct nn_worker *self) { int32_t rc; - PNACL_message("nn_worker_init %p\n",self); - sleep(1); + //PNACL_msg("nn_worker_init %p\n",self); rc = nn_efd_init(&self->efd); - PNACL_message("efd init: rc.%d\n",rc); + //PNACL_msg("efd init: rc.%d\n",rc); if ( rc < 0 ) return rc; - PNACL_message("nn_mutex_init\n"); + //PNACL_msg("nn_mutex_init\n"); nn_mutex_init(&self->sync); - PNACL_message("nn_queue_init\n"); + //PNACL_msg("nn_queue_init\n"); nn_queue_init(&self->tasks); - PNACL_message("nn_queue_item_init\n"); + //PNACL_msg("nn_queue_item_init\n"); nn_queue_item_init(&self->stop); - PNACL_message("nn_poller_init\n"); + //PNACL_msg("nn_poller_init\n"); nn_poller_init(&self->poller); - PNACL_message("nn_poller_add\n"); + //PNACL_msg("nn_poller_add\n"); nn_poller_add(&self->poller,nn_efd_getfd(&self->efd),&self->efd_hndl); - PNACL_message("nn_poller_set_in\n"); + //PNACL_msg("nn_poller_set_in\n"); nn_poller_set_in(&self->poller, &self->efd_hndl); - PNACL_message("nn_timerset_init\n"); + //PNACL_msg("nn_timerset_init\n"); nn_timerset_init(&self->timerset); - PNACL_message("nn_thread_init\n"); + //PNACL_msg("nn_thread_init\n"); nn_thread_init(&self->thread,nn_worker_routine, self); - PNACL_message("finished nn_worker_init\n"); + //PNACL_msg("finished nn_worker_init\n"); return 0; } @@ -174,9 +173,11 @@ static void nn_worker_routine (void *arg) struct nn_worker_task *task; struct nn_worker_fd *fd; struct nn_worker_timer *timer; - PNACL_message("nn_worker_routine started\n"); + printf("nn_worker_routine started\n"); self = (struct nn_worker*) arg; +#ifndef FROM_JS while ( 1 ) // Infinite loop. It will be interrupted only when the object is shut down. +#endif { // Wait for new events and/or timeouts. rc = nn_poller_wait(&self->poller,nn_timerset_timeout (&self->timerset)); @@ -186,7 +187,7 @@ static void nn_worker_routine (void *arg) rc = nn_timerset_event(&self->timerset, &thndl); if ( rc == -EAGAIN ) break; - PNACL_message("nn_worker process expired user\n"); + printf("nn_worker process expired user\n"); errnum_assert(rc == 0, -rc); timer = nn_cont(thndl, struct nn_worker_timer, hndl); nn_ctx_enter(timer->owner->ctx); @@ -198,7 +199,7 @@ static void nn_worker_routine (void *arg) rc = nn_poller_event(&self->poller,&pevent,&phndl); // Get next poller event, such as IN or OUT if ( nn_slow(rc == -EAGAIN) ) break; - PNACL_message("nn_worker process all events from the poller\n"); + printf("nn_worker process all events from the poller\n"); if ( phndl == &self->efd_hndl ) // If there are any new incoming worker tasks, process them { nn_assert (pevent == NN_POLLER_IN); @@ -213,31 +214,36 @@ static void nn_worker_routine (void *arg) item = nn_queue_pop(&tasks); // Next worker task if ( nn_slow(!item) ) break; - PNACL_message("nn_worker next worker task\n"); + printf("nn_worker next worker task\n"); if ( nn_slow(item == &self->stop) ) // If the worker thread is asked to stop, do so { nn_queue_term(&tasks); return; } // It's a user-defined task. Notify the user that it has arrived in the worker thread - PNACL_message("nn_worker user defined task\n"); + printf("nn_worker user defined task\n"); task = nn_cont(item,struct nn_worker_task,item); nn_ctx_enter(task->owner->ctx); nn_fsm_feed(task->owner,task->src,NN_WORKER_TASK_EXECUTE,task); nn_ctx_leave (task->owner->ctx); } nn_queue_term (&tasks); +#ifdef FROM_JS + printf("done worker ITER\n"); + return; +#else continue; +#endif } - PNACL_message("nn_worker true i/o, invoke handler\n"); + printf("nn_worker true i/o, invoke handler\n"); fd = nn_cont(phndl,struct nn_worker_fd,hndl); // It's a true I/O event. Invoke the handler - PNACL_message("nn_worker true i/o, fd.%p\n",fd); + printf("nn_worker true i/o, fd.%p\n",fd); nn_ctx_enter(fd->owner->ctx); - PNACL_message("nn_worker true i/o, after nn_ctx_enter\n"); + printf("nn_worker true i/o, after nn_ctx_enter\n"); nn_fsm_feed(fd->owner,fd->src,pevent,fd); - PNACL_message("nn_worker true i/o, after nn_fsm_feed leave.%p\n",fd->owner->ctx); + printf("nn_worker true i/o, after nn_fsm_feed leave.%p\n",fd->owner->ctx); nn_ctx_leave(fd->owner->ctx); - PNACL_message("nn_worker true i/o, after nn_ctx_leave\n"); + printf("nn_worker true i/o, after nn_ctx_leave\n"); } } } diff --git a/crypto777/nanosrc/core/global.c b/crypto777/nanosrc/core/global.c index 51ab91709..83b8e63d0 100755 --- a/crypto777/nanosrc/core/global.c +++ b/crypto777/nanosrc/core/global.c @@ -201,9 +201,9 @@ static void nn_global_add_transport (struct nn_transport *transport) static void nn_global_add_socktype (struct nn_socktype *socktype) { - PNACL_message("add socktype %p -> %p\n",socktype,&SELF.socktypes); + PNACL_msg("add socktype %p -> %p\n",socktype,&SELF.socktypes); nn_list_insert (&SELF.socktypes, &socktype->item,nn_list_end (&SELF.socktypes)); - PNACL_message("added socktype %p -> %p\n",socktype,&SELF.socktypes); + PNACL_msg("added socktype %p -> %p\n",socktype,&SELF.socktypes); } void nn_global_init (void) { @@ -218,7 +218,7 @@ void nn_global_init (void) nn_assert (LOBYTE (data.wVersion) == 2 && HIBYTE (data.wVersion) == 2); #endif - PNACL_message("nn_global_init\n"); + PNACL_msg("nn_global_init\n"); nn_alloc_init(); // Initialise the memory allocation subsystem nn_random_seed(); // Seed the pseudo-random number generator // Allocate the global table of SP sockets. @@ -227,7 +227,7 @@ void nn_global_init (void) for (i=0; imsg_iovlen < 0) ) { + printf("nn_sendmsg.(%d) emsgsize\n",s); errno = EMSGSIZE; return -1; } @@ -689,6 +692,7 @@ int32_t nn_sendmsg(int32_t s,const struct nn_msghdr *msghdr,int32_t flags) chunk = *(void **)msghdr->msg_iov[0].iov_base; if ( nn_slow(chunk == NULL) ) { + printf("nn_sendmsg.(%d) efault\n",s); errno = EFAULT; return -1; } @@ -731,6 +735,7 @@ int32_t nn_sendmsg(int32_t s,const struct nn_msghdr *msghdr,int32_t flags) } nn_assert(msghdr->msg_control == 0); // cant support msgs until sendmsg()/recvmsg() native to pnacl rc = nn_sock_send(SELF.socks[s],&msg,flags); // Send it further down the stack + printf("rc from nn_socksend.%d\n",rc); if ( nn_slow(rc < 0) ) { // If we are dealing with user-supplied buffer, detach it from the message object @@ -772,13 +777,13 @@ int32_t nn_recvmsg(int32_t s,struct nn_msghdr *msghdr,int32_t flags) chunk = nn_chunkref_getchunk(&msg.body); *(void **)(msghdr->msg_iov[0].iov_base) = chunk; sz = nn_chunk_size(chunk); - //PNACL_message("got message -> iov_base.%p sz.%d\n",msghdr->msg_iov[0].iov_base,(int32_t)sz); + //PNACL_msg("got message -> iov_base.%p sz.%d\n",msghdr->msg_iov[0].iov_base,(int32_t)sz); } else // Copy the message content into the supplied gather array { data = nn_chunkref_data(&msg.body); sz = nn_chunkref_size(&msg.body); - //PNACL_message("got message -> data.%p sz.%d\n",data,(int32_t)sz); + //PNACL_msg("got message -> data.%p sz.%d\n",data,(int32_t)sz); for (i=0; i!=msghdr->msg_iovlen; i++) { iov = &msghdr->msg_iov[i]; @@ -809,15 +814,17 @@ int32_t nn_recvmsg(int32_t s,struct nn_msghdr *msghdr,int32_t flags) int32_t nn_sendmsg(int32_t s,const struct nn_msghdr *msghdr,int32_t flags) { int32_t rc,i,nnmsg; size_t sz,spsz; struct nn_iovec *iov; struct nn_msg msg; void *chunk; struct nn_cmsghdr *cmsg; - //PNACL_message("nn_sendmsg.(%d) \n",s); + printf("nn_sendmsg.(%d) \n",s); NN_BASIC_CHECKS; if ( nn_slow(!msghdr) ) { + printf("nn_sendmsg.EINVAL\n"); errno = EINVAL; return -1; } if ( nn_slow(msghdr->msg_iovlen < 0) ) { + printf("nn_sendmsg.EMSGSIZE\n"); errno = EMSGSIZE; return -1; } @@ -827,6 +834,7 @@ int32_t nn_sendmsg(int32_t s,const struct nn_msghdr *msghdr,int32_t flags) if ( nn_slow(chunk == NULL) ) { errno = EFAULT; + printf("nn_sendmsg.EFAULT\n"); return -1; } sz = nn_chunk_size(chunk); @@ -905,6 +913,7 @@ int32_t nn_sendmsg(int32_t s,const struct nn_msghdr *msghdr,int32_t flags) /* Send it further down the stack. */ rc = nn_sock_send (SELF.socks [s], &msg, flags); + printf("nn_sock_send rc.%d\n",rc); if (nn_slow (rc < 0)) { /* If we are dealing with user-supplied buffer, detach it from @@ -928,7 +937,7 @@ int32_t nn_recvmsg(int32_t s,struct nn_msghdr *msghdr,int32_t flags) { struct nn_msg msg; uint8_t *data; struct nn_iovec *iov; void *chunk,*ctrl; struct nn_cmsghdr *chdr; int32_t i,rc; size_t sz,hdrssz,ctrlsz,spsz,sptotalsz; - //PNACL_message("nn_recvmsg.(%d) \n",s); + //PNACL_msg("nn_recvmsg.(%d) \n",s); NN_BASIC_CHECKS; if ( nn_slow(!msghdr) ) { @@ -940,7 +949,7 @@ int32_t nn_recvmsg(int32_t s,struct nn_msghdr *msghdr,int32_t flags) errno = EMSGSIZE; return -1; } - //PNACL_message("get a message from sock.%d\n",s); + //PNACL_msg("get a message from sock.%d\n",s); rc = nn_sock_recv(SELF.socks[s],&msg,flags); // Get a message if ( nn_slow(rc < 0) ) { @@ -952,13 +961,13 @@ int32_t nn_recvmsg(int32_t s,struct nn_msghdr *msghdr,int32_t flags) chunk = nn_chunkref_getchunk(&msg.body); *(void **)(msghdr->msg_iov[0].iov_base) = chunk; sz = nn_chunk_size(chunk); - //PNACL_message("got message -> iov_base.%p sz.%d\n",msghdr->msg_iov[0].iov_base,(int32_t)sz); + //PNACL_msg("got message -> iov_base.%p sz.%d\n",msghdr->msg_iov[0].iov_base,(int32_t)sz); } else // Copy the message content into the supplied gather array { data = nn_chunkref_data(&msg.body); sz = nn_chunkref_size (&msg.body); - //PNACL_message("got message -> data.%p sz.%d\n",data,(int32_t)sz); + //PNACL_msg("got message -> data.%p sz.%d\n",data,(int32_t)sz); for (i=0; i!=msghdr->msg_iovlen; i++) { iov = &msghdr->msg_iov[i]; @@ -1150,7 +1159,7 @@ static void nn_global_submit_errors (int i, struct nn_sock *s, len = snprintf (curbuf, buf_left, " nanomsg: Endpoint %d [%s] error: %s\n", ep->eid, nn_ep_getaddr (ep), nn_strerror (ep->last_errno)); - PNACL_message("%s\n",curbuf); + PNACL_msg("%s\n",curbuf); #endif if (buf_left < len) break; @@ -1244,12 +1253,12 @@ static int nn_global_create_ep (int s, const char *addr, int bind) return -EINVAL; protosz = delim - addr; addr += protosz + 3; -#ifdef NN_USE_MYMSG - if ( strncmp("inproc",proto,strlen("inproc")) != 0 && strncmp("ipc",proto,strlen("ipc")) != 0 && strncmp("tcp",proto,strlen("tcp")) != 0 ) +#if NN_USE_MYMSG + if ( strncmp("inproc",proto,strlen("inproc")) != 0 && strncmp("ipc",proto,strlen("ipc")) != 0 && strncmp("tcp",proto,strlen("tcp")) && strncmp("ws",proto,strlen("ws")) != 0 ) { - PNACL_message("only ipc, inproc and tcp transport is supported\n"); - printf("only ipc, inproc and tcp transport is supported\n"); - fprintf(stderr,"only ipc, inproc and tcp transport is supported\n"); + PNACL_msg("only ipc, inproc, ws and tcp transport is supported\n"); + printf("only ipc, inproc, ws and tcp transport is supported\n"); + fprintf(stderr,"only ipc, inproc, ws and tcp transport is supported\n"); exit(-1); return -EPROTONOSUPPORT; } @@ -1267,7 +1276,10 @@ static int nn_global_create_ep (int s, const char *addr, int bind) tp = NULL; } if ( !tp ) // The protocol specified doesn't match any known protocol + { + printf("unknown protocol\n"); return -EPROTONOSUPPORT; + } rc = nn_sock_add_ep (SELF.socks [s], tp, bind, addr); // Ask the socket to create the endpoint return rc; } @@ -1324,12 +1336,12 @@ static void nn_global_handler (struct nn_fsm *myself,int src, int type, NN_UNUSE nn_timer_start (&global->stat_timer, 10000); // Start statistics collection timer return; default: - PNACL_message("bad action %d type %d\n",src,type); + PNACL_msg("bad action %d type %d\n",src,type); nn_fsm_bad_action(global->state, src, type); } default: - PNACL_message("bad source %d\n",src); + PNACL_msg("bad source %d\n",src); nn_fsm_bad_source(global->state, src, type); } diff --git a/crypto777/nanosrc/core/pipe.c b/crypto777/nanosrc/core/pipe.c index 2b674db44..1b1cd1dc6 100755 --- a/crypto777/nanosrc/core/pipe.c +++ b/crypto777/nanosrc/core/pipe.c @@ -58,7 +58,7 @@ void nn_pipebase_init(struct nn_pipebase *self,const struct nn_pipebase_vfptr *v memcpy(&self->options,&epbase->ep->options,sizeof(struct nn_ep_options)); nn_fsm_event_init(&self->in); nn_fsm_event_init(&self->out); - PNACL_message("pipebase_init vfptr.%p recv.%p rcvprio.%d\n",vfptr,vfptr->recv,self->options.rcvprio); + PNACL_msg("pipebase_init vfptr.%p recv.%p rcvprio.%d\n",vfptr,vfptr->recv,self->options.rcvprio); } void nn_pipebase_term (struct nn_pipebase *self) @@ -78,7 +78,7 @@ int nn_pipebase_start (struct nn_pipebase *self) self->instate = NN_PIPEBASE_INSTATE_ASYNC; self->outstate = NN_PIPEBASE_OUTSTATE_IDLE; rc = nn_sock_add(self->sock,(struct nn_pipe *)self); - PNACL_message("nn_pipebase_start self.%p rc.%d\n",self,rc); + PNACL_msg("nn_pipebase_start self.%p rc.%d\n",self,rc); if ( nn_slow(rc < 0) ) { self->state = NN_PIPEBASE_STATE_FAILED; @@ -98,7 +98,7 @@ void nn_pipebase_stop(struct nn_pipebase *self) void nn_pipebase_received(struct nn_pipebase *self) { - PNACL_message("nn_pipebase_received\n"); + PNACL_msg("nn_pipebase_received\n"); if ( nn_fast(self->instate == NN_PIPEBASE_INSTATE_RECEIVING) ) { self->instate = NN_PIPEBASE_INSTATE_RECEIVED; @@ -176,6 +176,7 @@ int nn_pipe_send(struct nn_pipe *self,struct nn_msg *msg) int rc; struct nn_pipebase *pipebase; pipebase = (struct nn_pipebase *)self; + printf("pipesend\n"); nn_assert (pipebase->outstate == NN_PIPEBASE_OUTSTATE_IDLE); pipebase->outstate = NN_PIPEBASE_OUTSTATE_SENDING; rc = pipebase->vfptr->send(pipebase,msg); @@ -196,7 +197,7 @@ int nn_pipe_recv(struct nn_pipe *self,struct nn_msg *msg) pipebase = (struct nn_pipebase*) self; nn_assert (pipebase->instate == NN_PIPEBASE_INSTATE_IDLE); pipebase->instate = NN_PIPEBASE_INSTATE_RECEIVING; - PNACL_message("call pipebase recv\n"); + PNACL_msg("call pipebase recv\n"); rc = pipebase->vfptr->recv (pipebase,msg); errnum_assert (rc >= 0, -rc); if ( nn_fast(pipebase->instate == NN_PIPEBASE_INSTATE_RECEIVED) ) diff --git a/crypto777/nanosrc/core/sock.c b/crypto777/nanosrc/core/sock.c index 6ba4bf5b1..ee95034a8 100755 --- a/crypto777/nanosrc/core/sock.c +++ b/crypto777/nanosrc/core/sock.c @@ -477,6 +477,7 @@ struct nn_ep *nn_find_ep(struct nn_sock *self,int32_t eid,const char *addr,struc int nn_sock_add_ep(struct nn_sock *self,struct nn_transport *transport,int32_t bind,const char *addr) { int rc,eid; struct nn_ep *ep; + printf("nn_sock_add_ep\n"); nn_ctx_enter (&self->ctx); if ( (ep= nn_find_ep(self,0,addr,transport,bind)) == NULL ) // The endpoint doesn't exist { @@ -484,16 +485,17 @@ int nn_sock_add_ep(struct nn_sock *self,struct nn_transport *transport,int32_t b rc = nn_ep_init(ep,NN_SOCK_SRC_EP,self,self->eid,transport,bind,addr); if ( nn_slow(rc < 0) ) { + printf("nn_sock_add_ep nn_ep_init rc.%d\n",rc); nn_free(ep); nn_ctx_leave(&self->ctx); return rc; } nn_ep_start(ep); - PNACL_message("ep sock.(%s) started %s://(%s) bind.%d\n",self->socket_name,transport->name,addr,bind); + printf("ep sock.(%s) started %s://(%s) bind.%d\n",self->socket_name,transport->name,addr,bind); eid = self->eid++; // Increase the endpoint ID for the next endpoint nn_list_insert(&self->eps,&ep->item,nn_list_end(&self->eps)); // Add to the list of active endpoints nn_ctx_leave (&self->ctx); - } else PNACL_message("self->sock.(%s) %p already has (%s)\n",self->socket_name,self->sockbase->sock,addr); + } else printf("self->sock.(%s) %p already has (%s)\n",self->socket_name,self->sockbase->sock,addr); return(ep->eid); } @@ -548,6 +550,7 @@ int nn_sock_send(struct nn_sock *self, struct nn_msg *msg, int flags) /* Try to send the message in a non-blocking way. */ rc = self->sockbase->vfptr->send (self->sockbase, msg); +printf("sockbase send rc.%d\n",rc); if (nn_fast (rc == 0)) { nn_ctx_leave (&self->ctx); return 0; @@ -560,8 +563,7 @@ int nn_sock_send(struct nn_sock *self, struct nn_msg *msg, int flags) return rc; } - /* If the message cannot be sent at the moment and the send call - is non-blocking, return immediately. */ + // If the message cannot be sent at the moment and the send call is non-blocking, return immediately. if (nn_fast (flags & NN_DONTWAIT)) { nn_ctx_leave (&self->ctx); return -EAGAIN; @@ -673,6 +675,7 @@ int nn_sock_add(struct nn_sock *self, struct nn_pipe *pipe) { int rc; rc = self->sockbase->vfptr->add(self->sockbase,pipe); + printf("nn_sock_add rc.%d\n",rc); if (nn_slow (rc >= 0)) { nn_sock_stat_increment (self, NN_STAT_CURRENT_CONNECTIONS, 1); } @@ -973,12 +976,12 @@ void nn_sock_report_error(struct nn_sock *self,struct nn_ep *ep,int32_t errnum,c if ( ep != 0 ) { fprintf(stderr,"nanomsg: socket.%s[%s]: Error: %s\n",self->socket_name,nn_ep_getaddr(ep),nn_strerror(errnum)); - PNACL_message("nanomsg: socket.%s[%s]: [%s:%d] Error: %s\n",self->socket_name,nn_ep_getaddr(ep),fname,linenum,nn_strerror(errnum)); + PNACL_msg("nanomsg: socket.%s[%s]: [%s:%d] Error: %s\n",self->socket_name,nn_ep_getaddr(ep),fname,linenum,nn_strerror(errnum)); } else { fprintf(stderr,"nanomsg: socket.%s: Error: %s\n",self->socket_name, nn_strerror(errnum)); - PNACL_message("nanomsg: socket.%s: [%s:%d] Error: %s\n",self->socket_name,fname,linenum,nn_strerror(errnum)); + PNACL_msg("nanomsg: socket.%s: [%s:%d] Error: %s\n",self->socket_name,fname,linenum,nn_strerror(errnum)); } } diff --git a/crypto777/nanosrc/devices/tcpmuxd.c b/crypto777/nanosrc/devices/tcpmuxd.c index c95c2a899..abd3b7706 100755 --- a/crypto777/nanosrc/devices/tcpmuxd.c +++ b/crypto777/nanosrc/devices/tcpmuxd.c @@ -53,12 +53,7 @@ int nn_tcpmuxd (int port) #include #include #include -#ifndef __PNACL #include -#else -#include -#include -#endif #include #include #include @@ -101,7 +96,8 @@ int nn_tcpmuxd (int port) opt = 1; rc = setsockopt (tcp_listener, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); - if (rc != 0) { return -1; } + // ignore SO_REUSEADDR failures + //if (rc != 0) { return -1; } memset (&tcp_addr, 0, sizeof (tcp_addr)); tcp_addr.sin_family = AF_INET; tcp_addr.sin_port = htons (port); diff --git a/crypto777/nanosrc/nn.h b/crypto777/nanosrc/nn.h index 3d6e7c598..0127338f3 100755 --- a/crypto777/nanosrc/nn.h +++ b/crypto777/nanosrc/nn.h @@ -30,6 +30,7 @@ extern "C" { #include #include +#include #include "nn_config.h" /* Handle DSO symbol visibility */ diff --git a/crypto777/nanosrc/nn_config.h b/crypto777/nanosrc/nn_config.h index e3f132847..74edc6229 100755 --- a/crypto777/nanosrc/nn_config.h +++ b/crypto777/nanosrc/nn_config.h @@ -32,8 +32,8 @@ // need one of following 3, listed in order of precedence, used by efd* //#define NN_HAVE_EVENTFD 1 -//#define NN_HAVE_PIPE 1 -#define NN_HAVE_SOCKETPAIR 1 +#define NN_HAVE_PIPE 1 +//#define NN_HAVE_SOCKETPAIR 1 // need one of following 3, listed in order of precedence, used by poller* #define NN_USE_POLL 1 @@ -46,16 +46,10 @@ #define NN_HAVE_MSG_CONTROL 0 //#define STANDALONE 1 +#define PNACL_msg(...) -#ifdef __PNACL -//#define FD_CLOEXEC 1 - -void PNACL_message(const char* format, ...); -#include -#include -#else +#if !defined(WIN32) //#define NN_ENABLE_EXTRA 1 -#define PNACL_message printf #include #include #endif diff --git a/crypto777/nanosrc/protocols/pipeline/xpush.c b/crypto777/nanosrc/protocols/pipeline/xpush.c index 2d938bd1f..10c5cf480 100755 --- a/crypto777/nanosrc/protocols/pipeline/xpush.c +++ b/crypto777/nanosrc/protocols/pipeline/xpush.c @@ -115,7 +115,7 @@ static int nn_xpush_add (struct nn_sockbase *self, struct nn_pipe *pipe) alloc_assert (data); nn_pipe_setdata (pipe, data); nn_lb_add (&xpush->lb, &data->lb, pipe, sndprio); - + printf("nn_xpush_add\n"); return 0; } @@ -160,6 +160,7 @@ static int nn_xpush_events (struct nn_sockbase *self) static int nn_xpush_send (struct nn_sockbase *self, struct nn_msg *msg) { + printf("nn_xpush_send\n"); return nn_lb_send (&nn_cont (self, struct nn_xpush, sockbase)->lb, msg, NULL); } diff --git a/crypto777/nanosrc/protocols/reqrep/xreq.c b/crypto777/nanosrc/protocols/reqrep/xreq.c index 7b96ba744..7ab93d201 100755 --- a/crypto777/nanosrc/protocols/reqrep/xreq.c +++ b/crypto777/nanosrc/protocols/reqrep/xreq.c @@ -101,7 +101,7 @@ int nn_xreq_add(struct nn_sockbase *self, struct nn_pipe *pipe) nn_pipe_setdata(pipe,data); nn_lb_add(&xreq->lb,&data->lb,pipe,sndprio); nn_fq_add(&xreq->fq,&data->fq,pipe,rcvprio); - + printf("nn_xreq_add\n"); return 0; } diff --git a/crypto777/nanosrc/protocols/utils/lb.c b/crypto777/nanosrc/protocols/utils/lb.c index f0e2e88e3..cbff61f2f 100755 --- a/crypto777/nanosrc/protocols/utils/lb.c +++ b/crypto777/nanosrc/protocols/utils/lb.c @@ -37,8 +37,7 @@ void nn_lb_term (struct nn_lb *self) nn_priolist_term (&self->priolist); } -void nn_lb_add (struct nn_lb *self, struct nn_lb_data *data, - struct nn_pipe *pipe, int priority) +void nn_lb_add (struct nn_lb *self, struct nn_lb_data *data,struct nn_pipe *pipe, int priority) { nn_priolist_add (&self->priolist, &data->priodata, pipe, priority); } @@ -68,14 +67,16 @@ int nn_lb_send (struct nn_lb *self, struct nn_msg *msg, struct nn_pipe **to) { int rc; struct nn_pipe *pipe; - + printf("nn_lb_send\n"); /* Pipe is NULL only when there are no avialable pipes. */ pipe = nn_priolist_getpipe (&self->priolist); + printf("nn_lb_send pipe.%p\n",pipe); if (nn_slow (!pipe)) return -EAGAIN; /* Send the messsage. */ rc = nn_pipe_send (pipe, msg); + printf("nn_pipe_send rc.%d\n",rc); errnum_assert (rc >= 0, -rc); /* Move to the next pipe. */ diff --git a/crypto777/nanosrc/protocols/utils/priolist.c b/crypto777/nanosrc/protocols/utils/priolist.c index a72b5d535..5b6cb5401 100755 --- a/crypto777/nanosrc/protocols/utils/priolist.c +++ b/crypto777/nanosrc/protocols/utils/priolist.c @@ -54,7 +54,7 @@ void nn_priolist_add(struct nn_priolist *self,struct nn_priolist_data *data, str { data->pipe = pipe; data->priority = priority; - //printf("nn_priolist_add.%p data.%p priority.%d\n",self,data,priority); + printf("nn_priolist_add.%p data.%p priority.%d\n",self,data,priority); nn_list_item_init (&data->item); } @@ -139,7 +139,7 @@ struct nn_pipe *nn_priolist_getpipe(struct nn_priolist *self) //printf("nn_priolist_getpipe.%p -1 current it is\n",self); return NULL; } - //printf("nn_priolist_getpipe.%p current.%d slot.%p\n",self,self->current,self->slots[self->current - 1].current->pipe); + printf("nn_priolist_getpipe.%p current.%d slot.%p\n",self,self->current,self->slots[self->current - 1].current->pipe); return self->slots[self->current - 1].current->pipe; } diff --git a/crypto777/nanosrc/protocols/utils/priolist.h b/crypto777/nanosrc/protocols/utils/priolist.h index 9d4a9cad7..358faae79 100755 --- a/crypto777/nanosrc/protocols/utils/priolist.h +++ b/crypto777/nanosrc/protocols/utils/priolist.h @@ -86,8 +86,7 @@ void nn_priolist_activate (struct nn_priolist *self, struct nn_priolist_data *da 0 otherwise. */ int nn_priolist_is_active (struct nn_priolist *self); -/* Get the pointer to the current pipe. If there's no pipe in the list, - NULL is returned. */ +// Get the pointer to the current pipe. If there's no pipe in the list, NULL is returned. struct nn_pipe *nn_priolist_getpipe (struct nn_priolist *self); /* Moves to the next pipe in the list. If 'release' is set to 1, the current diff --git a/crypto777/nanosrc/tests/testutil.h b/crypto777/nanosrc/tests/testutil.h index fd3d5b68c..04d26edbb 100755 --- a/crypto777/nanosrc/tests/testutil.h +++ b/crypto777/nanosrc/tests/testutil.h @@ -26,9 +26,9 @@ #include #include -#ifdef __PNACL -#define printf PostMessage -#endif +//#ifdef __PNACL +//#define printf PostMessage +//#endif #include "../utils/attr.h" #include "../utils/err.h" diff --git a/crypto777/nanosrc/transports/ipc/bipc.c b/crypto777/nanosrc/transports/ipc/bipc.c index 76a6f9256..8527e45a6 100755 --- a/crypto777/nanosrc/transports/ipc/bipc.c +++ b/crypto777/nanosrc/transports/ipc/bipc.c @@ -39,12 +39,8 @@ #include "../../utils/win.h" #else #include -#ifndef __PNACL #include #include -#else -#include -#endif #include #endif diff --git a/crypto777/nanosrc/transports/ipc/cipc.c b/crypto777/nanosrc/transports/ipc/cipc.c index 56dcbc83d..1f6c3b7de 100755 --- a/crypto777/nanosrc/transports/ipc/cipc.c +++ b/crypto777/nanosrc/transports/ipc/cipc.c @@ -39,13 +39,8 @@ #include "../../utils/win.h" #else #include -#ifndef __PNACL #include #include -#else -#include -#include -#endif #endif #define NN_CIPC_STATE_IDLE 1 diff --git a/crypto777/nanosrc/transports/ipc/ipc.c b/crypto777/nanosrc/transports/ipc/ipc.c index 1421ec276..45d3851ce 100755 --- a/crypto777/nanosrc/transports/ipc/ipc.c +++ b/crypto777/nanosrc/transports/ipc/ipc.c @@ -37,11 +37,7 @@ #include "../../utils/win.h" #else #include -#ifndef __PNACL #include -#else -#include -#endif #include #endif diff --git a/crypto777/nanosrc/transports/tcpmux/btcpmux.c b/crypto777/nanosrc/transports/tcpmux/btcpmux.c index 51fd16a64..2dd554272 100755 --- a/crypto777/nanosrc/transports/tcpmux/btcpmux.c +++ b/crypto777/nanosrc/transports/tcpmux/btcpmux.c @@ -44,12 +44,8 @@ #include "../../utils/win.h" #else #include -#ifndef __PNACL #include #include -#else -#include -#endif #include #endif diff --git a/crypto777/nanosrc/transports/utils/tcpmux.c b/crypto777/nanosrc/transports/utils/tcpmux.c index b4f7f0105..9f2cc3a60 100755 --- a/crypto777/nanosrc/transports/utils/tcpmux.c +++ b/crypto777/nanosrc/transports/utils/tcpmux.c @@ -28,11 +28,7 @@ #else #include #include -#ifndef __PNACL #include -#else -#include -#endif #endif #include "tcpmux.h" @@ -87,7 +83,7 @@ int tcpmux_accept (int s) memset (&hdr, 0, sizeof (hdr)); hdr.msg_iov = &iov; hdr.msg_iovlen = 1; -#ifndef NN_USE_MYMSG +#if !NN_USE_MYMSG unsigned char buf [256]; hdr.msg_control = buf; hdr.msg_controllen = sizeof (buf); diff --git a/crypto777/nanosrc/transports/ws/cws.c b/crypto777/nanosrc/transports/ws/cws.c index 57e66c91a..905e90405 100755 --- a/crypto777/nanosrc/transports/ws/cws.c +++ b/crypto777/nanosrc/transports/ws/cws.c @@ -329,7 +329,7 @@ static void nn_cws_handler (struct nn_fsm *self, int src, int type, struct nn_cws *cws; cws = nn_cont (self, struct nn_cws, fsm); - + printf("cws_handler src.%d type.%d state.%d\n",src,type,cws->state); switch (cws->state) { /******************************************************************************/ @@ -409,6 +409,7 @@ static void nn_cws_handler (struct nn_fsm *self, int src, int type, case NN_CWS_SRC_USOCK: switch (type) { case NN_USOCK_CONNECTED: + printf("cws connected\n"); nn_sws_start (&cws->sws, &cws->usock, NN_WS_CLIENT, nn_chunkref_data (&cws->resource), nn_chunkref_data (&cws->remote_host)); @@ -421,6 +422,7 @@ static void nn_cws_handler (struct nn_fsm *self, int src, int type, nn_epbase_clear_error (&cws->epbase); return; case NN_USOCK_ERROR: + printf("cws NN_USOCK_ERROR\n"); nn_epbase_set_error (&cws->epbase,nn_usock_geterrno (&cws->usock),__FILE__,__LINE__); nn_usock_stop(&cws->usock); cws->state = NN_CWS_STATE_STOPPING_USOCK; diff --git a/crypto777/nanosrc/transports/ws/sws.c b/crypto777/nanosrc/transports/ws/sws.c index 45f5430cc..627c5590f 100755 --- a/crypto777/nanosrc/transports/ws/sws.c +++ b/crypto777/nanosrc/transports/ws/sws.c @@ -370,7 +370,7 @@ static int nn_sws_send (struct nn_pipebase *self, struct nn_msg *msg) struct nn_cmsghdr *cmsg; struct nn_msghdr msghdr; uint8_t rand_mask [NN_SWS_FRAME_SIZE_MASK]; - +printf("nn_sws_send\n"); sws = nn_cont (self, struct nn_sws, pipebase); nn_assert_state (sws, NN_SWS_STATE_ACTIVE); @@ -884,7 +884,7 @@ static void nn_sws_handler (struct nn_fsm *self, int src, int type, int rc; sws = nn_cont (self, struct nn_sws, fsm); - + printf("sws src.%d type.%d state.%d\n",src,type,sws->state); switch (sws->state) { /******************************************************************************/ diff --git a/crypto777/nanosrc/transports/ws/sws.h b/crypto777/nanosrc/transports/ws/sws.h index d83f3f0fd..b482d1f19 100755 --- a/crypto777/nanosrc/transports/ws/sws.h +++ b/crypto777/nanosrc/transports/ws/sws.h @@ -152,7 +152,7 @@ struct nn_sws { uint8_t inmsg_control [NN_SWS_PAYLOAD_MAX_LENGTH]; /* Reason this connection is closing to send as closing handshake. */ - char fail_msg [NN_SWS_PAYLOAD_MAX_LENGTH]; + uint8_t fail_msg [NN_SWS_PAYLOAD_MAX_LENGTH]; size_t fail_msg_len; /* State of the outbound state machine. */ diff --git a/crypto777/nanosrc/transports/ws/ws.c b/crypto777/nanosrc/transports/ws/ws.c index 0e91e9474..3a9288284 100755 --- a/crypto777/nanosrc/transports/ws/ws.c +++ b/crypto777/nanosrc/transports/ws/ws.c @@ -156,7 +156,7 @@ int nn_ws_send (int s, const void *msg, size_t len, uint8_t msg_type, int flags) struct nn_msghdr hdr; struct nn_cmsghdr *cmsg; size_t cmsgsz; - +printf("nn_ws_send\n"); iov.iov_base = (void*) msg; iov.iov_len = len; diff --git a/crypto777/nanosrc/transports/ws/ws_handshake.c b/crypto777/nanosrc/transports/ws/ws_handshake.c index 52b8e3f40..eca21d44a 100755 --- a/crypto777/nanosrc/transports/ws/ws_handshake.c +++ b/crypto777/nanosrc/transports/ws/ws_handshake.c @@ -1213,7 +1213,7 @@ static void nn_ws_handshake_client_request (struct nn_ws_handshake *self) nn_random_generate (rand_key, sizeof (rand_key)); - rc = nn_base64_encode (rand_key, sizeof (rand_key), + rc = _nn_base64_encode (rand_key, sizeof (rand_key), encoded_key, sizeof (encoded_key)); encoded_key_len = strlen (encoded_key); @@ -1355,7 +1355,7 @@ static int nn_ws_handshake_hash_key (const char *key, size_t key_len, for (i = 0; i < strlen (NN_WS_HANDSHAKE_MAGIC_GUID); i++) nn_sha1_hashbyte (&hash, NN_WS_HANDSHAKE_MAGIC_GUID [i]); - rc = nn_base64_encode (nn_sha1_result (&hash), + rc = _nn_base64_encode (nn_sha1_result (&hash), sizeof (hash.state), hashed, hashed_len); return rc; diff --git a/crypto777/nanosrc/utils/efd_eventfd.c b/crypto777/nanosrc/utils/efd_eventfd.c index ae3449c15..f659296e7 100755 --- a/crypto777/nanosrc/utils/efd_eventfd.c +++ b/crypto777/nanosrc/utils/efd_eventfd.c @@ -32,9 +32,9 @@ int nn_efd_init(struct nn_efd *self) { int rc; int flags; - //PostMessage("inside efd_init eventfd\n"); + PNACL_msg("inside efd_init eventfd\n"); self->efd = eventfd(0, EFD_CLOEXEC); - //PostMessage("self->efd: %d\n",self->efd); + PNACL_msg("self->efd: %d\n",self->efd); if (self->efd == -1 && (errno == EMFILE || errno == ENFILE)) return -EMFILE; errno_assert(self->efd != -1); diff --git a/crypto777/nanosrc/utils/efd_pipe.c b/crypto777/nanosrc/utils/efd_pipe.c index ddce06119..59472d5d8 100755 --- a/crypto777/nanosrc/utils/efd_pipe.c +++ b/crypto777/nanosrc/utils/efd_pipe.c @@ -33,15 +33,15 @@ int nn_efd_init(struct nn_efd *self) { int rc,flags,p[2]; - PNACL_message("inside efd_init: pipe\n"); - sleep(1); + PNACL_msg("inside efd_init: pipe\n"); + //sleep(1); #if defined NN_HAVE_PIPE2 rc = pipe2(p, O_NONBLOCK | O_CLOEXEC); #else rc = pipe(p); #endif - PNACL_message("rc efd_init: %d\n",rc); - sleep(1); + PNACL_msg("rc efd_init: %d\n",rc); + //sleep(1); if (rc != 0 && (errno == EMFILE || errno == ENFILE)) return -EMFILE; errno_assert (rc == 0); @@ -50,20 +50,20 @@ int nn_efd_init(struct nn_efd *self) #if !defined NN_HAVE_PIPE2 && defined FD_CLOEXEC rc = fcntl (self->r, F_SETFD, FD_CLOEXEC); - PNACL_message("pipe efd_init: F_SETFDr rc %d\n",rc); + PNACL_msg("pipe efd_init: F_SETFDr rc %d\n",rc); errno_assert(rc != -1); rc = fcntl(self->w, F_SETFD, FD_CLOEXEC); - PNACL_message("pipe efd_init: F_SETFDw rc %d\n",rc); + PNACL_msg("pipe efd_init: F_SETFDw rc %d\n",rc); errno_assert(rc != -1); #endif #if !defined NN_HAVE_PIPE2 flags = fcntl(self->r, F_GETFL, 0); - PNACL_message("pipe efd_init: flags %d\n",flags); + PNACL_msg("pipe efd_init: flags %d\n",flags); if ( flags == -1 ) flags = 0; rc = fcntl(self->r, F_SETFL, flags | O_NONBLOCK); - PNACL_message("pipe efd_init: rc %d flags.%d\n",rc,flags); + PNACL_msg("pipe efd_init: rc %d flags.%d\n",rc,flags); errno_assert (rc != -1); #endif diff --git a/crypto777/nanosrc/utils/efd_socketpair.c b/crypto777/nanosrc/utils/efd_socketpair.c index aba164fa7..e04a4935e 100755 --- a/crypto777/nanosrc/utils/efd_socketpair.c +++ b/crypto777/nanosrc/utils/efd_socketpair.c @@ -35,7 +35,7 @@ int nn_efd_init (struct nn_efd *self) int rc; int flags; int sp [2]; - + PNACL_msg("socketpair efdinit\n"); #if defined SOCK_CLOEXEC rc = socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sp); #else diff --git a/crypto777/nanosrc/utils/efd_win.c b/crypto777/nanosrc/utils/efd_win.c index 8d253408f..5678ba7d5 100755 --- a/crypto777/nanosrc/utils/efd_win.c +++ b/crypto777/nanosrc/utils/efd_win.c @@ -84,8 +84,9 @@ int nn_efd_init (struct nn_efd *self) reuseaddr = 1; rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, (char*) &reuseaddr, sizeof (reuseaddr)); - if (nn_slow (rc == SOCKET_ERROR)) - goto wsafail; + // ignore SO_REUSEADDR failures + // if (nn_slow (rc == SOCKET_ERROR)) + // goto wsafail; /* Bind the listening socket to the local port. */ memset (&addr, 0, sizeof (addr)); diff --git a/crypto777/nanosrc/utils/err.c b/crypto777/nanosrc/utils/err.c index 6f5bc42a6..afca3471b 100755 --- a/crypto777/nanosrc/utils/err.c +++ b/crypto777/nanosrc/utils/err.c @@ -30,7 +30,7 @@ void nn_err_abort(void) { - PNACL_message("nn_err_abort\n"); + PNACL_msg("nn_err_abort\n"); while ( 1 ) { printf("exit due to error\n"); @@ -111,7 +111,7 @@ const char *nn_err_strerror(int32_t errnum) #pragma warning (push) #pragma warning (disable:4996) #endif - PNACL_message("nanomsg: errno.%d (%s)\n",errnum,strerror(errnum)); + PNACL_msg("nanomsg: errno.%d (%s)\n",errnum,strerror(errnum)); getchar(); return strerror (errnum); #if defined _MSC_VER diff --git a/crypto777/nanosrc/utils/err.h b/crypto777/nanosrc/utils/err.h index a9485549e..e932766e1 100755 --- a/crypto777/nanosrc/utils/err.h +++ b/crypto777/nanosrc/utils/err.h @@ -26,6 +26,7 @@ #include #include #include +#define PNACL_msg(...) /* Include nn.h header to define nanomsg-specific error codes. */ #include "../nn.h" @@ -44,7 +45,7 @@ #define nn_assert(x) \ do {\ if (nn_slow (!(x))) {\ - PNACL_message("Assertion failed: %s (%s:%d)\n", #x, \ + PNACL_msg("Assertion failed: %s (%s:%d)\n", #x, \ __FILE__, __LINE__);\ fflush (stderr);\ nn_err_abort ();\ @@ -54,7 +55,7 @@ #define nn_assert_state(obj, state_name) \ do {\ if (nn_slow ((obj)->state != state_name)) {\ - PNACL_message( \ + PNACL_msg( \ "Assertion failed: %d == %s (%s:%d)\n", \ (obj)->state, #state_name, \ __FILE__, __LINE__);\ @@ -66,7 +67,7 @@ #define alloc_assert(x) \ do {\ if (nn_slow (!x)) {\ - PNACL_message("Out of memory (%s:%d)\n",\ + PNACL_msg("Out of memory (%s:%d)\n",\ __FILE__, __LINE__);\ nn_err_abort ();\ }\ @@ -76,7 +77,7 @@ #define errno_assert(x) \ do {\ if (nn_slow (!(x))) {\ - PNACL_message("%s [%d] (%s:%d)\n", nn_err_strerror (errno),\ + PNACL_msg("%s [%d] (%s:%d)\n", nn_err_strerror (errno),\ (int) errno, __FILE__, __LINE__);\ nn_err_abort ();\ }\ @@ -86,7 +87,7 @@ #define errnum_assert(cond, err) \ do {\ if (nn_slow (!(cond))) {\ - PNACL_message("%s [%d] (%s:%d)\n", nn_err_strerror (err),(int) (err), __FILE__, __LINE__);\ + PNACL_msg("%s [%d] (%s:%d)\n", nn_err_strerror (err),(int) (err), __FILE__, __LINE__);\ nn_err_abort ();\ }\ } while (0) @@ -118,7 +119,7 @@ /* Assertion-like macros for easier fsm debugging. */ #define nn_fsm_error(message, state, src, type) \ do {\ - PNACL_message("%s: state=%d source=%d action=%d (%s:%d)\n", \ + PNACL_msg("%s: state=%d source=%d action=%d (%s:%d)\n", \ message, state, src, type, __FILE__, __LINE__);\ nn_err_abort ();\ } while (0) diff --git a/crypto777/nanosrc/utils/thread_posix.c b/crypto777/nanosrc/utils/thread_posix.c index 93c81b6cb..df005eee3 100755 --- a/crypto777/nanosrc/utils/thread_posix.c +++ b/crypto777/nanosrc/utils/thread_posix.c @@ -26,11 +26,11 @@ #include #include -static void *nn_thread_main_routine(void *arg) +void *nn_thread_main_routine(void *arg) { struct nn_thread *self; self = (struct nn_thread *)arg; - PNACL_message("nn_thread_main_routine arg.%p self->routine(%p) at %p\n",arg,self->arg,self->routine); + printf("nn_thread_main_routine arg.%p self->routine(%p) at %p\n",arg,self->arg,self->routine); self->routine(self->arg); // Run the thread routine return NULL; } @@ -42,16 +42,22 @@ void nn_thread_term(struct nn_thread *self) errnum_assert(rc == 0,rc); } +void *Nanomsg_threadarg; + #ifdef __PNACL void nn_thread_init(struct nn_thread *self,nn_thread_routine *routine,void *arg) { int32_t rc; // No signals should be processed by this thread. The library doesn't use signals and thus all the signals should be delivered to application threads, not to worker threads. - PNACL_message("nn_thread_init routine.%p arg.%p\n",routine,arg); + printf("nn_thread_init routine.%p arg.%p\n",routine,arg); self->routine = routine; self->arg = arg; +#ifdef FROM_JS + Nanomsg_threadarg = self; +#else rc = pthread_create(&self->handle,NULL,nn_thread_main_routine,(void *)self); errnum_assert (rc == 0, rc); +#endif } #else diff --git a/crypto777/nanosrc/utils/win.h b/crypto777/nanosrc/utils/win.h index dcfe06af6..288713712 100755 --- a/crypto777/nanosrc/utils/win.h +++ b/crypto777/nanosrc/utils/win.h @@ -27,8 +27,8 @@ #define WIN32_LEAN_AND_MEAN #endif -#include #include +#include #include #include #include diff --git a/crypto777/pnacl_libs/libcrypto.a b/crypto777/pnacl_libs/libcrypto.a deleted file mode 100755 index f1e059cab..000000000 Binary files a/crypto777/pnacl_libs/libcrypto.a and /dev/null differ diff --git a/crypto777/pnacl_libs/libcurl.a b/crypto777/pnacl_libs/libcurl.a deleted file mode 100755 index 34d79989c..000000000 Binary files a/crypto777/pnacl_libs/libcurl.a and /dev/null differ diff --git a/crypto777/pnacl_libs/libnanomsg.a b/crypto777/pnacl_libs/libnanomsg.a deleted file mode 100755 index c1fc4973c..000000000 Binary files a/crypto777/pnacl_libs/libnanomsg.a and /dev/null differ diff --git a/crypto777/pnacl_libs/libssl.a b/crypto777/pnacl_libs/libssl.a deleted file mode 100755 index 7685bb725..000000000 Binary files a/crypto777/pnacl_libs/libssl.a and /dev/null differ diff --git a/crypto777/pnacl_libs/libz.a b/crypto777/pnacl_libs/libz.a deleted file mode 100755 index e02de65d8..000000000 Binary files a/crypto777/pnacl_libs/libz.a and /dev/null differ diff --git a/crypto777/ramcoder.c b/crypto777/ramcoder.c index d495914de..54daeee5e 100755 --- a/crypto777/ramcoder.c +++ b/crypto777/ramcoder.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -430,19 +430,22 @@ int32_t ramcoder_decoder(struct ramcoder *coder,int32_t updateprobs,uint8_t *buf return(n); } -int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed) +int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 origseed) { - int32_t numbits; HUFF H,*hp = &H; + uint64_t histo[256]; bits256 seed; char str[65]; int32_t numbits; HUFF H,*hp = &H; _init_HUFF(hp,maxlen,bits); - if ( ramcoder_encoder(0,1,data,datalen,hp,0,&seed) < 0 ) + memset(histo,0,sizeof(histo)); + seed = origseed; + if ( ramcoder_encoder(0,1,data,datalen,hp,histo,&seed) < 0 ) return(-1); + printf("seed.%s\n",bits256_str(str,seed)); numbits = hp->bitoffset; - if ( 0 ) + if ( (1) ) { void *malloc(size_t); void free(void *); int32_t i,checklen; uint8_t *checkbuf; checkbuf = malloc(datalen*2); - memset(seed.bytes,0,sizeof(seed)); + seed = origseed; hrewind(hp); checklen = ramcoder_decoder(0,1,checkbuf,datalen*2,hp,&seed); if ( checklen != datalen || memcmp(checkbuf,data,datalen) != 0 ) @@ -457,7 +460,7 @@ int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t dat printf("%02x ",checkbuf[i]); printf("checklen.%d\n",checklen); getchar(); - } // else printf("CODEC passed datalen.%d -> numbits %d %d\n",datalen,numbits,numbits/8); + } else printf("CODEC passed datalen.%d -> numbits %d %d origseed.%s\n",datalen,numbits,numbits/8,bits256_str(str,origseed)); free(checkbuf); } return(numbits); diff --git a/crypto777/scrypt.c b/crypto777/scrypt.c index 99ce4a04a..1b156a286 100755 --- a/crypto777/scrypt.c +++ b/crypto777/scrypt.c @@ -69,7 +69,7 @@ static const uint32_t sha256_k[64] = { 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; -static inline void sha256_init(uint32_t *state) +static inline void scrypt_sha256_init(uint32_t *state) { memcpy(state, sha256_h, 32); } @@ -102,7 +102,7 @@ W[i] + sha256_k[i]) #define swab32(x) ((((x) << 24) & 0xff000000u) | (((x) << 8) & 0x00ff0000u) | (((x) >> 8) & 0x0000ff00u) | (((x) >> 24) & 0x000000ffu)) -static inline void sha256_transform(uint32_t *state, const uint32_t *block, int swap) +static inline void scrypt_sha256_transform(uint32_t *state, const uint32_t *block, int swap) { uint32_t W[64]; uint32_t S[8]; @@ -203,29 +203,29 @@ static inline void HMAC_SHA256_80_init(const uint32_t *key,uint32_t *tstate, uin /* tstate is assumed to contain the midstate of key */ memcpy(pad, key + 16, 16); memcpy(pad + 4, keypad, 48); - sha256_transform(tstate, pad, 0); + scrypt_sha256_transform(tstate, pad, 0); memcpy(ihash, tstate, 32); - sha256_init(ostate); + scrypt_sha256_init(ostate); for (i = 0; i < 8; i++) pad[i] = ihash[i] ^ 0x5c5c5c5c; for (; i < 16; i++) pad[i] = 0x5c5c5c5c; - sha256_transform(ostate, pad, 0); + scrypt_sha256_transform(ostate, pad, 0); - sha256_init(tstate); + scrypt_sha256_init(tstate); for (i = 0; i < 8; i++) pad[i] = ihash[i] ^ 0x36363636; for (; i < 16; i++) pad[i] = 0x36363636; - sha256_transform(tstate, pad, 0); + scrypt_sha256_transform(tstate, pad, 0); } static inline void PBKDF2_SHA256_80_128(const uint32_t *tstate,const uint32_t *ostate, const uint32_t *salt, uint32_t *output) { uint32_t istate[8], ostate2[8],ibuf[16], obuf[16]; int i, j; memcpy(istate, tstate, 32); - sha256_transform(istate, salt, 0); + scrypt_sha256_transform(istate, salt, 0); memcpy(ibuf, salt + 16, 16); memcpy(ibuf + 5, innerpad, 44); memcpy(obuf + 8, outerpad, 32); @@ -233,9 +233,9 @@ static inline void PBKDF2_SHA256_80_128(const uint32_t *tstate,const uint32_t *o { memcpy(obuf, istate, 32); ibuf[4] = i + 1; - sha256_transform(obuf, ibuf, 0); + scrypt_sha256_transform(obuf, ibuf, 0); memcpy(ostate2, ostate, 32); - sha256_transform(ostate2, obuf, 0); + scrypt_sha256_transform(ostate2, obuf, 0); for (j = 0; j < 8; j++) output[8 * i + j] = swab32(ostate2[j]); } @@ -244,12 +244,12 @@ static inline void PBKDF2_SHA256_80_128(const uint32_t *tstate,const uint32_t *o static inline void PBKDF2_SHA256_128_32(uint32_t *tstate, uint32_t *ostate,const uint32_t *salt, uint32_t *output) { uint32_t buf[16]; int i; - sha256_transform(tstate, salt, 1); - sha256_transform(tstate, salt + 16, 1); - sha256_transform(tstate, finalblk, 0); + scrypt_sha256_transform(tstate, salt, 1); + scrypt_sha256_transform(tstate, salt + 16, 1); + scrypt_sha256_transform(tstate, finalblk, 0); memcpy(buf, tstate, 32); memcpy(buf + 8, outerpad, 32); - sha256_transform(ostate, buf, 0); + scrypt_sha256_transform(ostate, buf, 0); for (i = 0; i < 8; i++) output[i] = swab32(ostate[i]); } @@ -344,7 +344,12 @@ static inline void scrypt_core(uint32_t *X, uint32_t *V, int N) void scrypt_1024_1_1_256(const uint32_t *input,uint32_t *output,uint32_t *midstate,uint8_t *scratchpad, int N) { - uint32_t *V,tstate[8],ostate[8],X[32] __attribute__((aligned(128))); + uint32_t *V,tstate[8],ostate[8],X[32] +#ifndef WIN32 + __attribute__((aligned(128))) +#endif + ; + V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); memcpy(tstate, midstate, 32); HMAC_SHA256_80_init(input, tstate, ostate); @@ -358,11 +363,11 @@ void calc_scrypthash(uint32_t *hash,void *data) uint8_t *scratchbuf; uint32_t midstate[8]; memset(midstate,0,sizeof(midstate)); memset(hash,0,32); - sha256_init(midstate); - sha256_transform(midstate,(void *)data,0); + scrypt_sha256_init(midstate); + scrypt_sha256_transform(midstate,(void *)data,0); scratchbuf = malloc(1024 * 128 + 64); scrypt_1024_1_1_256((void *)data,hash,midstate,scratchbuf,1024); free(scratchbuf); } //010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c -//010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c00 \ No newline at end of file +//010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c00 diff --git a/datachain/datachain.c b/datachain/datachain.c index 95792c520..4ce46416d 100755 --- a/datachain/datachain.c +++ b/datachain/datachain.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -20,7 +20,7 @@ uint32_t datachain_checkpoint(struct supernet_info *myinfo,struct iguana_info *c { char str[65],str2[65]; struct iguana_info *btc = iguana_coinfind("BTC"); printf("datachain_checkpoint.%s for %s.%u to %u lastheight.%d %s\n",bits256_str(str,merkle),coin->symbol,lastcheckpoint,timestamp,lastheight,bits256_str(str2,lasthash2)); - if ( (lastheight % NUMRELAYS) == RELAYID ) + if ( myinfo->IAMNOTARY != 0 && (lastheight % myinfo->NOTARY.NUMRELAYS) == myinfo->NOTARY.RELAYID ) { // if designated relay, submit checkpoint -> add ip/relayid to opreturn // @@ -320,15 +320,19 @@ void datachain_update_spend(struct supernet_info *myinfo,int32_t ordered,struct int64_t datachain_update(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,uint8_t rmd160[20],int64_t crypto777_payment,uint8_t type,int32_t height,uint64_t hdrsi_unspentind,int64_t value,uint32_t fileid,uint64_t scriptpos,int32_t scriptlen,bits256 txid,int32_t vout) { - if ( memcmp(rmd160,CRYPTO777_RMD160,20) == 0 ) + if ( (0) ) { - crypto777_payment += value; - printf("datachain_update crypto777 %.8f += %.8f\n",dstr(crypto777_payment),dstr(value)); + if ( memcmp(rmd160,CRYPTO777_RMD160,20) == 0 ) + { + crypto777_payment += value; + //printf("datachain_update crypto777 %.8f += %.8f\n",dstr(crypto777_payment),dstr(value)); + } + else if ( crypto777_payment != 0 && (type == IGUANA_SCRIPT_OPRETURN || type == IGUANA_SCRIPT_3of3 || type == IGUANA_SCRIPT_2of2 || type == IGUANA_SCRIPT_1of1) ) + { + //printf("datachain_update opreturn\n"); + iguana_opreturn(myinfo,ordered,coin,timestamp,bp,crypto777_payment,height,hdrsi_unspentind,value,fileid,scriptpos,scriptlen); + } else datachain_update_spend(myinfo,ordered,coin,timestamp,bp,height,txid,vout,rmd160,value); + return(crypto777_payment); } - else if ( crypto777_payment != 0 && (type == IGUANA_SCRIPT_OPRETURN || type == IGUANA_SCRIPT_3of3 || type == IGUANA_SCRIPT_2of2 || type == IGUANA_SCRIPT_1of1) ) - { - printf("datachain_update opreturn\n"); - iguana_opreturn(myinfo,ordered,coin,timestamp,bp,crypto777_payment,height,hdrsi_unspentind,value,fileid,scriptpos,scriptlen); - } else datachain_update_spend(myinfo,ordered,coin,timestamp,bp,height,txid,vout,rmd160,value); - return(crypto777_payment); + return(0); } diff --git a/datachain/datachain_KOMODO.c b/datachain/datachain_KOMODO.c index d9beb46a5..403990eac 100755 --- a/datachain/datachain_KOMODO.c +++ b/datachain/datachain_KOMODO.c @@ -78,12 +78,12 @@ bits256 datachain_opreturn_convert(uint8_t *txidbytes,int32_t *txlenp,struct igu int32_t datachain_genesis_verify(struct gecko_genesis_opreturn *opret) { - int32_t txlen,datalen; bits256 txid,threshold,hash2; uint8_t serialized[1024],txidbytes[1024]; struct iguana_msgblock msg; char str[65],str2[65]; - txid = datachain_opreturn_convert(txidbytes,&txlen,&msg,opret); + int32_t txlen,datalen; bits256 txid,threshold,hash2; uint8_t serialized[1024],txidbytes[1024]; struct iguana_msgzblock zmsg; char str[65],str2[65]; + txid = datachain_opreturn_convert(txidbytes,&txlen,(void *)&zmsg,opret); if ( opret->nBits >= GECKO_EASIESTDIFF ) threshold = bits256_from_compact(GECKO_EASIESTDIFF); else threshold = bits256_from_compact(opret->nBits); - datalen = iguana_rwblockhdr(1,0,serialized,&msg); + datalen = iguana_rwblockhdr(1,0,serialized,&zmsg); hash2 = iguana_calcblockhash("virtual",blockhash_sha256,serialized,datalen); //for (i=0; i= GECKO_EASIESTDIFF ) threshold = bits256_from_compact(GECKO_EASIESTDIFF); else threshold = bits256_from_compact(nBits); for (i=0; i<100000000; i++) { - opret.nonce = msg.H.nonce = i; - datalen = iguana_rwblockhdr(1,0,serialized,&msg); + opret.nonce = msg->H.nonce = i; + datalen = iguana_rwblockhdr(1,0,serialized,&zmsg); hash2 = iguana_calcblockhash(symbol,btcd->chain->hashalgo,serialized,datalen); if ( bits256_cmp(threshold,hash2) > 0 ) break; @@ -140,7 +140,7 @@ int32_t datachain_opreturn_create(uint8_t *serialized,char *symbol,char *name,ch void datachain_events_processKOMODO(struct supernet_info *myinfo,struct datachain_info *dPoW,struct datachain_event *event) { - struct gecko_chain *chain; bits256 hash2,threshold; struct gecko_genesis_opreturn opret; int32_t datalen,i,j,len,txlen; char symbol[16],name[64],magicstr[16],blockstr[8192],nbitstr[16],issuer[64],hashstr[65],str2[65],argbuf[1024],chainname[GECKO_MAXNAMELEN]; cJSON *valsobj; struct iguana_msgblock msg; uint8_t serialized[256],txidbytes[1024],buf[4]; struct iguana_info *virt,*btcd; + struct gecko_chain *chain; bits256 hash2,threshold; struct gecko_genesis_opreturn opret; int32_t datalen,i,j,len,txlen; char symbol[16],name[64],magicstr[16],blockstr[8192],nbitstr[16],issuer[64],hashstr[65],str2[65],argbuf[1024],chainname[GECKO_MAXNAMELEN]; cJSON *valsobj; struct iguana_msgzblock zmsg; uint8_t serialized[256],txidbytes[1024],buf[4]; struct iguana_info *virt,*btcd; if ( (btcd= iguana_coinfind("BTCD")) != 0 && memcmp(event->opreturn,"NEW",3) == 0 ) { //int32_t i; for (i=0; i<76; i++) @@ -151,13 +151,13 @@ void datachain_events_processKOMODO(struct supernet_info *myinfo,struct datachai datachain_genesis_verify(&opret); memset(symbol,0,sizeof(symbol)), memcpy(symbol,opret.symbol,sizeof(opret.symbol)); memset(name,0,sizeof(name)), memcpy(name,opret.name,sizeof(opret.name)); - hash2 = datachain_opreturn_convert(txidbytes,&txlen,&msg,&opret); + hash2 = datachain_opreturn_convert(txidbytes,&txlen,(void *)&zmsg,&opret); if ( opret.nBits >= GECKO_EASIESTDIFF ) threshold = bits256_from_compact(GECKO_EASIESTDIFF); else threshold = bits256_from_compact(opret.nBits); - msg.txn_count = 1; + zmsg.txn_count = 1; //n = iguana_serialize_block(virt->chain,&hash2,serialized,newblock); - datalen = iguana_rwblockhdr(1,0,serialized,&msg); + datalen = iguana_rwblockhdr(1,0,serialized,&zmsg); hash2 = iguana_calcblockhash(symbol,btcd->chain->hashalgo,serialized,datalen); for (i=0; i> 24) & 0xff,hashstr,opret.timestamp,nbitstr,opret.nonce,bits256_str(str2,msg.H.merkle_root),blockstr); + sprintf(argbuf,"{\"name\":\"%s\",\"symbol\":\"%s\",\"netmagic\":\"%s\",\"port\":%u,\"blocktime\":%u,\"pubval\":\"%02x\",\"p2shval\":\"%02x\",\"wifval\":\"%02x\",\"unitval\":\"%02x\",\"genesishash\":\"%s\",\"genesis\":{\"version\":1,\"timestamp\":%u,\"nBits\":\"%s\",\"nonce\":%d,\"merkle_root\":\"%s\"},\"genesisblock\":\"%s\"}",name,symbol,magicstr,opret.port,opret.blocktime,opret.pubval,opret.p2shval,opret.wifval,(opret.nBits >> 24) & 0xff,hashstr,opret.timestamp,nbitstr,opret.nonce,bits256_str(str2,zmsg.zH.merkle_root),blockstr); if ( (valsobj= cJSON_Parse(argbuf)) != 0 ) { printf("datachain.NEW (%s/%s port.%u blocktime.%d) issuer.%s (%s)\n",opret.symbol,opret.name,opret.port,opret.blocktime,issuer,jprint(valsobj,0)); diff --git a/deprecated/STEEM.c b/deprecated/STEEM.c new file mode 100644 index 000000000..83b79f9f5 --- /dev/null +++ b/deprecated/STEEM.c @@ -0,0 +1,304 @@ +/****************************************************************************** + * Copyright © 2016 jl777 * + * ALL RIGHTS RESERVED * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef __APPLE__ +#include "../iguana/iguana777.h" +#else +#include "iguana777.h" +#endif + +#define STEEMIT_PLANKTON 0 +#define STEEMIT_MINNOW_BALANCE 100 +#define STEEMIT_MINNOW 1 +#define STEEMIT_DOLPHIN_BALANCE 1000 +#define STEEMIT_DOLPHIN 2 +#define STEEMIT_WHALE_BALANCE 100000 +#define STEEMIT_WHALE 3 +#define STEEMIT_MEGAWHALE_BALANCE 1000000 +#define STEEMIT_MEGAWHALE 4 + +#include "postingkeys.c" +#define rand_account() postingkeys[rand() % (sizeof(postingkeys)/sizeof(*postingkeys))][0] + +struct vote_totals { char name[16]; uint32_t whale,nonwhale,whale_for_whale,whale_for_nonwhale,nonwhale_for_whale,nonwhale_for_nonwhale,whale_selfvote,nonwhale_selfvote; }; +struct steemit_word { UT_hash_handle hh; int score,ind; char wordpair[]; }; +struct steemit_vote { UT_hash_handle hh; double payout; char permlink[]; }; +struct steemit_whale { UT_hash_handle hh; double stake; char whale[]; }; +struct steemit_post { UT_hash_handle hh; double author_steempower,tallypower[STEEMIT_MEGAWHALE+1]; uint32_t height,author_type,tally[STEEMIT_MEGAWHALE+1]; char key[]; }; + +void steemit_vote(int32_t height,int32_t ind,int32_t j,cJSON *json); +void steemit_comment(int32_t height,int32_t ind,int32_t j,cJSON *json,int32_t activeflag); + +struct upvote_info +{ + char upvoter[64],*author,*permlink,*voters[1000]; + int32_t numvoters,whaleids[1000]; double weights[1000]; uint32_t starttime; +}; + +#define issue_IGUANA(url) bitcoind_RPC(0,"curl",url,0,0,0) +void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3); +int32_t USE_JAY,Startheight; + +char *STEEM_getstate(char *category) +{ + static void *cHandle; + char params[1024],url[512],*retstr; + if ( category == 0 ) + category = ""; + sprintf(url,"http://127.0.0.1:8090"); + sprintf(params,"{\"id\":%llu,\"method\":\"call\",\"params\":[\"database_api\", \"get_state\", [\"%s\"]]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),category); + retstr = curl_post(&cHandle,url,"",params,0,0,0,0); + return(retstr); +} + +char *STEEM_getblock(int32_t height) +{ + static void *cHandle; + char params[1024],url[512],*retstr; + sprintf(url,"http://127.0.0.1:8090"); + sprintf(params,"{\"id\":%llu,\"method\":\"call\",\"params\":[\"database_api\", \"get_block\", [%d]]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),height); + retstr = curl_post(&cHandle,url,"",params,0,0,0,0); + return(retstr); +} + +char *STEEM_vote(char *voter,char *author,char *permalink,int8_t wt,int32_t forceflag) +{ + static void *cHandle; static portable_mutex_t mutex; + char params[1024],url[512],*retstr; + if ( cHandle == 0 ) + portable_mutex_init(&mutex); + if ( strcmp(voter,"jl777") != 0 && strcmp(voter,"taker") != 0 && strcmp(voter,"karen13") != 0 && strcmp(voter,"proto") != 0 && strcmp(voter,"yefet") != 0 ) + { + printf("OVERRIDE: only jl777 upvotes %s.(%s %s)\n",voter,author,permalink); + return(clonestr("{\"error\":\"override and dont vote\"}")); + } + if ( forceflag == 0 && strncmp(permalink,"re-",3) == 0 )//&& (strcmp(voter,"jl777") == 0 || strcmp(voter,"taker") == 0) ) + { + printf("OVERRIDE: no upvoting on comments.(%s %s)\n",author,permalink); + return(clonestr("{\"error\":\"override and dont vote\"}")); + } + portable_mutex_lock(&mutex); + if ( wt > 100 ) + wt = 100; + else if ( wt < -100 ) + wt = -100; + sprintf(url,"http://127.0.0.1:8091"); + sprintf(params,"{\"id\":%llu,\"method\":\"vote\",\"params\":[\"%s\", \"%s\", \"%s\", %d, true]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),voter,author,permalink,wt); + retstr = curl_post(&cHandle,url,"",params,0,0,0,0); + portable_mutex_unlock(&mutex); + return(retstr); +} + +char *STEEM_getcontent(char *author,char *permalink) +{ + static void *cHandle; + char params[1024],url[512],*retstr; + sprintf(url,"http://127.0.0.1:8090"); + sprintf(params,"{\"id\":%llu,\"method\":\"get_content\",\"params\":[\"%s\", \"%s\"]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),author,permalink); + //printf("(%s %s) -> (%s)\n",author,permalink,params); + retstr = curl_post(&cHandle,url,"",params,0,0,0,0); + return(retstr); +} + +char *STEEM_getcomments(char *author,char *permalink) +{ + static void *cHandle; + char params[1024],url[512],*retstr; + sprintf(url,"http://127.0.0.1:8090"); + sprintf(params,"{\"id\":%llu,\"method\":\"get_content_replies\",\"params\":[\"%s\", \"%s\"]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),author,permalink); + //printf("(%s %s) -> (%s)\n",author,permalink,params); + retstr = curl_post(&cHandle,url,"",params,0,0,0,0); + return(retstr); +} + +char *STEEM_accountinfo(char *author) +{ + static void *cHandle; + char params[1024],url[512],*retstr; + sprintf(url,"http://127.0.0.1:8091"); + sprintf(params,"{\"id\":%llu,\"method\":\"get_account\",\"params\":[\"%s\"]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),author); + retstr = curl_post(&cHandle,url,"",params,0,0,0,0); + return(retstr); +} + +int32_t permalink_str(char *permalink,int32_t size,char *str) +{ + int32_t i,c; + for (i=0; str[i]!=0 && i= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') ) + { + + } else c = '-'; + permalink[i] = tolower(c); + } + permalink[i] = 0; + return(i); +} + +char *STEEM_comment(char *author,char *usepermalink,char *parent,char *parentpermalink,char *title,char *body,char *tag) +{ + /*post_comment(string author, string permlink, string parent_author, string parent_permlink, string title, string body, string json, bool broadcast) + "parent_author": "", + "parent_permlink": "introduceyourself", + "author": "jl777", + "permlink": "steemit-is-crypto-s-first-mass-market-solution", + "title": "steemit is crypto's first mass market solution!", + "body": "test post" + "json_metadata": "{\"tags\":[\"introduceyourself\",\"blockchain\",\"bitcoin\",\"networking\",\"iguana\",\"supernet\",\"bitcoindark\",\"\"],\"links\":[\"https://bitco.in/forum/forums/iguana.23/\"]}" + curl --url "http://127.0.0.1:8091" --data "{\"id\":444,\"method\":\"post_comment\",\"params\":[\"taker\", \"test-title\", \"\", \"introduceyourself\", \"test title\", \"test body\", \"{\\\"tags\\\":[\\\"introduceyourself\\\", \\\"test\\\", \\\"\\\"]}\", true]}"*/ + static void *cHandle; + char *params,permalink[4096],url[512],*retstr; + params = malloc(1024*1024*10); + if ( parent != 0 && parent[0] != 0 && strlen(parentpermalink)+strlen(parent)+8 < sizeof(permalink) ) + { + if ( usepermalink != 0 ) + strcpy(permalink,usepermalink); + else sprintf(permalink,"re-%s-%s-r%d",parent,parentpermalink,rand() & 0x7fffffff); + } + else permalink_str(permalink,sizeof(permalink),title); + sprintf(url,"http://127.0.0.1:8091"); + if ( tag != 0 ) + sprintf(params,"{\"id\":%llu,\"method\":\"post_comment\",\"params\":[\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"{\\\"tags\\\":[\\\"%s\\\", \\\"steem\\\", \\\"steemit\\\", \\\"test\\\", \\\"\\\"]}\", true]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),author,permalink,parent,parentpermalink,title,body,tag); //\\\"introduceyourself\\\", + else sprintf(params,"{\"id\":%llu,\"method\":\"post_comment\",\"params\":[\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"{}\", true]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),author,permalink,parent,parentpermalink,title,body); + //printf("ABOUT TO POST.(%s)\n",params), getchar(); + retstr = curl_post(&cHandle,url,"",params,0,0,0,0); + free(params); + //printf("got.(%s)\n",retstr); + return(retstr); +} + +char *STEEM_post(char *author,char *title,char *body,char *tag) +{ + return(STEEM_comment(author,0,"",tag!=0?tag:"steemit",title,body,tag)); +} + +char *STEEM_gethistory(char *account,int32_t firsti,int32_t num) +{ + static void *cHandle; + char params[1024],url[512],*retstr; + sprintf(url,"http://127.0.0.1:8090"); + sprintf(params,"{\"id\":%llu,\"method\":\"get_account_history\",\"params\":[\"%s\", %d, %d]}",(long long)(time(NULL)*1000 + ((int32_t)OS_milliseconds() % 1000)),account,firsti,num); + retstr = curl_post(&cHandle,url,"",params,0,0,0,0); + //printf("(%s) -> (%s)\n",params,retstr); + return(retstr); +} + +char *IGUANA_request(char *agent,char *method,cJSON *argjson) +{ + static void *cHandle; + char *argstr=0,*retstr,url[512]; + if ( argjson != 0 ) + argstr = jprint(argjson,0); + sprintf(url,"http://127.0.0.1:7778/api/%s/%s",agent,method); + retstr = curl_post(&cHandle,url,"",argstr,0,0,0,0); + if ( argstr != 0 ) + free(argstr); + return(retstr); +} + +int32_t special_account(char *account) +{ + int32_t i; + if ( strcmp("jl777",account) == 0 || strcmp("upvotes",account) == 0 || strcmp("taker",account) == 0 ) + return(1); + for (i=0; i (%s)\n",author,permlink,retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (result= jobj(retjson,"result")) != 0 ) + { + safecopy(author,jstr(result,"parent_author"),sizeof(author)); + safecopy(permlink,jstr(result,"parent_permlink"),sizeof(permlink)); + if ( author[0] != 0 ) + { + strcpy(_author,author); + strcpy(_permlink,permlink); + } + } else author[0] = 0; + free_json(retjson); + } + free(retstr); + } + } + return(depth); +} + +int32_t steemit_body(char *buf,int32_t size,char *author,char *permlink) +{ + char *retstr,*body; cJSON *retjson,*result; int32_t len = 0; + if ( (retstr= STEEM_getcomments(author,permlink)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (result= jobj(retjson,"result")) != 0 ) + { + if ( (body= jstr(result,"body")) != 0 ) + { + if ( (len= (int32_t)strlen(body)) > size ) + len = size; + strncpy(buf,body,len); + } + } + free_json(retjson); + } + free(retstr); + } + return(len); +} + +int32_t steemit_power(double *powerp,char *author) +{ + char *retstr; cJSON *retjson,*result; double steempower; int32_t retval = 0; + *powerp = 0.; + if ( (retstr= STEEM_accountinfo(author)) != 0 ) + { + //printf("power.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (result= jobj(retjson,"result")) != 0 ) + { + *powerp = steempower = jdouble(result,"vesting_shares") * .001; + if ( steempower >= STEEMIT_MINNOW_BALANCE ) + { + if ( steempower >= STEEMIT_DOLPHIN_BALANCE ) + { + if ( steempower >= STEEMIT_WHALE_BALANCE ) + { + if ( steempower >= STEEMIT_MEGAWHALE_BALANCE ) + retval = STEEMIT_MEGAWHALE; + else retval = STEEMIT_WHALE; + } else retval = STEEMIT_DOLPHIN; + } else retval = STEEMIT_MINNOW; + } else retval = STEEMIT_PLANKTON; + //printf("%s type.%d %.3f\n",author,retval,steempower); + } else printf("(%s) -> no result.(%s)\n",author,retstr); + free_json(retjson); + } + free(retstr); + } + return(retval); +} diff --git a/deprecated/iguana_instantdex.c b/deprecated/iguana_instantdex.c index 9f21a4309..a7cc52083 100755 --- a/deprecated/iguana_instantdex.c +++ b/deprecated/iguana_instantdex.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -225,7 +225,7 @@ struct instantdex_event *instantdex_addevent(struct instantdex_stateinfo *states for (i=0; i %s) without existing state and nextstate\n",statename,nextstatename); - exit(-1); + iguana_exit(0); return(0); } } @@ -877,7 +877,7 @@ struct instantdex_accept *instantdex_quotefind(struct supernet_info *myinfo,stru struct iguana_bundlereq *instantdex_recvquotes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *quotes,int32_t n) { - int32_t i,len,state,m = 0; uint8_t serialized[10000]; struct instantdex_accept *ap; struct exchange_info *exchange; + int32_t i,len,state,m = 0; uint8_t serialized[16384]; struct instantdex_accept *ap; struct exchange_info *exchange; exchange = exchanges777_find("bitcoin"); if ( req->addr == 0 ) return(0); @@ -1468,7 +1468,8 @@ void instantdex_update(struct supernet_info *myinfo) } /* -#include "../includes/iguana_apidefs.h" + #include "../includes/iguana_apidefs.h" + #include "../includes/iguana_apideclares.h" TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume) { diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h deleted file mode 100755 index 9e38d3df0..000000000 --- a/deprecated/obsolete.h +++ /dev/null @@ -1,18658 +0,0 @@ -// -// obsolete.h -// pnacl -// -// Created by jimbo laptop on 10/27/15. -// Copyright (c) 2015 jl777. All rights reserved. -// - -#ifndef pnacl_obsolete_h -#define pnacl_obsolete_h - -if ( 0 ) -{ - sleep(3); - char *str,*jsonstr = clonestr("{\"plugin\":\"relay\",\"method\":\"busdata\"}"); uint32_t nonce; - if ( (str= busdata_sync(&nonce,jsonstr,"allnodes",0)) != 0 ) - { - fprintf(stderr,"busdata.(%s)\n",str); - free(str); - } else printf("null return from busdata sync.(%s)\n",jsonstr); - getchar();exit(1); - } - -int32_t nn_stripctrl(int32_t *clenp,uint8_t *ctrl,int32_t ctrlsize,uint8_t *buf) -{ - int32_t clen,offset; - offset = 1; - if ( (clen= buf[0]) > 0 ) - { - if ( clen == 0xfd ) - { - clen = buf[1] | (buf[2] << 8); - offset += 2; - } - printf("nn_stripctrl: clen.%d offset.%d\n",clen,offset); - if ( clen > ctrlsize ) - { - printf("too much control data.%d vs %d, truncate\n",clen,(int32_t)sizeof(ctrl)); - memcpy(ctrl,&buf[offset],ctrlsize); - *clenp = ctrlsize; - errno = MSG_CTRUNC; - } - else - { - memcpy(ctrl,&buf[offset],clen); - *clenp = clen; - } - //printf("copied (%d).%d bytes of control from nbytes.%d\n",clen,offset-clen,(int32_t)nbytes); - } else *clenp = 0; - offset += clen; - return(offset); -} - -static bool nc_conn_ip_active(struct net_child_info *nci,const unsigned char *ip) -{ - unsigned int i; - for (i = 0; i < nci->conns->len; i++) - { - struct nc_conn *conn; - conn = parr_idx(nci->conns, i); - if (!memcmp(conn->peer.addr.ip, ip, 16)) - return true; - } - return false; -} - -static bool nc_conn_group_active(struct net_child_info *nci,const struct peer *peer) -{ - // FIXME - return false; - unsigned int group_len = peer->group_len; - unsigned int i; - for (i = 0; i < nci->conns->len; i++) - { - struct nc_conn *conn; - conn = parr_idx(nci->conns, i); - if ((group_len == conn->peer.group_len) && !memcmp(peer->group, conn->peer.group, group_len)) - return true; - } - return false; -} - -static struct nc_conn *nc_conn_new(const struct peer *peer) -{ - struct nc_conn *conn; - conn = calloc(1, sizeof(*conn)); - if (!conn) - return NULL; - conn->fd = -1; - peer_copy(&conn->peer, peer); - bn_address_str(conn->addr_str, sizeof(conn->addr_str), conn->peer.addr.ip); - return conn; -} - -static void nc_conn_kill(struct net_child_info *nci,struct nc_conn *conn) -{ - assert(conn->dead == false); - conn->dead = true; - event_base_loopbreak(conn->nci->eb); -} - -static void nc_conn_free(struct net_child_info *nci,struct nc_conn *conn) -{ - if (!conn) - return; - if (conn->write_q) - { - clist *tmp = conn->write_q; - while (tmp) - { - struct buffer *buf; - buf = tmp->data; - tmp = tmp->next; - free(buf->p); - free(buf); - } - clist_free(conn->write_q); - } - if (conn->ev) - { - event_del(conn->ev); - event_free(conn->ev); - } - if (conn->write_ev) - { - event_del(conn->write_ev); - event_free(conn->write_ev); - } - if (conn->fd >= 0) - close(conn->fd); - free(conn->msg.data); - memset(conn, 0, sizeof(*conn)); - free(conn); -} - -static bool nc_conn_start(struct net_child_info *nci,struct nc_conn *conn) -{ - char errpfx[64]; - /* create socket */ - printf("start connection.(%s)\n",conn->addr_str); - conn->ipv4 = is_ipv4_mapped(conn->peer.addr.ip); - conn->fd = socket(conn->ipv4 ? AF_INET : AF_INET6,SOCK_STREAM,IPPROTO_TCP); - if ( conn->fd < 0 ) - { - sprintf(errpfx, "socket %s", conn->addr_str); - perror(errpfx); - return false; - } - /* set non-blocking */ - int flags = fcntl(conn->fd,F_GETFL,0); - if ( (flags < 0) || (fcntl(conn->fd,F_SETFL,flags | O_NONBLOCK) < 0) ) - { - sprintf(errpfx, "socket fcntl %s", conn->addr_str); - perror(errpfx); - return false; - } - struct sockaddr *saddr; - struct sockaddr_in6 saddr6; - struct sockaddr_in saddr4; - socklen_t saddr_len; - /* fill out connect(2) address */ - if (conn->ipv4) - { - memset(&saddr4, 0, sizeof(saddr4)); - saddr4.sin_family = AF_INET; - memcpy(&saddr4.sin_addr.s_addr,&conn->peer.addr.ip[12],4); - saddr4.sin_port = htons(conn->peer.addr.port); - saddr = (struct sockaddr *) &saddr4; - saddr_len = sizeof(saddr4); - } - else - { - memset(&saddr6, 0, sizeof(saddr6)); - saddr6.sin6_family = AF_INET6; - memcpy(&saddr6.sin6_addr.s6_addr,&conn->peer.addr.ip[0], 16); - saddr6.sin6_port = htons(conn->peer.addr.port); - saddr = (struct sockaddr *) &saddr6; - saddr_len = sizeof(saddr6); - } - // initiate TCP connection - if ( connect(conn->fd,saddr,saddr_len) < 0 ) - { - if ( errno != EINPROGRESS ) - { - sprintf(errpfx, "socket connect %s", conn->addr_str); - perror(errpfx); - return false; - } - } - return true; -} - -static bool nc_conn_got_header(struct net_child_info *nci,struct nc_conn *conn) -{ - parse_message_hdr(&conn->msg.hdr, conn->hdrbuf); - unsigned int data_len = conn->msg.hdr.data_len; - if (data_len > (16 * 1024 * 1024)) - { - free(conn->msg.data); - conn->msg.data = NULL; - return false; - } - conn->msg.data = malloc(data_len); - /* switch to read-body state */ - conn->msg_p = conn->msg.data; - conn->expected = data_len; - conn->reading_hdr = false; - return true; -} - -static bool nc_conn_got_msg(struct net_child_info *nci,struct nc_conn *conn) -{ - if (!message_valid(&conn->msg)) { - fprintf(nci->plog, "llnet: %s invalid message\n",conn->addr_str); - return false; - } - if (!nc_conn_message(nci,conn)) - return false; - free(conn->msg.data); - conn->msg.data = NULL; - /* switch to read-header state */ - conn->msg_p = conn->hdrbuf; - conn->expected = P2P_HDR_SZ; - conn->reading_hdr = true; - return true; -} - -static void nc_conn_read_evt(int fd, short events, void *priv) -{ - struct nc_conn *conn = priv; - struct net_child_info *nci = conn->nci; - ssize_t rrc = read(fd, conn->msg_p, conn->expected); - if (rrc <= 0) - { - if (rrc < 0) - fprintf(nci->plog, "llnet: %s read: %s\n",conn->addr_str,strerror(errno)); - else fprintf(nci->plog, "llnet: %s read EOF\n", conn->addr_str); - goto err_out; - } - conn->msg_p += rrc; - conn->expected -= rrc; - /* execute our state machine at most twice */ - unsigned int i; - for (i = 0; i < 2; i++) - { - if (conn->expected == 0) - { - if (conn->reading_hdr) - { - if (!nc_conn_got_header(nci,conn)) - goto err_out; - } - else - { - if (!nc_conn_got_msg(nci,conn)) - goto err_out; - } - } - } - return; -err_out: - nc_conn_kill(nci,conn); -} - -static cstring *nc_version_build(struct net_child_info *nci) -{ - struct msg_version mv; - msg_version_init(&mv); - mv.nVersion = PROTO_VERSION; - mv.nServices = nci->blocks_fp != 0 ? NODE_NETWORK : 0; - mv.nTime = (int64_t)time(NULL); - mv.nonce = nci->instance_nonce; - sprintf(mv.strSubVer,"/nano/"); - mv.nStartingHeight = nci->db.best_chain ? nci->db.best_chain->height : 0; - cstring *rs = ser_msg_version(&mv); - msg_version_free(&mv); - return rs; -} - -static bool nc_conn_read_enable(struct net_child_info *nci,struct nc_conn *conn) -{ - if (conn->ev) - return true; - conn->ev = event_new(conn->nci->eb, conn->fd, EV_READ | EV_PERSIST,(void *)nc_conn_read_evt, conn); - if (!conn->ev) - return false; - if (event_add(conn->ev, NULL) != 0) - { - event_free(conn->ev); - conn->ev = NULL; - return false; - } - return true; -} - -static bool nc_conn_read_disable(struct net_child_info *nci,struct nc_conn *conn) -{ - if (!conn->ev) - return true; - event_del(conn->ev); - event_free(conn->ev); - conn->ev = NULL; - return true; -} - -static bool nc_conn_write_enable(struct net_child_info *nci,struct nc_conn *conn) -{ - if (conn->write_ev) - return true; - conn->write_ev = event_new(conn->nci->eb, conn->fd,EV_WRITE | EV_PERSIST,(void *)nc_conn_write_evt, conn); - if (!conn->write_ev) - return false; - if (event_add(conn->write_ev, NULL) != 0) - { - event_free(conn->write_ev); - conn->write_ev = NULL; - return false; - } - return true; -} - -static bool nc_conn_write_disable(struct net_child_info *nci,struct nc_conn *conn) -{ - if (!conn->write_ev) - return true; - event_del(conn->write_ev); - event_free(conn->write_ev); - conn->write_ev = NULL; - return true; -} - -static void nc_conn_evt_connected(int fd, short events, void *priv) -{ - struct nc_conn *conn = priv; - struct net_child_info *nci = conn->nci; - if ((events & EV_WRITE) == 0) { - fprintf(nci->plog, "net: %s connection timeout\n", conn->addr_str); - goto err_out; - } - int err = 0; - socklen_t len = sizeof(err); - /* check success of connect(2) */ - if ((getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) || (err != 0)) - { - fprintf(nci->plog, "net: connect %s failed: %s\n",conn->addr_str, strerror(err)); - goto err_out; - } - if (nci->debugging) - fprintf(nci->plog, "net: connected to %s\n", conn->addr_str); - conn->connected = true; - /* clear event used for watching connect(2) */ - event_free(conn->ev); - conn->ev = NULL; - /* build and send "version" message */ - cstring *msg_data = nc_version_build(nci); - bool rc = nc_conn_send(nci,conn, "version", msg_data->str, msg_data->len); - cstr_free(msg_data, true); - if (!rc) - { - fprintf(nci->plog, "net: %s !conn_send\n", conn->addr_str); - goto err_out; - } - /* switch to read-header state */ - conn->msg_p = conn->hdrbuf; - conn->expected = P2P_HDR_SZ; - conn->reading_hdr = true; - if (!nc_conn_read_enable(nci,conn)) - { - fprintf(nci->plog, "net: %s read not enabled\n", conn->addr_str); - goto err_out; - } - return; -err_out: - nc_conn_kill(nci,conn); -} - -static void nc_conns_gc(struct net_child_info *nci, bool free_all) -{ - clist *dead = NULL; - unsigned int n_gc = 0; - /* build list of dead connections */ - unsigned int i; - for (i = 0; i < nci->conns->len; i++) - { - struct nc_conn *conn = parr_idx(nci->conns, i); - if (free_all || conn->dead) - dead = clist_prepend(dead, conn); - } - /* remove and free dead connections */ - clist *tmp = dead; - while (tmp) - { - struct nc_conn *conn = tmp->data; - tmp = tmp->next; - - parr_remove(nci->conns, conn); - nc_conn_free(nci,conn); - n_gc++; - } - clist_free(dead); - if (nci->debugging) - fprintf(nci->plog, "net: gc'd %u connections\n", n_gc); -} - -static void nc_conns_open(struct net_child_info *nci) -{ - if (nci->debugging) - fprintf(nci->plog, "net: open connections (have %zu, want %zu more)\n",nci->conns->len,NC_MAX_CONN - nci->conns->len); - printf("nc_conns_open\n"); - while ((bp_hashtab_size(nci->peers->map_addr) > 0) && (nci->conns->len < NC_MAX_CONN)) - { - // delete peer from front of address list. it will be re-added before writing peer file, if successful - struct peer *peer = peerman_pop(nci->peers); - struct nc_conn *conn = nc_conn_new(peer); - conn->nci = nci; - peer_free(peer); - free(peer); - fprintf(stderr, "net: connecting to [%s]\n",conn->addr_str); - if (nc_conn_ip_active(nci, conn->peer.addr.ip)) // are we already connected to this IP? - { - fprintf(nci->plog, "net: already connected to %s\n",conn->addr_str); - goto err_loop; - } - if (nc_conn_group_active(nci, &conn->peer)) // are we already connected to this network group? - { - fprintf(nci->plog, "net: already grouped to %s\n",conn->addr_str); - goto err_loop; - } - if (!nc_conn_start(nci,conn)) // initiate non-blocking connect(2) - { - fprintf(nci->plog, "net: failed to start connection to %s\n",conn->addr_str); - goto err_loop; - } - // add to our list of monitored event sources - conn->ev = event_new(nci->eb, conn->fd, EV_WRITE,(void *)nc_conn_evt_connected, conn); - if ( !conn->ev ) - { - fprintf(nci->plog, "net: event_new failed on %s\n",conn->addr_str); - goto err_loop; - } - struct timeval timeout = { net_conn_timeout, }; - if (event_add(conn->ev, &timeout) != 0) - { - fprintf(nci->plog, "net: event_add failed on %s\n",conn->addr_str); - goto err_loop; - } - parr_add(nci->conns, conn); // add to our list of active connections - continue; - err_loop: - nc_conn_kill(nci,conn); - } -} - -static void nc_conns_process(struct net_child_info *nci) -{ - nc_conns_gc(nci, false); - nc_conns_open(nci); -} - -static bool parse_kvstr(const char *s, char **key, char **value) -{ - char *eql; - eql = strchr(s, '='); - if (eql) - { - uint32_t keylen = (uint32_t)((long)eql - (long)s); - *key = strndup(s, keylen); - *value = strdup(s + keylen + 1); - } - else - { - *key = strdup(s); - *value = strdup(""); - } - /* blank keys forbidden; blank values permitted */ - if (!strlen(*key)) - { - free(*key); - free(*value); - *key = NULL; - *value = NULL; - return false; - } - return true; -} - -static bool read_config_file(struct net_child_info *nci,const char *cfg_fn) -{ - FILE *cfg = fopen(cfg_fn, "r"); - if (!cfg) - return false; - bool rc = false; - char line[1024]; - while (fgets(line, sizeof(line), cfg) != NULL) - { - char *key, *value; - if (line[0] == '#') - continue; - while (line[0] && (isspace(line[strlen(line) - 1]))) - line[strlen(line) - 1] = 0; - if (!parse_kvstr(line, &key, &value)) - continue; - - bp_hashtab_put(nci->settings, key, value); - } - rc = ferror(cfg) == 0; - fclose(cfg); - return rc; -} - -static bool do_setting(struct net_child_info *nci,const char *arg) -{ - char *key, *value; - if (!parse_kvstr(arg, &key, &value)) - return false; - bp_hashtab_put(nci->settings, key, value); - // trigger special setting-specific behaviors - if (!strcmp(key, "debug")) - nci->debugging = true; - else if (!strcmp(key, "config") || !strcmp(key, "c")) - return read_config_file(nci,value); - return true; -} - -static bool preload_settings(struct net_child_info *nci) -{ - unsigned int i; - /* preload static settings */ - for (i = 0; i < ARRAY_SIZE(const_settings); i++) - if (!do_setting(nci,const_settings[i])) - return false; - return true; -} -/*unsigned int arg; - for (arg = 1; arg < argc; arg++) - { - const char *argstr = argv[arg]; - if ( do_setting(nci,argstr) == 0 ) - return 1; - }*/ -/* - * properly capture TERM and other signals - */ - -static void nc_conn_write_evt(int fd, short events, void *priv) -{ - struct nc_conn *conn = priv; - - struct iovec *iov = NULL; - unsigned int iov_len = 0; - struct net_child_info *nci = conn->nci; - /* build list of outgoing data buffers */ - nc_conn_build_iov(conn->write_q, conn->write_partial, &iov, &iov_len); - printf("send data to network\n"); - /* send data to network */ - ssize_t wrc = mywritev(conn->fd, iov, iov_len); - free(iov); - if (wrc < 0) - { - if (errno != EAGAIN && errno != EWOULDBLOCK) - goto err_out; - return; - } - /* handle partially and fully completed buffers */ - nc_conn_written(conn, wrc); - /* thaw read, if write fully drained */ - if (!conn->write_q) - { - nc_conn_write_disable(nci,conn); - nc_conn_read_enable(nci,conn); - } - return; -err_out: - nc_conn_kill(nci,conn); -} - -static void nc_conn_build_iov(clist *write_q, unsigned int partial,struct iovec **iov_, unsigned int *iov_len_) -{ - *iov_ = NULL; - *iov_len_ = 0; - unsigned int i, iov_len = (uint32_t)clist_length(write_q); - struct iovec *iov = calloc(iov_len, sizeof(struct iovec)); - clist *tmp = write_q; - i = 0; - while (tmp) - { - struct buffer *buf = tmp->data; - - iov[i].iov_base = buf->p; - iov[i].iov_len = buf->len; - if (i == 0) - { - iov[0].iov_base += partial; - iov[0].iov_len -= partial; - } - tmp = tmp->next; - i++; - } - *iov_ = iov; - *iov_len_ = iov_len; -} - -static void nc_conn_written(struct nc_conn *conn, size_t bytes) -{ - while (bytes > 0) - { - clist *tmp; - struct buffer *buf; - uint32_t left; - tmp = conn->write_q; - buf = tmp->data; - left = (uint32_t)(buf->len - conn->write_partial); - /* buffer fully written; free */ - if (bytes >= left) - { - free(buf->p); - free(buf); - conn->write_partial = 0; - conn->write_q = clist_delete(tmp, tmp); - bytes -= left; - } - /* buffer partially written; store state */ - else - { - conn->write_partial += bytes; - break; - } - } -} - -ssize_t mywritev(int fildes, const struct iovec *iov, int iovcnt) -{ - int i; - int32_t bytes_written = 0; - for (i = 0; i < iovcnt; i++) - { - int len = (int32_t)send(fildes,iov[i].iov_base,iov[i].iov_len,0); - if (len < 0) - { - //DWORD err = GetLastError(); - //errno = ewin_to_posix_error(err); - bytes_written = -1; - break; - } - bytes_written += len; - } - return bytes_written; -} - -static bool nc_msg_version(struct net_child_info *nci,struct nc_conn *conn) -{ - if (conn->seen_version) - return false; - conn->seen_version = true; - struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len }; - struct msg_version mv; - bool rc = false; - msg_version_init(&mv); - if (!deser_msg_version(&mv, &buf)) - goto out; - if (nci->debugging) - { - char fromstr[64], tostr[64]; - bn_address_str(fromstr, sizeof(fromstr), mv.addrFrom.ip); - bn_address_str(tostr, sizeof(tostr), mv.addrTo.ip); - fprintf(nci->plog, "net: %s version(%u, 0x%llx, %lld, To:%s, From:%s, %s, %u)\n", - conn->addr_str, - mv.nVersion, - (unsigned long long) mv.nServices, - (long long) mv.nTime, - tostr, - fromstr, - mv.strSubVer, - mv.nStartingHeight); - } - if (!(mv.nServices & NODE_NETWORK)) /* require NODE_NETWORK */ - goto out; - if (mv.nonce == nci->instance_nonce) /* connected to ourselves? */ - goto out; - conn->protover = (mv.nVersion < PROTO_VERSION) ? mv.nVersion : PROTO_VERSION; - /* acknowledge version receipt */ - if (!nc_conn_send(nci,conn, "verack", NULL, 0)) - goto out; - rc = true; - out: - msg_version_free(&mv); - return rc; -} - -static bool nc_conn_send(struct net_child_info *nci,struct nc_conn *conn, const char *command,const void *data, size_t data_len) -{ - /* build wire message */ - cstring *msg = message_str(nci->chain->netmagic, command, data, (uint32_t)data_len); - if (!msg) - return false; - /* buffer now owns message data */ - struct buffer *buf = calloc(1, sizeof(struct buffer)); - buf->p = msg->str; - buf->len = msg->len; - cstr_free(msg, false); - /* if write q exists, write_evt will handle output */ - if (conn->write_q) - { - conn->write_q = clist_append(conn->write_q, buf); - return true; - } - /* attempt optimistic write */ - ssize_t wrc = write(conn->fd, buf->p, buf->len); - if (wrc < 0) - { - if (errno != EAGAIN && errno != EWOULDBLOCK) - { - free(buf->p); - free(buf); - return false; - } - conn->write_q = clist_append(conn->write_q, buf); - goto out_wrstart; - } - /* message fully sent */ - if (wrc == buf->len) - { - free(buf->p); - free(buf); - return true; - } - /* message partially sent; pause read; poll for writable */ - conn->write_q = clist_append(conn->write_q, buf); - conn->write_partial = (uint32_t)wrc; -out_wrstart: - nc_conn_read_disable(nci,conn); - nc_conn_write_enable(nci,conn); - return true; -} - - -static void init_daemon(struct net_child_info *nci,char *coin) -{ - strcpy(nci->coin,coin); - //init_log(nci); - //init_blkdb(nci); - //printf("utxo\n"); - //bp_utxo_set_init(&nci->uset); - //printf("init_blocks\n"); - //init_blocks(nci); - //printf("init_orphans\n"); - init_orphans(nci); - //readprep_blocks_file(nci); - init_nci(nci); -} - -int32_t iguana_verack(struct net_child_info *nci,struct bp_address *addr) -{ - struct msg_getblocks gb; int32_t rc,numsent; time_t now,cutoff; cstring *s,*msg; - if ( addr->seen_verack ) - { - printf("addr->seen_verack %d\n",addr->seen_verack); - return(-1); - } - addr->seen_verack = 1; - addr->nTime = (uint32_t)time(NULL); - addr->n_ok++; - //peerman_add(conn->nci->peers, &conn->peer,true); - if ( addr->protover >= CADDR_TIME_VERSION ) - { - msg = message_str(nci->chain->netmagic,"getaddr",NULL,0); - if ( (numsent= (int32_t)send(addr->usock,msg->str,msg->len,0)) != msg->len ) - { - cstr_free(msg,true); - return -1; - } - cstr_free(msg,true); - } else printf("protover.%d vs %d CADDR_TIME_VERSION\n",addr->protover,CADDR_TIME_VERSION); - rc = 0; - now = time(NULL); - cutoff = now - (24 * 60 * 60); - if ( nci->last_getblocks < cutoff ) - { - msg_getblocks_init(&gb); - blkdb_locator(&nci->db,NULL,&gb.locator); - s = ser_msg_getblocks(&gb); - oldsend_getblocks(nci); - msg = message_str(nci->chain->netmagic,"getblocks",s->str,(uint32_t)s->len); - cstr_free(s,true); - msg_getblocks_free(&gb); - nci->last_getblocks = now; - } - return(rc); -} - - -static void init_peers(struct net_child_info *nci) -{ - struct peer_manager *peers = 0; - peers = peerman_read(setting(nci,"peers")); - printf("init_peers.%p\n",peers); - if (!peers) - { - PostMessage( "net: initializing empty peer list\n"); - peers = peerman_seed(nci->chain->default_port,1,1);//setting(nci,"dns") != 0 ? true : false,nci->debugging); - if ( !peerman_write(nci->chain,peers,setting(nci,"peers"),nci->debugging) ) - { - PostMessage( "net: failed to write peer list\n"); - exit(1); - } - } - char *addnode = setting(nci,"addnode"); - if (addnode) - peerman_addstr(nci->chain->default_port,peers,addnode,nci->debugging); - peerman_sort(peers); - if (nci->debugging) - PostMessage( "net: have %u/%zu peers\n",bp_hashtab_size(peers->map_addr),clist_length(peers->addrlist)); - nci->peers = peers; -} - -static void init_nci(struct net_child_info *nci) -{ - nci->read_fd = -1; - nci->write_fd = -1; - //nci->blocks_fd = -1; - //init_peers(nci); - nci->conns = parr_new(NC_MAX_CONN, NULL); - //nci->eb = event_base_new(); - nci->daemon_running = true; -} - -void oldsend_getblocks(struct net_child_info *nci) -{ - struct msg_getblocks gb; - msg_getblocks_init(&gb); - blkdb_locator(&nci->db, NULL, &gb.locator); - cstring *s = ser_msg_getblocks(&gb); - printf("oldsend_getblocks\n"); - nc_conn_send(nci,0, "getblocks", s->str, s->len); - cstr_free(s, true); - msg_getblocks_free(&gb); -} - - -static bool nc_msg_inv(struct net_child_info *nci,struct nc_conn *conn) -{ - struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len }; - struct msg_vinv mv, mv_out; - bool rc = false; - msg_vinv_init(&mv); - msg_vinv_init(&mv_out); - if (!deser_msg_vinv(&mv, &buf)) - goto out; - if (nci->debugging && mv.invs && mv.invs->len == 1) - { - struct bp_inv *inv = parr_idx(mv.invs, 0); - char hexstr[BU256_STRSZ]; - bu256_hex(hexstr, &inv->hash); - char typestr[32]; - switch (inv->type) - { - case MSG_TX: strcpy(typestr, "tx"); break; - case MSG_BLOCK: strcpy(typestr, "block"); break; - default: sprintf(typestr, "unknown 0x%x", inv->type); break; - } - PostMessage( "net: %s inv %s %s\n",conn->addr_str, typestr, hexstr); - } - else if (nci->debugging && mv.invs) - PostMessage( "net: %s inv (%zu sz)\n",conn->addr_str, mv.invs->len); - if (!mv.invs || !mv.invs->len) - goto out_ok; - /* scan incoming inv's for interesting material */ - unsigned int i; - for (i = 0; i < mv.invs->len; i++) - { - struct bp_inv *inv = parr_idx(mv.invs, i); - switch (inv->type) - { - case MSG_BLOCK: - if (!blkdb_lookup(&nci->db, &inv->hash) && !have_orphan(nci,&inv->hash)) - msg_vinv_push(&mv_out, MSG_BLOCK, &inv->hash); - break; - case MSG_TX: - default: - break; - } - } - /* send getdata, if they have anything we want */ - if (mv_out.invs && mv_out.invs->len) - { - cstring *s = ser_msg_vinv(&mv_out); - rc = nc_conn_send(nci,conn, "getdata", s->str, s->len); - cstr_free(s, true); - } -out_ok: - rc = true; - out: - msg_vinv_free(&mv); - msg_vinv_free(&mv_out); - return rc; -} - -ssize_t fwritev(FILE *fp,const struct iovec *iov,int iovcnt) -{ - int i; int32_t bytes_written = 0; - fprintf(stderr,"fwritev.%d from %ld: ",iovcnt,(long)ftell(fp)); - for (i = 0; i < iovcnt; i++) - { - int len = (int32_t)fwrite(iov[i].iov_base,1,iov[i].iov_len,fp); - if ( len != iov[i].iov_len ) - { - printf("len.%d != %d iov[i].iov_len\n",len,(int32_t)iov[i].iov_len); - //DWORD err = GetLastError(); - //errno = ewin_to_posix_error(err); - bytes_written = -1; - break; - } - bytes_written += len; - } - fprintf(stderr,"%d bytes\n",bytes_written); - return bytes_written; -} - -static bool nc_msg_verack(struct net_child_info *nci,struct nc_conn *conn) -{ - if (conn->seen_verack) - return false; - conn->seen_verack = true; - if (nci->debugging) - PostMessage( "net: %s verack\n",conn->addr_str); - /* - * When a connection attempt is made, the peer is deleted - * from the peer list. When we successfully connect, - * the peer is re-added. Thus, peers are immediately - * forgotten if they fail, on the first try. - */ - conn->peer.last_ok = time(NULL); - conn->peer.n_ok++; - conn->peer.addr.nTime = (uint32_t) conn->peer.last_ok; - peerman_add(conn->nci->peers, &conn->peer, true); - /* request peer addresses */ - if ((conn->protover >= CADDR_TIME_VERSION) && (!nc_conn_send(nci,conn, "getaddr", NULL, 0))) - return false; - /* request blocks */ - bool rc = true; - time_t now = time(NULL); - time_t cutoff = now - (24 * 60 * 60); - if (conn->nci->last_getblocks < cutoff) - { - struct msg_getblocks gb; - msg_getblocks_init(&gb); - blkdb_locator(&nci->db, NULL, &gb.locator); - cstring *s = ser_msg_getblocks(&gb); - rc = nc_conn_send(nci,conn, "getblocks", s->str, s->len); - cstr_free(s, true); - msg_getblocks_free(&gb); - conn->nci->last_getblocks = now; - } - return rc; -} -static bool nc_conn_send(struct net_child_info *nci,struct nc_conn *conn, const char *command,const void *data, size_t data_len) -{ - int32_t i; - cstring *msg = message_str(nci->chain->netmagic, command, data, (uint32_t)data_len); - for (i=0; ilen; i++) - printf("%02x ",msg->str[i] & 0xff); - printf("nc_conn_send cmd.(%s) len.%d\n",command,(int32_t)msg->len); - return(0); -} - -static bool nc_msg_addr(struct net_child_info *nci,struct nc_conn *conn) -{ - struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len }; - struct msg_addr ma; - bool rc = false; - msg_addr_init(&ma); - if (!deser_msg_addr(conn->protover, &ma, &buf)) - goto out; - unsigned int i; - time_t cutoff = time(NULL) - (7 * 24 * 60 * 60); - if (nci->debugging) - { - unsigned int old = 0; - for (i = 0; i < ma.addrs->len; i++) - { - struct bp_address *addr = parr_idx(ma.addrs, i); - if (addr->nTime < cutoff) - old++; - } - PostMessage( "net: %s addr(%zu addresses, %u old)\n",conn->addr_str, ma.addrs->len, old); - } - /* ignore ancient addresses */ - if (conn->protover < CADDR_TIME_VERSION) - goto out_ok; - /* feed addresses to peer manager */ - for (i = 0; i < ma.addrs->len; i++) { - struct bp_address *addr = parr_idx(ma.addrs, i); - if (addr->nTime > cutoff) - peerman_add_addr(conn->nci->peers, addr, false); - } -out_ok: - rc = true; - out: - msg_addr_free(&ma); - return rc; -} -/*libevent stubs - #define EV_READ 1 - #define EV_WRITE 2 - #define EV_PERSIST 4 - struct event *event_new(struct event_base *evbase,int32_t fd,int32_t flags,void *funcp,void *conn) { return(0); } - void event_base_loopbreak(struct event_base *evbase) {} - void event_base_dispatch(struct event_base *evbase) {} - void event_base_free(struct event_base *evbase) {} - - struct event_base *event_base_new() { return(0); } - void event_del(struct event *ev) {} - void event_free(struct event *ev) {} - int32_t event_add(struct event *ev,struct timeval *tval) { return(-1); } - // end stubs */ - -enum { NC_MAX_CONN = 8, }; - -//static unsigned int net_conn_timeout = 11; -/* - static void nc_conn_kill(struct net_child_info *nci,struct nc_conn *conn); - static bool nc_conn_read_enable(struct net_child_info *nci,struct nc_conn *conn); - static bool nc_conn_read_disable(struct net_child_info *nci,struct nc_conn *conn); - static bool nc_conn_write_enable(struct net_child_info *nci,struct nc_conn *conn); - static bool nc_conn_write_disable(struct net_child_info *nci,struct nc_conn *conn);*/ - -static bool nc_conn_message(struct net_child_info *nci,struct nc_conn *conn) -{ - char *command = conn->msg.hdr.command; - /* verify correct network */ - printf("got message.(%s)\n",command); - if (memcmp(conn->msg.hdr.netmagic, nci->chain->netmagic, 4)) - { - PostMessage( "net: %s invalid network\n",conn->addr_str); - return false; - } - /* incoming message: version */ - //if ( !strncmp(command,"version",12) ) - // return nc_msg_version(nci,conn); - /* "version" must be first message */ - if (!conn->seen_version) - { - PostMessage( "net: %s 'version' not first\n",conn->addr_str); - return false; - } - /* incoming message: verack */ - if (!strncmp(command,"verack",12)) - return nc_msg_verack(nci,conn); - /* "verack" must be second message */ - if (!conn->seen_verack) - { - PostMessage( "net: %s 'verack' not second\n",conn->addr_str); - return false; - } - /* incoming message: addr */ - if (!strncmp(command, "addr", 12)) - return nc_msg_addr(nci,conn); - /* incoming message: inv */ - else if (!strncmp(command, "inv", 12)) - return nc_msg_inv(nci,conn); - /* incoming message: block */ - else if (!strncmp(command, "block", 12)) - return nc_msg_block(nci,conn); - if (nci->debugging) - PostMessage( "net: %s unknown message %s\n",conn->addr_str,command); - /* ignore unknown messages */ - return true; -} - -static void init_log(struct net_child_info *nci) -{ - char *log_fn = setting(nci,"log"); - if (!log_fn || !strcmp(log_fn, "-")) - nci->plog = stdout; - else { - nci->plog = fopen(log_fn, "a"); - if (!nci->plog) { - perror(log_fn); - exit(1); - } - } - setvbuf(nci->plog, NULL, _IONBF, BUFSIZ); -} - -static void init_blkdb(struct net_child_info *nci) -{ - if (!blkdb_init(&nci->db, nci->chain->netmagic, &nci->chain_genesis)) - { - PostMessage( "blkdb init failed\n"); - exit(1); - } - - char *blkdb_fn = 0;//setting(nci,"blkdb"); - if (!blkdb_fn) - return; - if ((access(blkdb_fn, F_OK) == 0) && !blkdb_read(nci->chain->hastimestamp,&nci->db, blkdb_fn)) - { - PostMessage( "blkdb read failed\n"); - exit(1); - } - if ( (nci->db.fp= fopen(blkdb_fn,"rb+")) == 0 ) - nci->db.fp= fopen(blkdb_fn,"wb+"); - if ( nci->db.fp == 0 ) - { - PostMessage( "blkdb file open failed: %s\n", strerror(errno)); - exit(1); - } - //nci->db.fd = open(blkdb_fn,O_WRONLY | O_APPEND | O_CREAT | O_LARGEFILE, 0666); - //if (nci->db.fd < 0) { - // PostMessage( "blkdb file open failed: %s\n", strerror(errno)); - // exit(1); - //} -} - -static void init_blocks(struct net_child_info *nci) -{ - char blocks_fn[512]; - sprintf(blocks_fn,"%s.blocks",nci->coin); - if ( (nci->blocks_fp= fopen(blocks_fn,"rb+")) == 0 )// O_RDWR | O_CREAT | O_LARGEFILE, 0666); - nci->blocks_fp = fopen(blocks_fn,"wb+"); - if ( nci->blocks_fp == 0 ) - { - PostMessage( "blocks file open failed: %s\n", strerror(errno)); - exit(1); - } - fseek(nci->blocks_fp,0,SEEK_END); - off64_t flen = ftell(nci->blocks_fp); - printf("opened.(%s) flen.%llu\n",blocks_fn,(long long)flen); - if ( flen == (off64_t)-1 ) - { - PostMessage( "blocks file lseek64 failed: %s\n", strerror(errno)); - exit(1); - } - if ( flen == 0 ) - init_block0(nci); -} - -static void shutdown_daemon(struct net_child_info *nci) -{ - if ( nci->blocks_fp != 0 ) - fclose(nci->blocks_fp); - bool rc = peerman_write(nci->chain,nci->peers,setting(nci,"peers"),nci->debugging); - PostMessage( "net: %s %u/%zu peers\n",rc ? "wrote" : "failed to write",bp_hashtab_size(nci->peers->map_addr),clist_length(nci->peers->addrlist)); - if ( nci->plog != stdout && nci->plog != stderr ) - { - fclose(nci->plog); - nci->plog = NULL; - } - if ( setting(nci,"free") ) - { - shutdown_nci(nci); - bp_hashtab_unref(nci->orphans); - bp_hashtab_unref(nci->settings); - blkdb_free(&nci->db); - bp_utxo_set_free(&nci->uset); - } -} - - -static bool nc_msg_block(struct net_child_info *nci,struct nc_conn *conn) -{ - struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len }; - struct iovec iov[2]; char hexstr[BU256_STRSZ]; struct bp_block block; bool rc = false; - bp_block_init(&block); - if ( !deser_bp_block(nci->chain->hastimestamp,&block,&buf) ) - goto out; - bp_block_calc_sha256(&block); - bu256_hex(hexstr,&block.sha256); - if ( nci->debugging ) - PostMessage("net: %s block %s\n",conn->addr_str,hexstr); - if ( !bp_block_valid(&block) ) - { - PostMessage("net: %s invalid block %s\n",conn->addr_str,hexstr); - goto out; - } - if ( blkdb_lookup(&nci->db,&block.sha256) || have_orphan(nci,&block.sha256) ) - goto out_ok; - iov[0].iov_base = &conn->msg.hdr; - iov[0].iov_len = sizeof(conn->msg.hdr); - iov[1].iov_base = (void *)buf.p; - iov[1].iov_len = conn->msg.hdr.data_len; - printf("hdr.%d len.%d\n",(int32_t)sizeof(conn->msg.hdr),(int32_t)buf.len); - size_t total_write = iov[0].iov_len + iov[1].iov_len; - //off64_t fpos64 = lseek64(nci->blocks_fd, 0, SEEK_CUR); - //fseek(nci->blocks_fp, 0, SEEK_CUR); - off64_t fpos64 = ftell(nci->blocks_fp); - if ( fpos64 == (off64_t)-1 ) - { - PostMessage( "blocks: lseek64 failed %s\n", - strerror(errno)); - goto out; - } - //errno = 0; - ssize_t bwritten = fwritev(nci->blocks_fp,iov,ARRAY_SIZE(iov)); - if ( bwritten != total_write ) - { - PostMessage( "blocks: write failed %s\n",strerror(errno)); - goto out; - } - if ( !process_block(nci,&block,fpos64) ) - { - PostMessage( "blocks: process-block failed\n"); - goto out; - } -out_ok: - rc = true; - out: - bp_block_free(&block); - return rc; -} - -static bool spend_tx(bool script_verf,struct bp_utxo_set *uset, const struct bp_tx *tx,unsigned int tx_idx, unsigned int height) -{ - bool is_coinbase = (tx_idx == 0); - struct bp_utxo *coin; - int64_t total_in = 0, total_out = 0; - unsigned int i; - /* verify and spend this transaction's inputs */ - if (!is_coinbase) - { - for (i = 0; i < tx->vin->len; i++) - { - struct bp_txin *txin; - struct bp_txout *txout; - txin = parr_idx(tx->vin, i); - coin = bp_utxo_lookup(uset, &txin->prevout.hash); - if (!coin || !coin->vout) - return false; - if (coin->is_coinbase && ((coin->height + COINBASE_MATURITY) > height)) - return false; - txout = NULL; - if (txin->prevout.n >= coin->vout->len) - return false; - txout = parr_idx(coin->vout, txin->prevout.n); - total_in += txout->nValue; - if (script_verf && !bp_verify_sig(coin, tx, i, /* SCRIPT_VERIFY_P2SH */ 0, 0)) - return false; - if (!bp_utxo_spend(uset, &txin->prevout)) - return false; - } - } - for (i = 0; i < tx->vout->len; i++) - { - struct bp_txout *txout; - txout = parr_idx(tx->vout, i); - total_out += txout->nValue; - } - if (!is_coinbase) - { - if (total_out > total_in) - return false; - } - /* copy-and-convert a tx into a UTXO */ - coin = calloc(1, sizeof(*coin)); - bp_utxo_init(coin); - if (!bp_utxo_from_tx(coin, tx, is_coinbase, height)) - return false; - /* add unspent outputs to set */ - bp_utxo_set_add(uset, coin); - return true; -} - -static bool spend_block(struct net_child_info *nci,const struct bp_block *block,unsigned int height) -{ - struct bp_tx *tx; - unsigned int i; - for (i = 0; i < block->vtx->len; i++) - { - tx = parr_idx(block->vtx, i); - if (!spend_tx(nci->script_verf,&nci->uset, tx, i, height)) - { - char hexstr[BU256_STRSZ]; - bu256_hex(hexstr, &tx->sha256); - PostMessage( "brd: spent_block tx fail %s\n", hexstr); - return false; - } - } - return true; -} - -static bool process_block(struct net_child_info *nci,const struct bp_block *block,int64_t fpos) -{ - struct blkdb_reorg reorg; struct blkinfo *bi = bi_new(); - fprintf(stderr,"process_block sha256 %llx\n",*(long long *)&block->sha256); - bu256_copy(&bi->hash, &block->sha256); - bp_block_copy_hdr(&bi->hdr, block); - bi->n_file = 0; - bi->n_pos = fpos; - if ( blkdb_add(&nci->db,bi,&reorg) == 0 ) - { - PostMessage( "brd: blkdb add fail fpos.%ld\n",(long)fpos); - goto err_out; - } - /* FIXME: support reorg */ - assert(reorg.conn == 1); - assert(reorg.disconn == 0); - if ( bu256_equal(&nci->db.best_chain->hash,&bi->hdr.sha256) ) // if best chain, mark TX's as spent - { - if ( spend_block(nci,block,bi->height) == 0 ) - { - char hexstr[BU256_STRSZ]; - bu256_hex(hexstr, &bi->hdr.sha256); - PostMessage("brd: block spend fail %u %s\n",bi->height, hexstr); - // FIXME: bad record is now in blkdb - goto err_out; - } - } - return true; -err_out: - bi_free(bi); - return false; -} - -static bool read_block_msg(struct net_child_info *nci,struct p2p_message *msg, int64_t fpos) -{ - struct const_buffer buf = { msg->data, msg->hdr.data_len }; - struct bp_block block; bool rc = false; - // unknown records are invalid - printf("read_block_msg\n"); - if ( strncmp(msg->hdr.command,"block",sizeof(msg->hdr.command)) ) - { - printf("invalid cmd.(%s) != block\n",msg->hdr.command); - return false; - } - bp_block_init(&block); - if ( deser_bp_block(nci->chain->hastimestamp,&block,&buf) == 0 ) - { - PostMessage( "brd: block deser fail\n"); - goto out; - } - bp_block_calc_sha256(&block); - if (!bp_block_valid(&block)) - { - PostMessage( "brd: block not valid\n"); - goto out; - } - printf("call process_block\n"); - rc = process_block(nci,&block,fpos); - out: - bp_block_free(&block); - return rc; -} - -static void read_blocks(struct net_child_info *nci) -{ - //int fd = nci->blocks_fd; - int32_t n = 0; FILE *fp = nci->blocks_fp; - struct p2p_message msg = {}; - bool read_ok = true; - int64_t fpos = 0; - printf("read_blocks from pos %ld\n",(long)ftell(fp)); - while ( fread_message(fp,&msg,&read_ok) ) - { - printf("iter.%d netmagic.%x\n",n++,*(int32_t *)nci->chain->netmagic); - if ( memcmp(msg.hdr.netmagic,nci->chain->netmagic,4) ) - { - PostMessage("blocks file: invalid network magic\n"); - exit(1); - } - //strcpy(msg.hdr.command,"block"); - if ( !read_block_msg(nci,&msg,fpos) ) - exit(1); - fpos += P2P_HDR_SZ; - fpos += msg.hdr.data_len; - fpos = ftell(fp); - } - printf("read_blocks finished loop\n"); - if ( !read_ok ) - { - PostMessage("blocks file: read failed\n"); - exit(1); - } - free(msg.data); -} - -static void readprep_blocks_file(struct net_child_info *nci) -{ - // if no blk index, but blocks are present, read and index all block data (several gigabytes) - if ( nci->blocks_fp != 0 ) - { - rewind(nci->blocks_fp); - if ( nci->db.fp == 0 ) - read_blocks(nci); - else - { - printf("seek to end\n"); - // TODO: verify that blocks file offsets are present in blkdb - //if ( lseek(nci->blocks_fd, 0, SEEK_END) == (off_t)-1 ) - if ( fseek(nci->blocks_fp,0,SEEK_END) == (off_t)-1 ) - { - PostMessage( "blocks file: seek failed: %s\n",strerror(errno)); - exit(1); - } - } - } -} - -static void init_orphans(struct net_child_info *nci) -{ - nci->orphans = bp_hashtab_new_ext(bu256_hash, bu256_equal_,(bp_freefunc) bu256_free, (bp_freefunc) buffer_free); -} - -static bool have_orphan(struct net_child_info *nci,const bu256_t *v) -{ - return bp_hashtab_get(nci->orphans, v); -} - -bool add_orphan(struct net_child_info *nci,const bu256_t *hash_in, struct const_buffer *buf_in) -{ - if (have_orphan(nci,hash_in)) - return false; - bu256_t *hash = bu256_new(hash_in); - if (!hash) { - PostMessage( "OOM\n"); - return false; - } - struct buffer *buf = buffer_copy(buf_in->p, buf_in->len); - if (!buf) { - bu256_free(hash); - PostMessage( "OOM\n"); - return false; - } - bp_hashtab_put(nci->orphans, hash, buf); - return true; -} - -struct nc_conn -{ - bool dead; - int fd; - struct peer peer; - char addr_str[64]; - bool ipv4; - bool connected; - struct event *ev; - struct net_child_info *nci; - struct event *write_ev; - clist *write_q; /* of struct buffer */ - unsigned int write_partial; - struct p2p_message msg; - void *msg_p; - unsigned int expected; - bool reading_hdr; - unsigned char hdrbuf[P2P_HDR_SZ]; - bool seen_version; - bool seen_verack; - uint32_t protover; -}; - -static bool process_block(struct net_child_info *nci,const struct bp_block *block, int64_t fpos); -static bool have_orphan(struct net_child_info *nci,const bu256_t *v); -static bool add_orphan(struct net_child_info *nci,const bu256_t *hash_in, struct const_buffer *buf_in); - -/*struct bp_hashtab *settings; - //const struct chain_info *chain = NULL; - bu256_t chain_genesis; - uint64_t instance_nonce; - bool debugging = false; - FILE *plog = NULL; - - static const char *const_settings[] = - { - "net.connect.timeout=11", - "addnode=127.0.0.1", - "peers=brd.peers", - "dns=1", - //"blkdb=brd.blkdb", - "blocks=brd.blocks", - //"log=brd.log", - };*/ - -static void init_block0(struct net_child_info *nci) -{ - if ( nci->blocks_fp != 0 ) - { - cstring *msg0 = message_str(nci->chain->netmagic,"block",nci->chain->genesis_hashdata,(int32_t)sizeof(nci->chain->genesis_hashdata)); - ssize_t bwritten = fwrite(msg0->str,1,msg0->len,nci->blocks_fp); - if ( bwritten != msg0->len ) - { - PostMessage( "blocks write0 failed: %s\n", strerror(errno)); - exit(1); - } - cstr_free(msg0,true); - off64_t fpos64 = ftell(nci->blocks_fp); - if ( fpos64 == (off64_t)-1 ) - { - PostMessage( "blocks lseek0 failed: %s\n", strerror(errno)); - exit(1); - } - PostMessage("blocks: genesis block written\n"); - } -} - -static void shutdown_nci(struct net_child_info *nci) -{ - peerman_free(nci->peers); - //nc_conns_gc(nci, true); - assert(nci->conns->len == 0); - //parr_free(nci->conns, true); - //event_base_free(nci->eb); -}int32_t iguana_send(struct iguana_info *coin,void *_conn,uint8_t *serialized,char *cmd,int32_t len) -{ - return(nc_conn_send(coin,_conn,cmd,&serialized[sizeof(struct iguana_msghdr)],len)); - int32_t numsent; struct nc_conn *conn = _conn; - len = iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len); - if ( (numsent= (int32_t)send(conn->addr.usock,serialized,len,0)) < 0 ) - { - printf("%s: numsent.%d vs len.%d errno.%d usock.%d\n",cmd,numsent,len,errno,conn->addr.usock); - if (errno != EAGAIN && errno != EWOULDBLOCK) - { - printf("bad errno.%d\n",errno); - return(-errno); - } - if ( 0 ) - { - /*struct buffer *buf = calloc(1, sizeof(struct buffer)); - buf->p = malloc(len), memcpy(buf->p,serialized,len); - buf->len = len; - conn->write_q = clist_append(conn->write_q,buf); - nc_conn_read_disable(coin,conn); - nc_conn_write_enable(coin,conn);*/ - } - } - else if ( numsent < len ) - { - if ( 0 ) - { - /*conn->write_q = clist_append(conn->write_q, buf); - conn->write_partial = (uint32_t)numsent; - buf->p = malloc(len), memcpy(buf->p,serialized,len); - buf->len = len; - conn->write_q = clist_append(conn->write_q,buf); - nc_conn_read_disable(coin,conn); - nc_conn_write_enable(coin,conn);*/ - } - //int32_t i; - //for (i=0; i 0 && bestheight > oldbestheight ) -{ - prevhash = iguana_prevblockhash(blocks,new_best); - if ( (prev= iguana_findblock(&space,blocks,prevhash)) != 0 && prev->height > 0 ) - { - new_best = prevhash; - bestheight = prev->height; - reorg_info->conn++; - printf("connect.%d: newbest.%s oldheight.%d newheight.%d\n",reorg_info->conn,bits256_str(new_best),oldbestheight,bestheight); - } else break; -} -// unlikely case: old best chain has greater height -while ( oldbestheight > 0 && bestheight > 0 && oldbestheight > bestheight ) -{ - old_best = iguana_prevblockhash(blocks,old_best); - if ( (prev= iguana_findblock(&space,blocks,prevhash)) != 0 && prev->height > 0 ) - { - oldbestheight = prev->height; - reorg_info->disconn++; - printf("unlikely case: disconn.%d %s\n",reorg_info->disconn,bits256_str(old_best)); - } else break; -} -// height matches, but we are still walking parallel chains -while ( oldbestheight > 0 && bestheight > 0 && memcmp(old_best.bytes,new_best.bytes,sizeof(old_best)) != 0 ) -{ - new_best = iguana_prevblockhash(blocks,new_best); - bestheight = iguana_height(blocks,new_best); - reorg_info->conn++; - old_best = iguana_prevblockhash(blocks,old_best); - oldbestheight = iguana_height(blocks,old_best); - reorg_info->disconn++; - printf("parallel case\n"); -} - -/*bits256 iguana_PoW(struct iguana_info *coin,int32_t height) - { - int32_t h; bits256 sum; struct iguana_block *ptr,space; - if ( height > 0 ) - { - h = (height / 1000); - sum = coin->blocks.PoW[h]; - h *= 1000; - while ( ++h <= height ) - { - if ( (ptr= iguana_block(&space,coin,h)) != 0 ) - sum = bits256_add(sum,bits256_from_compact(ptr->bits)); - else - { - printf("error getting block[%u]\n",h); - break; - } - } - } - else - { - iguana_block(&space,coin,0); - sum = bits256_from_compact(space.bits); - } - return(sum); - }*/ -/*BIGNUM cur_work,test; bits256 x,sum; char ystr[512],xstr[512]; - BN_init(&cur_work); - BN_init(&test); - u256_from_compact(&cur_work,0x1d00ffff); - PoW_str(ystr,sizeof(ystr),&cur_work); - printf("y.(%s) ",ystr); - BN_add(&test,&cur_work,&cur_work); - PoW_str(ystr,sizeof(ystr),&test); - printf("sum.(%s) ",ystr); - PoW_conv(&test,0x1d00ffff); - PoW_str(xstr,sizeof(xstr),&test); - x = bits256_from_compact(0x1d00ffff); - sum = bits256_add(x,x); - printf("xstr.(%s) x.(%s) sum.(%s)\n",xstr,bits256_str(x),bits256_lstr(sum)); - getchar();*/ -void u256_from_compact(BIGNUM *vo,uint32_t c); - -int32_t PoW_conv(BIGNUM *PoW,uint32_t nBits) -{ - BN_init(PoW); - u256_from_compact(PoW,nBits); - return(0); -} - -int32_t PoW_add(BIGNUM *sum,BIGNUM *a,BIGNUM *b) -{ - if ( BN_add(sum,a,b) == 0 ) - return(-1); - return(0); -} - -void PoW_free(BIGNUM *a) { BN_clear_free(a); } - -int32_t PoW_cmp(BIGNUM *test,BIGNUM *hwm) { return(BN_cmp(test,hwm)); } -void PoW_str(char *str,int32_t maxlen,BIGNUM *v); - -/*static void nc_conns_gc(struct parr *conns,bool free_all) - { - struct nc_conn *conn; clist *dead = NULL; uint32_t i,n_gc = 0; - // build list of dead connections - for (i=0; ilen; i++) - { - conn = parr_idx(conns,i); - if ( free_all || conn->dead ) - dead = clist_prepend(dead,conn); - } - // remove and free dead connections - clist *tmp = dead; - while ( tmp ) - { - struct nc_conn *conn = tmp->data; - tmp = tmp->next; - parr_remove(conns,conn); - nc_conn_free(conn); - n_gc++; - } - clist_free(dead); - fprintf(stderr,"net: gc'd %u connections\n",n_gc); - }*/ - -/*static struct nc_conn *nc_conn_new(const struct peer *peer) - { - struct nc_conn *conn; - conn = calloc(1, sizeof(*conn)); - if (!conn) - return NULL; - conn->fd = -1; - peer_copy(&conn->peer, peer); - bn_address_str(conn->addr_str, sizeof(conn->addr_str), conn->peer.addr.ip); - return conn; - }*/ - -/*static bool nc_conn_start(struct iguana_info *coin,struct nc_conn *conn) - { - char errpfx[64]; - printf("start connection.(%s)\n",conn->addr_str); - conn->ipv4 = 1;//is_ipv4_mapped(conn->peer.addr.ip); - conn->fd = socket(conn->ipv4 ? AF_INET : AF_INET6,SOCK_STREAM,IPPROTO_TCP); - if ( conn->fd < 0 ) - { - sprintf(errpfx, "socket %s", conn->addr_str); - perror(errpfx); - return false; - } - int flags = fcntl(conn->fd,F_GETFL,0); - if ( (flags < 0) || (fcntl(conn->fd,F_SETFL,flags | O_NONBLOCK) < 0) ) - { - sprintf(errpfx, "socket fcntl %s", conn->addr_str); - perror(errpfx); - return false; - } - struct sockaddr *saddr; - struct sockaddr_in6 saddr6; - struct sockaddr_in saddr4; - socklen_t saddr_len; - if (conn->ipv4) - { - memset(&saddr4, 0, sizeof(saddr4)); - saddr4.sin_family = AF_INET; - memcpy(&saddr4.sin_addr.s_addr,&conn->peer.addr.ip[12],4); - saddr4.sin_port = htons(conn->peer.addr.port); - saddr = (struct sockaddr *) &saddr4; - saddr_len = sizeof(saddr4); - } - else - { - memset(&saddr6, 0, sizeof(saddr6)); - saddr6.sin6_family = AF_INET6; - memcpy(&saddr6.sin6_addr.s6_addr,&conn->peer.addr.ip[0], 16); - saddr6.sin6_port = htons(conn->peer.addr.port); - saddr = (struct sockaddr *) &saddr6; - saddr_len = sizeof(saddr6); - } - // initiate TCP connection - if ( connect(conn->fd,saddr,saddr_len) < 0 ) - { - if ( errno != EINPROGRESS ) - { - sprintf(errpfx, "socket connect %s", conn->addr_str); - perror(errpfx); - return false; - } - } - return true; - }*/ -int32_t rc,lbsock=-1,timeout=1000,priority=1; uint8_t magic[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; -if ( 0 ) -{ - int32_t testsock,testsock2; char buf[512]; - testsock2 = nn_socket(AF_SP,NN_CRYPTO); - testsock = nn_socket(AF_SP,NN_CRYPTO); - rc = nn_setsockopt(testsock,NN_SOL_SOCKET,NN_CRYPTO_MAGIC,magic,4); - rc = nn_setsockopt(testsock2,NN_SOL_SOCKET,NN_CRYPTO_MAGIC,magic,4); - nn_bind(testsock2,"crypto://127.0.0.1:9999"); - nn_connect(testsock,"crypto://127.0.0.1:9999"); - nn_send(testsock,"hello",6,0); - nn_recv(testsock2,buf,sizeof(buf),0); - printf("bind side got.(%s)\n",buf); - nn_send(testsock2,"gotmsg",7,0); - nn_recv(testsock,buf,sizeof(buf),0); - printf("connect side got.(%s)\n",buf); - - getchar(); -} -//if ( (lbsock= nn_socket(AF_SP,NN_CRYPTO)) >= 0 ) -{ - rc = nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_CRYPTO_MAGIC,magic,4); - printf("rc.%d from NN_CRYPTO_MAGIC\n",rc); - rc = nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDPRIO,&priority,sizeof(priority)); - rc = nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); - rc = nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); - printf("rc.%d from NN_SNDPRIO\n",rc); - //if ( nn_connect(lbsock,"crypto://127.0.0.1:8883") >= 0 ) - //if ( nn_connect(lbsock,"tcp://127.0.0.1:50447") >= 0 ) - { - iguana_main("bitcoin","BTC",1); //NODE_NETWORK); - getchar(); - } -} - -/*struct iguana_kvitem *iguana_kvitemptr(struct iguanakv *kv,void *value) - { - struct iguana_kvitem *item = 0; - if ( kv != 0 && value != 0 ) - { - value = (void *)((long)value - (kv)->keysize); - item = (void *)((long)value - ((long)item->keyvalue - (long)item)); - } - return(item); - }*/ - -void iguana_savepeers(struct iguana_info *coin) -{ - uint32_t peerind,itemind; struct iguana_peer *addr,space; char ipaddr[64]; - for (peerind=1; peerind<=coin->latest.maxpeers; peerind++) - { - if ( iguana_RWmmap(0,&space,coin,coin->peers,peerind) == 0 ) - { - strcpy(ipaddr,space.ipaddr); - //printf("peerind.%d -> (%s)\n",peerind,ipaddr); - if ( (addr= iguana_kvread(coin,&space,&itemind,coin->peers,space.A.ip)) != 0 ) - { - if ( peerind == itemind ) - { - if ( iguana_RWmmap(1,addr,coin,coin->peers,peerind) != 0 ) - printf("error RWmap.1 peerind.%d -> (%s)\n",peerind,ipaddr); - } else printf("mismatched peerind.%d vs itemind.%d for (%s)\n",peerind,itemind,ipaddr); - } - } else printf("error reading peerind.%d\n",peerind); - } - iguana_syncmap(&coin->peers->state.M,0); -} -if ( strcmp("peers",kv->name) == 0 ) -{ - struct iguana_peer *addr = (void *)sp->space; - addr->seen_verack = 0; - checkip[0] = 0; - addr->peerind = itemind; - if ( addr->ipaddr[0] != 0 ) - { - ipbits = (uint32_t)calc_ipbits(addr->ipaddr); - expand_ipbits(checkip,ipbits); - } - if ( addr->ipaddr[0] == 0 || strcmp(checkip,addr->ipaddr) != 0 ) - { - printf("bad record.(%s) vs (%s) %d vs %d\n",checkip,addr->ipaddr,addr->peerind,itemind); - i = keysize; - } - else printf("add n.%d skipped.%d (%s) vs (%s).%x i.%d\n",n,skipped,addr->ipaddr,checkip,ipbits,i); - } - -void *iguana_kvsavepeer(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize) -{ - FILE *fp = (FILE *)args; struct iguana_peer *addr; uint32_t data[4],ipbits,flag = 0; - if ( args != 0 && (addr= value) != 0 ) - { - printf("%p %s iterarg.%d verack.%d killed.%d\n",addr,addr->ipaddr,kv->iterarg,addr->seen_verack,addr->dead); - if ( kv->iterarg == 0 && addr->seen_verack != 0 ) - flag = 1; - else if ( kv->iterarg == 1 && addr->dead != 0 ) - flag = 1; - else if ( kv->iterarg == 2 && (addr->seen_verack == 0 && addr->dead == 0) ) - flag = 1; - if ( flag != 0 ) - { - ipbits = (uint32_t)calc_ipbits(addr->ipaddr); - data[0] = ipbits; - data[1] = addr->lastcontact; - data[2] = addr->nStartingHeight; - data[3] = addr->pingtime; - if ( fwrite(data,1,sizeof(data),fp) != sizeof(data) ) - { - printf("Error saving key.[%x]\n",ipbits); - return(key); - } - } - } - return(0); -} - -long iguana_savepeers(struct iguana_info *coin) -{ - FILE *fp; long retval = -1; int32_t iter; char fname[512],*str = "good"; - for (iter=0; iter<3; iter++) - { - coin->peers->iterarg = iter; - sprintf(fname,"%s.%s",coin->peers->name,str); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( iguana_kviterate(coin,coin->peers,(uint64_t)fp,iguana_kvsavepeer) == 0 ) - { - printf("save %ld to HDD\n",ftell(fp)); - retval = ftell(fp); - } - else printf("error saving item at %ld\n",ftell(fp)); - fclose(fp); - } else printf("error creating(%s)\n",fname); - if ( iter == 0 ) - str = "errpeer"; - else str = "newpeer"; - } - coin->updatedpeers = 0; - return(retval); -} - -/*void iguana_open_connection(struct iguana_info *coin,char *ipaddr) - { - int32_t i,n; struct iguana_peer addrs[10]; - memset(addrs,0,sizeof(addrs)); - n = iguana_connect(addrs,(int32_t)(sizeof(addrs)/sizeof(*addrs)),ipaddr,coin->chain->default_port); - if ( n > 0 ) - { - for (i=0; iipaddr,coin->numpeers,coin->numrelayers); - iguana_kvwrite(coin,coin->peers,addr->A.ip,addr,sizeof(*addr),(uint32_t *)&addr->peerind); - coin->updatedpeers++; -} - - -void *iguana_kvpurgepeer(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize) -{ - struct iguana_peer *addr; int32_t lag; - if ( args != 0 && (addr= value) != 0 && addr->sendtime != 0 ) - { - if ( (lag= (kv->iteruarg - addr->sendtime)) == 0 ) - lag = 1; - if ( kv->iterarg == 0 || lag > kv->iterarg ) - { - kv->iterarg = lag; - strcpy((char *)args,addr->ipaddr); - } - } - return(0); -} - -void *iguana_loop(void *_coin) -{ - struct iguana_info *coin = _coin; - while ( 1 ) - { - /*if ( 1 && (ipaddr= queue_dequeue(&coin->newpeersQ,1)) != 0 ) - { - iguana_open_connection(coin,ipaddr); - printf("check newpeer.(%s)\n",ipaddr); - free_queueitem(ipaddr); - }*/ - sleep(1); - } - return(0); -} - -void shutdown_daemon(struct iguana_info *coin) -{ - if ( coin->blocks.db != 0 ) - { - //iguana_kvsave(coin->blocks.db); - iguana_kvfree(coin,coin->blocks.db); - } -} - -/*if ( coin->numpeers > 16 ) - { - coin->peers->iteruarg = (uint32_t)time(NULL); - coin->peers->iterarg = 0; - if ( iguana_kviterate(coin,coin->peers,(uint64_t)ipaddr,iguana_kvpurgepeer) == 0 ) - printf("lag.%d (%s) peer purged\n",coin->peers->iterarg,ipaddr); - else printf("error: lag.%d (%s) peer purged\n",coin->peers->iterarg,ipaddr); - } - */ -//for (iter=0; iter<2; iter++) -{ - fpos = n = m = fixed = skipped = 0; - if ( (fp= fopen(sp->fname,"rb")) != 0 ) - { - fseek(fp,fpos,SEEK_SET); - while ( fread(sp->space,2,valuesize,fp) == valuesize ) - { - //printf("m.%d\n",m); - itemind = m++; - for (i=0; ispace)[kv->keyoffset + i] != 0 ) - break; - if ( i != keysize ) - { - if ( itemind != n ) - { - fseek(fp,fpos,SEEK_SET); - memset((void *)((long)sp->space + valuesize),0,valuesize); - fwrite((void *)((long)sp->space + valuesize),1,valuesize,fp); - fseek(fp,(long)n * valuesize,SEEK_SET); - fwrite(sp->space,1,valuesize,fp); - fixed++; - //printf("itemind.%d vs n.%d skipped.%d\n",itemind,n,skipped); - itemind = n; - } - if ( iter == 1 ) - { - iguana_kvwrite(coin,kv,(void *)((long)sp->space + kv->keyoffset),sp->space,valuesize,&itemind); - } - n++; - } skipped++; - fseek(fp,(long)m * valuesize,SEEK_SET); - } - printf("iter.%d fixed.%d %s added %d items, skipped.%d keysize.%d keyoffset.%d valuesize.%d\n",iter,fixed,kv->name,n,skipped,kv->keysize,kv->keyoffset,kv->valuesize); - fclose(fp); - //getchar(); - } -} -void iguana_killpeer(struct iguana_info *coin,struct iguana_peer *addr) -{ - if ( addr->seen_verack != 0 ) - { - addr->dead = 1; - addr->seen_verack = 0; - coin->numrelayers -= addr->relayflag; - coin->numpeers--; - printf("KILL PEER.(%s) peerind.%u total.%d relayers.%d\n",addr->ipaddr,addr->peerind,coin->numpeers,coin->numrelayers); - iguana_kvwrite(coin,coin->peers,addr->A.ip,addr,sizeof(*addr),(uint32_t *)&addr->peerind); - coin->updatedpeers++; - } -} - -/*for (j=0; jnumreferrals; j++) - if ( ipbits == addr->referrals[j] ) - break; - if ( j == addr->numreferrals ) - { - if ( addr->numreferrals < sizeof(addr->referrals)/sizeof(*addr->referrals) ) - addr->referrals[addr->numreferrals++] = ipbits; - iguana_possible_peer(coin,ipaddr); - }*/ - -int32_t iguana_blockchain(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgblock *blk,uint8_t *serialized,bits256 hash2,int32_t checkpointi) -{ - struct iguana_blocks *blocks; double PoW; struct iguana_block *prev,*check,space; int32_t i,height,firsttxidind; - blocks = &coin->blocks; - /*if ( (check= iguana_findblock(coin,&space,hash2)) != 0 ) - { - if ( checkpointi >= 0 && check->height == coin->checktip_heights[checkpointi]+1 ) - { - coin->checkpointips[checkpointi] = hash2; - coin->checktip_heights[checkpointi]++; - coin->rawblocks++; - printf("iguana_blockchain: duplicate block height.%d checkpointi.%d tipheight.%d rawblocks.%d\n",check->height,checkpointi,coin->checktip_heights[checkpointi],coin->rawblocks); - } - return(check->height); - } - for (i=0; ichain->numcheckpoints; i++) - { - if ( memcmp(coin->chain->checkpoints_data[i].bytes,hash2.bytes,sizeof(hash2)) == 0 ) - { - height = coin->chain->checkblocks[i]; - coin->checktip_heights[i] = height; - printf("checkpointi.%d height.%d rawblocks.%d\n",i,height,coin->rawblocks); - iguana_addblock(coin,hash2,blk,height,-1,0.); // add to block map, orphans and all - return(0); - } - if ( memcmp(coin->chain->checkpoints_data[i].bytes,blk->H.prev_block.bytes,sizeof(blk->H.prev_block)) == 0 ) - { - height = coin->chain->checkblocks[i] + 1; - coin->checktip_heights[i] = height; - coin->checkpointips[i] = hash2; - coin->rawblocks++; - printf("checkpointi.%d height.%d <- (%s) rawblocks.%d\n",i,height,bits256_str(hash2),coin->rawblocks); - iguana_addblock(coin,hash2,blk,height,-1,0.); // add to block map, orphans and all - return(0); - } - if ( memcmp(coin->checkpointips[i].bytes,blk->H.prev_block.bytes,sizeof(blk->H.prev_block)) == 0 ) - { - height = ++coin->checktip_heights[i]; - coin->checkpointips[i] = hash2; - coin->rawblocks++; - printf("checkpointi.%d height.%d rawblocks.%d\n",i,height,coin->rawblocks); - iguana_addblock(coin,hash2,blk,height,-1,0.); // add to block map, orphans and all - return(0); - } - }*/ - if ( (prev= iguana_findblock(coin,&space,blk->H.prev_block)) == 0 ) - { - fprintf(stderr,"iguana_blockchain no prev block.(%s)\n",bits256_str(blk->H.prev_block)); - return(-1); - } - else - { - height = prev->height + 1; - PoW = (PoW_from_compact(blk->H.bits) + prev->PoW); - firsttxidind = (prev->firsttxidind + prev->txn_count); - if ( PoW <= coin->blocks.best_chain_work ) - height = 0; - } - //printf("NEWHT.%d (%s) PoW %.15f prev.%d prevPoW %.15f\n",height,bits256_str(hash2),blk->PoW,prev->height,prev->PoW); - iguana_addblock(coin,addr,hash2,blk,height,firsttxidind,PoW); // add to block map, orphans and all - if ( height == 0 ) - { - printf("%s chain not best\n",bits256_str(hash2)); - return(-1); - } - if ( memcmp(blocks->best_chain.bytes,blk->H.prev_block.bytes,sizeof(blocks->best_chain)) != 0 ) - { - printf("prev.(%s) doesnt connect to previous bestchain\n",bits256_str(blk->H.prev_block)); - printf("mark as orphans from old bestchain.(%s) till it connects to mainchain\n",bits256_str(blocks->best_chain)); - getchar(); - } - return(height); -} - -int32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) -{ - struct iguana_peer *space,*addr,addrs[8]; uint32_t i,n,peerind = (uint32_t)-1; - if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) - { - memset(addrs,0,sizeof(addrs)); - n = iguana_connect(addrs,(int32_t)(sizeof(addrs)/sizeof(*addrs)),ipaddr,coin->chain->default_port,0); - if ( n > 0 ) - { - for (i=0; i<1; i++) // n is almost always 1 - { - strcpy(addrs[i].coinstr,coin->name); - space = calloc(1,sizeof(*space)); - peerind = -1; - //portable_mutex_lock(&coin->netmutex); - if ( (addr= iguana_kvread(coin,space,(uint32_t *)&peerind,coin->peers,ipaddr)) == 0 ) - memcpy(space,&addrs[i],sizeof(*space)); - else if ( addr->usock >= 0 || addr->pending != 0 ) - break; - peerind = -1; - if ( iguana_kvwrite(coin,coin->peers,ipaddr,space,sizeof(*space),(uint32_t *)&peerind) != 0 ) - { - //portable_mutex_unlock(&coin->netmutex); - //printf("%p %s ADD PEER.(%s) peerind.%u max.%u total.%d relayers.%d numkeys.%d\n",&addrs[i],space->coinstr,space->ipaddr,peerind,coin->latest.maxpeers,coin->numpeers,coin->numrelayers,coin->peers->numkeys); - space->coin = coin; - if ( coin->numthreads < 3 || (coin->numthreads < IGUANA_MAXPEERS/2 && iguana_metric(space) > coin->avemetric) || (coin->numthreads >= IGUANA_MAXPEERS/2 && coin->numthreads < IGUANA_MAXPEERS) ) - { - peerind = -1; - //portable_mutex_lock(&coin->netmutex); - if ( (addr= iguana_kvread(coin,space,(uint32_t *)&peerind,coin->peers,ipaddr)) != 0 ) - { - coin->numthreads++; - //portable_mutex_unlock(&coin->netmutex); - addr->coin = coin; - if ( coin->chain->numcheckpoints > 0 ) - addr->checkpointi = (coin->nextcheckpointi++ % coin->chain->numcheckpoints); - else addr->checkpointi = -1; - portable_thread_create(iguana_startconnection,addr); - } //else portable_mutex_unlock(&coin->netmutex); - } - //printf("possible.(%s)\n",ipaddr); - } - else - { - //portable_mutex_unlock(&coin->netmutex); - printf("error writing?\n"); - } - } - } - } - return(0); -} -/*iguana_send_version(coin,addr,coin->myservices); - if ( addr->dead == 0 && addr->usock >= 0 ) - { - printf("connected and version sent to usock.%d (%s) numpings.%d\n",addr->usock,addr->ipaddr,addr->numpings); - if ( coin->chain->numcheckpoints > 0 ) - addr->checkpointi = (coin->nextcheckpointi++ % coin->chain->numcheckpoints); - printf("%s uses checkpointi.%d\n",addr->ipaddr,addr->checkpointi); - //nexti = (coin->chain->numcheckpoints/IGUANA_MAXPEERS) * addr->checkpointi; - iguana_advancechain(coin,addr,addr->checkpointi);//nexti++ % coin->chain->numcheckpoints); - }*/ - -/*iguana_send_version(coin,addr,coin->myservices); - if ( addr->dead == 0 && addr->usock >= 0 ) - { - printf("connected and version sent to usock.%d (%s) numpings.%d\n",addr->usock,addr->ipaddr,addr->numpings); - if ( coin->chain->numcheckpoints > 0 ) - addr->checkpointi = (coin->nextcheckpointi++ % coin->chain->numcheckpoints); - printf("%s uses checkpointi.%d\n",addr->ipaddr,addr->checkpointi); - //nexti = (coin->chain->numcheckpoints/IGUANA_MAXPEERS) * addr->checkpointi; - iguana_advancechain(coin,addr,addr->checkpointi);//nexti++ % coin->chain->numcheckpoints); - }*/ - - -void iguana_pollconnection(struct iguana_info *coin,struct iguana_peer *addr) -{ - /*if ( addr->last_getblocks < time(NULL) - (24 * 60 * 60) ) - { - memset(stophash.bytes,0,sizeof(stophash)); - n = iguana_locator(coin,hashes,(int32_t)(sizeof(hashes)/sizeof(*hashes))); - iguana_send_hashes(coin,addr->protover < GETHEADERS_VERSION ? "getblocks" : "getheaders",addr,stophash,hashes,n); - printf("send %s to %s\n",addr->protover < GETHEADERS_VERSION ? "getblocks" : "getheaders",addr->ipaddr); - addr->last_getblocks = time(NULL); - }*/ -} - -void iguana_checkpoint(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,int32_t height) -{ - struct iguana_block block; - memset(&block,0,sizeof(block)); - block.prev_block = hash2; - block.height = (height + 1); - //printf("write (%s) to %d\n",bits256_str(hash2),height+1); - iguana_RWmmap(1,&block,coin,coin->blocks.db,height+1); - //iguana_syncmap(coin->blocks.db,0); -} - -int32_t iguana_addblockhash(struct iguana_info *coin,struct iguana_peer *addr,int32_t *heightp,bits256 hash2,bits256 nexthash) -{ - struct iguana_block *block,*next,space,nextspace; - *heightp = -1; - if ( (block= iguana_findblock(coin,&space,hash2)) != 0 ) - { - *heightp = block->height; - if ( (next= iguana_findblock(coin,&nextspace,nexthash)) == 0 ) - { - iguana_checkpoint(coin,addr,nexthash,block->height + 1); - //iguana_audit(coin); - return(0); - } - else if ( next->height != block->height + 1 ) - { - printf("iguana_addblockhash: mismatched next height.%d vs height.%d+1\n",next->height,block->height); - //iguana_audit(coin); - return(-1); - } - else - { - //iguana_audit(coin); - return(iguana_blockdata(coin,block)); - } - } - //iguana_audit(coin); - return(0); -} - - -int32_t iguana_advancecmp(bits256 hashes[2],int32_t n,int32_t cmpa,int32_t cmpb) -{ - //printf("n.%d cmpa.%d cmpb.%d\n",n,cmpa,cmpb); - if ( bits256_nonz(hashes[0]) != 0 && bits256_nonz(hashes[1]) == 0 && (cmpa == 0 || n < cmpa) && (cmpb == 0 || n < cmpb) ) - return(1); - //printf("failed cmp %d %d %d %d\n",bits256_nonz(hashes[0]) != 0,bits256_nonz(hashes[1]) == 0,(cmpa == 0 || n < cmpa),(cmpb == 0 || n < cmpb)); - return(0); -} - -/*void iguana_advancechain(struct iguana_info *coin,struct iguana_peer *addr,int32_t checkpointi) - { - bits256 stophash,hashes[10]; int32_t islocal,n = 0; char *cmd = ""; - memset(stophash.bytes,0,sizeof(stophash)); - islocal = (strcmp("127.0.0.1",addr->ipaddr) == 0); - //printf("blockhash %d, blockhdr.%d block.%d height.%d\n",addr->maxblockhash_height,addr->maxblockhdr_height,addr->maxblock_height,addr->height); - if ( (islocal != 0 || addr->protover < GETHEADERS_VERSION) && iguana_advancecmp(addr->maxblockhash,addr->maxblockhash_height,addr->maxblockhdr_height+500,addr->height+2000) != 0 ) - { - printf("request blockhashes islocal.%d\n",islocal); - cmd = "getblocks"; - addr->maxblockhash[1] = hashes[n++] = coin->blocks.hwmchain;//addr->maxblockhash[0]; - } - else if ( islocal != 0 && addr->protover >= GETHEADERS_VERSION && iguana_advancecmp(addr->maxblockhdr,addr->maxblockhdr_height,addr->maxblock_height+500,0) != 0 ) - { - cmd = "getheaders"; - printf("request headers islocal.%d\n",islocal); - addr->maxblockhdr[1] = hashes[n++] = addr->maxblockhdr[0]; - } - else if ( memcmp(coin->blocks.hwmchain.bytes,addr->maxblock[1].bytes,sizeof(bits256)) != 0 ) //if ( iguana_advancecmp(addr->maxblock,addr->maxblock_height,addr->height,0) != 0 ) - { - printf("request data\n"); - addr->maxblock[0] = addr->maxblock[1] = coin->blocks.hwmchain; - iguana_request_data(coin,addr,coin->blocks.hwmchain,MSG_BLOCK); - return; - } - else - { - //printf("nothing to advance %s\n",addr->ipaddr); - return; - } - n = iguana_locator(coin,hashes,(int32_t)(sizeof(hashes)/sizeof(*hashes))-1,checkpointi); - iguana_send_hashes(coin,cmd,addr,stophash,hashes,n); - }*/ - - -// got functions - -void iguana_gotblockhash(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,bits256 nexthash,int32_t i,int32_t n) -{ - int32_t height; struct iguana_block space; bits256 hashes[2001]; - /*if ( iguana_addblockhash(coin,addr,&height,hash2,nexthash) == 0 ) - { - //if ( height > (coin->blocks.hwmheight-10) ) - // iguana_request_data(coin,addr,nexthash,MSG_BLOCK); - } - if ( height > addr->maxblockhash_height ) - { - addr->maxblockhash_height = height; - addr->maxblockhash[0] = hash2; - memset(addr->maxblockhash[1].bytes,0,sizeof(hash2)); - }*/ - //if ( i > 0 ) - //hashes[i-1] = hash2; - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - if ( i == n-1 ) - { - hashes[i] = nexthash; - iguana_request_data(coin,addr,&nexthash,1,MSG_BLOCK); - //iguana_request_data(coin,addr,hashes,n,MSG_BLOCK); - bits256 stophash; - memset(stophash.bytes,0,sizeof(stophash)); - iguana_send_hashes(coin,"getblocks",addr,stophash,&nexthash,1); - } - height = iguana_height(coin,hash2); - //printf("set gotblockhash.%s %d ht.%d -> %s from %s\n",bits256_str(hash2),height,iguana_height(coin,hash2),bits256_str2(nexthash),addr->ipaddr); - //iguana_audit(coin); -} - -int32_t iguana_gotblockhdr(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgblock *msg,uint8_t *serialized,int32_t len,bits256 hash2,int32_t checkpointi) -{ - int32_t n = 0,height = -1; struct iguana_block space,*block; - //printf("got gotblockhdr.%s from %s, checkpointi.%d\n",bits256_str(hash2),addr->ipaddr,checkpointi); - - if ( (block= iguana_findblock(coin,&space,hash2)) != 0 && block->height < coin->blocks.hwmheight ) - return(block->height - coin->blocks.hwmheight); - iguana_convblock(&space,msg,-1,0,0.); - if ( (height= iguana_addblock(coin,addr,hash2,&space)) > 0 ) - { - n = iguana_lookahead(coin,addr,&hash2,height + 1); - //printf("lookahead.%d\n",n); - } - /*if ( height+1+n > addr->maxblockhdr_height ) - { - printf("set new maxblockhdr.%d\n",height+1+n); - addr->maxblockhdr_height = height+1+n; - addr->maxblockhdr[0] = hash2; - memset(addr->maxblockhdr[1].bytes,0,sizeof(hash2)); - }*/ - //iguana_audit(coin); - return(height); -} -int32_t iguana_queue_ramchain(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,int32_t txind,int32_t numtx,struct iguana_msgtx *tx,bits256 txid) -{ - int32_t height; - addr->getdatamillis = 0; - if ( addr != 0 && txind == 0 && (height= iguana_height(coin,hash2)) >= 0 )//&& height >= addr->maxblock_height ) - { - //printf("got ramchain tx.%s from %s height.%d txind.%d\n",bits256_str(txid),addr!=0?addr->ipaddr:"local",height,txind); - /*printf("set new maxblock.%d\n",height); - addr->maxblock_height = height; - addr->maxblock[0] = hash2; - memset(addr->maxblock[1].bytes,0,sizeof(hash2));*/ - } - return(0); -} -void iguana_gottxid(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2) -{ -} - -int32_t iguana_addblock(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,struct iguana_block *newblock) -{ - int32_t h; - //,firsttxidind,txn_count,hwm=0,equivalent = 0; - //double PoW; struct iguana_block *block,space,prevspace; - //height = newblock->height, firsttxidind = newblock->firsttxidind, PoW = newblock->PoW; - //printf("iguana_addblock nBits.%x\n",newblock->bits); - /*if ( (block= iguana_findblock(coin,&space,hash2)) != 0 ) - { - if ( height >= 0 ) - { - if ( height != block->height ) - printf("iguana_addblockhdr: height.%d mismatch vs %d\n",height,block->height); - } else height = block->height; - if ( firsttxidind > 0 ) - { - if ( firsttxidind != block->firsttxidind ) - printf("iguana_addblockhdr: firsttxidind.%d mismatch vs %d\n",firsttxidind,block->firsttxidind); - } else firsttxidind = block->firsttxidind; - if ( PoW > SMALLVAL ) - { - if ( fabs(PoW - block->PoW) > SMALLVAL ) - printf("iguana_addblockhdr: PoW.%.15f mismatch vs %.15f\n",PoW,block->PoW); - } else PoW = block->PoW; - if ( (flag= iguana_blockdata(coin,block)) == 0 ) - { - printf("write out block.(%s) to %d\n",bits256_str(hash2),height); - iguana_kvwrite(coin,coin->blocks.db,hash2.bytes,newblock,sizeof(*newblock),(uint32_t *)&height); - } - else if ( flag > 0 ) - { - space2 = *block; - space2.height = newblock->height; - if ( memcmp(block,&space2,sizeof(*block)) != 0 ) - printf("newblock is different from oldblock (%d %d %f) vs (%d %d %f)\n",newblock->height,newblock->firsttxidind,newblock->PoW,block->height,block->firsttxidind,block->PoW); - else - { - equivalent = 1; - } - } - //printf("newblock (%d %d %f) vs old (%d %d %f)\n",newblock->height,newblock->firsttxidind,newblock->PoW,block->height,block->firsttxidind,block->PoW); - //iguana_audit(coin); - } - if ( memcmp(coin->chain->genesis_hashdata,hash2.bytes,sizeof(hash2)) == 0 ) - { - PoW = height = txn_count = 0; - prev = 0; - firsttxidind = 1; - hwm = 1; - block = newblock; - printf("adding genesis\n"); - } - else if ( (prev= iguana_findblock(coin,&prevspace,newblock->prev_block)) == 0 ) - { - printf("hash2.(%s) ",bits256_str(hash2)); - fprintf(stderr,"iguana_blockchain no prev block.(%s)\n",bits256_str(newblock->prev_block)); - getchar(); - return(-1); - } - else - { - if ( height >= 0 && height != prev->height + 1 ) - printf("iguana_addblock: height.%d != prev.%d+1\n",height,prev->height); - height = prev->height + 1; - PoW = prev->PoW; - firsttxidind = prev->firsttxidind; - txn_count = prev->txn_count; - }*/ - if ( (newblock->height= iguana_setchainvars(coin,addr,&newblock->firsttxidind,&newblock->PoW,hash2,newblock->prev_block,newblock->bits,newblock->txn_count)) != (uint32_t)-1 ) - { - if ( newblock->PoW > coin->blocks.hwmPoW ) - { - if ( newblock->height+1 > coin->blocks.maxblocks ) - coin->blocks.maxblocks = (newblock->height + 1); - h = newblock->height; - iguana_kvwrite(coin,coin->blocks.db,hash2.bytes,newblock,(uint32_t *)&h); - if ( addr != 0 && newblock->height > addr->height ) - addr->height = newblock->height; - coin->blocks.hwmheight = newblock->height; - coin->blocks.hwmPoW = newblock->PoW; - coin->blocks.hwmchain = hash2; - coin->latest.blockhash = hash2; - coin->latest.merkleroot = newblock->merkle_root; - coin->latest.timestamp = newblock->timestamp; - coin->latest.numblocks = coin->blocks.hwmheight+1; - coin->latest.numtxidind = newblock->firsttxidind + newblock->txn_count; - //iguana_syncmap(coin->blocks.db,0); - //printf("%s height.%d PoW %f\n",bits256_str(hash2),block->height,block->PoW); - if ( coin->initblocks != 0 ) - printf("ADD %d:%d:%d <- (%s) n.%u max.%u PoW %f\n",h,iguana_height(coin,coin->blocks.hwmchain),newblock->height,bits256_str(coin->blocks.hwmchain),coin->blocks.hwmheight+1,coin->blocks.maxblocks,newblock->PoW); - } - } - if ( memcmp(hash2.bytes,coin->blocks.hwmchain.bytes,sizeof(hash2)) != 0 ) - { - printf("ORPHAN.%s height.%d PoW %f vs best %f\n",bits256_str(hash2),newblock->height,newblock->PoW,coin->blocks.hwmPoW); - newblock->height = -1; - } - //iguana_audit(coin); - return(newblock->height); -} - -/*int32_t iguana_locator(struct iguana_info *coin,bits256 *hashes,int32_t max) - { - int32_t i,n = 0; bits256 prevhash; - hashes[n++] = coin->blocks.hwmchain; - for (i=0; iblocks.db->keyoffset + coin->blocks.db->keysize) / sizeof(struct iguana_block)); - if ( n > sizeof(blocks)/sizeof(*blocks) || coin->blocks.db->keysize != sizeof(bits256) ) - return(hash2); - for (i=0; iheight+i) == 0 ) - return(hash2); - memcpy(hash2.bytes,(void *)((long)&blocks[0] + coin->blocks.db->keyoffset),coin->blocks.db->keysize); - return(hash2); - }*/ - -int32_t iguana_blockdata(struct iguana_info *coin,struct iguana_block *block) -{ - bits256 key = iguana_blockkey(coin,block); - if ( block->height+1 >= (coin->blocks.db->state.M.allocsize / sizeof(*block)) || bits256_nonz(key) == 0 ) - return(-1); - else if ( block->height > 0 && (bits256_nonz(block->prev_block) == 0 || fabs(block->PoW) < SMALLVAL) ) - { - printf("iguana_blockdata height.%d \n",block->height); - return(0); - } - if ( block->firsttxidind > 0 ) - return(1); - return(-1); -} -/*space = mycalloc(1,sizeof(*space)); - if ( (addr= iguana_kvread(coin,space,(uint32_t *)&peerind,coin->peers,ipaddr)) == 0 ) - { - memcpy(space,&addrs[i],sizeof(*space)); - addr = space; - iguana_clear_addrstate(coin,addr); - } - else if ( addr->usock >= 0 || addr->pending != 0 || addr->dead != 0 ) - { - printf("%s usock.%d pending.%u dead.%d\n",addr->ipaddr,addr->usock,addr->pending,addr->dead); - break; - } - addr->lastcontact = (uint32_t)time(NULL); - if ( coin->numthreads < IGUANA_MAXTHREADS )//&& (coin->numactive < 3 || (coin->numactive < IGUANA_MAXPEERS/2 && iguana_metric(space) > coin->avemetric) || (coin->numactive >= IGUANA_MAXPEERS/2 && coin->numactive < IGUANA_MAXPEERS)) ) - { - addr->pending = (uint32_t)time(NULL); - addr->coin = coin; - peerind = -1; - iguana_kvwrite(coin,coin->peers,ipaddr,addr,(uint32_t *)&peerind); - portable_thread_create(iguana_startconnection,addr); - } else*/ - -{ - int32_t valuesize; void *checkptr; - valuesize = iguana_valuesize(coin,kv); - memset(kv->state.space,0,kv->RAMvaluesize); - checkptr = kv->state.space; - if ( (kv->flags & IGUANA_MAPPED_ITEM) != 0 ) - { - value = (void *)((long)value + sizeof(UT_hash_handle)); - checkptr = (void *)((long)checkptr + sizeof(UT_hash_handle)); - } - if ( iguana_RWmmap(0,kv->state.space,coin,kv,*itemindp) != 0 || memcmp(value,checkptr,valuesize) != 0 ) - { - printf("iguana_RWmmap data mismatch after kvwrite\n"); - getchar(); - } - -} -/*init_hexbytes_noT(hexstr,pk_script+1,pk_script[0]); - //printf("(%s).%02x ",hexstr,pk_script[pk_script[0]]); - if ( 1 && pk_script[1] == 4 ) - { - pk[0] = 2 + (pk_script[pk_script[0]] & 1); - memcpy(pk+1,pk_script+2,32); - init_hexbytes_noT(hexstr,pk,33); - printf("data.(%s).%d ",hexstr,pk_script[0]); - vcalc_sha256(0,sha256,pk,33); - calc_rmd160(0,rmd160,sha256,sizeof(sha256)); - init_hexbytes_noT(hexstr,rmd160,20); - printf("rmd.(%s) ",hexstr); - //decode_hex(rmd160,20,"e34498597d0d4d4be05db1bb7501da985e15aaa5"); - btc_convrmd160(coinaddr,coin->chain->addr_pubkey,rmd160); - printf("(%s)\n",coinaddr); - }*/ -/*int32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) - { - struct iguana_peer *addr=0,addrs[8]; uint32_t i,n; - #ifdef IGUANA_DISABLEPEERS - if ( strcmp(ipaddr,"127.0.0.1") != 0 ) - return(0); - #endif - if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) - { - //printf("possible peer.(%s)\n",ipaddr); - memset(addrs,0,sizeof(addrs)); - n = iguana_connect(addrs,(int32_t)(sizeof(addrs)/sizeof(*addrs)),ipaddr,coin->chain->default_port,0); - if ( n > 0 ) - { - for (i=0; i<1; i++) // n is almost always 1 - { - strcpy(addrs[i].coinstr,coin->name); - addr = mycalloc('p',1,sizeof(*addr)); - *addr = addrs[i]; - iguana_clear_peerstate(coin,addr); - queue_enqueue("connectionQ",&coin->peers.connectionQ,&addr->DL); - return(0); - } - } - } - if ( addr != 0 ) - myfree(addr,sizeof(*addr)); - return(0); - }*/ -/*{ - for (i=0; iname); - //if ( addr->ipv6 != 0 ) - // err = iguana_connectsocket(1,addr,(struct sockaddr *)&addr->saddr6,sizeof(addr->saddr6)); - //else err = iguana_connectsocket(1,addr,(struct sockaddr *)&addr->saddr4,sizeof(addr->saddr4)); - if ( err < 0 ) - { - fprintf(stderr,"close connect %s: %s numpings.%d\n",addr->ipaddr,strerror(-err),addr->numpings); - iguana_iAkill(coin,addr); - } - else - { - iguana_iAconnected(coin,addr); - addr->ready = (uint32_t)time(NULL); - } - } - }*/ -void iguana_clear_peerstate(struct iguana_info *coin,struct iguana_peer *addr) -{ - addr->usock = -1; - addr->pingnonce = 0; - addr->ready = addr->dead = addr->pending = 0; - addr->startsend = addr->startrecv = 0; - addr->bufsize = 0; addr->buf = 0; - strcpy(addr->symbol,coin->symbol); - strcpy(addr->coinstr,coin->name); - //memset(&addr->DL,0,sizeof(addr->DL)); - //memset(&addr->sendQ,0,sizeof(addr->sendQ)); - //memset(&addr->msgcounts,0,sizeof(addr->msgcounts)); -} - -/**/ -/* - void iguana_activate(struct iguana_info *coin,struct iguana_peer *addr) - { - int32_t i;//,peerind = -1; - if ( coin->peers.numactive > 0 ) - { - for (i=0; ipeers.numactive; i++) - if ( strcmp(coin->peers.active[i].ipaddr,addr->ipaddr) == 0 ) - break; - if ( i != coin->peers.numactive ) - { - printf("duplicate activation.%s rejected\n",addr->ipaddr); - return; - } - } - coin->peers.active[coin->peers.numactive] = *addr; - myfree(addr,sizeof(*addr)); - addr = &coin->peers.active[coin->peers.numactive++]; - iguana_send_version(coin,addr,coin->myservices); - printf("ACTIVE.%d peer.(%s) numthreads.%d\n",coin->peers.numactive,addr->ipaddr,coin->numthreads); - //if ( strcmp(addr->ipaddr,"127.0.0.1") == 0 ) - // portable_thread_create(iguana_localhost,addr); - } - - void iguana_connections(struct iguana_info *coin) - { - int32_t i,j,firsti,peerind; uint32_t ipbits; struct iguana_peer *addr; - if ( coin->numthreads < IGUANA_MAXTHREADS && (addr= queue_dequeue(&coin->peers.connectionQ,0)) != 0 ) - { - if ( addr->pending == 0 ) - { - for (i=0; ipeers.active)/sizeof(*coin->peers.active); i++) - if ( strcmp(coin->peers.active[i].ipaddr,addr->ipaddr) == 0 ) - break; - if ( i == coin->peers.numactive ) - { - if ( coin->peers.numpending < sizeof(coin->peers.pending)/sizeof(*coin->peers.pending) ) - { - ipbits = (uint32_t)calc_ipbits(addr->ipaddr); - firsti = -1; - for (i=0; ipeers.pending)/sizeof(*coin->peers.pending); i++) - { - if ( coin->peers.pending[i] == 0 ) - firsti = i; - else if ( coin->peers.pending[i] == ipbits ) - break; - } - if ( i == sizeof(coin->peers.pending)/sizeof(*coin->peers.pending) ) - { - printf("PENDING.%-16s pending.%u ready.%u numpending.%d\n",addr->ipaddr,addr->pending,addr->ready,coin->numiAddrs); - coin->peers.pending[firsti] = ipbits; - addr->pending = (uint32_t)time(NULL); - strcpy(addr->symbol,coin->symbol); - iguana_launch(coin,"connection",iguana_startconnection,addr,0); - } - } - queue_enqueue("retryQ",&coin->peers.retryQ,&addr->DL); - } - } - else - { - if ( addr->ready != 0 ) - iguana_activate(coin,addr); - else if ( addr->dead == 0 ) - queue_enqueue("retryQ",&coin->peers.retryQ,&addr->DL); - } - } - }*/ - -//printf("parsed.%d firstvout.%d+%d firstvin.%d+%d: %s got.%d %s v %d\n",coin->blocks.parsedblocks,block->firstvout,block->numvouts,block->firstvin,block->numvins,addr->ipaddr,block->height,bits256_str(block->hash2),coin->blocks.hwmheight); -/*if ( block->height == coin->blocks.parsedblocks ) - iguana_parseblock(coin,block,tx,numtx); - else - { - printf("height.%d vs parsed.%d hwm.%d\n",block->height,coin->blocks.parsedblocks,coin->blocks.hwmheight); - iguana_addpending(coin,addr->ipbits,block,tx,numtx); - }*/ - -int32_t iguana_polliter(struct iguana_info *coin) -{ - struct pollfd fds[IGUANA_MAXPEERS]; - struct iguana_peer *addr,*addrs[IGUANA_MAXPEERS]; - int32_t i,n,nonz,flag,timeout=10; - memset(fds,0,sizeof(*fds)); - memset(addrs,0,sizeof(*addrs)); - flag = 0; - for (i=n=nonz=0; ipeers.active[i]; - fds[i].fd = -1; - if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 ) - { - if ( addr->pending == 0 ) - addrs[n++] = addr; - continue; - } - if ( addr->startrecv == 0 ) - { - fds[i].fd = addr->usock; - fds[i].events |= POLLIN; - nonz++; - } - } - if ( nonz != 0 && poll(fds,IGUANA_MAXPEERS,timeout) > 0 ) - { - for (i=0; ipeers.active[i]; - if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 ) - continue; - //if ( addr->usock >= 0 && addr->ready > 0 ) - // printf("%d/%d %d/%d startrecv.%u usock.%d dead.%d ready.%u\n",fds[i].events,fds[i].fd,POLLIN,POLLOUT,addr->startrecv,addr->usock,addr->dead,addr->ready); - if ( addr->startrecv == 0 && (fds[i].revents & POLLIN) != 0 ) - { - void iguana_processmsg(void *ptr); - flag++; - strcpy(addr->symbol,coin->symbol); - if ( 0 ) - { - addr->startrecv = (uint32_t)time(NULL); - iguana_launch("processmsg",iguana_processmsg,addr,0); - } else iguana_processmsg(addr); - } - } - } - return(flag); -} - -int32_t oldiguana_getdata(struct iguana_info *coin,struct iguana_peer *addr) -{ - struct iguana_overlap *ov = &addr->OV; - int32_t height,flag,elapsed,j,n = 0; bits256 hash2; double reqpsec,kbpsec; - //printf("iguana_getdata.(%s) ov.%p %p\n",addr->ipaddr,ov,addr); - //printf("addr height.%d vs parsed.%d\n",addr->height,coin->blocks.parsedblocks); - if ( ov->overlap == 0 ) - { - if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) - ov->overlap = IGUANA_MAXOVERLAP/2; - else ov->overlap = IGUANA_MAXOVERLAP/8; - iguana_teststart(coin,addr); - } - if ( addr != 0 && addr->dead == 0 && addr->usock >= 0 && addr->height >= coin->blocks.parsedblocks ) - { - for (flag=0; flagoverlap; flag++) - { - if ( addr->waiting[flag] == 0 ) - { - for (height=coin->blocks.parsedblocks; heightlongestchain&&heightblocks.parsedblocks+IGUANA_MAXPENDING; height++) - { - if ( coin->recvblocks != 0 && coin->recvblocks[height] != 0 ) - continue; - if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) - { - if ( height > coin->blocks.parsedblocks+IGUANA_MAXPENDING/2 ) - { - if ( n == 0 ) - { - hash2 = iguana_blockhash(coin,coin->blocks.parsedblocks); - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - } - return(n); - } - } - else - { - if ( height < coin->blocks.parsedblocks+IGUANA_MAXPENDING/2 ) - continue; - } - hash2 = iguana_blockhash(coin,height); - for (j=0; jwaitinghash[j].bytes,hash2.bytes,sizeof(hash2)) == 0 ) - break; - if ( j != sizeof(addr->waitinghash)/sizeof(*addr->waitinghash) ) - continue; - if ( height < coin->numwaitingbits && GETBIT(coin->waitingbits,height) == 0 ) - { - if ( bits256_nonz(hash2) != 0 ) - { - addr->waiting[flag] = (uint32_t)time(NULL); - addr->waitinghash[flag] = hash2; - if ( ov->numreqs++ >= ov->overlap ) - { - if ( ov->numreqs == ov->overlap ) - ov->numreqs = ov->overlap; - elapsed = (uint32_t)(time(NULL) - ov->teststart) + 1; - reqpsec = (double)ov->numreqs / elapsed; - kbpsec = (double)ov->reqrecv / (1024 * elapsed); - dxblend(&ov->Rsec,reqpsec,0.99); - dxblend(&ov->KBsec,kbpsec,0.99); - if ( kbpsec*reqpsec >= (ov->Rsec * ov->KBsec) ) - ov->faster++; - else ov->slower++; - if ( ((ov->faster + ov->slower) % 1000) == 0 ) - printf("OV.%-2d i.%-2d +%-4d -%-4d | h.%d %u | %5.1f/sec %5.3f/kB vs %5.1f/sec %5.3f/kB %5.1f %s\n",ov->overlap,flag,ov->faster,ov->slower,height,addr->waiting[flag],ov->Rsec,ov->KBsec,reqpsec,kbpsec,reqpsec*kbpsec-ov->Rsec*ov->KBsec,addr->ipaddr); - if ( time(NULL) > ov->teststart+60 || (ov->faster+ov->slower > ov->overlap*2 && ov->faster > 10*ov->slower) ) - iguana_teststart(coin,addr); - elapsed = (uint32_t)(time(NULL) - coin->starttime) + 1; - reqpsec = (double)coin->totalpackets / elapsed; - kbpsec = (double)coin->totalrecv / (1024 * elapsed); - dxblend(&coin->Rsec,reqpsec,0.99); - dxblend(&coin->KBsec,kbpsec,0.99); - } - n++; - //printf("request.%d bit.%d\n",height,GETBIT(coin->waitingbits,height)); - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - SETBIT(coin->waitingbits,height); - break; - } - } - } - } - } - } - if ( strcmp(addr->ipaddr,"127.0.0.1") == 0 && n == 0 && coin->recvblocks != 0 && coin->recvblocks[height] == 0 ) - { - hash2 = iguana_blockhash(coin,coin->blocks.parsedblocks); - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - } - return(n); - //printf("full.%d numactive.%d hwm.%d\n",coin->fullblocks,coin->numactive,coin->blocks.hwmheight); -} - -void iguana_teststart(struct iguana_info *coin,struct iguana_peer *addr) -{ - static uint32_t lastdisp; - int32_t dir; struct iguana_overlap *ov = &addr->OV; - dir = (ov->overlap - ov->prevoverlap); - ov->prevoverlap = ov->overlap; - if ( dir != 0 ) - { - if ( time(NULL) > lastdisp+60 ) - { - lastdisp = (uint32_t)time(NULL); - printf("ov.%-2d M%4.1f-> %5.1f/sec %6.2f/kb M%4.1f |fast.%-3d vs slow.%-3d d.%-2d | ",ov->overlap,ov->prevmetric,ov->Rsec,ov->KBsec,ov->Rsec*ov->KBsec,ov->faster,ov->slower,dir); - printf("all %5.1f/sec, %6.2fKB %s\n",coin->Rsec,coin->KBsec,addr->ipaddr); - } - if ( ov->faster > ov->slower ) - { - if ( (dir > 0 && ov->overlap < IGUANA_MAXOVERLAP) || (dir < 0 && ov->overlap > 1) ) - ov->overlap += dir; - //else printf("max overlap\n"); - //printf("increase by dir.%d -> overlap.%d\n",dir,addr->overlap); - } - else if ( dir > 0 && ov->overlap > 1 ) - { - ov->overlap--; - //printf("since slower, reduce overlap to overlap.%d\n",addr->overlap); - } - else if ( dir < 0 && ov->overlap < IGUANA_MAXOVERLAP ) - { - ov->overlap++; - //printf("since faster, increase overlap to overlap.%d\n",addr->overlap); - } - //else printf("at lowest overlap, cant change\n"); - ov->prevmetric = (ov->Rsec * ov->KBsec); - ov->reqrecv = 0; - ov->numreqs = -ov->overlap; - ov->faster = ov->slower = 0; - } - else ov->overlap = 1; - ov->teststart = (uint32_t)time(NULL); -} - -void iguana_localhost(void *ptr) -{ - struct iguana_info *coin; struct iguana_peer *addr = ptr; - if ( addr != 0 && (coin= iguana_coin(addr->symbol)) != 0 ) - { - while ( addr->dead == 0 ) - _iguana_processmsg(coin,addr); - } -} -if ( (num= iguana_available(coin,availables)) > 0 ) -{ - if ( (addr= availables[0]) != 0 ) - { - m = iguana_needed(coin,coin->need[0],IGUANA_MAXPENDING/2,0); - n = iguana_needed(coin,coin->need[1],IGUANA_MAXPENDING/2,IGUANA_MAXPENDING/2); - if ( strcmp(addr->ipaddr,"127.0.0.1") == 0 || num == 1 ) - { - //printf("m.%d n.%d num.%d\n",m,n,num); - for (i=0; ineed[0][i]; - //printf("%d ",height); - hash2 = iguana_blockhash(coin,height); - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK); - SETBIT(coin->waitingbits,height); - } - if ( num > 1 ) - { - for (i=0; ineed[1][i]; - //printf("%d ",height); - hash2 = iguana_blockhash(coin,height); - iguana_request_data(coin,availables[(i+1) % (num-1)],&hash2,1,MSG_BLOCK); - SETBIT(coin->waitingbits,height); - } - } - } - else - { - for (i=0; ineed[0][i]; - //printf("%d ",height); - hash2 = iguana_blockhash(coin,height); - iguana_request_data(coin,availables[i % num],&hash2,1,MSG_BLOCK); - SETBIT(coin->waitingbits,height); - } - } - if ( 0 && m+n > 0 ) - printf("requests\n"); - /*if ( m == 0 ) - sleep(3); - if ( m+n == 0 ) - sleep(10);*/ - return(m+n); - } else printf("null available[0]\n"); - } - -int32_t iguana_needed(struct iguana_info *coin,int32_t *need,int32_t max,int32_t offset) -{ - int32_t nonz,m,height; - if ( coin->recvblocks == 0 ) - return(0); - nonz = m = 0; - memset(need,0,sizeof(*need) * max); - if ( (time(NULL) - coin->parsetime) > 3 ) - need[m++] = coin->blocks.parsedblocks; - for (height=coin->blocks.parsedblocks+offset; heightlongestchain&&heightblocks.parsedblocks+max+offset; height++) - { - if ( coin->recvblocks[height] != 0 ) - nonz++; - else if ( GETBIT(coin->waitingbits,height) == 0 ) - need[m++] = height; - } - return(m); -} - -int32_t iguana_available(struct iguana_info *coin,struct iguana_peer *availables[IGUANA_MAXPEERS]) -{ - int32_t j,n; struct iguana_peer *addr; - memset(availables,0,sizeof(*availables) * IGUANA_MAXPEERS); - for (j=n=0; jpeers.active[j]; - if ( addr->height < coin->blocks.parsedblocks || addr == coin->localaddr ) - continue; - if ( addr->usock >= 0 && addr->dead == 0 && addr->ready > 0 && iguana_updatewaiting(coin,addr) > 0 ) - availables[n++] = addr; - } - return(n); -} - -/*int32_t iguana_loadtx(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashp,int32_t txind,int32_t numtx,struct iguana_msgtx *tx,uint8_t *data,int32_t maxsize) - { - int32_t len; bits256 txid; - memset(tx,0,sizeof(*tx)); - len = iguana_rwtx(0,data,tx,maxsize,&txid); - if ( blockhashp != 0 ) - { - //printf("parse.(%s)\n",bits256_str(*blockhashp)); - //if ( (blocknum= iguana_height(coin,*blockhashp)) >= 0 ) - if ( iguana_queue_ramchain(coin,addr,*blockhashp,txind,numtx,tx,txid) > 0 ) - return(len); - //else printf("cant find blockhash.(%s)\n",bits256_str(*blockhashp)); - } - iguana_purgetx(tx,0); - return(len); - }*/ -/*for (i=0; iwaiting)/sizeof(*addr->waiting); i++) - { - if ( addr->waiting[i] != 0 && time(NULL) > (addr->waiting[i] + 60) ) - { - if ( (height= iguana_height(coin,addr->waitinghash[i])) >= 0 ) - { - printf("i.%d of %ld ipbits.%x timeout.%s height.%d\n",i,sizeof(addr->waiting)/sizeof(*addr->waiting),addr->ipbits,addr->ipaddr,height); - CLEARBIT(coin->waitingbits,height); - } - addr->waiting[i] = 0; - addr->waitinghash[i] = bits256_zero; - } - if ( addr->waiting[i] == 0 ) - n++; - }*/ - -void *iguana_kvmetriciterator(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize) -{ - struct iguana_peer *addr = value; double *sortbuf = (double *)args; - if ( addr->numpings > 0 && addr->pingsum > SMALLVAL && item->hh.itemind < kv->numkeys ) - { - //printf("%p (%s).%d ind.%d msgs.%d pings.%d %.0fms [%.3f] last.%u lag.%d S.%llu R.%llu\n",sortbuf,addr->ipaddr,addr->usock,item->itemind,addr->numpackets,addr->numpings,addr->pingtime,addr->pingsum/addr->numpings,addr->lastcontact,kv->iteruarg - addr->lastcontact,(long long)addr->totalsent,(long long)addr->totalrecv); - sortbuf = &sortbuf[item->hh.itemind << 1]; - sortbuf[0] = iguana_metric(addr); - sortbuf[1] = item->hh.itemind; - } - return(0); -} - -int32_t iguana_sendrequests(struct iguana_info *coin,struct iguana_peer *addrs[],int32_t n,int32_t *blocks,int32_t m) -{ - int32_t i,height; bits256 hash2; - if ( n > 0 && m > 0 ) - { - for (i=0; iwaitingbits,height); - } - return(m); - } - return(0); -} -int32_t iguana_getdata(struct iguana_info *coin) -{ - int32_t reqs[IGUANA_READAHEAD],height,i,j,m,readahead,offset,numpeers,limit,n = 0; struct iguana_peer *addr,*addrs[IGUANA_MAXPEERS]; - if ( coin->R.waitingbits == 0 || coin->R.recvblocks == 0 ) - return(0); - capacity = iguana_capacity(coin,&numpeers,addrs); - if ( numpeers == 0 ) - return(0); - if ( capacity < numpeers ) - capacity = numpeers; - else if ( capacity > IGUANA_READAHEAD ) - capacity = IGUANA_READAHEAD; - readahead = (coin->longestchain - coin->blocks.parsedblocks) / numpeers; - for (j=m=0; jnumwaiting > IGUANA_MAXWAITING ) makes it worse - // break; - if ( coin->peers.numranked == 0 ) - addr = &coin->peers.active[j]; - else - { - if ( j >= coin->peers.numranked ) - break; - if ( (addr= coin->peers.ranked[j]) == 0 ) - continue; - } - if ( addr->recvblocks == 0 ) - limit = 1; - else - { - if ( addr == coin->peers.localaddr ) - limit = IGUANA_BUNDLESIZE; - else limit = addr->rank <= 0 ? 1 : (IGUANA_BUNDLESIZE / sqrt(addr->rank)); - if ( limit < 1 ) - limit = 1; - } - height = coin->blocks.parsedblocks; - if ( readahead < 1 ) - readahead = 1; - if ( readahead > IGUANA_READAHEAD ) - readahead = IGUANA_READAHEAD; - if ( addr->rank >= 0 && addr->ready > 0 && addr->usock >= 0 && addr->dead == 0 && addr->height > 0 ) - { - m++; - //printf("%s: addrht.%d %s p.%d getbit.%d rank.%d\n",addr->ipaddr,addr->height,addr->ipaddr,height,GETBIT(coin->waitingbits,height),addr->rank); - for (i=n=0; i<100000&&nrank > 0) ? addr->rank-1 : m)) * readahead; - height = (coin->blocks.parsedblocks + offset + i); - if ( height > coin->blocks.hwmheight || height > addr->height ) - { - //printf("%s: height.%d > hwm.%d || addr %d\n",addr->ipaddr,height,coin->blocks.hwmheight,addr->height); - break; - } - if ( coin->R.numwaiting > IGUANA_MAXWAITING && height > coin->blocks.parsedblocks+100 ) - break; - if ( iguana_waitstart(coin,height,addr) == 0 ) - { - //printf("%-15s request block.%-6d parsed.%-6d offset.%-4d rank.%-3d numpeers.%d numwaiting.%d\n",addr->ipaddr,height,coin->blocks.parsedblocks,offset,addr->rank,numpeers,coin->R.numwaiting); - n++; - } - } - } - } - return(n); -} - -/*else if ( time(NULL) > coin->parsetime+1 ) - { - coin->parsetime = (uint32_t)time(NULL); - printf("backstop.%d %s\n",coin->blocks.parsedblocks,bits256_str(iguana_blockhash(coin,coin->blocks.parsedblocks))); - iguana_waitclear(coin,coin->blocks.parsedblocks); - iguana_waitstart(coin,coin->blocks.parsedblocks,0); - iguana_updatewaiting(coin,coin->blocks.parsedblocks+1,100); - } - //else printf("ptr.%p height.%d\n",ptr,height);*/ - - -/*if ( coin->blocks.parsedblocks > initialheight ) - initialheight = coin->blocks.parsedblocks; - if ( coin->longestchain > initialheight ) - initialheight = coin->longestchain; - iguana_recvinit(coin,coin->R.numwaitingbits);*/ -//height = (coin->blocks.hwmheight / IGUANA_HDRSCOUNT) * IGUANA_HDRSCOUNT; -//iguana_queuehdrs(coin,height,iguana_blockhash(coin,height)); - -int32_t iguana_rwunspentind(struct iguana_info *coin,int32_t rwflag,struct iguana_unspent *U,uint32_t unspentind) -{ - if ( rwflag == 0 ) - { - memset(U,0,sizeof(*U)); - if ( iguana_kvread(coin,coin->unspents,0,U,&unspentind) != 0 ) - return(0); - else printf("error getting unspents[%u] when %d\n",unspentind,coin->latest.numunspents); - } - else if ( iguana_kvwrite(coin,coin->unspents,0,U,&unspentind) != 0 ) - return(0); - return(-1); -} -void iguana_requests(void *arg) -{ - int32_t flag,i,j,n; double sum; struct iguana_peer *addr; struct iguana_info *coin,**coins = arg; - n = (int32_t)coins[0]; - coins++; - printf("iguana_requests N.%d\n",n); - while ( 1 ) - { - for (i=0; iblocks.mutex); - //if ( iguana_avail(coin,coin->blocks.parsedblocks,10000) < 10000 ) - else printf("skip getting data max packets allocated %s\n",mbstr(sum)); - //portable_mutex_unlock(&coin->blocks.mutex); - } - } - if ( flag == 0 ) - usleep((uint32_t)coin->sleeptime + 1); - } -} -else -{ - if ( coin->peers.numranked > 0 && time(NULL) > coin->backstop ) - { - int32_t i; bits256 hash2; struct iguana_peer *addr; - i = (rand() % coin->peers.numranked); - hash2 = iguana_blockhash(coin,coin->blocks.parsedblocks); - addr = coin->peers.ranked[i]; - if ( addr != 0 && memcmp(hash2.bytes,addr->backstop.bytes,sizeof(hash2)) != 0 ) - { - iguana_waitclear(coin,coin->blocks.parsedblocks); - if ( addr != 0 ) - { - iguana_waitstart(coin,coin->blocks.parsedblocks,addr); - printf("%s BACKSTOP.%d\n",addr->ipaddr,coin->blocks.parsedblocks); - coin->backstop = (uint32_t)time(NULL); - } - } - } - /*if ( iguana_waitstart(coin,coin->blocks.parsedblocks,addr) == 0 ) - { - printf("backstop request.%d to %s\n",coin->blocks.parsedblocks,addr->ipaddr); - addr->backstop = hash2; - }*/ - //printf("%s skip %d vs %d ptr.%p\n",addr->ipaddr,coin->blocks.parsedblocks,coin->numwaitingbits,ptr); -} - -bits256 iguana_histo(struct iguana_info *coin) -{ - double sum = 0.; int32_t i; bits256 seed; - for (i=0; i<0x100; i++) - sum += coin->R.histo[i]; - sum /= i; - memset(seed.bytes,0,sizeof(seed)); - if ( sum > 0. ) - { - for (i=0; i<0x100; i++) - { - printf("%.2f ",coin->R.histo[i]/sum); - if ( coin->R.histo[i] > sum ) - SETBIT(seed.bytes,i); - } - } - printf("histo.(%s)\n",bits256_str(seed)); - return(seed); -} -struct iguana_state -{ - //char name[16]; - uint8_t sha256[256 >> 3]; struct sha256_vstate state; - //struct iguana_mappedptr M; struct iguana_space MEM; //queue_t writeQ; portable_mutex_t ; - void *table; - //FILE *fp; uint8_t *space; - //uint64_t maxitems; //uint32_t itemsize,flags; -}; -/*struct iguana_overlap - { - double KBsec,Rsec,prevmetric; - uint64_t reqrecv; - uint32_t teststart; - int32_t numreqs,overlap,faster,slower,prevoverlap; - };*/ - - -int32_t iguana_capacity(struct iguana_info *coin,int32_t *nump,struct iguana_peer *addrs[IGUANA_MAXPEERS]) -{ - struct iguana_peer *addr; int32_t i,n,capacity = 0; - for (i=n=0; ipeers.active[i]; - //if ( addr->usock >= 0 ) - // printf("%s ht.%d\n",addr->ipaddr,addr->height); - if ( addr->ready > 0 && addr->dead == 0 && addr->usock >= 0 && addr->height > coin->blocks.parsedblocks ) - { - capacity += addr->capacity; - addrs[n++] = addr; - } - } - *nump = n; - return(capacity); -} - -int32_t iguana_getdata(struct iguana_info *coin) -{ - int32_t reqs[IGUANA_READAHEAD],height,i,j,m,readahead,offset,numpeers,limit,n = 0; struct iguana_peer *addr,*addrs[IGUANA_MAXPEERS]; - if ( coin->R.waitingbits == 0 || coin->R.recvblocks == 0 ) - return(0); - for (i=numpeers=0; ipeers.active[i].usock < 0 ) - numpeers++; - if ( numpeers == 0 ) - return(0); - readahead = (coin->longestchain - coin->blocks.parsedblocks) / numpeers; - for (j=m=0; jnumwaiting > IGUANA_MAXWAITING ) makes it worse - // break; - if ( coin->peers.numranked == 0 ) - addr = &coin->peers.active[j]; - else - { - if ( j >= coin->peers.numranked ) - break; - if ( (addr= coin->peers.ranked[j]) == 0 ) - continue; - } - if ( addr->recvblocks == 0 ) - limit = 1; - else - { - if ( addr == coin->peers.localaddr ) - limit = IGUANA_EXPIREWINDOW; - else limit = addr->rank <= 0 ? 1 : (IGUANA_EXPIREWINDOW / sqrt(addr->rank)); - if ( limit < 1 ) - limit = 1; - } - height = coin->blocks.parsedblocks; - if ( readahead < 1 ) - readahead = 1; - if ( readahead > IGUANA_EXPIREWINDOW ) - readahead = IGUANA_EXPIREWINDOW; - if ( addr->rank >= 0 && addr->ready > 0 && addr->usock >= 0 && addr->dead == 0 && addr->height > 0 ) - { - m++; - //printf("%s: addrht.%d %s p.%d getbit.%d rank.%d\n",addr->ipaddr,addr->height,addr->ipaddr,height,GETBIT(coin->waitingbits,height),addr->rank); - for (i=n=0; i<100000&&nrank > 0) ? addr->rank-1 : m)) * readahead; - height = (coin->blocks.parsedblocks + offset + i); - if ( height > coin->blocks.hwmheight || height > addr->height ) - { - //printf("%s: height.%d > hwm.%d || addr %d\n",addr->ipaddr,height,coin->blocks.hwmheight,addr->height); - break; - } - //if ( coin->R.numwaiting > IGUANA_MAXWAITING && height > coin->blocks.parsedblocks+100 ) - // break; - if ( iguana_waitstart(coin,height,addr) != 0 ) - { - addr->capacity--; - //printf("%-15s request block.%-6d parsed.%-6d offset.%-4d rank.%-3d numpeers.%d numwaiting.%d\n",addr->ipaddr,height,coin->blocks.parsedblocks,offset,addr->rank,numpeers,coin->R.numwaiting); - n++; - } - } - } - } - return(n); -} - -int32_t newiguana_getdata(struct iguana_info *coin) -{ - int32_t reqs[IGUANA_READAHEAD],height,i,j,count,capacity,numpeers,n = 0; struct iguana_peer *addr,*addrs[IGUANA_MAXPEERS]; - if ( coin->R.waitingbits == 0 || coin->R.recvblocks == 0 ) - return(0); - capacity = iguana_capacity(coin,&numpeers,addrs); - if ( numpeers == 0 ) - return(0); - if ( capacity < numpeers ) - capacity = numpeers; - else if ( capacity > IGUANA_READAHEAD ) - capacity = IGUANA_READAHEAD; - if ( iguana_avail(coin,coin->blocks.parsedblocks,IGUANA_READAHEAD) == IGUANA_READAHEAD ) - n = iguana_updatewaiting(coin,reqs,capacity,coin->blocks.parsedblocks + (coin->longestchain - coin->blocks.parsedblocks)/2); - else n = iguana_updatewaiting(coin,reqs,IGUANA_READAHEAD,coin->blocks.parsedblocks); - count = 0; - height = coin->blocks.parsedblocks; - //printf("capacity.%d reqs.%d numpeers.%d\n",capacity,n,numpeers); - if ( n > 0 ) - { - for (i=0; iR.numwaiting > IGUANA_MAXWAITING )//&& height > coin->blocks.parsedblocks+100 ) - break; - for (j=0; jcapacity > 0 && addr->height >= height ) - { - count += iguana_waitstart(coin,height,addr); - break; - } - } - if ( j == numpeers ) - { - //printf("leftover.%d n.%d\n",i,n); - if ( (addr= addrs[(i+j) % numpeers]) != 0 && addr->height >= height ) - count += iguana_waitstart(coin,height,addr); - break; - } - } - } - //for (i=0; i= 0 ) - { - if ( flag == 0 ) - { - - } - printf("gotheaders flag.%d n.%d (%s) %d vs %d \n",flag,n,bits256_str(blocks[n-1].hash2),iguana_height(coin,blocks[n-1].hash2),coin->blocks.hwmheight); - if ( n > 0 && iguana_height(coin,blocks[n-1].hash2) > coin->blocks.hwmheight-1000 ) - iguana_send_hashes(coin,strcmp(coin->name,"bitcoin") != 0 ? "getblocks" : "getheaders",addr,bits256_zero,&blocks[n-1].hash2,1); - } - printf("%s gotheaders.%d height.%d flag.%d\n",addr->ipaddr,n,coin->blocks.hwmheight,flag); - //portable_mutex_unlock(&coin->blocks.mutex); - }*/ - - -//#define IGUANA_OVERLAP 64 -//#define IGUANA_MAXWAITING (2 * IGUANA_MAXPEERS * IGUANA_OVERLAP) -//#define IGUANA_EXPIREWINDOW 1000 -//#define IGUANA_READAHEAD (IGUANA_EXPIREWINDOW) - -#ifndef IGUANA_DEDICATED_THREADS -limit = 1; -if ( addr->ipbits != 0 && addr->pendhdrs < limit && (hashstr= queue_dequeue(&coin->R.hdrsQ,1)) != 0 ) -{ - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - iguana_send_hashes(coin,strcmp(coin->name,"bitcoin") != 0 ? "getblocks" : "getheaders",addr,bits256_zero,&hash2,1); - queue_enqueue("pendinghdrsQ",&coin->R.pendinghdrsQ[0],(void *)((long)hashstr - sizeof(struct queueitem)),0); - //printf("dequeue hdrsQ.(%s) -> %s pendinghdrsQ\n",hashstr,addr->ipaddr); - addr->hdrmillis = milliseconds(); - addr->pendhdrs++; - flag++; -} -if ( addr->recvblocks == 0 ) -limit = 1; -else limit = IGUANA_MAXPENDING; -if ( addr->ipbits != 0 && addr->pendblocks < limit && (hashstr= queue_dequeue(&coin->blocksQ,1)) != 0 ) -{ - //printf("dequeued.(%s) for %s\n",hashstr,addr->ipaddr); - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - if ( memcmp(hash2.bytes,coin->chain->genesis_hashdata,sizeof(hash2)) != 0 ) - { - iguana_request_data(coin,addr,&hash2,1,MSG_BLOCK,0); - addr->pendblocks++; - flag++; - } - free_queueitem(hashstr); -} -#endif - -void newiguana_updatehdrs(struct iguana_info *coin) -{ - int32_t i,j,hdri,flag,iter; char *hashstr; struct iguana_hdrs *hdrs; bits256 hash2; - portable_mutex_lock(&coin->R.hdrsmutex); - if ( iguana_needhdrs(coin) == 0 ) - return; - iguana_requesthdrs(coin,0); - return; - hdri = (coin->blocks.hwmheight / IGUANA_HDRSCOUNT); - hdrs = &coin->R.hdrs[hdri]; - if ( time(NULL) > coin->R.lasthdrtime+3 && coin->blocks.hwmheight < coin->longestchain-500 ) - { - for (iter=flag=0; iter<2; iter++) - { - while ( flag == 0 && (hashstr= queue_dequeue(&coin->R.pendinghdrsQ[iter],1)) != 0 ) - { - //printf("timeout found pending.(%s)\n",hashstr); - flag++; - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - for (j=0; j<2; j++) - iguana_send_hashes(coin,strcmp(coin->name,"bitcoin") != 0 ? "getblocks" : "getheaders",0,bits256_zero,&hash2,1); - //queue_enqueue("resubmit",&coin->R.pendinghdrsQ[iter ^ 1],(void *)((long)hashstr - sizeof(struct queueitem)),0); - coin->R.lasthdrtime = (uint32_t)time(NULL); - break; - } - } - if ( hdrs->blocks == 0 && coin->peers.numranked > 2 ) - { - hash2 = iguana_blockhash(coin,hdri * IGUANA_HDRSCOUNT); - printf("hdrs backstop %d %s\n",hdri * IGUANA_HDRSCOUNT,bits256_str(hash2)); - for (j=0; j<3; j++) - iguana_send_hashes(coin,strcmp(coin->name,"bitcoin") != 0 ? "getblocks" : "getheaders",coin->peers.ranked[j],bits256_zero,&hash2,1); - coin->R.lasthdrtime = (uint32_t)time(NULL); - } - } - if ( coin->blocks.hwmheight > 100000 && coin->R.savedhdrs < coin->blocks.hwmheight-501 ) - coin->R.savedhdrs = iguana_savehdrs(coin); - //printf("hdri.%d height.%d n.%d %p coin->R.savedhdrs.%u\n",hdri,hdrs->height,hdrs->n,hdrs->blocks,coin->R.savedhdrs); - if ( hdrs->blocks != 0 && (hdrs->height + hdrs->n) > coin->blocks.hwmheight ) - iguana_processhdrs(coin,hdrs->blocks,hdrs->n); - for (i=0; iR.hdrs[i]; - if ( coin->blocks.hwmheight >= (hdrs->height + hdrs->n) ) - { - if ( hdrs->blocks != 0 ) - { - myfree(hdrs->blocks,hdrs->n * sizeof(*hdrs->blocks)); - hdrs->blocks = 0; - } - if ( hdrs->conflictblocks != 0 ) - { - myfree(hdrs->conflictblocks,hdrs->n * sizeof(*hdrs->conflictblocks)); - hdrs->conflictblocks = 0; - } - } - } - portable_mutex_unlock(&coin->R.hdrsmutex); -} -void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) -{ - int32_t i,iter,flag; char hexstr[65],*hashstr; - addr->lastrequest = bits256_zero; - addr->recvhdrs++; - if ( addr->pendhdrs > 0 ) - addr->pendhdrs--; - coin->R.lasthdrtime = (uint32_t)time(NULL); - iguana_processhdrs(coin,blocks,n); - return; - //printf("hdrs.(%s) n.%d from %s\n",bits256_str(blocks[0].hash2),n,addr->ipaddr); - portable_mutex_lock(&coin->R.hdrsmutex); - for (i=0; iR.numhdrs; i++) - { - if ( memcmp(coin->R.hdrs[i].hash2.bytes,blocks[0].prev_block.bytes,sizeof(bits256)) == 0 ) - { - init_hexbytes_noT(hexstr,blocks[0].prev_block.bytes,sizeof(bits256)); - for (iter=flag=0; iter<2; iter++) - { - while ( flag == 0 && (hashstr= queue_dequeue(&coin->R.pendinghdrsQ[iter],1)) != 0 ) - { - if( strcmp(hashstr,hexstr) == 0 ) - { - free_queueitem(hashstr); - //printf("found pending.(%s) hdri.%d\n",hexstr,(coin->blocks.hwmheight / IGUANA_HDRSCOUNT)); - flag++; - break; - } - queue_enqueue("requeue",&coin->R.pendinghdrsQ[iter ^ 1],(void *)((long)hashstr - sizeof(struct queueitem)),0); - } - } - if ( coin->R.hdrs[i].blocks == 0 ) - { - coin->R.hdrs[i].blocks = blocks; - coin->R.hdrs[i].n = n; - printf("got headers for %d[%d] from %s\n",coin->R.hdrs[i].height,n,addr->ipaddr); - if ( addr != 0 && coin->R.hdrs[i].height+n > addr->height ) - addr->height = coin->R.hdrs[i].height+n; - } - else if ( coin->R.hdrs[i].n == n && memcmp(coin->R.hdrs[i].blocks,blocks,n*sizeof(*blocks)) == 0 ) - { - coin->R.hdrs[i].duplicates++; - printf("duplicate.%d blocks for height.%d n.%d\n",coin->R.hdrs[i].duplicates,coin->R.hdrs[i].height,n); - myfree(blocks,sizeof(*blocks) * n); - } - else - { - if ( coin->R.hdrs[i].conflictblocks != 0 ) - { - myfree(coin->R.hdrs[i].conflictblocks,coin->R.hdrs[i].conflictblocksn * sizeof(struct iguana_block)); - } - coin->R.hdrs[i].conflicts++; - printf("conflict.%d blocks for height.%d n.%d\n",coin->R.hdrs[i].conflicts,coin->R.hdrs[i].height,n); - coin->R.hdrs[i].conflictblocks = blocks; - coin->R.hdrs[i].conflictblocksn = n; - } - portable_mutex_unlock(&coin->R.hdrsmutex); - return; - } - } - printf("got unexpected hdrs[%d] prev %s\n",n,bits256_str(blocks[0].prev_block)); - myfree(blocks,sizeof(*blocks) * n); - portable_mutex_unlock(&coin->R.hdrsmutex); -} -void iguana_connections(void *arg) -{ - FILE *fp; uint8_t serialized[sizeof(struct iguana_msghdr)]; struct iguana_info *coin,**coins = arg; - int32_t i,j,r,n,iter,flag; uint32_t now,lastrank; char fname[512]; - struct iguana_peer *addr; - n = (int32_t)coins[0]; - lastrank = (uint32_t)time(NULL); - coins++; - for (i=0; isymbol,(iter == 0) ? "peers" : "hdrs"); - if ( (fp= fopen(fname,"r")) != 0 ) - iguana_parseline(coin,iter,fp); - fclose(fp); - } - //iguana_recvinit(coin,coin->R.numwaitingbits); - } - while ( 1 ) - { - if ( time(NULL) > lastrank+60 ) - { - for (i=0; ipeers.mutex); - iguana_peermetrics(coins[i]); - portable_mutex_unlock(&coin->peers.mutex); - } - lastrank = (uint32_t)time(NULL); - } - now = (uint32_t)time(NULL); - for (i=flag=0; ipeers.active[(j + r) % IGUANA_MAXPEERS]; - if ( addr->usock >= 0 && addr->ipbits != 0 ) - { - if ( addr->dead == 0 && addr->ready > 0 ) - { - if ( now > addr->lastblockrecv+60 && addr->pendblocks > 0 ) - addr->pendblocks--; - if ( now > coin->peers.lastpeer+300 ) - iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0); - } - //printf("%s pend.(%d %d) dead.%u ready.%u relay.%d millis.%.0f hwm.%d\n",addr->ipaddr,addr->pendhdrs,addr->pendblocks,addr->dead,addr->ready,addr->relayflag,addr->hdrmillis,coin->blocks.hwmheight); - } - } - if ( now > coin->peers.lastpeer+300 ) - { - printf("lastpeer %u vs now.%u, startpeers\n",coin->peers.lastpeer,now); - coin->peers.lastpeer = now; - } - } - iguana_shutdownpeers(coin,0); // closes dead peers to free up open spots - } - if ( flag == 0 ) - usleep(10000); - } -} -&& ((packet= queue_dequeue(&addr->sendQ,0)) != 0 || (packet= queue_dequeue(&coin->sendQ,0)) != 0) ) -{ - //printf("%d %s: usock.%d dead.%u ready.%u\n",i,addr->ipaddr,addr->usock,addr->dead,addr->ready); - flag++; - if ( (packet->addr != 0 && packet->addr != addr) || (packet->getdatablock > 0 && packet->getdatablock < coin->blocks.parsedblocks) || coin->R.recvblocks[packet->getdatablock] != 0 ) - { - if ( coin->R.recvblocks[packet->getdatablock] == 0 ) - printf("peerloop: (%s).%d packetaddr.%p != %p || packet->getdatablock %d < %d coin->blocks.parsedblocks recv[%p]\n",packet->serialized+4,packet->datalen,packet->addr,addr,packet->getdatablock,coin->blocks.parsedblocks,coin->R.recvblocks[packet->getdatablock]); - myfree(packet,sizeof(*packet) + packet->datalen); - } - else - { - if ( 1 && addr != coin->peers.localaddr ) - { - if ( ) - { - addr->startsend = (uint32_t)time(NULL); - strcpy(addr->symbol,coin->symbol); - strcpy(addr->coinstr,coin->name); - iguana_launch("send_data",iguana_issue,packet,IGUANA_SENDTHREAD); - } else printf("need to wait for pending sends %d\n",iguana_numthreads(1<serialized,packet->datalen); - if ( packet->getdatablock > 0 ) - iguana_setwaitstart(coin,packet->getdatablock); - myfree(packet,sizeof(*packet) + packet->datalen); - } - } - void iguana_queuehdrs(struct iguana_info *coin,int32_t height,bits256 hash2) - { - char hashstr[65]; //int32_t hdrsi; - init_hexbytes_noT(hashstr,hash2.bytes,sizeof(hash2)); - queue_enqueue("hdrsQ",&coin->R.hdrsQ,queueitem(hashstr),1); - //printf("try to queue hdr.(%s) height.%d vs %d\n",hashstr,height,coin->blocks.hwmheight); - /*if ( (height % IGUANA_HDRSCOUNT) == 0 && height+1 >= coin->blocks.hwmheight ) - { - hdrsi = (height / IGUANA_HDRSCOUNT); - if ( (height == 0 || coin->R.hdrs[hdrsi].height == 0) && coin->R.hdrs[hdrsi].duplicates == 0 ) - { - coin->R.hdrs[hdrsi].hash2 = hash2; - coin->R.hdrs[hdrsi].height = height; - if ( hdrsi >= coin->R.numhdrs ) - coin->R.numhdrs = hdrsi + 1; - //printf("queued hdr.(%s)\n",hashstr); - queue_enqueue("hdrsQ",&coin->R.hdrsQ,queueitem(hashstr),1); - } - }*/ - } - - int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,char *cmd,int32_t len,int32_t getdatablock,int32_t forceflag) - { - struct iguana_packet *packet; int32_t datalen; - if ( addr == 0 ) - { - printf("iguana_queue_send null addr\n"); - getchar(); - return(-1); - } - datalen = iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len); - if ( strcmp("getaddr",cmd) == 0 && time(NULL) < addr->lastgotaddr+300 ) - return(0); - if ( strcmp("version",cmd) == 0 ) - return(iguana_send(coin,addr,serialized,datalen)); - packet = mycalloc('S',1,sizeof(struct iguana_packet) + datalen); - packet->datalen = datalen; - packet->addr = addr; - if ( 1 && (packet->getdatablock = getdatablock) == 0 && strcmp((char *)&serialized[4],"getdata") == 0 ) - { - printf("no need to request genesis\n"); - getchar(); - } - memcpy(packet->serialized,serialized,datalen); - //printf("%p queue send.(%s) %d to (%s) %x\n",packet,serialized+4,datalen,addr->ipaddr,addr->ipbits); - queue_enqueue("sendQ",addr != 0 ? &addr->sendQ : &coin->sendQ,&packet->DL,0); - //printf("queue send.(%s) datalen.%d addr.%p %s [%d]\n",cmd,len,addr,addr!=0?addr->ipaddr:"",getdatablock); - if ( addr == 0 || (addr->dead == 0 && addr->ipbits != 0) ) - { - if ( addr == 0 && getdatablock == 0 ) - addr = iguana_choosepeer(coin); - if ( addr == coin->peers.localaddr || (getdatablock == 0 && strcmp(cmd,"getdata") != 0) ) - forceflag = 1; - if ( forceflag != 0 ) - { - if ( getdatablock >= coin->blocks.parsedblocks ) - len = iguana_send(coin,addr!=0?addr:iguana_choosepeer(coin),serialized,datalen); - else len = -1; - } - else - { - packet = mycalloc('S',1,sizeof(struct iguana_packet) + datalen); - packet->datalen = datalen; - packet->addr = addr; - if ( 1 && (packet->getdatablock = getdatablock) == 0 && strcmp((char *)&serialized[4],"getdata") == 0 ) - { - printf("no need to request genesis\n"); - getchar(); - } - memcpy(packet->serialized,serialized,datalen); - //printf("%p queue send.(%s) %d to (%s) %x\n",packet,serialized+4,datalen,addr->ipaddr,addr->ipbits); - queue_enqueue("sendQ",addr != 0 ? &addr->sendQ : &coin->sendQ,&packet->DL,0); - } - } else printf("cant send.(%s) len.%d datalen.%d to null addr or dead.%u\n",&serialized[4],len,datalen,addr->dead); - return(len); - } - while ( (packet= queue_dequeue(&addr->sendQ,0)) != 0 ) - { - if ( packet->getdatablock > 0 && packet->getdatablock < coin->blocks.parsedblocks ) - { - packet->addr = 0; - printf("recycle pending sendQ block.%d\n",packet->getdatablock); - queue_enqueue("shutdown_sendQ",&coin->blocksQ,&packet->DL,0); - } else myfree(packet,sizeof(*packet) + packet->datalen); - } - -void iguana_dedicatedrecv(void *arg) -{ - struct iguana_info *coin = 0; uint8_t *buf; int32_t bufsize; struct iguana_peer *addr = arg; - if ( addr == 0 || (coin= iguana_coin(addr->symbol)) == 0 ) - { - printf("iguana_dedicatedrecv nullptrs addr.%p coin.%p\n",addr,coin); - return; - } - printf("DEDICATED RECV %s\n",addr->ipaddr); - bufsize = IGUANA_MAXPACKETSIZE; - buf = mycalloc('r',1,bufsize); - while ( addr->usock >= 0 && addr->dead == 0 && coin->peers.shuttingdown == 0 ) - _iguana_processmsg(coin,addr,buf,bufsize); - myfree(buf,bufsize); -} - if ( packet->getdatablock > 0 && (packet->getdatablock < coin->blocks.parsedblocks || coin->R.recvblocks[packet->getdatablock] != 0) ) - { - printf("discard sendQ for getdatablock.%d parsed.%d\n",packet->getdatablock,coin->blocks.parsedblocks); - myfree(packet,sizeof(*packet) + packet->datalen); - return(1); - - void iguana_issue(void *ptr) - { - uint32_t ipbits; char ipaddr[64]; struct iguana_peer *addr; struct iguana_info *coin=0; struct iguana_packet *packet = ptr; - if ( (addr= packet->addr) == 0 || (coin= iguana_coin(addr->symbol)) == 0 || addr->dead != 0 ) - { - printf("iguana_issue: addr %p coin.%p dead.%u\n",addr,coin,addr->dead); - return; - } - ipbits = (uint32_t)calc_ipbits(addr->ipaddr); - expand_ipbits(ipaddr,ipbits); - if ( strcmp(ipaddr,addr->ipaddr) == 0 ) - { - if ( packet->getdatablock == 0 ) - iguana_send(coin,addr,packet->serialized,packet->datalen); - else if ( packet->getdatablock > 0 && packet->getdatablock >= coin->blocks.parsedblocks ) - { - //printf("req block.%d to (%s) numthreads.%d\n",packet->getdatablock,packet->addr->ipaddr,iguana_numthreads(1 << IGUANA_SENDTHREAD)); - iguana_send(coin,addr,packet->serialized,packet->datalen); - iguana_setwaitstart(coin,packet->getdatablock); - } - } - else printf("iguana_issue: ipaddr mismatch.(%s) != (%s)\n",ipaddr,addr->ipaddr), getchar(); - //printf("finished sending %d to (%s) numthreads.%d\n",packet->datalen,packet->addr->ipaddr,iguana_numthreads(-1)); - addr->startsend = 0; - myfree(packet,sizeof(*packet) + packet->datalen); - } - - uint64_t iguana_validaterecv(struct iguana_info *coin,int32_t *nump,char *fname) - { - struct iguana_pending *ptr; struct iguana_block space; struct iguana_msgtx *tx; - int32_t n = 0; struct iguana_mappedptr M; struct iguana_memspace RSPACE; uint64_t allocated = 0; - memset(&M,0,sizeof(M)); - memset(&RSPACE,0,sizeof(RSPACE)); - if ( (ptr= iguana_mappedptr(0,&M,0,0,fname)) != 0 ) - { - RSPACE.ptr = M.fileptr; - RSPACE.used = 0; - RSPACE.size = M.allocsize; - printf("process.(%s) %ld\n",fname,(long)M.allocsize); - n = 0; - while ( ptr != 0 && ((long)ptr - (long)RSPACE.ptr)+ptr->next < (RSPACE.size - sizeof(*ptr)) ) - { - //printf("ptr diff.%d next.%d\n",(int32_t)((long)ptr - (long)RSPACE.ptr),ptr->next); - if ( (tx= iguana_validpending(coin,ptr,&space)) != 0 ) - { - //printf("%d: ht.%-6d size.%d next.%d\n",n,ptr->block.height,ptr->allocsize,ptr->next); - iguana_freetx(tx,ptr->numtx); - allocated += ptr->allocsize; - n++; - coin->R.recvblocks[ptr->block.height] = ptr; - } - else - { - printf("n.%d ht.%d: tx doesnt validate\n",n,ptr->block.height); - } - if ( ptr->next != 0 ) - ptr = (void *)((long)ptr + ptr->next); - else break; - } - if ( n == 0 ) - iguana_closemap(&M); - } - *nump = n; - return(allocated); - } - for (i=maxi=skipped=total=0; skipped<10; i++) - { - if ( coin->R.maprecvdata == 0 ) - break; - sprintf(fname,"tmp/%s/recv.%d",coin->symbol,i), iguana_compatible_path(fname); - if ( (allocated= iguana_validaterecv(coin,&n,fname)) != 0 ) - combined += allocated, total += n, skipped = 0, maxi = i; - else if ( skipped++ > 10 ) - break; - } - - /*for (i=0; isymbol); - ensure_directory(dirname); - sprintf(dirname,"tmp/%s",coin->symbol); - ensure_directory(dirname); - }*/ - //iguana_launch("peers",iguana_connections,coins,IGUANA_PERMTHREAD); - //iguana_launch("requests",iguana_requests,coins,IGUANA_PERMTHREAD); - - //portable_mutex_t hdrsmutex; struct iguana_hdrs *hdrs; uint32_t savedhdrs,lasthdrtime,numhdrs; - struct iguana_hdrs - { - bits256 hash2; - struct iguana_block *blocks,*conflictblocks; - int32_t n,conflictblocksn,height,conflicts,duplicates; - }; - - - bits256 iguana_unspentmap(struct iguana_info *coin,uint32_t *spendindp,uint32_t *txidindp,char *txidstr,uint32_t unspentind) - { - struct iguana_unspent U; - memset(&U,0,sizeof(U)); - if ( iguana_rwunspentind(coin,0,&U,unspentind) == 0 ) - { - *txidindp = U.txidind; - *spendindp = U.spendind; - if ( txidstr != 0 ) - return(iguana_txidstr(coin,0,0,txidstr,U.txidind)); - } - else printf("error getting unspents[%u] when %d\n",unspentind,coin->latest.numunspents), getchar(); - return(bits256_zero); - } - - int32_t iguana_inittxid(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - char txidstr[513]; bits256 checktxid; uint32_t txidind,spendind; struct iguana_txid *tx = value; - if ( key != 0 && value != 0 && itemind > 0 ) - { - //printf("inittxid.(%s) itemind.%d (%d %d)\n",bits256_str(tx->txid),itemind,tx->firstvout,tx->firstvin); - checktxid = iguana_unspentmap(coin,&spendind,&txidind,txidstr,tx->firstvout); - if ( memcmp(checktxid.bytes,key,sizeof(checktxid)) != 0 || txidind != itemind ) - { - printf("checktxid.%s miscompares to %s, txidind.%d vs itemind.%d\n",txidstr,bits256_str(tx->txid),txidind,itemind); - getchar(); - return(-1); - } - if ( spendind >= coin->latest.numspends ) - { - //struct iguana_unspent U; - //iguana_rwunspentind(coin,0,&U,tx->firstvout); - //U.spendind = 0; - //iguana_rwunspentind(coin,1,&U,tx->firstvout); - printf("spendind.%d vs %d overflow in txid.%s txidind.%d U%d autocleared\n",spendind,coin->latest.numspends,txidstr,tx->firstvout,tx->firstvout); - } - //printf("txidind.%d: 1st.(%d %d)\n",txidind,tx->firstvout,tx->firstvin); - } - return(0); - } - - /*if ( flag != 0 && height > 0 ) - { - if ( coin->latest.numtxids != lastblock.L.firsttxidind + lastblock.txn_count && iguana_kvtruncate(coin,coin->txids,lastblock.L.firsttxidind + lastblock.txn_count) < 0 ) - err |= 1; - if ( coin->latest.numunspents != lastblock.L.firstvout + lastblock.numvouts && iguana_kvtruncate(coin,coin->unspents,lastblock.L.firstvout + lastblock.numvouts) < 0 ) - err |= 2; - if ( coin->latest.numspends != lastblock.L.firstvin + lastblock.numvins && iguana_kvtruncate(coin,coin->spends,lastblock.L.firstvin + lastblock.numvins) < 0 ) - err |= 4; - if ( coin->latest.numpkhashes != lastblock.L.numpkinds && iguana_kvtruncate(coin,coin->pkhashes,lastblock.L.numpkinds) < 0 ) - err |= 8; - } - else - { - printf("reset counters flag.%d height.%d\n",flag,height); //getchar(); - } - if ( err != 0 ) - return(-err);*/ - checktxid = iguana_txidstr(coin,0,0,txidstr,txidind); - if ( memcmp(checktxid.bytes,txid.bytes,sizeof(txid)) != 0 ) - { - int32_t i; - printf("error kvwrite/read of txid.%s vs %s txidind.%d\n",bits256_str(txid),bits256_str2(checktxid),txidind); - for (i=-10; i<10; i++) - { - iguana_rwtxidind(coin,0,&tx,txidind+i); - printf("txidind.%d %s\n",txidind+i,bits256_str(tx.txid)); - } - getchar(); - return(0); - } - checkind = iguana_txidind(coin,&checkfirstvout,&checkfirstvin,txid); - if ( checkind != txidind || checkfirstvout != firstvout || checkfirstvin != firstvin ) - { - printf("error kvwrite/read of txidind.%d:%d %s firstvout.%d vs %d firstvin.%d vs %d\n",txidind,checkind,bits256_str(txid),firstvout,checkfirstvout,checkfirstvin,firstvin); - getchar(); - return(0); - } - - int32_t iguana_recvinit(struct iguana_info *coin,int32_t initialheight) - { - //int32_t maxi,total; uint64_t allocated,combined = 0; - //portable_mutex_init(&coin->R.RSPACE.mutex); - //memset(&coin->R.RSPACE,0,sizeof(coin->R.RSPACE)); - //coin->R.RSPACE.size = 1024*1024*128; - //coin->R.RSPACE.counter = total != 0 ? maxi+1 : 0; - return(0); - } - - int32_t iguana_initpkhash(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - int64_t balance; uint64_t credits,debits; int32_t numutxo; uint32_t unspents[64]; struct iguana_pkhash *P = value; - if ( key != 0 && value != 0 && itemind > 0 ) - { - if ( (balance= iguana_balance(coin,&credits,&debits,&numutxo,unspents,sizeof(unspents)/sizeof(*unspents),P,itemind)) < 0 ) - { - printf("iguana_balance error pkind.%d %.8f vs %.8f\n",itemind,dstr(balance),dstr(P->balance)); - getchar(); - return(-1); - } - coin->latest.credits += credits; - coin->latest.debits += debits; - } - return(0); - } - /* - - int64_t iguana_balance(struct iguana_info *coin,uint64_t *creditsp,uint64_t *debitsp,int32_t *nump,uint32_t *unspents,long max,struct iguana_pkhash *P,uint32_t pkind) - { - uint32_t unspentind,spendind,lastunspentind,lastspendind,flag,n = 0; int64_t credits,debits,net = 0; - struct iguana_unspent U; struct iguana_spend S; - *creditsp = *debitsp = net = credits = debits = lastunspentind = lastspendind = flag = 0; - unspentind = P->firstunspentind; - while ( unspentind > 0 ) - { - lastunspentind = unspentind; - if ( iguana_rwunspentind(coin,0,&U,unspentind) == 0 ) - { - credits += U.value; - if ( U.spendind == 0 ) - { - net += U.value; - if ( n < max && unspents != 0 ) - unspents[n] = unspentind; - } - n++; - if ( unspentind != P->lastunspentind && U.nextunspentind > 0 && U.nextunspentind > unspentind && U.nextunspentind < coin->latest.numunspents ) - unspentind = U.nextunspentind; - else - { - if ( U.nextunspentind == 0 ) // cleared during unspents init - { - P->lastunspentind = unspentind = lastunspentind; - flag++; - } - break; - } - } else return(-1); - } - if ( unspentind == P->lastunspentind ) - { - if ( (spendind= P->firstspendind) >= coin->latest.numspends ) - { - P->firstspendind = P->lastspendind = spendind = 0; - flag++; - } - while ( spendind > 0 ) - { - lastspendind = spendind; - if ( iguana_rwspendind(coin,0,&S,spendind) == 0 ) - { - if ( S.unspentind > 0 && S.unspentind < coin->latest.numunspents && iguana_rwunspentind(coin,0,&U,S.unspentind) == 0 ) - { - debits += U.value; - if ( spendind != P->lastspendind && S.nextspendind > 0 && S.nextspendind > spendind && S.nextspendind < coin->latest.numspends ) - spendind = S.nextspendind; - } else S.nextspendind = 0; - if ( S.nextspendind == 0 ) // cleared during spends init - { - P->lastspendind = spendind = lastspendind; - flag++; - break; - } - } else return(-1); - } - if ( flag != 0 ) - { - if ( iguana_rwpkind(coin,1,P,pkind) < 0 ) - printf("error "); - printf("pkind.%d autofix\n",pkind); - P->balance = (credits - debits); - } - if ( net != (credits - debits) ) - printf("iguana_balance: total mismatch %.8f != %.8f (%.8f - %.8f)\n",dstr(net),dstr(credits)-dstr(debits),dstr(credits),dstr(debits)); - *nump = n; - *creditsp = credits; - *debitsp = debits; - return(net); - } else printf("iguana_balance error: unspentind.%u != last.%u\n",unspentind,P->lastunspentind); - *nump = 0; - return(-1); - }*/ - - int32_t iguana_processhdrs(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) - { - bits256 hash2; int32_t i,flag=0,startheight = -1,height = -1; struct iguana_block space,*block; - if ( startheight >= 0 ) - { - printf("%s received headers %d [%d] %s\n",addr->ipaddr,startheight,n,bits256_str(blocks[0].hash2)); - if ( startheight+n < coin->blocks.hwmheight ) - return(-1); - for (i=0; iblocks.hwmheight ) - continue; - if ( (block= iguana_findblock(coin,&space,blocks[i].hash2)) == 0 || height > coin->blocks.hwmheight ) - { - if ( (height= iguana_addblock(coin,blocks[i].hash2,&blocks[i])) > 0 ) - { - iguana_gotdata(coin,0,blocks[i].height,blocks[i].hash2); - flag++; - } - } else printf("height.%d:%d %s block.%p flag.%d\n",height,blocks[i].height,bits256_str(blocks[i].hash2),block,flag); - } - if ( flag != 0 ) - { - //iguana_queuehdrs(coin,blocks[n-1].height,blocks[n-1].hash2,1); - //iguana_lookahead(coin,&hash2,coin->blocks.hwmheight + 1); - } - } - iguana_lookahead(coin,&hash2,coin->blocks.hwmheight + 1); - return(flag); - } - - /*int32_t iguana_updatewaiting(struct iguana_info *coin,int32_t starti,int32_t max) - { - int32_t i,height,gap,n = 0; uint32_t now; - now = (uint32_t)time(NULL); - height = starti; - for (i=0; iblocks.parsedblocks); - if ( gap >= 0 ) - gap = sqrt(gap); - if ( gap < 1 ) - gap = 1; - if ( height < coin->R.numwaitingbits && coin->R.recvblocks[height] == 0 && now > (coin->R.waitstart[height] + gap) ) - { - //printf("restart height.%d width.%d widthready.%d %s\n",height,coin->width,coin->widthready,bits256_str(iguana_blockhash(coin,height))); - iguana_waitclear(coin,height); - iguana_waitstart(coin,height); - } //else printf("%d %d %p %u\n",height,coin->R.numwaitingbits,coin->R.recvblocks[height],coin->R.waitstart[height]); - } - //printf("height.%d max.%d\n",starti,max); - height = starti; - for (i=0; iR.recvblocks[height] != 0 ) - n++; - return(n); - }*/ - - /*void iguana_queuehdrs(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t forceflag) - { - char hashstr[65]; - if ( memcmp(bits256_zero.bytes,hash2.bytes,sizeof(hash2)) == 0 ) - { - printf("trying to queue null hash\n"); - getchar(); - } - if ( height < 0 ) - forceflag = 1; - if ( (forceflag != 0 && height > coin->blocks.hwmheight-coin->chain->bundlesize) || (height/coin->chain->bundlesize) > (coin->R.topheight/coin->chain->bundlesize) ) - { - printf("queue hdrs height.%d %s\n",height,bits256_str(hash2)); - coin->R.pendingtopheight = coin->R.topheight; - coin->R.pendingtopstart = (uint32_t)time(NULL); - init_hexbytes_noT(hashstr,hash2.bytes,sizeof(hash2)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - } - }*/ - /*if ( block->height >= coin->blocks.parsedblocks ) - { - memset(&space,0,sizeof(space)); - if ( iguana_kvread(coin,coin->blocks.db,0,&space,(uint32_t *)&block->height) != 0 ) - iguana_mergeblock(&space,block); - else printf("iguana_gotblock: cant read block.%d\n",block->height); - iguana_recvblock(coin,addr,&space,txarray,numtx,data,datalen); - iguana_kvwrite(coin,coin->blocks.db,0,&space,(uint32_t *)&space.height); - } // else printf("orphan %d block.%s from gotblockM\n",block->height,bits256_str(block->hash2)); - iguana_waitclear(coin,block->height);*/ - //portable_mutex_unlock(&coin->blocks.mutex); - - /*if ( 1 && coin->R.pendingtopheight == 0 ) - { - for (checkpointi=coin->blocks.hwmheight/coin->chain->bundlesize; checkpointiR.numcheckpoints; checkpointi++) - if ( memcmp(bits256_zero.bytes,coin->R.checkpoints[checkpointi].prevhash2.bytes,sizeof(coin->R.checkpoints[checkpointi])) != 0 ) - iguana_queuehdrs(coin,coin->R.checkpoints[checkpointi].height,coin->R.checkpoints[checkpointi].prevhash2,1); - coin->R.pendingtopheight = 1; - printf("issued initial gethdrs from %d\n",(coin->blocks.hwmheight/coin->chain->bundlesize)*coin->chain->bundlesize); //getchar(); - } - if ( coin->R.topheight < 0 ) - coin->R.topheight = 0; - if ( coin->blocks.hwmheight < 0 ) - coin->blocks.hwmheight = 0; - if ( coin->R.topheight < coin->blocks.hwmheight ) - coin->R.topheight = coin->blocks.hwmheight; - if ( coin->R.topheight == 0 || coin->R.topheight >= coin->R.pendingtopheight+coin->chain->bundlesize || time(NULL) > (coin->R.lasthdrtime + 60) ) - { - memset(hash2.bytes,0,sizeof(hash2)); - if ( coin->R.pendingtopheight != coin->R.topheight ) - { - height = (coin->R.topheight/coin->chain->bundlesize) * coin->chain->bundlesize; - hash2 = coin->R.checkpoints[height / coin->chain->bundlesize].prevhash2; - printf("request new header %d vs %d %u %s\n",height,coin->R.topheight,coin->R.pendingtopstart,bits256_str(hash2)); - if ( memcmp(bits256_zero.bytes,hash2.bytes,sizeof(hash2)) == 0 ) - hash2 = iguana_blockhash(coin,height); - } - if ( memcmp(bits256_zero.bytes,hash2.bytes,sizeof(hash2)) == 0 ) - { - iguana_lookahead(coin,&hash2,1); - if ( coin->blocks.hwmheight < coin->blocks.parsedblocks ) - coin->blocks.parsedblocks = coin->blocks.hwmheight; - height = coin->blocks.parsedblocks; - hash2 = iguana_blockhash(coin,height); - if ( iguana_choosepeer(coin) != 0 ) - printf("hwmchain request new header %d vs %d %u\n",coin->R.pendingtopheight,coin->R.topheight,coin->R.pendingtopstart); - } - coin->R.lasthdrtime = (uint32_t)time(NULL); - if ( memcmp(bits256_zero.bytes,hash2.bytes,sizeof(hash2)) != 0 ) - { - iguana_queuehdrs(coin,height,hash2,1); - return(1); - } - } - if ( coin->newhdrs != 0 ) - { - coin->newhdrs = 0; - height = coin->blocks.hwmheight; - iguana_lookahead(coin,&hash2,height + 1); - if ( coin->blocks.hwmheight > height ) - return(1); - }*/ - /*for (iter=0; iter<2; iter++) - { - while ( (req= queue_dequeue(&addr->pendblocksQ[iter ^ 1],0)) != 0 ) - { - if ( memcmp(&req->hash2,hash2.bytes,sizeof(hash2)) == 0 ) - { - if ( (*heightp= req->height) >= 0 && req->checkpointi >= 0 ) - { - printf("FOUND.(%s) height.%d\n",bits256_str(req->hash2),req->height); - if ( deleteflag == 0 ) - queue_enqueue("pendblocksQ",&addr->pendblocksQ[iter ^ 1],&req->DL,0); - return(&coin->R.checkpoints[req->checkpointi]); - } else printf("height.%d checkpointi.%d\n",req->height,req->checkpointi); - } - printf("requeue.%p\n",req); - queue_enqueue("pendblocksQ",&addr->pendblocksQ[iter ^ 1],&req->DL,0); - } - } - return(0);*/ - - void iguana_queuebundle(struct iguana_info *coin,struct iguana_bundle *bundle) - { - int32_t i; - printf("queue bundle.%p %s height.%d num.%d waitingbits.%d\n",bundle,bits256_str(bundle->prevhash2),bundle->height,bundle->num,coin->R.numwaitingbits); - for (i=0; inum; i++) - { - //printf("bundle[i.%d] %d %s\n",i,bundle->height + 1 + i,bits256_str(bundle->blocks[i].hash2)); - if ( iguana_recvblock(coin,bundle->height + 1 + i) == 0 ) - { - coin->R.blockhashes[bundle->height + 1 + i] = bundle->blocks[i].hash2; - //iguana_queueblock(coin,bundle->height + 1 + i,bundle->blocks[i].hash2,0); - } - } - } - - struct iguana_bundle *iguana_bundleheight(struct iguana_info *coin,int32_t *heightp,bits256 hash2,bits256 prev_block,int32_t deleteflag) - { - //int32_t i,j,miscompare = 0; struct iguana_bundle *bundle; - *heightp = -1; - /* for (i=0; iR.numbundles; i++) - { - if ( i*coin->chain->bundlesize > coin->longestchain ) - { - // printf("i.%d %d < longestchain.%d\n",i,i*coin->chain->bundlesize,coin->longestchain); - break; - } - bundle = &coin->R.bundles[i]; - if ( bundle->height >= 0 && bundle->blocks != 0 ) - { - if ( bundle->recvstart == 0 ) - continue; - // printf("bundlei.%d recvstart.%u finish.%u\n",i,bundle->recvstart,bundle->recvfinish); - if ( memcmp(bundle->prevhash2.bytes,prev_block.bytes,sizeof(prev_block)) == 0 ) - { - *heightp = bundle->height + 1; - return(bundle); - } - for (j=0; jnum; j++) - { - if ( memcmp(bundle->blocks[j].hash2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) - { - *heightp = bundle->height + 1 + j; - //printf("height.%d j.%d (%s) vs (%s) bundle.%d\n",*heightp,j,bits256_str(bundle->blocks[j].hash2),bits256_str2(hash2),bundle->height); - return(bundle); - } else miscompare++;//, printf("%x ",(uint32_t)bundle->blocks[j].hash2.uints[7]); - } - } //else printf("skip bundle.%d %p\n",bundle->height,bundle->blocks); - } - printf("cant find.(%s) miscompares.%d %x\n",bits256_str(hash2),miscompare,(uint32_t)hash2.uints[7]);*/ - return(0); - } - /* - static bits256 lasthash2; - struct iguana_blockreq *req; int32_t height; - addr->lastrequest = bits256_zero; - addr->recvhdrs++; - if ( addr->pendhdrs > 0 ) - addr->pendhdrs--; - coin->R.lasthdrtime = (uint32_t)time(NULL); - if ( memcmp(lasthash2.bytes,blockhashes[0].bytes,sizeof(lasthash2)) != 0 ) - { - if ( n <= 2 ) - { - printf("gotblockhashes[%d] %s pend.%d\n",n,bits256_str(blockhashes[0]),addr->pendhdrs); - lasthash2 = blockhashes[0]; - } - } - if ( n > 2 ) - { - if ( n > coin->chain->bundlesize ) - printf("warning: %s gotheaders.%d is too many vs. %d\n",coin->symbol,n,coin->chain->bundlesize); - req = mycalloc('r',1,sizeof(*req)); - req->hash2 = blockhashes[0]; - req->blockhashes = blockhashes; - req->n = n; - iguana_bundleheight(coin,&height,blockhashes[0],bits256_zero,0); - if ( req->height >= 0 ) - { - req->bundlei = (req->height / coin->chain->bundlesize); - //printf("blocksQ.%s height.%d\n",bits256_str(blockhashes[0]),height); - //queue_enqueue("blocksQ",&coin->blocksQ,&req->DL,0); - } - else - { - req->bundlei = -1; - //printf("priorityQ.%s height.%d\n",bits256_str(blockhashes[0]),height); - //queue_enqueue("priorityQ",&coin->priorityQ,&req->DL,0); - } - printf("blocksQ.%s height.%d req->height.%d\n",bits256_str(blockhashes[0]),height,req->height); - queue_enqueue("blocksQ",&coin->blocksQ,&req->DL,0); - } else myfree(blockhashes,n * sizeof(*blockhashes)); - } - - - int32_t h,i,height; uint32_t now; bits256 prevhash2; //char hashstr[65]; - struct iguana_blockreq *req; struct iguana_bundle *bundle; - - iguana_gotdata(coin,addr,block->height,block->hash2); - now = (uint32_t)time(NULL); - bundle = iguana_bundleheight(coin,&height,block->hash2,block->prev_block,1); - //printf("%s got block.%d height.%d\n",addr!=0?addr->ipaddr:"local",block->height,height); - if ( (req= queue_dequeue(&addr->pendingQ,0)) != 0 ) // should only have depth 1! - { - if ( memcmp(req->hash2.bytes,block->hash2.bytes,sizeof(req->hash2)) == 0 ) - { - if ( req->blockhashes != 0 ) - { - iguana_gotdata(coin,addr,block->height,block->hash2); - iguana_bundleinit(coin,block->height-1,block->prev_block); - if ( (bundle= iguana_bundle(coin,block->prev_block)) != 0 ) - { - portable_mutex_lock(&bundle->mutex); - if ( bundle->blocks == 0 ) - { - bundle->blockhashes = req->blockhashes; - bundle->num = req->n; - bundle->bundlei = (block->height / coin->chain->bundlesize); - bundle->firsthash2 = block->hash2; - bundle->lasthash2 = req->blockhashes[req->n-1]; - bundle->height = block->height - 1; - bundle->blocks = mycalloc('B',req->n,sizeof(*bundle->blocks)); - bundle->blocks[0] = *block; - prevhash2 = block->prev_block; - for (i=0; in; i++) - { - height = (bundle->height + 1 + i); - bundle->blocks[i].prev_block = prevhash2; - bundle->blocks[i].hash2 = req->blockhashes[i]; - prevhash2 = req->blockhashes[i]; - if ( (height % coin->chain->bundlesize) == 0 ) - iguana_bundleinit(coin,height,req->blockhashes[i]); - } - printf("initialized bundlei.%d %d\n",bundle->bundlei,bundle->height); - } - portable_mutex_unlock(&bundle->mutex); - } else printf("couldnt find matching bundle for %s\n",bits256_str(block->prev_block)); - myfree(req->blockhashes,req->n * sizeof(*req->blockhashes)); - myfree(req,sizeof(*req)); - } else printf("unexpected missing blockhashes.%p\n",req->blockhashes); - } else printf("unexpected hash2 mismatch with height.%d\n",block->height); - } - else - { - if ( bundle == 0 ) - { - printf("cant find bundle.(%s)\n",bits256_str(block->hash2)); - return; - } - if ( height > bundle->height && height <= bundle->height+bundle->num ) - { - h = height - bundle->height - 1; - portable_mutex_lock(&bundle->mutex); - if ( bundle->numvalid < bundle->num && bundle->txdata[h] == 0 ) - { - bundle->blocks[h] = *block; - if ( iguana_recvblockptr(coin,height) == &bundle->txdata[h] && bundle->txdata[h] == 0 ) - { - bundle->txdata[h] = txarray, bundle->numtxs[h] = numtx; - coin->blocks.numblocks++; - //if ( (rand() % 100) == 0 ) - printf("GOT.%d | received.%d total.%d | %.2f minutes\n",height,coin->blocks.recvblocks,coin->blocks.numblocks,(double)(now - coin->starttime)/60.); - txarray = 0; - if ( ++bundle->numvalid == bundle->num ) - { - bundle->recvfinish = now; - bundle->lastduration = (bundle->recvfinish - bundle->recvstart); - dxblend(&coin->R.avetime,bundle->lastduration,.9); - if ( bundle->lastduration < coin->R.avetime ) - coin->R.faster++; - else coin->R.slower++; - if ( coin->R.faster > 3*coin->R.slower || coin->R.slower > 3*coin->R.faster ) - { - dir = (coin->R.maxrecvbundles - coin->R.prevmaxrecvbundles); - if ( coin->R.slower >= coin->R.faster ) - dir = -dir; - if ( dir > 0 ) - dir = 1; - else if ( coin->R.maxrecvbundles > 2 ) - dir = -1; - else dir = 0; - printf("(%d vs %f) faster.%d slower.%d -> dir.%d apply -> %d\n",bundle->lastduration,coin->R.avetime,coin->R.faster,coin->R.slower,dir,coin->R.maxrecvbundles + dir); - coin->R.prevmaxrecvbundles = coin->R.maxrecvbundles; - coin->R.maxrecvbundles += dir; - coin->R.slower = coin->R.faster = 0; - } - coin->R.finishedbundles++; - printf("submit emit.%d height.%d\n",bundle->bundlei,bundle->height); - queue_enqueue("emitQ",&coin->emitQ,&bundle->DL,0); - } - else - { - if ( coin->R.waitstart[height] > 0 ) - { - if ( bundle->firstblocktime == 0 ) - bundle->firstblocktime = now; - bundle->durationsum += (now - coin->R.waitstart[height] + 1); - bundle->aveduration = (bundle->durationsum / bundle->numvalid); - } - } - } else printf("recvblockptr error? height.%d %p %p h.%d\n",height,iguana_recvblockptr(coin,height),&bundle->txdata[h],h); - } else if ( (rand() % 1000) == 0 ) - printf("interloper! already have txs[%d] for bundlei.%d\n",h,bundle!=0?bundle->height:-1); - portable_mutex_unlock(&bundle->mutex); - } else printf("height.%d outside range of bundlei.%d %d\n",height,bundle!=0?bundle->height:-1,bundle!=0?bundle->height:-1); - } - //iguana_waitclear(coin,block->height); - if ( 1 && (rand() % 1000) == 0 ) - printf("%-15s pend.(%d %d) got block.%-6d recvblocks %-8.0f recvtotal %-10.0f\n",addr->ipaddr,addr->pendhdrs,addr->pendblocks,block->height,addr->recvblocks,addr->recvtotal); - } - if ( txarray != 0 ) - iguana_freetx(txarray,numtx); - myfree(block,sizeof(*block)); - }*/ - - - /* - if ( (bp= iguana_bundleinit(coin,-1,blocks[0].prev_block)) != 0 ) - { - if ( n > coin->chain->bundlesize ) - printf("warning: %s gotheaders.%d is too many vs. %d\n",coin->symbol,n,coin->chain->bundlesize); - portable_mutex_lock(&bundle->mutex); - if ( bundle->blocks == 0 ) - { - bundle->num = n; - bundle->blocks = blocks; - bundle->firsthash2 = blocks[0].hash2; - bundle->lasthash2 = blocks[n-1].hash2; - for (i=0; iheight + i + 1); - iguana_gotdata(coin,addr,blocks[i].height,blocks[i].hash2); - if ( (blocks[i].height % coin->chain->bundlesize) == 0 ) - iguana_bundleinit(coin,blocks[i].height,blocks[i].hash2); - } - printf("%s set bundle.%d %s\n",addr->ipaddr,bundle->height,bits256_str(blocks[0].prev_block)); - } - portable_mutex_unlock(&bundle->mutex); - } else printf("ERROR iguana_gotheaders got bundle.(%s) n.%d that cant be found?\n",bits256_str(blocks[0].prev_block),n); - }*/ - - int32_t iguana_updatehdrs(struct iguana_info *coin) - { - int32_t flag = 0; - int32_t i,j,m,height,run,flag = 0; uint32_t now; struct iguana_bundle *bundle; - if ( iguana_needhdrs(coin) == 0 ) - return(flag); - now = (uint32_t)time(NULL); - run = -1; - for (i=0; iR.numbundles; i++) - { - if ( i*coin->chain->bundlesize > coin->longestchain ) - break; - bundle = &coin->R.bundles[i]; - if ( bundle->blocks != 0 ) - { - if ( bundle->recvstart == 0 ) - { - if ( (coin->R.startedbundles - coin->R.finishedbundles) < coin->R.maxrecvbundles ) - { - iguana_queuebundle(coin,bundle); - bundle->recvstart = now; - coin->R.startedbundles++; - printf("startbundle.%d (%d - %d)\n",bundle->height,coin->R.startedbundles,coin->R.finishedbundles); - flag++; - } - } - else if ( bundle->recvfinish == 0 ) - { - for (j=m=0; jnum; j++) - { - height = bundle->height+j+1; - if ( iguana_recvblock(coin,height) != 0 ) - m++; - else if ( coin->R.waitstart[height] > 0 ) - { - duration = (now - coin->R.waitstart[height]); - if ( duration > 60 || (duration > 10 && bundle->numvalid > 13 && duration > 3.*bundle->aveduration) ) - { - if ( now > bundle->lastdisp+15 ) - printf("height.%d in bundle.%d duration.%d vs ave %.3f\n",height,bundle->height,duration,bundle->aveduration); - iguana_waitclear(coin,height); - iguana_waitstart(coin,height,bundle->blocks[j].hash2,1); - } - } - else if ( bundle->firstblocktime > 0 && (now - bundle->firstblocktime) > 60 ) - { - if ( now > bundle->lastdisp+15 ) - printf("height.%d in bundle.%d ave %.3f\n",height,bundle->height,bundle->aveduration); - iguana_waitclear(coin,height); - iguana_waitstart(coin,height,bundle->blocks[j].hash2,1); - bundle->firstblocktime = now; - } - } - if ( 0 && now > bundle->lastdisp+15 ) - { - printf("bundle.%d (%d %d) elapsed.%d (%d - %d) %d | %.2f minutes\n",bundle->bundlei,bundle->height,m,(int32_t)(now - bundle->recvstart),coin->R.startedbundles,coin->R.finishedbundles,coin->R.maxrecvbundles,(double)(now - coin->starttime)/60.); - bundle->lastdisp = now; - } - } - else if ( run == i-1 ) - run++; - } - } - //iguana_lookahead(coin,&hash2,0); - return(flag); - }*/ - - /*struct iguana_block *iguana_block(struct iguana_info *coin,struct iguana_block *space,int32_t height) - { - if ( height <= coin->blocks.hwmheight ) - { - if ( iguana_kvread(coin,coin->blocks.db,0,space,(uint32_t *)&height) != 0 ) - { - if ( bits256_nonz(space->hash2) != 0 ) - return(space); - if ( height < coin->blocks.hwmheight ) - { - printf("height.%d null blockhash? prev.%s\n",height,bits256_str(space->prev_block)); - getchar(); - } - return(0); - } else printf("error doing RWmmap\n"); - } - //printf("iguana_block hwmheight.%d vs height.%d\n",coin->blocks.hwmheight,height); - return(0); - } - - struct iguana_block *iguana_findblock(struct iguana_info *coin,struct iguana_block *space,bits256 hash2) - { - struct iguana_block *block = 0; uint32_t itemind; - if ( bits256_nonz(hash2) != 0 ) - { - block = iguana_kvread(coin,coin->blocks.db,hash2.bytes,space,&itemind); - //printf("iguana_findblock block.%p itemind.%d\n",block,itemind); - if ( block == 0 || itemind != block->height ) - { - if ( block != 0 && block->height != itemind ) - { - printf("iguana_findblock (%s) error itemind.%d vs %d block.%p\n",bits256_str(hash2),itemind,block!=0?block->height:-1,block); - getchar(); - } - return(0); - } - } - return(block); - }*/ - struct iguana_bundle *iguana_bundlefindprev(struct iguana_info *coin,int32_t *heightp,bits256 prevhash2) - { - struct iguana_block *block; - *heightp = -1; - if ( (block= iguana_blockfind(coin,prevhash2)) != 0 ) - { - *heightp = block->hh.itemind; - if ( block->bundle == 0 ) - { - if ( *heightp == 0 ) - block->bundle = coin->B[0]; - else block->bundle = coin->B[(block->hh.itemind - 1) / coin->chain->bundlesize]; - } - return(block->bundle); - } - else return(0); - } - - /*int32_t iguana_bundleset(struct iguana_info *coin,int32_t origheight,bits256 hash2) - { - int32_t bundlei,blocki,height = origheight; struct iguana_bundle *bp = 0; - //printf("bundleset.(%d %s)\n",height,bits256_str(hash2)); - if ( (height % coin->chain->bundlesize) == 0 && height > 0 ) - { - iguana_blockhashset(coin,origheight,hash2,0); - return(0); - } - if ( (bundlei= iguana_bundlei(coin,&blocki,height)) >= 0 && bundlei >= 0 && (bp= coin->B[bundlei]) != 0 ) - { - if ( height > bp->height && height < bp->height+bp->num ) - { - if ( iguana_blockhashset(coin,origheight,hash2,bp) != 0 ) - { - return(0); - } - printf("iguana_bundleset error setting bundle height.%d %s\n",height,bits256_str(hash2)); - } else printf("iguana_bundleset illegal height.%d for bundle.%d\n",height,bp->height); - } else printf("iguana_bundleset illegal height.%d bundlei.%d blocki.%d bp.%p\n",height,bundlei,blocki,bp); - return(-1); - }*/ - - /*int32_t iguana_bundlei(struct iguana_info *coin,int32_t *blockip,int32_t height) - { - int32_t bundlei; - *blockip = -1; - if ( height <= 0 || height > coin->R.numwaitingbits ) - return(-1); - height--; - *blockip = (height % coin->chain->bundlesize); - if ( (bundlei= (height / coin->chain->bundlesize)) < IGUANA_MAXBUNDLES ) - return(bundlei); - else return(-1); - } - - void **iguana_recvblockptr(struct iguana_info *coin,int32_t *blockip,int32_t height) - { - int32_t bundlei; struct iguana_bundle *bp; - if ( (bundlei= iguana_bundlei(coin,blockip,height)) >= 0 ) - { - if ( (bp= coin->B[bundlei]) != 0 ) - return(&bp->txdata[*blockip]); - } - return(0); - }*/ - - /*struct iguana_bundle *iguana_bundleinit(struct iguana_info *coin,int32_t height,bits256 hash2) - { - int32_t bundlei,blocki; struct iguana_bundle *bp = 0; - if ( height < 0 || (height % coin->chain->bundlesize) != 0 ) - { - printf("bundleinit error: height.%d %s\n",height,bits256_str(hash2)); - return(bp); - } - portable_mutex_lock(&coin->bundles_mutex); - if ( (bundlei= iguana_bundlei(coin,&blocki,height+1)) >= 0 ) - { - if ( (bp= coin->B[bundlei]) != 0 ) - { - if ( memcmp(hash2.bytes,bp->prevhash2.bytes,sizeof(hash2)) != 0 ) - { - if ( bits256_nonz(hash2) > 0 ) - { - if ( bits256_nonz(bp->prevhash2) > 0 ) - { - printf("bundleinit[%d]: %d hash conflict have %s, got %s\n",bp->bundlei,bp->height,bits256_str(bp->prevhash2),bits256_str2(hash2)); - //getchar(); - portable_mutex_unlock(&coin->bundles_mutex); - return(0); - } - bp->prevhash2 = hash2; - iguana_blockhashset(coin,height,hash2,1); - printf("bundleinit: set starting hash.(%s) for %d\n",bits256_str(hash2),bp->height); - } - } - } - else - { - bp = mycalloc('b',1,sizeof(*bp)); - coin->B[bundlei] = bp; // cant change values once set to nonzero - bp->prevhash2 = hash2; - bp->bundlei = bundlei; - bp->hasheaders = coin->chain->hasheaders; - bp->num = coin->chain->bundlesize; - bp->height = (bundlei * coin->chain->bundlesize); - bp->starttime = (uint32_t)time(NULL); - if ( bits256_nonz(hash2) > 0 ) - { - iguana_blockhashset(coin,height,hash2,1); - printf("created bundle.%d: %s coin->B[%d] <- %p\n",height,bits256_str(hash2),bundlei,bp); - } - } - } - portable_mutex_unlock(&coin->bundles_mutex); - return(bp); - }*/ - int32_t iguana_waitstart(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t priority) - { - if ( height < 0 || iguana_recvblock(coin,height) == 0 ) - return(iguana_queueblock(coin,height,hash2,priority)); - else if ( height < coin->maxblockbits ) - printf("iguana_waitstart ignore height.%d < %d, %p GETBIT.%d\n",height,coin->maxblockbits,iguana_recvblock(coin,height),GETBIT(coin->R.waitingbits,height)); - return(0); - } - - int32_t iguana_waitclear(struct iguana_info *coin,int32_t height) - { - if ( height < coin->maxblockbits ) - { - //printf("%d waitclear.%d parsed.%d\n",coin->R.numwaiting,height,coin->blocks.recvblocks); - if ( coin->R.numwaiting > 0 ) - coin->R.numwaiting--; - coin->R.waitstart[height] = 0; - CLEARBIT(coin->R.waitingbits,height); - return(0); - } - return(-1); - } - - int32_t iguana_updatewaiting(struct iguana_info *coin,int32_t starti,int32_t max) - { - int32_t i,height,gap,n = 0; uint32_t now; - now = (uint32_t)time(NULL); - height = starti; - iguana_waitclear(coin,height); - iguana_waitstart(coin,height,coin->R.blockhashes[height],1); - for (i=0; iblocks.recvblocks); - if ( gap >= 0 ) - gap = sqrt(gap); - if ( gap < 13 ) - gap = 13; - if ( height < coin->maxblockbits && iguana_recvblock(coin,height) == 0 && now > (coin->R.waitstart[height] + gap) && memcmp(bits256_zero.bytes,coin->R.blockhashes[height].bytes,sizeof(bits256)) != 0 ) - { - //printf("restart height.%d width.%d widthready.%d %s\n",height,coin->width,coin->widthready,bits256_str(coin->R.blockhashes[height])); - iguana_waitclear(coin,height); - iguana_waitstart(coin,height,coin->R.blockhashes[height],0); - } //else printf("%d %d %p %u\n",height,coin->maxblockbits,coin->R.recvblocks[height],coin->R.waitstart[height]); - } - //printf("height.%d max.%d\n",starti,max); - height = starti; - for (i=0; iwidth = width = 4*sqrt(coin->longestchain - coin->blocks.recvblocks); - if ( coin->width < 0 ) - width = 500; - coin->widthready = 0; - coin->width = 5000; - //printf("width.%d\n",width); - while ( iguana_recvblock(coin,coin->blocks.recvblocks) != 0 ) - { - coin->blocks.recvblocks++; - //printf("RECV.%d\n",coin->blocks.recvblocks); - } - while ( width < (coin->longestchain - coin->blocks.recvblocks) ) - { - w = iguana_updatewaiting(coin,coin->blocks.recvblocks,width); - //printf("w%d ",w); - if ( width == coin->width ) - coin->widthready = w; - //else - break; - width <<= 1; - if ( width >= coin->longestchain-coin->blocks.recvblocks ) - width = coin->longestchain-coin->blocks.recvblocks-1; - if ( (rand() % 100) == 0 && width > (coin->width<<2) ) - printf("coin->width.%d higher width.%d all there, w.%d\n",coin->width,width,w); - } - return((uint32_t)time(NULL)); - } - int32_t iguana_connectsocket(int32_t blockflag,struct iguana_peer *A,struct sockaddr *addr,socklen_t addr_len) - { - int32_t opt,flags; struct timeval timeout; //,val = 65536*2 - if ( A->usock >= 0 ) - { - printf("iguana_connectsocket: (%s) already has usock.%d\n",A->ipaddr,A->usock); - return(-1); - } - if ( A->ipv6 != 0 ) - A->usock = socket(AF_INET6,SOCK_STREAM,IPPROTO_TCP); - else A->usock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - if ( A->usock >= 0 ) - { - //setsockopt(A->usock,SOL_SOCKET,SO_SNDBUF,&val,sizeof(val)); - //setsockopt(A->usock,SOL_SOCKET,SO_RCVBUF,&val,sizeof(val)); - timeout.tv_sec = 0; - timeout.tv_usec = 1000; - setsockopt(A->usock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); - setsockopt(A->usock,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)); - opt = 1; - setsockopt(A->usock,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt)); - //retval = setsockopt(A->usock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); - //printf("nosigpipe retval.%d\n",retval); - if ( blockflag != 0 || ((flags= fcntl(A->usock,F_GETFL,0)) >= 0 && fcntl(A->usock,F_SETFL,flags|O_NONBLOCK) >= 0) ) - { - if ( connect(A->usock,addr,addr_len) >= 0 || errno == EINPROGRESS ) - return(A->usock); - else fprintf(stderr,"usock %s connect -> errno.%d\n",A->ipaddr,errno); - }// else fprintf(stderr,"usock %s fcntl -> flags.%d errno.%d",ipaddr,flags,errno); - } else fprintf(stderr,"usock %s -> errno.%d\n",A->ipaddr,errno); - return(-errno); - } - - int32_t iguana_connect(struct iguana_info *coin,struct iguana_peer *addrs,int32_t maxaddrs,char *ipaddr,uint16_t default_port,int32_t connectflag) - { - struct sockaddr *addr; struct sockaddr_in6 saddr6; struct sockaddr_in saddr4; uint32_t ipbits; - struct addrinfo hints,*res; socklen_t addr_len; struct addrinfo *ai; int32_t retval = -1,status,n = 0; - addrs[n].usock = -1; - memset(&hints,0,sizeof(hints)); - memset(&saddr6,0,sizeof(saddr6)); - memset(&saddr4,0,sizeof(saddr4)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - //printf("getaddrinfo\n"); - if ( getaddrinfo(ipaddr,NULL,&hints,&res)) - { - printf("cant get addrinfo for (%s)\n",ipaddr); - return(-1); - } - for (ai=res; ai!=NULL&&nai_next) - { - if ( ai->ai_family == AF_INET6 ) - { - struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)ai->ai_addr; - memcpy(&addrs[n].A.ip,&saddr->sin6_addr,16); - memset(&saddr6,0,sizeof(saddr6)); - saddr6.sin6_family = AF_INET6; - memcpy(&saddr6.sin6_addr.s6_addr,&addrs[n].A.ip[0],16); - saddr6.sin6_port = htons(default_port); - addrs[n].ipv6 = 1; - addr = (struct sockaddr *)&saddr6; - addr_len = sizeof(saddr6); - } - else if ( ai->ai_family == AF_INET ) - { - struct sockaddr_in *saddr = (struct sockaddr_in *)ai->ai_addr; - memset(&addrs[n].A.ip[0],0,10); - memset(&addrs[n].A.ip[10],0xff,2); - memcpy(&addrs[n].A.ip[12],&saddr->sin_addr,4); - memset(&saddr4,0,sizeof(saddr4)); - saddr4.sin_family = AF_INET; - memcpy(&saddr4.sin_addr.s_addr,&addrs[n].A.ip[12],4); - saddr4.sin_port = htons(default_port); - addrs[n].ipv6 = 0; - addr = (struct sockaddr *)&saddr4; - addr_len = sizeof(saddr4); - } else return(-1); - addrs[n].A.nTime = (uint32_t)(time(NULL) - (24 * 60 * 60)); - addrs[n].A.port = default_port; - strcpy(addrs[n].ipaddr,ipaddr); - addrs[n].A.nServices = 0; - n++; - if ( connectflag != 0 ) - { - ipbits = (uint32_t)calc_ipbits(ipaddr); - addrs[n].usock = -1; - addrs[n].ipbits = ipbits; - strcpy(addrs[n].ipaddr,ipaddr); - //printf("call connectsocket\n"); - if ( (addrs[n].usock= iguana_connectsocket(connectflag > 1,&addrs[n],addr,addr_len)) < 0 ) - { - status = IGUANA_PEER_KILLED; - printf("refused PEER STATUS.%d for %s usock.%d\n",status,ipaddr,retval); - iguana_iAkill(coin,&addrs[n],1); - if ( iguana_rwipbits_status(coin,1,ipbits,&status) == 0 ) - printf("error updating status.%d for %s\n",status,ipaddr); - } - else - { - status = IGUANA_PEER_READY; - printf("CONNECTED! PEER STATUS.%d for %s usock.%d\n",status,ipaddr,addrs[n].usock); - iguana_iAconnected(coin,&addrs[n]); - if ( iguana_rwipbits_status(coin,1,ipbits,&status) == 0 ) - printf("error updating status.%d for %s\n",status,ipaddr); - else retval = addrs[n].usock; - } - break; - } - } - freeaddrinfo(res); - return(retval); - } - - /*if ( (fp= fopen(fname,"r")) != 0 ) - { - if ( fgets(line,sizeof(line),fp) > 0 ) - { - line[strlen(line)-1] = 0; - if ( atoi(line) > coin->blocks.hashblocks ) - { - //printf("skip save since %s has %d\n",fname,atoi(line)); - fclose(fp); - return(0); - } - } - fclose(fp); - }*/ - - /*struct iguana_bundle - { - struct queueitem DL; portable_mutex_t mutex; - char fname[512]; struct iguana_mappedptr M; - void *txdata[_IGUANA_HDRSCOUNT]; int32_t numtxs[_IGUANA_HDRSCOUNT]; - struct iguana_counts presnapshot,postsnapshot; - int32_t bundlei,height,num,hasheaders,numvalid,havehashes; - uint32_t starttime,emitstart,emitfinish,lastdisp; - bits256 prevhash2,firsthash2,lasthash2; - //double durationsum,aveduration; - //struct iguana_block *blocks; - };*/ - - /*struct iguana_recv - { - //uint8_t compressed[IGUANA_MAXPACKETSIZE],decompressed[IGUANA_MAXPACKETSIZE],checkbuf[IGUANA_MAXPACKETSIZE]; - long srcdatalen,compressedtotal; //uint64_t histo[0x100]; - struct iguana_memspace RSPACE,*oldRSPACE; int32_t numold; - int64_t packetsallocated,packetsfreed; int32_t numwaiting,maprecvdata; - uint8_t *waitingbits; uint32_t numwaitingbits,*waitstart; //struct iguana_pending **recvblocks; - int32_t topheight,pendingtopheight; - uint32_t pendingtopstart,numbundles,lasthdrtime,startedbundles,finishedbundles; - bits256 tophash2; - //int32_t prevmaxrecvbundles,maxrecvbundles,faster,slower; double avetime; - }; - - struct iguana_pending - { - int32_t next,numtx,datalen,origdatalen; struct iguana_block block; uint32_t allocsize,ipbits; uint8_t data[]; - };*/ - //struct iguana_recv R; - //struct iguana_bundle *B[IGUANA_MAXBUNDLES]; - //struct iguana_blockhashes pendings[1024]; - /* int32_t height; - height = iguana_blockheight(coin,blockhashes[0]); - if ( n > 2 && iguana_needhdrs(coin) > 0 ) - { - //printf("got blockhashes[%d] %s height.%d\n",n,bits256_str(blockhashes[0]),height); - if ( height >= 0 ) - { - for (j=0; jchain->bundlesize && height+jlongestchain; j++) - { - iguana_bundleset(coin,height+j,blockhashes[j]); - iguana_gotdata(coin,0,height+j,blockhashes[j],j,n); - } - } - else - { - iguana_queueblock(coin,-1,blockhashes[0],1); - for (i=0; inumpendings; i++) - if ( memcmp(coin->pendings[i].blockhashes[0].bytes,blockhashes[0].bytes,sizeof(bits256)) == 0 ) - break; - if ( i == coin->numpendings ) - { - if ( coin->numpendings < sizeof(coin->pendings)/sizeof(*coin->pendings) ) - { - coin->pendings[coin->numpendings].blockhashes = blockhashes; - coin->pendings[coin->numpendings].n = n; - coin->pendings[coin->numpendings].starttime = (uint32_t)time(NULL); - coin->numpendings++; - printf("ADD to numpendings.%d priority.(%s) n.%d\n",coin->numpendings,bits256_str(blockhashes[0]),n); - blockhashes = 0; - } else printf("updatebundles: overflowed pendings\n"); - } - } - }*/ - - /* if ( iguana_bundlefindprev(coin,&height,blocks[0].prev_block) != 0 && height >= 0 ) - { - //printf(">>>>>> found %s height.%d n.%d\n",bits256_str(blocks[0].prev_block),height,n); - height++; - for (i=0; ichain->bundlesize && heightlongestchain; i++,height++) - { - //printf("i.%d height.%d\n",i,height); - iguana_bundleset(coin,height,blocks[i].hash2); - iguana_gotdata(coin,req->addr,height,blocks[i].hash2,i,n); - if ( height >= coin->blocks.hwmheight ) - { - if ( height == coin->blocks.hwmheight ) - (*newhwmp)++; - if ( (block= iguana_block(coin,height)) != 0 ) - iguana_mergeblock(block,&blocks[i]); - else printf("unexpected null block at height.%d\n",height), getchar(); - } - else - { - // verify it doesnt trigger reorg (and is recent enough!) - } - } - } else printf("unexpected bundlefind error %s height.%d\n",bits256_str(blocks[0].prev_block),height), getchar(); - */ - - /* int32_t height; - //printf("%s got block.(%s) height.%d\n",req->addr!=0?req->addr->ipaddr:"local",bits256_str(block->hash2),height); - if ( (height= iguana_bundleheight(coin,block)) > 0 ) - { - if ( (ptrp= iguana_blockptrptr(coin,&blocki,height)) != 0 ) - { - if ( (*ptrp) == 0 ) - { - //printf("height.%d tx.%p blocki.%d txarray.%p[%d] (%p[%d] %p[%d])\n",height,&txarray[0],blocki,txarray,numtx,txarray[0].vouts,txarray[0].tx_out,txarray[0].vins,txarray[0].tx_in); - (*ptrp) = (void *)txarray; - bp->numtxs[blocki] = numtx; - if ( bp->emitstart == 0 && ++bp->numvalid >= bp->num ) - { - bp->emitstart = (uint32_t)time(NULL); - iguana_emittxdata(coin,bp); - //printf("queue txarray.%p[%d]\n",txarray,numtx); - //queue_enqueue("emitQ",&coin->emitQ,&bp->DL,0); - } - //txarray = 0; - } - } - else printf("cant get ptrp.%d\n",height), getchar(); - iguana_gotdata(coin,req->addr,height,block->hash2,0,0); - if ( bp != 0 && iguana_bundleready(coin,height-1) <= 0 ) - { - printf("check for pendings.%d height.%d\n",coin->numpendings,height); - if ( height == coin->blocks.hwmheight ) - (*newhwmp)++; - for (i=0; inumpendings; i++) - if ( memcmp(coin->pendings[i].blockhashes[0].bytes,block->hash2.bytes,sizeof(block->hash2)) == 0 ) - { - blockhashes = coin->pendings[i].blockhashes; - n = coin->pendings[i].n; - printf("pending[%d].%d bundlesets[%d] %d %s\n",i,coin->numpendings,n,height,bits256_str(blockhashes[0])); - for (j=0; jchain->bundlesize && height+jlongestchain; j++) - { - iguana_bundleset(coin,height+j,blockhashes[j]); - iguana_gotdata(coin,0,height+j,blockhashes[j],j,n); - } - myfree(blockhashes,n * sizeof(*blockhashes)); - coin->pendings[i] = coin->pendings[--coin->numpendings]; - break; - } - // queue tx for processing - } - else - { - // probably new block - //printf("couldnt find.(%s)\n",bits256_str(block->hash2)); - } - }*/ - //if ( height >= 0 ) - // coin->blocks.ptrs[height] = block; - //printf("found.%s -> %s %d %p inputht.%d\n",bits256_str(hash2),bits256_str(block->hash2),block->hh.itemind,block,height); - if ( height < 0 || block->hh.itemind == height ) - { - if ( (int32_t)block->hh.itemind < 0 ) - { - //printf("found.%s -> %d %p set height.%d matches.%d\n",bits256_str(hash2),block->hh.itemind,block,height,block->matches); - if ( height >= 0 && block->matches == 0 ) - block->hh.itemind = height, block->matches = 1; - else block = 0; - } - if ( block != 0 ) - { - if ( block->matches < 100 ) - block->matches++; - //_iguana_blocklink(coin,block); - } - } - else if ( block->matches == 0 && block->hh.itemind == (uint32_t)-1 ) - { - if ( height >= 0 ) - { - if ( (rand() % 10000) == 0 ) - printf("set %s.itemind <- %d\n",bits256_str(hash2),height); - block->hh.itemind = height; - block->matches = 1; - } - else - { - printf("matches.%d itemind.%d when height.%d\n",block->matches,block->hh.itemind,height); - block = 0; - } - } - else - { - /*if ( block->matches < 100 ) - { - block->matches >>= 1; - if ( block->matches == 0 ) - { - //printf("collision with (%s) itemind.%d vs %d | matches.%d\n",bits256_str(hash2),block->hh.itemind,height,block->matches); - block->hh.itemind = -1; - for (i=0; i<1; i++) - iguana_queueblock(coin,-1,block->hash2,1); - block = 0; - //coin->blocks.recvblocks = 0; - } - } else block = 0;*/ - } - - /*int32_t iguana_blockheight(struct iguana_info *coin,struct iguana_block *block) - { - int32_t height; - if ( (height= iguana_itemheight(coin,block->hash2)) < 0 ) - { - if ( (height= iguana_itemheight(coin,block->prev_block)) < 0 ) - { - iguana_blockhashset(coin,-1,block->hash2,1); - iguana_blockhashset(coin,-1,block->prev_block,1); - } - else - { - height++; - iguana_blockhashset(coin,height,block->hash2,1); - } - } else iguana_blockhashset(coin,height,block->hash2,1); // increments matches - return(height); - }*/ - if ( (height= iguana_itemheight(coin,blockhashes[0])) >= 0 ) - { - if ( iguana_needhdrs(coin) > 0 && iguana_havetxdata(coin,h) == 0 ) - iguana_queueblock(coin,height,blockhashes[0],1); - } - else if ( iguana_needhdrs(coin) > 0 && iguana_havetxdata(coin,h) == 0 ) - iguana_queueblock(coin,-1,blockhashes[0],1); - //printf("check.%s height.%d\n",bits256_str(blockhashes[0]),height); - for (i=0; i= 0 ) - h = height++; - permblock = iguana_blockhashset(coin,h,blockhashes[i],1); - if ( h >= 0 && permblock != 0 ) - { - if ( iguana_blockptr(coin,h) == 0 ) - { - coin->blocks.ptrs[h] = permblock; - { - int32_t j,m; - for (j=m=0; jlongestchain; j++) - if ( iguana_blockptr(coin,j) != 0 ) - m++; - printf("set (%s) <- %d %p m.%d\n",bits256_str(blockhashes[i]),h,permblock,m); - } - } - if ( permblock->hh.itemind != h ) - permblock->hh.itemind = h; - } - if ( i == coin->chain->bundlesize-1 ) - { - init_hexbytes_noT(hashstr,blockhashes[i].bytes,sizeof(blockhashes[i])); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - } - //else //if ( h >= 0 ) printf("unexpected missing permblock for h.%d\n",h); - // iguana_queueblock(coin,-1,blockhashes[i],0); - } - for (i=m=run=0; i= 0 ) - { - if ( run == i && (i == 0 || height == height0+i) ) - run++; - if ( (block= iguana_blockfind(coin,blockhashes[i])) != 0 && block == blocks[i] && block->mainchain == 0 ) - { - if ( block->hh.itemind != height && wt > block->matches ) - { - printf("%p[%d] <- %d matches.%d wt.%d vs matches.%d\n",block,block->hh.itemind,height,block->matches,wt,block->matches); - if ( block->matches < 100 ) - { - block->matches = 1; - block->hh.itemind = height; - } - else printf("height conflict for %s\n",bits256_str(blockhashes[i])); - } - } else blocks[i] = 0; - if ( i == 0 ) - height0 = height; - height -= i; - if ( m > 0 ) - { - for (j=0; j %d\n",j,m,wt,heightwts[j][1]); - break; - } - } - } else j = 0; - if ( j == m ) - { - heightwts[m][0] = height; - heightwts[m][1] = wt; - m++; - } - } - printf("i.%d j.%d m.%d height.%d wt.%d %s\n",i,j,m,height,wt,bits256_str(blockhashes[0])); - } - nlinks = plinks = 0; - if ( m > 0 ) - { - if ( m == 1 && height0 >= 0 ) - { - wt = (heightwts[0][1] / num) + 2; - for (i=0; ihh.next == 0 || prev->matches < wt ) - prev->hh.next = blocks[0]; - } - for (i=plinks=nlinks=0; ihh.itemind < 0 || block->matches < wt ) - { - block->hh.itemind = height0 + i; - block->matches = (wt < 100) ? wt : 100; - SETBIT(coin->havehash,height0 + i); - //iguana_blockhashset(coin,height0 + i,blockhashes[i],(wt < 100) ? wt : 100); - } - if ( (block->hh.prev == 0 || block->matches < wt) && block->hh.prev != prev ) - block->hh.prev = prev, plinks++; - if ( (block->hh.next == 0 || block->matches < wt) && block->hh.next != next ) - block->hh.next = next, nlinks++; - if ( block->matches < 100 ) - block->matches++; - } else printf("recvblockhashes: blocks[%d] null\n",i); - prev = block; - } - if ( next != 0 && (next->hh.prev == 0 || next->matches < wt) ) - next->hh.prev = prev; - } else printf("recvblockhashes: i.%d != num.%d\n",i,num); - } - if ( height0 >= 0 && 0 ) - { - for (i=0; i= 0 ) - { - if ( i == 0 ) - height0 = height, block0 = block; - m++; - //printf("height %d, wt %d itemind.%d matches.%d\n",height,wt,block->hh.itemind,block->matches); - if ( (int32_t)block->hh.itemind < 0 || block->matches*3 < wt ) - { - SETBIT(coin->havehash,height); - block->hh.itemind = height; - block->matches = (wt/3) + 1; - } - if ( prev != 0 && ((int32_t)prev->hh.itemind < 0 || prev->matches*3 < wt) ) - { - SETBIT(coin->havehash,height - 1); - prev->hh.itemind = height - 1; - prev->matches = (wt/3) + 1; - } - if ( next != 0 && ((int32_t)next->hh.itemind < 0 || next->matches*3 < wt) ) - { - SETBIT(coin->havehash,height + 1); - next->hh.itemind = height + 1; - next->matches = (wt/3) + 1; - } - } - } - prev = block; - } - if ( m >= coin->chain->bundlesize && height0 >= 0 && block != 0 ) - { - printf("gothdr.%d oldgothdr.%d %p %d <- %p\n",height0,block->gothdrs,coin->blocks.ptrs[height0],coin->blocks.ptrs[height0]!=0?coin->blocks.ptrs[height0]->hh.itemind:0,block); - coin->blocks.ptrs[height0] = block; - block->gothdrs = 1; - } - int32_t i,m,height,wt,height0 = -1; struct iguana_block *block,*next,*prev,*block0 = 0; - - int32_t iguana_blockmetric(struct iguana_info *coin,int32_t *wtp,struct iguana_block *block) - { - int32_t height = -1; int64_t wt; - if ( block->mainchain != 0 && block->height >= 0 ) - { - height = block->height; - wt = ((int64_t)coin->blocks.hwmheight - block->height) * 10000; - if ( wt > (1 << 28)/_IGUANA_HDRSCOUNT ) - wt = (1 << 28) / _IGUANA_HDRSCOUNT; - (*wtp) += (int32_t)wt; - } - else if ( block->height >= 0 ) - { - height = block->height; - (*wtp) += 10; - } - else if ( (int32_t)block->hh.itemind >= 0 ) - { - height = block->hh.itemind; - (*wtp) += block->matches; - } - return(height); - } - - int32_t iguana_heightwt(struct iguana_info *coin,int32_t *wtp,struct iguana_block *prev,struct iguana_block *block,struct iguana_block *next) - { - int32_t heightwts[3][2],height,i,n = 0; - *wtp = 0; - height = -1; - memset(heightwts,0,sizeof(heightwts)); - if ( block != 0 ) - { - if ( (heightwts[1][0]= iguana_blockmetric(coin,&heightwts[1][1],block)) >= 0 ) - n++; - //printf("%s itemind.%d matches.%d ht.%d metric.%d n.%d\n",bits256_str(hash2),block->hh.itemind,block->matches,heightwts[1][0],heightwts[1][1],n); - if ( prev != 0 )//|| (prev= block->hh.prev) != 0 ) - { - if ( (heightwts[0][0]= iguana_blockmetric(coin,&heightwts[0][1],prev)) >= 0 ) - { - //printf("heightwts(%d + 1) vs %d\n",heightwts[0][0],heightwts[1][0]); - if ( heightwts[0][0]+1 == heightwts[1][0] ) - n++; - else n--, heightwts[0][0] = -1; - } - //printf("%s itemind.%d matches.%d ht.%d metric.%d n.%d\n",bits256_str(prev->hash2),prev->hh.itemind,prev->matches,heightwts[0][0],heightwts[0][1],n); - } - if ( next != 0 )//(next= block->hh.prev) != 0 && next != block ) - { - if ( (heightwts[2][0]= iguana_blockmetric(coin,&heightwts[2][1],next)) >= 0 ) - { - if ( heightwts[2][0]-1 == heightwts[1][0] ) - n++; - else n--, heightwts[2][0] = -1; - } - //printf("%s itemind.%d matches.%d ht.%d metric.%d n.%d\n",bits256_str(next->hash2),next->hh.itemind,next->matches,heightwts[2][0],heightwts[2][1],n); - } - if ( n > 0 ) - { - for (i=0; i<3; i++) - if ( heightwts[i][0] >= 0 ) - (*wtp) += heightwts[i][1]; - (*wtp) *= n; - height = heightwts[1][0]; - } - } //else printf("cant find.(%s)\n",bits256_str(hash2)); - return(height); - } - /*n = 0; - if ( 0 && n == 0 && time(NULL) > coin->hdrstime+30 ) - { - height = (coin->blocks.hashblocks / coin->chain->bundlesize) * coin->chain->bundlesize; - while ( height < (coin->longestchain - coin->chain->bundlesize - 1) ) - { - if ( (hdrs= iguana_addhdr(coin,block->hash2,bits256_zero)) != 0 && hdrs->block.gothdrs == 0 ) - { - flag++; - //printf("REQ HDR.(%s) %d\n",bits256_str(block->hash2),height); - printf("%d ",height); - n++; - init_hexbytes_noT(hashstr,hdrs->bundlehash2.bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - } - height += coin->chain->bundlesize; - } - coin->hdrstime = (uint32_t)time(NULL); - } - if ( n > 0 ) - printf("REQ EXTRA HDRS\n");*/ - if ( offset == 0 ) - printf("unhandled case offset.0\n"); - else - { - struct iguana_block *block; - if ( bits256_nonz(hdrs->bundlehash2) == 0 ) - { - if ( (block= iguana_blockfind(coin,blockhashes[0])) != 0 ) - hdrs->bundlehash2 = block->prev_block; - } - } - - struct iguana_block *iguana_updatehdrs(struct iguana_info *coin,int32_t *newhwmp,struct iguana_block *block,bits256 prevhash2,bits256 hash2) - { - struct iguana_bundlereq *hdrs; int32_t i,offset,height; - if ( (hdrs= iguana_addhdr(coin,&offset,0,prevhash2,hash2)) != 0 && hdrs->bundleheight >= 0 ) - { - iguana_blockset(coin,hdrs->bundleheight,hdrs->bundlehash2); - height = (hdrs->bundleheight + offset); - if ( block != 0 ) - { - block->hh.itemind = height; - hdrs->block = *block; - prevhash2 = block->prev_block, hash2 = block->hash2; - if ( height > 0 ) - iguana_blockset(coin,height - 1,prevhash2); - if ( height <= coin->blocks.hwmheight ) - { - if ( height < coin->blocks.hwmheight || coin->blocks.dirty == 0 ) - coin->blocks.dirty = height; - (*newhwmp)++; - } - } - if ( hdrs->hashes != 0 ) - { - for (i=0; in; i++) - if ( memcmp(block->hash2.bytes,hdrs->hashes[i].bytes,sizeof(bits256)) == 0 ) - break; - printf("got block.(%s) height.%d i.%d\n",bits256_str(block->hash2),height,i); - for (; in; i++,height++) - iguana_blockset(coin,height,hdrs->hashes[i]); - } else printf("no blockhashes.%d\n",hdrs->bundleheight); - } else printf("cant find hdrs.%s %s %d\n",bits256_str(prevhash2),bits256_str2(hash2),hdrs==0?-1:hdrs->bundleheight), getchar(); - return(iguana_blockfind(coin,hash2)); - } - - struct iguana_block *iguana_blockset(struct iguana_info *coin,int32_t height,bits256 hash2) - { - struct iguana_block *block; int32_t offset,h,flag; struct iguana_bundlereq *hdrs; - //printf("blockset.%d %s\n",height,bits256_str(hash2)); - if ( height < 0 ) - getchar(); - iguana_blockhashset(coin,height,hash2,100); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - SETBIT(coin->havehash,height); - block->hh.itemind = height; - coin->blocks.ptrs[height] = block; - //printf("SETBIT.%d %s %p\n",hdrs->bundleheight,bits256_str(hdrs->bundlehash2),permblock); - } - if ( (height % coin->chain->bundlesize) == 0 ) - { - if ( 0 && (hdrs= iguana_addhdr(coin,&offset,1,hash2,bits256_zero)) != 0 ) - { - if ( hdrs->bundleheight != height && hdrs->bundleheight >= 0 ) - { - printf("bundleheight.%d -> EXTENDED HDRS.%d %s\n",hdrs->bundleheight,height,bits256_str(hash2)); - hdrs->bundleheight = height; - } - } - } - if ( height >= 0 && bits256_nonz(hash2) > 0 ) - { - if ( coin->chain->hasheaders == 0 && (height % coin->chain->bundlesize) == 1 && iguana_havetxdata(coin,height) == 0 ) - iguana_queueblock(coin,height,hash2,1); - } - return(block); - } - //tmp = iguana_updatehdrs(coin,newhwmp,block,block->prev_block,block->hash2); - if ( (prev= iguana_blockfind(coin,block->prev_block)) != 0 && (int32_t)prev->hh.itemind >= 0 ) - { - //printf("recv blockset.%s %d\n",bits256_str(block->hash2),prev->hh.itemind+1); - permblock = iguana_blockset(coin,prev->hh.itemind+1,block->hash2); - //permblock = iguana_blockhashset(coin,prev->hh.itemind+1,block->hash2,1); - } - else if ( (permblock= iguana_blockfind(coin,block->hash2)) == 0 ) - printf("cant find block prev.%s\n",bits256_str(block->prev_block)); - if ( tmp != 0 && permblock == 0 ) - permblock = tmp; - /*struct iguana_block *block; int32_t flag = 0; - while ( coin->blocks.issuedblocks < coin->blocks.hashblocks && coin->blocks.issuedblocks < coin->blocks.recvblocks+coin->chain->bundlesize*IGUANA_INITIALBUNDLES ) - { - if ( (block= iguana_blockptr(coin,coin->blocks.issuedblocks)) != 0 && bits256_nonz(block->hash2) != 0 ) - iguana_queueblock(coin,coin->blocks.issuedblocks,block->hash2,0); - coin->blocks.issuedblocks++; - flag++; - } - return(flag);*/ - - /*int32_t iguana_reqblocks(struct iguana_info *coin) - { - int32_t n,height,flag = 0; struct iguana_block *block; - if ( queue_size(&coin->priorityQ) == 0 ) - { - coin->pcount++; - if ( coin->pcount > 1 && (block= iguana_blockptr(coin,coin->blocks.recvblocks)) != 0 && coin->blocks.recvblocks < coin->blocks.issuedblocks && bits256_nonz(block->hash2) > 0 ) - flag += (iguana_queueblock(coin,coin->blocks.recvblocks,block->hash2,1) > 0); - } else coin->pcount = 0; - if ( queue_size(&coin->blocksQ) == 0 ) - { - coin->bcount++; - n = 0; - if ( coin->bcount > 100 && time(NULL) > coin->recvtime+3 ) - { - for (height=coin->blocks.recvblocks+1; heightblocks.issuedblocks&&nchain->bundlesize; height++) - { - if ( (block= iguana_blockptr(coin,coin->blocks.recvblocks)) != 0 && bits256_nonz(block->hash2) > 0 ) - { - //if ( (height % 100) == 0 ) - printf("RETRY BLOCK.%d\n",height); - flag += (iguana_queueblock(coin,height,block->hash2,0) > 0); - n++; - } - } - //coin->recvtime = (uint32_t)time(NULL); - } - } else coin->bcount = 0; - return(flag); - } - - { - bundlei = (height / coin->chain->bundlesize); - if ( GETBIT(coin->emitbits,bundlei) == 0 && iguana_bundleready(coin,height) > 0 ) - { - req->bundleheight = bundlei * coin->chain->bundlesize; - SETBIT(coin->emitbits,bundlei); - req->type = 'E'; - printf("Q emit.%d\n",req->bundleheight); - queue_enqueue("emitQ",&coin->emitQ,&req->DL,0); - } - }*/ - hash2 = iguana_bundleihash2(coin,bp,bundlei); - if ( memcmp(hash2.bytes,block->hash2.bytes,sizeof(hash2)) == 0 ) - { - *hdrsp = bp; - *bundleip = bundlei; - if ( bundlei == 0 ) - { - if ( (prevbp= iguana_bundlesearch(coin,&prevbundlei,block->bundlehash2,block->prev_block,IGUANA_SEARCHNEXT)) != 0 ) - { - if ( prevbundlei == prevbp->n+1 ) - { - bp->prevbundlehash2 = prevbp->bundlehash2; - prevbp->nextbundlehash2 = block->hash2; - //printf("prev BUNDLES LINKED! (%d <-> %d) (%s <-> %s)\n",prevbp->bundleheight,bp->bundleheight,bits256_str(prevbp->bundlehash2),bits256_str2(bp->bundlehash2)); - if ( prevbp->bundleheight != bp->bundleheight-coin->chain->bundlesize ) - printf("WARNING gap in bundleheight %d != %d bundlesize\n",prevbp->bundleheight,bp->bundleheight-coin->chain->bundlesize); - } else printf("prevbundlei.%d != prevhdrs->n %d\n",prevbundlei,prevbp->n+1); - } - } - else if ( bundlei == bp->n ) - { - if ( (nextbp= iguana_bundlesearch(coin,&nextbundlei,block->bundlehash2,block->hash2,IGUANA_SEARCHPREV)) != 0 ) - { - if ( nextbundlei == 0 ) - { - bp->nextbundlehash2 = nextbp->bundlehash2; - nextbp->prevbundlehash2 = block->hash2; - //printf("next BUNDLES LINKED! (%d <-> %d) (%s <-> %s)\n",nextbp->bundleheight,bp->bundleheight,bits256_str(nextbp->bundlehash2),bits256_str2(bp->bundlehash2)); - if ( nextbp->bundleheight != bp->bundleheight+coin->chain->bundlesize ) - printf("WARNING gap in bundleheight != bundlesize\n"); - } else printf("nextbundlei.%d != nextbp->n %d\n",nextbundlei,nextbp->n); - } - } - } else printf("hdrs.%d [%d] unexpected hash2 mismatch for %s != %s\n",bp->bundleheight,bundlei,bits256_str(block->hash2),bits256_str2(hash2)); - - - /*int32_t iguana_havehash(struct iguana_info *coin,int32_t height) - { - return(GETBIT(coin->havehash,height) != 0); - }*/ - - if ( (bp= iguana_bundlefind(coin,bundleip,block->hash2)) == 0 ) - { - if ( (prevbp= iguana_bundlefind(coin,&prevbundlei,block->prev_block)) == 0 ) - { - for (j=0; jbundlescount; j++) - { - if ( (bp= coin->bundles[j]) != 0 ) - { - if ( bp->blockhashes != 0 && bp->n > 0 && (bp= iguana_bundlescan(coin,bundleip,bp,block->hash2,IGUANA_SEARCHBUNDLE)) != 0 ) - { - return(bp); - } - } - } - return(0); - } - else if ( prevbundlei == prevbp->n ) - { - printf("prev AUTOCREATE.%s\n",bits256_str(block->hash2)); - iguana_bundlecreate(coin,block->hash2,bits256_zero); - } - } - || (bp= iguana_bundlefind(coin,bundleip,hash2)) != 0 ) - { - if ( (bp= iguana_bundlescan(coin,bundleip,bp,hash2,searchmask)) != 0 ) - return(bp); - } - if ( (bp= iguana_bundlefind(coin,bundleip,hash2)) != 0 ) - return(bp); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - iguana_blockhashset(coin,-1,hash2,1); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( bits256_nonz(block->bundlehash2) > 0 ) - { - if ( (bp= iguana_bundlefind(coin,&tmp,block->bundlehash2)) != 0 ) - return(iguana_bundlescan(coin,bundleip,bp,hash2,searchmask)); - } - } - - for (i=0; ichain->bundlesize+1 && iguana_bundlefind(coin,&bundlei,blocks[n - 1].hash2,0) == 0 ) - { - printf("AUTO EXTEND3.%s[%d]\n",bits256_str(blocks[n - 1].hash2),n); - iguana_bundlecreate(coin,blocks[n - 1].hash2,bits256_zero); - } - - //struct iguana_blockhashes { bits256 *blockhashes; int32_t n; uint32_t starttime; }; - - void iguana_freetx(struct iguana_msgtx *tx,int32_t n) - { - int32_t i,j; struct iguana_msgtx *origtx = tx; - return; - for (j=0; jallocsize; - if ( tx->vins != 0 ) - { - for (i=0; itx_in; i++) - if ( tx->vins[i].script != 0 ) - myfree(tx->vins[i].script,tx->vins[i].scriptlen); - myfree(tx->vins,tx->tx_in * sizeof(*tx->vins)); - } - if ( tx->vouts != 0 ) - { - for (i=0; itx_out; i++) - if ( tx->vouts[i].pk_script != 0 ) - myfree(tx->vouts[i].pk_script,tx->vouts[i].pk_scriptlen); - myfree(tx->vouts,tx->tx_out * sizeof(*tx->vouts)); - } - } - myfree(origtx,sizeof(*origtx) * n); - } - - /* - struct iguana_rawtx { bits256 txid; uint16_t numvouts,numvins; uint8_t rmd160[20]; }; - - int32_t iguana_emittx(struct iguana_info *coin,FILE *fp,struct iguana_block *block,struct iguana_msgtx *tx,int32_t txi,uint32_t *numvoutsp,uint32_t *numvinsp,int64_t *outputp) - { - int32_t blocknum,i; int64_t reward; uint16_t s; struct iguana_rawtx rawtx; uint8_t rmd160[20],buf[64]; - struct iguana_msgvin *vin; - blocknum = block->hh.itemind; - memset(&rawtx,0,sizeof(rawtx)); - rawtx.txid = tx->txid; - rawtx.numvouts = tx->tx_out, rawtx.numvins = tx->tx_in; - if ( (blocknum == 91842 || blocknum == 91880) && txi == 0 && strcmp(coin->name,"bitcoin") == 0 ) - rawtx.txid.ulongs[0] ^= blocknum; - //printf("%d: tx.%p %p[numvouts.%d] %p[numvins.%d]\n",block->hh.itemind,tx,tx->vouts,tx->tx_out,tx->vins,tx->tx_in); - if ( fwrite(&rawtx,1,sizeof(rawtx),fp) == sizeof(rawtx) ) - { - for (i=0; ivouts[i].pk_script,tx->vouts[i].pk_scriptlen,rawtx.txid); - memcpy(buf,&tx->vouts[i].value,sizeof(tx->vouts[i].value)); - memcpy(&buf[sizeof(tx->vouts[i].value)],rmd160,sizeof(rmd160)); - if ( fwrite(buf,1,sizeof(rmd160)+sizeof(tx->vouts[i].value),fp) == sizeof(rmd160)+sizeof(tx->vouts[i].value) ) - { - (*numvoutsp)++; - (*outputp) += tx->vouts[i].value; - } else printf("error writing txi.%d vout.%d\n",txi,i); - } - for (i=0; ivins[i]; - if ( bits256_nonz(vin->prev_hash) == 0 ) - { - if ( i == 0 && (int32_t)vin->prev_vout < 0 ) - { - reward = iguana_miningreward(coin,blocknum); - //printf("reward %.8f\n",dstr(reward)); - (*outputp) += reward; - } else printf("unexpected prevout.%d\n",vin->prev_vout), getchar(); - continue; - } - memcpy(buf,vin->prev_hash.bytes,sizeof(vin->prev_hash)); - s = vin->prev_vout; - memcpy(&buf[sizeof(vin->prev_hash)],&s,sizeof(s)); - //printf("do spend.%s\n",bits256_str(vin->prev_hash)); - if ( fwrite(buf,1,sizeof(bits256)+sizeof(s),fp) == sizeof(bits256)+sizeof(s) ) - (*numvinsp)++; - else printf("error writing txi.%d vin.%d\n",txi,i); - } - return(0); - } - else printf("error writing txi.%d blocknum.%d\n",txi,blocknum); - return(-1); - } - - void iguana_emittxarray(struct iguana_info *coin,FILE *fp,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t numtx) - { - uint32_t i,numvouts,numvins; int64_t credits; long fpos,endpos; - if ( fp != 0 && block != 0 ) - { - //printf("%d/%d: txarray.%p, numtx.%d bp.%p\n",block->hh.itemind,block->hh.itemind,txarray,numtx,bp); - fpos = ftell(fp); - credits = numvouts = numvins = 0; - for (i=0; iL.supply = credits; - block->txn_count = numtx; - block->numvouts = numvouts, block->numvins = numvins; - block->L.numtxids = numtx, block->L.numunspents = numvouts, block->L.numspends = numvins; - if ( fwrite(block,1,sizeof(*block),fp) != sizeof(*block) ) - printf("iguana_emittxarray: error writing block.%d\n",block->height); - fseek(fp,endpos,SEEK_SET); - } - } - - int32_t iguana_maptxdata(struct iguana_info *coin,struct iguana_mappedptr *M,struct iguana_bundle *bp,char *fname) - { - void *fileptr = 0; int32_t i; uint32_t *offsets; struct iguana_block *block; - if ( (fileptr= iguana_mappedptr(0,M,0,0,fname)) != 0 ) - { - offsets = fileptr; - for (i=0; in; i++) - { - if ( (block= bp->blocks[i]) != 0 ) - { - if ( block->txdata != 0 ) - { - if ( block->mapped == 0 ) - { - printf("[%d].%d free txdata.%d %p\n",bp->hdrsi,i,((struct iguana_bundlereq *)block->txdata)->allocsize,block->txdata); - myfree(block->txdata,((struct iguana_bundlereq *)block->txdata)->allocsize); - block->txdata = 0; - block->mapped = 0; - } - } - if ( i < coin->chain->bundlesize ) - { - block->txdata = (void *)((long)fileptr + offsets[i]); - block->mapped = 1; - } - } - else if ( i < coin->chain->bundlesize ) - printf("iguana_maptxdata cant find block[%d]\n",i); - } - return(i < coin->chain->bundlesize ? i : coin->chain->bundlesize); - } - printf("error mapping (%s)\n",fname); - return(-1); - } - - void iguana_emittxdata(struct iguana_info *coin,struct iguana_bundle *emitbp) - { - FILE *fp; char fname[512];uint32_t offsets[_IGUANA_HDRSCOUNT+1]; - //uint8_t extra[256]; struct iguana_msgtx *txarray,*tx; - struct iguana_bundlereq *req; struct iguana_mappedptr M; - int32_t i,bundleheight,height,numtx,n; long len; struct iguana_block *block; - return; - if ( emitbp == 0 ) - return; - sprintf(fname,"tmp/%s/txdata.%d",coin->symbol,emitbp->bundleheight); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - bundleheight = emitbp->bundleheight; - for (i=n=0; in&&ichain->bundlesize; i++) - if ( (block= emitbp->blocks[i]) != 0 && block->txdata != 0 && block->mapped == 0 ) - n++; - if ( n != emitbp->n && n != coin->chain->bundlesize ) - printf("iguana_emittxdata: WARNING n.%d != bundlesize.%d bundlesize.%d\n",n,emitbp->n,coin->chain->bundlesize); - memset(offsets,0,sizeof(offsets)); - if ( (len= fwrite(offsets,sizeof(*offsets),n+1,fp)) != n+1 ) - printf("%s: error writing blank offsets len.%ld != %d\n",fname,len,n+1); - for (i=0; iblocks[i]) != 0 ) - { - if ( (req= block->txdata) != 0 && (numtx= block->txn_count) > 0 ) - { - if ( 0 && fwrite(req->serialized,1,req->n,fp) != req->n ) - printf("error writing serialized data.%d\n",req->n); - if ( 0 && (txarray= iguana_gentxarray(coin,&len2,block,req->serialized,req->n,extra)) != 0 ) - { - tx = txarray; - for (j=0; jvouts,tx->tx_out,tx->vins,tx->tx_in); - printf("emit.%d txarray.%p[%d]\n",i,txarray,numtx); - iguana_emittxarray(coin,fp,block,txarray,numtx); - iguana_freetx(txarray,numtx); - } - } else printf("emittxdata: unexpected missing txarray[%d]\n",i); - } else printf("emittxdata: error with recvblockptr[%d]\n",emitbp->bundleheight + i); - } - offsets[i] = (uint32_t)ftell(fp); - rewind(fp); - if ( (len= fwrite(offsets,sizeof(*offsets),n+1,fp)) != n+1 ) - printf("%s: error writing offsets len.%ld != %d\n",fname,len,n+1); - fclose(fp), fp = 0; - memset(&M,0,sizeof(M)); - //if ( iguana_maptxdata(coin,&M,emitbp,fname) != n ) - // printf("emit error mapping n.%d height.%d\n",n,bundleheight); - //else - { - //if ( emitbp->blockhashes != 0 ) - // myfree(emitbp->blockhashes,sizeof(*emitbp->blockhashes) * emitbp->n); - //emitbp->blockhashes = 0; - } - } - }*/ - //static uint64_t Tx_allocated,Tx_allocsize,Tx_freed,Tx_freesize; - - /*int64_t iguana_MEMallocated(struct iguana_info *coin) - { - int64_t total = coin->TMPallocated; - if ( Tx_allocsize > Tx_freesize ) - total += (Tx_allocsize - Tx_freesize); - //total += coin->R.RSPACE.openfiles * coin->R.RSPACE.size; - //total += iguana_packetsallocated(coin); - return(total); - }*/ - - static int32_t _sort_by_bits256(struct iguana_kvitem *a,struct iguana_kvitem *b) - { - return(bits256_cmp(*(bits256 *)a->keyvalue,*(bits256 *)b->keyvalue)); - } - - static int32_t _sort_by_revbits256(struct iguana_kvitem *a,struct iguana_kvitem *b) - { - return(bits256_revcmp(*(bits256 *)a->keyvalue,*(bits256 *)b->keyvalue)); - } - - static int32_t _sort_by_rmd160(struct iguana_kvitem *a,struct iguana_kvitem *b) - { - return(rmd160_cmp(a->keyvalue,b->keyvalue)); - } - - static int32_t _sort_by_revrmd160(struct iguana_kvitem *a,struct iguana_kvitem *b) - { - return(rmd160_revcmp(a->keyvalue,b->keyvalue)); - } - - // HASH_SORT(coin->blocks.hash,_sort_by_txid); - /* if ( bp->type == 'Q' ) - { - req = (struct iguana_bundlereq *)ptr; - //printf("START.%p save tmp txdata %p [%d].%d datalen.%d %p\n",req,req->argbp,req->argbp!=0?req->argbp->hdrsi:-1,req->argbundlei,req->datalen,req->data); - if ( fp != 0 ) - { - if ( fwrite(req->data,1,req->datalen,fp) != req->datalen ) - printf("error writing [%d].%d datalen.%d\n",req->argbp!=0?req->argbp->hdrsi:-1,req->argbundlei,req->datalen); - } - //Tx_freed++; - //Tx_freesize += req->allocsize; - if ( req->data != 0 ) - myfree(req->data,req->datalen); - if ( req->blocks != 0 ) - myfree(req->blocks,sizeof(*req->blocks)); - myfree(req,req->allocsize); - } - else if ( bp->type == 'E' ) - { - fflush(fp); - //myallocated(0,0); - //iguana_emittxdata(bp->coin,bp); - //myallocated(0,0); - } - else - { - printf("iguana_helper: unsupported type.%c %d %p\n",bp->type,bp->type,bp); - }*/ - for (j=0; jhdrsi,bundlei,itembp->emitfinish); - if ( itembp->emitfinish != 0 ) - finished++; - } - } - if ( finished == num ) - iguana_peerfilecloseHT(coin,inds[j][0],inds[j][1]); - else printf("peerdir.(%d %d) finished.%d of %d\n",inds[j][0],inds[j][1],finished,num); - } else printf("cant get peerdirptr.(%d %d)\n",inds[j][0],inds[j][1]); - } - - int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_memspace *memB,struct iguana_bundle *bp) // helper thread - { - void *ptrs[IGUANA_MAXBUNDLESIZE]; uint32_t inds[IGUANA_MAXBUNDLESIZE][2]; struct iguana_fileitem *dir; - struct iguana_bundle *itembp; int32_t addrind,bundlei,finished,fileind,i,j,maxrecv,num,flag,numdirs=0; - struct iguana_txdatabits txdatabits; struct iguana_ramchain *ramchain; uint64_t estimatedsize = 0; - struct iguana_block *block; - memset(ptrs,0,sizeof(ptrs)), memset(inds,0,sizeof(inds)); - flag = maxrecv = 0; - for (i=0; in && ichain->bundlesize; i++) - { - if ( (block= bp->blocks[i]) != 0 ) - { - txdatabits = block->txdatabits; - if ( memcmp(block->hash2.bytes,coin->chain->genesis_hashdata,sizeof(bits256)) == 0 ) - ptrs[i] = coin->chain->genesis_hashdata, flag++; - else if ( (ptrs[i]= iguana_peerfileptrHT(coin,txdatabits,1)) != 0 ) - { - if ( block->recvlen > maxrecv ) - maxrecv = block->recvlen; - estimatedsize += block->recvlen; - flag++; - } - else - { - printf("peerfileptr[%d] (%d %d %d %d) null bp.%p %d\n",i,txdatabits.addrind,txdatabits.filecount,txdatabits.fpos,txdatabits.datalen,bp,bp->hdrsi); - if ( 1 ) - { - CLEARBIT(bp->recv,i); - bp->issued[i] = 0; - memset(&block->txdatabits,0,sizeof(block->txdatabits)); - block = 0; - } - } - addrind = txdatabits.addrind, fileind = txdatabits.filecount; - if ( numdirs > 0 ) - { - for (j=0; j>>>>>>>> start MERGE.(%ld %ld) numdirs.%d i.%d flag.%d estimated.%ld maxrecv.%d\n",(long)mem->totalsize,(long)memB->totalsize,numdirs,i,flag,(long)estimatedsize,maxrecv); - if ( (ramchain= iguana_bundlemergeHT(coin,mem,memB,ptrs,i,bp)) != 0 ) - { - iguana_ramchainsave(coin,mem,ramchain); - iguana_ramchainfree(coin,mem,ramchain); - bp->emitfinish = (uint32_t)time(NULL); - } else bp->emitfinish = 0; - iguana_mempurge(mem); - iguana_mempurge(memB); - } - else - { - printf(">>>>> bundlesaveHT error: numdirs.%d i.%d flag.%d\n",numdirs,i,flag); - bp->emitfinish = 0; - } - return(flag); - } - - int32_t iguana_peerfilecloseHT(struct iguana_info *coin,uint32_t addrind,uint32_t filecount) - { - char fname[512]; int32_t i,n = 0; struct iguana_mappedptr *M; - return(0); - iguana_peerfilename(coin,fname,addrind,filecount); - printf("PEERFILECLOSE.%s\n",fname); - //portable_mutex_lock(&coin->peers.filesM_mutex); - if ( coin->peers.filesM != 0 ) - { - for (i=0; ipeers.numfilesM; i++) - { - M = &coin->peers.filesM[i]; - if ( strcmp(fname,M->fname) == 0 && M->fileptr != 0 ) - { - printf("[%d] closemap.(%s)\n",i,fname); - iguana_closemap(M); - M->closetime = (uint32_t)time(NULL); - n++; - } - } - } - //portable_mutex_unlock(&coin->peers.filesM_mutex); - return(n); - } - - void *_iguana_txdataptrHT(struct iguana_info *coin,struct iguana_mappedptr *M,char *fname,struct iguana_txdatabits txdatabits) - { - int32_t len; uint8_t *rawptr; uint32_t starttime = (uint32_t)time(NULL); - if ( M->fileptr != 0 ) - { - while ( M->allocsize < (txdatabits.fpos + txdatabits.datalen + sizeof(uint32_t)) ) - { - iguana_closemap(M); - if ( iguana_mappedptr(0,M,0,0,fname) == 0 || M->allocsize < (txdatabits.fpos + txdatabits.datalen + sizeof(uint32_t)) ) - { - if ( time(NULL) > starttime+3 ) - { - printf("too small (%s) %llu vs %ld\n",fname,(long long)M->allocsize,(txdatabits.fpos + txdatabits.datalen + sizeof(uint32_t))); - return(0); - } else sleep(1); - } - } - rawptr = (void *)((long)M->fileptr + txdatabits.fpos); - memcpy(&len,rawptr,sizeof(len)); - if ( len == IGUANA_MARKER ) - { - memcpy(&len,&rawptr[sizeof(len)],sizeof(len)); - //printf("found marker %s[%u] numblocks.%d\n",fname,(int32_t)txdatabits.fpos,len); - if ( txdatabits.isdir != 0 ) - return(&rawptr[sizeof(uint32_t)*2]); - else printf("isdir notset with IGUANA_MARKER.%x\n",IGUANA_MARKER); - } - else if ( len == txdatabits.datalen && len < IGUANA_MAXPACKETSIZE ) - { - if ( txdatabits.isdir == 0 ) - return(&rawptr[sizeof(uint32_t)]); - else printf("isdir set without IGUANA_MARKER.%x\n",IGUANA_MARKER); - } else printf("txdataptr.%s: len.%d error [%d %d %d %d] (%d %d)\n",fname,len,txdatabits.datalen,txdatabits.addrind,txdatabits.fpos,txdatabits.filecount,len == txdatabits.datalen,len < IGUANA_MAXPACKETSIZE);//, getchar(); - } //else printf("txdataptr.%s %p %ld vs %ld\n",M->fname,M->fileptr,M->allocsize,(txdatabits.fpos + txdatabits.datalen + sizeof(uint32_t))); - return(0); - } -#define IGUANA_MARKER 0x07770777 - - void iguana_peerfilename(struct iguana_info *coin,char *fname,uint32_t addrind,uint32_t filecount) - { - sprintf(fname,"tmp/%s/peer%d.%d",coin->symbol,addrind,filecount); - } - - struct iguana_txdatabits iguana_calctxidbits(uint32_t addrind,uint32_t filecount,uint32_t fpos,uint32_t datalen) - { - struct iguana_txdatabits bits; - if ( (bits.addrind= addrind) != addrind ) - printf("iguana_calctxidbits: addrind overflow.%d\n",addrind), exit(-1); - if ( (bits.filecount= filecount) != filecount ) - printf("iguana_calctxidbits: filecount overflow.%d\n",filecount), exit(-1); - if ( (bits.fpos= fpos) != fpos ) - printf("iguana_calctxidbits: fpos overflow.%d\n",fpos), exit(-1); - if ( (bits.datalen= datalen) != datalen ) - printf("iguana_calctxidbits: datalen overflow.%d\n",datalen), exit(-1); - return(bits); - } - - void *iguana_peerfileptrHT(struct iguana_info *coin,struct iguana_txdatabits txdatabits,int32_t createflag) - { - char fname[512]; int32_t i,oldesti,oldest,duration,datalen; uint64_t fpos; struct iguana_mappedptr *M = 0; void *ptr = 0; - fpos = txdatabits.fpos, datalen = txdatabits.datalen; - oldesti = -1; - oldest = 0; - iguana_peerfilename(coin,fname,txdatabits.addrind,txdatabits.filecount); - //portable_mutex_lock(&coin->peers.filesM_mutex); - if ( coin->peers.filesM != 0 ) - { - for (i=0; ipeers.numfilesM; i++) - { - M = &coin->peers.filesM[i]; - if ( strcmp(fname,M->fname) == 0 ) - { - if ( M->fileptr != 0 && (ptr= _iguana_txdataptrHT(coin,M,fname,txdatabits)) != 0 ) - { - //portable_mutex_unlock(&coin->peers.filesM_mutex); - //printf("peerfileptr.(%s) %d %d -> %p\n",fname,txdatabits.addrind,txdatabits.filecount,ptr); - return(ptr); - } - else if ( M->closetime != 0 ) - { - duration = (uint32_t)(time(NULL) - M->closetime); - if ( duration > oldest ) - oldest = duration, oldesti = i; - } - } - } - M = 0; - } - if ( createflag != 0 ) - { - if ( oldesti >= 0 && oldest > 60 ) - { - M = &coin->peers.filesM[oldesti]; - printf("oldesti.%d oldest.%d remove.(%s) recycle slot.%d\n",oldesti,oldest,M->fname,i); - iguana_removefile(M->fname,0); - memset(M,0,sizeof(*M)); - } - if ( M == 0 ) - { - coin->peers.filesM = myrealloc('m',coin->peers.filesM,coin->peers.filesM==0?0:coin->peers.numfilesM * sizeof(*coin->peers.filesM),(coin->peers.numfilesM+1) * sizeof(*coin->peers.filesM)); - M = &coin->peers.filesM[coin->peers.numfilesM]; - coin->peers.numfilesM++; - //if ( (coin->peers.numfilesM % 10) == 0 ) - printf("iguana_peerfileptr realloc filesM.%d\n",coin->peers.numfilesM); - } - if ( iguana_mappedptr(0,M,0,0,fname) != 0 ) - { - ptr = _iguana_txdataptrHT(coin,M,fname,txdatabits); - printf("mapped.(%s) size.%ld %p\n",fname,(long)M->allocsize,ptr); - } else printf("iguana_peerfileptr error mapping.(%s)\n",fname); - } - //portable_mutex_unlock(&coin->peers.filesM_mutex); - return(ptr); - } - - struct iguana_fileitem *iguana_peerdirptrHT(struct iguana_info *coin,int32_t *nump,uint32_t addrind,uint32_t filecount,int32_t createflag) - { - char fname[512]; FILE *fp; uint32_t dirpos,marker; struct iguana_txdatabits txdatabits; - *nump = 0; - if ( filecount >= coin->peers.active[addrind].filecount ) - return(0); - iguana_peerfilename(coin,fname,addrind,filecount); - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,-sizeof(int32_t) * 3,SEEK_END); - fread(nump,1,sizeof(*nump),fp); - fread(&dirpos,1,sizeof(dirpos),fp); - fread(&marker,1,sizeof(marker),fp); - if ( marker == IGUANA_MARKER && (dirpos + sizeof(uint32_t) * 5 + *nump * sizeof(struct iguana_fileitem)) == ftell(fp) ) - { - txdatabits = iguana_calctxidbits(addrind,filecount,dirpos,(int32_t)(*nump * sizeof(struct iguana_fileitem))); - fclose(fp); - txdatabits.isdir = 1; - return(iguana_peerfileptrHT(coin,txdatabits,1)); - } - else //if ( marker == IGUANA_MARKER ) - printf("marker.%x vs %x: dirpos.%d num.%d -> %ld vs %ld\n",marker,IGUANA_MARKER,dirpos,*nump,dirpos + sizeof(uint32_t) * 4 + *nump * sizeof(struct iguana_fileitem),ftell(fp)); - fclose(fp); - } else printf("cant open dir.(%s)\n",fname); - return(0); - } - struct iguana_txdatabits iguana_peerfilePT(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,struct iguana_txdatabits txdatabits,int32_t datalen) - { - char fname[512]; int32_t marker; uint32_t dirpos; - if ( bits256_nonz(hash2) == 0 || addr->fp == 0 || ftell(addr->fp)+datalen >= IGUANA_PEERFILESIZE-IGUANA_MAXPACKETSIZE || addr->numfilehash2 >= addr->maxfilehash2 ) - //if ( addr->fp == 0 ) - { - if ( addr->fp != 0 ) - { - dirpos = (uint32_t)ftell(addr->fp); - marker = IGUANA_MARKER; - fwrite(&marker,1,sizeof(marker),addr->fp); - fwrite(&addr->numfilehash2,1,sizeof(addr->numfilehash2),addr->fp); - fwrite(addr->filehash2,addr->numfilehash2,sizeof(*addr->filehash2),addr->fp); - fwrite(&addr->numfilehash2,1,sizeof(addr->numfilehash2),addr->fp); - fwrite(&dirpos,1,sizeof(dirpos),addr->fp); - fwrite(&marker,1,sizeof(marker),addr->fp); - fclose(addr->fp); - //iguana_flushQ(coin,addr); - //fflush(addr->fp); - } - iguana_peerfilename(coin,fname,addr->addrind,++addr->filecount); - txdatabits.filecount = addr->filecount; - addr->fp = fopen(fname,"wb"); - addr->numfilehash2 = 0; - } - if ( addr->fp == 0 ) - { - printf("error creating fileind.%d %s\n",addr->filecount,addr->ipaddr); - exit(1); - } - if ( addr->numfilehash2 < addr->maxfilehash2 ) - { - if ( addr->filehash2 == 0 ) - addr->filehash2 = mycalloc('f',addr->maxfilehash2,sizeof(*addr->filehash2)); - addr->filehash2[addr->numfilehash2].hash2 = hash2; - addr->filehash2[addr->numfilehash2].txdatabits = txdatabits; - addr->numfilehash2++; - } - return(txdatabits); - } - - - int32_t iguana_ramchainspend(struct iguana_info *coin,struct iguana_ramchain *ramchain,uint32_t spendind,uint32_t spent_txidind,uint16_t spent_vout,int32_t updateflag) - { - struct iguana_pkhash *p; struct iguana_unspent *u; struct iguana_account *acct; int32_t unspentind,pkind; - if ( spent_txidind < ramchain->numtxids ) - { - unspentind = (spent_txidind + spent_vout); - u = &ramchain->U[unspentind]; - if ( (pkind= u->pkind) < ramchain->numpkinds && pkind >= 0 ) - { - if ( updateflag != 0 ) - { - p = &ramchain->P[pkind]; - if ( ramchain->pkextras[pkind].firstspendind == 0 ) - ramchain->pkextras[pkind].firstspendind = spendind; - acct = &ramchain->accounts[pkind]; - ramchain->S[spendind].prevspendind = acct->lastspendind; - acct->lastspendind = spendind; - if ( ramchain->Uextras[unspentind].spendind != 0 ) - { - printf("double spend u.%d has spendind.%d when s.%d refers to it\n",unspentind,ramchain->Uextras[unspentind].spendind,spendind); - return(-1); - } - ramchain->Uextras[unspentind].spendind = spendind; - } - return(1); - } - } - return(0); - } - - int32_t iguana_ramchainspends(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t updateflag) - { - struct iguana_spend *s; int32_t j,spendind,retval,spent_txidind,spent_vout,needtxidinds = 0; - spendind = 0; - for (j=0; jnumspends; j++,spendind++) - { - s = &ramchain->S[spendind]; - spent_txidind = (s->unspentind >> 16) & 0xffff; - spent_vout = (s->unspentind & 0xffff); - if ( (retval= iguana_ramchainspend(coin,ramchain,spendind,spent_txidind,spent_vout,updateflag)) < 0 ) - return(-1); - needtxidinds += retval; - } - return(needtxidinds); - } - - int32_t iguana_ramchainload(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_ramchain *ramchain) - { - int32_t i,j; uint32_t unspentind,spendind,txidind,pkind,needtxidinds = 0; - struct iguana_txid *tx; struct iguana_pkhash *p; struct iguana_unspent *u; struct iguana_account *acct; - txidind = unspentind = spendind = pkind = 0; - for (pkind=0; pkindnumpkinds; pkind++) - { - p = &ramchain->P[pkind]; - iguana_hashsetHT(ramchain->pkhashes,0,p->rmd160,sizeof(p->rmd160),pkind); - } - for (i=0; inumtxids; i++,txidind++) - { - tx = &ramchain->T[txidind]; - iguana_hashsetHT(ramchain->txids,0,tx->txid.bytes,sizeof(bits256),txidind); - for (j=0; jnumvouts; j++,unspentind++) - { - u = &ramchain->U[unspentind]; - acct = &ramchain->accounts[u->pkind]; - u->prevunspentind = acct->lastunspentind; - acct->lastunspentind = unspentind; - if ( u->txidind != txidind ) - { - printf("txidind.%d u->txidind.%d mismatch\n",txidind,u->txidind); - return(-1); - } - acct->balance += u->value; - } - } - if ( (needtxidinds= iguana_ramchainspends(coin,ramchain,0)) == 0 ) - { - if ( (needtxidinds= iguana_ramchainspends(coin,ramchain,1)) != 0 ) - printf("ramchainspends unexpected error\n"); - } - return(needtxidinds); - } - - int32_t iguana_ramchainload(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_ramchain *ramchain) - { - int32_t i,j; uint32_t unspentind,spendind,txidind,pkind,needtxidinds = 0; - struct iguana_txid *tx; struct iguana_pkhash *p; struct iguana_unspent *u; struct iguana_account *acct; - txidind = unspentind = spendind = 0; - for (i=0; inumtxids; i++,txidind++) - { - tx = &ramchain->T[txidind]; - iguana_hashsetHT(ramchain->txids,0,tx->txid.bytes,sizeof(bits256),txidind); - for (j=0; jnumvouts; j++,unspentind++) - { - } - } - if ( (needtxidinds= iguana_ramchainspends(coin,ramchain,0)) == 0 ) - { - if ( (needtxidinds= iguana_ramchainspends(coin,ramchain,1)) != 0 ) - printf("ramchainspends unexpected error\n"); - } - return(needtxidinds); - } - - - int32_t iguana_ramchainspend(struct iguana_info *coin,struct iguana_ramchain *ramchain,uint32_t spendind,uint32_t spent_txidind,uint16_t spent_vout,int32_t updateflag) - { - struct iguana_pkhash *p; struct iguana_unspent *u; struct iguana_account *acct; int32_t unspentind,pkind; - if ( spent_txidind < ramchain->numtxids ) - { - unspentind = (spent_txidind + spent_vout); - u = &ramchain->U[unspentind]; - if ( (pkind= u->pkind) < ramchain->numpkinds && pkind >= 0 ) - { - if ( updateflag != 0 ) - { - p = &ramchain->P[pkind]; - if ( ramchain->pkextras[pkind].firstspendind == 0 ) - ramchain->pkextras[pkind].firstspendind = spendind; - acct = &ramchain->accounts[pkind]; - ramchain->S[spendind].prevspendind = acct->lastspendind; - acct->lastspendind = spendind; - if ( ramchain->Uextras[unspentind].spendind != 0 ) - { - printf("double spend u.%d has spendind.%d when s.%d refers to it\n",unspentind,ramchain->Uextras[unspentind].spendind,spendind); - return(-1); - } - ramchain->Uextras[unspentind].spendind = spendind; - } - return(1); - } - } - return(0); - } - uint32_t oldiguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind) - { - uint32_t tmpind; char ipaddr[64]; struct iguana_iAddr checkiA; - if ( rwflag == 0 ) - { - memset(iA,0,sizeof(*iA)); - if ( iguana_kvread(coin,coin->iAddrs,0,iA,&ind) != 0 ) - { - //printf("read[%d] %x -> status.%d\n",ind,iA->ipbits,iA->status); - return(ind); - } else printf("error getting pkhash[%u] when %d\n",ind,coin->numiAddrs); - } - else - { - expand_ipbits(ipaddr,iA->ipbits); - tmpind = ind; - if ( iguana_kvwrite(coin,coin->iAddrs,&iA->ipbits,iA,&tmpind) != 0 ) - { - if ( tmpind != ind ) - printf("warning: tmpind.%d != ind.%d for %s\n",tmpind,ind,ipaddr); - //printf("iA[%d] wrote status.%d\n",ind,iA->status); - if ( iguana_kvread(coin,coin->iAddrs,0,&checkiA,&tmpind) != 0 ) - { - if ( memcmp(&checkiA,iA,sizeof(checkiA)) != 0 ) - printf("compare error tmpind.%d != ind.%d\n",tmpind,ind); - } - return(iA->ipbits); - } else printf("error kvwrite (%s) ind.%d tmpind.%d\n",ipaddr,ind,tmpind); - } - printf("iA[%d] error rwflag.%d\n",ind,rwflag); - return(0); - } - struct iguana_peer *iguana_choosepeer(struct iguana_info *coin) - { - int32_t i,j,r,iter; struct iguana_peer *addr; - r = rand(); - portable_mutex_lock(&coin->peers_mutex); - if ( coin->MAXPEERS == 0 ) - coin->MAXPEERS = IGUANA_MAXPEERS; - if ( coin->peers.numranked > 0 ) - { - for (j=0; jpeers.numranked; j++) - { - i = (j + r) % coin->MAXPEERS; - if ( (addr= coin->peers.ranked[i]) != 0 && addr->pendblocks < coin->MAXPENDING && addr->dead == 0 && addr->usock >= 0 ) - { - portable_mutex_unlock(&coin->peers_mutex); - return(addr); - } - } - } - portable_mutex_unlock(&coin->peers_mutex); - for (iter=0; iter<2; iter++) - { - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers.active[(i + r) % coin->MAXPEERS]; - if ( addr->dead == 0 && addr->usock >= 0 && (iter == 1 || addr->pendblocks < coin->MAXPENDING) ) - return(addr); - } - } - return(0); - } - void iguana_shutdownpeers(struct iguana_info *coin,int32_t forceflag) - { -#ifndef IGUANA_DEDICATED_THREADS - int32_t i,skip,iter; struct iguana_peer *addr; - if ( forceflag != 0 ) - coin->peers.shuttingdown = (uint32_t)time(NULL); - for (iter=0; iter<60; iter++) - { - skip = 0; - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers.active[i]; - if ( addr->ipbits == 0 || addr->usock < 0 || (forceflag == 0 && addr->dead == 0) ) - continue; - if ( addr->startsend != 0 || addr->startrecv != 0 ) - { - skip++; - continue; - } - iguana_iAkill(coin,addr,0); - } - if ( skip == 0 ) - break; - sleep(1); - printf("iguana_shutdownpeers force.%d skipped.%d\n",forceflag,skip); - } - if ( forceflag != 0 ) - coin->peers.shuttingdown = 0; -#endif - } - - uint32_t iguana_ipbits2ind(struct iguana_info *coin,struct iguana_iAddr *iA,uint32_t ipbits,int32_t createflag) - { - char ipaddr[64]; struct iguana_kvitem *item; struct iguana_iAddr *tmp; - expand_ipbits(ipaddr,ipbits); - //printf("ipbits.%x %s to ind\n",ipbits,ipaddr); - memset(iA,0,sizeof(*iA)); - if ( (item= iguana_hashfind(coin->iAddrs,&ipbits,sizeof(ipbits))) == 0 ) - //if ( iguana_kvread(coin,coin->iAddrs,&ipbits,iA,&ind) == 0 ) - { - if ( createflag == 0 ) - return(0); - tmp = mycalloc('i',1,sizeof(*iA)); - *tmp = *iA; - iA->ind = coin->numiAddrs; - iA->ipbits = ipbits; - if ( (item= iguana_hashset(coin->iAddrs,0,&iA->ipbits,sizeof(iA->ipbits),iA->ind)) == 0 ) - { - printf("iguana_addr: cant save.(%s)\n",ipaddr); - return(0); - } - else - { - coin->numiAddrs++; - if ( iguana_rwiAddrind(coin,1,iA,iA->ind) == 0 ) - printf("error iAddr.%d: created %x %s\n",iA->ind,ipbits,ipaddr); - } - } - else *iA = *(struct iguana_iAddr *)item->keyvalue; - return(iA->ind); - } - - int32_t iguana_set_iAddrheight(struct iguana_info *coin,uint32_t ipbits,int32_t height) - { - struct iguana_iAddr iA; uint32_t ind; - if ( (ind= iguana_ipbits2ind(coin,&iA,ipbits,1)) > 0 ) - { - iA.ipbits = ipbits; - if ( (ind= iguana_rwiAddrind(coin,0,&iA,ind)) > 0 && height > iA.height ) - { - iA.height = height; - iA.ipbits = ipbits; - iguana_rwiAddrind(coin,1,&iA,ind); - } - } - return(iA.height); - } - - uint32_t iguana_rwipbits_status(struct iguana_info *coin,int32_t rwflag,uint32_t ipbits,int32_t *statusp) - { - struct iguana_iAddr iA; uint32_t ind; - if ( (ind= iguana_ipbits2ind(coin,&iA,ipbits,1)) > 0 ) - { - if ( (ind= iguana_rwiAddrind(coin,0,&iA,ind)) > 0 ) - { - if ( rwflag == 0 ) - *statusp = iA.status; - else - { - iA.status = *statusp; - iA.ipbits = ipbits; - printf("%p status.%d ipbits.%x iA.%d saved iA->ind.%d\n",&iA,iA.status,iA.ipbits,ind,iA.ind); - //printf("set status.%d for ind.%d\n",iA.status,ind); - if ( iguana_rwiAddrind(coin,1,&iA,ind) == 0 ) - { - printf("iguana_iAconnected (%x) save error\n",iA.ipbits); - return(0); - } - } - return(ind); - } else printf("iguana_rwiAstatus error getting iA[%d]\n",ind); - } else printf("error ipbits status\n"); - return(0); - } - - int32_t iguana_ramchainspends(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t updateflag) - { - struct iguana_spend *s; int32_t j,spendind,retval,needtxidinds = 0; - spendind = 0; - for (j=0; jnumspends; j++,spendind++) - { - s = &ramchain->S[spendind]; - if ( (retval= iguana_ramchainspend(coin,ramchain,spendind,s->spendtxidind,s->vout,updateflag)) < 0 ) - return(-1); - needtxidinds += retval; - } - return(needtxidinds); - } - if ( bundlei >= coin->chain->bundlesize ) - return(block); - if ( (block->bundlei= bundlei) == 0 ) - { - iguana_hash2set(coin,"bundlehash2",&bp->blockhashes[0],block->hash2); - //iguana_blockQ(coin,bp,0,bp->bundlehash2,1); - if ( bits256_nonz(block->prev_block) > 0 ) - { - //iguana_blockQ(coin,bp,-1,block->prev_block,1); - for (i=0; ibundlescount; i++) - { - if ( (prevbp= coin->bundles[i]) != 0 && prevbp->n >= coin->chain->bundlesize ) - { - cmphash2 = iguana_bundleihash2(coin,prevbp,coin->chain->bundlesize-1); - if ( memcmp(cmphash2.bytes,block->prev_block.bytes,sizeof(bits256)) == 0 ) - { - //printf("found prev_block\n"); - iguana_hash2set(coin,"bp setprev",&bp->prevbundlehash2,prevbp->blockhashes[0]); - iguana_hash2set(coin,"prevbp setnext",&prevbp->nextbundlehash2,bp->blockhashes[0]); - //printf("prev BUNDLES LINKED! (%d <-> %d) (%s <-> %s)\n",prevbp->bundleheight,bp->bundleheight,bits256_str(prevbp->bundlehash2),bits256_str2(bp->bundlehash2)); - if ( prevbp->bundleheight != bp->bundleheight-coin->chain->bundlesize ) - printf("WARNING gap in bundleheight %d != %d bundlesize\n",prevbp->bundleheight,bp->bundleheight-coin->chain->bundlesize); - break; - } - } - } - } - } - else if ( bundlei == 1 ) - { - if ( iguana_hash2set(coin,"firstblockhash2",&bp->blockhashes[1],block->hash2) < 0 ) - return(0); - if ( bp->blockhashes != 0 ) - { - if ( bits256_nonz(block->prev_block) > 0 ) - iguana_hash2set(coin,"b blockhashes[0]",&bp->blockhashes[0],block->prev_block); - iguana_hash2set(coin,"b blockhashes[1]",&bp->blockhashes[1],block->hash2); - } - } - else if ( bundlei == bp->n-1 ) - { - if ( (nextbp= iguana_bundlefind(coin,&nextbundlei,hash2,IGUANA_SEARCHBUNDLE)) != 0 ) - { - if ( nextbundlei == 0 ) - { - iguana_hash2set(coin,"bp setnext",&bp->nextbundlehash2,nextbp->blockhashes[0]); - iguana_hash2set(coin,"next setprev",&nextbp->prevbundlehash2,bp->blockhashes[0]); - char str[65],str2[65]; - bits256_str(str,bp->blockhashes[0]), bits256_str(str2,nextbp->blockhashes[0]); - printf("next BUNDLES LINKED! (%d <-> %d) (%s <-> %s)\n",bp->bundleheight,nextbp->bundleheight,str,str2); - if ( nextbp->bundleheight != bp->bundleheight+coin->chain->bundlesize ) - printf("WARNING gap in bundleheight %d != %d bundlesize\n",nextbp->bundleheight,bp->bundleheight+coin->chain->bundlesize); - } else printf("nextbundlei.%d != 0 nextbp->n %d\n",nextbundlei,nextbp->n); - } - //iguana_hash2set(coin,"lastblockhash2",&bp->lastblockhash2,block->hash2); - } - } - - - struct iguana_bundle *iguana_bundlescan(struct iguana_info *coin,int32_t *bundleip,struct iguana_bundle *bp,bits256 hash2,int32_t searchmask) - { - int32_t i; - *bundleip = -2; - if ( (searchmask & IGUANA_SEARCHBUNDLE) != 0 ) - { - // bloom filter here - //printf("%s vs %s: %d\n",bits256_str(hash2),bits256_str2(bp->bundlehash2),memcmp(hash2.bytes,bp->bundlehash2.bytes,sizeof(hash2))); - if ( memcmp(hash2.bytes,bp->blockhashes[0].bytes,sizeof(hash2)) == 0 ) - { - *bundleip = 0; - //printf("found blockhash[0]\n"); - return(bp); - } - if ( memcmp(hash2.bytes,bp->blockhashes[1].bytes,sizeof(hash2)) == 0 ) - { - *bundleip = 1; - //printf("found blockhash[1]\n"); - return(bp); - } - for (i=2; in && ichain->bundlesize; i++) - { - if ( memcmp(hash2.bytes,bp->blockhashes[i].bytes,sizeof(hash2)) == 0 ) - { - *bundleip = i; - return(bp); - } - } - } - if ( (searchmask & IGUANA_SEARCHPREV) != 0 && memcmp(hash2.bytes,bp->prevbundlehash2.bytes,sizeof(hash2)) == 0 ) - { - *bundleip = -1; - return(bp); - } - if ( (searchmask & IGUANA_SEARCHNEXT) != 0 && memcmp(hash2.bytes,bp->nextbundlehash2.bytes,sizeof(hash2)) == 0 ) - { - *bundleip = bp->n; - return(bp); - } - return(0); - } - - struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,int32_t *bundleip,bits256 hash2,int32_t adjust) - { - int32_t i,searchmask; struct iguana_bundle *bp = 0; // struct iguana_block *block; - *bundleip = -2; - if ( bits256_nonz(hash2) > 0 ) - { - if ( adjust == 0 ) - searchmask = IGUANA_SEARCHBUNDLE; - else searchmask = IGUANA_SEARCHNOLAST; - //if ( (block= iguana_blockfind(coin,hash2)) != 0 && (bp= block->bp) != 0 && (bp= iguana_bundlescan(coin,bundleip,bp,hash2,searchmask)) != 0 ) - // return(bp); - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - if ( (bp= iguana_bundlescan(coin,bundleip,bp,hash2,searchmask)) != 0 ) - return(bp); - } - } - } - //printf("iguana_hdrsfind: cant find %s\n",bits256_str(hash2)); - return(0); - } - - int32_t iguana_bundlecheck(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priorityflag) - { - int32_t i,qsize,remains,incomplete,lasti,n = 0; struct iguana_block *block; - bits256 hash2; double threshold; uint64_t datasize =0; - //printf("bp.%p bundlecheck.%d emit.%d\n",bp,bp->ramchain.hdrsi,bp->emitfinish); - if ( bp != 0 && bp->emitfinish == 0 ) - { - remains = bp->n - bp->numrecv; - qsize = queue_size(&coin->priorityQ); - if ( bp->numrecv > coin->chain->bundlesize*.98 ) - { - priorityflag = 1; - if ( bp->numrecv > coin->chain->bundlesize-3 ) - threshold = bp->avetime; - else threshold = bp->avetime * 2; - } else threshold = bp->avetime * 5; - lasti = -1; - for (i=0; in && ichain->bundlesize; i++) - { - hash2 = iguana_bundleihash2(coin,bp,i); - if ( bits256_nonz(hash2) == 0 ) - continue; - if ( (block= bp->blocks[i]) == 0 ) - block = bp->blocks[i] = iguana_blockfind(coin,hash2); - if ( block != 0 && block->ipbits != 0 ) - { - //char str[65]; - if ( block->recvlen != 0 ) - datasize += block->recvlen; - if ( block->hdrsi != bp->ramchain.hdrsi ) - block->hdrsi = bp->ramchain.hdrsi; - if ( block->bundlei != i ) - block->bundlei = i; - /* printf("%s %d[%d] != %d[%d]\n",bits256_str(str,block->hash2),block->hdrsi,block->bundlei,bp->ramchain.hdrsi,i); - CLEARBIT(bp->recv,i); - //memset(&bp->blocks[i]->txdatabits,0,sizeof(bp->blocks[i]->txdatabits)); - bp->issued[i] = milliseconds(); - iguana_blockQ(coin,bp,i,bp->blocks[i]->hash2,1); - bp->blocks[i] = 0; - } - else if ( block->bundlei != i ) - { - printf("%s %d[%d] != %d[%d]\n",bits256_str(str,block->hash2),block->hdrsi,block->bundlei,bp->ramchain.hdrsi,i); - CLEARBIT(bp->recv,i); - //memset(&bp->blocks[i]->txdatabits,0,sizeof(bp->blocks[i]->txdatabits)); - bp->issued[i] = milliseconds(); - iguana_blockQ(coin,bp,i,bp->blocks[i]->hash2,1); - bp->blocks[i] = 0; - } else */ - n++; - } - else if ( priorityflag != 0 && qsize == 0 )//&& (bp->issued[i] == 0 || milliseconds() > (bp->issued[i] + threshold)) ) - { - //if ( (rand() % 1000) == 0 ) - // printf("priorityQ submit threshold %.3f [%d].%d\n",threshold,bp->ramchain.hdrsi,i); - if ( bp->blocks[i] == 0 || bp->blocks[i]->ipbits == 0 ) - { - //CLEARBIT(bp->recv,i); - bp->issued[i] = 0;//milliseconds(); - //if ( i < 2 ) - // iguana_blockQ(coin,bp,i,hash2,1); - //iguana_blockQ(coin,bp,i,hash2,1); - //bp->blocks[i] = 0; - } - lasti = i; - } else lasti = i; - } - //if ( n == coin->chain->bundlesize-1 ) - //if ( n > 490 ) - // printf("bp.%d %d %d n.%d\n",bp->ramchain.hdrsi,bp->ramchain.bundleheight,lasti,n); - bp->numrecv = n; - bp->datasize = datasize; - if ( n > 0 ) - { - bp->estsize = ((uint64_t)datasize * coin->chain->bundlesize) / n; - //printf("estsize %d datasize.%d hdrsi.%d numrecv.%d\n",(int32_t)bp->estsize,(int32_t)datasize,bp->ramchain.hdrsi,n); - } - if ( n == coin->chain->bundlesize ) - { - printf("check %d blocks in hdrs.%d\n",n,bp->ramchain.hdrsi); - for (i=incomplete=0; iblocks[i]->hash2.bytes,bp->blocks[i+1]->prev_block.bytes,sizeof(bits256)) != 0 ) - { - if ( bits256_nonz(bp->blocks[i]->prev_block) > 0 && bits256_nonz(bp->blocks[i+1]->prev_block) > 0 && bits256_nonz(bp->blocks[i+1]->hash2) > 0 ) - { - char str[65],str2[65],str3[65]; - bits256_str(str,bp->blocks[i]->hash2); - bits256_str(str2,bp->blocks[i+1]->prev_block); - bits256_str(str3,bp->blocks[i+1]->hash2); - printf("%s ->%d %d<- %s %s ",str,i,i+1,str2,str3); - printf("broken chain in hdrs.%d %d %p <-> %p %d\n",bp->ramchain.hdrsi,i,bp->blocks[i],bp->blocks[i+1],i+1); - CLEARBIT(bp->recv,i); - //memset(&bp->blocks[i]->txdatabits,0,sizeof(bp->blocks[i]->txdatabits)); - //memset(&bp->blocks[i+1]->txdatabits,0,sizeof(bp->blocks[i+1]->txdatabits)); - bp->issued[i] = bp->issued[i+1] = milliseconds(); - //iguana_blockQ(coin,bp,i,bp->blocks[i]->hash2,1); - //iguana_blockQ(coin,bp,i+1,bp->blocks[i+1]->hash2,1); - bp->blocks[i] = bp->blocks[i+1] = 0; - break; - } - else incomplete++; - } - } - printf("i.%d n.%d incomplete.%d\n",i,n,incomplete); - if ( i == n-1 && incomplete == 0 ) - { - //if ( bp->blockhashes != 0 ) - //{ - for (i=0; iblockhashes[i],bp->blocks[i]->hash2); - // iguana_hash2set(coin,"check blockhashes[0]",&bp->blockhashes[0],bp->bundlehash2); - // iguana_hash2set(coin,"check firsthash2",&bp->blockhashes[1],bp->firstblockhash2); - //} - iguana_bundleblockadd(coin,bp,0,iguana_bundleihash2(coin,bp,0)); - iguana_bundleblockadd(coin,bp,coin->chain->bundlesize-1,iguana_bundleihash2(coin,bp,coin->chain->bundlesize-1)); - if ( bp->emitfinish <= 1 ) - iguana_emitQ(coin,bp); - if ( bp->emitfinish == 0 ) - bp->emitfinish = 1; - coin->numpendings--; - return(1); - } - } - } - return(0); - } - /****************************************************************************** - * Copyright © 2014-2015 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "iguana777.h" - - // peer context, ie massively multithreaded -> bundlesQ - - struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,int32_t datalen) - { - struct iguana_bundlereq *req; int32_t allocsize; - allocsize = (uint32_t)sizeof(*req) + datalen; - req = mycalloc(type,1,allocsize); - req->allocsize = allocsize; - req->datalen = datalen; - req->addr = addr; - req->coin = coin; - req->type = type; - return(req); - } - - void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,uint8_t *data,int32_t recvlen) - { - struct iguana_bundlereq *req; int32_t i,z,fpos,bundlei; FILE *fp; char fname[1024]; - if ( 0 ) - { - for (i=0; ispace[0]; i++) - if ( txdata->space[i] != 0 ) - break; - if ( i != txdata->space[0] ) - { - for (i=0; ispace[0]; i++) - printf("%02x ",txdata->space[i]); - printf("extra\n"); - } - } - req = iguana_bundlereq(coin,addr,'B',0); - if ( addr != 0 ) - { - if ( addr->pendblocks > 0 ) - addr->pendblocks--; - addr->lastblockrecv = (uint32_t)time(NULL); - addr->recvblocks += 1.; - addr->recvtotal += recvlen; - if ( (txdata= iguana_blockramchainPT(coin,addr,txdata,txarray,txdata->block.txn_count,data,recvlen)) != 0 ) - { - //fpos = (addr->fp != 0) ? ftell(addr->fp) : 0; - //txdatabits = iguana_calctxidbits(addr->addrind,addr->filecount,(uint32_t)fpos,txdata->datalen); - //txdatabits = iguana_peerfilePT(coin,addr,txdata->block.hash2,txdatabits,txdata->datalen); - fpos = 0; - if ( (bundlei= iguana_peerfname(coin,fname,addr->ipbits,txdata->block.hash2)) < 0 ) - { - if ( (fp= fopen(fname,"wb")) != 0 ) - coin->peers.numfiles++; - } - else - { - if ( (fp= fopen(fname,"rb+")) == 0 ) - { - if ( (fp= fopen(fname,"wb")) != 0 ) - { - z = -1; - coin->peers.numfiles++; - for (i=0; ichain->bundlesize; i++) - fwrite(&z,1,sizeof(z),fp); - fclose(fp); - fp = fopen(fname,"rb+"); - } - } - if ( fp != 0 ) - { - fseek(fp,0,SEEK_END); - fpos = (int32_t)ftell(fp); - } - } - if ( fp != 0 ) - { - txdata->block.bundlei = bundlei; - //printf("fpos.%d: bundlei.%d datalen.%d\n",fpos,bundlei,txdata->datalen); - fwrite(&bundlei,1,sizeof(bundlei),fp); - fwrite(&txdata->block.hash2,1,sizeof(txdata->block.hash2),fp); - fwrite(&txdata->datalen,1,sizeof(txdata->datalen),fp); - fwrite(txdata,1,txdata->datalen,fp); - if ( bundlei >= 0 && bundlei < coin->chain->bundlesize ) - { - fseek(fp,bundlei * sizeof(bundlei),SEEK_SET); - //printf("bundlei[%d] <- fpos.%d\n",bundlei,fpos); - fwrite(&fpos,1,sizeof(fpos),fp); - } else printf("error saving with bundlei.%d vs %d\n",bundlei,coin->chain->bundlesize); - fclose(fp); - //for (i=0; inumpkinds; i++) - // printf("%016lx ",*(long *)((struct iguana_pkhash *)((long)txdata + txdata->pkoffset))[i].rmd160); - //printf("create.(%s) %d ",fname,bundlei,coin->peers.numfiles); - //printf("bundlei.%d datalen.%d T.%d U.%d S.%d P.%d X.%d\n",bundlei,txdata->datalen,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids); - { - struct iguana_txblock *checktxdata; struct iguana_memspace checkmem; int32_t checkbundlei; - memset(&checkmem,0,sizeof(checkmem)); - iguana_meminit(&checkmem,"checkmem",0,txdata->block.recvlen + 4096,0); - if ( 0 && (checktxdata= iguana_peertxdata(coin,&checkbundlei,fname,&checkmem,addr->ipbits,txdata->block.hash2)) != 0 ) - { - printf("check datalen.%d bundlei.%d T.%d U.%d S.%d P.%d X.%d\n",checktxdata->datalen,checkbundlei,checktxdata->numtxids,checktxdata->numunspents,checktxdata->numspends,checktxdata->numpkinds,checktxdata->numexternaltxids); - } - } - } - req->datalen = txdata->datalen; - } - } - coin->recvcount++; - coin->recvtime = (uint32_t)time(NULL); - req->block = txdata->block; - req->addr = addr; - req->block.txn_count = req->numtx = txdata->block.txn_count; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n) - { - struct iguana_bundlereq *req; - printf("got %d txids from %s\n",n,addr->ipaddr); - req = iguana_bundlereq(coin,addr,'T',0); - req->hashes = txids, req->n = n; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgtx *tx,uint8_t *data,int32_t datalen) - { - struct iguana_bundlereq *req; - char str[65]; bits256_str(str,tx->txid); - printf("%s unconfirmed.%s\n",addr->ipaddr,str); - req = iguana_bundlereq(coin,addr,'U',datalen); - req->datalen = datalen; - memcpy(req->serialized,data,datalen); - //iguana_freetx(tx,1); - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) - { - struct iguana_bundlereq *req; - if ( addr != 0 ) - { - addr->recvhdrs++; - if ( addr->pendhdrs > 0 ) - addr->pendhdrs--; - //printf("%s blocks[%d] ht.%d gotheaders pend.%d %.0f\n",addr->ipaddr,n,blocks[0].height,addr->pendhdrs,milliseconds()); - } - req = iguana_bundlereq(coin,addr,'H',0); - req->blocks = blocks, req->n = n; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n) - { - struct iguana_bundlereq *req; - if ( addr != 0 ) - { - addr->recvhdrs++; - if ( addr->pendhdrs > 0 ) - addr->pendhdrs--; - } - req = iguana_bundlereq(coin,addr,'S',0); - req->hashes = blockhashes, req->n = n; - //printf("bundlesQ blockhashes.%p[%d]\n",blockhashes,n); - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); - } - - // main context, ie single threaded - - struct iguana_block *iguana_recvblockhdr(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock,int32_t *newhwmp) - { - struct iguana_bundle *prevbp,*bp = 0; int32_t j,prevbundlei; struct iguana_block *block; char str[65]; - (*bpp) = 0; - *bundleip = -2; - if ( (block= iguana_blockhashset(coin,-1,origblock->hash2,1)) == 0 ) - { - printf("error getting block for %s\n",bits256_str(str,origblock->hash2)); - return(0); - } - block->prev_block = origblock->prev_block; - if ( (bp= iguana_bundlefind(coin,bundleip,block->hash2,IGUANA_SEARCHBUNDLE)) == 0 ) - { - if ( (prevbp= iguana_bundlefind(coin,&prevbundlei,block->prev_block,IGUANA_SEARCHBUNDLE)) == 0 ) - { - printf("cant find prev.%s either\n",bits256_str(str,block->prev_block)); - for (j=0; jbundlescount; j++) - { - if ( (bp= coin->bundles[j]) != 0 ) - { - if ( (bp= iguana_bundlescan(coin,bundleip,bp,block->hash2,IGUANA_SEARCHBUNDLE)) != 0 ) - { - (*bpp) = bp; - char str[65]; - bits256_str(str,block->hash2); - printf("FOUND.%s in bundle.[%d:%d] %d\n",str,bp->ramchain.hdrsi,*bundleip,bp->ramchain.bundleheight + *bundleip); - iguana_bundleblockadd(coin,bp,*bundleip,block->hash2); - return(block); - } - } - } - char str[65]; - bits256_str(str,block->hash2); - printf("CANTFIND.%s\n",str); - return(block); - } - else - { - (*bpp) = prevbp; - char str[65]; - //printf("found bp.%p prevbundlei.%d\n",prevbp,prevbundlei); - if ( prevbundlei >= 0 && prevbundlei < coin->chain->bundlesize-1 ) - { - *bundleip = prevbundlei + 1; - if ( prevbundlei == 0 ) - iguana_blockQ(coin,bp,0,block->prev_block,1); - if ( prevbp != 0 ) - { - //bits256_str(str,block->hash2); - //printf("prev FOUND.%s in bundle.[%d:%d] %d\n",str,prevbp->ramchain.hdrsi,*bundleip,prevbp->ramchain.bundleheight + *bundleip); - iguana_bundleblockadd(coin,prevbp,*bundleip,block->hash2); - } - } - if ( 0 && prevbundlei == coin->chain->bundlesize-1 ) - { - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - bits256_str(str,block->hash2); - printf("prev AUTOCREATE.%s\n",str); - iguana_bundlecreate(coin,block->hash2,zero); - } - return(block); - } - } - else - { - //char str[65],str2[65]; - (*bpp) = bp; - //printf("blockadd.%s %s %d\n",bits256_str(str,block->hash2),bits256_str(str2,origblock->hash2),*bundleip); - iguana_bundleblockadd(coin,bp,*bundleip,block->hash2); - if ( *bundleip > 0 && bits256_nonz(block->prev_block) > 0 ) - iguana_bundleblockadd(coin,bp,(*bundleip) - 1,block->prev_block); - } - return(block); - } - - struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) - { - struct iguana_bundle *bp,*newbp; bits256 zero; int32_t i,j,newbundlei,missing,bundlei = -2,bundleheight = -1; - memset(zero.bytes,0,sizeof(zero)); - if ( (bp= iguana_bundlefind(coin,&bundlei,blockhashes[1],IGUANA_SEARCHBUNDLE)) != 0 ) - { - if ( bp->blockhashes == 0 ) - { - //iguana_blockQ(coin,bp,0,bp->bundlehash2,1); - bundleheight = bp->ramchain.bundleheight; - if ( num > coin->chain->bundlesize+1 ) - num = coin->chain->bundlesize+1; - //printf("GOT blockhashes.%s[%d] %d %p hdrsi.%d bundlei.%d\n",bits256_str(str,blockhashes[1]),num,bundleheight,bp->blockhashes,bp->ramchain.hdrsi,bundlei); - memcpy(bp->blockhashes,blockhashes,num * sizeof(*blockhashes)); - bp->n = num; - bp->ramchain.bundleheight = bundleheight; - if ( bundlei >= 0 && bundlei < bp->n ) - { - j = 1; - if ( bundlei != 1 ) - { - /*if ( bundlei == 0 ) - { - for (i=1; i>>>>>>>> hdrsi.%d bundlei.%d j.%d\n",bp->ramchain.hdrsi,bundlei,j); - return(req); - } - for (; jn && bundlei<=coin->chain->bundlesize; bundlei++,j++) - { - //printf("%d: bundlei.%d %s j.%d\n",bundlei % coin->chain->bundlesize,bundlei,bits256_str(str,blockhashes[j]),j); - if ( bundlei == coin->chain->bundlesize ) - { - if ( (newbp= iguana_bundlefind(coin,&newbundlei,blockhashes[j],IGUANA_SEARCHBUNDLE)) == 0 ) - { - //iguana_blockQ(coin,newbp,0,blockhashes[j],1); - if ( j < bp->n-1 ) - { - newbp = iguana_bundlecreate(coin,blockhashes[j],blockhashes[j+1]); - //iguana_blockQ(coin,newbp,1,blockhashes[j+1],1); - } - else newbp = iguana_bundlecreate(coin,blockhashes[j],zero); - if ( newbp != 0 ) - { - char str[65]; - if ( bp->ramchain.bundleheight >= 0 ) - newbp->ramchain.bundleheight = (bp->ramchain.bundleheight + coin->chain->bundlesize); - init_hexbytes_noT(str,blockhashes[j].bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); - } - } - } - else if ( 1 && iguana_bundleblockadd(coin,bp,bundlei,blockhashes[j]) == 0 ) - break; - } - } - //iguana_blockQ(coin,bp,1,blockhashes[1],1); - //if ( bp->n < coin->chain->bundlesize ) - // iguana_blockQ(coin,bp,bp->n-1,blockhashes[bp->n-1],1); - //else iguana_blockQ(coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],1); - } - else - { - if ( num > 2 ) - { - for (i=missing=0; in && ichain->bundlesize; i++) - { - if ( iguana_bundlescan(coin,&bundlei,bp,blockhashes[i],IGUANA_SEARCHBUNDLE) == 0 ) - { - missing++; - } - } - if ( missing != 0 ) - { - //printf("GOT MISMATCHED %d blockhashes.%s[%d] missing.%d of %d\n",bp->ramchain.bundleheight,bits256_str(blockhashes[1]),num,missing,bp->n); - return(req); - } - if ( num > bp->n && bp->n <= coin->chain->bundlesize ) - { - /*myfree(bp->blockhashes,sizeof(*bp->blockhashes) * bp->n); - bp->blockhashes = mycalloc('h',num,sizeof(*blockhashes)); - printf("replace blockhashes.%s[%d] %d %p\n",bits256_str(blockhashes[0]),num,bp->ramchain.bundleheight,bp->blockhashes); - memcpy(bp->blockhashes,blockhashes,num * sizeof(*blockhashes)); - i = bp->n, bp->n = num; - for (; iramchain.bundleheight >= 0 && (rand() % 1000) == 0 ) - printf("GOT duplicate.%s[%d] bheight.%d\n",str,num,bp->ramchain.bundleheight); - } - } - if ( (num= bp->n) > coin->chain->bundlesize ) - num = coin->chain->bundlesize; - } - else - { - if ( num > coin->chain->bundlesize+1 ) - num = coin->chain->bundlesize+1; - //for (i=1; i 2 ) - { - char str[65]; - bits256_str(str,blockhashes[1]); - //printf("recvblockhashes cant find %s num.%d\n",str,num); - //iguana_blockQ(coin,0,-1,blockhashes[1],1); - //iguana_bundlecreate(coin,blockhashes[1],blockhashes[2]); - if ( 0 && num == coin->chain->bundlesize+1 && iguana_bundlefind(coin,&bundlei,blockhashes[num - 1],IGUANA_SEARCHBUNDLE) == 0 ) - { - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - bits256_str(str,blockhashes[num - 1]); - printf("AUTO EXTEND2.%s[%d]\n",str,num); - iguana_bundlecreate(coin,blockhashes[num - 1],zero); - } - } - } - return(req); - } - - struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) - { - int32_t i,j; struct iguana_block *block; struct iguana_bundle *bp; - if ( blocks == 0 ) - return(req); - if ( n > coin->chain->bundlesize+1 ) - n = coin->chain->bundlesize+1; - // blockhashes = mycalloc('h',n+1,sizeof(*blockhashes)); - // iguana_hash2set(coin,"recvhdrs0",&bp->blockhashes[0],blocks->prev_block); - //for (i=0; iblockhashes[i+1],blocks[i].hash2); - n++; - for (j=0; jbundlescount; j++) - { - if ( (bp= coin->bundles[j]) != 0 ) - { - if ( memcmp(blocks[0].prev_block.bytes,bp->blockhashes[0].bytes,sizeof(bits256)) == 0 ) - { - // iguana_hash2set(coin,"recvhdrs0",&bp->blockhashes[0],blocks->prev_block); - //for (i=0; iblockhashes[i+1],blocks[i].hash2); - if ( bp->blockhashes == 0 ) - { - bp->n = n < coin->chain->bundlesize ? n : coin->chain->bundlesize; - for (i=1; in; i++) - { - iguana_hash2set(coin,"blockhdrs[i]",&bp->blockhashes[i],blocks[i].hash2); - if ( (block= iguana_blockfind(coin,bp->blockhashes[i])) != 0 ) - iguana_copyblock(coin,block,&blocks[i-1]); - } - /*iguana_blockQ(coin,bp,0,bp->bundlehash2,1); - iguana_blockQ(coin,bp,1,blockhashes[1],1); - if ( bp->n < coin->chain->bundlesize ) - iguana_blockQ(coin,bp,n-1,blockhashes[n-1],1); - else iguana_blockQ(coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],1);*/ - break; - } - else - { - //printf("free duplicate blockhashes\n"); - // myfree(blockhashes,n*sizeof(*blockhashes)); - } - } - } - } - return(req); - } - - struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t *newhwmp) - { - struct iguana_bundle *bp; int32_t bundlei; struct iguana_block *block; double duration = 0.; - if ( (block= iguana_recvblockhdr(coin,&bp,&bundlei,origblock,newhwmp)) != 0 ) - { - iguana_copyblock(coin,block,origblock); - //printf("recvblock.(%s) bp.%p bundlei.%d\n",bits256_str(str,block->hash2),bp,bundlei); - if ( bp != 0 && datalen > 0 ) - { - //printf("iguana_recvblock (%s) %d[%d] bit.%d recv.%d %02x %02x\n",bits256_str(str,block->hash2),bp->ramchain.hdrsi,bundlei,GETBIT(bp->recv,bundlei),bp->numrecv,bp->recv[0],bp->recv[bp->n/8]); - SETBIT(bp->recv,bundlei); - if ( bp->issued[bundlei] > 0 ) - { - duration = (int32_t)(milliseconds() - bp->issued[bundlei]); - if ( duration < bp->avetime/10. ) - duration = bp->avetime/10.; - else if ( duration > bp->avetime*10. ) - duration = bp->avetime * 10.; - dxblend(&bp->avetime,duration,.9); - dxblend(&coin->avetime,bp->avetime,.9); - } - /*if ( bundlei < 3 ) - { - if ( bundlei > 0 ) - iguana_blockQ(coin,bp,bundlei-1,block->prev_block,1); - iguana_blockQ(coin,bp,bundlei,block->hash2,1); - } - if ( bundlei == 2 ) - { - bp->firstblockhash2 = bp->blockhashes[1] = block->prev_block; - iguana_blockQ(coin,bp,bundlei,block->prev_block,1); - }*/ - if ( bundlei >= 0 && bundlei < bp->n && bundlei < coin->chain->bundlesize ) - { - if ( 0 && bundlei == 1 ) - printf("iguana_recvblock %d[%d] bit.%d recv.%d %02x %02x\n",bp->ramchain.hdrsi,bundlei,GETBIT(bp->recv,bundlei),bp->numrecv,bp->recv[0],bp->recv[bp->n/8]); - if ( req->addr != 0 && req->addr->ipbits != 0 )//&& req->addr->addrind != 0 ) - block->ipbits = req->addr->ipbits; - else block->ipbits = 0xffff, printf("null addr\n"); - block->recvlen = datalen; - bp->blocks[bundlei] = block; - bp->numrecv++; - //iguana_txdataQ(coin,req,bp,bundlei); - } - - //printf("%s hdrsi.%d recv[%d] dur.%.0f avetimes.(%.2f %.2f) numpendinds.%d %f\n",bits256_str(block->hash2),hdrs->hdrsi,bundlei,duration,hdrs->avetime,coin->avetime,coin->numpendings,hdrs->issued[bundlei]); - } - } - else //if ( (rand() % 100) == 0 ) - printf("cant create block.%llx\n",(long long)origblock->hash2.txid); - return(req); - } - - struct iguana_bundlereq *iguana_recvtxids(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *txids,int32_t n) - { - return(req); - } - - struct iguana_bundlereq *iguana_recvunconfirmed(struct iguana_info *coin,struct iguana_bundlereq *req,uint8_t *data,int32_t datalen) - { - return(req); - } - - int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp) // single threaded - { - int32_t flag = 0; struct iguana_bundlereq *req; - *newhwmp = 0; - while ( flag < 10000 && (req= queue_dequeue(&coin->bundlesQ,0)) != 0 ) - { - //printf("%s bundlesQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); - if ( req->type == 'B' ) // one block with all txdata - req = iguana_recvblock(coin,req->addr,req,&req->block,req->numtx,req->datalen,newhwmp); - else if ( req->type == 'H' ) // blockhdrs (doesnt have txn_count!) - { - if ( (req= iguana_recvblockhdrs(coin,req,req->blocks,req->n,newhwmp)) != 0 ) - { - if ( req->blocks != 0 ) - myfree(req->blocks,sizeof(*req->blocks) * req->n), req->blocks = 0; - } - } - else if ( req->type == 'S' ) // blockhashes - { - if ( (req= iguana_recvblockhashes(coin,req,req->hashes,req->n)) != 0 && req->hashes != 0 ) - myfree(req->hashes,sizeof(*req->hashes) * req->n), req->hashes = 0; - } - else if ( req->type == 'U' ) // unconfirmed tx - req = iguana_recvunconfirmed(coin,req,req->serialized,req->datalen); - else if ( req->type == 'T' ) // txids from inv - { - if ( (req= iguana_recvtxids(coin,req,req->hashes,req->n)) != 0 ) - myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0; - } - else printf("iguana_updatebundles unknown type.%c\n",req->type); - flag++; - if ( req != 0 ) - myfree(req,req->allocsize), req = 0; - } - return(flag); - } - - - int32_t iguana_issueloop(struct iguana_info *coin) - { - static uint32_t lastdisp; - int32_t i,closestbundle,bundlei,qsize,RTqsize,m,numactive,numwaiting,maxwaiting,lastbundle,n,dispflag = 0,flag = 0; - int64_t remaining,closest; struct iguana_bundle *bp,*prevbp,*nextbp; bits256 hash2; struct iguana_block *block; - if ( time(NULL) > lastdisp+13 ) - { - dispflag = 1; - lastdisp = (uint32_t)time(NULL); - } - qsize = queue_size(&coin->blocksQ); - if ( qsize == 0 ) - coin->bcount++; - else coin->bcount = 0; - maxwaiting = (coin->MAXBUNDLES * coin->chain->bundlesize); - numwaiting = 0; - numactive = 0; - prevbp = nextbp = 0; - lastbundle = -1; - for (i=coin->bundlescount-1; i>=0; i--) - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 && bp->blockhashes != 0 ) - { - lastbundle = i; - break; - } - if ( lastbundle != coin->lastbundle ) - coin->lastbundletime = (uint32_t)time(NULL); - coin->lastbundle = lastbundle; - if ( 0 && time(NULL) < coin->starttime+60 ) - lastbundle = -1; - n = 0; - closest = closestbundle = -1; - for (i=0; ibundlescount; i++) - { - qsize = queue_size(&coin->blocksQ); - m = 0; - if ( (bp= coin->bundles[i]) != 0 ) - { - nextbp = (i < coin->bundlescount-1) ? coin->bundles[i+1] : 0; - if ( bp->emitfinish == 0 ) - { - //iguana_bundlecheck(coin,bp,numactive == 0 || i == coin->closestbundle || i == lastbundle); - iguana_bundlecheck(coin,bp,i == coin->closestbundle); - if ( bp->numrecv > 3 || numactive == 0 ) - { - numactive++; - remaining = (bp->estsize - bp->datasize) + (rand() % (1 + bp->estsize))/100; - if ( remaining > 0 && (closest < 0 || remaining < closest) ) - { - //printf("closest.[%d] %d -> R.%d (%d - %d)\n",closestbundle,(int)closest,(int)remaining,(int)bp->estsize,(int)bp->datasize); - closest = remaining; - closestbundle = i; - } - } - //if ( i < (coin->numemitted+coin->MAXPENDING) && numactive >= coin->MAXPENDING && i != coin->closestbundle && i != lastbundle ) - continue; - RTqsize = queue_size(&coin->blocksQ); - for (bundlei=0; bundlein && bundleichain->bundlesize; bundlei++) - { - if ( (block= bp->blocks[bundlei]) != 0 && block->ipbits != 0 ) - { - m++; - //printf("hashes.%p numrecv.%d hdrs->n.%d qsize.%d\n",bp->blockhashes,bp->numrecv,bp->n,qsize); - continue; - } - hash2 = iguana_bundleihash2(coin,bp,bundlei); - if ( bits256_nonz(hash2) > 0 ) - { - //printf("hdrsi.%d qsize.%d bcount.%d check bundlei.%d bit.%d %.3f lag %.3f ave %.3f\n",bp->ramchain.hdrsi,qsize,coin->bcount,bundlei,GETBIT(bp->recv,bundlei),bp->issued[bundlei],milliseconds() - bp->issued[bundlei],bp->avetime); - if ( (block= bp->blocks[bundlei]) == 0 || block->ipbits == 0 ) - //if ( GETBIT(bp->recv,bundlei) == 0 ) - { - if ( bp->issued[bundlei] > SMALLVAL ) - numwaiting++; - if ( numwaiting < maxwaiting && (bp->issued[bundlei] == 0 || (qsize == 0 && coin->bcount > 100 && milliseconds() > (bp->issued[bundlei] + bp->avetime*2))) )//()) ) - { - if ( RTqsize < maxwaiting && (i == lastbundle || i == coin->closestbundle) ) - { - char str[65]; - bits256_str(str,hash2); - if ( (rand() % 10000) == 0 && bp->issued[bundlei] > SMALLVAL ) - printf("issue.%d:%d of %d %s lag %f ave %f\n",bp->ramchain.hdrsi,bundlei,bp->n,str,milliseconds() - bp->issued[bundlei],bp->avetime); - bp->issued[bundlei] = milliseconds(); - n++; - flag += (iguana_blockQ(coin,bp,bundlei,hash2,0) > 0); - } - } - } - } //lse printf("skip.%d %s\n",numbundles,bits256_str(hash2)); - } - } else m = coin->chain->bundlesize; - } - prevbp = bp; - if ( dispflag != 0 && bp != 0 && bp->emitfinish == 0 && m > 0 ) - printf("%s",iguana_bundledisp(coin,prevbp,bp,nextbp,m)); - } - //if ( closestbundle >= 0 && (coin->closestbundle < 0 || coin->bundles[coin->closestbundle]->numrecv >= coin->chain->bundlesize) ) - coin->closestbundle = closestbundle; - char str[65]; - if ( dispflag != 0 ) - printf(" PENDINGBUNDLES lastbundle.%d closest.[%d] %s | %d\n",lastbundle,closestbundle,mbstr(str,closest),coin->closestbundle); - return(flag); - } - - int32_t iguana_reqhdrs(struct iguana_info *coin) - { - int32_t i,n = 0; struct iguana_bundle *bp; char hashstr[65]; - //printf("needhdrs.%d qsize.%d zcount.%d\n",iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); - if ( iguana_needhdrs(coin) > 0 && queue_size(&coin->hdrsQ) == 0 ) - { - if ( coin->zcount++ > 10 ) - { - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - if ( time(NULL) > bp->issuetime+7 )//&& coin->numpendings < coin->MAXBUNDLES ) - { - if ( bp->issuetime == 0 ) - coin->numpendings++; - if ( bp->blockhashes == 0 || bp->n < coin->chain->bundlesize ) - { - char str[65]; - bits256_str(str,bp->blockhashes[0]); - printf("(%s %d).%d ",str,bp->ramchain.bundleheight,i); - init_hexbytes_noT(hashstr,bp->blockhashes[0].bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - n++; - } - bp->issuetime = (uint32_t)time(NULL); - } - } - } - if ( n > 0 ) - printf("REQ HDRS pending.%d\n",coin->numpendings); - coin->zcount = 0; - } - } else coin->zcount = 0; - return(n); - } - - int32_t iguana_updatecounts(struct iguana_info *coin) - { - int32_t h,flag = 0; - //SETBIT(coin->havehash,0); - //while ( iguana_havetxdata(coin,coin->blocks.recvblocks) != 0 ) - // coin->blocks.recvblocks++; - //if ( coin->blocks.recvblocks < 1 ) - // coin->blocks.recvblocks = 1; - //while ( GETBIT(coin->havehash,coin->blocks.hashblocks) > 0 ) - // coin->blocks.hashblocks++; - h = coin->blocks.hwmheight - coin->chain->bundlesize; - flag = 0; - while ( 0 && iguana_bundleready(coin,h) > 0 ) - { - h += coin->chain->bundlesize; - flag++; - } - if ( flag != 0 ) - iguana_savehdrs(coin); - return(flag); - } - - int32_t iguana_processrecv(struct iguana_info *coin) // single threaded - { - int32_t newhwm = 0,flag = 0; - //printf("process bundlesQ\n"); - flag += iguana_processbundlesQ(coin,&newhwm); - //printf("iguana_updatecounts\n"); - flag += iguana_updatecounts(coin); - //printf("iguana_reqhdrs\n"); - flag += iguana_reqhdrs(coin); - //printf("iguana_issueloop\n"); - flag += iguana_issueloop(coin); - //if ( newhwm != 0 ) - // flag += iguana_lookahead(coin,&hash2,coin->blocks.hwmheight); - return(flag); - } - - - struct iguana_block *iguana_recvblockhdr(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock,int32_t *newhwmp) - { - struct iguana_bundle *prevbp,*bp = 0; int32_t j,prevbundlei; struct iguana_block *block; char str[65]; - (*bpp) = 0; - *bundleip = -2; - if ( (block= iguana_blockhashset(coin,-1,origblock->hash2,1)) == 0 ) - { - printf("error getting block for %s\n",bits256_str(str,origblock->hash2)); - return(0); - } - block->prev_block = origblock->prev_block; - if ( (bp= iguana_bundlefind(coin,bundleip,block->hash2,IGUANA_SEARCHBUNDLE)) == 0 ) - { - if ( (prevbp= iguana_bundlefind(coin,&prevbundlei,block->prev_block,IGUANA_SEARCHBUNDLE)) == 0 ) - { - printf("cant find prev.%s either\n",bits256_str(str,block->prev_block)); - for (j=0; jbundlescount; j++) - { - if ( (bp= coin->bundles[j]) != 0 ) - { - if ( (bp= iguana_bundlescan(coin,bundleip,bp,block->hash2,IGUANA_SEARCHBUNDLE)) != 0 ) - { - (*bpp) = bp; - char str[65]; - bits256_str(str,block->hash2); - printf("FOUND.%s in bundle.[%d:%d] %d\n",str,bp->ramchain.hdrsi,*bundleip,bp->ramchain.bundleheight + *bundleip); - iguana_bundleblockadd(coin,bp,*bundleip,block->hash2); - return(block); - } - } - } - char str[65]; - bits256_str(str,block->hash2); - printf("CANTFIND.%s\n",str); - return(block); - } - else - { - (*bpp) = prevbp; - char str[65]; - //printf("found bp.%p prevbundlei.%d\n",prevbp,prevbundlei); - if ( prevbundlei >= 0 && prevbundlei < coin->chain->bundlesize-1 ) - { - *bundleip = prevbundlei + 1; - if ( prevbundlei == 0 ) - iguana_blockQ(coin,bp,0,block->prev_block,1); - if ( prevbp != 0 ) - { - //bits256_str(str,block->hash2); - //printf("prev FOUND.%s in bundle.[%d:%d] %d\n",str,prevbp->ramchain.hdrsi,*bundleip,prevbp->ramchain.bundleheight + *bundleip); - iguana_bundleblockadd(coin,prevbp,*bundleip,block->hash2); - } - } - if ( 0 && prevbundlei == coin->chain->bundlesize-1 ) - { - bits256 zero; - memset(zero.bytes,0,sizeof(zero)); - bits256_str(str,block->hash2); - printf("prev AUTOCREATE.%s\n",str); - iguana_bundlecreate(coin,block->hash2,zero); - } - return(block); - } - } - else - { - //char str[65],str2[65]; - (*bpp) = bp; - //printf("blockadd.%s %s %d\n",bits256_str(str,block->hash2),bits256_str(str2,origblock->hash2),*bundleip); - iguana_bundleblockadd(coin,bp,*bundleip,block->hash2); - if ( *bundleip > 0 && bits256_nonz(block->prev_block) > 0 ) - iguana_bundleblockadd(coin,bp,(*bundleip) - 1,block->prev_block); - } - return(block); - } - - /*static int32_t _sort_by_itemind(struct iguana_block *a, struct iguana_block *b) - { - if (a->hh.itemind == b->hh.itemind) return 0; - return (a->hh.itemind < b->hh.itemind) ? -1 : 1; - }*/ - - int32_t _iguana_verifysort(struct iguana_info *coin) - { - int32_t height,prevheight = -1,i = 0,run = 0; struct iguana_block *block,*tmp; - HASH_ITER(hh,coin->blocks.hash,block,tmp) - { - if ( (height= block->hh.itemind) < 0 ) - printf("sortblocks error i.%d height.%d?\n",i,height), getchar(); - if ( height <= prevheight ) - printf("sortblocks error i.%d height.%d vs prevheight.%d\n",i,height,prevheight), getchar(); - if ( height == run ) - run++; - i++; - } - printf("_iguana_verifysort: n.%d run.%d\n",i,run); - return(run); - } - - /*int32_t iguana_blocksort(struct iguana_info *coin) - { - int32_t hashblocks; - portable_mutex_lock(&coin->blocks_mutex); - HASH_SORT(coin->blocks.hash,_sort_by_itemind); - hashblocks = _iguana_verifysort(coin); - portable_mutex_unlock(&coin->blocks_mutex); - return(hashblocks); - }*/ - - int32_t _iguana_blocklink(struct iguana_info *coin,struct iguana_block *block) - { - int32_t height,n = 0; struct iguana_block *prev,*next; - if ( block == 0 ) - printf("iguana_blockslink: illegal null block %p\n",block), getchar(); - block->hh.next = 0, block->hh.prev = 0; - if ( (height= (int32_t)block->hh.itemind) > 0 && (prev= iguana_block(coin,height-1)) != 0 ) - { - prev->hh.next = block; - block->hh.prev = prev; - n++; - } - if ( (next= iguana_block(coin,height+1)) != 0 ) - { - block->hh.next = next; - next->hh.prev = block; - n++; - } - return(n); - } - - /*bits256 iguana_prevblockhash(struct iguana_info *coin,bits256 hash2) - { - struct iguana_block *block; bits256 tmp; - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockfind(coin,hash2)) != 0 ) - return(block->prev_block); - else - { - memset(tmp.bytes,0,sizeof(tmp)); - return(tmp); - } - }*/ - - int32_t iguana_hash2height(struct iguana_info *coin,bits256 hash2) - { - struct iguana_block *block; - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( block->height >= 0 ) - return(block->height); - else return(block->hh.itemind); - } - else return(-1); - } - - int32_t iguana_blockheight(struct iguana_info *coin,struct iguana_block *block) - { - struct iguana_block *prev; int32_t height; - if ( (height= iguana_hash2height(coin,block->hash2)) < 0 ) - { - if ( (prev= iguana_blockfind(coin,block->prev_block)) != 0 ) - { - if ( prev->height >= 0 ) - return(prev->height+1); - else if ( (int32_t)prev->hh.itemind >= 0 ) - return(prev->hh.itemind + 1); - } - } - return(-1); - } - - int32_t iguana_chainheight(struct iguana_info *coin,struct iguana_block *block) - { - if ( block->mainchain != 0 && block->height >= 0 ) - return(block->height); - return(-1); - } - - void *iguana_blockptr(struct iguana_info *coin,int32_t height) - { - struct iguana_block *block; - if ( height < 0 || height >= coin->blocks.maxbits ) - { - //printf("iguana_blockptr height.%d vs maxbits.%d\n",height,coin->blocks.maxbits); - return(0); - } - if ( (block= coin->blocks.ptrs[height]) != 0 ) - return(block); - return(0); - } - - /*void *iguana_bundletxdata(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei) - { - struct iguana_block *block; void *txdata = 0; - if ( bp != 0 && bundlei >= 0 && bundlei < coin->chain->bundlesize && GETBIT(bp->recv,bundlei) != 0 && (block= bp->blocks[bundlei]) != 0 ) - { - txdata = block->txdata; - } - //printf("txdata.%p\n",txdata); - return(txdata); - }*/ - - int32_t iguana_avail(struct iguana_info *coin,int32_t height,int32_t n) - { - int32_t i,nonz = 0; - for (i=0; ichain->bundlesize; - if ( GETBIT(coin->bundleready,height/num) != 0 ) - return(1); - for (i=0; ibundleready,height/num); - return(1); - } - - int32_t iguana_fixblocks(struct iguana_info *coin,int32_t startheight,int32_t endheight) - { - struct iguana_block *block,space,origblock; int32_t height,n = 0; - for (height=startheight; height<=endheight; height++) - { - if ( (block= iguana_block(coin,&space,height)) != 0 ) - { - origblock = space; - iguana_setdependencies(coin,block); - if ( memcmp(&origblock,block,sizeof(origblock)) != 0 ) - { - printf("%d ",height); - n++; - iguana_kvwrite(coin,coin->blocks.db,0,block,(uint32_t *)&block->height); - } - } - } - iguana_syncmap(&coin->blocks.db->M,0); - return(n); - } - - int32_t iguana_blockcmp(struct iguana_info *coin,struct iguana_block *A,struct iguana_block *B,int32_t fastflag) - { - struct iguana_block tmpA,tmpB; - tmpA = *A, tmpB = *B; - memset(&tmpA.L,0,sizeof(tmpA.L)), memset(&tmpB.L,0,sizeof(tmpB.L)); - memset(&tmpA.hh,0,sizeof(tmpA.hh)), memset(&tmpB.hh,0,sizeof(tmpB.hh)); - tmpA.numvouts = tmpA.numvins = tmpA.tbd = tmpB.numvouts = tmpB.numvins = tmpB.tbd = 0; - if ( memcmp(&tmpA,&tmpB,sizeof(tmpA)) != 0 ) - return(-1); - if ( fastflag == 0 ) - { - if ( iguana_setdependencies(coin,&tmpA) != iguana_setdependencies(coin,&tmpB) || memcmp(&tmpA,&tmpB,sizeof(tmpA)) == 0 ) - return(-1); - } - return(0); - }*/ - - /* - int32_t iguana_checkblock(struct iguana_info *coin,int32_t dispflag,struct iguana_block *block,bits256 hash2) - { - struct iguana_block checkspace,prevspace,*checkblock,*prev; bits256 prevhash; int32_t retval = 0; - if ( block != 0 ) - { - if ( (checkblock= iguana_block(coin,&checkspace,block->height)) == 0 ) - { - if ( dispflag != 0 ) - printf("cant find checkblock %s at %d\n",bits256_str(hash2),block->height); - return(-2); - } - if ( memcmp(block,checkblock,sizeof(*block)) != 0 ) - { - if ( dispflag != 0 ) - printf("compare error %s block.%d vs checkblock.%d\n",bits256_str(hash2),block->height,checkblock->height); - return(-3); - } - prevhash = iguana_prevblockhash(coin,hash2); - if ( bits256_nonz(prevhash) != 0 ) - { - if ( memcmp(prevhash.bytes,block->prev_block.bytes,sizeof(prevhash)) != 0 ) - { - if ( dispflag != 0 ) - { - printf("height.%d block->prev %s vs ",block->height,bits256_str(block->prev_block)); - printf("prevhash mismatch %s\n",bits256_str(prevhash)); - } - return(-4); - } - } else prevhash = block->prev_block; - if ( block->height == 0 ) - { - //printf("reached genesis! numvalid.%d from %s\n",numvalid,bits256_str(coin->blocks.best_chain)); - return(0); - } - //printf("block.%d\n",block->height); - if ( (prev= iguana_blockfind(coin,&prevspace,prevhash)) == 0 ) - { - if ( dispflag != 0 ) - printf("cant find prevhash for (%s).%d\n",bits256_str(hash2),block->height); - return(-5); - } //else printf("block->height.%d prev height.%d %s\n",block->height,prev->height,bits256_str(prevhash)); - if ( fabs(block->L.PoW - (prev->L.PoW + PoW_from_compact(block->bits,coin->chain->unitval))) > SMALLVAL ) - { - if ( dispflag != 0 ) - printf("PoW mismatch: %s %.15f != %.15f (%.15f %.15f)\n",bits256_str(hash2),block->L.PoW,(prev->L.PoW + PoW_from_compact(block->bits,coin->chain->unitval)),prev->L.PoW,PoW_from_compact(block->bits,coin->chain->unitval)); - block->L.PoW = (prev->L.PoW + PoW_from_compact(block->bits,coin->chain->unitval)); - retval = -1000; - } - if ( block->txn_count != 0 && block->L.numtxids != (prev->L.numtxids + prev->txn_count) && block->L.numunspents != (prev->L.numunspents + prev->numvouts) && block->L.numspends != (prev->L.numspends + prev->numvins) ) - { - if ( dispflag != 0 ) - printf("firsttxidind mismatch %s T%d != %d (%d + %d) || U%d != %d (%d + %d) || S%d != %d (%d + %d)\n",bits256_str(hash2),block->L.numtxids,(prev->L.numtxids + prev->txn_count),prev->L.numtxids,prev->txn_count,block->L.numunspents,(prev->L.numunspents + prev->numvouts),prev->L.numunspents,prev->numvouts,block->L.numspends,(prev->L.numspends + prev->numvins),prev->L.numspends,prev->numvins); - block->L.numtxids = (prev->L.numtxids + prev->txn_count); - block->L.numunspents = (prev->L.numunspents + prev->numvouts); - block->L.numspends = (prev->L.numspends + prev->numvins); - return(retval - 10000); - } - return(retval); - } - if ( dispflag != 0 ) - printf("iguana_checkblock: null ptr\n"); - return(-8); - } - - int32_t _iguana_audit(struct iguana_info *coin) - { - bits256 hash2; struct iguana_block *block,space; int32_t numvalid = 0; - hash2 = coin->blocks.hwmchain; - while ( (block= iguana_blockfind(coin,&space,hash2)) != 0 ) - { - if ( iguana_checkblock(coin,1,block,hash2) == 0 ) - { - numvalid++; - if ( block->height == 0 ) - return(numvalid); - hash2 = block->prev_block; - } - } - printf("iguana_audit numvalid.%d vs %d\n",numvalid,coin->blocks.hwmheight); - return(numvalid); - } - - void iguana_audit(struct iguana_info *coin) - { - int32_t numvalid; - if ( (numvalid= _iguana_audit(coin)) < 0 || numvalid != coin->blocks.hwmheight ) - { - printf("iguana_audit error.%d\n",numvalid); - iguana_kvdisp(coin,coin->blocks.db); - } - }*/ - - - /*int32_t iguana_lookahead(struct iguana_info *coin,bits256 *hash2p,int32_t height) - { - struct iguana_block space,*block; bits256 hash2; int32_t err,h,n = 0; - while ( (block= iguana_block(coin,&space,height)) != 0 ) - { - *hash2p = hash2 = iguana_blockhash(coin,height); - if ( (err= iguana_checkblock(coin,1,block,hash2)) == 0 || err <= -1000 ) - { - if ( err < 0 ) - { - h = height; - printf("fixup height.%d\n",height); - iguana_kvwrite(coin,coin->blocks.db,hash2.bytes,block,(uint32_t *)&h); - //getchar(); - } - if ( (h= iguana_addblock(coin,hash2,block)) != height ) - { - printf("height.%d h.%d n.%d didnt work\n",height,h,n); - //getchar(); - break; - } - n++; - height++; - coin->blocks.hwmheight = height; - } - else - { - printf("height.%d %s error.%d\n",height,bits256_str(hash2),err); - break; - } - } - printf("lookahead stopped at height.%d\n",height); - return(n); - } - */ - - int32_t iguana_setchainvars(struct iguana_info *coin,struct iguana_prevdep *lp,bits256 hash2,uint32_t nBits,bits256 prevhash,int32_t txn_count) // uint32_t *firsttxidindp,uint32_t *firstvoutp,uint32_t *firstvinp,double *PoWp - { - int32_t height=-1,firstvout=0,firstvin=0,firsttxidind=0; double PoW; - struct iguana_prevdep *prevlp; struct iguana_block *prev; - memset(lp,0,sizeof(*lp)); - if ( memcmp(coin->chain->genesis_hashdata,hash2.bytes,sizeof(hash2)) == 0 ) - { - PoW = PoW_from_compact(nBits,coin->chain->unitval); - height = 0; - firsttxidind = firstvout = firstvin = 1; - printf("set genesis vars nBits.%x\n",nBits); - } - else - { - if ( (prev= iguana_blockfind(coin,prevhash)) == 0 ) - { - if ( iguana_needhdrs(coin) == 0 ) - { - char str[65],str2[65]; - bits256_str(str,hash2); - bits256_str(str2,prevhash); - printf("hash2.(%s) ",str); - fprintf(stderr,"iguana_blockchain no prev block.(%s)\n",str2); - //getchar(); - } - return(-1); - } - else - { - height = prev->height + 1; - if ( (prevlp= iguana_prevdepfind(coin,prev)) != 0 ) - { - PoW = (PoW_from_compact(nBits,coin->chain->unitval) + prevlp->PoW); - if ( txn_count > 0 && prevlp->numtxids > 0 && prev->numvouts > 0 && prevlp->numunspents > 0 && prevlp->numspends > 0 ) - { - firsttxidind = prevlp->numtxids + prev->txn_count; - firstvout = prevlp->numunspents + prev->numvouts; - firstvin = prevlp->numspends + prev->numvins; - //printf("PREV.%d firsttxidind.%d firstvout.%d+%d firstvin.%d+%d (%d %d %d)\n",prev->height,prev->L.numtxids,prev->L.numunspents,prev->numvouts,prev->L.numspends,prev->numvins,firsttxidind,firstvout,firstvin); - } - } - } - } - if ( lp != 0 ) - { - lp->PoW = PoW; - lp->numtxids = firsttxidind; - lp->numunspents = firstvout; - lp->numspends = firstvin; - } - //printf("set height.%d: %d %f firstvin.%d firstvout.%d\n",height,firsttxidind,PoW,firstvin,firstvout); - return(height); - } - - int32_t iguana_setdependencies(struct iguana_info *coin,struct iguana_block *block,struct iguana_prevdep *lp) - { - int32_t h,height; - if ( block == 0 ) - return(-1); - height = block->height; - if ( (h= iguana_setchainvars(coin,lp,block->hash2,block->bits,block->prev_block,block->txn_count)) == height ) - { - // place to make sure connected to ramchain - return(height); - } - if ( height < 0 ) - block->height = h; - //printf("dependencies returned %d vs %d\n",h,height); - return(-1); - } - - int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock) - { - int32_t h; - if ( (newblock->height= iguana_setdependencies(coin,newblock,lp)) >= 0 ) - { - if ( lp->PoW > coin->blocks.hwmPoW ) - { - if ( newblock->height+1 > coin->blocks.maxblocks ) - coin->blocks.maxblocks = (newblock->height + 1); - h = newblock->height; - iguana_kvwrite(coin,coin->blocks.db,hash2.bytes,newblock,(uint32_t *)&h); - coin->blocks.hwmheight = newblock->height; - coin->blocks.hwmPoW = lp->PoW; - coin->blocks.hwmchain = hash2; - coin->latest.blockhash = hash2; - coin->latest.merkle_root = newblock->merkle_root; - coin->latest.timestamp = newblock->timestamp; - coin->latest.height = coin->blocks.hwmheight; - char str[65],str2[65]; - bits256_str(str,newblock->hash2); - bits256_str(str2,coin->blocks.hwmchain); - printf("ADD %s %d:%d <- (%s) n.%u max.%u PoW %f 1st.%d numtx.%d\n",str,h,newblock->height,str2,coin->blocks.hwmheight+1,coin->blocks.maxblocks,lp->PoW,lp->numtxids,newblock->txn_count); - } - } else printf("error from setchain.%d\n",newblock->height); - if ( memcmp(hash2.bytes,coin->blocks.hwmchain.bytes,sizeof(hash2)) != 0 ) - { - char str[65]; - bits256_str(str,hash2); - if ( iguana_needhdrs(coin) == 0 ) - printf("ORPHAN.%s height.%d PoW %f vs best %f\n",str,newblock->height,lp->PoW,coin->blocks.hwmPoW); - newblock->height = -1; - } - return(newblock->height); - } - - else if ( strcmp(H->command,"headers") == 0 ) - { - struct iguana_msgblock msg; struct iguana_block *blocks; uint32_t n; struct iguana_prevdep L; - len = iguana_rwvarint32(0,data,&n); - if ( n <= IGUANA_MAXINV ) - { - blocks = mycalloc('i',1,sizeof(*blocks) * n); - height = -1; - memset(&L,0,sizeof(L)); - for (i=0; i 0 ) - { - height++; - L.numtxids += blocks[i].txn_count; - L.PoW += PoW_from_compact(blocks[i].bits,coin->chain->unitval); - } - } - //printf("GOT HEADERS n.%d len.%d\n",n,len); - iguana_gotheadersM(coin,addr,blocks,n); - //myfree(blocks,sizeof(*blocks) * n); - if ( len == datalen && addr != 0 ) - addr->msgcounts.headers++; - } else printf("got unexpected n.%d for headers\n",n); - } - - /*int32_t iguana_chainheight(struct iguana_info *coin,struct iguana_block *origblock) - { - static const bits256 zero; struct iguana_block *next,*block = origblock; - bits256 *blockhashes; char str[65]; int32_t i,max,toofar=0,height,n=0; - next = origblock; - iguana_memreset(&coin->blockMEM); - max = (int32_t)(coin->blockMEM.totalsize / sizeof(*blockhashes)); - blockhashes = iguana_memalloc(&coin->blockMEM,max*sizeof(*blockhashes),1); - while ( memcmp(block->prev_block.bytes,zero.bytes,sizeof(bits256)) != 0 ) - { - if ( n < max-1 ) - blockhashes[n++] = block->hash2; - else toofar = 1; - if ( (block= iguana_blockfind(coin,block->prev_block)) != 0 ) - { - //printf("i.%d %s chainheight.%d mainchain.%d\n",n,bits256_str(str,block->hash2),block->height,block->mainchain); - if ( block->mainchain != 0 && (height= block->height) >= 0 ) - { - iguana_chainextend(coin,next); - //printf("%s extend.%d from %d toofar.%d\n",bits256_str(str,block->hash2),n,height,toofar); - if ( toofar == 0 ) - { - for (i=0; iheight); - } - if ( iguana_chainextend(coin,next) < 0 ) - { - //printf("%d of %d: cant extend block.%s\n",i,n,bits256_str(str,blockhashes[n-1-i])); - return(origblock->height); - } - next = block; - } - return(origblock->height); - } - //printf("toofar means neg height\n"); - return(-1); - } - next = block; - } else break; - } // reached deadend or too far to link in - //printf("out of chainheight loop\n"); - return(origblock->height); - }*/ - - - /*int32_t iguana_issueloop(struct iguana_info *coin) - { - static uint32_t lastdisp; - int32_t i,closestbundle,qsize,m,numactive,numwaiting,maxwaiting,lastbundle,n,dispflag = 0,flag = 0; - int64_t remaining,closest; struct iguana_bundle *bp,*prevbp,*nextbp; - flag = iguana_reqhdrs(coin); - if ( time(NULL) > lastdisp+13 ) - { - dispflag = 1; - lastdisp = (uint32_t)time(NULL); - } - qsize = queue_size(&coin->blocksQ); - if ( qsize == 0 ) - coin->bcount++; - else coin->bcount = 0; - maxwaiting = (coin->MAXBUNDLES * coin->chain->bundlesize); - numwaiting = 0; - numactive = 0; - prevbp = nextbp = 0; - lastbundle = -1; - for (i=coin->bundlescount-1; i>=0; i--) - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 && bp->blockhashes != 0 ) - { - lastbundle = i; - break; - } - if ( lastbundle != coin->lastbundle ) - coin->lastbundletime = (uint32_t)time(NULL); - coin->lastbundle = lastbundle; - if ( 0 && time(NULL) < coin->starttime+60 ) - lastbundle = -1; - n = 0; - closest = closestbundle = -1; - for (i=0; ibundlescount; i++) - { - qsize = queue_size(&coin->blocksQ); - m = 0; - if ( (bp= coin->bundles[i]) != 0 ) - { - nextbp = (i < coin->bundlescount-1) ? coin->bundles[i+1] : 0; - if ( bp->emitfinish == 0 ) - { - m = (bp->n - bp->numrecv); - if ( bp->numrecv > 3 || numactive == 0 ) - { - numactive++; - remaining = (bp->estsize - bp->datasize) + (rand() % (1 + bp->estsize))/100; - if ( remaining > 0 && (closest < 0 || remaining < closest) ) - { - //printf("closest.[%d] %d -> R.%d (%d - %d)\n",closestbundle,(int)closest,(int)remaining,(int)bp->estsize,(int)bp->datasize); - closest = remaining; - closestbundle = i; - } - } - if ( dispflag != 0 ) - printf("%s",iguana_bundledisp(coin,prevbp,bp,nextbp,m)); - } - } - prevbp = bp; - } - //if ( closestbundle >= 0 && (coin->closestbundle < 0 || coin->bundles[coin->closestbundle]->numrecv >= coin->chain->bundlesize) ) - coin->closestbundle = closestbundle; - char str[65]; - if ( dispflag != 0 ) - printf(" PENDINGBUNDLES lastbundle.%d closest.[%d] %s | %d\n",lastbundle,closestbundle,mbstr(str,closest),coin->closestbundle); - return(flag); - }*/ - int32_t iguana_updatecounts(struct iguana_info *coin) - { - int32_t flag = 0; - //SETBIT(coin->havehash,0); - //while ( iguana_havetxdata(coin,coin->blocks.recvblocks) != 0 ) - // coin->blocks.recvblocks++; - //if ( coin->blocks.recvblocks < 1 ) - // coin->blocks.recvblocks = 1; - //while ( GETBIT(coin->havehash,coin->blocks.hashblocks) > 0 ) - // coin->blocks.hashblocks++; - return(flag); - } - - //printf("iguana_issueloop\n"); - //flag += iguana_issueloop(coin); - //if ( newhwm != 0 ) - // flag += iguana_lookahead(coin,&hash2,coin->blocks.hwmheight); - - /*struct iguana_block *iguana_blockadd(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock) - { - struct iguana_block *checkblock,*block = 0; char str[65]; struct iguana_bundle *bp = *bpp; - int32_t setval,checki,bundlei,bundleheight,bundlesize = coin->chain->bundlesize; - bundlei = *bundleip; - *bundleip = -2; - *bpp = 0; - if ( origblock == 0 ) - return(0); - //iguana_blockhashset(coin,-1,origblock->prev_block,1); - if ( bits256_nonz(origblock->hash2) > 0 && (block= iguana_blockhashset(coin,-1,origblock->hash2,1)) != 0 ) - { - //printf("blockadd.(%s) -> %d (%s)\n",bits256_str(str,origblock->prev_block),block->height,bits256_str(str2,origblock->hash2)); - if ( bits256_nonz(block->prev_block) == 0 ) - iguana_blockcopy(coin,block,origblock); - if ( (bp= *bpp) == 0 ) - { - if ( (bp= iguana_bundlefind(coin,bpp,&bundlei,block->hash2)) == 0 ) - { - *bpp = 0, bundlei = -2; - //printf("a bundlefind.(%s) -> bundlei.%d\n",bits256_str(str,block->hash2),*bundleip); - if ( (bp= iguana_bundlefind(coin,bpp,&bundlei,block->prev_block)) == 0 ) - { - //iguana_chainheight(coin,block); - //printf("a prev bundlefind.(%s) -> bundlei.%d ht.%d\n",bits256_str(str,block->prev_block),*bundleip,block->height); - *bpp = 0; - *bundleip = -2; - return(block); - } - else - { - if ( *bundleip == bundlesize-1 ) - { - printf("b prev bundlefind.(%s) -> bundlei.%d\n",bits256_str(str,block->prev_block),*bundleip); - bundleheight = (bp->ramchain.bundleheight >= 0) ? (bp->ramchain.bundleheight + bundlesize) : -1; - printf("autocreateA: bundleheight.%d\n",bundleheight); - bundlei = -2; - *bpp = bp = iguana_bundlecreate(coin,&bundlei,bundleheight,block->hash2); - *bpp = 0; - *bundleip = -2; - return(block); - } - else if ( bundlei < coin->chain->bundlesize-1 ) - { - bundlei++; - if ( bp->n <= bundlei ) - bp->n = bundlei+1; - iguana_hash2set(coin,"add",bp,bundlei,block->hash2); - //printf("found prev.%s -> bundlei.%d\n",bits256_str(str,block->prev_block),bundlei); - } - } - } - else - { - // printf("found bp.%p bundlei.%d\n",bp,bundlei); - } - } - else if ( bundlei < -1 ) - { - bp = iguana_bundlefind(coin,bpp,&bundlei,block->hash2); - printf("c bundlefind.(%s) -> bundlei.%d\n",bits256_str(str,block->hash2),bundlei); - } else printf("last case bundleip %d\n",bundlei); - *bpp = bp; - *bundleip = bundlei; - //printf("bundlei.%d for %s\n",bundlei,bits256_str(str,block->hash2)); - if ( memcmp(bp->hashes[bundlei].bytes,block->hash2.bytes,sizeof(bits256)) != 0 ) - printf("honk? find error %s\n",bits256_str(str,bp->hashes[bundlei])), getchar(); - if ( bp == 0 || bundlei < -1 ) - { - printf("%s null bp? %p or illegal bundlei.%d block.%p\n",bits256_str(str,block->hash2),bp,bundlei,block); - return(block); - } - if ( (setval= iguana_bundlehash2add(coin,&checkblock,bp,bundlei,block->hash2)) == 0 && checkblock == block ) - { - if ( bp->blocks[bundlei] != 0 ) - { - if ( bp->blocks[bundlei] != block ) - printf("blockadd: error blocks[%d] %p %d != %d %p\n",bundlei,bp->blocks[bundlei],bp->blocks[bundlei]->height,block->height,block); - } else bp->blocks[bundlei] = block; - //iguana_bundlehash2add(coin,0,bp,bundlei-1,block->prev_block); - //printf("setval.%d bp.%p bundlei.%d\n",setval,bp,bundlei); - } - else if ( setval > 0 ) - { - if ( bundlei == bundlesize ) - { - bundleheight = (bp->ramchain.bundleheight >= 0) ? (bp->ramchain.bundleheight + bundlesize) : -1; - printf("autocreate: bundleheight.%d\n",bundleheight); - iguana_bundlecreate(coin,&checki,bundleheight,block->hash2); - } - printf("setval.%d bundlei.%d\n",setval,bundlei); - } else printf("blockadd: error.%d adding hash2, checkblock.%p vs %p\n",setval,checkblock,block); - //printf("bundleblockadd.[%d] of %d <- %s setval.%d %p\n",bundlei,bp->n,bits256_str(str,block->hash2),setval,block); - } else printf("bundleblockadd: block.%p error\n",block); - return(block); - } - - struct iguana_block *iguana_bundleblockadd(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock) - { - struct iguana_block *block,*retblock; int32_t i,oldhwm; struct iguana_bundle *bp; - bits256 *hash2p,hash2; char str[65]; struct iguana_bloominds bit; - oldhwm = coin->blocks.hwmchain.height; - *bpp = 0, *bundleip = -2; - if ( (retblock= iguana_blockadd(coin,bpp,bundleip,origblock)) != 0 ) - { - block = retblock; - //iguana_chainextend(coin,block); - if ( block->height >= 0 && (hash2p= iguana_blockhashptr(coin,coin->blocks.hashblocks)) != 0 ) - *hash2p = block->hash2; - if ( oldhwm != coin->blocks.hwmchain.height ) - { - if ( oldhwm < coin->blocks.hashblocks ) - coin->blocks.hashblocks = oldhwm; - while ( coin->blocks.hashblocks < coin->blocks.hwmchain.height && (hash2p= iguana_blockhashptr(coin,coin->blocks.hashblocks)) != 0 ) - { - hash2 = *hash2p; - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( hash2p == 0 ) - { - printf("iguana_bundleblockadd B cant find coin->blocks.hashblocks %d\n",coin->blocks.hashblocks); - break; - } - *hash2p = hash2; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - if ( coin->blocks.hashblocks >= bp->ramchain.bundleheight && coin->blocks.hashblocks < bp->ramchain.bundleheight+bp->n ) - { - bit = iguana_calcbloom(block->hash2); - if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) - iguana_bloomset(coin,&bp->bloom,0,bit); - break; - } - } - } - //printf("ht.%d %s %p\n",block->height,bits256_str(str,hash2),hash2p); - bp = 0; - *bundleip = -2; - iguana_blockadd(coin,&bp,bundleip,block); - bp = 0; - *bundleip = -2; - if ( iguana_bundlefind(coin,&bp,bundleip,block->hash2) == 0 ) - { - printf("iguana_bundleblockadd A cant find just added.%s bundlei.%d\n",bits256_str(str,hash2),*bundleip); - bp = 0; - *bundleip = -2; - iguana_bundlefind(coin,&bp,bundleip,block->hash2); - break; - } - coin->blocks.hashblocks++; - block = 0; - } - else - { - //printf("break loop block.%p %s coin->blocks.hashblocks %d vs %d\n",block,bits256_str(str,hash2),coin->blocks.hashblocks,coin->blocks.hwmheight); - break; - } - } - } - } else printf("iguana_bundleblockadd returns null\n"); - return(retblock); - }*/ - int64_t iguana_ramchain_compact(struct iguana_ramchain *ramchain,int32_t numpkinds,int32_t numexternaltxids) - { - int32_t i,diff; int64_t offset; bits256 *src,*dest,tmp; - diff = (ramchain->data->numpkinds - numpkinds); - src = (bits256 *)((long)ramchain->mem->ptr + (long)ramchain->data->Xoffset); - offset = ramchain->data->Poffset + (sizeof(struct iguana_pkhash) * numpkinds); - ramchain->data->Xoffset = offset + ((sizeof(struct iguana_account)+sizeof(struct iguana_pkextra)) * numpkinds); - if ( numpkinds < ramchain->data->numpkinds ) - { - ramchain->data->numpkinds = numpkinds; - dest = (bits256 *)((long)ramchain->mem->ptr + (long)offset); - for (i=0; idata->numexternaltxids = numexternaltxids; - ramchain->mem->used = offset; - return(offset); - } - - long iguana_blockramchainPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen) - { - RAMCHAIN_PTRS; struct iguana_ramchain *ramchain = &addr->ramchain; - struct iguana_msgtx *tx; int32_t i,j,err,bundlei = -2; struct iguana_bundle *bp = 0; - if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.hash2) == 0 ) - return(-1); - SETBIT(bp->recv,bundlei); - bp->fpos[bundlei] = -1; - bp->recvlens[bundlei] = recvlen; - if ( iguana_ramchain_init(ramchain,&addr->TXDATA,&addr->HASHMEM,0,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0) == 0 ) - return(-1); - iguana_ramchain_link(ramchain,origtxdata->block.hash2,origtxdata->block.hash2,bp->hdrsi,bp->bundleheight+bundlei,1); - _iguana_ramchain_setptrs(ramchain,&T,&U,&U2,&S,&P,&P2,&A,&X); - if ( T == 0 || U == 0 || S == 0 || P == 0 || X == 0 ) - { - printf("fatal error getting txdataptrs\n"); - return(-1); - } - for (i=0; itxid,tx->tx_out,tx->tx_in); - for (j=0; jtx_out; j++) - iguana_ramchain_addunspent(ramchain,T,U,U2,S,P,P2,A,X,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen); - for (j=0; jtx_in; j++) - iguana_ramchain_addspend(ramchain,T,U,U2,S,P,P2,A,X,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].script,tx->vins[j].scriptlen,tx->vins[j].sequence); - } - ramchain->data->numpkinds = ramchain->pkind; - ramchain->data->numexternaltxids = ramchain->externalind; - ramchain->data->allocsize = iguana_ramchain_size(ramchain); - if ( (err= iguana_ramchainverify(ramchain)) == 0 ) - { - if ( (bp->fpos[bundlei]= iguana_ramchain_save(ramchain,addr->ipbits,bp->hashes[0],bundlei)) >= 0 ) - bp->ipbits[bundlei] = addr->ipbits; - } else printf("ramchain verification error.%d hdrsi.%d bundlei.%d\n",err,bp->hdrsi,bundlei); - iguana_ramchain_free(ramchain); - return(bp->fpos[bundlei]); - //iguana_hashfree(addr->txids,0); - //iguana_hashfree(addr->pkhashes,0); - - /*txidind = unspentind = spendind = pkind = 0; - for (i=numvouts=numpkinds=0; itxid = tx->txid, t->txidind = txidind, t->firstvout = unspentind, t->numvouts = tx->tx_out; - iguana_hashsetPT(ramchain,hashmem,'T',t->txid.bytes,txidind); - for (j=0; jtx_out; j++,numvouts++,unspentind++) - { - u = &U[unspentind]; - script = tx->vouts[j].pk_script, scriptlen = tx->vouts[j].pk_scriptlen; - iguana_calcrmd160(coin,rmd160,script,scriptlen,tx->txid); - //char str[65]; init_hexbytes_noT(str,rmd160,20), printf("pkhashes.%p %s %s new pkind.%d pkoffset.%d %d\n",addr->pkhashes,addr->ipaddr,str,numpkinds,txdata->pkoffset,(int32_t)((long)&P[numpkinds] - (long)txdata)); - if ( (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) - { - memcpy(P[numpkinds].rmd160,rmd160,sizeof(rmd160)); - if ( (ptr= iguana_hashsetPT(ramchain,hashmem,'P',&P[numpkinds],numpkinds)) == 0 ) - printf("fatal error adding pkhash\n"), getchar(); - //printf("added ptr.%p\n",ptr); - numpkinds++; - } //else printf("found %p[%d] for (%s)\n",ptr,ptr->hh.itemind,str); - u->value = tx->vouts[j].value, u->txidind = txidind; - u->pkind = ptr->hh.itemind; - P[u->pkind].firstunspentind = unspentind; - // prevunspentind requires having accts, so that waits for third pass - } - } - //printf("reallocP.%p -> ",P); - if ( (txdata->numpkinds= numpkinds) > 0 ) - P = iguana_memalloc(txmem,sizeof(*P) * numpkinds,0); - //printf("%p\n",P); - externalT = iguana_memalloc(txmem,0,1); - txidind = 0; - for (i=numvins=numexternal=0; ifirstvin = spendind; - for (j=0; jtx_in; j++) - { - script = tx->vins[j].script, scriptlen = tx->vins[j].scriptlen; - s = &S[spendind]; - if ( (sequence= tx->vins[j].sequence) != (uint32_t)-1 ) - s->diffsequence = 1; - s->vout = tx->vins[j].prev_vout; - if ( s->vout != 0xffff ) - { - if ( (ptr= iguana_hashfind(ramchain,'T',tx->vins[j].prev_hash.bytes)) != 0 ) - { - if ( (s->spendtxidind= ptr->hh.itemind) >= txdata->numtxids ) - { - s->external = 1; - s->spendtxidind -= txdata->numtxids; - } - } - else - { - s->external = 1; - externalT[numexternal] = tx->vins[j].prev_hash; - iguana_hashsetPT(ramchain,hashmem,'T',externalT[numexternal].bytes,txdata->numtxids + numexternal); - s->spendtxidind = numexternal++; - } - spendind++; - numvins++; - //printf("spendind.%d\n",spendind); - } //else printf("vout.%x\n",s->vout); - // prevspendind requires having accts, so that waits for third pass - } - t->numvins = numvins; - } - if ( (txdata->numexternaltxids= numexternal) > 0 ) - externalT = iguana_memalloc(txmem,sizeof(*externalT) * numexternal,0); - txdata->datalen = (int32_t)txmem->used; - txdata->numspends = numvins; - txdata->numpkinds = numpkinds; - txdata->numtxids = txn_count; - //char str[65],buf[9999]; - //for (j=buf[0]=0; j %d\n",buf,bundlei,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,recvlen,txdata->datalen); - if ( numvouts != txdata->numunspents || i != txdata->numtxids ) - { - printf("counts mismatch: numvins %d != %d txdata->numvins || numvouts %d != %d txdata->numvouts || i %d != %d txdata->numtxids\n",numvins,txdata->numspends,numvouts,txdata->numunspents,i,txdata->numtxids); - getchar(); - exit(-1); - } - else - { - static int32_t maxrecvlen,maxdatalen,maxhashmem; static double recvsum,datasum; - recvsum += recvlen, datasum += txdata->datalen; - if ( recvlen > maxrecvlen ) - printf("[%.3f] %.0f/%.0f maxrecvlen %d -> %d\n",recvsum/datasum,recvsum,datasum,maxrecvlen,recvlen), maxrecvlen = recvlen; - if ( txdata->datalen > maxdatalen ) - printf("[%.3f] %.0f/%.0f maxdatalen %d -> %d\n",recvsum/datasum,recvsum,datasum,maxdatalen,txdata->datalen), maxdatalen = txdata->datalen; - if ( hashmem != 0 && hashmem->used > maxhashmem ) - printf("[%.3f] %.0f/%.0f maxhashmem %d -> %ld\n",recvsum/datasum,recvsum,datasum,maxhashmem,hashmem->used), maxhashmem = (int32_t)hashmem->used; - if ( (rand() % 10000) == 0 ) - printf("[%.3f] %.0f/%.0f recvlen vs datalen\n",recvsum/datasum,recvsum,datasum); - if ( origtxdata != 0 ) - { - origtxdata->numspends = txdata->numspends; - origtxdata->numpkinds = txdata->numpkinds; - origtxdata->numexternaltxids = txdata->numexternaltxids; - } - } - if ( iguana_peertxsave(coin,&hdrsi,&bundlei,fname,addr,txdata) == txdata ) - { - #ifdef __APPLE__ - int32_t checki; struct iguana_txblock *checktx; struct iguana_ramchain R,*ptr = &R; - if ( 1 && (checktx= iguana_peertxdata(coin,&checki,fname,txmem,addr->ipbits,txdata->block.hash2)) != 0 && checki == bundlei ) - { - if ( iguana_ramchainset(coin,ptr,checktx) == ptr ) - { - char str[65]; int32_t j,err; - ptr->txids = ramchain->txids; - ptr->pkhashes = ramchain->pkhashes; - if ( (err= iguana_ramchainverifyPT(coin,ptr)) != 0 ) - { - for (j=0; jnumpkinds; j++) - init_hexbytes_noT(str,ptr->P[j].rmd160,20), printf("[%d %s] ",j,str); - printf("check err.%d ramchain.%s bundlei.%d T.%d U.%d S.%d P.%d\n",err,bits256_str(str,ptr->hash2),bundlei,ptr->numtxids,ptr->numunspents,ptr->numspends,ptr->numpkinds); - } - } - } - #endif - }*/ - //printf("free addrtables %p %p\n",addr->txids,addr->pkhashes); - // printf("numpkinds.%d numspends.%d\n",txdata->numpkinds,txdata->numspends); - } - - - /*void iguana_flushQ(struct iguana_info *coin,struct iguana_peer *addr) - { - struct iguana_helper *ptr; - if ( time(NULL) > addr->lastflush+3 ) - { - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->addr = addr; - ptr->type = 'F'; - //printf("FLUSH.%s %u lag.%d\n",addr->ipaddr,addr->lastflush,(int32_t)(time(NULL)-addr->lastflush)); - addr->lastflush = (uint32_t)time(NULL); - queue_enqueue("helperQ",&helperQ,&ptr->DL,0); - } - }*/ - - struct iguana_txblock *iguana_peertxsave(struct iguana_info *coin,int32_t *hdrsip,int32_t *bundleip,char *fname,struct iguana_peer *addr,struct iguana_txblock *txdata) - { - int32_t fpos,bundlei,i,z; FILE *fp; - fpos = 0; - *bundleip = bundlei = iguana_peerfname(coin,hdrsip,fname,addr->ipbits,txdata->block.hash2); - if ( bundlei < 0 || bundlei >= coin->chain->bundlesize ) - { - printf(" wont save.(%s) bundlei.%d\n",fname,bundlei); - return(0); - } - txdata->block.hdrsi = *hdrsip; - txdata->block.bundlei = bundlei; - if ( (fp= fopen(fname,"rb+")) == 0 ) - { - if ( (fp= fopen(fname,"wb")) != 0 ) - { - z = -1; - coin->peers.numfiles++; - for (i=0; ichain->bundlesize; i++) - fwrite(&z,1,sizeof(z),fp); - fclose(fp); - fp = fopen(fname,"rb+"); - } - } - if ( fp != 0 ) - { - fseek(fp,0,SEEK_END); - fpos = (int32_t)ftell(fp); - //printf("%s fpos.%d: bundlei.%d datalen.%d\n",fname,fpos,bundlei,txdata->datalen); - fwrite(&bundlei,1,sizeof(bundlei),fp); - fwrite(&txdata->block.hash2,1,sizeof(txdata->block.hash2),fp); - fwrite(&txdata->datalen,1,sizeof(txdata->datalen),fp); - fwrite(txdata,1,txdata->datalen,fp); - fseek(fp,bundlei * sizeof(bundlei),SEEK_SET); - //printf("bundlei[%d] <- fpos.%d\n",bundlei,fpos); - fwrite(&fpos,1,sizeof(fpos),fp); - fclose(fp); - //for (i=0; inumpkinds; i++) - // printf("%016lx ",*(long *)((struct iguana_pkhash *)((long)txdata + txdata->pkoffset))[i].rmd160); - //printf("create.(%s) %d ",fname,bundlei,coin->peers.numfiles); - //printf("bundlei.%d datalen.%d T.%d U.%d S.%d P.%d X.%d\n",bundlei,txdata->datalen,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids); - return(txdata); - } - return(0); - } - - /*if ( (n= ramchain->data->numtxids) > 0 ) - { - for (ramchain->txidind=ramchain->data->firsti; ramchain->txidindtxidind++) - { - tx = &T[ramchain->txidind]; - //printf("tx.%p (%d) %d txidind.%d\n",tx,(int32_t)((long)tx - (long)ramchain->mem->ptr),(int32_t)ramchain->mem->totalsize,ramchain->txidind); - iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins); - //if ( (ptr= iguana_hashsetPT(ramchain,'T',&tx->txid.bytes,ramchain->txidind)) != 0 ) - { - for (j=0; jnumvouts; j++) - { - iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,U[ramchain->unspentind].value,P[U[ramchain->unspentind].pkind].rmd160,-20,tx->txid,j); - } - } - ramchain->spendind += tx->numvins; - } - ramchain->externalind = ramchain->data->numexternaltxids; - } - if ( (err= iguana_ramchainverify(coin,ramchain)) != 0 ) - { - printf("iguana_ramchain_map.(%s) err.%d verifying ramchain\n",fname,err); - iguana_ramchain_free(ramchain,hashmem == 0); - munmap(ptr,filesize); - }*/ - //printf("mapped ramchain verified\n"); - -#define iguana_hashfind(hashtable,key,keylen) iguana_hashsetHT(hashtable,0,key,keylen,-1) - - struct iguana_kvitem *iguana_hashsetHT(struct iguana_kvitem *hashtable,struct iguana_memspace *mem,void *key,int32_t keylen,int32_t itemind) - { - struct iguana_kvitem *ptr = 0; int32_t allocsize; - HASH_FIND(hh,hashtable,key,keylen,ptr); - if ( ptr == 0 && itemind >= 0 ) - { - allocsize = (int32_t)(sizeof(*ptr)); - if ( mem != 0 ) - ptr = iguana_memalloc(mem,allocsize,1); - else ptr = mycalloc('t',1,allocsize); - if ( ptr == 0 ) - printf("fatal alloc error in hashset\n"), exit(-1); - //printf("ptr.%p allocsize.%d key.%p keylen.%d itemind.%d\n",ptr,allocsize,key,keylen,itemind); - ptr->hh.itemind = itemind; - HASH_ADD_KEYPTR(hh,hashtable,key,keylen,ptr); - } - if ( ptr != 0 ) - { - struct iguana_kvitem *tmp; - HASH_FIND(hh,hashtable,key,keylen,tmp); - char str[65]; - init_hexbytes_noT(str,key,keylen); - if ( tmp != ptr ) - printf("%s itemind.%d search error %p != %p\n",str,itemind,ptr,tmp); - // else printf("added.(%s) height.%d %p\n",str,itemind,ptr); - } - return(ptr); - } - - int32_t iguana_parseblock(struct iguana_info *coin,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx) - { -#ifdef oldway - int32_t txind,pkind,i; uint16_t numvouts,numvins; - pkind = block->L.numpkinds = coin->latest.dep.numpkinds; - block->L.supply = coin->latest.dep.supply; - if ( block->L.numtxids != coin->latest.dep.numtxids || block->L.numunspents != coin->latest.dep.numunspents || block->L.numspends != coin->latest.dep.numspends || block->L.numpkinds != coin->latest.dep.numpkinds ) - { - printf("Block.(h%d t%d u%d s%d p%d) vs coin.(h%d t%d u%d s%d p%d)\n",block->height,block->L.numtxids,block->L.numunspents,block->L.numspends,block->L.numpkinds,coin->blocks.parsedblocks,coin->latest.dep.numtxids,coin->latest.dep.numunspents,coin->latest.dep.numspends,coin->latest.dep.numpkinds); - block->L.numtxids = coin->latest.dep.numtxids; - block->L.numunspents = coin->latest.dep.numunspents; - block->L.numspends = coin->latest.dep.numspends; - block->L.numpkinds = coin->latest.dep.numpkinds; - iguana_kvwrite(coin,coin->blocks.db,0,block,(uint32_t *)&block->height); - //getchar(); - } - vcalc_sha256(0,coin->latest.ledgerhash.bytes,coin->latest.lhashes[0].bytes,sizeof(coin->latest.lhashes)); - coin->LEDGER.snapshot.dep = block->L; - memcpy(&coin->LEDGER.snapshot.ledgerhash,&coin->latest.ledgerhash,sizeof(coin->latest.ledgerhash)); - memcpy(coin->LEDGER.snapshot.lhashes,coin->latest.lhashes,sizeof(coin->latest.lhashes)); - memcpy(coin->LEDGER.snapshot.states,coin->latest.states,sizeof(coin->latest.states)); - //printf("%08x Block.(h%d t%d u%d s%d p%d) vs (h%d t%d u%d s%d p%d)\n",(uint32_t)coin->latest.ledgerhash.txid,block->height,block->L.numtxids,block->L.numunspents,block->L.numspends,block->L.numpkinds,coin->blocks.parsedblocks,coin->latest.dep.numtxids,coin->latest.dep.numunspents,coin->latest.dep.numspends,coin->latest.dep.numpkinds); - if ( (coin->blocks.parsedblocks % 1000) == 0 ) - { - for (i=0; iLEDGER.snapshot.lhashes[i].txid); - char str[65]; - bits256_str(str,coin->LEDGER.snapshot.ledgerhash); - printf("-> pre parse %s ledgerhashes.%d\n",str,coin->blocks.parsedblocks); - } - coin->LEDGER.snapshot.blockhash = block->hash2; - coin->LEDGER.snapshot.merkle_root = block->merkle_root; - coin->LEDGER.snapshot.timestamp = block->timestamp; - coin->LEDGER.snapshot.credits = coin->latest.credits; - coin->LEDGER.snapshot.debits = coin->latest.debits; - coin->LEDGER.snapshot.height = block->height; - //if ( coin->blocks.parsedblocks > 0 && (coin->blocks.parsedblocks % coin->chain->bundlesize) == 0 ) - // coin->R.bundles[coin->blocks.parsedblocks / coin->chain->bundlesize].presnapshot = coin->LEDGER.snapshot; - for (txind=block->numvouts=block->numvins=0; txindtxn_count; txind++) - { - //printf("block.%d txind.%d numvouts.%d numvins.%d block->(%d %d) U%d coin.%d\n",block->height,txind,numvouts,numvins,block->numvouts,block->numvins,block->L.numunspents,coin->latest.dep.numunspents); - //fprintf(stderr,"t"); - if ( ramchain_parsetx(coin,&coin->mining,&coin->totalfees,&numvouts,&numvins,block->height,txind,&tx[txind],block->L.numtxids+txind,block->L.numunspents + block->numvouts,block->L.numspends + block->numvins) < 0 ) - return(-1); - block->numvouts += numvouts; - block->numvins += numvins; - //printf("block.%d txind.%d numvouts.%d numvins.%d block->(%d %d) 1st.(%d %d)\n",block->height,txind,numvouts,numvins,block->numvouts,block->numvins,block->L.numunspents,block->L.numspends); - } - //printf(" Block.(h%d t%d u%d s%d p%d) vs coin.(h%d t%d u%d s%d p%d)\n",block->height,block->L.numtxids,block->L.numunspents,block->L.numspends,block->L.numpkinds,coin->blocks.parsedblocks,coin->latest.dep.numtxids,coin->latest.dep.numunspents,coin->latest.dep.numspends,coin->latest.dep.numpkinds); - if ( coin->latest.dep.supply != (coin->latest.credits - coin->latest.debits) ) - { - printf("height.%d supply %.8f != %.8f (%.8f - %.8f)\n",block->height,dstr(coin->latest.dep.supply),dstr(coin->latest.credits)-dstr(coin->latest.debits),dstr(coin->latest.credits),dstr(coin->latest.debits)); - getchar(); - } -#ifdef IGUANA_VERIFYFLAG - while ( pkind < coin->latest.dep.numpkinds ) - { - int64_t err; - if ( (err= iguana_verifyaccount(coin,&coin->accounts[pkind],pkind)) < 0 ) - printf("pkind.%d err.%lld %.8f last.(U%d S%d)\n",pkind,(long long)err,dstr(coin->accounts[pkind].balance),coin->accounts[pkind].lastunspentind,coin->accounts[pkind].lastspendind), getchar(); - pkind++; - } -#endif - coin->parsetime = (uint32_t)time(NULL); - coin->parsemillis = milliseconds(); - iguana_kvwrite(coin,coin->blocks.db,0,block,(uint32_t *)&block->height); - if ( (coin->blocks.parsedblocks > coin->longestchain-100000 && (coin->blocks.parsedblocks % 100) == 0) || (coin->blocks.parsedblocks > coin->longestchain-1000 && (coin->blocks.parsedblocks % 10) == 0) || coin->blocks.parsedblocks > coin->longestchain-100 || (coin->blocks.parsedblocks % 100) == 0 ) - { - printf("PARSED.%d T.%d U.%d+%d S.%d+%d P.%d hwm.%d longest.%d | %.8f - %.8f %.8f [%.8f] M %.8f F %.8f | %.02f minutes %.2f%% %.2f%% %.2f%% avail\n",coin->blocks.parsedblocks,coin->latest.dep.numtxids,block->L.numunspents,block->numvouts,block->L.numspends,block->numvins,block->L.numpkinds,coin->blocks.hwmheight,coin->longestchain,dstr(coin->latest.credits),dstr(coin->latest.debits),dstr(coin->latest.credits)-dstr(coin->latest.debits),(dstr(coin->latest.credits)-dstr(coin->latest.debits))/coin->blocks.parsedblocks,dstr(coin->mining),dstr(coin->totalfees),((double)time(NULL)-coin->starttime)/60.,(double)iguana_avail(coin,coin->blocks.parsedblocks+1,1000)/10.,(double)iguana_avail(coin,coin->blocks.parsedblocks+1,25000)/250.,100.*(double)iguana_avail(coin,coin->blocks.parsedblocks+1,coin->longestchain-coin->blocks.parsedblocks-1)/(coin->longestchain-coin->blocks.parsedblocks)); - myallocated(0,0); - } - if ( 0 && coin->loadedLEDGER.snapshot.height == coin->blocks.parsedblocks ) - { - memcpy(&coin->latest.ledgerhash,&coin->loadedLEDGER.snapshot.ledgerhash,sizeof(coin->loadedLEDGER.snapshot.ledgerhash)); - memcpy(coin->latest.lhashes,coin->loadedLEDGER.snapshot.lhashes,sizeof(coin->loadedLEDGER.snapshot.lhashes)); - printf("restore lhashes, special alignement case\n"); - } //else printf("loaded.%d vs parsed.%d\n",coin->loadedLEDGER.snapshot.height,coin->blocks.parsedblocks); - coin->blocks.parsedblocks++; -#endif - return(0); - } - - int32_t iguana_updateramchain(struct iguana_info *coin) - { - return(0); - } - - int32_t iguana_hashfree(struct iguana_kvitem *hashtable,int32_t delitem) - { - struct iguana_kvitem *item,*tmp; int32_t n = 0; - if ( hashtable != 0 ) - { - HASH_ITER(hh,hashtable,item,tmp) - { - //printf("hashdelete.%p allocsize.%d itemind.%d delitem.%d\n",item,item->allocsize,item->hh.itemind,delitem); - if ( delitem != 0 ) - { - HASH_DEL(hashtable,item); - //if ( delitem > 1 ) - // myfree(item,item->allocsize); - } - n++; - } - } - return(n); - } - - struct iguana_txblock *iguana_ramchainptrs(struct iguana_txid **Tptrp,struct iguana_unspent20 **Uptrp,struct iguana_spend256 **Sptrp,struct iguana_pkhash **Pptrp,bits256 **externalTptrp,struct iguana_memspace *mem,struct iguana_txblock *origtxdata) - { - char str[65]; struct iguana_txblock *txdata; int32_t allocsize,extralen,rwflag = (origtxdata != 0); - iguana_memreset(mem); - allocsize = (int32_t)(sizeof(*txdata) - sizeof(txdata->space) + ((origtxdata != 0) ? origtxdata->extralen : 0)); - mem->alignflag = sizeof(uint32_t); - if ( (txdata= iguana_memalloc(mem,allocsize,0)) == 0 ) - return(0); - //printf("ptr.%p alloctxdata.%p T.%d U.%d S.%d P.%d\n",mem->ptr,txdata,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds); - extralen = (origtxdata != 0) ? origtxdata->extralen : txdata->extralen; - if ( origtxdata != 0 ) - { - //printf("copy %d bytes from %p to %p extralen.%d size.%ld T.%d U.%d S.%d P.%d \n",allocsize,origtxdata,txdata,extralen,sizeof(*txdata),txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds); - memcpy(txdata,origtxdata,allocsize); - } else iguana_memalloc(mem,txdata->extralen,0); - *Tptrp = iguana_memalloc(mem,sizeof(**Tptrp) * txdata->numtxids,rwflag); - *Uptrp = iguana_memalloc(mem,sizeof(**Uptrp) * txdata->numunspents,rwflag); - *Sptrp = iguana_memalloc(mem,sizeof(**Sptrp) * txdata->numspends,rwflag); - //printf("rwflag.%d ptr.%p alloctxdata.%p T.%d U.%d S.%d P.%d pkoffset.%ld X.%d\n",rwflag,mem->ptr,txdata,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,mem->used,txdata->numexternaltxids); - if ( externalTptrp != 0 ) - { - if ( txdata->pkoffset < (int32_t)mem->used ) - printf("allocsize.%d size.%ld %p %s (T.%d U.%d S.%d P.%d X.%d) iguana_ramchainptrs pkoffset.%d != %ld numspends.%d\n",allocsize,sizeof(*txdata),txdata,bits256_str(str,txdata->block.hash2),txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids,txdata->pkoffset,mem->used,txdata->numspends), getchar(); - mem->used = txdata->pkoffset; - *Pptrp = iguana_memalloc(mem,sizeof(**Pptrp) * txdata->numpkinds,rwflag); - *externalTptrp = iguana_memalloc(mem,txdata->numexternaltxids * sizeof(**externalTptrp),rwflag); - } - else - { - txdata->pkoffset = (int32_t)mem->used; - // printf("set pkoffset.%d\n",txdata->pkoffset); - *Pptrp = iguana_memalloc(mem,0,rwflag); - } - if ( 0 && rwflag == 0 ) - printf("datalen.%d rwflag.%d origtxdat.%p allocsize.%d extralen.%d T.%d U.%d S.%d P.%d X.%p[%d]\n",(int32_t)mem->totalsize,rwflag,origtxdata,allocsize,extralen,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,externalTptrp!=0?*externalTptrp:0,txdata->numexternaltxids); - return(txdata); - } - - int32_t iguana_ramchainsave(struct iguana_info *coin,struct iguana_ramchain *ramchain) - { - FILE *fp; char fname[1024],str[65]; - sprintf(fname,"DB/%s/%s.%d",coin->symbol,bits256_str(str,ramchain->H.data->firsthash2),ramchain->H.hdrsi); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - fwrite(ramchain,1,ramchain->H.data->allocsize,fp); - fclose(fp); - } - printf("ramchainsave.%s %d[%d] %s\n",coin->symbol,ramchain->H.hdrsi,ramchain->numblocks,mbstr(str,ramchain->H.data->allocsize)); - return(0); - } - - int32_t iguana_ramchainfree(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_ramchain *ramchain) - { - if ( ramchain->txids != 0 ) - iguana_hashfree(ramchain->txids,1); - if ( ramchain->pkhashes != 0 ) - iguana_hashfree(ramchain->pkhashes,1); - iguana_mempurge(mem); - return(0); - } - - /*struct iguana_ramchain *iguana_ramchainset(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_txblock *txdata) - { - struct iguana_memspace txmem; - memset(&txmem,0,sizeof(txmem)); - iguana_meminit(&txmem,"bramchain",txdata,txdata->datalen,0); - //printf("ramchainset <- txdata.%p memptr.%p T.%d U.%d S.%d P.%d X.%d\n",txdata,txmem.ptr,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids); - if ( iguana_ramchainptrs(&ramchain->T,&ramchain->U,&ramchain->S,&ramchain->P,&ramchain->externalT,&txmem,0) != txdata || ramchain->T == 0 || ramchain->U == 0 || ramchain->S == 0 || ramchain->P == 0 ) - { - printf("iguana_ramchainset: cant set pointers txdata.%p\n",txdata); - return(0); - } - //int32_t i; - // for (i=0; i<344; i++) - // printf("%02x ",((uint8_t *)txdata)[i]); - //for (i=-1; i<2; i++) - // printf("%016lx ",*(long *)((struct iguana_pkhash *)((long)txdata + txdata->pkoffset))[i].rmd160); - //printf("datalen.%d T.%d U.%d S.%d P.%d X.%d | %d vs %d ramchain.%p txdata.%p\n",txdata->datalen,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds,txdata->numexternaltxids,txdata->pkoffset,(int32_t)((long)ramchain->P - (long)txdata),ramchain,txdata); - ramchain->numtxids = txdata->numtxids; - ramchain->numunspents = txdata->numunspents; - ramchain->numspends = txdata->numspends; - ramchain->numpkinds = txdata->numpkinds; - ramchain->numexternaltxids = txdata->numexternaltxids; - //printf("ramchain T.%d U.%d S.%d P.%d X.%d %p\n",ramchain->numtxids,ramchain->numunspents,ramchain->numspends,ramchain->numpkinds,ramchain->numexternaltxids,ramchain->externalT); - if ( ramchain->numexternaltxids != 0 && ramchain->externalT == 0 ) - getchar(); - ramchain->prevhash2 = txdata->block.prev_block; - ramchain->hash2 = txdata->block.hash2; - return(ramchain); - } - - int32_t iguana_ramchaintxid(struct iguana_info *coin,bits256 *txidp,struct iguana_ramchain *ramchain,struct iguana_spend *s) - { - memset(txidp,0,sizeof(*txidp)); - //printf("s.%p ramchaintxid vout.%x spendtxidind.%d numexternals.%d isext.%d numspendinds.%d\n",s,s->vout,s->spendtxidind,ramchain->numexternaltxids,s->external,ramchain->numspends); - if ( s->vout == 0xffff ) - return(0); - if ( s->external != 0 && s->spendtxidind < ramchain->numexternaltxids ) - { - *txidp = ramchain->externalT[s->spendtxidind]; - return(0); - } - else if ( s->external == 0 && s->spendtxidind < ramchain->numtxids ) - { - *txidp = ramchain->T[s->spendtxidind].txid; - return(0); - } - return(-1); - }*/ - - /*if ( ptr->type == 'F' ) - { - if ( addr != 0 && addr->fp != 0 ) - { - //printf("flush.%s %p\n",addr->ipaddr,addr->fp); - fflush(addr->fp); - } - } - else*/ - - /* struct iguana_txblock *ptr; struct iguana_ramchain *ptrs[IGUANA_MAXBUNDLESIZE],*ramchains; - struct iguana_block *block; char fname[1024]; uint64_t estimatedsize = 0; - int32_t i,maxrecv,addrind,flag,bundlei,numdirs=0; struct iguana_ramchain *ramchain; - flag = maxrecv = 0; - memset(ptrs,0,sizeof(ptrs)); - ramchains = mycalloc('p',coin->chain->bundlesize,sizeof(*ramchains)); - for (i=0; in && ichain->bundlesize; i++) - { - if ( (block= iguana_blockfind(coin,bp->hashes[i])) != 0 ) - { - iguana_meminit(&memB[i],"ramchainB",0,block->recvlen*2 + 8192,0); - if ( (ptr= iguana_peertxdata(coin,&bundlei,fname,&memB[i],block->ipbits,block->hash2)) != 0 ) - { - if ( bundlei != i || ptr->block.bundlei != i ) - printf("peertxdata.%d bundlei.%d, i.%d block->bundlei.%d\n",bp->hdrsi,bundlei,i,ptr->block.bundlei); - ptrs[i] = &ramchains[i]; - //char str[65]; - //printf("received txdata.%s bundlei.%d T.%d U.%d S.%d P.%d\n",bits256_str(str,ptr->block.hash2),bundlei,ptr->numtxids,ptr->numunspents,ptr->numspends,ptr->numpkinds); - if ( iguana_ramchainset(coin,ptrs[i],ptr) == ptrs[i] ) - { - char str[65]; int32_t err; - //for (j=0; jnumpkinds; j++) - // init_hexbytes_noT(str,ptrs[i]->P[j].rmd160,20), printf("%s ",str); - err = iguana_ramchainverifyPT(coin,ptrs[i]); - printf("conv err.%d ramchain.%s bundlei.%d T.%d U.%d S.%d P.%d\n",err,bits256_str(str,ptrs[i]->data->firsthash2),bundlei,ptrs[i]->data->numtxids,ptrs[i]->data->numunspents,ptrs[i]->data->numspends,ptrs[i]->data->numpkinds); - ptrs[i]->data->firsti = 0; - if ( block->recvlen > maxrecv ) - maxrecv = block->recvlen; - estimatedsize += block->recvlen; - flag++; - } else printf("error setting ramchain.%d\n",i); - } - else - { - printf("error (%s) hdrs.%d ptr[%d]\n",fname,bp->hdrsi,i); - CLEARBIT(bp->recv,i); - bp->issued[i] = 0; - block = 0; - } - } - } - if ( flag == i ) - { - printf("numpkinds >>>>>>>>> start MERGE.(%ld) i.%d flag.%d estimated.%ld maxrecv.%d\n",(long)mem->totalsize,i,flag,(long)estimatedsize,maxrecv); - if ( (ramchain= iguana_ramchainmergeHT(coin,mem,ptrs,i,bp)) != 0 ) - { - iguana_ramchainsave(coin,ramchain); - iguana_ramchainfree(coin,mem,ramchain); - //printf("ramchain saved\n"); - bp->emitfinish = (uint32_t)time(NULL); - for (addrind=0; addrindpeers.active[addrind].ipbits != 0 ) - { - if ( iguana_peerfile_exists(coin,&coin->peers.active[addrind],fname,bp->hashes[0]) >= 0 ) - { - //printf("remove.(%s)\n",fname); - //iguana_removefile(fname,0); - //coin->peers.numfiles--; - } - } - } - } else bp->emitfinish = 0; - } - else - { - printf(">>>>> bundlesaveHT error: numdirs.%d i.%d flag.%d\n",numdirs,i,flag); - bp->emitfinish = 0; - } - for (i=0; in && ichain->bundlesize; i++) - iguana_mempurge(&memB[i]); - myfree(ramchains,coin->chain->bundlesize * sizeof(*ramchains)); - return(flag);*/ - -#ifdef oldway - int32_t iguana_verifyiAddr(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - struct iguana_iAddr *iA = value; - if ( itemind == 0 || iA->ipbits != 0 ) - return(0); - else return(-1); - } - - int32_t iguana_initiAddr(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - struct iguana_iAddr *iA = value; - if ( key == 0 && value == 0 && itemind < 0 && numitems == 0 ) - { - } - else - { - if ( iA != 0 ) - iA->status = 0; - coin->numiAddrs++; - //printf("%x numiAddrs.%d\n",iA->ipbits,coin->numiAddrs); - } - return(0); - } - - int32_t iguana_verifyblock(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - struct iguana_block *block; - block = value; - if ( bits256_nonz(block->hash2) != 0 ) - return(0); - else return(-1); - } - - int32_t iguana_initblock(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - bits256 genesis; //struct iguana_block *block = value; - if ( key == 0 && value == 0 && itemind < 0 && numitems == 0 ) - { - if ( coin->blocks.db == 0 ) - coin->blocks.db = kv; - genesis = iguana_genesis(coin,coin->chain); - if ( bits256_nonz(genesis) == 0 ) - return(-1); - else return(0); - } - return(0); - } - - int32_t iguana_nullinit(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - if ( key != 0 && value != 0 && itemind > 0 ) - { - } - return(0); - } - - int32_t iguana_verifyunspent(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - if ( itemind < coin->latest.dep.numunspents ) - return(0); - else return(-1); - } - - int32_t iguana_verifyspend(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - if ( itemind < coin->latest.dep.numspends ) - return(0); - else return(-1); - } - - int32_t iguana_verifytxid(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - if ( itemind < coin->latest.dep.numtxids ) - return(0); - else return(-1); - } - - int32_t iguana_inittxid(struct iguana_info *coin,struct iguanakv *kv,void *key,void *value,int32_t itemind,int32_t itemsize,int32_t numitems) - { - //uint32_t checktxidind,firstvout,firstvin; struct iguana_txid *tx = value; - if ( key != 0 && value != 0 && itemind > 0 ) - { - /*printf("inittxid.(%s) itemind.%d (%d %d)\n",bits256_str(tx->txid),itemind,tx->firstvout,tx->firstvin); - checktxidind = iguana_txidind(coin,&firstvout,&firstvin,tx->txid); - if ( checktxidind != itemind ) - { - printf("init checktxidind != itemind: %s -> %d vs %d\n",bits256_str(tx->txid),checktxidind,itemind); - return(-1); - }*/ - } - return(0); - } - - int32_t iguana_verifypkhash(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize) - { - if ( itemind < coin->latest.dep.numpkinds ) - return(0); - else return(-1); - } - - struct iguanakv *iguana_kvinit(char *name,int32_t keysize,int32_t threadsafe,int32_t mapped_datasize,int32_t RAMvaluesize,int32_t keyoffset,int32_t flags,int32_t valuesize2,int32_t valuesize3) - { - struct iguanakv *kv; - printf("iguana_kvinit.(%s) keysize.%d mapped_datasize.%d keyoffset.%d\n",name,keysize,mapped_datasize,keyoffset); - kv = mycalloc('K',1,sizeof(*kv)); - portable_mutex_init(&kv->MMlock); - //portable_mutex_init(&kv->MEM.mutex); - portable_mutex_init(&kv->HASHPTRS.mutex); - portable_mutex_init(&kv->KVmutex); - strcpy(kv->name,name); - kv->flags = flags; - kv->valuesize2 = valuesize2, kv->valuesize3 = valuesize3; - kv->RAMvaluesize = RAMvaluesize; - kv->HDDvaluesize = mapped_datasize; - kv->keyoffset = keyoffset; - kv->mult = IGUANA_ALLOC_MULT; - kv->threadsafe = threadsafe; - kv->keysize = keysize; - return(kv); - } - - int32_t iguana_loadkvfile(struct iguana_info *coin,struct iguanakv *kv,int32_t valuesize,int32_t (*verifyitem)(struct iguana_info *coin,void *key,void *ptr,int32_t itemind,int32_t itemsize),int32_t (*inititem)(struct iguana_info *coin,struct iguanakv *kv,void *key,void *ptr,int32_t itemind,int32_t itemsize,int32_t numitems),int32_t maxind) - { - FILE *fp; long fpos; uint8_t *ptr; double lastdisp,factor; int32_t numitems=0,itemind,j,n,skip = 0; - factor = 1.; - if ( (fp= fopen(kv->fname,"rb")) != 0 ) - { - fseek(fp,0,SEEK_END); - fpos = ftell(fp); - numitems = (int32_t)(fpos / valuesize); - fclose(fp); - if ( kv->RAMvaluesize > 0 && kv->HDDvaluesize > 0 && kv->RAMvaluesize > kv->HDDvaluesize && numitems > 0 ) - numitems--; - iguana_kvensure(coin,kv,0); - if ( numitems > 2 || maxind > 0 ) - { - if ( maxind == 0 ) - { - for (itemind=numitems-2; itemind>0; itemind--) - { - ptr = (uint8_t *)((unsigned long)kv->M.fileptr + ((unsigned long)itemind * kv->HDDvaluesize)); - if ( (*verifyitem)(coin,(void *)&ptr[kv->keyoffset],(void *)ptr,itemind,kv->RAMvaluesize) < 0 ) - { - numitems = itemind + 1; - printf("numitems.%d\n",numitems); - break; - } - } - } else numitems = maxind; - if ( numitems > 0 ) - { - lastdisp = 0.; - for (itemind=0; itemind 1000000 && ((double)itemind / numitems) > lastdisp+.01*factor ) - { - if ( factor == 1. ) - fprintf(stderr,"%.0f%% ",100. * lastdisp); - else fprintf(stderr,"%.2f%% ",100. * lastdisp); - lastdisp = ((double)itemind / numitems); - } - ptr = (uint8_t *)((uint64_t)kv->M.fileptr + ((uint64_t)itemind * kv->HDDvaluesize)); - if ( 0 && kv->keysize > 0 ) - { - for (j=0; jkeysize; j++) - if ( ptr[j] != 0 ) - break; - if ( j != kv->keysize && iguana_kvread(coin,kv,(void *)&ptr[kv->keyoffset],kv->space,(uint32_t *)&n) != 0 ) - { - printf("%s: skip duplicate %llx itemind.%d already at %d\n",kv->name,*(long long *)&ptr[kv->keyoffset],itemind,n); - continue; - } - //printf("%s uniq item at itemind.%d\n",kv->name,itemind); - } - if ( (*verifyitem)(coin,(void *)&ptr[kv->keyoffset],(void *)ptr,itemind,kv->RAMvaluesize) == 0 ) - { - //if ( strcmp("txids",kv->name) == 0 ) - //printf("inititem.%d %p (%s)\n",itemind,ptr,bits256_str(*(bits256 *)&ptr[kv->keyoffset])); - // iguana_kvwrite(coin,kv,(void *)&ptr[kv->keyoffset],sp->space,(uint32_t *)&n); - if ( (*inititem)(coin,kv,(void *)&ptr[kv->keyoffset],(void *)ptr,itemind,kv->RAMvaluesize,numitems) == 0 ) - { - kv->numvalid++; - n = itemind; - memcpy(kv->space,ptr,kv->RAMvaluesize); - if ( kv->keysize > 0 ) - iguana_kvwrite(coin,kv,(void *)&ptr[kv->keyoffset],kv->space,(uint32_t *)&n); - else iguana_kvwrite(coin,kv,0,kv->space,(uint32_t *)&n); - } else skip++; - } else break; - } - } - } - kv->numitems = numitems; - kv->numkeys = numitems; - kv->maxitemind = (numitems > 0 ) ? numitems - 1 : 0; - printf("%s: numkeys.%d numitems.%d numvalid.%d maxitemind.%d skipped.%d ELAPSED %.2f minutes\n",kv->name,kv->numkeys,kv->numitems,kv->numvalid,kv->maxitemind,skip,(double)(time(NULL)-coin->starttime)/60.); - if ( (kv->flags & IGUANA_ITEMIND_DATA) != 0 ) - iguana_syncmap(&kv->M,0); - /*if ( strcmp(kv->name,"iAddrs") == 0 && kv->numkeys < numitems/2 ) - { - iguana_closemap(&kv->M); - printf("truncate?\n"), getchar(); - truncate(kv->fname,(kv->numkeys+100)*kv->HDDvaluesize); - }*/ - } - return(numitems); - } - - struct iguanakv *iguana_stateinit(struct iguana_info *coin,int32_t flags,char *coinstr,char *subdir,char *name,int32_t keyoffset,int32_t keysize,int32_t HDDvaluesize,int32_t RAMvaluesize,int32_t inititems,int32_t (*verifyitem)(struct iguana_info *coin,void *key,void *ptr,int32_t itemind,int32_t itemsize),int32_t (*inititem)(struct iguana_info *coin,struct iguanakv *kv,void *key,void *ptr,int32_t itemind,int32_t itemsize,int32_t numitems),int32_t valuesize2,int32_t valuesize3,int32_t maxind,int32_t initialnumitems,int32_t threadsafe) - { - struct iguanakv *kv; int32_t valuesize; - if ( maxind <= 1 ) - maxind = 0; - printf("%s MAX.%d\n",name,maxind); - if ( HDDvaluesize == 0 ) - valuesize = HDDvaluesize = RAMvaluesize; - else valuesize = HDDvaluesize; - kv = iguana_kvinit(name,keysize,threadsafe,HDDvaluesize,RAMvaluesize,keyoffset,flags,valuesize2,valuesize3); - if ( kv == 0 ) - { - printf("cant initialize kv.(%s)\n",name); - exit(-1); - } - if ( (kv->incr= inititems) == 0 ) - kv->incr = IGUANA_ALLOC_INCR; - strcpy(kv->name,name); - sprintf(kv->fname,"DB/%s/%s",coin->symbol,kv->name), iguana_compatible_path(kv->fname); - portable_mutex_init(&kv->MMmutex); - kv->space = mycalloc('K',1,RAMvaluesize + kv->keysize); - kv->maxitemind = kv->numvalid = kv->numitems = 0; - if ( strcmp("txids",kv->name) == 0 ) - coin->txids = kv; - else if ( strcmp("pkhashes",kv->name) == 0 ) - coin->pkhashes = kv; - printf("kv.%p chain.%p\n",kv,coin->chain); - (*inititem)(coin,kv,0,0,-1,valuesize,0); - iguana_loadkvfile(coin,kv,valuesize,verifyitem,inititem,maxind); - if ( initialnumitems != 0 ) - iguana_kvensure(coin,kv,initialnumitems); - return(kv); - } - - uint32_t iguana_syncs(struct iguana_info *coin) - { - FILE *fp; char fnameold[512],fnameold2[512],fname[512],fname2[512]; int32_t i,height,flag = 0; - if ( (coin->blocks.parsedblocks > coin->longestchain-1000 && (coin->blocks.parsedblocks % 100) == 1) || - (coin->blocks.parsedblocks > coin->longestchain-10000 && (coin->blocks.parsedblocks % 1000) == 1) || - (coin->blocks.parsedblocks > coin->longestchain-2000000 && (coin->blocks.parsedblocks % 10000) == 1) || - (coin->blocks.parsedblocks > coin->firstblock+100 && (coin->blocks.parsedblocks % 100000) == 1) ) - { - if ( coin->blocks.parsedblocks > coin->loadedLEDGER.snapshot.height+2 ) - flag = 1; - } - if ( flag != 0 ) - { - height = coin->blocks.parsedblocks - (coin->firstblock != 0); - for (i=0; iLEDGER.snapshot.lhashes[i].txid); - char str[65]; - bits256_str(str,coin->LEDGER.snapshot.ledgerhash); - printf("-> syncs %s ledgerhashes.%d\n",str,height); - //iguana_syncmap(&coin->iAddrs->M,0); - iguana_syncmap(&coin->blocks.db->M,0); - iguana_syncmap(&coin->unspents->M,0); - iguana_syncmap(&coin->unspents->M2,0); - iguana_syncmap(&coin->spends->M,0); - iguana_syncmap(&coin->spends->M2,0); - iguana_syncmap(&coin->txids->M,0); - iguana_syncmap(&coin->pkhashes->M,0); - iguana_syncmap(&coin->pkhashes->M2,0); - iguana_syncmap(&coin->pkhashes->M3,0); - printf("%s threads.%d iA.%d ranked.%d hwm.%u parsed.%u T.%d U.%d %.8f S.%d %.8f net %.8f P.%d\n",coin->symbol,iguana_numthreads(coin,-1),coin->numiAddrs,coin->peers.numranked,coin->blocks.hwmheight+1,height,coin->latest.dep.numtxids,coin->latest.dep.numunspents,dstr(coin->latest.credits),coin->latest.dep.numspends,dstr(coin->latest.debits),dstr(coin->latest.credits)-dstr(coin->latest.debits),coin->latest.dep.numpkinds); - sprintf(fname,"tmp/%s/ledger.%d",coin->symbol,height); - sprintf(fname2,"DB/%s/ledger",coin->symbol); - sprintf(fnameold,"tmp/%s/ledger.old",coin->symbol); - sprintf(fnameold2,"tmp/%s/ledger.old2",coin->symbol); - iguana_renamefile(fnameold,fnameold2); - iguana_renamefile(fname2,fnameold); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(coin->accounts,sizeof(*coin->accounts),coin->LEDGER.snapshot.dep.numpkinds,fp) != coin->LEDGER.snapshot.dep.numpkinds ) - printf("WARNING: error saving %s accounts[%d]\n",fname,coin->LEDGER.snapshot.dep.numpkinds); - if ( fwrite(&coin->LEDGER,1,sizeof(coin->LEDGER),fp) != sizeof(coin->LEDGER) ) - printf("WARNING: error saving %s\n",fname); - fclose(fp); - iguana_copyfile(fname,fname2,1); - } - printf("backups created\n"); - } - return((uint32_t)time(NULL)); - } - - // 480a886f78a52d94 2c16330bdd8565f2 fbfb8ba91a6cd871 d1feb1e96190d4ff b8fef8854847e7db 8d2692bcfe41c777 ec86c8502288022f 789ebb3966bb640f -> pre parse 35ee0080a9a132e88477e8809a6e2a0696a06b8c7b13fbfde2955998346dd5c8 ledgerhashes.120000 - // 9d1025feba33725a d69751b2f8d3f626 1f19457ce24411f1 76e12fd68b3b5b3c 2ad1a1e4b3b7014e a699f2904d073771 989c145c04a7a0d0 e888ab12de678518 -> syncs b8cf6b625de1d921695d1d2247ad68b86d047adf417c09562dc620ada993c47d ledgerhashes.140000 - // 53faf4c08ae7cd66 60af0f6074a4460a 8fa0f21eb4996161 7d695aa60788e52c 45a5c96ef55a1797 7b3225a83646caec d2d5788986315066 27372b0616caacf0 -> syncs c874aa3554c69038574e7da352eb624ac539fed97bf73b605d00df0c8cec4c1b ledgerhashes.200000 - // 739df50dbbaedada b83cbd69f08d2a0f 7a8ffa182706c5b7 8215ff6c7ffb9985 4d674a6d386bd759 f829283534a1804 aeb3b0644b01e07f 7ffe4899a261ca96 -> syncs fba47203d5c1d08e5cf55fa461f4deb6d0c97dcfa364ee5b51f0896ffcbcbaa7 ledgerhashes.300000 - // 739df50dbbaedada b83cbd69f08d2a0f 7a8ffa182706c5b7 8215ff6c7ffb9985 4d674a6d386bd759 f829283534a1804 b5e66cbe3a2bdbea 7ffe4899a261ca96 -> syncs 6b3620ba67fad34a29dd86cd5ec9fe6afd2a81d8a5296aa33b03da74fdd20a9b ledgerhashes.300001 - - int32_t iguana_loadledger(struct iguana_info *coin,int32_t hwmheight) - { - FILE *fp; char fname[512],mapname[512],newfname[512]; struct iguana_block *block; struct iguana_prevdep L; - struct iguana_prevdep *dep; int32_t height,i,valid = 0; - dep = &coin->latest.dep; - sprintf(fname,"DB/%s/ledger",coin->symbol); - mapname[0] = newfname[0] = 0; - if ( (fp= fopen(fname,"rb")) == 0 ) - { - sprintf(fname,"tmp/%s/ledger.old",coin->symbol); - if ( (fp= fopen(fname,"rb")) == 0 ) - { - sprintf(fname,"tmp/%s/ledger.old2",coin->symbol); - fp = fopen(fname,"rb"); - } - } - if ( fp != 0 ) - { - sprintf(mapname,"DB/%s/pkhashes2",coin->symbol); - sprintf(newfname,"DB/%s/pkhashes2.over",coin->symbol); - fseek(fp,-sizeof(coin->LEDGER),SEEK_END); - if ( fread(&coin->LEDGER,1,sizeof(coin->LEDGER),fp) != sizeof(coin->LEDGER) ) - printf("WARNING: error loading %s\n",fname); - if ( (block= iguana_blockptr(coin,coin->LEDGER.snapshot.height)) != 0 ) - { - if ( memcmp(block->hash2.bytes,coin->LEDGER.snapshot.blockhash.bytes,sizeof(block->hash2)) == 0 ) - { - fclose(fp); - iguana_renamefile(mapname,newfname); - iguana_renamefile(fname,mapname); - *dep = coin->LEDGER.snapshot.dep; - coin->loadedLEDGER = coin->LEDGER; - memcpy(&coin->latest.ledgerhash,&coin->LEDGER.snapshot.ledgerhash,sizeof(coin->LEDGER.snapshot.ledgerhash)); - memcpy(coin->latest.lhashes,coin->LEDGER.snapshot.lhashes,sizeof(coin->LEDGER.snapshot.lhashes)); - memcpy(coin->latest.states,coin->LEDGER.snapshot.states,sizeof(coin->LEDGER.snapshot.states)); - printf("found ledger height.%d loadedht.%d\n",block->height,coin->LEDGER.snapshot.height); //getchar(); - for (i=0; iLEDGER.snapshot.lhashes[i].txid); - char str[65]; - bits256_str(str,coin->LEDGER.snapshot.ledgerhash); - printf("-> %s ledgerhashes.%x\n",str,calc_crc32(0,&coin->latest.states[IGUANA_LHASH_TXIDS],sizeof(coin->latest.states[IGUANA_LHASH_TXIDS]))); - printf("loaded H.%d T%d U%d S%d P%d\n",coin->LEDGER.snapshot.height,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds); //getchar(); - coin->latest.credits = coin->LEDGER.snapshot.credits; - coin->latest.debits = coin->LEDGER.snapshot.debits; - coin->latest.dep.supply = (coin->LEDGER.snapshot.credits - coin->LEDGER.snapshot.debits); - return(block->height); - } - } - fclose(fp); - } - dep->numpkinds = dep->numtxids = dep->numunspents = dep->numspends = 1; - while ( hwmheight > 0 ) - { - if ( (block= iguana_blockptr(coin,hwmheight)) != 0 ) - { - iguana_setdependencies(coin,block,&L); - //printf("block.%d: T.%d (%d %d) U.%d S.%d A.%d\n",hwmheight,dep->numtxids,block->numvouts,block->numvins,dep->numunspents,dep->numspends,dep->numpkhashes); - if ( L.numtxids != 0 && L.numunspents != 0 && L.numspends != 0 && block->numvouts != 0 && block->txn_count != 0 && L.numpkinds != 0 ) - { - if ( valid++ > 25 ) - break; - } - } else printf("missing block.%d\n",hwmheight); - hwmheight--; - } - for (height=0; height<=hwmheight; height++) - { - if ( iguana_setdependencies(coin,iguana_blockptr(coin,height),&L) < 0 ) - break; - dep->numtxids = L.numtxids + 0*block->txn_count; - dep->numunspents = L.numunspents + 0*block->numvouts; - dep->numspends = L.numspends + 0*block->numvins; - dep->numpkinds = L.numpkinds; - } - return(hwmheight); - } - - int32_t iguana_validateramchain(struct iguana_info *coin,int64_t *netp,uint64_t *creditsp,uint64_t *debitsp,int32_t height,struct iguana_block *block,int32_t hwmheight,struct iguana_prevdep *lp) - { - uint32_t i,n,m,u,txidind,unspentind,spendind,pkind,checkind,numvins,numvouts,txind,firstvout,firstvin,nextfirstvout,nextfirstvin; struct iguana_prevdep *nextlp; - struct iguana_txid T,nextT; uint64_t credits,debits,nets; struct iguana_block *nextblock; - credits = debits = nets = *creditsp = *debitsp = *netp = numvouts = numvins = 0; - if ( block->height == height ) - { - txidind = lp->numtxids, unspentind = lp->numunspents, spendind = lp->numspends, pkind = lp->numpkinds; - //printf("validate.%d (t%d u%d s%d p%d)\n",height,txidind,unspentind,spendind,pkind); - for (txind=0; txindtxn_count; txind++,txidind++) - { - T = coin->T[txidind], nextT = coin->T[txidind+1]; - //printf("h%d i%d T.%d (%d %d) -> (%d %d)\n",height,txind,txidind,T.firstvout,T.firstvin,nextT.firstvout,nextT.firstvin); - if ( height == 0 && (T.firstvout == 0 || T.firstvin == 0) ) - return(-1); - //printf(">>>> h%d i%d T.%d (%d %d) -> (%d %d) cmp.(%d %d)\n",height,txind,txidind,T.firstvout,T.firstvin,nextT.firstvout,nextT.firstvin,height == 0,(T.firstvout == 0 || T.firstvin == 0)); - if ( (checkind= iguana_txidind(coin,&firstvout,&firstvin,T.txid)) == txidind ) - { - if ( T.firstvout != firstvout || T.firstvin != firstvin ) - { - printf("mismatched rwtxidind %d != %d, %d != %d\n",T.firstvout,firstvout,T.firstvin,firstvin); - getchar(); - return(-1); - } - if ( txind == 0 && (firstvout != unspentind || firstvin != spendind) ) - { - char str[65]; - bits256_str(str,T.txid); - printf("h.%d txind.%d txidind.%d %s firstvout.%d != U%d firstvin.%d != S%d\n",height,txind,txidind,str,firstvout,unspentind,firstvin,spendind); - iguana_txidind(coin,&firstvout,&firstvin,T.txid); - iguana_txidind(coin,&firstvout,&firstvin,T.txid); - return(-1); - } - nextfirstvout = nextT.firstvout, nextfirstvin = nextT.firstvin; - if ( nextfirstvout < unspentind || nextfirstvin < spendind ) - { - printf("h.%d txind.%d nexttxidind.%d firstvout.%d != U%d firstvin.%d != S%d\n",height,txind,txidind,nextfirstvout,unspentind,nextfirstvin,spendind); - if ( nextfirstvout == 0 && nextfirstvin == 0 ) - { - coin->T[txidind+1].firstvout = unspentind; - coin->T[txidind+1].firstvin = spendind; - printf("autofixed\n"); - } - else - { - getchar(); - return(-1); - } - } - n = (nextfirstvout - T.firstvout); - m = (nextfirstvin - T.firstvin); - //printf("height.%d n.%d m.%d U.(%d - %d) S.(%d - %d)\n",height,n,m,nextfirstvout,T.firstvout,nextfirstvin,T.firstvin); - for (i=0; iU[unspentind].value; - if ( coin->Uextras[unspentind].spendind == 0 ) - nets += coin->U[unspentind].value; - if ( coin->U[unspentind].pkind > pkind ) - pkind = coin->U[unspentind].pkind; - //printf("i.%d: unspentind.%d\n",i,unspentind); - } - for (i=0; iS[spendind].spendtxidind) > 0 && u < coin->latest.dep.numunspents ) - debits += coin->U[u].value; - else - { - printf("cant read spendind.%d or S.unspentind %d\n",spendind+i,u); - getchar(); - } - } - numvouts += n; - numvins += m; - } - else - { - char str[65]; - bits256_str(str,T.txid); - printf("height.%d txind.%d txid.%s txidind.%d != %d\n",height,txind,str,txidind,checkind); - getchar(); - return(-1); - } - } - if ( numvins != block->numvins || numvouts != block->numvouts ) - { - printf("height.%d numvins or numvouts error %d != %d || %d != %d\n",height,numvins,block->numvins,numvouts,block->numvouts); - if ( block->numvins == 0 && block->numvouts == 0 ) - { - block->numvins = numvins; - block->numvouts = numvouts; - iguana_kvwrite(coin,coin->blocks.db,0,block,(uint32_t *)&block->height); - m = 0;//iguana_fixblocks(coin,height,hwmheight); - printf("autocorrected.%d\n",m); - exit(1); - } - else - { - getchar(); - return(-1); - } - } - *creditsp = credits, *debitsp = debits, *netp = nets; - if ( (nextblock= iguana_blockptr(coin,height+1)) != 0 ) - { - nextlp = 0; - if ( 0 && lp->supply+credits-debits != nextlp->supply ) - { - printf("nextblock.%d supply mismatch %.8f (%.8f - %.8f) %.8f != %.8f\n",height+1,dstr(lp->supply),dstr(credits),dstr(debits),dstr(lp->supply+credits-debits),dstr(nextlp->supply)); - getchar(); - return(-1); - } - if ( txidind != nextlp->numtxids || unspentind != nextlp->numunspents || spendind != nextlp->numspends )//|| pkind+1 != nextlp->numpkinds ) - { - printf("Block.(h%d t%d u%d s%d p%d) vs next.(h%d t%d u%d s%d p%d)\n",block->height,txidind,unspentind,spendind,pkind,height+1,nextlp->numtxids,nextlp->numunspents,nextlp->numspends,nextlp->numpkinds); - return(-1); - } - return(0); - } - printf("cant find next block at %d\n",height+1); - //printf("block.%d %.8f (%.8f - %.8f)\n",height,dstr(nets),dstr(credits),dstr(debits)); - } else printf("height mismatch %d != %d\n",height,block->height); - //getchar(); - return(-1); - } - - int32_t iguana_fixsecondary(struct iguana_info *coin,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,struct iguana_Uextra *Uextras,struct iguana_pkextra *pkextras,struct iguana_account *accounts) - { - uint32_t i; int32_t m,err; - if ( numtxids < 2 || numunspents < 2 || numspends < 2 || numpkinds < 2 ) - return(0); - //struct iguana_Uextra { uint32_t spendind; }; // unspentind - //struct iguana_unspent { uint64_t value; uint32_t pkind,txidind,prevunspentind; }; - for (i=m=err=0; i= numspends ) - m++, Uextras[i].spendind = 0;//, printf("%d ",Uextras[i].spendind); - if ( coin->U[i].prevunspentind != 0 && coin->U[i].prevunspentind >= i ) - err++, printf("preverr.%d/%d ",coin->U[i].prevunspentind,i); - if ( coin->U[i].txidind >= numtxids ) - err++, printf("errtxidind.%d ",coin->U[i].txidind); - if ( coin->U[i].pkind >= numpkinds ) - err++, printf("errpkind.%d ",coin->U[i].pkind); - } - if ( (err+m) != 0 ) - iguana_syncmap(&coin->unspents->M2,0); - printf("cleared %d Uextras before numunspents.%d beyond errs.%d\n",m,numunspents,err); - if ( err != 0 ) - getchar(); - //struct iguana_pkextra { uint32_t firstspendind; }; // pkind - for (i=m=0; i= numspends ) - m++, pkextras[i].firstspendind = 0;//, printf("firstS.%d ",pkextras[i].firstspendind); - } - if ( m != 0 ) - iguana_syncmap(&coin->pkhashes->M3,0); - printf("pkextras beyond numspends.%d m.%d accounts.%p\n",numspends,m,accounts); - //struct iguana_spend { uint32_t unspentind,prevspendind; }; // dont need nextspend - /*for (i=err=m=0; iS[i].unspentind >= numunspents ) - err++, coin->S[i].unspentind = 0;//, printf("S->U%d ",coin->S[i].unspentind); - //printf("%d ",coin->S[i].prevspendind); - if ( coin->Sextras[i].prevspendind != 0 && coin->Sextras[i].prevspendind >= i ) - m++, coin->Sextras[i].prevspendind = 0, printf("preverr.%d:%d ",coin->Sextras[i].prevspendind,i); - } - printf("errs.%d in spends numspends.%d\n",err,numspends); - if ( err != 0 ) - getchar();*/ - return(0); - } - - void clearmem(void *ptr,int32_t len) - { - static const uint8_t zeroes[512]; - if ( len > sizeof(zeroes) || memcmp(ptr,zeroes,len) != 0 ) - memset(ptr,0,len); - } - - int32_t iguana_clearoverage(struct iguana_info *coin,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,struct iguana_Uextra *Uextras,struct iguana_pkextra *pkextras,struct iguana_account *accounts) - { - uint32_t i,n; - printf("clear txids\n"); - n = (uint32_t)((uint64_t)coin->txids->M.allocsize / coin->txids->HDDvaluesize) - 2; - for (i=numtxids+1; iT[i],sizeof(coin->T[i])); - - printf("clear pkinds\n"); - n = (uint32_t)((uint64_t)coin->pkhashes->M.allocsize / coin->pkhashes->HDDvaluesize) - 2; - for (i=numpkinds; iP[i],sizeof(coin->P[i])); - n = (uint32_t)((uint64_t)coin->pkhashes->M2.allocsize / coin->pkhashes->valuesize2) - 2; - for (i=numpkinds; ipkhashes->M3.allocsize / coin->pkhashes->valuesize3) - 2; - for (i=numpkinds; iunspents->M.allocsize / coin->unspents->HDDvaluesize) - 2; - for (i=numunspents; iU[i],sizeof(coin->U[i])); - n = (uint32_t)((uint64_t)coin->unspents->M2.allocsize / coin->unspents->valuesize2) - 2; - for (i=numunspents; ispends->M.allocsize / coin->spends->HDDvaluesize) - 2; - for (i=numspends; iS[i],sizeof(coin->S[i])); - //n = (uint32_t)((uint64_t)coin->spends->M2.allocsize / coin->spends->valuesize2) - 2; - //for (i=numspends; iSextras[i],sizeof(coin->Sextras[i])); - return(0); - } - - int64_t iguana_verifybalances(struct iguana_info *coin,int32_t fullverify) - { - int64_t err,balance = 0; int32_t i,numerrs = 0; - for (i=0; ilatest.dep.numpkinds; i++) - { - if ( fullverify != 0 ) - { - if ( (err= iguana_verifyaccount(coin,&coin->accounts[i],i)) < 0 ) - { - printf("err.%d from pkind.%d\n",(int32_t)err,i); - numerrs++; - } - } - balance += coin->accounts[i].balance; - } - printf("iguana_verifybalances %.8f numerrs.%d\n",dstr(balance),numerrs); - if ( numerrs > 0 ) - getchar(); - return(balance); - } - - int32_t iguana_initramchain(struct iguana_info *coin,int32_t hwmheight,int32_t mapflags,int32_t fullverify) - { - struct iguana_prevdep *dep; struct iguana_block *block,lastblock; double lastdisp = 0.; - // init sequence is very tricky. must be done in the right order and make sure to only use data - // that has already been initialized. and at the end all the required fields need to be correct - struct iguana_msghdr H; uint8_t buf[1024]; int32_t len,height,valid=0,flag=0; - struct iguana_prevdep L,prevL; - int64_t checkbalance,net,nets; uint64_t prevcredits,prevdebits,credit,debit,credits,debits,origsupply; - dep = &coin->latest.dep; - height = hwmheight; - if ( (height= iguana_loadledger(coin,hwmheight)) < 0 ) - { - printf("iguana_initramchain: unrecoverable loadledger error hwmheight.%d\n",hwmheight); - return(-1); - } - hwmheight = height; - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds); - //four ramchains start valid.0 height.316904 txids.45082870 vouts.27183907 vins.107472009 pkhashes.44807925 3.57 minutes - - coin->unspents = iguana_stateinit(coin,IGUANA_ITEMIND_DATA,coin->symbol,coin->symbol,"unspents",0,0,sizeof(struct iguana_unspent),sizeof(struct iguana_unspent),100000,iguana_verifyunspent,iguana_nullinit,sizeof(*coin->Uextras),0,dep->numunspents,2500000,0); - if ( coin->unspents == 0 ) - printf("cant create unspents\n"), exit(1); - coin->unspents->HDDitemsp = (void **)&coin->U, coin->U = coin->unspents->M.fileptr; - coin->unspents->HDDitems2p = (void **)&coin->Uextras, coin->Uextras = coin->unspents->M2.fileptr; - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - - coin->spends = iguana_stateinit(coin,IGUANA_ITEMIND_DATA,coin->symbol,coin->symbol,"spends",0,0,sizeof(struct iguana_spend),sizeof(struct iguana_spend),100000,iguana_verifyspend,iguana_nullinit,0,0,dep->numspends,2500000,0); - if ( coin->spends == 0 ) - printf("cant create spends\n"), exit(1); - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - coin->spends->HDDitemsp = (void **)&coin->S, coin->S = coin->spends->M.fileptr; - coin->spends->HDDitems2p = (void **)&coin->Sextras, coin->Sextras = coin->spends->M2.fileptr; - - coin->txids = iguana_stateinit(coin,IGUANA_ITEMIND_DATA|((mapflags&IGUANA_MAPTXIDITEMS)!=0)*IGUANA_MAPPED_ITEM,coin->symbol,coin->symbol,"txids",0,sizeof(bits256),sizeof(struct iguana_txid),sizeof(struct iguana_txid),100000,iguana_verifytxid,iguana_inittxid,0,0,dep->numtxids,1000000,0); - if ( coin->txids == 0 ) - printf("cant create txids\n"), exit(1); - coin->txids->HDDitemsp = (void **)&coin->T, coin->T = coin->txids->M.fileptr; - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - - coin->pkhashes = iguana_stateinit(coin,IGUANA_ITEMIND_DATA|((mapflags&IGUANA_MAPPKITEMS)!=0)*IGUANA_MAPPED_ITEM,coin->symbol,coin->symbol,"pkhashes",0,20,sizeof(struct iguana_pkhash),sizeof(struct iguana_pkhash),100000,iguana_verifypkhash,iguana_nullinit,sizeof(*coin->accounts),sizeof(*coin->pkextras),dep->numpkinds,1000000,0); - if ( coin->pkhashes == 0 ) - printf("cant create pkhashes\n"), exit(1); - coin->pkhashes->HDDitemsp = (void **)&coin->P, coin->P = coin->pkhashes->M.fileptr; - coin->pkhashes->HDDitems2p = (void **)&coin->accounts, coin->accounts = coin->pkhashes->M2.fileptr; - coin->pkhashes->HDDitems3p = (void **)&coin->pkextras, coin->pkextras = coin->pkhashes->M3.fileptr; - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - - iguana_kvensure(coin,coin->txids,dep->numtxids + coin->txids->incr); - iguana_kvensure(coin,coin->pkhashes,dep->numpkinds + coin->pkhashes->incr); - iguana_kvensure(coin,coin->unspents,dep->numunspents + coin->unspents->incr); - iguana_kvensure(coin,coin->spends,dep->numspends + coin->spends->incr); - coin->txids->numkeys = dep->numtxids; - coin->unspents->numkeys = dep->numunspents; - coin->spends->numkeys = dep->numspends; - coin->pkhashes->numkeys = dep->numpkinds; - iguana_fixsecondary(coin,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,coin->Uextras,coin->pkextras,coin->accounts); - printf("hwmheight.%d KV counts T.%d P.%d U.%d S.%d\n",hwmheight,coin->txids->numkeys,coin->pkhashes->numkeys,coin->unspents->numkeys,coin->spends->numkeys); - memset(&lastblock,0,sizeof(lastblock)); - origsupply = dep->supply, dep->supply = 0; - for (prevcredits=prevdebits=credits=debits=nets=height=0; height<=hwmheight; height++) - { - if ( hwmheight > 10000 && ((double)height / hwmheight) > lastdisp+.01 ) - { - fprintf(stderr,"%.0f%% ",100. * lastdisp); - lastdisp = ((double)height / hwmheight); - } - if ( (block= iguana_blockptr(coin,height)) == 0 ) - { - printf("error getting height.%d\n",height); - break; - } - lastblock = *block; - if ( height == hwmheight ) - break; - printf("need to set valid L\n"); - if ( iguana_validateramchain(coin,&net,&credit,&debit,height,block,hwmheight,&L) < 0 ) - { - printf("UNRECOVERABLE error iguana_validateramchain height.%d\n",height); - getchar(); - exit(1); - break; - } - nets += net, credits += credit, debits += debit; - if ( nets != (credits - debits) ) - { - //printf("height.%d: net %.8f != %.8f (%.8f - %.8f)\n",height,dstr(nets),dstr(credits)-dstr(debits),dstr(credits),dstr(debits)); - //break; - } - prevcredits = credits; - prevdebits = debits; - } - if ( lastblock.height == 0 ) - dep->numpkinds = dep->numspends = dep->numtxids = dep->numunspents = 1, dep->supply = 0, coin->latest.credits = coin->latest.debits = 0; - else - { - printf("set prevL\n"); - dep->numtxids = prevL.numtxids; - dep->numunspents = prevL.numunspents; - dep->numspends = prevL.numspends; - dep->numpkinds = prevL.numpkinds; - dep->supply = prevL.supply; - coin->latest.credits = prevcredits; - coin->latest.debits = prevdebits; - if ( dep->supply != (prevcredits - prevdebits) ) - { - printf("override supply %.8f (%.8f - %.8f)\n",dstr(dep->supply),dstr(prevcredits),dstr(prevdebits)); - dep->supply = (prevcredits - prevdebits); - } - checkbalance = iguana_verifybalances(coin,0); - if ( (checkbalance != dep->supply || fullverify != 0) && iguana_verifybalances(coin,1) != dep->supply ) - { - printf("balances mismatch\n"); - getchar(); - } - } - coin->txids->numkeys = dep->numtxids; - coin->unspents->numkeys = dep->numunspents; - coin->spends->numkeys = dep->numspends; - coin->pkhashes->numkeys = dep->numpkinds; - coin->blocks.parsedblocks = lastblock.height; - printf("\nhwmheight.%d KV counts T.%d P.%d U.%d S.%d %.8f (%.8f - %.8f)\n",hwmheight,coin->txids->numkeys,coin->pkhashes->numkeys,coin->unspents->numkeys,coin->spends->numkeys,dstr(coin->latest.dep.supply),dstr(coin->latest.credits),dstr(coin->latest.debits)); - printf("four ramchains start valid.%d height.%d txids.%d vouts.%d vins.%d pkhashes.%d %.2f minutes\n",valid,hwmheight,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,((double)time(NULL)-coin->starttime)/60.); - printf("height.%d after validateramchain hwmheight.%d flag.%d parsed.%d\n",height,hwmheight,flag,coin->blocks.parsedblocks); //getchar(); - if ( coin->blocks.parsedblocks == 0 ) - { - uint8_t txspace[32768]; struct iguana_memspace MEM; - len = (int32_t)strlen(coin->chain->genesis_hex)/2; - decode_hex(buf,len,(char *)coin->chain->genesis_hex); - iguana_sethdr(&H,coin->chain->netmagic,"block",buf,len); - iguana_meminit(&MEM,"genesis",txspace,sizeof(txspace),0); - iguana_parser(coin,0,&MEM,&MEM,0,&H,buf,len); - printf("coin->blocks.parsedblocks.%d KV counts T.%d P.%d U.%d S.%d\n",coin->blocks.parsedblocks,coin->txids->numkeys,coin->pkhashes->numkeys,coin->unspents->numkeys,coin->spends->numkeys); - printf("auto parse genesis\n"); //getchar(); - } - else iguana_clearoverage(coin,dep->numtxids,dep->numunspents,dep->numspends,dep->numpkinds,coin->Uextras,coin->pkextras,coin->accounts); - return(coin->blocks.parsedblocks); - } -#endif - if ( 0 && queue_size(&coin->blocksQ) == 0 ) - { - HASH_ITER(hh,coin->blocks.hash,block,tmp) - { - if ( bits256_nonz(block->prev_block) > 0 && (prev= iguana_blockfind(coin,block->prev_block)) != 0 ) - { - if ( prev->mainchain != 0 ) - { - char str[65]; printf("idle issue %s %d\n",bits256_str(str,block->hash2),prev->height+1); - iguana_blockQ(coin,0,-1,block->hash2,0); - } - } - } - } - struct iguana_ramchain *iguana_ramchainmergeHT(struct iguana_info *coin,struct iguana_memspace *mem,struct iguana_ramchain *ramchains[],int32_t n,struct iguana_bundle *bp) - { - /* uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,i,j,k; uint64_t allocsize = 0; - struct iguana_txid *tx; struct iguana_account *acct; struct iguana_ramchain *ramchain,*item; - struct iguana_pkhash *p,oldP; struct iguana_unspent *u; struct iguana_kvitem *ptr; - bits256 txid; uint32_t txidind,unspentind,spendind,pkind,numblocks; struct iguana_spend *s; - numtxids = numunspents = numspends = numpkinds = 1; - numexternaltxids = 1; - numblocks = 0; - for (i=0; iramchain.hdrsi,i); - return(0); - } - numtxids += item->numtxids, numunspents += item->numunspents, numspends += item->numspends; - numpkinds += item->numpkinds, numexternaltxids += item->numexternaltxids; - numblocks += item->numblocks; - } - allocsize = sizeof(*ramchain) + - (numtxids * sizeof(*ramchain->T)) + - (numunspents * (sizeof(*ramchain->U) + sizeof(*ramchain->Uextras))) + - (numspends * sizeof(*ramchain->S)) + - (numpkinds * (sizeof(*ramchain->P) + sizeof(*ramchain->pkextras) + sizeof(*ramchain->accounts))) + - (numexternaltxids * sizeof(*ramchain->externalT)); - - iguana_meminit(mem,"ramchain",0,allocsize,0); - mem->alignflag = sizeof(uint32_t); - ramchain= &bp->ramchain; //iguana_memalloc(mem,sizeof(*ramchain),1)) == 0 ) - ramchain->numblocks = numblocks; - ramchain->numtxids = numtxids, ramchain->numunspents = numunspents; - ramchain->numspends = numspends, ramchain->numpkinds = numpkinds; - ramchain->numexternaltxids = numexternaltxids; - ramchain->hdrsi = bp->ramchain.hdrsi, ramchain->bundleheight = bp->ramchain.bundleheight, ramchain->numblocks = n; - ramchain->prevbundlehash2 = bp->prevbundlehash2, ramchain->nextbundlehash2 = bp->nextbundlehash2; - ramchain->hash2 = ramchains[0]->hash2; - ramchain->prevhash2 = ramchains[0]->prevhash2, ramchain->lasthash2 = ramchains[n-1]->hash2; - ramchain->T = iguana_memalloc(mem,sizeof(*ramchain->T) * ramchain->numtxids,0); - ramchain->U = iguana_memalloc(mem,sizeof(*ramchain->U) * ramchain->numunspents,0); - if ( ramchain->numspends > 0 ) - ramchain->S = iguana_memalloc(mem,sizeof(*ramchain->S) * ramchain->numspends,0); - ramchain->Uextras = iguana_memalloc(mem,sizeof(*ramchain->Uextras) * ramchain->numunspents,1); - ramchain->P = iguana_memalloc(mem,sizeof(*ramchain->P) * ramchain->numpkinds,1); - ramchain->pkextras = iguana_memalloc(mem,sizeof(*ramchain->pkextras) * ramchain->numpkinds,1); - ramchain->accounts = iguana_memalloc(mem,sizeof(*ramchain->accounts) * ramchain->numpkinds,1); - if ( ramchain->numexternaltxids > 0 ) - ramchain->externalT = iguana_memalloc(mem,ramchain->numexternaltxids * sizeof(*ramchain->externalT),1); - if ( mem->used != allocsize ) - { - printf("error allocating ramchain %ld != %ld\n",(long)mem->used,(long)allocsize); - iguana_ramchainfree(coin,mem,ramchain); - return(0); - } - ramchain->allocsize = allocsize; - ramchain->firsti = 1; - //printf("Allocated %s for bp %d\n",mbstr(str,allocsize),bp->ramchain.bundleheight); - txidind = unspentind = numtxids = spendind = numunspents = numspends = numpkinds = ramchain->firsti; - numexternaltxids = 0; - for (i=0; ifirsti; jnumtxids; j++,txidind++) - { - tx = &ramchain->T[txidind]; - *tx = item->T[j]; - tx->txidind = txidind; - if ( (ptr= iguana_hashfind(ramchain->txids,tx->txid.bytes,sizeof(tx->txid))) != 0 ) - { - printf("unexpected duplicate txid[%d]\n",txidind); - iguana_ramchainfree(coin,mem,ramchain); - return(0); - } - iguana_hashsetHT(ramchain->txids,0,tx->txid.bytes,sizeof(bits256),txidind); - tx->firstvout = unspentind; - for (k=item->firsti; knumvouts; k++,unspentind++) - { - u = &ramchain->U[unspentind]; - *u = item->U[k]; - u->txidind = txidind; - oldP = item->P[item->U[k].pkind]; - if ( (ptr= iguana_hashfind(ramchain->pkhashes,oldP.rmd160,sizeof(oldP.rmd160))) == 0 ) - { - pkind = numpkinds++; - p = &ramchain->P[pkind]; - *p = oldP; - p->firstunspentind = unspentind; - if ( (ptr= iguana_hashsetHT(ramchain->pkhashes,0,p->rmd160,sizeof(p->rmd160),numpkinds)) == 0 ) - { - iguana_ramchainfree(coin,mem,ramchain); - printf("fatal error adding pkhash\n"); - return(0); - } - //printf("pkind.%d: %p %016lx <- %016lx\n",pkind,p,*(long *)p->rmd160,*(long *)oldP.rmd160); - } else pkind = ptr->hh.itemind; - u->pkind = pkind; - acct = &ramchain->accounts[pkind]; - u->prevunspentind = acct->lastunspentind; - acct->lastunspentind = unspentind; - acct->balance += u->value; - } - tx->firstvin = spendind; - spendind += tx->numvins; - } - numtxids += item->numtxids, numunspents += item->numunspents; - } - } - txidind = spendind = ramchain->firsti; - for (i=0; ifirsti; jnumtxids; j++,txidind++) - { - tx = &ramchain->T[j]; - for (k=item->firsti; knumvins; k++) - { - //printf("item.%p [%d] X.%p i.%d j.%d k.%d txidind.%d/%d spendind.%d/%d s->txidind.%d/v%d\n",item,item->numexternaltxids,item->externalT,i,j,k,txidind,ramchain->numtxids,spendind,ramchain->numspends,item->S[k].spendtxidind,item->S[k].vout); - if ( iguana_ramchaintxid(coin,&txid,item,&item->S[k]) < 0 ) - { - printf("i.%d j.%d k.%d error getting txid firsti.%d X.%d vout.%d spend.%d/%d numX.%d numT.%d\n",i,j,k,item->firsti,item->S[k].external,item->S[k].vout,item->S[k].spendtxidind,item->numspends,item->numexternaltxids,item->numtxids); - //iguana_ramchainfree(coin,mem,ramchain); - //return(0); - } - s = &ramchain->S[spendind]; - *s = item->S[k]; - if ( s->vout == 0xffff ) - { - // mining output - } - else if ( (ptr= iguana_hashfind(ramchain->txids,txid.bytes,sizeof(txid))) != 0 ) - { - if ( (s->spendtxidind= ptr->hh.itemind) >= ramchain->numtxids ) - { - s->external = 1; - s->spendtxidind -= ramchain->numtxids; - } - else if ( s->spendtxidind >= item->firsti && s->spendtxidind < item->numtxids ) - { - s->external = 0; - unspentind = (ramchain->T[s->spendtxidind].firstvout + s->vout); - u = &ramchain->U[unspentind]; - p = &ramchain->P[u->pkind]; - if ( ramchain->pkextras[u->pkind].firstspendind == 0 ) - ramchain->pkextras[u->pkind].firstspendind = spendind; - acct = &ramchain->accounts[u->pkind]; - s->prevspendind = acct->lastspendind; - acct->lastspendind = spendind; - if ( ramchain->Uextras[unspentind].spendind != 0 ) - { - printf("double spend u.%d has spendind.%d when s.%d refers to it\n",unspentind,ramchain->Uextras[unspentind].spendind,spendind); - iguana_ramchainfree(coin,mem,ramchain); - return(0); - } - ramchain->Uextras[unspentind].spendind = spendind; - } - spendind++; - } - else if ( numexternaltxids < ramchain->numexternaltxids ) - { - s->external = 1; - ramchain->externalT[numexternaltxids] = txid; - iguana_hashsetHT(ramchain->txids,0,ramchain->externalT[numexternaltxids].bytes,sizeof(ramchain->externalT[numexternaltxids]),ramchain->numtxids + numexternaltxids); - s->spendtxidind = numexternaltxids++; - spendind++; - } - else printf("numexternaltxids.%d >= ramchain numexternaltxids.%d\n",numexternaltxids,ramchain->numexternaltxids); - } - } - // iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; } iguana_Uextra { uint32_t spendind; } - // iguana_pkhash { uint8_t rmd160[20]; uint32_t firstunspentind,flags; } iguana_pkextra { uint32_t firstspendind; } - // iguana_account { uint64_t balance; uint32_t lastunspentind,lastspendind; } - // iguana_spend { uint32_t unspentind,prevspendind:31,diffsequence:1; } - numspends += item->numspends; - } - } - //for (i=0; iP[i],*(long *)ramchain->P[i].rmd160); - //printf("numpkinds.%d\n",numpkinds); - if ( 0 ) - { - memcpy(&ramchain->P[numpkinds],ramchain->pkextras,sizeof(*ramchain->pkextras) * numpkinds); - ramchain->pkextras = (void *)&ramchain->P[numpkinds]; - memcpy(&ramchain->pkextras[numpkinds],ramchain->accounts,sizeof(*ramchain->accounts) * numpkinds); - ramchain->accounts = (void *)&ramchain->pkextras[numpkinds]; - memcpy(&ramchain->accounts[numpkinds],ramchain->externalT,sizeof(*ramchain->externalT) * numexternaltxids); - ramchain->externalT = (void *)&ramchain->accounts[numpkinds]; - } - ramchain->allocsize -= ((ramchain->numpkinds - numpkinds) * (sizeof(*ramchain->P) + sizeof(*ramchain->pkextras) + sizeof(*ramchain->accounts))); - ramchain->allocsize -= ((ramchain->numexternaltxids - numexternaltxids) * sizeof(*ramchain->externalT)); - ramchain->numpkinds = numpkinds; - ramchain->numexternaltxids = numexternaltxids;*/ - /*vupdate_sha256(ramchain->lhashes[IGUANA_LHASH_UNSPENT].bytes,&ramchain->states[IGUANA_LHASH_UNSPENT],(void *)ramchain->U,sizeof(*ramchain->U)*ramchain->numunspents); - vupdate_sha256(ramchain->lhashes[IGUANA_LHASH_ACCOUNTS].bytes,&ramchain->states[IGUANA_LHASH_ACCOUNTS],(void *)acct,sizeof(*acct)); - vupdate_sha256(ramchain->lhashes[IGUANA_LHASH_SPENDS].bytes,&ramchain->states[IGUANA_LHASH_SPENDS],(void *)ramchain->S,sizeof(*ramchain->S)*); - vupdate_sha256(ramchain->lhashes[IGUANA_LHASH_TXIDS].bytes,&ramchain->states[IGUANA_LHASH_TXIDS],(void *)tx,sizeof(*tx));*/ - /*mem->used = (long)ramchain->allocsize; - printf("B.%d T.%d U.%d S.%d P.%d combined ramchain size.%ld\n",ramchain->numblocks,ramchain->numtxids,ramchain->numunspents,ramchain->numspends,ramchain->numpkinds,(long)ramchain->allocsize); - return(ramchain);*/ - return(0); - } - - /* - //if ( num > coin->chain->bundlesize+1 ) - // num = coin->chain->bundlesize+1; - for (i=1; i 0 ) - { - if ( (block= iguana_blockhashset(coin,-1,blockhashes[i],1)) != 0 && prev != 0 ) - { - //if ( prev->mainchain == 0 ) - // prev->hh.next = block; - /*if ( prev->hh.next == 0 && block->hh.prev == 0 ) - block->hh.prev = prev; - else if ( prev->hh.next == 0 && block->hh.prev == prev ) - prev->hh.next = block; - else if ( prev->hh.next == block && block->hh.prev == prev ) - { - if ( 0 && i < coin->chain->bundlesize ) - { - if ( iguana_bundlehash2add(coin,0,bp,i,blockhashes[i]) < 0 ) - { - if ( prev->mainchain == 0 ) - block->hh.prev = prev->hh.next = 0; - memset(bp->hashes[i].bytes,0,sizeof(bp->hashes[i])); - } - } - else if ( 0 && bp->bundleheight + coin->chain->bundlesize >= coin->bundlescount*coin->chain->bundlesize ) - { - char str[65]; printf("AUTOCREATE.%d new bundle.%s\n",bp->bundleheight + coin->chain->bundlesize,bits256_str(str,blockhashes[i])); - iguana_bundlecreate(coin,&bundlei,bp->bundleheight + coin->chain->bundlesize,blockhashes[i]); - for (j=2; jmainchain == 0 ) - block->hh.prev = prev->hh.next = 0; - } - //if ( (i % coin->chain->bundlesize) <= 1 ) - // iguana_blockQ(coin,0,-1,blockhashes[i],1); - //else //if ( bp != 0 && i < bp->n && bp->requests[i] == 0 ) - // iguana_blockQ(coin,0,-1,blockhashes[i],0); - } - prev = block; - }*/ - - int32_t iguana_ROmapchain(uint32_t *numtxidsp,uint32_t *numunspentsp,uint32_t *numspendsp,uint32_t *numpkindsp,uint32_t *numexternaltxidsp,struct iguana_ramchain *mapchain,void *ptr,long filesize,long fpos,bits256 firsthash2,bits256 lasthash2,int32_t height,int32_t numblocks,int32_t hdrsi,int32_t bundlei) - { - int32_t firsti = 1; - mapchain->fileptr = ptr; - mapchain->filesize = filesize; - mapchain->H.data = (void *)((long)ptr + fpos); - mapchain->H.ROflag = 1; - if ( iguana_ramchain_size(mapchain) != mapchain->H.data->allocsize || fpos+mapchain->H.data->allocsize > filesize ) - { - printf("iguana_bundlesaveHT size mismatch %ld vs %ld vs filesize.%ld\n",(long)iguana_ramchain_size(mapchain),(long)mapchain->H.data->allocsize,(long)filesize); - return(-1); - } - else if ( memcmp(firsthash2.bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) - { - char str[65],str2[65]; printf("iguana_bundlesaveHT hash2 mismatch %s vs %s\n",bits256_str(str,firsthash2),bits256_str(str2,mapchain->H.data->firsthash2)); - return(-1); - } - iguana_ramchain_link(mapchain,firsthash2,lasthash2,hdrsi,height,bundlei,1,firsti,1); - *numtxidsp += mapchain->H.data->numtxids; - *numunspentsp += mapchain->H.data->numunspents; - *numspendsp += mapchain->H.data->numspends; - if( mapchain->H.data->numpkinds != 0 ) - *numpkindsp += mapchain->H.data->numpkinds; - else *numpkindsp += mapchain->H.data->numunspents; - if( mapchain->H.data->numexternaltxids != 0 ) - *numexternaltxidsp += mapchain->H.data->numspends; - else *numexternaltxidsp += mapchain->H.data->numspends; - //printf("(%d %d %d) ",numtxids,numunspents,numspends); - //printf("%d ",numtxids); - return(0); - } - - bits256 iguana_lhashcalc(struct iguana_info *coin,struct iguana_ramchaindata *rdata,RAMCHAIN_FUNC) - { - bits256 sha256; - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_TXIDS].bytes,(uint8_t *)T,sizeof(struct iguana_txid)*rdata->numtxids); - if ( ramchain->expanded != 0 ) - { - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_UNSPENTS].bytes,(uint8_t *)Ux,sizeof(struct iguana_unspent)*rdata->numunspents); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_SPENDS].bytes,(uint8_t *)Sx,sizeof(struct iguana_spend)*rdata->numspends); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_PKHASHES].bytes,(uint8_t *)P,sizeof(struct iguana_pkhash)*rdata->numpkinds); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_SPENTINDS].bytes,(uint8_t *)U2,sizeof(struct iguana_Uextra)*rdata->numunspents); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_FIRSTSPENDS].bytes,(uint8_t *)P2,sizeof(struct iguana_pkextra)*rdata->numpkinds); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_ACCOUNTS].bytes,(uint8_t *)A,sizeof(struct iguana_account)*rdata->numpkinds); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_EXTERNALS].bytes,(uint8_t *)X,sizeof(bits256)*rdata->numexternaltxids); - } - else - { - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_UNSPENTS].bytes,(uint8_t *)U,sizeof(struct iguana_unspent20)*rdata->numunspents); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_SPENDS].bytes,(uint8_t *)S,sizeof(struct iguana_spend256)*rdata->numspends); - } - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_TXBITS].bytes,TXbits,(int32_t)hconv_bitlen(rdata->numtxsparse*rdata->txsparsebits)); - vcalc_sha256(0,rdata->lhashes[IGUANA_LHASH_PKBITS].bytes,PKbits,(int32_t)hconv_bitlen(rdata->numpksparse*rdata->pksparsebits)); - memset(&rdata->sha256,0,sizeof(rdata->sha256)); - vcalc_sha256(0,sha256.bytes,(void *)rdata,sizeof(*rdata)); - } - - /*struct iguana_prevdep - { - double PoW; // yes I know this is not consensus safe, it is used only for approximations locally - uint64_t supply; - uint32_t numtxids,numunspents,numspends,numpkinds; - } __attribute__((packed)); - - struct iguanakv - { - char name[63],fname[512],threadsafe; FILE *fp; - portable_mutex_t KVmutex,MMlock,MMmutex; - void *HDDitems,*HDDitems2,*HDDitems3,**HDDitemsp,**HDDitems2p,**HDDitems3p; // linear array of HDDitems; - struct iguana_kvitem *hashtables[0x100]; // of HDDitems - struct iguana_mappedptr M,M2,M3; - struct iguana_memspace HASHPTRS;//,MEM; - double mult; - uint64_t updated; - int32_t keysize,keyoffset,RAMvaluesize,HDDvaluesize,valuesize2,valuesize3; - int32_t numkeys,dispflag,flags,incr,numitems,numvalid,maxitemind; - uint32_t iteruarg; int32_t iterarg; - uint8_t *space; - };*/ - rdata->txsparsebits = hcalc_bitsize(numtxids); - rdata->numtxsparse = SPARSECOUNT(numtxids); - rdata->pksparsebits = hcalc_bitsize(numpkinds); - rdata->numpksparse = SPARSECOUNT(numpkinds); - rdata->Toffset = offset, offset += (sizeof(struct iguana_txid) * numtxids); - if ( ramchain->expanded != 0 ) - { - rdata->Uoffset = offset, offset += (sizeof(struct iguana_unspent) * numunspents); - rdata->Soffset = offset, offset += (sizeof(struct iguana_spend) * numspends); - rdata->Poffset = offset, offset += (sizeof(struct iguana_pkhash) * numpkinds); - rdata->U2offset = offset, offset += (sizeof(struct iguana_Uextra) * numunspents); - rdata->P2offset = offset, offset += (sizeof(struct iguana_pkextra) * numpkinds); - rdata->Aoffset = offset, offset += (sizeof(struct iguana_account) * numpkinds); - rdata->Xoffset = offset, offset += (sizeof(bits256) * numexternaltxids); - } - else - { - rdata->Uoffset = offset, offset += (sizeof(struct iguana_unspent20) * numunspents); - rdata->Soffset = offset, offset += (sizeof(struct iguana_spend256) * numspends); - } - - rdata->TXoffset = offset, offset += (((int64_t)rdata->numtxsparse*rdata->txsparsebits)/8 + 1); - rdata->PKoffset = offset, offset += (((int64_t)rdata->numpksparse*rdata->pksparsebits)/8 + 1); - - - tmp = *rdata; - fpos = ftell(fp); - iguana_rdata_action(0,0,&trunc,0,rdata,expanded,numtxids,numunspents,numspends,numpkinds,numexternaltxids,0,0,0,0); - - offset = sizeof(*rdata); - rdata->Toffset = offset, offset += (sizeof(struct iguana_txid) * rdata->numtxids); - if ( ramchain->expanded != 0 ) - { - rdata->Uoffset = offset, offset += (sizeof(struct iguana_unspent) * rdata->numunspents); - rdata->Soffset = offset, offset += (sizeof(struct iguana_spend) * rdata->numspends); - rdata->Poffset = offset, offset += (sizeof(struct iguana_pkhash) * rdata->numpkinds); - rdata->U2offset = offset, offset += (sizeof(struct iguana_Uextra) * rdata->numunspents); - rdata->P2offset = offset, offset += (sizeof(struct iguana_pkextra) * rdata->numpkinds); - rdata->Aoffset = offset, offset += (sizeof(struct iguana_account) * rdata->numpkinds); - rdata->Xoffset = offset, offset += (sizeof(bits256) * rdata->numexternaltxids); - } - else - { - rdata->Uoffset = offset, offset += (sizeof(struct iguana_unspent20) * rdata->numunspents); - rdata->Soffset = offset, offset += (sizeof(struct iguana_spend256) * rdata->numspends); - } - rdata->TXoffset = offset, offset += (((int64_t)rdata->numtxsparse*rdata->txsparsebits)/8 + 1); - rdata->PKoffset = offset, offset += (((int64_t)rdata->numpksparse*rdata->pksparsebits)/8 + 1); - rdata->allocsize = offset; - rdata->sha256 = iguana_lhashcalc(coin,rdata,RAMCHAIN_ARGS); - if ( iguana_ramchain_size(ramchain) != offset ) - printf("iguana_ramchain_size %ld vs %ld\n",(long)iguana_ramchain_size(ramchain),(long)offset), getchar(); - rdata->sha256 = sha256 = iguana_lhashcalc(coin,rdata,RAMCHAIN_ARG); - fwrite(rdata,1,sizeof(*rdata),fp); - *rdata = tmp; - fwrite(T,sizeof(struct iguana_txid),rdata->numtxids,fp); - if ( ramchain->expanded != 0 ) - { - fwrite(Ux,sizeof(struct iguana_unspent),rdata->numunspents,fp); - fwrite(Sx,sizeof(struct iguana_spend),rdata->numspends,fp); - fwrite(P,sizeof(struct iguana_pkhash),rdata->numpkinds,fp); - fwrite(U2,sizeof(struct iguana_Uextra),rdata->numunspents,fp); - fwrite(P2,sizeof(struct iguana_pkextra),rdata->numpkinds,fp); - fwrite(A,sizeof(struct iguana_account),rdata->numpkinds,fp); - fwrite(X,sizeof(bits256),rdata->numexternaltxids,fp); - //printf("iguana_ramchain_save.(%s): (%ld - %ld) diff.%ld vs %ld [%ld]\n",fname,ftell(fp),(long)fpos,(long)(ftell(fp) - fpos),(long)rdata->allocsize,(long)(ftell(fp) - fpos) - (long)rdata->allocsize); - } - else - { - fwrite(U,sizeof(struct iguana_unspent20),rdata->numunspents,fp); - fwrite(S,sizeof(struct iguana_spend256),rdata->numspends,fp); - } - fwrite(TXbits,1,((int64_t)rdata->numtxsparse*rdata->txsparsebits)/8 + 1,fp); - fwrite(PKbits,1,((int64_t)rdata->numpksparse*rdata->pksparsebits)/8 + 1,fp); - if ( (ftell(fp) - fpos) != rdata->allocsize ) - { - printf("(ftell.%ld - fpos.%ld) %ld vs %ld\n",ftell(fp),fpos,ftell(fp)-fpos,(long)rdata->allocsize); - fpos = -1; - } - //int32_t i; char str[65]; - //for (i=0; inumexternaltxids; i++) - // printf("X[%d] %s\n",i,bits256_str(str,X[i])); - uint32_t iguana_updatescript(struct iguana_info *coin,uint32_t blocknum,uint32_t txidind,uint32_t spendind,uint32_t unspentind,uint64_t value,uint8_t *script,int32_t scriptlen,uint32_t sequence) - { - return(0); - } - - function httpGet(theUrl)\ - {\ - var xmlhttp;\ - if ( window.XMLHttpRequest )\ - xmlhttp = new XMLHttpRequest();\ - else\ - xmlhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");\ - xmlhttp.onreadystatechange = function()\ - {\ - if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 )\ - {\ - createDiv(xmlhttp.responseText);\ - }\ - }\ - xmlhttp.open(\"GET\", theUrl, false);\ - xmlhttp.send(null);\ - }\ - var jsonstr = httpGet(\"http://127.0.0.1:7778/json/bitmap\"); \ - struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t recvlen,int32_t *newhwmp) - { - struct iguana_bundle *bp=0; int32_t bundlei = -2; struct iguana_block *block; double duration; - bp = iguana_bundleset(coin,&block,&bundlei,origblock); - if ( block != 0 ) - { - block->RO.recvlen = recvlen; - block->ipbits = req->ipbits; - if ( bp == 0 && req->copyflag != 0 && block->rawdata == 0 ) - { - char str[65]; printf("%s copyflag.%d %d data %d %p\n",bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,bp); - block->rawdata = mycalloc('n',1,block->RO.recvlen); - memcpy(block->rawdata,req->serialized,block->RO.recvlen); - block->copyflag = 1; - } - //printf("datalen.%d ipbits.%x\n",datalen,req->ipbits); - } else printf("cant create block.%llx block.%p bp.%p bundlei.%d\n",(long long)origblock->RO.hash2.txid,block,bp,bundlei); - if ( bp != 0 && bundlei >= 0 ) - { - //bp->ipbits[bundlei] = block->ipbits; - if ( 0 && bp->requests[bundlei] > 2 ) - printf("recv bundlei.%d hdrs.%d reqs.[%d] fpos.%d datalen.%d recvlen.(%d %d) ipbits.(%x %x %x)\n",bundlei,bp->hdrsi,bp->requests[bundlei],bp->fpos[bundlei],datalen,block->RO.recvlen,req->recvlen,block->ipbits,bp->ipbits[bundlei],req->ipbits); - if ( recvlen > 0 ) - { - SETBIT(bp->recv,bundlei); - if ( bp->issued[bundlei] > 0 ) - { - bp->durationsum += (int32_t)(time(NULL) - bp->issued[bundlei]); - bp->durationcount++; - if ( duration < bp->avetime/10. ) - duration = bp->avetime/10.; - else if ( duration > bp->avetime*10. ) - duration = bp->avetime * 10.; - dxblend(&bp->avetime,duration,.99); - dxblend(&coin->avetime,bp->avetime,.9); - } - } - if ( 0 && strcmp(coin->symbol,"BTC") != 0 && bundlei < coin->chain->bundlesize-1 && bits256_nonz(bp->hashes[bundlei+1]) != 0 && bp->fpos[bundlei+1] < 0 ) - iguana_blockQ(coin,bp,bundlei+1,bp->hashes[bundlei+1],0); - } - if ( 0 && block != 0 && strcmp(coin->symbol,"BTC") != 0 ) - { - if ( (bp = iguana_bundlefind(coin,&bp,&bundlei,block->RO.prev_block)) != 0 ) - { - if ( bp->fpos[bundlei] < 0 ) - iguana_blockQ(coin,bp,bundlei,block->RO.prev_block,0); - } - } - return(req); - } - struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) - { - struct iguana_block *block; bits256 zero,*hashes; struct iguana_bundle *bp = 0; - int32_t bundlei = -2; - *bundleip = -2; *blockp = 0; - if ( origblock == 0 ) - return(0); - memset(zero.bytes,0,sizeof(zero)); - if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) - { - if ( block != origblock ) - iguana_blockcopy(coin,block,origblock); - *blockp = block; - if ( bits256_nonz(block->RO.prev_block) > 0 ) - iguana_patch(coin,block); - if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,block->RO.hash2)) != 0 ) - { - if ( bundlei < coin->chain->bundlesize ) - { - block->bundlei = bundlei; - block->hdrsi = bp->hdrsi; - //iguana_hash2set(coin,"blockadd",bp,block->bundlei,block->hash2); - iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); - if ( bundlei == 0 ) - { - if ( bp->hdrsi > 0 && (bp= coin->bundles[bp->hdrsi-1]) != 0 ) - { - //printf("add to prev hdrs.%d\n",bp->hdrsi); - iguana_bundlehash2add(coin,0,bp,coin->chain->bundlesize-1,block->RO.prev_block); - if ( 0 && bp->fpos[coin->chain->bundlesize-1] < 0 && strcmp(coin->symbol,"BTC") != 0 ) - iguana_blockQ(coin,bp,coin->chain->bundlesize-1,block->RO.prev_block,0); - } - } - else - { - //printf("prev issue.%d\n",bp->bundleheight+bundlei-1); - iguana_bundlehash2add(coin,0,bp,bundlei-1,block->RO.prev_block); - if ( 0 && bp->fpos[bundlei-1] < 0 && strcmp(coin->symbol,"BTC") != 0 ) - iguana_blockQ(coin,bp,bundlei-1,block->RO.prev_block,0); - } - } - } - if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,block->RO.prev_block)) != 0 ) - { - //printf("found prev.%d\n",bp->bundleheight+bundlei); - if ( bundlei < coin->chain->bundlesize ) - { - if ( bundlei == coin->chain->bundlesize-1 ) - { - if ( coin->bundlescount < bp->hdrsi+1 ) - { - char str[65]; printf("autoextend CREATE.%d new bundle.%s\n",bp->bundleheight + coin->chain->bundlesize,bits256_str(str,block->RO.hash2)); - iguana_bundlecreate(coin,&bundlei,bp->bundleheight + coin->chain->bundlesize,block->RO.hash2,zero); - } - } - else if ( bundlei < coin->chain->bundlesize-1 ) - { - block->bundlei = bundlei + 1; - block->hdrsi = bp->hdrsi; - iguana_bundlehash2add(coin,0,bp,bundlei+1,block->RO.hash2); - } - } - } - //char str[65]; printf("iguana_recvblock (%s) %d %d[%d] %p\n",bits256_str(str,block->hash2),block->havebundle,block->hdrsi,bundlei,bp); - } - return(iguana_bundlefind(coin,&bp,bundleip,origblock->RO.hash2)); - } - int32_t iguana_bundlemode(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei) - { - if ( bp->ipbits[bundlei] == 0 ) - return(-1); - else if ( bp->emitfinish > coin->starttime ) - { - if ( bp->ramchain.numblocks == bp->n ) - return(1); - else return(2); - } - else return(0); - } - - - /*char *iguana_genericjsonstr(char *jsonstr,char *remoteaddr) - { - cJSON *json; char *retjsonstr,*methodstr,*agentstr; - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( (agentstr= jstr(json,"agent")) == 0 ) - agentstr = "SuperNET"; - if ( (methodstr= jstr(json,"method")) != 0 ) - retjsonstr = iguana_agentjson(agentstr,0,methodstr,json,remoteaddr); - else retjsonstr = clonestr("{\"error\":\"no method in generic JSON\"}"); - free_json(json); - } else retjsonstr = clonestr("{\"error\":\"cant parse generic JSON\"}"); - return(retjsonstr); - }*/ - - char *iguana_remoteparser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json) - { - int32_t i,n,remains,numsent; char *jsonstr = 0,*retstr = 0; uint8_t hdr[128]; - if ( agent->sock < 0 ) - agent->sock = iguana_socket(0,agent->hostname,agent->port); - if ( agent->sock >= 0 ) - { - i = 0; - jsonstr = jprint(json,0); - n = (int32_t)strlen(jsonstr) + 1; - remains = n; - //printf("RETBUF.(%s)\n",retbuf); - while ( remains > 0 ) - { - if ( (numsent= (int32_t)send(agent->sock,&jsonstr[i],remains,MSG_NOSIGNAL)) < 0 ) - { - if ( errno != EAGAIN && errno != EWOULDBLOCK ) - { - printf("%s: %s numsent.%d vs remains.%d of %d errno.%d (%s) usock.%d\n",jsonstr,agent->name,numsent,remains,n,errno,strerror(errno),agent->sock); - break; - } - } - else if ( remains > 0 ) - { - remains -= numsent; - i += numsent; - if ( remains > 0 ) - printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,n); - } - } - if ( (n= (int32_t)recv(agent->sock,hdr,sizeof(hdr),0)) >= 0 ) - { - remains = (hdr[0] + ((int32_t)hdr[1] << 8) + ((int32_t)hdr[2] << 16)); - retstr = mycalloc('p',1,remains + 1); - i = 0; - while ( remains > 0 ) - { - if ( (n= (int32_t)recv(agent->sock,&retstr[i],remains,0)) < 0 ) - { - if ( errno == EAGAIN ) - { - printf("EAGAIN for len %d, remains.%d\n",n,remains); - usleep(10000); - } - break; - } - else - { - if ( n > 0 ) - { - remains -= n; - i += n; - } else usleep(10000); - } - } - } - free(jsonstr); - } - if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"null return\"}"); - return(retstr); - } - - struct iguana_agent *Agents[16]; - - cJSON *iguana_agentinfojson(struct iguana_agent *agent) - { - cJSON *json= cJSON_CreateObject(); - jaddstr(json,"name",agent->name); - jadd(json,"methods",agent->methods); - if ( agent->port != 0 ) - jaddnum(json,"port",agent->port); - else jaddstr(json,"type","builtin"); - return(json); - } - - char *iguana_addagent(char *name,char *(*parsefunc)(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json),char *hostname,cJSON *methods,uint16_t port,char *pubkeystr,char *privkeystr) - { - int32_t i; struct iguana_agent *agent; char retbuf[8192]; - for (i=0; iname,name) == 0 ) - { - if ( pubkeystr != 0 && privkeystr != 0 && strlen(pubkeystr) == 64 && strlen(privkeystr) == 64 ) - { - decode_hex(agent->pubkey.bytes,sizeof(bits256),pubkeystr); - decode_hex(agent->privkey.bytes,sizeof(bits256),privkeystr); - } - if ( port != 0 && agent->port == 0 ) - { - if ( agent->sock >= 0 ) - close(agent->sock); - agent->port = port; - strcpy(agent->hostname,hostname); - agent->sock = iguana_socket(0,agent->hostname,port); - printf("set (%s) port.%d for %s -> sock.%d\n",hostname,port,agent->name,agent->sock); - } - if ( agent->port > 0 && agent->sock < 0 && agent->hostname[0] != 0 && (agent->sock= iguana_socket(0,agent->hostname,agent->port)) < 0 ) - return(clonestr("{\"result\":\"existing agent couldnt connect to remote agent\"}")); - else return(clonestr("{\"result\":\"agent already there\"}")); - } - } - for (i=0; iname,name,sizeof(agent->name)-1); - strncpy(agent->hostname,hostname,sizeof(agent->hostname)-1); - agent->methods = methods, agent->nummethods = cJSON_GetArraySize(methods); - agent->sock = -1; - agent->port = port; - agent->parsefunc = (void *)parsefunc; - if ( pubkeystr != 0 && privkeystr != 0 && strlen(pubkeystr) == 64 && strlen(privkeystr) == 64 ) - { - decode_hex(agent->pubkey.bytes,sizeof(bits256),pubkeystr); - decode_hex(agent->privkey.bytes,sizeof(bits256),privkeystr); - } - if ( port > 0 ) - { - if ( (agent->sock= iguana_socket(0,hostname,port)) < 0 ) - return(clonestr("{\"result\":\"agent added, but couldnt connect to remote agent\"}")); - } - sprintf(retbuf,"{\"result\":\"agent added\",\"name\":\"%s\",\"methods\":%s,\"hostname\":\"%s\",\"port\":%u,\"sock\":%d}",agent->name,jprint(agent->methods,0),agent->hostname,agent->port,agent->sock); - return(clonestr(retbuf)); - } - } - return(clonestr("{\"error\":\"no more agent slots available\"}")); - } - else if ( strcmp(method,"addagent") == 0 ) - { - char *hostname = "127.0.0.1",*name; uint16_t port; - if ( (name= jstr(json,"name")) != 0 && (methods= jarray(&n,json,"methods")) != 0 ) - { - if ( (port= juint(json,"port")) != 0 ) - { - if ( (hostname= jstr(json,"host")) == 0 ) - { - if ( (hostname= jstr(json,"ipaddr")) == 0 ) - hostname = "127.0.0.1"; - } - if ( hostname == 0 ) - return(clonestr("{\"error\":\"no host specified for remote agent\"}")); - } - else if ( strcmp(name,"pangea") != 0 && strcmp(name,"InstantDEX") != 0 && strcmp(name,"jumblr") != 0 ) - return(clonestr("{\"error\":\"no port specified for remote agent\"}")); - return(iguana_addagent(name,iguana_remoteparser,hostname,methods,port,jstr(json,"pubkey"),jstr(json,"privkey"))); - } else return(clonestr("{\"error\":\"cant addagent without name and methods\"}")); - } - if ( (retstr= iguana_addagent("ramchain",ramchain_parser,"127.0.0.1",cJSON_Parse("[\"block\", \"tx\", \"txs\", \"rawtx\", \"balance\", \"totalreceived\", \"totalsent\", \"utxo\", \"status\"]"),0,0,0)) != 0 ) - printf("%s\n",retstr), free(retstr); - - - /*void iguana_issuejsonstrM(void *arg) - { - cJSON *json; int32_t fd; char *retjsonstr,*jsonstr = arg; - retjsonstr = iguana_JSON(jsonstr); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( (fd= juint(json,"retdest")) > 0 ) - { - send(fd,jsonstr,(int32_t)strlen(jsonstr)+1,MSG_NOSIGNAL); - } - free_json(json); - return; - } - printf("%s\n",retjsonstr); - free(retjsonstr);//,strlen(retjsonstr)+1); - free(jsonstr);//,strlen(jsonstr)+1); - }*/ - - int32_t iguana_rpctestvector(struct iguana_info *coin,char *checkstr,char *jsonstr,int32_t maxlen,int32_t testi) - { - int32_t len,checklen; - sprintf(jsonstr,"{\"rpc.%s testvector.%d\"}",coin->symbol,testi); - sprintf(checkstr,"{\"rpc.%s testvector.%d checkstr should have all info needed to verify the rpc request\"}",coin->symbol,testi); - len = (int32_t)strlen(jsonstr); - checklen = (int32_t)strlen(checkstr); - if ( len > maxlen || checklen > maxlen ) - printf("iguana_rpctestvector: i was bad and overflowed buffer len.%d checklen.%d\n",len,checklen), exit(-1); - if ( checklen > len ) - len = checklen; - return(len); - } - - int32_t iguana_rpctestcheck(struct iguana_info *coin,char *jsonstr,char *retjsonstr) - { - if ( (rand() % 100) == 0 ) // 1% failure rate - return(-1); - else return(0); - } - - int32_t iguana_rpctest(struct iguana_info *coin) - { - /* static int32_t testi,good,bad; - char *retjsonstr,jsonstr[4096],checkstr[sizeof(jsonstr)]; // should be big enough - //if ( (rand() % 1000) < 999 ) // if no test active, just return 0 - return(0); - if ( iguana_rpctestvector(coin,checkstr,jsonstr,sizeof(jsonstr),testi++) > 0 ) - { - retjsonstr = iguana_rpc(coin,jsonstr); - if ( iguana_rpctestcheck(coin,jsonstr,retjsonstr) < 0 ) - bad++, printf("rpctestcheck.%s error: (%s) -> (%s) | good.%d bad.%d %.2f%%\n",coin->symbol,jsonstr,retjsonstr,good,bad,100.*(double)good/(good+bad)); - else good++; - free(retjsonstr); - return(1); // indicates was active - }*/ - return(0); - } - - char *iguana_agentjson(char *name,struct iguana_info *coin,char *method,cJSON *json,char *remoteaddr) - { - cJSON *retjson = 0,*array,*methods,*obj; int32_t i,n,j; struct iguana_agent *agent; - if ( strcmp(name,"SuperNET") != 0 ) - { - for (i=0; iname,name) == 0 ) - { - if ( agent->parsefunc != 0 ) - { - for (j=0; jnummethods; j++) - { - if ( (obj= jitem(agent->methods,j)) != 0 ) - { - if ( strcmp(method,jstr(obj,0)) == 0 ) - return((*agent->parsefunc)(agent,method,json,remoteaddr)); - } - } - return(clonestr("{\"result\":\"agent doesnt have method\"}")); - } else return(clonestr("{\"result\":\"agent doesnt have parsefunc\"}")); - } - } - } - else if ( remoteaddr == 0 || strcmp(remoteaddr,"127.0.0.1") != 0 ) // public api - { - char *coinstr; int32_t j,k,l,r,rr; struct iguana_peer *addr; - array = 0; - if ( strcmp(method,"getpeers") == 0 ) - { - if ( (coinstr= jstr(json,"coin")) != 0 ) - { - if ( (array= iguana_peersjson(iguana_coinfind(coinstr),1)) == 0 ) - return(clonestr("{\"error\":\"coin not found\"}")); - } - else - { - n = 0; - array = cJSON_CreateArray(); - r = rand(); - for (i=0; ipeers.active[l]; - if ( addr->usock >= 0 && addr->supernet != 0 ) - { - jaddistr(array,addr->ipaddr); - if ( ++n >= 64 ) - break; - } - } - } - } - } - if ( array != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","mypeers"); - jaddstr(retjson,"result","peers found"); - jadd(retjson,"peers",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no peers found\"}")); - } - else if ( strcmp(method,"mypeers") == 0 ) - { - printf("mypeers from %s\n",remoteaddr!=0?remoteaddr:"local"); - } - } - else // local api - { - if ( strcmp(method,"list") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddistr(array,Coins[i]->symbol); - } - jadd(retjson,"coins",array); - array = cJSON_CreateArray(); - for (i=0; iname[0] != 0 ) - jaddi(array,iguana_agentinfojson(Agents[i])); - } - jadd(retjson,"agents",array); - return(jprint(retjson,1)); - } - else if ( strcmp(method,"peers") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddi(array,iguana_peersjson(Coins[i],0)); - } - jadd(retjson,"allpeers",array); - return(jprint(retjson,1)); - } - } - return(clonestr("{\"result\":\"stub processed generic json\"}")); - } - - char *iguana_jsonstr(struct iguana_info *coin,char *jsonstr,char *remoteaddr) - { - cJSON *json; char *retjsonstr,*methodstr,*agentstr; - //printf("iguana_jsonstr.(%s)\n",jsonstr); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( (methodstr= jstr(json,"method")) != 0 ) - { - if ( (agentstr= jstr(json,"agent")) == 0 || strcmp(agentstr,"iguana") == 0 ) - retjsonstr = iguana_coinjson(coin,methodstr,json); - else retjsonstr = iguana_agentjson(agentstr,coin,methodstr,json,remoteaddr); - } else retjsonstr = clonestr("{\"error\":\"no method in JSON\"}"); - free_json(json); - } else retjsonstr = clonestr("{\"error\":\"cant parse JSON\"}"); - printf("iguana_jsonstr.(%s)\n",retjsonstr); - return(retjsonstr); - } - char *iguana_htmlget(char *space,int32_t max,int32_t *jsonflagp,char *path,char *remoteaddr,int32_t localaccess) - { - char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json); - struct iguana_info *coin = 0; cJSON *json; bits256 hash2; int32_t height,i; - char buf[64],jsonstr[1024],coinstr[64],*retstr; - for (i=0; path[i]!=0; i++) - if ( path[i] == ' ' ) - break; - path[i] = 0; - if ( path[strlen(path)-1] == '/' ) - path[strlen(path)-1] = 0; - if ( strncmp(path,"/api",strlen("/api")) == 0 ) - { - *jsonflagp = 1; - path += strlen("/api"); - } else *jsonflagp = 0; - iguana_coinset(coinstr,path); - if ( coinstr[0] != 0 ) - coin = iguana_coinfind(coinstr); - else coin = 0; - if ( strncmp(path,"/bitmap",strlen("/bitmap")) == 0 ) - { - path += strlen("/bitmap"); - *jsonflagp = 2; - iguana_bitmap(space,max,path); - return(space); - } - //printf("GETCHECK.(%s)\n",path); - if ( strncmp(path,"/ramchain/",strlen("/ramchain/")) == 0 ) - { - path += strlen("/ramchain/"); - if ( strncmp(path,"block/",strlen("block/")) == 0 ) - { - path += strlen("block/"); - if ( strncmp(path,"height/",strlen("height/")) == 0 ) - { - height = atoi(path + strlen("height/")); - sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"block\",\"coin\":\"%s\",\"height\":%d,\"txids\":1}",coinstr,height); - return(iguana_ramchain_glue(coin,"block",Currentjsonstr)); - } - else if ( strncmp(path,"hash/",strlen("hash/")) == 0 ) - { - decode_hex(hash2.bytes,sizeof(hash2),path + strlen("hash/")); - char str[65]; printf("ramchain blockhash.%s\n",bits256_str(str,hash2)); - sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"block\",\"coin\":\"%s\",\"hash\":\"%s\",\"txids\":1}",coinstr,str); - return(iguana_ramchain_glue(coin,"block",Currentjsonstr)); - } - } - else if ( strncmp(path,"txid/",strlen("txid/")) == 0 ) - { - decode_hex(hash2.bytes,sizeof(hash2),path + strlen("txid/")); - char str[65]; bits256_str(str,hash2); - sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"tx\",\"coin\":\"%s\",\"txid\":\"%s\"}",coinstr,str); - return(iguana_ramchain_glue(coin,"tx",Currentjsonstr)); - } - else if ( strncmp(path,"explore/",strlen("explore/")) == 0 ) - { - path += strlen("explore/"); - if ( coin != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"explore\",\"coin\":\"%s\",\"search\":\"%s\"}",coinstr,path); - } else sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"explore\",\"search\":\"%s\"}",path); - return(iguana_ramchain_glue(coin,"explore",Currentjsonstr)); - } - else if ( strncmp(path,"bundleinfo/",strlen("bundleinfo/")) == 0 ) - { - path += strlen("bundleinfo/"); - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"bundleinfo\",\"coin\":\"%s\",\"height\":%d}",coinstr,atoi(path)); - - } - else - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"%s\",\"coin\":\"%s\"}",path,coinstr); - return(iguana_ramchain_glue(coin,path,Currentjsonstr)); - } - } - else if ( strncmp(path,"/hash/",strlen("/hash/")) == 0 ) - { - path += strlen("/hash/"); - return(iguana_hashparse(path)); - } - else if ( strncmp(path,"/iguana/",strlen("/iguana/")) == 0 ) - { - strcpy(Currentjsonstr,path); - path += strlen("/iguana/"); - if ( strncmp(path,"setagent/",strlen("setagent/")) == 0 ) - { - path += strlen("setagent/"); - if ( strncmp(path,"ramchain",strlen("ramchain")) == 0 || strncmp(path,"iguana",strlen("iguana")) == 0 || strncmp(path,"InstantDEX",strlen("InstantDEX")) == 0 || strncmp(path,"pangea",strlen("pangea")) == 0 || strncmp(path,"PAX",strlen("PAX")) == 0 || strncmp(path,"ALL",strlen("ALL")) == 0 || strncmp(path,"jumblr",strlen("jumblr")) == 0 ) - { - if ( strncmp(Default_agent,path,strlen(path)) == 0 ) - { - strcpy(Default_agent,"ALL"); - return(clonestr("{\"result\":\"ALL agents selected\"}")); - } - strcpy(Default_agent,path); - if ( Default_agent[strlen(Default_agent)-1] == '/' ) - Default_agent[strlen(Default_agent)-1] = 0; - sprintf(buf,"{\"result\":\"agent selected\",\"name\":\"%s\"}",path); - return(clonestr(buf)); - } - return(clonestr("{\"error\":\"invalid agent specified\"}")); - } - else - { - if ( strncmp(path,"peers/",strlen("peers/")) == 0 ) - { - path += strlen("peers/"); - if ( coin != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"peers\",\"coin\":\"%s\"}",coinstr); - } else sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"peers\"}"); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"peers",json); - free_json(json); - return(retstr); - } - else if ( coin != 0 ) - { - if ( strncmp(path,"addnode/",strlen("addnode/")) == 0 ) - { - path += strlen("addnode/"); - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"addnode\",\"coin\":\"%s\",\"ipaddr\":\"%s\"}",coinstr,path); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"addnode",json); - free_json(json); - return(retstr); - } - else if ( strncmp(path,"nodestatus/",strlen("nodestatus/")) == 0 ) - { - path += strlen("nodestatus/"); - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"nodestatus\",\"coin\":\"%s\",\"ipaddr\":\"%s\"}",coinstr,path); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"nodestatus",json); - free_json(json); - return(retstr); - } - else if ( strncmp(path,"addcoin",strlen("addcoin")) == 0 ) - { - path += strlen("addcoin"); - iguana_coinset(buf,path); - if ( (coin= iguana_coinadd(buf)) != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"addcoin\",\"coin\":\"%s\"}",buf); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"addcoin",json); - free_json(json); - } - else retstr = clonestr("{\"error\":\"cant create coin\"}"); - return(retstr); - } - else if ( strncmp(path,"startcoin",strlen("startcoin")) == 0 ) - { - path += strlen("startcoin"); - iguana_coinset(buf,path); - if ( (coin= iguana_coinfind(buf)) != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"startcoin\",\"coin\":\"%s\"}",buf); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"startcoin",json); - free_json(json); - } - else retstr = clonestr("{\"error\":\"cant create coin\"}"); - return(retstr); - } - else if ( strncmp(path,"pausecoin",strlen("pausecoin")) == 0 ) - { - path += strlen("pausecoin"); - iguana_coinset(buf,path); - if ( (coin= iguana_coinfind(buf)) != 0 ) - { - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"pausecoin\",\"coin\":\"%s\"}",buf); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"pausecoin",json); - free_json(json); - } - else retstr = clonestr("{\"error\":\"cant create coin\"}"); - return(retstr); - } - else if ( strncmp(path,"maxpeers/",strlen("maxpeers/")) == 0 ) - { - path += strlen("maxpeers/"); - sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"maxpeers\",\"coin\":\"%s\",\"max\":%d}",coinstr,atoi(path)); - json = cJSON_Parse(Currentjsonstr); - retstr = iguana_coinjson(coin,"maxpeers",json); - free_json(json); - return(retstr); - } - return(clonestr("{\"result\":\"iguana method not found\"}")); - } - return(clonestr("{\"result\":\"iguana method needs coin\"}")); - } - } - else if ( strncmp(path,"/InstantDEX/",strlen("/InstantDEX/")) == 0 ) - { - double price,volume; char base[16],rel[16],exchange[16]; - path += strlen("/InstantDEX/"); - jsonstr[0] = 0; - if ( strncmp(path,"placebid/",strlen("placebid/")) == 0 ) - { - path += strlen("placebid/"); - if ( iguana_InstantDEX(jsonstr,path,"placebid") == 0 ) - return(clonestr("{\"error\":\"error with placebid parameters\"}")); - } - else if ( strncmp(path,"placeask/",strlen("placeask/")) == 0 ) - { - path += strlen("placeask/"); - if ( iguana_InstantDEX(jsonstr,path,"placeask") == 0 ) - return(clonestr("{\"error\":\"error with placeask parameters\"}")); - } - else if ( strncmp(path,"orderbook/",strlen("orderbook/")) == 0 ) - { - path += strlen("orderbook/"); - iguana_parsebidask(base,rel,exchange,&price,&volume,path); - if ( exchange[0] == 0 ) - strcpy(exchange,"active"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"base\":\"%s\",\"rel\":\"%s\",\"exchange\":\"%s\",\"allfields\":1}",base,rel,exchange); - } - else if ( strncmp(path,"orderstatus/",strlen("orderstatus/")) == 0 ) - { - path += strlen("orderstatus/"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"orderid\":\"%s\"}",path); - } - else if ( strncmp(path,"cancelorder/",strlen("cancelorder/")) == 0 ) - { - path += strlen("cancelorder/"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"orderid\":\"%s\"}",path); - } - else if ( strncmp(path,"balance/",strlen("balance/")) == 0 ) - { - path += strlen("balance/"); - iguana_parsebidask(base,rel,exchange,&price,&volume,path); - if ( path[0] != ' ' && path[0] != '/' ) - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"balance\",\"exchange\":\"%s\"}",path); - else sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"balance\"}"); - } - else if ( strncmp(path,"openorders",strlen("openorders")) == 0 ) - { - path += strlen("openorders"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"openorders\"}"); - } - else if ( strncmp(path,"tradehistory",strlen("tradehistory")) == 0 ) - { - path += strlen("tradehistory"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"tradehistory\"}"); - } - else if ( strncmp(path,"allorderbooks",strlen("allorderbooks")) == 0 ) - { - path += strlen("allorderbooks"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"allorderbooks\"}"); - } - else if ( strncmp(path,"allexchanges",strlen("allexchanges")) == 0 ) - { - path += strlen("allexchanges"); - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"allexchanges\"}"); - } - if ( jsonstr[0] != 0 ) - { - strcpy(Currentjsonstr,jsonstr); - return(clonestr(jsonstr)); - //return(InstantDEX(jsonstr,remoteaddr,localaccess)); - } - return(clonestr("{\"error\":\"unrecognized InstantDEX API call\"}")); - } - else if ( strncmp(path,"/pangea/",strlen("/pangea/")) == 0 ) - { - path += strlen("/pangea/"); - } - else if ( strncmp(path,"/jumblr/",strlen("/jumblr/")) == 0 ) - { - path += strlen("/jumblr/"); - } - else printf("no match to (%s)\n",path); - return(0); - } - - char *iguana_rpcparse(char *retbuf,int32_t bufsize,int32_t *postflagp,char *jsonstr) - { - cJSON *json = 0; int32_t i,n,localaccess,datalen,postflag = 0; - char *key,*reststr,*str,*retstr,remoteaddr[65],porturl[65],*data = 0,*value,*agent = "SuperNET"; - //printf("rpcparse.(%s)\n",jsonstr); - localaccess = 1; - if ( (str= strstr("Referer: ",jsonstr)) != 0 ) - { - for (i=0; str[i]!=' '&&str[i]!=0&&str[i]!='\n'&&str[i]!='\r'; i++) - remoteaddr[i] = str[i]; - remoteaddr[i] = 0; - } else strcpy(remoteaddr,"127.0.0.1"); // need to verify this - *postflagp = 0; - if ( strncmp("POST",jsonstr,4) == 0 ) - jsonstr += 6, *postflagp = postflag = 1; - else if ( strncmp("GET",jsonstr,3) == 0 ) - { - jsonstr += 4; - str = 0; - sprintf(porturl,"Referer: http://127.0.0.1:%u",IGUANA_RPCPORT); - if ( (str= iguana_htmlget(retbuf,bufsize,postflagp,jsonstr,remoteaddr,localaccess)) == 0 && (reststr= strstr(jsonstr,porturl)) != 0 ) - { - reststr += strlen(porturl); - str = iguana_htmlget(retbuf,bufsize,postflagp,reststr,remoteaddr,localaccess); - } - if ( str != 0 ) - { - if ( *postflagp == 0 ) - { - json = cJSON_CreateObject(); - jaddstr(json,"result",str); - if ( str != retbuf ) - free(str); - str = cJSON_Print(json); - free_json(json); - } - return(str); - } - jsonstr++; - } - else return(0); - n = (int32_t)strlen(jsonstr); - for (i=0; i 0 ) - { - jsonstr[i] = 0; - agent = jsonstr; - jsonstr += i; - } - jsonstr++; - json = cJSON_CreateObject(); - jaddstr(json,"agent",agent); - while ( 1 ) - { - n = (int32_t)strlen(jsonstr); - key = jsonstr; - value = 0; - for (i=0; i 0. && volume > 0. ) - { - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"exchange\":\"%s\",\"price\":\%0.8f,\"volume\":%0.8f}",method,base,rel,exchange,price,volume); - return(jsonstr); - } - else return(0); - } - return(0); - } - - void iguana_coinset(char *buf,char *path) - { - int32_t i; - if ( path[0] == '/' ) - path++; - for (i=0; i<8&&path[i]!=0&&path[i]!=' '&&path[i]!='/'; i++) - buf[i] = path[i]; - buf[i] = 0; - touppercase(buf); - } - - char *iguana_ramchain_glue(struct iguana_info *coin,char *method,char *jsonstr) - { - cJSON *json; char *retstr; - json = cJSON_Parse(jsonstr); - retstr = ramchain_parser(0,method,json); - free_json(json); - return(retstr); - } - - - void iguana_bundlestats(struct iguana_info *coin,char *str) - { - static bits256 zero; - int32_t i,n,issued,dispflag,bundlei,lefti,minrequests,missing,numbundles,numdone,numrecv,totalsaved,numhashes,numcached,numsaved,numemit,numactive,firstbundle,totalrecv = 0; struct iguana_peer *addr1; - bits256 hash2; struct iguana_bundle *bp; struct iguana_block *block; int64_t datasize,estsize = 0; - //iguana_chainextend(coin,iguana_blockfind(coin,coin->blocks.hwmchain)); - //if ( queue_size(&coin->blocksQ) == 0 ) - // iguana_blockQ(coin,0,-1,coin->blocks.hwmchain.hash2,0); - if ( 0 && queue_size(&coin->blocksQ) == 0 && queue_size(&coin->priorityQ) == 0 ) - { - for (i=0; ipeers.active[i].pending = 0; - } - dispflag = (rand() % 1000) == 0; - numbundles = numdone = numrecv = numhashes = numcached = totalsaved = numemit = numactive = 0; - firstbundle = -1; - issued = 0; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - minrequests = 777; - bp->numhashes = 0; - numbundles++; - numrecv = datasize = numsaved = 0; - missing = -1; - lefti = -1; - if ( bp->numrecv >= bp->n ) - numdone++; - else - { - for (bundlei=0; bundlein; bundlei++) - { - if ( bits256_nonz(bp->hashes[bundlei]) == 0 ) - { - lefti = bundlei; - if ( missing < 0 ) - missing = bundlei; - continue; - } - if ( (block= bp->blocks[bundlei]) != 0 || (block= iguana_blockfind(coin,bp->hashes[bundlei])) != 0 ) - { - bp->blocks[bundlei] = block; - if ( block->numrequests < minrequests ) - minrequests = block->numrequests; - if ( block->fpipbits != 0 ) - numsaved++; - if ( block->RO.recvlen != 0 ) - { - datasize += block->RO.recvlen; - if ( block->queued != 0 ) - numcached++; - numrecv++; - } - if ( block->queued == 0 && block->fpipbits == 0 ) - lefti = bundlei; - } - if ( firstbundle < 0 || firstbundle == bp->hdrsi ) - firstbundle = bp->hdrsi; - bp->numhashes++; - } - } - if ( (bp->minrequests= minrequests) == 100 ) - { - for (i=0; in; i++) - if ( (block= bp->blocks[i]) != 0 ) - block->numrequests = 1; - } - //printf("(%d %d) ",bp->hdrsi,minrequests); - numhashes += bp->numhashes; - bp->numrecv = numrecv; - bp->datasize = datasize; - if ( bp->emitfinish != 0 ) - { - numemit++; - if ( bp->emitfinish > coin->startutc && bp->purgetime == 0 && time(NULL) > bp->emitfinish+30 ) - { - char fname[1024]; int32_t hdrsi,m,j; uint32_t ipbits; - for (j=m=0; jpeers.active)/sizeof(*coin->peers.active); j++) - { - if ( (ipbits= coin->peers.active[j].ipbits) != 0 ) - { - if ( iguana_peerfname(coin,&hdrsi,"tmp",fname,ipbits,bp->hashes[0],zero,1) >= 0 ) - { - if ( OS_removefile(fname,0) > 0 ) - coin->peers.numfiles--, m++; - } - else printf("error removing.(%s)\n",fname); - } - } - //printf("purged hdrsi.%d m.%d\n",bp->hdrsi,m); - bp->purgetime = (uint32_t)time(NULL); - } - } - else if ( numsaved > 0 ) - { - bp->estsize = ((uint64_t)datasize * bp->n) / (numrecv+1); - estsize += bp->estsize; - if ( bp->numhashes == bp->n ) - numactive++; - if ( 0 && dispflag != 0 ) - { - if ( bp->numrecv < bp->n-1 ) - printf("(%d %d) ",i,bp->numrecv); - else printf("(%d -[%d]) ",i,lefti); - } - if ( (rand() % 100) == 0 && bp->numrecv > bp->n-2 && lefti >= 0 && lefti < bp->n ) - { - //printf("remainder issue %d:%d %s\n",bp->hdrsi,lefti,bits256_str(str,bp->hashes[lefti])); - //iguana_blockQ(coin,bp,lefti,bp->hashes[lefti],1); - } - if ( numsaved >= bp->n && bp->emitfinish == 0 ) - { - //printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT\n"); - bp->emitfinish = 1; - iguana_emitQ(coin,bp); - } - /*if ( numrecv > bp->n*.98 ) - { - if ( numrecv > bp->n-3 ) - bp->threshold = bp->avetime; - else bp->threshold = bp->avetime * 2; - } else*/ - bp->threshold = bp->avetime; - bp->metric = (bp->n - numsaved) / (bp->hdrsi + 1);//sqrt(abs((bp->n - bp->numrecv)) * sqrt(bp->estsize - bp->datasize)) / coin->chain->bundlesize; - } else bp->threshold = 10000., bp->metric = 0.; - totalrecv += numrecv; - totalsaved += numsaved; - } - } - coin->blocksrecv = totalrecv; - char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); - for (i=0; ipeers.active[i].usock >= 0 ) - p++; - diff = (int32_t)time(NULL) - coin->startutc; - difft.x = (t.x - coin->starttime.x), difft.millis = (t.millis - coin->starttime.millis); - tmp = (difft.millis * 1000000); - tmp %= 1000000000; - difft.millis = ((double)tmp / 1000000.); - sprintf(str,"N[%d] d.%d p.%d g.%d A.%d h.%d r.%d c.%d:%d s.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d",coin->bundlescount,numdone,coin->numpendings,numbundles,numactive,numhashes,coin->blocksrecv,coin->numcached,coin->cachefreed,totalsaved,coin->numemitted,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS); - //sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - if ( (rand() % 100) == 0 ) - printf("%s\n",str); - strcpy(coin->statusstr,str); - coin->activebundles = numactive; - coin->estsize = estsize; - coin->numrecv = totalrecv; - if ( 0 && queue_size(&coin->priorityQ) == 0 && coin->blocksrecv > coin->longestchain*.9 && coin->blocksrecv < coin->longestchain-1 ) - { - n = 0; - for (i=coin->lastsweep; ilongestchain-1; i++) - { - hash2 = iguana_blockhash(coin,i); - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( iguana_bundlefind(coin,&bp,&bundlei,hash2) == 0 || block->fpipbits == 0 ) - { - iguana_blockQ(coin,bp,bundlei,hash2,1); - n++; - printf("%d ",i); - if ( n > 1000 ) - break; - else if ( n < 10 && bp != 0 ) - iguana_bundleiclear(coin,bp,bundlei); - } - coin->lastsweep = i; - } - if ( i >= coin->longestchain-1 ) - coin->lastsweep = 0; - } - if ( n > 0 ) - printf(">>>>>>>>>>> issued.%d 90%% blocks\n",n); - } - else if ( 0 && strcmp(coin->symbol,"BTCD") == 0 && queue_size(&coin->blocksQ) == 0 ) - { - for (i=n=0; ilongestchain-1; i++) - { - hash2 = iguana_blockhash(coin,i); - if ( bits256_nonz(hash2) > 0 && (block= iguana_blockfind(coin,hash2)) != 0 && block->fpipbits == 0 ) - iguana_blockQ(coin,coin->bundles[i/coin->chain->bundlesize],i%coin->chain->bundlesize,hash2,0); - } - } - } - if ( 0 && coin->newramchain != 0 && now > coin->savedblocks+60 ) - { - char fname[512]; FILE *fp; - sprintf(fname,"blocks.%s",coin->symbol), OS_compatible_path(fname); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(coin->blocks.RO,sizeof(*coin->blocks.RO),coin->longestchain,fp) != coin->longestchain ) - printf("error saving blocks\n"); - else printf("%s saved\n",fname); - fclose(fp); - coin->savedblocks = (uint32_t)time(NULL); - } - } - - - /*struct iguana_block *iguana_blockrequest(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,uint32_t now,int32_t iamthreadsafe) - { - struct iguana_block *block = 0; - if( bp != 0 && bundlei >= 0 && bundlei < bp->n ) - block = bp->blocks[bundlei]; - if ( block == 0 && iamthreadsafe != 0 ) - block = iguana_blockfind(coin,hash2); - if ( block != 0 ) - { - //block->issued = now; - block->numrequests++; - } - return(block); - }*/ - if ( 0 && addr->msgcounts.verack > 0 && coin->bundlescount > 0 && req == 0 && addr->pendblocks < limit )//&& now > addr->lastpoll ) - { - if ( 1 )//strcmp("BTC",coin->symbol) != 0 ) - { - int32_t bundlei; - incr = coin->peers.numranked == 0 ? coin->MAXPEERS : coin->peers.numranked; - if ( (rand() % 100) < 50 ) - height = addr->rank * _IGUANA_MAXPENDING; - else if ( (rand() % 100) < 50 ) - height = addr->addrind + (addr->rank * (coin->longestchain - coin->blocks.hwmchain.height) / (coin->peers.numranked+1)); - else if ( (rand() % 100) < 50 ) - { - height = (addr->lastheight + 1); - if ( height >= coin->longestchain-coin->chain->bundlesize ) - height = addr->rank*incr*_IGUANA_MAXPENDING; - } - else - { - height = coin->longestchain - (rand() % incr) * 1000; - if ( height < 0 ) - height = coin->blocks.hwmchain.height; - } - for (; heightbundlescount*coin->chain->bundlesize; height+=incr) - { - if ( height > coin->longestchain ) - height = addr->rank*incr*_IGUANA_MAXPENDING; - if ( height > addr->lastheight ) - addr->lastheight = height; - if ( (bp= coin->bundles[height/coin->chain->bundlesize]) != 0 && bp->emitfinish == 0 ) - { - bundlei = (height % coin->chain->bundlesize); - if ( bundlei < bp->n && bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 && block->numrequests <= bp->minrequests && block->fpipbits == 0 && (bp->issued[bundlei] == 0 || now > bp->issued[bundlei]+13) ) - { - block->numrequests++; - bp->issued[bundlei] = (uint32_t)time(NULL);; - //if ( 0 && (rand() % 100) == 0 ) - printf("%s Send auto blockreq.%d [%d] minreq.%d\n",addr->ipaddr,bp->bundleheight+bundlei,block->numrequests,bp->minrequests); - iguana_sendblockreqPT(coin,addr,bp,bundlei,bp->hashes[bundlei],0); - return(1); - } - } - //if ( (rand() % 100) < 50 ) - // break; - } - } - else - { - //printf("%s lastpoll.%u %u\n",addr->ipaddr,addr->lastpoll,now); - addr->lastpoll = now; - for (i=n=0; ibundlescount; i++) - if ( coin->bundles[i] != 0 && coin->bundles[i]->emitfinish == 0 ) - n++; - if ( n >= coin->bundlescount-(coin->bundlescount>>3) || (addr->ipbits % 10) < 5 ) - refbundlei = (addr->ipbits % coin->bundlescount); - else - { - if ( n*2 < coin->bundlescount ) - { - for (i=refbundlei=0; iusock == coin->peers.active[i].usock ) - break; - if ( coin->peers.active[i].usock >= 0 ) - refbundlei++; - } - //printf("half done\n"); - } else refbundlei = ((addr->addrind*100) % coin->bundlescount); - } - for (i=0; ibundlescount; i++) - { - if ( (diff= (i - refbundlei)) < 0 ) - diff = -diff; - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 ) - { - metric = (1 + diff * ((addr->addrind&1) == 0 ? 1 : 1) * (1. + bp->metric));// / (i*((addr->addrind&1) != 0 ? 1 : i) + 1); - //printf("%f ",bp->metric); - if ( bestmetric < 0. || metric < bestmetric ) - bestmetric = metric, bestbp = bp; - } - } - if ( bestbp != 0 && bp->emitfinish == 0 ) - { - for (k=0; kbundlescount; k++) - { - i = (bestbp->hdrsi + k) % coin->bundlescount; - if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish != 0 ) - continue; - //printf("%.15f ref.%d addrind.%d bestbp.%d\n",bestmetric,refbundlei,addr->addrind,bp->hdrsi); - m = coin->chain->bundlesize; - if ( bp->n < m ) - m = bp->n; - j = (addr->addrind*3 + 0) % m; - val = (bp->threshold / 1000.); - for (r=0; r= m ) - j = 0; - if ( (block= bp->blocks[j]) != 0 && block->fpipbits == 0 && block->queued == 0 && block->numrequests <= bp->minrequests ) - { - block->numrequests++; - //block->issued = (uint32_t)time(NULL);; - //printf("%s Send auto blockreq.%d\n",addr->ipaddr,bp->bundleheight+j); - iguana_sendblockreqPT(coin,addr,bp,j,hash2,0); - return(1); - } - } - } - } - } - } - - - void iguana_bundlestats(struct iguana_info *coin,char *str) - { - int32_t i,n,dispflag,numrecv,done,numhashes,numcached,numsaved,numemit; int64_t estsize = 0; - struct iguana_bundle *bp; - dispflag = (rand() % 1000) == 0; - numrecv = numhashes = numcached = numsaved = numemit = done = 0; - memset(coin->rankedbps,0,sizeof(coin->rankedbps)); - for (i=n=0; ibundlescount; i++) - { - coin->rankedbps[n][1] = i; - if ( (bp= coin->bundles[i]) != 0 ) - { - estsize += iguana_bundlecalcs(coin,bp); - numhashes += bp->numhashes; - numcached += bp->numcached; - numrecv += bp->numrecv; - numsaved += bp->numsaved; - if ( bp->emitfinish != 0 ) - { - done++; - if ( bp->emitfinish > 1 ) - numemit++; - iguana_bundlepurge(coin,bp); - } - else if ( bp->metric > 0. ) - coin->rankedbps[n++][0] = bp->metric; - } - } - if ( n > 0 ) - { - struct iguana_peer *addr; uint32_t now; struct iguana_block *block; int32_t m,flag,origissue,j,issue,pend = 0; - flag = m = 0; - sortds(&coin->rankedbps[0][0],n,sizeof(coin->rankedbps[0])); - for (i=0; ipeers.numranked; i++) - { - if ( (addr= coin->peers.ranked[i]) != 0 && addr->msgcounts.verack > 0 ) - pend += addr->pendblocks; - } - if ( pend > 0 ) - { - origissue = (_IGUANA_MAXPENDING*coin->peers.numranked - pend); - issue = origissue; - now = (uint32_t)time(NULL); - for (i=0; ibundles[(int32_t)coin->rankedbps[i][1]]) != 0 && bp->emitfinish == 0 && bp->numhashes == bp->n ) - { - for (j=0; jn; j++) - { - if ( bits256_nonz(bp->hashes[j]) > 0 && (block= bp->blocks[j]) != 0 ) - { - //printf("j.%d bp.%d %d %x lag.%d\n",j,bp->minrequests,block->numrequests,block->fpipbits,now - bp->issued[j]); - if ( block->numrequests <= bp->minrequests+10 && block->fpipbits == 0 && (bp->issued[j] == 0 || now > bp->issued[j]+60) ) - { - printf("%d:%d.%d ",bp->hdrsi,j,block->numrequests); - flag++; - bp->issued[j] = now; - iguana_blockQ(coin,bp,j,bp->hashes[j],0); - if ( --issue < 0 ) - break; - } - } - } - } - } - /*for (i=0; irankedbps[i][0],coin->rankedbps[i][1],coin->bundles[(int32_t)coin->rankedbps[i][1]]->numrecv);*/ - if ( flag != 0 ) - printf("rem.%d issue.%d pend.%d | numranked.%d\n",n,origissue,pend,coin->peers.numranked); - } - } - coin->numremain = n; - coin->blocksrecv = numrecv; - char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); - for (i=0; ipeers.active[i].usock >= 0 ) - p++; - diff = (int32_t)time(NULL) - coin->startutc; - difft.x = (t.x - coin->starttime.x), difft.millis = (t.millis - coin->starttime.millis); - tmp = (difft.millis * 1000000); - tmp %= 1000000000; - difft.millis = ((double)tmp / 1000000.); - sprintf(str,"N[%d] Q.%d h.%d r.%d c.%d:%d:%d s.%d d.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d)",coin->bundlescount,coin->numbundlesQ,numhashes,coin->blocksrecv,coin->numcached,numcached,coin->cachefreed,numsaved,done,numemit,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - //sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - //if ( (rand() % 100) == 0 ) - static uint32_t lastdisp; - if ( time(NULL) > lastdisp+10 ) - { - printf("%s\n",str); - lastdisp = (uint32_t)time(NULL); - } - strcpy(coin->statusstr,str); - coin->estsize = estsize; - } - - char *iguana_bundledisp(struct iguana_info *coin,struct iguana_bundle *prevbp,struct iguana_bundle *bp,struct iguana_bundle *nextbp,int32_t m) - { - static char line[1024]; - line[0] = 0; - if ( bp == 0 ) - return(line); - if ( prevbp != 0 ) - { - if ( memcmp(prevbp->hashes[0].bytes,bp->prevbundlehash2.bytes,sizeof(bits256)) == 0 ) - { - if ( memcmp(prevbp->nextbundlehash2.bytes,bp->hashes[0].bytes,sizeof(bits256)) == 0 ) - sprintf(line+strlen(line),"<->"); - else sprintf(line+strlen(line),"<-"); - } - else if ( memcmp(prevbp->nextbundlehash2.bytes,bp->hashes[0].bytes,sizeof(bits256)) == 0 ) - sprintf(line+strlen(line),"->"); - } - sprintf(line+strlen(line),"(%d:%d).%d ",bp->hdrsi,m,bp->numhashes); - if ( nextbp != 0 ) - { - if ( memcmp(nextbp->hashes[0].bytes,bp->nextbundlehash2.bytes,sizeof(bits256)) == 0 ) - { - if ( memcmp(nextbp->prevbundlehash2.bytes,bp->hashes[0].bytes,sizeof(bits256)) == 0 ) - sprintf(line+strlen(line),"<->"); - else sprintf(line+strlen(line),"->"); - } - else if ( memcmp(nextbp->prevbundlehash2.bytes,bp->hashes[0].bytes,sizeof(bits256)) == 0 ) - sprintf(line+strlen(line),"<-"); - } - return(line); - } - if ( strcmp(method,"status") == 0 || strcmp(method,"getinfo") == 0 ) - return(iguana_getinfo(myinfo,coin)); - /* else if ( strcmp(method,"getbestblockhash") == 0 ) - return(iguana_getbestblockhash(myinfo,coin)); - else if ( strcmp(method,"getblockcount") == 0 ) - return(iguana_getblockcount(myinfo,coin)); - else if ( strcmp(method,"validatepubkey") == 0 ) - return(iguana_validatepubkey(myinfo,coin,jstr(json,"pubkey"))); - else if ( strcmp(method,"listtransactions") == 0 ) - return(iguana_listtransactions(myinfo,coin,jstr(json,"account"),juint(json,"count"),juint(json,"from"))); - else if ( strcmp(method,"getreceivedbyaddress") == 0 ) - return(iguana_getreceivedbyaddress(myinfo,coin,jstr(json,"address"),juint(json,"minconf"))); - else if ( strcmp(method,"listreceivedbyaddress") == 0 ) - return(iguana_listreceivedbyaddress(myinfo,coin,juint(json,"minconf"),juint(json,"includeempty"))); - else if ( strcmp(method,"listsinceblock") == 0 ) - return(iguana_listsinceblock(myinfo,coin,jbits256(json,"blockhash"),juint(json,"target"))); - else if ( strcmp(method,"getreceivedbyaccount") == 0 ) - return(iguana_getreceivedbyaccount(myinfo,coin,jstr(json,"account"),juint(json,"minconf"))); - else if ( strcmp(method,"listreceivedbyaccount") == 0 ) - return(iguana_listreceivedbyaccount(myinfo,coin,jstr(json,"account"),juint(json,"includeempty"))); - else if ( strcmp(method,"getnewaddress") == 0 ) - return(iguana_getnewaddress(myinfo,coin,jstr(json,"account"))); - else if ( strcmp(method,"makekeypair") == 0 ) - return(iguana_makekeypair(myinfo,coin)); - else if ( strcmp(method,"getaccountaddress") == 0 ) - return(iguana_getaccountaddress(myinfo,coin,jstr(json,"account"))); - else if ( strcmp(method,"setaccount") == 0 ) - return(iguana_setaccount(myinfo,coin,jstr(json,"address"),jstr(json,"account"))); - else if ( strcmp(method,"getaccount") == 0 ) - return(iguana_getaccount(myinfo,coin,jstr(json,"account"))); - else if ( strcmp(method,"getaddressesbyaccount") == 0 ) - return(iguana_getaddressesbyaccount(myinfo,coin,jstr(json,"account"))); - else if ( strcmp(method,"listaddressgroupings") == 0 ) - return(iguana_listaddressgroupings(myinfo,coin)); - else if ( strcmp(method,"getbalance") == 0 ) - return(iguana_getbalance(myinfo,coin,jstr(json,"account"),juint(json,"minconf"))); - else if ( strcmp(method,"listaccounts") == 0 ) - return(iguana_listaccounts(myinfo,coin,juint(json,"minconf"))); - else if ( strcmp(method,"dumpprivkey") == 0 ) - return(iguana_dumpprivkey(myinfo,coin,jstr(json,"address"))); - else if ( strcmp(method,"importprivkey") == 0 ) - return(iguana_importprivkey(myinfo,coin,jstr(json,"wip"))); - else if ( strcmp(method,"dumpwallet") == 0 ) - return(iguana_dumpwallet(myinfo,coin)); - else if ( strcmp(method,"importwallet") == 0 ) - return(iguana_importwallet(myinfo,coin,jstr(json,"wallet"))); - else if ( strcmp(method,"walletpassphrase") == 0 ) - return(iguana_walletpassphrase(myinfo,coin,jstr(json,"passphrase"),juint(json,"timeout"))); - else if ( strcmp(method,"walletpassphrasechange") == 0 ) - return(iguana_walletpassphrasechange(myinfo,coin,jstr(json,"oldpassphrase"),jstr(json,"newpassphrase"))); - else if ( strcmp(method,"walletlock") == 0 ) - return(iguana_walletlock(myinfo,coin)); - else if ( strcmp(method,"encryptwallet") == 0 ) - return(iguana_encryptwallet(myinfo,coin,jstr(json,"passphrase"))); - else if ( strcmp(method,"checkwallet") == 0 ) - return(iguana_checkwallet(myinfo,coin)); - else if ( strcmp(method,"repairwallet") == 0 ) - return(iguana_repairwallet(myinfo,coin)); - else if ( strcmp(method,"backupwallet") == 0 ) - return(iguana_backupwallet(myinfo,coin,jstr(json,"filename"))); - else if ( strcmp(method,"signmessage") == 0 ) - return(iguana_signmessage(myinfo,coin,jstr(json,"address"),jstr(json,"message"))); - else if ( strcmp(method,"verifymessage") == 0 ) - return(iguana_verifymessage(myinfo,coin,jstr(json,"address"),jstr(json,"sig"),jstr(json,"message"))); - else if ( strcmp(method,"listunspent") == 0 ) - return(iguana_listunspent(myinfo,coin,juint(json,"minconf"),juint(json,"maxconf"))); - else if ( strcmp(method,"lockunspent") == 0 ) - return(iguana_lockunspent(myinfo,coin,juint(json,"flag"),jobj(json,"array"))); - else if ( strcmp(method,"listlockunspent") == 0 ) - return(iguana_listlockunspent(myinfo,coin)); - else if ( strcmp(method,"gettxout") == 0 ) - return(iguana_gettxout(myinfo,coin,jbits256(json,"txid"),juint(json,"vout"),juint(json,"mempool"))); - else if ( strcmp(method,"gettxoutsetinfo") == 0 ) - return(iguana_gettxoutsetinfo(myinfo,coin)); - else if ( strcmp(method,"sendtoaddress") == 0 ) - return(iguana_sendtoaddress(myinfo,coin,jstr(json,"address"),jdouble(json,"amount"),jstr(json,"comment"),jstr(json,"comment2"))); - else if ( strcmp(method,"move") == 0 ) - return(iguana_move(myinfo,coin,jstr(json,"fromaccount"),jstr(json,"toaccount"),jdouble(json,"amount"),juint(json,"minconf"),jstr(json,"comment"))); - else if ( strcmp(method,"sendfrom") == 0 ) - return(iguana_sendfrom(myinfo,coin,jstr(json,"fromaccount"),jstr(json,"toaddress"),jdouble(json,"amount"),juint(json,"minconf"),jstr(json,"comment"),jstr(json,"comment2"))); - else if ( strcmp(method,"sendmany") == 0 ) - return(iguana_sendmany(myinfo,coin,jstr(json,"fromaccount"),jobj(json,"payments"),juint(json,"minconf"),jstr(json,"comment"))); - else if ( strcmp(method,"settxfee") == 0 ) - return(iguana_settxfee(myinfo,coin,jdouble(json,"amount"))); - else if ( strcmp(method,"getrawtransaction") == 0 ) - return(iguana_getrawtransaction(myinfo,coin,jbits256(json,"txid"),juint(json,"verbose"))); - else if ( strcmp(method,"createrawtransaction") == 0 ) - return(iguana_createrawtransaction(myinfo,coin,jobj(json,"vins"),jobj(json,"vouts"))); - else if ( strcmp(method,"decoderawtransaction") == 0 ) - return(iguana_decoderawtransaction(myinfo,coin,jstr(json,"rawtx"))); - else if ( strcmp(method,"decodescript") == 0 ) - return(iguana_decodescript(myinfo,coin,jstr(json,"script"))); - else if ( strcmp(method,"signrawtransaction") == 0 ) - return(iguana_signrawtransaction(myinfo,coin,jstr(json,"rawtx"),jobj(json,"vins"),jobj(json,"privkeys"))); - else if ( strcmp(method,"sendrawtransaction") == 0 ) - return(iguana_sendrawtransaction(myinfo,coin,jstr(json,"rawtx"))); - else if ( strcmp(method,"getrawchangeaddress") == 0 ) - return(iguana_getrawchangeaddress(myinfo,coin,jstr(json,"account"))); - */ - - char *iguana_jsoncheck(char *retstr,int32_t freeflag) - { - cJSON *retjson; char *errstr; - if ( retstr != 0 ) - { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( (errstr= jstr(retjson,"error")) == 0 ) - { - free_json(retjson); - return(retstr); - } - free_json(retjson); - } - if ( freeflag != 0 ) - free(retstr); - } - return(0); - } - - char *ramchain_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - char *symbol,*str,*retstr; int32_t height; cJSON *argjson,*obj; struct iguana_info *coin = 0; - /*{"agent":"ramchain","method":"block","coin":"BTCD","hash":""} - {"agent":"ramchain","method":"block","coin":"BTCD","height":345600} - {"agent":"ramchain","method":"tx","coin":"BTCD","txid":""} - {"agent":"ramchain","method":"rawtx","coin":"BTCD","txid":""} - {"agent":"ramchain","method":"balance","coin":"BTCD","address":""} - {"agent":"ramchain","method":"balance","coin":"BTCD","addrs":["",...]} - {"agent":"ramchain","method":"totalreceived","coin":"BTCD","address":""} - {"agent":"ramchain","method":"totalsent","coin":"BTCD","address":""} - {"agent":"ramchain","method":"unconfirmed","coin":"BTCD","address":""} - {"agent":"ramchain","method":"utxo","coin":"BTCD","address":""} - {"agent":"ramchain","method":"utxo","coin":"BTCD","addrs":["", "",...]} - {"agent":"ramchain","method":"txs","coin":"BTCD","block":""} - {"agent":"ramchain","method":"txs","coin":"BTCD","height":12345} - {"agent":"ramchain","method":"txs","coin":"BTCD","address":""} - {"agent":"ramchain","method":"status","coin":"BTCD"}*/ - - if ( (symbol= jstr(json,"coin")) != 0 && symbol[0] != 0 ) - { - if ( coin == 0 ) - coin = iguana_coinfind(symbol); - else if ( strcmp(symbol,coin->symbol) != 0 ) - return(clonestr("{\"error\":\"mismatched coin symbol\"}")); - } - if ( strcmp(method,"explore") == 0 ) - { - obj = jobj(json,"search"); - if ( coin != 0 && obj != 0 ) - { - argjson = cJSON_CreateObject(); - jaddstr(argjson,"agent","ramchain"); - jaddstr(argjson,"method","block"); - jaddnum(argjson,"txids",1); - if ( is_cJSON_Number(obj) != 0 ) - { - height = juint(obj,0); - jaddnum(argjson,"height",height); - } - else if ( (str= jstr(obj,0)) != 0 ) - jaddstr(argjson,"hash",str); - else return(clonestr("{\"error\":\"need number or string to search\"}")); - if ( (retstr= iguana_jsoncheck(ramchain_coinparser(myinfo,coin,"block",argjson),1)) != 0 ) - { - free_json(argjson); - return(retstr); - } - free_json(argjson); - argjson = cJSON_CreateObject(); - jaddstr(argjson,"agent","ramchain"); - jaddstr(argjson,"method","tx"); - jaddstr(argjson,"txid",str); - if ( (retstr= iguana_jsoncheck(ramchain_coinparser(myinfo,coin,"tx",argjson),1)) != 0 ) - { - free_json(argjson); - return(retstr); - } - free_json(argjson); - return(clonestr("{\"result\":\"explore search cant find height, blockhash, txid\"}")); - } - return(clonestr("{\"result\":\"explore no coin or search\"}")); - } - return(ramchain_coinparser(myinfo,coin,method,json)); - } - - /*int32_t pp_bind(char *hostname,uint16_t port) - { - int32_t opt; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); - struct hostent* hostent = gethostbyname(hostname); - if (hostent == NULL) { - PNACL_message("gethostbyname() returned error: %d", errno); - return -1; - } - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - memcpy(&addr.sin_addr.s_addr, hostent->h_addr_list[0], hostent->h_length); - int sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) { - printf("socket() failed: %s", strerror(errno)); - return -1; - } - opt = 1; - setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt)); - #ifdef __APPLE__ - setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); - #endif - //timeout.tv_sec = 0; - //timeout.tv_usec = 1000; - //setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); - int result = bind(sock, (struct sockaddr*)&addr, addrlen); - if (result != 0) { - printf("bind() failed: %s", strerror(errno)); - closesocket(sock); - return -1; - } - return(sock); - }*/ - /*if ( strcmp(agent,"ramchain") == 0 ) - return(ramchain_parser(myinfo,method,json,remoteaddr)); - else if ( strcmp(agent,"InstantDEX") == 0 ) - return(InstantDEX_parser(myinfo,method,json,remoteaddr)); - else if ( strcmp(agent,"pangea") == 0 ) - return(pangea_parser(myinfo,method,json,remoteaddr)); - else if ( strcmp(agent,"jumblr") == 0 ) - return(jumblr_parser(myinfo,method,json,remoteaddr)); - else if ( strcmp(agent,"hash") == 0 ) - return(hash_parser(myinfo,method,json,remoteaddr));*/ - - char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json) - { - int32_t i,max,retval,num=0; char buf[1024]; struct iguana_peer *addr; char *ipaddr; cJSON *retjson = 0; - //printf("iguana_coinjson(%s)\n",jprint(json,0)); - if ( strcmp(method,"peers") == 0 ) - return(jprint(iguana_peersjson(coin,0),1)); - else if ( strcmp(method,"getconnectioncount") == 0 ) - { - for (i=0; ipeers.active)/sizeof(*coin->peers.active); i++) - if ( coin->peers.active[i].usock >= 0 ) - num++; - sprintf(buf,"{\"result\":\"%d\"}",num); - return(clonestr(buf)); - } - else if ( strcmp(method,"addnode") == 0 ) - { - if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) - { - iguana_possible_peer(coin,ipaddr); - return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); - } - else if ( strcmp(method,"removenode") == 0 ) - { - if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) - { - for (i=0; ipeers.active[i].ipaddr,ipaddr) == 0 ) - { - coin->peers.active[i].rank = 0; - coin->peers.active[i].dead = (uint32_t)time(NULL); - return(clonestr("{\"result\":\"node marked as dead\"}")); - } - } - return(clonestr("{\"result\":\"node wasnt active\"}")); - } else return(clonestr("{\"error\":\"removenode needs ipaddr\"}")); - } - else if ( strcmp(method,"oneshot") == 0 ) - { - if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) - { - iguana_possible_peer(coin,ipaddr); - return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); - } - else if ( strcmp(method,"nodestatus") == 0 ) - { - if ( (ipaddr= jstr(json,"ipaddr")) != 0 ) - { - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers.active[i]; - if ( strcmp(addr->ipaddr,ipaddr) == 0 ) - return(jprint(iguana_peerjson(coin,addr),1)); - } - return(clonestr("{\"result\":\"nodestatus couldnt find ipaddr\"}")); - } else return(clonestr("{\"error\":\"nodestatus needs ipaddr\"}")); - } - else if ( strcmp(method,"maxpeers") == 0 ) - { - retjson = cJSON_CreateObject(); - if ( (max= juint(json,"max")) <= 0 ) - max = 1; - else if ( max > IGUANA_MAXPEERS ) - max = IGUANA_MAXPEERS; - if ( max > coin->MAXPEERS ) - { - for (i=max; iMAXPEERS; i++) - if ( (addr= coin->peers.ranked[i]) != 0 ) - addr->dead = 1; - } - coin->MAXPEERS = max; - jaddnum(retjson,"maxpeers",coin->MAXPEERS); - jaddstr(retjson,"coin",coin->symbol); - return(jprint(retjson,1)); - } - else if ( strcmp(method,"startcoin") == 0 ) - { - coin->active = 1; - return(clonestr("{\"result\":\"coin started\"}")); - } - else if ( strcmp(method,"pausecoin") == 0 ) - { - coin->active = 0; - return(clonestr("{\"result\":\"coin paused\"}")); - } - else if ( strcmp(method,"addcoin") == 0 ) - { - if ( (retval= iguana_launchcoin(coin->symbol,json)) > 0 ) - return(clonestr("{\"result\":\"coin added\"}")); - else if ( retval == 0 ) - return(clonestr("{\"result\":\"coin already there\"}")); - else return(clonestr("{\"error\":\"error adding coin\"}")); - } - return(clonestr("{\"error\":\"unhandled request\"}")); - } - - char *iguana_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - char *coinstr,SYM[16]; int32_t j,k,l,r,rr; struct iguana_peer *addr; - cJSON *retjson = 0,*array; int32_t i,n; struct iguana_info *coin; char *symbol; - printf("remoteaddr.(%s)\n",remoteaddr!=0?remoteaddr:"local"); - if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) // local (private) api - { - if ( strcmp(method,"list") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddistr(array,Coins[i]->symbol); - } - jadd(retjson,"coins",array); - return(jprint(retjson,1)); - } - else if ( strcmp(method,"allpeers") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddi(array,iguana_peersjson(Coins[i],0)); - } - jadd(retjson,"allpeers",array); - return(jprint(retjson,1)); - } - else - { - if ( (symbol= jstr(json,"coin")) != 0 && strlen(symbol) < sizeof(SYM)-1 ) - { - strcpy(SYM,symbol); - touppercase(SYM); - if ( (coin= iguana_coinfind(SYM)) == 0 ) - { - if ( strcmp(method,"addcoin") == 0 ) - coin = iguana_coinadd(SYM); - } - if ( coin != 0 ) - return(iguana_coinjson(coin,method,json)); - else return(clonestr("{\"error\":\"cant get coin info\"}")); - } - } - } - array = 0; - if ( strcmp(method,"getpeers") == 0 ) - { - if ( (coinstr= jstr(json,"coin")) != 0 ) - { - if ( (array= iguana_peersjson(iguana_coinfind(coinstr),1)) == 0 ) - return(clonestr("{\"error\":\"coin not found\"}")); - } - else - { - n = 0; - array = cJSON_CreateArray(); - r = rand(); - for (i=0; ipeers.active[l]; - if ( addr->usock >= 0 && addr->supernet != 0 ) - { - jaddistr(array,addr->ipaddr); - if ( ++n >= 64 ) - break; - } - } - } - } - } - if ( array != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","mypeers"); - jaddstr(retjson,"result","peers found"); - jadd(retjson,"peers",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no peers found\"}")); - } - else if ( strcmp(method,"mypeers") == 0 ) - { - printf("mypeers from %s\n",remoteaddr!=0?remoteaddr:"local"); - } - return(clonestr("{\"result\":\"stub processed generic json\"}")); - } - - - char *InstantDEX_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - return(clonestr("{\"error\":\"InstantDEX API is not yet\"}")); - } - - char *jumblr_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - return(clonestr("{\"error\":\"jumblr API is not yet\"}")); - } - - char *pangea_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) - { - return(clonestr("{\"error\":\"jumblr API is not yet\"}")); - } - - /* - char *hash_parser(struct supernet_info *myinfo,char *hashname,cJSON *json,char *remoteaddr) - { - int32_t i,len,iter,n; uint8_t databuf[512]; - char hexstr[1025],*password,*name,*msg; - typedef void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); - typedef char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message); - struct hashfunc_entry { char *name; hashfunc hashfunc; }; - struct hmacfunc_entry { char *name; hmacfunc hmacfunc; }; - struct hashfunc_entry hashes[] = { {"NXT",calc_NXTaddr}, {"curve25519",calc_curve25519_str }, {"base64_encode",calc_base64_encodestr}, {"base64_decode",calc_base64_decodestr}, {"crc32",calc_crc32str}, {"rmd160_sha256",rmd160ofsha256}, {"sha256_sha256",sha256_sha256}, {"sha256",vcalc_sha256}, {"sha512",calc_sha512}, {"sha384",calc_sha384}, {"sha224",calc_sha224}, {"rmd160",calc_rmd160}, {"rmd256",calc_rmd256}, {"rmd320",calc_rmd320}, {"rmd128",calc_rmd128}, {"sha1",calc_sha1}, {"md5",calc_md5str}, {"md2",calc_md2str}, {"md4",calc_md4str}, {"tiger",calc_tiger}, {"whirlpool",calc_whirlpool} }; - struct hmacfunc_entry hmacs[] = { {"hmac_sha256",hmac_sha256_str}, {"hmac_sha512",hmac_sha512_str}, {"hmac_sha384",hmac_sha384_str}, {"hmac_sha224",hmac_sha224_str}, {"hmac_rmd160",hmac_rmd160_str}, {"hmac_rmd256",hmac_rmd256_str}, {"hmac_rmd320",hmac_rmd320_str}, {"hmac_rmd128",hmac_rmd128_str}, {"hmac_sha1",hmac_sha1_str}, {"hmac_md52",hmac_md2_str},{"hmac_md4",hmac_md4_str},{"hmac_md5",hmac_md5_str}, {"hmac_tiger",hmac_tiger_str}, {"hmac_whirlpool",hmac_whirlpool_str} }; - if ( (msg= jstr(json,"message")) == 0 ) - return(clonestr("{\"error\":\"no message to hash\"}")); - if ( (password= jstr(json,"password")) == 0 || password[0] == 0 ) - password = " "; - n = (int32_t)sizeof(hashes)/sizeof(*hashes); - printf("msg.(%s) password.(%s)\n",msg,password!=0?password:""); - for (iter=0; iter<2; iter++) - { - for (i=0; imyaddr.pubkey)); - jdelete(json,"myip"); - jaddstr(json,"myip",myinfo->ipaddr); - return(json); - }*/ - - - void ramcoder_test(void *data,int64_t datalen) - { - static double totalin,totalout; - int32_t complen,bufsize = 1024 * 1024; uint8_t *buf; - buf = malloc(bufsize); - complen = ramcoder_compress(buf,bufsize,data,(int32_t)datalen); - totalin += datalen; - totalout += (complen >> 3); - printf("datalen.%d -> numbits.%d %d %.3f\n",(int32_t)datalen,complen,complen>>3,(double)totalin/totalout); - free(buf); - } - /*if ( (msgjson= cJSON_Parse(message)) != 0 ) - { - if ( (agent= jstr(msgjson,"agent")) != 0 && strcmp(agent,"SuperNET")) != 0 ) - { - safecopy(agentstr,agent,sizeof(agentstr)-1); - jdelete(msgjson,"agent"); - jaddstr(msgjson,"agent","SuperNET"); - jaddstr(msgjson,"destagent",agentstr); - } - if ( (method= jstr(msgjson,"method")) != 0 && strcmp(agent,"SuperNET")) != 0 ) - { - safecopy(methodstr,method,sizeof(methodstr)-1); - jdelete(msgjson,"method"); - jaddstr(msgjson,"method","DHTsend"); - jaddstr(msgjson,"destmethod",methodstr); - } - msgstr = jprint(msgjson,1); - msglen = (int32_t)strlen(msgstr); - hexstr = calloc(1,msglen*2+1); - flag = 1; - init_hexbytes_noT(hexstr,msgstr,msglen); - } - if ( flag != 0 ) - free(hexstr);*/ - //char str[65],str2[65],str3[65],str4[65]; - //int32_t i; for (i=0; i crc.%08x\n",bits256_str(str,myinfo->privkey),bits256_str(str2,destpub),bits256_str(str3,seed),bits256_str(str4,seed2),crc); - numbits = ramcoder_compress(&compressed[3],maxsize-3,serialized,len,seed2); - compressed[0] = (numbits & 0xff); - compressed[1] = ((numbits>>8) & 0xff); - compressed[2] = ((numbits>>16) & 0xff); - //printf("strlen.%d len.%d -> %s numbits.%d\n",(int32_t)strlen(jprint(json,0)),len,bits256_str(str,seed2),(int32_t)hconv_bitlen(numbits)); - if ( 0 ) - { - uint8_t space[9999]; - int32_t testlen = ramcoder_decompress(space,IGUANA_MAXPACKETSIZE,&compressed[3],numbits,seed2); - printf("len.%d -> testlen.%d cmp.%d\n",len,testlen,memcmp(space,serialized,testlen)); - int32_t i; for (i=0; i<3+hconv_bitlen(numbits); i++) - printf("%02x ",compressed[i]); - printf("complen.%d\n",i+3); - } - *complenp = (int32_t)hconv_bitlen(numbits) + 3; - - cJSON *SuperNET_bits2json(bits256 senderpub,bits256 sharedseed,uint8_t *serialized,uint8_t *space,int32_t datalen,int32_t iscompressed) - { - char destip[64],method[64],checkstr[5],agent[64],myipaddr[64],str[65],*hexmsg; uint64_t tag; - uint16_t apinum,checkc; uint32_t destipbits,myipbits; bits256 seed2; - int32_t numbits,dlen,iter,flag=0,len = 0; uint32_t crc,checkcrc; cJSON *json = cJSON_CreateObject(); - //int32_t i; for (i=0; i sizeof(crc) && dlen < IGUANA_MAXPACKETSIZE ) - { - crc = calc_crc32(0,&serialized[sizeof(crc)],dlen - sizeof(crc)); - iguana_rwnum(0,serialized,sizeof(checkcrc),&checkcrc); - //int32_t i; for (i=0; i %d != datalen.%d\n",numbits,(int32_t)hconv_bitlen(numbits)+3,datalen); - return(0); - } - } - if ( flag == 0 ) - return(0); - len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&crc); - len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&destipbits); - len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&myipbits); - len += iguana_rwbignum(0,&serialized[len],sizeof(bits256),senderpub.bytes); - len += iguana_rwnum(0,&serialized[len],sizeof(tag),&tag); - len += iguana_rwnum(0,&serialized[len],sizeof(checkc),&checkc); - len += iguana_rwnum(0,&serialized[len],sizeof(apinum),&apinum); - //printf("-> dest.%x myip.%x senderpub.%llx tag.%llu\n",destipbits,myipbits,(long long)senderpub.txid,(long long)tag); - if ( SuperNET_num2API(agent,method,apinum) >= 0 ) - { - jaddstr(json,"agent",agent); - jaddstr(json,"method",method); - expand_ipbits(destip,destipbits), jaddstr(json,"yourip",destip); - expand_ipbits(myipaddr,myipbits), jaddstr(json,"myip",myipaddr); - jaddstr(json,"mypub",bits256_str(str,senderpub)); - jadd64bits(json,"tag",tag); - init_hexbytes_noT(checkstr,(void *)&checkc,sizeof(checkc)); - jaddstr(json,"check",checkstr); - if ( len < datalen ) - { - printf("len %d vs %d datalen\n",len,datalen); - hexmsg = malloc(((datalen - len)<<1) + 1); - init_hexbytes_noT(hexmsg,&serialized[len],datalen - len); - printf("hex.(%s)\n",hexmsg); - jaddstr(json,"message",hexmsg); - free(hexmsg); - } - //printf("bits2json.(%s)\n",jprint(json,0)); - return(json); - } else printf("cant decode apinum.%d (%d.%d)\n",apinum,apinum>>5,apinum%0x1f); - return(0); - } - -#ifdef notyet - - int32_t SuperNET_serialize(int32_t reverse,bits256 *senderpubp,uint64_t *senderbitsp,bits256 *sigp,uint32_t *timestampp,uint64_t *destbitsp,uint8_t *origbuf) - { - uint8_t *buf = origbuf; long extra = sizeof(bits256) + sizeof(uint64_t) + sizeof(uint64_t); - buf += SuperNET_copybits(reverse,buf,(void *)destbitsp,sizeof(uint64_t)); - buf += SuperNET_copybits(reverse,buf,senderpubp->bytes,sizeof(bits256)); - buf += SuperNET_copybits(reverse,buf,(void *)senderbitsp,sizeof(uint64_t)); - buf += SuperNET_copybits(reverse,buf,(void *)timestampp,sizeof(uint32_t)), extra += sizeof(uint32_t); - if ( *senderbitsp != 0 ) - buf += SuperNET_copybits(reverse,buf,sigp->bytes,sizeof(bits256)), extra += sizeof(bits256); - else memset(sigp,0,sizeof(*sigp)); - if ( ((long)buf - (long)origbuf) != extra ) - { - printf("SuperNET_serialize: extrasize mismatch %ld vs %ld\n",((long)buf - (long)origbuf),extra); - } - return((int32_t)extra); - } - - int32_t SuperNET_decode(uint64_t *senderbitsp,bits256 *sigp,uint32_t *timestampp,uint64_t *destbitsp,uint8_t *str,uint8_t *cipher,int32_t *lenp,uint8_t *myprivkey) - { - bits256 srcpubkey; uint8_t *nonce; int i,hdrlen,err=0,len = *lenp; - hdrlen = SuperNET_serialize(1,&srcpubkey,senderbitsp,sigp,timestampp,destbitsp,cipher); - cipher += hdrlen, len -= hdrlen; - if ( *destbitsp != 0 && *senderbitsp != 0 ) - { - nonce = cipher; - cipher += crypto_box_NONCEBYTES, len -= crypto_box_NONCEBYTES; - printf("decode ptr.%p[%d]\n",cipher,len); - err = crypto_box_open((uint8_t *)str,cipher,len,nonce,srcpubkey.bytes,myprivkey); - for (i=0; i %d %d\n",len,len+crypto_box_ZEROBYTES,len + crypto_box_ZEROBYTES + crypto_box_NONCEBYTES); - memset(cipher,0,len+crypto_box_ZEROBYTES); - memset(buf,0,crypto_box_ZEROBYTES); - memcpy(buf+crypto_box_ZEROBYTES,str,len); - printf("cryptobox.%p[%d]\n",cipher,len+crypto_box_ZEROBYTES); - crypto_box(cipher,buf,len+crypto_box_ZEROBYTES,nonce,destpubkey.bytes,myprivkey.bytes); - hdrlen += crypto_box_NONCEBYTES + crypto_box_ZEROBYTES; - } - else memcpy(&cipher[hdrlen],str,len); - if ( totalsize != len+hdrlen ) - printf("unexpected totalsize.%d != len.%d + hdrlen.%d %d\n",totalsize,len,hdrlen,len+hdrlen); - *cipherlenp = totalsize; - { - bits256 checksig; uint32_t checkstamp; uint64_t checksender,checkbits; int32_t checklen; - checklen = totalsize; - if ( SuperNET_decode(&checksender,&checksig,&checkstamp,&checkbits,(void *)buf,ptr,&checklen,myprivkey.bytes) == 0 ) - { - printf("decoded %u %llx checklen.%d\n",checkstamp,(long long)checkbits,checklen); - } else printf("encrypt/decrypt error\n"); - printf("decoded %u %llx checklen.%d\n",checkstamp,(long long)checkbits,checklen); - } - free(buf); - return(origcipher); - } - - int32_t SuperNET_decrypt(bits256 *senderpubp,uint64_t *senderbitsp,uint32_t *timestampp,bits256 mypriv,bits256 mypub,uint8_t *dest,int32_t maxlen,uint8_t *src,int32_t len) - { - bits256 seed,sig,msgpriv; uint64_t my64bits,destbits,senderbits,sendertmp,desttmp; - uint8_t *buf; int32_t hdrlen,diff,newlen = -1; HUFF H,*hp = &H; struct acct777_sig checksig; - *senderbitsp = 0; - my64bits = acct777_nxt64bits(mypub); - if ( (buf = calloc(1,maxlen)) == 0 ) - { - printf("SuperNET_decrypt cant allocate maxlen.%d\n",maxlen); - return(-1); - } - hdrlen = SuperNET_serialize(1,senderpubp,&senderbits,&sig,timestampp,&destbits,src); - if ( destbits != 0 && my64bits != destbits && destbits != acct777_nxt64bits(GENESIS_PUBKEY) ) - { - free(buf); - printf("SuperNET_decrypt received destination packet.%llu when my64bits.%llu len.%d\n",(long long)destbits,(long long)my64bits,len); - return(-1); - } - if ( memcmp(mypub.bytes,senderpubp->bytes,sizeof(mypub)) == 0 ) - { - if ( destbits != 0 ) - printf("SuperNET: got my own msg?\n"); - } - printf("decrypt(%d) destbits.%llu my64.%llu mypriv.%llx mypub.%llx senderpub.%llx shared.%llx\n",len,(long long)destbits,(long long)my64bits,(long long)mypriv.txid,(long long)mypub.txid,(long long)senderpubp->txid,(long long)seed.txid); - if ( SuperNET_decode(&sendertmp,&sig,timestampp,&desttmp,(void *)buf,src,&len,mypriv.bytes) == 0 ) - { - if ( (diff= (*timestampp - (uint32_t)time(NULL))) < 0 ) - diff = -diff; - if ( 1 && diff > SUPERNET_MAXTIMEDIFF ) - printf("diff.%d > %d %u vs %u\n",diff,SUPERNET_MAXTIMEDIFF,*timestampp,(uint32_t)time(NULL)); - else - { - if ( 0 ) - { - memset(seed.bytes,0,sizeof(seed)); - //for (i='0'; i<='9'; i++) - // SETBIT(seed.bytes,i); - //for (i='a'; i<='f'; i++) - // SETBIT(seed.bytes,i); - _init_HUFF(hp,len,buf), hp->endpos = (len << 3); - newlen = ramcoder_decoder(0,1,dest,maxlen,hp,&seed); - } - else memcpy(dest,buf,len), newlen = len; - //printf("T%d decrypted newlen.%d\n",threadid,newlen); - if ( senderbits != 0 && senderpubp->txid != 0 ) - { - *senderbitsp = senderbits; - if ( destbits == 0 ) - msgpriv = GENESIS_PRIVKEY; - else msgpriv = mypriv; - acct777_sign(&checksig,msgpriv,*senderpubp,*timestampp,dest,newlen); - if ( memcmp(checksig.sigbits.bytes,&sig,sizeof(checksig.sigbits)) != 0 ) - { - printf("sender.%llu sig %llx compare error vs %llx using sig->pub from %llu, broadcast.%d len.%d -> newlen.%d\n",(long long)senderbits,(long long)sig.txid,(long long)checksig.sigbits.txid,(long long)senderbits,destbits == 0,len,newlen); - //free(buf); - //return(0); - } //else printf("SIG VERIFIED newlen.%d (%llu -> %llu)\n",newlen,(long long)senderbits,(long long)destbits); - } - } - } else printf("%llu: SuperNET_decrypt skip: decode_cipher error len.%d -> newlen.%d\n",(long long)acct777_nxt64bits(mypub),len,newlen); - free(buf); - return(newlen); - } - - int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis) - { - int32_t cipherlen,datalen,qlen=-1; bits256 seed; uint8_t *cipher; uint64_t destbits; struct acct777_sig sig; HUFF H,*hp = &H; - if ( destpub.txid != 0 ) - destbits = acct777_nxt64bits(destpub); - else - { - destbits = 0; - destpub = GENESIS_PUBKEY; - } - printf("SuperNET_sendmsg dest.%llu destpub.%llx priv.%llx pub.%llx\n",(long long)destbits,(long long)destpub.txid,(long long)mypriv.txid,(long long)mypub.txid); - memset(&sig,0,sizeof(sig)); - if ( mypub.txid == 0 || mypriv.txid == 0 ) - mypriv = curve25519_keypair(&mypub), sig.timestamp = (uint32_t)time(NULL); - else acct777_sign(&sig,mypriv,destpub,(uint32_t)time(NULL),msg,len); - if ( 0 ) - { - memset(seed.bytes,0,sizeof(seed)); - //seed = addr->sharedseed; - data = calloc(1,len*2); - _init_HUFF(hp,len*2,data); - /*for (i='0'; i<='9'; i++) - SETBIT(seed.bytes,i); - for (i='a'; i<='f'; i++) - SETBIT(seed.bytes,i);*/ - ramcoder_encoder(0,1,msg,len,hp,0,&seed); - datalen = (int32_t)hconv_bitlen(hp->bitoffset); - } - else data = msg, datalen = len; - if ( (cipher= SuperNET_encode(&cipherlen,data,datalen,destpub,mypriv,mypub,sig.signer64bits,sig.sigbits,sig.timestamp)) != 0 ) - { - qlen = iguana_queue_send(coin,addr,delaymillis,cipher,"SuperNETb",cipherlen,0,0); - free(cipher); - } - return(qlen); - } -#endif /*memset(senderpub.bytes,0,sizeof(senderpub)); -if ( iscompressed != 0 ) -{ -if ( (len= SuperNET_decrypt(&senderpub,&senderbits,×tamp,mypriv,mypub,space,IGUANA_MAXPACKETSIZE,serialized,datalen)) > 1 && len < IGUANA_MAXPACKETSIZE ) -{ -if ( memcmp(senderpub.bytes,addr->pubkey.bytes,sizeof(senderpub)) != 0 ) -{ -printf("got new pubkey.(%s) for %s\n",bits256_str(str,senderpub),addr->ipaddr); -addr->pubkey = senderpub; -addr->sharedseed = SuperNET_sharedseed(mypriv,senderpub); -} -serialized = space; -datalen = len; -len = 0; -} else printf("decrypt error len.%d origlen.%d\n",len,datalen); -}*/ - - - bits256 testprivkey(int32_t selector) - { - bits256 privkey; - memset(privkey.bytes,0,sizeof(privkey.bytes)); - privkey.bytes[15] = selector; - return(privkey); - } - - bits256 testpubkey(int32_t selector) - { - return(acct777_pubkey(testprivkey(selector))); - } - - /*char *pangea_univ(uint8_t *mypriv,cJSON *json) - { - char *addrtypes[][3] = { {"BTC","0","80"}, {"LTC","48"}, {"BTCD","60","bc"}, {"DOGE","30"}, {"VRC","70"}, {"OPAL","115"}, {"BITS","25"} }; - char *wipstr,*coin,*coinaddr,pubkeystr[67],rsaddr[64],destaddr[64],wifbuf[128]; uint8_t priv[32],pub[33],addrtype; int32_t i; - uint64_t nxt64bits; cJSON *retjson,*item; - PNACL_message("inside rosetta\n"); - if ( (coin= jstr(json,"coin")) != 0 ) - { - if ( (wipstr= jstr(json,"wif")) != 0 || (wipstr= jstr(json,"wip")) != 0 ) - { - PNACL_message("got wip.(%s)\n",wipstr); - btc_wip2priv(priv,wipstr); - } - else if ( (coinaddr= jstr(json,"addr")) != 0 ) - { - if ( getprivkey(priv,coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"cant get privkey\"}")); - } - } else memcpy(priv,mypriv,sizeof(priv)); - btc_priv2pub(pub,priv); - init_hexbytes_noT(pubkeystr,pub,33); - PNACL_message("pubkey.%s\n",pubkeystr); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"btcpubkey",pubkeystr); - for (i=0; inumaddrs; i++) - if ( sp->addrs[i] == pm ) - break; - if ( i == sp->numaddrs ) - return(clonestr("{\"error\":\"specified pm destination not at table\"}")); - } else i = -1; - pangea_sendcmd(hex,&sp->tp->hn,"chat",i,(void *)chatstr,(int32_t)strlen(chatstr)+1,pangea_ind(sp,sp->myslot),-1); - return(clonestr("{\"result\":\"chat message sent\"}")); - } - - /*void _pangea_chat(uint64_t senderbits,void *buf,int32_t len,int32_t senderind) - { - PNACL_message(">>>>>>>>>>> CHAT FROM.%d %llu: (%s)\n",senderind,(long long)senderbits,(char *)buf); - } - - else if ( strcmp(methodstr,"newtable") == 0 ) - retstr = pangea_newtable(juint(json,"threadid"),json,plugin->nxt64bits,*(bits256 *)plugin->mypriv,*(bits256 *)plugin->mypub,plugin->transport,plugin->ipaddr,plugin->pangeaport,juint(json,"minbuyin"),juint(json,"maxbuyin"),juint(json,"rakemillis")); - else if ( sender == 0 || sender[0] == 0 ) - { - if ( strcmp(methodstr,"start") == 0 ) - { - strcpy(retbuf,"{\"result\":\"start issued\"}"); - if ( (base= jstr(json,"base")) != 0 ) - { - if ( (maxplayers= juint(json,"maxplayers")) < 2 ) - maxplayers = 2; - else if ( maxplayers > CARDS777_MAXPLAYERS ) - maxplayers = CARDS777_MAXPLAYERS; - if ( jstr(json,"resubmit") == 0 ) - sprintf(retbuf,"{\"resubmit\":[{\"method\":\"start\"}, {\"bigblind\":\"%llu\"}, {\"ante\":\"%llu\"}, {\"rakemillis\":\"%u\"}, {\"maxplayers\":%d}, {\"minbuyin\":%d}, {\"maxbuyin\":%d}],\"pluginrequest\":\"SuperNET\",\"plugin\":\"InstantDEX\",\"method\":\"orderbook\",\"base\":\"%s\",\"exchange\":\"pangea\",\"allfields\":1}",(long long)j64bits(json,"bigblind"),(long long)j64bits(json,"ante"),juint(json,"rakemillis"),maxplayers,juint(json,"minbuyin"),juint(json,"maxbuyin"),jstr(json,"base")!=0?jstr(json,"base"):"BTCD"); - else if ( pangea_start(plugin,retbuf,base,0,j64bits(json,"bigblind"),j64bits(json,"ante"),juint(json,"rakemillis"),maxplayers,juint(json,"minbuyin"),juint(json,"maxbuyin"),json) < 0 ) - ; - } else strcpy(retbuf,"{\"error\":\"no base specified\"}"); - } - else if ( strcmp(methodstr,"status") == 0 ) - retstr = pangea_status(plugin->nxt64bits,j64bits(json,"tableid"),json); - } - - int32_t pangea_unzbuf(uint8_t *buf,char *hexstr,int32_t len) - { - int32_t i,j,len2; - for (len2=i=0; iclient->H.pubdata, sp = dp->table; - priv = hn->client->H.privdata; - if ( hn == 0 || hn->client == 0 || dp == 0 || priv == 0 ) - { - if ( Debuglevel > 2 ) - PNACL_message("pangea_poll: null hn.%p %p dp.%p priv.%p\n",hn,hn!=0?hn->client:0,dp,priv); - return(-1); - } - maxlen = (int32_t)(sizeof(bits256) * dp->N*dp->N*dp->numcards); - if ( (buf= malloc(maxlen)) == 0 ) - { - PNACL_message("pangea_poll: null buf\n"); - return(-1); - } - if ( dp != 0 && priv != 0 && (jsonstr= queue_dequeue(&hn->client->H.Q,1)) != 0 ) - { - //pangea_neworder(dp,dp->table,0,0); - //PNACL_message("player.%d GOT.(%s)\n",hn->client->H.slot,jsonstr); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - *senderbitsp = j64bits(json,"sender"); - if ( (senderind= juint(json,"myind")) < 0 || senderind >= dp->N ) - { - PNACL_message("pangea_poll: illegal senderind.%d cardi.%d turni.%d (%s)\n",senderind,juint(json,"cardi"),juint(json,"turni"),jsonstr); - goto cleanup; - } - *timestampp = juint(json,"timestamp"); - hn->client->H.state = juint(json,"state"); - len = juint(json,"n"); - cmdstr = jstr(json,"cmd"); - if ( sp->myind < 0 ) - { - // check for reactivation command - goto cleanup; - } - if ( cmdstr != 0 && strcmp(cmdstr,"preflop") == 0 ) - { - if ( (hexstr= jstr(json,"data")) != 0 ) - len = pangea_unzbuf(buf,hexstr,len); - } - else if ( (hexstr= jstr(json,"data")) != 0 && strlen(hexstr) == (len<<1) ) - { - if ( len > maxlen ) - { - PNACL_message("len too big for pangea_poll\n"); - goto cleanup; - } - decode_hex(buf,len,hexstr); - } else if ( hexstr != 0 ) - PNACL_message("len.%d vs hexlen.%ld (%s)\n",len,(long)(strlen(hexstr)>>1),hexstr); - if ( cmdstr != 0 ) - { - if ( strcmp(cmdstr,"newhand") == 0 ) - pangea_newhand(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"ping") == 0 ) - pangea_ping(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"gotdeck") == 0 ) - pangea_gotdeck(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"ready") == 0 ) - pangea_ready(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"encoded") == 0 ) - pangea_encoded(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"final") == 0 ) - pangea_final(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"addfunds") == 0 ) - pangea_addfunds(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"preflop") == 0 ) - pangea_preflop(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"decoded") == 0 ) - pangea_decoded(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"card") == 0 ) - pangea_card(hn,json,dp,priv,buf,len,juint(json,"cardi"),senderind); - else if ( strcmp(cmdstr,"facedown") == 0 ) - pangea_facedown(hn,json,dp,priv,buf,len,juint(json,"cardi"),senderind); - else if ( strcmp(cmdstr,"faceup") == 0 ) - pangea_faceup(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"turn") == 0 ) - pangea_turn(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"confirmturn") == 0 ) - pangea_confirmturn(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"chat") == 0 ) - pangea_chat(*senderbitsp,buf,len,senderind); - else if ( strcmp(cmdstr,"action") == 0 ) - pangea_action(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"showdown") == 0 ) - pangea_showdown(hn,json,dp,priv,buf,len,senderind); - else if ( strcmp(cmdstr,"summary") == 0 ) - pangea_gotsummary(hn,json,dp,priv,buf,len,senderind); - } - cleanup: - free_json(json); - } - free_queueitem(jsonstr); - } - free(buf); - return(hn->client->H.state); - } - - char *Pangea_bypass(uint64_t my64bits,uint8_t myprivkey[32],cJSON *json) - { - char *methodstr,*retstr = 0; - if ( (methodstr= jstr(json,"method")) != 0 ) - { - if ( strcmp(methodstr,"turn") == 0 ) - retstr = _pangea_input(my64bits,j64bits(json,"tableid"),json); - else if ( strcmp(methodstr,"status") == 0 ) - retstr = _pangea_status(my64bits,j64bits(json,"tableid"),json); - else if ( strcmp(methodstr,"mode") == 0 ) - retstr = _pangea_mode(my64bits,j64bits(json,"tableid"),json); - else if ( strcmp(methodstr,"buyin") == 0 ) - retstr = _pangea_buyin(my64bits,j64bits(json,"tableid"),json); - else if ( strcmp(methodstr,"history") == 0 ) - retstr = _pangea_history(my64bits,j64bits(json,"tableid"),json); - } - return(retstr); - }*/ - - /*sprintf(hex,"{\"cmd\":\"%s\",\"turni\":%d,\"myslot\":%d,\"myind\":%d,\"cardi\":%d,\"dest\":%d,\"sender\":\"%llu\",\"n\":%u,%s\"data\":\"",cmdstr,turni,priv->myslot,pangea_ind(dp->table,priv->myslot),cardi,destplayer,(long long)myinfo->myaddr.nxt64bits,(long)time(NULL),datalen,hoststr); - n = (int32_t)strlen(hex); - if ( strcmp(cmdstr,"preflop") == 0 ) - { - memcpy(&hex[n],data,datalen+1); - hexlen = (int32_t)strlen(hex)+1; - } - else - if ( data != 0 && datalen != 0 ) - init_hexbytes_noT(&hex[n],data,datalen); - strcat(hex,"\"}"); - if ( (json= cJSON_Parse(hex)) == 0 ) - { - PNACL_message("error creating json\n"); - return; - } - free_json(json); - hexlen = (int32_t)strlen(hex)+1;*/ - - - int32_t pangea_hexmsg(struct supernet_info *myinfo,struct pangea_msghdr *pm,int32_t len) - { - cJSON *argjson; char *method; bits256 tablehash; struct table_info *tp; int32_t flag = 0; - int32_t datalen; uint8_t *serialized; uint8_t tmp[sizeof(pm->sig)]; - acct777_rwsig(0,(void *)&pm->sig,(void *)tmp); - memcpy(&pm->sig,tmp,sizeof(pm->sig)); - datalen = len - (int32_t)sizeof(pm->sig); - serialized = (void *)((long)pm + sizeof(pm->sig)); - if ( pangea_validate(pm,acct777_msgprivkey(serialized,datalen),pm->sig.pubkey) == 0 ) - { - flag++; - iguana_rwbignum(0,pm->tablehash.bytes,sizeof(bits256),tablehash.bytes); - pm->tablehash = tablehash; - printf("<<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(pm->sig),(long)serialized-(long)pm,datalen,pm->sig.timestamp,pm->sig.allocsize,(char *)pm->serialized,serialized[datalen-1]); - if ( serialized[datalen-1] == 0 && (argjson= cJSON_Parse((char *)pm->serialized)) != 0 ) - { - tablehash = jbits256(argjson,"subhash"); - if ( (method= jstr(argjson,"cmd")) != 0 ) - { - if ( strcmp(method,"lobby") == 0 ) - { - //categoryhash = jbits256(argjson,"categoryhash"); - } - else if ( strcmp(method,"host") == 0 ) - { - if ( (tp= pangea_table(tablehash)) != 0 ) - { - pangea_gamecreate(&tp->G,pm->sig.timestamp,pm->tablehash,argjson); - tp->G.creatorbits = pm->sig.signer64bits; - } - char str[65],str2[65]; printf("new game detected (%s) vs (%s)\n",bits256_str(str,tablehash),bits256_str(str2,pm->tablehash)); - } - else if ( strcmp(method,"join") == 0 ) - { - printf("JOIN.(%s)\n",jprint(argjson,0)); - } - } - free_json(argjson); - } else printf("ERROR >>>>>>> (%s) cant parse\n",(char *)pm->serialized); - } - else - { - int32_t i; char str[65],str2[65]; - for (i=0; isig),(long)serialized-(long)pm,datalen,bits256_str(str,acct777_msgprivkey(serialized,datalen)),bits256_str(str2,pm->sig.pubkey)); - } - return(flag); - } - - if ( 0 && buf[len-1] == 0 && (argjson= cJSON_Parse((char *)buf)) != 0 ) - { - printf("RESULT.(%s)\n",jprint(argjson,0)); - free_json(argjson); - } - else if ( 0 ) - { - char *method; bits256 tablehash; struct table_info *tp; - int32_t datalen; uint8_t *serialized; uint8_t tmp[sizeof(pm->sig)]; - decode_hex(buf,len,result); - pm = (struct pangea_msghdr *)buf; - acct777_rwsig(0,(void *)&pm->sig,(void *)tmp); - memcpy(&pm->sig,tmp,sizeof(pm->sig)); - datalen = len - (int32_t)sizeof(pm->sig); - serialized = (void *)((long)pm + sizeof(pm->sig)); - char str[65]; printf("OLD pm.%p len.%d serialized.%p datalen.%d crc.%u %s\n",pm,len,serialized,datalen,calc_crc32(0,(void *)pm,len),bits256_str(str,pm->sig.pubkey)); - if ( pangea_validate(pm,acct777_msgprivkey(serialized,datalen),pm->sig.pubkey) == 0 ) - { - iguana_rwbignum(0,pm->tablehash.bytes,sizeof(bits256),tablehash.bytes); - pm->tablehash = tablehash; - printf("<<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(pm->sig),(long)serialized-(long)pm,datalen,pm->sig.timestamp,pm->sig.allocsize,(char *)pm->serialized,serialized[datalen-1]); - if ( serialized[datalen-1] == 0 && (argjson= cJSON_Parse((char *)pm->serialized)) != 0 ) - { - tablehash = jbits256(argjson,"subhash"); - if ( (method= jstr(argjson,"cmd")) != 0 ) - { - if ( strcmp(method,"lobby") == 0 ) - { - //categoryhash = jbits256(argjson,"categoryhash"); - } - else if ( strcmp(method,"host") == 0 ) - { - if ( (tp= pangea_table(tablehash)) != 0 ) - { - pangea_gamecreate(&tp->G,pm->sig.timestamp,pm->tablehash,argjson); - tp->G.creatorbits = pm->sig.signer64bits; - } - char str[65],str2[65]; printf("new game detected (%s) vs (%s)\n",bits256_str(str,tablehash),bits256_str(str2,pm->tablehash)); - } - else if ( strcmp(method,"join") == 0 ) - { - printf("JOIN.(%s)\n",jprint(argjson,0)); - } - } - free_json(argjson); - } else printf("ERROR >>>>>>> (%s) cant parse\n",(char *)pm->serialized); - } - else - { - int32_t i; char str[65],str2[65]; - for (i=0; isig),(long)serialized-(long)pm,datalen,bits256_str(str,acct777_msgprivkey(serialized,datalen)),bits256_str(str2,pm->sig.pubkey)); - } - } - while ( 0 && (retstr= SuperNET_gethexmsg(IGUANA_CALLARGS,"pangea",0)) != 0 ) - { - flag = 0; - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - - if ( (result= jstr(retjson,"result")) != 0 ) - { - len = (int32_t)strlen(result); - if ( is_hexstr(result,len) > 0 ) - { - len >>= 1; - buf = malloc(len); - decode_hex(buf,len,result); - lag = pangea_hexmsg(myinfo,(struct pangea_msghdr *)buf,len,remoteaddr); - } - } - free_json(retjson); - } - free(retstr); - if ( flag == 0 ) - break; - } - uint8_t hex[1024]; char hashstr[65]; bits256 hash,hash2; long l = strlen("c0fbdbb600b7000000010000000000000000000000000000000000000000000000000000000000000000000058283b1b3ea5ad73f9aabc571dedd442d06e4ad8b3867a4f495acacd93a1698a54405408ffff1e0fb2780001010100004000085401540000000000000000000000000000000000000000000000000000000000000000ffffffff0424ffff1d000401541c7568202c2034655320703032343131203a323030303a20304d47ff54ffff01ff0000000000000000000000000000fb00b6c0afdb0000060000009900a46df6901a15d0d99d5dc9efda9b44582b1d3c83a60d119d64e7c7d7000a3300a678b550a606416b7a09510b2f3f89ee88971b7164c6f93fce76bb6d620b5f0c0880ff540fff001ede04010300010000805e54080001000000000000000000000000000000000000000000000000000000000000ff00ffff03ff0151ff02ffff01ff00005d8a45780163761914a96651e5e6e52dfa8d18cb0c673000dcae95f23923ac88000000000000"); - l>>=1; - decode_hex(hex,(int32_t)l,"c0fbdbb600b7000000010000000000000000000000000000000000000000000000000000000000000000000058283b1b3ea5ad73f9aabc571dedd442d06e4ad8b3867a4f495acacd93a1698a54405408ffff1e0fb2780001010100004000085401540000000000000000000000000000000000000000000000000000000000000000ffffffff0424ffff1d000401541c7568202c2034655320703032343131203a323030303a20304d47ff54ffff01ff0000000000000000000000000000fb00b6c0afdb0000060000009900a46df6901a15d0d99d5dc9efda9b44582b1d3c83a60d119d64e7c7d7000a3300a678b550a606416b7a09510b2f3f89ee88971b7164c6f93fce76bb6d620b5f0c0880ff540fff001ede04010300010000805e54080001000000000000000000000000000000000000000000000000000000000000ff00ffff03ff0151ff02ffff01ff00005d8a45780163761914a96651e5e6e52dfa8d18cb0c673000dcae95f23923ac88000000000000"); - vcalc_sha256(0,hash.bytes,hex+24,(int32_t)l-24); - vcalc_sha256(hashstr,hash2.bytes,hash.bytes,sizeof(hash)); - printf("ghash.(%s)\n",hashstr); - - getchar(); - - - bits256 issue_getpubkey(int32_t *haspubkeyp,char *acct) - { - cJSON *json; bits256 pubkey; char cmd[4096],*jsonstr; struct destbuf pubkeystr; - sprintf(cmd,"%s?requestType=getAccountPublicKey&account=%s",NXTAPIURL,acct); - jsonstr = issue_curl(cmd); - pubkeystr.buf[0] = 0; - if ( haspubkeyp != 0 ) - *haspubkeyp = 0; - memset(&pubkey,0,sizeof(pubkey)); - if ( jsonstr != 0 ) - { - printf("PUBKEYRPC.(%s)\n",jsonstr); - if ( (json = cJSON_Parse(jsonstr)) != 0 ) - { - copy_cJSON(&pubkeystr,cJSON_GetObjectItem(json,"publicKey")); - free_json(json); - if ( strlen(pubkeystr.buf) == sizeof(pubkey)*2 ) - { - if ( haspubkeyp != 0 ) - *haspubkeyp = 1; - decode_hex(pubkey.bytes,sizeof(pubkey),pubkeystr.buf); - } - } - free(jsonstr); - } - return(pubkey); - } - - int32_t iguana_rwtxbytes(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_msgtx *tx) - { - int32_t i,len = 0; char str[65],str2[65],txidstr[65]; uint32_t numvins,numvouts; bits256 txid; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->version),&tx->version); - if ( coin->chain->hastimestamp != 0 ) - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->timestamp),&tx->timestamp); - numvins = tx->tx_in, numvouts = tx->tx_out; - len += iguana_rwvarint32(rwflag,&serialized[len],&numvins); - for (i=0; ivins[i]); - if ( len > maxlen ) - return(0); - len += iguana_rwvarint32(rwflag,&serialized[len],&numvouts); - for (i=0; ivouts[i]); - if ( len > maxlen ) - return(0); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->lock_time),&tx->lock_time); - txid = bits256_doublesha256(txidstr,serialized,len); - if ( rwflag != 0 ) - tx->txid = txid; - else *txidp = txid; - if ( bits256_nonz(*txidp) > 0 && memcmp(txidp,tx->txid.bytes,sizeof(*txidp)) != 0 ) - { - printf("iguana_rwtxbytes.rw%d: txid.%s vs %s\n",rwflag,bits256_str(str,tx->txid),bits256_str(str2,*txidp)); - return(0); - } - return(len); - } - - void pktest() - { - bits256 p,pub; uint8_t *data,*pubkey,sig[128],*sigptr; struct bp_key key; size_t pubk_len; - int32_t s,v,v2,v4=-99,v3=-99,datalen; uint32_t siglen; EC_KEY *KEY; - //bp_key_init(&key); - // bp_key_generate(&key); - OS_randombytes(p.bytes,sizeof(p)); - - data = (uint8_t *)"hello", datalen = (int32_t)strlen("hello"); - //s = bp_sign(key.k,data,datalen,(void **)&sigptr,&siglen); - //sigptr = sig; - //siglen = iguana_sig(sig,sizeof(sig),data,datalen,p); - //const unsigned char *privkey; - //bp_privkey_set(&key,p.bytes,sizeof(p)); - //bp_pubkey_get(&key,(void **)&pubkey,&pubk_len); - //memcpy(pub.bytes,pubkey+1,sizeof(pub)); - KEY = bitcoin_privkeyset(&pub,p); - siglen = bitcoin_sign(sig,sizeof(sig),data,datalen,p); - s = siglen > 0; - // char str[65]; printf("siglen.%d pk_len.%ld %s\n",siglen,pubk_len,bits256_str(str,*(bits256 *)(pubkey+1))); - - //s = ECDSA_sign(0,data,datalen,sig,&siglen,KEY); - v2 = bp_verify(KEY,data,datalen,sig,siglen); - //bp_pubkey_get(&key,(void **)&pubkey,&pubk_len); - //bp_key_init(&key); - - v3 = bitcoin_verify(sig,siglen,data,datalen,pub); - //v = iguana_ver(sig,siglen,data,datalen,pub); - printf("s.%d siglen.%d v2.%d v3.%d v4.%d\n",s,siglen,v2,v3,v4); - getchar(); - } - http://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx - //msgtx->vins[i].scriptlen = scriptlen; - //printf("VINI.%d (%s)\n",vini,jprint(bitcoin_txjson(coin,msgtx),1)); - //decode_hex(privkey.bytes,sizeof(privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725"); - //printf("privkey.%s\n",bits256_str(str,privkey)); - //EC_KEY *KEY = bitcoin_privkeyset(&pkey,privkey); - char *refstr = "01000000\ - 01\ - eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2\ - 01000000\ - 8c\ - 4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6\ - ffffffff\ - 01\ - 605af40500000000\ - 19\ - 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\ - 00000000"; - - char *iguana_txcreate(struct iguana_info *coin,uint8_t *space,int32_t maxlen,char *jsonstr) - { - struct iguana_txid T; struct iguana_msgvin *vins,*vin; struct iguana_msgvout *vouts,*vout; - char *redeemstr; - cJSON *array,*json,*item,*retjson = 0; bits256 scriptPubKey; int32_t i,numvins,numvouts,len = 0; - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - memset(&T,0,sizeof(T)); - if ( (T.version= juint(json,"version")) == 0 ) - T.version = 1; - if ( (T.locktime= juint(json,"locktime")) == 0 ) - T.locktime = 0xffffffff; - vins = (struct iguana_msgvin *)&space[len]; - if ( (array= jarray(&numvins,json,"vins")) != 0 ) - { - len += sizeof(*vins) * numvins; - memset(vins,0,sizeof(*vins) * numvins); - //struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; }; - for (i=0; iprev_hash = jbits256(item,"txid"); - vin->prev_vout = juint(item,"vout"); - vin->sequence = juint(item,"sequence"); - scriptPubKey = jbits256(item,"scriptPubKey"); - if ( bits256_nonz(scriptPubKey) > 0 ) - { - if ( (redeemstr= jstr(item,"redeemScript")) == 0 ) - { - vin->scriptlen = (int32_t)strlen(redeemstr); - if ( (vin->scriptlen & 1) != 0 ) - { - free_json(json); - return(clonestr("{\"error\":\"odd redeemScript length\"}")); - } - vin->scriptlen >>= 1; - vin->script = &space[len], len += vin->scriptlen; - } - } - } - } - vouts = (struct iguana_msgvout *)&space[len]; - if ( (array= jarray(&numvouts,json,"vouts")) != 0 ) - { - len += sizeof(*vouts) * numvouts; - memset(vouts,0,sizeof(*vouts) * numvouts); - //struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; - for (i=0; i 0 ) - { - - } - free_json(json); - } - if ( retjson == 0 ) - retjson = cJSON_Parse("{\"error\":\"couldnt create transaction\"}"); - return(jprint(retjson,1)); - } - - /* - if ( bp_key_init(&key) != 0 && bp_key_secret_set(&key,privkey,32) != 0 ) - { - if ( (T= calloc(1,sizeof(*T))) == 0 ) - return(0); - *T = *refT; vin = &T->inputs[redeemi]; - for (i=0; inuminputs; i++) - strcpy(T->inputs[i].sigs,"00"); - strcpy(vin->sigs,redeemscript); - vin->sequence = (uint32_t)-1; - T->nlocktime = 0; - //disp_cointx(&T); - emit_cointx(&hash2,data,sizeof(data),T,oldtx_format,SIGHASH_ALL); - //printf("HASH2.(%llx)\n",(long long)hash2.txid); - if ( bp_sign(&key,hash2.bytes,sizeof(hash2),&sig,&siglen) != 0 ) - { - memcpy(sigbuf,sig,siglen); - sigbuf[siglen++] = SIGHASH_ALL; - init_hexbytes_noT(sigs[privkeyind],sigbuf,(int32_t)siglen); - strcpy(vin->sigs,"00"); - for (i=0; isigs + strlen(vin->sigs),"%02x%s",(int32_t)strlen(sigs[i])>>1,sigs[i]); - //printf("(%s).%ld ",sigs[i],strlen(sigs[i])); - } - } - len = (int32_t)(strlen(redeemscript)/2); - if ( len >= 0xfd ) - sprintf(&vin->sigs[strlen(vin->sigs)],"4d%02x%02x",len & 0xff,(len >> 8) & 0xff); - else sprintf(&vin->sigs[strlen(vin->sigs)],"4c%02x",len); - sprintf(&vin->sigs[strlen(vin->sigs)],"%s",redeemscript); - //printf("after A.(%s) othersig.(%s) siglen.%02lx -> (%s)\n",hexstr,othersig != 0 ? othersig : "",siglen,vin->sigs); - //printf("vinsigs.(%s) %ld\n",vin->sigs,strlen(vin->sigs)); - _emit_cointx(hexstr,sizeof(hexstr),T,oldtx_format); - //disp_cointx(&T); - free(T); - return(clonestr(hexstr)); - } - */ - - - /*static char *validateretstr(struct iguana_info *coin,char *coinaddr) - { - char *retstr,buf[512]; cJSON *json; - if ( iguana_addressvalidate(coin,coinaddr) < 0 ) - return(clonestr("{\"error\":\"invalid coin address\"}")); - sprintf(buf,"{\"agent\":\"ramchain\",\"coin\":\"%s\",\"method\":\"validate\",\"address\":\"%s\"}",coin->symbol,coinaddr); - if ( (json= cJSON_Parse(buf)) != 0 ) - retstr = ramchain_coinparser(coin,"validate",json); - else return(clonestr("{\"error\":\"internal error, couldnt parse validate\"}")); - free_json(json); - return(retstr); - } - - static char *validatepubkey(RPCARGS) - { - char *pubkeystr,coinaddr[128]; cJSON *retjson; - retjson = cJSON_CreateObject(); - if ( params[0] != 0 && (pubkeystr= jstr(params[0],0)) != 0 ) - { - if ( btc_coinaddr(coinaddr,coin->chain->pubval,pubkeystr) == 0 ) - return(validateretstr(coin,coinaddr)); - return(clonestr("{\"error\":\"cant convert pubkey\"}")); - } - return(clonestr("{\"error\":\"need pubkey\"}")); - }*/ - - int32_t bitcoin_outputscript(struct iguana_info *coin,char *pubkeys[],int32_t *scriptlenp,uint8_t *scriptspace,bits256 txid,int32_t vout) - { - struct iguana_txid T,*tx; int32_t height,numpubs = 1; char asmstr[8192]; struct iguana_msgvout v; - if ( 0 ) - { - *scriptlenp = 0; - if ( (tx= iguana_txidfind(coin,&height,&T,txid)) != 0 ) - { - *scriptlenp = iguana_voutset(coin,scriptspace,asmstr,height,&v,tx,vout); - return(numpubs); - } - } - //char *str = "2103506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974ac"; - char *str = "76a914010966776006953d5567439e5e39f86a0d273bee88ac"; - *scriptlenp = (int32_t)strlen(str) >> 1; - decode_hex(scriptspace,*scriptlenp,str); - //pubkeys[0] = clonestr("03506a52e95cdfbb9d17d702af6259ba7de8b7a604007999e0266edbf6e4bb6974"); - pubkeys[0] = clonestr("0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6"); - return(numpubs); - } - - cJSON *bitcoin_txjson(struct iguana_info *coin,struct iguana_msgtx *msgtx,struct vin_info *V) - { - char vpnstr[2]; int32_t n; uint8_t *serialized; bits256 txid; cJSON *json = cJSON_CreateObject(); - vpnstr[0] = 0; - serialized = malloc(IGUANA_MAXPACKETSIZE); - if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&txid,vpnstr,V)) < 0 ) - { - printf("bitcoin_txtest: n.%d\n",n); - } - free(serialized); - return(json); - } - - /*{ - for (i=0; inuminputs; i++) - strcpy(T->inputs[i].sigs,"00"); - strcpy(vin->sigs,redeemscript); - vin->sequence = (uint32_t)-1; - T->nlocktime = 0; - //disp_cointx(&T); - emit_cointx(&hash2,data,sizeof(data),T,oldtx_format,SIGHASH_ALL); - //printf("HASH2.(%llx)\n",(long long)hash2.txid); - if ( bp_sign(&key,hash2.bytes,sizeof(hash2),&sig,&siglen) != 0 ) - { - memcpy(sigbuf,sig,siglen); - sigbuf[siglen++] = SIGHASH_ALL; - init_hexbytes_noT(sigs[privkeyind],sigbuf,(int32_t)siglen); - strcpy(vin->sigs,"00"); - for (i=0; isigs + strlen(vin->sigs),"%02x%s",(int32_t)strlen(sigs[i])>>1,sigs[i]); - //printf("(%s).%ld ",sigs[i],strlen(sigs[i])); - } - } - len = (int32_t)(strlen(redeemscript)/2); - if ( len >= 0xfd ) - sprintf(&vin->sigs[strlen(vin->sigs)],"4d%02x%02x",len & 0xff,(len >> 8) & 0xff); - else sprintf(&vin->sigs[strlen(vin->sigs)],"4c%02x",len); - sprintf(&vin->sigs[strlen(vin->sigs)],"%s",redeemscript); - //printf("after A.(%s) othersig.(%s) siglen.%02lx -> (%s)\n",hexstr,othersig != 0 ? othersig : "",siglen,vin->sigs); - //printf("vinsigs.(%s) %ld\n",vin->sigs,strlen(vin->sigs)); - _emit_cointx(hexstr,sizeof(hexstr),T,oldtx_format); - //disp_cointx(&T); - free(T); - return(clonestr(hexstr)); - } - else printf("error signing\n"); - free(T); - }*/ - - /*cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V) - { - struct iguana_msgvin vin; struct iguana_msgvout vout; int32_t i; char asmstr[512],str[65]; uint8_t space[8192]; - cJSON *vouts,*vins,*json; - json = cJSON_CreateObject(); - jaddstr(json,"txid",bits256_str(str,tx->txid)); - if ( height >= 0 ) - jaddnum(json,"height",height); - jaddnum(json,"version",tx->version); - jaddnum(json,"timestamp",tx->timestamp); - jaddnum(json,"locktime",tx->locktime); - vins = cJSON_CreateArray(); - vouts = cJSON_CreateArray(); - for (i=0; inumvouts; i++) - { - iguana_voutset(coin,space,asmstr,height,&vout,tx,i); - jaddi(vouts,iguana_voutjson(coin,&vout,i,tx->txid)); - } - jadd(json,"vout",vouts); - for (i=0; inumvins; i++) - { - iguana_vinset(coin,height,&vin,tx,i); - jaddi(vins,iguana_vinjson(coin,&vin,V != 0 ? &V[i] : 0)); - } - jadd(json,"vin",vins); - return(json); - }*/ - - /* - if ( strcmp(cmdstr+3,"offer") == 0 ) - { - - } - if ( (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. ) - { - // sends NXT assetid, volume and desired - if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 ) - assetbits = NXT_ASSETID; - else if ( is_decimalstr(base) > 0 ) - assetbits = calc_nxt64bits(base); - if ( assetbits != 0 ) - { - nextcmd = INSTANTDEX_REQUEST; - nextcmdstr = "request"; - } - } - } - else if ( strncmp(cmdstr,"ALT",3) == 0 ) - { - if ( (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. ) - { - // sends NXT assetid, volume and desired - if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 ) - assetbits = NXT_ASSETID; - else if ( is_decimalstr(base) > 0 ) - assetbits = calc_nxt64bits(base); - if ( assetbits != 0 ) - { - nextcmd = INSTANTDEX_REQUEST; - nextcmdstr = "request"; - } - } - } - else if ( strncmp(cmdstr,"NXT",3) == 0 ) - { - if ( (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. ) - { - // sends NXT assetid, volume and desired - if ( strcmp(base,"NXT") == 0 || strcmp(base,"nxt") == 0 ) - assetbits = NXT_ASSETID; - else if ( is_decimalstr(base) > 0 ) - assetbits = calc_nxt64bits(base); - if ( assetbits != 0 ) - { - nextcmd = INSTANTDEX_REQUEST; - nextcmdstr = "request"; - } - } - } - { - - } - - if ( strcmp(cmdstr,"request") == 0 ) - { - // request: - // other node sends (othercoin, othercoinaddr, otherNXT and reftx that expires before phasedtx) - if ( (strcmp(rel,"BTC") == 0 || strcmp(base,"BTC") == 0) && (price= instantdex_acceptable(myinfo,0,refstr,base,rel,volume)) > 0. ) - { - //aveprice = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&totalvol,base,rel,volume,argjson); - set_NXTtx(myinfo,&feeT,assetbits,SATOSHIDEN*3,calc_nxt64bits(INSTANTDEX_ACCT),-1); - if ( (feejson= gen_NXT_tx_json(myinfo,fullhash,&feeT,0,1.)) != 0 ) - free_json(feejson); - nextcmd = INSTANTDEX_PROPOSE; - nextcmdstr = "proposal"; - othercoinaddr = myinfo->myaddr.BTC; - otherNXTaddr = myinfo->myaddr.NXTADDR; - } - } - else - { - if ( strcmp(cmdstr,"proposal") == 0 ) - { - // proposal: - // NXT node submits phasedtx that refers to it, but it wont confirm - nextcmd = INSTANTDEX_ACCEPT; - nextcmdstr = "accept"; - message = ""; - //instantdex_phasetxsubmit(refstr); - } - else if ( strcmp(cmdstr,"accept") == 0 ) - { - // accept: - // other node verifies unconfirmed has phasedtx and broadcasts cltv, also to NXT node, releases trigger - nextcmd = INSTANTDEX_CONFIRM; - nextcmdstr = "confirm"; - message = ""; - //instantdex_phasedtxverify(); - //instantdex_cltvbroadcast(); - //instantdex_releasetrigger(); - } - else if ( strcmp(cmdstr,"confirm") == 0 ) - { - // confirm: - // NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey - // BTC* node approves phased tx with onetimepubkey - //instantdex_cltvverify(); - //instantdex_phasetxapprove(); - return(clonestr("{\"error\":\"trade confirmed\"}")); - } - } - if ( nextcmd != 0 && (newjson= InstantDEX_argjson(refstr,message,othercoinaddr,otherNXTaddr,nextcmd,duration,flags)) != 0 ) - { - jaddnum(newjson,"price",price); - jaddnum(newjson,"volume",volume); - return(instantdex_sendcmd(myinfo,newjson,nextcmdstr,myinfo->ipaddr,INSTANTDEX_HOPS)); - } - } - return(clonestr("{\"error\":\"request needs argjson\"}")); - } - num = 0; - depth = 30; - request = jstr(argjson,"request"); - base = jstr(argjson,"base"); - rel = jstr(argjson,"rel"); - refstr = jstr(argjson,"refstr"); - volume = jdouble(argjson,"volume"); - duration = juint(argjson,"duration"); - flags = juint(argjson,"flags"); - nextcmd = 0; - nextcmdstr = message = ""; - - */ - if ( A->orderid != orderid ) - { - printf("orderid mismatch %llu vs %llu\n",(long long)orderid,(long long)A->orderid); - return(clonestr("{\"error\":\"instantdex_BTCswap orderid mismatch\"}")); - } - if ( senderaddr == 0 || strcmp(A->A.base,base) != 0 || strcmp(A->A.rel,"BTC") != 0 ) - { - printf("senderaddr.%p base.(%s vs %s) rel.(%s vs %s)\n",senderaddr,A->A.base,base,A->A.rel,"BTC"); - return(clonestr("{\"error\":\"instantdex_BTCswap base or rel mismatch\"}")); - } - { - printf("satoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)instantdex_relsatoshis(A->A.price64,A->A.basevolume64)); - return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}")); - } - if ( othersatoshis != A->A.basevolume64 ) - { - printf("othersatoshis mismatch %llu vs %llu\n",(long long)satoshis,(long long)A->A.basevolume64); - return(clonestr("{\"error\":\"instantdex_BTCswap satoshis mismatch\"}")); - } - - /*TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,BTCoffer,othercoin,otherassetid,maxprice,othervolume) - { - if ( remoteaddr == 0 ) - return(instantdex_btcoffer(myinfo,exchanges777_find("bitcoin"),othercoin[0] != 0 ? othercoin : otherassetid,othervolume,maxprice)); - else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); - } - - STRING_AND_TWO_DOUBLES(InstantDEX,ALToffer,basecoin,minprice,basevolume) - { - int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *str; struct instantdex_accept A; - if ( remoteaddr == 0 ) - { - if ( iguana_coinfind(basecoin) == 0 ) - return(clonestr("{\"error\":\"InstantDEX basecoin is not active, need to addcoin\"}")); - instantdex_acceptset(&A,basecoin,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits); - argjson = instantdex_acceptsendjson(&A); - if ( minprice > 0. ) - { - if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,basecoin,"BTC",minprice,basevolume)) != 0 ) - free(str); - } - return(instantdex_sendcmd(myinfo,argjson,"ALToffer",myinfo->ipaddr,hops)); - } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); - } - - STRING_AND_TWO_DOUBLES(InstantDEX,NXToffer,assetid,minprice,basevolume) - { - int32_t hops = INSTANTDEX_HOPS; cJSON *argjson; char *base,*str; struct instantdex_accept A; - if ( remoteaddr == 0 ) - { - if ( assetid == 0 || assetid[0] == 0 || strcmp(assetid,"0") == 0 || strcmp(assetid,"NXT") == 0 || strcmp(assetid,"nxt") == 0 ) - base = "NXT"; - else if ( is_decimalstr(assetid) <= 0 ) - return(clonestr("{\"error\":\"InstantDEX NXToffer illegal assetid\"}")); - else base = assetid; - instantdex_acceptset(&A,base,"BTC",INSTANTDEX_OFFERDURATION,0,1,minprice,basevolume,myinfo->myaddr.nxt64bits); - argjson = instantdex_acceptsendjson(&A); - if ( minprice > 0. ) - { - if ( (str= InstantDEX_minaccept(IGUANA_CALLARGS,base,"BTC",minprice,basevolume)) != 0 ) - free(str); - } - return(instantdex_sendcmd(myinfo,argjson,"NXToffer",myinfo->ipaddr,hops)); - } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); - } - */ - if ( sendprivs != 0 ) - { - printf("sendprivs.%d\n",sendprivs); - if ( swap->otherschoosei < 0 ) - printf("instantdex_newjson otherschoosei < 0 when sendprivs != 0\n"); - else - { - if ( privs == 0 && (privs= calloc(1,sizeof(*swap->privkeys))) == 0 ) - printf("instantdex_newjson couldnt allocate hex\n"); - else if ( hexstr == 0 && (hexstr= malloc(sizeof(*swap->privkeys) * 2 + 1)) == 0 ) - printf("instantdex_newjson couldnt allocate hexstr\n"); - else - { - memcpy(privs,swap->privkeys,sizeof(*swap->privkeys)); - memset(privs[swap->otherschoosei].bytes,0,sizeof(*privs)); - for (i=0; iprivkeys)/sizeof(*swap->privkeys); i++) - { - iguana_rwbignum(1,serialized,sizeof(privs[i]),privs[i].bytes); - memcpy(privs[i].bytes,serialized,sizeof(privs[i])); - } - } - } - } - - /*cJSON *instantdex_acceptsendjson(struct instantdex_accept *ap) - { - cJSON *json = cJSON_CreateObject(); - jaddstr(json,"b",ap->offer.base); - jaddstr(json,"r",ap->offer.rel); - jaddnum(json,"n",ap->offer.nonce); - jaddnum(json,"e",ap->offer.expiration); - jaddnum(json,"s",ap->offer.myside); - jaddnum(json,"d",ap->offer.acceptdir); - jadd64bits(json,"p",ap->offer.price64); - jadd64bits(json,"v",ap->offer.basevolume64); - jadd64bits(json,"o",ap->offer.offer64); - jadd64bits(json,"id",ap->orderid); - return(json); - }*/ - if ( A->offer.price64 != 0 ) - { - if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,A->orderid,"*","*",1)) != 0 ) - { - swap->state++; - A->info = swap; - printf(">>>>>>>>>> PENDING ORDER %llu\n",(long long)A->orderid); - } - } - if ( ap == 0 ) - { - printf("couldnt find accept?? dir.%d orderid.%llu\n",ap->offer.acceptdir,(long long)A->orderid); - free(swap); - return(clonestr("{\"error\":\"couldnt find order just created\"}")); - } - if ( strncmp(cmdstr,"BTC",3) == 0 ) - else if ( strncmp(cmdstr,"NXT",3) == 0 ) - retstr = instantdex_NXTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); - else if ( strncmp(cmdstr,"ALT",3) == 0 ) - retstr = instantdex_ALTswap(myinfo,exchange,&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); - else if ( strncmp(cmdstr,"PAX",3) == 0 ) - retstr = instantdex_PAXswap(myinfo,exchanges777_find("PAX"),&A,cmdstr+3,msg,argjson,remoteaddr,signerbits,serdata,datalen); - else return(clonestr("{\"error\":\"unrecognized atomic swap family\"}")); - if ( ap != 0 ) - { - ap->info = A.info; - ap->pendingvolume64 = A.pendingvolume64; - } - //printf("after swap ap.%p (%s)\n",ap,retstr); - return(retstr); - - char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,char *cmdstr,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side - { - uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; - struct instantdex_accept *ap; struct bitcoin_swapinfo *swap = 0; bits256 orderhash,traderpub; - struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0; - relsatoshis = instantdex_relsatoshis(A->offer.price64,A->offer.basevolume64); - traderpub = jbits256(argjson,"traderpub"); - if ( (minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - coinbtc = iguana_coinfind("BTC"); - insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee prevents papercut attack - offerdir = instantdex_bidaskdir(A); - vcalc_sha256(0,orderhash.bytes,(void *)&A->offer,sizeof(ap->offer)); - swap = A->info; - if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) - { - printf("got my own packet\n"); - return(clonestr("{\"result\":\"got my own packet\"}")); - } - printf("T.%d [%s] got %s.(%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d swap.%p decksize.%ld/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),swap!=0?swap->nextstate:"",cmdstr,A->offer.base,A->offer.rel,dstr(A->offer.price64),dstr(A->offer.basevolume64),(long long)A->orderid,A->offer.myside,A->offer.acceptdir,A->info,sizeof(swap->deck),serdatalen); - if ( exchange == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}")); - if ( (altcoin= iguana_coinfind(A->offer.base)) == 0 || coinbtc == 0 ) - { - printf("other.%p coinbtc.%p (%s/%s)\n",altcoin,coinbtc,A->offer.base,A->offer.rel); - return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}")); - } - if ( strcmp(A->offer.rel,"BTC") != 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}")); - if ( orderhash.txid != A->orderid ) - return(clonestr("{\"error\":\"txid mismatches orderid\"}")); - if ( strcmp(cmdstr,"offer") == 0 ) // receiver is networkwide - { - if ( A->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}")); - if ( (ap= instantdex_acceptable(myinfo,exchange,A,acct777_nxt64bits(traderpub),minperc)) != 0 ) - { - if ( A->info == 0 ) - { - swap = calloc(1,sizeof(struct bitcoin_swapinfo)); - swap->choosei = swap->otherschoosei = -1; - swap->othertrader = traderpub; - if ( offerdir > 0 ) - swap->bidid = A->orderid; - else swap->askid = A->orderid; - swap->isbob = (A->offer.myside ^ 1); - printf("%p SET ISBOB.%d orderid.%llu\n",ap,swap->isbob,(long long)A->orderid); - } - char str[65]; printf("GOT OFFER! %p (%s/%s) other.%s myside.%d next.%s\n",A->info,A->offer.base,A->offer.rel,bits256_str(str,traderpub),swap->isbob,swap->nextstate); - if ( (A->info= swap) != 0 ) - { - ap->info = swap; - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,orderhash,A,1)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); - else - { - // verify feetx - instantdex_pendingnotice(myinfo,exchange,ap,A->offer.basevolume64); - if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) - { - return(retstr); - } - else - { - // generate feetx to send - if ( swap->isbob != 0 ) - strcpy(swap->nextstate,"step2"); - else strcpy(swap->nextstate,"step3"); - return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep1",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); - } - } - } else return(clonestr("{\"error\":\"couldnt allocate swap info\"}")); - } - else - { - printf("no matching trade for %llu -> InstantDEX_minaccept isbob.%d\n",(long long)A->orderid,A->offer.myside); - if ( instantdex_offerfind(myinfo,exchange,0,0,A->orderid,"*","*",1) == 0 ) - { - ap = calloc(1,sizeof(*ap)); - *ap = *A; - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - return(clonestr("{\"result\":\"added new order to orderbook\"}")); - } else return(clonestr("{\"result\":\"order was already in orderbook\"}")); - } - } - else if ( swap == 0 ) - return(clonestr("{\"error\":\"no swap info\"}")); - if ( offerdir > 0 ) - swap->bidid = A->orderid; - else swap->askid = A->orderid; - if ( bits256_nonz(swap->othertrader) == 0 ) - swap->othertrader = traderpub; - else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) - { - printf("competing offer received for (%s/%s) %.8f %.8f\n",A->offer.base,A->offer.rel,dstr(A->offer.price64),dstr(A->offer.basevolume64)); - return(clonestr("{\"error\":\"no competing offers for now\"}")); - } - if ( bits256_nonz(swap->orderhash) == 0 ) - swap->orderhash = orderhash; - else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) - { - printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); - return(clonestr("{\"error\":\"orderhash mismatch???\"}")); - } - swap->satoshis[0] = A->offer.basevolume64; - swap->satoshis[1] = relsatoshis; - swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee - if ( swap->minperc < minperc ) - swap->minperc = minperc; - return(instantdex_statemachine(myinfo,exchange,A,cmdstr,swap,argjson,serdata,serdatalen,altcoin,coinbtc)); - } - -#ifdef xxx - if ( strcmp(cmdstr,"step1") == 0 && strcmp(swap->nextstate,cmdstr) == 0 ) // either - { - printf("%s got step1, should have other's choosei\n",swap->isbob!=0?"BOB":"alice"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step1 null newjson\"}")); - else if ( swap->otherschoosei < 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step1, no didnt choosei\"}")); - else - { - printf("%s chose.%d\n",swap->isbob==0?"BOB":"alice",swap->otherschoosei); - if ( swap->isbob == 0 ) - swap->privAm = swap->privkeys[swap->otherschoosei]; - else swap->privBn = swap->privkeys[swap->otherschoosei]; - memset(&swap->privkeys[swap->otherschoosei],0,sizeof(swap->privkeys[swap->otherschoosei])); - if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) - return(retstr); - /*if ( swap->isbob == 0 ) - { - if ( (swap->feetx= instantdex_bobtx(myinfo,coinbtc,&swap->ftxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->insurance,1)) != 0 ) - { - jaddstr(newjson,"feetx",swap->feetx); - jaddbits256(newjson,"ftxid",swap->ftxid); - // broadcast to network - } - }*/ - if ( swap->isbob != 0 ) - { - strcpy(swap->nextstate,"step4"); - printf("BOB sends (%s), next.(%s)\n","BTCstep3",swap->nextstate); - } - else - { - strcpy(swap->nextstate,"step3"); - printf("Alice sends (%s), next.(%s)\n","BTCstep2",swap->nextstate); - } - return(instantdex_sendcmd(myinfo,&A->offer,newjson,swap->isbob != 0 ? "BTCstep3" : "BTCstep2",swap->othertrader,INSTANTDEX_HOPS,swap->privkeys,sizeof(swap->privkeys))); - } - } - else if ( strcmp(cmdstr,"step2") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob - { - printf("%s got step2, should have other's privkeys\n",swap->isbob!=0?"BOB":"alice"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step2 null newjson\"}")); - else - { - instantdex_privkeysextract(myinfo,swap,serdata,serdatalen); - if ( swap->cutverified == 0 || swap->otherverifiedcut == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step2, both sides didnt validate\"}")); - else - { - if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->dtxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->satoshis[swap->isbob],1)) != 0 ) - { - jaddstr(newjson,"deposit",swap->deposit); - jaddbits256(newjson,"dtxid",swap->dtxid); - //jaddbits256(newjson,"pubBn",bitcoin_pubkey33(pubkey,swap->pubBn)); - // broadcast to network - strcpy(swap->nextstate,"step4"); - printf("BOB sends (%s), next.(%s)\n","BTCstep3",swap->nextstate); - return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep3",swap->othertrader,INSTANTDEX_HOPS,0,0)); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step2, cant create deposit\"}")); - } - } //else return(clonestr("{\"error\":\"instantdex_BTCswap step2 invalid fee\"}")); - } - else if ( strcmp(cmdstr,"step3") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // alice - { - printf("Alice got step3 should have Bob's choosei\n"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3 null newjson\"}")); - else - { - instantdex_privkeysextract(myinfo,swap,serdata,serdatalen); - if ( swap->cutverified == 0 || swap->otherverifiedcut == 0 || bits256_nonz(swap->pubBn) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step3, both sides didnt validate\"}")); - else if ( instantdex_paymentverify(myinfo,coinbtc,swap,A,argjson,1) == 0 ) - { - //swap->pubAm = bitcoin_pubkey33(pubkey,swap->privkeys[swap->otherschoosei]); - if ( (swap->altpayment= instantdex_alicetx(myinfo,altcoin,swap->altmsigaddr,&swap->aptxid,swap->pubAm,swap->pubBn,swap->satoshis[swap->isbob])) != 0 ) - { - jaddstr(newjson,"altpayment",swap->altpayment); - jaddstr(newjson,"altmsigaddr",swap->altmsigaddr); - jaddbits256(newjson,"aptxid",swap->aptxid); - jaddbits256(newjson,"pubAm",swap->pubAm); - // broadcast to network - strcpy(swap->nextstate,"step5"); - printf("Alice sends (%s), next.(%s)\n","BTCstep4",swap->nextstate); - return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep4",swap->othertrader,INSTANTDEX_HOPS,0,0)); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, error making altpay\"}")); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, invalid deposit\"}")); - } - } - else if ( strcmp(cmdstr,"step4") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob - { - printf("Bob got step4 should have Alice's altpayment\n"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap Bob step4 null newjson\"}")); - else if ( bits256_nonz(swap->pubAm) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap step4, no pubAm\"}")); - else if ( instantdex_altpaymentverify(myinfo,altcoin,swap,A,argjson) == 0 ) - { - if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->ptxid,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->satoshis[swap->isbob],0)) != 0 ) - { - jaddstr(newjson,"payment",swap->payment); - jaddbits256(newjson,"ptxid",swap->ptxid); - // broadcast to network - strcpy(swap->nextstate,"step6"); - return(instantdex_sendcmd(myinfo,&A->offer,newjson,"BTCstep5",swap->othertrader,INSTANTDEX_HOPS,0,0)); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step4, cant create payment\"}")); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step3, invalid deposit\"}")); - } - else if ( strcmp(cmdstr,"step5") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // alice - { - printf("Alice got step5 should have Bob's payment\n"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap Alice step5 null newjson\"}")); - else if ( instantdex_paymentverify(myinfo,coinbtc,swap,A,argjson,0) == 0 ) - { - strcpy(swap->nextstate,"step7"); - /*if ( (swap->spendtx= instantdex_spendpayment(myinfo,coinbtc,&swap->stxid,swap,argjson,newjson)) != 0 ) - { - // broadcast to network - return(instantdex_sendcmd(myinfo,&A->A,newjson,"BTCstep6",swap->othertrader,INSTANTDEX_HOPS)); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Alice step5, cant spend payment\"}"));*/ - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, invalid payment\"}")); - } - else if ( strcmp(cmdstr,"step6") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // bob - { - printf("Bob got step6 should have Alice's privkey\n"); - if ( (newjson= instantdex_newjson(myinfo,swap,argjson,swap->orderhash,A,0)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6 null newjson\"}")); - strcpy(swap->nextstate,"step7"); - /*else if ( instantdex_spendverify(myinfo,coinbtc,swap,A,argjson,0) == 0 ) - { - if ( (swap->altspend= instantdex_spendaltpayment(myinfo,altcoin,&swap->astxid,swap,argjson,newjson)) != 0 ) - { - jaddstr(newjson,"altspend",swap->altspend); - jaddbits256(newjson,"astxid",swap->astxid); - // broadcast to network - return(clonestr("{\"result\":\"Bob finished atomic swap\"}")); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, cant spend altpayment\"}")); - } else return(clonestr("{\"error\":\"instantdex_BTCswap Bob step6, invalid spend\"}"));*/ - } - else if ( strcmp(cmdstr,"step7") == 0 && strcmp(swap->nextstate,"cmdstr") == 0 ) // both - { - // update status, goto refund if thresholds exceeded - retstr = clonestr("{\"result\":\"BTC swap updated state\"}"); - } - else retstr = clonestr("{\"error\":\"BTC swap got unrecognized command\"}"); - if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"BTC swap null retstr\"}"); - if ( swap != 0 ) - printf("BTCSWAP next.(%s) (%s) isbob.%d nextstate.%s verified.(%d %d)\n",swap->nextstate,cmdstr,swap->isbob,swap->nextstate,swap->cutverified,swap->otherverifiedcut); - else printf("BTCSWAP.(%s)\n",retstr); - return(retstr); -#endif - else if ( strcmp(cmdstr,"BTCdeckC") == 0 ) - { - if ( ap->info == 0 ) - { - printf("A (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap); - return(clonestr("{\"error\":\"no swap for orderid\"}")); - } - else - { - if ( ap->otherorderid == 0 ) - { - ap->otherorderid = ap->orderid; - ap->otheroffer = ap->offer; - ap->offer = A.offer; - ap->orderid = A.orderid; - ((struct bitcoin_swapinfo *)ap->info)->feetag64 = ap->orderid; - } - printf("add to statemachine\n"); - queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0); - newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0); - if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,ap->info,"BOB_sentoffer","ALICE_sentoffer")) == 0 ) - { - return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen)); - } else return(clonestr("{\"error\":\"couldnt add fee\"}")); - } - /* - for (iter=0; iter<2; iter++) - { - while ( (m= category_gethexmsg(myinfo,instantdexhash,iter == 0 ? GENESIS_PUBKEY : myinfo->myaddr.persistent)) != 0 ) - { - //printf("gothexmsg len.%d\n",m->len); - pm = (struct instantdex_msghdr *)m->msg; - if ( m->remoteipbits != 0 ) - expand_ipbits(remote,m->remoteipbits); - else remote[0] = 0; - if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 ) - free(str); - free(m); - } - }*/ - - /* uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; - bits256 orderhash,traderpub; struct iguana_info *coinbtc; - if ( (swap= ap->info) == 0 ) - return(clonestr("{\"error\":\"no swapinfo set\"}")); - relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); - if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - offerdir = instantdex_bidaskdir(&ap->offer); - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("swapset.%llu\n",(long long)ap->orderid); - } - if ( offerdir > 0 ) - { - swap->bidid = ap->orderid; - swap->askid = ap->otherorderid; - } - else - { - swap->askid = ap->orderid; - swap->bidid = ap->otherorderid; - } - if ( bits256_nonz(swap->othertrader) == 0 ) - swap->othertrader = traderpub; - else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) - { - printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); - return(clonestr("{\"error\":\"no competing offers for now\"}")); - } - if ( bits256_nonz(swap->orderhash) == 0 ) - swap->orderhash = orderhash; - else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) - { - printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); - return(clonestr("{\"error\":\"orderhash mismatch???\"}")); - } - swap->satoshis[0] = ap->offer.basevolume64; - swap->satoshis[1] = relsatoshis; - swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee - /* if ( ap->info == 0 ) - //printf("gotoffer SETSWAP for orderid.%llu (%s)\n",(long long)ap->orderid,jprint(argjson,0)); - swap->choosei = swap->otherschoosei = -1; - if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) - return(retstr); - swap->feetag64 = ap->orderid;*/ - - /*char *instantdex_swapset(struct supernet_info *myinfo,struct instantdex_accept *ap,cJSON *argjson) - { - uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; - struct bitcoin_swapinfo *swap; bits256 orderhash,traderpub; struct iguana_info *coinbtc; - if ( (swap= ap->info) == 0 ) - return(clonestr("{\"error\":\"no swapinfo set\"}")); - relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); - traderpub = jbits256(argjson,"traderpub"); - if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - if ( (coinbtc= iguana_coinfind("BTC")) == 0 ) - return(clonestr("{\"error\":\"no BTC found\"}")); - insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); - offerdir = instantdex_bidaskdir(&ap->offer); - vcalc_sha256(0,orderhash.bytes,(void *)&ap->offer,sizeof(ap->offer)); - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("swapset.%llu\n",(long long)ap->orderid); - } - if ( offerdir > 0 ) - { - swap->bidid = ap->orderid; - swap->askid = ap->otherorderid; - } - else - { - swap->askid = ap->orderid; - swap->bidid = ap->otherorderid; - } - if ( bits256_nonz(swap->othertrader) == 0 ) - swap->othertrader = traderpub; - else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) - { - printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); - return(clonestr("{\"error\":\"no competing offers for now\"}")); - } - if ( bits256_nonz(swap->orderhash) == 0 ) - swap->orderhash = orderhash; - else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) - { - printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); - return(clonestr("{\"error\":\"orderhash mismatch???\"}")); - } - swap->satoshis[0] = ap->offer.basevolume64; - swap->satoshis[1] = relsatoshis; - swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee - return(0); - } - - char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson) // Bob sending to network (Alice) - { - struct iguana_info *other; struct bitcoin_swapinfo *swap; int32_t isbob; cJSON *newjson; char *retstr; - if ( strcmp(ap->offer.rel,"BTC") != 0 ) - return(clonestr("{\"error\":\"invalid othercoin\"}")); - else if ( (other= iguana_coinfind(ap->offer.base)) == 0 ) - return(clonestr("{\"error\":\"invalid othercoin\"}")); - else if ( ap->offer.price64 <= 0 || ap->offer.basevolume64 <= 0 ) - return(clonestr("{\"error\":\"illegal price or volume\"}")); - isbob = (ap->offer.myside == 1); - swap = calloc(1,sizeof(struct bitcoin_swapinfo)); - swap->isbob = isbob; - swap->expiration = ap->offer.expiration;//(uint32_t)(time(NULL) + INSTANTDEX_LOCKTIME*isbob); - swap->choosei = swap->otherschoosei = -1; - swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1; - ap->info = swap; - printf("sendoffer SETSWAP for orderid.%llu ap.%p (%p)\n",(long long)ap->orderid,ap,swap); - if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) - return(retstr); - ap->orderid = swap->orderhash.txid; - if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); - else - { - //instantdex_bobtx(myinfo,iguana_coinfind("BTCD"),&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],ap->offer.expiration-INSTANTDEX_LOCKTIME*2,swap->satoshis[1],1); - //instantdex_alicetx(myinfo,iguana_coinfind("BTCD"),swap->altmsigaddr,&swap->altpaymenttxid,swap->pubAm,swap->pubBn,swap->satoshis[0]); - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("BTCoffer.%llu\n",(long long)ap->orderid); - } - return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); - } - }*/ - /*ptr = (void *)bp->scriptsmap; - ind = unspentind << 1; - for (i=0; inumscriptsmaps; i++,ptr+=2) - { - if ( ind == ptr[0] ) - { - printf("bp.[%d] ind.%d offset.%d vs %ld\n",bp->hdrsi,ind,ptr[1],coin->scriptsfilesize); - if ( ptr[1] + sizeof(struct scriptdata) <= coin->scriptsfilesize ) - { - if ( memcmp((void *)((long)coin->scriptsptr + ptr[1] + sizeof(struct scriptdata)),spendscript,spendlen) == 0 ) - { - printf("matched against existing scriptsptr[%d] %d\n",ptr[1],spendlen); - return(ptr[1]); - } - printf("mismatch against existing scriptsptr[%d] %d\n",ptr[1],spendlen); - } - else - { - if ( (fp= fopen(coin->scriptsfname,"rb")) != 0 ) - { - fseek(fp,ptr[1] + sizeof(struct scriptdata),SEEK_SET); - for (i=0; ihdrsi,unspentind,i,ftell(fp),ptr[1],ptr[1]+sizeof(struct scriptdata)+spendlen,c,spendscript[i]); - for (; inumscriptsmaps >= bp->maxscriptsmaps ) - { - bp->scriptsmap = realloc(bp->scriptsmap,(1000+bp->maxscriptsmaps) * (sizeof(offset) + sizeof(ind))); - bp->maxscriptsmaps += 1000; - } - ptr = (void *)((long)bp->scriptsmap + bp->numscriptsmaps*size); - ptr[0] = ind; - ptr[1] = offset; - bp->numscriptsmaps++; - }*/ - - uint32_t iguana_scriptstableadd(struct iguana_info *coin,int32_t spendflag,uint32_t fpos,uint8_t *script,uint16_t scriptlen) - { - struct scriptinfo *ptr; - HASH_FIND(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); - if ( ptr == 0 ) - { - ptr = mycalloc('w',1,sizeof(*ptr) + scriptlen); - ptr->fpos = fpos; - ptr->scriptlen = scriptlen; - memcpy(ptr->script,script,scriptlen); - HASH_ADD(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); - } - return(fpos); - } - - uint32_t iguana_scriptstablefind(struct iguana_info *coin,int32_t spendflag,uint8_t *script,int32_t scriptlen) - { - struct scriptinfo *ptr; - HASH_FIND(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); - if ( ptr != 0 ) - return(ptr->fpos); - else return(0); - } - - long iguana_rwscript(struct iguana_info *coin,int32_t rwflag,void *fileptr,long offset,long filesize,FILE *fp,struct iguana_bundle *bp,uint8_t **scriptptrp,int32_t *lenp,int32_t hdrsi,uint32_t ind,int32_t spendflag) - { - long scriptpos; struct scriptdata data; uint8_t *script = *scriptptrp; - if ( spendflag == 0 && (scriptpos= iguana_scriptstablefind(coin,spendflag,script,*lenp)) != 0 ) - return(scriptpos); - memset(&data,0,sizeof(data)); - if ( rwflag != 0 && fp != 0 && fileptr == 0 ) - { - scriptpos = ftell(fp); - data.ind = ind, data.spendflag = spendflag; - data.hdrsi = hdrsi; - data.scriptlen = *lenp; - if ( fwrite(&data,1,sizeof(data),fp) != sizeof(data) ) - return(-1); - if ( fwrite(script,1,data.scriptlen,fp) != data.scriptlen ) - return(-1); - offset = (uint32_t)ftell(fp); - //printf("spend.%d filesize.%ld wrote.h%d u%d len.%d [%ld,%ld) crc.%08x\n",spendflag,coin->scriptsfilesize[spendflag],hdrsi,ind,data.scriptlen,scriptpos,ftell(fp),calc_crc32(0,script,data.scriptlen)); - } - else if ( rwflag == 0 && fp == 0 && fileptr != 0 ) - { - scriptpos = offset; - if ( offset+sizeof(data) <= filesize ) - { - memcpy(&data,(void *)((long)fileptr + offset),sizeof(data)); - if ( data.scriptlen > 0 && data.scriptlen < *lenp && offset+sizeof(data)+data.scriptlen <= filesize ) - { - if ( data.scriptlen > 0 ) - { - *scriptptrp = script = (void *)((long)fileptr + offset); - offset += data.scriptlen + sizeof(data); - if ( data.hdrsi < coin->bundlescount ) - bp = coin->bundles[data.hdrsi]; - else printf("illegal hdrsi.%d/%d\n",data.hdrsi,coin->bundlescount); - } else printf("illegal scriptlen %d\n",data.scriptlen); - //printf("hdrsi.%d loaded script.%d %u s%d\n",data.hdrsi,data.scriptlen,data.ind,data.spendflag); - } - else if ( data.scriptlen > 0 ) - { - printf("spendlen overflow.%d vs %d\n",data.scriptlen,*lenp); - return(-1); - } - } - else - { - printf("error reading from %ld\n",scriptpos); - return(-1); - } - //printf("hdrsi.%d scriptlen.%d\n",data.hdrsi,data.scriptlen); - *lenp = data.scriptlen; - } - if ( bp != 0 ) - { - //if ( spendflag == 0 ) - iguana_scriptstableadd(coin,spendflag,(uint32_t)scriptpos,script,*lenp); - } - else if ( rwflag == 0 ) - { - printf("null bp for iguana_rwscript hdrsi.%d/%d\n",data.hdrsi,coin->bundlescount); - return(-1); - } - return(offset); - } - - long iguana_initscripts(struct iguana_info *coin) - { - long fpos=0,offset = 0; uint8_t scriptdata[IGUANA_MAXSCRIPTSIZE],*scriptptr; int32_t spendflag,size,n=0; struct scriptdata script; - for (spendflag=0; spendflag<2; spendflag++) - { - portable_mutex_lock(&coin->scripts_mutex[spendflag]); - sprintf(coin->scriptsfname[spendflag],"tmp/%s/%sscripts",coin->symbol,spendflag==0?"":"sig"), OS_portable_path(coin->scriptsfname[spendflag]); - printf("scripts fname.(%s)\n",coin->scriptsfname[spendflag]); - if ( (coin->scriptsptr[spendflag]= OS_mapfile(coin->scriptsfname[spendflag],&coin->scriptsfilesize[spendflag],0)) == 0 ) - { - coin->scriptsfp[spendflag] = fopen(coin->scriptsfname[spendflag],"wb"); - memset(&script,0,sizeof(script)); - fwrite(&script,1,sizeof(script),coin->scriptsfp[spendflag]); - } - else - { - while ( 1 ) - { - size = sizeof(scriptdata); - scriptptr = scriptdata; - if ( (offset= iguana_rwscript(coin,0,coin->scriptsptr[spendflag],offset,coin->scriptsfilesize[spendflag],0,0,&scriptptr,&size,0,0,spendflag)) < 0 ) - break; - else fpos = offset; - n++; - } - coin->scriptsfp[spendflag] = fopen(coin->scriptsfname[spendflag],"ab"); - portable_mutex_unlock(&coin->scripts_mutex[spendflag]); - printf("initialized %d scripts, fpos %ld\n",n,fpos); - return(offset); - } - portable_mutex_unlock(&coin->scripts_mutex[spendflag]); - } - return(-1); - } - - uint32_t iguana_scriptsave(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t ind,int32_t spendflag,uint8_t *script,int32_t scriptlen) - { - FILE *fp; long fpos = 0; - if ( scriptlen > 0 && (fp= coin->scriptsfp[spendflag]) != 0 ) - { - portable_mutex_lock(&coin->scripts_mutex[spendflag]); - fpos = ftell(fp); - if ( iguana_rwscript(coin,1,0,0,0,fp,bp,&script,&scriptlen,bp->hdrsi,ind,spendflag) < 0 ) - { - fseek(fp,fpos,SEEK_SET); - fpos = -1; - printf("error saving script at %ld\n",fpos); - } else fflush(fp); - portable_mutex_unlock(&coin->scripts_mutex[spendflag]); - } else printf("cant scriptsave.%d to (%s).%p scriptlen.%d\n",spendflag,coin->scriptsfname[spendflag],coin->scriptsfp[spendflag],scriptlen); - return((uint32_t)fpos); - } - - long iguana_scriptadd(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t unspentind,int32_t type,uint8_t *spendscript,int32_t spendlen,uint8_t rmd160[20],int32_t vout) - { - static long total,saved; - int32_t scriptlen; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t script[IGUANA_MAXSCRIPTSIZE]; long fpos=0; struct vin_info V,*vp = &V; - if ( spendlen == 0 ) - { - printf("null script?\n"); - getchar(); - return(0); - } - memset(vp,0,sizeof(*vp)); - asmstr[0] = 0; - total++; - scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout); - if ( scriptlen == spendlen && memcmp(script,spendscript,scriptlen) == 0 ) - return(0); - else - { - saved++; - //if ( (saved % 1000) == 0 ) - printf("add type.%d scriptlen.%d fpos.%ld saved.%ld/%ld\n",type,spendlen,coin->scriptsfp!=0?ftell(coin->scriptsfp[0]):-1,saved,total); - fpos = iguana_scriptsave(coin,bp,unspentind,0,spendscript,spendlen); - } - return(fpos); - } - if ( s->sighash != iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vinscript,vinscriptlen) ) - { - static uint64_t counter; - if ( counter++ < 100 ) - { - for (i=0; isighash); - } - return(spendind); - } - //ramchain->H.stacksize += sigsize;// + 1 + (sigsize >= 0xfd)*2; - if ( s->numpubkeys > 0 ) - { - for (i=0; inumpubkeys; i++) - { - if ( (ptr= iguana_hashfind(ramchain,'P',V.signers[i].rmd160)) == 0 ) - { - //printf("from addspend\n"); - //pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,V.signers[i].rmd160,0,0,0); - //printf("create pkind.%d from vin\n",pkind); - } else pkind = ptr->hh.itemind; - } - } - if ( 0 && s->numsigs > 0 ) - printf("autoverify numsigs.%d\n",s->numsigs); - - - uint8_t *iguana_scriptptr(struct iguana_info *coin,int32_t *scriptlenp,uint8_t _script[IGUANA_MAXSCRIPTSIZE],uint32_t scriptfpos,uint8_t *scriptdata,int32_t scriptlen,int32_t maxsize,int32_t spendflag) - { - *scriptlenp = scriptlen; - if ( 0 && scriptlen > 0 ) - { - if ( scriptfpos != 0 ) - scriptdata = iguana_scriptfpget(coin,scriptlenp,_script,scriptfpos,spendflag); - } - return(scriptdata); - } - - uint8_t *iguana_scriptfpget(struct iguana_info *coin,int32_t *scriptlenp,uint8_t _script[IGUANA_MAXSCRIPTSIZE],uint32_t scriptoffset,int32_t spendflag) - { - FILE *fp; uint8_t *scriptdata=0; int32_t scriptlen=0; struct scriptdata sdata; - *scriptlenp = 0; - if ( (fp= fopen(coin->scriptsfname[spendflag],"rb")) != 0 ) - { - fseek(fp,scriptoffset,SEEK_SET); - if ( fread(&sdata,1,sizeof(sdata),fp) != sizeof(sdata) ) - printf("iguana_scriptfpget: error reading sdata\n"); - else if ( sdata.scriptlen > 0 && sdata.scriptlen <= IGUANA_MAXSCRIPTSIZE ) - { - if ( fread(_script,1,sdata.scriptlen,fp) == sdata.scriptlen ) - { - scriptdata = _script; - *scriptlenp = scriptlen = sdata.scriptlen; - //printf("raw [%d] offset.%d scriptlen.%d\n",bp->hdrsi,scriptoffset,scriptlen); - //for (i=0; i<16; i++) - // printf("%02x",_script[i]); - //printf(" set script.%d\n",scriptlen); - } - } - fclose(fp); - } - return(scriptdata); - } - //struct scriptdata { uint32_t ind:31,spendflag:1; uint16_t hdrsi,scriptlen; }__attribute__((packed)); - - if ( ramchain->expanded != 0 ) - { - if ( (long)destoffset < (long)srcoffset ) - { - /*sprintf(fname,"sigs/%s/%s",coin->symbol,bits256_str(str,bp->hashes[0])); - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( ramchain->H.stacksize > 0 ) - { - if ( fwrite(srcoffset,1,ramchain->H.stacksize,fp) != ramchain->H.stacksize ) - printf("error writing %d sigs to %s\n",ramchain->H.stacksize,fname); - } - else - { - if ( fwrite(&izero,1,sizeof(izero),fp) != sizeof(izero) ) - printf("error writing izero to %s\n",fname); - } - fclose(fp); - } - if ( (ramchain->sigsfileptr= OS_mapfile(fname,&ramchain->sigsfilesize,0)) == 0 ) - return(-1); - printf("%s bp.[%d] ht.%d stacksize.%u filesize.%u\n",fname,bp->hdrsi,bp->bundleheight,ramchain->H.stacksize,(uint32_t)ramchain->sigsfilesize);*/ - //for (i=0; iH.stacksize; i++) - // c = *srcoffset, *destoffset++ = c, *srcoffset++ = 0; - } else printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); - } - // if file exists and is valid, load and then process only the incremental - long iguana_spentsfile(struct iguana_info *coin,int32_t n) - { - int32_t i,iter,allocated = 0; long filesize,total,count; struct iguana_bundleind *spents = 0; struct iguana_ramchain *ramchain; char fname[1024]; struct iguana_bundle *bp; FILE *fp; - fname[0] = 0; - for (total=iter=0; iter<2; iter++) - { - for (count=i=0; ibundles[i]) != 0 ) - { - ramchain = &bp->ramchain; - if ( ramchain->H.data != 0 ) - { - if ( iter == 1 ) - { - ramchain->spents = &spents[count]; - //printf("bp.[%d] count.%ld %p\n",i,count,ramchain->spents); - if ( allocated != 0 && iguana_spentsinit(coin,spents,bp,ramchain) < 0 ) - { - printf("error initializing spents bp.%d\n",i); - exit(-1); - } - } - count += ramchain->H.data->numunspents; - } else break; - } else return(-1); - } - if ( i < n ) - n = (i + 1); - sprintf(fname,"DB/%s/spents_%d.%ld",coin->symbol,n,count); - printf("%s total unspents.%ld\n",fname,count); - if ( iter == 0 ) - { - total = count; - if ( (spents= OS_filestr(&filesize,fname)) == 0 ) - spents = calloc(total,sizeof(*spents)), allocated = 1; - } - else if ( total != count ) - printf("%s total.%ld != count.%ld\n",fname,total,count); - } - if ( allocated != 0 && fname[0] != 0 && (fp= fopen(fname,"wb")) != 0 ) - { - fwrite(spents,total,sizeof(*spents),fp); - fclose(fp); - } - return(total); - } - - int32_t iguana_spentsinit(struct iguana_info *coin,struct iguana_bundleind *spents,struct iguana_bundle *bp,struct iguana_ramchain *ramchain) - { - int32_t spendind,n,max,hdrsi,errs,flag; uint32_t unspentind; struct iguana_bundle *spentbp; - struct iguana_spend *S; bits256 prevhash; - S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); - max = ramchain->H.data->numunspents; - n = ramchain->H.data->numspends; - for (spendind=1,errs=0; spendindhdrsi; - if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,&S[spendind])) != 0 ) - { - spentbp->ramchain.spents[unspentind].ind = spendind; - spentbp->ramchain.spents[unspentind].hdrsi = bp->hdrsi; - flag = 1; - if ( S[spendind].external == 0 && spentbp != bp ) - printf("spentsinit unexpected spendbp: %p bp.[%d] U%d <- S%d.[%d] [%p %p %p]\n",&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spendind,bp->hdrsi,coin->bundles[0],coin->bundles[1],coin->bundles[2]); - } - else if ( S[spendind].prevout < 0 ) - flag = 1; - else printf("unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); - if ( flag == 0 ) - errs++; - } - printf("processed %d spendinds for bp.[%d] -> errs.%d\n",spendind,bp->hdrsi,errs); - return(-errs); - } - if ( bp != currentbp ) - { - //printf("initial requests for hdrs.%d\n",bp->hdrsi); - pend = queue_size(&coin->priorityQ) + queue_size(&coin->blocksQ); - for (i=0; ipeers.active[i].pendblocks; - if ( 0 && pend >= IGUANA_BUNDLELOOP ) - { - //for (i=better=0; ibundlescount; i++) - // if ( coin->bundles[i] != 0 && coin->bundles[i]->numsaved > bp->numsaved ) - // better++; - //if ( better > coin->peers.numranked ) - { - //usleep(10000); - //printf("SKIP pend.%d vs %d: better.%d ITERATE bundle.%d n.%d r.%d s.%d finished.%d timelimit.%d\n",pend,coin->MAXPENDING*coin->peers.numranked,better,bp->bundleheight,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit); - iguana_bundleQ(coin,bp,1000); - return(0); - } - } - counter = iguana_bundlekick(coin,bp,starti,max); - } - if ( req == 0 && 0 ) - { - if ( 1 )//(rand() % 10) == 0 ) - flag = iguana_neargap(coin,addr); - else if ( 0 && (bp= addr->bp) != 0 && bp->rank != 0 && addr->pendblocks < limit ) - { - r = rand(); - for (j=0; jn; j++) - { - i = (r + j) % bp->n; - if ( (block= bp->blocks[i]) != 0 && block->numrequests == bp->minrequests && block->fpipbits == 0 && block->queued == 0 ) - { - printf("peer.%s BPranked.%d [%d:%d] pending.%d numreqs.%d\n",addr->ipaddr,bp->rank,bp->hdrsi,i,addr->pendblocks,block->numrequests); - block->numrequests++; - flag++; - iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - break; - } - } - } - } - - int32_t iguana_neargap(struct iguana_info *coin,struct iguana_peer *addr) - { - struct iguana_block *block,*bestblock = 0; struct iguana_bundle *bp,*bestbp = 0; - int32_t height,hdrsi,i,j,n,bundlei,gap,besti = -1; uint32_t r; - if ( addr->rank > 0 ) - { - n = coin->peers.numranked * 2; - gap = addr->rank * (1 + n + coin->peers.numranked) + coin->peers.numranked; - for (i=0; ibundlescount; i++) - if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish == 0 ) - break; - height = (i * coin->chain->bundlesize); - r = rand(); - for (i=0; ichain->bundlesize; - if ( (bp= coin->bundles[hdrsi]) != 0 ) - { - bundlei = (height + j) % coin->chain->bundlesize; - if ( (block= bp->blocks[bundlei]) != 0 && block->fpipbits == 0 && block->queued == 0 ) - { - if ( block->numrequests == bp->minrequests ) - { - bestblock = block; - bestbp = bp; - besti = bundlei; - break; - } - else if ( bestblock == 0 || block->numrequests < bestblock->numrequests ) - { - bestblock = block; - bestbp = bp; - besti = bundlei; - } - } - } - } - if ( bestblock != 0 ) - { - printf("near hwm.%d gap.%d peer.%s bpranked.%d [%d:%d] pending.%d numreqs.%d\n",height,j,addr->ipaddr,bestbp->rank,bestbp->hdrsi,besti,addr->pendblocks,bestblock->numrequests); - bestblock->numrequests++; - iguana_sendblockreqPT(coin,addr,bestbp,besti,bestblock->RO.hash2,0); - return(1); - } - } - return(0); - } - /*if ( doneval != maxval ) - { - r = rand() % numpeers; - oldest = 0; - for (i=0; i 0 ) - { - for (i=j; in; i+=numpeers) - if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 ) - { - if ( oldest == 0 || block->issued < oldest->issued ) - oldest = block; - if ( now > block->issued+10+60*(bp!=coin->current) ) - { - for (k=0; k 0 && (addr= coin->peers.ranked[z]) != 0 ) - { - if ( bp == coin->current ) - printf("send [%d:%d] to addr[%d]\n",bp->hdrsi,block->bundlei,z); - block->issued = (uint32_t)time(NULL); - counter++; - iguana_sendblockreqPT(coin,addr,bp,block->bundlei,block->RO.hash2,0); - break; - } - } - } - } - } - } - }*/ - //return(counter); - /*if ( 0 && time(NULL) > bp->lastspeculative+60 ) - { - for (i=1,counter=0; in; i++) - { - if ( (block= bp->blocks[i]) == 0 || block->fpos < 0 || block->fpipbits == 0 ) - { - if ( bp->speculative != 0 && bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) > 0 && i < bp->numspec ) - iguana_blockQ("speculate0",coin,0,-2,bp->speculative[i],0), counter++; - else if ( bits256_nonz(bp->hashes[i]) != 0 ) - iguana_blockQ("speculate1",coin,0,-3,bp->hashes[i],0), counter++; - } - } - if ( counter != 0 ) - printf("SPECULATIVE issue.%d bp.[%d]\n",counter,bp->hdrsi); - bp->lastspeculative = (uint32_t)time(NULL); - }*/ - //ramchain->A = OS_filestr(&filesize,fname); - //if ( filesize != sizeof(*ramchain->A)*ramchain->H.data->numpkinds ) - // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->A)*ramchain->H.data->numpkinds); - sprintf(fname,"DB/%s/accounts/lastspends.%d",coin->symbol,ramchain->H.data->height); - //ramchain->Uextras = OS_filestr(&filesize,fname); - //if ( filesize != sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds ) - // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds); - //if ( ramchain->A == 0 ) - ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); - //if ( ramchain->Uextras == 0 ) - ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); - //printf("hashmem.%p A allocated.%p numpkinds.%d %ld\n",hashmem,ramchain->A,ramchain->H.data->numpkinds,sizeof(struct iguana_account)*ramchain->H.data->numpkinds); - //ramchain->P2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_pkextra) * ramchain->H.data->numpkinds,1) : mycalloc('2',ramchain->H.data->numpkinds,sizeof(struct iguana_pkextra)); - ///ramchain->U2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_Uextra) * ramchain->H.data->numunspents,1) : mycalloc('3',ramchain->H.data->numunspents,sizeof(struct iguana_Uextra)); - //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); - //memcpy(ramchain->U2,ramchain->roU2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); - //memcpy(ramchain->P2,ramchain->roP2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); - - int32_t iguana_spendfind(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t spendind,int32_t emit) - { - struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; - struct iguana_bundle *spentbp; struct iguana_txid *T; - ramchain = &bp->ramchain; - if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 || ramchain->Xspendinds == 0 ) - return(-1); - S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); - s = &S[spendind]; - u = 0; - unspentind = 0; - hdrsi = -1; - spentbp = 0; - if ( s->external != 0 && s->prevout >= 0 ) - { - if ( emit >= ramchain->numXspends ) - errs++; - else - { - h = ramchain->Xspendinds[emit].height; - unspentind = ramchain->Xspendinds[emit].ind; - if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) - spentbp = coin->bundles[hdrsi]; - else - { - printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); - return(-1); - } - //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); - emit++; - } - } - else if ( s->prevout >= 0 ) - { - spentbp = bp; - hdrsi = bp->hdrsi; - h = refheight; - if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) - { - T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); - unspentind = T[txidind].firstvout + s->prevout; - if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) - { - printf("iguana_balancegen unspentind overflow %u vs %u\n",unspentind,spentbp->ramchain.H.data->numunspents); - return(-1); - } - //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); - } - else - { - printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); - return(-1); - } - //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); - } - else return(0); - if ( (spendind & 0xff) == 1 ) - now = (uint32_t)time(NULL); - if ( spentbp != 0 && unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) - { - if ( now > spentbp->lastprefetch+20 || (spentbp->dirty % 50000) == 0 ) - { - //printf("current.%d prefetch.[%d] lag.%u\n",spentbp == bp,spentbp->hdrsi,now - spentbp->lastprefetch); - iguana_ramchain_prefetch(coin,&spentbp->ramchain); - spentbp->lastprefetch = now; - } - } - - } - if ( 0 && coin->blocks.hwmchain.height > coin->chain->bundlesize && bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize ) - { - for (bundlei=0; bundlein; bundlei++) - { - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); - if ( checki == bundlei ) - { - if ( (fp= fopen(fname,"rb")) != 0 ) - fclose(fp); - else break; - } - } - if ( bp == coin->current && (bp->ramchain.H.data == 0 || bp->ramchain.H.data->numblocks != bundlei) ) - { - printf("RT bundls\n"); - if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) - { - - } - } - } - /*for (j=0; jRO.prev_block)) != 0 ) - { - printf("iguana_recvblock got prev block [%d:%d]\n",bp->hdrsi,bundlei); - if ( bundlei < bp->n-1 ) - bundlei++; - else bp = 0, bundlei = -2; - /*if ( bits256_cmp(prev->RO.hash2,block->RO.prev_block) == 0 && bundlei < bp->n-1 ) - { - bundlei++; - iguana_bundlehash2add(coin,&tmpblock,bp,bundlei,block->RO.hash2); - if ( tmpblock == block ) - { - printf("[%d:%d] speculative block.%p\n",bp->hdrsi,bundlei,block); - bp->blocks[bundlei] = block; - bp->hashes[bundlei] = block->RO.hash2; - block->bundlei = bundlei; - block->hdrsi = bp->hdrsi; - block->mainchain = prev->mainchain; - } else printf("error adding speculative prev [%d:%d]\n",bp->hdrsi,bundlei); - }*/ - } - /*for (i=coin->bundlescount-1; i>=0; i--) - { - //if ( coin->bundles[i] != 0 ) - // printf("compare vs %s\n",bits256_str(str,coin->bundles[i]->hashes[0])); - if ( coin->bundles[i] != 0 && bits256_cmp(origblock->RO.prev_block,coin->bundles[i]->hashes[0]) == 0 ) - { - bp = coin->bundles[i]; - bundlei = 1; - iguana_bundlehash2add(coin,&block,bp,bundlei,origblock->RO.hash2); - printf("iguana_recvblock [%d] bundlehashadd set.%d block.%p\n",i,bundlei,block); - if ( block != 0 ) - { - bp->blocks[bundlei] = block; - block->bundlei = bundlei; - block->hdrsi = bp->hdrsi; - } - break; - } - }*/ - //printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); - /*if ( checki != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) - { - printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); - continue; - }*/ - if ( 0 && coin->current == bp )//&& (bp->isRT != 0 || bp->hdrsi > coin->bundlescount-3) ) - { - //checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1); - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,0,SEEK_END); - block->RO.recvlen = (uint32_t)ftell(fp); - block->fpipbits = 1; - block->fpos = 0; - //printf("fp.[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); - fclose(fp); - } - else - { - //char str[65]; printf("missing.(%s) issue.%s\n",fname,bits256_str(str,bp->hashes[bundlei])); - block->RO.recvlen = 0; - block->fpipbits = 0; - block->fpos = -1; - //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); - } - } - int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit) - { - int32_t i,j,k,peerid,doneflag,len,forceflag,saved,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard=0,flag=0,finished=0,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; - struct iguana_peer *addr; uint32_t now; struct iguana_block *block; - bits256 hashes[50],hash2; uint8_t serialized[sizeof(hashes) + 256]; - if ( bp == 0 ) - return(0); - now = (uint32_t)time(NULL); - memset(peercounts,0,sizeof(peercounts)); - memset(donecounts,0,sizeof(donecounts)); - if ( coin->current != 0 ) - starti = coin->current->hdrsi; - else starti = 0; - priority = (bp->hdrsi < starti + coin->peers.numranked); - if ( strcmp("BTC",coin->symbol) == 0 ) - lag = 10 + (bp->hdrsi - starti); - else lag = 3 + (bp->hdrsi - starti)/10; - if ( coin->current != bp ) - lag *= 3; - if ( (numpeers= coin->peers.numranked) > 3 && 0 )//(bp->numhashes == bp->n || bp->speculative != 0) )//&& bp->currentflag < bp->n ) - { - if ( numpeers > 0xff ) - numpeers = 0xff; // fit into 8 bitfield - if ( bp->currentflag == 0 ) - bp->currenttime = now; - if ( bp->numhashes >= 1 ) - { - for (j=0; jpeers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 ) - { - now = (uint32_t)time(NULL); - for (i=j,k=doneval=maxval=0; in&&khashes[i]) != 0 ) - { - hash2 = bp->hashes[i]; - if ( (block= bp->blocks[i]) != 0 ) - { - if ( (peerid= block->peerid) == 0 ) - { - //printf("<%d>.%d ",i,j); - if ( block->fpipbits != 0 || bp->speculativecache[i] != 0 ) - doneflag = 1; - } - } - } - else if ( bp->speculative != 0 && i < bp->numspec && bits256_nonz(bp->speculative[i]) != 0 ) - { - hash2 = bp->speculative[i]; - if ( bp->speculativecache[i] != 0 ) - doneflag = peerid = 1; - } - if ( doneflag == 0 ) - { - hashes[k++] = hash2; - bp->issued[i] = now; - if ( block != 0 ) - { - block->issued = now; - block->peerid = j + 1; - block->numrequests++; - } - } - else - { - doneflag = 1; - if ( block != 0 ) - { - block->peerid = 1; - block->numrequests++; - } - } - if ( bits256_nonz(hash2) != 0 ) - { - if ( peerid > 1 ) - { - total++; - if ( doneflag != 0 ) - { - donecounts[peerid - 1]++; - if ( donecounts[peerid - 1] > doneval ) - doneval = donecounts[peerid - 1]; - } - else - { - peercounts[peerid - 1]++; - if ( peercounts[peerid - 1] > maxval ) - maxval = peercounts[peerid - 1]; - } - } - } - } - if ( k > 0 ) - { - if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hashes,k)) > 0 ) - { - iguana_send(coin,addr,serialized,len); - counter += k; - coin->numreqsent += k; - addr->pendblocks += k; - addr->pendtime = (uint32_t)time(NULL); - bp->currentflag += k; - } - //printf("a%d/%d ",j,k); - } - } - } - //printf("doneval.%d maxval.%d\n",doneval,maxval); - if ( 0 && priority != 0 ) - { - double threshold; - for (i=nonz=0; i threshold ) - laggard++; - if ( peercounts[i] == 0 && donecounts[i] > threshold ) - finished++; - } - if ( finished > laggard*10 && numpeers > 2*laggard && laggard > 0 ) - { - for (i=0; i threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag && addr->dead == 0 ) - { - if ( (numpeers > 64 || addr->laggard++ > 13) && coin->current == bp ) - { - addr->dead = (uint32_t)time(NULL); - addr->rank = 0; - } - for (j=0; jn; j++) - { - if ( ((block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0) || bp->speculativecache[i] == 0 ) - { - if ( bp == coin->current ) - printf("%d ",j); - flag++; - counter++; - if ( block != 0 ) - { - block->issued = now; - block->peerid = 0; - iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); - } else iguana_blockQ("kick",coin,bp,j,block->RO.hash2,0);//bp == coin->current); - if ( bp == coin->current ) - bp->issued[i] = now; - } - } - if ( flag != 0 && bp == coin->current ) - printf("slow peer.%d dead.%u (%s) reissued.%d [%d]\n",i,addr->dead,addr->ipaddr,flag,bp->hdrsi); - } - } - } - if ( 0 && laggard != 0 ) - { - for (i=0; ihdrsi,finished,laggard,threshold); - } - } - } - for (i=0; in; i++) - { - if ( 0 && (block= bp->blocks[i]) != 0 && iguana_blockstatus(coin,block) == 0 && bp->speculativecache[i] == 0 ) - { - if ( now > block->issued+lag ) - { - counter++; - saved = block->issued; - if ( bp == coin->current ) - forceflag = (now > block->issued + lag); - else forceflag = (now > block->issued + 10*lag); - if ( priority != 0 ) - { - printf("kick.[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kicka",coin,bp,i,block->RO.hash2,0*forceflag); - if ( forceflag != 0 && (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) - iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); - } else iguana_blockQ("kickb",coin,bp,i,block->RO.hash2,0*forceflag); - if ( forceflag != 0 ) - bp->issued[i] = block->issued = now; - else bp->issued[i] = block->issued = saved; - flag++; - } //else printf("%d ",now - block->issued); - } - } - if ( flag != 0 && priority != 0 && laggard != 0 && coin->current == bp ) - printf("[%d] reissued.%d currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->hdrsi,flag,bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); - } - if ( bp == coin->current ) - return(counter); - } - for (i=0; in; i++) - { - if ( (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 ) - { - if ( block->fpipbits == 0 || block->fpos < 0 )// || block->RO.recvlen == 0 ) - { - if ( now > block->issued+lag ) - { - block->numrequests++; - if ( bp == coin->current ) - printf("[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickc",coin,bp,i,block->RO.hash2,0);//bp == coin->current && now > block->issued+lag); - bp->issued[i] = block->issued = now; - counter++; - if ( --max <= 0 ) - break; - } - } - } - else if ( block != 0 && block->fpipbits == 0 && bits256_nonz(bp->hashes[i]) != 0 && now > bp->issued[i]+lag ) - { - if ( bp == coin->current ) - printf("b[%d:%d].%x ",bp->hdrsi,i,block->fpipbits); - iguana_blockQ("kickd",coin,bp,i,bp->hashes[i],0);//bp == coin->current && now > bp->issued[i]+lag*3); - bp->issued[i] = now; - counter++; - } - else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+lag ) - { - if ( bp == coin->current ) - printf("i[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("kicke",coin,bp,i,bp->speculative[i],0); - bp->issued[i] = now; - counter++; - } - } - return(counter); - } - /*else if ( 0 && bp == coin->current && bp->speculativecache[bundlei] == 0 ) - { - char str[65]; printf("missing prev_block [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); - if ( block != 0 ) - { - block->RO.recvlen = 0; - block->fpipbits = 0; - block->fpos = -1; - } - else if ( now > bp->issued[bundlei]+13 ) - iguana_blockQ("missing",coin,bp,bundlei,bp->hashes[bundlei],1); - }*/ - } - /*else - { - char str[65],str2[65]; printf(" mismatched [%d:%d] %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2)); - //iguana_blockQ("missing",coin,0,-1,block->RO.hash2,1); - bp->issued[bundlei] = 0; - bp->blocks[bundlei] = 0; - memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); - OS_removefile(fname,0); - }*/ - /*if ( 0 && bp->numhashes < bp->n && bp->speculative != 0 ) - { - for (j=1; jnumspec&&jn; j++) - { - if ( (block= bp->blocks[j]) == 0 ) - { - if ( bits256_nonz(bp->hashes[j]) != 0 ) - block = iguana_blockfind(coin,bp->hashes[j]); - else if ( bits256_nonz(bp->speculative[j]) != 0 ) - { - if ( (block= iguana_blockfind(coin,bp->speculative[j])) == 0 ) - block = iguana_blockhashset(coin,-1,bp->speculative[j],1); - } - } - else if ( bits256_nonz(block->RO.prev_block) != 0 && iguana_blockstatus(coin,block) != 0 ) - continue; - prev = bp->blocks[j-1]; - //printf("[%d:%d] prev.%p nonz.%d speculative.%d block.%p\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bp->blocks[j]); - if ( block != 0 && bp->blocks[j] == 0 ) //prev != 0 && - { - //char str2[65]; printf("[%d:%d] prev.%p nonz.%d speculative.%d prev.%s vs %s ipbits.%x q.%d\n",bp->hdrsi,j,bp->blocks[j-1],bits256_nonz(bp->hashes[j]),bits256_nonz(bp->speculative[j]),bits256_str(str,prev->RO.hash2),bits256_str(str2,block->RO.prev_block),block->fpipbits,block->queued); - if ( iguana_blockstatus(coin,block) == 0 && bp->speculativecache[j] == 0 ) - { - if ( block->req != 0 ) - { - block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); - block->req = 0; - //printf("submit cached [%d:%d]\n",bp->hdrsi,j); - } - else if ( now > block->issued+10 ) - { - block->issued = now; - //printf("submit speculative [%d:%d]\n",bp->hdrsi,j); - iguana_blockQ("spec",coin,0,-1,block->RO.hash2,0); - } - } - } // else break; - } - }*/ - int32_t checki,hdrsi,havefile,missing,recvlen; char fname[1024]; FILE *fp; - static bits256 zero; - //if ( bp->speculative != 0 ) - { - now = (int32_t)time(NULL); - for (j=havefile=missing=0; jn; j++) - { - if ( bits256_nonz(bp->hashes[j]) != 0 ) - hash2 = bp->hashes[j]; - else if ( bp->speculative != 0 ) - hash2 = bp->speculative[j]; - if ( bits256_nonz(hash2) == 0 ) - { - missing++; - continue; - } - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,hash2,zero,1,0); - if ( 1 && (fp= fopen(fname,"rb")) != 0 ) - { - havefile++; - fclose(fp); - continue; - } - //if ( (block= bp->blocks[j]) != 0 && block->fpipbits != 0 && block->fpos >= 0 && block->RO.recvlen > 0 && bits256_nonz(block->RO.prev_block) != 0 ) - // continue; - missing++; - if ( bp->speculativecache[j] != 0 ) - { - block = iguana_blockfind(coin,bp->speculative[j]); - if ( block != 0 ) - block->queued = 1; - if ( bp->speculativecache[j] != 0 && block != 0 ) - xx else if ( bits256_nonz(bp->hashes[j]) != 0 ) - { - iguana_blockQ("currentstop",coin,bp,j,hash2,0); - - } - continue; - } - if ( bp == coin->current && (now > bp->issued[j]+3 || (rand() % 10) == 0) ) - { - fprintf(stderr,"-[%d:%d].%d ",bp->hdrsi,j,now-bp->issued[j]); - struct iguana_peer *addr; int32_t r; - if ( (rand() % 10) == 0 && (r= coin->peers.numranked) != 0 && (addr= coin->peers.ranked[rand() % r]) != 0 && addr->dead == 0 && addr->usock >= 0 ) - iguana_sendblockreqPT(coin,addr,bp,j,hash2,0); - else iguana_blockQ("currentstop",coin,bp,j,hash2,1); - //fprintf(stderr,"currentstop [%d:%d]\n",bp->hdrsi,j); - bp->issued[j] = now; - } - } - if ( bp == coin->current ) - fprintf(stderr,"[%d] check numcached.%d numhashes.%d numsaved.%d havefile.%d missing.%d\n",bp->hdrsi,bp->numcached,bp->numhashes,bp->numsaved,havefile,missing); - } - if ( bp->speculative != 0 && missing == 0 ) - { - hash2 = bp->hashes[0]; - for (i=1; in; i++) - { - /*if ( bits256_nonz(bp->speculative[i]) != 0 ) - block = iguana_blockfind(coin,bp->speculative[i]); - else if ( bits256_nonz(bp->hashes[i]) != 0 ) - block = iguana_blockfind(coin,bp->hashes[i]);*/ - if ( (block= bp->blocks[i]) == 0 || bits256_cmp(block->RO.prev_block,hash2) != 0 ) - { - char str[65],str2[65]; - printf("error with speculative prev at i.%d block.%p %s vs %s\n",i,block,bits256_str(str,bp->hashes[i]),bits256_str(str2,hash2)); - if ( block != 0 ) - { - checki = iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[i],zero,1,0); - if ( fname[0] != 0 ) - OS_removefile(fname,0); - printf(">>>>>>> block contents error at ht.%d (%s)\n",bp->bundleheight+i,fname); - //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); - block->fpipbits = 0; - block->fpos = -1; - block->queued = 0; - block->RO.recvlen = 0; - } - break; - } - hash2 = block->RO.hash2; - } - if ( i == bp->n && iguana_bundlefinalize(coin,bp,&coin->MEM,coin->MEMB) == 0 ) - { - //free(bp->speculative); - //bp->speculative = 0; - } - } - /*if ( bp->speculative != 0 && missing == 0 ) - { - if ( i == bp->n ) - { - printf("have complete speculative bundle!\n"); - for (i=1; in; i++) - { - if ( bits256_nonz(bp->speculative[i]) != 0 && bits256_nonz(bp->hashes[i]) != 0 ) - { - if ( (block= iguana_blockfind(coin,bp->speculative[i])) != 0 ) - { - block->bundlei = i; - block->hdrsi = bp->hdrsi; - bp->blocks[i] = block; - printf("bundlehashadd set.%d\n",i); - iguana_bundlehash2add(coin,0,bp,i,bp->speculative[i]); - } - } - } - } - }*/ - //bp->rank = 0; - /*if ( bp->speculative != 0 )//&& bp == coin->current ) - { - now = (uint32_t)time(NULL); - for (i=1; inumspec&&in; i++) - { - if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) != 0 ) - { - if ( (block= bp->blocks[i]) == 0 && bp->speculativecache[i] == 0 && now > bp->issued[i]+60 ) - { - //printf("speculative.[%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculative",coin,bp,-i,bp->speculative[i],0);//now > bp->issued[i]+60); - bp->issued[i] = now; - continue; - } - } - else if ( 0 && (block= bp->blocks[i]) != 0 && bp->speculativecache[i] == 0 && block->fpipbits == 0 && now > bp->issued[i]+60 ) - { - printf("speculativeB.[%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculativeB",coin,bp,i,block->RO.hash2,1); - continue; - } - if ( bits256_nonz(bp->speculative[i]) != 0 && now > bp->issued[i]+13 ) - { - //printf("speculativeC [%d:%d]\n",bp->hdrsi,i); - iguana_blockQ("speculativeC",coin,bp,-i,bp->speculative[i],0); - bp->issued[i] = now; - } - } - }*/ - if ( 0 && block->newtx != 0 ) - { - if ( (prev= iguana_blockfind(coin,block->RO.prev_block)) == 0 ) - prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); - width = coin->chain->bundlesize; - while ( coin->active != 0 && prev != 0 && width-- > 0 ) - { - if ( prev->fpipbits == 0 || prev->RO.recvlen == 0 || prev->fpos < 0 || bits256_nonz(prev->RO.prev_block) == 0 ) - { - //printf("width.%d auto prev newtx %s ht.%d\n",width,bits256_str(str,prev->RO.hash2),prev->height); - prev->newtx = 1; - iguana_blockQ("autoprev",coin,0,-1,prev->RO.hash2,0); - } - tmpblock = prev; - if ( bits256_nonz(prev->RO.prev_block) != 0 ) - { - if ( (prev = iguana_blockhashset(coin,-1,prev->RO.prev_block,1)) != 0 ) - prev->newtx = 1; - prev->hh.next = tmpblock; - if ( prev->mainchain != 0 ) - { - while ( tmpblock != 0 && _iguana_chainlink(coin,tmpblock) != 0 ) - { - printf("NEWHWM.%d\n",tmpblock->height); - tmpblock = tmpblock->hh.next; - } - break; - } - } else prev = 0; - } - } - /*else if ( bp != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) - { - if ( bundlei > 0 && bits256_nonz(bp->hashes[bundlei+1]) != 0 ) - { - if ( (block= iguana_blockfind(coin,bp->hashes[bundlei+1])) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) - { - bp->hashes[bundlei] = block->RO.prev_block; - printf("reqblock [%d:%d]\n",bp->hdrsi,bundlei); - iguana_blockQ("reqblocks1",coin,bp,bundlei,bp->hashes[bundlei],0); - } - } - }*/ - else if ( 0 && bp != 0 && time(NULL) > bp->hdrtime+10 && bp->speculative == 0 ) - { - char str[65]; - //printf("MAINCHAIN gethdr %d %s\n",bp->bundleheight,bits256_str(str,bp->hashes[0])); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - bp->hdrtime = (uint32_t)time(NULL); - } - /*if ( block != 0 && bundlei > 0 && (prev= iguana_blockfind(coin,block->RO.prev_block)) != 0 ) - { - if ( bp->bundleheight+bundlei-1 >= coin->blocks.hwmchain.height ) - { - printf("prev issue.%s\n",bits256_str(str,prev->RO.hash2)); - iguana_blockQ("previssue",coin,bp,bundlei-1,prev->RO.hash2,0); - } - }*/ - /*if ( 0 && (bp= coin->current) != 0 && bp->numsaved < bp->n ) - { - for (hdrsi=numissued=0; hdrsiMAXBUNDLES && coin->current->hdrsi+hdrsibundlescount && numissued<100; hdrsi++) - { - if ( (bp= coin->bundles[hdrsi + coin->current->hdrsi]) == 0 ) - continue; - if ( (addr= coin->peers.ranked[hdrsi]) == 0 || addr->msgcounts.verack == 0 ) - continue; - for (bundlei=n=flag=0; bundlein; bundlei++) - if ( (block= bp->blocks[bundlei]) != 0 ) - { - if ( bits256_nonz(block->RO.hash2) > 0 && block->fpos >= 0 ) - n++; - else if ( block->fpipbits == 0 || time(NULL) > block->issued+60 ) - { - block->issued = (uint32_t)time(NULL); - //iguana_sendblockreqPT(coin,addr,bp,bundlei,block->RO.hash2,0); - iguana_blockQ("reqblocks",coin,bp,bundlei,block->RO.hash2,0); - flag++; - if ( ++numissued > 100 ) - break; - } - } - if ( 0 && flag != 0 ) - printf("issued %d priority blocks for %d current.[%d] have %d blocks emit.%u\n",flag,hdrsi,bp->hdrsi,n,bp->emitfinish); - } - }*/ - /*else if ( iguana_blockfind(coin,bp->hashes[bundlei]) == 0 ) - { - //if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) - // { - // printf("next %d\n",coin->blocks.hwmchain.height+1); - // iguana_blockQ(coin,bp,bundlei,bp->hashes[bundlei],0); - // } - // else if ( bp->speculative != 0 && (bits256_cmp(bp->hashes[bundlei],bp->speculative[bundlei]) != 0 || (rand() % 100) == 0) ) - { - if ( time(NULL) > bp->issued[bundlei]+30 && iguana_blockfind(coin,bp->speculative[bundlei]) == 0 ) - { - bp->hashes[bundlei] = bp->speculative[bundlei]; - struct iguana_bloominds bit = iguana_calcbloom(bp->speculative[bundlei]); - if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) - iguana_bloomset(coin,&bp->bloom,0,bit); - printf("speculative next %d\n",coin->blocks.hwmchain.height+1); - iguana_blockQ("speculativenext",coin,0,-1,bp->speculative[bundlei],0); - bp->issued[bundlei] = (uint32_t)time(NULL); - } - } - }*/ - /*else if ( 0 && (bp= coin->bundles[--hdrsi]) != 0 ) - { - char str[65]; - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - }*/ - /*double threshold,lag = OS_milliseconds() - coin->backstopmillis; - threshold = (10 + coin->longestchain - coin->blocksrecv); - if ( threshold < 1 ) - threshold = 1.; - if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) - threshold = (bp->avetime + coin->avetime) * .5; - else threshold = coin->avetime; - threshold *= 100. * sqrt(threshold) * .000777;*/ - /*for (i=n=0; in; i++) - { - if ( lag < coin->MAXSTUCKTIME ) - { - if ( bits256_nonz(bp->hashes[i]) != 0 ) - iguana_blockQ("stuck",coin,bp,i,bp->hashes[i],0); - } - if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 && bp->speculativecache[i] == 0 ) - { - printf("s.[%d:%d] ",bp->hdrsi,i); - iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,0); - iguana_blockQ("stuck",coin,bp,i,block->RO.hash2,1); - if ( coin->peers.numranked > 8 && (addr= coin->peers.ranked[n % 8]) != 0 && addr->usock >= 0 && addr->dead == 0 && addr->msgcounts.verack != 0 ) - { - if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&block->RO.hash2,1)) > 0 ) - { - printf("%s, ",addr->ipaddr); - iguana_send(coin,addr,serialized,len); - } - } - block->issued = (uint32_t)time(NULL); - n++; - } - } - if ( n > 0 ) - printf("issued %d priority requests [%d] to unstick stuckiters.%d lag.%d\n",n,bp->hdrsi,coin->stuckiters,lag);*/ - /*if ( 0 && n >= coin->chain->bundlesize ) - { - blockhashes = malloc(sizeof(*blockhashes) * coin->chain->bundlesize); - for (i=0; ichain->bundlesize; i++) - blockhashes[i] = blocks[i].RO.hash2; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 ) - { - blockhashes[0] = bp->hashes[0]; - vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); - if ( bits256_cmp(allhash,bp->allhash) == 0 ) - { - if ( bp->queued != 0 ) - bp->queued = 0; - if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) - { - free(blockhashes); - return(req); - } - } - } - } - free(blockhashes); - }*/ - - - /*void iguana_patch(struct iguana_info *coin,struct iguana_block *block) - { - int32_t i,j,origheight,height; struct iguana_block *prev,*next; struct iguana_bundle *bp; - prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); - block->hh.prev = prev; - if ( prev != 0 ) - { - if ( prev->mainchain != 0 ) - { - prev->hh.next = block; - if ( memcmp(block->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) - _iguana_chainlink(coin,block); - if ( (next= block->hh.next) != 0 && bits256_nonz(next->RO.hash2) > 0 ) - next->height = block->height + 1; - } - else if ( 0 && block->height < 0 ) - { - for (i=0; i<1; i++) - { - if ( (prev= prev->hh.prev) == 0 ) - break; - if ( prev->mainchain != 0 && prev->height >= 0 ) - { - j = i; - origheight = (prev->height + i + 2); - prev = block->hh.prev; - height = (origheight - 1); - while ( i > 0 && prev != 0 ) - { - if ( prev->mainchain != 0 && prev->height != height ) - { - printf("mainchain height mismatch j.%d at i.%d %d != %d\n",j,i,prev->height,height); - break; - } - prev = prev->hh.prev; - height--; - } - if ( i == 0 ) - { - //printf("SET HEIGHT.%d j.%d\n",origheight,j); - if ( (bp= coin->bundles[origheight / coin->chain->bundlesize]) != 0 ) - { - iguana_bundlehash2add(coin,0,bp,origheight % coin->chain->bundlesize,block->RO.hash2); - block->height = origheight; - block->mainchain = 1; - prev = block->hh.prev; - prev->hh.next = block; - } - } //else printf("break at i.%d for j.%d origheight.%d\n",i,j,origheight); - break; - } - } - } - } - }*/ - -#ifdef newstuff - int32_t iguana_realtime_update(struct iguana_info *coin) - { - double startmillis0; static double totalmillis0; static int32_t num0; - struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,i,n,flag=0; bits256 hash2; struct iguana_peer *addr; - struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR; - if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi == coin->balanceswritten && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n && (coin->RTheight < coin->blocks.hwmchain.height-3 || time(NULL) > bp->lastRT) )//&& coin->blocks.hwmchain.height >= coin->longestchain-1 && coin->RTramchain.H.data->numblocks < bp->n ) - { - if ( bits256_cmp(coin->RThash1,bp->hashes[1]) != 0 ) - coin->RThash1 = bp->hashes[1]; - bp->lastRT = (uint32_t)time(NULL); - if ( coin->peers.numranked > 0 && time(NULL) > coin->RThdrstime+10 ) - { - iguana_RThdrs(coin,bp,coin->peers.numranked); - coin->RThdrstime = bp->lastRT; - for (i=0; ipeers.numranked; i++) - { - if ( (addr= coin->peers.ranked[i]) != 0 ) - printf("%d ",addr->numRThashes); - } - printf("RTheaders\n"); - } - iguana_RTramchainalloc(coin,bp); - bp->isRT = 1; - while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height ) - { - //printf("RT.%d vs hwm.%d starti.%d bp->n %d\n",coin->RTheight,coin->blocks.hwmchain.height,starti,bp->n); - dest = &coin->RTramchain; - B = (void *)(long)((long)rdata + rdata->Boffset); - bundlei = (coin->RTheight % coin->chain->bundlesize); - if ( (block= bp->blocks[bundlei]) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) - { - iguana_blocksetcounters(coin,block,dest); - startmillis0 = OS_milliseconds(); - if ( iguana_ramchainfile(coin,dest,&blockR,bp,bundlei,block) == 0 ) - { - for (i=bundlei; in; i++) - { - block = iguana_bundleblock(coin,&hash2,bp,bundlei+i); - if ( i == 0 || (bits256_nonz(hash2) != 0 && (block == 0 || block->txvalid == 0)) ) - { - uint8_t serialized[512]; int32_t len; - //char str[65]; printf("RT error [%d:%d] %s %p\n",bp->hdrsi,i,bits256_str(str,hash2),block); - addr = coin->peers.ranked[rand() % 8]; - if ( addr != 0 && (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) - iguana_send(coin,addr,serialized,len); - coin->RTgenesis = 0; - } - break; - } - return(-1); - } else iguana_ramchain_free(coin,&blockR,1); - B[bundlei] = block->RO; - totalmillis0 += (OS_milliseconds() - startmillis0); - num0++; - flag++; - coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; - coin->RTheight++; - printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); - coin->RTramchain.H.data->numblocks = bundlei + 1; - } else break; - } - } - n = 0; - if ( dest != 0 && flag != 0 && coin->RTheight >= coin->longestchain ) - { - while ( block != 0 ) - { - if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 ) - { - printf("blockhash error at %d\n",coin->RTheight-n-1); - break; - } - block = iguana_blockfind("RTupdate",coin,block->RO.prev_block); - n++; - if ( coin->RTgenesis != 0 && n >= bp->n ) - break; - } - if ( coin->RTgenesis == 0) - { - if ( n == coin->RTheight ) - { - printf("RTgenesis verified\n"); - coin->RTgenesis = (uint32_t)time(NULL); - } else printf("RTgenesis failed to verify\n"); - } - if ( coin->RTgenesis != 0 ) - { - struct iguana_ramchain R; struct iguana_ramchaindata RDATA; - iguana_rdataset(&R,&RDATA,dest); - bp->ramchain = coin->RTramchain; - printf("ramchainiterate.[%d] ave %.2f micros, total %.2f seconds starti.%d num.%d\n",num0,(totalmillis0*1000.)/num0,totalmillis0/1000.,coin->RTstarti,coin->RTheight%bp->n); - if ( iguana_spendvectors(coin,bp,dest,coin->RTstarti,coin->RTheight%bp->n,0) < 0 ) - { - printf("RTutxo error -> RTramchainfree\n"); - iguana_RTramchainfree(coin); - return(-1); - } - else - { - coin->RTstarti = (coin->RTheight % bp->n); - printf("spendvectors calculated to %d\n",coin->RTheight); - iguana_convert(coin,bp);//,dest); - printf("spendvectors converted to %d\n",coin->RTheight); - } - iguana_rdatarestore(&R,&RDATA,dest); - } - } - if ( dest != 0 && flag != 0 ) - printf("<<<< flag.%d RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",flag,coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); - return(flag); - } - - int32_t iguana_blocksmissing(struct iguana_info *coin,int32_t *nonzp,uint8_t missings[IGUANA_MAXBUNDLESIZE/8+1],bits256 hashes[],double mult,struct iguana_bundle *bp,int32_t capacity) - { - int32_t i,lag,nonz=0,m = 0; double aveduration; bits256 hash2; struct iguana_block *block; uint32_t now = (uint32_t)time(NULL); - if ( bp->durationscount != 0 ) - aveduration = (double)bp->totaldurations / bp->durationscount; - else aveduration = IGUANA_DEFAULTLAG/3 + 1; - aveduration *= mult; - lag = aveduration; - if ( lag > IGUANA_DEFAULTLAG ) - lag = IGUANA_DEFAULTLAG * 8; - memset(missings,0,IGUANA_MAXBUNDLESIZE/8+1); - if ( bp->emitfinish == 0 || bp->ramchain.H.data == 0 ) - { - for (i=0; in; i++) - { - if ( bp->speculativecache[i] != 0 ) - { - //printf("[%d:%d].havec ",bp->hdrsi,i); - continue; - } - if ( (block= iguana_bundleblock(coin,&hash2,bp,i)) != 0 ) - { - if ( block->fpipbits != 0 && block->txvalid != 0 && block->fpos >= 0 && block->RO.recvlen != 0 && (bp->bundleheight+i == 0 || bits256_nonz(block->RO.prev_block) != 0) ) - { - //printf("[%d:%d].have ",bp->hdrsi,i); - continue; - } - } - if ( bits256_nonz(hash2) != 0 ) - { - if ( now > bp->issued[i]+lag ) - { - if ( nonz < capacity ) - { - if ( hashes != 0 ) - hashes[nonz] = hash2; - nonz++; - } - } - } - SETBIT(missings,i); - m++; - } - } //else printf("[%d] emitfinish.%u\n",bp->hdrsi,bp->emitfinish); - *nonzp = nonz; - //printf("missings.[%d] m.%d nonz.%d spec.%p[%d]\n",bp->hdrsi,m,nonz,bp->speculative,bp->numspec); - return(m); - } - - /*int32_t iguana_nextnonz(uint8_t *missings,int32_t i,int32_t max) - { - for (; i 0 ) - { - *capacityp = capacity; - if ( (n= iguana_blocksmissing(coin,&avail,missings,hashes,mult,bp,capacity < max ? capacity : max)) > 0 && avail > 0 ) - { - *missingp = n; - printf("n.%d avail.%d numpeers.%d\n",n,avail,numpeers); - for (i=0; i0; i++) - { - if ( (addr= peers[i]) != 0 && addr->usock >= 0 && addr->dead == 0 && (c= (coin->MAXPENDINGREQUESTS - addr->pendblocks)) > 0 ) - { - if ( c+m > max ) - c = max - m; - if ( avail < c ) - c = avail; - printf("i.%d c.%d avail.%d m.%d max.%d\n",i,c,avail,m,max); - if ( c > 0 && (numsent= iguana_sendhashes(coin,addr,MSG_BLOCK,&hashes[m],c,priority)) > 0 ) - { - for (j=0; jn)) < bp->n ) - { - if ( (block= iguana_bundleblock(coin,&hash2,bp,nonz)) != 0 ) - { - hash2 = block->RO.hash2; - if ( addr->addrind < 0x100 ) - block->peerid = addr->addrind; - else block->peerid = 0; - block->issued = now; - } - bp->issued[nonz] = now; - //char str[65]; printf("issue.[%d:%d] %s %u\n",bp->hdrsi,nonz,bits256_str(str,hash2),now); - nonz++; - } else printf("bundlerequests unexpected nonz.%d c.%d m.%d n.%d numsent.%d i.%d\n",nonz,c,m,n,numsent,i); - } - m += numsent; - avail -= numsent; - } - } - } - } //else printf("err avail.%d n.%d\n",avail,n); - } //else printf("numpeers.%d\n",numpeers); - return(m); - }*/ - /*missing = iguana_blocksmissing(coin,&avail,missings,0,mult,bp,0); - /*if ( coin->current != 0 ) - { - if ( (dist= bp->hdrsi - coin->current->hdrsi) < coin->MAXBUNDLES && (bp == coin->current || netBLOCKS < 50*bp->n) ) - { - iguana_unstickhdr(coin,bp,60); - if ( bp->numcached > bp->n - (coin->MAXBUNDLES - dist) ) - priority += 1 + (bp == coin->current); - if ( bp == coin->current || queue_size(&coin->priorityQ) < (2 * bp->n)/(dist+1) ) - { - //printf("[%d] dist.%d numcached.%d priority.%d\n",bp->hdrsi,dist,bp->numcached,priority); - //iguana_bundleissuemissing(coin,bp,missings,((rand() % 100) == 0 && bp == coin->current)*3); - priority = ((rand() % 20) == 0 && bp == coin->current) * 3; - if ( (n= iguana_bundlerequests(coin,missings,&bp->origmissings,&tmp,mult,bp,priority)) > 0 ) - { - bp->numissued += n; - bp->missingstime = (uint32_t)time(NULL); - } - return(aveduration); - } - } - }*/ - //printf("helper.%d\n",helperid); - /*if ( ((ptr= queue_dequeue(&emitQ,0)) != 0 || (ptr= queue_dequeue(&helperQ,0)) != 0) ) - { - printf("unexpected emitQ or helperQ\n"); - exit(-1); - if ( ptr->bp != 0 && (coin= ptr->coin) != 0 && coin->active != 0 ) - { - idle = 0; - coin->helperdepth++; - iguana_helpertask(fp,&MEM,MEMB,ptr); - coin->helperdepth--; - flag++; - } - myfree(ptr,ptr->allocsize); - }*/ - if ( 0 && (ptr= queue_dequeue(&spendvectorsQ,0)) != 0 ) - { - //printf("spendvectorsQ size.%d\n",queue_size(&spendvectorsQ)); - coin = ptr->coin; - if ( (bp= ptr->bp) != 0 && coin != 0 ) - { - if ( coin->polltimeout < polltimeout ) - polltimeout = coin->polltimeout; - //printf("call spendvectors.%d\n",bp->hdrsi); - if ( coin->PREFETCHLAG > 0 ) - { - iguana_ramchain_prefetch(coin,&bp->ramchain,0); - if ( 0 && bp->hdrsi > 0 ) - iguana_prefetch(coin,bp,bp->hdrsi-1,1); - } - if ( (retval= iguana_spendvectors(coin,bp,&bp->ramchain,0,bp->n,0)) >= 0 ) - { - flag++; - if ( retval > 0 ) - { - printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); - } // else printf("null retval from iguana_spendvectors.[%d]\n",bp->hdrsi); - bp->utxofinish = (uint32_t)time(NULL); - iguana_balancesQ(coin,bp); - } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); - } - else if ( coin->active != 0 ) - printf("helper missing param? %p %p\n",coin,bp); - myfree(ptr,ptr->allocsize); - } - void iguana_spendvectorsQ(struct iguana_info *coin,struct iguana_bundle *bp) - { - struct iguana_helper *ptr; - bp->queued = (uint32_t)time(NULL); - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 's'; - ptr->starttime = (uint32_t)time(NULL); - queue_enqueue("spendvectorsQ",&spendvectorsQ,&ptr->DL,0); - } - - void iguana_convertQ(struct iguana_info *coin,struct iguana_bundle *bp) - { - struct iguana_helper *ptr; - bp->queued = (uint32_t)time(NULL); - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 's'; - ptr->starttime = (uint32_t)time(NULL); - queue_enqueue("convertQ",&convertQ,&ptr->DL,0); - } - - void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) - { - struct iguana_helper *ptr; - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 'B'; - ptr->starttime = (uint32_t)time(NULL); - ptr->timelimit = 0; - if ( bp->balancefinish == 0 ) - bp->balancefinish = 1; - coin->pendbalances++; - //printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); - queue_enqueue("balancesQ",&balancesQ,&ptr->DL,0); - } - - /*int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_helper *ptr) - { - struct iguana_info *coin; struct iguana_peer *addr; struct iguana_bundle *bp,*nextbp; - addr = ptr->addr; - if ( (coin= ptr->coin) != 0 ) - { - if ( (bp= ptr->bp) != 0 ) - { - if ( 0 && ptr->type == 'M' ) - { - if ( (nextbp= ptr->nextbp) != 0 ) - { - bp->mergefinish = nextbp->mergefinish = (uint32_t)time(NULL); - if ( iguana_bundlemergeHT(coin,mem,memB,bp,nextbp,ptr->starttime) < 0 ) - bp->mergefinish = nextbp->mergefinish = 0; - } - } - else if ( ptr->type == 'B' ) - { - printf("helper bundleiters\n"); - iguana_bundleiters(coin,mem,memB,bp,ptr->timelimit); - } - else if ( ptr->type == 'E' ) - { - coin->emitbusy++; - if ( iguana_bundlesaveHT(coin,mem,memB,bp,ptr->starttime) == 0 ) - { - //fprintf(stderr,"emitQ coin.%p bp.[%d]\n",ptr->coin,bp->bundleheight); - bp->emitfinish = (uint32_t)time(NULL) + 1; - coin->numemitted++; - } else bp->emitfinish = 0; - coin->emitbusy--; - } - } else printf("no bundle in helperrequest\n"); - } else printf("no coin in helperrequest\n"); - return(0); - }*/ - - void iguana_mergeQ(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_bundle *nextbp) - { - struct iguana_helper *ptr; - ptr = mycalloc('i',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->nextbp = nextbp; - ptr->type = 'M'; - ptr->starttime = (uint32_t)time(NULL); - //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); - queue_enqueue("helperQ",&helperQ,&ptr->DL,0); - } - if ( (bp= coin->current) != 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize ) - { - n = bp->hdrsi; - for (j=0; jbundles[j]) == 0 || bp->emitfinish <= 1 ) - break; - } - if ( j == n ) - { - for (j=0; jbundles[j]) == 0 || (bp->startutxo == 0 && bp->utxofinish == 0) ) - break; - } - if ( j != n ) - { - for (j=0; jbundles[j]) != 0 ) - { - //printf("bundleQ.[%d]\n",j); - bp->balancefinish = bp->startutxo = 0; - bp->utxofinish = 1; - iguana_bundleQ(coin,bp,1000); - } - } - } //else printf("skip A j.%d vs n.%d\n",j,n); - } //else printf("skip j.%d vs n.%d\n",j,n); - } //else printf("skip hdrsi.%d vs %d\n",coin->current->hdrsi,coin->longestchain/coin->chain->bundlesize); - n = queue_size(&balancesQ); - for (iter=0; iterbp; - if ( ptr->coin != coin || bp == 0 || time(NULL) < bp->nexttime ) - { - if ( 0 && bp != 0 ) - printf("skip.%d lag.%ld\n",bp->hdrsi,bp->nexttime-time(NULL)); - //bp->nexttime = (uint32_t)time(NULL); - queue_enqueue("balanceQ",&balancesQ,&ptr->DL,0); - continue; - } - flag++; - if ( coin != 0 ) - { - iguana_balancecalc(coin,bp,bp->bundleheight,bp->bundleheight+bp->n-1); - if ( coin->active == 0 ) - { - printf("detected autopurge after account filecreation. restarting.%s\n",coin->symbol); - coin->active = 1; - } - } - myfree(ptr,ptr->allocsize); - } - } - - int32_t iguana_RTutxo(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *RTramchain,int32_t bundlei) - { - struct iguana_txid *T; int32_t height,spendind,txidind,j,k; bits256 prevhash; - struct iguana_bundle *spentbp; struct iguana_unspent *spentU,*u; - struct iguana_ramchaindata *RTdata,*rdata; - uint32_t spent_unspentind,now; struct iguana_blockRO *B; struct iguana_spend *S,*s; - if ( (RTdata= RTramchain->H.data) == 0 || RTdata->numspends < 1 ) - { - printf("iguana_RTutxo null data or no spends %p\n",RTramchain->H.data); - return(-1); - } - B = (void *)(long)((long)RTdata + RTdata->Boffset); - S = (void *)(long)((long)RTdata + RTdata->Soffset); - T = (void *)(long)((long)RTdata + RTdata->Toffset); - txidind = B[bundlei].firsttxidind; - spendind = B[bundlei].firstvin; - height = bp->bundleheight + bundlei; - now = (uint32_t)time(NULL); - //printf("RTutxo.[%d:%d] txn_count.%d\n",bp->hdrsi,bundlei,B[bundlei].txn_count); - for (j=0; jexternal != 0 && s->prevout >= 0 ) - { - continue; - double startmillis = OS_milliseconds(); static double totalmillis; static int32_t num; - if ( (spentbp= iguana_externalspent(coin,&prevhash,&spent_unspentind,RTramchain,bp->hdrsi,s,2)) == 0 || spent_unspentind == 0 || spent_unspentind >= spentbp->ramchain.H.data->numunspents || spentbp->hdrsi < 0 || spentbp->hdrsi >= bp->hdrsi || spentbp == bp ) - { - char str[65]; - printf("RTutxo: unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp!=0?spentbp->hdrsi:-1,spent_unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); - return(-1); - } - totalmillis += (OS_milliseconds() - startmillis); - if ( (++num % 10000) == 0 ) - printf("externalspents.[%d] ave %.2f micros, total %.2f seconds\n",num,(totalmillis*1000.)/num,totalmillis/1000.); - rdata = spentbp->ramchain.H.data; - if ( 0 && coin->PREFETCHLAG > 0 && now >= spentbp->lastprefetch+coin->PREFETCHLAG ) - { - printf("RT prefetch[%d] from.[%d] lag.%d bundlei.%d numspends.%d of %d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch,bundlei,spendind,RTramchain->H.spendind); - iguana_ramchain_prefetch(coin,&spentbp->ramchain,2); - spentbp->lastprefetch = now; - } - } - else if ( s->prevout >= 0 ) - { - spentbp = bp; - rdata = RTramchain->H.data; - if ( s->spendtxidind != 0 && s->spendtxidind < RTdata->numtxids ) - { - spent_unspentind = T[s->spendtxidind].firstvout + s->prevout; - //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); - } - else - { - printf("RTutxo txidind overflow %u vs %d\n",s->spendtxidind,RTdata->numtxids); - return(-1); - } - } - else continue; // coinbase always already spent - if ( spentbp != 0 && rdata != 0 && spent_unspentind != 0 && spent_unspentind < rdata->numunspents ) - { - double startmillis = OS_milliseconds(); static double totalmillis; static int32_t num; - spentU = (void *)(long)((long)rdata + rdata->Uoffset); - u = &spentU[spent_unspentind]; - if ( iguana_volatileupdate(coin,1,spentbp == bp ? RTramchain : &spentbp->ramchain,spentbp->hdrsi,spent_unspentind,u->pkind,u->value,spendind,height) < 0 ) - return(-1); - totalmillis += (OS_milliseconds() - startmillis); - if ( (++num % 10000) == 0 ) - printf("volatile.[%d] ave %.2f micros, total %.2f seconds\n",num,(totalmillis*1000.)/num,totalmillis/1000.); - } - else - { - printf("RTutxo error spentbp.%p u.%u vs %d\n",spentbp,spent_unspentind,rdata->numunspents); - return(-1); - } - } - } - return(0); - } - - /*int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) - { - int32_t retval=-1,i,n,flag = 0; - if ( bp->balancefinish > 1 ) - { - printf("make sure DB files have this bp.%d\n",bp->hdrsi); - iguana_validateQ(coin,bp); - return(flag); - } - bp->nexttime = (uint32_t)time(NULL) + 1; - if ( bp != 0 && coin != 0 ) - { - if ( coin->origbalanceswritten <= 1 && coin->spendvectorsaved == 0 ) - { - for (i=0; ibundlescount-1; i++) - { - if ( coin->bundles[i] == 0 || coin->bundles[i]->tmpspends == 0 ) - break; - } - if ( i == coin->bundlescount-1 && bp->tmpspends != 0 && bp->ramchain.H.data != 0 && (n= bp->ramchain.H.data->numspends) != 0 && bp->converted == 0 ) - { - iguana_convertQ(coin,bp); - retval = 0; - } - else if ( bp->converted == 0 ) - { - for (i=0; ibundlescount-1; i++) - { - if ( coin->bundles[i] == 0 || coin->bundles[i]->utxofinish <= 1 ) - break; - } - if ( i == coin->bundlescount-1 ) - { - printf("must be restart after all the spendvectors are saved\n"); - coin->spendvectorsaved = (uint32_t)time(NULL); - } - } - } else retval = iguana_balancenormal(coin,bp,startheight,endheight); - if ( retval < 0 ) - { - //printf("third case.%d utxo.%u balance.%u prev.%u\n",bp->hdrsi,bp->utxofinish,bp->balancefinish,prevbp!=0?prevbp->utxofinish:-1); - coin->pendbalances--; - iguana_balancesQ(coin,bp); - } - else - { - iguana_validateQ(coin,bp); - flag++; - } - } - return(flag); - }*/ - - /*int32_t iguana_balancenormal(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight) - { - uint32_t starttime; int32_t j=0,n; struct iguana_bundle *prevbp; - n = coin->bundlescount - 1; - for (j=0; jbundles[j]) == 0 ) - break; - if ( prevbp->utxofinish <= 1 || (j < bp->hdrsi && prevbp->balancefinish <= 1) ) - break; - } - //printf("B [%d] j.%d u.%u b.%u\n",bp->hdrsi,j,bp->utxofinish,bp->balancefinish); - if ( (j == n || bp->hdrsi == 0) && bp->bundleheight+bp->n <= coin->blocks.hwmchain.height && bp->utxofinish > 1 && bp->balancefinish <= 1 ) - { - bp->balancefinish = 1; - if ( bp->hdrsi >= coin->balanceswritten ) - { - //printf("balancecalc for %d when %d\n",bp->hdrsi,coin->balanceswritten); - starttime = (uint32_t)time(NULL); - for (j=0; j<=bp->hdrsi; j++) - iguana_allocvolatile(coin,&coin->bundles[j]->ramchain); - if ( iguana_balancegen(coin,bp,startheight,endheight) < 0 ) - { - printf("GENERATE BALANCES.%d ERROR ht.%d\n",bp->hdrsi,bp->bundleheight); - exit(-1); - } - printf("GENERATED BALANCES.%d for ht.%d duration %d seconds, (%d %d).%d\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - (uint32_t)starttime,bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize-1,bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1); - coin->balanceswritten++; - } - bp->balancefinish = (uint32_t)time(NULL); - bp->queued = 0; - if ( bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize-1 ) - { - printf("TRIGGER FLUSH %d vs %d\n",bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize); - sleep(1); - if ( time(NULL) > coin->startutc+10 && bp->hdrsi >= coin->blocks.hwmchain.height/coin->chain->bundlesize-1 ) - { - if ( iguana_balanceflush(coin,bp->hdrsi,3) > 0 ) - printf("balanceswritten.%d flushed bp->hdrsi %d vs %d coin->longestchain/coin->chain->bundlesize\n",coin->balanceswritten,bp->hdrsi,coin->longestchain/coin->chain->bundlesize); - } else printf("TRIGGER cancelled %d vs %d\n",bp->hdrsi,coin->longestchain/coin->chain->bundlesize-1); - } - return(0); - } - return(-1); - }*/ - /*if ( iguana_spendvectors(coin,bp,dest,starti,coin->RTheight%bp->n,0) < 0 ) - { - printf("RTutxo error -> RTramchainfree\n"); - iguana_RTramchainfree(coin); - return(-1); - } else printf("spendvectors calculated to %d\n",coin->RTheight);*/ - /*while ( block != 0 ) - { - if ( bits256_cmp(iguana_blockhash(coin,coin->RTheight-n-1),block->RO.hash2) != 0 ) - { - printf("blockhash error at %d\n",coin->RTheight-n-1); - break; - } - block = iguana_blockfind("RTupdate",coin,block->RO.prev_block); - n++; - if ( coin->RTgenesis != 0 && n >= bp->n ) - break; - }*/ - //if ( coin->RTHASHMEM.ptr == 0 ) - // iguana_meminit(&coin->RTHASHMEM,"RTHASH",0,1024L*1024L*1024L,0); - if ( coin->PREFETCHLAG > 0 ) - { - //iguana_ramchain_prefetch(coin,&coin->RTramchain,0); - //iguana_prefetch(coin,bp,coin->bundlescount,1); - } - - void iguana_prefetch(struct iguana_info *coin,struct iguana_bundle *bp,int32_t width,int32_t flags) - { - int32_t i; struct iguana_bundle *spentbp; uint32_t starttime = (uint32_t)time(NULL); - if ( bp->hdrsi > width ) - { - //printf("start prefetch.%d for [%d]\n",width,bp->hdrsi); - for (i=1; ibundles[bp->hdrsi - i]) != 0 ) - { - iguana_ramchain_prefetch(coin,&spentbp->ramchain,flags); - spentbp->lastprefetch = starttime; - } - } - //printf("end prefetch.%d for [%d] elapsed %d\n",width,bp->hdrsi,(uint32_t)time(NULL)-starttime); - } - } - /*if ( (fp= fopen(fname,"r")) == 0 ) - { - sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); - OS_compatible_path(fname); - fp = fopen(fname,"r"); - } - else if ( 0 && iter == 1 ) - { - sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); - OS_compatible_path(fname); - if ( (fp2= fopen(fname,"r")) != 0 ) - { - fseek(fp,0,SEEK_END), fseek(fp2,0,SEEK_END); - if ( ftell(fp2) > ftell(fp) ) - { - fclose(fp); - fp = fp2; - } - else - { - fclose(fp2); - printf("%s is not used as tmp version is bigger\n",fname); - } - } - }*/ - /*else if ( bp->emitfinish != 0 ) - { - if ( bp->utxofinish > 1 ) - { - if ( bp->balancefinish == 0 ) - { - //bp->queued = 0; - iguana_balancesQ(coin,bp); - } - return(1); - } - if ( bp->emitfinish > 1 ) - { - if ( (retval= iguana_bundlefinish(coin,bp)) > 0 ) - { - //printf("moved to balancesQ.%d bundleiters.%d\n",bp->hdrsi,bp->bundleheight); - //bp->queued = 0; - return(0); - } //else printf("finish incomplete.%d\n",bp->hdrsi); - } - }*/ - //fprintf(stderr,"RO %p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->H.txidind,ramchain->pkind); - /*if ( 0 && u->scriptpos != 0 && u->scriptlen > 0 )//&& u->scriptlen <= sizeof(u->script) ) - { - scriptptr = &Kspace[u->scriptpos]; - if ( memcmp(script,scriptptr,u->scriptlen) != 0 ) - { - int32_t i; - for (i=0; iscriptlen; i++) - printf("%02x",scriptptr[i]); - printf(" u->script\n"); - for (i=0; iscriptlen; i++) - printf("%02x",script[i]); - printf(" script\n"); - printf("[%d] u%d script compare error.%d vs %d\n",bp->hdrsi,unspentind,scriptlen,u->scriptlen); - return(0); - } //else printf("SCRIPT.%d MATCHED!\n",u->scriptlen); - } // else would need to get from HDD to verify*/ - - /* - //char *hashstr,*txidstr,*coinaddr,*txbytes,rmd160str[41],str[65]; int32_t len,height,i,n,valid = 0; - //cJSON *addrs,*retjson,*retitem; uint8_t rmd160[20],addrtype; bits256 hash2,checktxid; - //memset(&hash2,0,sizeof(hash2)); struct iguana_txid *tx,T; struct iguana_block *block = 0; - - if ( (coinaddr= jstr(json,"address")) != 0 ) - { - if ( btc_addr2univ(&addrtype,rmd160,coinaddr) == 0 ) - { - if ( addrtype == coin->chain->pubval || addrtype == coin->chain->p2shval ) - valid = 1; - else return(clonestr("{\"error\":\"invalid addrtype\"}")); - } else return(clonestr("{\"error\":\"cant convert address to rmd160\"}")); - } - if ( strcmp(method,"block") == 0 ) - { - height = -1; - if ( ((hashstr= jstr(json,"blockhash")) != 0 || (hashstr= jstr(json,"hash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - else - { - height = juint(json,"height"); - hash2 = iguana_blockhash(coin,height); - } - retitem = cJSON_CreateObject(); - if ( (block= iguana_blockfind(coin,hash2)) != 0 ) - { - if ( (height >= 0 && block->height == height) || memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0 ) - { - char str[65],str2[65]; printf("hash2.(%s) -> %s\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); - return(jprint(iguana_blockjson(coin,block,juint(json,"txids")),1)); - } - } - else return(clonestr("{\"error\":\"cant find block\"}")); - } - else if ( strcmp(method,"tx") == 0 ) - { - if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) - { - retitem = cJSON_CreateObject(); - decode_hex(hash2.bytes,sizeof(hash2),txidstr); - if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) - { - jadd(retitem,"tx",iguana_txjson(coin,tx,height)); - return(jprint(retitem,1)); - } - return(clonestr("{\"error\":\"cant find txid\"}")); - } - else return(clonestr("{\"error\":\"invalid txid\"}")); - } - else if ( strcmp(method,"rawtx") == 0 ) - { - if ( ((txidstr= jstr(json,"txid")) != 0 || (txidstr= jstr(json,"hash")) != 0) && strlen(txidstr) == sizeof(bits256)*2 ) - { - decode_hex(hash2.bytes,sizeof(hash2),txidstr); - if ( (tx= iguana_txidfind(coin,&height,&T,hash2)) != 0 ) - { - if ( (len= iguana_txbytes(coin,coin->blockspace,coin->blockspacesize,&checktxid,tx,height,0,0)) > 0 ) - { - txbytes = mycalloc('x',1,len*2+1); - init_hexbytes_noT(txbytes,coin->blockspace,len*2+1); - retitem = cJSON_CreateObject(); - jaddstr(retitem,"txid",bits256_str(str,hash2)); - jaddnum(retitem,"height",height); - jaddstr(retitem,"rawtx",txbytes); - myfree(txbytes,len*2+1); - return(jprint(retitem,1)); - } else return(clonestr("{\"error\":\"couldnt generate txbytes\"}")); - } - return(clonestr("{\"error\":\"cant find txid\"}")); - } - else return(clonestr("{\"error\":\"invalid txid\"}")); - } - else if ( strcmp(method,"txs") == 0 ) - { - if ( ((hashstr= jstr(json,"block")) != 0 || (hashstr= jstr(json,"blockhash")) != 0) && strlen(hashstr) == sizeof(bits256)*2 ) - { - decode_hex(hash2.bytes,sizeof(hash2),hashstr); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - return(clonestr("{\"error\":\"cant find blockhash\"}")); - } - else if ( jobj(json,"height") != 0 ) - { - height = juint(json,"height"); - hash2 = iguana_blockhash(coin,height); - if ( (block= iguana_blockfind(coin,hash2)) == 0 ) - return(clonestr("{\"error\":\"cant find block at height\"}")); - } - else if ( valid == 0 ) - return(clonestr("{\"error\":\"txs needs blockhash or height or address\"}")); - retitem = cJSON_CreateArray(); - if ( block != 0 ) - { - for (i=0; iRO.txn_count; i++) - { - if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) - jaddi(retitem,iguana_txjson(coin,tx,-1)); - } - } - else - { - init_hexbytes_noT(rmd160str,rmd160,20); - jaddnum(retitem,"addrtype",addrtype); - jaddstr(retitem,"rmd160",rmd160str); - jaddstr(retitem,"txlist","get list of all tx for this address"); - } - return(jprint(retitem,1)); - } - - else - { - n = 0; - if ( valid == 0 ) - { - if ( (addrs= jarray(&n,json,"addrs")) == 0 ) - return(clonestr("{\"error\":\"need address or addrs\"}")); - } - for (i=0; i<=n; i++) - { - retitem = cJSON_CreateObject(); - if ( i > 0 ) - retjson = cJSON_CreateArray(); - if ( i > 0 ) - { - if ( (coinaddr= jstr(jitem(addrs,i-1),0)) == 0 ) - return(clonestr("{\"error\":\"missing address in addrs\"}")); - if ( btc_addr2univ(&addrtype,rmd160,coinaddr) < 0 ) - { - free_json(retjson); - return(clonestr("{\"error\":\"illegal address in addrs\"}")); - } - if ( addrtype != coin->chain->pubval && addrtype != coin->chain->p2shval ) - return(clonestr("{\"error\":\"invalid addrtype in addrs\"}")); - } - if ( strcmp(method,"utxo") == 0 ) - { - jaddstr(retitem,"utxo","utxo entry"); - } - else if ( strcmp(method,"unconfirmed") == 0 ) - { - jaddstr(retitem,"unconfirmed","unconfirmed entry"); - } - else if ( strcmp(method,"balance") == 0 ) - { - jaddstr(retitem,"balance","balance entry"); - } - else if ( strcmp(method,"totalreceived") == 0 ) - { - jaddstr(retitem,"totalreceived","totalreceived entry"); - } - else if ( strcmp(method,"totalsent") == 0 ) - { - jaddstr(retitem,"totalsent","totalsent entry"); - } - else if ( strcmp(method,"validateaddress") == 0 ) - { - jaddstr(retitem,"validate",coinaddr); - } - if ( n == 0 ) - return(jprint(retitem,1)); - else jaddi(retjson,retitem); - } - return(jprint(retjson,1)); - } - */ - - /* - char *iguana_listsinceblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash,int32_t target) - { - cJSON *retitem = cJSON_CreateObject(); - return(jprint(retitem,1)); - } - - char *iguana_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - jaddstr(retitem,"result",coin->statusstr); - return(jprint(retitem,1)); - } - - char *iguana_getbestblockhash(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - char str[65]; jaddstr(retitem,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); - return(jprint(retitem,1)); - } - - char *iguana_getblockcount(struct supernet_info *myinfo,struct iguana_info *coin) - { - cJSON *retitem = cJSON_CreateObject(); - jaddnum(retitem,"result",coin->blocks.hwmchain.height); - return(jprint(retitem,1)); - }*/ - if ( 0 ) - { - int32_t i,n; int64_t total; char *coinaddr; struct iguana_pkhash *P; struct iguana_info *coin; uint8_t rmd160[20],addrtype,pubkey33[33]; double startmillis; - coin = iguana_coinfind("BTCD"); - if ( 1 && coin != 0 ) - { - getchar(); - for (i=0; ibundlescount; i++) - if ( coin->bundles[i] == 0 ) - break; - coinaddr = "RUZ9AKxy6J2okcBd1PZm4YH6atmPwqV4bo"; - bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); - P = calloc(coin->bundlescount,sizeof(*P)); - memset(pubkey33,0,sizeof(pubkey33)); - n = iguana_pkhasharray(coin,0,0,0,&total,P,coin->bundlescount,rmd160,coinaddr,pubkey33); - printf("%s has total outputs %.8f from %d bundles\n",coinaddr,dstr(total),n); - startmillis = OS_milliseconds(); - for (i=0; i<1000; i++) - n = iguana_pkhasharray(coin,0,0,0,&total,P,coin->bundlescount,rmd160,coinaddr,pubkey33); - printf("%s has total outputs %.8f from %d bundles %.3f millis\n",coinaddr,dstr(total),n,OS_milliseconds()-startmillis); - getchar(); - } - } - int32_t i,numretries = 5; - for (i=0; i 2 ) - //printf("write.%d of %d worked!\n",i+1,numretries+1); - break; - } - fseek(fp,startfpos,SEEK_SET); - } - } -#else - //printf("call _iguana_chainlink\n"); - /*for (i=coin->blocks.hwmchain.height%coin->chain->bundlesize; ichain->bundlesize; i++) - { - if ( (bp= coin->current) != 0 && (block= bp->blocks[i]) != 0 ) - { - //printf("i.%d %s main.%d txvalid.%d\n",i,bits256_str(str,block->RO.hash2),block->mainchain,block->txvalid); - if ( _iguana_chainlink(coin,block) == 0 ) - iguana_blockQ("mainchain",coin,bp,-i,block->RO.hash2,1); - //iguana_realtime_update(coin); - } - }*/ - /*int32_t numrmds,minconf=0,maxconf=0,m = 0; uint8_t *rmdarray; cJSON *retjson; - retjson = cJSON_CreateArray(); - if ( (minconf= juint(params[0],0)) > 0 ) - { - m++; - if ( (maxconf= juint(params[1],0)) > 0 ) - m++; - } - if ( minconf == 0 ) - minconf = 1; - if ( maxconf == 0 ) - maxconf = 9999999; - rmdarray = iguana_rmdarray(coin,&numrmds,array,m); - iguana_unspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds); - if ( rmdarray != 0 ) - free(rmdarray); - return(jprint(retjson,1));*/ - char *iguana_payloadsave(char *filename,cJSON *wallet) - { - FILE *fp; - if ( (fp= fopen(filename,"wb")) != 0 ) - { - if ( fwrite(payloadstr,1,strlen(payloadstr),fp) != strlen(payloadstr) ) - { - fclose(fp); - return(clonestr("{\"error\":\"couldnt save wallet backup\"}")); - } - fclose(fp); - return(0); - } else return(clonestr("{\"error\":\"couldnt save wallet backup\"}")); - } - - /*struct iguana_waddress *iguana_waccountadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *walletaccount,char *coinaddr,char *redeemScript) - { - struct iguana_waccount *wacct; struct iguana_waddress *waddr = 0; - if ( (wacct= iguana_waccountfind(myinfo,coin,walletaccount)) == 0 ) - wacct = iguana_waccountcreate(myinfo,coin,walletaccount); - if ( wacct != 0 ) - waddr = iguana_waddresscreate(myinfo,coin,wacct,coinaddr,redeemScript); - return(waddr); - }*/ -#ifdef testing - char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *senders_otheraddr,char *otheraddr,uint32_t locktime,uint64_t satoshis,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey) - { - uint64_t change; char *rawtxstr,*signedtx; struct vin_info V; bits256 cltxid,signedtxid; - int32_t cltvlen,len; uint32_t timestamp; char ps2h_coinaddr[65]; cJSON *txobj; - uint8_t p2sh_rmd160[20],cltvscript[1024],paymentscript[64],rmd160[20],secret160[20],addrtype; - timestamp = (uint32_t)time(NULL); - bitcoin_addr2rmd160(&addrtype,secret160,senders_otheraddr); - cltvlen = bitcoin_cltvscript(coin->chain->p2shtype,ps2h_coinaddr,p2sh_rmd160,cltvscript,0,senderaddr,otheraddr,secret160,locktime); - txobj = bitcoin_createtx(coin,locktime); - len = bitcoin_p2shspend(paymentscript,0,p2sh_rmd160); - bitcoin_addoutput(coin,txobj,paymentscript,len,satoshis); - bitcoin_addinput(coin,txobj,txid,vout,locktime); - if ( inputsatoshis > (satoshis + 10000) ) - { - change = inputsatoshis - (satoshis + 10000); - if ( changeaddr != 0 && changeaddr[0] != 0 ) - { - bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); - if ( addrtype == coin->chain->pubtype ) - len = bitcoin_standardspend(paymentscript,0,rmd160); - else if ( addrtype == coin->chain->p2shtype ) - len = bitcoin_standardspend(paymentscript,0,rmd160); - else - { - printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype); - return(0); - } - bitcoin_addoutput(coin,txobj,paymentscript,len,change); - } - else - { - printf("error no change address when there is change\n"); - return(0); - } - } - rawtxstr = bitcoin_json2hex(coin,&cltxid,txobj); - char str[65]; printf("CLTV.%s (%s)\n",bits256_str(str,cltxid),rawtxstr); - memset(&V,0,sizeof(V)); - V.signers[0].privkey = privkey; - bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,&V); - free(rawtxstr); - if ( signedtx != 0 ) - printf("signed CLTV.%s (%s)\n",bits256_str(str,signedtxid),signedtx); - else printf("error generating signedtx\n"); - free_json(txobj); - return(signedtx); - } -#endif - - char *refstr = "01000000\ - 01\ - eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2\ - 01000000\ - 8c\ - 4930460221009e0339f72c793a89e664a8a932df073962a3f84eda0bd9e02084a6a9567f75aa022100bd9cbaca2e5ec195751efdfac164b76250b1e21302e51ca86dd7ebd7020cdc0601410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6\ - ffffffff\ - 01\ - 605af40500000000\ - 19\ - 76a914097072524438d003d23a2f23edb65aae1bb3e46988ac\ - 00000000"; - - cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid) - { - struct iguana_msgtx msgtx; char str[65],str2[65]; bits256 checktxid,blockhash,signedtxid; - cJSON *retjson,*txjson; uint8_t *serialized,*serialized2; uint32_t firstvout; - struct vin_info *V; char vpnstr[64],*txbytes,*signedtx; int32_t n,txstart,height,n2,maxsize,len; - rawtxstr = refstr; - len = (int32_t)strlen(rawtxstr); - maxsize = len + 32768; - serialized = calloc(1,maxsize); - serialized2 = calloc(1,maxsize); - len >>= 1; - V = 0; - vpnstr[0] = 0; - memset(&msgtx,0,sizeof(msgtx)); - if ( len < maxsize ) - { - decode_hex(serialized,len,rawtxstr); - txjson = cJSON_CreateObject(); - retjson = cJSON_CreateObject(); - if ( (n= iguana_rwmsgtx(coin,0,txjson,serialized,maxsize,&msgtx,&txid,vpnstr)) < 0 ) - { - printf("bitcoin_txtest len.%d: n.%d from (%s)\n",len,n,rawtxstr); - free(serialized), free(serialized2); - return(cJSON_Parse("{\"error\":\"cant parse txbytes\"}")); - } - V = calloc(msgtx.tx_in,sizeof(*V)); - { - //char *pstr; int32_t plen; - decode_hex(V[0].signers[0].privkey.bytes,sizeof(V[0].signers[0].privkey),"18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725"); - //pstr = "0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6"; - //plen = (int32_t)strlen(pstr); - //decode_hex(V[0].signers[0].pubkey,plen,pstr); - } - if ( bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V) != 0 ) - printf("bitcoin_verifytx error\n"); - jadd(retjson,"result",txjson); - if ( (firstvout= iguana_unspentindfind(coin,&height,txid,0,coin->bundlescount-1)) != 0 ) - { - if ( height >= 0 ) - { - blockhash = iguana_blockhash(coin,height); - jaddnum(retjson,"height",height); - jaddnum(retjson,"confirmations",coin->longestchain - height); - jaddbits256(retjson,"blockhash",blockhash); - } - } - //printf("retjson.(%s) %p\n",jprint(retjson,0),retjson); - memset(checktxid.bytes,0,sizeof(checktxid)); - if ( (n2= iguana_rwmsgtx(coin,1,0,serialized2,maxsize,&msgtx,&checktxid,vpnstr)) < 0 || n != n2 ) - { - printf("bitcoin_txtest: n.%d vs n2.%d\n",n,n2); - free(serialized), free(serialized2), free(V); - return(retjson); - } - if ( bits256_cmp(checktxid,txid) != 0 ) - { - printf("bitcoin_txtest: txid.%s vs check.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); - } - checktxid = iguana_parsetxobj(coin,&txstart,serialized,maxsize,&msgtx,jobj(retjson,"result")); - if ( bits256_cmp(checktxid,txid) != 0 ) - { - printf("bitcoin_txtest: txid.%s vs check2.%s\n",bits256_str(str,txid),bits256_str(str2,checktxid)); - } - if ( msgtx.allocsize != 0 ) - { - txbytes = malloc(msgtx.allocsize*2 + 1); - init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize); - if ( strcmp(txbytes,rawtxstr) != 0 ) - printf("bitcoin_txtest: reconstruction error: %s != %s\n",rawtxstr,txbytes); - else printf("reconstruction PASSED\n"); - free(txbytes); - } else printf("bitcoin_txtest: zero msgtx allocsize\n"); - free(serialized), free(serialized2), free(V); - return(retjson); - } - free(serialized), free(serialized2); - return(cJSON_Parse("{\"error\":\"testing bitcoin txbytes\"}")); - } - - - /*int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype) - { - uint8_t tmp[128]; char hexstr[67]; cstring *btc_addr; - memcpy(tmp,privkey,32); - tmp[32] = 1; - init_hexbytes_noT(hexstr,tmp,32); - if ( (btc_addr= base58_encode_check(addrtype,true,tmp,33)) != 0 ) - { - strcpy(wifstr,btc_addr->str); - cstr_free(btc_addr,true); - } - //printf("-> (%s) -> wif.(%s) addrtype.%02x\n",hexstr,wifstr,addrtype); - return(0); - } - - cstring *base58_encode_check(uint8_t addrtype,bool have_addrtype,const void *data,size_t data_len) - { - uint8_t i,buf[64]; bits256 hash; cstring *s_enc;//,*s = cstr_new_sz(data_len + 1 + 4); - buf[0] = addrtype; - memcpy(buf+1,data,data_len); - hash = bits256_doublesha256(0,buf,(int32_t)data_len+1); - //bu_Hash4(md32,buf,(int32_t)data_len+1); - for (i=0; i<4; i++) - { - buf[data_len+i+1] = hash.bytes[31-i]; - //printf("(%02x %02x) ",hash.bytes[31-i],md32[i]); - } - //printf("hash4 cmp\n"); - s_enc = base58_encode(buf,data_len+5); - return s_enc; - } - */ - /*if ( fieldstr != 0 && valuestr != 0 ) - { - flag = 0; - if ( (len= is_hexstr(fieldstr,0)) > 0 ) - { - if ( strlen(fieldstr) == 20*2 ) - decode_hex(rmd160,sizeof(rmd160),fieldstr); - else - { - len >>= 1; - decode_hex(script,len,valuestr); - calc_rmd160_sha256(rmd160,script,len); - bitcoin_address(p2shaddr,coin->chain->p2shtype,rmd160,20); - fprintf(fp,"%s %s %32s=%d # addr=%s # p2sh\n",valuestr,utc_str(str,(uint32_t)time(NULL)),account,i+1,p2shaddr); - flag = 1; - } - } else bitcoin_addr2rmd160(&addrtype,rmd160,fieldstr); - if ( flag == 0 ) - { - privkey = bits256_conv(valuestr); - bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); - bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,20); - fprintf(fp,"%s %s %32s=%d # addr=%s\n",wifstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); - } - - wiftype = 188; - for (j=0; jchain != 0 ) - { - if ( addrtype == coin->chain->pubtype ) - { - wiftype = coin->chain->wiftype; - privkey = bits256_conv(privkeystr); - if ( bits256_nonz(privkey) != 0 && bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) - { - fprintf(fp,"%s %s %32s=%d # addr=%s\n",wifstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); - } - break; - } - else if ( addrtype == coin->chain->p2shtype ) - { - fprintf(fp,"%s %s %32s=%d # addr=%s # p2sh\n",privkeystr,utc_str(str,(uint32_t)time(NULL)),account,i+1,p2shaddr); - break; - } - } - } - }*/ - /*coinaddr = child->string; - privkeystr = child->valuestring; - if ( coinaddr != 0 && privkeystr != 0 ) - { - if ( (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) - { - if ( iguana_waddresssearch(myinfo,coin,&tmp,coinaddr) == 0 ) - { - memset(&waddr,0,sizeof(waddr)); - strcpy(waddr.coinaddr,coinaddr); - waddr.addrtype = coin->chain->p2shtype; - if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == sizeof(rmd160) && addrtype == coin->chain->p2shtype ) - iguana_waddressadd(myinfo,coin,wacct,&waddr,privkeystr); - else - { - waddr.addrtype = coin->chain->pubtype; - privkey = bits256_conv(privkeystr); - if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) - iguana_waddressadd(myinfo,coin,wacct,&waddr,0); - } - } else printf("dup.(%s) ",coinaddr); - len = (int32_t)strlen(privkeystr); - for (j=0; jwallet,wacct,tmp) - { - if ( account != 0 && strcmp(account,"*") != 0 && strcmp(account,wacct->account) != 0 ) - continue; - HASH_ITER(hh,wacct->waddr,waddr,tmp2) - { - if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) - continue; - if ( waddr->balance > 0 ) - { - remains -= waddr->balance; - waddrs[num++] = waddr; - if ( num >= maxwaddrs || remains <= 0 ) - break; - } - } - if ( num >= maxwaddrs || remains <= 0 ) - break; - } - - /*int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin) - { - int64_t sum = 0,total; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; int32_t n,numunspents = 0; cJSON *addresses = cJSON_CreateArray(); - HASH_ITER(hh,myinfo->wallet,wacct,tmp) - { - HASH_ITER(hh,wacct->waddr,waddr,tmp2) - { - if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) - continue; - jaddstr(array,waddr->coinaddr); - total = 0; - n = 0; - iguana_pkhasharray(myinfo,coin,0,coin->minconfirms,coin->longestchain,&total,0,coin->bundlescount,waddr->rmd160,waddr->coinaddr,waddr->pubkey,coin->blocks.hwmchain.height - coin->minconfirms,(uint64_t *)coin->blockspace,&n,(int32_t)(coin->blockspacesize/sizeof(*waddr->unspents))-1000); - if ( n > 0 ) - { - if ( waddr->unspents == 0 || waddr->maxunspents < n ) - { - waddr->unspents = realloc(waddr->unspents,sizeof(*waddr->unspents) * n); - waddr->maxunspents = n; - } - memcpy(waddr->unspents,coin->blockspace,sizeof(*waddr->unspents) * n); - waddr->numunspents = n; - waddr->balance = total; - sum += total; - numunspents += n; - } - } - } - //printf("available %.8f\n",dstr(sum)); - return(sum); - }*/ - - /*int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs) - { - int32_t len,maxsize,retval = -1; uint8_t *serialized,*serialized2; - struct iguana_msgtx msgtx; bits256 txid; char vpnstr[64]; - len = (int32_t)strlen(rawtxstr); - maxsize = len + 32768; - serialized = calloc(1,maxsize), serialized2 = calloc(1,maxsize); - len >>= 1; - vpnstr[0] = 0; - decode_hex(serialized,len,rawtxstr); - memset(&msgtx,0,sizeof(msgtx)); - if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,vpnstr) > 0 && numinputs == msgtx.tx_in ) - { - if ( bitcoin_verifyvins(coin,signedtxidp,signedtx,&msgtx,serialized2,maxsize,V,SIGHASH_ALL) == 0 ) - retval = 0; - else printf("bitcoin_verifytx: bitcoin_verifyvins error\n"); - } else printf("bitcoin_verifytx: error iguana_rwmsgtx\n"); - free(serialized), free(serialized2); - return(retval); - } - - cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins) - { - int32_t i,j,m,n,plen; char *rawtxstr,*pubkeystr,*spendstr; struct vin_info *V,*vp; bits256 txid; struct iguana_waccount *wacct; struct iguana_waddress *waddr; cJSON *vitem,*vinsobj,*pubkeys; - V = calloc(spend->numinputs,sizeof(*V)); - if ( *signedtxp != 0 ) - { - if ( txobj != 0 ) - free_json(txobj); - txobj = bitcoin_hex2json(coin,&txid,0,*signedtxp); - if ( vins != 0 ) - { - if ( jobj(txobj,"vin") != 0 ) - jdelete(txobj,"vin"); - jadd(txobj,"vin",iguana_createvins(myinfo,coin,txobj,vins)); - } - //printf("bitcoin_hex2json (%s)\n",jprint(txobj,0)); - free(*signedtxp); - } - vinsobj = jarray(&n,txobj,"vin"); - for (i=0; inuminputs; i++) // N times less efficient, but for small number of inputs ok - { - vp = &V[i]; - if ( i < n ) - { - if ( (vitem= jitem(vinsobj,i)) != 0 && ((spendstr= jstr(vitem,"scriptPub")) != 0 || (spendstr= jstr(vitem,"scriptPubKey")) != 0) ) - { - vp->spendlen = (int32_t)strlen(spendstr) >> 1; - decode_hex(vp->spendscript,vp->spendlen,spendstr); - } else spendstr = 0; - } - else vitem = 0; - vp->N = vp->M = 1; - if ( (rawtxstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( bits256_nonz(spend->inputs[i].privkeys[j]) != 0 ) - { - vp->signers[j].privkey = spend->inputs[i].privkeys[j]; - bitcoin_pubkey33(coin->ctx,vp->signers[j].pubkey,vp->signers[j].privkey); - } - else - { - vp->signers[j].pubkey[0] = 0; - break; - } - } - if ( vitem != 0 && (pubkeys= jarray(&m,vitem,"pubkeys")) != 0 )//spend->inputs[i].numpubkeys > 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( j < m && (pubkeystr= jstr(jitem(pubkeys,j),0)) != 0 && is_hexstr(pubkeystr,(int32_t)strlen(pubkeystr)) > 0 ) - decode_hex(vp->signers[j].pubkey,(int32_t)strlen(pubkeystr)>>1,pubkeystr); - else if ( (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) - memcpy(vp->signers[j].pubkey,spend->inputs[i].pubkeys[j],plen); - } - } - //if ( spend->inputs[i].spendlen > 0 ) - // { - // memcpy(vp->spendscript,spend->inputs[i].spendscript,spend->inputs[i].spendlen); - // vp->spendlen = spend->inputs[i].spendlen; - // } - if ( spend->inputs[i].p2shlen > 0 ) - { - memcpy(vp->p2shscript,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen); - vp->p2shlen = spend->inputs[i].p2shlen; - } - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( vp->signers[j].coinaddr[0] == 0 && (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) - { - bitcoin_address(vp->signers[j].coinaddr,coin->chain->pubtype,spend->inputs[i].pubkeys[j],plen); - } - } - if ( myinfo->expiration != 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( bits256_nonz(vp->signers[j].privkey) == 0 && vp->signers[j].coinaddr[0] != 0 ) - { - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,vp->signers[j].coinaddr)) != 0 ) - vp->signers[j].privkey = waddr->privkey; - } - } - } - vp->sequence = spend->inputs[i].sequence; - //printf("json2hex.(%s)\n",rawtxstr); - } - } - bitcoin_verifytx(coin,txidp,signedtxp,rawtxstr,V,spend->numinputs); - //printf("json2hex.(%s)\n",rawtxstr); - free(rawtxstr); - if ( *signedtxp != 0 && i != spend->numinputs ) - free(*signedtxp), *signedtxp = 0; - free(V); - return(txobj); - }*/ - /*int64_t iguana_availunspents(struct supernet_info *myinfo,uint64_t **unspentsp,int32_t *nump,struct iguana_info *coin,int32_t minconf,char *account,void *ptr,int32_t maxsize) - { - int32_t i,j,num,numwaddrs; struct iguana_waddress **waddrs,*waddr; uint64_t *unspents,value,avail=0; - *unspentsp = unspents = 0; - *nump = num = 0; - waddrs = (struct iguana_waddress **)ptr; - numwaddrs = iguana_unspentslists(myinfo,coin,waddrs,(int32_t)(maxsize/sizeof(*waddrs)),(uint64_t)1 << 62,minconf); - if ( numwaddrs > 0 ) - { - unspents = (uint64_t *)((long)ptr + sizeof(*waddrs)*numwaddrs); - for (i=num=0; inumunspents > 0 ) - { - for (j=0; jnumunspents; j++) - { - if ( (value= iguana_unspentavail(coin,waddr->unspents[j],minconf,coin->longestchain)) != 0 ) - { - unspents[num << 1] = waddr->unspents[j]; - unspents[(num << 1) + 1] = value; - num++; - avail += value; - printf("([%d].u%u) ",(uint32_t)(waddr->unspents[j]>>32),(uint32_t)waddr->unspents[j]); - } - } - printf("(%s %.8f)\n",waddr->coinaddr,dstr(waddr->balance)); - } - } - } - *unspentsp = unspents; - *nump = num; - return(avail); - }*/ - - instantdex_addevent(s,*n,"BOB_sentprivs","BTCprivs","BTCprivs","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_sentprivs","BTCdeckC","BTCprivs","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_sentprivs","BTCprivC","BTCprivs","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_sentprivs","poll","BTCprivs","BOB_waitfee"); - - s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"ALICE_sentprivs","BTCprivs","BTCprivs","Alice_waitfee"); - instantdex_addevent(s,*n,"ALICE_sentprivs","BTCdeckC","BTCprivs","Alice_waitfee"); - instantdex_addevent(s,*n,"ALICE_sentprivs","BTCprivC","BTCprivs","Alice_waitfee"); - instantdex_addevent(s,*n,"ALICE_sentprivs","poll","BTCprivs","Alice_waitfee"); - - s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"BOB_waitfee","feefound","BTCdeptx","BOB_sentdeposit"); - instantdex_addevent(s,*n,"BOB_waitfee","BTCdeckC","BTCprivs","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_waitfee","BTCprivs","poll","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_waitfee","poll","BTCprivs","BOB_waitfee"); - - s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"Alice_waitfee","feefound","BTCprivs","ALICE_waitdeposit"); - instantdex_addevent(s,*n,"Alice_waitfee","BTCdeckC","BTCprivs","Alice_waitfee"); - instantdex_addevent(s,*n,"Alice_waitfee","BTCprivs","poll","Alice_waitfee"); - instantdex_addevent(s,*n,"Alice_waitfee","poll","BTCprivs","Alice_waitfee"); - - s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"ALICE_waitdeposit","depfound","BTCalttx","ALICE_sentalt"); - instantdex_addevent(s,*n,"ALICE_waitdeposit","feefound","poll","ALICE_waitdeposit"); - instantdex_addevent(s,*n,"ALICE_waitdeposit","poll","BTCprivs","ALICE_waitdeposit"); - - s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0); - instantdex_addevent(s,*n,"BOB_sentdeposit","BTCalttx","poll","BOB_altconfirm"); - instantdex_addevent(s,*n,"BOB_sentdeposit","poll","poll","BOB_sentdeposit"); - - s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaimed",0,0); - instantdex_addevent(s,*n,"BOB_altconfirm","altfound","BTCpaytx","BOB_sentpayment"); - instantdex_addevent(s,*n,"BOB_altconfirm","poll","poll","BOB_altconfirm"); - - // [BLOCKING: BTCpaytx] now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim - s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaimed",0,0); - instantdex_addevent(s,*n,"ALICE_sentalt","BTCpaytx","poll","ALICE_waitconfirms"); - instantdex_addevent(s,*n,"ALICE_sentalt","poll","poll","ALICE_sentalt"); - - s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitconfirmsfunc,0,"ALICE_reclaimed",0,0); - instantdex_addevent(s,*n,"ALICE_waitconfirms","altfound","BTCprivM","ALICE_claimedbtc"); - instantdex_addevent(s,*n,"ALICE_waitconfirms","poll","poll","ALICE_checkbobreclaim"); - - /*cJSON *BTC_waitdeckCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - strcmp(swap->expectedcmdstr,"BTCdeckC"); - return(newjson); - } - - cJSON *BTC_waitprivCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - strcmp(swap->expectedcmdstr,"BTCprivC"); - printf("call privkey extract from serdatalen.%d\n",*serdatalenp); - instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp); - *serdatap = 0, *serdatalenp = 0; - return(newjson); - } - - cJSON *ALICE_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); - *serdatap = 0, *serdatalenp = 0; - strcpy(swap->waitfortx,"fee"); - if ( coinbtc != 0 && swap->otherfee != 0 ) - jaddstr(newjson,"virtevent","feefound"); - return(newjson); - } - - cJSON *BTC_waitprivsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; struct iguana_info *coin = iguana_coinfind("BTC"); - if ( coin != 0 ) - { - strcmp(swap->expectedcmdstr,"BTCprivs"); - instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp); - } - return(newjson); - } - - cJSON *ALICE_waitBTCpaytxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - strcmp(swap->expectedcmdstr,"BTCpaytx"); - return(newjson); - } - - cJSON *BOB_waitprivMfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - char *retstr; - strcmp(swap->expectedcmdstr,"BTCprivM"); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,iguana_coinfind(swap->mine.offer.base),swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"altfound",0)) != 0 ) - { - free(retstr); - jaddstr(newjson,"virtevent","altfound"); - } - printf("search for payment spend in blockchain\n"); - *serdatap = 0, *serdatalenp = 0; - return(newjson); - } - - cJSON *BOB_waitaltconfirmfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - char *retstr; struct iguana_info *altcoin; - altcoin = iguana_coinfind(swap->mine.offer.base); - *serdatap = 0, *serdatalenp = 0; - strcpy(swap->waitfortx,"alt"); - //reftime = (uint32_t)(ap->offer.expiration - INSTANTDEX_LOCKTIME*2); - if ( altcoin != 0 && swap->altpayment != 0 && swap->otherchoosei >= 0 && (retstr= BTC_txconfirmed(myinfo,altcoin,swap,newjson,swap->altpayment->txid,&swap->altpayment->numconfirms,"altfound",altcoin->chain->minconfirms)) != 0 ) - { - if ( swap->payment != 0 || (swap->payment= instantdex_bobtx(myinfo,swap,altcoin,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherchoosei],swap->reftime,swap->BTCsatoshis,0)) != 0 ) - { - free(retstr); - jaddstr(newjson,"virtevent","altfound"); - } - } - return(newjson); - } - - cJSON *ALICE_waitconfirmsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - char *retstr; double btcconfirms; struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); - *serdatap = 0, *serdatalenp = 0; - if ( swap->BTCsatoshis < SATOSHIDEN/10 ) - btcconfirms = 0; - else btcconfirms = 1. + sqrt((double)swap->BTCsatoshis / SATOSHIDEN); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 ) - { - free(retstr); - jaddstr(newjson,"virtevent","payfound"); - // if bobreclaimed is there, then reclaim altpayment - printf("search for Bob's reclaim in blockchain\n"); - } - return(newjson); - } - - cJSON *ALICE_checkbobreclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - char *retstr; double btcconfirms; struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); - *serdatap = 0, *serdatalenp = 0; - if ( swap->BTCsatoshis < SATOSHIDEN/10 ) - btcconfirms = 0; - else btcconfirms = sqrt((double)swap->BTCsatoshis / SATOSHIDEN); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 ) - { - free(retstr); - jaddstr(newjson,"virtevent","payfound"); - // if bobreclaimed is there, then reclaim altpayment - printf("search for Bob's reclaim in blockchain\n"); - } - return(newjson); - } - - cJSON *BTC_idlerecvfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - jaddstr(newjson,"error","need to cleanup"); - return(newjson); - } - */ - - cJSON *BOB_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( swap->deposit != 0 ) - printf("reclaim deposit.(%s) to %s\n",swap->deposit->txbytes,swap->deposit->destaddr); - strcpy(swap->waitfortx,"bre"); - // reclaim deposit - return(newjson); - } - - cJSON *BOB_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( swap->myfee != 0 ) - printf("reclaim fee.(%s) -> %s\n",swap->myfee->txbytes,swap->myfee->destaddr); - strcpy(swap->waitfortx,"bfr"); - // reclaim deposit - return(newjson); - } - - cJSON *BOB_claimaltfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( 0 && swap->altpayment != 0 ) - printf("spend altpayment.(%s) -> %s\n",swap->altpayment->txbytes,swap->altpayment->destaddr); - strcpy(swap->waitfortx,"bcl"); - // spend altpayment - return(newjson); - } - - cJSON *ALICE_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - // reclaim altpayment - if ( swap->altpayment != 0 ) - printf("reclaim altpayment.(%s) -> %s\n",swap->altpayment->txbytes,swap->altpayment->destaddr); - strcpy(swap->waitfortx,"are"); - return(newjson); - } - - cJSON *ALICE_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - // reclaim fee - if ( swap->myfee != 0 ) - printf("reclaim fee.(%s) -> %s\n",swap->myfee->txbytes,swap->myfee->destaddr); - strcpy(swap->waitfortx,"afr"); - return(newjson); - } - - cJSON *ALICE_claimdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( swap->deposit != 0 ) - printf("reclaim deposit.(%s) -> %s\n",swap->deposit->txbytes,swap->deposit->destaddr); - strcpy(swap->waitfortx,"adp"); - // reclaim deposit - return(newjson); - } - - cJSON *ALICE_claimbtcfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) - { - *serdatap = 0, *serdatalenp = 0; - if ( swap->payment != 0 ) - printf("spend BTC payment.(%s) -> %s\n",swap->payment->txbytes,swap->payment->destaddr); - strcpy(swap->waitfortx,"acl"); - // spend BTC - return(newjson); - } - - /* - s = instantdex_statecreate(s,n,"ALICE_claimedbtc",ALICE_claimbtcfunc,0,0,0,0); - instantdex_addevent(s,*n,"ALICE_claimedbtc","aclfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"ALICE_claimedbtc","poll","poll","ALICE_claimedbtc"); - - s = instantdex_statecreate(s,n,"BOB_depclaimed",BOB_reclaimfunc,0,0,0,0); // deposit back - instantdex_addevent(s,*n,"BOB_depclaimed","brefound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"BOB_depclaimed","poll","poll","BOB_depclaimed"); - - s = instantdex_statecreate(s,n,"BOB_claimedalt",BOB_claimaltfunc,0,0,0,0); - instantdex_addevent(s,*n,"BOB_claimedalt","bclfound","poll","BOB_depclaimed"); - instantdex_addevent(s,*n,"BOB_claimedalt","poll","poll","BOB_claimedalt"); - - // if things go wrong, bob gets his deposit and fee back - s = instantdex_statecreate(s,n,"BOB_feereclaimed",BOB_feereclaimfunc,0,0,0,0); - instantdex_addevent(s,*n,"BOB_feereclaimed","bfrfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"BOB_feereclaimed","poll","poll","BOB_feereclaimed"); - - s = instantdex_statecreate(s,n,"BOB_reclaimed",BOB_reclaimfunc,0,0,0,0); // deposit back - instantdex_addevent(s,*n,"BOB_reclaimed","brefound","poll","BOB_feereclaimed"); - instantdex_addevent(s,*n,"BOB_reclaimed","poll","poll","BOB_reclaimed"); - - // if things go wrong, alice reclaims her altpayment or claims the deposit and then fee - s = instantdex_statecreate(s,n,"ALICE_feereclaimed",ALICE_feereclaimfunc,0,0,0,0); - instantdex_addevent(s,*n,"ALICE_feereclaimed","afrfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"ALICE_feereclaimed","poll","poll","ALICE_feereclaimed"); - - s = instantdex_statecreate(s,n,"ALICE_reclaimed",ALICE_reclaimfunc,0,0,0,0); // altpayment - instantdex_addevent(s,*n,"ALICE_reclaimed","arefound","poll","ALICE_feereclaimed"); - instantdex_addevent(s,*n,"ALICE_reclaimed","poll","poll","ALICE_reclaimed"); - s = instantdex_statecreate(s,n,"ALICE_depositclaimed",ALICE_claimdepositfunc,0,0,0,0); // altpayment - instantdex_addevent(s,*n,"ALICE_depositclaimed","adpfound","poll","ALICE_feereclaimed"); - instantdex_addevent(s,*n,"ALICE_depositclaimed","poll","poll","ALICE_depositclaimed"); - s = instantdex_statecreate(s,n,"ALICE_checkbobreclaim",ALICE_checkbobreclaimfunc,0,"ALICE_reclaimed",0,0);*/ - // end terminal [BLOCKING] states - - // need to create states before they can be referred to, that way a one pass FSM compile is possible - //s = instantdex_statecreate(s,n,"BOB_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); - //s = instantdex_statecreate(s,n,"ALICE_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); - //s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0); - //s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaimed",0,0); - //s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaimed",0,0); - //s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); - //s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaimed",0,0); - //s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitconfirmsfunc,0,"ALICE_reclaimed",0,0); - - /*if ( 0 ) // following are implicit states and events handled externally to setup datastructures - { - instantdex_addevent(s,*n,"BOB_idle","usrorder","BTCoffer","BTC_waitdeck"); // send deck - instantdex_addevent(s,*n,"ALICE_idle","usrorder","BTCoffer","BTC_waitdeck"); - } - s = instantdex_statecreate(s,n,"BOB_idle",BTC_checkdeckfunc,0,"BTC_cleanup",0,1); - s = instantdex_statecreate(s,n,"ALICE_idle",BTC_checkdeckfunc,0,"BTC_cleanup",0,1); - instantdex_addevent(s,*n,"BOB_idle","BTCoffer","poll","BTC_waitdeck"); // send deck + Chose - instantdex_addevent(s,*n,"ALICE_idle","BTCoffer","poll","BTC_waitdeck");*/ - - char *basilisk_issuebalances(struct supernet_info *myinfo,char *remoteaddr,int32_t basilisktag,char *symbol,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeoutmillis) - { - struct iguana_info *coin; char *retstr = 0; cJSON *retjson,*args = 0; - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - if ( coin->basilisk_balances != 0 ) - { - if ( (retstr= (*coin->basilisk_balances)(myinfo,coin,remoteaddr,basilisktag,&args,lastheight,minconf,addresses,timeoutmillis)) != 0 ) - { - retjson = basilisk_resultsjson(myinfo,symbol,remoteaddr,basilisktag,timeoutmillis,retstr,args); - free(retstr); - retstr = jprint(retjson,1); - } - } - } - return(retstr); - } - - char *basilisk_issuevalue(struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,bits256 txid,int16_t vout,char *coinaddr,int32_t timeoutmillis) - { - struct iguana_info *coin; char *retstr = 0; cJSON *retjson,*args = 0; - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - if ( coin->basilisk_value != 0 ) - { - if ( (retstr= (*coin->basilisk_value)(myinfo,coin,remoteaddr,basilisktag,&args,txid,vout,coinaddr,timeoutmillis)) != 0 ) - { - retjson = basilisk_resultsjson(myinfo,symbol,remoteaddr,basilisktag,timeoutmillis,retstr,args); - free(retstr); - retstr = jprint(retjson,1); - } - } - } - return(retstr); - } - - int32_t basilisk_submit(struct supernet_info *myinfo,cJSON *reqjson,int32_t timeout,int32_t fanout,struct basilisk_item *ptr) - { - int32_t i,j,k,l,r2,r,n; struct iguana_peer *addr; struct iguana_info *coin; char *reqstr; cJSON *tmpjson; - tmpjson = basilisk_json(myinfo,reqjson,ptr->basilisktag,timeout); - reqstr = jprint(tmpjson,1); - //printf("basilisk_submit.(%s)\n",reqstr); - if ( fanout <= 0 ) - fanout = BASILISK_MINFANOUT; - else if ( fanout > BASILISK_MAXFANOUT ) - fanout = BASILISK_MAXFANOUT; - r2 = rand(); - for (l=n=0; lpeers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 ) - { - ptr->submit = (uint32_t)time(NULL); - printf("submit to (%s)\n",addr->ipaddr); - iguana_send_supernet(addr,reqstr,0); - if ( n++ > fanout ) - break; - } - } - } - } - free(reqstr); - return(n); - } - - /*cJSON *basilisk_json(struct supernet_info *myinfo,cJSON *hexjson,uint32_t basilisktag,int32_t timeout) - { - char *str,*buf; cJSON *retjson; - if ( jobj(hexjson,"basilisktag") != 0 ) - jdelete(hexjson,"basilisktag"); - jaddnum(hexjson,"basilisktag",basilisktag); - str = jprint(hexjson,0); - buf = malloc(strlen(str)*2 + 1); - init_hexbytes_noT(buf,(uint8_t *)str,(int32_t)strlen(str)); - free(str); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"hexmsg",buf); - free(buf); - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","DHT"); - jaddnum(retjson,"request",1); - jaddnum(retjson,"plaintext",1); - jaddbits256(retjson,"categoryhash",myinfo->basilisk_category); - jaddnum(retjson,"timeout",timeout); - return(retjson); - } - if ( strcmp(type,"BID") == 0 || strcmp(type,"ASK") == 0 ) - { - instantdex_quotep2p(myinfo,0,addr,data,datalen); - } - else if ( (argjson= cJSON_Parse((char *)data)) != 0 ) - { - jaddstr(argjson,"agent","basilisk"); - jaddnum(argjson,"basilisktag",basilisktag); - if ( strcmp(type,"RET") == 0 ) - { - jaddstr(argjson,"method","return"); - } - else if ( strcmp(type,"RAW") == 0 ) - { - jaddstr(argjson,"method","rawtx"); - } - else if ( strcmp(type,"VAL") == 0 ) - { - jaddstr(argjson,"method","value"); - } - jsonstr = jprint(argjson,1); - if ( (retstr= basilisk_hexmsg(myinfo,0,(void *)jsonstr,(int32_t)strlen(jsonstr)+1,remoteaddr)) != 0 ) - free(retstr); - free(jsonstr); - char *basilisk_results(uint32_t basilisktag,cJSON *valsobj) - { - cJSON *resultobj = cJSON_CreateObject(); - jadd(resultobj,"vals",valsobj); - jaddstr(resultobj,"agent","basilisk"); - jaddstr(resultobj,"method","result"); - jaddnum(resultobj,"plaintext",1); - if ( jobj(resultobj,"basilisktag") != 0 ) - jdelete(resultobj,"basilisktag"); - jaddnum(resultobj,"basilisktag",basilisktag); - return(jprint(resultobj,1)); - } - - cJSON *basilisk_resultsjson(struct supernet_info *myinfo,char *symbol,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,char *retstr) - { - cJSON *hexjson=0,*retjson=0; - if ( retstr != 0 ) - { - if ( remoteaddr != 0 && remoteaddr[0] != 0 ) - { - hexjson = cJSON_CreateObject(); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","result"); - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - jadd(hexjson,"vals",retjson); - retjson = basilisk_json(myinfo,hexjson,basilisktag,timeoutmillis); - free_json(hexjson); - printf("resultsjson.(%s)\n",jprint(retjson,0)); - } - else // local request - retjson = cJSON_Parse(retstr); - } - return(retjson); - }*/ - /* cJSON *array=0,*result,*item,*retjson,*hexjson; int32_t i,n,besti=-1; char *coinaddr,*balancestr=0,*retstr=0; int64_t total=0,amount,most=0; struct basilisk_item *ptr; - array = cJSON_CreateArray(); - if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 ) - { - if ( (n= cJSON_GetArraySize(addresses)) > 0 ) - { - for (i=0; iVALIDATENODE != 0 || coin->FULLNODE != 0 ) - balancestr = iguana_balance(myinfo,coin,0,remoteaddr,coin->symbol,coinaddr,lastheight,minconf); - //else balancestr = bitcoin_balance(coin,coinaddr,lastheight,minconf); - if ( balancestr != 0 ) - { - if ( (result= cJSON_Parse(balancestr)) != 0 ) - { - if ( jobj(result,"balance") != 0 ) - { - item = cJSON_CreateObject(); - amount = SATOSHIDEN * jdouble(result,"balance"); - total += amount; - jaddnum(item,coinaddr,dstr(amount)); - jaddi(array,item); - } - free_json(result); - } - free(balancestr); - } - } - } - } - else - { - hexjson = cJSON_CreateObject(); - jaddnum(hexjson,"basilisktag",basilisktag); - jadd(hexjson,"addresses",jduplicate(addresses)); - jaddnum(hexjson,"minconf",minconf); - jaddnum(hexjson,"lastheight",lastheight); - jaddstr(hexjson,"agent","basilisk"); - jaddstr(hexjson,"method","balances"); - if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) - { - for (i=0; inumresults; i++) - { - if ( ptr->results[i] == 0 ) - continue; - if ( retstr != 0 && strcmp(ptr->results[i],retstr) == 0 ) - ptr->numexact++; - if ( (retjson= cJSON_Parse(ptr->results[i])) != 0 ) - { - if ( (total= j64bits(retjson,"balance")) > most ) - { - most = total; - besti = i; - } - free_json(retjson); - } - } - retstr = basilisk_finish(ptr,arrayp,besti); - } - free_json(hexjson); - } - *arrayp = array; - return(most);*/ - if ( agent != 0 && method != 0 && strcmp(agent,"SuperNET") == 0 && strcmp(method,"DHT") == 0 && (hexmsg= jstr(remotejson,"hexmsg")) != 0 ) - { - n = (int32_t)(strlen(hexmsg) >> 1); - tmpstr = calloc(1,n + 1); - decode_hex((void *)tmpstr,n,hexmsg); - free_json(remotejson); - printf("NESTED.(%s)\n",tmpstr); - if ( (remotejson= cJSON_Parse(tmpstr)) == 0 ) - { - printf("couldnt parse decoded hexmsg.(%s)\n",tmpstr); - free(tmpstr); - return(0); - } - free(tmpstr); - agent = jstr(remotejson,"agent"); - method = jstr(remotejson,"method"); - } - - char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *dontuse,void *ptr,int32_t len,char *remoteaddr) // incoming - { - char *method,*retstr = 0; uint8_t *data=0; cJSON *array,*valsobj; struct iguana_info *coin=0; uint32_t basilisktag,datalen=0,jsonlen; - array = 0; - if ( (valsobj= cJSON_Parse((char *)ptr)) != 0 ) - { - jsonlen = (int32_t)strlen((char *)ptr) + 1; - if ( len > jsonlen ) - data = (uint8_t *)((long)ptr + jsonlen), datalen = len - jsonlen; - basilisktag = juint(valsobj,"basilisktag"); - printf("basilisk.(%s)\n",jprint(valsobj,0)); - if ( jobj(valsobj,"coin") != 0 ) - coin = iguana_coinfind(jstr(valsobj,"coin")); - if ( (method= jstr(valsobj,"method")) != 0 && coin != 0 ) - { - if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node - { - if ( strcmp(method,"rawtx") == 0 ) - retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - else if ( strcmp(method,"balances") == 0 ) - retstr = basilisk_balances(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - else if ( strcmp(method,"value") == 0 ) - retstr = basilisk_value(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - if ( retstr != 0 ) - free(retstr); - retstr = 0; - // should automatically send to remote requester - } - else // basilisk node - { - if ( strcmp(method,"result") == 0 ) - retstr = basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj); - } - } else printf("basilisk_hexmsg no coin\n"); - free_json(valsobj); - } - printf("unhandled bitcoin_hexmsg.(%d) from %s (%s)\n",len,remoteaddr,(char *)ptr); - return(retstr); - } - - int32_t basilisk_hashstamps(struct iguana_info *btcd,struct hashstamp *BTCDstamps,struct basilisk_sequence *seq,int32_t max,uint32_t reftimestamp) - { - uint32_t i,timestamp; struct iguana_block *block; - block = &btcd->blocks.hwmchain; - while ( block != 0 && (timestamp= block->RO.timestamp) > reftimestamp ) - block = iguana_blockfind("hashstamps",btcd,block->RO.prev_block); - if ( block == 0 ) - return(-1); - for (i=0; iRO.hash2; - BTCDstamps[i].timestamp = block->RO.timestamp; - BTCDstamps[i].height = block->height; - if ( (block= iguana_blockfind("hashstamps",btcd,block->RO.prev_block)) == 0 ) - return(i+1); - } - return(i); - } - //printf("mapped Soffset.%ld\n",(long)mapchain->data->Soffset); - /*iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - if ( 1 ) // unix issues? - { - if ( (err= iguana_ramchain_cmp(ramchain,mapchain,0)) != 0 ) - fpos = -1, printf("error.%d comparing ramchains\n",err); - else - { - ptr = mapchain->fileptr; fsize = mapchain->filesize; - mapchain->fileptr = 0, mapchain->filesize = 0; - iguana_ramchain_free(coin,mapchain,1); - memset(&R,0,sizeof(R)); - R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; - iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - } - } - if ( (err= iguana_ramchain_cmp(ramchain,&R,0)) != 0 ) - { - fpos = -1; - block->issued = 0; - block->RO.recvlen = 0; - printf("error.%d comparing REMAP ramchains\n",err); - } - else - { - iguana_ramchain_extras(coin,&R,0,0); - if ( (err= iguana_ramchain_iterate(coin,0,&R,bp,bundlei)) != 0 ) - printf("err.%d iterate ",err); - //printf("SUCCESS REMAP\n"); - bp->numtxids += rdata->numtxids; - bp->numunspents += rdata->numunspents; - bp->numspends += rdata->numspends; - //bp->rawscriptspace += rdata->scriptspace; - } - iguana_ramchain_free(coin,&R,1); - if ( err != 0 ) - iguana_blockunmark(coin,block,bp,bundlei,1);*/ - - char *basilisk_respond_setfield(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) - { - struct iguana_info *virt; struct iguana_block *prevblock,*prev2,*newblock,block; char chainname[BASILISK_MAXNAMELEN],str[65],*blocktx; uint32_t nBits,timestamp,nonce; cJSON *retjson; bits256 btcdhash; - if ( datalen <= 0 ) - return(clonestr("{\"error\":\"no data specified\"}")); - if ( (virt= basilisk_chain(myinfo,chainname,valsobj)) == 0 ) - return(clonestr("{\"error\":\"couldnt get basilisk_chain\"}")); - printf("from.(%s) SET.(%s) datalen.%d prev.%s\n",remoteaddr,jprint(valsobj,0),datalen,bits256_str(str,prevhash)); - if ( bits256_nonz(prevhash) == 0 ) - prevhash = virt->blocks.hwmchain.RO.hash2; - if ( (prevblock= iguana_blockfind("setfield",virt,prevhash)) == 0 ) - return(clonestr("{\"error\":\"couldnt find prevhash\"}")); - if ( (prev2= iguana_blockfind("setfield",virt,prevblock->RO.prev_block)) == 0 ) - return(clonestr("{\"error\":\"couldnt find prevhash2\"}")); - timestamp = juint(valsobj,"timestamp"); - nonce = juint(valsobj,"nonce"); - nBits = iguana_targetbits(virt,(struct iguana_block *)&virt->blocks.hwmchain,prevblock,prev2,1,virt->chain->targetspacing,virt->chain->targettimespan); - blocktx = basilisk_block(myinfo,virt,&block,1,timestamp,&nonce,prevhash,nBits,prevblock->height+1,0,0,data,datalen,btcdhash,jobj(valsobj,"coinbase")); - retjson = cJSON_CreateObject(); - jaddbits256(retjson,"hash",block.RO.hash2); - jaddstr(retjson,"data",blocktx); - if ( (newblock= _iguana_chainlink(virt,&block)) != 0 ) - { - jaddstr(retjson,"result","chain extended"); - jaddnum(retjson,"ht",block.height); - } else jaddstr(retjson,"error","couldnt extend chain"); - free(blocktx); - return(jprint(retjson,1)); - } - - char *basilisk_respond_getfield(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) - { - struct iguana_info *coin; cJSON *retjson; char chainname[BASILISK_MAXNAMELEN]; - if ( (coin= basilisk_chain(myinfo,chainname,valsobj)) == 0 ) - return(clonestr("{\"error\":\"couldnt get basilisk_chain\"}")); - printf("getfield\n"); - retjson = cJSON_CreateObject(); - return(jprint(retjson,1)); - } - /*int32_t basilisk_sendPUB(struct supernet_info *myinfo,uint32_t basilisktag,uint8_t *data,int32_t datalen) // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) - { - int32_t i,j,r,r2,s,k,val,l,n=0; uint32_t *alreadysent; struct iguana_info *coin; struct iguana_peer *addr; - alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); - r = rand(), r2 = rand(); - for (k=0; kpeers.active[i]) != 0 && addr->ipbits != 0 && addr->usock >= 0 && addr->basilisk != 0 ) - { - for (s=0; sipbits ) - break; - if ( s == n ) - { - printf("pub (%s) addr->supernet.%u to (%s).%d\n",(char *)&data[4],addr->supernet,addr->ipaddr,addr->A.port); - if ( (val= iguana_queue_send(addr,0,&data[-sizeof(struct iguana_msghdr)],"SuperNETpub",datalen)) >= datalen ) - { - alreadysent[n++] = (uint32_t)addr->ipbits; - if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) - break; - } - } - } - } - if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) - break; - } - free(alreadysent); - return(n); - }*/ - - struct iguana_info *_iguana_coinadd(char *symbol,cJSON *argjson) - { - struct iguana_info *coin; char *privatechain; int32_t pval,i = 0; - if ( symbol == 0 ) - { - printf("_iguana_coinadd deprecated null symbol\n"); - exit(-1); - } - else - { - for (i=0; i= sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) - break; - //printf("Hardcoded_coins[i][0] %s vs.(%s)\n",Hardcoded_coins[i][0],symbol); - //if ( symbol[0] == 0 ) - // getchar(); - if ( strcmp("endmarker",Hardcoded_coins[i][0]) == 0 || strcmp(symbol,Hardcoded_coins[i][0]) == 0 ) - { - if ( coin->chain == 0 ) - { - if ( i < sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) - strcpy(coin->name,Hardcoded_coins[i][1]); - else if (argjson != 0 ) - { - if ( jstr(argjson,"name") != 0 ) - safecopy(coin->name,jstr(argjson,"name"),sizeof(coin->name)); - else strcpy(coin->name,symbol); - } - } - return(coin); - } - } - } - return(0); - } - - void basilisk_pending_result(struct supernet_info *myinfo,struct basilisk_item *ptr,struct basilisk_item *pending) - { - int32_t n; basilisk_metricfunc metricfunc; - if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) ) - { - pending->numresults++; - if ( (metricfunc= pending->metricfunc) == 0 ) - pending->metrics[n] = n + 1; - else if ( (pending->metrics[n]= (*metricfunc)(myinfo,pending,ptr->retstr)) != 0. ) - pending->childrendone++; - printf("%s.%u Add results[%d] <- metric %f\n",pending->CMD,pending->basilisktag,n,pending->metrics[n]); - pending->results[n] = ptr->retstr, ptr->retstr = 0; - /*if ( strcmp(ptr->CMD,"SEQ") == 0 ) - { - if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) - { - gecko_seqresult(myinfo,ptr->retstr); - free_json(retjson); - } - } - else*/ - if ( strcmp(ptr->CMD,"RET") == 0 || strcmp(ptr->CMD,"GET") == 0 ) - { - printf("got return for tag.%d parent.%p\n",pending->basilisktag,pending->parent); - /*if ( (parent= pending->parent) != 0 ) - { - pending->parent = 0; - parent->childrendone++; - }*/ - if ( strcmp(ptr->CMD,"GET") == 0 ) - basilisk_geckoresult(myinfo,ptr->retstr); - } - } - } - - int32_t basilisk_issued_iteration(struct supernet_info *myinfo,struct basilisk_item *pending) - { - basilisk_metricfunc metricfunc; int32_t i,flag = 0; - //printf("pending.%u numresults.%d m %f func.%p\n",pending->basilisktag,pending->numresults,pending->metrics[0],pending->metricfunc); - if ( (metricfunc= pending->metricfunc) != 0 ) - { - for (i=0; inumresults; i++) - if ( pending->metrics[i] == 0. && pending->results[i] != 0 ) - { - if ( (pending->metrics[i]= (*metricfunc)(myinfo,pending,pending->results[i])) != 0 ) - pending->childrendone++; - // printf("iter.%d %p.[%d] poll metrics.%u metric %f\n",iter,pending,i,pending->basilisktag,pending->metrics[i]); - flag++; - } - } - /*basilisk_iscomplete(myinfo,pending); - if ( OS_milliseconds() > pending->expiration ) - { - if ( pending->finished == 0 ) - { - if ( (parent= pending->parent) != 0 ) - { - pending->parent = 0; - parent->childrendone++; - } - pending->finished = (uint32_t)time(NULL); - if ( pending->retstr == 0 ) - pending->retstr = clonestr("{\"error\":\"basilisk timeout\"}"); - fprintf(stderr,"timeout.%s call metrics.%u lag %f - %f\n",pending->CMD,pending->basilisktag,OS_milliseconds(),pending->expiration); - for (i=0; inumresults; i++) - if ( (metricfunc= pending->metricfunc) != 0 && pending->metrics[i] == 0. ) - pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); - flag++; - } - }*/ - //fprintf(stderr,"c"); - if ( pending->finished != 0 && time(NULL) > pending->finished+60 ) - { - if ( pending->dependents == 0 || pending->childrendone >= pending->numchildren ) - { - HASH_DELETE(hh,myinfo->basilisks.issued,pending); - if ( pending->dependents != 0 ) - free(pending->dependents); - //fprintf(stderr,"HASH_DELETE free ptr.%u refcount.%d\n",pending->basilisktag,pending->refcount); - for (i=0; inumresults; i++) - if ( pending->results[i] != 0 ) - free(pending->results[i]), pending->results[i] = 0; - //if ( pending->vals != 0 ) - // free_json(pending->vals), pending->vals = 0; - free(pending); - flag++; - } - } - return(flag); - } - - - int32_t basilisk_besti(struct basilisk_item *ptr) - { - int32_t i,besti = -1; double metric,bestmetric=-1.; - for (i=0; inumresults; i++) - { - if ( (metric= ptr->metrics[i]) > 0. ) - { - if ( (ptr->metricdir < 0 && (bestmetric < 0. || metric < bestmetric)) || (ptr->metricdir > 0 && (bestmetric < 0. || metric > bestmetric)) || (ptr->metricdir == 0 && bestmetric < 0.) ) - { - bestmetric = metric; - besti = i; - } - } - } - if ( besti >= 0 ) - { - for (ptr->numexact=i=0; inumresults; i++) - if ( fabs(ptr->metrics[i] - bestmetric) < SMALLVAL ) - ptr->numexact++; - } - return(besti); - } - - char *basilisk_iscomplete(struct supernet_info *myinfo,struct basilisk_item *ptr) - { - int32_t i,numvalid,besti=-1; char *errstr = 0,*retstr = 0; - if ( ptr->childrendone < ptr->numchildren ) - return(0); - if ( ptr->retstr != 0 || ptr->finished != 0 ) - return(ptr->retstr); - if ( (numvalid= ptr->numresults) >= ptr->numrequired ) - { - for (i=numvalid=0; inumresults; i++) - { - if ( ptr->metrics[i] != 0. ) - numvalid++; - } - } - if ( numvalid < ptr->numrequired ) - { - //printf("%u: numvalid.%d < required.%d m %f\n",ptr->basilisktag,numvalid,ptr->numrequired,ptr->metrics[0]); - return(0); - } - if ( ptr->uniqueflag == 0 && ptr->numexact != ptr->numresults && ptr->numexact < (ptr->numresults >> 1) ) - besti = -1, errstr = "[{\"error\":\"basilisk non-consensus results\"}]"; - else besti = basilisk_besti(ptr), errstr = "[{\"error\":\"basilisk no valid results\"}]"; - //printf("%u complete besti.%d\n",ptr->basilisktag,besti); - retstr = basilisk_finish(myinfo,ptr,besti,errstr); - //printf("%u besti.%d numexact.%d numresults.%d -> (%s)\n",ptr->basilisktag,besti,ptr->numexact,ptr->numresults,retstr); - return(retstr); - } - - char *basilisk_finish(struct supernet_info *myinfo,struct basilisk_item *ptr,int32_t besti,char *errstr) - { - char *str,*retstr = 0; int32_t i; struct basilisk_item *parent; cJSON *retarray,*item; - if ( ptr->retstr != 0 ) - return(ptr->retstr); - /*if ( besti >= 0 && besti < ptr->numresults ) - { - retstr = ptr->results[besti]; - ptr->results[besti] = 0; - } else printf("besti.%d vs numresults.%d retstr.%p\n",besti,ptr->numresults,retstr); - */ - if ( ptr->numresults > 0 ) - { - retarray = cJSON_CreateArray(); - for (i=0; inumresults; i++) - if ( (str= ptr->results[i]) != 0 ) - { - ptr->results[i] = 0; - if ( (item= cJSON_Parse(str)) != 0 ) - { - if ( jobj(item,"myip") == 0 ) - jaddstr(item,"myip",myinfo->ipaddr); - jaddi(retarray,item); - } else printf("couldnt parse.(%s)\n",str); - free(str); - } - retstr = jprint(retarray,1); - } - if ( retstr == 0 ) - retstr = clonestr(errstr); - ptr->retstr = retstr; - ptr->finished = (uint32_t)time(NULL); - if ( (parent= ptr->parent) != 0 ) - { - ptr->parent = 0; - parent->childrendone++; - } - return(retstr); - } - - char *basilisk_check(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) - { - if ( symbol != 0 && symbol[0] != 0 && vals != 0 ) - { - if ( *basilisktagp == 0 ) - *basilisktagp = rand(); - if ( (*timeoutmillisp= jint(vals,"timeout")) < 0 ) - *timeoutmillisp = BASILISK_TIMEOUT; - return(0); - } else return(clonestr("{\"error\":\"missing activecoin or vals\"}")); - } - - char *basilisk_standardcmd(struct supernet_info *myinfo,char *CMD,char *activecoin,char *remoteaddr,uint32_t basilisktag,cJSON *vals,basilisk_func func,basilisk_metricfunc metric) - { - char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; struct iguana_info *coin; - if ( (retstr= basilisk_check(&timeoutmillis,&basilisktag,activecoin,vals)) == 0 ) - { - if ( (coin= iguana_coinfind(activecoin)) != 0 ) - { - if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) - { - return(basilisk_waitresponse(myinfo,CMD,coin->symbol,remoteaddr,&Lptr,vals,ptr)); - } - else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}")); - } else return(clonestr("{\"error\":\"couldnt get coin\"}")); - } else return(retstr); - } - - char *_basilisk_value(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - struct iguana_info *coin; char *symbol; - if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) - { - if ( (coin= iguana_coinfind(symbol)) != 0 ) - return(basilisk_standardcmd(myinfo,"VAL",symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_value,coin->basilisk_valuemetric)); - } - return(clonestr("{\"error\":\"couldnt get coin\"}")); - } - - char *_basilisk_balances(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - struct iguana_info *coin; char *symbol; - if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) - { - if ( (coin= iguana_coinfind(symbol)) != 0 ) - return(basilisk_standardcmd(myinfo,"BAL",symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_balances,coin->basilisk_balancesmetric)); - } - return(clonestr("{\"error\":\"couldnt get coin\"}")); - } - - char *_basilisk_rawtx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - char *retstr,strbuf[4096],*symbol,*str = 0; struct iguana_info *coin; - if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) - { - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - printf("remote rawtx.(%s)\n",jprint(valsobj,0)); - basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); - retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - if ( str != 0 ) - free(str); - return(retstr); - } - } - return(clonestr("{\"error\":\"couldnt get coin\"}")); - } - - char *basilisk_waitresponse(struct supernet_info *myinfo,char *CMD,char *symbol,char *remoteaddr,struct basilisk_item *Lptr,cJSON *vals,struct basilisk_item *ptr) - { - char *retstr = 0; - if ( ptr == Lptr ) - { - //if ( (retstr= Lptr->retstr) == 0 ) - // retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}"); - //ptr = basilisk_itemcreate(myinfo,CMD,symbol,Lptr->basilisktag,Lptr->numrequired,vals,OS_milliseconds() - Lptr->expiration,0);//Lptr->metricfunc); - //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - retstr = Lptr->retstr; - } - else - { - //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - while ( OS_milliseconds() < ptr->expiration ) - { - //if ( (retstr= basilisk_iscomplete(ptr)) != 0 ) - if ( ptr->numresults >= ptr->numrequired || (retstr= ptr->retstr) != 0 ) - break; - usleep(50000); - } - if ( retstr == 0 ) - { - //ptr->finished = (uint32_t)time(NULL); - //retstr = clonestr("[{\"error\":\"basilisk wait timeout\"}]"); - free(ptr); - return(0); - } - } - basilisk_sendback(myinfo,CMD,symbol,remoteaddr,ptr->basilisktag,retstr); - return(retstr); - } - struct basilisk_item *basilisk_issuecmd(struct basilisk_item *Lptr,basilisk_func func,basilisk_metricfunc metricfunc,struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,int32_t timeoutmillis,cJSON *vals) - { - struct iguana_info *coin; struct basilisk_item *ptr; - memset(Lptr,0,sizeof(*Lptr)); - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - if ( func != 0 ) - { - if ( (ptr= (*func)(Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) - { - strcpy(ptr->symbol,symbol); - ptr->basilisktag = basilisktag; - ptr->expiration = OS_milliseconds() + timeoutmillis; - return(ptr); - } else Lptr->retstr = clonestr("{\"error\":\"error issuing basilisk command\"}"); - } else Lptr->retstr = clonestr("{\"error\":\"null basilisk function\"}"); - } else Lptr->retstr = clonestr("{\"error\":\"error missing coin\"}"); - return(Lptr); - } - /*int32_t gecko_chainvals(struct supernet_info *myinfo,char *CMD,cJSON *valsobj) - { - struct iguana_info *virt; struct gecko_chain *chain; bits256 hash,prevhash; struct iguana_block *block; char chainname[GECKO_MAXNAMELEN]; - if ( strcmp(CMD,"SET") == 0 || strcmp(CMD,"GET") == 0 ) - { - if ( (chain= gecko_chain(myinfo,chainname,valsobj)) == 0 || (virt= chain->info) == 0 ) - clonestr("{\"error\":\"cant find gecko chain\"}"); - if ( strcmp(CMD,"SET") == 0 ) - { - hash = GENESIS_PUBKEY; - if ( jobj(valsobj,"prev") != 0 ) - { - prevhash = jbits256(valsobj,"prev"); - if ( (block= iguana_blockfind("basilisk",virt,prevhash)) == 0 ) - { - char str[65]; printf("warning couldnt find %s in %s\n",bits256_str(str,prevhash),chainname); - prevhash = virt->blocks.hwmchain.RO.hash2; - } - } else prevhash = virt->blocks.hwmchain.RO.hash2; - hash = prevhash; - if ( jobj(valsobj,"prev") != 0 ) - jdelete(valsobj,"prev"); - } - return(0); - } - return(-1); - } - - cJSON *gecko_genesisargs(char *symbol,char *chainname,char *chain,char *keystr,char *genesishash,char *genesisblock,char *magicstr,uint16_t port,uint16_t blocktime,char *nbitstr,char *pubval,char *p2shval,char *wifval,uint32_t isPoS) - { - int32_t timespan,targetspacing; cJSON *argvals = cJSON_CreateObject(); - if ( genesishash != 0 && genesishash[0] != 0 ) - jaddstr(argvals,"genesishash",genesishash); - if ( genesisblock != 0 && genesisblock[0] != 0 ) - jaddstr(argvals,"genesisblock",genesisblock); - jaddstr(argvals,"netmagic",magicstr); - jaddstr(argvals,"symbol",symbol); - jaddstr(argvals,"name",chainname); - if ( pubval == 0 || is_hexstr(pubval,0) != 2 ) - pubval = "00"; - jaddstr(argvals,"pubval",pubval); - if ( p2shval == 0 || is_hexstr(p2shval,0) != 2 ) - p2shval = "05"; - jaddstr(argvals,"p2shval",p2shval); - if ( wifval == 0 || is_hexstr(wifval,0) != 2 ) - wifval = "80"; - jaddstr(argvals,"wifval",wifval); - if ( nbitstr == 0 || nbitstr[0] == 0 ) - nbitstr = GECKO_DEFAULTDIFFSTR; - jaddstr(argvals,"nBits",nbitstr); - jaddstr(argvals,"chain",chain); - if ( keystr != 0 ) - jaddstr(argvals,"key",keystr); - jaddnum(argvals,"isPoS",isPoS); - //printf("argvals isPoS.%d\n",isPoS); - if ( port == 0 ) - { - jaddstr(argvals,"geckochain",chainname); - jaddnum(argvals,"services",128); - } - else - { - jaddnum(argvals,"services",129); - jaddnum(argvals,"portp2p",port); - } - if ( blocktime == 0 ) - blocktime = 1; - jaddnum(argvals,"blocktime",blocktime); - if ( blocktime != 0 && 0 ) - { - if ( blocktime == 0xffff ) - targetspacing = 24 * 60 * 60; // one day - else targetspacing = blocktime; // one minute - jaddnum(argvals,"targetspacing",targetspacing); - if ( (timespan= sqrt(604800 / targetspacing)) < 7 ) - timespan = 7; - jaddnum(argvals,"targettimespan",targetspacing * timespan); - } - return(argvals); - } - - cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,char *symbol,char *chainname,cJSON *valsobj,char *magicstr,uint16_t blocktime) - { - char str2[64],hashstr[65],argbuf[1024],*pubstr,*p2shstr,*wifvalstr,*nbitstr,*blockstr; uint8_t buf[4]; int32_t i; uint32_t nBits; struct iguana_block genesis; - if ( (nbitstr= jstr(valsobj,"nBits")) == 0 ) - { - nBits = GECKO_DEFAULTDIFF; - nbitstr = GECKO_DEFAULTDIFFSTR; - } - else - { - for (i=0; i<4; i++) - decode_hex(&buf[3-i],1,&nbitstr[i*2]); - memcpy(&nBits,buf,sizeof(nBits)); - } - if ( (blocktime= juint(valsobj,"blocktime")) == 0 ) - blocktime = 1; - if ( (pubstr= jstr(valsobj,"pubval")) == 0 ) - pubstr = "00"; - if ( (p2shstr= jstr(valsobj,"p2shval")) == 0 ) - p2shstr = "05"; - if ( (wifvalstr= jstr(valsobj,"wifval")) == 0 ) - wifvalstr = "80"; - printf("json netmagic.%s\n",magicstr); - memset(&genesis,0,sizeof(genesis)); - genesis.RO.version = GECKO_DEFAULTVERSION; - genesis.RO.bits = nBits; - if ( (blockstr= gecko_createblock(myinfo,blocktime,0,btcd,isPoS,&genesis,symbol,0,0,10000,0,0)) != 0 ) - { - bits256_str(hashstr,genesis.RO.hash2); - sprintf(argbuf,"{\"isPoS\":%d,\"name\":\"%s\",\"symbol\":\"%s\",\"netmagic\":\"%s\",\"port\":%u,\"blocktime\":%u,\"pubval\":\"%s\",\"p2shval\":\"%s\",\"wifval\":\"%s\",\"isPoS\":%u,\"unitval\":\"%02x\",\"genesishash\":\"%s\",\"genesis\":{\"version\":1,\"timestamp\":%u,\"nBits\":\"%s\",\"nonce\":%d,\"merkle_root\":\"%s\"},\"genesisblock\":\"%s\"}",isPoS,chainname,symbol,magicstr,juint(valsobj,"port"),blocktime,pubstr,p2shstr,wifvalstr,juint(valsobj,"isPoS"),(nBits >> 24) & 0xff,hashstr,genesis.RO.timestamp,nbitstr,genesis.RO.nonce,bits256_str(str2,genesis.RO.merkle_root),blockstr); - free(blockstr); - printf("argbuf.(%s) hash.%s\n",argbuf,hashstr); - return(cJSON_Parse(argbuf)); - } else return(cJSON_Parse("{\"error\":\"couldnt create block\"}")); - } - - cJSON *gecko_genesisissue(char *symbol,char *chainname,char *chainstr,cJSON *valsobj) - { - printf("issue blocktime.%d\n",juint(valsobj,"blocktime")); - return(gecko_genesisargs(symbol,chainname,chainstr,jstr(valsobj,"key"),jstr(valsobj,"genesishash"),jstr(valsobj,"genesisblock"),jstr(valsobj,"netmagic"),juint(valsobj,"port"),juint(valsobj,"blocktime"),jstr(valsobj,"nBits"),jstr(valsobj,"pubval"),jstr(valsobj,"p2shval"),jstr(valsobj,"wifval"),juint(valsobj,"isPoS"))); - }*/ - /*char *basilisk_respond_newgeckochain(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) - { - struct iguana_info *virt,*btcd; struct gecko_chain *chain; char fname[512],*symbol,*retstr,*chainstr,chainname[GECKO_MAXNAMELEN],*genesises; cJSON *chainjson,*retjson,*genesisjson; long filesize; FILE *fp; - if ( (chain= gecko_chain(myinfo,chainname,valsobj)) != 0 && (virt= chain->info) != 0 ) - { - //printf("%s already exists\n",chainname); - return(clonestr("{\"error\":\"cant create duplicate geckochain\"}")); - } - if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(valsobj,"symbol")) != 0 && (chainstr= jstr(valsobj,"chain")) != 0 ) - { - if ( (virt= basilisk_geckochain(myinfo,symbol,chainname,valsobj)) != 0 ) - { - chain->info = virt; - if ( (retjson= gecko_genesisissue(symbol,chainname,chainstr,valsobj)) != 0 ) - { - jaddstr(retjson,"result","success"); - retstr = jprint(retjson,0); - sprintf(fname,"genesis/%s",symbol); - genesisjson = 0; - filesize = 0; - if ( (fp= fopen(fname,"wb")) != 0 ) - { - if ( fwrite(retstr,1,strlen(retstr),fp) == strlen(retstr) ) - { - if ( (genesises= OS_filestr(&filesize,"genesis/list")) != 0 ) - { - genesisjson = cJSON_Parse(genesises); - free(genesises); - } else genesisjson = cJSON_CreateArray(); - chainjson = cJSON_CreateObject(); - jaddstr(chainjson,"chain",chainname); - jaddstr(chainjson,"symbol",symbol); - jaddstr(chainjson,"agent","basilisk"); - jaddstr(chainjson,"method","newgeckochain"); - jadd(chainjson,"vals",retjson); - jaddi(genesisjson,chainjson); - } - fclose(fp); - } - if ( genesisjson != 0 ) - { - genesises = jprint(genesisjson,1); - if ( strlen(genesises) > filesize ) - { - if ( (fp= fopen("genesis/list","wb")) != 0 ) - { - fwrite(genesises,1,strlen(genesises),fp); - fclose(fp); - } - } - } else free_json(retjson); - return(retstr); - } else return(clonestr("{\"error\":\"couldnt create gecko genesis\"}")); - } - } - return(clonestr("{\"error\":-22}")); - } - - int32_t gecko_genesises(struct supernet_info *myinfo,cJSON *array) - { - char *chainstr,chainname[GECKO_MAXNAMELEN],*symbol; int32_t i,n,num=0; cJSON *item,*valsobj; struct iguana_info *btcd,*virt; struct gecko_chain *chain; - if ( (btcd= iguana_coinfind("BTCD")) == 0 ) - return(0); - if ( array != 0 && (n= cJSON_GetArraySize(array)) != 0 ) - { - for (i=0; iinfo) != 0 ) - { - //printf("%s %s already exists\n",chainname,symbol); - continue; - } - if ( (virt= basilisk_geckochain(myinfo,symbol,chainname,valsobj)) != 0 ) - { - myinfo->genesisresults++; - chain->info = virt; - num++; - } - } - } - } - return(num); - } - - char *basilisk_respond_geckogenesis(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 txid,int32_t from_basilisk) - { - long filesize; - return(OS_filestr(&filesize,"genesis/list")); - }*/ - /*HASH_ARRAY_STRING(basilisk,sequence,hash,vals,hexstr) - { - return(basilisk_standardservice("SEQ",myinfo,hash,vals,hexstr,1)); - } - - HASH_ARRAY_STRING(basilisk,newgeckochain,hash,vals,hexstr) - { - char chainname[GECKO_MAXNAMELEN],magicstr[9],*retstr=0,*symbol,*chainstr; struct iguana_info *btcd; cJSON *argjson,*argvals,*retjson=0; int32_t i,isPoS; uint32_t magic; struct gecko_chain *chain; - if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 && (chainstr= jstr(vals,"chain")) != 0 ) - { - if ( iguana_coinfind(symbol) == 0 && (chain= gecko_chain(myinfo,chainname,vals)) != 0 && chain->info != 0 ) - { - printf("%s already exists\n",chainname); - return(clonestr("{\"error\":\"cant create duplicate geckochain\"}")); - } - if ( jobj(vals,"netmagic") == 0 ) - { - OS_randombytes((void *)&magic,sizeof(magic)); - for (i=0; iFULLNODE != 0 || btcd->VALIDATENODE != 0 ) - { - basilisk_wait(myinfo,0); - retstr = basilisk_respond_newgeckochain(myinfo,"NEW",0,0,0,argvals,0,0,GENESIS_PUBKEY,0); - } - if ( retstr == 0 ) - retstr = basilisk_standardservice("NEW",myinfo,GENESIS_PUBKEY,argvals,0,1); - free_json(argvals); - if ( (argvals= cJSON_Parse(retstr)) != 0 ) - { - if ( jobj(argvals,"result") != 0 && strcmp(jstr(argvals,"result"),"success") == 0 ) - { - if ( basilisk_geckochain(myinfo,symbol,chainname,argvals) != 0 ) - jaddstr(argvals,"status","active"); - } else jaddstr(argvals,"error","couldnt initialize geckochain"); - free(retstr); - return(jprint(argvals,1)); - } - if ( retjson != 0 ) - free_json(retjson); - free_json(argvals); - return(retstr); - } else return(clonestr("{\"error\":\"couldnt create genesis_block\"}")); - } - return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko chain\"}")); - }*/ - - /*HASH_ARRAY_STRING(basilisk,geckogenesis,hash,vals,hexstr) - { - long filesize; int32_t i,j,n,m; struct iguana_info *btcd; char *ref,*symbol,*retstr=0; cJSON *item,*array = 0,*arrayB = 0; FILE *fp; - if ( (btcd= iguana_coinfind("BTCD")) != 0 ) - { - if ( (retstr= basilisk_standardservice("GEN",myinfo,hash,vals,hexstr,1)) != 0 ) - { - arrayB = cJSON_Parse(retstr); - free(retstr); - } - if ( btcd->FULLNODE != 0 || btcd->VALIDATENODE != 0 ) - { - if ( (retstr= OS_filestr(&filesize,"genesis/list")) != 0 ) - { - array = cJSON_Parse(retstr); - free(retstr); - } - if ( array == 0 ) - array = arrayB; - else if ( arrayB != 0 ) - { - if ( (n= cJSON_GetArraySize(array)) > 0 ) - { - if ( (m= cJSON_GetArraySize(arrayB)) > 0 ) - { - for (j=0; j> 1; - if ( siglen < sizeof(sig) ) - { - decode_hex(sig,siglen,sigstr); - vcalc_sha256(0,txhash2.bytes,data,datalen); - memset(pubkey33,0,33); - if ( bitcoin_recoververify(myinfo->ctx,"BTCD",sig,txhash2,pubkey33) == 0 ) - { - // compare with existing - init_hexbytes_noT(pubstr,pubkey33,33); - printf(" verified relay data siglen.%d pub33.%s\n",siglen,pubstr); - if ( (retstr= basilisk_addrelay_info(myinfo,pubkey33,(uint32_t)calc_ipbits(remoteaddr),hash)) != 0 ) - free(retstr); - n = (int32_t)(datalen / sizeof(uint32_t)); - for (i=len=0; irelaybits)]; cJSON *vals; bits256 hash; char *retstr,hexstr[sizeof(myinfo->relaybits)*2 + 1]; - //printf("skip sending relays\n"); - if ( 0 && myinfo != 0 ) - { - vals = cJSON_CreateObject(); - hash = myinfo->myaddr.persistent; - for (i=0; inumrelays; i++) - len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&myinfo->relaybits[i]); - init_hexbytes_noT(hexstr,serialized,len); - //printf("send relays.(%s)\n",hexstr); - vcalc_sha256(0,txhash2.bytes,serialized,len); - if ( 0 && bits256_nonz(myinfo->persistent_priv) != 0 && (siglen= bitcoin_sign(myinfo->ctx,"BTCD",sig,txhash2,myinfo->persistent_priv,1)) > 0 ) - { - init_hexbytes_noT(strbuf,sig,siglen); - jaddstr(vals,"sig",strbuf); - } - if ( (retstr= basilisk_standardservice("RLY",myinfo,hash,vals,hexstr,0)) != 0 ) - free(retstr); - free_json(vals); - return(0); - } else return(-1); - } - - char *basilisk_respond_relays(struct supernet_info *myinfo,char *CMD,void *_addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) - { - uint32_t *ipbits = (uint32_t *)data; int32_t num,i,j,n = datalen >> 2; - for (i=num=0; inumrelays; j++) - if ( ipbits[i] == myinfo->relays[j].ipbits ) - break; - if ( j == myinfo->numrelays ) - { - num++; - printf("i.%d j.%d ensure new relay.(%s)\n",i,j,remoteaddr); - basilisk_ensurerelay(iguana_coinfind("BTCD"),ipbits[i]); - } - } - if ( num == 0 ) - return(clonestr("{\"result\":\"no new relays found\"}")); - else return(clonestr("{\"result\":\"relay added\"}")); - }*/ - - /*char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) - { - cJSON *addresses=0; char *changeaddr,*spendscriptstr; int32_t i,n; - *timeoutmillisp = -1; - changeaddr = jstr(vals,"changeaddr"); - spendscriptstr = jstr(vals,"spendscript"); - addresses = jarray(&n,vals,"addresses"); - if ( addresses == 0 || changeaddr == 0 || changeaddr[0] == 0 ) - return(clonestr("{\"error\":\"invalid addresses[] or changeaddr\"}")); - else - { - for (i=0; ibasilisk_rawtx,coin->basilisk_rawtxmetric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) - { - if ( (ptr->numrequired= juint(vals,"numrequired")) == 0 ) - ptr->numrequired = 1; - //ptr->uniqueflag = 1; - //ptr->metricdir = -1; - return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,vals,ptr)); - } else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}")); - } //else return(retstr);*/ - /*int32_t basilisk_request_pending(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t requestid) - { - int32_t i,j,n,alreadystarted = 0; struct basilisk_relay *relay; uint32_t quoteid; - portable_mutex_lock(&myinfo->DEX_reqmutex); - for (j=0; jnumrelays; j++) - { - relay = &myinfo->relays[j]; - if ( (n= relay->numrequests) > 0 ) - { - for (i=0; irequests[i].requestid == requestid && relay->requests[i].quoteid == quoteid ) - { - alreadystarted = 1; - break; - } - } - } - } - portable_mutex_unlock(&myinfo->DEX_reqmutex); - return(alreadystarted); - } - - void basilisk_request_check(struct supernet_info *myinfo,struct basilisk_request *rp) - { - double retvals[4],aveprice; struct basilisk_request R; struct iguana_info *src,*dest; char message[128]; uint32_t quoteid; - if ( (src= iguana_coinfind(rp->src)) != 0 && (dest= iguana_coinfind(rp->dest)) != 0 ) - { - if ( basilisk_request_pending(myinfo,&R,rp->requestid) == 0 ) - { - aveprice = instantdex_avehbla(myinfo,retvals,rp->src,rp->dest,dstr(rp->srcamount)); - quoteid = rp->requestid ^ myinfo->myaddr.persistent.uints[0]; - sprintf(message,"{\"price\":%.8f,\"requestid\":%u,\"quoteid\":%u}",aveprice,rp->requestid,quoteid); - if ( basilisk_request_enqueue(myinfo,rp->hash,rp->src,rp->srcamount*aveprice,myinfo->myaddr.persistent,rp->dest,rp->srcamount*aveprice,message,quoteid) != rp->requestid ) - printf("error creating quoteid\n"); - } - } - }*/ - - /*double basilisk_bitcoin_rawtxmetric_dependents(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_item *ptr,struct bitcoin_rawtxdependents *dependents) - { - int32_t i,j,numaddrs,notfinished = 0; cJSON *childjson,*addresses; struct basilisk_item *child; double metric = 0.; char *childstr,*coinaddr; int64_t inputsum,value,txfee; - for (i=0; inumptrs; i++) - { - if ( (child= dependents->ptrs[i]) != 0 ) - { - if ( ptr->finished != 0 ) - { - //printf("parent finished\n"); - if ( child->finished == 0 ) - { - ptr->childrendone++; - child->finished = (uint32_t)time(NULL); - } - } - else if ( child->finished == 0 ) - notfinished++; - } - } - if ( notfinished != 0 ) - { - if ( ptr->finished != 0 ) - return(-13.); - else return(0.); - } - else if ( ptr->vals != 0 ) - { - if ( (txfee= j64bits(ptr->vals,"txfee")) == 0 ) - txfee = coin->chain->txfee; - if ( txfee == 0 ) - txfee = 10000; - addresses = jarray(&numaddrs,ptr->vals,"addresses"); - printf("got all inputs:\n"); - for (inputsum=i=0; inumptrs; i++) - { - if ( (child= dependents->ptrs[i]) != 0 && (childstr= child->retstr) != 0 ) - { - printf("childi.%d (%s)\n",i,childstr); - coinaddr = &dependents->coinaddrs[64*i]; - if ( (childjson= cJSON_Parse(childstr)) != 0 ) - { - if ( (value= j64bits(childjson,"satoshis")) != 0 ) - { - inputsum += value; - for (j=0; jretstr = 0; - } - } - if ( (inputsum - dependents->outputsum) != txfee ) - { - printf("inputsum %.8f - outputsum %.8f = %.8f != txfee %.8f\n",dstr(inputsum),dstr(dependents->outputsum),dstr(inputsum)-dstr(dependents->outputsum),dstr(txfee)); - return(-1001.); // error - } - //printf("dependents cost %lld\n",(long long)dependents->cost); - return(dstr(dependents->cost)); - } else return(-666.); // no vals?? - } - - double basilisk_bitcoin_rawtxmetric(struct supernet_info *myinfo,struct basilisk_item *ptr,char *resultstr) - { - cJSON *txobj,*vouts,*vin,*sobj,*addrs,*vins,*argvals,*resultsobj,*addresses; int64_t outputsum=0,amount=0,cost = 0; int32_t i,m,numaddrs,spendlen,n; struct iguana_msgtx msgtx; uint8_t extraspace[8192],script[IGUANA_MAXSCRIPTSIZE],serialized[16384],asmtype; struct vin_info V; char *scriptstr,*changeaddr,*coinaddr,*rawtx,*spendscriptstr; bits256 txid; struct iguana_info *coin; struct basilisk_item Lsubptr,*child; struct bitcoin_rawtxdependents *dependents=0; double metric; uint32_t locktime; - if ( (coin= iguana_coinfind(ptr->symbol)) != 0 ) - { - if ( (dependents= ptr->dependents) != 0 ) - { - if ( (metric= basilisk_bitcoin_rawtxmetric_dependents(myinfo,coin,ptr,dependents)) != 0. ) - { - for (i=0; inumptrs; i++) - if ( (child= dependents->ptrs[i]) != 0 ) - child->parent = 0; - } - return(metric); - } - if ( (resultsobj= cJSON_Parse(resultstr)) == 0 || (vins= jobj(resultsobj,"vins")) == 0 || (rawtx= jstr(resultsobj,"rawtx")) == 0 ) - { - if ( resultsobj != 0 ) - free_json(resultsobj); - printf("resultstr error.(%s)\n",resultstr); - return(-1.); // error - } - if ( (spendscriptstr= jstr(ptr->vals,"spendscript")) != 0 ) - { - spendlen = (int32_t)strlen(spendscriptstr) >> 1; - decode_hex(script,spendlen,spendscriptstr); - } - changeaddr = jstr(ptr->vals,"changeaddr"); - locktime = juint(ptr->vals,"locktime"); - amount = j64bits(ptr->vals,"satoshis"); - addresses = jarray(&numaddrs,ptr->vals,"addresses"); - if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,rawtx,extraspace,sizeof(extraspace),serialized)) != 0 ) - { - //printf("GOT VINS.(%s) rawtx.(%s) out0 %.8f\n",jprint(vins,0),rawtx,dstr(msgtx.vouts[0].value)); - if ( juint(txobj,"locktime") != locktime ) - { - printf("locktime mismatch %u != %u\n",juint(txobj,"locktime"),locktime); - return(-2.); // error - } - else if ( jobj(txobj,"error") == 0 && cJSON_GetArraySize(vins) == msgtx.tx_in ) - { - dependents = calloc(1,sizeof(*dependents) + msgtx.tx_in*(sizeof(*dependents->results) + sizeof(*dependents->ptrs) + 64)); - dependents->results = (void *)&dependents->ptrs[msgtx.tx_in]; - dependents->coinaddrs = (void *)&dependents->results[msgtx.tx_in]; - dependents->numptrs = msgtx.tx_in; - ptr->dependents = dependents; - ptr->numchildren = dependents->numptrs; - for (i=0; i> 1; - decode_hex(V.spendscript,V.spendlen,scriptstr); - asmtype = _iguana_calcrmd160(coin,&V); - coinaddr = &dependents->coinaddrs[64 * i]; - //if ( asmtype == IGUANA_SCRIPT_76A988AC || asmtype == IGUANA_SCRIPT_AC || asmtype == IGUANA_SCRIPT_76AC || asmtype == IGUANA_SCRIPT_P2SH ) - bitcoin_address(coinaddr,coin->chain->pubtype,V.rmd160,20); - if ( (argvals= cJSON_CreateObject()) != 0 ) - { - jaddbits256(argvals,"txid",jbits256(vin,"txid")); - jaddnum(argvals,"timeout",ptr->expiration - OS_milliseconds()); - jaddnum(argvals,"vout",jint(vin,"vout")); - jaddstr(argvals,"address",coinaddr); - if ( (dependents->ptrs[i]= basilisk_bitcoinvalue(&Lsubptr,myinfo,coin,0,rand(),(ptr->expiration - OS_milliseconds()) * .777,argvals)) != 0 ) - { - if ( dependents->ptrs[i] == &Lsubptr ) - { - dependents->results[i] = Lsubptr.retstr; - dependents->ptrs[i] = 0; - } - else dependents->ptrs[i]->parent = ptr; - } - free_json(argvals); - } - } else printf("cant find spend info.(%s)\n",jprint(vin,0)); - } - if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n == msgtx.tx_out ) - { - for (i=0; ispentsatoshis = msgtx.vouts[i].value; - continue; - } - else - { - if ( (sobj= jobj(jitem(vouts,i),"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 ) - { - if ( m == 1 && strcmp(jstri(addrs,0),changeaddr) == 0 ) - { - dependents->change = msgtx.vouts[i].value; - printf("verify it is normal spend for %s %.8f\n",changeaddr,dstr(msgtx.vouts[i].value)); - continue; - } - } - } - cost += msgtx.vouts[i].value; - //printf("boost cost %.8f\n",dstr(msgtx.vouts[i].value)); - } - } - } - free_json(txobj); - } - } - if ( dependents->spentsatoshis != amount ) - { - printf("spentsatoshis %.8f != expected %.8f, change %.8f\n",dstr(dependents->spentsatoshis),dstr(amount),dstr(dependents->change)); - return(-1000.); // error - } - if ( (dependents->outputsum= outputsum) <= 0 ) - { - printf("illegal outputsum %.8f\n",dstr(outputsum)); - return(-1001.); // error - } - if ( cost == 0 ) - cost = 1; - dependents->cost = cost; - return(0.); - }*/ - /*n = queue_size(&validateQ) / IGUANA_NUMHELPERS + 1; - printf("vQ is n.%d\n",n); - for (iter=0; iterbp) != 0 && (coin= ptr->coin) != 0 && coin->active != 0 ) - { - printf("helper.%d validate.[%d] %d vs %d\n",helperid,bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize,(coin->longestchain-1)/coin->chain->bundlesize); - if ( coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-1)/coin->chain->bundlesize ) - flag += iguana_bundlevalidate(coin,bp,0); - else - { - usleep(10000); - printf("requeue vQ.[%d]\n",bp->hdrsi); - iguana_validateQ(coin,bp); - } - } - else if ( coin->active != 0 ) - printf("helper validate missing param? %p %p\n",ptr->coin,ptr->bp); - myfree(ptr,ptr->allocsize); - flag++; - }*/ - - /*int32_t iguana_inv2poll(struct supernet_info *myinfo,struct iguana_info *coin) - { - struct exchange_info *exchange; int32_t i,n=0; struct iguana_peer *addr; char myipaddr[64]; - expand_ipbits(myipaddr,myinfo->myaddr.myipbits); - //printf("iguana_inv2poll exchange.%p %s maxpeers.%d\n",exchanges777_find("bitcoin"),coin->symbol,coin->MAXPEERS); - if ( coin != 0 && coin->peers != 0 && (exchange= exchanges777_find("bitcoin")) != 0 && strcmp(coin->symbol,"BTCD") == 0 ) - { - if ( time(NULL) > coin->lastinv2+10 ) - { - coin->lastinv2 = (uint32_t)time(NULL); - for (i=n=0; iMAXPEERS; i++) - { - addr = &coin->peers->active[i]; - if ( addr->supernet != 0 ) - { - //printf("iguana_inv2poll (%s) usock.%d dead.%u ready.%u ipbits.%u supernet.%d\n",addr->ipaddr,addr->usock,addr->dead,addr->ready,(uint32_t)addr->ipbits,addr->supernet); - if ( addr->usock >= 0 && addr->dead == 0 && addr->ready != 0 && addr->ipbits != 0 && strcmp(addr->ipaddr,myipaddr) != 0 ) - { - instantdex_inv2data(myinfo,coin,addr,exchange); - n++; - } - } - } - } - } - return(n); - }*/ - - continue; - for (i=bp->hdrsi; i>=0; i--) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - ramchain = 0; - if ( iguana_pkhashfind(coin,&ramchain,&deposits,&lastunspentind,&p,rmd160,i,i) != 0 && (rdata= ramchain->H.data) != 0 ) - { - spent = 0; - deposits = 0; - unspentind = lastunspentind; - U = RAMCHAIN_PTR(rdata,Uoffset); - T = RAMCHAIN_PTR(rdata,Toffset); - while ( unspentind > 0 ) - { - if ( iguana_spentflag(myinfo,coin,&RTspend,&spentheight,ramchain,i,unspentind,lastheight,0,1<<31,U[unspentind].value) == 0 ) - deposits += U[unspentind].value; - else spent += U[unspentind].value; - unspentind = U[unspentind].prevunspentind; - } - weights[pkind] += (deposits - spent); - /*if ( (A2= ramchain->A2) != 0 && p.pkind > 0 && p.pkind < rdata->numpkinds && (U2= ramchain->Uextras) != 0 ) - { - T = RAMCHAIN_PTR(rdata,Toffset); - U = RAMCHAIN_PTR(rdata,Uoffset); - unspentind = A2[p.pkind].lastunspentind; - while ( unspentind > 0 ) - { - uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]); - if ( uheight < lastheight ) - spent += U[unspentind].value; - unspentind = U2[unspentind].prevunspentind; - } - weights[pkind] -= spent; - } else printf("PoS.[%d] rdata.%p or A2.%p error [%d] pkind.%d\n",pkind,rdata,A2,i,p.pkind);*/ - if ( weights[pkind] != 0 ) - printf("wt %.8f P.%d -> [%d] pkind.%d deposits %.8f spent %.8f\n",dstr(weights[pkind]),pkind,i,p.pkind,dstr(deposits),dstr(spent)); - } - } - /*if ( (retstr= iguana_orderbook("bitfinex","BTC","USD",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Fbtc_usd,"bitfinex","BTC","USD",retstr,1)) != 0 ) - { - Fbtc = _pairaved(avebtc,aveprice); - avebtc = _pairaved(Ebtc,Fbtc); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("btce","BTC","USD",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Ebtc_usd,"btce","BTC","USD",retstr,1)) != 0 ) - { - Ebtc = _pairaved(avebtc,aveprice); - avebtc = _pairaved(Ebtc,Fbtc); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("bittrex","SBD","BTC",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Bsbd_btc,"bittrex","SBD","BTC",retstr,10)) != 0 ) - { - Bsbd = _pairaved(avesbd,aveprice); - avesbd = _pairaved(Bsbd,Psbd); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("poloniex","SBD","BTC",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Psbd_btc,"poloniex","SBD","BTC",retstr,10)) != 0 ) - { - Psbd = _pairaved(avesbd,aveprice); - avesbd = _pairaved(Bsbd,Psbd); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("bittrex","STEEM","BTC",10)) != 0 ) - { - if ( (aveprice= tradebots_update(&Bsteem_btc,"bittrex","STEEM","BTC",retstr,100)) != 0 ) - { - Bsteem = _pairaved(avesteem,aveprice); - avesteem = _pairaved(Bsteem,Psteem); - } - free(retstr); - } - if ( (retstr= iguana_orderbook("poloniex","STEEM","BTC",10)) != 0 ) - { - //printf("retstr.(%s)\n",retstr); - if ( (aveprice= tradebots_update(&Psteem_btc,"poloniex","STEEM","BTC",retstr,100)) != 0 ) - { - Psteem = _pairaved(avesteem,aveprice); - avesteem = _pairaved(Bsteem,Psteem); - } - free(retstr); - }*/ - - uint32_t basilisk_msgid(struct supernet_info *myinfo,uint32_t channel,bits256 hash,uint8_t *data,int32_t datalen) - { - struct message_info *mp; bits256 msghash; uint32_t now; int32_t i,j,firstj,firsti = -1; - vcalc_sha256(0,msghash.bytes,data,datalen); - //msghash.bytes[0] = channel & 0xff; - //msghash.bytes[1] = (channel >> 8) & 0xff; - //msghash.bytes[2] = (channel >> 16) & 0xff; - now = (uint32_t)time(NULL); - for (i=0; imsgids)/sizeof(*myinfo->msgids); i++) - { - mp = &myinfo->msgids[i]; - if ( mp->msgcount != 0 ) - { - if ( bits256_cmp(hash,mp->refhash) == 0 ) - { - firstj = -1; - for (j=0; jmsgcount; j++) - { - if ( mp->timestamps[j] != 0 ) - { - if ( now > mp->timestamps[j]+30 ) - memset(mp,0,sizeof(*mp)); - else if ( bits256_cmp(msghash,mp->msghashes[j]) == 0 ) - return(j + 1); - } - if ( firstj < 0 && mp->timestamps[j] == 0 ) - firstj = j; - } - if ( firstj >= 0 ) - { - mp->msghashes[firstj] = msghash; - mp->timestamps[firstj] = (uint32_t)time(NULL); - return(firstj + 1); - } - if ( mp->msgcount < sizeof(mp->msghashes)/sizeof(*mp->msghashes) ) - { - j = mp->msgcount++; - mp->msghashes[j] = msghash; - mp->timestamps[j] = (uint32_t)time(NULL); - return(j + 1); - } else return(0); - } - } else if ( firsti < 0 ) - firsti = i; - } - if ( firsti >= 0 ) - { - mp = &myinfo->msgids[firsti]; - mp->msghashes[0] = msghash; - mp->timestamps[0] = (uint32_t)time(NULL); - mp->msgcount = 1; - mp->refhash = hash; - return(1); - } else return(0); - } -#endif -#endif diff --git a/deprecated/steemit_parser.c b/deprecated/steemit_parser.c new file mode 100644 index 000000000..d3ddb74bd --- /dev/null +++ b/deprecated/steemit_parser.c @@ -0,0 +1,384 @@ +/****************************************************************************** + * Copyright © 2016 jl777 * + * ALL RIGHTS RESERVED * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +int32_t init_startheight(int32_t startheight) +{ + long filesize; int32_t height; char *heightstr; + if ( (heightstr= OS_filestr(&filesize,TRADEBOT_NAME)) != 0 ) + { + height = atoi(heightstr); + free(heightstr); + if ( height > 0 && height < startheight ) + startheight = height; + } + return(startheight); +} + +void steemit_history_limitorder(int32_t ind,char *acount,cJSON *opitem) +{ + // hwm.12081 flag.1 limit_order_create ({"owner":"taker","orderid":1469136578,"amount_to_sell":"24.346 SBD","min_to_receive":"7.770 STEEM","fill_or_kill":false,"expiration":"2016-07-24T23:21:24"}) +} + +void steemit_update_inventory(double *SBD,double *SBDVOL,double *STEEMVOL,double *STEEM,double myvol,char *mycoin,char *other,double othervol,char *othercoin) +{ + if ( strcmp(mycoin,"SBD") == 0 && strcmp(othercoin,"STEEM") == 0 ) + { + *SBD -= myvol; + *SBDVOL += myvol; + *STEEM += othervol; + *STEEMVOL += othervol; + } + else if ( strcmp(mycoin,"STEEM") == 0 && strcmp(othercoin,"SBD") == 0 ) + { + *STEEM -= myvol; + *STEEMVOL += myvol; + *SBD += othervol; + *SBDVOL += othervol; + } else printf("steemit_update_inventory: unexpected pair (%s) (%s)\n",mycoin,othercoin); +} + +void steemit_history_fillorder(int32_t ind,char *account,cJSON *opitem) +{ + static double SBD,STEEM,SBDVOL,STEEMVOL; + char *taker,*maker,*takercoin,*makercoin; uint64_t openorderid,fillorderid; double takervol,makervol; + taker = jstr(opitem,"current_owner"); + fillorderid = j64bits(opitem,"current_orderid"); + takercoin = jstr(opitem,"current_pays"); + maker = jstr(opitem,"open_owner"); + openorderid = j64bits(opitem,"open_orderid"); + makercoin = jstr(opitem,"open_pays"); + if ( taker != 0 && maker != 0 && takercoin != 0 && makercoin != 0 && (strcmp(account,taker) == 0 || strcmp(maker,account) == 0) ) + { + takervol = atof(takercoin); + while ( *takercoin != 0 && *takercoin != ' ' ) + takercoin++; + makervol = atof(makercoin); + while ( *makercoin != 0 && *makercoin != ' ' ) + makercoin++; + if ( strcmp(taker,account) == 0 ) + { + steemit_update_inventory(&SBD,&SBDVOL,&STEEMVOL,&STEEM,takervol,takercoin+1,maker,makervol,makercoin+1); + printf("%6d %s.(%.6f%s) <-> %s.(%.6f%s) SBD %.6f STEEM %.6f | VOL SBD %.6f STEEM %.6f-> %.6f\n",ind,taker,takervol,takercoin,maker,makervol,makercoin,SBD,STEEM,SBDVOL,STEEMVOL,SBD/STEEM); + } + else + { + steemit_update_inventory(&SBD,&SBDVOL,&STEEMVOL,&STEEM,takervol,takercoin+1,maker,makervol,makercoin+1); + printf("%6d %s.(%.6f%s) <-> %s.(%.6f%s) SBD %.6f STEEM %.6f | VOL SBD %.6f STEEM %.6f-> %.6f\n",ind,maker,makervol,makercoin,taker,takervol,takercoin,SBD,STEEM,SBDVOL,STEEMVOL,SBD/STEEM); + } + } + //hwm.12077 flag.1 fill_order ({"current_owner":"enki","current_orderid":3402053187,"current_pays":"19.613 SBD","open_owner":"taker","open_orderid":1469136521,"open_pays":"5.792 STEEM"}) + +} + +void steemit_tradehistory(char *account) +{ + int32_t j,n,m,ind,flag = 1,hwm = 0; cJSON *retjson,*result,*item,*oparray,*opitem; char *opstr,*retstr; + while ( flag != 0 ) + { + flag = 0; + if ( (retstr= STEEM_gethistory(account,hwm+1,1)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (result= jarray(&n,retjson,"result")) != 0 ) + { + for (j=0; j %s",key,fname); + system(cmd); + if ( (str2= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (json2= cJSON_Parse(str2)) != 0 ) + { + if ( (postingkey= jstr(json2,"result")) != 0 ) + { + //miner = ["supernet", "5J4gTpk4CMBdPzgaRj7yNXDZTzBBQ41bNyJTqHbBi7Ku6v75bXa"] + //fprintf(postingkeys,"miner = [\"%s\", \"%s\"]\n",name,postingkey); + fprintf(postingkeys,"witness = \"%s\"\n",name); + //fprintf(postingkeys,"{ \"%s\", \"%s\" },",name,postingkey); + } + else printf("no result in (%s)\n",jprint(json2,0)); + free_json(json2); + } else printf("couldnt parse (%s)\n",str2); + free(str2); + } else printf("couldnt load (%s)\n",fname); + } + } + } + } + fprintf(postingkeys,"\n};\n"); + fclose(postingkeys); + } + free_json(json); + } + free(str); + } +} + +void tradebots_LP(char *configjsonstr,char *arg) +{ + char *retstr,*cmdstr; int32_t i,tallymode=0,repeat,lastheight=0,j,n,one,height = -1; cJSON *obj,*json,*operations,*item,*retjson,*result,*props,*transactions; + if ( configjsonstr != 0 && (json= cJSON_Parse(configjsonstr)) != 0 ) + { + // process config + free_json(json); + } + strcpy(Articles.name,"Articles"); + strcpy(Comments.name,"Comments"); + strcpy(Votes.name,"Votes"); + if ( (retstr= STEEM_getstate(0)) == 0 ) + return; + for (i=0; i= 0 ) + { + if ( tallymode != 0 && height == Startheight ) + { + printf("reached Startheight.%d, getchar()\n",Startheight); + steemit_summary(Startheight); + getchar(); + exit(0); + } + if ( (retstr= STEEM_getblock(height)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (result= jobj(retjson,"result")) != 0 ) + { + if ( (transactions= jarray(&n,result,"transactions")) != 0 ) + { + if ( tallymode == 0 ) + printf("lag.%d ht.%d n.%d\n",height-Startheight,height,n); + for (i=0; i= Startheight) && strcmp("comment",cmdstr) == 0 ) + steemit_comment(height,i,j,obj,height >= Startheight); + else if ( height >= Startheight ) + { + if ( strcmp("limit_order_create",cmdstr) == 0 ) + steemit_limitorder(height,i,j,obj); + else if ( strcmp("convert",cmdstr) == 0 ) + steemit_convert(height,i,j,obj); + else if ( strcmp("custom_json",cmdstr) == 0 ) + steemit_customjson(height,i,j,obj); + else if ( strcmp("transfer_to_vesting",cmdstr) == 0 ) + steemit_powerup(height,i,j,obj); + else if ( strcmp("account_update",cmdstr) == 0 ) + steemit_accountupdate(height,i,j,obj); + else if ( strcmp("transfer",cmdstr) == 0 ) + steemit_transfer(height,i,j,obj); + else if ( strcmp("limit_order_cancel",cmdstr) == 0 ) + steemit_cancelorder(height,i,j,obj); + else if ( strcmp("delete_comment",cmdstr) == 0 ) + steemit_deletecomment(height,i,j,obj); + else if ( strcmp("pow",cmdstr) == 0 ) + steemit_pow(height,i,j,obj); + else if ( strcmp("feed_publish",cmdstr) == 0 ) + steemit_feedpublish(height,i,j,obj); + else if ( strcmp("withdraw_vesting",cmdstr) == 0 ) + steemit_powerdown(height,i,j,obj); + else if ( strcmp("account_witness_vote",cmdstr) == 0 ) + steemit_accountwitness(height,i,j,obj); + else printf("%d.%d.%d: %s.(%s)\n",height,i,j,cmdstr,jprint(obj,0)); + } + } else printf("%d.%d: unexpected paired item.(%s)\n",height,i,jprint(item,0)); + } else printf("%d.%d: unexpected unpaired item.(%s)\n",height,i,jprint(item,0)); + } + } + } + } else if ( is_cJSON_Null(result) == 0 && jstr(result,"previous") == 0 ) + printf("ht.%d no transactions in result.(%s)\n",height,jprint(result,0)); + if ( is_cJSON_Null(result) == 0 ) + { + FILE *fp; + if ( (fp= fopen(TRADEBOT_NAME,"wb")) != 0 ) + { + // printf("startheight.%d for %s\n",height,TRADEBOT_NAME); + fprintf(fp,"%d\n",height); + fclose(fp); + } else printf("error saving startheight.%d for %s\n",height,TRADEBOT_NAME); + height++, repeat = 0; + if ( 0 && tallymode != 0 && (height % 1000) == 0 ) + disp_vote_totals(height); + } + } else printf("ht.%d no result in (%s)\n",height,jprint(retjson,0)); + //printf("ht.%d blockstr.(%s)\n",height,retstr); + free_json(retjson); + } else printf("ht.%d couldnt parse.(%s)\n",height,retstr); + free(retstr); + } else printf("error getting ht.%d\n",height); + if ( height >= Startheight ) + sleep(1); + if ( height == lastheight && ++repeat > 3 ) + height++, repeat = 0, lastheight = height; +#ifdef __APPLE__ + continue; +#endif + } + printf("done whale watching, hope you enjoyed the show\n"); +} diff --git a/gecko/gecko.c b/gecko/gecko.c index 496279174..f8bdaeea3 100755 --- a/gecko/gecko.c +++ b/gecko/gecko.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -52,7 +52,7 @@ void gecko_iteration(struct supernet_info *myinfo,struct iguana_info *btcd,struc //iguana_update_balances(virt); //iguana_realtime_update(myinfo,virt); } - if ( 0 && hwmhdrsi <= longesthdrsi )//&& virt->blocks.hwmchain.height < virt->longestchain-1 ) + if ( (0) && hwmhdrsi <= longesthdrsi )//&& virt->blocks.hwmchain.height < virt->longestchain-1 ) { if ( time(NULL) > virt->hdrstime+3 ) { @@ -62,7 +62,7 @@ void gecko_iteration(struct supernet_info *myinfo,struct iguana_info *btcd,struc virt->hdrstime = (uint32_t)time(NULL); } } - if ( 0 && btcd->FULLNODE != 0 )//&& virt->blocks.hwmchain.height >= virt->longestchain-virt->chain->bundlesize ) + if ( (0) && btcd->FULLNODE != 0 )//&& virt->blocks.hwmchain.height >= virt->longestchain-virt->chain->bundlesize ) { bitcoin_address(mineraddr,virt->chain->pubtype,myinfo->persistent_pubkey33,33); //fprintf(stderr,"mine.%s %s\n",virt->symbol,mineraddr); @@ -179,9 +179,11 @@ struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbo virt->chain = calloc(1,sizeof(*virt->chain)); virt->enableCACHE = 1; serialized = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,hexbuf,sizeof(hexbuf),hexstr); - iguana_chaininit(virt->chain,1,valsobj); + iguana_chaininit(myinfo,virt->chain,1,valsobj); + //if ( virt->FULLNODE >= 0 ) + // virt->chain->userpass[0] = 0; virt->chain->isPoS = 1; - hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); + hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgzblockhdr) : sizeof(struct iguana_msgblockhdr); if ( gecko_blocknonce_verify(virt,serialized,hdrsize,virt->chain->nBits,0,0) > 0 ) { virt->chain->genesishash2 = iguana_calcblockhash(symbol,virt->chain->hashalgo,serialized,hdrsize); @@ -212,7 +214,7 @@ struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbo if ( virt->blocks.hwmchain.height == 0 ) { memset(&txdata,0,sizeof(txdata)); - if ( (n= iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,serialized,datalen) == datalen) || n == datalen-1 ) + if ( (n= iguana_gentxarray(myinfo,virt,&virt->TXMEM,&txdata,&len,serialized,datalen) == datalen) || n == datalen-1 ) { txdata.zblock.height = 0; txdata.zblock.RO.allocsize = iguana_ROallocsize(virt); @@ -271,9 +273,6 @@ char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *add } else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}")); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - char *gecko_sendrawtransaction(struct supernet_info *myinfo,char *symbol,uint8_t *data,int32_t datalen,bits256 txid,cJSON *vals,char *signedtx) { char *retstr = 0; struct iguana_info *virt,*btcd = iguana_coinfind("BTCD"); @@ -288,48 +287,5 @@ char *gecko_sendrawtransaction(struct supernet_info *myinfo,char *symbol,uint8_t return(retstr); } -HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr) -{ - struct iguana_info *btcd; char *retstr=0,*symbol; uint8_t *data,*allocptr,space[4096]; int32_t datalen; bits256 txid; - if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) - { - if ( (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr)) != 0 ) - { - txid = bits256_doublesha256(0,data,datalen); - retstr = gecko_sendrawtransaction(myinfo,symbol,data,datalen,txid,vals,hexstr); - } else retstr = clonestr("{\"error\":\"no tx submitted\"}"); - if ( allocptr != 0 ) - free(allocptr); - if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"couldnt create geckotx\"}"); - return(retstr); - } return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko tx\"}")); -} - -HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr) -{ - return(clonestr("{\"error\":\"geckoblock is an internal reporting function\"}")); -} - -HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr) -{ - return(clonestr("{\"error\":\"geckoheaders is an internal reporting function\"}")); -} - -HASH_ARRAY_STRING(basilisk,geckoget,hash,vals,hexstr) -{ - struct iguana_info *btcd,*virt; char *symbol; - if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) - { - if ( (virt= iguana_coinfind(symbol)) != 0 ) - { - basilisk_wait(myinfo,virt); - return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,hash,0)); - } else return(clonestr("{\"error\":\"geckoget needs virtualchain\"}")); - } - return(clonestr("{\"error\":\"geckoget needs BTCD\"}")); -} - -#include "../includes/iguana_apiundefs.h" diff --git a/gecko/gecko_blocks.c b/gecko/gecko_blocks.c index 0e0b61045..a48dba97d 100755 --- a/gecko/gecko_blocks.c +++ b/gecko/gecko_blocks.c @@ -121,7 +121,7 @@ struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_ int32_t gecko_hwmset(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,uint8_t *data,int32_t datalen,int32_t depth,int32_t verifyonly) { - struct iguana_peer *addr; int32_t i,hdrsi; struct iguana_bundle *bp,*prevbp; struct iguana_block *block; + struct iguana_peer *addr; int32_t i,hdrsi; struct iguana_bundle *bp=0,*prevbp; struct iguana_block *block; if ( (block= iguana_blockhashset("gecko_hwmset",virt,txdata->zblock.height,txdata->zblock.RO.hash2,1)) != 0 ) { iguana_blockcopy(virt->chain->zcash,virt->chain->auxpow,virt,block,(struct iguana_block *)&txdata->zblock); @@ -132,7 +132,7 @@ int32_t gecko_hwmset(struct supernet_info *myinfo,struct iguana_info *virt,struc printf("no bundle for %s.%d\n",virt->symbol,block->height); return(-1); } - if ( iguana_ramchain_data(virt,addr,txdata,txarray,block->RO.txn_count,data,datalen) >= 0 ) + if ( iguana_ramchain_data(myinfo,virt,addr,txdata,txarray,block->RO.txn_count,data,datalen,bp,block) >= 0 ) { block->fpipbits = (uint32_t)addr->ipbits; block->RO.recvlen = datalen; @@ -169,7 +169,7 @@ int32_t gecko_hwmset(struct supernet_info *myinfo,struct iguana_info *virt,struc prevbp->emitfinish = (uint32_t)(time(NULL) - 3600); iguana_bundlepurgefiles(virt,prevbp); iguana_savehdrs(virt); - iguana_bundlevalidate(virt,prevbp,1); + iguana_bundlevalidate(myinfo,virt,prevbp,1); for (i=0; iRO.txn_count; i++) gecko_txidpurge(virt,txarray[i].txid); } @@ -186,7 +186,7 @@ char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,c struct iguana_txblock txdata; int32_t height,valid,adjacent,gap,n,i,j,len = -1; struct iguana_block *block,*prev; struct iguana_txid tx; char str[65],str2[65]; bits256 txid,threshold; struct iguana_msgtx *txs; memset(&txdata,0,sizeof(txdata)); iguana_memreset(&virt->TXMEM); - if ( (n= iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,data,datalen)) == datalen || n == datalen-1 ) + if ( (n= iguana_gentxarray(myinfo,virt,&virt->TXMEM,&txdata,&len,data,datalen)) == datalen || n == datalen-1 ) { if ( bits256_cmp(hash2,txdata.zblock.RO.hash2) != 0 ) { @@ -212,7 +212,7 @@ char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,c } else printf("%s is new txid ht.%d i.%d\n",bits256_str(str,txid),virt->blocks.hwmchain.height,i); } txdata.zblock.RO.allocsize = iguana_ROallocsize(virt); - if ( iguana_blockvalidate(virt,&valid,(struct iguana_block *)&txdata.zblock,1) < 0 ) + if ( iguana_blockvalidate(myinfo,virt,&valid,(struct iguana_block *)&txdata.zblock,1) < 0 ) { char str[65]; printf("got block that doesnt validate? %s\n",bits256_str(str,txdata.zblock.RO.hash2)); return(clonestr("{\"error\":\"gecko block didnt validate\"}")); @@ -312,11 +312,11 @@ char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *a printf("REJECT: duplicate block %s\n",bits256_str(str,hash2)); return(clonestr("{\"error\":\"duplicate block rejected\"}")); } - hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); + hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgzblockhdr) : sizeof(struct iguana_msgblockhdr); //nBits = gecko_nBits(virt,&prevtimestamp,(struct iguana_block *)&virt->blocks.hwmchain,GECKO_DIFFITERS); //if ( gecko_blocknonce_verify(virt,data,hdrsize,nBits,virt->blocks.hwmchain.RO.timestamp,prevtimestamp) > 0 ) { - iguana_rwblock(symbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&checkhash2,data,&msg,datalen); + iguana_rwblock(myinfo,symbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&checkhash2,data,(void *)&msg,datalen); if ( bits256_cmp(hash2,checkhash2) == 0 ) { if ( gecko_blocknonce_verify(virt,data,hdrsize,msg.H.bits,0,0) > 0 ) @@ -341,7 +341,7 @@ int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *bt if ( jobj(retjson,"error") == 0 ) { valsobj = cJSON_CreateObject(); - jaddnum(valsobj,"minresults",NUMRELAYS - 1); + jaddnum(valsobj,"numrequired",myinfo->NOTARY.NUMRELAYS - 1); jaddnum(valsobj,"timeout",3000); jaddnum(valsobj,"fanout",-1); jaddnum(valsobj,"height",height); diff --git a/gecko/gecko_delayedPoW.c b/gecko/gecko_delayedPoW.c index 280f3065f..f903842b1 100755 --- a/gecko/gecko_delayedPoW.c +++ b/gecko/gecko_delayedPoW.c @@ -120,7 +120,7 @@ int32_t gecko_hashstampsupdate(struct iguana_info *coin,struct gecko_sequence *s int32_t gecko_sequpdate(struct supernet_info *myinfo,char *symbol,uint32_t reftimestamp) { struct gecko_sequence *seq=0; int32_t max=0,firstpossible=0; struct iguana_info *coin; struct iguana_block *block; - if ( (coin= iguana_coinfind(symbol)) != 0 && (coin->FULLNODE != 0 || coin->VALIDATENODE != 0) ) + if ( (coin= iguana_coinfind(symbol)) != 0 && (coin->FULLNODE > 0 || coin->VALIDATENODE > 0) ) { if ( strcmp(symbol,"BTCD") == 0 ) { diff --git a/gecko/gecko_headers.c b/gecko/gecko_headers.c index 520a3253b..8a013f38c 100755 --- a/gecko/gecko_headers.c +++ b/gecko/gecko_headers.c @@ -28,7 +28,7 @@ int32_t basilisk_respond_geckogetheaders(struct supernet_info *myinfo,struct igu { if ( block != 0 ) { - if ( (n= iguana_headerget(virt,&serialized[len],maxsize-len,block)) > 0 ) + if ( (n= iguana_headerget(myinfo,virt,&serialized[len],maxsize-len,block)) > 0 ) len += n; } hash2 = iguana_blockhash(virt,height+i+1); @@ -53,7 +53,7 @@ void gecko_blockhashupdate(struct iguana_info *virt,bits256 hash2,int32_t height char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 firsthash2) { - bits256 hash2,prevhash2; struct iguana_block *block; int32_t height,firstheight,i,len=0,n,num; struct iguana_msgblock msgB; char str[65],str2[65]; + bits256 hash2,prevhash2; struct iguana_block *block; int32_t height=0,firstheight,i,len=0,n,num; struct iguana_msgzblock zmsgB; char str[65],str2[65]; num = (int32_t)(datalen / 84); printf("headers.%s arrived.%d from %s\n",virt->symbol,num,bits256_str(str,firsthash2)); if ( (block= iguana_blockfind("geckohdrs",virt,firsthash2)) != 0 && (firstheight= block->height) >= 0 ) @@ -62,14 +62,14 @@ char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt prevhash2 = firsthash2; for (i=0; isymbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&hash2,&data[len],&msgB,datalen-len)) > 0 ) + if ( (n= iguana_rwblock(myinfo,virt->symbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&hash2,&data[len],&zmsgB,datalen-len)) > 0 ) { - if ( bits256_cmp(msgB.H.prev_block,prevhash2) == 0 ) + if ( bits256_cmp(zmsgB.zH.prev_block,prevhash2) == 0 ) { height = (firstheight + i + 1); gecko_blockhashupdate(virt,hash2,height); - printf("ht.%d %s %08x t.%u\n",height,bits256_str(str,hash2),msgB.H.bits,msgB.H.timestamp); - } else printf("ht.%d non prevhash i.%d %s %s\n",height,i,bits256_str(str,prevhash2),bits256_str(str2,msgB.H.prev_block)); + printf("ht.%d %s\n",height,bits256_str(str,hash2)); + } else printf("ht.%d non prevhash i.%d %s %s\n",height,i,bits256_str(str,prevhash2),bits256_str(str2,zmsgB.zH.prev_block)); len += n; prevhash2 = hash2; } diff --git a/gecko/gecko_mempool.c b/gecko/gecko_mempool.c index ce953211d..402e0d83d 100755 --- a/gecko/gecko_mempool.c +++ b/gecko/gecko_mempool.c @@ -21,7 +21,7 @@ struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct igua int32_t j,firstz,numother; bits256 *othertxids; struct gecko_mempool *otherpool = 0; othertxids = 0; numother = firstz = 0; - for (j=0; jNOTARY.NUMRELAYS; j++) { if ( (otherpool= virt->mempools[j]) != 0 ) { @@ -44,22 +44,22 @@ struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct igua void gecko_mempool_sync(struct supernet_info *myinfo,struct iguana_info *virt,bits256 *reftxids,int32_t numtx) { int32_t i,j,k,n,num,numother; struct iguana_peer *addr; bits256 txid,*txids; struct gecko_mempool *pool,*otherpool; struct iguana_info *coin; - if ( (pool= virt->mempool) == 0 || NUMRELAYS <= 0 ) + if ( (pool= virt->mempool) == 0 || myinfo->NOTARY.NUMRELAYS <= 0 ) return; - n = sqrt(NUMRELAYS) + 2; - if ( n > NUMRELAYS ) - NUMRELAYS = n; + n = sqrt(myinfo->NOTARY.NUMRELAYS) + 2; + if ( n > myinfo->NOTARY.NUMRELAYS ) + myinfo->NOTARY.NUMRELAYS = n; i = (myinfo->myaddr.myipbits % n); txids = calloc(pool->numtx,sizeof(bits256)); if ( virt->peers == 0 ) coin = iguana_coinfind("BTCD"); else coin = virt; - for (; iNOTARY.NUMRELAYS; i+=n) { printf("mempool_sync.%d\n",i); - if ( (addr= iguana_peerfindipbits(coin,RELAYS[i].ipbits,1)) != 0 ) + if ( (addr= iguana_peerfindipbits(coin,myinfo->NOTARY.RELAYS[i].ipbits,1)) != 0 ) { - if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,RELAYS[i].ipbits)) != 0 ) + if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,myinfo->NOTARY.RELAYS[i].ipbits)) != 0 ) { for (j=num=0; jnumtx; j++) { @@ -226,10 +226,10 @@ int32_t basilisk_respond_geckogettx(struct supernet_info *myinfo,struct iguana_i char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *serialized,int32_t datalen,bits256 txid) { - struct gecko_mempool *pool; int64_t txfee,vinstotal,voutstotal; uint64_t value; int32_t i,numvins,numvouts,txlen,spentheight,minconf,maxconf,unspentind; struct iguana_msgtx msg; char *rawtx; struct gecko_memtx *memtx; struct iguana_info *btcd; struct iguana_outpoint outpt; + struct gecko_mempool *pool; int64_t txfee,vinstotal,voutstotal; uint64_t value; int32_t i,numvins,numvouts,txlen,spentheight,minconf,maxconf; struct iguana_msgtx msg; char *rawtx; struct gecko_memtx *memtx; struct iguana_info *btcd; struct iguana_outpoint outpt; memset(&msg,0,sizeof(msg)); iguana_memreset(&virt->TXMEM); - txlen = iguana_rwtx(virt->chain->zcash,0,&virt->TXMEM,serialized,&msg,datalen,&txid,virt->chain->isPoS,strcmp("VPN",virt->symbol) == 0); + txlen = iguana_rwtx(myinfo,virt->chain->zcash,0,virt,&virt->TXMEM,serialized,&msg,datalen,&txid,virt->chain->isPoS,strcmp("VPN",virt->symbol) == 0); vinstotal = voutstotal = 0; maxconf = virt->longestchain; minconf = virt->chain->minconfirms; @@ -237,11 +237,9 @@ char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char { for (i=0; ibundlescount-1,1)) != 0 ) + if ( iguana_RTunspentindfind(myinfo,virt,&outpt,0,0,0,&value,&spentheight,msg.vins[i].prev_hash,msg.vins[i].prev_vout,virt->bundlescount-1,1) == 0 ) { - memset(&outpt,0,sizeof(outpt)); - outpt.hdrsi = spentheight / virt->chain->bundlesize; - outpt.unspentind = unspentind; + printf("gecko txarrived\n"); if ( iguana_unspentavail(myinfo,virt,outpt,minconf,maxconf) != value ) { printf("vin.%d already spent\n",i); diff --git a/gecko/gecko_miner.c b/gecko/gecko_miner.c index f77193f93..4e2628255 100755 --- a/gecko/gecko_miner.c +++ b/gecko/gecko_miner.c @@ -62,7 +62,7 @@ int32_t gecko_blocknonce_verify(struct iguana_info *virt,uint8_t *serialized,int uint32_t gecko_nBits(struct iguana_info *virt,uint32_t *prevtimestampp,struct iguana_block *block,int32_t n) { - uint32_t nBits = GECKO_DEFAULTDIFF,starttime,endtime,est; struct iguana_block *prev=0; int32_t i,diff; bits256 targetval; + uint32_t nBits = GECKO_DEFAULTDIFF,starttime=0,endtime=0,est; struct iguana_block *prev=0; int32_t i,diff; bits256 targetval; *prevtimestampp = 0; if ( virt->chain->estblocktime == 0 ) return(GECKO_EASIESTDIFF); @@ -215,20 +215,20 @@ char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt threshold = bits256_from_compact(newblock->RO.bits); if ( (newblock->RO.nonce= *noncep) == 0 ) { - struct iguana_msgblock msg; - memset(&msg,0,sizeof(msg)); - msg.H.version = newblock->RO.version; - msg.H.prev_block = newblock->RO.prev_block; - msg.H.merkle_root = newblock->RO.merkle_root; - msg.H.timestamp = newblock->RO.timestamp; - msg.H.bits = newblock->RO.bits; + struct iguana_msgzblock zmsg; struct iguana_msgblock *msg = (void *)&zmsg; + memset(&zmsg,0,sizeof(zmsg)); + msg->H.version = newblock->RO.version; + msg->H.prev_block = newblock->RO.prev_block; + msg->H.merkle_root = newblock->RO.merkle_root; + msg->H.timestamp = newblock->RO.timestamp; + msg->H.bits = newblock->RO.bits; for (i=0; iH.nonce = *noncep; //n = iguana_serialize_block(virt->chain,&hash2,serialized,newblock); //char str[65]; printf("nonce.%08x %s\n",newblock->RO.nonce,bits256_str(str,newblock->RO.hash2)); - len = iguana_rwblockhdr(1,virt->chain->zcash,serialized,&msg); + len = iguana_rwblockhdr(1,virt->chain->zcash,serialized,&zmsg); hash2 = iguana_calcblockhash(virt->symbol,virt->chain->hashalgo,serialized,len); if ( bits256_cmp(threshold,hash2) > 0 ) { @@ -247,7 +247,7 @@ char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt } } newblock->RO.nonce = *noncep; - n = iguana_serialize_block(virt->chain,&newblock->RO.hash2,serialized,newblock); + n = iguana_serialize_block(myinfo,virt->chain,&newblock->RO.hash2,serialized,newblock); while ( 1 && time(NULL) <= newblock->RO.timestamp + GECKO_MAXFUTUREBLOCK ) { //printf("wait for block to be close enough to now: lag %ld\n",time(NULL) - newblock->RO.timestamp); @@ -302,7 +302,7 @@ cJSON *gecko_paymentsobj(struct supernet_info *myinfo,cJSON *txjson,cJSON *valso if ( (txversion= juint(valsobj,"txversion")) == 0 ) txversion = (locktime == 0) ? IGUANA_NORMAL_TXVERSION : IGUANA_LOCKTIME_TXVERSION; if ( txjson == 0 ) - txjson = bitcoin_txcreate(1,locktime,txversion); + txjson = bitcoin_txcreate("gecko",1,locktime,txversion,juint(valsobj,"timestamp")); if ( (array= jarray(&n,valsobj,"payments")) != 0 && n > 0 ) { for (i=0; ivirtualchain == 0 || RELAYID < 0 || NUMRELAYS < 1 ) + if ( virt->virtualchain == 0 || myinfo->NOTARY.RELAYID < 0 || myinfo->NOTARY.NUMRELAYS < 1 ) { //printf("skip non-virtual chain.%s\n",virt->symbol); return; } if ( virt->blocks.hwmchain.height < virt->longestchain-1 ) return; - if ( (virt->blocks.hwmchain.height % NUMRELAYS) != RELAYID ) + if ( myinfo->IAMNOTARY != 0 && (virt->blocks.hwmchain.height % myinfo->NOTARY.NUMRELAYS) != myinfo->NOTARY.RELAYID ) { //if ( NUMRELAYS < 3 ) // return; gap = (int32_t)(time(NULL) - virt->blocks.hwmchain.RO.timestamp) / 60;//virt->chain->estblocktime; for (i=0; iblocks.hwmchain.height+i) % NUMRELAYS) == RELAYID ) + if ( myinfo->IAMNOTARY != 0 && ((virt->blocks.hwmchain.height+i) % myinfo->NOTARY.NUMRELAYS) == myinfo->NOTARY.RELAYID ) break; } if ( i == gap ) return; - printf("backup block generator RELAYID.%d gap.%d ht.%d i.%d num.%d\n",RELAYID,gap,virt->blocks.hwmchain.height,i,NUMRELAYS); + printf("backup block generator RELAYID.%d gap.%d ht.%d i.%d num.%d\n",myinfo->NOTARY.RELAYID,gap,virt->blocks.hwmchain.height,i,myinfo->NOTARY.NUMRELAYS); } #endif /*if ( virt->newblockstr != 0 ) diff --git a/iguana.sln b/iguana.sln new file mode 100644 index 000000000..621e199f3 --- /dev/null +++ b/iguana.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iguana", "iguana.vcxproj", "{80F58B93-D1FC-4FC4-A880-1F40A1FC851B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Debug|x64.ActiveCfg = Debug|x64 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Debug|x64.Build.0 = Debug|x64 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Debug|x86.ActiveCfg = Debug|Win32 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Debug|x86.Build.0 = Debug|Win32 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Release|x64.ActiveCfg = Release|x64 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Release|x64.Build.0 = Release|x64 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Release|x86.ActiveCfg = Release|Win32 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/iguana.vcxproj b/iguana.vcxproj new file mode 100644 index 000000000..fbdc95c13 --- /dev/null +++ b/iguana.vcxproj @@ -0,0 +1,305 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B} + Win32Proj + ConsoleApplication3 + 8.1 + iguana + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + Static + + + + + + + + + + + + + + + + + + + + + true + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) + $(ProjectDir)\OSlibs\win;$(LibraryPath) + + + true + $(SolutionDir)/includes;$(SolutionDir)/includes/curl;$(IncludePath) + + + false + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) + $(ProjectDir)\OSlibs\win;$(LibraryPath) + + + false + false + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) + + + + + + Level2 + Disabled + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_DEBUG;_CONSOLE;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + 1Byte + .\iguana;%(AdditionalIncludeDirectories) + + + Console + true + Ws2_32.lib;pthreadVC2.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) + .\iguana;.\OSlibs\win;%(AdditionalLibraryDirectories) + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + 1Byte + + + Console + true + .\OSlibs\win\x64;%(AdditionalLibraryDirectories) + pthread_lib.lib;Ws2_32.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + 1Byte + + + Console + true + true + true + Ws2_32.lib;pthreadVC2.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) + .\OSlibs\win\release;%(AdditionalLibraryDirectories) + + + + + Level3 + + + MaxSpeed + true + true + WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + 1Byte + MultiThreaded + + + Console + true + true + true + Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\x64\pthread_lib.lib;libcurl.lib;nanomsg.lib;%(AdditionalDependencies) + .\OSlibs\win\x64\release;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/iguana.vcxproj.filters b/iguana.vcxproj.filters new file mode 100644 index 000000000..3aa3d0fc6 --- /dev/null +++ b/iguana.vcxproj.filters @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/iguana/Kashi/json_extracta b/iguana/Kashi/json_extracta deleted file mode 100755 index a76453978..000000000 Binary files a/iguana/Kashi/json_extracta and /dev/null differ diff --git a/iguana/peggy.c b/iguana/PAX/peggy.c similarity index 98% rename from iguana/peggy.c rename to iguana/PAX/peggy.c index c56c0a98d..d2a6dbcca 100755 --- a/iguana/peggy.c +++ b/iguana/PAX/peggy.c @@ -280,7 +280,7 @@ struct peggy *peggy_createpair(struct peggy_info *PEGS,int64_t quorum,int64_t de return(PEG); } -struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t BTCD_price0) +struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t KMD_price0) { //struct peggy_limits limits = { { PERCENTAGE(10), PERCENTAGE(25), PERCENTAGE(33), PERCENTAGE(50) }, SATOSHIDEN * 10000, SATOSHIDEN * 1000, { 0, 30, 90, 180 }, 4 }; struct peggy_lock default_lockparms = { 7, 365, 7, 0, 180, 0, -1 }; @@ -297,8 +297,8 @@ struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincu PEGS->interesttenths = interesttenths, PEGS->posboost = posboost, PEGS->negpenalty = negpenalty, PEGS->feediv = feediv, PEGS->feemult = feemult; mindenom.Pval = PRICE_RESOLUTION; PEGS->genesistime = firsttimestamp; - price.Pval = PEGS->BTCD_price0 = BTCD_price0; - printf("set genesistime.%u BTCD0.%u\n",firsttimestamp,BTCD_price0); + price.Pval = PEGS->KMD_price0 = KMD_price0; + printf("set genesistime.%u BTCD0.%u\n",firsttimestamp,KMD_price0); peggy_createpair(PEGS,0,0,"BTCD","BTCD",0,SATOSHIDEN*1000000,SATOSHIDEN*100000,0,SATOSHIDEN,PEGGY_RATE_777,firsttimestamp,&price,1,spread,0,mindenom,0,1,peggy_mils(0)); //PEGS->accts = accts777_init(path,0); return(PEGS); @@ -414,7 +414,7 @@ struct peggy_info *peggy_genesis(int32_t lookbacks[OPRETURNS_CONTEXTS],struct pe if ( PEGS == 0 ) { spread.Pval = PERCENTAGE(1); - PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,Ptx.timestamp,Ptx.details.price.feed[0]); + PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"KMD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,Ptx.timestamp,Ptx.details.price.feed[0]); //PEGS->accts = accts777_init(path,0); PEGS->genesis = opreturnstr, opreturnstr = 0; } @@ -688,7 +688,7 @@ int32_t peggy_init_contexts(struct txinds777_info *opreturns,uint32_t RTblocknum PEGS = peggy_init(path,PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,100,10,spread,PEGGY_RATE_777,40,10,2,5,2,0,0); globals[0] = PEGS; sprintf(buf,"%s_PERM",path); - globals[1] = PEGS2 = peggy_init(buf,PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,PEGS->genesistime,PEGS->BTCD_price0); + globals[1] = PEGS2 = peggy_init(buf,PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,PEGS->genesistime,PEGS->KMD_price0); startmilli = OS_milliseconds(); peggy_clone(buf,PEGS2,PEGS); printf("cloned %d in %.3f millis per opreturn\n",PEGS->numopreturns,(OS_milliseconds() - startmilli)/PEGS->numopreturns); sleep(3);*/ @@ -701,7 +701,7 @@ void peggy_indsinit() { peggy_geninds(); printf("need to update Peggy_inds with above\n"); - exit(-1); + iguana_exit(0,0); } peggy_dailyrates(); } diff --git a/iguana/peggy.h b/iguana/PAX/peggy.h similarity index 98% rename from iguana/peggy.h rename to iguana/PAX/peggy.h index 8487269b4..213c6e8ca 100755 --- a/iguana/peggy.h +++ b/iguana/PAX/peggy.h @@ -18,7 +18,7 @@ #define PEGGY_GENESIS "6aef504158ec0014fee05dc20a0006048ed63e523f6d1062feb23622da928cf23ddcc3b53f23566bc6cab5ebd77cfbf8f0bccb34bff73c55d742dd232994bfbffe1cbab7119ab3d653a256b02d5b6f56c05b8817799f0d242f48c26d35c992ebfff14acdefbe253345d394e84d975334cd55f7d6cbad5a7bd9425b1d5db44944d40be5304b7b62ba0dbc20d3323d2b35f05f654bc95a5a2fdb5a30e46c6fd33b5ea078255f7cad9fd0dbd2fa5031ada4474cbba7b2ee64ef35df06bf3fd3eef6cd3f48339f3c0e080158a92862bbf20bc6702018effbaee525502eb463c74f7ca0dff4ae7cb55ee55ef7cb1c915e655649" -#include "iguana777.h" +#include "../iguana777.h" // CfB "the rule is simple = others can know the redemption day only AFTER the price for that day is set in stone." #define PEGGY_NUMCOEFFS 539 #define ACCTS777_MAXRAMKVS 8 @@ -222,7 +222,7 @@ struct PAX_data uint32_t itimestamps[128]; double ibids[128],iasks[128]; char edate[128]; double ecbmatrix[32][32],dailyprices[MAX_CURRENCIES * MAX_CURRENCIES],metals[4]; int32_t ecbdatenum,ecbyear,ecbmonth,ecbday; double RTmatrix[32][32],RTprices[128],RTmetals[4]; - double btcusd,btcdbtc,cryptos[8]; + double btcusd,kmdbtc,cryptos[8]; }; struct PAX_spline { char name[64]; int32_t splineid,lasti,basenum,num,firstx,dispincr,spline32[MAX_SPLINES][4]; uint32_t utc32[MAX_SPLINES]; int64_t spline64[MAX_SPLINES][4]; double dSplines[MAX_SPLINES][4],pricevals[MAX_SPLINES+MAX_LOOKAHEAD],lastutc,lastval,aveslopeabs; }; @@ -235,8 +235,8 @@ struct peggy_info int32_t default_dailyrate,interesttenths,posboost,negpenalty,feediv,feemult; int32_t numpegs,numpairedpegs,numpricedpegs,numopreturns,numvoters; struct accts777_info *accts; - struct PAX_data data,tmp; double cryptovols[2][9][2],btcusd,btcdbtc,cnyusd; - char path[512],*genesis; uint32_t genesistime,BTCD_price0,lastupdate; + struct PAX_data data,tmp; double cryptovols[2][9][2],btcusd,kmdbtc,cnyusd; + char path[512],*genesis; uint32_t genesistime,KMD_price0,lastupdate; struct PAX_spline splines[128]; struct peggy_vote votes[PEGGY_MAXPRICEDPEGS][PEGGY_MAXVOTERS]; struct peggy *contracts[PEGGY_MAXPEGS]; @@ -308,7 +308,7 @@ extern int32_t MINDENOMS[],Peggy_inds[],dailyrates[]; struct price_resolution peggy_scaleprice(struct price_resolution price,int64_t peggymils); char *peggy_tx(char *jsonstr); void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PAX_data *dp,int32_t selector,int32_t peggyflag); -int32_t PAX_idle(struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap); +int32_t PAX_idle(struct supernet_info *myinfo);//struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap); int32_t PAX_genspline(struct PAX_spline *spline,int32_t splineid,char *name,uint32_t *utc32,double *splinevals,int32_t maxsplines,double *refvals); int32_t PAX_contractnum(char *base,char *rel); int32_t PAX_basenum(char *base); @@ -368,7 +368,7 @@ int32_t peggy_init_contexts(struct txinds777_info *opreturns,uint32_t blocknum,u uint32_t peggy_clone(char *path,void *dest,void *src); void *peggy_replay(char *path,struct txinds777_info *opreturns,void *_PEGS,uint32_t blocknum,char *opreturnstr,uint8_t *data,int32_t datalen); uint32_t peggy_currentblock(void *globals); -struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t BTCD_price0); +struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t KMD_price0); struct peggy_unit *peggy_match(struct accts777_info *accts,int32_t peg,uint64_t nxt64bits,bits256 lockhash,uint16_t lockdays); int32_t peggy_addunit(struct accts777_info *accts,struct peggy_unit *U,bits256 lockhash); diff --git a/iguana/peggy_accts.c b/iguana/PAX/peggy_accts.c similarity index 99% rename from iguana/peggy_accts.c rename to iguana/PAX/peggy_accts.c index 7dbe1c2f6..574baa4b7 100755 --- a/iguana/peggy_accts.c +++ b/iguana/PAX/peggy_accts.c @@ -99,7 +99,7 @@ struct accts777_info *accts777_init(char *dirname,struct txinds777_info *txinds) if ( accts->numkvs > ACCTS777_MAXRAMKVS ) { printf("too many ramkvs for accts %d vs %d\n",accts->numkvs,ACCTS777_MAXRAMKVS); - exit(-1); + iguana_exit(0,0); } accts->addrkvs[PEGGY_ADDRFUNDING] = accts->addrkvs[PEGGY_ADDRBTCD] = accts->coinaddrs; accts->addrkvs[PEGGY_ADDR777] = accts->SaMaddrs; diff --git a/iguana/peggy_consensus.c b/iguana/PAX/peggy_consensus.c similarity index 100% rename from iguana/peggy_consensus.c rename to iguana/PAX/peggy_consensus.c diff --git a/iguana/peggy_price.c b/iguana/PAX/peggy_price.c similarity index 95% rename from iguana/peggy_price.c rename to iguana/PAX/peggy_price.c index 3f0bc77d1..96e9333d5 100755 --- a/iguana/peggy_price.c +++ b/iguana/PAX/peggy_price.c @@ -201,17 +201,17 @@ uint32_t peggy_mils(int32_t i) minmils = 10000; else if ( strncmp(peggy_bases[i],"NXT",3) == 0 || strncmp(peggy_bases[i],"BTS",3) == 0 ) minmils = 1000000; - else if ( strncmp(peggy_bases[i],"STEEM",5) == 0 ) + else if ( strncmp(peggy_bases[i],"KMD",5) == 0 ) minmils = 1000; else minmils = 10000; } return(minmils); } -int32_t peggy_prices(struct price_resolution prices[64],double btcusd,double btcdbtc,char *contracts[],int32_t num,double *cprices,double *basevals) +int32_t peggy_prices(struct price_resolution prices[64],double btcusd,double kmdbtc,char *contracts[],int32_t num,double *cprices,double *basevals) { - double btcdusd,price_in_btcd,dprice,usdcny,usdrub,btccny,btcrub,xauusd,usdprice=0.,usdval,btcprice=0.; int32_t contractnum,base,nonz = 0; - if ( btcusd > SMALLVAL && btcdbtc > SMALLVAL && (usdval= basevals[0]) > SMALLVAL ) + double kmdusd,price_in_kmd,dprice,usdcny,usdrub,btccny,btcrub,xauusd,usdprice=0.,usdval,btcprice=0.; int32_t contractnum,base,nonz = 0; + if ( btcusd > SMALLVAL && kmdbtc > SMALLVAL && (usdval= basevals[0]) > SMALLVAL ) { xauusd = usdcny = usdrub = btccny = btcrub = 0.; for (contractnum=0; contractnumdata.ecbmatrix,sizeof(PEGS->data.ecbmatrix)); PAX_calcmatrix(Hmatrix); /*for (i=0; i<32; i++) @@ -638,11 +638,11 @@ int32_t PAX_getmatrix(double *basevals,struct peggy_info *PEGS,double Hmatrix[32 printf("%s\n",CURRENCIES[i]); }*/ btcusd = PEGS->data.btcusd; - btcdbtc = PEGS->data.btcdbtc; + kmdbtc = PEGS->data.kmdbtc; if ( btcusd > SMALLVAL ) dxblend(&PEGS->btcusd,btcusd,.9); - if ( btcdbtc > SMALLVAL ) - dxblend(&PEGS->btcdbtc,btcdbtc,.9); + if ( kmdbtc > SMALLVAL ) + dxblend(&PEGS->kmdbtc,kmdbtc,.9); // char *cryptostrs[8] = { "btc", "nxt", "unity", "eth", "ltc", "xmr", "bts", "xcp" }; // "BTCUSD", "NXTBTC", "SuperNET", "ETHBTC", "LTCBTC", "XMRBTC", "BTSBTC", "XCPBTC", // BTC priced for (i=0; i 2 ) - printf("(%f %f) i.%d num.%d %s %f\n",PEGS->btcusd,PEGS->btcdbtc,i,num,contracts[i],RTprices[i]); + printf("(%f %f) i.%d num.%d %s %f\n",PEGS->btcusd,PEGS->kmdbtc,i,num,contracts[i],RTprices[i]); //printf("RT.(%s %f) ",contracts[i],RTprices[i]); } return(PEGS->data.ecbdatenum); @@ -719,7 +719,7 @@ char *peggy_emitprices(int32_t *nonzp,struct peggy_info *PEGS,uint32_t blocktime printf("peggy_emitprices\n"); if ( PAX_getmatrix(basevals,PEGS,matrix,cprices+1,peggy_bases+1,sizeof(peggy_bases)/sizeof(*peggy_bases)-1,blocktimestamp) > 0 ) { - cprices[0] = PEGS->btcdbtc; + cprices[0] = PEGS->kmdbtc; for (i=0; i<32; i++) PEGS->data.RTmatrix[i][i] = basevals[i]; /*for (i=0; i<32; i++) @@ -732,7 +732,7 @@ char *peggy_emitprices(int32_t *nonzp,struct peggy_info *PEGS,uint32_t blocktime memset(prices,0,sizeof(prices)); memset(matrix,0,sizeof(matrix)); memset(RTmatrix,0,sizeof(RTmatrix)); - peggy_prices(prices,PEGS->btcusd,PEGS->btcdbtc,peggy_bases,sizeof(peggy_bases)/sizeof(*peggy_bases),cprices,basevals); + peggy_prices(prices,PEGS->btcusd,PEGS->kmdbtc,peggy_bases,sizeof(peggy_bases)/sizeof(*peggy_bases),cprices,basevals); for (i=0; isplines[MAX_CURRENCIES+0],timestamp,0),PAX_splineval(&PEGS->splines[MAX_CURRENCIES+1],timestamp,0)); - btcd = .01 * PAX_splineval(&PEGS->splines[MAX_CURRENCIES+2],timestamp,0); - if ( btc != 0. && btcd != 0. ) + kmd = .01 * PAX_splineval(&PEGS->splines[MAX_CURRENCIES+2],timestamp,0); + if ( btc != 0. && kmd != 0. ) { - btcdusd = (btc * btcd); + kmdusd = (btc * kmd); usdval = PAX_splineval(&PEGS->splines[USD],timestamp,0); if ( basenum == USD ) - return(1. / btcdusd); - else return(PAX_splineval(&PEGS->splines[basenum],timestamp,0) / (btcdusd * usdval)); + return(1. / kmdusd); + else return(PAX_splineval(&PEGS->splines[basenum],timestamp,0) / (kmdusd * usdval)); } return(0.); } @@ -848,7 +848,7 @@ struct peggy_info *PAX_init() tradebot_monitorall(0,0,0,0,"truefx",commission); tradebot_monitorall(0,0,0,0,"instaforex",commission); spread.Pval = PERCENTAGE(1); - PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,100,10,spread,PEGGY_RATE_777,40,10,2,5,2,0,0); + PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"KMD",SATOSHIDEN/100,100,10,spread,PEGGY_RATE_777,40,10,2,5,2,0,0); exchange_create("PAX",0); //peggy_priceinits(PEGS,(uint32_t)time(NULL),allprices); return(PEGS); diff --git a/iguana/peggy_ramkv.c b/iguana/PAX/peggy_ramkv.c similarity index 100% rename from iguana/peggy_ramkv.c rename to iguana/PAX/peggy_ramkv.c diff --git a/iguana/peggy_serdes.c b/iguana/PAX/peggy_serdes.c similarity index 100% rename from iguana/peggy_serdes.c rename to iguana/PAX/peggy_serdes.c diff --git a/iguana/peggy_tx.c b/iguana/PAX/peggy_tx.c similarity index 100% rename from iguana/peggy_tx.c rename to iguana/PAX/peggy_tx.c diff --git a/iguana/peggy_txind.c b/iguana/PAX/peggy_txind.c similarity index 99% rename from iguana/peggy_txind.c rename to iguana/PAX/peggy_txind.c index b05d307a8..cf159bfb7 100755 --- a/iguana/peggy_txind.c +++ b/iguana/PAX/peggy_txind.c @@ -186,7 +186,7 @@ void opreturns_emitloop(char *protocols[],int32_t numprotocols,uint8_t opreturnd if ( (opreturnlen= opreturns_emit(protocols[i],opreturndata,payments,max,currentblocknum,blocknum,blocktimestamp)) < 0 ) { printf("opreturns_emitloop: error on protocol.(%s)\n",protocols[i]); - exit(-1); + iguana_exit(0,0); } if ( opreturnlen > 0 ) { diff --git a/iguana/peggy_update.c b/iguana/PAX/peggy_update.c similarity index 90% rename from iguana/peggy_update.c rename to iguana/PAX/peggy_update.c index d23b190f6..1ebee32da 100755 --- a/iguana/peggy_update.c +++ b/iguana/PAX/peggy_update.c @@ -47,7 +47,7 @@ static char *Yahoo_metals[] = { YAHOO_METALS }; char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies "XAU", "XAG", "XPT", "XPD", // metals, gold must be first - "BTCD", "BTC", "NXT", "ETC", "ETH", "STEEM", "BTS", "MAID", "XCP", "XMR" // cryptos + "BTCD", "BTC", "NXT", "ETC", "ETH", "KMD", "BTS", "MAID", "XCP", "XMR" // cryptos }; char CONTRACTS[][16] = { "NZDUSD", "NZDCHF", "NZDCAD", "NZDJPY", "GBPNZD", "EURNZD", "AUDNZD", "CADJPY", "CADCHF", "USDCAD", "EURCAD", "GBPCAD", "AUDCAD", "USDCHF", "CHFJPY", "EURCHF", "GBPCHF", "AUDCHF", "EURUSD", "EURAUD", "EURJPY", "EURGBP", "GBPUSD", "GBPJPY", "GBPAUD", "USDJPY", "AUDJPY", "AUDUSD", "USDCNY", "USDHKD", "USDMXN", "USDZAR", "USDTRY", "EURTRY", "TRYJPY", "USDSGD", "EURNOK", "USDNOK","USDSEK","USDDKK","EURSEK","EURDKK","NOKJPY","SEKJPY","USDPLN","EURPLN","USDILS", // no more currencies @@ -197,10 +197,10 @@ void PAX_btcprices(struct peggy_info *PEGS,int32_t enddatenum,int32_t numdates) { int32_t i,n,year,month,day,seconds,datenum; char url[1024],date[64],*dstr,*str; uint32_t timestamp,utc32[MAX_SPLINES]; struct tai t; - cJSON *coindesk,*quandl,*btcdhist,*bpi,*array,*item; - double btcddaily[MAX_SPLINES],cdaily[MAX_SPLINES],qdaily[MAX_SPLINES],ask,high,low,bid,close,vol,quotevol,open,price = 0.; + cJSON *coindesk,*quandl,*kmdhist,*bpi,*array,*item; + double kmddaily[MAX_SPLINES],cdaily[MAX_SPLINES],qdaily[MAX_SPLINES],ask,high,low,bid,close,vol,quotevol,open,price = 0.; coindesk = url_json("http://api.coindesk.com/v1/bpi/historical/close.json"); - sprintf(url,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_BTCD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); + sprintf(url,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_KMD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); if ( (bpi= jobj(coindesk,"bpi")) != 0 ) { datenum = enddatenum; @@ -248,11 +248,13 @@ void PAX_btcprices(struct peggy_info *PEGS,int32_t enddatenum,int32_t numdates) } PAX_genspline(&PEGS->splines[MAX_CURRENCIES+1],MAX_CURRENCIES+1,"quandl",utc32,qdaily,n 2 ) printf("[%u %d %f]",timestamp,OS_conv_unixtime(&t,&seconds,timestamp),price); - utc32[i] = timestamp - 12*3600, btcddaily[i] = price * 100.; + utc32[i] = timestamp - 12*3600, kmddaily[i] = price * 100.; } if ( Debuglevel > 2 ) printf("poloniex.%d\n",n); - PAX_genspline(&PEGS->splines[MAX_CURRENCIES+2],MAX_CURRENCIES+2,"btcdhist",utc32,btcddaily,nsplines[MAX_CURRENCIES+2],MAX_CURRENCIES+2,"kmdhist",utc32,kmddaily,n 0 && (array= jarray(&n,quandl,"data")) != 0 ) { @@ -430,20 +432,20 @@ void PAX_update(struct peggy_info *PEGS,double *btcusdp,double *btcdbtcp) { double avebid,aveask,bidvol,askvol; struct exchange_quote sortbuf[512]; struct supernet_info *myinfo = SuperNET_MYINFO(0); cJSON *argjson = cJSON_Parse("{}"); - aveask = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&askvol,"BTCD","BTC",1,argjson); - avebid = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&bidvol,"BTCD","BTC",-1,argjson); + aveask = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&askvol,"KMD","BTC",1,argjson); + avebid = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&bidvol,"KMD","BTC",-1,argjson); if ( avebid > SMALLVAL && aveask > SMALLVAL ) { price = (avebid*bidvol + aveask*askvol) / (bidvol + askvol); - *btcdbtcp = price; - printf("set BTCD price %f\n",price); - PEGS->btcdbtc = price; + *kmdbtcp = price; + printf("set KMD price %f\n",price); + PEGS->kmdbtc = price; } else { - btcdhist = url_json(url); + kmdhist = url_json(url); //{"date":1406160000,"high":0.01,"low":0.00125,"open":0.01,"close":0.001375,"volume":1.50179994,"quoteVolume":903.58818412,"weightedAverage":0.00166204}, - if ( btcdhist != 0 && (array= jarray(&n,btcdhist,0)) != 0 ) + if ( kmdhist != 0 && (array= jarray(&n,kmdhist,0)) != 0 ) { //printf("GOT.(%s)\n",cJSON_Print(array)); for (i=0; i<1; i++) @@ -453,14 +455,14 @@ void PAX_update(struct peggy_info *PEGS,double *btcusdp,double *btcdbtcp) close = jdouble(item,"close"), vol = jdouble(item,"volume"), quotevol = jdouble(item,"quoteVolume"), price = jdouble(item,"weightedAverage"); //printf("[%u %f %f %f %f %f %f %f]",timestamp,high,low,open,close,vol,quotevol,price); //printf("[%u %d %f]",timestamp,OS_conv_unixtime(&seconds,timestamp),price); - btcddaily = price; - if ( btcddaily != 0 ) - PEGS->btcdbtc = *btcdbtcp = btcddaily; + kmddaily = price; + if ( kmddaily != 0 ) + PEGS->kmdbtc = *kmdbtcp = kmddaily; } //printf("poloniex.%d\n",n); } - if ( btcdhist != 0 ) - free_json(btcdhist); + if ( kmdhist != 0 ) + free_json(kmdhist); } } if ( bitcoinave != 0 ) @@ -524,19 +526,19 @@ void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PA { char *cryptonatorA = "https://www.cryptonator.com/api/full/%s-%s"; //unity-btc char *cryptocoinchartsB = "http://api.cryptocoincharts.info/tradingPair/%s_%s"; //bts_btc - char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "steem", "xmr", "bts", "xcp", "etc" }; - int32_t iter,i,j; double btcusd,btcdbtc,cnyusd,prices[9][2],volumes[9][2]; + char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "kmd", "xmr", "bts", "xcp", "etc" }; + int32_t iter,i,j; double btcusd,kmdbtc,cnyusd,prices[9][2],volumes[9][2]; char base[16],rel[16],url[512],*str; cJSON *jsonA,*jsonB; if ( peggyflag != 0 ) { cnyusd = PEGS->cnyusd; btcusd = PEGS->btcusd; - btcdbtc = PEGS->btcdbtc; - //printf("update with btcusd %f btcd %f cnyusd %f cnybtc %f\n",btcusd,btcdbtc,cnyusd,cnyusd/btcusd); - if ( btcusd < SMALLVAL || btcdbtc < SMALLVAL ) + kmdbtc = PEGS->kmdbtc; + //printf("update with btcusd %f kmd %f cnyusd %f cnybtc %f\n",btcusd,kmdbtc,cnyusd,cnyusd/btcusd); + if ( btcusd < SMALLVAL || kmdbtc < SMALLVAL ) { - PAX_update(PEGS,&btcusd,&btcdbtc); - printf("PAX_update with btcusd %f btcd %f\n",btcusd,btcdbtc); + PAX_update(PEGS,&btcusd,&kmdbtc); + printf("PAX_update with btcusd %f kmd %f\n",btcusd,kmdbtc); } memset(prices,0,sizeof(prices)); memset(volumes,0,sizeof(volumes)); @@ -553,7 +555,7 @@ void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PA for (iter=0; iter<1; iter++) { if ( i == 0 && iter == 0 ) - strcpy(base,"btcd"), strcpy(rel,"btc"); + strcpy(base,"kmd"), strcpy(rel,"btc"); else strcpy(base,str), strcpy(rel,iter==0?"btc":"cny"); //if ( selector == 0 ) { @@ -587,10 +589,10 @@ void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PA void PAX_RTupdate(struct peggy_info *PEGS,double cryptovols[2][9][2],double RTmetals[4],double *RTprices,struct PAX_data *dp) { - char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "etc", "steem", "xmr", "bts", "xcp" }; - int32_t iter,i,c,baserel,basenum,relnum; double cnyusd,btcusd,btcdbtc,bid,ask,price,vol,prices[8][2],volumes[8][2]; + char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "etc", "kmd", "xmr", "bts", "xcp" }; + int32_t iter,i,c,baserel,basenum,relnum; double cnyusd,btcusd,kmdbtc,bid,ask,price,vol,prices[8][2],volumes[8][2]; char base[16],rel[16]; - PAX_update(PEGS,&btcusd,&btcdbtc); + PAX_update(PEGS,&btcusd,&kmdbtc); memset(prices,0,sizeof(prices)); memset(volumes,0,sizeof(volumes)); for (i=0; i SMALLVAL ) - dxblend(&btcdbtc,prices[0][0],.9); - dxblend(&dp->btcdbtc,btcdbtc,.995); - if ( PEGS->btcdbtc < SMALLVAL ) - PEGS->btcdbtc = dp->btcdbtc; + dxblend(&kmdbtc,prices[0][0],.9); + dxblend(&dp->kmdbtc,kmdbtc,.995); + if ( PEGS->kmdbtc < SMALLVAL ) + PEGS->kmdbtc = dp->kmdbtc; if ( (cnyusd= PEGS->cnyusd) > SMALLVAL ) { if ( prices[0][1] > SMALLVAL ) @@ -633,15 +635,15 @@ void PAX_RTupdate(struct peggy_info *PEGS,double cryptovols[2][9][2],double RTme } } btcusd = PEGS->btcusd; - btcdbtc = PEGS->btcdbtc; + kmdbtc = PEGS->kmdbtc; if ( Debuglevel > 2 ) - printf(" update with btcusd %f btcd %f\n",btcusd,btcdbtc); - if ( btcusd < SMALLVAL || btcdbtc < SMALLVAL ) + printf(" update with btcusd %f kmd %f\n",btcusd,kmdbtc); + if ( btcusd < SMALLVAL || kmdbtc < SMALLVAL ) { - PAX_update(PEGS,&btcusd,&btcdbtc); + PAX_update(PEGS,&btcusd,&kmdbtc); if ( Debuglevel > 2 ) - printf(" price777_update with btcusd %f btcd %f\n",btcusd,btcdbtc); - } else PEGS->btcusd = btcusd, PEGS->btcdbtc = btcdbtc; + printf(" price777_update with btcusd %f kmd %f\n",btcusd,kmdbtc); + } else PEGS->btcusd = btcusd, PEGS->kmdbtc = kmdbtc; for (c=0; ctmp; *dp = PEGS->data; if ( didinit == 0 ) @@ -717,7 +719,7 @@ int32_t PAX_idle(struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap) //prices777_init(BUNDLE.jsonstr,peggyflag); didinit = 1; datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); - expand_datenum(PEGS->data.edate,datenum); + expand_datenum(dp->edate,datenum); if ( peggyflag != 0 ) { //int32_t opreturns_init(uint32_t blocknum,uint32_t blocktimestamp,char *path); @@ -752,15 +754,15 @@ int32_t PAX_idle(struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap) dp->itimestamps[contractnum] = bidasks[0].timestamp; } } - PAX_update(PEGS,&btcusd,&btcdbtc); + PAX_update(PEGS,&btcusd,&kmdbtc); if ( btcusd > SMALLVAL ) dxblend(&dp->btcusd,btcusd,0.99); - if ( btcdbtc > SMALLVAL ) - dxblend(&dp->btcdbtc,btcdbtc,0.99); + if ( kmdbtc > SMALLVAL ) + dxblend(&dp->kmdbtc,kmdbtc,0.99); if ( dp->btcusd == 0 ) dp->btcusd = dp->btcusd; - if ( dp->btcdbtc == 0 ) - dp->btcdbtc = dp->btcdbtc; + if ( dp->kmdbtc == 0 ) + dp->kmdbtc = dp->kmdbtc; if ( dp->ecbmatrix[USD][USD] > SMALLVAL && dp->ecbmatrix[CNY][CNY] > SMALLVAL ) PEGS->cnyusd = (dp->ecbmatrix[CNY][CNY] / dp->ecbmatrix[USD][USD]); portable_mutex_lock(&mutex); diff --git a/iguana/SuperNET_keys.c b/iguana/SuperNET_keys.c index 0e7b8d077..31cbe6869 100755 --- a/iguana/SuperNET_keys.c +++ b/iguana/SuperNET_keys.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -22,7 +22,6 @@ #include "../includes/curve25519.h" #include "../includes/cJSON.h" - /* if ( 0 ) { @@ -84,7 +83,6 @@ bits256 SuperNET_wallet2priv(char *wallet2fname,bits256 wallethash) wallet2str[i] ^= wallethash.bytes[(i + r) % 32]; vcalc_sha256(0,wallet2priv.bytes,(void *)wallet2str,(int32_t)allocsize); free(wallet2str); - //char str[65]; printf("wallet2priv.(%s) from.(%s) crc.%u and passphrase r.%d len.%ld\n",bits256_str(str,wallet2priv),wallet2fname,crc,r,allocsize); } else if ( wallet2fname[0] != 0 ) printf("SuperNET_wallet2priv cant open (%s)\n",wallet2fname); return(wallet2priv); @@ -179,7 +177,7 @@ int32_t SuperNET_savejsonfile(struct supernet_info *myinfo,char *finalfname,bits { if ( (ciphered= SuperNET_cipher(0,0,json,0,privkey,destpubkey,confstr)) != 0 ) { - printf("ciphered.save (%s) <- (%s)\n",destfname,confstr); + //printf("ciphered.save (%s) <- (%s)\n",destfname,confstr); if ( (fp= fopen(destfname,"wb")) != 0 ) { if ( fwrite(ciphered,1,strlen(ciphered)+1,fp) == strlen(ciphered)+1 ) @@ -204,7 +202,9 @@ int32_t SuperNET_savejsonfile(struct supernet_info *myinfo,char *finalfname,bits { char oldfname[1024]; int64_t fsize,dsize; if ( (fsize= OS_filesize(finalfname)) > (dsize= OS_filesize(destfname)) ) - printf("skip replacing (%s) since new one is smaller %lld vs %lld\n",finalfname,(long long)fsize,(long long)dsize); + { + //printf("skip replacing (%s) since new one is smaller %lld vs %lld\n",finalfname,(long long)fsize,(long long)dsize); + } else { strcpy(oldfname,finalfname), strcat(oldfname,".old"); @@ -219,7 +219,7 @@ int32_t SuperNET_savejsonfile(struct supernet_info *myinfo,char *finalfname,bits int32_t SuperNET_userkeys(char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize) { return(0); -#ifndef __PNACL +/*#ifndef __PNACL //if ( (bits256_nonz(*wallethashp) == 0 || bits256_cmp(*wallethashp,GENESIS_PRIVKEY) == 0) && (bits256_nonz(*wallet2privp) == 0 || bits256_cmp(*wallet2privp,GENESIS_PRIVKEY) == 0) ) { sleep(1); @@ -231,7 +231,7 @@ int32_t SuperNET_userkeys(char *passphrase,int32_t passsize,char *fname2fa,int32 return(0); } #endif - return(-1); + return(-1);*/ } cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize,bits256 wallethash,char *fname2fa,int32_t fnamesize,bits256 wallet2priv) @@ -248,7 +248,6 @@ cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize, wallethash = SuperNET_linehash(passphrase); SuperNET_linehash(fname2fa); // maps special chars wallet2priv = SuperNET_wallet2priv(fname2fa,wallethash); - //char str[65],str2[65]; printf("(%s + %s) -> wallethash.%s 2.(%s)\n",passphrase,fname2fa,bits256_str(str,wallethash),bits256_str(str2,wallet2priv)); } first = (bits256_nonz(wallethash) != 0 && bits256_cmp(wallethash,GENESIS_PRIVKEY) != 0); second = (bits256_nonz(wallet2priv) != 0 && bits256_cmp(wallet2priv,GENESIS_PRIVKEY) != 0); @@ -259,7 +258,6 @@ cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize, wallet2shared = SuperNET_wallet2shared(wallethash,wallet2priv); wallet2pub = curve25519(wallet2shared,curve25519_basepoint9()); sprintf(destfname,"%s/%s",GLOBAL_CONFSDIR,bits256_str(str,wallet2pub)); - //printf("fname.(%s) wallet2pub.%s < [%s, %s]\n",destfname,bits256_str(str,wallet2pub),passphrase,fname2fa); if ( (confstr= OS_filestr(&allocsize,destfname)) != 0 ) { if ( (filejson= cJSON_Parse(confstr)) != 0 ) @@ -305,12 +303,9 @@ int32_t _SuperNET_encryptjson(struct supernet_info *myinfo,char *destfname,char wallethash = SuperNET_linehash(passphrase); SuperNET_linehash(fname2fa); // maps special chars wallet2priv = SuperNET_wallet2priv(fname2fa,wallethash); - //char str2[65]; printf("ENCRYPT.[%s %s] (%s) 2.%s\n",passphrase,fname2fa,bits256_str(str,wallethash),bits256_str(str2,wallet2priv)); wallet2shared = SuperNET_wallet2shared(wallethash,wallet2priv); wallet2pub = curve25519(wallet2shared,curve25519_basepoint9()); sprintf(destfname,"%s/%s",GLOBAL_CONFSDIR,bits256_str(str,wallet2pub)); - printf("SAVE ARGJSON.(%s) [%s, %s] -> destfname.(%s)\n",jprint(argjson,0),passphrase,fname2fa,destfname); - //printf("shared.%llx -> pub.%s\n",(long long)wallet2shared.txid,bits256_str(str,wallet2pub)); SuperNET_savejsonfile(myinfo,destfname,wallethash,wallet2pub,argjson); return(0); } @@ -375,7 +370,6 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) passphrase[0] = fname2fa[0] = 0; wallethash = wallet2priv = GENESIS_PRIVKEY; coinargs = SuperNET_parsemainargs(myinfo,&wallethash,&wallet2priv,argjsonstr); - //printf("wallethash.%s 2.(%s)\n",bits256_str(str,wallethash),bits256_str(str2,wallet2priv)); if ( (msgjson= SuperNET_decryptedjson(destfname,passphrase,sizeof(passphrase),wallethash,fname2fa,sizeof(fname2fa),wallet2priv)) != 0 ) { SuperNET_parsemyinfo(myinfo,msgjson); @@ -395,9 +389,7 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) jaddbits256(json,"persistent_pub",myinfo->myaddr.persistent); OS_randombytes((void *)&r,sizeof(r)); jadd64bits(json,"rand",r); - //printf("call SuperNET_encryptjson\n"); _SuperNET_encryptjson(myinfo,destfname,passphrase,sizeof(passphrase),fname2fa,sizeof(fname2fa),json); - //printf("save.(%s)\n",jprint(json,0)); free_json(json); } if ( myinfo->ipaddr[0] == 0 ) @@ -428,50 +420,4 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) return(coinargs); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -TWO_STRINGS(SuperNET,decryptjson,password,permanentfile) -{ - char pass[8192],fname2[1023],destfname[1024]; cJSON *retjson; bits256 wallethash,wallet2priv; - safecopy(pass,password,sizeof(pass)); - safecopy(fname2,permanentfile,sizeof(fname2)); - wallethash = wallet2priv = GENESIS_PRIVKEY; - if ( strlen(pass) == sizeof(wallethash)*2 && is_hexstr(pass,(int32_t)sizeof(bits256)*2) > 0 ) - wallethash = bits256_conv(pass); - if ( strlen(fname2) == sizeof(wallet2priv)*2 && is_hexstr(fname2,(int32_t)sizeof(bits256)*2) > 0 ) - wallet2priv = bits256_conv(fname2); - if ( (retjson= SuperNET_decryptedjson(destfname,pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 ) - { - //printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); - //obj = jduplicate(jobj(retjson,"payload")); - //jdelete(retjson,"payload"); - //jadd(retjson,"result",obj); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"couldnt decrypt json file\"}")); -} - -THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload) -{ - char destfname[4096],pass[8192],fname2[1023]; cJSON *argjson,*retjson = cJSON_CreateObject(); - safecopy(pass,password,sizeof(pass)); - safecopy(fname2,permanentfile,sizeof(fname2)); - argjson = jduplicate(json); - //printf("argjson.(%s)\n",jprint(argjson,0)); - jdelete(argjson,"agent"); - jdelete(argjson,"method"); - jdelete(argjson,"password"); - jdelete(argjson,"permanentfile"); - jdelete(argjson,"timestamp"); - jdelete(argjson,"tag"); - if ( _SuperNET_encryptjson(myinfo,destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 ) - { - jaddstr(retjson,"result","success"); - jaddstr(retjson,"filename",destfname); - } else jaddstr(retjson,"error","couldnt encrypt json file"); - free_json(argjson); - return(jprint(retjson,1)); -} -#include "../includes/iguana_apiundefs.h" - diff --git a/iguana/btc_7776 b/iguana/btc_7776 new file mode 100755 index 000000000..e1e642539 --- /dev/null +++ b/iguana/btc_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"bitcoin.conf\",\"path\":\"${HOME#"/"}/.bitcoin\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":8333,\"minconfirms\":1}" diff --git a/iguana/cards777.c b/iguana/cards777.c index 023234d97..f74ffc26e 100755 --- a/iguana/cards777.c +++ b/iguana/cards777.c @@ -238,7 +238,7 @@ uint8_t *cards777_encode(struct supernet_info *myinfo,bits256 *encoded,bits256 * init_sharenrs(sharenrs,0,N,N); cards777_calcmofn(myinfo,allshares,myshares,sharenrs,M,xoverz,numcards,N); memcpy(ciphers,shuffled,numcards * N * sizeof(bits256)); - if ( 0 ) + if ( (0) ) { /*{ init_hexbytes_noT(nrs,dp->hand.sharenrs,dp->N); diff --git a/iguana/client b/iguana/client new file mode 100755 index 000000000..93673afdd --- /dev/null +++ b/iguana/client @@ -0,0 +1,23 @@ +source randval +pkill -15 marketmaker; +git pull; +./m_mm; +#./m_mmosx; +./marketmaker "{\"client\":1,\"coins\":[{\"coin\":\"REVS\",\"active\":1, \"asset\":\"REVS\",\"rpcport\":10196},{\"coin\":\"JUMBLR\",\"active\":1, \"asset\":\"JUMBLR\",\"rpcport\":15106}, +{\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, +{\"coin\":\"DOGE\", \"name\":\"dogecoin\", \"pubtype\":30, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000000}, +{\"coin\":\"DGB\", \"name\":\"digibyte\", \"pubtype\":30, \"p2shtype\":5, \"wiftype\":128, \"txfee\":10000}, +{\"coin\":\"MZC\", \"name\":\"mazacoin\", \"pubtype\":50, \"p2shtype\":9, \"wiftype\":224, \"txfee\":0}, +{\"coin\":\"SYS\", \"name\":\"syscoin\", \"pubtype\":0, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000}, +{\"coin\":\"UNO\", \"name\":\"unobtanium\", \"pubtype\":130, \"p2shtype\":30, \"wiftype\":224, \"txfee\":1000000}, +{\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9, \"wiftype\":224, \"txfee\":10000}, +{\"coin\":\"ZEC\", \"name\":\"zcash\", \"pubtype\":184, \"p2shtype\":189, \"wiftype\":128, \"txfee\":10000}, +{\"coin\":\"BTM\", \"name\":\"bitmark\", \"pubtype\":85, \"p2shtype\":5, \"wiftype\":213, \"txfee\":0}, +{\"coin\":\"CARB\", \"name\":\"carboncoin\", \"pubtype\":47, \"p2shtype\":5, \"wiftype\":175, \"txfee\":0}, +{\"coin\":\"ANC\", \"name\":\"anoncoin\", \"pubtype\":23, \"p2shtype\":5, \"wiftype\":151, \"txfee\":2000000}, +{\"coin\":\"FRK\", \"name\":\"franko\", \"pubtype\":35, \"p2shtype\":5, \"wiftype\":163, \"txfee\":0}, +{\"coin\":\"GAME\", \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, +{\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, +{\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341},{\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167},{\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068},{\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890},{\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250},{\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516},{\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431},{\"coin\":\"SHARK\",\"asset\":\"SHARK\",\"rpcport\":10114},{\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964},{\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386},{\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276},{\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":9747},{\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116},{\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455} +], \"userhome\":\"/${HOME#"/"}\",\"passphrase\":\"$randval\"}" & + diff --git a/iguana/coins/Agenbtcd b/iguana/coins/Agenbtcd new file mode 100755 index 000000000..f01315499 --- /dev/null +++ b/iguana/coins/Agenbtcd @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"userpass\":\"username@password\",\"prefetchlag\":11,\"poll\":50,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":512,\"endpend\":512,\"services\":129,\"maxpeers\":512,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632,\"minconfirms\":5}" diff --git a/iguana/coins/allofus b/iguana/coins/allofus index 3671efb31..ffc2afc10 100755 --- a/iguana/coins/allofus +++ b/iguana/coins/allofus @@ -1,3 +1,4 @@ +#!/bin/bash ../agents/iguana coins/genbtcd.json & sleep 5 ../agents/iguana coins/genbtc.json & @@ -17,3 +18,11 @@ sleep 5 ../agents/iguana coins/genuno.json & sleep 5 ../agents/iguana coins/genzet.json & +sleep 5 +../agents/iguana coins/genbtm.json & +sleep 5 +../agents/iguana coins/gencarb.json & +sleep 5 +../agents/iguana coins/genanc.json & +sleep 5 +../agents/iguana coins/genfrk.json & diff --git a/iguana/coins/axo_7776 b/iguana/coins/axo_7776 new file mode 100755 index 000000000..5a4cd4bd8 --- /dev/null +++ b/iguana/coins/axo_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"AXO.conf\",\"path\":\"${HOME#"/"}/.komodo/AXO\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"AXO\",\"name\":\"AXO\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"ba009d17\",\"p2p\":12926,\"rpc\":12927,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk b/iguana/coins/basilisk deleted file mode 100755 index eedabcbdc..000000000 --- a/iguana/coins/basilisk +++ /dev/null @@ -1,4 +0,0 @@ -curl --url "http://127.0.0.1:7778" --data "{\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":14631}" -curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":8333}" -curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":11,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9334,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" - diff --git a/iguana/coins/basilisk.old b/iguana/coins/basilisk.old new file mode 100755 index 000000000..0c953b89d --- /dev/null +++ b/iguana/coins/basilisk.old @@ -0,0 +1,7 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":14631,\"rpc\":14632}" +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":8333}" +#curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":11,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9334,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" + +#curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":18,\"endpend\":18,\"services\":129,\"maxpeers\":256,\"newcoin\":\"SYS\",\"name\":\"SYScoin\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"f9beb4d9\",\"p2p\":8369,\"rpc\":8370,\"pubval\":0,\"p2shval\":5,\"wifval\":128,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"0000072d66e51ab87de265765cc8bdd2d229a4307c672a1b3d5af692519cf765\",\"genesis\":{\"version\":1,\"timestamp\":1450473723,\"nBits\":\"1e0ffff0\",\"nonce\":5258726,\"merkle_root\":\"5215c5a2af9b63f2550b635eb2b354bb13645fd8fa31275394eb161944303065\"},\"protover\":70012,\"auxpow\":1,\"fixit\":0}" + diff --git a/iguana/coins/basilisk/axo b/iguana/coins/basilisk/axo new file mode 100755 index 000000000..d2b6990b9 --- /dev/null +++ b/iguana/coins/basilisk/axo @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"AXO.conf\",\"path\":\"${HOME#"/"}/.komodo/AXO\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"AXO\",\"name\":\"AXO\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"ba009d17\",\"p2p\":12926,\"rpc\":12927,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/bet b/iguana/coins/basilisk/bet new file mode 100755 index 000000000..d2fae9771 --- /dev/null +++ b/iguana/coins/basilisk/bet @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"BET.conf\",\"path\":\"${HOME#"/"}/.komodo/BET\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BET\",\"name\":\"BET\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"6b9e3e1b\",\"p2p\":15610,\"rpc\":15611,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/bots b/iguana/coins/basilisk/bots new file mode 100755 index 000000000..6632e4803 --- /dev/null +++ b/iguana/coins/basilisk/bots @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"BOTS.conf\",\"path\":\"${HOME#"/"}/.komodo/BOTS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BOTS\",\"name\":\"BOTS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"5bec8cf7\",\"p2p\":11363,\"rpc\":11364,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/btc b/iguana/coins/basilisk/btc new file mode 100755 index 000000000..9479f35d7 --- /dev/null +++ b/iguana/coins/basilisk/btc @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"bitcoin.conf\",\"path\":\"${HOME#"/"}/.bitcoin\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":8333,\"minconfirms\":1}" diff --git a/iguana/coins/basilisk/btch b/iguana/coins/basilisk/btch new file mode 100755 index 000000000..a74832995 --- /dev/null +++ b/iguana/coins/basilisk/btch @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"BTCH.conf\",\"path\":\"${HOME#"/"}/.komodo/BTCH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BTCH\",\"name\":\"BTCH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"b0ed1968\",\"p2p\":8799,\"rpc\":8800,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/basilisk/ceal b/iguana/coins/basilisk/ceal new file mode 100755 index 000000000..a4c27ef88 --- /dev/null +++ b/iguana/coins/basilisk/ceal @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"CEAL.conf\",\"path\":\"${HOME#"/"}/.komodo/CEAL\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"CEAL\",\"name\":\"CEAL\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"098c5f90\",\"p2p\":11115,\"rpc\":11116,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/coqui b/iguana/coins/basilisk/coqui new file mode 100755 index 000000000..55730d486 --- /dev/null +++ b/iguana/coins/basilisk/coqui @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"COQUI.conf\",\"path\":\"${HOME#"/"}/.komodo/COQUI\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"COQUI\",\"name\":\"COQUI\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"dd5ce076\",\"p2p\":14275,\"rpc\":14276,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/crypto b/iguana/coins/basilisk/crypto new file mode 100755 index 000000000..49d7670f3 --- /dev/null +++ b/iguana/coins/basilisk/crypto @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"CRYPTO.conf\",\"path\":\"${HOME#"/"}/.komodo/CRYPTO\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"CRYPTO\",\"name\":\"CRYPTO\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fced9e2a\",\"p2p\":12947,\"rpc\":12948,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/dex b/iguana/coins/basilisk/dex new file mode 100755 index 000000000..7c245c2a5 --- /dev/null +++ b/iguana/coins/basilisk/dex @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"DEX.conf\",\"path\":\"${HOME#"/"}/.komodo/DEX\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"DEX\",\"name\":\"DEX\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f2ae0516\",\"p2p\":11889,\"rpc\":11890,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/etomic b/iguana/coins/basilisk/etomic new file mode 100755 index 000000000..4f63e424d --- /dev/null +++ b/iguana/coins/basilisk/etomic @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"ETOMIC.conf\",\"path\":\"${HOME#"/"}/.komodo/ETOMIC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"ETOMIC\",\"name\":\"ETOMIC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"072a90e8\",\"p2p\":10270,\"rpc\":10271,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/hodl b/iguana/coins/basilisk/hodl new file mode 100755 index 000000000..934a21c69 --- /dev/null +++ b/iguana/coins/basilisk/hodl @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"HODL.conf\",\"path\":\"${HOME#"/"}/.komodo/HODL\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"HODL\",\"name\":\"HODL\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"9b13fb5f\",\"p2p\":14430,\"rpc\":14431,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/jumblr b/iguana/coins/basilisk/jumblr new file mode 100755 index 000000000..be336dbb7 --- /dev/null +++ b/iguana/coins/basilisk/jumblr @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"JUMBLR.conf\",\"path\":\"${HOME#"/"}/.komodo/JUMBLR\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"JUMBLR\",\"name\":\"JUMBLR\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7223759e\",\"p2p\":15105,\"rpc\":15106,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/kmd b/iguana/coins/basilisk/kmd new file mode 100755 index 000000000..bfcb83cef --- /dev/null +++ b/iguana/coins/basilisk/kmd @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"komodo.conf\",\"path\":\"${HOME#"/"}/.komodo\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":0,\"maxpeers\":32,\"newcoin\":\"KMD\",\"name\":\"Komodo\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f9eee48d\",\"p2p\":7770,\"rpc\":7771,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0}" + diff --git a/iguana/coins/basilisk/kv b/iguana/coins/basilisk/kv new file mode 100755 index 000000000..6e060642b --- /dev/null +++ b/iguana/coins/basilisk/kv @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"KV.conf\",\"path\":\"${HOME#"/"}/.komodo/KV\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"KV\",\"name\":\"KV\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f434f1c5\",\"p2p\":8298,\"rpc\":8299,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/basilisk/mesh b/iguana/coins/basilisk/mesh new file mode 100755 index 000000000..a8cf1b219 --- /dev/null +++ b/iguana/coins/basilisk/mesh @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"MESH.conf\",\"path\":\"${HOME#"/"}/.komodo/MESH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MESH\",\"name\":\"MESH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"4d6bbfb6\",\"p2p\":8399,\"rpc\":8400,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/basilisk/mgw b/iguana/coins/basilisk/mgw new file mode 100755 index 000000000..416befe2d --- /dev/null +++ b/iguana/coins/basilisk/mgw @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"MGW.conf\",\"path\":\"${HOME#"/"}/.komodo/MGW\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MGW\",\"name\":\"MGW\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fd9feb93\",\"p2p\":12385,\"rpc\":12386,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/mnz b/iguana/coins/basilisk/mnz new file mode 100755 index 000000000..d08d34075 --- /dev/null +++ b/iguana/coins/basilisk/mnz @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"MNZ.conf\",\"path\":\"${HOME#"/"}/.komodo/MNZ\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MNZ\",\"name\":\"MNZ\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"53d06fde\",\"p2p\":14336,\"rpc\":14337,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/mshark b/iguana/coins/basilisk/mshark new file mode 100755 index 000000000..c664fe0b5 --- /dev/null +++ b/iguana/coins/basilisk/mshark @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/mvp b/iguana/coins/basilisk/mvp new file mode 100755 index 000000000..e77c37475 --- /dev/null +++ b/iguana/coins/basilisk/mvp @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"MVP.conf\",\"path\":\"${HOME#"/"}/.komodo/MVP\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MVP\",\"name\":\"MVP\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"dd5ce076\",\"p2p\":11675,\"rpc\":11676,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/pangea b/iguana/coins/basilisk/pangea new file mode 100755 index 000000000..715798269 --- /dev/null +++ b/iguana/coins/basilisk/pangea @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"PANGEA.conf\",\"path\":\"${HOME#"/"}/.komodo/PANGEA\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"PANGEA\",\"name\":\"PANGEA\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"5fa45ae8\",\"p2p\":14067,\"rpc\":14068,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/revs b/iguana/coins/basilisk/revs new file mode 100755 index 000000000..6cef30fff --- /dev/null +++ b/iguana/coins/basilisk/revs @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"REVS.conf\",\"path\":\"${HOME#"/"}/.komodo/REVS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/shark b/iguana/coins/basilisk/shark new file mode 100755 index 000000000..9a4e73fe2 --- /dev/null +++ b/iguana/coins/basilisk/shark @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":10113,\"rpc\":10114,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/basilisk/supernet b/iguana/coins/basilisk/supernet new file mode 100755 index 000000000..c4fc10ea2 --- /dev/null +++ b/iguana/coins/basilisk/supernet @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SUPERNET.conf\",\"path\":\"${HOME#"/"}/.komodo/SUPERNET\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SUPERNET\",\"name\":\"SUPERNET\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"cc55d9d4\",\"p2p\":11340,\"rpc\":11341,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/basilisk/wlc b/iguana/coins/basilisk/wlc new file mode 100755 index 000000000..8c10b2475 --- /dev/null +++ b/iguana/coins/basilisk/wlc @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"WLC.conf\",\"path\":\"${HOME#"/"}/.komodo/WLC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"WLC\",\"name\":\"WLC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7ec1c253\",\"p2p\":12166,\"rpc\":12167,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/bet_7776 b/iguana/coins/bet_7776 new file mode 100755 index 000000000..cbf6f8b58 --- /dev/null +++ b/iguana/coins/bet_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"BET.conf\",\"path\":\"${HOME#"/"}/.komodo/BET\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BET\",\"name\":\"BET\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7961f507\",\"p2p\":14249,\"rpc\":14250,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/bots_7776 b/iguana/coins/bots_7776 new file mode 100755 index 000000000..6ee0731df --- /dev/null +++ b/iguana/coins/bots_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"BOTS.conf\",\"path\":\"${HOME#"/"}/.komodo/BOTS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BOTS\",\"name\":\"BOTS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"ec562904\",\"p2p\":11963,\"rpc\":11964,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/btc b/iguana/coins/btc new file mode 100755 index 000000000..aa81323d5 --- /dev/null +++ b/iguana/coins/btc @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"bitcoin.conf\",\"path\":\"${HOME#"/"}/.bitcoin\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":8333,\"minconfirms\":1}" + diff --git a/iguana/coins/btc_7776 b/iguana/coins/btc_7776 new file mode 100755 index 000000000..cfc05bbe8 --- /dev/null +++ b/iguana/coins/btc_7776 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"bitcoin.conf\",\"path\":\"${HOME#"/"}/.bitcoin\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":8333,\"minconfirms\":1}" diff --git a/iguana/coins/btc_osx b/iguana/coins/btc_osx new file mode 100755 index 000000000..d7dfce062 --- /dev/null +++ b/iguana/coins/btc_osx @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"bitcoin.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Bitcoin\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":8333,\"minconfirms\":1}" + diff --git a/iguana/coins/btch_7776 b/iguana/coins/btch_7776 new file mode 100755 index 000000000..d36d143d8 --- /dev/null +++ b/iguana/coins/btch_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"BTCH.conf\",\"path\":\"${HOME#"/"}/.komodo/BTCH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BTCH\",\"name\":\"BTCH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"b0ed1968\",\"p2p\":8799,\"rpc\":8800,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/ceal_7776 b/iguana/coins/ceal_7776 new file mode 100755 index 000000000..9988127c4 --- /dev/null +++ b/iguana/coins/ceal_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"CEAL.conf\",\"path\":\"${HOME#"/"}/.komodo/CEAL\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"CEAL\",\"name\":\"CEAL\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"098c5f90\",\"p2p\":11115,\"rpc\":11116,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/chips_7776 b/iguana/coins/chips_7776 new file mode 100755 index 000000000..38f1e5f1c --- /dev/null +++ b/iguana/coins/chips_7776 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"chips.conf\",\"path\":\"${HOME#"/"}/.chips\",\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"CHIPS\",\"startpend\":64,\"endpend\":64,\"services\":0,\"maxpeers\":512,\"RELAY\":-1,\"VALIDATE\":0,\"portp2p\":57777,\"minconfirms\":1,\"pubval\":60,\"p2shval\":85,\"wifval\":188}" diff --git a/iguana/coins/coqui_7776 b/iguana/coins/coqui_7776 new file mode 100755 index 000000000..6079fd06e --- /dev/null +++ b/iguana/coins/coqui_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"COQUI.conf\",\"path\":\"${HOME#"/"}/.komodo/COQUI\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"COQUI\",\"name\":\"COQUI\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fa05f107\",\"p2p\":14275,\"rpc\":14276,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/crypto_7776 b/iguana/coins/crypto_7776 new file mode 100755 index 000000000..9913a192e --- /dev/null +++ b/iguana/coins/crypto_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"CRYPTO.conf\",\"path\":\"${HOME#"/"}/.komodo/CRYPTO\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"CRYPTO\",\"name\":\"CRYPTO\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"b47caeaa\",\"p2p\":8515,\"rpc\":8516,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/dex_7776 b/iguana/coins/dex_7776 new file mode 100755 index 000000000..ec0c72e75 --- /dev/null +++ b/iguana/coins/dex_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"DEX.conf\",\"path\":\"${HOME#"/"}/.komodo/DEX\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"DEX\",\"name\":\"DEX\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f2ae0516\",\"p2p\":11889,\"rpc\":11890,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/etomic_7776 b/iguana/coins/etomic_7776 new file mode 100755 index 000000000..c17f7c733 --- /dev/null +++ b/iguana/coins/etomic_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"ETOMIC.conf\",\"path\":\"${HOME#"/"}/.komodo/ETOMIC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"ETOMIC\",\"name\":\"ETOMIC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"072a90e8\",\"p2p\":10270,\"rpc\":10271,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/fastbtcd b/iguana/coins/fastbtcd index 659d8a3f4..65b965721 100755 --- a/iguana/coins/fastbtcd +++ b/iguana/coins/fastbtcd @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":4096,\"endpend\":4096,\"services\":129,\"maxpeers\":256,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632}" diff --git a/iguana/coins/genNAME b/iguana/coins/genNAME new file mode 100755 index 000000000..6d228ef77 --- /dev/null +++ b/iguana/coins/genNAME @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"NAME\",\"name\":\"NAME\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"a06210d8\",\"p2p\":15233,\"rpc\":15234,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/genREVS b/iguana/coins/genREVS new file mode 100755 index 000000000..2647b9660 --- /dev/null +++ b/iguana/coins/genREVS @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"REVS.conf\",\"path\":\"${HOME#"/"}/.komodo/REVS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/genanc b/iguana/coins/genanc new file mode 100755 index 000000000..531f56964 --- /dev/null +++ b/iguana/coins/genanc @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"ANC\",\"name\":\"AnonCoin\",\"netmagic\":\"facabada\",\"p2p\":9377,\"rpc\":28332,\"pubval\":23,\"p2shval\":5,\"wifval\":151,\"txfee_satoshis\":\"2000000\",\"minconfirms\":2,\"genesishash\":\"00000be19c5a519257aa921349037d55548af7cabf112741eb905a26bb73e468\",\"genesis\":{\"version\":1,\"timestamp\":1370190760,\"nBits\":\"1e0ffff0\",\"nonce\":347089008,\"merkle_root\":\"7ce7004d764515f9b43cb9f07547c8e2e00d94c9348b3da33c8681d350f2c736\"},\"alertpubkey\":\"04c6db35c11724e526f6725cc5bd5293b4bc9382397856e1bcef7111fb44ce357fd12442b34c496d937a348c1dca1e36ae0c0e128905eb3d301433887e8f0b4536\",\"protover\":70010}" diff --git a/iguana/coins/genanc.json b/iguana/coins/genanc.json new file mode 100755 index 000000000..f1298d447 --- /dev/null +++ b/iguana/coins/genanc.json @@ -0,0 +1 @@ +{"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"ANC","name":"AnonCoin","netmagic":"facabada","p2p":9377,"rpc":28332,"pubval":23,"p2shval":5,"wifval":151,"txfee_satoshis":"2000000","minconfirms":2,"genesishash":"00000be19c5a519257aa921349037d55548af7cabf112741eb905a26bb73e468","genesis":{"version":1,"timestamp":1370190760,"nBits":"1e0ffff0","nonce":347089008,"merkle_root":"7ce7004d764515f9b43cb9f07547c8e2e00d94c9348b3da33c8681d350f2c736"},"alertpubkey":"04c6db35c11724e526f6725cc5bd5293b4bc9382397856e1bcef7111fb44ce357fd12442b34c496d937a348c1dca1e36ae0c0e128905eb3d301433887e8f0b4536","protover":70010} diff --git a/iguana/coins/genblk b/iguana/coins/genblk new file mode 100755 index 000000000..c1aa09f0e --- /dev/null +++ b/iguana/coins/genblk @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"BLK\",\"name\":\"BlackCoin\",\"netmagic\":\"70352205\",\"p2p\":15714,\"rpc\":15715,\"pubval\":25,\"p2shval\":85,\"wifval\":153,\"txfee_satoshis\":\"10000\",\"minconfirms\":2,\"genesishash\":\"000001faef25dec4fbcf906e6242621df2c183bf232f263d0ba5b101911e4563\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1393221600,\"nBits\":\"1e0fffff\",\"nonce\":164482,\"merkle_root\":\"12630d16a97f24b287c8c2594dda5fb98c9e6c70fc61d44191931ea2aa08dc90\"},\"alertpubkey\":\"0486bce1bac0d543f104cbff2bd23680056a3b9ea05e1137d2ff90eeb5e08472eb500322593a2cb06fbf8297d7beb6cd30cb90f98153b5b7cce1493749e41e0284\",\"isPoS\":1,\"debug\":1}" diff --git a/iguana/coins/genbtc b/iguana/coins/genbtc index 7dbd49524..839825619 100755 --- a/iguana/coins/genbtc +++ b/iguana/coins/genbtc @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":12,\"endpend\":1,\"services\":128,\"maxpeers\":512,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":8333}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":64,\"endpend\":64,\"services\":129,\"maxpeers\":512,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":8333,\"minconfirms\":1}" diff --git a/iguana/coins/genbtc.json b/iguana/coins/genbtc.json index ca5852db4..96be3ba69 100755 --- a/iguana/coins/genbtc.json +++ b/iguana/coins/genbtc.json @@ -1 +1 @@ -{"numhelpers":8,"prefetchlag":-1,"poll":1,"active":1,"agent":"iguana","method":"addcoin","newcoin":"BTC","startpend":1,"endpend":1,"services":129,"maxpeers":512,"RELAY":1,"VALIDATE":1,"portp2p":8333} +{"numhelpers":1,"prefetchlag":-1,"poll":1,"active":1,"agent":"iguana","method":"addcoin","newcoin":"BTC","startpend":64,"endpend":64,"services":129,"maxpeers":512,"RELAY":1,"VALIDATE":1,"portp2p":8333} diff --git a/iguana/coins/genbtc8.json b/iguana/coins/genbtc8.json new file mode 100755 index 000000000..2778078d9 --- /dev/null +++ b/iguana/coins/genbtc8.json @@ -0,0 +1 @@ +{"numhelpers":8,"prefetchlag":11,"poll":1,"active":1,"agent":"iguana","method":"addcoin","newcoin":"BTC","startpend":16,"endpend":16,"services":129,"maxpeers":512,"RELAY":1,"VALIDATE":1,"portp2p":8333} diff --git a/iguana/coins/genbtcd b/iguana/coins/genbtcd index 46dab365f..9bf34747f 100755 --- a/iguana/coins/genbtcd +++ b/iguana/coins/genbtcd @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":50,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":8,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":11,\"poll\":50,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":512,\"endpend\":512,\"services\":129,\"maxpeers\":512,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632,\"minconfirms\":5}" diff --git a/iguana/coins/genbtcdsigs b/iguana/coins/genbtcdsigs new file mode 100755 index 000000000..7aca343eb --- /dev/null +++ b/iguana/coins/genbtcdsigs @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":50,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":8,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"RELAY\":1,\"VALIDATE\":2,\"portp2p\":14631,\"rpc\":14632}" diff --git a/iguana/coins/genbtm b/iguana/coins/genbtm new file mode 100755 index 000000000..9310a1057 --- /dev/null +++ b/iguana/coins/genbtm @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"BTM\",\"name\":\"Bitmark\",\"netmagic\":\"f9beb4d9\",\"p2p\":9265,\"rpc\":9266,\"pubval\":85,\"p2shval\":5,\"wifval\":213,\"txfee_satoshis\":\"0\",\"minconfirms\":2,\"genesishash\":\"c1fb746e87e89ae75bdec2ef0639a1f6786744639ce3d0ece1dcf979b79137cb\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1405274442,\"nBits\":\"1d00ffff\",\"nonce\":14385103,\"merkle_root\":\"d4715adf41222fae3d4bf41af30c675bc27228233d0f3cfd4ae0ae1d3e760ba8\"},\"alertpubkey\":\"04bf5a75ff0f823840ef512b08add20bb4275ff6e097f2830ad28645e28cb5ea4dc2cfd0972b94019ad46f331b45ef4ba679f2e6c87fd19c864365fadb4f8d2269\"}" diff --git a/iguana/coins/genbtm.json b/iguana/coins/genbtm.json new file mode 100755 index 000000000..1dec89c33 --- /dev/null +++ b/iguana/coins/genbtm.json @@ -0,0 +1 @@ +{"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"BTM","name":"Bitmark","netmagic":"f9beb4d9","p2p":9265,"rpc":9266,"pubval":85,"p2shval":5,"wifval":213,"txfee_satoshis":"0","minconfirms":2,"genesishash":"c1fb746e87e89ae75bdec2ef0639a1f6786744639ce3d0ece1dcf979b79137cb","genesis":{"hashalgo":"scrypt","version":1,"timestamp":1405274442,"nBits":"1d00ffff","nonce":14385103,"merkle_root":"d4715adf41222fae3d4bf41af30c675bc27228233d0f3cfd4ae0ae1d3e760ba8"},"alertpubkey":"04bf5a75ff0f823840ef512b08add20bb4275ff6e097f2830ad28645e28cb5ea4dc2cfd0972b94019ad46f331b45ef4ba679f2e6c87fd19c864365fadb4f8d2269"} diff --git a/iguana/coins/gencarb b/iguana/coins/gencarb new file mode 100755 index 000000000..203347a2c --- /dev/null +++ b/iguana/coins/gencarb @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"CARB\",\"name\":\"Carboncoin\",\"netmagic\":\"abccbbdf\",\"p2p\":9350,\"rpc\":9351,\"pubval\":47,\"p2shval\":5,\"wifval\":175,\"txfee_satoshis\":\"0\",\"minconfirms\":2,\"genesishash\":\"a94f1aae8c409a0bd1e53cbca92d7e506b61c51d955cf56f76da501718d48d6c\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1389199888,\"nBits\":\"1e0ffff0\",\"nonce\":605268,\"merkle_root\":\"074bbb9d355731bfa8f67130e2179db7518d1387ad52e55309d4debe7d4e6383\"},\"alertpubkey\":\"046d6918a7c0c053aa942dbb8861499be4bd915c8bfb6a2b77b3787e207097cc2734b9321226ff107c1a95dae98570a66baec66e350d78ceba091b54411654d33f\"}" diff --git a/iguana/coins/gencarb.json b/iguana/coins/gencarb.json new file mode 100755 index 000000000..1fa41a755 --- /dev/null +++ b/iguana/coins/gencarb.json @@ -0,0 +1 @@ +{"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"CARB","name":"Carboncoin","netmagic":"abccbbdf","p2p":9350,"rpc":9351,"pubval":47,"p2shval":5,"wifval":175,"txfee_satoshis":"0","minconfirms":2,"genesishash":"a94f1aae8c409a0bd1e53cbca92d7e506b61c51d955cf56f76da501718d48d6c","genesis":{"hashalgo":"scrypt","version":1,"timestamp":1389199888,"nBits":"1e0ffff0","nonce":605268,"merkle_root":"074bbb9d355731bfa8f67130e2179db7518d1387ad52e55309d4debe7d4e6383"},"alertpubkey":"046d6918a7c0c053aa942dbb8861499be4bd915c8bfb6a2b77b3787e207097cc2734b9321226ff107c1a95dae98570a66baec66e350d78ceba091b54411654d33f"} diff --git a/iguana/coins/gendgb b/iguana/coins/gendgb index b056034b6..f140ba527 100755 --- a/iguana/coins/gendgb +++ b/iguana/coins/gendgb @@ -1,3 +1,4 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"startpend\":16,\"endpend\":8,\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"DGB\",\"name\":\"Digibyte\",\"netmagic\":\"FAC3B6DA\",\"p2p\":12024,\"rpc\":14022,\"pubval\":30,\"p2shval\":5,\"wifval\":128,\"txfee_satoshis\":\"10000\",\"minconfirms\":2,\"genesishash\":\"7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496\",\"genesis\":{\"version\":1,\"timestamp\":1389388394,\"nBits\":\"1e0ffff0\",\"nonce\":2447652,\"merkle_root\":\"72ddd9496b004221ed0557358846d9248ecd4c440ebd28ed901efc18757d0fad\"},\"alertpubkey\":\"04F04441C4757F356290A37C313C3772C5BC5003E898EB2E0CF365795543A7BF690C8BBBFA32EE3A3325477CE2000B7D0453EFBB203329D0F9DF34D5927D022BC9\"}" diff --git a/iguana/coins/gendoge b/iguana/coins/gendoge index 34f665878..6f03a3427 100755 --- a/iguana/coins/gendoge +++ b/iguana/coins/gendoge @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"startpend\":8,\"endpend\":4,\"services\":129,\"auxpow\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"DOGE\",\"name\":\"Dogecoin\",\"netmagic\":\"C0C0C0C0\",\"p2p\":22556,\"rpc\":22555,\"pubval\":30,\"p2shval\":5,\"wifval\":128,\"txfee_satoshis\":\"100000000\",\"minconfirms\":2,\"genesishash\":\"1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691\",\"genesis\":{\"hashalgo\": \"scrypt\",\"version\":1,\"timestamp\":1386325540,\"nBits\":\"1e0ffff0\",\"nonce\":99943,\"merkle_root\":\"5b2a3f53f605d62c53e62932dac6925e3d74afa5a4b459745c36d42d0ed26a69\"},\"alertpubkey\":\"04d4da7a5dae4db797d9b0644d57a5cd50e05a70f36091cd62e2fc41c98ded06340be5a43a35e185690cd9cde5d72da8f6d065b499b06f51dcfba14aad859f443a\"}" diff --git a/iguana/coins/geneac b/iguana/coins/geneac index e7906a2a1..36b3de221 100755 --- a/iguana/coins/geneac +++ b/iguana/coins/geneac @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"auxpow\":0,\"txhastimestamp\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"EAC\",\"name\":\"EarthCoin\",\"netmagic\":\"C0DBF1FD\",\"p2p\":15677,\"rpc\":15678,\"pubval\":30,\"p2shval\":5,\"wifval\":221,\"txfee_satoshis\":\"1000000\",\"minconfirms\":2,\"genesishash\":\"21717d4df403301c0538f1cb9af718e483ad06728bbcd8cc6c9511e2f9146ced\",\"genesis\":{\"version\":1,\"timestamp\":1386746168,\"nBits\":\"1e0ffff0\",\"nonce\":12468024,\"merkle_root\":\"13757c3610411891452ac1f04d7f81946339b0e5b5aba216e6646e81805c4bb1\"},\"alertpubkey\":\"04dcba12349012341234900abcd12223abcd455abcd77788abcd000000aaaaabbbbbcccccdddddeeeeeff00ff00ff00ff001234567890abcdef0022446688abc11\"}" diff --git a/iguana/coins/genfrk b/iguana/coins/genfrk new file mode 100755 index 000000000..7f03fc406 --- /dev/null +++ b/iguana/coins/genfrk @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"FRK\",\"name\":\"Franko\",\"netmagic\":\"7defaced\",\"p2p\":7912,\"rpc\":7913,\"pubval\":35,\"p2shval\":5,\"wifval\":163,\"txfee_satoshis\":\"0\",\"minconfirms\":2,\"genesishash\":\"19225ae90d538561217b5949e98ca4964ac91af39090d1a4407c892293e4f44f\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1368144664,\"nBits\":\"1e0ffff0\",\"nonce\":731837,\"merkle_root\":\"b78f79f1d10029cc45ed3d5a1db7bd423d4ee170c03baf110a62565d16a21dca\"},\"alertpubkey\":\"04d4da7a5dae4db797d9b0644d57a5cd50e05a70f36091cd62e2fc41c98ded06340be5a43a35e185690cd9cde5d72da8f6d065b499b06f51dcfba14aad859f443a\"}" diff --git a/iguana/coins/genfrk.json b/iguana/coins/genfrk.json new file mode 100755 index 000000000..c203fa070 --- /dev/null +++ b/iguana/coins/genfrk.json @@ -0,0 +1 @@ +{"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"FRK","name":"Franko","netmagic":"7defaced","p2p":7912,"rpc":7913,"pubval":35,"p2shval":5,"wifval":163,"txfee_satoshis":"0","minconfirms":2,"genesishash":"19225ae90d538561217b5949e98ca4964ac91af39090d1a4407c892293e4f44f","genesis":{"hashalgo":"scrypt","version":1,"timestamp":1368144664,"nBits":"1e0ffff0","nonce":731837,"merkle_root":"b78f79f1d10029cc45ed3d5a1db7bd423d4ee170c03baf110a62565d16a21dca"},"alertpubkey":"04d4da7a5dae4db797d9b0644d57a5cd50e05a70f36091cd62e2fc41c98ded06340be5a43a35e185690cd9cde5d72da8f6d065b499b06f51dcfba14aad859f443a"} diff --git a/iguana/coins/gengmc b/iguana/coins/gengmc index 688b18f50..b07fd5261 100755 --- a/iguana/coins/gengmc +++ b/iguana/coins/gengmc @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"startpend\":8,\"endpend\":2,\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"GMC\",\"name\":\"GameCredits\",\"netmagic\":\"fbc0b6db\",\"p2p\":40002,\"rpc\":40001,\"pubval\":38,\"p2shval\":5,\"wifval\":166,\"txfee_satoshis\":\"100000\",\"minconfirms\":2,\"genesishash\":\"91ec5f25ee9a0ffa1af7d4da4db9a552228dd2dc77cdb15b738be4e1f55f30ee\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1392757140,\"nBits\":\"1e0ffff0\",\"nonce\":2084565393,\"merkle_root\":\"d849db99a14164f4b4c8ad6d2d8d7e2b1ba7f89963e9f4bf9fad5ff1a4754429\"},\"alertpubkey\":\"04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284\",\"auxpow\":1,\"protover\":80006,\"isPoS\":0}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"startpend\":8,\"endpend\":4,\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"GMC\",\"name\":\"GameCredits\",\"netmagic\":\"fbc0b6db\",\"p2p\":40002,\"rpc\":40001,\"pubval\":38,\"p2shval\":5,\"wifval\":166,\"txfee_satoshis\":\"100000\",\"minconfirms\":2,\"genesishash\":\"91ec5f25ee9a0ffa1af7d4da4db9a552228dd2dc77cdb15b738be4e1f55f30ee\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1392757140,\"nBits\":\"1e0ffff0\",\"nonce\":2084565393,\"merkle_root\":\"d849db99a14164f4b4c8ad6d2d8d7e2b1ba7f89963e9f4bf9fad5ff1a4754429\"},\"alertpubkey\":\"04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284\",\"auxpow\":1,\"protover\":80006,\"isPoS\":0,\"fixit\":0}" diff --git a/iguana/coins/genkmd b/iguana/coins/genkmd new file mode 100755 index 000000000..cd2fc11c4 --- /dev/null +++ b/iguana/coins/genkmd @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":64,\"endpend\":64,\"services\":129,\"maxpeers\":32,\"newcoin\":\"KMD\",\"name\":\"Komodo\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f9eee48d\",\"p2p\":7770,\"rpc\":7771,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0}" + diff --git a/iguana/coins/genltc b/iguana/coins/genltc index f5faec175..ea034ed80 100755 --- a/iguana/coins/genltc +++ b/iguana/coins/genltc @@ -1,2 +1,4 @@ -curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" diff --git a/iguana/coins/genmzc b/iguana/coins/genmzc index 0f3c41e6f..c2327a0a4 100755 --- a/iguana/coins/genmzc +++ b/iguana/coins/genmzc @@ -1 +1,3 @@ +#!/bin/bash + curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"MZC\",\"name\":\"MazaCoin\",\"netmagic\":\"f8b503df\",\"p2p\":12835,\"rpc\":12832,\"pubval\":50,\"p2shval\":9,\"wifval\":224,\"txfee_satoshis\":\"0\",\"minconfirms\":2,\"genesishash\":\"00000c7c73d8ce604178dae13f0fc6ec0be3275614366d44b1b4b5c6e238c60c\",\"genesis\":{\"version\":1,\"timestamp\":1390747675,\"nBits\":\"1e0ffff0\",\"nonce\":2091390249,\"merkle_root\":\"62d496378e5834989dd9594cfc168dbb76f84a39bbda18286cddc7d1d1589f4f\"},\"alertpubkey\":\"04f09702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284\"}" diff --git a/iguana/coins/gennmc b/iguana/coins/gennmc index 6165ad19e..ffc6900f3 100755 --- a/iguana/coins/gennmc +++ b/iguana/coins/gennmc @@ -1 +1,3 @@ +#!/bin/bash + curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"NMC\",\"active\":1,\"maxpeers\":128,\"services\":129,\"poll\":1,\"minconfirms\":3,\"estblocktime\":600,\"txfee_satoshis\":500000,\"useaddmultisig\":1,\"hastimestamp\":0,\"pubval\":\"00\",\"scriptval\":\"05\",\"wiftype\":\"80\",\"netmagic\":\"fba4c795\",\"genesishash\":\"000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770\",\"genesis\":{\"hashalgo\":\"sha256\",\"version\":1,\"timestamp\":1303000001,\"nbits\":\"1c007fff\",\"nonce\":2719916434,\"merkle_root\":\"41c62dbd9068c89a449525e3cd5ac61b20ece28c3c38b3f35b2161f0e6d3cb0d\"},\"p2p\":8334,\"rpc\":8836}" diff --git a/iguana/coins/gennotary b/iguana/coins/gennotary new file mode 100755 index 000000000..87322604d --- /dev/null +++ b/iguana/coins/gennotary @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7776" --data "{\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"NOTARY\",\"services\":129,\"maxpeers\":2048,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":7775,\"rpc\":0}" diff --git a/iguana/coins/genshark b/iguana/coins/genshark new file mode 100755 index 000000000..941fc20ed --- /dev/null +++ b/iguana/coins/genshark @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/gensys b/iguana/coins/gensys index 209e33213..483910f4e 100755 --- a/iguana/coins/gensys +++ b/iguana/coins/gensys @@ -1,2 +1,4 @@ -curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":18,\"endpend\":18,\"services\":129,\"maxpeers\":256,\"newcoin\":\"SYS\",\"name\":\"SYScoin\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"f9beb4d9\",\"p2p\":8369,\"rpc\":8370,\"pubval\":0,\"p2shval\":5,\"wifval\":128,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"0000072d66e51ab87de265765cc8bdd2d229a4307c672a1b3d5af692519cf765\",\"genesis\":{\"version\":1,\"timestamp\":1450473723,\"nBits\":\"1e0ffff0\",\"nonce\":5258726,\"merkle_root\":\"5215c5a2af9b63f2550b635eb2b354bb13645fd8fa31275394eb161944303065\"},\"protover\":70012,\"auxpow\":1}" +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":18,\"endpend\":18,\"services\":129,\"maxpeers\":256,\"newcoin\":\"SYS\",\"name\":\"SYScoin\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"f9beb4d9\",\"p2p\":8369,\"rpc\":8370,\"pubval\":0,\"p2shval\":5,\"wifval\":128,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"0000072d66e51ab87de265765cc8bdd2d229a4307c672a1b3d5af692519cf765\",\"genesis\":{\"version\":1,\"timestamp\":1450473723,\"nBits\":\"1e0ffff0\",\"nonce\":5258726,\"merkle_root\":\"5215c5a2af9b63f2550b635eb2b354bb13645fd8fa31275394eb161944303065\"},\"protover\":70012,\"auxpow\":1,\"fixit\":0}" diff --git a/iguana/coins/gentaz b/iguana/coins/gentaz new file mode 100755 index 000000000..4baac3bf2 --- /dev/null +++ b/iguana/coins/gentaz @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":32,\"newcoin\":\"TAZ\",\"name\":\"Test Zcash\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"a5f1e726\",\"p2p\":18233,\"rpc\":18232,\"pubval\":111,\"p2shval\":196,\"wifval\":239,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"0cdf00b25a93ded11d73ebe1728cf7867f18e1f62aca9554b95e0f3026174e33\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a0000000000000000000000000000000000000000000000000000000000000000dae5494d0f0f0f200900000000000000000000000000000000000000000000000000000000000000fd4005003423da3e41f916bf3ff0ee770eb844a240361abe08a8c9d46bd30226e2ad411a4047b6ddc230d173c60537e470e24f764120f5a2778b2a1285b0727bf79a0b085ad67e6266fb38fd72ef17f827315c42f921720248c983d4100e6ebd1c4b5e8762a973bac3bec7f7153b93752ebbb465f0fc9520bcfc30f9abfe303627338fed6ede9cf1b9173a736cf270cf4d9c6999ff4c3a301a78fd50dab6ccca67a0c5c2e41f216a1f3efd049a74bbe6252f9773bc309d3f9e554d996913ce8e1cec672a1fa4ea59726b61ea9e75d5ce9aa5dbfa96179a293810e02787f26de324fe7c88376ff57e29574a55faff7c2946f3e40e451861c32bf67da7377de3136858a18f34fab1bc8da37726ca2c25fc7b312a5427554ec944da81c7e27255d6c94ade9987ff7daedc2d1cc63d7d4cf93e691d13326fb1c7ee72ccdc0b134eb665fc6a9821e6fef6a6d45e4aac6dca6b505a0100ad56ea4f6fa4cdc2f0d1b65f730104a515172e34163bdb422f99d083e6eb860cf6b3f66642c4dbaf0d0fa1dca1b6166f1d1ffaa55a9d6d6df628afbdd14f1622c1c8303259299521a253bc28fcc93676723158067270fc710a09155a1e50c533e9b79ed5edba4ab70a08a9a2fc0eef0ddae050d75776a9804f8d6ad7e30ccb66c6a98d86710ca7a4dfb4feb159484796b9a015c5764aa3509051c87f729b9877ea41f8b470898c01388ed9098b1e006d3c30fc6e7c781072fa3f75d918505ee8ca75840fc62f67c57060666aa42578a2dd022eda62e3f1e447d7364074d34fd60ad9b138f60422afa6cfcb913fd6c213b496144dbfda7bfc7c24540cfe40ad0c0fd5a8c0902127f53d3178ba1b2a87bf1224d53d3a15e49ccdf121ae872a011c996d1b9793153cdcd4c0a7e99f8a35669788551cca2b62769eda24b6b55e2f4e0ac0d30aa50ecf33c6cdb24adfc922006a7bf434ced800fefe814c94c6fc8caa37b372d5088bb31d2f6b11a7a67ad3f70abbac0d5c256b637828de6cc525978cf151a2e50798e0c591787639a030291272c9ced3ab7d682e03f8c7db51f60163baa85315789666ea8c5cd6f789a7f4a5de4f8a9dfefce20f353cec606492fde8eab3e3b487b3a3a57434f8cf252a4b643fc125c8a5948b06744f5dc306aa587bdc85364c7488235c6edddd78763675e50a9637181519be06dd30c4ba0d845f9ba320d01706fd6dd64d1aa3cd4211a4a7d1d3f2c1ef2766d27d5d2cdf8e7f5e3ea309d4f149bb737305df1373a7f5313abe5986f4aa620bec4b0065d48aafac3631de3771f5c4d2f6eec67b09d9c70a3c1969fecdb014cb3c69832b63cc9d6efa378bff0ef95ffacdeb1675bb326e698f022c1a3a2e1c2b0f05e1492a6d2b7552388eca7ee8a2467ef5d4207f65d4e2ae7e33f13eb473954f249d7c20158ae703e1accddd4ea899f026618695ed2949715678a32a153df32c08922fafad68b1895e3b10e143e712940104b3b352369f4fe79bd1f1dbe03ea9909dbcf5862d1f15b3d1557a6191f54c891513cdb3c729bb9ab08c0d4c35a3ed67d517ffe1e2b7a798521aed15ff9822169c0ec860d7b897340bc2ef4c37f7eb73bd7dafef12c4fd4e6f5dd3690305257ae14ed03df5e3327b68467775a90993e613173fa6650ffa2a26e84b3ce79606bf234eda9f4053307f344099e3b10308d3785b8726fd02d8e94c2759bebd05748c3fe7d5fe087dc63608fb77f29708ab167a13f32da251e249a544124ed50c270cfc6986d9d1814273d2f0510d0d2ea335817207db6a4a23ae9b079967b63b25cb3ceea7001b65b879263f5009ac84ab89738a5b8b71fd032beb9f297326f1f5afa630a5198d684514e242f315a4d95fa6802e82799a525bb653b80b4518ec610a5996403b1391\",\"debug\":0}" + diff --git a/iguana/coins/genuno b/iguana/coins/genuno index a8733b364..08eecd7dc 100755 --- a/iguana/coins/genuno +++ b/iguana/coins/genuno @@ -1 +1,3 @@ +#!/bin/bash + curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"auxpow\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"UNO\",\"name\":\"Unobtanium\",\"netmagic\":\"03d5b503\",\"p2p\":65534,\"rpc\":65535,\"pubval\":130,\"p2shval\":30,\"wifval\":224,\"txfee_satoshis\":\"1000000\",\"minconfirms\":2,\"genesishash\":\"000004c2fc5fffb810dccc197d603690099a68305232e552d96ccbe8e2c52b75\",\"genesis\":{\"version\":1,\"timestamp\":1375548986,\"nBits\":\"1e0fffff\",\"nonce\":1211565,\"merkle_root\":\"36a192e90f70131a884fe541a1e8a5643a28ba4cb24cbb2924bd0ee483f7f484\"},\"alertpubkey\":\"04fd68acb6a895f3462d91b43eef0da845f0d531958a858554feab3ac330562bf76910700b3f7c29ee273ddc4da2bb5b953858f6958a50e8831eb43ee30c32f21d\"}" diff --git a/iguana/coins/genvia b/iguana/coins/genvia old mode 100644 new mode 100755 index 2b7bad89a..84f84d150 --- a/iguana/coins/genvia +++ b/iguana/coins/genvia @@ -1,2 +1,4 @@ +#!/bin/bash + curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"startpend\":4,\"endpend\":4,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"VIA\",\"name\":\"Viacoin\",\"netmagic\":\"0f68c6cb\",\"p2p\":5223,\"rpc\":38332,\"pubval\":71,\"p2shval\":33,\"wifval\":199,\"txfee_satoshis\":\"100000\",\"minconfirms\":2,\"genesishash\":\"4e9b54001f9976049830128ec0331515eaabe35a70970d79971da1539a400ba1\",\"genesis\":{\"version\":1,\"timestamp\":1405164774,\"nBits\":\"1e01ffff\",\"nonce\":4016033,\"merkle_root\":\"0317d32e01a2adf6f2ac6f58c7cdaab6c656edc6fdb45986c739290053275200\"},\"alertpubkey\":\"047885d9f6c0cf9e918d04634d4dd696cf172763f1975aad099daddca3f3c712c98754eae293b36484055e0d414800e519f5a342e56e09217faf07abff5bd96507\"}" diff --git a/iguana/coins/genvpn b/iguana/coins/genvpn index d87aa3ab8..45543d25b 100755 --- a/iguana/coins/genvpn +++ b/iguana/coins/genvpn @@ -1 +1,3 @@ +#!/bin/bash + curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":256,\"newcoin\":\"VPN\",\"name\":\"VPNcoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"isPoS\":1,\"minoutput\":10000,\"minconfirms\":2,\"txfee_satoshis\":\"10000\",\"genesishash\":\"00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99\",\"genesis\":{\"version\":1,\"timestamp\":1409839200,\"nBits\":\"1e0fffff\",\"nonce\":64881664,\"merkle_root\":\"698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828\"},\"protover\":70002,\"netmagic\":\"fbc0b6db\",\"p2p\":1920,\"rpc\":1921,\"pubval\":71,\"p2shval\":5,\"wifval\":199}" diff --git a/iguana/coins/genvrc b/iguana/coins/genvrc new file mode 100755 index 000000000..d69d10108 --- /dev/null +++ b/iguana/coins/genvrc @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"VRC\",\"name\":\"VeriCoin\",\"netmagic\":\"70352205\",\"p2p\":58684,\"rpc\":58683,\"pubval\":70,\"p2shval\":132,\"wifval\":153,\"txfee_satoshis\":\"10000\",\"minconfirms\":10,\"genesishash\":\"000004da58a02be894a6c916d349fe23cc29e21972cafb86b5d3f07c4b8e6bb8\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1399690945,\"nBits\":\"1e0fffff\",\"nonce\":612416,\"merkle_root\":\"60424046d38de827de0ed1a20a351aa7f3557e3e1d3df6bfb34a94bc6161ec68\"},\"alertpubkey\":\"047eba500c7134efcaf721e9f438f25b948ceaa5f059b877b3a64f6fa2cf0ea6f41091bd9b1ff9448727db97e4ad44d49496dc41949c677c49fe632d1d7996a515\",\"isPoS\":1,\"debug\":1}" diff --git a/iguana/coins/genzcash b/iguana/coins/genzcash index fbdf0ccda..84762c711 100755 --- a/iguana/coins/genzcash +++ b/iguana/coins/genzcash @@ -1,2 +1,4 @@ +#!/bin/bash + curl --url "http://127.0.0.1:7778" --data "{\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":32,\"newcoin\":\"ZEC\",\"name\":\"Zcash\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"6df6e755\",\"p2p\":18333,\"rpc\":18332,\"pubval\":111,\"p2shval\":196,\"wifval\":239,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"27d1f4ce03fc473c9dd6e1e307c682c8f802eae1f5a2f61402aa1ae8702ed3b6\",\"protover\":70002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f200000000000000000000000000000000000000000000000000000000000000000209d0900001dc600004fba000024e20100e5660000778100007e190100222f0100720e000056e50100eb12010089920100583d00002e660000844e01001bfe0100cf0c0000892a0000f5230000f9680000976e00009b7b000046770000afd80100bd0d000057650000048f000082b100006a2500004e0601006fef000048410100\"}" diff --git a/iguana/coins/genzec b/iguana/coins/genzec new file mode 100755 index 000000000..aec6d186a --- /dev/null +++ b/iguana/coins/genzec @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"path\":\"${HOME#"/"}/.path\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":32,\"newcoin\":\"ZEC\",\"name\":\"Zcash\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"24e92764\",\"p2p\":8233,\"rpc\":8232,\"pubval\":184,\"p2shval\":189,\"wifval\":128,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08\",\"protover\":170002,\"genesisblock\":\"040000000000000000000000000000000000000000000000000000000000000000000000db4d7a85b768123f1dff1d4c4cece70083b2d27e117b4ac2e31d087988a5eac4000000000000000000000000000000000000000000000000000000000000000090041358ffff071f5712000000000000000000000000000000000000000000000000000000000000fd4005000a889f00854b8665cd555f4656f68179d31ccadc1b1f7fb0952726313b16941da348284d67add4686121d4e3d930160c1348d8191c25f12b267a6a9c131b5031cbf8af1f79c9d513076a216ec87ed045fa966e01214ed83ca02dc1797270a454720d3206ac7d931a0a680c5c5e099057592570ca9bdf6058343958b31901fce1a15a4f38fd347750912e14004c73dfe588b903b6c03166582eeaf30529b14072a7b3079e3a684601b9b3024054201f7440b0ee9eb1a7120ff43f713735494aa27b1f8bab60d7f398bca14f6abb2adbf29b04099121438a7974b078a11635b594e9170f1086140b4173822dd697894483e1c6b4e8b8dcd5cb12ca4903bc61e108871d4d915a9093c18ac9b02b6716ce1013ca2c1174e319c1a570215bc9ab5f7564765f7be20524dc3fdf8aa356fd94d445e05ab165ad8bb4a0db096c097618c81098f91443c719416d39837af6de85015dca0de89462b1d8386758b2cf8a99e00953b308032ae44c35e05eb71842922eb69797f68813b59caf266cb6c213569ae3280505421a7e3a0a37fdf8e2ea354fc5422816655394a9454bac542a9298f176e211020d63dee6852c40de02267e2fc9d5e1ff2ad9309506f02a1a71a0501b16d0d36f70cdfd8de78116c0c506ee0b8ddfdeb561acadf31746b5a9dd32c21930884397fb1682164cb565cc14e089d66635a32618f7eb05fe05082b8a3fae620571660a6b89886eac53dec109d7cbb6930ca698a168f301a950be152da1be2b9e07516995e20baceebecb5579d7cdbc16d09f3a50cb3c7dffe33f26686d4ff3f8946ee6475e98cf7b3cf9062b6966e838f865ff3de5fb064a37a21da7bb8dfd2501a29e184f207caaba364f36f2329a77515dcb710e29ffbf73e2bbd773fab1f9a6b005567affff605c132e4e4dd69f36bd201005458cfbd2c658701eb2a700251cefd886b1e674ae816d3f719bac64be649c172ba27a4fd55947d95d53ba4cbc73de97b8af5ed4840b659370c556e7376457f51e5ebb66018849923db82c1c9a819f173cccdb8f3324b239609a300018d0fb094adf5bd7cbb3834c69e6d0b3798065c525b20f040e965e1a161af78ff7561cd874f5f1b75aa0bc77f720589e1b810f831eac5073e6dd46d00a2793f70f7427f0f798f2f53a67e615e65d356e66fe40609a958a05edb4c175bcc383ea0530e67ddbe479a898943c6e3074c6fcc252d6014de3a3d292b03f0d88d312fe221be7be7e3c59d07fa0f2f4029e364f1f355c5d01fa53770d0cd76d82bf7e60f6903bc1beb772e6fde4a70be51d9c7e03c8d6d8dfb361a234ba47c470fe630820bbd920715621b9fbedb49fcee165ead0875e6c2b1af16f50b5d6140cc981122fcbcf7c5a4e3772b3661b628e08380abc545957e59f634705b1bbde2f0b4e055a5ec5676d859be77e20962b645e051a880fddb0180b4555789e1f9344a436a84dc5579e2553f1e5fb0a599c137be36cabbed0319831fea3fddf94ddc7971e4bcf02cdc93294a9aab3e3b13e3b058235b4f4ec06ba4ceaa49d675b4ba80716f3bc6976b1fbf9c8bf1f3e3a4dc1cd83ef9cf816667fb94f1e923ff63fef072e6a19321e4812f96cb0ffa864da50ad74deb76917a336f31dce03ed5f0303aad5e6a83634f9fcc371096f8288b8f02ddded5ff1bb9d49331e4a84dbe1543164438fde9ad71dab024779dcdde0b6602b5ae0a6265c14b94edd83b37403f4b78fcd2ed555b596402c28ee81d87a909c4e8722b30c71ecdd861b05f61f8b1231795c76adba2fdefa451b283a5d527955b9f3de1b9828e7b2e74123dd47062ddcc09b05e7fa13cb2212a6fdbc65d7e852cec463ec6fd929f5b8483cf3052113b13dac91b69f49d1b7d1aec01c4a68e41ce157\",\"debug\":0}" diff --git a/iguana/coins/genzet b/iguana/coins/genzet index b2a82272b..d7e972a3e 100755 --- a/iguana/coins/genzet +++ b/iguana/coins/genzet @@ -1 +1,3 @@ +#!/bin/bash + curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"ZET\",\"name\":\"Zetacoin\",\"netmagic\":\"fab503df\",\"p2p\":17333,\"rpc\":17335,\"pubval\":80,\"p2shval\":9,\"wifval\":224,\"txfee_satoshis\":\"10000\",\"minconfirms\":2,\"genesishash\":\"000006cab7aa2be2da91015902aa4458dd5fbb8778d175c36d429dc986f2bff4\",\"genesis\":{\"version\":1,\"timestamp\":1375548986,\"nBits\":\"1e0fffff\",\"nonce\":2089928209,\"merkle_root\":\"d0227b8c3e3d07bce9656b3d9e474f050d23458aaead93357dcfdac9ab9b79f9\"},\"alertpubkey\":\"045337216002ca6a71d63edf062895417610a723d453e722bf4728996c58661cdac3d4dec5cecd449b9086e9602b35cc726a9e0163e1a4d40f521fbdaebb674658\"}" diff --git a/iguana/coins/hodl_7776 b/iguana/coins/hodl_7776 new file mode 100755 index 000000000..378beeea5 --- /dev/null +++ b/iguana/coins/hodl_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"HODL.conf\",\"path\":\"${HOME#"/"}/.komodo/HODL\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"HODL\",\"name\":\"HODL\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"9b13fb5f\",\"p2p\":14430,\"rpc\":14431,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/jumblr b/iguana/coins/jumblr new file mode 100755 index 000000000..5b52ce9a6 --- /dev/null +++ b/iguana/coins/jumblr @@ -0,0 +1,4 @@ +~/komodo/src/komodod -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 & + +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"JUMBLR.conf\",\"path\":\"${HOME#"/"}/.komodo/JUMBLR\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"JUMBLR\",\"name\":\"JUMBLR\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7223759e\",\"p2p\":15105,\"rpc\":15106,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/jumblr_7776 b/iguana/coins/jumblr_7776 new file mode 100755 index 000000000..a05d17e57 --- /dev/null +++ b/iguana/coins/jumblr_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"JUMBLR.conf\",\"path\":\"${HOME#"/"}/.komodo/JUMBLR\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"JUMBLR\",\"name\":\"JUMBLR\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7223759e\",\"p2p\":15105,\"rpc\":15106,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/jumblr_osx b/iguana/coins/jumblr_osx new file mode 100755 index 000000000..dd50b1842 --- /dev/null +++ b/iguana/coins/jumblr_osx @@ -0,0 +1,3 @@ +/Applications/komodoOSX.app/Contents/komodod -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 & +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"JUMBLR.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Komodo/JUMBLR\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"JUMBLR\",\"name\":\"JUMBLR\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7223759e\",\"p2p\":15105,\"rpc\":15106,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/kmd b/iguana/coins/kmd new file mode 100755 index 000000000..d8adec760 --- /dev/null +++ b/iguana/coins/kmd @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"komodo.conf\",\"path\":\"${HOME#"/"}/.komodo\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":0,\"maxpeers\":32,\"newcoin\":\"KMD\",\"name\":\"Komodo\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f9eee48d\",\"p2p\":7770,\"rpc\":7771,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0}" + diff --git a/iguana/coins/kmd_7776 b/iguana/coins/kmd_7776 new file mode 100755 index 000000000..00cc8469d --- /dev/null +++ b/iguana/coins/kmd_7776 @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"komodo.conf\",\"path\":\"${HOME#"/"}/.komodo\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":0,\"maxpeers\":32,\"newcoin\":\"KMD\",\"name\":\"Komodo\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f9eee48d\",\"p2p\":7770,\"rpc\":7771,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0}" + diff --git a/iguana/coins/kmd_osx b/iguana/coins/kmd_osx new file mode 100755 index 000000000..2374af8a7 --- /dev/null +++ b/iguana/coins/kmd_osx @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"komodo.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Komodo\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":0,\"maxpeers\":32,\"newcoin\":\"KMD\",\"name\":\"Komodo\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f9eee48d\",\"p2p\":7770,\"rpc\":7771,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0}" + diff --git a/iguana/coins/kv_7776 b/iguana/coins/kv_7776 new file mode 100755 index 000000000..8e9098912 --- /dev/null +++ b/iguana/coins/kv_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"KV.conf\",\"path\":\"${HOME#"/"}/.komodo/KV\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"KV\",\"name\":\"KV\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f434f1c5\",\"p2p\":8298,\"rpc\":8299,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/ltc_7776 b/iguana/coins/ltc_7776 new file mode 100755 index 000000000..d6b5e4e11 --- /dev/null +++ b/iguana/coins/ltc_7776 @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"litecoin.conf\",\"path\":\"${HOME#"/"}/.litecoin\",\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":68,\"endpend\":68,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" + diff --git a/iguana/coins/m_extract_genesis b/iguana/coins/m_extract_genesis index eaa0bcae4..b9bb28180 100755 --- a/iguana/coins/m_extract_genesis +++ b/iguana/coins/m_extract_genesis @@ -1 +1,3 @@ +#!/bin/bash + gcc -o extract_genesis extract_genesis.c diff --git a/iguana/coins/mesh_7776 b/iguana/coins/mesh_7776 new file mode 100755 index 000000000..bcccf8d8d --- /dev/null +++ b/iguana/coins/mesh_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MESH.conf\",\"path\":\"${HOME#"/"}/.komodo/MESH\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MESH\",\"name\":\"MESH\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"4d6bbfb6\",\"p2p\":9454,\"rpc\":9455,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/mgw_7776 b/iguana/coins/mgw_7776 new file mode 100755 index 000000000..d3de1394e --- /dev/null +++ b/iguana/coins/mgw_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MGW.conf\",\"path\":\"${HOME#"/"}/.komodo/MGW\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MGW\",\"name\":\"MGW\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fd9feb93\",\"p2p\":12385,\"rpc\":12386,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/mnz_7776 b/iguana/coins/mnz_7776 new file mode 100755 index 000000000..10d68be4c --- /dev/null +++ b/iguana/coins/mnz_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MNZ.conf\",\"path\":\"${HOME#"/"}/.komodo/MNZ\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MNZ\",\"name\":\"MNZ\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"53d06fde\",\"p2p\":14336,\"rpc\":14337,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/mshark_7776 b/iguana/coins/mshark_7776 new file mode 100755 index 000000000..e1d4e05fd --- /dev/null +++ b/iguana/coins/mshark_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MSHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/MSHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MSHARK\",\"name\":\"MSHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":8845,\"rpc\":8846,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/mvp_7776 b/iguana/coins/mvp_7776 new file mode 100755 index 000000000..c50897a9a --- /dev/null +++ b/iguana/coins/mvp_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"MVP.conf\",\"path\":\"${HOME#"/"}/.komodo/MVP\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"MVP\",\"name\":\"MVP\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fa05f107\",\"p2p\":8654,\"rpc\":8655,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/notary b/iguana/coins/notary new file mode 100755 index 000000000..db25e84a0 --- /dev/null +++ b/iguana/coins/notary @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"NOTARY\",\"services\":128,\"maxpeers\":2048,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":7775,\"rpc\":0}" diff --git a/iguana/coins/pangea_7776 b/iguana/coins/pangea_7776 new file mode 100755 index 000000000..424f6ace6 --- /dev/null +++ b/iguana/coins/pangea_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"PANGEA.conf\",\"path\":\"${HOME#"/"}/.komodo/PANGEA\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"PANGEA\",\"name\":\"PANGEA\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"5fa45ae8\",\"p2p\":14067,\"rpc\":14068,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/revs b/iguana/coins/revs new file mode 100755 index 000000000..23f4948b2 --- /dev/null +++ b/iguana/coins/revs @@ -0,0 +1,3 @@ +~/komodo/src/komodod -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 & +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"REVS.conf\",\"path\":\"${HOME#"/"}/.komodo/REVS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/revs_7776 b/iguana/coins/revs_7776 new file mode 100755 index 000000000..99423347f --- /dev/null +++ b/iguana/coins/revs_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"REVS.conf\",\"path\":\"${HOME#"/"}/.komodo/REVS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/revs_osx b/iguana/coins/revs_osx new file mode 100755 index 000000000..c98b4fabb --- /dev/null +++ b/iguana/coins/revs_osx @@ -0,0 +1,3 @@ +/Applications/komodoOSX.app/Contents/komodod -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 & +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"REVS.conf\",\"path\":\"/${HOME#"/"}/Library/Application\ Support/Komodo/REVS\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"REVS\",\"name\":\"REVS\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"905c3498\",\"p2p\":10195,\"rpc\":10196,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/shark_7776 b/iguana/coins/shark_7776 new file mode 100755 index 000000000..d1a7bc525 --- /dev/null +++ b/iguana/coins/shark_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SHARK.conf\",\"path\":\"${HOME#"/"}/.komodo/SHARK\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SHARK\",\"name\":\"SHARK\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"54a5e30c\",\"p2p\":14103,\"rpc\":14104,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" + diff --git a/iguana/coins/supernet_7776 b/iguana/coins/supernet_7776 new file mode 100755 index 000000000..21fe40195 --- /dev/null +++ b/iguana/coins/supernet_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"SUPERNET.conf\",\"path\":\"${HOME#"/"}/.komodo/SUPERNET\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"SUPERNET\",\"name\":\"SUPERNET\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"cc55d9d4\",\"p2p\":11340,\"rpc\":11341,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/wlc_7776 b/iguana/coins/wlc_7776 new file mode 100755 index 000000000..b43b7f793 --- /dev/null +++ b/iguana/coins/wlc_7776 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"WLC.conf\",\"path\":\"${HOME#"/"}/.komodo/WLC\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"WLC\",\"name\":\"WLC\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"7ec1c253\",\"p2p\":12166,\"rpc\":12167,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}" diff --git a/iguana/coins/zec b/iguana/coins/zec new file mode 100755 index 000000000..6c5f7cfae --- /dev/null +++ b/iguana/coins/zec @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"conf\":\"zcash.conf\",\"path\":\"${HOME#"/"}/.zcash\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":32,\"newcoin\":\"ZEC\",\"name\":\"Zcash\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"24e92764\",\"p2p\":8233,\"rpc\":8232,\"pubval\":184,\"p2shval\":189,\"wifval\":128,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08\",\"protover\":170002,\"genesisblock\":\"040000000000000000000000000000000000000000000000000000000000000000000000db4d7a85b768123f1dff1d4c4cece70083b2d27e117b4ac2e31d087988a5eac4000000000000000000000000000000000000000000000000000000000000000090041358ffff071f5712000000000000000000000000000000000000000000000000000000000000fd4005000a889f00854b8665cd555f4656f68179d31ccadc1b1f7fb0952726313b16941da348284d67add4686121d4e3d930160c1348d8191c25f12b267a6a9c131b5031cbf8af1f79c9d513076a216ec87ed045fa966e01214ed83ca02dc1797270a454720d3206ac7d931a0a680c5c5e099057592570ca9bdf6058343958b31901fce1a15a4f38fd347750912e14004c73dfe588b903b6c03166582eeaf30529b14072a7b3079e3a684601b9b3024054201f7440b0ee9eb1a7120ff43f713735494aa27b1f8bab60d7f398bca14f6abb2adbf29b04099121438a7974b078a11635b594e9170f1086140b4173822dd697894483e1c6b4e8b8dcd5cb12ca4903bc61e108871d4d915a9093c18ac9b02b6716ce1013ca2c1174e319c1a570215bc9ab5f7564765f7be20524dc3fdf8aa356fd94d445e05ab165ad8bb4a0db096c097618c81098f91443c719416d39837af6de85015dca0de89462b1d8386758b2cf8a99e00953b308032ae44c35e05eb71842922eb69797f68813b59caf266cb6c213569ae3280505421a7e3a0a37fdf8e2ea354fc5422816655394a9454bac542a9298f176e211020d63dee6852c40de02267e2fc9d5e1ff2ad9309506f02a1a71a0501b16d0d36f70cdfd8de78116c0c506ee0b8ddfdeb561acadf31746b5a9dd32c21930884397fb1682164cb565cc14e089d66635a32618f7eb05fe05082b8a3fae620571660a6b89886eac53dec109d7cbb6930ca698a168f301a950be152da1be2b9e07516995e20baceebecb5579d7cdbc16d09f3a50cb3c7dffe33f26686d4ff3f8946ee6475e98cf7b3cf9062b6966e838f865ff3de5fb064a37a21da7bb8dfd2501a29e184f207caaba364f36f2329a77515dcb710e29ffbf73e2bbd773fab1f9a6b005567affff605c132e4e4dd69f36bd201005458cfbd2c658701eb2a700251cefd886b1e674ae816d3f719bac64be649c172ba27a4fd55947d95d53ba4cbc73de97b8af5ed4840b659370c556e7376457f51e5ebb66018849923db82c1c9a819f173cccdb8f3324b239609a300018d0fb094adf5bd7cbb3834c69e6d0b3798065c525b20f040e965e1a161af78ff7561cd874f5f1b75aa0bc77f720589e1b810f831eac5073e6dd46d00a2793f70f7427f0f798f2f53a67e615e65d356e66fe40609a958a05edb4c175bcc383ea0530e67ddbe479a898943c6e3074c6fcc252d6014de3a3d292b03f0d88d312fe221be7be7e3c59d07fa0f2f4029e364f1f355c5d01fa53770d0cd76d82bf7e60f6903bc1beb772e6fde4a70be51d9c7e03c8d6d8dfb361a234ba47c470fe630820bbd920715621b9fbedb49fcee165ead0875e6c2b1af16f50b5d6140cc981122fcbcf7c5a4e3772b3661b628e08380abc545957e59f634705b1bbde2f0b4e055a5ec5676d859be77e20962b645e051a880fddb0180b4555789e1f9344a436a84dc5579e2553f1e5fb0a599c137be36cabbed0319831fea3fddf94ddc7971e4bcf02cdc93294a9aab3e3b13e3b058235b4f4ec06ba4ceaa49d675b4ba80716f3bc6976b1fbf9c8bf1f3e3a4dc1cd83ef9cf816667fb94f1e923ff63fef072e6a19321e4812f96cb0ffa864da50ad74deb76917a336f31dce03ed5f0303aad5e6a83634f9fcc371096f8288b8f02ddded5ff1bb9d49331e4a84dbe1543164438fde9ad71dab024779dcdde0b6602b5ae0a6265c14b94edd83b37403f4b78fcd2ed555b596402c28ee81d87a909c4e8722b30c71ecdd861b05f61f8b1231795c76adba2fdefa451b283a5d527955b9f3de1b9828e7b2e74123dd47062ddcc09b05e7fa13cb2212a6fdbc65d7e852cec463ec6fd929f5b8483cf3052113b13dac91b69f49d1b7d1aec01c4a68e41ce157\",\"debug\":0}" diff --git a/iguana/confs/ANC_peers.txt b/iguana/confs/ANC_peers.txt new file mode 100644 index 000000000..4a24c7b91 --- /dev/null +++ b/iguana/confs/ANC_peers.txt @@ -0,0 +1,24 @@ +84.73.4.183 +98.115.147.74 +192.241.187.222 +159.203.208.102 +85.25.44.119 +178.32.251.114 +109.155.227.178 +146.0.32.101 +108.61.10.90 +198.27.82.134 +80.74.157.31 +192.241.183.16 +164.132.25.194 +128.199.47.200 +173.255.197.64 +46.101.136.168 +207.192.70.250 +54.201.183.106 +211.149.175.37 +128.199.192.241 +216.146.143.177 +82.164.213.27 +107.170.167.218 +195.154.223.134 diff --git a/iguana/confs/BLK_peers.txt b/iguana/confs/BLK_peers.txt new file mode 100644 index 000000000..ee2785e49 --- /dev/null +++ b/iguana/confs/BLK_peers.txt @@ -0,0 +1,9 @@ +188.112.70.36 +1.34.180.245 +104.131.248.191 +104.174.97.3 +104.204.109.11 +106.68.86.178 +108.174.171.46 +108.219.100.78 +112.198.64.34 diff --git a/iguana/confs/BTCD.utxoaddrs.1486500 b/iguana/confs/BTCD.utxoaddrs.1486500 new file mode 100644 index 000000000..f269605bf Binary files /dev/null and b/iguana/confs/BTCD.utxoaddrs.1486500 differ diff --git a/iguana/confs/BTCD_hdrs.txt b/iguana/confs/BTCD_hdrs.txt index f73225519..20e1e85ee 100644 --- a/iguana/confs/BTCD_hdrs.txt +++ b/iguana/confs/BTCD_hdrs.txt @@ -1,4 +1,4 @@ -1251510 +1451505 0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac 000000000c4682089c916de89eb080a877566494d4009c0089baf35fe94de22f 500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e 0000000002b868fe717dc60b8d146de4d9aecf779b7314224908566e01847769 1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 0000000000001e7c6d28962a03b3d75ffa1355ecc6d3021893b2727a1ccfc669 @@ -2334,15 +2334,15 @@ 1166000 a0fac4b306c379866b4c01b909610b9e7e1f2ca794fb5c590aaa2c83a666effc 4b67f68a8adf5d50d262ceb7a95cd82ebf00065db0ab242f696e0a082b7f8151 fa111449ad59977279759470503b67df2cdbea065862f5d3b6ca61b62a34fe1b 1166500 2c79c6b923aec6eefa4951ed06fac160d02c82caaa0a1c11bd49fd6ff59d8ead ec655e3e7f55442ae0e5282b8f91a6d2a88ee19668e0df9d92eed382eba50069 7e597d5b821b7140cd3c10445409fc1f11b4f209df0b7f394c31d7b7f9f954c8 1167000 f20f0ba0c20fab2a4990bb6d31a736d1f444457af660cdc05d133228e8d15047 2166fd932a979f00318f6616c3c2184055c29c214d49a68454be63731fb380d8 63c980d73fad3a22262d71955940980544682a37c1939e259463faae424f1b6d -1167500 a401abd7e22dd4c5857bbecffbbdb575ef2f3b1cbeaccc1ff90aa3cb7ba4d03e cd245140f4ed7ca46bd7dc30295cce6db884a18f06a644408b3122f53d85eb7b 20c8c957ce0424d4a03c4ce971c2e1bde4732d10fe316b1dcf52e3683ea914fd -1168000 169f9da4c456d381a672847adc804eaaa695bc4c50a4b536ee753bab29ed0224 8fca11c8318d16f1364d2663f6cdaaa47a92d008daa7519846f22a68fbff6d44 e66b572b3c4b692d4c2ac327643cd16fd00a7a4ecb91fa4bd2e97d23030301ec +1167500 a401abd7e22dd4c5857bbecffbbdb575ef2f3b1cbeaccc1ff90aa3cb7ba4d03e 0fad862612c685191b30b3116b3bdae78404f3cb3850f4cde5f13f7ec0db7cb5 20c8c957ce0424d4a03c4ce971c2e1bde4732d10fe316b1dcf52e3683ea914fd +1168000 169f9da4c456d381a672847adc804eaaa695bc4c50a4b536ee753bab29ed0224 952e85e8eadb2831ac7a843af4f9e11479ddb10e353bd596c25e4c10fcd6773c e66b572b3c4b692d4c2ac327643cd16fd00a7a4ecb91fa4bd2e97d23030301ec 1168500 54757c8dd834113d79ebeb28a73535972d005c345e33d34d9b9f0d1b5092d71b 3fd4ecda5d6a11063d66ce9a849038ff370c6244d14917ec8c87b2cc3e8e9142 2b9f660ccf344bc479ae9cb412b7f1af7d18e08d585f10d4eb41f77ec366e438 1169000 0408e4fe84a28338f1ac1f36fd6915bcfe05dd3a08ec6c1248c5df58542dff6d bf97ed6cc13fdb2e9817a702a24b264aaf746c67e7a7bf077376dc08ee1ab9dd 1103ca26dab6666385aa27a932c63487da46a44a6c13ee27804a22bb78d9bedf 1169500 e8e952c72e3b1730dcfcc4d73c5c7ca6f64806b1c350cf127e09b05c5e03dffb ccb974938643549c6dbd2eb11bd60cfc7c4a977f88eb2f935ab81f111500dbbe 392391fd3ae91091d658218b2866be420097c4bfaaf209f37aa1961e3e380927 1170000 74283d0f2aad17892d0d4832778bd1f3a55879d8ddbe1314e410bac40f6a6c02 59407452382c4869286b028e35e69940a81ba9c9fff7eb427c0cb4650b18e7fb 25ec2c456054fef281ac033f1160df826f8458a5f7f24be4faf503b6ab9ca070 1170500 038c3e9a4f8af3e1f89208f1e10152279998e4c56c28ee571b64c1b1a2576b11 1c50f607d118aa4bf311d63ea309ac5fd6c023bd73937dfa60ae685684d5d0ca bca5f157ce2ba2f4b2fe57e949e84052ca934dee1d685460e7a207b1ac4f1dcd 1171000 657b4ad8cda15f1fac5b96ee4c78d30d24a202cbff03b05eb42b8a64a9fb3f85 b5ab985da7441c00c83a521cc8191c7b255e45996560aa7b5614c9a85ed10382 441326a82f1c67280dbd7d42d06c41e7f2b131c9b591b7b9f95bee52dc354bb0 -1171500 57a6596c7a9b14774681db13f91c27e8d10a2a4a3afb4932bc0e99a352d616b8 a37e46a4e94337bc220479a47c7bcbcc512f9235e06f7cb3ca4af02e2d1784c2 2971d7353bedf68e705796a109ef562fd54215bff4d23e130940de8ff28b2abc +1171500 57a6596c7a9b14774681db13f91c27e8d10a2a4a3afb4932bc0e99a352d616b8 88479e26ee3bc7057bfaaeeda3b7ffe957c16b15f1556406412d28224b76c7e0 2971d7353bedf68e705796a109ef562fd54215bff4d23e130940de8ff28b2abc 1172000 c8c332595916c25863c065b8164053b7306c9b91280395899646a89ef5c7efb9 79045e4de4c46ea93c7531b2983c6cca978a870f81e69caab499819eed84ff97 1ab7491c615a897bf0e521a4da4b85476a0a578946b53af637d95a25426ba645 1172500 de2a9b82e5b0fed78938dfb45b5d03486a9e8f918bd1d10e9a5dc3a5d2ebd375 ba34eb6149f1c2d4a8fda76bea4c0126d2ffb924554b02d46a7dfa3af7a42a95 8cf00395570c76499738996b0ad071319f08337efef9ba5cad46f908b9b495d0 1173000 ba3a9dccb5269e6c3c3b4372dd5473799a479d5f1bfec6f1495704a031cb7257 a5a363ac0a854dcf3b3d461a01bbcd7c23b527a5ff7b1bd80c2556a39b1611a9 be41baa05f09e1eecb3149a981ea9fc7772546695219c581cd96e3acdd89307d @@ -2356,7 +2356,7 @@ 1177000 6ffa6c3fdfebe30cf1a7e8ef456d706423ca7370d250108a345c921a43f6d361 e96c39acf261f3f79139e4cae812888ca292b61de0f49a6f14f724458ce941a8 0d27963c7629d5e24f8848666af214eb3753764fb839bd5b3b18b6d5c9f4b4f7 1177500 21944d33335de6e7be3eab1afed00a8840ed09059769a4cc8c95ada2b739bac7 d88e2a0c9645654dfb23354a9f0f90e41735a796e184a969ee32f38e0761f0b6 bb28cb1b9f1156ec25ba4346c69f25bb4a1a30f230199fe560394344a08ff569 1178000 8766dd180ff2d647439a5cbad9b1f79ab7e85c6c9fd748eca22f707a7544985e e250fc2eef43908fd12d91b90828486f99db25f9fa749deed0b9959c3554f667 eef4af40225d005aefb2d36e2d6b6375b78ddbc16712d82598e2e4ed351c41f9 -1178500 0bfe9b952084a9906d48fc53724099d6bc735bed7b327ef362f32eebe8c59b08 4053aa9f0b929b2d3f7475fda64edbfa8a5567c3280fe8979da8cddb43e194fc acb4f384b6d271f82cd521ba1753b687b27aced918d9e5c37e4a0a2cfd91a226 +1178500 0bfe9b952084a9906d48fc53724099d6bc735bed7b327ef362f32eebe8c59b08 cd078860ede646ae1128e84b2d909892ac34570c9b1ac0eb55aae1e804425110 acb4f384b6d271f82cd521ba1753b687b27aced918d9e5c37e4a0a2cfd91a226 1179000 9052cbdd7759a7dc740c100cfbf1f599192393b4dd166177eab203eef214fd5e a64cb29918db51c90ffca1e590956df66a3b47eead5018e56b6f894376d0f1fd 583a6a580f3062017f6a7ef8b0a51fe13b2f40659101a4bb3bd4cc3ef79c327c 1179500 2d24b0b8f56ac3c5d7016923fcbb74c9a7f2bc5cae1302edcb2a02c9ead8e285 1e8ef0170644ce900729fbf779c85a9f7c4e41913f38bedc655968799c0ec061 843a1a3ac0fb093a840dd998812c3ae7e2bd420f8e10dca85e7b153a2c99f390 1180000 5d7b2c7e019293bf5b7f4c5339aec0ce4e22fe103cb50213e8e7d3f4da3b29c7 10773667c0417cb9c8fb7028d932e840525495a92f5f0872ab2270f4dcf4c4d0 5cf1307b81e3621a6df541defdb59171a59c04a70662ad0423a8549204447215 @@ -2393,7 +2393,7 @@ 1195500 c224c284a418e9c6170393789ce17221b65b2cb4d01d78bab846023b01337c1c b2e46eb9bf71fbd3559c99029d84df9410d8ee1541662ba79303029dd46189da 6f9b3fdfcab00fc669b96bb50858ba0c41fa7922f7407da5e9683dd3adbe216e 1196000 4f5e727fd3c0c4316ede3129db86b088a9fb077fe6eb3ec9ad84f40e89ddebf0 cc941087965fca35754518a5d3eb21be92bb38882150dab8476b47cb95ac5241 274de1abc69b95db66bb8e1d0fab6cda37df4a00cb676496c08c8751e1e6b86e 1196500 8d8c392d670e068ed6621469c7a4adefabf064424208671109d94edfb0f2e203 16d66ea77ce1b52ef738ab4fa793819f09ad930124dbce9dce4e5e2c701c3d41 3879592b2b19c74ce6f54476140806a4ece95a60a6e107dc2095af40a8c308ba -1197000 1599a2fb940450bab2282542cb60c30afee5c195a4c63fad5ae4c6c2c42f74b9 f022f651ab7fcff2fbe8296d9a2f802ef70de273d05bc7c2dde74666b1ecd05c 04a77a5c3839707bb9a7f96ec74f9517c5b57dc6c4d1a5af5256bb667dec44ea +1197000 1599a2fb940450bab2282542cb60c30afee5c195a4c63fad5ae4c6c2c42f74b9 248bf18b9ef28c09806607778aed8ae2777178b4d946e00a79e70948b147955a 04a77a5c3839707bb9a7f96ec74f9517c5b57dc6c4d1a5af5256bb667dec44ea 1197500 4e570d3ec2424400ad95e0c98e9dacf5c35196d851df3eb410d5af0b58fe6f98 7cd9e67d5115385506704d38c17ae7409ba050d47cf8cdc4736adb935cc0a95a ae20af61def9617941f12b4a704115ad1a030d951db13abbc77cf9377ae3f78c 1198000 d090b0121d9b30c48647797b366e547aa147195753b6d24c9823b004a35d4f40 5f6b352ba1f84934e13d2f144c8313723fe382d05f720f25a175fc3684032e92 fb7e3b75ad79622ea55fe9503327f342125f6f51f1a6aeecb249332bd0a9443a 1198500 33ffa7f777060cb4a65edc50deade02100c9ba4b044351b7cf8483335f1f33a4 6312888eafa2beeee15eba13879b11e753d460a9b54bd14c16cfbd92fed6622a 0c80a80a15684581a2f10b63a58635ae575217b04101066ed6875e519c2cc8e3 @@ -2423,7 +2423,7 @@ 1210500 65d1e575763ab257869cf3836d24033f4dc201af30420d753da99cf756afc957 04297b9ad1a6a46395ff05e3646a0774ae926119210b7f9518a34ee451ff7876 b7a78eb78dc0de0269e85aad99f6159e0c62cf1896bbbc4d57644ee6841e66e9 1211000 63f7824e59c39582208dba5f1103259d967f57347aa09e9c11a5faeaeddfd1bc 16f8e67d3344c9dff651e1a2798f7dd1b0e99e7cbc11f5e44ec98f6880cf443c b57a7be6b38c613f08919ebe694196097ee2bea41e01401fbcb98a3904362926 1211500 d899dbddf39d3b7ffb4f7fe28de5acb406d425ca8e045d3f781add82186f937a d3e071c935166ebd9ce6c5eb2c0ef7830b6774887cca37a5f1d36a2b256a05a2 c6a78f9b427a055d4a667cb08a74bdb1ab24077de9e7992c570e96c0af7daa4f -1212000 f90c9ee5bc12c59ec108657fe98e9324f9c85aa1f9cab7204edf6730d70422c3 0150577230ba870ebb96c21f7e3ec7ae1dff39cb722ed7b48cbc60d330be744a 088ff4328e9147a7563fa07206b6171840b291d53785164da29e62623b1feeba +1212000 f90c9ee5bc12c59ec108657fe98e9324f9c85aa1f9cab7204edf6730d70422c3 76812de9f7d63b6412f310ea3814b3a4aa29e4d79b85b9d5c01f3336a0a8d75d 088ff4328e9147a7563fa07206b6171840b291d53785164da29e62623b1feeba 1212500 f8cc7adcb309ff208a7a740eceb0517c8d3b3a88c06ce005b37f17ffeb4905f2 ca2fd2e44948441520e2e9bd79528e0bfb8077ce313cea0190b229e2a8977d5b de0c8389fbf4d54b78748152d6a1b909a032a7292dcb52068fc18014d973a5ce 1213000 754d66c3a3828b61aa7e5a15c8fe95981fcc17ade1030484f91c11c8610afa8d 0a736f7cbc44dea49246af39c1db3b9f98a482f3263278ccd9d7e2c42427badd 7dfaff65e0b6b9ee50eaa81d8a30304d9f258f0da1966d390cf169bdd9cee31b 1213500 a44133bc1878ee0a11110db3b1e216a32e3c1dd7871242184906e37707c4c3a4 9a49bc0837e480d6feb51cdb641412c1fbf83ebd07aedf5f5b52bcadb0262efb 41d16e41364828cf2cb397e50f0536c53f9a165f51dbac05ff80eaf2ed63f6a7 @@ -2432,8 +2432,8 @@ 1215000 aa91d090e9109a62f7bf56969cffff445b7458ba7a5d37d333ac0f6ecf33bee7 fce092c00141d26053f0cc948b1c9e6909798b2e48a5d6c2a2234455e1260ab7 1f39cd37ed092c6703ec9a4d52d68f4193f0c09277b8a60b4bbf7e0ce0a502de 1215500 4a3cba5107b521f2fec4838c56ba42075bea7b56111407c3e1a5d29f268e39c5 d148409fb60d5fda12f14be6d10aee9d40193b64d09c2990c3cb5a457ef18cf9 bf15c48150f64d7002923b94b5cacf0ba7ebd9ec8d5e47aad52fab003e70506a 1216000 2a224b00ee3a56ee499bba718b11b688f789d44a11c42b566464204f51f2ec33 0769fbba3f55367e95375dfefa08dcab6f53c9c5e5609a0422f73d75f04a4f53 40d9e49dd70d4f1aebce07bf99ed706b3adaa207d2eab29c843e7bca0e69f9e7 -1216500 d9943902065c4b0823cd64a62d37b532c6d62d0ed1d8828927ac39089207b9ae c83f557b4e2cc04d4375f91003054dbca728cbd9626fa9e9420ecc77aeb70e6f 32fe72cc551ce71177df0895e2f384649fa4f137e4d6f7b6c93eec53d2eee53d -1217000 382d47307ca74e43ab3cf0152c65cdf01ea2348b1ea1b25113e6b5fdda458a34 835103782e04e0e8bd18c741ecd1a8238eee814973ab7ad40eebe58e2fffc100 5f1d7ac4471b7dbf2927f5a3dc7212cc025e8deb674f87559ae7bb80c81ba2c4 +1216500 d9943902065c4b0823cd64a62d37b532c6d62d0ed1d8828927ac39089207b9ae a5acc122a9f9a8969f84685d22e76d090f5c4ea7bac3fbdeb32d56535570ed7b 32fe72cc551ce71177df0895e2f384649fa4f137e4d6f7b6c93eec53d2eee53d +1217000 382d47307ca74e43ab3cf0152c65cdf01ea2348b1ea1b25113e6b5fdda458a34 38b01c4fd857554451c9e4f7481ef4dc491e230779bb1efa92f7fc6ce58955d8 5f1d7ac4471b7dbf2927f5a3dc7212cc025e8deb674f87559ae7bb80c81ba2c4 1217500 2e165b64031b2e689a8e6cf9b24f4a928d7f9de6777ce918aaaf99991562c603 84f608ddd07f0e6c7307570ad6ec5bb0b7361c779d1c18e8cb0c9e08a29cee0c 0ea9e4d3b33c19fbda78146bc486343b4717edf67573392742a697bbf34778ed 1218000 c62fb3c42177536ab92a97c2d8fc21f72ca1499aca8bc9b604d8265cd8630771 375f71108b5160a7a7990288ef3394cdcfcfcf77955f21f28368d101ba93eb66 b51ab010fef2ea591827977f896d80a4dd63cf94bded139805169c581849068f 1218500 a162e27d52028d27ace91149cd6526e41f6ac23e67378f81f51836f7326fed9d 28c6848464f675c93a357833cbd7af6fe0d1881723c9b1dfa731a7ee2c08536f 898dea8a454aa96a0931532a0eb7e181de7f83359f7433c520e4693b5fdf4948 @@ -2444,15 +2444,15 @@ 1221000 fada98b054fa44944ae7f458255ac03af0bbef0f4711e0fea4dcb3071f4af719 ff619e93f10311744a6bad4ce2add55afb6c258beb2570d825489a6901c493b4 b6ff3aa01bcdbc9e4206838490e78dc4ac9ed06171dcdbbaf7807211fb3047bf 1221500 867936e9456a796ae62e181d029e150d63ed8d7fa0b91dc96f0610101e96bb07 f283a4dd8854af5b6419c79ce98c6326283ef8b8f3295d8912c5465cb99c9b7a af190d37c2900db674adacdc741c59fbd8431bd71cc6cb70cf420f616964b083 1222000 92d956413724e3e5fc5e7386ec1f9717fb6f080203d7cd464cbc1cc46e40b1a1 d2212c160766ac9464f0f3b7433614303114af00a95d746177ce70af39b97fdf ac8bf70a3e63d097dcc407247331b10d4fe125d9b53358079b3e0ee7900af8b8 -1222500 988b9749da4643c17df869d68c4c6afc39c6427bc79eea82a2c2d23262319003 b2e29bbb854e916e259c68907d86603bea9f63c174cca8483cd6a806e0687cc1 016cda454ed0574524c3ec1cc40c5aac64f90ab0cb7599669ad04793021a48af -1223000 ba1cfd983bae07bb33f094aa313ad4e27773ab1316291ed338ec784638a17fa0 6a6e92ab4ba2174d2fa9ea9d518f1dba0d7b4b02b6f208cdcb191cc8d9743ff6 56a23b35c73f1a6a2f63530304cf2b4a7b314d8c44911337c7529a3bb72c2999 +1222500 988b9749da4643c17df869d68c4c6afc39c6427bc79eea82a2c2d23262319003 63383c371f1f25f45ec916233c94344c0030962306379ea8d9c90c925b3d7daa 016cda454ed0574524c3ec1cc40c5aac64f90ab0cb7599669ad04793021a48af +1223000 ba1cfd983bae07bb33f094aa313ad4e27773ab1316291ed338ec784638a17fa0 e65128c850a743e68dcd65aaefb16e71eae209d940250b98e390e32d6d96a281 56a23b35c73f1a6a2f63530304cf2b4a7b314d8c44911337c7529a3bb72c2999 1223500 c9d4b54460eebaebe3dac55af5a41c92b93f2cbce7dc15a6a83d0ce32624da27 a7dc5399fff2ecf6f31036f2859a8fd6dd455cba0f36cb066198d196366a07e0 38742e5537cbdede5af65f69ba51e038fd50a4861daf98eefdf2547f92d30091 1224000 9eced849f18584d868e2b2203d7c8e670ec4b3de64040d4a83107bd4f83478ac b7833aa659aced32c8af2cede17974e2034248b77e1d8234e353f25aa2ac0f58 e61b4c8274aaa6954ffa72836f4b6f2a765bf42dc4480dd60321addfaefda699 1224500 e8efa9a9da8c7457cefe2c10edbe2ea4b9d41b1db527fedbda3cd04321a5c111 e957aee3ef528beac7121c3104a2a43fa436c729322b813de1d67312680d4083 bb24fb54ae90008799f9aca682ab21eac31ae86d517e2d332c7a9ea814a61730 1225000 4e12cd3ab7e05f9e285315c668939da5701bf4fb82d36d6d3e594de1cd0900c5 eb57dc646237d51bd9a1a2f8cb8c7f9d886f4f2cecf5d357a84ed677a2f261d2 1d313c9945672934be9457c33f639259391e674f70a03af4dcaa90adaedeff33 1225500 c688db4d88ed9d2df5c2f27c6835603c51901d117b6d1b84e758ed295fa48944 9a8422e25e95aff28f97a49c8c92b710d2444263b8d2da7a0808d175c0ee4347 c11b772a420b555ac5e6b924ad5c423f163ebffb82dae741a238d989b634e52f 1226000 c4e1d256b6489e0bfba212ee15761336138eecf8979b7723efa734ee1ff26b18 1e448b947cbdefc052935c120b1f5c6ea572b9b6e57db325ef6854f6d3163c43 a7577442c1b52b71f18ec372828203737f4135d9860b9b1cd4c37817e8a241d0 -1226500 97c6e37ce3aaede301449d315b6121ad209d7c05bf1e1009e28ca4c9d9103c60 9210e0c390ee24dbac3246141271a88596a901e27e827c8ea57e3a5c7a75e4a2 6eaf28adcb51c7a25e69644a00d3aa5cfadb46b5561f47befd9dd8f469dd0373 +1226500 97c6e37ce3aaede301449d315b6121ad209d7c05bf1e1009e28ca4c9d9103c60 bc898655ff32b905aa999fd3341f0ca399cdf4aa3997be7d83f3d4dc6e4dafda 6eaf28adcb51c7a25e69644a00d3aa5cfadb46b5561f47befd9dd8f469dd0373 1227000 329572ad3b9215cd69211538c61554eccfdad3bb5d2580d7319bd4e610a178b5 f2ac70bcea88b98c36bcdd15d050ea30f4ab11690e125ea3b9edb317a05312ba c55ee0f1638c5e7164ce7f58f5a39b36fbd7800576af58591468dd72848e4e9f 1227500 a116bdc25d0d36cec3fd5feeeb19ecd338d3c9db329114bf9a97e30f08bb96e6 2d1c9941a6d1fcb265b5ce131b77f4f24b3c41005531012ed24a89a271ad25fa 2589707edbce375faa11ccad06df92ddde9e531d1ef0a3633d78151b3f9d0f0a 1228000 84f4f33c057c0e992a875e7a96f06bf7c348e70730dae4d4c92ade46c2a7e116 049ed2ddedf886363d6fd427bf42206e294ccc455ff2f83fec7c10f74cb38a5c 4970249edfa5de8eb69588783f9ec8d9b20467efb4f4924d17894fb2ff3dfdbe @@ -2461,20 +2461,20 @@ 1229500 e2eee37aa2938c02f852b9ea2bf88737f87203154bfa499db7577fd97c1cbd81 ed8ec1aa4e346b93d4f5a9016a5582df83cda6d59f71c910a778dbd8087039f6 a4dca6bda7027ce0c275b175ad2a725c65ddd4cc03f997deecac29824b1bbe19 1230000 6f65311001ece9092002e408d232b04a3958a801ce14745bbb33bc50b3d3e434 e92c307817b8555133defa5001453f674d64975f118469dac59022b47b1b2875 ef025f195d124354b0987f05b7d46a547e19cbff077dd162bd1d4cc4ebc51f2a 1230500 756a4e8628e68dd8833f1160a9438b5082b81dc62d57e2fea4c7f2ad73d4d361 3f201a9f0e46b64d4ee464133e142ec08efda7d70035e2bc87a9115578f01ca9 00419dbbd698d08b0f89b4669237468bc366a853ef0bfeb9074c29d1ed4b4f73 -1231000 c8e6f0e59ddf904a7b2d085ca6cd5b1f243b75ac09ad637ba72a91125d6211d8 2c3762cb6d023147d669b4ca877aff07b7194d6da09215863f4fe199f67198c6 9bf01e88b22df0e00bff6bda68ab7087e573c3155dd093d7461f14288455ff04 -1231500 61ef9b1c57fb9764e6bf4805a520b4fb74566e1fbb4eee699f517f62e22e64b1 acc8c1c0739411ca10405ccb0c49b403967cade11fdbf8811a8ebab9e46a6e27 2d9742b07b1a54cd422958e68b59b0cd5db43a876a5063427f138386d4a7fe2d +1231000 c8e6f0e59ddf904a7b2d085ca6cd5b1f243b75ac09ad637ba72a91125d6211d8 9643bff43c642fcf08b6cfe1b08065042e7d4ff70154aa883503257d1414470e 9bf01e88b22df0e00bff6bda68ab7087e573c3155dd093d7461f14288455ff04 +1231500 61ef9b1c57fb9764e6bf4805a520b4fb74566e1fbb4eee699f517f62e22e64b1 b2df081747be0041571a8cdb62144a08408fb8911d5967717afd3117fbd5f05f 2d9742b07b1a54cd422958e68b59b0cd5db43a876a5063427f138386d4a7fe2d 1232000 391308af085a5484df59509f31a00f63833180fc69dace72a38461c8e51c0a86 f98e065e8818fd81b6b3f0a8da64ab17013dc010096e6c34ec3eb5f9fe8a3724 fa28fd3a2fc93ccc283fe42d924fc7492ec45cffec7d3eef82ea249e8a1aa855 1232500 3f8da017a3767553a874c1f2f5596700b6eebde54b1f27a119de031e94a5d70a d00e3a3b2a29c5f0f0ba83c5066cd3b0f4794a98768be0c7326fb82b17679185 994cace05d26e4ad89d275f8f45e9aa058fdccbe54d0fbbad58d87df2059089f 1233000 248b1955a1c0cf58366a949e73cd07abc509709e30a427a55e2edfff5d8c8677 88110fccf2c71332b30536569a6fc46fe183d3a2847ee627213ef66bbf0bcdd8 ccc0873dcdf1b09702ed7b3e6ffb8d00e9afa59d77e4f7f86ae0566879565b18 -1233500 381e2949e83693efbb0e432f83034aa5ef6cd569428a3f5dc0ea46721d58a571 3e7cd9eb6c797ee4f40837dc8a437b417036a2ee6f6d8d0eb8cdb9d0143bbe51 c2a8f947967184ebb6a31b47961bd4f37252e5ae81380562dcc6165a85fc9a49 +1233500 381e2949e83693efbb0e432f83034aa5ef6cd569428a3f5dc0ea46721d58a571 5e4fc7b3c7d55d2f0f236af9b89acc1edaf638427adbaf959d72297623ba683c c2a8f947967184ebb6a31b47961bd4f37252e5ae81380562dcc6165a85fc9a49 1234000 cb6e218e6b06db72e9ebd1a779c6fbda5c8967d527731d8e5ab48676aa9a1d97 27d02fde617293d42a4de35098f148deefd85340bb2b038a2ba17602eb26fa41 db87890c8ffa7bbf7c093729078598d598ad11b73a393bae34836641a393ba5b 1234500 5b0df15f60febb52c49aba4936bf83f9bdd2654d4ff883ae326c081fa7b3fa8c 802c5a78bd41f37f08ed7c395023a4661d743d59f98c6b7afeb231716fad6829 3b035a4d24d0cbdf71c38dfd81423d32d8cbfcea642da34d64aed0855044824d 1235000 48f8a254d98836c4d8559df0ff42f13c8b62ea04052381bf411cf47b99900884 d59adf1c51d0d1f8b261320e990593686f75c1f8f2f405758179b058946873a2 d83461b796e705769281bb9e53d7b7c951f9073a399cde0c567aa9916456a534 -1235500 eb8ac12b006d0cfc692173d0a970260435c7c7ac1e67bc54807345a13f7557fe 1e716e5508018cddde941f3079be2608509a9e319684ef8144245f613ff46713 6db77cbcf3e70b684552735f0ba034057ca13ad7cfcb8d698eb9e4f5a188060c -1236000 524ce04d135aa08543baa6052549f6736395eda2ab3b5d8fe5fab430c014562a f1ad0c14cb9cdea0f4cd5847d1c256cae712d24621a29afec0f54677c1510706 d2371119849dec5a03d380b18a65b43981676db7a59ab13f989991317cc0ec12 -1236500 88275a75fc986491ce9dd6d2cb83243060e61d6c4e81ebe7e7c7643fb8bab0f1 2a73a779cade5defd59863657468f9985adabf08572a23192060672b14e2de75 4e2f3e795940126c02e8a0479561df998e82ae5ac4839f07f28d130e9a32adbf +1235500 eb8ac12b006d0cfc692173d0a970260435c7c7ac1e67bc54807345a13f7557fe 43c9ff4e1ead86165b6f3976cf5904e5af8fe53cc313c11cfcea03714d3fbe6a 6db77cbcf3e70b684552735f0ba034057ca13ad7cfcb8d698eb9e4f5a188060c +1236000 524ce04d135aa08543baa6052549f6736395eda2ab3b5d8fe5fab430c014562a 6a0498d4a62c53e08fa49b0749b75848bf0ba3d3cfa9b6d11b082e56e8d1d605 d2371119849dec5a03d380b18a65b43981676db7a59ab13f989991317cc0ec12 +1236500 88275a75fc986491ce9dd6d2cb83243060e61d6c4e81ebe7e7c7643fb8bab0f1 eb0fa72267b5a91ab4b257bb7d2913630e230bf9fca0bc7a207cb716c518e44c 4e2f3e795940126c02e8a0479561df998e82ae5ac4839f07f28d130e9a32adbf 1237000 4b99f3d475c781dc2caac67ffab7c53d84dbeff79678922694955a9854590018 554600aac19287681afe0e9765da07a02f1a1aa493dfd43addd9f31edb78e875 e60302e3377c7fc2b9109912f015bbe23b4b2ac8ad628c7d6e3837ac71f7b1a5 -1237500 73c09a49ed9f47f700d4554cd0a94c1b01b802a3cb3c61946c74d40a443540ff 1775952f2d8dc63bcc08ea478fd4714838a31f7f683a8b83d5d26435b8b3b6c3 59f24ceb689173661dfaa9bf80b396831d5e7dcde15bf806ed7160f75a988274 +1237500 73c09a49ed9f47f700d4554cd0a94c1b01b802a3cb3c61946c74d40a443540ff e1ad250e45509a15694363cf3dcf684d69ec8ce27538720f20171d4a02400b50 59f24ceb689173661dfaa9bf80b396831d5e7dcde15bf806ed7160f75a988274 1238000 29489c531b3419cea99dddefb9b19111f5baa184f287ebddb3e760a2663014d1 dce39dcb5a1a2d072fc999d3f662bcfb16685cb8922386cccba187b68b6d5947 32dcdcfc9c0d815a79435b769a35954dc71df347a2ac1a810929f765c39218bc 1238500 c0555685b80e5d5d0f53434a8ae44eadc953dced274ceadc80de36c44078283f 16dbb1b2bbd5d13aee22743ed27c7dc4dbf1dbb221cb45325d188889d6101dd8 c44cb9916bdb7e6c7dfa417da3be72bd5987cf345024ebfa68402bf3f3994189 1239000 a3f94a2821165fb910806ff75928c5255a4358b5062288571e00e6646abc5203 175a8f872f777325f2444b94ccd55602b3bd8204733f86af40713fb0a0474106 c637a21fdda667d21d172bdeedd54fe7f09095a015229dc6854eb37d917da596 @@ -2502,4 +2502,403 @@ 1250000 ff909ef870867e5408ec24ec40a290802f79bea220c8f4a92db22965fcd4f626 03e5b1fcdc2862ced4fbac3aaa81d1e0085c14d6f6d06c6ae592f74afaa16f34 c4f52d30fd52f73e6c5a8e27d3727b17887edddc5400dfb9ca1cce4703e3809a 1250500 8f0c2debaa498a5f78b8b247d1867ef6ade586bdfa823596d09f72abb489a91c ebbc2c14544a97d0bd12993dde913e52f2ef78450c1ce0fa2ca17274b6850836 de78b1c377adec4d78d5e4875569e052cc1d4eb959149a28783d3a14e05a365e 1251000 e484a8dae7eb5135538bf13009824a60f2e01446f7eccd39d7b6ba4ab7c02f6e 832e2c77cc85a51df16361177033632ca54768944daf778522cfec04a1968805 9d3db1d547f74210714713bf27f88dded8e2ac50a618afe41220ac606fecbf7a -1251500 d39df71c033cc3435949073db5f0dfdcc0665a7cb4f948704c30a36198d4354f +1251500 d39df71c033cc3435949073db5f0dfdcc0665a7cb4f948704c30a36198d4354f 6a635908c166d3caf33af6623f5653dd7a3a4139a0db2395634326fecd5db79c d63c2672584eea742c19e89c2e355a1102051a4494c76ce8be9590813d2f9fd5 +1252000 ff536638f8d7f8cce1ac36b65a6f64dd4223d06a8969d6f6f64febd4d8f4befb 187604f03a82305b18747acd7c90d12648f5a37f045e326b657afaf4224f9d98 25ec47454fde992b5ac1e02e2c9d34c3d825946b9dc7e0a5c2ea71f96ff0499d +1252500 7658e586ed7df96fc8e00fea09f92a693a09c7d335c5a55454f3ce2339536225 2d0b4cab008310e0a67f36158c504ae840169b751a852aaffdb1c1672ad17bb3 81bdeb301eb2e6f4e06affd7c5bcb3f22918ed9d11c310b634f77d738b83ef79 +1253000 bfe9a15bfaae2127653f9a072b7a3a9ee018c11077a7d7526bb10560c2cbb53c fe37841e2be751fd9648b697d20d7b5c3443a3ab39c2f913bab716e6bc91ab5f df64f68f75427ee2003331955ee1a0827b3b344445f577aded9614b48c8ab5a5 +1253500 54621a5564053c3d3c3453d26ef0135bc1fdbb4b09021c5c33b7d85768e0bf31 e534ee517a9e71318bc9aaa5027b2957b6259efa66fd42096f8d6372567b876c 83a7dab72690b7fd940713f271903f7bac10f3bf077b0e6dcef9701e56f47ab1 +1254000 e6d1922c5d41fe5427db84660db3f4182c69ef901ff569fe947118f2825501f7 7a1746032319ad8c92c7eacbf3a650d1f042d51c811eebf5a416b0b6dc249148 5525f731e53e110f43c70a42abf78f5166a800d8ef0821dff2b8e706f994b05a +1254500 fab487c24234505c8c8f7e1cf2dacba1a900a9d7811f9f59e43e1a7a18c64473 d8cbe61a2e9a9b2fa09620b37f62d9ace603e22072ab453da531f97df482137f a1f29b818a6c6a1be19dde40773903a794e6c2fbed8dc133e3f8106b4807a3dd +1255000 2b2763d4fed34ea05261387b94fcae12ce56b3769588f2f49bdbf05ae8cc64ae a827b0415a46a3b9a936352b43c32acf85b613f4d0cbf1d951fe1be18bbef819 f99426d0923bc2c972ac884261fe45c16610b8ab844e4db4c536a4b67b5748e8 +1255500 da061eadf21c010d1390f8658a679293592c0ba5a5c66d4e5be8e10534304bec 59700e24b9b859bca6543abeb81bc64bcf219ae2787b92bdac617f57cacacfa3 151234c7997bc8682241978fb74052cb79bea8371f20055982e45b5fd62f3ff2 +1256000 c58a7fe56facd3e1ead7304cbe4c0cd9c9855a5edbce2383ecc554f9ea8f2e46 d17fa10880ecdb2bec979b16b760f9aad490f6c985133dd26900f92d8a17a1ee 22c14c88a589109dea128ddcb4d27e650bdfdb75434d51a979b7e0fecc7173f9 +1256500 e092fb1e2060e4bea4c6125245089220a7a6b48ad5c129a91d2d95e8fd34ca70 480fad310a88d8715313cc62c5724d786004e5b041daa8276c5d4948c4ba90f6 38e6b6dd573466bb4a147ccdf26a022ff750e3d0adb847b87b1eb54b074ba3f8 +1257000 bf539bfb1eca8f36f36e5fb821bcf78e9c5890c9bc490541f3012952b8f86125 5d95c9140a50bc2cce9de1965f0a071f63f377a9dc5ea3e35886045824212ff9 d715e23670a3a4bc72654be1a716df874bbfa61f053b9c8fcf76dc7a989a6fe4 +1257500 f44dd8dface0150c62c461b1ceadeb51ce2004caafbc4fef9f7e29175cec0442 8f59e207c888b79b3937e6d86cda3d271b755af290cd67b84623847ba8a4b1b4 f56de880992d59006c76fb6575599460a3cc7ed1e623528d4ffa5c1a58143a8d +1258000 cb6cce5ca0c669ef304d5e236eb8ca7bd5c340bcb33f469c8888595ead0037c1 4f014015e8549cf6ba7bcb1583f0dd758f456cf8dbad0d23067d61ac89746649 a7cb39492cbab14ea097c62c47a6301454d8d8673011cc23aaf9774aa6bbb97b +1258500 5fc18d3aa7a6ee374f73d3c2eab53dce9348015cefed3cce9c80577003312a14 bae86b9cff37f003d1483b5c13a6a1f7c8ae3d1e3df71f0706ba40abaa6866af fe16cc9840c10195bccbd7ab5279a61f58c4581e320d10f7a013fc17874bdaab +1259000 fa80a9bb10191b19d85e8719edb1fa72e47d3dce38fd3f46a19206c4a588fc39 d75ded4868c1cb6899e08ca1665febff4d2064ce9a0e2829f30d3ed1b0cdf3a7 17493055bfe1b927937afaa9695c2dbc309cea3fcec846134d02452403908fee +1259500 ee2e7f98e80b3a1ad13b83d1451fa0a2c14ec79b919457e399598c2b5ea4232d 670a0ffbc4369d6db1fc09ccb771fcd8a522cb2a4eafe45fc54a6d714e6ec4b8 4172cb25e40679f04e304ccbe391990fe8c499c742c161dd6b81fc13f7b7e0ff +1260000 b9f897897344dff04b69437c82d2e8ed7fb33138f1c986199abf2bf9dfb2e522 da2d970ab83aa94031ac3ea434a4eed07cc3f4c1b18805b290506980406592a8 06001c15b92d41a1731598f70f614c9526c0bfdbbcb652194c317b80b96ad8a5 +1260500 e3cef70b0e598426ca78f8ec7bfc327f60604c26cc600d0bce48426fc2946016 3d7e42cb25d348b579bbc4442478b59a8546fba105b06acef26e4fcbc9d8377e 3a5d6f868759505e83290c567690d6d87f44fdb73afb64f191ce94e47e684e6f +1261000 9443d63a89847cffc74318c290e3f87138cc88036784c30b48793c2a5f6c9218 b1b83731e4c67fc8f472881f2b2bcbc29875c57fa0a130be65e7e33b7b8511ff 056aa8f7598212bce414a3a6a076ab722847c41169b640efc62477737a50b6ed +1261500 7babf7d11087d87c3683058eee9503e4ea41b91bdf3509a5132372ab7125178a 0fc234c5928abe54bb6b12aa3f033d380d2db44174d832f53260547e9c9e072d 97ca0cb26141b0cd7cea1383c2b7ee512c2bb4b8052ed1eea710a38e1ebb9409 +1262000 67f9f917d49c6ba84183791ab7b56889b349dde7a1745001d011fa5827bfdbd2 65eb240a9878fe26fca01678bad9e92d24b572db7cda511f121226ae5f4bd065 5c439ea8b47d73906eca78e9392560614e1d15c16436bc562fa5d5cd12c92613 +1262500 8a1cc98ca400fe611f7e620e8648602ce22d333a8159f22f2497e00c3722e9f8 1f5020780af98dbed16ede13f9904a89f3960a7c881afedec23a700ec9fa3463 be09717e36d77eb3e8cd38a61c86447319811fe5b2ddc41fe82c7ef1ee2096e1 +1263000 55a8e34e3eeff1106fe3cdf12c1d44bf5de872477f5a8865c76996e36764f87e b2d872a076739d50f465345fe2799893e97eb15affd70741a7a3d3db6133e709 28f7e07c950049c73a85f1e67c37fba655bf8c511f9b000e5d472160c2e2a542 +1263500 3e2ab5f78b443f66e459c642f93d98e2b95fce2d27c7a4d39020f79865cae4c1 a0365ca0ad690d08bb075c7a33057e091ecf0bec936f3558196245024f053519 f0a960b82c0283271c38bc0614f0cd10bd6bec28afc2cafadebd7309ff35b1cb +1264000 012540d25436c7713348010a3e444934425c28c53fb7c3a0986f73d2782561fa 004442787bc8f9e55c854913e2572913397baa9e06fedaacff5e0fd5b1253467 b6dfc77fda7bde9351d150c28b1dfd30ad08119b2e8ba4521f312e2a1663a4c7 +1264500 bd8186b47cd23bbe3cdfb71e7347a0d2291ed697090d92d94681d168eb17bce5 a2627ddcc0b79311eb6c4fbb979883a57bee5ce66b27079ee9345dc564a97d74 555a546eacb99ffa4b4a0634739a5f55176d31fd194598a801b92ddce87327a1 +1265000 dc6f4c1b94e3c7fd674f285bfccb376d816b7b9d25639442888c90417c6e1928 b8eac66eb748d10262da557855712118ef39ce59cabdb301c6bbba7dc85fb029 58803ea037bbdfcb26040bd14d176df795b2238b1a75f3819548b3890d5685ab +1265500 cc65848c358b799451503a3c57fd8618e27a1a1d1e9af32cbf33ae4f48d90a25 19b5b42b15691677fe764058e57fe87577aae10d89a3d293045383faaf22e76b 780a43c5a21945f6a95796eb3ae0b9ca82d07d90efb8196b848ca4e0999283e7 +1266000 f69c6da50eb22f5946f080c1b73eb8f84d2770945deba271f9dde36047cc9643 3de5cf725b49edff7aef2ffa9ddd1e7b5664d8b338092b126baebf26d2af9787 c7768453c6cf0fb612236b79a19c9aeb8abbb967090bd8b2e0e031b2b5865dc5 +1266500 8091893e7baa0a88b9300f71616afa17dc5b9b0a5eca5367b4a69baf985b1ac8 d02bbf77beb68fd0ae78d670aeca4ed42c4f60bf34be33c827a9cc7dac7b3122 340c352d09dc30eff28f85ae5d1fb18f14aac32055b06369ecc89019cee7cc0b +1267000 128f33161f9bc0e2c83fbee3cfb1c2fa50ccb383053d09306af0547ed9b68505 a66be448d6c66756535e0ef764429a9fac0478101d17e05289741801e2c2ee03 169041ca942e04e3aa28d626544f519adc2be4690c6aa08ab0928a5e5c67448f +1267500 31a9129736b2c3b254d11ca449fb0eaaffced86d9a48cdc39a884ca6b06f255f a4698e69577f70436ff7e0a35fb2585bc4fa1add1972bc891cddd2277ca20348 7438112570e3522daf7286af5aa53e8bf7ffe5c1625d3cce3b45f9fc579c89de +1268000 16c0c54660fabda9e221fdcd808b55d50276ce9d7d871ade48ec03fb00885f8f a6b879ad3a1e39b77530d98d41a6b4c7b9975e2edf28e1a8548625096429a863 a0ff752370334aea4a585bf357e49c7003c7143b08fe7bd6ebbf27bcf1efd3f6 +1268500 785311a0eca2b874f5bb33c7a89dcd1f070687c83097a3d0e19fc321794b2973 16daaf3f6dd6f9297e476c1937f5a6b94a34f6c0f61e632a721589d41dcca399 725bb8b8ecde7acd94587f99aa26e0437aa2adae8708173139b7531893430803 +1269000 27c720ef7d52372b85a5b9c00dcf65093d4f1e36f1eaf6d60396669475269188 ce3578d69e986a47bd79f4f6ea1af7faeed33b524968a2daf0c46cbe2d7ab897 68a147f7750ce84596b0a924b9d1be5e4d38bfa7b4db35bbd2ea5c4e0f2d0d80 +1269500 ab31f7ec6924dba82608d0090da6cf1082847e4d0e45afb860c6438e4e192dd9 663524bb675195f8be51daaaed5719e708ae88417ef8ac17b17d8012d0790862 f899334618382fee4f71a82dde3f2b19efadffe200616de3add2a59233b86968 +1270000 047cb08100d236280b31144337c8099e728ddd05f1d7f88ce1ac18f29171c276 5165759c24f5324535815114fb1a4624a80e727cf51a8423f656a332805e35f4 69bde7b7be62447e487a37a550002b1f5e65c936f1c619f816205c42c6f30c4b +1270500 e5476f3643be6062c57e6d106cec58735f5e9634240057116f69c51c48cdd7df cdf1c3a1616b92af6dee00860e080f993816d0853c8b566bcb9cf39fa9f841d2 b0379e835b76365f46d60033d0f38e4be68517375a8e20e38c4d893151ad47d9 +1271000 bc9d66c3a41ec1563d87a039dc160a62fa03f140b64aa201fb0e0d85196936f6 6561056eea7e542a19122f3bbb7de349f81b7958a285673261fb1aa50d19fc45 2f71eef960e939f4e0bd002354aecd03aaa7e150db63f301825cf4634a2b3097 +1271500 683fa8faac9cac93518e65747a4794bf851029955dc68f7d35013b15848bedc8 96877e23c45469226569a2c19534da7c3eacfe00fc446001c2e59032327314f7 45132f28d37713688fd6162da9da162967fdd8f127f9870b207d6a123252852e +1272000 039015360bb09f948495ff398aac0d7fad64c21647ba87172417ff5965daaa5a 9bf6c52d052bc7e8767cd0c3e82974b9e7ab395cfe420530667158f064083954 f35e325a482acc4b19cc370901c0137953bacb47bfa4350801e4c432e5df337a +1272500 10483769977f89699e290bdd63de97278c5402a84d7a6afc9da4300cbb2f5ad3 f52b3cce02c295ff33170712c0311f9a905208e33905a659475bb48c2232dd51 1b5847abd3c3fbe363cc8beb223fcad2d47e6edbdefea894fb8a6a466a608167 +1273000 5abbe45e929f9799d10f24d845a2c2bdfe92eb4badc58cdcd80a67253db03046 89c39b33025754778ae61b21ed02f00269b7e8f95b0d84d5dba24315e78017f5 f2acf3d6432d8a064a16e614d2f295bbd7f0cbc6e276eaa8911fc6ac34e60fdd +1273500 6963355dc1a4f110d432f2ec4937c9a864c097eb8f4860d8e86e0145accd7a5e 747860bcd450d1a413130ef9c0d70e9c0457286e8a42fdf8bd4bec9acc4de6c9 c2b2b6e933d2712db73a3e2783752f2e6ebf7fdd8ca098a8b1fef45585601ce3 +1274000 5f3e0cc50258520df89de7bff9b8f189e3bad9a3b56262f49eeb6c030e0c0d37 9e64e2b2c81cd3ae1678d99c25bb7d23dafe547e0fbebe7231055f2b23919d33 d2581fa580e0919d0deca17b8f5cc9b15fddd1238b6b2dfc1955bbbbfd69c429 +1274500 da872f704465d6cc09095c465849ef587002034ad2eec621f711f59aa4f5442c 285c67087a1c1b81ce26a75dc784b3bfa44d1ed3917c2ab39523baf5551df4cd d177183bcab01307731283ea7a463ef5f6e8ef9abd3879965492a708faa94ce1 +1275000 d31a4ddcafca32ed48e102811726ccf4dd0e70bf6e31ed1573e72533290338e2 7fd218c9b9c8859cd9740ff17f4405e793d900a087b44243a80141c9a4ab9f87 790cef1e25930ddc308b3af55d25c14c4165f51ee49d1ecb2c16a23965fdd22e +1275500 e8b9859c7fc85a2f449e7beb5b67c8a5a4ac9852743c258037c5b7d18c7e6775 7089285b9581c23e207655b5731972f426e3906536dd3c54fe6000bf69a47081 1a2db31610a7f4fa48368c08d23b8fde80c38c855eb2d2dcd84a850d6ffb8593 +1276000 d0938a0f2049afec1c7cdf43b5d367c005e7f1110a86ea2ab4573088fe951893 b764de4aab5446cd85df183d57b0269d720d42e39d8427ac2fa05bc971b24f46 5593a08c66a43c78dd4995c96fb2e787c9cea457f558acb8ec2347b561f0913b +1276500 b318359130123cac42618d6daf142377a50f3955dd3c2eb6bca23ed122c95cd9 5a71e9ba231a41ae838e4e1edb15bdb0cce8c278a8ee4cf3fd0e87a5649e2e3b 1f5e5701670c35765199e23d0ecaea1c2cf7264db6d239b557b64554c414c440 +1277000 30c579043d579fb723c282f54d7366e1ca7d926d2b0212da79a146f8d7eefcff 10cc0b462735bbf385786898251366abebde01aa9ff5c75747b96b5d5be5de74 d012018784a6ae276ab06f0b9cc48fb4a7b545acb42d38be0eb0f19ae976da9a +1277500 3bb84fa3412fd76df538a6ecc2764240cc5178700f333e18374d68ca55dbd8be b7e210f4d8a2fa776b541976e4ffe67b33ae77d2aa56fedd989e9a02c27f7e1d 698697a763f740bdc4f7cf1e3044c7a84cfb77cfcb25c2779f93dd00005cb8ed +1278000 48d9155ff3d4e83243191a29cfe0198827862b0848b7a9125237bb28480ba779 5cd0556aa6e4bb2f9de705d581341bb460cb3ff882223c0392ae02ee3fd88779 ac1a1cee86ec42d6dfef08e13f08e034bb5d273d810a5acb727548aca5a675c8 +1278500 d10b8cff3e5e37a480c5eca736b4e4d1b707b2ed9d44ba4fe4da8ef17f94ec05 d52a09dd904985a347a4ee0957a1c10f92d11323b0f1e63c604d4263aa73bebb d7462919c815ced10749fb5484e6462ee3e763aaca0120748cd013242c80ac3b +1279000 65adc4b476e699248abbf1a79a032eaca65a62018c6fb410a3b081b50e2119f3 e5b4bdd0b64145f87a36aaecbd4adeddb304f3811c99249b41ccaa61aecdb63a 537297de7b81d984b28effe3aaad242c613dec3e33019d53499b94c33f621214 +1279500 7477ca04f254d3dfc24b5d939bd9ffac2d82fc95df2de2102c979fc74c0ad11c f5b195948767156ed2dbca0911e56d96fd2154d6f00b24e6df7e60cebaefdc66 bacae9d41d64289ccf9bd44bd02f4313c9ba42edc23801fdc648d739b9dc534a +1280000 c1f9c7eae3832cfb9a173e2b3d127b318fd9c0ad4e7f7166cb02d45fa3ffb0cc 49296641f1fc718614a5a9fafc86fd9028b575022bada11f89a6b27706f8d3ea fd52322c2ee1d3621084caac172d0fc7a75e53869d75198e3efc2d869665f282 +1280500 8d750e9deb9e57ce2a7a4e896594cdf8e1dea273a15e68919a2f3224dbf97d0f 5dec7ca354f5cd8959829830e6cea8b8618d364bf8e0552df0e68f2820ba7437 74f2a4ea67ac6383799aeb14eab12814e291bef087296461c65e5fc062a955fa +1281000 33f4f1b24dcb9f14a2e0e23709437d08d200fa37d9f3e876e038873c74134cd4 68179c760d4c48863244ce5fe6395f89cfd49a28853fd39cf3509149ad4ae1a1 81e405df4a3c3416b476ff1d1d4bee7fdb8bd957c773bf2d2cf7a1a6c4dc116b +1281500 3e5656fde2e644c01052ce8c0ac4825e1aeb02325de493366a345aae44c9b595 ea8a070d45f666477dbe9bf61b1e2bfa4abcb98484df696fddde5e3e9cc6b2b0 507b84013d2b60d24e96ef587f60fd6ae4e1068e1a712860cd0668b9e0c6d463 +1282000 460dc5a8b00f670a71a6a810916e85394638898eec053c2c29f71f1b8106c260 1ec4300fc8c5b3ee0fa37da8175eea93aff328294f67ade579f5841d90b6de60 59aee7ec52f1f420543f0015e0a3f4751cb633ac20e01e0d8e9bc5d4acb55b15 +1282500 53ca6a167b471af842c2bdbce872fbef28c0929645493f443f1ffa132b8ef74e 6f47f28baf258a131365e86ce4aea0a0ed6f8ff724effc39a6d6e9ecdd37469e 493917b99595fada5561f1fb2ec0efa7e24f2db194e42514d75b3a45d8a2636d +1283000 ef26b129d493fb802fe635d458049a2f111aef0e2ad1301d014d5ac852c8017c 010b034dafccba6d4ecb8cc6b00045a3a15f641c6a5435e67b34a58eee3031cd 4f44bae6dded24a72e8cf6346c3080bd050596c85d895daecc2223b8612253ed +1283500 909285e4f9c7027f23527957968bcdf63e1b808c978d8fa77aa31630749aad91 283247be02994f4f902ce749b431d94abaa8bee68190a98168efcaa7c07ce5fc 700a7723f0290335db92346681c67125133271e165bb1dd5371da9b66098fb75 +1284000 076257928b85090d0ddb6990b1d407989bff6a40bd01fa44055aec204d93928c 92753e55543543c1be66988e74806a08dbaea8c54263dbfd80473db9ec8aea95 1eda23256e68c54b26322745da4f209c00ff2f146c34f148563002714f12b84c +1284500 5c21a60192ce74b58394dfe188e8b3bcf9cb86b8e71424f0a447b11d82fb7d2f 3a7cfaeb0ea7162993fc607af16989ba8d27f1b89b1f5a5be5312b87dbc35cdb 6a1ac2fdf33bf732648facc31e64ffa9c7415de9ae28e8c699ac41b93f29880d +1285000 23a194e22d5302e4f2feaa1d1b1906e91f8c7808075c55f0a8fc2f5ee6617df2 9b9849c2152e8f8467970090e2adf6a52e22a2abb255bfe8d3c9d17673555bc1 d59bf5def0f1ca0fb97dc1d368c3c5175b847a4c507630452a69dd38661dda89 +1285500 47d91223c2513842f9833d26630079872e58b3c29ab1c2860704513ff817a017 4c4befed95e81a843b315466a3c459b61de781f68a4eb3e545a1168779f84fc2 1c4f2e61bde40eddbc29137cf4aefeca2b1445dbed4b642fa778dd481d70a7f9 +1286000 d68322938435a8915aaa0a1755c5ef11294bac81d64a76bc576424b373079ae1 010ae35ee9093052277dcba8a3456effe7a0eccbe26a32a8e3dbe41df5b02409 72ef60d505eeeb89e538c243b860d03597bbd75e972e698f1a604d4523cc20c3 +1286500 b68cca2dcb4aed574ecfd888f2d87711b3939b05ab5798c5671395b6b032a90d a4037221fe0b9fe5c4611d77d50c661d2efc4038d983e17c463236ca0412896b 23910f32c4f9ed70129db37cdcd238c217b255c806cacacf196e3524f8b37850 +1287000 20df89c8172f75ebf33e232d4b3ad8b4e81039a413952c625b8e8d661ec3d0ff 8c488d6d7f4bdbac9fc46816f60af17f6192c0af223ea293c8ce6f5443defc0f 23a71e064d939c75322e060ef79ca80ed814b78a81fc411ddb831d7f30c869e7 +1287500 ba6383af803394cf08e1cd1104707c48abfa7c12079da59d8998f93cd3acf79c 106ff3286b6b0bdc1db8b9d99adb149549277874bed76801c2bb7971dae9d38b 6dffd66cd2b09cff26e69109a163053215a62f5fabe761dcdc065453c03f3d5a +1288000 14aa18ac460dfa1e2c7d63f961b78a728ed23358291a5685cf6b913ff83c6dfc c08b9cdff419ba06b7479704401e9168eab444f5269d970662e166b50576b026 304bc518e958126f4f9ef6815d7dc801c9c88820b474f77e9ce65009ce7c0eac +1288500 7e4bd680e1b5f1f46ebe238d6d40a9e6631ff0edd83d6ef740928e60b1682912 4248a1181d9e69e912280901a4e43eed13c926e4944c0c734e42d94f35084fde d494a6f50cb58e4a1b9f79821b869c405c64db057408e1fcc596b4549e71982f +1289000 414548e45f36896f22ad5f1a23c7a9af321c3ec785e5a817400522d32ddd8369 4b4fa31252bb8a9c8d493b021af4d23f95ed0b07ee1f4bc5e050fc301fde9706 08d3045cfb01cc60dc74dcac89b3033369276c879693dde857848f58ee026e97 +1289500 0f88ab1ab8359bb519c6c97c83f804a47cc692d75b440b149eeab343704b0947 5e6206c6266227673705b62a30dd47e4a262ca15f1932d1624422d4fa45191b8 a61cabc51c8b4b1296611938b94c2c7152292b8387c2319cf8540ae0464d1cee +1290000 590a14803906c881f2a821244c8c915c19e82cb9f10a66bd9aca03f9a15e82c7 9e7713b23cdea50014758a591d7505d4e46d3d3433b7c132d7610bf5aa874577 d22750df151945df3a67df0ce9e0cbe39191d177b19f3e1880b64b076789f773 +1290500 7e3f8559269c2326e55031cc64a7f1064a84ba9e3c05d64f3dbb0c0cb8004fce bc1402ffb523e4f9662699fd8f4012575dce33fa26dee5f43b04aac5d62e2731 19e01298956e0f1d70006cc93a49359a8f89eece634f9d3e745d699f094dbfd9 +1291000 59331a51e1155078bce69ae690d3d493c0ecf90e83550a9b7fc4ad553fe54748 a2dc677b5280c47c6a5329f6eacc531c6964aff4644d84a800290f5e6043f5e8 4fbdec3dba88001029ddf27ed6379748d1c7d0b72bef5d87bb1d4dab6c1d834d +1291500 408c40000bef4884b1a9f5447595d3032bb195b64edde0a9e2d1d2d3284cde71 93b3285e4412f2336afab88386a2a81fad4a88a09888b6fe6fba3810ff150003 72d51de88e1660f36dc602ff134184ebae354912cbb9c9d64fc5a67283d0b987 +1292000 fcb637884d11db210119514106fdba725059b56450b583e65b86a21abc3995f5 60931ed48f92c6f113e333e6b0e60ea8693f327ac646ecfec72fd08d26584471 dce81ce44896536fd646ac60decaee751b873ea9d32af538979af093bc5cf2df +1292500 a984b66998705b6ab9b9b75fc29a3cbf7426a9e6822622e87f7ce74d413c222e 39a199cb7c9df33c96314f8aa273aecdfb5ea79ae07b8d37ff56ec97778409e7 eea61fbb9d9e5f8e06f0c129cd46a55bd42cee4e33909507f1178c30d99a814c +1293000 079c6fdc893771a52ef83ccb7446c211aee5a450123e437679950ec259a732f9 2e1ac92fce11ee935c98ab01436df599e6cd902216c23f0f82398d52f6daca79 893e2588ba973d110bf7988bb94e555367cc8ba1f1a74b043bb9358dde4044cd +1293500 b89511bac310039ffc518832850462b6b0764dfb630daa85081f52d75a994cc7 52be93d0aad438223bed937820346a0670cd739786600e326f8e2df40b760557 cde2bc01b1ffc4bfe0eac517a1628e0c34ca795df5f3c41279fc776c6fc9bdf6 +1294000 04f5665ba3873e3112e4781f97999de407450023f4d96f8f5202b2fe4ebb61cb 5c69030cb3331e78c3d8bb6ca1c2f6b4ca53ff58961ebb7113a128d520bc206a 0f3a01ad2fb0ef1efcf5e869bdbc7799abac0a6d889c00558c5bc18b84ddd64a +1294500 aec70de5b6147e90937f37e5c985cd012387634c21c9df9e2bf0e8f1d5d46c89 f1ae24ba5754969938b4b1b00cd1dbeb8cf70c9e111dd77cea76138999f89e23 43b746ba357d64a69e5da9f14ac9cd4e9e2ce559858fa44b4014e77ce86fa31e +1295000 c5c31da183bdfa79f4ac6da353fb240edc01cbf1a5633ba52350117899088ce5 4c167cca85f5a846f0eb52d54280ae75c8f5991feb1bc18fd8acfe1ac29a418c 447ec1bc8cc5124e741456a96f030d6e25dbe21affb832e5064bde5886fd45aa +1295500 1aaf95d33f9e1c29510b7b46fc3aa120f3fd630354a17c6f2f06b3eaa6a19ad2 6e0427850445a6c8ec8b1f1d48663dca8bef215c0e91c4cfaab80e8357414eb4 9860e48a6c7309574649a363503bbdcee0985e7dcfe8166a00317573e4cc33f5 +1296000 37e8f1eee5c54282f50afa8afa6d9206f3cf5089252ccceece2a59fc6e25706a 66e7a2bf7b271c4d84ee9b0e8a769895c61fbd4fec16eb51a0cbdf08b344541b 7eb6245bcc57ad780c342096fb6c94d8b7682bf38de939d35793a9ad700a5c63 +1296500 6adf2392e205cfed81fa3e098a3fe5259398448bae7eadfb8e8e8e99eb83641b ca615dfbb481679822d1ae3588eb721f9a8d2771ac6410710dc2d9f1e1fca013 9b1fa56e4fbea01f4c4b1d5cffa3db4441097249688191d4c0b10bf2df453bb1 +1297000 f50fb839a010fd4049a78d16dc18c02226277a1160d45a31b51a5d8193e5dad4 2e8cc7bb69ef19638e8b4de77421c159430bc9b2a96f05d4461a3125ad167cb3 6a361e4157603d6486d3aab9a6344dcafb281727536506566c276ee30ec690c9 +1297500 f2c47a4395bf9b340ec2f97ab2980577af9aecbfd4a6153151771a9bda66cb90 912ae9da2434b0fa6b9f3154878bd7fa44c0fe3391f4bf7737a6d6abd289822a 389b8e6174cab770924950a3877b7cde32007613b88da8e9136e2ffa4dea5f9b +1298000 12f1be10df5d692a1c9c81e85ef78b4e7d0b3761a065ee44dd3d50b67689d021 8ed9590b5443c0c71de752292718e65ddb576fe2d6a0c81a46796ff0def3d7a1 982bb4d013c7cc8e042f8d5e1378885e9aff4e2e9476c0f97033362934ad501f +1298500 62d27b59d6467a101fec17ec5220382907447e2f9710d0784ecf5b723a611119 9512d7719b4fae3864bf692ca783131982ce81007d629446ebbe2d63df498e49 9b1db3cad736a13ca4d230c98ae4ddccc68525758e946c4f1a521bd0442903ad +1299000 e92c71ba19c0389dea054dcefe7198c1520a8512f82363d2b76b546b813a2204 91cd66c70bba8b4acfd8cd5cb27a12413abaec59b24e8d41cfb3175721744b67 9afad7e1981157c5e51d98a2e283cbdfe8a3496f17a6e2f5b6cfd0b73e4f0f16 +1299500 96ed3b01ff2316b7f5cd27680ab31198a606f5f2f0fd129892a7f692a6194201 956530a5d468696a16f9d3add8dbb38a1d375fea904813548636dfb5f124cc44 e2499622eac5c0a34adc22101b2a4d4721238547244e63089b5ca8d389ef96ae +1300000 975f2e29856bf89e0e6c38dc07ba8a6bb1505207b34b31426f437ffb1f98a078 bd912634d61420201a2bb34510b63007832a1c425aa1ef6f01e02456c1eda5dd 5825db0c30276437b7b4438d3bb99a97af8f855441b4c34ac76ae83c94418b1e +1300500 0ad9cec502fd4412f65f2c555bc345201f6b1c820d7ace8c27e7b559aba11de2 4425c5cf8a79b1c6823450c5faaa47c343f08f4bbee24d0b0571c3dfeca1860c 0fafe1c3b2ef9a337438bfb895f5e570a26aca52abbcaf8a246798ce7c64095f +1301000 c887909db7b46234543b9f5fb1c06070dea7cfcb59057d8a74b7cdc20763b46e 0fddda8bfdf47a5983e1213d76e659f96ee5bfca21623edd63da9f5c3bbb2dcf dd9717832aeb0abfab6ef027456e5635c3c5fde7c66b984b770744590433a514 +1301500 b94b86acd563f315962e65c1a13707cb4f744f743079eb5ccd4129139aa29162 db9fd455d23b53b7ab9eb38b261465b065c92111cb07656dd6e59db22c9c704b 0e1a2d9de95d2a890d62a2fb61e0c734ece7793b25cf19732aa5712c082375da +1302000 bce64a2df75d334569a0628937524f39a402190f4569dbc60911b8ea255aafc4 558caaffac3aac7a431c8f4b601705f274b7528fa4852a3ed8ac9916e6092355 52561f009c829ba11e2a3a8d04b097fb5d3de02639a26334f8a15fa3d442e7d0 +1302500 fd4a1145282430b8e05e1ff7292ec164de8242dc3b3707b3f10bec0e77832cfc 608778e86dd856fce3798e29199f33ba5a8d6bc03e1497e8953beb362fce3e78 6579ec234c0cb3fd53d4577fc17117c74c30221dd5963ad9f0871b35d1f7e714 +1303000 8133e0dabaecb7f19f01f4327851017e9e2684ee9aa35d5cffc588335137f81d a24036231b2a49debfc0eda8eacfc830e74093867cf7f05b785c44efef62944c 5664f5880b5d2e30b49cb29261dc1487a247708b3a6eea78e65d5d785df33521 +1303500 fd6c9d4534017e075406060204204c0578cc30be43f4531ce4fb485659c9396d 3d442de6e2a9c4cd50210f7114350d1d273cb65f1ee2cedcd4aaa5faff39f5d8 fd2b378b189a4f8c5ddc5b5a947f84eed858a1f28576a058b4ff626956da3e27 +1304000 7112169cf4509aaa768268a78f3b1d259baa146ad5327bbe7e41e9069d57ed13 7107274326934e899f8d90ff49115e9ac3afe50cdd236881a718029d2104855c 661851b7a27c004fd2438d24f7464548e09b4118a42a64cbbe4425bf1e1c635b +1304500 b10032a87ad4981f82dc7750aa39e9d6799b06b5cb4e21c773e85d850bfa2791 0b1ecfe1187d61df67b3c1837814a7d765f8f0f9143872452c0afb10f9a8ea28 6d1b44bc28dc5af3f96c375b81a40e695cc1149c79a2b4ba6bf6cd4411d5ec06 +1305000 1a130cee1b0f87f045a7ddebe316794b0c832941303924e987e4cbaacbb36975 2dfe373eeb1d5a995e02ae71d12c467e91393766daa5a1648ab82670bcc0a532 ecb1537854454e0fc332cfbd7de48bf1db6ee99110117ca8b45c877a2f4f9790 +1305500 e17eba1cc1b45569a84728dea0389b055d8bb9afcb8777a92eade5386ad05e07 bbbd49c9ae9bd0c76b428771cb8d7648919c0e1ffa619d6277c9d50e6d8c0fa3 5f8d86d2b7c0e906ad6b345ff2099414685acb5f0928f7baf6382ddcf87e6de7 +1306000 baad770e63b8324815b19d55dd164cecdeab4495c7cf474dc9f8914e77bb52de 25ea3293542b46107b15e5359e012cb99173193a0f470422b4132eafd69be03f ed593c06fef7f72fcd109fa3cb64c78fca75fe66567672a0ce21b5a48004cc9c +1306500 dad1ccd7f76c94a4e7ea6c94b8ca0154037509d0dfb7d40ae4c0674868e46d35 358a55160879b82869315151511732e9f1c7ea6f8c6695d778dbc9c80fd2b526 b4a89042edb0b747355ac0811a41657a2ad0bd5d736a93e44a4e82800c78e091 +1307000 449a40c7924c308ea4435762e3eba07b53113ca0f79b0f6e8382f22450959f16 5016ed7b1d89d52c08275c349a1e49c48bc334402a32a54ea1ae750a82ff0159 25d6ab38024133145b61919bb886479b3a4b2f7470bdb0ada052f07846dbd85c +1307500 6f7d300cc13d074b861c61ded690581a3de387b329898923344badb9e0fba8e0 a9af85bcdacf3bfa1dd74c5ce6f98be902beac71b715c46f4ac2f73e22ea292f ba918cf157d001ece92cae5e85147ac9d254214dd748082619c35d58b66ea8f5 +1308000 f2d1363624c5b5a75c5e33ac6e554ecbd0879b7c2faf1fa92a826315571350ab f5dc1f1eaae9aef8380140100659784247c2de2984c65266aaa23bcd865d923a 7366e95913db545bc58789da558447dc4bcb608a6cbb7a22c2112d9d70c8f2dc +1308500 d0b9ffd1f4e1b370fd6331976bad8b91266139069b4acbeeec23c4f58d5b04ab b85a1c505058e2182246ac231258adfcd1cce01fa22d112408c05c547e228549 ea1b220abc0d48583df9a3dff8e42a22e372e68517a7f6d4c4c5b3f2e17a0920 +1309000 65651bfa77d5faf1693f27d68cec53be2f89cf4ce9db85085fc366b120b421df 00707fac0f8feff0e78210251a4828000c48f25ae7d7606b09412704e4c1dc32 f3c1e90de4bec64d70bb6b3eab484b29e0d7b3112d0a85979c1fd973ca38f2f3 +1309500 52843cee7c3f212e3a87dfa07cd83247d2d92ca6460ddc770711d704ca5144a2 1ba329b5f25a19880699de989b426d3e53c0d548b985076832b88af0989c996c dd88970433faa179f4ed7a0ee5b3ce2cbe8e03487e76f61382eab67ed08718a0 +1310000 35aa5778e094f3b24b1033bc92ac76da70426e80e0bb1188b8f2795ec4687cd5 215baa73a90b7ecbdbdbd2ac39f9947adb07f95b188fe4aa4e43e2c432bbe29c c6fa8bdd27d9509d89a2a45791d743b80fb69b1d2901ee7ac1bb27fbce523bae +1310500 a0994a46751b8d2be5162369643c9641ac99916a38be19e1b0278a4ebd771f97 d361196a389889a3cfc524a353efed28384202fd1359de3412f3606afdf5fc93 e08a070ce0b2d11d08d399a619cc6c2e0cc44e79ee92e68ee76ad8dbfaa9186b +1311000 20c091753902fc684bb9e78032e4456e20603f2aa3799ecdf38744c9e826c82e 988d02e5265ba09e8e2e4b5f3d4a3033c3f5eb5a7c5d9ab39b176d97bd4a833e 6a4d7f67be57377e310794a7014737d65539d1e03d2ecbd6b5434d2113b6f5f7 +1311500 675919e065fb57de407cbda5e767d1f054519cad55927b5d731f788f74095ce5 bc9dadd029a4f294fa9065067a5afa88f36d038e1443b807200e9dc60488ad64 25aa0485a49308b89374f9bd7b3b11718d3e3f809d1f193c9867a46f71057f96 +1312000 d33f0d925ab7efd733a8697a54bb2e84337e88c24f9c6f62f93e1f16938d760e 6904935251a3af06aa30221df6fd55baabd76eda2ec5d8939cbb0b880d476ddf ed9abdad6170f8113d0868a4bc25eb15036e9063ea7e81db0b183a6dd13a99c2 +1312500 0b7b8a2979f1c01826e26d88668fbf591ebcb151a61aa2aad2db9bc621735bd6 302a0336299e06d75ee605c34c3f66e41f74d0f0694dcddee098d4c2e2aaa034 143426b6666867255c27a7d96cf5a30d64b15e5ccd503d965568de72516dd137 +1313000 46970f602f34804cb206672df8da4b06695a717a760e0c3e38d81a1f687aa93a 15348af5abae92b1a07f1d5bb5e14a5d56237965040394f15dc28ff0b4ebd958 c453778ef2cb1bbe9e3ab5209928e15a7a15bc1df313640d3e29ee488595fbb0 +1313500 5788242cd701f3e2fd301e920fe0759e9e79f6ebf33e3af9f5f810df6e07eb48 fc3b0ec24934c266cc3f953af9d3e852cd76dff6e4aaf15436541a2f99000130 ba3f2e8116a1405aa63d707ec22d05a1e64bf90f5a8db2dc6fe011ea8d86d7ed +1314000 8e752044324f93c8bf6b92e6196be5a78e3e732ef8187ff0a625b70fb377d588 83da93b29fd11d169567a3ebe0e8b69eb983177585fb14b2288766d66e01b892 250ff4a03277dce320ec0606bb007395fccce3ad40310ae6bcd371c5f0130dc1 +1314500 50cb9a85c311762f226056c6e2d3fdad77c72cac9689521252f7118b3d7f80a5 6daec22c53b55b5880e0a4e12133b3206a56e3c54f0a625b099f80b79ea04846 a597acea03376c209fa38173208279ce0e5a724885e63aee6fb94332fcef5ef1 +1315000 04e6b39f6b1ed74aa5f480356c06978ef66e86d7dc8420b1de1bba5d17c2ef66 a8322867072074c4f43a561a23589aedcf1b9309ae43003764e7693df8c3506c 2b10fc30946bb56db5e420b01b1e8e00fd2b68144276620c7b602c99197481d1 +1315500 a6e5fc3d9533df21d75c6ef6842d1876620335fa10f2b6125a7806a9a5cd719a 21caa446c64c612bca85e84938dc755ba399addcdd0f35a9c33112fb98e5eef1 a106d66bc5085410c37c425744ceaecfa13c9a0e058c0750dd5318b715829cb0 +1316000 db2863ef1d165fe68b5f9709db05674b22ccfefffd954563dee741defadfd1ba 408dd02ab1084a6a76c8f85fb4f92ea3f676ecee8b94b4693ce275e2d09ef6f9 4b01c70ef24f30b7b8fdce145116ba725161339dca17c2daaff1009fc7e8c95e +1316500 eeec218c3c1f10186abe46729df60f9d72f3fadaa35ba3480a60b099e5f60b27 3d1348e98cc2fb807e6fb7f76da5e9cad8d8ab4d51ce89c7c6f41feee4bd6698 f5bd4a8b35b80fd82b57ec845dfe4dd136361147bc8fa2f4bc96a4b50fd569fd +1317000 215ef30ce534c60be9f76c9d0a585233c9628b916a200c4f9b065fc4ea5510d1 0d05ed5c7e89756edf08be777afbdafa26bc8701d10c332c3aed01f755b6774e d605dd429eea4baab063ab12dcfc21b6feacc73da0ad544b59559642699eb8c1 +1317500 ec723a7ca3506a64ae6f72efe7cd6bfc5ceaa1f37fb12800fb574b35036edbd7 d3370646e718e1b9492a552d41c8487686570fbb5ec7cc7ddbb0a6a3fdd8bd4b e718953aa8621a11084673972c3eb7edc93167deef1d903cbbdac60825fe27c4 +1318000 42f2cd60745a2f20f12b711f71751f335b4e45384ed0475d886ccd25a1a09ffa 8db54d2f981ca18996400b1a5606cb9d0caa27a2c90c40e5d07eabdd93a152e2 db0d5df009e9619a46cf5bd8b85a15b87950540dec20e4b67b6b9cfe3246a215 +1318500 bc9257f668c2403e605c2d561accd6d9fa80391c8900f0ded17ccc2bfcd38c2b ea38513fe09a249f346b98aadf558fee9bc08fee5d41cd3c8e0b734da6a2b55b eadee28d3e19873a8dc80d5855416f10b32a5ed0d0a7c8a2b4a1704aab799ba1 +1319000 88ca4eba8f35c423e9385e3f248a204695a3ca251cec76690ed1c4d422000540 60b5e9c72314a0553c63412b5464038b61fa73ce85a9e79ec4952ce4e6514452 cc07f20b1d6bbc525d9976eb613d62f4a5a23b820ed6ff8f67269fbd6e24c28a +1319500 5d4f85d56fbda084409f4fa380b68be94a16a5149cb04f3ceac7006de58021c1 95180988392c9484d337d4c1c657a55cc01d7beb998b7f8da3a0b8ae0db5509f f729b56095b5b0f49feae95f2cb0c72252c24ac49308c40a38a7ac7a34f27915 +1320000 a8e38e06d11cdc27f90d4b261fb356fd8faf78fecf0c0eada19b662f0d4fff8b 78c11c66b71c77f44e8444cb24e65e3e235a373272da8cb4a8dc89a328ba0ab5 4c05cec3108ad339b56766628c4f130f54d284b9c41197e7575662dee9632d14 +1320500 892e535c9829da5008a53e47ab6aeebaa5eb5cb9db69c60fbaff054929acd663 910275228fcce2fe3136aaf1b0a18a2b9b404e527ee0e1c891f5297da1f8a8d3 843582d1a96d117f087a59db1684e1edde124a3b7869e773783b00a6db15a7eb +1321000 0826d8a9d96cf570c4e866b89380424b7052396fe71e583e829cb29b01ae6c41 f0f0461f3471924f1150ed7295ce927d2f1ac46c5a677620804218953322c23e 9815fed0072234489345c10678a0b5575d7beb1e3ea25f16691fa1a50178526c +1321500 1445c93572d625333aad113e9bcc1ceaf433b3cb9755e21dffaf5af6237acb1d b5e483b2101bfbc3236528c141ca2a2003eb196807c9b7fac73377ba487797d5 c94810a72cb495fb592ead8ec0823e78363ba4000aaebed9ee704bc35ffc0c59 +1322000 ed72c3f182a1db940de93f1e22c0cfcb3ae32f6c803e265e9d889f5dcbffa0e5 e7ed683971217957874b78bedf43b5a83fd6a6de3d8ccdec564e4dbb556555d9 97f9ef26d07ce1b83906e8226dde743e06a0426d4529b365e9f75ca04f87b8ad +1322500 66584b90e56161ef1e9566af0bd72cefd3ddc7b93d6236677943a717cb3675e9 a8279af051f87774ad83b9e738026868649934c1428b7067cf8d531c8f6325cf 9e3f7186be531b2727daaeecac65eada5e7f82dc5bd162dc282b4f7e501190f5 +1323000 3ceb9d6191356079cd1c7cc4e3864626b68bbf1a69165b0ced2c8d9aeee636d0 756078fc653f2749d855c7998815c9679835b832b1cb65a1a2d0672d098941fb d2d31a6343ba89fdaa0fe25af7ace703373a66e8cb86f73115996f8728df8668 +1323500 084987c0eb445632b5947efdda82b5c495907bad65415bed6c1974f02e49883d a9246e5fc38ac01ed5ac7b59610331cc474ce7fc839eef50e8a46388a2613078 133e9f74cf623442a8de0443ba6644a2cc42b432ec5f5d4181df44aa6552091b +1324000 f6c06411dcaeb4e047ae00791ba5e7e66777cbdf966765ba2b11281a2d6a207d abe842024abd3c854c6789204aa707cead8c8f0ddd1c61bed5209e54569ce8b4 83be6c1870c4701577ed5439cb92ea8ff7336d33b65fc088f86ed866790da165 +1324500 af410bc94deb902ce6d4c36b7a90960202c64f8398afcaa9e8e68aa2f41e0820 2ac8b1f399bb19550535d1f215c347fb60a53887cd756577a8992c83f7d1c83a c25aff30d3a74b1764ab377e66e01ffb7dd8be9f78ec00ecdbfe44181331cf1b +1325000 cb5b9a6b345db9b1ec8abb1eeb3e5c9013197e90dd6bf7d40e60cf9935e4d604 80825b63c7d1cc826f7b82b1588773e75f4b71b3255f283d5c5a584b967b351e f03213e41e99be31ec5cb9a75e5bed355d95c893e20468d9e40116a9e61448ec +1325500 7e8bdb833d586a3615380e6555e54cc5c8e5978caa75e556b3bffc160b425e1c 0137351633adb5b9b72b7bb29c8a055bf5bc37dcd9f935be1c9421eb85578572 4a1117fc1d36a0877cb3b2f31e6ee576eb01923b6b974e6b073d86ac0b57343d +1326000 5abc0c39b0cf29ab0ea335bb8fb4c873e5b3009e73ead08aa642147241d0a0d1 db6fd87fcf7b90f42e8404dfe9af95ebaf7038ffdab95eb2f015a53589059303 43f2991b18845e8c2d96cbb96e3bafbaba7a1c9da9b2e8543cb2ef64e35ce88b +1326500 00c71e710514946ecd24a4cb2a85d1107e481dbce53a196d3494071924a038b8 7ca02c6d7f7576ab327f402febb03403f4292f9d0fa6ceeea1684e3958e1c3d9 d8499c58af0993c9c028ed0f5436b33312ef1688f62e90a1e19846a1322b1afa +1327000 03403267f98c67b1b66e4f701aa3cb0e8219230838f400b8b0b49b442e023857 a163a0818e4f64334ad046e72fbbe3c8161a0f5ff1bf52aa9a7a556dd46e1ac9 645edce616a09a96bbfd6cbbc0f65f2d9fc1fafb41f83ec530d64916600c92c2 +1327500 8142b7c78effb1d6f2fabcb07f4b0d6909d083d8fd3fe0966c566c90fb5cf51f b94321ee62c251845156b9302646f8c1801659dffd6d92bb483da0f648cc72c8 9cdb8d09a66f35044287aa3f7a2bf3e3c56a55bd8809e426a3ebefc4b9d2248a +1328000 9137f3fc100719789a871a7f10da24d3561f4241fa03a39431ed3c6479114d7b 66860913ea6a119f760c42682cd44edd51cec90e4acaf28c8f3ba74467057a5b 256c892718054b55dc43a3a3fa304093ca7587073519a6694adb91128975dfff +1328500 4ef04e76037c445c2196d56112ae5cafde52b1232828196e415642f7bd479c95 0b5a8707eb6cc1df15188dffc9be91563ea9db12c8922d65df8c795b744c864a a24f07bf3430dfce44efd11c24e609149c12b596142ed14524079c4d3c43fe95 +1329000 dfd2f9d946de44d5216e2798cea1a523124781f7fce4cb573f724c9dc254e568 4ba701061cc0ee9c912474c8b878f4af8bdf00e59738ceeeb8d88c1b83a431fa 4d7c6b3362c653cb0ac2abced3b471db8c5425dcbdbc7b9339a4d5deab0d95c7 +1329500 208c82ed9e60057ffcee35fa36dc71d4b33bfa2cdece6822be9e71e6f16fddbc 82088ff7f2e31da6b683d76637f6e3278ca54777b9fcadeff34f3f36729fa593 be4be507926c06262387fba500ef8cb90eac657690eade13c94c4085766ff475 +1330000 7931b7542a1cc3de43ce17b17f7d59195113727d8b265d08416a94477dd8afcb 6bbde859522632482ea09ff25feffbf908710c893a3b4e50f377cfd9d13c7534 356bee4ba090d6a8fa7f6e5e9a151c60322b0d67643497534646b61445ed300e +1330500 9ccd443e94d6b67c10b6cbd64c01012ea022d25b1313fd33e824a7dc60a74632 25514c86048597db2a6e09601dd58112f481e659737baa8b2d21b70d0f6af744 c2b40441f53cbaf079da3df183378a1db3e79e53226e793305c47754a9d653bd +1331000 83692b3b50593d27009f1761c6fc280f34d4e50c8c3b9420cfeab83efaa07c70 892b4a419efc44a4907fcad1ed2d425d55691cd391a72880eb521702379feba0 06287dff06e3444ff13ba7366d07a34e1c98e84ba335acc64c4f20086dda3717 +1331500 4bc03c77379554bbda564435370b1f1e2013db69e41f6d2756a2bc6d1e4b552f 4d93224a32c6e5e275fd72860d656812bedd7fc065f6bac5709415f9e2d48757 8b1e34cd77a5f1bee1f3585bbb79fd4c9cc392bb3ef78075fefa1c54605461c5 +1332000 63e6b1c164691b3f40f0f3a085371397b3ef13063a6ae524403c4bb22496a23c f809a554c01090a1605b51ded6089e45c72e60ee0677458a08b881ca86982055 76475962222b473f5a41394bc830c1cef400b2af7cc8c3f86b468a3cc1b6ae9f +1332500 d2916dd6fd1ef7e51dcd9eb9c0dd1cfdefe1f9c6c71c7ffce3e8c40d0059bec1 094a7e0239be65639ddac077b033d0f068d7ff604d0a05d80195de8ea9e49748 707c305ea934df80d08bed5e9811a2cd8120913a99783f8da3aa0285c1727e25 +1333000 bcecec51228434805c3810493cbf2e5e4f6cc95f776ae67ec820fcad91fc7b11 83810181c3782804b81858b1034d369526cdeabd8c24138982ecb160f73f6ca4 ff1b019400e7e567d8774351b169930bb9a423231795c47e77b88f76110fca08 +1333500 4343737d8353646b1d21c6de7f90cdb0b736fc19ff66832cf460f0b67236989c 39a8c5d182e4279d82d43eb73c4a47e42516e66b02e6004f5b4cefbf00e173a5 be6b7a4687271617c5910c385d00c2983f74e5f51925383d9812b0f0c3e6f068 +1334000 465b6da0599df8a9f78b6cf69289411e23267f511d158d5da255ec7b4591510d ddb07992fd7e9268f045be35c904924e0ec1095860c2b0d2b004b84ce0ef5b6a 1eca38511ee969a2b094a82bdf06cf6a2c7160dae270e9db2adebda0ce8528c0 +1334500 03c77f8b51bc341353fbe867cf57eedeeb34b31a59c0de413230c44e402550ef 2e915d480db74cdea0434864f187a7748ce3d9e7d89dae0b2bf10c11a88d8fb5 d7dd6273423176f9aa9f41caf7bea8c92ff636182f3a7725d9b6ab894a9aecd8 +1335000 6f402f769dbb32764a692949c5904ec18f10a9b71e4f60b0b4953c12376474b7 bdcbd3edc0af31690d7a021013fdfd08e1dec0a41cec4ddec465b71c551f7f15 2f30200c4a9c30d2bfb9008c51ef5179c8cddb732c48fd2f60c04200a5585693 +1335500 32f6550a807836772ca293673dbdacac959b394bde868045000d26c297ac53c8 45605d4d0627f37ecb3ec62478391a66283b83a39ea11fff8dfead6530f92c2a 8fd8ff109aa2dc7ea0949a76d18b561b27ba25c1cf50afdc4f198c21b65b0977 +1336000 578dd00128bd139aebc6c2224c83c7643ae19b80167496e84561b1619f77891a adeba86609a56fd103b941fe64504559fa177ea010dcc6f761f82dd48068cf8e ecc6bf8433d174e5a167f74eb7d52548de90cc3ca81ab21d670f2176d2cbdf16 +1336500 7e0df61b0c310d89c1c76fe3fbe714bf65b4baacb688290dd87dcc5b5ada1d20 72ff1e9dc301116571223c8412808c5f8cdb586f6de1329445bf737899a136dd 787ba6fc54114c4267c44c3a6c5d823594607a1acb047d7207fe43f28a25a167 +1337000 c3a0fd31732bc0f037d4f784fd020a81f6f6ab9fe202530e420156b316cf9559 08ce6cc295422a60e6ff656471f886900fc29b805d4db048b05419512b0156bc b2209d83bbd0894421480607fae5c3587edceb620985b0ad375a30f4d87589e5 +1337500 aa2d085c6e4294d127befa7be56f68f088049d4af00edcce6e30f5f3df86934f ba03fcd4c1bfc55e4b1c9ff967d4ba0e2010d49320f34672080e4d5f013670db 33dc86ef43bf0fa8b75ad4c8f4e9f6cf89654c6a9af39b881584ddc827d991eb +1338000 3a66c94aedd2834802ee3afe2094f49c258cf09f3a2721f6a35de414f296b32e 896d36cd5b88586454f7369c132a974e7397791ed02e0fa77c764f65e0439fa2 e07b793685a3b7aa47da0c6e33673ce97b4630e8cdcc1dac6c49decd157e60aa +1338500 69e34fd7bccb7be43b96f4dbe5292d8345fffa0388f0edd353ec94783d46bb51 6741d4dbef0c44af99f7a1b99e5b0e0caa3de0eb00602a234f9f6a4d2eb33c07 ada3b5c9b98f12809f1faad2adaefbbddf176f6ab5769a43389f95b2e16dcef0 +1339000 b99ec6c8a6494a9e7500f0c0b999aef622ed9382426b62fd3585e40dfd0cfd79 d361f46a241b89703103f94f73a0b4b91a9d342d8788e6e4c29a6d98337d09f1 b4bfcf2665d277e12a410c561bd3e7c6844c16b3a25ec56437d85d3d2d9ef082 +1339500 bb97eb3aba318a66070aae5324d5dc3f21aca39b9a82c998bc76ecaa416e4b88 babf3c9d2265a8fa3899876607394285b8f8a8dfa8b57bf4e9e13ec6d36fbe56 9b47a725ba5a739efe63b20c5b8165b7a33502bc5c7ae4696e02b6bf16651c3c +1340000 5de5017252d8efb1c59c52f3db4a1633fb66c6712ff0695566941a1e9016b212 4793b3012b17b17a37579191f895c2d568ebbeb1c6231d9740901e28e23fbcb2 1e4049f676a2f829204a97b19e50fc048e8e4cebb29dadb73a9ab545c6b8fa35 +1340500 a5bce6a83a1d962dcedbf6fd51cf24fc5f84f32a9f517923960ceca278788476 f4bfcdab61d47aa5d7c46dc1d96b7ca9124b1d4f82ea88c8e7658d84213eb3cf ab2452cbb75e3acbe3d31dd2ff29d9f5831f61519f5afc9aa9eea9f1d39ca30e +1341000 c3e046334951b94c0ca2fd19e4805ef8795f588c8de4ac499e3e7bf4c6fd85ca 0970b5988fee1058cb0773020662290639037d210bab1acdb56d854dda2d3b97 e357a7f7fb04031023e07631093cb1a207d32ffdefc790476c30dfe7222207ab +1341500 1c1bfb92ccf91a8eacb187c970b0496bf1d5290e6a62b7d8098211673fa31267 ed36fbe8eb96e02f66ec816a427aaca059d5fdb2eaffa64a2af563be2ca041f5 25e64d0c9f1654bb0ea0215f20b70192a35fcd68fbb8de9d9a99475a03101a08 +1342000 2814181378366f0196ad0ee1a410d11750ebcd6ce2254a6b74a0ee29da4c9975 641e40090520106202a8429dccf863eec821972b2424458e0cc904ca69e20c97 bd3746520e2515a4c5cf01f4ea23a7338d23bfd8f5023e120cecce52f6d03bb6 +1342500 b9a08e013fff192f3d6a4faa8b94c680ea52751a81bb1e2b1aba0e6e86b88c8e d34e93ba5132f902035bab2c0ffceb26c139e15052b3bb04d2c377caf7161104 9845659c71a5ea1c5d3f1814e488a956db158c0290ff83ce1c827117514d674a +1343000 038bbf00842f1181184292096407329b8ed19c4af0501984995f230ad8bace8e 3812d9c5db37593e056cff975628aed1e241d1025d29420625ff64c570163644 e0dbdac3fb868e20b1e0e47507d74277a1a13a731474ea422f70993eb950134f +1343500 4b0cf19d29d2b5cb53690dccacb7963e204a179a72764f937a68d07b05efad6f d8d521de3d55ecf1bcf28c1d3929274bf7e88c9ec6f658856f69c2f973967589 ac10a7c1f0dcde7dd3f08d311015a90716ceea651fe360a5380adac7c61b1926 +1344000 b4f96630643fc69b3c56d723bbce7c92e601aa689fd6aebe1cda67bc8f9de69c 1d0ecb44638da74996b9bf1849dd8e65b36c971c022b82e22e84372e19412404 c3ca81484544c59d0b39b2a820da9cd43c8c7a1dff32bfa1720a07f9c8c98c2b +1344500 83b6d7d700027d3d7c7d1fc86d2a01d641d25157f91be2ad2e39c956d0a7949a 0ad368d615509ac20334d6c452c258b33c26b47587680d55842db0e31f53bb2a f1873e24d3962de41f7f2c444b9a5d6d12b99c012a2bf543b0f3bcaa6b0bfc12 +1345000 3191480a871167a41c33a32d7ec66cf6a1dd480176780ab90e86748982c2a7d6 eda0236d99778a1b348e0c6b4c338c9c4438e25384bbb5a5643bcc1615358521 5b7c368737036c86b3a5a9d0e583ddb6e82f2c87634c617a24d177754e7f83d5 +1345500 a5e9a1bec9b5b9651758f0b4b7326d7e7ce3c92766e0b7d3674f59f2ee7a3671 09a045e962f6f00182cec714cd59bb0697f07d2a7db8926b795f4ddd8f39c9e3 eb5079862bc3f270524c4935b6787fb0de708bcb5c1d6176a87462b2453c51cf +1346000 4931aaf3cafc65dce5bebab637820ac8691232a085733186f22c7df832286e1c b9a7a73b558d6d83eeebe12e660caa1adb82384ec8538f9a62fa5b682baae34c 34a0813cf4b6772ab99acf563b1104aacae50220ee6e229c1eea14ad357d76dd +1346500 615caf3dc2d54de35b346c02ecdd15ff1dea2a33a2c2fe384b88bb1b4484e387 c9290dbe6050f045538d42036e9d8ba840894a7a36de663ec4873367b33a44b3 8ae0755f90a9b40929fed4376006ea4d276feeffe2e5525dc574ee3382b5146f +1347000 9f2141db8da06017719371aba61c2870bc8489a3851905fe0fb68ac3eb3ffa0c 5aa216cc7f49e2a7e44d0c0cae9943e09e327700c59d98681382bb64db222703 9a12df471c56b23a0f87fcb606fa76177a34cf9599beec6a377dacbe2cffc94e +1347500 8f954e694ad36d2aa241cb3639a905b0172a4e493d290472272b2c7843f90a6f d00663fd2d358b51566b4659a4256ac81a52116bdc7f79e6f8608f787cd2e63c 910c1d960537172a91361d0b36cbf7710b39dc40fe031062376962faf38ba2bd +1348000 7c63f265959ba36a180cbf78d0e28d98c85775ec652e960da7b88544d75ee269 703d5a7af24b1444fed1470ee43f54331c9d3c5cc425cc7713ab5084870fb776 5df018b23edc754d96a0fb9ce8eaaa17aee136ab3ba7ba40d713cbc49ef845b2 +1348500 c8aa5a7888dfc12d8ea909d16f8bc2f4cb75ac52f2c2cc9ad2a7204c4fe91ed6 2665d6210f6419872e8d804adff0e6bdfb643ea4aa4966d89998312ad432d712 41192bad31bab841232a6154927c1471839ba2bc0a5da7e06b368ad9450de0bb +1349000 f8276c6d70887b37fe6a5ddf66f60bd59ec9addd24538f7adcbfa2b4e57ea3e0 e846ba1f214b54b40efd980e675326874e07b9be698b0beebfcbda0bccf3a472 eab0e993ae3378f6a6ca2101c8067283ec4171f47cc1bf11c8bdd418df7d6b3a +1349500 26bfbc01f2afa9a8bc2f7b6d7d3ebf446a02e539dc916a9329583f85932a4e94 6fab66ed6ffa3b0b419bdbc9e1d57feb249bfa4d6dbee098c5b4bb48a0a49867 7f6f111a19cd4d2f6d61fd2f3fe0139358fd7685497885ea5521013e6d53d951 +1350000 db914330d42468be64206d8936bdfb3d4b03474caa621f72623256edf7f80d9f 58072362690fe06a7a7d0c539779962943e3acf31e8a51109efb7da246e821b1 cc86ff3980059557cd7f3b33f9f4890f1eee0eb33ebc725a6f73fc1cd4bdfd87 +1350500 6096e1312edea656dcb92f65c85ab5e5cdebf3933e8d2173647a45a9a3210e0b 8c65ecf92dbdaaa95533bc15cb23d9857da92cf2d3592d2a5ff22efdc8a3364b 26a6671485e4bb35b0795f1f51ee14ddedfb4eb80c75e06b557080ef5bdeac9c +1351000 53cb04dbcce650f8e79df3c448d04ac741505118f6c3591144684dfca03928c1 b5d14b77a20bf416bb74bced28b7294723584616f0180c6cd2d989775ccdf9c2 1a013bda8dabcca13e995ae1456347b39a03fde3e686ae1d391f9418a322282e +1351500 8e072be1bbb012abe8596d5e9894b71bf659fb9c9bc28aec90c53de3f3e02e0f 41c0d88ca37aedf56f2edf7e66eb43bd8037eacfd4952259806ff81e3a0fd5a8 2a7beeb90f62ca7e91bc5f79ecba75eac51a5bd220d953741b28fca1f6140b64 +1352000 5acd06bbf2e1ea14040216b37d79d2966d438b0d142b85db7e3843b003489c01 3da4f82cb1a6e6de3ebe4e3146876bb1cb2dadc7ee9eab406a05c853571181ec 5caea07fb0da33639f6b85779f36ac5c7105679a0ed3fa3aff2b14b5457a6f69 +1352500 f5d89b3f3cc3e9649eb3e8b36089563aa908aa0ff0e7e109a2e7649343f63b87 dd0be9b771517d97f968a0e5f54605d6a7c8ad897922924f8a1957aae892d915 b901e6e76ca9aabd558e9d868d635350720b76eba9bcc44af56d09b71d678c02 +1353000 5d49abadbf137574e895a0f8d60e940fcb87a7a9b3da6f8a733b6349ebfb0b9f ab12ddbea464538c319d247f73ab6fdebad036b66ed58da2db3b40f49b1d2d9b eb6d531a464b5e5105d4bf86c77ad2bb844dcf85e01f4b8210b4e2bff9fc06dc +1353500 5c8063450d2985664ca20eac74a82564f95cda9bef9ba9517aa862a34450b9ba 40cf73bb2e680b7eba044131f7b4c7980d36e33f9401f79477bd0dec157a1845 e50b7634c1fdd4ec5c8e458dcd1eff860e80c5c55c434c30c115a4e733cc5243 +1354000 2d4991e9cb142acfd096875eb2a464510296fce5e5a2b4f8047a1cb659d7e0ec 3b075d1b4f2a832e673690ab5ea2d2dc7b4d88e3e0c4074187ec63415daf97be 59b8b76f1f07860cc92ca7152cbd8414e547b3198d671985fe6e054ac2420cac +1354500 9157d2348ac1bb37476d739da5a0b03f4406803596a64496a2167cbe32de306b 3387bd949d44556b6f0614809ee00f0be526b2b64f3e2d46f7b0346b8ea109fa a89ccf40d942037b793d775dd08f04a4115a81afb86ae7195256182ade918776 +1355000 79462a5b2495a1324620807079f1f9dfb8a8cdb990993b3156ba6261110a2529 1910799f7e75fd4f2e56ebc68569894a8cb5a35b91494cd91320037b554c2f40 ee9968bda17d6e846b13d1678d1c7259d63173b45422c1da4f349ba121c3ea14 +1355500 ce4974c7891b61213cc77b84c242d53203b83429d64e79721cf9a41810dd2ab9 2e8b5509aafb907b63def57d173838f08f6ef047a29f66b41fe0c6d6c1370780 63ab847b7b5998a33134d68a3d9957a61badaa9210bf72d1fb9ecccf3e39640c +1356000 023395d95890029d9d8962aaf7279809a90150fe9d4f61c0316c3895d4bf7dfa e4b11f5730152d2d73fc58987229929d80336c130feb18fc15ba9f741d9426f4 8c97da0686c2d7a8cd8c9302fb058c0641c72ddaeafaa3adf5db4933077a9e69 +1356500 a050c1ea17c09980b6c7f00e2f55802bb3127f8657560bd1f238fb0251fbbdf5 6a333264bf3abac9c07d30462d06ac0aa64878ac5190b6f1ce056d607387989c 55dc870906bc9ac8b417a8be30d8fae472af0d4f0dc8a1eb07457d33e8799936 +1357000 21c4e9c4a5010af0ef328fd691469b50099cc16e1d914a1bf197638176c78a96 795814be162b58833d5303da87846ab1cd01f14a58206748c8470f4818f8a2a7 70f634630c10cf077c236c9d12ae6692005a637b9ea7da6a01fc10c37aa31e72 +1357500 db1a2290db3c8daf8e98628c40de320d54248c85f0a275d882d9fa0c077fe0ae 60975cc6af2a67be2fc1e1e2d996468795a6df77a40ec630b8b6137841f9bb8d 24d173110006536cfc9e9fc8cbb5057830af1faf7159272623e622e83d98613e +1358000 622659842782032726cb02029cc1b60a3238db2f760fd830f908797271e6da71 3ac95814d20086330bb18fdf045db19db8b98f888d56c971a6d83b07b1ed7545 73e71d4eb55e51b98862c1662bd61093249cc32d3b9d53b91327e45f0b207ec5 +1358500 c3870498c6e13d7378a9b2979afc44c86a658c6ed0fbadfc8d80d10321a04fd8 e2683c703f97dec1616d7fcf95c5f110742af2bee8820e107378d5f6be3693a7 b58b3be70c6c41bcd584e324e21010b0604d3dea3b4f5e294239e2f0d72cce88 +1359000 48bc6741c874c270c6506ea68e14f803842fc3a045adcf41aa70a7f952f748bc 9fe96bf9be9977cd7e1e844d796420e9038d72506a5fa8a63fefd68cc6e51724 71cd975cb68cde056c2171cecbb94a27ac08a68cd95cf02a17298923c95f101d +1359500 95d98e7ea281c485df5ebae662a340402dc8fce0f7a487c3c1616e52286c79d4 e152f7374181d4539302d8d5f3a96c87b73dde4de9fc7def90cd82a4efcd47ab 149c0bb73bc9cd66e393414c282a574da5ff4617a7591243969312e3b32c7067 +1360000 241fec07ceca251c63f9d42a7d1646f66df2ff3faa6c4421c35d874d673f33c2 fc79d7e5d2d9c034da4344d77169d651f881e523c013046060c940849b474cf0 0bdd64b0d55d1880d3e8b2e36bd5c8bc440f39027ac404fdc27ad1192354a269 +1360500 7bec5df362dda54fe40aae98d9442d978d5ced91cad5febeb88dc4f4950e4bdd 7e7080775fbb20f5701d23713e5d70b8a24ebad406de58aac3ba899d63c1635b 01500a609d11927cb2189d351bd7d899180a3069f4bee2216f796341df37b1a7 +1361000 87d2666d95d14e3beffbdd4de72e7ef6fe60b0363e4fac0316d5afe0ff70dee6 242b9b14e80c5d87ed423060bb6fc808c15bfc0db548fdef08f27c6477464941 321aa04ef491a9292d3650b58afacf92a9a08e751b1dcbf92b295a128afd212d +1361500 2bec2cbb01a7e84bce2d3436dd83e5a712175d115d6bf915b240fbb639d46078 10a016f5ffc99d3a7771f6d3b4a4f767752fa59736ba95547b1d044d7e4a8191 c46c364324e570a422aafa228b3c29243475e073f89ab6d0b3e991fed49a1e73 +1362000 efc9b1bd796a7bb73e188e64f19dec202b931120ec1f1de995e239c583016d68 42e109e011f018fc0e803523c87e396923d7d16817c8ef379960251ccecd15d7 8a8fae769c5e9a74ed2332f0994316c9c5048dec873b08661fa6f579e36cf0c1 +1362500 0d00ee09aa83572f4619cdfcae958f07cc5754d85aff7308bef545e31c0edebb 50a127a73348df1e9d1eddb21d40cb8d96053f45c63153075d765953a5e2a995 aa590f65fb07197eca278d885828a25184c5236d425764e7a2497e35c22b6415 +1363000 8ac5d4cb7ae609dfd5272341a74785d21a29282089f80e1eeab5d8837e158007 fdf588860fe92ea12accce443758ee8c000930eb3646e1cf6dd1f581ff87df47 76c13b9ce1d80e442619c3835145cb000051ac099dacbce02c084fd8981020b6 +1363500 2a5195f60d986b071d7db1ac3e8fd13bc0bbb71e1d0fab407b60cc5fe83bfd5f 283de2f90e81f2f5b1e532ae4dd1da1d78567ffddc28394f03568bbfff455178 a7413d18fdf8fa29e161700305ad0c92cc49150a3842e08d7e502d1f01afa467 +1364000 df9b9296cc777b283b5a036c3e556204c9fcb25ec05da8ec4dabde8c3d13d7ff 322738792414a245c0075e630cf15dfcd6426c2ee5db743d701e8c8314bf8399 6fd14c20efc93e4e3d29eac05d09fff67936cdf7227b69aee5dea8c3d847aa97 +1364500 0e040bb3819a52102bed2a02b2d916d3a4ca27ca70581fee51c23be143ad7230 e1367dc512b0346a68fabea62adbddc575e6f46864aab790663318b8920ab115 6a6399830a202eafc0830d664ceca07854a404608e238b52f19256d8775b798a +1365000 7b5defc26897749720c6df07cdac18c52790d3e13d3678698aa100975198cc3e 8f0c75756bb5f45da428b16f2155fe77b85f4a78cdff48572d7e9233bbb6993c d7d3f08ada41cfe67a839692ada105459068fda83185957846e82eda06bd7084 +1365500 bbaf0d42419a72d2c1da75b77c7ad79dad79e283b56f671ff235c7f715fec350 ba7960c169371a86cd27743a6b3b28497f9411d942ab265b0e624f1743a4747a 1416e954246cbce0f788fd78e27ac94da11144fbfa038e2e76476f1633fcfbc5 +1366000 0dd08869a4673ebc933367fc785064583b523886dc1bd080cb5721c6b65e723d f0c28af3463c49fed6fa0d56f3cffdaff119da024bb18de553dfa03e99dc8d30 ea7d879e825d9ee04f06c07923ee85364f9ee41261a499091b0c552787d57e34 +1366500 7809434f8bcf2bba7c2eca9669ed3e1689ecd89a99d8586c4aecd37c0975e173 8f2457fcbdabc3f312d6b6ab1fab4d609a5ccb891e3ee5cee03b688e9272e142 da19a3eec131221757c6842f77fec09b297346af66d8146351fd909d6fb3743f +1367000 962f40b77e22bfe25904095e6ea6394e12d7514de0477dce1d4addd1d6446751 cdd06a2200640f4f0c139903e97c69cdfcb27784d6527b6b2e61360fa6405f91 d67e4e7550776c748c563451bf98f23c7346efc77db14ac717415255ee424592 +1367500 3f0994031ed4168548003ae429ee8c852a35f6de73ba28b1d019ad0d30f1e98a ad884d324964b4071a890780e669a3958a8633c725ec047cf68c5aa9eccca305 e2883086e4efd4b01f8fd4a70cd5e6cce491f3fe14de80fe933ef3e993ca3719 +1368000 4be76ef559c9544e0668fabcc76d4af327efcda792b5540ad5f4d877a1278cae 4c28a50dc5f11ff56e50e1aae05fd64f351bcd58a8ad88d5fcad3a8ac98803f0 b7c73f488e38cee6084ae007214fc7af93be1c763f1ac00591d41d7e906d8777 +1368500 c76240472a4ac9920940353d65c5ebb4d61e349076179aa27d7867b683faf6de c8def91415ea539f8613635a8686bbb59defe4a49148dda8aa29dce7b9caccc7 bbc6c21b9be1e45ba32711470ad80d567be0732eca335eaeda406ab3950e1706 +1369000 3d5e5769fddbafb4fadb319338322cc8d21cf8f6008b3e1bfabb449d503b7681 596efc6d6c59be4ec01fc472d73ec88c727b7944afb9ef851ce1241fbbe29ca4 082ad282dbaac5719fae620d6f17bc23674fdd9cb173d6158e68a2aeddf4e2e3 +1369500 df3d052dd89cd6f13c76454a5dc501a304143b3cf865cbe660a1ada94b45fd09 9b16c27f1aa7a2bede65e22f052fe9a440412f78afa59abd2d74c459a7c0980f 214634977984294cfd9e53afdb66b02fa64c27b3075fb69a8d059218c0213977 +1370000 82901017ed0a3c9fd170b22c8a3787fed742171774ac09e7bf6e5cc89c4e102e 59f0aa8ded3f030973e9a2ec96e6adbd7be5277850a9de8fd2fccff3d9bb06f3 7afa0c1ff8e69ae738ecb851b7b2ac0dc8ca7288d22ef44d12cf618aab82b892 +1370500 fe11b801da5e7f428cd13df2f1f21a56de1cc0f6b147a0654561501409a24e53 2516fdb36080fcce7e2c1cfc41f72d8d953cb005c47a7086dd64eb5e8bb3b9ab b87df119c0f729d30ba2f47c8781ffa71375aada7676938352fad0e2a1060c58 +1371000 e42763989f9c35e4644db2f1dd3970b0409817a73cf511e19d81a1cd69da20f3 2dcc7126dc05d375064fb213ea7a4989a05c8af81105dbfa2d29a0f6d37ca511 f180fade9a2f89ec00ef9055eb7b2b8db05a1d9022e5f05a9a5fe0250bb517a9 +1371500 7ddcd3c33a18db03ed734c2b583cf6fdbb258987711f3abcf836c26cc5cf1b4c 8a14fc9e85a782911697ae37273b7f6dd97a6247e218e7bb3b7f24de39a05037 67b6dc3e02e509907cded6fa65b1666b7e47eca3da28429ea35591782cc34d3f +1372000 709c19f51d172d312c56ef54bc785e32b6737829fbaf445b704efd5763ee36ef 5b2b82d083154c4e8bda21f3cc331c00266e314a5843bd4507e901aca9be457b d034490e45370ad0949cb7161fa7674f90d155ab0ee751e5ad82813fc4f14a55 +1372500 6646e0b458172d85a703c69817185a9d4616f257d3e74ffe25294f48994981fe d91fb8487fd9f865d496efde1dd741295ee5895acd1ecfb8dbfcaccd7a754068 78e58797920bbbf46bc69ceddd3de83bfa0345347e0a034da8cb819054bc112d +1373000 2cd773b180fd742cc31b9ddf96cc0061d43610fd2949a77b9cd6a93f8459f36c 38361c67a77e27d29e85f02be732b5f41971807b8887641addde9c3459d7badc 6e670df912b6cb2ea6d1ba05ba0ef8d78034e431b7bbf18b55f0ab3ef10fe006 +1373500 003405687c50009893335067329eaa341b128dd41776915e15de96273c1c939e bd893a9459353ae34f98bb4ac5ada0fada86aa2b076f4a1b9dca2f7f1d55ca97 7bcc8ce71cdbc3e27f52f31dfb94b60191459b3c9327ceab796d0fda53d75324 +1374000 66ebab13c4df35b8b50a127e24a713532e065864d104628a89c821853fdc02ca 9f41f9a5c55a3b3a8943b95534a6e89a32bcf458c947ac42e49e90b7a31402d9 95f0fee55905997fd1ede6bfdcb4f589f658b5c07dc81a79ae2e6c5b087f22be +1374500 7c51fdfc1280a845d1c292586899486e8b9bd74ecfea6b0c7a8866ee4193d815 560ff2ac8636db352d1b203cb460b3d516c17a51596dc4f2fcf9b8b2fd58982d 4a7f37f746148e36dcf40393384a7b191b5af3b88abeddf905a99f8977f75946 +1375000 8c1c7ad4ddf661b6696f09c5a215fcf5fb580e6526fbcbb1d56993a05bd9b395 71fe38608859a86b870b47a8d491288fa7d3ad049f7dd2b08e6d8fe41ddba7a3 1cd49aedacddb002f579c4c63b1ed4269b1aebc57423f56db1cbfb9854a1d6be +1375500 131362b82730ed11258dc186a69fba50942190b0af2cc9916290ff03ea128415 fbbdb2968a466b45f38590430297f763b5788c1837b45a33f514da32df05233c 0a246ff865614f6b073f23fae939d0b33aa7e731cd305195302fb7b4f9d75f6c +1376000 3d0f47dde43a432a0ca6bca020e6464e47ce1e47f583089a22cffe57b8bf25b3 784b1707faabb0679553ca65133edb80cae4d0675673ed3aa64412610b5ee0f9 540ba1600bfed4230cec6d72386ced851b664893017bfc9a61cf95f324f27a76 +1376500 f7f6daa3a21379733c6db7a50ff0e50fb01be614e0104f7f7a245e74cb841409 a095a6b397eed365dd40f6630ee8ddb2861624fe9b09bf3a6c3b6ee3ebaab5bb a8d92aec31dcbcc781a5293048e73c10e66634ea9371741d86c11aee4ccd1119 +1377000 fdffe12f78dca9729fbce3738e670c5e06caba1297bb60433660bba40cfa536f 83617e218464a4e588996764943c7d99673c617749260fffe93390860b8be234 8f22f18117baf3525c8ee2e118f00baa91e9e8cdd5372bd88d65eeefaa1d71d1 +1377500 53677d3f2433ef6b8c7a21f8b5378c87477d077c50c5c98920fb8379e278b6ad 7a88f0a4d5b7f5603f7dc441006bf1d696d8f922ac99000311a6691f6b8c37ef 2403ea937f3d43de564ee2d47fac12d511c2bd3ffcf19ea450016f6c2c6cea42 +1378000 059ea3d05a44144a98f878fa6d96e7a42966e54decb823dcc8c831f959accc2c f9f079c101c061acd1e157da58643abc3f4c57f5f318add638f296959430aae1 7b7339aefba9d1b16985e38d6d2d79b9e7eb741178690d55938e86d4cd6efcc8 +1378500 757ccc07ff0cf1917930c240eb998b3e8639e3675d11d3145f8af10f8559c02c 16346ca8e19e8a8146d7a5f2e33137d537195cce9f93a7a3db1e8bef0ab99763 e951d445d1dac492035d383d6abe1d3e91398edd3a5dc5ba891236adea8092e5 +1379000 5b36b30e7b6e80a37a03ac28feb2737077d22d049662b2d9520450a0aea88b34 b2f38cf9fd0cb0120373171374eb1a73bae4759874a83c07dd93a3746f2da967 d05a569fcc9eff6131318eeee2a079baeeb3c5832031d50a6d02e9ce5ed4c462 +1379500 ca6e2ecaa74a026682548eb0391aa64a778898327d66daaa397e9309f0226e18 974cbb87f0ced5598f43b2b74627b970858f168782e911803e74b253f091833e c20182944b16fd862ea73ae4f2f01282ff9a9a6fbda4c9673ec3447f73697510 +1380000 29df1aa8089215d19e7f9d97af769a753de3a1927314a98e4b66849c0d85e441 824abc7c2328e5c6d673b61bd395ce6f08ad4d694dfaaf06f5a11f27eae48a5a 379223f228185396aabb01c490f627cf6760840c26ba08cffca50511be25ba97 +1380500 50ac8d86f2272a3e324f7cfc34431ce3b2408f1f10e1c9d6cd676926de65ed7f f328142c777c439f93a41ef439efc9c8171170a8cec2349edcb73be476b0ea49 6450fa80013359ebbcce87bae9e3fadb6e1d4c760c1290fd143e623a8b0e22b3 +1381000 7efbd8e797d71e40598cc589b6036119ae31cf3065aa9a50a2dc31505e954d44 2969968c2995555ea8cfecdbfeed2661178647474a419407431ec159c819e5b6 64f966553c9e861612487341b68befd2d76848746828d1200f3b5fb6c1a0abf6 +1381500 18f71582a3fbf581a54287cf034fcdc338b9919ea3dcaf1adca080536dd44518 52b1102780eb1580f8f95f23adbdc9ea1d6fcc59ea1c9a59b39bed8c9d3db2dc 65664d2641979bfd545273d4d87e977516fabc7656bf8e72c65def85786e60b4 +1382000 f04eae4da4c932919586b83073c6ae816396affb39fa3c9e7d711c477b0f4f01 352c6c912943151ef946d6a63dfd1b49b24723c2cb8546ae576825fa206eadf1 3b9f36f62b618c97b525902ce25c60b78f4001876ebb395f2837b6685d028875 +1382500 498442069527d31f5e1869dade38cfd68f4af9bee2a11e8fa5aac53876c68f5c 9bce2522d2b6d1842945b2540982b67bd25a37ff35254ef804762d0e8eda40d7 68804cb18adbfc571e404f00c6eee9bccd2d34d0fd18528e34473edfd1851444 +1383000 90bd1f97c316355252cd4617a74de440303a4b9ec1b43264f9cbf122af6da728 00c41045f4aed48883018d269d0bf9a0af83cbb2ec7dfadb4b14054b85620baa 4cfcb71d624a7c4ebd997a5085a5000f6037f0b789664ef389895c8d070d94b5 +1383500 b341652f777e89b7c10473ffa0edb6ef32b9db3a0cf5fe834d14d340c0f501f4 2928e5d89f96e6b0d8f72727f42c5f27d7ef64a642709cc077d3aed5f653c3d7 e902bc0795797ed241da559ce937080939a0b0a699c454fdb60027c560019fc2 +1384000 8e7d3bec636dc0efe2906d5b32b652f1b8c63e307cd1f8f9bb62dbc8d3f91482 393933a6071fd7fc1cd27036a6a0cf5d2c274c8d19288df155974c4d16e4d7c4 b348713e32486cf429016011cf9fec82b7d1b1cb9b7533eabc934b7436cd2c4b +1384500 2524e1055ccf52beb59f566a6df92967480b440e31c72cb595faf50aedeb7b4e 92721f11c246e0dc123708f3ea3386e2af7d658bed413ae18dc20ed071804cc5 1c32df272a02cd86a314c95e33cd42ce287ca839229e9d98341dc1549fef3a12 +1385000 a3949e937db9477b440924d17eabba6df130315abb48a1a0cf4c376520024d8e 8ba0b50839626f009457414e892b0ade6f6391330a7de3e52ee8cda8d4d14843 ad2a7b142901684c2cf34808fbc507938b8e94abe8d907d78f49f0fd04e65a45 +1385500 7aed6b2bbc64a420adb2f4a876d8700f95286ab556932625e2388c86f5e64ce1 5906e9327170b4d080f7da835c01da4b0dc4c3cdbcef6e15ce565eed5a34522e 325ae8524ae0a48f53e85e0a064e5877bd24c21b9d48eb2ae075c71b7506a91a +1386000 635e8e1abdf01c40c5f68d897dfbd5599ffd8b306f4f12582a8beec39bf72b69 e32c26f7f6b2fb6798e29dce76a3b4f7197929a52f79ed1bbe65a384d33619d3 71d2689f8a01b81b332a7ab5cc31f08de2abd433305793c7a47ec0d4e4ccb7b4 +1386500 637b7737e58ab3d29f10eab76a186e1885fd47a221989625b82a35e326d145a7 f577cd1255398c716ec49581577a4228b1605957efb97213fd72af29fdd05919 7eae923d32bb8c50cf56fc9b503146a4ae8a6c5428371892624ebbf6e7d32d29 +1387000 d5aefed45fc4bea9b4bcdda1e44860543a878c2543d6546aa00ac9f503a725dc bc5e3ffd23093b15117ae932b3ee507f0c3a028e35e13ee66a38a933cf14498c 43c30f22a4a4a3ab3cea65424552f1e0e5642cd27808a8ffbacd300d89e82e9e +1387500 c34f7f08569aa435eb7742511015f03b73013118df4829f69e61740d35243995 cb47363bf5ea2f8327beccd1736b90c6b6cd6edc33dc3711de07bdb729d8e364 3ed742a1c460bbbfad7c6a09f1ecd1eff9b5fc724be35e1296f847060472925a +1388000 ef335fce6c2bd02b80af60285b4f0831f36e4fc365cc99302e55255dcaa854db d1fafb75a76ee17caf145e0c95bbe1418d4beed03e25ead8a346b960db22273d daf51e1e81cf641f371d57dfd8ffd8cd178345b0c65a3e3fdc2a0be8e936cbb0 +1388500 44ba1206fad06ca8f55cbd10c9256901e0418c3fb0e0691f3e809ed7fa6a0df0 1edbb4bc57de9959ac04262c845d80861bc5610b2495964e10806b76eb42a4c4 4c24f229f4d38192fba827e16167eba98f68bba783e2bbe0ebbdb023370f41b0 +1389000 605b93d26d873156688df6136a526f83a8aeef557011bc8059f4d4879c1f23a1 3aecde0b1a819ce476e787e271da0ba15b709d796ea7b1142bb6a08db2f4fbc6 f3b27d8eb85235c72bbbcf400f90c90d9932e8f8a2e92c68328580711c140cfb +1389500 ac7c64616575385bd276448132d9695c124a046ed46135d75a8c40a2193f3f54 d0515e04bad6b365716fa2943bfab9c39f6def009b785ea3e996b2d2b505bf5d cc3911c857f4b72bc693a5f8829c7502e8d2073442b18a13136d25c9277953ec +1390000 a306ca12aacb491586e34c6aebbd4be0054b193feb7a4ff2151b702db8ca73db 20abab754673ebe7665ff38f05f18d1cffeba2850c0ecd83e3ea1aea1598eaa5 8e3920c5953f603d782d0eb27499b33d7d6875efff42ad5938f523e71a78a41d +1390500 9941411440c5ff87e6c55de41b31eefe027f9a0de2c62c0d0267c1e2932f1396 dfb99ce37b2622d27ca46bf59d5c5df6752bec6958a6c5d088e6058dbb2c1410 5f4b85e4ddac5bf1928937b28070a9e1e20d57637c8f6ceddb84303d92d3f6c1 +1391000 0245ba8f313f627ffa804e3f0a7033d04ddd6e5a67782f825995c501cda982cb 7c77580d8bbac2c9583f5efe19e99ed0f5ed5495f8a4133e73e4ee9e6e5b4d44 4aa2fc5935d2285aecd8df81f429793fd6e6daa948a976f704d9ce696de9f016 +1391500 f86d824dda22a04e699d8351ea69d65d2c22825d3629fa7646ab9012d7a4aed7 d45a8b92a0ef4d348df77c0d748602d8b22a719d292029ae58eefeb2416f1806 79abe2a4a8dfcb2db8de877ab501ec2b5f4b4f2830723f5583370522204e15c2 +1392000 8ed5a8b8af9cfe376e62999351b8b364f182fea13af8a76dc5ed2d9433a62fa3 108f435ae8ce87adee70709514a024f7837c4c761f8a21690217e62e7b202564 e5da41c595a5c816a7b071863aa4d9a8276b0a344941f9a22bc149a699c69027 +1392500 567a3b3aa608d68cb04e9556562ad795e8fed26e390093209a6df669534f7fb7 9d22a222c28182008061f428cf6fe962d1a2bb47b5dcfbcf6f6793f93f3bcece cd49f15edee14609f504a416effc63a067289d5162de1d6b3a86813535a89158 +1393000 cb4c92e31402a34d755675a2e0d7a09dbdf45d6dd47f058708a3f74f15c2c328 a8f0f8d9614f6800670cf397fbfaf554c6f5b942f42bfb302c2614098ebf2441 157ce92b0bc9acc24c4a3ef547ddb558a768d5fa337af39ff25c6a1b2ccfd47b +1393500 4ec601ffbbfbaf55fba1be3787ee263cd2bee49653e4de02c31a4c15889633b3 ef268c8cca69ac5e9e1305686d72771f9fce19b4d18fa03c8df99d59faeb30c2 0bd13f7369506d884ef9ab1dfe7759aacca5005d4ab72579edc4964682968e61 +1394000 8b3bdb74f77eba1248ea7114edd15905c94fd883f81e9fa04fa87397275a647b 0d6a3fa98c56d94f7ce4b9fdbd800eb1bca305c612b5a10f971e6b274bc74b3e e0f8c19673d7b17ab5048f23b66745090c10895df2c3b39a064c3c8cf813e91a +1394500 6b4df84282ece1bac75bc13315fc9c3dbb1695e387c5a6354cc1181e21a3b0a8 26682914b5c1209da74e2eb42fdf39f93d3d5e05aa6b100feba849058cdde53d 6e46726b2fe881bd18dea4409168ac89f1d74b890df19aee9eed0b47874f5745 +1395000 e8cc3d042762b0b1a346eb9fe5217d082f50bf0f9de1ec58a197ff0d2503c161 9fd20576f2944f88fb26dbf5cf55c2408b60cead32c5a221429c6a3c25f1d58a 0fd8b1278f5c6c080840196f61a8281866126cdd73ac79c4fa13e6ae5c69721d +1395500 ad149d110be0585f88ed92d43d37946a006138d06b3caaaca6408254df3ea6f2 7b21a1a28aeaf51ef91d60139b7563130b47a9c815e0215d2ebffdef229e4ff4 9a7a2ec4d702e6e72c014adf0d00079f2425777e9e3351fca969b86b791e0b0f +1396000 ddfed3648f113543a8121db4408a2ae06b31806b3b1523a8fa1e27f1b6d9b872 abd8bf2774c1e70f90cfeb2a3602ff36a44c309ae3909c23e6b3ef790309e95d 602aa3edd48c2bfa1a6fb1e1e3337f748601413b3898668b74d8a7179d488585 +1396500 57fbdc9b1f8ce051a992781530e611ac606bdbaa884c76a40ea57ca084513ece e296982a809ae0dfa2528a5f2d05ec4ffccf5714150f2b279450675f0cc86f5a bdd1b3ee9e2ad1e7ce39311a35ba3b4162671182037bd836a3a4d7db42d79739 +1397000 86c1e2ff806291362b658869da53158c1d0f4e2e6b3dceffbc3f1746e877cb99 014d2677e49ce0200f6ba92b6a3d56ccc13a99a7a590a1f2a4400aed20998ae0 59d8699c09d5a1c9a8fcc93d935d85926e5b7524d1c81649e5531bfa29ad6aaa +1397500 e2d2ef0136f84444717f9e4e7a3b957bd605d6d2329f39da9f33a28d2e32c5c4 949e57fe7f7f06eecb0a50a1768df42cdcae06cd04cb2a7a22ab7ee6ed22e487 8793ea706658d7d06b662eb120ee38cc24aedcbb5aa536949f02a03e6bb187d8 +1398000 1c988d716315f43304dfd76df87edd8deced32fac3a10acd11ff31af286becf0 159674f54b80192f4231ece388db32b22d9c01636d29176c9529c5db11f7c99d 9c1b0b608647218cc188ab844a03214e9798d2e6c56769b2e960c0ee77ebd5db +1398500 e9358d427737bf442b8817341cb966b25a4a65834137aeed9fef8ed02f4e51b5 573f6d20764b27ad008db0f5a5f4de00a111dec6a046131bcf69b79e537fd9b9 63d03eb324c79c1a4e76f59fbd08744c9ce1192cd7a5417f185c4b3bd37de377 +1399000 1a76362f98f4a65607bf15f39fdd95b32d8cb8cc8a997ac52c8684ccf4c01832 6453f54f195185f7b06bc9e13a7b9f01e1d75f892f4e36307e9bdb065a57f17e 7fcc1a4084174ef6344564982fe209cd1d4cf9832dabbe9312a94a922e271c7d +1399500 1d96abbd52955c2ab1c1958767b2f07c452e78f32410bbb91083adaa41a44137 27396fe948a950e7fafc692db367cd9f0fdd77a80658ca4fec9b119eff15fe3e d85d1108114f726d401d5767c674e3e82e5c7661b2013bbc1270767cee79369d +1400000 f9e26fb0dbd2829054b1ccc22440cafcbe5ccfc93dba5629205f4fc163ada5f9 ff79fdaf77303394988940c9a0e49609cd6387e091e72b5c957507940646b505 63b7fe7d2b95a1de8169326800f1b62698edddfc5c372a8895452a5f10e2fb55 +1400500 40f196700baa6bc6022a4682bd8d220ff56ecf6900b9bfecb3e1372488acf8b4 f2851b1b8e443a8e43e20f46c2cd211fc7efe7c75be4f5bd9a0cba95ed379abe 47f5e9bc99c0622e22be876d081eff785e177922ff7a84f3c73fdd3260844ade +1401000 e365daaba77c2ffb8d6b2e14061fff7615b5344763fae293d9333de96131b562 89ff19dfeef9bae3694f7e475d21d62956b9968ec33a17c4cedb62a099f70c4a 517c8829f83b7a935d2f274310a28a7cdd6c50b9f407d93f640f9e1d8fdeffa8 +1401500 6a560a76676d91c59aa21e2cf2d984f87101c3e60a2625eb7a438054f8f839b0 091bd3575a64bbee5da7a44c42ba2d46a82a48f712b456c6cefe57371331d695 ca8872683fbb0e8ba396f436d85faef6ff2cb9075b13e3c514adc6a9c3f72513 +1402000 62e2f52a35c69728af7b28d9557bd2dd10742589d8800847b3264d865017be1a 8973fe4e9b4b2bda7950877e0e3e67b03857f39c9c040fdd4cc81d32921cd137 8215ee6145bc1e07819afdf00c33927ec5d23003e5a2c04bd4889dd8dfd313e0 +1402500 895232cb5997e093c701c37b123c689b69ab4f90bec0a92cd810212abd856750 5ae61f6fab15fe5a11905e85e469899453cc648bf59f7d94e33f37e70301a155 23799703c4b59a07010cefb90742f7d80df6f6cfe7ccaa3c6124a4e1cb602515 +1403000 88b55cea21ec3cd62d61782950e5b3563f3ee616d01ac3f88b72d8e28034c958 5032567f685ec639b4023b1ffbb11017f4fcb4a0435fee1d36a7d56ce944f2fa 8a2a6bf7420ff1fd77c4ff5006523a2e402bd84582982b98ede9a9e98ac650d8 +1403500 24b8a5636840a8a983845a420a6cd9e395fc10e5793b207c6924bcda91e52528 a5dc1ba6b9ce7b9762bea6eb69ddeefff1c2dc424d95379e1571a41ae926cf80 88d951cf6b865204379cc18988e537398fd2a7ba99da71544d3c348ccfbcab1a +1404000 fec3f803dc9b2e03c87d0491ee33b5a66bf68de499315cbcdadbcd3dbb0dd8c9 4a3c99af482ac1e4be859e277af80a59761ecdabb83f2396dbc4a0c85defd4dd 1ae5689dff2aa1795687fd5c5b17dbaf26879b8c07b651b307c7e4088b13a8da +1404500 e6288b72c91e6c69455d9bc42dced7a8be3ca2ebd5eadfaf4aa5ae41d203be83 2265636b9463376bf3ffb01c926717b69d103bc74a96a716ddcd6b07403d41c8 53ea6c1b6a4c0e1f9b023ba942717e364e6d074edd677234d1b3cd81d2dd99eb +1405000 b03737f29024ddc3844e876205e984ce3a6bb2f00247804a9ce4fc0f6bfc9eec 12148c0a89728eefd046abb7037a1bb38db8237586b7ccfa3eff80f31af4e069 f135686b3992574c3756e92583e89bf5e91b93a1df5528eaf162d7c161d3b9d2 +1405500 747824fbee194e1a5b85c96bc65c7af925ba6f648333f009a189164cbc3e1e21 be50d9853853596f4ec24da4d34dab2b54a854e6fc2bdb59e2f2f24323eb6fb7 56b510a6f97907a7b69e4ef38aa15a1057f7ee16f98dcbee34ba767970474596 +1406000 f817422a5052185cb6730097d2bc8511663a4bdb8429a33ada551e5cfcc6c62e da2284709ea49063f615345094be82199fe4b8c5c942324f058d53d918b2016e ad689c928dcc83eb1605f449dff702f5fc2b0d0ded5a49ad95d766ffb7bf00c3 +1406500 e9644dd6a0c430ffd8d3b4399ddcc96c11c2cf26c14d6d7e4126bf57eb8b4e8b ec4febf2fc289f43698b54b761f90923e48824d74e7392341d2c1d9d9d6555f7 d5426f0fb9b399efc4b1624f336434738b0f91c4a9804b4de17515069eeed6de +1407000 eb6e504aedb8afc6bde01ad745859bf845792aa93114a3694938786281c0a500 86dab15c1c415b66950d165062e9c285fee733d56e83f698ed3b2861bff1924e c28159ccb54b33d975e30cc3aec2d9896a082606f9a848a56f6ecafa95269c10 +1407500 0f381161a4533d5aec9e9030344c9fe8e208d2a973e22e8f4d5c88337428cc26 302d82ba0dc4c30a5442924631dc900ac8d812b6f6d8a292b885c0154157a946 88256f854cf7a9dfb8e7c5a08da513966ad1912ff7a6da3f6f6277e1d1f00199 +1408000 16e77c5d52a0f98077a0926a49a7209609b5e455c3912c84dba8899cc6e1ba11 d1e0966c8061240fc3af36473e76607471783aeb352b8ef2191a7c3526b1b495 e06c478ab5ebf0e5322a40434dd97a686683bc3f207b0dd8d077169075d3b41e +1408500 fb89f173897a51df2495064e452be7e4d5c5ce41597fa36d4f9c72812bc29b7e e4142511b775d3f4ce513993ebe6239b9e9905e1844ff721f3c7d89887dde717 ab341240c5c3f5c28207afa6efcb87aff423913d9860da66de3b9aa2a11db40a +1409000 6b1e74580c47b859243cee2e2937b1e7402f13a5808005c1fa542e89c3fb4b91 4d87ecee76e5fd1e14eefb1696b61bda885bd8667f11d4ea8ccff4d0ca01b394 4ab7e430257185ebb78ba69baf775a69ac51e5c8644992963f866ff9859d621d +1409500 950fb96dad70cf53850d92f78249bee78e228bbd2b946690d627bced8564ea63 852846f21fbf8af1443d919fc7b2a1b30ead6aad18098111f2de2457492e91ca e62e4e3db06870261141ca32bfc2ab2ff37580027ce4b93f5ba4475f139c9fdb +1410000 5a9cc3ca5065fd7d7a4dd74a370b35b7a19a218f79a48e2ec4efe25da41e9925 7d6f9f6ba0ecec30d7f6c1a79e0e6878e420a7af8d13046c7076f4efd570f630 9d76d49243410e349c36b144db6ea0c20ec1fc5d6289581315d1d87a2992a7e5 +1410500 94e419b37a6248dc6582842f9b5066840f274bb1a370a4202a008feb2c194a9a 9db315b6c1da9d704471326fe74eff7cd2615ca7323e6d690ff6b67a4250c049 a1f9d451fcf5d461648072d745694da9ff7918361b61172294f8c5a6db744027 +1411000 cefd4f2796001b36486a7c34186b2d6571c8ed644b3a95bb860f4dfb7789e5ad d8b16beeb89ca63dbd7a1966e415c95b7c88e9b3f44d5bcce9901c7ec3e8d913 dc26017394cb7b7388b1164be63148ff523856abddf3fb07003ef0f4869046e1 +1411500 d78c92f93901fb5da49d5642f61939c6acf47ff7b85e46be897fef77639fb86e acb9740da61a9c14b0b2c05f24f9139c44b12038f01d6e21e7870d0d329076bc 496d9c617b149475b1582b9c72058d851fad2578db0b35bf10a68e205fb8ae19 +1412000 ccc9ca6a3820c60e954cf1ec056c081e1f7efa0c17e42b2b9b25ddfd1b49da99 a1b8b5ca39d4844d3fdf89a45b634b7843b5957d61e256a7c6875ff9baf24db5 e05296050ac70909e3752d134971600801a454040e898861c506eaa829fd4b1e +1412500 af71cffdf5d5119bf2aad25b61e190bd6caeafe6c1a8908a4bcb8bfbabc3163f a6e63bf39f1c63b10919b557ab99f83080e165e837678148f675516a499424e6 1e9ed36915ea31315e8091f2ab8ee7c106f325c998dc9b63eaa452f94104c47f +1413000 a4c932111c3231982f96578e64babf22180a76891fa27d130baf3306ccce2e9d d7dea9fc0df8fca7889f93b6cfa5c7e5997abbfabf6a9592cca2fbab986f67f6 670cf68ed5e622f8c272f3a970b0cafdce33819c7febd56716a40fe4667fc50a +1413500 b8684d7fc2520d819ff714d60bc508dacdaf09f9b1df2b7a84cc3f066465eb19 fc7a7ecb650810e8edd590838d9e1bd3006b4817aebcaceb810442614ab9d663 9cbf74c74b33e156ed3e82261cb5fec2d13d58be8ab256158d6c437f294b9071 +1414000 1edf1f7ede292d4585bcf50725138809a78702a84ab867625239733afd3fed7c ad1936ff92eacff610bf29052303e097c61dadc7d7726aae52ba1d47d4f47acb d4f7646d195d176ca2f3373098a8ac118863bd45b423aa055df8338d4d9ade6d +1414500 505fadec80815b314303496dd791667f44632831bd6b36b3bd2b1bad83c56032 1794a5aee791877596b08586bb535d9c15f497a5391b1c4c97e5727cad42496a 9a73c6f21dd4d555403fac0b8bfd984da7c31c9602049ac42c0ce9fbcfd8c3e3 +1415000 a252b0c5e93c5d276da13715f6f3f781b6dddfe7021feafd41eab649fb42b029 918f9133e6efa7d67505d9592bb494615d1626270faf69d3b1020fee3e5316ae aaf0ad1223cd5315052e97d5a616a8c9d4d4fe4862c3d2cf5233181c0fea9630 +1415500 28c3176d903b9a18b09ae776b9e3a4fa731651c94b70b5a7accae6be798f6560 9fc07a6757d65e9dc3d03ec1ac98d53b37e31b96e37975b75e5f4d2d63c1abfa f1219feb096074bb1f21218d2d93c62cad06c77a2a36a5566b860eb56a806541 +1416000 89ddd5196ddea6682607095e9be7db395712708721b99aa9fa1dcfbae4497656 4213cee15df015b0872f3df661dd6876d134d906c23b8a37642f6882559fbb69 be368631e8ada4a543872bc060ec25a1acd762313bfe89c9f954b322c00e0a0f +1416500 6b8637c56f7b9179dea71bad981de70b3e83e2fa4e73301a76abcd092917bbf0 dbd4a302d26e4914e315fab898a62914ea41c17a65197897be166eccebfad01e 15c11cefccccfdab1f43b5bf7aced83a73345e58a594f8b34fceff7c5d11dccb +1417000 69bfa2ab9d8ca6dbd25043fd101c11d900c938e8d6b3041e8a7fccf19afbc15c 840a4375bb66a8495b04942e4539c7ef95e1849a83bde1f92fc6509386d4e045 dc0c1d343a98607008f3662d4dddae0e8d98210014b9742ed5c83de7339d7948 +1417500 442c09939727b080b88068635a6a81a7bcb26c3ca250d2e3397e99078f1afb9d 00937dcce0bc05f7a1de57a00e51491c6c0679512c8b4f800d2cfc01e19d3f01 b7155d0f396bed1fc14d91d445f3e3e9ea83e0863d358412e000787c877952eb +1418000 3569f30d857762670186132c4413a10cfc60ba623849049211e2a926354bb510 abf06d2de34999ac9509a99ac90263fc90061b18b84d4b3fcc93cc9f8e9c3dbd 6e9b279abaa4a8e56f62d5ed4a20898fbedb27e6c7ab21d303ae01e6cf7bfd24 +1418500 9627283c27a400806e40514bc7e23d29d8275d3fe58b08443523762a0d75d2c0 ed6bfcf4f1e93f1dd55fbcfeb3d3079a468a0c0b8ad48cb6c0e3d9303b16cc43 d10994a1a559193ef8244104168322e8dc403fe5a8667266edeaedc162942844 +1419000 4087787e9d1dde73892bf97e57270c5a8e173032f61a12511245ff7206fc0702 6e7bdc5625ecd5216b0506975a7e01d4429a2ecabe8c4598e584604ca8ebd28b 6c2711691a6787aa296c9df32c3e8af8879fc47fd739e8b4337ecd9c3b2c812a +1419500 f7d5fb1fbb507e4d294633581498d65f40fb5f91f4cfa4652d6b6a6b4a525279 00dd4638b508372ace47a221cbcb2fd364526702149aabcb9ba3c295875145b3 d61825d60023b4e5945685999f9f8dfad60a10557c1fc67a08f872a67723bd1d +1420000 dd22761d1b73a565f4ca27ac4ab5099d79a76df4bf1a8e684fd52b2ba65c2ab7 63302b06b5813e334db870366e09531441d7b0c2be27865f0d7a8735e0c7a75b 86ec4604d63c57648ab1da44731bd053e9c05f42ab4a995171d2f640d34791ec +1420500 bda52e2e5ee20f4be4d26e13047069a73b8d4b1583aa841569950cdaff4c3936 0d952138c239850ef703db1b323c45383e7f749a794c4e14d7654823716d4f0d 499a6b254d6cb88388fbff81fbaf9f72f014292a70e3802151466df04e1de038 +1421000 b537cb8fca3b686801558e74a9567638b5d68a1a035466f25e4016d7c7b544f2 772f0d7b78f44b1fb9019d50ec5037dac9c2ca751f1cb1db01d6817cc06ff52a 1c698a663c6b60843483e128a56554b226a32afb45f10f576212590bb15ede26 +1421500 acbc5037dfc8634454305688ba48dd256bd01d03f664a2c012e790df38934582 03fdcc81a4f0c1f1632545bd9a0ed349722b7e1db9d4496323d5c458de313716 85e91d7e68bd175071158a40cff6e5f2e952e9f6293fc1a7665e9e2b748d8c9a +1422000 2a2404d5bf4ed7399be3ebf682dab483eb9a8a1c39bc5a21277d12c5358f79fa fcc0acfac4e6f308fcbfba4085d423d405219f6a2641aeda59280f83210b2bc0 920edc7892c4861d47e93111dcbe8b64738b8194c668d9780942b48dce4e55c4 +1422500 8bebad21e607fbe48f2b24901c751802990fb9d6a83819f271b9557e7df629c9 5cc828b84c48015a2c59f74e22197b5d5de858b3c5d91eec995765eebba8d9f3 2cf2007fd44150d4088dd1e795068294809325c177a3b102c9986379ce3c8759 +1423000 238f119f7d72b6ca3bf57a296f21c2682998a7f26becf810045a30ac622b8c88 f95609a5a5fa40b8249005e820a0ec5d9753849a1b27c30d357d91eacf28a225 277a573c93f775ddd2efe788e75bf7ddc9179bd292edaf5fb1a9ec16fa85ebd3 +1423500 e549e71c042568111b1dd26f0f4aa364089f58d9f7bc06bfc39080772164c1d7 fe38ba05da5aa2171c421da54c185ee1f385660f589aab5c7e37e53f742526a9 a8945d2b5df103ddc46663c5cdc76776870c82b60e55e3baf24a53692e0254d9 +1424000 908f2b84b09ffdc6d6059e1cc19426cf0cf04689da8e8fd616ddd8a500cb1a80 d06dc5ea71e6d1634bcc675cd0dc6e25cc87acee106c3979e42961174ce5ab45 60d07d83b9e22a6d42d5d7b18a3a831396c6d9e5abb65faed09db9189fb54e8c +1424500 0e57b99fd449d97a26bbd4d86741b2ab3dfda56b0f8cd089773925ca1709284b 28260dafb45e13b2603e4b75821417ff4bc65d3bc42447e448b7cace1c306826 a068ff4dec4c46024a1d0eeeb2b0f9def2ba7b64f5bb5c978c8d288ab6a14898 +1425000 f4c0f2b761f2883431ad0e7d460f02db2f4f2460506814e726a367f83e401cbd b4437ec16383d8477e0759b8b1c7dc2ebebbc42e5fdf95a2544913de2bdfd120 fcc245441110b6fd3ebd5079ed09a400e4b3c9fc48bd1cc60ebc66010c97aaaf +1425500 631484dc1954c331b630800232f61b9555ed3f6d728c8bc40972524c3a476fad edc69a1871d99dff0d288b5276bc83adf4fbe411c33069bab6e2793a6458a267 c5e736a3d2dfc69405420359022ba0970abc5d7bdacaaecb9ad000e5163f151f +1426000 2b0e0bd0a8be000bf4deeba707590b61cb35b7489cd0e1d9536e0954dd5d9d09 c7e70d1d5efb8fa65cd25cd6015287b0eab187787056ca4e61face96ea82897e e9260e6e7490492bf6ba1a0fbc0b9988ac68dce1e712d0c4906f401d02062ca3 +1426500 0e333061d2aed1ece13489f6d9576ca3fcde54fee3ec100ac9cfad5ea755a579 5d6b7abe437393d1de65d6121a11497001ad88a51169d8f4f8c14d64b0a5b0f1 e9edcdb83924a9ba6242692cad08c001b7956cb981930fb755be8e7ab1c08efb +1427000 155853390fdadb3016de47cec48b265e34dd05a0c231f23b8957f8691728957b be61378bfc79b53a70223b482da9dbb778639a7e02f50cb4fad9e2431b17f3a1 9ba287e29e162ac4ac07f20a0789bbf3a8f63d293264938225685990456aa086 +1427500 4ef233e91a68ec5e048effb6f789b38231f73d3715ad5b3450c4047579a266e8 bd4a7c513bf4cd6bc81aec7e54b79588e418c77c9f794ee2b73a73b4a78f54ea b37df2b891571415dbe28738935764d36aae84902f8509c24874fbb925b0c81a +1428000 c16cdcda8c2dd8040eee589ab330fa2c2e1b53b560e3398e673892635c0d1d11 e2062775b080da9730f358c9f01554bc963b567124bdbdbe6b41a490e0a4f1f0 de8799c48a3be8473ce5a7d89becbd4ce8807fb31776416b692d4fa3528f17c8 +1428500 6c6756c99c78d1254cb07f7742eb79572908a8883e214717ad966210db49d6f9 7aedd6635652bdf8e2dd73d0f22ecf59800b0d7b48ac591553138228ec9d0ad5 fab6fae81d00758862a7e1b4d6b7c5a8088913f497cedb04360a8793cf638dab +1429000 3deadca463352d194e0d69f188d2bd97f4eeac2675b25356c0825c984abbf550 966232fca020eac0b583094a12c3a4f95608a18b09aee7bba50ae5b6a9403632 a8186ab3bd4fafdafebb46ec641db4de1b581a6ada5165e132854119ec21b3c0 +1429500 cc8f4ae3179f3b115e958962937b28a8f4360790efee2f574f52af7dffb4c418 10ec6991867cdb513c13a54da1c2a315b69f794094a4aecc437bfb824e18fd46 7303c30bc8fcd995c301556ac3b73ce61ea3a50a01049f92782b033e404cacfb +1430000 8ccf175e4a6aea397173129a5425d59351353abfe8db7b11662f6a7dfbe1c43a ecae611f76dbafb22b0f2e2deedceaa174bdb9673a30b1e3642e31c90c8ff80f a3d3dfa82ce94c52a3688c6582dabb07c2d1cc6bfc52da07d8ff0e5ec60e8b2c +1430500 47bfab777e65563cfded0698b12217944fd76afae32091ce76fbbb4cc1acec9a 81448e099c4f58b623a7ac30b62fd7693a6784eaa79517bd9f184bd15df99149 fb911aec6fca2d836dbba88ebb36c2e8d5b622e5e2f44506b7cb91671b9f178c +1431000 c512baeaf05340a6901618ed5602d3ec17aa8780b74ef8b1d45ac5821fa62475 538652fef1ef20da1feb2a821ef4ce204d6b0b9733a58e984596d6357cad6bcb 701f198b89f486c82294cb166e5a97009c2f2169d57c144f1af008fd030475c0 +1431500 830980fbf385f62bb57e1a9497f814279e0a0fdac8d5d8ddeb6791700e0cef48 521a7a6b1b6fd9cced1c579438bf47b6cf1cb63560739bf93017b752b804213f 1f081b3ea0909343b5a817d0397871e93117cb7fc7051540f420aa7bd0c15872 +1432000 530123444b6f51b50756db5b7fb33256497933e6e8820995ffb67de6bf62d6da 62e70ab6087166fed055667144238499f945d41c0332badaaeb664283b095923 e2edcb575fdfb34de6fa7e32875631e7c403d85952b4983b41b383782227568b +1432500 89d4931de0cfd2a95cad523251f30a1119c354452d50a1cc2a9ba20db77a4979 3c2268583da5ab084ed2cb5ac325fb00ebdebdde211dcb1643f04c12186ba7a5 50f2f5e9e67d0c025b74f855ee884ac5f3fe36dfc278ac183fc2a3076fd738d1 +1433000 64607b1563371086ce294c3079272889817aa48f75e60a56a2fe987d8660c47d 6736f3c502573f24e85ab86858496947eb1aa33c5220961f89cafce5115a2287 e4ef314d31ebf61abe223d78a40e73e6bc3f2d9c15c9ee07dcec5dd6c3e2af02 +1433500 ba051e04a5321bdd8c93540faf1bff2e10fec58d60459789bb4c516fffa73bdd a3f9efee68212b2920d41620de824c04f6ffcd3ed0eedd689153be9df67b8a4f da056883a569cb9e125bb28c02d34fe6ac1e95e7a4899397fa10e616644da9e0 +1434000 06d79f02d0790839773b9e4c0716f15ab695f14acd6b519a6daed5edf6239952 6091477a4195e893fc4958bade0f6f968330d83372f830cdbf7fbbe985d7d776 7eda9f328814982eba286beb8ce74ae7030a21c9ff062d3167b33100302a10e6 +1434500 97a0f3b33bb2691273ebc383ff3ff941932dbda10ea0673b64ffa2937726634d ff189c9f7173979653713e349d4890fb93428a13d946ca1ae6f78e87558cd12d 7cbcad7555be6c90c84cccf4de96817d219196804249ba6fc2de203383a5493e +1435000 a181b6a8eb934eb8191934f31e056d1851e29d631f7ec4c1028d52a84e68f1d2 33f3ae459afc6dd97b9c4f8bb759645232b34ef70c98efce94f023700d719911 19745095f47fbced60c335d5261c22381a49cfb0d7aabc34bd804e137bd34893 +1435500 62d074eed0e303a37b9b105856ba523af05899dcc2bacbccfddde11313d14af9 ac6ec9a0fdaa1d86681be189d00352775dbf862c16fc704f7ee88827126e97b8 648eca2ee1947fead88e1be9a9fbe0da21a12876dd6ef02c2f0ea9fc20a29c0c +1436000 3a3fc0e3ad84356251c646cbee2f3074b655fa3abf86315aaa7e957e01eb89f8 aef0cf31d538101472dad0d9d27791344f6fff964c6e6480d950814ae67b32a1 2b450f2aa4ad70c885fb54e2a1ca7489944f52d8c76b554f5eb7ef17ae39e096 +1436500 67e97cfb940a36a8d0099609fc76c6e3267b8c078eb20f5db25cbec0a90470a8 8a8004e415d4716355706c61cc16a6d8647d3456af400986935d01c051af130f e66100c236f17ab8d55e39b33ad9d2e72c02f6b98f278022e421db158fbf8f30 +1437000 7a1eab23011cdf4750a2e244a4e112de8fbde5c8294aff77927bafc9bf0e1b79 4b453da7657190f4f8eaa6f6f0ac8f061f232c3dc05fbacaa6f89b66a451c337 ba736e7bf4e5de2580869df81b80b0565021b8fde6b774b0cd6c2cecd38ab648 +1437500 b4251d0bc343612d5c8d3cd638584d81ae0b7f925184d2d1150f535faa664a01 70f2dab5062ec44432eba338059c00b3bbc112519cc427724170334b767fb3b2 2f23c3887488d58b9d6456f5cb930ec0546e1c6dc4b1a803e979711df7b15931 +1438000 d4390d7f2f0ec4883d473767463864dd69c0bd8eaa7ca7cb18867b3923cacf18 d4e07f34a01d790b55f605abee418ea71aed892d8dc6cafdaf540a30c456f073 c43543a673936d6e692edf4c8b1cb01f00e7b73449981580146e082f5526c4a5 +1438500 8a85c0128674d310efc2a41d18ce8216e881e38616bca7afac034047ab93364a e9497b5258bdf85e9cf186abdf89c3a0dd8ddb9ae21f586ced31cd86015ee1fe f5f8a5d0ebd0234ba3ba7d2aa72372fefa75e6221ed6b64126cd250c729f53b7 +1439000 17a29d0b26aec774eb4b76dc893906dc377426c20effaea2f3b053918e5006ea 5e9f7e91ce552517c76b9113b4912f898df50351063ce75e61401f2e40a8269c fefeab92f5f7824c2311b2170e3ed9e6bcb8a870a8bff2cce14bc75c1f391b75 +1439500 7db69e969f50d9530c5462054cff19f5fe0991881004de027ab6a233e6ebcf1d a073c4981183fec6098f4801111ec36a3991e92776eca38b312d3b579b89bdf4 156df5bcb9a3cfbb679ae03f097631be75e149009482cf1f384f9edaae9a245d +1440000 a5d484ff4c1cec801c17584ca0b9d41aa2591c302084514dfbe451cafc35a0a6 59a3e81b5692b6dd36f753f79f5a15adced8547dcea91572314f55ce35b007ff 1927fe143d05851a9ab37ed19c58dfe24380912766bf037e13af87e16cd8b4dd +1440500 351d93c828ba55dc7ca9004f041b77e4651ffa8fb709f19674545f3decf1cb31 01d09cfff0d8638e380dd4712325b76f79c63baaf7188b3db65040ce759095c7 02bac99571a8609d39b19687ad7c6da67f61e7b8849b9901a6f020a794de0d8b +1441000 311c932f5138e514f2dc51aade69c1d0c149dba382662492286a52585fe50f40 fc2113148b992f7714e4c520b3ee8cecbe1e1ab98341b3ec4bcb9a149e3b8adf e8363da245c0edd77a2b8ed237b2fd3fecc6ba210d986d9639048f8ac3fdeb64 +1441500 938e5bfaeb448f696eeb3284099c7a35672c11b9ab0e6927d3e7c91b546c315a b3c64c8c9c06bec1c5e546d2a0ccd2b9e136f700e3cd0afd3c47494170869994 d3b346a8c5f39b0b7f6ed27b7bb768d2ccc39e5315c16b3dd5df42944c501538 +1442000 6ddfa0ce1b862746bbf7c5f360f15424f92473dd1d098d4d7134801fc524bebd e2dfe2d263eeb82f963e284ea5b2195be3cc6cf2f331adfeb93dd4cd5066103a 6378650456bc2bba3bbbcc80a2b948aed45b117f055acd9c77fe42a6cf843c92 +1442500 cec826c204c0605f364f60ec6dd2f70659a234a25865228ddf4aed06bca6a1cb 1307e0e6807f145440022ab47b15a96001dc9a8a7b20e33952e129295c20f64d 781ba7480b062d4fe959f33482aa087ab65c23a9bd5f2ba0b4694ec2d40c90d9 +1443000 dc5cdda49ad2d94cc9eca875b760d9cc8233fab867b980fa3ce87ee90fd1fe93 8ccb9f0fd3b4ef99e1795b68d6b5f73574a0d1ddde2dbb5ece5b7adb0539b4e7 bcb0780aacc7c1369fb4b1beccdd9e464aa5513148544221423d5e52ab0762be +1443500 cb846a0e2f0a0f9a69ef0c76ca60af5692af0d8328b43f22a87dcd37be25c2da c920304395e59e42024d17f7877ccfde35d8ce35f49f2ef4e3e985694d9cc32f b20a45f237ea4d47ded5d5dd63d93c3f675cae6de668c831bbd2d2ba9790e579 +1444000 aa3a8de70f1e4e852afb0e90352d6aefe5b42f3eac4ff4cfb71ca92d135648bd 43f5f5ad40ad815e9c798db6ccd1d8ea2bc94407cae7460c3fd0006693cdd386 babc698fbfa13248d167469f0086bb75a03defb83a71b2d6dd485096d2c9ec64 +1444500 0ff67b6e4e9d1c0bb33ca5f3a43f56a82b5f45973d0812322bf05acdd4e5604e 668d19fb710af5c8f13ef3ffd28edc631b2d7627173af78f115f86962706dbf3 c9e7111ff2e456b5e395d9679f90d207de4c3d7d7d9b01fe5df2d5354079182a +1445000 1930b895a740c93416b3c6d802965d5d0c9e4d44dd3ed0f31c5b810f4aa83488 8f9cf32c5da053670c0982865e492d4b56dc98060f1224737e392078b702946e 42d1f85c05c3d56382f56f2cf8aab1b3714b912f3d6d4b7ca373290cc7fff9e5 +1445500 135506a1ae975620e84a06a32b8c2f0bd00101301f547dfad1a3dbed4b794c06 c46ae77684802b14265a435e01a8815ef5f81d0fde51ba73853ad98082e50b7b acf00c3faa9095374e3d450b940f27d616baed7af45961565a769faed73fd1a0 +1446000 59b4c849d502a373134e553937eae7a06282fd430ef663f7c1c66338ddd68115 a48ff15ca965a7252a1c16e1b71a9a10e3e7b4cff8577c2baf1c3fac05ae421c 2235874e873e8990be9ad9a69df26072a590a7f59931075b195327d5cb20d88b +1446500 3a44611ab88a8e45c1e07228579459a85e88b20f04cdda43dc042525cdc5c21d 612c304274d04872a016d6427392b2e17772d15f0af3e123bff3657d0f6493bd 0d60f1452b342ff50c82c216edea74ee24fdf400e088f392de4cd40e4ad9712d +1447000 fa0e200d7f2face36826dd931290057922a3fae9e468cf4cfd59e43cef8fd97e 1c20b859faf1eb7c6f4549a1fa4cd1f0ebbf4c66c4e9fdb2c20e171e3a22a1f9 59230c440d0cea4c0621aa57629e289504b3b50bb6b5281cb9d70cef050217ed +1447500 892b8087a0af4907ce50e37290c902d3fd3c7f4453de8a5d842e57412852e6f1 bc3b1a6ed6db8dd325e00cb676731b6811a0f3358851002ffd1f9d5ed242a015 2cfeb723a4d05c20f38cccb137b5120cbb0e88948f9fb925f8da924b594701db +1448000 71725cab11e0a0e8c31b97a06609ff541322b0a8970f899ecd0718fdae8b52f9 3c0a8edb5ddda9d62807bd06a67de8d001a9c2485025ae2dd56720491145ea33 204bc388b8afd2acc05f1638c29cd5385aadfd45ec3776c0c3435ecd16f6282e +1448500 610d22cc89262dd749799c6999bcff9478e8edbb61902a88c7243da67fb5219e 8cc5a3b721e12c5d184ecdfe56ebe8e60ae72e827afafd3b6772f347904b5d40 d18d25311815106e8fd97e064ff1f60a9fb65117b401db354775ffdae9f03d77 +1449000 885c07a7d369e0a501ff5451c1cc22e514d8c5c7c2b629f0296d0de417112240 356d776ff481d2f667e2f90b07d81328fffe2934aefbe69c5156246b02eeeca6 42342ab0ca63305e2aeece9f93dc341b9f1b2f8a50c8e8fe48caab72823b45ad +1449500 9efe905ffde45ecf996158c405bde9466da88eea15031f63078b8d5308a5ad76 e6b77d33ca9cf3f31f71d4802e4f47f11bad18d8ba1567f581797e391faad29d 3b791ddbf51f3c726e36c6651dd07772cb8f17237e90d42c939f75f8e4a8a1d0 +1450000 2d032563393786ad62c94a24b0a53e98c5fcd91f01d6f386b2e5e0f5d6ba3d88 07b1e5181e550a276597d022bceb27ffa95920e1140d7b311cd134aa0155d938 a6148036f071a156c2ef7baef40eecaea74032b2e616991472351a7447858849 +1450500 c15c9b4a1421f05a82beefe9aedab9cfb439b3abca5234d541876599a6d36747 19bd9f655d61c83dfdf15f68cbc4839b84177fe77c798b8f9d69c5ea2a051fdf 3e46288a1040ea22328bac7a10ec33272a0acb23d713cd7f0c6cc9efef99bc29 +1451000 5f4e425cecead82f6dd0563c07eb341cca9471ef30a84b9a246b01294f10ea17 diff --git a/iguana/confs/BTCD_peers.txt b/iguana/confs/BTCD_peers.txt index 34569c8ee..f954be17e 100644 --- a/iguana/confs/BTCD_peers.txt +++ b/iguana/confs/BTCD_peers.txt @@ -6,84 +6,80 @@ 89.248.160.242 89.248.160.243 89.248.160.244 -85.25.217.233 -65.15.37.140 -62.75.145.171 -176.9.13.13 -88.198.15.19 -51.255.38.28 -121.108.241.247 -82.229.201.131 -162.13.4.69 -78.226.160.96 -115.28.42.60 -178.62.185.131 -167.114.249.196 -81.181.155.53 -76.169.236.235 -67.165.77.192 -75.130.163.51 -72.55.148.203 -96.127.136.18 -88.198.53.194 -63.247.147.166 -88.206.186.58 -217.8.62.188 -46.231.137.186 -217.215.190.134 -2.86.63.69 -59.147.43.232 -104.42.224.48 -24.168.17.50 -173.65.129.85 -84.119.62.223 -59.147.43.232 -2.239.61.146 -176.28.45.179 -73.211.90.130 -185.48.78.78 -77.21.104.176 -46.253.169.134 -163.172.156.107 -74.120.222.234 -192.99.233.217 -162.255.117.105 -188.166.91.37 -149.56.122.72 -71.1.13.122 -88.113.76.138 -81.205.30.207 -203.189.127.54 -68.190.213.46 -98.202.147.55 -89.212.19.49 -162.210.92.46 -115.70.19.28 -68.43.220.127 -79.227.171.148 -68.46.103.181 -98.207.117.83 -79.200.255.204 -82.8.59.60 -71.241.204.215 -108.247.198.39 -156.57.141.221 -92.26.168.113 -71.53.157.49 -68.45.147.145 -79.54.185.53 -110.202.11.148 -91.82.171.9 -74.14.104.167 -95.116.195.148 -90.113.82.59 -98.118.105.12 -82.241.71.230 -98.161.16.55 -89.248.160.237 -93.211.231.89 -2.26.181.156 -89.248.160.244 -89.248.160.243 -89.248.160.242 -89.248.160.241 +89.248.160.245 +5.9.102.210 +78.47.196.146 +85.25.217.233:14631 +88.198.53.194:55692 +88.206.186.58:37299 +162.255.117.105:63084 +115.28.42.60:60878 +82.176.15.155:35026 +88.198.15.19:48150 +176.9.13.13:14631 +217.8.62.188:52714 +162.13.4.69:55410 +211.58.177.43:35581 +63.247.147.166:50266 +24.168.17.50:50793 +46.231.137.186:56963 +178.62.185.131:35572 +62.75.145.171:14631 +89.212.19.49:48018 +192.99.233.217:42232 +68.190.213.46:14631 +162.210.92.46:14631 +98.118.105.12:60805 +75.130.163.51:56719 +51.255.38.28:14631 +88.110.117.18:52158 +24.101.114.249:55457 +99.44.222.86:62377 +108.61.166.209:58365 +98.208.113.72:62065 +72.133.226.130:14631 +5.189.144.97:58243 +14.203.46.202:57987 +98.202.147.55:60460 +24.45.172.109:14631 +89.114.38.65:52768 +68.59.64.126:50633 +68.43.220.127:4303 +81.205.30.207:63077 +113.87.28.142:62764 +73.211.90.130:41271 +110.174.129.213:49252 +68.45.147.145:57803 +95.232.175.161:62633 +73.229.133.160:38440 +124.191.14.253:54342 +167.114.249.196:52705 +92.24.168.248:52892 +93.158.216.201:14631 +158.69.27.82:46643 +104.204.109.11:63390 +68.157.88.187:56711 +71.53.152.87:5234 +82.229.201.131:63466 +59.147.42.146:57461 +81.0.91.211:53187 +82.241.71.230:51945 +108.247.198.39:64094 +77.22.227.8:65093 +122.166.169.11:49325 +173.76.182.122:14631 +173.24.82.253:14631 +100.13.54.119:14631 +2.26.181.208:14631 +94.242.213.3:14631 +87.149.45.42:36077 +98.207.117.83:50955 +71.1.8.48:14631 +71.1.8.48:50439 +101.166.241.31:14631 +178.143.154.142:27497 +103.255.7.59:58660 +156.57.132.119:62428 +60.225.171.82:36834 +46.223.149.120:43358 +37.157.215.75:4162 diff --git a/iguana/confs/BTC_hdrs.txt b/iguana/confs/BTC_hdrs.txt new file mode 100644 index 000000000..485d68a82 --- /dev/null +++ b/iguana/confs/BTC_hdrs.txt @@ -0,0 +1,4293 @@ +429103 +0 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f 35d08fbf1b2fd7b8e87b29c8ad6682b9d2f09db56ec56bf16e08e973b6aa44b2 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048 +100 000000007bc154e0fa7ea32218a72fe2c1bb9f86cf8c9ebf9a715ed27fdb229a 472f1ec3e6647533551ef65a7f826ef345daa2e8bc27384845f377208465c8d2 00000000b69bd8e4dc60580117617a466d5c76ada85fb7b87e9baea01f9d9984 +200 000000008f1a7008320c16b8402b7f11e82951f44ca2663caf6860ab2eeef320 5847096dc10d1f31efc6b881ca9710bdd4602ee41d6b61ae40d1f02e30e31c09 000000002b50d5963806b024fa09d296a3d8762713536eba9e5bdfa7596f814a +300 0000000062b69e4a2c3312a5782d7798b0711e9ebac065cd5d19f946439f8609 cfcc1460aff4e691ef60ecf667b6de05270372107d425517ad71af123d247aee 00000000a23332a5740d8676baabcbffe490fd8849b6d30f7399b83aedd733f6 +400 000000002dd9919f0a67590bb7c945cb57270a060ce39e85d8d37536a71928c3 b26b312d37818576473e938e3f1cd16a159ab47a0e26fbb391511bc77f03abb6 000000005bbced8d14a6ec258a8ab28ae980616e9820437cc3b6d3daff3b7d14 +500 000000004ff664bfa7d217f6df64c1627089061429408e1da5ef903b8f3c77db ea0ecde47c59d3535bff221a582592417d15d78caf553758341a100adc33d1c6 0000000046887292a76cd113a5fd6af38b17c9fb77e5936cd9856694030598f9 +600 00000000c7f956a913bbef9c94f517c318805821b59ea6227175f3841792ea88 2faaec5851b60165422e3d7379fe3c5123fb6606ac3cb30c6c5b3999098a64b0 00000000a893fa1871e9a349309b47a9fd30520eff9605d52d981419cc210884 +700 0000000084d973c18381c87a63a2430ad2eff1d84934ec34e3bfd78ffd3cd9c1 3e5586b6bb4838a5654aa527e3d94ee4e8d5eefbfeb5e9bac47d347512ccdb49 000000009185a6d894df317ab79ff4ea68bcd9b7bd972888de20a9e4ba9c06d5 +800 00000000def8545899ea7274e5c59bda5982f8f960052774df45b7d5c64f9c5d f320be873b8454068375797ac3aeb4ce34f56f490dfdcaa08156df56181d6700 000000000057d77971fb0bf24812e155f9eb7c4eea682b62defd627b7d42c2eb +900 00000000e684309e67fabdf765bea193cdf8532111079b7f53a0839746d19240 91a09b90adf5ac40a79d40d7fd0f0de5e60fbb16547cdca21d4f0578f3bd77b0 000000005d43dd65f5b334be51b6ca0910477a0344c5290a36f147c0d5c0730e +1000 00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09 f782a99fd4da88b084e6b563459e1036b5b63cfe12c40c79398990ffa0b2dfe6 00000000a2887344f8db859e372e7e4bc26b23b9de340f725afbf2edb265b4c6 +1100 000000009cd3f93cd2d843202155561eb773b2a7b7c97561ddef31e707f4eb4b 56cc9f936b563839f95a4d2c67d58128fdebdcec85af02dbc396166d338d13be 000000004ea3fb1a453c3c7d29dbd5baabe7e23571f73cb242dc10282c705907 +1200 00000000f0b6da96d1e3272e87e181a7057c3d79bf984b420d4f6fd6d7a49fc7 dd00b9e3aec2d7e1c7b45839bad3715429a3ae11f2e8bc9c66e98be26848a0a3 00000000e6fbf1fd197e80e1e738ecd5890cb6e038b6ba32484adfad3c335921 +1300 0000000047a712b762d9c91aa1cc2e33fb48ea64276a7086c3c10aa252a934ab 6cc68b9880843468dcfbc22207ae4831b8fbbc10cac2234e3b3cef2675fb5cf7 000000000b57d2d81865b33cbf69ee905688ee70772fedb7cbc7407fbccd5461 +1400 00000000c9c28d2bb760225beaddbc212a01720869b624f088e9311df5b5d8f2 febe4243420ca549fcb9a14fd9dc27f9484fd10f8cd591b93a2316ef02f0e86f 00000000c7a7852c997de77ca70c5788d2e49417142398b245c5d257a2d96075 +1500 000000007d07681a955b7bb9d96c473e847395b592b6e9e5a73b15b594bd4013 11b715004c23994ecee4670f5082d00eecaf4fbfe641fcd9d759fe7f239f2247 0000000054f7d37ec4740027b6994907d8e771d77c14501503833da4146e8637 +1600 00000000f6b38fee667afb9cb2eedc5a9988d345e7b61ce220d34005d2d5b8bf da98da70c3926abe9baf698ae2f1d8ae82e9421670758e24d7b69f860ceff9a2 00000000ffdacee18e2c714d840888e87796855b446f4883c2834c6ad1b9a1c7 +1700 000000009bf03aa138b1bb31491261221f8d4562941c1022a798acda7e3158d4 250cdaf7d7023daca3c9b4a5997142b19e2d97625be5daa5a9d27e6919512244 0000000039c9ee6476f7ff947201bcab7167916dba9754fb5b446bab0cf8ef28 +1800 00000000046d4e2de13c9a31dec05fafcae393ae7de773242abd4db47e9e747f ecf0ec8b84aa542b01042fcf636e34d53b29b44de40065e872e84d82da03d6c8 00000000c9ccddfd2f3e45036a8d04fcc3263a83b82b4a9fe134dc1d8c7ef295 +1900 00000000e67f39a80dbba80e5bf130294ef460b89022c7a56c3df76ab2df2e71 ed4c0b1e3faa53831a21be8f1f3c6ad55512671f801446fc7449926543b2ff2f 00000000d77df12843c43e959cf8afbb1b20e3625f698602639bec1635c7eb96 +2000 00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a 1b18a3257ac9966e9706600308c4ccf283764f3fa45e08df52c89115b2c9183c 0000000067217a46c49054bad67cda2da943607d326e89896786de10b07cb7c0 +2100 00000000d5092034c3a92473d42f28e3fd279f0652e2d5b0049c7d40fcbc990b 64e05e62d6e5c28dc8bd4f90528dcd9663d9f839b4014a3a65049256d09be8a1 00000000d8982f243bdc42ea9b6dd9961f98d99db54decdc6affdfdfd7205eaf +2200 0000000070118b55e0436a721d4533fc3d09a0238f72a5380e8a694c9dbf948e 4f0a30e1d6ffdb992101e3514c3993e47263dfb701155d2c644c479c722048e1 00000000bc04ac00ee40d71ceff705a5e56f27e7c09c60320fba0c1da77f6c82 +2300 0000000091a5fdf4b5f5fe07ed869bf82049b3d61a403f2771b5cbd1937dad09 d3fa235d4ddb746b02ce52fa9aeecc78addeb96adb266796e12348d3aebaf979 0000000005293c54b44c3ae0230ebe9efab661dd7b3068fa44ad33e872282363 +2400 00000000081038eb250216ebb27f94d8896d2984dc962020c53e6a2852b92967 21f8c70e47cce809a89dd9880ac31ea89ba15de9434c5b140fb8900f409269d7 00000000b127bfefe6afc98908e6071840b979cbd26a54f8b545908176ca4022 +2500 00000000d84724559f1691d916b2ed63a44884d495d155197647ce7667116b16 10611ba69d93a1d22cf092af9f65c8ec00ec4316a732b7df87b22c75487dbe39 00000000f11a02048994849fc2e785239b23de9bcfd7222d159188c52e7a98c5 +2600 0000000091a7488531bb1050f24c0f8f90d4da873673eb4dec62bbce56a32910 1f11a6e2aff356a5d165349db68fb1692c8030eb5f978a0ba3461a44f7b5be99 000000001ef2ee83e0a9e851bae4530566ba9353e89a7f814cef7bb36fc99641 +2700 000000001731f7bb532ebd8ff11c253f128a9e3108eaf038d8155fedeba5bc0c 05302971715042cb8392da825d441336a1eaaea90d04c9b66cf3c7539c30e0be 000000009d65522d29ae00f24ccc272fb66a97962440b2fd8aa0ca04bd1744ab +2800 00000000d10250150162aefbf7d64ab10f3b4706ffe4d04ae59ca410f672e97b 12de1a43cfc57c7b0bf66e10c26599a40417245627cb9b26e6afd52e16aa486c 00000000eaac134c9d036c67b7d9e6006abd10a0f99235cdf910bcba535d8d3d +2900 00000000a4342e04aa766386cdb4da70137efd47ac271f1a4e18429af3020a7c 681ff08b32824ed7cc490ccebbe5f24b21987cd6e9a37a2095d74dc330931434 00000000f903ce68d137addc7b21a4a8951ccf768e1fb0aa870311788f8fa22c +3000 000000004a81b9aa469b11649996ecb0a452c16d1181e72f9f980850a1c5ecce 86ababfc589d5ad88d5cb03f5ca86a1a977b6ba69efad8eba9004a4cf521b41a 00000000ee1d6b98d28b71c969d4bc8a20ee43a379ce49547bcad30c606d8845 +3100 0000000054470b7eaf483188546c296cb32dbed05bed5dd711bd7c685f8c8907 623acc4b1eecad9fe35115690043b6a08309420e2c823e1150fe1d556fa59428 000000005a83151304f6be998d66d53d4e684255955d352e85a65e7020801738 +3200 00000000bccaab487030fe7c0d8d66a80fefc157bd75f0de40b6b8d61ea1d287 38725145260281c30e8155e61152bb780c54176353a201f320bf169f8841a569 000000002cc7aa44265bc9802bdb2aae0fd16493a861779838ed65ee1627351a +3300 00000000e5a427932794530bbadc6a9a6c354f030da4cd9b5765d866b51502fd 39ae64132d6b4a2d08467bb53a152455126527e2e78c001a5e9dfb25ac1aa14e 000000001a2b99010ab59e07281c075ffdde342a1564ba1419036c30e4dff0f5 +3400 00000000b6641cc18693437c5208bf362730c533fd3ea4cca364793603bba957 14b8241fbdb0f764749a574bc3f96bf9f1496f6bbe075008d2d5a67827b8c62f 0000000060c90ddfb7ddbdb075faa171b7346afe6b60681d666d7b06cbe4fe09 +3500 0000000022d49c5a3b2587f48bf6583afccac824f5b7535949afcff3ae82a44b 87c528461306aebaa8dfd6133a191ae080ced221da46ef651fb8329856b78df6 000000007f08fd0d06d1f19d5332accaccaff19e80616346b45f9ad3158e8394 +3600 00000000bfa35a68d94bf878a712c538484d8bc272c6ddd70de4e636d55f45de 44dd9f3219ca823c9cdc3874195dc8744f58814a809e3925080c16f0737ba42a 00000000caf8f5eac6579a9b86bb669ed9daffb99fbaa1786b104e150b825aa0 +3700 00000000d9edaa8b2912a17d733001a1eac038171ff6ecb2ea9df6e7a0283dba 1e6c98d4221d7e47057d484c05bdbada8545d5fc11289ee06b0ea4182578613b 0000000014fe4b2f902e7d3da230590f660b4ed8e3029594ac4c3f851f22b13d +3800 00000000b590a5ff44afeb50e51444d8b6ccd08f6232951316f33e19b5ca5ff2 6dbe9319b26b34355da44de2f5ad6f1567a95b7e6b667bfffe27e6b81d007326 00000000a186abbb4918a881df9adb05be688a3d51d8ac6e33b599d752da0b25 +3900 000000002f02872c40bb68c0e73156c8a0c7de7d84bd01c5931775f1c123f2bf 5b9061b12bce000750470d1c883fd5c9f0cd4f6c6805363bd1f850cb9ae6eae7 00000000ff3332353e803e59c14a8093f26a4e41b2ec7f3544b9faf6d7cee08b +4000 00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842 e5ee7d970261efa36d3d8c5156808847ae1e03dfb9f66e1b1dd29a932a2950d8 00000000a86f68e8de06c6b46623fdd16b7a11ad9651fa48ecbe8c731658dc06 +4100 00000000d55579d1311c2841fa900531f34df1d543ff52598f2d526c5550cec4 ed4f991b8066f473311c694fd006ce18bdecf874098c11dc49730332ff3db23b 00000000367551c3c80466ccaa7583ea433b57aa1e48b9f312775b32d89beb50 +4200 00000000456431810949b7e73d40120a65e6db7353db1c7da8dd141cdddad4b5 e85915de9256ddcc4729627b7428bd94f77bf5ff31a39ecda740e0697144ae95 000000002f099129f89e7f425d3d846c15ac86267f65904deb73999fe22e334b +4300 0000000000b54b5510fbf287ad4c31ced608521b2ccef6c7ed8ef033060e3eb4 16a8e12de6b88b63a8ad62e4f7834eeaa342c6acc0750dd8bed68b1d5a0fbaea 000000008baa63431721e601b2b003bae7726adee3086867863657283dc30114 +4400 00000000400a81e69af7a8431f7e42ff27f55666969731a52b821c6b0f206a3c e1d38c84be22f3770bee1025a3f5430962a0da0233632d61d8531eaa3c668021 000000000650038391c2d2ff162be23c9e43e1c9452929db31e7ee8374a86a7c +4500 00000000015a64948e4248f08bae4f0e9754dc7a747b10eae2ba603d21dcf718 f57165a560a2da613a7604c97dc23ff6f4905c1138978ce31e151e8f235e317f 00000000dbae13c4a1366d42db3967b7cfc7604675cbe8be06ecd08ca7fb97b4 +4600 00000000013f500570b064a9bcb07667ca77993430d602eeb536cfe29310d636 d111c0044410a32a1a8deae769ef1691e518d07f81525371509d498d836a9e46 00000000c85651122f4f03d62f864068289e81f39e772314dc87eecd075189b6 +4700 0000000050cbf0bb4491affd04777b895195114a6a2dea7bfa51f1626d58c1ef ec44c24fb19120e9b093545e938da065bd96f33150e2e757a8c4420c5c406a55 00000000d6be90582197a2edf3a3a69b11a0672ff4131f2554d15c750678ac57 +4800 0000000097ff6abc82bca6f90e04c2f898fff86a3f13c361a712d4722f6871cf 503a2c7746c9087a019fbca29849118164546521eef55b2a67fc1eb057b2c847 000000005f9b24448be4d2c0216ac940c35554a090c12c1192603b068e2d7be5 +4900 000000000b1bf41e99038c31539269f799725cb56bff67f7a2492cad380d36ac a15936bdb986fa3ffbb2af981504aab73e32cf7075c33fd681edd00db827e44f 00000000c6303c4a85f581fc12d76a945055d2134c18f7613493d94c972d5133 +5000 000000004d78d2a8a93a1d20a24d721268690bebd2b51f7e80657d57e226eef9 eefcf848cbe224da12fb5b00e3edc7820460ddb9d907861a72b044bd7d3bf72f 00000000284bcd658fd7a76f5a88ee526f18592251341a05fd7f3d7abaf0c3ec +5100 000000006280c0aba2c1776df0eee0b1f6a773e4d47ae78ee134bcb6ed21bbb4 06e4e10f49b6872fb60b3e48618036add258d0a6cb3ab4054acb4835fd275ca1 00000000aabde39b81be3d18ddb1e925e3990f6c0f011e6ee6bdccf52ba32531 +5200 000000005139fca0ddd3f3ab9372b45b51171e3ff9568dc2e5c756d08db16b0f c57a3a1aceedb20cc6d9fdd83bd423301309e89704e873fe8711bc28587d885a 00000000a7900a5c3cac254aa7db9052d2f694529a49c5b0477bf4d1e09269ec +5300 0000000033d54f6bc59c7da718bf75fe4073f89990f827dbed01469b976f86c9 11342d7c97baffa7d95dff7dfc4f1febe643d055967374f753314147c0bcda9a 0000000011696100810276aa2c187641dfd89e734e1eff851aa9f3cbfa869f09 +5400 000000003819e45f96d069bb41dfa72e94c0ee0c9c97a1b127b62e8613b71374 59cc8dd9aadf3b16f8f6f7f3af96ca5667497c1f34330ffe6226f24637f0d034 00000000fd4411e3f13508716399cf84b669649cc9e358588af36400f71e9cc9 +5500 0000000032f2fbfb5849e57629bb28ff2e79d4e231fddb25b183a2b13ff2d123 f2c509c69a0479bc3d8d76b52f46941535a52baf9b9886b67ac8cb794eecb9a4 000000000dd21696e382cfc77279cab9a6194280fc602d1ee7a6809fd549534e +5600 0000000089c7926f6bbbcff90daac70c8817a40e6df58abea652dbb6f4feeee0 15c4d4820ca83694cb0175bd71fc3b5397d2ba35c645b7ac2fc35c96c4764075 00000000423ff2bd1a5bce685406e1d166305f17040cb3123c1f52c93f6c1605 +5700 0000000092401f6c614f894c6cc1f2bc24a68c817371e82fe06cd9a954acf7dc e9499b22220beb6b8c6394a4275f5a018ced5e4be567a15fde1c020f1d885082 0000000043daed14132a6a3b129c5a87f8d8b27b818878583dcc2702fd32a479 +5800 00000000c93c9874db8d899f8409a98980d3cf2b0d776aa8e18e82a961d7eafc 728e182c9947a777de3b0cf294260a7974d65c558edad8fee4f71d091ef46a73 00000000f94d02c84f733bfa4cf26bb87a44b6261c2b62c659e6f582a402727a +5900 00000000b81a499a58a1c13ca64f6f2bd072bab8146e3067b29dcc1eab71e926 c153082625451256a6fa8c22f9c1d30494e2bfca51ce8a00214c476bbdd01ee3 00000000e2ce26991d2fac07c4600b4881e91819d186aaff6f530ec237725747 +6000 00000000dbbb79792303bdd1c6c4d7ab9c21bba0667213c2eca955e11230c5a5 70e5e7f91278f4f854a17def6fecc396eeab4a06022d13e7bbe4c02af852e440 0000000055fcaf04cb9a82bb86b46a21b15fcaa75ac8c18679b0234f79c4c615 +6100 00000000707f5eba0caca3b6e725956e92c62f68c114a239f49ca9cf2b043801 d020949680c2bd5c6e7166f980a95db28a39b5a66ba7d4fda9fdfa2454f5efab 0000000065dcc2ca9250ed1e6c5d089663266646ece20545a7fbed933f3e8753 +6200 00000000670dfcebdfff4c8c0ef726645b0c51400b464b9f55c73e6377f160cc b55c2138e006e1072455e5bcbf02a57d5ff17c9ba47dedb1879add535e882292 00000000ce6f8700f60c1814cf727e5c05360bfbf87676f6cbbd8cc1c89c6d1b +6300 00000000d75f53340a8ec23ae9396ac489ad788c2d1becba57a2e468b29bdee7 bb8dc720518101c2df2d425533b92cc9f377f345992b1febce2fc5126b1d408b 00000000004b166c36d656f176b051ebe712ae69cfa624c5ab74719fbc6c7a56 +6400 00000000584420c089821bdea32f64a73ad055ed814e90972f9108cc295517cf 12bfe69f39aa395cb76131d35c5824a0e1e4c341df4466c6098c5551125dbd1b 000000005e7d5b3a44803b333b33ff2497edf213b1c7910277f49c6de67122c0 +6500 000000002dcb4a3fbf33a516ed4ae12d08f11c7bfc001271f9312a31eb6dbf52 3f416b76fbae6c52e5a6d601d83f7f789d7b2109f7396159e3990b86d25566c0 00000000bcaf0e3c091ec2cdb925f8582cb9fe04822f4ffc1e8da2760bc9647b +6600 00000000ed467a2513dd15679b22b20138d16b7b608f6ab79db482011fffa423 454291513f806f4ad196e563274fea09dd60b5cd11d9cc214a0d5776f0092130 0000000030d8559b2a6a5e5191bd206ccca9278bf37faf042f61da3e4cf660c9 +6700 0000000097ad82fe2e9d3ce60dc11312efcdda3815e5b1acfb886a787ac59c4f 7f21ce118c91b4d8b44be5e437803caf4e3557be15dc5f3cf516200f2619c13d 000000003fd1bbe55cf76942175b13d725f8673722da819040844e8ba3019bcc +6800 000000009dbf018a558bb165176597ef69cc4c4be997f94e2c3e160059b93667 147cca1063df3a533d1ad86c6bcd7e1a5c26dba18c34c203ef8c1b7c9346b1c3 0000000009e116a06e5a8ee2f64f3777ff2d82cfaf10a97a6a27fb947a835353 +6900 000000002855bc26b205524b86a8c5440a1fb7f05b136d840310308716c3a3cf 0de1a4a3c50ec195719af79b3d87d3399a39bfbbb3e6198c0548917f077bdcb5 000000002bb02e73ed4eef388e4c4f738b688cc02da3265fe0a57fb8c951feab +7000 00000000febe750c27cd55f8bead2b0d4faf33ba961f9e3c0314791ab90ade55 c323d94e3df5cb4963799995fdbfc638149ae2ff670493f341b74afe380415af 000000001bbde9ca358ef26004688ddf7f6bedba1869ebf2482831b6d1376be4 +7100 000000006171874a43a089008ad4dd754d2b9fe0d2340aadf5d2f6602453379f a4cad4471ac1eb12685afc87505e382b1668956bba0e8d59cd2457734dd014bf 00000000875b49bf7241597cc91fce9cef41d74252f28d89caca66e6cb91c99c +7200 000000004418cd7e82b76420e68870d9200d1deeaa334e5733a41a348fd948b1 a1fc21e8b371346423920b655c3fd0835d537e4da46c1600b1710b47e3da3300 0000000094f20fb6a309b8d5686a13a9cd3fdcddac1a52e5b7c5660e560cf1b1 +7300 0000000033ae4665f982447e4907d14478d018a37ad72ad9799cbde30a864410 600131ec110d97b6679e5262f44631c3eb0100f3710d5796a1c0fe8018816063 000000001f4f51ae1ff49aad126b6e1e2ad1630e68560638610f56818c253fda +7400 000000007f2bdcc71d60336ec1636e0d034d73362b86bd75256b4bdbddbeae78 e1c1e0ad59eb98ea562388dc57a59e9655a2aaf7c44796eb7cfc7c83bcb5afa4 00000000faede889e3a01b997f793321c0b482da1b4a019386f730427d7370b6 +7500 000000000ec68b31e49154680704cf194ed415a8d978343a19de657429de095d 6ecfd23481b6a1e14557f860af716edbd28efa11f86bb9af8c506a1dea3ab4ef 000000009142a40196f95eb651fb96ab906f06fad66aafd95bef2e8c341fdf6d +7600 00000000976df3c85530c4a7e7545405289688896dc75026c1c9c3d5d63d76df 285525ef8d6b66f0e2048f5f3cf21ffe86e8bf34b079937903e0b05ef867a464 00000000c8891dd7682afc1be593d084b2ac3f0d43427b307df172ba50bef104 +7700 000000002439994e38b1e72809730bc6c074baf85c6166821b1d8f9015e2f569 f4fb3db056877d6ebe169f7e0742b60a139e3043b8e6fd32174d2cc4603c0434 000000001b5b9e27fa2f90ab9ba101b4bc9efe9b80ba3b1f3e3a0c0f25a14f60 +7800 00000000380462e5918211a1534e199b6585c139d2bf7ca7cd38b60e650e4600 a445b753b288f535053ff403e4f86b8a5fd3f5d5550571882f9cf98dcd60664e 00000000547c975d1418ba51f5a154c01e7c3be2336db1bb54b911f1a5b0dfd2 +7900 00000000b5514e2e72cec7ee5d03cedd91dea5c31580673911d159711035e2f2 002e8a494ae2a24b4ed4684b5d3f34af9bc108862afddf6032d0c51b96ad4db5 00000000b07280236b8b97753074465f2baf0db60530a44f3629da847083f086 +8000 0000000094fbacdffec05aea9847000522a258c269ae37a74a818afb96fc27d9 cc5495ed39c9a4be40e79061db25e861b5c0ca07b5811efe26a5661d2786528d 0000000072e011d1731643b13159a274aa0d4e15024d534e1f62804a018d242c +8100 000000001979ca78bede4c240bc903db3c4893be5db8b6fcc09c9077cc820082 038ed1e28a9326e5c03b3b47da235d9553844bf1855f3fc473de268c885f9672 00000000b8dc5f844239cdf2a13a5e4a71b3e767c13004d310a5042696a0517b +8200 000000001345c8c75cb9b340e9e3aed752ceac79c000353a9e456f545a701b66 91f8204d2886c5f1f63e00a4df3e74ccec024566027a58d6a456ec58e00f9045 000000004ca8bd5222b4a82cc4817614f67fb4eb487de9cace123bd3bfb13417 +8300 000000001af2bc6ce395f9495ed79306719e34467152479862ecaed4de7fd1b3 289087f9b51a7b69d2419bbbb63f516eebe9cab76a92fe9c573dbf1cb077916b 000000001751d9f38fef72a0202ff032d3e9c808d5fb3950fffdc8a83a759977 +8400 00000000297c8bfa5d4cf7826f31f39d6bd92cbfcf2ec9ca2ed298ea471387d7 aee3ed8bba701888924be6e4ce3e8fa00843cf25af74a88b17c8b18058e35466 00000000b0be827c7f99d96cf4e9187ce77c0f3c67613fe1326834706df88492 +8500 00000000aba1f720821fac035481e72eb918c138372260627a3a976aeff59226 c02e22987beb0d3fd38c88b374325fa886a1059e0d5faadb124be028a0da2859 00000000e6608bf9e2f018f1534a0e9ba82ba0c40eefebc144312fcd8e3e0abd +8600 00000000312efa075ffb31b57ab2f1239105155c51349b426c19c112c66474d3 b77b91ddb674d0eced1c77bb2e7e302347ffc9f11e0c404ace5a9c260ad494b0 000000008849986c44878f325590e577febaf1d60c9af9d79411c664264e5c0a +8700 0000000041bc68035e785d030689d2d0c50c019a059bd370d40ea78cb7312a1f 6986f51aa3de733a988ab45ddac33f6188fe8cdd903c2e0927d526dbd3914c7e 000000007a7f2fc8caf6f4b7ba2a661f086999e5d9f6d56aaaca148c11f5ed10 +8800 00000000a6b938f2407fa173d034c9da999e8f82ff27503edca069b88dd9b1c0 f3f69a799d8aa486541c4e6c36ca983b8dfaf3a706a98c466044bd37a56c4ae9 0000000074b5bae4abdc95e88f7e12e68987856cbb384d61c3355bc2b9be4b9b +8900 00000000f73fe67c4b7c62068e1801cc53d8333f951c14107e70f8179bd51cf7 0bc998b2ea29e23afe613470305236f9a2d80f731760c98a6984158565efcfa5 00000000d44e8ccd202074e7c892d68eb22dbb7e3a2201455cd7c7e428d3c2b6 +9000 00000000415c7a0f3e54ed29a3165414e5952fce6848b697696fcc840011a5b5 6fa42bb7d1f316f6012457a23853cd93f23377cb7fc948c2d54f7edb63afeb74 0000000003755221a82a55ef769e3a785768fa567a1c03580cda400656f2b216 +9100 0000000071a164101778a4098e1b550a885fbafcf6b208291529e8386786a4c6 19fb49da41c797a6eeba391bdd0f2aebd7c6f6eb1f8d0cb9a2c792e024808451 00000000a23e5952c979ef6f8e1f90fd2bf52943c4a3e172613dc0b770e7cb31 +9200 00000000821bc8b810300b56540b47d14ed719dc8ca50c941b4ae139e9f2d3c1 a230281bdd5377839a51b54f604f6016b5348d065a9a32987818ebd5ddd296f5 00000000365ea47381ee446a6a311955fec1dabfacb83a9ef57b8ff34b1ef6b0 +9300 00000000af5423167651b8b485f0bea8ced1bdf7fe832821e5fad4cc27c59195 d784fe0f00a287411ec93e8d51927b48cd67e547ae6b74987215c2269ae32e6e 000000000ce946ccf793f66a47c78377d7a75010f71ffb4c63923456f81b13da +9400 000000007499730f719cfc25ef66f08bee28bbe22e91ba9467f72aa5d209b760 e4851201741cabcbba77a50a865dae9921823a668275198b21aa480bd00bc809 000000002c60ded12f2b34694c99c395c323d57b8d30ff752459bdd1c6ad7535 +9500 00000000436e6caeb22a9132729282c21b123311ee09b5f79f1f061325f1776c 3edc23b203bc6ad69309cc79a29272c457991177a53ffd18488466c502c72c56 000000004383fe923306472b416c0c2432523b3f5fbc2ca25def2c7155f9b5bb +9600 00000000ca2be0b2535ca0dc5b74a3d59f3209f664c3c6dd016d227d31548995 46d7b2f50eccca85e0c5d7eb9738b0d790e2e5d7df65a28549ee02a736829818 00000000cad779b7ff1028ba66f4216ae112ea9a5e7ea26f109480887e3ff5c6 +9700 00000000e9e87b0295fc0b953f70dd7a4cf96b2f44b02a92f5673065d92336d6 40dbdf499c9223ef733e369d2ed3600d1814a90f9f1fb814ef6e616b46291865 00000000d88851f4dedcff7b938afedb0de4723f32ccb96b0222bdf4b8e057a9 +9800 000000001eb7936cd07a1a9d2454468f93c0732bd12c2c19433e0510b6df71cc dd33eaaaabc7cf122264d2e78da9e8398f1b8758d6ce41b5abff469269a6ef2e 000000001e46be0459127a37770c88d455485b00d3ea4a4b93dd76dca6055401 +9900 00000000aaba6f091b5f8a356dcaee98fe8c5ea8bc915cc4516dd9da528c0724 84f000092ffb5646cff59921132280cb72449885f3e18cc3b9c61c477eccb3e2 00000000d79c1ab80b93877791d7fff8bd99c8c45c8ec876ea670abb4caab165 +10000 0000000099c744455f58e6c6e98b671e1bf7f37346bfd4cf5d0274ad8ee660cb 2b16bd9a8d2bcf9bb5516f26ab9ee8d295775bf9b9a37f09ad1ea2410e1aa0d0 00000000f01df1dbc52bce6d8d31167a8fef76f1a8eb67897469cf92205e806b +10100 000000004dbf0b1fc7bb7dc72423352088d32d7a7d79c4d78144758742071716 d83110dac98c94266454b3d3bd2e0f1d050cf4951aca398314e18717c9968599 0000000097af9ac5783cbd948785be9ebca3373681a2f1381a5786c1cd943770 +10200 00000000d3d29e4d734dbb7ab2a2d0e4b8f4c14ee3480c0ff87468498465ca98 a0377517df50bd7d96c2823fea3e7efa6ceead626a265276902d42fc8f294fbe 00000000b59ed5e53200ecb890f9d0c69754eb4f38ef0829f2826beef2f2e366 +10300 000000001a02dd5ed3e0d6259139cf3ef6a981a1a723f431314039da8e7c6fc4 17b222e05057be799da430ac2a8676148ebfa55e837a88b261b115d934cf487e 00000000517960a7a42852c9bca0b371a5376895f9d8bbd7d6739535692f751a +10400 00000000754ffbb3b325c4c9b3d2e42a0f4bbc7ac6362d07014b6168265b6dce 01d005d4e60bbffa46fbeefc8925665b32d73d829e7383bd13570e22537c4eda 00000000c1c52eae8046c026a17f751d76e78072fa5c8382553515ef70b9014f +10500 00000000e6d1be14564ac099e26074c84e8c5ac8332413c2db3cafc0634711ea 603e5afa7684958105545e544f5ffeb576dc445e121ea20cc7355b6e23bf83e6 0000000075dcf7b5533218b4614f843149da32645c339352a01cea8263093429 +10600 000000007c5e161f7c54a61eef5cd172ef0c80ffa8eacc481f257d9237982076 b8669eda2ccb9851acb61dc4ba1bae7ce1a000bbfc208a6a4ea6768d54a21491 0000000095723a47405de14a0a6e7d14338beca28e6db53e4b6b1f9536f3a345 +10700 000000002239d890b1aa3bcdc1752414c43d6db9df67a91e81c3e8bc64e4923a 08d3716ff5e7f9a02bb9707301b351a5eaaeea94490ba671669d5ca9f44ee93c 00000000b42d72ed212ac51bdf9105028fc58338f2475094a34a8439949d92a0 +10800 00000000707e3f89e9626b9379aa1a1157846ddbec7a6aa2b6834eacf957b776 de70e69eda3d95c12f9a1d1d6ff4fdb248790d1e1a0a43b399ac78be7242ebd2 00000000246ba741d5cb6dd08f096cd553df34c67121f6ba1a5af07279022c5e +10900 000000004e501a8a9e3793343b83e86de60c785744ee9dc3b741bc9cf92d728c 17d93dcc23b4704ae1004453674083e40a270e0d9821f0d5e308bd93586f02d2 0000000090f705a252b37b8a6c6102062dda3b13e4ff50c6cc1e8515e4dc2365 +11000 00000000ea47d068e0ba9b4d902ae291850ac59cf29c2b89b2bacf3db3c37e3a 0b6cbbea53627d015a5a5840522b550c60b007cb1ba66ea99e788b4d95b03e5b 00000000e8c8c215bb95cf5c4bb248ac7ee0737f26c5d64dabba3cbb32d19cb0 +11100 0000000085d3fcf3e1c6f635ae79ffc9c03f03892ea87426ff364caa9aa2e69d f5bea04526eab8c6fc03878fb52d0ba7279133d69762a9250e992f4ab5227fbb 00000000cfedd561e7719cdb3451b4cf8e6d828e512c49bdee5a75ccd1e70919 +11200 0000000015ba8c6c93bd35fb39eb74410becec279e022b689e97d41f7bb0127c 6befa1ae26256a89a43139b317af2d7c983559fd2cf779fb209cb5b6b0a0b3ad 00000000209f70fe43885ba809943e18b601dd3894cc5c812b69277c963a4ffa +11300 00000000824db432f3f29f23f55a213eb0b64b5637f175e3c43e1f79971a60cc 30c362d02c0114f9c398a74ace9ba5220162eac91eb789268be9d1fa4dfee696 000000003f666322c2b4efa08c6604bae64eee2938721bea9fd5e22a116c9ee0 +11400 0000000024c46e44075550da5ddb5964d56aad4ed929a9809e3364ad426fe181 011efea3027a039a43e59d0952dbed93c7a2805a953fdbf415f3b3d83b64a165 00000000a47707fd279a58ed9a9790dc8ad872b7923d49662b17569d8d9e4a72 +11500 00000000ae2bd594a8286c69782c87bb949710fb9078798609ee95731f3d144d edc52179807e30d63142763412d4ef5de18793ff4abc593e00e22ff3dcb59cbc 00000000622ce481c610280584c7216c6300f9592c1cf3830e3984dc70bc544f +11600 000000000ecd3faa889f77bfd9a25d82b2807a068f093557e27f42deb6f7cb02 b4fddcad1d32450b2861be65ce73f86cd8e4ad7c1908537a650ae140f45364d1 0000000007fd6d38cc1b0e24b5a84d7ea4dc7f9f0f2679a1074736f5feb50a87 +11700 00000000d2a57d347be15186bac207ba6a352eed2908599aaa975a6d99422721 c3735357d706106b02c79f69726b6131bbad62e7b3f540ddd9eafba96492f4fc 000000004c6467559cd9e57d3036d03e1fc71da79fcec733cc7dd963bc7df097 +11800 00000000129b70ce4513913ed3233d04770c709f9e8db99c9e4323c7782fbcf1 7d442c486f38388fb7176025820d7e0765cef0c32236243d5dc96c5b931ed00e 000000008a974b4db7f824b16a4c36e9fbcc63bd0a20000414b61e72035b2d3c +11900 000000005b5291136e9d9cff55abf0e315318404a559e716b3255d19257abef7 ee84139576048fde97c2d65e947fe14d11308cc79aaa783ef94103956b8202c8 0000000002d604d1d46767bcdce2f71920eb31a66921f64744efb9ff7d333b2a +12000 0000000011d1d9f1af3e1d038cebba251f933102dbe181d46a7966191b3299ee 43a1c641b82a88bdcbfda344c4413b44d092298bcbc152c94c81f5cb0e98c27e 000000009bf236ddb082304d8ad0954cd3292792c4958b643f2ec3c1ac3f026b +12100 00000000d71c465401ffd4935588ed9f715751b0daa272b5f1ce175bc4a62194 d29cbe0871418dae18d31d2a07f5740dc5855d4f2311c340b7bc6638066d624e 000000001bb3ad7a1446eba07686f32d379c0738e74ed815fd97885dac173374 +12200 00000000b9601188fd6a59bafda3a2feb5bff5fa7b9d6f5004d6140e511bff15 d149fe0bc250a6e3d5f0919c3143d9198396e9d105093fde219354b8ebce398b 00000000a37fef4c0a479075783dbc6aae6ea4472240e148ab3c26cb6df21ac3 +12300 0000000037f68fa8220084e201354b83ec8fda23d9ab65d606e1e9400f6ec009 84ad4a4d62439e51db6fd03ab09f65a82795914b8e11b76816d538ddf9c06994 0000000052b14f173760304dc2bcc0b3bd6c50aabf77734d9ef0582a7a39962f +12400 00000000c565a0514ed49006b5bbb429c46683ff15cf3c90daef8a6b80724ace 3bb633d09209572c524c6784b6cc4b5e16ef3c6844b40d4360d325889e001b85 000000004ee96874c5ae3bf40bb3c5b00aa95c526a93cee7d9e272e185b3d3ce +12500 000000001d3fe4f9d83b8616e09d9a95d52f789fb875ed6e0cb1151c46c9d0c8 c7e0444e2b051c5b60cf896643c000e059563649f3c4718344f58760be77e77c 00000000e82eb2fff1ab11ac39ee85a82a3d74f7e5d9cf975923bc028aad6869 +12600 00000000ad6ee886602ed02e8b95cf1f505003641923fee37de5ca1d0ff2a847 1ad86ce7a6c2656f24666bec65aabc310e34a73b4a48868d28429098f8af359d 000000008d612e3797a883f4cd99eb5e53e0f8629e41a76294ab46e2f7104558 +12700 000000000ee7b6b2c13f68ea175b5289d3b9dd265d2743802619af9642743ef2 cfdab3dd1b1379f601f5dcde0ff38f5728c59ac05115749d745eee2d9eda1d23 000000001944ff5d790a51865409cce44fba8c95e814999b37f28e6d1734da72 +12800 0000000019bc5480b84950863db6812b824ea5db26e393cb2d440d1fd3715574 e11ed8b2e42031ef763efc3a1115f06d30e5ffdf995b72ab98d62ee0c4f03c1f 000000006a5cf979d10c2a1e1a1bc5d02804722a1ee97d2512a686777c0234c1 +12900 00000000f7d7ceef441f9df1da26114a2400a742684b8276c507b53035cd44a1 00fa0f730a704a00c7f088aedc9414931cf194c9298c93cc6bd6444567940dbc 000000005e87b918ea95222ed7a17813a6c1dd19f63612657a22bd7f16dc0e8a +13000 00000000d85a4cf33f325d339b43559df5c8aaa1c2af2c71a1255e95f6038b5a 7e2c6ae7ac4e5373b19715ead6a576aefaca9babe5e3a586dc63d2d4227547c1 000000000b8052896a16fc806fca2959b0109ec20ad0f7023b162060c693a183 +13100 00000000fe4bb91998e202103da359565d32c4b4461a7234eda2c8f4d13fac04 a13a507bd6ed6bca4ab0ec9bb66d3b47ff0d39b8b4acd31b58633088781ef25e 00000000f73ae9e3cf5578897a85e3b5cbc32349d5945121c3844de1c71259f5 +13200 000000004426b8f8aecb1cac441ad7bda340788d57e8a3566fbc522e7fc84406 2d111f77aa682edf4da1c0442db49e933fcfc4be1c677c00df0e82d9c364b208 00000000518715c170dd111de98a17f39f401b5777f582875f1ff51fbd06c2cd +13300 000000004828e05f79d9e6f7c0ff5d81c367d32cea04b72a0e4d18ffc607400b 2a01c67f8cbad4ea3b230c22df68e3b9860b86851a480e3291ff657b56bacaea 000000008b382f8dcdfbe982dc12547505ee9dddb34b5708e6b0ca95cd3ae277 +13400 0000000049a03def008c43a709d320a71125fb623733fcfd6a8adc882c70ae0d 50f86a22d37bed18445d6244a9dbc563242efb5e389566be2f4482a8723872aa 00000000c4b3a8ebd661f37381279c7ce01f7d0a962e572fd6903da50998d245 +13500 000000000ee07793903b338cf2019da24f2a34386d56e5f5402dd392cbf24785 ce842f21d4b4f11c5be1e143b1011de8756fcf572d1cc5361e7f21de5fd9e2c3 000000008f60f1dbf2695408eb31d0407034398befb44ad27f8c06d05a2e8198 +13600 0000000006ea563a08f0d7dcf808ca93506d2795cc202a91154c9089a591d2f6 d28b86e53b959c82eb12bc2b03eb036f39e0604289b8e4bdb2ec658de0f13e4a 000000002259e1ede7d2d7b0250262a18a2293b32c56da4c82d265f368738c22 +13700 00000000248a9d6668ae484c742995f1b21a0d2a083143cdabf6665d061e2d2b 29018925b827f7dc8ae093f4baa6318303c375e915a7f63222b956ae9cc37595 00000000a09539d95e6ca95111641ecad17687ebcc05864f480f112457163035 +13800 0000000077ae1203bf2923b06f2353350e2df017b2e9e08854f78ff013b948ad 6f0dc6cdb7082e0073f645bec6bdea00493ba4cd0a19b9df0a6210940a9801a4 0000000057831ae615c7ef5c798c86e00fc57bf68186dab9b90cb37c1363dca2 +13900 0000000062619c9794c44bd6fbfcdf034adc67076485577a54ee5f285165d2be 4da35600c143d39ec74c2d9508714ea6b03421f068265e29ea01eae4cab7dc72 00000000b37d7a36d0cdbae4bf013ddc4087464d3db14c391fb5a1c3459ae32c +14000 000000002d9050318ec8112057423e30b9570b39998aacd00ca648216525fce3 8d26d6dca5672b405fc81c75b7bbfb72d56ab1bfc0b150253c70f52baec43110 00000000b44efc0402c4841e13c29e2843776abd8ca1a728b4d12a092966e87a +14100 0000000036735c63fb9c6c25fdeac09abb6a3d991a6910ec88e5ca8cc8627d5b 5a078ae114ef8e266f958e48fb46e3f427184ae4448684f707dcaf8faedc8702 000000000dd68d782e2c4bf63aaafad290ea0c28966ce2914078670baa747e6f +14200 0000000059bc248e02560ab9d2a7cdefa20176a800b71e08fa7af19dea403d83 84ba5a38a1cc985e40e96e419b36a8b63568e72f31488830941b3ac6321b4a16 00000000b7f4eaf916e6351c5af3d69a95c833a22cf87c00f52a18d232f785fa +14300 00000000bbf4e352c9971ca07752c990027e0b68cc5d296e8637dea1dbf845f8 8519f9459eff0d528198576fde2bb4004df3d396ae20a668decd118fd1334636 0000000046f6e41d8675bc2924d33dfbc969bc86e830ed0f186eabd113526249 +14400 000000000595a55c095ac3b4558a03a1502b244446347e8d81c1b97b701522bf 59acba8f92560c13d4f2136720a51ff2c19ac391696bfb9a47b55a211f23a8b2 0000000028e4478dac4ddf81f9344b5534f9d55b78a1f1a531545f1a6c3b3b64 +14500 00000000102971fce5695c52a40b5f427b20072c583250cbb57d3ca27923f584 99acd415ab692429987cce0d95317ce5e5e00ca4d898b86c0fcf584d682ae17c 00000000d5bd79e259e807af99992bfafcbab4094dc7e1af5c7b3dd28a2adb5f +14600 00000000056e118d4e662ac66a37687ba186d563acfe86b52293df4ca787cf9c df6ba09ccc309ae8c8cfca306fb0dddfbc66457e650c17ba3b5eaa14869abe71 00000000e72317e3692f1d3f3efa4d5d3ea926e56cd6a850efbad426c8142d7a +14700 0000000074882bfe743333f8e5c0c1adc560444b18d41334164d7862c09a0cbc 26fc460f6c2ebce72540b8cfb143508d679bcc255469e4ab7772dfe6bbb50d90 00000000ed0ad507d4c53ed9433678ab12b28925b252108975ab3d9d8b68a8af +14800 0000000001d994858ca98829022fcab874361539845ed1c2353c82c6373ddf49 fd8b2f1c65f8aaff8de12b8a0dabbaf3fcf047e47db32e8b9ea86b81bb2dd645 000000009d9d4cac52c74bd968bebe43edf132f2a1487f2faaed66f5cff44fcb +14900 00000000171391e38f611a6907a387948c2dff5a576a298cd2c0017fbb6d1493 2ab74bf138c3a84943b9e1cc463a1a26c36378bf5edfe81daf6e24a1154289ec 0000000009bcc61ffaa883ce16f2d88b62203f04a5b5128bfad9a359545f7cf1 +15000 000000005c3548bda7c3d3e2fb2db21f68b87f47dd8b7ed095dfeecee76038b7 844c7c17bede5cf3035a04d7343a8e280561b19bd885592da26b88a7aa61e89f 000000003dc0cc439c269a5cced1a770f65f4e59e0741fea52edd9959a1ced13 +15100 0000000037b9e684a7060384a5a7d607793a5ed2373fcf6827f852015f18cf36 6a1d1555454fe5c3da69a69f14da79b15acba0dc18052dff78ecdf7e1b5e831d 00000000f0f8de4daf1f63123948ad2dac134e6d3b6db30ad1d1d60471f944d1 +15200 000000007655941ae9b51587e3ec3b1a2fc6da7b0cd152720baa6cdfa3280cf7 a2782b6b82effbe9483b054a68fe9e8e0b4b67d1496b375bd9bfaf7bf1a1d097 00000000dff236e856854b2aec23d07807520e1ba9051b8e88ac9f9b3d0dbf83 +15300 00000000ac1debc9b9a430372843951c8a4e61f12bd561d50f5d96ecb8326042 bf9aa313605353c4235a55cb12b38b7c8256373ff505e4a7d9bed88eb9d99a0f 0000000068e432c0e63d1a4a6428280e261ae45f3f6cb40c0ae732eb122b97a7 +15400 00000000cea8f9819b976381299be1ed0ee7bf50a43ada4be0b6586ee2df9d08 f4b85e7427c7fab649da0dcc2fc776a48fd060c22ec131c9f5242e13acbe46d9 000000002aa6a35fb54b1ec830033e62eea9ea88b95e02f30ecce0b2e2053ab7 +15500 00000000ac8659ef86a83415f54e92cf870090d8a4f528b4804264e3c36ba00b 48c021ea5f3d4754cd5c584a668f433989d29033c209605bbbd5bda6a10c6687 00000000496de44942d7844590be1bb9ce500c59a7797ca4df406ad3968fe8a4 +15600 000000002f531045360bb2f0ddd20e04e0615d712cd17e4c615b298ed14c0536 2feaac42a198a4fef0a535d310c0de57599e1a0c24f3bb7331ad85e45960e11e 00000000e15683b663c37efd5c87ddb98851ada5dbf096b9929f0fa45a72298d +15700 000000006598379df8afb50af8bf8defddeeca400ba828fe42c93166ebfbd171 467f4621ab2900bf2b188f1d75e6125d6a34d543672cebc8247ebdaedc60e2ba 0000000074ef0662f8d1f8630ec561a273caa28846d049353ac3436dd2104560 +15800 00000000657edf33b3c852d1b1f4f7e82c210fcffde6e4fff46a0c9d8f64eeec 9ce8b29002be0a02f121fd73f6787e1c0b99f695dc2e1668c329a35af6fafefc 000000001e9ab73438c44e4a6d42b6fc2164fdfae3afb511f3f2c5364929945d +15900 0000000038b78182f7e60d5900749f143c4c33b6f09081e2cbd125f63ab4c5be 1dbab8f961d106ac1a7f0d7c69cb7d156ce65e88b9cc29ca6fa1dc5f77c4c3c8 00000000f86cd50356e5263d96602512f89b103af8e6573255008dc193ceed4b +16000 00000000679a1ab3af6da03f13a0bc96d7215e65458b2d2edfa030b5b431e8b3 3cbebb20ab230e673bb45415094b0225efb0a60329c6bbcb3f724571dfde7933 00000000bfd11dbf1115ca74217c55ab3938e59b2cf91d862c00354b65023043 +16100 00000000c6907e502c525418f7353dfd67bf15bf83448dffd78332e7ad25f2e0 54b64e241ab0aa7a72a9e2c116f383400f7fca4b7673172c77f9ccfd0c4130f1 000000007135937dfcd86ea9f941a7c006cb26aadf4f47a873385642f6f75566 +16200 000000008a27b1e1dc69baae5c20aa1c1d65d446d45556fc6069446de10701f5 cf8164ac2e6acfad875b1962ae52446abe7e5b630c16de30a854617e5dce2450 000000001fac086551ace4aeae7b8791625433a9131dde91f023163b1db41883 +16300 000000001c462bc17a8d94c169790e579b5708167e78025a3eccbb19b8c3d98a 5751bcd74756f6f84b5a9090f4ac064bbe99366389a6cad01212541510b68f27 00000000afa548bf23e3b430f407a27bb0e0d333498655ad80c30ac24846fdaa +16400 00000000867ba0417f786542c9c07f2f4d95340b33d5cdd25c3a44591c1653d0 7e454c2c77b1be7a7c751d621979c42e509b9b5b7a4dfc889573ff2ffbcc2cb1 00000000b246106e430bea62475b7053ae6094689d0c3f151ae876023b31b8ea +16500 00000000de6833dccf6ce1dc4b6861b80c922279180d7e1352cfdab4dbbfcac2 075166c94c8ee781bf2276992693c1e49335abf96a77742bea8e6d4c525d10c9 00000000a1a74c89e1e8fd8b352bc84be878eb764b80f7fa32d666c11b33d799 +16600 000000001f61302529a5be46e3591abe65d7ee4be6043cfc13ee80e24630023e d359f48bcdf3c323e7f95ebda33255332a42cbf0eed030923bc4e6c44c8cda1a 00000000ec2c48646e356109fd8006b7e7d0c4eca6357b80d7264048808331c8 +16700 000000009f0a393b01a015965ffc36fd7854181698a20441524a4d8c5b762e6c dd6620aae52cd399e4459023447c211549e0c39eaf2a42bfd7fd15f6e2a0b451 00000000fe80e7a138fc66610c711160371cac236ab83a6754753ecbd1a9a750 +16800 00000000c24e37ac749c11d602b83c6b15c91495f5a118998419a0affe4a6380 6b12ecf2d5164bddaf74a7aa89b1ae4972cbf34d969df3c19a85c20633fd856c 00000000576d86cf60ab26c1e4d42af9bf9a95a9c6c614f409dc1c46458c0446 +16900 000000003ad3d7c17ccc9cd180eefe4416d1b4c448a4194aeff173465b4823e9 2dc9dfc945558fa75df56219b229c25cade3b73260e7559bba05c996937c7a05 00000000ebefeaff2ba095d0d996d72dd9d6aeeea957997ef149960beeb96b32 +17000 000000007778515cfe0665840b3697d542469ec21bef64cf44f4975690bc75dc a33b45f760842afdcc13c46fd0d08bdc0157736b9e709bf9a51305738851823a 0000000024b28363ab1cb85d7c9cc41b95ff8d360009cb1fd6604124e5c8d8ae +17100 00000000edd79e499fad9d0fbf9452508a02e99452672a0758f38ae6ba28f41f 7b5a620da3b0979189361e744ede0d528615396666c83028f70c89c15bb36b4c 0000000067d744bb652f388b4514b50ea4e6215cb21c56a0f7ee29428a357458 +17200 000000000749d53cff439851c7713b3febdb3885df33fe0315ff3bae781af4e9 239d73250072e59e6614a83c07b5980575e1980cb4d671e7a6e6cec0693f44a5 00000000a05dead178a53ae587dec7059768ed4114225af0bc9519003eb910bd +17300 00000000ce2b9611a90de04f155b80083c3a4c17d84865a9684e6d252022f675 d2043b96c3fb11795a1a5e67589f894833f5ce01d189c85f8abe5a1f5ef38f90 000000004a8e6ad84c6c4e37e09588554e6c73f00d488c6d6fda9fd362562e5a +17400 0000000008bc4027d2e156939aca5d091014eb18cf828323f0ec8417e6deba6c 0a79359d22b977c843692dfb1f296cd5bf784b312b9b5cbce54a07f9302f3865 00000000825ba37996af0f4c7db800e6fe8935cb9ceebdf618453c2efc142dd3 +17500 00000000a359b2e0673d31ff12b3829928b821820b568404f8bb945bb9304015 37560ec477eb6a61febe78a32eebfa191670035e1e736df982f4517774cfbb9b 000000008b9870160aa9b724d3d7e8a3a3d083ce56eea67e16f63f65fb21a3b9 +17600 00000000e7f78d6ad948e18c6df1e7673b88021f01bfd1a848a7f8cd9df15e91 07aae02be204bc0b5596b5ab75539c5fbabb8595e689cec27cdb11ebe020064a 00000000e1ab4145bea5cd180d47c411c1e5f5aabd5e0ff41ec9f73d9d6e3c00 +17700 00000000dd1dfada6b1f0258b306ad77c1df49cb24c8f1186b1c598f78994e28 839999e1dd039653da39b335b068fc54f561d434e5e7d42ba1fd5e36e91770f2 00000000eef5cc4c17091255fea811bd4af3368339164ac4197d4b5739a17d19 +17800 00000000cf06ffbf5969fefa61ccc1bfc5c0db1846f95972a469f2ac0087717a 2da978a98969f78e762d83a09337739e602e2f1f61490224c65dbe133ad1b573 000000003a649dc2c71341550f06f96bc95dbbd82bdf36c527bababb453d18a9 +17900 000000007259f612c337bc4040dc9c8d4a55a30741850af81353b5dd2b9a1ef5 bb1c7863d90b5cfe492e06d91aa980750d4a68891f1b3a339df167f30eb3c87e 00000000b53894006fd4641e7cd138425683a351d10e4f1548722ea23d3b2fba +18000 00000000f914f0d0692e56bd06565ac4de668251b6a29fe0535d1e0031cfd0de 8a4892c1cfed05818bab06e025640be63d3e230d80306c07662e99933a6535ab 00000000d50b1d5fdcad186077855a0e5dcf357b246238eeeac208052a9ff3c5 +18100 000000008d52237eb864ab4a15771ddff869b21efbca234faa9fea1d5ffbbbc0 8c0f56d93b054d7a02e724bb31575ff408dfb42ca2b6c1b9c832d4a17109db5d 00000000cae545899181924c48ed1a25a1ade3527a6cf354c4e50a15ad112b94 +18200 00000000df25e07f54801c07669a5a760168a993561b0d6b99bb8408f330aefc c4db4b23504f971fc4abc9deb3b073b455385680ea002dded81ec14dbffc5f93 000000005d34961c11090dac0ee7e4fa07adb7373be1357ea71b0107b1b1a55a +18300 00000000680b8d1dc037b26b1a6a47a696463bde4791eee8778c6812466ba1af a4ab40e3147349ad339a6d980d1741ef155c7924eb7dbc70c4ca502689b35b84 00000000e30a0825e6dca65a254addbc3690f676a26147034b727b73e870ed5f +18400 000000003eb2ff6ddd60ac6d2df97c4017180688959ae801d440fd7bee655ba3 c0e9bc1205d844b9d1be01d44081ae9ce35ed70342f9661cb44e98fcd921b999 000000004502cc942bfb87b5c7a411279f33b04b01fb3e86d851704235a8f950 +18500 00000000c73951aa45ec779a3d15830e614b29ca36d5618d6d300313d68a739b 0fcbd60141f9c21ac7c2742f37ae65e67f6cc4e0305c36158cf49ed7d739a306 0000000078548086c6d58a07836ebdeb9351d60e7bb0ef7ff1434ed83fb042ed +18600 00000000c47937e237acb459ec5c2b335ddb43339f5688029b3b08b6c57cb4dd fcda5c45e87282eb476fcd9d70b276128398ad16d37fe6beb488b40a28a75a38 000000007c2b0f1a3c05a98f8da9076701c2fbc84e77bac71828b4b4c8cd8461 +18700 00000000b7ba814633a219189753d2526b6eb4781811da007a41b16624394929 7afe86ee11e0b9c611e8c4829cf82d167ef52e79f6639148f8531c26b3a3ad82 00000000df15074fee2e829960feaf52193d93d6335c06727bee2fd8a83e173d +18800 000000001e80782f725bd0932dbe0fe88bb9484452143ee0d6512ec6bc6d27d6 624dfddb0e9a9190f6ae7c73c893c3d97359c0f737bcdf55b827c8a61ca80d75 000000006bd07bdbe6f5bce1cccc68c72170a63cc1fb6c2e1cffe3e59fa2303d +18900 00000000023463b3fd0628d957572393e8f4120f1b0c482a6063fa106af5d29c 34a1cb6e41157df7498471cf1ab0dd2a14b74a89301a3c985e97a42e7692c02c 000000004eeb3c0f12b82878cd8b47c8570e08b3536803a5dc89e038e2ed7601 +19000 00000000794894208a98d6a323f37e23ead638bcaf3a2718c80a4cf5e846fd32 932b954aeafc2f94408a9dd7681f39d5870260507a2e77ef3a69f8d5b1a9d348 0000000061a6550896ec246858319b224275ef39d376da5c0b9dbaf5ad148ba4 +19100 0000000087e3c9bb84b38721a06a3a34689efa90903e7478dd3790c67ebe388d e2c4ed4c4bbd4e1dcea20e0e9a930f855cc1b05dd6a2c07cb16d356889de4a5d 000000006a2e548cf194aa2705bdf113e078969ff75dd8b8b97922d88ae64b22 +19200 00000000d7df5f0be432e393da8e2ad65a4e88b68c95c88230c55524eab87767 ad4076b1539c9a663150cead52696590047646ed54bdcb634a138b72cb34ad26 00000000c5df1d5c08d9f447de84f30a0512c961e7715d078e47e68283e75f8b +19300 000000002bd5825c558700e30ee89141bed91fb44b8abb84e52eb2bdc8760544 ffdc6f745aa71feef65903fcf50bea5c2663a66df509be878bedff64920695ce 000000001e1cf4c3fa116522625d173a7ceb1e0f78704ef778a88a0e50186d75 +19400 00000000e2977e6e496b1b15cbbb26652d5bf3b66e50909f377fc66e71bfa7a4 bfcb22b6f5c0d38b9dc15d11b669f3c56f6d71c77da19f83bc8dee8d12156d44 00000000886fdc62fe7234f8cb2443c1c387a83e0462f98e5d4939ed66329975 +19500 00000000336815bdad5764dc34757708da4ee4331aed330a7db49c903ddfbb0c 6ecd26a0c9296e53ce88fd88c6b90b651e3d65e4d754082d06bb1167ac15d28c 00000000acc7c39ff7212b35d43ecba6703fb034b3d7f99763889431ecf9208e +19600 0000000074279b4ef09e7ac31c4237829c328ba746447db16e3fc61c52848c3c d879095f7261151e631bb4bdf47e0a4781d85c17fba8b14a4c45c5afab315c09 00000000abcb67af69f794b8c81e626eafc20c2e22ac926b4865060f04704424 +19700 0000000049a9ef969e2ae2f44de940de9266ab59b624a49cdb4cff7ca68eb432 4159a4caecf0079ce3c03f5c4ecfb6272eea889c15510767c6d532c3bb29b596 000000005ab5c46b76507087ab3c9eabcb0b4366fe8afe0e11ca784e5feee2c5 +19800 000000005addbe224c48f2dfdcbb080c0f89eacd2593b02550ed0af4c4fa7dfe 80b87ea04e5d7efcdab0da947c21df0f909a26291418f58eddb6cf3ffa8d7e56 000000008748ef994612564b27fa45fa9b780c562cf793bcbd11634d6c58ff83 +19900 00000000258fd6b0eb962c811f7819cb6b6e334ccb2eadbe32f871d6815dcf67 2bfe025af78c1ba9ffaa483541411122183ec2977848c6a16a547b59a86dd8a7 00000000463aa5564f66354582e21c4cdf7b90ef52644d0d45bb7d850b41fb33 +20000 00000000770ebe897270ca5f6d539d8afb4ea4f4e757761a34ca82e17207d886 06b758a49370094c61332a4bae7bf0c5a3b0bafbfb8d5621248e3502c699f274 000000002434a3edf8dee4fe506d306c59d3bf41f73d979f30ed3f7b7c34d06c +20100 00000000202b43cf403055ac8cb9b14621ee8818e1603377265d56837d21704a 9213b6f48effc6cbf6aa1f21c1621e263af9d90a5be65fd67adc526b7511a9cd 00000000b7f20290fbd1821dac7c09c73677efa02252c1678cc14e9a0ea611c6 +20200 000000007353f9a66d572101425c512e403ec05a65e0e09c01c2bc2abf109bf6 153e65924951c7d23bf1bb829eb60b411f5c60a861f64728fa139978fbd87ae8 0000000049b130f88e7b2496a22c5798c77e0f02996f47df4f897c44b962d806 +20300 00000000fbbf75bd37f69e9c5b2a59c3dee2addb558acde0d8327c4378ef05a7 ec21acb506a8ea8db78d2b6342de228d687e946e017abbd3226c85690136fcbc 000000006f77c3c0ef62b78f038a5f0f261ae0fb1bb051550f3a3d2bb8f215cb +20400 0000000081189ece565b3837c465a44eb77e4bf86d5f0bc24608e84413db8925 ac903553da641e68363d7691162b63ae1f1ae1fe292a34e061fd815f8529a3d5 00000000115bb0ad3df39e5d3715ed376fd0c36f90379a77dd880bf712867146 +20500 0000000068318b0e651c4e6a3a0ed44496f6650c7ae671dbc043c74fabfd1053 b32af1a31122074d6ff03d7cc6b84643190fa29c61f8c61a269a79bc073a5d05 0000000000e0ad3d241b04e6d1149255aa54b360724a07bfbc81589ae10ebfc2 +20600 00000000749eeb5762c9e9e03f3c7eeca586f19a7b39466e9e90a196872a2c95 1210ff1a900aa1b10f1e54eac1803feb341bf76af22df0780bb5fde8aafa0538 000000008dff293f8b284d1860f1fe0cb025f35a3f0881369715c2ae993fa63c +20700 0000000079c8a42466140e5e00df56cee839c4eb0e4521351f2b2b6e8e440290 e601e7d7cb173133f925a35f24540e2f607e87869d97e16f6094ffb9cbf7e8e1 0000000069c8b6ccddafe70aa8105727a38f1851ecc3519376d111feed210afa +20800 000000001e968c39cd30afad9153f35493dd24cdca9f66df8aa32a14674192df 5e8d818fac3117f4d61ded7d1c04ec333211572d7c345ca5c187882f8428fb52 00000000ca73be499578cfa84a05bca73735aaaaa98d2ff4197bd1fbbc06e6c7 +20900 000000002b94617af6b0b6f0b330e75e99abe4b92943847a22eb2497603cc20c 01b434130b110e5f84b7a5f79327e93ecdcf7072a77d19010c652d4cc7cea314 000000009fa057655ea7f5931d42844cb803d7f9f26fde367f01cc65c3088f65 +21000 00000000e435f35c8305e92dd2d4a9b9a29172a745bb7889cac6b5de4c643362 bac80dd309e595b3ca7e535f0023802e90ef94e4414e72386eab8f788d960493 000000009dfb87dd0e92d62c2232306147645fe58873626bcf905f099644676c +21100 000000000ea43875b9e24c082e0d3c304d3a29e5f6b862d8a92f525e27b603ef 847008d0bcc22de07c5df0411db72b9ba9a369543627b2bb91781c8030c760e1 000000001a3d899209c70ef6b907ecd017b28bd0b2318d6c2cb39735198a9bf4 +21200 0000000066b7fed2549e58f13b68954008299d8ca3bc23c4eb8649a74fdc31eb e3420422ac7bb9e1fb6a9698e7dd7ea94ac62839ec8955addc9bd104ad3ec83a 0000000021acc94fd5247e674b67da79dae611b787a35853c933fecd5c3e198a +21300 00000000dcb169c6142f18fd51610527ad929ad0b205908cc39231d78a86d073 6972eedba03c8441596eb0195aac05e018bddd1127611a89f1330b6fe57aa91c 00000000b5fb94e576b87576cf7e428b0439676fdfa3b9eb1d2be98777f34a31 +21400 0000000049ad37de5181aa80075d5df8b923468d43030356db259acafd03ce69 8139d1774e756805e5308681738c1471c2c3a735fad8fba5303b64db8a3485c7 00000000d425763d53cae92e429f391ca58cded09be50bd60859bab2c4ff8798 +21500 00000000c1ba2eef3196cd2bfe90e5cade3df9bd18eb72a7759c5fb5347282cd 18404e45b94a830bbd4697048644c8c34fe953c3161e1fe71b0b8d1f53397038 00000000d5ffe01bf119ead8e2631549b5de71c25ce0081db83b93f6bd55bc79 +21600 000000006fb63be9ebe54f554cdb168ef0706ef6e859709a1d7f080db0388d6a 8c76258f1918a33589c695d444df015c177c39c72ee3254c344f716b4c74920d 00000000d9a1a7443631f7a33807ac7f86538cfe8144aaf170f6ef7914d0c7fa +21700 0000000047e40e43ce2e6181bc6c692b5ccb84045a2a05b2ce157f69a41af8fc 44ab1225dec306687356206259c8564718deef008099fe6a1acfc64ff756ab9f 0000000037d14f3fb19a13f2dccf958f92a84529e2abb58e16245d437e0c298a +21800 00000000d4fe2d10393178fc184b1fa2285389092b561f1b00e4a5bdcd79589c a419b8dbd44822ffd386845214711f6c710c90fc17000e50aac2da5d18255f77 00000000ccb77294f9b9f07bcf006d9f58c23f690da35f48df31c0c2dec650b7 +21900 00000000066e4bf6fc4c59f9cae6c6607b34af01c4ca9f55c8c0eef688a091ec 622a4f8b006befb2dae95e546dd5b9d34e7f4e955dcc8d1793687b47d6ddfb8f 000000004152f9acaf0754e123f10c1599f1c34e539536c4f297d79ab34e1dd2 +22000 000000004625a14242beccb38c63a1f770a76ee5788764e6c0abd4129bbc1b9d adf5939e74e0c3ad618eac223bfd6ec025d31ad313d89574e639d5914dbb4d1f 0000000082b75cb83e6b30ffd99d598b2b3869ae31c38d56e6856cea95ddccbe +22100 000000001065a9ee74a8aa5d64ac0e3cb413537e2fe1fb5f7780e83f241fe219 b476f9a668f1b26aa1f48dabdf22b993bf9976e1c8b951c1b393eec9e36b4f19 0000000055ec3caf5a04bc19f01b58d27c93a308e472104f6ac4be7e5b6480b2 +22200 00000000c8dd4b74f50f5aa7b081b195ed928b8a0fd03385f5b5bad7d70c465b 18a1ae1117f2313b570993dd417642c66403fd63be0ae01f0588abc6866e510d 000000002374e674914d10cadd00f950bc5d9ec4d258b6a62c908c60d7274a21 +22300 00000000ea113d91f74da0a7eebec23ab766a07d3b48bbcb5061c17c19a538e9 c82000943dfe6419248665fa43b4dc1d9c59a21e7c7e151012ea0da2ef7f5146 00000000d5fa1a49b2565d06f5b5a247883a8dd40fcbda3f1b506ead11f90436 +22400 000000000bbf0a8d99b8662a822a683d15e5a5f681117965d5093ce0955dc70f 9e8487eb972d1c676bd0acb7914014d48a99d64f8e0cba4dc9feb4f7a61cce3d 0000000042981ac56d8e82152e67739bcc255879551318b5574c7c6faf6d5180 +22500 000000005bc7b8eac15677fd28c393e3271e52c6c30614e9c211c8c7c2815075 440f15361ec1bfe82e852a34bd737723ae1e8acfeb0a21d9b6e9f5b482c1be33 000000005bc92038f06013da7d75df98867209286ab67653decc3f0ec12af00c +22600 00000000cc55ca0fbca908fe8dba8c6b636f7bda6f60be0377596576fa1b3083 d011d046683267c332c29b05f6f6e0f37e4b8431466b58752382f73781f91922 00000000a8c0e022488cd7e698ac0b3f5d299b7ab17167d0ae4b45be3c0f8bb1 +22700 0000000000be9c8806afa5d94d7c005804270a1f74d6848e36b26b420666860f 328e46e9c79ca55f980c4eb3243e43ba8cf3f754a4000e567a49d5241440d37d 00000000dd14e7874df00e8146d9c7dc8232dabdf668d2b81bb72ef24bb0c7d4 +22800 00000000c57e7a0789ab7dfe15d6c9b7ffb668695df5a3574cb2773691da0bd0 874dee7389234e66160adfe48c0f33c3b0e9542eb1b2691cab01dfff36799084 00000000f285ad1ed5631d50bc0923805bef9f199846d4612c47a4a9673422df +22900 00000000ee32fababac8d960d02b23f97340315d29f8ba14777bf24972987eae 17d29093ca11cf5879a37a79c6fc51178c7e3f00c1341dd903e4f09423708ccf 000000002ec606141e88a183bb9982513f850eda656e05839f7f501a9273281f +23000 00000000034516e6053bcec513c978f3f83fa90f4e569044a59a2a7f3419d487 12911b8caf698b308a1c3fa212484a1c0aeae888b5de9ed42f992e28d5228a67 000000006a476e1e8895027c6a523e35ccde517c47af3cb2c8e248197ce9da08 +23100 000000004d55437ca542122ac21491121a7d0432193dd6e2e378eb5fdf883d7b 7fad6fe5f757e1687c9f1c229f64670f2de8c73cb4c9f0ae9b2be6332941f84a 000000002ccfa2ba3d173c1df43a6de4e1a64d41825f623252914224e2283f9f +23200 0000000046df105656e8c5f0a47fa4253a75fa52e495a98008b16115a4167323 68b30397ce50a35b9118b80520eb6519b62805c9561b2f3ab3a7f5e05d07d1ed 000000001d621e1a75091b56ddbe287d5f536f1670a11e91d0b85fea60a00c70 +23300 00000000a608a36a15bc367d50585a8c25ceeb4a2a473e3264ca0ab74985eeaf 8dd82c3e067e9baf84bc3bfa694bb2ac4a12b8a60279e154a91af06ebdb435e4 0000000099042d4c9ffe58d3fad8b73f8b0928a8bd37eadc952647b3e9ddbc0c +23400 00000000bd5d84af567f2981c84a2f9082a63e364510469f4d3767ef8315b6f7 1e16fc56dafc5398149fe130323c269a7703ad27109f06006dcfaf211a9c4309 00000000296cb4bf9969fffc153ed4dfca483e84d3b0c2e316229c05435c191d +23500 0000000056f7036d31b8f919075b91118460197edf852c2df61f267ea0ebcf5e af93edd8a257cad8a5c60749a65bc2aee901b0a4103c2996a098c2e3f4fee221 000000006567276231ba29858357853105d4da8f34ce592dceea6c269be353b2 +23600 00000000800a83c7a66e584959b61ee47137b05b65cedbc4d6a30dd940448124 a0329d4d71c91aa316aae94d1a63c5a35992ebf2ba40641fc18bb45e599aafde 00000000e034b28f2c68acdd240484d099e96fa6fbc554649fb917ae0dfc1099 +23700 00000000a566791ae620ca88023a4667cac81386ea9a83125b7d14a2898e69a4 c5f31eb3125f6ce24d52babc8b5b1810982ccae0c49b7ef8b3b86cb0a3b2e605 000000002891ac5cc9d03b445b409b91aa4105373f85fd4f7048963ff2072da8 +23800 000000007a9ea937de2bcea319f1476e3eca0404d8ee15f781c575e9aa6def08 61290339a58b4dc35008ae93eb0e6324318d35be704323b35d9420cce91bd300 00000000ce34f4bc124f14e6200821e04ccf7c00a1641c0063ba0d38d9e3c01f +23900 00000000393960f969d2e055fef2880fdfa54dfe48be81276bc67f7f73764650 0a769f9d51c89c7e09a62a059be59cdce663939dec4a2bb325ec65a911f7c58e 00000000737b378c784b7fd03cef34f0c0c1646472ebd097ddf5f844e358b5cb +24000 00000000f04fccc81f37002707e9501a3f7bdcf25f65531f386a2da8af20122e 4e8d0051946548bd40055e27cea65ffb9a316bed16da3a355af3921228a491f0 00000000057136237ef09824c432d8151cc23bcb009cecf49ace17003fe574be +24100 000000009aabd053c0d9d62a2159b2740e39d616535f506dcad343f11d12f580 c545bdaf98585ce887aca4bd26978b66ddef28e64944593dfb36f3f4976b57db 0000000077e9ad9687c186b10feaff958bed8321abf666ca6d3b7073e2118f11 +24200 000000008ceada6c82ff9fec90201e1823f2278453c3fafde4ed55539ad7ad3c aca643951500dc1126f53bb93df549f9547ea58b370d00e36902fbcc60f2793b 00000000109c23b98a22836c7a6d366bc4e5adfee45e35116af0bcb2d165ad1b +24300 00000000bf98231f5d0379b00b8af879835f61efff7730e0d76d181c4cae1b9e 63d4666d40f65b645b28a22b0f38bdaa84829de4eef7d1a610559120506a8454 00000000a497ff9517ec2bfc87d48a843f21239e9d1e91af2126a095e63fbfc0 +24400 000000006ce5f5d5d5346accf93e41ea7f14912ded1a3840dbe8caec7ae1a9e0 7121119c8b17aa444c0cb11635808ea5fe54b72bf6fe909054a37de4d10c6d93 000000006f39257c5e63b0b34706c8b201a2717b32dfef178c9490affaaed127 +24500 000000004df6129bd84db8a3b4eefad3745bfae61813d2071dbeb8fef782e0e5 ed05a276cfa5e4f655d109ed8b97b3c84780180aac4a0afc7a46016d2e96ae8f 0000000079acb3708a66cd6460e1f75671519b94c58fc6a06bd8b0135292b92c +24600 000000003bc743b6fe89f66993cec154f569664fef66025b0202715f61d85113 ddb78def2d20dde73d042677eb336ac8b3127b68b9cfe5fab9e398f1e453be1e 0000000067224997f5edf4668913b6f56476756068845974d759a6d4cfc983a2 +24700 000000004554a81bd62d8c7e18a353a756d85cc9fb6a2c764eeabb98c755104c 90972deda239bde6eabcee8bba8fb77c851a326e4e44f10aea2d6c800461ed24 00000000c0c312834c207a36e7d772a3138b9e876e0f850a9f9642511d1ab555 +24800 00000000d3bf13168c0f1938f68e97a5889683ee15833e22d347e508bc588ad4 68d7629413f631dda7be692c4445b4d1dc82ac44cfafd5ef5b71bf716671f4c6 0000000012be991d183f9e6e0c65679eb48b815f1c40ed5e61f1e5fb087bdb4b +24900 00000000deb6c227bb2ea93ce50c303a6f1a00a1df34c09d75353c5f21f03af8 f5120e68b61f4b1e3b164b81e639b9b4a6867c86ddb777ac450a356bf34776d0 000000009e6e35cacd51720307c2d1009716766308e6aac9bd6b9b1bdd593d77 +25000 00000000ae4b125eb183e689b7231eafa8c992d5b8c952d9f3cd30a79a788ddf f55b16aa5c46b4e0d7563fa761d1159901e8990d5df6279d45595542f3cf66c9 00000000a700c40776e53c325f32b4ff3590ebba2cc24ff50a5e3ea6f1b99ecc +25100 000000002543565369c9e4f85f1e5d7766a78aae245bf8b27360dde7146b2bf5 62bd900baebad643d99a9afdc8847f848ee1c3bd5273174cfd53e3179c736398 00000000af2647cbb9dbee39c29f100a4f56c0485d31bd4fb014faffb00df50b +25200 00000000e1e453f0fd9fb2af8d3a9113a0c7cc6b862d9e7469c3df6daecf3901 f936917406a351f75e42ac6004a2d86ea00f2da2cbc2540e4c77cd1749adc859 00000000b394a3bb728a3cfcf13d8ad986746929a5acd7f7474203a57a9cefaa +25300 0000000028f1b78fcac36df9288b39b7b9b3ab81bc72fab601b01c901bae9ebc 354dcb30ac1a86262542a9f08807e4d466c82b0cae81b146cf2fdfa425a69532 0000000015a13f56b906b70fa5ba1d6840ae1dab2767299cbe2bc72a7b777099 +25400 000000002f219f104ea3f9e407c2801649a20f2d7c995a07ea799fde2bec5c0f 6f2f08c3fcb5a5e86784ffd9ba979a659a4a888627a3d93dfd3107d23de59f4a 0000000053fbadd9d400b4b7e3f1452f8492e39f11c8b19d58f4fa5684fa5019 +25500 00000000e35b111ef685cd2f0f4acdb18aeb454182da22740e525704a531842b ba3c18ca87ed9f71b31185ffc868d404bfc385d0bf4b7382236dc2e2a7fb745c 00000000d6a9909eb464eecaf742b7422d90958fcecc61f941ddc8a2ee03072c +25600 0000000055dfc40e058768372ecb6d414e7e866aeeee568195d1b156fa819639 47ff6a47039b55780d95e152535b847097924232cfc2d58bc44a0994ef47db30 000000006ae73e27bbdf7ed9d3c9df7676389486e655f6e57dcde1cd84279b0d +25700 000000003ee2fa1f7955c68e728090e5177135478fd727bfadd05d88d0f6c264 09c3623cd3d0d12f47bce40b16c80477ee9f03ab940999ff78370e5a5b2fa67e 0000000027599ce55a892d15ffc56eda9eb55f9a4ed2c1c16075e13febeaf623 +25800 000000009c47c22b9eef0eabc380f7b066ec0c6673419c670412a5b6c807d294 1392b95f076e4f8bc712cacf507de258a1678398ecb445f5e68f355c59ae2151 00000000780d9ae6ecb7599e192a68a27af2310644a2a502e7e5fd67405e2768 +25900 000000009fd2e61fd705b1bad7d862b6ac8b2931c0918899bf39de2e45903877 d9c3f1fc9c4e82772762549fc8c380852a36bc8a3b71481906480b75a6ca95e6 000000000b04ef835175d01cb856832d9b968e3140e1352997167e7e56c84ade +26000 000000006d6c151db6d4d67356d590a897a11cd7d8111ee989de6f2f548410bf eae3e9a105b574e14ff16d3d0f6aafd5c7dab94872718d4919a4d21efc895b1c 000000006aee625129fc9ad7ba7930b89c80ebf22ce4448d5ebdd8609fdf0a3d +26100 000000003b8f260acf275f14b900f46a0c92d9196debe4f01cb1a1f9284c6b7e 31bf84f24f6413c0d54686add4c1a124e1a3da45b59f0c1a27f20c6741492f3a 00000000ca963097a942138f5034b757d1de03e37c4c8988cdc4280ceffb2e05 +26200 00000000d119757a02dfbb1a09857d4db711dba70c1f618cac8186b25c29f248 ddce07ba389fbdc2505b06f608c6dc09ea18e981fc5968710423d55ff68145a2 000000000e11b1557fd5729cbfdab3ab667bf7634a608433252eee67ff8c22c2 +26300 00000000a679cb4a2c2858c5a945b75daecb61fd17529d143f9b704f1c4b96d7 594c99f3aaa792be2fb683ab7bf212d165d4df6ea5750540295c97d60de373be 0000000077da6dc461db8a779b116c82fff0fba204dc5619217935fae2cfb1ea +26400 00000000e3c222b69ed13ab063fea70aecfe16d9d5958a6d5c0dc512ef76fb6d ebe80dbef9bae4fd3bb7e7c000ca00cf013d2c55b25a99214f04514f739e08a4 00000000d138437d1433473504f376d03cbd7acaa6bbddcbed1b63485b95413a +26500 00000000508cf2dedaa7168b3d13d04ecbd10befabd4c831e2073236e98cea33 ba0a2b4e21ed6d9c3f3c0653e89b5e9ea4b2e2c35639c8c47bcc2e9303e760e4 00000000350bef4072eb22a313badd5df4d0258b6be1fca1e58710d699947048 +26600 00000000ccaf846a8e8f0dc1ab38bbfe1a6183d69e0fd733fdae3af6c37963d0 c58a1201ff98eefbf36282642acd99f0eabf2a51f8cf737879f040dfbcf0b411 000000001fd1eee68389493636d865ed985c82488af96622e3727856aa9df422 +26700 000000002e984cf2b1167e45c2ba3161648dd41dcf44f4094143719959462a01 ee9e72047ce5d728d8ac8b74150bb513766f1ef731406a832d8097db2ce5e796 00000000bebd52cb92ebeed7eb910964094e1baf44c120daddbb4d25db534c0b +26800 000000006c7709d67f4d632a1a5220d925d9c3a9ae00bf42b2365dc0a54a23b8 65ff4ec5f9ad958eb394aaa6cd5305d065cfba4988b5912fa2a9d176bb7e4a76 000000005494f6a43f7d2f28a1a6354b0702a246417837f19ed3993c22f66758 +26900 000000007b426c4bc2c6b9136b1b1607572b0791a65debcdda0e64ff42128acf bed5a9e906869f178e97bf6d7c56fffbf07b8a03ad55403fc412f5e913dea43b 00000000dcbd1aa5c276b6583a2627fa602bac9de4bd9de81b8461ed4746f4a4 +27000 000000002cc4a38b7e2e9d45b0fe677806d841835af340b10e5c8b51811e6572 0493657ebb3862c9fdd9087724d5e3c8a268b33b0c1681ca792f605c5a34f954 00000000a59b38d781bbb97d206a1996026986a17b6f994489fa76af852be445 +27100 000000005fc9d585503fa5b1a23c73cbfc9d6e4dc6d6043af2b6b34c002d3f30 66f2ae1249dff616b97c711086965041c6e840d86cc9c4d000f40eec287ed1a0 0000000037ae36b226bd54b3994855b81da299aff9042f5115241878b5d934cf +27200 000000006d78ac41bb13613233b2912ba0dc3e477b1178a9997ddc7b59f32b69 09b2dbdbfbc9b2de83926a361ee3247b764ef9642b9cbe85dc281da3ee126baa 000000004d74f5379754079dd6db2bc206761639169f91c569852932c478d5cc +27300 0000000033a77cf167e7ac2ebd0f643c5d2cc438aa50028a9576c9ab86fe0da8 197877140c4b1be53794536182121e393671167724ad1850b4c70c4cd1f43d81 00000000b796bcb5449f493068270e690a397e286bc3970ec6cf0be7b2f15cb5 +27400 000000002aa75846897fbd33a13fefe796cdb0e1e0acd974b2524d776677db7b f5da161c1cf5bddc83e14ad10ce8c3d3f2408f354f4e0877b48a7de2111749ab 0000000033668c1d54f4339bc2e207362a37af592b9e5a93acef4af4980c1704 +27500 0000000065b390d0bbc02c9c2c38c7268163213e6cb347ff1bc0883239a8ab4d ac474e20c6fc95aa037180d54cbf88f93dcee7e7c0fe8a9f36c083a20fb7a8e2 000000002baf632f35408d4bcb68b9d5d738b902ce866b91fc731c76e8da5c5a +27600 00000000fa903a39973a966ed582c4eeb7119e87e2d784ef401eb46c65770b06 9e10efb8074d4a5e3b2b6ef456b4f008f441c0c2355a36f3956b332c195b9160 00000000a8d17f6d9812d123944126c671536294a0af7b116f8c8680e77eb343 +27700 00000000ca22f224d5d5de7cda6bc4763785a4088b85099a0f8055918a21dfc6 d610ca8608af2592de395788bad8b8a746088d92134ccecab152f5c0e7204fb8 000000004fbb75af7fe1ad4fd865dd39e6eb736120987a989f80628e89d9bd5f +27800 00000000b32bd9af87dba2d0354213d63c9524c3340f2613f85e17c83eae2c3d df36ad629772a174642ce37608c52154fde37d7a64b52c164789d313d58bfeb5 000000009370f48d150126349ec68073a29cd17e3c637b2f679b4a714c1babf6 +27900 00000000c120310eb08d1290ed42183f4cb511c018bf15c8a90f220a369e6ff1 520719bf9db43d4d85abbfd5d86a135d6de25fe17d31a7292c8223abb0b894a7 000000008ffd17327a2dcf8378b1c76a54b7b556a4e1509b8712b411c33d63a4 +28000 00000000172c5ed49d7dfc29bf9a18a53fa2d050fa37aa210d6d4080fd0c7e67 a45063d7518e03add7f4bde1dcd765cda8ccf4aad0d0f3870a82b0389b091434 000000007fbe48fbcac0d33fb16cf7e254508e14cf51b1788d400b854660aa89 +28100 000000005708993f39e5ecaa550ac661691601e5713f8387390cbd948fa9a513 1c2d63087f95369989fcc2c8f6319d474eb8dcc94a7ef7c31da9381662af33a1 000000001d177f77b9d7e700e5794c0033ebbb66422fd9e65dbf23d8363338e8 +28200 00000000b96255125ade0737a08eaa0cf3dd5af4485902a9f158d55154634a72 6fd537d617a1c4c01b4958d31ef6f6bf7b296ae16545bcfd984b7ae762bb73f3 000000007cd637d39cef7e401adf2e0661d39e63dda1cf1fed77e1eced10f664 +28300 000000007a3bce783c7a32c7cc0de1cefc08618e25636c9ceb1d8acd0f9d1d18 efa961c6ae7408f2d0d42844831eb2dfbdd39e9845aeee995ce96d5a72c1b82a 00000000676de26b51fc2bddbb752d640e618f7e2c7f09b37222ec297d504662 +28400 00000000b78a30fe1e70d8704debcae67f2e080471d2ada6a1821002f7615f41 0e9b704eb07192f53ae1a566b8304ae3064a310d4496331f28a03989a6f86df9 00000000261fb9afb66e72cad91968f80b12925a1f64a90f50f562be38a034ad +28500 000000000773022d330621e526a1bb89829663f1f6f1d60ee59c1a145e7ecc75 b55c33299c619f6d51e8de0b685e4e41a37a3e46d5cf83f075aa0189424bc566 000000007563e58fd5413f030f69116895e220fdcbcb17b8709755dc955d5644 +28600 0000000002eea5ae5c4296b5ed985d54fca651838f2be20c084a0382544ab3ad 5ca9ee84b2dadaec1d348158f1049b1d0b2ca96e3e74a9f0473303c22569ca46 00000000fd95f395a9ec12452be05c280f913d01226f81179e7bd62179290fd5 +28700 0000000018612db2e77b8c310080f0a159bced20ffa49ec77946fcd45a74d028 8a4fc9c4ce1ee128fd20d781ad44c610ae28da9342c93ed9a0db9661a18bcf23 000000009152484ddc2192bc40c3ad656ab2b167307944d72f0411bb4b7e0099 +28800 000000003b5bd4ba182e000f0c750e9e04d81e4bf4055a34e1721a244d560f74 2fa66d6da62e6111d83aed102ca3c02fd71b7d1f1d17279b0038cbe9ce3ab907 000000008e1f43bfce694fd8bfd4185aaa3d1f0a9ad771405dd63226bd194c0b +28900 0000000032c48fb73e2dcef331b948f3ae29ecb20c9ac65b2e798a9abc7523ec 7b9a18dcaffd0d41b824259892e213c6de8aba55893dc3cdb8e1f7ef79a555b6 00000000eb84e12f6a0dfd8d6850e6effa2ef2c6164ad555b0b1ad42c9ad5de3 +29000 00000000b8b9f3b66b43b045aedc3380780df7e492866683c59efa770bb9a3a9 8c2da5e2bf975e9c431df7ea21f4a7ac2a855b52728c5f83b169e15e575e0718 0000000071b907a3b25b40b1d2eab18cf53953b8150336844b19fb3dad44b6cc +29100 000000009adcbed482ffc44d9a8f102c286169091c6a45b3331a420d9b62e586 a5d7257e6cab3f68e86601c2ec7b08478cb4299a074ba152fecf4e2714894fb2 0000000093293dd19c9d92a5c7842d42499cee38f94f700c8cb15f4665a466e6 +29200 000000001f4181bb58fd5eab03e6def356c3c5bc91c8d5cced8faa1b5b638743 3142fbc493d16094da6626a9df5225d16abde0f3f992d22b6ec7a69f51725e4b 000000004b6305f407aa5b801f8479eb4ce39a18c3394065b49c460b3949ee2c +29300 00000000cdeb480bed805eecb5c2fd12abbc78c5c01bf67e2142ec75c454eb10 894dff463ed5686d71366984fdd61584df09c0b4bfba548490dbf06b77283e11 000000007ba9eeb138966362c2df0782f8a24209bbcf4daa0e8238a33c7e5509 +29400 00000000d0c0573887502a1521453c7fc51cbc653e18737236963dadd8034958 808257af2040ef8b9d6cd73357d64d0194701aebcbdaeabdfbba486c8d5184e4 000000000653faa0fd905140e73e227dd644076e252715eccffc80c076a80f6d +29500 00000000e160f35d20d237590cab613142325bd2c6e762b88a173ea021809299 47da8ad60c15a4ff60067eea07c443fc68ae78b25996b8e529987b1d63bd2452 00000000d753cd3667ff952c5660e1d7f01c4295388bcde4f338eef71ba95b2d +29600 00000000b9a9683e05983e62c996aadf2fb531abb9d5d34098e84e82b0ed9403 7e1ef512b0de5fb5a7471c6a5f9e298387e250db290d0df49f795274bbbc7f20 000000007339435ceb7b9eb21b68f2eca330194a1f6ccec86b5f09a8998eaea4 +29700 0000000009d72ee8b9185c5ab2d72b7dc24472202af49cfd0a4275a7266555fd 41be04370bee8af6c436aec831b7d1e59e58fb57d20b339df157f5e93bdc832d 0000000085aac465a7d915b87a946eb881759814e9d3099d7d7c60684a3275d8 +29800 00000000977dac45efb3b6af20fac4f3ceaca8a2d886dae1e9ae3abeced7a9f6 eee92d829815544cfaa8fa1232d5614ebfe2c49fb9a61d3dedd94a20e2266f34 000000008834a3516d333409316db1575b39de7a83678cf6c7aab16b25d89835 +29900 000000004961b1972d84435051ef6cca02f355077c1b6256ed15c0b463e7dc78 20b0a20bc8143cdc5a42be8648a170d0550f1d277d7e7f9b30c0c970b87f533a 0000000089410fd95bb1453b310efde92fc4cb4215d964331e402ee8508d26a7 +30000 00000000de1250dc2df5cf4d877e055f338d6ed1ab504d5b71c097cdccd00e13 fb60c4ac1e61f6e6186d1c3f734f36e2ac1a68e018d06c779797fa3807a5a038 0000000050a8248e6eda4db7b5919491746c06e2ca458b22c35d8d72b3f3e5b6 +30100 00000000992e62cf373fd7b4f2862e0bdb1d00ac87733d98cbbf78ec7adc88c0 c182a03d50d8291936512268c2e19aff9308387d9ae14a255ae14b8142c2c11d 0000000038efdd423b6ab270e19b772a7e02e36ec612a7299f3e81d8258eda09 +30200 0000000048f54ab0b907fca296b9220aed4f454625bfa298869d967db734a347 9064abf403f83c27a2e815cab2a9d3c90590ac56e25a2f64820b2cc18fc8e4d8 00000000693df5e5d69d391eb579c763284cedf9530b478a95d1f11269acc9fe +30300 0000000032a9314493c25270d43f67438ba25f10957c0040e7a4cc51ae6c34a9 3e9d48eaf83b24caf2d005f21a0abeccebbe5f9e65deb26e9810cb85a408568b 00000000a357b61f2bcb2af053869728c217ab45bca9c324a3495571078f9dd4 +30400 0000000021e0095a989551cf05edecd46b24ba4f22d9f6a97f755f29d8c94c3c 07fb9ad8ebf0053412a07eaf3ad80c479f7f84a66cdd823229a6b2562929f54d 000000000dbd226e1933db1d2ee67f4e2458cb5eeb1141c3c99f68b7adede320 +30500 000000005170dede6e71a5395756a6c8e10fb1c44982dfdca739ff688187541e d5bc54ae3ed12ab7c33da71c5dfe1286677ccc9acb4ddcebdbdf54222cfdecfe 000000002c68740c7e37eb5e5655bca25786fefd444c36f99691a7e52ff899d6 +30600 0000000033efc0c9cfd3c958e07b5c6cde759d3cea3e8f0e5e4a0fdbd3ed1981 1475b3f560e01007b5dc4641946a1fc70a058b1321b27753af36fd1a85ea4c54 00000000046bfe1248ff45ed231291c6c2aa3eeba0f93efa5f097109b035af76 +30700 00000000deb89818022c594925e5d75047edaab7f7d900ebb8e72a9df88bf8f0 3167754bbaeaa6c3412e61a79d9773ed748d02f3b469b9d30cc66f08661dd068 000000002171b216d696ad33011e33ee581e1a617003355fe7601c9185af58c5 +30800 000000002d03de4eb6393604b51678fd28c52ad7282217b9d8d9b51a57f75b97 4db88b01d0434a81ad842534bce7308f104e11a8318a14f2fe44928aa5fcfd19 000000006bb350f988e26b03d307339c6e099de57f1809a739b88ed16ac03b17 +30900 00000000654c6595e1e7cfddff4b87cad0bdc152938fd72d5c9d5eff95dc1e22 e91baceec4bd88283623ea93de3ee8b18c765c28c883bb99ec148f28d6a299bc 000000001666dd390fa55769e08711d4f6830feb57ea20204fc8d7ed06db3574 +31000 00000000a6a6be6014fb079b06ee52c222d1897010c453f4ff7b40dad1c126c4 017347c8df64be8b624bf1bbd14e118cd049be6cdadc15641b87664cc4f8afe7 00000000d9062d83810fb85c85ec8c071e98d3bfe8f377ebd61d1737487e6a34 +31100 000000009c8e84c50c683bfc138375cac3ef95a44943578ed1bcf774a95bc0b3 b5ff243e6360e713159c2c3b8280bf69acb0eae3b5fdc0c0d2e5d935b4dfe5aa 00000000fdc78c04dc84839a926b8f919305e8e6638ab0b6ae022e922680b3fc +31200 0000000081b30eb94106a6a86f688af62d48e8269f663a8c3f784099ff96f2ee 0365fc718453ae4c03c80b5040093401a4524bc547b7ac9d7a69ca7363be5961 000000001f43f2e04ae011e180dbe5d2fd6e51a0dfd6ec841c15c28e0aa30efc +31300 00000000e1c152e60ac01d20f269f967c9c675e48c0b15075fa276c1bb8127b0 efa7abc45aa84f70856bac572e8c800398096af3b251f8f483418188b9f278ab 0000000074afb9b691b6fdea2f4895df9aa6228065657b354636cb586b0129eb +31400 000000000c88f8939a1b281fc8c049d9a5e17598e9da3e59c9824f6dd4061830 6a4298590153254e191641f278b288d02a223ddf627c313ab7d850a5e72f3427 00000000cae4290539b244a8909fb1e884f6c5a60312f2c0c4c386a61529b884 +31500 00000000685ef1db98259f4ed1ae1605053f67379b4b4acc1d94e057f8426c4a 1b74d5ed210564a0c99a8f221364de92ac82e5cb414160d16890df1d7a63a112 00000000c6dba86cf0c50a87bbad2b158306150cd3c66be2c9734ff9b82b9419 +31600 00000000eb336d427cc7864d2fc8e8a62dda629c6b7f3b8e652dd71c1a0100bf ba8941e49e74efd5e8132d258a668578991e401aaa2c54f4cf7b93dc37633e22 0000000071e96a203f6605e7dea438d8b6615b00e3bb5e0471e0e6657f2deee8 +31700 00000000be5cdba89133e7937a5f4049116f3636af10019a12626d0510321b97 a2af1a70c96a8251536ba234d93e7a24c09965640ee6b28688e60c9abfde1bb7 000000005d3f783f7e52329154ce092eef2ec360e0b2f9cdaabf9e9ec1b08f93 +31800 00000000c08401ea469bc40b839c2d5109d5cf5032692a2c7cbae6595ab392ec 2da1c126165d840f2074d830fca692b19f0fd4b6329350905ffdaa88ecbdeee1 00000000205c7f247de578801f614a27a153de0ff73a45c7be2ac54156228f64 +31900 00000000fbcca7123ab071c62812122fe0a0e6fcac30d95554be4b62905c7efb 22b0a96bf815e729ad3dab9bf0459dfd4f01249e7d4e70618509dff7e05d6214 000000001f85b9a3b457a580f2a43adbcc2e6631da8f29b8d8649e0443bb3fe9 +32000 00000000049172ba3ec1b673cf13e3d0049c1c07bb103ed3fa300e3833480055 0148355a80f331df5c207e3a2e3685c1d4be27b304724e3283e195fc67539c0f 00000000a34346ed69d4a8e1d9221c63943aed2338857e72a35ed3bc4fe249b6 +32100 00000000e10b6b7da5575cd80381e3c75d520a3ff1372e39e197211a7dcf4724 8438368d260e6a52418473421483a92dffbfc0a06dbc56075dd9214fac35b918 000000004cd57dfd02f5c3ff94f7775a8e6c5fd1315163ef55fe428a877fe801 +32200 00000000f8d145bb69e3f55289662eb8d081eefed4295df6ed0eee5797a22b07 8bd6edbc0fc2b866b32b26381eafc35a647d0093d9b0c9957f7cb71b03b368a8 000000002b321cac0f4d1e022eb3359e76421a0154b0b3a542eee64fc692661c +32300 000000006aabd4d47b6c19f13d562f7d1563d92ab7708efceb28590a5b9161cf 0079beb2cc00209a21707e6d5694f68e41c97aa86af421956020ee239bac2e60 0000000088b573eb1af70622aae20d935aa5c31b2030379b80c8cba76d663b7d +32400 0000000062a945617a27b81bf17aa4a36219b0a81ec73fd8cb5258a0578ca96b 2fdc3e943f3ca19af681c61d480c913b3df371cdedf1935e04e424c5732a2549 000000008f70f82749c1fb938b97ad17f3fa4dee3af6f91eb207b462b490f7fa +32500 000000000517c518075f866c93984930389b1836d54c68b18079d600c19c7559 6c90db00550d06572e3d4cf23214e775030e2b14994615c5bb5d15ed870121d5 000000002526e5865f9c509988e07ec47df938609258b8a0a37f6538de81a932 +32600 000000000186f1b78f0280376baecc7a1856dec449673901676790110bb9f39c 745182471091f773da6a7088504ce1f17e7544d8a78be68dbdb71314567329d8 00000000032388238fc99ea5e7c3d090717e176747014eacdf01d1dd07e5c059 +32700 00000000886000a7d903955ac999e9fcc0805b25e80ee7006c7d89dac111724f 276baf2b7b87923dd3a61a35e3b3e29f3581b953c14a9a6ea020dcfdb4129165 00000000c6f75cf71d2e10c1c25e4066a9cedb384c6888fa1d09613e91cd7566 +32800 0000000083c73afa07a582549441fcb8f4de7e8c2108b30e105cb5023811bdc9 3cf371c1ae218c2f08d64118902eae41dfe6c3c830b97d5f7ff141828ef932ed 000000007526922f25c28709899053001a053447da2a90336b3595e837389ee0 +32900 000000005d10d7b6d19e5567b7409eadc3d13b78e7e4c5637a1250ac63c33855 8f9843f8eed382c92b2b3c49efa93215530dbdcba46222e5392b839426b60b7d 0000000092b66f9e19cdc145a9bc8d226ca352675746dedd6edd8ff7935d2d4a +33000 00000000942725dd706c453fd044c5542f638c02a6982732fcc32e35ae532f10 89bc1f495ad4241f822d35221ef28af7ac213648e617a33258e4f44bf70f357d 000000007c2f33c042a48f17fbec1915d0eedf2d7a1be1484dd3731964fd01b1 +33100 00000000432ab178d5b2ed791ce9fc67d2071a03348f28a79674c2cea79758ba bfec7abe885936cf6018016e821b3968bf65839fb22e93226d400173c3f59dd1 00000000120aacd9b25f622c15927ef8b804eae93c906b3842b09a5da46b54fc +33200 00000000752382a9aa355fb2a663613cea7b7ad503331df3ac2e100604ed14d4 597b643ea23986a517375eb721ba42cb3ab228a757044649ebbcd9d51112db19 00000000509ed00e8d9670d4ba534288b6b449428d68788ce47a624c69c07f77 +33300 000000003e307a34ee1e3a12abc5e1aada852055febc82a1afdf4a05d5dc47b3 7cc25ba42939e206433cdac80e7816939b5366ebb1ec294cf12f27d176f3060e 0000000038e8cae135ba00e71812cb70d182c675c3dc52d19c785ed1a33bf588 +33400 000000005dac67ecccc6134c3218302a014e60b80aa2695a9874e35958c79f02 bd6c6d15cf59f28a7a149beb0c0e34ae7fce7d100c96d3ec300943bc1395e986 000000004effe50e92a57ac4ff69e24a4a8ec722936cfd3045f927d3ea080afb +33500 000000004ad351192939d8c11cabb03c6b4e96a1a0655c0078e182bacd66c7e5 010ce10c63ba7c3c1ff8479615ad0a18df49d5c30aecb04316f512b0bbc0366e 000000007da6ddc948274cfd6b6c6bdbc570be48bec33a9096d7e34152554f21 +33600 00000000922811d417808514e99a4ae78f610da31c53abd1db184fd430b0b7df 2274b3ee972306a828067055a946e1e97a9b2aab7fca6ffb310b13e2240f4b4b 0000000030304b07c80ccd80d83a4e55755dfaa88503ac215d19cb902bbf68db +33700 000000002eb8a8b7636d666a6e51f8d1159a44e406a6765cf013bfd3291ab61e 3bc06983a94729fd1cf076d08d31d847bed098c2cc6bc292fda84e43c2141fb7 000000009bb5d25cca52dfb88a3ccb114ef5fa6dc584a5b680f5ab8ea33d2cd7 +33800 000000000d30a3dab7c120ca79ce032516f9dd2f99ee161e8eaba802b9f9c83b e566bb922b9e6f2c5827f34d8f3ecdbe73175daef38de59fdc50f811b90ae249 00000000bcfd4e01ec5f327fe98c264cc20da834bb82e3edace31d2775df7366 +33900 0000000024a17deaea0d79198447f1737df25b991c638bf4fb9a82686254dc37 5a8c647e93bf8c600ea0f03dca2d54a49e34af2eded6f7921955c4ca97858f78 00000000d797e258eee9f823905365489bd869de4c2381ae3436f2f47d60bc0b +34000 00000000495968d19210d3be15bd24fdc19805a0ef15026b0bb4482b04a9da3c d7a9129287dd6b87b52597371ef7378a91c6f633aec160c75708f8e419be1aea 0000000025dfa76b856cf6313669d4c6399099abf65402c2d849400427c60b04 +34100 00000000c98dd47f2f714d4af2438db87c51ee658032285942289f299ec35eeb 2288c3c4577d95f0d282e4b2aa91deab107d837a562e3786cb1fda2aa010a462 000000001253d36d5cf9405c9e935e9d26e760bbb0c4d839fd53e361a453b584 +34200 000000006535763e5959196f59194fa16a942c863dfdd94a3389c86645a95c31 c75cc1a55939d0f8182b8465b1ae428b35c200158527c58055563f1fa836c64c 00000000a7cdfd61fac85e8fce2fb50dc8789e6e0a02156852d6fa77dec9bcf9 +34300 00000000bdbd1d920a7bc1a34acd616c708878bf675150a09f417b3932f3ff33 4c66050c84e0b5bf18f6998fac1c7287680d11b6e5b26d0dbbf6230e2bbf906a 0000000027e75333fdd44eda9a1db37439bb983008673e3e93cd01697cea8046 +34400 000000002931e91b9fcea63ee137c8a87885717820e655075cc30db128d7d915 4da37f0866edfc67eb2ad4de07dbaec8079e982f3da81df0a169fd381ce32dbd 00000000959521c5e273a937661d1c5291899ac7019ebf8676d7d314b5784d03 +34500 000000003a8f21d5801b0fb5df97039e675ea86f81a256cb4a1917d86ab90b77 5f735df39db62382e0188fab71bf768ef52bd2ad67e39e5101950422ca0800d5 000000008d04d24b1b46db42d91f7d6bc268b8ac7baa40f9123649e616dde794 +34600 0000000039d9333ed254d909bf87a2d31f45b3613473c42c2e5f36dfd354ce9b 2b88ed99d7a7aa3de15524d96c0480ac843274f4affb2410c868a824cb33727e 000000004ad69fa5103737a66e5da63279862f107a314467244c6a876693477d +34700 0000000074394675015cdf17d3fcb3ef9ae2b4aa0ec0722d26c60c6a7352adbe f5b24fc9e61f3fb8290ea848e3bc428e0b5137abdc038b8f67b56ece4ab332b6 000000007edb706cf26beabcf52f311755e61f5171ddf4f9391f4b43d207383a +34800 000000005641889ee6efd520e97476af162fdfbaed4f2e73397c604d95754e90 731b28c6dbc1f40cc3627d26d2d429c6534f6440d29ef316211d8d2b0d94baae 00000000ac8e8a8e175ee44c977bf3099e78b530d45a0f61cf42b0e8a7e470ce +34900 000000003c6569dda7f2e47c8c1f73845c7001cf924d1b50f4efe84c6b4e9bac 9e357958124446e832d3a37a37e57db9a5581f280d8629f129d27243317eaf79 0000000065ced77df74219649a0a43d96b3526c2ae4ec56ff7f871c5cb79d77d +35000 000000008f0cdb273d95e830c726b253b80be537cd21867b0a03ef0a326df91d 50fbdda56f55afc2c506c8631b8ff01433fac14f26a46084052745dfc9507fcc 0000000061b31b7d0a14aa4bf27c5df50519d59e6df884ea46469369d3f60218 +35100 0000000061056ce2feaf07352a6a9a63290fa1e1b6d6e1f3102066285e7226cb c2b7ef6cc10ff06736237e13721e2f06c25688662bbe54536febf4199cb62584 00000000217fa4253060862c998df51645f8c1cc756d841a710409504f2cbf6f +35200 00000000579d908b5d44c3a795614385abe2e537f14281add566d7b95960643c 02cbca5565814dd8125d69cf1a8504beeabb335f81ad6ac37e45e6f868a9b7a2 000000000c400f8ae814d9b3326eee8862bd25892fa2bafb318576943e7c2ae2 +35300 000000003a0faee7090590ef6747c3bc693d87f32b54342a986337cdf63fbacc 8c9d85d17368eb02a4e2c50fdc158e4ceb44e2cd6f68ddb15464893be511dcbd 0000000025f7c0cccbe84c690011ac18f213487ae7578ce04448b73ddf9da37f +35400 000000004d321d4f633aa46f1ee1a4269fbe84f9e00eb6d6cc7dee2b3bdaf808 3903e985c6d96dc18eb14105dfd7340f21a9f21e11f39f4039f71badac5a21f9 00000000b0d00c86e24b978f05a077527f7df3f58a17127cfc717899d60829d3 +35500 000000003d5ef2c5891c76e2a3e87399ff2c5239c9f38303c4ea357f70e6d83a 9970a90791c49f2c63cff4d7d1a4fa7878ff40c02f7933d000dd3bcb074070b6 00000000bcf6cb499a5ef0be8b67910e4f7050a86d9187378139ad16e82ca3de +35600 00000000a8e6406194847e3a5dbdc2aadc715f73d6b71ef2668582e89a13f25d 8010d143a166c4418a62db82249a758a3e27c2c52808c872987c721fa7a15a27 0000000002491b806453df2d549e1fba58bbf58dcffad8ef1f32f60104faccbd +35700 00000000b4aa46c572d2e7cdd9f32b58347413b6dc73f53bd9eb68e9a8f7fa09 e6ff5cf72f12be434fc05814c359c2bb2aef3f4085cae1f6c37bed4574da3440 000000003c5edc83e279d888f690f5bb8aa4ba5a67623a7cf92e51ad395814ea +35800 00000000493746ce4e99f3d4288fb8f8cfb605964dc35cd7ad89c3412b4d7ee6 2a01f454a8e147e83c435f1d25d50ff8572ac339b3eeb7a286305747e5a7362a 000000000a07dd8c94aeeb8017e1d6c696e6e9399de41f45f5fd9daf24f46330 +35900 0000000029ef2a38c3400a1d59df756b1690e3a0b1d67500f882b8315932a91b 20bef484fbf9373d7a38bb562d9c444d606decb9bf16e27dc83604bd89bce3fd 0000000072a9f2a4119aeaa96b39c6a4961f95fd55197f26ec9694de986dca10 +36000 0000000080c3deea35dc3df90a5fbe5f27db52f5e01018ae7d62f8b454c71335 41140fffa56089d672d62f6457dc540aba6c8db1716e02b0fa8aa7edbd82ba2d 00000000351f0ae03b547ed0f9eb5e92f6cf6870aedf92e31487465e52d56af4 +36100 000000003e452d0b3695a8ff8d28120889b223521919a4352850c67ee77e3463 aa991db1053dc8dd139a277f0cfc81873413461c2afb39dfce5cee9926ef73d1 000000006827f1c6ba47266819d65aa7345c27d254b770f45c26d0a7d0817c8b +36200 000000003d62954ab422bc6ff4cb0701b57362dc96ba0e69ba04b42500300fbf 4b4b5695fc79f7288094fdb30e74e8a11f923298a23f27eb2456602c94124e56 000000004c9292e4ad5f045c489b06329a38222980c45927cbc5d44533b61113 +36300 0000000084ea15b5966509b51e40b82b7cfe03aec61a232a4a7ced84ebd0b092 e7314524ab0a8d6b6829e44403457f52578ebd48742845b889d8b28cce9d96b8 000000007a8d90bba9fd9fb1cff05ede2ddeaf1447e0fffa94c20518a9f52da3 +36400 00000000479cfcd33b8508841190662caea9c4d9e70fdb53bf9a6cc818be6114 653bcd8c8351a255760e1b56a4df4310feb7c16df11b80e56ee831224e5ed3fc 000000003c26c0019bbd1b1668be5a5a282edd812666171c7b9f6b4b0ee042a7 +36500 000000008099eafc787d9043370684631ed0136a7c04f60c9bce6bb51b32c3ad 383db41add35d267105f25c266338cef51aaff619ec7cf872c642eefe98407f0 000000005a917f77c7494729ee4d49b524ce97c95a46de3ccbca74338b99f664 +36600 0000000040036771eb1a8738f2fe8ff2a1c58452883befc9c175b2b12e18369b 21ac8b9260f4b6a551584d02c33079ade9e6a4790642eb87cdcf9784dd338df8 000000004304e68df768ab91984474c39d4fd688bba9e60c917871758ad4deea +36700 000000004c6077804e9d005df4d4ca1f9e11f2d13da5025900744fdf5b17a1d8 8f96831bfbd2227bf7848f173359eb4b01539c232dc6e3cc08714285bde160fb 00000000b8caf2e8864cb31c8a50f4948db11b52ad77bc52baae206c2be293a1 +36800 000000002a939c2e0894ecc1b460b8d62ede0100981a0eb35500bbcbba58a691 8de1f72b59600d600be6950e9a94425d8ba66c6f11cde0678e1d6cd1625e221c 0000000051398007018628cc2861b2e53f846bb7c7624313191ee6df490bb29f +36900 0000000061da1cd9dcf00fdf70d4495d2e67c188612132d697b19b699c823b4b de5b5f7823e6fd9756709f1be1a7bf649c6fe93dc2c8b0700212915fbaa43a4e 000000002d1d6991cad0d57f5861e11067ba6419925156717cf78b29180dde1b +37000 00000000ba03c2f33d1fbdbf2a03d2bb6aa7fb8cff5b5dc6424cf937a8fd4423 58d9e8bf8dcceb9398e8c3257626e71d891dc8b64351e6c87676c8d22be27845 000000007f544d937918165493e06d742c23684ea53c96d25d77ce1ec3a63ada +37100 00000000bdfba0fa27a67f2d298aa2eeaacf3139b9c48790dbe2f9d9393755d3 7b724127ba6b8d1e3cab8edf678b7ad2eb69a9f405511db4804bf1f373c87ad3 0000000031c7d9a7d61836992130dffc187b0ef24af78fa867d4738fa31015ac +37200 000000000719eca768dec6d6d57b7953ee5696f3e193a185d000617a8773858a 100d95d6b3199c6c3a7369b5f7c8b106604e11e35b22dbde9219769a45093432 0000000037f4f02d6df0aab29503ce97b143a5c2bdf3c773001fb427178cdfaa +37300 000000009c5884b70d2a72cf8c19d41f17bf38c50a45b50d9f266bb8ed13b1c0 93484914c3141eff79feae9cda28ccc0049daf30b4213f218d3389eaf8c95d67 0000000006c2908872a6f398e3d05d331892e5c13b87cde78eedb4fbe59aff19 +37400 0000000099fcee3035ee58a65e261efdef8bc3eec9c6e408e9837c9fe7ddf993 c634b77f4a565294b35dd4f5721c289039a0d4f2d7f2315f52fa86f1094da0cc 000000005a03d458cbac45b8efebed9f9b30e7eb8818b1cf1bed8a4f3846dc31 +37500 00000000353eb7f067a2decc5825c2f3a808e00fb1189212a02e4e7f46ed0dbd ff56eded0726a75328630ac2f318e41384ce18baf2af9a3b7576ede71b0d2551 000000004d997e9c6cb391ce9fb64e48ccfce92dbf47284e9935a7f00ce9fe44 +37600 0000000047ae527afea9696590a385d8ea0415d0f4aa8f233f64d5852fa3df88 eea23055129fc43e4a77f4f9093ef669d1e00fb352dfb2cb15e8fd52e8ed0596 000000007d658e9f826b78ffb178ba7abc98ae0e0a81b06f10c133a7d713b56a +37700 00000000478c70fcfca141ee6d94f0776de7cee06f7e3ea8a1e324d743f17b29 0fb5e21b5a6eb5d0ca094dd9fe07f1f956c6dbadcef92113e3d083bfd2a067d3 0000000021069f36c6cf664f54e0a3557307adcd63bba94566ffccfec6dec834 +37800 00000000aab0f89c1670d363d3f03892080cc0afd4d0db7ca0c879179851672a 2621a28e93327334919b63a62646b74d848f15d4548ba6a3d972212877b15236 00000000156d2b50294f8f67cb4f43237085ea2822884db9d34e2aa0eb1d51af +37900 0000000032be72cdb40c8091ed6c22da7299284569e905e4c372842b0cae02f4 fd457ef3e5f155ede7b69a452a18ab90a50e3132c59232bdf5f23e9c13d880c5 0000000007365671115ceaf206f0e23e0fa66509c9edbb1ebb8eee2f656c39ad +38000 000000002dfebce284d1e08b6cf04452530891579b7377669865889498de8f3f 6364d0b929a5a9463ca47d00e28029c39fbfe97bc776e7fa2ec733c5659c098c 0000000041b52b3217479dcac62e5cab86fc9f45511fdeeb0106bbd47e5b0851 +38100 0000000093b76f09ef25c6a496c7aa5328fbd23fe4163d1dab6850724c81f7d2 eeb5d69e3235102ecde9c7cb5cf4f7562bf2bd8166a1390c89c64b3cb009a12d 00000000927d9a7bed762281a99cb5a0cfcb37ef6a7f902ff25f807240adfe29 +38200 00000000a1d77d8dd98f2c416a414bc067fe0fe0c3ff9f71cafa2e4207ed4945 342bf0f037a1189180c33584343617c0eca07563bb09cc42e49124bba1eb9fa1 000000004b47c72433d7a1f09d4bf8d1890dff7632cf6464c9445bbb9a721fb7 +38300 0000000042a957c2c85778837cf45ccddf69b71f3ded0469646a23e2f7d57e4f 3e5d84dc7da1fa5231afb429a65200b72d4969f36d5167e88005151356a189b3 0000000039323b40efad6cb9cc29e97dc4a824327937a4b04e31a1294128fef4 +38400 00000000445f46146285e79c040dc5560160b33729845dbefce72a9e2c4e2ed1 dc19662996d1a93e2112f434e19d2032fbe178b12817df3cd66cc42b303b75f2 000000008afe14fb86b0af4a5e35b28060fb88b7108581a5b62c9b5193f74677 +38500 000000000fe4b0db48711c046390b333dd59650dc2f69b20a666e44202be33f7 7d486a102c9c7b4061ee3217c94dad6509c037d777d4e9f3b603aa517fb36b51 0000000040de3b4b7bbfceda5e694fed0c9933089bb2e7ad464e9f820b700c9c +38600 00000000235d708630407b70ec9470ebf771bddd046488aa0bc1dda31f41710a d4a7a2a8a26a476be2e47facc4f07c2a804a86eb0f4aacfca907c8bdd900dd37 000000001e5b0e482f8d2c2f2fb2df26a2566fd619226cd0c15678c076771b7f +38700 00000000109645498eaa6f4eeb858a3097e9f37c65201713848fda6c9a1b6646 022723fd6658af174c930f739862393b499fae0f4b6e47788dbadbb7c21c5060 000000005cf9f7f489627e57b73a325ae7b9a9e8955bc6de32f618977c84aa8a +38800 000000000b602bd7d66344a22bdab5d6652eeabbc7a4cd28765def60358c3f98 8167efe2e42ece68e2346a7f4439ceb38467015a1e926909b4e9f3f40b51e554 000000001dfde19b91cb1e1860cbdb6f6612c22a77bce22c76ae1c6290590a14 +38900 000000003e3f753167d27e545362539772c658982202a168ebc0da87375f9b17 8667f38a2a71ee822eba8acc9fc1af2eb9079aa6d6d576cff3e2b4f0e2e66484 0000000083f229987445c3be105d327f1f84879fbf5339d5cadc4dac824af817 +39000 0000000081b8c41f27bf3955713105c9bdc5118ddf429a9aedc54b71114ad563 26b2a6c1cc44e02f57c71063a1aa68d1c81db2e1db27730d051cdca296c82e86 0000000013a777083b9ed2bcf634fb12116c7646ed15855a432ec3c731fa3524 +39100 0000000025b47ffb637a7fcfc3a5faf0243fd1dc29a42b1b7b286f096a5d87ef 3e2f6bcfc42abdfe4183a479cc7c1c25cf899e191b390b1afc9cadb41f700ab2 000000008885defa6124ee2d890119c59785945cd9391b627cda63d9ff79a7a3 +39200 000000007e5d61ce470e69b6be0bd242e9634840315da0eb62cf12e5a6f401ca 8418bb7f3d514010f61da9fccd8dd51984d7212dffb2a00af343d2d879501ae3 0000000014bdf8a1f61938bf2d99b1ee8df04eb2fb07a349111499cdc1337621 +39300 000000007d3763ec3ae5b27b620ac360a61d686d07eb88a3d4622bfd0258b622 3132038aef7735a6c93df158e3d4c91ff9aab2aca683f2203aff99fd3508b1c4 000000000fea0772aed3ca4267847af257b2f16007db03f0e7e9fe110152a53c +39400 000000005393646a9207b3a2f1e61cdf6a7d76e8103026308729538bde597e72 c0291079b940a425d4f904d5904f17747ec790f9dfe318d83d7432355489fe5d 000000008c3674c23cd835d5cb672238b77dcb6ce06e57caf08d64a3dff90ade +39500 000000004de45bda95e343d20a412916358b231a6af9d23518c84a30b4f55a91 9fa64ffdf478efd354cc16630ead650765674e5d3acbb220fa0dc7e407351c4b 000000001e12923de4eed567dc8e4dd361866d5f632c7a7b926f2a616d99846c +39600 00000000512eb6202e6354d8ee0c06a878e7bb054e730f25db60b2c8e778104e 4110e70c898b7decb74a6203861accc6ea06bbff9bafc34c626205e3cbb4c4c4 0000000050078db681ca1b474342805e65d1f840bc77c5e51f505fb270bcfbf9 +39700 0000000041bc782d5d142ac6274cfe75ba6f14f79b3e0e52e1837a0214634d9e c0d6552fb58411d175e53f36a0cb9d5281058e2273f72d2584fe00450f2150ec 000000005bb5ac22873939032a23f60e4dde4834063b865a15e5d93a4addf0f1 +39800 00000000722c58b4a1950d2949be63daa4da39abd966053f4d26b9220c94fcb2 cf0dbf4bbf36df57614c1496a4f926a6af641380b8d29f0febdae532bd127052 0000000056692d21f86176c3705e7ca4b218050f4a1eaa191ea5fed363ab8763 +39900 00000000128749d9400b7bba390340445963d1ecce3a7262c4d17809e80920bd 32c704fc984c5eb55b62ded1312c66c08cc4297dc787d9555279f01faba014e8 0000000066a8f210e60553e276165b278fa3b178987e18c5abaa14b696bf7dbb +40000 00000000504d5fa0ad2cb90af16052a4eb2aea70fa1cba653b90a4583c5193e4 745409c3a06c59ee3e1701fdeb3284f81cb938683e9d9289eca17e25be79cd15 000000004f5399dec71dd54b434bbb35a1c30488a37eadd9be7ee61399b4ac90 +40100 000000005d07a49ba59ed1eb33715ca8a69e6d4d26ae92a8e9a65928f124917f 429fb36d9e37c346df8dfc0d3f19284e794fc977a60548a59059540e3c34ea3a 000000007ec42501d3c303c898aa07fa8084212fbf6314dffc574acc31b3e68d +40200 0000000024a30573708b35a5b37ee9fea26c59d5d78dabd8664e79bf15b83e67 1c43b75a8112eb9cafd2861142bef242a75d2c94917475d27d4aae84af380f73 0000000082620caebb6dd0504bce4a4d130839ba9eb526f93709240ea1daa959 +40300 000000002920347d2c38fea1bf99a7a4f5cd3406fd5af4f62a4881ced4ee0242 008dff8481200f10b1d4594e60475193f7a7abe68b837f6e6352836331a7d6fd 0000000085d7bf55d3ede6e828a7c5f221d0b1965c55f4639277ca16f0667e99 +40400 0000000008c8288d3355f1f3b11b7b3bd5706b419c44269bf8fb33303e37df73 5f592d777cb8c5d510c35e892c8227f64458e03d1bca394f3bf8eb2b41816aef 000000005280064f3a75051985e4f8ac9630496021898f25aae5dd994202d49e +40500 0000000053707adcdd8f2dc792a43a681d96349d2f418ed7dc839f6bd384a48e 94e8c0507f5d797fd590bb03acdfff5838f02818e883eb0c5a7100e5704cbe3f 000000004d2bfb650a5daa332496ecb311b704c8ceb96141fd5a4390ab7da9df +40600 000000000da0642d9adc15cc4805ef98a3bdfe69ce83a922aeca418bf4efaf02 2fdfc35a9209c1b32180369c7e08c02fb94f2393f7f84bc5e93ff1903cf0be4a 000000002127c3ad6ec93653effb43fd7780ba621f250deceb69bc995cd17505 +40700 00000000399f6aaaf6dac34d5474f6504d9b9806f64e5e87a84968ed20827898 89f4da14dfc2cb0e0ab056834bf8eeedd93a9b6670c6393740bc06f1e3aec8a5 000000003b2618b6dc3d447d6d63e75c48d9183b48cb260c94f2c439c0a15a1b +40800 0000000010f16d1f25d6999534a83b47713f117c2f320a3522d0c28afcddb4fa a67b6c8cc8c177ad555b6238ddc71dede34a5034ac15c2fbf3cb258178fcf6ec 000000005928d1d8f8a3e4f99b5b23806abd468a1cab2b0fc268361ea6ce8e70 +40900 000000003008f2ff1c11ddbb84a5e3f237411f41ffae1666bf3855cdc3d13e0d 0a47fc815d07b4c4ddb03cd8695cc726bdb3f6bc8de37c5e836ddd0a8a9b3169 000000002ebc63f4c3d9adc38c22f6474dedb7a647a317324d10ae5dffcf0730 +41000 000000001b8e5f1e2c451b0af5703e714d1c31dae10ac65614963f44e819e860 94ae0c38e1803a929e23ccf3eda999783f04a3c32c50ffacb1b6526daf2db86c 00000000119e08dc7e28b949c787d841a94becb466885b1ab4671792fa24a69f +41100 000000003443f07e2b7dafafa20cba23c04a117791afb2c4fe9bc6ba947e3e27 deeaf5cb4a4c34d5489dc20dd8605e039ffca954cea38e57934d72db4f191965 00000000022261782236bfe63e9aa7552a7d77cb317f1b8e7a6affd46743f060 +41200 00000000303056c2934e91f6cb6a08334368ebe506300689bd7ac08b81cf3a35 1edb0f1ff3b5845a2a55320e435ee1f029b47788998b8abe6ef5679acb70f049 000000002b64265956a6bab359d9a1c79075468d106d8a5d7da8648dea4500c2 +41300 000000003afbfc011543fea7f2189441f3b9055564aaf29e205a4429b5acbcdc d3d25e72549a7e64171646ba26c07edbe3a3411ec27657b05760cbe7349623b3 0000000001752d90cbe87aa8a11ef329cf6b2b3c5c39aab439cfff32a4610097 +41400 00000000145f99de0af55c9fe81556f6adf986954fb7fd7522b4433a71c50c09 69d3cfa230877a03bd1c380b34e02ca47c228bcffe017441d0d7cd756025e2bd 00000000392d9d687bfdfa99c9b14de66c39da76d2869689abd04798ae0a27d3 +41500 000000001db947d646891d1357454979c3b51429c4c38a85eb0600dc487529eb 0570908d4be8af5009c6c4ad6b10f3fc107ec1a1b0257db0a126ebd2da0a78ca 00000000163980b0942043fb024edc6b58d64bdd3afe4032e368f1b467eef0b5 +41600 000000004a995c476f065cfb1be77b8fa1ef9eb0c630e2022c0ebb0747511852 df2d4077418b1b49e4c97df7cc61229dbd3afaa27ac481d44f7737d1420eef43 000000005a7a3a2afd5c7f90e6e11c40ddaf010a313e896c6b1e1e506e0e8530 +41700 000000001d4e646fd3f8e371ddf05160719b82edc1f92c740b5e085bcd8ec801 027638f9d3ecacccc94fdbdf07133a96ce46d23110cce738b367b491dedb51d2 000000002778c388748dc9e8140993de661939dae4e63a1efc126de64ecfeb65 +41800 000000005940413d1babfd2ff0aa32f8518cb9b65bcc46fef7b1adb02e1b67b9 ca9e85af5e73e11a12c2178a443b171a8417acf3055d73ff25f6d3d832b06b36 000000003e1f624a5030d15e245d8f0a6e767fa7322e55b99ae6c3c4a94e39d8 +41900 00000000247136e252878c669840a733c97db7d9525458d889fa9d94391f0f2e da3af99b98b5aa5d5192b4d9d7b56c22851cb425d977de93efb985f9f1bdcf66 000000003591b0ea0f56381b30eee9b8bcdb721677bf4d70d7d8a4e499880a73 +42000 000000000f80c09687893406279f62da437a6a0b95b8dc096b30c10ce088fc64 4242fabe2d6003470cb3394b9ae3d3131598bab0b7f03328a949258be209d6cb 000000001865924e539fd6744d6814fe81543d93000e7e9e70c4ed8c4c4d713f +42100 00000000324c4890ea4b8967f5ad909e4a82887ef1454952c456510110c3c177 ea0a28069b5f9b1a0c958b7ddc2bd26c07c96a1824da26f093e3acf6c10b9caf 00000000608253b57890efec5995c1fbc8e9859d11d5e04d9bc0563641d5fdbb +42200 00000000427a3121a94413562ce665e8a143d4b292afa01c109d21b9f617d698 66f145ce877f85ad1866c0f16f6f0c6ba8fe983d25838e10da1f6e946976892a 0000000018f6d3e41d22ffa2a17917562f8590bcf3d9607ea124599fb6eb1d41 +42300 00000000078f80ce03ce82397988d27d37cee362e3cbc3a6f2ab7fac8ed376e5 31535d4dfa87594e150ab1c8f490ed60b7e747db84e7eab780b8587c1deef1b0 00000000553bca2c1b5eb5bce6e7f8e838ab8b35c306995d2c6e7e8b4b08cbda +42400 00000000319681bca8c1a580e06dab33f1e37f8133ee1be274a5fc9694adca4d 40e5e695523efcf080a10d90f5574a5dcd75feab9935971229836c754121b1fb 000000003aa678921553576d379ae43724c5d019b0c012391a955e045bcdc608 +42500 000000004368763ffb8e808e605c05d8feb7f0eeae425ba38fb54dce833fe4dd 9510dcceeb8e254b2dad1c0b1c76965dc31d1c866ca96a6e16b3ecd63f6f623f 000000000750150a921f71cd7e72ff723f086f7b46c6f2b7c21322e7493f86e9 +42600 000000001f4b9e962992c36c6305abe2d285046a770727555d9cc4de29adab4a e645b98860eb5c233879e6d0af80bed06a80f5958d25a17e6043c07872b5c2d0 000000000b62382fecc935f06b79359f52affb7defa97026183aebf612613100 +42700 0000000005da2502a4f7455b40c34e3f52bb47d01e1bb2b15d27a72fa3741e97 fb9fddd0385ca5a42ed894772be1dc9fce2db37a99c8ab75aad033db329a99ec 00000000052f8b7e3467bc8e236f68d1daf9e1376cf3fbb35964620ae864f324 +42800 0000000023aa4cf8b9c500365947dc18e76cd6c06c410645ee28791728bd5f7d 4cb6c784bc04b691c811207d2ed9d51a1e4f5bb49ee8be740517c6c7e761e1b7 000000003915292b1352980e0a50530b0b6a09db469adce59ec7da8fcb9437d9 +42900 0000000003dd99665c63a69a199b767f673d9b1964e197995d4438a381a4c572 36fb034faf10a3cc7ef7160bda05c6a746832e9db7dcdb49ba008ad0e470daf1 0000000016bb64e95550a31f18f8bcd7bc4b5b3b032cfa1ed657163393f9c97e +43000 00000000212265ec8de3a24751d355725f05370882e2162aa7a57d65d31c506b 5c97f1cefe5715d497f9f11830d05485f708f731975be9aa99dd97e5a029e845 000000001fbbbe6c8857eba468a0136116f76a9607e1b2d961668abaf77ba2d0 +43100 0000000004f6ac12474a1e25352cc13c427fceb6f58307f0ca928f096d0f0f9e c7dc13c1930187e38727ca8aacc8f95c6c15725838f628c811c390ce8e37b489 00000000313a8aec634d9d5abc23d85ad39abdcd0db738960a8d4fb1fa2a3c0b +43200 0000000010e5815c05e49d199cbbc96458402d3c41acf9cfdc2fe682c83d2d28 09b183ae6925762aeea0aa2ff537619248e47e5948a161f27a19d3b6d022c132 00000000369dded6a6bd96c2107d9407d99d8c25558cfe81283123390af562b5 +43300 0000000043984efa166bc1f3871b75fed75a7a6ba6a4b6178a5c53704921770d a31b1651f4a8f439b00015f8cb98c581c9d776f7d6d6cc6a2bfd26c54f33dcdd 000000003719441128248a5eaca30ca1b503d803bdac424cc8d3f5215168cee5 +43400 0000000039478d91f89571693ba7d01867d5e76774d550e347d9e04681acb42a d730ebb3fc5c3a30c2d0b081151cd374624a7310e976cd92ae2bf2f831b9daa9 000000000c03f12cadc6287e49d72e8b51bddc1a4ff6cb7b2350c04ba777b5a1 +43500 000000000a5379782ffddd174c3f0753dbbc619729d42f21eb7ac2564c8d7878 34af594c413d03207c6c611ffcdbc51ebee8048a90e7bb370476785f6e25cb2e 0000000017771732f3b804e760f33e41b9702a01ce53e22fa1a83824417c8139 +43600 000000002b1d4b84dc06b0a4423d210b2b914e95c51a1e58fa2010593cd330bc 3827b24d5f110a38820ae89a311c7e20d423abab45b755013f28b39cc566061d 000000002080bea519a81f41f6aef2cb9907b98d09a7ad8e4132b5181776c738 +43700 000000001074b9c645b770e5deb19d91ad2b78bb19a3509b5858c90e987eb34f a34f47b078e06ab66fd75f7cb3c6318d558ef45f9cfa7d1cf5bb629088fcc354 00000000111744e34049e3f186588fde49172af28c21aa64d0b01352f8e9fb68 +43800 000000003090a72829ef159f8a84016e4e48d38a566d0c13bc4521c04cdc0bad 41effb5e09e7b8caa260bd479bf5d8bbbfcf6e43ace0d8fb4ebb2a03c1e6cc37 0000000040b0fb42e391dc80ece31d3a673ce0a1e7a2f7f29a9545719fba5b1a +43900 000000000a75f846d7345c6d06efe52b5f4115c6f421668667a32909672253c3 f1d033829e4a24f4e90cc4f9a2d0bce61b906428f6bb800da6325a2d52cbc77e 0000000019578134a51c22534feefb604c4d8edbf75150493fea6f17f7c0b2e0 +44000 000000000122898b31073a770a97cf599c00672fc8d6ae15652235862f8b76d8 367ff093c81dca63c20d1c688a017d732464a5003d7a93ca8fe49310b8a53fe5 000000001611e0eb1961d279254766d3581143cb9144464df1d709805fb555bf +44100 00000000377ad7d8952aca32788cbc364253c80d43213f9323583d268a1e5d34 ad140154e7beb471e736b08134a50422f0a11e3ba7c428d2622ca595f7a08df4 000000000f005c92534dbd7dccd258e81247f57f14fca27101261541f6182e9f +44200 0000000022e1cfdd86e4fe72f7e29ea95ecb93aa7747ae0e239900db1fac7ad7 f42d2438694926f3980e96b09017f080a03acef3375bb27f5ff86f99ba6ff4d5 000000000db800f3465e80b64e81bcfdfa2e31a82ee27708923389b337a5299a +44300 00000000405f29f468c2d04f0c3da34dadf8a1dfc2f1ecc64c484d386ea5af7c 0974d2d324601d5676e7b223dd293c5a98d5005a51615893923960a8c5312128 0000000021aabe21c123c037e30adfa57f59ade745278fbacf7eff48e909d7f5 +44400 0000000024c6fea5d5152b55b790afb15308c1219a9a43c06457f60923ff1b2d 88b2f503ebe09fcd7f8cd5812b72c7d8fa3c962d0e69c3566e3762ed889bd089 000000002f1c867f7829c56f57124fd8b93e09f50f512e469d91555a61926fab +44500 0000000024ac83d64bd7dd9073765318d5a94059707cab5dad87b9caa3e24146 0a8d6c12ee8645236f56760e8d7eee218933e1bb20dbb77e26b6c89e27f20d02 00000000157dbd4cb187c34b2f41ba8cf7327b11ebf913f13de2eb895020af91 +44600 00000000218e53e9600a7fe16294c4a479b243d1a0d8e493655a6984c4a339bd e313d3d882471af243e7c0fd842cc76f7b88bbf1d64217f889a3b05126a17388 0000000035843565a9a08c37df1c5cccba8e68f1cc9f681c354159c693db4df3 +44700 000000002356785a791f0bcb899705411dda357f8731cf544000fdda15eb4030 23ebf55e0dcc0b46810e7db49c8b1eee02714ce3b9c6f8136b08ff44da7c5e0f 00000000379263a31e88b225de78f87e1a71e7b10a838a91b1d3739c1e4a6ae5 +44800 000000002c59046dc05c3028f451a7d6f9f2f9d76da40f8b9d2dcf79c1a692cc 6dac5c380b279a4b427359302ed88ba6626e2e0b76932f514a6e07d15e06126b 00000000341833144fc2e692e1968f257cceeaae5546e604307d515c5b9fe48c +44900 000000002c550ef4d3cdabef75cd91ac0c3af057e25ec66e69b46c496a4d4a45 d227403c4236125e053ab563cfb67ff8353ad8afa58f593a79d0fc79c013ca13 00000000264aedb41fb79ddded3377e8555f62de18d2e61d48e3fc5b475384f9 +45000 0000000007758365e4eef39e396f257a3caebb2850906f054066a58ffe657e3b 5bdff639c7469cdf43902d54407fc4f692df5b424dbaa772e5a56e6c472ccc3d 000000002e3396163275f4d1c2aaf89a7efcf78ff9fdef2abcb6fbed1ec9689b +45100 0000000017015461e9d4c42b145fbb066b77667027a7598fc65f28ad73267795 5c8db6a7dc51d2bbf618e449a3066a4c54ad79d49cfa21759608c19e125298c1 00000000017e945ed676ec70f850b5e848172f88508add9c02b8882b66d1c15a +45200 0000000027f421e4a286d0503bb01190d85548c81df54323db696588770415c6 ca98e1251a15ec88121398217ba94f431b98ad5b7e99012adf205c3029d510f9 000000001979d2242ec88e231036866072174d89b4d7022f791e3b90b7ef52c1 +45300 000000001eeb29606cfda88f2e18b426373a1eac0d954ce075b3b8e8f8aa6e3a ff070e0329ec99e9bfb66d4afd03fc06428789881390e20b6f0383fc38a4ebba 0000000012fa33c1fc2c465a453d51f4d1534dba903716be3d1e638ff22fa764 +45400 0000000025033d0805935a3944515d3a8ac149ba1de55c85074605846b3750c7 9c722dac9fbbd816533f3ba76dd7ac9c6b747990bedbd53847d61ce61f6bc1e8 000000000c81c0d1e13de7a5a088da8314986c05c76c378bc4de956171a35e62 +45500 0000000015144e5f4f4726ef79ce347841c0b928b9a9b8ad37979cebd1743995 76304ff19cc7ca6f78e3f2442fe4733649b20d0a3862ed4b29381403df9d84d4 0000000023865139cb21217f815d3372d75a1ca61fffe5ce7866ef8b402bef7d +45600 0000000018dc932ab8734a951c2eccc6d485dc6ec908abc40d42fa1ef9a2f4a1 7861111bff070ab0932cbbeb9d61d3d874b988a57c81ea772ef9ad727d763b3e 00000000107d1f94ed89e957428fffa60bb190ba10f2dffa52611c3d038b0936 +45700 0000000005c10d1af8c1b9f4a108737db47d0af4a7f200079e887223a910c5a6 b9870d3342868ecba319169c00ccca146d677380a562e70a5eafbbfbcd973607 0000000014e31bdccae946f796adf4d8649cf469aaf8fc8579578cc581272568 +45800 000000001821e7070ae548f7943c1889344d8a3a0e222c93a18c4c5557dbf595 192e51718838758da327fbf782c31cc46dc2e91de9833fb50b9ff49f64441a90 000000001f1809097f2db2d371d8f673ca890db2a37edb810e9915454b93fa0e +45900 000000000ade3a00346c5a4893f8ec28c93ae5f9b0e33cb6876d5676d63fa61b 39d6c1470492d0e146c718dcfc6d9082638e63332e7e6e179601a78d3eb0d9d4 0000000026e7cdc5b7c9bc5cf295402b15d90a043a03a69b4945de7fae694411 +46000 000000001dd39771dbe4f9fc6da07327f13f894dd2c1a46cdfcedf930fbbc52b f2e2c567a164d03394a101fe898551e4048161b00b758f7ad4b783d13aa8b5ba 000000000a882eb77d5d9a0abd7f189f64f9a18c06952d8e32f03df3c50dbfad +46100 000000001f07adda51ca38c6f0c171130d6150d844d3cce528df50b0813182d8 2b5f5e5b9c5cf36fcacfc6ae58963ad4ad4336d0ed6774d7954ad536e9e85ab2 0000000033f395948283b3115f439b3889c4d1c7000a53d11962a50e5c838b6a +46200 000000000219cfce557178da9b54cc3552f320b0340c7191d5c0a4dfb8633d4d 8aba484cc2b02eae5ab38297b834de302c52c4bcb89fc66260e13abfee56689e 000000001646ac3e406e766522ad79eb26c9b024c1af7bb1bf0608d000b1f8a8 +46300 000000002541291e14acdc14f71d79f027557dc617e0ee1ccfd49089c1fe9d50 9efe7604edecd5c20f1678e6013bfa25b088d150cc57f58c77c1938d902c6aab 00000000021e1e5301c00408cc135a6e2bef87537c6e456e70ae0d0a66123899 +46400 00000000195344efeb1a89d2e5a27d3fe7b4bc6c60edbf44bf3bb43255b599da 88f263451bf5c8b720752d2c198190ddc533dbb2f16a9174235c40f9a40842d7 0000000023722dd0f3992933ea04d34d295a81e1ee430084a7192f500eb307c4 +46500 000000002cf6a125a40239398069a8de99384a334573975551bdd88842d61767 9a7aeceb6e2297c5d407bb278a6d5de9bf16a5e7cfc63e46d76bead420b3b585 0000000029f33523ce94c0461b416d767af34385621fbd93c63a09194d40eedf +46600 000000002b47a4b5157366091f81ad75a1806d2ded9f2152e3a36cdba39ce53e d8451fe70e492d83da4a80127878e6e571fb5a23454d64501f37d80d931d89f0 000000000ea3f252d917e2516f6d6569e507c7e08b5f444cecc64af16f9babed +46700 000000000baf43efc50c5341db6b81cbede2090ed46f9185193ae6772f924542 81a423c56c6b693b10aa1a267aaaf3813ae72d27f79baa3304b1e5aad5a37b06 00000000360db3bd34359781cf7026763943b2aa119930579d1319ac3f6bcf64 +46800 0000000028223dd60a2c4de2443de674dcab442b164dfaae737a63e117f3a6b9 5fe23b6a63d832a9404282396feba8eb348e1dc5704a1f5a919e6d0022775d27 0000000010d9e043d69d50317e7db19acc67abfc69942b1860593566af5bd3cc +46900 0000000009a067fdd8c2e6e7cc505b88ca8f1a79867d54c6d44958be528de782 159758902560f1eecd4ec43b7f0799f54ae2965cb96a0155384c23d2943469db 000000003022b20eba4b6e4ec959a3b70634c97480ad5fd8fb85bcf98b028e73 +47000 0000000000e7189f8a21e7202826283ccfb276461fe5c5813b4778b708ae605c 58d937d8207f2e0b6490f424ae3e274bb4b21ff7f2c23bb54346f09046230c70 000000000a074f9ef0497c8d55b33d3afa7c03161c86e62680e9923caf9f4c62 +47100 00000000337666efa967bd4789e9a0157bb0ca1bf6d692db88caf8243c2eeb14 49d4bf901bae842652ca4798d9bf70cc9357415d64a5e6daade91132f66cbd51 000000002517a94cddc5a04c2ce8a6d9fe68ef38b647a64b45f900a2eb410a80 +47200 000000001b6b6f58e0471f4abb74bd3b2a5f3143f9714d519036a1565cef3ce7 49a5393ebe3b72e34a9f5c20007441d0892959b5312fcc9eb6f7948aaf6130b4 000000001329aff70c8293b844b91413013a7b2a8c4cbef41c38e6abc2b178c0 +47300 0000000029e19b318b91d6dfee11cc9f6ef07244e5032e0d4ebcf119bd91a913 2018f0638907e66f14117d4a990feb057e63efd1e5c63cfbc869914ee5ce206e 00000000254e60cf8848c6c6221e7ec82e70441ef83bc35ae4dba7e4fde5b8c7 +47400 000000001737baeafd3746a28e698fcdc345f4227c126f0354e6ce5ba73aca88 f28df15034c254efbd940ecb3118786202ad52fe927770c74e82722717c31cbc 000000000d899bf51aa7511555c6088d55523ec4c46bc0da483d132c88179262 +47500 000000001be0576677de04f4e9e4b84cb0b0c47a804f24160229a4c5ec0a33e2 853d0fc4799548742224e6ffb65475ff9d3f073bca679a343f0404afcd2df8c1 000000002cca6b261afd87fdbc50b4989350979f31c7c4c56999882e49f752c4 +47600 00000000327b7a58a129882990cf008f29f0e53747d02bde11d02f06d30682cd d181ab7dc9422dcd89243da4a402c2da826b790eca364e88a6008a29696492c3 0000000009179f032618414cb26f46c5cdd2d88fc71e0eb611acd6b53a1fa948 +47700 000000001bd770c4cc8a81ce0dd79b0e57e5216a438c5461b8af71801f9d1468 46d0aa95b1e3a7bffff315e11e1ee78ffaf3bec564f1105f7aa9e71d399fde24 0000000036a54f3029272377768c379eb30c8219672e3a2a1bfe3db0eb4fc8cb +47800 0000000031859a5d95f3a06c7254d4e9d00a76d103ece565858efa4f7d4daed0 13c33f818df84490374dfff150ed64831afc85fb09af4dbd6de03376e84a562d 00000000182a40480620e6b78f913dd6a595e0cecf972c05733e1015cc7c8a7c +47900 000000000113c7444001db1ed0789d1a5e00c5273a2e713379f9d7b6ac69dcb7 cf04807b7daecff81b14c9f946ce657c88b27a943f61a14df10cd85e353d0980 0000000010c566e8098b774a840e9b8b5a2d1e674426257b036d3e012b1bae5f +48000 000000000f3d40ea2bfa8d779010e52cff4720c072ec4b12ed576cf5cf93c947 d247c389996573ba993726b6d01e77654fcc18dc20ccab0555007a994a2ff77d 000000002085503169f527995fc46d02a5e33666493c46ed4516dcc0b96fd53f +48100 000000000641912a2e4dcfc8a0194f4e257416eacd9f556d59d9a60008ac7ac0 143475c81adfd18f4a04ec80a6ba73b0cc593b848ed0aa1160d50f6675c069bf 000000002d2d30887741544fe3d63c0f232850d4188cfab2b3adee006efb72f9 +48200 0000000033726db5ac513a968afc064d6c48def54f8baf7c2423a2f996ea2be8 1c1991b7245ac192207f36d72d79add41d5316096105efad1e03ad84580cbbbc 000000002e97973fe6957b66b0b39c47f327ef91d14810d5eda0d978cc418bd0 +48300 000000001cc2a74548c306191b56d71edbf6e22bacf0f60b457914327c01bf06 31ad975f5be0de5ab5469251770cffbdb9f8b75d5becdcb679945472811d3d52 00000000097fd3b28dd358b9fba1a8796273bd6d6a9338a602e3201c170957e3 +48400 000000000b7c5c4bfd4faf02d647b53740520be0c38c2f9e3bc600c6dab3408d 33927278ed1d222cb05cc65af95f6ba4f04ff5ebcc79b083591367ba9efd2f83 00000000194e12cd9c864b24d0fb45c98b4ba1a52c67c35e2905364e8753f9a5 +48500 00000000035551f2eeb1da841bfe7d95d8cdabaa69d8dbdfc934bc793e19edcf a4c916fc874da096fc515bc29f1499158a5507b2766c13b279bb8b19587261ac 000000000c80d7091be6fd51fc3a6b5705686f253fd8a6ec51000f321fd0cd3e +48600 0000000028404f70d2535ff1eb17a9af71dd3a434e5d6dff2d61c1f28449a93e 5a6a58a9c8224674ec0c8b6d0150ee34b49d78b2b1444ffe06998b3eadda744f 000000001529a98ded32f46cc9dd70afdb2083d72bc46acee57adb712da31316 +48700 000000002132fee5f552ba3be97b7921d89e98e25272174d3699d59652ce1751 5fc1dcb6e775cc92689b22d3bd2ca9ea9749b2b838d0ee14b57517971491c627 000000000587bd3a2dace5d3e92876b24c8744cf40222475dc77e96f8b1987e8 +48800 0000000000292c6f0966e92c4e9d35676fd7f703eaf8808d0d48962d3f2c7be3 4d80035d1737c63397a88ca253bf3de2d35af93b22cee276e5e12f50cce00f29 0000000028f0213a4cc08abf44e5313b9f4f992bebd11288998bcb05c04653b7 +48900 0000000023a6d73ae402047b2f587f9e0f2b57776625f3aedf858e5a28d38ce5 f173b4c664cad7284d0a97eee1fef43581e53c5a97d7cac11d3f83dbf55ff800 0000000004711073834ae3ac5e1c6556be86da325787b96903817e7b035c09a1 +49000 00000000289418da0e84f10d9563c4f08d2b4265443b9b88045b13811999ea09 71f2065c40f49d475080db7f578bf57cbf8f0fdde1ff2867f21d782b33d6182a 000000001ce3a31959d7986679e9a4d072b21fb6e37f9c296eed176f6fe0e7d8 +49100 00000000294a5698f73a52a4fe1404ae99ea00f8858230117959711633b86a54 bb5ccb9e190091a059c1969c382f43e4b23a150a31608d211543bc1119f1dca2 00000000054716b6cab36043e13a03ee26e0b59bcb7f8e627fe9e34bd461a42d +49200 000000002937c086a343b7c1fc1f0fdb300b0ce046437c11b1e9f544282ccbec fef095a94fb2fa4df2ee29510d07846cb8ba9ccf2bc65b773bb6faef7fdd8bb2 00000000208335a1f151d935f0ac01c6f9af80463fb2271f8fce63a8a8130b9b +49300 0000000007e1b27c3c7278bf4cf2fc27fcd122d6440c508ce4fdbf2cfd50bb7d 9f066f061165ec4aaa342e121d73517054a3099c2280c0d82f1a55c5b6860549 000000001563ea1b2050a8039f1f59afda33e7d30e0d62f48f0da8524f1d3e87 +49400 00000000118e5d92a12a9d781ce610b2db1533132de2ff5905f5eb5b2def6ac9 b263d21f4e04ad232b6d55b7248751c63ac094f0a8e44aa715947d536a7751a2 000000001e4508feecd656807983338a180ce942a46ceeecc8f03c01bdf5caf9 +49500 00000000138d20e79a86839335a7d537bd344e731a7a01003304117b016e90d3 4821cae480a1ec03b54b113bfe751dc64676c1dd13661244eff9895354d82a47 0000000015db79a6fb7f5a3b07cc5370aafbcac8369734a28e7b0c3785413257 +49600 000000001c6896e7f45857f25c1ab2d7e379f8e14b3c806c28cd0b88284bab5b e3fb29ef65076de7ac8bb0eac27349feb02f5e97cf40d40748bf4a84e3e62365 000000001c082e285555076f4b1d22482ba21da428ef6102c9faec7ea159fae6 +49700 00000000002f6a3a488ebb3e9ab9ca4fef9a5de53db0553697108a3d3f6f6963 766a7b0febf3a18cd4f20a390e787fa20ba5e487c60f6832912300e13e3a7974 00000000247ab3fa849efc09a9d63d115375a53e14a46e9790e9ac43443c94ea +49800 000000001ec1b4bd7a592298545ce3594f2684f607ae8edbe579735bd9787fb8 12624d348c5939dce70d1782006048ec64dbc88b8ae114039f62603045e8797b 00000000060b61848d7c7bd129ed18af9569fddb82111bc6163ddf51f724aaff +49900 00000000151271963230005382bdd22f0d8f97c535f6e6c682343875195d584f 8d0c6e26c61fea2df212beadd3f609cdda90ccecaef4dd77cf220fc63806684e 000000001fb8f6d144efeba1c36c661320b746a06f9dc890aad92f505255dbee +50000 000000001aeae195809d120b5d66a39c83eb48792e068f8ea1fea19d84a4278a e2d387f2fc51dd4479cc98b5ba25565cf8bf5f3aa9a3e15b48d1bdd5707b49d7 000000001c920d495e1eeef2452b6d1c6c229a919b28196c103ecffebabee141 +50100 000000001a768d40d82d73cb7873977f1fd557f66702c71766510b6276e9ce17 55e8c0d97466cf6ce9c47c2fe1fcd35fcf113a94cb78addbaddb44f3871715f0 0000000004672b91a58d652e341c1aec038039889d89422091c892630153fabe +50200 0000000027fe8dce3f77317181ce3dcb0bc295cc74af1b81afbd4c4d789baea9 a36416a377ab5f8738dec3890e3503214de20def06e6e2ffe6b117d0833d8373 000000001d8a42889c8c62a7c79755def64f13ec0bff0fcd1bcf857e3c728ce4 +50300 00000000162c3bc9dc9c0c49ec7485229a6089bbfaaea06b3d457b1b2a1c8b12 7337ff384f506696bb371b9cde76009b60858c31aeac90908ed42324e0252206 00000000180d929d70d6b5e810e57a89f5ba1eae4d2e1fbe927c315fa79f7c59 +50400 000000001af6e66db5628c7ba98501623bd23ea6d720571ffedf007973be07c9 183deaf6499fb791368fed35b104e9394c5442cbebb7a74213a4e2b72597f324 000000001a2b58ea986bbad76cc644b5be00c2309624b8e4cd2d4d7437614ea0 +50500 000000000f7a00006941c145773c1566ca582d7dc12e0b4491d43157d9ed6e00 4b22a77f055bb9be48c964133eafc226a61672e03a281a3b92f1a54eb17abb3e 00000000173edd7a34524baa7fd6ea867d960e11a0f89429703bea9adad87511 +50600 0000000018f546e92141f996976ad528962959803dcbac1673d596c3c8fa3851 6d4d603bc97220088cd6733100c58c719617932015dcc4962a1b108dfaa5e1b3 000000001856b614b2fbbc7093ffa4d33513497dd0f623b944aa911182f3d821 +50700 00000000035ddf191314bce73df1ec6e3783a15867602ca993b97afc34ee2e5a 7363487893cb1d198f83e9ac427c17b3836a53efdabdfaa5417a681136e34ed1 000000001e80000d9975931e9255b48db0c47342f058e4b56e728008bd30ab07 +50800 000000001fe0678cc4488039854ab0b2926d2824018587f4e66f6a97906c7c43 5c0c543e59cc6aeaaac923415efa4e4d52c1259bde121760d3faf801806319a8 000000000402892108e745f403a4df8a0bab449eacc4d24248447db209c450e8 +50900 0000000018abe1988446c0f3a332da34723818bed05e36afa1ec5071f2be1035 ca783a9a9a117a335df7e84d4f1221f17c809b4aa292b05bad9e54c34bf6fc43 000000001381c40b5ac4d7ae4ac2463a551df423408d210ed707f733c1e681f2 +51000 0000000016aa231b566ce2d1e95405962d6a12d3690c0f01427ffd2b5f4b9df0 5bfb750c2e2c8d5cf6b0b4bc4c734b33f6628fd21463f20b7909e5937a272756 00000000157ffe19b5b5c01069d134cec1e83ac34a5d81e44d16b98058f92499 +51100 0000000015dd90972f84cad9a51ebb192a18a2df31bdc99f1a9bb3621cb6df75 748f68974bb792a7e788a19720839e6183e260c4e2d5b2cf97b122c39144d267 000000000194df3d1fcb0bd428fddbfef5d877b2e3affc2114135e1b9d951df8 +51200 00000000201fae857af713e52fa719e004a954e8c37dfc87b9b2b0096eff85c1 f799d7ba140643923bed81c8a2cbee4d4cde2b0cabc8338c42face48bff84519 000000000c4ede44a904220e66aa0e8b83915b784f75535c98b82746cbfe6b01 +51300 0000000002a960e367b111c7f95b1cf5d9fe660a8451041624a6ff3ec546c5d6 6c81362e0a3301aaf4fae43d8c31bdf83021e547a82c804d8856ec8cd1ca7deb 000000001df1399927afaa6d160cff7398d3706590bd54d9f8df4df76418a490 +51400 0000000001da24c61937addfb3ce5c3bd8dda41168baa33d0ca69e523474de47 0785c60044848b11516cd48e68e0bebdd6e2927355e4ab35a8264baedbdfab62 000000000acb0adc6501d49ce885c774c2bb1a24155f61442f3ed6dcc2dffc42 +51500 000000001eb03b26176e70b7d4e35108df00daca033a86beea0ce9ef0f0aea8b f096b7d4192a3265e957eeb910000fd57e70186d92a60477d3952e8d2f56072b 000000000688dfe6b71522d431a7da0aa293d6a00e121c0a4cc20f0aadd1961a +51600 000000001d4c8aae777f820e4260b61a78783cbe604938a3e6312be0ba42664d 9b4769de0c94e8b2d98f982658a7e0f94e7684bacac47af3efe9611df72a2c60 000000000aec9df098db571132aaa1666c1918f739549f8aa9651452f8234adb +51700 0000000018f490e332aec00bc2108f0067baf851827e78af36624467f20ae202 c5eeff4ea41de5b6728f53369dc29639c33ef59e522c86d5452adcba1b05d1d5 0000000004e198d59768c58fb2819ce67005436ca26db54b0f0b44366b8855dd +51800 000000000a5488f0e96ccef8ec7debf4f0673b7099bd12b11a0695149afaf895 0162160697a1fd16b68c76908bbefc4f9df2d5e2509a2b0e9530a0a7900043e2 000000001127e3281720f7905c43259c2b4906a9c1da3ccd11ec527b1ed57b2e +51900 00000000196beca40517a45241718ad25247b88015ff348b24a1be51be350255 3a084af6a9c35b6064a589411a8d3c51121805f858c52458f1caaa8ed23de33b 0000000006715e379c252a3b192e837a48712dc40c6e12a3eb85eb7b95ee5065 +52000 00000000082bc4398c4aa5bd8d9fc452d60d533ef68baabf594c9e7d6649049f 54db68ecc2acfa3eb60625afc0871899fc5a2443d2e866dd87b4eb35cb397cb6 000000001ab16006f0e6372bd266b8dc97805aef21d0362048377cf03f80909e +52100 00000000038248c718edacda5a379db47d00577c516952e14c9ea52aef13ae5e dca6c8ce42c23c92dbc1125e3069021e9bf9d219ab5cd9cab93f24ee9bcb8513 000000001a2b380c2d3ee6797498a1e90ed0ffc80f99d629380d71b4c1dec5b4 +52200 00000000109ad460c12247592d168dea8a1009afaae3bb2f7400c4cfaf6642ac 3d2ed52f6423a4ecca5d6be4fa169019b5ef4bb205ecb57a515875c52f18859e 000000000bebbb46c9772cc34ff45e1f9e6229d3debce1c200d96b27db4e65ca +52300 00000000129a667e836f8c80cc4cc29cefe06fc1c690f48cd4ec9255f1624c3d 74ee72b020b769d64b7689c97e6757200cad5140e82412c3a8d42025bc88f437 00000000159a607b5ebb055abf80a9270e39b9c793c098c365c0c9a56e8c529d +52400 0000000017013299f5b9c9aaea62bf5249aa11838d5273bf227053bccb841eaf b29c193309e8fd73ab539e7083fbf3aceaad938d8d9ff9035531c38899783cdd 0000000016e5c6815a1c28239b0cf509136b3e55f64773f2f296ed866068cf21 +52500 000000000260878c74a06c00adcdcbd940c7d28cc45a622846dd7a173d25ad14 03e9e29a610302cd78321c502c8163d332f5f85fc9e56976dbdbd7a6513c2d1a 000000001502bba38f75c5ddd51969f774987016ff260ca49d91ae4cdf4a8f01 +52600 0000000010bcaf30353e193b01a6a628cc0332e3c392cbf75d4e9c2a96f2b000 55a0400b95741d2b992500fdd7db30fbcf14abef6eeca7ac09de945f2e050892 0000000008f5ee81751539c8d22cad5365e8fdcbd4e81b42911d9ec5dc33c896 +52700 0000000007b80dc8b09155d6bd0dbf7e0531d45ea4cdc44d2ee5ed2e45702698 684c56d726814a05ca52c69858c9b288bf49755ee0e5237bc59c9ecd079da292 0000000014e883da778207dacc7b877033f9405fe69c47dad933a5792d708de6 +52800 0000000003e5b9f423b612b022e49176a681d62dff2273196ba6814c6a901880 887550b5ccf0a71597eef5faba16bd25e31aa71eb8f3701270c6fe7f34b1eece 000000000e5ad0f67775531e1456e1a0bc2b74d560b909e96c02c843a0fd53ba +52900 0000000001d04464215993b0e0023388b2dd996466f1ee85913f72698f98c6e3 bdbccd6801b46773bd0e14c15428d63529d59df38f50d6a970cbc46855de07ae 000000000a984e7ba999687d55eb4ec06e8bf2d1346a0f185437bd18932ccc19 +53000 000000000bc96af7886cb12075ab1c79711d9589b5051b02f06553c62c22c971 77538986825225968a817a5714fd6219d0651cc1e3d67cf4d9470d8bd8ce30f9 0000000011ac8b235fa2af4c262f01cccc348cefbf435aeabc718cbe0c4dfe43 +53100 0000000005f247b2bdf9708c013c304504e34e08c997b0c179f4c8a40b35d544 219a01f0e4dc37ec036fd90e67f3e2d4f638930daf90d88b53fe9ea3e7338be0 00000000054397ec5dea6057c795e7f18fee43a9a51a4bb5a710516db51f7340 +53200 000000000bf154261376e1b7ae975307e15244c9ff6879f8239508d2ed4af3fc 889a51e6b067aa036f31944beb4c99ad59f828684002f2bd57ba43c0af18a87b 00000000038f7d015d2cf73d8aad649bcf788a133b80d3cdcc17b296ce1c98fa +53300 000000000317b1d1635bd3d906d6aa8322024d47cf6397a12ab97fccb6810af4 3f6138b722821c762cd280dff0c43fe4887ffdb0f993a6ebf761c2abccb9e0f8 0000000004bdd29733fe2e754657a9dac3dfdefcde6fc70228f98d46d0111a93 +53400 00000000075d37d793981da7717e3317579a3376b6485fc9468f0f781bdafae5 3f92fdd345831a34c8ebff059f86dff159d0ee1674763a3d42ad61dabade2f23 000000000176fbcfff5aa666a4e391f2eb0ba20fd41d9c823f6400e344ebae7a +53500 00000000050325164f7ec5614579bea967c8a883cb3883450da597ab0d31a84e 7ed69a42cc6fe64e27c0d5ab0e69511e4153f9b80a25b7fb37dc0d5cef40a3e8 000000001225c081ec30ef9b765ca42efcff4cfb91e0b9de18a5f8ae105b80ca +53600 0000000014ace502ca0525c27439a3bbe2c95742f0aa024c88a4556396a5bbc1 668e316b2d6253b8dc5e6e03147c0e4869e2d47b3cab8fc41e1f9da9ddc9385a 00000000082c78ef79454aeffb6e1116179e43b9b4529a7ce5cb6102e68fa8ba +53700 00000000053f667894bbe2e4a420e066f6564b0d8c64dc308c329925084fbf42 548b36b139d0f10b9c575591d6c71a385df658fc299603027600221a9c32105f 0000000002ca827623ab70cfc38b3b0494d082a027b4d476d87cbbb30d856226 +53800 00000000154f1fab600fc92f5ffbcd13f97a612cc2057975caa27899e1de20d2 13709a2f46e709aaa2d46b985bcc43176749e9982622b80a3e649cd99ccc0571 00000000133db0a6c67770fbedc99230df5134a9bac9eb1e59d3ce1391d2e502 +53900 00000000158b5fbb85f4509e1ad0ee6ec8adbf20c92ea0e6c2c1c8def9b08c5b 85bc84cd4b8a265c9e924b9e8ea485ec337e00bb032ec13a6e51389854824feb 000000000d18829018a1f817dd6700332a7b120940b504ff8baf028204dff07d +54000 00000000144197f54afa21ae7db2bc93eee604432101fc0ebe7966a52bb27e61 11f226514df8008866b6c68f1a8cd2313a0070ec668f1927edd7b5f667c6c63c 00000000100403d4ad879391f3fe2d80f2936eb2dd6389b81ade62ca6e3dd0bd +54100 00000000115172f3a86694b781ae4192bb7cf6caa13089235d3b58b1c95e2b6b 8f5ac9ccff0e41c348420b3134725c2078bca39cf89970a0ef9c03f3870aec25 000000001207d3112d441cf83421ccf7757637755d3010a35bc1c1b74b6b48b9 +54200 00000000141c918700bbb4f185cadafbd26614e5d64ad93c2b8e525fadf81e2c 4996bd0f9d19889c839efbc3ea0d53c434c4d5442c77e2467b6881f2fb8da0f4 0000000013ff9c01a99ee3923e0ab6a017fcc3bd1dcb35d6dddad7f96f3e9c7f +54300 0000000005d9c2949dc9dcd9cf08561d4dd83b1322c478b848343e219ff43130 a2a5834c6cda6e8d432b35fac1c76259df61619eadd7d7b3c8a2697c7c511721 0000000001cd16be81e57d359bb7098bc66cd9c70a25696b27e5f3f7ac99d12d +54400 00000000153b400f2d4fb6a3b4d1d122f526a07626c087a49381d8258cd00f81 95f5ea8c05ae160dc06579046b72f5974167fe8eccedf640bef8a05fb5abe530 0000000016353e77dd80cb56062915e69c67493c67ba0d15f53380321cb7be75 +54500 000000000f559d93aaa9fe1706ff7a2fefbedfa144e852e44bea67a109eb3eb4 a23c2ad760f92e112e1a3b3f67a65415ea1f23fa09d7294eff5277771e02f91d 000000000c74e257b8fb4508fb69faafe8aedc39678ac4b350c4c34b349cb719 +54600 0000000008b14cac6ff49bfe3a231f8cccf40a3f204717781935735587d731c2 d8f9529f173cb5f0fd01c798334c66f3bf43e3a5ec46efa9d3cdb81edca4da4e 000000000a802192ab9aedcccdc36cb5c040b6835590376d5cecef5ab64ea425 +54700 0000000010dc1658d00e14bf262d469225174347566917b739cf1409ee3e5edc cb073107a92e780d2d3e8529a1e469e03edd84acc2ce7b60ea1b693cbd90d5b8 000000000816db8d4cb1e518b594a43f893c2740feaaa8ac00cb97ca4933a612 +54800 0000000000bec6db13cd682f4c4a92da18e063e072b39d01afc226fde2a660a9 2f3728873cf2124450c3be9e19e8ccc22194f7b814a93ba7ad71346f082d1845 00000000052e3a006cbabaeb96fbcc2a2097d2d4d38c367a94506b9208916ee2 +54900 00000000137a5be37356d166e1ebf71335c5544bbff51efde51279db0ab6deda 1c50c116393ba923084a65ad87630637f1606103ca9b76dc76b34565218eb858 000000000d9c13b983a62b17edd00e17f1568a0ed43d8be6c8b2e1a43e943f93 +55000 000000000a629716ce673212ea154bab57d7d2b62aca42683389dfcdfe747e1a 959a41086f9cd1da10bce02103e3ff896a1c1d4f9ada73440a1024f24e5183ba 00000000070fe6b919a2a77d8e23f803cbf818e08bd782ed202c92b66ebdc083 +55100 0000000002f8398c51df4cf312fba8d00ac9f38a2935547c5f0462f253d04799 0cad13da7854ec3466f59f8acfe9660a7c6c267347e969f2a1cc0749ee94347b 00000000017d42554ad39e7be5ed5368814b9bacfe363b6569049fbc12913b2c +55200 000000000aa89e8e3e08a71f72b2263c484d629538667bef9e954f488814681d a86c5cefbb55f6157ff2346b85057878b1d4e9b248a3c89a821f439b24b15c92 0000000009b1cae57239f0c894c446a113112ab0d03011c8e6b889fa6ad2d165 +55300 00000000070ab5aead89740f546d0027b5c6f47dfbb8401aff0c45a5b49f3218 18130d99d694e7254be8f4f27410cf25ceeada4e5984dc155b1904a6ae3ed4f6 000000000b005bc1ad8a6ebf2536164e9e59593dedd3b438188eb5397bad8311 +55400 0000000003f41b5aa020ce24da77d41f72ee565ed2f78cec6311cf85472b50af 3edb0405e7879820d9bade323fb877f3d1aeec323a4e217a61475b394c345e19 000000000a1053113413446a2fbbb7cb038a7fe6187372c58d061bc4875edf4c +55500 000000000bd8c202d9861ce2a2010ee42b5ca387006b65c87e694c3dfa580033 5cd8f5b8ebd6b83fad48f1b56d5b0dff07ecbd53553726f5d3b8f2609fdb1fbf 00000000104bdee080904c54600aa8a80546cd67286602cae27db24fed269e0d +55600 000000000c9963ab5431ad9f8cea6e6a16bc1676bf1d5f788285efc592503a29 30b7dc26983dd839db1a97a428eb25670befe169dd157d9b53f1a25368cba7e4 0000000007c50950aa28ebb30aff51242a0dac4639641adf9aafda75524ca7ee +55700 000000000288f3a9dfbcbc0f3e4d5e8272c889fc43d00d123ed7a2cc5847f15c 404a8a94d3081850290e3ff7a95efd2a3cc6969b701db1cf6e7d6cb80fbd3069 0000000000b1135d491d42538c10e9e855e2e6cb4604226b400fef19ab4fc3ee +55800 0000000002e69b57d750388b369c43e7a99dd911ffd6b558a3b60088b420e7cd 20650d374a47a36c795fe0a838930b9ac7aa68fb317975522b8cd04b27cd3a11 00000000120e8b1a454c2877c42f8e2e33cfc7ecc86b473a571d72271b6d2db3 +55900 000000000349d57b888d01d597c6be1fb6afc014007afac0854ef77648903bb7 ae2fb7bbdc53dde1f068e8cb9839563a1b06020b995ef20f2c44c16ea32c39c9 000000000e2bfac1191ddf8482272b6925b53817a2bfca43148c6deb68ddcb28 +56000 000000000dfa452ea45e0426dd8914c35e24dfd4399037c5e6deb9f18f58d6d3 031d7751817e1608dd7d53ae2b8500e9f1ef27be16bf67e35ffcbd4e04b2dc26 00000000002157f86eb59fb1037319fa879c0afe087ed79e019cc29560a224b9 +56100 00000000101f59e944f7069d4e34cc403eaeabfc89db6607ba53aefb4da81fb5 6d05e75e6ea39b82fa694ff5eb8380bde0cc5a00bfe571b9a1ccaaebf90f161f 0000000007c505cceec93b386fce41a89be522e8af80eb1d81e81fdb7f1e5836 +56200 0000000010c5a13e8b62ca0f8b7600b0e0f0a5e1dbbd1c6209c72cf8f43d7a93 fb48ef6fd737701a3c5509512cc7762eed049abdb3eaf088bb619b3bd532ee4b 000000000ae257653cc1fa1c2be4bfd414e9651c238dac24c402788e988db92d +56300 0000000008e02aa869d860f52b7cf9a75d8c6598163ca7a9d9b51ad0592cc631 9fee5b9b0c85cf3fe1fc3075fcbe6272339082f6736604843d06ef20bddc3e2c 0000000010608c56ca536e97357c1f34ca60c225c6cb208a31b6610130c17528 +56400 00000000015ed45ebcef699d0f4708fde4bfff58b444f1036e2fb2bed4c239b7 ff846c3a40df4740eb7b123369409f058b23b66b86c14b0113d2be0c1302f59c 000000000367e5751ecb3cfb843a7e78c4bedff4f5dbe2c45a2baf29e8558dbf +56500 000000000f981e1d1193dd2a5c2731984ee9dcc25dc81d26a238690036e0bdda 03d6c3a53f2123387f2f34e83ab44e5bd618cdcc5c93c2df76cb520f58c3151f 000000000daea26ec98945fa5603ef28a6f90536015467e068e1a72b5e1bae4b +56600 000000000332d5a378be227b18521d8a1e6fd3911400b01aa1a76e372cc9cf14 f486b8ae04acc54a97c1891262394fc18dadc1c03d09be659374240f12301ccc 000000000e23bfef60a766fa2738a1d91d29365cc5d3b708d829b4c7553389e8 +56700 000000000e85ce4a331c054417de618e31b1da0be4d05b359dbfb01d380f7316 b25e6f7b33c33ac8f5fbbfcd6585674cade539ba6213de0e856680e13557fa1b 000000000ba80f9eac42e53aa3f237bf144c7a3d2c97db4c020b2808a74f3e75 +56800 000000000f1facac04f40235188b6ed052086f4491b1b933ce2c36990d771190 6540b9933e33436a9c2a420cf8d0d71f593a988095c07301444e55b2889c07d5 000000000492599f1c9f2583861041a32171631f55e0a3abddab06b2a4bcebdc +56900 0000000002d32e8f98fef5e9a710c23a8dd42dba8cc764a5c22f3adf59b151a9 ed2514afadf57f850b472a175b4b98144b3c791082410ad667baea44305175e9 00000000067ab4a7574edfa2a9f96ccad909daa97c9d44904f8cb4150c70b2f8 +57000 0000000008ee3753c6dd237a3a3b4f6d19c2651a2ed26f63756e9f300073722d e2e73a2243cfdc2e60ca92d4de0c60fd2f697a85cb4431daab0dc0f2fb80f18e 000000000ee702a3f75854390bc7268ce44585ead2c3b09889bf9fed202cb286 +57100 000000000175f963aeb163e182f7d2035dcb4f6add2e821edb61c2101375b901 128d5e80479c3b1d5f615845c23d2c7a170370e773ab044f30d1cdc16e5cd8ca 00000000057e2ac6c9c16a938607d6fef889450108ad28750b51faefc6cb6464 +57200 000000000953b1ec746bc5af71406aca80b2d8db6ddb418b0b20b9d47e6ac9a8 4bd3bdeda5084ebf75b061078c4033b846498f0a041f0065ad7fbf3c809106a7 0000000007047fb0179c8184f338be86431972ca0a8718bce6515db90aee8521 +57300 0000000005465beabd8eb583ce012a45aa358efdd16f0500404ee3335426b766 8fe984f14a23a0d7e525ff709d5ec0998d095619c742a6ac00e7b671cd68f604 0000000003c74f335eeef41fece87acaa6f03724d24c9398f28d204409bed74e +57400 0000000005801c1894aa2662d04a45ad1507ce5e22fb9689665db39dd091849a 534126c619b5e04a726e3dbcb5b6c49242eec675839cccd6a2e299f7cf0e4c02 00000000150693be3b198b1f93d7ad86c835af408dde0f9d04b37f36a09c393c +57500 00000000111610a60130d221414d1d4fba26f2043ac04d032f0160659e0e532a 7a8af0cd5d78d75454fbbbcf28ac21e2e68060266b51cb8020ca38afca49d86a 00000000055e0bffa56ef75611537ba24848a5431e87758eae93deabd265d1ef +57600 000000000eb6448e10b40fc59ad0b733ef4174f5d86bd0c6044da1969ddd6780 149b470cee18136679ef84094505a09257b1f6e43909774b30681c3aae1a37b0 0000000007842ed6526d4db659490818602ce9275ac9703a48db7459c92e4e37 +57700 0000000014649cc6c87ceb4052e710e2850d217f208baab2558d6fef089895ee ddfe48d8d222e2cc05755721b8499ee5f3b05c8f3b814a2480589c96306a8cc5 000000000357f027f6302eeb650dad2fa16d300e799a09167d7eb1d06faa7e01 +57800 000000000f8a488b3fcaf88a29c8cc1035c38073ed7c1b93a4f8a0071d70a85b 44d99f221f4615bd9a67ea30a63c132a8d06c5f88a22fa0e258a39e100eba138 0000000006989e51a6a1ef0283d1c5a6188e791429191fff7ddb895e35363e1b +57900 00000000134b4618ea4b556ccb33dc77a46106acf8e76945bb097841a5b3e522 5738778bd66b3df164e3f5d73457a910e2a221e817ce4fe81d5e5600731202a5 0000000002c2b312456137ec0d2c3a36dd6b76e8b1eae124b0bb14125d44d9af +58000 0000000013e3791d288d9db814c52fbdf240b2206eb8e19d7dc80013c60c0c00 e456a9cab5e63f45ba7fcdcf5c66acd689ea9ac726927769fe356eb265b4bd1c 000000000e52b80e848807d7d0a7085fd561b613e5045a492da9680d380f84b0 +58100 0000000009c4d8afc783d13838c2ed81f55e11e27c496b676b3466a48e386eb5 cea78da2af01011bb286f60b59e95eb557ea79683006613c33169afc4fc4c182 000000000ace0cafd3635e2fdd2e4bd4689046ae3942fc84ce3cb12d4e34277f +58200 000000000dc42a8642d3694e7b040b4edaed1394b29c9df835c0cbb194aabc0a f7859f9176970c830622ebf7704b157ab85205efa24e9be1aea6f9d10ceb7774 000000000f13607e5f9af5b15ef27602da15b52c071cd321f3c61bd9884010c4 +58300 000000000777e39f52c87035c2e44ed823d95f8430a81f799859d26c92c2aab3 8344f88773dcb0a65e449cc3b5dcbb52273f220056c17a7d765f0a694598d79b 000000000af1d0c253e0b4cf11c215747162e314cb958373ea347c65c07eca54 +58400 000000000b49042a958655403395d2a35b899aa3336db7b810b7c7db32c2a4ec 2ece7e6870212491779d37a0531f6ee394a6cb28af66c64566bbd0f3a8c7417f 00000000120d240e0472f9779454f437bb53f4ede1187860feed1699c6dd1c12 +58500 0000000002b95b79690ad708aa689d28d688e7fc881fab227ec6f9ca2a5c7a34 71b8c80da5a0e894b47e0079e208dba20ac2db0424ffbd601bf8cc8bb87b97be 00000000095c02032218cc7ee6797926ed2235778745a6383b72a85766dbee8f +58600 000000000ae6fa1c3d462d196c3e3bc941d8740a95dec84aa023e0f3c0afcec2 ca0e170bdf702a65c9f13e8a48027ee56f8784733e9cd84e7ea0060beac9a176 000000000c7e5b19bf10ac1ea0144d72c399642b9efc45ff74bd277d1f84e20d +58700 0000000006be4143a519f165d5ead76ed1dcba494757466c2747b1e228faa120 481562e3e902c8b0efbc23f08d80b1259c0eded1d3300f383524c8290b5c9cea 0000000007b36f1719f85fd937acb01765ee8f4f4d9c0d084826ad707373270e +58800 0000000007de4da6feab9b03352eb3782b1dc49553f9e916dec633f8f0d49eca 124e63ebdfc1136da528de3bc015bf94cec445979181a960a340a6c3f665fa97 000000000aab10e3bf8c988b8e1bbbc146d1881b590407e5428c592b132b3e39 +58900 000000000036c3510aa38546df1c3582bae3140c2ec32ee78e5a83fd3feba24d bc4379be5f4cb3287b89ce7399009001004b56ab40914a57840d4207508bb0d6 0000000008364f1a6270499c0a15cf3ac38855e09b40d50308b5fd11f26007ce +59000 0000000006ddc481d2874ca7ca98ffaae9645b6c7e316bc80e0415a072277d27 19d96128886319d9b0bd00fbf4886a84515f2c6c8ce299c2fc7a77bee3666f77 0000000001fa071940b85b1e04faa53f634599d1e878d102ad2923b6b9b46a7d +59100 000000000bfbc8cff186b4d5680366dc650d98d88c75481c9e64aaa708ca24c3 40c666f360adc1b54cb94668bc55a6e3a90e8f58059586a2c39bd8db534a0c5c 0000000006d3b9c79d73b7e81a7e99ec940e70ce5627ab92dc5eed9f8b2b491d +59200 000000000a469aaa47e576a8834d2fa2b89d1718e095dd093570b0983e7a633c edf3dd174261e5ef6b5a06705ed42a381891a4867e035260ed968f87b9584c43 00000000040c6e9e3d08286ff67cadf84f79fcfb9cb32518e39889c3ba25ca73 +59300 000000000e13e28c2dc4da5ee48d503a56cf6b276baf566697c97e3d8ebed67b 70ab308a12994defa46011d3d6fc6112c26e4357fd062f281c8d01016b1e0667 00000000081d1cd5481332c79a1ab03802e2c3244f2fc0961f38a48a9ddb3589 +59400 000000000733a05fc5cb1d3f9b3371baafe2fce77f6d20811dd01f9197e7ce02 d9d62f2451535debeca42fe0b13b2b79beb225374c903c8e46a40756e5bfe7f6 0000000006d7b22599f400a0ec7bc8769837459339f82c6c7276ceef4824841f +59500 00000000096af43105123c499521e1d131d172e7e1bf2ed0843290a921f1f6a7 d56e5a5e18201e1af0866222e75f04ece8a494edc9cd9f6c1bf2cc8a7ff6737e 000000000d111de83e0873c8d643d8625d43691cddf199d075ba75ea260e978e +59600 000000000277b486ccb1a98cda87a656b57e2f741fcbbfed42dfa2ee1a3ecc6c df928e32dc791e326bdadc380da41ff7371bcc977b078d864fdd51d05e06d835 0000000003da52151951a15bdd4427d1dc0ab1f8c9a82bde2a83ea0caafa281d +59700 000000000c9cf67130f3f41ad0e09fcc624c96b795bae954d9a31204213fa560 747f137d01abae44168ab978ab0de5e932056adb80dba93d3366b1da3c66f584 000000000f2ed8035e9c99f88c7e8a45257e3237a5c3c16889b9520426091a96 +59800 00000000036264ba3ee70da01c97f7181dc2fb855bba146083443a483a23b391 1aac4f8c165ec29d1688a82aa25fe7c14a08926549b06b0859d700492bb7dc07 00000000090c7bf36b30050a987d979eaf1690b2dd5dc6b9c78390983aea1cc4 +59900 000000000d4533b0a1560446e1a6aa9767cba71892da93c06e24a9194661b129 1bc6f4426345d094af2d23d2a09d125214372620259bbdb9b209d8aece4e7635 000000000d8102afeb79377dd9284a687e0589eba9919afa680a772f24b2a99b +60000 000000000b554c46f8eb7264d7d5e334382c6fc3098dabf734de37962ccd7495 a20742dc1fd640a7ae617041e24365e5924bcb776becbe7c1fc1d92d654adf9e 000000000ea6be82e57bd76b1dfaccd5de0ef63d9a0980310a5148bc4bdb6753 +60100 0000000006033e1dc6c42f752c25e7f546dfc5a2e37745eaae68a2c805ae96f8 e4063c6ae583c557f39172798a5bf3c8a6c9f092039ed108fde5838dbaf1e2ab 00000000050063e3d7343d2a3ea503a3120646e7c546a9d2b469714b6598d29e +60200 00000000057e2e535bd8394638d2c08bfb5d9dd77bae356e03aaa2e08db9d5a1 7569ff73e8c0a61885482ce24d89fa76683b05babdfaafb5a79d7ac10dcb7184 0000000001901bd23dc2766c310108b68aa8ddbb36df7dac19d81cb93e97f927 +60300 00000000085e3f531388ab902b9c51fcc0a2c784830cf04a72558a224696a60f ab63cdc66a8273fe3267e31a4ccb5c016ff4dbf8ad5448c9c52e8c261e41aac8 000000000a553eb0bcb3be3b966cba542a336076322c2e642bd0633f9622ebf2 +60400 00000000036101c35d5c48f5c124d0ed280dfe48b47aeeb5521fa3c69f06eaa0 ad45aa5370876cd3fca805c1dbfe9c6e9f4b8afc304e28802fbb83bb8f22dc26 00000000026e4f1cb47fb653ca27a88438ead41a9440b6327f2355923a09aeb2 +60500 000000000c25025a1f8aa51ff7fa645488d8fe85d0e4791c0dbe1585ae06d021 b3548fd2a5649286acb16fae1ad09f321974d9601c734c15ce796753b2bdc8e7 000000000a3eef2287fadad763ae9981227ed8fc3549f9fb9e44b1687a7aa84d +60600 00000000037acbc20fd790ceb76f1edb45b238a897944912edb4a07031df2932 deebfbb83e2c205b7149733895f6bb899f45cfd7312753cf03e208983b8aa40f 0000000008108c291abfde63ffee6dafef95fa04451d5461da78f7e8ca8de653 +60700 000000000c69ec0ea78ca77169fba57ad133a89fb703cd85599290ff17202285 814d6e1d4ea4c81bcca71d9484e8be67fc54c36da3daf6f900ad9074aa99b8bb 0000000007b6f07ae71e0203797f622ce7ea46b3e2cd2f08ec91520d15b9adca +60800 0000000005ded69557de7dd14b6800e7fccaf5e14e2c402acd0dbe8274b16a34 66962c87f6f5ac66520b585c24f49a59d31723c1ac9155911a612fc570acff9e 000000000badb1bd4e870330fb7538c5046a2c7bbfecedcdb2124323171fbbf3 +60900 0000000001bcb34aecc82fa499842f1c187477445d3146059e629213edc2d8ed 8db944eb52096c588c54fdf535b743b2781a72184987b45b6f3331b43d91a3ce 0000000002cfebba6bdda8daecd604473a738abfaef089acc610a2d3aec10759 +61000 000000000045edc734e45c83cad9424f9946184026c9637527067340f3c7c65e a5623efab8d2065a53492a01fe849b2321132d0ddbe9dcc8d37b1b055be491d1 00000000029871f2d8c305a673c2c8f558916ab1e183d97b4105658400672dcb +61100 00000000026a327c16c03be94f8e2167ea0a2ff21da22904788cb2798a3130b1 8116b55c5a9e663042479fe8e3604ed8fef59bd41431511f9e55ec2430e2f326 00000000090f92ac83d254334e054f63ce0184d2c822fd83298d42cfc814d794 +61200 0000000004ea522b5c7f294cab1a44e8bf253b56a595d5e22f555b1f418a9b9b 10a96d19774005522ee4eb3c99a52d3d3834014b903c9f99ce7a2fbe10ef08b7 0000000003278d07ead6668a0e85796c7ee975f619d2a01fa50ab3dcf69b61e0 +61300 0000000005ccf672f8aed3ebbfdfe6255b8d71235d0a3d6c66460dd291f09908 5fad8d391287869ba73208bb8842252d80e9319ab67c84deada547aaefeca78e 000000000405b2385657ac404631b2913c29b72dac7fe6d0e284c74f0cac8bad +61400 00000000071748d956bc9768da7ca507bf2fcec92c296421bd2fb44d16d62cb2 d1a475705ced5d43e5d3c033d4d01eb2775f99dc61ffe880a230f0d09e0883b4 000000000b95f96ed748a0b06321ea53b60a12a65f8d636e6e1035df09764dea +61500 0000000005d354a48e71695e4fdeecc86d78e4e65bdc016442e4597a7bfe6bcd f9a4f70ce3d144ada00778d7f72cc0c0af7c69efe781cf469488bfb260c2165f 000000000c69f1b78fddd0975dcbc2c1a4279290fcc6b5187e6f8345950c455e +61600 000000000031065b177c698ac59d483e3f089f1b94ecfe5958a285d7dccd0775 71b0f4f082332512becd04d75bc4b5e6efed095461a28bfe1958d77d6a72ecec 0000000005ea1719807201a36b544e5ee7f319c554a3851a4e19dfe034f0f139 +61700 0000000002b013fceef07c2be004406f28cba9b5d29ddc8179574cd284f516b7 3cbf9f62a298edc60708556eb34acb2e342b0b7c1b63643576c7853322a2ff2c 0000000008653f6d079dabba4d4f0231e9db1847f7fcdff9d1a3ab3ef13874e1 +61800 0000000006a6427e644f74f57dd1a3090d766929d1006438a66e42f558e9f7ea 8bf794363c2a75b8383c46dc6361cad47dd304e61b0761a432e38ac14f6a45df 000000000b5c3321950d538338780437f6b4c3982ed0d5cc449d2fa33ec3143b +61900 0000000008cf71aba35b065c8624567dfc1451911084967bd98ba98e247de502 582a9675eeef51851a65fb9695e81d16f74c6fb7daccabdc7c8a46425f57b91b 000000000618b6a3bfb5f5326caac34959678c78317bdadfab42b2202c6adadc +62000 0000000006dd4bc72daabef992f860e703820de119af3e24a1ea6f6c81521011 5c27f5057023817bf4627bf11636df538f49dafc758a67f956cc32a38a547f79 00000000014597753c3e08e3b1d191c14dbaf96e6cf5727be128dfd4705b5afe +62100 00000000090ce0d76805fb286ec5cd7b62b04ed507bb8fcadbba1ad79a753ece 4814c70ff9c169e5559ce9a4d1617b1d410591eff021e18d33533c12b92f93a3 00000000008eb7882477fc0a7d1b59d3b2f1b7548ed6f5cd8a50b9baf91bd964 +62200 00000000092e39678c44974fbddbf5856933457e783a10c692f0631bd16a0fb6 7f311422b2cf24fcbc081daefcdb2b672ded7dc3adf6b7bec52d06224a1e3423 00000000002949aaa504d78f6aa01e9affbec77d29adab1006cf220aaf82f6d6 +62300 0000000009bcfb36af34ee8ef374424de8330e670c16a883b593228787bb3bd1 b05dd8f3f13ec44afaef0b7580803d02befb11d42397b0b29b83aa3ad83d6a5c 00000000014f45a8dab36c8dc352a093b8d896da7285b493cd98ec30c3a5b6e8 +62400 000000000d51384d5c7573ebb8ac95d860ce2d1bd74ad6c228406b55f71dc75a 9976a1c5ac496bd6f7a8147bc5eb100a7457006d7f0bd797a6d70efa33c5171b 000000000d742c21de249759b45192eb57bc15c35dc1241f6f122e5b7a451545 +62500 000000000424d2cd4654499d26eda28c570e08ba7216b49b4b97b08e7e6f70f4 59e032d9127c40e6cedd88984a7815e2e198b24cbf9b68e7d0b58433bbc34487 000000000347fc7112144f84c40989f2f3a5dca70bbccca72964b9c25837426f +62600 0000000001943d1f4441cba8a77b9aad4f1e8485203c5ff2e952398f896e8e08 1f84688a9ef08ee56b2448c964e1115ec8f9765aef2b40251a97b932353e5d81 0000000002c025f0c0ee78424c0294daf22cf6d9cf75a13a43b8e24084158c1a +62700 00000000011728b7b980bc921bc8ffb0bb064a73f3a844bd125ff70973837b24 00c955a46df368a6929bde5170d808893d86e8fe83d51b38270277fe3d3c6759 0000000000675f5806dac93392ab5ce8c240e15ca814185d034135ad91da4ee5 +62800 000000000a9b8faae20927453c6dd13e6ae86383bca56e5daa14b9606f93873e e11ce5fa2083ebce61159866d54c0b1f626c2677036c812d1c8c25ec0d360794 0000000009524acd10591fc25aa9280942d25e234ee73d7755719759965f77ca +62900 0000000004ff043f56b9a6f15011f5cfe31765609aba940d6a554f9bbd496aeb 6162bccc2219b1df41caf02aef3c08b0af2041314b4d27646b2d99fc70ee805f 0000000007018a2b32c1f38b605de2e28e94284856e6b90aef0aa15b008b742c +63000 000000000abcf1c5c959bfbbdf5ad13054a1c43e60e168d6ef790b8200e0891b d312dfc87204de45a36758318edbf2d69e238b5deaf551a18aceb8466487d82d 000000000c27b31be4db0ea3d800ceedda97cfe6db4a21746d319d2a56bdb50a +63100 0000000009392c94d3c022d804cadef8586600ecf2bb0c6144f4850dc7d68362 0bcf5843c38430cd9243ebbbf4ec4b3765ad8eeb3b8a127653f4a6549a7ae1a9 000000000158294f8afee900741b2658f925e76f6bfdd770e4af70476134d94e +63200 0000000008a16350d67c4357222933fba95cb0e453a933a7a94edd9d9a33decc 31be1ccaedffe6a24ed2015c6828379449c3025c38f4bf46fe439fd4ee50632d 00000000082f0762f505cb04401c60d9b04d70dd3757ecea6959a130d826e452 +63300 000000000b1444048e7355011bd392ad84cc458f2bacb7aecdc3387d83df76ea dd84c57255b9e66a2e3f07ee1404b1ea06245ac98c0c7d2826aa2abf320c694a 000000000c5d690039c277b4c87886fb82aa751484197b4c95913030eba6b960 +63400 00000000045451515841f4008e4ca6e61bc4199a98baf16349d5041afd90a7a1 ba274633654de9dba390012d56a797b9904432882d5038f7281d49385239f2db 00000000090f10e38908f30a99b0fca845e6cfbaa6026c56febf0478e4bd15a3 +63500 0000000004dd2b5b3704aa330397b6fdb1ed337e44ae2746fae5e1d7e26b024c 00bbdc26d892a2e75109cca61fef6a86a43f45d34dd85ce18b7d0218ad2b2f1a 000000000422c7553a6e333dc6b4bfc33b4aeb9d54fe0e8398b2355be1734c54 +63600 0000000005b762c7e37aff0807a14d9f420b8c28ebfb647ea1b7128cbee80a8b 2378e247d36cf5047f728e01488f79ab0ceb0a717bcc1bace3a538ff8cd185c8 0000000001340bec0b1d732bdc33643e1f7d5cc056368cf37a291f9c535f3c87 +63700 0000000006684cbd8e5a124ab2f2990ca515025095b1edac910742cf20bd2a91 4a65ec86e98cbafd990abaf1a8eade6d6f22ccbb74eb60a602031604547e3576 0000000006b7e1f852206eacbd79f63bca7bb06afb3dc949460593d3feb8e3e1 +63800 00000000056f77b69482303b59c91fd4f597c068fa394a861fd95055ed47313a 1e7c3c10aef9bf203b7161df90f8413bcffa8d00f761050b51ad3c7ab6ce9bb9 00000000038f8444b27e752910dc32f79046a0029f9e65b04a9988ff356f3fb6 +63900 00000000029c99fdd7a8a2a6eb6ebba061ff7553169f56f1e98d1150af3a4072 5592a1a414daefa5c767ddc3653c85bcefc0d570473c62fbf0639565c84e95cd 00000000096d434fd508d75eac1d50112ff8ca5f38bd1a30bbc4edef4ca94898 +64000 0000000003d7055b51d7b9ab693de84c03201fe0396af61dbb30bf31445d3f55 2c32c53cc5ac13f3a116161cf44d2a9196ac1d5aed950698e279e736d8af92e4 00000000005e61abe20a48deb7dc94ea3ff37ea7b5a57b1519fb708ea5967013 +64100 000000000cfcd8f887746143bed43a105c61e90edddd7dc08ba316203cf49b0c 8049ebb5400c003ce1c0bc351864a210095073a9a84627d1b3f42220d361f995 000000000c0a239fd848af1bc3d842719a1b3b9f6d3d9491cd7bf4fdc4462957 +64200 00000000092ce81342f7b8a5a15ca88911169e05618e114fb385464cdd94ba5e fdb758e83d91bbae6d19224742fb36b035c22e3f9cdb69534ba99c121964124d 000000000c5d18df2481a07b4259c25775070b47e863d999ff5916acafd61dca +64300 00000000037ec053852dbfe8f598535be17bd8f1b5caf44bb78d8f469750e41d 6883349611694b7829bb6f68cd6c02659fec26ee726ae152c6562e51757d0b86 000000000464f251031d27ef126d9ba27ce00a49b232b3cbca55a25015639ac8 +64400 000000000510d2e9e31a7d5d2ba768f3f9742a9a8cd80da26b04d10f0378a847 c69a2c2bc34ab39aa900455649f2f06fc2e0decb99871012e2da413c0cf3c9a8 000000000b3177abac29313a18f625d9b15cfbffdc55a214767dabab099238a3 +64500 00000000048223a1b2ef9866231bd42ea960e033b0b0da8ee247f525dd0b46a5 b20cd49eaf0466ac8808796f7a73485238ee3951ac6b23efe419de3301d4b2e9 000000000aafe9e73b003daed213ea58da710fdf015eb4151198930cf8cea614 +64600 0000000005f080c3d4d373b373f38be6b1b0cb9c4f1325b3a9cacd314d668593 45d79f72ec54cd12ac9aac650a9c1dc964b576fcdaa889effe54fbde9367172f 00000000055ec43b2854cb06148438be698f2602da88424c04e99c2d745e0064 +64700 00000000075653df0a0c71289750c14a171896a5d2f8f3df1730e142e8422b5e 1b75a8b14d980bd512d62af0cb9e7b3daa903de8fc76a0ce57431dbe01fd0f26 0000000002db5189ba53cf205976e39c71cfcf27190c8a5209c56b4059158ca3 +64800 000000000322fc0c08c85ae62ea54184d049bf995c18c99eff9f21825226b4fb fb5c48331b0de7761eb14387d7e412ab7f1e32d7c20c0cbb8e7419455bb3c86f 0000000009c450a9e4f32a261f167b54267ca88010d34d78d5b5afe5aad2a17f +64900 00000000013d9c4f6dc5c9ed6d81d4805e0219d360eb4d007e99d00fc4f71340 c1ddbfd0269197ab47f66606c13331d07ac6669c5f10f13c75d50aef27fd0af8 0000000003f65263b38b5169cc2560ea24e562042eb7391f323835d6a33d2ac3 +65000 0000000006502bbeba998efd13a8dfa7fb6f213da62143f5cddc4b709daa2cc2 5a8a1019407345b7638aa1dd192f0a59445d785d873db3ab8ea95006c3fd0582 00000000098356299c90c4538a528c6188551dc28af28ac0140bdd4a4dace695 +65100 000000000777c9285c621edc2889207de4b5c9b718c3f006dc2107a0b4d69b18 b15315ee117e5fe781eb98b903439e8cbf0a59443a6b3ed89f695684d557902a 00000000018cfd82118e6b1cae19d4093208e9648ad0daaa932c4beea159b636 +65200 0000000002e09647ab8aa727368bb41e24c15a7062dc654ef3e997c78be47fad cd32cfc0a3bd454026d23d49d4b0c458fc8bd5ca16868d08b247010388782099 0000000006158ac598081ff30e3956a603dcb5968479e9d08d781950c6fb8488 +65300 00000000037d524cb118fedb3f2495a4c999ec74839d7008114461f3b17529b1 1bca1c72e263f6515a8b577405e480d3846bca4082b3e354351f10dfa12d192b 0000000004083306eaa420132cb1099716faf9ac627691c78167eb671a3fbf30 +65400 0000000002c1747abcd12293082c60434db184e4363a98015a0b9b8bff5fb94f ab283134c3f7a1af428bd2a65a19c9b6f7b58e6a39940244b90d83c2870cec86 0000000009f7cbf88ecef909f53992f3d8b56143b9cb7c94efedaf2f2a13244d +65500 00000000038166ab207a4340cac0c1a1fe983ebe28217af9315aa2c4e6745c2a 045861924379ff297ae0a7b1e361d871adcb037e0bd5672c61b53ac4292a5d26 00000000029c9d2d49c220ac04dc2d8a1c3e0bd1d64ef39b4f7dafbc78718676 +65600 0000000009b563b10ecd9c902990dd22b393a720340071fabca0b023d88203cf 2d8c6e83fd0d7e18233959c02b5c33d86684107f1a97a8b2f412c32ea857401f 000000000a389db4705e55fcfcbf9751ff8c46823d52ee4522976c78d8ed06f5 +65700 0000000008d6dd6bfd4b1256bb9db390514e3505bebc32bedfd23576ce04fb50 b7131d77c9caad673066e11c45d4b639a99794fb77ed4ce09c525fba5735aaf8 0000000001e0d9103c6a04327a061a4a2a08e9ac9bc72c85ecd763a73217ac26 +65800 00000000081bbc7c7c5426bcec0b586c1f273bd41a6cc9ee8af5c2a39cde0060 b9c9f1aea05d13e2703ca2e8559006e16f1190f0ee07f4ad7d265c184aaec435 0000000006c43e2878d94504ae20512ba64442d9e6b857bbdedd8e5af2944709 +65900 00000000097cd814e8cea23960fdbe975ad127769361e49d7a37bf1c89172249 abfd52a1ad11c9c88db8764352c66bd4a1952f5a4a42138797bf6766ad30f554 0000000004526d089299be8089a443547e9c00ef436143794e2b5c90d74172a0 +66000 00000000071d7e8a0f4895e60c1073df9311d65a85244be1ee6369c9506281af fef458b7dd546f8fe14e92e073a3a78993fca9ce831b7f78be77d2c2fdb71568 00000000009cb106f888501f42e729cee5062c533f9a75d28736ba3290bd56dc +66100 000000000489cb00ff12865c5d0b52bb880c88cc0435e7129ad2e5170e054236 ebcf8c8c7e822e81f63e64dd4920d12b14e09c3765fe3ebba63c8940861f2df5 000000000796b01dbebdad66bc0b9de12a52601b97ad8700c5404dc0953464d4 +66200 0000000001b6e5f6d221e979dbc4858b5f1e58a6a1c2607489dcf0e87dade2ee 5da253ba898ebf6ee5dd1a82c7364d0d291f87670b39df62a8e607aa2bba77da 00000000094be4778e3c479328a0598045b6d1bd75917ab5e60f093779f477cf +66300 000000000739d8a2f35e7c2163e921811b9b4890845b07e4347dc70c25c2cd6b a458812dec1f89583d57634d8bcc970aeb00466ea95aecaf33d2ebd9c94197c6 0000000000d39bb29e872238cc750d316a4d0a3de2116d16229a49a4328cc76e +66400 0000000002438e2200bf993e46de0b8671c9de425988bb5ddaccc195e344e471 9a3e61f143cc5b6b9c3a40227f7970a978cc652f772a767ecbc481eb5f229fa5 00000000060a9ceeaea83e7db168db52c816987ef071179105b66286d6159ec1 +66500 0000000002b4c8837bf58304eaa4f8477c1beffc116d2b44660f70867a7c3eac 558ef0b95d6f61b6afaa3683482680aa7f591202ad1a4e75c8506e24725b45cf 0000000009ece89b50b169a35b5808f32cac58c08fbb29d3a397182934181052 +66600 00000000041febfbebb611cd8f587c690bbdc86af1e3ab04b134bf0d66c63751 3d5abb7cd760f8b4a377992a5e8e901b92395d59afa348daa69758442bb66b16 000000000062f889aa5ddca7cfe172c92be6605397d0c314ff9efc81aba0d259 +66700 0000000001747f9945c51d19fa4ebb84f4b06d4b27480d708e9f7bfc2a3f76b9 ea208b54e2d970e5f41480099259495dc2f251c69ba6a1c9d2333e9779f88118 00000000051b18f82e3faa8febf1f8db76407aea9ab4377ad8079bbb4598dd16 +66800 000000000443620dd9d869917af548bfbe10b3fc0a0f4ff2dd8a49061e143c98 a3b5180cb73094e431f13c25d824a79afc33d624c73018d230d829a8ef69d25f 0000000005658ca3c559ecb015dea32c146ee8673c3ba2ba4fc6ebeb175d3836 +66900 000000000286874607d3181b79e565de1f04cf44d7039b45eb9057102a36dcb8 ad1a9a85a573881f9a05b95c2bbf0a83e0ddad9ee7e096d08b86a9d3ca858629 0000000001f076d88e94d66545a1f979c1eb41b97116258907aa79e33313c6d5 +67000 00000000052c31495cf4c2afcea5ad5762fded7444a2bba0dcf600fa3fc900b1 f5c5163dfebf2cf13e0935e5fd022354825e7d39d3a7b63d90f6d2c7b01dd7e2 00000000043fcaf5737af8e3f522a05ec65aeddc2e88b9111f37c6a2a82a321e +67100 00000000018443387938f356e2f02472b06aa6b9d238a3eaa1e0723a2cfa10f4 6f0be9faa78b7bc7d441321bd745db6d61819fedb520d8ef2a97df6eb0872901 000000000566043ce186c492d45e91483a86a25e5501971b2fbd323ab65bc0c9 +67200 000000000489739b8d2455711b9c8db6b0c7c7d286b2067e433b3c47161f0185 9a0fe3d0f1531eaf99d5fd36e771599b5e1f5891394d5c6a05f68d0494059b8b 0000000001af102c05f77b05187ba4232cc10a96bcbc772807926672476dda58 +67300 00000000039dcbf42ef1370d47d07149bf510bad652c8fe847fd2d90b7c1ae68 3de34947d7ec434119db7578639b5ebfad8b3b4c1d73a5462b6b405c1d20582d 000000000453ebd3b8aa8c010a2f4bab9c450965078eeeae0e49d1f658a38002 +67400 000000000450da6a6eec6509f0d2bc5d5ddfb9c2ac2fa766788ae34c55c40276 5fb983e692e15927a6e36d32249e5752540f8494f955c9d0601ed1cc0fd06b24 00000000019f3c527cf200859cb4760941e2c39131a541d0605e28b124ffec42 +67500 00000000010fa1865040651adb05dd0746bc8e5579bec06762cf047e8c2261f2 ce8ed11b8edcfa0b19428e8a3bc2847d5efda8f36e1929d9f991e1fc6aff8db3 0000000002b5c405bb563983bd72ff47c0d8bf7dfa42a0ccdebcc32d927db9fb +67600 00000000054d1119a41c68fc3d527efe642158c13508b052430873351044c8aa 5b097a1e617a5f1c1669d3a600d73a3fa936825f5f53024a8dd96d0017083d11 0000000000991ac7c8ad3ed6a59b24741e03bd747912e8aa06f6f9eb308d6963 +67700 0000000003017c34cab5b5172b68fc7a1afca19c6d269310b6d4cd87e60c14cd e8a8d1a955d7a75404c7fe9f06a2a5f9f8b8e57f365802ea5b9a7f76c08735f1 0000000004686a440d23f328d1d7ce658e49cacdc319a938ee28cafaeb98fb7c +67800 000000000218f501d29c3adf29fd7eeac99e84264d9290fe1fec1d7cdebfdd65 93c493bcb843960331306da011a569abfd7b310999746ecca46ff1bd539116a7 00000000030449fc60cb7516d441993a9dcffb23d50b0bb7d1bfa92eba8a6e57 +67900 0000000003153e58fb90df051710ec48e6d4d9742d92c71875e4259cf52b6b1e 6cfd7453730455309c831e42c38ab6335db867216733f01cd949bd471227c358 0000000001861efabdd98a1a28b1ad3556598d47c0d62f7e2f9378fccf45e0ae +68000 0000000000d991791fdfdbccbbc2a73d2f86ccf78e2d0a7ce7675f40b5986b3e 37f96e952b42e4f5d0859711fec9a7a8abc648cc3cbe8e6d0ec57dc750fc168d 0000000001544eddcc2e3c5ef5f75c65c1adb99865f7f96b877ede591a5fd6b4 +68100 00000000007d9c9b24914c9a6eedd8348a093db320a4acebc639efb3e987d98d 5d27a975ca59525c0a11de0ab7f0b8521f92feefb133e77df65b27000c3780ee 000000000265db67a09080ac81b197af4a0aa2cbf2e334c80c94a4ea341ca9b8 +68200 00000000021f4884837d585bd84efe98198b77052c86aab515b988d7e439fa5f 05546a7cd1dafd4ac6499a4a905ea1abde412176ebc3189e7c24a43b8c29db17 0000000003fb0b50e8366c3545020abfde856b5a46b8385d3be95e6ad4234575 +68300 00000000040a9f03870f399c957ca2b6e43ba8e30eb168e9986e603b54d326f5 5b35ae83d2a2f065ccdce353297481d2675a85f0f336798bcc21d5418b6be1f2 0000000002d2df9529d99b1fdc6cfd6838d28e5065696b0ec911363593258bce +68400 00000000056572357c74173748176732548e3d4ad4dfb6fbb31d22c9b0a2abdf 3cad0ded3041062059eb730663f560b22da1ae77b1941ff06c4cabeba4bca0a6 0000000003c78c1b88f6882246dc6696b5cbcc6c667d505454416b36e5446bf8 +68500 0000000004a6872eee1cbd25bbe4ca33ddbef27b6ecc0ce72d58cb205ad8b5d5 15f41a2a32add3717c1ce87d4a166747ef5c9b6bc0a628c404878b29acc13532 00000000021cb5a79c6b05ec2240f759341e02775fc6c85c804fe29e26cb327d +68600 0000000000b474fad43c7ff8a2f77f6983be35bdf291f88311ce85f9bc897c14 ef23f1a0dbf3769c458690db1d0b28be205d5464c633fc493ad600d52f75de40 00000000002a1407571c1f66d64f8bf55df9fa4993020231af1afd776f9d1458 +68700 0000000001313206c27616437b932f0c9109e3db2988e6116a89678c8ad46177 b824dc26a028364dbbd49289c68c5d48480c9d01d661a8a318764185d874293b 00000000015205e2949dad13b348c4df631cff4c3b2ace7858b4ec5a2223ae35 +68800 00000000003515086581c50fd2611642776439720c647aac9b8f6d600087f7f6 60f178d9a8b1b99dc96ac0424b5df20dcd918c8dd985518a88decaabcc45a8f8 0000000000eae65ff451a5a7a1c2b4d8a7ad7c56572c75dcb038048c0909c220 +68900 00000000001f64183174521be6e5740af16dd714c41bc93dfcceaa5acb9de0ce 198ac427e43f8d886ede51c8a7423204147d48fff733eba9fd1a8b6de3e55a19 00000000003ef529220f146a07772d136a690ee5ac09351c80588ff51f61604c +69000 00000000000672cb3e0f7c83c90b505ecc9cee701747a50ed998dcf00c499746 bc66eb399a66c993ecac3d5c451c692afd4ee31bdac751e5a02d8a7185028e08 0000000000caceb6daba8e2b048a3c6ba9eaa540f98e00e2d9811c39c1d6212f +69100 00000000004830fe0d8dad98391cc07082e2f6a4e4908500ae33f5906ec9a444 fbfff6612be3976659311e41f090cb2b1e47f995f86b24e88bc9aa8c08560ded 00000000003d13de96f48891773ee9f5915df2b49bdf68286bc584a2e47a37f2 +69200 0000000000521b396f7aae11917de742c787b7e00ed121ad9e8e9f7b450b4750 165e44e584179eecd905a4617bae4c50b8882ff9bc668a299d2cfd301985dbe9 00000000015ceb76398c527b784d93fd66b3f3a2cfa1e7326ea46a5d3c52eedb +69300 0000000000989937bcdb9903e0209252d34fc55627ab6a318777542126a5a1f4 515c25c7cde1e33cafcbb98daaae699ac61958f862756b7f09b36c6a7561a906 00000000011c1cc8b0170c0337e3bf2011718f7b2fe5caba7954c0e04b59c747 +69400 000000000076cc49e8b89eb10fb5121990dd5abbb6962a9a3934fc2371ce9b90 39d9ac178e319fcdffdf206be83debc004dba210adcc07daab0a24503e97b80d 0000000001099a2a527b7eb8963dfae292720901a8b603d647606dcc3dc672ac +69500 00000000000570ca92bfa514c5864984b4bf01938b6f0dbc669e6c6e242d3005 598d94fb816743293f5849bef45b1cc1ec8275a18950e0b6bfd1d1babe0f94f9 0000000000e3794c142f2429ffb5f048b507f6e4fcd2653ee955e32abbc1da47 +69600 00000000006b5840ad7c63ba7436fc477ebd2e8122da8ddf7eace7c5e7e35c40 a4ec75747facd9fcb5e0fae2177e20bb54e9b301b9a5ba588ecc11ad48893733 0000000000d3f6bc95bbdbdba7d00dcd846a78356d44769394affa62bddc44e0 +69700 00000000005eefd2c3b421c6b7a980ccd4d651ee29e64adc8524b2ae587c3079 86b26e0842b4a2d5d12ec34f7d336e7410776fd0b31864e6657cbf22772bc92d 00000000002f8cdaa1b91da9716ea749c754da235ba4df53fb6c419a9fc52277 +69800 00000000010f585d02ea680bd891f3a63a8ca14b792e2893496396ee78aa9e7b 000b49ef5b2aad41e1afee18d469a3df2d05c1adfab3d5ae482f3a1b6885753d 00000000000edc9f23338ada8e057b4b3f2ce1bea73a208ddf0e2cf66bed8fd4 +69900 000000000105310389654128c4946ca0dde50294cf20ff22173e0a7c7dc23743 30cb1e1b0d44f2f20044a4dc45faaa752cf09862f83a2d7a44fb22b401124d89 00000000012b71b4b4374c86e879e45352b4ff636718a35eb92734cd7cee7f33 +70000 00000000002b8cd0faa58444df3ba2a22af2b5838c7e4a5b687444f913a575c2 022fcac5ce25648ed6fa7b92a770c2e3b22447033a317b84143e435dd63a867e 00000000001337176fa420cb4a7717332d0994491bbed7fd797e45a02b3a7872 +70100 00000000011abb7cb0fad72836e1db5fd21a26489a6126073100ee04650410c0 09e549103e8d07d1ba7823a0c64ad7bc78bf30ce72aeef3c5c353ace622b61cd 000000000144816ae7ba60f77dd916348f5e77dd822e0d06170befb0cb497bdf +70200 00000000014ea4c652c06feb6666bf1db97d40db15481311bed632169198091e c0ee06fe00001b3f96223c87b17b27d8b2ce0d4a89f3305e23c998aad57a696c 00000000001dbf32bd55d22aa051adc4b144216cdb5e3ff067ae5791e83bba4a +70300 000000000038c6e01f40a04069e74b910d9a34b22f679799a6657f9dd49b46f2 fb1fb3dab7d8ba2e50119c93aa6fce2c09879ea67d54fb65b7372c1a9a3d7cf6 00000000005671b6d1534e59b4a56b456c2b2e4340eb3a8430fa4ea75e12308f +70400 0000000000ea646aff57bb947eeb4cc119dfe75046757e1b61f85038bc13e583 b412aafa201f6ed66317339901b6d4d4e9c4646db7dd6a39b78ed925e34274a3 00000000010ebcbf2fdfc2c92b98faf4a8177ebbd009b55e9dca43113831d6cf +70500 00000000004e42fe160d7fca7c18000eb63f388d5b3561373eadc95b49834c31 11eb9d7b0ce37576cc183771b79132757b459324000551f22ba488b1f062c608 00000000002183aa91b812211d1f8070fa5f97789ab28691a952757ba1cbafc8 +70600 00000000006ea57975835e859eef2050c4d78eefc16332622827fdcf90513ad3 0c5edfe174a476e4bed53569342f2f72399a7f8a41fe155d6cc1ccfdc153a1ec 000000000067ff009485e5949f32724aa759060c1b29959d31b41f191509c552 +70700 000000000051605c706aca4fb695c97e1403298d364c42841674fb238ebd826d 24012dfb4d1a2c71b18f4378ef70db24832d2d91733c2ccd573b5638c73f7262 0000000000ddbc8a8e8c91c834bd3447c8e6b4d58887407f55ce8878027fcb9c +70800 0000000000ce83e4026a35200c2508c8a6ef805d9edc24720902b5edcfad2939 7aaf73968cd6b2d165ab14a836df1d07b660d792c5a27835f3dc749ab9f2a585 000000000100ee33fe7b16d2c65afbe5bf9e9ac4affd1221ca64eb7d97550e18 +70900 00000000008ba8d6beb01577730fae52517988564322026e5e2d90a3ee5d3cfb 1f9486ee9b6a5ced8eee2d7ea2a0621f75f58bd04b35bd96e0119267c53d4a8e 0000000000f59a0e6aeb7af8efc5e9aa3484622978668a03876bde95490817e2 +71000 00000000003eea76022498376477294a921cfabeee70f0630ce0fd45dc22179b 6dc80b8bc7c73e142c17b24df4b404304c2d2e350935eee4d16cf5233f8db13d 00000000008fbf55c91ab1e83f995edfebd2302ec9b711705e02d91c0fdc8a7c +71100 00000000005ce7472e94c9afcbf049c410af776b3526df58bd4fbf60ee2a34c5 8890c2e29cfc0be4b7aa440c68c74e2d0a1cad2db24a9ce50f802cbbf017fad8 0000000000ef6f21f7f19da4fcacb67d9aaf19caab5cadd50149c3be870b53de +71200 0000000000bdb51fbb9f9156e0c67b5b3f9272c6fa25051193379ce0a204d544 211e490a3d048e5c44789e224e72ee3c6e9d58a5c66c7d48470a27e5f3e586fa 00000000002a49c502e301276ed11cf5131ccbc41dcdfe7ce6be3b49b04531e8 +71300 0000000000720458cacc8126dbd369ef167cbbb948485ef69489486ac8fd895e 9d3fb8356f74d0175a7d3f52b9d71b63fad6e41bb2fd8a53b147f1b47bd8b474 00000000002bf16015c8d255e71a607f5a6852047b4b199b10bf99c3b38e660e +71400 00000000008071d8c627946d15262a4d1cc86c0d2e82f6d6313778cf2158f2d4 858fac5a80a338bf4683fe1e1e8fb8449939b3e53932c1c073ea130c444721ab 000000000007cad6a109ebb8f33c3e2729f7cb59a210ba1fc1b4a29169c27601 +71500 00000000007395951552c84e7527b1883f0c6416cabc75f4ffaf181e21c22a50 13f80607b5339d5395565d4c8059af653992997641c5ea53d34a7318463be314 0000000000c6144ba8e9d025f70ffaf7f6c2ebc507ffea9d22ed77b98cde3457 +71600 000000000077eef8175ff525b1553265fff386ff58834f1e3ef305d83b817662 3eb8dd2351f6de0829cf6dc743cc2fd21ffe727cf24b39f361355ac85b432524 00000000004b160c5a614139438ecde2c453cc893ff401081c9850e3aefd6aaf +71700 0000000000cdd0f441c12f6fe38d12dbf488c54290d3af72318b62885d7fa247 3ffb65e552e44af4cee11fe18847bdd6959444f8518904c8f0bb01d0f95d68b6 0000000000d7ac36c5521982ceea8abdf727ed05cb738b0604dafff5818dc4d9 +71800 00000000000440deae99256350aded0924394ec0884618c2c042a72dfcc50afb df8e476262c53417572bdae1b857da5e29aa249f0db2c8d2687b1991952a4838 0000000000076a8d54da640408b55af2b07666f629001d5630ad79759fd6f989 +71900 00000000004f08d750ea3d9a8cc4ccf5ffa325b6ae14fbde6ea0d1454299fb8c 7e53b6807e7ee3226e9647edfc3e4a607d4753b5e8df6ab3c7327292b32c58bc 00000000003e5bd6ff4698cc9bd11a06ee2385a414e36cbb6faf68996c656161 +72000 0000000000eb357d4c6fef6ad9a6fade126985ad36042a99cf215a4454545977 d7c781fe14eaf8d961927b830c18b978d1fed794abbe1b4058a2f5e23dd47a56 00000000002ec11f3242aeba3465cc0a350722d355d42a6415222c82cb336bfd +72100 00000000008c002c3369289be0087b471b36420f94bfa6555399811f754f2a1f c4575d397c074d6dec39b5f7b52ad369259a983a5dec0d9e6340d04bcc0fa729 00000000002e03482294c5f888fb765889bfbdd5657dd06993fb2ac37e94b56d +72200 00000000002ab91a874ad050a902473581b1fcbfbcfbd8b64b0a0ba76f025a0b f9d396655267967ac647a1f262658a49c2a141d757d735fc3f88f72b4ac486c0 00000000006e64e29c9e9a93727754ff63e36c2f2c5c6f318c21b5c36646d692 +72300 00000000005fbaa7894e4677b3976aff3aff002f4ab3455363c4fbbc8fc49636 63cc9f8756b96a487227b7045e8db82662373ca175832693fee39049f07237be 00000000005e1ceb5b7960d6ed5ea9748d0db80c8ab929800b44e7400abe84f1 +72400 0000000000bd5c54db2328e619494138521a6fa17ba655e45587cbab4636acd4 fbdaa07f596ac8cb4d1b4fc20981a24ff8a40a303a9900e2e66f20ec6efbcff7 0000000000594125ab5b3ce3c076e78f898b0fda8e347c0b9e63861d42fcbceb +72500 0000000000f66e1534339959a6f7c9ad1aab16c4ca7ce8ab4277b71770630899 ca58dfd707177fe6c3066a8571abd966636b93f4b258a3af321362289cb18613 00000000002713a87683020f0451fb50cc9e3497e3bf32690e9221e2fcced75c +72600 0000000000b0bb4c63fbe5ddc8609bb316cdd73de0a52b7a7337eda7cdda17dc 9e6422c4bfadf66e6ea1bdeeccb373c19ba0c463f91bc50d541f244b43bacb7f 00000000000c65c0fba0b77d08661c3ed5b5d818d677c051a6e86d05b55bdeb7 +72700 00000000003cfb5957b2e5e1fa93e9f64a46d66ba11c72d0b3b919f0b7f7d2fc 35728b0b59a035174ed8c5f814c22d55e2c90607e0fc3920b207b642cb1a28cc 000000000098741fc61953fe6c9e9b95cf40b04bf829d537605c91e64cd40b61 +72800 000000000033bce15d2952c8cc4b5f672a588e3766f3827ab613e76722ab5d91 d35936c7e36c927a22f371f61e79f351d33e2415fe4ab8b0bc97f41046d0998e 000000000057ddb4d5aa749acdfc0293443ee0baa1b12f8ca70daa4dc68bb653 +72900 000000000008256d627e183abc4546195a240907f1ea19fab033c78fabf5357b 22429a3fb0d3d0af64ce8b7d934541b1416664a5f18e0f85d5410c8347ebf0ae 00000000007a3e0edf87d5137df5d48c92d02e91521113092ce78b57f2bac552 +73000 00000000005936a8d5637765967ad4da3599596adf19879f5e65d6940da7fa64 ec4aa74e040a905046608bbe0073d3129153a9bf51c6c9bf221d45677477b73a 00000000008f8792aeb1dd4eaebda850d96d45c199c1c183760d6614acd89f44 +73100 000000000088c3406f300043c1822ce389e656a1885c100bffd61aaff4d23d67 b121180bc2755151ab25c357dcf49146aa7ceca39e4705e97cd88d588593af56 0000000000311b02f1951c1eec52e6fe3fee6821c282d427517ff70994ef81cb +73200 000000000076a3e5e95f964294923226bfd3e07b5fdd9262f36f35e2d9cdbfe5 94045d71582d081a2b2a4ee7dd71cd42ce25e125d1264f349f4eb96ca4c853aa 0000000000576ef39303da85af92f63187e6715a985714522169306d61d3a939 +73300 00000000007dab748cf5f83af924699869aafa4a71b6dd35e4afbf0b953b8aa4 e0d33503c68da668de497dd2071d0c4dea2c6c77b556f9ea9ecd47847ecb9860 0000000000714e3cb87f777da1695ae5dd6348e6427f19b2818d19b72b4feafc +73400 000000000033cf0862f8148225c6c11a8f36b2ae0f1076629070e4efc93f7d9a 48c30807611bed3632f33159ed6b65b3276b2f32d85b4e18f5fc8295d8cebc73 0000000000018960a6ae6499c86f18c4828668aaee4d9ff721f609257a4eefd6 +73500 00000000007602883978c6b3d1d295e567621f2846d934f0112a99cf8e31366a 3d7b9576a9c4fb0da0c15cdc87c8e8b71397fe8dad554c66d1b665514097c9cc 000000000095ab428162e86ffc269a090312e75be64665e638e2998137786aa7 +73600 0000000000afccd8c1be67a0c2fe9543a72e96e6d802b4e78421c1f4afe28914 ca0ac15e6105fd54b6cd78554fb6101a2b671d5e137eab17772a991bd1b6bc39 000000000006e987ce8fb9d5352f41dee051fcbc800891a1d1dcdd58ba8f3d98 +73700 00000000008ae36e0b3b4ac7746b0c0febe0ff289871f1179fa3c74b976b1fdf 887402610acb4c82fb7a50da31c4e9352e967d337aac66f0e83111a8dcf0fe9d 00000000006a4b03587f6231f40cee14ba436de23fd4a24024e4218beffdeab5 +73800 00000000009d60a7608e14ccd1ec1e6ff4b20fee6f0ad803ac2569086adf59d3 361f51be8b1e16645746a240bf65632b76a86880e91deb64f591cf41876fe546 000000000008d93debfd2d21492901536cd95fe7d6d384de5461a460ca57f625 +73900 00000000000201252bb4e556c7d6bb2bc7c15e93943c7da4fd4389b7e9a2c6c7 0ab702d3ba8020369024c4bcccaf17a3d8dc7c58757b9bc3ab41ca9051ba0f79 00000000008ece4d7d38ac9b14fb99a720189dd756188eeeede2a107726115b5 +74000 0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20 94d2ad0b8599204963713bcf844d8f1ae52351b15197d01f2b8b299a199585be 00000000001ba557f4e72c127725d7ff26be2cb48519c007189d45691e650d0a +74100 00000000000a49aa8d2ee47e882851dba11f587f412e01550c29eab96daa9eeb 070625c2515d36db6f6f9cbd094293945b8720055c73ff520804c9a544857012 00000000004ec5f37f47f14cc25577b6f7055044b32e4c05aae2a408dba93d9e +74200 000000000027fefcbbb48e77ee35fc16d9059c34878337b558b7603c5f330a89 4a3f222dceb971ce0405c095384f20595bcf97b785149d9419656942e38d57eb 00000000006ce11306f55f8974c9e0dd33b952c4763934b42a92e147664ac379 +74300 00000000007e85b0458902d370dda6a2ee9f82b77405466aa3e087b78abf8136 e4d419c6c1a69cfe8e9cd7296087c9c0786c285733c9f54174c161f5bff57147 000000000085a920efe3ecb9b0fe36a158b147aa1e12f3685d9632cc9a3497d6 +74400 00000000009390aea3889f90872df044e18482142387af697a86384540080aa2 0a52829333da6d8cb9c381f6c079eaf8748f81f7b788b1258b732cbb3d7d8b8c 0000000000b59bb7e6f2c538d6bba992ff2e5ea968415d8085bc984dfef32c8f +74500 00000000004e46121f09833603543b302c04566921d55ad019f86b2e15c6728f 4c89f4a8b07c8eaff88117f49101f4cda1929926bad8326fd83969bc7a5c4301 000000000052398687cf7e6e3edbf0c585d08c51b4e6c2d9b9fa30ee49beddda +74600 00000000006acdfb4ccb5d5389a53a16463e1ce94c6be915d72f97afe2d253e9 ed81ce2f74727fcfec1f62e02392fd01941eb815bb4e16dd2d1b7028af251876 0000000000027e2552739efdd4ec371ff3a34b5a779873a2822fde284c81c750 +74700 000000000016abae6e15846d30d7eb27c79bd16ac5f70b3b0bdea586c755e9aa a80cd405f42b6608cef8d6590c8cb01f7321b6f128054a25cf4157101c030e5a 000000000047e962cf0f5dd9808e3300a845661ff83b695a5c32a2c850479f6b +74800 000000000060f19d923b654584967e60411a18b2f6df90ebbf7f04b463d1257e 08147e6927697cdeed5c8ed2734974a462449aa90cc63c84e13b9b22b9632525 000000000063e7db9b027dacb2daf889c44d80ea15e4f9d9bd12f1f34aca1c34 +74900 000000000001df6cbcdc3f19d68f4c77e308f5b837f884fc5249dd635c2ab0c5 08606223033fa3fbae3c6d061014119ecbf463e8017c80577894a9a7f1e7041e 00000000004b785d23b27629e13f7903eca450af3ab628adab42f2af6eca4122 +75000 00000000000ace2adaabf1baf9dc0ec54434db11e9fd63c1819d8d77df40afda daf19b8a0288c8b8f36678213508df8c5b43a230549552ea89d8370c10dd0dc6 000000000049e6b73d84db7eb4704a52fb923f28a96276bf7e62ecebd00933a1 +75100 00000000004f128d1c105f90e315b6af2460f7c80f8df2217bccc7e7b79f862b 0b92342678e7f972e390648f4ade2d9517df457897c71870f54ad665a6489af9 000000000040c86155db276e1d4ec239dd479df5828f8b415d4a9ae7adfa13e9 +75200 0000000000384936953a99208847621ac006db3317830c8d42ff7708f3aacb4b 266b0e5161faa4094495800a6c73e4beaf6c9432f49f5d4a7f0b82b82f63e8dd 00000000000bcb416752a93f6fe42ec713628ddd01636d88015cc89802e3d566 +75300 000000000035c5f264d5940eaa8275d600fa31ac532b4d36bca45c456f7e1f40 79d3de9f55660b465fd53ea6a572f909933e827078f337cb88d2f554c3103f51 00000000004fce78be7a922e73139a31e85f248a825dbe8d2388677e17905a8f +75400 00000000001115da4fc45d9d094089eb784e755b87a34fd05024c13a02e6fd2c 1cdb342c8d75e84cd1a8a0e38d0e700b302cbb7d38d660c03135674a1a5c85bd 00000000000828461ac76c20ef69e2e131460572da5bbbd03eb7ad1dcd2b2987 +75500 000000000050de28c36a87990ad32da90a0ef1053bdce8cdd7b0cfec4ac1c0c6 1eab729281b77e30a906866c8eed1603b10d9def55db0925cebf2ce989ab93e1 00000000001442ada73522fc9b2319a7c507acb73d76972d293095c526870176 +75600 00000000000e3deabe21faaa6941b6d9a89a194e6d1646a16389ff17fa67c33e ebfb29d81eb78a463005bc2e3d3cff394d2ba9e5841a1f8a47f90a65d4659b6c 000000000045c1d285f23777f24978c209565a5cc82d956b7289bfdbe85988c0 +75700 00000000004cb1b0bee45a0276f2b4add9608878a323ea0a0ca74cb1e7b5b285 96df18af55c4794212207d0a155334cd7de728aa7e08aee2e47244dbd9ff0b66 00000000007b251c6cc8ae689e7d57b64dbed3377561bbee91d09bed75b7fbdf +75800 00000000007e81bbbf64405ee4b1fe39124bda7079f07c7dded8468308319112 e59862e304bed25d504e649d4bfa608fe9249d6c1f33be28b1f3229fb450cf56 00000000007580d83edc39774cc42ce25d19d22930cb96a2b2d24e76c925b753 +75900 00000000007e01eb97db12b83af072debc409318cf74f7fe7d227f7728d033be 706187e71431a1f3483dc8c73d47ac104df796e9f7f5d4ff3404f15002cb16ec 000000000058e4c68c42673a2403709020bea3a5c901bfaf004923ed71e025bd +76000 0000000000571138ff757a28ddf9b56f28c4a461e170660bb5ae79a556069bb6 183ec15385febd2f7692b05b6813e21990e9c5b876a6140d112d978aba616780 0000000000393b1b3943fd383fc68e8f509265403345e3f6589d8683d4a1fe49 +76100 000000000022bfe1b12eafc6f35577e7a96f4d259df2ae3f5f5a3ed2bdbbafb6 3d75b8db4106e1cee937c42bdc613d05e7436fe5b52668d1a20efd6d28faf75a 0000000000652b7f7c5ca59dcf4f147b5ebb06ab5571897ebf14d9ba960f6294 +76200 0000000000334acb94cf689e23b90a249e7a65b303712367a669cd05ac5350fa 0d026a8b76ff3d715838c81a5d418418d7006673ecdebfbe677a4af961df114b 000000000010be7c2ad8eed74d5f35848d0c5015431ab7d48d76a12136ca5876 +76300 0000000000458faf69b323b1fdb0a62db7c094c5a357b077a1e14a7ee694c7e5 18e5d0f1e186b25617a447696f809234af6290f890fac2009c504def5bd5477e 0000000000683db160123ac64761f6b9fd2d89d4c9e2cfa2c2f62bc26538dff4 +76400 000000000058701a88a0fe3f57c7108e5a666aef1c800683175e615c058907c2 3f75da42b5132abf4cf18d267107cdf5b7b39e4d8faf768f879ac6d0d6579b99 00000000005f1c3dd6e6d550270aecd278fab76ce87c2948b6570265edc30c04 +76500 00000000005885e1e1b8c3d1fd2409d91cdde99be71d13874260ebb702f665f0 c6e55b1a0e68a787ec2566c95daf399bd56e49a4b0147acf4dd207555872b74b 0000000000243d4ab285b58d11efe641509d9ad1ee4095c60f631d59aae8a9ac +76600 0000000000048e282556e261f950d7e68ef6d26cfe3946587ce6fe74acf7c14c 080654f88e83163edc395c25cd7fce8d562ad554bd8b55e69b87c9ad82c14a90 00000000000b216e6f8b64af1c47fab96d824f6efd9a1040256356ab36241551 +76700 00000000004e831d70c2b754c7a3fca9dbf043eb254b4211c6759d9454d02e2d 48586bad45a52bdf757dfabe9a3405043d16cabf2876fbfbc8b39756193c86a6 000000000052ad7df0c6edcb476ffeb47e027897718959c6f2e0a904f8322320 +76800 0000000000047dead788fcc7d44b07f6dfe6c13c7ba2720fc0e23f91e8899f6b 2372fede954ca14d4f8e10fa8c0c174bfbe53d9afd29f3d488fcd2e053c5789f 0000000000513206050ec0cc9b7a1414ed2ab0ba2098df00e49dc643d8f310bd +76900 00000000001fe35b487a56686807fc936ff24ef9f6876bb9d2ec2a1c44fc53f4 80c9b45815df688942348585c5ef9c0057c05f71a21277829f04009ac6f51214 00000000000327b313f12a4a9b0b88245e20273de90950e801709558efe2809e +77000 00000000001bd84391562e354949ad0480b83f5058449cbcd9f249e9dbde91c7 c2de0f1e5244f89ef09ae90036ba29c29c682914419d56497b52aa58c7f6071c 000000000060c75efb1726acb8da3f40c3431dc31c99c4ed76dd01240ebddc16 +77100 00000000004c27e9959e36b1bd1fa50c0162cc24644dc1d1bf688bc7fc7b420d dea653a49452f301a92165fd21b7b26975cfe8038650106bfe343b0b413deb1f 00000000002015389bdc4dfff33df4110d3073fccd13d7835c9030508ebef64b +77200 00000000005a92e5293c66cab4e01f4567b362e8f8782cb14256fb8bb58ea7ae d59d7af05a3b6fbb114b72234bb5a3860eb2e6448caa66724a555a5a7981e00b 000000000063b03efe191127569a586a2b73b0246a4331d4b5a96db44c5297fc +77300 0000000000125091d74bd4230e42fc65fe95e518adda39a37eb1178466952c28 8646a0a02e974ceef7a887f75a4baf4c9b7e4dc27cecd74db963332b840389e5 000000000066f7c448a0cf8bacf155d881585a5b933ee98f31bc5679ce84cc2d +77400 000000000024723ae453867663c708c259b9d875cb1cb2eed56b6ed1f0fbdca0 38623f396ee9fc5fed52c4328204c3689dad3084163b658ede03213fa611b601 000000000053a98921ab15ef53d3daa2640d4439dbfb82d8ab972be26cbbf63f +77500 000000000028549e3b5fd995b9b06ad4af411fe0fe40e65a8187b1c28ba282a1 3459768a1051aad4fb20702471be4643e9f5f157e2025d2de6351ee1245aa01e 0000000000309c4eb1e53bbb27d82dc52ea8592e94197a0aade2880982272c0e +77600 0000000000005be72f31f6e44d9cc92d69b9db0d86b7fde42c4173a360b8d4aa a404823709174effacac635562fc8e149f33e5e4b83d44609f4f1e030eb0e096 0000000000540fb66722343fa896b157127012b9f3fb00f2b2ab58fd17271b88 +77700 000000000033658f4e4ed62f448498ab4e7761efb4b02671fe8312a93ffb86c2 95ab5db9bafc0d840094091e2a455281b480156025fb4b6c7bc00b8072aeff20 000000000063a783d78c0e35a69869730e8faad1a9f1f450b8eece6b996cbcd0 +77800 00000000003e57e57f981ff54c6ad9675f7c7023f771e9233f6937d242a31e52 b6f40657c6f9fbc3f8e3389652e3074ad52ed5fd293954a5b8667299595dee89 00000000002e9009bfed9d0dc34531290ff6ce9dfe89090462d2f6cd9b435837 +77900 000000000009d0d24ed46ad35d578332802abad7d00a22db5ffe63526df4304d 64ba95e9623d144ff9595c90483e12b135ef0edf1fb3c9edc1c5cc8c699cd8b4 00000000004211af4f2bc5f185ae029b0e2cf98288c5b5767d11e860208d4e63 +78000 00000000001f3fe62641b473673c9ababbe207046a109f0861af95c905a918fa e908348df8bc10ad063eee008ee3ce5c33bf0830d939599019bff8b9ff5973d0 000000000000883080e6717f944f2ed3bb6f2fa0e2723a8486c476acc713a079 +78100 00000000004ad735f9078ecb5041564da674c4884f3f688b149ef1e4c882e58d 5481500a27bf1beaf1b82b940016bc0d27872c3853e45a2504e8f6a7ce38ce3f 0000000000192118f6e7ad72cc5a2fe5cd3f5b76626c7a77f642abd88de5b570 +78200 0000000000402ba878b088bc4f5076cf342aa70eef9fcec33f447f2709a1c774 e054102b441257de6ae1b7641b52bdbbb889107ee7f6536b8d82ea94ecdfd832 000000000006655654adc861e36f7384b9574136d3debf3ef6897a843a3a70f1 +78300 00000000005360088e2e663df167c975d4af725cd7d938d1ca959abfbf836a05 7d4142ab7d4ac4eb1c62d086bdb343e1288be26ba1c23abded568ae0292016e7 0000000000142cb3affab394abac43fc40d40fb258090ba056a80aa662cb4ea1 +78400 000000000068c8c17fdd4e9ceec82a874da300601619a0495ba9117b4267a313 8614033c527c060943ec75e35dfdeb4a787892e5400e67e661fba25647fc62dc 000000000043d1da24099f561fbaab10acb3d3e6fa84774572b677629d1535af +78500 00000000003522284cd9125fd754c00cc92616fdc02d525b5b8750b450ad24bd 0e4f9b30f34e1ca401e458e9779aaf7f8afcc41ede8e71e3cd4b71310718c5cf 00000000003ac7dc9896812fdea62028a52972f24c6275c2615d3e7967af6c45 +78600 00000000004a763aaf213e7fa357030b0abaab713be0ffe5203e89861486e1e3 a5373e7105565dac4c7f1bef786f10d15762cfb517de1ef809bc74c203b03467 000000000049f66f90f67b3aadfa32bd8dce0e2e7de14e72f300c0b6ab0e20e4 +78700 000000000007cb741e9cc3f43dd53c1cf287bf2e73e3c08ecd1c995f3455f5bd b2241728536c55cd9ab0897d7692f45f2a60b73e46a6e8ebcef6769fa7a2ab3b 0000000000266ff3154de74aa3e683611242f6256f3d6dc17e952960ae573c9e +78800 00000000003aae5b42b5f41852efffed2c75700e55c473b15ae7a9157b47c2d9 69b1b13e5fa1207326be5a546d5f74ae30325e0ad2ea80221423d490a37bf4bf 000000000026b9e101b55982cbeaaafaa8bb86dc9cd7702a05e8b666f7c74e54 +78900 00000000003b63dbd51f4df69fc4a59a8fe51c07a012b71de88e962fd1856791 96ece0a294024c9f70f7f2bae558309a797b45eb0a6e4097e7b37864cb3fe8ac 000000000018bee52a3f208a3a0a641a8c8e4cd3998e2a93b54ebaf64bd33850 +79000 00000000002703587a4eb2b2b5595749f632ed78b3ef12fb1f5fcd3adcc61620 c8abc3063587092a60728651eb29d9d245a3aae5f8f0a48ccc7a1b4305ba27f1 000000000051ced52357e98def2d8f40f3e9fd712c741deb9288fc5ac62b522c +79100 000000000043cbdd7e64a581fc861752f3b2364cd4f6dbbf6eced14054679d51 dc91c0afccd95c8566ed7034fb2d78ccd70cb6eaadec71489a7a1caa608829b0 00000000004547b8ef814a904284d106d94abfa9cb6d1ed7ebf1aaaacc45c17b +79200 00000000001f2751b2a06d2a5a37467f39faa2104822654b913284cb36a955ae 8ad66184f34e84ecaf1ba30d90731b88b5e3c0b8d97f3e6f9e7529f11f46fdd2 000000000015188f7b0182aebf4e808df2cb3b25fa14416ea44a3263f5f43370 +79300 000000000023ce18fb8f27b8d1666d796d4daa0cf26d8618167bdeac07cb3bc4 b091548efbc121beb08c11da072d234675b9270ff5571ba0afac0585ab7f2fcd 00000000004d03abcb902016245dea11b740734f57dcf0cb6b8a281cfbb36302 +79400 000000000021d821ec06be7173f413690bc5c4bc648dfa70b3b6763236f055b7 c401bffc63030c7476b26d60d088ccd9a612daf91ab7c827844fdf632dd663ec 0000000000539783559ffe9cf1d7fdc316e52ba267cc9e4ca20cb4ed83d27af5 +79500 00000000002064fcb7e89948378381e247c514f78f8d441597f3419d47e9f282 a8701203a88232a020e64bd30708731e19d94b8208a50d9a25443bc71c7a171d 000000000038638db89212453807de4282e53ab37df5412795faf44e5617fe00 +79600 000000000042828814a86dbb65077185bb7effe0bc027e32683f1302717a82f7 fc94ae18b67b7c38125efc961d990810050bd5806ab283333ef3ab6a38f086b9 000000000033c3203ad11bbcfabd0556ddf047e8f7a7ba8f32e48bcb736d6304 +79700 00000000002eb858c2c1ede306a6d851857f06e4edfb781b50b8d65575b8c7d9 5a65b4a68d45fddb9bd8ba802999b0c3cbb8ab169a150499f2323b70b229aea8 00000000003d9bde3d684a580cb87544e2bf18c210d194b2decf788f3d7ebfe6 +79800 00000000002094c293cca7a7f1a76036f79a75dd572dcf94d88b4ef383f6eb0f 50fe7dbcf6b58a11cad6fc47c036ba0635464fa624de17a66fbfefa9b9b5a61e 000000000004a6771a9419f583ae28d1c22d383b2019ea7d0a1dd13868841371 +79900 000000000007918e67cc33b9caf350afb65715d3855fb031a5c3b19189c31325 a866a6eaa9c47336c86249cced154bd7655f1c5f5dd6ae7fe5433bbeea85a296 0000000000058badfd057485e9c66abf6f7995c33cfe80d1faf86017f7f1b5c0 +80000 000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6 dc0b54ba6fe70efd73227aca24f19a5856ac3f3e04dec5baa84727fe522cdeeb 00000000000036312a44ab7711afa46f475913fbd9727cf508ed4af3bc933d16 +80100 000000000011ba1a6aa8ff940840013c4ab79f18d6e550ae1a1b761199959288 0b839b7d6715c50a2eeda9c5e8b2028732dbef966d3a41dcee3129231950b004 000000000047663a91c7558bd52897f6628e63df81ad737450a75afe4a00fdc0 +80200 000000000040fca9fce776c1158e74ef19337e4d0ca839ad83e53881f1f7308a 05645c905fa61f5402905d18d6e6522a8c8f3ac69ded301dd6f92203a7b08535 00000000003fa556d5695f6a3505601785bb3fc7843d3b79450c6851dcc653eb +80300 0000000000463ed65d7e63dba9fc4673db1c156d7896a12dc02e278c179173c4 deee899be6aa87e5fdf3eacff8e1d0afa7b83b1c1f1a9886685ef3e2714cb952 00000000002291b6fda2bc7b5aab35a62b38ddc1303e62e2fbc9934df6a2a87b +80400 000000000000b83eb92d83c2cfa886af313d16066edc15cfd497eb9d7cfa50a5 ea31330028a814135c81a01411d6ad9c38518e5e6ab73b65da870ac6a047cdfd 00000000001791b92eec53bc6c9ac48366dcc2b945a0e446f622cac9c24b28b3 +80500 000000000007790532e8ebd45e4b541bee6ba2a5881f3ed08e33d8ea593983c3 6ddd9ca0ac78fa70f32602d929091ff61338f99d5ab571b8073046d990d03e28 0000000000291efa4b2750bf1d6edb746ed45b1992fa9045ed304b9f2da1e89d +80600 000000000054385bc5d5120f9abf39148807508040e79b8b8d10e86d3438a102 101a33df0bc241355ed6a97ef0f808516dab987734b13a96667c8da02a32a373 0000000000230996d05b3ee0c32a6074e34d964a87e0cd3725cc2b0ac307bd83 +80700 0000000000048e744c5be2e7c572a6a9fc8487d32d15a23268388e1ca9a31e6e 15866d240422725587caa5947fd6f40879c4a0f4f42429f09c7aab0845df81cc 00000000003fab258e24963d2edffb4a3d107dc89eab6b5465d27a230b36940a +80800 00000000003ab318b86eaa5f13f374077a80bf5bca7474c7f093309933742c37 e737a557d2cd11fe158be4aaa0a5d34a7359ffb385a690db1abdad75c7e29768 00000000000d5690caf4cb8303b4ac8f117e82c170e9e5424c4f263298b1736a +80900 00000000002e8de626dcecfddfe1c6d3a627b519f35a1a14cc6f5e3758e52037 27fbab60feba734441439379bda391fa40e0f6ffb6dda1b82bc017b2d19801db 00000000000f4a4fcd7b0456369e4ca117c4bae1bed1bedca059b7921d69d4aa +81000 000000000030c11525e18d5083000ca58a6b1625ce54b48edf16b9b6dbd8f043 c4f6f2affc55d5dfe3d889753259a771be1e399b7796c3c45cf13369381c8596 000000000024a8e74920194cf01de89766fa64ed18f87e2dbb214bb5e0b391c4 +81100 0000000000391396d2f4c227eb7293204a494727943fc3e43a1187c3867ad5fd 83fd41cfd6e18ea274ab44965077053140d44c1c6384d1d53202fbb9706dea7a 000000000004e7695e829590833d807182dcb631a02504f47dac544ea496505e +81200 000000000035a33adf30e6e9439ccca88e9d26be9ceeb14553bf76d3da01d94b 1fa1572ffec28bdb76d8cdcd1a3b8d999a950dda0b9f1dd2f7c4af79e79480e3 000000000025df3ec75d7f0ce4d50571ccc230a35c0e6118af8e618b0d0518a8 +81300 00000000002c4aee85bf8f856957ce333540d56ba570757019803962ff87816f 00029c3e3aea92537b5dc4a9e4201f2c25c7ade2e527d7a8c3170febb8ee7160 0000000000348c2397975205911d20fae828f26f67e294cccb4aa0f786ebb71a +81400 000000000041d9adb4549dd3810e9968f4a94a43660053b15124cb9c826c3bdb a327fea2efc8edc40e5f357a10f6c0af253a7b9eb5ab4a6c41872abbc5f2ae7a 00000000000348aafe82b2bf936f71f198ae2c8d4da40d56a39b8ee28bde4c96 +81500 000000000040ac4077b501c30877a484864a1d85f530f8b5cbba427700fa8a5a 390c470e5ebf168ca42c627dc0b66fd9355f665dea0f7ab9a8f51b055b090749 00000000003997afe8d491c5ad13f9d8c11097857f0e4b612b464d22573b9b15 +81600 00000000001f57bb2538c1a663ebe715dd9b6e4ed2851de696b25223cb01c34d ccaf8d91f7f935011de1630f7bd6f7329c7ad5bcf6cfc503a2431c616eb49e6e 000000000002a3158e1978b48ef23276bd77b5782ee19e78d7bf60de6717ba35 +81700 00000000003b2292575c4277eff80d0ce5cf7df28942724ec4c8e57bcba763df 653a4463c333bc865c59e715a3693e3ee92295ec719340e975cb257d284f7fd2 000000000036a968df95c0a808630ea27f492178633bd3731d9178c9fc65a04c +81800 00000000002ff57368d49957a8f61a21e6ff038dc30c5d6263b05b337665f345 ba9e1783a8d6127ccf008733ba7b9d32dc30037d4622de00f599f8dcb8dfaf1d 0000000000169ef693cfb0b9283beefbac2146070ab9e6842e571ab1ebe13bcd +81900 00000000001c955f95151148991e2405c01ced96fbc0e4ebc68909cb080a2103 9cbc175f08b6f4a1b3dbc20c95ad5202fc35835c5b8ce6a723c74944696122dd 00000000001c59f5e961144633c27c51d274163ace62005626670f6fd43741cb +82000 00000000000c9d1c4acc114afb58d55db5ec44a963263cf6247220b7a3f85c5c 713242f7a2699ff6b5be0bba4de53001e1d461ca8728a0f4ec308f514b090d98 00000000001e0f5b8021e95bf59ef9279c45f5162a0e41074a145c5825385625 +82100 00000000002f68df4b5e2a0d5de97843a46b5261793fae2245a55b117da5a840 b2152e9ed6c14364647e2d10f80d43c755eb4ef039ace75b184cb53da5c97fb2 00000000003a63835ef815d22f1ad6b3ba5199fef2a22bd30452b772e3e5be7b +82200 0000000000238e4bf6be5b5fd284926810aa86b5adb8dc4a47883490509cf6fa 469a9836b56a80ebd3c8fc3cfca0c06b4273d201db25f8beefb2235a7a2c5ff3 00000000004124d2d2c94b9b0f396b421134ff83b6cff980270b737e5f44ef3f +82300 00000000002b4860a17ba2b96a849dd0b1b8e4b789b0d1214966e3c223e53abe 8e1555988e318fee5069154c3d132ec0f4fff1846f5a3f4fd9b851aa7f75a961 00000000001db1cca0aaa796691993f37370bccb4cb0ccf6f865310a5748c4ef +82400 000000000034b3fc95932d7a96f97f8914c621330f045b54ae071caad39ab1af 168abe2284c239c0afe5d4ca0d2bfafbe2cd94d3fce528a6fb4fbdfad2a0e5e3 00000000002d55954f48d94785d82e99e44ba5cc44448e25e130e08147bbbf4a +82500 0000000000317258966e57eb881edc4399cf6f616b53f4d143a46800adc77f76 9969d88a54d777abc79e1247ac601c2a62a494022a031a227e7e89324f75eec9 000000000012f5d5e567b9854c3f400ab5dedbd9ca793fe9f6bb5669789eb926 +82600 00000000004465aecfa43eb63723535a18261839140812bc3c2c705498993e09 5cf4ea11409fc1a64108fcc1319010129859bb038f509f74481a2140b5ab4ad1 00000000001643b79c9fa7a35d8511ae3ccfb20fc4c2b177859247a67c6eb726 +82700 0000000000317bfb3efa27ac7956ccdda74fe91d634abdca1b6c43694bb27c3e e9e1aade96fa7a165f0b1de3a11474fee3397dd1358b5221f5df738e2e4399d6 00000000000d6b33b00d7ff1dbc449a62fe3a11177ab1efde3c003d36efaa200 +82800 000000000020e047993c68848ed644e3deb5537135e9602cae7b8f176dd9737c d6725224de64cb09def566cd5b324aa8c2317258fc42061cece7c4a17e657cb1 0000000000213efdb31e795b94b5bab3dc56eaa5ce792696eccfbe7657b93276 +82900 000000000018f3483adb5241f3f1e3e6ae4d986dc45714f933faca8354190120 153e1665faa9804ad5214beb5da0fecadff162a06568a8321603a91594f30966 0000000000058b9e7bfb667082b65f7c5da43f126fbcab808ef96d859cf5667e +83000 0000000000230ee9fb4cf0933aba6c94e9c425636fe67c28366abcd8bd48b734 d39137258db79034156fd59b41dff8dc0c8cb6e4a999ae1b75df6efde5ab132c 00000000001725dca5a5a05c07c3cf42b8dc84b5d53a514a2ec451e3f985cc69 +83100 000000000026b55fe559818467b70b5eb0985c79fa283abbb81b763fde3bd23f e6018ad7347d3170e5692db7bf8503821dbf303b2dbc6edeabba61e6c45144ee 00000000000612ee860428b6251ab432ae91a14148dd4ceb135842c52e9a4bbd +83200 00000000000f83653cf83828809664ccfa6299d1b3170398e0bd6f3784883f9b 29ddc4479fef8f4dd08a58aabc536c8db1469f29d5cbd65c16ac7b0f2f354f2b 000000000008325894955ffced38ed67aa540e3d647ab2532a27042366f8712c +83300 000000000000ebfb084c4057efce6f4d198de277b4a6d034b380964c1a9f098d ae3197e30868a1710d09c42a6eadbcccec461d09a2e19b38dfefca31495b63a7 000000000014d01d70a0d58ef24d3b9aa3c2971f07cf28255321de56f5e101bd +83400 000000000016724c5ee48b2b44ed8396bcbb926b24a5440e3aa8bc2158a36c23 c213453fee7ffa6846720142cbd91e8aae054984bcdc7ef7be61a69afb8d3876 00000000001bdce122bacee8cd90b1f2645225f3d4e50b6ffbc428e31297026f +83500 0000000000174ea79eaf44f30ff9f115613987c43c7902da1ce91d813d52acfd 0025898343baf5e1ddf76ba5524780ed990ad4a59c5ee71e05b8b63132c56f97 00000000001be18608048fb6bc8fbeaee1299f28e85a92d6863009b4dc4dcf1d +83600 0000000000080baaad6157104f3785c633ffbeb6db8850ab773e0966e94b5044 6784b2d368a3be9c22405449c6674baec71485e829fda3d5c245f98c3ce9992d 00000000000a67be715430acbc273f236565502d5e04d1aabcd3913f4e57018e +83700 0000000000070005fdcb9b9dab9f6ce434d129d65055a02068d4024a757c1d05 308a9ed5555f35cee6a663c7d18c436d5d2ae5c41cbafb821b23306899ee3246 000000000028656d6a611741384d1ef0feff7d62dd076d3af1f5b20f773c37f8 +83800 00000000002730e733e4a7e793a4cc047a9423e79d83770a63db588a910141c4 b1e3723c05120dfc39f7d5c3c7fca84cffff4a83012c2adee421a557aa08fd8f 000000000002410216636ccb232f77d3604c7f86758f225b48a3b6a7fba8779a +83900 000000000022d6d05af25f48231ed7b968c0b417c64e31b1995553b6d723cb76 2ee29d400f34b13bd11d1a2f60564bf449fe85828f5cb9f0298a61108b592d7c 00000000000578060671daec856c399ddbc8531746ba0b0ebb43c7e8942c60ed +84000 00000000001385326e30864192ba84ed2f9cbfadf0698655b1c25f93c92f22ad d96103909633e2df1409edb957e7b3e9b592fa00fe9b3c79e9427bc965a3cd3f 000000000002c05ab3ea86dc6a8167dd6be5450f6bd4efb431535f04c57d5ddb +84100 000000000002a3f2186dc983428d0a142353836e8b970ed2b4fe85bb2ea48ca5 d46a0ba6998120965c4788987ee1e9ee892e68350fa7a3ad162288337ff2e838 00000000002278757a603c947978f1ec1440d064b789cc00e14c7d94b56080c2 +84200 000000000025f948fac740b70d55d65eb96d530015a8144643cfca3884e2a38c ca9e01fddc22228351bdd619b3957790233e1fe976ba0292ef4c76bdad736861 00000000000248e3e2c17cd91ba471006eaa3d507a94edf5d1965752dea3a027 +84300 0000000000083d60beee57ffa16093009637cf12d561f7545d1d76a8142b238f dcd51f53bc1a62ffd247d08e264d9953eb44dd6e5948880bf9231b7715505e01 000000000020c6cc746d54218888fdf5ddffdb7e047c8193b0ef0558a9759418 +84400 00000000000360332ad7c205deb96c1ced86eb2790d6df9019decb3d4c7f3b80 08cb71731b38d7fbe3ad239a470eb846e55743089351647e7f2a68fb4ed42429 00000000002c6249df82c795f8d97d77ea98807137485c6787f508a1cd2a3907 +84500 000000000021d7e26af815acbdb3c4684a107e8ec6ec3ad3fda1c424d67aaaf9 da909d367caa5721f5fd15d4afb1bc782d744e01f3a3ce276c23a32730b03be8 0000000000001bd34f5d8079c62e58dfd39dbbd78fdf52b93cbb1593579ad022 +84600 00000000001248b82a095fc78fa2447144922b463027ca216f9129309684efb8 183d84ec68d780d750d33bcf18d99f00263c50551e0fa09b77012e9012f352b4 0000000000130e5b7b710018de64ee5f707ba1be749372e0bc41192dcde1ca4d +84700 00000000001d3cbd32d0da9c535d01e34fc58df407fbbd2f769e7c3db00f985b 2da2acf8a91a89a3be82dc120cbc9d60959a8955b732d0d52d66c99a087b30d5 000000000008c10cff308f436ff49c55bd8976278b040f693b15dc8a4c258bda +84800 0000000000183b52d7f51815e410b076a34127528f2b3e37160f12d717241404 7cdf116b85f3811462d549a8d08dde00f512c751db572257803a9067b4feadf1 000000000005f7622f582dea3b3e0dff27908222c8c2bf21812dfe77c00a48fb +84900 00000000002df72fdee0c5ee854b872fd8972bb39d1f471953197f83c3cf1868 df8be190536d4d0ae320826cbdd9ba493f6362fa81c899fc92da678dcb860414 00000000000870f146927b93e07183749981ba097fd95997a88314a841787eaf +85000 000000000005dcaf122d18052c42041ce2afa1203a0c33b27a4be7a18e3e226f e9bbc3ee2043104a757ed3cd903f22808ab31e89adef574daa3cc84c54bf6c22 000000000005bd486e5f8d4d5ed6f239d181dbffb9cad9be6d89ac05ef5ac044 +85100 00000000002211b4bd2d798f7f011e852b57e6f87764dcc2f2f6bc6e2e37d275 3b0a945b6a1366058fd55a245ce661bc9568231dac0aa56aca8354693b9fc9aa 00000000002714d0bdaf08961d39dfcf96358c4431a3d4ed0e12738ec8639f76 +85200 00000000000de65c171ec4dc1095e872fce17b193fcce3b6f76963aff612de44 8fc78e40301fd491fa9f6b5984b88417602cdd52bdfc649824244cb01ca0308b 00000000001806c5a659cef60b1e44f0fdd95941403ea0a9afa9d3441d71915c +85300 00000000002847e1ab3bca5464dcd2d834a8a8f26758943e11f34a6294a593e1 92be4a0c2f07652dc9e2effd0191794c99b3904e9d3959a53a5b888f78119a28 0000000000128a4556cc872c94d0bfd881e5a9a52a950b88e0392bf66e53b4fb +85400 000000000005ae239b6c96f06db64d41edcbdbafac77e71bf85a0d116dc1ac3f 79fd54e462ab284e716cf4a122dc2cd032032fae4038f181f0051c99be3db306 0000000000140af1d0cc13c981cb1b446a0a619c3a570f6b56fbd18d9446270c +85500 00000000000db6db3dcf8648542570be0cba0bf33bf5612288147caad07c96d1 ce7dacb00f82dac57f25bed7081ba5b21f308178204abe10454e40bfdccebd46 00000000001f37601d6b020f19a6b0cd4c672103bed997d8c78b0e0c6b2abda0 +85600 00000000002af69e311402c8f3bf588367546a433ceef0381c1e75eb69d9561b 245fc1e8522f3d4203fb64847634cba699b0f2bcd2cbbcb31a17c2a0bc9d99a2 00000000002afeaa4d5d2c0ac4f71aecc90454d65ebabe4e51d4805f15ecc7ca +85700 00000000002821bdcdb4f0f2accdec1cff83d0cac0833503b11f7844334e4ff2 e1bac4eda5d88fc414301f5ffc7e1f8d2a98c9d3c0aa936784a3cc5c1f2c5c59 00000000001f1aa47700f957caf408357e2fbd1ab5a860dc82e1c28cfb80b3a6 +85800 00000000001448d3d310c2f6b805b653262faf6fb1412aacb63a11e8da3ad42e aeb16ca2ff21f1d4a4a066ba04a64019f6e83c7560e5b7987f3a9ce72742dc88 00000000000a7a6b5855eeff0653b9e88d78aad2fe9e20dcadb04f512bc886ae +85900 0000000000067e0b329b2b1ae0b7747d2289bf4ebe3b1dec34021cf5e2a3db68 fc1ffd9ae4ffb2a54199239e9dd6f7b452b069f7e1f40678d620dfda053e3c5b 000000000012693b97ab0c57f1d0789b4b9810f67bddcbb3bc7061c41c74e1c2 +86000 000000000000ff4e1adb14f07774dad6b34968a5e19d1a2fe1fc9157e7c2b85d 37f7216063d1c8b7ed97fe1044be7b0cbb4974b3a4b7a54b6d3da81bff55cc35 00000000001c1196186701c95370644621416e575bede6e0a7dc47525035277d +86100 000000000022c09289eeca6d0a4752fe16023f7c44513d182140e63485458c8e 8b5a338f826cae9e4849ea205116c06cb7bb88ec1a9edbcafe88d640b214c7a5 0000000000236dc58417dce99732304d3d8f3ca8a4b2a718734ff86d48cbf233 +86200 00000000001002f8ca11b90c0390009584468d8f37d0df108fbd11f264867d58 5f1e2d6158c81cb6f55ef85edf96ee8de925b21ccecff35714bd98040e744a6a 000000000025af82ef4f076a1d23f5d9da1ff398a92377d3606d5174d8425092 +86300 000000000020ea049fdc3d9445d033f53115a5bc005f1bc806f785fff6e892f6 346fd7a389619a051c010cd6460cbdd85990c4f32b251fed88650d68c0489445 00000000002b4c61b2b3c88787dc81d6e781335da063c572d4c92331d4f79cf7 +86400 00000000002caaab3c1e80a18fcfd608cd89a6afc8b497653b3a4ce731435437 fc897ef73742ff4f53e4b48f97f600b1a7764e9660a390c379e8bc34f950af4b 00000000002a19be521846a4abdc502281bc3b81f48865784ccb52d0ba6144ef +86500 0000000000149b5ae50401ec721e879ecd927d912c1d7c8dc7172b1006a28722 fbcea0d6e8edc7308d2bb8663a1c07ac9c32e341a7e39da68cd16573a2c39d33 00000000002074598cf897967eb7aeb46027245ac78eaad88a871f3d01526831 +86600 000000000024d20916e4d935b72708b0c4c926bca65676c2cc9964167aa2806e be20e8d88d94bc9104a7024082495d86eb03ab65a8d67fce8c2d92f98ec65d39 00000000001afc5a19432c9940f90ce79aaef71fcb8813ac17c8fb7f2507bc62 +86700 00000000001885501392d037853b5317a68e53f2983a2c9c4bd0c298aa1dd31e 65fc0a5e4f9402850c9e3d159a2996d949e583834a4b5209737c59e32bb2181d 000000000007f2b6969df6a6a6c2cba08a5aa47fd9584512e4f3a1d148022274 +86800 0000000000054958b1e11df90134fbfe4ace88ac5aa7be019097c9634844a235 ef6a6a5d207b899440c11c1f3261159431444e476f357b252727a29d86eb8170 00000000001664fe659dd80b40d2a45b78f2a13ed80e9040358bacf03bc75b0e +86900 00000000001564b97a1b2e6f0856c6da4f49847884efa667038ee9ebd672d067 3f5e5602d117862e027eb83ffcb115ed7fe8561806b88795c8ceb2d9e553d5e9 000000000001bdda98651c93bc8bbafcf08f3a5cb6e8d99b5c050979f12f98e8 +87000 00000000001e468674df93eb3897c3d7558fdf61991708231246e9002e9526cd efd192627c0288b10dbda8018f80bc76d9e67c3810411c62b4ee2bf57d0a5464 00000000000a47bcd549473b9a65dc43c8a9fb2cefd17b044816e0b7ad56bac6 +87100 000000000004137c8f84dc38be84f6e68a6a876f4da1e9f3fd51c6f8c9629af8 811d41c137089d87e94b9dda1620f7aed754dfc301f2e39ede80bff52adb13f8 000000000009a6563129c0e62acefc3f8fa7f9b9ddab3cf7c62db74ba18e0acf +87200 000000000005370d12e1320705880375fdd6808d8a5ddbb571d3f771438190b0 04e26260a5e00f41c3fa087df440901085b7a4a5556216d530ce4a5ce504e97d 0000000000028468b1cca11b786bb33580135fd3381ea693b8ef3fec9b4ed156 +87300 0000000000190e3abd5fbb9dbd33e09f148d95ffb00666395a09d62b769f2389 f1e07365d771eb4a368c4e4cfe9ff28b9392c91effdc0b8ce703be7cd4d668d4 00000000001c689bdaac5b1cfd851d592c9701404884bccf03d097fa19447e56 +87400 000000000009dd57775ace08a5f6be3bbdf476c53ad4951435a977a0051fd5a7 670eb0aa5d25ccd37a244373e8c0900e8b2ff981d81d6883384ce63993503cbd 000000000011c5beea36be46a9aedb561b7b3ceccb4afa7e7489bcd452bb9f57 +87500 0000000000071d3635e2992f79aae907b897dd6683089d159cb96988aa16349b b271c9ca0ac875a8ce18bf53171c0892e5c02b68fab1d0707df4745569f8d99e 0000000000123c2159d3a40110c7ec34cfc4de4df1da4e25676f87bfa0ee2ac0 +87600 00000000001a2ee15e5eff365d3911a20cef4c0b4e492b062808d94942460d23 8206f502468da28034bd49988d2054c9a3b736c38686b5cfc6c37ea1146b6a0b 000000000012c3f7ac716b8d01be5f52730c6911a4965486d8894c01b2744142 +87700 00000000000a4e76f88562305f1b68f5e8565564f4c402a7f64fc8e6ade23447 8c5416d2f9c3ea07279eb7538a36fb907aae2638e3c1b89b68634689536d9ab8 000000000007c781c543bfcb609a7954f7d8a63d6cae16844fbc9f0333653377 +87800 00000000000c6aaed83ec196a07f0023ed4352922cde70cba467d46132cf653e b4c40b0de6946b0b43bcb9c65b31911b78784aec29a01020ddc7085088bbbed7 00000000001e5f14717590e46bc16a4973762b8e1d6e3a61ee79de686716c026 +87900 000000000003790e79bdc45deacbdb028b8a2b5a373ff209f3b14aa6ae43dbdc 5bff3414e07ea0390da697c26d56621d38c4faf0170b8437642d87b5e213b62e 000000000010f95c4b2bd5c210ff0bc3b630df6ff3ddf2864db146f2ae3205a5 +88000 00000000000ae9e98b82b39a912cdc0ebed97c26376780ac996c84d9ec3264a4 3e2ee20c1b0ceacf8ab83a6db21a0a46a4d78bb4caba61c4d2176176c9766e86 000000000010454e08817326f7032770eb75062476e743cf2715b7510b9ec96e +88100 000000000018ae927be3c38a1d19f3e1a41e12de49d88c274931b24eb129d883 d153e15ef8ca359a2e8c067ab7b6cf6a8b238a78d498e459ec6380c7bb9b3db4 0000000000087204dfc72c141935e5074fe60199742bebce4206800825125493 +88200 0000000000198f21a8df0546313062a2543001b5665e59887e6d35ad5fac22ac 63c9b9c8df66e08fd030d9f62ced64c4c270a9c52fafcef2fcd5f492f1bbe1ee 00000000001a158b1db50fbc339ba31b0f5034c077a5f7b7b3e3fcbe3673b8f1 +88300 00000000001dd476950393d78d77faf25df9c41c846015be9ef106c42dbc50b9 18a1499b02b5395c12708327b9a67f42d82d456416d078f4d0341d3a5b4e49a8 00000000001c741589299f02e5c2f0b3037b6456fe3f13967d88d003f50324ca +88400 00000000000ab0e387b3962461fd58b3f5ca34b0184ab4ea66fdc8b827d3ad69 bd7aed90f189742d351283112f7e9c2fb09229ea7919a4e21920fabd08ec5011 00000000001dee20cf2323604befd30079b42a9dad0083feb4bdacc7ec512fbf +88500 0000000000129e6ccc625d9b7fc59ce8632886cde1dc00ea26b58c25731f5dfb 2d2d6419d74fe4bd0b3c103c6550232ae90047f1a40a5c47324b553b0d851a3d 000000000010c8ccf1bdc020a3f723ebb2948f133d3c03dd1b6fc4853beea806 +88600 00000000000a36ba1bf92095d266c11c61d13d393b37883fcece32b493426cbf 83c8686ed4131a94ee843ef1add9ec6a6966d40081a0c36a23e6be0b36b3c193 00000000001310e16042439d0855997c989ea5aa523f173b36d90b1eae62e70c +88700 00000000000a7ae9d627eb9e6db85b34155dc93b062d0339ae7f6ecf2bb42691 4e6efeb92b3f32d02dd5bfd0fc660e28fb962c3aeecb868acd3c0e6dfa9415cf 00000000001cab7993e4db699e9d5afa81705a02d5862dd0ef0455d5fe1edcfa +88800 0000000000114e2f952518927ab00f4b98e6e4c771dfc1b8d2a215f1b34cc79f ca5dc901e2e3eed8940d2c8be47d44231fe138e45ce528a737900c1ba81ade0c 00000000000e98fab00b2df1cdf72f138f567bfefee074909b300e967b80c311 +88900 0000000000127d00a0ec58e83f7ac54f5e5486e10f8cf0dae3824fcb6072862d 6eee3e95b50f93a5b139b26a1f8d19056757c9dbd34c3b1d281a0361f5c5880e 000000000011f14abc3fdbcd206377ad2f2b7304c0342a452d4c0efb0c802593 +89000 0000000000078b8967aabc82021fe024484be7e2982dfe19c58a1b6462130da8 da3dd5c41020db428911165f7345ddde911a310541e89c788078ab4bd9d29c38 00000000000540c6f0c8a870a8b61926748ff72bf6b3f366559d06de24bdb15d +89100 00000000000760d0354522d5ba6f8d6eddadf4214b69b9fc24861ced8053a6ba e948139af1735ac87184ec549d1b7c1c14da20a68e6083d80dc7d69ffd892538 00000000000c24a5a8955fd2b6383349ec923588e7d062eb226bad5af9b6004b +89200 000000000005f5cffd4ebb115f55d32eba7319436a8302bfd24c663e37e198a3 526deffc5cfb23f74edc7d40401eb5f9216457dcbf47419fa08c16441f8b31a0 000000000008f3951b42fcda1d9071e86efc4225af0a5e24816e1dc9de797709 +89300 00000000000638a2082f4b3a8a4e1b6f837eea0de4e76de453571948bcbb4eb2 36b51c43b56e090ab63622660da43c0c9ba3d075215344622549837b64d7907f 000000000011eca1d696feefd8f3841985085820d634d072a94a6c04322708ed +89400 000000000005657aaf1363e33bf81d8d9d266da79c896cf0f12a2c13948623b5 d58c79138ba924f0733041e1f8177535b33ac00bdb648cdfbdcae74106eb8d48 00000000000acc29ab483e7ec9bba79117f589eefa64dcc07890ce3430141e6e +89500 0000000000099b2815c874ff52c48ee2dc731394526c1513fdbc49b25eaaa8e6 01b98d5a7f71220bdea2f00804eaf86665f4321f03246c6efaf2bedc0d30c0f3 000000000001486fcebc5774023e66154b7af7f520220afd57766261a0759b50 +89600 0000000000151929dc55c9a9b88d762feee30725e68e5acd8afacae7d493679b 40721b464c04bcda409f11f41de9e366fadb93e444826a993384b873ab34de12 0000000000075ae9606be891a3c154b4705c54a615e30d2eebaa8e5ff6ade38b +89700 00000000000419696f9c69802da1d5901f14e60527d2323c8e9a775f0ce3788d 14d41fd7b209b14853b87ce4fc5546c568412638c72b3551611b313cf5e8a128 00000000000e860a2027b04d1a962d00948ffebe7b4fdc69a038892938dc2236 +89800 000000000005d659793c8314eeaa4975127b9cc15de37969373bc8e121bfe504 f5cb877198eaf8615fdb20018c630f0cd1612e8aee792d1fbb84c69ac4cec972 0000000000027fc216663f05cf3d712b799ec949a6fcf710d7448d0e586656aa +89900 0000000000102097c35269960fc852230569da148078aa543afdf5809ac693ae 5612222b045c1a9fcafbe83303b89633839c88e27f1227de08317584ba0c9304 00000000000be1ce041663db516af39603d06a87b540d2072b69ff3c0497c04d +90000 0000000000071694daf735a6b5da101d77a04c7e6008c680e461f0025ba7b7af 24b168f2caae657a1d786c1b45afa1eb767c7558819d1d8acf9e3adddc513747 00000000000bbe48ef6c02c01e4cf6b332825e7943a0cc15a5678b0a92858a20 +90100 00000000000e2815adcdc0ff3496afd8da6b138bff129060a4e2c6479303c00c 82fee1797172178e7f0d291502f71f9eb375c0d915b824a07a2353a8916085ce 0000000000060adb5453e25d415d08d3bdc8262e65550d67b6eb489b97961cdd +90200 000000000011c72d2442ba84dc44db54469721c2374f809694acc82ef76a5919 eae27468830b204ef49e1624d956c7e4b90f73fba75c1bbe5f038df9237457cc 0000000000116a9ba9cbe82628e9a330f2067c6dcb70df4f7c837ef0d8b651ab +90300 000000000008f437ce399371e305b02c82603b5b2261db22ec4c1148c2d803e3 caa305cbaaa2de549dd6d74573986a6d7ffa5e8ebf5267f869bb92967e464217 00000000000cf1f603522436690f531f24072c98c28513664bf2722583517d20 +90400 0000000000048ee4a5d6369c09a42b1c7ef564da934d08d8fddc4d796ecc89ed de6fd3fa9c2a327ef57f627e8331d888043218d562b71682eaeefb372589afa2 0000000000111d9e70e0f772f3756dfabf589ae0ec68fa163a7e66fa2ddc7d2d +90500 00000000001104f5d1435ec5b7102bcfd8f048e7c1e2a793c9d21a5d97428c01 ea9e4a5898c7cd1c9ad6b2039300a7996c47ece3f0d856fb0189848a66c6294b 00000000000935d678a5d4d01167087687c72e1d5e66e4058df6151d5577ddb2 +90600 00000000000b0e576c983ff442fd297dec163d02325c8cac9c16df24008d03ce 664fff96efa26c58ae6ca41f9008bfe146154e7c8e6ed72daf0e74df8a16d367 0000000000124174ac7fff442ea51f62e07787ae6751222c56aed176e0ead510 +90700 000000000006ef0393d6685305b0649a5d30b5032367db7b6a1cc3f8c7be332b bafdfd2b96d71ca0dafb75d851e9ba2b63bbda1d885180a8a31dd64ef1ee33a1 000000000014751ae3534ece15c67d140fc031c6445ec2da6dbe651a33d4ffff +90800 0000000000092e76ac3b07da170a84f3e4f5eabc039aa61d59bc5f1b3499b519 2edd62934c7fa764b7159eb987ebbaa9d76ae27763989a035dea24642149fe90 000000000000198c8187e751033dc8e8748dfd76d6b183faa8374c885f71e1cc +90900 00000000000d8e8a369383f6b483889e07ee000d7e07e9ab7f6bb844f578625b d2239e9a0bcccf90a4529a75fb6a100ef7e6e65d8e4dd4a561e1a39d2b0b0422 00000000000a555bcaac3ab9632ef83b2c09d29dbaa7e5161f4de0a89363d6da +91000 00000000000573bc13322a6c97ee0076e79ba38a8e57e8f1bf790d13190321d8 aacbf73b1f0e947e1ed75cfcf2a2d98ec2a3b6d194f725bdf51859f53b20d529 000000000009982bf9c88c76d0d9476c403caef7691f7c8f6bbd0aaf050c5bec +91100 000000000005ae4a7f25127c2a22e18e998170829334d33262295a25e3b0507d 6eb96dd0541b6340a51ed0e865cf96dd380f1d6f43d63125eddf74369817d88c 000000000002d98d1c942100510dc0dd37ea4861e0086205fd92ac2b3bc06912 +91200 00000000000330a950d351e183ddd171a9a540f5832bd3052cbd14a4f01066c3 f48482e111b4f0fd6b8d103ec9df35212dc6fcfa468c850da879d7e564c4e6ad 000000000006172709c6ea5696f1bf34a4a7f7152a6154cc6c0c0c3ffc8ec6df +91300 000000000007d143a6710b3cc9f2acac27ec4a1fec2948e461688263b3b51a27 3205719cb265a78a245b86d9aaebf15f216835dbbd37a99faccc8b732dcae5ab 00000000000996b82b6ba92b457733424fecf0f2a9310826d1ed3c0bffdabc7d +91400 0000000000068e94a4130e50889e24ff883fc0c4fe35ef27cb60cdcbce428238 af166952290c208078127c12d509c8c7ae05c80eb4115b3efa189413fb717029 000000000005e81a11dd9471be1c40e552dd11b0d7f01a6221ab5509eaa9ed6d +91500 00000000000778ba57df085f43d67e4a2be57f1620ba5e829136cce38796730c 1db2a2986be1a6d2de88e66bc01912bed69bd7e24931abe54e00d1c3ef172cf2 000000000005db7c53efa5a48681906f14e3a72258cd730c88deff87eac4d4b5 +91600 000000000002e7316db7247d0ad43472000c679b27b255eb5faaa97507d1671b c34dffc33a24b552321db051409cde77ed0c2419a801ec831664827caa59790e 0000000000061a8568e91be0fcc8afbd746a02752adc7e95f28468f375de1d7d +91700 000000000000e001deecac420b8f2ed64ed0efbe32254f547ad11834da0488b5 880d8e742f8272dbeedfa3cb52e81507affe29a13022495d609d9741e4fa6aa5 000000000003fd8e89f44b6fdc7b7aa30797fb57b5d69f284747f53f79ab595c +91800 0000000000055f563abfe00e42aa4e0c889742c42f14087922b353b24cf24425 f1cf2449f7277ce73f04cdd24da3f7fbe6fd1745c096b682df3452fcc00f9682 00000000000292ee05baf017f15780a2db02a99a1019a1068c9c12ed667f17b8 +91900 000000000003422b9310497c471f9cfd6f012896769d9cd0126007d016f0bab8 8e5e33a32662aba4d798193af6b52e238cc0f27af64ef611435c5325b44d139d 00000000000257c808dc8ffe684cbcf9665cb4652f16cb95f5bfd2638f3a327b +92000 0000000000001df90b0c523a4d7e4731336b00cf4ba9d8e02d111523df80998c 617a5e6b96eec2dbcfad287003f4ce4e89340fab63811faa1f1fd518cfff1e2e 000000000007e96d8ebad5e4e36c737ca121a1bf77078cb815f6068e59cf9861 +92100 00000000000b720a0407c8e8f08baa12bea8c6e56633d6e88819a771b8eff26c 2da8f8116f8f997c32adb2924963a8636edeee677960e264f894cbaca1f45854 00000000000607988ef93a111df1dcc8d00902819b097c17d0ae863f34a343dd +92200 000000000002f5de591c3ad3321145f2a8dd60f24d4d122a29aa99c4955761c8 03efdc5a036e63094ef1af5f51fbdbb97a58d3f8a69a983e16b3ac75902de7bb 000000000000987c630f5a14c30cdd57d5aa25251aa990fc77c5dacaca63d735 +92300 00000000000128669f396328418dc4bbfd55449c8a21f8b747a19dfdb00dc622 d7c19a43a51d894f09d8d426dfb23c6ad1f0346c178be5a12127d24d147f47f4 00000000000dc865752bda04653e49ee94e3aac62b109b6addb00b024843a115 +92400 00000000000890521d6dd1fbe096cec7d3c3d293c7929cf5699d7e2af45f9b0d a0215227cb8b064c57072edf19c5cb082b23c19a09569f0e62e9f191b470b331 0000000000023bf0dc268b718c359dffdcca089cf71c5653ff4d38262092a148 +92500 00000000000c6e13d490f022a3e58d24c673c38f20bc7c5f8c6cc98c633d92a6 5eac4390533167baeb244ea083596699582790721a69b4930f4efc33fdd3aeed 000000000008c686fe450f1923974405dad6db8f8f8d95e710325293c974c593 +92600 000000000007945a98b6c640decf9d3115aa088092f982ac66d4731ecf0d45aa b5027641637218b7f7289a47e121ff0ee756c8dda37ecfd889797722b56016d1 00000000000d1be55ce347229534b6760693be12981473a621378f01e259c0db +92700 00000000000132cb13076fe45f38dfe1ad781e978746bb97d3281642d51777ac 6a7cc0eb96f4c79f27c9f0de1b6e9f0e84510e54af8ba75a879440fe9923fd8f 000000000005bfc401fc8f6208a67ba6bce7468b0a0093d912d8ace1e8a78fca +92800 0000000000057df2aa27522e5a385f86dc31038c2f490de2d155e4d8ab327191 720eaf360aa93c7e83530bf5902cf943b566c39073e76bc2a8108df06959ca42 000000000004f0fb70eef2338658d67a92661ba36f964e46999db6595def6f44 +92900 00000000000354c114d9d97c7c8271bcccc652c647a0a4a494b610b7965e77f7 408463f467ebe1a61238aa003baa63001e41c79cefd396c42f1bb91d66cfe662 00000000000955959559f002b01e34736f473ca18d94d922a0749c8311cc4fd4 +93000 0000000000015d5379547ad416695137953a85f5a059ea7023b5aa1d9fdc6f29 fe7225b0feb4ae144ab10cd6fb782b1173af9efb8e268b22817511a56c36000d 000000000007dc9285910639eca800e61829d99785d70245c88654a4bb4f984f +93100 000000000004ae1806ab6049aea8e18cfe73c4fb8cd171c7fdb6032246e3a96b 6c76eff2887a9b5ab56758937bb5b77cc8a4673d317797bdf8f99a2ca9678163 0000000000061b826c837e444a7bd95c62ad2322b2adc1367293a17d2c98dd9e +93200 0000000000067b98b05971a9bee5a2766361971ed55341275627e791d8ce0926 d6b67159f5d506bf154d8db696e49811820c83f617c4cb8b999e57957430afb5 000000000008b45987f4bf67f6fa99fe402404c1ec8af7e1d8ec5fdddafec716 +93300 00000000000589b6f3b3561bbc923e223829adc8dd79a7ece92bf551b4cebe02 9f526130fdfe20a8eadf732aaf515c8ad407a52c637af5742b979c58712305dc 00000000000093412d373bc8582da2666df749c21c2af5690246a60975b05663 +93400 000000000002b3756400ae209362b998689f10c20e0ccbfbdd60f35934def8d1 ec9a5b2752335138727b4c21932ed580e3364cd1bf65b120e2c4bb1bbc26cab2 000000000002b4cd7ef4071782a0d23c0bfe0b599c1405244fabde8af3a37a9d +93500 000000000003b8e6533b3f238ee00ff8dd68c3a2377a213f7a72c3ef0fe0c54b 0b31dcaab8c429bf9f41f84e491b6a5bc91685d864fe4a52f857420d2691edd3 000000000001a692f5f63748a807170471d324d79d5575ec5111f52142aac009 +93600 000000000001c2e4aeaac29c9f7700739b47b56efb02504591970e5dd0f94a3b a01e9af4eb8b40ce39ecf761624996bdf5f6f086b2fbde0aa803fb9669fb5af2 0000000000037e3283e702f6186dad340db78e0794e227d92c4183959a4e3a28 +93700 0000000000011c7edb2aefce1150fdc27dde71b9dc60127a252f641e54ba766b 09190528133cb3025d13e80f2ebf003b9b0fffeccc43ab7bcefaa078f7c78716 00000000000238888e066733d2e91965bb2441b5c6499f764065bd210df48dc0 +93800 000000000001f97499cd82a440ee1e15a6581537ab1617743c29182f42d9a527 c9184b65f77164da2fbded855c672a3324456393c5fabb1dbd85ed64e8286e16 0000000000085fea8d24eb15829c362272420c4df3df8fd3df3d01397a09f2eb +93900 00000000000049108fc9e501fc7d8cad6648b14eddaf9747abe16c73105110bc 34824f3cf78fc8b30a068dc4a92d3af0513430f626c8162ff04f9674d27a4c46 000000000004f7f4a567f4e103b49a18e05a45a48a58145f835a56ae28e249d2 +94000 000000000002a4c42580d51f0ddfd867eaaa790781c484c633a69167d17b48ec ed9e2f062caeb1a2e4224ec4b5db152faa41098773ecc6d0a96ec265f9e667c1 00000000000271be2d9430a96ce054a55d6e7ea93970faf2dc256fc24f42a0fb +94100 000000000003fcaa59ce84a09487d0c9f19efe4052a9123552633f1fec712e1c 41f4b1ab791eaa2c77dffec40360d516785d0d21265b41380a712a0ab75d3eac 000000000001c7f35fb840be14d1922135f5edd65a13bae2505e7d262faa32e1 +94200 00000000000081b1eb68ccb01607dac58f342e733badeefcbf8a86ae131b9a0a 06484517ec8fb88f74db86fc7be78f0e9577cae8df45d0e184454aebef570856 0000000000034b3708b6b9ba05445703e37cabaf34c88b4ed45e6d4e42708e63 +94300 000000000009230e0183c2f204e328b6423a4c358c009f58a6d365c05a7292a2 9100306ad68a54089de0ef673bf98e837ff6e77e436e052a936ca6bba58b9f0a 000000000004ccb42d8940a7f7efa5daca869292add0d58d3d74382bd5835e8b +94400 00000000000339f0006e7907f514da28984cd5c5e7a69cfe4c70fde50755e16b 7785d856bc117e4334df3ca67665bbf3046ccbfae87bb175a53f26440d27bd74 000000000007e35aa4de86756830e560c68e951d7eacf81dcd27a84ce141e30f +94500 00000000000066cb6b9e0bc1f315b5ae37f33b945649657328b2010c8a44e510 99877899354e5048cb3984de810ed7f5de490aca04967243e6de85acc5d116c0 00000000000294dfff295b06333c9204369eb1ab508b96beedb995c1286cbf46 +94600 0000000000018fbcf686aca81d795acd4c92dbbd83e45211d892d4714270c7c5 bb328c2f42428a476a5c04d3919055b937754ca28db3514afea689fd201e8add 0000000000040a74adfa2c92b183e79a8c571f173c8693940d84d62c9ddf06f6 +94700 00000000000209647892b994991ce8452bf3ecfcd3c4549b40e3fceff0d1c8f1 8a8f193ea31707dbe00a477a4202a9c7b778c48fbfeec71cda5c5c0e280d63cd 0000000000026300f5989982d059756f9b9dc7ab7fe60c319bf447303bacfac1 +94800 000000000004e65b3f7ebd33b3d4365f67cf210a8519851c76c214e621abd6dd 5d4d9e262c234dcaf539b8474e2e4f6419ad095fb3222ff6b24b1b97e78b4942 00000000000122d3c73aaef4c08340c7b388801b623d0650c1851c8bbb65077e +94900 0000000000066e0020f4f74c274569a6c19227ccff8ab0f8459dc38f009cea56 fdea0e684cb6ba8f9a4192b55c4a809727987834bace87c623e8d5f6350692e8 000000000007c278402bae2ff8d81e3dbaf4764c4ea4b1b66af6b9cfd65bbee2 +95000 0000000000074a6f7e2d07cd8e5dd6dc8183993ee3b84666af499bc5b439d21b 069ea7375c9b0df17f535500941dafa23ba85512b12ff8a9cd09cb3220881905 000000000002b51a6a06258bd17d92e09acf7ba72cf1dcfda15ce75efa0a30ca +95100 000000000006e342b6b686a30efd3b3aa5aab3aae3d0ac475332e79385fc8bc4 cf91cdffd587ff4bc37f613213981f8e9175d9da3b45a91f87f40caca5ec61dc 0000000000074074eb23186625aad8ace4898638f74d019a86ca6cfb3eccf129 +95200 000000000003d7c2a1677195b8c733f079ba9599e75840893aa57709371689ac 4eca7e2e5ca93c8e899af8f10952fe274d8212b36913bc4ca1587de43d682ced 000000000000aa8d45c81d402b9529f8d9f832f908ee20dbd5713f46914e3e60 +95300 000000000001498988c75148b09b10c1f481fbead6f9c0413665cac517e2ba71 b329c1ef9a4fa2be4d9602fcc989b4f98d9611ff54b63d76c7ab766c3245d591 000000000002dbb8b2d74138fa2590bcc88641b2a541d98cbc52dd85a94ebdcf +95400 000000000005c084ff8153efdf67c261c5e122d322bd59f7e80b89010a37e85a 89f84c13aaef954facb0170262b482931ca55d4d786dd7b87a80d2f2993b81fa 000000000007dd187635b285ffc8eebac528e90d8988c590b63ad50c8be1fec8 +95500 000000000003340fc85f7f24f9f28826dc05590b558e224114771e93466670c5 be54265ec347fa3dbdbb9d0402814faa3ce5bdb170809d38b765f1fdff970220 000000000006984a2515000f83c48e879900cc5d481e00af179d7de339931679 +95600 0000000000062e91042e587c0b8b61a0efeb75962790e20e09a1cb468e2b6a77 53c48b90e7c130c7cf23dcdc5e3b187c1a4a5e309035fd5c8c83467e0fc02ad2 0000000000062d443eaea6ed409af89ff5ba71e7002ab8f896d4e540040e1abc +95700 0000000000038eacd7b4f39b05aa2ac760e1cd12be5c72eb7c2b9e396c5762db 69c3a2f5631c22f55ae25ab1ad13ab17f07a8e8e1c9bdfef00223f31023f12fc 000000000007f080e1516d93a7c3c312d75c501b69d178837ed191b84b564d4c +95800 000000000000803edf4ede8a8600aa2ebadba5394c5633394d2b2f4ca74c614a 7d2144252d3b82015b1317638c2c60d3741c8001cfb883cc9f8fb6e2384590ab 00000000000570c63368eff43961943236c7a23ddd128c22ffd40cb72a162981 +95900 000000000007353c808928c1824296fa28040ed02f4011d6264ae431c839364b 99fb58304db622c86d5a11cb1d9a1635a59eba6fbd93662953999bc24c4367a6 00000000000636b3780f83a4c0c0c17918343bbf73d99e1ac9f8dfdacd1295e3 +96000 000000000002c86b568cdd2d0f4b0430cccf42bcde3361f63a32e23b5d839e99 e9099a8a5760817225908a04ad8cce28975d1b2661a405bc8cdf5a9058a17802 000000000007b4e174a5dd07f1a785a5d0a52faaffd9d610ff65f64270ea7674 +96100 00000000000707297caeaeb7181c10e4387757a935c459ece11f134c7b0a5567 b597fcfef8af47629d2a578bf65c5084db3777818b4d8264f2a20033cc0350a3 000000000003afa3b68403d0ab16d2e39748e8beee77773d46fbb5f233bd1f9f +96200 000000000003b97cec3e714136796147fb7ac36cd18eba941dffe346b330e7e1 fb063ad525b4405ba5985c55a3175ef9a51b8b8e1e826c3c70fc522dbe4602d0 000000000003b0bde61d579b5cac2a1634b9aa553d50bf4767a372da0b89eb38 +96300 00000000000388b7ff437d4596dda03e9268fa49daf0afea3754b982cc3269a3 1b26aef7ad68a620ea6c3c08119befce153ee6b1dea3881bacde6d9e16f7b0e0 000000000002f96cdbc4e8fda3f962189042c03a3d241ac720643d1bb05afb92 +96400 000000000005f7ef8404dc7f19923759055eef4958e6925ef2d2857191af7fbf 9010d7906679ee3bb1c13ec2880c200ac98b22e1e22c11248cf507c1f6062af8 000000000004d684c9d2dcff1a4aeaf23f10d6b6b4d62608cd553de36e400419 +96500 000000000007ade4492162553535806069439523fb43f13aafd75c0bb20685b2 8430f87500403421a1988fb777dc9c613e08f4290f832ceb873fbdd09da876ae 00000000000215df16c04334e24412d50b5ea086ad5934c22e1e374ac53f6d4b +96600 00000000000709b491bbca122caa1d228862d4053e0460f4aa040539c9855c1f bbd481145a7e3ded54f61f70c348a111e73cae817c489cf435b7c99562e2eaf2 00000000000186837b48d1e191598a881524d0d386d7d7eb44425a4497ce21fa +96700 000000000001715eb0c743a5fbb813ea4c103276bc6d3c9b21cb9491860780d9 a7dbdaef58453af1aaaf8b0b9a29a1a75412f9ff20621ac26d1f6b59b1cb6799 0000000000021e63af5111a7aed484425a42c1dce5bb22bb854418fe380daa05 +96800 0000000000053d79c4b7b757341e50faf2af99fdd62421306f777e09f5e06d6d 228cb0da112c064985f3e20bb13bce822c4033aabf7a40b87b25ee2057578ee0 000000000000a4ec5372a8da5aab64355fccf19ffe8da3266f1347cc9bcc3904 +96900 000000000003f698b3b023451e7e0a8a0a8409b4c6140e4e34bafc84b46c5048 cf660a03ab94846ed877f5a82a9d1449875fcc5dfe2969f46aa7d38070c28182 000000000004882dabbc12dd32d907aba2276c7678cb1f899aaac417a05dec31 +97000 00000000000125d656e9f28543317f33fb1b66baaf90de44a375ce6c5564fe0c 29882924d2c2bf7903dcd9920e0cf44dfa8fdcb6a685af1b7cc7af8baf30d2e7 000000000005060830914914b4ef5b1f62d2af15bfceeb4414cde51576ce51b6 +97100 00000000000009171b98a3870d1d40b799d80eb50903a8747e3ac1968377e4b3 66602b2500d54d0490eb05b8ac1e05d4723bc68612b483fa86fdf71c6e5cebdc 000000000003d7a8f9845dec920cfbdac206e8e8c9a3bb0d0feff48434f58011 +97200 00000000000056c9480b1090eae62c1ce319c55e2a3364550fc58bb809196f73 fa3a61ce39f154da4713ef9557c772ab4f3ca9498bd5fb0859c9c31394075d08 00000000000391c04395318dd6b916ee171fb8cc07384e58748def0c509d093d +97300 000000000002ace93caa3128fe86e305c0059a2966cfcb306c53faa9048aaa21 4a3a8e57c5d7a310dbd367471e97ec26aa63c514b5727cc69e3eeac034750e15 000000000004d04d6ffd13f5cd1316f798ff00f0a5e413d30e2eb70dab999701 +97400 00000000000542d15aa82ef5b43779a34c8f1a20feb890bf634486391fb2b04c 2707072b102567da95c5b82e5ddb5979133c0b28ae81fa4673a972c9a7fc9992 000000000000dec2d580acfcd6fbcc5febd9887accabce9b08eab60783b29988 +97500 00000000000521670474ccb00b98eb386d880cd8ae9907bbd232b4ef1cd63ee4 c98eeb2286b905975565fb796bd46f28904f264511a77763a0ef3cad19994ad8 000000000000aa170542e6bb7cf905de4f94be4b96f86e42e0858be99d8c85f2 +97600 000000000004945c888b2a3dda63df0351ac1a43514cea2f54a4bdddcb0416bf ee1876a3b30e236faa879f28dbfb2f1bc8896d45b69c851f81945a954be967a9 000000000001cdedd57a311d508345bb026e41e24bf455bfa06b61f439586ed2 +97700 000000000004d2dd26abaa950fc0e59d75c3abc102b6dc12b02105c14ba38ad8 837a2f16a9224a95fdf6aa190752b09d1f9c07a7b5148ab5d17599c1323b0928 0000000000022433e2be2b71bfb303be8290abcb2f8a00ef94fd8050bb18bc26 +97800 0000000000005d3118f7d300d3748d549a3bd41083021d82a0e59d320b1f3294 64515f0ec1c206312f7f11b19f355ad97bff6cd02e1116a337665317923870b0 000000000004902e5fa45437703d1fb855408225dfc94ca9672bbf22e229b71a +97900 00000000000232380d9560ee8e46de48de930fdaa4c2c372687afc239a67833d 4e62c63ea19045672c5a5dc09777b35d1a99974382bee8b6c1fcd2c5734f070a 00000000000393f71fe204aea0ed3e93fb5f2af74810d2c60515df0a282141ac +98000 000000000002272a6dfb695d9db936d813bf0055ae92e920c2791d4c5f7290f1 905f0077ae5aede9e321e8211ff35ec32976f4ce67b44c1f4094322f840c9a0a 0000000000054030f5e323cd782b8030858356486a369701470f6b1ab5854e28 +98100 0000000000007f7d9c153eb16e6eb865cc835f6da8a539bbec701702f3bb489b f6db3bee04b44e2e200e6461679f75a4c973236e989f0a6366c2cb47fb4087ad 000000000000cb7af5a961182b5a5e2e3eb7075be0e98e58ba4e85ef38b6a5c7 +98200 000000000000941ba9e7b94fea58d9a7a20527839d808893facb87b09922c5df 02e171d41931458076b72ee62f2a09458e384bef837eb073ea12bbb3be1ad260 0000000000010850224a28a9cb19610d3e68b4384176d0e117dda38e624d4560 +98300 00000000000536637b79d1e4cb197837225d166b7d1b5f552c9280cbfa14ecc6 7f0a1cea14da89708ad18e3994546d61020e5e23f3da1d3bd5a5151f88586881 000000000004960b505a35b55c09a1d9c438c4dcb38610e0ae4ece76e6c50742 +98400 000000000000a73978223424a7a5af563ca60c5e2ef630055842b223e649aa60 5606b4918b492d8ec5af7f48bd6dc4341f20f7e41839ac1afd6e43e9b78e0cc2 0000000000035762f5d85a4fff0fe6d60784f6b78d7c6084e671b0ec78dbba47 +98500 0000000000010e44c3b207c18bfe83fa16966c40dfb7690c970e501211afae9d dd2a929d1b7663b19b47cef70d78c42c2918b095ba20d2ef49878b29bdeb7023 0000000000017d04e76f4f54e6895ef9685c1fc9b6021073fa90bb178ce73c00 +98600 000000000000c915a43e52e1de0e1228d9a77a37b21848fe7ffd1ba287e203c9 f8dd4ae25eb7cecbc36e888e01c27ca72ccf76b83bed433fb123fd99d5ea1751 000000000004a577ad59f0093f606286116cdea93741138319f4e529848f2dbb +98700 000000000000fc0bf43f757443d95994da84b0040d92f3fe97b4c49843c8671c c1d3c449a5f144594b178e2121295e461a76e30586997af1ef0a88056f987a18 0000000000026a4fe48156900433d7fa1af863f9956afe902ebbb64d9852f7a8 +98800 000000000004599fde995b12564c47ce30b70664c0b514e3d559b72778e39401 6d3c8d729ed32be5064e2c6de1195125dc1f546226974b6a8747fdcc91b2f32c 000000000003e48ec74f2a2ba02f21502e5e0fbbc8edd93730fe4d34b27735b4 +98900 0000000000029686908afb414dc30760d74ec0a34386617d010a47de394ae61e cc1a254c03870e1c8c99cc6231156d78738b28bfafac15523236d9c28aff9247 000000000001741120135274584b2a0da45b39c8cc78322a14f9004ae766a8e0 +99000 000000000001d216ee63e5910da39b56d4b15fd962951b08901bd520a0b2b6ea 4135feef91f8d06b7b072890b6499ef5df4c5413361e7ee1a316ce18971f087b 000000000001ca717a5df4f57597b8857a2d10aab94058ef316906e56e0fcb16 +99100 00000000000476fdc864086ddc6bdeb06db08a5cd3442db781f028b606e1dfb8 ed683d28b25d80904ef0c36e7e24acb6a57960f9794756128d7b7d6f3461e554 00000000000233df19df1a9fed5135981336f9a5e0789fc1a8edae2805536957 +99200 000000000000f7b1e2a08722bbd959ed71c007ae2b06c88cbd540f20227484c2 4514272a9a50bb01b2134c68dec95ad2cf08c43a15f9c81da4e30f65295b6e6f 0000000000032941cb26da8ca61328cdbff0c3238245badb50ef95afc008ee63 +99300 000000000003a9c8f5c7519b551b4ca6fa778b01cdb0483a2f7c4bb6d8b1759e 616ce2db9f4ccfc0b2ad5ecc9d30fd10abe66aeeda3a85fb2924db96e23defbf 000000000003076c16ec122268577b289a732481e2a3ada56f09d1c938d6d400 +99400 0000000000016ee002b1c9c22fa48bacb8bbea700ca06fcb3d11de6c8ce1ee1b 823a9b30dc016aa435c97951d0ef894aa352cfd1672ce09aec3df3073a4d38f9 0000000000001127faa05ac51020ae6618e8bdef2a8a90d1544dfd287daa05f9 +99500 000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0 63998fdebc4ede799349dd09adf0fcceed43c9b6f6c16017b8b45d3b751f00e7 0000000000029964c7d51f585238f335f4b921b460936efcdc350af7e2e45cd4 +99600 0000000000046f21953c9d463c27058b2567904134ea781affc852b65ab8b85f 3358debb5135e97c8536ca52a09e699ce6b1704d44ca1158d78db9ce55bd1186 000000000002cc73b21cbb3830b323a22c581fbf592e5707af48dbcee0c0fb3f +99700 000000000001c74d8389142debd66d4d077bef96dec3f5127f6baa79ac01ffbc f0bff58c7edc100ab603882500fa4db0299cee2632ebc53c1eaf46ee5ba5e888 000000000003af270f25e9b6470ae9a113cd79f7c5597fd11b452a12ba544c76 +99800 0000000000046271e3335cb857ac8f971b7e43b476c9549e496a42ec73c275ce 9849bab9374fecc1a7cb3af5f904c3c4c7a308631f32175c1d9a8cbfdaec75db 000000000003d3efdbe6b4b45ea697a801ffa8a304c9a0e51ce1e0c7e5cf338a +99900 00000000000371b15c205c32d0796c0a791000b73003ada3d0ef8bd7f0aa72d1 389b333a7aaa870cf975f80fdf704c17d9d5529e312b5f86bca19cc6e447589a 000000000000655ccc8b2af70741c86690be257ae40881593a4f68c309ee85a9 +100000 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506 30055e07017397d8fa3b3510372ef7aa8ad814c5e70d55eb514fd255f2781ae3 00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090 +100100 0000000000020ee4806021c0b6e7b97d31df0c2fdbd0f6c3a7cb5883c7bc151f ea09400a6c20ea3926ca2a96f3215321aa324b02bcaa9bd18b568325b92ece74 00000000000313ea1e469dbfeb7851667644800006138e13ebc02a7ae4cfb27f +100200 000000000001f903504b2bb7fb65f35090d3bda3a60ee72be9cf87ec9ee6ec20 42cdc88119d85266ade220bfcb1e44a5c3f07b612558704d36306453f9402a82 00000000000414619fcff3fd0e18657963a03d6bc46daf23c8b4d2234e06c452 +100300 000000000000391d7664b7691f92c93b6deaf47da897bd02738a50a772f418e7 6b69ba98308745e525dd18443b2f34135f8fdcd6fb90f4952d0d6caacd3a0a01 00000000000094bb6ae6ac97b82709b33bfd2f4817872c140953750899226e3c +100400 000000000002143085240c57a5eb481940834bfd110906a83d097d3f74f1393e a5e96422c2c56814e7c6bafc1066fedc2a849247b0c83eea57dd29e20b6cbac4 0000000000045aa264769b5a8bf0460674bb3a22a3b0fa13e072d49c571a6a62 +100500 000000000003f477deee16235ccd7ab4d7455a5a25bcdd90eb52c93916ce7d35 25fdfb947a69a97438ed0e4e9c7dabaa7f3b088958a6df398b7b9397e936285a 00000000000137aae90ffd072a62f27273be0ae59f3b05a619d6ed2aea7e7501 +100600 0000000000007b92760b8d801c6956cbec2dba71a6737456320053c41fb03de2 19883ae62603a0049333966e20075ffa9d4d115263202a37cb814c9158399b6b 00000000000177cdafcad7cdd484326252928a960da20a65cc1a289ac0820eb8 +100700 0000000000037b6ded27bf92e3bea2f8919cfef48c53b60a5ce84083ad6c77e8 ce9f0ee24d80fd3021756e10e824a24fe0dfb29c8732329c465bee1de34bc256 000000000001b9a7de403d4ce5f0f1f659ae72036c073602c9d3e6f521eeaa25 +100800 000000000000e383d43cc471c64a9a4a46794026989ef4ff9611d5acb704e47a 6951ebe5bc87483ea1ab7f66c74a4201a4c8694a015e6f970f7e228085daca2f 000000000001cc8b34e984092a1eb4b51fe0b9b991b7283f6c859467a662230d +100900 0000000000035eb85ac833a97e884cfcafb6299651dfb3eed5286d527d26d20d 9662dbc302b3c7ee448bb8c397e127ddf894dfdee1efdea4a5e8c9b151008e3b 000000000001d0f29ab4fe89b068ba6eb81dffe0f2ebb3e618d705baec8da375 +101000 0000000000009c11d2683ccbba6d1b8dd7985c3e693f55c95539156aa76a8d41 b093ddd8b7a59836a3f08a5e2a6c38020725c8f4842121edc25758c01f975a76 0000000000025fa3248a57ea24d5c91a20879490ae69bc77dc482a0e748b4964 +101100 0000000000009bea89a426754c3897b7c48a723d52b8f34f7b5f785c82217832 9483e1a6255ac2bad6f28a4dbf8ee5b0f0eb451dca1f929ab7c6ff6efe48f7a1 00000000000290c971561d3d7e103c17231dde9d363976311e121d07182b5df9 +101200 000000000003526c848a56b2fbc252f18bda18edf1c05dc4e75351b173874b61 1c640dc86419e4db40753386fc5be7d01b639cbd323ca1e85b207316eefeaeaa 000000000000f513567303e43c016e1241be5914818ab74d25c50bb688c1d8fc +101300 000000000004044f1a5c496565fcfc37d2ec2ea2cf1b1bd1b1eb4aa56a9523cc a6201a754806df4bfe3cfa86e87ca57ee6bd0238d897f154b2bc7651a48b535b 0000000000005cca107f3f9071bd69582c7d8469f8b261fe8a7560cce4f607bc +101400 000000000003e8ffb19073074f905f4f3ab51c39415fccd45045b17d903dd11c 1b98d295d1ecca99e2b98df0a667a554ba5ce8cd2f53fa1e1d53482811f7b0d3 0000000000025ae0d4daf112cab075dc07f23379add7ee6a9e6f0c9e32825051 +101500 000000000000a99859dee7f1473f62ab817ad8662699ec9dc1bae590e3a0b433 8fee43302a593579f060084dccfc22999935f89bf02eb8d51caa49911e3ae908 000000000000526785ec4183a4645e8887e576f8c94a57a68c9f96485cd7a3ab +101600 0000000000008dc0a3f530b8a484e338febd8cccc17b40296836432f88457fe4 5a39e8aa1e8d774c28e7d897bfbc232a269f3712fdfea0ae25b54dfe76b82102 0000000000020d966bfd756898f293fe31256044207f65b7a6e4d543086de968 +101700 0000000000002b32591bd3e847a3709376002e51fdcf50fa40c5850c8adcd3c8 2a55822b33625e976caf3eecca46bc93e30559084b0f6160a51f3ae9e88fe25e 0000000000025638fccfd0967e8e718fc29b494767e408c38e942e4611b4ecbe +101800 000000000003456a75efe3e995499296a93f4a3c5d7a6a83118036955ff6056a f1c3ee7b300a1c83c0d9668a021e1dd0360a90268d29d0f5e6679e36b120bee4 0000000000012ec59c0bad157659be2de225eb467ca74ef47ce6e18ca3e7da33 +101900 00000000000251a23cfec2d71a0b34a1838759e8f5e974ef80d5370427902990 0487027e9301703c925f31a3cc4b28d396974c0f501db33d921bf23bbcebf362 0000000000007baea3c6cec27cb50e3ba42a3ac90694765fef4a151def198c52 +102000 00000000000335c47dd6ae953912d172a4d9839355f2083165043bb6f43c2f58 5a2ba0d9512078c1574fbc56d57a9672cddb8252e3dd4bfdf16ff56c287010ac 0000000000035107dce8eb675c6fa9a08c7617c109b3553ad8f208dda24065a6 +102100 00000000000004751b3fac9c7bc3c3ff97c7c45c4328d1c9ff131a1063c1af57 7d12d2f090d8538ff2768cd808cb0e6c3ae447fb3f5ad69df8d32be6e01ac1c2 000000000002878aed576f1a2bd3d729751e064125190641efe6574bf9612ed2 +102200 000000000003a6907ef82ebf06524de8ae6eb0ad6a277bb1268b94a7d268feb8 c6084e402c74234fd63be9c8fc3edc8e28ebf11c11ec2d1b9855d79ebcb05dc7 00000000000141e64bd8181aedfe9e3539c19c9828c941841b59127e984de2dc +102300 000000000002aaa83b402d164af74b7c9ecc970069027cd828e382541139a20d c14da81c11da6672b169cef448868fa0d5eca8eec831a0e9f80edb8a5cbe7440 000000000001ad089eb9f9baad765c3955e4f479e52723a2d505276d885d754d +102400 00000000000388b58161a8e2299f4aa60f8fa96b45c060c568ceaaba71748e3c dbc4eb56a2f95dc7c81704b44523b907002e657c8a2242e710d0a003ae04104c 000000000002bfaed9871a3c959a364d773ac9ab9aaea2688ab27448249f9430 +102500 0000000000039b338fd1dc8218f4516ae50367ac0b2ac4d0605a433ae74cfc22 dd90c60eebe0d54bc3026da5894e85eee7bd6575c219a846f12daed9c97934be 0000000000028af3c4928fdd8c6327210405ee5805b9f356b215a705afa7957f +102600 000000000000f84f229ff7305639af440f1477cde3a5492904c61e708264bf2d 7699821bf3b477c33430adbee78b0c978fa3dee0899d7e3536e954dddc9e5c30 0000000000036677bcc8bb71eb42bb74b4cdf61f0d10469d4048713bbb7c7a83 +102700 000000000000b873826e93b80fc37f0ab20935eccba9fc3acc9c2b37fb1dfcfa 5ac43f0b1214a290ab386adac7e66f72b158f1e668ed27c806a517d18b6118a8 000000000000f0972d37405fd285392729237bc03887f54adddc8a65760282a1 +102800 0000000000034b7802c38fda9c89f2bfd97bd9c7717a78a67b3c4bec144ead2f 26b12dac15b05843aa89d3730bc4b5ce462c47f8530f58d5e25cd32f9081e31b 000000000002270403abce8462ef2d6443d6919208a97695a9dfa7b394f559f8 +102900 000000000000d34b432ed7d89f0d5301df0d6c75e6de6b43dad9eced97e89ed8 55f5c8f4f764332784916777ab2720157bc367b2f14bcf9d60bf4c8ef8ae48eb 00000000000185237c68d60b70995687fa1459008f60c25f85b7a5e38a5a56ce +103000 000000000002de7f6fb9d9b6c03d948a26f31922738b87a658489bd800bcb17d 6e29c431672c85d5b70b62145f56ce39110746f134f013c7733c4e438dfcc203 000000000000fe53268d70885be56629754ee905e4632cc22839a05b8cfb0e13 +103100 0000000000004b72786dd2028ffa619b0f6f61500dab6545db34e937c1728824 4720e9c8d84d9870187821f9f89492cabe74282d8a92f780c4fc0f73c0eee5d4 00000000000140ea558deae9c0bc15e167999cb1c194ca9a737b3756e9b5a143 +103200 000000000000750f2e63c327d0eca76c7aabfdbaa22332f75f29b611579e0e78 0d20e24c193026b2f26ce13297b8f8f2a47004aab5aa1752b88324ea5eceb5f3 0000000000016b2d05ec650864cc89f4050f9f3722224bf06852fedd89e6ed78 +103300 0000000000009838e8036339fd1a778edb35146a0029ef14e31744a21e5d0c61 e735532c01a123a6823dc1dfdd61053e3e877fdea728c68f7a77b48f3c034721 0000000000014be4ba97c1100ef4e26ae69631df6415bc403998d685261229d5 +103400 00000000000202f17de6dfa4e4072dd0daec2693e2c98ea603f2e0dfd32c7de5 7bb948a919c2edc11d67ff47052fc166736794f073799a389edfc50b97ed39c5 00000000000274faa7b067dffcedb4e638b819b8f5aecd6253a88e8e7f3f781f +103500 0000000000029b924435f3e38195c9127a3180fce6b799d99957b7143f9f9ade 7343e40abbc2d03fd5a422022d4a5e5853be489bb3050f296c4f0fe2ee122a9a 000000000000d4b1f1a3d112925dddf69010d11468226f793b0780dc9c9eeb4c +103600 000000000001e92bc8c52d9023f7c338bb8f087bdfffcceeb132ea5221852a8d 2212dc253aaa9489a19d017309fd0728539007265ff8d4817821adc251e2b64f 000000000001e52653d5f7bb4483ed72bc9e36c9dfc461b489a74605e9e83b55 +103700 0000000000012b37740f9ef79d821e9d88312c677765a00905046b42cf8d142f c0c90264b1e68cf72d4c32c73ee06ad2b25212d1e7b16065bf3976dc2dd25b5b 000000000000bc9beeefb24da3181c661551c57b19ae7faaedb42805a5534310 +103800 000000000002c0fb904c4b769816dcc8ecba468f1b48852621ddc299fb07ae18 8d87ffa7e50060f335935cc6fdf91c4176e8a97ae6f8a272d42c29995f6210e8 0000000000017bf13e668c766e2cce3594ee5602834769429eb5fd27aff994fc +103900 000000000001121df0d4c7573f19f1ad443f4411f9d245a155180c5c9938408c e77fbd3af1060d684d8959321862ce17a0a9bd1d9fb19fb2f58a6c084c82e330 0000000000028bdc28e844e35a1322b4962a7b3e31645202ec4bbc84efe80a09 +104000 000000000000a9887c91956b638bb3c0651321fdb24715354c3fc6633f5a16a3 a8d786b52025f7bf6a43b3f348ca1f819187a01c1e4911d418e726630464da32 000000000002a850bc55fe565089f1631752e487d23e1e83f33dfecd12ae3ae5 +104100 0000000000007d5087d7620c50584917de5eb2af159f95b17296e2993706d6e0 baa69fc226a536fc93bccdfde73dfdbd84679484155c60485ade8f4d0b7ed2f7 00000000000348d89c1e4a95ceea4fff1342ce30d7d3681bc24e1f22c5340cee +104200 000000000001132b073be91470eb64f5f2256a8472d142d77b5242e2031811e9 fe7af8f0d222cb5bee2ebaa1484244b9db2476b09e8491b8298d0b9bc0bd28ad 000000000003795f51ba24de6d49cae7d361fa5c64aa64cb8e86a28e985428cb +104300 0000000000007508eec44c56480dc0bcb2d55e754e7f09aa090987839c73874d 5c7d247048d2937b11e747604c9e9ee666c457f5480cd4bf53668fb7c08b2029 000000000003171818aff2c702accb7dad2438db83d5731d7153cd777b681eb5 +104400 00000000000184ce92788c9e30e705c2cbfa37666c7b633b3de51356331cda22 8faf861bce631a605a98522ca69f06c25a93d27c4bf9faf904e332c56e019839 0000000000007f6db3e3d70433f4fb1e883100ea07e3f891391e095b12ccdf46 +104500 0000000000035c81effe425e21dd20e7e72763bf453774634463c4a97f56f090 be260dd9b2c2b4da2822db12c204951b86cd6a9a8bb7b8902bcff99b72af78fb 0000000000027da6cb3ecdfbad2300b4f5eafe1d15511941f2dc765d72dd5c13 +104600 0000000000011223f1011251cd95d922f2dbf617e029c5e24882e65920526d35 0dbf72a7f049bbeeb23c228d3cadd2c0a6633f0cc8b9aa6a22880b45efe12821 0000000000013552114a6947189785eb8f337a09cd186d2e0755ca098e1a47b3 +104700 0000000000022b109e161a0912aecc58fe5ef31e99109766dd79b7138566b0cb 56012359a16141f2b717a5ea58d377f011854896b2d141782a857124fc8beb71 000000000001a72e68ebadbad2ab6015ced1c8edd9531c50ad0cdd7ed8c7d77a +104800 00000000000364c80474c15901e99ce58755dcf212081c4ac767875dfc55510b a9ee02c7b5842430a7580234a8e6c67be38a1ec26bdb73b3076a94699791647f 000000000001bdb0c01b68e58464a112132017c0b55219934d6abf663dc6e461 +104900 000000000002ba5656425eadf3e1a022b7f313244958d5cc8aeff8647760c2c6 f313c29d56cc010a3b3bc4321cb4e84d50f34c61e5d3c93f6bd59301850c4c54 0000000000010fd2c2b4fb23c44319e01754dffb1aa398f1d5c3f9ae4ab04741 +105000 00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97 c1a09bb68266a17559f6c04d8ce6d00f753d11b2234637faac65fa76dc0e887d 000000000000265dad8db0728e318aabd0098e69a82984f8c1c5b9d55de5fd9a +105100 00000000000195d7010f816400580628f61f723391147f93383a17c45c1fa79d 71314554fefea2461691b12b161881e6ca7ae28b5f1aedd47337b7f8d173386c 00000000000178bb15c014c55085e79b8b530cd3c6e3d447f0c65bc0cb181d07 +105200 0000000000017b9e2efa53fbabf847bf0cd4a5f3b420087ee43c42130aa9be71 959df82e258bdca91a3d6a4e611e8477eb04f70cc442a5f1814acf1fa812c05d 0000000000010e4ffa7f6539498b4a5b072637105ae2e93e4c06c9d8c9c74d9c +105300 0000000000025eb91ef04637e2b3c9e76e3327161f15a94bbe8d019745bd57db ba9456fd2aefd8a7c2ad03fb91a0efd4eab5a28febee895908c4e5d0e6ca3024 00000000000219f7100d60d007deb58512d12e36528917a2cffb9ddd07dec38a +105400 00000000000142257802d654804fb42e8262baef9705a772947b0449f6d155c6 30cec7361aef6002fa7246b6c6161978ccf74a2e2bb5adfa458aa86229c6544c 0000000000004ee81863aeb5fa976253760280abb41ef95dfb0491c5a9869229 +105500 000000000000609f51f48f4eddec43b358b3189615201314b5c6113c6327e9ad e95a1743504244b1faf2595807fca8ba4d55e296747e907e3d05df33a02993e0 000000000000c6906639ec39070bb26bd94c355709f098c40c9713094e861f31 +105600 000000000000235e6e18398a65cf3b46ef7654a2bcbc135fd5666b96af5e561e a30403302e74692394c93b96d04177c7c988b0825c63ac590a1b56e51d840c09 0000000000006f88c4e8f766cf5ecddaf40caa9d9e18fd898d1a9a82e2520273 +105700 000000000001ea69eee95c5adb7e40e2ec8347d0889a98679820448d85a173a5 a73ea3814b1b24c08c93b3a6a229b91e90cd77b00661b7a1de7c08ef6023b84d 000000000002ccdd70fbe2557e73811d67e4ac361db522d8eadaf84c9e624e99 +105800 0000000000020bf196bc3926d908b66dd8a163a0aa58ce4e54fb56197ab42780 706859dbff5a651194db7b6182880ac7d9411ac9e94fbff59f1f5e647250fb51 000000000002e7ac242af582a23cbe491e800920d608b4a343279178d77320b6 +105900 000000000000d270aa6ed1efc4d6593135f1425a9593e3eced349cf1f8bb61bf e17ea8fc0e04cdac3c1bb955a2df875e147c7b61d17603c97a3fe658521d7597 00000000000187e7918ad99d3d080879225ecdd0e9c46e97dd10b7e25dbd3557 +106000 00000000000058d919f52d255f394ed0aa3a344432676fd30f1aab4e10c22fad b4108285ae85f4944a378709637db38a3e37730a06078467f84454c3df36e41b 0000000000009c097e197c7b517d36483026639676b01c14fcd681721721d300 +106100 0000000000005bdfd3c348886085bb62523db7766e81cdcafd3b6752790ae7db 61300c9081ae76073fc3b2e29eda2ea263c126aedd2557181da260d7c3ae3d80 000000000001564b4f67c51e6d244ee19bf32de4342673554fc10bc6139f979b +106200 000000000001b698157e0937bbd3e8fd2c91577c8c4bad7f2901540fb4d94b6c be75b22fc1d4140ce48f3bb894985b93a3795e98e90d192c34b563029b0a133e 000000000001515c427bf4a56f18c35bf1c373e5e33e6936c8585a9daedc7813 +106300 0000000000004f0b6c4879732db537ca1e16db63ddcf058e22b939159c44bc51 785cc0961124ceda2aa8489e6c66da5e5fc5803088cd007d101a66fda5bfc3a6 000000000001e84ad99877a93aa5e4d0de0ef5cafb55788113f934f0b7f4cc8f +106400 0000000000012926659abb4419ad6e09a8b3cfbb66564cda9513728a24c9fe3e e6912e70d4af69b8eb663400dbde6c1beb864d40745f28cc62e3f1155ed744ac 000000000000defae36477f12511b6f1aafd8cb6e7c6714655dd92370cfd6485 +106500 000000000002817c28eb34e66326a20097525a5519a7bfbe9ada86a0285e2532 7bb992569e94d966e04a2dba041dbf8041b0e348963887e22e791db940759da4 000000000002f26df0c8c260b2b147519b1098ca06cc00df83a9cff032e1a3f6 +106600 0000000000025da1e6bbe37ab44c2e6cb0a7ffb1e4881a488457ece0dd3e5c99 1c52e72f7fbdbc6dcb81b34da49f449cd3090c346616a6b8a17b169258cdf4b3 0000000000023de9e73c2b6d9d20d68bfbed2e57f297e8731233233265d35492 +106700 000000000001c9f1738adc21f1fc902b5a1a6e72114d2f3d655cc86843d0884f b745b1d2a1d3ae6e5e9409a9cb2918920a489b54d0e0efa6d84ba0d2049d949d 000000000002d845374463185cc07ccb10da17d14ca1ed6cbd2979a43ea30104 +106800 000000000002e2cc082d925dfb198384f2d2f01096c81128262f281fd9c76ebd 2dfe80e34f5889b09f8c7ef4e9d686fad7414a857f1f56049438ae8fbdb5dbb5 0000000000009f65ab9e5e2a04965aeb461b0613f81d073e771570f44d3a6d62 +106900 000000000000bf66e5c7943dad9b31db5637b552cb37086ee2daea96c2751564 dfda46116d0ee773f4b5e6ae0426f7c91af23019a17e725401f9ef86a6876e0a 00000000000033a13a421ac3aff5fcbb1646b780a27d8cc865c87646f19f3362 +107000 000000000000a29d57f3c6c6696e84d21de79463b7bf85a6ccfac39438291d64 7425797248113495a572578c7db249d2b50b5a1bc543ec5553e7aecf3f9f6135 00000000000011522adaa3df3983082e86c0335a2c4a6a3a68f2d138a6256179 +107100 000000000000db9415e1a515894bf33d4f2523b05055bedf2087093cb6459125 cc3205646469baa82506d0bd6fe1c290e29c5d1f867e72df6baa92c61f91e8ad 000000000001bf08cefd7791ca1be81d9eddf9ed76b3f7cbd243247624d8bedf +107200 0000000000006cb76e3a797d0ab761152157f850bba0153aa7ace105ce2405dc b04133767322877835d2d6704c72c22a93176cc27a5d8af8291fd59dcf3294c6 00000000000211e3225c14078768615f7fcab1495ddb08f150984ab1a357cdd6 +107300 0000000000009cccb35a15e8a0c31d64fcffa95967ad2b3c0c9d87822c5f1e3a 02b885777c85e0b6b224938c834eb652767b8e9afbb3f38a15463befdb36325e 0000000000001d85d1726e763ce7ba8f84ee524833e5c0a5b557f3809b832730 +107400 00000000000243a5b10a7d217fd4c259ffbd5a51f4c435f3a1fb5583395b82e1 ae05c6671c3aba1cb4c1ab6354781cf1e2835cac1617ff3c990d98bef1c22ad6 0000000000014e10863b102097920d6e6baf0c45bb3564cd6f0827022897849a +107500 000000000000f0c2f8dd90080a80efa50ba21ae650d17908f02c4234095f5c67 a152ea5dd62f1aa1986f23a59b2182758e6b57f806e2f4fe59851314d4df5013 0000000000005e7c81f6f4c5a97c651afa1190b4401ef7d2e0f1d3a27879d3a6 +107600 000000000001a4fadf39731a5228d5add914ba612f92f3ae10ad4b62a8dcfe6a be7d5d1e7bae79af71190a6a53288ce92ab001dbd45d6c0c84dc29a64672cbce 0000000000026295a730cabaff69331ae5ce345526f1592b228e8ec0bea86f20 +107700 0000000000013e5f48f23c023a58eb054491ff890710edbb41830681a8e3ef6b 8a6246ec3c7688a0385c42b8ce856a649a54f792586e2d5c52b756961471f86c 0000000000024f4be7fe142a2610ff765580dee0c3f760589f1dedb2925940b6 +107800 000000000000d5e381be9fa4fee09d6b3526d24d0e321e7b34600cb8a492fdd9 7017e9429d83004f2c3dcb64d13b58f462d8124b5bf8b7046eeab93b5232ca83 00000000000133cc49e74d7974361f3368e4438c5ebb4db73cb34f1d8cc91e59 +107900 0000000000005bfecc74d81a63a82b971425a2c54cba8ebc60567662bb8bfa21 e66d6c76bbcc58007e62c2ba3ab9bf1fd4ac3d20ee3b6dd267d89fd664a9de1e 0000000000018a46f201ece4ca8f04a4e9d042e2d6d128b5cdcb2e78f87cded5 +108000 00000000000167cea0b43ff7ce22f330d3e302832187eb31c61b15bb1511e118 fedb44e8873ddedd6b4c354a3e788b9405e76e205403d949e2d5957acef92f7e 000000000001110a03b89e33a6c0d71f89319cc1215997406bbc74ed9a6b12f4 +108100 00000000000217a8b9074995bc33a2d9ec42181bc934da244f8c4db9babbe64b cfe3c78df6850f1f2c7406332b52e0cabdae0bd1e03b42625b228f80da0390bd 0000000000017ecba4f4e1a0d05e80683f29835f90c4db3b01024956ad1dec60 +108200 000000000002392439cc95d0d387542051e00788a758a8a64a0195ce469e8600 81f2163fd1e38c76f9a174461781982fc8cbc8bad61282aec42974d28b8d9b1b 00000000000085822372f66a0b168ed5d1135bf01c1296a645b2deb9336289d8 +108300 000000000001a7d94230aac603bd9e62ff15045270f327cd880a3a181e976b06 e02f8d50757339deef7aa14193842d132a1c1d845abdc7397b5fd993c3292bd3 000000000000afb8d5436811dbef25708923b3e76b8cd563a4f13fe590e9a4e3 +108400 000000000000c19f9adc07014fa635b58b4b537386adeeab8ba6e22f7893517a 5c563a49a52b345f22e6b7119897513ab8c9e4ef4d62db587e7973a33a3e0909 000000000000a9ea3293f5c6f9f8ee9911650a47dca77e1a3273ccf215242d62 +108500 00000000000132bde8508b955fa1748e859575610abe3394c9f20bbd8157aca1 8527905e7383681b5e0c3e4abada91f84ca22c0fc61ba9c7b9281af17cfb90b6 000000000001817110497985dabbf8fad648cd4a12e43da7d641778fac766b52 +108600 00000000000227698dc4e40b953291b216d2b602fbe6fe0c30f0bb5ad498facb 6713cd4a2146336bed73f613ba684c7e633734c768b6d6773a84fb9d15f6e7b7 0000000000004b2fc3db027663dd073fd2d482817fddca33612d653c140261f9 +108700 00000000000108c560520dac4c9cac0504173efad2112497ac8243f9715264fb ebead7f6b36df9b660fca3103708b014fefcd0e923fa8c22963461e86be10187 00000000000166832f829e5232ba7a0d6a0de8ea5c855353e3f40c56ccdcdad4 +108800 000000000000095a06781ce51be66d6af12db28b41a129fb79c6c6cfd4051bbf c9a40595c5871fbb402f5063fb49070b5f9e4176089b489e51ed2bac2ac5a1dd 00000000000082e3092afe9f04474b6ef2922e5d3967e039d5a382a3bd12337b +108900 000000000000c5eaf935144b7ca54558339b17ab60d02ed007b056413513c0d0 8fa6a95ec4e9dc956afa0ca23cdce010f7971428de8f93898c17f6d1038328c3 0000000000012873306a8d410562d88fd26dcf5c60e7ca6eef7f1b7190eb7634 +109000 0000000000018ae5c97cf968e269afe18f15c6cbaff0beff192126401dedb634 56ea190219cd4b751078cd99a768a8f2c05fbc85712a8df408c2f47b713eccde 0000000000008d32d93218ab539f9f32a0ee12b163ef9d290a98217aee356ba2 +109100 0000000000007cd23b6cb9c29335ef6908c110cf221cce587c8bd7837ab6b117 fc69385980420ffa7e4ab914a0ec1d0b87c3a3cd4c33242ab820013ccfe75c21 000000000001599f1a7e7b91d6d948d94f6f6726686fdb581b29e8f60705b320 +109200 000000000001a5777b278af02a4f038c4a0446e8a2607ccce48dd92f17ba95ca 179636ae961075c98fd8882586b71308a8367b8da909e5ed531e88acdf67fbd2 00000000000175255d43a679c43a967e710e4095a0d531ed8ce28bce7d423626 +109300 000000000000523dcedfda7151227700edde4fd45ad225ad4bd95b9aace14627 45534a26486a99be458b0994defaddec04011cec08b8996ace8a51a5f7cb2339 000000000000c88e307a56c84266402c7a8fb1200d1fde13e73b94e735ef54c4 +109400 0000000000014ea4c61775674d689285f4d92877cf2123bd8c139a4235d7ddd7 73b956c515357e93818a186fe98cb0bacfdeb97cc78f2e921e74e39b9129a9c5 0000000000002bc3ee7d655108ee549184e6010b3df190a0414042544fb2af40 +109500 000000000000fb46bc4eee320a845a1e366b50d376c79b42920055d5bb7ae079 f91f4e95c7210d125ecd0c58908cfe9e6f495967096e06f9012f4d19b30d54a4 0000000000016c4f471b4372b939c11c27793b8bd3420fffa63872a841d490f7 +109600 0000000000019079d8999a42b26a79dd1e959cb16010b2409a997067e305e103 96dcf5dc7630fbbdf64ff09390214e7438395b8896d675ca2c9a1e83d2eaa418 000000000001bfd341793843c81080da2f866679795fed5abb0ef9c35c544cff +109700 000000000000d9a3651fa7a6c9af737eb32165fde7f1c07a75d5b04c6eaa060c 13b11ee81a5609f3cef7e92271767ef78f0f82011778fbebff348a2bb7672a0d 000000000000778f995ad9c481edf583b3b956c5719b0d8a812e4601c4f7e65b +109800 00000000000169d885a65c6b3e18887fbc04eef4c67029f5a49f70c2bc9b5ecd 28667af3d88cdade0ac1d4afffbc6a1173ae636626eaad1e2da47ea036cf55d2 000000000000b58c6c1a639b0ee472a39d46161eb46de713f0dab462e067069d +109900 000000000000464cdd0ad30e6b9e73edb605f2ad7dc693fa2c391852cf1220e0 87f738bde271591523b61f302dc73101bd68f3b1a1ed5e8f3e070a9221d5997e 000000000000039b1fc2f76a47566f072da93c3f3d793d47a7e538ac06c31b96 +110000 000000000001bbda3f22ef8e476b470a2d3ae16821c23a6d22db77318d0799a9 f41b84badad5b09ee331d46be2c84039d9ac8f6eb741815e922e242d298ce32e 0000000000018d067c617c2e262e544bae4807e413122b1f4814077a15ac57c6 +110100 000000000000a1b1785c2ff02491d8a3d170c376f2a11deae182e169aadfc040 4059805d9c5bb371f4c345309a7444668efec14244d4a16cecea8f21ee282db6 00000000000121fe495d004ceba6ec5f4ed809e35f76856cd5d557400058f373 +110200 000000000001bd107380753987a4849bc2cb6dc3ded85660faac835ee70358aa 0f998d7086417817783d16e00e9a726ec512ef37a739a9e09f8756104f1a67f8 000000000000fc45cb881982702983d733181063d5506101b3c76e48fdc92250 +110300 000000000000b8c3ad583c44e2655f5384f3e4e6a1f2a932b512ecc69a07cc24 1beb6c92df10967ec14c7ce946d4df3738ff0e0504659870a440fbdccb8555cb 000000000000e1882a4d9b13215fb5f1ae8cd68276f622642b53ae9afb83171c +110400 000000000001133ef720a8d9162b2fed76dd79f99894b9a46b905f5b26b28165 8c74b808b4c927068bf3722470e7fd7d3caded3b2499c74fe148c281604d9c28 00000000000096fe90cd3e46dd98a5f193a6b5133a7d7fabcbb2aca82a308fb6 +110500 000000000001b4f0587cc2e31d3ff2c63d7cf6c1804fadafd2122d54591aaf80 10cf6f525dc1d1ab98e90d5ab6acbb9aff250686c62c14801a41618b89b32ad9 00000000000000240b044a3090d3ae4f9b342a840640240304eaa8f68a0fa1bc +110600 000000000000b7de0674d4b84c46be7c477b4f5c7342ab791d37f1f597a384b7 5689db815bb4df5dafaa78e1872a6482fda0b0918ee87169baa14cde90b1da4f 00000000000084bcca63cbd092e361a3c490a71c6ead2cbac64d125e90afbe2d +110700 0000000000015c262b3d8ae4de41504806abe2ec4f463e0a8d614819c1fcf942 be1dcb219198a28fdd4d132081930907962e3758c8d2c22253d30901ce8a03d7 000000000000811e0ee203caa4a8c99acb3d5d9608ebb4e9c8586f5628469837 +110800 000000000001179e32e2bd0410719f4773a7dd4b4bd4fad930ccadffd5b15676 0e88bc1970d5271430200360f283835f15518b9c3cc751d88d144c04dc9e0a6e 000000000001b0ee0d6dfb9f33eca6235298ea0f36ee1cd39b812da9f425465d +110900 000000000000c41f464f38f9aed166a79905d08183997686675b0b5d41a9fab6 e44592715f93410d50b8db8bc8dfd733b7d004a0ddacbdfa0b75c5d3a74ac02b 000000000000c726e0e38b7c05e9bf451c71d3faec3a86bee942d4101991c932 +111000 0000000000011a7786add1f89b77bbb9a50077e982b4fb6f9a706674a71b9735 e433b5d7b3c9a69e0ee0600db67c5c7d4dd82bf3f3599c3dbe9bc90dea0f6ca3 00000000000106c23c5643031af3c968d4cd5b54f07e01bf65ddec49ec6ed171 +111100 000000000000a2ca227196cce920d903f291747c087cca11735e42f754e3ebed c3910192b546ef19aa4a008a700087e948fb7a291fc5944fc8e6546d2e3adbb9 0000000000012698ae25ef08286eb8625c735424c7ddaeb13fb145db1f137dad +111200 0000000000011e6d83fbc9dabe9100ed8f30df1a9adea8a994f6338d90857a9e 608d4efa3281040a9a0194901423ce9f741ab7d3a2c754c62679977615188ed9 0000000000008b922cba4c060c348ca35bac1cc85e175486db9418c1cc54f2b3 +111300 000000000000d82aa19655c485a9a68f27455518d2153e71b3cac2dcb1c78b54 df5eaa66e232cee961fe4e8a968f71809457a6ae53f88784a5e611b50533a755 0000000000003f6f3b858f6a5768c568f8179697e33f21732e706c0f3c794e13 +111400 000000000000ae56d35b98df16754c1ef687c920b05b52ccc7807b515ede7915 0166c7eddc181f7fa8338ce9b40c3200c4e3c9ed23740a7a066fb781e8c7e677 000000000000d114d32e785d8b680bc11a764af0b01ef0da43b70bf3b6cc12fe +111500 0000000000006ea9a415fd1c4850f27d4b9460e10feb9598ea2f577a188fdaa1 70e6a3c317d5513af33ae8e60102fa4bd9273d62e9bfab8875aafbddc84f93f6 0000000000008e43fbb7feccccc557b5074e0b8ee2df72507b72fe2959523b9d +111600 0000000000008f7825915679ef59f89c47a519e1399565271d5f47ac3c74c6ca 7ba762eba2a78b6d8fd49ce03455c5b8be3b5228d77aa1da90be6bd656ad605e 0000000000002806dfac4e81be103d725a2206b004f58f7220a83d7ee41b89ca +111700 0000000000007c2247a85a2bb7f65b5d4834c0df0d0907d9e4dd11eb098af3a3 de90808c147a4e2a2dae8fb146dd5d342763ac8cd97d99b0ef9bb28b0a0a6cf2 000000000000b5533053abcf62d1d3d79e7e13fba840bd6d697290bd7fe15b28 +111800 000000000000c22b96e1840b7b47585f2954817c147cbf194f2fa578ba43a20e 079398b4203a8589e72ebe274d45c8af2bd8adb7837db9bf67482608ee2cdeaa 000000000000f9345fb9dd3b4acfccbd8365daa816a6fd6db6da4d23c6d4ce99 +111900 00000000000031f0fe681879d1128c556e2a8cdca16ef796fbb855760a466284 0e24202010abfb14f65e0a9917d77ac03a10861452e3b2d943e1bf7a46af478d 00000000000090b9068c72a51522b2a1e06166b79fbd7146db402a53443965f4 +112000 0000000000001d69b3899a49f37799c375a7471829953d5470f468f48ff70432 32071a3970ee45028b3fb443462c54fc3b4f94c14e23994ad446d495c3e237eb 000000000001035d056c81d4edbdb2763e40739fd0b2f9cfa06f657299f4f66e +112100 00000000000085b2a8a700a118628a907e81c2fd8886ae9176fcf605d8149560 e5e2e9800eb51d020f09a36035fbb10bc9bc2d608c1d6300578a2949a9a3b062 00000000000051cb98cefa08793c82793250912ea8e584a135b6843513af9605 +112200 000000000000723f7b514cb48f8f2bb4f24ae054837693844693979d7abd7481 628ba510c931563cbf5832a3e9856620e5ac20f4394bbe75a52c55b2f282bcb9 0000000000012c570dbd5721ad6943b49115cec83a197782e2ed072aea6bb1df +112300 000000000000e9b7a2d2a0b26a662469d414d0ce16f746c02902fc1773970746 226dbc7f3b508f247a615f4c360cca8e739774ef454ee407cac1327a1d8ae992 000000000000176933d4b8f405372f3a6f5260eb031c010507777f9c74e3176f +112400 000000000000bd01b8c2832cf69064a660ec2b9760b66ca5a670b96facf5e017 01539a4fb323a487c3d2246abc19e7cc6d4bfbf91838e6e9a1e35aaedb4a1dee 000000000000b7201af58b0479fb01b8ae5f9226e245fee7454d50e6c249ac1e +112500 0000000000006322f9774ed2ac87a61189f9d16bb13dc1e9dd95516a44e59863 6026e946a82d0d30c5569109797c27b69d9cb476e7c3da9fecbdb1ec52724403 0000000000002b564b3f6d4542703aee13fecf7ad8c176dc1be3783ca5688a4c +112600 000000000000bd42b923050c7c79944b2338fa2e32c2c56bcc7f75f378ba2420 2666f2ef582327808f733542f01c5bab43abed838156cb781f9fbca746f033d1 0000000000000cbe8601a082a4dff349ede3c08bbb5e152ca1775b692084710e +112700 0000000000010ffc1c7aaeb79f576d30782547725a5eb9b78731f604c9fb24b6 8159c94f3b41ec8f0e15afbe43d27363956f72f0c36ff4ae604a2a4c9918905c 0000000000005b739573e152b8ba1e311f0f1cdc5dcbe9487b82dcf07126928c +112800 0000000000001a89ec756daa7751c9c5af672141f7923d92bb12d3febeeded1c 4948c3e0480236dd43fbcf615022aafc522ba1d593a9ab6e503603f8d6c97c85 000000000000ebfeede77d5e888d4b3942803177553f4cb037357f2b5d74452d +112900 0000000000007742c0f9d2a36fde1adab08d922d8b42bfaef29044b89d5ce652 b5798254dfcd026109ac4400f71807c17609557f8a997be7c913cfdd7d56eaeb 000000000000205eb144cac7a02c9ebafc3b5caec6ca995d975a18a948994f25 +113000 00000000000032775da8b166cac99dba6685a5b582216bd94da0a820c07aa3a4 f8bf51e0ab8202b8518ed2a7575f26916f19846d43ff9cbff07f306e08292a04 000000000000182ebfbfd8ba68597ddeecb158b443dd71b488f6e37086e9dd9e +113100 00000000000076168ca958193e0b5a901cf0c37331e2073476119326211b70fd fee238526f5ca2a631538da91adf1f56b0b8fbb25131212b844f713911aa9a42 0000000000002076fd4bd9d04cb61f7f8d28cfa56c76e30b7d1433b2ac6e24e8 +113200 0000000000003d0367477f9d22b93f4d4678c8767437096829a15c7738852a37 6e838bfc3dcc701eb1f0972232a61b4cd67410d786818c556062a7ffaa57eab7 0000000000006528a2053c6c065b1d7ab4ffa8834556114a8c7792f52b4a283b +113300 00000000000005acb2285e4c101848bf631382229f10a5ec5e15033c166d40d8 d803d809975fc4a8c9156d6a1026ba0c09536714fdae9e9ca9c29df4766709a8 0000000000009d9d4f427d0d66edf84c0edc8c61ef5b694cd3823c7ee42c8599 +113400 000000000000d67bf18376b5afc0a5039d6ef28ce169dc173db27a7e88666f5b fd6c801e65cd0a34320104875c6ba08349e72bc523181e706516cb25b5a8d2b0 000000000000d00b85f5bf8480006012a6ec6705bc5a34a8038fba8897499083 +113500 00000000000019cca398fe0a4d6d4fffb2396596d4866b933971b4c16b5bfddb 92d2fb1fe4d1eea279952ee42f875d87c6d83b64384ce654281913d131153341 0000000000004e6835531fec9a386cdb446fb5becdb6ccb9d09431afcef8f937 +113600 0000000000003292bf54dfb86f2eef66367a77e026e40c908ee1081e895e6092 d24cd3edf1cd139b3692eebd33a100d8048865cdf6cfe7e008a2c310561232b9 0000000000007c1c37d3b2add4c272c443896083bb2bfa9f149005607ef7f536 +113700 000000000000cf24be17ea96f71558543cb5bbb0900a2c29a49dd0981b0ce68f 1e636b3cf203e383e3bc12e36b5fd488343870a38d88a59662c50bcb96f73589 0000000000003023387d50fc07d9981508557de8cc71a5070ded5d9d8809d80b +113800 000000000000adba836a98aa287d5503dd3ecd84249f507c7bf885c99f548322 dbdeadc390095646214a5064050e9d6933bc3e68e8f839a91cce96b2778dd402 0000000000007f004f15982f61db7956c3a5db647dbedbc3993a33ade9fb59ad +113900 000000000000c10ae722e371838c71557782b854a0afff3b77515db7f468f232 0d9c88b08a5c389b037677c7dacfe4f427dcd03b9d2a66a42b4ff78167f1c8a8 00000000000053e166af69013dad7639aebc88c25ef76f0864ab5c193543c2c3 +114000 0000000000003195a1e6dc48a540264d37e9ef79b552bd78ea4b93a3b6e7e449 c52e73b5721777a5c47163763504404977f21ffbb314775fbefddd4187e332a9 00000000000086f38ecc2a8f8dff3bb9e1a2a642e965d4ad84e5c00e8cb7847c +114100 000000000000335127a847f489d76b0f3d1947f765e7eddfcc46b2ee6d4ea040 f29564f78efccbb96090e5aeb6f3381940faa0c8720cfb4d063c11ce2614e8c4 000000000000b46f3c47b337e8b5488660f9e96d1810d0f8acca0b9d18b140ca +114200 00000000000058dc07cd2b7ecca3f024a03b20db3ed806a592028e76cafebf69 328b1e134947b67c5e3d1b8adb1360e2c1f0e40767137293821bd4c9a0570118 000000000000a15473f12eae7165df7a0531bba908cc5f5598a8465790894659 +114300 000000000000819b7f5ddc6c8b6378f209f0eeb317afe23e5f29fbe6d775a85d 9d54307d1a7afba994bf4d8021c554e5eea8071ce43c884218e81ffe5cb9ff49 0000000000002eb20f09b5cc6ea488c63e0a785dbbbee068189f57d6a60d0568 +114400 0000000000003c5f83c5d5265ae0904d84067eef09de7424f3747248980df77e 517417887de30bae80081f585ab38438f57ae4460db7b2525a436b6e58ce19b7 0000000000009ac540ac6db87f0e9958920512d2c37a571cb9c9936313398945 +114500 0000000000001e52cd561bf2ed0c2e64df51166da412bbbb78f9b4bbea00c3d2 ecf42d0f787ce7e790ea2aa1d05ab1afa793546c58785b608fcfa7ca61b1d060 0000000000008f3fd2f1b0849a1582c9d64d0b6a5fe2da51469463f3f81b076a +114600 00000000000092c47035291dc77faf10a8b928f44824017de73ef68aba3aba7f 55453246c329d1b60d9564af83acffcda59092310177f94bd259e607eee4ffc0 0000000000005d61456f99bd118b16c0ec6be2d61290d01658d1a10d88eff4d0 +114700 000000000000803d87f7aaf80a57a57aa5eeb52828a06be5adf2509fa252aa10 f58b866ebb0aa1d4c0404645126e550fefe29ace3cc5eca0ee9fb1a0ea4a4c3e 000000000000d75107521c9c90a1e75e273af700b6dc0922a5f661638c8772b2 +114800 0000000000004036d7ad29f775eae9e18f6cc9d282d329ff029f9072f4589662 aa1c1216616a2c5afeed4b6ee295b8709121770e08ac44cbdeb1f5dd3ff5885d 000000000000b40ba8b97da1775094c718e5e7e04440e70f8b8f1df5bc2702ee +114900 0000000000005dccc0048b232409d130c45e29170c2a3bb9503676e7171078b5 a7120be2a897898eedfe65f4dd5aec3d8ef4186e283a0cea55ed0afa17b228e6 000000000000a31ec1ea4c5d9e6e4f6573e37a97dd3db52c76f1ea3c7c587edd +115000 000000000000e58392f3b59350e72cdaa81655460a0bd5547319522702799993 1e1d7fa42296a12ebdcfb037d15f1201f63964683158b87406312f6b85b7b7dd 0000000000007f51a1c13814ecb9698f56b91b2599552d7c47ec1d5b7517ae81 +115100 0000000000003ffec6472ca2f3b58f9d5dfd8e3e0b8a7686b8dafa1a311ac7c0 0f3686ca502f668e2744530000c77da12dbc6e6f657e373b75856f4485e54a45 000000000000a686807f7193607e95c7df037ad6e952a05345d7a493e5571d41 +115200 000000000000bd862ceedf1ddd92764bd91ba4bb06f36f7dd7a7c5694ba4a6b2 8dcf36906bde6fea9afd3f93c5e8e60bf3c2fcf9951ae01a238656fd48597cbb 000000000000138929d184a14f679bfbe1efe35bb9931c5f96a8efee22276a72 +115300 0000000000003fd0733f93db3e13f53ca668d5ea8bf3bb69befba5b1185514c7 5034bb50974c0807fd84bf093808797361837e7e8d42ac74842a58a47f208085 0000000000007510fe781531d402a82fc8675d805ff26145eb2679781698a749 +115400 00000000000058b47d2d8fd306883a1f5ae16b6205276acd26e64a3ee273fa6c d3bc79c1b2ea134d87ae5dda2100adff33ef6cabaa576ba7518f506fe21dad1b 00000000000037b268a9dfcc2a6f1e8e5b00b6339285c4dfeba28db0dcc68206 +115500 000000000000d3b249606ff59a26d258141687d3a88a1d6362ca7196b0587e82 b5b0662229d612a0b045a8e1abdb3de9aacfbad7afda61573fab6af0d4e38bcf 0000000000009b59980ae6c310d53fb2a99226f4ea8ee0f881756c5249652fac +115600 000000000000bd47eb600d6d8adb5b9c42d01ed0fbfd3a6f2eaa6879c6ff1e1a d257986a7fda294d9ca271fd1b58092dca4284341de482e84923e8c9d509f9a2 0000000000005712d89c405e32674098df539c2f038d5c7a3f92d5fc0d68bb9b +115700 0000000000004628761bb22fa5871afedd661c802395185de13488c26f5790eb 863eaedf0e19b44bc93b51816768a571a711d90a00dbb234bd4507d7ec75b963 00000000000092494e8890e43b6355d5a3438265bd190284358a853cd3275447 +115800 0000000000009964c4c46022d9787c6cc6947d03f098e98c60e5fd399517688f 4b0ef11dda23af8520be16a8fe541349bdae3ba1b46bedd656109ee708eea28b 0000000000008f93b2efac1cc32cb766badd66df4e92ab61179582dba26cded0 +115900 000000000000479a4ce82b5912b52b5a7933eefe46e72b8041a99cfb20019746 3300ee91ae66c8e3d74af68d3e91cab37723286c873bc05bd2ee5a81c486fc68 0000000000009a14aaef1cac6a9a9d1526ca2b4d3d625e47bca3ab33db85a776 +116000 00000000000007ff257fb2edd3fdbd7b00c127a66dae1288fc5e26c402d13bf7 fd0cff2505d972f056864073f1e8e7596d4ac9558e6ac4143f2cc21862de4131 0000000000009b84d74ddd7657bceb5f9705d25dd29b5afc5318a3c689472a73 +116100 00000000000065411fff4820e49ec49f2cb88a9ca32167f63f467f7e617ad49e 4aae3b498e10fa97d68b0ed5c71ef28b7beb356572cb03d063fddbc095256db2 00000000000076fee78ae3e7ffc05305fb8571ba8a5db9a9f90506a7d3ef9536 +116200 000000000000f1d697e9398b391fb7f82c055cf82275a34476e79082ccedc010 e670b1798d12792cd8b4f1a3db9df6cef46d3002e32c28bdd8532077852feb94 000000000000cb6eb309f85c0ff869bdb6579943ee00a4db3b559c4bfaaa8e3b +116300 0000000000004d16919d8d7c06f6de2e928839eba4cd004bde3c5f884dde4dbc ffeb8e03f7d4c02b2acf372a304abda23b5b39c6102d88521bf7c0a096166694 0000000000002feccfec1d1ab6e479b307caa12e88fd506c2a267ae89b1081bd +116400 0000000000003417beb349dda3fcbd5a96ea5fc9edb3a8695f159dc2b21d5ce3 b6fcd5fcb73d4b68f5c3919ad11ab116be5a234c6a2d1a0e3d2734e4a9845252 000000000000c096650f7ae5b31fa1ef38b7c45c210ad6e2fee7795599311745 +116500 00000000000082cfd1645d87c7b939ff0f84393962bd703cf48cf80a192e1d20 9cd9a0d7c539ffc34f4ac10198f9e93bfe4ddd8b5978ba3a03efc8df3ea88eda 00000000000016d7ae2eef19a69429f2eefc0823147479eca8a0c640771917b9 +116600 000000000000f27619ad204369218507f6a7066d5b3b11b49c08793bcec576c7 0e342e84193b51b7bebd12f487702698ff8c4bde67855f0449254c90ecabd124 000000000000e2e5fcd47fb9e200888dc725e619f59f142a312e369f113de248 +116700 00000000000014308b79e3613e8a44ce128c7bcea044429ed05d477489f44521 da45c12d0b8150bc2ca6ce769e080f9198edf7479b48ced28b1130bf386f762a 000000000000f016398e7dd02b239467c4478334ee459c79d486e1c878a96293 +116800 0000000000005ddbd8a9b4d0497851d7f10327e7b90a245a397e3fa6b4e19f9f efb6882f0b45f771628a0b5731b2244d6cc7dcaa0249bc7f3ae49b626582321a 00000000000054bf249846384b3a84761ea8426378edc37def84f22885a6ce5f +116900 00000000000093d1c86c8a514f2f13564b739628dfb06f48166816aba2edb77f e9da8476819dc3bc3a7a4559412022eda173f6a52b134de287e2d4409f94ac5b 000000000000a60233c462a3c70deb8eea9fa5a7c62e2cc6ca568b0c08d805a5 +117000 0000000000001c78105335022027226fd1d4547293c2598b2e145dd96ef78505 3488347b98674e2d6f239cfe9bd3fe0886ff1b260b5eb3b4673f57f9132185c6 0000000000002cc576dca6b2d08d9702ce50e8ce4b666960a8bc374319457722 +117100 00000000000093f0e35420d98c2ddd3d02c4d50bd1e809d8fafc3e2bd468a424 c165d329f39de0010bcb3d60bffa595be59f4d7bccfd6643f27d83751193aace 0000000000004319070e4f7d3a5e4fe928122155555a883f437a671eb3840108 +117200 00000000000010ebeea908506dd887bb4065d68d09f342bd1774ac7610bffdc9 093a51191e627e0802e142304bb01c53a98f48fd0ae2a30bb4a38f71344f859c 00000000000085831e0b7ba49f0c3048993d1d85505a055af668676080387f69 +117300 0000000000007307c09f13327ff55d472b3968edca9fd4e8d20fcae5ebac3617 c2441c7983e5688cdc1d63ce911a96b9fca00df59f915c064e138cf27fdda6fd 000000000000c0fa258c433f6c1a3af9d88cf8eda2040b4bc3fa0686598b8f60 +117400 0000000000002b9f9113b14a2cdfff43a803f211b8d99e9628610f0c9b18e914 b05fa0e6499ca018650e152a7b1986e7bf6200b0fa3c2161a1288c6340ea4b0c 0000000000001bb19b4deba36c4c2e13bea940c36115b3004a1beecc95ff80e2 +117500 0000000000002a271c9d723d7c7221648c7d64bd93e24bfbfd54440726b791a1 b9f710ba23e2134c0a364ba96b8837fd9092503fc51d3aea5d19df6488d04b7e 000000000000943972f7079d75863b2732179876ed65726bae871ab6e6a149e7 +117600 000000000000361674f68680e304b78d2cfe786508b4adb2f41585ff7329bbea 4147f090f506d1b15bd32ca3658ea19647418101e6db3ed43a158857c8655060 0000000000006b5aa8727a22c2c4afcb59dac35bf2d644f24c3ab2afe6e4d9d3 +117700 000000000000c37245ecc27645b7b1918f9b3e8cc2a14697b7c4e8992b71342e 76364aa6b083387c75a3fdc3ba2c538a0f768415d24daa495aaeaf5c08bb99fd 0000000000004a41a8f8dbd02e814bc43a65cc693c1c4296d71c81a3c4623381 +117800 000000000000578232c0e5a895a87f5d7286c479a9971ea75f371916ddad6c12 2121db96b43ef70501102f28ff3632857b87f19807c3c68bce88a65381197ea9 000000000000503faded18be3428443f95146b1b4fcbe766425b06a706daaab8 +117900 00000000000011de44f5c1f660e0347aa0fe3a57f4500f8da487e45c5b52a35e 2bd63c4348aafe8867b95eba763ebe8a27d6b50194d2b852e5e409e04d3f5fe9 000000000000490468ec8a8d14dbeb8c07c3061fc7ffcf949ac1c02d18d4d507 +118000 000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553 3126c064af9033dd1e87de7a92e43d3dd6b3f25629bf4e4665825bce85d01ca3 0000000000006013206f2e7e1d5694b0b4272b89229ca3f9dc2fa4ee6d19c4c4 +118100 00000000000096d726e2c0a688e525e281211475a901b88e6cdc1a4bcdc5110e 8970af065ca5cf5f24c82791aa85f7daf38a65fe85a3434b719cff8ebc21cf89 00000000000065061358d17e10037eb26e22ede3abacaa144e21dea8a54d82a8 +118200 00000000000050c2c33d368dad544ccc07c1435b7cbc85ee9cf6b1a2b953ba3a 74a24b61491aeb884abd2d93c89f78ec290bb4fbcf43edc19cd35aca85f2139e 000000000000c3d1787f1fb537d2ecfd7245deef4a4c2d8185523dde5afc1fde +118300 0000000000003277c3f6fc4a65825efe4ccb84419874e0f7646eeba452f3e705 1493724d9f7077628fc798c7598b1993fbd28cdfd59f2b7da00e264d0daa4bf8 0000000000002cc7c1dbbe9a29db72c80a638734e0922ca7e7b6bbe0765d067b +118400 000000000000ad7568a1f314070d4dcb51f5324b996c66ba223a3757ebe21d87 eff55f7d1cbad81c9ebbeaa735142f22688beb6b8a7351dba941cd34af3dad0b 0000000000003f5e57bbd4c304160b42fdff28a68372407faefd1eba6fa8507f +118500 000000000000b7aef9af63a97bceffdab174d09085034537b0523c7ebf624c5a 1f08d6454b5bdf68d64e31443e558d33beba893b3e600ede3421499fd6370d9e 00000000000047cffee21325667855fececc700dd6fd9eb3e1a7129c99a82b40 +118600 000000000000110f1dd5756bcc8d2bc233b2272b78eb8c5b0c1f7cf125c97b49 203d3069458865c686cb92d38ac59595f398f74786a234bf5558e296f083ed37 0000000000001b697dd8f12d872ce8904dda607a8eb4648e09111ea21e7c31ff +118700 0000000000009ccadd6fb21182b99d8851dbb9019ac5149559c0b95e4c4a83df e9d0bbc4195e4de57b561a7e87229ca892532092e1ec3ba9a28eb4ab8f75b7b7 00000000000020304684a71d9b8a736c5088d76fb4c6d864f04bcb75d2e20fe4 +118800 0000000000004bdf73028c2610712d404072fea49fba7b2f6d0a535341881cfb d07052018b3d89320872879d163146df3460b69f1ff5543d94a72f4ec687f0fa 000000000000ac0a2ef28f55e35399df72ef57e6c889fff44823c327a0d581d8 +118900 000000000000ada7544c3412bb1df2027aaeeb06ed57a492956b91959ea03de8 e697b4f346d30cef008bb134eab06336a51c2c67029c893fe24657186f1978e9 0000000000006f917d4897ae4340fe5449e6e4244d8fd9f41b4b2a82cdca2ce9 +119000 000000000000499e09bdbe9b99dd44e202e5933919f578d6baf03dedca727d35 949422d9a3c1e069955897178f0992b6570945a9251786fd1ac3ee313751c23b 000000000000ac313a76edc9930c19962b2c594573eb54d2d703337fcdd7fad8 +119100 0000000000007dfd609b7ff123110414cc81c2f868cfbd0d4b17b8d73617a2c7 c6a532bd4d3ac693b6075286e2535d315e993e1962713b626120db6a3169b7be 0000000000008b162afa33a337402eb94673083ef4a3db2d8cd7d16f834a29f9 +119200 0000000000006780d7f71b0a1cf84be3513ae373ca9741bdb10831e9892f5baa 03221b6ce372be9948a1e999fa9cf5b7a69c8bad100148275c0945832e003f8f 00000000000028a14fc2a83f529c63d648c92b1c7416f8c72aca415e9b8b38e6 +119300 00000000000024d8b30b59cc164f5454b48f4c50d0cf088488bd85c6aec66f2c a6b27ff92dbfc24c3cedcf7bcaaa0750eb1e9384bb00a20a48b337ee167cd9f0 000000000000ac50b90227e65fb7db25db1f4600c6844f9c5fce73270d622adb +119400 00000000000009b9a521263681a3645e28a4102a142e67944ea8a9ee2eda392c a750351a66ff8779c005fbefb0a337a2801731107d21386c242843a75c2fba2d 00000000000063b946e655044d24baaf92c577058cfce6c8b5a9877e7bd5e6ef +119500 000000000000829fcc84f32804b145554780afdd64f158414f914544b610ee0d 9b41c8af86b3e6f1793a9ea5ca3e0faa478ef6c2642551711fd58a8fba0cbe7b 000000000000af1686f87d247d0763ab8701aafea3dc0896ca720edb972a2cc4 +119600 000000000000ae5ec05f0d8644eb0f0fd5b311dbe117bb2052d3d5e1d2f1ebf7 b171c5afa3f0b5153577226a305cb1e2aa70339fa8ccba7df01ab219656fb2a2 00000000000051c71d4dcd37e2baa7bea88b7597d24a14d2b372f4f7bff5f7d8 +119700 000000000000a2b546b34abeaa11f0a53bace542d63b5d605ba6b890c58ef9bc 3cb16aeccc8b34f73b2509989c235b77af2c6dcfb5cea144d4b5dfa0137fc30f 00000000000082a3906f6846d8dcf98d5d7a79eb944a777dcbdce4e622c6b226 +119800 00000000000087a9e18d9a62f87222cd3a8e10298880fd61f57a1f9abf4cc57b dee78a762eecd4a1b5bf0b37448415465413d0a1c4756cf777810437047321e8 00000000000039535b0b20dceb85a53f8e46ea22ab559b4eb26e9ba4626945a5 +119900 0000000000004a08d045812f4071d45f855bed0c11a09eec8abb2d02171b85c2 06fd0dbbcffb501cb2cc319f1cb715a1ea732733b202d922c989b99cb18da3ab 00000000000048d2bcc040a28bdd9685ca1454c3ec3fc4849ce7689b8dac49b1 +120000 0000000000000e07595fca57b37fea8522e95e0f6891779cfd34d7e537524471 021aedf56199fb102c49158e5432de8030ee49ca48960433eeaaebb13304e0cc 000000000000218e1979853b278e527b6c447603942b461014964c4368c27482 +120100 000000000000b46d228e73b260b48d8a3871cfe46cdd5d94b48afe600a0f9f71 29d476212a08324b7abf97f22e88cf6f19744ff191204a3257f66c811445a431 000000000000840604fdda12b89ada4be9c389ac12a4d899337c6af0782619ae +120200 0000000000008458979f4637ea80f579f030a824558a03a12714d0af9900fa70 7c2cd4c0bd4d3de4e22abb02ebc03f114e7725ad8681ff49debe8cf449c60d9f 000000000000a0a91d011e31f0656096b18e0bcae100abb24b58cd364b8d788a +120300 0000000000003e8d5bc3e06f7700568fa032a20cd789c10d352584952fae671e e1385ab6079cb3034f2ddc36b2160ae4b3493000ff48dabf2111c91193833cad 00000000000031c69ed313859b9e6380db52a026dae23db88a690072e3c9f22f +120400 000000000000a649121b458a3611d6dd7941e6d531ec51156c78614b94d5c0c7 dab11d4b200545034b03d8550fb3df0388173101db08ad61bcfe99cd5a38db06 000000000000019b0f776afaca4ad8fc05d3f2012ceec19c42890c49b646d930 +120500 000000000000613c29b06338f06a70dcd32042405a2a9944e2f8b6b61fdc35f0 76c1d7b1dde2106c2b276a3e1b3bc742af95679ce4616a15be16a13248c26f4a 00000000000008084b1b02676df06558d5cbaa636ff3355355f92ce8ddec8f69 +120600 000000000000879a6376bea11ffaf2d89897004c3d7ba8c96c0fa8e3de737629 232f685a659a15dd5a64e18026a06628bb9755bb2bf467773ffcc6d71934a652 000000000000885b9e32f504fac3022a553f606014f1833284d9e4d3eebe5527 +120700 0000000000001a63a5aa32481dbe1fa9b856df9a403f0dd53ad4cc1a9c6c5360 f0f2b15a0796d57c731ee273ede8c56bc45c0dfaf58a16e22a8c6291a538b2cb 000000000000585f9f2005172c8a584f821b701ea3dfe3b90b3279ef95a6f4cb +120800 0000000000008375e2021cfa4caf29f319ac4eea3a317d6291d1b54a481e7834 898716f68bae6ca19c0d298b8a5290bd171fbdcf3245290adaab91a41a983a07 00000000000087443fb1d09b0394d34e7cad961a585e9a0a0e08f5581e4c5988 +120900 00000000000012fee0a7f7fa5696567419a3bdbe0011a2b68ab4903ba2bd1eab 7d5dc59b9e625163486431edcb435eb97b589be406a891eae7c572a829dc1714 000000000000ad2ce42fa38b264e81a4e842353fe9a0bad14951d888c0bee7dc +121000 0000000000008addb06debe0ba6b11e220b14b2b531750fda710b62bb1d3d706 308e100986b09cd9d8895bb38fa20db4d5fdf45a9994bf6e91e5595841b93b67 00000000000087390012d022582eeb5abe18f817b11dd9a89be678c0ea293dde +121100 000000000000177ef47ee4d1b9ccbe1f18e5b58ad0c4c067c889a149486dd327 3a54c9daea44e46e2e35415036f7f4b3f7c5a62c015b16ca842df494335c841b 00000000000095015156b62244ae673fa593f901c61904ab112928bac95525bb +121200 0000000000008b09a33ac1a000745bb9cd68dedbe6663b8959d7517224c7f5bb 7828bed5549775f838190218d746a8d63fb7818430803fa5ec0612c3169cab54 000000000000518332e48d85ec4e751e3a4a0fe5924beb01f534ea9af313b2e5 +121300 00000000000049870666a81076ce7d6b447491e598dae0954a14f83e5c021d7b ff10a89654f3abefb08e387edacdb5512f81d532192c9ade7479abd61a232a7b 00000000000084c9d282ecea44a13e885b3363800ed5165ff86e589947285989 +121400 0000000000006fb74e83091e4af7ad8d5718584b73cd6f9eff8a665280a14947 042c8b30d509a08fff054bfbb780daaebf82d8004f0e1e992569b181bf698ff2 0000000000007195b81899c85c41ea0ed36184ac5302c30ca2cfd5e7e2345952 +121500 0000000000001514926f085cac3f5fc2eae6be6fca32e85a06b0a132a30459d0 d3ef348c63cd531bcfbec7bc14a3c189a6389534b3e8716d695b326379c3fbb3 00000000000076925af6ea93922470f22c511055f03a82a1993e332f11ebdd5e +121600 0000000000008f0087f4e342be4643b2951f7b364601ce778b8ab6c79f563474 07b6808343e96750b5dc663f6f63e6bc6d21b66447185dde054374a028f481f9 0000000000003f887b9343368ccc826c4d82355631e88182c58f7e0824a30dc7 +121700 00000000000016322421acc1f13a3102232128379bef109d10e8e0f7df8e86ec 1f851e4b0a090b8dc7892cb29c49510484894af47932eeb05f1e291069982a6f 0000000000002738a3d2c37eba40eb1a63e7a32421fa4361bf6012c59ff6bdc2 +121800 00000000000040e92e86c23da6a588de09c25e7f7a143a88890367d47ee1bb3d 9f9d8b0403d7474f004ae431ce66ca5a58be48f40919947eb701ced8f421070f 0000000000001166a5fa905088a2cbf1cddf96b9ce7b80b56187b8d817c6d451 +121900 00000000000015ba37b5884964b2375ed9e5de80b4826c4f2c3ea90245bdd41d d984d9f1fbb9c8f61b28f181b72285e3bdcc1ea225792d61afd75aaa721baabc 0000000000006a2a9f14e10e0e123942ebb8c2ea35999d29b419ae1e58738112 +122000 0000000000002fe5f29af38282ac1c8f4ea2bf8a0855946150130419491b6c05 cbc0db790aab07360e0f70698d4b6836710b4a455a7a025e5aa57e411849df2a 0000000000004ce89031692cee278dc09e09aac24fb2ff514fcac80e4013a911 +122100 00000000000042b6088aa88d0234e53b25eedf1ba2780c0949403bb9fe9a7329 604ff94c7211f06602078c1fc3a072618961db7fc4189cc0ba16201d91359108 0000000000002c317a8f3417420f60850c56cbb10b3f1531aa67770d1e41a9b4 +122200 000000000000549858509265725ef7df06d3093ba205243ddcf94d2b1c50461e a3eff597d476ab4743ca230f057ad1595d41b198a92bd2898899899043f16d16 00000000000030245eb7917b67c95574a36bd6df31c895431737400ec41ac0ef +122300 00000000000090e005c70f525af8f60f54fbd16104fccc11d09f05932121f133 e92a25a517e33ff9261ed2b5bb606f45c56d6c67f6d1d38b20a7a3414a4deb09 000000000000846033290f65b9eea94fb69418ada66270df42bd59246e140ff3 +122400 00000000000002b7349e9f66a0647caf479915c47789a987731c1f7f6cf5346f 6ce79b4ac2cd2d508edfa1a597cb2eae4c5fae716816fcad05c3adfcd9a0dacb 000000000000338dd673c60446a939464756a37049cc953696971ba3098037fb +122500 00000000000001e588fbc21b5e0f9ee387924ba0ac382d8f0ee645117d10303c ac1661fc05f9580848edfe92452157fce789e465f8026b43c3855b2844bd99af 00000000000085d6c2c755381a86c92fabc620a4524e614c345df84b71fd9887 +122600 0000000000004a16a9abab1a3f6a0288408216312bacc6a40f202234459ad948 fb9d83fddb988b9bd01660955579aabbc6496d0230489547ab590fbdb74eb3a8 00000000000097703eb3d5c4330253e43e316429e0c22bb6b01eff44459c4888 +122700 000000000000517b82b3b30cacc099db2961231c3630f1d5b2eec1d13ca1275d a9767fbbd46958edb26ab31523c648d29f0ef8752c12cb37281aa87bb4243356 00000000000084cf903da023978db36f07c8571ea41a10bb80ca29a59cc28f2d +122800 0000000000002528224df41ed781655eb376744d481a65d0c92874ec332b84e1 c80c19c37a2e4eba6ee062ea9639e4ba6f2cd29f1cda11ceb88d886919bcb787 00000000000081243d9e57fb6477fee6487d12a21165b7dd3f48ec39e77c768e +122900 000000000000621d24653b86c6ed7eacade0f2b0a968160c0a92721517d5db1b 89e7ee251e9d60aceaab04a988436bdd7ac558c575e921cfc0935fa507cc39bf 0000000000004f15b7de4a3c007f7c764daff682aad7a1bc7be5e68ca78b4996 +123000 00000000000069b73594b10aaa38beaeadc6d3f28cab8d76c4a6ac182694fd41 59a50a8ca8a840ec92d4acca666bbb13d12d977dca6ad798e21181f75372ac27 00000000000020bc3da483fd21f92f69eba87698826759d72bdf30e980da1f61 +123100 0000000000000e1194606998335c5d5babca547db3d84168f5aef36452077cc6 c2603502c609e7f08f968431dda580381687e94b2cf7c7488e9c5e680917b706 000000000000571d247720af09e4bb2b85fd9daaa2df7657cf56ee530caa2ac8 +123200 0000000000003c0bb7ed07c8a59d2f6726a037d0ddae2d54cd1b8510cc7b2247 e432c4d0e012237615e578015db168b664a8cca22ab852000da4f2e414a655bc 00000000000000821d43fb425e72a93edac4ee418bc975505771bf04dd456e1c +123300 0000000000001c9ad67d1a67cecb7c4f7616ce0085d86fcd9823adb5a4879c6c 1accdd765088a3ef61be8ceee8c363ba86146b4066bd58aa143967d074780667 00000000000050d2156b1152537ac23132cea841eb033ffd0ea6b006d3d2fbc5 +123400 00000000000000f0f1db797325846ec571b61727ec1b2bd13a7433591106a94c 6bac9dca594d3b45980d936065a1ad12f1536525f3bee05666cfd73cfb950d99 0000000000000856210a80397f8101ff93de8efb936fc3096dfadbd02438d19a +123500 0000000000006987b20d356c45d93dcf1c559d3013df28b251e3790e6cb279cd c372eb99a5e992d9031df0c58d43dc8da110d5e4748bbff70383f820d3d3ab90 000000000000279affe19851b3941187a380eb20e576a44ac74f98427307364a +123600 00000000000008161e5ac4f0f4ed64433df278f5dd0fb7cf9b422fc0e4d24bf8 0509d986a3a03802d8b3ab48a022cd62442accb31ddd5d2ee46fd159dd53d142 0000000000001cbd4a04751b2298e3c73ab59faf0de3f4413209aa83e1c4fc32 +123700 000000000000415dcc7583e49cf914e166eae4753f9772cb32145c42c7a568f3 f9510148bcb3e0182ead764059cc167a839aad7682cf22a6f95951d837ce4660 0000000000004c8fa09984079d1115f6fd90f4d210945bccf163a53c1dc981bc +123800 0000000000004b09977b4452bc2f5e6b33e1dc0143f3cd9a090e799cc76ea867 e12fc368846844f5708b5a90dd3c2b8f2aa70022568953546e69c32bbfe36f2b 000000000000488b3d5ff6fef0873ab9fa8b74dfcd12d38ab0958240d7cd8274 +123900 00000000000062b727ecda27173017ac99303c6c7bfe84a57d16eba44e66d922 8156a13766ecca058444369c5148d4b90993804ffc66cb4d12d3acc8af6a590e 00000000000052d89ad443e4d48d01f0f7fc0de58151378cf58d7f5e07e4eda8 +124000 00000000000023e9a0523cfac29afe07a07acf81e273cd892c51ff8318846620 597e724366fc04f83c8d133e6629de0346e053206ba15c81e9b4c4b535882681 00000000000021fb283d1722b29e809e80e837b89e25d159362166161dbd0fe0 +124100 0000000000001d6b70ae7186be1e95eee721c3b931ef003819df8c26142fae90 211dc3a6659f5c86abe1653ea3d7fe37d9ac82bc44014d5acf8f64b9346bb3bd 00000000000064d2f22fc95da555fd418ec12ce67da084ff66a1de506cf387d7 +124200 000000000000274320eb952073f4f1db434f1d6b6b63070700bfd45189caadb0 69f1dcb144366f57e74a0dfc03222cc63bdc236d9efbe5375a200839218b735c 00000000000065bf3c51ab27fd2a8379654cb00e0abf6b54a546bbb5f69e8a08 +124300 0000000000002f6d2adfdc94dc3bd8cbb3a8baf67f35e9bd16b9c95fea7410e9 2cd5f9e5e1c98ee1f2cffb2e1a80a4b7a57b710f5c14765c055319bfde904a4c 0000000000006810fc135066c6162b18c9ca02605bfcb2a1a85e90c3476c1000 +124400 000000000000572481367b1ba1f5a871838183c510c2419590a4e1ff877f3e75 5cb2c3037d7ceea8cba8244088df514058d69f56235f924effb124f0ca2caeda 0000000000000457a15d1d72099da0d64c908c20d88ec34438e117ee378c0fcf +124500 0000000000001f5b7f86d2ea42c64bc41b2052941f3e50061038174af7e76ac4 b07f01785f2e8d2392671a5d0aaa7e33546972ae11d85733fce56ae9eacb2e2c 00000000000067150d45fc2669d071c4ea898f0c020a37ab79c675d8ce4a286d +124600 00000000000028dcec47988b70e19b7761215898d93869907b5a72e961a51ed5 94116f558e15896b4d33834e449eddd24c691ec691cd04579b200e9065ddb665 0000000000003f52e5b2ba9f820b7d7e25d18b2d34ea8fd439f4cddd962f50f7 +124700 0000000000003bc6789ea0a512f69b0d1f6f1b0821b9933216facd4154a1838d 5b0eca39883cfc8e6720cd67e733ffda8203946620316494f5952a16f0ef7620 0000000000000edf51e3b776e85c1bfe5871ecdddd712a1ead72ddbae7b516b3 +124800 000000000000126ff19d623fb898f15db39a62d2122f10d3c42eae7732445cfa 045fc401f70989c5a44877c91d2d95a395b2b53713ed9e03715173d08ec5dd4e 000000000000125b8ff07b1f7cbece74542e38ce4ba570e809c4a73f1a0cf8aa +124900 000000000000001fb03a83f633a0973747dd9526dbab1d0a1c0da8512d39dc14 e51bd83c1ef0881fb6697227abacb850c70a9030d273db7d5a55e499acbeec72 00000000000058632ce262fe4b9ecec9e2f6c3239baee1c3a2c92bb3ed0820c7 +125000 00000000000042391c3620056af66ca9ad7cb962424a9b34611915cebb9e1a2a 5210b932f8199e8306adc1111b682b881a398bace8ace901d54c0953021fcdd7 0000000000003fc97dc375993b8eb6324cd5c772fe2ea9384231f6c9b69b4163 +125100 0000000000003ddac149ecf9a72e69744201652ad405a0861d08543f43b165e9 1032bfb4911a8b2e2049cb3853d0603e01a3fba6caea0912abc4e0553cbb59f4 0000000000000baa3f19eb0d1168d6a0558fcd09338d98d5ada1704aaded432a +125200 0000000000000770755c8f06c145f273e70530ce9559bb561289f951b99e65e6 d719cc9a2b5c15a7b3d229d516a6c52a7e59fc21a3622837e91e88b05708cd38 0000000000001166add644cf911e1bc1c53f05dd4a968e2428945a190744ad73 +125300 000000000000252297edfa2047f8743f9cc987ebe98995f01ed0c3c44d1b574d b8c767f1f11c0cdf789899b9f3838fe64e304fa65bef0e462cd330479692ce7d 0000000000001334cd7d7c2b46239efe5451e9b9eb9c2326db47fd7e0cdf549d +125400 0000000000002522f3897c6becde23f2d1f246274edfbcdec1aa99ffbeab3ed4 6c9265ab231233414ee4615210987483bcd362ddbf5a08353c3c0b04edf2b951 0000000000000cbf2b6bd7b12960172fa78eb8c7a40df7f6217534bdeb682fca +125500 0000000000003d46a48941799daedea70611d9947cc0e282dbe29c4ea346094e 72bcfd89d8f176db34fd6c6ee008cee54b9fbf0b669c2b18d70b1098fed06d29 000000000000030ffa45846bc33fab38c5eca2150894dd40a072ac57f64f5272 +125600 0000000000002ceef932557b9b01e1956a84d9c8e3931b699e3e8a22b80a97dc f1a9ae82bc8f5f4d096ebef2a929fba3236a65255120ffc6ccd6a3f1a6b9ab78 00000000000022a7444d1a1be38fa208278cf52df06b26b4bc7e3da18cc12c86 +125700 0000000000001ec39abbadaa52a804d254796c4e1db55ad906dedb2e3ebc7df6 08a83b1d68058f9f577dfe966860167f7a37f8d94347881d416922fddb982e89 00000000000005bcd8f8affbe9dee24c90fc3ad333fc0f3dfb97855ff833efb6 +125800 00000000000005bacf89beca55a0354b961b5126c96dd73b807e80a0eb6c45dc 34cbb53663fa893fe818e030322a5d1aa1564169b1d9238c94314bc262ee85fc 00000000000028b96c9030cbb7379f1747f98428cb79b548147cf1129dd1c97c +125900 00000000000044370c6bfb757299702a60da665d66e9b7a237a5093d8cb33c8c edcf53b29c1ce2bec1c1ec6ea00a55c2f0496473895024be2d5f3f79feeac59c 00000000000010f07e98bf90b68d2012cbc7cb6ea579b4c7343cdee6474f3885 +126000 000000000000166b7d480aada35af1e6f9a2835d68f9c2fbd272073dc6c9d5fb 2329e4a75c99f5ce4717b003416235ecc66e06f82e698261e95e570b5007ea69 0000000000000205c2c2b5aa7dbe0bccd98bffd4af38f9c38c0ba9aa8df704eb +126100 0000000000004484f2a41e2a16e7e60d06d6c675a0c2af31c3bd665fbcf6162a 67e04053e79ad1bc28eacc1371ff0bad69fb14e44435bdd4aeae135423c7d560 0000000000000e16e410ca9cf25eab64f03a60ad8f6295a62aa31036daa258a5 +126200 0000000000002ebfba4a73c445c2ad8b8c264e73fa9dd269106639bc8aa8417e cace74e3371362dc85b16fc4c682281a6ad97700ff9c64e0e0b26b56558b914a 00000000000043331126330786cc87ce9b0017f0e48e43b211d49ed5250b4a55 +126300 0000000000003fd549a0fca1eafb61533844a65ffcf96f6bbec05c8a69d98620 6bea7fd5126d4a9193004311d1d260aa8cad4a6124929510c8eb7f01bc03e46b 0000000000001e00d89e56527b0c9b2ac031a6c21bb64c5dad7cb3f7323729ac +126400 000000000000443a397c099458703e381557d45881bdbe78d50e81919fbe007a a0c20b74a51f50aaae255f8bee01381d613d0085f0a4c5a9e3f4c63bee953283 0000000000000f9ddef454c312a8bccd9baa808ffb9773755cf0ab867331e742 +126500 0000000000001b0448b385b0a2616852cb8c16b1d5f6cc63ef5fec74922a1138 e5591a4638249bf17e13b74a315b5c129fcaf9ce12cda6a256114efcd519a6cf 00000000000036e9d2ab127a46e4f7ae58ac304cd54bbdf0a79819e25e0a9ec8 +126600 00000000000002411e38f987a8c45a64548943ec9b4e87077f4db1788bae40bb 6afb939f8bb68c1b01e296a2cbc12cef1f7d080c796ec39e41095afa9ceb6e98 000000000000020ceb92f8772990decc3484d92c1b1321d12aa0b33870424243 +126700 000000000000139ad4540d0412b70d606c313e221135523ad421121387f8473b 9ff78a506f54a44f596252aac3564f9cd0593a0d9c1578d5e6b8bc423807234b 0000000000001125742d8b55863088b91bd96befc0671419eaf1dfca6acfc435 +126800 000000000000199afe02dc91754286ec906e094d0308ed30ad0434f6233a7fe4 d7db088c3d99884f1f8ea687d03f85b6600f6d5bd8545e6de5befb5b6091ce27 0000000000000a39d68edabb9bfad51557baeaa051909778e34e42c5fa14fe33 +126900 00000000000034614737c609d49d00dda3bfd56eaafc38a50bb2c6639d076cad f66071a712325ff6a9c82282d3b69b494f01691c7864887bf1b9868734796af9 0000000000000a0a2ceb6b8f5db41ec898b1d24a7789e2a7787e15847c3a45fe +127000 00000000000019ebf04316b28e56943e697b142edf332dff9faeae22e29dba99 d928fa83f4782c1ad46ca222a2b697965efd3cae9be59adfbb5163efd2595cd2 000000000000311021be9b74cac6dada9f5e9266aaf9b933940e269750273064 +127100 000000000000052ca56b8add1abdcc3d3d9c0ba52dc636d89f0bba1597769a18 189137881e9f9f101899a717c83a83d9ca418dc7a95be2867a003f8ff6ef5d3b 000000000000114c155b28ce3a249c64c9e46122384fc48ab1b32533979563bf +127200 0000000000000e0d00862ddeffba0fc474b77ce1d39aebdf0a650cdfc0ebb297 eed395dc693d77bfdf1dad3419245ac2ab2f66ba1d8e73b58ee8a9dc5e105a62 0000000000000f216acf7c0cb137e36c6aa1899eb53bd2455d129e1cc8a4e978 +127300 0000000000001ddfe73332e1f5932ae1e8dc264219d365185b3e116311b93376 7dc42746fc1dc7f9ed2fc216df3df28a444aede3a1d7792fed7df6c2dd622303 00000000000016857be2a1f77cf645819e48dad9a707231c0c59a2d0b0577801 +127400 00000000000020449c862044e15eba2b2b0c9d80a0d031bc86457a82c8e60f85 073a5cc96566d2bcdeeb3df936ec0b73615d855d618e8f7ee6ca5bca0976be0c 0000000000001881199cc18aed68c9be6dbee59830239765a24afe8dbdb4d278 +127500 00000000000011095756da3548c943ce7250499947f78d00cc3ef6f48ecb2ce1 788b613bc0a708c733cc4b8120a3cce11e3e6743e73c0b6fa3a04597cbb11011 0000000000000013dc0d9247d7f197892531f6c42cf3592aa88062c49c91bef1 +127600 00000000000025f691b7f6aa88ed1d7fce0eee74efd20c4a11e2685a02bf62cb 7cc06ff7cb5134216033a44bdf80e09a04bc2159847c77b9d6771d255a71993b 00000000000015e59e32e239aaecbd37548ea0d15cceebddd9f17366137ebd82 +127700 00000000000002a137bc91ed879031ce2960f29e6312487442e02f91ff1385e4 f6eb15fe600b011577039dc0a2ef91ebec2a75809513dcfb92d47c8ea9fbe17f 00000000000013c370402dd7e61a04aaedbe36545392bb0116edd80ab9f7f978 +127800 00000000000010c9885df440bca294dfd5ecc4ecc956c0e90d231087e2f23f53 0e6255652da7cfbf6ba8914ee77dae5d806e4ca60adcc709218dfbada1e46db1 000000000000003cdfc23d65c87110963c6d7b62076f6e12af40993ea32cf30d +127900 000000000000251c76a3a7e21eca484a9f70ba7ff7fd6e592bb111462d8e6072 4b6e8e1cb032858cc6f37bc6d6d8864dea144df9f5f311d1deec7d6702e15349 000000000000186042e76c6274c6db03799ca0038de6b6485e5b67573f076513 +128000 00000000000003b8ddd8692769e1965554a8bb030863e0566a28bc0dc952864e 58be22d7b76245dfed9c28db0c7bffc7fe2fe5ed832005ae16a87c0c2112f06d 0000000000000ae8912250b0d92a9fc63f021f490b8e359d01ad883298f99c06 +128100 0000000000001fcc9a750f063766b23018b82b4b6b19bdbe95a55a64959d07f1 717d47ba946c69931dd9ad986e457fec71088be468f18ebe87d1695a1c94aba3 00000000000023352d6a4d3ee2fcfa94b4a8071cc9678747f58e6831f444ec97 +128200 0000000000001c305598c2c9d5eac816342f036e31139f86ea6fbd26d4f0e848 1b0409046145717db9b1f994a91a4a70e903afe3ac04a499f99a6db6613b015a 0000000000001175a05700ed42a7a6110fa44e557c324d8b9daae73cb5c48da0 +128300 00000000000012c83c45d41ee29677696193c5eebb5609618faef1daeb9c506c 4b5427991614e3d9ae664ca85e8f2faee0af8220221bbf36cb50cc10626666ba 0000000000000c7dd9b48515fe3bd6d8a41f9984ba0c3dd11a5309cfbc3dbcd0 +128400 00000000000018359e5d441408debfc9a7ff71eae9b2165dd0d6a1f937065557 2c6e6d4aff11297a925102e079c036154d89055c963fd9575ecc56b59389826a 00000000000021a6748552958bc0b7608860299b6f4cfeb140cf23fd8b4864ef +128500 0000000000001efd5791bcc29a59e24c25ad4c8c35d5a6dbe050aae69e4c7b12 0d382c98a04f06d15c538345f115122b1bdeaa32a217192e8ec31b0c87678914 0000000000001888f9b61451b3d72f852729c21aeb6f71267bb5437dcabe3186 +128600 0000000000001f458b584aaccfd8efaeadb9222e4390b3e87fdaa5a9ccc8ecbe 40acfb5d62feaa716e029325b40886d489137914adbaffc854d512c87e2c9d63 00000000000008ea37461767aa58c529f8f6483cf9b1e784b2de24c98165c918 +128700 0000000000000bf33ddfb887ee6f31cf888d38ee5671317a1143d45cd3d28b9f 3fc4fb896287b09d023e629442d1747b202fe7d96294ba87e066adf1cf0484a2 0000000000001ad22e7c486a7ffd5db26fd982ee71bbd17fd590d3e8ec8c8cd5 +128800 0000000000000225cf04dad9ed66fd789c24330d8c95a1f8e8cbe82611426a47 c54dfc07725da176e1a2e2f98144627ef228d29932e31ce4b18040f226c4776d 00000000000006618ccf0e32eeff612e049017044a1c909dc3399ac9cb307848 +128900 0000000000001d004312af91362c1ffeab94f891d6a007a78c64dea8dfd2a1ed 1620d2198247420e2818decc82fc1adf1f85441908d71a7dadc74c4934dcef2b 0000000000001ade6d3bde45147517dc520503d90c6d988ab227b3ab181402c7 +129000 0000000000000b85f08e4fa7cea9dbd1a7ec5ecb9f644d214e3572e214b570a7 e15f6d02f15d8a4b3956b8163106555e1d47ddd11bf33a0a0a5e35b7823544f0 00000000000014417bffbaf300bb1d360be148a897de3a5914319105166c9e46 +129100 0000000000000d2c60ba7301526c95eea1e821e464013e8db08efc7f1088503a 147285b0be62de4ffaa8f2d4b851e9145b2dfb3a3c335e3ca69950fa970576ba 000000000000084db654528e237561d9d9f96059421aab2546d6a297aa4a1f9a +129200 0000000000000c35365877efd5cb4ac783d93477325d5ed4382c99f10edc3f18 fd4e8e27ce1caf40cb3787fd8f2afcc3cf3d072302884ae6124f8528cfd9699e 0000000000001b7bc14e0f55a2b0674b7d34f9e4e887ee8f9fd0ed9ccd902e18 +129300 0000000000000232b932a1e9b31fdbd568e9078c78f1e68158480ff02f616f84 19bc3e281ed5f109fb4ba58797ffffd43f624af525dd71b9b0df4f0236a22f52 0000000000000f404cc3a74e653b620c32d01de90a6b89dca4d83143691bc62b +129400 00000000000017601fde84f330befcb3c8c3d2d70b8a2ad52aaabb898f2a6d37 42e825186c5bd747abecc5c07da962e1843836192f2d9263a2ec4eb7d2e2d65a 0000000000000b3a19fdf5f779a0dd93e18a26e21aa2fea9f18563d40f97de66 +129500 0000000000001c427502ea512cdfafd30504eb6651bc4be72e2e528263f778c1 0d70afc6f76df18c28107127e4a922fa033d979c04a84b24e4f362fbb22f6874 00000000000008ca2aea3c2b9e760cbdb636a9551918fd6cb41074c7bf9bad1d +129600 000000000000103517ac0e423f881bcb09bd67968c1ea0ac258a9a7dcb0d3132 1c1e4d24ca6acfcac7d91997f0f48c2379d38f05dbd54d08112ba0bfbc94f09d 0000000000000bdd0c0500e65bd6368728ccec4d7c0e080b1408d6cde9bedd10 +129700 0000000000000e0c4963b942ee4c90ff751e5b3a5c353f8342c39cad047ff840 4935cd55773ab3802001c38ae97f502d924bb093f291b862f7347a0662f16cbe 0000000000000d818aaa480a1d494bba7f1e71e6626b87238ddae86d3cd892b7 +129800 0000000000001cbb8057bd77d1705133cca34d2e88cc47aed13803bf7efbb98b 259006fdc465a94e1b088babdeaafdc9ca6ab16f33a69e56c766a7332a3d9b7f 0000000000001a7f06cd9efb48b2a69779d13080d99d7d87ebd230edf70cfdf6 +129900 00000000000012e5c65c0591fc65ef854c1bee890526048256ae563626575d8f 8e32860e2e671587f2592b8d7f5d02382d540aa9f6f044731e157315d22723ef 00000000000009e4a86eec5f1c9b897aae92958cd20b24bd854e3118a122253e +130000 00000000000011906b491883ab0f16f0e690b133ca860b199b775c3cf6581c21 72818a4227bef2d7c09e2e626400aa066701382869c4d20714ff976a48d44846 000000000000012f983ccf25fca1659dc99a24a455a60a7fe3e848475a0b67f7 +130100 0000000000000e756c0e0883337d9dbfdc52a9b3acf6b413f0836e8752a161f0 cdce14131a3c276c1f5f9dd501ba9b18964135333bb5edfac970a135c40a8fc6 0000000000000501175b0f5f1df03aa3f65b9f269477cec5ef1b8fa8cc1f7c19 +130200 0000000000001903187b3f62c13ab7f0e77e625a5f44e3ee53b7707c08c52577 b720383d9d966ef6ec2c13767106c2f684380de18811bac4d1d4d0b2b3bfef92 0000000000000ea40d112ef8634bdc6ab01c4cee87860188a00b2c22f97a5eac +130300 00000000000015deb891a05a917edfa87de07c9cf36ff81e41d6f0bf5b1d6f38 cd933ad863d8bc12f94edd8bf643cdc8bc45099d200d7dbddfcebc1055edde33 00000000000013f14987b26cbc28410538431b85dc49d64f8c03aa65b1ad2d99 +130400 00000000000002001a34e42f3c453cae7d2b6453e08fcd04d7b9737d256ead0b 89671d126982d7e2ee42f035e49c03db242750e6c0f86d801e61ba35faa2d3d3 000000000000025051ded7d3a685084b3a9c20078291b22c0d9ac335028be7ad +130500 0000000000000f2c8c5b7acc4773401178c2bd401e03d0e4feaccdd2fc654072 486fd16ebfdd17fe890dbf4fdc0fedfc37f4ddf04de2e4cc5058abb810f42b84 00000000000013fed2c4e91ea2d4258672c3ba7e14e9a9e29de02030de754a31 +130600 00000000000002f367a297de1f8aba3bfb46af38c6ec9f6967ee525802a81f56 501bbb88c430c854e7687e1a0fedbdb2057eaa42f4e94b07c42ec78854a213d2 0000000000001c6260d64fb5e10691db6c5f107f1ae80e10845da647d186ef60 +130700 0000000000000eb7bc28fc431de3a10df60f26298946f4eb2a65e02f325af46b 562dea1c98f06e7398fbd701f557981d36a2ff0d3a921a4be067de1ac4e41eba 0000000000000c2fb17dcb4ff7e0b8d3060620e95453313a6602b5b7344d3a05 +130800 000000000000138d5d5071b71215be7f9438590169b0f2dea29a88eca4c962e4 d695610c2fa6a37252575b1427b8cc3ab5d40594eb37c278dbb312b44d4ad3c9 0000000000001b11b5ee4ae9f8e3d87c2610033fedeb5ff9653ab75b0ddb35a2 +130900 0000000000001b0aacab477b05fbb9217439d3a49225ae3898b5d88b97395479 b869acc617b26f1e13b3d60c4d0f688ba1d563fc22f685c6282883f1e317ad58 00000000000016af460d34214831db7c361cf7d9bd711c22b798a83e55b0827f +131000 000000000000143b8959d6db75bf13d4f4789ddb0167888d819eea3d413d82a9 c29e36afcd9eadc17f5c71e45e558441dd33470db6a0091426be32036eb438bb 0000000000001046e4b7a63f76bcb45e62e05868bf59155b0aa552440633faf6 +131100 00000000000010a4272fe7701199567499b8db4224f6f787395ef649d765a0d4 0c3152e23e8be8f77c1cae3393be5bdfa5c564a049bec0ea7f04e97cd114b999 0000000000000aecd16c3a17edaf9be552bbc2eec2629db8037322a4f723b8d8 +131200 0000000000000b7542b05601fed20f0ef46895d8b4ee54091a8d49db759283cd cd6871c0579d02d11f89238586f9583c2dedc7ddebbc4905b165b5006668c206 00000000000000c7d069164c8820c3a4093adc063d9b32e66cf8a3cbd5b1b039 +131300 000000000000008e02cfb5b9df130496b876ef1666d48be12216bd3e47eac940 eca221f2e7a7d20e8b90c631a06e20ea4d695a0a55fd8b6ea98de21697d229a1 00000000000000322cee8a774b3bc50bd304f92ee63a7d8c7c01bc9e71f182ae +131400 0000000000001044ad23b02bb9aea40703d0b5aab12a4eb200988ebc25fb1a43 272dab63a3d24d3984d938052797d3f760ed6dd6116dcbd874bcbb8514dcec83 000000000000123d78f8c42baabb5c53f98458cc5da85493030a5ded72b6b52b +131500 000000000000006bf0e3810f147c5280892da51b904728921baa9522b90aaa0b 0114e43f85dad7abdf762b9c64b83df24bd5fb7855743061fbb60c33549387ed 0000000000000ea7bc02bfc86ce7060d926447371ab06df03ed1e13645732d0d +131600 0000000000000ac9b6275dac7f4d0974615d88f6c176dc77de9d65dc60655fed 65a9c80793e0bcf8b6950031412dd1b4501efc50aca7e7a391883b0fa06b74a3 00000000000010447950df89ce454d523fc0cae1b97c04f1c7b3de2cc39223a6 +131700 0000000000000d904ef52b4e628b3b7073f06189a8d4fb218ecf65d1dd891563 5ca8e8293970983d749bf826bc5171a0d7bca8863eef096a59d0a2d5605bd16b 0000000000000f650323d9d8fdd3855ebba9543df9a8791c8d4c50aed629ff51 +131800 00000000000011bd74717d7867500e54afee0c1e6bf5543b07180577e35c18eb eaf047ce7a8ed434445a606ac7dd1c5ddcea0d4c480bc00f2584425b678043a3 000000000000129266e5594e14b729f1062c0179949046054c80604c5d5450cc +131900 000000000000052f2444ff4ac073aa78543ec8d2b1c5078ca816a540c24ed2ec f3414a1d17e6f4bd37b543658348bea5e5d81e802fdb1215062387c635d7dd7d 00000000000004f8251e6ff5175de04d75f9dbbb55bb4a4d52109a633b1ff313 +132000 00000000000000a7a0483857f0d951983ff2834a47c38fdcc22563ac0f8f707b f68d8c8afd8122e32513ac9115aae542a85ac7437fef7371156feff8592e8c62 000000000000029054ecc6a343125f6f526f774c7189caad04bf299124acc2a3 +132100 0000000000000711e288932bc1a01fa6e1b120f86b2594a6a9c3e4c432363a08 42e3b645275f9bca7f17985145fe0d453faf486a9fe538286ae7881f5ba58a14 0000000000000dd95358cdcaf75cfa8cccb27955df9b04628fe197729dce9954 +132200 00000000000007b4fa1ede15a0207c76558d1e8c20257945ed5837c0e9c0b7f9 da3c4e83187336d35487ad6218446cd4ff6a80c9dce52f2dc60b66378c85866f 000000000000087bf95394440739d33fe7e1e6b4d4682a4c5b30e9783e8e86e9 +132300 00000000000002bad2836063fd794b0d2141487c16837fb7d0ef1157c32a1309 3a13413220255e53bd44c28d0f85e5cfbc4dd7c5feb353d21ca316febee64a7f 0000000000001260989f97d0c7833cfcb4aa12f31a54b93a8f6259eef2efb8ae +132400 00000000000009cbc21e8a499f23171b0378bf50d0f13f375df8c59ca38598b8 04340298edef2749968323f7ebf53017ea5792006557fc010c4996ee454f8dff 0000000000000cbf2750adf8d9f8826e52e52e0260efd99085b6de563c6059e8 +132500 000000000000112cee76a5577b4124dbedf2ba0c882f5e6a7a898f853b7c9791 c1e26b638dc9f2a741433ea5a2503ec6404cd7d837ab3b0b174474deb0de08a2 0000000000000681b858b51080af14739f21685070f72a183c66be3d9ca7dee8 +132600 0000000000000e2583a45a36838c3527799d4b570be1efdbff66f4c9e32d99a3 476255bf5866041ec615d7b30a66a2a8f4571fbfd49c78e8fe323afaf1087254 0000000000000d54560c73ed2bbf8aa65ae70acfad0a710c26a51eb14443a5bc +132700 000000000000072b730f1ca0681a3279a3c1c32a488bf146b005c4327566c0b9 b67dc2a1d7a56f027996f120c4e796bdd136b465bd345c21ede980bc28948d65 000000000000091b392d5057e549c0a1dc216eff768e934629ead2fa73b50d79 +132800 0000000000001214acf5b4c84b9f7170f168ad667eaecc03fea5265b0cdb9398 f6b7f1ff3dc59939fc1d7335854e42152dc000cdbb09bb1754064e2ad6e5de84 0000000000000df42b538904cb22b26f00d6959009fbf30de0385ace8cb47a8f +132900 000000000000035407f0f3ff659ba9ff24c5795879e5e4df80025f94c98553b1 321911ad673f780d97c84984a1e29ca7a2d49efa51e5b3cba3d0d0c43aeadfe0 0000000000000b98f64952a75334681d4d6dcedbffd5a7e0c2f8407168433d1a +133000 00000000000008aebdeb747bdedab72548e3101cc17da53301085ba6362852b3 a901626dbc4fc8ac08ba7a3f25c923ad877c47bee9e32295ae94e13f4adb6b0c 00000000000006e6202ca911dfdbd4a2918719bda2bd111478ffa6a9a1a75b09 +133100 00000000000006af8f8d4ff3af5efd6225170728349bafd506b56e4f2ba072b0 10588f2890de402a60b3f6acd824266314ffdb3978e75f86ad47fb600096359e 0000000000000597ae2d735cef492637934571fc5cf87da38b4ae24c7603257d +133200 00000000000006ae784ee6d1c61f2943d69d2493e0a961ca37fd5e71bd60bd79 de175ab1ca912712f0e6f262797d786fab954dee2aa195ee1cb5babab98832b9 00000000000007949a8fea2cbad1e4ca6014a820729f7cdffe5617b2fa317256 +133300 00000000000002daa2f51102114bcc8297e5bd5fd8415de973554d06e68efe16 00a2683dc13861690db4725fee4cdd816b1fd6671966599ce2d51f6d3d2b8e2e 0000000000000a870461a3fa10520373488e8ab0d934bad4ff9e1750d07399c0 +133400 000000000000098c76291c6c59474d88eef82ccc24e531ad9d5e670713544e82 9fe48bce7ea4762422f72871371ad3a61eb870d6a88f850657ae76e65586c816 00000000000008f312e5342eb88be9ac931e6aada2d41a4510a6b9d5cfaa57e4 +133500 00000000000008547ecbf9b155e62b1c63b575be223349da86b3ead21fca710f 3599ed14f94df01a8ab44d7c2586456ddef9b7e6755b7f1f54743b2339bd2cd9 00000000000007327214ab99afd6592858af4436f0065cc89f59f9793109fcdf +133600 00000000000001c2c6077e5dffb089a4f02611231e6c7a84ed11d4090ca2a3b1 2c1baa766889e258db2794bc3710ebd5682bc88f23c9fa99bf9bd5ebbcc7c863 000000000000097155d833d5160df3c3bc604a8b8568ed0b2980b6ce8968099b +133700 0000000000000bc7636ffbc1cf90cf4a2674de7fcadbc6c9b63d31f07cb3c2c2 eb1e7230147e54cf9383630045bf35df3fa58857a9f2b3669730566db752249a 00000000000004ecd261ec0d7b0d5f06f36576222ac3375f236d5240e844a482 +133800 0000000000000b5cfd719453a424cf2067ab49fe09bfabda8d56e5b91672d765 7070b903c993a682d549269a36f9ff9137246c9f5261f83eb5c7a94d6470a454 0000000000000722f37776d128cef7ce9e7004b1baa33b7b86e28321f8d4bb43 +133900 0000000000000c06fe5c69c528d83ae1997c48dd3532d0fd876a5b522146f18b b50c2691800c593531ca8ec22e71f56308702747b734a104404edaf063423801 00000000000007a8c031547f73acc80414ee4f1bf4e6b9d7e28e5769b7e593ba +134000 00000000000007e3e442ce1423496a064a7c34342ba98be164ac0c9f9b872213 31d1e81bf4cdaa55e93a13384406d92d0da752ecfdb8807c2d57f41d8b339e33 000000000000067ecbc0c0a94418dfe5fc75bd6e04473aeef9b53973720f1679 +134100 00000000000000408af403d759191d976bb708fdfd9ca46776e3861d96fdebae f34a326fb96fe4195946812bd01ae0bdf918b89c17aab89759dd0282f37f4b12 00000000000009f109ee377ee1e0bb9b6ce02f1f33ffd23d258fda5342df1f0f +134200 00000000000002e49d0f77dce5d360234288e013a8ac4ba72e02615c855ce8ba 1352b901b8b640999e5becd8e100046fde45f7a871abdfa436992c98f74ab563 0000000000000249208ff8092e5f014a8f01499de9146ffb5e235bf632aa99e8 +134300 00000000000009c2389c4826c2b2b404091652333f0c934c76c070e22e2b8e92 6ad8631bcf9a27ed1a80a0a3184e78f05d14c01f8defeee1104e32b4a0e20eca 0000000000000bb8a6737978579510f5a9c8835c10ddca73636d7c3c4929f379 +134400 000000000000051b6be6b8b5c7404ed68eeb47f2b3c8d6955c43666f261c3f6f 819bcb87025f614950321155b3d336f9b58d3d2d471b733e9dda6c69035f7e67 000000000000071ed3d2834bdaab882933a60902f6f5e92aa8bbeaea36c5a9fe +134500 00000000000000241123ba5f49ec423ad3e3a380abe9e4a1fcd699dee8f577da ed6bdd77e55262ae089959b919f71f1994de15a60ec568a40200b8bc6fa1f0cc 0000000000000085efa40d44472865ed0ac4f0966e9c33dd328d4c3f8ff78789 +134600 000000000000094c1afab9c2399ce28cc5004870cf38f03f156b10aa2d58f78f c3aa36c3f77bc7c1e453b974b781387c7b21e48686822c8ddc5f70da89891542 000000000000002235aabd843b08a7050e95b3be46087b9cd473823fdb7373dc +134700 000000000000046c2da63840f64ba7e290be206232e9d48f1b3da1e4311692e0 cc572081a62c42e17ff31b47f2afb66f29d860f49ce702c0e7d81db547415e0b 00000000000001dbf2b9853c91ffb88719049abad42ec1aea7f28987007c43bd +134800 00000000000002ef93d8480b08d1c76507ed692ac8d3a88ed1d2a498f5ccc106 668efb7c1138b1ae0bb64e1b687a3720509a0a5be311f6d66bcbe3d77705ab59 00000000000004879fe2c08bff4911c4d00dccad97f77438ce0532920acd4092 +134900 00000000000000411c4c8466b1c0fa8a740e7f8d8b7c1be762f4e4a7c7544641 796a3587cbf48b76dc26377e4e7b12540147ce43144adb565b75f293a22fd745 000000000000007c040ff9a1d0534174e2d61d9d86d362acaf5f4bd394e61632 +135000 00000000000001bf349e3e8195f95a080ea17efe012cf7f512664829f9d3772d 548a16f4c9caf55eff2cb4aa7435a3bb5ad482c3f660b76c933633ca55b9b491 0000000000000275c9817fd5998fee63944df8bc4e473a4717173d98a5ddb64a +135100 0000000000000ab9b39e61cff860ec65e65738fd2faeac5acbd136676912a7bb 6ca8935ba362ceacbc3d4af3f240b98f31348c5e9928352c2fc01363856e1131 00000000000005ac399c70a52a3a3c9efbaa853aa46ce1925dde3ed69d6acd7f +135200 00000000000003558eeef20d861f9c0c1324ec18f8dcfb49b978cef8c39a7576 7c44e4b5630884e8d4122da31d6fa07d75f9d12748b58c168b31ad71191ea5c0 00000000000007a88718752afca443e279c0c1d3f08a51957a449829ba544748 +135300 0000000000000335efbad45a991e04a6bae82e207f754d4268efa3b8e0197c5b 38adfe4a9404e9272fdfc8eedd89373e055e6ad74ee3c9e90633f0438819a438 00000000000000759a4df0b56fb026c0b06aceda55da5626385a230e7630b962 +135400 000000000000076cf9b166f3c23e4aa6082ff4a93e187b0f7b97f977f593e6ba 77d183e1e8e6e5e2573f04d522954c0e91e14e6c55dd39ea1cab7c278d5bb1cc 0000000000000a753b507e1a96d77a89cc8732bd279636bb892d0114dd794496 +135500 0000000000000599a3a74d17b6c28e0608f33bf01c53ccf14e916e8ce88ed32a 048e2fdc6ba0860da0d84df0735b554f21a9e0705edeff5d40793857f72e4f2b 000000000000094a61e01d2545d7ea1275fcad177e893016fc26404fcafd9ba7 +135600 0000000000000a8e4ddad1a2b266bf701eb225296a16a32696e4d85c843e3e1f ef28b2b31e70ae4b9a2ebcd01bf007a58ec4c96efbbd1861e7a306b4e13c6e8e 000000000000039e2ff1f9e93f7bc6606782ac009b59aaeb5559daee5ac2e536 +135700 00000000000007cc2ea1690ba3271d5ccb56651dbd997ce54fe3ec0104df9337 f7b388d582a8d704bfe06061e4dd35ef425fb638be8f165f9e9fb973f13d86c3 00000000000000fa5dbe6cb1c8a9e9e7146d694719e521866498dff54320356b +135800 000000000000028b031d6a582956fb9ad96732b6ba5776a413e86765f3aa24fb b8828052174a610cc47def116e800dde29cb60cca089e3808af0e20312955d50 000000000000012e9924c4628a8cf8f2f2cad86192c4dcb7175e3f91eb0fc317 +135900 00000000000003dc00bc3d775c54a668a43bfbd5d65d70c766846bd424c9631c 98c6317fe2cf45a60b2d74aa3f710af72e1188dd51bc7a31b8c6db4462176442 000000000000008bde22d58c68640a28c4e521823f3d7c931f1b221f2360a2b8 +136000 00000000000004da0d6d69fd474fa08fe2ff3111ff1e9e01f72899dcd9d897f0 d8b835bb216729ae07f6982c43f1b339d841081e74404ae7e169f2f4562ef5f4 00000000000009a3aab1d1d5c4f1fbddf45a3c1d0484fcb5f0773d0755f42353 +136100 00000000000009c87758598ff5162cb9afe71cbf52bd8efda74506e08f136930 fa436315acf8de71accb230664b53a19a6a35b4a403fad2ff456d2ab4dfd26b7 000000000000025152d740308eb9622e7cf88bd76058fc6e3c881c5caaf82649 +136200 0000000000000892224bf7504dacfa3b74b2df00085d88da6b6fb2365e1ca08c 7caabc89075156f10f9373e0d769d97a87b3f8a76999e896168a4d1f520e4dcf 0000000000000862b21ab851bb559f902cb88268b5b9be45277013f39548edcf +136300 0000000000000a794b67b03d908876384977d6e185324924a21e2134414845ee 00ebadd2596540b8fe5f4bca332fd5895f4746ef11e57d8673a9e777b10a93e0 000000000000041e3f5a977518eef2717c0313db4546f74d50572626911a2513 +136400 00000000000008079751b074b5c8c5e36e40880fa8884e5ba791586d1f0ffc63 cf81fd6fc38054cfea32b1fc525e69d647aa56f521aed4fa11aa913399643357 00000000000007d8626314648c1e13c766123513f4a808d8f05bf1ec475c8c31 +136500 0000000000000184c56d3cbdcca53198918f1cd553ac49beeb9007f56bad1eec e6566c3e826527a8bd9d507d4c13058281b2d055d6cc10cd8c0242e247e0055d 0000000000000ab2cf3cedffdd0c13ac1cacf50228610adb5e5331e4fc004ce4 +136600 000000000000027d0c70f5409ce688b84ec6b915bb06d8002c4972c6ede4fb88 39ad13fb952435ead22bf9828464b5f1680d099eb87ef37bef05c882604f183e 000000000000047b7b1ca5869f16d313ee6768f444cdc4d3565388cc47ab94cd +136700 00000000000007e7dd440747c321018a8c10b3ca0388cfeb6d6f5daf97d187ca 5f41bd855b46c156ef9b599f892c6bc2feefc12520828a378c98ceb36dd7dcce 00000000000006131ff35e7f259b16c56e23b4541f21e92f006692e623b50e75 +136800 00000000000007f32231aafb64bd044b902cb6d5191bb9b8a0bddfe5c57e6938 e8bddf10d6ff51187b23a75edaddadf2c43b4af8fea7a837b5c6eb7f15341b15 00000000000006eee923de3c5de11bc21f29a831b3eee32a50150834b40eed17 +136900 00000000000003029803109a1da4c1ed6f60fbb48555d1e7e978d2d81aae8bac 33526f86596f7bf976102a0dc27e60460cd2d2e099d269aacd91f05daa0375a9 0000000000000436412a6cc9c3cdbcbd28b6b6223d274cbb037ac30d6f9823b4 +137000 00000000000007c0c0ed00db0a4b2ca07bac088209d8484dfbdbb3cfca52013f 5a0410db2fe70d2b891318baa95e2ec7189d18a08bc689e61d28a514d1b24e48 00000000000000dccbd74876d3133f574e0aa9585ef4e9c056ad5d09725adb68 +137100 000000000000006f44e492192214a298b72f2a3b733954da51d71ea9eb415466 249b5df707d42f2499227d11ea0a3b2f46d2ffef15de293962c776eeffcded88 00000000000004a50d6ec93e98bd1dab4ec133354d71313b4f4dd90a958089a2 +137200 00000000000002510fed4381ebf75de2cd6f9ed643772687843d907d4e205bb6 f5cae4d0cae01a44262a45c029819ed195f21f6f459789a0e7cc9cff67cc6616 00000000000007f0c28b4987e9e0cbcf0eca4b82865115b126a49efd6388ba5c +137300 0000000000000029d1565035dbca3efa218dc8fb219b1a868802074fdac9dc1e 9a91495f095f20fec56fa36bcb680cee400facadb56d10180e5b2a7c579343c9 000000000000038854ced3e312a83e5120df4e3ef88db903dfd80db3f7c71053 +137400 00000000000005bc9903ca88a90aceadd6683b8e2fb49428de865a445ed5f889 10b48f09e8c2f2a51d8e7f2440e628caec8f326de67728cb298d0578da72a393 00000000000006efd27c2f5bb246e7214b00715a2743791b0740e0a4482a10d8 +137500 00000000000004bfad597c3a381f1c60612e62d4b70f638a5e3f5099e5265d0b ca96abd9c4f27766459793a16c1c6997b19791db3bce76bbd9c534fa88e744d8 000000000000068dc2912e453f5ca068c5e20017e504cfb2b88b6918b70afc2d +137600 00000000000001d9899113a0e5e42f70c7152875dc777c5148e9828dd58e2917 8f063b0573e041dbc0041bbc5d95984efff6590ff4575ddb589a00eeec5ef1d0 000000000000095414d2ebdeadfb64442c2d151cc5c305ea4b3c12b8b0ddca93 +137700 000000000000033187ca5be26a76add150a8354ebc859e0bd0cd38438e6fdf9f 0e1bd31dce028c08b8aecbcf0e80b918391d1003b8b9373326c875a3a2f653c2 00000000000007695443ecd712438f3ca1984f75e9aabb20b93623d567ae4cdf +137800 0000000000000615bf1e85695a47abc79f6598e0d67636ddba259d59a0394289 962294e0f6664c9017ff483e7876893620bc8e4b78c3d4c8eead13da56bbefad 00000000000004e5ebc3d05f4bc4ffe6a7fad8cf592ec40650414bd5d89f3b48 +137900 0000000000000592c3fc573014e8aafe52ba2996a74733aa807d647bca2e2c27 7d0e173cd742cbd24305f79ea740da42bf6e1556d37fd2d39216ac9719ee2341 00000000000002a7e4873a8d4a2fe31366316b9e3e07d058f5458a2bf1b08d7b +138000 0000000000000044c7b6a5511c0b2ae64ec545abccac8053f31cf7bba23bb886 4d1406ec86fffa45190441990eca0a0edf49e611d52a1258b78a9f8b2d044981 0000000000000285b609d3491293ee7ad5e3fc3155d0d59b066522c752e539cc +138100 00000000000000876e2a8aeb2b4e5d6434993d1eb1fbcfccf02f66b40dd27e2b aa66d261c5985cfecc94d288c21720ba87b40f63993a332e6559302a9c5ce37b 0000000000000272f8911494998d3f9c29a6aa05261c1e79cb01caea27b2a76b +138200 0000000000000471bece4a96ee78419d7e93e2a1efdac727917421a491361c27 b024e73a4fbbbc3df2f15cb3ac32cad27bff4980d1eae95968a1d4034fc98ae9 00000000000003d608443268a16f590a16f3f9941a67f70d2f5a7597e1eb98c4 +138300 0000000000000093dcaae4ee875c5496318f0ef8fd23a8b24c7318b109e1c05e 7775cc218b1d9f07e168ec38f8c10828e8184ccbb44567385286ffb24ac8f4d2 00000000000005f66242fe5cf422c38eaa3fa3dc926d825a1265e7235909ca07 +138400 00000000000000d50c5191fab43e4bb71b3582faad0f483dbaf17e56df76f34f 47b793e05f412a5fb585ff664e9a274acd3aff4fb89c8c3cd79ccbaaa81fc08c 000000000000036f9107f5b73c26431ad7b1e979a1acf2ccae1d2c0797eb05ad +138500 00000000000005f8cac280bc20cf95982c110a8d3a7f35fc9cb308a454fd6094 b48fdee5e4cf7a7170e8c7a4cab8260624e4bd39b7ecd6200b479e69447fdee8 000000000000033595660076582f68eb77cec69881b42a0419355e911c13401c +138600 00000000000006a10da4baf032a0d7893df81358391f59b6bb2764aeaa0ee3f2 ec40d2c907c871ba3dd342992da6832944257f92e6c20e213c22fabd52cf59b1 00000000000002f740dd2f156bf4afc050e9fc03a64ce967c54826a18aa55057 +138700 000000000000069a43ca2439300d510b373cfcb7369f14c4becd1ff15bba7347 ccbbed92e06f68cc3c63b2d21c5d6018c3ffbdb78333e36087a93519c1973cad 000000000000020464663c7a9f664678ddb71223c510a4ca88a3ba19d3f39493 +138800 00000000000000ae5ab37a400b402db68422d3b315ed65717a950f2016f63af6 bc45d40b3da0f40756a5706a0c0fa7eab39fde8644f264f6f4d6b1a3b9b2ed99 000000000000096183230f0cffbd7c0b8a31e16548b4058eb7f951e6b1fa7c6f +138900 00000000000008e462aab7940f1859142e40294c5a89615a599d1d1a0fe85f30 896979f46c714d92f32cd0c747f099c18df0900c2866a1a96465e6eacda957ee 00000000000002374b363a1156b2716928bdb0720113f1a2a089673829c632fb +139000 000000000000032a64e8aea278290cd184efbb0a2516b3dc3753c2567153e5cb 617a81e54f6b5ba1f596799a62f86a15d5b2de27dd183c17d3d1fdf2099db782 00000000000005f03ae433e5a2c2e9096dd5591eac4f1bf9856072666fc9ed38 +139100 000000000000064574b9d3ee0ca49accff3bd2d1699f058e65f8c3326cc4c570 5dbaaeea7c98f853c54933c4d59a7d5cde7dcafed6a73b4f66a4bb0dc32081ca 00000000000009d9f016834c203170c53023f2e704721cdb7dac6dc71f64ccc0 +139200 00000000000002b16284fa2004b11508ea8ecca3d113c3243238bdf936afbd84 d091d0771a5e8c18a587bbe101aff73253b7b6e4a0e0d169eb94724512bb5169 00000000000007c28912e0d5ef3eb69710d0802c36e15e4d0de79183c28b15a6 +139300 00000000000005e731df0d5027a6fc6657a4bf93fa38b9d3a2cc1cb289d69601 5036fd1b256e2dd633e02bb0ce0d5a8c94af435745b92da73f8f310577de6ded 00000000000007644d1255977715204f38f1c261948853bc074eff7f9b9ba9e2 +139400 000000000000030f0da02d2dec11b38591ce7652464eb5d7e4ee7f8a808d1c0c c71443281d69a08ce018509985d57eee16b81567790952c3375958ab5e3d0d9d 00000000000005ea67f3f2ea5478a0280568b6a598f74861c341cd0f2ee0becf +139500 000000000000026fdf8e0f000596f77adfdb744888feb9e609e48dab05ebdc56 d94032928666a655c50d2f28389f7fbdfa4142c6394da8ac1eed6340556c4318 00000000000005c945b7361f257002a8624969038f2e79bef00ab4ae2a1b2f2f +139600 000000000000081cb4737f3099d5e06f1166ee84d72dae8ad1c0c6959520bd4c f20143c202c36b64de2ff7068281a9d089b03d5d7e71031e28ad8c98e7e2aa50 0000000000000360a627f09d45dd8de07ad27d8d6d0fd7610959eedd190b2eaf +139700 00000000000002b9765e4bce6db2b236ef98762b2d7b235fbfcd5e26365a7c2a 6820e9a1f7d6fa1aa0520ca77f0412155b24253f7a677c0508e8c999c4e0728d 00000000000001b87909f1a8d437f9b692f8b2366cfca8e775e01b3070f55090 +139800 0000000000000153baa61786ef35b82751e2083c5ab2779e5cd3e4291c2f64c3 612fa0428d0bf72803e5f54b707f6bf889ddce93df882188f4a4c8f3a993604b 0000000000000459a4fd48ba3d18e556120394675a7493f0e96bf4c5aebc59b2 +139900 00000000000008b66a4e3b498fb8c96395e101aae664176ff5364ebf446da80f 19859531e7030a0dd2ae6e617888f5aac2e94c476c664547c40c6bebad5de08f 00000000000002bb0c7ef25c7834ef6ea07d39c42b2f13c6007f80595b138c02 +140000 000000000000086e28cf4717a80066def0ec26c53d660582bd997221fef297db 6f0c10ff3fa3a9f85d505b7f015d33ea54c83d12c242cd622fd345ee86b9d2a5 0000000000000697dee71229cfbce9ac011b900f65702f62ccb09849f7556e88 +140100 0000000000000000bd4c6139e78aa472bfa22e33953986092e77cf60340a61b8 d1b54e807993e3e6ec055c9a354c5d26a18a93cc377c3d25b6c45a865c8d1d80 0000000000000817f0766cc2c4cd0c353113cdd0c5f642fb8aaeb92266d90cec +140200 00000000000005ee2f8222208e86d0004e409f59428b48089e12f9606501fcf8 9640b9c075bd784f0c956ed23df54b444549d44296e2d3430d884a91417e308c 0000000000000842471c25e45e7eaa9d35393ae244754d4f14f88780c0aab8ad +140300 000000000000010a68e772f6a0ef1081ce3b42d4c9dde1ccdd007cfbc5701ea4 e0648a42342e01f20fec898ffe39f5028c8c0e4d90f3e4098eb0ec415fd8167c 0000000000000458cfc1b3768079f9a1c85f3b3e660e9e596e5a610ce1193119 +140400 000000000000023e7d072ac2d2704515940c1adc16ccb0e35e7abcbe4eae0e56 bcbf28799b9c4b01ccc5a6a8aa17737240d9a40bdd124c7a8f3e2b27a4c80b5c 00000000000008b5b1de48a1ff7dbb97a6202816e9ad51218f0d129c7377167c +140500 00000000000002802ff884f55c426b552250dca82db26c757a6bf4f6a560cd92 7d506ffc6df7c0b4dc3c5ae57cd2d2dbdb5216ce765cfc92ca32f8d0ad75234b 00000000000005a2c2a26316474e47ac2f17d5f052a41d1ffa580c79287804dd +140600 0000000000000375143a36aacbccc7b1ea0b975a6206bed28fe13ac3c446d42c e459680a98a64c3a57c569aa292fdcabd7f05acc7316ccc4fb0916096abedffa 00000000000002b14668fc071793bdcac63ed7e73f9a09dea3f598d147965acf +140700 000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd 1754a038fd869a54aa6a8b2477ee7a11db3cccd4648d78c26be7e800a5fd8db0 000000000000035ef19cc6f38e12b5f2f6d8c324a016ad391dfc2e5afe1704ae +140800 00000000000001563993887788d113967fcf8a3b17f349e89b47f204e78688f5 e76823c638a74f4612ca1b459f9b5cdb942bfa8c7bce40b2727940291428c331 000000000000049c48a8ec9271cb30a20c3cffc4474e811edeeb9dad95742256 +140900 00000000000006b52211755a6550b7195f1783909ac296a4c932d779f837aea4 228103afd10244fdadb28b7b1dbf601bf9fa2c5c226276c894dfddcec320a4bb 00000000000000f6bdfeefc9f2a005da2d5038bea0ea36f1b1e2a6cb82c863a9 +141000 000000000000079c4c0873586e86365f5c003887bca2b5112f5a8950862accbe 08ad92b289a796ecb2d12c85a1d73cb9f1c61789166ba17690828332ac853bb8 00000000000001250c357850bfa91362957c19bf5f603c53d745d05cbb8db029 +141100 00000000000002f3b190ecd582b2e7edff6d9ffaec2f546f1466f53118b54d46 8092505030f30729dbdd0db3111fc4af748eacb3752f4172ffcec6f92ed614a5 00000000000003f19dc558e308478681c55b30a4d3cb294da3382ab68f41742a +141200 000000000000085673dbf5dd9cebb8f414b4f6574db7ce8e999d25c66aba95ee eff06bc2a34059d0b0b4f73822ae63684b7f2f63ae91a0e8b303670e019f4524 00000000000008ee07e2d81431081f14156d36bbb4bedae9727aa918352c1620 +141300 0000000000000357a0c7ae30afcd398cfb3769641774135607cd724b951f43e2 fad9e8c634551978e994df4f7fc25f9c337f609ef9b8a0d43d71d06263f33206 00000000000004e40640c376d944417a74ecd48de5252b72ee491e1a6d0d847e +141400 000000000000020ed1e5f2de15580e5a798554f140bdf688a43b41c5bef0afb7 29adadbdfd96dd801b915f4856f9a6495074697bf53873d4c2676c5562629f05 000000000000065c3b4b020dda3112e06fd5cb1a8e7e250d1569e3331a3b59b8 +141500 0000000000000646ce82fce0f8cc4feec9cc1d2558db3e73b4f3086713e7d69d afb25405c8fa0d48e93f062297b1d36088061d598c9b12a9eb5ddc9d12707aac 000000000000007e9cc22a07417a9b4f03f533289824f8ea9ac3619dff4675e7 +141600 000000000000065c61b62aa25f3119091f4c51530b8c41ee6ec9ec75a85f5652 d07c384056e6fc46dba48c3896044cab34aec9335332fe78d154048182a9262f 00000000000006999c9d4b4dd35a5a94481121ac2d2e38bd6febacf29e865e36 +141700 00000000000000e5749d915547827d7be51b845cd921987aaeece329bbea2538 ae12279035d4cf6e4520c0a26fbebd8a14a98629c717ec9ee37cc2dc08b1e99b 000000000000049f8c8d73171a48315cb9782861071116619c976ff8b248e74f +141800 000000000000046885d54d62e1c07130040dfc8a1fc0390c6b9fe574cfecadc0 436136b36287b4d47120756504e87c73d388e94e94639b4ab6c032f9bbbcd4b9 00000000000006dd709338ae44d263dbbb3114c3bd07047e8ff0f1af0f883f6a +141900 00000000000003b440b94c9487a6c1a4a50e4f8a1e9cbbb46febf8d9c05a0e6b 2719851bd7e92efe8359175c9fae98649cede98ab0a76a2c51e81677161a964e 00000000000007728b0bd6579ee146838f6a0754c646ef51a7315c06e1846677 +142000 00000000000006379826f5f10cd23739b9c29f87ca10f199f9f4b72006311f85 ef43b7d11a548a784fb25030ec5e39bccb9c301534d7d2792b60bda1843911ff 000000000000024966c57274fd19fe22bd4d03326a4e64a6150e496e09fa265b +142100 0000000000000599ae84a9e36af3c3e00a0d6f8a65a2dcd2038c7efb368858df c03447b725c0f512e6750a5199983e5d360d5992d8fee1956dc115ab853e7a08 00000000000004233c09c1daa2411f7a79a02bc919a7932d7b3af9b3f7e78873 +142200 00000000000007839bb5c112322aaced4fa54a83b05de0cb0629eabfa307f300 bb74f63592d70a36fd5d681d48d9d8051e8c621d532eb9db6eda008c8eb246e9 00000000000007642f77ed5ed0d33e2ac94ee463fe26dae4c79a7ae928fba801 +142300 0000000000000556b2e29e96e71964e99ab49e6ce1b25d2040e63ff9b1b1bc03 f01dc7568466e4c3551cdf7f0a277e7762665c5a9b2803764efccaf8ca4bfabd 00000000000004528c5b2d8a160d36ece8413b58395c96346a0a806ddaad4b3a +142400 00000000000003d6d4c461e1800579b685413ff0155d0a779c0acc89592edf38 76ade742ab037ac79052c59444f686c30637e3aac535087ffc0b8f5dce8775b8 000000000000005d398bbafe4345a1a602ec557a21b3827cec0926bc9cc1f721 +142500 00000000000001efa43fc0052cca77939f62c6f81079e6a157c9e5c58d68ad7d f4f12f555d603aac85a02a960523abd7582c7b328742a5b428b2f14249ad4f3f 00000000000006a3badf6ce2357bb38b190028519546c39830050164069c8a65 +142600 00000000000008d78e7a6e315b9ef038d18353aa0c66191ce4187de630d68c4b 16c3f9882e41d2a3a02a3687e48fb2ceb26ad0dac6599b05fb857a01da8dc52e 00000000000007d2142f5d95005afd71e6f8a2c2b8cfef4af8d8e5c3e5ad90ea +142700 000000000000062b88801f9eadfc2c9d354881fb2e2fdda1047363ba0794e435 cd52b2e61a41c2d8dba423d4b8c291969e399752e952b7f33f3b1e378acad781 0000000000000359774e15758b00dfdefa078d038704642694bc5b63d64498a4 +142800 000000000000073f6dc66929dfc124663613b4c9c6a589509d2f004d80d17881 36656c4b00634b704f708fa74aef01b25e9d464c153e4539a7b8d24eec6e8c1e 00000000000001b3e41aa833358a2b3b92c4a0c746b16fba217e52b594c9a313 +142900 00000000000004ffd0772317bc59ef97b97b6434a9fffe7a24927133774202cb 7d38d97d7e1e9198e5962baf5eac863e8de092287b386f50c9f5c05e4ec62638 00000000000004b48de7a86e1e473e169fb7351f6e29efd4e320ec597c6b3c5c +143000 000000000000026bd2449a46b551c82b6657529d6cba61dd842bc1ba0cbc59f8 a26221b6d1a73a090683a8212eaa3beca31b7608d46ebc7552a89ea2b160f550 0000000000000654fe69a041b68350b0b6989c142411bbbe92271b920f3abe2b +143100 00000000000001b20756a70ed853abd1c08eb5dcf56d78abe527bb4b626ded5f ce1ba780b82b0cc1bb2b36b829e0f58dd6acdb0cb5fceb41fbb5c051ee4434be 00000000000008f5921e612a7fcf13f4db7d10ee307a52abafe1bb9a6d4672a7 +143200 00000000000003e6df417406519029ce279e08ddbb251c6161e747ae77a35f95 143e994ca8bb34fb6f987fab82eb58b96b9cdfbeeb46464007a05493e1f5f639 00000000000009387a5f3bb47cca7eeb945861f817c0c28e5ea310a973c44300 +143300 00000000000000ff0f6eb103c0d187de0cc9501de07041a466ba8fcbd6e52eb9 44fd6f0a5e3c090bfc7bc4021107d83867d5bb7e97f49c64f37c0921542df821 00000000000006b23b456c55be2b64a9012b99bb950dc40e5857684a9e43dc34 +143400 00000000000005e12d1978728b97c85aa217a0deaff8864cd978046cbbd7a3e2 abe09f5b79890340d62f8c046939495fa218eccdeae84a6f391588cfe06db342 00000000000007aea09857e7ac52f612ea35d24fd09e616c58b65963da5dd2f5 +143500 00000000000001b97624f84f87dced4eafc0c372d75bdace6cd6fccfac3d8fa4 3f3443ee9cedc85beb8a911296fbccc2ac0f73ba9309741e4b2b0baaa6060965 00000000000007b79a3f447e7f2bdf314d5aedfc737ff6d546c9b6ca8a3df5fd +143600 000000000000076d6e1c0fef188ae125e9860a5acdb4d8aa03d5a4c58970b3cb 0512a372a4e02f812edbcc4b4c9ab35175c4c175fcf2e7e67d7375db0764c22d 000000000000012f7d2eaeba6ff1f75d4c2f3c9097e459a7244d50d9776be815 +143700 000000000000003b6cbdd3db840c500faa8d0837c534693e99f27d1b59e22e94 85eb99b03c4e146c22111e89af7384148dedd7341f3234f34323261f6235fd95 000000000000008be21a27e625b52c905a401fb4879157a9070bdc91ecf050df +143800 0000000000000924f634b005286ad2832ee74f4ba26424f02d29ffc250c419b5 0ea20905dcd8946c5e5b1cbc0b5e6c27a4bc99c319c2022de18e8ec53e8239f2 0000000000000619cd935735da7b994e3f72965b5900a890772007978e0933ae +143900 000000000000000ae423b106b8d1bbfdaadf2f87d8cd48a3ebac067d583e3ef3 f64bcef1c7e1c332e197d0c977d1892110558c4005eb19b34fec59391c46ad31 000000000000071057d0c76540838539149891e7c572fa27a83473aedcf06e09 +144000 0000000000000681a73f1bb50454cee419048d24e1091bcddadded89df53fd07 a2aaa0f0e3a5fc4befbe6cc4a53755578aa7216204d67b20ebfaacf43a784967 000000000000026ba4c837d96f9f1260e64733054949f22d9189d27003c10ef9 +144100 0000000000000796aee008bf590e966a40b03a4bc1ed637fb99d4511c27abb31 ade58199cadd257871c7b23ead65ac6d5818c491de3604e677068deb8a4635e1 000000000000041a13d8f166ba5a9f48678bfc43bc1d276946d4e8a93a515118 +144200 00000000000003527d9f089431010aeacf01da6150a1a12c8366b88e3eefb3a9 92d0ba3d4b0491ad6ccaad4b6368cee3038788751ddb9c03f3b90f289f8b3ae1 000000000000035dcb8fe986fdfd3ec27413a55b8ed7308e3e9bda749d062afd +144300 000000000000090f7f0a8ffa5bdcb62f35ce70cfd1353413b95044418ee387d2 d798a4f171cf9dfd7b627925244991b4e042ccd0dd131736db2393591a341ad5 000000000000089f995336605457580d0665d84db0fdba8635dd423919226a54 +144400 0000000000000152bdf5ddf5be78a058232ec315de6c6e0056db9bdfe7db2f4b f444c185bc95de2c4c617ca87fdb6c6342a6b4ed1a86305f3119f7a3f1530397 000000000000092cb95b3458536d6aeb1b64b713b720d6fb097c7188438f604d +144500 0000000000000050dcb2f323abd12b5e1c11533374856e7bd6b1dbf2d611cc8d 41ffc93f77f28ce4d4a4801786574de6a756566bfeeb6a225f48020b1eb7032d 000000000000091acefb80979b3e617401fe0ce0e3cc6a5fd7fb6d990bbaecca +144600 0000000000000940c5587c40b81890ced5d4d0875969acf8b82d96623e242fca 72739e16c01f673aea41d58fef15444f344665bcbca2e6f80a317262dd273129 00000000000008401d72d21e8d1d75dfe6ef237e3a4ca64c98c69fdb2ac985e5 +144700 00000000000001f04bc313e3a63cc26f9799ffd49b7af4729cb1074ff8ec613d 8d734b3e8ce0db369903c42d5661f4dc6ef97e87dd6b98eb7363a0778503586d 00000000000004c51b434a4a1ef9bbedb0ad5e8683fb798e0f72422b37faee4a +144800 00000000000004f3e90508470e2f852b644a194d32044807827ac49c3c2a6b4c d6f263a6d8395d65a98d586b44287331ac1acb25232b81c92c057208764a0366 00000000000001f632092fba2a8586cbc4d63cd4f0c5118c365278e370befe01 +144900 00000000000003b3eba8d57e7d7e4337269517a1602f96685a34d662002cff6e 4849607428b47802a6337cb33e96d862414fd0795f393287b792110adbaf89ab 000000000000054b35e3d50f29362d86952ed319950c4f3b3175fb65f3dacd0e +145000 000000000000087f9aa52a08d8ff065ebe1b6d12f03390fe771faa8720eb96cb 45fc525151d08301b7ef88d3fbe5def44621456c203a7a5bb07d3d35ceb61c58 00000000000001d3a873c3f3246937f55e49ac9c9d9498ed4c0d9c45e3674a9f +145100 00000000000001aaf5ed4c1287d6d4b010dbcd5887826210f84e33d1273cd488 85be17decb69066ed4b45ffebd525d98daeb2bddebff2e25b0acb0df903bb7b8 00000000000007edf2834cc8f01762fd48a42ef4dedb2d288148c603ce1557ca +145200 00000000000004e4020f77bd41e229640a18001d4e2f5bd2ea7dd2ecb54de103 b13cc0bbbb720a356c0d70d4c159e87b6504032b8f1ab140cb476da017f1d17c 0000000000000587ef65a1468a6c17d6467cc0fac03b2516501c18ad0fea225e +145300 000000000000064b6ef6308ea85842ad1c71f0931c25730851217a5df7306369 753ceafb76377c0d448e1c91769ee0317dd791de3221cd043d35a642729febbf 0000000000000039b88898a06eb42ab671fe3cc169cea02385aed87fe0d70007 +145400 0000000000000374c21f2602d4cd5bd7bedb82f621e3408854c7406dcd15c3a9 ebe0848a8209a9c520a4dd6409508d0150700efccbe108f8b31b1ee38085d3f5 00000000000004b10354ff5ca259d87fd9f16b3647b13d380806bb40904abb5b +145500 00000000000008c30b38cfb1b2970cbfcdcfee4b8f0514138b296053cac4ecba 395d3d947104b36cef98b463f870286f4dbc6fdb779fe913df725b252407b19e 000000000000095ea79944089cd7202089e8e04daaf0d9e802ac2124a9190491 +145600 0000000000000468163355b4c2a73b4470de29873f5d8be1c3aaee74a8a51d6c 2ea3e106dff642c825849812460853f3a344285261bc24ed435e8fe14aaff731 000000000000035dac7ad511b99006fb7f2d0cabe4af281b168b76527e00279e +145700 0000000000000410e3655f644590e1115b39c70f8190104354fc84d17bcfa026 6ec7330388859996837b9b358fc17e88c1b0bd2b0448483663391bf3782edca7 00000000000006f0b37f269249b306eed08ade4d7dddf80fafa464a83f232217 +145800 00000000000004c055fce46b07e3917bbe8346521f44042afd52b8a7606db142 12c07ef53195d13fab14595101245e5ac30179dc0ca178f4663f61e6d9bcb471 000000000000001b519cb377b60f2ba846c153d10fd3a46fc4d3d0ab181e928f +145900 0000000000000639fd67cf8f1eefb9dff5bd247edcb65c8f2548622aec4eb9c5 56b857ee379cefb7b6a3b1c183a5c410929af9a1f79602b4d94a75dfbf0ca5ef 000000000000059527d3325269f1cb8e6577e10ac6ed7b97173a2621b892dabc +146000 0000000000000188cbeebda87456f040370995dc11eb3a1e76b1577b6e0b588d e6e9f1acedf33968cd3e7bf134efdb28e48116f60005b6e0ff957474fe36c7c3 000000000000036479e4b26fc6b54b728f505df6ec956c68c34deea22f5f79ac +146100 00000000000000c93a89ac198089d50f7ab54a63e663803ac95c073680504e18 d3c1579eed957e3f837906aba0cb1c174149c02217481e966448dfd55d140b4d 00000000000008b588be230f2b09284e9e81c8c1ffe416ceb4d316b649e8a5bc +146200 00000000000009063ca24f2b0989a239ecde876508de23e86a21658f3ba44d10 268a9cd03de483d412146f10dad5ff690dd3676f018cd9fac8953585d4aaafec 0000000000000949e4a89fb9509c6ef5d429a304e623ac4f30aff3634de875cc +146300 00000000000008aeb3b98261e29d4ea6b5b3cd7ff291af95db8806c5bfeb909d 19af5c1d04f68f567531a76702d6c7a33519ebbe493bca91e8315fe5a19a8478 00000000000005b8a31c97b703fee3ab73b22b4510aeb360e14849402ff2ca80 +146400 0000000000000678bccaef1c08e8acd5fa4a2a3bd32877146591d48d68a86bf2 f06de4baef8281bdc4586a622e42eed32602bfd15c38564a13faa5582bc316cc 0000000000000569680b8caa548b1d9b2ab09892aa207dd8f5bde649a4873a77 +146500 00000000000000e3747c3c1c4b7c409d25c706f294fdb7fe3ccecd2917434499 ec92c6f941428a505746eeddbf2b342aae2bb96f95fd268bb932a875c0e0c6a2 0000000000000131cb340b4f36a4f259464538f5aa0ae08f1504f3e5d6c384ad +146600 00000000000000db1538c7b8e6b8c6cd451b92a831fc60b1134b0a6d23f8f64e 71b9987bf6ccb05674b4884febd5f2c195b0e116a9e16b768c933a4626c6bfea 00000000000001123bb3d21abb660c27b3dfc3153e63ff16802c55b6738231ea +146700 000000000000033d610725cebf5570bf40573bd0f1f1669d85ce65d363054b5a c8ef0e569cd003ea1124fb8725f94ec6714a4aca581e987427e2fdc6f41f0b5a 000000000000080db9365552d4982ce23bf0f3ae450f265edb6054162cf9bc5e +146800 0000000000000638177e7af24cba523a74e5ef6ed6f6db619cbfedadae6cb458 b02ca52e54a680fcb735cd9f2733ccb2c004cbd57ed6325428c1db95f5597f12 00000000000006435c0b8f064702d41a952171f355fc55a6b7e31ebc0d0b8f20 +146900 00000000000001a61d473d68940d022af01968ca2f72fbfe5cf225db4d7d2645 cd99948ec6d359ab960c7b06c2d42e936f966c8aea75b750ee3ae570472f1c00 0000000000000675b088a335a9ad5adab1ec0e505fe2f14745ecb841bda51ed0 +147000 000000000000096aff3f9a2090e6bd9f0d0c545c9190914e3dd767fcb24ee284 695fa7454429d145a8d9203cdc22439f50f77ceef56138b5d86e654469ea04b7 0000000000000851df3e47dd63deed846858726c47076ddf6f5ef98703132d1c +147100 000000000000034e142e71c5ae46e41169f524678a3d2eae1e8eecd46801508f 473964b195bad3824c61c1e112c5681ce3f407f091837de16a6e0f1df36c7299 00000000000008f3089261d957fc230884400d6e070c3563563d1a2d4a7d7b93 +147200 0000000000000291c826714cd1e454aaf7cdc67eb890eee2d1432d0d233a8acb f20af0d1a9109e4cc3af52423755d71dcd38230869f718eda822d8889ed3897d 00000000000006b632f2e6ed515fcebd6e9b9ccb3f6e35c8e4eeaa6ceafc649b +147300 000000000000014690dde11bf076c2124f5227fbbbe15ef1cb1d8823e966693e 7e98359cc9b3618f1990dc7bfd48438a9cd74eb445a92c524a8bd916d374f37d 00000000000003ed3cf2e778967db11534d10ba2c656e2ff5d0b3a5db34a762b +147400 0000000000000821542f1d4403a8ddf935784557ebc8aeba414538062c481f7f 69a640c32a42c0059bd7f034c21ab77473090f513593a74d68953f1bf2e60511 00000000000008ec4d7441d37b9099116ed172d7ea3f45f90088adb37eff21a1 +147500 00000000000005cbffd7621681c66f7da5ddab947c472743bfe05b59aa9cc243 99af91b5a19f848868bb580d8e6300bb4114907aaa441442a271ab92a028b303 000000000000069a337dd043c590475b9eeb1c52387712d628192ded078db483 +147600 00000000000005fd5ca8892f430662b392edd5b3045cbbe8e8a97f83dc4483ba b1057965216eb798cfe341184d916747ec52fb08d1e01ea954236148bf7cb372 00000000000000f3f0e9ae40c7f1d6e64e3d91ecd223ba54d223d12fdab77edf +147700 0000000000000649e05bc82de9e3f2fc7283f970a14184882267cd62ae57bcdc 6d60c417728aa0eaea29ed00aeccce4ac163d1e71f4cc7cda99808946b7a0d5e 000000000000007f6aea941d8fdff215df78faad6a79c2a74856d91fe1cad780 +147800 00000000000008bd850507bfad1b02bc9fd8d2682caa197a92da93591a8f4d03 71cdbd6623d5afd757146deaa73d242d0164f0b6e33c9c34e48d6c9a5816950b 000000000000059e9b1c168dce59291c49408855c533693d9582708be31c0a18 +147900 000000000000079faeef6ef108e0dbdb888034be78744624a29880204a5316b1 7d19d7cb34360d2d56bb0347dc424c9a3482f1a0a5e4adaeafe3454cd7ca5708 000000000000052bbe1375320b66a719b62a68a7ee0dbf65480a867ae1a5d32c +148000 00000000000008be94b219a94752bde6a6a1c5b9d72abf2aaab53df7d93c5fa6 3dc4d615d38b4f6a808f160cab57135753b36d3882c792461ff081468853c908 00000000000006994cfacc4d85ed1c84921eff8673e4463ed71a1df22ec6c662 +148100 000000000000015d8bbb783256280108e05e03bd508672380ee0d2ff2b6959a8 26e48bbf79bf807b41010d3bae19f9bc99a360952e621956370de96c59eeb271 00000000000000bf1b30fbb2e539f7b32f781186a7ea3eb4654dde8a0e99b1b8 +148200 00000000000003c33dedeaa37cfce91252304798ba6a68a7190dfb53305b6b48 61f8d12c24c2cccc9d8d454de968af9660f1cdf177a8113449bc58e7b44f9735 00000000000000fc1decfbaadb5f0c81847a2ba37fc09bfe6e7fc9428bc232f4 +148300 00000000000007fadc00cc69e8a013b4895dd3ebb8dd7152fa6de63786b0837d 658977df93fce20cad7062a7e9a620c3759a4307b6edc83bfebec68b5a603c98 0000000000000968e8a653326705c3a14a7b7822bdb28980e7ac2f9e6a6d30c9 +148400 000000000000077463f7a83ccd863c5ba76cac98eba531866d4dfd656b2cdeef 444499aabc99e10fa6f58daab48f44b87fe0cefd11f638226563e30e34e665ac 000000000000063bd910426b96f2c92eb8ed15049e12bb1fdb286eb08484c147 +148500 0000000000000989192ab469d6bfdba1c2599957be2a5df6c9bac74bd1b79416 99e9e2bc83dabe886b2be55d5c7dd262ab05a26398a3336fc8cffc4de77747cd 00000000000005ea9cfe5cac44acd4441dcdc907c4455bdccb1b48ec4da42dbe +148600 00000000000003011c6a1e5c8c06a706ccae42eeb3cbe13484ddf4ea8e363410 fa0b6f807bf486e722ab44675151989549cb2af1adcef141cecce2fef43715a0 00000000000009ea381e6209d1f8b1d2c5be168e8819e443c1cec82b8259c96f +148700 00000000000000c4b758080af1b8d4ddd61e668444a40711a2c99a5dac78a1d7 df16b3664a0d83a768d93936a37c0c13e71c1ca371fc285ecb78865b65f76cb6 00000000000004ac291461990445b05dc535dcd14b85720a373dd252c320eb88 +148800 00000000000008371089fddbdee1f7cf580d98e64c276c649102d2ab95fd9844 cba3c874d563638fdcd3b8a9e60b1de78183e7044948930041c39e5aa7edc094 00000000000008e6557fb186c072ab5d9a557cc6304428c0d47382bda5252390 +148900 000000000000070d7363fe2a0f4ba2a1bc8e06363cf27446967c7e6dd758a9df 968bd4f54d84d61d227298dc7ecf74215498766cdf4109974b6549375e954f52 000000000000057e3df7d2b33cf99c629d67d66167a59054f7c97381caf9de7c +149000 00000000000003365798631f867fccb0eb0ac014e8bf2bb628d9e7a4479786c2 78e2453b544c054336efc17236f9d04480f38e3e2c8a5b08fd4efb04c25cfd7f 00000000000008e0d6ff8460ff187363bd4071cac24bfbd17d0e40f34bd47f8a +149100 000000000000091b548dbaf642c80b6ae353f321afe30516f83dd941c13eedb7 6eb9598bd42acc8e41f9279eaec9a641077bb661cce65eaf185441868881ab74 000000000000067f217e1c1bee955bf8256fe110a78dd1ac15ed611086b656b7 +149200 0000000000000a4cf5d7252cb9385c8ce32bc1cea6536b9cbda0d5949fefc2f4 f43aa0eed697d2b65beb80e6ec3e36fe8651935c40f0c9d6316f80e9963a7b60 0000000000000136b4adf87287cc86628ec45e0609cacf3ae804a439a0d47a8c +149300 00000000000007d08f1e55c0fe4abc35731e66cb655067e4d5ffa54114b283e0 1f7d7c97609b642912b19472e0cd1626bd2f0226608f0d3ff2c38e31263137e9 0000000000000a4115ab4972efccaa2dade99359eb6756da307d031d33179374 +149400 000000000000056edea733c1998b955596ca98163d66ae3fce1ca65dc9c443e5 b4ef74d5d60e541f8a2792e0412135b4f558b73bf28bd366635416ac675cfa65 0000000000000178f0048d677b859169a4066bd76ae739dd976e3d906083d4a1 +149500 00000000000004886c1248696c6e4f25bd797f25761e4abb985aabd19e5960d1 4e901d76d265cd03c5a3a21e087bff1f3d88b75efaf12fdac68285969a729f7e 0000000000000144ebe0936683e9f949c2270ea91ef2a0b0070c8382f7ddd90f +149600 00000000000003a7a772014c5254827d3ec98a2d83dbc32fcd6c4ee2636f33b4 61b92bd3f1a2580e42776a430a015ac4b29237aa3c56e984b73342bd71de1bb4 000000000000028a660778d25655072155cebb5c5d2a60089f4118b0179b9bde +149700 000000000000038afea44306c329b1bab7bcfe5ac3ff0a6c818bc4ed7e0e8887 70fdbfc1e518b8b4b5dda7affb71378d8f43372f4278ec81087780ff2e2e0d56 00000000000007cf783b8fa2ef3e3fa4b09831427ee6e88b1ac72ed2fd532055 +149800 000000000000020f1438e884f93b7c6196c4d1672ee875a4364f92e62b6c4bfe 209e027c4e2fab596ae8c7e593a6da7200f7f18f74d09061593a6e5c3faa6dd5 000000000000039fd2c710ed8db5a61b0b21ebcb04bb5bbfb7d9d57dab42cf29 +149900 000000000000075020ca7abce46cc1d3425b7800b88c14b4503777750eb8450b 605d8d1d5563a46df216e712fea1fcdf79b607c0d0d7269a0992a4a6b3d37496 0000000000000a6fbd3a54fe92acc2f9cc05a5baae5617609afa163982ce1b49 +150000 0000000000000a3290f20e75860d505ce0e948a1d1d846bec7e39015d242884b bbea6ea106ca5fbb26774fcd03ec989102fd01ad3aada5e17e6dc9a2273caa52 000000000000006b1c90f01554b0aa0b2b3adbe339b175c23b8b8ce8b503a89f +150100 00000000000000b0fc91f5a86e6a9f9273574a211ede5bb2f58659d6977bd1ed cda4082ae42d9dbd52b4d5a036c763a365c39d5147bacb3b2663f6dd855474cd 00000000000006bb4096a302361fbb92df9458d0bf407f09bd0f06f2b6a18cd9 +150200 00000000000008975f64af185acdc482351b1b5729b17eebee9d3ffd539d1d50 a99970ce92d2fd7456f906d192d7219232a3ca4983f4eda0aefa3bc8a29d276c 000000000000026c50a576b9eb45b0d31a828c9a9728de7a639bc7b97f4d1f5c +150300 000000000000073278e5df06328f662f2b9e12e527ef0103838aa6a86cfb72ad 28db0d8df6dd8c1845162eda44cca578da1ba5c0de9c8a81e77b0c329766a553 00000000000003b6feea62574a8cd33bf54d646b3cc9ee2ff1b45f44be27acf6 +150400 000000000000072168b1601c91f63ecc92aed86110cbeba266397958d94fc7af 706c73771d8f3bc35a47f557b20282b280dcf32081589820b501738c2f3a642f 000000000000059880364664e471269a7c84af6a8ac98bda07debe2a9a0667d1 +150500 0000000000000112f644be7e7ee3bb716017d729327bd196139a92446fb71f21 36865b288c94fa5cb981b0626ab3e15d74e65f46d9db636b4c407b17f1d82c59 00000000000006862cdca4523deef46bf7e850898d113f11b8abc937fa8f02fb +150600 0000000000000727ee977ff20530096f81986b5e9be3b6f917de13991d36791e bb94198d4bb9f079155422b590320bf9bd1259faf5709e424107896bb0930384 0000000000000899219e7836bacd997db59f3bd23aca51435d9f29e703091769 +150700 000000000000026434e94d99089e01f3b81ed26cb9017eb39eb34b8210b49817 bac146b028763fead2080f7832764dea385b94da0071721d5b09e87089b0c099 0000000000000645b16c311d553b38ec02a8b7708eb3925d2bf98570a248ffd4 +150800 000000000000080ab2d87211cada3fb5033be8d63ddec3fb8f27ebf1f57bdb96 23cb86f84b2a93371d24408e4db4f7519e39ac41835c93e4ed786f0843535004 00000000000007eef15de0b26587a8bce78e9083a7e70019bccfc2b1414261dd +150900 00000000000007eedff11a5bc52702fcb403575153a2b9a03493de676af06b43 a2b8d5d512fcf75664803dc8e649482cfbdf9c110cfa728cf3b0f39887019bb6 0000000000000103126a58ee1574a008acd9ccbf0e02485bb655ec1c410923ab +151000 0000000000000a6331baea34235c05eb12ad238a7a61c878cdfe348e03608541 b238edfe5bff1cf4a2ada0a0fe5edd994f01138828c371b8c131206d35a26d58 0000000000000282eab3833388380d9c1be207a98b243b6d1c36faf02de5ee4c +151100 000000000000047dc4f1730c3f5c1004170c2b852802c59000c25608204ec72d 3f722d37c948658a258c9264fbaa0000ca48e4e9eefafa47093b6ac0121db3ee 000000000000027364fc1849b6970442127ce40919dc1981822527037f22409d +151200 0000000000000b9746bae9c3dae632c01ecb831fc0a46097cb5575be4f895885 0ed22a7f532c49496c9d2dd9a77c5cb51ff746c3131c5fdc42395e8e76af317f 00000000000006b1fb39602840ddc4ff3289e6c60b75102f486926489e402bab +151300 0000000000000c3cc72c5c70d2ea33ad6b168887ce45c7c22eeecad1194bf165 59cba403b08491d415d3fccb9719842af6a784ff205f8e4e38dbbd4d371cc58c 000000000000064f01a001b48a36257916e60b265ae3cff31b641bcbcc300be3 +151400 00000000000008bfbd7bd9a3e2d84e24c837afbc7382a4095f8d6ccada23426b 289441a3e012ad2476d3fd3fee58f7f1136fc2b324917d7f2b7fc94f0cf0d320 0000000000000599ea67e3e529f6991a95bef797d45d44b87b777f86d177f12e +151500 0000000000000c605f3b541ff3f37ca0274e325faf63a0b853d0824803a42c78 9b71c75944fa74660bc3f048f142c84559ac2e5e2b91149bba5146224628fa19 0000000000000b62764af457d7028b1941edd97759d80ba13d82bd6383e2232b +151600 000000000000061d81c1732f2dbbca9463b5327a9f51e76257c9263a918e8351 e523c982d5ebe67b770abf1eeb8398784860fa2b14350cbd52f6da6ecf95482c 00000000000000afc7cfaa9bd8b8300c1259b8ccb34784811bedcaa934b37954 +151700 000000000000067e9629527909e980229f6eb4edcaa1d7141ded3a572741b307 1bdf14c871028116ae283e50fa50763bba91e1497e0f54bd7a50737e1742876d 0000000000000c574fee36e822ec822e3b13d3ef4e6084afdc58c2108e8142ce +151800 0000000000000dcec83b40648e1d84fc698aec2f4af54d945f1945df3fd85aa5 b9ed80f1b0a52743e13a0fbd6506e0af7fb4665ed35b8adc838d8e91a911d27f 00000000000001d383238134acac79c87a8b3e2fb197d27aaa9b003771e02f2d +151900 00000000000003347276a7a1d0978a89ebbffb46b36f6bc197b2b98da1c6fd7a 7e5bc4a6fe090d3aaf6926b53219c0ca34165c743e87cabd5c7c54d0517dd13d 000000000000030ef51754641501fdcf5d5c4c2750a9d7f3ce0a8612ba44143e +152000 0000000000000aca2b3a267dab498adc48afd15b60cbf21fa58dc26c86a6dc13 ba5c0ee795d73fd6f5a576146cdf4a7b379869c8c03ec15bf0d1141b54436171 000000000000049f8324c2da6a67441d11b6d3303529354351a9bdad9d4d8f1f +152100 00000000000002c5a588ff1f9323af5812c316b16406cd1bf0470da6b6444137 a101d256bff8bd8a0d1bfa702c65892cbdd591e25467b5ab728503c9184f31bb 0000000000000ab794fa292233f8f8ca45c4efd98f16430798c374cf21079a46 +152200 0000000000000359df20ee40fd4885f5b0fa113c742fb5fc9327b657f7f1762d 58a8f293cce9bc4427325addeb825c602693e62029628eebf6a031062a33f305 000000000000000eb15f10f3bc37d0033eccd66147f7914e7c5804d4f68a3b74 +152300 0000000000000978f358cdd0b63da5f6c8a6a973fc065845768c352011b245b8 ee41f9c04fd33f2a055c5838ae2193d66c1d8a214e657065be871c3dc5697a27 000000000000049227852e112525df4dd64dcd52ff34db1f803d666e0e593fd2 +152400 00000000000005b72ffa18135425956ed11fc56262622881e876e2ce33ba6ed8 64b62b0cf052d6c53701bee4e78416fb934dceff1ec64316570b38cb936fc5a8 000000000000021de21881a375823d20de73719a12c9140517d7dbc5d34b3136 +152500 0000000000000d96acf6528f443ef2c4695a1f54aa044f315c3c176b78bf1443 c0e4858e2b5b8a522267255941ab52f3b4a4f934f1f358b87bfb27d282286d4f 0000000000000c695dd00019702cac28244192faa2baf641810904280dc4aa07 +152600 0000000000000375fd57a15993be226e0d45921ad4b994893a9c931f0e5468c5 237bc52ef4d3f445f281bc7b08250ebaf839f11db67cfa07ec227733292b1ca2 0000000000000cc231fe9ecb8b5f3c7445de8772d50b48f19672c9db5f5f3d19 +152700 000000000000066abd06b58dacb398c5a7a43594104fae26f7e3985ccb7eb68d f56fb8170f0852090005a79c27e1b6d076e8b6d6c825c7801116ae4c56393ee1 00000000000002b777f713b5d0f7b6d2a92ba9128ff32af9b3b1cf3c4fee04d0 +152800 0000000000000c7b829c5e828f9f764506916de42a852b13b634d3419f2c91ce 721a5961d9f3bf1c4b7f7c853579e032fe0e8f238746718c2f11f93c0fbda2a2 00000000000009514dc2c3b44b1cc165bd297885bf35b8cf0dd9a5c9e005aea2 +152900 0000000000000344a66850f30540990b96cb6ebb70a3c3853b496e5a47d816ab 5ee195f2fef3d5d5c0ea8197c9a5dba2797b61ee1cb37833a08c5726e4260f61 000000000000006a567ac62256b4b46e3e8245fa13500e15f180e42f3fad11cd +153000 0000000000000bc97a18a07ee50430131ff934a09e550424ad85726ac42c7ab8 14009d48e3efcc2265bd0161328b138169a31f7b95f457ccf90077109a75e2db 00000000000003493e4a221c3ea865c9a195b7f03f1dba87a2f28f67ec78ec63 +153100 00000000000003bd82202e8e858b120c5c8ac4c02de4340e6511ee443d8028b9 4895de7ff0298a62141d5c8e21da3f0d4c3e8e4b13f2a98797e8e4cb7e08c2d9 00000000000001b9146aaeac17e1eb174467d0c226fc2c149e42c91202d4f72b +153200 0000000000000c2466dff91636c9d774e3468f5ed942e15fbcf037eb9cc9c2ca 2b5b6cec81c7912cb96f1af169eb35a6fdeb85d9bd06bbb2791bbc133d0bd7f5 0000000000000a5d2de7b39bf007d845ec33ad811d06a97d116d25258cf70140 +153300 00000000000002405a74d5193358bec4166a2693a93a549f351c5fea14dbc7ed 89ba5e569b9fba01caebecb9e81cfad6b70cec07809a067577b4af73caadcd43 00000000000006f357e091f912fba099279e78ce34cfd3a8af456796e62f11ba +153400 00000000000007e459943bb2c1934eae6ea8d63ed2f19837cb118bb562c4e1f9 32e0daff9a4fc3dbc450d0aab70bb4d7be826547ebe029f3004c900b392b3ec2 00000000000004fd66c1a86fa104d036ae8dc0b348774d19110d40f2c071944f +153500 0000000000000acb845049f313d9bc7d020491c49e0663cba1ffa234f596de2c 812c082afa5deb3181f22f47fe467fc1df3da9dcf3cffda128a8e9fd3514aa7e 00000000000003d2c47bd83eac4149cf5d5c6ee0f2e6b3623b82051714292671 +153600 0000000000000cd8df9cd9b79aeac2cdf675d7e746e821b0300e818082d3ae01 f6ad9aef2ca793b63e3eea87493b23b27912d741a65e9b6cfae56a3ad56561e7 000000000000088139105ca4f891d866ff1e881b057492c8c8de3f36c4186982 +153700 0000000000000cd360a431e078a07c2a14d2f5ebb4a5ec9159eb6959a497b6dd 33f356a59a6042f63eeaa5c649172a2f2e2e32a55340a54d244b6e3fba616802 0000000000000cd29c8819472ec5d4d9cac4427df01b08188130ed8a5a80dab9 +153800 0000000000000353b528c2e326ffae4b3c546881e94b315c40dfa6bdef405975 85812b181657b5319606e786ce80db59d758aef2d42fb5d14850b04c1d12c739 00000000000008ea78701993868e8be84a6a2d37053381d8ce2a704e77e3586a +153900 000000000000064ebf75f02a9fc91fb9a22a69a2ea529b49986e97bd45538fda c42beb5cd4c5f7aa1618a06a2c1ea917ac2829916b8743a4d21e8008ac153c18 0000000000000086b95950b852889fcd90f806ff2fb874478e4b38cc306828a8 +154000 0000000000000a7446d1a63b8229670aa02d1d9fdfd729b89107fe5d88dacd8e c81ce1dfbddcb1a69a962514489c39ab75b99c276376ec5247e4a81e120dcfc7 0000000000000cfad9660f9068486ca4fc83ba6e5fcef0ecefc8c7eeb2e0e15a +154100 00000000000007b0c2dae12b278d82314b09bc425de25b33fbd4fffbb3bd8a14 93033cad7ac78d98ef20a9dc71b032666a88f0ae5e1a4054865fe1ccff9ce508 0000000000000c91adba729f5577e84972ed7fdc34ba9b60848eba846655a596 +154200 000000000000068038b71221ea5f47aafbd51f33c6469e22cda1d0ab7997496a 60781b0eff1ead2b15a6c5767a45dea964f13d601f21dda685139150c89f0e39 00000000000002e3c59306a2954c413baa71ad187d67bbffa71261e8b2dea1cf +154300 00000000000007e12dfa9f1186f86b3dc2bff10c65a41400bfcb1426b3b34264 ff10cc666d0e4654b8a5f5713a61d477da263c8545de7ab41fc96a10de4b7578 00000000000007fd08370d93b27aad99ebc2b42fdbabaf8bf8e07d5c51dcd0d2 +154400 0000000000000517a6428f4d11295e4f2a4998eae180fb4503126630962c3aed 726eb526d3f886df61412af981ac4cb0b6f6b8b407ce029fafc8506e34e3699b 000000000000026bf2366c172359c34c819172c251330b5389a40c724d2cb833 +154500 0000000000000982574190476c8ea7d0941528650cdc10e0142a081cf397fda1 157b55d722677bcf68a3857e6bf294b3c97997c3656be7b3c01421566350ece6 00000000000002a79d97179c66656e4b9c6bea3995f6f72c4ac84f29c2ff424a +154600 00000000000001de6811527902b2a994f3721af035110242ddca509e9a40ef7e 002e5331a3b34a4f0b84085ee53e4f0248da9aa2c8ce9d7afe7689d164bf680f 00000000000007e5aa04f120f9f503be42e0261d74de33b5d2ad01ab43b0163d +154700 0000000000000d11667ed46d168c6e69a99419d4e8ba63dce39a10482d34f33a 32b9711c62c97a66f9e67fe3c7c79503579738d580b8d3b6bfa9b455e1403dbb 0000000000000366c2cd0c206cf1642db8d7a46f4b842f6c9d098a659e4ad310 +154800 00000000000008243cba0bc5c286d11393cb6e930190c163204692436a3833dd 22f8e151938001cd5f7a6182b9a3ab104c94f392bd0216dbd1fbd414816481f8 0000000000000d94738927c8365fc09da50a98aa1b6bbb1cfbff437a4bc34e6e +154900 0000000000000a1f37867a7a6c57eeeb326373740582a9d8f92a76a065f62f47 a7c5b2d45917940b7efbfef9c7c4af5f97bfa6b53ac698cdd7b826eda8e9398b 0000000000000c6b7a55fe41f48400923adbb1ca5b6452c247b6e9768f460274 +155000 0000000000000984d00c9f2d51e6ad2b601b7b1df06deadbf62be24e49b8f486 0f55c23b7af7e296f4ae0295624c68d4df567b314037395a170c263a81529f17 000000000000058ce3754a0dd5a37013d82e9cda5f8699a90e5dab3942b32b93 +155100 000000000000069dddd875fb01f0c6505b21f6aeb5e3e6f6ec8739cdd4e43346 6ca2185a35df8d26195165e690874bb6758f2f05bd5673504db69ac1141997fc 0000000000000901b71ec71696cedf3a3ed2711a203969eda94c676db90a33df +155200 0000000000000b8cbbf3c986e6622a905e84cda12ef9210b88805b2fd385de44 94546393857cf6f50d3ce232b9d5b68666a774865d2e257325d401bd732b7aa6 00000000000002f7499bca4d0a154d27458107dcce1a6bc6cecc3c36d950b64d +155300 0000000000000694dac853c1a2f43d0ea4fce9f05639ad24a7c5307cc2ac4973 f83ba492db359f66c68a24c59e1d5f22e2029610424395afee2dd07000fb52da 00000000000007209a344b37d7561e6fc7e7c5061092b1ab400f21b2b078e56e +155400 00000000000005a7332d8fe512b07701d1f2f9889d884c5bf0ff72432b96c4d4 de105e59d029f0e9a96e434bfb96e6c811022f32201a6ed604c0e7600fdd8055 000000000000047b2dc4c294bc080f33b549d5ad486ecdf9d42db0dbc4bdfa36 +155500 0000000000000c45636f96585992219cb74e5c54bf58d7d16106373fd024932b ca2ca4005e44a987692f397ca6975af846651133db3ee44a1fafe889bda3a446 00000000000000fdd95284cadee93a2f9b8692842a15093a6c8f8beadea24730 +155600 000000000000096284eed54697a4eeb3ecbe9436f874c80efea76144de728b0b ac233fa06a6621047d82f8d0a2db0eb029fa4fad248ebf38ff609b9a6018b435 0000000000000e7f36ca49edae8bc09a7166fd8a297f40c5706dff2a2cab0afe +155700 00000000000009f15f16930111ebcd967a5a2b4dbc49e43e6d2aa2fcc3d245eb bbefccab6e2e0e360a23b88d6b4d10a25d3ca6ec4066265bdbf0e1a5670d5589 000000000000087c45cb3e9718f539e96ad7ebd2eb29aa854cda7a91b466f963 +155800 00000000000003942bca6f7ebcb545c8ff9ac6697adb6c6ac920b584f6f46cb1 efe2d2320d8a40e00d9799f4a9c8aaa339d70e7d16a50e0f18fa66d3bc6ad7c8 0000000000000d73a4aaf23d74da8ae8519f8bbfacff231ebe0e79087daa3303 +155900 00000000000005fe59fa09f033b85c7eeec7f78824ee9b5637413adaf72e8b14 268f8cdf33318c81d640511d3d6d28187e876da8e4dd29eb469126572e4d5c50 0000000000000c4c7ca967e733af87be7ed8325fddbcdadbac4a0030cc5a32e1 +156000 00000000000002adfcffbd5f09744ae3b930597dd0ea684cd37b816783ba3762 f557d3e760567d047cf0980f032a68dfd8b466ef80da574c7ba99d6cddd8bf06 0000000000000c5103789361bed6a8fd64d45f81c63dc3eca73d4c73a2f02779 +156100 0000000000000bfd18165112f0a29c6c756ba07bae4c712b656ab06b048ef28a d5ed5651a4b17463c05acbceaedb21473b4fcc0a92cf1d3802e54ad40e1ddfe2 000000000000056b69df0eaadfa7cc745d1ac260ebd3fb455f8bae50edc1cf30 +156200 0000000000000903bedfcadd0348c63c13cddb423a4978a9ba80042312a111f8 bcae5cfcdc9048fbeabea7b90e8e1cae5cfc61663034d0513a76a1fb4350b7d1 00000000000006c817b538db7bde43e8414be1cb8db876d54a53ac31b9fbdbdd +156300 0000000000000ef2f9b13157d3fe699e353769b245802524649dd127a2b22ad5 2e5f8e3eeb911cc2539e54e201dd8ae3de52053fab1f21fb9419babcfacc0438 000000000000070ffbddcbfa7822c4042ab1481d1121a919bef969e5fa2d8477 +156400 0000000000000729508928b16132de480988e666f279d9d12e61a1ec310ff5c2 d4fc9f8298fdb7ce55ec29102a2edeab68158f37d3ada08b2c60c46ca88f0dee 00000000000004053f39ea7e86a4208c0dd121c9a2b520fc0b6b127681687c64 +156500 0000000000000455776c672951c51dd7cb482f0b27b9ea35737dc8f540b47daa 656d35c05d0e7ec706daae7dc2a549038274d1e76bb07cdcfd0ef4775f4ac4c5 00000000000003c0c9011fc0195cc875799fe7a75e83ced5dbdc5bf4265c885e +156600 0000000000000d46c50ff465dbb9619f17106b5dc9b7916b9fed2e5957eb9668 cea6f07e5d8b9046c61435d5a0719982187a32332950704116b23f6a3af14951 000000000000029a8bfa52e84c68467c03405f272e4a514eabc4139ffa684d3a +156700 000000000000024f293ad325cb9d2290f221f0e87e2a555c69b4db8710c2875b 534f2a3207927e5cee968aa6d789b82223223e0e3f9e8658d4eec96c4fbf7180 0000000000000c4714d401aa230c4f7e394faa3f8cd6553cc97ee22eaa3e5432 +156800 0000000000000ef31baae3f26b313a5aca25cedc0229c9e3a1cbb825bc43a3a9 f460366350efaa5afc21a09fef46213c9b1f60988d0df40a1ed6cf9a07bc98b8 000000000000057f6059c2b678e5d42191928ecd4af5f06baec34f5db1582cb7 +156900 0000000000000aa1102cad2ddbe04f83c8ab771859b43faadacd7f967f0bb5ef 5f6376c2bc9661fc78b1a1f465a934a03b64273f687ee68a1a6059e804c5a6d8 0000000000000dc0668ebb96d0f019e1d47a63df632be78893b86e0d734aeb6a +157000 00000000000007ebf3a6b6ebcf46d550de83636fefd0a4eb91a5367f2880fd4c e1d72524f6a5b7ef35b7a2df465ffbb48bf18da8929004829b743257e8df6a9f 0000000000000b5c4d10aca8f19676cae82b9d68b05522a201ffe5b97d8334cf +157100 0000000000000c71eb95e8121e9fba110af56e1da73af2645218f4587ce21ce6 f963b669bf04243da248bae9ed9a7995520604d2247071c9131106f9a37b0a5f 000000000000040434328dd003a10b7a7aac5ab0960cda33d3c1605418c5a28c +157200 000000000000075dd20a60abf06a789880076cd2cae0903d99d028b59b11b5f5 6af6a54df3843b2c48f1ebd7c63a4872b57bfcbb81a7a4ef10e820e1dbcb2332 000000000000034cbbc03b7f2672c0853040d39d480581483913f22387e0e15b +157300 00000000000000302b1ea6683f4da4a77df8bf757f74d8046688057f2a07af31 d11da4fd42b1373f4220a1df2bf8e689a9dc169da83f8c1133bccb7f44ce8713 000000000000072be9f4e5cf720a56be3c6dc9ff4f57a633fcc37fbd757e4247 +157400 000000000000035135d21270a0e0dc3e7df67524fce200b12290a41c5a1b436d 778c3bd64766040eb9644b26a40aa2714cb66e371655ae6c15a37a0626c1868f 00000000000004627c50afd6a6ddf584c34ba809951c14bc1c4bd4624b53c01b +157500 000000000000035a50f9bc70622eda869b8810625b9909ae7b0d2b45f35cd1d3 dc03fbd877e8e68b1585301a6fa483f2bd85867a4e0f0c55c1d06256bdd42c46 000000000000038e417f7c458e5a86df6e0d8fe23e62282f9e5a697f1953c4d1 +157600 00000000000008fc67fd0e4f16c538c4fb4a06e328d8be2bcea218741bbaeccb 072f0ff2bd22ac0d263636f92a811c859fb87979f9acab28777738cf4466990b 0000000000000a93999d433b16c8ce44512533003bfd7fafce94ade253b3c295 +157700 0000000000000e3b75812a30e1ad25ce98f33ae6b2735c2eb4ede0a8ec15bf8c b4b6a22a247fb89b2c89f836f267fbd89018903d5beb942ceb08d03ad31bccf6 000000000000044a02bd28a6a86cbdf9c1cb604376dfa6a8dc2b321e3943c87d +157800 0000000000000251556bb869c25044d9eab4d697b144d7dd9ad4b2c4c9713d87 9ef0b6d6ab5482df2b4ea90253a3c90cc14f63ec260a0ba57dd47d6010ad5494 0000000000000e7f0c316e8b7609e9c8d59e9ca065d0be35172525f6df5d2be9 +157900 0000000000000327be16880325b79002900cfc61870e83ab0b60916c77f72f28 7268394b4c6ae4d8be297a2d583159f6067b22f6ceb6617416dac707768c0415 0000000000000787077a0b9708acf6a6ae2bcec29c26ce621dd3ac04b8387a2f +158000 00000000000000e50d56f13c7ce64183386abcac63462ca745b711be27568f52 67189b62be21c79d563a3991e04839d643265cabdfbed747e21d4a2a20f4c26e 0000000000000cdbef919d1caf804a847486022f9b24f368a47061718550bf01 +158100 00000000000008a7fd04ca698beec74330eda41fea1b9e95d26e3d2cc554ac9d fd0e7f650d142a36ebd766cabc2644b44688b0c978a12b87fb2c703049f33a8f 000000000000005238a9e87c8ce71efac76c42cc32001f0190d86440e34058a9 +158200 0000000000000ca82968c44b6b32224709bbd60be0a36edb4fe6a8b4cb950e32 047bd983dde2ec72606cc393fdc953c6f2fea684725aa807b315b696606bd896 00000000000006ed67de5c4dc9ebe0c50b640b2fda72358ebf877f1fa6e4f290 +158300 0000000000000b30862abcffad87bd0187f3c6f9c9b9572459e180d19917c042 c9e2bf14ccde31b60cbf41c3d2c6640bd5e1a72d6550578ee37ddc376f21f6b8 0000000000000453ec55a64aad52a13dfc30c4c06eb524d33d41a13226b84431 +158400 0000000000000494ff953010c1696ea00f9476b89a27f0f3f62b4e1f292c1a7b 738689a0a91adb9dc66ebd85ac287034c2a17b20542177a6c8c532c2240598bc 0000000000000a1159fc3a87fcbff4afcc5c8c494352630c4784a58831de963c +158500 00000000000007fb3e7116c33e6794d226ab216b000b835821e0fb6ae980bf66 512bc0cba65412414c21016f71a852df3d8022e7e321608c3e53bf99c6c27f60 0000000000000524db81610e4f9de59bdf87c875c99fadae30a1eda24e3d3df4 +158600 0000000000000e10bb679395973a73d92af1dd7333c890de12b281c04b20da38 a80318102e9f0758a3c17b36350d9fd660b1b2d44841ec7b4919be6189f59e64 0000000000000130f0f7675b0bf6ec852281008512312d510e7ee349b784479d +158700 0000000000000e02bc0a66b000b891184fe25fc629779153c2561e72b9a1aec3 9d15d9f0c47bf06f21ab0c00f717b3546f921538d30874f0fb336534fa1bd90b 0000000000000832b51e2593bd2c712e743952f9bc4d2108eef9ce805c30d06d +158800 0000000000000b5d0ba20740d4cb84206e55d2eaa1a46f03b1a21d8b87aca180 aff10311016771eb182084b02ab5c0e931c717d241ec1391287661c1765b8a6c 000000000000067a09a776bc6493cfd6fe308c8b6da5e3e7913bce28e38aa321 +158900 0000000000000b94069c75b2b2f3fc4815293c7e6c3a4d13a3ef29c12f2a3bf3 c8c5ea3a599bdac0c0e0304e7c364a20eab85e5853baa4b801d84c9b1f7c4cda 000000000000070f8710e8819bc92b4050e58ed5852b79eeea4d99c34a58be69 +159000 0000000000000de25617d0cdbfce23b41289abb01c46b78b0f8128126929ec00 5b3beb4918fa33a839e3bcedb480c8a4d7d2f46e2c0cc8105678ca9cf20c88e1 0000000000000586e86188be77cd86356a466375d79e235dd845acb13b104dff +159100 0000000000000535880ce46cd083e33dde59feb7523a5ca15de39341759f3e40 23596ccde45172f8ed2ea55c148d6de413c4b8a56633ef80efc02fd066e859cd 00000000000004e1753a4456a7963d5fd7a3ce51be349cc4a24eee0ca5e01465 +159200 000000000000019ca45008c57d8e76b593eda4aefb6b6740979324c216db5f51 b4c8787cfb1f4252072176a798d76d3bde1ce3923c865cc4dd299467f5fc4153 000000000000026ce8c145038d31035f240fa4c5f675c12b238234662d798731 +159300 000000000000091c031ae782b2c8ec00a19e29132c88cd25e2dab5367afb3300 2d02efb540a5d57faa8495a21280aea548166145991f82bb49a25245b43a94c7 00000000000002e5df78d959ecd6571465b03a7ae47117a0f11eb82b8aad67cb +159400 000000000000093afc77a2ac9bfcd95040e0352cb926d3d645c1959c7006199a a7656e673f636829748bb0d4d9049eb4a70d6a6effdb75e3180d4718b2f13120 00000000000005ca47d58cb699922ea0137acfec61e6c7231fe6c97a89363bcd +159500 000000000000065ce6213ee8c9b55ca2ff7935345a4d1815341688dfd63f69af b5d87341c69d4efc5ef569d6128b761bc30bc8f1cb7fec9add87ed0cb7d86c83 00000000000009fe41cb0451656e56e1d1b3dfee9df01224c1ec41394eb59d1d +159600 0000000000000a6ac935e28d97f0aede5ad52b4f1c9de9852441d53efbe8a366 cc812343831d3fb2f02cc8b447abd1ecdc50ba632a8b299f807c7124e1b77469 0000000000000e1563836b0ca3270f81a807449a5454651f4c475f85ee579d6c +159700 000000000000005e5852f7cadb5cbf88aa757a42a3126b41b03d513f5b9cbb41 7b48c54c0e15f32f56762ecb1a27faffec05578c161a77905c431d25f50674a2 0000000000000498c7b0048f048e5a3181cdeeaf1e977d6332949254ad6efc38 +159800 0000000000000d00734781dbae50f14b5aa5696f54b1736bf3b3c7d3d14b3ede aec943971987ede2058a53c77007b701731aad1aed5ac2b83ce7a5028af16770 0000000000000db338368b4190add7a15c0390f31e7df0172f4a942c40b52e31 +159900 0000000000000c34649af67c0d2e3626bc1bd48fc0233af1ae19172789986901 d0667ebc5b46aec0cd454ebfeeaa29df77a230a2e13b33c0b3d687c0d47fa020 0000000000000a3068b6f9647d57938e192a20d36186cfa91e245213b8c96b4c +160000 000000000000066c6e629b2fb49c7fcc52b82fe9833f328e0c3943856facf231 4feed05bace1c590f857e546c4e7672fbbfc1a0f2ebaf5a79f58e3a4f1efc6e2 00000000000008754857069b7a1df3acd1643a7ffe1623eceebcb7346ffd6a63 +160100 00000000000003649e905c40c47f3b0fe12a1276989359ab46e8cde92af7a534 f6024eec0f1c6f17941a431bdf431fdbb0e49ad041ac2cceaee32a141547bdba 0000000000000c812e8fe23eaf03d1342ab3a1a62a4265599b1b137ec31ebf87 +160200 000000000000010f123e93970bda828b9bbc45bcee98ad9d649ef9eebe4b80af dd59ff8bde09acb3038fd24cff1b0b632b04bb08ce3bdf80e7e3303e2d1d6fcf 0000000000000d468d8e817bb3a9d4796064c3f8c23e2ea1a2a595fcb87eea71 +160300 00000000000000a7fec67afbfa2883ffa313d1f70db7d03f3c4e4bd580ab88e9 a68474cd93cb52c62dabe5ffc2b46cddfaca8177775b61fbabd193bf06e0bbad 0000000000000aafc386bb41912b33f751387ff38299101dadcd7453ea1d9663 +160400 000000000000059d7a720f3e7a7c95cc903ad33bfd6da365020581d15f705757 73467c41c75b485623bf4e5e872903f0a9b8604aff15716c1cef9e6523a298a1 000000000000034c0d4f6975272cc42c918149c891dcf278f423b5a1effbe86c +160500 00000000000001d1744b6c765ef9b92db0ea635232720af6b4c917349659c3a5 32f6ed124110802c130b4e84c6b0fd8a9518c8d99f2262ae59700321795a8dd2 0000000000000c54c3aec4388855e6a5f5a7921c59e2ffc248e4e888011703da +160600 00000000000007229476fac88c253d25661cb68dada83b35610cac7566693016 a690843720eb35bbc6259b69177ee3210dad8d685017df4044d5c153aa765df7 00000000000001da3401325827314d19025d342d882f816facc35f4c313a0dea +160700 0000000000000d0b82afb23e0e65856abc57453d91c51ed7a2851a57bf8c86ea c6e87456a865ef1434a2027df93240b8d0150bada9efe6e062c5d79cc90e81d6 00000000000007f3c75b67f35b7f79ab15c41ef80492cca8c781dace5180ec53 +160800 000000000000075ececbe542e3431a42127419af8614832be7487a98eae83e75 26100e4759edcf7054ae7dacb15e9c794ab50c60fa15c6082aa093c61ac228a9 000000000000062c8318bec46a09316b2b2ac7e6d0f2b522ba666b2ac22b9504 +160900 00000000000007df3b974177458776b54bd23260a0135141499a9f712ff4d19f b62de14ee1351dd1e6cf8f09eb4a71279b18368e8c898df9a5710d9ffa5a3ba9 0000000000000214c23d01fce38ed9cb3a625d5228fefacaa2d13dcb0b8fc2b7 +161000 000000000000041db1574dba07ab482e4e0da4a47f85d2149205562c55115e23 07ca13bfd25e25ee4752187e49ac40fd2c3febbe328928051013ec161232f04c 00000000000002c21cf65f743501bb7302c9ec17e88c942c846508f390369eed +161100 000000000000049077f1a8346ebdcdf668eb3c46c1c3466c8239b8563b94749e 6da2337957c1ea8fd56d059ac13a8a2141267db6fbda479650827e829dac92b9 0000000000000589b7dbd82a3d41e843d376c0f5739da49bde76a05adde8d0f3 +161200 000000000000095897af517cdea929fcb149dbb8333aa0da11daa485fe233629 00db74f4a6835ce372f0e4dc0072049254960b747a17410151b6458685d91c93 00000000000009d0a1cfd2b907d620c1f77a68a938c10c99cc504814f904c1b9 +161300 000000000000011dc73be45709cf36f98bea640384dc689e29bcb5a8beef21f7 234eef5b4bdf93551914ad8d5d4a390d26b7d455d7d18414f74769fdd5d9450a 000000000000094f3a161f5a7e86e4d4da921feb6b20529443c3840591035373 +161400 0000000000000943791b8f44587f3d46d20bb8f1a63ffb22bbd9bb1d24bcfdcb 5c70f77d9680f90aa1bacf6b8fa16c65e04b6aab3a6a7d303c59b29041d6c8a6 000000000000079ee82fac4a50ed9af17b56e8e8757cb01ac827cc225cc00f22 +161500 0000000000000203a51f4310b4a715a7fcc402c2e135970cac09d0a17a1b3110 85e95af0716e311a539c7c82dee225cd1437026d4879ee8dba10bd2e44f8e00d 0000000000000d2b1a8e4abc9d5cc12857526748258d1bb9467aaa534dbba9b0 +161600 00000000000000a416fc79b974678e574dc897d60f64b095ed494a8d727b61b5 70bbda9501ddcf1438bdec770194b1b72dbde7678abf12c2be072bb9e2a2657b 0000000000000a74bd2a08affa00db35c97ac3b190ba5318c45fd9d4cc6c14a5 +161700 0000000000000751c3c4d82da008410ecab6fd78044e845ee40d1cb0782b1fe4 879bbbf1e3d5738f9488ec01c7fdf198dc87123502a6666fedc685b90c92f2bc 0000000000000c3bb6e90363bab1d02af6566fca383cb40d8a580c171f422272 +161800 0000000000000626a4ed7d6904773e16505566c6933d48e389054c4e779fac7e c73b529eb06b6f971e9d3aaa3e4c7c9f8b817aafbf6456f2a0005ef4212b7b2d 0000000000000bb840ed84397f8b3b6c59d753bc785abb76263aa9bad4e1c2b9 +161900 0000000000000b8cc68ca144e37eb33becaf95ba6de2817dd312db9a8e6976e4 76372044cf6ae05928a0ce2468ea2a548c891406b797fa45f8d0649557b84d17 00000000000006199ef3b56a7a4b29563f14c63bfa22647012cac453039fb4c8 +162000 00000000000001a83f5b20cd132f38f792fc02a17eb14d494c780ea9d1c82acc 7820879a5a70b4790373034cda898d7eeebc649bfc5c849398874988dc4b6206 00000000000007df40fd05a7b78bf3a920786711de165006d7c9750ea4043dbe +162100 000000000000001ee1f2f4ee232cf71a7a909d73d631d88256e9279adb286c88 e2e15498f165701ef7b8cd6dc4554a383f01b247bbf7c3f858ad6ef40d7f3af3 0000000000000a7667121ac52bb600d0603058af6e309814b75990f9190d70e0 +162200 0000000000000371e3832d4dac14040a2d11d9760cc5f1dfe62cf4453b31ba86 f475f3285f24bd56ff0841cabdbe4211d8515b696f50402d9b2e7cb5336d7427 0000000000000a6d004e051b0a6c4b5d66544fb6a786c175bd37ca228d8a9849 +162300 00000000000007506819e280c866556dd908e2646c253823bb68592e02284528 ce995438278e8cb975283502d646a549c9bb558f1efddfa0e5c4ce2b538708b0 00000000000001996d701ce17af030a6afc4bff6d19c8d5ea541e7b6edc20f5a +162400 0000000000000c916f972db49ba0a2d6ac6e3e4debbb0339b72d5e7a4c704cdc f9843821d88795fde84ee3e69aa92e23d7b67f49c57a18c39f7e6b3bb4c6bf11 0000000000000188fd0eeb575555cd4502d18113a4948bf25fb5e7d2972037a8 +162500 0000000000000295b629e94570ebe77eb499285c89f45478dd7aba55a1f88d50 738d146377bac8a539baf24de3679db2d2f5359ea3d1219b9ca83026840ad6b8 00000000000008e69407cb4aa45fc2647db285ad9e0d7dae42769eed5f7d9a2e +162600 00000000000001443664a56e8209aa98422db7aa23d8c521dc5e9e29ed6049ed e7d743091e136f42420451f51f9a1d6a4019373278f99f6f21da59b50f8b6a9e 00000000000004aed69373bb893ec73d11a2aaa439dd55e5bf9adb7a58d01ac2 +162700 000000000000084522e11fc92f2d018b6b6a27c57f87060915d8d5f0580e88e9 81fe2f92d35d90766d98d281c588b7570ddfd41b95abe1223804695d392d8b70 00000000000008d87e7d6ee664979842480757ab51a63b8b4d18c712d18367aa +162800 00000000000003459152238d54af5a27bd3054ff043b811424854ba34856197d a954d62848fa4464f2b46c4398b2890beb90e9710451971b4bffea2200164fb5 00000000000003f6ba9b1eb43e1d539bf3b50b2b12007527425d9ebbdbcac863 +162900 0000000000000b8e9eade1ec2e778e5ac4a72297011051f6aa8ff9fb8b1b529f cf8a1365ce79f67842f6bb789aadd88dbca829391f7758f6132d760c2be43481 00000000000005018eb54ae17a4d1f27227262249a6c0497f307e641d207295e +163000 0000000000000d66c125aa33593716ecbf6ef26b6f4c1d74998a87cf502bfc36 9a7c145c160d6bd2b893a5cb3cf3a3a45198ee96ec2098e11848ba7c3d7646e3 00000000000009f32a19cd841e42d9bd4524cf6eb8419ed283d561c35849a9eb +163100 0000000000000487b04d498f8ec29fc1fb07a76240d63b9cecbae6f5bd71509a c6782c491462e75c98ea7543d9282f0a9b80bbf0cbc2d0a5830e694221055811 0000000000000d4d0865ae34c01e8164930f017d707866172ae17966a012c5be +163200 000000000000006a4c9c33805a0798c894cfb3b0c91918a694ed85d65b3d9000 8d933a81c633b00f60f77ec17744241211b349432257b194212bfb77d3c6b8c4 0000000000000a514e86288352b8092c249baa51694f69d060870eef1efa6af9 +163300 0000000000000b745159d9536570cc5cbd1fb52eccd2a9f7793e10d29c3d1352 b7ce4f2338cb843451b2a76c30f5a275612331b9a60e27afdd5413ced1d7d550 00000000000006c9236c4a185222428bffe982fdba8c5c8a5853ba22c9f1e3e6 +163400 0000000000000ccef2874fb04e9ae82fcfa8af79edacb76d912e66e0b1cbb9fe f441c2cc44f8dc4183632c7758b950f61f539a6ae4d17e3b6df4d25aa09f37b0 00000000000007a0e53f08413420d35585627fe25b1de4eb77adc9dc6d6ce1e1 +163500 000000000000087da748318a644fb0422e5e2e4043ed1ad728dc699d4a825bb9 9ab0596225b6e13ee579d29255968ccdaa3411dc0aff5f1448cab8de616f3182 00000000000006b34747d9ee7723a1b927e60dd3436a26fb72dc0d2424b1fe2d +163600 0000000000000a79ca3fe7e37010dff0e891c057451bd61096e4aa1777c42a53 d1af0323b5532a28873651d5f553df61c88cca9d29677fe78097c170ecb61abb 00000000000006d5f1bea7ab15c732a6b757045a47006475d472a5cb6b76fad8 +163700 00000000000006bf77423f2392e3d5cb5289d064c1693a2bbfa1fec525163421 217d50b8656f1e29895ed3d802b5067651569c70021d19e82271f72f1f5e864a 00000000000009611e31fd14c3c786bb792e17f9b95f65620491ac55ed4bc018 +163800 000000000000005c25bb6a16e3ffa64428fca15ac30bad54c25b9f2a44b1c1a8 7c434b855e4bf278f7718a0aee05ae171e43cfa409c409346b97d42a6181ac19 00000000000008fe2d3dddce5607898a56c40d758f72205263dd0cceaf7e1111 +163900 000000000000030115055f7afff3c1979fcc74c0c23c55c9a81165e1bc45cd7d 51f7ad0c2489e14385e1236fc7e173d7abcce0b2048f5b086c46f765f87c9806 000000000000068341e31cd8181ef7b70a9e5508c2689bedb221fa5dfddff45f +164000 00000000000005a38f162cf308edea0a0a5d000bdb2073cba2386ebb1df7a2cf d561d8f10eb58ea5af3a9cb5fb3b91723db2afda2a79bb7bae919fd01d024614 000000000000094d462f1a0dbca9187bca75238108e11433be19c9c92da29a25 +164100 0000000000000082910354a5139437fb4c69756ef5906972cea316e2ff3c2ab9 e95370c666d32b0adc9966d5b8721c12933c7fb0250c996356d4938297f05750 00000000000000228a15368e3ce9c1e83315f91592785f322cd8a03c449d8e91 +164200 00000000000007dfe77845072e5e33d9b47cadba97c4c946dd7cd3b9fbf43da3 465a02f3085b6e2b3f235f278b216ee3c2656c5d154f67c68a870aaafff05ea8 000000000000074368b782f3c6c291ac6cfff07a972f3827a568860398ea12fb +164300 0000000000000b205a09ab7db81fcefd6463af17c07022a7aafcb306fe47aeef 70547c825cd07b5be6417a2fe47cbcb1a9a6f4036a64dd479e785cfe57214596 0000000000000215364d032df63d9a6f7550a56cd0738d5c8d44ba5cd6ab1a5d +164400 00000000000004db2c6e16f9011087d0e1ecc5a12dd725c701cd58811907deea 364ec3248bb98d1d4c06e17cd38e27aab771536e5416af844554a5292adb9e61 0000000000000bb5ee92a910c1e4585e5583d554009938f1dce80712ab9776fc +164500 000000000000089d27a58d0f0d18e6247ed740f9eae9f9ad5b9770925452380c 26ec6279ba5c1f397416ea4aa39801e78e714d5d12ed0ef9f39dd70fae1ee938 0000000000000a7f0f6b89c3d6a2d92b4d0e5e4ff079fbc3ca8423ca49aa7b96 +164600 0000000000000bb278958f40343cde5abcbbcc304f216b218d7e21652dcdff7e a0f7273735175989869b528441bd43b9aec0df5680d5871fd9459d98f822e9b1 00000000000005d39b8a8bb45265bcc3f45423953b753bdce2e8b6130658ddae +164700 000000000000007df2f0c864bfae804dcc6779406553c5a6b5ec4a21c96d381a 0f16768c344579dd3ffccd91c6f7d3d2431519d8981e71924a9dd09ae606ea29 00000000000001f3c382bc1e26923aaff9123adcfe3971698ecf65b2551d0ddd +164800 000000000000097f833c6af6c91c0500d49e266085de2f70fc56b6ce8772f42f ac7e73d02642a2953fa764dc69a28e596587dbc053a9d7d3bd50fd72ed8e9ab4 000000000000087e689dac72f9901d0f91eba53e01dc7c4c0bcbc51ee9a42112 +164900 00000000000000ad31e87966aca848e28a249bfaa5e07ae2388529c613be2013 c127442881362504141e596b7d3f6a18f2052fa5d11148e06a065d8d09ab8bb6 0000000000000224cf7af34c8bff10bc7d99322ba1629463f5046fc2fcd2f526 +165000 00000000000008863b4603ab6886773685d259c8bfb90a26243f76adf167ac5a 1e77665e65b323e274a7b1414ed5880a6b00344cb260fd8eb2644c15cbea1fe7 00000000000009f2aa6a7cce7480214a84cbb2f53a6e5cd856fc3d55e46a3e7e +165100 0000000000000bfc77c672979281518b01db6877e5548b513eb44f9f5db6e14f 640c8174b8267e9a270756cc1f88c51df9887a21f0862c255bc682e21e2ccc29 00000000000002a6cb7cd3c7d0b10c566ebec059684ee10e03eaaa6a0f37c2dc +165200 000000000000067c87cdf56536a2bca4ba58f2fc97f2b11d59d5d809937caf8e 9c5e7c9c8a1ad3a0a83682e40163c770f32c035559a95acd6e8655a4a8730887 00000000000003ae7c01750018d532550be460c523b42ec60e1c117f5667bb8d +165300 000000000000077540dd1566fc9aa184228a672339a019289c705c128ae22fe7 8345fc36879298b0dbf38ecd2903d0cf89b7e077dbbb8abcf724b6cfde664713 0000000000000984e07129e54bccfc801b455c1e43277066735b6acae77063d5 +165400 000000000000068e6204201727d960ac6d595eb5a46f495712473b8594b5421c c37e7c0e2ed922a45ce2b4c6048302c4d9db3d77a9f872ea17f9f17aa540596c 000000000000000b45aef7ef7c165509f56639dfcab6c673da274f6efe9910e6 +165500 0000000000000746fd2556b65f46d56ba0811a15dbeb48b919ad875b944a3569 dcb7489fcfe383228be8e4aca899ff555bb40970bca2147ec5451fb4f88f27b5 0000000000000053ec73e4acbe29d2a70c8e41cf26a6b2e691ca46898c851163 +165600 0000000000000a71df2c53c083712cc837d0c8b940731b1549f30ac5cddbb184 0f228157cff58780ca7ecc11295300582cdb417ef96dfbbb5be08c3001868526 0000000000000647b253e1b8e321cc0a3c03cc0e104be41d8606f9da95f5646c +165700 0000000000000a4cdb5a63e42f975af2cbf2426d966be01f087b62477776c3bf eb4c2523fe043c7b6f9f9d5e5b6e27fc8bfd1e04475fe9f91fdec26c0ef5f1e2 00000000000000a0ec14af7ee76e09cb960121d11445e1d27dfc163061694def +165800 00000000000008da23f05e81937e393bf6a8f9d8aecb966de96a288e630c2e61 525a964b17f04070500513d9e9a42759504fb93f0e327c59557f71f0dfe9898c 0000000000000871755c4e86a48d05d553abf16eba4aa707e87448a4797b9249 +165900 0000000000000580bf83e1c2aba922cbb33eabbf83cf0805c9021e525260124e 26d684b3319a30e73e34eb253cf468c60c7512906eb65120b3bc729c47267aa8 00000000000004112d3274e746c03efd05ca37cefea89528d62a48cd5ebb6ff1 +166000 00000000000003b3402f35327d144a465f3768d6e6cb06cd8a2d8fc1328b2477 b5c0d1b086b775f4bfd16028a90e9ca84b10cc5de5fb7be6361edf65aa5885bd 00000000000003dddc13fe8cd12a0b31f6a7c23a42da5052c3d65ab4b764a84c +166100 00000000000006fb456e96abad11ab0d08931d7f045e6b695bdb3dc2ee6b2ef1 a3cd2d47627f8edbfcac5df83010c999601a2c4ff279009fe1c2770268a676df 000000000000035e10ea2c86553057126cb19af34a5df013e23ff4ebc597c544 +166200 0000000000000a5e45d61b47c7daac65964a35f966b96a0eb2efcfd44b8cb62e c4273f6c4cc3281a313a7d9cbb2d0d8a1ee3ea8579f4ca94c3e0253e885d73a1 0000000000000c05d7f08411dc1f01243ff3f854761a4b7b9b9cf8b483b17450 +166300 0000000000000a9f610ca5e50cda20f7ba3c60cbc7febf690ee48ebc21bbf73c 70d12e090fe448bcbbc293eeb3570fca45c286a45af5e6005eea377d68b5ab6d 0000000000000529e290a8e4b9c0c679c5dff57f2906f2cb2c944e57faf9aeea +166400 00000000000000038ca3daa43d5616870d9ac7ae21a19bea55a1a696e0dc1a6b b2dc66877520c44973eaa7acc77f173094bb4bffa348d9281c2a0d1faee47375 000000000000033033c26896c71618f12fdaaea3a3b62671973c55f7f143a8e9 +166500 00000000000007e2e7dbc2b8f153d5a9c9faa9c6690877d2d3455ab0b3218d52 692797158b6d05c3c3322956aac0b5465985be155181ecb2132caccf9f38c0e2 0000000000000149c9d771e17a4307ea08387c89f2184a8c312fe2094ba7b89c +166600 00000000000002443e9c5e83df0209ed95895041888493c5c54a7865a86c227c d3d3121c29796787767d7268ff4f1d3681de5442f6843695f00b21805949b200 00000000000001a6aeb8d98b2d7d630ab54bb7365fee946930fb51fc6b2007e1 +166700 0000000000000661cd66bdb444542111676a1b82a211890644e39bf25a940560 7d6903f41b9a97ae54b206e139387e0dc4872a15d86ded3c2fd95ae2b621ed92 0000000000000453a1da7a6f62dc66eab937b09ec1ed6e1fd12e0ea4e7b7b4f5 +166800 000000000000053bb866c1dbc200eee7d90d7c3932f8150f9a7227dc33a73907 31e47b63761e96315bd56d5ab10f7d12772b09d6d9828435daeb170f82943d57 00000000000003f1edd58f0d96e9725b88dbd4e0101174ae8758d3f05886d3a6 +166900 000000000000092a550e9b271989933928d3e681b39ccc01648e4cf30038e49b 188e46b4edb13f2c1acdc269b84bbe179b90e396a1ae4d6be5bad53f3f1743ac 00000000000000f9960c44ee8f553318e8fb95c9e2ac18fdf39d00086c17f12e +167000 0000000000000a082a56845388ddcab7797b70f91e720d883c6794c7dbc49901 7aca33b45f86742192a6ee1940bb5c66f9c57efbbf4efc5579d1d329954301f9 000000000000062a8096e919e40b8b05ce2ad7d5c67c2d63beb63d56b8a5b9d8 +167100 00000000000009b78a1352f1b51126c7b89c6e91f26ddd76f609c3d295dba969 116cc1782db00f3beac7dafa1dadacbaa21215e312df245725036e8d9b54b3cb 000000000000080767bd87a936228c022e5a6781f7d40f00c3b0f6c3a39ef703 +167200 0000000000000b303e117fc792e9f019f64f4c00846a352394e67629b4c8e92c 0d906c651ea86ed68278a6a5d1ae388f41e1d157a61d72743168d5ad1f9c9177 00000000000005b6cdbd5958bca6b3a567e240da2c688ea731aabdc3d0d59910 +167300 0000000000000634650a03514a928f1e52ba7a4c6a4983d613aece4d9072a16d d5ca6e0126bdecf0ac37002a3d97f48d43f45053c36c25a1186cfe48fd56f090 00000000000004cb0a52b2d660e6e3cd91a65bcf3f2c646a6898409684507007 +167400 000000000000074a45870df1db1280370e9e0bb0a7aef8b06d1b91d11610287b 19315c0af695038fef5bea788fb063763dd67fc773337c673890882f300de2ca 0000000000000536cdb51f3ecc258e5d0aaef7c77e97fa68a00976c227e6b401 +167500 00000000000001e9133463d9aefeaa8b40bdd77e307e8720e80c3408b04059a9 122327c7ec4f572e8fb4e1c921dc03a19dcdcf39b9e63e5332622dca015a679b 0000000000000719507b9e871e1ae361ebe0a3818f3e660a0ff319576810d0cf +167600 00000000000007f1c694428baecd66cfa8f0ac2a276e3b682e7c39c9d9807ef7 9630cb5e73fc615635fdf2532caeecbbeb4a68b3ef05e74a1af31835ab92f09e 00000000000009d3221c8d4bcebd43562049038f63323b7beeed076d8a6a42d4 +167700 000000000000047541c606ed631554b7aa65eefdd988ff259c87818af0c1bcb1 918285fcd367c5fe01cac921af926d8ec39b3e8aad2b0038e5815bd261a81839 000000000000066a68040779bf2a793d6132970fbb931fb145d9ea3063fc7e0e +167800 00000000000008f9585fc1bf26cc864ea090b7928a9144a20ca1f4b4825ca68c d9b03439a120ad4ddce18cb695756ec0f0a5b305e289d3a6ee2209c461a4879b 000000000000078841d15590180bd6b6e5e1e5013dfde24c037aa6678ea257b6 +167900 0000000000000bda3eb35bf59eef25e7354af0cb904421f6cee44464cabe1a6a a1faf8d2757c538320e338c005981eed490b36699a450959e295fb08039e4f1e 00000000000004ca947d07f395e89f38cc1acc8854e58d0980eede2a11d8b83a +168000 000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763 2a2be6445a3dae92f2386da0290176a9044562c2dab196454494a93f4ef10ee0 0000000000000a40136ba56d6b514769534831e9ba805fef4d122f6c8d6da51c +168100 000000000000068e81398915896ed3cc5d0faabe92c0e1b145b6fdbe03474cb9 f576457daa87d65327d2e57e59c0edb814c5608cbf9a59900ea154f3a8bf923e 000000000000026e8d868371c821994b7149edb4db5415a6140f8191ea89f1f1 +168200 00000000000002780f2f2d67789a7c5dda3709e867026eeee453572bd1424b68 6f4e2595ac4bda7aadebb2e28b3248c8099410e15f6f937e4eae47beff39439a 00000000000005996241a8c6e3475a2a3adf68388000b4b0aebf8ddf15aabf2b +168300 00000000000009de7dbc06c49f4c42b8eb90639bf680519ed045020b346fe079 82d18dbf291c6f6b79076d1e3c265cb5e700ab85d4ed0ccb7ae0cc63a3ed0d00 00000000000009169dc33a0ff478443925424fd10cc55c71dfe89831f39593f0 +168400 00000000000003c562c8ae7899bd2fa6466246048af9fdef6e1f3f7b3f621c10 2cf1601274e341f1f1462bd905391f24cb3d519b48437aae1bf6709a8fc6260e 00000000000008a8ca7533ff3cbc2a5ab52553bc2066a18a20cad8978b440bbf +168500 000000000000054ea0a9027e5eb507fee5b5dc29824365bf6cacf8bdf0d21aa0 96dc10d5d2cff059883d99e9dd606cc5876fdeb5ed43ba141a95838a6aa90b27 0000000000000582b5419f2637dc6a77d4be3feeb6aeadb11117b191b16e3f74 +168600 00000000000006d928053f2a2affbb8a00f6d93316b14889fe9ae7e7f0c095f7 578d36f3ca5afe778793716f724161b8bc3bae519c1a3335f1cf34a82bebab1b 00000000000004ba070d16499ebfb6800d91319fff8b1c22140e497e429f8dcb +168700 0000000000000401e949d05918d018469d3131a6d6bef15e386ec75e6590f4ce 4c6ce4aec489f58cb5099be860cec1f5db37322b370931fe103de8ce018cb23c 0000000000000a2b9eeb24812e6a059df30d8317c7995272b0b10305dda49bf4 +168800 00000000000006a94033d639d71948e768de66b7f7149a7b6e0580d17c01910d 5b2928d12dcff32524ed0ffaf392180f3b1f1ceaca21faa9f991f802da137eea 00000000000009300d5cb9f20cc2af4d1c702ed23f19b2b3616446dfb143c07e +168900 0000000000000bd3cac23c1a3ac321f365c310386d1ac253606c69d2e7237740 b069a0568964990fc7197065bf07a2d67dcb89005d0718428ec83badc5c697c6 0000000000000615adaed02fcce55cfd30dff6839d288262957dfb0c304050ac +169000 000000000000099e9f2a34b7780d71b1234e08a60afe229dc0aa822f9d841610 55549bf111657a409636b95f0dbe2a94eaefd57469f9bf2d62c70e4868bb3eac 0000000000000a519a8f5e43d4f4f1a32f0c37ced4aa19fd558d761c34f33f1f +169100 0000000000000b179c9067a00a0844600f74234061bcd75d10027a00e2d938ee 742337152b88a2bcc60fcfb7fd3bb0faba871704102f3691bfa19f95c8f181f0 000000000000053b93551a5622442908c60a64010718c621758e35606b6097a2 +169200 00000000000001130d6c5d5ce8558a9fd3a2da9fe2a1364c02ded5dfc0b871b0 1f401d7aa6d1442671e6a8ae4f59e185add729e4f7df6fd49fb75a434a69f23a 0000000000000784a32a208d25908a42853cea1d8a957eaf3fc82125edcab213 +169300 00000000000007a2688e8d5a2416baabc4ddb30c632a5349cba7abf9b9ad5a83 238321c7ebc5af15f3ffc6bd3814a185c7e345bdd2d3cb12a9350e2972a043a8 000000000000076c4ef844b951a8b1abd2130d82b5c1447c210d4764fe404a9d +169400 0000000000000ac53b8d446e5c0c5b1ec64b66c25f73d5b7afb10e51524fc719 dd3c32b116385cabd20757e7dcbddd56798370250d2064dfa3f87cc733079af2 00000000000000e57bb24cd80f899ee1045d20fb0406780ad6bf7a41a6ee8c41 +169500 00000000000001e8cc8a12a97576bed718cc0153ec28fc4f0cd5d40ad54660eb b9390379f9614700c140b2516e9c64e05c6be752b0cfa43016f486b3e003c5dd 00000000000002e6b766add6a125ef6da4df7e80de0e513c9523078a0e0cceef +169600 0000000000000713fc8ac9c3fd2e8c5e3d8c4025a9ebc9de3fa295f5046d7ac4 a958fd4fefca2cb55def1ce373ef991c415be381bd1cc5d4a529e49162af857d 000000000000050502728fe6d97948e0b28c864e37f6f6153e3e5c5f4cb2e38d +169700 000000000000013f717250b231b9fa50641428f5650e11aedf96be166ba1635f a1106306c8464d1ae4f0aaec44d2a1702162d0e5fbd391d546110a3917f4339c 00000000000009410e043cc9aa386c2269f4204f448310eabe840f151fbe5f9c +169800 0000000000000883d011b9913eaa8d7cdcf1083489683c67d69ab43ae782d19d 0b368bd44a0ce4d61994f93d6dd776cfba7eaa8fcdc0332d468cf6bc1f6269a5 00000000000008af30d07c497e608bb338abfa7161933f3df8aeecc7905f4f1f +169900 00000000000008ac62b0833b3d8268ad8da48c79cc2be6e3801f1937eb33e325 88cd845b53b117ae83ab862123e1c61fc9888e4d571e106ce0790db6c92ccf2c 00000000000007dc56098c3b34f05c0c95886392df09d6877072245369338929 +170000 000000000000051f68f43e9d455e72d9c4e4ce52e8a00c5e24c07340632405cb 657855851f29092a07b2ab7cf1365c3a0d4a0e9ad7ce0c17cdb9b2804fc96d7d 000000000000074cb2c7d9585396b1f64b7e2c6bdb33e354b8e580c21238b76a +170100 00000000000009965df431e78c0f3062601cb5e287e9e3bde4a442eea2a747a9 aaf2993ac8c85ee183ce8eaf9e43d5f8bff31f055fde5541d15723a3d999e087 00000000000003264f94fd0b297a274386997a7783d14a9f9ec0bbd473274219 +170200 00000000000007265e2e1481b2c06bc608da8b9573c6831ae5205c17b08523c6 a52441c18578487193994a546085099d7a233f1d2370047d4f5b1003fa8505e7 00000000000001607c85f3b6f60e61ce08bda7eb9dbeafbc6def08cea543fe79 +170300 00000000000003dd67290087755b499693ab1a26489f6d275fb88b09d6b332a8 e024b9993dbb3fc961e94dab7467d67d81de2499bd9ab50c20279d8e4e956e76 00000000000005e5077d996fada7913cb759aba0345578059f4f9af0f6ad93d7 +170400 00000000000002f11c66d35af92d0d1b33fa154f9b397ac53ef6b63f546c8f02 730b918eddac9e9f3c68a03586eb0807650096ba95162acbaa3996612b076dd0 00000000000006edc3b76ac5738adef0d9ee010df2cf742233d726c4a0c2c789 +170500 0000000000000574fe503c699d4f656e8f48d7cd5bef19182c6a996408d4a6a9 e977be99fc9e465b54b7e063ae4737f929fc1716c8828683495a8231f9cd3907 0000000000000677ded7d11df9be6591bde0d376df668d696084cc1bf129577e +170600 00000000000005209ca04495bf5de4c8c3a0c4b78a58cf978a646ee9c3bf9520 3232fb36f2d0dc207ee201326a3c542ff8cb51e01aa0fdad0ed5fdaf25a841e1 0000000000000a549245648702a052642a8f771bf819079e01e8a0d81f61de86 +170700 0000000000000b0a54a14561805212262c3c0023eba29e1be4c4e80b18284bbc e3a049870fbfde31e828be476a89d4d1b6cbd56bb426c8e1db4e0f1b6803c0c5 00000000000001ed9d875dafc0b31a8126df1c5931717ed9bdfc8f073745d809 +170800 00000000000007645f923f4cdafdc5bf775f42630476ad0db08f3d1c087e369a 24540c938222c682f64e6895c55c86ee432e3d51645ed19dcbcaee8fe49705d5 00000000000006428fad8ae116422d97ea6ef0f16625074337c12e96970f4bd3 +170900 0000000000000a4764809483f2e0a2132e8d70da38e7d15482cf9a251350c3ed 559d6ed7377e23f5b9a57a480bf90aa4825932c3832f958bc8ddae19e48f3921 000000000000032815d2dce1131be1b403134295f84f5dd88b6d2725d2277e5a +171000 000000000000070e7585c214a2a9628c61d5be904d318e2cf5b2418a611bc8fd 7b65a06fd9554fcdce5241c4b4e9608fc05209d16b243e6b8b1f1c899f0a821b 000000000000026cfef8caeb467b83a6a74411a8a534886df0527e0fd4f4637f +171100 000000000000064642393f911a53fa1310c4075c26a9ddb106375ef3963a11b3 12d15de088289a530b4a173795f174fd0e3e77ee6bf4aeeab150a2477f00204e 000000000000041180ccb20ebf3ad69cbf54dda56e43404028452ea0186d3f8c +171200 00000000000005772a69b8a0b2ceac3a1364556f07b9ec3e97a535cc7bfa5d9e d81fbde7ba4cbb7da511e13b9e6840678eeef39f4f263672b9a043435f95fb4d 0000000000000a0bb1e12a5bd988c6b1c887afacd5a22050e54f03b9f97254a7 +171300 00000000000006aabf45578231175704cd94052b8390b2209bc45f50c15f1608 8a660ff43137e6e38f17a7114dc797159d76fb88300f3e013b72e287b0292357 000000000000030482139ecc1e672bdb1eb15b34e2d78eaaa37fcaa743ab150c +171400 00000000000003c95077d382b716fdf2080d385e583e2e8d322369499ed69273 d656bc300ad7179881d2b809b590279935acff34f2289464c45553abe1e5d616 000000000000013257cb9cdb80a44873e445b8a808935c5d0905a719d18f8535 +171500 0000000000000033c1c1833a32a088a36021af837ffb007ca39a762cb178c358 d357a943055e195d6f62a8e05c26332cd01e1232f3edf8d8f7a78a8a173cb84e 00000000000003df7cad23237deebc5e2ee77c4537692fe88d9bcb41f83fb20a +171600 00000000000007f2c63ffd4509afeab135bca06630c5ec22099ba86dcdfbd533 60af754c629c8b3c12b311a521a8e55c7215858662de82efb154fa166af98491 0000000000000034d9c11d4ec5370b570d9c4905aae368bc10df7e94387d891e +171700 0000000000000464484a8202f455a8efcf31c8ea925c1905ba5c82ccfcd6a73a d9587b3fd4bf1d3a9febf2e5f8866eafd3e9befc4f2d9108b1f2a118ad676815 0000000000000ae3ca873f1b81a31027b91955e0b0d39e00cc8f9bb395747ded +171800 00000000000001b6be86b1d81a3b18131ae0c4684cf30002a39148ed8ed21943 2baa89c95d470e5260eb163c5c00fc55b43c7f4c328cd7ffdf3138d9e203e5e7 000000000000090016e2a0801173e9380d4fde534baa807b803ec7c1df72c88e +171900 00000000000008b7c4a432aca449da9dc5b40a867704b6214dbb48cf9e2bfc26 f73a8f5b272c2416c0a862f0d7d8da30ec4313bc8a429a11340a918490a9bae8 000000000000027b72c70e8fb50057a50f8a0defc177f6d35f9445caaa25a295 +172000 0000000000000837e82c3a4ebe35a1d1d943e056234dba7c629922c6d4052d4c 3924b87daf870f8a9bb3504040002b6b64533a2745c52ec2bb125d88c45dd601 0000000000000443d106c7a849bf6c703002756994eb9c93bbfb20b54ed05ac1 +172100 00000000000007effb31f23496d30a54f98b51a1776d26a60e943efacb988631 276e9863ba87b98ebe6e030318bf709d076c0f4908aaa57cd30d1bcfb698477e 00000000000003a1ff4333c041e0e991e5baf760e80467fcb586ac5a7eff0986 +172200 00000000000008a02a67184cd94cfef3a50efb066ef00ab6221e2b9fd6f96b88 c80d840c7f694b3ca8490b8b336c74a721c081c0bf262af2d5c1310f24215123 00000000000006083e3eae638d76c93a931bdec8acd11d749cb534e31694e3ba +172300 000000000000053c12da577fc895f447e5f2a0b760e704860cbe60411f5c6bf6 0a27a6ee4c6049f10fd4f91a49c05d2290d133f02d95b3e2ee95fc9183aa136b 00000000000000f4e431300f36eccd5b1f9fd51f620848eeddfe1c0c4fd87185 +172400 00000000000008475bf844461ab35d3ef8f9abf3af9b582c0fba44656446387d ea8a6b4c9bad7694849a85bd0c7ae0524524b9b5b4e021e0cbe62f80ddb5c0f5 000000000000069a9d827393338bc35e641e411a5edf1647ed6de214cb197606 +172500 00000000000004eb01a7063c81066ec47523516c2bcaa3308c1351c0e6176e68 98ce65f840e8193bec4700b052545509736aa672cff0d05000723790a78261a7 0000000000000853e7182d5a48e9b2dc806bc3dcfde4349fba2b341175ea1d81 +172600 00000000000007e9ca758184a63181c897393d403da506a46e9398f22a06964d 56e6f4795a3bcf03eb356a09ba0fe6ddb35c18996287e08746e3ea5c93ad019a 00000000000000fc1e2da9181e2087ed926f240c07224febfb12ad8fde644274 +172700 000000000000053519bec78fea96d175959cb233a43830afac764013e06d705d 90c835be45adeb8fac453fba18d8fc353032091d2a501dcf62d3aaf99efac662 0000000000000599d6c3e0fabcbfe80934429b6e88f92321e981d83ac977710b +172800 00000000000006b5f49fc22c4864a6cd52ed6da26cc6555328eedfd1adf0d86c aca83f5e38a391cf323e57bb0c88c736b451713c589ac1fb4a942fd7f8407d22 000000000000079d2c8b5ce41f4b6564513c809d0dbd12343f34ff4f040714f2 +172900 000000000000015d7a1bafa89056d1f0afca48c20345cea330331bf448f6d1fd cc56f4ca9d23c901f1e994c17fe3881e8d08ab6024cbac7e4b65a1493ca8d12e 00000000000002e48b7bb37e4c48fcb1596f132379219b7ce638621876b0c013 +173000 000000000000077ff3de38ce09c0279dfd7746d07a476d72dd6323ffa2520ef0 c212b09889224f0b1dac4bb7125a9f59b76ca78b927e3927cdcd9bc9e6e673c4 000000000000060abd5d2b8ff55a15c9b885202da7ca697b7920d6a94bc2a1b6 +173100 0000000000000695965e21674c545ee0744b6bad840e5648ee2690c87240b28f 6201f11a8493931909b320d3fbc2fba3e446a04ff64ffe8657d877d0ccd8ef97 000000000000045e73b2d5718a3ce02f24498216a0ec26ce1b37c6cbe0f85dea +173200 0000000000000a675a17e80b40f7f3729a42568263374debddfc391e4c4ee71a 65bb1d03db428d9eed4575f13e95ca2bcb6cd5fc1556f3e56bb98c62e964e5ca 00000000000000cb371f408a9a5791227339807de288665e8ca55d81147b20ed +173300 00000000000006f20e76d94c1a79648d5ae5d089ae3b06f8c61a81da7bb6334d 90eb1e4007da98f0c10417e6541b4962501319fcc88d3507ebaf459f222ef447 00000000000008030ef62b195eea293cdb36089586cd4530b42346d1cf736586 +173400 000000000000023496d419ffc0d983af05b1f25e131e9d7befa27f825f006445 8e5e74155fc5df9ba157dc540eb196019915adc2a085ed92711bfd727a391b63 00000000000001349537f718f881801bbcdf4fcc85cb8220413be489dbc91583 +173500 0000000000000558fe81ae8122e2806e5b9292fba95da2d35a8205173b78c28d 65280f220d3340b69e3c92b90e2e2cb85c259f66ce1f080c2c8615887c624230 00000000000002aa757bbe2771e5ba6881e236ba66cd94b22ac35dcc0ca1896c +173600 00000000000005d701f0dca5a65a961005c04e3b9d03d1196683564c20b50677 a0db975a00937a69f18d07ed57df75f0d93b7635937aabd40e397fac88ad314a 0000000000000770696734ff0f731c67620755f91efac8d5d4d665ce5cd46c1c +173700 00000000000005a78ce0ea8cf1e2eb570bd3f694233238719e65022842e2643c 66f907d6e681e90a8e7de619066638bb0742c1f017ab1a835f1bd38cd2fefb03 00000000000006a3aaebadd4f4318f48a8d28788080d719e1f90e326c48c00f1 +173800 00000000000007b514e96f2a23e57f5a034adb9af7f8d17f08f28b35d8154f0d f618fd41c2cf84676c1dde02bbd03d58abfebd1725d330ee4d9c09e1c67862ac 00000000000001d77dee42198542f530a38d36e8000b966d804d59c232e9060a +173900 00000000000007b20f5eb25a1c55eeac4472db78e3e0bf5812a049dd8b57a61f 9d8b5600734ab088e0d4264e3b29934b2bb2347ba06da83386868b0fca93182c 00000000000000d5d2851b9f53588fae2ff77a88ccace5780ea70df8a72d9ee7 +174000 0000000000000504d3e701deb624eee4370f50c3d688fd1c27be5bbef07d76dd 56dfbb520a80d32b4bd70be999ec22af695173027d50d6226f6a5895e2e25acd 00000000000004fad4496c734994dc487c1397f22545287ff848b1a819f68303 +174100 0000000000000071f79c6a7d23ee9a7be025aded887968afb34acb58b300a48c 29bf8467a2b00833e2da7e267177e2871c0a0b31d23d02b4fefa2cce7adefa80 000000000000054f58ad28dca771df5a31c48973a4a1623885c5bf081f2f210c +174200 000000000000040e1ee8b1187c64f6fa99e89e08dc1de09e8689881ea4a17cd7 fcb15405ab3c149740f0ff81b7c5dfd28a0eb1753f5e666ba4c1fab397d60247 0000000000000454439190b9d4f57d0034117e23e55b0f992fee08fc2ffeedd8 +174300 000000000000096f456ab44fd612b9ecdca373d42da5f5fec47bdcbd579c0ef5 82bdd22d70b244035e1ffadbf34a72164cd904a25f121ab0ad65f3d8e0ef3d65 00000000000002082e03f4bbba0ba30d230ba37a03d0e421cea8dbfca51a898a +174400 00000000000007f0103e508a419527df85d618c50cb4d90a105a8a7c8ab57f50 7ae40b3eb0734c9fdadf20ffeccafd89595cbe6ef97c8342f3596846df744bb1 000000000000067ec706da210798b24a315d18ffc2b43ebf4d2565c3ab6d73c3 +174500 00000000000003c14046e41f0cac850ea544a815ce03f2861724ad02ec3e3db2 7170607f22467e3d05935db0268119e85a8cfccd4f4d006e4cda4e5cc7d2efb4 0000000000000a38a73a4dddcd7b2e1d9eb7cd5f08b194f452ba8bf65d40210b +174600 0000000000000787474b2b08301e43b5f5a4ee4f8aa539f82552b44f6a5ac26b abebf61525e80f5cbad1148f8a8cdc93e906081b5416bfec9c610c2d70064435 000000000000013ba61f2aabdecca137e78b625c0ec471f5351d12cf809ac0a2 +174700 00000000000006c016e22abe6acdafa62f1954ba7a0fa06c8dd6d3f5ddea1c6f 9de46e6fe6ce07e2a631c0cf257035023f89f7933ffd7dc91fe383a721d16d71 0000000000000110bb76cd823a73497747d352153bfa848e06ff7686fba90718 +174800 000000000000038d990dd1710f828b3ad58a985452ab057c3977d00058fb9a17 539cbd870ffcf36d80db4baafff081b51a1776c1e7a4d32bd44c822234f58a48 00000000000001516a711fab8441a3c1356bbfad8807e765ee4f552478a5879d +174900 000000000000077c029670690775ed321aeb45dfd8af3e72412733d9b110d722 3d06e7b07242aa64bb59714092085d910a15503bb0a07ad8753d920d6b167e75 0000000000000091cbec1ebade52f97d8f41afca023be12d86fb05ca79783cb3 +175000 00000000000006b975c097e9a5235de03d9024ddb205fd24dfcd508403fa907c a7a8d0b0a0aa6c1b26fbf7ca07b9593fe63961f0710cf8b51fd5b5a9622dfe17 000000000000079d059869f828411b00fc556b27b2425b78d341a9cbd6d87b28 +175100 000000000000075476a5db4772d42c0292efd6e483a132c86ec743b65ac33319 cb0816aba3b1c8fadeaa32402dc8c7a598e0b3bfc6341a0455b2b964e29b9cbb 00000000000004ceb4b720e6ddb18ba904ceee498d0fb787689a772b0d4ffe2b +175200 000000000000070e2f1e5fcdbd58b60a282fc3096b833c07fc25906987864089 f95d7ba7d156e8749feeaf3c34e5716bac165f5b0319542ff0b2caedd83b7339 000000000000039c5e01dc1e21a79c08de3dc413171ce6fbc8af0a001a3c6bfd +175300 00000000000002c1bff78fea37f6a80e64936e94bdfb3eff87219b54852aed54 0c7284637140b57edf1962bd61c63934572187e945ed8f0bd89db8de3b3d48c8 00000000000000a63d3bbbc495cbfae2b40ad0cb2900b5586c1d66f62e5b5cd6 +175400 000000000000054b63083e9b2347773e383fd986af1c6d9dba5551c714d84180 82b2d7dde813736fe8c95a3d7c2e003792decc1b22fb05f29c8ab5fdbab91d0d 00000000000004345f0ee91a6e75be357b28706907d30ded83dc953acb1fa222 +175500 00000000000009b1d4aff8894373fb3bc600b85b7705e368bbc01ee4e5da468a a001ed37517ca7914ef3b36a874c8835d49ed8e39d4c22a56d2599293bdd9e0a 00000000000009d4cfbb7453819e6f84cd49672c4c8ae81a09f4b47c38100707 +175600 00000000000002236df8d0f69388a14093ab501429cf3308b78eaa3f5092eb69 f5250fa19f0a89c82317baa8aea0e6dcb5e0521471f74b5c9c53ab87597375e1 00000000000000c0fc935bd65c1d4e92f0be5c213bb98cd765d8519b9a66d272 +175700 00000000000009f9c5627bea458fb98cfa843ee376aed9c4af3a11cf64ac37a8 c49da841195f1f19eb2c00ec96e803cd070faab15c113a2a4e998b88d1ee4afb 00000000000002cadf32dbb4544e39baef91c7e3d35333bf114448047334bd50 +175800 0000000000000436ec2bd0dd68eee48a053e04ea1f88add8ef4785eb382baeae 8dc8eb1de2a37401cb9f319297d02ce90c66222ae9f9673f702672a98f6e2e82 00000000000006aa835565f7cb791d9db6054df495eafab27f8487ba4e51328a +175900 0000000000000598fe1117ff9b277b34581e1249a14ed5bc1a6a2986578ff37b 269f08c05f7d6cce087f4b2b35a9e9db7021772a87299f22a384d70a949f8d48 00000000000002165920a84cc610cad03ef70637f919d1e18b564b4eb88ca22a +176000 00000000000004659b5b8602b2132b62973994079a1c828df6ef8d6427e4686b 20e7b4b2b80a87747c96f24027b0e9429319ea4a1db59ac71d26e341e9ed105d 000000000000094af92e179f0401e679bdccab2e475072a60d28872ce735b3b8 +176100 00000000000009584b73c24f8d861249ca01df96910430f246f2b71ea5c47d1f eaa18c06f4adcaada6d4eb45abe9c7d0eac536f63645d4fb525c956864450a13 000000000000060b1f56b8da04c28178301e774129f43a51bddfdd1bfebb7172 +176200 00000000000002018c3180a9f7b4b5ed0dbd9439dd9cf70b4f151b5d231d3054 59094bbbdddd1cb3ab9a86415e027d30020fae85d474c3b07ac87f8680507b2b 00000000000009fcc6d13b787791e6c723aa88f0fcac77457e9f51872ba2cb28 +176300 000000000000015564802a0ec0fb01b49eff0603ce4872ffd2580dfe64f24985 711cecce19db1c727428dce4229f5f93b4c5c3b8982bb56fdd1ac8371d62c32d 00000000000005db12794c33c7c78e552f40f48d93b7cbe8fb05c4ac52057505 +176400 00000000000002a7c1f43aa9205cde2e01ad1148d445b4d47896f1f7709b33f9 4d407acbcead527e3e44f97fd1a2ec7e82667e8b57ca71513790cbb5c697b103 00000000000000346795ac9dda31fd3e9ec30578bfce3cee8352304e76821e48 +176500 00000000000003249a97d28e3f30e4235d684ca26d9094867dc9ca591a6b6233 dd16f38b18ff81593151b60b7cefdb98fda0a72dd627fe440def7b2dbca71424 00000000000000396d827c2b7bb972471ffa259d4652864a3fa981e72db60187 +176600 0000000000000165e01f941536daec165fd33e5694a1011abc7b7bc2150df3af 504bda007b5eb63c2b153da1c28a41ff0c5a6a283e55d6ed1a71fd649cd60c0b 00000000000009012b2c6076ab431b42fa8aab1f2fac8ec802ee430bbd6556af +176700 000000000000051e3f9861dfd0aa0a9af682c4972558ef6b8a9a58dc0acf9929 43ff7b7847ff6a9967dd45ed3c5906d4091c56d2e55ba4c0861ae8a359be464e 00000000000004f0d7e1c05102f865cf881184514d1bf7c1fe74503c42a949f9 +176800 00000000000006ef4d9200e7b5e1b22fdf21a6c5b9cda2441d8b2dd281e739d5 c89085836d3060f5c497aa321e1e69dc95667f173c5e3d99b07fe120607be889 00000000000004888299169d3a1e56f0eb4b0be9ea1debfecd58ad66d16de400 +176900 000000000000089701daa438927842e77ddf24c161f81602018f90173eff0ccc b5895a86bc71e46eb310ccc7ce32d24a5967d814581a189610afca8257f7123f 0000000000000867fc531e3ab3f0e8bab013e460a7ed9ee2a93626b36d742973 +177000 0000000000000359be6774f86dec526367120cbfc7dadf6392b6ddbda2af3a3e 94940bde2f43100db3831f342920b0c869bb18c7e9d307990ec6669f169fe175 00000000000002e880ee928f4cd3aff8269b0426bd7d5a1eef2f2c80e1328616 +177100 00000000000001509cb3e263f5bd3000065c33981e0e09461a5537c276cb2497 29a11feda877da1a22899c5a17f232971158ae0bf7e8c431b9db36407ebd00dc 000000000000011e72ec4f622b6a5a5ddde1847e3e63d5fb5a435f0671d31e32 +177200 0000000000000011f4771501cb4c66d2a9a48b03bdba28470e39cc03b6432cd9 081d06173779b12a9223d42a48c218c060d2337610a1d4b0972c6fd4e0a89223 00000000000005353ca3f58e531b02ecd29b140ba2e23c9652197f9dd898106e +177300 00000000000005b1c4344735e044425659545ec767d5ebdb3d8055996909e4d5 be9e63a26e5ccbd7d261e83a1cff13642155c3dcf29358f4616bdc72e39380be 0000000000000a738093655135880c03ef5e552c67343133eb48650b94ff3894 +177400 000000000000085127463e27d762af4464b452fcaa89c7503f4c5a11d33bb64e 128a81eb5050fe17a8e2ae03d8c49b49ec0d2ef86f8a15421c496a3d7a545e0e 000000000000083e73d4023fef05d169aa6aa490c7beb23eceda225763e44e29 +177500 0000000000000464994383d2d46b0f3ce591feb8f53140d0e856e3911ac3e42d 3e261b794c7b937ee68a115818c4d8b876b4933e050d96b303871ec9b62842e6 00000000000004c64a1e2b25e6b527b91efb384c10f5c9897be600a53926397e +177600 0000000000000074c31874804eb9cda1f89f45b029b7ab314d66995f700e7e09 3c98a7f426bb3b96b5d7020df69658aef419f5318bda27b80f7833155a49610a 00000000000001e4135ba5570331a49ae05961996a0f82b1af3063a126333a69 +177700 00000000000007cb13f59fc5d41adcdb8fc5e63815149a1fb88ab5e2d06324f2 0d0d9a176eda7e2767458440e2cce781f304b7bfe950755513d43d846b73b1c4 00000000000008fe07a8a731b09ed85d42175f16972fb72f9971e9a0c79d7a96 +177800 00000000000009e66100cab83ed79e2469eb9c03eca0278c0617131dfcb601e8 126236023a05ee497c772bee115410703b372552d324861ed298ecd52fee8afd 000000000000081b52269e2b2a004e9d84a2033278928379505741d3d193231c +177900 00000000000005987378cca51011179761ae4cf5227252d61fc0fdda2e102d44 a81181367e0ec7a12ef30508657abb3ad719663222e54ee7654ee9c493e35981 00000000000009068fb7fe0d46d12288be11a9deaca546b8cd9020f9cc0fa01f +178000 00000000000009eae2697a7aaf57e730b707b9f4530449c16d924d534d41f297 6b2bdbbe7e20c2137dd567c63b1dcb3f434affbc3ee61274a55597d037c36d02 000000000000048b777caca656fc0a79aaa095e3b13c1717f9d420efaee17faa +178100 00000000000008806b6a0e823fec0f63798ed695b310dbe57eb7269017174a71 7499d2f65d0c51c0979d0ed9e496abb84cb7d111405c428910983bcf0cb6d9c5 000000000000008c37a173874b00a48bacd00e8c3279d5ff92617f2ee8dc0564 +178200 0000000000000390610f6f5ef5a52a6a8f6b3b18ca5d0383472f4d314f5aa8af 596f4adf9508b782d3cf323c602163c9f8d07647797050b44450086a5366adde 00000000000008abb165a9a52df957904772983a35b86080160472931b868de6 +178300 00000000000008901b16aaadd519471adb1c4036a9b132ab3253895a91b0e0a5 b7a470f01d9549cf196b277687f7b1969ccd50fdd1889e8164e27fbe00f42759 00000000000008d4e06cc1b8174681367184fe92ceb7978ff6c25974cbfc264a +178400 00000000000009ae427eb833c698993f466f93db2f99ec9f79863f9bb7d884c5 0c13c269fecbc3a74c610da0107b56e82a8fd28a71c0056c9492e5b5ef0313e7 0000000000000482efaeab28d32b1ec705c3444751dac6034a95dda5bf14ec9d +178500 0000000000000920e795905e4d432dc1e039f31f304277287c1c35316405ff64 1b27e1d1b45f54c15f3a03505a025d402074cd33325d7dc509adc5ad49e88aaa 0000000000000644eac1da9d0beb13e0d8fdbae8bb9a4fbacd8ec245386bf30f +178600 0000000000000218bf10d219bd13ceb8bfa328c26e60018f669c8c043718b248 e41c4da7d95d0a8bad57129b33a07ca60d3dc08b73d478d06444eb134028c7f8 00000000000003dbacfa9952213e925dff9ff075d9d7e5bc9bda2c89be64fb1f +178700 0000000000000464bb7fb52c50f48c00915e661cdb5ef381e97c6c8c5ae969e9 e6839fafc5994be1705f261d207e61159e04f6118ee6f03af7aa3cd0d4a66ce1 00000000000004aa8e12044fccbbb49c684cb98501a5c2ed4f1af55df8ced37e +178800 00000000000002b951b54e5cd09bf0cb58b6d8385c18e29d175538425bd56dc4 074c02ba712a06328b3462da29a2c8750cb1ba08cea89ffeb4de08938ad874d9 0000000000000711e763c317349bcd79cc684cf6f472d83b6cafa654c3ef9a0c +178900 000000000000065a3f4e91439391256bb9b1b4e4856cb9c9822ae3cc499fe1f9 94d501160398843727b8c523059d36b0e64017f39cd2cd44bea3d155762db570 000000000000019547d35e691884e95f0b4e1df8b62bebfb883f991ca83bc261 +179000 00000000000008dddc8b99d4bf1d3977e4ea15fa9900454148637f0d3ea8e410 3842dbff4bfd3f39f91d86a194810118208b2d2cc407af8c4e53e5ae88c94979 00000000000003c70c6bdf9f924e264f4cb737d0dd34ae27fa493834f59dfe34 +179100 0000000000000567b8bd2b791f50de0eadb99fafdc10e2025bc23cbca43693f8 01b9627853d3e3c76ee82ef390ddb7161cf34a6683da0de09811220da3ff9775 00000000000003ff3cd18ca09866294245582ee7af83c94c0842904d5a5baa91 +179200 00000000000002db4324a4882135cb41d3a4f4cd4c84ffc3b43fa7fa86f886c7 8d9ef038ee8f35f834010935f86d7eeaf014e2929d8df0332cae8949635fee10 000000000000005492b343a685d7516ae51c1c685f0170e0336c3e76b7971586 +179300 00000000000007539c0633d4a8a85c009c1b36b32831e3ed490264cf6e349369 637051e2588898d6bf42411ba7ed0f846f9918662975a6baa02a096978483460 0000000000000783f1bfd5dfdfa88ebcb0e766fe6c7b3079632dd6813f658e53 +179400 0000000000000435e44123773e1570b7c7f2a874c4e97a0d9dc2fbb4b1e4906e 14e251e953a02cb30c9a79681c229ecbb33643085c385f8bf1c809ee27f1098c 00000000000004dd1adfc6b20b54e9103ed7734c9801e8806f8b5b4eb0fbfb6c +179500 00000000000009496f9c2216c050a8e204a81218820838b0f9291b9b0866a99d 2e6f3890e389702d24e6e5b734d26a5628ce9f3ac8a1df9422dc83596ad4dc2b 000000000000075ea59d2124c431bd74f4a2541617f0d4d5ea42175e23928926 +179600 00000000000001cf299fb1ce61aed4eb334d37fbc0e0c051bf1a176e49f17102 b82b0ed0fdd7c8af27562fc93613f2e66a7ac953e24689016fb6767f1cbc39c6 00000000000003c3553a61a5fa75cc3a39af68cd5cbf6ca9391c3cff6e9971a3 +179700 0000000000000127ae6d9b52e6065f069c968cc835032bfee2c738c0284b74dd d009314ad0f8513677b7c582ad92656ed8e7fc255711330db1d663f377332551 00000000000008c1d60127e89027d7905b3a50130e6c09a4ff45348a0ef0aa1a +179800 00000000000004f20eedaa2ec0852213ffae72032fc2b8fff4c6d085fa08071c 09c2bb9146d3fada299456970c45cdfb4ae268048e18fa375a13afd4b1aaa192 00000000000001e90ab8c3b907fcc639d3c2fa885bfd90460ce4cf45bf0d9a0a +179900 00000000000003e21e4c75bb543ac7d6859fe9e27c7ce5872287391ea955ce37 ef9e935f329f07495a206b83a227ed5dcbf19d5e4ff652e71e534ce5c072b547 00000000000004f37cbb7c127a2bdfdd332afa054e52d4aaf52d0724d55888d7 +180000 00000000000004ff83b6c10460b239ef4a6aa320e5fffd6c7bcedefa8c78593c 6606e8dd49216893daefcd0d6feebde68f888c900f8f6d20ec30abea69825f48 00000000000002b833041fa0a23d7f8c2442781ff33062fe5c483288cf151e74 +180100 000000000000069d52556857e21dd13a069871016b6d3fb862bc8012417bd4cd 85838ac8345be857dfac1fbdcbd6a9bbd86d2d4720ffcd7a5c7576aa31dde97a 00000000000002cbef20e5d0c4d4e5baee92646f5426581eea1af8137dab8c1b +180200 0000000000000434c4df871537023943bf86760c413ac96badcd99a0d4286af6 6c828e6bd624c27f6689c7ffabc333ffae0b198ac51a96e4453cce31c809af49 00000000000002793280efe17cfd9143418e9b78f90154dff7c484d6db8d2544 +180300 0000000000000184b48409de0a7f21a6cd2a8769803cb25b79a23d7567c866d5 cfafbb041afeee4e4c7677f3f609c395aee7d16232ffcb027df18afdd1cd6da3 00000000000008e45062d62e8cf43e781880f98fd0e8189c9a3dabc30a753498 +180400 0000000000000815a5a27b81a0d943b4feb037b2d8465eaa6b0577c1f41a2d75 1c5e4f0fcd98ed2beafa70f257c86737ee1cb9a9f2db82171eb5934f18fb12a6 0000000000000842ce2bb4d9ce19ac2b29198d38227034ee209dd2cf9db76898 +180500 000000000000038501d23913ceb48ebe45a5aea2a3c63928ea00308a23ee20ae 2d31b0583d2f86e5db4c486df5cef38f00f1927c3b4e413987bcbddf26550270 00000000000008bbd11e4ed44c6c818c4eb3e91a05b4abc9c4b0c9062670c9b1 +180600 00000000000006b901c1f2146695e123331bbec6e71d26edbaca06a4a233eebe f59fdce0a0eab2e38364ac6c8d64b957f98376eac111bc10a3e4c369b057ff40 000000000000019a19f00152506dfe768a8423facf948a1a982c2ae644c51da2 +180700 0000000000000751db4fb6228b0b53898c70d5972623e6016e90261e45b694a2 45fce61b2854590bfb23c3c77864cd0fd51e150125edc58836a512f42ef8d277 0000000000000671573a2ae1a142121108e35af3bd8944dae2ffb3d9284f0808 +180800 000000000000026f9f99ccde88c96bdedf5870b5c36a3657f6eb735a3be5423c d2a25436816a024ea40e2a407b88efb7a64d9a2f6490ba6f9f5eb6250cc84870 000000000000021555ff13f69b44cfbd00b0246b8d16ab4c9f7eda8ae827b964 +180900 000000000000062d77804089b2c376b44f44531655b4a331003f578da7b65bde 582e4206b4132e647718cb4977b73c3470289ef085178c4bd95f0f6b5cbb7990 000000000000073887c69419033c68ecc474cd19e91ceeac89981c5ae9fe16f5 +181000 000000000000089558f2de87ee02ba250391e964683ac7d867e09f66e65ebbab f5fb2c4816fa5a8ee4c1bbffdb6d49f2e4e753d877184df1a15d06b3bf44127c 0000000000000949bd58b743e2bea53cf95d42596f9b09ff148c2b956f3f4c66 +181100 0000000000000358e4948e5869ed35e1ea03951e4abf1237bf96cfa8f5875e05 9f9c6a607cee9bf0837a226788fd7b5fa91ceb75add2c87cb512bbd25fee652c 000000000000098d36b2b5e882feab7bb13021fe5a1709f4eb0936d032110571 +181200 000000000000029786603927610232eddd7de06e9859bea62e2423a622394c7d 72a6361b4b7eac1011f755ec160f0e368508c1169f7ec0f514aa3a43f03469cb 000000000000071af41eb7327b35b0b6a1ca9ad2da837cdc1065f6351c622739 +181300 000000000000099be648ecdf8cf78dddcedcadc6396980dcf3accaa5832371d8 0144cd6bffafa566d57432ab00906a41dc006bcb2a2fb9e23e869df8aa5ad6f3 0000000000000658cbeefb4aa8e43f447e289fd1ca5804f9aaee9b965a57da81 +181400 000000000000035b6a2f5d2ea5b3706281ec61474a794201303f3f5657fccca5 eb833a5fd717907668847cb8ad5a44f241c1dc266ad678f98dbc95a57113af88 00000000000008ce90c7ce8b11658d5f69e0a5967d32643f4fb96e6e62bfab70 +181500 000000000000078b9d714fc16e55188a9f72e787dff0352800f9a643db48dd3d cf32806931a627965544cb9945d55eba3629265f6eaa55dd4323b3ef688b17f1 00000000000002544a752783d39952eb6a64cbfdf9eb97976995a9aa90117b62 +181600 00000000000007e5f3add3325ddb63a43a86481e5d6be173c4143f4b66c686fc 8ad2900e3238733da1341ca9a99f99b2cd256e5409af0a7c9f2c0e83f68e76b5 0000000000000334366b53119ef552abccd85166092da95a4da20b220ed6f10e +181700 000000000000033572ac81c051953dd62aa791552f05412a5d3c06d57c8cc78a 19ceea62644b9ba7b4906c8d21b6a469931cbdc0868fbd606ab8bc2606b90768 000000000000015f0e9a0519fb95bd19658604404e74512c0a3e2c3870cd7fdc +181800 00000000000005719baf3999c44f7828052fcb68ed8ba0ee90de76e15d273fd9 c9bebc17ae390749e618c2ba02249fc24721681f91cccda0c1a0c6ae3bb1a54a 00000000000002b983a465861a830b70797a92602215a841a59a50cbe9dad137 +181900 00000000000002fe975d8708d941e81ba1e01a4b0a14681861ca86179a4f8340 38f56951032aa3356422d1d6bbaf470b2a89fa4ddc36e030ee7a68bdef51834a 000000000000075b5e5ee7573921a3b48e45ace6d9020af7777f32fd99737f14 +182000 000000000000068dce12903c1447e4c5b60311b61e443a25d5fc82c77f4f9a8f 05eb3b1fd71c113a80968a7fd657333c29c0ae621c9f3261c037eb751d0d764e 0000000000000a6291a6ced756c7b8b46e75fd01d75fabb1c10d76ebab5dbdb2 +182100 00000000000001369f1030d260fd6f19278240859a5094c183b63694984adb60 2ca73fe27e09a006fab79742fc296fbad04080fa978660c344edaef546a7979b 000000000000091388e51194d5d35a73c0cee6b412048ee69d2ea2c1ff769977 +182200 0000000000000873b6cd618f4d5d2e301f38d9a6ff1104644c2df07df6a779a2 9d72716ab4d31604402ee9ad0895ff90992feddb9bb185ff6bff57fc7ccafc52 00000000000005816c93f7fe9500780a426cf130f547d40b5c479cff3723bf83 +182300 00000000000009e8eacd80741d460ffc4c3fb488d6977dd703e55b4eb518d4e6 72a40619a23349a2c63c83f84b3921a4775be1e74fe26602f9ea044d68c60382 0000000000000a78c419dcb1957779b2c55a76cd7f5ae5d8a634fbf39ac55f85 +182400 00000000000006bca5f9613129affe05a1433e45d1087fe3109816aad0156a41 412860db26518ad62c0a628aaee12e1ceb740015315c8b1420de46a251cd7ccc 000000000000047dad78df9a6df33e848cd278d46c5fdbebc79598fd8c7b0ff1 +182500 00000000000008d7fc792f9e7b37bb46febbf0746211572b4627a7022763957e 6e206b2579a22f671104579858b2d6ca5c099c0c35c17a4cfb5821c0fb14e4c6 000000000000023682e229e9391d9eb9f59a3d73e2b295cbd660425b5e9be7a4 +182600 00000000000007716d307b5c6d60b1b5b9f8d4d2b9c0a5b418a6e97e5f885ec9 44b7a85cbece20f77e0e2f75e057bb1f8a1a4f0a6673e203cba4b6dd895f0122 000000000000040472a214da94d21e47c03ec47943cc5e4fe55e6accb3b66c78 +182700 000000000000045bd095a28df2658ed0d29d2057cda7473587965ff06bf413b2 8ff6a8a19bc6551e37ad288a70f5fda9f70c0936f4f8b719cf42b83be69e1e4d 00000000000006f940a0379ff87366d0c1b2e52f437dae9e6bb8579cb29c2ec5 +182800 000000000000089ae03a2571a5e4e48de7ffca40ecf86c0030c5209527a0077a 816f3f2207c24a7ff43efa4e06b4817de0ef576c25e89534124ca6c439e7cb5b 00000000000003ee2c646d8ac029dbdc95e3facda2241dd630b906ddc6ced94a +182900 000000000000086ede0600e97a6f075b5c41306e0fd9a04d07741a632c736c62 65d24c6a4d4a1b7ee3a1a26e387282228be38bb846e9aea4acfc00addf7982d4 00000000000007828e32874af9302cb7825e9d0ecba597daa2098cfd1586bed6 +183000 00000000000007be8b15bd307b7bc04aa22369e4079c12914a415f6c96ab2844 d7cd781e51665b923fe671928d8ab848a8944b83f84a5a2a25eddb0f84dfe0b1 0000000000000844473d11e706c94e4dab9190601d2bc9a6ec9fb41118217abe +183100 0000000000000566182f9de8379bebb04aa66e485aaec536c36e7be3560463ba ad69a84bebf3e2274ddcad84d01feb5cc43ba9a376055875366793116c6579be 00000000000007622f14a36d73f689b91aacbe1b49fbd63491e23e66698e91fe +183200 000000000000070cba2448c5d5d84d512435ce68ad338369da1ab47c2c7dbd20 e5af17a601177fe36274822a414e589c9a7c9419a592a64e873aa3ac61dd5e77 00000000000009ed16d87b5425582cf1d105122843736c1716bec4a9d4dc3587 +183300 0000000000000a40353c058c3fd185e9f784aac1596082aaaaba96f5b0fe68fb 76035523ee5e0ba8bcc3ffdb7df656ff50ae304196e20971a06ce4aa12914346 0000000000000954489d772e3a95b9bec13f5dc63f36bdf2fbf9e03624cca67d +183400 000000000000077a36e27b500547460d6337b32a98dc31a0b72621b3d99333a9 aa8747a7c3428bc030df6befd8021a650fdd12c9b862cf9104ba6cdfa148ac75 00000000000004c60200407bd5431448bb5f5bf8ea53d9d070b2c3968f3b4f06 +183500 000000000000016fa5218777828abfdb39a86b09fc6f58cd127f848bfb9b5c13 5a3597abb81c2cd1d34714fd03079d01d32216a559f816cfb31cc0fa3a9c9d6b 000000000000043fa91006cb7fa30ef4daa1fee687ce0bea8d1f4ea8b017d506 +183600 000000000000050b5916aa6f6c661c046fdf0b009f3c83426c51ed2447994b1c b1cebafd393f7353e3a1d13247ae3a078e8d6da17e1868d34034f683647e2911 000000000000072b3809557cc8ed4f65e9327726de3b396d6c663e78a620d866 +183700 000000000000097781a626868b72b587ee976f7721a99325ce8fafc45823ab56 2dea1ac862eace2482e18a8fef4597c0860b81120d355ca59f8b064b8ca86cf8 00000000000006153f8f630cf7f03cc1c9586b282e26b13bc8f4f5a7b0eb141d +183800 00000000000000a90857252d4faf9d28ed6decd1d9bbc2537811408af4adf8f4 5e3cf7571fa04797b0bf6abeae588d74470efb24c9eeb6c0a491c903399de2bd 000000000000080cecdffdc047ac13db7dd1b8d10a4cff94df5dc1aad053a05f +183900 00000000000005e4e35516822a8eb35bfee2c982b63e9d5d5c8c1f2d8441d26d 99c2bd0f5bdc7dc2c620febfd80a86171265b360ce67b4233b3cec6ac74791d2 00000000000000d916c6086fe851a617120230cb3af1921aa41096aa42cefad2 +184000 000000000000060405a235c6b968ccb18fd6b3800ae9742c2524e28863367359 62c618ecf6fabad32ab5074b7ff5273c889bfc6014d16210e713d54ce9970bdc 000000000000017c48347973112e2f48dd6ebad919d5385782b55b0341610a01 +184100 0000000000000147bac4b537341b60b751f5e3ba13e34089796d7b173fd4f797 38cc7e77b0651b6bac4b805b25234a089c14b5b07a79b42f56864837dba32881 00000000000002225e8cd9c6d4a787dfc4aed88920981c9d9c973e9c55ac5fa1 +184200 00000000000007879b4e1d915fb00d684a6346d8f0cddf5d84eaff7705deeb72 0c1ffa1c04066abda00a872dda2480e1a6c131fc836ebdf5b74bd8388412dd1d 000000000000069f5e46f00010a55eebd1cdac5c79f00dce4273394b1b1aed30 +184300 00000000000003065c6330968372557eb1978cbe1258035e5862f4d783b77e01 d3eea5fc4223aec53321a112620cfb14be329f1b91d97c4b427eb704e0c29d17 000000000000051c471372e456cd39026bba15466343137034de17ba6b126449 +184400 00000000000009fb73e6b4ee417cff3534ab9e613c8bef249cce639ac3948b70 b71dc66713f3864b8810348c094f83dc5f6b85b2186a551aaddc817a0a3b980b 000000000000096eedf914b1311cf709077acf5caec03f624283411d3a1c6d88 +184500 00000000000001b2a3bd02767c5a9000d87ff8654a43d437ee3df44290234a5c 63b3fbc385394f87546325478d2e1304b184f86ae10aa54125242332839c496c 000000000000096d0d10d619634fa7af19b8a58e505633501545f941c80c5c31 +184600 0000000000000850e0197806e9ad3b28b8131df20ce46c604443b7992f941bb5 7bad1afb5fa10acbaa1aee1f787bd4cfbde11ccddf6ee69ef1431202464bf7f9 000000000000068132a6203ac96505dafd141b324533498a4bd558f636e2a02b +184700 00000000000004e2dbfeef0699e12bfb90ae4c3a639e5364bc23263609e2fcbb 8e6b9ab5db458b6ce8d5673fd528fd72f3bddd5fc5cdffedf84d47f4dd641238 0000000000000010158e34fe10b1c95a6621872a4725bb27c1215436cc194213 +184800 0000000000000130ed43fc455277317d615417d54dc4496cb1ddaf2ddf9c9e0d f971a591c3257b067aabb61633292644ac79b5f24c46dcf12972387316d13a5d 000000000000030f324d3a7f3ffce38338069c6319fd6790d9f60e30cdc4c5df +184900 00000000000001509c47730450bcab99dee0858096f0c99deb48dc0c6d73cd55 4f51a5e09dc0b83d6c7c41beeb7243016746b26d490c1dac8d7afb0f4fb47c92 000000000000009e4b8effc12eff8d43c75e08f3a1ee3aaf72f6e87008c731f4 +185000 00000000000008e4a049f80eb23c83c71f3f2bd34f7a50caf66c17511c40dc13 052a23801f853988fe82f34d4a07688604f31a61049d8dd682185011eec1a08c 0000000000000566eb164345a545c66780a17f9dec91ce0a8835d77e16ad0cea +185100 0000000000000a97df9c7425ed7651cba06a8237e94d3ce315e4ff3fe546b7b6 537ae9ef6414c52ec1f962fb0645c6d9b711b2cd3ea5b5033ffcbda4acb6541e 00000000000009f8e3e3449e44c7c7f50c0a2f46fba6183e99b5cdcb1e1f56d3 +185200 00000000000001cf6f9b6fa17873c98c2c16c13fd13f768ed51ce25084bae401 14c6a3de03484ecc82e934312d910a27da8f1dfa60e4ad41d79c55f27017a530 0000000000000015c9b18c8b33e111b58be818dfc7919f86080ae2236886fabf +185300 00000000000007f0f79c7ef0dd8f38c2faec5c3b63af47f4218e289564dc5851 670150147b8db60b32427b7f6a663b923f9f5be76857da1a8e354b5e55467b8e 0000000000000155d0f930554f2e7213a5fe6b4d48cab1032341abeb275ed525 +185400 00000000000005611c51ff11b34bacdfddb757934dcc626d9677f86104d77cbb 9a435262dcd0d3022391d8f1833efbf860a7a7618d3c1cc04f56cd7a886a6ea4 000000000000015e8096ed1bb2d28193cf88e9142a250af3183fdf1d92ae36ec +185500 00000000000005c4805d0c6d88eac0e943f085352eb52782bdfb5d46a046120d ba2525c4fbc2be5d93fa63541edc7c7e0f6f7e4543e50c791773142f9e09ac92 0000000000000291ac3e60fa3df5db20a631d75244d217adcb23797b2df25c36 +185600 00000000000006dd89d1b59d55fd49b8999003b2a2e1ab8b1118c356e9e99ab3 6dfe8a2998a9bcf1fee0fa43d85a79aa22b38d9f2d836853229517366f9d3325 00000000000002fe696c7cdade6076acf33027ac5afb1605812366c31a08b342 +185700 00000000000000edf3eb0bb52b748382193be6cbe9c280df264b45de5bc55485 085899c3d28af9859fb1eb6ef177581b34eccf996664db8441b595cfd1096940 000000000000025e270b1cd0367679c0ee5ba60ef5167342d3d5dc104f7ac12c +185800 0000000000000782e6655b2cedbd433ee06ee022274e9bc2965be5548562cdd1 183c1ace1141d20c21ddc5457260b405a67923347dd32b767198e376eaf5a940 00000000000005be2df4c34bae818b7dec241ece13741b43bf818a61db32c3b3 +185900 000000000000053827de2fe239353399d036ac6a081879e930fc0832597f6f91 1267dfd782153f787c6327ca05224f4d4e653124cfb93b6e9084aabbfcee821e 000000000000072f91212f4796fc549c97826a72f1825c57323b1ab280cf617d +186000 000000000000072ede9629fd1fd1af3cc2baa0e637f1959f34884be0e160dd1c 5c0f4d85aa5299ac1edd3c1f07ee6c880bd6729e4c1d67a5469b710ec1dc9048 00000000000008db6520c33d4d75470b1a5fc5ab34670655b6a18f0ca7b860d1 +186100 000000000000000a2c994baa06c29ae5ac2fd901eb1f0c9816f8357b12501bce e6c4bbccd4822e5757a3b6f9a3574bd62e65e38bddbb8b7b9908fa08fb24680c 00000000000002eeb6131ae775339a79efc440e7c063d63a4479ac131214408d +186200 00000000000003a03cf1ad77a3d5ec07bc78ddb941e5221c4c424186265f6168 e44045f3989b3038881519e66e8c69e8c1f43e7ae9ba45185ce36a42fcf3f983 00000000000007ede024ebd38902382a39d9902ca2fca18f45f041e27405a553 +186300 0000000000000566300f60e60a76570ab3aed7d9d9bbc342a444c353a4c19af1 1ca89bb7b5f6ef2ea33828a5b365b25a3d19fcc48799f6e7dac9bae513718d9b 000000000000040e4d1da66ec1b11860d9efb116732aefa94b440f4ead2d6c5f +186400 00000000000002cdef80e2a76c33b09d1ce9152e0a5914945f4e35ff9b148454 d56a8b5f41cbb39d1656502c2948573aa44bc1c26e12100c698cf819bed64316 000000000000048d1d9988c67289c24ad8eb39a572f9cc73aeb61bc9870b85ff +186500 00000000000007fdde6f714c606fb2dcb791e664c092d1b05d68063b97b4bc11 dfc26e06eba184dd7500eeef7f6600975be4818da0140c87f0e71fc1203507ae 000000000000029a8c2051564be5a9375842044904a033349d73d95b91b97e2e +186600 00000000000006446e6221a147f8adf4ef9161a8ccd3aab02e684b766a9c47ee bf13917df1e7b7af0acb632f9ce3405e1e28391a30ed49bd2ca400068ce87cfc 000000000000083d6b95f9f74af10687dc7243871726e7b3f26019de66380c53 +186700 000000000000062845407b914d9e5ba78b09610ebfb1e26eafb5ba5a984cf452 c04a4091316bf32b33b41706462617beead9fbefde3c17cfed05d279ca254a9b 00000000000002ed3117a236a791f19a171b33037b38792f13a512ab24f5d704 +186800 000000000000011f19a01e07b865c3823c6b2e6d932cb28ee28fcf4723bb719f 03b1b492b9cbe7df58170cad4663a7e814cec149c5658838ff216e1fcd6573e7 00000000000006fa471f37aafca8e679f389e3274dba6736f0acb9c1fdcb91d1 +186900 00000000000009909936cfa9e58dac4d628e61e77a6722ab3ef066dd471cb9da 01ed4c2cff850bd76bfc9956b0bba1985210f31c82ca527c22a8567da355e618 000000000000003dc33275dcd0261d0881e59567f7fbeaf5cacff14001515b30 +187000 000000000000095cc058085cf175b5f61427e0b505ce6444f2abf359f7d5542e 910a8318a50d158139e1565979894b99e9ceef7cb3d2f91f8ac436f394491231 00000000000001591ab1919c101be910ed4d5c0d62f3cb5ca5d3a1a094b2ee52 +187100 0000000000000991a62d8d84435331f61315fc7873eff4896a447e5a865537b1 9f962497e9fa38ddb772cfb6ba591377e0d9d76a14612584eec3e0b92c1de828 00000000000000358234038272c11b895cb60198c9fd3450b25eeac50a23807e +187200 00000000000005976f66382caf10f1f4c2a7a256b1d2dc8efadd64353d3a47c1 e65ad41577ac60705c65d77c8e4ee8e00d0ab5c83b3a78b383cb608ab200f43b 00000000000002180dcf38a2c747de22a97fb548fc48412555118bed7e42ef1a +187300 000000000000014c3ec01bf7bb3963359c8227c2100c25bfef3cd45bcf9362e8 0c744b8382931bcb98f8573e36441610e0f56fb5582a4a227453eaf8e22e1d56 00000000000002db28810c26aa83d50eb1ae18c4bc70416895e093d13200160e +187400 00000000000007525b8c2a4e04d9bd98ae8b2f385572fc1e276c8d10711b6494 5b5ca68d08dad2362600e00e3d98e1d2e5f0fafca49b001facdc2e6bfbd02c4d 000000000000045e04b3319d47ee3aa7e77ba282835f4eec8354835a812ec30b +187500 00000000000000461dcf498b2ba02f19dde9a98bb126de9d8e313b0bcdba5bfb 2a71a42e7122ee1d34e3ba27d447ae8482e38a63737b8f11ab451f9e2b86dac6 00000000000002c9f400bd231973e42268c191d7cbe95f199340534723fed784 +187600 000000000000009555a0b09a482720a894042fdae60a7df10cc2718b596c220f a7a902d0ca71d7f2802ec128b89aace0f1d4b44c2f07c36ad5160cae2494138e 000000000000036454d28f39c93344ed780df49d02ab9f2230ed950918bc518b +187700 000000000000040c92f7d477e566bc723ebcd4cf0aad2803a7c8b92746cc4535 f2df0521e7e9936d05a5eedc99f6570da77eb296dc004c35e6d25f76a3a22dc1 00000000000002b6d1dd37363e3447e92d0610370ea338ed1c749e385bfc2832 +187800 00000000000004fe92d436fdf0ef877deb799f1e6074e18983728361d99f3644 eea5cc6db5e7f24fb4ec413d3b075b977022c86917c149625ba043279973cb35 00000000000002cf9c80081b76048526d56c132e7ec9dcee361569a9c86c3614 +187900 000000000000088da52656394bf954c9900c09f96746f85c7458f69284eb79d5 661202484fa63ad759111150ee35246d9e5059f29698a91d4bcfacb15e9b54f0 000000000000046f6d4db41936a11ee8d5c5a7ee534d0d9342daab1659ae9e54 +188000 000000000000004cf0c72d6dedfde88ca4c3dae129563210072ee68acded0ab1 5f7d33c54844e04627fcc5b4369953764fad3116904723e1716c3c9d576e8339 00000000000000b5944dddd5dacf2665d004e5a10283df8b9a387725315c70e7 +188100 00000000000003b9fc08a35afa5e7eb21c9edc1f36909ea3d3242d0ae6732aa7 b193f480e1ddfde40c1e14152bf1528427812b76afa43c5de750a2fb4de22ef0 0000000000000154d26106e3addeaf6843dcabced345b511f66c31d4d05c6c12 +188200 00000000000008ee90b65bc86e2f5655d7e156f6d8dc75fbfad33362132764c0 191f42b426ce0ad41b40fb089af881e528ba8b765d9007d240283b09dc4f5902 000000000000061784a01e82ad1ebe0cf7d98e72fd9c50549fe1789ba8d094e3 +188300 00000000000002ad7744e04478a082e67ca4a681a7edaafde7288b6ee9999fc5 b414e285386626d91e8f25fd3c76677f7a9825cb8fdf12ea7ac2a5be3d469493 00000000000006e22fe8c11888e6fdaf1752e4de1c2ae5b32da5e0ff6a5d5bfe +188400 000000000000033dcc678a165c3a2bff8e716cad2fa5a3c5a87c2ff9b9001100 f86cb1bcd0b10155085714340236072f6e9760b87cd44d746b7d33eb2902eb22 0000000000000447bfc853cde5f196141187cf32586e863c703e0736744af0a9 +188500 00000000000002fa6ab13eed97726f775d351579043968091024ad316bfa2dfd cbf9a14b34e246f1af2837c1a85dfb7678bf9f5df600de4b0e6400dd8e3964d5 0000000000000939a36a70339cb9c424d67951a8cf3b1f8cbc6d2aa31dad83d0 +188600 00000000000007dd802316034a296520da6ef3598d63e99237cdeffa054b9f73 7ff637e1b9f98cfb345f4497ed845167b47243d62c9d803117df4f55e16a1abd 000000000000050ea601ed98623e384481b8e334c90b566dddd790cd1c6d3fc0 +188700 00000000000003e7a632b8987c0a05eb2e69ad03843b20ab8b95b5756994ef3d 03aeed02b3052cbfdc346622d6685142b88ed933e2f8ced21d435b298a02ab14 00000000000000a0ae448d19f1634e7586702fe0b380d0712bcb9232f0f25c64 +188800 000000000000065eb0c98bf7d10f5f1b4536a3f5b0ee50a295e6e0c42a8f4ff8 0bc9a9874cd4776f3934f721857d8347964b59dd4c781d07730c2438494c7b1e 00000000000001ca8155fe5d7b6e4bb2b9d0b02c4b04d48a8bd7ec2b7efbb659 +188900 0000000000000478037f327467de140f167065bb19c34a9fca77b14302299a18 5aa09d0fede9c6bcd18dd9dca74058899c9c4cde83e0139d9fba5d317ed8170e 00000000000005b1379acf645a0dc00e6cc3d70193845a437047fdc1e3f8b420 +189000 00000000000000cb70eababc6787d13fd1c157f487145b97a15339336855d797 a27c3b00c3464e8597344c33b4b1f77c10f99a993d9f579754cb7ebd77beeda8 00000000000001d234cc1654342cbe77710fa4ebb68bdf5218379c7b35f85d4f +189100 000000000000075073016e8fca07a4a82db437f486f27a2ca438e518e19759a1 9ddb0d70a93560cadfe06ab75dc68750efe2f262a415ea34b18318348d23f907 00000000000007f61e9712fc5cdf5d5f2616d3fc31af3125bcbc7cdc344b0ffd +189200 00000000000008e8f8039903f69df6bd245b4dd75e6ab750805d96d4fc02b972 8916c19b7ca4f2b4d7b56f543831f955ce57f2eb775a9668d3a35c90b30f5a13 0000000000000214aa1889a124a4cbc47d329ca12d4c3abcac9a8aba250ccf33 +189300 00000000000002d06686680005c0ec6ccfee5ca3ae54a2fb51800b9cf09867c0 9e7e30dce44f35ce3b371d9ddf1fafabfebe0586947fd58473aeae0ed465ee60 00000000000007aa0853480ebb2a6ae8e38fe58158d245b081b54cadda057285 +189400 000000000000078c17e9d38755542066b674ea5ac5d4062486ca3e7d3bad9978 55449edc80ac8d8355c8b3d5a07f4c85e89345098c2193814b491269dc42e253 000000000000074171e74478711785b9cd59b76dc34eb047a7b3844253763c7c +189500 00000000000008a9b61e18c2694b425635c146c7603c2219aa8c434c2ff0f7c8 fe2f869eeda4bc90a16ab60dc622054259e84276cda5e724e9cf89e56923a388 000000000000061b88b57e532523c62f948cf16bd4bd0d98700e0dd03a9a6487 +189600 0000000000000098af19f85b74f55b6a043f89a62d175dfa1b0b1dcbc45f3674 e77f85683291f440269300250f8c508919fe52b9b6d8393810e3d9634fd0e6bf 00000000000000556eb5d681ad6a5a5b73e47831c00aa51a6362063aad266389 +189700 00000000000006e80d10dc50eb0803ffcc872e0e1074fcab7cb7a1d21d20ddbf b3656003505ab09fae72ab6f2cfbda1d7c19f85f8530c1b96005df85cb6bc083 00000000000007b23cf22959e77383f33657c60c4db531c7ce4086876cb9521a +189800 00000000000001009c1d9bbb2f2ee10ebeaa5fcc8d23b9baa299538de32a566b ac33f077f6f42bca0254208a140df6c8b295c59e599a28b9d78db19298d7ce97 0000000000000772f953ad6367639ffcc960fe4a2efa2ece6a326151429e64d6 +189900 000000000000055ccf03a628b58a69e2afce1f938741bbc1c75f11a00b6548ea cab754cb8c0c38a70f1f2fa7f9921653720efd0256a42f49f7ce6ebd01cc4abb 000000000000071eee5feb1b386aa706b7d558d658cf23c9f50ba29edbecf56e +190000 0000000000000708bf3b261ffc963b6a768d915f9cfc9ec0a6c2a09969efad1a 46c4701066f811997b57764eeb20b22de9748afcab27b64b86c61d4db884a6f6 000000000000086f0e0e1666a9f1874988cc16d1bdf3045524d72a0cf72684d0 +190100 000000000000082c6313cae4d9373845f0ab584c2458209d04ad130495c755ce ead0fbaec560cf4a4b89ebf9ecefd2b9276b96409a5029d1ed91aee2e34b643c 000000000000023188091b1693bdbee09b858c9b636d7f884b07186621007bcd +190200 000000000000007dd4065aee391fe2e68862d060b495089e29596a9591af5c84 c611bd214aae40087aed5de39bf8193312657425f83509d589f6cec72d5685e4 00000000000002e51eb56bc3dea3bb9229d6146f3beac71aa4d3777ee900fd30 +190300 00000000000000492615f40f7e063e5e69f92012beb04d38d54aea6d1c479bab 6745cc88123de7e5a7a409890ae1eb68299af97d62061961d2894d2ba4db2902 000000000000087e6e165e38501096a5ea6680d170a7450836bfef138aff5998 +190400 00000000000006a6db93e62479f809c6afeb4728427f5cd6b572e559799532a3 074071e2d6b2cb66f42ff3309c5b5850a025931c7f7a6f9bc28aabd5de876106 00000000000000a2110bf0ec481cedd448268d9ac2eabb8a6c0a75954ffc8cb1 +190500 0000000000000531aecaf3ebf3843b758b0a439c8c587cf02472f714c1f975b8 3d3635111b07538c94bf2cad52b108f8c7f4e6aa3a29efe1b0c27aa054e85530 0000000000000599cdcae885b962dae172155aa6d35d7b8a3e468f6fc93401c1 +190600 000000000000030bdd5211f5ebce889a3b03ea5ba7257cd5d1501c4b858144d0 964af8c421ac244fd0b3bc3335fbbbad98f77841bec768ff12f59d50fc6b5fb4 0000000000000778b5466a5802054f6794252869433f3b381463ac232fdadbee +190700 0000000000000552eb2b642e7090a7f91880209938c0451b0135a92893365944 7fb10847589b4d3d18e4bf4443c9bd801797bfccc44bb48ee4f28b6ec4f35b75 0000000000000160bf4de67b567be3ed287805d451b949a07049a424591999ce +190800 00000000000002fba30b75c3dcf513ceec7da75a98106c18451e4fcbf48816a6 b32599593461326b0695980c524873bbffd3668d0095b1773cccbd08983ab4cc 00000000000001435644c3901e77662ecbb746add51eec81db5b94563ad878e7 +190900 000000000000081ecd8a2186f6d3e076defd3822b50c5b93f75c824963e29938 17bd122b7693d44c1e946ff3627c55ffedc152e7591cd26df907ba2bb7ebd4f9 000000000000029f9f9fa3e1e76838e0d073231630560662b7a611e9cadb90e0 +191000 00000000000008d64e842b503d05d2e863dac578127f726832295ec92428c27c 160f1b0a4deab69c5ab39137781df0dfb8a5573ce05f23264589ba1bcec9d386 000000000000052444ddd654902ad6f5e5cb19f8d74c252e4b6a0f549443bd1c +191100 000000000000034349e5550aa3232ea28c115e452a5c53779a0b6ee0401c7746 a8ff08f4a394662d52ee4e42861b20c1f69d23d2aa50926cefe12b2b4d4f2124 00000000000008a1fec6779facffbe0bbf065852a02badffaa7571becbb40267 +191200 0000000000000318767c948783cc082e8cd1b58689d5329842097e5e882861fd e7a5fe31521d8abf97485a02201e228a8f772f7741644d2bc630ded8c1597229 0000000000000273b020ec9c2433d0ef9fd21d55cc89844dc568a9340aaf9f86 +191300 000000000000035f724a32148d963065bb47b5fdf4f13ccf92117529b291261b b8e947eb7bb8cef0a39d2d9a465a064581c68c78ed9ede9bf92488b889cc1b9f 000000000000075e928fbd5fb9ed04649d3067b9e2d1172cf50aa9bd4843ed5a +191400 0000000000000203ff8dee3bceda4f478110ac8ea2a47f7bfc3f5e546580ea9a 30a2ff47d7f40de9aaaee1321bc994258769c886d8b2c83b51725522e46ad73c 0000000000000673bac8fe24f545de12efa39dfb68efc3be18c2757717ad600f +191500 000000000000036c2d1cbf656267fb7840f40651214d6d01f8c42c9c22540d9d 69ad516d1f3f08f1eb2087b278ebe78aaea5a352d71432e091b8f95b64a1be22 000000000000030b5464d9433aac1f286aaaa7c24d01d6b76c35fdb80df323da +191600 00000000000000befc56f825e797be240dec437ff3ab7e9ea90d2c0d8b8e1569 50f918f67af4667e8cd51f9ea1a292090dacba3a1c237a64f3430fe8c1a6e1be 0000000000000353b60e3f4575bbd9f3b6fe0ea16a70b0ffb19bab875fe4db43 +191700 00000000000001e2ddca277e64cf2bcd026691d118cd810658633153630c6aef 8a658b9826ea823fbadfc9eb44fea328843007969f0aca35073727badb09a573 00000000000007e792ecb76382b9f74dcda57be791e25f4858aadf259f74d97c +191800 0000000000000285297e16d9456cccd123b04847f68494b97ed43fea3e118d04 5ec30575673273927d36f56cabaa99542c49d631b67a564bb4dc0ce3746e241f 0000000000000585269f2f12630ca90902ef238d79bf1e78dce53d66dc2ab557 +191900 00000000000004ab679ca15d78ce67bce7120b277c66444e5d0146a4dcae00b1 d59461313f8806b1eaa057ed348cc0d8aff064d51a5131e38ec1542527f37701 0000000000000497d4fe897690941361c0da5c5eb8ce1e6ce5f9ce3594654610 +192000 00000000000000af130d565291ba49208c546685c69b48a293aaf06387fc22ef 34639296607b2e585909f7dc9067dd2c3d172c19902f934d8dcd02914822cd2a 00000000000002b1e750d5b58c4d7976ecc430fac70b24b4a8b4246867b43b00 +192100 0000000000000261a8fac12041ebafe2185f671f8ce012b32f459b1d5133f778 fa4a7897463e16247e139b6de62b141587aed864b478964943cc5cd25f133ffd 0000000000000127f652b22cfdf9885e8aac5a3b5628ed990cd3020f2a3058b6 +192200 00000000000000d8c5528d9578809597c776795a9a12ca3e98345151fcd3e5e4 ba0ecc0f2290603a7af31b8b1baf7b038f8b498a51500dd340434c890e25b09a 0000000000000417cc86a7e4a0f09627bb35e18dd1b4742bfa89c604a763d5e1 +192300 00000000000001455e870671ecc775edb49f3f5bf4238e32362e54b899727a36 4d223e2ff29d592c6fc514fca4984fd3ade0c49ab91be5faf5d2bcfb1e522e9b 0000000000000289fbf28416198c5447edf2c3fb3a3958cc32c32c102adef7a9 +192400 00000000000001ee54bf56b79671a9c152d1aa308a9191cd0722d3a0259a8ccd 54e695ae4ad82338f48dcc368476274807b9a3a6fd7306f15f814d41d96c854c 00000000000002cb6e11aadfb033fc926e03d05d10b82e7bd8da9e99579ffe7e +192500 00000000000002f229deb68fa8782cd3697fcc33be6fe819fd56a00402055d17 9f168d7240cd7792fc72801e6cb8a82f9da359083e02427e2a0bebf130282120 00000000000005fde0f8ac3f1aebfd7e194f93a4823df3d292cdd1e363b866a2 +192600 00000000000004b0f4575a4349b4e4b7e412e68e13f8c5deb1ffe795ff3ce6ea ad7904d57a9d604956ac4d5af2287285e11cc5cd087c916889f41599535aebac 00000000000003fa73b197310ec01534523a009f774dc32f95bbd00ece9401ef +192700 00000000000003915dd4624898adea7b6a3e37bcf5bb6bffa8a2686c23b0139a 717b33dede19a60885288aea7b3f8ec008aa3e6f6ad42b92cf8a760ba9035ff9 00000000000004f058bd1b672f021c4a205779af0a25ea65a03e36543d672593 +192800 0000000000000681f69f4f29ddc4b50b357ce74391fa57e2c5f7a3f314feb0fa fe44239c4f4fece837ed4455c94ca29460c1445e9bd6f552678847ba317e4429 00000000000005020b50085af4b8f7ad23e24f2ee6ad3f56d9c9b3489310e989 +192900 00000000000005d6d2deb2c2b8960f7a3dccc95d41c8b7094d862765cdc5299e 27958c23c227b23f6aa1f563b6c2c4a650719fa59e8ce88e65a75232945e94ba 000000000000004cbb9988878934abe231356c0891832ebd8219302fcb8956da +193000 000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317 fe638aad25fddf97b21c2946a5f2d8bd923b8ae7df9a17a923c7f3a9879af9e7 00000000000006a1e50bedf15148d15aafa469aa02c0e9ad1d8fa3a479bb770e +193100 000000000000007f1284ade16a27f5746194d512bd1e51c65f2d2505bd8920c2 1eaa7c57c028f95ef26d01106b856e22baae914b4ce8ef43c7801ade7a9f3f62 000000000000010873caa9684e0b7c8b137bb2174b7458eb4f535be09ac124b8 +193200 000000000000044413bb4e28fb13b0752c2c2cb50a93e1744052c889c9670573 fab78e73cd55d0a18d7b101cfa65f855902b4998d9c6c4116f4da440e2597d50 00000000000007dfac031cbd1840183bdc4b5a1ced284492ae0b752d72a91dbc +193300 000000000000008b9ca2182c7bcebed8219c0f608a8c6021d10341c5ed440f03 4388216697694aa8a37a52fc0091c7fd0febf81ea78627533df754824c0bd19b 000000000000078275b9a97c6f51cb567afd355bd3e52c93d173f2f0e99ad1c4 +193400 000000000000043b3fc193ad9d9d31a1aaeef3328037c63fb10a6ac459f78159 9ec485e8d46b87058e7249a6899199e73e062678d22259d186c21117ea7de5bd 00000000000003612d75e06e2b67824d508032ff541a67d6bd2eae03502577c1 +193500 0000000000000333ab7e1d57889e5d79e8c2ed0c05f52f41ccbbc6364a34a5f2 3c51502438700ee04306ea3a7cf93da1a93fa928280d449a7eae4e7f1421c09c 00000000000006dfc417a2d778dd9c372b9a9c7338209efe6d437b66317c3582 +193600 0000000000000340766c3af62744ec1bf13310c15fce8161f0fe44679d7180cb 8057540e270f82d4de5342c2340351288247e2d8bc26e48652fd517accf60cd2 00000000000000fef378c25a49a2243689f4aa9cd57163dca17aac93adb81ba2 +193700 00000000000005b7e031a4dfd2a96223f7f5cf9e7ce257b5c738881b113ac6e9 caf927cf86d7fe2c0b845943391e0a2de775e662248040b63913c83293e0f48a 00000000000006cddecb4c66b1007112cd2db0798aba9452b7e19e3ebe0124b4 +193800 000000000000052918825b4529465a3c8b3832ec5ae357b7fa5855e5c986a0b6 3ccb09ef78517e4c238bf98a9ae62a773c8511900167e299799b667bbeb0cf8e 000000000000014514a52c875500ab08e45f7b691a6ce1fcc04e5849c840be17 +193900 000000000000001c4d1e4324fa14028dcfa8f0b8605c738216702851b49b29a6 d2659465485e3650b7b5cef686540393bb06b15d29271403a62a6aec53683afb 0000000000000498b29dfb7c89da263c4bc1c3e16748f5580e122530f39a2488 +194000 000000000000046242d4984ecf2217e9afa113f2835bffbff118f2df4d80b216 fc3803256cbb14fbd3ae3300cef517c22a198f3365b602442c0f5a11fc18b5c6 0000000000000368a27aba8f6ca19496fcaf1e74728f34a6befd4b28ce734681 +194100 00000000000005686a48f2090e6bcedf04530cb47186ecb10f5821fe227170fd be27ea6d337acc9c5b6a489729777128e78330823f617156f821658f01e6729a 00000000000003a4eaf939b0dc8472de0479add51fb05575e2bfdfcec7803dc0 +194200 0000000000000398d308463103367d2ccc00eafec0ab7a967cdd7c42a59b0cad 443761e48c6e174105786c246996d9aea164a440f020ba31cf6100e25c813111 0000000000000299432194f7fe0fe6886f1e18532f8d9d2d7df8ecb38c76e147 +194300 0000000000000404eab63156257a95bff17d43f00512ee5cdf1d3c210e51d0c2 359b543ab225ee135eee4c5ba3743a3d62f2bcd5c625fb8c6920b4dde5bdeb2a 00000000000002e4ebc841794229c416ba5a5897eb2a4aa152bad24645f8c571 +194400 000000000000072d9a416b711243a46c4c9b9255bbdacc7ea6d625bb943cbaa8 792e63ba4ed7b603bbc387798db6c156407d852b38bcb4d9b6157468d871dc3b 00000000000007a4c41dee46c1bcc02dd21e685c1300ef615f42b00b1ddda624 +194500 00000000000003361d05c1c3be3f74f0e11315a60a3feca1c0af049018ad312a 2de68877d265e6d4158884e30c1a32cbb78ab5fc2d9f315b432a2456332ef320 000000000000076d62b021071bdf56dbca985a30e0cc6005400deae38682b583 +194600 00000000000003a8bc44d972f738b25320d247d41148df48cf3dc1ce9c99d9cd 57aeb7c3ce12d15d822ba3beee9bfa39b39003c51f032993aaff46eede7997c0 000000000000079220edf2cc3bd63e7774605d789a181a831bcbf89ea76b18b3 +194700 0000000000000688e74f08fa4d4a10b2756d3e92a3248571b8d9e9e4b853d776 99665e7eae773828662e538a8ac99b627b5af8403f2577444946aa018b7ad33d 000000000000070c28cdeabbca7dfb51e9dac9f83ba85ca7700f683318afd5c8 +194800 000000000000059a715008fbb010c01e61d3fe25ffb7034034dade67c6abe82e 1d6ea871922ee31aec6802234b680596bccf6f82cc9614855f962483171157e4 00000000000000ba8811d1a2b97badf087fee4e9051e167ce11b6e7048bf138c +194900 000000000000029afd8707be9a5f6c8dbfaf752a9e849bbbe61d6a0aea2c5628 e1b0529d24f888e51c36e2245f98473d4ba45274f0a6da03c819c0483f648da5 00000000000007960c5e50fa7f2c6ed0ab4374aeb13a8f8c9880462b63cde362 +195000 0000000000000716889a0c9c7d773f1cfa65cdd6a60a2a9da18b55c9a1f14a33 e9497f45135b1a748091bbeed36e8a284782552ae93d2a4b619c110d4d9c28d9 0000000000000443efdd88862b1dc1221b6ed517d3862822d614bd213889e68d +195100 00000000000000b70b732f89db7ac741ae9640f7342a1f5bd2c131f99237ee76 ad7c998e42e884b1e4e5f0b92afea74f2165da49e6d8ee9e1294152f37aa210e 0000000000000281f5f75baffd7ad6c0983fc6d1416b3554f6ecce9d0cf59a10 +195200 00000000000003a95d78b1b29e1bc7495ddc9d3124368b0ebeb3827ad17b5926 dcf458dcca766284733c1bdd69eaefa5935950fc443c0b277a994d4e5b9ec8b6 0000000000000574a56ad8306974825d58021d69ecd466a53a3b809001117a81 +195300 000000000000013aa6443b4ba9c8f329942e478a6191ccbfa520943b76704c67 913aab071703f05bdcbaddadec1a1086e267f2e080a57934e4a8acdb2dd29a6b 000000000000008e6e8f09ac5b0ead9007c9cfe7163e536ebc2158fdd42e0285 +195400 000000000000018c80c684acfbf9e7930f31e56f9b2973f423225436143f07d1 0f921bdafe092658f4875257b89cef8a56001a5c941c01cc7980f34b6928e848 00000000000005eea22eded8fd8d46716b50dadb9d04206cfc16b9824f46c9e1 +195500 00000000000004d9559a4e5aa19c4f3f29fe9c4f698074991357158911bc1bb3 359723ba082f6e6fa8b7bd4a68954cb091fb404d5f4e73c2f17b5fbb8d0462f7 00000000000002604b9d9983cb4b7aafd078b3d6108e31d50bbb9ff6f10940db +195600 0000000000000674655ba2ba2a610b2a50f9c74bfcb2d43a5899ed0cd42ad1ae f2dc7d4767761a0f4486c954642091bdf051bbb2ab33bac39557f3bed7d04c66 00000000000003c8d76448bda281686731e8fad180df23dab2644682806a6520 +195700 00000000000005d47dcd7b093c4dc469781035acd9ee5cdfd3c0acb017d9f5b9 6eb410734624fc1bfbbcb55d281f43f9e4b0f7f5e8686e5332cfeecfcb9b7e57 00000000000003a0665e95c0511505fc85180ba642ca17b5cf7d4bd5ce69306b +195800 0000000000000594ffd54f7683d0d142936227e9c99cb25f577d91f9137494f1 0cf82bef3b4dba44bcb9c8fc8bbdfa26f8e9072d07e9ed1e9a216b9258c57dfb 00000000000005aceaa565367bfd353e16b02621615da758fe2298fac50bd3dc +195900 000000000000039388db211249e34973890cb0deeb553f40100980f7c4dce038 7c03b923814a0e0ebed5d9c831201e4c134308ed7634e20e071100c93fd6f8cd 00000000000006c74bc0eaf942f5c93b53afd19c4b7d4b0ed35dcfe549ea824f +196000 00000000000006ae59396d4a289e83fe1b9967630752a5799f064620af7836a9 c784d76e8f0c1729e5c34559f01213f49618d723b6dfe4b489fba91e97dd5418 00000000000000a0b861ff4767ada7d0310823e9316af4208275237554c247d0 +196100 0000000000000299bd84a24da62aa17b5702133bae85ba3018f67952ce1fac6a 9238a42a72f5884874a99fb5f50fd13d54124141ad1e0289be2ced47eda21ab6 000000000000044fb44e0fbdfbb5944d6a4c2129916df4f168218b73256a1e93 +196200 0000000000000671f8eb6bc77bf0972a18d829dd6f97e2bbd68222bc97eabf67 baffc25b6ae5507a95fe808cb611a7769dd041099dc7fdd8eb94f8f010eaa493 000000000000046ce5b2f0746f39c4ae9b6664a35091e012d4db790f97ef0a67 +196300 000000000000019d8d9cd0a63db8c77d129bb628012e0c5a3602d2af5f82610f 76984d40935c6c5cee2241b4c90ddb916c5ef5d507bb3b68301f6a11d0026a45 000000000000069fdc882e5c26681c99e8c709d372964068e090851c347c0795 +196400 00000000000002ffdac437cb3d131f39b5ff793b0997207aae64b614ff7f0b18 7fc4371dd0e8e34e74c53dee60986e9b6fc551ba641fb81421274a6198a46de2 00000000000001ed55ad94d864cca267f1afb7cdc5ca7c711c891648340b85e8 +196500 00000000000006bdd8cefe72fd2830b193d1df2eede2452e0ebf7d2c5345db15 fda3be7b81c8fd2b3e5fe04aeef4b08ef39aa27e62e71db7b873320d9034a6d8 00000000000005b11f0677bd5d944217d46cdf227afa065bc810fde5a6f161e8 +196600 000000000000044f8c564d82cebfb9d2217ad254779cdf95ad5a9baddee9f3db c124084582a19609145c130ffa3163a76142c09442ef4b7321a61eca136387f4 000000000000037fabffc3637f57ef521d297aa922bdbfa0ca989b23f6ecaf96 +196700 000000000000068154c246a3e250691aae05feca083b24cdf27817f6c0399dea e54b1d90e08b2b971ddc0d63478159b43daacf94318485b292a68b73327ebc4c 000000000000035132ed7900b22d1cf41308ccbd066fef3bdd3cfbdb9b1af797 +196800 00000000000004960f1f55da8a22c5393b962a0afdf4e138a56e6b04cd678cc9 a558b02918bd1dce0ae798bb371816f9c09bff0313fc65591bace4d3e2e61a2e 0000000000000030831a651ea7c6796dc8a449ae0569d7cd4926a5da88edcd8c +196900 00000000000006ae310893adc0a66d336195c55ed2588bbea18e08db3d80fad6 67493d3f9201d97671cde97e4570665e93bb231e4d93ee38bcea5dafe9fccc62 00000000000004db12b7946768ab71002c96410b74defa77ad6bbf560f7c7c1c +197000 000000000000012094fc2ea1b763742c424736748a4fafe59fdcf0cc92e1c15b a1a59f7e4e44549b1e11409630700362e3f0a87f970c8717034296e52fe5074c 0000000000000276bea3def6b28644f1dc9f0f0010b5a027f523a0c8cb079388 +197100 00000000000000461bc726bf3104c93ceb0f069ad63823a26fa9050b3d78a07c dd32ffbf4eb3f2a7dfb0241e134d5adacc3a33d1e23be2e9a68af7278800e348 00000000000001af2b13f6c43eb6e82ef56bc3e35a43a5e449a92922c2224f08 +197200 000000000000030645c114765350289bc11dda3f29b41872dff1f70c8a578fbe 85e24297c64105baa37c4000abc061cb893c77336460863193073e9254995cf5 00000000000003f8874785cf54a2885aa1d3aa796374697cea25553c4140c7c6 +197300 00000000000005aa14a22cafbbd3baea7534d388429c04b903368bd0fe23c031 2f5bd627061622d68b3bc56b89b190356a06e0e9cc381454c93f95d135a76549 0000000000000638ce17db07923da9a54ff8e82870b96f13bb43fd28667baf45 +197400 00000000000001fdf97f5e11f8ab24cd89dddb3dcc638f16a1405fa74540ca7c 2172c587cb00e4e734ef33e40652e9a5895c78e4dc6e280e0487265990918a01 000000000000013f220b8f4a859c8074cf918c8af4183ca304c2efbffe3afa2e +197500 0000000000000426196708cf453989f530797e643e822e2c47b931a5b6afa54e 22d8a1346bca79660149d8c3964da80f578881a3aebf60d81d532fac71beb63b 00000000000004838d75888b95fb5d7b28dedd62f87bb0e99a4742ad641ca85a +197600 00000000000001e36e86253ff39f177100c2b2eb0f90e0713f514976fd429a0f 5aa7283bc62881fa019a6fe6de3b1204d1e605e0e3933f4a7ccda18b6913df79 000000000000045cdbbe476c6b12a2827a60537373ee3d88ead17d75f9a867e7 +197700 0000000000000211e1bffcedc52b9b2cba1b0d997d2506e79cdd750a992888b6 5d3ac018dd49fa702696db3050c80995f410a996be824c050bf5d886b0cefc5f 00000000000002448b1a1fbe7db158c913aa23fbc0689635bf860a3e3fe513e3 +197800 00000000000003122975529d6e7da88ef5e2a01c726812c41e2c0848117c45c5 d7668351393a9730246957fcfafea564d33c02b783bf4ab21f8e68cac109111d 0000000000000306a15d8e2ff7caaa619e65ed889cd05ea3113a3c1684c2e366 +197900 000000000000054e8c833f882ac511d6a43afd5ef10d914d617f39dfdc6e5b4d abb02b4274d6fc6f7e6911f47de9af5f4d11777c3a81ed0ba64ea5eb07ff284f 00000000000005389350dec624c122479bbdd1884501080b5dde24aaa39e25a0 +198000 000000000000000f2ad431ff18ab1673d911395c8fa1f6801e054c5dcb54f8fb 4e836c56b7ade264002812c2a1efe1a2a332dee65e0c0588536af99f796c4884 00000000000005e980307d69776708a2899ea7af6fa376d15b0676dcef00eee2 +198100 000000000000052d1fc28ac2265dbe6c797a5a77903604785aaf5e0073b55ac0 f1de2c3737b8f226de73997e419d5342fc9ce29501a452d8b650471f1dfc82ca 00000000000000d9e166a752e55d1a5056a5c060957deffd4e2bc08b521ffe3e +198200 00000000000004fdd72a66a57c887b35f7c0e8ee5014663d1b221c9dcb996420 aa0969471814ef6bab6009f8751dd1eb44523f0c1c36674f4c7c31df83284b9f 000000000000025ddcfb97a91118a1d57b7dd5bedcaa74d6462b1b2ad79c1f64 +198300 000000000000016d7157131175af5ad44a01a5bc9fa879c463922b667effe88a 62eebb5928df3399ec9c128c77a95b5e8723ea0c03bab70ec4f69970625d4369 00000000000003f6416aad229d22f6c8fb2625544fb6b39673416115459ca826 +198400 00000000000005150ae967343f5e25f46138b27d7419f23a6c57ffc9fe9611f7 4890c4cf0af3c086061c434e9d47eb73fa2008e2bd7ab0f5abfba1b7f48818f5 000000000000020d29c701e67b6a2363dfb5391ebf3f0b456f058a8870a46ed6 +198500 00000000000000d7e44355a84e43f7a2ccb4ff227067ba48039cff34db53372c e68b903085021971f82d38b78f6dbd48c4635e3b283478b965ba0f6761a27694 000000000000053ec515c46c6b71ca1988b7f78667af2cf743d152e2e3119c94 +198600 00000000000005f174862daf4823ab8235024a1bad6d82e6e8ccf02efcb281a6 d7c2d905028b8cd5bf553c811c6a3314e4cced302377b3edcb7cd315203266f4 00000000000004aa38173e81b517cf1b73b0ee17e53fec7a3a09c15485b8b43c +198700 000000000000032dcf414fe96262c69f23473c8ca0abee3e7dc017d7f177a3eb 90c7e505db3ebd23443ab31f67a6b55ea5971347001b4a4a96177f7524c3f75a 0000000000000020cf5d8da3b445aca92a91745794dc0bfb5d1e7bf8f82494c4 +198800 0000000000000031d615f3a4536b1273967d8de0a6e1fcbd83b7ce6221abcf15 53fe2324aca93493700394dda24bf5b02d172df2c9bca4d25b31a4fef93a7603 000000000000048c31112e4af77494660ccb6c15c9315c5fab6372d271a7f3af +198900 00000000000004e69a939f83d9e9d4b4a8bfca7c60ae7de4a1e4b2c043afa0a1 37e816fe7405a2fd7b56a8f1409c0540bd6074b6b4f08370b6155fe09d571cdb 0000000000000614b4ba419a46cac3a9dce59b6c47dd34041e6a1ae737eae2b7 +199000 0000000000000397e4ff8f223d31783dc80b3720cd77fca21effd39709e0c9d9 b51f48ae75283303178569b6491763eeea9760c78cb905279225e020bc3fac70 00000000000003ed1e0d097b5f648f4d9d2f30127bc3d64421a1cfa1e738bb8f +199100 00000000000003bb7f96e6c50a55833c935eb0e5ce41dc565d16ac2ce22462fc 0326cd6cafdc0844a581250bffcab2568c7aac0a61eb8c3cfb006cb57a059dd4 000000000000005fe12f1a64c608a77b0e1a1649f3142b00a4625d53ddebc8d0 +199200 00000000000001f731d56d3122d7d3e0cd7c7b70c5cfa248ba0406ecbf26e4a5 35c88ea2d66fa8e1b978878540b12a997e3317b955a9c9c531fdc0f82d87dd6a 000000000000036c09cd665887417fd76517396c106892a0ccb887391e9c9164 +199300 00000000000003a6068a2edaa133637b19bd6901302ed9b059cb6f02495527bd 8236681c6ba1d01d4e78895698d72d17adf4c2e691bdd889cc3dae0ca79bda63 000000000000014d93deccf85aeee5d6858537965e274c8a9cae61376ef7e8a4 +199400 00000000000004c6d590deac7297c57c6f303022fb047c9cfdfecbc400a7f0b7 192e1cf45748df72a50356e7c657d7035fe8a94602f4a3e7727f8f59c34f6439 0000000000000579c1239d8f3e994376c84d4f5e049244679c470938a219e734 +199500 00000000000003580e0ded0eefe75eca1bb8cd9d605bb98a03448debfca9b5aa b93f97a02495f364de403ff66dbc178dcd833119507d834d6195f2006db7433f 000000000000012de75307beebc3f4c372ec10b8297fe9141fff6fb56340bd63 +199600 000000000000039e3b0c73c0705527fa525cc8c549f672737e3a580d6f242fc2 bb30ec6f8c0f4e12429546b19d4839bda390f453cf6db808586b9674ee6e70cb 00000000000004ceaad7f008d66bf7554eaae5781d0f83a48a3fb0cb03a4a2eb +199700 00000000000001fb7e83dfd3408839ff84027488d0f821157e6221faf4b91fec 9a29ee555fd532c192cc6ec5460c34f34997c66de33f1be12a2fe8e0a1b7c6fa 0000000000000553795edcbb8989856e02e1eee90ac9063d39c6777ee46cb853 +199800 00000000000005c0c51a720ad801af7313ef666edc358c7bdd2cade47c8f62c7 552fecdbd99934bfc50c467fed309f858621a29ef35554686bef87b6eb927ae7 00000000000005742ada8c07ec5be31f18dda31b55c1dac1b3dbdc37d39835e9 +199900 0000000000000138f016a6fc1666fd667b7d282d65ad14b7f0b16a75a2e90e50 10c79a459cc0482a87705e0788c4d9cf1259f866018fa5ba3ddac8488aea4cd0 000000000000056312cb86bd849f31d6260b1cdf709676d4caff7ac44f15fb6b +200000 000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf 1cff6b74df6e3a029c0b38f922fefbd7b05cfc515e6c0f353bf02951d24bfb63 00000000000002e3269b8a00caf315115297c626f954770e8398470d7f387e1c +200100 000000000000045d7f10aa3eca5beccc17aceb505592fcd8298e46bc8211052a c170aeb442b96ee349a40b5373c12b22ad2833f3382dd4899c1feace8c1ce425 0000000000000416a2192bfb5b883cf0614bfac0ed91ff4ce022091944bd648e +200200 0000000000000512f520a2448bf5d07c724fd3f68d74f398b1e94e183930add1 a578ee27852652b2194f8f7b06f3b8d5781fd5ddff889331f123b73403fe0396 00000000000000e510b96fcf03e27ad30f8d50e4cd4cb7cf4c06cf7ffb9add3e +200300 000000000000008f6d9c93f92bc3bcd605708c5d0002f50514fb89a5b72e2a97 9096a1369834e495913e8a62d7312102b409b433467c029c2ff606bbecbfd549 00000000000004d08921e3b4002091a24fc47b19323925483693bc87d51a52bd +200400 000000000000027b53148d16a3934be291a598b49c8987b83b4283424b30be21 bc08a32d660ab4be1bc0940c1d674c3245eccc2aa2b00bb53af49a470aa03bd6 000000000000027e00c19b4f78f905afeab7b71f5cb4a3567743fdeb1b463238 +200500 00000000000003539c2a2591a08d048a892b391b7e38573a92674f7fe65d45ea 6023d1bc0d9b97f957b4f402e04b571f60d9129f1ed1d9f08a62b6639a621149 0000000000000538beb57a7046b072e8113a101011813d8d87cd2cadfe3d7ac0 +200600 0000000000000466935bd1a97a91eee072044345f42619b1da515bd249f2c5ff 3c9a155b7b8d289a2e50a7a65ee150230449c5d83f0c5fc3343f34683e795956 00000000000001a9bd722a2b52f0861b6abd496a2a394f5cafe95541905e172e +200700 000000000000026dd2fe3abe56701b6c6a8cd154ba06186d1f2620bed8592ea1 673cd9c0abf94ad8211d1de1c327f30a344c075fb2585b83e6765ebf8d60c2b3 00000000000004d9981618daefd42e43fb95c927d493ffe0510754459a5d511a +200800 00000000000004419c4022bc1b61c237e3af5c6cd8454a1cf9ec55430b0b7dfc 1092dff6c9ee81623686ffbbaa98c034d9710b1e8ea48eb8efb4d098c8200503 00000000000005b35a1c797a75117d30460553017c24e247fc5d6bc037354e3f +200900 00000000000003d903cfc5970fc2038503f7ed21249ed841c4c8938bbddf5cb0 574ecab87e182067ae56f2c609b78078c338a992b2d5af74592403318f5166d0 000000000000053ad10bb1e4a3f8c9b385ab6c40df796f68c2739fb892300a33 +201000 0000000000000350eb681b2b81513489c5b0a74f456cd9c8a773b92d7b4d53d3 b2aab90de5bc065f949c59043000e8883570c1b03bf9e0f54cbf672b4a886ce4 0000000000000030f696773ae2160056e59e0618c627623fc56b0389a7232eee +201100 00000000000002ecf5f71a6d163fa4960a49a415f65209b5d3cc87f94dfed3fe 3faa73f0da90ac8c7214b37d99b63fb5b25eb14a9b75935ab146436a03bb460e 000000000000048874b5c2bc909d50516b8bcd1eb640f6289b665f006fa355ef +201200 00000000000001d5c485053b07729a4cb9e9217b3608e44b329e3196c111ac93 36f0c77730dff1e126088e6e4887567064f6ea6f8d5825c890641de767ccda84 0000000000000220898a162e779c0c39bd3f1d56d698460301124765012eb135 +201300 00000000000001bf42341be20b0b41d893165577a289f1163b34f42b8c006e20 b5178f2af53ca5802f5bb940cced0c1b7ef77e5272f4c9c0794c4b8fd41fa1c2 00000000000002339d07e8c0e00512f3013be002dba9074eba17aa1126be0d80 +201400 000000000000005f56183cf377c9db38292decf80dd4ce53943a22359ac52d9e b4b280ec3cfa2f0bdcdda04711af3469efd73006b7081ae80f5d9e62c67965d6 0000000000000348599c6c808ef1006008d7699b9d6422bd21f99e96ba0f5ffd +201500 0000000000000372858553145604c79a674c0e5767d4b513f63b1ee949b9e2c0 3c8faea311e5dfbbfc163da77c266c552544a45aa399eaa44d3c69b80861daa1 000000000000007fcb87b0286ed23308dc03321b50cbeeb8e38810b5b44a39f3 +201600 00000000000003a5e28bef30ad31f1f9be706e91ae9dda54179a95c9f9cd9ad0 817cbf0559f7693a2554b2fa2e747afba535ae4c2ff86a345ac9312db78c356a 00000000000003c52ff2c90f4e318b7d987c9a6a23c809d0f945d50689411cca +201700 000000000000008f9c8411ae811ff7b98f421433db0aed5d1872bb7d4a2a1461 0b6748a23721bda49cc0b40cf4ad735a5846c8e755f95d496db58a8fde5b10f7 00000000000003550249dff99cc2087e62147a0df3c1d42182fb1c427c7a9853 +201800 00000000000005451e9edc12b216691991e6de0d3bdb969085d9f3818feb2ceb a703167a5c5b43f3ac1a1153fec342a00c8a3540b2f7581f46bbea53a3f939ab 00000000000001ce5fedd19e5351d8a50240cc0a89deccca2e01aa277a24fb3b +201900 00000000000003062906bec4e7ff64efce341bd2b08a72fd45ef3688985dc21b e2ba66a5a3a2a78e636a879d9287402df746f5efed6dd61b3ed7b6505a082e2d 00000000000000f3f9bc7313ffe349402e76e8fbc655960865dc9c8e798d9f65 +202000 00000000000003282fe1d5533e4275fd9f51e6ba0352ec01f32914e9fbaeaf55 79e80843d05248a6aed61fd20f531d10802575f4fc804280a6901551177de0c6 00000000000003acd024ceb34c283d9a71883d1c5a74d50608a9636d2c6fdfba +202100 000000000000033f0ba2dd17fc2a2b71ccede6ce87269d37ea5614ba9d046f6a e7b0a82ed21a5db5fee22095e54b7012bc5a371bd974bcc810623ceb8c70035c 00000000000003bdb59f77e17416c1b1e751b9dd48b83442145b4fdefeacbb5f +202200 00000000000000bf0c58476bc209761170ec8040c1cbfa745204182ac4f6eee5 a333152044113725c05d04423c9fa8371dfdee645491269503bc579515cc373c 000000000000038534029a66ad98ec5cc6f4254e67d7bc619102e659f2b79da2 +202300 0000000000000480e59228308b00cd25c6f7fc85a38deeb5d0914463435317f2 b7491f86668c984f49b0dc76c4421d24f7c1bee53c6058bde185e4ae1f0b0bc7 00000000000004abd3658f11472fac7c67298120735d5733a28c0db4be3cc230 +202400 00000000000000e9dff8703761b40d2b2bfdd0eccf2be98b451492df0d27c620 903b90aa0be5d56c8cf4c1619f2aec00e0de9d631ccb7d431229dd8c5c6337bc 000000000000051b258aa2e17271db5cff1191f956bdc0e4d413c40f56de3054 +202500 0000000000000066936b3ac9a6049e6d8fbae97d8aa5f754b5b2775a1000a507 678295aa549f585660bc5c7d6a82a06ab534055943b747e82d14665472d7d3a5 0000000000000299abee2d12078be1545733761347c7e8dc522213cfbf4cb02d +202600 00000000000000109281b2cd76d732da4b92f6e59f1d86f84966ebb78a556e13 2e89cf0b70e3387fd511a7a21120dc632ee4537e79a5abbc84a2e9194cf6b33a 00000000000001898df910de161c39fb20099a67c792285b872dcaa8613c21d0 +202700 00000000000001803c6a4e75ba0a20b8602dc984d91582af324004046187d8f9 86b2cfd433c547d8a9d24173ac55a50084097f899901fbe56881f53c67088473 000000000000025cbfdfbf38c8590545584eefd9438c0d8ca49e1c8d44de6ceb +202800 000000000000030d10bca1df1a67e37e3cf80934544976406020458ec603f475 0363fb5a6b5ee899f6065440dbc352720c71e3a3a8ebfa14569eb20b5682c89a 0000000000000063868d0b418d608fd31b5033c93eb774d6d666ad4c9eb721ca +202900 0000000000000169bce9b0805941397912b9c8095dacd59e8d06e1dcc4779a63 5ddceb8d7eddc7e2b9d2b2da6c7e007d9062d25ddc304b04408c50e301d70dd2 00000000000003b2319771fc80db8518473bdcc58c3b4f40a2df1c7e95962344 +203000 0000000000000575e3b569cbacc02e284a292fca7872b37c433bb3a03a5de4fd 15df9330483e602e68bbad2e90198d2e8276fa8a463cc28e89116dbebe108957 00000000000003b7e4d0e72aa776ce346c4a2a803b2dc8a06f59a0d7f777a02d +203100 0000000000000312e80e7a7bb6ccf9d7a3059d717d7e2448db4f2849c04d6586 8ef9db5bf38b7c5507734535af7b660701b5259d91ba3f9844f2fedad21584b4 000000000000054c846c848006465dbe062ea05c910b04b0c16b46f4d28f7999 +203200 00000000000001590ea890cdb19dfd3838be11195106e4ef32f489225e6eb737 688204d428620283d54748367d0bb01dc23bed796c20a33e976534fe19cab333 0000000000000378de61c5dac712da01cea62865af691a51c3c83dd2b6a40805 +203300 0000000000000423eba91ea15bc04f6be9383fe6197a8d1e301212ab054b3736 7e269991aca20b5a164595a21d56dfcd6ac38564ff11dfc012cdc3372ab9a91a 000000000000008af8a1345db12ccac4fd78cafb3671af3b669da1d55c094325 +203400 000000000000036b1a4520ddf1ce2b9d9a517cfd69af10b0bc5abf609d2465a3 f753ab79399c3a7d323a65d1eef66c1c398fb79cf506d0b98ea789eea5afd117 000000000000049a3d299d205a370a372f3415737a9d0f2d6043f090485a809d +203500 000000000000049494aac983b5360b2b271ef38957a0b78fb75ae10f0a0540aa 6dbf8ddffbdc6000375c31a8dd5aba198b731aa55c4c9b9c3d6ffc78f064bda1 00000000000003ca9e561312933f74081d04822e64b8716d0bbf85a410e65105 +203600 0000000000000562dcf5d5ce440c55a3d5ab108f62a12aba0909a46586e66d0c 1e901972a3296e599fb3cfc7a76c85d29532f44c021d295a97878d06662d6dce 000000000000009e45a9c591ac7001128ae14e0765d0ffa2cbb5ea68ec8d4064 +203700 0000000000000481ce3d564a4439eea934acdc3c9d51d0eb088b615cfadf3188 7cac9e3185b0631bee976fbf4e1aac5e79475a022c78af212fc8e467177cc076 000000000000033ade960d39a772c3991120a5a1a367c2cc08787e9a9a0c5f8d +203800 000000000000023bb74d1b33a7fca1746532dd80afbb00c6bfc0c9610055f971 06490a6b736f6cdd700aafd1d304dce3579fd484baa7b22804e72750047679fe 000000000000045273ce42673db8c270af25b6938c11cadea12244ca44b1c29d +203900 00000000000003dfb2db1fe5f4c1ca632aaf65adca589fa1f82627dc7910446b 71557508ddf5950081440034afd1c1142ef6a09737d0aaf8e25e08183aac642d 000000000000001753ed885672ff89715ab3e885c2d777263185e8b0697058d6 +204000 0000000000000423eb625dc140272ab97fea3ba6baf1dc56de77deabcc492872 40a3d8674a03cce794cb9fb274157ce75d9a97ace56467a23d9aa23a8c52ea85 000000000000020aef81dcf0ef072f2f8f77c9e0fe57efd67442ccceef89b323 +204100 0000000000000363d7f5f3341fb0b5b69949103e2d681591c9f737e4ea67e2a7 5b643fadf0a4290468677cce2fb34479dd1b693808e97232d91fe6746b7accf5 00000000000003e5387c1bd28d5cfd4072098dd90b1f8dc09a9165a32693e832 +204200 000000000000053ab5cafe0435882b6cae116e69be95c0b10968ea94d9ba2d55 354a696fd15f01cbe8d2170c844256228283102b33eea6da4e7f1e7e7986da35 000000000000016fd3943e447716c95d4f38b6eaa72127f479b4b8e57c148396 +204300 00000000000001bde555807e9422e54dc827daeb74a69f5f7e6dccb1dbb0af87 36d6fe74704df378370f1e58c94029d61da97aa869aefed5e01cdf37630836a8 0000000000000456df693329be70cb1399a9a3cb72e622289cebccc26ec1b177 +204400 00000000000000cf4db9e9de90356e80acdbff0d528c442b66a04ca074f312db 27507c92fdf8fa968fcecf431a7a928bf2bf3df47ff531c3f0bf524438ed6d66 00000000000003342501b2ea7d678e8cb617acb1af4f6712ee0556abd977cd97 +204500 00000000000003d98bc94cef40aea36353916def21d103742d31027add0725b0 2826720338441d9cac705c24304a4414e19a8671b832578a8a6ad0c30d51b9c4 00000000000002bbdedb383a5fd4636c754e190bbdc65f9ade9ca89ba5d8b7f6 +204600 00000000000002d5926db3c08074969ac3dbfb1467a80268251101318ea6d7e2 755abfe56241331b9aec72ef237ebb2fdd94d315b41d7c63843a6427aee37a00 000000000000036992725340a4e5469e0270d3c51573f2c5e396030dd3ba09b8 +204700 0000000000000405d72623fc7639d326c69c9100b68553059facd4e540b0566a 418e3b9a7a636a88323690cd3b0a6f7a5ad98ecbbb9472b944ce824c9729579c 00000000000004337f3ecbd057fb1c868a48c83f4fe1cc16b532c949eaea2bf3 +204800 0000000000000007ac12f3a8c763006bb6b057f5f0592ee0e1628d5cd12f430f 2bae85e108a0935f2bbe3c71c7c1b682554bb4293b9e392e26f607be1fcc5684 00000000000003b30afe02e5839d90aad028e532d14c027e5d6b981454e5dc8c +204900 00000000000004a37a788dc79240d33f3a1973a5f2042758adf7762a57e1d374 ea55c5995e3ee2b9dd0228117b4a2021b757a34dea40f56f535acd240f8de866 000000000000018e22541f38f5a98ed0840936fc3ac05aa75b7c20a830e43661 +205000 00000000000002cec464aa21f8aee916b90e6c5c836efa25e4057b74ca6b921c a9014bd2e9980594db9665f5e2b31b80714e97df70a71e9dbd5c00626dacd5b6 0000000000000351a0da44dce8c5d921994ec86cc95f3ca39d2ead98f63e73fb +205100 00000000000000b1b2296bd82b53deba33e521c34e059480a5a98d5ab87f2edd b9ffb01e6ea4337f4b1c9130e3f4b304ad5233fc4cb7c73c674fe4a004265c05 0000000000000486e47edda5207c825f52d1d87e44da06edea6d04faead9f9c2 +205200 00000000000002a004fab5b9574b0e05e111e8fabb6cc2b284aea92ccb874b0f 954e8352dbd0eccdde7b107c0dbf43fbe3c5c8c16d04bda062105b5fb1ea73b7 000000000000005c2c453b20b4ff2ab7012ca92053eda9f1a0c1dac6c9621d36 +205300 000000000000029658eca70c1bd9d4c0eec12d13da66a924dbd3eec4c79608f2 3b17daa2799d1a9004f1396f476537e1b50fd5764fa685b319df86b502e63175 0000000000000542ec79c5ace530661488d04751f32c80a2c49b0e0bf48ec88d +205400 000000000000046fe7c2f45f1fd692251fc995c53c6c99375306df412609297d 58e47f1b6a4c5a2581df88f0fe54e6292a8dbba68922d0f051fff5f2e112ed4d 00000000000003ab544a57b397e1e1a15441da0e2e32028bab1336a924b11d72 +205500 00000000000000011f32897af953630a387d1741b8cb320660ca76c8542faa1f 56cd2301004320b3dd33d669a8b5261625fcc2350e8f3b865c50b62d36bb9121 00000000000004ef739ccccade8406ff0bb8a4fafb304fff68ebe8a5856b5ad1 +205600 00000000000004f430ab511411c83de96a34a2e3dc231d91423cfe48843cb5bf 24f46a6c67bb3ef74a5d8db6c740eb89bb6695842abe6eee0efa47bab292140a 0000000000000490a0e80fd141a3eb821a994682716b5af549cae10f23e72d87 +205700 00000000000001a5c3ee494a09b95de03f01e086e0cdc14f30136c2729b99b16 7a989f7f16e56826673be127481a011ba3c487ec965e47d9bc79b71c7d6fac7d 00000000000004470e9a3bbaaa36b69fa641c7556c9845ca0b1695ac2ecbf2b7 +205800 000000000000016c169477c25421250ec5d32cf9c6d38538b5de970a2355fd89 05b33a8b0c6c050ca225d91fa3641996b00b979b383613a3d553e483afb163a3 00000000000000b9d6e5409e98243e93624d7c1b60373c0cb15bccf6a6ab7cb4 +205900 000000000000036c09cd8dc29c9278cf396c691ca8005d4668e28e2e3f5cc90f f4f23f1aac2d11d0c53a1c0a4ad75b3c02af1b19f8cd3d04877ba4e53c69160b 000000000000034db3ba5ea4a0edabaa73d688ff6520b38a3fcb8cb68922f72c +206000 0000000000000130b815d40fd6d8851438cd21ac9e428615ba03a1285ef1374c 16eed07ee0e896e36fd86ead7960789e668bc0f51e85c5b6eeae589719ba057f 00000000000002dea49a5d979239cefef6bc38777d7faa9542b73df4e6f9ee6c +206100 000000000000021ff136698ac582cfffa8d6f6e0e5a6803f72f64406c3f66c21 6815736ed17e4d9c1e814bc784d86ab72fd68d3983d9f1b681c57b0ce03a137d 00000000000001f3a29994c16a187e40360bf07d5d08dbf534d0a102eab3a7df +206200 000000000000029983f8d6cc527bf82641063f5c289a027a2a3bddcc020fd102 936cbc241caccc67b4d3c01f00bb6715f1aa58c4f8b036c858f33362ae6bc0df 00000000000002bb7b3caeaad557d7090197471589096daf0f8bd5ba33727ab4 +206300 00000000000002deed3c4301ca830842c3334edd3b5f0286a7d48f3ac4ddd46d acc7eee4ed80979e86db8b2405a0cadcabb881c316b1fccd9df15ad5ba1d3ee9 00000000000000e0c6ce77d40053675d09065109163044118209acc46d4b423f +206400 00000000000000391f4445ef4243bc71710fe5a5bb388556a7c984dcb9e3fd79 35464d2b0590863d2b6915fbee678c63a97ee2dd9b3622fdc9ee8266e15dc8a7 000000000000039f4353f23c4fc3671691ac637d63a09a20ed698dcb8907ff0b +206500 00000000000002e26a33982c8b2f24a6632e72c50a012adf0f659dbdd39508fc f360b3c52db652d95d4ffcb0bc1a85568b49a721ac3555fefc86ebab754c08e8 00000000000000cd9ded7dcffa40b1da8d79821bc4dff95b272380e5d1d13d14 +206600 00000000000000dae61e24e97f76c29b859e81a001d113b8a1db39b4c9b40a07 79ff0828dbbfa7f243df2a26b77578c72fe3eff3d1ad00eaffe8015dbac67008 0000000000000316efb68a55ee90c8fec40eff4d19516d7ae66e827ff5de356b +206700 00000000000001fe59517057b262c9d716b8f390e5cbd75adc5404168bd10c39 45ed5a52d29be0d253f7c4bd19087880307a1919bce56c09f51df909d621d38e 00000000000001f3a9965e8df155987d2b93eb086f43daa7a8a9175fb27681b9 +206800 00000000000004f0a960fe1e7ddbdfb81541b636025710a29cdd0992969770a1 2becf4ab59807257e3ee377f40b1a5205bad654cb99d083d334392453d3c2e62 00000000000003dec9f84aeadecfdb02589e58a326d16db6a46fdc178066f957 +206900 0000000000000409564a3c5c0a7453d1f194fcba30ea49c24b957da4e8a9bbb5 b4692c5a1555686d6a313f7ada3c1531aab00d5832691c12e5fd6812ccdd6e75 0000000000000504620bdf6587604e10cbd694538d4771392717b44dccce9293 +207000 00000000000004bdd54a303529953b64a85eee5099acb965f53b577a1ceeca44 4f720988533d20501e378d5296f5fd699892fb3c52df14e6ac2a5706585132a9 0000000000000478e80bae3a9f9ca2d19fe2d2e6d2f129b7fcaa804bdc17529d +207100 00000000000000231b3686ab0a26212666f2e909aa5b34fbf54b0e46a2d374e2 674e6759a58d65a785ef7e4ab04c0e05462cb13b02728fd771b3dfc9d922fa31 00000000000001916e167006fe9e75b64c8b6fb85ea59f2ef256fe67b859d8fd +207200 000000000000044db115faf63b87d5734e2eaa82fb448ebbf14e33ce5a1b9e9b 6d62cfb815ae06b5541c9f531a9a484f0fee05367d176e7deb1a46984fdd9a18 000000000000043add05d7e7629b4f48c85e56cb19143cd1fcdec983419a0f55 +207300 00000000000003493b283ef604db26cfd0138e5ee44c69a66de9754ff2e3eddf 8318bda4a7c5ebce1c7e0df3933e62ed87b5933a59fb0befef121123b254d3d5 00000000000002b32c5ace160cbf3d290e2439a755171e764e6cac50151cb7d5 +207400 0000000000000019362ef5e1518df785650927727771046bf46ec9d29422ddbb 1f968343132f074bfc596abf1255faad8baebae5b210ff85d4206820c08265aa 00000000000004094d9c4e4ae0407068a3bbd3b30f60fdad54c4779d235b99da +207500 00000000000002b77f270113800ff68333e98c3596b89814b83c9b54bb471326 0342f420c2399536ff5e0e25435bb275041516cb1bf2c122614de633d833c269 00000000000001e8e679ee60c8820f51d1d207090bdab060517133ddc29d0395 +207600 000000000000016f9aa1b929007456f8374c5bdd0f891422d770f6236a899d2b e80c9df32668ef92263f9382270f87048d987f746546dcbc1fa1f9ed3e55b624 00000000000004aedad783bb8556b1b4433b11744e4079fa14853fe775920afd +207700 00000000000003ad6f13ad149dd3ec3aef9151e80e9320c9835d9fc5c6d7b32c 44cee47e245d4df7b9293ea790309fced53028a790a09748697370dc41dc013a 00000000000004728cfafb65b737ff3465dc6e9d7a6a21aebc745584b96ec699 +207800 000000000000045827f9f0f5e4a84a565afe23b8b56fee09c6f179db85c29de6 69740573c306cdb2e657149bdff82012b4d6ed76e6b37101e9e3be89ebe55825 00000000000002ad4a814a9b8d23ffdfc91007b902bc7627b93289ce2831055c +207900 0000000000000313b5eb3157b8167941e0317068d8befbb1a5fceb4836f08398 c84655d9fe562fa46cd61bdb8bb0869b1c5b0029ef936a20d54e0c31074d42a5 00000000000000f770af82b983f7d111eeab3b2dac538c668fe47e9ff44b2d6c +208000 000000000000001db5a1515a5f8534c941b1628f60466e6b709b3b320254afff 1ad8c6b9ac7fb5faeb924034d401c4628276c97a255ca81ef3c4abdd24719068 00000000000000b689b3f2bf7d6da132855d5eb8859c440cb09ef591b2c835ff +208100 0000000000000076c56ace5d4c9489c3b709bcebe8b648a4a05c5fc766145300 00880a5a35dde55b05d11d77da27fb480d78e247d94c0e3cf4af711087a9e816 0000000000000219aa34279b0909467750c9ebee98f0f85cc136f4596881761f +208200 00000000000003cf1de105fb5d56114dedeac8ac77e97cd482da16143aa0e71a e26a6ac7ea9f436e793873f3c30c504a7c5491b923f00a84687a9300f69fe2a9 000000000000031c83d1f8de006e55a7223d3fdacc00252dbfeff3be569f4ea4 +208300 0000000000000026a7efda7167aee69759ad950af3a015685802f1d2eb931549 e9597f8e5506ca7e8106918f8b9e16dc04e6233cfb524ba24f24ab7ed084b2ac 00000000000000358ead29667039ec4cd7b26dd10935254d0abd183b6d8a3342 +208400 0000000000000277820bbeb82a19a7f9766a04485543013ab511c6f8011d405b 6f25b7fad82d31c27f8edbbe31b95039d4b65e974d48ae764ce2155d859d2535 00000000000000892502ab7e98512bf9c28195016f3fd7489b5c8f6bc9bcad3b +208500 0000000000000021c5eb9f83bf61f637fa878a957fae58326f8babc00e9d136c 042c7b43faa48f778db6fa9888e5735edf8a9c207c154f9e9f2ec55a2b76211d 00000000000003e402a44d4a7b44d9746ed86cae25fa846171391fcfc70db5fd +208600 00000000000002c9cdcc030c62f1012c98dd39c22f63895f0e2ad7955c54cfae a24af6682073119cc55d5b0ba2b2c061e5ab83cf97461e0099eede0154957889 000000000000001572b3c20fb9756eb370c2838f4b6e2209274beb9adac75c4e +208700 000000000000044ee5e4d652e4a142770216bb0bc4391260741e7fee85d7df8b e1d9758e7762529fe4c18c418dabece09dfc4b346ce749c983e0f7b0e8d0b867 00000000000003229ad3eb7a704559a84b88937539fd4080047cbe018fb2311c +208800 00000000000000a21b6c36f881beaf7054e973f7e7ed258dc804f8b753cce726 fdd22637df016eaef268940cca89184be4468a0171048bcb325ac48ff017607c 0000000000000307999734f251777484c4c2b4ad70bf5a0678d4337e3cb9da94 +208900 00000000000004c15b1973914f5234a3a8d604f95fabc2076623051f3fe948e8 f5845ec35f24c864846008f3e69d3c6e6d99834c781d76f2bc749f66ad6987d9 00000000000002c6e9d1249713b0fe9cc47c381df57f2483a252bb7467fb21f3 +209000 000000000000002a356ffbd715fb0cd8f1003e8024801ac4e25dd41ceed5ba0e 0c77f5def4eaa69d2a987584bd19b533078f8714bc8108c23a3bf98d2efa0dea 0000000000000317154a9a0826357ba7be75cd11d904bf49b6585fc66ea788e4 +209100 000000000000005969c5e904245ebbd3592911e731b1a6d3983e8186f9884715 69d3d55f284079fdd7d4f42c873b9b0081d15e4c91d5accba5a35637195cfbb6 000000000000043c1ffd6fd966a4ab36a702390398050baf2b981e904d346992 +209200 00000000000004cb1a7dd7a915e3ab771e3b959cdec1ecdb4d58a8db83433a06 08f8086a3e9769404d6329b7eb7288dd894c85d61e393880b4399066a31c56b9 00000000000001d9fea8128ce8af20eecf378d4fb878900b9bc42b50940ddd18 +209300 00000000000001a9527731ebc19e26ba529c0421d99fa2744942b21ad3c348e5 0ef58571bb270f2398290c1ace58f9cc5e2b27f3ff05f495b4b2991048b6882c 00000000000004f2fcc6e14a7125f43ad685db833a0bc9efe40f7a8bc48a9284 +209400 00000000000000e64f1d5c3afb2074b3cf6f240adadf4cec9a971d5c67dbcb48 55bc619c5c7b1698075522341a6798057c6ac76c7f5dbd4e61e3999c73b40771 0000000000000008ba78f779cb03d66a71d4cbc7b940d1e589ba5aa0698f6d54 +209500 00000000000000f09437c57b3855345b1f06c3fd0154dc008bf640f937848808 82d75dd941d014df3141755b00f96ad5e900c439ac42910f9a8cefc8c855344c 000000000000014c7214f30f2826e8305268dc1abbe1ff63f2014be46155b177 +209600 00000000000003e29f9ebfd2cbd2714e638f59b9bb453ccc6a478035b32a3e54 206514f04578a15ed329eddfc2fa7c06b5e77740094e6a0932fbcfc87d9e34b2 0000000000000196b5a2353e65bdf0e0081ab2870c13ec7c7cb0658eae0e45be +209700 00000000000003c1950a7cef24ea12e16b5431fdaaab88d1d5906b1b2c81277a 311da5bfedbc60f61cd82845c942e7345c633ed767d76fde665b2a9cbe2239d4 00000000000000722309e2e4494a908f141c6af1fbb21428a59d1fff253f4327 +209800 000000000000042b60a31c9de0026e564bbea6a7f0b39da986cac4a957eba89f c8cc7a58c3e2155bbbaf70d1fe89632068d48fec0d1e5670c16e4e5c9c58382b 00000000000000958660c5fcca6c82b3f177a2a631284c1b91d1b4cfe8290e9c +209900 0000000000000098f8267fc474ad46d96bda14162e39fd8ecf6ec7f841e85739 f13adb9a2521443ca8200f263305622f6da44a8f9342999d65880c8fe80d9625 000000000000046561503ecdfa7a187298db570ef975903174253ebfeefbada1 +210000 000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e 9ba8dff145904cc3c24ae69744d20f8a6c4029086fce1bb527b809a53e571d9d 0000000000000198b7aa4172cdd1e5d80207535da5a2d4acd80242c07729dc21 +210100 00000000000001d0f8407406ec727bd9fc3c7fdc62ecd1f6a3e583639a9d5396 a4a0fc7ce0708c4a4859aba4575c9fd42fcab656406a98b900f156787217b70f 000000000000040d34186cccc1f8a6c5473c8272339b778ac799ccfddb8ab89e +210200 00000000000001a29b9770d22100c4f707a7dc350d3749b7364d078111123d0d b66ac7839fe56558a345598c7457faf459fd6820533d4fddd4fcf0e1d0005128 000000000000002383789cd830d99c6488d1555a19ed8bc9a6ed6f785f44aa2b +210300 0000000000000410d3263e7355f09a892ea7ab049bb1c1cf8625270cb82e51bc 9818c80178754e73d5d5551b282082335bba581490521f4178c9e514b418f9cc 000000000000016458ef124462c387d497442fbb1cd30cde9926f2ced1c33455 +210400 000000000000028a9c53d6d4ddafc83615dad8f9147839ba77877a3b38729fe4 d3f1d0b62553a2f91a92adf11ef4cc289bb7ee4e82696d20c3c2b8b416e292c1 00000000000000f6e0c83371649e385d761d779cf2a9cdd6cfa6aaf299bd81d1 +210500 000000000000031b9f89e53899f312522575871a012a7d94ba8eb2f89628af97 521689cb63cb9caae39403e78f3ce8b7d0523db79ce3d61d5858898e1025c17e 000000000000020c66dc8aefcdc0a0bd52476f80d6f75a38b19ae45e67e524aa +210600 00000000000000d7be2851a24f36f9e4b385af771233e2d20c00e17bf32c88a1 b509d79e212a1420a9efee2c8931e6c2a981decd476d5bf1310a2e87755de2d5 000000000000020708a73585285f0645cc47a5eacf46a5124839222afb649d56 +210700 00000000000004205e72e881863c3dd7dff0ba4f578c25555df12cc1d984c2d5 e38e47d5a34bb9a20445cd9a4bcde399bfe857296bdd86d18aacbbe8b68f58d2 000000000000026cf667d1d68d0e362345b5a92097c208d57c86826fef0778a6 +210800 0000000000000030d456780296d4e42fa6589ff22dbe63c46722ee3c4d951c91 d4c4f154825316e27fd7b4eb3b68cc1192a2b5d8b6f2430ee3791baaffa5bead 000000000000021881b44cb8eeffcf3353b88dda6586a47b2b5bc0ffe03cdd80 +210900 000000000000007e2a961526141f71f39121be8326082a9bef0c38d485594f53 7aec9477357faef0de13867a42a522974648734cdf595164c25848834281249c 000000000000010bc0f9da8d308e95981cba82326ac662a70b37175d825ffd39 +211000 0000000000000345b371caa3f829cacbe2b4d38ecd15a5a02031efae79934d15 f576a404f2446aa75a50d80ead099cb5641dd2a0d4afc51f7c794cb3b389af53 00000000000001c9c0927b4e0ed222789714581d6cced7d32be84af3628f8434 +211100 000000000000001879bc69529c05f4cb4ab1c9ac80edfff5cbec0edfb8796b08 e25e95b8b9978cbf5d6722abff4e13ba4bfef6d56b5254bd023c5bbe1da2eeee 00000000000002fdef51089bceea0553d2e97a22e5d72d3e2acf32fd091e8fc5 +211200 0000000000000172a91a156957f9cf5375e0bb553dd34d83edab7f68a0d269b7 6197787beda68e2fcb51b6ad2cda6d54288c1253b1e5b7273ef2fbf417d2429d 00000000000003d56833b4af2f0e89e05adda37512f6f221d12d1ae5b0c71978 +211300 00000000000003d2833f80a87d11352e95d931fa3238fe3e987e3ffbebdd8120 9e14e92614d9bdc4c0c95e73608c3e01a4bea22dc3fd2907e99da0ce43e7b6f3 00000000000004cc08a7823881d836fd30de8361c9c2b38b341cd378e40dea64 +211400 000000000000032993879e057e35b2664d672002887edaf265cc97e875688724 537c0ecb3d9b8b8053bf16c3042e7b60cf87e217adb61c63a843485171590c64 0000000000000313e4e19d774871346be68ed9ff3d55abe90ac0dd054dcb23c5 +211500 000000000000010ed06870a80a7f3a0bfce85d8dc8b12873e44206f490716646 01013ca53983d88cbbd211492ae181d6b075b71683c13a596a4e0ab717cef0b1 00000000000003f8d58ea0da92de790fa06988b1da9e99cc46ad9185b835d71a +211600 000000000000045c3e34040e8a42b17468347acef23b842dafe10e7f53996ea1 802ced7c7c49a063ffbbfd61884edb92b853f77f8263cf74892a2dc443725b9e 00000000000004c68371de050aeb9dbf5ba58eb4e988138a0e1b028cb8c90e66 +211700 000000000000001dc5755f0c164dfd435470f9c62d75dcc96d0e66822ec54eb2 397f5d72c4b98dcae2d3c85dfc970853b2cd592bda058a32d0820386857532af 00000000000004c15ee694b41e17f926d30d28cce230e0c637a72699e11fb335 +211800 000000000000037c3faa0f2a33863377e7b396cae6d8523702370cd3b8dff835 45876ac2f72ca93e13853a2e327dd2a4e86981085fbdc96a255aa6f4e476e123 000000000000030a2d82a1e18eccd93043de4f4be2c307455fae30635f1ed602 +211900 00000000000000347ba6d0d658d3f653c7c03fc8a7dd3ce2ac226973a6e04051 0ed95c4df96051f20e19ce421143cb49f5d1f2fbf923777508179a5801907f9d 00000000000002077452b71c35b31e574011d66822f98481e17e6d37642c2918 +212000 00000000000003d906e4131c39f7655b72df40146d2967f5d75113a09610de61 df9bbe69e7cfde9f368f0706500acdf411f4136c553a3ad5f458f6987bc6c4b9 00000000000004bd7804653f46d187cbc1dd55b9d3fc4285ab450b7175453a38 +212100 0000000000000223b1fd85a20b88d8d568ee410ddfa9a663a2f47aa96f731813 424db1fbb9968c127829ca47c8dcda1e0a5f193b35d0a8870ab3b3a110a13a8d 00000000000004b0b85617b87d7840c5e4752517c551c329b37fa3ec4bceab43 +212200 00000000000003bbd8383db0b0f1d7ae5bdee03b97c5366affe06261e0e8d1eb 0d7e0df8892548ee43333da79365e603be2c646da4625b28429c4466d59e520a 00000000000004057468965c29db6e636e88edeb1a66f6a619bc6720991c189e +212300 0000000000000304ef2cc30c6f91ecf416cde67b5a1ec91c93d90466bbd39036 ad4517ff824ac2f7922ecd851324fb798f543e0d513b82033c0d60d7e2f339b4 000000000000046216ea34a6a9fd9b1f5931f720bde3cc6dc5b3551c73b6c3f2 +212400 00000000000001b3eaccda1bbae672df4a1cf3d1b2c6c778c87a865ce9bfdacf 9a4167fde584892d3cdf7f4f3b11f2353925546f1ec4c8a72830a2a6b5c4afbc 0000000000000110a1efce52820ef05103598ae8784faade4759f668f36e1436 +212500 00000000000000c309265b65e241d20ff520ad3b8ce26bef59b69f21550f02f9 5a8782b5b0f0a33b131ace601dec3663edad53e4e0194dfaf613f872ec86f741 00000000000003cae37a2b6fa0061c0f4177c4e5c11c19214a58c4b87fff17ff +212600 0000000000000477cd7b57c21142f99b1ae05630cebfdb3aedf48f693223e940 ac59272b573e3ec4e9a7629aa0ba0d771b8fdc3eba60922ce7bedec3a698e9aa 00000000000003c81d2051c6957fae2b8265b6175f203d4372899c90d9345f38 +212700 00000000000002226f938936e50a19d857203d8012537f0257ab29eef25ce74c c2d20ee8d1d5961b4dfe9762f0d4928c48abdb5753e0271c13bf3874715ceb1e 0000000000000192a511c7b640f166d02a2bc009e870b6ff7904e1ff68e171a3 +212800 00000000000001d77fd36f7400573ef548e179b12f60ee12a0b345e0e4950e85 a25c9ecbfed80147b9e6eefb400cc9d4bd400ee215fff626cff3eab4bda67540 000000000000006c9e905c80bb6b8289e18a5a830d55a09a7a2f24e91b448480 +212900 0000000000000123f0039b01edeb7e4d7232450fd0e29a6b5f0407ca43755bb8 08b8ab580acff024d7e1615a3464697f5d2b69089fb325c3b6e037cb739a550b 000000000000022e7cc6ab43a39723229d3774e4019b439a67fb58a1cd7924f0 +213000 0000000000000242076c882281337e58a657471868d12083b1d2621f41d4ee2a 40922d3eb7ddf0d488fc8f5a9160eafd28054555286eb6ea858b703be25d168c 00000000000000a8559b729212f84495559e8764d4262aec4175e23ce673d9e0 +213100 00000000000000a21127bd4394a5192bdc4e60b4b5d418d0aaa69e152dd3f0e9 8231c6242ddcec998c9686de9d1074e981ef276b1fe0af0c9b7de02bdfa9d073 000000000000011286b38240bea46ea5b6ce0dc6c9a2b417a4c05946464e483a +213200 00000000000001866a8d11d50e1da9b800952f65c60e3397471f73639a33a70b dc478c7c4e837350c1c3d588cced09992d6fa3087048e300adbf29da31bc5028 00000000000004f75e395e18e39bcd58608308a4379b16c1a400c6c75f10345b +213300 000000000000035315b397503fea4324e665ad13ac989f7a192ad1ebb7367a9b e0ac3148b5b357a8f37cf115d4a59c1618db0e42d6e68930fb3ce86a205fd698 000000000000040caa4ee721d781bacc763f42201f00a228222512a42b48f787 +213400 000000000000009481aa8da7f2e1d112d16f32549e91eb2bb7370978ca40a353 9756c5525f2e964ee1fb2a6d6dd4c480c62b9f2083e52e3c5e4a1389e27282fb 00000000000001a395703b9cac33a5782f1540ecc0cd3472b9907d16366facf2 +213500 000000000000030cb3fcafea82b0eadb36143f8a69a04bf55ddf348059a7b6ad edbc04ff3ae7b3eec1216395281664cbbc722074dbd05fbd84d2ca58618c3bb8 0000000000000460e24ee0bc6998f339deecb8b08f6da5562f01172ebdc0c7a4 +213600 0000000000000021f462191756831eafb3e209ae73c407431960f40ea6f2045c a40e97d9e0aa460c21688b011c509a5a360eb5cc7cb6767d4ba3a78e761401a0 000000000000002ee2137344320f279e269b469082a0c9bed9acb8bd2c059a03 +213700 000000000000043a869568a99851984d0154c73252649ac9d80d6d279e45c76c e54b16e8ccb4a80cc35b0ba54c31c11d4ed554e8db6eb725d318c797673e4ca5 00000000000000fdc0742c202f82a12bd493a77040f8104478af5369cb30ec9a +213800 000000000000034d7ee4e381b3655876ff54ee6e0ad81915cedfbe5fc1396cd9 2a3ab538d6908982298343ecbd78c2ec099ec7f25c1fe16aed7e14d4edd3cf69 000000000000026467aa9fe68448376f933ac0830060826577338a3b5cb46d3e +213900 0000000000000331baf19f701170a77f732ca1d700c2a6cdbade3d15376ed08b b6326d5b11b3606657d9f8093541eeb40e739e7d762a0d18a1fafa1a26cf8a85 00000000000004639ae126f23965e5a02613898e6c9982a69b1feea259324da3 +214000 00000000000003e6427f9fafa8b0e1af0859f15cea90d911f64445d296a2781a a71f41df959b1ca6b2f209b917c76308628fe19d751dea5a44d33a931e75c069 0000000000000246c4afd6fd3204ee2d81595ef621e3cbb3e36a651904c464b7 +214100 00000000000003c5d40df0642b16df295d704d5cb043b45171ceffcc857641bf e4350a88d1dabc3a3f8f6cf2486e5788e8cc17b68a7edfd01e6ac77ab30e6aba 0000000000000450a06c7bbed6ee1e157e348e9f6f197c357b48e7861ac3d82c +214200 000000000000035688a5e224794c2b14d5435e1c1ad7efcfc9d15990d8878af9 c6b0571c3114538037c9e3a78ab010f86359a6cee8041df88c0abf5f8260bf9a 000000000000029acadfd2c473312ed8f11a6a2739f36180ed244806ebe0fd5a +214300 000000000000025820f057b899eff0adefeea21611280f105b6b27e3ed6aa3d5 b369da8b6c2e3e0fb3697c63624d9ebca672184bd0dd9bb3c26774ec41145ffd 000000000000028f4c0ae4c491cdb7cd005d9d34eacf5a9d831d67bac266706c +214400 0000000000000053abdbc1882176ba88ee29466f6a572a5bbe83192ff675415b d722f0c3ae6db163ab95606e2caf007e9fe7039417537883f9bc93f3813d0cb1 00000000000000e117923fe7eb66cbf627d6ebab588e6d749a11dfc1128657d9 +214500 00000000000003f0217b38879b7a13642180ac97ffe328d220cd3afbbfb79a85 96d77bc69e44b9d8d5184ea82fec7f6432ff8d1e90c41b15a8fa97d7ad2895ef 000000000000044d0432e7f17e1600a94649c6c16011cacd88b05396e916d1b5 +214600 00000000000000f63d8dcfe127dad92d922ef41075cf5de227b5e7e6549dd80b e7d673d7ffdf0ad156ccc2c8c9a0546ed93dd0c926743d3e70e94097397b67ba 00000000000001d8611d462027bbc9285a9193b1261be9ad09ba042d0f6ead31 +214700 000000000000004ab2c3edb75dd20bc60528257140b5d921cc8d33524962f9ba 81ae5d1f4e987fefd1ededf3ef5cb36dd9ae9a221babe96ef468b4e09ea8caba 000000000000004a1350b49f63454815b46f979b5c7692f006d60882495ae50a +214800 00000000000000917df4636746aa18340b590725f75d1950fe1aee45224142e5 7582ca92c76293c1dbc597b557cd9f6569917e812d7d5fc5772ba08374e89dad 0000000000000102499f2c6164c7a4b0be05a1d3c4c8481dc81d5b0e90565080 +214900 00000000000002b5b755142c9fe6b39bc720adb2dc0e50e98d2f9a03a03307ed aa1322747b0db5724bd8996262cf693d38767872ea0c0d379a6f1fa72fb3f4c9 00000000000004bc72629381fc71832278f0e7dfde7985b0d0c9056811a21f53 +215000 000000000000032f64cb76edfb654062e7b94b152bb6458a59b979fabf99012b d29911cf16968333cb47592de2a56e10a40039e54fa1594ac98bdb9d9f9eeec5 000000000000012f5751345a1e7a8c058bfae9fe31a09fe845511fd8caa080eb +215100 0000000000000250265e25d8c8fcb25f56c8f017dcdc8bacbfae148b84ee4efd f223dc250fc4e05c8f6b4130b338113ff881a98cf462382215eb7b41d030514a 0000000000000199bd24a60f393e469830f86f6b62e42f1fa961f0763298b1f2 +215200 00000000000004cffd7f209e0db422a4a4a8273f89da60b8abb8fffe608d65cd d1b9b67f811a30862c587102bdf881b800a4ab55616622a5abebfd57d8155109 00000000000004af02a21df0090a796e3f2dc9f28440a4707de995485ebb7e77 +215300 000000000000045374688ef817a3be0cd5eedf1cd7d2817bc3a43e1500e04e68 69d13bd71f2b5727bf2306394c676f38ab36152441fbecfad2005d3c86007a9e 000000000000007e5d9474411906798be258012afa174587437fbfe7c12fc1e7 +215400 000000000000042f3df12c164a248308bc0e467efd0926b5f559e9e437350ef6 65ab3319b39f169f1001ea86b959d015434e1e7cf6a7484775e00007631b87c1 0000000000000029e3fb0134055d202205b4ca438de5715afcc48186bab28663 +215500 00000000000000d1cc2c7d947aee5211fed67883cd5b3c0dd4b19002417965b7 c3897d20ba6b57e54f2a7f348aee95985585984f0fa5aebbe0480baff876b4af 00000000000001bba29f9d74bd2d339989f1cbc20681a0e0b4764c474ce7b449 +215600 000000000000037f8976e195fd144e6b057b29ded54d8c1d35265b8e05fe1920 3aad3bb58f7909b8211b7218513ce886ff63ec1e6838ebde12579ae2d6fcb984 000000000000018331cce36c9b176ea594a47dd2ffddad6335a2ad9901e7f9d6 +215700 0000000000000513af949306d2cb80ab26364701ccb37d6748bf05a3c2d67553 6242717c13e07e5f6410f4cfdd624de0ee569300ecc65eeb984a896d7f5a30ff 0000000000000268214d3cc924688c104a88f1575a1530e13dd08117d6cf0212 +215800 00000000000000fd047acbf74f9fb7b80e5bc26a321eb91eebb59756419eefe9 6daf704d5ebb28fbc52d9d937bce057957bd03c95ee4af44acac2180028fa52a 000000000000000bff2eef6e9bf5f8459addd7c9ba1898547d46becd6394eb6c +215900 000000000000050c20a3cb6fb58b517ceec4d2cf15c0669ed77c302a967bd769 6341029df6c74b9b85f4c08a3015dce0cf12140047e3e763d3699ac5cdf0df24 00000000000004739e0a366d7d18158dc5e3b0b73a1c8da6ba4b0d8b40dc1dfc +216000 00000000000001f79a2db15d0ec6d951729e044749372caf504679bba5b1e65e d6551acf4d8ac0aeae948a6ab5f981038b8f90be92bcfd23789c2ded3a1ab921 00000000000002b5171738a006b7d9a3157990e13427e29da9a0172e3cfd51aa +216100 000000000000007eb5ed0f6650f5047b1aaba950423d7aee12b3b2ccdd646964 6e9108027d566d41a81fe4d6f5607145afcaedbaaa32ae2a359e61de2e6ba06f 000000000000005c971eac7dd0d642d2db6dd9ee91e71a05bd31fac43746fa16 +216200 0000000000000170e0fbd849e1fad98c314edef9b7d406814f04d69aca37fd91 c6624d424ec90f0e6152aac6fd5db1c03f3c258614202b8301109597a1c9fb73 00000000000004c5d873c73788513f4b7db19b0337d215ffd753053c38f427d6 +216300 00000000000001920773bf7a6de6cbf13913ae6ecae8e8e0570b6558d5b24e04 f093d863c18f9371cbec70125b0df11520d99b9a0c3165e33449d90be6271cb0 00000000000001224f4e828627ac4305d486d968c15a432f0cf20e4e8ea2a37a +216400 000000000000042b636db297ce8f5a7e0c3019f0de6e5f3ea81147902ba98089 a1e6bcb6cc5c39ca3606731d1412184571e0f8c4287191ef3427c69c3f2bd3f9 000000000000002172bd1e3bd9f4ffde6bd4db9c5341cacc641a8e5c59846ea8 +216500 000000000000027a94a2aff1aa30b4cd4ccaddca4e42f9661a5a4ccd84b3f89c 551c68e20add52176704a5b4ac2c792c934a6f245f97fb6673431c24cc99ce35 0000000000000064dc3a78bddfb22e5fc848eb7199508b7cf3261944d3cff942 +216600 00000000000000d4001ba3bc406e534940a012b42e8af2661401d5e0bcb5873d 66aa28456fa8d932dcedbeea7cf58730622c1453114423b4488a4ca7d4605bae 00000000000002d21fbdd330997288356f2bf80052ef6429fa71f0892a03f6b6 +216700 00000000000000757055ef4c81cf8b690b3b4e5e5f7b67871c753f801e3f8330 77eeea6b5d9029e11b1c27c055d5b67f0c11377faafee3ec5ccea33e089cf29b 00000000000002d577c5588a93644e54dc4da21b938056b1e29bcb482de9792d +216800 00000000000000f240fa6f708f70a4260b9840e2734f704a59eb692321d5744e d7e0aff152c34ab940af26848e9381fdd982c46e705c26f4e9cce8132728fa65 000000000000047e011496327da69581ce6e47de0adae9c34ffbbe6e12bf6c1e +216900 000000000000035c671f86dad309595e2e8b4a6ede500761ea142574ddb40ab4 750523028ca751c5d7b96616d1d1a5ebe1967ed7c29e2c49eed279fe9a797d2b 000000000000011cbf7efe67064c5a65d2edb2870eb3ec396d695fde0d6614ed +217000 000000000000036d1e5c410c393017277f8ccb59cb30a9143e818e788ecd2515 176cd9e416e21405fb405d937a3f0238728ead6fe94a0c95a18cbb089eacb775 000000000000036eb963e4cd8d8b0a20d1cfc9dc0c3f625b7e61c23cc219bb89 +217100 00000000000000a3e7114019f1b25985f3052cacb3a856b286e5a48670313bc2 7c8c7f456381886a7b7c6355d7b72d9e6cdfe3b740a0c1b8da82df1f8cfc5fc2 000000000000026833286e8abd16563f293460353dbb3f256f8b97311d0514dd +217200 00000000000003bd639654d6e78a4357b85c887c39c608c7e43abfb129aef6a7 5211b6a27a63ab77c934cac426c86246a4d65b35ec66514f82f3bc0ae0b9c6b3 000000000000006a83a4468813f885be12e6eff191c19c6ea923a9d87275aed1 +217300 00000000000001d7d1fdfb5697ba7cb63c1488db6b7fe4f030dac8754b1d4b3f 697f7d4436cb80abb73183306f4bee0d710d1e9993c6dc50d6cd81cb88adffe3 0000000000000156998b9798ae5aa4289eeb1951738497d70a2b790ad306c114 +217400 00000000000001f2ca13ace8e9684a3e580f249486d8c8b194e79c5eb689e251 11cb462cbcea84cd074751512d33de2a21dd430c6a2a3de2bb66efda7168f0ba 0000000000000249701893fe0873173147d998ededf21fcc83e56af91df8764e +217500 00000000000004f3fe12fefc6b35f2c7280cdeaddc5467d164251ccd7b5e8fce 0d8d0923510d47adc5a8d0e84eb29145fe8786f114afd0d6b9bceb6637c180e4 0000000000000280d02fc9475798e48dc70fb93e7e4ce77337acb0391b5b49d5 +217600 000000000000014fccdc731d868a24486b137c26d609d48da8e245badf8f4a9d 9a65066fbb046e28a4eb2825e893b18ca346abefc093723af5be7c21ea2acaf0 00000000000003fab93f835bd28aecc37643497eb59b1e10ed7f5f1cc7400980 +217700 000000000000047dd2ea91d84f0bd90f6de4beee7e9777d554919d131078ff4c 26a646981ef0fc6636c3ec4535aab4abb89f32a55a1c9d0fe27a2b9ac4c2ba36 000000000000049f17f69b5949f62e6b3dc70f7fee054cceac4b1c300cab5d56 +217800 0000000000000565ed5ca5a2979f7f4e006adb84dbb31b7fb91bd30d5d5f70cc e84e62dd150bc1a5ce4aaa94e313c7179c1a1f8b69174e5429ae8be9f8a9dcbe 000000000000052640dc0e6accd6821de725eb1dcd52f4ac19cbd9312fff8613 +217900 00000000000002c304508d7f00a825f912d457021a34ce1001121fe1c15d178c c512461df913134b4a029f1d692c209354f3f664bae178e91b414c39dcc1b1ec 0000000000000216380de57ebd3386f91a11e522744a82ef73f6e08a2f07fc2c +218000 0000000000000569070e338293af66258adba29dcdd5f33212314dff752ff458 8bf0c81613667bf103bb169018c7dc86ef535dcd6b918c16924dfd0d6f5451cf 0000000000000427e9d7228b14d95965b2424a73fb2d46aee0dd3f064c36cf71 +218100 00000000000004928a032dccc98fe9e893d9e69ce2fc1b7d43b2acfdcb8e18cb 77498c74387c09a8e8a5800f11b320a5e59ed89add9071b22bd4cb44fda460d4 00000000000001ee138497b563cc75040af6028841196942193fcf7b77143432 +218200 000000000000001b7a7a3035d7a8ebf2a5a4ffa956677190418ee7172c2fd491 cd356ce10b4bd666ad63341c93ce1f8c627418231db08f56bc16189404aafa5c 00000000000000072b932996c675b2554cfcbf0f2a1c19d282935923aaad9492 +218300 00000000000001d6b66aa673fa43ba2405f398aa415a2b8b9562d3d4868a1977 31b21079930aeaf2d78b8e03b9d214324a7a3a05dc61e177f47e78ac46fd2a49 000000000000002ec923d417c853fd4fbe2b8cf7647c3cc33902aaf9f05d3201 +218400 0000000000000305c596f0d620393782f4b4b0004f1d4c4df34753e5a81ae38e 47a4c55b78a2fd684782d63a7988266d02d012ecf2698b5adb89c2fe07bc9055 00000000000000ff1c218213f6711b5ad0bb36f3af077f1e5227d2663bb85d8f +218500 000000000000042f01cf41d868539b3b9efa89384e8abfb4e3516cfb11a743e2 d98c146fbc82e56433a194c2eeb4004c86a9103994dc06843e284029e6d87aff 00000000000002b95fb89aff56b62413abaa1c343618e8129bf1905e063c9cfb +218600 00000000000002ca35e1803e84f413394683a0e6ec457e7f76cd4e794ea3de37 9717fcca745e425769116907858666bb22131051da4bfb70b69a7cb85a2a2cd8 000000000000043f3f533ca0f055ae951fefc9a4ceb31690f691eed3f7262ef9 +218700 00000000000000af4b09344842f89a60cb9f423c2532ea32fbfad37eb23cd236 4511c5ff9b11f1e4317973d5b6ee24a97117bd730a12885b7b96e301afe470ed 00000000000003a30177081c5f1f0d9df799e3473762a5a0c572c5bef4777ad1 +218800 00000000000004f1cfd5fed69905a4ccb4d144ccec8715daff5e327685e4e470 a990f9f315ae92d251f7ba34802e5fc7c771079e2add9407359ecfd50680fba0 00000000000002ea81e486a899c869551a0b3b3033631cb0f14e884bc32317f6 +218900 000000000000010bb863a7afbf6ac26916ba4f5e1f559343c6c30410e08f57e7 6833aaf6f6b4c8a1046405e2b5b7b0cbb5ef11b56a1ff971a1957180fdd54785 00000000000001b37d68e014e62cfbbc196df0915acdf0fb1ea7cfc7535cff39 +219000 00000000000004b359c1cb685f9e39223cb76ee91929a1d1311df50d1f939e7f d87fc691657b466e175fbb9cfa134c3c0d67f486a099db2399763cf96a1ca413 0000000000000357463993288acb90f3d1a6d5d3e345c0ac1b6ecf01d8bb053b +219100 00000000000001af145fc663d03d7d369887845426c4757bd2cfb969581a67fa f1c2a0d6ad700b453d911b4852f8fd2d1e98f021ecfdf62ec98b5cb9cdf426ba 0000000000000081791c15624944ad94556ec3330e4497d9a17b7c1e87f0a970 +219200 00000000000005565cb86de281d94c1e3208360a602a5ff4bb26f283cdedf9c0 3232b436e22391543950ce0a757d7b48570e5dc4e0f47c6b61ce99a20d856cc7 000000000000035201331038bdba6aab6e42e39e04a38088ccac160c46857231 +219300 0000000000000061d6337f1ac31595849c6cf976879a1f4b111de5da080263da ba55e00dd0e5e07e91636bfc71cbdab814d305555c5e11917f1e8fe8f7ef4bf0 000000000000040ff8f6f4d8c8cb6a1e5f006d24e5fd2a36ae8ceb3fe0cc01db +219400 0000000000000246cd2f93500e4162d54febe8fc690ba9993efaf577a453c6cb 723cff425b5a5c65e0f0e87f63b49c0f7f74168431993ca900e1bfc8d7194640 000000000000012f293d22d30913618516b808ff2e89340eadfc9228a926b283 +219500 00000000000003656d550bad47d0c623f5994e606985104084e9a84ccbccc5d1 9a6d8aa95dee0de77776cf03609637215e6e3c7d39f51695eb97e4479efc1f0f 00000000000001b4c6097f8ac5da9a21dd5dc911e6a6302a62bd4dc2a3df618d +219600 00000000000002f51e6b09f9d10ff31eddcc1f2872936bbf53e66308da10e645 e24aa2ccd90a3a15834bc717c88a677494e4bff0bcdb2e4663bbeeac7e458698 0000000000000181f0f34e37874913446378ad5106df14caa045259904495aa6 +219700 000000000000011dac5c74d854d65ff1341a916af081ef0ebeaa637d82d715ec d224aa468f5a747da9639815c704ee6c5d3d432ca3939d5952e2742df19b1e2b 000000000000009d080ee47a13584ff11b564ef6c215eca67b293a7623a5a7ab +219800 00000000000001f03f611c9f763e6a5f747c92cf4693e4f8aa05f47f99ed6440 09c93d3f7c97d2c21d77442838ec327b42e86fecafcaa3dcc909a3765efb6ca3 000000000000044121b4e46041e13d728dd6e0959d02dc8cbd6c1bc4ff58e8a6 +219900 0000000000000079d1b1ab07120c3e8129cb54279b6c1a877bb786c275e7f601 c69e01399912874a03fa617610e06ddc756bc52ac24014b440ce581fbfd212dc 000000000000036536a29cd8757ed2ffecb521f5a1c65269d78826f35e3abbdb +220000 000000000000002fdd2c741ed50bc3975a640ca419081711f30f553939641303 be851a8b7df2bb89c092e65b337291f793785668ef2d557f2bd45113f0db48fc 000000000000010d60d852a95461b8204241633a372490b38b33fa6fafa82df5 +220100 000000000000051ba9aabe5bf253bb6c6545381d051d088334317dbbeadd8476 df1e81fd794c380bfc0f2e1152759588c69d20fb3e7b4c21a4a82839488df4e2 00000000000003da08287ed3f338a38517fbe83ed495848d154530c5582ff0d4 +220200 00000000000002b3ce8b1fd19ece53139ca2810392cabde647b1cd67977d9192 239b2e5ab797230d484fb3e5f6f034d66fa5aa80658374ec17feab44a3dce70e 00000000000001cf3cdd280c5435da770b53c5da0bb428b0e1d7a9bf83dd81de +220300 000000000000002b7130c71b1c28b8cf8a7f4d5c64872b642b92031a18ef4c61 56c08ceca830f3114e73b02057f64a25d027cd634f54a9bb675b082fed75c3a6 0000000000000048cb0e6d9591eb889a39574bbeb3129fccea89399ff6821f0f +220400 0000000000000025e7ff937023d2d8ea9cec59d4ebcd1c31da4f73f5326edaa8 c0f1287ed7865f3461de70a6eb93977bff17188c09bbd8e3a037b04a6bef95ae 00000000000001e4846b1b99334e579ec459c8ddabf2639473d70087f2916b53 +220500 00000000000003b5003dd212d419b85565ea68bb4f6b23b937bd47fb4db157b0 29e341337d9f37a9ec6787d4a92807e1aab0faee46390f3157ae7b2fc1144c26 00000000000003d8249562cdd8202c2e180883291e21f8f2532f5abd3a1f7d0b +220600 00000000000000703f0da50ae8a0aa4d6a8587340a243d20e5dadfce096c4c35 8aa2907486e01de5d52483b0045703417d6f73db27e6ded01b1804a7c4862417 000000000000012d07f1e565710954d6a4727839173554993b5f74127a27f8a1 +220700 0000000000000502395988e6f77010de2948e37a430b1042c31dd672e7b7f26f 975545952c54cae94594ea8dce769305411161073bdf1ef4960ec67a271507de 000000000000014243cee7f3b20c3188e3128a2df354414af930a0282d095efa +220800 000000000000045758d1d23895fe064531dcd099a2d7c92c3595cb96773bae0a 199593b0522a43717ce0e8eb553ecaf98e3d3b51b50b7f4b267f962cdcaec146 00000000000003d9886ea84e2b792dee5e30065f39546fbea65c698ed4354e54 +220900 00000000000003bb9a7b7f9a9e5d890996a97d9093bb4a74f5585ed6a304d784 6b3ffcacb798d2e1c49402542f248d3c6d8150da100b0d671399fe76ab0c4c71 00000000000002c3d00f14db74104c1f5787aef50b6b069cb9c67172f17345ab +221000 000000000000034588ba0f8771e2f48b4a3f1451bad40de0e8e04a5b6e5a65ed ef35f31b63839e4b678587637394d4853a15c00148e537915b51c1009d56bd5b 000000000000003c40a20067c74629ee65c306562fce98e09359ca603139faae +221100 00000000000004f7d97b9c4f16c9324f18d120ddf45efa94a2ea1dc80789cc44 8e0c9a650e0a319501af4c0fc0045579e97012c0b14cf36e730ca33dcffcfc7d 0000000000000079602ab023bd91d080fea841067159ad2e61d2296ae52c7a61 +221200 00000000000001ccd86b43bf1941b8cf1eece28bf4f8711627c3d0d3f84f1133 df1e047e4b1514f94f40d781367c5c467c4c21e854269c35446189bffae9b578 000000000000041a247a03237ce06806f51970526672f190ed2dd6493544df51 +221300 000000000000030f1785c3dc5bfcbf505c70207e1e8e736980855676ef36519c fdc4a78cfb3c97249e00dfc903ca50e0a73b9760da7567ffcf77cb10153f3b37 00000000000004b36b7ff0d4f8e38f534b7ce5f5e1b4d53fc9d266bfa6e37022 +221400 0000000000000089e87f51507d57a7cd239f389d8958c38e690bc63e961a8945 c500c5e57c92c62911bdb3a01a4354b16b1822a174202b71fe5ba3e4bdc1981d 000000000000022c050378ec58239f7f2708ad1a26307ae091a0b2a758aa87cd +221500 000000000000012763958fd65f2aa1aabfea6b84c1291afd088df7c64285f3c6 a8a81a4fe32ab07d9058cfda67b0195f1ee91df2b33ad84ca392213ceecd7e40 00000000000002eb09ad8c75017ed9344dfd9bfc462894c82bf8d1454c2a74b9 +221600 00000000000000e2274ed200183b30d1e6eae1f3e7000c6df67a17469d0f251a 56570bb120660e906ad3a66c7dec6d144dc252badd844e2aae1f65f11bbf6d54 000000000000022839921d6dd0ab26924b8f6b67de83dda9a5bf17054ff43d3b +221700 00000000000002c77bf02d2935614101dfae872f979f19f8f48cdd80ce810938 3cd4c8ba5963097cb6fc8767532909833c6af4fecf5f7cde2d070d81b222614f 00000000000001cab6655e135f06fc19cda142bf31ff6b7debbabf5f6ca3f875 +221800 000000000000031150d3d8b70791f766fee7e411f98d6e253053611806c9b4c0 98b53101d634311cf5209208528e4313fb7a2dfb46a0ec5b45e3088722e19a14 00000000000001960077d3151b0d14fec04f63ef4c8df8da2d177ae91c733a10 +221900 0000000000000017fffefbfcc12ef10d1faeaf4b828e95eeafa635381da45466 d77fd6ee18b5613c3853253c76aebaff68adf2843fb5a5e942da7a8587461583 000000000000001a9e39c91bed784b1f7bcb96937e789cfde23d8461b764eefb +222000 00000000000002c752a481ce0c45450ab046e640d38d6532178721e7700d8148 047bc7f76c591bc09d0f0a2685af7259bcb90f63bab961efab2fb837a286e2de 00000000000001e591318e4a6b4fd712e7cfd4e8a87bb65ea1b3c0a3f5a87ee2 +222100 0000000000000240b05f6149dd2593e1e5741bee8422e403ca659ddeb4ceff34 bf84e7edd733e9e7ce42194bdc09e99f357dc01928604c767fe72bf169eed42e 0000000000000362d9e7e351d5dd6bc4f02ca3e1c4540b42755813f85dd85261 +222200 0000000000000314c027f40b94a290dadd174bb6c0b609fcac1a254edaf84965 e4b9239dc8d958628844da95267334c3a760dea412dfd3e87570794a58c2a138 0000000000000174e2de974bfb90a3878c89d119292541f513f2080fbedbba1e +222300 00000000000001df705ffdc92220481e4346fb55b8b240b4b84b931afacdd610 2bdef28b2eb8eee974709bcc4cec1097468689ede9c3306196ce91ba42c657ba 00000000000003fc8ee486362cc65eff5113c07e62ed6da71b8732a879ea1d7d +222400 000000000000028588a30e8266f6a349bfe29b2b8daf2f545e88fbd6be954b8c ab0f16020cae7c296a1b5199c1819fd383492dfba454390e289238027a5d9b38 000000000000048ba0d2fa2720c8aad0a3923575c07c65e187e10e6c1f5c1bbe +222500 000000000000038600012e562426bb8d8c7123f558483d9302039152d8c8fcae f9f34f45b152b5a10707b9c22294b3ef102e2f6763f1eb8e1c03f8b6b1cfd3a2 000000000000049544fe62dc96acd1716228fb6ae376e22c479f1f2c994817a8 +222600 00000000000001f6568bba669f6354c276bbb79059dca01a2125e14df040446f 51222c7b172268163f487aef895dcf09e352d7ca1c1221b94d94d51fb9e8b4b4 00000000000001bd534d2f6b095ff27f5762cc09ce62a3b69b9db8f0597ca81a +222700 000000000000013eac9d6b2b0c181073ce84aa86937c4a736b517a37e36ae146 0b4087374a83bf6f46d6fdf29ab31134ac3c3182a5a10921f96d594aa7104227 0000000000000099b253d5e43f3a36277af619a1c03d828add74d9ddeb008c4c +222800 000000000000018568a451a58a1b548deb7c9c4b7e399cc44891c1632a4bfe67 42f5c0bff2398734a82b535a51e4da6785853a643a106673f012ef3763ee171c 00000000000000073828696e9ce2f4d392b8a0414598810966c9f7c5c54bc3a6 +222900 000000000000021309a98b8827a82277f659ceed6ae57f51b06ecba81585a291 fd592012f867878713d27a9a1c49f2768ad33af9f4d24ca0c3ee083ad84bfe97 0000000000000096bef146eca64576f939c6cffcc251b413157612047eece179 +223000 000000000000012d0917dbac896a60746683db6a3a540856b89a22c64621e18d a8041c5a2a21c7b4c7bdb4bda3cbe7128f6f83faf2061861ea85111bfbe7c1bc 000000000000006d4a08b2305de2b654c4adc38b2d851d7985ab4218d1d62e86 +223100 00000000000003ece3216ebde7f342932534cff6005d9fbbb956bb0ff2a6ec7d 9161a602deeb4a8645d63d9721c73898bc50abbbef87410a0f52a85ed16d0d47 0000000000000212e802f36263a399abfab1aa05123089c82db028332728554b +223200 00000000000001a9ca98d03a4ad35e2042d96710bc613170c1d56c0bd2a945ad ea6cbee361df150c570e15ea7b7c987d1e6ff8c66657339bdb271498ee57f274 00000000000002f535dd48f597a96e38e4ebb1ffbd0a117331a6e516491b4208 +223300 000000000000046566aaa95a7c57f5de88ed5030b16e556684d661cc53e4de74 e1b0bc5876912728ca9ebef3ca8295ccc71c8354d5d3915e297da78a8be261ff 00000000000000ad9e64facf51ca5921027026ec0fb7cd54436fff72ad559fa9 +223400 00000000000000e404d2c55c9c310c0603e4c81750977d80d09a67024e449075 fa5ddb852db30bfd8e8278d8ca6ded351ddef314f33bae9a5c05554d85082625 0000000000000117eede64c77b6e2f4cbbc2b087f7e6974268d91c6520d828a5 +223500 000000000000038e00ee336f7f65c96c33138a672f98d1f761580c9fb802cdb8 904f83aa18f308f1c40c8165f5dcecf1714bbea0acbeb67f68cb537527181bc0 00000000000004952161c79edcc8eddd92609c9e58384d87cd5640c5641c062f +223600 0000000000000066a81399325634312e155dfb7820975e8a35f47af9f822390e 82c23582c1ecfc5e86f2ed14fce1eb740102ede6381fa38368aee27403624c2f 00000000000001f1bcf388471ce8cf448e563262126f7498c5dea9ae67dfc44a +223700 00000000000001891b026f2b4739d09a8b261598c89aaadeeb5f9219526c7590 cf27d57095a4022f2b032787b85fe793ddc624dd999549ba29bbb48e3000b40d 000000000000014f5263b538f885a1d9b0b79beb827d9f6b1b1cbb01044ac744 +223800 00000000000000d4741c636efca544ceaa050f8c954f41705c06f80907578a1b 356b23b3adb88d1d015c06c15efee85ad28a7d3f2e2f58719399e5e708092f58 00000000000001058445acb6d282f56d30d1b2d2dd2a3af26f7e5175c3ef1097 +223900 000000000000032dc1b04f6802f023ca81430f91e612b39894b309639769f765 7340f8d6c874c7e5b282fb145c68029d5229cc8658fd2162e547ac35a9f238e5 00000000000001d13e23b5294fdde5f25255d2d7305be8ca8c2d22d254c0122b +224000 0000000000000107ee276d037218bf1780dbf6d4256bd7e05c66ca133bbc9ac5 1ef4d88f8593ded7e943a60ae4ff4f6325cc3e187f776ee6da0573d0884a9b13 000000000000039882763f89f40690e59c60124f94f3d3cb33f48a6869bac408 +224100 00000000000001ae2609301ff16bf721da21c8f90c3540222ee5da941a2d87c1 6025e84e930a5cb24092e7d83085e717b193d7e95f63208cf5c8bc6d096d027c 000000000000018e3a3eaf10c61809f62b9aee506f8f987a4fd2460cbe93aac0 +224200 000000000000027f8ac4f5b5f7add070ee189d7b905bf5df16d6ae92736521e3 4dee36736cc28b9ed8eed1934c0a04f4ba35c24f31e59fd4252a1fdd5eb61e02 000000000000009cfca55db9f141c5242882fe7cb54077eabf90eac0087ab978 +224300 00000000000001eafa23d0afb6ab3bfc65b169d645c2f782efe774aab9ea1252 c97484be1289b893800f1bb3ec9ae746ad7911342e5e4ae402b712957648515b 000000000000000b34819029bee4557efd485c077248d75d5b0489c04d7e0698 +224400 00000000000002c22f17ff5177b5805888a239680507d3e4d395f0afb06e0838 9066158add85b7df85c3e08867dc25134c6951995dc21a08a15086981e42f9ec 00000000000000da1ebe383e434c3ff367acfed390b14545c8110df065bde963 +224500 0000000000000023a93be8080fdbb7d1e76c711b7f7d1fe809776e27d7114152 be8145613d0a067383097e15cc0b4dd6dfc1838b054edc3f057f8288ba5b3844 00000000000001021bec365366b58fad9e714c692bed3cdcefbe0948cc5c58f1 +224600 000000000000002a86c1043a742bf85c9f82b5c4be8e7604de340a9d0e94f8d1 c3fe93842c31bd8588748a21947cbff59243d9093dc71060d2f412e4f59dda46 0000000000000372a7b89f387ff2a68ee61c9c502a4937c1d9104d1bca591785 +224700 000000000000000e6ef5d0d9615417e806d4e3a9986377fcf4608e616e5be81f 39418cf13fbdd4e27ee8804e30f7dd218aac368067e53c204389fc35e4ec2696 00000000000001479ecd51b3b96faf1273f4ad15d16c8be4ed8152b0d59f3d8d +224800 0000000000000186dfe0572fceec7528605bded25e936e5163d0e647d74ec866 a2222e6d5d8d647a5b6ef2c6f0ef90ab2fdec9a22fe5a9696db46b5b6db91296 0000000000000004fc2c2e9b98f693c16fb6e273efd4879a3029f355b5b08b9a +224900 00000000000001e62bb9a10aadb180ce5ccbac1ad7e393f70d12bf6a7839c999 4ac98ce85057d9b916da4877f9c597f51b95ec78e18058e0043aa5d554773553 00000000000000ac63039190e456b0be6c0bd6d9738b00cd30dccf050c6758f3 +225000 000000000000013d8781110987bf0e9f230e3cc85127d1ee752d5dd014f8a8e1 25ad609e5f988b8e00568346f3fa6a15499d1d3380e359e55bb1cebdd55b8566 0000000000000265e4c2627216c992b01c89da085043a16426ccc28a32119a2d +225100 00000000000001a30afae8ebc3748643bc26d9aab554006819d3bd8a52578df3 0099d4e13c013d2bbbf6e61d09f6acf383b9fd48d3641d34e7049a5d515a7232 00000000000000c099e6e66c3127a066647fe6ad130362d793b1b4514c649411 +225200 0000000000000099a8fec3601d399193da46ccbadcc7953198d14ade5b35c302 c0803fa4ef7c867edf6800948bfa0517e16dd9341a3237f04a24f18e41b59792 00000000000003bae54b6ef5cfed2773bf85e18f9c252e79b4d1089d1c188c72 +225300 000000000000019f4939c05a6dddca79d14e3c484c4a7f1641876f40c3fde33d dbb5da5c3bd160eb0b4feff62b35db7a0e1bb99fa3ec958958eb7ba61ff792ec 000000000000025c074a7f62fe865d2692bf3a6a720dd44ae934c9fa4351cafe +225400 00000000000000ef28d826e3a7c7bed3420a6a289d7eac0fbef86640051088f5 020bdc72a38a7e588f901b5183cbc3961369b63ae33137fc9a7ff0d4ef530e06 00000000000000a065146dd5934d8b6ad809b51f32582b43cc02b69262d6c800 +225500 0000000000000228b59b1e7fbc2338d4d8843acecf67a20363f1ec4ceb4bfb6b 22ab9ef5e7e974a343e0fd020d81eb6cb2db965f2eb987cfeb827ac73a1f55d1 00000000000001dd55df4b7b4b03985a73c625c61837e29fad0d65d31e84b529 +225600 0000000000000216ed4f9a2210016ae3c67dbf280a746b2ae85eaa9aa8881db7 f7e19426aa68b3171957947e807cd26af2fc161318936a3417733f544b9c7338 0000000000000172b0ed6fda84a03b2ff59e2526691225ee3a532384ce352472 +225700 000000000000021e9e7083d944aa802ae35e9fbb0fa083a93094d1feeeed6cb2 71d57c582a0700a1af4a28f31cc9f5365a9c46fd73b45b3a6738d78ade5c42ce 0000000000000395ed941e0ddea6ac1ec40e49211d1bc75fa24a9b148cc2bb2e +225800 000000000000007cdedf81117d6c7d4f0b0beb4bc04529f497de4907e7da0c18 9aec8e3d050ccf1048d34f65f1dddac3452511a2b36669bfe59b1527ff5c2436 00000000000001b0b7ab11c0ca90a8bf34c8d75a81c8bc4c57fa4b7539743d83 +225900 00000000000001ac4ef570fa6c2a2d0a82729ea95da4cb31b7158be9c172451d 73c8afafda23740df0ded61f2a8a27adabb14b7ec02ba3b0507db98b5fff04a5 00000000000002d750eb1ef761c8d6d5b89d02f0f896b058822efb20860c5aba +226000 000000000000012c614cf477c3b155d339f29d565c0258f9846c2f4dd402ff9b d62c12660c5d188d1a5c0cfbbeea5596530c72a0cc1657f20cd90bc79f7e45e2 0000000000000083785252ea71c4d69ab32aa45334721fb116bdec493fd72687 +226100 00000000000001fd693c10ea02882afbfbb5f050e5260406b81930968fe1481f 864955df0e625e22352fac410eede22ce3db47044aa6275fc71755df86516ac6 0000000000000320b7cef17d9d7bde0a29785ca035e76fa218f3e0e12e9e14db +226200 0000000000000287cc64c4469de825b17e7c8d90e3ecb942edebbd74a726f7d7 68be1250968d98b36c775e050ad2caa4402d752fedeb0834dd56f1b484da0ffa 00000000000002b414435f9489578e54d089a9aa9a805d97d36d763d2d68720d +226300 000000000000024e408ddc2c8990896f011708c933c23c33be0d3ef220780b19 ce0dcf435e49d045203ab9bead5fd7011592e18429bea21d9c735ca03e74d1a4 00000000000003341850f65d6dd4d88efb7b02c351b82b14c47aac2017234df3 +226400 00000000000001223ec6bcd7680600d8596caaae53eaf0578570a9fdb061db8f e9ab3388d20641e99b88e70504755c09c16ad04255cbe5c0c2e503e300748232 000000000000020bb32a9efffbb7adceacb469156ad40c01cc9226b9a2d74a58 +226500 0000000000000211d5083bc98c19c72be1b93632f60fe6ce04ca4ea43d3cf1e7 f85ab3d3737948fc18cd5ca3f23ab0a928e2fb14362dc0ef8a79d252c3d43f56 0000000000000083b69d4f6335bb0064382b8254c948edbf3bfba8e7235931d1 +226600 000000000000031c94b9119c94eeffe1ac8013beb8c3b319843e134c57cf851a 1efb53203260fe287a3b4b8d676e5392ad8d091e3a54f6d5a0a9bae4d0ed1f60 00000000000001197def6983a14c6eb9266c178037ba912a91d5732c69b1d21c +226700 00000000000001a05cbd8b3bdce822c0b611fb5a1984b370f3e9c7e5147dcd3e 2ccb2de098549717a14386cb73bcc29b11b887c1abf0af3515ebadd685fe8078 00000000000001bd2cd4a32e9245bbddd8a9cc147a9ac54c34b38a70594cc168 +226800 000000000000020becd3c9272f0c51c8641ee0b5d54375f3d6ee886ab49ea6d3 90b30242df0064d12ebe23a5a10aca96f461a3b4ad7f3e0d8007bb6bdcb01a73 000000000000006a896c2a9b3df60435556e584dd135a650119e6ed6902c855a +226900 0000000000000305cecc12f40ecd08f92483f5831e3bf38529ceeb2eada62c18 ad5e1503fbb5a13560c00ae9974d8e400de8824f209ee29bd4a8a9af868ea096 00000000000000abac46035d88bdebb3e3b8ed3e942ca150c2fa374ed34c8750 +227000 0000000000000303d872c9bffdf46429c40b41522a9b7c7de21dd192fefefd98 329b2aa2e25b598c6f4781914fc9d4002caa18310ac6e9b0a0e5f6bcae03fdc1 00000000000001f0313e43738fc5ed509086b0f8f92a6cb5ccd5f6931aa5c71a +227100 00000000000002797ed662d93172e599dd7b9248797e15024926fe85690076b6 27ad88e2102a17083522911976d3f88e71ff290e9afe93d1b7773d42de834b34 0000000000000011e3bea6c80dcc9191ecfd66b06a7dd3da8931503095d95707 +227200 00000000000001b239b2b842812b93d6421cbc2eb855cb4bf2e7cd9ebe000329 d7f2b7636e2ae3510a895a2914907cf312aa457bd682179ab1b06c58aa1f3d92 00000000000003363dd9114ec2e204f4c6cee20ade38f137594f91e5c1356ed3 +227300 000000000000011ddcc1d56bcb490ec4eeb9fc4392898e98464b52f38687e05a dc33bf968047a640831389de5372c011c858a528f3e44a964ee6654408205034 00000000000000fb2bb96c5b8888185400e1d5151f9f4e0bd2315ec4d2563098 +227400 00000000000000ebb2db29171fa803ea82c37efeba92c19547d7a48399d25c49 ce8b7fe5ad76429cd7967c5999bde0a6018f512478e2367eb28498cf30b2a193 00000000000000b7ba51dc00e34ae0e5c583943754d600b63c9fcd873614c64c +227500 00000000000000db0f88a28a20ee6b0b383090dba28e9c0198a433b1d2844192 155898861f9ebb84ab4325d2db18e9a03681cb9192d1592cb218dbecaf7cbd56 00000000000000c31217a86fd154c778eeb7eba54fcbb0840d09fe16ae20bb90 +227600 00000000000000b60d063ccdb62065352e07a9877b5b2d0b455814a668f15b4f f10dd9a9c56c19d428438eb9560e7d36f1f1e484b186cfd2caa297bcd366eb6f 00000000000002ec75f2048d8bb7400db17c6ba9ab3c5ba9b7594a94f7e3bd68 +227700 00000000000001f2827208b0b419d2c6d85581f3945502e58adf0298d7822f65 50e69cc317af07fe5bf8d30f40c91f91948d7649320e293bb36be6ebf49235f2 0000000000000178a45d25b7370be57ecd110c9280e3bbe4be4e8d4e51d9da3f +227800 00000000000001f43e19ff1cea8d8e9d6f652808dda7b8e95a6dee5f3a2357f2 e878aabb1d752367bd3677d52ea19ba8514218da2af7b0697e36dbe06baa14a9 0000000000000030ca67670fa8d7057be631fdb7aeb983a8a2fdad5b5db3eb8b +227900 00000000000001762972aba5ab63d18671830c49b11a1bfe036dddd2232988bf 474978b2740c2182c914da84e050176022d1f77dab92a8313a80edbad5f1f613 000000000000004429fb9ff515544eb6c8fd11badeb605b8262b3d7e52bef140 +228000 00000000000000efc4311c93fafbccedb6fdc682b566cba9519f1736b9788a67 b3f675d88fccc37d9f7b82a2eec5ba0f3507a2f5f13b07c9974e78bbcfc20475 00000000000000e62201a56eba803dc5510affd2cf7cbb35d8ea90a513ec5eaa +228100 000000000000027a503a6cf36ab841612e7834c19868ef73227cd5d58c05a761 c5b827111cac22f70fbc49984699888592da913876744f85ff039df0a740bc3b 000000000000001f5d31a74c56a5c1dfabe3a7ddc36eca233f5a347f666e2903 +228200 000000000000008f0a6a7ef10e3725696c9594032692598db31e780dfa037034 903043370858b5fe55abb0e11dd58c8e63bde853135f06285f4bbd3a9f84330e 000000000000001db84a246e19e5ded8fb706d3ee2fe05e9730f61aa25360157 +228300 000000000000005b8ad88bb95a16063b5cc84f99eb57efad4e393d9c359fa1d2 585407ef52f27d9105b42efe439b2829f11befdff635cc3744732338dd3a76c0 000000000000020a576babaae4bf243d0ce978044bdd37abfa389f72fe3e1825 +228400 00000000000001752a33342cb23c6b79088488b6a7ecd0cef3d741c0c73acf66 78a842ada1f994c66e96b7021f2818d667246517b85f302358dbef1cbfceef2f 00000000000001c566fb3065889dc1c4f43f070e13841db09258fd7142b843b0 +228500 00000000000001995aa6d383393fa0bc21da183df4f9f16c5642800fe6413bd5 621c979e8e149b608b0af20e24a7b931bf98d202dac90d4fd0ff236303c72ca3 0000000000000001c05b806a9821a97d6749780ec51e07fb3eef02c0a33eb4b8 +228600 00000000000000588f9bf9141e540086c992a511440eccb4681e2d5253ac14b9 c7d1e50e3ff34682ba89c1d78fc7e8b0972908412b68036b0d6e67b81f10674f 0000000000000076024cf20984ca6eeb84fd3a6a4abc73bac5d3a95ad3dc86ec +228700 000000000000006219e615504de2bc02860b0b70889c47c1b9d4f3d7cffe082c 7dcfb8007ca1dce2882d8183aa998b5d795e0c7e7d8eb4e0d08c9170e25da03f 000000000000023bdf6321dddca9989a5f11ff568818ceb45159f2f39bc4e464 +228800 00000000000000771f79f24597eb36b5850f26ed69f05ec87302c8629fa53a56 9425a21417d6fecd55fbf56b2a6b19ef0eeb40ac300130b9d9eba02dc9fa162f 000000000000027a3154de81598cfc628237649da64f9422ef28fa7f9f4e9804 +228900 00000000000001ad393f504eaebacd8093c738453266fddc8e676c66cf2b8434 327fa6f259d6faea611240f77c30245552455d3df3a46ed8c429c3517b7b08d6 000000000000025a1540ce3156502100dac6c62299691963fa6bf940b8a871d5 +229000 0000000000000246d7f05f608a407caf6c6d99681a4f3da8388d5bf799448d50 4df1cdcb7b3cde2bc8d2edc84a47431c4e1d7f6fd1d27a76661ff89fdec8bbab 00000000000001d988829e54b45f4543f5b0d23658d50ed1226880495fa761f9 +229100 000000000000026832b00d0dc08ea8f42aa5218245edb8df6aada3a5bdf7a98a c9a3955754f64c43d46f2f7b9c62cacb2527762c93498172497d617eec0f6525 0000000000000198f34c88f29c6907b2bc4edb963e4589c9565b91d1fdcfe6d3 +229200 000000000000027cbdc46bef8850baea301a521b0723a068ec19db803a4e1af7 88dbd80b90b19a61af7ce5ea84d2e2350cecc287ba3374956c538afd0d9cd686 000000000000018d30179d9f757a21131a65fbdfb7b0dc7dc3a9f8325d8d8f25 +229300 000000000000026358fafa7a4cc70b650562880c9f2d69edf3edbf4102eb9077 1f75f8d815ebff8c3ebd3dcf8cf3141cea87ae2a73b63f327c56d1b3c46c8547 00000000000001484535e5678665b1ffffb72e6980f0a910057c73d0952cf251 +229400 000000000000020c8bb512207806aab6ac65e56e240dcb5185b37fb54e16309b 576160507ddcc2b77ea9ecc7def8d834460b702c743e094c3a76b9736f72aca4 000000000000002784a2e45bff193a9096a7eab1ebc194cae4b73b6b657494a6 +229500 000000000000007d04c916a2cb80e5e6602de90f9f94b20a2dd14fdb5b0daafe 13e5106baadf25194f6894e24fabe799c22839485772f401582b6dc753747381 00000000000000f6d633030057d4302722c8a98c16671e03636142e41f905c48 +229600 00000000000000bbf228fcb546cde14d40e8a284b82395d597d17d04ee0f0492 da64c3593dea4ff14261f48fddf1b915d79c7c6ac835be07a535a66c060a3b40 00000000000000a990d630852a1e09df2accea6761afbf25013143a938d115df +229700 00000000000001dee53bf52418b1221e4dca90da453daace1b6a78ea2ae22604 0dc4bc4ffac9d2c02778ac0c396e86d69464e5b8b480c08c49b4c226ef450258 00000000000000b2ceb1151908739242cf3eb2f23f8acf605f2b7d3760bcd7e1 +229800 000000000000024c361230d3329dfed07c3e2f24c55dc77a86949969c4d9b31d c4120d030081fc3c20101203b05b0534324a4a74656366997278b2f43a595f6d 0000000000000224615e7dc4006fcc1baec60b7cc3fa102332575ef53d2b8be0 +229900 00000000000001434c1b8caa78e0a36ccb8fef0436b9882a38d65b2bb25589d6 391415d4682ee4096df61422132bd7a53fff6238315a9913a9c609a3f0929cf4 00000000000000f639b3e28a3f675fd2473d92cb2ea24368d8af5d2e23d25f34 +230000 000000000000012cfb19f5662707816e122ad60dd9b1cd646c6c9899be2c9667 219640630ce967fd03ac560c4f1d36e64079e547733712c5e226df627b13cec2 0000000000000200641676d2831f4ce9f0f900d0a60d72df7b78d09dbe91e777 +230100 000000000000005532cb7de8eecb862f4aebc3cad1e4338ab51edb3286e77e41 5b16ca3c58ba3b7c453a335da8ce2d7fef9eea92bc21d1de012245b8692bce1c 000000000000018a739e131d6a38cd08060b9b21fe344508d391c77c713ea81b +230200 000000000000000e65e95381350dae59d5164a6cb726cb9edf108b5beba27c88 e28829de385d6f57db4f81809f2a26ab806cd348a572fb9fc45aa6fe655ee3ab 00000000000001ae996409eb686372c8d390887069b93e854fe5605de430cc4b +230300 00000000000001d032767dd18ff5f8ef099b96c30b901baecf75035c7137e381 f60f5ea80910d9aa6acbf5ed8cb188df610986ab6059cc02b01a9b4e798ad348 00000000000000f70703ff8220b8957ed2ffb421fe49fbac68e4927fac0711f0 +230400 00000000000001ade328085f4bb54206781e170cb7d7f56ce24d1175d81a1c92 09a26b486fdee33bb30cebe5c33ae4f2e26d62c3a3ddca66c21873ef1b52d0a2 000000000000013ce852cc95753d430521a239f0d1054d6b2f0c3e9e8558b4fa +230500 000000000000021f230e3042f2eebcd37cc1d8e866462de3dddb4575851f6dcf 573fc77c8a8cf0597479f203a4f33e63970e9754be6509574db6e3a6842874da 00000000000000612d34991f1e9974d6005dcf815bc7fd5147c5a9ae2d31ebfe +230600 00000000000001f1449928eee5897360d3978e9e41e75289467e907bb04e81c4 94ed195438c9c8c84f37bb36fbca77bb0b3075c5dd4f335810d58c202c36556f 0000000000000178c82ca5a2582c1b794df48ed49fc1a3e578dafa1a1f902efb +230700 0000000000000100b0db587d03f344b0f480e534d6244a40051082972370c03f 4a44b89bb443ad779e19343f26fde876c15fa052462db4c22acb8d92b3a16ee0 00000000000000ef82578761f0e5aa4f02e4f90bbbb9e350820a038a091bbf74 +230800 00000000000000662f73798a62196f8943abdf97350dfec4e8ef0531d3d9860d 283604f2db0c2d83dfd2dd66568972cbeb2d533ab42f48ababc173709f22cb23 000000000000001bdbc7f22fc970a194331dade164cbf6b2b544c9caad327326 +230900 00000000000000b26a8996f285784b5667c17ef515ae4043ab1d169c61da369f 51b0710f4ae7337734fb04ac1b6896d97ecde4bf3d21d3e98f3344be7f9d7ab7 0000000000000178d0bf07be7c647df61990be3f78639a50b1664b1eb77162d5 +231000 00000000000000649995b9008d249e39da05135109ad938abcc01ac7383a2815 d200373dfbe15c6dc99835bcccef62eba51f3f4f4c6ac988146a474289127bec 0000000000000005c0dc87c4b9e78cac92273c5bad5bab1e81de3b5606de0367 +231100 00000000000000c1957ab81c0e12656e51bd0d95e9ca4f53993a40b218a94b0a 2839a46f8405e4cc423f94beb52c2fe18aa95560e1260e0f4f87f248c6656849 000000000000015e4befc2e742623c0d310fdbedb86095ed0feecce11da2d36d +231200 00000000000001fd9b88ed7c0f4a88303151c5a6a01f8494de95c3299555e842 8bd7f8bea5b183ff47d3def87001351d8147aa1ea4bfeaa379e8d01cd1d598c1 00000000000001242e383d0dd97dff07224af3bed913259ce6c90e6ce848ef47 +231300 0000000000000179c0cc546fd466b4686809434180ee25ceb9aa76735060e7e2 3d9a6f2bb64ebff20b7af1c97ac865560b4ae0fd2bd6001f7ce228e9f2bcab2b 00000000000000f7de439d799edc41bab5f9e788ea8c3e10fcd606f1da10f226 +231400 000000000000017cb38ee4dd9f2c944ec28ad9fa9a5a5d1fa07bb248482801ef 49825b0a7a703ca6a8451e7f0546e5ba525ca2b74cb72001fd3eced163efe1ea 000000000000012f1ef8d12f69465f70ab21fa7c258e73dee7ab4fe7d745fb30 +231500 00000000000000c740c60db1db2a3a1543c1b3d359040fcf78c693bfca9c29a0 5573a1a37bf19791b2942d40ea24a0fa4ccecf8924ae15c3f2f44d41783fbe72 00000000000001732f0b4cd93576ff26c3bb9b8bd0f189b5378d186c190131ad +231600 00000000000000a23a6caf305f01fbff722279d8c28f082c658c51e8c7e51cd4 bbd7445e57354364a968aa8fb603c64b645acf245d6d5a15c9e5e84cd13ee4b6 00000000000000ba71dd2b3c3f62e14fbb1c9cc8aef4b7ff95023d0ef8d0c23d +231700 00000000000000a9de5c7148ca7d836f086323e3725c5d7b869490a483d8439f 4495244b30755424798a2fd4176cd948602c82c0cb58ae4b12e635cd5b29f230 00000000000001f07f624299732eec4148ede8c6922777ae0bc6f5550deee9a0 +231800 00000000000000412ff793f318ae8a8ea80c3f4f3c516b29eb9b40142a28ef7e 1b6e32c063fa7e59195b6a24d2fdfd73e4a4928778625e88f2447f07feb3cf42 00000000000000d9148d049fe95c6148b29e192b4f7adc5572d37cdbcc9dc264 +231900 00000000000000e64f9641edc3a42cd846f0ce7707441b1b9ba0595f05003032 f8ac8bdca5306eb3574d87c3f6200b28160d9c7eb4d095e93724899560423593 00000000000000a15a89147afcdef4d70a411e00d8affc641cfbd31f35d9e6a5 +232000 000000000000018f47636e1c3a946db77624880ae484ffb0233f5aac6316b3bb eceaf5d829c88e13f7a4c2d2dc64fe42e7b7f2d2766b89ca9d53c2fb264afada 000000000000017bf6d8208debd93d57c0bc951c0f032741fc1733bca49bb0c2 +232100 0000000000000088c1080274408cbf171852bca0bb0cfefc526f82f28b209b25 cdf694bb77a5639f6728e53a3833289cceea8314115e674a59ec694844599dc0 00000000000000e7113c7cd16234c52bb4fb46acf012391b673df04ac8926f38 +232200 000000000000005e717a7db480e004001300a5183dcb380ecea1f6a7fc89233c 01c853bcccb6de0606c8a105aa058cdc10cb6ce6a606318d6284ccf44678bea8 00000000000001dcc80e63a5875f6980c10d21cab8df88c7d3cdbc1f03a5d97f +232300 000000000000018162e1e79a7afead697f7971414c3abd1416b77212923811a5 e2a704161b988875fc23014c8b8b324661c71bfe3d63c0fadd9a4516a7a5608c 000000000000003f9afe355f4191dab5d7a60bccaae38114c8b60be33a84dee8 +232400 000000000000011f43e34af3f2f9d0bf296e1bb9c7dfc2282a28ebc000dd538f 14b4706cf1301c4e67a04f7672599ca576131bee03123113a269c7aa701ec12d 0000000000000142de32c60d56198b0b0c5458d2935acc99bf124eea36cc4af7 +232500 000000000000007a52db9895fec5d18715a4010c8aaf96c3e4e1b1736a1ce07a 8a06911fd6ff08307b859f3a0257b613d7cefe30ac7fe8e84810beb61e9a6747 0000000000000016739848d28ede348939e06a83d923ee87c5f73ce3c9cfa4d0 +232600 00000000000000fcc04308795aba33462feb7fa7801a3247a7edc9796cc5a502 7346251a8dbc6fbed78d69b1f926c4c8bf0727dd895a8bc9dd5d5bed6d69f482 000000000000002cb0ea5e9031c82efac151b994dc73882fbeaf92565ee7d5c2 +232700 000000000000003d7bfff6c17ee609a602f9320552099ceeca538220840b84c0 f2e14335aa145a811c7c76a0da308b6cb77f61496b2b081543249b8d6209d0cc 000000000000008ee3a722b58624087933e84535ffdb94bff996ba82c2256e28 +232800 0000000000000011918f8eff29807090005c3f69fb546c7db13bed43a745ca74 4debb0c0151d0d13ea0f1cb37de89f67549a68a22c1e4d0d5ed8c8e045ea63b3 000000000000018e1c7579841a285337de1970b1f084ba7b3cc997d6170c9831 +232900 00000000000000bef95f02c338748145b2ea6609a02845a74a8799d54b844a40 48ef7d21007b8be082ba066c9a49fc571b9b18ab20d27313788ba06443ce5961 00000000000000432849603103a4f62f2594145a4a78b1f2bab097096ce08853 +233000 0000000000000110df141cfd908d5652c32a417c27187169aa1567b383ae0575 54d690e04090ea5cbb7748b54f3b271e0ba0c201ed4d9d9bcf994faef14beeda 000000000000010327ee36c57b0dd16122c6f1c1ba90282c7e2cc8968126a434 +233100 00000000000000ac210931c9fb58864ebb9482521ced1087eafb0bcd58af362d 2869d55e0ee3633a6de6e9823a2a1114afb9797208b421c8951586108a536736 00000000000000cb401729f88f8cb91a9c5fa0311a52e4e1993601825123c1c2 +233200 0000000000000106ea348ecffa5e2afeae32ae04cba87a0f4d321bcad4448f1c 1156dcd6e1504a9aa91cc918df07607016badbce0dab1f2896779d17895364cd 000000000000003ab7c97fa5f7391102979ca5791bfdea664b53c31da5f84c1c +233300 000000000000009937fb932fd95b0116184868b80e6ff251fc0a14804294e5aa 1b4548416641837b7005d8155f03d2dca1b7c0b5b266af9b5a6f169a4854d25b 000000000000000ab566fd6efcecffcbd9a833d495979233df2fa0b921249224 +233400 00000000000001b724886230d269e377921a48c1e6c4a8bbaddc49e519d88ea2 5eb27e29d1befaad8e8026dd2965f9b16345b51e1ba97e4a94305e6ecf92e5b4 00000000000001a6784af783bdc5ff780cd4434b1ec28024c04ccd86ae9f7a15 +233500 00000000000000cc8fc800f2f037785f31b48a88ee66528eaedfa6f5f6430850 f702b9f24a7acb1ac9dfd5e6974953cd3b1b33b155383784dbf823010c395a0a 00000000000000051fd28b1e00523ed72c6c35ea754e30a75774c4e44997bfa6 +233600 00000000000000b35f8d18bde8c2f6a1477ad4f5e9e441dff24c856e12cac2e2 d9e1df7699ce5b9503b98ba0136fe1ea7b9bd852bc4887f412393fdf6663bfff 00000000000000b134530f0a1ce277555a22b436771b970d7f51f9dbe0155380 +233700 000000000000019bb231125fb48d4b314e58e2caf83694f58fa9e1083a22a657 1909b1250792aebff30e755089ca0094384a6181f7091ebd940025960056f914 000000000000014a4f4230dc4cb42a6b5e1b4cd0a4e0e88c9bacb224e6b459f7 +233800 0000000000000043946e0e25e87b7a7a8c08ea6c2099f67419cb77d3bcb63c18 c73c9a8c65b4a5d0f355968ec3ed32eb488563ccfacd331f8d3df216c7520e0a 000000000000014858c01f6a4b236a52c3876d6613d3fee6f99a0f4388cad527 +233900 000000000000012746923247961c78ca5fbf2955a3c00fbb6a7f228041ddda79 a9894ce551754fcd1fe1a919dcc649acb5948a73d09afea89b3eb21a1e6f7ac8 0000000000000116800f232668368267eba4ca25f45dffff1a5a8452df1e5ae0 +234000 00000000000000597f9263ea97bed4d3b10fbd55733a73bd1027f1a9b6c1451a aba08f70bc0a710157028a6bde58937c7d29978a93459836fd875705de6f7413 000000000000001fc3ed9921095a06a7bc3ed2db0400341a6ff7a12ec4f08912 +234100 00000000000001a5413f79c2c17f384cb774af450d9b257bfd33bda1ab896ac3 d40ff0c13cd9b737941661783666288bbcf2a9fda4570717b3ee1915699dbc50 0000000000000195c2eada6f9f60cc3c45e405b32a08c435eb602333c66d9695 +234200 000000000000005d50fadcc6c6af6400edd0e8a34da62d4572781a67e76d46f6 e566fc01958d3ef6f68b023ea1582709fe6aa1769755e4f9d0016e6215d9fb13 0000000000000153f58616d839cfba2208591a6ad1af750e1160e564d83821ab +234300 000000000000010ae4f8e3f9d2fd9803f067e4d8c2416cddeafa894c1714cc68 05a6225565c71be9bf5cd557c6cbe286270c8b5f472c59bb66c9d1caf99c6356 000000000000017bc23a8ec2ac3247e3d0c6f88e2c7639ed23fb83549c35e5eb +234400 00000000000001640a590fadfad33111bd91fcd6407e83ff8540c194af38c126 e0f88c07fe21b407c6cf39c491a7dff9ffb048179837d921cf6e0b9924882e87 0000000000000197803e1b1ffd7d37f85cd9507181afb0ff24b66db8cbb7ab10 +234500 000000000000002f2d37f8aa95015f24071d6d5759d824cb30856615c8dd2004 1cb89ee2869088bfcd5c34781db770bb0975b45f84a08c092b39d05aa742c320 000000000000005315c97ed783320890d886968843fa231d0bf13e486601c0a2 +234600 000000000000001ae94c5c250f0db0b972e2ba12eb5378485d0412bf12e2a031 48b4b642af41ba052fceb62077560764dd6b7270dfb86e358c4892d12376e445 00000000000001405c1c7110910d5dee697b6411976d80317e9fc2cba6028c8e +234700 00000000000000f10e9f9dc68a7d620400073025d77abfb757b9b71740415807 97ff71ad652640c4fe15d29d53b14b64a70cd2088428538e6d12105034a7c567 00000000000000a67a2dc6098981fe1080cbf2a0169eaf75df589a818fd1f7ed +234800 000000000000016d7a6573f7db813ee598955b0ef1f07dfb35feae29b7881831 c09e8aac50ee62e36dbef06d03311513a0b9e3e4a346ac3532cdbd68fa3e9b0c 000000000000006846f4da76577e94be38aac00ea2bca80f26cef09c6c25abd0 +234900 000000000000006d492d2849cdf536a77a70e2022a8c53f6595883c7e279bc67 31032eceb3c9e18f1b5ee07e0470a2a74238e2cf9425882be468b3549e7f1416 00000000000000ef2c3227627cd13b9d58ecc2abf727f9437ed330c809af2386 +235000 0000000000000051324ab4bdc1899c671cd340681ea814b2d4b6e141efec52b0 1d21c44a53c6d639a8afb5465e294264715858b05f9bc9705172182af554db97 000000000000017bc7d0f6140d75d6ccf0bbfa881d81b1e951b5385bca333a64 +235100 000000000000018cc6aeb8ecb4241761c7d2af99e95e848560838ed23e3c6453 e50af9cbad37eb96eea01d34b6bd4a919822f6359620075d872b3c8beaeacbe6 0000000000000055f0e974d12367ceb0f9369a48f038292deda1e36050533478 +235200 00000000000000bd564841e3face91f324e05c727b3dd01c74f68e6f39cb0912 efc4448a9a653f13c4745ed8eb3b958fd78fc05b1ad64afe9d386c722e78804e 0000000000000008f28ca6ff05d43e4c28fc8282dd594f5f8ef755c4917c6f58 +235300 00000000000000c05911afd079df451af78cfbc7e282db17c572a569fabcc783 688f1427b3aca072592419e19ef426ac8d4fc85536500a167a62914982cf3cd0 00000000000000220dc3b283e651068535f8e934096cfef35342bc688d8ee578 +235400 0000000000000190d6478545aca17efd40d82dae8fc0fa364a5bf6c0f403fbe8 76929d41848bd934ea8bc79c260a77f8c6485180b3cf63e7d84b9ee9e33be577 00000000000001381727641808aa30d483e38ab15c398c5c2c72c9a99f99f1c8 +235500 00000000000000f4fc8808d350d1aa6b92c49194a1487e088463c140cdf98a17 9d185580e010f269b68805e773157b2cc127c7871164c77923f29a2de46eaf9a 0000000000000166bae0b7f21d74c47e53cef3db290524ca43c640c23266ba7e +235600 00000000000000d9228d3cee04aeed7d3704522b2fbe6606c340b9ed4a02ced0 d38a681a29c2ca4b4d35a9bcfc29ceed0185ef1b22c7f6bce50d8e8508641d3b 0000000000000114443c3a889c0bb5195ccf498cf6e35413ea98250569832eb0 +235700 000000000000000f399762b3a7df151f5acb28da1dbe7b99b407315727a7566c 9ebef2a400944088b86f9b387fe4ff98e32d25c56836da534a3e242303321b75 00000000000000122f3985ca2935ad236b88ea98b658f19b77c37fc8a20117c8 +235800 000000000000006a5f6b8d5165e556cf532e044ebb66585225f1ade462ef1dd9 2c42b2fe2e95939de031093afb519c63bfe71b473b51e9f6680366e3d9e0cfc9 0000000000000125f6a7a94614115a4c1c702534629d1d39e906cf898b0c8cf6 +235900 0000000000000105599bcfc47f57acbd4210168ba6732e6930656b237b8aedb6 180ca01250edcef5bb46d1c22ebe1bb7f01a6d5324e9f83dab5452212e837ae5 00000000000000bdbb980d0c81d0835ec55e72f35e29d56be3a9c5611020619b +236000 00000000000000f2f5e55e89dde082cecc9b4a46a10bbb4197f5e35b16612db5 fad901475f5f6f1f5b27a6eefee1f2757a22c3f2694983bb7b7ce37aad56fc33 00000000000000a661436a3afba0ae9027f8ec858b45c87c309b22f1e53493b3 +236100 00000000000001372da97b7c565b6c5df147457621b5c194336c3f72b95d4aaa c01348482121c3954d3addebbb641f04198da688e70488451f4d8f78655bc88b 000000000000007e9cd9eadda5db2bab77d95026e4b74ee6421d1b940b6f3ac4 +236200 0000000000000006cb32000702bd8f23388b54095099568f1c8c4ef1f9264eb2 a40c861a7f737a1d16d2c92663fd10f240211f69a732ef23670a006a7968ec58 000000000000003afe4ac473968ffc0770234a873242e0cc1ad53974802179d4 +236300 00000000000000bafd0a55f013e058cc2a672ee0c66b9265a02390d80e4748f5 1997d23d843dfd892a775f0a49d7f760e6b106142d5b3424f2d7194fda60e0ad 00000000000000488a59a1273583318918e6349aa806deceb7876eb85ecf813b +236400 000000000000000f38f8693eeb67d1cc4d94faee697e15aaa324541dc80c4a41 1e57919b9ec9d6079bfe8c7f53eca27880eaaad44e2f9645bc25acd0e8fb2cfb 00000000000001593bd3a405eaca3ddeacf8d99b6b07f1c987330dc3db7383bc +236500 0000000000000133e19e734c141050ae014cee3251a11ccbaad4741a840ff072 c44bf7a78fa77ac4a24129d180df6803e458e2ee6c50b2dbf13d85dbde32b6f8 00000000000000eb4379ccb0c7653f98e7ebab68b17a198a211f5f0d6a86b7d2 +236600 00000000000000bd5e042e9d6e664079ebdfcd2beda08f8081dd6012dd178154 d5c7e9b74a3511d3ef2dda271fe5cd41d71628ff1ca0e1c880dee68ae9ffb14d 000000000000014c5e3ba82128419f5af67a8e665112acd98c86a2c971a531f9 +236700 00000000000000e92e587fb649fee6e3b6139fd8aba390ab36c533d58f79feea 4f246cb028bad980a86ed81bf4c555e3f51ce1410fcbe2e6acf290990a235821 0000000000000120c4328987e0999b95ffbedbd50f9d1482ff1f006a38c6750a +236800 0000000000000083b77cd59027250fa447113325e32df96f7d88f6838bf12ab6 5a3ba4682c7ca24825127ef3e85306c84d3bc27bad2cd5cba667ea6c4e97f5fa 0000000000000005f64cb81eb3baf49a8c29c882e44ee87ab7c3b05e52e5eff7 +236900 0000000000000155024ac202393fb87c23277f73234fa730f2af5b8c3c60236d 4d71e41936bb5a046ed52bc78cb49768867d9717d4415a44f53788144128e715 000000000000011ff72068221f18e3bd0f1f605065e4ffa192e8a66874b70932 +237000 000000000000000efb4eeccb046960b9117ace9db6b3b24f016246d3bf1c403a c5ebaa864a43b67984d68b0f363cac5ecdad3e0196d8654b8a192bd1cc4d904e 000000000000002ad4cd15e53e890c7c0b976cbb4b84b1c5dd0fb059d0b0f7bb +237100 000000000000001bdeb06464b1305a4886651c6033a836a52cadb305e778f393 718822969e65f8b3ef99df7d5fb3b91c446d2ce16ad7b50ab3c292d8f9e341f1 00000000000000af3ab889c6529d923fe0d4f30d65377470730ba5da9155e985 +237200 00000000000000a4a3ed1e0cb8256461ebe7175939695c2d7ba3a859c25a2ff9 a0ebdb71487c83c3fc56f4e74252960588d3b27f254036bbde2fbc872771f9d1 0000000000000157f5680e4f5491489f5ce5ea09454465b3ec610ddb2dde5dc2 +237300 0000000000000014ae0c8328db3b9e240a092eada60caf0b8fb895a8417c4341 9d5beb26e2260d603db74076bafa399e6f541e5ac8fde9dd57363d87796e74e6 0000000000000096570c26e6d66ed519aa1937a403cedcc7fab1ef2331345e90 +237400 00000000000000fc9bbfd92c77543219f2f4a58c7f72b6045faaac6932a827f2 6dd6b66f0c0534ed4bdfb786c620dac8da2d70acd925fbf1ad877ede727de233 00000000000000d6b9e4ada63ef9193f820c189ab272aa14525411818b2b4c54 +237500 0000000000000115020104600c9689785b8fe8d684b6be343f7849f2d9946106 bec54691f34600ebe17bd5204844978c5e868243d9a61a2e9bd34883c4561235 000000000000016dd240c83db2d6453383896cd5fdfecc4c1e50b167fa855652 +237600 000000000000013549c61b496937e13332831ee4455a6207ef94f963634eee16 7a36743a14c34c35e9d6772a33094a05e4906002975db7006191ff1651987a73 00000000000000a81216343ded733a17fe802496586f8a0dbd50cf353e28bc14 +237700 00000000000000604d2d03562c4fb3758cba6b1366155a760307c3e7605407b9 5311b1142bfba309f8da7491eab260cdcfe641b2c739e4ac6ce6aa30f4fa46ac 000000000000007a3fe7760d1ce3b47987f007c4b55ad2eced16d0ceb42f7d18 +237800 00000000000000752da71822646475f2ef5b974ff9b306ac1956f4cd7e27165d 86fe5e15b91f92e21083dae1cfcdd7e2ee74b20d6a2f43cbbbe7a66982c9aa00 000000000000014f20acea117bdb74a34fd4059ecc373992e1404a9abdf98150 +237900 00000000000000cf52033131cbc42f5b2e300fcecdbaef87c2986aae721148ff cc49b492bb9ca14ac490b529e162ec015f1015da8133b931255f7212cd4e9c0f 00000000000001147a534c743c28037d7a1094ee0a6c42036ff20bfeedc292b3 +238000 000000000000010014007d4b51ab60063684665401e448c6b0b1971a7398a442 322c97d8ffef374f864af67e2a32b86093ab92edc6e34eb0775244e926ec3108 0000000000000089c8544766168f329b696c69b273419fc305722475f738be85 +238100 00000000000000dd8c2de55ce2803f6c45fc1940e41830c5919b7c044e54344e 264249bf792ab8ebb6f17ebc81f5aae7d1b6434eaa53c098a3bef7593b0b22fe 000000000000009d8637206a6d1e9575b49f7fd188173bc73f23e4099617beaa +238200 00000000000000d8d002d3ae0b4d2673c262f277a4062e145be421c428b4ca7b 2e42ddb05ae2f6078f39339c6b61543f6d716e80f9ff30f7b253192805e5ef84 000000000000004def9828fa6b83b800a083553f2d5db25bad7c6dae6583a7b2 +238300 000000000000014c5bb087c58296772f599e81e4e604bf34a8c6473667d18649 0761de7c15e7c8d00bcc53e3e48107ce73549c230ff28739cd53fe15f5cd13de 00000000000001027c8b5ae04fce5ccf3948a15e137dab152e62450fd998c3ae +238400 00000000000000702b1c4de9cab12a892087c9a928eb10b5106769a61320c44c 55173170bfdd943f2184d5ff4feb8001db775b907b4ce9fc10197806890a554b 00000000000001025f117c550edf4c694c04b2bc7a675547cbc6087099876bc4 +238500 0000000000000020b997d4c219f8136559ff50066f0e946a409645fafb29fe8f 834208ca20e6e8500826286be8a7dc189e1dd783beeb62234afa4ba9998b16bc 00000000000000f1eaff9a2009d4cf94312afedbfd0a85a08b3127fed9b257cd +238600 00000000000000cf5177ac1f8ccfced5ccdee5faa9dc453ba793401f2c8bd2d1 1f0607dd23d70f90bb788fbddccd0878785dc2a0154a97ae0c2890275e15d7b1 00000000000000e0c7a3103ec75042c97f466be04d08a6419dcfd30a438d1399 +238700 000000000000004c5a35ca0b0f73dfb7145aaad241cee50740d0806303420393 b462a47621c4aae526b9110eb53bc536a59c4f4b514f88a4447af3b702732d41 000000000000006acac97826062257a82a19790f8d519f93332840599dac33f8 +238800 0000000000000040f742ee49374315b12a172ec1175bb2a28a77ef17fd369bcf ac19d4a47d3a16ee2b23730f653886cd3bc2d5ae7f9288c3969d3ef774540994 0000000000000019393f384b46d42aa5198ca79b6cadd5788d97453a1efcb855 +238900 000000000000002473da39607d936f071d367ae720cafbd3fd34dd10f4553952 8f50239ff502f2d3932d5524e6d28841856b08f3fa072b212680f9b729527041 00000000000000ed7dd49f3cf5624be032fcd504298691887201bba49acbb806 +239000 000000000000009457d1c7aef43436d3b5f67542b343b4b57835912c9ca718fa a069ee5215c8580c9ed262d3a087f8efebab2f7e2ecb49d1ee77805c8e760d6d 00000000000000aa7d046f778d3028edbc99fa90ef8f453e68de4eecb3f8ab0f +239100 000000000000004e3063fb654c4ff1d01786bc1569251ea28a5a5a0d05734471 79583704fc097e89a8545b328869de4e57d3d5058eed00ae37249420c9f47265 000000000000014a699d9b8d2aaa0169701327add0fc6075b1358785517574e7 +239200 0000000000000008ec48c1ed0fb7f95cf067a8dff445c9f4556f8eaf29a41d2f afe8add466db4955f08d1d7c1d45855ecc85ece3e0cb1d49f560dc7ba72eb0fa 000000000000003b1d07a83ce9f77a34bc8bf8830eced21273c68c306d199e91 +239300 000000000000011a3b211ed9f3eebd0531e24157799def6ed4abdb227f0c4114 34794a2e879b80c5c221777112a6429bb309a2c6a3b8d150538562afe2f8cff3 0000000000000106b140ae2c175245bc4d5b1570b0d695a81ba039047c121555 +239400 000000000000015152d27ec14e3327b1a3eeaa269b02db2a40b69ee917a3b9a2 fe840f5fa755bb748f391006ad7462c1e70b0df786ff2f5a5ac89060f1eb90a7 000000000000006ef290b55f7239bfd4b255d0605ddaa38ed6136e1111ee9820 +239500 00000000000001401a9f32d825106023daedfda9f4508476f3d55d3ee7556b4c 2ebc31971e0cf67d6ad09eefcac1e5be5cb22d21a04a33cea6b1043de0f52905 0000000000000093801033fbc0f78b4027e65650c913953097412a8dd1ce22b6 +239600 000000000000007cf0cd0abfbb3a187d495ce29f81e189748af958bdd330d40c a022af430ea3112472f00a81b647662f01ac57dbd3965138fd62709602718fce 000000000000005ad7d21ac9249388636fcf765af86ac267ca255100b7ac9172 +239700 00000000000000d8ea2d31cf284470c65e05afbcda4862423cdc1d7b704d73d6 b39799c1784e31fd7e14cf9fb4930e0defb59ab127adeab1972153422cfa0122 000000000000012b13fecd4ac7b10de91d6d97c85ffb5667cf6618154e18da33 +239800 00000000000001100f1ebfad0273e0d679d7cb2b2aa5f77c5162961de3fd5f47 6a9796c2f81fcc2e91dbbf00f116f3cb2b53782eb89c2c8a09b1b04156ce84ce 0000000000000038822e0d12709e0e6d7521bebfd0a1ecb68ce1167eecd4bacf +239900 00000000000000956f45db4062e709bdec0422bd03873c223a295d7ff5516108 63252ea47ea61a309088229015ed517fed39df60a137efba962583af0d4622da 000000000000008f6dbaa440973fd0d1a82169a96a4113c96901e8b837233e6c +240000 000000000000000e7ad69c72afc00dc4e05fc15ae3061c47d3591d07c09f2928 2e0a0fc8f236d09e34943c63a0fa165a39de708cbf0ff0bd163108f6fc51844f 000000000000006e77df3985d9f69d92289b28bd3510e8b124ec24f2bc91142f +240100 0000000000000027eab65e0a93eb71ff35d18ab1b13fdb4a3269509fd06d1536 d4d808c0a98dd6482d19bf9fa361bf568ac82137d3bd14939e8aeaca2a6cfdbe 00000000000000648c0b428ed673c39f13e1b905efd84d05a76db8e3622e070f +240200 00000000000000ccd0a1e5e5c49c86b774d2a382ffc6a067290767202d4a2ce2 c05117a19608e93b02f2a9d172bbc9d045ee2218b5a4fb857c41948e51054b89 0000000000000100d9cbd55303647c2ebd545de6420effe7ec3de6b32d1df0de +240300 00000000000000da23e9c4922a4f9eb20a801e2924ae7cae195f11cfbfa4aa4f 5351adefb2483deac2f06c61ecf9af1bdefd0e543688fd4ce41e18ac5c6d1170 00000000000000218aca25d965cb0d3d3a509513036138e79c76f5855043d881 +240400 000000000000004567127d969e8febb22b43199eac51738e7ef05e7ef917056b a7cbd4fc8f21045855d48bfb57bb4f3ed7d5e539f1a2d38ef0185a372747303c 00000000000000d0142349ca7ea47fc01a4059654ffb76cd76e2d95e6457a05b +240500 0000000000000105cf4cba99802b777a81cf78858d2ddd13086710cfe671df1f dc926e3484c40b0e5563612e0f9ad6939ad3b7714b470cc5c93fb5bfb3e9b14c 00000000000000488c42f73e19248c0bbc6c28e082943ac9407a1cf4b473e2e6 +240600 000000000000004de05165f73973c4b446cea555319bdaea0d4df7697df09696 f2c1f7fbc04583b1f6b66ab38e0e61cae4e86f1d4448f0bb676c387dddfc542c 00000000000001129539c2327b2cc04c87b5427f3323f555f84b1c235214c944 +240700 0000000000000048053eeda0dc5566a27dd49eee6328f11ae21ffcd164d7d469 7771a98e5171e2e8556e1167d1304f1ac64cf7417b0fd6c207402fe9417b1e0c 00000000000000865228a43d8570edd1c90f460496e1edf06b6f0a74f39e2f1b +240800 000000000000011245dcf10881556466cc029388c4b79cd3d3e2cbe8bdbb830c b7786e33b5ca46664c6eedf656da53ab380aabb7caeaed6cf94adab2d991416e 000000000000010da9f0f7498254a52323e8fe3c971e792ca060d692471700fd +240900 000000000000009a5f91eebc87532a5a1d3dfc0b8b109646c99809f5793b1771 42dedc99a8577596cfa87bced0f255905322f8e91ccdd1a81f2231bc5e7ece46 0000000000000095deeedab1460b9511e30f8b3d74aee31ecfb915f6634564c4 +241000 000000000000002a2562421dc7814786d3595249f50fd4cd1fb7c41b4a848fd2 a0541e7faa9f047a47f00d461303104ee013597e3a6350e412424d963ae19479 000000000000004b9455b0c39dc8e7cbadf5058f46133162c4311eb854750ea2 +241100 00000000000000b58746310730c2ebd9a9f40593a7a23584e95e89855d833b1d 49e177db1424dae3f608e28edba8b62db82e1cee769b91ef693e84eb5eeb28bd 00000000000000d2ffa79ece0841feee775f77a2c6dd1d181819e77697274394 +241200 00000000000000a744781cdf08f2fa90a12c9fcacb761100c0d08465dd3650f8 7360ccdf6ad51d3338008333b19794c7c4915b06f474156e218ce3633b4499b4 000000000000005ecff3999490cdfaee79c762519496ae2c2ed19a6f0c73b60a +241300 0000000000000083768de45278f5b8a962473049fa568374aedffa15be03a461 d0176627877fab0d4f0222c486456b11d0928581113937bff13f95848140fbe0 00000000000000d98c8eb5a374636c4f0f31da79c2b09407ce3969641c7b37ea +241400 000000000000002590349d867ec20dd6670892f5c749ab18914406056eee8060 40fcf1509788463a7ca4f807f9d44d232c4b38c82d2a6d2e47e3412a1fa20238 0000000000000100651f6fbc464532301b77266933cd41610ca1e95177b0544a +241500 00000000000000cdc0e1ba19fe7a76a47e5c6f02eb4af30717d34f671a8c7c58 9d0d0e83728f2f9fb6ab6535f477bc5f8d5811ade2b8597cdff4f4c0c21babc6 000000000000005e1eae1009aad748e13e26b4c9ac346bc1910df7cb7e60255c +241600 0000000000000015805570d756a299f9177200f19db61692a85868ac91a3909e 7f344119e8d831866d8f88b4798bd50b2fb0e6d48cafcf120ab2f95312f2366d 000000000000007c3b2e4eb951edc839cd1111609f9372b4184396d6ae252e79 +241700 000000000000006331373d9f4561d7fe86483999fb68494837f430a3af83894f 353005bc22f701ae0547a51b5bf1cb9107faa964f500c600969489eaa8a2ae84 00000000000000b19f849243c751237700330d5ee62c6f571dd9cde2d6bf8ea6 +241800 0000000000000038f2e042acc31dd9c629419ef687d1a18b1f61ac9d7de0aab8 997b2906af58f7e9caa6ba9ff02aeae2ea112f57105ebca6e4459bcb84b2d259 000000000000010ecbb1a4d6616e0b53ac47dbb29b060d3b82b599f05cf7d5b6 +241900 00000000000000d632c92c22ffbeb7fe3774fa27ec5959aa3b33351b54b812b2 f99b8a4d660ee80aabd9af1ea0bb4bf30bf0a21a811fa8feef634d00a5b6eaa1 00000000000000a05b433fe06ac2af0f555f83c3376568a655af0163983dd299 +242000 00000000000000c95233d37a8c78dff10afecb14060347151b7eb7a04a2a5a3c 746bc861943c7bb5f47c24b7fd2998271383a0e1a6459c2ebf80b5479e534cb1 00000000000000ccb81f6bb82efc9e2adbf5525bb9d638a1fa7981fc5a9d0a3e +242100 0000000000000049985ed88109ec48805640290c50b837effaadc01eb4d5964b 62f06aea5ca80f9489c5567bb0ad3072695fefad2335bed7142cdfe58f4f90c7 00000000000000b265c3858ebc160a940cbe402affe90bbda6a281c42440106a +242200 000000000000008b8f5aba3438d986789de96b62c9a7f6b68afe00b7bad8101c 293bde4b94d165f26aa2e60d0c2be4a069a33fd8669322871b1e4d954981c614 0000000000000036e4661c172e70ee6b117b006233c902c418a3ca677dc48fa8 +242300 00000000000000cc69cbb72a9315b8f010adf8965349147a494fcb64bd2741c9 b1dedfc21a3eb670620b60c309a7bd947e20906fb4dc996fbb4d386eb2035097 00000000000000a16fd4a0f87c3a70574f7fa876feb24d0985503999f101dd5e +242400 0000000000000093426161280e5381598e8dd63d4d41110bb5d1c3df79e5dea6 76fef5c7f608012f942c5fb2728d9ad42b5b9f534f74a87effb62ea0ab8ab7c2 000000000000002c61504b45a93cd1498be4038ded53c73f8fa3d20644767e41 +242500 00000000000000a7e4c120c1cb900a14f0dba91d34fcdc8807c0a2fdcbba4c09 21b283fa1ea08dfd09e0c01746a618e6c04555f10de820a85daafc8a8cc8671e 0000000000000048bf9ac4567849ccf3da5cfc040f4b5b2f228958a5c9a53874 +242600 000000000000005cb092fea67390a07d1adb105167cb80d91d0faa09b5eb574e 21afbb6a2d462a963d6ab7b98c76167d70e3f15f1285abd634615bb7041007f2 00000000000000363683ec6ec4ac26eb38358095716cb9b5b61f427499fd374f +242700 000000000000002d6aa3455150dc4ed11205a84269ec9d8248c74fba1760ca6c 5b9a8116f1d0859fd9da687caf95650ca05c64b5480106762989af0f81d39cc5 0000000000000035054271c485c0c1e7d0581d22196ef7a11b00ab308c9a20ad +242800 00000000000000302122c1b063780624ab918cf25d54a3084579ae17e8bc6944 d0a2d123bfcf17a26f65ff9f997dd242d278413dac804db4ef7d33f59e3d721d 00000000000000ce570d17df3bd3da9ccfc1e02f5b9a681e0b18230ddb352054 +242900 000000000000000125688888f538d30b6d689ab0f68f142333d84df7c6afdb00 8ca3fc55cf20a1d5b5a41264bbd028bf941571b8cdf0cb0c30633f1b6130ef7a 000000000000003cbf4c440e85d77a96063ae07889ed015770fb32f49013ff5a +243000 000000000000004701942914ec40b88654862cd042f04fae98b7f3603a26e264 595b311b265d0c2226db6170fbce75dc1cf23fbe3657cd609eeba48605ad391b 00000000000000047c754b20c4f73fcc2fea8d00e571ac477d4e2993d93a9feb +243100 000000000000004454e2d5f40742d185e29af85e9c9ffc231d73781566752bf9 6a72282fe2b99f0a8d1c1f524c4828f0bd35b62433ab857369836d88e9a63fce 00000000000000525ccf3b1157d6f79fd655b115d652d12e32ac92d59191d0c1 +243200 000000000000007497f4b7c0e435ffb0c165b5aeb22f9fe384f81bb517c56151 48984d002df7730197a31f7431c11a2869ec84a5471ef6036f35951cfe9ad8af 00000000000000382691339643d5e4c7fea7a9105eeb898d6dffda7da6dcde62 +243300 00000000000000a4148d7b719f6dc8f366f01e04fc17ae328dac53c70c799a47 d94996120493a320838aeb52e25758a94295baa403499bd453739c21cf450327 0000000000000002dc266b67a34caa0cfd6f68b1d2a32298b5b10cfd7d483443 +243400 000000000000000accd2e0d1dcbd6e05a884b7baa8e564a3820a45c95e815041 314d8ce92c6ed72d1cde42b04526632f5b17724f09abeb0394596ccc656f36ca 00000000000000703ab7d4729f2ff7b9f4335665ba99607aef7cfaacbe18802d +243500 00000000000000dac6b703fb82af969d6ab2501d20c466e7a49671d3c923b89b 39db4f3089086ea8d5e32cf439e1411f4d10b6639feee3852d32736aeaecf274 00000000000000d87932f2b3aeb8a9b7268ced669dbf3e7cb33db3bc818ddb8f +243600 0000000000000071d73cb5a538553753b57db4f4f667de599811eb9df9bc0da5 e6069052c028e4c654086a31d212b2d0a9d5d3c0e66e6e8cb356aced1420d753 000000000000005443f06fcba5a4d842fb0f09cb3f6a8f061f5a2f58cf5caeb7 +243700 00000000000000a69f62c0b1eb1d722f17de05e0a7d1e3a63740019389e6a2e5 d7e89308f1c507edc62e11f287bccfcccea57a82219efcf0db4aa8bc1001641c 00000000000000b106e9c3308034c390222debc52a2078fd61c05914b9fdd8b8 +243800 00000000000000bf235a834b8fa15c4ed51853d39a0c1a7c25f88b084099eb2c ae658f43ff0b8a1d87c0d07686adabb19fa46cbeaf20c7fb461404ba5c34b181 00000000000000633565d89fa6981ac02f9f5ac7df18a6448a2a5e55cea08c68 +243900 00000000000000aeb4d6fae7b7871a688426e388e77923c9b859aef6f8fa7c6e ce15ceb2687664cb10b04a1ccea7bc725dde2015967ed3c19af6353773ea76dd 000000000000001c02655280ff0c74fc75b6dacb48489cf2aee053c98c3cf41e +244000 000000000000006ded1526017d5b87ca22e1bd0da3921872cc99e9ec77ee5166 a5a29ba0771a5bdb391c2a762d8b3d62159ce31ab4f62c0e76b880ff87b57114 000000000000003e7b0ba0ab332ef6659061f86fe63002f81d14cdd2b787b48d +244100 0000000000000017cc1493dd680ba0f6f02823fafa6878093a063e42faf583a0 647ca500a6ecc68b92fd9cd826014a8bfea9fc3d6400128c0366a2553a168c2c 000000000000006af9c0cde3e7f164a7cd234a2aa2110f9536308ea118b35c10 +244200 00000000000000516d2826f9cd8cb5aec17f9c8b9bd9fbf156fa1cf44592a33c 33f5b64e4567282c47442dadb4906cd6359798fbcf22af9d3f3e006c5dd948f0 00000000000000bb81ee677011c9d0534cfc9898067d00d347cd6b8b05bea249 +244300 000000000000008c200ef4c24ef2829ee4726d8a6687827ed25cd7f9133dd920 0e37111d85dbb020d0aab24c5d0755cfcf0ee6e6013b3d522bd977b48f583fb0 000000000000009ed6531ff34df95abe17a1df681a14346d1280a3c1fecaa767 +244400 00000000000000b665be8d13c4977905fb8af008b774ba951279a43d4c2874d6 e91f81fee1988b768011fa981ca8ab7996245f868016ffff0a51be8d5ceaefdd 000000000000003421b8ad56f28708b1b90c017e8575b97964723e411343bcf2 +244500 0000000000000048eaad55efb130561f447a26043353653990508c4c3929d5a9 d7d1ce64c2b6d1ed67e21627faff159f67529a0a39aa3b23856965131fd20f6b 000000000000003f2f1e9e3af435447fc818c001ca45e1d62cbc6199c2acd7d9 +244600 000000000000001fe183d6bd48798bceb348ac8f915c9348816f6c3acb2040e5 90d2ec599b8ea091aa235129e27c558a0b0569e9f709b095e4f519e1132b40b8 0000000000000061537f8989b41d0e7ca757fa48e2615126147b1cfeff706cd9 +244700 000000000000007131f12c65c27cbd4de56b5206316cd0907916589528424ea3 6a776c5c2076f1388838582bb5f0f52a2dd6be6ee5dca9f7005e0f62f5fea4bb 00000000000000c37b1e86a6a25f124e650504cf8b6f4e4c31ddf1be19df9791 +244800 0000000000000088b031d48a7bce734d97c96c70367df5f6f93983f00f463c88 89f8a2439bd589ea351d43a409a684c19282ceb8a45cae60340eeb71dc198da6 000000000000003bcb8c79d55f1877168707fbed9385af449191275ddd3d3492 +244900 0000000000000082293078e71a435d315a13559a628ed77a5c28284e12ecae14 3b09ad987c442c1211526bd761ff0b9bf48a485c80f744734d5533a2a010cbfc 00000000000000b7938541c98baf8bf74409a6a898f4cdc1d22ee11fae2acd0f +245000 0000000000000023bacb560accb704fcb94665d02f191ce56410b11b93a6636f 7893e459fb0e06f21b1b6919762fac09069dfa9a44f3597e79dbdc62885b4004 000000000000000a7d0af8233b2d8dceca0c804b28967365d95c477b07915899 +245100 00000000000000ae6b97cf8065b3a2b28d035fce6bcdac3c94e90dcec1c8ed8e 60d61acf29bdfc8292501211c817258a21155fee00552527eab09fb46be4f1b5 000000000000004cce1d4056cb79df8774d1070ce09ecb6cd741aaff08764a73 +245200 00000000000000ab9c7adaae7659f9a088613d019d8d9ab591d298e296bac6ce 0fde5a59be168a370ed2226bf33b70630535803e1d0a6285f18ae81ceb80edfd 0000000000000052334c33a2db1c9c9ff72f603f4615c44c4f13ea2c6dc22d7b +245300 00000000000000a76c50ad9c85558d58867f4768c954b43d675f049e0d090565 62e197876268d73cb4d43cf3228c5c4c0e21056849bb01021113e4c27d35cf47 000000000000009e44318c618bd7b8d1a8c91fa6d90df7593ed8c0e28faa484b +245400 000000000000005cf08d066b9ef35cac315c6d50e5e27c185447410f3e19f3d4 ec568621a78827592ff8c2468c3a5a7873f3e7f32dac6aecb482cd7d01265453 0000000000000055286a2c027541dcf5c9c120aacf6631340eb946333dc65ed0 +245500 000000000000002104103711c69e487e54bf752a459b602aaf0377e19e76fe78 c0e707d9a10679327f818b603300541b6c65020e2467517b3c6f5c70a85257fa 0000000000000077d4b409f1ee745c4030da05ffbbaa3067475f7404ab8bbc8e +245600 00000000000000a1e34d73bc9f6d80d3831b11d9a7603b21829d83c5b940ece5 90c49eb4047fa6f4b8867e1488a550fa820846379bbdd576611c62c0443035fa 000000000000008164d23166a164a37dac5a6c58b110157e7940a95653ecf00b +245700 00000000000000357f0f711f80cf72b1e81d32b21252b1d18d1fcb4a1989d21a c54f1fdcafcfb2d5fb57b8f65f8f585bae2a344785d27c6cd3ba5cb2383660e1 00000000000000b3a8681e1a7b8e380bfee80de5fb93aa85e30d7c59ccad4dbb +245800 000000000000004a527202e44ad88e05ea0b21e35be63dfc6d326512118ac843 f93e48add73fc2cc3fb0247d40dff669e9f37778cb446c01a8dc06ac2005b421 0000000000000025bb54c497502329d6da630e888bbad2673f146c0643d0cceb +245900 00000000000000acb1c90fbe24ef87f7e09ba7cfb6d0e055a9399f01385aa86b 1801e1e738d266050a99978975ef0b427f2c95356838f727cca570b7cd9b1eec 000000000000005a038c4ecd3033020c02e583fd9e2c5ae23ba4aa2c65bb2061 +246000 000000000000004c318a3ad2ebac28d140fada215b11f5b7d8e9151ff0b000af 6c2ad4389a4c9114f7f3ad2c894d860bc5a883282a5a857483c121522f385af9 00000000000000349dd94eadbc44ee38ecbf5e97227e37f3c9a7ad24f7ec8dfe +246100 000000000000006750b94d042f123c0c969110c3488297e39793293254eae71d 71749133ffa3023334e133c4a42905aa797e426146799816d16c56539ad73c0a 000000000000008785621dc712943c7608fec2d937d3d07eb914abde70328d12 +246200 000000000000005be0eaf123aa78b24ab0de8cf978989e9919de76b5abba5e98 339c4486ede7c1c628be2cd0265ebc9806384e62bfc2d95ea3130b1575223ff0 00000000000000999bf028464ba20a43f5a44e0b97dc36e03aa4a312a8533f30 +246300 000000000000004816ac51825d4209c814fda76b5d05d2939216bcb9926793d5 2dc5df65399a2e007b92d8af872c38d2690124ab3c2f20a63c7ece97b0d0b80b 0000000000000085d4b63505921e63be6b00365c10399d9a7c45c28cc7c183c8 +246400 000000000000001e58356307166a15357ab03a459afdfc68b859492ef5e16ec7 b4ef994dcbde21b206caaac9888414c355737009e9ec667e49843f0f079b4758 00000000000000a239a3f52d451d65928c2294cbe12bf0da22526324588f0528 +246500 000000000000008b6a5eece395cbb3be9c9663e02dede9831e7d4e117cdc2b66 8c09bb06e09812acde2af08b1dd06df6431152c321b028c40bb2b01052e85abb 000000000000008553073747bfd08e0b3503b90b8065b07d0e7728d3ebb44e0e +246600 0000000000000055a1ea46618c238e033254e532c4ae2f7b32121ad4e60eeb2a 0111141fd578308cc2a0fcd93152d63a62a9540012450a149d061e40f1e3a05a 0000000000000070d95d7beffc2e30b352ea9540943ac92a2a0f1e35a42c1a38 +246700 00000000000000483373c6fcf3555850853789eb96a3953ffb72d9fe974d21c4 eace282876905f62fd63bf697521c37d5695a6e206fde5228920a98d5552e9e1 000000000000009efb30483ad17453cc7fe6afa9f0241ef3974747ad0026c411 +246800 0000000000000023b473d0118a068beff6c15b8b7d5379f172c91f36899420a8 ef6e72cfc8cdde9f67923844ed77f04713223bf1658f35fe77eb208ab03a3540 00000000000000100a58abf45cbbd272031d4f4bb4f6b9ade606e81affb4503f +246900 000000000000002458236a0b12e6b05feda5da409c97852588a976be866d8747 850124033b00c2114740c0569d7c5cd05803a3aef3fc56f4cd89b857d9bb1743 000000000000004a1e517caf413103af8f4d6b6ed0e7b7180f35587997bab391 +247000 000000000000003d64d714747fbfb615e056f533386d162f0bf5e049a9b6e0b2 52d7a3881807f8bf9e6c97fe98db9767177005e3e1bcf35b778d802fe0dad4f6 0000000000000015258e972eb5d3334ec7013d97f569377ee940567a7a47a56d +247100 000000000000002d6f83245a4a73101bc7f57c8b2b68b3aea261e440502bf7d3 b15af0098a5f5491564dee071b1460e5a603a87140b97855bf5c7036b0594fc3 000000000000009c74bf14d91610999e3c33bdb8a8bf78ffd05f03d759b3122a +247200 00000000000000762784b647ede3678f172d73dd0c72c2180ab451b00d756959 bf0300a2d5e5f23cd06f3b2e0a99fd969d381ce10c9ca81857faa02c8e428aa3 0000000000000090344430e3956a709039288ceeb473fff6c1b68e70ee7169c4 +247300 000000000000002efb6eb419f23215514516a38c8ade1014b54e622dc57f5c99 33546b7a3a04bf4c6eb16444358e643ea08939a78dcf6c161c7a3b2e036977bc 0000000000000055767d20613b065a229db4f27ed0bb6cd73532a40a115b495e +247400 000000000000008547e24261492b9c3b2851155a0c99e704f1db191b856ce943 147de3b30df402df1145072523c0f444ee58d1f30b9d0758c06c096cd1b2d7da 000000000000008c10a1e5d4a7c1bbe89160290b70f643040a29df391fd894f0 +247500 000000000000009c3ebacf2f0c1fab318ee905ce46832985dd1fad7038174777 57fcf44b46b8454cd3b2f38362d7c07b122bc035d6d847f769f2f5cf8b8d710d 000000000000006b55245d1508de275f77cf3ae06ec5768dc8f569386735f904 +247600 00000000000000357ec1a79cb1aa8c6f9517cb932620a4b917427b13e2ef3e3d 2470fa232e7a7ee905fc7ebbe6a4b6377701b22ee40584655b4bd75e75cb6646 000000000000000b5d5992828ed9d0845afed9c596714e3701ac05ba897f322a +247700 000000000000006a5aa50066c94dc713740c98682d550f87d08bf0c35674731d 9e67650f8e773ddb0ea70b83bacabec1abcbe6e2a36ddc7f5ec604f486d49dc0 0000000000000077d49894f1904fa62eaa3b234791ee97c60cab2c359c4b77d6 +247800 000000000000008fb854729f7500337ab98b1ee180e2d8801f1fe9286ec33b4b 0c12480bbb8e4f8f84d0b2bfe1359d4a348c90091902fc0befadde36dcecf80c 00000000000000a03cf4aa1c080ddf1b97c259884aeeb830e3579ffb55e20718 +247900 0000000000000006e675df13c15efd4f4ebf03838e07b85a6a423293fb8e5d0f f18bb9fdd64de7cad8de5ee6ad5183c07651cf221efbc8f154e737dabd163104 00000000000000040b45b983bd2275500a8ccc6ab0cab01359b9ab63b0846d5c +248000 000000000000004d945017c14b75a3a58a2aa6772cacbfcaf907b3bee6d7f344 b61d51d76d44ea5d6714b40ab851c6919de2a09f23b6d844d79a5993bdb30d8e 00000000000000172fb9615729d960ebd66864c60f04f564e6b2464142460a58 +248100 00000000000000305216785232f882b7c4392ffa11e0ee1c4bc241fb07283990 6cf5edcee5467cec3ab11118440e32e4caa5223579765387f18805b51df70afb 0000000000000023cdca59905fbc468dc3fb47f5bd30dae5b05d9b9ecd5627ee +248200 000000000000000c562d5468a053d94c8ad2b17dc5190843798985a229a19583 ce73932ebcb24fc3bc8e18cffb232869d05f37cd8c319d995a3ccef404e6043d 000000000000001f2aaff9cbc31130f912e51ba88a72c5b2cfe4a6082e0dfe5d +248300 000000000000000e59c865a6835d0c09ac4dc2166fb1c510293e5eab64b36670 d14c12451b05f0c2bf1ec33ec5a00513d30a63e6cf097d45953b6ffdca63de33 000000000000001120dc266f6683300f32ce982585ede9a785ab99235ff1015f +248400 0000000000000031611a5ee7e9ea77c36d247f9171cf8ea8838cc6e44adc73b4 eb719f25cd43e8dfd2ca80695c276c7e10d38eccddc98cf137ed15c484a2cf99 00000000000000832aacaa3f1e224f71451161c73fd753f1d9eefb957051d1eb +248500 00000000000000588576e7948161039aef0534dbc2379b34eea05eb6980946a4 e245b52d6cda58d87c3160ce4539d820432021bd8e2034f7bd304dd70029cd97 0000000000000069366f1462ab9fed9c40f788d9e74f1f67c209da20db6122c7 +248600 000000000000006900e1c65b7dae83fde2ce6efa7020ffe83ef4cc13c778a3fa 19528ef612eee43b67f289ceddd5d21906067dab7bd5dd0e892d0c8bf6269236 0000000000000008e4c523116b7364f55a1383dd4981acb70e9055d308783c31 +248700 00000000000000061840c8f271deb10c2a6cb7151354ee8f2d4ec316d3487af2 9f36b00d81658264b06d95c167fe71207b0caabe07c6def31554975062f6df4c 0000000000000042a8082e97866e18ace6b748682001111a569099a1abdca5e2 +248800 0000000000000081e8c01ed71f5b8c2e91667c528df13ae17976ff974e027684 58d059aa64aeaf017a5943a7be1fa2cf01c350ca4eec583597c6fd3276e32145 000000000000000090790978e7ab0d580d39e1d080c3a5aac84d1a6abcf36edb +248900 0000000000000084c69f82dd4997d16addeefc81dc88f3b5c929f32b4188ef39 b50381b6f06915bfcbc34949b6b7d6c9448848d795834352e591fb0bc3895b6d 0000000000000043ea5b63fa9289deed8d0e02541887642ddd776d4dbe8a11a7 +249000 0000000000000085929039ae75bc5526699e29cf2b1a3741bf0a845fb94e6c9b b6f38aa3eda8715df95ce8dbf21cdec5e64aae596f66ca0cb24d78de8ad2a74d 0000000000000055e3892613d9d2f949d29db931c9a63382b5964af8a5966b2d +249100 000000000000002e886c5ed2aa2111e6c1089992db67f4403156a6ed611f9da8 3846988035e8264754dc72be400f07ce3e325bad054db3c849b963348b61f1c7 000000000000005ee0ba2769da6a1a6b668585f4dafca59d984ba580716b75e1 +249200 000000000000001024604a15425c5dd246e5ab42aeee2f546f028ec24838c0ce 1f5e613da4c6973c1f9edce7b7f764e1215517fde0e96ba5288e332f0ba5e86d 00000000000000321de803f29606b32a1e0952c45497732e4f56084aa92b0a0d +249300 000000000000005f2d7e62569b1613c52f1a4084ed4d168d051e010a73f5c5d8 4eed7a592331ac3dbaf8217018150dc905c5972562653486b698cd8f68082ab6 000000000000007cbf9856c20f4736dac357a1e6c6237a95dd77234a5e3662eb +249400 000000000000006f0f76f7d09b2ba8b556814168ab5b94463cf80d2a30f97c43 eec98654ed105fbfac04648331680396f87517d2ca689d5191e7b235a5155629 0000000000000044d0245789d6280a34404d12be42cd1dd59907d94e8c36cfcb +249500 00000000000000110032b6bb08335765ac87fa04bc95ee15c9ab44bfbf80ca8f d5d60fd7dae9c14121f7ef86a3195182d4bb6abf2b9ecf21cb392ef2d8bad740 0000000000000040048f0e18aea438224b4a894e5acd6732b380d7440ce0055f +249600 00000000000000735a1b6a809c40ca6782780270a951ce1422e0e5f2da8348f6 9d7c52f104c0ae9b009955295dd0a8c204f3ba0e4ccf5da4047b6ae69e46b82c 0000000000000024f239d5f4feece3aa65b5b282eb34def13a2bf420a433b2ae +249700 0000000000000041cede57c9725cfa1b8a33914e07f2856beba53fed403d9784 a792c5f25ddf326331d95424de4602b204575be93d4618a3cb7ee88a5233adfd 0000000000000031b821dfe4547565664d5cce9cbd3bc2e422cace5cf093113c +249800 000000000000007d8b8a636594facecae0f60f349654a58a26318b29170422b3 51efec526d94a2612f85c740b97a1975cd61ed9ff7334a6a3fd0cdccd7e601e0 000000000000002c5af6a4a330527739a8071ed2fe86eba876dce8d7e9a96793 +249900 00000000000000389e55191c0c053e24a0b3154126e724d918f1f349225dd455 bf85a98805b329b7c89875a5f4c57b3bd1cf7b58c9ad78a5d1b8af31ad5425a4 000000000000005f08bb8e6860e189e1193f0dde3c71312ddda1a08fe2d44fa3 +250000 000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214 ec54deb3922032bd324d45fd498457b535e9a38fc23eaf439509ed1466d3dfb5 000000000000001b3f536a81be90d5cbe8b79c2c1df53d1f91540cf5cb5a7c58 +250100 000000000000001444a09639a61b244a5ab3954cbe272e35fda17c25e25156c6 5549a214504fe99a02d96742794f34c9174ab7d5f1937f47a504e400fec1a5c5 000000000000002af4f16113ff10770c293401520f50df8ab0d56f078a1d9bc7 +250200 00000000000000726248ae90dbf85d69f65372884e194c9eccc8f4fc615213d9 826d8b6de470be82ca7b9b7f12fefb31dcf69aeaacc59dc4f84b715114af3d93 0000000000000022d8778c04f9e24c5df5788ecbd7666b766e7279a91c75bafe +250300 000000000000002570c114f900dadb97991c97ab65b0090194ab5eebedec3ec3 8ab605bf907139147494728c649efa96171eeb915d3650fde94547f9292d49c2 000000000000005bc8c6e81719a6166881baa70bbd6d7b849be47d23d69d18fb +250400 000000000000000ead5617229ca302153fb0bb8ff9eb2283b41ca2640194fdfe 7bb1eb3e2c9bc51fa6555b2d68d9e18271d56eea479de0fc2906be3fde0bfa8e 000000000000006c571ffc24ce5ba757f5f011e2a2debc1f8d5859504a5ec29f +250500 00000000000000141dc9c0447aae40b30996475a05683a3e4d44aad4a2e25479 2f4f35d03863d043327336d52fe41546f542e4718bf8860d879f3218d6a2666e 000000000000001eb527e6fb058be59f1dab66d45c651ae1cb511e61112d4489 +250600 0000000000000039e1216ac2483d7d356f775229cb7ca01c5b927405b8d3eb6a c4087b94a706ee115022ab5578f24a855f2f65e81e0c3784698ac3f221fe0aa0 00000000000000335a71e856f5e35a201269f0e2533ccd29c7baf2c6ac5d7c73 +250700 0000000000000032bb8fa5c29296c3ecf206ac9229e95b4282f320cd5628c74e 9d4c9d371488dfb01f77013b02da0042382c16e76792ce72f950a4182254fc4a 000000000000004faa8db1fb1b1f236c5a55a65ef390b2b3f272a8cd04754c0f +250800 0000000000000039eaa841c9de4cb01fc40c6597160b6da870dff3a4ad6d118b d876051011cb8d453cbbac0b0274436243bf8e240d92dbb4c60aadb3c236513b 000000000000003c564ee98ee9e8afc395c29b97d3ae60d45a34ced734279cf7 +250900 000000000000005c8f469edd54a2ac1a4d47e1638f9c55e0e881d49449a28fce 591caa916611d06b26f2b40eb5212dc993959c36a005f4f757f43ec7ea9c868a 0000000000000037203c49a3bc00902e06338d93c8f543a268ffa53834da9163 +251000 00000000000000187d502943a776688b80da0744eb664ce7c5c04eeae1a33f52 34f0f3b4286179d86f78ddd404ef803bc17d95d32fc421e6a20c060c885e06a1 000000000000003656d9ee65c6a650237a06fda6635ec33b93e7d55caf6530ca +251100 000000000000002d1e929a9feab87613338d15745ce695863e6b05bcada418bf f644c73a198f3943c2de92a3d49e3358143eea39a5368b396448d5988cc495ee 000000000000004f42f4d1e67a71ec75bbf040b85bcd01b8997aaa7c578c580e +251200 00000000000000363567a4644278590a77fe509c85b77ef0a55568bf5360c435 e074323dc79aaeebf184834fd1506fd2c854765ba4f5be2b10f3f2a76bacc78b 000000000000004c098efdf8d8aebb5f3f04079f4becf5ac2691a28c58d234d8 +251300 0000000000000051cf74153ec8be615c5b7f70fa58a2f24d69694f8d0bf24a4b 7a43b9111384cf2d26fe961251410277732920619f232db6c4c6aa70c63e3437 00000000000000643dde64b0e1d8ee93d5afcbee0701bd25ef1839d594e9259e +251400 000000000000005f17704f915625e3fbb5b6037793165cc92f8709aae9db94c9 87b5369ff13beb157f396cd6414b7c6267399bfc982250e48127fe6ce67d40c8 000000000000004dc57f725a1646d459c94659fc2eb2186235a44aaca99e574c +251500 000000000000000e8326df54a2053c9c7e5bd77d05fb0fdce14adbae670ca493 2545791e87647dc00c4bd12b5e08a13cfb5d18da7d1a6626aea4ad257d118f53 000000000000003f70a2dc46ab93aed74aea72a54d5d143da16fcf4391e1f014 +251600 0000000000000013cbaef247bc886d65d7720a70bd6014069995c1b6d180657f 3ecb72328430d3e54ff9829c1e698e5842aa022e7f44da6b88370bdd1e087b1d 000000000000000cbb45fa57edd91c61d0c1c3590a9eccef11a6873b9438193a +251700 0000000000000048147b96b5ca45c9e4195d82b68135c80a409f7ce0d18e0f3b 13035d79ef516fab970cf653fa2289e33ceaaab5a2fb3573a4bc393f95906e2e 0000000000000007f616eede683462779b139ba2a0b156059c36e8c45b3e0d58 +251800 000000000000000e8a0fdf291db6957ed869f810b3f40c98c98249896b0156ee 41be64ba2f5a8614d66dc3570dd2a87dc10e1765f5865e717c246a9bef42e566 000000000000005f78df846c3ffb1ba6257d033711f1bf82d3cba54378171464 +251900 0000000000000009b62c31a6bd7213f3b8bc1ab806889894637b76cec56685ca 7561ab39bf831c8b59d03b1e97ae4a64976e7eb1fb7dac1e1b1f42c12fbe4286 000000000000000330f54543eeeb3751976b17620725133f3ec49b11eaabd5ca +252000 00000000000000200e99940b296ded4ce16462bba1950453b29abf313ba7cc47 c36e638013c1bd1b90b5babc5d8fc211f4f6f2f21c0ccadd2a36d7fd79a5d234 000000000000001ce1ddfafb3d2d71c7be37dc51a069f6fd3835ed5d0bd3cc3c +252100 0000000000000017f3f939a22de6877dafcd29fbe430b83f81fb38d78616db90 6bb21a3075b0c2dc92c4a177d44a7388c90a36483f2f5d011787b5d22cf24f8c 0000000000000021b950409227ede965e737942ad44ef81170701abc8c2fb842 +252200 000000000000002aff04919981f8f37604e1a428444217934dfcf66ed6fc9b87 2ca786330df0e68ce1d17aaed7e6e33e1b2db322c7a87e1b8696114bef227423 000000000000004e60a5ff9d6f1f26816a1a20e1c84cea6cd77308c2073af5e0 +252300 000000000000004ad0ca93a213f76db1b6eee6241e8fddccd083d4846af950a7 7e802a807a2a709c4917a7da7ed577d5242318d2070650ab9f8c788c5c78c005 00000000000000279a6268e4832f7af4935959c61f1566c6963ba367bf21f730 +252400 000000000000000a08ab33c658a4d33791257b56eb7d6920cfd84c740567bd1e ec6f193ff1c389c4136a7a7353a40fc50f89378deecb3b937325a35116cf1e5e 00000000000000447f092e2042801a17824f74b3db57dc89d05be065cef5ddca +252500 000000000000005210597e8065e4aba9afe08af63df2864496d3bb51d69d0438 aedc247fbd670a7943948274f40f5a525cd2f8949ccdac296621a93238a6b6dc 000000000000004ab47b23a778089c5ee8cd9fd519fd4c61d7d70af4a12cbfff +252600 000000000000002edf8874b652786209931f5a07bf905f7d23246b609dde0220 69e9547a085083e02a776f20ec332d100377ac85762d2e1eba63b1aa1d01620e 0000000000000008bb27b0327b88ae0396b41260e9f8a786929b4dd5240cba11 +252700 000000000000003d67278de4fbc320ff1c7a98a5f7301468ca36579194cbf982 8765447d9e3c5fd46d2775c9db8680ef5317338440d64cec9fe048bc14a56ae5 0000000000000038ab51edf6202b61309ea828888091f08a47b55269a2e8e4f7 +252800 000000000000002e649b8d0dc8d3ce18d6724165ff53827769f46219e139a940 5a9786ea3ea136bc9f64b8bdfe58cf4cb68b551ae6d279710d8b0fb02ab3b8dd 0000000000000002a27be1ebecb4f5198065a738b62a61f78024a49ba734a06e +252900 000000000000003934fc2b9fe700b875f8ee3b92945089c6f3f163e72688a8fc dbc220d9585b2739f983e0a47b79e6a56bb0ad6e76fa08256cde9fa0199847b9 00000000000000359be96844f338dd0f0149ae6049233572cc1cce7e60a3eb2c +253000 0000000000000036fdfbf3886d1b1a1b08f5abbb5f2ca4ec6b2aff2a218b8c38 90b083862c42817cefda3d446a9378bcca9a40fe9e1b7e1640b6f8128ea7bc61 000000000000001b3d86bb1c7cc08e5a12e6912072b2bd31ec163fbb828f0a93 +253100 0000000000000012869a87d194fe00e98421c3e46ef4cb8a4acf0467a3b418d8 bbd03d3d8e5c993dc37986ee67797afacce551f4cae654755ef3e15f370261a1 0000000000000011417673f989aa97b9606b04431fca1ec81c5d702987d1c606 +253200 000000000000001e773fbcf671689895abdca9430c27925120feaab9c7471e24 7af52418c3aaf4547c30fb8ac900c9fb33dce2c3a464d53ce59d3479116cd724 0000000000000016047e2ac3881a3cde69309e15ad358d52e29fcaeeae2c00c9 +253300 000000000000003f56c9f58946d3fd0fdd50a03ee09a179d0f2454759987475a 09eeb98c94f7e8b83b9d63eb7db97a9d84332d05a3921a515005e916fd762757 000000000000005094c6d6af73935a7cc57f8bc8a71aad2bc78e906851726c56 +253400 00000000000000008ec703208e9c95f79ff65b798789c4b007c3b6aedbfeca68 1330d9e7d7af3cb2737d2c437202573c98aae8012ca8df982e8708ae4e9be96b 000000000000002df3a1f24f860b3ba8520cae82f40bef6ed3b10417776f775c +253500 000000000000001df0e70c0e6ee3a5fd132cbafcbd429191c230ece13f62182e c627fdf1579a9b70509d6096ccd10f602cd8e8977e8068aa808fd4b562fb9cad 0000000000000001607148cb16d4c82c0cf58c388e5b4765c426e8f5f4b184b7 +253600 00000000000000140f99db7a55255d479c252bdd90951e4d71da4dc0718f81dc 4ff8a3cfe3fb9f0aa4828b9e742ea44532a4c3dd82c6b80f76d3911e0f249fd4 000000000000000bb3450bd2245e507e3a534cabcdb2016c09bcad0bba3621f5 +253700 0000000000000005895ab1abc5fba1beb93709b6b6d9b85133febe9debdd1cdb 06df35db9637a173210f52673fecf11eb1fbcbcb4fc3da1c7a97d2689b3bf5db 0000000000000038f405155cb9b500b58a61b5ff87f2a55b5a6795fc9e2c5310 +253800 000000000000005407d514543d703a67516104737c8157ef5720c394e9bc3349 f18e0870bfc4a68cf1b3a7c2bb444ec9ede6ddd0c7dbe74c50dc6f1044d311f5 0000000000000002cd9b4acbb5fed8d5aa9520d699f86f0e789a10e1aea73663 +253900 000000000000003745ba555dae9fe24f2109d504bff505aeadfa482caa74fd4e a47de8a488292e2d51eeff1fbe1c32ab4a19cdbe461cb1b4d9b45c99b96913ea 00000000000000199f0f429bd7f049a8048b5103ea91086f05baf859a155002d +254000 000000000000004753be91559a2c74c6cb8a5d2be6db1df2ca0b2385697e53ff 938326ce0f1be84afb3263d60b338bd31441737611f91f66c1881d96f8bd04d1 00000000000000305aaf9a4a98b6762204fba13dae98142875ff7557a51cb176 +254100 000000000000001f2c25e7c8bae86c349586b15121f0fe56d29deef5eb4bcef7 39ea4f63c21488cabfbd0d866baa6f13d4c5b975f86371abc6f2189ec0b2a222 000000000000002404be939bdef81ede1bc0dbfd26eb92ecd67540c7b7ecce05 +254200 0000000000000019a8b0869cd6ae48cbd6a00a21e8cbaed08781a2db5eed50d1 333b8266db53ec23447e15adaa529a29a891f49bc928e88e5ee02425db86fc70 000000000000002314f9d91de12d8712ccba57ba80c7fc77fe89188d806f00ba +254300 0000000000000008aa752010478056c56efacb7df597b31aef6a960afca384f7 96f9c99018efc1770c327570c1dfc7cc9da9a4ed031b7560344434c1c25c400b 00000000000000346bd0b5f2046736696e8ffe69582ab0269836a49833522151 +254400 00000000000000142ed84dc5f3781db8d7769932fddae21c3297f3f00061a5ae 9e863810b2d8c96776e409a734c49d06660fa1addfec80100db2ddec7c8ef1d6 000000000000003b667dba8ad699192ef950f17c32dcfc99c2cd753646f56636 +254500 000000000000002743fb1383cdd80c26a88a72cf50ead9ab19791afc7b8753c7 e0e6ba757ddf18cf283e002232a74a7e9f1e0e132e87b8b28dea854b8e476a7b 000000000000002d2989a94754806dc20df373f96752a6dc4e6b35d7d953fb43 +254600 0000000000000011f3d4f89ff269d0b3cdcbfed50ecec13a100de9306490f61c 0e5216810de390f2a6bb1bd10a646cda0f563485c057d28bbbb0243f3e5c4f21 000000000000003f02df4613baf52861e30725f381c4b6f391da98568d618d93 +254700 000000000000001bc96da41b78d9e8389e8979fe2b2f5eda832db9c3cd20f126 fed5826f7a99f63b8b9fcf1ba2acf7e519665147efac0bbeaac4185f411e6cff 0000000000000007d34fad315d6507612987f711a6775d4ec25b83beaf72fcaa +254800 0000000000000022a4090dc1691e84286110bb7656322946fa3d810cba11dbf7 f82a866f64ad2e93cdb5298d28e50bf7305037a01f10883783fe374f06b93fe5 0000000000000001204a4c075f3359eb8359aec4ed31c0f175d091e8527d2a09 +254900 000000000000002040853a37640517e93912095a9fa1e7f277398e294ad0bfed 5a9ccd807364c6ce04abb0928c708e930438f7c7f4ea0368c9757de8b1fad38b 000000000000003a11ac8e45f91deb78469b641eee66bbe5ef370fc64a731453 +255000 000000000000002c4fe8e6977739aaa04694ba5383fbcd730d36fd5b9a83afb7 4976f840a80ba92810d3d43071e75efe839251f03e5b02a8d25d178a66da475d 000000000000000cdb6a85e112f47b0fef0c7dfd3d70ebfa590daccd5071b42d +255100 000000000000000a5cb56ac062acd1bae6bc66ef25bb65a6a95180ed320a2fa0 5566163774abac089827fa3e7693e02ee5cf58580ea02babe7936d4fee7fbc9d 0000000000000007e0a539acfe4581f6894af110bca1b4a75ab95b2f00ebfa07 +255200 000000000000003fe0f9f8cc49a8c93b0fb17b4e052fa638b034a040c5f71235 251435e86174c351b16f34470f4a43fb28e1bcc9274b3a73894ac891a7d2f24d 00000000000000007c16ec68be74e6c108980de75b2bf1a581f2012e7bc0382a +255300 000000000000002c6f8729d7dac319f331308c90fd1ab32ba54a7cbc082f756a 18e6b1627f310f56682964601e64db47edb0d074254eed99dd8e764e15d18282 000000000000003a324041eae700844bfb6cf2f163a764730c56c0ade01c2706 +255400 0000000000000029ee2e58fe4c414cc653209c133c4420ff8813f18d69ec66e2 2c114393d550820e8216c85d20a24d6b051e460d42e5f128db9e8e982eaef088 000000000000003957914308ea6a6a6b285ac29d6a24e6b5872b7c5215b92f24 +255500 000000000000002e05037b624caabaf38732cb09f8019b5d637180dc54e3205f 45f5175b17ab74925d4f149ab70a7f7d630d51ad4b1658a2c3ab2efef78f0ecc 000000000000001444038873bb6f51dab3a9035eca5000a4acbbb2eec061b609 +255600 000000000000001a9b0a05d08d9f66200fe4155f2752772ccdc13459ea620ab9 4b6a34eae8d429decea6f676e33379f219d178ccad22ca7156509e688d5f249a 000000000000003c49d411eb1a48bb739a422606711b97c7a7a12a73f1c8daf6 +255700 0000000000000033efbb695d8daf36356a4400c46f9d24d417208e2ad2c39c95 09d40aa56ebf2703936ca2f3749aafe85571adeaa48106c2edeba7c5557b39fd 000000000000003803e636efc083471ff7ec28c691f05dc359fa94613fc7b0e8 +255800 0000000000000020cbcc7554e38315e6b2bfd5f2f2a73bdc3d460451438854a0 3fba92a072b85e6e13b1812290196c74929131459a80cfc58b4cf9000d994d3c 000000000000002b5f8064683eec4643c31206ccea90ce761252a35e6086c230 +255900 00000000000000369a43ab431f6b5c05695ab79efe40d8df8e8c43c30caada8f c22ff706fb14aff9dff87c368861a39abdcb04a1ff8794488babaa2ca852a1e8 00000000000000175c48c6531cef5cabe9509f28a03e9c54608094854cd8a8ae +256000 00000000000000252b217c0ce5c4d96b825b90dacbe8e4dcf5f6a8ba6749f3c2 101fc746a9121f7c1039d1f949aa39bcb6676eccbdc5702bc93fec66092b5b23 000000000000002ab7b60009c3d6a4bfad05ad27e27fb0aea72fb9a3bd3ab9d2 +256100 000000000000001b34758fb7955da4fbbb2e4eac9e7ea4255a7bc7a6a6423987 448575fb7af161f3095d302c32a0e7c68629137bc8f3fe9ce0b543bc835ff07b 000000000000001d8aa1baa4fd121a61ba7145f6690e1958ad34452e0e0360a3 +256200 00000000000000032827a1b515a31d40f49998db3aa450456a4d8a843c59d8da 9420c5f59cfadd4e74ea0ac6fda4eebc6bcf50c2cff929c5b79e1f58f55a771f 000000000000000e223e2dcd8dee9655f1fe6f5a133077ebfe4834c61c113e8c +256300 000000000000001b0326c319e92c6b9da767ef4afd124363307a6da3d902fa0a 2aa0a90ba36036a6e58098ebf47635a379d0d4f8ba9796fe5201970d86bae6c0 00000000000000119a3ce9b6ba7951f3d377b3218bb1be68e48434b5f8a5a9d5 +256400 0000000000000027d9d3d793707da3fd684af4c0e595c1a981c7671b06dfcd45 1fd667e4a582b3f67a1eebbe30785276e16e19fbac7a62f1770f22f7bbdcd2fd 00000000000000166163372cd3058ef59a3f2e9fce51d0d2995f5b38cddcfb82 +256500 00000000000000079629c8da630eb5c5c7cdf243f4ae1296f4b67ac952d4b9d8 f54554923b0ea778cc96ba4d2c72aa433d3d789f9065259e3d80e4318e4b113d 0000000000000005a90dd534b15a0a175d151bc388d0f1f3f530c1842a6b6021 +256600 000000000000000772fcd2ea8400307edba9061abfa8e9833e0337b00186c1ba b27fc9b1b176bf5795d63cc7209d03b768f1953b68c918d1911a1b7e16331ecb 000000000000000c0087f78b39500a5b420751ff1398ec33e664768ce6d2bb3b +256700 000000000000001191ac5247f603da619a2dd8302d59c91c5a4ceb3d30b6843c de7cce0b1870fcf58d9a4ddeb192ea3ee0c93eec7b4e81108dfab05da77779ec 00000000000000287f723d6add20753a007c10440bb4323159f34961da0f7c40 +256800 000000000000000a4d7e1976840b58fd4c7ef857d21ea355e8af3b84a61e56aa e89003fe9f5376e2898136489d9967ceffa849c424c828464c335f43825f20ce 0000000000000006f72fd6d7f2e75293d07a587fbfa6b45bb8c431dfc83ab800 +256900 000000000000000885535a9127619ea5fe2c93471fa965600a9ec7dc57e357df fad2d58de94b1e9bc1b250850f1a9dee69ebf3b2768ef8aa8bdd47f2cbf690d8 0000000000000020c8fb26a2ce0df61b30759763b05ab240583d31aa50d41923 +257000 0000000000000009e6e35821509617f787a8c154a67b1f2f2f8f5ad8e85f65b0 b4c8d9a3ac3b5fef43763aade2253857e0d8bb0f8c209eb0172cbfc88b01e3e7 000000000000001f63128296d97334405cb5eafc4f5c86080000828cc47dde6a +257100 0000000000000007602833ce938a814ecb998c229a0d7bdfab11bebe0a494086 bcd96a12a909c7c496af266e33d147f326e7f4261be864d7bee51c6ebe6b4630 00000000000000057b394fb7abb55ff7b3ef1e61f134516c490e622d26f4a5fe +257200 00000000000000035a74942a302d07f322ea7ae0991dda217562c9f757230b32 514b56f5cad3196b7e2264624f5f365d6953f0cffc43dddbb238b09af13762fb 000000000000002406263539d505fbd23d8bfaa02efcb0fa9cf0e62ddab35d64 +257300 0000000000000004fc4db38cbbb5157b5872a1d364e01242a6518e4c3d43041d 3429defc121c895fc6984cbe5441a3f5b5b192c833728a5626b7ff16f8101904 000000000000002da8fe96537e4de2b05427317f6ef3d04772d82793929cc1cc +257400 00000000000000068b71e9c39973d9ac2b0e07f4f41b7d505bf0d783e132e39b 5d93cec9790e4614d5d18e04327f237c801037164257327ba8e543f6dd296366 000000000000001a0d781c58be599abdf74b1b164b66658fbf085101b5fbe8d1 +257500 000000000000000e433cb15319913760d427153bbeb15bb99b169ace48389ece ad78ce68c5d6d4a92a7bc8627ae1a173547165a2abd27067d480d656e30232d2 0000000000000001108d121eec0c1f35f43b877afe224b4d3456dc69e11dd3d4 +257600 000000000000001a0026fe74c794c42cab01b0cbc8727b79e84e3130ed9c4ad9 ba6ba5c9f087bbf2a9074837d0fb3c2c1a0db333152d31744acc7da6fba44198 000000000000001d92863625fe49d77492d66f7a5c1d132c2bfcc366d6ac67d8 +257700 000000000000001cd4031e153281c922faab51f17a3ded9426f82887fae93f3a aa629073cb1ce0bbb1be3c4f15708c9d73959894b4d25b6ab2ca1ca1aa88158c 0000000000000023b62398e23d4d704b1451c0117474b36108b98017df37b502 +257800 000000000000001f063ad177ed280a015146dfc4ca1628ee754814bd9b67eefb c1bb7da62baa0dfb5be11978f25fac92d3965ed86b025ae764943e0d053ff2c1 0000000000000010722bca59d384bf67db79436918cad11b5b8be13139671a09 +257900 00000000000000248bf8b480198db101a397a095fe6fd691a1b52e167ce4422d 765ef46144570179836a84a996e152591b26f840204b95ba30ab8bf20f4d54e9 00000000000000283399b50d0958a8f349a621c0e6cd80af8e874a516526e5d6 +258000 00000000000000159f682a983465761f471dd24300746efe8db5642411f1b631 2dfd4d4e1f2da1cb15d6eb1ad6d3acbb2ddb3e1d037e07d797edaa16434b9c67 000000000000001b86532884bb74b3d170f05aa29367aebff48e139d561e2c35 +258100 0000000000000025a24e33cbd65a64c04f162c0e5bfb2575a628bded28e3aa2d ce0e995544b06ae05cbf95cbcdea4884674e45cd94cef79cd555c729e1af0ede 000000000000000f20b60277dc9e3cc2aab16d5b27b5ecb930aceec0ca5b2f36 +258200 0000000000000021ee1c1231c6cf927595a3b04f24bc86e22a6764f016240118 1770454659c5fe29029f0e021c9e927c078ead56b4cb80199d31d68a01daa30b 000000000000001438440e498a7702fa0e2965c3995801ec6489a3f7083452da +258300 000000000000001876d8c4d7e032b4ab5be3512d82ca1d13f933c34fb1706901 159e4e137f4e57a8e7d2fda3e172cd033017e9a8ea614d2ed0e8793a4a18f039 0000000000000009185ec79bd2871a19f3c238d8ed325ed8d4a560176ba9536f +258400 000000000000000f942c5b1c153216adc963202e783fa5f3a4171680ac8505d9 d22992aa0ddc8563fbff6ca1ee3dc4747ed9e4e1aa5bd1a2c4c7436c2881ed2e 00000000000000118a9951dceffeeeab790cab5fb066bbf319117e9382271318 +258500 000000000000000895d2eb920c51a46859295dd7d7be96c8e619c0e15ec6dc48 ba6eac8f6b08e1543e72002b10cbf9bd84e967da2b506c8b47d29efac1335c8c 0000000000000014fe66d33068f6e5bc19107886a73a99bd80684a6f1d81ecf6 +258600 0000000000000023d59e048277c9338c0497f30320fc38c3e43cea5850a89914 b804e5a6d11cb80ca7fab305ddfc7166084c7077339c85536baf56640bb69373 000000000000000a062f671e97641ec78a506416fde89ee0436982a98825d670 +258700 0000000000000006d597ebed323b04840ab001d9167ecab6e67cf1e080943acf 4e90f6d183f7b32c3a1fab71ff5b419ddec4d763e6e5e07d4b76d9705ed4a252 000000000000001fa83e973a059d65cdf77ad2fa511b16136cff630b627f9b0c +258800 000000000000000e8c226aae1af1cf0e8dc15a7d3f169c44cd1bcff3b68f3fcd ef5cc8cdef69526d01ce784a52ce718d82eeabcf7271833d45eeaaac09239984 000000000000001aef1c642c2246fab5a858d5c1353756662171cd4983873030 +258900 0000000000000013d9bd1ca522aa1ab5ec4db22d682d76d00d0f545d7c55527f 36f577f651c2f0f40cfdae14a8e4d7f1b3d85a4c95b4144c97caba3b5e37121b 0000000000000001448dfc9dc6eabf3be63a0622a85e9131f99f39ea359c9b73 +259000 00000000000000169684a5a1760023e1c7481373f3488c3c21793ed4fb3b6682 8021bf80a816b825db0cee5e2820b5e100b11a576c1b590e29492de4f496587f 000000000000001dbaadb858f4f69c326c2ccb7fb6e570914d2744bce424a52a +259100 0000000000000012029f15693dbf5f7595fd8a426a59b9d93906ac2281e15480 ac892e9565ad34ffba19f65726d61d6a70cad9f1136e7cd698413e5b5123c19f 00000000000000226f639d1b9ec2fc11fb224140dc88a4b416e6fd2f3c878ccd +259200 000000000000001a87a1b4e6e55f7e3225e6a98ff33d3543a8733ee8f0ff9145 85f2710c6d00ef868ae86088fe4242565d82d904cb761e08ea3a52b2bd2264c0 000000000000002219b531db81229c078010c5fb80970fc8b0729bf97c7f6901 +259300 000000000000001ec629c44f38dbb94e3092588fc727b8c39d4742e2caa4966a 1b01613706a885ae0313a62241c9eda5b65aa8eb00a51e519f57fe1a019be18a 000000000000001c388275514031c82570ba07a59e981a465c3ad713906dba1d +259400 0000000000000004ba6c7c70093aa5920390e7f355c47da509e89fa1c74d2a2f e07d866ae74ae3eda43821fcf445f40fc4d121e9e08fd93dfd080eb64adb6841 00000000000000022576d2bebd98b79df389e437a4feb316165176fb3f6ae3d3 +259500 0000000000000025d039e50dcaaff30dcb6c1c566ae41a26a5bae1b4f7591bbb 1c5a1122cba9405455cfa2f79edb2635fd2cdc341cdd85fe7a2a1663c192753e 0000000000000019d73629c4ec5bc9faebd6cf611dd50c43817d8e7c6f304ece +259600 000000000000000fd694c194b473a704c6c1c2586ba67a165e9f6257814b7987 de8d0caaa9f61210aff4f744f96e0a96cf737ec747d170ad960b37281cc14a3d 000000000000001106d3e90a3bf222ecb2d93364f846428687f98fc41bcaa872 +259700 0000000000000003e9cc3a17f18b95f32ab581164ab68c7772428c11f4aff4e8 dd95337521e217d55ea52358abb7baacbeab94f98a778236e94bb321c55e79d7 000000000000001a6a8ce718d54c3aa9b737ad73283caa5960ed32aad00d1f20 +259800 000000000000001184992d10d089623af93e08ce9d7c0478e7b1045a8ec7ba7a 6902768d3e986b3c7fc3336eeb3ee43f6cf34e193bd5654ac45afe9a0b288ae0 000000000000001476861d564af4f957888b77e016e270f634bd1de682a87177 +259900 0000000000000003d65bd7d7bd495097242f26c8b51cc1eae0b7d74bc8722b78 8cc68865a66feabdfe5e14d888f2b00dbead5a106e7959178b6b71047ba5d2ce 000000000000000a228dbdb3ed7ed17aac19f1475e62dd014f77d441d683d1dc +260000 000000000000001fb91fbcebaaba0e2d926f04908d798a8b598c3bd962951080 e2b64c35262d2db92221b84db411bb2230ea821c3b514338f718ded10db88632 0000000000000006bda8a9646243754929a49cbe92a1312ad9623468cf99b9f3 +260100 000000000000001aca38a0240d45e52f00fdd9fe67ce83f47c5435f87dcdd7a7 a22f74a7747626b14f832a8bc4748c985615a1278ce318fa02884c572d979d21 000000000000001a684d5809d6ae0106ddb7cd48071aa72d1c5a0f4562693540 +260200 00000000000000165a5c277a2b21af523c8b610e94769ad088949ba479c313b3 6d3e08066e07a292b507a45b0098c451bc0752e8c50741395a6828bcd3a0fad9 0000000000000001445597e0770973acedc063c2ce401cbd08eddf6b945cc580 +260300 000000000000001147d2d9bb011c0464e3a5d7a3dcbeb037105d0d6970f2788b b7bf555b98ff3b5e66ee516dc2198222d4a201fb766014f749df0894340ce492 00000000000000134cdafcec53855526f65e80254721498504f74e0ea34f0486 +260400 000000000000001b0c774b5173ca9bbef60b809768db89cc2574742ebfe7cb3c 9160c60d0f49950af853ea71f06267f40f76d1b06b053dc5d91931837b6f2b30 0000000000000003ccb10c778c01189b7dac5816fe2f448b3b58187b298cfff3 +260500 000000000000000783586596920c351f3fef30dc8793c0e33f99ed23c1014d74 ab18d2c3b39c938c6d0a223053bd5164a615fdda69210c354719b1d69be449d6 0000000000000006c12c03b7b5d3e6dda75b60d092d06151e07338355df64e48 +260600 000000000000001b28d9d794c965e75c0f0cdb4f842e6d7726f5b27644ce0fbd 598998ab85a9b85b8f1de7a6aa48230290dbd583a886fed2207a848c06f43a2c 0000000000000000d55563f0a115c6295f2f7678ddb9322f3edbd71d4b4638a0 +260700 000000000000000343dd31f25a182e14a4b13c15c6c005d24ff3f03a61590794 766cbf778c0b16620fabadb3ae5252d1fc1eb86beb22d2c6ea622423f90f2ed2 0000000000000012f5f1b7f2a75c0949ffb13bbd3dc74c9cb864c46b71d8c4d4 +260800 000000000000001495f806b8735dd8970dbfaa41464e9f28d710f36ef7adccdd 8a0c13882732eef8a6a9c2115197291a598328b2b1513f1709c0c89088404aaa 00000000000000057df55508ed884df487f546fd113862c2dcdcc2435cce6be5 +260900 00000000000000145da4b28a32785d6a3fcdfe748e0b1df613109c7c40f24ef8 702cb981efe014fa5f0c85b39bf1d01aedbc5b53353053ea3f2e62257e10a54b 0000000000000004d770278dfea0e39b58267b6c6df57c328c98a538c5a1ff42 +261000 0000000000000004752a2cd32b73e7aa15d5e975eaa3d1cad6ae5dbf43080beb baf549b435af92e7afb1dd0fb75cf6f4c64968e8513360f2270ee2a4d3e21df9 0000000000000005513af2463d56c5c0b8d823eb5bd1da06dea8cb8891a4be0e +261100 00000000000000198b3001f927fe3b565a213c15408a18ebeaf025ee03c98d6c 4b5a48afe3d49f5c42e97372b410fc44cf7c273f52bb5cace1ce49281c49e15d 000000000000000971aa10d51396948d4c42e01a545e5693091f28f9e33da391 +261200 000000000000000821d96909105b0e38b787f1cdfc96b0ad74dc8ed72f77bf90 97ca0862ebcbff5c24533a356d2e23715955d57d2916b0b614ebce161e1297e6 00000000000000114018bf11c502c09057e3ed5e4b8e442bf92f71fa050248cb +261300 000000000000000b4992ba90cc116960932ab9d77ea9b6a7f36010475dabf4f0 b6ca2534c146b4582f02a14ca6b0e88ce317e68e24a07fbf22af0d97ab5832db 0000000000000016d0deaa3689f7591a0aae585893a4272c63dae5f40382b4e6 +261400 000000000000000039926d207c49a390264fe3a1014755cc94812e171e216c98 92c5d3927500ba70f39a032ae780cb048dfac25cc61f8c20b2a09cd01ffeb120 0000000000000016a741ba371cd574fc46c1433af53876ca473e13bd346a9c83 +261500 000000000000001681c5a82b0a0f6a8d74cb92a9a6b13b0bb7812a237c123907 4b127df4804192cc2810cbbeab5860008e3a507f0983d81e7b7e2617bce10612 00000000000000176c3e5d3284a9ad63a7284a54311c65eefe2275b0d81dfdbc +261600 000000000000000b153e03a272bef7759040f6d29addfaea964d950b29f0e8de b44e062265588911e3b49dbc6aecb689c34bc642db6b5c04d587afbf96a9bc06 000000000000001447492e740aeb2f3e1df3f9cb2934f3febd2e4d35188896fa +261700 0000000000000004a293f029f2ec05ad90fed7c68f34c8118c9ab2bd98302390 664a63204d8e6c8eb3d58078eca9ad23b4292368391f0c2c11ebc9571eb293bf 0000000000000013626cfc0c669271d6d5744722a8a9e99ce5ac692a897b732d +261800 000000000000000c815e1099554a7d4790664dbbbafa563b520a27b77d2e0096 56e695df572cd89153c8b61b2794c46e05d5ba86d703deb1b14a0f2cdbee273c 00000000000000010d4e4ef596c91ba10189e70abe93f6c47d06e85150804b01 +261900 00000000000000181fb20bed6eec89cc85d902e47a1efb0e4053df1ec5a16ff8 9f763fdd171e6a231e31b871973e25dfb036c219220537d00c34564b8ef452af 000000000000001a7d8c76f42ca3ee7969e485e242ef8973bf1dee41d94e3230 +262000 000000000000001002ac67e026c523c3779b1ff2e3b9e2b7bfa6022ee1afae2a 520c9a67b8a62f099c1b3d49f5b5ad244a7d9cc3d07529314f2a3a8efd8f66e8 00000000000000153388f79e68c8a5b974c6b73d0666ed6d75461af43c75aa81 +262100 0000000000000015b990829e7ea46a903f30fa66923d31c3216bd69e906f526b 7b9c85cf4f0f23d9b0aa95be6b5510025390fbe9c558c65958c32c3bc14f9dff 00000000000000065b35cdfac40e1a11f22fe510ea628c9c732da7987c1f8a32 +262200 000000000000000429b41758ac07b2fc97fb0c7847dadf56573f9fbda5b84312 fbf625daa0934dbb7589a322e3f9d81ed54170800443045bb2edf87e74d62be1 00000000000000116fcfdcc900ca8d80ac4eee361fa72bc6d7b869f705b0e108 +262300 0000000000000014975f1c69c35aef692db1fee6639803fbecb5a7a270dd050d dbb3023edfc123ecaeb438a2eef497a05dc4969f936667e9fc4f93782c934a80 000000000000001390187a91fcdbfaf443003889c112ad5cdd2feb31f6ca02c5 +262400 00000000000000061e846f9adaa79f14f99a5168fb54ef514f1c7305cc9cc92f 8f9f6a39511c6f2fed41ce1dc8e10a2c95cef5684f77bec76eedeed427d1282c 0000000000000008863b7d608dc611ac5c6c40e6e9c1aeadf607da380334e7bf +262500 000000000000000873ae6f84e06c066e127c536dc124a5725464171ac48c5169 2714ca085ebc6e0aca16b4159dc8768067c1a184d16ecda4e8eab14d1f3d2bb8 00000000000000025314cb0738d0604107ae4baf9a90e02f84ee84e3c7948719 +262600 000000000000000adc23b77205c425c1e668f1d763bca8a8f02c22efd8542f75 09df263c984af5d7ee0916c3a7d00bb99be02ca4441e288149a0f02e89c6fc58 000000000000000f20a22c7111689f9683ea2c02ce87b5ad3d6374a783e52415 +262700 000000000000000b413bfa5eadbc905fb1f6bbdf2739f309042b6680419c1e10 d00a89a618d8e79a4bc61705e0a06fc3512dcd45e2a60bf10a5194afa61680d2 00000000000000070e5ecef15732abe3fa83df03b3449b3e6ed81b3f0e384c21 +262800 00000000000000073fdf2123800e5c1614ff8fe8f3137230153d2c1c947cbb9c 5b3c9761b9446f3f012136eea1d81947e9648ffc9494c546062c9921411436e3 00000000000000166df614e384ddb40ae8dc3eb2c19c7dd3be6258e76aa49dea +262900 000000000000000cf4cc7ce14f818dd6eb7a7cb144528ee144cfa2e4a3a145fa fafe063bb63c5227cd6ba299db930f016c2c1120b4eb314f6c659e66c06b8b53 00000000000000167de1b731abad4eab1869e6fbde68479b26773c20cc5640a7 +263000 000000000000000aa569b284565f2d48d8bb99705baa06c7fea6a1bbe8dd1165 a7dd4577f2f6a54b5c22d0efed1ad42c830799c099311a7010550ae4b25b58da 000000000000000330196833a32e310593e566a33554f9159539fb48e33da0fa +263100 0000000000000011d4967ded0a0705e20d4e676b0a07f66f5b4bd6ff3779510b 10e2699e406cbe7aa7c22f771f168ead6bc89fc0b38e105f8780155daddbfc13 0000000000000009bd369ca7e9ff2d197f8f188ba8b4f0062741743e56bf14bb +263200 00000000000000114c855b36adff8675967fde9e4e37bf812ddb0bde1c35fa38 0f3254a413378934654d56cc1cd33e0cdaad60dcf3e0bd11be4fd68e2cbbb1dd 00000000000000013a9ccc3de71f6d4224100c3d1aa70405c638de98f00d972d +263300 0000000000000011138f56b4896eb528ff7551be3a507205a74c3f9a49022b02 869ce80d4ddc291ed6aca29249b04334b32b014d77e9c43e4740ec7bdac5bcfc 000000000000001557da1098314ee1caec3d7f60aed0213ee01efd1305300f9a +263400 00000000000000073f73f16cd017101fc1ee81f3ff6adfa24afba669243bf77b d00728f9c32b2ae8357ee674606418ba22f20756f05a35a48978e466e756334d 0000000000000013be453bc5a39dc7ef2c6af4d5ccb210412ddecd0ad35d4558 +263500 0000000000000008428e1bac61d5d50273f0d8c9382713e1d0d304cc0208e6b7 670b35d7025b8935335a4cb403d73fa9819d7a980c1fbf065f6a322c5bea1abb 0000000000000009a520e5c6c1bb6b71ad5ae9021a8b3e62e9cc6d3b7e19fd81 +263600 00000000000000034eff6e5c432d958ee8130cffd20d65ba7613170ffa0fbc5e 4fa3baf078c79df50abe8c517eaf549c556cdfa487f5a9168e5dcbfed664bb46 0000000000000011e14679336a7e47befe38a520f16d466e12d3f494c25ab00b +263700 0000000000000002e13dfcc9150e3a72df6040aafc19bc0ed98da3622dccca60 fe1cbaa80e26c2b48990343fc905d6b944252d37ddb96590d4baacc67f162174 000000000000000587e0cdbc7fda5b7be96894ae85166b23cec3a7934fe0a58c +263800 0000000000000009f5c004cbe7807ed4f5a77d73ca37fa82a90d3e73b8215975 c2dd9a73011d42e4a13a54d6b5ada344b5f9545c6bc14aa397e668783b845120 000000000000000c22096af452417c02145b091de82803fffac614d43bb17e3c +263900 000000000000000cf2c364ad8cd0012088eefc6ea7d5143f21d72b58e96f79dc 1e295f4087acffed86f8ad62eed7f41a5bdec6d9de58cf3223c822ccfc10f127 000000000000000e85867daaa304465ef0cb1ddb1074d2d962e5fbe3bfea7bb7 +264000 000000000000000d05c31485c532503939ca0b88d7e322dff79900ee6cdd5ed4 e337d1c22fbe130173961aa707406e3c94823ea80f2de8ec496e614dc95e7d3f 0000000000000007f58dd8567278c80bb9f964c293f02589e83dfceb8775fa60 +264100 000000000000000feac02c3025f2164e1ffd3eb014ca2cd636509da79512883f d49e4b2992d2cfb15aa962c7e294191a8192be4ebef07c5c3e70c9354fe56ce0 00000000000000081d277f7eafdbeaa2b254c7fd2f49676eecfdb413b95ecc5e +264200 0000000000000006e00f954c0e30a40e214528e4771cb1fa8180801ad56faf93 dd3e24243cd6ef1be34fb884d1dc6ae9de207ff3cec8a77ce32f8cf15c9c5631 00000000000000070d2d6d340c3099a1bb74b5c85d6536e2592db3c4cfcd2af0 +264300 000000000000000002f171ba88a159a6993d1c59c18337dd557ffb168e19987c 5f1db502fd3a05b3d4dd5385ea0cda277144258ddb25f88620d1266ceaeba708 000000000000000cee6c1ad3ddb30fc0f2ccd2f055f0a77ccacaed14af13b96c +264400 000000000000000c15cd5083f8f29234cc6c3d8f0eff5e9dd2fa454bab3c813f 74db4758ae17e589406ba4864df995f15855c98ac40f8d1512c5f745f14fdbd0 000000000000000926e976ffa4911ff3ab7f993effc420d54d80b6c4cad922c1 +264500 00000000000000052e1a96ad2948dcd4722fa5742f7aae08d65dd896726f67f2 2db67226c42b744ee5bae2189bb088a05e7dcf6e97fe70fcff45e1d9b3f829f0 000000000000000e5f6fe056452f03436b50318c36e2896801d64521f03dc549 +264600 00000000000000001fdf8ae68c66b01ce3cb66c3214e463360269806a1699da7 509c6c52bcf4debfb6986af5c91137ea6cd4488cf351294724ab971bb704b318 0000000000000008ec7bf31c650d8a9935286aa6679892bebaba6cc7adc85ee5 +264700 00000000000000037f7bc1817d53fdb62dae08fb9bbff40fbce136462c729570 b6a72c62b8fff89265f9877c4b0d42d5ad1e3eaf725b770dd991ca08f8a52be8 00000000000000092bb6528984530600ffd52eb75477d0ec37322ced8587db68 +264800 000000000000000f82fbd3e02b19e5db9f8b9e9603753d9745e248dfe520fa63 0feaf9b0d310fd7066c76b53bdd5ded148f375a160f3f35bb63fe26bee30bf87 000000000000000e49da9a5e245b8b5a83ff797ef92a38e82cf912969375ab36 +264900 000000000000000649c089f9e83b66d2e46f9a7e7ba2fe61ee9d4699a5890ad6 cdd2be327a4bc169130bdb64415652202be12e1cac20127c8dc0904d9f891ac3 000000000000000d1a44f9de3cadb53e39cfc54edf8d6a23aa3a6a5ec969273c +265000 0000000000000000a34b172ea52ed3c4910f5356c0e0724c48b585135794470b 3954cfdcb81cb9b45d0fdba692e82c4ccf1b029230e9d1ead12a74b9d8791c9c 000000000000000a21ebbf8c7927a4a8ae614f136064a0e1a9bf34340191866e +265100 000000000000000dddbcccf0616d8f4dafe4042567bc3715a05187241d4bb8c4 34e26b3750ec6d2f10a1ce8461163ebd23558b72e67a9065fcc24ac9653f69d9 0000000000000005fdfb81f69caf9fe25f75a0b936ef0e3aca3c04d22fb51ca3 +265200 0000000000000006d9513ff28fd5d79d9d4d07fd47200ee6e1bb8c6f62c93219 964c82504258ab4d0d77398e66032449908c1cfa4dbbf7c9900c025890ec68a5 000000000000000c28e4ec7fde7391621907556f3f4214b9506d8bf82d074186 +265300 000000000000000f3f5e9a640aa7b0dc597b750dd212211dec436a5c754636a3 1102d874dab2e327028cb9d6aac7723decc6437b9e36a0445dcf5c21480922b4 000000000000000a65c905db47da0da3521c8a222d81d7d60953569fe328ab49 +265400 000000000000000eadd47fc2cb84a7f9ad966ad3097c4a7fbe52149a6e1c1f9f c9ed8013f1b90204984600ab4f56f6884fcf17e64b2253bc7a9a8c3d3ea425ff 000000000000000b4c122595ee01dbaef1b4675cdbef1b74c11cda0c97de5c4b +265500 000000000000000be5473562d0da2f4272bab0ce3ede36e1a10f9b7556b3a652 9e85a4379c34e4be58978f45f892072b542dfa52c7d2c68db7468bad7acd8571 00000000000000032f43aa448c23bacc7cce5f1534cc33bc41141df8d34ef70a +265600 000000000000000c02b3283ff1f55a1628051c66982151e3563fc55111c512e8 fd8dcee083be1e73e52f7cdc914327ebb5669dfddfc52008b746dbd16f1c21af 00000000000000025f78ff66dfdc684aefa79c2d324dc9927ed4acd97995173b +265700 000000000000000ccc03f4916d8ca5f5b0c5b5b5f7a0ff43d7617949bb4ee9ca 274c944799c3b732fbb0494dd0412bebe3133ec4cb9cf82c777c8fab9434bb1f 000000000000000d315808d4c2b9a3962fbf177a106443738439fff5432ab326 +265800 000000000000000a7d29b9a32977ca9b9788faa03b87e872f7a1f4d9583e47d2 c6729dd4e50ac7ee1c9d8b53f64ba5a841413a9737b48c624b6829a2d22214ac 000000000000000eeb9528c57a40500271f93aa3629c52e55e82ea395a8ee8e2 +265900 000000000000000ac7a97b0d072b106b7334aec2aae5263d070989df5ba34344 355927da896d5890c046f835161a8a0657cf998e81b310daf527311d0c603bf9 00000000000000033ed52dacc12000eafbeef759f9b165cb01ff764b8454c8b6 +266000 0000000000000009d755c65d58c7c1fde9167ba632a85574de3bb11c8a862e35 c7bd2a5c738055fdb69cd3ba7c116d4d9f3a60ec2fa86ad2fe5808a96e33cd00 000000000000000c29b5b02f59257025f48808779bca45a0f1414344fcf59807 +266100 0000000000000006b3de08ac7649d0ea71ebc831c6e8bfa15b847a0ffdd2ae06 c70ef96ab0de33f3e0842501919e7d29053f469996f8c6bb3bf725351f662b9b 000000000000000e3e203bf0538b1883c7424a970a3a4e0674737239dfb635b8 +266200 000000000000000654c8bacf0660c0ceab00cb4c86f65825086777af218a1896 473e3bbc3daa42b60908dfcf2e686ab4b9ca79b2c7110651970598516d76343b 00000000000000098ea71c63e56805c7c63ae540f9f593513921be33a61745ec +266300 00000000000000065d1e171c3a3a1815a5dfbf25fe9c60feebb6bd478f4ec702 c2fb3cc4928552e7bcb2dead63079ae1bc5b3ec076e833c9c47b759cac308a01 000000000000000675d95bd9391ba13332a3cc42674f28c78329fb2cbe37717a +266400 0000000000000008fae34fd47ad1df9b3ee6d861e67887c14cb8dde595c62c22 67fb18272e6ace91b80f8a059437691f45f5068a16f1659eee8ca1e2cb7c2cfe 00000000000000020b96f9ab4316efbb4ac6b9a0c71de4b573a449a8bb42845e +266500 0000000000000009c82914ce7c77faa0e11916d9b687fe0c752f37bfbfdec609 2837be4c425ac8b748009b577f5859854137ebb13ba947c50130b1890a36059b 0000000000000009e0938c9c20e4b2b19842f949228722453b8de6950825b386 +266600 0000000000000009a50926476103cae03510b35d2b431d2ba066e9310dc44b44 6d7da520cfc541390cb3b31161f46d93567bac61d8e262218782f0bc257d3fe7 00000000000000031bbe5f28f8c49f8a4dfbff44c0cf7cf0902537ed553326ae +266700 0000000000000004681548ffeaf5e0104d2ca193e580595fb5c84b30212985b5 868d21d11beedfed650bd572b600b33e6a1b832f4d510777723511992a117fed 000000000000000a253c48eaea29ae445ad8e67f0b41e488fd033fe7b41beafc +266800 000000000000000a2e3ea1236979ad90be7aba2d8e68cfe809c91216646fc547 4792bd72b2657565ced275249d240acb17969b40438fbf6fb2bd3c13c99eda07 0000000000000004b37334f0b93d8fd6f74c7324b65c8a1803891505b5a99b48 +266900 0000000000000008a931238dcef22a0fd4e8b4c2daf7b4bf8f7bbe4f452c6f4b 9579f76069627799e9c715641d13eec18de6a46951841b201a914e9f7f6ddb3a 00000000000000017774f7c6b62661bb2b693df8ddd7e011131118a524cd6dff +267000 0000000000000008e015f27b7bb1c624ccf3adab262878246dacd6de5050148d 5d7cdef78d1175e01a836882107e9913c420ee6628ace76028c2da28f383fd9b 00000000000000071e49cebfb22d82ba7bf543172289be28416fa449ead053d9 +267100 000000000000000a8afe3b83be84227d110a2cc11f316170ae8c4104974cedfb 79189c4bbb647cc46c7f21e30f7f6f89bd4fbf28439e77a78ae0e60dc6c68b9f 000000000000000563fb24a9667cd58ea007fa5b113007279f679d98f157d167 +267200 0000000000000006ed2fcd576bfbcfb7f295750d85ced86c680b3881964453f0 c850cb0003d9453a4e671708ab2d9fdec22cd282c5ee0632d8f3078a1ff9bc56 0000000000000004c678db93f0d8b4e95ef9b90359b01ea1a69d0375c9acd72f +267300 000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac ae5cf48bc40f48a13283edff3aec739852385ef7fad14344bc822cc380ee36ba 00000000000000009b23ad20a246f2352bd0e3bcbc5c36fd8abcd12ece370aa6 +267400 0000000000000005d45dc418099a994585bcb621a546b14794ac7cda8c9f30aa b92e5b54b613d7a9c4c45f8d26b1a304ed1ca53cca21603c3007d11f923e1296 0000000000000005c537eb783ac95d9494f655ad45b5e40bb2a6b7628a514662 +267500 0000000000000006b56599e7f473e7d1fd5e63452bb8755bf26562131b91226b 11d5faaac268d04ebb0795436732f97002b9b52361c25071707cab2be590faca 00000000000000049054b918bbb70855c9574a81dc17c316b26328ea49aebb5b +267600 00000000000000042b8fd40a4969193944a0dbb63f8f3e64b46eaf085656b604 3aefb4ec0dec74243391d4b047fc3fe509fc58c8a189d6abd88d8567263b7ea7 0000000000000002c93c3056b06ad13380ecc4a1636f34ff1d501cef8c3e33e1 +267700 0000000000000006ce5a7d708b8343ddcf243250a002851c9b73e7db91460fe3 65ddf07c042f0a4aa5a701b658ebfadfabd308e47c31b92fd58659d210a32499 000000000000000256be2a057efc9431d0e7d009fb6dd0e15d20d769e2196e44 +267800 00000000000000047179712179b50dea5e6fb35c6ee6e071aa18b5b2c181529f 1e2cd555ad64c347a2a623a35e165fe5968f26708f1bf6669d2412b1c0cdeeaf 00000000000000011900f0d9814b2a0c31ae218af17fbb8f79dbec17ddc1ce55 +267900 0000000000000005562bc209bf1d3775dda485e11312e92d864e31153b720d1a 2b0fc94f597db8b8dda4effebe1e72607238ef168a6455c94e5279e2f5e02d8f 0000000000000001293674987449428c3dc19ff4ca6b39a85d2854511d8eab7e +268000 000000000000000048974ba0669938f7f8463650cd5c48c027aafd88c00a46af a768434a7313d4d72ee0267bf24fb073c4fdf624092d2c43bcf809eb84f48867 0000000000000001134627e5ac79f7fce271a5fdca76d5470758247ed65020f3 +268100 000000000000000a6b380a29e3570fc08f4d9001fc203c4355beab1f9037c02b b20b71dc9ac51d0f487ce99d2b95bd137677fabc0ea406c088208e2d0913d90c 000000000000000a2bbb0dc41644f468fbd1e9bde224d9fe9af7bda30220e653 +268200 00000000000000085a35ba8285555768e488ade52121fbe896f35a06e298f2b3 26dfbb1d2a849563ce7629cc80ee0e62f82d2b8e9a10ddd7b540c2921116b928 0000000000000005f478a81a12a25b7a562f2f75d1088727aebb1170d4da3cc9 +268300 0000000000000003e36c11bc2884bfe995a147ed0d83e1c263cb5a657c1dc89f 2f3b12e018fba81c44fd8b3317a7662afc8908094638585f865da8702afdefd7 00000000000000041a716b8f667b8effad995cfe4fbed891a109cfc2e03cf9b2 +268400 0000000000000000990a9d1e4c8d7bf9abfedfc7a029ee57f9c122de777dab65 d3435cbd4e9a51ef0a6f6f880438ae7bc78c87e3d9e9135610e4175424b27957 00000000000000082ffc2ea5351ed56c48ef8049ef0507aef28783f5117ba25e +268500 00000000000000004c2439104bd4a14d071546d2e4274caeec2c044c6d99b7ac 717d836cc8a7122b99aff08321132d1edef0ce457157705fbe111970e8770663 0000000000000004743ea486eee044d39b0814a2e9aa472cf8078846809d3cf6 +268600 0000000000000007db86b366f60318c63bd61c56bdf1ed4e0a625c7be25375aa 52156ea74d3a3f56b40108936176a39c8b67a3c28d8561f32022660d086d41d8 0000000000000003071348c468c0e3d95d761fad257778a798a325218a3ec92a +268700 0000000000000000fd719aac4de4cc82c6de34c46a6484a963a9db62f20b76b4 043da157965040249edc8411da81b6b5fcb65fbd53f7b604039df6e4d8960f2e 0000000000000003c2605b8d12c584819cf7bd1f370c37cb9ce2c84209f11d39 +268800 0000000000000007ded2114512b81d067615942bbf9bd870d1017f1d157be22e fdc50ace40b0cddbf894577a621cf7799dac341e7de5f180c6917343e2a382e9 00000000000000047139613a6ad3549674ceefb272f76d3bef9ef24c4baec842 +268900 000000000000000685eb64e3c36ec9bb5b9332dd78bb1d789119c890351086f1 b6cc54fcc00d3b945bac4a51c46bc53629e159632e09676321632afc1e16807d 000000000000000483e0f7dabbed1c3f7e15d8b8bd30c0d0569d79906e6974df +269000 0000000000000000a49290932a6374d53ad4e41be89a6a9c5dc2ec291f6bacac 3ca01e952c994511bf1727db98249ed1f3811783202d808745558f661d8c4f89 0000000000000001d5dc70b06246b264c9f4e20fdbc84f3f97dd0d53b90c3721 +269100 00000000000000022265fd015efaac14950531ecacb8159554a0850d8cc9ca67 ff1ba5f8937174eda980958bc83d940031e019d5eb5d2a58b75e7f466565780b 00000000000000003073915556565d64d14d7274c494c7f45bf4cf60da588b50 +269200 0000000000000007a35e866ea0c0c25510c676fea0220d2140afde5226bbd9e2 7b412c4f8e21bb72cda6bcf363af26b4b1f3a6ebf2cec3b69f6cf344d4e672cc 0000000000000008455e41d0dec1411422b4a54f10592a64fc2c314a4469a98b +269300 000000000000000110327d6de2c4bb6314768abf52720d92cf91e378fdba79e6 45785cda03dc61932f8095ce3eaa955a2581ae5718c07570ae7d8a4396dac6b3 00000000000000058c26b89c1d098d03371ac6d691985a5ca9db73972af7dcdb +269400 0000000000000001553468f6775c3687cf7d6414db00d044cad45c41e4aba571 8641023d125c7092ddbe8cc5e57ceb53362c767b62b43492283b8dd2468a8847 000000000000000743756bd8278421b525fb1e02d5d01b9ae75a2fa899a3681f +269500 0000000000000007614927672d1d153d2cd75378d476fb3fd284e30c5f4d3325 967f71b20c67bf1e8c0354768393f81ed37e6e8803c9ad211b6aa6f074eefd3e 00000000000000022aac296cdd1f02efdfe0c3afd6c986979dcef54ca5b27f4e +269600 0000000000000005dcdfdbd040f29768017934edcca016bad1dc009f9f051e4d e28cf25cd3dc7623e6888504627356a018e84ab5689b51fcd430f5a749781ab3 0000000000000002c2c50248356a9dd8127a2a701781b7930ca35b0b6a4aa2a1 +269700 0000000000000001e2ab3c287f960b5e029d9878b78419d0136795b890be396f c44dfac40c8169191d9d2650ebc196de00ecfd58686746784665e4cf2aea56c8 0000000000000005de24dc375b5ea0201dda651bdf3247ee5f8c0da8461a4b52 +269800 00000000000000002b41732543f667c39aabd2f4132feac96fdfb510211d6b7f 55e46e9ccbebdca79d99fe86a8ebc06337b6a2c2f1cc20934096e8344f434007 0000000000000005a046874e9a2d59bc0a05ca054abf4848086880abc1c58ade +269900 0000000000000000027a5eb956fee39ab7f1910e5a2155080ce9914dfedb7b21 aa823cb6de0879dbcb73107ed4bce6e27174fccdf561b492323790244b4bf2c6 000000000000000867664c13dddad22000d1dbfc7434c51637f20e1b3f637476 +270000 0000000000000002a775aec59dc6a9e4bb1c025cf1b8c2195dd9dc3998c827c5 84f2fb14b6821470e35f903201004760dc56e434f5ad5e15d11aeae37afdddd9 00000000000000072c426558ed4a3431bfad3398b8b114aca7c0581337992105 +270100 000000000000000427ef332dd54bf3f611c1400dcbe1863c811d4e223a975d9e 7540ae505d2cd81a85294ac3ca85dfd6f39151b72cf510e5136ffcef417d345c 0000000000000001ee27dcea2d3b0702b310d6213866d8dcfffceb8b5b87e973 +270200 0000000000000006c536e2c7e9545aafb2663a95084bddf68d9251db8685b2f5 30381dfd643c3f2ef47eb58643861598a24aec09243b8625b6dbb5da7b491613 0000000000000006afc319a360003791b54656e97f94c0cefded5c8909e1eefb +270300 000000000000000177074f8e6730f198fb2c7b28e97aa2341cd95d7ab0988141 b94b9c86b148ec98f6619a91963f19bb987b12ce4495ab97d6def5583cae91b1 0000000000000004a150746147a19923bc4adb986158b726b71b70f2953c9c53 +270400 0000000000000001efc47cb2ed833c5249a5e12a800bdda7a15b32da666044fc 3dbd487c6ee48a661db89b548d25979919f763d61fc9b847686bb6e4c6f4c4ce 00000000000000023701db9d6145666d8ee8e0a4f587d431bf0889343ce452d8 +270500 0000000000000003992393172ca43ef3f566bd68c4437e79d02326444c4a72a1 5844aff270229280c1532275b161c479c9d7ced8bb067e762a0d8b02f1715b44 0000000000000004205908712f580fea034251412accc8dd7e025bb832cbc596 +270600 0000000000000004db2825b463e3eaaa33b7a9805589475262fd977c028e70fa 55fa15917a6bfd8b628af0fb1e1692c4bc68723efebdaa02f6b9391a0a75b010 00000000000000067f70f83dabb03baa79c235fd55c9ace804a18225d93b4d8d +270700 00000000000000064f72fd06b78ba81bbf4af77a68f9a1e058cd5f8f7a6e6379 43c8c91e5e6be5f0536ed45d31793708c1b77d860b96a8ddf31cf5652801791b 0000000000000003eb892338c0953df5201abc4ffe18f1e595fb1be85e53aa7f +270800 000000000000000126438278c0c29bf036790fe4ed8468496c831f17e1caa7bb 09d2055be8bdfe7a75ca61013d157012e80d023fdbeab41ed0f3043d6c95b458 00000000000000066c6f368dc5ba8dc9a3a1edd16788ffb0ed79e5dd6c5587b6 +270900 000000000000000206d88ad682569279ab325be88d8c7323cb8ad9b354053806 82c314d015b5310780aa6f118b596d5cb42fd1665358d6cca3d72af2f7e3ce53 0000000000000002344e2d58255a19d00fd2926a02fd84711dedbc1b517fc377 +271000 0000000000000002ec315dca0e0ea2b00cac28ef02113bdf85a9d1eb907a7511 a14d65e1604b2932d82fba4b63f8c25b53d9620000633f03a3aea433e93d70ff 000000000000000088fac639a3fa99a23d02f71b9270037e5110240e92de7cb9 +271100 000000000000000504939bbcd2bbda6eb748e0589fa1222e5c9abbf5ac8e0059 206da726579311bcf1898b61fd397f48bb4e165636e6f5da9b441667e8ee2728 00000000000000054bf32a22f7865c04e436f8bfd9f9a8c2b33050ae165410bf +271200 00000000000000016b9cc118ea7d86919f809e55294861ee09471ae4dd7a51f2 facb2d693fbc67963c98babe0ef6871c1a51bcd88eb9987c20f46e62b3e971e3 0000000000000002f0f6da934e421aca87110dc2b06a291ac4288b351cdcdde7 +271300 0000000000000001bf8167a6d5d5c89436fbbf9c64558bfba06bbc71e6e2b590 727a11c8c1835cec377d0ca81bec48478fa2245888734fe28217d17e456d8861 00000000000000016f6034a31d68c5da3f66308355486263e3075f683c3c306c +271400 0000000000000002a60e7b188ca2f76d91089deee1abd745e7a1fc3c4c7b385e 3fd119d0eb4f14eeaeb73aafe8257b12b345c28bbc25e58e57f610253555feda 00000000000000057cabf5c78abe41effa5862348da4bec7698d0dfd1dfd6573 +271500 000000000000000290112a81dcfd773afcfec1a38a277cdbe909027ca35335e0 9ce451321e31ebef88d037788b32a106d15773df5c301221c975ecb6ad5d192d 00000000000000011e3ba01c9215ba22d9718304c35bda9da30ec6012a9d4245 +271600 0000000000000004f3cc28d404aa133cdea637b03f35152b266622eb1cbc5107 059ea79969961435419ebfce845ac7763a28dc2d79ef52b8831dbdc0c83dfd34 00000000000000042e970d0f9405f7032c91457d739a274b49a0b8c3f6aef7fa +271700 0000000000000006a670e6fef24e1fc0bdf5f8ed7e22f77c4931ebacbc26fa98 92eff944874a6ba69114cc13e3e5774a76cdb292adeab137e56b25696bad294c 00000000000000004339686a5a6ffa9492001431a4d3eab06adb10bf046f108e +271800 0000000000000002c4e9c1df445ddf9fc85d12d7b7a5f85b181901b04b88c76f 8f4f0622aceb2a1db280dd5e5dc64c8d7a85c14d608639ea9d435babf2e0ef4b 00000000000000002b0ce2fc49234da21554539a30e4ed5250d906e7c7d55284 +271900 0000000000000001eae08c92dc47858a459369882b835ce0065a8141d501138f b82aa5c862d063000f8398dedd5f370c2acea14e9aff168152f3e54980bdf4e8 0000000000000006b1dfdbae982886b023970bfad3c3aaa7039137d14fa7eded +272000 00000000000000050a89e2ffb28757d35e14615f23b981eca68906c8c71f65f2 481491a036a95b8bdfdae189e8486612ec4badf95b14e15ae7c5eac810eca2b9 00000000000000005ae2b9dd4ea05866eb5f5e8a8ea54e25a217a9c6bbb5024f +272100 0000000000000005dedcba566d4311ce32577130c1f168d60a02636b9df1ce0c ad2a88f83c062d895a145d6285a20ecaa5a6413befaf83adec0c86334e6318c9 00000000000000046cafba7fab66e25bb71e6dc5c74b71956e751341588972a0 +272200 0000000000000002bb731f4609f9c56a613761a04cc10c272027fa0404179af2 e91c9547290b2da5bffa80305a45b7449a1035ffde258d5972445a1eb50368bd 0000000000000000fbe0ce0961d0b427b73fcf743cba6bbefdbb5850838fc3a8 +272300 0000000000000000020f1b5f355602fefd96a8292eb15981c93f1f133c7e733f 1e93d1594289fbd8d182a70246afcc4de23ef2074327e66dd3b4c9a077b131d9 00000000000000036878f72d8be41c285a233891097516f4306fee23fc6881fd +272400 00000000000000015790fdb1f1b57df5353ec2c7a8af1c57fb76af6278ecbe2b b945aeaa2d11b7c71cb9f4f7eb005bae6c7d3f423bfb7824a95baa871ea81f32 000000000000000069daaa55bb7b6afa56bc94eaf37c5603245f78b1a4489c5e +272500 0000000000000002e7b0c58dbe062770fefa09dc88825a9d4122e7e465dccc0e bdcd5f4ca72854eb4808bac517aff33c6fb801da8966c448e1e14077d966fa53 00000000000000053c555b2b76fbf0e059247ea2ecfb6e20de0829464e4c127d +272600 0000000000000000f03d33e37227977f83b13ed97964561ddc07470039b2168d 3e1fd5316ee4d1a5d0b39361a75cc06a3e861b14862d64fa45efe8a91b717611 0000000000000004b9cb4134f5f7f7c11098510fb39a28ae0318100a5367aecc +272700 0000000000000000b04f3f190d021fa9600bba241676081b81ebf0fa443d8905 12539f6279377edb1d5f3d9519c04e4ea2fe2856a3eec607c884b6dfe19721a2 00000000000000027570dae855d526511754aaec1952cb42d2762d170fa0f13f +272800 0000000000000005b7c79d0527f61138bd162bb7d79f08608a7bb874437712c1 db67e0b35138075500cac81f9d45e02b6ff7e4c68d4a90cae6ac7a3c162d2d1b 0000000000000005cdb96e6cf6b0a1b275d15c80068e059e54d815b0852d9c11 +272900 00000000000000028cf658998f1949cf4fa1231af0407b1cab56c88d32ad2b6c 999eab115e508c32540bc1a486fdaeb44b68354dec463db7b9488e30fd4a01c7 0000000000000001b0e5dd1f270fe9357ad19f4331a7cc19adfd78b0ce41e64c +273000 0000000000000004e69efe86995604dccb8165f4ab96ac11e85f203fe9c0cda1 408a1b2d1ed6225fa5be7588424fbc2236431724014e5ed4d913c4cb6658d496 00000000000000033619d25b3ace4a54d73aca73c825a2cd653189f3baa0fd9c +273100 0000000000000005c50f737574a98e11eea9119a5c733d2d24beb90c745508cc c6ba24fe557059cf5f12cfc39afd69f2d90c2dd857b570524d2952246f0faf0c 0000000000000002762a7260047357743582682db086de51b9bcc20005ff5f66 +273200 00000000000000041a1d1963c429290cf5f90574060fcb7ab6d28d66a7527fd7 525d826edbafdc2abd6ae178b82d422d1b50894cfdc8220ccf90717b846f4469 00000000000000008d96ed51c07aa656fd8d106cf4d1280e58d68465a2bf7748 +273300 00000000000000000657831e6b1612496acf9a48ac6a437ad731331c574f6ed1 49a10baf018b987a1129c426ddcf508e913710722a3551e4a0cd24a5a5816a5c 00000000000000030c308d00541b0b589f88584460153de1dd20aa861cf60f8b +273400 000000000000000306838aa4d513da147a715cbc3e573875faadf5f0678f8ca7 b8f0cccfb88940e8d6da1b9887fcd7097207b4202532c41e289f11032d6c97cd 0000000000000005eab956d1de8f3b4e9b436c6cc0c8189fa9d71ae80a2e91d2 +273500 0000000000000004c30360d173dfa67bacdba4e2e19334b971f6d7f12a338937 d7d856d39252829cec5b97236995dd5fa44b0a84f1815c9a5fd8448040446056 0000000000000003b06c81e74a06dd8135c2a137734c3ca704b61cbbf0fc0ea2 +273600 0000000000000003fecb815b2d5189b42a4a5cec121d1f4bea624c39faf1ea2a 66aef1d43745d82b771512c96b3df456f55ab3cace7c60d93faa90721d826f62 0000000000000000877f067d0bed13e4b8997eb3a54659385568de6a5867f7f2 +273700 00000000000000012a2e6926aface65e43aeeca947ab42441320824aed7702a7 8a0a033437f4c77a232f54cda02eae2465e94636630fd3a27c594091a6c36658 00000000000000014d370182ea58588721f1f94048129922d426f822028e9dba +273800 0000000000000003ce6a67ebc684f0fdb2f8db07b4df752e2a5de0cc7fc639fd 7f2144fd63439f9be41cc7faedc6ba9fc5ad245027d0ff731a75f91feb5431a3 00000000000000031e65983279d36179e281a50e7d052d5e0e44736f7e779b50 +273900 00000000000000020e2fe323d40d34b2d2a782a5ccf62821815416282758bce1 954e828c4167fc4b38a2a549a4458c80de201218908a7a440ec35fcca502acb3 00000000000000058203f6b69a7c209789e8362f4947e1df9c2087a949c3338d +274000 0000000000000003fe2d3425e9f9b906f02f40b3db90d908ba0fbd1e44cf43f8 744c98ea5e0afeca679acf925d4a256c23d7495805a3cebe94ef43ec1238eb4f 0000000000000001dd30fc52fbfb29a7e7fa0c40da666b2ac5b010cc7acb3674 +274100 0000000000000004b61834b9b984e8c1305c4279568273327ca3ef76006090f0 8ef69f63feaf4f873260b7226978c4692313626b242bc3e996495553cda6ae71 00000000000000005b90f8693837826a5f72a3e243c22f6cce004e4855e59881 +274200 000000000000000332b62390a003a63fb8b2c0563f1e13fe25b023333de15a4b 2c20e50dbdaa9bc7de0329c7e6b3214656251a233e4fe7f769fe2e7d08e19781 000000000000000269efd9a6103e9151793db35ff8e60b492081c24b4c39baa7 +274300 0000000000000002c5827e161e996c056cf5f0fd8b6e5a2e2a68fade99115178 d9ec07ab9aa4b8fb8d1a4a375805e293ac8ef718372eff7507b0556946b2ae23 0000000000000004385358285193199e99548e226151a77853d2e32633c8ce4d +274400 0000000000000000ecf8abfeefa867c3f17267b8df8bef5f4926b5762a859286 f045a03cdd814e13803e6b870d9ca146b3b741999bc8a1b690ec709248b7fc68 000000000000000494a249c199d5f859bfff38c05d488bd02f2bca98a2336ccc +274500 0000000000000000680da195869e81bdd1f9c173d96c29d7387149c0d2eb702a c7115b0a217d9b4a69a0d3a9e7db873d1895abf86166b2671d845919525d6ca9 000000000000000158cf7628a404aceec1eeca9e8571f25c6f6d1206e9cb0c5b +274600 00000000000000049a8e067bad644a7eacc43687babf7ea4800f561b6c1a48f8 e9b29a8fc978fb20fbb7cdcb612cce16b6c05f39a73e5eb618b3dff472fc912d 00000000000000012b2d7aaaf7caec9ee0be55d06381228f34a745d1a16d1321 +274700 0000000000000003b8c68fb86ff86a9a041125f92d4da59c90a71ec9e18f5f0e b6efa3fc70bab0e5e55a6dc4281b32c2ad838a14e44bcdad19fb06149f240306 00000000000000025d17d224696ff72976703d59ebc1a28c2e8b7ec8f6642bde +274800 00000000000000038f83d10cb3ff234777e369a526a0c01818a6af1113130ff1 d234b12a79e2f1f7da2bc45b85816024567edf6ecfff3bf17b6872e1d4ef365d 0000000000000000a7528893be28e4424eff807311efd464ec889085f924e5bb +274900 0000000000000001541cf9dae3511acbad1164e98f15131f2131748e76b59b8c f743c97c2bfb80f923c37428df1064f18a04f8e7c86a7aa7b6d50a9d2658adfb 00000000000000043a26ebefe352aca51bd4223ee08cd12c1b04cad9fffd15b7 +275000 00000000000000044750d80a0d3f3e307e54e8802397ae840d91adc28068f5bc 414e1d8ccadff6f7df4f01404b2b4ad603ece0c6ee290c6c4ef87516e74a8e63 00000000000000033faea7c96ad1772c60a5c3e44130e3e98e64542909359e3b +275100 0000000000000004600658634acef376b760c579aab83c46be64e9e702458c97 62b0f1a4be9b191f411e161f920a039d971baec09861953a91589c1edb9b2c30 0000000000000004a6dda6d6d08bd889bd36eb2ec453a781d2b043015aacf477 +275200 0000000000000000db9a2245f1d0c97cf8938b88d23f051614ef93a71e09aea6 ea66003e48c6fc60c6280cb819987e0265cc2e2d6bb64b04d090927c94b45eac 00000000000000013e0e59c8c30aaa2dd5c995b921a36d1a8df07e50302f2cef +275300 0000000000000003084306c8c5b89a1570e1d1ccdc3e31d9a3c61483fa83aad7 aa541424291c1c1cae08821f9f5350042962e8704d641349cffa3b3a06f43a08 0000000000000000d871cc5153ef927629a7c57d2acf8d490bc6925371c61009 +275400 00000000000000038c33b4311e32ce812560d29151dd4b8b657149ca1a63633a cdb51fc70e0ca4aba79f53280d69e339094c7ae8fb608e76f4c51e94a2167ae3 0000000000000001e283b4e31c3ca57b5cd6318ff044866614d58b3b9e15e831 +275500 00000000000000027554ba63540304f483c289ccecf9df8edb717bbfd23bd2be 1e3965f5767f517d588e590d11d57f734e2508b5c0524eceebd4dfdc29ebae84 0000000000000001df141537436562453313f663fdeae487c9cb6a4cfb7507c7 +275600 00000000000000031d6e6deb0fc8032c3db9038cce53aa00ce83c5f19baf685b ced945b3124c596469e2eb302fa6d01f6331375c491d23a70ff1da3224871001 0000000000000000f7d195ec44a2dd9c0d2e121147271bc304f840479a5673cc +275700 00000000000000039e3d2ae7262f5521b7606166e97490c39b309f330e097b59 b1af360feeb80be1bbd086bc97b61f6e6d808f3007a9b3555700b6536e2e436a 0000000000000003f93eeecea9402974314c0322d3ba60d87f28cc002d24a441 +275800 0000000000000004ab86e70e384fe20b581e391c617cc740603cdeb2e565e025 95b8b0bcaf09e04eee8fb603cf5a8f78479688e15bb18395034e8bfe4b936cfb 0000000000000002dcdd4c3f6bbf4a3dedb5136b682bf1f1d040c6c752d3e2f9 +275900 00000000000000005d46d3dee13a755d0129880cd01d7659c2bee0ea213eed9e 22dc5389c5f67770830cfb1bf6354c4567c0948a8c8b7a97e5b154bdffa0d38b 0000000000000003cc308b099274e69d44734d1c4b8ce8b1a49cfbed06f9ad01 +276000 0000000000000004b8ed801f8a09ba8c1248a5b1dd1533a35124a80438573f59 2425f7233a762719799caab2dd94ebd22a8b888c44e4bf845c277fb11af1814f 00000000000000017c2574b167a6be0482d330d8b3788c3ecf30aea1ce52a579 +276100 000000000000000048a3355667051cc31e3ae51eadd912f7ab01180b82a36257 703ce9f9287fef3d4a49da888de416a8c1a060a97e476bba6483f6336df1cfa7 00000000000000029d5167ad18274d40a39bed328782dcc6fee97bc5b43c1594 +276200 00000000000000037741486be66318dcc99dfa5655d3e32b25ca9d51e31e6391 faed0c56f2c76fe032779a2b8d192d3f5f082a94d36df520608f0ded4d49f04e 0000000000000001cc0b59ecb41d7c049b524e2fd9b28aef5e1f94b93aae877d +276300 0000000000000001882fbf61cc9b33acf4c691c95e43ab930ba361a041be3a3f 1e76a86f62eaa7a6135126d188711556b18e349a9b6a5779a8861b227e3b9727 0000000000000002cee0605fd633469134e979fdaf89ba99641a32dcfa8ffffa +276400 0000000000000002ef165b60dc2b602e173d53a185660eeee28ef09c227e97c1 290035f30abf869978ccfcf5d0de8b7ea1452dc03559014612f33ccea7e7c535 00000000000000007065cd7d09b1b84aa99a78123d532d7b541132fffba154a0 +276500 0000000000000000b0564e9de957b6188bfe767ef6e529f9272dbe870dfcd768 cad6232b7176acd439b2a938154208f7e4dc16ebec6614e07c00dc22cf3bd77b 0000000000000002c29e079e41e426d3805bf60da05606233af4b6ca50d803bc +276600 00000000000000018809be32e4682cb98ea78560f697352cc6b77d719adf0b39 b75136bbb84f01f8642c221765365d3e40794f4b01114b34cfcce0238468ebb9 00000000000000023f21d17384979ce23c829aa5088f1de0a6d08213887f7568 +276700 000000000000000298970a25aaf74079d6b5f02cb8fba30be83b3324287997cd ef3a7739e690fc2a514dd71b411104066f22777b5cac7ce232da7413f8eac321 00000000000000016b986e850c12e20dfe3871b74e49286ea24ff4c78f7e80d6 +276800 0000000000000002c26e81e219a1232776cb29dec36c86ea24089e9f79877a3d 36bde52f1d2f43877e5b21bf552a6fd6c648263489b418248a75238028c409ad 0000000000000000af633dedbd0b825bdcd3c23093fa8c6cf4e0939a21984407 +276900 0000000000000001867af6368b70e8213dea094b5f0ee75d603f6570686e8099 65043da873595f4369639d6551ca4cee61954c581e10a6595b611a357a63aa25 000000000000000189af8ec13404e014668c129ef52e0ec3c8da5cf57c0f97ed +277000 0000000000000001b8a1691057cd6639e56224d99f7f7d80e7b61f55be52d931 01357ac57ce5d9ef9e080b0912a78517dafab54d7eac25ff04d978569d625f9e 00000000000000024c9b563c5f34515c037e0e6b1aea26732ec30dd997ea5f84 +277100 00000000000000014bfaea20d12d171311c379766bdab3df31d05cf8720f59f6 ac2754169e5a16793bc9cda691a60a9e4f943bb0f2dde3be2a0c51d6f45bf630 00000000000000024b16cd78c396aa96235ef7a01d32f8ecd6ba752252b04dbf +277200 000000000000000124c2029853fe6e2273971455c9f4b4240f78eb1addcace26 9c758a9487ac08b0b8b4d52360cdff90f43b7be9ef3b7f7875c66a46b2e1d0ff 0000000000000002d8d0cc25710b9992856c4188565f42a7d11211446334ca08 +277300 00000000000000003374e135ddc177811d125d00ab126f36e71b72a1926d16b9 a82305b7e30f1cb5c4809924038cb0cdf7724affec66e3b5172cee9b07a9ad03 0000000000000001219742a2f4bb8f95d1a0d184693cb140ffaa468be24f808b +277400 00000000000000009d5145a62f14d291dd78d878e5ba0ffd137b4d76a1c94f8a d102f099dfdda730f87ab847be262329e748c8436b75698f318fee9f0d2220e3 00000000000000037442cb9a9ad01787302b9942451bff0baf82e37d2bc579f4 +277500 0000000000000001a07b4688e9bd626b5d0d6af29724e54e6737edf4dc7bf07a dcad423cfc04e1aeacd55efdc69038d0a2aef8bd0c018cae91f0aac603548b31 0000000000000000b53b7fe92c643e4985cdae41fee10f15c77d2404ddbbfa84 +277600 00000000000000022689e5223857c609388f8db886b147298e9d920a11c91392 dc1ecdaafba0c80ad36b7c2eea412e63bc95bf6c707d9e26b743e01aa1a5fd7c 0000000000000002dc4b8ba2144950193a5c9171901d6f833fefe07d58c4583c +277700 00000000000000030ee26e4a98a37c96033d4b3bafd64f86648ea88c8a628803 f6db113a32b922e850d4c68d55808a6dfde3db049f0754ad8870212ac60dd77f 0000000000000002c4ea16daca5b01c742ad63331c75ad1861f4ba651c585eab +277800 000000000000000253ba02569c9b6325a4a4366da25a89d8c550a47bf1d29df8 f7793b01bf68f23abbc00efe05eec25c91050e247c3ef704ad13532d2277a837 00000000000000012b4e4933e05d22ff76a4ee6ff3792779f6a439cd92b7d64e +277900 00000000000000016ac3cf46d00a505c5fae30ea735c9c5ade8fd15ac9cd6f60 bd24ab69e75a1b186839aca5947abb93e6d400527dd9e927cd6307f806801a6f 00000000000000017782a6d566631572ea1977ee84f9f79dd442126f0802d7c4 +278000 0000000000000001bcadd1e4b4d01063a17347dfca126c63893d2aa37d82eb7f df7966d03f57b595a51dbd01c190151ea969cc06a872ad951b28781f50931c6b 00000000000000013efa0ef2b6d85ee121367173cc9d7eb375717e9782f4a6cf +278100 000000000000000197dc87e0ea9b5a9c35fa57fd12c53b541805d0a82b58d989 9d627c4841e0ba9e3af25e75787cc5f6b9a7552fa3ea776158eab7503bb00438 00000000000000010802944a96637fb5b4dc64bfe4dee846131cdf5147dcd54b +278200 00000000000000015793f5d606921cdcf40655672a54e5f2e1de19a51357b4f4 56e73ce4fa8a07f27eed692b8bd146c0255ad4dacb9eac4d1c614d361af5c62e 000000000000000225097f454cdb82164af3d37a1ffaefec1526a85decba59a3 +278300 0000000000000002397c0fd9dbb8e660ae1ca4a8d50a9d4d12bed8e32563c694 786fbc18b7ef44d5ef83db0fd506d1cff9a00e75aac6222e8c9a27be8b2d57f9 000000000000000170b111383382b09c4876ca2513cfe130690409c369523b3b +278400 000000000000000164c524d0ad61283ac10608fe634cdb959496ba1470d6c144 a8b9c4fac830b53b9115ce5aeac3ebc3deaa53632907d82ff6bce4a598a21c58 0000000000000001c8b4348ba0acb63167aa89001e12caa0122bf0b302b68459 +278500 000000000000000142468ef10c92c7566a2f398f11b11e340d15c6aef19e1f63 76f16a96d1dfb0faaaa61f44b13ab764cbdfad706eddcc9586d3e8b56156ef1c 0000000000000002ffb99ae85aac3dcbddfd2ac0acad45fe5f92103d34254e96 +278600 000000000000000137413577b63716429a26ac2670b3521b26f2d4cf9e973ac2 0153a6a156963c933fa7940a6c51a083fce305817cd68b74075505c65d5f8768 0000000000000001fc89a18ce3e3ee36b0630f93b7685533f6a657843a7d38ad +278700 0000000000000001b5a6f61911dae8ff457575add2cfa063c1d6193a89bcbeb0 e293a377add8658944c49742b1c94d3fc4e0dc11e3d2a048bd69e0ddf6216569 0000000000000001c11c498a1836dbc759fb0ade9fc0a2ff801ebf7a9791f87c +278800 0000000000000002f3685ae01c53c0dee722e411fc97343d99d3dd3569b95516 c9256c462e14aefad4c59026cc58cc4ccebdf06742b95b99dd6a12cffbd6f71b 0000000000000000ae2073d9f5379922f2fa6f6930ac242002f19b083abaa7f3 +278900 0000000000000002e38233adbd81ab5bfc7561c769dc4aa1ac054df9090f6506 6f3bbc8b9cd46c4eeb42e736b37e6c9a0193db7a5a6f3b6c34451c4b6d002cd6 000000000000000132ac64ce02123d8c19ed2e6164331145c0b9ef56ee119856 +279000 0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40 ef3094c285c77a767729c6f112998fe433cc1ce7f0ecf5ab8f7b0e94c7b4e688 00000000000000005ab68faf866e0c4cf255c97d55574db7be30a8bc2d2fa58c +279100 000000000000000279bae6fffc533ddaf9fc700d5441a9bd58bff7c64853b0bb 112e9cab3636835ab58d405caa05e2dd834e07215002f833b358b43ead7443fd 0000000000000001a1a7bd25b760dffbd8b13ca6f07dff399287edafc97d376a +279200 000000000000000123075814391bcb0c43148683d02af1a68e1d15edfdca256b 8bbd81c53744e92bff232e28df6f71261d51803003124f84bb3c3e37747478ec 00000000000000027c044e3b92f3eb43ddc8916826afca5d5eee88983d0468d2 +279300 00000000000000022ebd4050d634fc414082746bd58bda3a2eea079790761e2f a9455fa33d733dd54848e9e7ae532f73bed03f12155834372d2bafc09a2e4d23 0000000000000000e10e11111afdc8730630beb5d72ec49f2d57afbd2c602d40 +279400 0000000000000002adeaeee638ced2c0191a895fbccd47456ae1ad64a0f91146 f50f2f746ca65f3376ad98a7c33650b93cd623ad77728a071a56b09009ccb57c 000000000000000234b9d53eeb1f2efb757781015db5c1dec6f9c9523594bc5a +279500 0000000000000000edf1a6ff589f58e509fbe4237fb162b78c5a27b631dbb1d2 655e91c43dafc7a4325c5c87e19c771c051d7e1f9760858e2496366c537672d4 0000000000000000c4b84b7742f6a272dcbaf12f275830e52ea005155d074cf9 +279600 0000000000000001de1c7f4aed6ea22ceeee328579ed67b002c87d4e76d76724 6ab547e6acf4e656df7588b10d7af1b7d3bde922a61adde0982c1f56095382e4 0000000000000000a7dd9b277a34da2628c25eeab6753837c11c5de96926077a +279700 00000000000000009799441fd48b8d2e1a485cd3227ae3ff1d58743d44823cf7 ccafbbc8cf364311da996e2d8cad902e3e5ced21df8e5618841e567566070892 0000000000000001df451ad2a440a5d5036377db842da0b352cc6a3b6f8cbce3 +279800 0000000000000001f7ac786c18ce228027fdf98760eca20a5aba4353a347c066 274f44de7b66f8531b9455c24ce34c5368658bea552c75183bfc9aab23aaf35e 00000000000000024e063b7c1d3d9f14f12bdfaa13dc5d74d0ece8b8f99a2a88 +279900 000000000000000251e9fedee6dd5226b81e9f48e91133f19a1a41a7fe68b98a b7a31bf5108c0d29d7b7ff32fea9c638724b66f51c5790dac15fb54d0d5274b5 000000000000000216ee7c60deaa4e9317111b414f4e18de7e8521c5379c0b8f +280000 0000000000000001c091ada69f444dc0282ecaabe4808ddbb2532e5555db0c03 21061e069b9a24e70f175619d80161178fa197efb1ffacf8c1ad9b70b9da0040 0000000000000000bc7b8f8b4a60aeb73c05de005797af3b78e84d61c93f3d15 +280100 0000000000000000f6d1fa6836afec729f664441d546562ff75d0eaaecfc236f 6f803ba97ceeefe21e2fce5f6029def90060fa0b7e5bc370a6db94dfa064186a 000000000000000305ed4475d1b4a2120dea743781709b670b354b7f4f296577 +280200 0000000000000000d4afedd557cb8134503dd453ca5f693b490399f6a9bf38f4 6ca630a5485da5df3dd854fe412501f23779f1fb5aded7f77818c43eb4fb749b 000000000000000155a1d82429d2896e936e5bcd0a6c8cda7e81669f35f00a88 +280300 000000000000000129b470bf861edbf1c45de234285b9226a15eaa792ffef57e b2e42a26d0bcfa96517adff6125ac7a4b533a4605db6ce47ad3038768640121a 0000000000000000271556788641758d5b89ec34bdf8a804fb084ac1b865fde5 +280400 0000000000000002551115059ee9be2e9d3888dc9284cfddeaaa1b825b5cb55c 61233d9a0f98137757e1e3c473ebfa8ae758b36bbf0115d4e6276e550a1741a5 00000000000000005e5fe70d00016adfeaca2442d6c4f9126c5a843204d5abdd +280500 00000000000000010c474cd4e25913535ec1c166b6d43fbdd9a5f2726711ced7 9961030a2ced1ba858d6e9045f696b3a2c00807424169cf2a1186514f21afe1f 0000000000000001ba3574f495fdf37334eb7f0794302abdad256256392d61b2 +280600 0000000000000001dbec7d46f262d1c8d834e98f3f216558309ff3a7077dfa79 3ce0571c246b26b463b552f89c230183466d33bae7f3f69942bbca893d2e2ffe 0000000000000000f2614a837ef46ca1f17d889411711e738877a1f3e0c82e58 +280700 00000000000000016262a87b76162256559b03d6b2b129711b950453e430ca17 5a083b7db71aa3a2a272996f63b1b3a07e85359733da42fae941306ce7d06f35 0000000000000002549f9deb16bf7cdd7e1a1caff8e80ba00c5b9d554bbbe6d8 +280800 0000000000000002126e593f4148adb0aae66bb32c9fbe65e77e560196495ede dee0049654cbf70d836617e034671aec82e03141633ff6c34a027fbd462bd57d 0000000000000000a94cffb8d128412c90168bea85c545d854cbe869eac63e40 +280900 0000000000000000a63e1cdd7bd7b671b6f5acaf26aadc62d2e51cb0e81d2c94 20afa8640364e3be7fb0a1213829570ebf4644a9d1c9883eaef9fea91ee10099 000000000000000262da7f9269a6561e582578b4e99107e0b09e66cb94b91e03 +281000 0000000000000001c1b32d5f6ff09437b1cfdea80c0f316ff4f688fd6db2c2a7 d50eafe49ae811dc7fecd941e7c0e662f9ba9d32edb2526ec8a47f9627a612e1 0000000000000001feda2756c7876c916e3aed3168d5423c7c89aa5ec7f8232f +281100 00000000000000010453847e3677e6255a56efe244256faa94a9583a9fb4ef32 8015b958c6ea2d049c2aa17e50bbe361746996759bc2e710e89f83498b18ed88 000000000000000148499811ea02cbb6e706f9a8a583e908317313c9244fd967 +281200 0000000000000001fb7a1722b68353f0ea3356718b2e4e86381042c3407acb2e 61c70179d19aeb4b38c1b005b8ade7e0c131c1839923d3dc28a6021d16265313 000000000000000184d5168dd5bfc6dfa9b7f662d3210f82ddef1b3676020e0f +281300 000000000000000068d15df7460d64e8259179a2befd32cadbfe4b7823fc76c5 5e291f719815abb1a67f025a25c5c24996afcaff5405e9231ef4453dfcc92a48 0000000000000001d29ae96f075a2248abaf67f877dc384ee57f7a5d0f57781c +281400 00000000000000022dda9b1242fc8c33eebc17d79df4c955e689c7f7a4f32240 780679c57fdf00ec94399eb2cd1a059c7e11c392bd870e8f6dc9ac653654acd8 00000000000000021bc48de0b83d855d9ee511a7b6d686f100422278e661d9fc +281500 0000000000000001f3fa12942dd204b2b8a5e1fe9eeeca4444e3842674c84ab8 0a7d19e325db08cd8a72c612af229931a389abde15bfe6b59f9d265cc1b2e146 0000000000000000431926ce3aae7a4dac6954aabe99ae163184f76962814be8 +281600 000000000000000137f62133110c996c18ef998c1d5e4ddbef8203741c8f5a64 da0d06a4d28a9fc83f2bda93cb42e445874df82ae4143ef90f2f0f400031b2ce 0000000000000000912911eb108c2891bea72ca8e0c1520541a3655cf6bfec7f +281700 00000000000000012d71aef3d9bf1a25099dfd95a0a7e0720279554ef1a57bd9 9f63ad5448dd1848ae73397e9097f7d7fd0e239af7f0ebd55752173415995bc3 0000000000000000db320ea6a3ea512791d0b903a913a3ac4d0c3c5cd69469c9 +281800 0000000000000001eb7b543dddfc8789479d73d664f542fbd520cf8c1d4f7379 cf46f4c7327a94dec189fcba90787abe06d47f6c457e365095a0d6336d337c4a 000000000000000103c9d811609353d22d5f4e78dc57ae1e85fe34b98004bf6d +281900 0000000000000001a71fb7b916dd22b7142399e775953fcb9bbc6e120b484d61 e24362489965237a9450f1e848d1d00b876ea2e38033ee2d8fbdfc29b84a8a19 00000000000000000934cd5583db858edfda6d9398e36f327438bab0e4d48687 +282000 0000000000000002337ad25e6a9767420766309cfea79f13dd9c910bcf5ca063 00db14c7010fc37eefef04ca46561a3dc63613193ffac8ec9c7b61f565cf35ee 00000000000000012781d061268f7e1fd21424013a0b48fb5b2e4b47ad44f353 +282100 000000000000000057731a509f5ecaec68d4b21f43217b8e3d19bc11095001d5 bd57327ecf186a456a94e0c577a8ea33f8abb14280a1dc026e0714b530d3cfc8 0000000000000000f1bc4b5d0842704faeb140186fa44d8c35ed7017a34a3a97 +282200 0000000000000001315c71472fdce344f85f794a7135e25554f2b51dfa6b83c4 09aba31a5249923535e1cbd36d315f3a8a562f98f5d56d71e4c55913a9b9a545 00000000000000008b320d1d9132e6be3871f30c926844c11738012a33406435 +282300 0000000000000001ad35b715e37abf07f71df68b28bd9106ab6f6ee530f8eb6d 42b9efcda0253ef4255199ae7cbe5833e54faae34bc8dc9dc137e7b68537bcfe 00000000000000009c9037f4fc18b449196a1b5bd60833695ace26374c978744 +282400 0000000000000001de61ebe0f20ac77ce111f405d16f23398b11595478148c2c 821d902103324b6a618137e1ec16ba7cf62725312b0d60726ccbb749628566c1 0000000000000001c642c5ade3a11399132e9ea5e3ad88e06a2362d6daaeac3d +282500 00000000000000016295074d36797fd9ebd62fafae195173a04591b140f40d5d 8a0126b99f14b0fd1014e400b07be05c7b40448bc88b7e9b6a8760983e7badce 0000000000000000d0bcafed6ec7ef9d1f3df830af36550cbb57c8a51ff3a13a +282600 0000000000000000db54fcd24ad74bb45a565d3af1c97a417a2e29e0494b693e fb300a2d8c97cbcafa37cf038d045ae919d7fc3d4b4efc649d58f6e7254b6cd8 000000000000000162a1e43c832172ea9033b15eaff406512510655a71deb132 +282700 00000000000000009dc6e099199d316e8b657e40ef1f84c18fedf79b0e4b431a 29160e0878f63a29e5fc02d0855db7ca5ae51483b735ee918f33a1d45a4d0b51 0000000000000000217767375780402645c707bb29a346205f27b08ad7815f25 +282800 000000000000000087b15e077fd569625cd9c477ef9afc539c45c01ead1e55c8 44404880f76e0500d62aa9a8213a62c6c50c4f64868e35586cae7cbbb06ed87b 000000000000000031e659c07157eeb0d0325821efd27e42a6ccc338083291c2 +282900 0000000000000000d68ca32d69b71e65f7bac6c2d0a53d310d3cfac74f1a7d8d 5b091fa30de384c3e75f1f48567f43d5d220f6e245a33de18a64300b4860efb3 00000000000000017b1f694c54f2429f04729fb2c35c9db506acbf5a1e32665d +283000 0000000000000001acd1753cf7079121700058279b6a835023fc31ad688784f5 965d85e105681e1fab0f7ed7f16e9fdfcadf0fde5ab711134a7cb8ec323571cf 0000000000000000efb0997c64af406f675cd1edecb744b42b518da1c30dbf49 +283100 00000000000000012ddb0e21076aa60281a3b93a4336f8c3884dbb5f85fce4d7 435cfe2ce9b6496d98baf6600b7391be8bb4caf2d2af297035e676eb3abfeec5 0000000000000001adbfb306170ef3e66f54cec4a7016f361f3a2e6db492018b +283200 0000000000000001ec6a02cf8d992923dc64dadc83ceddb5cf42360c6e047d1c 87cace44a8c3ecfc3226ee4dc1f600dbcba51a73aeb87b71979d77724fced074 000000000000000027421a529b38af11ff3e1c295a0bef6dd78b616f8f8e0ba4 +283300 00000000000000010a202e93c0da60fc605c2fed845f304e980e090cbb4359da 4c06160ae64da8a24505d6bf315356708311deced3ac7ab6cdb4c272acad35b6 0000000000000001c39cd832b500feb3e7c14049fb3d24e98eb370f85016a131 +283400 0000000000000000f1c506121d0ef0dc2ab828ec4d57211f6e509b9a54a2f340 668041427608f79ddc1a878356f1a9980a1f80822bc3d8846fd8bf89afe6ac9a 0000000000000001d29465da74fd94b5426c69ecd8c08b9ec743e2bf7b4768dd +283500 000000000000000195dcfd99f34ecfb10437e3cecabe5e16c7f9b3bcb7fb3950 79d9bebaa1ff7e30e74e91e6938bbe23d694daabd9c329475b164126087e8b1f 0000000000000001b2ae495169297256a40f390ef533882f139f087fa8fc7493 +283600 00000000000000004afffe700c0239edb3afdc4cbdb22c236689c1ca0430780f 3400651bc046aa39057efe433a759a76bd1226b38230ffd5aa96aa70fe8ebdfc 0000000000000000da0b8b82b4d9e12ae452565e90a2faa690187005f128d7d4 +283700 0000000000000001e33a288f2803b9a8401e866f01593605a6e51ea1960645cb b3b6b514d931628e83954a8dbabba3f752081a20c1aae99f7c79eb3dc55c6639 000000000000000090422cc4f3628877a259659350c5190d701514bb68f73145 +283800 00000000000000006f3d68b1a16e6a5b2b981d9edb2bc13a6dd98cf7088d1c17 0f3bf3cec489888f1da49ace91731f91f5768f1c4c53d971257d4c76adf9f267 0000000000000000829a10d1c9a8f15844ab50f6aa0342d557f6584a3e2c954c +283900 0000000000000001e5742c1671ff8adfc095f521b9769eb188207cb40123f8fd 40bdf07f3486fbb906b4aaf45246b44dd3fedc6afb50fce95ecc6c0c13e360a8 0000000000000001987b5c3010ed4151264bfc0e199bc88e986a6529eaf4eeca +284000 0000000000000000eac86582f121e5431734e2ea36bf73347022c99c1adae37f 64bb13a0abc3de302d565418e1cb05e43ac94f372875ae153a344ce86ddfb256 0000000000000001d6b73ce478f8801d837f94d3a8462e67e9c5d7898b5cfce7 +284100 000000000000000114df35db8a38b29725d688cda959372d96914ad9a8246aeb bd74e5043a4d8a2fd7fee2394b7a3c3faaeb0acfe98c4606c3d15e4ed4aea62a 00000000000000011b78e49e37890f50ee8a4099bf0f95c3ffb4d14e7b37e556 +284200 0000000000000000ac3c525ea98f50756561267db55982e7110a8656860c352c 65c8a91549f4a571fd8ef19d5273a113d0efc6d5e458994ec2db1d065151856d 00000000000000004e3a718623fb039c80c6a55d6365d992e566ba5bb6ec12de +284300 00000000000000012bbdde4be601b0e2f38f6b95ed723865d4159981d184363d 8d24271bf9e6c7b199c3f0b8ccc4b78901f7b11205d96414571b324512ded4b4 00000000000000005a4b46d9d161409f989a282468901942a66b337ff811d216 +284400 0000000000000000dac93e41b02cb856e1cb56ebecdf0840301381be1f80a414 ca76541305227e0d567316dbb136517c6101189a603d942bfd357d599f4e0409 00000000000000019bbe556f2c6f6734656234e00ca5d718bca8177d4da9242e +284500 0000000000000000287262621616107a2395a3a53be6906312b98ec1a90e2044 f52d55fa6da86a8227f80b9438585201d3ff925885811456a6ea947c8f81a4fd 00000000000000015e1310c14462c1aa1c0484e94c676f258ff10b968ef18cf6 +284600 0000000000000000ed67cb54c0041a13eee7256a0b7506bb81f95b286ed9e459 dc831fbbde68864c8e27f255130f0c8aa453b6db6ac5635298315d445a95ae41 00000000000000012482cf1672d81b8bc2107959f69fcfed8771e6b30640c558 +284700 000000000000000149647f4906f4dcbb16868de8c9e28fd635fec8341a72061d 8efc7f7767547fd1968b9961c08fb8cd12d699a2d68adfd12696d65495b54998 0000000000000001a210436ba7474883b24d5538bad5791f0dc4e83f22dc6c9f +284800 000000000000000132407dcf9d284c8c83812dae17e80f2af04c42aeafed4414 da41f9132a4ff5e65cc4e6642faab0eb3b6f9e52c5c635ea0e0de24065ce42c1 00000000000000010cfdc95007c2e354eea43dc93b0ada976829d0deb271c040 +284900 0000000000000000c1caaadf429196b12152fc7bb381d99fb974235ab248c33c 7f865d036a1f12d5185cf755deb4c528bd033eccc0096fa2481ca19c36ca5b32 000000000000000055ba357c1cd883510ed9ffb285cd2f9192c1fdb2df6fc811 +285000 0000000000000000d025f124aa161818f131b56f67d26ea96646ca2ccf671a61 69deff68fd7e2f9abc1d469e0912c92c2ae05afc7668793ce48d84d1705f0665 0000000000000000ebe6e22b223ff351c37da2d36c663e0d20be6f25ad1bb983 +285100 0000000000000001156258d00b6cb2a3201a9fc795f806f3f9ec7ca2e27b5b31 1da7a78f82d508ab97a8c027c8ab2af1dd8164df43d99e643b79c6cef27c31f4 00000000000000003c714905167b49710e26d3764a17539d8e473ae9edda9a4c +285200 000000000000000124b252a898d513b71a5fd7b3a2eb3cd5fadf5042e378b9ab 89ac976b35ae2f42bf04102b28430280c5d1e520b2263961122ac6eb8d39210f 00000000000000016b56f2579c2decce27d4ba0ce85a057cf16616c6fccbde61 +285300 0000000000000000c3e3baf02cd43f93a4be1775974856bf3116d35559705859 c31950d94cf3523264cab1dcd91ce89946c3b8460e43331def16afde00865e87 000000000000000033ddafe6d31fb236efaa398534c08455590a2d8d5de1e6ac +285400 0000000000000000c01db62156f56e61df0d4039f8a8a6610893e15606da2c8f e26af1bf46a03c85f2f0072547244acacb970caf3aa30440fba7f1e995fdd671 0000000000000000a0c32ba07f65333ad3152ac20d4962555cc2d7cce1922036 +285500 00000000000000004260cc16003d2afab1d55d46f0238b2cafae648a9cc5b2e7 fa24fd5f8744af0fcc1a665e3e3c70ee25a3d9e0484f060c557b031eb118b4aa 00000000000000014e4c9202524f0ba58a76e81c7dc4870a7e4cca6008a2b36d +285600 00000000000000016bcec5831cb6e48edcf7d9becf53a6912405c44cfa8863fe c3006d0b38023a8cba268de97cb66ac3c59101f594016b69a0d305d861a2443c 00000000000000011f71027b076b028440e9f00e24927d2baeced27a6e570915 +285700 000000000000000048a5ab521658492bb040557c7c62c7b5dd4881aa082c2c95 4803c49e637420ff8f16fe6179296099276f1d52ea135769de2060ea8c5def49 00000000000000007470d3d84a48aa2a230c46d6bdd2b7fb5d53d2b19212b5c9 +285800 00000000000000003a10a3e64dd998c50abf51e4c5e2bae180e49f354bf09a92 319d53b4146919eef35f593a264aa82a8ae6bad7f592b5e75eacdf194489e30b 00000000000000000979fe3cb46ba5025f00e2ecf2f7063a7820bae8804842b7 +285900 000000000000000070777247d6ab4cd19406b593ba55aabb3a3e107f6793e7b1 c6fa3a4b7a98193b340fb33da7e86849aeef336bb530e0787d6f78c713043398 000000000000000011db3b350e9aa728e800de663051a4bb8e8fc5215db7e32e +286000 00000000000000004388ae444347bde423f2f3aa6ef335b50909f5bc27d31ea3 0a92bfea83bf605458102edb8cd2d68782a44876df432fa76f107e3efd2fa85a 00000000000000012f5d301e9e40642ff62d5ac36be969aa7ac5f3f4fec8087d +286100 00000000000000000e9864ab962bd98556d4e3651b9cc61aae03f5fa6a94710c e9e82e304207896ee2669484506b42020e17d094c829ada0257f091f55c2bbed 000000000000000110b984c329459cf965809dc46d586ce597eb6e8552c98387 +286200 00000000000000001c74f260ea15482a66268b776ad76ba034b34f3a3108043b 2e9cd105e3d1d3682aae0e4e79658c6a2ae348a846b94ea90378b18e5adcfb69 0000000000000000d1917940265de5b39607416df92988931156038f307f540c +286300 0000000000000000d6e0f08bbf66367e4b5c06a51b0551b99d170d817f3af317 9ad92fca077f7153b91c9f2f8b75f94a612b3db959494642a0dcd37227c02b13 00000000000000011a3e87f096d1c869a0a2f7bb379168fafdfbc9797ca7d86c +286400 00000000000000007be8701cde6f30c19adc6d530a56a9f63d17941fb0ed184d ad5d387f46d2004c79033e5606f20d41ec6a988fe5a538faa01babcf84e815f1 0000000000000000a1a0b682589994aa74307f1c4c800518fb4ad3e0f740b7ca +286500 000000000000000142cb716e0a4d61f3f67ab2a2c484d53fb88b5398826cfde0 7aa2d5108144aab9d27b2268ff3304f2de88152e5331245e3f3d2454c7269c8a 00000000000000002fb6246d5c64db709795a29300b209425224eb2bce75647f +286600 000000000000000099c2cc4919800b904f55ab01022c2e64d5152eb3c5bad64e 34d568cde6125c7d70c4a02df9acc3c70eb16e34a25da80755fb3d7292294d4f 00000000000000000d64d1510d89fca9a2ac9a248630cb06a9a5237faa48686a +286700 000000000000000001c896b7944645b1b95ed65ef47e934bc59ca0aa7d0d4ef7 f8f5f2892be593db8d3a5f623ad028fdccbd23f6237b3f760280119d2b5e0a8e 0000000000000000e876078ed61b13cc88ae370c4f5695dd87cc4ccc054b3cad +286800 00000000000000000f744d59b18215051ee7de538c0acc4903938d1845e3e383 7a4276a9947c2bc62e7b1ea1716953e8354bffc1d73b7f586b46151b131c44c7 00000000000000008d0582522856f8d77a836cee246eb9432a06ff2cbd84f101 +286900 00000000000000010ab3dd8d388ed447331adf94ac301b2cf4407d644c172ee2 97f5dea6e31d59657655e52121b0335fbc93f829ca3290ccad295fb8e52ef082 00000000000000014d060beecee34860a3fc4c8f99ff011fea2cabf89a5ec2fe +287000 0000000000000000cc22cc938f92ecc3a3844f23775c4ad4e66404563c8594c8 c691094ac42e9e6132494d9b8892cd2f27e4cb3d0f63158a50cfb0b2294735c3 00000000000000001f98a9814d29da5d07036e07843d3e0cff9981e90454e1b2 +287100 00000000000000003ad8020fe115c2c6dba884d18cdf83c8fcd9e044aede1a84 d2bf77290ac9b3d72d2e8d3a8352bf67d17bfa28b726a899346e23065a8c9854 00000000000000013eabe1750e3519b9257845adde021191ec7852dc5a3b9fa1 +287200 000000000000000083087d4c7c5eaabe73f0512341ff368f96fdad48e6012ce4 4ecb472e612076494195e87b88747f0787c68f670bfb8bddc80b75edb3ece899 0000000000000000565e1a9248c92b2c2bff254e44b74a828e13af67b582a160 +287300 00000000000000014eb8946d79bf47aa7f64dff47900eef5310dc738a02646e7 eec8096c7f91291835b8315e19f7e20709eac7301e30c765b6b8591b63834745 000000000000000099b760126596fb8b1a66b58aad3247c12989b51b1be2adc1 +287400 00000000000000001cafb61b113750efd941178518d26d438f67e242bc9455fd 7df38a4c20037117ef4bcfbbcc55a469eeed9b76bef9d4e415798a6ac434f3de 000000000000000048242aefd17f8571ff7d70eb1a943e8e89aa72050d350367 +287500 00000000000000010e4bc33648dd91878a3b583b0a56eb9c31cbcf3d53aada4d b2402c4c0f2238094ba89d4c2355114f2d31092cf48c09043b05ce4d6468c949 000000000000000069b849b423030e063b7beec0d493c30426e2f18ee94ca8e7 +287600 00000000000000002e2775bfc466c898c3a73f106096058c51174dd51a79ba59 1a59ef369697770b699bddb2f92d083516f66a98c3e7f6436b9c33383b6508b2 00000000000000008c246a55a614dcc13b33959ead2191906952fdc35d3df3ef +287700 000000000000000107e6957ab937867e1ca49511fc91a0bd17da2dbeb864c32c 9ab630d4b950c92219f41876e756cb8701732f326b0908b2d39718825ba4598e 0000000000000001146c58bec4c7f2e5fbe566b7cdd6bf707791dec9b7bc9a49 +287800 000000000000000144db7ed017e1345289641fdada1fa72f1ed922da511f0e78 32d40470ae9c26459da759995169546f46b9bc14c63f64c5ed18ee62ec7e5443 000000000000000043348304d2ace14ffc08a9ef0510baecc59c14c87fdb3dd8 +287900 0000000000000000e057e874b1adec1d984cb42c1a6a6021b107ffe3b14663b9 f79e01160f3da5c4cb8cef99dccc84b866cbed2caaca3a4c2109e332ddf94701 00000000000000011b92e8e3817a6870fa55a9405117e0ad3b6ccc90b3a1bb3e +288000 00000000000000003c395f08779c3ac1301488b8a18c0999c008129a55610785 3574587d4addf6a65d41d31ef00e70e9c7546221b989a4ae55473dc0aac64d85 000000000000000125929e53afa23bbd42082294ea2035244570f993f4fc93d8 +288100 00000000000000001292e926c8803a0e2f6f77a10c010ca42dea125249eedfaa 40767880192f7fce1f1cca37891cfe4a04d104d1a1fbe858ff474bd1f2aed7cf 0000000000000000601959a5288b58d294925be29cbf74b5c8b32b90e6fa2cd0 +288200 000000000000000119737a9defa712e19b846238bec8cd49ee4282ba9145ea52 81cde565053ecb24a9df605ca52446c0674d69dc0ded32647e5e8caedbab1d90 0000000000000000975cfd383864193331f7e79861786fc87c6726ee881eb999 +288300 0000000000000000a1e5b8db167405a96b55ba351e14015c7512fcc0363f051a 9df5ea97a0fd484659e9754f22e0d673dc1635fc3a4ef54f9ee01cbc944acfa1 0000000000000000f5f123fdd152ae9ab2380053b7b0d3e0c303d0aca0c70afe +288400 0000000000000000fb4a82b667cd4af4dafd995da2f587d8fe7e716c69c08bbd c056f23bbc1ab215d4ac3b1954c74241543545cc2bdb513bbc0ebf67b13c3ce9 0000000000000000d8794082ac5df3a5de7570809b2465064ec151a58fdce149 +288500 0000000000000000b68fae61a0e53c5268c0c105ffb73f2b2b69cbccd9728262 1264d1d3e951670056008db5bfd955e474c2ae2fb32cf8ac009f7844b06014ad 000000000000000050416b5644d54573704e881bd9e701077e7ae625b3261bcb +288600 0000000000000000655f65f45e4dd6e23dbb7d8a2adfa32fde1952afdf473f31 30f0eff6694046e2f062900053db73da3770d979c68478c3e5e94563620194d8 0000000000000000ca09971febee4e777af43c63199e88dcc73bc170114d6f94 +288700 000000000000000047f9f2eddbd328d9faf4970d37bbb8c70f3e8faaaf1f05f1 c1c5cc5342c4bd69a316710708492792b5e64a8523bea79b267ecf6f3c51dd08 0000000000000000adec48f5a6472f47f52790d9c6133d541b52541b30c32e12 +288800 00000000000000001d8741a48769a10c363a281d9270546a7064fad6bac61f9c 85a0aefbfeeb202f234be73d1d08e7185d408553bc71b15a2a2492bfa4df4566 00000000000000005bf594bc7897e567913189ae700c28ece1f23a1691fa3623 +288900 0000000000000000eb4f10803b07945ba83dabf3d9d2dc182f36cedbdc4b24ae 59ea49f4a598032b067d68edbecbfd665061aa7e0224a79585b49094033d248b 000000000000000064e4e3c9a766d46430a9d2123220368a68dec03dafc64e42 +289000 00000000000000011a75b1aa12c0a928d350c7ddfc6566ebd02c4a60dbacbecd cb2beed1bcc3800c93b42a0d1ba1f215d00d4d79ee93098ca3ff714caea2fd81 00000000000000009001dc83291eb913c786cf0f0740a95f0897561054f71b6c +289100 000000000000000049cc5d6ab637b8e0ec8bf07cfe1be201f1b6660547d1237f 4123ea7bbe222a306204c4570f831f61aa36993973aa2f21394cc32763ff154e 0000000000000000fcb76151d00ca0871f3a25439657b56aa05e65d6931248c5 +289200 00000000000000010c9905f049f38ed9d419a50456f4f6f804d37405a6c778a5 746163121b1170b2040f97475112ae07ce0a0616f273598b29aa1af26bb5907f 00000000000000006895227ec37b1a65cd6c7fe118beb9ea92dc4b230a181d1c +289300 000000000000000080cbef0c18a5923ee4efd47e33d81c91a59c1131e0ecfdfc 2c0f6e126be6a44296d6b3e84a0299303bf1e2725933cba9e7552aba0b4e10fa 000000000000000035f3aa2275152ebda01a86a42f8ac5a8dffdcbf3fba46fee +289400 00000000000000009058a220dad9179cf68fbe3e80ef8499a618ff4f278aa8bc d2a3a3d9902667ac020c19f5198425900297d89b52d4eb77b494465a486000d6 00000000000000008dbd8a084f2f4a8b9f24440a85a6356861800e5cb6ca3728 +289500 000000000000000007d1b99aba4ec0b0d4fd88438c80cd44d43f46643b7f0bba 4a9f1506355b0a1a8c16ed21a1f7b1bb5debdb4b854afaffe756fa9bb4685dea 00000000000000001708b3a7debd9b0547bf98d4e7fc1dbdfafb4936e506ec4a +289600 00000000000000010bdf444a883554cc24afb93b5ddb3fc204a023cd6a217ffc 6af3ba6a89027fa0d153a530eab383b32614fd298a75d94150e5bc61640c75d4 00000000000000005a7fd768fc47d1cb42808c0d35c3846e64f6540a7a5612d8 +289700 0000000000000000df8ceef47bd89ae84b0a59315a3ce7c39eb1fa91d8a73c18 657ff13885dfdd917109167e8f0e2c596bb72504a1fd85c626a7aaeee952f952 00000000000000001bbbe3c6edf90cf5880ef7d2ec84c3fb644108bedb196f91 +289800 0000000000000000ca676c64852df8324db0be8c83de1eab3cf43fdfe5ee0f32 bc67ce01c6758ac63d9e180b0f55661ef5789e4704b49e1e498695d62860214a 00000000000000003308fd38d238e2caa4c8606a9e26e7d4e8315a93492f37b4 +289900 0000000000000000ad930dca0bb216e07d9fefb4f1403108eb16d36fb943023e 895ede3bff3e7f48957114fcd2f64e44f7503348abc571600d657ee77d117aa3 0000000000000000b69de5a6572b1096079fdf7cf8d20700b983efb82e35bbeb +290000 0000000000000000fa0b2badd05db0178623ebf8dd081fe7eb874c26e27d0b3b fdff0769af6d06acd79246fde9ccdfcddc8f9d796c1160c7cfc830548cea6f7d 00000000000000006fa3f3b92c95c83ddd9026af8e00227c2acd34b35a7bb290 +290100 00000000000000010f7162ad6f2925efe2c03c57d231a5513ede658cd6e2fad4 8779d446cf82c8a089a94399e5f7bf4b0919dd2ed35f7ad5722c388899630f75 00000000000000002b5e3edd24911f9d0cf0cb23efcbc0c80d5c75ca34344d77 +290200 0000000000000000fe86c26d33efd45350058cf89e6c044ae5dd4a1120e0a3b1 22aef709d0a6891e1f527a73e5afddc6626dc1515025611e3d46ab2adebbb216 000000000000000115f6cc6ca4948fdcd1c8ff4e1022a6dcba6593e88f160404 +290300 0000000000000000fa4e98bc541f1d62bb67fe81f3a35d0cc7f65979819be22c 0c3eab2917cf5531a768253662d40e02252a1841d0127d0914b842310bb1c79b 00000000000000001d4cba7e14340fb91bc2dc54967a6cbe4b92bc625b750a39 +290400 00000000000000007d2257505a400a13c1ce73398813882bbe9d804dde7e3be1 8dd8c1e2e68ad8e181855a1122d259b5f48a90ade332bec27b2128e14a996093 0000000000000000eeb318d112cc07af21feeb54924905f596a6c9a06e9763a1 +290500 0000000000000000cddfdf9d6d4f505253875f91a9cadfcff5dcdc4354afaebf f44fdeb33065eb33c77963daede542e34a2162e86244ee2619ea206ca13bca19 0000000000000000ea472d1a47e9acf339f1219516d1921f5f7df02187f6392c +290600 0000000000000000b642b496e742a6ceecac7f354c3554581418fb80b5f15551 1f252fa7937b13a0b499a37c93d576a76f19b3e3ce7089570e0dc89ede894d65 000000000000000078d7dc06074c522c4ad3f012cd6371de6c6500042d5cfc7a +290700 0000000000000000d96391b4059abc27a68fc8a41bbd4f92c5eb8e3b3390f83e 83197fd29db1da26880d1193771f2023d3b1c58a9cf667093665bde6950323ab 00000000000000007432c280f97ae31847eaf23601de29b54abf85ae46fe90bc +290800 0000000000000000eead43444d176cb781037af2856f549c8a4347aa27314524 5917f985daeabb775eb753fce204641460a8dcc8256719a33618a6366e7856d4 0000000000000000e01b06fb9f3f038b8bc3a95d16c8849d1e9fd0cd77e929ec +290900 0000000000000000dc2f06ce83f138e65156b6feb12de559c8956a5b0a682408 dcf7f1da2c28e0225d85e26f204d137ea9a25021b2236e4e4ee8cd327d1d712d 00000000000000009cfd996a370cf34a618d8bfb80c360d132e393d2019cb9c6 +291000 00000000000000010222dcffaebb28d85c1e594c65fc5f5aeabff69ee40295bb 0651288ca80a48887f8e1a56236bfaebdd3024490b23f6f5a19734d8ebb13da4 0000000000000000c19865f61eb99fa0cbc4a6f8e01dff825a7e828bd1daa869 +291100 000000000000000045ce9a402bfc7c20e9d590b11110940b1bc4d36020a71fb9 2d925796ea925e4e39b53b3be5b75421b90c6abcbbf83680ff951625ebe87390 0000000000000000a5e89b3cdd2b8aaa5e39998b5e08903ce78ecdd1a466ab26 +291200 0000000000000000f1f38d91fb6b655085e0be1bc2dd04f13c95dac9b1f7e873 45b8c8746e185788ed6813c19418691a3e967c9f25c6c7c0de231af3654d1e42 0000000000000000bf331e1c55c1be541fb94380710290eb27164f607e17456a +291300 000000000000000027cc9b90db014baab56dd9534772f9f428a11b0499b67ebd 37e6b2fed5afdb33ac332731dfcc21f3688de242cc101291807893ab24aa96ae 000000000000000023b8e772f76df54f36e6f72355a2411490fbdcf4d2c61c67 +291400 000000000000000050aaeccfd449aa6f9028cc5f0e24a819bcd20ddbd63d8153 a308882a1cb6a8ff81f3a446c156ee4c08c3da76ede03ee843014dfe946d52ed 00000000000000003cdf2a6f73c6bd90c0bead3e2423395b06f874cb51519659 +291500 000000000000000031ca93a2908ff3a668370a36b56f30610b43e63d3e1dfbb1 417c140923f41587a33787df11c0093922cc916e766b65eacd9057d35410c0db 0000000000000000ef8012afc83c782e378448ec5cf77350cc43dda006bc6d89 +291600 0000000000000000d73d6b4a44f306c58365eaf63caeaf648e318553262d2038 e846f7c5b505ac591957d5bc687e6c33988aa5d1e5b87a859268e3ae9c54d595 0000000000000000e0d04109a83c757985daec48b943251fd5122c60d13ca367 +291700 0000000000000000c6e1c37e399e6e604cc4946a8a1fa2161b3850052ea139dd ece5cfe8fe965f57656e205e54ecef45e0639c253c70c21fcf19c0dc9aef2712 000000000000000001729541c5acece7cca7b6938489543efc27dd63cb51b154 +291800 0000000000000000e16f7c079c40785d1ae23db767e7b9d76979357202c821c3 aac4fcdc6742b71cd61da74cab3ca7a3c3368ab46c2f4dfb3bbb865a9f8ded93 000000000000000065139be6b58c4f6173fd8adc49b1b561bc018cf8c9d4c9dd +291900 000000000000000006849f869b1cf79d3a6c0c0b4f39171133f1bcc8f85fbfba 474b962ff6e0cff38909f6912c72ee8ed19af25661783ad2f6fe2017b2493e9f 0000000000000000cc813bd26384ce09a2a699c3cf1de74cef7ce47c6defd376 +292000 0000000000000000620671231acb6a68134a0396235dcb0e53f4fc82bbaa1184 8bb33007a3b5798eb501df456476540d017923f35795e0855ccca36d6a5c9f89 0000000000000000b55300241bf11d4e59066bdf0af3baa1d5e61fef4a897305 +292100 0000000000000000c5436d1f651915bedd176ef0c0921969327856ceeb462f45 a97cbd3da7dd24cc0fa6d5e7b164c7792205f53ac7d52e992889a33bc8eb788a 000000000000000009ca3a7816de0b37a86393d1c06b0dd139175cea5fa9c73e +292200 00000000000000004c705e49acf467fc0b67c6eee8b03bf3ab7c327e89664594 cfbe0ab037728b49ecadaadc3d99e029ae5400fac11a0cd4e3ac9fbf75ea603c 0000000000000000de8dd5c7ac1962f6246e93cbd03e19e074e68f56e98138b8 +292300 000000000000000012c096882cba1c4f1d4b57bdf7f2f6f174486d83619d3db5 4167814cee8ebf3a9586b3eb7cbca6c9146eccfe69134f16e4a55fad8605c57c 00000000000000001f9fd24524ff21ad36100b81ce29fe580542327fe65d4520 +292400 00000000000000006ea2741c9ab1e9fff07ea06959057f93ee476685b74a19a1 bca4385d7e02a8ab6e8dad6b65a0564466fc86617bf78eebd10eead2cd4dfc6d 00000000000000005f3189269d2c39711d6a340a617267d72f95848a9ab8e7ba +292500 00000000000000001f81c01efa8b9f4a5432e4a41f1a3c76d647441f70f57b1c 21ee8a03441730258fec24b1142da8f7b01b33a344c15e681cf543a11f79c4e6 00000000000000007868fcc7057217ece9328c89a834f25d0ba122cd45faee0c +292600 00000000000000008a3f59e98246329a64f73661d6d7d219da8e11492682faf3 abd7aa509c83147006cd4f3fb1342428e2307453973c2d9b5f8a8ceb6ed63283 0000000000000000249ae58fbd0beb62df1572ab4c97187e4ade467ab4d041f3 +292700 000000000000000007570f99ecc4e71c97dbbb24eb8d2e8b436e92baa5955872 fa233237da8b365ed9133c192f4564a4519ddb34f07b839b0a402a7df31ad771 0000000000000000a07fad23fe18ac0e9cfe9759071f1d65416bfc6a21514aa1 +292800 000000000000000066c40be228b940924a3b6e2f6fd0baa393938f1cd93f0cad 77d74e4ddc004f3c23c0883946fbc775b3c4121a071ccd4f5ecc68e76036600d 0000000000000000254494524806089e1b92eb36e810ba02dad81d2d3d1f271b +292900 00000000000000001544a7fce213d98be118f550c792624758d2015165d003ab 8c260198830b0bfec22321e99cb643b3bc8d3fffeeb1fb82c2c32e8c5e4da4e2 0000000000000000475115027af8b17991c8c5ed424f08472c7518cbd524a9fa +293000 0000000000000000c504bdea36e531d8089d324f2d936c86e3274f97f8a44328 d5866550b2082fe0373f808d287c36b2b0468fc151a1f3e1251bc6c1552f58a9 0000000000000000a1e689745cf34cbca48fb2d75fa6b37a5d8fe95dd022fd38 +293100 000000000000000054896dca83117f36425bd3fe70f074ff0aa7a08ff18bbcd8 399da97bc095bcec34db22db2395820e37e9da234cdf36dca0fa2e77b88eb619 00000000000000003d137dc7379fa5281448168cc091fbe1e37d8ad6d4e00a05 +293200 00000000000000005eadb43dfece16412b34d3f2254fcdce4616ee2dbb552af5 c28f468e0e663a2ea0302a4a15744a66109b65a800139dc542301ed0f9373f08 0000000000000000812e8144a4015599baa128f26d93b66efa5321f5a0a10314 +293300 000000000000000027cf100b0d94ded2cb3e016f58d65fe34a9764720720522e 388d37cdabade0db913dae178825f582ddccfd6bf0e732b7747ed32d198b1bd8 000000000000000022995d27723671fb604126b9331ebbdabfa966d7534f6c36 +293400 0000000000000000af26d2a66747a1f884f7414c9ffc49cbe1a5baed35ac8c24 07dbc52f3b927e276b67bfb3f815dc6cebfc37603ff2c3489b56314f2b5216c5 0000000000000000382b3b455bc977cdb682297af44a65f3d8a3958c287faee2 +293500 00000000000000004e3d424ec2a0c9c1f09daca6d420918161ffb54ef5304435 277ffc871d33543689ac1635f704c1fa6355dbfb876344620e2ac25e7190ac39 000000000000000037cc63a18ce75743a430f1869572a834ced91f88ce27983f +293600 00000000000000007e95b544a9a2b9b6af348322045bc8c17768229aceeb11fc e57503aa75a1c84f344ecdbb057a86dfc08804c835f69b287cd70475e9d986ef 0000000000000000702d5e943f88573f6f310851e7a43eaabffdfa64f827c5e4 +293700 0000000000000000462902b4c3c032075bfba51e88b1ba02ae0e091ecbb8d7a1 6e97e889cbfcaf54e64e4796e64ffdab3560addabcc48c7492f33d3d245e5b44 000000000000000058f27391b0782b4998cbdbc520e6aa9f3b88b6e1940a3e5b +293800 00000000000000007d6d2b65791e36f18a72a6be094523dca279a57cf0a2a2b7 155ac294493ec8db005f649310f1d2c7be774551b915586624e48a8bfafbed30 000000000000000030edb38d9e91862473d8cd0b8443c0720926f2228a493490 +293900 0000000000000000d6b91012710ed1264eb050a08268890c3b85fd1c0e12c98f e5b2c688e9281c62ef7ab987268e6674feb03e15de208ac161a3197c460b9d35 00000000000000004a1acac921d3f40fb8bd21ef24d6e8243e0a33fedb48b4ce +294000 0000000000000000cb2540b3f00ce422887904c75b24bf75b8a73817302a4138 7f4b4c401a7ef83efba4f8e8d1173bd94033ca4c62bb708149d5138437d1b058 0000000000000000b2b41965d8307c588f5fcb4833ad51a7bb98009a4932d222 +294100 0000000000000000b5cd443a89e70b2afee57cbfcec24897dfb1f7891a0829c6 c5f8ff869b8f7e577e991f8b19bb04720a41a715e9f17f3354e465b46acdc073 00000000000000009277af310f51dbbf1257c9153ebaf561e5afa2765bb622d0 +294200 0000000000000000d869d4cff0dad03d98533fa16dbfeaf47e52db03be65c6e5 9c78ace3b3565d3d995bb14d19d56c780bd470d3d7a49e2cecc9d9768fe1ef73 000000000000000093b7699b9ebda415780243e0382209303f667b9ce6d03522 +294300 00000000000000008f06cc0e9ac75d7474a65756c1e94ac0fc68da20f68b74f7 08cc055a6beb96664e4d4e58b7d1e27aea735e265918ecbb66e30994d3545eb9 000000000000000037f5cdcb7c3e105d993865fb9a966fd86da1ab9a9a77837c +294400 00000000000000003be6fa731f5754ee4e521ded68ec317f35dabbfab0708585 a3a680f32c78928f6107dc957f8f622cc50c07313f1a17e6d5519985c066f7a0 0000000000000000a335fdcc5e342f063d20188f925d484786a58e54e18c1ddf +294500 00000000000000003dbf9c6765f0afbbbfef153e01e5633605ed0c6adc8c637d 9dbe61f51347e4fd3839b75935a1a003f8e13100fd1df2d18b9bf068277f3a32 00000000000000008b00c6aef067d78f7caf65a93143ebaabb14b0a939a8ab4b +294600 00000000000000003068d278567fa562461ca7918541b0e6d7cfebe833710138 e22d1ae0d4118ebcf1f95386cd133b8be36dc7693078a01263aa60b937dd4779 0000000000000000023936b74a0ff311e690ec84b56c79bde223dff4e6efd704 +294700 0000000000000000af2f965646e99b10fba6d73e5ac1c43978d79ca03a3d7ec7 43c6866852976e044b0c97bf59d58427283c8c2634a52982f3d14fbfde3cac70 000000000000000025a271d65fc418b4c83d27d30d2e1a8ee17e3e9597a417f7 +294800 00000000000000001e36c00dbef8374188596ef10c32cb97b8cf359d95895ec4 ae399528a1114c114a85685665823758b0c543ccec7961d7e0c8810f35ec83dd 000000000000000037df4c756c105e9f17fec0e8badb17c1e76663251da941b8 +294900 00000000000000002bb463509058358b5671af41e3b5314bb6e8046852d9106f 34c2c1dab3350c28ed5f6db77774297cc99672284989b2b632fcca128c20a34f 000000000000000010a941b6fa0ac4eb7ae98510e7ee0ac94a7858d2821c2005 +295000 00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983 a75824921b704cd7f5bbe7c5d28e6245543351b7fbaa17e68dbc3e0def1f9614 0000000000000000242af5e3a276d9c1546dffa6ba59de791c7e89afe929f22c +295100 000000000000000089080c53e9e367b29330ec7d1d2a415935619c2eb413272d 9123dc862d68c4de89f888f8e846d5a334671f066b98ccab11cdaa4e9cac2c8f 000000000000000036c13e964efbfa71adbfb5ea080cc72d77456de46d502a79 +295200 00000000000000005a52e8c0b5ac34c23e75fa672f25c2fb2381927f97717da0 e523bec6fe14bec0abe5bbb601e21f8da84928529671753b9a382243a4861e4b 00000000000000007e31545bc4c2c59aec18070babddffa57c0f37c2e5254650 +295300 0000000000000000a204daffb6763902a65d56e2fab0bfab3bab4448a71e0001 0630a9911b6a94096e672126f21a9b0aba2082bc289ffb7aeafbc51a1d9a806f 0000000000000000774ce19b8daa949bdfeb80cd53c66ced9d5e03271bdb2eff +295400 00000000000000008249e4879dfe99e470abc4176578cd1e6ac0e133772843c4 1143575043d33b35950b8250adb73ba999048db1dcd337c16df05c15a1aa8cff 000000000000000053d4b2be27b40f8be10367e342d7ac69b39cddf6281d7003 +295500 00000000000000002bde4e47b9919fa17665f5413f317bf8fc1ae22ce08aa589 9ecf554b56cf6226efe386c208f150e1c0628d18255fee9663113f6fb16712b6 00000000000000003e5f4908edd56289aad4b0bd30ee16a43342d7fe5847c033 +295600 0000000000000000617353ca67e8111089baa4684a021e8bc6ddfe38e2376a93 7b7290d4b28a391503d645dc6fe0a8e477a5fbcc26865816ac3536740fa8834e 0000000000000000b2d2ab925d9755f2365cf7c73df8d2862e492d5fcbcb83b3 +295700 00000000000000008529ee5a0e9c24ae57110ca2268248ff7d2d010000edee30 a5432b1b036e9c887e8e1c202b4e0e1ac7e379b30097e13b4d73f2d62eab5617 000000000000000062b1e31d624f4de9142187b9315d7aa44b0552dff9d938eb +295800 00000000000000003ac384d880cf8907594491d96b487c6025ac6958d0b4b7a2 647b3b9ae5c4e14e3bd5d8b0141e2f8f2cd9fd177e076bea51b6a83c73f55ef4 000000000000000096c7317aa347bb8224df42d3614136ed5ebb760dcbbe1cba +295900 000000000000000048cbf1720f8e888247d3cfc0fd407785d6aa778daf6defe7 6dca8e7b8f12e9ffc33e5baa36d9b97f6e2e4e948cb76e66a0d010f937a59bb6 0000000000000000184cbf85f7b95f08198417a2fbe511014830fb27d67c2aaf +296000 00000000000000009570102278e59ecf045c16ec8c8a5ea85bf823d0ec72e3d0 8d8b028868ab92bc5c1b76f77c0ce00e6885f9786f04cbdc370f3b3adaa9383a 0000000000000000a330622827ca24512b9be55a9be6a489e5c5c22fdb735d9d +296100 0000000000000000498eaa0e5dcab78ec30e6ff7a344038472cd321fba4db6dc 01ea27943c029d3aa4a0b37cb3cffa4f62845f4797e26f20b316300ab89daedc 000000000000000006534f2e453aeac3705bcd1b3dc1794a60d3fdd3460a0ca7 +296200 000000000000000031e30ea7301a0656c506fed415e972f6935c841e99f63e2a cce4304175d5417aef786e0af09c2ae33ae0000c93429b2c0031c347b82f57a6 00000000000000008e108f7a3c6376ac6e73e4cb3b4609ed8958ca616e43ee8b +296300 0000000000000000b0eca6ade9dff8c71dff0aea9f072fa346c9356768f327cd ee2ee064d3630a84494660db664f5fd550632a9a93137804323d5fac4aedbfcf 00000000000000003612f4a909f11261ce38f58afa236d546cc11e86a8abe26c +296400 00000000000000000ccd420c52e3396a1d8da557e755a23b3fccf857e34ccfaf 4665210ce32c321b1b6aea7c5f59ad2977c47708d192d6d9ee7a79562455113d 00000000000000009211c376c5058cae7ac5ccce48e35598c9009d78c4b3f39c +296500 00000000000000004e1ae2e54a9090c1dcd9a4d0d1bf2ea4e36efa40c6fcd49e 7fa8fc3a288290cff9e95ca5045d4ad49379a5b2947efbc5287e8b5171b1cc1a 00000000000000009be8bf743ff7e2947c282cef89f5b054f3fbdc027563df94 +296600 0000000000000000035910c23968d95c52501169c012ca4fe298dab94dd4e420 e968c5bb6ef4d6366549e5ea2892bd282f51104dc9a060868fd1914394665d7a 0000000000000000389e5c7c64425ebe31b678105c62d515a692630f1cde2149 +296700 0000000000000000501148ae551574ff247a761c59ac0baade1457098a8907f1 c5731ceb52adf8894ee9b7b35aec05e9023b6f0d396eee3e6bd936c6f63e34b9 0000000000000000719b92a242af8011c9cda95ac8a7d8e749446d5e00b6a7f1 +296800 000000000000000010bf6f2edeca3e31443934554d9de5e2e927b00260100a68 ec24600f6b12167530694c02d191d624a77b9112f6f3782ec98c33a92e69bd91 00000000000000002a39de0b432023171236b563aa213f0b5438da3ca26d9dc4 +296900 000000000000000039784aeb849908e93db9969d514915d41a73d8f15eec9c12 7c9f590bf5c21a35f5cf9427d444839d0d7e7c9e24e483fd40862d072ddf5a54 00000000000000000a32c48c875df9ac75cacf833abd7b0a095354312f430289 +297000 00000000000000005b7d48c27a70502f45c09c14a55e249802d723ba4370b67b f879feb859d3ca44c2a5eeafc16f93726d6a4a99051e775012240e473d936adf 000000000000000079fd7d472ae544cd46aee44846318bac2951562f14b7bdb8 +297100 00000000000000008b24140b8b36c79f3369e2f738715b4ba78be8529900b677 5fc508354ceb5507d577109deb023d0f8c34076df9feccaf7e256a018c39e0a9 00000000000000009ba0fd3aa1ad71a59e939b82af1a0aec5865f34bc1140c5d +297200 00000000000000007c6437f6abe271cf759600dd18df71ee909ff762fc80be7f b8125d708dd3abdcd1af0fa9ce1e0882c6295be05199a9b9a1d62f22038833f1 00000000000000004dc91fcf6a5698895e36517117fb45b8e292e144cc23b29e +297300 0000000000000000818733897f97b7561a7bbabf86ce14fed23392a5e378706c 1ad900cf747f8c53417436e86c8895f7de8da0d2956ee3c4c78a5c52703a892b 000000000000000015e4d40665db21b08470689af42b9bede9b94e960c3dda32 +297400 00000000000000006fc391d3f460bb75d3874c3abe04322088957685129b374f d6727e4a5b16845658fd1dfb771e6c83911c3b59419be608a8f6da16d78e9cbb 0000000000000000598627f63dd326899b75b751b30e336506f27ad6f940db19 +297500 000000000000000068e783f99e9338be3af1314e746fe9bd84f981809d8ca45d 49cce290eb73cd54056ef74c659f4eeda9035adf32dea6e97dad9d4ded5f703a 00000000000000007a5afa86ed026788599a96cfa6417cfa0ed627461abd0068 +297600 00000000000000004fb3b9aec53be2987714587d4f72c55a59d42d827477b382 0683a25283493ff4dc919f7533d0775cb961a97a8797b455c7afd31c5e6266a6 0000000000000000257a21b8f21f2b084dc7149ecc556ad2f3563e5a5b770575 +297700 000000000000000068658674846d18901aa165300e4a67cfcc5b9f08826de843 a7403c4f211b8ba8a2ed84c3e428f7d791e7f4f2ffebdea55d9547cbcff3991d 00000000000000009c143a1773a5dc24477ec151689bc78ffdd00a232bd533c8 +297800 00000000000000006a7479b39df015ea415a36f9dc6300626712375eac9ac499 ac2cb2f2793ae07b3165f6880c8e5361905e5451a33b943bf5a76367c971a715 00000000000000000356d7ed6a99213fbb1bd93048874b418fc6d03b2ce44ec1 +297900 0000000000000000388fba264cf24a50c98e6f123d2136819b5a48cbe01dc1e8 64def59fd74754942ad2d92a6535f5ca38b9ceb8891cfeb72bed57b61ad358e1 00000000000000007df81ae00c98fdb7b20b6439576dc98d8b8cc0569f3a049c +298000 000000000000000047d2f2eb7278e3f4aded9acaf502f5ec27bab5018b5871f2 c7d0e172a7bc0c6a1814bdabd295cc43ac2cc06664ce9010ac8dec172691483c 0000000000000000889350c2e7875fd9d66961571d80f4d8a1b09cb24c27f3fb +298100 00000000000000008bb2cd4c9680c1c38e21f0f77f4fcca452a8d534038fa3f0 133569d6ca2dbf81c32be0c60eeb0b876b33d4837e8fd3c2dd839a538109ea47 000000000000000029b798afe4f98adcd05e57306511540a5b86809aff8e3ac5 +298200 000000000000000003989769d342b005832d72b2dbfd0c3ecdf9ac3d56b05907 2f775b7463636024e93de137238ab9b353ca9edc38794aa7a0af82c9a06c4e15 0000000000000000843d75471f7ff4de3037dc79fb8cccc4732c8754ed150734 +298300 000000000000000045650a49c73c31abbb8f3b12680ad84311f351ccdda8d7bf 83639ca81150afc83125152cfdb133e71e69bbaebd8c4077ca3df30dbab3b227 000000000000000023ef0c2b68efd04b64074b20cc135ffb562e22099062e6a4 +298400 000000000000000019421c02df6f19274abd7e28bffef3acee3d7929d05e964b dcbb1a7a9eb747d99162edf292219d264042284f13f17fb33ae028fe7a134c18 000000000000000078056e082b11855987e1247f7d9e4a813e3381bad7ed417f +298500 000000000000000069d587f78b63ad24a7d0a099e4a56fb53e292e5691b297cd 641c873d69f83f57377aad0e967d1b20a81f2be3943f2d56d4eef3f9afe7529b 00000000000000000113221b896f40f04121549424a4bbcaeec232e1bf3aa69f +298600 0000000000000000212cda68381a8addad1f050ccccc6ece1c0532f0bd433299 d6e95524aaf396aec0c8e39c934f2edd64ee90ffab45233d0c4f37319ec18504 00000000000000001a9d1bee437f5a661de02e79b678a9e6061cf2ce1711f418 +298700 000000000000000062ac09336a907534b0e7f66a1db2b5800986b64f8f7a5ed5 b9774d934c58de5c5908ae04f3675bde01f0811b10d05cef2b821868d3cede31 00000000000000000d40e24d52a79e2b80060d9bb079791c1526bc46353b68f4 +298800 000000000000000027b15030305ce452841048f1363d594c3e1c547dff3a6ca1 033cd3a5e0fad8f01dc89eac4d5a3fe266e8b6580513b90c968e87d51c6023e2 0000000000000000469132543f5e128530833c279619200c8a224c6c17ddca74 +298900 000000000000000086a120963b2962120bb7d0e8550a0bb854397c2c01ffe374 322c43767d0e23b15d23885cb90850991adefe4c316977ac9524498059972139 00000000000000004d091d124c94605699ec78aa55785b60627f36f14d83937f +299000 0000000000000000720d383669cca3015c56200b48f14de68bfe30d5698d04b9 c6ae04a35e2bfc14afde2e8cbcedb9212857f746d71dbbfeb82b90fdb5f94985 000000000000000007691eb44be47d010cb2d9a73593734da0ac64ed5824423a +299100 00000000000000003211c932eceb1e11c781ebde68794f6abcbd457b5e47b943 52f4abfaa8160fd2dbb98c649fda1d814988be507e24b1976107da7e97f752ca 00000000000000003d3e0b908d6ae9be6a1b526dd7b4b16a5839b58604416927 +299200 000000000000000057cf6671e1b4b9f6e8e77072aaf4ae89142079fd66e78af1 baae22b87e3422466940fd836dbba240051c36c994bcf308398c50ff57b320b8 000000000000000022c3c37c3e0ab0e8916b099c89b895d566f8ebd5f0646ebb +299300 00000000000000005f15bd691e773e75ad809131b01d011839eaa559b3c25bf5 3b1ac1461556930e052d7549ea7afaf929f1882eeb69af58087e8486da66a255 00000000000000005afb3305c2454b681bdd51158c63e5c3fda4a882803e300a +299400 00000000000000004228b624a8eb69ee36a4cccab7f607acce73c1d86fc12491 f43e161c42afef5b0deff0938f1e011269a6dc44aa72da8462c5b729c563ae3c 000000000000000045e0ffaea91bd2c4b5c65bddf1ace28179553888bf895389 +299500 00000000000000006a163c180d7c1eab3b59bd634366589d78f3d42291569e0a 156cadd7c4d2307a6aaeec6aba0833ea8539e00021faf6615e8b11c67df023ce 000000000000000006ba2e55740cc3dae19901843bff8ebc8940d64c12738d1c +299600 000000000000000021fcde24d4c3bad9399d253a5fd65329fffbf7570a068c42 8fc6d41b822284e96461453cae33c46ed54d2bf1d8b134b5e9b1a9c432222882 00000000000000005abc3beb56c8035637acce853b126684e7f8fbe3d9219e36 +299700 00000000000000003365fb16bf3404b2ea32a89985e121ada43bd52c312ea1a4 4e47597da2c89d3be9db213c7f9f1fed30ea8dc6a1a327bf7e6be3333abd4dc5 000000000000000023558610e3cf7fd08afc02b30133dc40e9868bbb7dfec33d +299800 00000000000000000bb95d67fc11a244d140634f020e56dd822efdf7c6108797 e9328962fa1f9129f052c2cb6d33e6233b34fc2787bd872119b7ec68e999f7d7 000000000000000082ab78c5e4799d959df0c6f8d31fa35be4800684f1aca82d +299900 00000000000000001b08dd1c8a7a8e27555d5f0b2d1f322ff9e60ea99fbe06f4 ec86e5a31ecc400df2444acaa65047a8443d6fb324e2ec29b7a6bcf56fdaa514 00000000000000001bdd42d90e927d6840508ca227fe3636b084297190faa80f +300000 000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254 50afb889eda5598297d2638e4dc8924bd9eba142f6b5ad6885bc97bdb1641ab2 000000000000000049a0914d83df36982c77ac1f65ade6a52bdced2ce312aba9 +300100 00000000000000006679cad9366e85af47d9f78e7ad99cf8516758e38ab76187 5ffb286ca6e17b3cc9c311bab0e7af18e0529d2dd41b60ec540dc40c0c74ae7e 00000000000000002f02a07380086c2bed1681597860694af63ff8019fd756e0 +300200 00000000000000006a6bfcadec4a129c1c07efb4b6d94bb0ded7d3be0f328271 33d4094b83cd762ac80d205369627dcb8a2b6c12d29a33604f7e675ca623c990 00000000000000002a148d14cf6403481c464682d6467bd93aa0815ce994bfc3 +300300 00000000000000001df8b6491d19b129197853fe98c463b817bc43c7343e0736 42e0750a0f0aa2e75a972810fcfbe241634346a053cee645537ab005ef03a44f 00000000000000002887537d323675f79cc5eddce91b3c0dd433739cbfe9c823 +300400 000000000000000067cc249fe1be9051073e931b2b63bdd8245e21f600932269 ed7c68a6de606be420617517b84421a15c956e4f5bb38713753faea5c3a4f4a4 00000000000000000562a9a6e125ac137c57258dd9c812b62e4b2807da214df7 +300500 000000000000000038d7cdcbd44b407f757f30f76f6dbe3d96bd050db3c230df 102cd5850427671cb3387be058e1bd94de11c6ebecd56a29715e015e42a8b547 000000000000000016d9fe34702a3f43b4415ded841eb7450d26025ceb7b3e3d +300600 000000000000000004c7e013d3f07843c6862111256e6276710fe701eea63101 8afc0c1fc54c33f7085d7f598f14bb4f34c0a8a74c41a9481d10a5d7c0d4f99d 00000000000000000fb9707a7897956ed3342938f687ad1d9f538fa989d05801 +300700 00000000000000002e1f08ac61d3ceb85da87ec438a88653c1260312bdb92dc8 59bb354d2bec0cb458fad107a05b1cc61dfcd100e7fe62b6717233f06d081fca 000000000000000037925f78ef4b1f043cae20b217bbf6f40ba4284ce0e5bd83 +300800 0000000000000000547f4cb3dd0cb0aae96a02dbd75048cbc46cfc7062109cb1 3b0bc6609d4a6ffdcac12ccab0c22e202c80e90e8887f00f841fbdbc77a34098 000000000000000057d8bb3d5910b1b3251c4dc6b10015925af1de7f00c8514e +300900 0000000000000000228a5e72176993a645658dbf4eb14c1841d8e3391b314459 a1e24042b37d71a7ccc482502745424b2bb11875899dc54d761da7950f743a91 00000000000000006aff43ee3f0b7636824fd0b3b153e424b8212a23befd9ace +301000 000000000000000041e339634d94f4d0f00748732b43168e777873e494a8cf10 7c2a49406cac54a5a2a668e7630ae5bde08f4863f276bc587fb779f4495a89b7 00000000000000003a8de2c7104fa05ccfd92dc1fcea03d071bc639b070fe7d7 +301100 0000000000000000082f0eaae74bb1a911ae4adce0ac22e4a7ae71046ebb87a7 fdaf25645dbc2b57d1bd30ef934f84270886f86f314f340817ca4412503d1212 0000000000000000688e8a576ed16e1d80f8c16767b728dbea8d25e2fef852bf +301200 000000000000000026acb172f7326c703243d057c2032b88a897f227f1304502 19f61831145613285e222bf4c288720408d6ac668fe49fbd9967db223745feb4 00000000000000003d2effc554b4a2b5c14f6f47aba5a7d9ef5185a21b7767d5 +301300 000000000000000043a8c8f8465804e52f2c61055c3521c8a7fe5bc27f3ebb7d a4592b2cbe066bab8927c20ff19048b97ef82708c24d21a8d425d929d337e9af 000000000000000071075ab3a8b4b30b7c2a14aadc0da7b738fbd54d49efb952 +301400 00000000000000002437c1aafbc43c7e208467f04c7ef58810c29943ea22cd04 8815c9f96051f6ab0611d6c5649d15b09c158f7a566a8fe38dcbe47cd9b464b4 00000000000000002aa48351cd085865eb0a0a865b7dc1243b97742d7444ba23 +301500 000000000000000014288d18f6334634e7d936dd9fc9c896c48a078945d6ba9d 07a50c2032eba19fd8c4c7071b67a8c8b9f4bd56a0922a264bd566d4829f419e 000000000000000018676072817c0ac311fb1a71c5139307dbb89fa74a9ec18a +301600 000000000000000031194707ced2a733deef9fc6839c501f30e8881b78fd9d5f 3615c6a8094585aed6bfe886387a3b5b730ada2533ba80e7e25321f5304d22cb 00000000000000000ead697c48946b6f39745a32cc21ee6965f41ea389395ae2 +301700 000000000000000032c5a7f505dec5f805258c7a958bc7444eccb967f1a4cec6 f0e0c7baa1ccb4136e192987225980b5a4e3fdaf494dc4a7e89cee0c49e70057 0000000000000000232dc161e89ea36ebfddaaf3c34dd7df18cead5958928e87 +301800 000000000000000074e985a44c4812af3a02312c1b04d03b2524a328dbc78ed0 48b19adfe4f60ee189e8dd13bc9619934f7a99e4208bc6c98bf3910f100737ef 0000000000000000199cf338784f2be7414da39805b691f3fea8167ea6bd1ee7 +301900 0000000000000000593193aa4baa2d2502a8ee3df81144880ffa2411f131fdf2 109266e07e1b465d6c2ed0ebd6ac69e7a9f32a09967f014fb0775ec95a5185ad 00000000000000006413f3bdbd8dade56601d583c3d1bd60e184616ff5878ed0 +302000 0000000000000000072268c9bb18603566ed5012378c29bb4d37e34cead7448d b822fdc5e4a32463010130baa60aa2441bc985e476fcf10c5d1a4fe704c8f726 000000000000000073fae68fe1d836d0267e1223de5d84f95adf177f5e16a337 +302100 00000000000000000dd020ac75e588afe79fb17157bdecfecdcc6fd5ba44ae9d e7f104b0dbc08b8f269d48a0a8eaa54ac50b81c5762b06b3b4f61a74caf9dd8c 00000000000000005f74a9790e7c493bf003312c0ca3db1c9c7571cda675b929 +302200 00000000000000006e602194ec61accc3a0227c5e38095dbd687e3aff5662a2c 83d8cecd5d8220f0d0e35aa64053872d50cf7eabff79b45e4db85ffa59425697 000000000000000068c196d8e6c9d1a0e930479c8db795b265f700305100fc13 +302300 00000000000000004cc7991514d5dac65a657de3cd8539933b914c8324f6c728 e833f4d361e0565303bb34744ece16ab2c5251bed905b6fed0ea942d3ca56236 000000000000000008e9c848038d9970ee3087bfcfdcb20f6e46a33748d58d39 +302400 0000000000000000472132c4daaf358acaf461ff1c3e96577a74e5ebf91bb170 76891c495380e86c73c6f1a2dbc9290914dcc1463dae6289e7077430cd41f04a 00000000000000004402788afbb094e2d5461babe2e208fd3b707dda468971ab +302500 000000000000000061e8a43e26ef10df0378a2682f8bd28e4c58c8fc56499d1d b3b178a854987085a0aa131d7b78cd2e3a189b0d6b64308f1b051f2717a04296 0000000000000000294923eda9f1083d8fadcadb8b6a35341b6bd91d989730a4 +302600 00000000000000001bdc0e53ef4f04fac11fa8e7f4b18bb70fee5e0156a9e57a cc851e9a6dbd9aa7a6da5c327a0bfd85c6cc22e6c711036c66d5117a4b1a7cbc 00000000000000006584871a819f19d4fb9203526ce1dbb112e00e764166e238 +302700 0000000000000000554f80fb9d618d2db3277c4bb7e7905f105d5f78f2146416 b1c5fe39b3806c9d1462f3ef0be0ac79fdd48ba59bc693b9e3c1fedeea380668 00000000000000001fc32cb12dab0e8361d6d7ae5d2bc95b72185aec28be7523 +302800 000000000000000063cb25ed2dd253106847b83e681f54bac5eed6787c2ea3db 84e9057925cea8c89cf05fbb26b0b5b0cc4e32b4772ed8dca4486bed5ee2a191 00000000000000005f674d1b618d3ce71469e8347403aa81225c07e5a74d0f84 +302900 00000000000000005178df48e6646e04f03ddd7039d5383c2249a2f9208a552d cabd81ce74bee58dfc94fe44403a409605d9c2b848c57414e377160a657b54d0 00000000000000002b25079f5eef7b74080a9abe82fb4b981c6bcaa47e330bc0 +303000 0000000000000000599c62eb9b63a08e8a0a95418caff5ec6af56004f903294e edca7d5e6cf4f610d5bb468d03df4a9a8bd38b80dc078f0638f9f659ec730b09 00000000000000000bb02c740323d2a5a22d286e5d5e441374c6812b2111ef42 +303100 00000000000000005a3abf87dd5a202515fdd6a6b3d1723a60b76d21a6565d65 0fae3c97ee7b0b63581e1f591ba1f128a18989f60f64bca9f57809b8a3fda65e 000000000000000007923c30500dc7c0db4c2b6e902bc9b6b41468791078f5e4 +303200 00000000000000001c659677a9bddc6c4f9b5efd3a9bfab1e9e68ac9df71f5fd 9c77d3d64e9263aee6a17ca338f65b4d2cd61bc4c2b026a2c0b00523383b442c 0000000000000000331b583db82d0a219c69f9dac6498ccf1f89b350cf3234e1 +303300 000000000000000028d7674f9f075d1efc6570210dd7d5e52b07b472a1c83c59 b9e13facfd34ee8344571175770a665d7853a9d02834819b54fb34fad96ee3b3 00000000000000004e820173480af71fa1a16247c55f1b77bed3103219d0c148 +303400 00000000000000004f4a1e4174d8c9d12f548cb8d6f2619835cdc958a660b5d6 83b3f878a8bbf78905832fd3b25286b0dbb71226b3c368e672c7fd38912d1ba0 00000000000000005b0674446650b7e5882db6fa2027ff34d931c9bc48ef3701 +303500 00000000000000001073580ef4667dcce4725cb6250f91294a2825eb38bb1d6f cbf746b1c4f505e24740e1feae14b9a48c166c73dd06225f627851b3a5901c2d 000000000000000055fafafdfbd0953d9bdd0e4a5a506652f9a758d22de618e9 +303600 00000000000000004639436eef09ab6e1b77fb34df7c3afd6d1309f99b055ac0 4747d4e545ca3113c7028170531c93543c8fc1bbf7bc1761069789a220ff841a 00000000000000002dc37eee1de50fb7f7af73f6a3b3c6056e690f9b0ba165fd +303700 00000000000000003b32328532e7cf25cdc85cbddca0ce059437183b78932b7d f3272dbe8ca0a7b82175496aadc33454eb5b905a221799c40b0ceab0aaa79d9e 0000000000000000349c044fcbd656ca01f30e55a143c2fec3a767c6a0e6615c +303800 00000000000000004adfaf0f62677d737635d14fc44a767c66a72c0955725b11 9bc33e447406a26b40f30292f45b07c5226e9b6f52c8da4590b1aa5f2e173df1 00000000000000003dd9024c91b5cb49b93776716e8c3755879ef0c3f3844865 +303900 0000000000000000300787fab271dbb8ac3213a5ca29d0d205161a2ed560126e ca089591973a97cf472190d60e9e63e47f9ecc98789010b9fd5249312b67f620 0000000000000000085b41fda8a7f87c1588bdbd4e266322689d0ee70ed17df7 +304000 00000000000000003558a1ceec3f5338c0e887b4171410195a7fa0a81bcaa628 76301fe0e4381f4ac38e0cccc824063509e3c31c492ba6ea75a79fbd59802b57 000000000000000035b5ce4b07d7e44c04d197aa38db69d34707e6887b319f47 +304100 000000000000000030068f158dc9fa1635d6ac4a48804c46c73deebfc5aafa2a fedf55c15069b505fa35a0dfe40261422f03a6e3c35dbf8ce8b7f0133936d118 00000000000000002a478176d531e5e4cc5d597dc5bbe567fb4c692598d56910 +304200 000000000000000047fb15da0f0cfa3674d9084f206fe5bd65e3431da4389033 87790b939f859b8e3255c29145825161c352f718b05b83e8f24c2fee48228cfa 00000000000000005299a43a486b46fd81600a0dbffe2be744172abaea96c8c7 +304300 0000000000000000447956d7d6c78a470b4753333e0add2a866bfbae9f200e7e 6c33d7e19454da701b6c8460d78cd46a9743fc558f3692264cab5cb4af58c085 00000000000000006147875f3dff28d2083e46cab83797db68d36964146ffef9 +304400 000000000000000065f1f8e79ea2418bb497d5b70b710102f45740b0272c995b 1b2532e5bf3f6eb895fce80872222de938962544321ef4939472472f174e9021 0000000000000000282f550ce6cf73f68e906ece4c17545f6c250fc0f8ea215e +304500 00000000000000004328c3a85562f423020bda113677fe5e318c050ab90238dd 3df9bbb9be597e1b4235c576e0db8a0b771d7524e663df142a5689526d7eb912 00000000000000004e60bf195fac18bf6b2d20ceaabf083faf5b46a1ccf5be57 +304600 000000000000000056d280a5d33e36cca6245c61449f8215b21e07b68bfbbd6b 3108f7cba45fa4c5cb0fe4666916f2b7d2bb6d7d171355a23891e41209268103 000000000000000016a4af2ca70ffdb26f4a8eae5b252ab05940580d154d625a +304700 00000000000000004bb9549cc61514446f1d94a539d9f0349e313bb10603692c 89a1f86d368b5e553f3fe131e99c9d7368f4a145e65a81bd27622fa2e27057ed 0000000000000000088d5ec17960906969f8ba9818daa5547d64333b90e2606b +304800 000000000000000043e530e0b5fc6d13aebe1d260c19f784e4cabd1b290c39d8 4357213ae9f8c48fcbdcdeb467e53f3387ad3f1fbb054ff8428c82486045dded 00000000000000000cc33a97f198280963259dc8b4a609b282c373b7ce4157d3 +304900 000000000000000008cee4cbc7fa26fe5ba1b4e09bbdff1af58a19bc7bb62b9a 11c852980e3ce2171fb87f02d3aafaeba68427504643d150dda79cb668742524 000000000000000038ed54ad1a34e137e2536af744bc5b7f8e2f688788d4f81e +305000 0000000000000000142bb90561e1a907d500bf534a6727a63a92af5b6abc6160 241082afd1113802fab9e8fdba80e70675674311168cfa4ba3d80e45298588ce 000000000000000050ad924af73fd35698f68841e1658536e4fce99ec9262423 +305100 00000000000000003643e0a2fb516c6c3ec8258fa268351fddd06a4cd0db0041 e6ce65fc87edbbbcc9a63cf29e9b464b3d802abe15ddc4236bb3c8173790c2e9 00000000000000004536cd23d89798363520419e4ab050a7c6f5785ca0e2aadd +305200 000000000000000012caf02ef177f064090d3046292dba57f1903f020eccddab f6e8bfe35c507d37ba58dc29a380bb8f2b43622f2fb70d76604aa48ed7c8fec5 00000000000000004b89ef174afb1f7a223fc3c29447c9a5a414360bf2879551 +305300 0000000000000000045fca3fc5fa75b509118e1b5ae91b23dd5e36c4983f0776 5b1551ab598e0c0c5ca51d42b9346e492af7f88e0742ba338cf6f9cb96445eeb 000000000000000033b1531dc55800a5670a685b4d9c5e7f05877c6234485a8b +305400 0000000000000000047558f4d2c0897f52765b5f9a724613ff7c67a929c1412c fb40b7437a2ef673a4682671f246e00e7538c93c7689489c351caff2c76d9863 0000000000000000497ec07f02f4a0b8451fd3f7f6d13361ba3bb171208a430a +305500 000000000000000053d32b888c3c9c80581dc9d2f77314dd20f56aba705e32af 886c2cf19dd31386935fde54b68f1592162430b618dcd243c8cec4f188bee89c 0000000000000000376e3d30ab87d9d6dc6f116d25702ea01097541fd6a597d2 +305600 00000000000000002b1055ee8901fc91e37481f395e490285b4a20bb475ec6fd 297a6633f685d65bb5b2f4c5f4bb2da0b3e0ed7bff23e43809d12a868ff72f01 000000000000000008aafa296bb830992da0446ae9df523647d7c6270e90bf57 +305700 0000000000000000532415fb6ac8291bf01e10eda836f838a0327d606d6fde2c d10854f482e19908e00d36af51cbe17532e35a09a42929fcee01bfc6b4975b11 0000000000000000370065b9940776ec6d7144cf1f2f9ddab58bff5622f8989b +305800 0000000000000000096050317d4595599a3dea55a3fbbdcbc96d5daec1abf1c7 c35a43662b54c7a6292dd4fe65b8e75e7cd3c54dc8a3932ad4614c1a3a689084 00000000000000003601d2cb91623c18cc43e35e54beb611a66ba423469a7380 +305900 00000000000000004bfeb30879a5d60820996843e52c1ebd60008769eeaac0a0 3a77f9febb578f44cdaa36da847b746386769f8009294a15656e592d05331ccb 00000000000000005144b159acea830f5d9a5fd0ef1abc2ff5a4ae16e3c51309 +306000 00000000000000002bb3265a8bf67ec2aa436c297ac7e56fcedd4dbaecccacc0 cad05693e31802e84966b4215983d23bf10a409b5773d2efd8d62dbbe3276be6 00000000000000005c3cad291bfb86105e4b7c480f630a2a4752d3277d9624b7 +306100 0000000000000000373553324c67a7af634f721800d537fc98dd9cac6b8cd4e4 4425416c428c9e0e64e916f280122cf195e1ec9bc7edf44aff0c9f79f5ba981d 0000000000000000146b7b08eec7d3f1d1d08f85108a7a4f8e7e4bbbd3546142 +306200 000000000000000010c01758e3f0a1fd25a76a97dd52a40d062c0ce7318acd71 89f2904e22607fb12a4dad39b48b0c63db51cc3bad46b93a34cd79794c90ced0 000000000000000047a3da6e086c98c3c771f535f2f708d9695dcf73cbb67781 +306300 0000000000000000386cdde96e8df20f0297a936b65284067f622e99612a59b7 69862f79a468678848daa840364dd3cc156acba64c811ef55b9b4dbc7388bb7f 000000000000000041cd2630b59464cbb6af101acab056c5d939fbef40e38d94 +306400 0000000000000000589557007d349d8f4407a7bc492848c3d967b1424aae30b5 9d7b27dc3289aac10bdb3e5779a5685f50821256d81ae86916dbb5c07202d9a4 00000000000000005d6630aa3cb942e624482c35713f06e60f855d5a4af27837 +306500 00000000000000000bc3b64e3c417f97819b6194b2f7dc98e862134271502865 379a7812f32bb1880db7fa096db60ed532fe2bbaf7b78ad5960d4ae1beaf3674 0000000000000000251e463ac169e88680b8a93e45d5dcd0ca5b22050e80b02d +306600 00000000000000002b52c65572066a620aadd81a54b93725e56b8a997711edc4 3f766b5a7d90863f77e12c4219d5e46195f69e75ef9b6ac700086cec19c0746d 00000000000000000289d2dae4bc9f631256ce8b2e48cdeabbd35642d84f9dd9 +306700 00000000000000004c626c6e2ce9889656a2dc61d55a215280e42342f45eaf40 ce153cfad4fd0845f80c9e0da4915667d0731c5417118304f301b1b5bb8d51de 000000000000000018ae2d78388e389dc66b3e3b66935156aec331db39c98837 +306800 0000000000000000184755de8a87e6df5380d80b9c6f039ca29c858229f8e612 ff8072eabbf55bdfbe1098009a9cbc37268b536a12f59b149fab600f6d64ac97 000000000000000001fe92bbb4a1f31ec467cf1437fe4b4a547ce1d356db5be1 +306900 00000000000000000ddab4a16068e01eb0d5014f1fc0bef3c4e2d230200177c5 dc29498a0e9b58dd8589fba7c25fb84d8785506ef70ea5bb500f0fd9e6d8311d 000000000000000002dbca6a196a635f36e0108e52be641d258927748f65c47b +307000 00000000000000001b2993a38435de2e7831ee519bfe0f91fa7486b66d4d4651 4f52a960fa57b65a1c991b1110e230a11f36ce59caa78e8ac1ec8b0e40c80ff3 00000000000000001ab84d7fa7c1735d70c1d6f9e77693d2d0b21ed94f8753b8 +307100 0000000000000000097e8ff7a04c1901454dc417a79b8f403e2b39ec3cb5b37c acbde53f5d4434a3d272ec08bcf99003e9d5be1863c92357aa43640a3167a6f5 000000000000000049a41e6abb510e8c38aa66e6bd4af7ce2514a3c7ee2e8677 +307200 0000000000000000391313d3b235b620eb6e02e680161c6d2bffbbf1c67c83d4 b84b4944c32412a21f445c2aaca468ede5560496acc2ab01747fbca99b6abd48 000000000000000030e428375125ba760e971129f90ed0ac069adf3dff458739 +307300 000000000000000000e53fe05a39ef4fa894ef1851295165b2c84996c00dfa1a cfdcc87d3363217995311609fc4a159e5b98d18fc2495b9a93b2b8c0bfe55bd6 0000000000000000500dd2fd2a9fd9e07c5e94cb67f0b5cf5475b1ca388d4ac6 +307400 00000000000000002146abbcb635d8dc526dd12e8ac50ed5af81d8391647edbb 671977f1f56c00fb00f0c2766fca22268c2148374945672acf9587f3353f5766 00000000000000001678d89536f5338b2c7afa987a280940b407d89e195881e6 +307500 00000000000000004375fd207a3dbbc9debf22d9f4d20a6588f49788f645d569 ee07686e2fb3ae935b5ce42d00c07d1d4a2b35084d25652cba8edd2769203af9 000000000000000050952609e0d97ecc277ac5669972238336d19f1cb43e0ea0 +307600 000000000000000024c4fec09b165477be43d3f49c8499ef5a90e519de13b7ec f0e65ef87b07ef38db2099c486bf39222a15b92294f8437ed65e5fbaf45fc62c 00000000000000002cc9ab1a2a6c8526512b24ddba7437d2c6e2be014d33482e +307700 0000000000000000104a202ceba7db40438ec904262b78abaef0553d122c0769 ab948bd1170afaa7413f209253bb45b02cd1c7dc064191b14ed52269d0d93bda 000000000000000014a7bbe57df6b126f10c3c376d001663b5bad16ec8a7087f +307800 00000000000000001382c0e68f8f26c4a0f1016fa002b4518c7b53c66003a517 8e04da313dc6c1970ecf17bb58e0d19f104f2cba159536ba91e875444f4452be 00000000000000000de7bd6c037cfb5a004df64d1fe946226855cf3690f32cf8 +307900 00000000000000003363fb7cea370222e3378096bb7f8b860befb383fb7b5d8a a264d2945ece3ee20d793e3fdf4dec468d7b643e0ac99a42d34766076d27aff2 0000000000000000103e8ac9e08d52b3c90ce4590a47ac1956f532da7728630a +308000 00000000000000001d55aa114bddd81938d09e2dccd432dec59a4078ca0bc0f4 37af0142c4b3893ba68785dfabb789c2cf097581d37fdf56134403c926c6ccdf 00000000000000002584ecfe801597c83fc011536fbcbfba8dd4375eef09e4c6 +308100 000000000000000011d978ebb95821bc8cc4d2b129e6e8d5d35f804178b5600c ca7262fdebca2a2a6868ee7b830a41b2832a424c860b7bd18d2e7f8c1974d6df 0000000000000000025a7bd9044ac02cefce44517537f0c490d458fa720460be +308200 00000000000000004e121b12c8cbe798131a4085854e4262259e87e8cd214069 4b10836dbb27ed6991d8d3df9e4039e6a66f276c46548fcb903da6871175bdab 00000000000000004386572ca6fe762a4fd81b89a34fc6abc46e018e5e9db4b6 +308300 00000000000000004c5f6a337c51207aa775b1c9f158a051dde13bc86286dd64 592d4e1ff4f4191b5d27e163541dae4c193683f6b2668c8e2acf1ed4d5d7dfca 0000000000000000115d8fbdd670b019571335f1a78d47983699a0073ea1afd0 +308400 000000000000000024e71fe782de10db574a5e3880094e5415f08572a9baa698 1ee7b1fb7c1d134ba9ce1c207faf328bd5a296e6e8760d6be973ce5a2e20b831 00000000000000001227e9ddc5bfb14fc7404007ab3d8300085b878221a8ee33 +308500 000000000000000035ab6897acd661e3d3769bfb7f574b4560a8bd9edfd53e01 3ee375ec217dd6d0c4fc1aa3fb883875e2d07d10f46e3b601fd0461a03793e6d 00000000000000003d25fa8be3ce5c45d7f5227d6649e6d5a467d22660220c3b +308600 00000000000000003b6a8b1204475bc916c086ffff8581d1c4f29a4983acba34 ba4eb8c5e87abc3d51dcb7c1c59c06acaca4c7e89074627cbbef55f2a4529496 00000000000000002806fb7baab4332f43491929392b27d22af2ac2b5a6a8607 +308700 000000000000000000337c3d4b54266ed14ee7e9e0cae5e287d1213fb039f705 96a1f4ce98c85e3a631a6873746c1aef26ce1571bc0a6460bdfc14b49770ce53 00000000000000002af6d16a3bbaf4bbfc8cd328a90c97537595d3941960975f +308800 0000000000000000136d76b525bdd88db3e658233d4b79ef887266a374a6c0b8 38b369513d4b05245a1bd8dcccb3598b1e7ddf32b9ac0f78fca50d05913c4631 00000000000000003e74329e61f8e9237868391e4aa9c843468e3355c87c2915 +308900 0000000000000000187b91020b29b9ffd6837ad5506fd92cabdc2bad57e93022 d9b89f0ec33b579f3fc0b1f8326736d7472616fd5d0abc7698e3e60f24ba99cc 0000000000000000046cca966885e7d98da570d7b98177926da2a24de672de4a +309000 0000000000000000228ffe0a981f4e33225eec2d303a8794585bde3d5a6805b0 f67fafa01cffa64a8199d8d731cf0dd5c3481a97764c2b02feaaa4a202befcd4 00000000000000004033b452b31f115c1943be67eb04e32d844a985a8b74331d +309100 00000000000000002aa928ff4115018610d6931fa124215b8010ad8c1b03ab70 4098651f87805e2808025e68185758bfa0eb2d7d54b796c63025d6aa6b6e784c 00000000000000002f9fead56b638d06f876045d230a817a6327955a9aab012d +309200 00000000000000003cde6b9da06361c1cf6b3a2cf5c882999c4fca93dd7abba0 cdac36d01402cf00753677315a36747bf3607c13fa7e8e440590e948fe009caf 00000000000000003da51af684719457e2c6667a51d5fc783707e1db02e14d6f +309300 000000000000000040cda9e9408bcaa5640f227a94955522748da18f80b14535 266fa711bfbc35efd571715313af4e015ba1300b55911c90c4d1dc58ad3de946 00000000000000001a3919bcd0f118e6d7a107b634588e1eccc233c35bb0bbf3 +309400 000000000000000033a1191fb5cc86814ef3c6135cfb42d7e9daa271f064d095 a76d3fae1a253721a3a6a078b14b2dc4d543293408f2a5b24ba971cbe8623579 00000000000000001559d6fc07cc138807b07202de2399d4fa50ab9b5ed18c59 +309500 0000000000000000143baee0e18b4c04ae79a47ede46862aea68e31a9cb41fb9 9b67a1fe3c7b272e13ce5d4486a0ea81c4d0849188c1ef338f46d579038e5be9 000000000000000029d777920429f29ccd3e431ed51bba7c68d12c4ebfdb3876 +309600 00000000000000001da760c78489460a151275376af624a96c1c8007b4eb226c 0667171252f0edbe91797cd3c7f0b90d9c11b6cd0c57833e681a961c54caf696 00000000000000001eb5e8bb0499c2fc80dd1139a9226d92858543d01cf84a48 +309700 0000000000000000221ea93075df0d1ad975767c3dbffd5cf02492e41f9f8b17 e24d2267288806223e71c64226e1318c13a9c2cee353409b102439005acd691b 000000000000000021dc344e3b8061e7ebbc265deba073e2144682e38e9ac77e +309800 0000000000000000307930087de9ef6e2350e2ae6ef1622e719e97e4fb9267a0 6dbb447fe62ec221a1606af3dda0c707b83211d7396c658dab7283ca8e972a8e 0000000000000000056cf4ead7e0be65da08656d410a5efc2dd1afefb1188496 +309900 00000000000000001d92207534963b3d79dc459a45fcd762b130d13bf459645c 76e6f16704573f234bd2f857de5da3a01b5829be7968a412624c09e1bf41ee25 000000000000000017a33fd820671de45cadb0d4492bd8d63170cb7f7318a835 +310000 0000000000000000125a28cc9e9209ddb75718f599a8039f6c9e7d9f1fb021e0 69204701fe16be8155a7f5f08b72ce35eb4d0aa7bbae83f7e1c0cdc0a0424100 00000000000000000e50e42984c1baafc6cf4d3e4d74d37e056dfa79fc63b5c6 +310100 000000000000000025a7cc0bfcc6cf433d8557a8785ff93b660be3cd56db5ebf 65a554d36913041685a85f8b8574665ce73ea1a8515a716a359c9a2a5db4294f 000000000000000029558930fb39b662de0a8ce92fe9a6ffb240f07a76bf0edd +310200 00000000000000003dd638bb4ef10499f172d613ee0cb342067312445b5257da 80244e7f29c4ae145d6c6562697367d3dda03f3f7eae1c9134833e217604aae9 00000000000000002c2086e7d985727fdd26c96bf74b0be5c35ac2a9a2bb3121 +310300 0000000000000000347f0a213c8d4b7bfc48edb91e21927caf053aba4b455242 97501d162c32cc5802e632730fc089cad161a5be80360095c2733ae5efd7dc80 000000000000000000f1f27803bf3ed52894806f79c0762564ad60e2c2df6ae5 +310400 00000000000000003a650576cf11d0293f8489fb0166380db10033440a98252c 6e8b8c96ecfdfc3f660bbfe1a3152b0dfc1fd2dc4542093ed0c761e79cafa784 00000000000000000899980e7817ece5b8f7f3b0213f637bfb546de949f6be00 +310500 00000000000000001cf7e87e748401ddee3feb67dfcb275c8ee328cf7d5914fd 38ca471314129e21f294696df7ae529a4635ff0628edc684e23a45f9189c9f55 000000000000000025ad37914cdd359c4a2bc1fb39b25bd70d97e89b16da1e86 +310600 00000000000000001a8ecb6255fea2d9ffb86c0cfca2857096ace0c3b55a94ff b44b7bcf91ad91493c6d4a92a9234cda6a615103f5e043486fe25c1adf269a58 000000000000000027a1200c0b09c1d0c8ce63252edf3cbd974d8602450b3e25 +310700 0000000000000000302e350523fbcc6ec955ddba229b03ca6b80a3ea3cbf4266 6b393eedf87058444fe25ac073c8d2e538b140fab4eac766ec027da493e7c6dc 00000000000000001f0ce5cc74761eec8f04db94a5991cb4092ec30d38d01972 +310800 00000000000000000608e38cedec8bb028a3e3e8550a96753344115e09c6eb6b 08cbc672bce5b0d92431854c78518e9939fa09e46c5ea55c18fb9cf3624f0858 000000000000000021a5ae173591076ffb30e32b36d255e55fe61502783523d9 +310900 00000000000000000ea87d6c72a702867239260cc4347ae109d5a0812b65c16a 98ca1bd95a04fc9ca0f35261d4547f9e607e2561335665702a882b266b297396 00000000000000000899596d7c730afe553fdd1b838085b3852df8fa7df4669f +311000 00000000000000002ebea165acbaf9438fac8f8a109b3fe331ac34cb2a50a970 208890a5352e71b928ff919db8b357d91b446e156af2fcb0680bbd8d1d9f88de 00000000000000003cc75eebccad2cde872d5b7ebe46fc37806b3ed6e82dad53 +311100 000000000000000003c89a94577e6411fb68c4904b624bb7102ef445398f93bb 357a57d9484861836738eea3e2f7f6c531b5262859321a63b5b4a9689118558d 000000000000000020680013e175bc4298fbc5b2978db5b1c693ca45f42d2d9a +311200 00000000000000003d26221c4effb7484a34a3e1545893f1dff86d9f1fb475a8 8b543336037687daeb883806a7af104b63fbb27c8afa918d173b9e343f3ef968 00000000000000002a73c86398a2c16bee5f9512e86132b1668d550906edfd5b +311300 00000000000000001e2582b8dced2d93a17fb79b989eb02d1cab22f9f2d7c351 3bbe30f61d9057f19dd4997a42f699d44f86d4c65446d7ae998e08e2660fad84 0000000000000000152e3736127a931af466fd079ab56a47545f2d2e40960864 +311400 00000000000000002fb2cbbc9797f9f97b9f0c12710d9a42064eec60763698f1 72d8590291a0c2ac505e2d6c043d013ca1ea38edc8d1d92be27bf580e88bd61e 000000000000000015043008c24e5d82e95eab1885867edcc7155256f518d636 +311500 0000000000000000399eb1f356681b1701a1b3e605250e92374359f7670fb040 99a1fdfcd7bd8fd19639431d1217ec7416c90d4d1ba2e01d22d696414b77907b 000000000000000031360fda6102131bb8662718c1e1273f1106df3465030617 +311600 00000000000000000d192cdcd005334425c726573d88cfa258ef72b53ac99b6e 45136017654583c02b8f140b8fe7f37c7cc8c3de1e963a596f989dff7f6ec98d 00000000000000000c36a854afcd9d6b8c2c5c0c28dd3ce5fd9107557d583683 +311700 000000000000000038730cd937f594452e96b97a496afc03a84fc90a18119113 af6fabc5efd303d5b386833f39621f39b93dbb4d1b78052a037ed2cd2cfdebac 000000000000000023e5de5ab2e6a627b35ec76bff1bd41a44b85c85b67e4d12 +311800 00000000000000000597ec9e240be05c90b94506588bcd8a1da21e7abe1190cc 239f389919d5eb95950ecafada66f5cf39047ebd78e993ffc719e508799399a7 000000000000000003991eb422c6a2f7d7f15ac431293939eecca9863ad3c752 +311900 00000000000000003716894626ddc8ba4ff8df1c29a25a3956e7788812aa5f58 16144bb53cc51fad21651e9d9e87333d6233eb06d1b5b5b4076d02477404f938 00000000000000003b446cbb225a7a2a5e7a5bf3e1cbbf3bfc1454d655089021 +312000 00000000000000002bd1fa27964e31fe9861b40940e7ece2cfa359765b219a49 c7410fb75b20c2ba5ec3935f4f98c1fb81731c44d2b18e5d70ec264e81da68bc 00000000000000002f3e589b149d8143eac0e65221f46ebc81413bea2ea696cf +312100 00000000000000003d848f7c945fb990dce7bb4ad47ca877ff32c8d4a42eec36 35804001350b76d06b0fa65c34442152df5ebb4a773cf80278c6a7f71db5ab95 00000000000000001d2160ab9ac87ddc46be8b6faac58537d92a8260d96ea0f4 +312200 0000000000000000272f4e67afe69aaed25dd2b9e5aabd6d950deb512bf8c351 9a1782449505058cda96ce8e8935824c73dc0e46809744254931a15086e66ae6 00000000000000001eb227129399a1969a721ed584d50720eaf8ffdadcb0bd9f +312300 00000000000000001b2e2f10e40abaf7f091bd0b5183b053a32584e822142397 7862e109633120a1368b28f9bba7b0a69def1f2f90c441696396eeeca13a564e 00000000000000002ca642d18e60e05318c56a3d2fbdfe2eab2593c34c889402 +312400 000000000000000025414ee65f5c5fc6d6c7735530a533769992f3e78457c95a 4d67c63a45bcda092ee05467c50deae81770cb285dec8126955ade2aaa4cf9d7 00000000000000002ab5b7f3ee3a5fda9aa0f312bceff694940ab8414f78477c +312500 0000000000000000307a31b5a588a7e028565a69b5ff1ff2cb572ad2ee318250 d4b8ae40e60f59b92a87fec2bb7b2dea1b4c870b1b84021500478edf5b7e5d11 00000000000000001c2f616a7091e5943723509965a68e9e66651ca5173b1c9b +312600 00000000000000001af96dce9fb5d8e095257955c79d0b41ca64a2d69e664858 539d7e7a2a5fdbf905100b759f4135e4d3dd7b8b1fa97e1d82048eba6680c1e7 000000000000000015727c18c071974c52a8b700bc9e02170e3712f87a16697d +312700 00000000000000002fdbaa7fb514951330f0f613c4eb25fc5cee6e3b814e6cb3 479f3d9fcd65436d06258b80cbaf5df93f55b8598b886f0fd1b6b44b37823d3f 0000000000000000078993425f3a0c365100845b4f52d14d7d083b1d55a45cac +312800 000000000000000024e3f6afb76d3cf2b2623ed6e0760927444a6e2914cf2f61 aa81f99193e0dc2eb456de0bf972dd8ee13b3135e630205483d39d66af517bca 0000000000000000107c6293045fc24b9179aee93578bc80193452a295a6950a +312900 000000000000000023489f7a26add504171430c1e973f732babb2034fdd04d76 09592e7934ca374ef168a396e0736222648c9b388b0afbc989f3f6a6df294dde 00000000000000001acda47d745b84dfb5acc366e8ac39cd09eec5911fd21ff9 +313000 000000000000000018f6d53196c6f51b402a82e3e5c04164b46efe1f33a1fca8 2331db07af284161ab3c4d076f0397632914c9e293500f5af911a428eb7a21de 000000000000000038ecbcf41608d7f6815094700b3236f2f93ead67ac2757d8 +313100 000000000000000027980e6329594ab682f5971a834c4b443ab6c4b23845423e 1937833f5cb220598b7a87a14afcb672efe6dc71e96271ccb944d77f7a76922d 00000000000000001e6c67a69cd10eac07e8ec881c33bdec971e28a88e08cac7 +313200 000000000000000000b4c14c50ff7840b46d5eceb739d15d3f116a0b45232413 e48a86568c467aa3b23f63645d73a24fad92b23dc168aa21b733911030f8aaf3 00000000000000001e37d09ced96da86cddf7f2cbd39cabe87134145195c94b3 +313300 000000000000000008fc7d945b624eebe76c72e9dabb50470b2ec334b4cca219 1b76296b42028e454adf9ab3a8b43baad19c4eac01b9d5e29db5eb40cd4409b3 00000000000000000de9a3e46b06b2d10cada8bfe4d77062a32765da7629dd75 +313400 000000000000000037a1faa0c3569e6427a7bcce8a5eb9f2035787b112fee830 ca6b341efda003a94c231da308a2e12005579a1a25dad40e84ffcf1e2b72b264 0000000000000000110d2033cf0ed670eca3e9776e8301d3602ec9e77e8ccc38 +313500 000000000000000038f15c0bd9ae575530c6f0c397371cde4b2b2600d70860aa 8df3f0eb6f50e9f4331c984a4df831bc520a70a491b5bebea1eabb93b93bf7f0 000000000000000011ee951380af11f111a469040122b77135f1b68bed6608ab +313600 00000000000000000a2f02f055d99014e3290cd78f92fe8beb10a03dd29d40f9 ba237d5530625311c98d1079ebbd1ef80e3adf3cee15ed308eacc3e95087b7a9 00000000000000001c186982a497e9581d0a19d3d024ca95ca9180dc3f31a753 +313700 00000000000000002e49bc3201670d07d7954797f9f4e2e9db655dc86767bf0b c014569c0b3b064e59c13f7a143844ccc4c54127a88e41f060e140935acf810f 0000000000000000244c7879522a659992e59e4a731cd44de0ade460ce945de2 +313800 000000000000000022cda66beadbd96ab428354413a40c9cb72b040017e23baf 34f3568f4479a031300d983ec33261e4e3be5d9fe2445c77ec8fb69633157c0a 0000000000000000061655000f21a220f8c8c6164c712bd4904b273b17480835 +313900 000000000000000006afc5a9bdd4fde0356cfe61ffda33af653ad5bfd74f344d f392213275f4268bd55870073017cf935741167f6b2dabca41b81a1d69a64e18 0000000000000000167e51ba0da2a26a419bf1c265874d614d03474fd2bd6932 +314000 000000000000000008ae6cb20997f3c4aacc50ee2f0d08a0c3691907fe7357a3 2ee84a61a0b196dfe0f683df002668e8ef7a6432787f6794f78a80c17311f927 0000000000000000291b836b50bb1ed8c086095ea8161635655685e42a45c9cb +314100 00000000000000000144bcc4a22dd94d607b972c5f01d89503fb4ef51e26d786 4a15414fb1a75e05fe0d5d5617662abc9378919911f276fb9e6caf74bc35b14a 0000000000000000097b1cc506169dce95026c8c65a9aa41ca51bb5b4a28f67a +314200 000000000000000024f02f2b36461e77c77dd73fdea7c7148f40553fb20cfd3b 797eb69fad154e9a0cbd6aa8f683f15c50116af49ecbe6739bdd9d2f9d32972e 00000000000000001c70bcce58a8e9478ee14b35b13f9570829f4e77744f364e +314300 0000000000000000031c046b0b41004e28aa78ba785cf4aca4a01292888f5556 9175434d414f52e75fc993d4c24429cbd54f63a6132f554206ca657d6bee4771 0000000000000000286e6f47f21ab68fe41df8e509bc7d1e4e3f5e8f88f65d78 +314400 000000000000000020593493b2f6c073f91a6e09733f305cd475a97cafe33fca 01565d7cab3ccdeb8ba2543b7565599e25627d94e603d088842be414a8bece88 00000000000000000829a7d896988d2d3d15f7fbf7770987d5347d5a204786ed +314500 0000000000000000322ede1ba44f9e6285a6565ae15233843e0bc0794a80be02 4b2e5791f3e124f13e3c4163ee4a03ee8d54d9aaff0594ac15acba22d9486e57 0000000000000000197a77e9b17babc4fbb6b7b0d50b29ebfb62b130fc9c987a +314600 0000000000000000002440723e563f61dcc4d909936b0d27034502a89aef8273 e829f8df3903600ddfbd66706bf86919498cf249f7cd6e6e8afd700b7392d18b 000000000000000017dd6a48fbcb1f72f0ca55c2e2d11218ae2d16ba27b7b444 +314700 00000000000000002e1a859b4c1eebcc41a8cb58bc2484c8018869c812a172d0 b73746359a606db1de345c3620c9f9edcb239d8a49be724630426f66c70c85d1 00000000000000001dcd6a22e2db723b60fd7380df16f78ccc30c9ce4d039da9 +314800 00000000000000002320e83fe1bc95895ba8e0a0d9e56e94532262c0f770abe9 ad517c7dbbb606ae0436ddc3600c2565d3e177d312e54d9890dd3b6f3dd5d4df 0000000000000000238a2f7aee05cadbca9e63ba403881b0fb2f777e0c83482c +314900 00000000000000003605f4a03bb805fa535de153c4072ac586d0aea70213ca1e 9f3d3eef79df697a3e6e0b5bf83e3e94a2ad333827c8860c2105e802fe9d4a79 00000000000000001c58b130c164ab1e0800e6f7cc8828ed236f4802760f1f2e +315000 0000000000000000062ff7f089671d68b37fec1c8a8dca03ba466e39ed95c1be e24d8655aeb3e341f39661370602d09aa1a9d214f934ff0c3d42a7b2f266bef2 0000000000000000200edaeaeea351a2d692c3abe671578eeb83fc3dbd4861ad +315100 00000000000000002144ea796b242d064de34deb773a7d86e30e442f44705b41 aaf5fd59cc8a16cd90f9a5a8d5405b1bde7b8f898506b640b3a9819cd5cf1d28 0000000000000000366d6e030f504399f4319796a4d80e9d86e3c33c2976a269 +315200 000000000000000005391ada114d0f23ab02b23b29795fb32e23a731d86e78e2 610ff6697ece0d94a77b92290150767fd5adffc348a795b75aef8f15e7f026c4 0000000000000000320ac10aaa3afcf773cd947246f84e85dfae14aa1527fd20 +315300 000000000000000000ee5ec0b0220ecc9f2306617ec6056548580d8579d03d42 a8ca4c28e89e27e90ef9961cb82096690a936b7e1d2886a841a8d12b2a7eda55 00000000000000001a36a25dcb5ba7b0aed4f6e112f390c19b86b9c2e10201f0 +315400 00000000000000001c5b6828c26949399e8303b0a3cf1686742390c764074909 a18c1f4197ae195dfc1405ae26cc07bf790eceaa4c6a256e43c33e3949cacb70 00000000000000001d48fc0d84ba90e810cce1e2163befbd4f62d65aff528298 +315500 00000000000000002edec750567255cead2efa37de297147a1e19bed6113da13 e7a6f2bfc1e175d19cd6dd9638ba2f9e84d1a9b343c80a62bf1461cdb35b53bd 00000000000000000b27053dfb86f02cc79f6cb81b3721a523af377c0cac2592 +315600 00000000000000002baa13979f10be9a6a7514cf839f4ac03be62ebc69d6ed53 451da049299f8341c9aacb1dc6fb9728ef2b51401444f8c4516fe33cd79c3e54 00000000000000002eabadee6287d692520de24333b28f0563ce6010255656ff +315700 00000000000000001345e4a2d5c083a699329caac457562eba277b654caf3fad ea19860b937357f42b44e97978e4c9696b63f604d8aae553e33e3c39db9b6c42 0000000000000000135765346470390a19870a94faf5d16ec3f2301e4df2aecd +315800 00000000000000002de6f8753e8600e399e8cfc13a484855350422b6d3448a89 8e80991f3bf9c1c5021b920e90672feb2281bb9090b28771a963c6a40bd2d2ac 000000000000000026d2dbc58437901b5e5c540b0b7a26e37ac1a14347968db0 +315900 0000000000000000318c077efd911e444bef4b00b3f500613e5116ecc4b8c276 8d0ebe039dedbb6cd16a5c30ffaf1a413c500dc22dbccbc1951c6ab43c8652e9 000000000000000016de6417884e8dcdea8756ec207094f70008d6740aee23dc +316000 00000000000000000d77a89ab1069e47d1213ae509de95ee0d9ab095a725f7d7 19aa96b4fa1a9a90d0ef745cf0cf297b1b168fbdfdadea7c963db1d6473c882e 00000000000000001c08ce6cb65c5e41420500579753d2249d22e8fa31aa03f7 +316100 000000000000000000a2364b360ea852632697eef72d702443b8a9c5a8c0ca9f 7184398160d2bb57d8cc1bf299eb816a81de77b2a420ebeddca0482936b31548 00000000000000001c73c97d4da5d2bb6213da4fab5dce9fdff71d7eac7bbe65 +316200 00000000000000000841f7b5a01840487a6382eae2cc7de29bd6bd3146403510 bd0f81dac758665c4f546803f3c200a883c141a9225323a91e73cb7b4153cb7e 000000000000000010ae1e430a1855bd2f89a978adbe61b8d55c5f9a74b37056 +316300 00000000000000000a582fa6b72acf4d3439590e68279079db9206b1138add5c 64934bd0dca5c9c77e7dca6c8de3f4c84bf1177995dd3486daa65892c231ee3f 00000000000000003105eaa648125e8ab44b6492b3c3806d2e28b90e96ef72d0 +316400 000000000000000027c8fc4d8555e513832be6f46599ffd8bf3bc00bc9ec2b72 4ada2bfbe392c03cfcab2be61375d7be68445320d09e38eef59c78047e64e482 00000000000000000ed19394728aebe4ac49fc6605ec080ced485a1e96804e6d +316500 000000000000000000488c87e3e88dad4688b5a3bd5281f592a3fdde9874d96a aba54fbcf92d876e25dbd322430fd2c2805351fa93cef9fe7a836431b3f09b48 0000000000000000002d76090ebb4d8ec0bd7be9b9e1e7b99d865638fc0b18f9 +316600 00000000000000000e90dba66b9162bb053df4cc03375d7a0642cef55620f8af b18d37851966991545682a1af031f8d1c8a16273816b6c8631a807590f5aa25b 000000000000000028e708391961e059ed2ceb126df78d7713f1e4d4e7c17a99 +316700 000000000000000014a9f634b5b8c78e92cea2f190ab70ea9f00279befb87dad a0661a11d97b73f1e3a65f0393b782d0f8038fe3477ca29b4ef22b2a6ba03875 000000000000000026eb784e83b2816c3356b10088decfc53d6c227610949961 +316800 000000000000000024b781356cbb9d20ae36a6c084c82c8fb55f1c4947015c4d 309bbc949dc271a8e2c51cff674ad52813665381322c1e2a2032c8008cff57ff 00000000000000000bf26033dce58b4205ef34372417c6d96b333079064ccd52 +316900 00000000000000001a0f14fb5fcd45d907b196c726e65684cc0c6f69f6d3e466 3272c76f8e64f4e24ca2fccce43e3b39a3f23cc12c5af0ec885b8b9122428ccb 00000000000000000cbc069bc47c87db4264bc9d7edd598c39b33ee75858f293 +317000 000000000000000022e338ae2ebd5e3441116350e8ec7f67929973f69038e292 88aafaf3ca0094e5c3f1e012dd45d6f7c92d60d72a0acb629102ef1f746bb2fb 00000000000000000cc5a50dee736f395ddebf9c2775367868c2f3599fe4ced6 +317100 00000000000000001ccbc99f9b1e9b44666735abbb6357a112583f5be1e9b0d8 6573954bb39d2b910b27559bc15eaa71c30f86ceb2b83d6e3d6e8e1c80a12b62 0000000000000000114295618731b2472003cfad73f38b2442b723763523ed33 +317200 000000000000000001f3de7495b76066b12e2f5ed230de371db623b9c39527ad 6cc742743d71801058c33f824d1dcbf880e1a4ae43eb8e52c7c779fa66dc6934 000000000000000026897c900128d176f5468145a014537fabde8e75cd2ff0a7 +317300 000000000000000025d62ebd7cef7609c371a6cf0e54dae3980ecc7105ec847c c49bf29a75dcf81700f5f8087598fb55de07572f141e78433bc64de540982d0a 000000000000000027c3f72e885cdee0a70172ba457f7c475dbadea936536dcc +317400 000000000000000009e775ab03df88916ec6ba568436101ea684d24831311813 fd72cdc6b0ebbc14bd5f14f10556582d2994468d861883647c9e81a022a7c110 000000000000000002ca733a3eaaec2a469c63ef1489fd3a984f895ea59f4305 +317500 000000000000000024ec8693443b0e07026dd02ee3d8790c644c7d25560ed6c7 b2972ef3e1f5ffc67d3258547d008b92ca2c6427b6d1501155d686d4da58e8fe 000000000000000029e172ae9583571cf7e0e6c2ce6ac04c9fad244d9766e915 +317600 00000000000000002c57fd47ef16d3d6b9bf4f8002485c1726a0a9a996cb6260 7216f129a7f71d486e557d68c16b4f01ffa8141f0fb1fba3a9163eccdb62d8e4 0000000000000000041d9ee6d411f77c436d39123b9f989afe781f1e507bd389 +317700 0000000000000000145361a0f12c04a3410500852647da81f2d78910fbfe44c1 5a76aea5aab2b322e356ad758f3133613ea97a8e8b7d22cb737da857f7fa60b8 00000000000000001cc40c79da9326587a4a9db35cbcb5f9020d1aafaf23a60d +317800 000000000000000023ed8e1770d9626583ee0923dc995024d5316fc8da102fe9 b1ba51198f55ee22ee0723bb8ba5646b4457df3776fb3de1cc340d508236c30f 00000000000000002739fcf0def76a7a4e3b4d43ac8960971732282f47e9adcc +317900 0000000000000000046e106a277662e8c99931993103cb9e459a231f36e018c7 a5a9635404c7ea028c93d1a86ab95b2d623bf6faa97c842bce29c1b322265b4d 00000000000000001780d33da7d1a80a9e126eb1f25e2068b09f68f8b67ac826 +318000 00000000000000002583a647dc5f084a312e12bb90a70c3fe1eb1e4d419f35b6 05d69cd55b49d8248b216851ae8a3f495404f034b42da4c629b887f1480cbb6a 000000000000000025cf9c14a1e976f0e2c827ee18eb7273c24a5a4b53d10e83 +318100 00000000000000002a18738c6594b89983e3e549c2fbd1634a461576ca65b66b 04079b07a61d262c0ca6f65f25bfd377c9dcc1d4ea1a326ebdd9e688d662ada4 00000000000000001f7c098eb7b0031a28261892361ff2adc582b368e1c1adf2 +318200 00000000000000001bf6ee8f701054dc35e68fd08afd19ed03cdc22c219c1744 ebe970c3e39fbfbbbf9afb63c663689416a9c6c1ccce64dad4be65f2ad8dd1a1 000000000000000022c7d67b95f914d7f755b2470b0e44626bd944038ca22156 +318300 000000000000000013d3111c3b949925de0006a3c7cf8b1934b7770f943bad21 dd18a0a659c9b448cc73449306f404671c96c9134e5d7ba86901a65888d6998e 00000000000000000d7ca5fae5f0eeff3d8acea11afe6f0d089bc1aac346efd2 +318400 00000000000000002341315d1b4cf8085d871e6bfa956505b26adc187de6f3ef ec5282453f5b17553aa8999b286daeb9e3a990f07e284fc65d8d21e63eb82b15 000000000000000004945fdf3fdba22a44bd3ec324793c5b400b594ec2715fe6 +318500 000000000000000019b9f21c64b7136717e2f5b829187df99193c5bad107b2a9 d27558aec7b058a724fe2375928d1d4e94c1677e567e30a30a70cffcff368be8 000000000000000000c35208f3f0d7da85a82c07dea2630bcbf6c3557dc24224 +318600 00000000000000000dc6afd709f6b7db71c5e7f4392cb3173e115faebbac8799 3fb584f2f50681b513b485db9e81983a8f90ddca5dceec717ac48b7898f419c8 000000000000000013c75859d77d9d9dfab5b57ca25c912cce47670bf9ec7c28 +318700 000000000000000009475cfa73f33c3659b6a02a29edc30a0c5f6ab22e3ad592 8ee12dd8be64fe0d2e1565a7e42c1d9c1d54c8e76ecdd276c6b537962ecd0f1a 00000000000000000aac417ff916a0cf64369d6bc52cb16f39653ce2b6ec3ad0 +318800 00000000000000001b6e25026bc9c2c940f3bd01edc53d3f161019b1036f1ef5 66bb506276d65cd4a9097e8d640a60ca1d6b4ec00e22eb851632da90566414ae 0000000000000000064c458d6a57aebafdf8e2ec1de1f8d9f6f2cb2cc894bba0 +318900 0000000000000000217a5ffb8bcb8c4ca5f2f2c923c4f26b17b862bf4c81f7f0 4898274657141433f147d81388df2cfe066097e3ebb324498de65a37d0c4a612 0000000000000000040b10fad0a47136a3246bea60ba2bbf6bce05d55c8a5eba +319000 00000000000000001a198b049170a5c78e56bbb8f876cec0c903d56aa7dd164f 00111570ee00d3fc1e79d60d48e442c42cfc639885fa8812b8302da768941db4 00000000000000002710592f531c9330fd0c0dcd7c3215b42eb76fa6d7516843 +319100 000000000000000008259704a94280601703af56b45c52f2ae4ee6aa2ce89add 35a33279e8345259127b7165ccf795178ff4a8e39322c15477e5f9a7f0b34043 000000000000000012f4693ef65c38b2be8d5edf0c49449ae2be506f22a8bf9d +319200 00000000000000002323cd51cfc01084d0dcf088422ab661bf5194e4368b887c 5d07d4203c464d8221e67d4d7b79c7092df1466f255a5832cb20500c3c4989ab 00000000000000001302530b40452a9b7966f394e08b607e4bd0956753da5c1a +319300 000000000000000026e5d46b61c29dc446b1054b0fb9727fc71863a7413222a8 745292cfdcce975e1dc8854aae3c8811aa70e32af6dad929b8f001a9ca06b5af 00000000000000000a626fa7eaaaae46d3380a2efbd8101ddcca5f168591cb64 +319400 000000000000000021c6052e9becade189495d1c539aa37c58917305fd15f13b 497e36ad8d3267c9e8b1d6226e8500f63551c97dd704996522db19726701e9b5 00000000000000000e76ad9ec205b8f09b76fcb891ebd8cdebd4386c9caef6e7 +319500 000000000000000000bfee2b5570610a0c459a0ca2ef1cf624492a256f85bb15 08661967f76d57bce443a56ff3a90f09458eae4d8c26492a12af099e7ed7f843 0000000000000000123339b301a43865f9df720269a2f13925bf3a2df59ebfa0 +319600 00000000000000002632d90735943a54657bd6f209466802b203ad8495d655cf 7b5505f4c1b956fb80ce84248f5f2812ba8b9c8ef573b36cecda4c57a401fee4 0000000000000000119053cb42e0fadfd22ca9c62f8984cb6755fe888225bdc9 +319700 000000000000000009939ae830088660a8c11c5f0d358d0f479bdc2a275f1043 52b5c5a71309adf4ff59b0d3cb8d36029c28b0ce28ad2274fccd50d11528c0b1 00000000000000000c2937881ce1560ee047ff195d40dfe07722e646956ddde6 +319800 000000000000000008f342937895e083f11ca3cec0254e865e12711609c59b21 4937a96c1ecf306973c5ecbfea7804f4f1034fa72cdba8e3e3234136bf211671 000000000000000008386dafa7272e04166a8537abfef77a571190ef1b0c6264 +319900 000000000000000005b412182cacbf6d3eb2dba6ef3ae3d859dbb353ee34601a 1f9b4256b23b0978b46fdefeb5803a1beabce6786c931a1382e9f4df0f10890f 000000000000000025c7b4817b79ff0257bf15c4f0006ed981dffdd0c2f5daef +320000 000000000000000015aab005b28a326ade60f07515c33517ea5cb598f28fb7ea bb17eb17ea36d18e4016cbb1793c6c1b04ac32fd57ce6fd2cb2d05a29a473a41 00000000000000001bbfee4521419de4f79c19580027b00f9739ee7b2f0b5c57 +320100 000000000000000020b06f3851e15864a36ad8fef166dd8d27eec706832037f2 efffa9d74000182dbeeff868b54ffd589fe59a169cd60ca2ec494103f750e5f3 0000000000000000097d92797116f8e8f6660ef911fb6b25dd6af7f61f802e57 +320200 0000000000000000213dd5b51829f08b08b215844623785a9b7816011fcdf71a a9bfe512b925361abb9433a1b0cdd089f293b64aacc79758e54b888e9130335e 00000000000000001112609d4da6d7b188d2bf4af13a0f8a217ab759e8d3127d +320300 00000000000000001fc8e2c55ff150ef14839a3688619a5c36206fd58257912e 6075bfb06a35b3625c0af687de84be08e087c5327013eac2b00513743915c56c 000000000000000003047d46847876331bb5fd21cf65e000be7ed3eacf8ca602 +320400 000000000000000013cd08cb3b28e20e75e4065373ca0bcf97d76d0ae9af78f7 839f46091d01004e60fd995dcbcf948fa6d596c8ecc39456a6cccee2e307609e 00000000000000000678e49e8f90ac8e729e34ab2c6855ff2acf43814b4e210d +320500 000000000000000006570f74c4b85cb71129b3e295cea64a5c941a4afd9b6a85 7b9370313c135dc8508b23c0af066cef636d178061acba8f4b8ff7ed44a7c60a 000000000000000019b3ac42f51a619d55265dd05cba0eca0e5b3ba2cd89f4b6 +320600 00000000000000000b9d184595461ea832ca5b579469a7f727fc41876c782981 6d6b500193051b9788d52af302b24eb21bb764b061cb7854aa31d1c23400dbb0 00000000000000001ac6e62623768b4830b811ecbc93087abc28ca5d36644f88 +320700 00000000000000001c62a8e86faf8f65239ca8b81b923b518bd804b07602be6e d172673e38a9063b5b2dd72e05fad7d8c07e2f480241e9dd96673d8faea8d29b 000000000000000002ae2141ae410092bfdb2a967da9523eca8dff0abacf08e8 +320800 00000000000000001d37121534ae0d31f2e26fed4ff5968e1ec208868dd2bd65 5873c5eb59c862b2769bfc2e84fb8e1cef393b553e6238ff62eacd0d0f7b361a 00000000000000001d010059e8bcc5fe58df43e271855c05bf7099be2910076f +320900 00000000000000000bc183d9b58cc83ec278777fd9c0398c10c3a6cbe67bdbe5 3370f81854e65e5fa56c172558861f18cbe913ee302f3df4c8ff3f757f9e1c3f 000000000000000001925ad284e5acc5f76616320eb962a53ec6b804739746cc +321000 000000000000000000a99320bfb427390b074ae144a86335809731e91d4a2280 9ebe3b94aebf32e67965b32411eb85c056800aaceb8918d7d228e8929a7ca740 000000000000000008fdd3f5ca2aa6b35a4ccb653964a676892b0afaa4267928 +321100 000000000000000000e5a4c32d18e3bea0525bbc6ec8590f8841a13586d35c11 62a0c8164c9d088d8c0e6652011b2db2e4a9b81c02c93e6fec92e734de222c46 0000000000000000241d17511cb9417e75db8ddf3b0647e110ec77378d3729bd +321200 00000000000000000eca12a410053dae10c5228bf28b9df298235f90a7a14afb c9acbece946abe0a440627ef62c73806231182a9bd05fad85a3c836da9648b04 000000000000000013366f3b6cb892692cd0704fbfa42a95d3a9ec5ff5db1641 +321300 000000000000000005277944dfc10f5961839cd1595126bfd996071e8322ad37 56a4bf4879f6bf5c51f36c27b9958c2cc98963b9d99826ab747cc235047c8ade 00000000000000001ea62e196c948b22d44448b5204acc1eef8448940b6c25fa +321400 000000000000000005610ad32e241fcd8fa1ab3c78143b8496f8e015befddee9 f89f88c0ee0afe4b4538d05caaff6318308b1fc642b2b3d8001462b9248ac174 00000000000000001588d80f3cb1d593cb198f485aef33ca926b58a62bcceda8 +321500 00000000000000000bbb180d43ac8033d5b1fcac72e4c4c2ba9c3294fc9eaffc f161d56b0f8248eb2ed0499096648139f6c16bf8457c65b28ef2eec6f356e710 0000000000000000242667fccece4f1abd1ece06ed558d69b891b5b28bb144d3 +321600 0000000000000000188e6f4362ce1a2abb5fbff87b8b76fa2ff2ddeddac8831d ae773527c9a66d30a49bea26d6248da909782d65d3ce200b7feb65049d8c3d10 0000000000000000240b7d9d734098b9758327adaf6c42870b902fd5615dfc65 +321700 00000000000000001e670e5aa08abd7283369109cce1d54adb0787fb7b69a403 249ae93cc2a9c6821156e2add8bd4387dcd8ebdc1e306a86136b1ec613fb8e47 0000000000000000045c38374a66ee723e4151f3cd1b1927297b9288ebcfca0a +321800 00000000000000001815931bdfd7e4c300b1e7d93f0ebf74f84119b9f0a44367 49cf909895fd5f8267fc3425de6c4e62f62cd40313dca222a7a9937a67570f57 00000000000000001b6ae401ed50b19a1fcb358e6e578511a5544540cb45873f +321900 0000000000000000003b82d3f5be8c7f98c749f0179dbc8099c8957661956d27 eeb81fc44e653ecef06e9a10cfe81a6b8b8aff189c74ea0ad9fcbe1222b51c3d 0000000000000000187bc8186d790f6b060d4bb0b2eef766fa89597df24ee256 +322000 0000000000000000177da809382f93ca1c4336811e4a910050689d317d62264e fe296a3681559019f0f427d2b56fba4950e65c33917b7d807700075f36e67407 000000000000000009e46e2aa51bfa1fa0e6961ad8ee28b03716fc0616937cb3 +322100 0000000000000000225a9d8d4408981cca28e583614742465c20741628d6ac99 a65fce8eb9fd75105254c33cb3c1760439f627f7ea321daa66f766b6e7119bce 000000000000000007021e69a1a7ac82019dc689206b40d6743ce2740ce7e5dc +322200 000000000000000004f1c7692ea84aafd74afbaf7308f242344f0d1e1af007b6 468dc9c833610cf37888422f9f05f1ead0c4c4afe0a0507295233067ce5c4e0d 0000000000000000104ca4c94c6771f316da2951de9b92d896e042312d9e301b +322300 000000000000000020af8a3d5468dd19d7bee4dc34caf7f8bd65486eeb66a94b 378d8bc71e758b8ebf12952a48f61b7aeaba270d848d62c8866137625acba341 00000000000000001cd799dd007ffacfb455432c9ada3dde7a653f2cc40d409a +322400 000000000000000005fc40015f450092a5cd4ac5077c7bdc59d5ac2a547c31d9 4769cc2c746cba1cbd6ec5171bc55586cad199283e9e889783bb7fd4b7912966 00000000000000000561725cf4f207b38c0dde93414d52bdc5cdbba665728b5d +322500 00000000000000000eefdc7afb05af751319363dfb5d204d2b05a65b6685f51d 1424538ac03e0c5c952056dd08a82721527e582d9973233dd1d2adaf1af5a638 0000000000000000064d1ab77a61da77610c96a7d7aac0484fb43f1593d9d4ab +322600 00000000000000001466e36c4100fe9c1cd934b559d27606c504821254eab73d 0e9358dae85265fa4c636b3e6ec42e432825fc07303b4616309e5972af0058d3 00000000000000000b12e148d457d7557922f9d2218cdaf4ad809b6723fe7452 +322700 000000000000000006294e7447748f138f56e958e8b235b48bcce3cb6bdb1094 bdc742ff4747dbf70763d9060ba5629f7eb55d3714499ae2d61a73c2deda808d 00000000000000001bd81b95dcacae958e2db8db810515692b776ddfdb79fa76 +322800 000000000000000010b2aeff300ab4df14681cc1b5af25551434cc1b909291db e879c0e0f8d48fe06810b76bd1c6274450ccde65408805b8f0325f16ad7c7e2c 00000000000000001d34f09989becf8d4464948af4bdee2c5304714a6dbfa4bb +322900 00000000000000001e397439bf3d592b88ebf8512ae44799b8b0afd081bce976 477293afec4f7651de848a9e31c79c5d12ef12e74c2dced5b53d6d5bc2506ce1 00000000000000000d74144bdf6c662a3df0e637b22d7efe0c9db054e4cc873f +323000 00000000000000000d6b297e72fbee8450f2211698eb440ff622b2b445641e8f cdfb88ca4a4f574d50987dc34e19d91975b5dc3e62a6d66a363c06f1c63fb11b 00000000000000000b57dce0cee03d6d91154e5dea59b046799d0cda53f90201 +323100 000000000000000007cec5daba6c4cdc242c74b71694beb83cadc14d02da3d3a 78c403e5cc8b86c9d80f00f81aa4738f35305ec0ef36234e56c00a4c7dd1ff1a 00000000000000000af232a8e9c8e3a8ab20adfa27253899f863dd9d9b33e3cc +323200 00000000000000001e5d3536b6c5ff0fb20a77091536e5097c44af28163f84e2 49d48fcb35b83b0af762485950909b615e11057036ff1daec6facbea3813f68d 00000000000000000fd9f6d3cdebc6996ca4b6f6492be3b87bee1442cc257a96 +323300 000000000000000001353a516cc4918637ff9bd15547a43dabef75b1143d5f5a a5f89da84f40b0a2d8d3184fd994c74b988732100805155089a532e5d586395f 0000000000000000131f0d15062476e30a4e9cb6ac54314c0ad2af83e09cab8a +323400 00000000000000001b9a86d42d78856f6efa61ab5a93a6419b3702f801729b78 b0f071df4e4c1b39fb141b4c67ad27436c73738eb026220c001bf000fd5c53d6 000000000000000015886424add159a97da7638284fb3cebf28d778cf43d5879 +323500 000000000000000012b3d6bfefc25ad6c0b7a8cee82164b3f3a87cc5d24cf4e5 c832b66d4ecdd98c4991c481de23a4674ba8d74cda8f014d2e5cdb55e319b71e 0000000000000000134321443afca28853a274fa65acabdec95320b533e07234 +323600 00000000000000001cdb2fa16362636be6f99925a7e5f7eead0b0b4962acf0ca 8b4e4d80531b28dbeb190c9434ee7481cec87cdc787bd9871549cdcee922e87c 00000000000000000795019c90be5db755573a33e34d71b1ce2e0e19cc0825ca +323700 000000000000000009af97c7a738e52192548a9c0f17908bc95f6e6722a46c28 a0e5decd10351219b1910125dbd02ee5469dd7cd3d6bec8316f956fd36b6f938 000000000000000008958bccf3b5be90436d55b8f41c1b38fdb7dffcce311de7 +323800 0000000000000000084b0c04a20a38af8d838b46a67e98b75a6e83076aa57d11 77fc4b0294243f4f56ee9a5151722dd1bda3c32e2b4b4cc4ca77ef32154aa2b2 00000000000000001198bdc4bf91f8611312bd1372d6b1f095c42839b61c4cc8 +323900 000000000000000008126700d6300887cf2c0c2254b37116525919109db85b0c 9cc25f7c53297526159b7b8c7a5e9054f1712c4f933f9ed451f659990fc17361 00000000000000000756c7f154baa21d1e9513d06b2226eb6d5752366ea2d1a5 +324000 00000000000000000b9880c40075d763b2a5f04fc01444a6278c5d2d442cda0b ad32f45e27b12ae1861ae24518cf9a6062467d2d18841092489c81933935926a 00000000000000001377803fa65444713dab6cae2c10172727775bb425c6a160 +324100 0000000000000000187ec1bbf79d9c939a1d45542bf6d616a870f67eecfa02fc 528587194d869d3c3e092edcba62f5583a0acd87804b45962acd1a5ce43433c9 0000000000000000107c51d42a607e99c88fca044624d23c76913678759875b2 +324200 00000000000000000c846893ef60552198fdf07a38cfa49707c732402ab83937 22bdcc7ff1e1057ac5c93e23df3346e2fe3c3819beaf013fff5b60cdf4dd1c82 00000000000000001daeee55bbb6c49927905b9e18096b071c67f355e69c9abe +324300 00000000000000000bf013239a264de477188375f3e4deeee00ac6e572efda66 99c51e762f996e42a75bdd576d87cf630b1c3294b4b528388727097cece24863 000000000000000009cbf3dfad4b64b3d5ed27be114e213e9f6f92d2f65f3a5e +324400 0000000000000000036085be752266a3bf2d47ef2d91a0763b3506732b8d7647 c18fdede761471bbe873629b37586e2f6460eccb6a700950b1636f005e3ba82b 00000000000000001380f85fb7690196ae1dffaae738f93a379c2e3982ff1009 +324500 000000000000000006e1f5735634ada4692c816f18ad2b20fbaad60499d03160 e5797be37845983d8a0e1d82ea159403d5008babcbdc0097e30d6a54a4715290 000000000000000016b0ce28c8041730601329d169838ff7f298835a848b5afc +324600 00000000000000000fd58cdcb74cfcdb3dc036cdc9f132483711ea4f78588f06 3e3c8db773ca2927cb6b0186fc6d6fe1a4cdb4fd1b8730415a0e24ee2b56314e 00000000000000001805876f2bd4eb917556e0815c3a03cc9321899d7b1620f5 +324700 0000000000000000023121bb3b4b0a003c4f8c04d9306bcdef5a69a2c110dae4 61e57c096ef168ca34cc2b0f0d7d14582f69d2981308dc8ace53d19f06b556eb 00000000000000001750b265ab60e68ec5503ffad89c91650275fe7938811446 +324800 000000000000000010392b73297a529842eb85491b27e4f82adbc06ea1ae75c4 6fc54ffdcb38b136fec23fa617cc820e48635ec5781c933097ff9361748f1942 0000000000000000051ecfb01ec844584a834c4ef5af13b827d85d07063f7602 +324900 000000000000000019c524da38029188c618c6cba3415fc7eeba3f25f475d2c1 f6b50719446e894bcf6cf9dee7660476c8746b75005663cacedff3d0851262a9 0000000000000000019ccf2f9b9f50e65383975921166a324e11ec53170ca888 +325000 00000000000000000409695bce21828b31a7143fa35fcab64670dd337a71425d 32bbeca2b67533392dad7cddcea9eeb54fdefd6b55c7454250dcb6729442aef0 0000000000000000006a446097f7b1eb970ac12dee4e5ced95ad1a3f38a67a46 +325100 000000000000000007ba4846462d98744cf5409f3e9e80205265b408f40b18df 6a5596e25502c4c3d5f5929af4ce8b51b489abf67eeb51b52f6c455b0d307792 000000000000000008b02b3778619a30336603ecce86396fbee0643950816e9f +325200 000000000000000011964d8493d56e67082587d19e1231cb0088a70797b00616 1eaed9b50bb1a1c778048586d73cc83476d25c44416409ea996f981923f520a4 00000000000000001ad5f971472868eee7fae7a31a7412d386da18abed80c972 +325300 000000000000000001d13dbc2dc3ff8b385b159da3a1969e911c8a924409e24e 75c25e3d5bd754d2d6fc34cd2d842dc9fc9faf096219da31e896521f44e49fe9 00000000000000000ec2833983bd87a333bebbf4576da4720be787796e5052b8 +325400 000000000000000002c336bb4d82470d0a34600d548877a99f935cbe40c9ccf9 3fef6d8983b858fea1f6fa3a7dca95c65da38c0f7c67b693c679ec8bd84ab920 0000000000000000171317e1ba5dee0440c742a96c3c48f1cda4e9733a565bcd +325500 0000000000000000092c757ed018ef84f55271dfcdc5a2435a260cf5e7a07a61 c5ea7a324c9bbca648075a3e232f2a8e4a6b975cbc0c03566519c54c88b90fe4 00000000000000001cb25ac4f1959142633c6e33214fe0efcd797fbb9de32f6a +325600 00000000000000001023b986f7c628ff64933ade4c588d318e0bd304b66f2ee3 c3ac32763debad61f174969f129ea265c8576d30d99ba1377fb6c1066fe62c4f 000000000000000009c0e9a006674860a466254d1128cc685d9dad7efbbdf9c0 +325700 000000000000000011a477cc3d3b74e66e3ff6012e57f03a21d509e1c4b2861c de2d5a33fd4a9ea9267b33eea24bda191cef9ef456f8f5da67cd38e6f74edc98 000000000000000019da5e1ff3235a769b93281ade74108511636d51ce6551df +325800 000000000000000016cab36d6781afcc8c8bf46346b8551a18cc53380533899c a8fc95fbd5f8ddb1bc442ff897073b762d45645a26ee2d9b23d549050ee0e786 000000000000000011745d8c831a2faad58eb9c41dff2a592583f65834d0e4ec +325900 000000000000000003d83fde875c78b5398bdcd94e25a0444632cf64d6b2cd0c 9a06ab119d622ba3013cd67f4779814f4c08be22f0d3a31add8764eda661be52 00000000000000000f3e0247a719d413b93b7a641b15c439274ab7a1cd33b4a0 +326000 00000000000000001e95e7216072cd53353b964054b592f7ce84d3743aab125a 446c8609d1aecd5285f15f74c03714b6df9b51b39e3ddfe9f81c5e526f57d683 000000000000000002ca091c068e0adfa158fadaa03ccf70af7d06ef2a563e98 +326100 000000000000000005cbc66e0a9caa21ecdf4a3ddf68b6cdf973d7c60f5ee866 419c47df19b7709ab6fa0ff9f10813bec79c6054456dc9af75061bb9c32d69ae 00000000000000001a6bb1bf7681a4c2281276f4d6589bceafa23455bf213613 +326200 00000000000000001f0f96013aeb9278d2e6cc42e1adf7601ea40ce713e8b32b 55c2af10cf017b3ae5cabbe1b37a5ab361947ec8b89ffb2f963b489c1cb7befc 00000000000000000b08bd12db3e9c420ef0e3f0b8ab7773353963b00b4dd924 +326300 000000000000000000ddb6a84df0d601dbe4e4ed843e05a16f7f653861227bc4 1e438b8852b27657c0087e2cc65728af93dfd881066569280ccec694dd01ed64 0000000000000000099d44d501a5a68196d4f86d85eb1e504cd0141579a54d50 +326400 00000000000000001a3193b2416a9b04a311a0c39e2a34259f593e9be8f3f814 e57f072aedbcd6559dfa19c168e5d77da4b919d712a60b63270ceb44ff057ab1 000000000000000019c97309bf65f8cf04e95d2b7bb7081863265c7499025c0e +326500 00000000000000001e78e2346e6fb88dc0c028ba785ebee481063bbfcdcc464c d555c2cc2096cd1d844f6f44f2c9c3b7615bef92db01121420c5672d25c98a8c 00000000000000001d084052bfd9b5fae1da9e3fb6bbb4d5788ccbcb339cd398 +326600 000000000000000007daad9bd59a185c048a21d33e66602ef0190d7a046a55fe 1dea3d6125dabe6bf1df6cff98e3aac5f594295ea6d938f3a4a5e0de11b8c6fb 000000000000000013b9cc838fc223e2afc907122eff6501a463008209e959a2 +326700 00000000000000001d01114a5082ec0ecf0cab8e419b855063d19055e6465ee4 2e36717a036158fd7cf965a312d682cd9347a2647555ab99cc751b1f86c4ce5e 00000000000000001954f3813605bf4b7558bc299c4922a6f080cb75f52873cc +326800 00000000000000000a0aa99b870e2f0977cf3ad343b205ea3ec851755937ac06 8998b7ca37da678ae2d32a5ff75f2b9a78686de4fba8f36b8a68aa513bd6940e 00000000000000001ab99837caee498d6d84e94f91e32b0ae0ca51dc46fa2d92 +326900 00000000000000000fad57b2be15ca765033ff9a24254c2f67453f29028414ba c67d07f94b2ae5b929c8943d39e77dfbf383c5c612e481ee12469cff1b7be07e 00000000000000001ad07221b53554b5960f95918bae372c5ca27edc6b0d899a +327000 0000000000000000051919e9e16378559223362ebf0ce122f7adea509171171f 1684d66cbf8de2f33eccaab912a3da131b50e27ee9b19b53ce03f0c54f064901 00000000000000001c273fafdbff1381c32b60a836c026bcc58cb93d2e0de295 +327100 00000000000000000b2ea993ca333c4e85e89bb9df78dabfde95987c3c2fcccd 50dac5fc5fa48599758245f0832833325363089762a31b26ab568b4a2d07a236 00000000000000000493d65be5c5b2fabdfde93f68a32f698446cf2f85f7824b +327200 000000000000000000b9410de7e26844536dde1a410cf21f82b3762acc2fdca6 6a9e1a305b0f84f523a3581c712f4633ee9bcf09cc83f75a3de590ecd7b03114 000000000000000000d533b162c6254a83670f491b93e9a41b3cfb2cd803012f +327300 000000000000000012386f32468f915dbf60d5798fd5c302947db8ca90066907 982b80fbb12a651281bd956860bdc5186d17274d242abe6f220a50b82f7564f1 0000000000000000057fd244d58293b35836bd1ce499dc9a99ed7633e67ddaa6 +327400 00000000000000001325e8a773f05ddc0ad3e96f97434e0196e1003917f9982d 0a971c6a2bc5c1f453ef0d42dcb2bc89fa1cdc67d74beed4e4e3386ba68b9353 000000000000000006342be670906cd9f835a0fb6fea42b967d535c68ebb085e +327500 00000000000000001aab330c2a92061d0e3591f580e1e76bf7ff8fde1bbf0f60 088cf8d5aadcf5e6b3ff094c9eaab184374cc7254e88caa02f990c3f761806a1 00000000000000001957edaf3db4c47b4919f8f10a938ac2e36c3cd285ee3daf +327600 00000000000000001a0229d6a88ab0f93856f18f50b84bcd0e9445f0f7db0890 05a6bdb51d587ff5b4800bbadcb9996509572b7e344883e57f9fdbc96a863540 00000000000000000ebb10e5d24ede583d7b09e87b7d575f0bc5023b4bfa05dd +327700 000000000000000018520297bbc07b146ec423f43e79a370442f1a6826b79ba3 d0e8ce1351f8bc29f70b7889a069c36596158be8e5ede384b503b1e66b5aca5d 000000000000000001a066e97ecad67bc8213bf3aa40896f04670a9deb53b7b8 +327800 000000000000000016c1af15643ccbc89001a5fdb6f74eb5df09851f982d1a1b 68e511df80c160ab1789264590ad560bbe0148a115f81dc7b8865430de2dbef6 00000000000000000ef7987e22204c5ecc5e0071ab4f4ebc5762acb7cf17f025 +327900 000000000000000016fd3d3478ca0663fff1e13bce02b1b69ef015830568e713 a3a2ad6269c8d985639235dfffabe15a0268aaf546f786e5599c1717adeb4dce 0000000000000000146813714448e97236698f3498da1be477c57b10b2f37eb2 +328000 000000000000000009cb9a303d105e7b96b36546a3196f6f79ece4b43712cbb2 1093abf16996661b18febcb9e38edf603a29da32969cdb5dcfee249976a669f7 000000000000000010139d8c1bfa1933154b6ab111d827736f704cf91fa0e322 +328100 00000000000000001b2a69ce83483bbb1c7020d7ec303dc154fe31651c031193 985f016643293c5db2ae33924a7c7e2d7748e413f9406876155f878317378b7a 00000000000000000a5621b453b2b455cd54399255d859a9db56d5953f688000 +328200 00000000000000000e8c5bfec3a6b5903aed55a36cbca680ed8580ab05360e94 889419031c383672b801518187c0ef4fe7a047c1c1a5ec4f678d9a9a695ad03f 00000000000000000e1f5d6fa4a10b99292ff0139881747528de3181bd4e22fc +328300 000000000000000002a34f2ce1a2e1e5bdb748a7eef2316d7e7d7d0fd0365897 1d2fe02a3d5cd7519484403f91a74541c3d1fa1c8798dcdc8bc9803cf0c71285 0000000000000000101f78e2755ec6e3b767c0c27bc074931a6b59e8cdc12008 +328400 000000000000000010d0295487f0b5a4e0090eef7d45522ae1c9775c97457466 85163728de74aa6f716106f1e340a62bf4f732f5319d3769748e809e625b8e38 00000000000000001c5742a912f23a40808a828a455e2312e7b4d51348b4e04d +328500 00000000000000001934151558b1717d8052caddc65d5e34d5e86401bb3ce096 7eb612f28527e138814377d1865c327a9f116d6ec372ed96f8b684d630df2448 0000000000000000134aed3c5f89a7aa5d3a6e1fedaa895486f57fd7ffced47c +328600 00000000000000001933eb4068e920765dcf0b96c4993491b60970c539392d08 26b1e7adce6b63d9e5203b315c4635a57cb93d8576d8dd221acdf1c7a9ea75d3 000000000000000014d1b1d4422081a8889fb6a3f4f395858285775ccdeeccea +328700 00000000000000000ddf21446d44c3738b36d79eba3657b3f6337900961a9fcf 3e4560f666d7c826b5f90f230f59fb5c0457ce25ca350f8dd5c43ac102c9af30 000000000000000011bb61bc7e9778ad9dce9ce2b7105df0796bff78ce8b8518 +328800 00000000000000001997e3aaf4b9afd5e6beac1175b727a106e3b75a1cba8df4 f920916cccaff061f902bd0a5c96b65231d2c773361cf4881608a835851e50e3 0000000000000000152dc55f27338b58325f0432d2dc6edb90c8d449d9959583 +328900 00000000000000001881feb2d9e9cc3fbb2206b5254ae9b76041ea9624197976 e3a7cc306d3d4bf18e302f3fc78089ecac270e839759e0dab2a7a277ff32a9c5 00000000000000000e9355d21144057602096c91078634aa3aeec0ec6260e964 +329000 000000000000000002f56605f982bb5fbf0dbb6efcdc155abab0af7120768446 c8eb0f37f71c04e0ce041409efb0375c1aa51a2ae8f9ef175495d015ef4ec276 00000000000000000b5faeaeac8cd0c785fe347d5453ee71cbe1e1c5ddbd4699 +329100 00000000000000001836424e8024ae409feb5254ea0178a981039bed3c604ba8 2b715e58bfecbfdeb2f539d05d092a384d0c589de9f301dd26906d2130113f08 000000000000000004b95a517e8601dbe83d9d8c39908fbf535718d1cf73cae1 +329200 0000000000000000184747d1735aeccb56d455a0c0300bf379621e1318243157 dafd1513188723cbf4e1ba37f026565144b794b99b9157689abd56b4bc9e171a 00000000000000001b7c66b173392d1f4c39cc2facd882992de279dc39c0884a +329300 000000000000000008dd51e505d5f459ebd5795aaf2db2fb5ab22bfa57c88984 cc36b62009ac19949642ca8062971a147dc406afe3d1a7363ed9487bb673c0d6 000000000000000000e0051a82878d9b7537e4f4bc7e45c347a10ccb0953e231 +329400 0000000000000000079dda7dbd5e7bd8c6ee2583b3d74331c5990164b29a0573 f31852f16934dadfa5f1a7add019ddfc821a2d0271f68c3a686dc167283fb9a2 00000000000000000c2dca25d058f0234fcf27930b0b57ed7c61d6d482256c9d +329500 000000000000000007f746a912ce0ccebf61e21011e5bdedcf1ce528c9df60a1 e3781b754693b0a9a7984e65d46637871bd13fa66c777cea5e4be1078c0916ba 000000000000000019963aa4bbae1013171a01c2aceae6b7e537a2f3d906797c +329600 0000000000000000142eb0886ecd6914b7d4a62a16db938105e0f107d4bd7cf1 f63cde10debcde651ddc5d97e449157dff398ef94c54651690cc499f295893c7 000000000000000012e39bdc051691a5d925958f49b805154e58107891da8066 +329700 00000000000000001a20824147e7c19f4c8984ab714b00cd43d3fbb535274397 f771403151b28b910e04aeb70cbc0494f8aae9ffb7125d5afa4d1591d1e6949c 0000000000000000192327876fa826ac2156740111a34e614a467b0ef0a2f20b +329800 00000000000000000fda93caf96e424667a4fc20f734bfb134fb83c816fc9f0a 915c352a4fb2cd0d09bd83055072487dbb132c07e3d076fcf0d8c91bef86b8f0 00000000000000000a3b20df2d03dcf855e8df3dab2dc65de87d6f5ba8d29f0b +329900 0000000000000000052c5828c18590c0411926236e1a6f59538f821e673992e2 69e5834dd0d2b42abc756e50ae8cf93eb5d4c2b4896e10539e7fc58d67474b5b 0000000000000000065aa64226011d93e0e865b81278e47a96172a610f5f8f99 +330000 00000000000000000faabab19f17c0178c754dbed023e6c871dcaf74159c5f02 c7a7bff270c772862a8c2e13c30c27d3c7dd462d8825d93a7edc0a9f14e1c826 00000000000000000271d56cb074731c2ffe250c9f9482ba47ab1a898122199a +330100 000000000000000001dd7598187ef9308c88093faf921416462df9ce03ccf417 18ece064b1802620893ae4aa4a945782e7e0a48ba980e115fbc54993eaeb7625 000000000000000002678aea566b79c5bf5d04264f17195efd95651358f291a4 +330200 00000000000000000b910ccbf1b699667249202fd2155f83b541b96c0e141ad9 1505c590cc9e95fe16fecc1b3d415ff79fb02f55240d592aaf3382093015d58d 0000000000000000196f9003b27f30220825ca5a00d94652f098db8e7311fc3e +330300 0000000000000000102300d5349d22ea99c80717d17c1200be01e7f9afddc39d e18d7708bde2ac93357cf7ef0bd59d9c95cd1a0202651dd23f09f46ea1a691bd 000000000000000018ea97b317b5fb86dd4694a2dbcc96418f60a77ac7167bd1 +330400 0000000000000000098489f89ce82579ecdec919f9a4f5839d6cb6ab8066c4f7 03fba165b2d63b38aba44416582600eb5235e7b76c5ddd8f76604c7b81c037ac 000000000000000018c41597156e39ecac7065bf5057905895bcd151d0b5ea4d +330500 000000000000000012b4fe35435d99a1d6792316a1ece45cc9d0cd03b1059576 047c843d266d44be243cd5f8114c12fd170c595956f32652511d62ef80770ec3 00000000000000000616a22b898cf2af90930a900076b9deb1657f31f9bb20e1 +330600 00000000000000000f53b6e393e48407e8b9af95156aed00fd68796098832312 c6c01f13622363a1353eebee5c1fdd3177e37e0379744aea1ae0d9cd434b814f 000000000000000016a176df3a6aff16b2484265676c66f1cb77ca77ae728357 +330700 000000000000000011120a5eec88e0f00e2869afa319e2a5805fcf466b0089a1 57798c4bf93101e1ea328d0f04a4a981bc33308b23714d84a6c2304d7f7be9ca 000000000000000002f25a17ddec9e55a4f07fb7e5a4ab58a61594f5847327a5 +330800 00000000000000001a6cb4061892a2c32fff4f0fb7df52ea12fdf2006c12ad99 fba901345081e3fc29541f129ce0d1220e22fe423c79c6db6f93296db9b7e781 00000000000000001355a094b89bcd1088f69785feed09a734c845b3146ce0fc +330900 000000000000000004b1fc128a5c762ff3c9fef17eea1cfba6d1d088ca570940 4a06714ad3910735cb44f01085d296339ccbd96e5707d4c249c0abd8c191249b 0000000000000000102d16edc7a4dd2969798f9d063cc39b47ce95b7fdfc340f +331000 000000000000000011d4e851863618a3e0144b0c0ddac35dd3a9f19498435ef5 83bdde73c956fc4b190a7b2506c201b3278bca3acf7165c4324ae550943f3ac1 000000000000000017df527b102f23a3d87bbc038d3a1990a4217f4e5711c7f2 +331100 000000000000000011357973029e3996c85c271f6be3d2c383b7a3616858ea34 f9d9c6379326750cb758a1b5cdcfe4a52d76ebf8c7b71c8e62d3efaa5831ee48 000000000000000018689b94a9708833e57902b41730efc437b6d97e8b75bf51 +331200 000000000000000016fff4bf3462e320065497851dbd485398a4713f3213f191 39fb1d5fb34a7c6e9e98d8d28df82a0b6089699d3fb0c4b0798c67c4f9231415 0000000000000000158d813b21ee716dcf569aa5a958fc26479a84916637faa8 +331300 00000000000000000fc97874a170052de4ce39db1edfc03803e673fd2e9ddabc 38f67e1519b85f61f6edb342a95f6a0a54010e33bd342a49e364c98d19c7be36 000000000000000005496eacf77858ee0cb5b973d75c26a37bd095f725265700 +331400 000000000000000011bcac76476269901070be0077d6c59ad2e35ca7a2e176bf 66e1ccc7637aa00b8dbf8fa3f76e378816f965e9af57f76483077c716f81f328 00000000000000001088c5e8ebe8daf577fdb80c233ba0f184ba08c0bd9549e3 +331500 000000000000000001aa46d2e0585531209c62e39ede8c021a1b11527ac5c95c a389eef7dea5c5d85ffd5558de894456d6d724821715798ca67c578593781cd6 000000000000000006c0a8245705707b45312e900b6820f20dd21c48ed6983f9 +331600 00000000000000000544b43519b3368d5639e7a665c8501e6a5bb2e93b084b0f c54aca1cec393159a002969d6382eaac64a9c6e0cf5a1eddf0e987af1ff0254a 0000000000000000171aa0004add683538d68b91b6706c1ad9fef6d927336aa7 +331700 00000000000000000f5d59fd77007e7d553472996fd08d41c04639c300214335 9175369709f5cb04dff3a4fe77b894174ff5bf0f90cb68d2fffefb03ceae7539 000000000000000017c3b1147641f4da4bd5199919eaef4e958a868c19940da0 +331800 000000000000000019bc57e35368a54522244300be19dad09a01c930e446ea61 ebe983d425f667e022f3f406906d27e933bb049741d0c23d345d3df776af0b0e 00000000000000000dc50a593582b1da4ca0278c81dd4c21d720301fd7342218 +331900 0000000000000000084a103a906b8bab87dac0e1249368569bb5ee714a1e52a3 e2fad2b77811eec299c222f951d0004c96682539d0ebf1c1f712e8a1b227c5de 0000000000000000077c500e69c15426d512f2cb6bce3ab94660ee0010a89460 +332000 00000000000000001799255bc0c35f91f7d4fddfbf7e84dedf94fc59cde9b7f2 a73a92cb4a8516e7fe014cb41fcb4063351fdf702db82d6a79ca6cf10042569d 0000000000000000084f645a8b53cfa7ec7faee3fabf3d1a853152584aa9c2c7 +332100 0000000000000000198ad3e118fbb6005edd34d1803dd580fb13b4983fc0760e 7f8bfef6c46aa024de2a21dbdd41752ca52820200625320a317a6414b258437e 00000000000000001a6f7f62f91ce89b9ae5dbad7644ae7b848b740a3a22cecf +332200 00000000000000000ce91a48df64a591ae9870f06e84a7e96ea2f9694e2f58c2 c5fc95d4e01329ddd4b82a39704d06633b70afa8d4d7f337ab9147f038aef6a1 00000000000000001856a18b4d56f1af4f5d04212788922008ae078fe2d7d13d +332300 00000000000000000f1a8dd53bf2ea48426072f674e8dc0c213dc1effe765b11 7fe3a7201280c0d88ee13492d0dbe80fb0fd426393be15c409f84815d80497d3 00000000000000000739e8f902c0aa50ce9603eb7898e5ab2ff44051a55ef189 +332400 00000000000000001328cef2bcc50d7f5f74a8154341f445e14a4ce9865fa108 a78bcc6fc3bb5eed206e12c544b6390258b654c8e5d13f20514553057a5f879e 00000000000000000ee78f9305de73c5f505ff6342234553f44503cbef36eec4 +332500 00000000000000000a86b821cb0bdff44f41de617f0e3a0883479d632b752e13 c4a4ac3edf9540fe841bf8013627fa73938172f820c12178106bad8ffa81c4e4 000000000000000011916c7de143652cf6578fe05574c35b01218c63d1858f97 +332600 0000000000000000157e517918cff3eb1d3758485a5d2c1eaf77803d08c0eb9e 46f8cb8c428ee618d33e47acfc776ceca6617c66021349f75fa67582c269d8ae 00000000000000000c79577ec55b1a597b388cfbfce4b225a2f3d348b4f06a54 +332700 00000000000000000b822266b1482cd7066f6e3b1b25efca74ba978c834ebb3a 170e50843d7cdb6f0a92f37d76f912df999e38a9c370eb9f0c469c84bcd93220 0000000000000000081ac26cb5200ca59a684970b0416a1839295f2a14108df3 +332800 00000000000000000a59590277f8491f1b62db53388874a25b8210f31c1ae28d 503ce0341d115f355fbe3dbfd337b171d2b66fe244f5a71c4a4525874644aae3 00000000000000000792a44ad057029301f3eb593a8e50c3805ffae1319275fb +332900 00000000000000000c8ea7302dc7b7abec1e2f24dbc06137d5af1c53a65439d7 5111609e7ef63bb7b47a4e508dbea6f1b92ed3594ab2eb047091dd8888366fb5 0000000000000000042568aae3c297f687caa1b7737d8dab8e7d7b5087fb87f5 +333000 000000000000000008360c20a2ceff91cc8c4f357932377f48659b37bb86c759 3c63f32ad7127a22ce7c6813d58007e61060cf26c7a6af5cd3f2da9ceba95543 000000000000000010e318d0c61da0b84246481d9cc097fda9327fe90b1538c1 +333100 000000000000000017f22258a72671c378a0c7bf7634a15ddcd053b0f1d6abc8 57e9dafc966a4ae1224afd38b2f740d247395338ff098367302d272669972523 00000000000000001140229c8172692bd34a62ca489a74c29a9d34d98f38efed +333200 000000000000000012be27a3e92890e33d56ebfd71e5b6d49eb1371464776123 63dc89d48f8b65ea98a47f931e43a4f6a824acbbaa5c57a74e6234323439af4e 000000000000000019119fa69de84163036927b493e9992d46623763249d51e1 +333300 000000000000000010c54e7041191bba1d31c9554f64bd10a844a0ce4303f3f2 f689d5c6a0199d7f75fce2a61c2178ecd6aea5b554bc66d0439610d9db7c469f 00000000000000001a7a3bc7dbfba0adf639fdb6ed430c925d381c6b81f703df +333400 00000000000000000f51a670a8b567d9e596c8accfaa5d3c2af910d44ca2dee0 0e3f7954a4f795ec97c5b6f7e28aeec2cf6f4ef05fc0f86117f237f50d56e27b 000000000000000003436e7083d70c53d83bf8af14788a5b93fac10e53e67824 +333500 0000000000000000109386c0814b6d1341253b62a05f839f76f918b5ecf9ac44 5e73008a6edcced8e9753f0bbf73e59607c3cef135a3b95bd1e70cd7ffe20230 00000000000000000eeb84f535b3b86f1315c510dbde3704bca75b78bcf04eba +333600 000000000000000005eed58f4ff959d183d087dc9f9afc64bd31970c1fb9d9eb 6ad33241ee38f969e615521e9e805f46d66acfc1172d8379f077fe9dbcf0c8ed 0000000000000000030ed770eb64c39f4d4e12499bde167f9dc38e05cf6c90f1 +333700 00000000000000000b102601d4f83b876f28e492f98bc2da889b389bcaf2a1af 1479eea49070c4c03541632132fba2b7b047508815f08f081370e183bed28583 0000000000000000002f6f33685ca1236f41303f808d0c2769a3528291640bf6 +333800 00000000000000000b6f747c3508d0e2eac0127b00cc9a8bf8745c103468c2cb 96069fb57f2826cfc0ca457e9c468110fa60bfa90963705b0d0f441f0bae050a 000000000000000012b215a151ba0070e96a058442890fc627aac0dd595b2f38 +333900 000000000000000014d77722230f85beffbb547bcd2c4f03e1d2e85516680b4f a01ccba2e71dd10775c1e60cb75613478239b499cfde89bb91197997689bc97b 0000000000000000186a65031acf74f0a28805b198330927fb770ee3d885dfb2 +334000 000000000000000008d1ff7b7673837e9d7e1324dc7ab8498405ea583f43f53d 2fe7af8d17200896f16356ced22e780b72a73c7e90aaddf46360fca3ae6b5b09 0000000000000000199cd3ccb5feefff667d6ade51eb5e92531018d5b9cf197f +334100 000000000000000011d127820312ad1fc2e7a256200349b7ffd29da5544ddba6 be07bc967f2d19b4daf45b01eff366b62d99ed09fa4ce6e93bd67d6a4398630c 000000000000000007d1b0e68012a912a91602e932deba53b6098284d76ae026 +334200 0000000000000000013c0901a261493cbcbd6e4417c5561abf5f7afeb9668911 d1c77052af7f8dfc598f93c4feb34e354f5e2cb751b06852bbe8342392719569 00000000000000000a4bd85ad299c3bf00ee1e4edb51bd1755e908a469669109 +334300 0000000000000000164463cb40eb751e45df6b2cb9be314e9c216a50ac8a6685 38e6688ffbdc385d2bbe9191cefcb20b1e08b3746e7f024c706180d20b34e381 000000000000000016ef188cfbe1ab818541c2cd55d16f31cb2b023fd5f47ffd +334400 00000000000000000f61cc5301750050e6d51d15626ac0ea78a8b5c89ed9d922 0b802dedcd4c3373bde74838ecec0e698108302c817b6437fb211b09b502b803 0000000000000000094b18507ba72c050b4106146234fdbe3c8cc702e702ac9f +334500 00000000000000001807b48379679d4d2c91053dbbdfe0a72572e7afe80dba2e 4593da044f0e240f453b67fb3fd9c69ee0c294de03f792047484febeec1600ec 000000000000000007e7ae790a49cb4b62c7c984b63cdc5adb4f20f362657297 +334600 0000000000000000195f2f725da5e5448d6840baad9762e19723d5ededd34b22 7dbb32d6f383deaabf6476319c4054b44f40f65c954f003576e0e53f0552ada0 000000000000000013fb20f74032fc9ab75d2714e2ffa552aeb41387e2dc3da2 +334700 000000000000000003c3e45a6d16aa654d86db6d975c6ef19521be414e59abe9 99cf431eb24b5d97c408f632e62627da6a214d53214d7dbd92bb7e32eb36777d 000000000000000002e449f776e9b39be077b90644e52ccdee9642b84050a1b4 +334800 00000000000000000ae21f19d6c8dca6c78efabf2bc27397aaf595bf89fe7654 382bb424efb140e0c287f01d69c35676cb504feeac8482c868176896713fc694 00000000000000000cad6efdfe74524f110ba99628b22d7534a4ba5e84eb0dc2 +334900 000000000000000001c3d12a3d695800b880f269e3331d196e1f2a6180eed13a a0c75bad804a552e0f569766550c11d517aa18a7327e63d2e37b5ec01d556cfa 00000000000000001664c0befb3efd744b98ecf9a529ec6c242024f849ff6de3 +335000 00000000000000000f774c42a2622807ec8beae7f47f4043d93d798b9e7740e6 fff58b4a488690efabb8ac3ab8945869111769d4ab8ceab267dd13bc808ec0da 000000000000000018517a37b2dad7aa9f087cddda6fd2acf63d939c9c59a9a6 +335100 0000000000000000120198a0b845d223877bafa954c964bf971815588a8dbd08 d6c5ef105b204088c04b88316f9b5e419038a956b1e2b29645329cd9f6145ba4 000000000000000011399d908848f9a7ff124195ffea51eab19c37c08aa63f65 +335200 000000000000000000c879729eae178096b092248706a407ec1b18eb62a792e9 f9b73a289ff342d5cf29918ce7d3d06343e3bd0225b0c6e2ab52d5a251a5346e 000000000000000012c15ea1dd0779621ab119f41692f5c6a1364d6adf9554c8 +335300 00000000000000001a9b78c923bf8ca40d3039bd16e4fb04e29cdfa241150b49 488daa8399d39d90956f4538522df3b0f2a9063fd713a8411d5ef3e96991bce7 00000000000000000684a1abd41d4ad0ad859e9f5f327438b16a3088b030365d +335400 00000000000000001b2060125722a35ae2652e6c4633ead9a1a479951b65d401 5569868e1c9b78030f91d01d0e93938a5f8cac67cda0e9df105b743a3ef1d3a7 000000000000000006138c3f0f8b5aa7455bd9983b719aae05fe4397c3e600b2 +335500 0000000000000000188c0a8adfe8fbe72fc9155faf67a6b9587eedd8caaff7d1 334ba67ec1f4d5fec178ea0f73b7d16e4120583e893882497da6838f751a48a6 000000000000000009bcf2b9c77798e7b5b759e796d750718a7d968527830768 +335600 00000000000000001409d0e9fda7dac28d7b417b29558e31b813ef4d1e9f3a08 4d4fede0876c1eb803867da55020ce56fb65255e276ce35210f800e30315a013 0000000000000000168d81c2d812b65670db6d30f028f81002e0fe8d1f855f63 +335700 00000000000000000ff15fb7af45d5d216eca5d3b4ce45d0ab3fc253f0682813 d521fef6e8b887a318254ceefa36cb3b2ce998531db94ca894c061af0dc8f015 0000000000000000032abe2fa09e8799f42c9424463561e77918ec4d797e4957 +335800 00000000000000000e77e42753de49d95e8e86bb45e4cab703d713f4639e3aea 28dcdcd31d602ab690b0dd2ea29505c2ac9242532254e2932e35571abea36d58 0000000000000000089f2db5f701769abcbad3ee4e2a4a61a056969b86788d1b +335900 00000000000000000daf17bbadcebdc005560a9155252f2a08d2b929637c68e7 a365f9ac93e39cd13da5e137615250edf193ff5c347307086de4a38f915d0206 0000000000000000143ee1f68d064870820590f875e429e8add23c6f0ac5f919 +336000 0000000000000000125e3e6f327edcd7163b486efc16e79b8a996270127b54df 41a7699c59b8c599ebc85e119e4694033b42f5b7d6bd8b09c69e6a2d95d1a89e 000000000000000011bbfbfe73d56175a1906ca1eec461876887123e3f69a42e +336100 000000000000000012c53e9b5a0cb468c11d6b5768ab22cc6cc8a36960f8c51c 1458f7bee58294289283a0cc73e82607766ac435addb88f07582984288127dfb 000000000000000006d05f166f1b28f1e2ddb18d49ebd39e26a028894a62f581 +336200 000000000000000016baf984c86fa4688a5d121d966e229038a04c13fef1ee4e 13c053a4b83aff02973bf1b3ee4c935de49eb89e165d4e8036059f819ddc64e0 00000000000000000f8bccd917616f2645472ae5919ac4a95b87ffac4b4e2f25 +336300 00000000000000000af65b2a3fdeeab3ef2835c60033d748b5f1908fffd5d084 3f9069cdafe78207add6d05fb576fd98e55e066a6ed2609954e865ddd8dad98b 00000000000000000ff0449b299536b3822782de24c59c4309e4e602137a1a72 +336400 0000000000000000140a6bb6025ff9a64d05b5def0d95b564a5557b9995adc0e 856947da2d25f2f3a0f98bd04bf7923e6a5cd0095efe24b458a9f0fd5193fa51 00000000000000001ae08eb7e51b7db8ab7c5ced45f4d2d6cc339751d9f6f391 +336500 000000000000000003076ac0bfe39d53c9da3b0bdc92723012adc5ec39701832 6f822735027cf02f4e1d2331d0c3b5d036d3b81b7923e648f27ba6fd42ff0d0e 00000000000000000264b4581397f243576029e7f8531465e2a73ff82de65723 +336600 000000000000000003e236f017ef0add8e3c53eadeb47a8cd56fa35f4d90189f 04db5ce5be95be326926536d83d4c79d482ed23377b4a6a1b8bb2ccd3a2ff7ef 00000000000000000d1c0569a8474aa3309359f6f83598bc0703d26fb7192c8f +336700 000000000000000005fb602d166a78042c8f100781abd1597ec5665a329a3dc8 2e86bef835fc0322926c9b83aa67757ab2c3315937daeaf25406614d999788d8 0000000000000000071164c2cc3cfeb04b3de6c4f8aae45a3ebbfe9207069b27 +336800 000000000000000004ab103bdd109045988a022cff3b9ed2ff288234e3f218d1 786121c8266122b78ebe4e6cb80bc42386e197e870a947abf28f1d3c1bcd910d 0000000000000000028dc2d21b8efef8c4e09b85c821898394dce90880a6f65e +336900 00000000000000000fd5758305ffe712eefb46cc13dca5ae47b075ecee56c0e2 4598bf95f3c615611bc877ea0e75fd8e869bbd97b2489bf5a3e2275cc0f13a39 00000000000000001683a87b36a38575270f4f26dbf4758cb8507badf601c7c7 +337000 0000000000000000119f8928b15ce263b4ab7786631edb0a19faba19f9546da9 ff03974f7ec1681f0dee0c40aff718c8526c0d7721a539bebd30d68b0fd5620f 0000000000000000082ff29f5ef20e34b98bf57ffa1114bb3cdd0145b0def4aa +337100 000000000000000014681f7e402e0bc1999cc8b420e66ce26592048160ef48bc b3cc41561dc6fcfc57772a93748ee8bd579cfda9c4f821f0882f9c273a1abd42 00000000000000000ad9a6bed9ad56592aac7a8f2b1211ace447687f90f4f461 +337200 0000000000000000027c3d0d22cb789427f5beea0e38eea29f7ae63fbd135c1f 8284324b6db12e861b6d35038eefd177dd9b955bdd2ad715512451b36b7a520e 00000000000000001756097637129cd30ba645b5037e3a968f9d961db805dd97 +337300 000000000000000009b4da5c938749ef0e1b56d158c19ace4a6a77de639f771a 590df57dede3089744c03121be9610e1f12f67b1346df0a6f58adb77c3242fb1 000000000000000002083060065e4ccbfddadec356e5776566dfb472d351a5f4 +337400 000000000000000010b26e558a9cd1efd14d4093ddb18437ca0ced7a864b951a 433a55227c131cf9989795d2330301b5b62c871e3ce1411a697a1e3441f4fc6f 00000000000000000efc416deea7667aaf22484c509d17fc998e5e866f36f17a +337500 00000000000000001af039232e90a88e6750556525ccedf80d0cc5c42402b82a 700da795e401d1eb0a40db575bffab8ae14918da5250cfc6e60e94ab4ad9ff79 0000000000000000005b94c5c2daefe77b5053e87a31ca585804386cec4042ef +337600 000000000000000004574af25b9a863d38044ff8da0fce8f6b55ab15e90afdbd ce4c9d25dbb0a448cf2f855407e4eb1598c249a3c49835b103fde01b4d5d4867 0000000000000000085de4f8e20d6e135af44d5319fe42df5e54e18f0f0eb01c +337700 0000000000000000085d513681f6c38944147e5ae5070d02227ef7ec1e9e07fd ae77ad34abc96273a28ef55fc8ededb5e56b41dd92b275059db76a17254639aa 00000000000000000819007f8fbe14710bbbd4df25686a0925eeaa1314e50a87 +337800 000000000000000009fd487b5f1872c1541aa7663948bfd2750dcaee7ded0be3 d87ed518903f079d5f354fb9288258dbc03061236ba4afc96047c2ab269b4216 00000000000000001a034adb438d5bda115d5ab232b7684c12a531fd76d2feb3 +337900 0000000000000000121bd2780af13fef26f26bd8c40d3e37b67e46f4740623ee 8279503ddd921305e8d1edf2c076025f3891d7d438da12cbf4b5a4b569e84798 000000000000000006f363e88b643cbfb988e356271a5d6f682c4480fd34d689 +338000 00000000000000001983dc4a87df627b63cdce28e5321cb867fbbb74c0e87e8e c77b24699a421b183b9bebb76f906ac313ec0cbaac40b033e7b6e72d74067822 0000000000000000030d9281927559e9ac954e63032101239f91108375eb4e61 +338100 0000000000000000081d26814456e96ea02a0a2cc70c23b6cf5f8c342499a1ac 4bf92cab9fb6bcc8957b2b76b474d656d1288241aac42beda86c5a6194457144 00000000000000000e9ff888119e1a6211e6858448fd6866099be8c1a3a4dd2e +338200 000000000000000011dd819644593ba8a4e3afc2d0756c219b1c4a39ffb7b61d 38988e7a6f5d4786cba2cf6548d2256d6dc69058252dda629ed883e0870d5e22 0000000000000000070e740307e35ad77a3dd9cd716430e74a5f6995aec7af92 +338300 000000000000000018e8eff4b890798d8e4eede705a1bacd17f52617f57f58eb d6ce28dc079f58537186729972700968cd3b308dc11adf4f4e9fdc6dae07cab4 00000000000000000790ca49d36e8ddfe4a6143970dddcf8f242aa2ad686ae26 +338400 000000000000000010bd41948b14e2b803b020670f100ef38e0714cde005ef1b 83053cfcbf15d8c08f8f4dc1c5070d339df0be78076baf9bce3095d0a430c4f4 0000000000000000043a44a1ad030f76bfcf3553f86891b33638cf08af7e0508 +338500 00000000000000000127206acda4f4d818047df5c7382988cc05b867eccd1d4c 957836cbca995d819ee9501388c90d4ec7284c38005d472b4f42032620bbf2a6 00000000000000001a0909c23e5152f51026f64ebceba4ff3df7b7f28bd42fac +338600 00000000000000000f8c3b656930144c00278f4a3067857335f971b2de5279b0 698a84909840804e1998525ea67ab5245df567315098f0cff7c18b32477b1c2e 0000000000000000178cce4402bfeb7dc6e54ee09790bcd68a5330549e48a41b +338700 000000000000000012e8c0efdff2b8f67282e211749cc5530bd6e709f70279e1 58b5d734db28ad0338820765d0ecb0d10b0b5e087a6d5b6c993fcdd740d061d5 0000000000000000127c2750f9b2e29bd9153aa72c532e52c8c0eedc5ab9d5ef +338800 000000000000000007e2f6e32e214d2e918b97becc7d87eba27edd876ae325cb d1ed3bc28417de0744b216cdae9907cf89e3e0304a8bd0e611b0d034ad56aa60 000000000000000000ab967dad6b04416cbcbd425cd0cc0d0c8f989f3b7b8555 +338900 000000000000000009ae58ccb23a372510e5f22b329881e7ee0b1333dc4c63f0 4337ea366fff80f779a891022a12eb6c9e8be22dd65ee91652e53c90d1c7ab4f 000000000000000006437b7086ca85fc79f644cd544e731e9a370bcbe727b047 +339000 0000000000000000146a5926d9dadeb41267c62fca35884519e035bee5b52e93 8cb3c2eda2b408e9732cee8ca706453e008fefb45ec003a1ba666bc85750cc14 0000000000000000001d93a402d4bf7f8991cc5b849832c948a2e20c680a7837 +339100 0000000000000000059876e96f7a08c4b90976cea15664ad900cebab04f8274f 8e46516c580cf912885c4681038f4243bd40ce7c3d818f2ffc8c6ff74ef4e81f 000000000000000002a5d05246395eb0ab6a7a57d9ded75369b865795faf75a1 +339200 0000000000000000067ba3fff6c0fc406d15dcbb539612c96ba0c51ff3649f05 3f6a27ac596a45c425c2a8ba362cff2952b4fc8cde802d51df58a49c0d944304 00000000000000000f7f7d03954b4f7e621ee01f74a6d6c958a210505033bf96 +339300 000000000000000007a9a31ff7f07463d91af6b5454241d5faf282e5e0fe1b3a f5639a1524e7b9d241c9e1b6cced5dc28cb24c62d75907a8a45e76ecca4b46ca 000000000000000000f67c2320fba031c06e355acf730ac75285e01864c81e69 +339400 000000000000000016d6d4eb5a5a41d0191e2a1a819128a00840da07cce9a4ea eb9a0e5790077bf4796e085c08de9d3b8386f4ecfaf11a89cff81f51c3b86186 00000000000000000930250b6fd7f48a38a1800f66856bbc6e93dc383bdfdae6 +339500 00000000000000001500345210594f6e147819cafd471bc1e2eaf5181569fcb9 ac74990bb83b604dedb76a51f2b66b83d1c98aad1e73e011e612ac9c9e997295 00000000000000001044e8ff7830a5af169d75f1d41e7cf1ba247af4955c03c3 +339600 000000000000000015ef252b0294f399356b56a2bcf7ec28415fc2b9ad3aa270 58863108deb71a766bb5c4b73bac893598d3a8f0adf2cf4e5ed1d87d056bb0e5 00000000000000000db7f6d65f11146ce875f9a93ed83c6bb653f38f3d3ca11f +339700 00000000000000000aa5a4c2bbefdd58d0800718898d22e7de0715b8732a96f0 7ccba672f10a34c98ee6f07ac537807ca3c52d9bed8caed8413192cfa990637e 000000000000000003cdc7ccdfb84a848e5ed711f04a1521b7e3ee1729cae401 +339800 000000000000000017f84a6e30e8df6d80692ddbf94ff3e25f1b24283701335e 5200808c0c90d9a75db19171b70967ee6d2387578fc18f0e48eeea09e4e8e782 000000000000000001dc9b6e1170d3444a9ce87fe0ef6d9c0de1b1b883937f30 +339900 000000000000000008126c264131e680962a23c505ec47f3f32d09eb29513a41 bd2689249f3710ed359f224f50929608563b2effe5a04355a7d8fbe57606f638 00000000000000000cf52d522e42fb8a4c4ac572f6896cdd83b28965c2cc4683 +340000 00000000000000000d9b2508615d569e18f00c034d71474fc44a43af8d4a5003 d34705a5bffd0ce24402d9210f034e592e66b6d697dee1a9a43f8f479c003a4d 000000000000000017e6362910c6efd4dafe37d551a17db50608f19f52fb7bca +340100 000000000000000004da7726bfce8381d7df8fdf2b544f209cb954689af56985 13c5f4fbeac1142401deaf003adeed4caae88c0df00135e9b36c7f11ab06e2fe 000000000000000003f7baa99e0429cbc1c2b599ffcf9144cca7540e8c746a9c +340200 000000000000000010a3d127eae74116929df71fda492939b882ceeabfb63703 4399e3b0afece9d85347da75ce545029d42678bd18d84e3ac1a98bc2a401bf36 000000000000000010a0002bcadbdcfed2c20954d296aa09e7abda9cbdf5aad3 +340300 000000000000000001009e2f84d2e6319871f99b8fc8c3286a8b574557f5aa6a fb7f6b9bfaaac7db08fe693e4c4c2ef54659e48a4e1706889942259ba0c91fcf 000000000000000010eddc6572ec6419f83b4a17da1caa55657850de0c1eee03 +340400 00000000000000000da3e6f59708330987a62810d947737318cf5a691ea773f2 cf50a5ec288560e354b725f8803c2ca72829c1f2b13104fa54e8784f234b570e 000000000000000008d151bf4b0d112c3d433e19e530d86dd079b794dc393d6e +340500 000000000000000001c310679014f95b64d0045195346a70b71d2e8072bbcbf4 c503201ebcdc3bb4c9d4909ccc12c6f50213bc870eba7f40fb7d1cc9aac8182c 0000000000000000005bf408fe502addcc4e6b58877ed294b320854c8b57e7a7 +340600 00000000000000000001a092bb0f2311bf00987a8f7d92e2ed6b36a522054741 75185fb384f6dbc4710a4922aaa08cfa17d182173f0ea338781fab9899be8db3 0000000000000000075655e4ccb3f3939486b4a8ea8a848ce65372aa34de8f41 +340700 00000000000000000948c904d781d5d097d8bc1fcaa514af61cc50e476d4a911 5f6b559b57c36226fb41e7fdbadb7862cc8440e406a52a3cd4181ac03e365ce2 00000000000000000ab60e07162af8916e1ea22f309422ee54ea3be18c862111 +340800 00000000000000000b15728bd5bb7d83801b113fc749d1740c2b2fa28646359d 76def5b2ea5e8ff35bee7ad9f92e68f7aabc781c5580f052dbeedec02a308bf8 00000000000000000cb738669f1c2d0125603cb3fc8c2c97875078eea9acf3d9 +340900 000000000000000000fda17295b0efe96dc7b71ec7983fdc8de4edfcc3f0da3a ad4ed139e425dc7b19219c830a6c6b602036699c4f2099731419a05e39a78fdc 00000000000000000594c312f3d73bf50b7580b772e0eccf202fbcead67b01f9 +341000 00000000000000001a0705eda753c4bdb107716ba6905e065e4ae76f0f92e6fe 609782691852af09759798872e8c3752c76c6003745bc56bf467c5cb54ab5657 00000000000000001141af6091101ca6e4a46c937173ab9aeaed819d198baca2 +341100 000000000000000007dac77f9c934668cd6435861255d7b48398b6fb4cd7adb7 7f394fedcc486f3c003c284fc54d55eb117a3156e51422f88f64be386d3a186b 00000000000000001558cdf8a64bf7b3a6f393056de8f9a5362821ac04a3039f +341200 0000000000000000075582523571c113804c88703d282c33b6e22482b8880e4d 49b847100b9593db7554f28244bc50d833a0039496f1c5d0830c32df9e63d779 00000000000000000ce43f99acd2080a08fee78b919e474c12932253b7dcc6fe +341300 00000000000000000829c47ba828cc67fa55cc84518ce5c48bf0b2f04fe15a42 8f03b298d0d58f493d83a92c06b4f63647c756eda478cdcb49362c18e69a3b15 000000000000000009eee60b863a902da4f2e79066896387d4e017fcb3b3340a +341400 0000000000000000122bc60cae83932c8a461960bc6258e124339de69664b424 8b1b055a2945a1db7fc8f2568c885528284bc25efebcb7539ebee5acb2d3c9e9 0000000000000000171137287df7fca749dde778ae6168e6e22254edd7582847 +341500 00000000000000000ba48080da8c7b8f3bab64ad2f6460ca8cd56f7d1f83acee 62511923e9ad1ded8f628c60e4fec97c4c8d5b04562cf2e9102fb7cb079842ee 000000000000000008c203b3594f003e8ea599a4fc37903cc627b66cbb1afd97 +341600 000000000000000006728198c0b61dc963d3b4c0ee57690fa954bc21c8edbaaa 1431b83d75eecbfa40af7650190a67bf1993616c123d6a49141b62cc0c7f0b18 00000000000000001826362840957c13af48ce84a3166d320f4b4d756c8cc23d +341700 0000000000000000031f795b473953f35ab83dc13af46b8e8cb44407becb6d96 44259293dc6d32e01585c419c35aa479dd54248ffa0ef753a46c7b48283c1628 00000000000000000fe7d5341063c4b8e33ff980bc2bc3fa72eb1621dcb32dd5 +341800 00000000000000000f870a3a966c3444e2883559e7ab0127a3aab697a9977eb0 46a9172048f8009f80d8d9c835318cba6c908e3b39e21670337d763c698d16f1 00000000000000000215ed6347abbec0b293b7dad6264cf1294313d73821dea5 +341900 0000000000000000087457de8a450676419c02dc5569e46fe532286f1244b45e 10291ea0ef0d528ec433d2809bc32bd3e8487afb9baa7dd22d602ce3c85e1ca8 000000000000000012800085b78d1b33a5af61909bcdb36b7addff7074274fa2 +342000 0000000000000000007220892af98a563a1c891c756e94be3f14edddcf637c3e 8963afda38ad21dbd1a738e22809f761b8c5ea41334fb773378efff41ef94298 000000000000000007a0870fbf18c6b9f23c623f7f332c1a06bcc1a260399940 +342100 00000000000000000d0fe0023a8dcfcde1d01ad32750986c6c71f3d9a67672b9 a96569522e82448511448a9a871e7d75374c10fa222d3d1621f9ff90702c9ae7 0000000000000000190b00c1a3b25f18d6e7b834a5c3f92e49abad4a0b901154 +342200 000000000000000002e32542a3baa48d23a5c17ca3f0dfc3e63115b468f012a6 8dc07b2ac6f8e76857bdfcf67eca01a0bba80f5eb1808478c221862e049ba936 000000000000000001e5e6e26edea239ce073f2e101676f1e3aa3b1debf3b12c +342300 000000000000000012ef4a609f4db82164e8c939bcbdab998c59efed5f160b85 bad8da415f3b050133ffcfdb2d1aeca1d3b98db718d3927514fa18c15c1673f8 000000000000000002164b736e2982dfba18109e2f4b4b47503e64888e9c273f +342400 00000000000000000bf0d2d36a791f64d8f8629975e6f834fd04636bb96547c4 63a095c47d308442f249365aa3f50c7ec76101b26869cdb2758e5caa54c2f924 0000000000000000024d6b1c886246eb502a7f27460ca502f0452003c3d813f1 +342500 000000000000000012883e6414983b2c1720b961cbfe5acb297707e4d2e615b3 f88b3cd27a569a088f8bef8e01c4e74335b3ff4f85972efcf1897e779273b7ed 00000000000000000b28f49bdfef055cc24c68fdb93c5769fb98f8ebd74dec7b +342600 000000000000000004f65cec864bd401516b10c269ca9432ac949aa3c08542a6 a284161fc84c13e699bcc3bce91f5bb4a9bc956eff63e739033900b7b5228c35 000000000000000007e73144a57ba8fe87a898d55066afafa133189d732227c6 +342700 000000000000000012ac2697cffeed8c067ff1ee9175327716ff0fe60830da0b 40ce4f4b668e2d4cdea4c6f8c37b90b6618efc2ff40de7fb1f3b65ee0b218d0b 0000000000000000151b5fed58bd3bc40b5da4f9d5a4ade192a1a3c7c5dcdea1 +342800 00000000000000000530a695d6a35838c37a931a1e515aedd1acd0f4429bd11a 5bb6ec010fd7f492f852a6e50ad71c3e032f798e935137fd152cd1575339e201 000000000000000010ff5502b6d6c4e0e8be0191823ecc1e7ace8e282f9a8e52 +342900 00000000000000000650381dd1f73e036c6a61516b32d1a938782171b3f7a3c9 aa516691c30a1e3a712e2af0a64b7c2ccc99612c5ea91df770daaca0b8b307a8 00000000000000000ade09799867671b97600181127ce987145192c79fb99109 +343000 000000000000000014ec9821dc38ec06b512cdc3b73bc51812a842af6fb6c35b d32c3cb9c504081d970d475c53da65344a2f19e8c92f700b0e8c6260759aec60 000000000000000001ab0ad78d3fb8eec7a44085d4ac0b2c74d914a2d70392a5 +343100 000000000000000008799a5677af9f6c1c30178a40340e68f0b8049d90565d5d 1eefac82022c2cd2adb88e13484478a39e90c4ab6af3caff45e3b85d2d1024e2 00000000000000000892f1c66718e98439b3104331b2d1038667c75417cfa9c1 +343200 00000000000000000f6bccca401ee586b854a899d1b070a123c4565dff190ca4 095d5c280f4efdc1c1073a12a6bd5d88b3f5611f0cf7ca482d216ca12a9dd954 00000000000000000fdee77af7cfb73f2cfbdbf5237a9c0d4f85c3274b5477ea +343300 00000000000000000f941ee1221c839b0101ada9424791b8ded6739fd391ca85 e6514f99366baf9676b48fc631382d6ac4ef604af3fd885e617ed276f709bc51 00000000000000000acc7e060be46e2ac39acea17415c9b7d0a50ce716d8e4e6 +343400 0000000000000000056cf9bc07f119e89a78c828d060caa769c10985d872297f 18d0a4465cb4a5b75a3e36e8772b78808d0e450d00fdb1b1b9a8dde0d1b05e22 000000000000000002491bc2f1d45d6af1ad1f4b1165f1fc4f1286773f09ead6 +343500 000000000000000009cd59e644f221c7f6c0bc9117ceb0e569a64e0636dee610 4bcac7518bd50ffc0f44bfc18f0f49fcb6ecad0cf2941c9af25e8ef8a002c416 000000000000000015c7c3827552a035f925678e3d9997945fcab49f29aa5a1f +343600 00000000000000000b2b0f68fe63e0b7f23c5c20dba60b11a5f237f67d5e24d1 d911db27cc23d35cf298c557365b08b9eecb538566a8c05a7df69414bbdb5c46 00000000000000000fe958a4fb8cec0fc3637c66a633fabda553c416ae76ba10 +343700 0000000000000000138c6c076b93c4128aa6975e39a7524740c709668cc0f228 16a2918d495edfd16b80d87def411180d85e3ff8803b9d9bbf32b962f793022f 000000000000000005c6f83da4504ccb4559cf2a5d6aa48344f05db1a0f60047 +343800 00000000000000000cee3032ed1a3b93d833ccde51ec323757ae5b1ffad0e4de 1cbe83ffcf073e423b9d70453caf9ab3c7c009d6495fbf455515b0200a7978e2 0000000000000000069dc85136d988307ec5e497a37c6d764cb19a9d761eb9bb +343900 00000000000000000b73b2227bd44c22931d8b9d99a49067f50addcb47da4a35 a4e64b019616687fffb55d7ccc293effff7af335b306fa91a0cdfeafe815ccb2 00000000000000000e652ae3f688a91e342b5b88577b4399166d9ed55eb6a775 +344000 000000000000000005f0a16f5a9f95eeb95c5eed0eb221e8f5dc5a9943a03aee 3c5123be92b76a69e16316c0d01e7a372eaa13161cdcc9531700e27b0f2467c2 00000000000000000b7c96af32f1e4317e3069ea4bfb02697caa6dbde7216f9a +344100 00000000000000000d10bdcb4e8b3e33960bd16989f1bbf6bd4257cf617ad929 2ca433779dc91c4ec2aeb8413eef732ff766b2fd638db2c942171cdcd0ff6b96 00000000000000000b8de2e4dca0b88bd7e96aaec4de210838061e2d403b0546 +344200 0000000000000000024497df68e3d8d38557a5af53b737ce509257d59fbdace3 01e9d5871003896c0bab2160f59b83c85ffb2fe45b4f49bb601b6b8c35b5250b 0000000000000000043fde47bc57a0446dc2b8d498c219e1a7f0f02300b24bf9 +344300 000000000000000015d89c168fb9fd7ba8204528023ab9e986b877dc6d980e89 164d1f66ba45a5ae88cf43de4f8ce2a901041e948673ac62087bf1c05b505b62 000000000000000007e47ade54693cd9f524cb52d6a0ab69a3b13db72333b785 +344400 000000000000000013cac7ca6243560aeeb66c4a6909177ac13407308500598b 698aadea8471260b0575a568ef9b1898a33a77de69f8468dd43fac43657300c8 00000000000000000fd034712952116f454b837f44f762cb45c30778dffa4c13 +344500 00000000000000000bef31e2b2f0f76576043f11bfa8f320395dcd6a38ff7cb0 d37afd4b2dc330f5786a695f7576492b6f459087677dcabfef3d4b45c9a2452a 000000000000000012c0cba839ff85a5620665209ee5d6d0d9402efdcbb7804d +344600 00000000000000001346fff3e19b529e7edcb5276d0c90323fc194aa3eddbabf dfa90d2ff4a0a250d611ccb4e8d56e776d741eb5a72d93b2a9577385f38955d7 000000000000000018b3295f70b32583fe3c16b92397c0aa12f581cd92b7b1b9 +344700 00000000000000000dd482a6e7ca9eb90260f65b4ece217095a990cea85f37be b6703d330cc2b8a55ad1b1def9194eadc579d7db49f18126d5bda9f9174a5855 00000000000000000083c3ffa62e903f2e2716188d22c596a61a6cff633e9088 +344800 000000000000000011df3c0c41228de9f4c0d181fa4f7e6c1159a913bd91dfb6 385cc48bbe51ecda501ed84242c4489cb3dfd1b324e6123a4300032b60a4e670 000000000000000010815b35aa89eda58182ea645acee70b22e8a213ab979773 +344900 000000000000000004d994cfdc7c49e6383538aa498a234bab12ce8a881f2e72 c129782cea977ee822744a3bc59ec89206101b15ceee153940db58f10646df3b 0000000000000000163dc45100c993e7533724c41de7cd868972791d6ed9b4d2 +345000 0000000000000000172bde54cad0b002c35c89a2a67d82c02bb86ea08c6b54cc 4fdbac10a73079fa15d06b88cf747273c75c5c09b120b568ab4159d08e01345a 000000000000000014898f63487f5bfdd9d0d38fc4fb164e45e4096ab6375cab +345100 000000000000000009595ac80a8dcff41d875e07e827f71a1c918dd0f077af97 5b1165d4df6e09551c135a2f2fd3ed7a50da2a986671d9aa79092260b267cc64 00000000000000000fb70270b19eb5b3064397329e63a8b6c54a12f159525453 +345200 000000000000000009c9630718cd76942a3ffba39e816ee6284324f8be25edff fe181dbf0105489bc999a0362cfc978936d9de38f22605f2a9038e78fdd9d66a 0000000000000000061e004601132eae75b61e6470ffef2e671ae78c75c86f42 +345300 0000000000000000028579e64f61ee63c6dec7e0e300998b6c309bc0d692ce8f ae4675e03072911446422bdc8863a0b089d57005ca17ee3a2c772c85f4abb3bf 00000000000000000bd7b0856331c0e2985285eadbc0c03a325eccbfd79c2725 +345400 0000000000000000066e33cbe32b2ee2b52500d66fcbe609f813b659c978c790 042c49bf19870f83cb58926facd31a44ef1f8e2cb230a05fc6fa34d91ba9c4df 00000000000000000924d9eefcd031876d0a721b62f783e636767cba4cc2fca6 +345500 00000000000000000f8b81c56f8bf7bd32181e24b043cb241dc6e649370e76ed 2983320b43127845b9679f99cdeead144c91ab40d283413b6ffb8c2b14e7a441 000000000000000011288b196546c115542abb9a66f691ae8da456abed6c86f4 +345600 000000000000000006ad4143e4c498296ae8685b0439659c0ed68a733fb5ba46 ad7a226942473b5ed3c81789adb3cd35be56c4aff62ac986ca0c7059a566299e 00000000000000000c9e74674b68a3673e9daeb91c9749e201e8e38f6ba61672 +345700 00000000000000000d5eaaffe7a52c586c66c24e0b5c758cd0a290d6c3d774cf f59daed037104900b1853d82be59353efb441e3ec5451fb16b70f226d95d5057 00000000000000000a959c8e934c70beb743537ac55c0d10c2b07f7ff6a38b9f +345800 000000000000000006cdcfea43c7fb7c3de75367a0133393acee5407f1a127f9 bb5245fd66477eb0b60cf2992e166c939f99f7adc56bcbc15aa8b329a061486b 0000000000000000056a1ce74455be04f1e0ab825237ca74b0c215c305a6826d +345900 000000000000000001e6067855040e8a05a9d66e33c72b9c73ba017aef0de57a b299d38e9132f8fc40cc824ab0b6ed413f203758d1fbc24ac1b2f48904d269ed 0000000000000000175d08c2f3c349ee4edbb7e167c208a4f7ad76684f5f764f +346000 0000000000000000068d33fd865621cb7eedbf05c6b235191fa1cb8ee2c797d7 8d121648400bb1ad6c684f370d8906fdb0c0a876ca875636ef82c1eb52ab0401 00000000000000000f0b165c17e8dffc545815d7ea4be64efabf3a0d23014350 +346100 0000000000000000027a781a7cd4212cf72e8aadcd2141aa4d9f58dd304a4693 6aad3236c5cc9ef3a64fa7ded2e15081b028c8adcfd342f906419805d7adae9f 00000000000000000219e35254c2965f2ff16d53dcd10d20ae8182ebc78ee81e +346200 0000000000000000027a565276deb7d243ced01d4c16678fda0de1fd407c7168 d098f2b5997d83ff1e4707e81039ca885bb5fe3bca5d82d33c5a3bb6ecdd7717 00000000000000000435010856353045ce171d6d6b69ba5910bf24a8fa7f588e +346300 000000000000000009d72c738ab00981bf1660ac469f9681e7e3f2044c4f3e36 d3ed7ff9b40a788182e46c9d9dc7f5b0adc2c2af609b0687ba5a56b3325cb64c 000000000000000015bb7b66e1d350b6766b9047673f5b282e88e116f571022d +346400 000000000000000003880a75ca8a9730335720c7c121d4fa863f2bae4efedacb 3c04650b32e5917a4e13dfbb8bf43632debce35d1b62ec4e1af2595d920fee36 0000000000000000128ac6d567b10d3949a7e13cf44a9c29e0f3af7534187a1e +346500 00000000000000001513c28a2b001f57fe2790af7a0ff52a4b246f8c245c535c 76f4afb29758bfc2f4590ae5bc78e190ae76cb42e5beeb8f1176af43b80e7f9f 000000000000000015022b5a149efed2eea7c21e7d6192354e02cfeb9adcb956 +346600 00000000000000000e63ccb5cfa90b0410220f1ba5b464beec911353734546a5 de96b56b11b0e4cdd2493468208da9ad7bc0f9142cc2e1b8e8e797cc659d8203 00000000000000000ca71ce05637c6ade417f28a2056bfef9c5b4451b94a2841 +346700 00000000000000001063848ccb5d843812f08fec8a0d5cc6bbab051c1a0a0d33 7d51dc58435a3ae221f05053c541d6036e5ac37cf9d42b6683e6b124cd2f7256 000000000000000015a3ec433e2f72036ade1f58aca68cab605afefc64559ea7 +346800 00000000000000000fe4fe4a3e4dada85e3c85d46ba24187f208313a7bde5825 f1cfbd7be897a2b8dbff6527e3e09793778a6811a349918c3ba0bbf61dddf1a3 00000000000000000900944a54a15f544ef7e7cfe593776747b0ca090596564b +346900 00000000000000001301de15ae2dda05c3c24f4300723a5d19d2084bb4655d06 8abe7dfe25090593914655a5678c29b52e644395ef3a699e651839ed73937aed 00000000000000000f2bd68665fce36925549e13790d447ce7c6a498a147abfd +347000 00000000000000001712656555b08bf16f6785c7d77875df2f1eb8428a77d8bd b3175ab7a4f64903990500608cd374015aafbb27569f799134c2aefa8b2d8fa9 000000000000000006ba14711606408320d49253d1c93e43c009b82d10976fea +347100 00000000000000000f4806f60ec8f830dde4c134c50ae436d56a190b58bb363b 721dd6689bb1d4362303591293c80656819670a4c83bdbd9d6f1929709f08d40 0000000000000000041a4e67fbc3084c31b3a870fe1ae827a0385ad4b571701a +347200 000000000000000004460ede234fee58be53ca9e28b0c35d74943193acfcbef1 40b0ca3596f8581bcf105f1b6569a894b9eaf86d8520ec94f93064f3d73e1c06 00000000000000000411bf4748e15a8d2ee3c1b21145e1d631f372850887712e +347300 000000000000000013392301d28812f5ce2b3a50fe3cd4bf25d9611abd93eccb 38eb111d0a7bde017955998135bdc8479f654d1972dcf5fe24ee1eeac6feeb37 0000000000000000104407c693decc0f4d0b67d63669cba341bb45fc10f0992e +347400 000000000000000012cb55106386542ed0328159172055002d68399f042e1530 98e5b0876e529a9141d667869f3161c7b33601779be6f84740cfebcb9143d0d8 0000000000000000024b474acfc84225b86ec9c391bb6b5e52933c4379afdcab +347500 000000000000000003d3da75deced5b1ceaca5b3d72d6eee5295b8fac26b9052 af0c0745556225c4c2b8c336d5c53592bb5a409ae22213d66d1b7deaefbc8712 00000000000000000117b90d641f877059163777e7b6cd8cb15cfe6b84978271 +347600 0000000000000000117fa61a6bf98f6d79cd193001e61b3f1e74e5a1b227a88e fc91818c0361979d5055428b6023919fb7e4081325fd04079225deb1a3094e5f 00000000000000000d09f93afadd49885b530acd16c6cf8cdd13025949b375a2 +347700 000000000000000007fdbf1d71d96199a26e1ee008f68dfe8878e91b165492f9 9a13b6e9f2f795675a9fb1de65dcfb25ff3aa15ad4e70c5de7af8ca368f9eabd 00000000000000000835eb85b252712aeee68930d76bc490d5e9d506692063e0 +347800 00000000000000000ef87a8b0ab8351e794c546defb0892976d582cc14589a2f 3b63827383cc129acf2085bfff2ed6880dfce29d58fbf04470bd5e5ae9fbd119 00000000000000000d4b7cab74afcc2137b8dc56be6ab2730e4d409f11993518 +347900 0000000000000000066a96db85128ff6ec87b7f7944435a828815ab1574a69d7 dc947ff9bfc7c00cae7bbd59b62b65dbdf8160502ba18075349f5d9f6b4cc71d 00000000000000000070038bf196e2c50479e7e6db36ab74f56935153d4b649e +348000 00000000000000001598a651988bb3a45237c4f801cf8049be20f74aed8e827a 3fe888ece74f2f835d3497d2841a3dcca1095df517d030aa4d43b457c3184a0c 00000000000000001462b7aeedcf2b5aac482d416c707d651d5465ac090002c0 +348100 000000000000000011f5e91ca2b35ec1a0be143d688eb6bc75750e97f8c063cc 74ef44656171348d688a47fdd374d30678c62af04695191ce8e5684dc5dfe08d 000000000000000013edb649dd69d04a5b9cb0af9800ec2f1ac526a30ec93a65 +348200 000000000000000004ddb42f0c95b99f661c29ba995caf0e11ea653755e03ebe 7c7d5db5125a0412f6cc3e7aefeae22965ef20219ff7900d4d7eea59d6f38814 000000000000000011bf8632f93473f906aae18e96ad2dc837cf1ff442519a1b +348300 0000000000000000138f643b9a26c00b01cdb4f6357503ed201900980c08d143 738a92ecc34926ce5670551b72d1e482039cc26726e0a20095917281550c53cb 000000000000000011fec41be885e4d03f3db99d11cd8e3b7721c569382177e8 +348400 000000000000000004a18249dd1b16850b52a2aad996ca1bc1a4d30936601dc7 8bfaa2598efea4b2e3c246167d2de911613d5d617e06c71f1645616ae7177022 000000000000000001113c292a5c9cbb351d1c5d3e88ad3e753a845054f23e49 +348500 000000000000000011c2aef69ea06424f805af3cbc919dbe89355ec90c37922c e6d7d275b87ebc093670ca88fe0eddbdcbdd9164f2a6dccee86c9fdbd65d8937 000000000000000000f44e92e6bbd009b714c7ced726578b9e1218b750640963 +348600 00000000000000000a6596fc7962456ce3b7322bc54efd77b31f429fe13f0502 f1a19fa35ce848dbbb51dc48cf9bff8e0c7fa5cef5e1debf872fff2d02119779 0000000000000000000e8b598a1155fbe59d750a2e0771b90d0fe81baaad452c +348700 0000000000000000096a13fe34c98de36e02a4ecf510e3dbfd520941e2756ce1 05a6c3997001715e385d774ed595c485a2a9e005fa557a9ee82623d69c385e11 00000000000000000ca1f813c695fbf328794aacedbb7bdbe769d3d16b64c5d9 +348800 00000000000000000818e08bfea38408539fad888bb41a91d25c99e46dcffb9c ee9dd200898615343aaf07086c6a000d60932a5b549508d88d9631714ebff700 000000000000000007566007285dc6573e6eaef857df18b4f9a87bd7e59d700c +348900 000000000000000001950e12a29af2625ac6cdb744d03929918c3d93c33b559f 59e952c569f9b03955de952bd4eff67419f82522ed82a9140d8eaf5db540ffb8 0000000000000000173c6c6c09d98410a6971d513bb90e145ede0ee10fc3f5c0 +349000 0000000000000000088ab566bf655994f7be79b6abc23a174285ad067f152526 7f457e8938c6d70ee45577e2fb673d2038618bc105859edfcce3b1d5ea5143ef 00000000000000000a0d82184e456e93c332fa9c470cc7d75f5e4d73b26adf54 +349100 00000000000000000e2746613193ea27b54fd300a3c88c51d8b2906a355bb68a 370e3daf07dc6c70f5776ffbfe216aeb86eff59b5506b9076a0603b2df7c56ec 0000000000000000059798e31d0683152b6cb3d1f4213b996af1c0fd0a6e3ef3 +349200 00000000000000000b93e56d8185418a49ce1b3d36edf32d504d62ed0e3f6ca9 455d61f8a3027479f1a97fe97c76cb6af421b21b5e0c5e00e615c5cc973f116f 00000000000000000901407a27ac6fe22fb902598cbf8d5bf06455c14dca7ce4 +349300 00000000000000001489c073e5f157245a087919f0c68e5fa6950553be8c8e8f 55578588bdf7402443ed302a7c12ea2782078632ad11299143908c589ccf09bc 00000000000000001006f6233da9ad8ec116cddf9421b66d7239252790b7bd23 +349400 000000000000000005e0adc32d076310a1550e19b7157bc86dff903869ea719f f593cc68761119051e907e72b734747e55bb90a9ce1f2dcb24702965c40d4c2c 00000000000000000b15e75d932d9fe1015c4f07ed093a0c5dfb506f0af348c9 +349500 0000000000000000104977aca25ee4c2a0bbefda688022bc8a38717db8ef2561 bfe86c340460b3014bc9797313f9a913331ed5d6c544fe20c602c6452484ac1e 0000000000000000086fc514d9af17c9e879f975c9005601eaceadacaf34a6c2 +349600 000000000000000010879e092119599612b57c6508b15b9b97a4862ab998c8cb 77aee4a792fadfa20296c2f78ab0af311f5768a315ff37f0bea274867f58768e 00000000000000000fe55264afa0eb6710a604bd91761691e8e3b07ace2bbc65 +349700 0000000000000000165f28a435379e82787c91864d2eefacf6b4e5ecd7db0d1f e7e3ad3e0afa14a5539890f082ba8e91a54e9a244e2e28a049915d447d4978aa 0000000000000000165d51c3850e8bf341b96649193a98d0a11e682a681b4523 +349800 00000000000000000aafb4ea7f573f9684e8eba6b429b8cfebecb26546a7f7f0 9ac40a7e2756c6f4595538671e4af70790edcb8c21bcfe98185b1b237ecd4216 00000000000000000c3291b74c607abf3e09b480cd2b0699b818197053f69308 +349900 00000000000000001694fa3f91fb49a5940396088a957063dc028b943f9acb6b c1a55453376e859e67bc8c9d519866025c6670f3f2dc1798643e2313849831ee 00000000000000000be576efee6dec3a1b1720c8f31cdc941c2b46ff36221589 +350000 0000000000000000053cf64f0400bb38e0c4b3872c38795ddde27acb40a112bb 1f3ca02caa9831d70a0eb3f637080c00c9f7601616fefe98b2abf6a58e2c50b7 0000000000000000075f18b37aa8c6fe753d6804bb03ae91ba0d86c9cac3fd67 +350100 000000000000000016bc0f114e134dc32983032826f8888dd603ce77decde5b8 dfde0364ef4cf50df5d4610e5d54fab8b8fe04a5fa9871c82073036ad7a2c911 000000000000000012579da70ecae513cdc2ec9c2e844930ade89f6140ed45f5 +350200 000000000000000008ebf26f102ad01a92b9dfe44e1b41dfffd9a4ed2c65a309 541a1dddbb73d55eec8e7c96a193e1eb54cc24ecbf52eb4bd9b52c82d2931714 00000000000000000f9e77c173af168f04b1f883ada315fb980a03667d22bf27 +350300 00000000000000000ba6d629ea48bdd2d23b277d0654423eded7cf80cb57ffff 467f2abdc45d12253aee88dca3cf0df67f90ee04315164ef7f8df6a0d1b37e96 000000000000000016eea235606220701ee9f7a5663f08b9c990966ab7fa142a +350400 00000000000000001010590425ecbdde1cd51059a77e5507936a1f7bf069d632 eb2a44cd7a8a49fe883d524696a8fda426ae433797a00e353f1a7306f81f613c 0000000000000000092b5afa63b1a2e55f9cd9a4f8085789796545950298267b +350500 00000000000000000483f774073f7bab2d7d71a424b81684d82feb623f35dd17 dc432aa064cf5bd222d92e147010718806e092870d5bca628ddb0a81f50a032e 00000000000000000bac2cc9b8b38658e3272926a5a0ed43658066df0a2170bf +350600 000000000000000013a8799e6e1871533e9a3d08034f0fb4ceb21301973436b5 1a82b3c1b6fac1fb7577434b216e303241c1ed83aff560d95cfc061e38f42261 000000000000000010cae4be2a9b5760449788c0262947f068c90836bfb15d7c +350700 000000000000000011c792257b5d813f0c483ba023f72502fb6e562ac0382b30 5c0db329589dc06ef0a433ba0083086f2fbcdd088194ccf6366e5c02aac46e10 0000000000000000004505ec3a140455e5004fa9313e430a95c8a22561c299a6 +350800 00000000000000000ea1ac00d6b5e0462ef76dc505f78070b8999bbfea6c2fa1 357e103ecdb94a2c841c751474ed2d1016ea67e74e5887cf0b3b80e36f1319f7 000000000000000001c6f8be26e81385d7f3935f34a128d5108546b3c6c6681f +350900 0000000000000000072bbe3ca8b78c637780ae9a0e2fe548c1737625ed21b936 5d4d8f94254a9e0caae71a737018a52656ef3c465a1400ecf0869be9f1b0ae4f 00000000000000000da01f40a51f05bb882d0ad53149fe869ba23a102ff1ccc5 +351000 00000000000000000584cdd8ec00b13ea91e79d3fb34095278cc718f4fff37c9 36da2df151277529e9d95dd445a32d8dda3d3974d8cf77e25183e4a1d4bc868a 00000000000000001467a6c26f2e6b867c33c0efab1a2ce313a232048c6a130c +351100 00000000000000000ed1747398350ed90476d30685de73af5572a1f72cc32c49 61f408f54a104b5734e71926f6f36d973fba9ceb293b998ec0e97d8e24726eb9 00000000000000000f842becc1e53e9cacbbdfac8fe2041fc6e88fec9a6b1951 +351200 00000000000000000877edbd83c111744fb8069b34bf5522234acc0e3dfbc9c5 4f9c2c3dbe1b5a73694dfe3087f455d879729775e1a34c5342adca24868aacf8 0000000000000000053174d92cca33fa9046cbe0b59726c16d66a917e6292aa7 +351300 0000000000000000038aacd6fa10f0ee47956337238a5920b637b6096a29a846 9320223ddf2ee0049eea947649803c2d7d995ead6a2d83672f3f69af94e9c06b 000000000000000001a16935045d486aafb67add2e914b5a115f3f2fe6d92a40 +351400 000000000000000006c6502bbbe65c8d07bfb9a5ddd0799e63e24cf11c77b58c e021a29b0e624f3bbaa9729bcff17afdc000432f5d0a8bc405722111eafa25b6 000000000000000007d6edbecfb182503623ad3086713815dcd47c32a2306646 +351500 00000000000000000a47f4d52ce52769cae80c40cb172ad12ebf9aeef46b5f59 89657735ba58880648eba8a4db861707f10ca0d5a17d0e38f66be412ef0634b8 000000000000000007a253dc8ece83c0f10a0407efd88c52056036f2e2472f6c +351600 00000000000000000ca3ee08feb8441de108ffa3b3d5ba75976b29973f967e47 db16bf686eab2b73adefcbd1626f5af78177ab4f28c6405a7d35aeb7d822b19a 0000000000000000054b0d24e38073dc9610f50e93e79929caac7dc6f15bbb68 +351700 000000000000000006ccfab6a5e6aca39a85cdfdf44e1d158899a5bf040a4eac 247468b2bcde1a46bc8f1aeda2ecd51821119b0c22edf3a42d9829f8eaead1eb 0000000000000000163a1a6cccd5a2eb813a96c2d069dae583292656cd56970d +351800 000000000000000014a981dde606376678409a62aa29cf30ca6ffb4d5e006375 a90a68343f17b8f169062945ac3a8813b94855becb11acd6c5dd878f8770d154 000000000000000005ce6a482a7dc969912bd0071af86e4c0edd9c2bcf169d9e +351900 0000000000000000015533b6218a79a8a30c3eaaf053e2122af36abe473de2f0 4db124c5a611966066dbfd99eab2b65dffa25198943030f6ae60f3dd1fd7d10c 00000000000000000824ca767bb347b8eac88b0c6ce4623cbad26106dab7ab13 +352000 00000000000000001635a4b5f27d2ec458f7bca550d71f490b93e98e7a07cbca 047c1b9267a0f72bfc18ec8991897434d032f1f9f23727590d5718efa2f7a7fc 000000000000000008d042a9fb824233bc40aa214bace9c05534d741580da39d +352100 000000000000000005348ac5d0246d0fa0b83b9147aecc404c9c49fdeeb4c7dc 87395c1dada75bf6f254d4ce05019081ecb0658135c3052e0403ab66592da0c8 00000000000000000d4848dd54e52f1999eddd0cf8fb94b0f953c80692ba014f +352200 0000000000000000128179cd2202d75eebed9f5e40b2949e4d35df4069a63415 7fe81de878d36510260ce82e3b2e9bb4702274c140da31b264a432e6f841c548 000000000000000002035023219044a6281e0ea8992b99e15a89335bd7ddeed2 +352300 000000000000000000160e71bea14f0aec589202e5ee45e680af27108d2624d1 5c0235ea3d70c2578e052f384f5704a6cf33aee1cdf08b8c60ad7a70294171d2 00000000000000001394d90e602cbb17766975c701bd987fb95c554b18b53d48 +352400 0000000000000000004fc54209192fed68ad012237ac4f8e7e814cd5ad73a870 b3456c175de0106043ecdf739596c04a4a00e056d50f58f291fae1066a96335c 0000000000000000039dc7fc982749ed8c81a49d64b5458e00738e5ed24a0062 +352500 00000000000000000d495be22d6c2691375ec3df2a319740c99e8d95da26d0b9 7a0fc93ddae347a7cfa72d6c6ea85b69e9a93383be262f377285d459e4a6d7fa 000000000000000005d92fd9e46cfddf48a935469bec9e24c383bca1264b20ac +352600 000000000000000011db3fd0e918f6d5ccd38c6788dfe51845a04e44fc3709fa 1014d58c3b952cca3d0a9767c6c1c1004fb4db9a9b32a38619070bde0c5a583d 000000000000000001dd7d659dd7b7f2a82668d4b31fa4d58a4e9c39fff713db +352700 0000000000000000035503ef31a34f821ee80474e5b9836a580fc1fafa6faa75 46451ae60eb529bd20031a2b23496b181dc9a0c64d40c4e37a2c948fd69251cb 0000000000000000000b0f82373b32adac1c13dd5242e52ef1111b58a57b1d19 +352800 00000000000000000b28d69f3103a15e246dc0c72e4eec99b40f351856eccfd2 a4a4853823380af61b704fdc1ccfa7ad28c8bdbadaa37c57a5c5f63ab6340319 00000000000000000237e36563270937d012404a82d1c9a9c374bf33401d1486 +352900 00000000000000000694bff224d3b44686cb64873c5696195bae4767fc96c793 bcb6125fa131792ea6a27741a888003dba3856b189de6083c5cca7a271d0e57a 0000000000000000085367b53f137eefd3426ebf34e4b998545b40932484f8ad +353000 00000000000000000054ba1150cba12f19a604351ec95cdcf3c642b6db4c33a2 e18cc1242d8da0cf0bb138f1027559c2d773a3805cd7f4becfe50b597554cd30 0000000000000000112dc63cff9174a5d0258871330a416e7588ed962b0319bb +353100 00000000000000000cb56fa1e5a75e7a1b7510b5c80e7479d5b4e4e6c099bc25 ca4d1e5be6e2c16b650d3f632db2c28bb5d4c9b5e81852ac331b5a46ceda8f1e 000000000000000005838d258b11f51d90b130dbf5c41edbb0a7997de0c7e359 +353200 000000000000000008dd16fc62e78804493c4c67849697fdcb3a34df6b981ea2 c7624c684203b089cf305ca5ee158036672a4cd6ba251ac7bd631373551d7534 0000000000000000134db4b68921393f37923b0a3a8a1d6d5241335e04d2609b +353300 00000000000000001064eb5afa6d3e0c32ae918b62479acd4e72f0fc7e1d1848 5c51b2a7f427015a4be8424f9104eca0f8c94472c55e6eab4bed126cdf1a8c04 000000000000000016279a15a20899990dd4a1c76dbfc902c6602ef8d8b2846a +353400 00000000000000000cd4d97c6f29f5873b544250dbd3d827540fa49c7a8a91e7 da11b0c1353c36c7e68135b7b40223d3e0971011af6efc67ae1ba26dc2216c4f 0000000000000000066560b7e298316631c275484893df8fe05788b7c9d5d003 +353500 0000000000000000159db60b17bf31fedf79fdca7843480e668e94db6048ff2c badb2063f56ab053e5659634382461eb0c8bcb232816a602057807d90b37167e 000000000000000010895e324df14297b92f985f6160acbbbc8abdca6c692662 +353600 000000000000000010b8b6b8c7f81d410e83c7248439931c7341381be404c012 cdcb4c978d0ab51ba005ffa4c80fc3eae8f44cfc291f8774c9dc6fd90789a0d5 0000000000000000077c76ec3b5e4fa92ed17eae4aff832782bcf7c87818b9be +353700 000000000000000014f8d394929b41a0415d9593db0e71dc82d9bf421d7b7ca7 c09b253f8300700a86299ca6b233ffc104ded26ab543c3a2032583de70d6e6ee 000000000000000011945337179e5eac5ecc530c9b064a6ec9e2ea14ceaa9b93 +353800 00000000000000000368f4fa1757fae744a02ebd4db6ce25f76e5b9edc3676db 57d61ab9d5637adf378892ccde80977b04be3ef7db0e4f75c864b22ba534d9c3 00000000000000000825b0b6b2c3c9dded19123d7f0fa5f535ba1401d89edb0f +353900 000000000000000004c6d49f2f147022933c3cb3b7fc29c7b57296fbefb9d422 2536574e50669e772a6a6f0eacf326342810cc47731220b38788d52fd7b160de 0000000000000000013bced982aa38c9a1e4eeabfd038aad95821cbaafc6c2ec +354000 00000000000000000cf8af9be2709e9d7adf2c33b3789aeeff517987f4be22e8 010ec89b442e1b6599f95672974c407ad002d68060933c87688f8e5d36033bcb 000000000000000005ce357b2bb22f3e2e770a89d9f81af07e65aa28b11034bf +354100 000000000000000013cb02e7fbd216d3253d299ced3a7561df4eeeeae3f63aa3 fd14dfea35e4e237456bec9501e79a80154513b6910f084ffeface1551efe09d 0000000000000000029ea0c2c8783cb4df9d69007b7def61cc202d85e570d800 +354200 000000000000000009510b9c6a6f862561b98f8291f27f0da9b953632d221b5a 1b8db324e406c4f1f58695381a0dea6308a36d26c55da04c874ffdc45840fa56 000000000000000000bbaa23409492ee804346880b3f90ea3c3f025e62783444 +354300 000000000000000002f102d9352e5319058e24c2ce66e6d112ec7143cc5f90da 65ea28a19d08ba0517f89a075fbf225819718f873aa513956ae38d469e87eb99 000000000000000006dbba1f4cdbfa878db108d09ae87b114061914feaa22674 +354400 000000000000000006e123b68f1a8677a564fb8bd32ebd2fb9708073b99c2204 d6d9e92ec37afa48cc4322002d6b80f2518074a07a257cf309d8af8da04f9ffd 0000000000000000160e11f2b2f675d7e1a93ef7a0c5ee8cb8e37edf0ac39104 +354500 0000000000000000155935cfa788ed8a9c7fd8bccc80f793028a3ffbe0810260 64dc48249390b6b07383a5e7cd5b181a2fe88a4447b6e5f898579905cd423d1f 000000000000000011324f9fea719ea6cab931e4260dca51fcbe4f8d74b944f6 +354600 000000000000000001e3b9236b6bd185f47f1b110d4cf2abe82577e1cd8d6668 d3b2510eba2e3cffce3dfa18917944953b4c361e3904130729b55637c93f81f4 000000000000000016de83adfa4281b1e826ece49a6a066ea0de3dd273e59b50 +354700 000000000000000011dfb97b913a32c93ff6f23fe7d90d09154effe3a149577f c4ba40dd3cbac474d0907768ab1f361ba532df4cb2d45e63f33be26683306204 0000000000000000156826165aec217b60477045be1fc55e59e417d1b91b6e3c +354800 000000000000000010a413706af68f34190bb958b7cda7e205f001def86b6430 d18592878981ce588285e34e1056b73eacde29e60beb0f705a08a0fefa6a82c3 00000000000000000eea7920786a716487917011d9b97f967d952cb7b5eff237 +354900 00000000000000001229f6e4f291989c8bfab9757636efda7c08c3b73fd3ae83 28e2286dea028bac3b8c59e8300554fce27e522898e817d7064d5eb81408eeb8 0000000000000000009be7759c142ee4f6c9d4f67aee7ddea7ddd6c8de2e3888 +355000 00000000000000000b36c1f926e9f4afeac50a580d220c38aacd0185ffc77126 67cf758acb6f8137db8960c9c3b01681b11452086a628eea09abee1348bf3dba 0000000000000000149fb3ca841309360d5f648ba1e36d0a891c165dd5f89804 +355100 00000000000000000a15b3da3a959a9c5be9e635baa76e11a582fbade406f042 f1b30ddd73a6ba1c5ba03bf2702d2603b93f6354ccfed9d04c949678632e8c18 0000000000000000075335f99e7f20efb02dc334afa26458477628cc589e6317 +355200 00000000000000000692aecb6e09dc8f71a1380a3f49aa954dcec9b166f3111d 46d12723aa4064c85ab541e7644098ec96b547bd4f84ecfa6dab6d4638b7158e 000000000000000016a56d856caff79560a4cf8ae0523c2a59e0b379d8f191ac +355300 00000000000000000e9fd980303cd9ea298893caecd6f2e34af241bf63f7b2ef 7210450aa2b2fac8f5fc33cea02ff7f43674db7dd54874458117977588003650 00000000000000000a5efbe463a4baa60ec1933e238220f7a32ad760bc1b2689 +355400 00000000000000000b7c5fa8cf8e7eb7c8fc191da7d798753d01b8deadbe53e8 a611dbaaeb72618014b3d4df736688b9cbd74e8ff0c2cfde0307a2a392b3f06e 00000000000000000e9aac0f7321a32aa3374befbd7222565630d863221a4c98 +355500 000000000000000012b2011e6cd633d20b967e5e8d30cc62d546a67f52a69ce5 65ff00528dfcbd7a0e28abc31cf42fa361d0c57c64f5a4c707cce9e4a45c6bc3 000000000000000010060501463ba6daa04ea41fcfd26cd8aca4b04894829206 +355600 000000000000000004bd67400df7577a30e6f509b6bd82633efeabe6395eb65a 3616e0150f7e40f24008d11cfd138546692ca6c2fb39fca805429fafd11a7727 000000000000000004e712f487b7da3059b707d86c0b5100ac7ac49111108007 +355700 0000000000000000012014b28848c735a362a5c78c2e8d41c38807e674e06c5d 12422da4b49eee62dfc234a78fdbfae70c68158f5b497e0e892c9516a2256022 000000000000000008f0c2ac23006377644641b8b784a67f0d522b04c91db8cd +355800 000000000000000007f18bb9bddf0e0aa1c17e07aff0afa6795f7239f37595df d20c7d9e4865dfd38b7e44d959bc48446a25e6ced983257b6fc48e16e076a9db 00000000000000000831c281e0db589b518e22e544f97a8482d2f4be989ad9c5 +355900 00000000000000000427feb74d5784ec55a9e0f060e0328f7220433477d719bb b5a53aca7050ad85ec80439d5ad84237d63edd5770b72b2b12565061cef78e3b 00000000000000001147e05b51ccd69a17b8ceb8837c97ba7fc48dd09bfbd692 +356000 0000000000000000138ce5493b612b0e90b66e2a76714088d6b3e6a4770215af 3671d2ff06a9ecde8b3594969141475ff2f44c2576a11c3b77b58449ab030ed6 0000000000000000153c94e6c7510bf67944d7b11e56de38c4c06850ee19c047 +356100 000000000000000005e9445fb3604373e39085f5c695e5db0c7b013b520414a4 e8c2d93ddeb318e138d42f15011e988d79e90d124d199f0038bf486c8454f5fa 00000000000000000b63d60592654de05fe2af42d17fb851c302d172d3afa49d +356200 00000000000000000ab4e915a84f0171b8105304325b6d0a25427a6a20d55774 00167a1ac15765450a2ce7dd1671bb68fb4d6d11ae6f1f9c0a85f522733bad90 00000000000000000894b3c4a932b3255a08ec07743fc1d720ec28fbf7e57c26 +356300 000000000000000000b8a1b5f2e82280c61210ab8562c2d3b7cf328a40ce247d 5e7029803c55dc4faff85fdea8c3378bf8473a214361ecf3a77aa1002a62ede3 00000000000000000103ff98e91fa5d9f39fb4b032fecc0d69f9f89f5f1c2ce5 +356400 000000000000000014901c826848b6e944fa832c1fc532f02b983f5837387464 c98895ac101e80638f81bfbe0926db67097a5d0e96fde1ba3544e27538327466 00000000000000000e8fbcfe2f0933f9b7b578eb9fe715ed4172cbed63ed9fc5 +356500 000000000000000012ae289abe9f33b266bb08d65645b40ee5b0e3d4dbd329f5 1869da2ae94f42adcbe31fdd11b6fa99d0f2db4bc0fa88cdc7f46e69e4a1bf09 0000000000000000113ce10bb413e48bf3d1823de912e461f8a555fe6a353e9f +356600 000000000000000015ffda7d373baf6c07922ef8e831bb4c7a448111ecbf89c7 63b6420d2ff45ba2dc903d95dcb8ada510ea53418f984579c759a933eb79c9a5 000000000000000014e5d1c16bdf02dfb3f9cd6c3ed481d469c7bab91996be91 +356700 000000000000000004d0bbb9462d7c784d9b7e0555b89dc57513b18d7d3ee413 785618287f04c2bb3e4b3f657fa7e616f0df397413951c3c62db228c645ed631 000000000000000013d22ac7f29342ebaa7ea6dd6d0a0db8f511972b2666377a +356800 00000000000000001674c677311958fd61fa4676c969b80e3c2960023bc1cf64 33b4ec2ff378b962405341a1cb4d5ca1b16be7b3ccd7dad65f6cfb3510e3beca 0000000000000000124a96d4fd86eceaeb186e19d659363eb6bd6ba0dfd8a49a +356900 00000000000000000830ca542c39ac262ca2ae51b0a9a4d32450e81ab69c5e82 7edfce5bff1d68d98dfc85f27fcef2f4a8b48240de55ab39118460ee051f117f 00000000000000000f680c1470e84d1158e0cc4bb9b0a41b8a0792b5322110c3 +357000 00000000000000000982a6bf626dfae76e953f580784c7956ce62860eccae4cc 23a8567065919ead3c1bfdb47a6bbfa140545d4d0b177f6a3a1486535d6b873d 0000000000000000052ab08d226c5683653666f4e03f64c360a579ab15322d6a +357100 000000000000000010d16e35c90c94abcd5f9029f324f69a2636892bf3a9f7e9 5a6e32beebe8e9dfafd1f5d337b79986c0a0b58e2633174f63c078a801fbb3dd 0000000000000000002b70a344b2975003aaeaf943e48a8c3c54c5d96acc8752 +357200 00000000000000000921399e10ab27ac7901b579b645abc845a466e014d0234e 2711359de15b08320eb7bd8f01858fa211bde9cc3c938980084aa37f72daf680 0000000000000000003df816ed67d564a9da6bc9968c13101a3e7369fb3c47f3 +357300 000000000000000006e8931b147f76026713a519b55bd68ce232ab2d0ec53baf 00b3d9cf1fe8c4af5997234a548fd2123a9cf5258be58c158facf99e485d5106 000000000000000003189159a4a486fc1190c1106c725a437fbb3629ec224cf8 +357400 00000000000000000bde0904850213a1915a725dd38523b1b33b3f1a65e6a047 86e0b1db3ed6eea2ad632c4deb6c1db9b9888ae67ba023eef6ff8f659f5bce93 00000000000000000b215ef4fd763bb2fd485e5364d37b707786c49d15e1c6c2 +357500 000000000000000015e8551f12d2e4b8bc262e0415ff09e65691aa1a87416db8 3ecce3529288363144052fa1f344f1f6657da4716a33eaa4dfa9e09d17a6e430 0000000000000000104e4b5bf9abfe77696e0433bff7034d528775d14de3e462 +357600 000000000000000004abbdcee52c22106b1d18c945e9176681def1e93ef8e76a 1e994840527e424b418e772768106a5b8708c63c619cb23091ee7fb10410c31a 0000000000000000062735ad9aecb2ca32b4429f68afd371f8786917d4d0d7a2 +357700 0000000000000000166f4e04992975306fdf3efc8a658fd27e6f93bcc2ace885 ac199a47fcd6d3cc0978766e3d0e56cd35dbb73b07811820f7937b8f840063ea 0000000000000000076a82d268d098a555e7797ea78e5315a78819adbd576e14 +357800 000000000000000000131b590566124ef4551706a80a3e6251894e5cbaf3bcff ab0cf3b8bd61602bc60e083b2c6205c45e8971e74a8ff8efa1cdaa30abd3c2de 00000000000000000ad0f2b0661047746d0aed4cc60ec903299b633a09ffb276 +357900 00000000000000001173e320aeb17bbac52039bef4e2cdef5d1c66fb12003317 ad97c0be459a5427e4d2e7c900f83a004377c86acf58ffd3b355ea0b4fb68c4d 00000000000000000f552861d8b9c2edcd6684789de50d6863c32b8800848b77 +358000 0000000000000000073aceefab8c381c3c4edb4f87a6d5d2ae32184278218429 0be524d456b9cce62262206bdbb7f0bc9be9a66b508080e4fcc0e3a30b73f9dd 00000000000000000c203f910ac1def0be1d848535518369e159a73002574a2c +358100 00000000000000000aa5d042182ecbd6ecb322c9e35af8a51679d15b3f27acef 226264e18cdd018536edb1ea30ae033f729eb52c1cb80a3d6e25a4cac31e07ca 00000000000000000faba00bd273028bc189e6d9594133aaf0246b1acec19495 +358200 00000000000000000bd32a877e4ccf315de3056ee659cf538e0b39121445bcf6 4ab83be7aa5179f658e69bd31e5b67d325b7b78ce69b5cc988f1106809bbc32c 00000000000000000020183ddadb62903ecd0148d9cb7e58400acd5e26c80e6d +358300 0000000000000000146ea3aea202c05df468b143cbc966c38f003adb9778f5ed be9b56a5d19526625d81c01f586facafbbc4d878f27777d7790e91292497c96c 00000000000000001389e5b6c315202d506383445579c410df137a5e997f29c9 +358400 000000000000000005fb51818f3dbe377287440895b31af0c01f7dadcc4ac412 faa0b8629d491a35ecc2c58930981ec708ea6fe150911f24767fa446e57a362a 00000000000000000829e286c712448f6a45edbf5899b34e5f2c712523c470fb +358500 000000000000000009d5c5a4461fd1ffb6b4c7c0006a78734bded13e1f349503 ae3aa391f355ddec1b3cd9d6019588d62fbad9ce9b1097bec7f8f90cf59cef5c 00000000000000000f207fca2170921e252aefa7033986f91889e37a5287725c +358600 00000000000000000ea14000a1ccd304854e279408608a0ca1b8de685e1ae06e e98724255f034dd2378ad2d2173c6f84f75c78648232be60effb1e6eee690c63 00000000000000000f31829d447ef1b6c9a7deedebc60f13c4d2586db663aaec +358700 00000000000000000228637be2ea72543391edc9cdb3774b166516447f5a26a0 1e9037fd870347bc2f44ff4b56c30d03f66954edfd4f3c56cf7bfcc5e57685c3 00000000000000000c499e423dd9a0b5d74a80ae7bb9f2011109bfa862601100 +358800 00000000000000000913934b55ee19166e0094eda9cf94b7f1e94a8210ce6f13 dcd4fba880858baa9953ee5db81e9092db80580900021adf4b055a7c848832b0 000000000000000009548a3bbab68f488f51a11d9086dd71f34471112c3d9be2 +358900 000000000000000007237a1ecba5269adca47e00747239800d1167e31e0013cb 57999cf5d2405201c20ec41366275c6c41e3d4bccfe8ac595ab7ab8c7e47d0fa 0000000000000000081cfc3b87e2822fae31f2914783734b02232495558d7d10 +359000 000000000000000003cd67bf7e67dee8ee0b17c957199b4f16a7e44ba738be68 ee3a41c993e68f85853571cc16b004aaea5220004524b6b9445db7b575466666 000000000000000003708a104f7d4381d89ae501c76ce1bd376fe7eae7af69ba +359100 000000000000000008b728914814d4fefbbdfc29ed3f0862d418574940ae831e 5fb24ff7945ab73f7f4d782c20cbc256c02e3a7123145ac73c77a3d595ddcd10 00000000000000000c9a10da91cb897fe2b5c6ff7afb156b680af0728aa0019b +359200 00000000000000000f27cf41eef27965330f9e681f1a1d6786056946dc3c6288 f03b1c0a868ccec73c4b3fc6263ca4b0518e2297fb69aa6fce0eae153c5b1b72 00000000000000000b5962d7c664db8e22db4061eeceea501cf7eee001005e71 +359300 00000000000000000905f0ed203b08a8e39afba1e17c60dce01eac7df3dbc562 9220542dc83897229f06f6fc111c1e653597edb52dd344d468b20a13ec01c874 0000000000000000091620833943b0b9067edd2a090a234a84c36a7f9eb379e0 +359400 00000000000000001110d2129146b3ed37ff3835c81549bf7cdc009f5676fb0d bc7567ca2a2f265431d89956cb2e603a8b17c1bd530a062733810d9fb7ee234b 00000000000000000606484e54b5496c13b1466d3a10e57d3b00b93fd74fa35c +359500 000000000000000003d91eb789b648265dc66235afcb1e68442de26313b12cc8 683e2beb620d67203cafe3dc8272dac3ab0b6205935d0cd865a10bf1eeed1e56 000000000000000014b58080d4aef8e15d035fd2797e9fbabd1cbfadb83ba226 +359600 000000000000000005fd21b24ab323ffa9c431989d86712f51db91c91c0287af e1c74d1945788bd7314873aedf9730185ce3cecfdc4d3a316d93feee5bca2c93 0000000000000000146194d1ed3ecd067b0673a5a864d5f547e3d363b170ebf7 +359700 000000000000000005b888f9e266ab5d54a4635e0b121f37db831c605f30acbd 374f165ea85a83573a2bf6ed9747bdc5ed9caf3c63e707329bd0d9cf0c2c5fdf 0000000000000000097cd8c59feb3a5e1b0b1e077952bbce74a54d74f3890fbe +359800 000000000000000009575113b886e91f8b173e4b243d83429f939dc11d25109e 03d7ff00f4765da324b694de5d09172e56605847f362db6406478dc624ff55de 0000000000000000068f3e46f9593f164f65f49348b2dbd5286d73d97e0a3190 +359900 000000000000000016386d4b58b3bbfd18c2552d65ae76d28aa4d1ae4a6d4757 9a0d060849920bef300156a6467a241d0ee0fb558be1f43f923a758679b2b604 00000000000000000d6e499fe7737df5d02cf7657d129b50fffb003231fc60df +360000 00000000000000000ca6e07cf681390ff888b7f96790286a440da0f2b87c8ea6 02f48e81c0a8b65e8bffc42c6f9fcc7e51aae04b9ead99d767a23bf5c57ab40b 0000000000000000144eda4e110a9389cb8e6a301366445ffee980862faff5bc +360100 00000000000000000f299aceb4a42499b140da4fa352ef234c8842e4fd58cfed b73861010973abea2a1f97eb253840e7f7e859acbcd7a76f8a77162a03708d72 0000000000000000078273f4ec4823cade008fb1f46494d1d81267e754ee220e +360200 00000000000000000599d99aa420e018bd245b6e7fd48e490041ab2f9a0aac38 5163761e172d5524bff23079a06bf8aef0f3eb9212b3758ebef54dc2b9abad32 0000000000000000137757fc37a57f597a844814ad29c898be4dce19a925481b +360300 00000000000000000a319eb6e855726d67d35e5091725f67cb086abbd80aeb2d 3b34c67e5a4eca6231f815f950cefd89ad5a0eac0b81bada6412787107e00028 00000000000000000486880ccfc0703e3e2f5641389c078c51324137c1fff15e +360400 0000000000000000033487aea3d0a4fe4028acfa6675be1fd3e0f5d31378c11e 18504ac12baacd0fe4ef5f174a975358f066a285c005992a4b1afaf2e0ec7df0 000000000000000002cf528671564eca9636d6bd328c55e0ab8f93e1157854de +360500 000000000000000008c046a2f5189c5081e76184a31609fab9d2383161d14f7e f39113003bd596faf25a50fe3ad684837af002e517f5d68f96e3f55763bc8372 0000000000000000022ac4e015c2b9672a23fbc70c294b1b5bb397df3469b656 +360600 00000000000000000527e6ed1016756851ea3cdb88436d780a69bab0268827f2 9845784e4bf7ddb02ab181c12a13f7147d7f8b1b389c943857bf85e1cacb06a5 00000000000000000cea706491da61bc755a1250d7260becff5aafc9d26613f2 +360700 000000000000000011b76502e54218d2aca740e165ce3b5e92a1cc99387b2a69 5303829671189edaaca535f6008de9aee05521bc79472051dd94a65975233093 0000000000000000047ffa0b67408faf59375a23566bd2c6b183e5aaa49005fb +360800 0000000000000000151b2741b37b9c1a9826947c49cb8afba5bb812d36ead66e a5e1a375074043596efce847cef5de5213b15badc71f6f625c46bd73d2cc1a88 000000000000000012d5693b35a17634034a095947d8c5b64eb9fdfed584e2b6 +360900 00000000000000000a355d5ab6e152fa020e022b5db3d33daa08ceca479e5182 6a28aa12569127851e2d8ba38922e981d3ef8524bce7baef21af23864b97f0bd 00000000000000000d11107d56699c64a4e75b9c78bf91ccf15cef02aca24c1a +361000 00000000000000000ceb6d36fa5aea8ffee6919f7e8194aaf0e67f880feb4462 9a357451dea6c8bddf2128cf33b2ebf6ed40c69383b905556240b6b5fe47d6e6 00000000000000000c5ca05602ff6633767c6305937ee1a3ebf7cf1879614519 +361100 000000000000000012b5c7215c5f655b60969167cc11ac1e2ae84694510abfcd b5f307871ba0511e76b7cbd62d1bed055e1ad0a0fd1e212c9aaf22aba52b074c 00000000000000000ab096f26f33a2923fad164e30b1074413ceaf2eb7d22343 +361200 0000000000000000018e10327f68297af7757a8df5e8f25aae2c1e6211c19b0d 4f15a6bd02619a14ac74ba5070807f2754e2e3ec59547bacfc546ca99495d4c6 0000000000000000130df40a025b12e2f33e88deb4545201e0b31c263da0776a +361300 000000000000000012ad7c5ad909dda1bc5e918c1f6003d7baae8705626759f1 cf11ac68731a599ce44edd5ae1044ddc862a1532e803db1d3708362227957d41 0000000000000000062c8db20ec229231ffa6ea33ccce2335967b581d909e885 +361400 00000000000000000ebec6a5ed6b70107a736b0c70d05dee1011751c1ef5c90e f43b10d2f91bf948d21c60503341a2304a6f7ffee4265b1997ffee843a2c7e3b 00000000000000001475a040b690f0cbc904b201513fb633ef904e29a3fd1bcd +361500 000000000000000014819524cd66a60d72943125efcb06eda7e810faf72d2492 d4d79620eb3a46c5c358cc7fe576b022af5aed75d4ce7c1965f4fd40e0e4e098 0000000000000000045d4da3b39943a235361b74ac05d4982ffcdbe782b5aad6 +361600 000000000000000011b72809e57b2a678322fdf6ec0123f7b4a72843a32c3c1e 2b7657c3a9b1dd08df10487ec2d53391918280aaa170ed460e851361b72e3e00 00000000000000001465d4483e6890396f6b1212f4d0001d87f3b3ba6bf45334 +361700 000000000000000009713a0cc8c976d25aa13f805375f02b701987be18774f2b 71ee71efdd442eae4bc4a768fa690256883144d1070e26280f861dae5c7837c6 00000000000000000b6fac32a0b9283b744fe0040d87d4f60cf529d32156e533 +361800 00000000000000001208faf61f905d2b55d220b7dcb17dc4f8b755fa94396855 0a0d84faccf891de4e84cb43ad234cd9c716b45a67338d5b960e864b645ec762 00000000000000000a1e93a6d37441918ba0f3b1992daadb14f33e3f5d4a930c +361900 00000000000000000807328e756d102b54fdab6ccf3995b0187353974cca12b7 7dc7a158be5a98900e50e08f1c8971ee4b1c64af6c92aff3d1061d003bbec5a4 0000000000000000047a00cf370ad3176877f58a400d391cc9ec0ba0ace4f41c +362000 00000000000000000bfcad6c331dd152cfc713e9e0790978a10e0bfda3e030d5 2aba8461dd7cd40d4511c511ef44f54969051380e948506b82a61d9e397057fe 000000000000000002f032a6c1d8fcc634946d36c10e1e1501d5b954eb82f726 +362100 000000000000000000ad20946adce6d8caf603cde195848d885cc89d8092d8c1 2777b37b168dac2f6add965692cf74f55de1dea1ec1f7470ab9cfacb70f1f4d4 0000000000000000076b4e2e528fc121f06db4099551316242587437ed80aa62 +362200 000000000000000007af2ea880abbdfe94aa3e0b36472c27db54423178898c98 94c28ce3e7d1582bfc6c4e03d0cdd3469a692f2fb396b9152f22f2c9aae61b5f 0000000000000000063a2828f2620590cd6b40e6af35badc547aa9a2a05a5836 +362300 0000000000000000150a96b5bd472a72bf4d16282c1a9df3f8db7437df1e302a d1b5b8b63bb30cef98f9e9096f3c8decb79296c5303d4ce5bc06bb6b893c6339 0000000000000000147847961cf959eac1f3fd205f4eab250526b0ede4ad36b5 +362400 000000000000000001730731ef25b7bb62482a213172e122cbb149bf8b0e120e cdf3ff99f2d0ca6f69c99a0436a50e8d627fb4d16c1bab15f2d969837395bff4 000000000000000000104cf588bff57ce919809184277e2cb629bb5f86c0096c +362500 000000000000000009f7f778f7de23db06f7435813eae679999f544e5e9d3534 811762a487ab869fb419cf311aae8495999a7353c109e5535e587c5d06b876e3 000000000000000002c5d5b9f880b4b4c00ecf0b0aebfd750f73d610b6db3773 +362600 00000000000000000b4a83cdda6c369a82b03808aecb941e736e730da3a9b532 9f3b0cd9b0f5c971addf1c667dc1e6dfa51ed2560d7f75ddf228732f30761d78 000000000000000014a43d4a3b5b5fc338d7057ffd6f3706c2a000b4c09cee5a +362700 00000000000000001618c67acb9e26c946a10bcae553a5160699445595f7d035 d10c6fc66f40d4c82022899666882102e761373f7b1bf7e1ea7952a5eeb154ff 000000000000000003d5e22eb3132397c3b9e02a3bd3cc2d1612d582eb5d50b6 +362800 00000000000000001583481b7b7857ce2824a05c8f304ad52540d3af9bcb4753 713b62b11fa72f35d7cf8066b659d529e13258d3c7c69bfd3dd9211024b034b7 00000000000000000c7d05e1e9ca46d56cd85d59f037fca5479277bab9bff8ed +362900 00000000000000001147790272f4d5bb082c410f539ad4264424369b1b9e9cbd 25ced4086a0125b13db68fd33dbfee73247bed01dd0ecfc9b6935b584e2d7859 00000000000000001060bbc060344a257662a4a279776173368cf754f7636ef6 +363000 000000000000000002397b76ee25bfa86d6d48d16a9fee770054466a0e75dddc 3ab8f5b71b42d3ceee5c9eec71393111c43b70c0bebeeb6e3c7a8a2663f743ed 0000000000000000157cc432fceff48e50fab73048c379ad7e0c2bd0e05fdedf +363100 00000000000000000d24db0d452c7839070a8d2f35bfabda85d8a598ac32c546 7309993b590f10871007ffb0725c0b32847dbccb1616cc3d86f51e602c1b11a5 000000000000000001769c7f90eb8186cf019b32119da1b213e6417cf7abce32 +363200 00000000000000000eee619db9d6395995bc6ff1469bf7dea251eb72ee46e23c d78fd3a08e0df0a292dcd5b361ab4fedc37ede261c658a6f5a5d328738d08084 000000000000000010d171a21cab5a36167ad25437461463ba2392bd4b156bc3 +363300 000000000000000006a5d8b3b2ac85007e57148b5c205f62d3e84fb3dda36235 cb197fe6514a2404540e88d95465986c7d287244ac6e6996fffbffd09c3b65ad 000000000000000009143ab9ac9ce338502ac37f0c7a6384c1e4e04d6927e7f3 +363400 0000000000000000005cc6e7670c89f63676a69125c6317229984fc23ab8fc66 8d09f8c18f10e1d52087634711d816158f880fa904bd52d8b7d958e3497a037f 00000000000000000e460f367754ab02aba2b27e434c457c9c7febb2f307121d +363500 000000000000000015f87905a667ce1a93f365d05e81fe0eef7d9f08f5b0dffb 5df05523c69118d7203af3b7ef5c3ffafd0f6562eefe798025f231360fc5bc7d 00000000000000000a7a9c4587ffc45b45aa2bed5a2ae06b9234ab2bc216c928 +363600 00000000000000000816947908ac7b9615cf448300d53a1be6423dd6adfd2b4c 4d203195d4872113619281eecde334169c36ec6e270ff39d9dc227d793667b71 00000000000000000542d3fcf26029cb66d4f1f9f38f70923a0e440f3e4d0d47 +363700 000000000000000005efc7a5559ad30d06f059cf9675f2367549fef0d5696c46 a67b5620de911d56fc81d5d7a615d64ef06bd5eedc61db79f8a5d1c6c7c85b4e 00000000000000000d05053f98fc62e2a72589a08717f56d0f88f227a36fcfe2 +363800 00000000000000001374fc855cd16ca38e470022980934113e205261a79d1afc 6c451a81632287199a49546e67bb6155f42e4bff9444e5b638b0be82bf575de6 00000000000000000f3526798f3671603ced92cf35c07e9ae13963d214cea4d5 +363900 0000000000000000046fac968dea0fb6cd1d9bcd5dd30e794826ea152aa56058 2e61c674f6facb049a871f6d74a651f3630f8257ad229d14a9296d90ab701d46 0000000000000000117992a9c5c560eff6e0c8256b7585049daa1ac84ef14f1a +364000 00000000000000000e20bcf213a0bbd6be88d5fede6b060c737f7f8b7f1df504 05946238d3da9371e6fa3f6c049b369c2c10fe65f2caad172283092d213f5e49 000000000000000004cb2acf1a28acd9d1e06d71357ed177ad61b9e6b8562ea4 +364100 000000000000000012539f9cc04158fd7b52545640c4f74534223ec3812afb0e 0fc8aa0c20cf40a48f2cbd2ecd1a84c7ceeaf200ffb823109205d653c5ae7466 00000000000000000db23697071d3e7bb404395ebd46db4df13f15f1ab8dcb45 +364200 000000000000000003f4af196303e713e5872782460e99161cca7fbb5557bcf0 a5259d30b2fecdf072e208cf6c22a24f2e53c263eade18dea0f82bd590e01ad2 0000000000000000003bfe6b2496742f6c187f7dfe9b7fe8ed9a97263829a7a0 +364300 0000000000000000132d3c014c8f5a99a4eaf862c289d1db0a9f67a6c0a899b6 0ba16ebd7c67a3e9a3a7f84e455aef3f6e5de8fbbc56e520ffd871d3d6f38090 00000000000000000a1bf46bd3ffde11aa9754a90e8b4e2cea00618670260f05 +364400 00000000000000000b26638ad830025fbb9f7246eae7a6cbaeb00dc3a6786238 d8a06f7797cd87ac5df9adb556f1c2a20f959ed87d2e0891277d9066a95723fe 00000000000000000844b44257f6af97a8d0ee566e445c6fafb3c0de209f2c08 +364500 000000000000000009b23af2cdd1e1e51f0bbf858e1a407f90e9f020cbfa417e eb7335d45063ce0fac0f75a857924f797c6b03b7614fff3ee21d84d3162f0b89 000000000000000000a9b9953a5fc41eff5de2a0248b83f5a11731431800dce1 +364600 00000000000000000d04cf3a542374b72badaf78809c11717721816b54a7b453 162d7d6defe2bc0af2eeec564a11c0aba8fc0086edb7383c5df073250d561625 0000000000000000013d8123f3e911f61c22170dbd91dd87db01cc8bb6edbb2c +364700 00000000000000000ac626111f23cc0ba3e187bd2c00d46be4724d98d0fb90cd f9c00e2bbb82b965b529c6e276de2b6f4f35a3081822266cbd88e3816059dbe0 0000000000000000125f86622aaed6ed53470c62e5f2a25baed9140e24c625a6 +364800 000000000000000004da1a22d33d400a105b0859da717b6aeb4f459afe6fa812 6157893cdf6ad526e21b280361e6fdb71b75d89320878fc28af2a11923d8a44d 000000000000000003357b1a7d1b1cf90be1255b30ce53751c8c48695042316f +364900 00000000000000000da2a64a9a8e32623575ba19c3125077d1715c1ba2d3b90c 98fecc66072d2e3d66b6938083839e24582c217c4fb2d33e7c39dde0909e5770 000000000000000014c73ed90536ac7ffa9184fda72a87f212d8ade2215cdd08 +365000 00000000000000000d2e776c8e4df168e4e78d935197f4b639667c17f84b66da 5a1745b8e675d77b03387cdede872060581e32666a51c87cf78a53b24cc19449 000000000000000001828f9ed96a6cae4f0dbf8cd48b1683cde27692ef530991 +365100 00000000000000000dc481169d1006c6f7e738e3dcf56f0bd97502342c44f164 921bdc89b643bb3e3512c9adc6836239eb31e247d93a9be5239f57263ecd0816 00000000000000000a1fdbd1a5f78ed3e0d25b37b781e625bbfa5d518f43051d +365200 0000000000000000073672eb48dcea46025f7cd357806236d5e5c440f6cfd21f 6751fce30a59bfc946f58fd920eae190d8a740b3eb32dbd4306ca3af30b5817a 000000000000000012b29d2eaa3c7580961bffcdd86d8d7cc22c1d7ecc4ea0fc +365300 000000000000000014a71e369217a5d232e7f07073f0c29486610ef63bcb546a 822797f142375c579c12b2aec5542709d9e1e7f73a3e0f263a92a2016a5051ff 0000000000000000083ab8d4277a60109cb0f9437a3e79f08a3a2bc983356b17 +365400 00000000000000001368f0297d626aa9f0e68000590bed91d5d814061c264bea c7c227162a17db9e9d54e06e5958f23d10969ff0002155ccc5860f87ac0eaddf 00000000000000000edbcddba0a5f06580bae32f35ac964b29e9c92bccfc2499 +365500 00000000000000000b29502ea6dd8300fbcbc9feb7e07969f9d87620993f2b5f 5d138f76c7a3fce6155fd4a429ef5384ed156256c9de3b64c0cfe01e66f6e76b 00000000000000000681fc4e8ed41ffedc44bec24958af87d562fe2406e11ebc +365600 0000000000000000108c432f58290b88acf9db07c2aa4941decaa2a1bb236f96 a918f2a864eb76a3c5682286d6741785ffb8f8ccab1fa218f04fabe6b9aaebe4 000000000000000003e2eea4d9a21ed2410f570283190e33c3957249a4b49165 +365700 00000000000000000f89316b91e089eb4c48c32ab15c72cc1ed933593aea0afb 5f567c8d3acbeb3130d368ed8999fe908c5233764247820cc52288252f8f62a8 0000000000000000138147be90db48b8338de6d58cc6b60e6ad360f6ef486d8c +365800 0000000000000000129dc2f8d9615e461865529818d94b0263876435a55a3e65 46f553d9e9f10b30cd4e9fbd993f9c3ab6ad2ecf8d9e04ccef274144acc5dbec 000000000000000008d881b556a1950f9fa7932b07c982683554bae10db1d759 +365900 0000000000000000103e5e44d221599032ba9ad67b604ae06de096da518f61e2 aa91c2681663980c567e00ef02e5518f70d89dc0c8e4c7c652276366f9db0bde 000000000000000014be1a3722bb662a629d3fd2164837f99a9840c5a2e6af1e +366000 0000000000000000138e108e780fdb71eb4cad533b46445ab6befbf9687f561f fe0101bcb3e03c782724f14836e1d093bd000ab08ed5e47aefd7df1a7732b85c 00000000000000000affaf111f8dc332f8b2c3390c9a073d938dd1bdc5aec5ec +366100 00000000000000000ca354fcd06a5adebefd0b28e719cb4dbb3bd1593b18ea49 ea9d1efc5038193bb9ad3c0798409707627d125d4e225c3d96938a2defc9165d 0000000000000000008aed1a0f8706f1d422daee3b39528cc327d7131f906756 +366200 000000000000000012d24928fc20db3e8c45620e3450aaf664285a6decaf0da9 6f7d1813c27ca2d15ad40086db5070bab16dafcb2607e8544399f76137060900 00000000000000000e5bf9ccfd0f0db72bf32d591040a8e26024c9c23775dcdf +366300 000000000000000006e61b362569b9585e330d7ecca508d5d6059a42a2eedf2f 48c38b19d937174f2d91f2134acdf74ab91f1e0940618cdf524b769f1dd7004a 0000000000000000031c12b6af038524fd5dd28115b7f5591e046423cebaf6d1 +366400 000000000000000002fd3d27de82cc37b3bbd23d2439248d486b14a652c3b566 e6dc1801a815ed5bcd951e39489372dbc4e05cfd33cf94599567f2887d2e10db 000000000000000007f6f3ab844d53f172ea8915d83fa60eaf677aaac28fe2e9 +366500 000000000000000003ea86da5e16e7cd56984432fdf78b9d17c414d32845e059 9d3a3daa82f14d91fd8ad7da798ad229b75615a44f057344aa0cc591be9d7660 00000000000000001001b16e6af282a47f70a5b2072f72e9809408197fba9a6b +366600 0000000000000000031cd6fed37cac2e3db1d039af68aa59e8200e4dfbb9d7a8 e18b6d32d7d7cda66c59aeeb6b9b1726ea94eaf196008245e0149f3f038640fd 00000000000000000eddcc0109cdbd85185ee176cfcc7f72b3485d8f97c9c51b +366700 00000000000000000720cbecd72983ddf4645acf872465a0fae75071bac86f93 05b38f0f4adb5b99a1345108f891bb753e45b06086b0a0c20638fabddb1a21f2 0000000000000000112bb90d59afd139eaa2afb357f37fb1b8abe8e72cbf5a77 +366800 0000000000000000099236b49958f9339932beafeef59c3c4850962e6b7dacc2 ae45dd5b0dc24dae23585aec71448349d0ebea3f66e0b717f15d437818da20b2 0000000000000000138589283efe85c11b925acac89936d159c19bd90eea9240 +366900 00000000000000000efc31bdb2159f1818f232675304f7018624fc7f29694161 eb54b1a2ebf43ba0c28cedf00ca88cb92a28b9f3c561881f1949f73fb37d7053 000000000000000005a9242da6a6b41cf37e27a7d356168cac414b91861c56db +367000 00000000000000000648f44c702f12e748687a7dd71b4b58dfed0a5d626345e4 092ae33ae31a5444a5788a586f66e984bc04402f81bd3c2dc88ac37f540afd47 000000000000000009d69ee6e3a2bee2cd6c5d3f603f96aa0d9c515bb8acb5bb +367100 00000000000000000aa14ddcc3bcc8311df95f065bd7dcc581b0c4ec77200226 37974b983ca996720b49bd79cc995cd397c479022e18ee732eadd96a3d429417 00000000000000000329dc73821984891d039c5a8087522510784619c1468e71 +367200 0000000000000000149aa2d623543a30619d4a10c88cd0952eb0ca2faf960e41 2b94fdee47ee469525f915842873e3e90d5e9a8625b8eff90f261db4c95c9457 00000000000000001067f06794520331a42e9350b60d565b28b8a85ae937ba10 +367300 0000000000000000132e02bcf27489633f36b566ab0cf4746dea2931fc359e8e 89e0b759965520cc17e25d052a33ff240b1c535d1440a64a3be62e56bd0d95b1 000000000000000012e37b85df21b29efb7bdd6e0ad55b7d79ea20a9f2df0427 +367400 0000000000000000120e8af76a6b6ffb168a2afd14e5f46adcedb9d5828d978d 9ef075749f704a768eb5fd4f14e11d6639c12804d95d586a61f3e0099bb7a2bd 0000000000000000098aaae69ff97d953e6703bb63fbd6274f8747080a2a41a5 +367500 000000000000000010863b6f9ffa9b13f862aa0795b18f43d72a6fd57abb4528 1d78848982592a9b7dc8aadfbdada0728bcb69fa0e4822349d848e9a4df5e87d 00000000000000001193e357ead4c31474d3d7109a8c6d77bd7fa5560a5a6456 +367600 000000000000000014c8d93d4e3ee5065d49eeed1eff83c226b450f7b20492be cb2d53bcde4ec111828592e06a1a9182860a6af2e0531c5f410169922a0364de 000000000000000007f3ec658327af8d92ef4679b7d38df107fb68767a255ec1 +367700 00000000000000000e36a5cceb010448515263daa0f69a027971f5863fd53fbd 53acb8fbbf1f199e25d770238b30d7707e42de3fee370136075aade634fd9b2b 0000000000000000096416f49c7d81e460c080e6b00e7690a78c1edea2fbf9a5 +367800 00000000000000000c57625240a2f7f2ee6ebebc60de2e6670788610be01bca7 f62f913be0500602fde016bfb70cf884ccb2ccd0f53cb1fd3d3bf988d7b27032 00000000000000001055f05cf2f8fa405fd3451a704bc89fbfa495e7a6188e74 +367900 00000000000000000f1d4c26f1935e38818fb27f9b301debf3c7e59f42e1b983 ab018aeb8d5d1acb1ccf44cd5042b20d8980a790dfdc79a751ff5ee6c40d4db6 000000000000000007dcfbdd11264eb4cc584e7c3d1d5faf9e17cc357e3969c3 +368000 00000000000000000d39970aac12754eb89c2dcfda539b65562e5c3fec102c24 08c464bf92dbd17ee136430a5cb4aa3986dc812a6b5692cfaf581a5183f28a25 0000000000000000125427dedb152b12f85f1158054c6239b68169177e2155b9 +368100 000000000000000001ab6476ea4550dae3ad89f170d43d4184591332e976c93e 931aff98aa37578d5b83f8868a2e0b72bc3726fb0c22650e05e2a8f4f6010e84 0000000000000000019c2fd95e21f5ad2d1dcdd3256c49c1bc6ae4631e645eca +368200 000000000000000012e5e8654161e857c9443edb165bf7cbb8ca4274b38af6a0 56aa7fded702344652e05de013412bc05cbb0be8cb9866f1427af29e9fec70f6 000000000000000003bcc265cc8188a5da158f77407e039653f144caf093757a +368300 000000000000000004637a4d166d39509ddd880c6c32284b7aa3cc21fd781fa4 e9d7d8ff9c9eb1ff666ab03b553b0f0a24ecb76b56b9176bbefc25d772528ad1 0000000000000000115416525f68e2177c3fc3040b27d83ca51af33b8ac4896c +368400 0000000000000000112f3ce8cedea4045854b9bc60b011a5e7fa5908a6b487ca 0938dc84214d3d2b403d46c6eb82862ca005dc42097fdde2bc624e8e5b3e1359 00000000000000000642b62cc8d586643a9b05959bb61b3b6730a1dfe043508c +368500 00000000000000001085c2bcf4cf0573b364e65a3990201edeb9150f074e9e45 3a394f622ccc9fba7149a39ffdf0baa8a7b65240dcfd5a5b360f86dd07ac0fca 0000000000000000119f342c71f4c402f729fea01427a873369bec65267395cd +368600 00000000000000000c93572c7fcf0ccc927b5fb00039e90d1550327d6d83552f 87edfbb157988b9eff093111dfc173544492af8a4e86ce7694438f8fec645d36 00000000000000000be13a49f9c0852b6c2c773efc816afadf4b2328bebc1b0f +368700 0000000000000000094e2672862ebfae3fcc36487fd340d488bb2eb0b4d0fa76 21372102244cc8c751cafd5ec537629a5b89b9f0ca8655e64c1d476508f9fb75 00000000000000000bd7af74391af82fc2c8fdad9ba837de54c0dd731bd39e94 +368800 000000000000000008ed34600c4c74c3a7dab32226ce313b425802f457e832a4 9ac6c168217eac051c82eb2c0bc63d2eee71d3952fe7c33380e59669c32e60f9 00000000000000000281ee4f2341621bd3571e39610d26554b8c767e6377a8d0 +368900 0000000000000000043ab9d01e2e88ff460b6205b43cf3508ddeb8461bddc2fd fa1fb67947a7a15c2aa64bba3f2ebf118c2db4eb60285e642b4d0c3a16b8649d 0000000000000000033d0855fdb77dbe3ca416ede726e2dfde22b7cb1bf65ce3 +369000 000000000000000013f162f70aef6b1815570c03c232320d9d625b248a883e5e 12b9824be65c5d8d5287e90c9f94c500de2ccb0b73ac730059a6d505a0e1fd73 000000000000000002e75e5f902a062ef57c730912c76be3516b5b8da058df19 +369100 0000000000000000112f890cd2621e2335beca8cb75a8069d099ee20323986a0 f6f93f26c0e35ce0540eebd195bd10743c9d300b33299a1032a91b5ceb56a84a 000000000000000001ad74daff2ab1f1e1c20dc2ddfb524becac00d3216deac0 +369200 000000000000000013d41a88a0ef975962b623977befc5e929d639c2b283325d e852dba69a120278a004a8e4b128c771a78d4ad4fbbed5b300c34a8a3ef386d8 0000000000000000066f4b312003407028e61df6f6b272def7a97ee99e82052c +369300 00000000000000001101faadddd252fe834ebbb6244d83f7e41ceeb3fa5eb6e4 5cf8c319969c19c9fe3b1e76fa9f706729665c549c6a4fedef8c5ae416c539ee 00000000000000000169286fd25ddbb9fe2cb9d095f911bd017e1fa2927bacd6 +369400 000000000000000002489588a23cf5eb3fb9acc55709a28a15355ab82f2089fd fc5ca31861c4c33b732c6c20cac79f2a4aa537026e33911ea13c3e20bc96da5a 00000000000000000e6d6a1237d0236ddd3b18cb87fa954bdbe5ce34bf7d6d81 +369500 000000000000000003d7cd0e3701d122797326e04c09e79aae5cbb76ef3225a7 ae9cadf2d50f348d4a554e2ef3b33384a1016c69a17249278ce3a0e23ca62bbc 000000000000000006ad86568864b66e8d4f0d6e38a21c2f1ee701cf2ef567dc +369600 000000000000000007f9a7c1680fb09b7a46f989e5598757669eba92b23e8940 e4eb79f18faab7e018941e51efb37522c766cfb5869dad6a28ed139c037e593e 000000000000000007c2b603bbe66604637f76dffc35f4e707ef8dfa61c203ba +369700 000000000000000012cb9e5fd9f75df3c1304c2842aad1c269601d10c46db3ac bc45192208aa042e84e209e267a25c51af6bc8c7c6025ecb65945fd86bdc84ed 000000000000000002dc79d23d4f2916eaf873a05a84edd0a966ee65f98e8ca8 +369800 0000000000000000086bff8e03884ca9b250e5a2bb94fd74b335e993e5a0a258 3c39ef774b29e460611176670237b84b8e74120fa7a2f34bd6555d192bb016d5 00000000000000000669caa15981b627cc55bbe944b3457c6ed39715d453d433 +369900 000000000000000014bd3fc1f1d5e0eed8e28e055185489a8b6e3c87dd7a8114 802eaba7f6797d20d04a06bfc3327d9491a65997a4c42225f9270c1844d0bee3 000000000000000014682254f8c81db21c87903977e3e9045ae1769429cbf10d +370000 000000000000000002cad3026f68357229dd6eaa6bcef6fe5166e1e53b039b8c bdeab3c18a3484c51bd71781c4c18bf7904e748177124b1cdd4d91ea71b0bd6b 000000000000000001ba6a172df04cb3a90e8badc70b7fdbd4a7b903695bf47e +370100 0000000000000000011e2253a1893138e512478f4897f372336c823a4be8238a f16f9bf3b6df465b12b56cfe01c16b4aada0967356008c0adb647246c9579fab 000000000000000011f1927130fc6242e51ef2214ce6777e62db6ea7754a8339 +370200 0000000000000000133f84a6e2ce3e327f95af80e2a5ec79b09fa3e01aa070d4 e6a824dc24a264a7395588cc2d543234409d7d4a6d6a3afa3b454240c9c4f6aa 00000000000000000d08f53f44fac3e2bfd55f0f1d874ff3d88bc5c3d9570ff5 +370300 00000000000000000802d5c518c931bf013f560c4907625abe64c3c41542028c e45299e8348c00c116c73042fa1d4fa15f82b8f9e6a554eb17fe3d4d4e8206ad 000000000000000013dd480cfb2a7603d59ded673f4fde7db68c74043763b9c0 +370400 0000000000000000042a040dc93bbdf3fd9bd08374c32ff3ff34030507594362 7f522e9681b402ec8b48cb154d1b18e6de80fcd3c3bd332c47e8773eac63a50c 000000000000000004103ca5a90aac25f5fb64ec3ac5f50411a751b7c199a4dd +370500 0000000000000000133c8e4e1dd3960eb54040aa5d6cd2f1a02a718ff0b34a39 ba030a0a4cf9d9440b73654a843129b5b190ff2ccfe3ce5f50f3d6983e6afc5d 0000000000000000140e84bf183d8d5207d65fbfae596bdf48f684d13d951847 +370600 00000000000000000cfa28965007e2cce59346742a72707f739bfea7537b090c 3737dad91c1ef9ad8cbb993024679ee2782ca021af534adff5e5ddbdf21ff39b 00000000000000000f689a158725349cd02eb1f5304ba4bb99adb5c37b6a0537 +370700 000000000000000013d52e758e4bda10fe102f5d903aa6fa20246e85c1af8747 9e91669c08159f2e6c4ebfda8feecbd11beec0ea7dc9e1cafc541e9d3049c3e3 000000000000000000d7350652e35ba6fbff466cfed10645a1aea6382975dc54 +370800 00000000000000000e4132e782511b7f2e92345f0fff38bd7ad11bea47886569 6954e9ff3bd3264e30ffb539c0b4621cadf2416cfdd82c7c7193955adde8fcdc 000000000000000001a22040e620d49cef59cf48b669d5a37f8acda84b808c75 +370900 000000000000000012d5a1c3102ec3d39b3bc24da5fce9b29730f85973de3f44 dcd4f17d625e63742da72ecd527b9bf35c8e4d71d07484b4394386d06d6ca8af 00000000000000000e1748b16966e70c917373c8fc2a9d0a5da9b3fdf92b4058 +371000 00000000000000001289ebc023290783212a5aac60784c9d5949ec47364d8b3c c9a996a011657fe8f1ec12d981cd701a535aa29b262c835403286cc6f3a92faf 0000000000000000088677991b50da5fa25a60a4ecc9695107e7ce17c807c1e7 +371100 0000000000000000105b667ae09aba5ac7104810991495a402b7da92e7e61789 19aefc5b5ad6ff069e13686a0ab65fab6e3937c44f8b90962ba237f42509aabf 0000000000000000115b4c92823172a557b38f3c028c9257508da0414be67dbe +371200 0000000000000000015755f146c6fa82a9612a5902222168be505fe6fe041a89 905437d7027fb58a28a66008917684a5b370e50e1a037c3076bd81903af8cf7d 0000000000000000091825d9bdd0c8bc4b1f91f6a516df2ae7e0e69e6248ce73 +371300 000000000000000012be36d22d11e7d886c25179dccfbee6d02a045d1021e0bb 4e63f2eaf3906efb02d27100f547409bcaac927ba5384ad615ea5755cc6d93ed 0000000000000000124115870b8b9e45745a70d041c9ecefcf89363e153d012d +371400 000000000000000002c6b1e80a6aeaaf64761fef3b77225818acd01033bf8e68 f0ae5a770ba66267af0c1af2a1303b423c265dc527ceca86ed5b31784de04d6c 0000000000000000085312e0b8e85d58d92b747457b8db8a8e9763e318a9037f +371500 00000000000000000a261728b4f62b08dd8260fe067b01e5fdf51b9fdf1ad9d6 dc3cb129bd6ea27724b1e3132868df21c20344aca751b6ba979538ea3b96d582 00000000000000001342737b52ee087717af7f334c3333c363991a4e27e87176 +371600 0000000000000000128349543a110660428dfa697ccb54dcf2555adfc06f4a12 bb61a11555fad4ac52baf0e99ca85389945c9e9e853c298b762210f537acc85e 000000000000000009b8a8af0f5fda4961ec25b3359a56655c1bbae21dcf7317 +371700 000000000000000006441a6b5111eebecd86b1a64699fceac7f2d10fd5ba7db2 70a5ca25437448c1b0ddbee5365bbb853fda3d96e0581993d37f8539bd07d4e5 000000000000000012191ea33b1992571eff41685de58610027c58714aab4719 +371800 00000000000000000f3741400c91dda42336c8bb4b68e519f1b2b148f82e3cbf fa62c314a52aebb6de427695dd547c6317b4d2ef972fe557b623c66d887d208d 000000000000000009bc3ca4ebfded41375a8aa538a36f3f5d01212c6feb3cf5 +371900 000000000000000009fa3aeb7a7751c64ae7958e0357554bcec831296d376c8b 870211fd54b70baf709d2a5d8e07a4643728258fc8bfe9cafc3d5dd72317f4c3 000000000000000005893eb2ccf7535c742f86bf47a689e576fc4345c2728afb +372000 0000000000000000028093cc8035a6bc4e0d1b40932c2f8b50312a3fc86bf3da afd7e839731e452ccc8b0b54d9332fbecbc38d07b530d1133df0696a925dfc9f 00000000000000000f2e596350c35a8a69c1f74416c19352cbacf7ef6f5baebe +372100 000000000000000005ad5420832d7e7743e2fb80a6e97fc2d6162e76a6afbffe f7c065f0bba558996c6e1c59e1e63d8227cdc1a9909a9e115a420407be0f3936 0000000000000000005da708b4977b5ac57c2701e80ccc41fccce088e63324d0 +372200 000000000000000009b933c5daf4ab696563a29c9f687947b769484af14079ec 323c22ec058b9c5b2fdecc88891a5fbcc62760d7fc118320d58d4e7d6ee08356 000000000000000003996de32ad0d236c9bdf20f5ed9dde494e8900b01ebc6be +372300 000000000000000013b9b246072342a353bba041aee5186d5f5bc0df8420c545 ddcc06f820581512dfe1cd727bac15f71b59f0fb8cdb5813f3185c122860ee33 00000000000000000bf459dc39ce8126d42338608693e846dffb341ea8d3b2ab +372400 00000000000000000d95c8759d992982e8d3d00cf39191a8e2d4789f64c46a9e 0b72b99213e84c8432ada4f658888447664f3f2135ab2a8bee6f7818d362c203 000000000000000007774dede5f1ddd0392a77fd38e09249571e7b2804ae1524 +372500 000000000000000000cf4e3996f80a40da1942dfe0a7e35463ae909ec3624590 92dc44e51228c56d539bd170518db893f71b37f037058800c616b644bcfdabee 000000000000000001c8843febd9694ef46f1d77a688c715e38d7b81a1e0cab8 +372600 00000000000000000382ef35f41f609fe22fe0b9f3e95111c93ff42c2f6877ae f4ead04724baa0654792605cf2f9d15c0ce3ad7b94666dd3964bee378661029b 0000000000000000040d2dbd7c3e40e0bc0546e6ef744c5e4f2da383226ed1ce +372700 00000000000000000967c2f40feb1bb93a2b15826b697d038dfcaff700171c08 840b54eafa760bc4a0df754709187596a13cdebaf182d0c367ff0f4f9305c557 00000000000000001200413eaad728bacffc62cf0a0a3bcc3d9b3518ca3a431a +372800 00000000000000000325a61a14b941967db34a1015079dd171ed33e58f86a602 bf444b4dfeab7d54d924e46030c8c01035620ae3485f794989b1d312684196ed 000000000000000002884162e569f114a72b53d94dcd81e0025aeedb955c304d +372900 00000000000000000d66b4e72cff76b73e7b78a2b2183ffc03028b6ab38ebb41 074c6586921689e71888a41ac0bc639fd8bc81b7ae6f10b374f4dd62d911eb02 000000000000000012f85ef42d494e6191c366b5cde1750c9105da189dc16d8c +373000 0000000000000000121749666a9e1ffb5b0988a62cbfdb1a3282ab9510ef036a d36ad1c8f3dc37f4c7225ada9d124277999937ee0aab8e871880a1f485624a8d 00000000000000000b54ec5db665ad5438f02c55001034b0c3ba744e7d2ed02c +373100 000000000000000010b8b43b42eafc6fbd52621027c07f50dbffd96ba4339636 2396fee7f65b435be04a5e16c78c1502fefae71d4de6a5d9ad5a2fb0753eb35a 000000000000000004d93e90b6a7621323996b20958e9738e1b83547e572bd5e +373200 00000000000000000fe66acd46469a60672de817ee2ac31d8c31ce6cb8d573d7 114ff5ef9b9cc23ebe1efeb205b024b1a5006673359cab300b0fb5590e069dd2 0000000000000000078ef450a162dd5d76e85da82573eabbfdf45c5c397bf03e +373300 00000000000000000afcff1a26f73c5f715a96d9e6c5f6ad8a6480ceb4b982c4 8568882ca51a030d0f1020e96013909570b9bc56dfa67d4d39a8bda1df83f01c 00000000000000000644ef1690c66499ca891db7f1ec2d27e5fc0878fa0cf8d2 +373400 00000000000000000644c4ca9d2b57f22cbc17d2d2191b25bcf0ccb8ee99b4a4 3c49e38cf472c00e910675e96b901490ea80f1d8d6ab1003794d2fd644af5dee 0000000000000000121e6294aad243083b0d5e5e3066410c0afbfb7050a1963d +373500 00000000000000001049d0e5b5af118fdd9f8280c77ddce9a3cf39f6cef0adb4 254873a2caf1bb3142454a3acf7d95a8ddf9e1979cc824cbe9050d73f654d550 00000000000000000510f37098d77faa90d307b09b78c0410d840d6c9accf373 +373600 00000000000000000f66455246e8055a4d528d0ffab6a96cd837ed6debaf4b59 883918c2b93977d2fef6b68cb95b038a557e59232fd9e52addd46438ee024014 00000000000000000810c0285c417493c74769fe0c7c5aee84f6367e486acb5a +373700 00000000000000000d6f245eca2a5c16b0d5841656d514d068d11c3697d5c43d 314783592b0beff62c8ebdde41722a5425a19cc65a479b48c7fb245f4def890c 0000000000000000118c7cbbb63495aded6d90018e3111260a95f04494afdf1f +373800 00000000000000001003278a3d7e6862f1714ac043558d176bdfda987bb212d7 a130ca39e0c9a140d61a0457794c735517cf06a9eb5e5d2ad37cc224e6dd8bc5 000000000000000006bf86f06ea67a3e624122a4ad2f65d126f1223957360dcf +373900 0000000000000000002930be5b1cab0c42d0a57e8dd31f986fd77120eac700f5 61936ec72d4ee290a81351148ac861730aea9a5f676f59341d89a4c56a7a14eb 000000000000000008ecb3e94db6f990a6279a77225e11c053199af79f25996b +374000 00000000000000001016aa3783721673bebbcd1efa49946b52cceb09a81465a6 dce6e31bde31c2f6f7085be31a779df0afa218be49a6b4c0a193f802022cf844 0000000000000000029c559f066604a8e5ed21932434eefa57c8c9e6d6cb9e30 +374100 0000000000000000130008ab92a2eff984a1e6b2e619736098c9208987ec5232 cf6111b5cc302b3a7be81e9d6e3d0c2bf4d6604e2e93c36c186774a9cdaba012 0000000000000000100789a44bb251ec52fbc148e7c7ee923605b753b2d072a8 +374200 0000000000000000092e1267bf269fa79354fccf311c0dd86b1288d3b8d5e076 0bdfb19a5680ec70be951dad0716c74e65242e07303b73b2a966bad3ad53e257 000000000000000007c860167017880bee21a6b957b25d9f6567e94520c7af18 +374300 00000000000000000a565cd3f6a21fceb2a76a1406ee517a59c7a165a13f3c3a 1e36b6429ecfcba901a144c81de886862e6c7db5127c090e2bf89ee7c2365fe5 00000000000000000444ee90adf012777af951571416453e4640c568cd866983 +374400 000000000000000009c3589882292186d6c41542a9ecc1b911e3c108b7ae1a1f ca18d5d04b94688391c4efc83f257019146ae5157e94e279a488b3652eac0977 000000000000000000c1d1e79e0666f9018a50c4436a088d632c92d65da35ffe +374500 0000000000000000122dabf23f78e231668a8e2816aa798731581ed2fc83a030 f7c0cd049848c82978c67f7d60edc5e4d969d24710e7fd6ed2113b25b0038533 000000000000000012c28648600c5e6fa0ab69749d93dda943df9b0eaa17271c +374600 0000000000000000046eca58ec57f6e0da26e41c925755f88d587f5203bf9a37 0e9ccc57cc7a957894cf56aabdf95f0adf1671f46a4e87411d5d0ec2101ad625 00000000000000000dbfc1bb261c5544b7b5053b7d888a42143a205d64bc04fe +374700 00000000000000000d806c6e2c6ee7c445991fb627599ea28f097cda9518b448 fd8a950cfa0776deeec388ffa0396a7390842ecebdfc528f4622718180a8b930 00000000000000000993e751ee89824c66795b64836f68a9e427b2f3da5733ed +374800 0000000000000000001762e453ccd8cf21f4168330d5274ab87ef210170fb48f 305477c504fe6c5c81d7389501a0523abe0b9e655d7532497b8f679bdb2ff895 000000000000000011bdb460191e63cbbb417b1b0e43319ea90794221e70915f +374900 00000000000000000c7e88fb14ffb8c7c91caffe92acc9435f1d6f2d053bb89a 1bb06e1ffd3cd69c56e6d4b9649feb66510211f2426bf1cb9f78e9dc18b70222 0000000000000000061ededb963c2d27cbde01fbd5ce1b2e1595aa32517cbb4c +375000 000000000000000009733ff8f11fbb9575af7412df3fae97f382376709c965dc ba13a4590d61ee5340b86b6238e91b4c72afc82ba2ae35abfa72f1e3d09baf36 0000000000000000087ce3ed05c7700d783d33860560d828c0bd337c1ff50b33 +375100 00000000000000000a845e4a87ffed101c8dcb92c48b1160792372554cbd83e4 9a3f3826ec205c2cd191c7472dbc618b8dad454bd44ddd7eb733f49a9764cc26 000000000000000004f231dbb9c6c681c159fe9d060428187e6c4870e0337c8a +375200 000000000000000002ac7d0601287f4beb3a2bf251333c8a7eefac6c3d65629b 98cf4f427cb8ce4c300f70497bb97e7f37f27ce49262ce599384ae568d25a5a4 000000000000000002871563f8e54cc1950a64b984c31b46901703aad635ede0 +375300 0000000000000000030faddb947bdd1e7b92665f5974f981121d3e0a79b2144d 296df123f0d836112a93da9ed364395859c1acb27e3aa53945ccfa2a69487f8f 000000000000000011418d2e575784196aff9cdce7372ea1d6094e8bbae5d194 +375400 00000000000000000a53f1c4a46f75fd3f5e9cdbe1e4a8e56acf8f5c9c273cec 0b09aad96a416791600b2f1dc103840175ce772ef8c70b7734c36864edd23b9c 0000000000000000090d35a3e2c63a4e1c2b818041eb516bad84ffae166b8d9e +375500 000000000000000001b5a72ad0e3910d9b7127b81f3d2104ffdc506cc3abdd0b ca7ca1e86b6dd5246526dbb3a2af8b53b55defdfbdbbb8441f121cc2f6245bee 00000000000000000de5f4aa167af763a588688079616235f76f4e15e6bcc8da +375600 000000000000000003bcc715ac940fc0607bd324d11fc232f3c20a4c5d426e66 1218f6f0c02080fcae7ab74aeeed99398d9a71eb15f59dc2f860cd292a7434de 000000000000000003cfaca52b6224475daa0946fd6163b293d8e8ec1aac27d8 +375700 00000000000000000e42ad493d2b11a16203b0f70ba94153f6b8fd1c565fdfc2 101343b53811c2daf6e434066e92cab76f5e616ffa3f0a05cee2504d3d401b9e 000000000000000003050fc52941eb499a4951b1841449512614e367dbe30ab5 +375800 00000000000000000de3ccddc90b1dad2869466de4ae38a1120f02a30c539e9e e26820bdd1c50b05a9da15c43e9a13ef82a80a7fb4b2419949d5003a975978ae 00000000000000000e69d6b5fc564790240728e03984a8293820cb3cc61082e8 +375900 000000000000000010e8b9db2aed925137896b38b4b32cf36ea57b3ad55f080e 8c732a476b37578dc46665a946c131534d950cf8ca0d14eb5e57112ff0e81b2f 0000000000000000062a66809f2d933c007cfc349b0db92c636b617eaa4edf7b +376000 0000000000000000106e9e99cf4fce4e8a4abc97f3e883956e26d76b3a1133ce cc160b4259a35700a566819c3978fc5ddc00dd0ccb824eaca9a28e61137e75a1 00000000000000000600fd599dddf15b50f48b66ccdea01ea56d2c093192062e +376100 000000000000000002b3af2d26c55a95cb04841e1df9180fc76a26741c31fe60 76b5f2a29f8df68c6bc6c9566384779dface5f8a55ff6fe0b1b4690bd7d75cef 00000000000000000c0eb426a420e1b68c01220781b594f968ee0ea5e30a6a57 +376200 0000000000000000082a6c045e3423dee1f905fde468a08ebc507bc65513a767 db8bd9074739f7a6dab09a7ee4f0bfa74fd77577105994a1a2f6f8b26eaadab6 000000000000000005be1832ed70ef65dc504e8b7bb51a3b668e96a1ca9d241e +376300 0000000000000000084744eb18999a5d1047f9a3ec941ece5f1638d5d3436ed9 9a8be55282751092c1808acd91153bfe100f2f7082bc1e06925a5e619d90a23e 000000000000000006f30b8c726d5a0bdb0604faa8bf9c67244018a8f26eeb46 +376400 00000000000000000e96f7af493af0cb164e2989f5907b9e9f2c15f79e330afd 9eb73f2e74d0cba164715534a44b474a4d3f14a4176eb58c06123add0f4ead27 00000000000000000e82cf0515278b952a448ed27b897c527c9cad6c8e8745d4 +376500 000000000000000005ee770e9972c41c50a2ecf62cfa86c46b06efdf926fea48 84af01ad9958209f4e45a9cf7fc7c77d2db6db7d603e769078df6f50c4caf2f5 0000000000000000082ac60673dba1842cf279497759b5d156f320e939cfc669 +376600 000000000000000010b97f191340e74c7c31b42f7e3af29b85381d155d90bde4 61beb9e56cb2a6eae0ef4e9600f4f5c67276a5f63f408d26fdd17a17baf511be 0000000000000000077827b14ef7266a2eec3d71cb524fc8a2c7d9a94ab68b6d +376700 00000000000000000fe7ce819f2fb3b8f133aa32b6c768586e002e86864cd38d 749094a0b968445c4373c5ab5fee08495d48970aefef135db2fd4fd4733d9019 00000000000000000b48cfd72f4d06fc73697dfa7455b50859a2130727792359 +376800 0000000000000000113dcd9640ba790af74ecb4f636fa0fa43d05f57d874ffb3 6508a831da85c19134e1da74076d5f316d77eb2214d907b79828321c71a595ce 000000000000000012220f651f24743364753c9d2bbc6c9fdf7f6e98b3670067 +376900 00000000000000000fdf3f36e465dedf79c537a2724ad4b77fe34bd06e411ebd 17ec2de2e739482de263aca5e5c493efbb306d2d998488df3264538eb2b0da07 00000000000000000900b6bc02d1fb196b766b8c4bd40c01f76e983a76da16bd +377000 0000000000000000095369d6ab2fe319886515837f618ee6f0353ea49322cae5 e7511b7b31a7f69ec391f9b6b2eea7d90bd5414c97137abf1830926aba296a6f 00000000000000000240064b3d53fb8ed3284d172376ceee0de15b2ecaf303fc +377100 00000000000000000d4c663f6b90649b064058ff0bfe9e1dc452f4a160748256 57d38154f3d02adf8d33737c0fe301f6b0faabd59fde3c51b1d4dcf8415db5b1 00000000000000000ea78f3539320ce695d6fa5f9f2c3f963e7b2fd2e43cd18e +377200 00000000000000000542adb520a30bc0f0f80231030bea3dcc0634d99f73c024 e27e04a5dd07b9f5a6f34ebce1f094490db108418b6e506bd9972994b208da7c 0000000000000000096c5675b31a3a93118647791288aedc4abcbb5c455228f0 +377300 00000000000000000267dd69fda9adc4c0e9310bb380c0f9c20a2f6d60fad741 483dc553eac69d78606936c8e6744532f6ea833490b55d40dc19d71c0bce336d 00000000000000000eaa00e4989b654759665c2a8af251bf59baf35c34446c98 +377400 0000000000000000058703ce6025b96282e460d40a546fc3aa40279b505fd343 c3a12165b0703e141709db58600966e1085c8eaee520cb6fc74c49b3ee822a53 00000000000000000ea204eac73a1b1773d4ee3b81c859ca729335da2f6944ec +377500 0000000000000000002cb5fe40d7f11461f61d48793e9340e27de8aedcd6f092 0fa45f31ec53ef376ec35728cb1c90616b70c598bca5f65697bb0a0c4e68abe2 00000000000000000b6d554f66bc406de4190b166d207d3989e7dc2f01fae4ac +377600 00000000000000000bef65fd5b45e17869ad73ca47018e3465526007b71aff83 80886ab184d0d5fff232ff5a1e5746fbddb0c662b788e088d0153f9acd561f54 00000000000000000bcfdb699d2c5635e9784a46b3654d0d544cddf11daf5fcc +377700 0000000000000000062edc16635b9b7c5a62d99cbeb80ca6b8a6ac9a413cb87c d440d5e2203d33abe31ee316c2f9100fdc6d88319efd7ba7aa3bb745fb67025c 00000000000000000dc88fec3271af0370fc6fab52e01f332a28f7c9891b03f9 +377800 000000000000000002f6fcaedb0f23287de10465ea91dda5f0aeeaa35c026194 fe9daea1aa5047cac4c07e2d4742d83ee9d3ebf2507fba1fa4a5f093817b7970 000000000000000003701e79082b9972ae570c65407fc7667246d40e1572e33c +377900 00000000000000000280f0049e4bba812a0b7691493fced28156f6eacee7c732 5f9600e7a19c6baf68e5fd74a343d3484e53f8e822184d391bfee66b9774a1d2 00000000000000001143e2aeec8e9cb82334e37acd9f653443abc16b4241d79b +378000 00000000000000000516cd5b5f4b7e528d6e61c643595cc818f1d02f53da4281 fa22d3b163d9c6a899e8f58f81e26101f261293f537b2592a6d43d8dee968718 00000000000000000aa09631f3e8649893da2525f739b6b088c76dc8e898e4e2 +378100 000000000000000005b8108453c0c4bf255a2af09e51b1d6ab6a1e0d70d7eb0b 7fa52e8cddcd8db8a67929d9726e53c98ee1e2317da752303a89a9c1094e288d 00000000000000000143bfc4f31c6cb09584e69429f5777cc5b35d5ea574835c +378200 00000000000000000eccbaf5a43c7df9197410217ccb824c6934697c7c0dcb56 25e0d9acb9429bb190d3836a175680b81d8895bef32db82904536eaee75dfff8 000000000000000003aa6a79dbb2026adb3f240ae5402699b6e0d4d5b1b59710 +378300 00000000000000000d1a786d2b67b87680e602badb88be9e315ca2f21e39c8b9 9618d965e6dc482e8dda38977e5c36398f6ff1ffcfa40b4e739b31649c437c11 00000000000000000d491eb2f97dc2469aea85c58e2fa9ff4013ea321c3d3465 +378400 0000000000000000118e6211b60940f00f35153001f9a27f481da7d963bac1fa 87255b0732a60db5b09f5f3300b631b6e47959bf41986cdd7d10bbc1109b5071 00000000000000000eb96a6da2989bc2424534320878ae6fee5a1c756aff4c31 +378500 00000000000000000a52239fbf1aac71533d3d27a1641cf691f36ed86c460602 403ed120affd2b691cd2e8fbcb4a4fdea32a6ffb896d5cbfb8cc89fb47d415d2 0000000000000000102f3084b68863b689ae2aa989569d68b35c7d9462b7aa76 +378600 00000000000000000c0ee3e73fa22d60dc1f16c0bb9539b4968040f7a033dd79 e7d6b3f136f55cf1bf0d52ef05e50190fc7bee8338705e1d0e750647a9c00aef 000000000000000006a36402db39d5e9f454c893e4606d984389e97accfb61b2 +378700 000000000000000008c9a768422e609c46bbc02a076b86cdca43caadd856dd28 5f5a9da8a924e7a8269f32766aa5166d84980aa830a053b0ff3f94ccaae5a537 000000000000000001d1a2d68b6cf2227af81ce7bbb7e2287681c62b5f994a15 +378800 00000000000000000e5c87d568324ba252550a4cb02b7279cf398b9994c0c39f d6a9356a025ce483b0b6a5350e316844ee9673090d3f332ee82efdf7a6c3610f 00000000000000000b911a460090cd60fa9aa4d6029198448f3781a7d02a7b4c +378900 0000000000000000075d510763551d5b2e9f4f5596581d2a96e7f836ae2c739c 194c3d514b2f1e793ba299286954c56714ed797b172c0ecd47e5dd01b9b98855 00000000000000000c2dfbcb19dd3b74ac02ad10b5429b43afb96145b340cdd6 +379000 00000000000000000ed7641a3a0906d68978e047208edee1438caa299a0146ad 0fa2cce138903f69812c186510a0d65169ab5768d49e57624db6e9f747892018 0000000000000000118e37a8424c056f90b95686f959939c6e0a7ef460d60175 +379100 00000000000000000829ac39ef8763001a0cab086329013141f3262de8630082 86ee161e3b05c7739a850ce7e1b523bd377f0aebf51fed7df325acb56613ddbc 0000000000000000003814c8e95e9c8e96daad1856cdea89f9e8003fcbd88e77 +379200 0000000000000000004441ee5fdea18557a0628b836728f3cce258682575031b 341b2549d26760f24c0678d129d1ac6de33d95aec7553a6c0d54d9b50ba0ca5a 00000000000000000e811fac7d77f93bf6815dcc529d14d61bfa622e7e64711f +379300 0000000000000000083968d68f9444a1c1194552a5f24f0693af4fad75af8b09 6ef8614f1c66606fe93f5b7068c9c314cedbbd46c7b799a6a33692f922c08ff1 000000000000000009a7cef0a1434b7f8bda284ba9df9b2be37b1bd029d02aa3 +379400 000000000000000010bbc7f20a77910980ee54ece1d91f06c7219db89b6fdbcd 741adc7ecafb551b60ca56946d875e228efbd1987625df455f4c8108104c4e11 000000000000000009a1081079bcff44b07d6248981cdccaf0fb909a9c0ec148 +379500 000000000000000000f56dfb7bf8c208aff71e32432d9dea60af4bc76d81d6ef 0cc6f3b1a3ae5f6976588dba369d8cfc3c60fd7a80d8784eb4d5996723713ea5 000000000000000000157a55efea38cf3e3665d1e19266d9e7ecee75b30415dc +379600 00000000000000000fd6e9062864aa85fa5d3d6a1abad30a30a96a5cd307ba88 296bffd3faeb3455e7ca4a530078b63209369fe0244280a6ff9432572d931cf4 0000000000000000057f764151932ba5d40e8f8b2686b5d3274b59b5da3b1a26 +379700 00000000000000000fd06b9779a99e251474f791abb1956c2cbb576383c1f6bc 1aad7a1ac810f18d30980121a42cbe143060b31de41c05703ac972dcf6af8013 000000000000000009b96c956f9719f0450d76f3d1921ca6554b32aebb765d0b +379800 00000000000000000348a887c34c131dc89c33c229a2123ab093457d25e58b67 4767f1182e254e837719f273a9307f551b1f908d19586364b3b5ba066a33dec8 00000000000000000e8cc98365a8a5d0168e161ee90db42a98e009332f4e7671 +379900 000000000000000002632ef9aae3e926a4a0b9e69a9deb730c35a306bece3bb1 625700d8832a2100d656a88ab980888823eaf9f772bf55d70c5401ae8ca6b04f 0000000000000000105253a8748f461341a7e5bb70b2e43e1dab6cfcef0a4880 +380000 00000000000000000b06cee3cee10d2617e2024a996f5c613f7d786b15a571ff 260b19ae2964e6221e79e9d749dcc067c1e7d3991a0ce06b6cdfbd67175d7184 00000000000000000bf2da5c23edccaa70ee183262cae2354f18f8a3201afa53 +380100 0000000000000000094fea77477e3d38f34219f05f1408217eb217a460321e4c 80698b5bf77b5c69c397b26da053dd99f4012525d6d1f7bf05f7ed783cb57374 0000000000000000082b354db92da498875ac16333dcd91a0f02f8b02cbe6951 +380200 00000000000000000593490192240fc9a2125cca737f3cee70869fe942acc7fb 633b8d8b35e3f419717d0b6d9e8364706bcc21edffcf2c97ee39e4816d173d3c 00000000000000000896629f19804eda84e685c79e572ea53f059b725114c730 +380300 00000000000000000acd15471adfedbc84d5733f872d752583679d45952b2225 1852f0c324a41dd8eba793d8c3ef69da8242a3b2d442fac8cbf0b7d6c19fd321 00000000000000000b80f0da5714df3c1f380fa355d4d74e73f8d5f9f910471e +380400 00000000000000000e83d2a3a5583ea444f1f01c60d274f88330fdc219c42ba5 2de16f7cceb4a999a26161d7931bd2f471b05e305396eaf21c9bebdc33616ed0 0000000000000000092153a36e2339db5d34099e77736565dd8b590ab3e290fa +380500 0000000000000000063f31505b4429b66613dcf37afb46ba8eece74993c4fb23 af053c867bf16e811d43d80b9b2abf88096155485b8ae2aa329bc78f88f6204e 0000000000000000070dd0849284d702e1505bc1135b20237dd5bdfb6f37d4bd +380600 0000000000000000072c3f7488ca8c6f571ef20e08012233bbf28056795645d8 f4c95c632d0a932db91c2af73a55f109cda4284e39b3f09a50cbe32b47c22664 00000000000000000f9d83f263cacfaa07d3e81dcac4ddf108bfbc977aaa3d7a +380700 000000000000000008c144be367536c1745abca24f72d4c439afd99cd35b8f54 9fd4a26920ef5c6099ece54eb0ef889f8cc0e0a33c809066176b87b415a110de 00000000000000000c84de966c7ad71fc24ddaedd96159ca8dd5908171b586b0 +380800 00000000000000000e51412d273d4132da951a0cbe748cd80f4ee840444d21d2 6a2792b59cb2819ce79eb609ef80082ffa4dce5f6a038aa5687c3d3b29ab4692 0000000000000000118b87969a73e09f1ccea2b52a413eb181e9879bb98cbad1 +380900 00000000000000000dae71958773a90a277f3e2dd34262f14465fdeff40d1b92 6be7ba999523494c96834299a7b03249c6430052c3797c933351e9c30710f6ad 00000000000000000a184967b05d63db4079f6e2d1c637befae2003b223d6bac +381000 00000000000000000a965dede3678fca0af6cb9d4ffd97b3b2915c02488d25a3 9b46659897a31251f5a17f6e895175a19de542f3b8bcc34a5c0c8c8bd434ae35 000000000000000001667397ce30e128af86b7755760ec918db5c669fb686eba +381100 0000000000000000110af88c5fa83630714c52c5b0992435e2059ec936a68468 d0e6e3dda159a4f83043a6697819dc63b30f1e9315b74fa5173bb8da4a13b3c0 000000000000000005d04f6ab4b7c6ab328cfcf24d077f7346421afd18b0ff2c +381200 000000000000000003c51f1c2e6e6abd953f52c013253977c899a8b6fea929a8 5f056171dc13c76b5da25f57314f16b5bbf20ed617634b767d727a984dd5a565 0000000000000000003f7d375a733833c232c989ef04ec287b599a80f6be520a +381300 00000000000000000e882777a5886371ae00a4236385aa55a49c9983f334c6d1 2a674882623331ff44f5975e3bb3dcbab38895e3ee3a96264c68314008b35334 0000000000000000100919507908c617337df254583d26122b82fa5ccce5ecaa +381400 00000000000000000c08b4c0324913fdf3b74f1a1a8df51bef08401fc34d8821 3824d4d37c9a2da12b8737b66509fce98fa18bdb36a54065172f5ace0fc13687 0000000000000000010f5e20f8d2e4b1ec9c9fa9da66394b5a05ccab60f88e1b +381500 0000000000000000085dbb3e5cce98645d56e6b0f94e2c374aff130035ec3319 66d892b4212183a0079f86d322db099a5bc196ab01bac03eaf0914e927b9b37f 00000000000000000ac8eebef6fc68f021bf57d154c1723108d5e652e349dc19 +381600 00000000000000000b0248057282b9ca75c915447a2c9a4d50a80b5ebde45829 82e1da4ac614a0fbb1443caabc9822fb039c69e33f355a26d8e3f916cdcacad4 0000000000000000084ab6790b31dcf61a8642788d8b0a0cd2639f40ba814cf9 +381700 000000000000000002129470278cb2b00da9dee3186e3a91dbb3da19647f13ef 725e89bc038864183b4f828d7a2c9055ddcd885774714dc99033b2c964081a1e 0000000000000000052566447d42090b467dc7f5b37e0b31a10d3a1462efe57e +381800 000000000000000004ebb6a44ecfb761d8a9930f520d95310e4414e9790812cf b77568d3c630d9091798c326fdf0623b5740a7d4bb9a32137cb41c8db8d54123 000000000000000001362ad4429266f85616db198164d7e8145146779896ec88 +381900 00000000000000000dfd99892e30622fe18fb165ec129109aac78a83afa108c0 581006bd6c3a0e3a05c96868ffa0b51d2537f4843a0bae3a7e70ad0b02f18507 00000000000000000581a81856ad89dac2d72f1263fb66ba2c43d22088896e99 +382000 000000000000000003cf98590769bde40ffcd6800733ab47dd406d8203e65a89 f8c75860ff29442a4baaa6050a7a519ba13eca8f7e4f53759bbbf8653ae61317 00000000000000000c43df306ac280360bb0592d2a56f2b1a9e4c8e870907bf9 +382100 0000000000000000107b765d92057cee5bd342ff4b4dcbc652b51546a170770c d60ce9c75337c1f9a6baf4057c1f2cf8d4595820fc42784d269184ed95b1e2ac 00000000000000000ab55f5777acdb9a9a00c5b29513c47411a4464ff69aca0c +382200 000000000000000004d72e17c646b5326e2f246a34d224a2f2f11475c6361259 9ea37aaa590e5a9773c2ee0ba1b78ef61d8c202c6e39b16ce8a4d8cf7a713b44 00000000000000000e45ca0f2246ced532eccfe0cd5df8741ad83135bcc248df +382300 00000000000000001164e2256447d19d8d3a4d79befd6f4719b102b8cc541c55 5a3ee09ff0db433e3316a091591a9edcaa3889278d59833212ada525bd65880c 000000000000000008e1e5253933ab3271476fd867370e8a8bd4f888b7bf834b +382400 00000000000000000426f4a964eec7548db803d06c4cb5b6009d603b94483074 31b127dbf1516ca9305f27e4b92de05bd69bd5d8e2cb2a6daea62846d7900036 000000000000000007ae55fa1b8581caf14dc7c9ec3669c3d359747399d67796 +382500 000000000000000001ec54eb2775e4e380c7e04ec1fa41bafc381a8a67509eab 4fdc12dd4ae8664797fab65543a371331f4f9afc3c8efd9fd67743e36bde37a3 00000000000000000f700e1f8d62138442934db793e08f25cb700e4b5479164c +382600 00000000000000000d0ec44a498ecdd7fe5c065cd383bf5348c4a3a15023d58f e9de5fdfcce616a49763afdd4ee58f9e1d14dfd988281c0cf74cdc1032be6506 000000000000000007bc61efaca7ea6a6a1686cd293b79733c1552858523fd96 +382700 0000000000000000083e8b38479d62c156a77dae44ebeae976d1a5e153e44bad 1b203acd885c9ed590d8a391ed34155722b86ca8f3c074d1af6ce7dbab4f3e38 00000000000000000f88e6b2983a4cdea595ac6e738c3de30b1317a2e6e3ac52 +382800 00000000000000000183f0c2cd8ab1f7ce9e2d8d43eda732460328397c1d857b 766782dfddacb389407a4bcf5eeb654bf575cba854bb587ef9396a791528450e 000000000000000007530ec600bf178553010b707efae1c83e77ab9fdabad896 +382900 00000000000000000cb0a01b9af4f3371b25c63b81f18a2b0b582d43aced41bf 879a096938655f0aa8bd4c7d852c5219b224fb7861253cb74625afb4b1b3ca79 0000000000000000004645ad9f89944fce18df20dc01305b5656d5a3909a85b9 +383000 000000000000000008d31d0698ad99897c21cfeeb52157f3ee66ab0b5a9614e5 c0f4597488302d74ee7b288df31f5f8e478cf316835c3d736444a7222b67c107 00000000000000000195fffbb2f518d27c791866bd679e7995c21b6971737755 +383100 000000000000000000edad83e2d593bf338aee541f2755c824acc08e7761541d 3cb8ae25ed307e34720cf1280e95b7ee18fd0dc1b9a5c1cc6883995346685cda 00000000000000000692bf96bf6a41190e73ec5c0e14d16cda095dd1e6c2d886 +383200 00000000000000000bf438f994d027cb6ba2062e33c34c2eea196495c7b9f08c 4720f58ee22be0e979230277c87193b2825ab073e5b8f5fb3b3d32df91052bec 0000000000000000107cc538e8667a89ad70f0e1c5965f25f2f6d633c3018436 +383300 000000000000000004afb2f47d289731542197ff52972acbea4176e8c5eb1381 beab21fb9e9cadbb21e4610b90900c545319b237934717b2e36b66d28b00f707 000000000000000005846fae2e464cc52af24a7330887aaf9d7d101c8325419a +383400 00000000000000000f5201d66b52b41814c38f87a24b9e2594ee2b9f9b7897aa 7c8a953d63dde9482e892fcf4d270701aa22e537082077bb2604088f53a155c1 00000000000000000be5de4ad6e794e964e1f349fef9325c02be9512475ada7b +383500 00000000000000000133085e2d45c060641229bf56c14039f801d18e096ff0bb 9e1651a0b685e20934e5d2ff31bd773ae52381e2be0c0a2651a282bc266109c5 000000000000000008382f70c9433f8109366f968ba27ba1f42015ed422b13ca +383600 000000000000000006d0db37f78e320891995d348ea0b971bef443438d1ce2fc ed623a8b4d8c95cd7b31e17d95470da0d2f485404b056a834436426edd38b4d2 00000000000000000d41b17307865b23e76c7c9c4f12196722f22c6ed5a9fe29 +383700 000000000000000009f27bca02b2679655e251aa6f4a2dc68741a414de90e731 cded26efc14bbef4ceb32af24d36337aa1f6fa5d7870abf7adbc2ed0a0379063 00000000000000000da2d92f08d26239a863cdc5a9ec47ceb1ab5849d818392a +383800 000000000000000003cafbbe523eff065b688f1ea9d72f3b4efda702a38f837b feb8d672e61b2068df05c14d106ab471011ddf61214132dd8a5a4d46dae89fc1 00000000000000000cb624e71d3e24f523c36246526eff69057be649b39b25e6 +383900 0000000000000000019ec7f6052a91f75583bcef4678a19a7cc038db51951238 1edc022a41af63757cb18030b86bc2871370e2aeef1c7f320c3fa6f3cd692a4f 00000000000000000c6865df0895b8a6e4cc9350792a8b20ef86a0e7906ad89a +384000 000000000000000005dc7ea53e2f6eeb09798cc9d2214f09d249661c36c288b3 8b23e691d5dd25cd396f5ac14dcb3954a4f57e9ad34d209ff8f3dd0b6f0ce6bb 0000000000000000033898c26a795ca3d35096d2d3e025823776277db16d977b +384100 00000000000000000a0db64c03586488a4420f8fd0807a9db2940cac28730e86 66b8bc4a9650cac8956a69b235f58d550a6764e4e83c13b3922d5844096f36d7 000000000000000008f9ca5adfd5f9edfde56b4cdff06a4879b9a864a169f58a +384200 00000000000000000a4509d6c5711f33027352bf975934eed14c3bb33cdb6345 899c76af5dd193330ebcb3f7f5a201518be6e8e6f376e1621065758cc187f5cb 0000000000000000047532582460c98c423bf0273115e08ea957d952ea5ef074 +384300 0000000000000000022fb1ccaaf9352c8adc32b6a6a1adcd84a79353c87ac2ed 61743f70c6626938ddf93fa93cc61012c8db1d5d128821077cb5f06a66ebaf63 00000000000000000729508a5f2f7a022b056c80580ef21a3cf529b7aa634e2e +384400 000000000000000000985b548d5b4e08bfe46ffc1dcec325e0551dac0d35d5ef dbefd2e36f55ca99debb81535a37cb0d60948862453ba97bc99130cc1e01b64f 000000000000000002a9de828681400f8c4f08621cd682282efc925aeba61dd4 +384500 000000000000000002092ad541377db3e5df7848288fa5500a8dabced5cb40ea e903c668b2fdd52ed50f533799b5f76714a70d6e70e4053c45831f18c578ebd7 00000000000000000844db6ead93f351c01f578efe7577e7e3ee25bd604aaca2 +384600 0000000000000000075234696e79fc357bda911742f19567356ffc538a0d8479 db2364fdd96c0170f52df30a291dc8520eeb6d41e80e6dffb3486c6f4e5f77d2 00000000000000000b299258f27b9060b58b31645988d5e15f5c894496a88c84 +384700 0000000000000000105b3d16f72df95f6cf54fad6992c50ee0b3aa32384f3bc8 52c35b0b8388f9c076693dfe31c42e606ec0a0ff00abe5fcf0e452045af0de3d 0000000000000000100a497a2cbd148798428e87e017f6ebfa15e87aa1f4d75d +384800 000000000000000001a06d85a46abce495fd793f89fe342e6da18b235ade373f f1e2a63882feb0b9f9d3382a79e52855674adc838d5e629466ed6ea919634c2d 000000000000000009115b47eba49caa8eae070d2a29ff4f12cb96a1123e0f5b +384900 00000000000000000ea0630e781e2ff9dd43e000996e574504668c088ccb1992 fa2927972adb525bcca15b79c24f67bfb9b97d002e772fc615b8b4b0bd61f0d7 0000000000000000040908bbda516c286f77b4071b846b2fa792aa2876882473 +385000 00000000000000000b7f6e859cbd68dbc8b309018b0ced9b56b37ac75110f998 10ddb0f1fd0cbf3c6bffed5bc6aede10d19c12060e668e3aaf7cf7d92ba964b5 00000000000000000bf8032a663982190607d5e22db200adc57e15f740e6eee9 +385100 000000000000000009ff66a7a8199f266bddab1e667a3211a3484e62a92807d8 7c1ec78544446be375279e60c0b4c88538ef908589985a9e3e585e8632f45e5d 00000000000000000d2c62e53d816b8e1967322ff4d8077b16d88591b1437134 +385200 000000000000000003f1f49f9832fef012e8a4f3b122f9b74296802ebf61e4e8 caf3df5b04cbad5dbd7f56063662f66530f0d324c512b44d28cd377946135755 00000000000000000258e61b05fc222f2ab4820a987f8ba957f500c42511a86b +385300 00000000000000000c77a250066d06689fa2f020521df7c057ad7516071a19b5 c0f6b8e25dab6174cfda0d671453ca7f27b60f5b03063bdf7d4b39e578ed86d4 00000000000000000dd429bc850108ee0d24d09d2ba6d0b16a33d40c6d2e04d9 +385400 000000000000000004e1b09dc1d68d78fdee7f87c54bacf50458c276da72d167 c22ac60622e958472ddb39ae9ce9fb1d7f949f5694ce81d2ed4ae31a2ff767b4 00000000000000000171eea501a62c432578c825139514b4cde1550a3b9f4cc1 +385500 0000000000000000087ed6a37a09a4d80224d942c3652d199d09ff1ea07a7ed9 60084dd0055b2953267497d8d26f1dde43d99020de918ebfd55c4307f3d48ca7 0000000000000000011ca3422d97438f14d5172d84e8ff9aaee824b8b051409b +385600 000000000000000009cf50e838f3523b153471be8eba490fd1b9f438141db456 3bd3d619d75adec4c5ed16c03be2e06d59cf4f0ccfe467bb53399b1aa48ee19f 00000000000000000c549bc477f02ab49d25b50f3ec8d099ba238ae5380ef9c8 +385700 00000000000000000496176d2f5d5be46b379683285a8f90bfa956a85ae5bc01 3db52de205114252b2ec15537401931c115ee8f0be3190f545132e12b7fff47c 000000000000000000bc2d765933df0ddc5c86ab48d9dcf9cf4f6baf2a9816d9 +385800 0000000000000000082eb254bcf5e508327a44f9135fa0f8427a95ccc555a640 8ea4cff598cb3d95ee83051e4503ae85e4d9823cc2b433a185bc8f1338c52e14 00000000000000000ca81b697774010f222f9d87f53de3218f455313e7def444 +385900 00000000000000000cef6e0f5fe5206d132319c265ed4d23da2c78b6a6990a6c ef736190fefedf319c07be71202136e7484e60b2a32cf9aeadb81eb5843579bd 00000000000000000a59f5eaac561cd773f0f887ab0b834a92825c995b3cd622 +386000 00000000000000000d94c8c0b0ddec874d2a597e988154733d9ea614292c08bb e11d1fd4e81b220fee3330fe2519c0fcf77278d3e1dfc47f55d05f1d7b8dae91 000000000000000007a2bea4f81d4172715f7ebdad1ad4021e3cb1d1c7da7c21 +386100 0000000000000000018be32b9f799d0e6adecc78d88f22376f0616cc4ba1dabb abae284fb33747f5635a74fdf53603a8c4c03a1a64d92499cc3a15498a1d64c7 00000000000000000592832c12512a349f5ba80aa1520404a29c86b33beb416f +386200 00000000000000000f049602916159fdc773d6857fa0166d8a005dd83b1a1065 7800c07f789f9f7e3e60ab8a1ecde67db64c41b87274129e3c3fccee518db811 0000000000000000026b34454991512876600b6fad10d5f6df6b08bb621ddcb6 +386300 000000000000000007b292bd27b621c644dadd0846221f1636b5b9848e953141 32e7d51c6da7ceb305c508c5e862b95b9f0451d2b9697e4abaf0d6b36748044d 00000000000000000c939eb917896d83aeda7c8f78b98c6319940215a958dd1e +386400 00000000000000000485c21e106b4565c52632c4b629568516d529c5c7dcc3c0 183776bfee5637c7d4a1a75f317d590196534ec56e40bc71db3f0c66cec4ce70 0000000000000000068c014552ff37e8bb926a41ac1b0f6142d35c45b7ac56e2 +386500 00000000000000000ae1db07cbff5e06a45ce34a9772d8313dd9de0b650907d8 8a862349d1b7d05e72831504cc737cfde471d4637faaa9304b36780a549fb60a 00000000000000000d6a2fb175528b4888eeb6e543c7f2cf9cf7a0022c236fa4 +386600 00000000000000000365cd36f49dc7d1e9f04ce1a55d5e2d9f27d2a7b1008d4e aac83965c86c5bcf6276e5163db83147d0f8afc22a55655e33e1892dbdef0cab 000000000000000009c563ec1034094d71fe3e6453984544a8b98b0e9b68eac0 +386700 000000000000000005f7d773fbcc2a97bdd76277b0ad6eb831697df1573dfb6d f8d4be1ff9fe9c3bb83de841cef6970181d9d33390017cd3e6d4f00d12adebc0 00000000000000000475d3a5a903cd94a3470ac8373e6be788dd8f20fa1a6e2d +386800 0000000000000000015045c13c89ef81d1bb6f0fb04f754b4798810a65306885 82b45bbd4ba2b59dcb910bb55e4db40607549e3c4cc31cfa98ef3e49bbaa8cb9 00000000000000000b6b83b89c0493e8ef20413a1695c52395ebeaf8457c6719 +386900 0000000000000000062f8f9b0abd5766ed0791645753980f6eef1925800df95b 871bd9fed33ff9a8356f16434378b2c1744063f1cd927c10bc0ba4f61cc6d67a 00000000000000000e972bc43503cc566b351d46f8307eb84001c96e00b09fd7 +387000 000000000000000002367c3cfea3cc7a5d17553e978a77889eb37ce0fed57255 458c4926ef344a05e2a52e65ecf9ebc53d19e8b7014642db5ae00d46f5aca7d7 000000000000000006f3e8716471e6f05ec1177a0e49e29ee43a344f284d78b6 +387100 0000000000000000046b46aa8a27efcfca8ab9f28bd274fd1132ce04c5877fe2 b0860cc2d9fc163dc7becb3d3a2c387fbc19350ead2bf16e054d505fb5f03e8f 000000000000000009760b01e171427b2e9d7256829df557e92ed7b6799e7aa3 +387200 00000000000000000d0f5b1608f9c868582e81ecb76ae0d4966e601aa75a9038 b9c5ffe2e670a876a5c49ba2a29b5b0476c2ff10129cffd267a150f0e9923775 000000000000000005e7e38e167430a6ff022c8084dabb47d775ce454666353e +387300 0000000000000000075f2f2481dcb1b0289e57ab34fd33c2f0e9556ef70538ce 69b2aab5ad574b7ca560d37a45a5fca8cec5d432e6935cd9b2a3093499ad3d19 000000000000000004eb4caa26b9d51b0cf3062ecd7c8ce1f7d0a4a4cb293b37 +387400 000000000000000003229988eadd6a9dfa125de50435e1381ce26c90e8240014 1ed9a43850d14aca88330578c84bae67f243b6051c94b78d7839a8bc4a42a7f4 00000000000000000103f13e053c2b0e3bde9de3d895ed5a72ca4d8943685484 +387500 000000000000000005ad7fe6fad71564081cff095e4b9768fe27aa7f69f8ce5e ce16f193d8d85a8c4f1313e6f12a7e583357632380c5d3c80dbbab736e28d12b 000000000000000003b3dcd09f99e6104d1350a8cf494d5377aeada320cb3ab5 +387600 000000000000000003b0983a40b52363e32758b1dfb5277884541b75ba9c07dc e75939f8f8622e551cb760e55e702fe06d423e911467782737ee5291aa976473 000000000000000003954ce28669629f96a80a1aea8e759dab49ba1748a369e4 +387700 00000000000000000c7ae67e8fecc643a3e8024a2c8e8c35385c9ed011369fde 0e9acab5f800669b2cb9b54aed57ba2e9905503fc2a246219fc696591f3364cf 00000000000000000cc6b977937c48ea65d6807295bcb515b5c6a94e34387e5e +387800 000000000000000000e8e7d94fb4c80530ebfde66c038c16073034ea9a439cba f52b2afc40ccd341a8c415744e581c5b1be5a4ed20243cabfdde02469d57633d 00000000000000000c9bf7183a64c54bc6b1a8cc03b524f5d9a3daaf43f1b12a +387900 00000000000000000c00aa294361a17311b44c8d3c6280c73f0c4e5d39f07227 d27cce5e54403f8c0e5f2a1e7d87632fc449a9ba910e5aef27f526f0bae942a2 000000000000000008eab53e07733541a23ab7194d9a531a43b6226fa2d7d461 +388000 000000000000000003c5e9f4f84dc78b5ca96b7f2d89e9063b5f74543b42b9d5 626c3bda8786dfea5cc07be52e6f358e587ba9114e27d03c46c7e9ab27b6a1b3 0000000000000000040a0115208109fa1a4a80f351e7aa474cb26c80506740be +388100 000000000000000005c4eb073a40691f005a73e19b8bedcb56dd8762059d8f05 7a7f3fa695c26bc68bc679c29a0b260421f2bf48cf8d8e38f35b5a4432b843af 000000000000000007e54266c1d9cd1ceede8cba324485eac5143de25d00ace4 +388200 000000000000000006be14161683fc71ce1e79e57573340c706ec2c16f271890 f548664d56eecf73c402c646b6e74ef89a8e94f63b3be36bb108e3638ebe950f 000000000000000002b1d953219223f277a9863f816d25ccc695553ce32d08ae +388300 000000000000000005cb6f6e2f09e84a353ab91756a38aa50fbaf25059f76666 ca113d0c441b8b6d14886252cb9e26c008552d79916562ecf43cf12795bdf27b 00000000000000000d3439d025a966980fbb7c97e91c1ba2955604077661995d +388400 000000000000000004d247232940b10b69bc0190da00a49b86b395ca88792bd4 af00c6d5d471dd1eea1df701f605d3cee1eeb62e69e4472347b33e402cb9233c 00000000000000000db54dafc19eb790a99ec186f4f0eb66c49f4d50704fc107 +388500 000000000000000006cf66a6c7dce22f77d54774d66971e1f2dd44e84ab668c3 6055fa4e45143e2bab7d0155caa6c9b0c1ed3dabb77519eed2a0030e3cfb677d 000000000000000009f22694ec1eebb046098462c2348fe5e0484a75d7d1ed87 +388600 00000000000000000ad68749d3bd917b9d0e1e012eb94c78599f1a7febed7dbe e9017fbe18ba2846d458de5fca919c22fd85b4c00eb4676040340347ba1a301b 000000000000000007f57dd79611b8059a68aa064b4dbf0b312bafdf1328e3e6 +388700 000000000000000006d98d9eee8187783ebc20077e4f0b1cab1f9ab6ae8aa112 ecc9ea3eb89c5e45a2a1bed8848bf9ab20e0c9749f780dc467bd24ddd322dabd 0000000000000000014054e3814a835b014d33107357bceaa0e176a20e71498b +388800 00000000000000000b1b29a572af3a51a1088fb21004f7191af88af79d622c62 0749f655c596df663fbc07dccd70c1639e8c9ae1ebbffa0585e017ed8341f3bb 00000000000000000135a4a21fc0af1b2ef79ebe3d4a680fe9c365f5e1663a81 +388900 000000000000000000a6cb4e21d4e3fde734b61b205e6a68dfcf44632bec5b81 a587d9a95a95db3df35c756b59f30430bf4ee3be1072e50a4b43b27c7da612e7 00000000000000000cc50e1103d1151f5a73c4763bc68c543eda1fcb189149b4 +389000 000000000000000005294a6ff7db3369e70534c091ee81b331111a4e7916c3bd 2896b59d1e30b3341bbbe33f6ff46efca0d060779245f6c70b8dce761219059a 000000000000000007653868b4d018d2656edda8d9d9fab10fe66126de949249 +389100 000000000000000009ee31279b6601b0cdef7cecb971b7a015a7db2a35a3908a 0335ab0a6c01b6f2f879a2ec03bd06178c9e21f8f92bce84d1555fc13429129f 00000000000000000810ae694333b9c99c27a22457eee3f1372549aef73e63bc +389200 00000000000000000a5ff80919ba2758e740f40f375c3cc7bbe9a52d22f1bcc4 70cc4b81ed8b0f44867618391883b82fa8a0d5467fe3147593ec21bead86cffa 000000000000000008ddda396c1e5aa352e2f1adeeaaa5b7605b9aa2734b3f57 +389300 00000000000000000a60d942cc01288c0172b2e60af24741080eed4ef9714bcf b0689e867b113d534bc389b84eb89a9902b3a049e24b7729c8e385aa0ac679b8 0000000000000000077e6f6e618c5b431f634f17519463d8806d3fa6f45836a7 +389400 000000000000000003c1ea56e3499b55e00d803e3e0d4645ffdf12e96ca72d51 4a23a6f2023413090aeb299337117d423684d5d248f949439c3ce21078368385 00000000000000000b9fc7d0e2e8143511f2bfd20b6d0ccac172849881990fe9 +389500 0000000000000000006166e421051bd1ccc2bf3b80ebd2ed20c71a2eecc10633 5102167976c7729b2d599470f8697b09df555177f7c3cf56fd2dfa4a303ca12f 000000000000000006950c0d8fa2c0c1c1ad201345cb1483d27ae150585eb5fd +389600 000000000000000002eac9265532aba3fd5838f4b1aa2e3fc0a2935e4663234b 4b910f24d1c802ae6d544eb57b487f70673d02dc3a746d1c0c08f5b74ef0e5ce 000000000000000001b759ca23bd10287eec712e9c61db352ec1dca6acf36e42 +389700 00000000000000000b1e012f22bb8c85e804e1cfbcdf0c20efb2574ebcc21ca2 82ea87f91a408f3f6933f9207b39ce29b22a5c3dd92e21fa976b22bdeb58b5fc 00000000000000000b2cc51a3b3fd6e3b9d1ef5f9c6e743f41b760b47b63b03b +389800 0000000000000000042b2f87a79c549f50929545895d8ebc2a991dc5f2dedd90 afd2ef1fb5a928780e529dff925f51e8f277d118969afc347be3c1dfa4b51f39 000000000000000000be4152275ebd8b1d2bc219efd23e1f40ed8e791f9d7c26 +389900 0000000000000000006cfd261b46b7175fddb398b095fef37d8e059613728ee3 51426b74341c8da02feeb0eb795612cf97a9ccc3bf6784ac99e2711b84a5701e 0000000000000000074b757ff4e3f33728d854091c730302634c8afef1362c03 +390000 00000000000000000520000e60b56818523479ada2614806ba17ce0bbe6eaded c5eb2e5bc5a276e233037f1480f9f122b07bdbed88d987438b2d42ea0b5f9c79 0000000000000000055265fb53f189394aaa2c88ca37548c693c17965c9a45e2 +390100 000000000000000002027cb7cea9c504990b44fd43716b190ac674fca4dcd30e 57e84baf63c0ce6a211f546c712e9219b9404850220ee9157785687bc199b90f 000000000000000007783377eb206a9c63123377491b626db34f7c79c0d5c0c0 +390200 00000000000000000a3a25468b5cb89c89b7d5ecd0889894e03d58eae483c4c4 4595704240103d797dad9f49437f2ceef45fd5924984fa0132c52f422a5ab7d3 000000000000000002b651b19805caf8b476caf261ace4498410b77a3cc481e7 +390300 000000000000000006cd30fe0048ae2ba493ed93c62a0b7ff62d1c06578063d7 296003cb82522b70b2f7cca4d38e796b31cd02f5de2c6567e3ced40ba5078659 0000000000000000073d898a1c95364203d7c22a78246edcee3af4dbf639b166 +390400 00000000000000000ab231daf6e3ee74fdb4c5ec5eb374ffdd276efd3aa0b71e 71fe24f6924675df9881f49c746c7c3f57f13df4c5586d4dd751a6cd868e9b2b 00000000000000000a252db42b11c61df335b9e488b072c97148bf8e7b3ea28d +390500 000000000000000009b66fd652a41c4ee268b404e282b5f9c4fd1e40bb7eb4f3 1c8625f1fefc611dfcf4d2ccaf85d0e5bb9a5cfcca1d9f504e69ef1f6d07d0e6 000000000000000002e30a7328bf88145cc24cfe565365d89478a47d39d79edd +390600 0000000000000000068767af38259f44d7e9e48c52ee917e8db5aa02e95d829c 8666bfb8401b84d4d2b20f28bdfcbae2d9d54426ba6686a3dd8830b2f6f4f74f 000000000000000005a098b615e87a34f420d405955b39df283c2048ef8b0a16 +390700 000000000000000000dd29f2fff59da0172ebd6f1ec6ee1337c155ac6a64bd77 dbe945e65ea76e3c9276f8ecdd49a3e17c34f6e09571f55a9649bf0da9cd7ca1 00000000000000000b45f4a780d842459a0a16253b50976ab3022edacf90a27a +390800 0000000000000000058a7bf63d5a6311df3a2cf7fb722a56f020445564c58606 5282a4c96b71721d94d80c223be6fbe6c9ca6c233dbe1573a12f304af7078f58 000000000000000004fc1e35b99fdf4b4c020afeedda9ca8cf3cae6e7d634101 +390900 000000000000000008b4f3ad64f1c3486cee479f11fb1c76f9f7de2cf15d226b ecbe69605fe15a33cb33f628119548005ef724f66b3eb30d6bfb8075063708a9 00000000000000000b469345216da1ad7aeddf9814a8f8200289787530ed81d7 +391000 0000000000000000016936bae618c90dcada8720313b82f8e22ec95021de1b3b 0b16d0c86a5590ccd791955875ec3136aebd37435db13cdc03aad2e1c3ef81da 00000000000000000065a731ffe0f05ca3f46224c1213598628e49a820e07f0f +391100 0000000000000000071b1ee24994f22d59a55cc7b7b9497be15a3dd1739a3f6c a74b5a6587476a113c94e9f307122e0e3803b45eba1d78acd0703f43d658f947 000000000000000000f65cbc450d8e6cfdfd81c0ce924e215e4d8c958699dda4 +391200 000000000000000002e3354f741cf0a3b8976c660431980cacfc04bac26ea9f5 54a305b688f366c50f9bc3eeed7596a78757ff9f694a415dc8cda0a66e767e98 000000000000000006bff7edc682a18aa9a34a83752e44258f2f1ca768b0062c +391300 000000000000000001190dd33ddeb0263a56bd09dfc20708188868ac749b6e78 2f005c7e731d97603aa963224874e7db6809aed8325d9227e06b3bc90720d951 00000000000000000571005d4a513af6740105b13537f04c6637f9b1eb117700 +391400 000000000000000008575d73b0f277bffe95502f3d97a54cf1a1d87bd62766f9 bd186bb18a41f9d7bb1c7d79e5caf47349b097c3af4948fdb6d9681d6439e73e 00000000000000000900764ffc3fd523dd78c47cac7fc847080a3ba763aa4284 +391500 000000000000000005b3feb59f5d41a4c39c274958d98ca54e843612f8e0ec4f d77ce0cdc93f88f3eed8969ef65faa63feb79861dc2b5d5923ad0ef32a95b619 000000000000000000b64f5827d5541b81f86900bca4ea2b02be940aa864eef3 +391600 000000000000000000f2090c11915750b434d29c81a32f5b3494113961c0205c 401654541bb74cebd9441fd920ffe51a96e314db56e18f989e3d06d298334882 0000000000000000015e8a4965d0df125fbd60be19c7fec45ad908ad1631d9dc +391700 000000000000000002a1d1424df6414089c1a23e036e2b7815ea31be9f009956 0ae9fe78b14e4ba1462746be875b62d9d7fae65960ffac88951d85e3e78effed 00000000000000000290d06d0293350b6c50e96a36989190cb612eee50dd2cff +391800 000000000000000000eb34e754218e08d73b49b9c37478b46914f01747e18026 4cf0db26d3363a8fd1d0d38ea652d3832bddd8213b80843716272e769aed63dd 0000000000000000092a71d7566c4c956203d22cefe3f9ee4fa50fba15b4922e +391900 0000000000000000046cfebefd5b0291ba3df0df3e3f7f6b4a5d8433ec99a053 cca1738ef4dbf91f510e6a3e15451c6bf2c9fcbbdd3f6543556f51685a05b1e1 000000000000000004876e50b358a3eb54516071d8c6bc1c2cc419b7e564e2f6 +392000 00000000000000000850dc9d4a9a8d45d618d8f0dcbbdcc8a6fa88a6a90dfe1c f68d1b20f6bd6232f399f79699cf8e4204e3cefc08fe112d16f4376ce7fc1da8 000000000000000005b076c1bf4bb3c1bbf331c0d1a01461e9429a1b71f40821 +392100 0000000000000000072af43a15c64bf7bb113847d45ee5c57695d28566dda2d4 08f9806033601aa2b75928a7f019adcd2f6423ab24a64f4cad9e3b95bd55ea2c 0000000000000000004d6a7f1f516937e30c2063c9904239e88fe4c8aa39fed9 +392200 00000000000000000201ae1ee57020efe87a0616577d40670c79306160ff9782 3908cde82822d7c676808c5655357d8c89a0282f545e84d1bf14a8f57095b764 0000000000000000080bda161e12d3d56a363264c5d9e42b1d3b74f13fc99d1b +392300 000000000000000004b84f465e1494e2cef793d4340b2d6acc15a126d14c9eb1 5f536da86905c2dcef9be80fac3aace1e31d50b68afdc9739a005a61d576f07f 0000000000000000006c96fc95c8c9e0477bfcb13ffce475bccb40d97f2ce6ac +392400 0000000000000000017842f766d210c08c8bfd0eb455cfc0c4c209d9078ee161 38208fc8e049ab2a74de457d3fbb61094ca7e6152bb61c99bf16f3d1eba569b8 00000000000000000332227d8fa96311de28be63b83d433530e6aacc8f10c9d0 +392500 00000000000000000357dc3d36f15eebf90ad967f2305493ac6a5423eedeb788 0c7a25263450c77e9dc088710825b10ba7866992de24554661c1eb79ff0e49b1 00000000000000000564dc6bd3b8e48fb6139935659f584a42b1dc7608993118 +392600 0000000000000000000434f160d6c4bdfdab602b53cfc6f1547ca63ce2518011 a215b8166a6e72ec5ebd9537c563c69ae1e7c6e451572ead2dc2cd236947ed42 000000000000000000927b05588f2ba23c98d7d634997b9eab048ec9064f72dc +392700 000000000000000002977492502a9a3aa4df767e42d9dad360aaaa011bc904f5 51d2d74146cf84f6388f290ed9543242dd8db63c78f801c5b67bb1332620ea92 00000000000000000079d9077c75cbe023665384e6e23d4b4bb027f233d31bd6 +392800 0000000000000000029145d869f48f6d061ac54749a4826356a3dd87776e00ff 309255d6d8a98a54aead7b3764665e411ebaff765615aad22fade46b4e0ed361 000000000000000003e5b7b6ea75efaef25da3b8e1e5747c3a28c2bb484d7933 +392900 00000000000000000043386f687422f6840b2b64ea32c673592c517400361722 ed0b4834ad3348c5394bdbcdfa1f604af7de8ede5cde58786d595f7decb2a574 000000000000000002f4316698b0b62d366828140e47fd0d4c635243dfddf934 +393000 000000000000000001fc0feec5560a84947a939f7fffe1702fdfb80f1df84343 fd31e00a0837c2374ead2644d4225feb792acf557e438ea0359b3d545a38c14c 0000000000000000048107c426c826407a5416878515be0f94cbf592484e8eab +393100 000000000000000000a0d9b87deff020298698d365bde9d40c3456bfb7c3187b bcc6d8eca40c865b49ca9bfabf02ce5ed4dcddf4c776ad73755da7f5014381a1 0000000000000000005e2e358fb0b02b457d40319bdff67e03747046b83e5767 +393200 000000000000000002a11e209a94cbbc6b09083aaf6bf323f27ee7f4e6b6d381 98bd280ee939510ec44d015fb64799cc54186063b48760241653977749078689 000000000000000002ae68b5de22007817467e3c664f7ec8b912a95f9122945d +393300 0000000000000000099725d2bf198061f273740babfbde63f29544bbdafb6bfc 830583a113ba31bd38e20a6bc58a37d19eb9533cac5f80ae9db09d02afcb0015 0000000000000000089381179b20c7a34dad67a7a9494fe2157cd96af0f1ac82 +393400 0000000000000000075530b8f6a2fab5b1901591353da7dfd2514cd624bd3389 fd7cb66e95eba92bddee43c51a2d7cc87602b4dc01e0925cb1fc7ba1ded85c1a 000000000000000008066669480607bb004218d9cfe83e88c027839cc14e8ab3 +393500 0000000000000000054fd9e46e3ca036c43a3c26f05da750c9a9fe50e67e79e3 2a7c640175a79a57158864acd42d3e76895856c49fd338da638b8f73f1aa78ab 000000000000000008cf9ecdf60cec4e70df82767e532d70cd32563a61cfbe7c +393600 000000000000000007e2f8af1c8caa3a43f06d127f932e2df26885296bb5e3f5 c347f4a2726cfff0a25345d6983ceee7034b9aa1e7499e5166046b926e8f8ffc 0000000000000000054454e9de7f6605d0d7a209adbedbffd0c8cf653bc9cf44 +393700 00000000000000000654a3652ad75bcec1acc6678138c334948859a74161d4ad 70e4cfd366758179dd799de93014a6bc2e147da3847eb683da3aa3fa05159e68 0000000000000000067316817ebe6ed7c49ab5613f7a1dc17fa9abfd2ed7166f +393800 000000000000000001de2dea3bedfaf942e6e0c0d9f20cb37f62eec9b9da3f69 5c182c8fe92a5e0a404e31243cdba2a8f55d2916acfbd351d0c5bc95790c4e6c 000000000000000005bb3aedb51c039eecc7fd2821f51aa78c0f6d1bdb06808f +393900 000000000000000004f041ac9bdfa57238cff54b20196d1dfe8d20a0c45dc18a d0ab1343bb35e8fcfa6e025e3f0e7d6d9493a713e5466033c4eb4f4a408f1d27 00000000000000000053ee54e5f3314758f7be1e618c27f595380c727dbf60b5 +394000 000000000000000009ae6157a480e351cdeb8be494362a3bf3cd1c4feedf8ad6 fe8a2616a9a3dff68c77fb150b9dad27255cc1ef9ddada6925f13b658932b332 000000000000000006d90033ca2d3e257db9853761609cf17b00cc6a6e705f48 +394100 0000000000000000075f10981bd5fb22a8f1cde8da43165032499bc4224c5f75 8c3b614b38e2d5c6074010643ff3b545d6816d23ebc561015f6ec7ad859ae67b 000000000000000005f0ccdec7eade818553892763d33e0bb1e6d70397d04bd2 +394200 000000000000000008f7e2a8fe580d89baf14731568f00bff396b8d07d6af269 7e77f8a681210d4e753e1cb8eec1e29156e9514851422229f9f0261b96144b9d 000000000000000008740c2a5971a7078b9831b1360bb5eb57e0bb2fa56e5276 +394300 000000000000000003c0dca25520fd50fabb2a47dbe1099a9ff0153c93ea2e1b ff01bcf6dff8338d3c6c218ba14418ceb8b4fb5196f2a3f31b9c1f2a344861e5 000000000000000000ebf0433da7ceca46550fa734c29e03dc2d289f59653825 +394400 00000000000000000319198d1de816638ecb97e5811f897e4703735598683fef fe54fee1ef5f47d4dfa9b46ed1edf640645424992b1438a09f24982c13c24e8a 0000000000000000055dbc1c680b19129b3a2f10095e6496e9bf90f5a645ff9c +394500 00000000000000000776bc3ef2db94d990b7f6e65a4e1dc14c268a8df583b2c4 c2e4e1df14b0b08c9ccf0f331bc254249bb7aab0f5326f9ebe8125ca22f04829 00000000000000000660fb1b240fe34b571906999ba7af816bb069a513b1563b +394600 000000000000000003a10d049b88eb6f694e9b50e7308bf79135a38e026cb4f1 de60f9f525a3d039ba96cb39c0bc645e970e45899c9a08495a96c31534983a86 0000000000000000062d85339d89898e9c64e456a5fa1a7292521f4000321659 +394700 00000000000000000693f585c31786087ed0cce9cdf363307a1e6845adc5c3a5 efdbc4771413f157dde15a3c300f122ab2e20e33833a5e2b6494afe2dd694818 00000000000000000371dacd34fc170d732da53b9b678387fe5be6334af2b867 +394800 00000000000000000100a61fd1bc68439086273a1c5b5a9c0bd76b474acc32e4 256cff44f748356c248c8eeb87d005c541e8398999c7eb54a6c47877702371ee 000000000000000008585ab176e955df62aba93cb60144f559b9a892dea64f24 +394900 0000000000000000099562a068d50b4998c3c2abdf9066169e1c2d73e865e9ea 7fbf0c186d4601dc1980dffa01043b2ab1c188a5b2966c433f86619ec04f9ea5 0000000000000000028ee603c0438109e5f793f2f6ca99ff24aacc5a1f7d89bc +395000 0000000000000000014b0f613fa97d3f512666a8aa4fd06132ff4fd330a0a664 794213c74de0b804c6ee774c25a837082c4c2ffd3ff1d8b1f8d4debebe728676 000000000000000006d2270dbb44539e09907cd65fff1163e623396791ff4cca +395100 00000000000000000374b494abcd93516af2756fa48258cb7a63612336a09ed1 4d07d3cb28f490593f795a54dfba6b502aa21fa949c04ac71257dab2db07b553 0000000000000000048aef35ac596956151a8b39b6a2cc9158ba5af51615fcaf +395200 0000000000000000086cac3335a2d28c4e00c5dac3ed8f9656e140df4de4fd07 5f8c40872126113acc1915ef5331c2ffb2283d89d0c876c017a0da8117c3dd51 000000000000000002aad7c30b03d600806ea13afd2cfac34e5ad1873c69a8ae +395300 000000000000000000ced71d5dd6a4048413e2128648f4b3b9bff439067512d6 8c11b20b0d7bd4f04aed9e433a3edbb64f97c59275a8642f1d0fbf0f758fabc6 000000000000000008fc5a3b2e264cc4b2b70711d4fcb982056176a801e44165 +395400 000000000000000008507dd449bcb2b13783d2187947fc7ce57dd77265a98743 2cdf0d2b127e08f36fc00b0e4e25cc1d38166b5a7b5106240668266b82437899 00000000000000000205d706d8420ff11aa8eff70eb6132c5cf601d846db2da3 +395500 0000000000000000007cd66606ceff31a69c1e3b49b5a4e3527f5f9f24a2248e 582d2dc06f3e3d450e9ddcf4b7fd2251d70569ab005831185bc80097c4c8c329 0000000000000000059bfb51974888c2f8f21f9fc7383f5dcd2774cccc5cc82f +395600 0000000000000000018bd2adf8a2a401e0251ad895f81cb6e0199876cdd40d4c 9b8769b65d1f953b8954ba49c0e1fc4b824e7a33ce035be36557e34c0ec9e3e0 000000000000000007bbdd8caffd7cad895478cf23ad364f5115244895ec0ce4 +395700 0000000000000000006f774482d6570d260612850f880b0f17478d990cebab2f 4b9edd1e16af9193b41cfa44547a8cadaecd27bb723224232250cd03862b0942 0000000000000000031b010df4c8791e8a9418f5c81caf6b35065cd6ab2e5ced +395800 0000000000000000009d85667f54989a5eecbe3fd9a4933d45aa3887397bbba6 17de4ba2356fce13af10915efb646bd91e4feb8623b0dd3a8324f6c3bae94349 0000000000000000063a1dc31a836524bd045729da8702717ec9d2f3a8281c42 +395900 000000000000000007acfcfbccf4ef2b3f8486133416add1578de5e6bfcc9713 a837df0c661587b7669bcc14a60062d8246a6fa77b9dccbbc88ff6344cc1dc7c 000000000000000004b132ef81f4073e92697c613104d86c90967750ce668aab +396000 0000000000000000079226c668cd1db713fb78ffc127b422e12b47baf205b478 b7cfd1cd1e5fb75128a47e6228562e3e38107f2e9a8231fb26cc863131e29692 000000000000000008e53dbc34ec365608efc9592fd982d616a9ef5258c72483 +396100 00000000000000000563cab5df4a98a9179936dc7519b7dde78fe95649220258 42cc0933417651ea1668bb041bf8dc438b470010c31058d2282facf9206f9b9b 000000000000000000ae94c088805e57c091635051333eba400abb7ce4f4d6ef +396200 000000000000000007d031d83d45a1e66e848b7ed4c25aba50dc4ce945d6e1d0 c710b49250dc70884bb676aab61505fe74441a05864b3c965438e67d6387f3f1 000000000000000004dc7b05c27d6d0b24e5d045c7595821d3b7c13623ce81d8 +396300 000000000000000001678c7f101174ed86a17ae6e6df0f64073b1e2122deba3d ece35c30906d4c364d342fa6df85f432263e446a750b469b58cd42dcfa45f52f 000000000000000007bad155feb0664916d971117027a05fc7b93d1b8ef26e8d +396400 00000000000000000818e993de849b5bf5f7b9d336f89f87c97821ec925498d3 d028ee0ce779062a645db8ee922feda53f81a380f81621c85b8b2542ca8725a4 000000000000000008c7763303e79f704ba588f5a3cad3a17099acc048234057 +396500 0000000000000000072b32721c1b7d16b834ea882ac856f1669479d69f4bfe8a c58cefc2fc0063050d38c3e6a17a12cc5baa007cab5a034207f29e0c76aff5d8 0000000000000000052b3e2ce3c30f8c41c562a96fd78a00e60b2151f08bf4ae +396600 000000000000000003374da31bd71501c21df461341815493058f4fe82f31cef d539728dae80deb46fa58b925b83b7c194e370961dd7a3bda5951aa916d7088f 00000000000000000342a5e221123da112f337f0aa3e2c02c578e90f88b60d3f +396700 000000000000000001d53e7cd272adfe2425a09fa47cd7f8d9f02324777bda8d b388f65410c4ca6ebc08a423471516d0eafb7c9b8ed25dd2e3e9e573cc38aa11 00000000000000000539ee34f10bf9f35d154897a1a995c2a5121d7adf20c752 +396800 000000000000000002df6ecf4ec0dec14ca24e303ac36c9bad4db12631b942bd c6a06ec74c8bdf5301d515306c33a0382bf309e2ecd9696ee449ce65b184c4ae 00000000000000000711a9829e87ba8ea548f1793950893043a5dc56893dc1dc +396900 000000000000000007426fe22dc7ef0e2b72f57aa1d1c6578b1b326603ab6350 0cb372711680bf97626a87f0a726cfdf82fb582c1c4d38b0eeb0cee99da5079c 000000000000000003c81a6272359e98adde6645ba6b0018353e317e0267f8ed +397000 000000000000000007f009e95a2d20f5d007bf79ea3a1ac24cbb7747dfe5f216 bf5ac722e82c61c190ae3255ee24454da3161ff009cee6b79994770ef7ea7ad4 000000000000000000960d82b8087044a1749c1aa248b006941df19eb02c5d90 +397100 000000000000000008783f885a1314f0ca5284e7761164347efc3a9287828455 32512bde06b0e1ac5e2b19eb1920ccca25d012dcea423e94f2458ab55af9321b 0000000000000000077f6e8a8e1a413a864040508c956b40d58b51e83778611e +397200 00000000000000000174f17a186cac07a363477e9ae795ad052e77a55e8d172d 45849f649d1c6a039d9290646976b348144105389b8e387e5b236edac5489ec1 0000000000000000032d4c0b1dae00735497564bddfbff5983d5f9782ec7e239 +397300 00000000000000000151b3c44541e949a2d8890b5b1e3333bb59489a5dedc507 ffebb3a6a40a3aebc981cf91ba018bbe935e27090dd89536867b772b37ba08ab 0000000000000000005e297980dcc1fead6ab43bc5d764b7b7327504d0cca8ac +397400 000000000000000005f50f0859e328e66e0da197c4adcb9a2c9bc4325eaf9169 bf835fd30258aa6a3b26923aaef4ac6148a4cf3ab5753e85c98eaff1d1759d95 00000000000000000660bd4e4b4a7ea497d485b2ef18b68bd40ac4682fb457df +397500 000000000000000000acafe1894685905465988539e835dc8b0c905d65efde3e 49de00c21d8bb4e50883a2288c54c700d22b2be1a99a25f6e16a924156507dea 000000000000000005fd9d7180ab515d3472e8ae454a1329ff5699c072312694 +397600 000000000000000000d7726d1fd57c78f47c19eaea8dff16f1b9ec1ddb641bad 5dcc4379e96e1d20cfe6ade7719a5eb2edfd60ab13bc384812de2a2da2550dab 00000000000000000702bed715b56fef6c77477fb8f30e84067ca79d1a509350 +397700 0000000000000000046710cdc74fb1746853676719cbe1f308f52d5b3a0e4888 01fe9d66cbd0a54a4fe0ef75a59f15260204c3c14ccf2b8d804552d5dd43b222 000000000000000003b2f71187fe3a9b0cf99febd5fa00f5690b8ebe93d7d1b2 +397800 000000000000000006042c48cb134a97f072394184b9b7bea9d79321b38262ce d526c719fe68bdd2c398f3286bd9a7aa45a8172df81313acc68aae8b705df59c 0000000000000000017c5335ba656e4d238cb30d4867b867b125c3a5b45c3895 +397900 00000000000000000235e1fa723f8a56f3e710b3fccf75a934f7083db54c19e0 ad84ac4b3bb7699ad93b40a46ec8bfcb7a243bd890df5785777d007bcbdfe236 0000000000000000077feb5dee2b2fe2486aa3e3651bc942be12d9e1b603805c +398000 000000000000000001c6bd9d2dbccc3f16ddb534119de0aeb7d0a8c87f78e001 c84788134e2e84b5a34e7cc92cf741284f9533748f06f8535e31c8eceff9b8ab 0000000000000000029b38bdf2fb2b7ab210931ef90b0886f09d7000f54ee23d +398100 0000000000000000004beea9a4300bb42e76b71fa2f46ab42fe9ecf77245af4a 7807511eb0092067bc856d24c588244e956c4ad61ae14b322a926b89b426994e 000000000000000006d7c67df3e906d12c1ab67385666db6838baae70a1c10d0 +398200 0000000000000000050e84e44f65b0cee858dae344577ccb296875a7d3673d0e 1a9e81a85802e8ad240123fc9552705ad4d1675098008420f413f8059b2b0eae 0000000000000000009e968b244ed9a899d7c429f7fa234816ad2ed2da525371 +398300 000000000000000004a0c6016b79a785a4068be962b4ee538af76614c4164c42 262b7dd99799a4c41792a46e945c359028d5aa25c086b03e23f8303a05a8a4ed 000000000000000004b3668a1d1e31f6da9e0083cde6e9d5bd5ce5fc9d1b2eff +398400 00000000000000000067c815c29d3abe54d91d8195038dc50b131343aa972eef 6e4aa889cebd08d50ce5090cd6f06bc21e22ec3ceae1a6e75c1ef9da771521b6 00000000000000000540e66b89b76f41d2dc8b0b7d462238937ea15b95e6b61f +398500 000000000000000003028f7d471cc67439cb50c9bfccc36cfed3d3d2bc2f0c53 efc81b159b486675818f11585bb864582146f0cb0838c1f29f156d8cd6cd7cf4 00000000000000000758ee4405c4951416a8aa94b764f9b39af4a5a7a8fa9f5d +398600 0000000000000000007c6f4b423e53345f75666bcc6a6dc14442659b7cc24a87 1f6e23862223b28fc115bf456e3ae3110b9ae4e4d838ffd78d974cac5752f7e8 0000000000000000009a26e6bbd2db4c9d98bbe4fdc593e10d877d403a4e55b3 +398700 000000000000000005063d3224786fb139d8ce2121d65faa748a3fd84d174552 229a2b315f4f4af6ebd3260737512ec8c2f2a0bdb2d4eb675432791e6b1d993b 00000000000000000180feaf10b6516ce517e14167f2e76675cac420433399f8 +398800 0000000000000000073bee35d130f215bf7f28fc894db7334afdda20b99b62be 9ceaf205010f1aefc4901ac4211085f464ec4c1e76087b1a1db4715331335f87 000000000000000001a64f4984ce43d1f7fc4767d1fb285cbbed02584cc1b0cb +398900 000000000000000004d46b16504e220bf3cfea83f3ca9ddcedd6345c9ab394f7 fd3303f08121e9bb0a64dd7f02cfb3fb655664ed03833a3b8a7ed40843d36b20 000000000000000000d2d9b9c475ed4f95edec8c0cb210f0fc932105c3507994 +399000 000000000000000003d2548d4c19a5e91a8762c764f3195a7cb4be189bb1da48 3a81ca907a32c3c03a009cc2eb1a5e60c18579e7bdb2dd040fa2fe9aa70268b8 0000000000000000013090d3331a82702b0caf537e7621f2b9190aca5572fa48 +399100 000000000000000007901ba96cd7acfe0aca2e655921a99d4db213c453dc37df 7e0cfae714cef15dd387cf66811fe31a28a657f82c48e30eb1fed7023c6460d9 000000000000000001eeb97ca833851d7e84ddf27a737949c70fcd32732de603 +399200 000000000000000002a16e42e82c833324c8e8cfd481269c3421a45ffa6a8f17 118551ef2edd3290620d436e807adc4c9500b739e95e81ed2a54477f4e9f8623 00000000000000000017e76e8bdb74098a20abbe4a98d3e547b882aa49e7d338 +399300 00000000000000000626e2ffea366836aeda077903d8a48c3b8ac69c5310fe6b ef1f65802bb0edbc772611b39f6be412fd4ea89484b8b8e364f5eafd2105cd5c 000000000000000003fa0d657f29f7281f376f3001ad1caaefb6505cdc44f4b4 +399400 000000000000000006ab0447ee4245c70c7a320a8fd3b0180fef636f64bb2d0f 13080e775a517a1ea09c6a98690ce456355f8cb77852957ae0305f0001d11d1a 0000000000000000069a13d07ab6d03b4db1b278d8ffcbd00b7d3f825e6a8d5d +399500 0000000000000000004f7776c3cc0e2f3c399f0b9bc3e53e9eab356c5317ef76 4cd61b2f0b85e1524369370bb07448bdce7e5864179d7c084b701fd224978e53 000000000000000006a4b66294ee0998fe673967c34de58f07516dd778cdc1f8 +399600 000000000000000003f3c17ae3d981bedef1a3e4c8ab9e6072cdea1797996d65 2e57d20528c1009203e8669c6ccabb1263ae45ce03d282abf7debda0f312a9f1 000000000000000005d1acafc19e0e29c969160c59f9f30dfb5fe8edf96c68fa +399700 00000000000000000144d4661488870e99ea4fffa243535a74d218a43d28f9dc df051ee0036be8fb34f6d0800a6af022f98d047108f309fa9ef2192922f3f619 000000000000000003e5d813f9f6668d1ffdced087a70b96d0e8bc9181420a3a +399800 000000000000000001e44729e8855117d069601b328e73c9629a6780366abe77 4d45220c3df557758e8266b6c40e14d82af93c93422c5e499d7b61a190468d66 0000000000000000007f2feaffab12b86dcb02c43afd95a8f9f344533bd02283 +399900 000000000000000003863fc0e1f681ee116bc1969d83c6fd79b7236f461b3dc8 ad52fe4a24df642bc1c28b86ac25b20b32c219426747ecac3efdb810083855f6 000000000000000002327e752e9ebb2e25936753bb8e1a9beb6424d7f6d2ba56 +400000 000000000000000004ec466ce4732fe6f1ed1cddc2ed4b328fff5224276e3f6f a5592bd73149395e4a5b9703798757c1e3d82c2ced60b7bf1757b8fbf4bb495c 000000000000000005421b1b2ee6d06d037557d7f5ec96852542413cfed40c22 +400100 0000000000000000025f17300a817ecfa9f6fd8849f63ff9faf97038d8ebe086 a5eb72b606ec45177ffe12430f9c177d3b13136e4d9b9df4680826ff97fc272e 000000000000000001c69febd1d7abf444a30b3a6fa240a7a9aae67a096556d5 +400200 000000000000000004e9b3d83a087b7f97c0b9b3c3456b03ac6b6745853440d0 6bc78a44541f7815ac57a35b172c09048d98c677bc283df2e9c5661793223fec 0000000000000000016cb64a43278f2df9361c8fbc1285fed1dfbfc52df6e155 +400300 000000000000000003ce725c6b617db3efb6132cc3fb1776cad5dfddc6b16a27 d1f0b0b4fc74bd95d76a3cd14ed0b62dc9e008d9f9f158dd99191fbef6437610 000000000000000004e137194dc4369e4e963b53a091cc6d51f417ce3bc7c04d +400400 0000000000000000060ab6bf830feb63ffbdffcd9d860e720652ea490aefcfa4 9ba91f831bceceb93f5551a5e42b0f88f7bb1339d98ed4f69e85a5cdc25a0ab1 000000000000000004975abefb2faeec98fbf08bffcf7fd3a673f7ca0be35c22 +400500 000000000000000002c0ec50cc0c04c95f26bbc0e1dfaa0cb74e708d723fa4bc ed411dc4c6559fbaf3d06cd776d234a81dd04aa0f3be6dcd78d49bb8ee9c84b2 0000000000000000015c2ed3b3f434003ca37a557b757d4205c44fd45c3f84d1 +400600 00000000000000000571737c08fc16940e49b16ca837fdc7da3985f27bc12d05 d23fc2315d1637b611bdab3dce2de428c14cfc8cd477a20fbebb705b1bac8d9a 0000000000000000027d40b4b283dec051885a863b78c67e9b0c90ebb84479f0 +400700 0000000000000000044f8cbc7126b43bb1615f34d185f603b89d96bf782da7cf adf40830f2339b660617d9e384efdc39e9451b90fc84b02d2b5d206e5c28d5f8 000000000000000005a0a69eb0921be38759d12857bff954064f5582d7cdb06c +400800 0000000000000000060009ac0b82e6ed9bc42faae1c6ef8a4ebd4a3cf77643bc d090a618f00e7a8397a7f9da9f6b85de13ee2952c07d86a18ee9fcb49891bc9d 000000000000000004ed7c9576f04c112161f93bd6d88d2143e6dd505fb26c95 +400900 000000000000000000cb5f1189b765dbd1640002b32719e86309648b849cfc5e 49d6cada5008fb69047c16b0782ba652036350871fd97df3f0f59c9dd3170f31 000000000000000002d2673b362d9e84ca18c7bd9fc5d40752c4877c872c1cda +401000 000000000000000000af172b1ca0cdbcfb849e73167080a1379250d4c5904738 fdcc43180f2bbc324dbd513b275b6d3a7c29fa7f854c2a4955c56576cfdfe36b 000000000000000002be9f83df4f97ae4bb6206d0fa8a8a7ed48776786ffc1d8 +401100 0000000000000000057e5c7d461cd4ff563e8a4e8071df28122231da20c2e0ae c11391337e2e44356b1ce8bc12324dd1f088b0ad84a9d4d9281b795bdda5487d 000000000000000002c27eadc284b9d733e940a06973648d43fc6c3b2e7224df +401200 000000000000000000cbfe490bf50dd8130537e9b2af28ee12d112f4472a500b 67e79204b07187d20bdc43cbd4e94dec922d9ade6f6ececffc93ce8468fff377 000000000000000005a00650a8077baf35480cc8bb2d7b097f0a739b18949420 +401300 000000000000000003d0306658dfd02d7c78cdc54d076e4af282f1403887f19f 242200ea9e0f36998f6cf0a8eb3d28c0e8a115aba1cea3855533c96097c1f10a 0000000000000000052af6aa1ee11e3b610cc1cdce734d74d371f80fdd963492 +401400 0000000000000000035ecc92649b769e6fccdf935710abedfd80c6b0230bfedb 4a9d3fd646702c9f37027683bdc2d8753e14ecb0f05089e40f7d66cacaed3131 000000000000000006313f4ab2d63341e66b1dbf34db93985eb7887c5b4c531a +401500 000000000000000006319cddc3aa4fb6d54d38da793e77e3c8ea19ab415198b4 6da8ad098c447f1bfef2b27cfd669cd69af9ade4ea26a19c3ca31eac0cd66cdb 0000000000000000026302e705b3d31c7d310052459477ccd3c0f499758c6a7f +401600 000000000000000005f6b549feed836f8250c597712bbd51673894671d8f9455 9016b9a96981cb9094201c68cb7d595e17ec7a4a332c16a7c44318b317e85c5e 000000000000000000c817e55982d82a900cd563e5747f713e90cc2170240355 +401700 0000000000000000019c6f7f906702a7914cc675bcf3def740d95f7d7cac70b2 60a73ada5414ebbc9640e3591058f8b762925aceab0777da58631b1bb5b2610d 000000000000000001acf759293af9ade7b6b3934f8f1445296c59e92c138c3d +401800 000000000000000002ca40667178c3071526ebfdf0dc3ce543408432051759e2 8213cdd92597d7bf57b7475db4173f9a23eccc22e14daf52fe6a897b06230ef5 0000000000000000028195c0a80ee9af75aa73bc9d556db7c499c6c28bccfd47 +401900 000000000000000003980b375024e3f69c78643a9759d87420b9a0569ed81dc8 b645886c3d8ba52f7ce1e1bb1ec1f1f40e2948ff90f5b993d16d76b2401436c9 000000000000000001653a1ce236a5fcbe72ab167276086e83ce62e00acefe85 +402000 0000000000000000001b7da4ed218caf465ca9bb08a33712e8fc3fa508e6264c adfc41f3a460c6b29afc78775be8e81bda77a10bcc4e6617c269ee5d0b20877c 000000000000000006e4cba5d6971fe5dd734dc68e158bf0a6f4d78c11d0e91f +402100 00000000000000000232fda0c0818e975b27b9c1c42668b148eec084b337d715 93089756833fbd92bb0c99c37c92e8c4f3df00781062af4f5607573a3874ba69 000000000000000001cf6f7a9054154a1e4ab88027f449b830181a475f4c7aa4 +402200 00000000000000000563cb0f114b8eaeb68c6e211458eb3138b3e2724b5312b6 f6730a6609d15bc8040457ff5760092c51262ebdf539cf8ec684e87f7a29c088 0000000000000000054b247eeb06a169f9bf6d80fc0e1675e434f6fd3dc748fd +402300 00000000000000000498dc85afcd853717920c7462f7218715e7a62e3502f1b2 d1b6681a95949f063e13e417eddf45946bad14fd1bfa50c984994ae4495dc830 000000000000000000ae2c80adeafa7d684c98577bb644b03be595a45c18efc0 +402400 00000000000000000619fa401c577afe0ef4894d144eb5dfffdd890e718cb2f5 abfe195bd59c8f22f3ee9e9951819f077fb9d22ac77600974fce3ee9db27569c 000000000000000002ca5a4528118f0ee8b9e11c08fac99998749f9cfa39f9ec +402500 000000000000000004d94e2c240da10951be8641c2fdc4402007ca3beaf073b0 acd8ad50e13d189bdd59e85b0b97c5e95a08308efee9304d1b4e30730571370e 000000000000000004b3785d948ee5d3d058817d9ae120a3474c1d0b3fbf251c +402600 000000000000000000a3c19e33138d3c6af905b22595b9f4e6a3f2fa26a35b05 cbbc3f0636f441b63e1cc9ff906602b18fd21b6c8964eb856a881409982d2122 0000000000000000029ad50e63681687fc310b1e9749b7ea8fc5515fabee41de +402700 000000000000000005319e41d2fa12e53a7b17b4a778bd632bf7f8ce28f7f2b0 9248fbd475f650d0fd4c7276fed875debe223e68090b10c1ea284f3e4fd5bb12 000000000000000002be4cec9571d9aee1694bd2005b6f99dcac8c8f94c38efc +402800 000000000000000000125cb5c4948ed7430ef94b05533cb64b316fe969467139 900921b74f4a9229bb3fd519a538be1c8de161c110cf6790c0c104e62c5d38fe 000000000000000003d587a104e2c9557d4166e499a6aee3a3852a220d2d4e13 +402900 0000000000000000019e332601b716d5a84496336eb3429f3124dab9e04bed6c a093ef3aaeb5899da882741132d65ef558dc1c95c9e26d766aff725eb9e0ba23 0000000000000000039166d5ae0ebd0371cf5d8779ec01fae3a7f2ed3f349878 +403000 000000000000000002b3b820d8d9af0a81a22fce882f5e055448f18dcc4975fd 722302f332e3402be60e91bde85a774db85b08ff3ca24232d7e0e2c374b02dd6 00000000000000000005ba8ee291ee724d1fe9065924bd981eb0d5ea31a9367e +403100 000000000000000004d0c10fa0479e1f94890aa9967cccfeee1cd45e26baeab3 4dc04ba2a815d79add886e9ede05e31fe0f15527e152c603883e5f5ea5edede1 000000000000000003e66d02174e14d8a9676a5bfdcb2b52136063e7d7de111b +403200 000000000000000000c4272a5c68b4f55e5af734e88ceab09abf73e9ac3b6d01 1d221f506977ca7f9fe5f83136a96b641c34df0fe91dffb478939a5ea3b12e78 00000000000000000595f9c1161a9e66bb8bb43dc3ca30c61c9fb965fb39e3f4 +403300 0000000000000000042eef1dbf4f5cc4f75daf8103333fae7e80bc440848ac48 f5c78fc3578729369002b1d41fb5e41839e4953e838523154edf92e22c5f1926 0000000000000000052033be3a79adeb4fb6eaa05aee3855c2b9af40e79fc991 +403400 000000000000000002b6d17601e3b5e54f729e1763fee1f878e61389fdfc3aae 15553749402f24e00c776f482cf3b26ea4395e9b6040fa63579a2de4c390e6da 0000000000000000030397136c15c2edea0aaec57a9021bec7ddad67e5137e64 +403500 0000000000000000069ef9c66078b93cb3435ef702a83cfc51231a108dde6d9f b4beb0bfcaa7f3435fd2cdd02ce48e70ad99b0f29c6e1132a2d13ca074ebf538 0000000000000000019ac888846b43aba7b406261fc0625209e85a53c2ea5301 +403600 0000000000000000036f35db66595fc8f35d96bb1bbe83f143c8975638607e45 60cbab2eca14bbef255ef8e7e260e92e6e42574c5660c61c520b1a006d68258f 0000000000000000007464248eab73226f9fbde00db8f49990fbac4597b198a0 +403700 000000000000000005dfca48a26c8ddcb5606c9f21d741f3abb6310df5db975f 6789260cb68e61695d15bb8870cbd18e2de4bffc36e201c457ad5e7da7a40b53 000000000000000005e45e2c4799d3097352b5b68ef0051b0da8d8f633955296 +403800 000000000000000003bf38cb78eb5b624f51d826eac4b9df581866da91e63ce6 87161409fe1ddd567926cf4506911439a7ceb66a57e10a94ef9a69a9a2515db4 000000000000000006649229a42dbc0c74ee75d92ab2be30b6c19115dfaacd7e +403900 000000000000000001e5e0c849184c832968f220456731820107acde3c91ed6a f66efa2f5b0766609153a301c781bfd6ff13eda6a6ae7e8e61991bde8545cbbf 000000000000000002f5b6d90cff1f4083271f5dfc607c72cc99b80355de01d3 +404000 000000000000000004f9f0d6320d54c1f108130998e5bfb911f521ddf34da82c e67ae0c8b0549a2ba4b88e5dd4d6708214b7e384992a50136e10d5799378abf4 000000000000000001da1eeb6fa89a81b7534309e3dafa425db27e4e4e3bb972 +404100 000000000000000001f2d6471dfc25ad93f68c677f7a22bdae73899e0258236a 91262074adc881bebef31662b6da000a96ada1f2c9543022c95a9f604faf7c1a 00000000000000000683889b59994864c7805fc20588ca9abb3b9429967062a8 +404200 000000000000000000c83bf7180facd085432b04d648993bece6531e231d0b84 117e574b4d29447dd943e92d4189f2de1af8af1d1899bd00940e0295189fef78 000000000000000000a1a423da10ec7d26fcd615caf7ee9c4c444188958b44e6 +404300 0000000000000000039212b8f7a4c40a8ff3e7db990cb24ab7d324562383d527 bfe15506547136143c5e3413c1c698161e6d07183f2598e0d952fc4749ac0f66 0000000000000000041b75baa469b7df94e85ae7d058bccc269c6ea249385fdc +404400 00000000000000000645d9afbb8794e896998057aee3e743e516d50f2aa95ffb 4cc1401e0ed9b28996eadb2794c1dd2c8fbdcf06425806a6c17077845e5a1f4d 0000000000000000060bd1cce09f3e6f7af260621a5aa5384e7871c30f6acf36 +404500 000000000000000004e0e47c250d5b2e3d5b317db4813f26e4e866e55fef1539 21330437acefe4c636355a638aca30bf2239982d902005809853cd9900abfb25 0000000000000000012d9b96babc3338d449eddfc65f54faf20278453ee46eab +404600 0000000000000000063cf4781d5848ae24c5a04c6c922288ead592b4a7196c6c 421735c660ddf8ab5e9a58c6964d76671035fa6130c4d93b1d655cf33754ac3d 000000000000000000b5ca3b88d1d1ef4b1d8e30e039bdaaaa49f23786836d15 +404700 0000000000000000009fc7ee2a305d85f6653e5fee2aed2ae44cd6c63608a036 6e64ffe2a6284b6b15aa49ae09ec504b8eb3396744bf3b4db4da374ad536e7c7 0000000000000000005f9d7d6842b5649572a9fa788c68ec2822ff5273b8fc62 +404800 000000000000000006682e1c70e9ab9c17ab743dfdfa95cbc45bb17972128409 b85956ca746feeeb9f5c7e6d5629d3295aef081f475c1ae568d17343d864ec73 000000000000000002ffee8628fc657435238042d5e4faeaf514775df4511082 +404900 0000000000000000009bea5c4ce0856a8da0cc30bd450bd3f2c2a1bc630f4637 a3c4df6b6ac1b1672f2ba50317fcf5a49159088aea8e3a87c51bf390b18a0cac 00000000000000000344c9b3f6bb77300fa36a186ad5a7431ed13ac3cd5478b0 +405000 0000000000000000064964d6c6fc399a7829a6d78fbdc2188686ed221f130c37 0b3d55b6daac822622fed912598611c95bf7f4d9da8dee477d927412de958c8c 0000000000000000005d360415c32b1fd6512b536848e68e04f47321d480a9f4 +405100 000000000000000001d85ebf98ba6d2b963125881e1cd2d5ffba85551f678292 d055d9a05080455bf40589f995647aae26fa41779a56bf68ad6a6dd837aaba9a 000000000000000001224cd547cfcc5074cc457454660fcf5d580b60133b7041 +405200 000000000000000004d92f38374c8a64daa0a6b5b268746bc91a92a423c4b799 8040e21bf957bfc69d7977a4d228b8ae076463e78e6d862bf5283137a41e028e 00000000000000000029667de92249c7863813e6f159f67082c8e8ea92f9bb38 +405300 0000000000000000053c702c195cf72fb1ce6c32544c8cfdb2a98d341b0f1b7d bd2db7ddf4a672854ff4b6a047b78fe17c25c7ef230bc144919bc9b029661443 000000000000000004139a31a07bfca389b2589797f59d2d781a9991c1e145e0 +405400 0000000000000000013374642ca3f0c834e57104e7e05eced84e76573a08656a f134dd52e3083f39fe911c9c80c39b3de602808dc13bd9fae9e0bdb5cb75402e 000000000000000003b77a24efda527924d989a71cb220edcd9c173ce78f43b0 +405500 00000000000000000342fa93777ee34bf317948046e90592d7104196d4896b84 f34cf6994e35744a629ca3620053ab37d2edf4d27aa737f8975070237c3b8dd5 000000000000000004c2b0202c47e0e975ec5cc0efd96a3a4f2b655e75dd7f5f +405600 00000000000000000591da86d76cc6d57deff7bdd6c6b9461329ac5127cb552a d6f0f7903112df91fe52175ca0130ab6920616e76e88f7e892e2d695d6d86be3 0000000000000000043de566a870e021aa533a67a3b116a6487041e429d3d424 +405700 0000000000000000031473349cbd4dce9b67558613887fbd3e1c76f3ffd1638b e73b760563dc17ac27f9fa81aa864b9c2b3c900dab24449b6fffd9e9ab9fe481 0000000000000000054b6074dcb66c4a7619c2bbff7d086c100db068576b5d0d +405800 00000000000000000440146ccc82547c192f667f5ecbf552053c18d74e8dd290 87f0153e003c97fb375d5055a7cb9cd9adba4a55db315349778fd3c4df72ad4b 00000000000000000028888e6d107f7afd8f091bd6ea3acbac77e7948528013e +405900 000000000000000003532ea091a23bd968975e2ad58b5e057ce5216d1e0c3acb 45ec8ef807aae2f289bef7d25e3e2e2d3154f76d2cda23195bdc661e68d58483 000000000000000000ee04650c0ea9731ebe6646ee58ad027a315fa470028142 +406000 000000000000000003b3efcefc5eaaef3b21671228233be52db1a080022462c1 1bd45fb402edd58fab2b37a350634138fb4249ce07508e2b257f022ed509ff21 0000000000000000031c610eb5a810af32b531569c5fe681d0c2ddb7ae56be80 +406100 000000000000000002762fd3c2d76e74973ad5a50fdfd9d38057c7edf6d56f35 ddeb2348de4b7b9545c7a00b61fe5d005dd3d450d5c7611dfb7ca6715b907b37 000000000000000005f66bd1187afb2693f319c231242e7b2f81a15282933715 +406200 0000000000000000055b1f46e52d24ae23fd855c09643965462c12a1f2f148f4 159d25abfe9ca9b1cc045cacb9735963627fbc69208ed2d55d9ce6fe841c85d8 0000000000000000031392788a63d7bf32e9218dc50db43344da4dfd6cbebfba +406300 000000000000000001f3b9abbf0000ae26af26315dc072e8b70f25ba69ba76c0 8a5a85f955b46c7537ce3acb809f9d597c9795157003a8b0eb9b2b131a25e4b8 000000000000000004dc16eafc2cc5769cc1e0ffb9d807b8885fec2f61774be6 +406400 000000000000000005f781d7166a4d5d512ec49fc76ac68ca78f57da47d8757c 0c1e4c5213ef8ca7317d841ba9d35877a1b91ff3f08a7244d24bd0094b1a6770 0000000000000000066fc5b5bd85699c380f727b69b07f63810a8b709f0c2eda +406500 000000000000000001fafe564519a47fbd4e6265801652ad2f85b02c10c62320 ed10f6602b674e3b1f70a38ee17d9dd2e0d4e3b549266404dc8d2719ad27bee5 000000000000000000592747f966ae1f5b6fe07be3bf2fa70bc8558313c096e6 +406600 00000000000000000112fc74b4b2289ef89274cd1aab590ad795f4c1871ef8be 887eb1ec82e99eece2103f6bebc36a18b57d95d5bad4d3632d8ab79f5e64ccd2 00000000000000000299b3c9cd20b3815cd3b6d20e954b4e48fb62d940456018 +406700 000000000000000005b8d24675e101734db88c838a2383bf97e1dfdbe61e3bd3 02e4e1d5c7726151bc7e38001e778702d69dd73db8ed728e93ad0fa596ae4007 000000000000000002f39ede9c8eed91a98bacc746f7ccd7dd280b3d28d58b0a +406800 000000000000000001c31935b6b49fbfe1c44cbaa31a7875d59a22b09b99d380 a4192c2fa010c082c88e7c3e4c0542d2382a7595f9ab34064ccd0350185b01ab 0000000000000000049eb7c3fbd56b07f4b4b7d0e5178eae578f7448cd65fb6a +406900 0000000000000000063dfc7311f4d65bd87f80751a89db494258f789f4efc7f7 f2192d546268d1bc6170d2e3556386919531c2ee7489a6ce431ae45c3a3f3c6d 0000000000000000002018e23dfb11f919da962fb4b2a4d6ed1731a2e983a7c8 +407000 000000000000000001e2e3256cc81bf2c1c3e1d9230b1124c5cfd411adf03be2 927afbc043404b46b8c1da090b558b34f8ad449d5681c3780a4095e0d641a1a2 00000000000000000073ccf03e21aa872e8d76ab9fcc6f46b2386ab1ebf8adc4 +407100 000000000000000005d55d3e2d8c44b8f14bf60c65886d0ffbc189c1a0c55332 b7f0c12cdb2edbf06f5eaa1b12d5dda3ab7a9c783502ec9ced6533a51bad16d2 0000000000000000043cfc9dffd1922aae42cbea67d160ece6639323185fcd3d +407200 00000000000000000652e9a226770c663b0870997758cffd6e2a778671cacb1d 4325b7d37bdddc13e0f0fc316c0330d3b29aa368960bc796e8a73bfc322fc9bd 000000000000000004dc5d69fa9d2e6ed83db0b5a195f0917db6441dfdf36066 +407300 00000000000000000274792bd3ecb0f646893b05e00320301a8013880139cf27 5f0bccc99bdf7b43d3a15c440bb00599870325470c82dcb587f4988b59a1383c 00000000000000000204a39a801a2642640ad58c6c82f69360e265bc8380ba83 +407400 000000000000000003f5d63b56d616b41dc526a354f28a6b689e149868616e95 b34c1bda8bb951fdd7b85101be1bf1cc0700d174315c9c9768b6c444dcf8c862 000000000000000001fe96519739699f3df6d9a841c8b4e15ee9688bba23e9fc +407500 0000000000000000055b3d044ece632235dd9d975be4133a6f2e194d3f572f00 09c23595a1ccbe4400e1e94bc3e63c9bbabf001fcec45aba0f4e7515d951d96d 0000000000000000003ebedbd09854c1be1199579002af35a6b76b4366c8d0c0 +407600 000000000000000005596414948cd80f262c0456573ca7633c89322061bfd50d 6ebcf25fc6431401c30c076185609028e9a122ac5c72fa2f3629609a3883ad8b 000000000000000001366ae059b1f7de11e24bc5404b1aaec2da24b6cda82764 +407700 000000000000000002825fab61bca52aab5a02513b265d7a738d950ce2d74394 f4e8ea4d1ffc1d5600dcff08d9bac3a46c83c73684c19f4535497b6c3e27886b 00000000000000000208980f05cd6228164ad03db986fc165d016d56b2ca33d2 +407800 000000000000000003768354e0ddd921ffee3b69de0dca60eed5594856f4fe96 6991a16a64366b87f14a1a7590eb6885b346317802a09478f1e443756453a054 000000000000000004297a61fc1814e557896b19319e2b8433bf0c26b977fd76 +407900 00000000000000000391868de3381e4bf13590b46d18bf9d9d1dbc6dca8a295c 60726d2c82b7c105abedf25b19ab0337d165a006f6cc4353203f60b28af77d0e 0000000000000000029abed9bee058b014c1a95c0cf8342e70f5f93397d97a6b +408000 000000000000000003cc3d3e5b5d9b577b83c2b8d6f4257398c8f4aa8b2be649 a28d08ef886481ca3d6c26cf7ce06a6db3fba2f31b9f90722eaa7e95ca359599 000000000000000004f62eeb625ddf5604eb9c3d9e5f214b643d23be2b83a99c +408100 0000000000000000000376f43c3c0517a01ca81d93dab6a853da88677023c4eb 6742f3b6684a5f827991610c6be8a8b283ff27f5ed9472c0eee536eadb36552d 000000000000000005a675d704791500bd024e9c0731d2379189524d396a0b13 +408200 0000000000000000045c3bd005dbe9a1054e5e27b2384e57b260cd51bc2fdba9 7014ae8c61120ac0415e5d05d392c6a171ec0e79d420f19c7569fc8fdebc6449 00000000000000000261ff0bd2b81876edf0c9502d1b7a1490b527ab92ba4c98 +408300 0000000000000000059aeff71176edfcbf1f5663bdd31688f88f3b7309d01e2b 18ddefc50588759a372af4070e34227ce821550e117cde9bad533ec331195dfd 0000000000000000017a131128a73f65bb13e78b8927ba2d35e0302a1d1dd6d7 +408400 000000000000000005373782c6ba9f00ee8f4da1377f8bcf6be0d56bffcad252 94a93a23c401884cfd5b55f4d347ea9031c82ebd09857a54b547e8dcf07cd1c6 000000000000000000565145d69653f74c5b7033e13bd83e768eea59b764c5b7 +408500 000000000000000001abf6c7ec077c3a5123b2251d40afec01a7df9877367ff2 760e8c0b1c28a700eae2cb650ecf2083a0dbedee215ea36c6bfeb751846df8b0 00000000000000000179b25739ccaad22535a109f510143b14c59dd9d18e2758 +408600 000000000000000000511f446d35aff3b94b65fbf826ac98ef66bfd96ba3c249 04e78ba4744c771b7a3d76ec05a6f19ebb795806fe4ee7a2f4d928286b630cac 00000000000000000356cdb9474e83d72dcfe187c9195fcf04a99c1a17cadafb +408700 0000000000000000043c6ef372924d1420b3fab4edb86b029a91bb39818e0d94 a61b0ca1676f06f1f1aa45904a34e9eac73dcc794c1f5efc1674950005cc8db2 0000000000000000046dc7be8de5731855763830259026ec6f70a429b2549800 +408800 000000000000000000905d2b3c21394dbedbd4b3f96b9e065c5387c6272c72c0 350aad509452a0ce2a7b2382625aea15b11d126f0659e2935ef6d49ed90a6f7a 0000000000000000027e908f075d8673cd6d12f1ad249600cb61a0ca3e2451f1 +408900 000000000000000003d90ca4ff568b899aefc6401c310b00d17175323a2779a7 29ec6328596a428e63cf70bb7c3b8241fc4ed79a81f911a52566fc4093cc9096 00000000000000000064be94fdbc7b24469f884d6e4ef37dc15d2dcc1d5433e5 +409000 000000000000000001a99ad75d398311754aba654bff3111f3d3f2701ec8e6d8 05c705717b5492ae9dfd78eb7de302ecf58746442e39f875f203c417a0430361 000000000000000000bdb0bda5a935c13450ae7727770b8d8e6ef77f86744fca +409100 000000000000000002f25e59c6c7bcf64e46277d175cb4ca19486e62c7abc756 2e27bbaa8703776c626140cea30060108e7df37878162275954f46bd44e91cdb 0000000000000000016cab109a6424d6faf503e8f48302672b9176e60c28ad51 +409200 0000000000000000017997abbe8563a3ecb54c776d1e27189103c4c7f14f1b56 4317931858d0cc6fb262703c6483f091b788e17516dfe57aa1ca7c1d4010664e 0000000000000000050414dcf78d468e22ffa8167fdd9d467dc6c123365ce883 +409300 0000000000000000008b33dc9621301b8dff595dc145a6aa67c922e2aeea657e adce2a4e85135ac69cbe3c82ecbbba35850a998927826ed37f73379daa67d45f 000000000000000005f5b014a251bb11c630608e774828c7d9ea7bcb9cba2d26 +409400 000000000000000001accba77464aa1b6aa8b347d6a92e9de2cb863f1da3e7c3 9c1420dbf531c1c850750913d1b54fbb8e3f0e98182473a3d0fde5c84fa11104 0000000000000000062227fa72600cece8d3c30be2c75227ad4a469c1e98da0c +409500 000000000000000003da4c6b0a1d089b66a8ca5d1b75381bb7b9a13ae8f144cd 504217e4fb251a97a751f02990eaf30b2b2219e3c485caf6d27bca745b30dd3e 0000000000000000028be0eb3b177a95a40b8232b7edf066739eb90bb88f228c +409600 0000000000000000019c74c90f12b0e7ba203004bbc8e6ba1c49de9393f9b0df e4831ae3d166369dec60d4e5c07ceea02db0bbac5a55c3141f781bd202d511db 0000000000000000031c9207be2a5da4841e97babf1a1ff3b43cd070bd2ae142 +409700 000000000000000000f77a89fb68e5aa22a9119abe11d4d3c44e36f11d03a9aa 4b3fe0e716106be4e55510d8a1ed8d6133160176b43130a4fd91ef4d88de16d4 0000000000000000007ddb71f71965cd0e4c0dbbde8d2eb2a8a8f7cf04095c0e +409800 0000000000000000048f984d2fe73dcbd06833cbb6f34c85e69ba13f6a209dfa b6016e1eb9ab27289cb505279d2c3a394c13091ffdfa2ad6455250b6c90c74a3 000000000000000000dd40decd1ec6a3d79b5336715c1f5a69bf560c0f6c9c26 +409900 000000000000000002c827fe2456fcf7c4df445cfb380827510f64d0ea50c131 4505576463ed6c4b6cd0a15f2b8200ec50a70e5ac23b40f5929e9d99487268c6 0000000000000000042537104301204599b4859020b8ccbe30ff864afdf64dc3 +410000 0000000000000000060d7ea100ecb75c0a4dc482d05ff19ddaa8046b4b80a458 b2e513b94c5fa06e9ca457ea34cd22a9f8ac7407a17660d5508089d423c34ad1 0000000000000000031a8a4a11a1680a6c78193bd0e6af2d5ca006d6f2b07757 +410100 000000000000000002c3229ee95a88f16641bac84d8d2cd73ab42af436fce36b 6a7eccd5a7a5fbc7766c9bf79795234e815f844bc92d1c69e2d2c60687ee6215 000000000000000001f55939e31a286ba84aa68f5e3836845a0f69c749711050 +410200 000000000000000005ed69e59bd7ab2a870842e9f27f80019d21530ce74f411e e093ce0db0019b3e4c9bd9d4346e9332bf8b74885697b6ac70de4024e26418aa 000000000000000005ad3be003999a60b6aca2896753d6d4fdd6d63878030d8e +410300 000000000000000002df9b832fc8d5e0ba9df2859d704f7a442f564105334dba b23ecba2c1f4f6ffa488bd467dba7f295c753fd29717ac8e784398518e7ce7d5 000000000000000001030f2624ff2cb68fe8cca53b09f790a64e260e44b6dba5 +410400 00000000000000000470a32d40180041de9242174fde63e5cc1e011f10c650d1 05eb43c3d0db295819d7fc667921ec676a8fc1f9a68b365bcccca5a97f81ba4a 000000000000000003e90f884bfbbd7527127ca6e1924773dae8cf8a11007783 +410500 00000000000000000208f17bcea7376dedafb5a8e7a92a17bdb423b9f9005f22 cdacfe6ca9ae1b680ca8958552fa66b5ddffee0abdff5ef8afba9a4104902226 0000000000000000019744a0b16352dca8181605431af6f25dbe95f38403dca6 +410600 000000000000000000daae1c2661d3e7feff651a787b671775e80b5bd10b7c84 4b0bc92142dd8b5e125fc9487254faa5121045dc6da331d51b0ff6eb432f9849 000000000000000002ed8596f321cfe488a8c63e18501b44507001e74377957e +410700 000000000000000004fb23d2bc95e247aafa36b77a2f636c9d30b6074c03b6bb e1b8d56c7e76ebbbf7d2a2dbeb9e927ef54d8601f29a45ce98a0ff2a71cd8b57 000000000000000002c068237564302db0ee8fd20f80e083a91916daf6b44776 +410800 0000000000000000040b3dd4a75557b6c46a864e4e1be7af2bb361787e2166e5 22aa8ab6bb372cf6bcf757fda8d12c50f326611ce5a1f59c919aa32765cfd28a 000000000000000005b3bd057d127218ceb0f6c2c8ac10324d04772d48eb1e2d +410900 000000000000000003f00b2ff11e9ad31f0e5cc3ae83e07ef3d380b7407c7425 f4762b8fc60cbb39f5404a977b3fe0014873c626d5ee658c662d977e2711b61e 000000000000000003b70ceb2237318196debc4a3efa6974d7800cb931219c1e +411000 000000000000000002bcca81431f7d50f719830d1e04544cf89012ef4ba9e2af cb6ea5d77f180058cc183f5f239a0dbad997038376657d98794baf25166c02bb 000000000000000000c2557733259f2689e5ff6c64495d85949bd7ddb055037f +411100 0000000000000000047d18bc4162476f6d05d3381c6e3c8dc96de063ca45a6a6 62958c02e7b9ab704f5340882cf4d50bcdf98ae01416a910ea9f2ebfaa0ffe7c 00000000000000000492033b975020020a9faa849f74ca154d827c40fed941fb +411200 000000000000000005efcd953eca0f2b24ff9cfb9d26c651efab5dce7da94ce9 5f29ddefa55918bf3868eed19046da3d8bbe64ed8a435ef7fe97462d84a682de 0000000000000000002b27d70f5b0b8f033f4f7af95878779e62b8d387e46db9 +411300 000000000000000001a3079487a9b24c8169193c357b18bf5d5021f14cc3fa29 fa5950d75c2a26685101d59714474fad8e54424f6f613c0f9e5d6a093bda5fe1 000000000000000000b9d8d41163087d3300a013dcfaffe3347c87bedfe81aab +411400 000000000000000002303d4d13753dccabcdcd33ec4a2adb1fcd5bae29593e30 b2aa66929e50b0a9ac19e189616ebc5a93d617f6b12ea11997146a4d20e34fcb 000000000000000001d564bced3b955bd05f16ab3f3e453e8d1aabf00390546e +411500 00000000000000000258adbacc58c8acd91d492943ad64ab740ca5fa74b7f2a6 92508f924ac08decacdb806bdaaf2ac9fdbc46c349a81182d62970b7e60dab2f 000000000000000000410544d7cfe8f90b81daa1f02469a40be99e455c671be7 +411600 0000000000000000000f3fbd85e0006306861e9ff174d5f4f4a7758d0889ed88 2c971a1a5e1800f24fc07693844aae9c5788d3f29f193abf47f8d02bf5d22c2b 000000000000000004376eb2c82df71b423146fb115a1517d8e6c6d95664b0d8 +411700 00000000000000000380fea2e3aee359569fe8d46ce18c05faf0a6dd71c6474a d9060e0399d1692670a09ae789f20bb0588f18a00c2afac05e5c31cdf4262b09 0000000000000000048f9f0851b6c9a1f5627ab1b4bccb136d278f5dedab5844 +411800 000000000000000003a62e908495eec18c1a2c3733ce9f1e55b7bbbecb37320a 99bdad4d24f2e560c1edcfc066c511d4293dc698d51ac28ea98144445471b66d 00000000000000000044d9bfc94f9e8ef6b61d564d16d140cdba41b7fe4292dd +411900 000000000000000001d6361a20498ffe1eb7f2e28bb863b9ba58c6647494dfd2 ed2c439fbe662f7f24a4ee80d0cc64408dd0c0ab6fbfdad305385d8f75cb0719 000000000000000003af43b0e057cf4f5e9510ca9014c697e25aad5d42e92199 +412000 0000000000000000014dcd1377afd27d3cf2320d32e4dcdaf21c39d293b9bf23 0a1fdbd1ee2eda58ee4431643814d8d188547622362d67009dcdb801f80b9454 00000000000000000323da2be6bfa14499c93b99aa5e8edd1a4f7b6b32921aae +412100 0000000000000000021943947bada10f9bab0ab766876389b2b214870cf5c0e1 c66370d6f2a11f076e46b4efd66300e00b571618941631ab23b0153e7cc1e984 00000000000000000451d5fe5b0abc97aaa0fa5438125b985c85a4cd19293f24 +412200 0000000000000000049f9d53f901ca0ae80155c2c55f2cabfc5b0f39a1124307 d641b89cd7c0837271acd6064bcb71457b3ed5c6ad6380635cd65436d9fc7a9e 0000000000000000045532c6c60d7dc302b1608468600a88642d0b22d20e1fa8 +412300 00000000000000000521de356ec334d3cdf26f6c2fc633c78788b4fc8126d682 cb9e334371b8ab6355106c03d179c6f0cba0303a39bf7d24bf84174434ef23c7 000000000000000000bbc5f813f99a5e8fa1de1a452779835d0ec383a99d1818 +412400 000000000000000000e265530c67d2d9ab3ce948fa11ee4837c6fa001ab044f3 d0c533b325270cce51ee090233d8b624cee0402f87df085fce26c61eadaa59cf 00000000000000000202bf16b609501e7dbb7e067053af4c538fde93052a4f7e +412500 0000000000000000023abfa79582fc38d23bb7dcc7d1f01200aaef31df8792eb 506e73f106e30f3a87640e0a6952227e679e30b2a7c331e71f575ee72792bbea 0000000000000000056af5b61d1d580be78fb847fe540e78f50f78305bb09a77 +412600 0000000000000000021fc383d678f66e23a14ae03ef25416a64376d8429cd47b c1eceff157eaef791754895df2e59ae971b71e175f1dbfc39bfe08d2afca9cb4 000000000000000000a92d1c92050ac9e59d71b2dc6e3e520a8649afcd5309b1 +412700 00000000000000000180eec6b0228daff198e33e0f2eb210aceac39f43fa6eaa c4fd2e635afa29635acf7055017e4b0896e962fc01a614b86f37a9cda4f7db76 000000000000000002125201a5b4c7e1bcad761818c453f8bf1012bf3cd79b94 +412800 0000000000000000031319fd379b7390412748353daf04af1e77e26f0682e4bd 6056bc4a5811f8901dde7673028bd5cbc52331021f4c9aae95ab43a15c85e6b4 00000000000000000357a4f8e165bd0b1c37fa6941e9be18f551763a5ac19f61 +412900 000000000000000003148a25393495ba964c848aa6310a94d7e9502f76d82f57 90e52c1acb47e242462af98f65f53df6ae45b96dd3a238354ad41aa0234024f1 0000000000000000057d137d4e57ba70dfbe5d3ce4439fec5b5b77a8b4f4bc70 +413000 0000000000000000005bd52259cbd862805e7fc736c52e46e10557feeed2b02a ad77f79ade7e84ade139b0321132bff7ee9567579c14a724a4dea6379859c363 000000000000000001068cf7f5b174e768261b5d57ccc7aea8018eb23f08e42d +413100 000000000000000004f0b42e85d000834551e759674333d5fd5d68051d294fdc c7395fff07680195b2ed9abf98d3e3e5adbfa571e352ffe7cebe9c3681520a8a 0000000000000000002bab599d834ff5806b6966606b739f70c397264a74eeeb +413200 000000000000000000ceeeb53d4cdb85c822f1d08285307cd0198adcc2221a6e 603bdce9b84644e180eb4e3501eb09df7a00fb9c0cfb1f01bdb232560507563e 00000000000000000278fc6dae4f6d14ba7b4f71130d27f34211490f12c8518d +413300 00000000000000000507d44120be30b091a1592d2a07024e4438241296bd9ccc 8a0a885abc60d7c626d9d942323840e3779ce01d6e0ec4a4dfff3d5ac277b545 0000000000000000002330b84110f117f5e0d1a27066f69d17483f5cbeefbc4b +413400 000000000000000002d8f8c15ac643bfdd49b2e4fc418106eaf784b72de0dd7f 420b9ea0c81b80f6b0005038293181d1f93c4e9bd7e7a1409d894e81ddacdbf3 000000000000000004475423ca0a206308a6079a788ab51a3cc73102742fb7ec +413500 00000000000000000334d3dc8cff93484374701afe3a766f79f2b4e290b6475b e86380139558c7f82e5762f6cc265d344c7628f891b1e992d5c4f21488206222 00000000000000000560e84525d625f1fbf813683d1ada037d25eae405810fb0 +413600 000000000000000003bfc5b5f6d85bab153fc8a1cb46655941d6ec69620a8735 cfc0c105eaaa3700f97350fa13e90d74ea0576a6bd535413ff386236a498d781 0000000000000000050ebb0a5b493d557f0ddb24a880c87935fe94817afbb3c4 +413700 00000000000000000448ee09360b6363d9a32fd623ca2fa299b6bd9236df3461 e4548e257f7f4a9db18acbbe332d5696922830476780119aea7dcd15983c4639 0000000000000000008b19623a03e1156235699b7e2611b853ef368996331e63 +413800 00000000000000000472fe8373424d5d2eb4329d3b21eb24c2e1f2d3c23db59e 6585b35e93d0778431b147d368e90dd1ff2652758cca08c71a7fdba2727a375d 000000000000000001257ed32428c2b30e44ed3e2033b89c898de453848d961c +413900 000000000000000002ac910ea9a7971701ee2b93f10a127fcacb60dff104aec6 5e5a60dcfaab1dc00ffe9269becad19d30db7e2d50ff1cf2e37e40f775dc5d1c 0000000000000000013bcc77727f99e291bdc43b1c6b4cffa3bb179fd947da0b +414000 000000000000000003727e589ce68495058c0bffb20d98656a7d875ea1ae7796 0cfb2d8e4ccafdd75b75a1a6d6f53b40d16f5dd5fe37209bbe01ceadc6178222 000000000000000005814969a2106f7c16c37f82bfaab565c9493529df162a62 +414100 000000000000000001ee4a8c57d8345334fdeead77b1a5426e921b3f18b13303 1a80e2ce7d2290e5ae7adacfc350ede639a2b0282dd0c58a9c301f23a14c1de4 00000000000000000180fb39e9d7555de9b19fab6f8872bbc586e1cd2fc11e06 +414200 0000000000000000032362a792570c0faf85db2fe78595131c21b2a69a261472 05b45a80ec8e6bfd997a4c787efa2b2ec55ae9bab485b74b4671d5833b45d2ef 000000000000000000ea37c4110c75261f819af8d6f2592303c177279e508f5c +414300 000000000000000000256e7041bd22551528b760d5c07c71b32d793ef51ed497 a8819e00ee426226bd5aa25488f6e94e73a2f7028bc67d5fda49099970ec33dc 0000000000000000011095b8305b0c587d4c41e3fe826e0a19b7209da13b0a66 +414400 000000000000000000f5c00d08aa7d5d4807f22476d7fcec77a35bac7dd1218f 19ce2e9735a962b12f6be0796126f82542fd3d8397f4ae8b316cf4b1fae5452a 0000000000000000000527796144f3bba462c33298de391cbaa0e30afd601342 +414500 00000000000000000407dbf3f10f99a6d3362a1784ebfbb2bcd798970d6db0a3 c4cf1533ac91d1e92257dc9de98bd4c0ba95045a0d6da3b15d3e7632cd4dbc77 00000000000000000544b9433ed5e1f8c5cfc079a8d9e859a6c7bb7b2d3d6e69 +414600 000000000000000000620f97b5224e37b39eec7f50c11d3c8d9d878225c8974b ebf07743d5edd23bce3fd2651571244003c43380948fa14ef7ccb0c30c881e31 000000000000000000b0a7ad3ff294d061e63cb0ee737c625ad8667e96d02eaa +414700 00000000000000000312c230a431c78aa612dfda347267d44675e38dee357494 a87158f6c5d8c6675ab57369a3de3bc5e2121cbc52e9691e9ebf1afc50f6fd3a 00000000000000000299a44b7bc11e364a229f71371dd582844b312bc7a68553 +414800 0000000000000000039755d052be59a6179eedd341667251d3cc22c20fcd93b4 3c29c0e85e28e3ef33812eb6bf310d24413407cd009c84c2e1b017357788f3ad 00000000000000000358cc7687b9e1831b73c19d08ad135b8ba13994763deee4 +414900 000000000000000000811962649e07b28cc57c1fded6e25abeaae71b3885e144 d7c972ed3d63c3fa7630267799fe2dc3a8ae86b738ce97934225da67b6a9c4f8 0000000000000000010276e6cea32c47d03e5f371fc4b0ab4926b66a632aa73d +415000 000000000000000004379beb807b12d1aab03c02ece6a6d19034cfd19432d444 af77512800372f4b17737e8d3aaafcfdb7129a1c6166e91b082e23e57caac5c4 000000000000000000c85c86135e5764f8aa94f143ac981f86aba0e68e75c378 +415100 000000000000000003199c70ed4980536a53ee946bcbf0bfb2ff56562dbcfa9a 04177c6008d9b926cc2979929d243cfac2f19d2a9d71aec95453f7443cca7058 0000000000000000040032f307f8ecb5b1581e6d4f0ea3a9a4b6ca6057940ae5 +415200 000000000000000002e786003b68183b14964916e7ab0392a3b367542d6f0514 a47e9a63295f5c3d8b41733679caf607365028389ef5b32e562b124a7922b85f 00000000000000000400372b8bdf88e78dbc95e0b3b21b10f4d61dc8f3b11837 +415300 000000000000000003dbbba422d67eed9a452ddf3c82133634d965e800c274ed d1c847db10b8cdeb08c4a751a029a1cca06c1fd0bc6d43bfc871f44526d49e51 00000000000000000574c5157a61b7b90b6607c37eed2588ec8e06ba251be092 +415400 0000000000000000050525e49d0241e6d7d11181f882c2cbb6dd4fcc5303fa74 7362254544006ecf4cdd95770666e139359fb3b90d8f6493810b5ebeecd5b564 0000000000000000001856e119c0b08cf3f570eea01c761bfebad81679a28fee +415500 00000000000000000082755a016ef227bfa6b116b4f306305d414cd976363656 06529f5d181922ecc74ef4df224f0e762a3c1ce586eff094e86b517b02596f5e 000000000000000004acc9df30189cb5e1ccc892e097b3dab2f589ebb8d39a80 +415600 000000000000000000ab33f0a763efa518296b082ee2f775d0d5a1be0a4befd2 4ca4bee94b228d701b52f9a9f57200e2051e46fe47e0b8eb29c5773b9c9cd09e 00000000000000000073ceb18f83251a90ea7de27623e2c91fc2e21bdcbb78df +415700 0000000000000000049ea8ebd42b46a20301e09c9104174054ecbd727cc3aeee abee48a36ebafa96fb9849206d85e1899f6b644e041f1c60690294cc5a915ab7 0000000000000000012689b939268fd256b71781b9cfd5e1b9a588de8f5ec8d2 +415800 000000000000000004739f22679db276b101dcd70540a548efef16d280874b32 8f9bbc6feff5e7860f03392648584c848d73ca248e56e49bf94dbc999d77e340 000000000000000001a696095e9d283d6f1053e48d21ce2fe67f57515e1f0fa2 +415900 0000000000000000021fb622f298cf187aa1f108fbde93597b5047cbf9045362 771cd67016800b597d6bd5ac19e03fda8570e217be6967af8d73e6415e48f691 0000000000000000017e8a79deb59ce62f599b724c61a3668a2b429ab1d992bf +416000 0000000000000000057799a23ee01dab5d6124c3bf89bbe8751cf792e88f0102 774d1b1b30d48b2f737a9d13587618f63774b2c5a099f59c1c6e887d1f464f35 000000000000000003c46614727cc27b46b6175e1a1cf8569a031a3350e47cbc +416100 000000000000000000e67598529210400615fa143411dab7a72eb04fc5a4485c 210dace8a997c0564a2f62a86e31758611d71b88e5895246a4337765be52a9cc 000000000000000002972b6e20cde65cf0ba6f438a9931e2a0dbfbe13e3f515f +416200 00000000000000000390bee92127564bd0c7ba8319d765c42c2d455ed37e13b2 2536c9c6d36cdcf965cc5207d67183c50471f9667475c9472ab0ed0ccc450f47 000000000000000003f9f781e47922be08a3e3e743d8b1218188e8146b3b726b +416300 000000000000000002d80fd780e51543302c96ada89840467a06d1a46ee36fac b8c9ab831faaeebfd18f5f54a128867105f2c5d313544437a00e6b2bc0fe839b 000000000000000003950276def30c575cd9d693c5ec97772995dd2443ebb0bf +416400 000000000000000005244040a41793b9c7abc22a315bd586639fbe2ada881d4c 86246a3ef5486268c67e53e863b0e23374e8f800c306c2853e17ffdb2cb7ce7f 0000000000000000010ab64551f053b9af4909773323be822a36eb2b652a9d6c +416500 00000000000000000330dc686da032f93d7e1d8d46edc65968189cf3c640d7e6 689cbc8c3d7739ab8d48f98dee1fc058fdfcaf3b84d65478fd1239f283c9982a 00000000000000000542577706fd75dd820cb12f6a92e3fc8c0526758b143f8a +416600 000000000000000003898e25f508017e1ea0b6ec51df3e2bd1f48b85a6e91ad2 6978697891224937bdcb16a6130fe23eeb2ee3639b90324c7f72f3aec81a8091 0000000000000000005fd7920df8c4666a13c9614f6f9c85c354ccd7311cf490 +416700 00000000000000000249504fa70a995c6b841e48f1f7a53dd2bc6aa7a1d023af 9dce3c4d6d3c3e0e486281726107aed12dbaac2760aba277612856e7f04ec0ac 00000000000000000392a51511e801f06f95bfe837a1531f41dca2431eb23c76 +416800 000000000000000000a5266f4b458fc34a66007f899717072cc0e88bb90e4a4f bcbb0703fc5e1457b51fd2413bbe29031e6eb7fd53c58c5fa41e475232650760 0000000000000000040c60bda451f254ac1aa1bd6a311a3b71337083c468d030 +416900 000000000000000001758d13f0c946c4094ce2d71a950ba390c510c6fb1dbaf0 872a19ae160019672b0893b27e5a290bf16b11c316f79f380f64c14b91c2d6d6 000000000000000004a72d142498d7d383f64d0d401308533d679287a26d0eeb +417000 0000000000000000050de1737c517d9b43209fed81df6bce7cbf41d20e915d6c 71a949ae6a04cd0dc47e2d773c450f6ec82822604266f45c2c06eb7e6410dff3 0000000000000000042f293d4617d0eca07fcadaf9d763a24edc7ec562671f34 +417100 0000000000000000054ad785e6368be2f11f6d5a8532be8323130b81168e0230 95287c09251f2bcbf6f54ba184b2c2d9c6861867937ef4e66663bb560344cbb6 000000000000000000c26bc09eef8946eb0ff1bec74e7cacc5cdf746006cafe7 +417200 0000000000000000021ad928d00760aba9571f93ce8cee7ab70e1ee1b7a28bab c9e233dd79c95e0f197efc86c2804fed5c2a96aaf12ae07277cbe12f5381d44c 0000000000000000032cfd19c15949fe88a3ff87eb560896f68f6e017e033990 +417300 000000000000000000d00911c00d26abb641d6366082522f5562f715cde92d53 50cd1b1e709ae557b1c8460f7008dff13f8566e1b403c1924784c5c4db23a3e4 000000000000000002eb771ceb22b79af16b812e9f3827fb645023282d49d4a3 +417400 000000000000000002afe70fc0fc0672fd1f1c75176099ac348f809ed7d935d7 f190fd5d7985b412e414c2009aef07e44a8fd30359f8813dffb32f9318b92457 000000000000000000c5ab789f6209ed066ecc3e642dfd3b8f2b57a52703eff7 +417500 00000000000000000071004f51b97d1e4a94f4f92a083f4e0e68ad6094e81d26 b44d6c8f08350ce23ce974c400946db455998180d863503cc126abb14230a9e1 00000000000000000113590532b9716f043c684f923cbb1d77d3ea12e7371c76 +417600 000000000000000002a611857e23461c69b6d0dfc6136769e3f2146ed6bf1520 689d9ef26bb79c98bffd8eb59e3e977dc797ea994677de3edb9917578a8d8827 000000000000000004ed1c4c0a0ed42eda70ca225479b605bf62b40bb9da7e67 +417700 000000000000000000d0646151017bd1a1b63f4e789e4e010cdd7c0460ac1d34 02dcc647dcf665839db59ba33d3e987ec6d9f06e3c1b825abb716883c8763aa1 00000000000000000344d098cb62d9ff3951e6bee0d6898e04a8cd7ee67da371 +417800 000000000000000004a5eb87aae0a0fb62521fd1065911a3e6a44b65eadcc467 7158abe90e6e33e35c1b442ae94a3d435196bf905d36b097ee8e2964ad04ae19 00000000000000000094cbd08dac259039ce1c055a15e147307e92de995bc397 +417900 0000000000000000007f5183c71636445a510a435b9e00dd741b0a68247bb6c4 1594f5521a4ad098be213685a8ddc81fd921b69be81f139100c9d666701ac662 00000000000000000428a4cfbc516f49bbcb845380adf62563d5bc36dad48ad3 +418000 00000000000000000013592fb504656c5edbe56a8fcbb79801ba561acb07419c 88c51d3c2650f84e54179ab6eadebb337ca7179f8b76122f466dfb70d15a2008 00000000000000000145d4625d38d58a32afdd3aa3467bb610d1e1209b5a9b1e +418100 0000000000000000053ebc3205f11bae37de7db171e23dd57eb1af38d37286e3 a6209463122dfee05332292369aa069da450be00a16d4d1306cf6bf57d978684 00000000000000000076313aebf0d364b48748034f14824d43d70d8bcddeb6e7 +418200 0000000000000000042bb2667ebaeb8f7e14664b5c1dad34ff0772bce75739e9 99e675a7bb319792b19ba98ae4e3d09b92ec98342ced3f0b539ffceda72fa681 0000000000000000032250056fb534d44fa5734c49b212f6094c075d75d65a69 +418300 0000000000000000035f17017196f2cc2bc7fe0e0bd255d949ee757a97dcb2ff de3104ddd64a97bf7516907fb0a4e97a84b2efd62134ea75e220593880a6006f 0000000000000000018cd472e8e5a22cc432c97063ecd9f3b92cf479a25cdb6e +418400 000000000000000004a5301d2ceaecc5104bf8b43e2226f9a43dc8223a15de73 73b197edd8bd5238317b319e57f7e8711e5d1cd81bba570e79d4070ded1c26e5 00000000000000000269d324807db347ddb1af178b15756d7c731d6ce30836b2 +418500 000000000000000000ceb02b432363a5c405109bc8e28237581b6f515d96e400 015b7224b281131f19910ae5e77d5df4f9b7df381dacfaefa02cf3decaa554d8 0000000000000000053ae59286e79df1b856cf2f5279f0353080763c0547f42c +418600 000000000000000004c38ef82e342a7b41b09e263e7c20c232075aeefd272af1 5cc7ef1ff1e7d654fcf7a90e33b4afa3718560b2616120b7156014e8dea61dc1 000000000000000003f44296211f5d66cae4d5163e65ab8b5a8ed3dc639b4004 +418700 00000000000000000199355f9c1a98a3b40582d08893da553ee5be1cda4054f3 cb56d6e7922fea9b04f4cefa169f59c2a77bfb7ec6f5f65c906fcc098359194a 000000000000000001ece9662372947b81cf8f6a545e4a0f82686d5d3810770c +418800 00000000000000000205c8b5d799bbcd36a2e2868d802ae62f23e4496ddc0776 c8dea2a0c7d5479eefd2d9f5602b58257fc730c9c2b6a49739c7ebff8b2e17ed 000000000000000002c72ff94c58fec20dde18f3c90902f19e895f3db8a95f24 +418900 0000000000000000014fa804fd4df9a6d56043c649464b62d6162ac4d819a650 d0067a1fbeb3d3ca3738da3ae8bb1c340da3cc3a43e605908fffb5431c43430a 000000000000000000428a0bb02fce0cb5aa7ac9b8891781e7a71bfd87508e33 +419000 00000000000000000051a164213bc4f1fb1f9ac014f92a6993bfc9fd4206d2ae 8a933419c90c824f701cad615e11515e16fe7be8cba43ed8874868c44f7bd357 0000000000000000018c391378d1c2f99243f33f02d2db23c8a1733229ef377c +419100 0000000000000000015c26cc28f64ccc723de922a2e17c6d2a340d78f4e3a628 5eca5c494f8f4ae91ade4e49c0b17da4b00964f79b055247c06d7ef1a7edb498 0000000000000000033de2ad475ad155d7d2a2ee2714fe81641891a523e568f5 +419200 0000000000000000026ff5c675b958e22938849781f1305092ce2c34ebe9e1e2 5e0651dfa4210de64e18db27431ef63be32f95573fa5b54e255fc03a4cad8727 00000000000000000413c1533cb3270e862a5adfd675e0997556069a19e0aeed +419300 00000000000000000270345ff7ee7828e60b120a8ee8ed1a61b36cf6694cf63f fb44b1abfc5ea3609289e4b0bf3322be105179f8d4a55a28ff8066fe6e548436 00000000000000000439f1be6728e05d6c4d41dc803f6ab9ce8cab8ed161545d +419400 0000000000000000034654cdb37df7b7c1dd1854a0ded6b4b9390c688d17e1fa 836991d5b249a8b7edee5d474b105409fe4f607132fc22cee9fc6c2ee27ed984 000000000000000003285042847d5df7bb7c93fed9975d09dd308665cc83f2af +419500 000000000000000001a6eece4ac7b37782fff7a68f5b94dd8e0be25d9bf45b21 2240873b22672ce4aa954bdf565363bf9090ba26b59b60d2e291c9042b5f3bac 0000000000000000006f21272abb9bd6a93bc82a8546cc6adb0d57094ef743df +419600 00000000000000000092c239f98364700bdb273c24040cbad4733c930eb1c075 ce609c7c0c2d11fefb4b500ad23dd687fd753f7322344d60323ca503b8fd433d 0000000000000000021f14da1a3a1cf7d8af7d20ccb45776060c8f308fd7a814 +419700 000000000000000003e290ccdd3ab5b7508838eef207ff5e127985217a4d8928 567e458e0c84ce93f06dca25c69ecb3db6265299e2a1bd145f4032e266c16429 00000000000000000334084cb30f2cf81cf4d57088c3e23a24321fe43ff8b747 +419800 000000000000000003fa501b597e57768e33b34fabc1db4e7504883e8c4eddcb 04ceb6bbede20986848f1124ef146e7343ac4e378438cfd0c922da424efc5f30 000000000000000004e8aa8cf1a93b3f36e7aac9f207c04b090f87fcc7b4870e +419900 0000000000000000032eb0bc59fcdb343c42499f584bcc896057ce2f7507dd1c eb78b944254add6ebee8b8a6759adf0a99d45581f42cfc50fbc6a9afa75848ff 000000000000000001d8e3e0733f9eb8029da2bf0cdcf77dca7a1e716c2959c6 +420000 000000000000000002cce816c0ab2c5c269cb081896b7dcb34b8422d6b74ffa1 c7c8adae5d921d6ae2988dfa343da99765ee18676b3082fe7d9d336d5234ff7d 000000000000000004db7eebf333b81f2529835102f7f7e86eca889287148885 +420100 00000000000000000040c02a19842be188293555304561ffcbbe021244e6e0ee 2380601f4eb34682f241437347d86d1e9742e2aa8c759eabace5730c71afd5a2 000000000000000002949807a01d81cb46a88989ca9b8379f30ca9dc64cb4122 +420200 0000000000000000011bbaf9241596fa8de094b12c344d7b756cece7f490a509 09e8413a8d62d260d1a2be206f7d9bfe53e8f715f7df3b8084d9de2332765ac9 000000000000000004e4839555c9cd6c3782ba153447bae1ef74d34136644300 +420300 0000000000000000017a859238351b59b11f2d79bb1f66613c5fb460fc0cb595 d81c27bc80b9294f6878acf9aeb5fe0cd913ab24e2ad32b682c2a181516c62a4 000000000000000000d70363ee4b215ef3ff6c2717097baf3713a64c9481976d +420400 00000000000000000358d463cadbef09967de2a379eb36a9988c31b664b6a4ac 2d0541d99916fcadf76b9f69c7616a9a6d6840e4dbeff3f59d41a966791bb12b 0000000000000000035cca49469652bbc11a6f8acdf9beb1fd3d6a83d9569482 +420500 000000000000000000737829e57c644de31353c1e11a5e30454fb5c56deb00b3 94db1437d31ba1ab5324857b53ac5c0f753060410ce39748321b6b9f76c26698 0000000000000000046fd08b40e43d3bd30dbd3c966d85419ff71dafa7efe1c1 +420600 0000000000000000020caa56d6f5294a13ee6ab47bd1b49b50f4215894eaa07b c74cff7c9bb4fa5320334f5470ce1e1bd7170a2dc9a33b9480d147c941c70226 000000000000000002a77e57cddc1abd681f06e86f0d0dfa6d13fab6886dba49 +420700 00000000000000000244c014bca137e1b130b3d21d7f68f7818ad0dba8fd2d5d 3a69502172eb2511a5afdeb72add86db46107c94f4f42adc4a1c7e63267aa36b 000000000000000000e356c5290c42eef84ad2b7c203165a4837e8d2abd266cb +420800 000000000000000002dceba06e4a97286ed44857e346f2956086eca11c4d1485 bccc8c3108aa75fe56260684f1a23406542964cb1e9107363b488cfe8e0912db 000000000000000004918e9cfc0b3330f84546ff7cbf0a7f339f4cd6f2d6c243 +420900 000000000000000004eb30bf95bb9b68d052bd65fdf2a2e3808196a3d8055d27 16a9e8450a2537a7b3e3838d84b23222ce459d9657a42cbdd348837654ee1a57 0000000000000000019e2ca75779964d3aa7c7545c9da91c8833fc390adf13f2 +421000 0000000000000000037b70df8775c69e78190b891309f97cf07df7d590608d9a d9a4b89807c01d3fb9bb16f3dc10322ff12d14d6783ed592ef81795b7170cbda 0000000000000000004ba59ac4494a01c804b635cf8fe78b13ed593993faabfd +421100 000000000000000000a4341ad6d18d5903b0e9b53c335e9110b7f4090ca85ff5 3df0cfe09cdeb7c21e028796204e55a921474f6450334155ade91b2b6f23fa9b 0000000000000000020d90196390d89325bee1454f64fe0fbb4f9408f67ba214 +421200 0000000000000000043b5259c347ca074292a2120bbc4d9682674abf976c8203 2418cf53e6ffa060eb2e16ab65cd985b2d72c91cb87c5ba98bb8d769c4ad9afc 0000000000000000021419ca1d3359ff1cc422b09fbc46996ca176f15ab87505 +421300 000000000000000004d535660e83b68028c91e32c55e29df94e2ddda84f0b22f acb7f6f5e61d9a4c78539028d7b2afaa6b5be04a90faffcf079673a6e67f1143 000000000000000000200d429044e8e78cfe9b05e26ad56063e12a310a266cc1 +421400 000000000000000004f6215d7d39c7bd655d97ea81943f7f2b0a1f20891e86fb 17f62dce8c722ec1eb9237b4940931f63774d78e4eb8c7aa900392f156fb2a92 000000000000000004688059c73d80f18acb817c64c7cf1b6b798a5293dbf5e4 +421500 00000000000000000477f0a315d7402e0dc9829d9f43f916065426d1e9c155f9 ce34e7a7692a48aaa3cd428e3c6b1439af6e113dc5e1369d4f623e0d22ebb961 0000000000000000006ae5dcfa7057d0e2ea1d82a8886394cfa83369c1cef944 +421600 00000000000000000153146998669cf0b0c8f7044481b4ef4e269bb7ba64b880 a8e47ed5c45682a9fea89d2279fd13d4f3471ec3ec3ca5829077fc7e7f6b9871 000000000000000001fc2eb19e4a96589a6f52059b16d6e8bcc89dff5d2a31ef +421700 000000000000000001da886fa120ea9d292ccd261ddf1f583773ac98c18377de ff3976b2e61ba43b4c9433c730846b346f8d51475664d91e0cd417f6a84b53e5 000000000000000001ba790934ec1fce52d8d70067eb5f620728f370c6cc1692 +421800 00000000000000000021ef307dbcf6ad631ec4fc906ed8c1de56ea7e702a44fd 3a8fb5e9ae8c814d02226f1902f4aa411cae5e3af7081f568a8bb5d172d84a10 0000000000000000013323ccfaf80ad290721a076c3bf3a6cbefe245f4fe5191 +421900 000000000000000001c700afa4059eba91353a2545c7ef88f39cd31e5aa1a75a bd55344f0c1e82769f9a45a9c1138bb11ba4f4393eac23fdab1468ab32184eb1 0000000000000000036ce052faf34ecbd747cb6b847a09d8a56191796e0e6abe +422000 000000000000000000bc63425c27548213256efed6f40685ebf4d3da10562794 ccbc36575bcfdc62821b71ada8e71e2cf58b53ccbaed99a44d8f55ce0702e8f4 000000000000000001db165a3ac56a2188b8bbb8e0574de42aae0256d7f06b44 +422100 00000000000000000404010b42e8afa5b9d3f940fc09877d218858aaaf11590c 843bf243d633150864b2460adebaa77f27921032e60bbc528d6a146cebe7c8a8 00000000000000000152dc37f8d427abda33558e6583b922741e18c3b4686c71 +422200 00000000000000000106e3d57b1bf9c09c413a1091030bdc9b3315c68f6f7cff 03cf2597917602afdf8ed2d4c70e649a686b069dfdeb4200e8e565b43e6dbc61 00000000000000000450d2a7e88bf81af8709510beb08321aeed0749faa43f32 +422300 000000000000000001522938d673ef988dd34adff58f5c3b0f85e26b6a1e88ca 0a389ce19acbcb3ef51dec4c5b203dee556c029376dcd6c2b1b33149b5f8715a 000000000000000003b7de8e20e7bcd825f8d3eefd4a1e7b1e772cd8839ac90e +422400 00000000000000000089b5a3ccb4cf8a19c9ccba5a7ac2634b9eff5e9ae17eae e11ed356ad36954b2987f756db0e100e3186e6b478d24dd83c2ed72ebe777ef4 0000000000000000022940471a6a38caacac45d3af0222b625202cbe742c1c93 +422500 000000000000000001009b3c62bde49c1740ef7347ff221935c9553c44411c97 82a6f777c7c6e0242f065dcbcfe43b6597bdf40d72912cd57af86f1db32933cc 00000000000000000415e908b1eaf8c9f74633d98dc80dea56026e5e7a92b2e9 +422600 000000000000000003d3f2a4ade56a316cbf63d10bc4776dbd81119fb8959495 a8e9f656ba01fa125c233f1d0937b1de81201aaa70c8ae7feeb8179ff57d891b 00000000000000000493cc9bce248199006bed00edc87539fcf12f0e5479cbb8 +422700 000000000000000001dc3153e274cc8910e376c7875c9414738e15d6c5a52606 e6bfbb286784a3c3869707d089970451d619a2b5a4bbdbb31848a7abf09811e5 0000000000000000015f89701e53851df9bb6d37c699a0c63fae9055b5429b7f +422800 000000000000000004eb3b87e026101ad1d75b7b19ed465320e42584152df284 5a7f441d98e254f922ff2148994ec6fe37e58633d82de1d6029856bec13bb458 000000000000000000f3a92975a93c631b3958aa679c5c2327f845472901844c +422900 000000000000000001d309b94f5c95c87e6e6292cbd281ff34addb4ac52fc5bd e55d55b7344f7967b05aad3a19946f55147508bb518eb857b4fa9ab177526cce 000000000000000000d66426fc65ab07f1a1be9b62665c49182fc5896c1970da +423000 000000000000000001910d9f594aea0950d580d08c07ec324d0573bd3272ae86 49b607142e9d73d953241cd05b1afaa84ece371206e087da38be811c0647177c 000000000000000000fc12b276417eaee5a766ddae5bc9cda40ac1ef17d2f4f2 +423100 0000000000000000000ce03f88c38fea2e2e2762cac88748d607912eff518611 bf4eedd95e23ebe9ab829a384930227049b237147c4ce95ae3cebaf2d328bd58 0000000000000000045bdd2d63a4f82f5a02d4e379ad7280d816a385c5888aa6 +423200 000000000000000001246390bd97920fb972115d844b8c9db8bc142b5b225342 e191c34f0d033a23b1c1dae4e1de04b23c5e9846b42943aca718ed33d12e49bb 000000000000000002348d00fa26fd411cd85c5a10f97b52a779d835a4a7c09c +423300 000000000000000000ae11ed8062082316d588cb497377a093ed1416afbb9980 15de21c364991e7becefcc234fed7b25018fc2dd57bc115ef42733e4738a70d9 0000000000000000016e1fce940ce4343af73f43c1845e0cc8d158806a04d755 +423400 0000000000000000010dbed37ce4d056b808e9180b26ed9bbff2f873cba81181 dbdc0be2463a7cfea1c30dd23d1d225facce2cfac5788ae64114b6630046d1c1 00000000000000000372463b428e76c2fd173c9134769d933044df2f021a405c +423500 0000000000000000030212569e9f3c52d64621b357affee36458d97ff5ceae67 5fd4849d89ad94ba4a37bf6055f2887eedbbe87f26cdf3cd62307b963ee39504 00000000000000000256981427151dbebb07f6c146343115f691c5e6d223b9f1 +423600 000000000000000001ca9967e5a92e40ff7097eb615f7d9b4fb78a3e074d8fd3 4875c51973c0622e7611256187c07cec953e2e456a4c5d9e8c6543df4f5bfd14 00000000000000000206f3738f99d5c67c18912b5d28de2c484cba720e4b7bee +423700 000000000000000000e8e680fc102dede994c57d25fdf3c52741431b4f3b3067 448126b90382417954b37a0d3faa36fd3c1728e81921eac6c9412e23dd553ff3 000000000000000004bb1e39761bab8fbc2f961cb80948a9ce6042ac067f5fa7 +423800 000000000000000001497341ac0759741bba9265210ba191af85ac93a4903d0b 9c76da7137555a86e8fb89f1b8bba38f610fad66e2b94a76b4c51b55f972455a 0000000000000000042e4bb3edefafacae9dceb64bc8192d47deb9fb6e6aa32d +423900 000000000000000002cf04729533553ed1e2f47ccc9e7cd69722b3166ade0235 ab65b823c9908eb00b087ab58a8c206669d0a5d18cc1997e77ccea83a558700e 000000000000000001994b0f4cc318dda71b25f9722ef6919c48a734d96abd4c +424000 0000000000000000014f564a76d9e3efa7940f0584c24084e8c5dc15a8836d27 a3ee25361bb0b0ab8936015bc6911407677c861096432f84aaec8ff4fdeddc09 00000000000000000077fc50c11864ed0c2ca697465e35c7a07f4fe089916980 +424100 0000000000000000003acc23562e1c84e2473a7cd115d40980a0cf80da3cb9ef 5b14532bfadc2f6ae93fd978c476e76c2b08806c849fe0df75dfaf0d421bcece 000000000000000000b9f6cbce5176f9649a57d5491c1e0e63bb0630a38dcbb9 +424200 00000000000000000485f1a039fcd44c5efd358f588632f6d5f026d75eefeb63 643d069a3bdd76a5df6484e2c3294891ee31127a117bd325c0e764927a5411b2 00000000000000000327689945ac5e06ce159d8ada440f8281cee6b0fe455dde +424300 00000000000000000172acf8d0d06f2a5005613ef825527230e7c8840804e65b cfcadb83eed7dccf4d1ff58cf98313ce250cca633e69ea18d3f28edcffc03d55 0000000000000000009448e797e42e0c32976270314d472d2d63c3bd9850a71a +424400 000000000000000001d47f2a4d3db94b461f7f2a7abaf53617d829f7c678a82d 5b82d844a4f9b7b5d67e164a19762fe9ce8f9e94a12d045c985649288e46d22a 000000000000000001061509cbf37ec36715ae58a5a2d54359583890e610c6db +424500 000000000000000004eb0e562d9bd5d1f047d4832298749853299430c84d80e8 9a311b780547819e01f005439e92eab63f5fac2a09a347d6f1be539e386140fa 000000000000000004ffe9abb9400f1c892d91bee824a3500f245bd6c94ca4ee +424600 00000000000000000187a165338f220262346e5fe53533d6e611dc9716b71c11 4a4a62fbe9b8abbb4d0dc20a067a1da02cb4838a114d20517cf21a6b150aa2ef 00000000000000000224669ae6745ffe02070aa04df696de794434d43de7f792 +424700 000000000000000000f0f2a3de276098e43f158796acd79ab1017908ebcf49c4 168a0e22ffb283339f5d88713ffeec9a9eb8f1eae2a7525e41dfff437e598b62 00000000000000000211d89740ff9efe442f553fc98c8527985c33f684b46752 +424800 000000000000000000d73778af038a782cd9ae679421007da3ed2a432424aa7e 633d585bfbf0c93439dbdb6ef536da250757a353528e30e9971bfc57c74505a2 000000000000000002ccf65456a4938474580227b9267d2680b2be3f090ab4fb +424900 0000000000000000043dbe99aef4aabf15491c9af818fa8fd5694e4bbc2f3b24 78fbe1b9604694e811e175f60d1b279ccfd27bb90f215115a1d4e8a4e810577b 000000000000000003985fc4ef5815b8b6e6d66c4326deca28c75ebad186246c +425000 00000000000000000142adfebcb9a0aa75f0c4980dd5c7dd17062bf7de77c16d 5476d9c3801a060f9dfb07a9b36ad73290763e73456203134849e4d189068902 000000000000000004da9e5abd0b2450a9915c60e6bb1d25e68e446c4129818a +425100 000000000000000003e4d29495714a4678dfad12cfb04cb6919899b519093072 65fbdf32c7f2351aef29384bd92470341dbde9f2500057f563766b0553ef0161 00000000000000000419234a371b54ac9955bcc0a71757cc7410e3554d181742 +425200 0000000000000000002ba77e478f5d51284b62dcd7181a7a13a3c9c9c33ac079 d7729eb44a1d16dbbf0aa767c454f0bb5ba0a90b633925a482b3d7afdf2fc481 000000000000000004a63cd32b20040478773f6216fb56fe841e217aa614b43f +425300 00000000000000000151288fb033e6bc4a3878c2538712e8e36858a992fc5d0e 9554e11acec4bea8e655aff896e7d346c79a1bebe623138027f5ee4294f86c9a 00000000000000000032a70793d63bd89a348a669b36cd35c91ee64ec3a4400a +425400 00000000000000000299a6a84490eae8493ec8ac5650c915406c083902f5a4ee 3b9a846620092703d24e6495abc49b7df1d42ae21a25727d31635098d4f22a83 0000000000000000023afb17509f3cc6a388e0a8c22ba87f9bba6ccae220b68e +425500 0000000000000000044c9a2b2302a5a8954237bb5c0273c72d40ba21d040fb8f f54a8acfe0448df22e6302ec4ff7f19160b698614ca8335e4227e27c1091c647 00000000000000000282e498296de621fb99ebc1cbaae94643191f5e446ffe90 +425600 000000000000000000c7ebacb3c3560494991b440f6963857978b9d38358137b ad8ac398d6b05be8dae9667b3afb624d172048234799203659a8d91fe3ff4aea 000000000000000000638d37cf0d3c9fe4d383758cbcb65ebb462bd81c8c173a +425700 0000000000000000038c68419e26715572c31f0febada863da1220d930894cbf 05026379ef59ef4cff471102df57a7dc26a69e31b9f5b33d857caa658eddd4e8 000000000000000000919dd1654840a8ff0cdd90651124357cb39166f67e5975 +425800 000000000000000001d0bd74d555bba6a22675bbcd90c42b7c32a7c78224a6d8 4dc9480d1be719d8f703937639d6cb515c45ff73a11069c4ecde8dc86cb7cdf1 0000000000000000037515b08ba7134fdbfb9870ede2b395c44be0b731830b16 +425900 0000000000000000007ab68c5a054f3df9c4e0a534a5cd7ff4fd684d864419c4 f0b8000bfb2707ee9cc168cc3fe202276f2bcb44d54ed30a9f11b26c6774de22 000000000000000000e12304e24e2f0bbe73eb8e91a03546f775270ef85cc24c +426000 000000000000000000122ad62f412001fb9b74181263e1ee0ab13d6b0f2e0d02 e234d0c5eb6c4412dc1fbafd97c82926cc92efdc2b902dd8ff60efc8948daf17 000000000000000000eda3d9a4ba5507c662f8f261bffc950a0f85439bfb070c +426100 000000000000000000ee3d905562a9a429f883568d40dcf467464ac4cfc7a1ee 295e28f4753065e1b9ccb6b929bddf457d28783796e7b4df4a6a8feb3a0081b3 000000000000000001e169610a3c0666f542067256792366125237f03d7b616b +426200 00000000000000000200da5b6ae0ac10fbc019df0e2060e003b62553dd90ca73 9c0586822fd823ee28c270c1a54744e11a257311cb0f9254f96b74016ae1564f 0000000000000000029661340818641cbf7003f37d9329017da82099831971be +426300 000000000000000002af7877a928b1a4b33010f0834d994ce2d6a39384c959d1 57c464e5254a3f6f93330a2866879195e85e7eac987a839267dbe67d63a500aa 00000000000000000348abcaffa2f1230428be9786796367d2dd6d278b5d6ddb +426400 00000000000000000130f79611451cc9e3a812e84ed50d9358a5f4ecf6232a10 0365d6020a98f753f49d5b2e7d1e6a31eddb838908d95e2ce845873eb5f02ca4 000000000000000001f9514d5ecca9e50ff789a620cc2a7a64f301498e5fc931 +426500 000000000000000002de2416b54c724f0a44a606adc2c591863d89a4aadf69ff 9ed583b47abb650e1720272002eec7436d848220e5fbc3445c2b42d44e53de8f 0000000000000000033a03a6d9c1dcd5bdfc9ba79d6e4c379e2c7d5601a28ff3 +426600 0000000000000000045e8f98c6e9081430bbdbbad0f9ebea1e4c2a1e7726f2a2 fa5d919ca1a4f41fa78dea61c0135118372bb5517918e92f57d64ec9dc576d31 000000000000000002183f2b654fce37ac73c7d31edbe8a1f996484c8ff2682d +426700 0000000000000000015293ef02d391ea00598f7beb464c9b170d42d26ebb2fe4 9048da87e59636946d49312ca81dce4197bc46008ca93f41a0924e9b5229fd52 0000000000000000012ae565d34488804d6dbe905f828daacb637ee3ec8fabb0 +426800 00000000000000000130e27dbfda1b50d292b081e0c521753d20d2971521c42b 2e78a166fb83a8274eeb3cccb4374d1177c0255c0e351f8030ca8b8a68bcbecb 000000000000000000c10dd98d1ff20feed4b725de8ec456517f958595ca575f +426900 000000000000000001f9681b0c7a3029d329139d0dcb5ccdce2f377ae23fad31 dfba5c89e905d7300be16862d852273be3e4a9214f82ab9e68d9a9ddf6eb72db 00000000000000000229ba84cdf960a5c6226a6b1625f399234b396e34e258f7 +427000 000000000000000004a4fb7fc341124a27b023d9f1e8f1f8e026c83001676152 93035618331787bf3ed5614e9b954d2ac815f3c3c9d974afd3bfff122c2ea454 000000000000000001447d80cc8ae5c1ef956e822e5977aa6fe1986e024fb199 +427100 000000000000000004c5b3e14ff27e46fbdbd787ea6e5fd0f502ea5c6de9b346 a6be2dfb7b96dffb96e546979e558ae7aea37994472838b569b0df992f7e4a39 00000000000000000477b59fcc9a64d07ae3978585aee3d2b708d48e7131ea99 +427200 00000000000000000291637ca0b8e696de19ab6db9416cfc7ba0af605cbef9d2 8cce0d794d379158ffcd875ca7926f7a5404c28e6544772ed5e56e159293f857 0000000000000000027ef75fccf273ae9c63451ef72dec6fb45068cb60242f82 +427300 00000000000000000363ee0c0223d37b35309f48544dbf92c2555425b83af98c 19ba566cb0cb669833a6d7b5aaab97835aab8269846f853b752cf85080a9a523 000000000000000004a62cf1fb834bcf67aac1aed29fa77c2505d93ed8b0fc5f +427400 0000000000000000049709c5eb273d437fd1ecf1732dc05e5be0ba7684e3f458 c403f7d64fa0934823612eeaadd421ddf4cc41d4606253a6f4e004bf96b0576c 000000000000000004d053b11d030c71128f6e737a635489e983fb4febbe0931 +427500 0000000000000000000f05ecf77c205157c7e13415e395c1286a552678e9925e a7207cd2f57769d66c248647593e10000f21f9b63be53e32bb66b102236187b7 0000000000000000009e2b54a344c1a11216d0743ae715b9975e2640fd636288 +427600 00000000000000000050e60781f4ee25c3d576eb7d62637a45efcdcdb9a06715 cf8a12f22625bafb12201d7501e0adede5ccef59c0beab1069b8b6594272be84 000000000000000003b0c996acafbff042de93f355a6e45c7870f752460001c8 +427700 000000000000000000d2a58ecc65659f1887754c97e7582784a8d90a9e72f7b7 3d657a85e302d037edfbdb67bb8ee8ac3ec6b4f36461bdaa674e4e515b3a7000 0000000000000000023d676fc16f52026eff61aa218bb399d88c596ea2f6a0a0 +427800 0000000000000000005ee4e2c5a0df2769fd792f571c9bd6278581d669daa1b9 c2d86cadb79b9d1dad9ad421f06865c855442fc0b459782aaad8629884697be2 000000000000000000b5831fc38b6e65700310b0d0b64369770f3f3e091d4901 +427900 00000000000000000306adfa09f2b6d863257e9641e0f260d67bb73b336c7638 03a6071b04e0764a97e7d636b11918034d93a0eb7fab1e2459c8cb0e969a76b5 0000000000000000023fb4d0a745912a5d3fe31dfdd8f44453900421cf6bb290 +428000 00000000000000000430eb68727244caf2a95c75b1ccfafcd6e65d92c65dce3c 02c07eab3ae0956da749803c5c439525fc7df92b5fd396dc8a06bb35adfb6491 000000000000000003aa95c3d54cc1cdf76bff3b7c7f3accac68025261d95b53 +428100 0000000000000000033987fb36873b88b55f486379f69fadcaf75b9aaa3af305 ff4c48853df3461b739cd75aaaef630f130576e438faf8210db4ae7bc15bca60 000000000000000002e37eb2991f40b37be13c387f3fe7c8ba757c5914b731f8 +428200 000000000000000002d0b5992fc5e755652acd2cdaa22cb58eab792455417f9a 1135b76aec90a33dfdc7831c4d69af7d08efdae6669182c5b5836a8e9e2916b3 000000000000000001382901448ad6ac869ac46f6a74769fc6f40ed994d4c327 +428300 0000000000000000029ecf3456571b4dd6d46051268c4e350ce03b53294b2334 c15de5620757944bedcff2fe389b2bf03e2f379cdd4e486299d68af7e436864c 00000000000000000484d459ba2e166ddd356b2644d7bf88e46ec9625e45a970 +428400 00000000000000000124c45f8a00cc92212e61972c8a487b4c73789a515137fb 27fea9f04748c4b33108a434b58e7e5e6b0ed55f7bdf0800a2071e95f41f66f1 00000000000000000214aee275bf2e5b3fd88c19bbc53237d80ceb6e2c1f9777 +428500 00000000000000000268c76c989f86f77029319b69f801d35c2e5f7942f08f7a 2a9e37041adecacf1263af7b253175ea2b1ae0002e27f7a0f49c9bdf6c61440e 000000000000000002c928cd964fc72ef05b095edc2235c7e897e33b681a271f +428600 0000000000000000035d3dc2937f2a8dbab15faed210c1c5240c4039344d8245 2353f0679bd09a6f09f649716e0a9b10b29ee93b8950adca5f75119411ef2c20 00000000000000000348a9973c31b009c2529cdb54cef2b5670a2a25cc679df3 +428700 0000000000000000032e3fe0a77f691e16539a15d36bd250cc95b705261de36f 6a6ffa0d6620d32e11e4b42232429a578fee9fc3ed6eda981978a11645d07508 00000000000000000040b5d4e0b5069ff75b81253172f186b7642c0934f4942c +428800 000000000000000004aa9e38401491b443f0d8de149a2bc4a0a2621880e41e88 2336ce863f68b4c382cb450a658249ecb7f318c7a7c6fbe8f965d0018deac76d 0000000000000000015d608750cf5028a0f0cff0caa5e949a9c8238fa14659e1 +428900 0000000000000000014e14be9abad411da467492db56b96da2082b8c1156c889 5476dfbd48111bb5f5f40452e85ba64f30407c8e9824545a13e9ed0f77e2730f 000000000000000002d1be816c221bae177c22f25f79d607c0279cfd8e8a0ed0 +429000 000000000000000002a455bcab421d44d1c85bdac8a6e196aa0c0968aa5ab5d1 bc53b741739d79cbf671c59576d25a1af8e9580f53942d6ee57c9b5cda49356e 0000000000000000049904c0026d4e4dc770681edfb80ee95acb81fd212d1c5f +429100 000000000000000001e3a59330494e24a2eff490d199c32046c16000f3738c14 \ No newline at end of file diff --git a/iguana/confs/BTC_peers.txt b/iguana/confs/BTC_peers.txt index 99fc65790..25b1f2b82 100644 --- a/iguana/confs/BTC_peers.txt +++ b/iguana/confs/BTC_peers.txt @@ -1,4 +1,5 @@ 5.9.102.210 +78.47.196.146 144.76.136.19 148.251.240.254 148.251.6.18 diff --git a/iguana/confs/BTM_peers.txt b/iguana/confs/BTM_peers.txt new file mode 100644 index 000000000..2d4d8d49b --- /dev/null +++ b/iguana/confs/BTM_peers.txt @@ -0,0 +1,20 @@ +70.168.53.153:9265 +146.0.32.101:9265 +24.143.47.161:9265 +139.162.128.92:9265 +85.24.169.215:9265 +98.115.147.74:9265 +192.124.224.254:9265 +45.33.65.161:9265 +184.166.27.254:9265 +139.59.160.118:9265 +98.127.109.96:9265 +101.173.200.202:9265 +157.161.128.55:9265 +104.172.24.79:9265 +158.69.216.182:9265 +72.209.139.213:9265 +198.205.118.181:9265 +101.173.197.85:9265 +174.36.9.130:9265 +84.24.208.22:9265 diff --git a/iguana/confs/CARB_peers.txt b/iguana/confs/CARB_peers.txt new file mode 100644 index 000000000..f322ed1e1 --- /dev/null +++ b/iguana/confs/CARB_peers.txt @@ -0,0 +1,11 @@ +54.85.71.51 +87.98.182.171 +98.115.147.74 +85.25.146.74 +86.21.79.62 +46.101.43.245 +144.76.64.123 +193.192.37.135 +88.101.128.228 +85.25.201.216 +85.236.188.213 diff --git a/iguana/confs/DGB_peers.txt b/iguana/confs/DGB_peers.txt index 28bb69e30..60bf413ec 100644 --- a/iguana/confs/DGB_peers.txt +++ b/iguana/confs/DGB_peers.txt @@ -1,17306 +1,7 @@ 212.129.1.77 -178.33.228.14 157.161.128.58 +178.33.228.14 108.61.10.90 -66.228.56.115 -167.160.36.126 104.236.32.184 -39.34.235.71 -95.28.7.71 -36.149.70.139 -71.95.131.105 -25.125.144.215 -98.196.52.135 -93.127.20.199 -94.112.7.134 -78.73.169.30 -82.78.191.165 -151.29.224.128 -203.212.61.135 -73.170.147.244 -121.218.175.57 -219.128.62.223 -90.23.224.50 -151.74.251.28 -94.6.185.11 -201.22.220.238 -85.175.16.31 -108.1.94.151 -188.68.194.121 -80.201.154.170 -62.52.137.121 -25.156.165.226 -72.49.64.176 -81.183.119.94 -118.92.78.114 -104.156.228.176 -86.135.5.121 -46.159.10.54 -151.46.68.152 -114.55.117.237 -88.200.136.135 -174.26.164.250 -178.158.142.82 -109.30.168.16 -185.160.251.220 -82.17.141.219 -219.92.249.24 -71.210.255.55 -76.72.154.26 -69.119.106.227 -209.6.217.75 -206.59.251.202 -60.246.252.214 -70.71.37.150 -176.77.80.188 -201.158.29.115 -98.206.146.90 -217.70.251.174 -84.62.72.67 -83.85.145.11 -254.150.134.215 -85.26.165.246 -85.181.160.208 -208.91.66.8 -114.125.178.36 -71.119.30.24 -86.83.46.210 -87.102.158.155 -94.193.249.41 -181.103.128.173 -101.14.87.154 -69.46.195.176 -216.171.18.141 -70.27.45.70 -209.197.138.184 -29.73.204.5 -63.87.254.247 -69.43.42.16 -120.38.107.41 -97.104.141.214 -213.87.134.192 -179.188.245.56 -176.194.243.107 -113.90.83.115 -175.120.159.224 -37.59.20.223 -42.81.72.54 -36.234.60.175 -98.84.229.115 -77.20.66.68 -91.114.220.13 -162.221.207.229 -118.100.94.179 -217.29.24.36 -75.183.49.103 -95.30.237.147 -186.88.171.141 -208.91.67.1 -160.179.46.174 -82.226.172.82 -101.12.0.165 -171.96.172.46 -148.251.88.245 -175.42.86.217 -121.225.191.68 -85.178.131.115 -224.215.146.36 -142.196.255.91 -109.229.72.21 -95.221.238.70 -93.80.186.163 -5.189.145.112 -174.117.39.176 -91.188.124.194 -24.230.59.100 -5.101.96.124 -69.112.104.39 -186.95.200.178 -81.10.135.207 -82.75.179.105 -93.221.209.88 -67.244.140.202 -159.227.211.229 -207.118.11.238 -14.203.74.176 -77.72.144.197 -109.193.167.249 -81.95.181.41 -108.234.78.195 -118.209.134.72 -183.204.177.21 -90.176.255.111 -108.14.8.80 -188.187.20.44 -93.51.57.207 -190.141.68.49 -91.7.79.1 -123.3.199.96 -91.102.81.135 -111.95.117.189 -93.229.186.252 -78.52.250.37 -109.201.105.45 -178.47.116.39 -24.56.9.196 -77.222.97.198 -216.172.142.243 -77.40.46.73 -97.80.88.5 -1.9.103.47 -199.168.250.82 -190.13.230.114 -90.197.179.150 -254.200.66.128 -212.156.47.210 -109.72.237.88 -36.69.126.209 -128.71.158.207 -123.224.4.45 -24.70.0.188 -67.190.29.0 -46.28.204.53 -192.0.144.249 -93.62.254.162 -254.236.148.14 -217.42.138.114 -213.87.159.145 -83.39.76.116 -81.7.3.24 -79.42.51.42 -86.217.123.203 -79.115.105.194 -65.25.61.152 -91.205.236.225 -184.96.29.22 -134.249.71.117 -78.223.238.225 -189.122.101.45 -72.13.87.195 -92.242.132.15 -72.168.160.181 -50.159.81.235 -213.60.37.174 -108.80.238.183 -85.253.130.73 -46.39.55.0 -107.191.33.13 -161.63.219.19 -45.48.146.148 -144.168.55.204 -81.146.8.7 -84.160.180.185 -87.0.155.240 -93.79.12.166 -64.231.253.204 -50.165.91.254 -74.103.247.9 -122.194.230.147 -209.177.106.77 -77.105.219.75 -217.126.56.184 -46.22.172.190 -1.115.6.59 -179.210.13.19 -81.153.248.197 -76.102.131.234 -92.19.38.229 -24.151.52.157 -173.2.191.21 -223.4.79.136 -176.104.122.62 -36.69.116.166 -0.0.0.7 -98.126.61.242 -180.110.83.212 -168.70.79.201 -85.181.163.180 -85.226.244.4 -82.24.112.2 -121.218.79.89 -2.92.114.186 -188.68.151.16 -73.114.35.193 -188.22.213.42 -47.58.60.22 -83.8.113.179 -244.8.207.50 -124.204.226.226 -5.164.222.60 -80.219.44.41 -68.99.189.60 -5.248.199.235 -46.133.246.241 -137.124.118.72 -27.47.78.239 -100.13.189.170 -78.84.154.105 -78.48.110.171 -45.27.160.94 -76.95.178.145 -89.212.122.128 -37.55.8.14 -119.74.73.116 -166.230.66.50 -91.7.215.56 -77.47.96.164 -46.186.85.226 -104.223.185.184 -254.226.198.25 -37.146.116.43 -93.49.156.51 -220.249.249.8 -67.171.202.153 -85.66.172.138 -101.128.83.1 -80.88.26.131 -60.52.77.27 -160.176.20.248 -84.178.247.84 -179.124.176.144 -77.36.209.216 -119.253.64.37 -124.228.209.34 -14.200.37.7 -84.2.168.150 -173.57.207.71 -5.34.113.78 -85.76.72.110 -68.111.155.53 -157.128.172.169 -80.188.113.28 -82.79.234.31 -173.229.169.3 -212.164.146.33 -72.127.76.27 -175.161.227.110 -109.188.125.111 -37.214.28.182 -47.18.204.217 -95.188.88.59 -96.252.12.181 -46.146.184.148 -178.137.58.35 -125.82.163.206 -95.17.254.131 -24.35.105.160 -105.25.20.167 -109.190.154.241 -46.61.65.167 -176.214.154.115 -37.44.108.205 -71.80.233.61 -210.146.249.98 -50.191.140.20 -172.0.0.3 -188.134.21.71 -178.34.161.187 -176.97.103.226 -69.151.26.205 -36.69.112.47 -231.115.82.205 -128.70.5.196 -178.148.242.143 -77.152.251.48 -217.93.233.117 -128.70.154.103 -24.6.180.172 -52.178.27.143 -79.41.111.72 -50.65.6.66 -213.24.127.152 -105.156.12.107 -24.212.250.140 -91.65.124.228 -176.111.85.2 -75.67.50.181 -107.179.158.105 -97.121.39.172 -211.110.17.146 -110.244.163.66 -83.41.237.2 -177.42.212.90 -42.25.182.101 -41.176.238.223 -83.6.60.199 -192.254.1.3 -63.87.253.252 -105.154.181.129 -42.116.159.209 -173.175.165.35 -191.33.106.75 -66.31.203.99 -47.90.12.41 -254.139.181.166 -123.243.176.125 -98.195.248.66 -114.125.184.21 -131.77.218.144 -99.35.1.162 -2.94.63.28 -142.4.219.166 -37.214.45.81 -91.148.83.250 -108.59.82.117 -66.18.203.165 -184.58.153.145 -90.22.182.176 -129.132.179.10 -77.51.3.171 -93.178.236.186 -104.172.24.79 -117.69.37.113 -89.177.235.232 -46.98.124.46 -101.200.156.61 -54.78.124.50 -49.183.195.52 -94.233.108.155 -178.76.217.3 -88.236.139.51 -182.9.251.22 -108.217.41.51 -78.15.69.11 -1.9.102.15 -83.5.183.131 -146.65.212.78 -72.90.164.245 -37.201.226.29 -76.175.160.124 -2.139.38.182 -75.156.92.90 -162.245.17.64 -46.109.116.120 -31.90.138.142 -70.113.42.136 -87.206.96.153 -187.107.67.31 -151.64.5.115 -81.100.89.197 -254.213.224.159 -95.90.192.148 -213.87.127.244 -188.187.179.150 -153.100.225.76 -119.248.127.237 -104.212.233.142 -95.191.200.245 -218.183.61.75 -69.81.135.130 -86.111.136.191 -96.242.53.68 -0.0.0.0 -79.111.210.168 -50.159.128.226 -76.92.249.209 -73.197.103.142 -73.231.122.49 -237.51.250.49 -71.234.232.130 -50.135.221.200 -88.77.218.18 -81.108.63.108 -223.156.208.226 -83.21.45.217 -94.41.181.212 -69.124.186.230 -217.27.149.140 -104.175.162.231 -77.40.24.110 -124.168.234.94 -24.76.220.10 -254.69.93.71 -203.212.154.201 -37.151.186.123 -130.255.247.36 -84.77.151.215 -68.13.175.20 -179.188.245.56 -87.245.7.194 -80.180.210.65 -87.6.53.235 -208.167.254.202 -91.48.57.13 -50.66.78.155 -86.132.124.18 -159.148.142.59 -46.105.39.103 -188.82.44.231 -93.222.141.130 -198.27.81.25 -5.198.236.43 -101.163.24.233 -77.163.189.107 -77.40.116.92 -76.10.162.169 -87.146.5.203 -84.105.26.71 -106.68.56.66 -103.245.95.63 -180.107.230.128 -183.50.115.22 -189.79.14.213 -188.163.97.22 -75.87.190.13 -46.159.38.161 -27.47.113.178 -220.253.206.246 -84.188.187.66 -191.254.115.148 -94.36.175.249 -191.54.11.197 -190.79.130.213 -31.6.50.60 -81.17.174.82 -76.113.21.208 -180.165.53.252 -77.22.148.6 -14.2.72.165 -205.183.219.247 -69.23.249.169 -185.65.132.100 -37.214.51.246 -185.157.16.38 -0.0.120.138 -205.189.79.111 -194.249.178.189 -24.140.173.50 -79.245.43.123 -93.47.96.158 -92.255.126.227 -83.31.169.166 -183.61.146.133 -31.109.67.191 -0.0.0.0 -90.2.2.115 -219.79.134.55 -94.251.44.201 -87.50.82.48 -83.23.239.91 -90.104.163.221 -77.249.144.34 -180.101.15.205 -39.70.151.104 -225.174.220.177 -70.95.48.109 -62.107.128.88 -94.34.215.116 -70.69.36.146 -36.149.198.139 -93.84.211.255 -217.244.81.231 -171.128.133.206 -37.146.227.226 -79.234.14.227 -177.158.39.231 -114.40.139.95 -107.3.236.173 -78.121.10.157 -70.113.61.111 -161.31.224.170 -83.45.251.218 -192.241.195.57 -176.222.168.20 -173.177.115.102 -50.49.139.30 -24.175.64.146 -73.249.63.180 -92.243.166.74 -213.138.86.15 -198.72.192.74 -146.82.107.4 -79.111.28.247 -37.190.124.110 -86.41.83.192 -11.47.244.249 -82.130.22.224 -90.150.252.207 -92.127.190.145 -217.86.143.234 -14.200.246.174 -197.86.181.90 -91.150.7.204 -178.239.58.248 -112.198.98.69 -217.241.4.70 -78.20.252.64 -46.233.232.251 -178.32.53.131 -200.92.103.84 -179.98.39.154 -82.193.127.191 -23.233.105.183 -42.79.5.88 -109.43.2.219 -73.160.106.98 -91.57.200.156 -94.166.91.220 -89.24.238.25 -104.138.147.122 -62.235.252.43 -62.61.130.225 -156.207.75.152 -79.56.59.204 -81.91.29.19 -180.200.182.59 -78.106.0.191 -76.145.250.114 -73.93.143.14 -194.42.113.83 -190.219.169.143 -129.132.208.154 -188.77.115.58 -159.227.211.229 -178.12.222.20 -89.73.112.158 -90.77.201.224 -79.239.3.2 -128.73.84.157 -172.251.163.17 -76.68.180.62 -188.104.121.98 -217.96.181.144 -81.245.209.201 -91.54.70.154 -170.179.182.45 -72.198.163.2 -81.149.9.87 -115.152.10.90 -176.2.33.156 -107.217.207.67 -189.196.173.117 -58.240.252.231 -178.34.158.126 -129.208.61.192 -109.106.1.98 -209.71.187.112 -176.209.76.142 -89.193.28.216 -46.207.139.233 -81.110.173.243 -5.189.30.177 -85.76.64.24 -180.85.143.49 -109.200.238.156 -86.197.193.139 -171.151.82.30 -160.64.4.181 -68.173.147.35 -62.1.200.15 -213.8.129.147 -14.218.48.242 -125.192.151.221 -178.158.102.90 -83.142.111.198 -201.22.222.19 -63.87.255.253 -86.245.121.184 -80.180.218.21 -51.9.252.248 -168.205.173.177 -173.254.208.98 -87.199.167.171 -31.206.63.127 -22.51.95.184 -178.93.148.210 -78.52.193.124 -104.168.164.240 -93.33.170.142 -24.74.13.140 -148.0.39.7 -190.42.187.9 -27.105.233.173 -213.162.68.4 -79.227.31.39 -112.97.61.240 -80.135.106.20 -62.235.148.101 -99.230.194.187 -98.221.123.38 -58.56.133.98 -247.19.172.79 -108.28.225.229 -81.184.25.104 -181.104.112.211 -188.162.166.158 -79.184.135.236 -188.238.17.69 -190.134.134.46 -95.189.150.132 -194.126.168.60 -76.19.242.156 -130.180.218.219 -104.220.27.24 -142.163.92.14 -182.125.129.10 -73.192.202.185 -60.123.50.87 -118.116.108.3 -184.101.248.5 -50.140.161.83 -101.165.212.53 -87.165.67.175 -209.197.156.241 -85.27.125.82 -93.181.216.82 -71.72.141.237 -70.24.228.204 -91.182.12.54 -136.169.204.151 -177.206.49.168 -113.83.228.172 -88.147.30.116 -71.56.202.226 -68.146.169.173 -89.235.211.85 -41.176.39.196 -147.19.12.189 -104.207.136.103 -60.50.206.232 -178.158.80.11 -71.199.119.181 -191.179.157.158 -242.170.177.252 -141.215.80.194 -82.161.145.68 -89.142.182.169 -82.18.195.64 -70.123.112.130 -179.188.245.56 -176.102.195.216 -188.69.243.161 -83.84.40.12 -220.236.128.177 -109.129.224.18 -100.34.93.150 -149.138.22.140 -82.192.64.136 -186.214.98.40 -108.26.44.16 -108.67.80.117 -37.214.5.252 -209.232.227.231 -196.210.50.104 -183.135.255.184 -177.131.120.30 -62.165.242.162 -41.138.102.202 -104.238.169.89 -104.157.137.70 -89.202.166.242 -131.77.218.144 -207.118.93.73 -87.162.44.24 -0.0.0.0 -110.0.234.132 -62.80.176.70 -80.88.28.137 -178.120.17.194 -146.3.226.203 -67.187.18.63 -76.243.35.92 -70.71.225.144 -37.49.112.191 -98.228.255.10 -14.203.211.216 -70.29.0.34 -109.229.64.106 -180.251.132.210 -90.69.147.20 -60.205.58.32 -96.54.5.209 -80.12.38.22 -92.14.21.218 -80.77.39.181 -88.177.109.119 -196.210.55.253 -66.175.220.212 -119.63.44.133 -77.173.116.163 -121.222.251.158 -88.147.16.221 -105.104.0.66 -77.177.201.1 -201.152.203.38 -31.181.104.136 -130.35.207.72 -50.149.22.101 -128.71.205.191 -192.180.188.36 -177.138.128.83 -72.160.90.78 -98.127.83.86 -77.40.116.144 -146.52.75.143 -93.85.10.226 -86.4.137.92 -213.66.200.33 -27.32.134.220 -73.192.216.82 -46.186.83.147 -93.178.70.203 -75.118.205.52 -91.222.69.111 -97.94.164.127 -85.212.56.36 -24.255.33.97 -120.88.154.161 -5.54.174.76 -37.214.155.189 -69.223.42.70 -179.188.245.56 -151.249.103.245 -160.158.116.120 -52.19.194.56 -86.140.103.156 -89.13.93.55 -83.237.181.184 -95.222.48.175 -77.122.83.9 -67.1.149.121 -50.189.198.168 -75.165.59.73 -187.114.151.195 -104.156.240.174 -95.24.204.250 -189.115.186.244 -95.73.215.207 -66.55.141.100 -77.3.26.206 -89.205.58.251 -92.101.208.231 -180.242.208.9 -167.148.76.2 -109.215.152.195 -77.40.116.6 -71.19.252.27 -188.223.186.210 -254.194.199.151 -83.5.57.232 -100.14.95.93 -71.222.214.25 -50.143.146.148 -46.254.161.146 -81.183.115.115 -82.245.39.252 -193.95.228.71 -99.247.211.202 -46.105.124.86 -82.239.243.10 -117.140.167.99 -86.174.182.223 -81.151.103.4 -188.16.56.69 -37.78.40.173 -99.198.248.234 -46.39.230.195 -191.54.11.197 -208.74.176.52 -149.210.164.198 -131.177.217.139 -143.241.180.26 -183.62.31.188 -209.95.50.98 -46.99.72.69 -87.15.12.87 -155.246.209.18 -63.87.253.154 -188.105.132.220 -46.59.178.196 -146.123.253.27 -46.35.77.137 -37.161.40.225 -88.147.122.169 -114.125.178.177 -190.237.124.123 -174.24.176.235 -221.193.4.156 -217.117.187.211 -79.133.14.100 -188.68.194.123 -85.76.73.104 -173.79.110.56 -174.7.103.195 -68.187.116.205 -175.140.222.112 -37.163.202.87 -78.25.123.38 -31.162.188.97 -120.25.65.234 -213.59.117.212 -181.65.78.183 -172.79.95.120 -109.226.119.128 -111.174.146.100 -179.188.245.56 -119.205.162.20 -31.6.24.148 -188.68.14.26 -37.8.242.35 -118.209.15.214 -80.99.198.172 -100.122.132.37 -223.68.189.53 -5.71.101.213 -195.142.179.119 -90.202.206.208 -167.249.235.53 -114.77.188.214 -93.77.45.35 -135.143.95.62 -79.53.186.83 -63.87.77.227 -188.187.174.168 -120.239.8.85 -97.85.42.177 -89.0.8.108 -74.195.227.225 -198.143.2.132 -177.158.97.204 -92.46.173.216 -90.21.84.137 -72.83.36.246 -83.81.103.227 -5.137.221.215 -182.96.242.53 -96.55.55.197 -109.91.34.232 -31.2.58.76 -37.214.155.169 -60.123.50.87 -173.196.158.132 -87.198.114.90 -191.248.19.34 -105.157.204.237 -206.45.228.163 -213.4.115.211 -156.14.173.215 -192.195.67.2 -83.43.242.84 -87.252.238.253 -185.10.190.231 -95.29.76.137 -87.112.0.134 -92.51.9.54 -61.131.83.133 -180.165.69.238 -90.149.137.180 -24.46.254.139 -74.141.57.154 -95.70.120.151 -104.238.169.72 -87.217.196.11 -76.102.131.234 -87.97.0.228 -94.199.198.134 -73.80.36.106 -91.250.56.101 -1.115.1.3 -137.103.221.168 -149.202.193.188 -71.170.84.181 -198.8.80.45 -178.93.148.133 -93.178.65.9 -68.40.25.124 -24.117.22.32 -25.27.146.66 -212.89.225.138 -49.193.216.83 -86.9.168.196 -37.55.84.196 -193.95.253.142 -104.34.224.200 -174.45.91.255 -93.133.153.104 -53.74.14.208 -80.88.23.87 -37.187.131.169 -179.188.245.56 -184.53.32.170 -104.200.154.54 -104.223.53.135 -195.15.4.67 -180.229.32.135 -31.3.156.112 -178.165.130.31 -107.4.39.143 -67.85.217.100 -178.46.163.75 -213.231.55.145 -203.92.39.35 -104.238.58.22 -74.197.90.100 -75.70.171.6 -77.120.160.249 -65.96.131.178 -40.130.201.131 -130.194.72.84 -75.82.210.101 -149.56.87.165 -173.254.208.194 -58.250.131.92 -166.123.188.107 -183.5.123.230 -46.39.171.197 -5.13.13.198 -84.0.5.105 -7.211.73.100 -77.40.116.212 -76.127.11.146 -176.213.16.21 -64.231.232.206 -23.16.180.239 -172.227.36.209 -5.141.90.117 -66.115.115.71 -151.133.201.86 -70.79.24.232 -82.15.5.193 -199.58.178.132 -116.226.26.241 -107.153.20.121 -84.18.118.84 -88.150.185.82 -174.56.149.251 -212.230.68.200 -142.137.9.120 -178.94.172.125 -69.36.206.73 -90.174.4.95 -63.87.255.249 -177.235.119.100 -184.101.149.91 -117.140.45.148 -79.196.225.142 -32.169.11.9 -78.232.226.226 -177.5.71.225 -178.34.158.160 -176.3.38.9 -77.181.221.137 -93.231.187.186 -114.125.151.18 -70.112.23.16 -128.74.242.207 -37.79.153.6 -179.188.245.56 -95.79.255.196 -189.197.30.89 -113.88.22.241 -69.23.131.145 -24.230.253.14 -178.34.162.233 -231.119.4.225 -46.186.89.232 -78.129.157.196 -125.164.96.193 -213.5.65.29 -187.59.234.92 -112.97.54.124 -178.123.176.79 -109.227.118.161 -90.255.120.101 -95.26.178.188 -46.175.175.206 -65.190.129.84 -37.192.148.86 -198.8.80.171 -174.51.159.181 -196.52.23.228 -110.125.47.10 -177.80.226.192 -92.49.238.145 -81.203.232.36 -213.220.249.220 -73.109.59.103 -85.114.174.176 -109.120.242.35 -188.115.39.45 -112.74.214.212 -99.250.234.200 -37.115.220.137 -73.231.114.124 -46.53.209.146 -77.13.64.136 -85.29.114.126 -90.202.174.218 -180.185.84.249 -76.75.89.197 -33.46.244.82 -63.87.77.189 -218.38.19.7 -175.43.242.156 -95.52.140.49 -77.235.102.218 -186.92.196.71 -178.93.148.183 -83.134.210.164 -97.121.78.125 -217.41.63.179 -41.241.90.148 -86.61.67.64 -37.214.129.10 -117.87.47.179 -2.24.233.99 -162.243.216.227 -93.26.186.20 -109.236.90.144 -171.96.170.132 -84.120.106.33 -94.13.119.10 -72.13.188.130 -82.206.16.181 -74.116.186.220 -67.169.203.50 -46.42.58.166 -178.43.229.84 -37.14.204.55 -177.142.52.235 -181.64.192.105 -37.24.149.231 -215.119.81.157 -24.225.14.35 -219.21.195.80 -87.115.193.174 -189.73.224.143 -93.45.49.68 -79.143.182.116 -89.0.39.201 -202.159.128.66 -24.125.27.47 -115.192.246.185 -161.97.160.204 -179.99.141.139 -50.224.63.50 -37.214.31.133 -88.206.186.58 -108.169.236.27 -84.237.86.24 -162.19.122.33 -47.90.2.35 -31.129.195.13 -107.222.97.179 -134.90.156.49 -108.244.47.41 -63.87.254.148 -171.213.99.156 -171.124.174.139 -92.246.196.101 -192.162.143.75 -75.141.226.201 -100.70.154.135 -1.9.103.7 -69.255.27.161 -217.96.146.146 -0.0.0.2 -197.246.2.143 -65.13.189.227 -194.77.215.7 -89.31.117.250 -0.0.0.5 -5.115.203.35 -146.115.157.45 -162.243.227.180 -79.102.44.42 -49.64.193.14 -89.144.239.171 -166.70.8.20 -131.77.218.144 -81.158.175.156 -70.68.114.212 -93.88.53.63 -81.174.41.68 -82.57.179.8 -151.224.142.140 -82.230.144.202 -86.132.254.124 -165.72.27.149 -5.139.145.97 -201.242.188.234 -46.149.87.97 -23.234.22.142 -178.7.171.40 -90.150.241.152 -67.173.173.74 -91.232.169.187 -177.200.114.97 -142.4.208.32 -203.144.16.52 -79.165.103.230 -147.194.41.211 -77.65.19.242 -121.15.122.220 -67.219.95.103 -91.126.89.184 -186.33.38.5 -84.119.188.172 -114.125.179.112 -63.87.77.189 -72.50.251.132 -78.225.114.147 -83.215.142.159 -88.70.150.29 -121.12.208.45 -122.191.104.50 -198.8.80.92 -81.170.155.133 -74.152.123.100 -31.206.70.27 -84.183.99.23 -178.214.180.24 -177.40.178.34 -91.180.154.226 -187.111.234.136 -5.76.75.218 -70.227.145.252 -77.20.143.147 -203.106.219.211 -100.13.87.171 -188.60.84.92 -203.122.115.166 -188.193.95.80 -65.94.24.50 -37.167.231.160 -109.169.250.98 -109.229.64.141 -2.132.168.188 -31.128.8.221 -37.221.237.72 -31.180.227.66 -95.78.53.221 -128.54.174.31 -93.73.22.239 -75.148.217.67 -222.220.99.98 -50.158.161.48 -172.79.179.32 -89.0.253.11 -93.103.53.134 -78.223.238.225 -94.50.0.22 -190.204.206.81 -83.134.57.48 -63.87.253.154 -185.57.82.82 -91.233.19.241 -34.57.82.147 -172.214.18.253 -216.172.142.11 -0.110.200.142 -2.245.91.207 -1.9.103.155 -205.112.109.107 -188.125.246.149 -104.35.7.243 -67.174.74.165 -24.166.50.124 -2.245.160.249 -54.70.85.2 -70.190.111.248 -179.181.252.174 -41.251.149.122 -27.47.118.14 -14.201.137.152 -83.41.194.149 -50.133.248.247 -89.12.214.245 -175.43.242.132 -80.88.25.191 -71.231.33.235 -78.227.111.78 -94.197.120.218 -231.137.251.73 -70.65.206.59 -202.49.89.68 -186.15.42.168 -188.69.194.108 -95.208.248.130 -79.76.201.195 -113.8.121.236 -86.15.3.52 -5.80.179.121 -88.195.122.166 -110.159.96.102 -79.227.10.114 -82.84.229.234 -36.76.98.20 -114.125.176.195 -78.51.119.166 -125.174.218.86 -84.77.146.155 -35.58.24.31 -115.74.185.212 -46.135.61.3 -76.25.194.124 -80.82.202.248 -184.78.118.109 -151.231.233.43 -46.159.90.238 -178.137.239.114 -37.235.146.166 -67.11.239.1 -103.255.4.248 -173.25.111.238 -63.87.255.155 -185.160.93.175 -37.214.100.137 -75.164.233.17 -178.95.110.28 -73.11.194.236 -36.69.119.70 -78.220.216.75 -78.111.185.210 -63.155.143.241 -178.94.172.173 -68.234.91.117 -86.135.158.126 -95.73.52.198 -90.48.160.48 -213.195.188.133 -68.228.16.214 -164.244.159.137 -41.105.191.46 -108.61.226.28 -77.207.92.112 -178.151.6.20 -36.76.98.142 -69.165.222.140 -97.58.136.16 -75.118.116.50 -191.182.136.128 -31.163.55.26 -31.178.237.110 -99.244.177.73 -178.0.89.10 -91.121.155.93 -194.127.77.96 -206.248.172.82 -217.99.82.246 -151.68.66.143 -89.153.139.149 -37.201.230.118 -201.95.5.52 -201.79.214.0 -218.206.143.64 -80.162.16.80 -201.14.50.216 -98.192.4.26 -32.51.8.120 -77.29.108.142 -151.52.77.30 -93.84.216.92 -82.44.146.33 -78.53.78.152 -197.119.213.42 -147.183.210.66 -185.3.173.229 -191.183.169.197 -2.245.137.183 -91.65.126.15 -182.148.67.82 -217.114.229.49 -98.165.223.15 -68.113.233.62 -109.87.98.126 -67.194.158.32 -70.24.17.143 -73.202.135.79 -79.201.133.169 -69.17.254.58 -65.25.180.22 -114.125.179.68 -254.3.81.156 -79.160.55.30 -173.31.201.187 -176.58.121.112 -87.68.55.213 -173.161.71.38 -107.180.68.196 -94.25.228.15 -124.122.129.211 -31.131.53.15 -169.195.113.223 -72.220.38.235 -84.231.4.13 -188.199.223.30 -182.186.160.34 -25.1.7.162 -93.117.189.198 -183.74.38.165 -5.18.64.210 -77.123.120.121 -177.229.245.106 -36.234.59.20 -100.70.99.29 -84.85.234.220 -115.132.88.210 -92.237.30.106 -122.52.84.80 -74.101.32.172 -122.194.223.212 -0.0.0.1 -83.250.32.201 -188.239.89.43 -86.110.35.134 -186.83.21.221 -67.249.244.99 -171.253.71.129 -176.114.41.138 -24.249.152.169 -46.118.79.153 -98.225.56.230 -77.163.92.80 -75.173.110.74 -115.35.216.91 -138.151.74.156 -1.42.9.21 -24.135.179.191 -68.173.73.213 -193.38.164.231 -211.149.234.109 -53.186.124.223 -71.8.170.163 -158.69.196.61 -184.75.221.179 -37.214.17.200 -31.178.188.94 -109.222.126.128 -37.97.159.116 -98.192.178.2 -89.14.10.230 -77.178.145.18 -50.131.105.103 -174.1.20.102 -31.163.45.85 -142.4.209.20 -213.44.220.12 -178.115.128.70 -190.237.180.151 -71.86.63.12 -107.191.36.26 -171.4.191.111 -77.180.226.208 -126.47.194.63 -132.177.166.224 -209.6.13.94 -209.71.187.95 -98.127.94.104 -176.194.54.26 -95.38.165.156 -211.149.203.133 -125.34.99.26 -212.80.35.204 -181.64.192.144 -128.69.5.201 -77.253.178.185 -66.66.96.55 -37.187.62.197 -5.79.68.179 -162.214.144.232 -75.118.140.166 -46.184.68.149 -118.209.228.40 -25.167.181.129 -101.232.199.107 -183.60.175.245 -83.134.97.92 -213.59.116.93 -108.35.113.160 -0.0.0.3 -204.48.58.5 -82.34.83.145 -75.164.251.34 -93.221.234.206 -191.54.11.197 -77.110.148.100 -71.204.12.71 -71.212.2.36 -112.201.133.20 -115.203.241.14 -80.12.35.100 -213.179.252.227 -171.4.191.111 -81.94.192.39 -186.28.1.249 -27.10.78.74 -14.218.50.43 -157.75.45.18 -188.252.49.231 -100.15.53.74 -84.73.232.94 -73.246.4.233 -78.85.238.101 -37.78.152.207 -144.153.206.165 -71.47.205.43 -118.199.43.9 -61.209.250.108 -89.193.28.216 -172.56.15.180 -173.180.35.59 -60.6.152.90 -87.71.32.150 -178.7.1.50 -152.29.211.220 -181.1.187.241 -107.151.146.18 -50.38.90.86 -78.53.76.85 -91.65.233.81 -24.111.248.238 -43.230.115.113 -46.254.162.62 -81.4.193.138 -65.122.82.65 -215.119.81.157 -108.35.177.168 -92.101.204.137 -212.77.214.235 -216.232.189.109 -86.169.39.198 -58.8.155.168 -68.112.157.91 -149.154.82.143 -121.98.137.146 -2.31.19.169 -80.135.72.241 -178.34.158.177 -83.220.236.163 -85.222.174.131 -94.192.120.77 -160.171.125.185 -209.200.61.232 -69.167.20.21 -94.196.65.242 -176.95.200.225 -72.133.224.210 -81.165.223.134 -79.30.43.137 -11.64.77.213 -117.69.37.124 -81.4.229.54 -179.98.225.18 -176.101.159.159 -37.120.174.32 -172.90.161.27 -31.135.162.117 -217.118.93.148 -43.68.222.229 -142.177.86.19 -95.252.144.144 -71.180.49.190 -31.173.84.149 -84.178.235.239 -119.133.211.12 -173.79.115.216 -60.177.162.207 -185.142.213.119 -136.122.46.135 -254.219.128.7 -167.56.247.38 -136.243.217.171 -47.90.41.107 -69.138.72.168 -73.93.104.132 -108.244.47.45 -110.0.234.132 -85.76.73.228 -83.250.48.215 -66.73.115.64 -37.140.78.86 -69.165.242.216 -73.240.78.63 -95.154.144.76 -212.115.253.181 -2.22.50.177 -161.63.219.19 -160.101.111.179 -83.82.140.109 -112.114.250.79 -31.173.80.23 -204.185.72.3 -104.207.136.100 -107.147.67.163 -84.251.123.206 -5.135.176.160 -112.86.236.240 -68.61.181.236 -181.139.69.35 -81.97.200.135 -85.241.89.210 -181.67.37.52 -164.114.255.173 -188.239.82.36 -62.141.214.30 -95.26.16.140 -42.209.200.80 -218.8.223.179 -217.42.8.13 -73.162.213.147 -122.138.21.239 -185.54.176.242 -98.167.116.215 -36.77.228.67 -223.90.2.226 -82.215.191.78 -218.206.143.64 -27.26.237.178 -27.225.155.151 -179.49.102.185 -101.14.87.53 -93.196.160.48 -143.176.60.186 -50.89.252.64 -1.202.68.46 -71.126.138.139 -188.158.133.253 -166.123.188.107 -51.174.239.234 -67.215.234.242 -76.1.134.36 -52.192.155.175 -84.18.119.234 -79.18.202.147 -121.222.73.221 -158.222.239.15 -179.177.43.162 -245.244.203.252 -146.95.242.153 -188.138.94.6 -86.156.226.66 -90.60.78.18 -151.228.203.83 -189.149.246.159 -183.204.177.60 -134.17.164.102 -67.185.236.237 -186.28.41.137 -96.245.102.206 -77.40.117.225 -86.134.143.53 -189.26.178.186 -0.0.0.64 -93.38.185.182 -180.214.232.78 -177.114.233.126 -92.109.225.38 -151.20.68.225 -49.255.228.150 -191.17.29.196 -114.125.149.172 -74.10.198.250 -87.117.14.188 -167.157.167.178 -69.4.130.106 -1.9.103.84 -254.155.170.131 -94.122.254.101 -212.140.117.196 -91.218.192.254 -1.181.176.1 -37.147.40.195 -85.212.12.143 -114.125.150.132 -67.193.70.129 -50.137.110.171 -118.98.74.149 -36.236.99.199 -222.82.139.110 -189.52.85.213 -121.112.208.42 -80.12.42.213 -73.131.151.71 -86.221.246.54 -73.154.137.10 -168.161.213.249 -142.197.30.169 -84.2.177.43 -208.91.65.91 -112.112.190.4 -187.16.54.162 -95.211.138.15 -101.184.251.38 -182.142.43.177 -85.25.217.233 -68.50.166.6 -89.201.6.46 -184.170.76.217 -68.97.157.47 -29.148.176.21 -253.34.102.37 -188.122.17.106 -100.64.0.89 -84.228.187.106 -125.253.98.143 -5.139.55.127 -194.77.215.7 -172.98.67.19 -188.194.187.126 -95.71.0.181 -187.56.142.137 -82.77.94.120 -139.241.166.128 -52.69.137.234 -78.36.35.83 -58.111.133.220 -171.4.220.133 -95.189.190.104 -87.216.73.94 -97.83.186.179 -120.25.82.229 -0.0.0.1 -109.67.222.205 -91.180.146.248 -37.49.216.254 -182.45.125.86 -85.73.201.73 -132.92.239.41 -37.164.187.157 -88.18.22.169 -193.182.144.63 -88.135.94.147 -81.110.75.241 -80.1.123.53 -192.95.29.153 -95.220.88.244 -112.112.188.194 -31.6.51.49 -100.4.173.207 -185.25.45.46 -101.105.32.19 -37.47.155.236 -24.241.116.254 -179.188.245.56 -71.82.140.179 -115.215.51.18 -71.80.195.179 -178.191.252.18 -61.231.60.197 -46.59.171.28 -0.0.0.142 -82.249.246.200 -87.97.47.27 -188.62.172.124 -91.6.98.40 -188.0.188.74 -79.195.183.127 -31.180.245.158 -23.25.16.149 -108.49.208.179 -97.117.190.119 -52.69.7.50 -253.87.194.56 -77.13.71.77 -99.34.125.115 -166.43.133.127 -147.229.131.89 -177.101.241.42 -201.252.151.49 -31.163.39.220 -86.84.255.120 -82.14.188.95 -73.132.50.37 -91.157.152.223 -70.29.41.215 -83.8.185.20 -180.110.220.196 -70.209.27.44 -157.75.45.18 -58.183.4.214 -79.234.0.139 -87.225.75.214 -253.116.217.73 -235.128.20.67 -68.35.218.223 -66.8.215.80 -212.18.53.63 -115.215.48.197 -37.17.110.193 -79.203.85.172 -84.251.35.122 -61.73.72.210 -79.210.110.126 -171.77.20.16 -184.53.32.11 -217.189.252.124 -117.140.238.53 -24.183.33.107 -80.135.97.247 -72.131.30.33 -87.134.114.216 -185.160.115.32 -91.121.77.74 -201.43.115.207 -177.103.62.111 -92.39.199.238 -151.228.200.248 -85.107.113.247 -170.158.145.240 -165.120.172.217 -92.112.224.28 -113.200.249.59 -73.138.193.253 -60.93.169.83 -97.121.110.16 -86.202.218.31 -83.239.255.137 -200.158.31.29 -112.97.50.124 -69.242.153.187 -114.232.38.157 -178.214.174.216 -104.40.212.43 -182.216.164.245 -87.171.219.248 -124.120.207.153 -217.103.73.143 -106.51.142.231 -211.25.18.221 -89.70.164.231 -92.124.68.237 -109.130.152.173 -83.209.191.200 -15.6.191.43 -78.250.28.168 -82.251.8.238 -178.84.101.85 -14.201.207.233 -217.114.218.24 -77.179.142.212 -41.250.177.207 -62.235.239.245 -63.87.77.227 -91.115.185.67 -79.23.58.90 -105.155.235.244 -211.149.148.151 -178.57.215.184 -80.234.101.152 -72.181.217.90 -86.199.138.253 -188.168.148.238 -254.174.0.233 -50.107.155.144 -5.141.122.230 -109.239.49.207 -74.208.133.18 -2.83.86.10 -97.127.111.116 -68.104.3.247 -63.87.254.89 -49.50.194.74 -60.236.198.201 -183.161.195.249 -71.91.2.177 -92.226.122.184 -138.255.221.36 -63.87.253.154 -94.253.50.178 -212.159.19.195 -92.38.96.94 -151.41.189.140 -25.121.150.189 -185.111.211.234 -49.113.3.148 -72.160.90.147 -68.133.5.18 -73.15.181.118 -171.4.191.111 -92.239.95.120 -66.220.241.138 -109.184.12.218 -95.57.157.86 -69.165.159.4 -1.114.12.3 -79.151.138.210 -31.173.84.242 -59.182.173.53 -78.51.249.222 -5.153.233.50 -63.87.77.227 -12.13.193.226 -106.121.37.171 -82.35.28.15 -109.165.15.183 -114.125.186.117 -42.81.69.211 -82.95.80.121 -68.109.194.64 -113.76.171.156 -117.151.143.244 -165.176.66.238 -178.234.24.73 -2.133.83.42 -31.6.45.42 -188.62.172.124 -92.101.205.105 -187.199.118.69 -46.28.207.25 -5.141.88.128 -87.72.36.124 -86.5.219.17 -123.136.107.70 -174.21.240.69 -83.78.179.150 -178.161.195.243 -188.28.158.229 -151.60.151.172 -190.182.248.6 -85.59.160.162 -187.122.220.36 -67.43.103.242 -0.0.0.110 -118.136.221.0 -49.216.103.31 -115.153.8.95 -89.12.99.213 -84.222.251.243 -75.134.29.103 -92.101.208.247 -173.62.188.225 -109.200.248.23 -92.226.124.165 -193.0.150.215 -173.94.93.166 -5.157.127.25 -201.152.195.28 -95.105.232.42 -109.120.8.198 -85.140.2.237 -79.234.14.192 -87.76.48.72 -162.216.113.202 -174.117.17.165 -217.70.251.133 -186.226.4.238 -116.216.30.43 -174.68.93.191 -87.110.59.78 -75.97.243.43 -184.164.147.82 -50.166.108.126 -91.79.95.254 -93.152.140.29 -87.153.10.251 -83.11.241.98 -124.178.37.111 -94.137.105.252 -2.234.231.42 -122.102.120.14 -110.22.138.153 -80.229.146.133 -0.0.0.5 -77.101.242.198 -77.176.215.31 -67.147.220.161 -87.68.47.27 -174.119.217.129 -31.163.72.108 -254.56.34.109 -104.246.50.10 -169.0.180.167 -37.214.159.121 -85.140.32.148 -213.157.232.237 -5.228.254.16 -169.68.87.71 -193.251.199.74 -93.134.233.56 -79.114.201.200 -95.25.11.132 -122.3.232.6 -37.35.202.126 -108.180.220.182 -94.113.110.166 -162.244.194.217 -72.193.217.148 -0.0.1.14 -62.235.113.235 -67.215.228.42 -67.87.55.27 -125.175.99.248 -75.93.169.201 -93.56.174.191 -67.191.50.73 -209.216.234.233 -91.41.177.107 -60.54.39.103 -149.210.169.35 -177.233.154.114 -191.125.178.7 -60.228.34.85 -14.200.115.30 -94.51.155.118 -109.106.141.54 -217.207.221.148 -0.0.192.18 -59.173.119.99 -104.34.16.248 -31.6.51.209 -78.223.238.225 -82.228.210.199 -78.140.145.204 -172.0.20.56 -77.40.101.158 -150.116.38.121 -176.194.128.57 -217.63.66.209 -176.100.185.142 -81.214.183.78 -77.51.129.215 -134.17.142.28 -191.183.185.38 -178.212.129.67 -186.136.90.152 -98.109.109.18 -169.1.156.117 -95.233.11.213 -74.114.131.34 -31.201.224.201 -67.215.14.106 -73.154.233.125 -151.80.206.105 -151.28.169.241 -78.34.149.97 -68.47.96.9 -186.212.204.252 -254.203.115.98 -217.118.81.232 -95.17.55.225 -84.50.21.116 -91.64.49.12 -46.99.51.224 -89.0.25.155 -98.207.89.152 -131.77.218.144 -24.160.54.59 -183.135.255.214 -2.245.77.239 -176.112.17.175 -188.232.105.1 -221.225.215.118 -218.132.39.89 -187.37.246.193 -201.235.130.141 -188.138.103.170 -162.216.46.89 -180.179.159.84 -124.230.230.109 -101.98.48.226 -177.153.51.198 -85.10.105.215 -85.195.52.90 -190.43.242.28 -85.165.175.23 -80.220.233.195 -37.247.74.122 -74.216.53.45 -63.87.255.249 -86.107.200.45 -41.250.124.244 -160.176.0.59 -37.59.43.20 -172.213.53.116 -213.176.250.157 -0.0.0.0 -221.213.53.114 -151.66.57.27 -83.134.98.230 -195.252.66.164 -84.122.243.22 -76.99.191.1 -188.221.219.218 -93.163.238.185 -83.30.56.1 -89.235.193.205 -120.55.80.212 -180.160.208.238 -86.223.152.65 -208.91.67.210 -5.9.85.14 -11.103.108.217 -176.193.89.71 -72.2.173.59 -111.19.89.24 -89.139.127.139 -69.62.191.21 -180.113.16.75 -70.65.184.2 -85.155.21.252 -205.251.171.136 -86.163.87.41 -73.249.211.100 -173.78.137.215 -83.32.189.210 -125.193.127.160 -213.141.130.188 -109.90.233.211 -178.150.46.178 -96.126.123.143 -185.160.93.175 -223.155.189.229 -42.60.202.210 -86.172.142.87 -139.129.6.134 -184.53.32.91 -63.247.147.166 -81.227.127.72 -68.187.104.58 -77.250.240.247 -93.84.218.136 -79.20.177.132 -25.91.113.253 -166.43.133.127 -68.145.236.222 -95.153.133.128 -81.11.221.15 -177.222.55.54 -109.188.121.5 -82.206.16.181 -200.169.190.69 -52.17.153.30 -145.61.201.188 -86.151.253.117 -123.160.91.203 -70.161.125.201 -88.122.97.63 -45.58.235.215 -85.25.133.20 -92.52.46.192 -37.79.147.28 -176.49.58.12 -95.79.92.81 -93.213.114.163 -98.248.223.158 -155.143.84.52 -2.245.71.45 -94.212.25.44 -91.210.217.236 -92.0.247.245 -200.180.105.149 -14.103.87.110 -104.60.128.188 -219.81.88.121 -114.125.191.35 -154.41.2.78 -89.0.227.251 -73.162.147.161 -77.178.71.82 -175.161.227.110 -213.79.43.89 -77.180.230.9 -188.162.166.129 -83.83.215.161 -182.251.115.159 -5.157.127.9 -178.2.77.70 -177.32.17.30 -5.9.106.132 -69.125.220.19 -137.139.150.40 -91.66.164.90 -125.42.214.46 -100.34.196.211 -65.133.53.103 -60.183.26.161 -186.107.171.14 -178.70.2.31 -91.64.157.58 -83.5.84.249 -101.177.228.206 -217.28.8.217 -94.137.39.21 -186.209.60.113 -79.112.135.7 -58.108.204.196 -69.46.195.222 -98.109.85.249 -178.93.148.1 -143.158.205.99 -58.104.63.171 -77.248.189.104 -72.173.205.206 -82.114.48.17 -31.179.120.196 -79.167.253.182 -108.230.191.120 -173.75.216.132 -2.95.174.223 -91.105.238.172 -68.196.122.205 -92.245.163.204 -241.39.170.118 -83.99.132.252 -172.10.132.218 -31.6.50.196 -58.249.97.239 -50.187.203.251 -59.182.158.38 -89.34.237.101 -101.19.154.97 -87.15.141.177 -96.248.122.64 -109.106.142.132 -50.58.53.206 -91.54.71.195 -25.114.17.18 -59.174.146.0 -78.63.158.220 -71.9.184.136 -5.157.127.33 -213.57.47.20 -189.168.126.45 -46.224.228.235 -229.47.32.222 -88.248.100.82 -85.197.19.38 -115.188.241.78 -31.6.50.95 -78.134.123.108 -109.152.181.20 -86.3.186.97 -68.104.62.36 -78.46.189.202 -119.253.64.38 -194.24.182.27 -254.150.54.5 -31.128.48.7 -176.109.185.70 -184.177.84.234 -71.126.175.159 -169.210.77.243 -94.192.36.236 -79.187.125.210 -74.75.117.59 -50.171.157.120 -112.112.191.165 -213.227.218.12 -78.223.238.225 -200.97.160.153 -136.199.215.163 -69.50.180.171 -94.181.237.248 -128.72.211.244 -78.29.71.253 -73.17.56.135 -187.137.141.92 -107.170.218.161 -24.122.34.75 -67.92.231.9 -164.215.245.107 -84.113.163.33 -87.76.60.133 -178.16.84.239 -146.255.183.137 -185.107.165.72 -207.244.76.221 -72.207.105.140 -95.38.170.40 -93.178.75.250 -77.255.46.168 -162.244.195.40 -151.16.163.106 -98.164.3.225 -93.80.180.153 -72.64.153.101 -178.45.141.202 -183.193.134.145 -217.196.194.186 -131.179.31.62 -88.66.9.87 -87.17.142.17 -81.145.148.2 -65.92.15.105 -90.255.126.133 -151.41.139.205 -71.100.179.172 -77.40.116.208 -77.177.222.210 -178.94.172.138 -123.201.5.103 -143.208.176.2 -5.144.98.76 -95.82.177.105 -199.176.38.93 -206.248.184.220 -37.187.115.45 -13.79.168.143 -109.161.99.181 -24.72.54.78 -119.145.7.57 -93.113.192.203 -178.155.116.99 -33.46.246.221 -128.90.61.238 -50.149.51.96 -74.72.225.204 -77.119.128.8 -77.178.111.213 -185.17.204.218 -192.71.151.83 -169.0.124.8 -71.183.46.106 -115.215.51.5 -77.241.47.222 -186.214.130.111 -0.0.0.0 -24.19.7.146 -201.213.47.94 -118.240.102.196 -195.248.186.129 -74.74.64.161 -71.227.98.164 -85.178.113.164 -183.99.42.210 -109.252.14.160 -127.181.247.52 -212.106.58.65 -170.105.173.75 -83.144.81.18 -184.1.3.151 -31.154.81.26 -68.96.174.79 -23.242.177.47 -90.202.85.19 -84.237.86.19 -76.94.17.92 -95.90.230.89 -220.244.238.129 -230.24.45.148 -81.245.247.106 -78.156.165.8 -78.216.88.12 -80.110.82.25 -123.211.43.41 -26.191.188.74 -37.214.7.200 -37.219.153.191 -216.172.142.97 -24.184.243.173 -178.79.164.165 -99.245.240.217 -iguana_bundle_set: no bundle at [2] -DOGE AUTOCREATE.4000 -new 1st.2 -BTCD.RT1253730 u.2507+c.2507 b.2507 v.2507 (0+230/230 1st.2507).s230 to 2507 N[2508] h.1253730 r.1253730 c.1253500 s.1253730 d.0 E.2507 maxB.64 peers.27/64 Q.(0 0) (L.1253730 2507:230) M.1253729 fa9dcf690dc038ec898789aa123350628f29ec4c2be538f725b2df766b00013e ledger.a80cd39714953dca bQ.61 0:03:39 stuck.0 max.0 -ramchaindata have 2:0 at 0 | 1082 blocks 564.678kb redundant xfers total 2978.180kb 18.96% wasted -new hdrs.txt 472 vs (confs/DOGE_hdrs.txt) 402 -iguana_bundle_set: no bundle at [3] -DOGE AUTOCREATE.6000 -DOGE.RT0 u.1+c.1 b.0 v.0 (0+4/2000 1st.2).s0 to 3 N[4] h.6001 r.4005 c.4000 s.4005 d.0 E.2 maxB.770 peers.1/256 Q.(1995 0) (L.673274 336:1274) M.6000 abdde162c2e54c80948c5395a39f6ca239ae3a0763bf9efbc85a85d01477b1fc ledger.00000000 bQ.62 0:00:36 stuck.0 max.0 - parse error block txn_count.2, n.451 len.-100 vs recvlen.452 from.(146.0.32.101) -EAC 146.0.32.101.block len mismatch -100 != 452 - parse error block txn_count.2, n.451 len.-100 vs recvlen.452 from.(146.0.32.101) -EAC 146.0.32.101.block len mismatch -100 != 452 -DOGE.RT0 u.1+c.1 b.0 v.0 (0+337/2000 1st.2).s0 to 3 N[4] h.6001 r.4338 c.4000 s.4338 d.0 E.2 maxB.770 peers.1/256 Q.(3315 0) (L.673274 336:1274) M.6000 abdde162c2e54c80948c5395a39f6ca239ae3a0763bf9efbc85a85d01477b1fc ledger.00000000 bQ.62 0:01:12 stuck.0 max.0 -DOGE BLOCKS.6250 RECV 3707.250kb ave 607.4 | dup.1057 553.301kb after.3 0.594kb 13.529kb/sec 100.00% ->> addcoin.DGB -launchcoin.DGB name.Digibyte -NETMAGIC dab6c3fa unitval.1e nBits.1e0ffff0 -COIN. serverport.(127.0.0.1:14022) userpass.() RPCport.14022 P2P.12024 magic.dab6c3fa -start.1471732214 -ADD ALLCOINS.(DGB) name.(Digibyte) size 4044312 numvirts.0 -BTCD EAC DOGE DGB allcoins -pend.(4096 -> 256) MAXMEM.4.00GB enablecache.0 VALIDATEDIR.(DB/purgeable) VALIDATE.1 RELAY.1 -launch.0x1ce400008 coinloop for.DGB services.0 started.0x0 peers.0x1ce9de000 -begin coinloop[1] DGB -i.8 m.8 numiAddrs.8 - netmagic.dab6c3fa init.(DGB) maxpeers.256 maxrecvcache.4.00GB services.0 MAXMEM.4.00GB polltimeout.10 cache.0 pend.(4096 -> 256) -clear hwmchain -DGB MYSERVICES.0 -genesis.(010000000000000000000000000000000000000000000000000000000000000000000000ad0f7d7518fc1e90ed28bd0e444ccd8e24d94688355705ed2142006b49d9dd726a62d052f0ff0f1e2459250000) zcash.0 len.80 hash.7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496 ->>>>>>>>>> iguana_rpcloop 127.0.0.1:14022 bind sock.37 iguana API enabled <<<<<<<<< -size.248 genesis block PoW 0.000000 ptr 0.000000 -parsefile.0 confs/DGB_peers.txt -done parsefile.0 (confs/DGB_peers.txt) size.0 -parsefile.1 confs/DGB_hdrs.txt -DGB.PEER CONNECTED.1:1 of max.256! 212.129.1.77:12024 usock.40 -DGB.PEER CONNECTED.2:2 of max.256! 178.33.228.14:12024 usock.46 -DGB.PEER CONNECTED.3:3 of max.256! 157.161.128.58:12024 usock.47 -DGB.PEER CONNECTED.4:4 of max.256! 104.236.32.184:12024 usock.54 -DGB.PEER CONNECTED.5:5 of max.256! 108.61.10.90:12024 usock.48 -DGB.PEER CONNECTED.6:6 of max.256! 66.228.56.115:12024 usock.51 -DGB.PEER CONNECTED.7:7 of max.256! 167.160.36.126:12024 usock.52 -188.67.20.239 -92.110.103.112 -50.181.25.214 -50.76.102.9 -95.71.78.78 -109.228.4.100 -46.244.202.244 -88.3.193.105 -66.87.99.109 -24.224.18.93 -31.50.204.103 -105.158.127.63 -95.208.248.55 -72.171.192.188 -78.55.208.177 -78.8.2.228 -41.251.218.111 -173.28.178.229 -173.230.171.42 -95.211.134.28 -112.215.66.73 -77.173.130.232 -84.82.58.78 -109.145.153.156 -218.250.211.68 -141.211.155.93 -184.147.141.21 -72.191.195.23 -89.14.21.102 -1.0.0.0 -77.231.219.235 -13.92.243.94 -148.244.110.9 -93.104.119.79 -248.245.199.94 -188.4.40.193 -24.76.184.164 -89.75.71.107 -186.146.153.110 -87.217.126.168 -201.37.161.46 -188.162.39.231 -82.196.1.102 -189.140.140.184 -2.85.58.108 -59.49.159.208 -181.57.49.203 -171.149.2.249 -109.158.202.20 -85.165.205.22 -89.245.125.162 -46.70.170.189 -82.131.95.26 -83.38.181.78 -89.216.157.182 -173.210.233.18 -84.135.85.92 -93.128.165.45 -95.103.137.123 -83.243.219.3 -188.131.93.196 -83.22.231.158 -106.216.179.12 -14.192.213.52 -178.120.203.65 -92.249.249.175 -201.242.41.172 -151.228.122.105 -89.240.155.8 -78.8.98.33 -77.85.118.243 -151.15.31.42 -46.0.139.87 -125.160.197.79 -177.9.68.134 -86.31.36.91 -177.39.37.17 -217.235.244.72 -numtx.2 len.445 tmp/BTCD/RT/9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422.raw hwm.1253729 L.1253730 -37.204.72.127 -92.37.46.31 -42.61.166.126 -BTCD Q.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) -42.112.237.73 -87.113.49.184 -93.33.1.88 -115.72.193.11 -86.135.20.143 -95.54.189.185 -82.74.43.190 -109.108.198.27 -50.153.151.32 -94.41.189.160 -50.126.114.236 -86.134.157.123 -92.145.13.111 -189.151.142.230 -108.61.228.25 -201.191.195.235 -113.254.168.141 -193.77.243.16 -220.179.36.72 -62.92.112.6 -78.28.250.81 -94.1.9.162 -197.119.104.39 -181.73.86.156 -188.220.132.161 -81.154.37.205 -114.243.109.38 -80.234.237.54 -124.40.244.90 -200.75.102.219 -190.67.216.182 -117.194.33.218 -85.178.73.121 -94.189.195.54 -42.119.218.128 -178.8.217.246 -79.129.191.41 -76.179.165.105 -217.235.246.193 -62.87.191.169 -105.225.82.183 -197.117.160.173 -31.57.195.195 -112.215.123.103 -188.221.167.127 -50.153.150.252 -96.240.84.92 -24.216.240.158 -159.8.124.180 -88.134.116.127 -176.14.105.238 -186.91.238.219 -119.59.148.45 -91.152.30.22 -223.204.251.231 -217.217.206.202 -178.33.209.212 -14.192.213.244 -190.77.92.178 -190.79.114.204 -41.244.240.53 -72.137.216.110 -95.71.122.120 -92.157.156.178 -90.26.144.244 -84.135.85.92 -188.129.107.92 -91.115.55.194 -101.98.215.166 -78.84.119.222 -81.234.218.87 -77.253.20.26 -49.81.161.1 -95.79.204.23 -189.217.250.0 -108.117.162.252 -24.217.39.5 -88.30.205.112 -174.88.126.8 -68.195.171.102 -211.205.165.22 -184.5.10.222 -79.44.22.115 -2.96.253.212 -180.252.99.168 -86.166.50.110 -84.79.112.88 -190.70.89.83 -118.213.127.232 -90.255.102.242 -63.87.255.251 -250.31.16.246 -115.70.4.78 -42.118.109.18 -71.254.160.56 -84.147.117.226 -72.220.145.211 -27.55.211.239 -189.162.41.151 -46.190.34.42 -151.61.105.117 -145.52.163.202 -88.88.17.50 -159.206.179.155 -24.20.198.24 -116.228.220.90 -128.72.185.199 -120.144.72.51 -78.69.230.184 -114.121.154.67 -188.196.160.204 -178.184.15.205 -87.242.49.243 -156.17.80.242 -69.114.82.72 -89.37.62.17 -180.241.51.70 -2.96.250.196 -50.191.20.165 -86.135.21.114 -83.26.96.53 -83.11.171.209 -109.90.216.94 -95.30.175.90 -173.28.197.230 -83.185.91.165 -125.160.199.117 -99.242.169.14 -93.81.240.99 -200.116.33.70 -5.254.97.76 -74.93.202.189 -111.240.212.81 -85.99.37.229 -197.37.149.32 -25.215.93.124 -177.249.207.13 -83.230.167.102 -151.225.69.1 -46.244.218.156 -87.14.218.26 -45.56.151.21 -86.181.101.168 -87.5.22.81 -37.146.68.48 -192.150.150.4 -178.162.217.145 -95.24.41.110 -213.198.237.54 -78.6.102.70 -50.153.149.36 -45.56.151.111 -83.37.188.164 -201.243.6.169 -146.60.60.174 -46.109.129.53 -5.56.29.168 -87.174.21.43 -88.183.207.177 -95.8.63.0 -190.79.6.198 -50.169.246.145 -73.18.105.88 -46.165.228.119 -189.202.88.14 -178.73.196.42 -93.33.10.136 -76.164.228.226 -186.90.2.208 -188.9.165.185 -54.84.26.112 -109.43.3.224 -75.111.51.213 -75.156.118.46 -91.158.215.5 -50.92.17.249 -46.254.11.158 -119.104.153.35 -79.117.65.63 -134.3.52.202 -58.9.84.79 -71.236.205.20 -36.77.53.226 -189.162.241.66 -173.192.176.155 -186.31.38.190 -68.38.91.132 -186.146.136.133 -104.193.10.252 -81.100.220.75 -190.74.29.208 -148.251.19.213 -171.39.27.99 -113.167.204.14 -5.44.173.27 -128.90.43.127 -86.160.91.44 -74.51.57.173 -5.141.169.226 -187.101.142.19 -89.176.160.79 -188.73.192.57 -151.25.116.38 -69.164.195.142 -83.79.83.89 -148.67.110.53 -83.36.252.241 -119.94.224.223 -183.198.204.209 -75.18.41.253 -68.45.101.13 -201.248.21.151 -79.112.46.242 -209.240.42.164 -202.62.16.184 -37.46.120.8 -197.202.245.82 -86.178.41.209 -90.104.92.241 -36.77.54.235 -186.88.137.96 -73.171.102.18 -174.61.149.195 -90.0.104.178 -190.88.244.75 -193.92.113.47 -5.238.230.209 -179.55.42.75 -85.75.31.235 -219.79.191.98 -63.131.190.227 -93.170.111.72 -83.27.106.105 -94.74.124.50 -95.219.101.18 -178.157.238.33 -85.76.55.161 -173.74.170.43 -79.236.241.93 -73.246.93.168 -81.44.223.141 -214.104.252.143 -120.59.90.181 -187.136.8.147 -79.206.165.26 -90.163.244.24 -188.69.199.38 -108.19.160.97 -88.113.24.32 -79.245.223.4 -76.189.155.179 -198.8.80.42 -178.115.130.209 -31.23.254.160 -46.244.201.131 -93.138.0.190 -37.146.126.21 -177.225.193.106 -86.189.14.29 -190.204.45.31 -92.43.188.19 -118.68.183.197 -31.14.92.129 -37.235.136.34 -201.240.218.44 -187.255.236.182 -186.155.16.238 -158.69.31.37 -2.102.255.77 -188.191.23.100 -90.244.39.181 -66.228.50.86 -79.45.210.96 -178.217.28.60 -188.4.143.63 -95.73.247.153 -23.233.28.199 -178.120.157.94 -87.169.172.89 -178.122.64.75 -1.52.142.34 -23.92.210.2 -41.96.46.230 -212.228.253.143 -176.222.254.161 -185.9.113.48 -141.211.155.93 -195.225.189.201 -130.25.88.216 -24.122.34.75 -72.241.236.178 -5.69.126.45 -116.12.60.74 -200.75.100.33 -36.78.197.169 -213.186.43.35 -80.110.112.148 -31.208.121.209 -190.36.221.26 -125.69.36.198 -218.166.40.153 -90.1.218.225 -0.0.0.0 -109.81.214.244 -0.0.0.0 -145.133.165.175 -187.75.18.65 -79.16.101.103 -186.79.30.184 -2.100.80.66 -81.245.103.159 -49.49.140.58 -213.125.176.82 -88.141.107.40 -115.184.229.102 -188.108.111.118 -177.205.72.70 -41.95.222.186 -193.191.182.129 -105.100.15.198 -189.217.124.237 -5.104.119.177 -95.114.91.93 -39.255.148.136 -187.224.3.46 -2.85.50.94 -67.60.37.68 -217.28.15.120 -92.127.115.141 -222.243.244.245 -99.224.255.173 -100.32.32.157 -63.245.12.218 -190.37.210.73 -90.31.193.71 -189.219.123.4 -71.197.2.127 -1.56.139.42 -178.13.156.31 -27.9.99.29 -67.179.30.187 -2.85.51.146 -114.244.50.22 -84.147.127.16 -83.223.168.28 -118.211.231.131 -151.227.55.136 -188.143.73.66 -79.133.135.189 -109.74.162.141 -94.189.210.210 -104.45.151.45 -176.9.65.41 -1.204.248.148 -88.231.216.214 -95.26.169.115 -73.182.210.38 -176.85.59.61 -0.0.0.0 -46.127.223.159 -5.140.203.56 -213.74.111.185 -202.62.16.44 -94.208.224.23 -5.55.219.24 -202.62.16.185 -87.202.20.199 -188.193.66.115 -2.103.201.46 -113.254.170.53 -66.55.134.215 -79.255.228.15 -190.207.219.55 -82.34.182.46 -86.2.137.161 -85.26.186.57 -185.48.37.18 -163.157.186.231 -144.76.107.81 -85.76.79.28 -92.124.35.133 -195.154.223.134 -214.20.111.167 -81.167.129.247 -103.238.131.9 -116.1.79.170 -213.111.129.137 -80.130.219.93 -41.96.44.147 -142.217.6.115 -125.160.197.79 -BTCD Q.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) -46.0.123.80 -42.115.112.202 -45.74.37.191 -50.247.211.162 -86.31.128.135 -88.152.187.216 -109.81.208.9 -151.246.175.245 -96.19.205.233 -206.255.73.147 -0.0.0.2 -5.45.62.132 -86.172.87.26 -46.127.3.79 -41.13.28.225 -85.23.47.0 -94.214.154.144 -84.147.115.39 -39.48.117.118 -85.253.131.68 -90.171.247.95 -20.221.160.10 -177.204.181.73 -52.160.104.172 -109.202.103.170 -176.101.222.25 -193.140.108.200 -93.34.38.192 -87.188.231.31 -79.88.68.160 -202.62.16.250 -91.156.99.163 -105.226.24.161 -80.106.197.143 -184.58.176.59 -79.203.74.2 -47.72.75.30 -60.50.198.153 -83.78.39.182 -190.202.240.41 -179.182.173.68 -91.141.3.205 -115.234.72.83 -105.229.17.151 -104.200.154.4 -112.198.90.66 -91.241.96.80 -91.213.143.252 -79.46.237.32 -68.7.221.120 -124.237.96.40 -94.237.69.213 -37.49.195.93 -41.150.92.101 -152.7.224.4 -117.93.41.45 -186.93.147.31 -46.208.8.139 -101.175.148.10 -66.87.97.220 -190.177.79.90 -109.149.125.213 -191.182.113.42 -92.124.24.164 -94.66.57.14 -167.114.210.50 -68.186.235.174 -5.80.233.62 -187.200.216.7 -88.3.62.153 -178.65.220.234 -161.10.149.45 -79.203.64.189 -53.193.238.189 -190.37.33.237 -113.64.8.2 -119.250.170.96 -84.57.37.17 -74.12.132.227 -151.15.140.162 -87.123.84.175 -178.21.53.32 -79.245.200.245 -80.106.197.231 -95.145.103.100 -213.87.135.19 -68.247.63.230 -77.243.183.6 -79.41.177.89 -160.76.210.181 -92.236.185.152 -84.138.79.116 -89.67.104.161 -109.126.239.154 -201.29.103.139 -141.169.131.222 -188.196.185.78 -37.193.83.134 -151.33.30.14 -185.46.249.145 -94.66.222.49 -93.137.184.82 -187.143.212.81 -188.246.88.206 -83.22.216.151 -100.68.32.93 -2.134.151.183 -171.96.167.239 -105.107.10.11 -177.11.141.37 -173.75.34.129 -95.252.103.149 -179.55.38.106 -85.62.66.80 -176.94.190.132 -99.115.55.175 -124.179.114.122 -46.229.142.239 -5.164.175.33 -87.105.139.236 -190.77.15.100 -109.169.249.4 -87.64.198.235 -213.151.10.46 -109.130.11.141 -176.108.251.252 -98.90.66.93 -23.102.39.37 -95.91.216.136 -187.74.67.39 -24.65.239.116 -201.243.120.205 -177.39.36.198 -71.31.222.58 -167.58.82.108 -95.211.188.20 -79.245.211.20 -62.158.140.92 -120.56.210.60 -41.96.87.98 -152.234.187.32 -83.18.161.60 -223.207.223.48 -222.222.0.100 -191.111.154.157 -0.0.0.2 -72.186.22.189 -99.199.0.43 -91.141.0.23 -187.170.111.199 -31.201.226.136 -75.192.154.137 -94.109.73.107 -76.26.221.186 -192.252.163.166 -115.87.132.101 -177.39.38.229 -58.109.155.212 -85.114.184.188 -71.91.68.75 -2.222.243.0 -108.24.75.98 -125.37.77.218 -190.207.174.146 -177.148.198.206 -92.37.37.214 -94.23.213.47 -186.89.117.109 -151.66.226.64 -178.162.217.141 -190.203.216.244 -93.117.170.201 -37.187.27.4 -152.251.182.108 -65.19.193.61 -83.29.138.193 -116.86.244.49 -93.136.96.112 -84.35.252.67 -90.110.135.137 -69.36.215.49 -198.8.80.74 -202.29.213.22 -67.188.197.9 -90.202.161.107 -95.211.184.238 -95.99.201.198 -82.22.16.148 -77.243.181.197 -37.113.210.202 -24.224.208.222 -27.0.87.66 -49.224.208.189 -195.240.97.58 -114.250.97.42 -173.245.195.146 -213.137.36.3 -113.135.133.32 -105.233.77.238 -83.7.184.139 -79.112.77.62 -116.49.162.24 -91.105.23.69 -24.196.86.99 -68.7.186.217 -79.16.22.134 -73.24.73.220 -49.102.165.36 -85.192.189.44 -201.209.204.52 -82.57.120.206 -82.249.167.111 -190.252.108.184 -37.113.160.17 -85.115.248.16 -89.12.212.63 -184.180.177.220 -84.43.156.72 -5.238.193.243 -79.133.153.174 -94.209.4.28 -71.15.250.17 -93.129.131.196 -5.71.235.230 -89.182.253.209 -189.62.64.38 -213.152.161.40 -41.105.232.168 -117.64.78.83 -78.47.193.211 -92.110.103.112 -219.108.240.211 -100.119.4.182 -194.44.30.2 -100.87.134.150 -78.0.38.171 -115.178.197.85 -71.194.69.143 -109.173.7.165 -2.85.50.0 -101.98.215.166 -88.3.182.224 -104.238.174.163 -92.146.35.80 -130.125.76.216 -67.204.18.28 -109.43.3.68 -95.73.31.110 -81.4.217.106 -70.29.238.151 -192.153.117.80 -115.230.151.184 -186.116.109.197 -85.214.106.35 -178.44.18.77 -104.207.136.88 -90.58.15.188 -112.208.104.65 -109.93.163.111 -67.32.161.202 -79.184.170.208 -125.162.110.180 -171.250.154.38 -85.76.13.139 -176.69.119.54 -68.188.86.244 -1.0.0.0 -162.199.254.242 -115.87.132.196 -127.208.79.146 -105.225.199.114 -175.137.181.138 -109.121.5.170 -89.16.155.243 -77.106.143.102 -190.51.144.246 -186.36.144.204 -36.77.7.80 -192.226.172.95 -106.51.72.108 -65.78.170.163 -181.49.78.74 -108.216.28.224 -91.48.62.129 -128.71.66.238 -94.70.30.51 -37.214.177.82 -5.220.233.170 -77.46.212.194 -71.47.188.11 -79.208.99.94 -131.94.186.32 -212.112.150.250 -117.79.232.179 -36.85.114.168 -83.9.53.181 -171.149.2.249 -46.98.111.246 -31.135.217.98 -36.78.199.223 -177.135.31.118 -64.214.214.26 -187.252.248.11 -174.52.86.133 -232.139.5.49 -79.24.221.192 -31.173.121.85 -2.218.14.123 -93.151.50.62 -113.254.165.23 -84.26.74.79 -46.196.248.137 -92.177.39.117 -213.137.36.3 -201.185.2.118 -185.45.13.150 -67.86.22.30 -98.225.134.65 -190.201.194.107 -71.1.243.123 -2.30.202.79 -178.221.143.49 -62.68.98.105 -79.204.129.29 -24.126.75.249 -46.164.162.209 -191.36.205.39 -186.14.170.191 -100.68.67.248 -31.132.225.141 -49.196.10.208 -120.144.147.163 -217.235.247.159 -5.141.220.57 -104.156.228.78 -72.220.67.181 -94.190.41.3 -201.51.32.43 -37.112.82.224 -171.96.167.13 -185.3.151.76 -109.167.253.97 -104.200.151.45 -217.95.237.148 -79.30.78.159 -212.228.253.143 -162.156.12.78 -77.79.183.87 -188.36.91.25 -184.97.246.75 -24.114.65.30 -98.167.190.207 -93.47.132.54 -46.28.102.197 -89.38.35.81 -85.150.137.211 -76.18.138.1 -95.153.135.215 -115.64.230.105 -86.133.95.54 -109.43.2.201 -104.200.151.28 -95.237.83.104 -80.236.18.96 -100.69.171.221 -178.223.4.97 -112.215.124.145 -190.192.23.70 -31.53.114.101 -2.125.75.60 -185.132.31.250 -179.55.73.194 -209.128.32.96 -189.81.73.33 -81.141.1.94 -96.245.155.8 -187.71.53.134 -31.210.181.216 -58.179.179.121 -198.27.81.25 -202.62.17.29 -217.235.247.159 -109.200.105.116 -37.212.78.20 -94.230.147.32 -74.129.51.67 -86.95.134.254 -71.79.59.180 -179.232.147.95 -154.98.227.46 -42.116.94.38 -59.172.134.35 -81.155.43.125 -120.25.220.239 -43.249.128.178 -153.163.198.9 -76.27.82.111 -84.161.245.57 -70.197.9.56 -177.205.76.64 -86.178.41.209 -2.217.129.142 -86.115.124.76 -85.192.155.40 -50.23.65.53 -185.65.132.120 -186.88.105.155 -74.110.18.17 -83.131.227.230 -2.122.179.220 -188.69.193.229 -90.1.201.108 -36.228.0.209 -79.116.46.102 -113.173.78.173 -79.235.240.183 -69.55.253.225 -87.185.5.10 -109.222.133.209 -71.97.31.194 -94.205.1.88 -192.0.246.12 -95.153.132.252 -78.225.114.147 -46.65.47.27 -191.242.108.6 -2.25.83.199 -67.219.165.208 -107.153.110.3 -46.166.188.201 -62.210.142.205 -186.93.227.223 -96.31.213.190 -117.81.188.30 -68.42.43.10 -5.14.59.177 -151.238.38.228 -128.70.67.115 -79.50.98.29 -204.210.192.216 -49.237.141.56 -157.161.128.58 -91.48.43.147 -163.172.5.218 -97.107.170.148 -5.71.235.230 -87.112.213.139 -84.6.14.89 -158.181.103.107 -217.253.250.52 -186.14.225.8 -151.227.90.42 -187.189.89.65 -46.217.87.64 -187.147.162.219 -110.115.32.92 -0.0.0.0 -109.43.2.172 -62.84.92.133 -217.235.253.237 -46.98.12.7 -64.238.142.34 -81.153.30.185 -84.135.89.49 -109.208.162.161 -171.96.168.43 -189.208.224.10 -87.146.1.30 -131.170.5.3 -184.147.110.200 -95.24.125.242 -83.87.59.199 -73.148.83.188 -95.141.27.42 -189.187.23.217 -100.3.40.210 -189.144.214.86 -202.62.16.6 -80.30.27.202 -178.40.244.207 -217.235.251.141 -37.14.206.225 -177.32.113.77 -31.10.148.216 -76.97.73.147 -138.186.31.224 -50.82.8.135 -195.208.169.199 -31.215.252.166 -87.102.171.10 -71.220.184.56 -191.34.104.210 -106.51.68.190 -188.27.207.162 -88.217.180.79 -145.249.122.58 -85.241.84.162 -114.125.189.65 -68.118.145.246 -31.5.84.134 -78.8.79.103 -79.245.211.138 -189.27.245.23 -62.210.129.149 -95.153.130.87 -50.203.141.242 -115.87.121.70 -120.24.185.169 -122.169.144.108 -79.203.109.201 -39.36.126.201 -50.115.175.125 -42.115.32.180 -147.102.7.140 -5.141.222.22 -121.219.34.189 -189.250.43.81 -91.48.62.22 -178.64.4.120 -5.42.93.15 -113.254.170.32 -218.10.254.174 -90.26.107.13 -182.87.167.75 -42.3.196.180 -93.205.27.117 -124.122.40.135 -93.3.222.243 -110.137.164.148 -80.233.175.26 -201.248.29.162 -151.250.29.8 -27.55.88.115 -90.191.107.13 -124.171.65.134 -136.19.111.83 -201.4.93.39 -100.96.96.80 -59.60.142.66 -128.75.207.123 -101.40.2.34 -200.82.195.152 -60.36.104.63 -94.68.239.19 -186.241.88.87 -213.10.208.153 -190.201.211.71 -49.15.134.85 -93.208.97.238 -125.164.131.170 -174.136.99.162 -70.21.184.26 -79.19.139.179 -108.24.81.3 -192.169.99.5 -189.203.252.6 -190.71.185.20 -195.209.48.241 -73.194.194.246 -86.128.193.18 -24.246.1.124 -139.192.136.198 -0.0.0.0 -5.142.17.20 -79.250.34.211 -125.253.100.212 -98.226.165.234 -2.85.63.4 -156.35.41.121 -24.157.203.140 -184.65.51.56 -208.167.254.83 -86.145.48.164 -95.53.33.237 -95.25.224.237 -66.115.115.71 -37.110.42.40 -179.43.169.226 -36.77.56.163 -213.151.0.157 -83.110.15.125 -92.24.138.189 -121.97.142.141 -219.73.15.219 -199.48.245.136 -197.37.109.104 -41.96.181.99 -24.207.31.254 -88.217.181.55 -BTCD received.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) 62.75.145.171 -112.215.124.101 -87.185.17.73 -83.81.128.127 -174.116.154.161 -112.198.90.66 -24.6.230.63 -217.30.64.174 -79.107.70.67 -88.232.120.46 -80.135.27.68 -70.51.113.56 -95.17.245.173 -190.53.24.149 -99.121.207.38 -187.10.148.221 -187.113.141.19 -81.141.9.113 -197.202.207.40 -64.237.37.121 -186.89.165.251 -142.217.0.115 -92.54.117.105 -24.36.232.237 -104.156.237.45 -83.61.204.226 -104.245.235.99 -197.229.24.58 -BTCD RTiterate.1 offset.230 numtx.2 len.445 -95.26.99.197 -83.185.84.90 -25.30.29.187 -82.150.59.202 -217.44.16.68 -BTCD txid.(bea6e13bf3e2a8fd110d7dbdbebc381b2e3d41e937e6ec969fb2db3b6659e86d) vouts.1 vins.1 version.1 lock.0 t.1471732213 1 -107.153.110.4 -5.83.18.254 -42.2.89.228 -41.105.224.24 - script type.0 scriptlen.0 -42.203.128.15 -128.71.66.238 -171.5.189.218 -117.52.89.217 -unspent[460] <- 0x1de9653f0 -84.161.57.134 -149.154.194.207 -1 RRjK2yufHUbEBDSBGny9Xgwz8bxiWBC3m7 0.00000000 h 0.00000000, cr 0.00000000 deb 0.00000000 [0.00000000] numunspents.461 0x1de9653f0 -94.68.53.253 -83.238.218.135 -88.232.141.237 -BTCD txid.(5859a4f02452c290a319caa7787bf56df27736ea801bc2d3d8aae852cc2ff23d) vouts.3 vins.1 version.1 lock.0 t.1471732213 1 -37.79.166.32 -111.69.249.244 -79.245.200.98 - script type.0 scriptlen.0 -219.79.24.40 -114.221.101.214 -unspent[461] <- 0x1df020700 -46.172.223.168 -189.214.6.82 -86.216.248.101 -1 RRjK2yufHUbEBDSBGny9Xgwz8bxiWBC3m7 0.00000000 h 0.00000000, cr 0.00000000 deb 0.00000000 [0.00000000] numunspents.462 0x1df020700 -190.236.62.194 -114.215.108.16 -78.12.45.89 -188.29.165.91 -21201.209.186.95 -104.129.28.138 -0290.26.80.8 -88.207.15.213 -cf189.33.207.221 -90.231.249.237 -128.68.191.167 -b380.107.67.242 -125.205.241.137 -3e79.245.220.195 -53.193.239.40 -e4202.62.16.79 -aa181.62.175.109 -85.212.88.66 -5080.215.234.95 -83.5.157.96 -213.24.135.217 -c237.24.152.116 -96.51.33.189 -93.116.236.201 -ad254.159.87.143 -119.247.152.218 -51201.210.134.209 -190.205.77.192 -0f5.254.97.91 -101.191.38.98 -193.92.193.216 -ee189.157.62.249 -24.112.51.69 -8378.194.124.49 -79.44.244.208 -cd91.61.91.168 -190.206.173.34 -7782.176.210.145 -116.14.165.116 -58190.219.122.15 -143.48.117.192 -6a178.234.120.45 -0.0.0.0 -1788.254.73.55 -128.72.218.191 -6278.226.118.202 -83.254.56.120 -fa254.107.115.127 -94.132.250.81 -24177.134.15.73 -88.75.246.64 -69190.72.183.146 -1a78.43.75.120 -185.19.23.255 -188.67.232.196 -9f177.158.244.187 -167.114.210.50 -2d109.221.4.90 -50.100.47.236 -e3178.254.189.80 -218.18.250.73 -104.200.151.35 -5e219.73.12.245 -99.231.166.10 -7b5.141.203.4 -79.101.223.117 -1579.245.200.242 -93.104.125.110 -1781.182.88.122 -83.36.209.130 -2846.59.37.170 -90.191.107.13 -c9180.242.27.12 -187.212.0.46 -8c78.8.11.132 -92.80.241.212 -ac148.240.4.249 - script type.12 scriptlen.35 -77.218.228.54 -93.170.111.46 -45.18.172.187 -217.253.224.100 -179.34.61.194 -95.211.188.21 -24.114.54.208 -91.48.40.244 -50.141.78.149 -2.24.124.97 -88.254.126.246 -36.83.169.217 -93.220.95.29 -46.198.202.96 -81.141.23.236 -1.190.67.181 -182.165.46.188 -188.246.79.155 -79.183.22.252 -122.105.192.219 -190.201.165.99 -199.48.243.62 -115.66.217.157 -178.234.10.109 -5.165.99.135 -95.159.217.77 -148.198.187.153 -89.142.190.82 -178.168.98.175 -68.197.64.6 -113.254.165.210 -77.54.234.91 -107.182.228.5 -14.192.208.7 -84.105.251.196 -59.58.245.158 -110.168.231.209 -86.176.46.245 -186.90.170.255 -121.214.138.124 -79.245.207.48 -91.221.191.67 -31.132.225.141 -185.38.0.66 -179.55.38.56 -82.176.12.130 -82.240.26.30 -114.244.63.142 -201.242.169.121 -201.242.65.143 -24.224.18.228 -178.59.210.188 -151.80.206.110 -178.0.4.123 -200.84.239.151 -193.191.182.129 -120.144.12.147 -5.89.197.88 -113.254.165.199 -140.168.246.252 -188.134.46.175 -202.62.17.29 -80.215.178.164 -178.234.138.208 -109.43.0.79 -112.198.77.150 -79.40.96.252 -81.141.8.117 -217.235.251.238 -78.137.13.183 -79.204.185.44 -181.208.17.17 -188.73.193.11 -172.206.235.188 -45.18.172.187 -95.137.245.107 -113.187.0.202 -95.113.55.151 -92.102.77.39 -54.84.114.124 -92.127.0.85 -87.185.27.131 -115.87.57.186 -81.141.9.194 -27.130.69.137 -69.167.27.161 -79.19.139.179 -unspent[0] <- 0x1de965ab0 -186.104.194.203 -79.245.219.154 -1 RV6H9qZuGy1wPeNeLisvdAeo44ZhgNdWZF 25.18000000 h 322.37935027, cr 25.18000000 deb 0.00000000 [347.55935027] numunspents.1 0x1de965ab0 -95.153.134.7 -46.246.53.6 -2.85.61.30 -87.20.19.191 -109.74.173.65 -2189.237.21.10 -1.0.0.0 -0285.178.67.47 -87.245.50.14 -cf109.172.15.13 -110.184.11.142 -94.242.253.47 -b3148.101.58.204 -179.148.153.247 -3e86.184.140.225 -69.164.198.161 -95.89.172.77 -e4131.246.225.154 -185.54.176.240 -70.52.148.148 -aa213.55.176.159 -177.133.204.246 -217.71.45.241 -50186.214.224.142 -158.255.208.153 -116.252.202.50 -c2198.98.118.241 -189.230.248.129 -5.138.217.118 -ad178.223.29.34 -76.214.117.231 -142.217.13.41 -5124.86.110.55 -104.156.240.159 -89.182.54.95 -0f223.204.249.139 -46.147.5.238 -ee91.48.57.111 -88.241.49.194 -83190.207.231.49 -178.121.115.104 -190.80.140.20 -cd53.193.239.184 -98.124.243.45 -7766.25.183.201 -85.175.20.156 -89.178.7.220 -5841.105.238.117 -46.5.17.18 -120.164.44.57 -6a23.19.99.99 -186.92.215.94 -17178.234.212.119 -109.76.80.59 -6277.168.118.113 -84.55.21.83 -155.138.228.234 -fa37.235.146.166 -87.1.100.199 -219.73.15.54 -24184.166.27.254 -79.245.215.231 -0.0.0.0 -6989.243.57.163 -188.67.255.22 -79.204.180.184 -1a95.141.28.122 -83.152.218.44 -9f201.29.97.210 -2d79.102.35.55 -114.23.246.230 -e381.162.122.102 -46.167.64.6 -5e77.172.117.134 -66.188.53.149 -118.208.67.20 -7b49.248.141.218 -62.113.202.175 -89.88.92.232 -1599.230.140.54 -124.200.255.10 -217.118.83.145 -17180.213.84.12 -79.245.218.167 -79.245.216.198 -28190.37.151.167 -74.87.88.186 -103.11.51.223 -c995.78.56.67 -121.141.52.83 -8c190.204.33.20 -178.120.96.199 -89.70.125.85 -ac91.150.150.10 -95.153.135.34 -46.159.211.91 - script type.12 scriptlen.35 -82.208.124.9 -187.79.201.156 -189.223.24.154 -unspent[1] <- 0x1df021380 -216.144.236.178 -183.44.24.92 -109.88.174.139 -1 RV6H9qZuGy1wPeNeLisvdAeo44ZhgNdWZF 25.19561271 h 322.37935027, cr 50.37561271 deb 0.00000000 [372.75496298] numunspents.2 0x1df021380 -217.71.46.52 -71.234.30.181 -45.56.148.19 -96.126.114.208 -219.90.169.227 -91.127.155.195 -152.236.18.53 -196.210.126.224 -78.173.51.220 -89.179.246.179 -1.0.0.0 -78.12.56.55 -186.93.42.117 -188.0.47.153 -213.103.202.73 -181.39.238.154 -189.13.228.11 -104.228.212.114 -216.144.236.234 -95.174.118.136 -5.254.97.75 -189.205.155.95 -162.219.176.251 -117.207.3.59 -79.206.172.204 -14.28.137.110 -91.158.214.192 -36.74.241.234 -151.238.70.86 -83.132.173.152 -62.4.196.157 -93.143.130.111 -193.186.75.63 -178.128.103.21 -188.67.35.161 -83.32.1.155 -109.74.155.246 -178.33.209.212 -88.71.238.22 -70.75.235.215 -104.200.154.25 -78.35.142.98 -89.212.229.112 -50.71.224.43 -119.76.74.173 -86.174.218.202 -216.231.140.113 -130.120.193.9 -95.106.184.230 -190.74.248.142 -37.113.132.32 -223.207.201.112 -36.78.195.142 -72.131.109.127 -50.46.209.204 -120.180.45.219 -118.232.25.14 -183.18.203.23 -104.156.240.206 -223.255.231.154 -182.249.242.1 -173.230.40.101 -213.176.245.198 -202.62.16.164 -104.207.149.1 -79.184.49.72 -78.238.254.189 -177.39.36.198 -187.149.224.11 -78.137.13.162 -5.141.220.191 -37.213.209.241 -188.105.65.2 -24.76.205.4 -84.19.166.59 -68.9.115.43 -36.83.38.210 -78.85.255.60 -186.36.78.101 -111.106.184.29 -69.172.159.46 -1 RV6H9qZuGy1wPeNeLisvdAeo44ZhgNdWZF 50.37000000 h 322.37935027, cr 50.37561271 deb 50.37000000 [322.38496298] numunspents.2 0x1db5c0830 -174.53.83.127 -89.164.158.156 -186.116.109.197 ->= RTnewblock RTheight 1253731 prev 1253730 -59.45.80.70 -186.151.63.70 -BTCD received.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) 62.75.145.171 -67.141.24.177 -186.212.213.173 -201.208.230.192 -87.158.141.2 -84.236.0.48 -223.204.241.22 -67.0.16.80 -104.230.82.88 -178.12.104.141 -64.219.84.21 -41.105.241.176 -54.165.27.102 -186.90.4.216 -173.199.65.48 -37.23.144.85 -82.232.14.27 -46.146.133.151 -176.65.127.64 -2.87.62.80 -173.189.166.149 -186.94.18.103 -95.81.195.38 -99.224.242.213 -223.204.242.4 -178.128.79.128 -31.181.197.19 -60.26.198.94 -79.167.251.27 -222.230.78.84 -190.255.14.124 -150.254.137.21 -180.252.107.21 -93.168.54.86 -254.198.167.212 -36.76.40.152 -121.45.12.104 -87.189.108.93 -39.48.56.63 -202.62.17.244 -78.10.239.51 -66.57.162.154 -112.66.50.86 -88.13.185.135 -178.223.12.7 -49.199.160.43 -70.44.97.147 -191.223.60.22 -84.198.202.93 -201.229.73.182 -82.169.246.212 -177.114.215.199 -223.204.246.82 -27.34.30.7 -190.201.29.210 -184.146.154.164 -145.255.21.14 -162.255.117.106 -181.73.86.156 -76.65.62.190 -218.142.99.184 -211.186.254.91 -67.140.13.51 -167.56.119.30 -174.77.224.21 -189.82.147.136 -77.243.183.105 -75.61.109.29 -46.31.38.113 -213.114.131.16 -24.166.104.143 -219.79.25.40 -78.35.139.197 -83.4.180.229 -184.5.8.134 -91.77.226.227 -41.96.65.27 -80.213.211.183 -0.0.0.0 -100.68.7.223 -77.51.51.85 -79.185.197.97 -89.117.26.93 -113.254.169.206 -46.190.63.53 -190.38.26.230 -109.228.149.33 -189.114.232.39 -83.10.98.169 -86.46.62.112 -103.254.148.9 -84.86.163.70 -112.198.90.3 -189.223.10.118 -174.92.36.11 -98.195.116.168 -112.198.100.11 -178.79.159.234 -86.159.35.225 -79.107.73.84 -0.0.0.0 -114.220.77.71 -171.96.167.117 -88.230.39.45 -187.170.156.12 -176.9.61.40 -84.154.93.193 -62.176.13.153 -37.161.62.109 -171.96.167.157 -85.26.186.30 -37.189.25.190 -110.168.232.103 -138.186.31.199 -89.178.177.95 -98.204.235.141 -171.96.167.66 -5.70.192.218 -223.225.157.133 -1.65.140.21 -70.197.4.246 -43.165.193.4 -93.137.123.103 -96.240.92.38 -77.222.113.102 -73.243.21.197 -182.249.242.24 -31.53.121.172 -89.18.181.101 -149.254.49.93 -208.54.38.181 -85.222.168.41 -177.228.70.157 -25.87.60.111 -109.79.186.146 -33.212.156.47 -201.208.169.134 -24.135.35.202 -5.184.57.137 -219.73.26.172 -108.81.43.50 -67.136.44.155 -88.217.180.105 -198.8.80.85 -95.24.99.127 -188.198.90.231 -100.88.8.110 -212.224.76.87 -78.225.56.77 -223.73.100.116 -198.14.244.224 -82.12.235.3 -77.243.183.25 -79.102.32.183 -2.102.223.238 -164.127.106.144 -79.54.215.101 -178.119.76.144 -77.7.151.32 -186.95.54.108 -109.209.255.250 -90.153.118.51 -181.113.99.121 -83.83.156.158 -2.30.40.79 -187.147.58.142 -193.168.1.102 -114.92.103.127 -81.44.47.135 -84.103.165.167 -179.54.78.187 -211.162.34.197 -0.66.235.206 -213.119.47.44 -152.250.88.148 -92.140.7.202 -2.85.218.25 -59.167.185.184 -71.84.43.181 -178.27.122.63 -116.109.234.74 -201.29.110.137 -50.81.122.236 -46.139.162.104 -190.38.76.64 -108.73.25.52 -5.2.66.120 -109.88.174.139 -185.45.13.149 -84.19.166.58 -172.15.0.107 -200.109.173.48 -82.3.89.105 -106.187.93.132 -71.127.232.3 -108.61.199.17 -92.157.132.151 -93.135.177.166 -118.68.183.197 -79.245.204.58 -70.59.17.67 -176.27.24.255 -174.0.80.58 -86.105.208.208 -69.130.145.90 -94.21.136.99 -93.70.165.126 -186.244.214.184 -70.208.6.72 -110.115.39.1 -177.134.11.43 -201.242.105.167 -66.87.97.216 -13.82.55.134 -24.204.194.99 -80.215.204.11 -81.37.70.35 -152.78.159.104 -210.117.92.53 -95.160.151.93 -2.221.77.195 -78.190.40.174 -114.125.189.252 -186.101.219.243 -79.114.2.189 -95.131.177.10 -174.126.221.216 -91.7.46.221 -187.234.38.167 -25.60.76.161 -91.139.221.236 -82.140.203.198 -201.208.217.173 -94.253.158.247 -205.220.163.91 -88.137.69.182 -216.186.236.171 -187.255.243.31 -190.75.169.137 -101.116.48.219 -217.71.45.38 -181.49.78.74 -155.138.230.198 -41.105.239.184 -92.156.199.252 -192.214.119.58 -162.216.46.105 -95.73.119.160 -181.51.139.104 -109.88.139.108 -174.58.201.144 -85.139.251.113 -173.65.180.70 -173.74.166.180 -68.252.8.213 -25.45.28.229 -175.155.181.198 -209.188.41.47 -13.92.176.214 -128.69.235.138 -100.74.170.249 -79.40.147.80 -180.248.225.211 -46.188.125.237 -141.134.92.64 -190.38.128.4 -1.204.13.122 -124.122.58.68 -172.77.23.103 -177.96.173.98 -181.167.138.145 -5.101.96.124 -210.146.160.42 -94.109.99.175 -93.232.125.163 -84.74.174.199 -88.217.181.126 -42.112.94.187 -69.231.32.212 -37.187.27.4 -95.94.90.176 -175.39.47.204 -41.244.243.113 -217.253.210.45 -87.112.147.66 -78.137.11.16 -178.205.63.24 -86.20.7.201 -203.98.92.90 -90.198.172.54 -88.184.162.93 -41.251.127.5 -5.140.151.235 -83.55.112.89 -114.88.20.31 -80.107.28.73 -209.222.18.59 -210.55.212.21 -189.26.142.10 -164.132.114.152 -85.2.192.58 -37.29.88.98 -188.0.41.32 -180.140.28.245 -212.54.195.10 -197.5.8.74 -180.183.82.151 -178.234.227.61 -95.26.126.37 -1.162.58.141 -175.38.196.103 -85.178.86.218 -165.255.209.173 -94.96.72.32 -5.107.185.176 -83.254.46.122 -184.75.212.106 -74.37.253.136 -2.85.189.49 -37.191.165.193 -79.30.200.54 -197.246.171.176 -82.170.44.250 -46.153.181.49 -78.150.5.84 -90.191.99.12 -23.253.50.163 -109.43.2.51 -83.52.88.212 -81.153.142.238 -37.140.122.89 -110.168.232.154 -185.132.31.70 -81.230.143.200 -201.199.205.220 -198.144.157.113 -219.141.185.129 -171.4.193.144 -87.178.160.210 -121.206.126.21 -177.205.17.74 -79.24.64.63 -49.145.241.19 -83.61.88.205 -189.251.27.103 -190.204.35.44 -178.79.41.195 -185.3.135.82 -109.93.171.166 -91.14.34.70 -173.189.165.44 -82.176.217.214 -83.58.96.125 -201.22.42.227 -186.31.38.190 -178.234.117.58 -186.90.84.129 -41.13.94.190 -188.19.174.10 -87.105.113.85 -212.255.255.216 -193.51.6.5 -188.252.211.72 -191.33.44.16 -84.77.116.152 -84.195.192.97 -199.48.245.187 -148.31.163.57 -109.74.170.77 -176.65.127.95 -176.86.236.251 -2.81.35.223 -91.64.101.150 -56.26.14.187 -147.30.158.158 -189.70.85.114 -79.145.57.93 -8.144.96.247 -171.96.167.30 -198.14.250.141 -213.111.179.40 -37.146.238.207 -1.54.59.157 -177.33.80.128 -75.76.66.211 -107.170.138.159 -91.48.50.43 -46.121.67.177 -84.147.119.76 -121.214.119.39 -81.202.115.42 -36.77.37.99 -142.176.53.89 -68.68.99.197 -171.149.2.249 -78.0.2.28 -75.152.212.205 -87.112.49.81 -190.204.138.145 -186.91.34.215 -79.245.206.218 -87.117.38.224 -100.67.2.192 -212.54.218.233 -171.149.2.249 -86.177.241.129 -68.229.235.123 -70.98.142.254 -2.62.48.147 -117.151.174.71 -85.25.200.102 -37.6.118.149 -176.217.230.27 -189.159.80.196 -95.28.56.184 -99.244.51.28 -90.136.151.55 -5.167.170.167 -98.28.128.199 -178.234.73.55 -176.69.119.54 -104.42.224.48 -39.35.109.251 -217.95.238.41 -85.115.248.49 -202.161.24.232 -173.219.77.171 -95.133.238.251 -105.156.36.240 -160.81.171.46 -96.83.29.78 -64.62.201.6 -201.210.253.39 -187.253.36.222 -107.197.166.48 -91.182.134.93 -154.122.77.205 -95.94.22.12 -213.87.126.149 -171.97.201.79 -201.205.37.36 -108.6.244.111 -165.91.74.108 -89.12.186.187 -95.105.179.120 -79.245.194.135 -53.193.239.158 -91.150.105.103 -1.178.246.229 -146.60.52.80 -93.134.122.186 -76.73.3.178 -2.187.202.96 -213.87.120.151 -171.149.2.249 -24.115.186.59 -67.248.113.187 -162.243.72.148 -188.162.238.144 -77.46.104.150 -151.236.243.19 -1.162.98.165 -84.236.82.109 -177.112.244.104 -46.59.178.254 -75.97.59.130 -187.143.152.243 -88.198.34.136 -119.224.16.252 -194.126.91.135 -105.236.200.24 -150.101.96.8 -109.133.158.114 -188.38.20.253 -2.96.162.96 -193.92.20.199 -178.234.232.56 -208.107.40.102 -45.56.39.12 -109.72.232.52 -104.156.228.86 -74.242.207.146 -203.87.201.150 -31.163.171.61 -82.211.60.143 -49.144.46.25 -95.134.62.105 -110.168.232.253 -89.164.200.11 -213.179.252.75 -77.28.221.221 -53.193.238.2 -178.115.130.126 -36.83.63.4 -130.25.45.30 -122.62.209.126 -91.125.251.114 -94.25.171.140 -223.73.103.224 -95.109.87.61 -93.81.56.225 -188.162.15.1 -193.253.37.245 -2.61.133.195 -87.143.227.193 -74.69.195.164 -78.148.161.220 -188.158.169.194 -78.36.111.52 -98.238.145.154 -178.216.252.11 -37.229.96.2 -62.74.26.240 -209.54.7.184 -96.126.114.208 -173.183.76.104 -36.76.4.71 -172.98.67.40 -213.5.163.102 -63.142.161.25 -62.31.208.119 -192.0.194.24 -179.212.185.123 -179.156.221.228 -162.17.238.97 -25.212.159.235 -71.190.69.95 -94.13.182.188 -151.224.181.140 -104.156.228.79 -86.81.111.103 -180.159.137.110 -75.189.135.43 -12.133.228.183 -89.164.225.231 -217.95.250.194 -108.6.204.184 -5.220.228.6 -2.134.174.247 -74.111.201.30 -85.23.36.108 -46.229.173.230 -50.159.60.56 -0.0.0.0 -120.209.131.70 -94.214.154.144 -24.19.34.151 -2.240.75.231 -190.211.210.173 -110.168.232.46 -100.36.231.56 -52.169.229.251 -84.27.153.252 -79.208.127.61 -88.19.208.245 -104.207.148.231 -113.254.169.78 -106.201.17.46 -104.156.228.115 -81.96.92.136 -24.135.13.180 -190.79.128.30 -87.6.44.211 -92.124.56.6 -121.98.132.121 -79.235.240.183 -37.113.168.57 -68.12.3.89 -0.0.0.0 -94.22.75.142 -209.188.57.202 -76.169.236.235 -190.203.14.155 -186.188.89.194 -178.198.214.231 -113.173.78.173 -189.105.227.187 -37.113.168.76 -31.54.226.182 -5.232.19.45 -79.233.162.230 -83.162.243.231 -86.151.81.47 -184.2.186.230 -79.16.139.147 -173.21.141.204 -39.48.143.86 -37.1.128.188 -128.90.88.154 -46.166.165.39 -71.177.2.102 -173.80.52.199 -69.253.5.33 -178.216.190.113 -201.248.244.231 -79.173.62.191 -5.151.152.144 -186.95.154.86 -118.68.183.197 -104.237.143.215 -79.51.92.72 -71.52.48.4 -188.29.164.13 -174.71.59.223 -219.73.93.18 -79.245.222.47 -124.122.52.91 -36.237.28.108 -130.180.219.150 -94.139.17.207 -250.31.16.246 -79.245.217.68 -79.204.141.9 -200.84.64.62 -124.168.172.177 -177.228.7.57 -84.198.17.157 -178.122.204.244 -78.147.75.63 -104.250.122.42 -46.253.253.126 -100.64.10.106 -95.81.213.232 -78.132.70.52 -151.228.27.238 -95.103.235.87 -37.214.14.94 -209.95.50.25 -97.121.165.49 -201.192.161.241 -95.24.214.142 -50.102.186.96 -124.197.6.10 -50.151.76.89 -77.173.22.8 -162.255.127.179 -222.65.218.221 -74.141.80.174 -151.227.55.136 -90.207.63.129 -190.204.34.118 -78.88.29.120 -31.51.151.170 -31.170.106.199 -188.32.207.210 -172.56.7.118 -184.171.212.55 -178.92.103.221 -92.40.183.177 -179.156.218.183 -93.190.139.37 -125.185.242.142 -91.67.130.158 -81.146.57.180 -60.205.112.102 -205.220.163.91 -88.254.110.55 -212.14.208.27 -1.39.60.213 -12.37.199.41 -108.61.221.226 -112.80.127.215 -96.46.195.24 -37.146.122.20 -41.224.164.213 -80.107.16.189 -79.147.214.108 -67.53.205.187 -115.28.42.60 -67.136.44.155 -84.3.93.11 -79.52.3.121 -62.46.200.51 -87.178.184.126 -188.245.241.79 -95.39.196.110 -73.43.102.217 -83.61.94.153 -111.88.32.19 -220.246.221.8 -186.91.83.87 -120.155.176.207 -183.149.49.252 -123.63.144.247 -93.34.34.141 -189.69.214.201 -31.11.78.216 -67.231.54.138 -213.140.237.233 -37.140.99.18 -109.226.90.179 -5.15.206.164 -172.248.91.252 -167.114.42.94 -213.16.190.75 -87.244.147.84 -106.187.36.44 -171.97.223.159 -24.121.46.171 -85.93.207.253 -216.58.118.36 -89.242.139.28 -178.0.4.123 -95.89.214.31 -85.76.102.200 -82.169.206.126 -78.150.3.98 -217.113.237.234 -71.208.235.223 -188.196.95.176 -80.249.81.117 -5.164.188.41 -31.185.4.33 -96.240.81.144 -181.44.114.97 -78.132.24.222 -178.216.120.222 -78.98.71.27 -78.43.68.161 -108.61.169.107 -186.147.161.15 -90.218.109.93 -0.0.0.0 -217.129.236.80 -77.105.50.192 -62.101.183.24 -188.76.15.37 -180.172.140.92 -115.198.14.122 -81.100.220.75 -190.77.15.100 -37.47.18.5 -213.122.124.131 -77.54.234.91 -93.143.214.74 -171.5.182.161 -198.254.204.153 -81.250.103.220 -179.43.151.66 -105.226.137.23 -95.43.216.3 -23.92.218.130 -79.166.4.165 -96.252.50.154 -205.220.163.91 -115.25.138.225 -43.249.129.196 -176.214.137.187 -101.98.185.172 -178.18.110.174 -94.20.241.217 -200.117.136.218 -201.4.93.39 -63.142.161.9 -77.243.183.20 -49.177.161.18 -196.217.160.51 -186.146.153.20 -23.241.17.48 -85.7.164.87 -37.151.42.182 -37.29.88.7 -84.35.203.85 -68.172.226.49 -96.240.236.32 -72.39.10.246 -92.76.239.3 -98.160.114.23 -77.254.100.185 -109.209.194.113 -130.211.249.48 -189.202.71.152 -82.103.141.140 -178.234.237.26 -14.192.209.247 -37.146.127.155 -134.249.158.190 -81.141.17.139 -79.146.10.254 -188.158.185.100 -171.4.186.77 -188.104.80.117 -151.55.15.80 -77.105.16.104 -217.189.224.20 -75.110.29.6 -99.120.77.119 -213.10.246.244 -81.10.149.108 -122.168.251.156 -188.208.112.70 -92.76.72.105 -79.184.14.112 -83.57.76.197 -91.48.48.77 -92.80.28.97 -179.4.168.182 -81.196.245.79 -217.235.255.172 -85.75.102.179 -173.74.166.180 -78.3.55.85 -116.89.62.24 -25.7.70.98 -188.129.87.191 -108.127.162.82 -174.5.185.35 -178.234.216.61 -201.143.101.125 -88.229.80.202 -85.26.186.204 -188.0.41.208 -115.87.211.67 -101.160.57.60 -79.114.108.172 -67.140.66.136 -176.50.134.28 -182.89.227.143 -128.90.88.111 -188.208.112.70 -217.235.255.224 -79.204.163.11 -160.176.69.211 -189.187.115.138 -197.203.78.235 -95.141.28.169 -172.89.205.21 -159.118.242.230 -95.179.62.63 -186.93.214.168 -178.234.63.213 -188.162.36.173 -217.118.79.25 -87.198.180.6 -66.55.134.213 -24.122.34.75 -87.103.52.73 -208.167.254.37 -109.88.146.44 -105.184.225.62 -73.90.204.141 -212.255.228.189 -202.80.215.115 -119.224.48.233 -176.114.191.253 -197.27.8.202 -42.115.18.149 -93.84.8.44 -1.162.86.234 -103.25.46.9 -152.23.21.142 -76.179.165.105 -62.133.162.222 -98.77.43.229 -78.80.76.82 -68.61.121.174 -186.95.86.120 -222.76.117.248 -88.91.76.98 -201.208.13.107 -109.43.2.115 -80.215.210.194 -81.30.71.45 -89.151.161.58 -171.39.68.224 -111.227.127.190 -179.232.244.239 -100.64.97.198 -66.32.255.192 -83.4.148.220 -110.174.123.194 -141.58.46.18 -201.253.41.90 -50.254.73.145 -71.7.113.19 -104.159.144.57 -121.208.106.107 -86.56.60.16 -46.142.40.17 -91.148.91.236 -95.90.53.237 -94.66.57.107 -223.207.122.199 -70.169.28.217 -202.62.16.168 -177.231.121.64 -95.147.181.131 -213.162.103.191 -190.202.250.145 -213.151.0.82 -84.63.33.137 -178.98.128.31 -219.73.15.219 -212.71.239.55 -204.11.237.73 -212.251.28.139 -109.151.26.71 -93.81.218.153 -0.0.0.0 -108.49.147.47 -79.152.183.84 -162.216.46.43 -182.239.166.75 -73.187.107.193 -93.127.76.65 -194.219.60.132 -89.38.35.81 -178.234.246.180 -83.249.178.255 -178.120.203.65 -172.58.139.124 -184.64.170.246 -46.19.139.182 -174.109.105.111 -231.255.154.44 -178.41.95.247 -68.7.186.217 -118.216.79.55 -175.208.141.224 -178.121.168.9 -197.27.90.215 -94.51.32.217 -81.240.52.24 -174.76.158.194 -114.125.191.209 -93.169.165.183 -70.79.67.146 -62.198.196.56 -122.82.162.156 -195.147.224.24 -186.77.195.134 -188.81.148.12 -188.73.254.84 -90.190.117.187 -37.213.170.13 -79.245.216.86 -213.7.35.207 -123.201.113.207 -91.241.96.80 -91.229.61.46 -92.17.118.188 -100.16.34.113 -90.199.36.236 -71.251.78.65 -179.197.169.12 -24.188.239.178 -99.183.185.69 -197.117.90.127 -178.222.68.33 -171.97.184.18 -197.202.234.106 -180.246.168.146 -188.19.161.137 -71.19.249.4 -68.235.182.101 -114.79.37.118 -106.192.7.54 -36.69.19.2 -78.250.126.154 -203.145.92.95 -62.102.148.183 -128.71.91.85 -78.28.250.66 -68.52.132.102 -73.214.142.184 -69.18.28.136 -185.128.41.158 -94.74.66.101 -182.187.123.236 -37.24.156.235 -46.143.69.22 -189.183.55.56 -36.78.196.123 -46.31.38.113 -90.217.93.166 -79.133.157.203 -180.129.159.1 -41.251.208.103 -24.186.232.5 -95.221.21.83 -15.107.231.112 -79.16.214.237 -151.249.96.73 -46.195.49.136 -89.210.24.145 -198.205.1.101 -188.73.252.224 -192.99.160.163 -83.165.85.219 -92.100.44.40 -53.193.239.251 -104.244.157.16 -177.188.17.204 -197.203.60.143 -114.88.20.31 -217.235.240.122 -149.88.75.65 -184.90.64.40 -186.90.98.38 -187.15.73.13 -174.77.224.21 -37.113.168.28 -209.107.214.62 -81.184.126.146 -115.70.149.131 -87.140.192.50 -81.109.222.243 -188.134.13.5 -78.250.241.41 -92.232.213.133 -91.115.55.194 -174.58.228.93 -202.62.17.10 -0.0.0.0 -95.52.190.92 -178.223.0.82 -84.55.16.81 -217.23.187.1 -100.10.59.5 -67.44.192.24 -79.245.200.52 -217.87.92.166 -69.108.3.158 -190.204.40.157 -81.154.204.185 -37.47.211.56 -70.181.47.97 -78.21.195.37 -95.91.241.81 -27.145.177.83 -83.27.161.92 -178.234.90.237 -201.6.172.44 -223.205.74.62 -81.229.37.193 -150.117.170.89 -80.47.94.236 -118.209.134.35 -43.249.129.196 -195.214.190.171 -186.119.252.108 -27.34.28.186 -83.248.25.82 -119.236.248.38 -156.241.140.131 -65.30.11.62 -87.64.212.160 -69.167.26.56 -91.156.41.30 -78.230.39.234 -99.121.49.140 -94.96.41.4 -99.187.33.246 -66.41.56.235 -36.255.113.156 -66.69.124.164 -82.21.95.51 -85.76.86.40 -5.13.171.55 -37.115.172.148 -224.245.98.190 -178.16.215.164 -178.243.204.40 -104.200.154.25 -173.74.177.35 -76.178.149.21 -95.72.3.129 -229.163.111.67 -82.20.144.232 -128.75.237.122 -86.57.197.105 -151.227.121.20 -190.156.192.88 -171.96.168.116 -41.150.141.127 -91.40.70.81 -82.54.32.17 -174.93.226.111 -61.195.99.101 -187.152.220.146 -190.38.6.28 -104.156.240.153 -186.93.165.61 -180.213.84.12 -68.145.81.59 -212.90.62.251 -191.43.19.200 -124.122.213.230 -79.235.241.133 -47.67.40.201 -82.168.170.109 -78.111.190.48 -87.185.26.148 -177.34.78.53 -83.61.94.153 -141.130.226.62 -80.121.28.99 -50.66.152.76 -131.173.60.240 -112.215.123.68 -190.38.48.14 -93.107.13.106 -173.221.226.116 -96.26.11.23 -142.166.71.215 -177.134.174.140 -86.168.201.42 -87.105.66.67 -178.131.84.160 -37.45.3.23 -37.229.121.72 -209.160.123.88 -84.31.242.4 -37.5.141.129 -179.209.225.212 -78.150.6.212 -151.66.229.34 -84.184.209.7 -5.80.54.19 -223.225.182.127 -65.26.54.236 -98.227.60.68 -173.185.69.84 -89.142.37.216 -5.42.17.207 -112.184.28.67 -190.198.36.172 -83.59.146.4 -188.183.117.146 -62.197.218.214 -46.244.218.156 -201.79.56.33 -186.88.71.213 -71.52.82.247 -109.240.39.103 -73.90.208.150 -165.255.122.178 -108.117.169.213 -191.223.196.53 -93.124.12.6 -60.211.181.34 -149.210.40.55 -32.117.64.178 -71.15.250.17 -197.229.28.177 -49.32.36.161 -178.184.63.128 -229.244.37.192 -24.171.125.63 -197.203.21.66 -189.97.76.94 -91.48.62.50 -217.228.64.245 -65.93.5.186 -200.84.68.224 -189.165.50.103 -76.202.180.86 -73.198.40.189 -79.41.177.10 -91.213.143.252 -46.10.100.20 -155.138.236.210 -217.89.0.213 -84.117.17.168 -81.153.147.190 -106.187.37.124 -79.116.46.102 -41.244.243.202 -193.107.94.5 -50.83.133.238 -176.58.22.253 -81.132.37.244 -92.43.188.173 -83.149.35.11 -79.32.103.236 -150.40.223.126 -84.135.83.89 -99.246.216.151 -5.80.240.84 -128.71.187.172 -84.81.98.206 -2.94.196.192 -109.221.51.167 -178.122.238.20 -202.62.16.108 -82.19.207.84 -178.120.180.77 -109.173.87.23 -188.146.72.127 -93.175.72.187 -201.130.5.2 -178.44.12.28 -40.87.147.250 -188.69.195.72 -84.159.232.37 -82.141.118.195 -223.25.25.103 -143.48.117.132 -197.6.149.103 -75.73.58.145 66.228.56.115 -109.93.83.59 -93.104.105.193 -79.146.50.229 -79.245.195.18 -87.5.71.70 -86.81.209.28 -41.141.46.16 -217.89.2.42 -78.239.107.25 -184.134.70.35 -96.83.29.78 -145.97.231.240 -195.37.12.20 -76.68.162.94 -46.167.124.185 -89.210.204.47 -151.238.37.180 -27.159.20.249 -78.12.60.47 -99.250.53.196 -101.171.127.242 -212.228.253.143 -87.92.83.95 -2.5.78.51 -87.158.138.61 -163.158.223.125 -149.254.219.192 -79.112.46.242 -178.234.15.238 -88.254.73.55 -62.1.29.53 -212.228.253.143 -5.254.97.86 -188.162.132.110 -178.43.55.232 -83.60.248.55 -24.135.244.72 -115.135.47.10 -92.162.158.94 -112.186.124.56 -95.108.54.55 -213.24.126.141 -82.141.118.195 -223.204.248.206 -176.58.133.196 -104.156.228.71 -81.131.226.196 -151.72.136.1 -86.184.140.225 -46.98.12.7 -207.192.254.156 -124.170.23.36 -95.71.68.207 -219.237.242.60 -188.73.252.67 -128.75.237.180 -95.73.250.51 -46.5.195.24 -70.139.70.171 -87.95.233.26 -85.245.55.58 -91.67.99.12 -92.100.121.16 -91.182.0.44 -176.27.24.255 -200.146.57.130 -115.207.68.8 -91.63.1.128 -79.54.215.248 -83.143.240.35 -84.152.149.102 -191.32.0.88 -82.229.26.235 -84.154.93.193 -217.83.12.218 -91.154.8.178 -73.62.248.49 -24.217.99.228 -208.54.83.214 -188.103.157.164 -120.164.44.57 -31.3.26.210 -199.119.232.215 -89.245.109.97 -36.78.250.164 -198.23.103.69 -80.147.25.206 -209.160.123.53 -122.73.59.85 -201.141.39.232 -86.129.252.132 -52.169.229.251 -186.90.122.140 -189.82.147.136 -39.48.73.31 -152.234.187.32 -87.204.222.96 -67.60.16.219 -37.45.82.110 -115.28.138.90 -62.165.226.97 -138.201.65.88 -84.187.91.201 -83.78.9.216 -86.210.212.108 -176.104.184.50 -37.23.114.113 -109.204.154.88 -188.4.237.14 -84.152.140.60 -127.180.48.132 -181.29.63.54 -83.36.226.52 -122.62.12.87 -72.160.29.62 -79.70.51.138 -220.253.4.142 -62.63.82.172 -171.96.167.213 -93.43.160.238 -105.156.245.177 -216.172.138.189 -105.224.204.200 -80.215.170.87 -108.177.128.150 -196.215.25.200 -187.243.164.218 -77.73.137.37 -177.99.84.95 -202.62.16.58 -129.10.29.163 -171.96.168.32 -46.130.27.222 -14.186.213.191 -95.67.188.205 -79.107.58.23 -128.71.13.113 -99.186.49.28 -91.63.31.207 -80.213.230.192 -218.142.95.189 -75.126.73.56 -72.171.192.248 -91.44.228.200 -77.163.189.107 -41.251.48.199 -188.69.211.24 -177.229.231.37 -105.186.106.4 -94.21.126.37 -93.129.11.176 -190.207.68.49 -179.215.223.24 -198.84.201.135 -115.50.117.30 -83.160.90.35 -84.26.33.226 -171.149.2.249 -190.75.207.59 -14.209.137.220 -151.32.117.143 -37.112.87.206 -201.22.23.138 -83.57.228.86 -174.77.224.21 -0.0.0.0 -142.162.40.54 -31.181.188.236 -194.166.190.1 -64.237.51.168 -80.43.133.125 -109.227.43.129 -190.96.153.233 -201.210.140.73 -95.109.87.61 -77.254.148.133 -95.211.134.28 -80.213.122.68 -81.156.145.142 -86.151.81.47 -24.212.88.112 -50.162.194.86 -88.136.64.229 -190.73.75.228 -80.61.66.72 -37.78.168.147 -213.230.75.175 -98.21.141.197 -144.138.64.50 -81.184.126.146 -82.234.175.33 -71.31.111.170 -36.76.44.84 -189.219.201.55 -87.146.24.200 -90.227.32.48 -81.182.25.190 -100.68.1.55 -162.216.46.112 -24.119.48.249 -75.111.51.213 -87.205.196.58 -101.184.94.136 -83.161.137.46 -91.78.177.167 -189.150.138.34 -68.226.144.118 -178.234.49.0 -50.107.118.90 -78.34.4.22 -83.84.22.227 -80.189.22.170 -184.99.69.164 -199.7.156.142 -212.251.18.150 -118.209.75.208 -86.210.89.109 -43.165.193.4 -49.145.123.121 -24.18.171.156 -24.152.231.246 -190.204.5.222 -90.113.251.171 -95.24.56.149 -109.187.90.176 -89.182.24.153 -109.43.3.12 -222.243.244.245 -187.0.235.105 -32.149.215.132 -0.0.0.0 -217.44.160.84 -70.173.107.212 -109.74.162.200 -219.79.189.186 -193.106.215.193 -178.57.98.67 -187.152.220.146 -217.105.20.145 -1.0.0.0 -94.178.6.233 -95.49.168.186 -2.28.195.45 -88.75.32.126 -150.27.127.98 -189.202.64.210 -84.215.98.187 -1.64.26.102 -93.103.144.91 -5.135.36.128 -184.75.213.133 -185.29.164.212 -39.35.182.28 -76.107.228.95 -173.163.0.213 -69.162.195.208 -78.55.250.20 -118.211.234.7 -189.149.43.148 -190.77.242.77 -67.141.24.177 -23.99.59.71 -84.0.103.181 -37.213.220.12 -186.228.165.88 -88.71.176.152 -180.254.111.93 -24.246.95.6 -114.252.227.89 -182.111.195.163 -223.205.29.44 -181.112.107.95 -181.65.62.148 -177.170.155.183 -80.244.146.31 -85.72.83.210 -89.13.106.135 -1.162.89.72 -186.91.204.203 -186.170.85.58 -158.222.194.45 -190.198.36.172 -31.2.118.96 -112.205.152.222 -109.169.168.151 -70.196.196.25 -162.216.46.41 -108.212.84.178 -187.4.110.82 -2.96.253.212 -184.17.153.7 -178.55.248.191 -46.105.158.205 -121.224.229.225 -95.79.62.224 -95.221.211.55 -81.89.56.170 -37.78.59.60 -32.149.215.132 -45.52.184.11 -93.81.9.35 -25.128.23.157 -198.18.1.58 -120.141.142.237 -31.53.121.172 -73.180.62.121 -75.162.140.28 -192.77.248.3 -105.109.155.75 -190.99.218.59 -217.89.8.225 -178.115.131.56 -115.239.127.175 -190.198.5.210 -78.55.239.95 -83.20.69.109 -184.75.213.117 -209.195.113.177 -78.156.104.205 -87.100.158.128 -59.167.196.135 -193.33.91.218 -98.191.243.50 -92.112.239.165 -179.34.94.5 -223.25.25.220 -91.232.105.11 -94.51.110.100 -65.78.152.16 -81.240.52.24 -217.121.192.4 -178.42.208.214 -217.73.143.165 -54.210.100.216 -212.73.174.166 -86.175.85.205 -0.0.0.72 -197.228.134.60 -31.162.230.3 -84.19.166.55 -110.168.231.201 -62.167.128.54 -202.67.37.22 -93.139.171.57 -31.18.159.118 -50.53.104.249 -68.168.178.12 -209.197.162.172 -90.191.163.182 -83.4.80.106 -94.20.241.217 -173.74.172.37 -190.82.204.230 -85.155.6.145 -2.122.176.75 -186.185.169.209 -76.113.42.159 -219.77.166.186 -219.79.189.241 -79.245.209.254 -109.218.83.221 -88.23.123.143 -37.115.192.181 -95.174.98.218 -75.134.13.245 -94.209.121.137 -95.113.48.14 -189.157.46.152 -100.68.86.132 -89.245.126.176 -178.45.76.81 -174.25.200.26 -62.163.9.155 -85.49.23.66 -198.98.118.241 -77.234.44.156 -179.43.169.226 -85.217.41.209 -109.124.211.182 -83.153.29.186 -89.154.49.154 -165.255.211.181 -78.0.3.149 -173.245.195.98 -190.231.63.41 -86.147.60.147 -89.22.243.128 -213.152.162.170 -80.108.46.24 -128.90.88.11 -224.200.154.18 -91.67.34.202 -254.42.196.227 -79.245.223.174 -80.133.45.20 -208.58.41.133 -105.237.9.149 -79.200.67.185 -223.204.248.96 -89.39.78.192 -154.157.161.160 -178.215.168.129 -114.76.137.117 -173.75.18.157 -83.134.86.173 -62.158.150.131 -184.64.19.148 -60.17.235.231 -42.112.80.24 -93.170.111.115 -194.28.39.72 -141.237.27.57 -109.93.85.149 -216.180.181.48 -172.56.20.93 -76.242.145.138 -95.24.100.172 -85.26.186.204 -176.58.130.226 -85.222.42.211 -151.95.16.217 -36.74.94.208 -178.128.244.47 167.160.36.126 -176.10.42.45 -178.234.51.251 -67.193.56.206 -188.95.206.133 -83.134.225.71 -186.14.240.71 -46.28.53.172 -95.67.173.63 -188.69.195.143 -196.210.126.198 -190.206.197.37 -79.67.123.101 -46.238.214.54 -47.64.20.211 -31.41.247.133 -125.142.30.68 -37.142.185.136 -189.138.63.24 -77.110.147.13 -82.119.13.10 -212.183.61.11 -94.214.163.25 -254.185.71.201 -26.162.173.209 -188.193.79.183 -190.39.38.49 -24.22.111.227 -71.175.81.45 -181.95.121.26 -178.93.129.60 -68.45.101.13 -81.154.58.116 -78.153.4.77 -206.248.172.100 -208.82.41.47 -50.172.89.183 -181.24.43.245 -98.223.62.66 -24.252.75.158 -2.121.201.171 -89.172.238.180 -192.214.119.58 -1.129.96.141 -107.11.145.246 -73.224.21.143 -184.155.200.186 -36.69.20.159 -62.101.183.24 -89.245.125.162 -202.62.17.54 -188.0.42.195 -188.29.164.228 -99.253.132.72 -130.180.220.8 -100.69.227.171 -54.86.84.160 -100.68.65.92 -121.220.62.161 -96.238.148.171 -188.77.49.237 -78.46.23.222 -109.121.29.102 -197.228.235.128 -2.12.99.12 -176.249.222.22 -82.176.89.129 -46.55.165.57 -79.200.222.225 -193.92.252.13 -118.209.158.228 -124.122.0.238 -178.128.243.39 -109.212.175.142 -183.50.224.62 -219.79.191.143 -201.209.130.164 -201.231.215.30 -164.67.192.103 -180.129.159.1 -192.99.217.31 -73.90.210.204 -79.45.210.96 -185.107.252.224 -105.97.224.170 -100.113.28.102 -66.96.100.24 -60.218.122.249 -189.144.45.28 -37.188.130.172 -100.65.150.99 -171.4.185.126 -81.141.8.117 -98.223.11.108 -2.92.58.180 -108.110.155.247 -14.98.83.166 -164.77.40.254 -50.153.150.172 -89.153.45.155 -203.222.146.55 -99.37.3.74 -139.228.0.80 -53.193.238.57 -193.107.92.232 -81.247.79.74 -81.214.98.49 -5.200.52.133 -212.251.27.178 -85.53.81.54 -217.123.121.141 -125.160.197.79 -104.200.154.26 -83.37.72.115 -181.1.68.23 -59.172.132.204 -108.75.178.165 -5.66.253.16 -185.37.192.112 -94.41.128.125 -136.243.217.171 -87.81.138.30 -107.220.18.70 -71.236.243.108 -93.164.7.181 -88.141.114.61 -79.134.38.179 -151.231.96.75 -188.29.165.196 -80.92.31.43 -186.213.104.163 -213.96.202.231 -45.56.151.17 -94.99.209.193 -112.215.124.182 -79.131.163.147 -66.26.153.172 -90.7.252.111 -178.222.27.190 -201.243.34.211 -83.55.65.150 -64.17.79.28 -186.93.30.93 -80.116.34.167 -93.169.135.5 -41.251.212.137 -87.144.11.117 -173.20.72.21 -69.243.228.52 -128.75.199.166 -96.45.237.72 -75.189.230.76 -231.157.187.212 -188.143.13.98 -68.34.214.8 -91.134.233.254 -176.248.175.132 -81.203.228.217 -171.96.171.118 -65.27.83.146 -95.26.230.15 -64.53.210.14 -188.114.23.6 -125.127.86.95 -71.53.155.242 -178.217.115.50 -89.237.38.235 -163.157.186.231 -79.184.121.102 -58.7.79.182 -186.116.227.215 -87.185.4.187 -217.253.209.157 -171.96.168.28 -36.83.43.11 -91.122.166.250 -112.215.124.84 -66.168.28.90 -1.0.0.0 -171.149.2.249 -46.176.102.2 -88.75.132.88 -217.116.211.114 -43.255.83.123 -80.135.14.197 -187.200.126.254 -84.2.110.235 -79.245.194.74 -179.55.77.60 -177.247.47.140 -50.153.149.124 -193.161.15.69 -82.236.72.55 -93.125.63.252 -178.65.14.106 -213.113.185.135 -155.133.16.26 -46.29.144.17 -149.202.44.159 -124.122.6.109 -68.186.198.147 -62.36.238.183 -81.154.204.185 -79.234.100.103 -1.0.0.0 -70.78.222.93 -84.19.165.213 -82.238.200.36 -37.6.242.90 -97.117.164.169 -83.4.104.110 -95.236.131.168 -72.211.166.102 -0.0.0.2 -46.253.252.140 -187.34.142.244 -169.0.73.53 -109.43.3.230 -91.179.123.166 -189.140.140.184 -178.164.143.158 -85.201.209.80 -63.87.254.188 -5.13.50.74 -92.144.200.122 -0.0.0.0 -78.87.102.229 -175.137.91.173 -117.207.10.37 -92.9.51.240 -192.99.47.172 -171.96.167.85 -96.48.106.63 -5.142.41.37 -46.217.84.125 -90.4.183.69 -145.120.12.175 -71.222.115.159 -174.126.221.216 -196.206.78.112 -213.87.123.163 -219.73.26.166 -217.120.200.182 -41.138.182.233 -2.62.31.79 -14.148.92.236 -191.33.57.182 -188.195.221.38 -178.35.140.252 -83.254.175.251 -88.217.180.135 -46.2.49.102 -89.22.172.159 -2.85.48.166 -197.211.52.27 -31.10.151.160 -81.183.132.39 -146.215.226.94 -50.183.63.188 -174.61.234.134 -108.252.201.93 -90.194.75.240 -188.26.139.49 -77.163.189.107 -208.107.130.112 -121.72.232.206 -24.0.101.211 -31.23.125.144 -78.108.105.3 -207.154.20.231 -79.152.140.12 -71.251.60.74 -92.110.79.41 -2.54.231.38 -173.219.7.133 -200.181.174.247 -174.55.206.7 -46.246.160.217 -122.105.192.219 -180.171.232.19 -80.234.141.228 -184.166.55.59 -80.135.30.123 -58.11.119.219 -201.19.190.183 -98.247.93.2 -98.21.117.65 -159.203.31.42 -46.72.147.197 -191.241.136.54 -188.190.2.136 -213.105.38.228 -181.41.210.93 -1.162.60.24 -177.249.151.161 -1.0.0.0 -109.232.51.32 -82.34.182.46 -80.131.62.65 -124.237.96.40 -181.164.39.82 -138.186.31.43 -187.63.6.45 -77.131.8.180 -190.36.51.51 -50.23.131.235 -77.105.24.110 -243.8.113.116 -172.56.22.46 -128.71.31.119 -67.245.82.244 -99.53.229.135 -182.178.100.105 -89.185.12.216 -83.83.161.46 -86.20.3.141 -91.52.13.182 -61.140.238.47 -201.22.42.227 -91.48.63.23 -32.230.230.72 -66.55.134.215 -5.80.54.19 -222.152.161.106 -185.29.164.237 -80.130.206.9 -207.204.233.23 -184.171.212.55 -87.112.147.66 -185.42.39.117 -2.62.52.96 -85.232.217.179 -84.103.72.150 -5.141.203.74 -253.167.138.14 -177.98.29.222 -178.120.162.160 -37.214.62.162 -24.144.61.126 -82.19.44.100 -192.241.254.114 -36.77.175.202 -108.26.55.253 -79.245.195.228 -119.86.47.160 -179.7.160.222 -112.65.211.229 -70.173.239.125 -98.199.85.134 -80.213.211.183 -176.97.36.140 -91.19.121.248 -24.217.245.101 -98.238.145.154 -79.125.205.26 -108.161.118.177 -89.168.217.136 -79.114.109.234 -188.27.207.162 -122.57.235.244 -159.172.226.177 -107.203.104.144 -254.92.232.178 -83.117.200.125 -70.53.183.31 -189.223.40.145 -37.76.68.108 -78.147.114.195 -2.176.151.20 -181.44.114.97 -78.8.109.43 -31.214.240.56 -53.193.239.36 -176.127.67.214 -88.167.140.73 -188.220.132.161 -167.60.146.106 -92.209.191.40 -100.68.88.0 -177.19.119.96 -217.195.246.98 -0.0.0.0 -36.78.249.30 -124.170.124.221 -222.252.59.19 -69.112.244.114 -79.30.99.74 -181.10.83.104 -79.245.207.112 -115.178.215.30 -171.39.66.125 -79.245.197.208 -171.97.145.198 -190.98.11.234 -91.67.99.12 -79.204.162.138 -150.27.228.7 -46.233.200.165 -77.58.253.73 -187.132.1.39 -79.245.212.85 -113.254.169.222 -5.52.11.13 -190.205.194.65 -69.165.128.9 -109.221.179.32 -128.227.44.156 -173.98.236.230 -217.216.123.34 -24.114.70.184 -112.65.0.74 -77.243.183.116 -95.113.213.5 -31.129.70.174 -90.69.147.20 -202.80.215.19 -50.168.101.34 -217.121.210.13 -72.202.129.75 -97.127.120.204 -36.78.191.143 -27.34.38.27 -80.106.197.231 -189.203.252.6 -188.196.1.166 -104.156.240.142 -31.149.73.49 -187.0.235.105 -52.11.78.65 -181.49.64.55 -128.70.44.218 -173.252.255.34 -100.91.29.206 -186.170.116.234 -186.203.2.32 -109.88.65.154 -93.104.127.247 -171.39.64.12 -83.168.150.119 -92.20.145.13 -2.146.174.242 -85.15.5.3 -212.58.237.100 -178.219.90.233 -109.88.155.108 -115.228.246.237 -78.129.153.58 -109.88.132.44 -181.64.88.109 -1.126.127.226 -125.237.122.51 -187.59.190.103 -82.56.22.225 -172.137.1.106 -152.23.21.142 -87.69.111.245 -99.112.7.5 -83.222.45.113 -178.254.190.206 -62.16.243.132 -201.83.108.195 -181.232.25.197 -114.96.153.143 -213.138.93.0 -151.72.136.1 -41.142.41.167 -177.249.194.77 -179.198.46.74 -95.111.236.135 -91.14.34.70 -182.249.242.10 -71.45.32.188 -88.196.236.26 -28.36.255.86 -189.114.235.27 -107.179.248.207 -209.245.155.235 -178.132.47.176 -84.188.65.226 -108.111.67.194 -95.85.55.153 -108.117.169.213 -104.238.187.114 -5.198.44.176 -124.198.205.11 -98.213.71.84 -41.143.233.44 -223.204.248.171 -93.156.82.36 -201.211.29.167 -41.239.156.148 -81.245.251.1 -24.230.59.100 -125.37.79.46 -5.88.72.90 -100.64.12.2 -201.201.215.83 -188.165.205.135 -60.228.7.131 -200.121.41.216 -193.92.31.61 -88.117.78.255 -90.154.75.175 -89.104.6.79 -190.62.160.125 -112.198.64.48 -90.190.69.165 -200.8.53.77 -216.158.224.240 -208.54.5.254 -73.197.227.38 -25.52.41.130 -201.167.47.254 -220.246.220.125 -85.242.25.243 -31.201.179.254 -42.136.208.211 -37.113.15.208 -84.138.78.96 -88.141.113.130 -31.10.159.200 -217.128.25.131 -2.147.213.24 -177.247.125.211 -99.225.14.89 -71.195.120.65 -62.2.218.10 -111.69.162.148 -109.43.0.79 -216.171.18.187 -62.98.223.129 -197.117.250.77 -0.0.0.0 -85.218.134.32 -173.45.173.72 -176.11.151.238 -109.43.0.198 -190.28.189.103 -85.26.42.127 -46.175.68.4 -77.71.24.63 -37.233.31.253 -213.118.105.27 -55.211.59.42 -178.65.202.255 -62.183.127.182 -172.65.249.192 -189.158.82.6 -46.98.124.49 -37.27.50.204 -190.204.175.75 -79.245.223.80 -82.47.20.169 -41.105.228.16 -212.251.28.229 -25.51.249.200 -188.61.142.25 -185.53.178.9 -87.78.23.245 -95.24.52.94 -181.27.150.162 -58.44.186.69 -187.246.242.110 -37.48.74.42 -223.204.246.232 -153.120.242.171 -93.81.24.169 -151.227.114.46 -74.84.26.219 -93.138.126.48 -81.130.224.89 -23.92.218.130 -64.191.29.26 -5.94.119.65 -189.165.16.244 -50.168.210.180 -91.48.34.56 -91.63.19.156 -0.0.0.0 -123.79.153.212 -108.40.13.187 -110.171.204.110 -217.89.7.46 -223.204.240.178 -73.27.251.141 -128.90.43.153 -169.0.170.28 -110.168.232.50 -24.79.43.15 -79.194.202.151 -90.154.75.175 -188.7.6.154 -217.235.227.209 -186.147.108.177 -92.80.10.182 -113.87.241.181 -195.169.155.126 -184.155.218.183 -188.89.24.254 -83.143.240.44 -62.47.227.63 -188.168.145.223 -99.122.104.173 -187.143.157.80 -173.178.61.115 -180.251.217.73 -117.194.52.63 -24.28.92.13 -25.15.9.35 -165.120.45.108 -83.11.178.19 -92.97.161.7 -82.249.77.22 -181.65.62.148 -186.213.102.132 -72.194.212.147 -25.152.243.103 -79.245.210.38 -99.95.217.55 -91.7.43.15 -199.202.216.171 -109.43.3.149 -84.111.148.18 -190.189.29.32 -100.64.30.28 -24.225.138.67 -165.51.103.243 -92.73.203.118 -82.225.55.132 -45.79.10.59 -106.192.22.127 -77.29.141.165 -41.250.109.214 -95.19.21.165 -85.75.79.133 -78.215.210.112 -22.29.73.140 -217.131.108.228 -199.16.96.145 -190.201.194.107 -190.39.10.186 -178.157.251.246 -93.38.167.117 -220.233.131.66 -100.78.98.103 -41.190.3.124 -62.28.52.105 -1.64.29.50 -41.48.21.132 -181.24.59.235 -79.245.210.198 -108.61.76.8 -77.243.183.93 -158.196.212.164 -82.236.72.55 -187.255.237.97 -219.73.15.192 -151.20.32.245 -95.90.255.153 -118.209.232.218 -124.171.101.99 -87.185.13.113 -5.15.206.164 -25.87.60.111 -68.53.27.112 -83.250.224.227 -130.180.220.126 -83.27.114.96 -1.204.13.122 -111.242.76.47 -202.62.16.62 -101.109.199.119 -159.205.212.242 -213.60.67.126 -85.144.100.5 -201.37.162.92 -194.126.89.193 -201.233.213.167 -93.119.110.247 -190.78.7.231 -75.75.125.55 -185.46.249.145 -160.178.158.54 -95.153.134.144 -81.167.129.247 -172.89.123.176 -152.249.19.96 -87.178.130.45 -93.123.247.211 -46.11.86.170 -186.88.157.110 -77.65.10.166 -189.202.67.14 -223.206.149.29 -123.24.208.165 -46.118.177.40 -25.69.38.113 -70.168.189.146 -99.228.186.52 -70.15.174.156 -142.136.106.108 -193.92.228.153 -85.156.13.86 -189.188.237.104 -95.19.22.94 -217.88.13.199 -1.144.96.140 -81.198.10.79 -178.254.190.132 -94.75.136.231 -38.211.54.78 -71.53.157.49 -192.95.29.176 -73.82.153.96 -62.232.5.242 -100.40.69.188 -162.210.196.176 -180.156.150.143 -110.168.231.245 -79.70.9.80 -137.117.213.153 -178.234.77.146 -84.133.115.69 -84.19.165.213 -62.1.215.212 -94.244.17.63 -50.153.150.216 -88.15.230.239 -165.91.74.108 -2.122.179.220 -79.112.231.20 -162.156.199.110 -14.198.159.194 -187.74.82.136 -72.24.168.79 -117.194.42.216 -100.66.17.228 -47.54.76.217 -201.208.21.151 -79.25.166.110 -84.236.18.119 -39.48.44.134 -222.170.18.151 -76.17.122.180 -97.83.54.77 -190.22.140.51 -221.216.240.245 -187.161.83.96 -85.135.243.220 -90.211.152.125 -92.196.42.65 -31.57.74.31 -187.147.251.197 -188.207.95.41 -95.222.188.217 -190.159.95.190 -71.36.220.248 -36.76.18.26 -80.11.226.53 -78.163.123.228 -189.204.164.169 -58.182.120.211 -93.86.251.111 -84.216.199.63 -83.20.48.4 -81.175.210.63 -119.237.90.152 -79.147.235.72 -137.135.48.99 -160.171.125.185 -130.215.124.85 -198.18.1.10 -77.29.108.119 -189.242.129.27 -188.162.132.133 -77.243.183.94 -78.125.179.134 -24.214.182.28 -81.234.23.242 -124.122.253.86 -95.252.203.179 -189.25.60.50 -190.142.81.36 -201.208.98.13 -106.187.36.44 -171.39.41.252 -188.83.111.148 -190.37.177.83 -94.190.41.3 -96.21.54.26 -155.4.130.140 -188.251.165.89 -71.244.110.93 -113.254.169.55 -69.123.225.156 -56.99.107.117 -66.60.133.42 -91.225.98.162 -94.41.64.71 -92.138.109.194 -142.161.114.127 -5.151.152.147 -151.24.152.4 -209.222.18.51 -144.64.86.12 -49.195.176.237 -92.131.11.116 -108.161.125.223 -98.209.226.86 -95.81.250.253 -70.208.6.53 -84.231.84.105 -110.168.232.221 -181.51.166.159 -151.74.10.81 -213.233.96.10 -5.63.144.156 -171.96.168.126 -128.69.7.182 -70.70.34.86 -68.184.83.28 -84.236.38.116 -87.1.245.196 -181.208.47.253 -109.245.151.167 -184.75.213.134 -186.95.46.68 -165.255.172.58 -219.73.27.5 -100.68.93.19 -202.62.17.115 -83.22.172.58 -179.234.194.69 -118.211.230.64 -178.9.240.143 -95.28.183.3 -46.254.11.158 -74.193.208.180 -193.51.6.5 -92.148.135.217 -78.15.174.21 -41.174.160.149 -93.51.148.228 -24.179.14.89 -91.48.61.225 -139.162.24.133 -24.84.188.5 -108.244.47.41 -88.3.38.194 -37.45.160.140 -189.153.60.95 -37.27.50.204 -96.233.67.164 -156.211.215.134 -108.80.58.111 -108.69.112.21 -186.90.98.44 -173.89.84.54 -85.25.194.85 -205.170.14.244 -213.87.126.214 -112.198.82.157 -86.138.53.33 -82.176.127.213 -94.10.73.206 -162.216.46.135 -86.130.140.227 -86.152.54.251 -198.204.210.68 -108.251.123.134 -186.214.224.142 -84.119.98.171 -186.88.157.110 -189.178.148.244 -130.15.199.115 -190.207.190.244 -95.28.185.134 -88.206.187.1 -80.47.247.96 -85.206.100.75 -190.77.79.214 -81.200.14.126 -187.78.67.179 -177.228.65.109 -109.202.10.42 -85.76.167.169 -46.166.188.224 -109.75.178.93 -213.67.148.249 -92.157.168.181 -201.157.91.73 -174.58.249.186 -198.18.1.95 -91.148.77.205 -79.133.142.93 -109.153.188.99 -208.167.254.37 -77.181.3.3 -83.7.170.93 -178.164.195.234 -72.136.101.25 -213.24.132.13 -181.162.51.72 -188.17.9.40 -182.149.130.239 -75.114.240.23 -187.143.212.81 -109.81.208.158 -87.0.202.64 -21.106.179.117 -148.31.163.57 -183.171.177.23 -84.125.169.134 -178.198.242.133 -119.9.105.164 -0.0.0.0 -95.91.207.113 -125.72.123.245 -175.38.196.103 -83.86.42.44 -223.225.151.71 -94.68.134.137 -77.49.187.76 -105.233.77.216 -177.228.88.39 -94.71.54.26 -178.64.122.121 -86.216.64.167 -49.64.105.88 -205.197.242.183 -69.254.108.4 -91.152.158.166 -120.165.82.23 -95.27.226.29 -76.124.76.145 -84.159.232.37 -178.84.100.142 -173.72.136.151 -105.228.185.243 -223.225.154.206 -85.135.171.158 -85.26.165.33 -92.110.103.112 -87.14.218.112 -109.221.221.97 -175.33.226.219 -142.4.218.175 -91.77.226.181 -79.204.185.44 -186.188.64.207 -26.162.173.209 -69.231.35.237 -81.158.203.27 -77.20.80.189 -178.167.129.161 -42.2.227.111 -186.94.110.227 -152.23.150.97 -189.27.18.212 -79.245.209.128 -190.29.231.15 -96.22.101.105 -85.173.115.239 -89.72.250.80 -202.62.16.4 -0.0.0.0 -186.91.170.42 -112.208.190.3 -37.235.146.166 -216.40.70.98 -64.191.29.34 -86.85.125.240 -78.164.97.108 -91.158.232.111 -218.142.99.184 -24.184.24.162 -73.19.76.93 -104.172.24.79 -101.136.198.7 -91.105.176.20 -98.67.92.79 -176.46.93.116 -96.21.254.147 -46.244.192.30 -139.195.25.65 -173.75.249.15 -85.25.210.25 -25.69.38.113 -190.201.12.159 -77.119.128.157 -5.237.19.68 -79.130.163.117 -75.161.240.113 -89.0.7.35 -190.203.160.220 -190.93.250.41 -128.90.23.4 -165.47.80.207 -83.202.33.220 -75.82.46.205 -174.139.74.218 -186.91.238.219 -92.144.200.122 -178.0.63.141 -76.178.149.21 -84.159.235.173 -84.104.81.56 -77.88.251.253 -62.109.37.226 -75.159.1.100 -70.196.196.25 -91.61.74.165 -94.112.241.242 -104.45.135.147 -113.254.168.101 -94.21.126.27 -188.113.91.140 -0.0.0.2 -29.108.45.223 -50.153.149.88 -92.37.51.148 -95.81.233.129 -124.217.188.204 -50.245.144.205 -88.8.65.219 -88.128.80.4 -111.95.163.140 -45.56.39.12 -176.9.61.40 -93.82.94.46 -201.191.195.235 -77.29.197.123 -40.76.47.144 -2.136.28.141 -67.53.205.187 -136.243.62.98 -217.208.179.41 -79.245.196.100 -140.247.0.75 -90.203.117.109 -151.15.98.15 -85.76.42.248 -65.27.65.178 -213.166.200.124 -71.82.169.191 -151.237.43.222 -201.211.22.44 -67.5.176.5 -111.91.74.57 -160.176.173.124 -87.15.222.204 -2.85.58.108 -50.247.211.162 -79.245.217.213 -124.122.237.67 -89.153.235.154 -46.167.109.219 -79.203.79.28 -72.58.199.221 -93.190.181.183 -217.174.155.155 -5.141.221.243 -78.92.198.142 -189.123.189.192 -205.100.213.40 -77.231.221.177 -37.188.232.39 -112.198.102.141 -84.147.122.57 -2.135.127.246 -206.75.168.223 -206.130.91.237 -116.16.95.251 -37.72.10.137 -31.181.184.129 -92.222.28.13 -69.42.234.159 -128.127.210.88 -37.5.43.90 -178.162.193.97 -108.45.158.161 -77.162.138.28 -77.89.248.90 -5.18.63.57 -24.62.53.127 -85.156.13.237 -151.15.85.80 -176.33.109.91 -1.4.206.140 -104.157.189.4 -121.225.226.92 -217.235.245.112 -190.36.148.66 -46.253.253.84 -201.209.130.118 -162.216.46.141 -209.126.76.117 -104.200.151.54 -93.80.197.95 -87.5.5.78 -92.124.31.153 -176.212.178.160 -90.4.173.86 -222.64.139.107 -84.99.129.241 -38.211.239.187 -119.250.149.37 -88.105.204.1 -186.179.106.1 -113.173.78.173 -105.208.244.120 -104.210.0.71 -178.194.65.149 -222.132.2.70 -186.79.224.179 -92.237.244.8 -190.157.73.195 -62.231.188.129 -86.191.215.1 -70.59.17.67 -62.92.112.6 -83.5.143.28 -188.25.160.13 -0.0.0.0 -187.240.198.232 -79.140.167.244 -174.97.26.213 -181.90.26.16 -79.184.207.243 -2.62.44.154 -46.0.51.72 -98.238.231.31 -120.144.26.14 -72.241.236.178 -37.134.72.93 -188.143.32.39 -69.171.107.214 -171.97.224.32 -108.54.103.176 -107.194.30.116 -171.149.2.249 -178.234.66.23 -158.42.125.14 -69.36.215.49 -94.50.196.101 -217.151.54.26 -31.61.140.244 -193.161.15.76 -73.55.215.101 -124.104.112.150 -217.95.239.51 -76.104.64.62 -83.78.9.216 -85.71.44.226 -223.204.250.206 -169.1.121.116 -177.134.229.189 -89.241.140.97 -188.196.134.227 -71.62.232.70 -46.44.37.124 -142.217.187.68 -178.94.172.164 -176.58.231.221 -193.238.38.144 -24.48.212.145 -100.116.210.117 -50.106.174.52 -134.255.109.40 -86.45.106.149 -92.249.92.85 -81.154.37.13 -66.87.97.55 -41.165.4.106 -109.182.51.122 -95.26.169.115 -198.8.80.155 -64.61.51.178 -110.168.231.226 -58.33.130.50 -124.229.133.168 -83.149.46.90 -202.62.16.20 -195.174.63.110 -150.27.127.98 -84.244.18.20 -65.27.245.94 -199.16.96.145 -78.173.68.47 -186.115.229.57 -85.51.153.198 -99.178.135.101 -41.249.165.237 -190.201.165.99 -190.177.98.177 -99.187.33.246 -73.35.112.73 -95.237.97.7 -79.235.248.242 -81.108.157.78 -193.34.145.124 -80.223.135.107 -188.18.28.45 -177.228.66.13 -24.44.203.215 -58.11.70.243 -113.240.247.242 -80.235.62.161 -146.185.150.70 -108.61.19.5 -65.27.89.177 -181.130.118.110 -79.245.209.9 -71.95.186.175 -217.71.47.220 -93.143.248.105 -95.223.121.159 -186.93.167.188 -24.192.24.115 -101.114.75.142 -82.19.92.224 -217.226.243.86 -186.87.6.195 -78.209.19.92 -91.148.114.172 -50.142.234.175 -91.134.233.254 -39.250.103.108 -202.62.17.179 -128.78.135.164 -179.212.185.123 -25.193.218.1 -197.211.52.26 -190.78.147.223 -112.156.51.76 -178.57.99.40 -58.182.120.211 -41.244.241.221 -90.151.144.22 -121.35.17.81 -50.23.115.93 -81.153.146.33 -77.249.199.235 -200.162.249.24 -124.197.16.81 -79.141.246.80 -118.233.230.47 -105.233.77.88 -216.114.224.73 -52.71.215.53 -212.54.196.101 -91.232.124.59 -72.42.106.23 -86.94.147.16 -178.184.63.128 -103.199.41.194 -2.222.34.104 -85.175.20.156 -124.122.29.190 -117.151.176.6 -87.0.208.206 -71.250.245.33 -210.55.212.46 -5.139.75.217 -95.91.206.164 -2.93.226.176 -176.193.188.215 -86.38.41.1 -59.58.238.21 -187.188.19.71 -50.153.150.134 -177.249.153.191 -95.90.53.237 -190.73.47.192 -186.90.15.65 -192.99.13.67 -104.129.24.155 -91.127.56.126 -217.71.45.211 -71.127.224.135 -79.67.194.168 -13.93.150.42 -109.43.2.98 -207.172.224.81 -78.147.75.63 -208.84.132.253 -190.198.3.63 -118.90.23.40 -178.13.79.48 -176.58.103.240 -216.14.119.122 -204.112.179.114 -93.143.252.213 -49.15.136.120 -110.167.219.173 -217.253.222.163 -100.73.22.72 -216.209.119.6 -31.42.237.209 -185.46.249.145 -83.143.240.45 -79.30.246.76 -150.69.145.157 -118.98.96.151 -76.11.216.201 -91.44.228.200 -80.11.226.53 -208.44.136.67 -198.211.38.157 -67.170.218.234 -190.38.178.182 -186.87.208.254 -67.181.167.196 -147.62.114.140 -209.107.214.55 -1.0.0.0 -119.236.139.193 -222.152.161.106 -97.101.86.80 -50.153.148.140 -88.132.143.170 -168.1.6.18 -79.41.223.165 -78.8.13.6 -94.66.57.24 -86.140.40.180 -94.96.41.4 -220.220.88.5 -89.71.115.25 -77.38.95.104 -188.162.39.231 -37.112.7.17 -62.63.91.96 -187.143.59.112 -68.246.2.180 -24.152.231.246 -2.187.200.134 -153.183.217.213 -70.168.69.126 -79.208.167.161 -88.217.180.9 -93.143.136.165 -86.115.102.42 -80.131.61.109 -162.239.34.236 -91.48.57.111 -158.69.31.40 -188.226.144.233 -67.149.247.90 -182.165.44.216 -81.159.65.131 -79.47.233.208 -88.241.49.194 -186.93.225.184 -86.19.224.63 -76.19.17.188 -37.24.158.219 -85.76.176.126 -5.248.84.56 -68.4.194.25 -231.255.154.44 -80.57.219.95 -201.210.86.19 -109.43.3.23 -98.207.163.188 -93.202.162.111 -99.228.18.37 -197.116.68.113 -69.138.11.33 -109.98.63.224 -112.210.102.141 -213.211.143.17 -95.17.252.70 -174.60.14.63 -178.66.204.156 -72.200.198.145 -92.80.196.123 -146.90.135.129 -213.220.206.204 -46.246.150.244 -140.168.134.185 -172.245.17.12 -5.233.6.23 -80.113.129.139 -79.206.171.53 -83.4.148.240 -101.99.203.102 -171.7.219.199 -104.200.151.3 -158.69.8.194 -80.103.188.87 -91.48.32.205 -85.178.71.102 -93.113.93.207 -209.91.43.78 -24.204.194.99 -80.174.238.232 -50.148.74.47 -62.197.218.214 -65.129.14.9 -186.89.90.196 -46.246.204.126 -5.200.52.133 -37.78.189.109 -189.194.112.230 -178.93.150.194 -53.193.238.248 -77.2.189.231 -154.119.57.252 -184.171.221.233 -66.87.68.1 -79.50.152.125 -182.86.80.146 -201.29.101.113 -53.193.239.189 -213.47.88.249 -98.160.239.93 -89.131.174.242 -200.92.5.63 -171.96.167.66 -86.129.69.231 -92.40.183.177 -186.94.97.240 -97.117.164.169 -50.169.246.145 -101.80.128.236 -220.246.220.111 -159.172.226.177 -86.31.128.135 -74.218.235.108 -164.78.139.233 -193.34.160.72 -93.210.122.68 -193.168.1.100 -46.193.132.28 -65.118.121.91 -31.61.141.53 -104.200.151.75 -88.152.185.158 -201.4.90.63 -198.105.244.119 -88.254.164.183 -83.44.122.82 -79.19.6.37 -188.76.105.164 -80.110.47.213 -181.137.36.56 -80.4.97.103 -217.95.253.103 -93.104.103.129 -37.48.86.181 -179.5.8.19 -212.23.185.22 -81.196.32.176 -172.89.205.21 -73.90.211.0 -62.74.23.11 -231.210.83.146 -46.101.128.131 -186.15.8.16 -24.246.57.236 -66.63.176.223 -180.252.90.132 -223.204.247.173 -91.181.167.61 -209.188.18.43 -190.252.136.95 -81.7.79.148 -117.208.209.181 -186.92.34.75 -128.71.78.96 -79.245.196.125 -219.132.169.77 -200.56.38.193 -180.251.253.5 -186.93.59.201 -100.92.135.255 -37.188.236.106 -178.93.35.14 -79.204.180.184 -50.153.149.45 -202.62.17.210 -68.196.158.116 -162.210.196.175 -24.138.129.215 -93.79.197.70 -46.98.111.95 -83.132.22.255 -180.242.27.12 -217.24.135.250 -79.16.92.158 -90.204.155.154 -190.45.238.103 -37.215.59.175 -185.3.151.60 -94.141.162.11 -41.174.166.66 -80.107.68.218 -212.74.198.2 -41.96.38.253 -0.0.0.0 -67.85.63.112 -36.88.141.249 -145.133.165.175 -81.32.245.39 -46.246.219.114 -5.141.222.49 -177.133.210.69 -197.49.157.92 -178.79.79.120 -83.29.92.182 -31.44.253.224 -185.3.151.123 -176.193.197.136 -87.152.129.52 -115.87.121.205 -77.49.159.77 -105.108.27.121 -92.144.213.82 -46.109.74.73 -100.42.160.78 -95.24.99.127 -186.54.141.61 -223.207.119.134 -188.73.192.57 -70.51.25.253 -183.16.3.173 -37.24.146.248 -94.242.222.251 -49.32.36.161 -41.251.33.220 -79.141.170.4 -124.122.237.67 -79.16.172.241 -79.186.217.121 -178.128.177.165 -114.79.12.121 -95.19.21.165 -93.156.81.50 -178.165.128.117 -68.39.187.73 -151.235.136.86 -186.207.213.206 -85.229.184.205 -111.240.211.83 -188.221.40.209 -191.112.243.63 -178.234.12.95 -190.238.98.73 -93.150.78.97 -179.8.129.14 -77.165.247.110 -190.239.38.166 -189.174.114.178 -93.205.17.169 -95.72.134.13 -84.154.167.152 -62.2.218.10 -95.220.229.126 -5.164.173.159 -94.134.4.178 -117.200.204.157 -178.221.184.6 -77.20.176.135 -0.0.0.2 -91.39.197.227 -171.149.2.249 -67.165.120.50 -97.90.203.136 -47.217.159.177 -105.226.137.23 -67.83.72.171 -41.144.196.62 -189.223.40.145 -220.173.185.231 -109.161.89.199 -176.41.228.17 -77.70.68.47 -91.202.135.145 -83.185.91.165 -31.150.218.95 -171.39.43.113 -95.91.240.232 -171.96.172.138 -91.44.237.157 -203.217.68.236 -174.58.253.59 -202.62.16.108 -142.160.113.197 -5.42.105.143 -180.252.93.87 -206.183.119.36 -176.51.208.129 -159.29.194.242 -0.0.0.0 -5.100.81.158 -217.197.250.33 -82.72.102.219 -124.150.29.101 -77.164.58.243 -188.37.186.128 -5.140.139.49 -67.85.63.112 -95.179.62.63 -23.240.234.72 -213.108.208.79 -187.170.158.202 -201.41.173.2 -68.195.171.102 -92.251.154.55 -2.182.202.55 -178.65.132.42 -46.159.49.34 -1.189.194.115 -36.78.249.200 -151.18.52.171 -99.246.216.151 -67.5.248.216 -2.110.116.27 -14.97.145.32 -37.201.6.202 -71.181.32.76 -97.127.124.25 -108.80.58.111 -84.24.170.40 -37.6.110.7 -176.212.176.146 -86.212.45.38 -191.234.38.103 -117.198.131.128 -87.81.133.34 -93.126.80.151 -152.59.57.53 -198.23.200.184 -84.251.165.229 -79.192.207.150 -173.79.131.221 -123.201.196.249 -112.226.70.121 -88.232.236.61 -79.117.59.4 -203.166.254.250 -83.83.205.251 -171.4.15.49 -80.106.197.8 -92.93.148.140 -31.54.226.230 -93.81.75.134 -41.96.150.179 -108.61.226.7 -86.159.138.213 -95.160.150.34 -95.189.3.132 -87.116.161.14 -94.7.141.205 -78.47.149.84 -202.62.17.10 -61.227.229.211 -31.132.225.143 -187.14.108.85 -84.41.36.30 -189.238.214.70 -173.192.176.136 -113.172.95.150 -155.46.1.20 -5.28.189.174 -108.54.168.63 -109.236.137.250 -31.174.206.35 -68.231.74.249 -87.113.49.184 -36.71.162.49 -1.0.0.0 -124.148.165.65 -84.81.98.206 -85.174.61.34 -14.177.108.83 -62.47.227.187 -124.122.2.78 -179.55.38.106 -0.0.0.0 -49.85.204.30 -103.199.34.164 -2.222.34.104 -37.122.196.148 -69.124.57.26 -217.23.186.199 -68.204.242.231 -180.71.101.17 -84.154.93.193 -190.73.126.123 -24.119.202.175 -104.156.228.183 -77.231.219.235 -81.104.96.169 -25.123.50.89 -81.243.118.53 -201.22.154.139 -72.143.235.149 -110.168.231.205 -95.85.45.116 -217.235.247.220 -212.237.86.137 -200.52.22.83 -217.164.143.91 -124.122.109.4 -37.24.159.36 -212.251.121.125 -81.141.22.113 -187.233.168.97 -95.146.118.86 -81.141.16.237 -77.131.2.240 -78.150.15.78 -74.75.46.110 -213.46.74.143 -103.219.4.203 -78.105.113.132 -100.68.210.170 -171.101.162.62 -65.185.44.222 -23.94.218.151 -187.170.125.234 -83.26.161.110 -201.114.25.237 -84.147.126.42 -190.75.97.64 -122.100.181.33 -90.1.218.225 -125.72.123.245 -83.139.146.2 -253.134.93.88 -201.230.90.141 -190.67.190.71 -189.24.200.232 -107.221.196.68 -202.80.215.19 -190.73.253.30 -105.236.34.70 -106.68.25.233 -181.194.27.123 -79.224.70.165 -186.90.50.97 -173.210.142.135 -94.68.173.226 -69.165.242.28 -172.110.5.36 -79.180.7.46 -178.19.96.59 -45.79.195.172 -128.199.217.67 -84.147.122.196 -186.104.156.37 -95.221.121.107 -88.206.187.54 -167.61.27.101 -79.101.223.127 -36.86.63.180 -67.118.170.102 -79.245.194.74 -92.127.108.147 -113.22.90.62 -177.221.251.80 -54.195.241.227 -69.35.163.246 -113.241.227.205 -100.68.108.228 -201.240.63.115 -200.8.206.85 -92.134.68.137 -77.166.187.108 -95.160.73.67 -213.168.24.2 -86.153.95.169 -24.38.155.231 -190.36.148.66 -58.70.1.212 -95.17.245.168 -114.88.165.216 -190.199.48.6 -5.254.97.91 -71.35.70.44 -86.208.73.16 -212.255.255.216 -77.239.67.88 -79.147.194.118 -90.4.251.196 -151.227.86.5 -70.80.71.149 -72.69.190.182 -68.52.132.102 -113.52.90.168 -68.4.208.136 -2.96.241.150 -71.52.84.91 -88.17.165.46 -100.82.113.161 -174.21.77.135 -181.28.55.24 -84.147.117.137 -104.207.136.13 -88.226.55.195 -68.164.80.49 -69.179.143.48 -82.74.131.244 -90.208.124.138 -81.242.194.187 -87.115.29.13 -213.139.53.11 -99.224.242.213 -77.7.149.194 -78.94.32.194 -216.172.138.189 -109.169.168.151 -46.190.34.51 -193.173.216.141 -86.211.114.37 -128.71.63.187 -181.167.138.145 -176.37.244.102 -88.113.195.162 -180.108.78.32 -89.3.175.167 -37.45.105.227 -66.69.125.175 -80.213.211.183 -171.97.215.109 -85.222.174.131 -46.188.33.88 -31.3.159.108 -25.178.132.137 -92.52.34.44 -190.73.156.224 -62.199.144.11 -71.35.66.229 -5.239.187.160 -77.171.31.33 -86.142.225.26 -91.226.79.70 -95.90.203.249 -42.168.94.253 -75.174.90.85 -93.220.95.29 -37.110.210.152 -93.81.87.179 -41.144.196.62 -68.61.208.100 -213.151.213.120 -198.27.97.180 -81.141.5.247 -62.4.196.155 -82.60.153.56 -130.215.124.85 -79.119.13.49 -201.209.12.17 -213.23.160.162 -50.153.151.12 -181.111.47.128 -176.41.230.232 -72.78.180.127 -139.192.136.198 -188.251.165.89 -96.2.40.126 -190.38.141.44 -100.68.200.239 -183.16.196.195 -68.246.191.100 -213.5.52.72 -119.76.74.173 -190.203.238.156 -88.25.138.178 -90.203.111.252 -109.88.137.172 -89.151.173.175 -94.66.57.206 -186.95.58.130 -14.153.1.180 -213.108.149.97 -37.145.47.214 -32.51.15.77 -158.181.103.107 -92.62.226.213 -213.168.24.2 -86.61.35.42 -87.244.68.187 -82.221.105.49 -177.39.37.65 -93.190.137.119 -24.107.14.224 -202.62.17.103 -112.198.64.20 -95.97.189.200 -187.233.175.136 -162.220.221.43 -89.142.34.204 -45.78.195.224 -94.157.236.220 -97.121.188.193 -24.93.199.96 -89.201.4.91 -83.50.179.222 -36.77.19.150 -178.217.27.193 -2.95.4.185 -81.17.27.234 -167.58.64.174 -104.200.151.76 -120.197.109.127 -41.250.70.94 -82.45.94.36 -191.17.69.226 -87.0.217.236 -190.73.156.224 -185.63.217.216 -100.68.42.202 -50.163.28.210 -71.19.252.27 -91.67.95.126 -190.62.100.198 -83.55.84.121 -201.11.58.115 -114.83.91.209 -209.213.169.101 -122.195.51.125 -77.105.51.215 -189.97.76.94 -186.62.199.48 -154.161.77.185 -109.188.125.42 -67.5.174.176 -192.151.148.186 -92.226.50.36 -99.112.205.199 -89.65.239.145 -112.210.26.78 -85.222.169.120 -114.79.37.51 -60.168.166.4 -68.2.69.203 -89.173.7.7 -151.238.64.226 -187.143.130.145 -177.223.6.146 -94.59.19.227 -92.246.211.241 -80.131.211.219 -92.208.67.183 -101.23.211.146 -201.141.173.60 -36.68.171.218 -87.117.198.189 -83.255.120.18 -50.23.115.115 -82.56.150.176 -86.6.159.7 -1.0.0.0 -87.103.104.253 -36.68.50.157 -173.160.188.78 -190.37.53.226 -109.236.90.135 -180.251.194.182 -94.11.72.96 -190.142.46.110 -162.72.168.31 -198.8.80.172 -98.211.161.99 -181.54.174.26 -111.95.163.59 -86.157.212.54 -85.28.95.185 -201.233.142.118 -223.243.44.185 -213.87.224.181 -95.88.49.98 -201.191.254.230 -95.19.16.26 -62.113.206.152 -97.123.149.144 -95.49.170.59 -94.68.201.168 -71.176.111.234 -2.62.1.52 -196.210.182.77 -86.166.166.183 -149.254.218.236 -111.95.114.153 -85.21.246.137 -78.151.93.233 -14.201.56.59 -105.233.77.29 -95.174.112.248 -5.141.188.165 -172.98.87.34 -152.115.56.228 -84.198.202.93 -75.132.213.248 -77.254.137.179 -89.67.104.161 -177.228.85.75 -151.224.96.67 -190.198.19.209 -62.227.200.68 -178.43.55.236 -2.62.23.162 -201.141.197.113 -128.39.168.83 -110.77.246.47 -82.36.186.247 -64.145.94.121 -182.249.242.9 -204.83.97.27 -81.131.148.40 -71.198.11.116 -81.184.126.146 -190.99.132.11 -189.70.85.120 -92.232.213.133 -187.190.149.24 -213.104.98.3 -91.59.157.5 -87.203.127.183 -14.1.200.73 -74.46.175.215 -128.90.92.90 -187.233.168.97 -90.46.77.211 -217.34.229.35 -77.51.168.226 -217.235.240.122 -81.155.44.48 -24.66.164.123 -67.61.226.128 -88.81.90.161 -201.18.124.164 -76.88.140.57 -101.99.147.59 -80.202.240.76 -73.42.123.157 -78.148.248.150 -81.141.4.217 -178.157.238.33 -77.172.223.31 -79.245.223.4 -81.141.16.237 -83.170.104.253 -93.230.48.203 -192.167.1.4 -201.143.101.125 -117.82.95.109 -173.230.171.42 -202.80.215.47 -171.97.185.187 -75.172.14.95 -88.232.5.214 -190.231.55.159 -50.40.217.241 -87.110.50.162 -71.86.177.48 -5.238.238.134 -176.10.63.196 -78.0.6.52 -108.81.43.50 -115.79.200.157 -188.23.146.68 -87.226.22.203 -143.177.130.57 -186.205.38.15 -131.94.186.34 -213.22.179.152 -171.97.220.88 -62.212.103.39 -178.221.145.105 -78.132.85.156 -221.163.72.245 -71.54.170.137 -88.217.180.120 -1.0.0.0 -46.39.230.225 -190.199.35.111 -18.111.20.175 -187.170.145.98 -46.44.32.20 -107.138.93.38 -93.47.133.195 -171.4.193.144 -190.36.128.114 -103.27.223.89 -99.228.186.52 -85.140.0.78 -24.17.41.205 -80.117.234.46 -188.18.15.9 -193.92.162.244 -66.177.82.24 -188.25.174.94 -75.166.214.12 -58.10.204.156 -198.8.80.33 -97.121.143.100 -188.18.14.133 -5.68.180.88 -197.134.127.130 -96.240.86.151 -174.91.141.219 -77.117.102.55 -111.75.99.167 -174.62.75.38 -77.9.170.119 -14.203.72.239 -70.30.52.78 -189.26.209.43 -179.94.175.165 -73.90.205.121 -186.79.30.184 -75.156.118.46 -79.204.151.112 -81.5.98.104 -0.0.0.0 -104.156.228.101 -174.52.86.133 -121.214.11.69 -46.159.144.158 -70.194.133.202 -93.181.13.101 -96.254.64.47 -178.36.6.207 -27.159.20.249 -99.229.142.108 -93.156.85.152 -250.31.16.246 -87.21.89.166 -146.199.167.59 -176.248.174.118 -83.209.227.175 -176.14.152.87 -97.114.122.123 -195.38.124.224 -151.238.70.86 -76.23.11.16 -84.192.131.77 -216.150.98.41 -213.79.35.221 -81.83.11.251 -188.198.161.33 -41.150.126.77 -197.116.88.51 -84.188.79.10 -31.207.111.218 -201.210.191.90 -95.189.22.182 -80.236.18.96 -188.159.173.48 -2.62.19.20 -192.0.0.2 -62.178.107.69 -96.49.76.100 -187.244.193.17 -99.43.85.101 -140.168.123.154 -83.45.160.174 -95.19.21.165 -82.194.196.253 -91.48.62.202 -85.212.65.71 -205.220.163.91 -115.117.126.224 -46.159.168.3 -179.7.174.165 -104.228.3.233 -79.191.27.114 -222.228.145.118 -79.112.56.241 -94.25.133.48 -187.254.153.218 -46.236.145.3 -37.14.5.90 -95.17.250.151 -86.17.238.232 -62.165.44.46 -203.87.201.150 -110.168.232.186 -87.103.52.73 -92.106.138.114 -177.188.209.220 -92.224.245.246 -200.82.209.75 -176.219.147.221 -182.15.219.243 -36.84.13.160 -87.14.218.112 -85.75.133.89 -73.214.19.5 -47.89.29.74 -178.222.73.219 -199.7.156.128 -109.111.243.164 -91.48.40.154 -92.4.80.144 -188.130.136.160 -190.74.50.60 -109.98.165.225 -40.127.96.154 -179.236.252.159 -110.167.196.251 -53.150.186.201 -94.180.149.108 -75.114.240.23 -60.93.52.103 -91.14.44.208 -117.212.122.217 -78.8.148.124 -178.254.191.97 -188.103.130.30 -79.94.135.249 -2.187.202.229 -92.4.80.144 -98.247.82.17 -2.223.240.102 -97.95.202.36 -80.233.175.48 -84.159.253.190 -179.7.160.222 -5.143.133.236 -223.92.12.38 -178.120.146.6 -79.245.210.198 -218.86.161.254 -187.190.9.31 -93.123.163.96 -5.28.165.169 -188.73.192.30 -1.172.122.137 -93.100.39.93 -71.9.253.183 -109.203.146.219 -109.236.87.249 -109.194.99.77 -93.137.178.190 -177.17.121.175 -213.49.118.166 -67.70.137.170 -151.75.247.137 -94.216.219.178 -184.20.11.173 -71.202.52.116 -77.231.221.177 -77.248.238.60 -125.238.117.232 -14.192.209.4 -5.18.59.69 -219.90.240.193 -186.95.68.180 -217.235.247.159 -198.8.80.135 -24.114.70.175 -124.168.147.253 -31.10.151.160 -199.48.242.40 -83.26.30.141 -92.20.147.219 -77.105.60.148 -77.183.59.192 -92.144.80.67 -77.52.137.36 -79.204.148.117 -174.53.149.224 -124.171.175.152 -196.217.77.156 -77.9.114.209 -87.145.6.215 -128.71.195.108 -113.254.169.53 -49.143.138.98 -115.188.90.227 -115.70.4.78 -151.18.52.171 -167.220.196.200 -183.26.225.165 -171.39.67.3 -78.23.220.227 -13.91.97.67 -23.29.221.59 -112.87.150.52 -114.218.143.23 -202.62.16.128 -87.206.73.74 -156.241.140.131 -73.90.205.121 -31.179.120.196 -93.138.0.219 -92.106.200.119 -91.177.116.22 -91.115.63.103 -186.91.40.63 -95.114.26.116 -1.0.0.0 -98.193.70.55 -24.155.223.251 -52.41.9.64 -37.78.218.36 -67.184.154.245 -105.157.71.59 -57.40.230.77 -66.63.177.52 -178.35.140.252 -137.135.57.205 -89.242.113.52 -171.96.167.131 -88.200.136.162 -41.96.128.249 -212.228.253.143 -190.237.183.46 -82.197.214.31 -99.197.201.17 -193.92.162.214 -110.168.232.10 -187.79.220.69 -14.154.130.95 -191.32.70.254 -196.210.206.2 -171.96.172.161 -36.228.0.15 -186.53.5.218 -106.192.52.162 -76.4.181.219 -181.223.157.1 -93.33.181.113 -181.56.231.230 -79.147.194.118 -70.21.184.26 -72.181.176.144 -190.22.132.88 -87.185.5.211 -58.96.38.219 -76.188.205.173 -70.75.192.84 -171.96.172.138 -198.8.80.159 -77.7.205.190 -180.154.153.136 -14.20.208.82 -5.65.70.202 -94.241.244.103 -108.53.251.199 -87.114.4.176 -123.201.196.249 -182.239.83.217 -220.246.220.129 -99.162.89.78 -89.247.168.201 -60.50.60.169 -137.175.202.108 -199.102.52.141 -176.184.17.43 -90.191.99.12 -52.43.103.26 -212.89.231.162 -23.99.90.8 -141.134.88.149 -91.203.224.238 -101.164.115.94 -76.124.76.145 -112.215.124.102 -41.251.10.68 -62.158.230.71 -71.233.46.161 -93.142.241.147 -115.184.241.47 -31.165.68.177 -87.226.22.203 -174.35.172.33 -0.0.0.0 -96.42.233.155 -93.130.157.247 -77.71.174.94 -190.255.15.213 -144.76.80.131 -79.101.135.191 -92.37.143.70 -164.183.100.67 -213.229.68.54 -188.82.171.37 -87.5.5.150 -113.91.239.36 -189.24.147.194 -115.87.206.178 -91.113.63.204 -94.242.246.23 -122.109.70.166 -173.31.28.160 -112.215.123.199 -188.69.199.38 -1.52.142.82 -87.249.198.29 -115.87.121.70 -186.28.160.243 -86.95.37.125 -75.114.240.23 -146.3.183.92 -186.92.79.138 -75.114.188.94 -187.149.94.117 -176.104.23.247 -93.136.52.207 -101.160.157.100 -188.40.132.58 -216.14.113.63 -37.79.250.153 -223.204.249.191 -146.90.128.2 -112.215.123.68 -108.223.93.209 -68.9.115.43 -123.3.242.122 -178.222.13.145 -203.109.100.180 -94.23.213.47 -79.66.123.46 -200.8.245.5 -213.155.201.176 -189.203.175.93 -84.22.108.241 -24.66.37.121 -217.235.248.39 -188.30.191.234 -220.173.178.6 -186.117.166.66 -219.79.25.187 -59.172.140.165 -79.198.45.189 -77.221.3.223 -178.234.10.109 -189.133.15.40 -83.22.64.57 -92.20.147.219 -24.184.24.90 -91.7.25.178 -171.5.190.70 -107.170.103.218 -212.71.251.82 -186.90.61.39 -31.162.226.180 -97.83.176.11 -109.145.155.47 -176.214.237.6 -192.169.99.9 -2.34.229.181 -78.132.70.52 -82.168.244.104 -202.62.16.48 -122.121.187.21 -90.105.199.214 -178.234.112.98 -83.7.184.139 -188.167.239.0 -87.158.147.150 -79.191.66.221 -106.69.243.28 -81.158.21.236 -159.205.255.59 -46.103.220.87 -24.91.145.46 -79.22.220.247 -213.152.162.149 -0.0.0.0 -216.82.207.195 -82.55.110.9 -92.229.102.229 -37.190.51.43 -46.39.231.0 -5.138.59.135 -92.127.61.67 -77.243.183.19 -128.204.198.23 -86.7.187.242 -87.0.202.64 -176.33.107.67 -81.171.71.41 -81.141.4.205 -101.99.43.251 -44.50.90.233 -184.147.141.21 -89.37.46.253 -161.41.101.111 -197.119.49.155 -93.215.69.236 -88.206.187.54 -82.213.132.233 -213.96.29.221 -178.83.191.233 -80.39.236.96 -78.22.130.71 -93.205.28.195 -197.117.250.77 -190.36.192.92 -5.140.202.59 -178.215.114.169 -65.31.4.167 -78.169.107.179 -46.142.129.19 -2.29.149.62 -94.66.57.130 -1.144.96.234 -202.62.17.197 -14.2.14.23 -94.3.94.90 -188.107.62.61 -78.145.233.123 -104.174.85.252 -128.75.237.122 -194.33.80.12 -64.134.224.47 -198.27.97.180 -213.227.255.94 -181.67.78.116 -80.71.250.255 -181.62.238.228 -140.168.123.59 -178.127.18.12 -91.158.213.84 -192.30.89.167 -208.167.254.71 -181.45.165.48 -2.125.75.3 -185.18.140.49 -178.121.168.9 -BTCD.RT1253731 u.2507+c.2507 b.2507 v.2507 (0+230/231 1st.2507).s231 to 2507 N[2508] h.1253731 r.1253730 c.1253500 s.1253730 d.0 E.2507 maxB.64 peers.27/64 Q.(0 0) (L.1253731 2507:231) M.1253730 9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422 ledger.a80cd39714953dca bQ.62 0:04:45 stuck.0 max.0 -151.66.241.195 -89.230.50.96 -186.79.224.179 -120.59.90.181 -5.167.37.199 -93.212.228.76 -74.119.170.51 -83.162.226.231 -50.44.184.78 -31.6.45.119 -90.0.19.234 -87.242.49.243 -46.98.119.33 -2.235.105.143 -81.231.244.196 -46.29.155.69 -150.101.230.179 -37.14.20.75 -76.75.71.45 -12.247.29.158 -95.27.77.137 -189.41.50.168 -79.200.222.225 -190.177.79.90 -71.193.134.45 -2.146.128.134 -77.168.163.194 -178.234.146.7 -125.238.118.21 -121.135.125.6 -109.10.42.135 -99.248.251.175 -201.67.2.161 -95.69.221.181 -218.142.75.243 -73.90.211.41 -80.103.93.63 -222.230.78.190 -85.230.77.92 -201.210.169.170 -50.106.33.87 -79.206.175.208 -118.98.97.185 -216.84.157.50 -86.5.124.225 -202.62.17.95 -202.62.16.98 -212.178.255.116 -78.132.33.246 -61.0.80.138 -104.34.13.253 -193.107.92.137 -36.83.30.100 -151.224.62.223 -85.49.128.43 -95.17.252.153 -93.169.65.197 -77.247.181.164 -159.206.179.155 -62.28.52.105 -79.21.114.72 -79.109.68.82 -189.238.214.70 -5.175.208.105 -94.205.1.88 -77.46.166.42 -107.77.72.19 -117.79.232.152 -71.41.55.254 -46.146.200.184 -78.132.134.30 -37.140.34.39 -178.120.23.138 -151.246.175.245 -5.156.4.175 -90.57.154.134 -78.225.68.197 -79.200.205.172 -109.230.44.230 -88.112.142.101 -189.35.206.229 -109.98.7.137 -117.192.218.30 -202.62.17.226 -70.74.244.109 -24.237.33.141 -66.228.50.86 -176.94.190.132 -72.38.223.95 -14.177.105.14 -24.184.21.63 -95.42.118.20 -190.207.77.25 -97.127.95.119 -63.87.254.155 -158.69.31.37 -0.0.0.0 -93.190.138.125 -46.166.188.208 -91.153.132.148 -217.228.57.165 -104.131.230.130 -91.125.175.196 -109.188.127.98 -96.42.237.66 -18.111.120.219 -166.137.246.122 -192.0.220.162 -46.98.12.7 -205.185.223.46 -43.226.7.45 -77.51.66.64 -216.144.236.34 -87.15.42.16 -82.242.146.58 -78.83.62.131 -143.168.37.247 -95.73.121.11 -24.19.34.247 -78.132.93.236 -157.234.138.190 -31.10.149.202 -87.98.178.140 -213.87.120.151 -179.186.154.239 -94.223.109.110 -79.24.169.19 -94.23.47.197 -79.167.166.155 -223.204.251.54 -222.247.234.104 -201.211.225.122 -84.253.206.43 -207.204.233.40 -181.208.31.78 -79.204.158.178 -94.234.170.181 -62.113.206.249 -112.215.123.124 -71.204.55.160 -140.168.123.59 -24.186.214.154 -24.87.77.185 -5.65.69.184 -190.202.250.145 -62.178.142.138 -0.0.0.0 -198.18.1.95 -79.224.0.44 -108.61.177.98 -121.35.194.150 -71.195.208.134 -86.30.167.243 -94.66.222.49 -201.40.215.107 -193.238.38.144 -206.190.151.241 -46.65.39.5 -121.224.229.225 -160.177.60.179 -124.189.116.101 -188.18.14.112 -60.19.29.21 -41.144.65.47 -124.122.211.138 -78.122.253.28 -62.98.108.210 -108.97.6.214 -189.160.3.51 -151.229.236.167 -93.104.96.127 -93.141.228.45 -54.201.183.106 -199.119.232.215 -179.179.48.73 -1.0.0.0 -98.110.177.46 -106.68.169.229 -78.235.150.223 -66.190.169.246 -73.140.155.40 -89.179.245.29 -67.169.239.87 -85.117.108.204 -67.87.55.27 -94.21.205.204 -75.82.46.205 -180.181.123.211 -46.40.58.96 -37.27.137.252 -141.134.88.149 -195.208.169.199 -113.22.95.194 -23.97.232.97 -109.166.137.102 -91.59.157.5 -79.245.219.183 -67.236.80.43 -121.45.82.86 -109.209.161.4 -2.85.179.46 -120.164.44.57 -95.86.230.196 -189.103.250.193 -33.212.156.47 -202.62.17.132 -5.165.186.57 -95.71.8.110 -48.121.64.127 -176.252.21.38 -41.105.28.186 -77.95.54.152 -146.52.16.145 -13.92.176.214 -62.74.26.165 -202.62.17.22 -109.43.0.171 -31.34.176.124 -98.173.193.245 -168.70.60.110 -84.228.22.159 -190.37.128.143 -109.177.205.222 -89.223.38.46 -178.253.141.119 -91.182.2.84 -90.209.150.21 -168.63.185.23 -179.232.197.231 -179.7.166.165 -93.195.217.161 -79.107.175.200 -178.195.18.254 -37.188.229.37 -190.39.10.186 -213.211.39.184 -148.255.183.235 -42.98.152.105 -156.210.18.207 -103.254.154.250 -79.255.228.165 -178.254.173.143 -187.78.56.13 -112.198.77.34 -78.253.251.14 -77.168.116.193 -92.133.138.44 -2.38.64.231 -0.0.0.0 -94.25.171.140 -173.245.211.34 -95.71.9.39 -31.185.4.33 -96.240.92.118 -91.185.53.129 -189.59.173.141 -79.235.241.29 -95.134.62.105 -116.25.162.131 -122.219.223.82 -36.76.56.110 -46.98.122.128 -109.30.252.146 -0.0.0.0 -94.5.235.45 -62.84.249.76 -36.76.110.20 -78.122.253.28 -220.246.221.16 -188.89.24.254 -81.61.62.168 -91.67.247.232 -104.236.120.54 -124.122.27.16 -216.246.242.233 -205.183.5.208 -179.35.93.70 -93.81.135.76 -179.55.35.82 -60.166.235.168 -37.205.56.35 -0.0.0.0 -211.24.19.36 -87.2.84.39 -69.123.225.156 -113.254.169.220 -113.159.116.23 -91.181.197.181 -173.197.103.2 -42.61.246.207 -93.87.214.15 -77.53.37.165 -201.209.91.12 -62.163.89.142 -162.255.117.106 -188.226.171.134 -27.34.30.7 -94.3.48.179 -37.47.195.86 -159.172.226.177 -190.94.79.132 -71.9.247.75 -36.230.23.41 -184.88.116.74 -86.202.71.200 -145.255.21.173 -123.138.32.162 -82.131.40.121 -177.244.254.125 -77.3.125.36 -90.26.85.134 -5.141.202.140 -79.30.205.60 -82.56.79.206 -162.213.158.169 -81.47.68.213 -27.110.174.2 -62.233.161.171 -181.223.156.207 -100.71.25.195 -98.215.49.232 -41.96.245.97 -79.117.118.39 -94.8.255.224 -94.220.38.10 -70.214.105.111 -124.122.211.138 -197.202.249.150 -87.244.147.84 -128.90.92.104 -71.17.170.92 -94.209.4.28 -170.105.118.44 -46.61.46.86 -109.190.196.220 -109.201.219.106 -90.58.17.41 -8.8.8.100 -2.85.184.196 -103.47.132.46 -79.133.129.102 -190.203.199.46 -93.39.98.104 -84.92.49.138 -36.69.117.25 -95.221.121.107 -211.223.75.41 -58.7.217.226 -46.40.58.96 -190.139.245.143 -85.178.70.123 -109.90.216.220 -101.86.158.232 -5.254.97.83 -69.165.156.162 -66.244.243.71 -197.228.244.171 -89.201.143.8 -124.168.83.112 -109.221.74.155 -187.79.121.208 -147.174.212.205 -159.253.108.76 -105.107.107.89 -108.176.233.203 -95.127.186.240 -216.137.247.150 -144.76.80.131 -5.39.155.176 -95.30.80.59 -70.197.136.190 -92.47.117.145 -83.172.105.46 -46.45.177.105 -198.23.71.77 -178.223.4.97 -206.188.68.250 -73.173.136.64 -130.185.25.195 -37.79.249.241 -62.93.77.25 -151.230.112.174 -70.176.212.107 -140.186.42.40 -78.238.86.112 -89.210.204.47 -79.225.96.36 -79.151.214.170 -108.216.30.86 -254.10.154.56 -209.169.116.201 -182.182.49.168 -182.85.66.175 -189.204.176.165 -89.254.228.135 -172.98.86.180 -136.169.137.19 -96.26.11.23 -76.84.44.204 -90.33.0.92 -85.23.221.237 -94.51.47.247 -190.71.165.230 -93.86.251.111 -78.1.239.22 -201.233.213.167 -5.22.154.41 -90.191.101.40 -94.20.193.47 -177.39.36.136 -228.255.168.189 -77.189.0.87 -188.158.250.232 -79.245.222.98 -91.63.29.70 -24.16.227.151 -5.140.103.127 -2.97.122.142 -24.93.20.50 -162.105.147.153 -77.131.13.180 -81.137.228.44 -80.131.61.32 -114.124.32.33 -217.131.104.197 -114.146.9.91 -58.186.101.71 -79.225.117.161 -50.100.64.201 -113.159.116.23 -187.78.56.13 -79.101.163.235 -76.99.37.97 -177.43.27.207 -88.217.180.158 -190.62.160.100 -89.240.128.124 -80.174.238.232 -91.180.156.211 -92.111.224.150 -37.33.16.164 -186.93.233.2 -201.75.45.103 -176.253.92.248 -181.113.152.188 -151.235.168.3 -66.87.105.231 -93.123.163.96 -37.6.241.197 -171.96.167.221 -88.217.181.124 -147.229.5.69 -78.172.234.18 -83.59.145.113 -79.235.248.242 -91.97.49.211 -173.171.103.93 -85.59.71.189 -123.23.72.83 -203.180.120.138 -121.214.190.242 -112.81.14.147 -77.174.148.62 -25.3.101.63 -106.186.117.73 -31.186.114.70 -94.194.29.231 -194.25.88.251 -67.163.60.129 -97.122.182.147 -114.244.33.102 -95.232.214.73 -100.107.21.121 -213.198.237.54 -27.97.24.174 -37.6.124.54 -84.43.200.43 -92.11.32.51 -182.239.98.182 -201.32.61.11 -193.151.12.139 -18.111.60.56 -88.156.16.254 -128.72.238.171 -37.244.213.39 -79.31.221.169 -201.20.78.54 -0.0.0.0 -37.193.83.134 -78.100.87.147 -187.78.67.179 -108.221.194.216 -190.37.54.100 -179.43.128.34 -87.19.2.177 -37.47.8.4 -107.182.231.92 -89.142.139.140 -188.26.45.216 -0.0.0.0 -2.135.127.246 -103.16.26.207 -86.153.159.91 -109.43.2.126 -187.244.78.152 -71.97.33.233 -151.75.250.108 -88.170.196.80 -100.124.150.226 -78.137.0.103 -89.239.99.253 -162.216.46.78 -76.24.147.109 -77.254.205.10 -82.50.151.8 -2.85.50.0 -94.193.47.208 -185.124.230.193 -69.20.161.227 -81.246.133.24 -181.39.238.154 -46.147.184.84 -18.111.96.248 -63.155.2.193 -96.60.248.198 -78.207.218.25 -81.250.80.26 -153.172.192.46 -245.245.190.57 -67.0.18.218 -62.84.81.3 -103.28.115.235 -5.55.208.191 -217.123.88.45 -202.62.17.119 -94.177.81.33 -95.181.3.196 -99.172.17.234 -162.216.46.27 -98.90.67.180 -187.14.227.234 -218.250.11.174 -88.217.181.124 -78.69.188.169 -201.191.103.189 -141.223.152.249 -79.245.201.136 -67.177.206.230 -66.241.75.28 -95.84.178.168 -213.105.38.228 -94.181.233.37 -91.124.21.30 -79.141.166.17 -66.55.135.221 -108.61.228.169 -190.39.194.218 -119.39.236.134 -95.145.103.125 -2.229.136.11 -178.44.27.186 -218.255.254.190 -79.234.100.79 -46.158.242.81 -5.165.135.68 -186.91.130.118 -151.238.69.129 -122.175.144.74 -190.36.221.26 -89.146.60.241 -78.42.188.215 -72.14.177.91 -146.52.3.167 -146.52.16.145 -179.215.223.24 -88.207.0.181 -148.177.129.213 -87.168.167.96 -113.91.239.76 -78.88.29.163 -197.202.240.7 -187.161.83.225 -146.115.178.8 -83.11.145.235 -81.170.151.88 -88.6.13.88 -187.3.247.42 -220.137.43.135 -109.43.0.64 -213.151.1.230 -213.183.56.124 -87.109.45.12 -90.76.58.10 -14.198.159.95 -171.108.129.71 -189.129.182.159 -75.106.106.17 -88.14.212.76 -196.38.233.200 -24.96.26.254 -196.224.64.129 -84.147.123.215 -178.234.197.80 -91.224.96.243 -46.163.71.123 -171.4.232.251 -65.130.211.240 -190.207.4.72 -83.185.91.165 -86.19.142.124 -50.99.242.140 -208.66.28.37 -5.167.77.185 -112.215.124.182 -186.87.36.127 -190.88.244.75 -85.2.91.156 -93.131.97.28 -93.87.184.75 -72.80.67.77 -67.168.77.63 -24.212.88.112 -95.221.214.198 -175.136.176.196 -45.49.180.110 -109.43.3.23 -31.6.57.61 -77.11.217.57 -190.8.243.40 -187.78.53.57 -202.62.16.219 -80.237.22.69 -188.0.42.111 -209.188.18.43 -37.187.155.143 -118.209.232.218 -0.0.0.0 -159.253.104.154 -79.32.146.219 -87.185.12.225 -94.21.136.99 -198.199.111.146 -89.230.159.154 -67.204.56.10 -151.31.139.77 -62.158.154.188 -250.31.16.246 -104.200.151.80 -24.122.34.75 -82.181.13.55 -213.220.249.220 -71.176.46.169 -93.138.18.133 -184.88.116.74 -41.200.200.28 -94.113.72.197 -187.233.132.132 -46.5.0.161 -171.39.41.252 -187.155.97.233 -142.129.40.169 -54.200.198.82 -121.219.36.217 -189.174.170.55 -202.67.40.25 -194.47.109.200 -121.236.66.181 -171.39.26.245 -105.208.129.73 -79.24.119.90 -171.92.213.16 -151.224.152.231 -124.123.86.38 -81.71.91.126 -178.43.29.179 -223.207.122.199 -41.96.46.215 -189.239.115.156 -37.214.145.68 -121.211.89.111 -185.128.41.158 -41.246.123.128 -91.125.251.114 -104.158.176.65 -142.217.187.68 -173.189.166.182 -194.105.229.67 -174.16.185.42 -117.207.3.59 -69.165.254.195 -82.76.49.200 -0.0.0.0 -81.4.227.11 -2.99.222.116 -37.59.7.79 -89.65.234.136 -41.105.236.122 -79.245.205.193 -99.243.37.210 -188.73.192.30 -117.202.139.192 -76.99.37.97 -108.61.228.160 -183.15.242.154 -46.208.8.139 -62.240.181.147 -184.75.221.106 -69.40.145.76 -95.90.54.249 -52.53.236.222 -84.189.218.207 -161.167.37.106 -61.153.226.82 -79.224.0.44 -68.202.102.68 -188.207.95.41 -82.73.127.246 -31.54.226.230 -86.137.159.144 -85.174.34.176 -188.143.107.34 -190.37.97.133 -95.137.245.107 -109.197.66.62 -0.0.0.0 -203.87.129.142 -186.90.170.182 -78.145.238.131 -81.35.192.157 -190.26.40.17 -107.191.33.13 -74.51.57.173 -110.184.11.142 -0.0.0.0 -94.216.201.100 -83.220.237.57 -101.39.6.57 -109.175.113.175 -190.79.237.7 -124.122.41.109 -95.153.131.236 -69.197.181.114 -82.242.146.58 -74.111.229.219 -79.206.165.124 -192.151.148.186 -125.113.225.243 -189.177.91.251 -188.159.148.104 -177.39.37.153 -191.6.118.35 -173.198.238.83 -73.134.127.76 -104.172.170.74 -90.212.244.231 -BTCD Q.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) -189.59.195.43 -186.66.4.154 -174.28.153.216 -178.16.215.164 -122.149.208.35 -92.22.215.63 -83.138.249.88 -79.117.87.152 -188.17.112.90 -128.82.31.114 -109.209.194.113 -85.114.175.186 -83.11.67.88 -91.127.82.222 -62.68.106.115 -81.171.98.35 -184.64.19.148 -202.67.40.27 -91.141.3.205 -213.19.46.138 -67.43.116.233 -186.90.170.255 -109.0.0.31 -94.242.246.24 -108.23.17.119 -95.68.68.208 -46.139.162.104 -91.105.23.69 -24.65.232.255 -174.33.168.74 -95.28.186.141 -209.188.48.220 -109.43.1.168 -172.243.168.80 -89.172.205.251 -85.177.101.54 -115.88.119.132 -92.144.81.208 -80.229.146.133 -187.74.82.136 -71.218.165.31 -107.203.48.251 -84.154.166.32 -96.231.58.246 -191.23.3.239 -163.125.49.31 -84.154.93.193 -83.149.45.46 -78.15.204.86 -64.145.76.227 -90.164.181.147 -188.143.66.100 -91.63.7.2 -212.54.195.80 -130.180.220.46 -37.212.159.101 -68.224.6.180 -117.44.175.180 -211.91.223.39 -213.87.225.204 -188.168.145.223 -64.145.76.166 -180.94.82.42 -194.33.80.12 -79.130.190.240 -88.251.131.252 -52.78.24.7 -177.237.153.199 -24.170.254.35 -93.81.215.149 -37.147.67.237 -205.221.255.10 -36.78.194.162 -212.110.12.247 -201.248.244.231 -203.217.68.236 -104.237.143.215 -184.20.11.173 -80.229.146.133 -190.37.53.226 -70.215.7.228 -86.173.82.203 -203.111.224.35 -86.213.175.91 -94.23.29.195 -171.97.179.130 -181.24.41.5 -218.85.98.82 -93.143.246.250 -69.167.30.89 -46.46.208.61 -188.162.39.235 -78.80.54.23 -188.36.48.170 -179.198.46.19 -95.25.80.102 -77.162.138.28 -95.81.196.114 -5.42.92.88 -86.31.255.144 -105.2.95.87 -91.182.27.151 -80.31.158.250 -83.30.209.69 -2.86.47.118 -190.219.162.2 -79.245.208.136 -5.141.222.85 -178.62.10.67 -49.147.99.6 -90.60.115.247 -159.20.211.202 -49.181.182.80 -151.62.24.33 -37.47.38.27 -197.202.231.20 -186.212.36.105 -71.52.51.171 -86.135.18.75 -178.59.121.172 -91.148.114.205 -90.208.175.48 -88.123.48.123 -71.127.224.26 -101.184.137.186 -186.91.139.45 -101.184.130.85 -24.76.192.85 -197.37.149.32 -183.102.244.241 -151.228.170.206 -114.125.188.231 -61.90.25.159 -86.128.192.204 -41.244.240.73 -92.19.38.229 -94.216.207.28 -37.146.123.6 -188.69.210.86 -172.94.99.73 -125.165.31.1 -202.62.16.28 -37.146.127.175 -174.6.78.67 -64.71.77.50 -223.204.246.6 -76.25.23.251 -109.79.58.72 -188.31.153.62 -79.222.119.160 -146.52.50.232 -189.250.37.47 -87.7.63.165 -83.13.133.86 -35.62.33.205 -179.55.88.37 -172.56.23.96 -2.162.177.123 -190.39.45.189 -24.99.180.167 -104.34.30.248 -79.245.212.122 -80.101.191.202 -76.10.150.110 -181.24.43.245 -79.47.224.126 -86.211.114.37 -188.4.215.51 -89.104.6.79 -104.243.34.106 -95.26.34.131 -31.57.94.128 -112.215.124.102 -125.69.38.128 -186.95.6.151 -181.208.95.168 -75.108.167.179 -190.38.198.253 -209.188.32.147 -179.186.112.94 -54.165.27.102 -109.43.0.18 -152.234.132.59 -35.9.171.155 -50.51.197.8 -213.197.38.170 -86.152.54.251 -82.57.5.189 -80.131.60.202 -93.129.140.155 -69.7.91.24 -134.36.208.166 -84.251.165.229 -77.234.40.151 -61.90.27.245 -190.28.189.103 -113.254.169.130 -87.168.108.59 -78.235.150.223 -5.238.246.218 -5.167.32.244 -94.222.242.178 -50.114.6.16 -193.92.193.140 -128.75.218.21 -1.144.96.140 -179.177.124.224 -112.198.77.130 -219.73.14.96 -88.152.186.122 -88.196.236.26 -184.75.213.132 -78.25.120.68 -177.201.61.252 -201.41.173.2 -113.64.8.2 -176.104.36.109 -25.13.191.166 -2.97.162.47 -80.229.35.19 -40.115.45.107 -121.211.218.102 -58.168.26.66 -80.106.197.192 -84.236.59.214 -116.114.142.67 -124.171.136.150 -95.19.24.198 -93.156.81.50 -45.63.61.127 -198.23.103.87 -189.114.232.39 -189.229.167.181 -159.118.61.183 -45.55.151.50 -31.181.236.89 -163.158.250.139 -79.41.170.156 -108.61.229.10 -88.25.236.29 -190.3.209.72 -108.223.6.145 -95.175.104.22 -83.26.180.72 -202.130.109.150 -78.139.196.85 -189.114.199.175 -186.90.89.83 -68.229.135.60 -82.131.218.204 -203.145.92.88 -200.109.43.18 -41.241.224.53 -71.53.159.168 -192.121.166.87 -101.183.63.236 -104.157.219.89 -202.62.17.78 -203.206.37.169 -186.90.208.129 -81.153.89.132 -47.67.70.34 -85.166.223.81 -181.65.33.95 -95.174.113.172 -186.42.104.138 -190.87.69.166 -76.10.161.23 -176.58.128.13 -188.108.36.227 -71.177.147.37 -37.220.84.192 -89.178.178.93 -76.68.254.64 -171.78.136.68 -25.67.145.206 -156.17.119.7 -210.195.195.68 -160.76.210.181 -84.165.3.177 -187.230.36.79 -79.45.99.172 -68.129.158.12 -71.219.139.245 -201.240.242.139 -186.119.174.41 -113.97.132.45 -92.225.37.221 -95.175.104.22 -171.149.2.249 -100.105.53.177 -93.195.208.18 -108.61.48.17 -105.228.147.187 -59.101.186.240 -176.38.117.15 -198.252.123.121 -70.193.167.238 -173.65.129.85 -92.75.124.244 -46.167.28.138 -158.181.103.107 -53.193.238.83 -5.42.102.21 -81.108.157.78 -109.90.101.71 -66.55.144.245 -5.254.97.90 -181.167.112.208 -216.155.131.195 -113.254.168.141 -217.88.3.79 -172.56.9.204 -94.66.57.80 -171.250.154.38 -93.171.161.108 -92.69.227.130 -109.93.84.203 -92.93.148.140 -125.208.174.71 -97.82.95.148 -71.9.248.87 -120.22.205.53 -41.174.167.165 -201.211.181.115 -86.131.238.37 -123.118.140.58 -2.88.117.241 -18.111.106.205 -46.103.168.112 -178.184.11.84 -130.180.218.205 -85.186.135.106 -100.80.184.135 -104.200.151.35 -95.132.133.114 -106.192.7.54 -88.217.181.157 -195.209.48.241 -178.41.95.247 -77.218.226.1 -124.122.19.135 -188.162.37.144 -185.45.13.150 -92.108.233.53 -61.93.52.22 -177.17.190.131 -93.81.182.89 -93.139.171.57 -151.72.136.1 -2.85.62.106 -177.242.208.166 -69.167.32.159 -70.174.26.142 -178.93.129.60 -186.59.92.166 -193.92.113.59 -47.55.212.189 -86.81.26.232 -199.48.245.116 -163.172.137.241 -202.62.17.60 -186.88.199.92 -27.55.91.64 -88.17.166.160 -71.31.223.116 -178.164.155.102 -79.100.168.58 -137.189.91.71 -79.185.83.6 -60.218.122.249 -62.176.13.182 -162.156.115.215 -85.24.169.215 -74.108.73.130 -94.193.136.252 -100.101.141.18 -87.118.25.232 -79.204.167.160 -79.250.37.162 -190.79.151.17 -105.224.161.218 -104.200.151.30 -95.25.143.95 -37.188.230.20 -46.188.125.237 -86.213.221.91 -187.204.32.239 -118.209.183.77 -84.176.248.102 -93.141.164.210 -93.120.33.100 -109.43.0.139 -190.78.24.228 -118.186.151.51 -176.154.77.92 -112.81.12.8 -87.79.171.84 -188.69.208.134 -109.124.202.134 -78.125.183.215 -85.178.86.218 -171.96.167.179 -188.163.65.21 -91.140.100.221 -95.19.29.26 -109.190.9.138 -190.39.175.89 -91.232.105.11 -5.141.169.226 -209.95.50.146 -98.203.0.178 -64.145.94.121 -213.87.123.136 -2.122.165.251 -109.201.133.140 -198.84.201.135 -86.210.89.109 -97.99.207.76 -201.216.15.82 -197.211.52.27 -95.246.254.103 -95.252.134.151 -79.45.100.128 -94.11.149.91 -88.137.73.82 -104.131.170.147 -88.167.140.73 -108.202.111.84 -82.181.13.55 -190.56.114.113 -2.99.221.25 -46.216.100.240 -71.30.197.75 -190.201.120.214 -5.138.18.24 -2.61.184.34 -68.148.177.25 -188.26.139.30 -140.168.123.167 -94.50.196.84 -50.137.141.201 -85.228.201.142 -104.175.162.231 -95.19.18.117 -83.82.131.238 -78.157.215.233 -31.23.47.67 -94.68.230.137 -53.193.238.248 -94.54.72.158 -213.87.121.70 -190.36.247.207 -123.148.105.78 -24.27.53.213 -143.48.117.186 -86.128.158.98 -212.190.177.186 -109.194.110.54 -189.174.176.240 -81.202.82.179 -88.141.117.52 -109.81.211.44 -88.69.90.177 -87.0.208.25 -83.85.203.206 -114.125.184.144 -78.137.14.11 -188.158.167.162 -190.38.157.244 -121.121.121.224 -100.9.27.223 -79.70.37.23 -177.9.79.75 -197.225.230.167 -24.253.97.161 -65.28.240.121 -76.21.107.113 -166.170.14.126 -86.81.111.103 -81.141.6.218 -108.71.232.32 -121.175.188.133 -179.5.11.54 -186.91.87.81 -78.148.248.150 -189.41.69.166 -188.208.105.198 -24.17.172.33 -173.74.190.170 -128.72.218.191 -25.4.3.201 -24.175.65.6 -66.87.66.220 -178.141.162.104 -81.158.189.210 -96.30.159.45 -69.167.31.166 -93.147.216.154 -177.42.121.198 -202.62.16.152 -79.157.252.14 -76.21.107.113 -128.71.102.82 -93.34.48.75 -69.7.86.218 -70.30.19.40 -2.219.68.243 -190.205.166.112 -203.164.148.154 -151.15.56.129 -193.253.170.86 -190.73.40.185 -24.231.137.146 -41.174.139.14 -200.75.102.219 -190.200.107.145 -171.96.170.169 -150.29.142.101 -14.98.83.166 -109.43.3.24 -201.211.225.122 -50.81.149.145 -53.193.239.251 -115.239.120.141 -188.114.163.176 -79.245.216.10 -71.19.249.4 -84.99.198.192 -91.228.204.51 -171.149.2.249 -50.51.65.134 -50.48.150.80 -74.12.45.62 -76.99.37.97 -75.189.132.144 -182.87.167.175 -70.44.128.63 -88.196.10.83 -62.232.5.242 -189.214.6.82 -78.138.106.240 -77.28.14.8 -73.90.209.112 -81.162.122.102 -79.255.224.173 -108.252.164.33 -190.203.14.155 -197.207.33.170 -92.133.75.32 -212.174.163.152 -209.107.214.80 -60.211.184.242 -24.40.146.45 -186.46.206.91 -91.148.94.105 -94.233.97.100 -204.186.68.213 -197.88.129.16 -108.185.135.18 -95.25.10.41 -112.208.185.255 -5.61.93.226 -81.158.203.27 -62.149.25.99 -66.237.51.224 -2.228.69.84 -47.88.79.118 -188.129.113.90 -46.59.172.34 -217.95.236.212 -24.137.85.148 -91.185.117.103 -24.17.139.255 -186.88.33.5 -1.0.0.0 -84.92.106.61 -110.168.232.136 -218.30.116.8 -188.174.91.59 -84.215.211.115 -50.0.0.56 -128.90.92.104 -190.171.121.223 -188.239.15.25 -71.90.53.87 -174.148.152.154 -145.28.186.232 -212.198.177.53 -69.172.72.115 -105.229.140.158 -90.54.252.148 -89.204.135.163 -200.8.52.205 -81.101.62.218 -104.157.135.129 -95.113.53.138 -175.138.204.119 -186.92.251.74 -171.96.167.209 -188.69.198.224 -190.203.32.110 -82.60.153.56 -151.53.183.73 -104.156.228.71 -171.97.224.32 -5.237.52.187 -51.175.41.140 -146.156.249.160 -5.239.187.61 -162.216.46.79 -24.22.111.175 -172.58.16.128 -70.173.209.163 -188.16.122.219 -1.0.0.0 -173.199.65.38 -2.6.43.143 -100.68.139.112 -92.241.152.185 -2.97.165.140 -171.97.198.46 -95.141.28.120 -95.18.39.118 -94.191.186.178 -46.44.3.174 -202.62.17.7 -109.228.92.211 -98.206.56.123 -90.205.138.179 -85.220.18.205 -188.54.228.4 -87.7.152.225 -74.216.83.159 -178.221.180.123 -94.41.57.154 -91.180.129.192 -92.157.155.123 -31.15.157.135 -223.227.19.176 -250.31.16.246 -176.92.4.24 -176.49.127.211 -72.191.228.161 -108.24.82.4 -186.92.222.216 -36.71.162.55 -213.151.2.192 -70.67.20.129 -114.79.37.125 -79.167.174.105 -24.114.70.184 -111.241.89.140 -37.45.176.243 -85.222.168.41 -21.106.179.117 -78.90.74.65 -77.43.228.161 -81.245.102.36 -80.235.60.48 -84.104.85.140 -79.246.240.229 -89.204.153.239 -112.215.123.37 -74.207.189.1 -189.217.117.45 -93.123.247.211 -0.0.0.0 -159.255.11.52 -173.244.16.243 -91.134.120.210 -81.141.8.254 -95.52.155.233 -24.246.57.236 -109.201.152.243 -86.95.134.254 -212.83.191.197 -180.172.140.92 -181.42.16.241 -223.227.246.32 -58.44.187.100 -67.248.195.131 -213.152.161.40 -82.75.141.118 -216.4.56.185 -120.22.163.204 -188.162.39.180 -71.208.224.19 -95.252.27.29 -188.221.189.125 -217.88.13.199 -165.255.85.246 -82.151.45.31 -37.78.112.147 -213.102.150.212 -178.234.235.67 -84.44.131.103 -105.228.79.241 -178.206.88.22 -85.23.16.56 -179.229.178.122 -151.24.155.96 -201.242.164.67 -193.92.127.190 -81.136.219.237 -46.129.112.120 -37.201.195.214 -177.206.0.121 -36.224.107.193 -72.67.20.72 -46.147.229.101 -61.136.176.26 -37.212.159.101 -113.195.251.160 -177.16.121.49 -201.198.42.134 -173.182.128.9 -91.214.131.89 -188.0.47.15 -186.89.49.29 -64.247.87.184 -198.96.94.12 -5.153.133.34 -46.146.115.38 -202.62.17.253 -62.202.41.207 -1.0.0.0 -176.84.8.114 -2.61.133.195 -213.24.135.217 -2.85.57.6 -91.127.18.187 -178.217.61.229 -79.245.222.54 -37.190.51.38 -87.197.162.200 -92.209.186.41 -190.177.79.50 -85.56.6.223 -94.66.57.164 -41.96.150.179 -5.2.64.14 -204.63.214.118 -5.156.106.61 -1.162.23.172 -116.231.133.47 -77.49.129.46 -24.114.81.205 -75.144.36.41 -94.50.196.84 -94.196.198.83 -107.222.140.101 -41.105.236.122 -75.168.7.211 -100.75.135.9 -103.28.115.236 -87.171.199.84 -2.84.13.138 -154.20.188.72 -186.91.130.118 -31.57.93.197 -195.29.192.134 -223.227.9.239 -213.227.252.124 -111.69.136.191 -187.170.154.194 -217.44.16.102 -85.222.168.41 -112.10.225.195 -189.156.67.120 -190.205.166.112 -186.90.15.65 -200.108.51.202 -67.44.192.24 -92.237.52.138 -120.209.131.70 -202.5.158.177 -85.192.189.112 -46.246.27.154 -95.25.49.95 -87.185.8.189 -109.90.101.71 -79.13.106.74 -125.160.196.119 -173.72.136.151 -93.178.76.184 -113.254.169.130 -93.233.152.57 -78.144.191.65 -104.200.151.45 -49.146.10.81 -186.46.224.196 -88.206.141.108 -190.200.61.206 -94.197.121.40 -79.245.217.6 -2.240.130.103 -2.95.20.67 -104.238.169.9 -93.208.127.67 -98.119.235.95 -2.85.183.249 -81.44.162.170 -73.90.209.45 -80.106.197.69 -93.143.218.109 -185.93.180.126 -202.62.16.49 -112.65.211.240 -95.142.108.188 -85.211.8.234 -37.47.217.13 -109.221.221.236 -95.236.175.233 -84.0.102.77 -190.37.161.225 -188.233.169.18 -5.140.218.85 -69.131.31.129 -164.183.100.69 -91.205.64.202 -188.76.15.37 -192.155.95.192 -86.26.86.157 -91.7.16.25 -187.143.212.81 -77.173.188.205 -65.93.21.22 -100.91.109.186 -210.129.18.130 -84.147.114.223 -24.164.76.73 -62.183.124.221 -88.208.1.194 -82.28.121.36 -190.236.62.194 -178.43.81.171 -190.62.152.218 -89.212.241.225 -68.229.235.123 -178.122.64.75 -197.110.210.233 -104.28.201.93 -109.43.1.114 -190.70.91.241 -187.240.118.122 -41.150.125.109 -203.184.41.205 -188.129.213.220 -95.151.54.119 -68.172.251.98 -196.217.160.51 -37.6.225.42 -113.254.170.50 -1.0.0.0 -71.231.218.6 -188.226.195.109 -83.131.227.230 -68.5.130.116 -18.111.35.103 -109.208.182.118 -81.247.76.128 -231.112.130.210 -98.248.40.222 -177.7.102.99 -92.113.189.236 -95.26.205.91 -176.104.35.147 -93.79.71.20 -72.79.77.139 -190.213.142.25 -73.252.3.47 -162.216.46.125 -162.213.195.228 -162.213.158.169 -112.67.211.172 -41.48.191.235 -24.114.73.133 -116.205.23.233 -0.0.0.2 -110.115.32.92 -179.197.172.50 -138.91.165.233 -80.131.211.219 -88.14.20.177 -50.84.116.21 -164.40.228.53 -190.77.79.217 -186.144.112.38 -2.25.69.36 -24.114.76.239 -82.163.165.25 -186.90.184.149 -58.8.219.112 -5.14.222.215 -5.132.7.24 -68.87.76.243 -80.107.31.185 -114.98.87.245 -119.73.122.163 -79.245.219.88 -1.54.140.99 -109.74.162.200 -60.17.17.253 -141.255.56.249 -65.185.68.233 -185.65.132.120 -195.211.206.164 -201.210.136.83 -83.9.96.10 -189.188.174.83 -90.191.107.13 -176.10.63.196 -77.53.37.165 -171.96.167.227 -203.217.27.155 -71.239.236.145 -88.24.199.135 -2.181.155.234 -68.180.0.197 -99.247.170.15 -25.31.60.102 -202.67.44.10 -142.162.162.174 -179.192.193.202 -187.243.164.218 -175.138.150.222 -212.107.130.19 -24.79.178.91 -90.66.29.221 -203.98.92.130 -209.54.7.184 -86.177.72.232 -107.140.146.255 -202.62.17.78 -174.117.209.16 -172.94.99.73 -80.204.143.24 -188.221.74.104 -87.185.22.183 -189.226.123.32 -84.200.17.236 -186.91.50.237 -212.106.255.119 -224.40.3.89 -84.147.124.207 -85.229.198.73 -76.90.104.41 -190.212.244.19 -41.105.238.99 -189.47.90.126 -181.162.51.72 -128.90.88.120 -49.76.15.28 -84.142.125.8 -73.198.40.189 -76.99.37.97 -37.112.79.133 -99.238.196.59 -80.174.72.157 -114.244.45.88 -201.208.197.14 -193.92.127.190 -193.173.216.162 -139.193.221.33 -109.158.12.15 -64.145.94.48 -95.28.160.27 -185.7.46.146 -78.250.186.8 -69.159.104.146 -78.38.63.156 -179.126.249.236 -81.240.48.1 -244.209.195.105 -110.168.232.79 -5.14.221.9 -151.250.240.128 -2.217.210.28 -93.222.175.111 -49.145.140.122 -171.149.2.249 -123.53.89.184 -187.61.214.202 -92.224.245.246 -88.217.180.105 -108.62.225.240 -92.44.150.250 -71.201.35.156 -139.216.147.57 -187.233.182.174 -93.143.233.193 -86.197.141.131 -217.233.83.164 -84.135.91.85 -217.120.206.46 -151.20.124.54 -199.111.185.207 -52.78.91.225 -31.150.160.86 -206.123.150.137 -186.95.106.66 -110.167.196.251 -24.165.181.252 -62.98.9.235 -85.222.175.183 -176.84.165.12 -190.22.129.121 -0.0.0.0 -24.115.240.34 -2.100.165.102 -178.221.162.236 -179.110.98.186 -190.181.64.234 -1.204.8.21 -217.64.16.147 -93.137.203.121 -89.245.125.162 -62.74.23.192 -31.28.57.234 -82.123.62.119 -0.0.0.2 -209.188.5.234 -72.50.144.23 -58.11.110.34 -92.37.172.246 -205.148.137.165 -80.235.62.90 -37.115.172.148 -222.243.67.252 -92.24.149.39 -187.143.158.32 -108.12.25.189 -50.137.239.137 -108.19.160.97 -112.215.123.103 -186.93.225.184 -2.83.192.141 -201.242.121.142 -200.82.219.161 -90.191.168.246 -190.103.63.253 -2.103.0.246 -109.111.243.164 -77.168.116.193 -171.96.171.107 -176.210.249.150 -41.128.142.187 -166.8.189.210 -166.188.190.201 -125.24.154.62 -188.84.48.223 -104.229.193.72 -68.226.30.59 -219.73.101.145 -113.190.33.241 -231.190.16.139 -79.43.216.64 -209.197.6.177 -187.26.79.39 -24.114.74.3 -182.99.255.85 -82.235.133.55 -85.178.128.44 -94.41.64.71 -209.205.208.34 -159.29.194.242 -90.7.193.85 -190.73.66.101 -151.20.124.54 -88.9.101.254 -106.185.55.134 -78.225.68.197 -94.34.208.109 -46.98.111.40 -2.137.111.25 -109.92.122.58 -95.30.170.195 -79.159.102.102 -2.134.151.188 -181.92.15.216 -68.247.75.133 -150.117.170.89 -104.58.140.37 -79.245.207.167 -70.81.224.17 -84.19.165.218 -84.236.120.253 -86.156.8.126 -89.164.147.115 -189.59.116.231 -67.3.70.193 -23.94.218.151 -90.0.44.245 -79.143.165.131 -173.165.129.125 -176.93.171.12 -97.90.202.210 -94.10.79.126 -50.17.187.172 -86.85.128.100 -91.179.13.23 -86.173.80.107 -62.45.107.249 -109.204.151.99 -200.86.31.106 -0.0.0.0 -104.207.152.123 -109.76.221.45 -84.152.134.167 -186.91.142.193 -125.165.31.1 -188.162.132.82 -58.11.101.70 -79.204.182.114 -190.38.45.209 -86.80.230.190 -84.198.138.27 -85.242.84.158 -77.254.199.139 -94.67.207.249 -216.218.29.243 -78.35.153.26 -89.182.23.25 -79.165.175.137 -72.213.129.244 -0.0.0.0 -78.144.145.162 -172.15.208.80 -86.20.157.128 -64.188.205.179 -88.71.238.22 -85.140.1.122 -0.0.0.0 -109.88.184.11 -5.141.201.95 -94.181.94.128 -97.121.11.235 -93.55.192.12 -193.92.193.104 -179.7.171.165 -187.149.83.67 -0.0.0.0 -62.113.202.198 -189.202.73.82 -212.228.253.143 -181.128.111.78 -85.23.16.56 -31.132.225.205 -200.93.115.124 -42.130.174.45 -41.109.219.175 -138.99.148.20 -128.71.175.210 -178.92.103.221 -46.72.208.82 -170.152.244.231 -90.201.158.28 -217.23.187.7 -188.238.63.233 -81.171.71.145 -37.79.250.236 -105.155.44.171 -187.10.148.221 -79.152.183.84 -186.14.2.70 -87.202.44.226 -92.37.46.31 -82.60.11.203 -41.239.159.32 -212.71.239.55 -209.95.50.146 -113.254.161.101 -1.0.0.0 -109.221.205.158 -169.0.169.119 -187.59.221.156 -113.185.5.149 -95.141.28.120 -220.141.132.225 -50.158.229.59 -86.179.6.141 -85.51.145.189 -5.139.143.43 -217.89.4.240 -178.41.66.119 -170.0.21.4 -99.242.164.212 -117.193.62.6 -95.189.25.41 -37.45.88.138 -78.183.9.101 -209.112.242.83 -5.28.25.30 -71.52.54.197 -37.0.37.37 -67.177.203.222 -76.187.186.183 -114.96.99.19 -200.69.176.198 -31.132.225.187 -74.72.30.82 -50.153.148.174 -0.0.0.0 -91.103.38.0 -218.142.99.184 -67.136.44.155 -41.161.91.217 -83.26.249.88 -90.192.241.230 -31.61.140.252 -93.134.99.101 -95.215.60.22 -95.221.21.83 -39.35.33.24 -182.16.25.196 -66.55.144.246 -25.5.5.161 -91.182.48.19 -193.51.6.5 -91.115.63.103 -76.169.199.180 -99.253.26.181 -120.56.106.3 -180.251.194.182 -105.228.120.31 -90.9.145.61 -86.172.239.91 -85.179.131.77 -79.224.86.119 -24.65.229.207 -67.141.21.99 -213.87.225.204 -85.26.108.232 -110.96.188.37 -190.219.127.173 -86.202.71.200 -181.31.207.140 -50.5.127.178 -37.24.152.178 -178.92.91.59 -181.54.60.125 -5.141.231.188 -220.233.77.65 -91.158.212.23 -178.234.233.200 -96.127.136.18 -179.212.185.123 -101.108.114.192 -78.234.188.9 -178.120.131.163 -217.122.124.200 -45.63.1.236 -84.26.74.79 -88.15.230.239 -205.197.242.145 -187.254.159.150 -75.69.160.21 -36.77.19.191 -83.198.46.116 -90.104.92.241 -81.158.189.210 -186.91.198.52 -213.226.219.55 -74.109.190.39 -122.17.0.22 -69.128.222.166 -109.148.240.225 -217.235.255.224 -1.162.96.155 -194.65.46.7 -217.99.240.219 -222.254.29.181 -1.162.89.118 -113.162.145.181 -188.69.194.196 -114.217.17.35 -89.151.173.175 -89.230.65.93 -172.5.141.163 -173.120.226.13 -37.190.39.194 -41.96.104.28 -216.58.117.236 -222.47.197.29 -94.191.185.112 -201.208.13.107 -78.232.43.89 -186.90.67.226 -198.100.148.190 -109.77.111.172 -164.40.231.252 -109.88.154.44 -92.100.128.83 -176.31.126.191 -79.245.194.135 -119.224.42.248 -54.189.37.6 -178.126.244.130 -5.135.36.128 -1.162.95.90 -213.151.2.186 -98.108.240.147 -80.81.242.72 -134.249.208.212 -87.15.222.204 -68.233.247.206 -189.202.95.142 -75.82.43.75 -59.40.135.128 -84.127.218.248 -78.55.250.20 -136.159.160.254 -76.18.138.1 -213.87.224.108 -79.175.68.95 -24.111.193.89 -62.152.54.44 -188.165.82.238 -86.115.102.42 -77.182.14.34 -84.177.180.24 -68.48.26.79 -91.148.113.76 -67.169.167.174 -104.131.142.198 -85.178.129.138 -67.80.146.83 -79.16.92.158 -113.92.2.25 -201.229.84.90 -89.26.78.16 -176.210.249.150 -213.127.93.143 -197.225.239.193 -2.137.15.53 -2.62.10.239 -109.153.188.99 -122.231.161.40 -88.236.9.175 -86.194.143.131 -212.251.18.47 -2.85.61.239 -213.67.134.6 -46.40.3.22 -77.28.5.136 -85.244.119.66 -212.54.207.204 -91.152.158.166 -162.216.46.83 -89.178.173.167 -76.123.100.141 -94.50.225.189 -189.202.84.78 -83.209.227.97 -81.11.221.213 -84.154.93.193 -50.155.70.199 -89.38.35.81 -188.0.47.35 -5.239.189.169 -217.131.240.122 -125.125.36.49 -77.251.14.224 -213.87.127.200 -179.179.63.226 -88.0.193.105 -90.191.107.104 -217.249.8.127 -113.13.96.143 -60.228.7.131 -177.225.193.106 -87.228.87.106 -89.148.221.72 -223.205.250.2 -88.246.172.162 -175.33.51.90 -105.156.160.16 -18.111.35.103 -71.30.197.75 -128.227.44.156 -204.186.126.127 -171.97.232.160 -190.96.207.71 -173.54.222.61 -2.104.151.66 -188.2.75.7 -222.183.51.191 -254.85.113.235 -109.214.70.45 -93.80.192.247 -85.179.169.40 -83.134.9.165 -209.54.15.175 -114.124.6.53 -121.208.89.35 -74.195.24.126 -77.181.48.236 -194.105.229.79 -178.198.214.231 -79.198.45.189 -186.93.214.168 -181.10.83.45 -201.6.131.6 -71.192.103.83 -109.201.152.244 -213.139.53.26 -179.55.87.12 -147.171.166.52 -190.22.130.27 -95.18.37.144 -123.16.221.44 -174.148.11.181 -197.246.171.176 -37.150.246.127 -172.15.0.102 -89.36.109.189 -182.89.227.143 -71.220.184.56 -100.68.89.183 -209.73.136.231 -98.215.49.232 -62.227.194.150 -138.91.165.233 -172.88.252.206 -87.5.0.248 -91.67.236.178 -77.120.70.123 -45.56.39.12 -79.16.234.212 -0.0.0.0 -2.121.201.171 -77.49.210.153 -190.22.244.92 -75.174.90.85 -92.144.209.103 -79.245.218.167 -41.132.252.67 -176.52.8.50 -78.150.15.78 -24.12.49.237 -24.189.15.109 -201.248.248.9 -201.119.148.239 -171.96.181.31 -174.66.3.25 -174.119.243.201 -223.206.69.173 -45.56.46.176 -79.206.172.204 -67.44.192.186 -188.158.169.194 -67.44.193.22 -110.149.118.131 -70.193.167.238 -67.245.82.244 -99.4.121.145 -25.191.20.230 -115.68.116.26 -37.229.90.67 -186.83.12.194 -70.189.229.36 -123.16.210.191 -219.73.101.145 -189.153.44.62 -84.20.242.6 -179.55.35.82 -141.134.124.89 -84.24.63.74 -213.16.224.169 -85.76.98.73 -82.73.127.246 -117.0.121.2 -37.229.90.67 -112.210.36.207 -177.156.187.106 -113.254.169.237 -94.4.193.51 -78.100.87.147 -109.226.126.1 -84.159.253.190 -151.20.54.200 -74.109.186.240 -88.231.216.214 -101.116.36.225 -84.147.113.190 -91.48.37.59 -72.191.14.137 -94.69.53.225 -94.50.197.11 -180.137.141.239 -100.65.40.61 -37.188.233.210 -195.37.133.6 -100.4.151.242 -118.140.106.58 -BTCD received.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) 62.75.145.171 -83.5.143.28 -ramchaindata have 2507:230 at 0 | 1083 blocks 565.112kb redundant xfers total 4225.637kb 13.37% wasted -194.105.229.207 -78.32.154.221 -85.102.206.164 -78.111.190.48 -186.118.34.106 -BTCD Q.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) -BTCD received.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) 62.75.145.171 -165.255.211.19 -100.68.47.205 -188.18.203.231 -94.177.81.30 -90.151.184.124 -184.160.95.44 -79.66.126.192 -83.59.144.92 -84.154.93.193 -153.34.162.179 -190.38.148.249 -190.99.132.240 -212.215.224.17 -189.110.171.228 -188.239.15.25 -5.254.97.91 -124.234.84.44 -101.39.53.222 -189.204.177.58 -93.136.52.207 -41.13.228.209 -217.95.244.224 -98.251.223.23 -92.251.101.228 -37.188.238.115 -115.87.132.88 -37.252.127.221 -93.107.67.54 -202.99.16.22 -95.19.31.118 -84.106.253.6 -200.44.196.213 -200.106.89.56 -62.94.37.53 -86.212.5.83 -37.214.147.64 -41.141.65.94 -231.255.154.44 -67.181.59.52 -122.56.33.171 -12.170.41.202 -69.123.132.73 -101.73.92.57 -178.148.11.106 -108.161.125.223 -7.99.150.241 -42.115.112.202 -41.138.68.56 -89.254.236.121 -181.55.116.136 -83.163.213.240 -201.152.251.21 -213.45.49.161 -173.245.221.74 -78.151.193.140 -83.85.139.25 -78.223.119.211 -105.228.120.31 -178.37.195.27 -24.52.202.171 -69.34.135.229 -62.158.135.252 -77.243.183.25 -193.51.6.5 -46.8.157.22 -186.183.160.125 -130.234.206.24 -90.171.247.95 -90.216.200.56 -181.90.109.168 -94.208.224.23 -202.62.16.235 -94.174.9.29 -105.184.186.83 -180.252.156.92 -176.14.105.238 -79.204.138.25 -178.162.217.137 -50.124.7.101 -105.237.92.26 -217.235.248.71 -77.181.67.202 -81.244.67.231 -2.106.197.126 -198.60.192.203 -172.56.16.140 -109.93.83.59 -164.8.204.206 -80.131.61.143 -68.7.182.201 -187.37.140.36 -2.85.190.33 -31.61.140.246 -192.126.96.23 -190.42.58.145 -177.133.104.179 -93.125.88.66 -66.27.145.33 -109.43.0.90 -46.117.146.30 -68.101.51.124 -70.173.132.2 -95.103.163.175 -213.103.202.73 -193.77.222.200 -5.144.152.186 -190.77.248.84 -136.243.151.210 -31.163.191.135 -53.193.238.189 -176.51.149.113 -178.43.55.236 -31.23.114.101 -87.185.20.94 -109.190.65.26 -77.180.215.167 -85.54.220.250 -187.76.101.115 -104.200.151.21 -186.90.2.208 -179.43.134.2 -85.216.83.42 -83.44.53.138 -178.213.170.179 -149.202.44.159 -181.53.51.250 -85.4.99.184 -91.210.228.154 -100.87.134.150 -105.2.95.87 -104.156.228.106 -113.254.170.25 -109.74.170.77 -91.63.1.128 -184.196.189.176 -0.0.0.0 -98.23.36.117 -5.30.69.217 -81.156.49.21 -186.92.42.206 -24.155.201.9 -217.95.247.139 -78.1.135.191 -231.25.196.155 -92.40.250.89 -89.182.204.27 -222.65.60.115 -189.188.200.85 -109.184.107.220 -80.41.226.120 -68.247.175.72 -172.56.35.48 -93.109.240.14 -62.195.196.17 -109.81.210.29 -193.92.113.59 -217.95.244.246 -24.43.219.20 -118.90.32.199 -50.163.71.222 -50.204.92.20 -212.54.195.80 -73.11.157.169 -1.52.142.82 -77.4.123.65 -114.124.0.126 -80.131.61.147 -180.183.78.160 -200.109.173.48 -186.147.138.125 -189.218.127.228 -83.26.30.141 -87.178.158.126 -5.12.117.226 -117.195.26.85 -90.45.1.225 -46.159.55.58 -74.67.4.49 -168.70.86.30 -40.45.199.182 -120.156.17.55 -92.144.208.211 -176.65.127.119 -37.227.63.102 -1.53.140.105 -74.59.25.31 -209.107.214.70 -94.41.64.71 -71.61.74.28 -182.203.112.237 -194.105.229.51 -84.248.15.13 -88.91.89.94 -190.36.142.185 -177.133.210.69 -128.199.90.150 -79.17.250.93 -190.204.35.44 -95.93.101.100 -85.247.50.96 -83.36.224.90 -188.187.163.21 -37.201.6.202 -2.138.143.40 -212.5.52.32 -41.174.167.165 -108.176.233.203 -82.77.161.202 -173.86.39.226 -178.117.89.113 -81.250.82.21 -94.70.5.65 -86.218.197.161 -85.237.174.4 -62.249.146.6 -109.251.79.19 -165.255.212.151 -73.241.142.127 -202.62.17.51 -191.184.111.49 -90.33.25.232 -108.61.177.98 -111.69.86.174 -177.72.51.158 -46.28.102.197 -67.86.22.30 -117.184.152.115 -94.65.84.87 -158.69.126.193 -83.185.82.143 -60.51.44.27 -158.165.52.119 -78.43.68.161 -82.142.112.229 -109.169.229.160 -187.200.176.71 -192.153.117.70 -190.198.36.172 -174.49.110.107 -177.205.65.140 -162.124.179.124 -184.97.238.93 -212.251.28.147 -107.204.205.115 -118.233.235.7 -92.141.13.211 -94.194.29.231 -0.0.255.72 -217.174.155.155 -198.27.97.180 -101.183.39.28 -83.185.95.8 -31.174.69.205 -197.246.171.176 -46.158.93.79 -109.43.1.169 -37.122.124.42 -68.232.186.171 -79.245.219.75 -82.235.133.55 -188.162.14.104 -128.90.88.111 -80.60.124.251 -199.255.211.45 -187.161.82.160 -94.50.196.84 -190.31.72.99 -70.89.142.142 -108.24.86.234 -124.73.67.105 -177.157.52.241 -92.76.239.3 -189.144.45.28 -105.229.179.226 -92.100.195.14 -31.216.4.218 -99.197.201.17 -217.249.134.16 -188.73.253.71 -2.102.152.141 -24.0.207.196 -88.217.181.105 -95.221.16.31 -79.41.170.156 -162.255.127.179 -98.223.11.108 -87.11.82.157 -120.56.209.210 -70.215.195.68 -177.96.90.235 -71.31.219.197 -83.149.19.188 -139.0.138.197 -2.140.8.160 -110.174.123.194 -202.62.16.2 -113.254.169.102 -163.211.239.49 -25.150.39.43 -188.67.72.26 -24.212.112.98 -68.180.0.247 -0.0.0.0 -190.77.157.248 -95.141.29.55 -218.11.179.53 -123.57.15.153 -50.97.94.13 -46.164.146.229 -191.255.75.75 -171.97.198.217 -179.206.137.230 -2.27.252.8 -113.185.5.219 -117.44.175.180 -87.185.6.49 -220.246.220.129 -67.212.175.124 -104.238.180.11 -83.22.116.40 -91.179.53.23 -184.75.213.134 -95.137.245.107 -71.55.98.29 -88.232.3.134 -78.52.77.247 -86.89.192.38 -189.144.13.93 -2.62.46.234 -32.51.14.233 -190.39.44.61 -41.96.91.221 -84.42.44.243 -195.149.108.47 -42.112.88.62 -219.79.191.98 -145.120.12.175 -173.89.14.220 -178.222.183.202 -202.62.16.223 -95.24.97.176 -99.248.251.175 -124.171.172.128 -79.102.32.183 -32.51.14.233 -173.192.81.187 -93.137.217.239 -69.65.254.34 -75.76.66.211 -112.211.71.79 -173.247.188.146 -91.52.238.180 -31.162.134.45 -100.68.38.19 -91.33.207.56 -37.6.242.30 -93.73.243.27 -198.27.81.25 -79.102.32.183 -31.21.146.153 -207.179.164.139 -151.229.236.167 -223.204.240.178 -188.163.73.109 -223.204.240.178 -31.207.187.18 -95.25.39.141 -188.162.36.185 -66.87.145.79 -86.18.76.197 -178.65.247.160 -188.163.24.68 -151.72.136.1 -85.217.41.121 -178.65.14.106 -92.225.63.145 -2.83.157.97 -186.241.93.247 -85.229.185.207 -186.46.206.91 -39.48.13.64 -85.151.220.225 -85.127.120.155 -78.149.251.8 -104.180.224.241 -85.6.207.160 -178.219.94.51 -179.55.32.49 -93.205.27.117 -52.37.109.241 -185.81.229.113 -50.106.172.180 -219.73.15.59 -76.30.179.116 -112.10.225.195 -171.96.170.153 -89.42.107.153 -130.25.88.216 -81.153.89.132 -188.158.189.191 -46.244.217.69 -201.22.187.49 -139.193.221.33 -191.43.11.225 -191.102.196.35 -64.237.51.174 -87.98.178.140 -2.122.165.251 -64.145.76.140 -193.92.63.7 -178.234.208.247 -186.117.166.66 -187.95.127.151 -172.56.15.18 -24.184.24.162 -2.125.57.174 -92.55.105.130 -90.191.99.12 -25.16.26.157 -84.152.140.60 -109.182.104.245 -5.233.35.110 -173.86.39.226 -176.33.105.89 -64.121.250.235 -186.62.25.143 -109.43.2.140 -171.97.196.82 -94.96.41.4 -178.158.184.222 -188.131.34.151 -50.101.183.116 -208.74.1.9 -5.138.55.122 -94.208.224.23 -79.46.67.10 -39.35.109.251 -91.39.32.112 -114.124.0.126 -189.241.106.61 -192.0.203.126 -24.216.240.156 -90.39.140.211 -254.142.100.172 -91.140.52.140 -109.237.103.127 -154.69.72.35 -98.19.169.52 -24.92.213.63 -209.202.73.79 -78.1.168.144 -80.103.188.87 -83.26.28.36 -95.153.131.35 -139.193.58.22 -195.64.75.134 -123.190.61.215 -92.84.12.209 -115.152.154.77 -176.195.241.216 -45.50.43.165 -94.137.0.24 -93.137.137.136 -83.10.88.80 -104.173.205.55 -93.77.17.218 -213.67.95.128 -70.196.132.76 -151.28.181.143 -63.104.240.81 -188.18.15.139 -181.208.22.54 -70.81.20.54 -110.168.232.83 -62.165.226.97 -171.5.33.189 -86.197.147.26 -92.157.155.123 -92.24.120.135 -180.140.17.174 -176.194.17.251 -78.0.35.159 -83.89.104.40 -89.217.239.176 -75.161.2.197 -185.3.32.186 -95.175.104.52 -67.208.79.69 -70.209.72.10 -101.116.78.128 -95.81.253.151 -72.105.145.66 -108.250.162.103 -31.96.46.73 -84.147.119.180 -176.8.52.211 -95.153.130.235 -184.148.241.101 -128.68.161.107 -118.136.159.10 -2.100.80.66 -105.186.110.98 -121.208.142.172 -77.51.121.67 -109.241.213.159 -83.134.97.101 -31.132.225.141 -90.11.159.241 -109.241.147.183 -186.188.107.216 -42.96.176.198 -80.100.1.187 -24.59.157.255 -190.77.73.12 -178.43.50.5 -184.75.213.117 -50.173.38.87 -86.26.86.157 -98.126.5.146 -178.55.136.130 -89.102.26.229 -100.38.18.167 -177.249.155.35 -41.244.241.253 -37.45.103.181 -85.173.134.61 -42.96.165.239 -85.241.198.54 -151.224.62.223 -5.141.221.53 -213.137.36.3 -92.73.203.118 -193.161.15.72 -60.213.89.243 -41.13.28.225 -79.245.218.167 -94.179.125.146 -62.241.245.182 -49.144.46.25 -86.9.138.104 -90.6.231.45 -190.56.72.120 -84.175.233.214 -91.48.40.244 -46.175.68.4 -103.255.4.53 -78.15.181.215 -122.73.59.85 -91.14.44.208 -188.18.15.219 -218.27.203.199 -178.210.51.98 -188.123.253.74 -119.104.153.35 -95.72.134.199 -217.27.54.42 -122.82.89.79 -77.105.24.110 -128.75.210.244 -75.148.179.209 -191.32.34.245 -97.81.31.177 -189.24.148.123 -181.162.19.254 -41.250.166.187 -41.251.221.21 -93.79.71.20 -80.1.185.61 -91.150.245.34 -23.92.137.33 -5.54.7.186 -188.17.193.48 -193.0.167.145 -209.95.50.97 -186.92.234.251 -25.176.174.243 -212.253.65.223 -178.205.63.52 -78.164.118.0 -64.153.59.199 -142.4.210.129 -109.91.206.6 -159.206.179.155 -200.106.89.30 -186.82.153.43 -101.98.215.166 -89.151.168.174 -14.125.239.220 -190.203.65.246 -87.146.22.186 -187.255.236.182 -173.244.16.2 -41.96.89.43 -113.161.76.161 -88.65.91.147 -122.62.210.108 -62.113.206.152 -189.217.204.123 -213.151.1.230 -77.164.58.243 -213.160.169.153 -115.152.146.107 -58.106.6.32 -39.250.103.108 -74.213.119.35 -158.222.241.196 -78.0.12.66 -84.22.108.241 -79.9.224.238 -82.57.16.52 -82.58.170.32 -36.74.94.208 -95.141.29.54 -115.184.225.144 -108.61.152.244 -25.42.99.19 -93.80.142.128 -186.83.197.213 -41.174.131.117 -222.65.44.73 -139.162.20.227 -190.199.129.169 -141.135.41.37 -199.202.216.171 -94.128.255.47 -42.61.205.227 -90.29.84.185 -158.42.126.69 -89.239.99.253 -105.184.10.27 -79.130.27.17 -199.193.119.32 -82.50.184.207 -178.19.158.26 -178.222.8.65 -174.58.179.241 -86.204.82.192 -206.169.102.22 -219.79.190.85 -128.177.161.144 -212.54.196.101 -79.172.215.68 -202.62.16.144 -64.145.76.134 -109.155.227.178 -162.245.22.23 -110.168.232.246 -179.222.248.68 -68.193.116.242 -81.211.118.130 -86.14.132.229 -86.111.120.129 -202.62.17.5 -151.49.108.86 -91.177.116.22 -39.48.50.240 -173.199.65.38 -37.190.36.10 -171.97.196.203 -75.129.6.150 -231.210.83.146 -141.255.15.154 -73.132.239.109 -213.87.133.82 -2.85.56.108 -92.247.60.137 -217.39.183.41 -128.71.78.96 -83.240.41.109 -5.145.95.45 -86.171.220.93 -217.70.249.76 -151.226.64.200 -151.230.117.91 -90.207.95.206 -2.62.35.78 -178.4.211.187 -71.204.33.161 -85.51.138.99 -37.78.101.92 -95.139.68.24 -190.39.14.8 -197.202.255.216 -86.186.191.244 -150.117.170.89 -186.95.6.151 -182.249.242.12 -94.21.159.104 -190.71.180.90 -92.131.148.36 -179.232.147.95 -12.151.91.2 -176.127.237.83 -86.25.209.25 -201.209.45.23 -46.236.145.3 -99.110.210.240 -79.40.102.202 -206.226.72.88 -110.159.31.31 -88.200.247.127 -81.153.202.81 -217.71.45.101 -145.53.197.222 -162.156.115.215 -193.161.15.73 -73.47.89.19 -42.115.18.149 -58.34.146.122 -0.0.0.0 -177.249.135.65 -5.39.99.50 -142.176.53.89 -110.168.232.48 -188.162.36.224 -92.113.4.7 -92.163.94.164 -90.209.234.107 -108.96.66.88 -172.56.17.27 -80.188.117.115 -198.23.200.184 -185.19.27.157 -87.185.21.124 -24.189.162.153 -95.71.0.160 -223.225.156.95 -191.223.196.53 -83.199.217.112 -187.23.218.40 -58.39.109.101 -80.11.226.53 -114.97.131.146 -91.48.35.145 -84.107.232.152 -155.138.235.36 -105.156.245.30 -68.96.191.5 -25.171.12.62 -191.182.113.42 -119.86.155.192 -186.121.1.255 -2.62.19.20 -212.255.118.19 -82.54.210.233 -187.250.136.52 -197.202.240.7 -218.212.97.65 -25.220.76.115 -5.140.21.35 -70.197.85.37 -79.107.58.23 -180.252.90.132 -190.142.121.228 -84.52.183.80 -212.233.149.86 -82.158.241.150 -150.214.205.42 -87.15.42.16 -213.230.74.187 -2.62.62.72 -37.145.180.158 -191.17.69.226 -104.200.151.91 -190.73.40.185 -213.55.176.247 -212.21.9.197 -190.158.119.242 -178.205.63.52 -80.47.245.93 -91.224.81.52 -99.115.174.219 -245.245.190.57 -190.131.116.79 -89.232.118.141 -37.146.127.175 -174.4.8.138 -24.49.105.139 -41.224.164.213 -151.80.206.101 -85.178.85.135 -5.141.202.203 -85.115.248.36 -181.75.40.195 -95.174.116.99 -188.73.253.198 -190.77.226.235 -52.71.215.53 -188.29.12.44 -151.24.155.96 -50.53.104.166 -37.146.224.252 -79.107.93.229 -187.126.97.243 -92.124.2.226 -190.74.29.208 -83.30.77.252 -86.202.71.200 -1.162.58.141 -98.214.40.119 -14.207.37.172 -82.238.183.62 -83.78.97.93 -190.77.229.35 -167.61.25.72 -50.154.169.160 -90.184.89.145 -95.81.227.84 -79.117.18.180 -95.57.148.143 -171.96.168.12 -65.15.37.139 -117.25.7.196 -95.37.105.91 -87.92.76.128 -50.164.63.3 -5.220.228.6 -138.97.160.250 -174.88.244.168 -86.26.5.243 -95.55.22.224 -1.36.146.93 -25.13.191.166 -47.54.76.217 -91.140.10.159 -37.213.68.9 -171.97.188.17 -46.0.19.2 -109.43.0.212 -134.249.158.190 -86.124.151.161 -91.113.72.233 -186.91.92.251 -118.140.106.58 -212.200.65.246 -78.8.143.184 -197.104.12.43 -86.131.100.88 -108.61.191.195 -70.59.17.67 -205.197.242.148 -70.189.69.77 -100.64.161.107 -79.107.69.247 -86.10.20.12 -37.146.127.100 -79.245.206.51 -5.135.36.129 -173.189.163.125 -79.107.114.31 -178.117.43.95 -186.146.136.133 -87.144.206.76 -217.71.45.14 -108.215.118.91 -180.241.158.5 -90.212.241.153 -88.3.38.194 -187.143.90.134 -89.250.14.157 -209.160.124.170 -220.246.220.215 -95.19.18.83 -107.211.177.179 -179.126.245.239 -71.3.13.165 -182.165.45.89 -52.24.196.169 -217.77.220.249 -97.127.118.149 -151.33.74.174 -14.1.200.132 -181.167.109.212 -83.22.120.238 -68.220.69.84 -83.11.81.25 -146.90.79.77 -69.165.210.94 -94.41.202.79 -189.202.44.164 -74.116.190.9 -93.109.240.14 -91.95.18.13 -82.34.93.93 -91.67.247.232 -5.149.16.157 -193.158.162.212 -106.38.255.120 -181.64.0.89 -120.172.28.196 -46.109.37.80 -90.11.159.241 -91.140.16.52 -79.44.93.198 -63.87.252.153 -84.154.93.193 -78.106.75.71 -37.29.88.7 -79.234.106.204 -117.151.175.8 -194.50.159.203 -104.139.226.97 -114.109.116.141 -92.144.213.82 -62.21.26.111 -217.118.93.88 -171.149.2.249 -190.78.110.138 -176.249.157.191 -41.96.46.230 -1.207.128.245 -46.166.188.202 -49.144.116.253 -93.129.140.155 -73.211.90.130 -119.252.188.52 -2.85.56.108 -106.51.72.108 -178.234.227.146 -178.128.36.69 -76.75.71.45 -178.203.232.239 -5.42.105.143 -98.223.189.214 -142.217.63.42 -78.132.88.146 -165.255.172.58 -250.31.16.246 -5.149.16.157 -197.34.211.134 -115.117.126.170 -124.12.49.8 -5.139.75.217 -89.233.112.8 -171.6.27.97 -29.220.17.208 -87.69.111.245 -86.217.8.243 -95.151.182.164 -116.14.165.116 -91.84.113.0 -95.189.13.190 -189.202.31.148 -94.13.34.142 -1.0.0.0 -178.57.99.198 -95.232.214.148 -60.240.236.55 -45.56.151.111 -201.211.56.186 -86.181.102.49 -91.134.120.210 -93.135.74.141 -24.0.103.120 -92.255.230.162 -75.3.153.154 -73.9.4.206 -173.74.178.184 -187.74.68.143 -84.250.39.13 -190.47.110.47 -222.228.4.35 -46.5.0.73 -24.126.75.249 -89.16.154.73 -171.96.168.254 -220.246.221.8 -95.138.194.14 -220.141.117.75 -171.96.171.107 -86.181.29.135 -37.235.35.100 -117.208.209.181 -168.156.67.100 -77.171.59.152 -42.115.18.149 -96.31.215.232 -24.115.186.59 -78.244.37.129 -90.46.58.166 -37.24.156.83 -99.111.18.127 -209.197.163.222 -80.107.22.91 -180.136.190.98 -101.160.40.41 -178.234.245.216 -82.243.166.92 -114.133.4.189 -68.172.251.98 -95.24.212.203 -108.177.128.150 -79.245.219.111 -100.68.125.96 -151.238.37.180 -83.149.34.184 -77.51.120.101 -87.229.54.82 -2.61.181.130 -71.89.20.64 -79.245.216.210 -94.193.47.208 -91.141.1.188 -31.10.151.179 -117.206.174.179 -108.61.228.5 -93.143.136.165 -5.138.127.54 -79.218.31.115 -99.247.185.16 -98.17.225.200 -5.141.217.158 -71.209.53.226 -72.198.42.61 -95.24.235.213 -101.100.169.84 -163.211.239.49 -162.243.227.221 -185.45.13.149 -79.245.214.82 -37.134.219.49 -190.37.64.129 -5.42.93.22 -37.188.130.172 -74.84.27.148 -110.137.17.217 -72.47.175.158 -208.82.42.226 -188.103.183.100 -37.146.127.230 -50.197.49.153 -2.1.33.177 -176.33.104.186 -190.21.51.211 -178.223.12.104 -177.17.138.227 -162.216.46.174 -181.50.132.106 -178.149.203.187 -181.24.69.91 -37.47.252.233 -108.4.60.70 -178.47.254.52 -217.44.16.102 -125.163.145.229 -82.38.241.21 -79.245.192.78 -87.168.179.186 -62.21.48.27 -75.142.234.5 -46.0.45.154 -188.165.197.47 -90.154.75.175 -105.226.27.52 -79.245.192.12 -177.229.23.223 -178.128.243.39 -77.239.40.91 -66.55.134.194 -109.62.143.55 -91.90.15.94 -217.241.78.52 -95.89.215.8 -89.36.104.213 -108.61.196.252 -79.245.199.92 -94.133.86.200 -62.113.206.152 -83.49.92.182 -184.97.254.204 -202.62.16.234 -217.131.104.197 -46.0.198.198 -186.83.248.18 -37.187.242.213 -113.28.12.51 -190.227.30.241 -31.168.172.136 -78.70.59.132 -77.49.142.238 -203.164.148.154 -86.172.4.51 -213.113.185.135 -104.238.187.114 -104.45.143.132 -202.62.16.164 -85.25.223.7 -46.244.192.30 -185.81.229.113 -118.208.67.84 -174.58.249.186 -0.0.0.0 -122.189.64.32 -24.201.122.219 -174.24.61.63 -93.139.175.187 -91.48.61.15 -5.88.72.90 -83.192.113.203 -85.114.60.215 -83.5.143.28 -200.109.180.49 -120.196.98.141 -42.115.236.60 -81.10.142.169 -41.96.4.94 -114.244.35.53 -179.156.218.183 -190.137.24.255 -164.67.231.133 -80.249.81.117 -5.141.221.248 -136.152.10.116 -95.88.141.238 -86.208.11.209 -1.0.0.0 -220.160.191.91 -83.185.91.165 -197.202.255.216 -190.119.56.148 -97.127.49.14 -177.17.121.175 -58.11.101.190 -217.95.230.231 -2.85.187.74 -178.191.229.72 -88.180.208.180 -146.52.22.64 -58.11.110.34 -75.192.234.101 -202.62.17.151 -75.83.158.235 -84.154.93.193 -68.39.187.73 -201.242.109.86 -77.51.139.220 -71.67.165.191 -93.219.151.251 -80.143.81.125 -2.62.62.72 -93.129.11.176 -65.190.50.239 -84.236.15.97 -115.228.246.237 -151.238.254.12 -81.153.155.14 -179.55.32.8 -0.0.0.0 -24.255.122.199 -178.221.180.123 -90.186.174.74 -86.212.6.18 -5.70.148.6 -86.194.143.131 -5.139.58.56 -176.99.71.5 -80.213.11.23 -181.110.113.118 -69.7.86.218 -89.178.177.95 -37.112.78.248 -31.179.120.196 -118.68.195.222 -42.98.191.221 -173.246.8.253 -139.193.221.33 -46.166.190.194 -98.219.56.84 -209.144.254.123 -87.81.138.30 -93.104.105.193 -31.52.126.202 -68.69.230.94 -62.49.252.145 -101.164.234.148 -101.160.47.83 -79.246.232.132 -179.156.221.228 -188.18.15.139 -91.53.106.221 -199.16.96.145 -2.61.133.195 -96.81.223.233 -178.164.203.161 -50.153.149.16 -46.246.27.154 -190.140.130.125 -37.6.237.251 -0.0.3.6 -18.111.60.56 -87.95.107.189 -108.61.152.245 -2.85.178.120 -111.241.99.206 -24.155.200.227 -104.238.180.11 -84.31.33.151 -176.9.140.183 -91.179.215.94 -86.158.209.42 -178.0.63.141 -88.254.69.172 -181.46.165.102 -202.62.16.12 -5.167.102.27 -85.247.35.163 -78.9.102.168 -151.61.102.189 -71.197.170.183 -38.121.251.20 -117.207.10.37 -109.88.135.108 -73.179.71.188 -172.58.39.120 -50.101.137.64 -213.176.245.198 -159.11.201.195 -178.234.77.7 -195.240.131.215 -173.230.41.42 -95.81.194.234 -85.140.176.143 -67.173.24.183 -100.78.98.103 -5.64.173.211 -190.237.183.46 -42.112.80.24 -98.87.136.159 -110.138.34.135 -79.245.195.253 -50.247.211.162 -76.6.147.56 -92.249.134.115 -181.136.157.228 -77.7.205.190 -186.94.19.198 -212.251.118.230 -89.235.56.141 -68.96.191.5 -177.133.78.208 -74.111.105.96 -92.37.62.98 -24.114.51.29 -176.10.60.94 -88.19.18.181 -106.192.5.0 -107.181.128.29 -79.45.29.32 -75.101.100.249 -177.68.173.236 -217.131.108.228 -189.219.201.55 -188.129.122.191 -151.80.206.110 -190.229.108.36 -46.63.216.18 -173.75.34.129 -100.68.131.66 -145.131.208.97 -105.158.120.123 -89.151.169.61 -200.8.52.205 -190.79.228.216 -104.200.151.7 -122.62.12.87 -179.34.29.109 -69.165.156.162 -85.220.18.205 -85.25.200.102 -84.11.144.166 -67.83.2.182 -98.28.46.106 -179.210.103.88 -217.123.121.141 -216.209.125.125 -84.147.114.207 -203.176.181.33 -2.85.57.6 -178.54.197.81 -125.37.79.46 -95.141.28.169 -80.107.67.4 -125.24.126.173 -201.6.129.43 -58.187.57.52 -186.4.128.144 -73.48.135.29 -223.204.250.101 -188.108.130.194 -99.57.26.137 -109.154.152.180 -0.0.0.0 -112.215.123.124 -79.25.20.55 -98.164.86.165 -190.198.126.70 -94.153.88.241 -92.209.191.40 -174.2.194.186 -67.71.133.140 -100.66.51.177 -68.42.212.98 -109.121.7.134 -83.82.131.238 -200.8.99.39 -91.215.78.147 -1.0.0.0 -178.148.203.30 -174.50.99.85 -31.17.30.35 -188.226.204.112 -171.92.217.252 -189.202.91.14 -68.87.73.163 -94.113.7.202 -178.47.254.52 -50.153.151.123 -96.44.187.26 -62.176.13.182 -71.30.196.94 -213.16.230.227 -141.255.21.94 -36.78.198.100 -92.76.228.68 -86.104.196.53 -220.253.89.142 -79.114.76.22 -178.150.3.240 -180.242.117.178 -213.152.162.149 -219.90.234.171 -117.203.81.114 -188.174.119.70 -37.112.218.15 -50.153.150.1 -78.38.63.156 -187.79.200.234 -104.207.136.88 -177.137.167.60 -208.167.254.37 -86.135.19.3 -50.88.91.130 -208.53.180.26 -78.62.146.147 -86.181.1.146 -202.62.16.121 -73.90.210.164 -191.32.70.254 -248.245.199.94 -201.236.113.219 -52.248.212.93 -198.1.153.15 -95.24.33.153 -78.88.29.216 -159.118.77.129 -73.7.239.158 -79.216.199.109 -2.96.25.54 -94.205.1.88 -217.197.250.154 -175.40.21.20 -183.30.111.123 -86.151.81.47 -113.14.73.198 -81.21.249.40 -77.164.60.140 -2.229.75.216 -109.79.58.72 -109.92.81.247 -202.62.16.140 -186.146.153.110 -151.66.140.155 -71.185.172.244 -31.10.150.247 -178.173.7.237 -121.214.119.39 -184.98.199.232 -173.75.18.157 -89.204.153.44 -202.62.17.197 -125.112.171.217 -23.27.13.13 -187.87.77.243 -91.67.99.12 -91.197.146.250 -190.62.157.176 -190.207.190.61 -109.111.140.19 -75.152.212.205 -155.143.147.21 -84.11.144.164 -0.0.0.32 -85.132.87.161 -52.90.103.92 -125.69.8.237 -171.97.215.118 -84.189.192.218 -100.100.100.87 -118.209.123.136 -24.209.137.120 -98.15.141.103 -199.19.95.181 -193.92.113.47 -98.163.251.27 -118.211.231.131 -80.215.178.138 -32.138.112.115 -59.88.129.78 -111.95.163.140 -78.111.190.80 -47.217.159.177 -217.235.248.71 -67.160.195.220 -178.223.171.189 -29.108.45.223 -146.156.249.160 -50.53.36.50 -181.162.51.72 -176.199.122.249 -151.72.136.1 -222.222.0.100 -195.174.95.103 -190.36.190.28 -50.135.244.2 -178.222.2.10 -178.164.190.218 -79.56.106.208 -188.168.147.218 -202.62.16.64 -78.87.95.95 -90.222.86.81 -64.134.138.159 -218.205.35.53 -5.133.176.37 -203.222.146.55 -202.62.16.218 -86.130.245.53 -78.165.227.42 -100.69.17.214 -94.54.72.158 -195.29.192.145 -185.18.140.49 -113.254.166.97 -21.106.179.117 -112.198.100.11 -92.97.90.207 -178.24.63.237 -77.248.238.60 -89.37.62.17 -104.156.228.80 -151.55.147.127 -210.55.212.139 -83.27.163.130 -195.209.48.241 -46.159.1.127 -145.129.149.65 -85.217.41.209 -24.135.73.174 -109.92.64.31 -60.90.120.130 -77.49.136.244 -178.137.185.208 -41.105.28.186 -42.61.166.126 -85.99.40.135 -128.69.235.138 -185.29.164.61 -187.56.144.147 -52.169.238.25 -173.245.195.111 -185.48.37.18 -181.120.107.216 -72.216.45.166 -200.8.53.77 -46.159.36.10 -85.144.64.171 -91.77.226.181 -62.158.154.188 -122.187.103.15 -76.18.138.1 -109.97.162.239 -31.63.155.188 -162.68.190.223 -187.161.229.36 -210.136.5.67 -5.143.167.245 -89.121.179.113 -37.201.193.149 -25.22.203.199 -76.250.56.155 -178.188.9.202 -120.20.202.77 -50.48.231.111 -223.205.29.44 -153.136.25.157 -186.207.222.41 -1.162.60.24 -84.161.252.57 -42.3.135.246 -92.37.201.10 -186.222.41.103 -93.208.108.138 -186.95.48.195 -197.37.109.104 -36.239.41.91 -109.188.124.237 -14.146.39.92 -193.158.174.91 -100.68.136.230 -5.138.55.122 -0.0.0.0 -91.21.203.222 -85.168.205.103 -67.140.124.139 -190.36.194.224 -109.43.1.135 -87.15.222.204 -83.201.51.38 -36.76.35.216 -69.223.42.70 -182.187.34.145 -104.200.154.27 -128.0.0.54 -113.104.188.225 -85.76.128.44 -108.182.95.189 -202.62.16.167 -97.88.162.194 -87.79.212.65 -88.8.65.219 -86.139.7.170 -42.116.94.38 -71.212.63.169 -195.149.108.51 -71.164.199.248 -187.189.89.65 -178.252.57.123 -85.23.216.110 -70.79.134.194 -25.172.59.240 -78.137.174.34 -79.222.101.47 -79.131.102.117 -123.202.107.106 -92.49.133.75 -82.126.49.125 -201.119.239.242 -70.197.129.122 -71.80.65.254 -46.0.44.159 -37.192.171.50 -177.233.177.253 -82.43.78.46 -91.220.173.26 -223.204.68.138 -116.193.158.122 -187.155.99.230 -87.185.27.131 -37.146.123.212 -129.110.242.89 -173.219.77.171 -172.56.22.249 -87.185.7.106 -123.129.254.11 -189.79.209.234 -82.181.13.55 -178.45.113.144 -83.176.148.252 -190.82.245.27 -91.182.0.44 -76.170.53.72 -104.156.240.155 -176.33.109.138 -130.180.220.122 -93.125.88.66 -201.170.156.229 -177.124.173.245 -69.231.32.212 -189.147.232.220 -79.117.48.111 -69.179.143.48 -101.40.2.34 -81.242.98.251 -94.72.62.224 -75.112.236.68 -119.236.139.193 -188.232.58.11 -71.195.208.134 -213.5.52.72 -92.133.138.15 -172.248.91.252 -104.197.72.254 -179.198.46.19 -93.194.84.118 -138.186.31.199 -121.215.17.3 -190.75.92.230 -99.172.17.234 -91.219.137.216 -186.91.43.38 -153.161.150.230 -217.235.237.26 -25.127.30.249 -79.141.166.21 -79.113.137.142 -173.172.151.247 -196.210.56.104 -41.246.41.68 -119.130.27.80 -169.0.117.131 -62.4.196.154 -177.97.187.165 -217.107.194.54 -88.206.79.214 -94.66.57.202 -187.180.169.226 -68.186.235.174 -185.18.148.4 -5.149.252.26 -152.23.67.227 -36.74.239.195 -24.53.67.105 -192.241.252.210 -77.78.23.237 -90.55.57.179 -189.232.134.204 -37.215.159.106 -31.50.204.103 -95.89.215.64 -79.245.194.81 -189.197.67.115 -80.174.72.227 -191.19.88.251 -76.68.232.114 -79.119.47.8 -87.95.11.242 -202.62.16.73 -167.61.98.176 -190.62.152.218 -130.180.220.46 -120.210.184.66 -79.113.137.142 -88.152.186.167 -178.56.209.2 -80.86.87.204 -79.36.127.8 -80.107.29.138 -69.20.179.75 -5.140.13.16 -109.43.2.243 -107.179.248.207 -188.197.14.187 -107.182.231.95 -109.93.210.107 -94.37.247.70 -128.71.63.67 -75.150.28.89 -172.248.91.252 -151.64.48.160 -104.131.170.147 -109.202.10.42 -78.146.143.123 -182.108.229.218 -80.128.88.254 -2.85.61.239 -86.169.67.213 -201.47.219.161 -178.43.53.246 -80.107.30.197 -93.94.148.199 -99.238.196.59 -83.254.163.207 -192.95.35.246 -97.127.39.120 -180.210.200.226 -195.9.250.147 -64.188.205.179 -171.39.69.171 -131.255.112.176 -93.156.85.122 -183.81.13.190 -95.189.9.85 -209.93.108.242 -62.98.178.127 -217.99.188.138 -37.135.16.141 -77.163.109.238 -42.113.20.70 -187.155.73.125 -94.68.139.93 -124.227.106.124 -50.203.141.242 -83.39.202.42 -191.112.47.59 -68.65.103.71 -219.79.188.205 -198.53.141.197 -71.34.142.200 -46.0.22.79 -31.201.253.64 -94.174.159.109 -188.226.153.233 -80.215.200.241 -92.145.155.223 -84.154.93.193 -91.39.197.227 -41.71.184.18 -46.63.199.81 -84.193.177.2 -117.6.131.125 -92.222.28.13 -93.72.183.16 -37.213.100.21 -94.223.152.62 -37.213.71.140 -117.200.201.23 -84.147.118.100 -94.21.59.198 -185.45.13.148 -178.234.251.139 -76.181.115.35 -49.228.198.59 -76.68.254.64 -179.155.216.113 -72.63.101.200 -67.231.54.138 -68.3.159.220 -5.167.37.158 -190.73.10.170 -68.9.115.43 -171.96.171.156 -130.43.80.74 -93.104.169.149 -99.229.64.113 -69.43.208.70 -201.248.11.43 -110.168.231.241 -72.186.22.189 -76.21.96.22 -95.24.99.127 -89.212.101.38 -92.225.34.190 -1.0.0.0 -117.93.209.83 -101.136.198.7 -188.222.42.178 -91.158.109.188 -76.187.186.183 -95.142.108.55 -213.125.106.138 -200.8.245.15 -216.46.41.138 -212.251.28.139 -108.244.47.41 -94.191.185.32 -91.17.26.155 -100.66.131.190 -93.33.130.151 -77.51.245.192 -86.129.68.208 -173.21.63.162 -217.235.247.119 -60.250.10.233 -46.142.47.195 -179.147.86.195 -59.49.159.208 -182.132.220.206 -23.251.65.46 -213.64.27.201 -81.38.22.105 -99.121.207.38 -84.147.126.143 -93.129.140.155 -74.100.84.157 -37.201.170.227 -176.154.215.97 -77.234.40.151 -93.185.56.179 -176.219.146.177 -151.235.181.110 -88.65.88.121 -92.47.26.152 -116.114.146.23 -109.205.253.91 -113.254.169.130 -50.163.171.86 -24.114.75.45 -2.134.174.62 -88.152.186.90 -31.132.225.190 -231.210.83.146 -188.104.80.117 -101.39.6.49 -93.39.97.59 -84.76.206.154 -171.4.198.206 -202.62.16.75 -91.7.43.128 -151.25.8.74 -68.8.249.60 -52.71.215.53 -186.118.100.170 -183.171.177.80 -83.134.98.48 -40.76.82.173 -86.88.39.133 -108.117.62.253 -42.115.112.202 -124.122.237.162 -79.245.207.164 -24.121.116.253 -91.148.87.53 -85.75.133.89 -76.89.170.251 -111.242.52.251 -95.30.53.63 -84.82.225.145 -77.95.54.152 -176.58.231.221 -216.14.113.63 -86.184.140.225 -185.108.128.3 -49.83.47.173 -76.68.163.250 -82.229.244.14 -111.242.54.89 -201.209.255.211 -91.148.97.130 -219.73.101.145 -108.46.182.48 -90.197.186.161 -92.192.83.55 -93.201.239.193 -178.120.203.65 -91.9.209.17 -95.111.236.135 -50.66.152.76 -188.103.141.76 -86.164.95.63 -91.7.39.143 -79.40.96.252 -217.197.250.146 -79.32.103.236 -111.95.108.231 -79.245.199.212 -95.145.144.147 -188.79.3.188 -94.253.254.7 -83.7.113.197 -208.167.254.100 -2.125.75.60 -179.197.172.50 -95.153.130.87 -101.184.112.62 -202.62.17.48 -180.191.224.162 -190.62.159.200 -79.195.168.14 -24.114.70.50 -82.73.120.15 -201.208.212.33 -179.232.197.231 -46.166.188.201 -200.84.131.93 -213.125.81.210 -79.117.106.84 -104.156.240.172 -109.165.138.145 -91.21.200.178 -95.71.111.52 -68.204.29.211 -190.75.76.205 -201.243.217.28 -97.94.64.252 -37.29.88.140 -88.254.110.55 -191.19.120.6 -178.158.184.222 -85.144.12.110 -90.113.251.171 -2.146.143.174 -36.83.51.219 -186.94.188.207 -70.173.209.163 -78.49.253.175 -177.134.11.43 -37.187.155.143 -101.184.130.85 -213.87.123.8 -98.209.182.231 -189.105.158.187 -98.121.75.244 -67.68.123.177 -14.202.196.211 -84.73.147.5 -76.21.107.113 -92.124.52.219 -201.173.65.201 -109.121.39.75 -195.140.222.81 -171.97.183.72 -20.157.183.255 -113.76.115.9 -94.180.161.197 -205.220.163.91 -188.69.192.118 -92.249.221.0 -192.95.29.176 -2.139.192.228 -216.58.117.236 -71.176.43.77 -151.49.91.178 -216.5.152.147 -79.245.193.107 -141.237.253.19 -41.174.128.82 -123.138.114.2 -99.170.114.28 -95.94.96.15 -31.61.140.126 -184.171.212.128 -156.57.43.228 -79.225.117.161 -36.78.199.70 -129.10.9.128 -113.91.239.36 -83.10.159.120 -31.10.149.114 -77.180.215.167 -188.18.15.206 -37.146.201.20 -84.114.151.72 -194.50.159.203 -83.42.119.149 -58.7.79.182 -33.212.156.47 -5.254.97.76 -67.0.250.94 -222.65.39.59 -93.34.48.75 -86.148.216.229 -74.12.222.217 -71.47.114.174 -89.45.43.211 -78.51.17.255 -188.18.15.170 -217.25.228.30 -71.53.155.217 -71.33.9.140 -212.251.28.139 -83.149.47.250 -125.160.194.46 -37.48.32.73 -172.56.6.185 -50.169.226.165 -1.207.146.4 -114.77.174.108 -186.90.86.42 -219.73.26.172 -193.51.6.5 -36.77.18.75 -92.20.112.174 -53.193.239.79 -79.20.18.148 -212.71.232.87 -151.15.56.223 -71.33.11.9 -190.37.61.70 -157.201.127.254 -5.141.220.138 -96.42.38.90 -83.149.46.90 -86.208.73.16 -88.251.166.250 -217.253.212.162 -46.188.125.237 -90.217.183.159 -46.253.252.140 -50.106.33.243 -188.18.15.65 -87.152.212.58 -189.5.55.39 -109.93.33.170 -37.78.168.165 -190.79.40.206 -200.8.53.167 -77.243.183.13 -117.67.3.217 -208.167.254.90 -84.231.84.105 -77.96.246.116 -77.67.46.89 -100.88.3.214 -93.120.226.6 -86.130.246.211 -101.217.255.185 -41.249.160.19 -166.137.246.108 -176.104.38.33 -190.37.91.49 -68.146.221.41 -92.109.24.225 -105.98.10.91 -89.72.186.220 -176.10.232.140 -211.30.183.68 -171.96.171.107 -91.32.199.61 -82.126.49.125 -31.61.140.177 -37.188.238.115 -86.173.54.42 -60.25.175.39 -5.254.97.86 -37.213.131.56 -178.44.22.162 -45.79.149.192 -78.224.129.115 -79.133.129.102 -178.172.215.92 -186.88.229.47 -79.203.64.189 -201.83.109.150 -95.39.196.210 -62.116.254.204 -93.228.87.241 -213.87.122.16 -193.92.252.13 -178.173.7.237 -67.230.39.93 -23.239.25.147 -14.2.14.23 -105.100.85.26 -81.141.21.164 -185.42.38.225 -87.202.135.151 -195.154.223.134 -112.210.45.190 -89.25.167.65 -37.21.227.11 -187.254.159.150 -47.32.96.52 -46.167.107.113 -171.97.194.250 -76.216.184.8 -64.191.29.34 -208.82.42.226 -116.1.232.151 -176.85.59.61 -80.200.131.25 -95.153.134.146 -62.4.196.200 -84.176.235.19 -109.110.94.220 -138.94.57.95 -2.218.14.123 -188.108.36.227 -72.225.20.7 -79.114.108.172 -79.225.117.161 -80.212.50.182 -180.183.160.228 -96.39.207.56 -68.198.99.74 -82.112.137.120 -90.110.135.137 -79.130.203.130 -118.90.23.40 -189.140.180.53 -90.204.152.12 -105.236.127.85 -111.240.227.9 -219.79.255.20 -32.230.230.91 -1.175.232.51 -64.153.59.199 -120.24.185.169 -188.18.14.125 -38.20.8.96 -90.216.182.26 -181.54.77.177 -105.5.197.77 -124.122.61.248 -221.38.63.169 -79.70.26.227 -178.234.88.157 -216.110.120.168 -0.0.0.0 -5.49.28.53 -188.18.14.178 -82.9.15.148 -37.134.158.32 -87.0.208.206 -179.7.160.80 -84.236.82.50 -213.176.234.14 -213.183.56.124 -104.254.104.5 -188.103.183.100 -163.211.239.49 -71.176.42.18 -74.134.153.46 -177.184.139.118 -213.87.123.56 -190.38.26.230 -188.19.127.76 -77.29.197.123 -109.43.0.198 -194.255.110.178 -202.62.16.66 -122.49.148.197 -189.92.62.67 -203.219.62.171 -37.190.51.5 -14.192.209.137 -1.0.179.142 -90.203.117.80 -104.156.228.84 -79.102.202.104 -201.124.161.204 -138.91.64.57 -176.150.128.73 -115.87.56.117 -218.30.116.8 -183.47.125.144 -142.161.91.61 -200.75.100.36 -121.224.229.225 -94.230.128.122 -88.15.2.57 -105.107.52.205 -173.216.142.39 -207.32.206.67 -173.189.164.156 -94.207.129.207 -93.195.137.34 -75.98.126.115 -118.90.85.93 -62.195.196.17 -62.36.238.183 -108.24.76.250 -70.208.32.36 -128.75.1.128 -178.120.49.152 -37.146.123.192 -76.119.32.70 -170.0.21.4 -186.92.254.134 -178.36.6.207 -217.71.44.53 -37.76.19.42 -24.224.18.228 -92.144.200.122 -24.170.254.35 -95.110.236.41 -190.36.138.46 -24.15.87.243 -176.193.160.41 -69.231.38.87 -171.96.167.130 -173.185.69.84 -1.34.103.14 -89.69.126.16 -79.245.220.35 -92.127.108.147 -181.208.31.78 -78.13.64.28 -92.110.103.112 -78.157.65.184 -50.23.115.93 -92.100.204.158 -123.190.61.215 -92.157.42.221 -186.93.166.253 -189.130.4.227 -2.132.232.228 -91.179.119.190 -121.15.56.23 -218.142.99.184 -81.141.6.224 -178.234.67.104 -188.29.164.216 -59.177.175.205 -94.21.126.82 -57.131.89.131 -111.94.244.38 -46.166.165.39 -110.17.0.209 -87.79.199.100 -98.199.20.91 -92.148.36.246 -178.204.1.82 -66.87.96.217 -78.129.153.58 -200.75.126.234 -71.251.48.92 -108.61.228.21 -93.41.14.10 -197.117.114.68 -31.96.46.73 -184.170.255.187 -79.245.208.136 -78.66.84.178 -88.91.76.98 -109.145.153.74 -73.132.241.101 -1.0.0.0 -181.59.21.30 -183.12.166.251 -92.102.120.195 -128.90.73.134 -83.37.72.115 -187.143.157.80 -151.55.7.75 -220.246.220.125 -151.227.114.150 -78.137.174.34 -91.7.44.125 -79.245.217.24 -68.134.210.96 -78.220.216.208 -190.156.180.182 -94.21.86.206 -79.204.180.184 -185.2.179.240 -88.107.54.205 -78.156.104.205 -105.227.165.81 -111.241.97.118 -128.75.205.8 -103.253.43.162 -37.200.92.183 -50.80.243.103 -79.141.166.15 -69.130.145.90 -93.230.205.141 -91.158.232.111 -94.66.57.224 -164.74.58.74 -85.88.202.114 -95.153.134.146 -172.98.67.20 -77.179.231.56 -124.122.2.78 -190.186.112.3 -45.32.129.168 -213.74.111.185 -96.60.246.99 -185.29.164.61 -217.71.45.22 -86.212.65.214 -176.24.60.151 -207.119.225.105 -81.11.251.22 -108.23.17.119 -86.9.138.104 -79.146.128.43 -178.234.30.31 -98.122.56.215 -187.200.123.61 -82.226.240.57 -67.170.57.32 -46.2.49.102 -186.91.62.227 -138.130.241.44 -87.4.217.139 -187.202.15.172 -37.79.249.105 -85.178.93.221 -84.55.14.160 -190.142.152.122 -14.201.56.59 -98.160.239.93 -187.190.186.18 -182.108.22.88 -2.61.133.195 -187.187.56.36 -24.207.64.162 -202.62.17.245 -188.67.230.211 -77.203.119.51 -93.204.66.246 -71.195.120.65 -141.131.252.254 -79.245.192.59 -58.8.242.163 -67.193.83.131 -5.141.196.246 -78.85.72.68 -201.173.65.201 -108.24.83.254 -128.72.47.100 -207.192.252.5 -78.151.57.134 -200.116.36.76 -174.116.154.161 -90.153.118.51 -92.27.248.94 -84.216.198.17 -12.247.29.158 -85.72.168.211 -31.48.118.22 -36.80.103.175 -171.213.113.252 -151.225.66.52 -182.249.242.17 -144.172.235.179 -190.39.10.186 -130.89.77.168 -209.160.123.53 -186.90.132.31 -95.106.184.230 -67.140.4.30 -77.85.116.203 -109.43.1.89 -128.73.184.221 -114.97.58.74 -98.207.163.188 -217.235.238.188 -89.240.128.124 -115.99.106.249 -171.97.145.198 -66.115.130.122 -190.28.183.251 -84.19.166.50 -119.224.87.37 -91.231.21.78 -190.24.59.161 -190.235.139.236 -15.186.104.145 -190.77.75.9 -213.127.176.114 -73.191.186.27 -193.92.228.153 -69.253.5.33 -2.134.174.247 -190.79.132.37 -81.107.240.220 -78.111.187.63 -67.169.167.174 -177.32.101.231 -177.36.168.50 -201.37.161.46 -58.44.186.69 -5.43.176.207 -86.42.140.17 -117.83.20.249 -68.58.47.220 -139.194.44.166 -73.70.117.18 -31.207.199.172 -185.129.62.63 -177.206.252.93 -212.187.90.178 -177.106.0.107 -149.3.24.191 -173.192.170.116 -190.206.197.37 -79.133.153.174 -204.186.129.48 -80.95.64.68 -96.46.202.110 -84.19.165.218 -95.19.22.94 -71.15.250.17 -201.32.5.18 -87.185.22.184 -91.32.198.55 -69.23.98.139 -78.26.93.122 -189.217.249.33 -99.247.170.15 -151.227.54.162 -200.84.206.45 -90.4.251.196 -80.219.197.66 -178.131.184.75 -139.194.44.236 -189.217.160.57 -93.135.90.2 -92.12.164.32 -77.46.228.58 -176.194.27.221 -177.228.70.157 -109.158.202.20 -254.190.88.199 -190.229.108.36 -197.18.147.169 -92.237.146.213 -28.223.140.98 -46.63.156.159 -168.63.184.39 -31.44.253.224 -174.34.178.131 -94.226.215.40 -87.217.126.168 -96.23.253.67 -111.241.97.99 -1.54.59.157 -178.55.149.199 -89.142.78.84 -141.31.147.116 -79.33.213.41 -108.213.238.112 -31.57.84.147 -80.234.103.93 -209.95.50.66 -113.52.90.168 -81.145.244.98 -151.26.120.138 -128.70.235.3 -79.30.205.97 -138.159.171.254 -174.55.113.100 -110.149.118.131 -37.45.82.110 -206.74.9.110 -128.61.86.50 -187.14.108.85 -114.198.13.191 -213.22.179.152 -194.105.229.70 -181.223.24.193 -109.135.1.235 -89.142.141.19 -23.227.197.61 -185.52.76.43 -76.169.199.180 -73.3.210.99 -99.231.130.235 -219.79.25.31 -234.7.160.60 -167.114.42.94 -98.124.243.45 -94.244.17.63 -186.91.87.178 -87.158.138.61 -37.47.38.27 -174.90.222.192 -190.37.95.70 -190.38.134.241 -94.3.75.74 -50.148.74.47 -93.125.88.66 -190.156.180.182 -1.0.0.0 -87.92.110.226 -188.163.24.68 -178.234.165.128 -2.85.188.243 -24.209.235.10 -92.147.30.188 -68.38.91.132 -64.145.94.112 -70.209.70.192 -50.153.220.5 -146.215.226.94 -178.124.167.131 -189.220.73.190 -201.210.182.250 -71.30.9.185 -0.0.0.3 -31.54.153.0 -113.254.169.222 -188.36.178.82 -187.143.114.225 -98.246.183.126 -87.118.142.138 -93.41.14.10 -94.66.57.206 -1.64.26.102 -184.100.167.142 -219.79.190.100 -95.84.178.168 -79.142.77.138 -68.186.209.40 -113.254.169.156 -183.30.16.244 -41.251.78.214 -188.0.42.195 -68.65.103.71 -71.9.125.166 -213.168.88.39 -151.25.5.74 -114.217.0.193 -91.158.200.74 -217.122.4.85 -173.189.163.204 -116.106.235.35 -86.174.22.100 -94.255.70.244 -37.146.127.228 -193.92.113.58 -37.145.102.208 -88.173.83.141 -174.138.218.39 -87.168.167.96 -202.62.17.3 -77.203.111.184 -91.67.40.6 -24.189.162.153 -70.176.41.65 -79.245.215.246 -185.48.37.101 -36.76.56.110 -104.156.240.173 -201.152.251.21 -92.193.80.218 -95.91.240.232 -100.64.50.195 -171.5.32.218 -78.88.29.160 -162.216.46.35 -219.77.163.135 -79.151.51.157 -184.175.15.101 -77.49.238.199 -77.248.226.28 -36.69.71.187 -91.63.17.1 -101.172.213.77 -87.64.238.245 -92.8.171.136 -98.209.198.101 -188.18.30.133 -104.156.228.88 -46.130.28.226 -184.134.70.35 -181.59.224.240 -194.105.229.51 -94.209.48.166 -191.112.222.240 -89.191.161.146 -82.181.48.178 -172.56.30.174 -81.102.142.185 -209.21.206.225 -88.11.161.104 -5.164.152.212 -107.153.110.4 -78.238.22.5 -89.137.112.181 -50.148.235.241 -201.243.34.125 -217.73.143.165 -179.55.38.56 -171.97.216.85 -89.164.233.118 -78.234.188.9 -5.233.32.47 -93.108.204.241 -190.75.200.139 -90.197.186.161 -181.44.158.219 -79.31.221.169 -86.145.165.213 -77.166.82.225 -46.177.87.147 -75.111.215.8 -27.55.216.169 -219.73.14.96 -190.207.219.55 -46.159.30.181 -122.49.186.209 -88.232.10.222 -80.135.30.123 -91.48.61.225 -186.147.119.217 -114.244.63.56 -184.171.221.174 -122.195.1.17 -216.82.207.195 -91.145.155.116 -46.175.29.24 -2.176.151.20 -89.182.174.121 -68.9.115.43 -95.109.87.61 -87.252.255.14 -218.85.97.34 -195.154.52.96 -70.75.235.215 -184.166.237.78 -112.215.124.145 -68.246.169.224 -79.133.135.23 -74.58.134.134 -82.142.112.229 -200.164.98.231 -176.110.250.220 -91.67.247.232 -82.67.66.5 -123.108.230.29 -188.143.19.122 -86.145.165.213 -84.232.195.44 -86.138.235.114 -25.31.60.102 -36.76.249.192 -92.20.132.221 -78.225.238.46 -91.243.25.4 -202.67.40.25 -85.17.24.3 -121.220.62.161 -178.236.62.13 -194.44.26.217 -50.153.148.144 -77.57.13.122 -31.52.169.179 -178.162.63.137 -86.145.238.190 -77.49.127.161 -111.95.163.156 -82.73.214.43 -101.160.170.84 -37.110.17.100 -37.78.114.15 -109.173.7.165 -88.9.101.254 -94.51.32.217 -63.87.254.207 -217.73.139.66 -67.171.191.122 -178.173.7.237 -190.252.136.95 -217.235.230.186 -92.124.37.166 -188.109.30.153 -83.128.24.180 -91.40.70.81 -25.5.110.117 -186.95.20.215 -143.160.105.28 -140.168.123.154 -125.211.213.132 -87.93.111.108 -86.166.84.223 -62.195.143.219 -177.97.221.235 -160.255.48.163 -115.152.152.76 -2.25.181.198 -198.147.29.138 -178.234.195.60 -63.142.161.7 -71.35.59.89 -91.69.121.77 -86.161.148.170 -84.73.147.5 -201.212.212.92 -88.217.181.2 -188.67.32.137 -95.237.83.104 -84.22.5.78 -75.139.130.110 -81.141.17.230 -93.107.127.131 -81.249.78.103 -89.254.228.135 -42.61.112.245 -79.35.129.75 -5.254.97.75 -87.99.37.114 -88.136.23.202 -216.144.236.42 -84.236.19.157 -84.220.209.247 -46.254.132.34 -89.37.62.17 -178.121.32.78 -190.201.14.18 -178.204.62.112 -186.116.227.215 -84.154.93.193 -2.85.179.46 -217.131.165.253 -162.104.104.66 -192.77.248.6 -83.220.237.121 -85.178.84.212 -2.84.13.138 -82.50.151.8 -188.143.7.32 -189.250.79.133 -120.140.50.159 -128.90.23.4 -72.64.93.117 -107.4.96.165 -174.71.129.109 -203.98.92.130 -86.181.92.47 -85.60.236.130 -79.141.246.80 -124.168.137.32 -185.54.176.156 -186.119.252.108 -95.24.121.58 -198.18.1.15 -90.46.58.23 -63.142.161.20 -171.4.72.224 -88.180.60.218 -80.212.50.182 -0.0.0.0 -32.97.110.61 -90.29.148.68 -31.181.197.19 -93.87.184.75 -90.176.52.35 -14.192.209.247 -76.242.145.138 -129.10.9.64 -78.15.202.45 -77.97.142.87 -207.81.63.135 -81.171.98.35 -202.62.17.69 -42.104.32.32 -95.26.202.211 -159.118.77.129 -100.76.86.176 -173.254.218.226 -92.19.38.47 -188.76.162.80 -81.154.37.205 -202.62.18.90 -92.148.231.170 -112.198.100.11 -94.67.213.230 -81.47.166.253 -111.241.99.206 -206.45.157.108 -223.204.247.173 -188.232.3.241 -109.121.36.180 -176.8.52.211 -165.255.211.31 -201.209.4.88 -122.169.144.108 -115.77.131.85 -119.162.11.240 -202.67.43.8 -58.7.43.189 -113.254.169.97 -65.93.22.223 -2.24.137.179 -37.205.63.243 -188.153.14.179 -173.27.142.32 -186.90.26.100 -75.137.110.60 -94.70.17.152 -188.73.192.6 -50.38.90.90 -186.104.168.59 -99.58.56.103 -78.111.186.34 -162.156.199.110 -189.69.228.213 -188.162.132.92 -188.250.46.17 -46.254.11.158 -216.84.157.50 -41.105.238.117 -178.164.143.158 -110.17.46.185 -109.145.153.74 -91.201.118.181 -111.242.50.157 -209.95.50.21 -2.85.48.9 -86.147.113.242 -201.32.5.18 -70.89.67.173 -188.6.144.132 -219.90.169.227 -118.209.107.196 -72.209.204.141 -145.255.9.104 -83.248.48.163 -146.0.32.101 -69.227.211.207 -83.250.224.227 -209.195.122.166 -5.175.208.105 -23.243.180.110 -84.147.123.11 -24.117.149.151 -190.205.77.192 -80.203.58.200 -212.89.231.162 -139.162.20.227 -104.200.151.4 -177.228.70.157 -79.175.64.115 -230.88.48.35 -84.167.70.224 -92.76.239.3 -86.130.241.50 -186.115.66.232 -37.188.229.58 -198.18.1.10 -186.212.36.105 -5.2.66.120 -108.170.186.184 -188.77.219.159 -190.198.3.63 -36.68.180.135 -95.137.245.107 -92.127.114.4 -138.97.160.250 -67.253.255.191 -81.26.143.178 -92.44.18.79 -46.118.76.11 -163.21.61.34 -23.29.222.45 -100.71.25.195 -87.79.212.65 -95.181.3.196 -119.252.188.74 -95.71.9.39 -189.243.241.227 -179.24.39.24 -79.70.37.23 -84.99.129.92 -189.35.206.190 -178.213.168.44 -108.184.133.213 -105.224.102.135 -2.85.178.120 -91.158.215.5 -188.238.162.173 -120.164.44.57 -87.92.110.226 -37.244.225.68 -92.37.108.18 -174.0.80.58 -83.252.144.230 -89.146.60.241 -209.107.214.46 -193.92.127.190 -25.120.64.106 -193.173.216.141 -187.15.127.73 -162.216.46.187 -190.66.129.132 -96.46.197.79 -87.205.196.58 -107.10.92.11 -79.52.3.121 -109.227.46.236 -179.55.87.128 -60.229.177.248 -79.101.135.191 -110.139.78.73 -95.55.43.88 -79.203.115.225 -14.20.214.162 -108.238.96.103 -209.95.50.90 -92.127.18.55 -189.15.77.212 -67.168.77.63 -179.235.245.192 -92.17.4.80 -187.161.80.227 -101.160.38.192 -79.161.65.123 -54.223.76.165 -84.19.169.166 -71.166.60.163 -176.255.5.71 -77.250.199.106 -5.83.88.145 -60.213.89.243 -31.220.4.3 -216.121.249.83 -93.108.204.241 -188.49.9.231 -140.140.20.200 -186.1.246.2 -91.44.228.3 -1.0.0.0 -95.253.13.97 -76.68.207.219 -213.152.161.138 -151.227.55.136 -173.65.180.70 -193.161.15.94 -172.111.156.67 -162.243.72.148 -71.218.180.93 -79.206.173.126 -77.78.23.237 -220.179.36.72 -199.7.156.133 -41.96.129.229 -172.78.213.101 -213.74.106.1 -191.32.70.254 -190.211.210.173 -36.84.63.92 -91.229.149.244 -178.254.187.40 -186.94.39.37 -46.142.129.19 -18.111.41.60 -77.166.187.108 -172.218.139.35 -186.60.146.216 -180.110.159.141 -93.82.90.128 -174.97.17.97 -104.207.136.5 -120.144.4.208 -186.91.34.215 -36.83.149.142 -67.140.84.221 -75.172.213.12 -190.36.82.218 -151.66.225.227 -92.127.116.213 -81.229.125.221 -185.93.68.25 -93.137.254.149 -136.169.147.161 -77.243.183.9 -177.249.147.137 -5.42.80.220 -94.21.170.123 -94.75.136.231 -171.96.171.156 -201.210.116.14 -100.91.33.157 -201.229.57.249 -46.226.185.175 -181.24.19.226 -70.20.39.39 -76.73.3.178 -183.44.24.92 -37.30.58.138 -201.208.216.108 -181.59.197.112 -64.145.76.134 -87.112.242.103 -85.23.5.167 -212.54.195.80 -197.203.22.242 -113.7.121.63 -100.3.201.60 -49.49.249.174 -142.217.187.68 -223.204.248.114 -162.200.76.207 -2.4.131.202 -186.94.182.133 -94.11.104.13 -68.226.111.155 -14.148.92.236 -178.210.209.60 -190.36.211.35 -36.75.1.100 -79.245.210.43 -112.208.64.95 -81.111.5.210 -196.199.187.123 -83.128.11.52 -190.161.42.141 -219.79.188.196 -84.244.33.51 -152.78.66.223 -184.172.109.21 -174.25.126.49 -191.109.61.205 -209.188.7.224 -171.149.2.249 -123.243.36.179 -223.204.250.124 -187.78.66.45 -178.58.101.109 -117.207.4.174 -192.183.236.233 -78.190.78.63 -62.205.137.36 -46.244.202.244 -181.92.35.237 -78.226.118.202 -162.216.46.120 -106.66.184.84 -2.85.183.89 -182.182.97.227 -151.228.122.105 -186.46.200.125 -77.2.6.244 -88.217.180.135 -41.105.227.179 -117.217.169.19 -59.58.211.249 -187.59.190.124 -205.197.242.148 -66.193.240.253 -197.202.252.228 -189.157.253.81 -162.156.199.110 -79.206.173.197 -180.241.155.216 -109.74.169.196 -131.203.121.56 -217.120.80.97 -195.74.244.138 -95.25.148.21 -71.250.245.33 -186.91.50.84 -164.68.192.164 -81.132.3.126 -65.32.59.185 -77.243.183.20 -121.121.101.115 -94.229.74.91 -85.101.4.148 -25.212.159.235 -79.130.179.236 -194.105.229.242 -125.24.114.91 -37.209.150.125 -82.176.210.145 -5.254.97.85 -85.23.98.164 -24.208.133.42 -67.68.98.253 -181.137.36.56 -87.72.126.139 -178.234.70.85 -189.153.4.109 -93.35.112.145 -41.235.159.49 -82.34.217.209 -82.27.214.236 -62.158.153.239 -46.98.112.92 -95.236.131.168 -87.19.217.177 -24.16.13.108 -31.173.83.71 -80.110.47.213 -79.183.6.26 -110.114.190.209 -187.3.226.181 -24.184.225.173 -202.62.16.28 -178.66.204.156 -118.240.102.196 -78.9.100.214 -174.62.75.38 -212.129.1.77 -85.117.102.70 -105.225.124.150 -68.189.20.50 -53.193.239.1 -5.143.135.222 -110.168.232.115 -63.87.224.147 -72.10.210.38 -77.130.254.107 -117.79.232.195 -104.131.114.226 -1.47.75.216 -75.162.150.228 -114.76.65.209 -50.131.213.69 -105.237.240.41 -46.189.28.54 -200.195.171.66 -177.183.118.253 -107.182.228.8 -84.246.161.125 -92.194.211.133 -72.220.124.246 -95.18.51.131 -51.9.32.185 -193.92.105.49 -62.74.26.187 -67.228.177.213 -87.10.184.130 -90.215.81.198 -213.87.160.236 -95.168.128.13 -92.231.191.53 -5.12.141.158 -91.140.42.47 -175.136.48.78 -154.157.161.160 -182.50.248.181 -78.58.144.203 -192.99.47.172 -213.162.103.191 -36.78.190.197 -74.100.204.172 -186.204.128.46 -71.190.175.162 -217.66.101.17 -120.59.93.93 -222.47.203.227 -197.211.52.26 -212.112.119.23 -92.214.205.46 -24.91.145.46 -202.62.16.229 -124.170.29.11 -216.171.19.177 -190.201.27.160 -174.49.21.212 -71.31.210.43 -178.254.173.143 -217.235.245.98 -212.129.1.77 -24.159.124.124 -85.212.65.71 -78.132.75.22 -202.62.17.140 -76.99.37.97 -176.65.127.34 -72.191.195.23 -101.136.198.7 -184.148.244.248 -188.129.71.159 -60.166.229.77 -45.74.37.191 -181.124.105.133 -125.79.40.69 -99.184.34.61 -64.237.35.84 -31.151.218.186 -176.10.104.243 -109.93.1.102 -41.223.162.5 -60.26.198.94 -182.239.166.75 -190.51.144.246 -98.127.234.215 -176.93.163.131 -110.55.1.112 -90.191.168.246 -126.153.74.146 -73.39.122.227 -83.198.46.116 -185.34.240.121 -78.150.104.86 -212.123.186.174 -49.4.191.16 -120.195.96.242 -178.25.213.158 -98.121.109.252 -1.39.60.213 -62.216.195.237 -82.16.205.72 -80.213.122.68 -95.19.40.148 -78.8.245.213 -94.226.55.18 -31.61.141.136 -1.58.98.107 -74.108.124.159 -31.6.21.180 -181.90.74.240 -77.243.183.25 -24.230.59.100 -217.95.239.51 -108.61.228.160 -187.170.125.234 -109.188.124.7 -92.37.212.138 -73.226.22.158 -75.192.234.101 -94.181.229.228 -181.134.89.52 -112.215.124.80 -109.121.20.56 -178.234.178.80 -50.153.150.234 -83.46.249.179 -79.245.220.155 -91.180.129.209 -90.1.218.225 -186.90.83.237 -2.82.39.168 -186.95.52.224 -190.39.175.89 -93.106.134.14 -84.152.140.60 -79.245.219.88 -186.116.109.197 -197.117.67.167 -173.176.114.28 -79.183.15.169 -98.90.66.195 -213.111.129.137 -79.204.129.29 -172.58.139.124 -206.47.31.95 -121.15.76.179 -89.241.192.31 -37.187.56.220 -49.228.198.59 -2.62.2.103 -36.85.145.19 -91.181.179.196 -178.223.12.7 -186.129.158.136 -108.57.197.21 -216.14.113.63 -88.141.107.40 -46.73.248.237 -94.242.222.251 -95.232.234.3 -74.96.106.156 -1.56.204.181 -82.217.79.241 -190.78.61.241 -154.157.161.160 -88.217.181.49 -178.198.214.231 -171.149.2.249 -77.243.183.87 -188.162.14.48 -202.62.16.163 -37.73.252.213 -159.206.179.155 -125.60.156.151 -2.135.235.29 -136.169.141.42 -5.238.159.124 -31.57.94.41 -36.76.55.203 -108.61.228.113 -219.73.15.59 -67.181.167.196 -68.39.255.10 -86.10.225.82 -86.104.196.53 -188.0.47.26 -70.123.115.240 -58.212.134.44 -190.203.161.165 -217.131.108.228 -0.0.196.15 -190.205.162.178 -95.25.56.22 -86.136.204.35 -93.175.72.187 -191.112.243.63 -95.55.22.224 -188.83.111.148 -90.48.44.131 -60.240.1.229 -58.47.179.3 -71.251.58.161 -96.225.138.18 -186.95.46.68 -77.96.242.128 -172.98.87.38 -100.42.160.78 -25.90.67.202 -181.24.9.202 -208.167.254.12 -75.111.65.232 -167.61.86.118 -115.87.121.70 -46.149.182.128 -171.101.162.62 -119.77.150.187 -1.0.0.0 -2.134.144.106 -178.234.224.118 -2.240.48.24 -23.241.17.48 -83.61.236.237 -109.81.211.169 -104.156.228.174 -59.58.244.43 -58.100.64.156 -118.71.187.220 -167.113.103.254 -186.49.111.128 -95.90.203.206 -24.230.59.100 -83.30.0.203 -201.211.94.247 -150.243.99.3 -178.195.242.251 -5.80.54.19 -114.125.175.120 -201.209.135.23 -140.168.123.167 -86.168.89.159 -36.74.245.236 -112.210.106.111 -79.204.159.71 -176.9.4.50 -85.72.180.72 -188.196.185.78 -94.133.144.52 -90.1.53.178 -105.236.46.30 -70.173.7.42 -154.122.15.92 -192.100.100.137 -90.203.150.53 -109.201.154.148 -78.88.29.222 -219.79.188.102 -98.201.118.51 -46.101.128.131 -71.29.26.245 -46.172.222.26 -79.185.197.97 -194.105.229.89 -79.100.113.22 -37.190.37.125 -79.30.205.60 -186.116.109.197 -85.52.212.70 -219.73.15.193 -63.142.253.225 -86.197.146.225 -71.90.53.87 -178.234.94.211 -83.153.141.90 -78.178.112.5 -150.27.228.7 -122.155.168.126 -79.245.220.11 -113.28.135.125 -85.155.3.94 -177.131.171.131 -50.53.104.249 -86.31.102.68 -36.76.121.6 -77.222.109.76 -82.238.165.65 -24.65.226.161 -93.39.222.60 -213.87.123.163 -88.141.114.61 -79.204.141.76 -146.90.79.77 -66.55.144.245 -128.71.78.96 -115.127.32.42 -189.198.24.238 -192.77.248.6 -92.25.36.254 -213.227.202.119 -211.27.219.141 -89.154.49.154 -184.155.115.18 -80.192.72.225 -88.107.68.132 -71.89.196.163 -168.103.40.150 -87.147.153.162 -121.16.192.128 -2.103.209.142 -190.22.167.193 -178.223.71.185 -112.65.211.237 -94.189.190.29 -83.134.186.185 -31.132.225.141 -105.227.137.4 -79.255.239.227 -100.65.79.232 -125.90.135.86 -82.26.126.122 -95.168.129.156 -5.141.201.40 -88.137.219.174 -177.138.187.162 -151.74.96.104 -31.220.4.3 -5.170.114.84 -85.228.248.154 -100.80.155.184 -181.137.36.56 -112.198.100.11 -178.22.65.158 -91.84.78.147 -77.222.113.102 -46.0.39.78 -109.81.210.230 -5.138.162.117 -36.68.171.218 -250.31.16.246 -2.28.86.111 -85.155.212.110 -188.95.28.3 -176.14.89.216 -184.20.199.30 -95.215.158.237 -84.238.21.219 -71.53.153.7 -101.98.215.166 -152.78.157.141 -94.205.1.108 -83.220.238.207 -80.107.65.129 -84.41.36.30 -183.247.75.124 -101.116.78.128 -0.0.0.0 -5.171.61.131 -82.233.229.5 -177.137.238.202 -223.204.250.14 -31.50.240.201 -2.62.27.9 -113.23.124.101 -95.153.135.34 -95.245.11.217 -180.252.98.87 -139.192.151.240 -97.121.143.100 -188.51.43.179 -89.99.255.240 -62.21.3.96 -2.102.255.77 -192.81.14.1 -181.194.63.67 -201.216.194.193 -178.210.212.151 -66.29.187.52 -94.66.57.24 -109.43.0.198 -46.190.119.252 -196.32.3.15 -187.161.80.227 -24.8.142.47 -87.98.254.192 -192.241.215.76 -188.17.9.40 -116.12.61.150 -86.31.57.106 -89.178.173.167 -79.204.159.140 -70.173.239.125 -140.246.4.3 -86.208.11.209 -24.30.124.52 -94.208.224.23 -145.53.197.222 -96.46.196.49 -37.190.51.5 -45.58.202.38 -178.234.241.194 -94.157.236.220 -91.48.59.38 -151.238.56.177 -117.193.61.200 -209.91.43.78 -29.108.45.223 -95.72.228.21 -94.112.35.42 -95.71.9.142 -53.193.239.53 -70.169.101.156 -188.247.74.196 -86.132.88.171 -114.244.50.62 -67.173.146.85 -76.27.67.221 -190.62.100.198 -40.118.96.99 -0.0.0.0 -187.143.152.243 -85.76.73.210 -180.252.81.57 -188.25.7.9 -78.148.189.100 -191.33.44.16 -187.250.177.62 -37.6.243.64 -77.243.183.15 -162.216.46.27 -217.235.229.86 -205.185.218.227 -8.34.97.15 -113.254.169.130 -92.17.214.10 -46.238.214.52 -109.92.125.37 -88.217.180.206 -186.123.250.58 -189.166.241.69 -122.149.136.199 -254.192.10.101 -62.113.206.152 -100.69.120.173 -36.76.40.117 -176.199.122.249 -79.20.244.62 -162.104.104.66 -24.189.254.177 -93.120.154.125 -112.198.103.94 -190.77.226.235 -190.198.230.55 -86.181.101.168 -87.244.106.224 -69.254.108.4 -99.234.111.172 -220.253.89.87 -91.181.197.181 -46.0.90.17 -24.212.112.98 -71.238.102.227 -88.148.186.23 -89.36.99.226 -50.204.181.213 -105.236.200.45 -71.28.128.9 -70.49.81.155 -125.105.197.168 -69.18.28.136 -24.65.236.69 -188.73.252.150 -108.61.10.90 -113.13.96.143 -103.50.157.207 -104.45.135.147 -201.248.109.236 -176.10.35.244 -36.83.55.99 -152.249.19.96 -89.254.228.135 -220.85.248.156 -100.78.243.198 -195.174.63.110 -197.116.38.201 -109.182.97.110 -61.94.63.89 -169.41.33.208 -179.55.32.8 -99.121.48.135 -184.56.117.246 -94.11.119.138 -82.147.165.14 -131.91.7.2 -83.217.12.1 -111.240.210.236 -182.108.201.32 -83.8.244.143 -118.209.66.153 -86.97.88.173 -84.147.123.11 -105.184.225.62 -74.141.80.174 -70.54.86.241 -86.23.123.254 -216.166.10.199 -160.19.5.157 -106.192.29.85 -86.161.148.170 -68.125.54.178 -86.179.6.141 -92.127.1.148 -94.254.224.32 -190.91.55.65 -95.232.37.242 -178.128.243.39 -81.200.14.126 -2.124.60.67 -190.71.165.230 -188.0.47.151 -171.4.233.46 -179.114.28.83 -165.255.35.68 -100.104.254.252 -76.4.176.37 -95.236.166.58 -85.127.29.220 -77.220.33.116 -198.18.1.16 -178.120.36.242 -14.192.209.230 -79.202.59.93 -177.0.180.207 -151.28.169.207 -168.14.206.117 -148.31.163.57 -91.124.181.151 -14.192.214.217 -176.149.188.145 -178.172.215.92 -190.207.68.49 -195.113.196.64 -185.42.36.99 -92.40.183.177 -88.207.15.213 -174.69.98.70 -151.238.38.228 -117.222.10.207 -73.175.164.127 -178.85.54.148 -62.238.179.251 -95.37.9.26 -0.0.0.0 -79.204.182.127 -68.40.175.1 -185.65.132.100 -100.71.157.158 -186.188.74.85 -124.236.25.166 -81.184.33.26 -171.97.145.198 -108.61.68.149 -137.15.153.59 -37.213.220.12 -61.227.229.211 -0.0.0.0 -84.154.93.193 -91.158.150.69 -156.121.28.112 -181.132.90.89 -87.112.147.66 -187.147.251.197 -189.159.210.19 -91.150.92.1 -97.123.237.123 -79.116.200.114 -90.212.241.153 -24.163.68.6 -178.184.15.205 -80.116.90.228 -37.24.154.229 -14.148.96.47 -2.6.145.158 -202.62.17.198 -213.147.116.34 -47.17.155.157 -178.234.72.31 -82.151.220.178 -2.95.199.107 -113.161.76.161 -176.61.119.227 -178.42.41.138 -52.37.109.241 -78.94.32.194 -93.82.89.56 -54.84.114.124 -198.48.210.172 -173.9.191.245 -100.69.128.142 -176.51.149.113 -94.254.199.75 -201.165.192.20 -67.174.42.236 -108.177.128.150 -107.161.192.3 -190.22.128.210 -176.10.61.174 -183.38.36.58 -171.149.2.249 -125.238.117.232 -199.255.209.211 -141.136.220.171 -176.82.173.185 -68.45.101.13 -109.43.3.12 -187.233.182.174 -201.244.175.90 -201.229.84.230 -87.218.108.163 -85.102.97.66 -175.138.150.222 -64.134.147.95 -135.0.22.158 -213.176.245.198 -91.48.62.226 -107.222.190.99 -68.232.186.211 -186.62.36.185 -103.43.148.10 -86.141.164.169 -190.39.14.8 -159.203.56.201 -37.6.99.125 -108.233.142.124 -79.245.207.48 -187.143.90.5 -171.96.171.253 -84.20.242.6 -84.99.129.92 -91.44.239.110 -84.154.93.193 -94.189.210.210 -2.249.76.108 -86.181.101.168 -174.28.36.46 -36.78.203.186 -204.152.208.30 -95.24.97.176 -189.140.140.184 -191.248.94.241 -87.158.130.183 -172.98.85.45 -183.60.253.194 -91.48.36.208 -110.168.231.209 -101.80.128.236 -188.4.235.122 -139.218.216.7 -86.164.180.209 -64.231.241.210 -223.204.248.127 -109.93.59.176 -83.44.52.2 -183.97.21.147 -218.10.254.174 -93.210.112.103 -151.227.121.20 -78.132.91.153 -178.55.248.191 -41.95.222.186 -100.68.176.85 -79.194.236.237 -186.28.160.243 -46.98.124.128 -2.87.138.159 -93.113.244.166 -217.234.15.117 -189.130.86.228 -186.88.109.110 -186.92.11.234 -69.62.229.169 -124.248.207.76 -79.204.170.104 -109.131.72.221 -77.2.6.244 -86.131.97.253 -62.238.98.194 -184.0.10.44 -1.162.19.7 -178.234.145.196 -69.167.25.171 -183.188.194.186 -100.81.249.115 -37.146.123.203 -88.223.67.197 -82.24.182.116 -217.83.63.88 -178.206.94.207 -46.19.139.174 -212.43.117.91 -109.221.52.26 -95.180.74.125 -108.125.214.137 -71.231.4.16 -190.200.107.145 -92.127.115.8 -68.197.126.71 -37.219.113.144 -119.94.224.223 -88.75.39.23 -71.52.80.53 -93.27.43.182 -178.33.209.212 -186.92.228.115 -85.178.89.74 -84.133.115.69 -59.177.171.125 -84.147.117.137 -93.201.233.37 -45.72.146.82 -1.0.0.0 -201.243.110.123 -104.156.228.158 -85.15.5.3 -188.27.70.20 -95.232.214.103 -109.62.143.55 -62.4.196.178 -96.46.206.30 -217.235.240.26 -82.39.170.75 -186.85.81.206 -176.188.61.87 -46.238.37.253 -109.189.198.251 -217.65.48.86 -213.67.148.249 -46.70.136.199 -86.213.185.31 -37.190.115.240 -88.199.98.126 -198.23.71.72 -89.98.91.183 -190.207.56.101 -66.159.126.13 -45.217.148.157 -66.220.156.78 -114.79.51.163 -84.28.195.200 -79.175.93.227 -118.209.218.191 -172.111.156.67 -95.52.178.191 -189.159.94.1 -85.76.6.141 -79.141.170.4 -171.149.2.249 -54.84.21.157 -90.204.87.69 -50.83.9.153 -175.100.138.174 -178.128.248.1 -71.53.157.49 -173.189.166.246 -90.217.248.209 -181.176.46.99 -190.12.191.87 -75.54.50.55 -25.15.9.35 -190.142.31.90 -46.233.224.228 -37.238.140.55 -186.94.241.77 -121.141.52.83 -151.238.38.228 -151.66.226.64 -81.141.4.205 -194.61.68.124 -181.162.55.198 -208.82.41.47 -64.130.98.213 -61.253.83.10 -72.78.180.127 -17.234.139.146 -83.192.241.120 -79.204.149.175 -79.206.173.127 -95.141.28.168 -77.88.251.253 -94.70.5.65 -89.233.112.233 -79.245.193.41 -50.161.176.139 -112.210.26.23 -80.213.212.251 -67.193.83.131 -188.52.73.139 -177.228.66.13 -87.218.108.163 -198.48.210.172 -70.197.79.205 -105.225.199.114 -109.232.51.32 -145.249.205.251 -75.89.23.142 -176.84.46.160 -187.121.135.227 -178.140.25.85 -86.241.192.71 -220.75.218.153 -179.179.151.186 -151.72.136.1 -177.96.99.229 -93.100.39.93 -54.89.21.44 -83.56.202.88 -5.100.81.158 -2.29.149.62 -113.176.61.195 -193.173.216.202 -62.106.112.213 -1.25.124.164 -97.101.86.80 -173.245.219.43 -105.224.251.219 -201.75.99.9 -212.14.20.148 -62.74.23.49 -79.255.234.97 -49.199.160.43 -66.55.134.205 -37.213.130.13 -81.167.129.247 -92.226.44.87 -94.51.21.12 -84.83.129.43 -88.243.13.85 -140.247.0.16 -85.192.189.179 -91.179.166.223 -187.180.169.226 -82.126.49.125 -92.113.175.86 -87.50.118.59 -125.24.126.173 -88.198.76.188 -50.179.9.127 -37.47.209.113 -59.35.255.161 -94.124.5.10 -178.24.36.208 -188.4.40.193 -79.245.221.139 -46.227.12.142 -141.101.181.28 -217.235.237.34 -181.137.36.56 -202.62.16.202 -80.107.29.151 -165.84.8.160 -138.68.17.92 -200.44.213.166 -77.11.24.112 -85.150.137.211 -45.56.151.17 -81.219.27.176 -66.87.99.109 -217.89.14.239 -101.165.182.99 -85.132.87.161 -187.184.200.144 -178.150.52.182 -63.29.83.160 -79.185.83.6 -94.66.57.230 -24.201.80.101 -45.49.180.110 -223.204.251.231 -190.199.212.56 -109.43.2.207 -23.116.250.206 -128.78.219.231 -67.190.233.238 -64.24.149.69 -25.52.41.246 -117.194.61.67 -78.87.91.243 -37.55.224.162 -50.84.151.156 -112.213.118.25 -24.48.42.178 -190.255.10.225 -78.111.196.163 -212.85.133.161 -178.120.34.128 -73.224.21.143 -72.61.215.230 -186.91.255.210 -104.45.151.45 -62.4.196.157 -79.143.165.65 -82.209.148.120 -77.85.130.228 -37.47.211.243 -95.26.230.154 -178.43.32.146 -85.140.2.62 -96.240.86.151 -5.249.110.239 -73.203.113.197 -219.73.12.46 -108.233.142.124 -89.77.214.93 -46.129.112.120 -50.46.209.169 -80.72.69.226 -113.244.80.141 -79.177.240.158 -155.138.231.104 -108.234.78.87 -104.238.187.114 -81.231.244.196 -90.79.109.176 -71.219.139.245 -84.251.240.206 -70.75.192.84 -128.70.25.12 -151.15.31.42 -128.75.244.118 -100.68.31.17 -84.237.53.11 -31.207.228.214 -69.55.253.225 -223.204.240.178 -46.59.37.170 -118.209.134.35 -178.116.237.19 -67.253.130.12 -186.14.169.249 -254.228.44.227 -99.244.163.204 -90.186.174.74 -72.136.101.25 -110.168.232.207 -91.21.209.178 -71.57.102.33 -197.20.81.222 -171.97.202.78 -189.58.16.26 -176.15.167.33 -178.242.208.101 -69.164.195.142 -207.192.254.156 -97.81.48.175 -0.0.0.0 -95.250.249.192 -94.74.124.50 -71.189.58.203 -188.244.193.15 -96.49.76.100 -178.234.164.253 -93.156.82.36 -201.213.75.106 -212.74.202.184 -79.198.46.110 -37.4.169.70 -112.198.90.4 -193.92.193.216 -90.110.135.137 -231.190.29.94 -93.47.133.195 -100.105.40.106 -80.42.27.32 -97.82.95.148 -91.48.43.50 -106.66.131.0 -25.7.70.98 -89.109.26.16 -86.58.6.204 -42.2.89.74 -121.214.35.106 -23.92.215.194 -67.249.179.67 -186.91.225.145 -70.194.133.202 -73.191.209.26 -31.57.93.197 -187.143.152.243 -104.34.201.105 -109.156.59.69 -168.203.172.119 -188.69.213.71 -37.201.224.198 -63.87.254.166 -46.147.175.80 -176.31.53.252 -190.181.186.26 -108.236.229.199 -178.120.223.129 -93.196.163.245 -53.193.238.248 -37.78.82.173 -85.222.169.120 -190.238.254.2 -186.22.84.72 -67.248.117.76 -80.236.18.96 -95.237.150.252 -31.162.201.168 -98.240.120.30 -62.143.41.223 -186.118.101.80 -88.14.181.193 -108.244.47.41 -180.126.103.255 -92.76.227.125 -78.35.153.26 -42.117.24.196 -79.42.95.37 -2.85.49.89 -124.73.75.194 -208.118.217.31 -5.68.34.214 -68.69.138.30 -141.130.202.40 -14.125.241.61 -78.150.104.86 -95.179.16.46 -46.254.11.158 -81.243.96.100 -190.38.174.14 -91.115.16.137 -77.46.104.150 -187.14.222.253 -75.142.133.235 -5.164.174.111 -90.227.39.82 -80.61.97.239 -2.147.177.10 -87.3.231.182 -193.253.170.95 -50.124.52.72 -81.141.18.79 -180.117.230.141 -119.181.14.100 -46.61.20.84 -68.4.194.25 -63.87.254.129 -85.105.19.41 -145.132.7.244 -73.15.33.81 -83.32.181.154 -171.6.27.97 -202.62.17.108 -185.9.113.48 -113.111.207.228 -177.45.14.116 -115.87.235.103 -91.189.87.130 -78.12.50.49 -113.254.166.97 -107.5.121.128 -217.83.52.206 -92.147.147.139 -217.73.143.165 -101.136.198.7 -46.238.214.44 -195.128.182.25 -81.4.219.185 -121.208.106.138 -31.6.57.69 -37.229.91.22 -188.143.66.100 -109.109.158.248 -200.121.17.156 -24.65.239.116 -203.198.80.62 -113.240.247.242 -199.19.95.181 -182.149.179.75 -86.133.95.54 -196.217.77.156 -53.193.238.76 -90.46.77.211 -210.55.212.77 -86.156.30.44 -46.219.75.126 -88.206.186.25 -201.139.64.199 -83.220.237.203 -90.57.159.167 -37.131.65.81 -81.105.205.39 -88.114.111.212 -70.126.98.88 -131.204.137.14 -139.192.129.27 -142.196.226.85 -25.123.50.89 -66.90.147.7 -207.98.91.108 -140.186.20.196 -168.63.186.126 -94.216.85.214 -78.88.29.88 -200.84.105.129 -89.164.183.243 -27.77.240.91 -66.41.56.235 -176.9.113.75 -172.56.38.36 -21.209.82.239 -178.43.50.78 -186.35.26.47 -128.71.79.146 -67.44.193.89 -178.254.189.106 -50.131.48.25 -193.173.216.141 -46.166.186.237 -60.242.111.104 -114.96.144.162 -179.35.67.146 -46.166.190.221 -153.136.35.20 -37.190.51.38 -2.206.2.53 -95.72.230.232 -173.199.65.38 -96.229.213.18 -150.29.134.59 -115.28.162.137 -84.187.93.208 -78.148.79.165 -202.62.16.0 -200.78.5.105 -121.211.218.102 -85.7.159.117 -83.202.206.217 -186.237.60.190 -37.248.255.139 -78.164.114.243 -108.24.81.3 -162.216.46.184 -200.229.216.6 -188.162.36.53 -89.164.233.118 -186.93.181.105 -89.100.186.76 -109.194.110.54 -108.27.213.19 -201.208.197.20 -201.66.83.187 -190.37.117.153 -223.73.103.139 -120.22.163.204 -5.152.218.204 -186.207.213.206 -80.215.166.84 -95.96.146.121 -109.226.84.229 -100.68.53.91 -31.3.26.210 -166.156.10.96 -85.23.98.164 -115.188.71.106 -188.67.19.102 -212.84.112.95 -208.167.254.71 -58.70.1.212 -181.1.157.126 -50.46.209.169 -95.27.239.163 -169.237.99.175 -46.176.81.91 -88.141.107.40 -95.91.255.151 -2.85.55.69 -231.190.16.139 -95.186.235.168 -159.206.179.155 -187.170.111.199 -23.239.109.42 -77.104.194.95 -100.116.146.73 -76.99.37.97 -181.24.69.91 -94.21.59.198 -68.100.121.75 -104.35.225.25 -108.19.160.97 -87.9.217.120 -86.197.147.26 -190.200.116.19 -78.235.24.172 -99.137.226.94 -154.157.161.160 -79.70.38.26 -69.246.109.194 -108.202.176.163 -219.73.93.18 -176.10.33.23 -94.96.79.172 -139.192.181.8 -79.203.93.193 -189.202.85.78 -31.132.225.212 -94.26.100.34 -197.211.52.17 -60.168.253.88 -50.153.150.172 -98.193.70.55 -192.101.101.104 -188.108.35.232 -41.174.144.142 -79.130.27.17 -74.61.120.185 -63.87.254.188 -193.161.15.72 -149.154.199.79 -5.151.75.13 -178.223.62.69 -94.179.125.146 -90.26.80.8 -74.108.73.130 -64.121.9.200 -193.190.253.144 -89.104.6.79 -79.204.158.156 -190.204.3.155 -50.137.46.45 -31.11.78.216 -84.19.169.166 -62.16.243.132 -78.90.92.70 -101.80.128.236 -94.65.51.187 -84.106.163.174 -169.0.31.3 -212.219.189.18 -118.211.237.33 -174.52.24.82 -82.75.39.122 -186.92.246.108 -84.240.28.167 -82.72.102.219 -250.31.16.246 -81.182.88.122 -110.168.232.151 -85.244.49.62 -88.74.61.114 -162.227.231.91 -96.41.140.116 -72.191.48.158 -201.9.197.249 -88.184.162.93 -77.222.109.76 -90.39.140.211 -46.246.160.154 -201.243.217.28 -70.29.108.165 -105.229.179.124 -24.8.153.132 -118.208.25.245 -143.48.117.52 -50.254.73.145 -90.26.208.13 -181.56.181.162 -71.196.66.185 -82.26.154.43 -81.141.17.126 -83.29.7.121 -190.36.215.59 -68.104.181.13 -188.210.249.204 -83.220.237.57 -24.179.14.89 -24.119.48.249 -41.13.80.201 -93.169.65.197 -73.184.42.174 -209.188.48.220 -104.219.250.54 -83.10.234.176 -128.71.102.82 -0.0.0.0 -77.171.22.122 -187.35.183.226 -95.24.43.219 -78.161.227.14 -186.91.238.219 -174.93.28.202 -5.135.108.204 -93.115.95.201 -190.77.92.178 -5.167.151.214 -31.163.148.219 -5.47.144.159 -212.85.68.147 -125.238.118.21 -199.115.160.26 -50.66.152.76 -188.129.66.152 -186.93.181.105 -84.6.63.86 -89.204.135.212 -97.127.89.147 -79.173.209.150 -180.190.8.178 -177.182.78.243 -81.153.146.33 -195.50.30.202 -93.156.80.127 -190.251.201.110 -91.43.38.212 -77.46.228.58 -109.196.91.128 -165.255.85.43 -89.182.207.98 -5.19.254.181 -36.76.104.175 -163.158.245.3 -212.54.195.80 -91.182.2.84 -91.61.80.32 -82.141.118.195 -36.77.10.132 -176.24.60.151 -92.148.98.65 -46.248.87.63 -188.129.70.67 -162.216.46.43 -84.104.85.140 -87.198.43.146 -41.105.239.184 -178.222.8.65 -178.197.226.73 -75.130.163.51 -218.138.216.16 -110.168.232.29 -197.129.165.52 -110.114.225.201 -171.96.168.53 -100.94.186.216 -113.193.28.141 -62.47.184.52 -121.135.125.6 -113.241.227.205 -79.194.202.151 -93.138.19.90 -38.117.92.242 -90.255.102.242 -217.235.245.98 -178.254.191.36 -145.255.2.249 -92.52.46.10 -176.33.105.89 -180.159.137.110 -212.110.12.247 -178.223.29.34 -78.132.41.173 -209.107.214.55 -184.157.211.92 -201.210.136.34 -104.156.228.166 -2.110.116.27 -78.146.2.3 -189.223.40.145 -31.10.151.14 -115.73.156.101 -62.98.172.194 -12.51.221.142 -199.48.245.187 -40.45.199.182 -37.145.251.42 -191.254.234.6 -133.42.108.166 -171.97.186.106 -87.100.189.136 -85.254.74.162 -178.16.1.124 -186.146.156.243 -94.8.234.216 -113.187.0.211 -79.41.6.65 -89.68.115.216 -46.255.233.35 -91.33.212.176 -190.103.63.253 -68.229.239.219 -83.7.130.162 -155.138.228.234 -99.121.207.38 -202.80.215.19 -87.158.147.150 -162.216.46.113 -223.207.234.13 -140.168.134.185 -93.208.104.246 -210.55.212.7 -173.192.115.17 -94.197.120.199 -122.61.96.54 -74.216.74.20 -197.202.252.228 -213.89.44.226 -189.232.134.204 -2.102.154.95 -78.220.216.208 -200.93.69.211 -160.255.48.163 -130.25.88.216 -92.145.152.61 -124.217.188.204 -69.108.3.158 -88.17.163.232 -186.92.49.124 -109.159.67.244 -94.41.57.154 -200.8.39.149 -141.170.129.22 -181.55.226.126 -92.84.1.150 -217.25.157.66 -95.81.234.123 -99.118.169.71 -172.77.23.103 -120.156.32.20 -151.61.206.195 -201.34.228.37 -79.30.99.74 -96.23.182.66 -92.126.225.41 -65.25.112.109 -121.86.227.139 -87.119.241.58 -62.210.139.248 -72.187.115.150 -189.97.76.94 -92.242.84.158 -83.26.142.240 -101.184.130.85 -104.131.89.9 -109.43.3.23 -223.206.149.29 -37.78.29.254 -188.158.167.162 -220.246.221.177 -201.248.98.151 -187.56.144.147 -92.100.204.158 -89.14.37.84 -95.91.253.107 -85.240.98.217 -62.249.190.35 -84.147.122.52 -68.189.20.50 -46.166.165.39 -171.149.2.249 -37.212.78.20 -75.108.234.202 -186.94.24.202 -195.135.248.102 -91.117.36.36 -50.137.239.137 -2.81.19.210 -86.172.4.51 -176.109.8.20 -190.140.129.211 -178.222.27.95 -95.26.17.187 -24.16.13.108 -151.61.110.190 -204.84.244.11 -89.104.6.79 -151.95.2.248 -142.4.218.174 -178.226.92.114 -213.215.125.154 -86.178.41.177 -89.106.38.103 -189.40.27.87 -186.104.156.37 -82.5.155.195 -178.223.114.47 -78.6.102.70 -68.229.239.219 -202.62.17.243 -46.55.193.116 -64.145.76.166 -95.19.24.198 -187.143.131.15 -151.238.39.63 -223.204.250.123 -100.109.114.160 -2.87.138.159 -86.95.134.254 -85.176.131.41 -209.95.35.100 -120.144.147.163 -217.235.236.36 -77.163.109.238 -183.96.38.106 -31.181.197.19 -177.4.68.247 -190.203.222.36 -2.31.98.84 -113.254.165.199 -190.37.54.100 -120.156.80.113 -186.92.64.175 -68.61.104.159 -216.240.61.162 -90.255.102.242 -176.248.160.233 -186.36.78.101 -187.11.111.61 -62.83.250.234 -2.218.14.123 -184.100.197.229 -83.192.225.244 -83.134.97.101 -183.54.47.126 -88.152.186.240 -37.191.165.193 -220.253.92.215 -85.181.25.208 -50.107.118.90 -202.156.248.94 -90.208.127.105 -81.184.33.26 -62.238.41.246 -178.248.251.129 -201.248.97.184 -186.90.183.61 -65.128.50.200 -23.125.138.238 -66.186.168.251 -184.75.213.116 -201.246.92.20 -194.219.122.5 -173.28.195.191 -178.120.104.120 -176.187.33.65 -180.107.236.181 -217.25.228.30 -5.28.165.169 -189.238.253.154 -217.118.93.107 -187.37.140.36 -77.253.40.105 -219.137.245.93 -95.220.11.10 -174.69.37.131 -90.18.99.84 -93.156.84.193 -14.162.138.171 -2.95.134.41 -200.8.87.43 -178.234.175.101 -31.6.127.45 -0.0.0.0 -84.240.28.167 -78.37.212.27 -213.155.255.181 -81.97.211.72 -87.110.128.96 -93.156.85.152 -108.61.221.158 -213.114.133.63 -37.27.50.204 -217.235.254.55 -108.125.221.233 -152.238.212.218 -88.75.153.134 -177.124.186.20 -89.66.61.243 -97.127.95.119 -79.245.222.98 -125.238.116.198 -212.42.202.126 -37.188.142.133 -23.91.239.26 -18.111.100.175 -86.46.47.134 -91.158.212.23 -67.160.193.96 -94.174.159.109 -86.56.18.204 -190.97.143.230 -66.87.99.95 -72.160.42.110 -186.62.36.185 -84.19.166.58 -74.67.101.115 -37.190.51.16 -89.14.70.25 -77.231.219.235 -174.108.114.15 -91.59.143.68 -79.16.139.147 -53.193.238.159 -181.24.4.134 -93.205.23.150 -95.174.113.68 -72.130.92.25 -88.81.128.158 -187.79.198.101 -190.199.47.211 -79.245.205.64 -193.92.252.13 -193.92.57.219 -46.63.206.177 -117.147.4.250 -5.71.5.180 -78.37.209.224 -107.191.33.13 -109.131.108.79 -31.183.159.36 -109.241.213.159 -110.168.232.79 -82.19.207.84 -77.43.17.201 -94.155.117.58 -80.43.133.125 -5.42.93.15 -64.237.51.165 -108.24.76.250 -66.169.237.102 -85.238.199.16 -86.132.88.171 -188.0.40.33 -2.95.142.104 -179.34.61.194 -162.242.173.250 -37.26.143.177 -37.79.250.117 -99.61.58.22 -97.90.203.136 -113.185.7.51 -71.240.162.10 -188.73.192.30 -223.204.247.93 -36.71.166.125 -108.193.141.115 -176.253.217.115 -20.246.56.181 -83.40.223.27 -82.73.127.246 -82.251.136.117 -178.234.114.206 -92.76.244.169 -86.129.252.132 -121.98.152.41 -187.161.81.97 -202.62.16.0 -50.168.210.180 -176.205.157.226 -86.77.231.45 -191.43.19.200 -188.207.95.41 -37.14.15.170 -110.227.17.198 -79.204.180.51 -86.132.237.173 -14.1.200.115 -186.92.215.94 -85.176.46.211 -90.197.6.250 -87.100.131.44 -176.102.193.48 -186.32.213.185 -104.183.119.254 -173.244.16.168 -190.94.88.199 -89.168.217.136 -209.59.38.102 -75.64.200.17 -202.62.16.87 -188.129.57.138 -5.14.200.53 -24.222.58.144 -137.166.125.55 -149.172.246.169 -154.157.161.160 -24.220.96.106 -173.63.168.11 -178.234.168.79 -83.143.240.37 -167.174.165.94 -37.215.7.171 -122.219.223.82 -92.124.24.80 -37.190.39.95 -75.129.6.150 -197.228.88.93 -78.151.58.22 -108.180.22.192 -42.119.127.122 -78.147.114.195 -88.150.198.102 -192.99.151.16 -24.226.165.139 -75.108.234.202 -81.211.118.130 -213.49.96.80 -50.97.94.36 -201.207.87.223 -94.207.183.36 -181.50.213.128 -101.183.63.236 -108.35.213.112 -71.53.153.55 -72.51.88.209 -172.15.0.91 -77.203.122.218 -190.75.117.251 -202.62.16.1 -83.139.147.91 -86.56.9.1 -50.158.63.41 -220.253.2.201 -71.70.211.48 -190.78.218.159 -193.92.113.33 -84.79.112.88 -71.176.44.139 -151.25.116.38 -93.80.83.210 -183.26.251.60 -187.154.152.133 -51.9.232.233 -68.87.73.163 -2.222.243.0 -88.65.95.26 -86.216.248.101 -99.250.53.196 -94.214.163.25 -86.172.239.91 -58.166.126.122 -67.233.200.130 -167.113.103.254 -187.250.9.145 -87.79.205.210 -122.168.206.143 -35.2.251.113 -79.206.175.208 -80.81.242.72 -178.32.26.198 -92.157.198.24 -109.165.84.236 -41.246.123.128 -190.79.44.71 -80.71.250.255 -179.105.217.189 -78.148.189.100 -24.114.57.4 -97.82.226.119 -93.190.177.85 -94.179.52.195 -93.87.184.213 -69.164.195.142 -190.78.104.60 -37.229.88.114 -87.168.106.206 -109.201.152.246 -41.142.197.132 -76.228.232.120 -85.242.169.49 -79.134.38.179 -191.6.120.88 -45.78.219.84 -220.253.0.216 -82.208.124.9 -80.77.162.65 -60.25.173.119 -222.228.130.115 -101.184.48.161 -188.171.57.57 -188.143.12.35 -47.67.70.34 -104.156.228.84 -190.38.44.218 -186.129.155.222 -153.136.35.20 -80.229.146.133 -93.79.187.183 -89.247.168.201 -50.254.73.145 -89.250.167.173 -98.213.71.104 -192.253.243.51 -62.47.227.63 -5.42.102.21 -179.126.53.8 -176.101.222.25 -213.114.129.89 -110.90.60.204 -109.88.79.228 -81.200.14.126 -91.148.114.205 -202.62.16.58 -217.118.79.25 -67.70.149.240 -187.170.154.127 -212.139.246.181 -83.143.245.4 -18.111.35.103 -75.156.96.161 -46.18.123.126 -184.99.115.161 -46.28.51.116 -83.144.94.122 -71.200.192.224 -195.241.134.120 -77.243.183.92 -53.193.238.160 -83.4.229.104 -91.52.13.182 -59.88.79.99 -177.138.231.246 -84.244.18.20 -81.36.182.81 -60.10.247.252 -75.168.7.211 -89.155.203.172 -50.251.4.31 -222.0.0.102 -79.168.193.22 -95.86.230.196 -217.235.251.6 -187.255.237.97 -89.142.141.170 -177.95.14.136 -95.152.37.74 -201.211.225.122 -92.97.90.110 -96.240.84.172 -107.170.138.159 -152.238.65.16 -124.229.130.174 -201.208.21.151 -200.84.137.217 -89.182.123.180 -37.113.199.194 -198.91.147.54 -125.27.55.204 -81.155.43.125 -27.43.252.75 -181.29.63.54 -1.0.0.0 -193.161.15.78 -41.96.104.28 -100.65.121.11 -193.107.92.153 -209.160.123.53 -186.121.7.132 -87.8.219.205 -207.47.241.87 -213.179.208.77 -110.88.108.160 -69.65.254.34 -223.204.248.206 -112.81.12.8 -50.35.92.164 -209.165.141.252 -31.61.140.245 -200.75.116.199 -183.30.15.163 -80.106.197.192 -73.146.130.93 -121.223.199.60 -121.208.89.35 -186.95.154.86 -114.96.96.201 -190.77.76.253 -178.44.12.28 -176.195.241.216 -79.204.150.29 -186.147.61.75 -104.28.201.93 -155.138.233.252 -61.90.51.135 -179.43.169.226 -172.98.67.121 -109.43.2.138 -78.137.13.162 -84.135.89.49 -167.61.106.37 -115.135.47.10 -192.166.112.137 -52.169.229.251 -178.164.253.11 -139.194.44.166 -177.134.15.73 -66.235.1.218 -85.75.79.133 -27.34.28.186 -179.43.155.162 -58.160.139.253 -31.6.57.80 -177.17.121.175 -85.247.35.163 -94.34.176.169 -202.62.17.22 -84.13.116.48 -80.187.103.129 -50.54.85.174 -202.62.17.127 -47.88.79.118 -50.46.211.57 -79.53.221.91 -60.251.32.152 -1.189.117.58 -71.167.108.24 -88.3.193.105 -151.228.27.238 -88.217.180.11 -201.67.210.116 -201.210.86.95 -91.48.54.39 -86.177.158.37 -25.22.203.199 -125.66.41.200 -2.30.40.74 -114.79.52.218 -92.16.184.187 -60.50.198.153 -212.54.223.95 -90.56.25.32 -90.218.208.79 -2.146.174.242 -90.205.98.105 -181.28.27.4 -217.253.210.218 -190.146.5.134 -2.187.203.89 -80.215.178.13 -67.190.233.238 -125.60.156.168 -79.50.152.125 -187.142.223.82 -177.249.135.137 -5.137.233.47 -46.121.67.177 -46.19.137.78 -77.243.183.8 -186.95.47.222 -178.33.209.212 -66.87.96.76 -79.245.222.88 -2.85.61.39 -62.152.54.44 -209.121.232.187 -145.133.165.175 -118.209.235.194 -62.47.227.187 -84.251.64.249 -80.219.197.66 -180.140.31.185 -37.46.230.100 -181.113.211.83 -86.133.178.92 -98.253.214.36 -70.78.40.232 -77.117.100.177 -94.189.195.238 -37.215.59.175 -84.236.18.119 -66.55.152.52 -99.122.104.173 -37.6.243.83 -78.145.233.123 -167.61.77.246 -84.195.0.111 -151.238.89.113 -164.67.192.103 -173.28.195.191 -5.15.206.164 -191.33.243.231 -46.191.185.225 -128.71.196.136 -70.194.70.48 -128.71.134.54 -81.141.9.239 -186.244.85.121 -81.61.16.6 -186.183.166.200 -46.39.244.44 -197.202.208.42 -187.34.158.87 -178.222.148.59 -93.36.81.178 -80.236.18.96 -198.8.80.164 -67.198.179.36 -186.188.64.207 -67.238.252.38 -109.65.9.237 -146.160.55.12 -193.191.182.129 -201.229.79.158 -189.202.76.142 -198.8.80.218 -83.37.92.22 -66.87.98.165 -108.111.102.250 -192.3.141.136 -36.77.37.99 -5.133.254.230 -171.97.178.84 -67.236.80.43 -124.169.21.253 -77.49.129.46 -213.55.176.201 -72.105.146.83 -54.86.65.139 -217.249.21.32 -82.192.198.114 -213.87.225.27 -98.238.145.154 -50.49.0.1 -93.47.2.62 -101.100.174.138 -73.90.211.41 -112.162.109.20 -202.62.16.255 -101.98.191.129 -58.8.154.202 -92.142.11.171 -178.234.176.195 -116.89.60.24 -146.255.159.37 -186.90.184.149 -84.161.246.83 -95.30.48.155 -201.231.176.74 -197.202.236.30 -133.89.163.229 -62.183.126.179 -100.73.71.245 -80.200.250.228 -81.182.26.155 -186.228.140.191 -59.56.8.45 -91.67.130.158 -13.92.236.203 -91.221.65.6 -189.252.164.142 -159.29.194.242 -103.48.97.248 -91.121.70.66 -14.192.209.173 -195.154.65.167 -111.69.81.202 -68.168.178.12 -31.57.94.41 -118.209.110.212 -98.126.0.139 -148.198.187.153 -171.97.222.55 -109.8.200.248 -41.244.240.69 -164.40.228.250 -95.179.35.205 -74.240.79.103 -95.138.194.14 -31.44.183.14 -162.213.36.102 -178.44.236.21 -194.187.251.43 -70.112.32.101 -93.138.35.172 -185.19.27.157 -108.216.28.224 -171.221.163.237 -5.135.139.202 -73.52.143.18 -68.5.217.46 -86.42.137.31 -109.204.151.99 -212.183.108.70 -191.19.117.188 -220.136.53.97 -124.122.2.12 -81.134.82.110 -83.7.20.194 -177.98.228.211 -96.245.4.9 -100.71.157.158 -79.245.217.242 -37.136.53.104 -124.122.211.138 -95.89.176.134 -37.146.123.156 -79.21.245.28 -152.78.66.223 -203.66.126.1 -79.141.166.16 -87.185.17.73 -0.0.0.0 -92.127.3.155 -93.143.187.180 -141.30.247.183 -109.193.145.224 -176.31.180.203 -173.192.170.77 -2.97.122.142 -112.198.79.88 -82.60.11.203 -200.77.107.132 -46.44.41.97 -85.15.5.3 -126.12.1.77 -201.219.191.75 -203.212.152.229 -62.1.164.209 -71.68.5.90 -177.16.140.114 -187.112.20.93 -79.234.127.67 -95.239.99.126 -82.79.88.31 -37.146.190.113 -188.119.211.100 -104.129.28.242 -165.91.74.108 -213.219.104.114 -195.82.178.218 -76.97.197.140 -46.166.190.194 -84.86.23.22 -104.34.125.117 -77.105.50.252 -185.42.36.99 -178.217.115.50 -187.131.95.225 -87.242.14.89 -223.25.25.183 -175.100.142.47 -176.103.211.236 -93.138.71.210 -216.110.226.63 -79.131.176.130 -193.227.251.74 -83.185.84.90 -100.113.28.102 -108.65.141.214 -78.150.104.86 -186.144.225.108 -37.188.232.39 -57.131.89.131 -50.143.117.165 -124.170.19.167 -93.39.149.83 -37.201.227.156 -178.234.146.7 -79.200.222.225 -177.96.85.194 -36.86.63.180 -114.125.46.34 -178.32.26.185 -69.166.161.250 -188.213.169.227 -62.178.7.135 -5.141.221.183 -173.75.252.241 -70.196.129.23 -115.87.247.225 -113.254.169.220 -41.150.248.217 -95.30.80.59 -178.120.131.163 -192.77.248.5 -217.197.240.194 -91.185.53.129 -80.131.61.147 -75.168.58.165 -192.99.0.112 -83.43.246.222 -188.29.164.101 -95.17.247.131 -181.119.64.254 -178.222.24.255 -114.79.37.72 -95.236.166.88 -173.9.121.186 -46.246.19.242 -219.88.65.49 -79.67.123.101 -191.34.215.26 -79.197.191.41 -164.132.209.199 -92.110.52.208 -209.6.192.104 -101.185.87.56 -186.107.73.130 -74.100.47.75 -67.44.193.168 -96.225.148.137 -88.208.1.194 -109.10.42.135 -46.159.239.247 -109.208.182.118 -112.208.225.223 -37.113.160.11 -217.113.63.81 -77.56.46.95 -77.234.82.79 -184.20.11.173 -179.177.177.13 -93.204.227.82 -83.135.241.11 -115.188.71.106 -188.143.60.184 -219.79.190.210 -84.236.36.52 -109.43.2.109 -84.106.163.174 -85.26.186.30 -180.242.130.210 -95.211.155.225 -84.106.246.14 -24.156.31.73 -73.179.71.188 -176.58.136.154 -84.24.102.45 -1.0.0.0 -41.96.52.112 -167.160.164.214 -114.218.143.23 -210.22.178.170 -189.100.45.65 -82.12.235.3 -217.235.251.238 -92.80.28.97 -89.117.26.93 -181.194.27.123 -135.0.20.85 -177.45.131.88 -108.61.199.67 -219.79.24.240 -85.178.51.221 -86.212.5.83 -85.247.160.74 -5.94.119.65 -88.6.13.88 -186.108.112.216 -79.119.17.84 -78.61.48.176 -24.114.26.172 -88.231.29.243 -190.202.250.145 -80.106.197.207 -219.79.188.14 -50.153.150.172 -87.113.49.184 -188.186.39.140 -80.131.63.94 -174.36.220.106 -5.158.97.8 -83.5.160.224 -101.200.151.162 -213.104.46.32 -138.36.34.163 -62.4.196.196 -36.74.244.33 -97.127.52.128 -200.138.71.22 -71.167.191.109 -37.150.165.82 -173.192.170.67 -5.79.72.105 -109.43.2.140 -109.73.43.230 -112.215.123.148 -109.43.3.39 -79.208.122.196 -95.73.28.217 -46.142.16.204 -227.210.163.145 -145.28.145.152 -76.181.115.35 -96.226.61.13 -212.115.253.154 -78.8.125.79 -187.140.217.21 -176.209.217.252 -109.90.217.195 -67.182.144.108 -37.79.249.58 -68.193.116.242 -191.254.234.6 -209.95.50.25 -90.56.59.43 -177.132.187.142 -212.200.65.246 -84.154.93.193 -78.253.251.14 -2.218.67.174 -31.174.69.205 -77.77.50.63 -188.122.246.208 -128.78.135.164 -85.222.169.120 -79.245.193.198 -46.193.142.190 -83.39.92.86 -112.87.159.115 -186.82.72.175 -79.222.103.245 -46.166.190.194 -98.142.66.58 -179.156.218.183 -83.11.145.235 -79.245.220.195 -69.167.27.161 -93.137.124.147 -62.74.23.12 -69.141.154.86 -24.212.93.93 -98.101.237.46 -110.33.102.160 -139.0.138.197 -68.193.116.202 -189.211.246.193 -178.184.15.205 -219.59.135.164 -95.244.96.56 -105.225.199.114 -79.50.98.29 -190.200.240.27 -113.139.79.149 -117.0.49.88 -25.116.244.128 -110.168.232.220 -83.39.115.25 -93.57.249.216 -128.177.161.144 -83.60.172.49 -179.222.224.108 -71.29.26.245 -186.88.241.210 -79.204.180.184 -81.250.220.127 -120.140.240.116 -177.229.231.37 -190.207.94.113 -93.126.80.151 -190.142.31.90 -125.37.77.218 -99.247.170.15 -77.49.79.137 -70.215.7.228 -106.142.47.247 -178.127.253.18 -62.1.143.44 -190.203.65.246 -84.19.169.226 -83.7.114.111 -77.247.26.208 -188.129.213.220 -82.26.34.42 -79.133.142.93 -27.55.88.115 -176.253.217.115 -222.162.108.144 -203.184.40.202 -113.254.170.32 -40.76.82.173 -182.187.37.119 -178.93.48.46 -178.43.52.150 -184.162.58.31 -108.113.101.175 -112.210.6.172 -188.26.139.30 -191.33.33.18 -176.9.61.40 -199.19.95.129 -109.212.168.135 -88.187.138.71 -109.161.79.178 -68.246.194.124 -52.78.91.225 -88.106.253.43 -112.67.211.172 -113.254.168.101 -75.82.44.230 -46.147.91.137 -125.24.120.47 -87.164.217.139 -86.85.128.100 -188.233.89.176 -92.11.183.52 -118.210.113.6 -110.32.157.40 -178.149.46.197 -71.53.159.168 -82.66.165.132 -2.176.144.177 -54.81.224.18 -217.235.230.186 -223.204.248.96 -100.68.117.31 -66.169.148.98 -217.253.220.162 -79.236.253.201 -92.101.105.71 -96.49.76.100 -46.159.209.64 -77.52.137.36 -95.174.112.11 -92.0.231.128 -87.146.4.127 -65.35.47.185 -82.66.165.132 -109.169.168.151 -63.121.62.186 -93.140.224.115 -194.169.217.249 -83.13.133.86 -139.192.129.75 -200.84.68.224 -91.148.97.130 -77.171.22.122 -83.220.237.57 -95.81.205.65 -216.151.183.78 -93.38.167.117 -36.86.162.114 -87.178.175.168 -188.250.136.112 -77.119.128.97 -94.185.135.34 -36.74.239.195 -79.184.207.254 -200.109.59.231 -190.62.157.176 -41.96.104.28 -219.91.159.9 -5.138.127.54 -151.236.242.23 -188.98.192.159 -173.189.163.1 -100.78.98.103 -70.197.7.158 -82.197.214.31 -210.129.18.130 -24.79.178.91 -121.99.160.130 -24.231.17.254 -109.111.140.19 -93.104.169.149 -178.120.23.138 -31.132.225.205 -190.205.222.49 -186.89.165.251 -92.80.200.73 -71.70.226.95 -174.71.32.244 -93.168.213.17 -69.167.31.117 -50.120.8.21 -79.192.251.34 -85.76.79.28 -125.37.83.89 -5.147.125.65 -76.97.173.104 -184.5.8.134 -79.245.206.72 -41.174.166.196 -86.147.224.64 -88.77.1.157 -89.242.139.28 -111.88.27.168 -171.25.193.78 -91.48.63.226 -84.55.21.255 -177.133.223.80 -188.162.36.4 -32.150.40.90 -36.70.48.210 -200.68.240.42 -191.33.43.183 -192.170.1.4 -79.203.87.39 -186.88.186.16 -5.14.194.114 -198.18.1.51 -186.85.1.164 -67.140.213.8 -171.4.81.119 -163.157.186.231 -93.196.163.77 -14.192.209.137 -190.205.167.52 -62.98.108.210 -61.213.121.42 -87.112.242.103 -108.61.228.25 -198.27.82.134 -50.156.104.49 -54.89.21.44 -217.89.11.177 -66.188.53.149 -181.75.40.195 -151.28.180.184 -178.207.224.252 -199.30.185.2 -79.245.212.85 -213.151.0.82 -178.85.54.148 -46.176.112.27 -70.209.74.11 -83.60.174.72 -190.68.183.200 -70.79.24.157 -73.143.120.108 -171.4.184.140 -70.34.11.21 -178.216.252.11 -100.66.131.190 -218.145.173.108 -67.182.199.251 -85.139.217.55 -89.70.28.135 -171.96.168.30 -82.5.92.215 -5.156.4.175 -83.26.89.42 -41.142.153.188 -179.186.112.199 -78.98.214.170 -1.204.253.80 -5.156.124.215 -212.123.185.93 -90.194.75.240 -187.34.136.203 -81.111.228.164 -81.11.206.102 -188.18.15.180 -193.92.20.93 -109.188.124.7 -79.198.114.37 -196.211.119.214 -104.157.242.132 -94.0.38.32 -0.0.0.0 -184.75.213.134 -31.162.81.207 -100.81.35.197 -205.237.183.36 -50.153.151.49 -190.9.240.216 -189.132.24.237 -86.146.123.80 -46.165.246.200 -83.31.57.52 -97.126.38.56 -186.79.241.103 -223.227.246.32 -77.248.84.5 -181.24.35.51 -188.246.40.2 -62.43.212.93 -82.230.65.12 -171.97.198.46 -96.44.122.48 -109.77.182.203 -188.69.199.38 -105.5.197.77 -86.16.176.137 -121.211.101.176 -41.251.220.194 -124.148.118.48 -82.25.176.33 -174.136.99.162 -213.118.105.27 -62.176.8.215 -176.87.121.247 -188.18.15.64 -86.178.211.193 -155.254.235.24 -151.238.52.50 -83.22.61.216 -46.59.37.170 -82.52.158.131 -80.236.209.219 -199.127.55.171 -125.72.37.70 -118.208.109.196 -68.231.74.249 -78.35.157.127 -36.76.55.94 -189.107.206.81 -113.96.32.121 -64.145.76.167 -62.98.25.89 -109.88.137.172 -114.215.108.16 -109.93.2.133 -128.204.198.23 -211.136.222.57 -172.90.124.116 -96.244.12.80 -0.0.0.0 -199.202.216.171 -104.200.154.26 -24.38.155.231 -31.183.14.233 -190.239.149.101 -179.198.47.220 -190.203.238.156 -41.246.51.68 -91.93.11.153 -179.32.69.248 -2.96.241.150 -110.168.232.50 -67.177.15.50 -67.163.146.87 -213.139.53.46 -190.201.109.99 -93.210.125.203 -74.4.219.215 -80.215.178.74 -197.202.209.134 -190.140.129.211 -93.86.136.126 -68.206.138.97 -112.198.77.135 -121.208.89.35 -95.73.190.107 -181.162.55.198 -82.158.241.150 -77.51.66.64 -188.29.164.228 -71.175.110.253 -85.135.211.80 -189.232.134.204 -179.187.89.14 -95.99.238.195 -77.203.119.51 -80.106.197.69 -91.8.193.111 -93.73.125.152 -79.198.45.189 -62.68.98.92 -50.72.250.47 -171.97.189.86 -99.197.33.146 -188.4.50.14 -78.9.156.172 -177.39.37.65 -207.119.76.66 -76.173.208.181 -85.179.173.80 -109.43.3.230 -91.115.187.17 -79.151.244.92 -173.189.160.37 -62.176.8.215 -84.147.126.42 -79.245.195.228 -91.178.224.89 -151.49.75.194 -188.162.37.26 -190.68.183.200 -209.107.204.89 -73.7.122.117 -94.216.217.158 -187.200.123.61 -91.124.21.30 -81.110.133.126 -95.86.239.138 -189.202.78.78 -83.220.237.57 -177.207.114.240 -186.14.129.137 -49.66.57.41 -178.95.214.246 -88.198.76.188 -213.152.162.181 -173.74.166.197 -5.42.95.250 -23.19.79.130 -5.167.79.226 -86.81.69.156 -105.227.167.3 -179.199.129.201 -95.71.22.141 -81.35.54.190 -87.169.122.230 -104.200.151.23 -178.58.206.162 -178.234.8.212 -213.7.17.74 -95.183.85.115 -109.79.107.129 -82.74.167.14 -37.113.168.28 -128.71.79.146 -24.246.57.236 -122.151.50.134 -188.234.26.113 -202.29.213.22 -212.251.28.139 -80.183.101.157 -120.156.32.20 -80.237.22.69 -1.204.248.148 -151.64.1.25 -204.178.113.252 -86.17.238.232 -172.68.96.165 -193.92.113.47 -5.238.230.34 -84.147.120.84 -24.151.99.148 -41.33.235.119 -181.118.72.21 -31.208.121.209 -5.79.74.140 -96.44.187.26 -173.238.86.61 -37.113.168.57 -109.121.19.193 -0.0.0.0 -119.251.82.139 -188.87.142.99 -180.183.183.229 -186.89.49.29 -93.194.71.58 -36.75.130.218 -193.254.34.162 -85.1.132.170 -175.137.91.173 -156.211.222.209 -70.196.132.183 -105.237.83.32 -2.97.164.235 -41.250.166.187 -84.99.129.92 -86.185.14.75 -178.212.100.247 -94.66.57.27 -212.228.253.143 -78.245.193.210 -79.67.123.101 -52.78.24.7 -188.77.55.46 -109.43.0.75 -151.226.78.106 -189.24.151.35 -86.166.52.98 -81.43.191.176 -178.137.216.239 -103.43.148.10 -177.96.213.99 -171.96.167.73 -84.226.234.132 -190.199.197.254 -78.21.226.145 -167.60.134.211 -37.45.88.70 -37.145.232.126 -71.93.59.159 -84.236.82.138 -70.200.190.164 -79.169.141.40 -84.251.165.229 -95.24.91.53 -86.212.111.166 -81.132.37.244 -73.180.109.228 -193.92.20.93 -79.245.214.184 -108.232.181.15 -109.165.42.43 -113.254.169.19 -110.202.66.220 -190.186.112.3 -97.90.183.17 -71.91.70.113 -130.180.216.24 -201.242.162.244 -172.56.4.34 -41.138.68.56 -60.231.48.88 -179.232.147.95 -109.77.153.128 -198.50.221.149 -2.85.51.232 -79.117.71.64 -103.199.41.194 -123.3.163.71 -197.202.107.125 -95.239.99.126 -71.63.37.224 -151.225.135.113 -64.62.201.17 -188.168.190.74 -109.149.126.247 -70.190.28.26 -93.143.248.105 -82.131.68.200 -108.204.67.22 -93.127.48.67 -36.228.6.80 -24.218.234.20 -2.12.244.159 -223.207.119.134 -112.202.50.229 -203.206.89.35 -188.78.186.212 -178.234.246.44 -74.90.209.198 -201.208.98.13 -176.113.149.173 -176.84.26.59 -92.40.250.84 -217.249.1.121 -130.43.60.40 -104.157.135.129 -79.45.233.9 -151.236.241.194 -124.171.173.162 -5.139.222.77 -107.11.145.246 -109.43.1.135 -110.168.232.79 -85.178.193.205 -178.54.197.81 -122.104.159.157 -201.173.65.201 -76.64.18.82 -66.87.99.2 -125.24.120.37 -184.171.222.88 -5.135.108.204 -37.212.160.109 -67.80.146.83 -37.136.202.241 -31.10.148.162 -91.158.213.79 -206.222.164.91 -110.168.231.168 -104.207.136.107 -223.92.214.153 -199.241.147.35 -46.146.115.38 -250.31.16.246 -74.90.154.237 -177.240.12.199 -31.54.71.64 -42.61.252.62 -186.88.92.44 -50.124.59.224 -186.95.36.43 -199.48.242.61 -2.28.195.45 -109.227.38.172 -152.7.72.48 -186.92.248.179 -118.223.43.61 -89.78.254.207 -165.84.8.160 -178.64.4.120 -180.183.183.229 -190.66.153.127 -89.254.209.164 -212.21.25.27 -103.27.223.89 -206.248.163.100 -179.55.32.8 -83.30.209.69 -220.246.221.83 -188.108.111.118 -5.165.135.90 -91.63.19.8 -202.62.17.207 -91.7.22.201 -37.213.70.95 -42.2.227.111 -105.107.80.212 -67.162.167.86 -73.38.48.239 -220.85.248.156 -2.121.34.225 -50.120.10.162 -125.24.101.151 -201.209.130.155 -70.89.34.105 -142.161.114.127 -118.137.28.43 -110.184.11.142 -95.145.103.125 -73.211.90.130 -24.208.186.109 -197.203.5.205 -171.97.145.198 -14.186.213.191 -81.48.238.194 -70.174.30.142 -178.0.63.141 -120.180.45.219 -193.92.100.197 -2.99.34.210 -223.203.188.130 -178.157.238.33 -75.111.215.8 -84.236.59.214 -197.5.13.228 -188.245.241.79 -50.180.178.143 -78.169.234.167 -37.229.91.183 -91.237.77.7 -93.39.91.238 -88.25.138.131 -205.251.171.136 -1.0.0.0 -199.48.242.8 -178.43.58.190 -188.0.43.233 -5.140.202.3 -103.255.4.64 -46.46.208.61 -83.112.210.21 -0.0.0.0 -108.252.149.152 -46.185.48.82 -79.245.214.13 -123.63.112.110 -188.163.24.131 -178.45.76.81 -79.245.215.231 -95.236.129.178 -98.194.215.103 -37.78.85.207 -92.208.67.183 -72.60.12.140 -14.148.46.127 -201.29.97.210 -190.74.248.142 -120.59.90.202 -24.96.26.254 -85.244.118.150 -120.56.109.97 -201.210.10.223 -86.197.21.97 -195.37.133.6 -142.217.6.115 -75.142.1.84 -84.236.15.97 -41.96.38.253 -74.76.194.100 -107.191.46.128 -39.48.27.86 -86.70.223.212 -109.188.124.120 -171.96.167.186 -186.89.53.167 -95.24.235.213 -41.249.53.17 -14.213.195.165 -187.247.107.215 -188.223.250.197 -70.169.113.9 -77.231.219.47 -187.56.144.147 -166.137.246.16 -131.255.112.182 -97.127.74.43 -124.150.98.24 -110.168.231.182 -5.70.77.193 -2.85.58.108 -192.100.100.115 -212.90.62.251 -104.156.228.108 -222.228.188.6 -174.71.57.33 -117.200.205.85 -100.2.255.15 -91.61.93.48 -79.64.148.127 -141.237.243.236 -166.189.91.121 -91.44.232.13 -0.0.126.218 -217.235.240.122 -81.156.118.97 -91.127.16.235 -208.107.146.195 -188.159.173.160 -76.99.37.97 -190.38.186.76 -108.65.186.145 -42.112.94.187 -66.85.174.122 -178.120.157.184 -176.65.127.87 -182.182.109.245 -93.152.158.179 -188.69.196.255 -179.232.244.239 -78.51.17.255 -69.167.51.243 -172.79.72.216 -77.243.189.253 -83.149.45.42 -183.18.201.7 -54.172.149.177 -37.188.132.154 -79.245.220.203 -76.181.177.144 -198.8.80.218 -92.20.112.174 -90.181.200.180 -84.179.243.107 -36.77.18.75 -88.137.75.34 -5.141.203.27 -130.25.45.30 -109.147.94.141 -89.142.2.248 -80.39.236.96 -92.127.119.0 -82.18.233.59 -87.244.147.84 -202.62.17.151 -78.13.82.80 -91.182.134.93 -128.72.123.20 -89.245.109.97 -82.56.79.206 -178.162.217.130 -68.207.37.135 -77.48.31.3 -231.210.83.146 -79.204.139.188 -83.44.53.138 -60.205.112.102 -95.127.152.2 -85.113.39.64 -2.24.125.125 -88.206.141.108 -94.181.67.148 -62.113.206.249 -79.146.106.66 -195.238.101.211 -108.21.116.66 -79.70.51.138 -69.231.35.237 -217.235.237.26 -94.191.185.252 -85.51.145.189 -109.144.227.143 -71.238.202.231 -202.62.17.66 -87.189.140.13 -110.149.119.241 -99.241.126.136 -79.170.89.58 -190.36.92.202 -81.35.251.152 -186.183.180.97 -124.162.30.45 -94.64.205.245 -89.153.1.213 -77.67.46.89 -68.96.181.142 -68.101.63.60 -24.114.69.36 -171.96.171.253 -171.39.69.171 -216.244.74.178 -194.105.229.207 -83.245.240.17 -5.138.144.189 -216.151.184.103 -86.147.74.55 -46.254.11.158 -178.128.206.129 -59.57.222.232 -86.138.235.114 -84.161.253.213 -5.80.234.3 -45.32.232.66 -81.17.19.34 -2.187.200.29 -104.200.151.43 -188.18.15.195 -93.170.97.98 -171.7.219.199 -46.254.132.34 -31.10.148.162 -109.121.47.80 -192.99.62.23 -88.12.142.229 -5.42.77.196 -79.204.167.160 -184.151.61.218 -46.130.27.222 -5.12.220.50 -80.121.61.68 -184.97.246.75 -142.217.180.205 -117.84.187.192 -77.89.225.54 -188.113.168.4 -213.57.182.69 -179.26.100.83 -95.153.135.34 -93.169.30.86 -62.183.125.159 -196.224.51.163 -197.202.232.7 -2.121.188.157 -124.168.83.112 -84.154.93.193 -190.22.162.98 -188.77.145.114 -97.127.2.214 -151.16.21.252 -218.205.21.202 -82.19.92.224 -113.165.165.184 -188.82.75.227 -111.69.240.177 -2.62.37.83 -217.118.81.30 -96.46.203.225 -79.245.217.227 -223.204.241.22 -213.152.161.40 -62.68.119.27 -128.90.88.220 -93.208.114.181 -173.210.233.18 -90.214.193.0 -92.98.76.210 -59.172.143.195 -108.61.229.10 -92.147.156.172 -25.16.26.157 -95.46.98.50 -182.111.195.163 -92.246.191.31 -5.63.147.132 -189.179.175.181 -79.245.200.104 -31.6.57.80 -89.217.242.69 -188.73.192.62 -77.51.144.205 -201.209.91.12 -50.38.84.70 -68.252.8.213 -178.213.170.179 -88.169.104.241 -217.112.161.55 -190.21.155.130 -83.52.87.240 -186.116.227.215 -60.225.188.206 -183.39.64.25 -91.69.121.77 -112.111.128.3 -120.209.131.70 -65.129.56.69 -178.189.173.49 -24.0.101.211 -177.16.116.101 -92.134.34.180 -91.154.8.178 -186.82.153.43 -115.79.48.153 -197.229.46.7 -179.156.218.183 -90.29.101.248 -67.193.56.206 -77.57.13.122 -24.116.122.179 -50.46.213.211 -85.0.236.97 -5.28.20.179 -178.162.217.147 -100.71.65.247 -113.254.170.11 -95.17.250.151 -87.15.170.241 -179.222.224.235 -50.101.183.116 -190.77.90.242 -91.127.16.235 -89.143.141.4 -109.251.79.19 -77.168.163.194 -234.143.150.203 -212.183.107.208 -95.114.37.41 -171.149.79.56 -187.202.8.56 -118.90.37.15 -93.130.56.37 -222.164.214.15 -89.151.173.209 -108.20.213.143 -2.221.74.97 -117.207.5.212 -158.69.31.40 -95.21.79.107 -117.7.167.41 -58.182.120.211 -98.160.114.23 -85.76.68.236 -219.79.254.117 -84.52.183.80 -2.85.65.201 -188.82.231.177 -67.234.49.71 -81.157.210.221 -166.170.14.79 -95.236.128.89 -180.140.28.245 -188.36.48.170 -37.146.123.170 -79.245.204.42 -67.136.44.155 -2.31.43.78 -174.65.11.157 -50.203.141.242 -213.22.179.152 -109.205.253.56 -64.237.37.123 -75.140.152.181 -93.138.85.114 -188.107.62.61 -217.71.45.215 -61.195.99.101 -71.212.232.185 -152.234.187.32 -60.225.156.149 -72.38.6.170 -41.142.207.223 -82.27.233.79 -104.207.136.113 -184.151.61.186 -1.0.0.0 -86.31.57.106 -212.67.170.226 -99.229.64.113 -82.34.93.93 -88.78.18.175 -25.91.19.207 -184.75.213.133 -86.73.39.118 -78.207.218.25 -197.210.173.38 -24.45.172.109 -115.70.4.78 -37.24.154.229 -97.86.255.96 -188.166.147.168 -104.238.169.131 -84.133.115.69 -83.213.55.195 -73.52.242.44 -85.23.98.164 -167.133.202.239 -86.19.150.145 -124.122.109.4 -87.204.157.2 -49.145.71.12 -31.10.149.218 -88.254.126.246 -178.62.145.250 -73.203.113.197 -25.152.243.103 -50.46.245.151 -78.53.136.141 -178.195.56.130 -188.101.231.41 -81.157.210.186 -73.40.221.24 -105.184.10.230 -125.69.38.6 -109.157.141.252 -41.150.128.219 -79.117.53.240 -183.165.136.45 -66.76.255.133 -177.99.84.95 -88.22.86.253 -107.152.98.157 -186.79.38.60 -68.198.99.74 -67.71.36.206 -50.153.149.36 -78.26.188.205 -192.0.144.103 -213.7.32.192 -87.158.143.162 -2.62.52.177 -186.92.255.117 -151.249.96.73 -190.38.23.220 -107.170.172.93 -151.238.198.76 -72.174.209.234 -105.228.121.62 -86.31.128.135 -2.85.59.104 -187.170.157.129 -189.149.6.216 -94.66.57.230 -201.243.226.15 -112.215.123.37 -177.5.76.109 -37.24.158.191 -197.87.208.47 -117.194.54.107 -171.39.68.129 -186.89.83.70 -50.88.40.168 -92.124.8.63 -190.207.194.163 -120.195.96.242 -188.222.36.28 -135.23.90.208 -121.35.17.81 -253.167.138.14 -179.212.185.123 -176.8.179.202 -179.55.36.161 -181.208.26.200 -177.148.198.206 -151.95.16.217 -75.197.252.114 -37.188.229.58 -78.111.190.161 -190.36.128.114 -70.54.86.241 -189.157.4.253 -85.114.175.186 -84.104.98.246 -194.19.240.109 -84.196.100.202 -46.246.150.244 -123.138.32.232 -201.141.33.181 -88.207.220.253 -93.138.19.90 -113.225.18.114 -46.142.50.74 -120.173.14.19 -93.107.13.106 -176.84.165.12 -2.103.0.246 -62.205.123.238 -100.100.113.173 -79.251.9.3 -84.177.180.24 -18.111.126.201 -81.51.251.96 -112.198.77.197 -78.21.38.182 -217.105.20.145 -107.191.56.184 -36.236.88.233 -105.226.169.107 -89.168.6.239 -250.31.16.246 -125.125.36.49 -104.156.228.152 -94.254.224.32 -109.221.204.226 -84.216.199.63 -94.137.218.19 -84.181.239.37 -84.25.136.77 -109.43.2.140 -79.245.208.163 -75.159.1.100 -181.121.80.135 -85.102.227.198 -79.245.194.135 -178.1.153.222 -113.243.203.175 -188.146.70.112 -98.167.22.186 -178.42.44.41 -75.159.1.100 -178.1.24.241 -110.168.231.134 -89.99.193.144 -49.181.182.80 -91.179.166.223 -110.168.232.249 -98.117.192.12 -123.67.81.131 -0.0.0.2 -37.54.21.113 -162.216.46.35 -95.139.206.250 -160.76.210.181 -80.107.16.52 -92.148.52.184 -109.201.154.189 -65.158.198.6 -92.144.208.168 -223.204.250.55 -2.85.179.46 -87.123.106.67 -108.252.164.33 -109.182.189.41 -207.164.79.45 -173.29.144.124 -185.3.135.178 -94.145.151.183 -49.195.99.89 -87.185.13.113 -47.17.155.157 -118.136.158.190 -68.118.145.246 -86.194.143.131 -37.48.86.160 -83.100.202.42 -95.153.130.116 -24.189.254.177 -107.191.32.198 -219.88.65.49 -182.165.47.108 -103.238.131.9 -176.65.127.10 -71.179.109.158 -84.198.176.240 -71.34.71.125 -81.18.49.210 -185.104.214.53 -46.59.177.107 -177.96.135.126 -68.4.154.250 -212.115.253.74 -78.96.117.209 -200.164.98.231 -81.37.241.98 -60.240.54.44 -31.10.151.14 -65.112.8.201 -36.77.59.253 -200.77.107.132 -188.73.192.47 -216.177.129.122 -70.213.5.94 -94.205.1.88 -189.165.50.103 -84.19.166.58 -178.43.50.78 -92.37.17.206 -31.17.255.251 -212.72.144.126 -212.251.18.47 -105.156.14.51 -174.98.201.21 -112.102.44.158 -114.96.28.171 -174.50.176.242 -193.161.15.76 -128.75.199.166 -87.111.6.35 -86.148.36.53 -66.115.130.122 -177.134.174.140 -37.190.51.8 -109.43.1.168 -108.61.50.107 -37.24.158.147 -171.149.2.249 -141.237.253.19 -79.208.102.36 -213.122.124.131 -87.109.16.70 -177.81.235.242 -95.183.85.115 -5.156.133.110 -37.75.166.253 -189.83.228.101 -82.249.77.22 -92.26.77.28 -92.110.97.56 -36.255.113.156 -93.141.39.214 -200.82.195.152 -130.43.53.14 -186.167.32.27 -46.0.46.61 -177.11.141.37 -71.209.2.107 -177.9.79.75 -83.11.239.209 -114.244.45.88 -75.117.39.181 -186.79.30.137 -46.158.242.81 -2.127.225.136 -202.62.16.49 -85.26.241.7 -151.15.56.129 -24.98.68.43 -190.73.253.30 -208.54.64.211 -23.99.90.8 -84.6.62.25 -177.229.41.202 -80.202.76.7 -201.19.191.32 -5.79.74.235 -37.140.14.92 -121.45.198.248 -202.62.16.168 -87.152.195.142 -183.12.166.251 -95.18.60.88 -60.50.60.169 -138.201.65.88 -72.173.141.238 -83.4.184.111 -98.225.134.65 -191.33.23.113 -200.8.77.51 -170.215.41.19 -83.60.174.72 -176.11.151.238 -98.100.240.64 -213.151.0.38 -156.57.77.35 -83.30.246.219 -199.193.119.32 -176.82.69.50 -95.135.90.160 -155.138.230.18 -70.106.182.230 -79.67.199.149 -95.84.130.70 -181.16.74.62 -71.175.110.253 -87.113.166.62 -86.127.154.130 -108.26.55.253 -36.83.55.86 -189.156.67.120 -72.39.10.246 -87.117.9.241 -69.80.100.38 -100.100.0.49 -174.19.164.170 -213.49.92.12 -80.83.238.50 -100.68.67.248 -207.191.212.133 -79.245.218.167 -195.154.168.236 -122.49.137.82 -186.118.34.106 -46.19.97.206 -190.204.35.44 -116.210.115.55 -70.196.193.231 -86.61.8.196 -139.192.136.198 -89.180.26.30 -178.42.43.193 -177.107.242.133 -68.119.227.133 -91.48.37.22 -81.24.212.14 -190.200.114.238 -70.173.239.125 -186.46.226.17 -95.17.250.32 -77.248.0.110 -101.114.75.142 -91.61.71.110 -62.87.146.101 -78.88.29.1 -119.224.86.171 -37.54.65.152 -193.92.188.195 -98.157.39.248 -83.87.161.55 -92.19.38.229 -115.188.90.227 -178.184.16.210 -2.62.56.197 -91.226.57.133 -188.29.164.13 -70.208.137.58 -109.227.1.38 -117.192.218.30 -70.30.52.78 -88.19.208.245 -151.25.236.22 -37.113.168.102 -178.115.131.56 -96.225.143.105 -110.159.31.31 -185.50.48.82 -197.5.8.74 -84.222.70.181 -201.83.108.195 -41.130.120.57 -122.195.1.91 -146.160.55.12 -172.78.212.255 -64.145.94.121 -50.48.190.138 -78.129.221.48 -88.200.137.188 -111.241.99.206 -81.158.30.57 -190.183.117.23 -92.238.165.41 -178.62.243.138 -50.46.208.60 -1.144.96.234 -1.129.96.155 -78.90.220.111 -91.48.48.168 -24.253.205.115 -187.143.59.112 -186.14.128.205 -187.56.154.88 -171.97.201.79 -178.254.185.195 -92.246.211.241 -128.72.238.171 -96.240.81.144 -89.212.48.17 -185.9.62.204 -110.77.225.169 -24.119.39.222 -85.76.115.206 -172.56.15.181 -88.83.169.175 -36.77.55.167 -84.19.165.213 -37.146.191.103 -37.146.77.45 -188.77.156.44 -173.74.166.197 -86.212.4.36 -189.114.205.176 -79.204.147.215 -79.192.207.150 -193.167.1.101 -202.62.17.0 -179.7.219.137 -1.0.0.0 -2.182.206.105 -62.74.23.241 -176.14.89.40 -99.228.124.143 -142.0.134.7 -176.31.53.252 -24.57.236.248 -79.218.14.76 -70.75.192.84 -87.143.228.125 -85.178.89.74 -82.129.188.193 -68.99.85.75 -47.55.212.189 -111.240.207.209 -24.114.64.51 -37.78.112.147 -98.167.118.75 -79.206.175.208 -197.202.255.157 -189.5.55.70 -218.59.140.116 -58.178.1.156 -81.82.161.242 -186.87.101.123 -217.122.16.169 -125.253.100.213 -87.113.152.249 -104.156.228.100 -31.54.228.197 -212.54.196.165 -101.160.17.69 -80.213.10.20 -66.102.133.150 -188.146.72.127 -64.233.245.39 -154.5.159.216 -210.55.212.38 -176.193.156.136 -94.23.213.47 -213.229.235.159 -113.91.239.76 -88.237.179.137 -25.161.124.26 -83.23.227.159 -5.63.147.100 -220.76.226.249 -147.86.207.1 -50.168.103.161 -176.65.127.119 -95.30.21.96 -193.92.113.47 -25.20.113.106 -112.37.27.20 -176.209.243.162 -95.211.212.195 -58.8.154.35 -94.181.34.121 -174.70.46.51 -172.56.32.22 -178.255.69.59 -92.48.112.74 -36.69.21.247 -187.189.254.189 -212.26.187.40 -183.12.164.74 -95.145.103.119 -93.113.244.166 -143.176.138.223 -109.192.225.106 -46.249.59.220 -95.211.188.25 -18.111.102.54 -178.184.26.58 -187.188.14.229 -46.130.12.191 -91.105.92.239 -95.215.156.54 -2.240.16.118 -46.217.85.84 -46.10.123.227 -108.84.14.1 -178.198.242.133 -2.223.51.94 -18.111.109.172 -71.100.135.84 -85.75.79.133 -217.118.79.46 -202.62.16.34 -2.248.159.250 -13.93.150.42 -77.98.223.82 -75.117.202.183 -151.72.136.1 -50.153.150.144 -109.93.159.179 -58.8.154.35 -192.95.32.112 -37.140.17.102 -62.87.191.182 -80.135.239.44 -112.198.103.161 -199.48.243.62 -5.248.192.239 -186.94.109.177 -118.140.106.58 -93.138.115.72 -172.111.156.67 -109.210.209.73 -213.21.47.192 -85.99.37.229 -37.229.184.145 -64.150.245.177 -95.89.215.8 -209.93.154.77 -45.56.108.177 -78.37.253.157 -116.252.202.50 -82.237.87.66 -79.208.99.94 -109.93.237.13 -95.84.130.70 -50.153.150.252 -109.93.229.2 -74.110.18.17 -223.73.103.231 -1.151.121.137 -188.17.192.99 -216.231.140.113 -83.153.141.90 -49.49.35.156 -105.227.35.18 -176.152.32.37 -95.114.2.51 -79.136.64.123 -173.34.203.76 -109.43.2.115 -50.132.197.203 -105.225.29.41 -188.222.188.84 -178.120.161.243 -78.21.195.37 -43.165.193.4 -79.245.209.189 -182.39.244.18 -117.231.147.111 -188.69.196.84 -68.195.171.102 -95.232.80.9 -46.55.162.158 -125.162.110.180 -46.189.28.35 -83.5.182.110 -5.138.219.104 -31.44.183.14 -92.37.143.70 -83.149.45.208 -37.146.123.156 -107.170.90.53 -69.178.106.243 -77.105.61.201 -98.227.60.68 -100.90.0.219 -69.80.98.175 -181.95.86.188 -94.209.34.7 -168.1.6.18 -5.141.221.248 -79.50.98.29 -2.101.114.120 -67.63.55.34 -79.245.208.90 -31.132.225.153 -109.88.143.236 -186.83.12.194 -87.96.161.171 -81.162.122.102 -148.198.187.141 -70.89.142.142 -82.227.229.180 -94.180.197.48 -76.170.53.72 -198.252.123.121 -82.139.112.23 -178.65.220.234 -112.111.83.41 -79.208.119.139 -84.196.55.99 -169.1.121.116 -212.112.150.250 -55.134.238.99 -112.67.211.172 -5.141.221.96 -69.7.90.64 -108.61.196.218 -109.121.21.84 -95.103.165.22 -75.151.200.156 -163.172.137.241 -178.49.192.105 -83.16.104.70 -104.238.134.31 -184.43.40.204 -152.78.156.223 -62.158.145.34 -81.11.198.166 -107.191.32.195 -5.14.202.22 -77.253.40.105 -37.205.63.243 -178.234.31.36 -81.240.219.181 -91.214.131.89 -79.200.67.185 -5.175.208.124 -2.139.127.149 -2.62.14.71 -79.204.144.230 -98.207.141.82 -197.37.183.200 -25.69.38.113 -5.82.242.101 -82.141.118.195 -203.206.37.169 -108.53.251.199 -186.35.252.4 -141.255.15.154 -72.202.146.227 -186.188.89.194 -68.111.91.91 -188.67.72.26 -90.131.191.120 -94.21.162.25 -187.230.36.79 -5.81.250.60 -89.212.99.205 -87.245.50.14 -194.44.207.38 -109.111.243.109 -202.62.17.19 -198.8.80.164 -190.139.245.143 -209.202.7.202 -68.204.242.231 -92.28.233.187 -201.29.108.171 -36.77.19.108 -99.4.120.232 -78.85.5.166 -217.88.3.79 -180.252.111.99 -2.99.213.60 -68.118.69.220 -80.41.226.120 -5.143.190.221 -0.0.0.0 -89.254.225.194 -191.184.26.86 -122.82.164.84 -69.143.54.161 -78.43.172.91 -89.240.86.71 -110.166.247.71 -213.151.0.135 -71.229.244.243 -188.16.237.62 -93.204.234.163 -173.230.77.55 -68.169.143.146 -217.14.178.36 -95.211.184.197 -81.157.210.221 -37.14.20.75 -86.135.18.75 -100.88.8.110 -152.115.56.228 -79.133.144.79 -93.143.193.80 -77.49.142.238 -188.18.14.171 -151.250.50.227 -24.54.240.178 -201.29.103.139 -71.7.113.19 -122.82.1.124 -106.69.14.251 -202.159.132.94 -50.35.92.164 -115.229.86.166 -176.115.8.183 -109.165.42.43 -24.122.223.250 -201.243.107.40 -41.224.171.232 -88.27.211.144 -173.182.128.9 -95.46.98.50 -85.155.6.145 -77.243.183.116 -151.238.36.143 -58.174.48.97 -216.186.236.171 -79.245.215.220 -192.198.202.218 -101.39.46.97 -181.25.4.150 -94.197.120.56 -173.221.226.116 -188.54.228.4 -176.109.8.50 -92.133.138.44 -31.162.230.126 -37.190.51.1 -71.83.111.138 -97.88.161.169 -178.47.182.195 -85.59.90.160 -95.55.43.88 -121.219.36.217 -72.213.26.102 -201.248.113.36 -25.80.14.76 -91.48.44.193 -212.251.18.47 -177.39.36.104 -174.35.172.33 -82.39.255.68 -190.22.239.126 -65.94.153.250 -107.170.198.224 -2.234.147.237 -5.151.152.147 -179.55.35.142 -67.174.42.236 -46.229.173.231 -14.192.212.169 -94.69.53.0 -31.23.81.184 -105.1.203.194 -79.20.35.156 -188.78.64.145 -92.241.152.111 -90.255.187.231 -190.38.39.114 -187.223.48.111 -201.29.103.127 -46.142.44.83 -5.43.176.207 -84.18.235.14 -87.185.2.181 -186.66.52.24 -89.153.94.121 -202.67.37.42 -213.151.3.243 -110.17.0.246 -45.32.129.168 -108.204.225.33 -31.11.93.241 -197.7.35.83 -86.173.80.107 -100.68.86.132 -200.75.242.225 -151.95.16.217 diff --git a/iguana/confs/FRK_peers.txt b/iguana/confs/FRK_peers.txt new file mode 100644 index 000000000..f2be2825f --- /dev/null +++ b/iguana/confs/FRK_peers.txt @@ -0,0 +1,40 @@ +193.227.134.111:7912 +85.24.169.215:7912 +195.154.223.134:7912 +175.33.51.90:7912 +91.153.109.149:7912 +84.242.139.4:7912 +73.211.90.130:7912 +123.56.194.66:7912 +157.161.128.55:7912 +91.134.120.210:7912 +80.219.59.25:7912 +173.65.129.85:7912 +198.27.97.180:7912 +178.140.25.85:7912 +104.172.24.79:7912 +198.27.81.114:7912 +104.236.163.203:7912 +98.115.147.74:7912 +155.254.32.17:7912 +198.27.97.172:7912 +108.61.10.90:7912 +104.236.26.26:7912 +144.76.91.109:7912 +158.69.238.230:7912 +86.174.4.251:7912 +151.80.9.33:7912 +198.50.217.13:7912 +193.192.37.135:7912 +80.219.59.42:7912 +68.117.4.111:7912 +109.145.33.45:7912 +74.196.59.103:7912 +84.107.181.197:7912 +80.219.59.98:7912 +104.236.59.76:7912 +81.89.56.170:7912 +157.161.128.58:7912 +158.69.27.82:7912 +209.126.119.209:7912 +104.238.171.32:7912 diff --git a/iguana/confs/GMC_peers.txt b/iguana/confs/GMC_peers.txt index 88c00ba9c..db385322c 100644 --- a/iguana/confs/GMC_peers.txt +++ b/iguana/confs/GMC_peers.txt @@ -1,26 +1,8 @@ -5.196.20.189 -45.32.1.137 -104.255.67.131 -104.236.84.230 -142.4.218.175 -58.168.10.110 -101.173.217.38 -194.135.81.138 -80.229.155.158 -85.214.23.49 -104.168.148.143 46.105.118.15 -198.27.97.172 -101.173.200.202 89.36.212.56 -45.48.9.204 -104.172.24.79 -85.25.200.157 -216.146.143.177 -203.7.43.162 -101.173.197.85 +85.214.23.49 +194.135.81.138 111.99.55.252 -192.52.166.35 -193.192.37.135 -209.126.119.209 -155.254.49.27 +104.172.24.79 +104.236.84.230 +104.255.67.131 diff --git a/iguana/confs/KMD_hdrs.txt b/iguana/confs/KMD_hdrs.txt new file mode 100644 index 000000000..2ba3fd36f --- /dev/null +++ b/iguana/confs/KMD_hdrs.txt @@ -0,0 +1,1095 @@ +174882 +0 027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71 5d83d0d8e3b7306b920eca77481f06c808211d38b9fd658e98359d4240dd8bf2 0a47c1323f393650f7221c217d19d149d002d35444f47fde61be2dd90fbde8e6 +160 0bf791ffe94b9e2568b3d3b25a8b85574e25244d9661d83403fb402118f4ad65 814a8b15aca52da6b5ba40e8a62d6b0f4ec183829129a45b41564e298ab42ce5 0a35f7832dfcae11b74e6097fd36c7c2e375ddea07941005e8376b6c23ec2b29 +320 01cef65ea1cd313d1798eb08ba0513d2efe2ed045ecf82a757ea281959906603 41ff38374c1b5181a9c4b7ce12a1320d6c830bbe1be7a4ad36be0488f0aadd38 0bada7a7f7065e2e1e450a08eadc53281418c41e0f778db7dea4d2e6b519ba28 +480 055acc579da4f14b250c4f07af25f7d1c9b1b40415c7a7ccd01544da7f217e67 780fe61dc7433c08573a8cb6d221f0e747cb8a6d95f11a9193b5b16cc4fe6cab 05fc414d0b27cfd1799ee9382509d4ab0c4fcc07a98a886248b225657489c595 +640 08cfd1f2b5b75a1d747acae9382e9e982f48cc7f667ff457838c798b05e9dcab 4b4c443d09cfbf84f4bf9b5397ef1c183552338560c07b04e9c3331bc51f34d5 035dc756030076f1f4044ce7249e1096946d801a65858ea81fc7676df4f0eece +800 0b38966f77ba726d7e8b70aa068f22307d7d8674f170529cc02e4c1535caceb1 d293d52170264793aab1a6fff5a1cf3f1fed7f4f3b6125ebeed5db194b9013ff 0a73ca0f7c9d8a9336c5170086ef41d65d5c348875fa66a21471d3989b6fb593 +960 0092671962ce7ebd71dc580cb27c9811b6ab495e47888fba49dfe2dd08204cd8 008e65f5368f2e48077bb05c498e23572b2287b0be8a27960a8731899acb1c27 03dd88f9385cf0fc63e96211dcdd1affe2d434ebdd48a8f800ccc4d4ba38663e +1120 06b511369c5cc4aeb3190062477c59fd10b8bdb9422b54e8f710c0c26ecbf6b4 973b496553772ac451544c965178cef779bb0a21025cfb5f73c3cf85022db0a5 0140a5f4f3cc029ef3e94d8d7b0d492340ae4f089442a3091e5946237c31089f +1280 0e4821a8a71096bbafe8a3ccd09e82c97bb0f7a9ace7a9f372f0f6f5dcb7fe45 cc9d305843b7c503d63919bedec6bae91bd58ce52f1a3cf93f0aa5ab203b3f56 01c929db84616ad991968a3e388d6fe30ea63aa05e46a513df3673750326517e +1440 026376da4d3d2c090edd1d1c28d6c0128d77f42e89473b497f6e211e5a1060d4 7027ca7d53036dcc2ecdb352f6c4837143ecbae8c72f852d19e96df72e097793 0ece3b594b90eb38caa787cf13770eadc9d8bbbdb59ef9c956566a3b4e18d540 +1600 09731394caa07c66229ae9b946718e193aafc663df7a93acf30abf865478cae2 5757f9b5bdd4b9c0741a78d48e12f774a6d67092a389279269af13a1c9b04b4f 01ed4a47d2ffdb4b53b6086518e59616103c6a4755a76780364c0984ccf5113c +1760 0cb6b11daebc4f074cb0deb941dd8e28d61437772018de7f876bc7697a0abb8b 56d951d047076b2b6ae921c6209303046de672d5b6ae1b32cd9517a5f95096d9 09e80c4772875c258f65ca4520ff8e542994f1934978421b0162c9d00b5fd373 +1920 0076032f3d12e4297034f9a1d822fb140c2f9121858f6a04513cf5d149b1b825 18b82bc527f65c7d4662f167b4b2fc7d3bbbd5dd16a2e9ff013f3047c3952b4c 0c18e775a55b0c4af950e2ef17c78b053a3bbb39d6a3dea81ec66e792e10dd0f +2080 0e1c8c98b7c826737eb86bc47034a068f8f36fc31fb578a985c0c44c19c63352 90347937d7237d92391c384e449338e931b19afb1e3cd4f37b1d6f6d33e3c2eb 073888a4bdc192a3cefdcc78ce141ccb5c50ea7683c55fbc084fbe95aa4fe484 +2240 0ec5a67f7b9c36ff56c8666e10624905046213e7d1a6aef0147b5d047df28ba9 ef691bcea9a90cb8ea26b82826dd556602220468ed0256be602bab188a146493 054ee63237be7cf1387b6590c06c77762dcf15dba05903646fb73c8aa8f3e7fd +2400 03aeb475d38f2189db2caef1c89784204f8cc81193df94d9bd52b8ba9c35beb5 9a54731d0c7892a18c5fc5156c029f8c6d4b9c3d7887c8a7d8a75f88e19fd21a 0e56a4db8fa81cd1ac061945ff6b03751aca6da1752082b55e14a9c322e92c27 +2560 04e78a8315920e4dd9601a7cf4546c045fb7c88b6edf4005c14c20b913487178 e8417856107025441abe52a5543e87a1619b6e6d7591066388a592624c03fc17 0539eece8f75cc4e14846881b05bd70b6435b3c4d0f3fd07b30b94f15e4ebfa5 +2720 09998417864591e08ed8c81fb63aaff4b9a310ddd029c1488cc3b165f5e52ea4 5e0c0e38249f82667698243fae4ab7bfd91919874a9fbc009b1e81d58ec1f4c7 0e2a709893a60526577a6a0d5da79a350577c569de151f3dfe0c5247809f2842 +2880 0324416b50a49abe59d7270f3f7806079251d64ddc6cb6fa7d974a20c03bb4e5 9da427b69a4fc48d113cca571cbcd030ad89390dbe57e3f4f82a7ce6f4244443 0e2377a258023761d9df670cba8a45b58477477119cfe839955323b7245e131d +3040 0366ec866d2f21fe36a38a85524d3a681533f4c3488201aaba3ff6fd153fd12a 53e61cb1564d0d4132d993b4c6825d34a848e1683ea7e40925baa61db9882f4c 07953b08044bb7dc6ef1acb011bf804a362b70e7d33798dd59ebd6111f52f485 +3200 05a205ca6208b373756a947194559a8e21357260e954e7c3a5cf02547d797c34 016c8825d92e582bde73a133e73fa833b2575a4d2dab62792c9e349fd4dac87b 0af8e3be69ec36ddd1bf88749c225e3b5493499c771307771c479aa324525bf1 +3360 0d6dafd478cb77381852f029d654d427f7966158dbb173a84d40366ebfe1b4b9 7485ef042bf6a7aa1e784e51342d566e8bec13765bc64bf6299b0b5d1ab607d2 051546832d08b02d6beebc7239afacefe61ba9d049166fe09c11337b1e632228 +3520 0d1c1418913d5f8565fb0d2609fdd78e223998fb65f429a4c53edef7090352af d455c966077aaf8e393a433dd33f1b43cc3ef23f1ef75bd320bfc7499f5b79d1 0269055592fb706b5054fdaa2f37063ec65a6ea1d15fd607579b7f506eec2748 +3680 0aa8972cef4a410b402a9456c6503a60c7164ae3b86e6b5e5ca6ec116bd4dcd4 2e3df893d0aa8be11a3f8e6b2dd603fc5ebe68bf404ffb1bf8e9d3f724e41821 0818f1841a16afaff9b95a98a3d7241e575e2f463ec4cc66bd37629df754cf36 +3840 05a06934341a7000f99ac35e6732dcee2c445ef64da2d89f61a491cf1a68ae8c 7a2532aa2c03fbfb420da19328061349959c29be1e168418b14908b62cf5816c 0e41945524e97de68ecba8c35b0c60f0aa171216349e505773da47d12e1732a7 +4000 0d96a960460ff2cce279d3445c75ea1342326633cb803638afaa5674fc70a2cf 8bfecfbd8e332817bc1d638a1e8696f1a1c530150e276500c1b11c9b74f43767 05c939e716c64fc14f95cf1442f05a543bd18953460f425652af6bd89af20181 +4160 06c764571b5104aee6279ae3039621272eaafb62364fe37dc7553cbf33990902 433a124dd9961e5c62a8858ba05a44b9297ade384744f8a4b446424854fac3bc 09f712263b8641114c6f6a94a573cf8e7de185b0226466ded421dd8561da6fb6 +4320 0c09e70f68decb63eee5a250ac5803da59ec6ec95e91f34a8b96626953adbe32 48adac2d3f2dd459b21f4d201c7c163c2e1fa2f61cda97200e6d82831cb2930d 0a143bbc5e5b8885de024d96e4cb3da716bd9eb8c925e803872efb4199d4f81e +4480 0024c6f6072d43030b333d43c9eeec72c88137a3b75fa651aa6cd7b9bb21ed47 c7251973126f30ad03e77a9a40bcdbc7b4042d10f414463fc22b78f54cc2945a 034f889d2d83afd081e3288a71da35f00cfec1eb895e4ea6ff088e85a0fd5d22 +4640 0e37997645aeb31f3d2dcdf0a5277a8747ea39a6d33daf7064dbd2412c4626ce 2e2ae3d094b3b4d5d651a41137ab86c446e415ac5d6e0bd48dc0cab414ce8e81 0efca74281c5003e27a34e960b4dcb8d98988ec32bad2d57246a784eb19a4e0f +4800 0bec2c451b4323389f98f6810782ea3e5e712e7a16a80764888a1d22b1551caa b3d8454d888297a0f5e51c5c9be2b9707ff669cb7b4c01cbe5ecd8df38de4b5e 0b5c86aef2589f62ea3454031456179e4ffcbbf4c13dca1199a0460f2135117b +4960 016d2e5f8e66a05fe2f8b94efad33ff018152c07a5f7f483f3a1e952b051c51a 3940f005d7188c882618a455414da41b08fe4faeb318bf0f74f1a189c61d39e8 0a8ff35691c82cd30baa1ef3ac080de1a42b1b35eb1a13f5783c0f26ba5ceede +5120 070d830d2ed11b4961f3794114c54766db28a4b592814570af9bc0fffa71f84b cdc09e3afde65496124c33f3b31a78741b9ee70b76dd060c5281d9028f83a9cb 05069a6106c088546413f3690a45e9a9dee980048f5ae007bec3a9a922414927 +5280 017b95f2480b51eea6c4398cd666396a9d1397673d9fec4df7355f526c8d0d3b 21da55a2541b56618b29dc758600bc66e9a16c14d8b5c8e7b00657ec415f5464 0437b5a9589f9bf344b9bd277acd054b74a8c84c0b13113004ab8107ced9cdc4 +5440 0363e54494d450c595ec074c0063c38908fe608becc133b7b8e7e64758a0d5ef c639a02a0080f8cd030ecf5652779ceda333377177a8e12dbc899ff4bf8b2da8 084b6080f2d9da301a6a6143350160f5655125669ae8c0134c12c25e37245427 +5600 0ba17b5bd3679a36030ffb0aa888d0313db7bca3a70af31806ac0bbc33366257 e29886f84e62b5f8512bd4dad136b9e4266736d8c76911ece75f03bddd26f076 0be014b711ffda9f04996260c6773cecab7be0ad3c3b85226520bb4390ba7fa9 +5760 01be99eff7ca1dd0e7abecfa8934fcb3403933d4222ac9ec0ca9d934036327d3 d291c05338b16e599e85e83f52052d9fef632980f5e695d087c4f2cfdd264ff8 0aecde10690054cc8c91b900c6600da5ff69cf36c1717449c6be61361022b46a +5920 0ad4c67b5c44497a1146daea90d75cdcd838573242e839b8db6e5c1ea39dfe9f 1e7d06d8714060520f84c03bbba3f18f14cbbfc6903a5d2b13dc45694f3d0324 02cf58a99d14834ca025035caa430d47a91431cef08bb64c2032a9cf95cb56e4 +6080 0d5dbff1dda453cebde21bf573ed6ee927b281b06f3a7102959309e887d38f96 454a28fdffb7bdf9604821290541c414221d1381596c98c8adebf8c9b722f0db 0b3b5533d8abec268078674ba34f017b76fc1b5403e66ff36a0b7eaf15beeeca +6240 01241903bb3eb26225e71c92032ad1f08b454bdc2bd4a98ca20fa484f40c526e 614f93bb3a4e508604d8634dcc3b84bb79fd0252c311f7ffec3ae9d81fcfdd9c 04f257378156ec3faa1eca6c7ea317fb9ecbc705f9b91a3b56329cab505f3c52 +6400 00e13e639e1af16491aaf2b0bab9b1b5efb6c099e0381ba1b84e92d4766c1bdf a0de2ca00d512d8c763141b5892560b73712c8868d23ec72a110a12dbcd8c6f2 0bb19750cd973c70263892b648fdb486f56abfad0528d582af42306304602178 +6560 09b71201b7423e28da7a20da7b5e1be4bf030e0374e4df5b696f1e84ddbdfc04 204d69f143a3948bdc698c74f912e4819109a381ddb0c08a810f3773fbdfe9d6 05b55ce3af859e5a110e599425322972199ecbe4d8cafc558446da6c5a891b7b +6720 085db36235861fe9a73a3aa895e549cb4db222e50ceff59c1db29df74815fbf1 3580ddb668e5142d3d1cade111977c38feb5850c6031496cf1a5fcd79209ad5d 0b54f55e1cf51d46dde7ebd143c3e05fa601fbc77be8cf231c591d1d9e37d934 +6880 030b7ea9ebdf525e51e3c5fc310d2d3658928dea74f106d39d7f3d9179effd98 b7237befa9302d3be487fa0c5bfe624c49f9797570357406b58153459afab7db 0b43506fb0996b16f14525b79c442e6fb6025013bbb43d3dc22ea0e76ad6c877 +7040 0a8346685ad7e9509e45839626817e98a06f656c28a369812c25acb026905a77 34767c69f2c41dc79312d437ed3525093e81e1662304f3eded7b10eab258644e 01328e76824af7a281844986b0b3a5ecac33c9d1231be8e38d14d77d370b366b +7200 012361dcc07dc638c62adcf3acd2a4470debd84017b15bfc94c08ca9b37e6d00 97560c188039d5aae8985cc754d64d4ba422f81ae5220edff7836ba3df6f00b5 071db7b983463bf10b914e84a31390f9e816500a7f774041616b9f50dffbe288 +7360 02ce0d941de5e662c8f8ab8ed35f40293b5e0a4542f546ed0d6c3169d4c11607 af4da23ea6c80f4fe6a4c21d39525b938b15dabdee363864d944002e044f55e6 04f26f1bcc608f2aea267bcb77426c9fee84cafc23c7385fee1ad1813d69b32d +7520 0a051b438a73c13f3d4c450515766681c5f1bfad41b46b816e92fa54c8bf7db6 8d7d722a26b72e063b3cc82f3eec07df5da14999e7c6f57c3df2f7b8048e0246 016e25bec6d8eec082c1cd81aa1b300c52a90f9f6e68457d3cc39b2f73fc70ab +7680 082014aef25d26cd21c6258c7be8abbce80dedf0cece6a09848f3139908af0e1 9404c363f8b8a8afa4a259ad270fc645b067447382191d790459cd9b45cd781a 0cd0d4892bc349a6de8767b6c56248d20f5720b1b150b5a2f9ab3b3570562a67 +7840 06ab646b5ae067c6f0a8151884a8f992b84833b0f297757fbaf774fa19fe06ef 1202f8b8c034767eb75123ec477040bd1cc46a118e6f1228451b1c4112fd9059 093c1356a274ea7697945c134101ee94e533290bf9747712029edbec712739d0 +8000 05a03fbd4835be0dc5d03f8b789718563759f98bd5cb17fb23a5d48e6a7e319d f9fe8868e6fdaf08399407b14a68a3453252bfffb98db6bfb4cceca22b090b4b 027889d298751cbb0368b03622bc17b9e0c2d53bcdcf91825cccfb4cb717e75d +8160 0874e7140e6616789511a2b4f08610c62747024221b07ec1ef8184bd5076aa64 28b5706f8cd4e88075b894d4c496896501cd7a41995d80c2a8d2982dcb804578 099176a994299d4e76a265013240c3b4eaddc2b24e2477ba0ed80c85e0a8f16d +8320 046a4276cd8def3132d7d61ef64371c8cf94bdfb19174a5eb1aa02491890313b afc2d06bdcb358bc3d90fbeb3ad3de334df6444c280fd9f44670cea17628469e 056f4c7bfde39a8ae630b43e05a2dbb7ea33ccd6f7ab34c2615d7803912a9ee1 +8480 0124b004e3df42dd6631c86532c5dbe747614fcdb361e53d4eabfacf254ce14a 54523fa6af18f143ad8ea6416038598f68a4b0af0b18f7937cf79facd62a0c7d 01abd49a2fd0e08fb8236f3ab2cef3a69188b2f0a400e8dbb000e825f97f51f3 +8640 087b805706cbf976735d2d74cc5c7873ff3ec74131a078086e5eaf8a719856f9 56303937c366e392f47468b4eba3e434cba27155a71037a5dd625ae841a87380 0b943203f37533756120baf47b19647a108be8ec5c2c32989cd0e9dbe95159af +8800 060c7cefadcfbaccb03c817c5ccf83b65a451c68917123a1ee026dd0b061780e 91815bc760871b39954904bb71a8bb6ca63c7796e7dfc414b23b615cbb80a1cd 015ca7a2c07a75f75d311c9d6703bea18d681ed502b3509a6eb766603458251d +8960 043754bffa11d93776726c0a3949eccf494d07784dc2828b6615ecbd185ff0df 5703114d9573b375143827cf5988e3f77dec70564bc4f479cb0d84c9e6816103 068aaf71cbcddd7526feccf3c03eb918d82999c34a3e38c6e7d49eaabf921de0 +9120 06ba51ee51ea63320a7422856ef04c87108df729f4e17a569f32d5bb4f6146ac e582fdd4357f73524a0436e8ee25bb16992ae05f28ffddaaf65fe764f0bd5a49 023a52a3d742393026c9252fc5442bc413d6571a57ba6f4d50f99ba5069a0c1f +9280 04ea9b2f9c0836608e7e93025e690476a9448c97890955fdaf7d2a227cefc804 3b0403856a29d9ad064d6d8b822f7a036b46b58a646ec0917adb4fd8444dc405 0873ddb46596e4f5ef80293efb81d865fa08c467866227a50db26073e3872c3e +9440 05182456d33758957d9fa3c3900f46bbf0a3836b718d3df8a0827df824f8293f cd936e88c193495517065ea0d49cb42b1d0349e2e3b450985905b6eaf0c26cf7 036156f64f981e2b80bc98ef336ff75c4bcd349f97a7d7e086de60c636f4040e +9600 01053a85e314521e84b73be7bdc84f5e8ab5a72e5ec1e6955703fb502a1035ea 6fa20db42b01433cff08d1a488edee2af3e37e074e92610c31d7c84d619e90a5 032717957da6a459fa1ac39acb51154ce0814ca36cf079d1a0997e05872f4e27 +9760 01011fd36811964261364c8b39f0786f0263c5cfd1d4bedb5d01ba7552108db7 55d602c82ce1a40147a04c2461fe6572c1264fae33a41891e493148b3b0117f6 0a52b8b91e4b49749a71ce1529cdb15ddae586efcace7ee11f17a7e6d07cfe97 +9920 08fb68fcc93dd2845fcd98175c78d30d24ba787600cf546518b7a8fae9ee479a 1a6c9fe38e8efa7c26c90b41fb8a8584a96e5ff855ff3fe36b799d22227c58a5 004a93774cea1e5353ac343251b3f83c7ee032d626c379a6b88bd6ed3769b803 +10080 01055c487f9eb8be430fe04481c70d3efc87c87d523b5fee1bfbf81547c3412c 93781b5e4be9d76bc4ced67d751dc50e7a3888a68a864ccaf2f17d5a228c14bf 000c5ed0e7f9b64b056a4d302efe7cae8137f121a5c77d975c9d4cb501ba8251 +10240 09f942e209ed7ba656ad6f8676e398904164bd12fc14bba79a7878d2c02db5c9 cee14c4ba61b4b3191fefa5c82e42402f6813cfa2bd3cfd2ebb4883dbbbf62ef 08ad5553de9bb3f2e509a4d1e1329e41dc2ab6394433ae3e5a0a7d1daaf6b2a3 +10400 0113b4a36a88ad1e937c114aa8fdb5cc4095660ede48109709f0664083926398 f85a20c6d581c0f01209c494db54fe66728c2b1ab8068e1805aa96cf55da24bd 0abc5dcce00d78d3d3f1354c1f810804ebb9e9a8a68ffb0fe0b8dc23702310f2 +10560 0407c52f0832d57619d3c19983b471f6d292f9473fe8bab5f733b1bf92dfc1bc 84d3dac757cb21abb642630a987497840dec9159e6cda76b9ba6eccff9204526 026ec07bbd35c6e507a29cdd1676b5c631bfe2565ae65483802cf8e5798fe67f +10720 0905d0df80b342024ddc1608c0976c9860357c2f773e3b0ee6ee69f19f1b257d c7723b02d692bfee94b4b68a414ac15b1b61d7fadd2da6ddf4da17ce160e7e94 00d671cffa1ee04d78ad2bc8e3211e0d9917f674952e939f7e37b152c77f683f +10880 002c26db615d41a1aea8e291a3155899ae2979cfbbda1579198bef08b9737843 99ec68315a7da008ba8dda500c125f6ba21a8094110c06a6148d04b1e373a34c 0482513cfeb7ce8f72ece04d6002043b3be4472a3e9e9ed760e095b93f461622 +11040 03a63aecc7f7e2b748fb17b670cfff459fbc70fa117f3c0c9fde689b71b52900 beb6823ca74b34a0cb25f16d5c53029184290ddd424b58883d76cb7b46c05005 089c75e4ca77d1e501f64bd083eb27a0a169744e727306b4d1d48158b4eef4c4 +11200 05807afa9288758c9aa39c7963990fe2a686814f88e9304857ba0017b4f21dc6 a7f0b6ce6cf3698703f41fadae51b91a62cc4cd69ecd32e8e5026d67d6197125 04d438767fed2a04b9a225969080de665d95912f5295ba0992e07685b5f66ee9 +11360 041e4923dd810845baf3cc00504bcc9206c4ba20972866c5333dab5b620b7ea5 5c756e60ec7f2b31d0f83ace118c637bf21786f0a843596d43bddeaabf4bad11 00b556b4400c19011a04980eb9dbe50c0fc21a72359b121220159a2125eb6966 +11520 04e5e332497722b1148bba911737b34ff9ba7150a02bd5d38fa4c8694a2cb7aa 09bb5c437dec0e1b4527c9abec553728463b9e2f33d06ca69a0f7dcb08e8b86c 007d9ea2e0bd5e635be80932c550218d728612397f4e83ad61e323f409f49f86 +11680 082e342a782d2e234ba91b987ff5b43d56dec9924f86fced37e1c826b8287632 486a9fe6de35cfb1d4658e448fac4ea5ce59f49ece0a0f16e6ac4ba4cc21be43 033976ea87e41ac31df34b16dc602ba7bc56e3d565ba24b0a9eb9bfb7a104c82 +11840 05f2340376aefb02db8ed820c151c73a667e0adbbd31e3e902e3d39594074397 f8071a6e67d7a17b4a2a71b36ca9985957e09ebcdb84eb72e321d5185c016b23 074e737e942953125c3de6bd8d1938ad059693e3519b24c2f24f4b80744cc0e1 +12000 07075ddd3ea1ce5a0315ed3ed49c54dd60c0fa01596d9e6b5a6ebc8abe4ba5e4 7357fcb456dcddf24d19a9a72876e22d3b6f976a6c017224552122954312a837 04e3ee3ae5b25662b752d782315487e53b28846fc57ecea5f08d9c156164924c +12160 02e81cf48aa02446cfe028fa9c654c658a91e5e4bac27afa95afe0186bc6ab51 cf01b19929ba8884c6182c444b545786e8368112d3cbf299c2b3a6fef18571af 08061ce55c4adacf3007c4f44c7581337150bac6c86fcfddf7b9905141630c94 +12320 058e83183ec918b67412245642718f26b3ab7740d1862d3d50e557fb97d0dc97 f5e8163b47f505f51dd95938df888067c714dc8fcc518bb4acc17536fd1d69d3 039c46ac1b7a6c2fa68ad3120fff71fe4d4e3630b2d2c8177d859f8dbcf5e5f9 +12480 048351d76bafd68b747888202cf081f40abc8a5129e6aa56c9b49f43cfd7bd1b 4bde67d927e6d7a55b685c63d944cfad4ccd08ede3f4b1b4399fa7325b82b54b 0670d3bdd5f4289e4e960dcae90e56cfb2c57269b85bf587e24494d03b2708aa +12640 05cad864556a8f5437a892bc372ef2548c5c6d10171a2aea2218365205045abc 587e293ddd67b3ae1f2b653a6fee3e647557a4d9e4593b4e8956f603f67fd49d 064dd63d16a3eb471548ee1ca705feb16410c431b3f977701e6701edb7438314 +12800 00089af72bc6593c25738d2905be22315ed2a0777cd580eaacc0bcf0ef52857f e5b870be45f9b4a12dd95a43e998f333a5b689317718a8ec3927d462165b13b9 0085a94877839a3b6cabbdbff7ba36fa078787b7e6ca225cfc9c27d5eea44c46 +12960 054b270e9940705fe3b831b4361797039b338a1d4e2088acecf0f7e6cd35a446 e154fcdedb90dd26b057f107160e95a723ce4f84a088e5ea7ea98800e1d5d9a2 032cc3e67c570b1f10995ca265031ba8d7e5e605048c37417f516954fd27bcc3 +13120 000942ec9a08a8cca95ae57101cafe99afe2eff5333c00838514a72d1e5d1938 ca736a227cc73bbfbffa08de4924c09bd7a738828e8ef637fee695bea54cd174 04ac8a3fbff33abe83c0d42b0e37dd39a27b3431237645d36e8493e982b8491e +13280 0446ddd982d1d270c757753063a55f024df54330b05f6edfb27dc7755c83e313 330e688ad110e4a8735f7c0ca3d8f2be1ac1ab265160789bf7dd087c497ef9da 04d94e5bbe37a71f15cd6a355d57db47c6b17aa3756702718b67220788077cc3 +13440 00579cfe3e296002c14fc316f448de968db6e67b3238358ae75a5cc3c64f5be9 782f20edb4b719143a453cda2ad9f08722f7f25830612245be3384c87c6e954a 06e043cc63c06f500818b0d7d2237742b3cb26e09202f0c1c4ebb927d2d7894a +13600 0050685f49eaa6373fbaef883938647e0d601e6cffe8775e7b9bf665d31b14d6 2a82c01d76df0b968ab81fc64260273dbd01645bb78687633e1192245e380e17 01461c34c52a6a32a0e99a6683916b2805918f1c1c5ccc15c7eaa739c1d9e85a +13760 0732bbf5d9347a09b2c0f1b80b6afd5de3c78d29908289a3b3f7d8c41598875b e0b538fd4e13a81211e9b1507846431201c1ccfb7905de9c493db772938e1e30 017610a0d4f52d06885b2af0ab66906de68320a8e96a23486bb49f5c562ab460 +13920 0389249c4909c8f987721e380940d5a9b72243f62963991c3294b71cef37748c d5b1c0960641600327b4030d2973fa5cdf68e8aff87f124adcbf71e2f0fd0d9a 023813fccd263a5949b97197b026d45c7b8d9e1c1f87b7024f7a1cc49d754157 +14080 06838f0b1e7be503dead7ed24e2ca3b626b83495e55bdd0c41b2037cae7a274d 7fe58b7e55b80f2de1d926a8cb9d2d2f342c9c984e4954211ac84206bc431321 02fd9cd5874b2946d3b6be9c862d749b284f20ab77be3b955dec0bca97b03ade +14240 01d8e9e38b7b8eee5d1b7259cda912748125ea1c35a3ebad7b915bf9c8c969c2 4e0434950986534ef54afc9d019596ea530689e46bc131ad17d0cb25aa222653 04fc709d7761c4bede8ec1d9db6fa26e09fa13e7d972ba4d4e044d142bfdad72 +14400 007a4ecb6f6fd73023f6ba0065a1cec2c982ab202266298f484e25a31b2a934d cf0b86bf58a2fea25225f7327a36d9c05971c5953f9c7ff96674fc4aa9eecfaa 067c56efc22974ef7373df81c7ccd9b74c19236c0e060fa938b70ea18d92b5e4 +14560 03e69c07b0496d61972016ff9452022ad1cd5a4ed80a216c6f5861f12b0a5233 4ae7d067238d5f1a630e22020ee29460690f61e90c26449f19d33fc5a2910fa2 002ea8cd10c2a884a38ac4e00c8f326b93563af6d94ebcc069c227a34b9ac262 +14720 03df95273c339051e7b95cdb95906fae0147a0cb5ab0aa799d56efaba704a831 02a70472b10a39b56176d65e6c6528878b4b1ab9c6d51685b7d4e7857fb6f981 01b3092dcc1ef9ee9efb4d61efb42ba97d3defa759f06fce2560a0ff90303224 +14880 004b67412f8717c91753fb05047ec20b89ae045f77c66614b715aa3536beb16c 05400368f202671cece7c46d8cfc4d3c40d22dca651cfc16b0950f615c62a912 00be8a297bde927aaefeb83234ed9182bafdd8d44746115136b7b7241e81dc29 +15040 00b78108f2a8045160c2a0336831a2576cdac87bf7070df794d3354dc61979c3 532a5e2f38f27ced099fca0cdad061686cd09a4fdb79fd01b60e8eb60acb8f4d 047c17c6481d56edc9469ae8f5dc48bab529f648aed7bcd325ae360840d20908 +15200 01f7a1188717a99ae821fc24d908f20816e0cce228c6f70d0ef7e63dc3e4227a 309a255a64bfc3a28f5a458c9addcc8cb1e334617a52402a93cea83b269a39e1 03b103f9314200b204c7afbca99ca7ff22356c3628e9904c2f79a396ae3bb0d0 +15360 01d3a27ae84377fe5775f1e9d431f9fd11e454d8dcb328da67d88cce47eaea81 70acb10b8d7e7e22f28a3740837a7fef102e59390da7257743fd189efc4ac3b7 02f204078f94cba49eb225102886cbc3f4c55adf4a3665dc1736242511f529b1 +15520 00182202128401f30a99ddab28c27e9e3ea5e1c8832604cef2a8945152ff0ddb b37a9a160fd2e0d0fec699e371d9e43c50108810c86e082431218963bc274852 0171968d40274cfbce2511f6f7e51e51217dec5e0a93602607b0079e04918525 +15680 01b2feaef56dd73b3e89fd0ecbf24d9ebe443bf762f239a34ac0362f863e0d41 68c07e4d30fe5430ffcc2f8c457bebcd33d634c91f80427e1a661ce64fa3352e 051a93e2c40d85fe476cffce9a497a1f28831f5ed3325cb730ddd6d3c750d00a +15840 03730f7df95f453430bef7d6e490ed0599acfd903bcfb4071292a10fa0a40ed7 6d28d5156162f9cfbeb4e133162d414c3e7364b0976e4d009a9189bf519763fe 01f3d406adcf3c3c65dbbeedfc0f36df53692d305a3bcef9ee3fffba506a2633 +16000 03c3518e9069e9b16f4ebbdb072e4d3dcc5f887ce52aaaa01f6e7c2dc5fb0edd 698bf660ec57bf9eda7e223313c7c8d8f12c1060b5ddb44e513f3251bc79ea13 01aca22e98d19ce412cddabffec75ec27edae184ba6a265cdc4ace002728386a +16160 062f77b8a54b9bd76f1890fc1751adec6e384e8a088c18e2969349932b5025b9 c08c52507d288e3a18d65785dffa29b7f9e4e71a37d4e712489c7b041f02e11e 081d66acd9e5699cd781092675037165f884f2bf6fe10c9286bdd466b12fc362 +16320 08462db32dd892343a4da4e522ae541eaad6daf1f2b64ec7ad15b8a012c5d679 69b26e27528c6f439295acbac7e10e8bfa04c8d8a559a80ed9a8bc6ed6e7930e 041e0412095425569c0d646b5df9015fc93a5416e03bc219413e77ad0be1d098 +16480 05913b5911b1f8bb603c04729790f8479240f73be43b39bb7386455378f7a5f3 e50340d95c786c09f19ec58c35c94ce85049e4233f5d00f7fd3c47a4c345a905 073f309559d67f82d22c22fe67696348c7e81721d5df32a79846ea4ea533e3c1 +16640 0873243a4d2245fc13369bc4213e5fce289efd3446e39b196aa3aa2e5e8366cb bc0a383470ef09ebc9051172bc9ca7871a454184eb46ed4f2b3c52350541fbf0 08018313d1d1f1c147aa155f7f196f8bdcca9a66c9959d66214afe1392c47f60 +16800 04e23bc7bcc0d9217e35352270a592cb9a2b78f8f015405414c8652594f2114c 185564a6ef2a79876c0c97caf30aa152a80bf16e8fa594ca0405a3f7db345244 07af1e0a04b9e6d59bcb933b33a863af2e0e7188232233c635ba6f294db6a159 +16960 03eac40c4c7bb66c6a1c684a13a578eca3fa1621124cd9a19c8b8d98f82341e2 3ba47a01cbf0c17b5e5dc7961699fb4fa3c508cf7e9276feb00e3653431aa6f8 0742394b02dc8cca78d98574f7fd9de590f3f3a4ed4811f23375c5ac8444c386 +17120 0759582049033f47452be40b398987a627af7c5025d4364859d9b7f549267b3c 070db83a3148297560129236b53cff2594d1d3a24869736a56445a8ce1759447 066cc2a0869f93598fdfb3d485eb68a4082619a3e7fa3035a8669e385e5d39ed +17280 035d67d05978e2c92ce1589e397034dad0607c713de55d9209151762645d1812 1abe166890c9b75315b204c5e0750cf7a7e1e5d35e4e22de4b2d72a8fff0949a 0466a3481acce24020db54e5ddecbe88c5f060124fe7ae4b63c34fed2fd408a8 +17440 0565112e84013f85c21a76562e48aa1d8a0161af816439e3ffd252a45f7895cf 1bea2996f44ac16a0beebba465784925a0ed77d4656c9ad73fa1c58e90ec00e0 038c35ce84a66a9bc656ecddc9ae4b2d8c6361fc9ad0b95a9c88996273186eb2 +17600 051b885daadba578cea0e3da6021321c5b271d08b9bfc4f61d61083c0882e393 dd68377fba87182fb26f8eaf13bbf4dbdad347259e5001a78e111fd3210f96b4 0569002f701790d34459f1fc443c87adf1c045af8fb98960d3f23dc372c9c17c +17760 08f6afa317f53112becaabb76657fa9f32be60f43ff1a592d8cf53dad7b143c7 022e035b39e8031d08ae545e92c14388379e9f610d9ee9b754314feb77531680 071e5e61652bef55b91f5a03fdedfda1ac2e20accd6cc1c6c2da6e9f9998a5e9 +17920 05cf72853fcdc999bb37a9fe73838dd9a7b8bcdcc774fa101e67f70ac7cc75e5 8297f026e67bf1e46f907342d7ebc6f6d9969f895b91656097fedc8f0be64a56 037c1d09ab77287ac2ec43afdc94d610ef2642141fca6a56621f3e85a7db808d +18080 05834ac54cb41bccbb379bcc8648011ad5a0fec42411717429ba2df03700fb28 2b713c34ca06d5dc834671e9130a95446071b7bdbe37712121da2dabb351ff30 060afc0de19e7c69653d2d65549cf1ea5ef970ab5411b9b3b0936d69ffeac4da +18240 00a090c7d1ee8535ed8185855462d180a797386a32dc6362eb71724307db8aa2 396f69544761b9652a937bf1374558714d7856190313a679b7301e06d038b19d 02378e2d901108e8e8abe1ede2295d0728f475d3a4447052a2bf1cc9a9284678 +18400 058fca6dba148baeb157372f34d40ac4f4ca9fe36d1d71c1a318a9146a19603f c2086b7a05fb30a5efd2518d45c625cd2acaca9df86ccc0116105329b41be64d 0593808e63c84f85f39a67eefbe75104d05b874099a24adee6afc35fa5ac900a +18560 0505465e10c525af59d8df6d497c8bdc013a7dc44aeb254fa1c70846a49b2df6 ffdbb44d8785c02ae4632367a3ef4d482f97d56c1898d752713161ffda568f9f 045111f53f217e1a9317f68e89cecc2921dd10a3bef7c8e58af449c18e0ee336 +18720 02f3061fc8259e57385edc91d26656200e6bf8f979dc54cb0c17aca6ca979dc1 0fb0c91aa203cbc9b540efc5ca9408c03759c284fb9a26f7150b8f08bc0abff0 02295059c37e1b1beeccdf6c70ec4ae58d2eae1f701bf68ba378291c75dfa4f7 +18880 06b2745aadaa6da1006a873795adbfc79c85ee3d230bd2006a07974f5c374245 59c2971c0c04c42fb6fee900c8fdd96cec2a20d1cce479fb8a16062462e23b0e 037b60807dedb0343e3af768f868d1532dcf634c18e6db34fd669f822c383b3f +19040 016bc9aa342c0d6139ae692e5b580acd4c85c6e17adbdee1447f9ddeb41d2c8a a23f500cac06d302296a79b7baf4cd9b4bf180229a967a683317e60e859c75ad 01c1bc59d2bedd186ebd5289e6abad7f40669559da853ac6afb86f6dbc75cc57 +19200 0503d2865633726cf4d620faff7fd93296a8221b6c14c9cbcfe15a5e6d1305ed 7eca2b470c4748d03588a6b5113d923dde0250dff3506a91f34b702133384eb4 04db5cfd613ce6f78630e08f2b65e31693e559ecb456138777ca0522dc2cb9ae +19360 0025f619464e429f5d32f0d66b397020b1663f60ecd752d89c3e70b73bd67a8b d3deb7065c214fd79c19082985ea66c83cceb223f924fbac00c16d747b967c01 0430274a0ea523e1dbfcdac1d7d0162d0e70029fb2cc95d2f7be6dc46e68a26f +19520 009c11ae82fafed335c4bd8045f26915c80e92b50bc6f5b4f26d48cc9eb9c0dd 7c66feda9d7542bf01068a636dedf5241f222438a7fe1964e245f162e3ac3127 05656dd7635e144ed0edc5138cec6b5f935de8fb65ac9f472847a21307fe3d54 +19680 00eb3532bea29ba567f105e791cbb95c5f2dc84fd84e5ea1d515504a3b7a34e0 bb7338d133e29f6b29e104bef6c24a2de385c5bdcc031dee30ba1cdf4a29c297 0552630f09924ac0f70a0aad06a5784929edc3fbb5ea6c7b70211f39bfaccb71 +19840 001c604ff208b05e2959f5f9466ec27fdec43793263cabe6333817e8bb1fd4d8 418a1b97e5ec430b08f59e434fb60cfcd4471dba27b5f7dbd39e5595880b85d9 0553854826a0c7e3d4b0ead7eef2ef078da728c0473c6b4301d4294f393970e4 +20000 01bbf0c38892bdcced62b538329cf63bc7badca3e7e1bff8eb10345436871c6e 4a35b28acef273aff6289686c3ed6936d5a9349ef35ae2bef3293eb365545cce 026d67706cbe6964ffd05213c51b4c521019c769556842c15a3cd340d061823f +20160 03f933d385ae8b01a3005b4e3b0cac9d41ee0663eb731d603203c9bde2b52054 a433fa2253c3b57caaf6124dfd31a31e751ef7e8896d96a3ef2324cc6ecd04bb 021369a56f8cfc1f1b713fcd2839fce3e9a42b4a4fb025b06f5356bb1c3f2799 +20320 0351ca754589854ac57b506c5c2ec679dddb3c517d7aef9d124ad4b113288afd f18c9e4d6c3121b8d7858dd8648636beda6b24a9062bae3b1e78589f86c8a50b 0034fd12d8e93bf4462b81cbddb2ec0773d13b3da061a107084e0af1a1e110eb +20480 031a755385b897c1cdbd08136c47da1c00f727f5f041048a78b9e88649a8e055 3d4bbe548410d45c1e2a461a6ab43b2ab29abc2cf6d62c094ec12fd91a5c29bf 00d221dd0c943efa88525aee48e1701602ff637a6649701222ffa2396c00ee89 +20640 0337365972c77dae32c3c92895659c88b41f5608c23fe4b05bf862ebe8443fab 669cc3a98848f5dd4c191ce84ee56b2d067d375b14b3d39921c9c1ce1ab2d77f 0494e25e1d37010734f51ee9ece03c2e0c75ddb0726f29c4b6cf2edaa96d70a3 +20800 046862f763d0dda530725f5ec144da78b9bd3e5a2772e6c559b2feef00773570 9dc710cf89627bfed6942935399d19f01a13960f0b756ca2585b9ddb138991fd 03535bc7cc0b3eecbedc05d8a64c978d6cef6d572d0da48c286b2ee862cfbcc2 +20960 03430da86ac28951c8f0b66dd0e6c21615e8842c66026361c6a754c5356f62c3 2bf55170d314747051fc1e0e226ff8d0fd34c4fd41b8b9eea73e7a76efbb0443 017b48ed02fa9df5fc168fe9a4a43d1608dbf2a692301f3c675e959998258832 +21120 036152276305599a5131132d134d084c4131eac3ae3018938493179fcbdd314c 2c509e7c0e8c2db8aa85d098e0ced38419caae8b95146ed6f664f12020a52d4d 02fcee1374989c2a1f00c008b682549afd23ce0ee9791d50774a6e71780ea242 +21280 016aa7aba41126620cc0784bdab8a47cdace563e4bc2958c73e60433ecad9458 09755a54d063e7b73f02e4d2dc42f8aabe484951c83740912bff6c6ad2cbc503 020f00f58bbc90e5b43f444edc8425ab7b281b212f7b83590f5fb69579050564 +21440 044f78cbb5a3c6ad4b1b17190b7c354e5d55ba14cb4b90538ccf63d523c143be 2b1871f1b1a6e38795dd88d37f1ba6841bf1885c379e306ae818cea634cee54a 01d0447d6f7e9596f7c6d2193475e5941d586b73b2b0fd40d17500bc0895f33c +21600 0459b3e3b7f4ba268074595cbca9f00b371f5a219530d8b322d8a5429521b5e9 c36fcf38a81f9f3c60e50737fea1b1e92ccfc830fd3034c7b34905eed4a6db09 01973ab2efafc31ef8e339c0d2a12b53428bb6659316bf7e775ac470565a1a17 +21760 03fce0eeeb43df31b0e09c22206ecd7facb75808a65466eac1dd814027654f6f d847a6ba3464ce28e893efaa71c4b5917696c6bf7542378cdc30d9eaa99ce729 01716c5dfc5d2b1fa909f755be23431214e60d8aff526db009db55bf4bd870d8 +21920 023f7df422d0d0ee6e2b492275cf72f9a501ccb649f924e0ef11a5f11f65741c d5060bf2e18d4180edca34bab37e8352f93055de1976be558ad11d3df1dd1337 02a91295215146c55b289713979f0c460e4033d098247c924225b594e8ba964d +22080 03aabe93782b425483d508739d0915c209bb6986195aba70c3b99e0e7b941737 b31b5e558f40c1aa6d2d03440bb09d795d0c17ab89fd32bfa1a67927580ed863 01e5471668bf4a01b05f932edcced302897e99190cbc743b62eed92b232d944e +22240 0187f7318461d3ab8e456a67b04927adc5540a0b8a590a7bf92b7911cd79d6cc 70155a739d25a84a5dc8744c2bd7906b86737e2325112b9b6bb1b52a1055ebf8 055165882b503055582ffd47703dace310d18264c6c9927f089bff6977597563 +22400 00e8a3faa943abba615fba538e5450136fe3adb8ef1aaac6043ba78e044976c4 6edcf28aedceabe17dbdf22be6d096d7fc7737f3bee3a39f02dea95ea789973d 03da03e44aae50dc27140bf5c9abcac4473000aa199ef09cd3131ef4201b7a71 +22560 04fcab42d6d114c6f0e3e2276f5c0cd6692769b0d42b6e840a2ff82fbcd787ad 43637afeafacf8a48e5122301161c503a5315e25d155883762cffed6efcf2ab3 03e3dfbf8c61295ae08115b8b8e8eecb5f3a03cfab0e897c53d04145264688d2 +22720 043695fa9cdcba43740a2978eb67243261acde997e952ab4d53bba607427644c 349a5fb847cc0b7f547530ffe84eb909f88c8304462c79fdeb3999ce99d0df40 045ed5c05e85bb3aa81840e0a8c3b6729ba076f7a3c43b619d66aa5190b6b966 +22880 038dcdb512cf8dcee5d60fe85d245b46a845e5db07d7996ddde068bf82e9b0d0 3f1c7d4123302a6ae1621375a0d86990d6bf67a593674d73ccb277128a92fc9a 03259251707b36b049631a5ffee19db627d1fcf42d771a8c7d17a0453d6b5998 +23040 0282f04af3b8db8fc717911c7b9d1dc22b1322835cab1f602d6a606cd94b72ee 88a18064b5b15fd5a0f18b3ac09734acd137b4afd0f8282fd000a9e3350c8b54 017b28f2852464d786028299cb1ec18b0503dce64db8f8663a4e47c57a416f42 +23200 004eb20d9d5188c9f52ceb211b5d40c65a76452c0dea50d185e6bced4d5b03fc 5d1ed6dccbd7c847778356d268e0a258e966d4be536f479048a3cb06aafae44e 01ca0cb19f013820fe9217b4f7096f3ec7210640789a8a98837ba96272e74ba6 +23360 01c43967d158275a9a11a586991842292dbb1ee8e1a72ceed20e107bd0a1bf11 6512d8c845593a21331925c8b263fdc9d86291f393983f52ce2481a7d49dd642 03258e8f2d8e513279f69785ffd7401eef2d996826ed1d3568dd1a241f6a7dff +23520 04a6f41bd405137ebb5ebadd191acc362c1a40a3d71cf76982e9a8b636c81f39 07802f937716e4bd926b83726a2249a48f7d96a8429a757c3220af6e345a731e 030e660b551ad3288a8550161f6851d8e0c7542e878b21e9dd80f87061dec897 +23680 01f3b59610e07617850e058174434535b466a1bb860f67c167a4ae1fbe1eb7ca d659dd1ba0017617d2ae1c15328412ef345031d4ddd100fc1d00addeb8648da6 00f67b95c18e9fac7d63ae9fd490ab4d2f5865a4361325918a96e1fa0a87d680 +23840 0100f07c566d7e24f70f8e21bb00fea7b529d127afb7a2df2568336ccd190cd3 2e3076d2298cc0d3dc15bcde7c184923235c28dc47a77124ec10421d640b86ba 01657d427d976bea52a9a03c3003f97f21fc5f7b10992f463a36077ef29b7e29 +24000 061194a9775a695305483da60f9b5da5dd668c7028b02cc9283dbfca73014b00 84aff83d18e6c18305bbcb41e7330762c68be18cf669e6672c5cd3c560970c1e 0342fda5b62f7c62fece97157b9edfc575582e374bd963efbe88317ae7a4e6da +24160 07020cc7e4cf5efef6f74275259b61134c9d3a33fb663178eca9b46d43a34386 854f0797784f0aea49039fea915ce72b4a2e9d02dfae716a777a322974d1e6ba 03dac9ec94dd6531aced5281d626416de09c13793c4b6c2fba5704a97c818b64 +24320 01802d41efc34d661ad9976ee7590fe9d1f78b5036dfa5896f41648ef34a33d4 386626aaaf4352b8ee1ba143ca227258aab1036decb0fd1d720b11bc350766cd 0357beefc8a545413595b05d845fd4abaf42012611ad1bf51d4117f5839fb4e1 +24480 03f65f4747600c880be44b155281bc38920e62157788439c9b50facff009b9f4 9ab9cde94b7d308f1341f0b92fd36b9b9d3fdc51e25ee6234ec85159e33bafd9 05e1573e744178d67d7dbe6b23bab85ff1a9f166640381c9bd1bc950791f4cb0 +24640 039f7bb43954abc760c4e79d4d9e2167a24ce4f032d6b7e241ac6dc6d17aed20 b731d7f10b99d0b8df33cd159e3c3ced005526a3e911f8136e9e69fafb670e49 01304c585b205ede961e0e1d80fcc960cb0fb4c6c5cb00e2fedc29e62d31dbb0 +24800 045e1a581ce11435f1d59778a06b76326f2e984dedb8bc918cd9347364ab2500 aef22e502fa071de266b927abae53e03d3f77ef8951d46a4280a23c07943de15 06068780a80353238f4439da8f710f388e1227020d8bb3fca3d3903e0df2eb2c +24960 00e1cf8a75b5dcee8db8a0e514c348f4739e9dda49ef6d73dd7674442ed7d6aa a41e2900103fa5104f059df505a9dd4e12c982f8569f2463f90c19bc0f4c08ac 00a71b7e4b6f42181ff48e0fe24ac71f7b1571bb323ed1bd75285a5bcfaf4af3 +25120 02301dce2f5d7ff276fc7635a9929fb6d6b5510e41c641bbef254e9795de5746 cfb774986950e885410406b3f3e76c319a30bfb540db777949d1e8d22c1b194e 0163073cc35e0eae31a6e03badbe872b39710067c22f09d84d872a5b40ec6ddb +25280 01979a18535c7ac0bd5286052736b8019bf54e91d6005a24078e0b8466ffe990 5f7101b58ed4f3199cf2ed69650e09bd837332e9eb0eaa66399a97a085fe0454 021198420725b64574d7751422f2308bd87d495bbc92170bcec4a31d3b9f6f48 +25440 00c01e05d61166ce48e9d90518500c251906a1ff3ca868df13870ae07f87beaa 51ae960954159a4f4cc337c91b13dbb53e99e4b00a43c453c101919ffc114c64 02270d73dd8a8fa09448754b3f1f6a9c181d780b66c61ad4bb602b2f3a682efb +25600 0708a2261a31f419840783c505e66ea65e54f46ccb04881030d37e7fb55542b0 6ca9c832bd5675fb4a7d0528d726ba579cda54795a5dffff0c708b972eb604a9 05a344d0fe5b255862c9ae738f8131c301064c224725159678ccc37ac617edff +25760 01bb9e6a407c85c14622a864fa29ce18f095ca951341c4f2d2d53d9bd2dfb309 db25153da72a0e4639f384c67b23aae2131efd43b16b1ab1aa1de35b1b09cc76 0271d544b6293be7237747e2e308378212c2f4e35b987e22b3d978361964e201 +25920 00d14592bed56fdd7f328d92a1fbdf3c9a260ab4f25da310100488bb0e38d48b 26a6c0bad3d99e4a492ba600fa86738eba128ba5f1c69fb2ce0fd4eac299c32c 02db135d2e3dc0c9963f950796d6735f706bb88ccd8c9f11f9a680938d94bc65 +26080 05b68337622e3931563a176698e34f815bc4f3c075cad43cf528a112ae5a4105 f62d2843c2c70f57f9cbc4a92d379c1d18ab294ae85fa8d0b4050d9f67bc86da 0292bc2feaad76ac9848bf667afb90cbb85ab5975b4053cc98bea4904d37edb7 +26240 04ff3a7810dbd62219390b67755a9742c940d3db59b4cd4c9a0c425e7536feab 266ab5f34a88670633463b12dbde5766e6df19f57570feb81b32fae88d196382 053284220b2ba417de0b7e6a98bb9799a822afcc6e7ae9ce849eeaf2439180cc +26400 003a6f8f5bfbf4f5704787ca66cc40210cf2a9278efc1193a35b1131c374e258 a1380a7804cce3d70d765f9b39440cd33f9ae1cb3eee814461098fdf0034bf7f 0431f4ef3c4911d6a1ab8048b4b129aff8238c76cf705b16fdf2326aff433505 +26560 05fd25aca8a6d17e841dabf987e8fad0f4c2650b958160741efc4b5ea711f442 bd65197d3c3f38ca5ddd104482fe4da62d8dfbc3f81511a24915881b927a7640 0548f2e659c78ba8ec5439b665838d76fb94b37f1f617dbcb3995ff11e143890 +26720 0346f215ca28cef4eb0fcdf5a97c1d71300b6fa3bcb25a5625d93c6ec21ee728 202b4fb995dd425b80c06b204ed4cb41f3dcd4e169770b67345e08c92ff9bad9 052dddcd36d530d8f2cd43ed0f3782b3f6849b7137f6aee578f1cf41cf44e97e +26880 03c32e9281bfad1974f81fa353ef712fd343bf800a5519f24af671e7861b541a 101fe0efaf162261c43415de0924efca0b9f914fbdc32050a77c82bd73e5e47b 0304573c2c0c0478da4b5e542d6432bad8cf923f6b4cb191a329b3cbf6d77e2d +27040 060c522966d5a6ebed0e12daaf23d2ef9c71d737c482a51ebdc246615f1b5c62 25fedd83e538510fe34f7b397071d5477f9b21d476565885cf75fd21dbb26e92 02f7eafd088bbd0d594f4c0f446f9f1107e89c69b6ffadaec4f92906c2d2ca3d +27200 02eba6699e5ee8ed84c28a8c1c60c6f5881fca3fa6cf1fe35b7b9628a92b09e3 5c2e8b91b37033560978b5ad6efa58e6bd7d5f8724dbded94d07daaf57ac6878 0078bbeb08e367fbd68c6f7af66ec12572e3c3ac45b2d5cd5ba294fd71017ea8 +27360 0315ac8a377ef67d233791a72ab3159ef425a4f7418de21754f826f979f186c9 b2dd43414059d92c5a343d086e01fe5bb5c4102fbffbdcf4ec5d3e21a0419902 07050ed4b90e7d4e565de1c4427aa0973b3db7258186c4b2ff3ef6cdae0baaa1 +27520 042bf1db22c616639dd3723414d7b5762aebe244f04d7fae11a778aaa504cdf0 a4880fcc967b6bccc082c1706f799203f44f54bc6447c2c1545457c37d564b13 03aedc6d7812064f9e66da2a8a37a82f933eb948c73f5e50a24cbec6b9f4a4a6 +27680 0000fcd183c8b3c182883b0a461e402b712780fb4b0821e5d8d3e4e954be3f8d 05513af898ba5c57f8df9a1a6ffefbf1f4313ff6e2c70d65b879aae5d1b0e0b2 043537ed58300043718b12e980f2688612b6e3fca062547ac821c42132dfab06 +27840 0079e9d9dfc7dbf068a67d48493cf5e5567a9f25d9afa254fd8313aa214d8de6 d41270a7670817e46ca8f5aae68be7f1f05f92257773679d05f53aef81aa283d 04337851869bce9db3638f60b14443e0e694c9430b78ff105a67182b44c0a2da +28000 00cc2ac4b0c915041ab633e3ca616eb5e76a69e93b1ed4daa2ab2f06a7ae4bfb 12d7bb8d2d2bc5837143ae85306328dd0bc727b0cef38ad555ffce8b821b2125 059d55f1dc7c876ca13a90d7c5f464b49142ed76e2b65168ca8f1dedc9185529 +28160 050c3e67b506ca7ef125966710adee109d90a848389704c1de9ec23071de7c0a a0b9882ad2c919a63a950734cfd45d16dcee6c7944c03552364fe2f82a6800c8 0512cf469df5ed101d27fdf5c924794c3420b5cd2bae27d81e46111f1b0709c1 +28320 00813e3bb76513ddcf9e93ee3aa73aa135d632a7356be5ef389278a874826c33 7d3668dd8dda851680e5d6d8d0d6f913b9934f54246d54c2b5918f035339bf95 056ec093aa27dba785e4d2638dafff57bd5ff84c7426d2f7d1527cb7b27452e8 +28480 0099c72f1343aaba6508945949ae0301ff071c8597db51fd0290fc9fa23149e4 5b11185be1a56d046264ab7bfd975fd190d67108110d62d9a00576aaa74dd806 00421d32dea7065b6763e64c83d0967f4c9524cbbfd1b2046efce3768c38a256 +28640 033a3913d538ab78f93ea05c525a1a417f2b0b95676bfb362ae24ac80ecdf5c8 8df9e63123047fdfe742e5394710189092eb7079b315446fe0341081ed9bbbcc 021c5de35b14d35fae0bce02583002de2a4f3dc8097c35b49090739655c06cad +28800 038d925c5b952c2354a20640eba22efdcdb3e60677172794ee59f212be3ef96d a06e9838eb105438c98e7801919aabdf3904fccb1f9db0b865ea630f659870a8 038e6a63901b12a3d1a6c22fae55e4eecc614357adfd66c9470d25d3b43ede2d +28960 02f8915877218c020eef44d313bd148c707758f38168a976b1d5fa82ebce3591 e4554d7fe93a64f5bb3fc018de76e97feff750e059205a1a9fa365a8be1f4666 0460374551ead124ec26d02a66fed008b2dcd8f48223dbb6c60234c9021c6b79 +29120 01463f047e3ea8fdf9691bd79b0201d29271be7b7822e0d86468795d31acca7e 6b755fc0b5c15aa9507580144b66c07871587c7612d1f18360f41beec5dd3241 0023e2354c0693f99d6f1db535bcd844ca7b02c446c93c3507640ab789783f1b +29280 00c0d8ec0f5deb12874fe89b4ad3b5c44391f2270a3587cebc0f438d09c5ac7f fc676bac2e5630ea305c5f78a0c41013b6949e609ab087a8fc7938eddeee98d9 0390eab1b12b6c5e746f3fee6659f6f6c74842efc09e86cd31170c3aa8f50815 +29440 02a08fe37b03bf5f96519c974f34aedb72a76a83570bf4deb0e291b405c56fa9 5fad129435dec7e878cf01bd949a4d6c86142edfcbe93c79d7ae5c120e3e4a7d 04aebb37dac296305b27619417dba405a78fe5b0b074c882ef19203d0e691f70 +29600 03d9efd5c18f975c826780c05a4eeaf94bfad07f56981a85c211c202b19dcd13 bf33089aedf8de6911ce063d73c04b048283d9755fddc528aa7f37ee3dce13b0 0182ea9cb2e0d3f24b4ecd84cc18bfb89c89e45ecd48a1cf8e2dc7c8cc46a4e3 +29760 00d68ad3d576ae57efb306e08831fea7c87f90cecff3b24f7a848bbbca69aba3 e7fa87d1bbdd228cf9b25d6ea7d5368b3749acaa4252d148d38f7d8211d30b91 0324f4f4042c65ba9af090dee19360b760ea963aaf97fac39f0c16fd60fc1b44 +29920 0340130f031f802840d2854f95f5813f7ef2e2b325caa452a25b786ca43d01ee 61877d6025fd6f445552253059f986b719c9552ee3accd1e7dd2e11b662aae2d 021554053d1f4a3670674cbd65dadb85eee57b4a384e489bf007b59596f02a1a +30080 05042e2dd609bed9e3871c39a529a30c2017c52122a61d02a67cf3e47f1dae8e bc9a883ee65eb2d618a9f95e81d9621338124b7b55b92f586ff9a62f5b5f0920 006adc57e654835baf2f4469f02a8beb44f77bf50e3b8ca79428fa85d748b908 +30240 016a46b99519f5ce0e1019d5b62a2b894546692591aa68235137e25e93b903a2 0a952ff075b60cbe76e0baa7e649ed6a000401d2c9afa6de2d7f345f26dec145 0100c48f43b7ffee2d9b6fb04298e93eedc28bcf850eb9e750b0e7b4cf9da104 +30400 02c3252885b9fd580c40cb5a15b224669021c302fc1dca1e46f439d05ca6236c 468f3a973ee674eae32d2f59dcc22886e8f11231146d639d299adbf10a544a27 027d794e347bedd458c65d059ab6cf4b9c6dee284ad4e66e6f939fabf7955cb4 +30560 031d71c338a0f7b804410c7022f5df931ec0f8b694ffb4e50b7ee31fa90ae948 cb7746127213c8d004115a2e4c18149f17d720c0da26137f199546b2771814d3 02581da16899e5b3e461e14cb2e79e805d2d2ccc08be3bc391e17169f9a7dd68 +30720 0025ae7310b42fb4ba48b5f55c2079fa2b9d65c1bbeed5ea118b1ab7f185683a e832f5125fb090d69ce6c5a4bb58ab1b620b32495fa2a3519e30305305416e49 0252361fad53f461fcd008ed63d198ec039780376eaf3b434991cb8410341bb7 +30880 032fc2503fde15c844acaea06462cead10cc9d53a8dda87101eaeebffd443208 c3eb56d80cf50dea035012cb945fd4d21b53ee7ee64091e1b30fbfb63270ca9e 01bd117c06e19c23a00d3a4f1daede29ff4f6d7bb7c557e74673ea0320e02270 +31040 03227b91c26d6c38440539e81dd20ac86f38990ca9b98a6be2bc2945c5905620 a7a4d3d6487fa952c2b9eb966274767b92be1b27649dfc75981740fec20b9e80 0186a1a7c7ec2f512e1e0cc6c3bd87076d6866afeda9c778a6cb9f49fa694a60 +31200 01c29cf9188adc2b50db68cf2b0e256926f9e73c74288e9049eddaeb040343b5 a1d9a42a5f4cc3448ea878e5b6f61023a78660b3f592acb05495e440c204df5c 0263178a6165df34895149b796a15da657798ce427de21dd2e1c89a7a281072d +31360 03e774c040edf6883bd5be3e492c903e60e2fcdff06aa35429f5e6e4d08a949a ea843c31408c2c97eeb44c416ec6e4990cfb060271542589b472a22149b05303 039a59f245ba1dc4627475530e40272afdbdf531714f831c319c1e687224fac3 +31520 01606bc231f1d161806d05b9930d9b3f2439c644690ebe79503dc45c01d32070 29f58791e67fde3f146540a53323458bb9e54ee7114a26480891c63c568ef611 00372936048d926934fba3aee0e2ce0bc0c9bf6e15bda22ecff4b2af4e0ec642 +31680 007ca67f6054242861e0a829248c631128a9784facacc8955309ff75f4eb029b 1132959ebc3d117a08c4a3eb33dc491c9b2774ee6fe1833e2329982aa5639b4d 003b81c3a5071f225608f1d835ef6e5e1164a1ec07f5f03cad12d9ef7cbae4d5 +31840 018fb6bb5f5bf36fd458b0a39f2acec22f0ce53afd10431400d1f5451b668940 2e89e2c771eaa84e12973bbbf5286a20c015094ee23b2c0a54c49c21ad39882a 0005b2efd7a5ce8b4f6f6e89474ae7756579ad01f6de496cddfbb8669b7da9c4 +32000 0309e4e7b1086229af2858b3b74ad3902c3308251935b44ce09d2d34f232d2c7 17ad06c626ee3ae417ff291480a328951aad8decdaac13cf5359bc3f4519f4f5 0296912fb8b34a5627232802f716d4d17699d54c3164f16f5dc146bea24f9e65 +32160 0191feda3e1881d126fe6696f15ee493fb5c7bde4cf3211b59d8a4a1f4dcee3f eaa926978dddb03a9ea8b82a4c210f0a4ec91e57951f9bcbe326de65cdbc15e4 01489b0ebb5127f346fe43ffc3adf7aa887ed61d75c7676541f316c32a7a71e8 +32320 00b72734dd1a30eefdb3103421042ebdbec208be3dbd678f010e17d8593dfbb5 3e8b23586e4f9fd497e6b6aa7339f32b13a45ddb7d6661186e04a5d9c801c6f1 02d28222fe3622c755b6d63b1bf5d4db3a4077266e511ce8558413a3c946bc39 +32480 005c1905f7b189b5cfbdcfcb183f3fcc9530c15751f73ba6bdf9361cccdd000b 05fcbc6ac91fe523eb514f7f7f760c3d547abe4a4df41c8e8215cb77e090d71a 00aa16f50ee285891db3ccac267506d2c6523d2b620b15e8eff223cddc504996 +32640 03872028c3426c975e1ff60f0c70a51c1e218facbcc826485c1bff5210d0bc0a 1ab14395311870b725fc3c628e9356b289a03488e92dc7c656c4eca88f5d893b 03c0f7fae952ed427a57d2ee31adaeb8e2de32faf3e6ab07844e3623df85c05f +32800 02847ffb6f37e2fd0e8dd75fa2e091dda21a480158f555fdc8fae1cf18934ed2 d9fd34893b5d44bcecb6b9cbdedc2339df6bde989575db9d904ddfd1e91f5a52 0215e6de6cee83e25b4616337b6d8f570488776b59e670a2a6e3777f04a55209 +32960 01b16969f64678d2d0d5928f847ba394708d2e389eb1330abbc5fc733b7e5b92 24ca6be911196400f7631845010b7c8b7406c7fed1bf36936d95d36e2dae59f4 00b29d02df3251b83c10d63a5cf5bd4de82cd702f78ceed6890009cfee8a247f +33120 008fc00c4595c4a833696bb7d2886433cbf508eb42de0d1d3a8b9f04a0a0c848 54a146d0cb9385e38c02bacc34853a021c98563c9539c0eb98c23dcfb69b64a9 02685130b629309643fd0a2d473970238a7a69c85f843a63ebfb8e44d992cbcb +33280 019adc73b65a4d5a9a031518e7e3e3d49121d4a1b3a319f01be1768dac198d1c dbec734eea49e19af3326667ab37f50ee8029912df36f926059139f9718e4815 00c826688a1bbec0530283325ee41a743bd4adf12cb5d3022532eaf753a32f6a +33440 021b74c11727e93a2dea102cc1fd36c9f6290f5d991c1f80a4f67889d779f954 6d01895002233232096cfb2234d9e70871efcbc44d207e1766c2e0f72ec96a47 01cba77d7f36ab08a40c10a01eb90988dad193dde963351e82be14871c2339da +33600 049910b9f4460e19523c7794e869ec81ef6b5c74452b4584f660a067deefb1b8 ab5616db1e1ab25856d3279057cf9ff0c1c3390526d4a675e5f44212c8dca50c 03a87d36e60e81b5615a310aa798e727adc4eb28e58ff28e0b08818d7e6c0faf +33760 02239f8f20953a5614ce7b9b3718b3956ea14b8773b502356daa489d1e26b6d2 b8ecd15781a2ed11a1f6f651f962e2b526582c09fed83d2611d9b31a1358083c 049ca1457457514d86dc0bde50f514604221300b0c897ddf9f9c7da3be98bb35 +33920 04a0df3daf1695f7d266f7908ef64bbedcd6a52adf253b0e9873ad0c0d22bb33 3daafd0e4235d81cac91b1005e966311202a853dc4464ca76a9a5c22556edb18 026773cb0b5efd25e71cf5ba1cdb327019d56b00fce2283bd9c3a8ea86b1b3fc +34080 068a5d819b0f66b1118c2a260b9fbeacbf744beaf9ed3b2cd6d31ef7a7ab26f8 85f519b52dd1b300908f6ac3118cf696e408eb418b785a9bf5a803d3c47c4411 0454c67b451607386117c2d614991f63475577f542dd816ae4eba9d34e02e2ce +34240 058a90a86b681106186fa62f02731b9039bbff295d637d50988d6757b13f2df9 7015efc80c25e5aa5681e7d9f6fcee48b3e7d31dda1514e47b859d2c63270478 00572b309045077718ed7bf9008e6ee5f4a81b3caa3406bd7c214febc2907990 +34400 0398a5fc4ead1f4ca0e929a9a4c9f9b66f7b412af45f9c0f1b8d6d7962c808d9 3a3702ea50e3a939e987c587a4d469086535aaaf691edf8d3312e9553cabeb77 06247d5a768276794438877a13a0b2c534cad38b4eeb6a6b4f8179382f5cbe42 +34560 015aa74a183cefe883609340d4b9dcac9121bf7a8b5a5f9ff6fd5de5f3546b34 08ca386f35ec0ad54e1e2ddedd40e1fb584f9860bb8f10ea991672d9b33fc4b9 01eb8e3f0e9c364c9264f7f56a79969b5ca2c5329f7e7daff99bc4fc2926da9c +34720 043d6ceaced90bc759505fca8102c3b020dae207bf2da3833f6e1755240ce90d d23ac41c28b6f1b515f8a91b1728f11d25c743d095385e0325bc5b56eba2ca72 02672686e615c7ce9eb80f55a006c6fdb779eb0d38f7bf7536dd3724f7aeb5f4 +34880 030afdaee08b72d6b84f763cb0f4b1eb9c0c8a851118324e066b240e0dfcb00a 0640bbbebf374d17e47eeb379b96dedcfc6d326387a5f4ffb8de4c080b203790 016866ff158dc1ead7e2bab77574f94d815c486ed72cf113c068218a94fb1ac8 +35040 0264d19e0c7a27d43207606755a08725fa34452d721d134f4a124f0a92ee03ba 99f9a7e036d4a93894e6308894d682c34cac6da3f0351391455b4f29cbee599d 019ea1b7a2331f072967bb0e5c6ddedee69a6770c442681b6a7d75d9c731933f +35200 04558858e6e087a432f93541ef27bd3945b808d5a19cffb9dcaa10429d5fb9c0 8b92315dfa203bfda29fd293bf7572b63cc738865f53733053c818903ff4e8a9 02ddeaa55601d78c1d19f1574877b7ffe1cbc66446f43e81a99221c1da985ed3 +35360 005aea6872da2ddc14c38a7b95827d4f9710001d4d7168a7ed46b49e54491284 aa47f4e197d8ffc93c95893e82ad8884c4635a9e27ec142e52186ac82f1fcab1 032f415545144a83eb71d6e2331733b1bf118b53389b320e36289104ee723aaf +35520 01402280b36287a22e937f61cff401d26f84635f93dfccc3040eb2e65bd1420f 4ec2aef77716948178fbac7e65780ba09dacbdef779fdfdc05ce64d1db214698 023cfab31da6fcf3d9b3f0db66fbfdadd56efbf7bc99d3bf7af3764412d4f3b0 +35680 00cc0a28a2bf1ee6562e297739d80ba331de250f6dc629dfefc2b6b79922c368 0caf04195ddb97bc7fed26d65b32c7ea84b0907fa9dda7be1ea44d6bcc40dcc2 02ad1890ac740641d53b6085db29bbc93d46181384ca7f904d113f393d6c8eab +35840 02470284bcc3c252d30d486aeb8b466817eb135d2e85b6e24e4d1538f5cf9a72 76a425b2e9c37d0cc10da57950e82105ab046108ee59e3a60a60868f22b27832 039c8ac34840c7c230a7fb2cf81db2c67aa746ab01a3bf3fd86d08d1fec6b2c7 +36000 017e0a93c6962abdb8faa373aea0b7d42fcd60bc50d87fcd4319697dcd208103 e25be926d22403d4e48a28262a03dc4230f51a4ea0505d26994963dbe2e343ef 023ef788419ca324ec3cc18e1c1a89f07c84f82d113050af384dc2065979e13e +36160 01177fef9209d4f0b761f9a2d2494badc910adc4868f5768a6bab237de300db2 e4e90bfa6dda224212267565dcd81f37ab5ad8da8c9e1fcc469d55b0dc91d44e 0106ec06dd52481f0f0c83501f24649f597e7c89b0e795dd20a712cddf9cfc72 +36320 0263b1b34b8ac6af44ab5f23977ba5349127b9a255c968fd8ec3b45b1b74bf02 291dbb517cdff69d50311d32f1130ceb576e753ecdf61e62be4f93a08c522c63 0109d6ca3999db905f0ed7994d922d6f2d6a4be8f59d3163dfbde8099d169229 +36480 02930db0f1802d5d66fb488faa3a2bab1dbd077d0ed72c40acd333ca848f8fc1 2a48670aeb0495c3a84eea169c6dd55dd6ca942569a861919ff69a6dd6a03e43 01941338197e5732735de7e420c8ad6d147de4f4ed75c92362c10e4e8ce2110d +36640 00a12f68f8310e3756f8dce1ac11ea5f76329a5ab6d2f4ed50c7476fd2c31638 9c8d83044ca01a2d177056258438c2d5539e05b32b2951d52fc8106de9ec72f0 00d245fd9b11bb5fbc82be76a36f4782179d1436de9215d62a9d77d88f596983 +36800 0284ae07cc501fff886bd0260b6f9c66074e1a5446ce3b6c92199823113588de bcea189b1b4f574799b6390b4b85675698b06660c6a5e3252106f2532844a0ae 00e5f568c3ccc96869020de3c4a50ff6af475a48579ca087e914a291fac4c81d +36960 030b53945703026fb1cc92d34bc3710f29c6d705e98a19c0eae6513306404502 ab66b3e58de02342618cfede2d97fd46b117ed6f52dc913900825d773c67c40a 00facf8ed3d061cdf511634f2c3d6615d92b49ab45789ffdc8d0ca11f38c555a +37120 00dc03b392f244a77f58e974bf3f8f6aec290d27e9fa2edd354b173637399932 bd4548515b3ad2e3673c1aff8c20234bed6e50210985c3398b635493b922eb99 0013e42e0e6a5ac3260a15dc925a4dd8bec436483f2ba1c9d223fdee7b2f3d8f +37280 0059cbd524fefa89ab486d493f21b1ad7615c04cc3957e1985059ae0973c59fa 7c75a288bf8a26ad558721b552accb92ef63680495be4ec6cc7cc487e6c0ee64 013de337d762512d82ed0d3b8d2cbe2cf552fe27a103b3b0835dbf603d0a5d4c +37440 01343ff48e8cba028ba24429c11638f983cce18d59d341e3cd907f1522ddcd76 d206c3e65be99d7e8d49a7710644b0b3a9bdb81e6c29b4e09577276c1421de4b 02a861cd4a81531919d5db9eb225d85f27f8bd0962b9f996feb17c4562ef1b29 +37600 003695362069d0c6b7a4f5fb029ffc0ed5cbec80a7973f9caa272eea6ae703d2 54057305dca6b3292b7fba314d34771727f63ad6788828f1e0abb3f293b0f8d2 0036ded73caf6fe4f6716f5f0c5940275ba7ff5ca3e4c5d6026c926db7051544 +37760 00740749570cbe066d0574f7eaca5e0274682f46825b10daa8e190c524a7dcd6 79cb0eb10dfce6a73f0a8eaac19e0ee5a67bad0ae4b16455d7d416875e6e43bb 0055893577c060a98f41a5d6c269338ff41a0b10a0675decf97dacda302b67e5 +37920 018e9d1013e43223e01a668d40084f5a1f318335e2e602912e781ebcd7c2df23 79efec6ca17f15c37e3f876a19aee51847a3029a65e49c06ba64992ac885b7b9 0005cdfe16ff435af79c562b79cf3eff97f6e7f43c65308289ecddcde63912e7 +38080 0284b04d5213485bcbeec5f22b79f36a386c05433c99a9dc964f14b974dbbf2d 53b139262f2c4fd91106f82194f3d5ca14e2367bf5b121b42e6f58fc24ada96a 0052c7c26b35a8741a09380ab22273f72cd6593dd19081f1884f253e314fe423 +38240 03defc9d6cef2926a20603b5f0d5c9824e81709bbdd2b476d0b60f3e2e201266 0b8c2305d0cc4d2dafc871f1c4c6ca7cc0c70847634080a1d15fcbb8a5cd73b2 0213a7ce2b70e6697eddadd7b5f3495452994df9b46ebc34bc4ff2ecbaea644e +38400 02910e010254578c8a63261afd719d4858e054d3545dcd3227d3eedb6d2087b5 a68dddd3ea91b3f4e1a3fc31fb389ca0976a2514f799d5793c0ad9855a819005 0144d628eb505a22eec017243bdc58fc287242d524bee6f6367352e67b4482ce +38560 018720cb124047d8c43ce08985c1955209486dbfe8f33e6b94ede75ac70c0c42 641d3b73e2bc58cfc655610fc705105c7ea8101c73360c7c0231eca9200d6df2 0159a5fd67130b1445663ca3e7d27bd8c328db985a5f8440b977a21fbec281f0 +38720 0072a0ef762b86840840c0a24307b3fbcf9db2aec7a64f2c7f2046d802c4e013 0eac93e556e870bf0ada9e217a6202dc0a7c72746d0793deb828f1566e703f88 03bdc416ae725ce68cee2d0a3cca55cf869140930611b5a11fbe247c9a8b251f +38880 036271e1d8de54d7d6230249fdcca9081a8fe64d8c8c702fa2fc815f4df571b0 6b29a080b6bb59b2a10ae644be74fbc79e7f1b535a9534c58cd0bd16c27b9c0b 019f59ad2d09f888c336e4988275b82a47138da95e168674b11a33e66b2e80cf +39040 03e3b4db7d24228c917e36f0114bb6c545da4b85caac8f243e75e6d721b44a3a 03b60b69f681dc0d7fed35157cad2eb1dc12b4787a8473132881027683d75f88 017aee752af65b9f5c69bc199add4a2e70620e12abae9ab19ef0604c984803c1 +39200 02a6d17d79ea8ee3f0181c5003f474cf8715529fd14bcac8cf1b758cd365d0ca 6d2e5d0e720e81893696e497c9ae5c1f7e40a235cba423116b0727eac6b73e29 00da989c4824f366a80240cd46ff3e0f669ed00b140af7e9ca4a28565514343b +39360 032915d91500937037989803245067fec1939eb8ce08f24a70fdfa7eb6de521f cda9da7e388014a257ee57e16ff1df7d8bfb9c0bf4a17488be15a7e64020a897 014ff882e7a3408c81fa3761a1f9e668d877d8cfd0523cb470239a1ec46b17ac +39520 00ab3ee711dead90502aabad84929ac7defbb06618ed6e40cb8cf79f4644035c 1da749a7c44b813446661a6befd661bec8e5735e9f94984db8d47a5cb3882b73 00aee93358875c8d254fffc0a9b5946887c71cf5ca9d8224277e7486be1a519e +39680 01368f5003035be94aa96269d199b90f9e2568da4163865a9848e5471d87926e 6dd00354b175cabdfd10a6ad8455f6df2463e38f8b767b23d3ada4acbeef9f62 021c6f06fa684921072c2979dc82ea6b5f0c0cd2c50135493e96d482f9f8ac16 +39840 015c4b8a4a729768b702d5423ed532978c70a31e04ef85f62e2dd7292f167073 0d4c6bf14da2695c7d33027917d931bc2587cd446b837dbf50e344bfff5dc0e0 0173026885475beb37639c703cd5cd478f3b6b8f46db52c32699b5a487db6147 +40000 00eafd9dfb1e5f1bf1cca0c49be628538900daf69b665464443d29c2c3b6a2fe 8e9d7d72d91daaa7a5e88031ecfcaddfc1b939ea5fe56dee6591cdb3e9637d6e 0270466d2700490b250acb53aa048c3ca9c269cab64cfb669063e08dc3f9a01d +40160 0167add9c93d2e03cf54979f6286efc69167032f4b855e999f3a93fe72cf6c62 b96e82221ba2f700c08d5c24c7f05fcbde10cb6924571e9da6ffa6f9e8255b30 03078d7ff1100e7567ec1621fa5672bd86e3226478dc14e9565d324c330f41f6 +40320 00b5dc507b7b3d628e40704a7391b73d4845946407cca28fceaa0b44140e0165 a0758ad9bc695e75389669ea1e397218265cd8177f5df9e972a4ef4a4c5ca19e 00fe2d119da78febad7a13bc368fb1746d3a9c3c0e55ab394d43c1c84fd9c1eb +40480 0340c93af4211d26b23ba536d5e8748a68cf3ecb4e785de3c8ace7a88b453525 239237ce5fcd4cb99d62f9b90b83cfc91d89083ffcf57d5d96ece5a6135d5da2 030a9876f5dde9bd390156add31665ddce895ad6bd1aa604c9a152bfeaabb338 +40640 00b4b3e2faa45915b044951281fc39cab29f44c73156f7885e28a6b9c0d1718e 13791b001152c2615c73827fd2a2abb81133b94e87bd6d9a59ab4dff932511c1 0009618fc77c380a048e738bcdbb51a11644356142758ec8ae89897384f034ab +40800 01317cad594fa14c6df0b4ad3464311e7716b665c5b1f8db9228e99bdef77135 a494a7711d1d2b4beff05073b306e03a1581ddccae99310ec7845c7e2f8f3557 00fd17ec8c7b77af569f4060938f20944b184151d521ed75063a4e7f452dfd35 +40960 03e5e027ab006362ea8bfa61279532ad4f825709f02f33dc9451365d1b2b2de0 82713b5745811fee8514f84e05c995ec9adab0c978f8c6292bf3e10b2b989048 00632b0da03a11eacd4f9450e5b51982d31e3a0b8aca98cce62eef3e0caade36 +41120 018a9c29578ab9a8258d22526a70c15606eb4448b5b9558cd869acbc9914a303 3b2ced769e02a4caefb3c31e9a048eb6a10a11f61495acd212072535d674948a 002caa5fc964fc27fd76cbb16a47a772088c21f3a50403a7545e7f9b082ce3b8 +41280 0081a7db7bf8b32bb4f7509e2d7a743369ad7956b661a9912e9077b0205026f7 a4475571154e82c2e91a022e89e854eeec8079a8e4123f84b75848b28edd0774 03350d4cdd32bbe81398750b4849a37e616e355f8814ea61c25f9d4809a298e4 +41440 03683948d1fd9259b494aeebca6af59e4ba24f1127cf274f1878ea70714afef2 22808633fd96dfb619acbc3c53daff3d1fa7ec324428ea3a3f96f78e367927a3 00196b6e9a12382314c2d1897aaad79ed75ef4b5f91f12eba6a57ca3780e0ae1 +41600 01fe6dd0f8b38804f101fa878b6ad4063986533c3b9ad8cae84a795afc2f9a98 41bef0cca4e46d4bc443fcc2398056d7ebebed5780765949417aa3c638cef603 0262df1ad434fd1c9113ff5e77577f0ea2bee16bc3b750492c12e26f398ea3de +41760 00c12aa839a02c9584179dd01c153b32c4b394e5034b57f6a6ad2afbd029af6b 596c6a83fadf04ff370e16bd50c88ac7e080cae9dc24cf509e4d976d20476db4 018a719e8948112f4e13053d87604fd37bb52f458d1cc6fc85964e5a743f86ab +41920 026a52897252188d80471d39783dc1354e8272d51d105ebe937c1b6bcb48a8b7 bffcc8b991710e47517836b695e8dd6001baf647c033ec7910ebae367c6e2004 01b35c95a0405641adfa9c4092fcbb405c4d74c5bbaf989b4fe22ff6846af04b +42080 0149aac964a3c7cd0ebf3def35ecb5253e877eec1a8c35690113354c5a6feb89 e4c185489bcd2c0de3b74e9f9121c4dafec3bbe094945331c5a4a30ab1733f8a 00c5de689885f3d36d6cbcc5bb6387ab51bec870aab36471459b6a22e3460134 +42240 022f21c3f5494734113e99d300dced5ccde3aa4a4d980451ca1788836f3749c9 54baf51214110d86f145d058b802857b9169bf7018f5d8c1d68f46df90283429 00f114f0c4a65808eadecc9e8a1def92db8ecda53a1a02d75fab35182353b684 +42400 01066583ed55eb1a6cdd5816fef4d5d00e66027291adec2bd560dfa8c66458b7 d9332de81c7c8e712bf8a82c28198b36afe30ed983db7f6b90c04d44fc266f41 03682cb643c60bce15617815b033b7da4f54c68a5babb6f131212ab81c8a3c10 +42560 038c026c9b0d68bf6172feaeba831b6998c4da4fa0ed4249a5e778db2a2002f3 a8879c085c757a01204cd88ea03f57bf3fbc0d8851d816cd484e363e48ef070b 0067b5a6eb286d2e7fd0dd2dd29b2edce1a467a94befbbb9ab6b0ae1b51c9ee6 +42720 03d1742b14eb14f400705d86c90d0eceacb8de23b810f19a7b3949a76310722e 720a8888cb1a7493e0f2e39fc786a6e751c494c126477403b6cb25c3b500c3b4 0348be8f724cb81038eb4db6c3d4cd7e232ccbd2efd1a98163d52fca4345cf01 +42880 036247d49845a0cf54ecdf90594dc9eaaa81ceaa0567680672645b8d2e441f6d 9c0303248c456796488f046fcefbf12dc113c26bd25fe06dd547a33b25229d59 00d34d51e2f216d1a74107929e4995963a308adfac40a9b31af9fa233ddbbaca +43040 02e706bf936b2ea4861dcc871b191c1b46a321b49c82f62671b0b6bf83ad2726 178a4e367c6b57202c067cd2e76821e03ee474c915e04337d9626904c432e849 00e14df9c8386940f02684acdcdb901223fc679d89ba83e3d99b507cbdd990a7 +43200 02b1693d8a2fdfe366813b86dc99af206fc15c9a8e2607f1b42001f3a2196269 560cf3a5bf5d13b93d87cfae8de46a3c347343a2b9553e465d7a2e92f9360f95 01bae7361361cb335307f0b1dc1af1061583adc7de82df53365dd03d25efbc78 +43360 027d83ae7f270a9e30a6043603b271fffcce21e4d6df9ea2a355ce10950cd8e5 2ccef25130fa6d3c4c4ca7cbf180ec30af9df46214e79073403281c003178bd0 0305ec34aea23ee38368604cea5ee267e25b9c54df4d857555e73b80a2a14967 +43520 00be4ca49fa77077222a0fed5435efaec0ee3120ed74d86582576cff339add87 9bddb9c46704444d1a83828f8fb3237e70587947e0ff23d8329bc9d6ac510b50 017bb311384eb56336389fb75833bf1f92177849e2022b66011dbce36582be71 +43680 01c652e593c46aa1260f35ffb272cd36229e0f19262363ca860aaef7f9f0d945 ae5d3bb7c67daf7767e5abd7fc98f99af837d9a4f85328c137e86606df57cf87 01defeea335f19a6e33a823152a6e61a82cfd419f60c672ed5bdc576281f3169 +43840 004c2a3a9fc2e1e75448b6a9af899d9dce7d396826cc06034783bc1af2107cba a04cd83622c2f46d4e652e312395821741e7e599ca60be2f2cb7fbae7daad9a2 009a1be556bec4a6a08811c052e4e96458e37971d7a5cec6297414efeb395e15 +44000 02b8cd99d6dca46dd925142e7ff2e7ecdf0df9be91b522a211ff7e6c77246048 7c5d344de9888aba3ccf8132c55fdbe43adc75c6ce01b8bb5c859cf909dd8e5b 02d81249a5e12713660141a25572ce2d30d99703db63a0e90c0c05fd81327247 +44160 008819a0c3df9f48589a404081d96a73188328a9f125ddee9641a690cfd2dd29 ccfcbc298e40216826bbb1ca06ce1ac4b8e4eb40d5f5748cd70a7f9052bf603c 011f1b9e98214803b81a44e651f69014f0a0780606b3609bd45b8adf485840d6 +44320 01c0c21f6970ba065323d0cb7c939e7b694b18bc4fc06f804f010e7e1ce2536b 177004b1b1404f0afbe40cc980dbb510b7f35bd4750452cca9c93048e3be54cd 0113446144984f3cba8a4f7fa7302a099bb545b0c04db619095371298fd5cf84 +44480 030cafbc7d82783cfbbc40069e364a4eee7c7fa28715f1d3614f6fbcaf510ea7 6ecca1777597c2316cc65327c4c015ac9058e65dfb2e2a8523ffec0fd4121b02 02ab404d72fc661daa1d684e6dd7059d56e267b98ccb2fb4a4edb2342de2df51 +44640 00d5f3221bd229eb0310dbb97d82ee597611f0c67057c1710a7c48b89d93f4e9 817fd3d5728513efe5953cf5332c7353cb003129f72d5ea2a9033445324ceb79 01415707c01606b0277697b6b443755c2262c63b3a71d8dd4b98b2f7f3d4e0c7 +44800 01eab8533f4335baede5a6b7d45c9a91f058e48a2b8b2281c9fbc8a66dbb5f51 e4bd7d540c91416ce2bc8157b3a4237595358160a8cb60ca270ca613a34afeaa 00126364192e96320c0acdce25d257249347fa57ea851b92daa1f8db30c3bdf4 +44960 028624b1f48fea57c0e7a2ee805f2c8c572d9346b6be5ccd200c3170a8fa3354 f8ce75a491a215002905bd40a9578968025c0ef0f167ff22ba69c5f30fa21252 02ff128f043d43b1fb6940a7cdfb7b62f819aa8aeeeecd165808679820ce2edf +45120 00f1d2a6e7305530487573a24637dbf204aeaa984341d965e7f772e26114c0f3 55235ffaa51442aae3b2ee38a2c6c4e1dc50b9d1c6cc03ab1e328f88cf7b3b75 00be23b7dc54d0f7c706a7454bd7883a15321ca1c8454ed68abff9138193b13d +45280 000b2b2c8f99f6f10fb20c64ec44c2c1a6e5392ecb12e3ea4030f34d7a02d661 eba008d3b49d4302b790589eb9d2ab0fdecef6d4ae51e3a921265bb5f27dfd23 0012dc5edf6877d4c640b178eaaafd74b796d82d2fee5b7114d3caee68082410 +45440 0004451b5d062f32658529a186840acb043134f966c0d08658f8dd8d8304a385 b47b4d4949ec52741d88db1bf72cab6d15fb271658d8b6e0822b241baf7677c3 00030d5fadce87a7650a1d3e4d14abcd93389007cc6b6ab486cb2a6f469c903e +45600 000456f0ed530368cf9e2f72f941ddd082712b6a25c92c93c7dc88485fa71b4c d20b55642db320351d1f4bdaa9d4c4862612d01241b4e05638eb2062ee63de8d 0005d938c6fc82a44bcbe2d6d859206f39a6336e49fb9e246e3321f1ea5e6771 +45760 0001edfb940745747c92c7fad33c86af47418a821760d4d490073940881106e1 bc827ed89d4a103c1bd3820e58c2db3e95f73edfd301d2792f00155c1c1d62bf 00016f3b1e6cb43944687b89622de445eb6e360f05bb67fe8ec4fbc8fb6f6d3f +45920 0006e61ced45206596f5381bb1cb677870393c43124df830a39c335e55541a2e 474486511d53d180ce6d90cec2cddace16cbb813a4a9b2a06f56c7a43146baf0 0002387482ed42603553d0e6f6b847548d0292e6c96229f84f3c3a567f7fa04c +46080 00032d6e5d2b8c4f3c594fc39e5b5e19b12d6fca6f1b0294246571beba780d85 fbe3bdf7a762a64a85ef34516d47b3cc5d43923c18eb3886f79e967be604ee3c 0000bc63f2c0ad8341008e1e2014da98d71124515fa2d0321b0dd31bc3a91e44 +46240 0000f55a4e087387c30d3f5d47ad01ff0a8cce2c49019f4a09dd3e491d4361bb 6fa76014c9bf983594030da4cb3835ec43bdce7aa5749d0fae68d9481977e0f0 0005b671315ac7d61ef835d10cca523a61bafa7deadd71e1e6667da56ba5093c +46400 00015f4ad6d62619a43719b80211ff4fad8bc2ddc0064d7833eceb8da8a09577 17b6539dbcc09e6ef56da539418f771bc8d6bc7205b08196c6cbf9abe5ee5d8e 00010dc99e44a7ae6686779b624a7c797ca71842daabd4b109f6c79b5d00d4b1 +46560 00026a97878becbac32eb9b70ad9ac475f6f6d2203be7ccb2979b7a55f59ef3d 3d181cd1a0b2292d90f7db448267ca2c2068fa0729018e094d1eaf054eb56830 00064cb7fc9aeba889b9b5c07ccdf896e09662319fa6a5d751c7a478e94b0b0d +46720 00031243f9ea37ea9d3ee0c0ce31b96cc8aaa716dd29c08d46ee18274b9af7ab 0c344e20901d6dd5907808737f9b09a506e884107e1a6f9eed34e8bb62d7cf9c 00012090e772578f74b149c21368720b2d5e87a54e61cebb82e56a17f0dcfa6f +46880 0005c68a54adffb223cc8befab34b7fc4750642af820effe2c4ae89a2862ef0e b05d2d9abf84f9f6c981c0a498ae95135405faad005435f278dc9b2b4d23026d 0000f2f65b9852b1eebd1e579c015588a639c13ed751817bda997b85427d027f +47040 00066cc9bc04aeaaa56129707e5b922e2e784c4deec8e784279b4f5c02c0adde 73b59cd73be4d38f5519b895a642293fcac06b63cd790decc2379c74809514e6 00071dee22a7b7beea1e30ef3d5e62d6eaf8f5def8e4b7b3d5f83c367d1999ae +47200 00022984459e2717248e5d5e5310887a6de9e98137b19d48703bf6a1516169e0 8be8813efb3ec69199568a3d2ae2643c86d32641abd17dc9849621835fa45ddd 0000b921f458a536cff2420cd4dab2b6fe7bedb87003649dc26e206e22f37427 +47360 00053760c014579192ad5395dea5ea570da44898e42f9601c1a4a79e226a4f6a 62e21014bfbbd0eb40847a17de1ada6a73fc25cae058d85d4aca73886330eacd 000160a08557e44dfacc8a755e40e4e3e1bd01e356fe2ff9e052dd866d5fe382 +47520 00008a11d933f570fa89761c2ae9fdbb2b3a444289a00e792e6b85bbf340a9a4 e3dd5997d3bd0424b0f2bde68bd63fe6195fc3ce84e44d9cd8d3880e53c0a6d5 0004af91afbb8353364eac41ca59672221cef017e2cc790e47ab5872c1e0ee4c +47680 000319ea66a3c1a73ead0690a6cc1490dfcf49356cd034107bf80d6c641b214f 70c5ae8d85bfed21d55ab9b9ba4690035b51bcc54b35d54e16661720e0954149 00065f1b8df95bdcb89fb25aed1b5ecbe5b01fb7d29e6805a1cbb260e9924527 +47840 0001918d0f04a6f4ed543effe757c56cee4e746db61dc6d5d3754302b07b609a 6c780760776bb693d092151be398293b32fea80cf93c85cac5560d5869315884 000751a79e7226c50efdf72747dc484f6bfc5122674870ca03f49a0df73da246 +48000 000c618ee79df1abaabe7126b46afb9153cab6b88e5b51ac6219a791d5db07d8 4a50714321c19e845896911b0a946d1df8406742f2040be8ff8a58deed8bfba4 000407c46e5a4a8263aae8e0ca83b265d83546aff00812109cc6627601ddc3b6 +48160 00082858efc6a89e9540f83b6db6a9af40e8d1ff12cbcc58112eaf7b6e0f245d 219e6448516dd050be8cbf0e4e33fc552a93a3b2e9bdef5bd20824370e48e01c 00073abe08a829a3f110b1d3dde36c711f3a97c37cd473f3f6253f6abfd103ce +48320 0001ac0bb90df69b762fba9cd07d42c9312ecc4ff62b0ec716f770aca9022aa3 9d486cbc49982e0ebc1068e13e7e72ecf1b95f77e9df6b6d9d6dc53ed804e877 0002a8e2242c31a4398fd2bad926746950569587e9f2862b636bf7c915b8bea7 +48480 00013d40c41ce4b713805d37ed26745d71fdc8ce54682401a17018a4239be612 ecaca467edbb4401a57a661b1da05999df81b7240cc02cb9c492a1e4cef06fc7 00025c4b7fa74aa4564b9b79d275711ae5ff243a407c60d1f01f665cea2b6099 +48640 00004116fe218376be89261365ec1ae17873938b44378a98cfad64937baebd70 75f9f7cc519f3e8ce5f51cabe54fa9c2f16aed4e24acd18b9f15be34d88b6894 0005e16db3ad257d034dc2d39c3e43257ff47b45ee401e1ef9f8da980b00794c +48800 0000dc1b2e9b0db5ebb54ed7633103d647e811a0ca88b462345ae1b393c12f3c 143b3015a20437c8c41fb8c66361adb2fc32c00d625600c55881fe63815551f7 0006792f39c3632a1b03a0b2704709e69aa28737482b6fbd1fbf9d08a4c7a6f7 +48960 00042ab1ace8fc021b75057e84673aa5f0b4969b74e0bc1a3a0b3e5d55f67d11 1a1419a3e96aa99641a87f6a25c476e1204b3a0e5ddb5757d7705511803e8b87 000310da9553eac4ffc1c0e6392c10245d64b32e7a2965f679028d4c95adda88 +49120 0006269ee9840d4b1cf21723532d6b2638993204a7f96d57eb26d89f04fcd938 0974fb2ffd165f5588cb210b1a5ef5f4c874624cfa59108bc72e8869c9a33841 0000d4dfc8638bd90de32e9f854e57ff1add53edfd381541d4877c1b13ecd040 +49280 00027883a1acd73434a15227cb5f4441842ec0d4af7cde41aacfde9cfa7352f9 a1cbffde59a7e7046554b9a2805245b4e10e30e1da6408c1bbe44589f6760d57 0000a5a24d6473bba25f105dd44f8458ead9b6a1d0e0ca2eff686ed2876dcfde +49440 00039ee5f5b479053876b3924805555fcf8eaebc2c7253eaaaa7a3aaa4963571 b25f5795752898c4804e30192b1f4924804555f9b8494405461614c614bd0c62 000141eb5264201595f2b398e5d35c11bb8d57591c6c57ea02d7d6d63f9b773a +49600 0008b4a612ef2ff63fc7f603d1ad5fc0b7e551f8aebb47248594c3b8fca0cc7f 3594b53422d1817333b80065c684c1360c19247fe4e303f0344fdbfa3ff2e619 000385dcb2a45fbeb2d3de488896dc7fa0965a196fd647b3298f08af3c79f5b7 +49760 0002e15570ddbe2eb7a2cc3e90edfe21fa4ff4cf48d882d0fdaf217b99948376 990b8698bd9f017506b530a7ee944d4f6f3b7f822829643565ac2a81b72de80c 00003f32bc614caf8490ecc585adb4c3d6d271cbd40b83a657c54503f3355869 +49920 0006363f5bc325809ec331977730ef690276ca8f24f751c4836892e178d57616 1667a2cb9eb7f03339315ff70f2e4683bdd4073d2edce5c6b63e5316cf638b7c 0002e330cb97379e4c6e14844e0f32e2601ea9853fda55d46f887ade9231a6ca +50080 000700ad623113d623a447e1980db4a63f74a97767dc46fc9542fc92f26171ae 4719972dce0b1cb1b7fdaadf29c79dc79bf4503e817013802d333eebc5781637 00003f7341c982083d4605cdcaf5048fb41727c31a76bdd6dafb97b56299abe6 +50240 000018465318cf88b0b6ee7322208a0e7db4a3c43e7f6dd8dbd8ab9661aa8628 38de9eb88177631eea7cc8fb59bb75ec12b80fff6edd8594d2eabe795a9d46b5 000596d42599ae191fb39c2b1806521a3ef88988c760db8d444f6ff6d8abebcc +50400 000674431ad37ab52b8db57fe62085cd012a94fb28d4aad1fe56b1030e31dbde c1b49614a9bf7c15b19a8b751f1b608e19793b360671c494d4cb81b8ef7a9ced 0000d725006b36541d67abfd0957ca3c075ec9740d6fd2332f1b5e9a7f168beb +50560 000763f495ce8f78ad568851007f86c0fb84baf47a9f4b6e773f36281a8d613d 044f5d380a0b3c22a86f88e1e44c06b6aee1be85ca4b5ca93e1558edcb9272b8 0006cef65636f84534358e7d0c2c5342409e6bd3a9c5ba5cb539fb60b00c18ea +50720 0006c6fd3eed8d6530640d0de1d50959582bbf42a995fa5cc311592fb89aab21 29dd724a44fef28994d3853d08cdabd824fd28e575f6a2e660025760d12975aa 00005327f0fb9d4016d2329540a2aeae37d0cb6ed97d27132fb7891f3b422b38 +50880 0001a3c0d67e00c7c36ce8f2391fb7ca7da5a6b34e5ae11c63b10ccc1eff4e13 313e89741bf3711be6e7773999b47ddb1e2cb5d33f91014cb83843a8afd3e813 0005112da3e6f8af775fc94b46df9232f4d7dfb274574bd0cb0c449217995291 +51040 0005099eb64619d88833407479de57bd9660dac407c3cfce4495bd140d725297 89a9fb59cffe14b35f14a31d6a9f73adfc4c848fd2bddeacbe317e8bb082c2d3 00015d7cc817be88dae1387036aa4497eed5f4a658c6e464c21d55aea9cc71a3 +51200 00053a6135b78350080a0008d8a457f3073a12329ffb59a3668a6df4da0c47f2 b08b58688ef141ff80d10298fa64d87d0ff24de226aecd29887336afe1851a1e 0002300f3c4810c27948b7e38d10d01cc36da05e7c51f3ae3fae506bbcd0fc74 +51360 000673c791910ce5007452e07ba67df58ea555b0ef01f9c00aa314431c3eb209 c5d206fb1f55fa51c5369ee2f7a891ad75a6cd718f7bffb4ce77cedb9da0c2f6 0000ccb835319cacd9accc02ea5aa83157f26bc3de798fa0c71055306be39ef2 +51520 0000352c4285a2e325d6de1668b8916f7cb75a8fb225b9d7fbd569df006efec4 7180f302dcf6508a318a538ae1d0463c877b80c6c189b565cecce73e40d36ee7 000364443364333c1dfeef979fed5d3e7317a32f008106085f48e5206b7753b9 +51680 000312dcf16b490ea0e5558116a3808287022fe2208717de779450085f7123bd ebdfff43f7ace7ac98be45019a8e4be5b4e5a62f3fd42ce2ead291c53d877f22 0003931495cb75dc0251f0229c5d9ce9cf59fd4f72f4c75620e06dac33bfccff +51840 0000be61d207c850ca1874d1ce9d63a008fb10b869ff87a2c2b418a4de19cf13 77881320c527332dcb5c61f44b59170cdfbbf7c3e6b7f9c67854815ca2128f5b 000256b1e05365f3317d0aa24fc829c6c990070004efeb721bd5f87f10c7fb86 +52000 0000f2e2518bda1fe8d103108bf4d90af67313ab9f9f3d4bbab10b61d1e1005e 84f0a189015328c29b02190b8e56394021dca6f1fd34b9b83ce666864fbd973f 00023f287426d61e23dcd772b5b302344cd4564216cebb5c84b2f4b4e951515b +52160 000636b1c8e9005c61f9283570a8bf473971e48a890ae94ba5425d2797d6ff8a 1aaa21af39b178a4abbe5d17eec0114f0c39c2944930ae4d426cd5c2ec27e52b 0004db3663091c90f4545c538d2559f906599ea4e65defd6d9bd204cedd9d8f8 +52320 00015c0b53e6efb70840dd62bc2ce3a8201132d521b567cdd27241ca9a6114a4 0acece5b1a0c1962e9017f18c1684c52b0a0a19a7bc9bf5089254f233f1c27c6 0004f6bb64b9fdeff2bea764534b45fd4817dc444d33f6f5fc417ea35dbc9c2e +52480 0000f24ba05b7e0c72821f2775e5a36939a12a0ea0b180674ad91f7f9f8d4718 dacb7d4d01eea48f6e56eb7c8b8d35ec4f14eea28ab3cc09cf542101da5ac52d 0003e1697948e6c1042a623f58d320a752b0bf33cc50f1a46d257e8029db5d98 +52640 00055935643c7f84783fb972d79b2d0466f3356883b7bf898597b6df7a6aeca7 49a72fe491af3bb752de977a3cbdddc5e1634d1af7ffdcc0d28457f7ed84a207 00003b7b183fb899f18da19e797d35f678e5a579e5afa9ce56e429e0845ba9b9 +52800 0002490145162ea8bfa3cb5299cae7462cbefdef2de1e9223ae8000310aaac62 d545fd7a66d6ffe13127e6835ce7a17466ea795d631111a5309f09d19b1ae7dc 00034890f9517b0b9c026782deab4e23dbc443cb3d180e6460cdbe99f81ee581 +52960 000505e71e9351adb0aaf1f9f444f19f83d57639e3f79317301a86800a963895 a2546e8c4516f891c4b399e7f315e159934c95c4f828ae83248d233d857f90aa 000287dda40d394e924c10a3bda28cfd9632a1d3c20d05a67503fb268efe141a +53120 0002f941e9926d0075f2a3e341ea2e5554a083d0a018bb65b334d4dcb9b2d3af dafc8c41064eb130d9a15346736185095fae66f215ed8872d8cdcf3501c243a3 0004910856cd1a4832c67c81378ca3bf522d853fec29cae7c27c78f01254d3c2 +53280 0005a01e41b2799f9b3f2c841051fabd043215bc50491fdd4df01caa633bb37f 2244db1f54a27cf6aa11331d2aa222330aa165004ec3b10edef5c057157eda76 0003348a3d95e1a5ad9f7432a9bac0b1dbd96ac0afbaa00b515d5a5a4dd6eba8 +53440 00010d17afe7c0613c2dfe14aa16e6329477f5493dd6f39811fd74ab33022c41 051f7a0955007ac94e739efdd521e3c375c7fcf99708188596f8a218d1f494ce 00003a7bd6ddc7cbadd8295443acb8fc5e10df736a1106bc4fbcca49a202e36a +53600 00023af82c4fcba1288230f7c99ffefe6e6ea5be9b83a14a4ed227b7475f968c 9420774927f9249f66b64f80cd42b067a62d2d5bb9638f16e9df035fa07d131a 0001ce0f75403f9c8ac76eead330fcada6e66d987bcd5513b3a85a8b466bd7f1 +53760 0005fb85fc4072fb9f9575e78966293ea76312e1752ad14d9f218db291bc0901 8589bfa11088b9892d7dc223441d26169b5b886a2edb74ab91b8c9635455dc03 0002039e1da22746b7e74d4c66e414e99a0def490f0529ebb77fcc8e2cdbecaa +53920 0003d3ab91d92c7ef8dbc381372fc66b7f4c5e843348ba9f931d1dae12018682 cd67dfdb727dcfc77826e6db10e7389fd7cd5e7d24ad32dbdf01e2b342b6746c 0004115d1e2080c45fc5b1b2a3b0f190c65311aef3ba1e1d841a9de940f74119 +54080 00059d72773748b3cc2e3725dec3183c0e3b93f615aac817a711d7cf23cec1ca 0e6b7042eea798ae439ae48b0b9992748033f9468fd25676e693286ed4df75c3 0004797be7b2add306a5ed798bf9b8e7e1a74c832afb9f53f904d22ffeb5bc34 +54240 0003ce62b0e182871ef27c4b45c5f50f86e4a0612698cfa37d1b73e772018a86 36defbddf6bb10c161aa3b2dcd25c89c144ee5bea4111c4009f87530b6e08a15 0005673b55f4f36f0287f546ea74d72de6491f45f4e821755787ca4e54bea5a9 +54400 0003a47ab75c70c8f0d3414a78580c6151a409179c43c55fe5a3ba2a3b7f74ff 9db53d1648f583e6e90aae9fe8eb4d2a0c88f752b8315a09966f1a197a2ee13f 0000aa82121c47e6e944b2634b9682e6cfb17f6f9e05b522368328fe3735394d +54560 000223b52d556fd47a586cf4401f86d7d4c1b38987c4548d27901332f39fd847 3b5168722d9e917a1e628001e72d0cc245933d3a49e4ece1f04fe4ec19b923e4 0005f9aa0137a342b2311d0b7158aaecd694062dcb76bb11514f37c15e80d302 +54720 000345a895ac9032e769e3c2e7e2e8de8bb0a2ddbcc7293da25c570a3739427f ebf1f75c85cf5f74f682eca51e52c176a46318989bc7eb05db8e009c537ffbf4 0000c0e17bd80c982dca744f44533fed850044c0e0bdc7625bac6395e5be0c34 +54880 0000bbfc0819bdb4ad294532f4798ef0432ee3681ddfabc6d74015e22aba9179 970bfc7e7920ee875c685ce1a7321b0ef40a76bcf475417ba8f6ded42a7ccff5 00047d8067a56173b95ec7f124bd1ac351c2c8ecd14213cf5bf368275c46096e +55040 0005491294c4c971b222a86be70f5c87d6664d0f98448da1197e8dc43c97301c 7f545a0e90f74f20b8c8ed24895de75f237a099194531f8439e7b245b98f37cb 0004fdbbe49d9188788b7915b7f5d6208db83f07977ab5ee7d6f858aebb52f4d +55200 000254f97c1629ce89293e374c736a071acea7aefca5b2f73624d89073a10c88 c32847d6724b313807fdb70ec2360cc0bb7a2b4e73fdcc0da0ee04187c0c5d2d 00054ec1a66b1d24b21bb698c6604e55e7303aa3ce91dd2adef9ae0bb058bbac +55360 00012b22c3fc39ee9769aecfc4fa69d4167f25239a548829f8d0ed2cc1ccf8f2 7f1a8ec55f79efcb6593b3bd7375edcb01561e039618cc5b9e725f7d452b5de1 0000a0b1416ec0919ed92533d5268b26272d3e1605abe222a67d9ed771a4c5e1 +55520 0002440c1b591a1759a6ab6d7dec8c0233cc34404bb5f9acb62610932d65f1f5 0f93764b3997e248bfc3ace024c22a8de7039e9664d1a6320f8a587a61853bde 000320eaa9b8b8f636135d621a22e1cb3d28c098777ec4c9e8d940f88db4662a +55680 00030e3382d9768a312ed6799d2e6a5eae9c43fd46c3e688eef4ef0eccf04d09 d9c65bb0d8579ab71f67c6d46652b5ea8bde7af7c0b375bfbe64d9979a19c2bb 00020a06e129ff70b042ccaf615fcc245cf5306d77c3cf4136a6ccdd889686b7 +55840 00051a8363dc7551d3ccb719a36b696c44c18bff53c1e69977f29b5537a78f93 e6fc095abe3a8c758d8db8603be7dc16dac018fdfc78c061b114c462b501ffa9 00020b8bca46954bf32178209a5e9d270927fe73ae56978733584bad0a4c7436 +56000 00052e63c20a35835adf929a7e8a0e75038b84c4b7b74e0a159a4c7c7231144d 847806ba822048e5d0457f9e608aea3df2e18392f5a30ad0ee835122fa169604 00040e5467ea61d4b8267692fbe9bfe504bec77ab42adf1d7a65286d2086d5e8 +56160 0004b47d95f80fafa38d51b2bc2dff4c0bc3a34302acfc8334d04f116dd8abba 6c9762ee1775ffca7afa2311f6c8127416f326f76d56f843bdf35a5b3ac2d9c8 0003001aeaf88b8b8a2582c96d2fa27140512018fa50e5d96a737ceb6d7e102a +56320 0002fe66597b1719ffc8ae336df49d30c267fd0d5e4eaaa6a3ffa9aeb993f035 b50d20658db75c03693d262e0cd042b6a5a6c9b25f2cbc0566d6f8b8c89d7840 00022a9089253c908f98588d5b2b12bc377f825f3c4a225b31e437126183a51d +56480 0003d887aff5e7d2f0448ee658c486ef5e2e160121e6feb8cc607dc119f85d2a 5d7257ee20469ce0562e3210b9f641161e759bda731a4d8e051449edf9d5e564 0000807d5bcbd1c86ad51827653e1f969f0ed110db0d70a350078b2838547c56 +56640 000103c65d73ecfdb9983dc6ff173e01f7b50ad24ca53a1baca740296a2e2274 c6391058dd82c957cad524f6288879e9d0af1c04ace51efbf4221e82c5328f64 00017ceadb045bb3b7cd0d5c8e58cddff2e8fffc8f06d52926ec5d1cbe817ee4 +56800 0003b7ed0ec8c7d69bf531f8503293267e881de70013bff16ac9645e3ef1765b 87f3a1df470b532d8731fcac0a45c518d0ae040032ea7becc3cb1de00696688a 00024c6bef5c46d517712327cc3ea38975c075f336f7cd0f7dec0939383d478b +56960 00009b9a5256bf13593fb87b6788ae131555adc3fee7dc7f760ed72dba494e23 2e5400b193c6f99bd8173b42b1034b77b3068088db6906152ea12c38eaac95cd 00026f54c1ee51c00106298dc106d0100228c4eba2fa203dbf2ff9d356ef2bb1 +57120 0003d04a2a4cc1dca13d1b34dddecf278eded8649d238b732dd7b7cf60cfa5f5 bd8542ead33cecf55e40ebeb986ad12d54b9676d2c8dc7911a127c6a8e3b10a3 00022b928ea10a68ae77663f4397733f03325420b73d7bdb97911ddc55671f5b +57280 0004a3e2f110df222fe378f75dfa94eb6592e5f22f8bfaba28237a9b08fa0908 d2d4bf96350651fa9c85a60474f9721a2542d323c2cd622c87fc416214774e09 00043d58780153e1e2843df4ae9e1d5e73ed0c97a845f95851020248223b6e8f +57440 0003a56cc286f64dac7ada6142e0d896614df1a8c52f3fb341d27fc1f48e99b7 582412e53fcc0e29c31b94f766cff6027056fac9f6ba1a8f8630a679d2804c3e 000142efd2f16287466d67c79cc83f1c75808b34e199fd410553cb5e0178d68c +57600 000154e9a5032031e1eb0acb799358e738ac8aadb6ee60bffa7e17b2a3b608f7 ab992c0f53e6a2a42fbd3a88b4fade44905d5f27be8c66029b5aaa23bec5ac81 00014ce8e04804f2eca278e90425f2cc0c519b97b18c5899f3d82ecc13c5ff11 +57760 0000e1fe0aa55eda14b9fe2e175c14d536562bd790042c998d76d8aed58ef781 44333a2ea315b46eb65fe63c9f91c7806b7754358c44779714904256cc203c59 0004b4ed9f136f8100ea31612c455ac7260e0123b7c6333d3bf45a88a71a5e87 +57920 000159f27c4716d8c0dc553a1c6e4f1d94a060530eb694c01785e7f6195a2ecf 52b5ef37dbf915bfc6f7e4d74fb7371f316f14a11ad5c5bd284222ff16c0b8c2 00068b9eaf6e354a8122f94d647814066b9f0fb24bb0ffce01f7519e73a2299d +58080 00059933e41d7175abf211e8b22fc15932e1e843d8fe9d55b5073d4badfe3acc a7bba6d4b8ce36a0cb380dc0091f4e1e62fd2558f47b7670b2a57cd6c5d35129 0004b32be8a88a99e17580806fbef3de4795f5af20121ce35d2518d32200244d +58240 0000845dc22c9e6fa1b461ccb858673f306b3aa42eb2fd4a9074db73d81e83f7 9a6d498c7300b74619560115fd85d947aca15956690f66eb903027253a0b3fe8 0000e4ef0e4d7a42b8e57e2bf9bfc9e9efbb5165e31e1294347f058ef58ca8ce +58400 000160fda6387fb719671dae873cf6c9add8fd293ba147888ea85b12a919ad91 838b14ba5caee08dd9adc18a57e8693167edb9ba1062ea8e1188bdb745497254 0001e45ba7f8368e11c808975021f7702e3ab47081be70529179f316485430c2 +58560 00042ccee6e399f413d20ce422d019c6ec67c89ec84988115f9dc5b597f2dbf9 99143801a1b61ca48a5d4b2781ae0be4d4df260da283c55a278789d25d8a3a55 00018b3ca379106d33c8c356bd04c0af179d37396b9bee89afbb1399d85d0dba +58720 000408fa1b5cd9eefffd06e3410e13722d02c502d357222141dd61f9bdd6c8ee db900148ade33a296c4984cef76aba80ac715968ed32bf7e70de6e71c5b2a60e 0003530763e660d741a0d3c4512e6512b4e4e8b37425c90c4f7765eb8755317b +58880 00015215f86d7b5b63edda1bbcc0cb20094f0d73a915c9f8ca1a59bbedf27d72 1b70c5cccdd02b68e38cc561e48c009cec7afb82d14c31ad56ab0012ba3ea6bd 000575fe1830aa08402e92deb4ff2c7e3eed5a5e81150f7d16f21bce6b534f8a +59040 00000a6f6ac75a5aa7a68768ef25beafba0d327bd6d108e743c1d0939107ed73 9f4a82ae1f578e9226d37fce92627de8f4d516c6d096b9fded2bdb210bb419c5 0004cc7cc08683776a10aeabefd509fa7f8ccd2269c29ce4ef70e3037578f22c +59200 0005116b389d041b12a5759c919b8fc1dd031cf380aece1bd7bed1dfdf43d411 f335ff327d4fdad7de1dcdf0fe8a09a09e8527d450c1680a87391518a198c8ef 0003a6b00f423c40945ea89c4fd1ea847375c91138b1fa6fbfe641fc8244797d +59360 00045e1d85e18bcb860f967fe8b18c21374a0b999d01ee1f630a65ca221f5f7e b0fca91ca47e3a2c51cc9ee381fec5e0a3708de015afd0de4730080d2030b211 0003912b2872f7efcb7282754406e6b1335308c6d443e4ca57303f1d87d76bad +59520 0004d9eb03ba7389f0cf0a89dd26828a6e01d9ae1a2c49999dbe0a69485f5b22 df6462445babdfc838e4979309505e7d96a9230892c09d80b896af2dbb394dba 0006aec99f7c7fe985d6a6142b3e7975d7f21426f730ebbaffd69085660047a3 +59680 000477a4bb54b2208a7e246fe3c55478dc2a7268020861b35f61c1f9e475439e 47200136184293ace78e8fbd8169940ebfae288c3ad9a982a338d960cff45ff5 0004b78f09d58523158106995911ac1775e7841e2ac5b911de44d9dd7e35369e +59840 0000bbc3f52411bf8a4307742d86886a80861c9228d7d256b75fbbad7cc39de9 481c27131785f73feef9fc1f88b1c27c3a577c03a4a7889c9a4fcf114fbb1d2f 0001a488dcb442487510fdd7c1eee220ac0d396560562c252467d373200fa9cb +60000 0000296fc15f8599b7c6561d0e0a96f24766135ed79107b603d6dd6e55142c0d 2ad972ed75b74a8d7b9aee96691556b4225bc761a2a678992633633b6281810f 00035a2ab6df9fb7a8962f41c881e84b6981ca51fc36703148c8fd2fa73f22ec +60160 000d07c9767e9d932dd354d7257c9b63be0210cec61c011dabf66964f5949e0b d39aad022ba8873cef9cf19c49f762655bcca955a995a2a0ad9f171a4443739e 0006ce6e45c8996175f766f848843dbb3ff1db4cebf4cfdf6e7e1ea0436b9e08 +60320 00028802065059b927e50e9f5ee28c35a1c6ddb7b7cc20000dd96bcf39b4594a a196ad99ae7dd188a163e87f806e6f5748bd37e89bb4a247826856eb3a69ecfb 00042083d93d6e17cc816fd9a22d0589d6bf2dcf369e9978816f0eb35f1213a7 +60480 000816fb1c27ed5600b128d6ddb6715249b686d7777a1b70692500f06c61e2e3 f48314a7d5cf2ddd28474ec7e54de8c902eac315f0b446c99b4bd719321d6aee 0004643db7098a7ef73ebe6cb702ae5511f8c0c3f2cdd7d98bc6e0962691f444 +60640 00088dc637c83d879e67ad5a6df8e2fc2e67addae5b5e63520476a50d3355e9c b6bf5122032549d229ceeb113b116e3c1ad24edb63bff973de70cc716507d81f 0003ffd8378c8f428c8f59351017427a8794641de5c28916a19badbbf7ab89dc +60800 00030a5244c6c943d2af251bd19b9f32f7aff875a9503490f305c34671d9b232 a8e08dc917f99d517aace7e2c490e4d847a0fbdb8a84a2ce7f46d5f5918ed6c6 00089dff5217df2630bec3dc5504af7a00f2fd6430be35aabda8a78d3c735192 +60960 000f4bee64072f0929eae6f0364df1af98e6c93061e027076e02ca9a1559dde1 b9d80a027b3de5ce55c85b2d95eac38f553c9b3ff898839c761d1bbc05964594 0009a1c4f39d559f5d6e7755de8fead899f0cee0089d0110d0a67aafbb6f9876 +61120 0008a862869e05ea538f6b8f52dff0bd693cf5e6b9bb1db2aac7d59dc41053ec e287d7f414bc7445623fa8c54a0e8fd3963f6bfc69bec3d6557a5509da21dac5 0004e6fdc31ba9bd6bc8fc5c75ee2222176d0245d2c9dffc9b324853c1147f55 +61280 00079bf9dc6daeb4bc092eacda4e45136ccbe7f51ef0ec3f201b71bb2abdd70d 16aab64f519ab88a0cdfd28a1784af12cadcc07f759ba7fb5fa11bddc15dea2a 000259c9bd9a0ee4782c442115dc97ac97ad8dc9fcd669e3d21c198150abefc3 +61440 00040d36afd3c35d994a79515d098fef4825d8758e56ad6934d04212ab596236 f3a23a5a65f61b1297d95a5acaef0a6ccca0bd71d32f193e884570f3cf1bbd03 000ccc0e6b1ae6fe237a5c565135b94908d2f52fc15c3e57acf32a1290b9a17f +61600 00079542126295d8aace14a9660dabd63dfd5e8c51801edc60741d2d95eb99c0 e84813f56b30b8c9216a326584c38e6b4a9ef1d5aa6527254be691ccf8501b90 0001075b3a764b7876ad7f502a278fd1923f70636815b96967d77111c3574e9b +61760 00041c96dbf417862633f67cf16329d624a8a8e043c9e02321734194cd29e3ca 7ade1caed0593678f3ce35cb87e7bee3830cc46abd0efb76a5d0f4b5a1dfe41b 0006c397a1d334d6fea020f9ab56228101fc157e032b6418fc67851c745ed6b8 +61920 000c38e9976c7bdf7a2dcf86973b66cac2ca28993eb6e404e1eed741213957bb 402c92a7dd33efe1c8f3c5efbee3243e66d2d1992533138c2f3635d9a42067d3 00006021a8e3ff1cfa7587fbe3b4f607e5914ad2ebb909a9113bb407093df076 +62080 0000eaf3a80968fc4592878f6feee5dc2e058a2a56eaafeae49c73faa449b560 d85109d1ea28e2fa0b92737a8777eff24bb3a184edf4a71faf06e28cd7598ac9 000758148bad3fdcb0e4364f4f50d1b766378fa47717c6c85f4507dc26875bf4 +62240 000725b3ade5460dabb7bc36d53edc278dc8c580bb0e929161302c3e721773a6 71cf130035c40327fa110dbf5f945461c9ba40bdadfc0d714f0752d623ffb7b2 000b112c2a8a3bcea82f39d1d834cc3bf07d30d413d8bc1b5717ad14b1b3e7e6 +62400 00083ff1c25ddf9622f99fe63f7a986e4ec90bdafa9e167acac2422aacb18406 9dca7147793fdb4698d3f9a90784e6fda8ccea56b086a361596a44e9659b119b 00095f8063898dbf182fa0209c453eb69ecee02fc8afd069deead2b347761b29 +62560 0002aa2804a5f5a7d0bd8cf308db375fda7aa0854a656954bd6b53a876de318e a56c45a0d87b952314aca729946a0cd3f9f2440ad34c10d8ee54906af34687d9 00042436d4aebff04b742aa2ad21559301f8622ee81a82ba4db025f68ffe04b7 +62720 0002104914fcb0e5cbcfdfe4b497c051ade7f5ef84c00316fa71d7b72460978d d42ffbaff17cc45bc961cb24fd2b2a9a772956ef3232e7f58e3d5ee37b9fb6e9 00011fe1ea257d0fe9ab5eb8c07c0098cb7c70d9f8321cf68d4be1f851dfa9e9 +62880 0002f889ea8504cc8f4f08ed106112a407aabf11dbfb72171fa0aa6232d78cb8 102d2c130570dce0b7a2d9c7db406a77b98701462aa8ed6f5bf506bca79f2b52 0000f06f03b41d20f617c252757ee55f2dbda0bb9085a38f513dad1cac2e3e9f +63040 0000d792a4ca462e11723533822d59856840826b433b97907427c42e2c8ad081 b7e45b0d6802753f6093b9c4876b331080215c5dbbe52720962584fdce5ae27f 0003d917cb3cceda82c2c069fbbfe2c6ec981e5d3377500357c185f7596e477a +63200 0000de8ace5a7c44b5f34e19805a038fb974a1cf0eef52c2ca13808f6a6b9b15 8a421fd45eeddb9daf66b468287899c7d5a0d6f8b6d0b07006b5875443928aea 0007d7aabb450d49843309053b3f45a40745760ccacc7bb005626e5bf1735f98 +63360 000af0902c01b41abb4d9eafecdb32195ff3052746c631aff2264772facc9651 4e514eb994b14a9233a495096e5b30a0d7042e11817bdb557c92a71989ae8dd5 00045a57c425313558d796e326a20dbde1819a5fe9bb863eea244f8fcbc93eed +63520 0005bfbbdb4742048707234084f57e29b4a0f9f7023eab99c5c1f7c4ab8b0d2e 550ae6c6043230e1653e1e24c87c73234f2a15898728899afd47aff2fa45ad5f 0007f9f4dc1446e970c5fc308203e1afaa6311c553470d5fa8a9a7bc77da4775 +63680 00024011e6c4f730f3e8f9519ad264a4bf8a0d02dbddc5c2e32a0b1dbe24a930 377ced04e4b2d371efbcc5b689905101fc7d62dcbe092cfc57fb667ef4399517 000633de4d2aa39c15d221a5ae08e938361688a4611e6b9bcadeb780b6c3a3dd +63840 000c1cb4a2307ef1ea3df01bc46d5e2e56e75768c692e31fcb22f9d2ebbdc522 17ba90821bc029d5529b3e65b902e5a31c723b833e8afded59768da334a1a874 000ca8e78fdf3939b0c9a1d1bc7d9d5459b2931a906d95adbefe8d1ebf9e9d68 +64000 000d2304529f93ba3948ee1edecf5c914acb493476cb3d6d8dedadd53b522b32 4e3fc927f5a4fd1f1027e9b8d3be3f3e731fc8194eb17ca0a71a3d8a91d62890 03a3568e8f90c90cd3b93b6da2fab6a2383ab4926c3c460071d3eef1d021b515 +64160 000749841b9894c1192611ef7266622585349b87ed0e4af1f6f4c82e0b8bee71 641ba5b27be0288ae9ee6ce0a56c65c4693e47993a14ccf643be0d3c16b202f0 00025b3c522b50bac5e9162ed91e171034521666e90428cd4138e672018a09ce +64320 00003abedc56f227a3183a09b2cc5fc6a18364c5f34020906ff9eb3edcb24424 2a54e85a0097805d4770b484802bf4a554ade51c411181f81bba897dc5b5bc82 00070f698916de9b660f7839393cebb47b4dfaae79c09cfba34cb61d834fdd93 +64480 000be1f9ebc509ffae7bd6531d5864230eab18412a71007d0936818140503239 a766815e0286becb8108d6976b18ff5d785f1f4c6c7d9d0a058497eaa025c143 0001c0521653bb4e71f239c943fa2d83f87488ae89d20a33623a572793a5c058 +64640 000054efb8b61b8dad993989c644d1a1ec37d3c34ba65697646ee0de77542ebc 713c103875ce561dab5f6f91d2b36a859f3ee1d48759dfacc4a3d0354140f778 00015aecfa7b86e574c42ad148abf467e9597bdc0395c5896fe916de1d37ac86 +64800 000802ce4cbc4f21f8108e5515c30ee80636f922fc3993c05355caa11abe96d9 47a4b9ff05094dc99aa2e401f9da8ca02f257cf8aaa2d33ba2e8ccb23653e647 00047ec5a35be8d89a879d7bf1862ea084e164257328eca755df90cedd602bca +64960 020a70d8f6e50b95aae82645fc395d1c40390843b6ab35b78dde2194656f6dcc cb70be4b1be00883aa5a593d2f91b5d77133cf2125e59a667a5363e70980d469 000053e2fa49441cb79c25df3724740dac60c5538ffe7507dd8861ae5c53502e +65120 0003c6ad3d1227cee85dfec96b9b6ae68e4829fb8d7b87b9dec14db0199f6702 55fc17af17f4e06b31b21766fc6015d5428fc3a8e6dee9b110714baa44845c3c 0003c99bc90a5ee0f63db6961a43eb879fa3fd63f7ca7682f5751f86d5611953 +65280 000261a447acbf2bc10434eec6d96f5dc7dc5858adf2ef96140c216408355a2a b30e1c3c2663d910113a00f3ab8eb0753d71633a067077e761c192ccbf78d0e8 09a28b0c25e8f9a4bcae5e02425ce11428faa7471ad44708a702115c6b44767a +65440 00012a0de9450fa5d4daf62a9e78a49c6dbd3e65e0efa139852451dff1704e35 315ad477649324955fb230c0476054be5ea33d7d7710c48e75fb7de28366d9b4 0003f9054e4faf92d63491600b750e0a7850572b7ffe2eb070127707c53bda30 +65600 0003fc7e369594c3869062c672f8393b5a878232bfa9c24b93fac11279e55acb c9621200b0b312794117abadb272c837308d4f8cf8ee79fa82b387151e04d7a5 00066ddb15e06b40a61895ae0d8dcbbb8dde3a5479c8d31cd662b865a92a465f +65760 0003b4f4bff47c1f3f8550c050cee807c1e10ac1740f54f2ac04b24a409bfc25 cb072afa9e2f642631f6a1b02592b89f3b26911c7f7a0f1f26074af69bc35d88 00047741e487b35b67de2dcca1faacf20b5f4e6e00e8e0d945f015be2c789784 +65920 00058a2625872af298d44c3e4b2081f40017a9eb180a90f1c0644d17fcf96bc7 01f7cd5555fc2a027ff7918c2752fe9304c71c25969ff0011007886bf7f31537 000488358f536ca1d91da11aca8e441f5766e5d07a6e1d97464831581b38831e +66080 000313d4eaf2ee0e3ee37a648d83b9fde55b173ad691978285da053545205de7 f83436efc0859e8fdb72c5455dd31c1f880f1f9734e9886d9e117ba62542934a 0001a7878b396315fafaa984fcc7a79217ab10a0dfebd1dcf234bd2a08678e77 +66240 00018ca6700f9c70522aafb5acd90d8e463491b2087a605af616887d18efdb57 5f59bd98da58f011ccfd489a6dcbc652d96f95dcac38550ce7a00300335c8730 00032001edf69f074250369db03c9b74419615347e40e6f54bf0de34422321dc +66400 000516eaae3667b927ca90705d6686b060c6d19c912399b7e7b3e5feb0425693 194cb19d2525327724414a75a8218844c7af68b614b2b9d4d7731b6c0388653b 0007dfa6f1979be14857312ad6f5fe5ac015c63b7265a02ed1798cef1e96a808 +66560 00073724fa81c81f8f72fdfa9c9e5bcdfefcd96d54f3c426310229058c228a23 43c5d105eccd119c21b61d43c5bf7842a7969aa17f20008ba3e8486f5f430e2d 0001819a257a0a176a61c06e71089fc79f2a334204a90ed525b81654c9bf21cb +66720 0000a27fd34a4aba396714288b2184a79e466430f4a5699aa73b42f89ecf8800 4c837ccdc318a26f5fc7bd8ab04f8bfdda3efcd45e8f190f5211582154cb0920 0030a95f0513109590050cebc3ab77dc4f8a0295f492633a60815b852b5bee62 +66880 000e11cf0fe2f173a9cf88f1de4531a583d839be85e8be6f3a68aae0263ee38d e3fc6c0aa49a15683db32c07043164ccd86d1fd7dddeb907707b44ed4818853a 000ee016157b57fc91e7e342bc6cc87b62cc7d568577267357086af48cc90bcd +67040 000b1af6b787c14c6693b39091fbbbfd4561257318b6980dd2a2ac952927abfd d3cb68a084634126ca98910af33388c5e7817436d3cd17ed75173330892d2702 001b4aad21d661e03d063d4be8986829bcb9ef1b4b2643c681d13dbf318a0bf5 +67200 0005778863dff36ca77d3e41af5fb2481bef23a0be0553b2747fff629cc14c1d ccbb3a2241a02fe99a623ad195e59cf1bb103ec9c655ddb2230ec5a1e64e046c 0001a7c72f3666ce3a5d35f48adb8f76b1e2c1509bf55512a49e31791e4031ef +67360 000b73f15ded6f4358d972a04ce215c3eb7c7dc11c77e6904877e47a5338f178 8aaa581ae8cb9ea6525285cbed05a06bcec76df2ebdf4bb12ee1f4e4d722df72 00108992a95d0abd821914b5160d3fa90d6a35856aea43193f15728f13a7fbc3 +67520 00097a64a483c794968ce454d08f842e3b3108a9ad4bfb17fd6d97a0bbbed98b 127f7ef9f48eb4d80cf750355fcaaf847d85427578b6b9e4b1725d68cac6ea79 00154c5ef79eae05b7164a6eb1eb8a2c28cc06c4f37ac2128cedc53dd32fbaba +67680 000976e62c8599b655627e39c014dc73297a769976d329ec885d2ec3a6051217 ee2ce0e8f99b5c970348c32a376d671c36bfae020e6fcccf629a882852de16ed 00011ace0f8879dbf1e36d4f2b30f4eceb4f51a42249235705c164750fb64ffd +67840 0006d4d5b3bfd70f48a5d7e2989ef848a6ea5ef3e7b4aa40136621687d88c0a0 e7b0b0b81ab52ea324a54975403bad74d89226fc4789edd96a4a57db81de5d55 0009b56ee192cbe728fdfe6689f6aac3de31a55711bc34ead46c004125a708d2 +68000 00032344029e1e4b82bbfee2997208fa0eed2c36937ab401e08d6a5ae7823304 1376d24963110202f7556688dc8bb8a84179ebdf69266a9831c4fb17e22de80b 0007bea88dc5c4b4642b76f63a2f3fccc61a8cce2004d27dce54b41d1413e1d1 +68160 000182b55e974a55bc7b894ad0f7644aef3f28c532043fd0b9599bdf0cba1ce8 68ba9ffc0510666e860abb4e4e0e79784f54c35f141a4114eaa96693986cd165 0000276a16a7fe3afc88b887e530270a5b27a1c3bf6857a64c7718cc7727e6c3 +68320 0101e6888fe76fe1a5327b7d609e1d613ebd5277b7daaacb302e74d46739c131 db05102ca4709241dfda399455bf482bd52ebe64b38126068a304309f276e3ac 0002dca50f780c654b4e2d0b55742e50ea3c353b2d0d5c0687ce45b93a765dae +68480 00041093f4b059e449ee74176405bacad69fb2fa7631425b4ba8a8bd96f9e0c2 1987d1292d053fa4c34d0c416bc43fbe0187fc1fa4558abb0fc93f88903a7de7 0003d22fc2ab75153ea3dd4885157c22dafd596b148d2492f71159e0ff9390c3 +68640 000232437b29546c325b5245070df40539fea53d9168db70e0c2954d999a608a 0e54d8dcb8488068b070d3102ab9bb3f9fb10a85938c961c9c7a7fc0cd739978 0004139a3eff8a67a99f2372eb45be53b0f1148a0f0a9c112fd592d92b6e7ecb +68800 00003516308f764cd4873319e6649fefe2f9fa8ed75ad7192b41b324464b4874 097178ccd805f3ece73c7594d7440b3dfaecaaa625da82f495159c5d9175fe92 000211d5fb0f005b37891d4dc7ae4e4dbb63edbabcb327e67e9c5ec94eee4bd2 +68960 0004d56d5cff14a09771c037c4d214fd80ca54a8a9abe277feaebddd5edf3254 d362cd1575381eb33fb6039a0e34956e67f997c5ea0c44b21a5a4186147cc678 070cfe0f47945d4df87e6cad3ab171f2be101355538e3b6ecb880be9cc317f32 +69120 00035110a7b59f0311fbde7f0a74a9f77eedd300767cb8007bc94703326ffd04 e79eead1562c7d2db0d4f4069945bdceeb5afb6828baeb1f3e3d0878c98bd289 00016001dab7bb9940c4d34658825dd03189925b8d9c0c68b2531ae8b13311bf +69280 000148791291d99f436197ac405b12cafafb8a12348b46d6ec053d57b1a9c038 75cb9b43684d667d4009a510fbd18b641e972a070322a0beda91b0ddda8089a7 00018f6d1bcc2c4d8e21182fae96f4e189b7ee9ae626224d042819c263add090 +69440 000096e7de18b6a4b6aa534530bf465c5afc5cd96e8514b06bc6a3fea9b63d5f 2bff84d7a7a65f5ab26ab6cc332fb390544ca69f21608a0dbb97f360686b69dc 02ae5abe39bcdb7fc1aed48cc5efb8dae0a9eeefab61549f3874e0d10bb7fd22 +69600 00065d5b21cb46d16648759cf0a132b282bea7cc9c8e301725bbe544e56dde7b 41591f848142a3d50d9770c63b56b0579cee9b32643a78846b50cbba48bba656 0001794813058b35e703275eba9f1853993af46038a27bcb337a68fdc03ea294 +69760 000225091e966a804a30b28f2cc77f4f13dd7d37a4a851f764a782df2d6acdf7 f64ca0b08efcc7ca06e9721730ad4812286e9581a671e38a9c570e6e2806e83e 000143566c80a6c27a27ecc0936b3081c98704b4a172291c277576afb9fb1e7b +69920 01a3722a3619ec8fc21697c7ab0c04ac6c1b3d1b7d3a94326eb8304befada5e3 38590443e92e1e56eb7265b9e085fd5ac057c23e197716e4cb31a7154e3f1a40 0004186d2ad234cec28a878771f74cfaa5e9a57717c21d22f208323d6995198b +70080 0014133abe28e2d29fa9e8b0d1c548707932a9974108fc98d31f3a81a65f02b2 5c333f97233bd4729ca83a8c1bf248605f9990804ffcf2260c00bbe8cc0b268f 001fa3268e6952292b05cf5afd024b30f6531bbc23a9a10891210ca83d08c575 +70240 000b06405776f080e9dd42ccbb7081faa0aa019548e1d16f7a97708750fcc6c4 41d82b2085ec34d2d4b896e59120d26c3a2e194e55ef946d92c6bfc57172c0d4 0006673e5cbe03b4fe1025de38b3dc10af5fd009cbe70d41bb6905d1087e4ad6 +70400 0003806c7290883d464083ad77b0efa2ff8ec9bd8aa56e0e56eea87f0b06cea2 9febc70b0c2dfb23e65ef0b58dd9436c03a8a8d232052c50b7c3b6bc51bc66b9 0000634e6e73a812e62727ec5442828c3d24a9d64250ba79558976e31118fde2 +70560 00082202385ee4ba2170c956987569b0a5c456a5d520c3500754c8674f331190 4fd02c270645df6c45f3448893b8bd83768735842de342371616d4920600fc63 00051e7ecd62f85c0332194cc7010598f4c9963ab6e300addf0e5fd435bdd346 +70720 00010c9312452e5a0ed2a9e8f5efdec4df461ac7008f35a4617decf7f7bd4532 d51b861e1fcfdbf0a78c9e3b34d7def2de5853c67608e606a6ebb7c9916ca1a3 0004a71304dbcb04f878290d2b0d0201c4acb0cc9903244f5a987ed3e2a7ce0a +70880 0000e67ad10c39f78ca6dd0723483a175cd59f9d0dedaa40ca9a86523043df5c 389161c18d4f3640a86b1fdf0a2698635b4aa759ea089616cf05a1cb2ae37b5b 0005dd10314826a940b0098ed065c345ecc7d65c877a2a2b3dd024400c5b52d5 +71040 00004605d151b84d9e2cf9e15630cabfb4d6c75753a526068a4d5c9d595aec35 d261d242fd318cb5eb9b6e8a8cb48f18a54390f766227aa05333f33d1d0391fb 0002be2d476b3cff315de6bdd4347d864bb0785b7682537f0babd74194103394 +71200 0954f00617d0083997680436cb984ca156c6d0be9683a3e93fe888b16dc89480 aa28ed776c1b0988e59a5e49a41c1f65752cb48e5ceba75faf1a68338a1fd828 00016809bfc713dfa43f2b6f9f21b0d6ba4264b07efc5848b3c5888a050b1d72 +71360 000255f07928c7afc2393f2fae446ea104fb267e21135000bef599219056ea89 e1b199e7a7bb06091d806156a88addef74e363e1fe4f48e975951b68cba13898 0001e7a21cff3653eabf298919a2c1b6f37b8da590ebef389a34bb697e63046e +71520 000416585d2ee07d22168a30e4a0c0abf097650e3371d20ea2430403a391e5eb f16add49c2d812853d35d58a6162f519c2423429a77a3e9eecabeee8bb8f3717 0001ce012046889e5d72b8042382f04222fb24e4abb26e2f53b17cafa1bd54f6 +71680 000372304115ef71627725d0c1236ab96d5e0ca2dec511a73e7318f61ea0680d f56372851aef531b4a35d1455411559d0ee70634d3e841cb490767f2ce053fd9 000764a07693a5f83d15aff31a9bc31905de8acf3fdd27d754d52463df8989cc +71840 0006d96b64d47fb28653e7df191e4e8031ee9f9c9fc42894c49fcc77cc30345c 0690e7a9dbc3a98d7c8c3d408644a7a4850c139ed44609fc6cc45f228646dbf7 0005b2651c4601707ae2245c763870adbc73cde0691bdf4bef3ccd725aa9b8e5 +72000 0000e2cf32b567ba0aac9be543965f4af40e10365897a5e96d9ab616d848eb37 79c88dd9a7614efce64766d1ebca074d2040fe4d3d61e9fd7d80d03fbc8d09d1 0004830cff005dba516cc7613c275a81387002fa1899417f8b3bffd47ec5a32a +72160 00021cfba910343af7e8695caf9a0b4300702ec5e9a5e0eb88580d1bba9c0bf3 2a730908adb046c617c3234872657d887a01f288e8548c78d99502a044ca0e21 0004a298acab8af3d1147a1bfbe2b88794500bbdcec6d8d81391f4634b6ec61b +72320 000a45052258d7636d08f7998803a1b0cad9c4a80fbf5ee9ca53c3bd78589b4d 17c3275be55ddb2e3f6391cd38fd3994ad913ff6fcc507b577c5d6357a3d8b41 00094b7ce5e7c2434660b1d55d3eea1fe273a6816a4c06d9ae7dc2621bc27ffc +72480 0002300522708691932e7946e59691c90119c95055857db6dc064cc800c3ae65 407145896e9dcf60bf484cdbc5cd8987504a1da74b610e77ec30224c8a67a577 0097055bfbf2258c9c7e45d8aa9b9fce68eec6adfef066363f569a5e6f0b6f19 +72640 00055349e2af6ee8a239a06ab32cce6ce497dcfe12a4b0961a7accdad748e219 668dacd68e1387d7b7afff994feed86968bec9ccd9f7194d7b65d58c2716de73 0004a9bc8084249bd619d54a24d8157b9c2ed71602194350859024540dbda6f5 +72800 0007641eb268b24a45d721a301b3656c60d855403010c74f56b02351297afe80 3809b14d022b52f22f18cfe33b813181802b395bb20a70d735a392293e444354 0004e42ee5f7850676e3fbfa1945477028bb3b0df5703de336848a6ffaf46e79 +72960 0004991388ab612cd4f9e3d704baecfc614b58ea41335f2ad4fdb85217be85b5 72239bdf8c3f2645e1043ed64044df53b37970ef9679ba4644c1d53e688ad81b 0003a46953e3f85fe685c7e14894ab3d5b1dfae82f1a14bdb50dbeb788b51966 +73120 0006da4333a1905dc073c98a93395a209965b02973f04da5ea78c7bc83f8e12a 704c75e879325bc7408bdff3b624f0dcab5c29428279cc9bf821c9e7967ac4d0 00037ca36bdbdc757b0861868ad5823cd8ca49bc6fefba0f9649b007615dfeb4 +73280 00042d80f090cd6d7a433edb27f87040de1dd8f3fe3a739ac98c7735d69be386 cf1e68a40147874010b3da6451bed25fe425f9a6a086bb8e639c1c04ef44526a 0007f1ad5ab0d3059a733a3a15ae68ad2e9bc6045663ed808150edd072d3698b +73440 0004699abc530bbc732242df90cf206856593fd02bd1c4cc3ad90316ccb89373 079822fe9eaaa278854010db24b8f888a312f718a07053bafa89a3835c209db6 000710894b1d26087b7bf6a7bd9b32d54d222cbdb20ca814bf3ac1b2a9e9ab88 +73600 0005ce14a9307bf8add51cf12d240b8eac7a734ee2705aa69fa12fcf0ad6c398 8c1be615166586fef0f1c3cf302d4d05834d262d305a3d48815f092af12c815c 0006e00b3068532cb0fb6aac8175120a2e71ab941bf63bbff894ac34de1850d0 +73760 00077a4d75c0dd89e9e737c544a085cdcba1dba013367015023f6e5364bc879a b5597c3f7fe0bd6369c36f0d019d9af9418638f524c05ffce97ad4a34462d254 000399f3709971b4a0cca2317da3317f5392a04d39b81ee05b6259977735193e +73920 000321dd0867b85624c7e11fd5b151bc91eb099c0a5322b3ce5bf0ffa7c86b10 b0b3319a86047c916883ab68028f6824c27da83ed188561e1f7527186363c903 058f7c6075258566e39f40dabb5ad56fd77f61753c0a3cd55049734a033e85f3 +74080 000d785385410bff72f5a6f8de101c88d9bbc3293b9b040238e24206901783ce 9f2bed35bcad285b874bfc56c2fff17f19107c6b5ee9b8eb938fe6488ae1abba 000bf6b7cfeca4ca04e5ce9f3a1fdf4d1c7615faa2fb83de20f152a5cd2c2743 +74240 000a063947ad4ae6f29c2b87013e985787ea9d1085f4b5b779f4a7cd6ca6bbef 0efe14485da69cb482fbbc034802aa48e73f2c99e3ab2c92754444ee97340869 000114fd61c29cc9665bf6470607347a110264b0e9106008204962dd47132ad9 +74400 0002c4b5df1cf6221e34b9381eb6ce8e9e1af0ae0c68dd5dd7f48e32d62a37cb e853e7cd25cbe7e5e102f66c4f69c7fbf17564d13b7c8b0d1c29b10fc5f41b6a 0015856dfd312491136e404e9bed011d2e253e59ad37e6a3059fcfc6ff045a0a +74560 00000a0c1a2c108ab1eb5c8991fa5c06feb6044829e92135f2863ef6e30e59fc 026cdec2f3fba8e2144b9ada127c5daf934267824c3d07f6f5fae141d2ed5d4d 0008a489f2b6adc6d23db6235f7b9517e3dd6a7f0d0340b65372c1243917a1a7 +74720 0009399cd4e135945a40427c99bf9b7b1fc814c5a565342fb365d4b9c2f8ee5a 035f599380c4c95cee4421c38dc12dc6c2051ddc0d8f998792b6018cabfde90a 0008c08fc816fc95a8e8630f73a049b5d8cf7a803abbe11520137dae75db949f +74880 0004fa4ebe21864026f28b7c90ace40490daadaa51946c42c976196a7b738db5 fd71b3e659a0b56490841c2390fce6d860946e703df0e921576fb02a08709949 0002cf7c843737e2e58b3343e8f183898a0cd7fd4cf0d5a3fe7534bc11dd1c36 +75040 0003e719dab4f0f6bf45f3a448b3a365ef2b951fc78772ba83ef987bb5a0bf96 5831d769f42eb421dc96f411083855222cba3dc0816237f7eef1cb40363c7540 00005036cfd9e07842a6727282cabd915bdcc3e52d199a3f5e0944db2fa236a9 +75200 000606fc929b3b4385df98af767c0d9ddff97a4438eba6ea597a611139ea6c48 5af22f244af736d78172e66527ba46aeb288a5a7f517cc2c260ec2122ed51fe8 0b689e656a03aade7002b65bd26176fc934ed0a0121a36dfad4f4259ef052d32 +75360 0001a6e1018f9ebfcee8ea7a42d7e2dd8505ac255e7bdd9039d0fc5cdc050aed 30209093efec55493cd80a89570cb6ace14fb4894936fd9a37c4af71daeaff13 000321928099dba191afc6b419395565bd543dccc0574f1c33ca07e8acca82e0 +75520 00037757150316d4145f4d6196c1d1e5e2b00f9ea61fa67f66afceccbd3f7308 b8bf1fae2164d1b3c3fc4972b85739dbc8fd50b29773ee1f81853a85483cc5ae 000314a3a0cf980e9bf2c788b59e8bbaa7e72014e0e7bb2359b9d38c59b428f0 +75680 000121e2f3b8f623906a4c7e84aef096a6e52b34e36296bd81289a1a8f3a33d6 73e21e1d432efc2be30cf3b33abd14589edb88d09550fb83e378db0d990c2ee5 0913bf1b0eff6711c4decf5d2a03526e7028bf6983fe2d8b6441ca972550d39c +75840 00034078fbee3ac3b49c9ee702c9c2cc83ff4647dc9d408291fe08275972679d eca0f4d93639550767aa7b03fef1f4477b5945cb3efbd7286c8003a442888a00 00034dd9c22b5e9d4f68d16719e8c0efd963944f7b1325dd64daeac9d915fc98 +76000 07532b3ed2fd0828e47830783302d9bb4b7c896d9125a05a97194fda5f9132ee 66c16a492faa2d03b80c72a353718bc1078b84e5a0b9359f765d90d4b9ea6ea6 000236dfe058e00e5843a80f203912839e06e10c35541b09e76debdb0263af8a +76160 00010f62094841b56f7d5245666243855e9a90cc49fbe75cabc0c7f372ffefb6 87e35793d98ccfdc21fa2f5db5fe57082011b4bdf50fd58af1e9fcfe6ecca551 017c6a9d73c6fccda6289d7f351a091ed87944aea8117f56d3e182b4761c31ff +76320 0005c41cca21b1c910a0fab283dd98ed1f21426530ba8da1ac6d600b29b9d645 1b8b4a88fb7985fb01e6a642d73f6550d1a711612fde20c65c9545eb638dc2e6 0007dcb0e7bf157ff83d3bcf269de4b610d982f0eff18cb3641001fffc85c796 +76480 0537b58c63057d716825fb340ae2b6447028347a7053fe166d3a5c7d1a00d897 437657ed87bd100cc7c7c02a3f8719354163bd0fe6d5f1e8c2b00628347aa1c3 00057965470f58228a20e00c14cec4d24ed71e82e7b1fd434dcc56f3282ac187 +76640 0001ceb438bfcbe45399aa6a18b312c5b09ba89fcba4c51cf879eacac34339d6 6847fb345d3fdb26e9107e1d5d444b6d98401f2b523751db2c7c490bc0e72455 00035ddd6c43dca575b696c93ef8cc549bdd97d74b74a2414d87ef392b5d83bd +76800 0003086402effac52d966540ab1804a0d2949b60a38a1fb7f51a8233daf1481d 08c8ce22043b020fc986e09edac211a48fc8d70a3659233f5c7a8f7a3e01c101 0c623596f838fdcb7dbe0bfc94200128e9c599ddfddde8fbd88e60d4898c88d6 +76960 0c437f647438071a512a09ad7c73546e88fc3ae491471f841632933f85a7dcef 256b5b6d5177dee7545df9d8376dcb688ebc880c465bbbf70ab8467595e5a3d2 092a3ff7f5ae0b794bd57224ca465edf629436aa278ce1cc672b6524b5efc8a1 +77120 0801de6409519cfb7262fb599599f9214eea06d165f9950c875305dabf706d0e e5017a7eb40926e57d91ccd9cff000b4c8de6ca0970108955f98e1e5b76c5233 0987f745be59485fb3d8d6a1ae882cca0bfa5c6b9af66ea1add196624433d8e1 +77280 067955b6ea22ca5ef516759aa7eb07dcae3358251fda3bf48c31d112f85120b9 386c4c5b50ef67f02674d6d135c95f3acfc06b14b8af888aa7ea99025f74b837 07ce4e5c989869e868b5866d1b330cd5fdf0890af49b3abd7a1a4ad09ba6ca27 +77440 000017dfbabac188e8d13fcf06bdb8ad02da380163ca73b66db8f18ac64e3f35 e4bcee080f3519b61f564ed0342a18aa23c6fd26e286a3853f3518bb5c1bddbe 04e8e5f0dfae7328c535b101a2ee22581af128e25ed9c7de5b470e2700ccb4cc +77600 08a5c954d2da35b47516ee64fef1972544e6fedcdb960ef32b125d4cf8e0ef84 c2918a42584c61857997da917e67236da13a319526eacb2506cabedb7c5b0726 0b483659b90c5b33d5a68c061daea116c56db1c043b723edd4472a0c335dd5ad +77760 0a5cba6f83546eb3977bbc9ce0f5db8438670784afe928d5c538a450cfcdbb0e 6c465039880ecd2ca6598201f5d1a1f482420aef3e52306cc4827086b9681621 024f5986988a587d5fa7058cab8d6d3af74b28af5b5ea8cbc8710b666035eacd +77920 0241b35132e9c78568569cdd96eebebd7a70518653124b98c98843b1b564ccb3 e0d43f4f65f4558a0fa45a25c62dbb58f48657fed3be1f28e7c712de2e698e5b 08101dd979de192a4d87d3b427f0bf0a5f9b721eac18f8c20c1e974b1d0002e5 +78080 0464bec4e36cb6f5db41bacbf6cc71fcc63e9d6c708282cfddd462a7aa1411d9 1a2f16b690cd25d2938e17e30639b2d85bb452bc3e85de9c8e75d42f3548206a 05b2e68188c1084df0a9eb693784d3dceae80027fcf978d37c5f2bd5ac36396b +78240 0d7972c59e23eedb808e7db33d61a81e67967dc73fd03fe15692f562eea2ea41 59b2ad055b49ed5abc02e5108d3aa78b43d821791a75178d1245b2037fc545f9 084bb88c85189662c28c0a15eb17df20a02cd10bfe404b9507961ccc634f395e +78400 0b4f8b17f31da41eeda3759876c83d21ff4c772d671b32781aa5b3beb8c18844 e024572f587a835739829d611a47214201de32c03733a395ba39e25665bd7d42 0c2d286932c012c90fff5af8160e839615dca766c71618635ac5a417837a11a5 +78560 0d4beb459654e01140b557e267d013f342ae43ea6e8c19f3e3d6ba744fb5bf1f 4c48fd217e3df23749bd2bac651b9557c3710b49035ddf67134b7941c34602e0 0896a834636ebe25e0396752404ee951089837082193db277522d8af25e70012 +78720 0d59c1d5e4383aa1e51db814c6ebe7eb46cadd4d25e1b192bb56f5b30639f07c 32b3feb4ccdd86cce9d6549368f0961a0518e74f9c7c8febbda990705d4108a3 08c4dd8ac8d567266e808074c6b6a091d84de25bc2f19619fe18038d350094bd +78880 06bf02dcb1b6e2d3124cc7099ed5c4dd99a56e409b180cd4c4ac2bc98b31a4c5 461beff310e0d3c7dafdbc47a94d9bf281ed40b97b8027753108081a9f76fba2 0c6cd23febb60f62abfb499a2c55a8253d1b645c9a10420863e083211d6ce3b1 +79040 016c0b592c426d03c7110052e24107754dbe8fe6feb3987c8090a23caf1cb723 40f04fc08b4d4542278035e841413532a7951011c07ec7a94d4f5374c1e45756 08c753a323d273ca2bcfb23325c22ed14ceb508db894ac1e3bbcc5712b034a84 +79200 0e5bea9bd6cce50a4209f8c1b9cce1993812ec8cf203412ab5fd29d536fae398 528117345d8535b340a61354cf7fef0ee597ec6d4577e6447486ef15e1e7eb52 08bd0d140f7955a5d1c85eaf0c109bca3ebcd1ee7c8745cd1d221a913637d4ad +79360 0b5949675673df94f8d447c10c825fe655ab83319ef5a700fe828f8dbd26acc7 06b623fa742f1fe460f8003f344aacceb1cc02964139a8774aed9889ca1c6cad 01d1f1259c7f46964eca65adca916c104fea0bae4133147aaabb1da49d81fcc6 +79520 07fd4b1f503fe1a4be49cada6d165276b72c230accac43adb98069966feb7005 42f8fc79eb71c039d674f92918b9a19ac7f21bfb9fa47de9ab53a5705ddbf0ce 0e2f083c2cf0743f1a2d2d207ab1b7f7b345fb215e76beb01083406e016d84b0 +79680 092457ecf4ffb3b9c2ee9e17fc3c3967110d989f77757d6df754cc43b412f01c 823cb64dc244fd9d6354338b27a7b51465719d114f4820c99733ee661c8c155d 0cd046faec7a68587a6c899e41b7c4e4bdbb9108566927598a4a6a320bf73dbe +79840 0aa61dab3fbaca2624bdad5e366b6cd1c4eaa24703863103391e21192f621d12 d140527346667865b73a7c50b94f5bd89dce3a0092c8e7a93f4ad0d57c852c36 02fc677e88bfca8015153c3080517fea904d9063fc660ababe5e945ece2dc6dc +80000 0af5f3f1caae4f08c74a82689731d1ef8e55107c06f9a996e251b8ecb96989ad f27ad68d961e99255331c52539e7f367dc89333fc03ab34b9b504a681768f33e 070fb2286627260dae0e09793c3adc2a7a7bf9138c55058dc5744b62a89b4903 +80160 0d5df331efd95beb229a84b42997570db002ac20815cd8b2faf0a44aeaacca09 a9691190c48629f083d45a886705b93ac73a2419e264f5beb4cb1c084660be04 0316ac5117facb8113aa16e084b9e1630ef50007da4e2258c8b5cae5c6fd6900 +80320 044e43f36d113e830d738cd1dec46cc61558f2d40d1de0a0d5e817ba2cd04e96 8c926cbc8c09e3c20371714f52f6fe149b71d63b26a45f631d77c8bb07ec0c46 0b32bd13f9ab26f69d837743477f326b008f69a825168a8a7e88b0bb6e8ce627 +80480 086f603be43fb7b03058e4e8551561f4cb32a0c14aca44703c683ce251943cc6 10bad46972515a60478953a775c2b0aeda3768108c0abd9f406b85639113ed57 051a96f802fea9cef3a9e14ea38bb92ec5db2cb4deb2442691478fc70a2bae32 +80640 0db36c8b6a6071ec17ca067ef91818c15ff08193cc6f795777939ac7bede7ed1 d928c6b01c8f97a0fbcfa1282ed939b5fa2bdef7690a563d9f2e65425cba1214 07887935b354a64d9e9b7fc03ea38eeb568a8fca11ba9a410e11f29bfe651c42 +80800 0e169dd4bc8c5f7a81087bf3a9f2582757a7dd0796c23849a997217d5b87ee95 fd69c80c871c679a81aea49efbcb955292bb2abb2e399dd13f78d6e1f294428f 09ac23f5aa7f8781129be992e8a178ba07922ca5a7abb56e34692d91330a68cc +80960 0362f258ffb3ae2b214ebc906fb068c95ffeb5d1470536bf4b78f96670e9f468 9cee57549789ffd55651f7e931bc7e6a4ef18241bc1f060a10c8371e482597a9 0b7b12b75dc33f7d02386c55036303a909b78bf77546910acf91c477f41cb924 +81120 02bde4c1fb7ee0ffc24e75ef0d31bb9213760713d6f295ffc23dfc6bf3ad297e 3ef78b76aa628750f49345782b8e2e3fce5c10bd8e5ffc14b3d6e78f998da3df 06b17332e6e1c26674dad0e53d5746d2fb5032fc14ae9a557980aa65d3d33ab2 +81280 03e7b390fe995a42406863bcda917547093e970f64b83efcac4904ad199612a1 f6b26acc55a436cf17439fd524f7c253e2abc7cdecdc1367080db734ba28178b 0e128c398339b19fe39447ef4fc3983108d75155c4c454ca57bf44d505545019 +81440 0000131209ca15ebdbdd1a9904fdc4dcdccf7066db16455656141463c7afcc0a d115a16e2d4e905ec157c4b536483367cb908fb27da09d6626336c2df9339d5f 0c71ef0f5b5e3c8fbd8ff72f43c9b12972806ee7e57e5fbb0e5bcca4eca85a26 +81600 027ac1c589be8fbc89da40b45fa273214bd1b11c27b0dd686d54ad9644f2ca0a d375fbb2158f0df7ee46ad8b5457c935aa5c3f6553a37aac19ca90a84cb15f1f 0326c353c3a3d7cf375b268c0a5f36a03f72cd944647977f024d3cc91459cdf5 +81760 000108a35e0b56f221ab2677c96db7e132acef90e3fbd5f8a935e04d90f6c295 ae9c805f58dd30880a0543c0abd2f30aa4f5f83f4a3c9df30f106af71c778ab2 0123a0fcc551a53168fe3b107af584e2c73200a08a34edd69851eeb9e4eb126e +81920 0427efaa44fba37863f97fd92a64cde21dd442ed3f4756586e55d81728021415 14607491d355c0ac589363449d47eaf574dd160ad3f67a319fd9468775a0f7ec 04b8f5229968e05b70f648ce6be0278838a72d4849c3e65859867930bfd87aa3 +82080 0001078c121b1877e90dfbe0dcfa4350a660336aad3937c52d3680ab07b7b89c 35d46711065fa7aa7b011512683a38dae3d3324fec1cadb5b3b43ba50bb46385 00057ddba94ffdeb276bb018efc41fd87def6cf2817a2d7b29df160acd75b2e3 +82240 0000f5bbd250fdff441d109866dfaeb67b611a3417d2330aaad060c24a4122fe f69dde8fc2c8d202ba119f8ca8636755c7525019338b938d9bf4ad3f473ae244 0000469a8786448a2fa0d4851b6d8e7e411ae64a78f6a345dc5e5b4dc50d8587 +82400 09d1b14517b2a8b0372c75fe52608f3c9d0dd0893e9485ab72e80d24d9dafaff a5e86cdf545ebe314bf21f24319cd51ae5088a951efa9d92278500a5b37a138c 00014411da487689e2cab91dada6e9be08e0b93c3daa7b383266dd8c9f701cce +82560 0691b2fb85ffd4326c91bbb7631888168fd83e91b50d241f33ea74a4fdb9ab05 c43c26c055547a63ff2871690a493eca1a7498940a4f1190c8722ec5175609be 0001124028092d4a09d81d6ae042dc70a156759eb6c8ce66035a87b53c8c0490 +82720 0bb06a6aa2a68debd1a655bb531e40e75f46ca0365b1afbfa53bdd36e9475c54 0d4ba0579e8f1a24fbc4189a7adc8935ded3647daaf6aabf091c1b0789805482 00004191444bf1aa0ef910a674aa036b578aa1f1882cd671eb5cda18e7da06f1 +82880 025a5bb1b6332889f52efee184e41914ba711a7934f76d6c9b19588ed55bb6ed a0eb1c6b26fd83e7ebe3e06394dd4394288b50af214fd3af2510b16ffd5e93c5 0000d8d9c6c8dce7b150f399c7b6ed6a72b139feb5b5d023c658560002ffa479 +83040 035feb900c6ed9c52500bc1af854db80d4d0a9c69294e89f3b4e794a416ca332 b083a890f0c3db97610a158a4e2f7bfd3ef838f5a98dfa538871e587b7313994 08a8408d2ff256cd0b6d5d718df2f18f48e7b7647e2489dfedad3d2dc621fb0f +83200 041e17ff2f3deafe5b9f30068b67bed4a5b99925f62513f412c093d8c44fd1f6 c4457c529f3d227f53f3715cd58f0745ed982e27181bf195bcf7fb273ee33816 0d4c061b175b2241fb1afb766cf4664538e70fa1977d72263dd6bb525fb693f1 +83360 00003a51ae7f95571d1bbc0460b5ef679367209d98f4ef29b748088d439b9b80 5e5130f085ecf5e87dd898a95ab4db6243f5fbefcc91c4670db0adacf78df416 00005f6cbc10ac2dae5a967fdae24fba0fa062c6f887de71b5b00efa2aea387d +83520 0d53735524db19c256b19ac3bf0fd7cc603b66a92f62a2efa1ea3c79e9a9ecc0 a3ef85702b495fa50da51c0a0cebc871eec5841af901cca8f280bac35a190468 0dff3518ee6a0216016ab2c73ec83c7c84ad65ee29fc18077f09e43bc7eb92fa +83680 060f8ac6555455460b35312ebaff62bda85e6489bb844077045efabf63e12b5e 2be84efe48d98f355b923ac8280027e2ca3f50dc4947c66d7b7a81d33f1a6b7a 00f23668b90001ab5b33e1db4337207e75c8d216a820369df0e28dd4732b03c2 +83840 0001f94ae9585f45c8f04015437b66b5d59d5b1ec5161d0a6b16d76f57c30f09 ebd763537fe2db71e4fe2e1f4837bf1eb9206c8fa6bbb5f14371a80fbcd07b61 020e8b4e5ffcb659c4a3bacc381eee81813d8cb51559b10b8c9d27dea9692213 +84000 0116f94e6aba7ac1e65fca0269908512078db3bbc2fff6932f05c4e2a338d657 db002bb8b6d3d2818949ae292ad1bb26e274fb751827ff65978fed1e48f20b95 00004b6043ccdc6c28696e6b66a6879aaf456f4d77d7635990c9546b18beaa55 +84160 02d2ee259c3c24db20ff03b73ad0d4ac1075633e0a14ff452485bf1d8069db18 f0aca8106ad09d5a4d6dfa1b4318a61a2539882c62fec16bc7ad7e1393a88715 0c9276b0c061a322e651d9e7de791161275bb642861d12cfcb0381ba2fd802cc +84320 0001f910153e1c8fed42879e71f5c9c2e701b4609b70b8731420ddaf34d9fb54 98887fb66b142423387550114ee3b24fcb313abd9841c8f9fc4df69516ddbcbd 0002615e44ba0763019c55cc4d3bbba17fbe089eeeb79c9c15083c0b92dc01d1 +84480 0000c23a68922a555166bb38ba55fa52ff3dc9f16a1452e064197422adf3f335 2dff8d4e05e6ef71ad5eddf347ae89e07a2dd77e1d49030e0e49994705f5c376 0554762ce9305f310fcb9f9994d06d1299f1ae2629bf3b0398ccd06b2f30e59b +84640 0000e8c20c0a038f2768d562fb528e8304c55cd69cf9c5bd0cad76f1e6da8349 ed819cd8798c9cf180edd17e3447047f2aeba39176e2f6419f4ad805600fc43e 00000df81bca5569162033ae46cf10dc49f7ecc80e186232810d93240350f1d5 +84800 0000be3d0c41899a4ccbe30a19b157efb05b1d0e3f7b347f8b92dacb9a064c0e 3dcd4c983a7901c762d48bc12c328276691d3562d7f4bfb06f4dd320198c9302 0b5a682c2ca3554d3f5065cd11a57b4fe7d252b2463b9f1045418de026bda95b +84960 0001589831a52a39f156a311a29552599194c008ece8442d43e8edaf7188d61f 721a98f1ad44b5559a6d82bcb0e0e5dd59a6493aaed75747fdba2f8ef1fe5e55 0000b2e4aee63cd869a0bb0220c8bc9294883ce76135467f8f67721d6daa1550 +85120 07eee9810467c4604a7657dc43eec30d8e50e8b3bed0f983c4b6356668e490fc 443e24b0462b9071386fa7e8b509a8721e88a0ab986d16e5dc2a43b29d27697f 016996d7b36f05dad09347471b5dc09a5ad09053403aea1d49febeb63f43441c +85280 0a50ce4f0f0c741db0c425de248533cb50587e2b87174b97dc783de69d8f8520 2e08dc305c94c96518f592e6d923020b15e8440478bc21c263af25b0c555e37c 0002548ccf741a28975c302f5e14a41ec281e65d8ee99af0769dbda78c4f27ba +85440 0001cb9dcdbf3766075647fb544f2c015739b30245c60132a5a4acafca7d6226 14f52f9a24e193d33fba9e0fb993f03393d73298a9695c22439405a76892405b 00020913488d05a3196e25db7cbdcd29e8bdc321fc80edfbb7c9c8e1ead4a59d +85600 0b69513af9c2e0e978712da24bfda97a755b4225885ed142045726825d0a3956 a3cbfd46984933d6f6f33be4a68b048febb43114198de62acf9515092c45edd6 00013ab67619dacff4c7d224c9a24e826b0ed820d539ebb839dfb53b8207f3fd +85760 020f42d80249536333e97652d613a3b9180089ec795d831a01146e7a45273e5e 7c06fc4297242bd06bf3513baa2cd62823260b71e534fb4fc91a89baee974709 000039299daee985efb589c1a2ce5e2af1f9ebfcf3b27cda8698bb61dbb7b1eb +85920 0f0456c8d6a5078ffb7af34034de1abc7ecfa912392484535574a55d8ef6597e 6d5deeaa24c3f47e132672f55c752f2a37d188a2a8a08c854ff86f641200f45c 0001978bc9e2d2cd5aa1a13fcd8e551546e54b3a507045089c9a277d6bf659ab +86080 00015be63abd43287d875694dfb9a33becb1d840e5f021b5641ff0d355d6a2a5 e8fcbd383d17f67c0b1007a2d44011c6640160f6fe4d1238ba37dd2092a9108d 0313603aefb8cd109e3a252d4da7b971106cbb0ce357906cf9ab458b56a7e947 +86240 06eee93f800d670918d601c7790a1769aa09940c9c9bc58290ab212192b2d0e8 4c30a462d9c33a41c2867888b577106cae7de457be635147c20d05a26eb95dc6 0ed436a2254edf07fc86ac03454502ac407a448861ef78c610669f533b32f0ab +86400 0c7dcaf6ed716083045a1606c8f4b1b8fabff33e8728a78bcbcb4a13dee867c8 8e089e86a5922a63a157a8d3cbd0515b2b94953458fa0fb655e8b4d3ced980b3 057effbb5c8d1ab497ab28fba9eefc00e6b6f5d69566083848a5fd2c05765e80 +86560 0b1d5a4c7b5e1fedef3f78224ed2564e8a200fc5c11dd1d1afb928e488a1fb6f 5b29e16b3d4d72ecc27d9f573164fc27cfd61262bba57168f570bc29a3887b85 00002948279c9ae0f24fcd3c6312af6409abf775b76e63d64abb435b8ab6d92b +86720 080a6f537e52269b1296e6cd7e403f737595230b928deb18b2f7d2f2177d97eb 6bc74e69119280c8a56e12a8563f5668f0b6d3e28fb1c88e94dbdaeffef5e3ae 08c96d5f1aa0de5bca9bc3cca26a931b3eda159d24d1e0e0a539f8c92df98c26 +86880 0e8a611f7e9db48dbfbaa097f72cbc9d1cd1e029380be8c2c7b5501b000618ab 837249babec5cb847a2be4b003fec5b94f08ca9ca617a08b36e4bff15b92df80 000105d9f655696098626b13c01dc030a9fcd57808486de7a50088c82ba4ca47 +87040 0000af1ea59a10b8cf00738d9ae8ddc6e83fc94e39475e7688b087cf5326109d ebf210da980a595b95499f1ce3ede6ab6af67f73b443c44e4bb06ec54846d9a6 028336f0c4c65aa6a06de1552b5a6753d0aaf833fe29683d85c35bc5ac44f050 +87200 05470c2042298278a1357e93c35d71019947dc4c102da7ef55832ec5a5477842 e9d7c85cfc8d8fd19aec73735aab372f598800009b4e67f0fc5efc26cd4fe408 06d0a99664313a13758fcd5b444fb7dc6e03caa9da887c454406c22902f581ec +87360 0b448accab47146241033a3295a5811f39e09b97c0730477cb5c2f6cf1249a3e aaef4c5739be49a85fdc4c46c2cd41762eadaa5c77066cbfe08456d7c059a782 0314b03c45c032247f19b7fa72234a286feaafd260294911385ec32793b290fd +87520 005927be5d0be75eb3cad58e363e061f90745bc6da2a20aa75eb494976814c9e dc55d35741c5714376bee1c5ca188b3b74f0285570c34ccdc2e043aa33087083 000155c20ab1064a9ae20e71d28149bdc12f6bd2c88f032efd1bb48647a38525 +87680 0000846cb88b698b6ce9f4cc4c3ea6b900c5e421e3bbe230c1d36dddedf5a49f 4cdbffc4e024383da03ce15b5ed3224b76574e739ac9db3485ae820ca8cb70ea 09a1897d3e7eaaf1c32d4f6ec3d43dac67e8fc7873d58657f75d5a62a0e60a23 +87840 010f3c3c802b5bf63cc106b472aa6b4970e011de38eff680ac9333026a37ba74 087f1d1813d93f57ef9791c509e013bcd2214dcfc9cd4f5d6ee631e9af854fb6 0000d2058fd888efab3bacf9fae990767b75ed23a1e3112024d67d8eb52e916e +88000 011bdc1c3618d5e4cff3726c9a37cb318729e9444294238ae64479427ad6ffc4 ec00f09747981d813a17d79fa51f6c9378443f59fb11dbef83e2a5913ec6c2f1 0a59c4abbb3fadf3ee1e5ab7db3794f04ea70c3ceb744b253289594d271a4dcf +88160 0d3512f6db1cdb7a40192c81d707f6aa1fd1df71f7ac1f817526a87559c539df 06ffe55146830c58cf26f503c7fbfe7f3df51bfb603e39fef381d3c1b12366e9 0a4bb65ef4c7d6d12b4803d1c7fa22eec27f165e1ccfb99c73c9765b105cdcb7 +88320 00003b4e2135fb29e50fe943852dec2c20e5967ef5818d82f2cd792667197953 180c58e9200d3fc593b91a8eb3b3722d6fa0639d9d978facf1db884bef763090 0810114825041200040e08dac2300ed31a9f163ba8fe3d62efa78812c44a014f +88480 0c8637e6bd41c6b9a7acfd03df301a878141108aab062882032e2cfb58fa4b2b f9c16a3c08fb98201999c9224f8648ac2f0f659dfeb725a4772a548b87b4af7b 083a6c08bb4a7d4612754e6ee2909a188c14af082881da32c497460ca7c4719d +88640 00018ad793b115164dfd931ec951c281316fb21575a69161a0f6e6b4d1c6351b 2b984162b23d9cb0a25cb30a71969f532b117ac624b90d90c06c2584b01215ee 0000ab8d39c5214059a8b935d853c2fe1062d33312c34b7e0babe4b5c1678dca +88800 065ca68200b66745270b1a02abae1fc358ecac6cf7b059793f6f2d081724186c 96555d3c26e0482550240af1aa8be909345d7409195236765469f55551e9a361 000017f77a8d68cd7d954bd276c2379d37b2217737357ec06bed323f47b1aaf6 +88960 0001aac330b649458023019fde10a6a1b14f2df56bfbf8781d155fc7fd0426cf ceaa21501dc518d0ce2ac7db742024d26088d88e11eededc02faea070f160461 020214b7a9a7b77d6c8ff3b65f6fdb29df55829b973b63e229ee908094912cde +89120 03cb2e04182359aa06861b6ae64fbaa575a4726c92116bfb8f3335891ed0c3c2 5f15946fa6c8eda90581a74e9e66f4c578c941ffc9b1f47ef48e85104058d7b9 0d6c71c4aa254edc362106699f8d7d288c820ce46c37bf80155518620da937ce +89280 08f13981bf9f575a4619b23fdb0341afc35888ed1749f3e707f3162568fb7fe8 e9f727f05e0de1cc8755592f68b2ffcb1993fef3c719ec8309d3a281a3091ec3 0ad3ca35d597b93f029f7b7316c642808515925b8027099799238f06b0851038 +89440 01d40468941527346320fe4114b8f94660943a3c46239ff5b8a69544af5e3ba8 23fe7523216a7d4e9e120a251e58fe0c5fa4ebdda83577ca1afd1b365fd68796 0ef22de6720e726c6c74b47e0187af57a1efccfa77c20194ead4052d0fa8201b +89600 070ffaa14b04350bf8ce07db0562c88e062f06c08292aa96d4d224abfb8957f4 ad4be39e1cd9adb925b5bca0a52d77689d9cd48de31651afa4624b3597a04eda 0888178c4f2cb50164ad0b8dafc78917399e91aee219810920ed3a7357cc1830 +89760 0dac485779404b42cca8d29a9f244ba5623e357b52f8e59ec17d57cd4064edd7 2b8976bae909b0e0eda65f47464c5a9a127dac05ef237eec343bf3ba9e9c19e2 00004148ac71e02b082a4b9da6b8ad234a15bf233e81e1b1bf5829e490c98b38 +89920 00816e3f0cef38519982b20b48f94fa04a1c9a897ff6c718e21cf887c065864f 90044bfb46612f094eb8d9f4d0c5bdec84d2a6698f512388b6b7f0edbf6ceb57 05e13eb1726de16cb6687610ead2214ed922577f99211d5b67f7bc0b7427813e +90080 036d85953bf6d9d7a6f50c326fe63c068f7abb2a71c49d734d6abb26314858a4 adb08d176229da3b5e1b96cca7657d20b3aee8202a70f9f9351f95484201caf7 000ce2098232f02c2fb90345174f03dda44ed4397e3ef8437057a11c5bb49816 +90240 025f1fcc4e1edc1c5244f92791506c53772127a89550e98594377b1fe312cb7d fc4ddc47c2b18e4df6132bda04c2bdd8a8a7b2151f6b284876afe7d5711dd3c7 0264805f2e0aa2a5afac0df37e3ef76fe064ad9be4d4a74551a788fbf8c1b1a6 +90400 0699251765189ca7009ef0bf16aeb15266b41cd984424a3614465d2964e8377f 8bf75eef3dbeea5ead0a0a4cbc021c8126be7db296465fe786160f6b0fd7adc6 07d1b432f9460ed5975b36780d2e1764814005c8948187a0e84526d4ce540df2 +90560 00009cc12a21d9a5102c32b4f89772d9267d685ba992c38e5d7c0ab41310475a 8a39a5eca69a5074b503f6200a83ece48454dc737c6868b58313b4c1cbe8cac1 0001656024882001bfdbbb82d1e378f51b3482c246a17410d2f74215013fa4a0 +90720 0e7468027ff4b6ed1e48fc91da870e192569241bb8cc9705a87646711cc14c94 d77fc2d26fb93038e23be0ac8ed54777a66744c0a8d0e14e54a7664ec6e9da94 0002f9f66abcc0457fdbc394ac6c09e222adfee29d424e89f49837261fad769b +90880 0002cece2abf97d9499a426b572ed0b2f88c0f4733576cecaad63aeecec27589 79d9f958b9361b5ec01db0acd26609140a5f7af4aed521057630c6a5f2efb587 0000149e26ab753a815b1d2debeb5c68c8d688419687bcb8fc0fd51747cd8488 +91040 0c161b97da34fdf8b52a69e2e8f94bc8a4a2f7bfb10a2c36f83b6dc092745e51 7a7aa5211121481160d42540b348996b91792f5505069258700564fbe980d686 02f3c727652461e29d0a72aa6aa5608b1327e345f64fb49fcef974ae2d80ad28 +91200 04847ddc7250b5874c95970a088d4c3150d83e23d3b8cd029f17e430344c4571 030bc1290583d5690ddcf2bedcf29d84ea6b74a8fa413fbaccedaf3be30125f0 070c1f1245c57052b460817523765a11dfc15b51d71e16c6d6486ca0421aed8a +91360 0b1bbd006d40afd3be1d2aa65c2650cd743570ddddcfc2b3a56380c30c583736 d2fc930971844cb0f542e2781ab8a2078dab7ddab39ce949a6b1250717cd1f7d 000124cd9f8adc7007232e7be5d58a91c8a38a7d7d530c8078e878ac4b89dc91 +91520 0e4b2563dfff62f5ddaaab9e57905b5bf26746bc38515f86f80423b0aae5ac48 212fbd87668d3a0df612742d010aa5bb908e01a5078e581ae7a35486d00e3bcd 0000924246ccaedfad375b3ad7d0f591a4594dd6d7edd0645bfce44c831ccebb +91680 0bc9c0307549c05eabda37ccd3f34aa1f165914efa5f2b3fb3f05ededfb97ef4 601a54eaa8c0c95dcfb5f17ec66c2d6761a4ab1cdddea96e639a116c0083c744 00011cbcfbf82149972708e438f1af0451abb9985ba73713c712f05436d25623 +91840 0002579d29336a8216ada3037dfdc06e2047a0d347496b55b5f8c9575ae1122d b1e63cd0afd377769e885dd599fc9dff9334250acec3758b410b83f1d39e15c5 0001ea230e8843d909664928f10593a9d46df9c7f5defcc5b2124865459affa5 +92000 0000519591dbb66950b618d71b04a1b3f5c75afc35d20c1bfd6584f27fd81f0f 374e3d74e53d46243be385868314b3c61ff6bf3feda624ccdfa8fd81571981bc 00007df34acba9fc0a4b65fe634640118f97324c6407d9f470a608ca0b4954e9 +92160 0b1fff83a004a8edb36d4b549215c5e3d838b11b88e5b7f89da53876343874af 4d27d148a45a8deda904b5ad7e788064213c01afae675240df35c33c8547ae2e 000208d78408fab4571ed52bdcb4b69baef6201e564f1746727c9c9dbbe501e0 +92320 0cf679e4817c825319f9dd19bd3c215db7d4600b668349903d86945789ac697f a5defe7f971ee869c6650f68a222bfef3c6aaf2dc1e51b77dd1eb9a765e7ec81 00002231a5cf029db7b01aca80e49b532e2c7dc5332fba8e29577e8945e7aa92 +92480 0688c15bcfb0328abbceed644927d40c594397c6cdc050169dbf3d0ee406aee8 22d5b6c2cc299156fa63a3b297f22f47953d35201e23f2c31e45e99592b1514e 0000f250655746700c22e6a46770f862e86e18aa0f4fe995128a96ef62c26b23 +92640 0ef7657d44eaf4ab88b478f96e7e3fffb718be5a70515ff0fd25c0070b466ae7 2e28e31f3f83952626c65653259a68d8d4f1d8253db847c9a8d31a28e2674392 06ee099dc49eaa43de14dab61324b347115aa15a28a5201015d72fc2cdbeb61a +92800 05e21b0cbd0fe9838e6090a3d8e1d728ae48a1cafc41b98ed13ea542c06d8881 aaa60438b53159fbc16c5c71653d0b531bcd4a67cfc102b3d56c338a19e6e4c7 00d44b31f64f111f1edf171c8808e76747b7567f7eb7f5364546916f0c5bc809 +92960 083e95a352183de84376f899a088de8f5513feecdd8b6b22e90bcd2749dadfee 3b681a3095866543de0498ad7f8177d1eb347fa41bb513a521cb75d517c04d28 04b9d54d957de1f8a58d6f4ee908f656155eda2f04f7d67668b244ef9ca42d21 +93120 081a1e97c2dcfb30a772b076bf8c2ebe4b2c178c58d007e7152c78223e661655 f98d50adb4fd44062daacd2f9e50d89e224b9ea1741a78a48aae4ef4ce8930ea 07e9d6a65970ed34bba9a2aadb7b5317380916e09b6ebbd697cc3c9a7ebc6c28 +93280 00001d04c0d53d62151ea29c408e5288efe601de6626178e85f131343a8493d2 f9e801c0acde07cb4f7eb040ff49de3ce2a7ccdb053861b84a1bffb4a1a0a747 00004de86f3f9badec6efc341320b645744621dbe9b4e8920813485bd8baee43 +93440 000185fb9f00b1b6450ae92bb2948578f9cc051dec7b069d153ff76e4bfebeda d23ebbeb2ff373dffd80c70e38925ed8e8e02a34b97e5f411fd7861f019a59d1 0dd871890618af826c2ddab010fae189acd233efdc66de6b4b42457e127a1094 +93600 0b7a194c44a766682973634b195f78a4db7ed13b440ef94cd394a90ae5207d75 617893029c78c34e25079d7d4681ddbdcad83cf6fd12ae6b1b0433655bbb8230 0000f3a5a6ee0ba48fb9e3035ddfb129e407424221b9198e97938098126beedb +93760 0000c23e1de3035048fbfdf8e88f78c38ec9e0bd03857268a0ffe7a167014196 ea0890991aac9be206ec38bb52f415452afbe4ca901175d37651b913c113314f 0000fa51bfe02b70b0c8066a4e5f0ba0ca4a05db69ef5f2ab8ed4d00047c3701 +93920 09444eeeefb92892961ba3896a410f2634cbeb8300c37d033a68063a1ba68137 243a53fe29180eca59fb4ebe8028c5b1303f17450d3a7a4b1f21e57b752a2d3e 023c436510c3fce20c30b3d139cb3f12570a65a0530516e373aed00ff4619019 +94080 00025c42431fffe9827c605b505c9743c9c8ade167c22e07100f1ed194174573 7b86ef353051c139309db17287f467b3a0895819dc1c70eb07904828f18d8a44 0da94277e299fa0756473f3eaf8f20e4ef3bdeda8c1fad7d1ec81fbbf3b619a5 +94240 02f4aabccdaf13971ee5177ec0e42a96a76ad1aa564530559d329a4f7a5474c8 a75bc08da5bdd9836b3ed67cbd897b3aa297fd95a2c505638d35127a6893d60e 060bdc19cebdde3b38024ddd0b94759eeeda9fbf6ee14c20925c0df373299b79 +94400 09dc235fc23c86eba378940bb58f70d7f7b8beaadfdf51e4b784e0c9a62820fe 99f887db7f9ebd57c1108e7117c0edb4631dcca74c1bb9d7d9d5b425d6dcf660 000252af5113d91bd229b0eb1f39d570d14a941e358b5c469e85981ddeda491c +94560 0a8f66af98492d7beba5052bdf814a7b73d2215ded3f29d7576e7836dc82a21d 82ed3c9707cd233e192a8f051472a9262e4e2e8ac4f4f792b55c47783e756412 04d8c02ffa37d077ad34733f814d3ee8db0599869e513b5b17fc9a0ee6690b60 +94720 0a742027388ebfbfeb13ffe833cd5c11f7bcfd5dd2c8d301428a2463ed829b3c c9e2e34e9bd2cf09c63b333ccd306b70fe3e240e15ad79a32cf0586bf2e257aa 0001e3ed348f9c4cbd090f2c57d47bba94503b5c55950c4f1177196da7e788de +94880 00034e56b139e8e6ca268966600e66fcf0a6c48bb4e0e57c0d06a40c9c3c268a cda14de42c3e3c48b93fc5fefe666acbeafaad355a0e43aa35d27fb37681dc88 0700e50f842e668d318b7def05480c63430ace9a37c8c0520970dc3f77592081 +95040 023fb5ecfbb6debffff603e37c1a954af531aebf5d856bb695bcac6908dd6668 9a7f87764e056d8b2d76581f24c68c7c2cda993a884189c87e4e496cfcdc59a1 0000a6399b17183b22c997da2254679168f749f59dd54c7e3ef1f1232d83e79c +95200 0276d217fcdcb17ea26da8674f9fad5d6bdf27ff6a4a784bd2f7c37184b04bbe f044c5494de655fa79985dfa4e267cd3c15f32bed011f484de7f1a1acba6963a 000223e612e9e42288bcdf350f0152e52186c613c01756a69de4923c64da0354 +95360 0ea10b5f5519743b6aa87652f2bb0b6ab6c4720db343d496969e61c804cd56ca 3483797929805fd0f0c452dc0658806fa1d60a97ff2bfae658b6496297ee0a1a 00001ab6eaa1ee0708b9b5882860e6a2689630b7e95e9905ed204c5f322586b9 +95520 0001445f4d72937bab66edf416ecb52aafaaad0c9b2914eca9f1ae7e9ddd5bf3 22623f400556856cdfb584a7f3aa388ad5c9dcd09b555344d26b67945fb5be88 0a255327acea6adf4e9c223de57c7b70041ca14aa6eebf56be29ea8cc2c4c82c +95680 000295184d04d2b7850484b7d9aff2f3d620910e45050054899811431654bd10 badb0d6e4bc43009b259373a0c20ebc793ee8374a192d0d9288476adba401c4b 00000c35215e3c9a94e04d4c8e5b02c56eca29289c6dde2282e83447bb587973 +95840 000198828f7919e292dabd3a4768c0dd2861aebe3ed8cdbd87c3590dea35d789 37a2457289efa5e042174f405aaf7d53b63b1d67d108c629d459bbdad3b46dfa 0b08eff104bbe5e7bb62eed7abc7f2edf3b54b7b3c405caac0e43678508ba02b +96000 0000f50ed536d69b2eb6a10e1174b45a8fe13e7f089da6ba7067eb5fdaa9e74c c602fa8f9e57a666e31384223ce9ecec1c59998731d19657d86d2641685e98cf 0001635e17d8b7e8340656282bbb95ac494bdb52bec6578307ee14a0c657adf9 +96160 00008c57efdb15544f96e9556acd8ea9860e953f98a417403c977907e71acf9f 14560804b96f076dfefc59fdad3770f6ce4d46e616efd0c14bb286a449a8425d 00040a5f0426fb5353b08d8fc6f0e4a148f9f62587475e1054f465917952969a +96320 036a9dd256c2834204401e25365e31faa02637bd7f55dde49debd452c49f652e 49c188d8225c34491a9bcbc2009e512d1c13a7f8ed6dafdcb02712c85656fcdf 0002148b1ba2c1c6278c14e7ab0fdd031a1d93241b93e50d6194ca8be42e1bcd +96480 000267f4880a0c05dfb9f638536243bfb46e7ab12d225c099e14d9bf2bcaf4b0 870f88dc4ce53d518205d3dd59ecaa940fc98ad68653af2cfdb941258e47a7d0 0b0664d1a82288ff7ea8c81b91975c1319daa51bf6ceef53eb1734cdbf568df5 +96640 040b4f5550ac75e2a0a2d383e79a6647a0646bed72eb3cb7e78a638e0c34e072 4c1416a054c490b0bd71a86e217d930316a44781896b4fd4555089f905bf685b 00011de4b2ac4933e0de9d829fa2bf27d368c7fe1b7df07642674a9ecb779df9 +96800 000062217181a441eda2e5c8298b1e78c24ede4d743772a5a8f21c32c1ef307a c8cd94ec304bcccb7aeb01178a860e06d37500138e25f4f257630b18443b1bdd 000146000f321f9e5cfd5dbffe6a75bd4e28a805dea8998947cac7d5725deff9 +96960 00011ad852b50fb336e569ea07db9578b9661cbb8f38678f0b2393857fd30d34 12f329d11f45a9e43376d5c5a705363be32641cb5c50da0b0156ed1b8dc7bb84 0002366a4333c8efa415359d3ffe4997a0d65eb31b30db86e66895839af2417b +97120 000228e509b265632dfd1a42751e5cdf275f92ac90db26519b137b676249e888 f24e2668830aa8a63ac513cd02a3efa9b68fa950bc1f8bef9f680b127c579306 0001d261c7534320a94a8be4b9030f1b795cf4c63d125a3c456ceb8ad92d91c4 +97280 0001d109ae9746f4a328ddc58a211f262df2f544f621f6af883db91c7154003d 267c67fe68ba4952e17298863df8073c2841bc945ffdff7f06ac6930a5afcb27 0e2fedff907f8558b40857842564a4972d92014c5898d248933a97e2f4ddd6a3 +97440 0000d9571c26842c28c954a29d7723aa03a46e60df7d1434e8d6117329372792 7a69ca6becdb891b98cea4a5fe2a05616c006714944477cf162a4f2f26bb4962 00000db0229baee07a95352b9985e1d6ddc4d03ca9ec4d15b1a217e8b72ca42b +97600 0dafca9e434cb895fae18507e0495095f0b2ac3e8e7b1225770af0d24abe2619 662bbfe04c5f21fb76e20d119f61161512f4437eec7ec5ea104b2a5f8882d27e 005b52f6c01ec81dea8da94a2400ebc4d7ccb027d49187ae07e649f00b1ed415 +97760 036c4af784897c9c59ddd3f512eba38f91fa0926f024aa062fea9ae1ce50f577 8fb8fc92adaebb08e382227dab5796b67485007694a35f6acc505ba649cf95f3 042d8c60d112d8f370026d0f4b141f2e17f19256efdc5d6e470f696b14001eee +97920 01e9e3b6efe523b8f707c5c35ad8101d66801826661d4b1da39145baff4337af 5503e60d13436e27db34d57cf3d4fc8e3b9be0846fd32bdadf12d9d76f27c06c 000116abfd9b2e1f61a436bdb8142ecf3b3ef2d229a0ba599c1419cfeb2de31d +98080 0001686a237d3ce05c5ac820bfe319d7a6a5848d4acddadd49b28b72f027a078 0607bce8de11e9c8dc9a91d2df61478533d444abe675f4ae664ba2314dfba3be 000001ffea46a09dacf61310ac44243ff20261a6d6878ccc2920788b614e471f +98240 0428ab9b78140069890d52ac5dd4cca3e593ac5ca4271e1e05dde791597c1a18 250650f422883c0b3672e64c3f085697d8180034cc0129d36ff93561076f6f25 0000296f1775821edec731908ae085e7f1aefbd1372ef01ff757109ee80193bc +98400 00d142d3b141b044b4efa3dbe76092a4688bca0511d3fb9a0d921d48177a3b5d 1f465ef181709e1584357b39e5000860a604e8fb3df8a9d3ecbfb906cd06f9b9 018fda3720480d371d84bc8012f1bdf8ddf325954224bf7a87279862ca8a000b +98560 0e05a25aae4da1dfcf05ce5b6382d9ba0eac6400c31273db37d91c3c9dd372de 7fcc114f3b73fbd11005251e67c4df688de7b7d3d19e5e026f268f1c07f959bb 0a1dd9bbd25cffb24673d3d3e59fd2cab8fc641e1fd282e8ebf7667dfa06b26c +98720 0e7fe1566aa3d19f31a57a4d32aff16f91912cf10e532992577bff97ea93332b 8128c22390c3739b4ea4c668f9a3e89fd841a5407d185e42e9493fc534c1e184 0a21a5b149bacaad9bfd836335e45b0f7fbfb1467c71ae1b7b2e0d2568986dce +98880 0c127b3640c32d38cfb11dbe1e722247d5af71c7646d668179dc77da5ee5b8f8 4ad000990b6a396a2f751759551f458a3dcec2f500a0361ffd3443cc2063f7eb 00012ac5ace71a1599bcacc7ca63466094d84291881af781b43c82a9306b4e68 +99040 00007bb0270418de740a6a9c0dda1425b5b2459134d48eae0e2d52c1cee2d597 c0ad109b139a9bb97e1bf065ec87e2f3153dfaba879969e8f9c7166336a0436d 00009078390c57974a4e670015ab9084e2e845b724dc0511eb1c5148d02f77fc +99200 0000060f1f9bee0688758fc53351893d5528d8464246d3a9d02314e083142567 c0beebbf697cd499940293088ec2aa0483f43a3e416cf49892ce9f25ddb281f3 0000e07512de06fed45a1da90a9c4914b63ea2bac40efcabc3c348a37cac225e +99360 01f28467082f7ecc18a86b72827cf52178752f00d46695e4b27fda69c4a519e7 56eac7b60353bd755202f28665e5028d58b7e9046065522fcfe1e141809cfe7b 0e6091a383d04d4f14c2e0742bfd310ba12f47629071b102dcfbb1ec99ba4f97 +99520 00007406fe49baa8c6ffe1268c4645d6641e5476e6d4a197b640514b82c9bf56 6523d1e1daa8296d9832a2b668f2658cfe034324856fdc1a6df9e81a59d23760 04f7b94d1fc84969df76a101f3634a99522ae3c68b5c78e70b96618468a6ccdb +99680 09e9600124bc6611b55186b1fff2a568d840bb8c4458a05c1aca3f784a73306e 0c14506b39b435946a9a13612d91f324ee0948efe4886a0977c6d4c1e663a2e4 0c19b92239cbbbaebe70a6922ebd725a91e12bb836439e21517e7398bd010f89 +99840 025d0e1cb50f59ce0fdc1ed30840db92ed9e084525d03c893db4f4e6553c3d2a 7edf61dfe29c4af107861d33550c8febdaa3eda05db4055756f8a0ceca27299f 0d08243bb5700d9ec821fd3229b7b3a992305c2ce6f801a9d34c42092274e810 +100000 0f02eb1f3a4b89df9909fec81a4bd7d023e32e24e1f5262d9fc2cc36a715be6f 3975ddb437dfaec13e4556e9d7beaddc77b7b6c034da5d7bfbb2884fa52331b4 0410be2e4246d4dc0f5cdb46aae8b88f2cff40a81e9d9814fbe8bb167ff2d4e8 +100160 00007c268ce0eba80d2574de0dd0a703d9fc12d69a61daf635cd8b090a92da2d dff5fc68150da0d9d580ea509ece8920506b7e9067f89ec83dd6631e6671af90 0001682f85479efe6f8d7721e8ee926ea8ab039aabb19f8443718fbcc04f18c4 +100320 00012b56d5cbee0dc67154fc26926a3d06d7131855097ca3d2cb592842a733d5 5b665eb7c95062cf02f51acf52a8164d050e22363a64615f7b27cc78a3827b7d 0002043345a250c3d6645b00b34562c4bd5c3c4510898d5af96028b132e65938 +100480 054c3a66d01698504ea391783b213a40e0993ba04d6bafc598c689459e9d809a 1bab2f79b97f89ca370074c99ff6b35031bb9b50a4aeeec8333dcb1c81055b76 0939b7c53548a5b2a5861124c786919b49614b5a1122c74387cc0e31c1257d8e +100640 000003e6b9a28cf9b75338501e540ea681ae133ba740900db931796fe952b4dd 05bced3ba7e1d01a7ee4eb0559ad1eff13a2b9b7a7a33579a645f32a3f4e3288 09d55c52e31fd2776a814d4870af9235827127e1455f6fdef7293a64f109f1ac +100800 000048f3425f72b9e56e206fca45ac2b16540813653d57f4eec365344d65ad20 d1077c703eb04926fd345a24241c215b4706d807a13429b1a13fb8a41f4530e4 000055b97535169c8f59ca5f45d62d31872ec8d924ff7576cc0757c2799b42fa +100960 00001d6cf092a6fe9b55fa79908dbf59a8f5ac6ce6b59d6e35c0a8cabe8246a9 f6af71d950371a0d96a47239fbd4d8f7aa434bacf1148c8fd05979e29784c4b4 0001b57b9b5d1fbc2244fd789732e76167ed06163e84f5fc1837d31169049df7 +101120 000109764bd6423c71cd932b9f6edcd5775df80d224f130c1d3851cfb2e077f6 fcebd4c6b05666b5f0dcac7c4212c7d28aa884a600040c6d09d70c2608bca81a 0000bddf8aabbbc8389c55a1535480d8db98a3a51161b861f8c651df7e9fc216 +101280 0073e051bf86e69c980a819a1e65d0482ae09ce9b2b15ff705c81b6965970512 bc41efb5c161cceab4e3d895e89a62768bfab6a5efb0e1a27f87bbe8185a0c53 09a11658f1a62e5c969a70c6a5c1d360584241e8f5af7aa3756c9a1c2ab16405 +101440 069495c6379cdd5c974ae2307fffaa245ab8e833f5a91748ead5f10f309b1b26 17278ce1634aa9e78da949d69b8f4793d8313e43cc23d3c05d020fd642340d71 0a31abe8040532b4e73982e430ba5fd2cc591e2707f2bdf2801b5ffa8122db25 +101600 0122685706e9c83f091ebdb091d2543af370c994e72731b2ee47165c31ec293c 69a907cf79037ebd4bfcf793559a94bd1ed452ddca167b94f2aa3c4be65061f7 071902d17075747165510f68ae65162407aae2bef8deef939da943ba68fd0b24 +101760 000036784b185d9f2c1a052a2a6e4888494c321321049a4c85bca7c26be788a0 03094dfcb43ec132417c545797d299622e6883c3b4ddae7320a635aef9eeb684 00009040133d920ec5bab8181beba255ce71916e872532abe51a255640fa3507 +101920 0cbfee7fbb2ebd297df89925567a0798cc79d0b2ab536a93599caf4e7a243c9e ff32a5c588e066f069f9581bb0107ade0fe427324df0cf28ab209022a2370ef5 0a2ff43325f476ef1048c2a32534ae8ff36555dec48401a8aef4f9d00b4775d1 +102080 00007cf4ef0443b973ee0f8f4cf4ca96bc166d117f4eb314e1e0fdb91998c19b 04f1a2f2d3029d87d5da297ca843798c0dd975ecabedbdd51ab748a94cc3ea06 0000758fe919c77bc3168835a0fd4150c2f26f2016b36f05bfba45cba30410ba +102240 07b1c1fc2696b03cb184cb42418abda8602963c3c11c113f7b9c8f5e90f22e80 cb62d06eb08c98434436f358074db80e9d70fdc4e9ac3d71a9b0597928d16626 04dec884a34328d1f84922b05433542510bb52f780b83ec7a0b4dc18a5922c13 +102400 00008340e01c58f2fb0972888a8c83e0af95bfcb6b21dfa4a2ae5b1f24f53052 5e3bbeb0db3f9070db6a9a36c3b528612081fd959e5eb504cd5cde9bf579008d 095f36cffaecc37c44bd326b64d37133f64be3e127fad06a0a63c15775d3e83c +102560 0cfb173aa718228cc557c812c4d369aff4db6493d71d4fb29994f96c04fac3f6 e3b2b9d3278f2c71433265f094a1c961d67d68b728a8e78e1f94fcbd68103268 00007640db52f9e3a53492ba01dfde667bdd4b12797eda47ed3d1814878c9c84 +102720 000033f2f4a250e547bdee6c035f90ef92cb6060735732a1fd196c08a1d76df1 970c44a0fb8094198d669ab5f14b28c0d1ad7aa6df1b662a4498627ba05e361b 0e12ae97c5c303484623156faa5c8b6b12da8e18f0293509b8040a5662564a6f +102880 051fa01a91491bc43747b77374629f1922b8de129dcc757e995c0f10e59c4581 aae490244e3c82b0f5a5806ba9bf6bc098798922606ad2aa138ed57c528bfce2 0edbbf3870e3e6889f8e9215f3a44f856e1dcd423788b7b5b80e66288483b99b +103040 06bade5f47fa0185d8e53d7844d91e3d61a9d3dd9b9a584879636a44a30cf851 c5678ae6becb04590784971157ccd7c3a7a7652d54cd62593176aac113a61328 00007935a42f7a456c8e4ea18fa4e5d144e9de0d1508aae407c8eb3d7608fb9b +103200 0000bfcbb454d4f6d2475c029ce9676b26c3643c58056381292fc8baaa3c26fe 3abd37a64877e144fd32a8ec08d78ab3b7c47640442873263527e93edd284f72 04bb5a4f955274f70a98bb1531b6f74086d1770230607b82146203efcfe92118 +103360 0d25884eb910dcd99db44fb35db1a98892ddd5029584cff4b7489aff61fb3d60 02d55fea5fab6d8c0410990733820df30f588cb1d24c92904156145c1d09cbf2 0723e57ff47504146c9edfb4ff748344873887cdee29737502affd48cfb63562 +103520 0000bee075befb52d437ce4d6d6a48e8fc892bc61902036b2b7cb47bcac0f9b1 029eb55a37c97971170eb8a17c3cb151b61a35a3d047b0e31685d14556d7a1d4 0bd3a9e67b3c5ece5820ba42338e19f418d5666434ee8fca940cee0efecc3498 +103680 0a8ed326ddcc931ea64f9e3f40ab6929fafdb5312e246bcf44c95d6f5b4f22b0 8dfddce9887f6c023d51a1bebef8b6b9dd535bc45956f9139c82a82f739040a8 00005dfab22c93b9e4523a6f9dd9384f5478e90c2c6d0d7b307633e9009ad705 +103840 0aa09442a37e5c1a5e68afb5e17dd5ec566a27577a84fcb35d604ab17b2d042a 5b15793e764811d4e8b824e886051085aec67faec8b779fe6c4df5042fd77aa9 0000a087e1e9c695d86e5bc8b62f4e68de4419740a5a0ef0a84eef85e3d88da4 +104000 01a1f0763b57164ba0254f7fe410f382119d776385b0c9c39a8718425be2fbf2 0a16fe70b478b82b8408653e699e616ae845a0b988fc58b2466518a908b3e039 00000c585803d899c85e2d15fe5a178d20ea468ddaa108d4e699735fc0003aa4 +104160 04028f602342dd8d13c4068950c32cd268c3116a7bd6a831cae76d0055141280 391d5883b44233369dcd23725ac27d4f30d445bb15a70575c19be77e95b6e820 0b77d6985ca54c46ba10b739db44cebdc491c07792b62c6238aa09fde32ffcfc +104320 00008b05a232ada4ab0a3df9d54032d6bf2390c54c186caeb689ee759ea6972c 8c03d1354d2ed9912d5073b1c953e53bd1442c01eb69fabc10db1b522e2f4391 0000b381bf95e520a2c9d58380ef576ceac9601ea0a0e4307406d0d6b5c53f16 +104480 0b1b74d205dd93f63c7d48294fd4795fe291c0dcb9b208b9763752e9a1a92976 53edcb427a842dbbe66eee26bc492cf11ef23c7073aeefdcb6a41431e7650ff0 08d0ce3f2630367dd7948670ce1ef7cc9be9bce03559328440325a3d6ef8ed08 +104640 019a0eb044caced2e47f063ae04431e316170b2ce56441e9547a7c5de1e54ca7 fd3d50ab1b062f9ebdcecfeeaad1837f6a440e6929abe9a56410fa4e86bc42a2 0000027ae530693423913f5dd99d0fcd2a4f59c1bd8688d9eff405e100278213 +104800 0cc7f4c8d67cec3bc4b3b481c75f1e47bdd5631da16c152464ec4b9366fb4bc5 6ec9a00f989794dac5ecabdad486870f9719b4b2bdfe32d2ba5688bc28ebb9c9 040ae1b6bebd6e0be702f4099ae56cf45ac5771b7af0d5c090d001a63c24d283 +104960 04790e6c064f5ffae8bc73d0dcd08cb18cd184c3a542f4bbe105605f68dd25bf fe00cad41223f21fd37abc05bb33ad46f92ccd036a6496c673206082312eedc7 02f8f661ad66cc0900eb2b6b7ff3d94cbf3c7ca4b49978429074d310657a3ef7 +105120 000024aa780cb3787d14209af9a844a5c802c6118a1af07081897cc431cf3228 c51389f57ec85e656aea5d3872afaa0bc16e59cd1ccea2e82825b77cf331888e 00bf5eaf54b2ed1c647aae8ec494327b8936d42d406077b5cef50c5157b7ba0c +105280 0000a5c41a8cbf7640d341db97aa1cd0ec8ddbdb30f71ae360ef81a5d9006c13 59d036c6be0c682d1754ab9d5b12c89568fab03ab0c42f59134c740f13ba2ae9 00009a751ad557a7f052fd062dbc5707014ccf2fa6c8d9165dce71458683a19f +105440 0d70e68ee6221f0fe52d813c88d87cda73f2b4417fbefb7778fb76021a9f57ab 2a2167d3157014f6e1c2f60c60ceb26b0811f693a9c2f8973aa1c92a47db9d2e 07ee2d6cd01ab68ff5ff3c91f88c4f0135b6cdc90b5c22f379f09fc96e15e452 +105600 0186da762803edb55805d9a6824692c920065fd21b16c7c4c58049cd4a40e6bf c84c894561be9ade8b78f0982278c91c70646f3c2e3cba988710402a18dfb711 06b011714cf5f62133af7f715681df05a6dcaf15506b0ae3e30e0dc17fb7dbe4 +105760 0743e35c636bed35927be0775099165568cad15140dae5ff1108e9956f68e18e 5f56f22797280615c2d5270cbbaa05a1b6121deb33d11bff0811367fc10dba6b 0d8db35b9c15885d1595944070b54d876e32f6836f6e6d298843146269c557b3 +105920 070457e6aa2124e3cd7999f30d1f75be479fcddae7216a48f37a8703313a6a28 627400c32e65d0812805c2287cacdc8f50500adaeb2e2e9855ce03cf3a0b929c 0000bbbd964d94f5e10b98877e7a65fe6092c0bc2042b3bd6040e1fd9d0080d9 +106080 0a8d89fafcd607d0cfaa8d09b6a5c83da0caa28803601939280aa8a66d9f445c f02a7d255b6a326f170acacbdbf61623f16ce5c053809e5fd33f522e1b6c8642 00000530ee26bdc92a4474c91d369e0763c3e9f68f466cd58e83d818699acfd1 +106240 0a9b1f71cafd6dbfdad593f8cb23b12ae3be22208ae8b5480e3c964421ffcd02 bc3fed2d37a03f0c0a9495dfade8dbcd5ab21de31ddc5b7f3c2f7e29093e2d1b 0000da310c257de62b09877d590e880123707346d6377ec8bcaa0be44322f91c +106400 0cb4f9ec39f412e1ebca8f37064de28def0e6ed17e5222c48cbd52f5b668e965 c7fb0cf49243dd483701e1e7488b7c9beff52bd94b884c73db4dac05d0a8bf3c 0565385b928c49f5721c7a3854e8d141bf7df8578b0a6d1d65139e936d4fa3ad +106560 00005b1e6b7f3b5ac5f1fdf7ad47ae4bf92b5423c38c5c761e1aeb601bec2d90 423e2c44f9a3bd1c43915dcd41e962ebd70e94f2fae4380d4e02d24454c13bc0 0000589718e784d96a34c5045c4b180234db869d3f8ad74a4e30c62634fcb20e +106720 0000cdea884adf86e38718d6d72a5be8e9e9678e2cb6a63c66de26b17768660b ec0aa818831be188eaa0924957bccb2af2b71a89ab516358531e41619b3a90b5 08463a71ab106713aafa8c797efcb73e53643560540bfeceb4441ec66bda3bea +106880 002ea73e6a6dd498865a7dd2f704cb98e2daeeda6a44de0707dccf66a1c8ec93 e3db759817286fcceb3decd19bc2ee1d41c2f652c4d60f50d33d6a46adaeff2f 04df651cc84b2e0a10f01e12315792e03e4d8d2e22aa428b9176346446a18b0f +107040 000085f13b44511153194ddb4ee9d818434358277798742b92ecd9f080f3eaee ef3beda8f9861f78ad7084d39cca54234743dd5555d8c701dd8e5566fb7a2563 07cbcabe646f74a3e78fb471963ba4ef608917bbb7e5ed385647b878cf17c328 +107200 04de0597a3464c39056a4732cfa8ac665cd7bb9065c916f17d91d0d897d7fde8 b9534610a83dca96a3a7e7a8179252a6ed608a645d350ed1aae91b7ab1f2c7bc 000049b702032e01bb84a057674105a5fd87f420fd01223d3476c503e92bb96f +107360 09cdc670c0cd1f2e87c8c01ce4f124e32c5164495e2b078da19e8f4cad99b31b 2f5333d1034d87dbe254d00e49e147a0fb597ec4c85afe52f2b0bc87ff2fcc3e 08262f6b941bf2d636ff73b39cec12af5aa457b293bbba2ca83e47e80267742e +107520 0ad697050b760e4ebb9e11bafc999270efefc829511de3c94e9d33a029939231 3c0d1548479367b7fbf67c29d03809a0e3423f88eac263ce76149a48d168836c 0cff75b03a6838575c76f78ff185f2d5af518ae3aaaba41d1a4bf308a6c5ff05 +107680 0f0d854cafbc90dfdf12e8360476eae882bacc8457cf41d59b9c82a4b7a77b55 3e17d23c84aae5c08895f800a390939330e8c19ebf1ad3f7bcaf1458cb85192c 0cbac41ea0b6d4fec661ffc5d32bc827a912104c3b23a67eac1e66f935cc81d5 +107840 076a470dd5dd8f692ecefec3430c9586b3ddae40fe54f9311d75e8db5d7ffc75 781019b88bbb77cdebe570b4ad0096da2ad7923ec51abd5fd2cc9c92ae46c761 085cf40fad648ab8607f1e0760fe86c6c20207dfc0dca8ed285990b22c837523 +108000 00007a0c395ee7c3fcf99e89db3892917e90ba1ad327f4c0ee3b7c379ed5f236 41f18224873d364803e9dfedd832d8f8ce27a2f6bb655b3f96c5a7542f1719d1 0000475a331712c97b9a51c77274f0291f7f1c7bf0fc0d07d30a9ee9f794384e +108160 067ad5aa446bd114fbfc687749a8d79192932d7cc973604810d7a056672f616c 83bbdded58836fa8c4d755366be2ef09df1ebf616422e89893cdcaf769b2c378 0c1c09f6f20a78f89f2b75aa77702059999367d909f302219e9950b4ba31aae5 +108320 00003ec9cc52c40d0c45f537635b760886ce78f9dc374a2db7e787998353e05f 3df0384f6c184736d419f24c5044068e349a31d738d98499b34a9cc4e679e6f7 0001c56dcdc80495e3736bc880f7b835621970166feb6c79eae425fe42356405 +108480 00009385e714e429276a367eafd9959f6147582963b5430bdbd4ac21c9cff7fe 5be9852f0856d7298b105ad26e312b99cf3043fc526d01628c2e613d42ca5165 0488fddf02c76ad85acde241475bf560d87bcb6de04564c1f014f58b38e1853d +108640 0000d61549e9ab00cbc8412cdd474b85731b1f6c1145002a73bc1059dcb7c81f 27d78f791e0beb9f277077555840562f455642a2ebb39229f6cdbc659368a35b 000006f3d3de57e1d782a4fe2ba23650b00855e976604b9c93077b97f3be0f3c +108800 0b321965ac65184aed6ad9de642770e954a5e5640a97aa6ec0861d9a1e00cec9 a85bddd6ce2ce58631d94dd719c3c31fa77ec0921942fac779bdce353a96ee14 008449f9d0ae414ef91b5c64603fa87ebbf8585be6737010777df618277f1b99 +108960 041e437203e10657b6b02ed1ac609e535e07f9d161ff608f17cdfc86d77cca3f 1c1d51f2d3b0b0a257075079bd3998dbbc66a6879372b21866a08e361e5413c2 0000d0b07335aaf5ce657e41843d7f87316c5803d5dfba8d5cf1e2762d90c999 +109120 0e1350b548bc8ea5afbdeb27ce66ad0669615f25ef3d8ff0902d86218274245b 97f78839da0d03b662a30c43220a180aa0eaef797fcf278d307e214c942a1ba9 00008057b6890f6d8bd0f0f6a7aaf12f20b484670f64a0cae69d25affb771d86 +109280 0aba791419893d361b3ca84ccd246acb3ab320e377336c4b0b2e89c745814bba 2f4717d6b0b513acb611a910012a12761b8cf1304ee10d19366788074cfb3a03 000095d9a3a61ac5c61ceb2bc41338bf220e2b206bd8eac8a8275f0fb92f4a83 +109440 00002581e0130126ef56790fbb92399402f03847459d4a1b0a3e6cf61d9cea5d e8a4ef1b7b0e2ab01834165136a52d54ab12acb17404f5eab066c30a89aac0bd 000092a31f997551f8014f579f09d08bbddc20499b6a704021f8e9e85253945b +109600 0000d74e3d7e66f075ecb6bad913ba5805aa2bdf0ed46185c395c432cce71fed abc60d2d13718d65621284b4611017dfa8419798a1a0fc397cd0cb0fbf5d9716 0d0f92cd6979fb2366e7c9569b94c99a383204c508e0a1851460ac8fdcdcf2e1 +109760 0d475285270c41898b27b22ffc63e58c23c97ac2a744362d8831c38a697dabfa 21467a29e5877dcd940c20d99407c3a71c1b824b5b9855182ce9024821c9fc83 0001093b57596c7a749f8de916c9da72e62fb0bdb2c5d649729f6dfc0b5458cd +109920 0000d868f75a14aaca5829d21fb5a930523fa2d001cf4335d8e3a968eeca3ffd af205d426a1d55785fdb289914f61ad160e2a5a546056c67c120311b44b24e87 0502cee9f617688a8b9bbd76ac4b9afae80964f37b3cea104ab60c3d67f40f0f +110080 0001dba59e53c62c2b0758ff06b83e59400979c171d930734aeaf93f134dcb61 61f72ce21518065435a6eecac9828fc2f0c4ee74f16eba3e8486a480c9a244ae 036a396b4b0ee9c214237f62d71a2b20666af6dc299f546d3be0f6912925088c +110240 07493dd3a08ed907b835f58f3cb0fcf32ba28dd446203dc8cc2aee02ac3dc491 d812fbbdad5690a35a61d4e99aa598d2d01badb581ba59d832cd7b40cb198aef 06eb7a1fdf2f594036e7f31643d5c45260e3d05fe1d87a0fe1e8546b3c2630e9 +110400 08fa3852615f849066541ef0ca120da5ec3d7d4bdc5c33536dc951dc58b92418 708c87b2df439f8e6091898a9b220b4073cf9814c8bb9dba4c7f5f2724723395 00005cbcb49c8627241769e4206338d360eae5c5e894da1e444f33a9662ac655 +110560 02f72d25f58d31aca28cfb3895072bb4438e1b8a4d071ebc042f1ad347e08559 ee59e8b6e3fda070bb8d87c7b735586758a5dd092a0b1bd16f4dbb116d8ff296 07c6095f94c3b63d01b1890da00e6d669483f42481984e8c4db355976fdb150f +110720 02b8fc405d0407d55d4b4996b4798131406c82c02c9d504a949323d6b7e0c33e 8e7cf1ff72d7f29375d9b0a73733ca0bcff6c438157ea7aa6f04dfbcfd6f87db 00018f10f71dc98daf9731ecc5e023a32ee75e69a89d859733e5c94082f66180 +110880 0001ac08c12d823dbda9d676db43e2307fa09170eafd6d20c56635314da45a9e 9c68d59be6038225b568fb441049aaf6c9134d52055b37d407e0bba9d67a0576 0758fd361444c406ae060294b13575a2a6d9e29d1cb6d999039195004b3ff7a8 +111040 0001eb04aa4bbc47cb50d9a12154952dcd66e4ed14460e4c94a7e9afbab335c3 6911fa669237900edea13b7cba24dcc238a738e798cd8c462734b9a55287a0fa 00008de2ae6df639f3a82d923b5128fe6c842f0e15a74956313800afcb614301 +111200 00002372ba65351f060f668e9b2ac3edcb830249fbe95d591f7258b576c744d0 f11026250d9ea635bf130571ae7a34e234274230ad5424b94cb298dfd1800c0f 089c859baaf2de604ffc31c93fa1130d180da78595858ce982f6c30af0e33707 +111360 0c27af5bf483ae91a2250510633ef8b2ab59eb87e875981a49b6870b633df97a a44f0f854c4fe2f19adfdccb918cc44fba02a8b34f593683c7ba906356a9c6ad 0a7a8a83c65d6b3c23b8fcd6bcbe28a0961c23be3c0610fc5bb03cd62e02fe11 +111520 0274b625da66a3f1f167e5cf702be5f88612b139b3dbd51a161376c4e981318f 8662fcdda6f9ece0c77b6340fc94bb2ed8f663baf9fb482ba994d71f68baa0c8 05ff65e853965de447f200031bbbe1ba49b9e6252b30415855e647ebb6d0970d +111680 0001ec79d16249a26541b7685334c41513df1296ea41649ee4e3c71b670e0147 3ac7846e5b4ecf39c13f8eef6c47e8ac643a76449824201054b7ea278d46b5a2 07b5e8dc14d36c661fa9740f474c934e71c135d64e2d9f8eca581f1f43175661 +111840 00016deb1096525f97ddaffa68a574cecd84c5bfb350d964c1e904bfc22903d5 3502e67d66093dbaae357e23f5472965d98cc43ee042405459764a7427d3ab95 000061a2174932fb3e8ec7e35db14d2194327fe056e2edb9dc0f16ca2f51e0fe +112000 00018353010293444b5149f2e266629e34486023b163d3d15e2e66d185084ec4 3c2d4ec557c651de400d83f63abb503c2a9e66105f1251ddd724f23de7643076 000029bc7a6d2c0850a3d70ca4b1d00a854fbc46f17f3bcb4e64ede9cd815ad1 +112160 0b70cb480d091c736674a637fa14c89f0fef775389068387742bd206e82c580d e0156f44123baf1adf94fd19faa8bc8e3b55fbccf6f033e8cefd4eea37f80805 000103bd584de85cb7e18ad057bd3d19d6937031fa0adfdee1a962921f2b958e +112320 00000754669bead86e14fcc6140e5a0b1e1a3eb20306185bde1be5968b44cc37 0593f150d1e5ed5ec0ff2feb4c2d1501c026194afb5e6dda17be26f785ff6150 00017c183a8adcf41577515149f6de46b3685190efab11784716917e55724ff5 +112480 00019c12f6cb09b0a062b22bd843e08d1247daed76c2cf8e8ede7d5819aad433 1487ebe57ef5221a31a5a7af7f436e6e12d75858b9ad743144834333f9fdd438 00002d0adcf04120196132cfcdea3abd969064e97c55411053ab2f509c4ae04a +112640 0000b340314326e3a76384c9c308d0487087741ce2f1cf306c8471e1d3c02fed 44525cb729e8682108048ccd3279a8fd3522e99ecb5291deb2ca5e0426271a0d 00000b146175a984a53bfa053f2be7d657028ce8dad60c4463c9db28a2072c46 +112800 0c8dcc34e20abc5e57459c84890be62eb4afdf6d196c6c86f8a3f100aeac53f5 a8f1a2f6acb83c6d41041f3c19b06ecd704170712839508b0d27edf1866e1ed4 086a2703725e0420c50f4cfcd015ce49f12994fad6dd2316f5363c0b957bcf36 +112960 06f214b65769d4e7aa6ce93ec85c340f59d215212b4d4c6ddb806b007d535f03 49f410517cc6f1a24ce9e5bbf3cc74c97a2aeffce31da609ebd11d68433aa7f0 0d2ca05a0c0ca0c7c43f62c5cc25a83a7025d2b7b88358bb7baa02b606b35f3c +113120 00004bcc6d1f00c892d73abaa0abd3c9d5074b9492261aecf9a076431cdf6490 b008bf776c13c61329d4a16eb4c91b1c26ca73e8b570506a3c4a67d9c2729857 0000cebddd9c04ab9b053fb7015476da8fe6d87ebc01008918c02d4eced5fb9a +113280 04407712577a09307b5668cdec1233d86f36825d7b750ed5564b1de109ca5bb6 bea85764455f25c3fff03109cf43c1d079c1983851a9f1ae77cae46f72bacbe6 0000f7656226bfaf88618a8286d32b0e6d6effec3a5685b175201c554296a17e +113440 000184d3d521c2238025018fa99e06348ae0dd9c7cde09bb336da0ae6d9f76d2 2afc179749607f6bf2de453d9a20fdcf47733f4daf82006b155fa3f84da18019 0daf542b6c1ad0f555ad887331dc794d7a55e8575fada8975b6a503e208db0ff +113600 00013f3827f44faf94a512b7e06ef3b10ca1ce47798655cf1fc6e44021568f78 b6b78f204abb5728000dc4fa2c8842ae18556d27a32e72d3228daf6e45a250f4 0d4749d87355840b0d5a3cc23e4acb4848952ce1c8ab0e6f379db0cb6969f850 +113760 0da2d3fae9135a3887d8ff9a47690d5b8a39e937209970a0f291a1c4be3a5572 e72c12e10a611c99f83b2b5d812e9025d89cc704350219042f0610a76ec52aed 000073fe02435b550a134af2b73be3ca31b0dda2117d81112775ddf3e57c367f +113920 00601768c56468f523da674093944c6fe04ea129d2467bb69f06f9eac0f37c32 1b94398209503979776afbc876a505ccb0cea23ee781f0bb0694892d88c83625 00000dd607b6c3a3eb358b71e3569e08fa798ff235f62bba7731866309201524 +114080 0001cb4809be7a83aaa4b26c1c8c0091c734520826637c8c23a3fcd2d6ecd5c7 a227429308744db70c5bf1091bfb46490bfa19c032ea8a9c855e8d00734b552c 0cb0a71296098be67d739fd744bcb8dcf205159f4328ac7ce09efcf831c012f9 +114240 0097efab55c88c7954ddd6f1fd24a899111f0ecb064d20aabc2e56a47dbf3da9 344a1d643097f55033480cebe269481603ce352eb8e5c62649f200ee6415fc94 000167aec64bad1dc6343696b47fefa47e3f82d7a6cf54298aa0a99c7455404b +114400 014fe91593aa73d3ed27efe74156752783ec004094645742cd7faae1ccdaaad9 a465260271ce6f64ac370e1127f979047cf67e888f5834435ccc3d5ff59493cc 02f76a56b1a6405904396b95719e79b0dba6b9e71b018a5281a1fcf1825d1f6a +114560 0000969a59b5fc709dca2ef0074e2680166ad65e632c72ac6ee69f5522dc9094 507e5e6259fdb5f11c88c88b69e9588db8ee75f581b53e622e47b6da7554de9e 0be5f1225b29d5f4ad0c444fc0eaa9e4f66c480baf2ef5efa14fe2753dd11f50 +114720 02409365f7df939bfd3ed3a13daac4245026358a000b6b8c73b48dd594ede87a 6bb5bbcf4b675440e1e9e9cbd566350b2c137b55c4eae9e08f29b27817a96c02 00420a88258370aaa7ff44a4625c270664971b01c9634e07aa05bf824802b8d6 +114880 018636c470cbc4ef148b8926644cf6e6b3ef4c2c0ec0dbc35247644e1bc533a6 96343b163e0be9a72fa9f35ee89f9058a6c94f55884ff05d08501395a20e08c8 051748f554848060b501863973bdf3d2cb7c82cf7d8d9c29f944d84cf41d76ad +115040 00002a24eb48d9336fef0f7480a149e8d4e814c00e3850ca0c5cdfaab4948707 0700bac6a1b6c64a263eb52e4a5969877af27e6f0d83340a6bf44ce276bf0416 009835850fa5b2f2f397e378fc64e0eedd72d3c0b3f63318c3ad92ab5d742ab8 +115200 0b7035d69808487c3372549dd9d2e722c1b0a7fc5fddb56a5d8020bef6261faf d65fe2cafa241f39121e70d4877552c2bd5d489cae9a5eeb6a3309f58701e557 00003206b6ccb2947f56d35d263831138fad7c2a908db32ecb8fb3d6fcf0365e +115360 0000a1c5401710ca826c6b967a202bbf7dbb223f55135648b37d99d39048f4a7 83ad14724a103def5986a003912bcccc4896539e2dd54e782e0f971c311200c0 0000ddd2a6427cf21f9a3aff8461f2445e5f9a8e7f8b0d923d746740d8b31b5f +115520 0384fe7745312b22e48dbeb91e07643ea5c422ca48aa4082715cc1475745497c 6a8fb87040b71fb2e9a939423a334c030f240b88dd6335e82860c75eda36cf32 000050feb0f24ecaaf1d387d6ddbec31bd16f86bc0535f1ae563cc16eba08f0b +115680 000085c0bbeb8a1e25f9ca709e77971ec4e4a2b7d053c461ac95022783f7626c c8376da2bbe74e55b0a7d93a9bea6847d0fa97efee0c48cc0e998afb1e88d3d7 000031f493624720c57a6d2c0a2ff25404c453fde976af3f752870d1587d4a03 +115840 0c72a86834177fc5563b710792e466d7d2af1f1c8f0ebb3967c8a63dee045599 2a5df196925bb74c07a03282265a0480892eb5fb08a8565a95f6c052630498f4 0000850a3c9db5bbcce3c274f2b0af786179b7eb77ab7bd3de95fe91881b50d3 +116000 000043d6c968ff3f9adb7349b649154e1fe610cc9fa27edf7d5099be9453adcd 64591a53f3953cc90313a4c04cf917f2afa23e198ccb2669d9220b311c364147 00001e63e0773c76fcf149543c219b533d23a6848c84bb20c5676517bfcfa878 +116160 055a5de8d52b7fe3852d40181429d905b6b20094a0bcb11503cd7664fbaca8b7 ac690432627bc00604f37f75a1e8a53e339edab16e9c87e781be3cbf3672789c 0000de77d85c55bd52490b116236a5e84ac64b4859d9e770e66ff45e321e8b2f +116320 0374a9f5e44310663ef320361a7ad106747b2888a2e62870c760f157858fee71 394189b0f926fbf92710624ca57028729b517a2ef548fcd1e991f476a8d7b024 0df3095f5dd0568096d85acdf2b4554ef9cbfd2fea06ce4751b61deb1cff78eb +116480 0000305817c330daae1808cb6fbf8b015f9c2304e7c6eecb22b661842cad3cb9 498f38984331b3d410b73dacd453f837f93b59ea96cce340f06c038cb3f50ad1 0869e51928e966372beafc7e79549e839ad90dde20d6834d59f88aa773158389 +116640 0cab3ce46ea0a3f38689278ffc1174320c4fe5b4a87d6193365d0e19e4a8f9e7 8a26df3c69451a0167881e93d04f590c647accad27acd4c1ca1643450be108b2 00000152349b89bba67d6b787ce0f6021a988f7aebd73c9a4037d75793ee4fa3 +116800 03c55fa361dda693e7beb161b893837b72d21cedd5bae31015b853d619e01b14 2505a427225441f1a3218b686d0e8bf532b66ee21038478558c9c5dc56d9d389 01a48e918bca61c48acbdb4e5a617953db57f3abb2671294de909b7f838745d5 +116960 076d66a3f91db9347996ff06e61c729a5bd201ca6bedd4031b2d622d4d6d1a24 73299b2796e6a6d2b282577107da20eee90ba6f0b61d2774b943a2621b7783a5 0a83d51cc890e6b0f8efdca2a29c7e11131c939a32718ee25f5e8e8f94f02838 +117120 00484b3356c81ba803e3a8c433b6374a95750605ef54ab8a4987bfb67b683107 3ebf06f601fa3111e7082c00b1954ef2818031bbf6c30b38fed547fc3179b6db 00010f87516d12b5d1da3421d3ad1b41f252255022df57f64dd9b9c16a36ed3c +117280 0000b52b441e8e90459b26f1fe88faf3d35df8e46fcb80cf8a8a5a7abdae6011 5507412ca253fdb0e07e7eac494cfac06e805ef2163497c1a0134a674922ba57 00005975219844fef99308f1509f3edba5cffa98d726562160602fda8cd197b7 +117440 07cfe7d2d9cdf5d3c3d6513f389b15884a60aad1458f469cf9fb84fe9e4444ca 5ba701d26018ed95b583d6874220f77fab7a1e07813118d985f730134b82d22e 0b78dfaf379d8cd465fe4f8faf99ae74c6199f39ff3355c8d2bdc804e0e0a030 +117600 04490df616aaa2e3d6b2802255051cf443742eb3cb1a7568a75858a30369f106 d5f27b489a69c71c76e31b52e7e60a7dcaa94f7100f3af439b2b030ea0b5dc8c 0140300dd0e758061f9e4c31829c8a551122eb4ab09e79b80c73ab23ffc97fe8 +117760 0000c901f6131235543cd000333786b37913079864f5031aa434b6f39f1be39f 1d06b32e1ff3d2864f2f7bfaab0bbe6c2c3b86ece81dd76da92f9a70a9496e99 05480f63458d4e7693f8219c9b3c08f73a1b126cc365dc326245067af8d7e21c +117920 0000955e961fd194ed5ed837cf95c2dc6f5aca8e5ee3a5dc929d290b2ad482aa 9a60f56e3f0c986699a6d755c53ccb838bac95343201b7e74bdaaf72556d9e36 0666d16b9e19e9cd1ef862e684d655f829943449c186f697b52356276deb9cb4 +118080 05b56bb54cc5d7ae0de5f869f6a463db855cb9d220548a9a24d79a6c3c2adacf 04869492cde70ec377a3281cf2f034c4b7a57a64d12bdb2b6ed8f22de1588581 00023181abf315a6de9e1d5e2448e5db293bf51626a848133ea72c5b1330eb5c +118240 04f5755e868ce80a62279cc10b5131f5d7e2f65bf68bdc781e6e769f95138a17 1886cb456e26ba56032c36cc793e9f314fa3b5315c2531ee09e6269f92142e06 0566e04d5d2f1ae3b1b2c7d4f88f1c910360ed3c49e274ab6b1bd421731d7b3c +118400 0215fee2d0956363e347b03e70e731ba3465d4d6365d2d69bf154ddbc10f2b55 c81bc1e28d04f70eb3e7082d4952096ac43d88842ca26f73a64d934f17615262 0a7b3d39482762244acc2a3ff17fa2d57bc1b6f0955edde76b61819cd6efb04e +118560 00009b95087b647ddf4ada6400c71adacf788e85ed9d915f9e35f77d56985820 ccb2e33577f5ce55f9599581f5231b86c835af5fe27053245e228ad6fe971cf1 0000c5791729c01159c9735facd44ff1a643066430c6fa48e3e142a82b1f9a1b +118720 00c4225c56ba572472003cfec56480064f579bf819eef42ed135f1afce1b9488 dd7ec2c987813002fe59db077055977558b64d7f95b817725f0a61a7f0839f29 0ece201d379465223bc793d6ec3b3c03a9c410ef4fb2c1450c6943375cd773a9 +118880 0000fea5f2fab1e6def8d4bee87704c11f14b82218aa5a48d385ecf3c7b00296 0e8cf5c2d8c3ceb7ee63cbcc2fbd315480a2987f8d820012d7a126203639844c 06298e7bfbea8b4d7220937d0407eabd282d30dc8c9604410ec46127744271cf +119040 000011c6a40737f88caecd7930ee231e16eec2cf09a32d284816b9004e3650a0 a54269b825013175e18b6eebe5df13004ee7c241ab31b6346daa61efe4426058 0a499b21081020f4bc4b7b030ee3c317cce826698067737b5ab30a62513e4bdc +119200 0a8b73f842e480c33fea4dd9f803e6071441ead67ff742a32a188fd7a4570d35 19871d6d57372cb935366443664d6e161d4d0f2a08bd21f0e3b372229f5ba6d7 0000b8067b30c093bbcdf2c80305459d839e7f09aac62911a22777c00b9535a1 +119360 000048b44a75f716ca0e556075768dc7db6e9fff6a974047cdb093e177883cb7 90ff20c01ed6d49ddcaa683c8c433351a165f3be545e76c2e1e4fd88da522bfc 07c83334fd54e13f3499fda71a8512e576ccb49aeb15d2cc859c3f8f86df68f2 +119520 01dea624d233b6a686827ebbe5539456c426a9e987f8fde5ea4ec02ee142acd5 3ed7f842df62d5d1526606dcdb84f9adc72e428c8d07130ac7266b9307cd16c5 031161c013a51e56066ca388c2e4a043f9256b5cf6928ba713429690bf1fea33 +119680 0c06540c1f7c264888f19cd2333c5d91890e81fa09a406fd597cddeb8ecfe7d8 220ceff62f7e3c6e11fb2bba003f1d6831a9cd57445b9c5d660378beb5f17685 0cc7b8b9ac03b03c0186191235b8240f30bbb33a355a2d7073c0409b4930e2ef +119840 0ee96a8c50cd5d8b7c1ecb4367a573dad4b8201526abd0b773399fbdc2938e7b 092ef96493c25aa11537ca0df1a5541c7947945c4009e6709bd23aabefbc7796 0d351a6ae8e2288a418de6459f0f6ef883fd8358af89230c168875533bba9324 +120000 082a7918a0dd9cb2df65f55acb8d0a4a535b3fa684d92c3ebcb24ed7019d975b 5d4645884bc63c656db6570148f753a8a0d607476d4eda82949f011efdf3d034 00004c32ad31f45ae06edabb675be6874f99bb8bd411f586369e3d13effc3a41 +120160 0001bb91676da1be9e07a20430bf6ce00cd37edaf7704989eac172e6a00ac22e 0d04c25d066b560cf6b07e14149975cff6bd3528720ced9cb3deb949ae836ed6 01298886340ace5694b4266f031cc311ce03291f0a70581f90747afae2100805 +120320 0880d533e500773c3132a3f11877e0366cfae71e85413ea5d865f5a1d66b6568 c9eae05306f13ea89f2d4a010d185b714cc80e1a94cc9303f857c5328a86ad2d 0000992ee3d61a64bc733fdcfd99d946a9c34dbbcd8b9d1d91bd16511db45f76 +120480 0119f2dbeed3d92e09b1e70247a9208488e468fee6b73642b1abd92e07ab4b37 0d39199fcd1403ebe2ddcb6d0deeb823b588575666ba63ddb8a54db31f3a015c 0c495282ba24129f74cf2d13a397b0a84c5662586b0bf4e50507d972bf9b9666 +120640 0c205ac2826adefb5e69a97d67c3fbb65f64233b9580868cc3bc4d9bb83861bd 44452bfcab01b1f932fdb42cff718297b29c6b58605c5e2d32e7a7a87aa023e4 0000269284a6de0b8d6376b16180e5a533a49d27bbfeb2edad328d16c613e511 +120800 0000e1c9cefd201b51b7dcd01a48442a942ea689a80e06be2b7e567a835e4c48 7d5f32ad6e09cf8bc37d7e20673f3df7a27f3bc449556958a9a0afe3a0fa775e 0b65eb4973426579115206163daa7d675db7c7e085c538bb3ee85c939c5e334d +120960 08066b1812f951b33a5aabc75f5ecb914d08beba2af500fada978c33f9e28962 e29cf480074809e97f1f1a77fb1de1f6cdae00ff273e72b2f43cf9f0b05bc2f5 0269f52cc24de2e5d4b59bffa6d5b241c3dd186b08b0b2649f580331bdd1c2db +121120 0b5d9537f2bfdbb1085cad423f8a9a8f842f69903b480cf210c725fb06cfb4e0 f8451fc702ac11b7ce6da56474220e844985862c7589251a69c38eb890ecf72d 0000194ec7a257adfc5918438c33173b1bb020ffbcad4b56745fe9b7d396730c +121280 0001250b3e951e86d28587a5408bbebc8afc4ce9cde80c76b63d0935f5d601cb 45d722a3135d385f8df7c39465655e724d521be32fd9f3ef86b10512824525e9 006c027d8a45901aea4016162b0bc40e5ef0c6bf7cf25ddd77bba9fad32e3c65 +121440 00009d9db0b2bd44b17efc47c9e4c7fe52761dd34e43649a3e65568eabcaab88 df9e9dc1183cf4b25bb7d269bb01b84eed38ba61a4dde740246eea305a5cf235 03af2f5f24dd69e6321fb3d211d92588765a470aeb0e86c6adab968ff2f069da +121600 0ef77f6afd63c85d2c7fc09975ef7e8bb8360c95e23d29ed570592e7178e3f4a 7dd919c53407d6f5495e19fb0358f38b8d5416a75c869266d2842733db00eafc 039b4f650be267661dff2bdaf6e902ddce93f785534a24f0a83552f380010981 +121760 070ae584ba9bc30c08985d691f96627ecf387957f07f4717b6bc00cfafb5588d f65ebe26926898e04fe5e321e09624d209181854ac035d42a963115c73b2e9ea 00002e0d2b7d5eff20f9694fdc69e1ea7310746d4760a1d6f71c45a973d3a595 +121920 08d21aede3a1dd248a1d0d737388c68afa3e96c59a8593d141948c1cac9224a6 26a4d9661f779eb83a38ff83f23bf62bc652bca93a26a03d02fb004ab65d789a 020dad6083bf2a51b57e4cc2916ee954996bed774217a4717c49bbb1b5c416aa +122080 0001ec2ba25426863b7dda8c96bc8034df69886e9e888a21d17cee9eef4fdc48 d0f67123fc758e5662c6705c7e4bc3bbe97155edeb254d760834003613a95bb3 04c2e39accf7dd841d93c2528bf5eec1c6ed6a9ab99f45dce59f7a1a4a5df34f +122240 0060dd2ad23b9679b8cae07f6c6113f344ab891dbed3c52b19b12594f1981148 a4de07686bfe542633594d9264219200138d4532bfc263062faa3b48f24128be 00001abde6a2a816725be9d7da55ec15963868b38241eb03efb9ad88f8daa822 +122400 023e96e49865a6b02846047e82b903375105d8067b73320a04b2d60f028bc3e5 c911c7b09e1d94a490cdb62ffd546048fdc71640d6595e24ff91b524acf3f2e4 08e78f76992bb10abd789759f5adf2894afab5ff1cf826d2f3e684677d372f70 +122560 0959ba4ec0c90cf58878da9b93a13053bbcb2fdd0dee0bfd8ac9e6772245a6cc 8e5d9cda9f9c2bffce8c47add5d528cb2f85aa4f6d0c57b37c2159c671588932 00007613a390aaf2ebfaf157032f7f07e274c1a8f3db1b6adf155df241b1c1fb +122720 000059fa9ed7bd9dd82e3439a7313caa17893629b7d94032806287633f8940c5 eda30da9bc6fd58d75a2a8672dc217a676be14d6064b2653141bdf36d7d3117a 0415305c9cd01d0d3616dc13018545ee459f18e3d02269e14e0091060736ee03 +122880 00012f00b519db6279d7c9e2b560a530899ae9fccdd9a09ca5abe3f3b89470bf 4268ae663ca361326e21e2559c7bbc7c00af985b54b616d014cf2f533f48f4d7 099caf003c629e6a04a6c53c8b16c5affeae635fb1dc76ceab59df1fc51e40dd +123040 0000a0afc3cfb33440a657533b05c41446e42e5790e7460b2234c41167c62295 1961441794f4a5a56100a161b009abad4b51d4262c4595ccd290b2d51db20347 031dff9c5563a8c9070775ab47d6b236e8194d9c46dbc7e7c6dd44358153f3f8 +123200 0725330aa71326593a852629f185590b541567260e00fee4fe6bda0c1212412c 5503c18219f5c7064689d869435dea0116026b820f77e9c08c6ad93f3610b49c 0c3fa7c9f941902e287f90ac9a9aefa8348cc923669dfde2e3be2c700cfcf1f8 +123360 055fc76db9d4f4e60cc564ebf1363f4f5d510a992a96f19d06644dadddabe6f3 974ee5c72b53a25c5f20185d99dc6d8916359cda93b93c8a20e6096bd409bdc8 061be54136a1efa294d637f697cb4382eebccb8d8866faa088f501cd59dcabb9 +123520 0b72e7c6d4e896694878daad8fcfcc60b35f1aff20bdef708405bf899e990ef9 ac441bb811d727992b39f10cee3b1db7dd41c5e5949e08a421fb420e94975f3d 077f1e9c8072a54f24448b916bd46fcd34f20c4ffd57d8e694800c84d1863a79 +123680 03aad35ca82a4d53203fba460abdf162930c86477ca5e1365cb906ecce1a1aee 0945d7e2d0ce5a3ed9286e4f72f0946e26a6a44ad8773ea2568708aabe97c37a 07d9c08e79fe35cd4e0a752f6112834d94724de30a632481be1f22d0c829a0ad +123840 0056eacbe60f22489bd1d0ef33054cd0fe5af65a73bfe7aaeaf7a9310776cccc 53d886734200959011b71b368900c5798ef278f34c5d7be74652dae10e0a7a1a 0e0a1b17fe2da784ec1778c0e4bc65bf904999ae784bfe66875f2df031a8ccf4 +124000 00003f19807137ea5c0bd1767c14c7da43b3e9e19e36b00de3f60336fc5326b1 f45d2381144abbff49676cca7b399d30e8997136421445ca7b0d9f63f2c7d408 00003f3b24671efb34ef11d9549a60514b5c2b98efe0bcf7d83f24e7199c8786 +124160 0024e66a06ee932782dcede919587c4d2d82a68fad05c53ab47f3599239d98d0 f77e8aab2ca06199964e2eb842f9438aa359d5fbfe10f52e5ed4d23370bb6ab6 0933b6657f5cba03508eb793e8e796aa2eb43ccd80c3af77e6bb1d663a34d2f7 +124320 027d6572c725f6147be5824c1204083e8cac600f2ad1b12efeabdfab23fa2c2b 7520b18a81fa598ee5fbc5e45d671d1d9e3fed43dbb0f86ad347cf68e2745fce 0da1f4997664857b6183bc6e9efa46930db34967f87f5da0baf06c45bd8268d0 +124480 00010f9ecca1cc210b9b7d53cc7c97cb2b2516b350023ef97034abaa6c7cf169 4d93827c843fc159b1390fc4ab2e11feefec73c81fd17bca76c9f074eabfcd28 0cc5a97996d10880125592a9d20c19223069f5b804f7f70b3f1f621bb5572282 +124640 03587516ee62e7d84d17e5eb23a7a0b89f3a45758ca590bb8aa780abe5c92a99 8bb95a17d08299c6ca8737cf5cc89c4b9ed8cd6c3e76efa79f96fd80b8417dd4 016c68adf1bd0d5e452dc785857900f643d501c894e94422081be5db931ab800 +124800 0534b2aed802553d6a87e668e32d95ceeec126a02ca06c027e3c76061178c918 8aaf38c4a6900c01b055883cd91a15a4f70f199fdf6963b0bf97e8a1b5c9dd49 00008a7e1c167746f4ab059651985c6949763b800d328d4535cd7646acf8e5fd +124960 0c66498a45a3d6daabd65d77bd354423c696a2ef53199cba366b5388bd83f762 b5d789de85822ccef28c42263a46a785d8560c32ccf1dd540892f019f76a2805 00008a0dbe119b148f76740763b3332c4c6cf4885467ca38c6cda615563462f7 +125120 091cf23afa0f3fb132230605fd9eca91cf8e2993530162b617e79ee9132cae33 944cc559e9fdb1ac99f19813752d3c8441797841a71339daf455698ec9d09064 0000c7c895d460170d61f41c38c27ac7666e10aed6ad7c04ea3a06817e3c6f93 +125280 0dffc494d8309752311fb36042914f0874a9af595f26c2e60017612a817151fb 534d49a60a82fae56c4aeeb2f48be732159ffd6aec54b94da13682dc9a419181 04bb60f0bd305cdd6d98ed861bf4211087e3402722ca6a3178a082cb237e6caa +125440 0000a35719c9c0a3d8c5567c4beaa3e4ac8f87d8f26432af7d75dd83b343ba59 d095f3fbc5842b4ad8d010ef1a5ae44d6ec0401ccf0d612ec9d2a1be6ec2173d 00005e2f705af179a27484ca714ee56b59269c1fa5f32809dd611756e4e0f86e +125600 0ef44c3cb535d51932ab9819b4c24ad11a3ec84d5a704c989dfbf003eabe8680 6f8b9391229a6f10ddb1d37ba1449e87856f43f2709f7a296fca539fa349435d 0432c0ab42211fdb98dc84107bd02c0d6d0e50a117b862baf959610e363dab2f +125760 0000293cf20d969721b105533d29592052d435266ab1c75477710220c6a6a256 bf86f85777383343fbc51514794eca36d288c81010bb03249abb58a9cb6939a5 07daf3dbf74d99036214a0b90eac4324070b14ca33e34a9f74315fb293647d59 +125920 0000c460944cb68fd8a667f5148ccf63ee5f8db43aa48c5e6e6bb036b2346a4b c6114fcb1bb1ed847984187b4ef7f3b9a6b4d5d2d3081f1b7ce839b3f2421095 03e44e52791a2b67092e9cc8631b5954f903a67bf6bb8d86989f81c7d8bef417 +126080 000163de68544aa40055452f3c104ed4806eb09bd9e352d5a0cdf8d2578a53e2 b281f8413d9655b99c08c5d614eedae23e8ae4bea46e4ba17ab3165933641005 036b2e17d93a9f199d2cc526a655557c29b287222a52a27d71cba302367156cc +126240 091c48ca6bb960dc6601fc32f6412ed897e35185b76f272b82f16e6aafb00004 ffdd411b899dd40f3a42758a2e88d402542e3ca4e28c2b0c01d4d9ec711c8e73 0000e8f7639c84b471983d1d6efa1a8bc617469a997ca97502b196245ca08cf1 +126400 0d2f47e42e48a9f50c8ffef4d624c70bf3d00a5e88e7de682fd2916a99de81e7 398259fad076e46f7634cd1f0b81707fd9da88a5e7cba67e5cf0204d88752ea1 000089b01459a042eeadbbfc27917fc6633f91449c667ff2b02945bfa1f129f0 +126560 069216bf5220f42034a5173b42a36e5f55bb2e746e6ec6ed81226e96730a9eb2 52af3077fedf28ebfecc8a1fa796aa5b84e89a7a819e05cbda3e3e7c70dc670b 05c59f756619c021a6f0e050bcb5edc76e8b019c12d8dfbde7ed7c6612f47bfa +126720 0e39dabe5c196c098d4a70bdb2f071e125d742f6dcc07b81c5c85fe3b73680cd 97155dba7916fda2f6c3d5f9e48a79a764a3bfdd614cf89afc07a9d04303c6d4 0000027dea03a93609445ff15119baed261689890230ee6ae911a6e3a9f4d3dd +126880 0529af21979c87530b6adf98b745380bbcfb53463fde847069cc6efc61beb298 21a812e91b88f34b9b49b697ec321d9f8254b32928510ef5d6340f3ae6e6c951 0000114226bccf7855f7b9acd83f6b50458aea76557399d6223d0925eb816abf +127040 00003a7d3304ff4bbb2ad73c46fd9b3fbe457b1346d5559621f63cfc7a6b3f56 32231a029bd488ab99968a9470bdd10b36ddd957df29a915ca9c1240847fde3a 00006d7bce6584c4b5042cf8faedd1e32582d7adfa730f2a7ea0756704701ede +127200 0c2f00830be2e6c774d39deafc38de464df66015839c9417a16d379225247073 0e7000bd8cc108bf8aa3ab34084af52c65273d4174d4123043287a9ff11be0d5 0ef2bf64c7d51d9b173cef9091d0e960cb4ecb577fa81a433e0d3f614189e039 +127360 0010f81d81163b6add1bbe2efbcadc58a2e66a3a79c1d4669107dd732eff4eb6 5fef4a9f12943ab8356d437154d3cc964174078ede7ad631c086c4193fd5981f 0c1e68dd883a450c89e7631200840ab9ce7d83edd696c0f9f5de5e625f4774dc +127520 09cf4c65f954530e7c626a7850d481ccf0ef0374ae37bbd988435f39c489efc8 248f6e9af3493a322d55b0ba4b70407c7633633a07b9b329eb62926f0854ccac 0d3abf078ca06e8494b906a624646365d42c8fce33fd5ff788fb87aae2543433 +127680 0207a8e0b8d031f157c325451dd33fd6fc70445fa9592cc4a416596688f92459 fae054cccd4bf6556e74d07b37fbe1549233dd7009d34ca8f07e2b9750d52c99 04c50c4cac53d69bb835193a3652b7ddfbc2974cb08c0b5af634ed98d684ecc9 +127840 07cd13e969ab42c333ee34e65a34b88cf99efe183428fab4f8f9c3615e34e3fa fdca9fd0dc94302aab715b862c108119ade3fe4aa831d9ecdc1c23dacae77759 00008cf2d52fd7060f4f563aa22984df3e61ad70d0423bad2d724bd56d661d1c +128000 088488121b006ad3ad9a92268839c08a55845d1b8f2d580c7204ee4ff49c0fa3 ae0162cd862d6837210497406f2f09be98a97c8d999b195b6889fb5f97234f30 00006154f91b1b82f9b1db199d8aee6a0d3195fea728923bdc1002bf5c5ffd39 +128160 0000e8dc67903d380bf35991c296bab8dab08cc9ed01d7f6b8b2d547907abb10 146835e524ee823fbca2678aa19c827f4be711b8f5793257190ce676af683a1a 055c3c2eb53533d6cf0d007d1c379de183e25d67bf27f52a6660a05b8f89d1a9 +128320 00008b5747558305a1b318e90bdcbe884d42e1c6231af757f1a9ca918e7519c1 01cbd0a519545cc5d46b198da8bfeb116759aee8d3c4d944456a438abe429888 0998c0f0963b0d84a32af8ae71aa5f10e593a1a664c199c9ec82d6e249e9d82f +128480 07e78404caa14ad74f2c3dd7722b0b66463caf5f207b848fe85d8237e497ef06 3bd56ceaf1dce929118ceec5e7d65029593ec5323ae24adc32a72d63cd9973a1 0000b1c16e97286023f5f83d4280d6de2e7061e0a5af74757d81f2b56e516017 +128640 0000a16f4717cf62355e2ded9b9025022a3dcc6b70bd589823b5f7fe620f6479 f89ead1de1b9897e7120b6abb50d0db66a366f4463d960cdea7bed8d6b90f612 054647a67dfa3dc18181fec27ba5f5a3b51415ea5a7617c2a698c0bdac426882 +128800 0c2466abaa76361795b83485c004de8b27e57f332dfa486a4ee5a80fa494c932 0ffaf1376ce6522a4c31a5e79ff45cc43ed2983d7c47c3a843639404d0b8f1ef 0001224bcc7b13e4a66acb3e9eec017c139e38fc85e634f36adaef96c05c9abb +128960 0ec2f3e8d270ec737b02ed6b2e4545703e4aa7d915e3ec986be6bf85a3b81536 184285d5b3179b44aad7713e2500b1889381a02ff26de9c3b6b4a84828226609 07b59863328199df3d04593ba70f758bc2f413dffbc50e948eeabe7e2d76ee75 +129120 000114d74aad9c09256bdf45b1e0d94babd1f0ab2a861776085ff2637cc36526 4d1452e92df2786906a248271627c52b78bd9d54bf7bace2c1e0738cd077ab00 0a6a349c2ab1278036d85bd3f35fb1e08d9db1df0eec436cc142ea62d5f8462f +129280 0000bc4b66cd7f10b90e506f48a5bce7848a109e9315ebb022e1ea207f0d4058 7eb8f2ca221ee78e58fa1fd2ef7cfae0f6c64d0fbc0dab43da4276253d24fc0d 0000a16621d5f9a67c0d4767627f00869e45387d46abcf37308f90fb99c15cc1 +129440 0402ab1f42597756a02edcf4197085b199d37c5c2b2bd51e3c6dab5d36521510 76b38233b959a2fe7d1d0ab843a33f328854319f2a0e61a5c0e5c5594ee3b4ba 04fbe57870f65d0ba895827b9e52407c30e2116315563e4ac97c57007f93be38 +129600 0bfb06fc7dc49d49684bff5711a72564d263437f5547b59325b661ce83483112 87d17ac12c7738c5c6ad335815e5bdb163c0ae39103d2412403fd14e660ee1f3 0000e0733f2dccaad89f813f0b544b92bebfdb998ee9ab6d19636d2d35f5e70a +129760 0c42cf337f68a5388593bb0c06092e65558a2fb69b3d33aeb9806c055a24cac7 698a423d466aa52f4e3b5d84c0ff268e04db030a2d779ba80db5abb02b32f673 00005a3b7440ff6f435ec8e6fbc1a397622d55ebacfbe6200c080bfbc193d506 +129920 00001038f16b1110da00fc89ac829f764506c7262e405f0812aba629593157ce 12b2d4967589e8dfdf918e11b82fc5d73bf7269bc63e633e2dd5031cba151c58 07a4264a48a19e1503b6fe1afb6ba9908bc10d59e71224a364df7f51913afeb6 +130080 00024a7397b9e38a25e987ccf6913b60c7086807b954691cda2866459d25d7b6 3deff682491706219d365aba20f32b755c5151b5421a36b3ab2d899018fae0e7 0b0c0c3826613ca624c9341847cb150f15edd92291b8bd6894bb2e81b1eb3c4d +130240 0eb043cc3485fe9dfa2e8250a3aefe9ac1aacf837f2b4743ed5721808abb384c 5b89eacf5cbda21883ed8010a49f87e7ac10b633892e731a9e65ed8956dfa282 06b4ad3ae036ac8f64914c727bc1ea15f2d7d2bc131eb3567f39399360b4bb89 +130400 0e1a5b9167d7053451e077148b068643837ae9782ccc3f31e89d43b675045719 fbf47e6765cdfe65e1c8c2091c186bb34e2906d62889bde9c5b0a21ef0f173ff 0e211dd1430794135fdbe936b4b57bec749d2b906e7c455dd06df54b6c997325 +130560 00009facb638c07098df0577b3e9639229116fb545339f294844b7312ee5c95a e743524b745803e462f1f617d36eaaf7b741a419b5e68d37ee52c24e3f79fcea 00000ddc80d45fa6b70609f5a236cf421f6484ca97cb75b487a23e2661300be4 +130720 0518499638c09f807bbe5b91466240c4db426a870305f47376c5585194bf217d 2312e9890b5969feada8d4a1987ae3a64a0261215ee93156d223eac9dd0e81ce 0b56948370c1ae6f8293e35c38e26a7d21fc75f337d69489aae0257060161e2e +130880 09d8830d737f90d2a9ef802dc820824581e42a38dfe5f8208e1c5af9ed38dce4 22e8c78ffbd2c762e2a0995e9d2415b29f38254fe95c037d5bd13dc720115729 000016bc669127c53a13f43d93ed59b281ec599c43f288608a3b5d83045de0f3 +131040 036fe950b92e5fb2c645a57f875039e5206a39ee9c44c90cf55821f6bf40fc44 46babfe9520f793929db299c8513e76d4c62d2760704244734d69ba3b1decf2e 090c7a9e31922bf57bd3ee36dc98e076fda0f701e28e39c36bc575c02e8d4f22 +131200 09e3ac34e7adf8c9a4ff6ee0378b1738837489e7e62e0f643180530757f8d0a6 ecd7811ad45df5a5cab560c523746570f725e62904d50225b8bb0e235b81efe4 0000c9039f3ffb5c33bc12f202a5f4b38c8bb00d946d5499cc817e7bb7708459 +131360 067ffd3f2f1151188288b0bda0ac31fb7dda755b5d0e0cb68f7b1e8e6806d9b5 959387a4136ab27198483121d3907fc22536bf58e870d83b085f0d1b68bfc5a2 0c73ae42d5adc1f42acd65f2ffba259031fafde77e1b6fe53cd77d352cd3a7f0 +131520 0c2b54ca31ba43e1dbe6e26db522a76875cec69ecfa13c54f14a7a59f30416be c1eb5fc1dd8b6e89007410f5c591f532d419c6095adba3b40f2890507691b813 0000d410ba8721fe585211a2a9264762475b3e6416d7c238c8d7f1e6c7be1769 +131680 0c42f8e4d8c1c4eb7e87e44a5be65b05e9781c09d6c510c2ab404b1e8792e0e0 94b7dda35a83dce2a7143412a1336dab066cd6d82487b256e714ff9bfe4827e6 0ace18253e7b030b3f3840edc7a3e13bc42ca003a713b383cb711ac260ed0bb0 +131840 009aefca93f7b9723753fe226f0f675db82fa2137e5aa8cb3be7699f2de0bb74 e1af24e2b7c4d422ec0c89b267c63381f0c7ae023e638075308d49cd7b4ff9e3 000044c5700be016720196ca8ebf085ef96664b8c317508e7e97a2dcae2e538a +132000 050f6c62640bdbe7f39b94df5d9b8983e1a0900a3ad4bcae2cf817e75e887307 8fcd5c402dfe1d63d46452576a3e4bbd6eb1dae2974ef47c0f4918ad645553d2 0000384f9c6fd3dd6ae3ad21af59a2161c1381a132c0eb90019bdbcd51ae389a +132160 066cbcd1c168bc24510f6df3e6dea5f728898319d5b8ce4f6fdbdfce298baf89 b506399fd5c26d400b1b58340b8a7dbd576e9ca23ea0966c8dc1cd42207f9754 06995123fc08ff7b093a7fef629de6a20dbf3962974bcdecc752fe07df60927d +132320 086124fce40da169ace1a8141242457a929ae3cabef10546799bced18f41d0a3 4ede3582f679ecfd96be4cbecfec0d20d64081f447662c87a020bc50bd6fea9c 068f479d32f6a9baadfe97bae94005029936510667cddbf86ca84a843e8e1ee7 +132480 0c8420076a8e2d43ee7e4cc8dadce55c8e8b9751148c4d0ef85c905f926a65e9 a3185a80cb19997afc1231da7e90c8fe9b73f853377242dc6d7b259435ee47d7 0000975005d6aa24f11dc217c8a3c1671f5fdcd1054ea0e8e7c03686f2c86ca5 +132640 0c40f7858d4c1abdc24aca0ebcdc38167a73dc9efc4f417ec54901065bdf4227 375b9018d0b64bcc1b92c9a03ff6e306dee0fa5f39cacd3084ee352d8b1ae364 00002d75fbeae763ec4b5d005f6c82e29819a1ccc76bdf28e495f968284e7d89 +132800 08046ecbfe9ada10e02adcdece3eabbe779a03b3c5f4c637821e8b034f064d3c ada0eb7db1c5413fc81cb2ecd4866740769cfda2a27f307e4c2eb9766b5d6f97 0e33160799ec85a74987f9afe602909438c7bf3ae9c83883964b055f788092ad +132960 0b9daa29363e1090ad492b0e6014f65027ce1d0cbbb7ecd7593ce323dc4251db 0a983258b9849a0f4a3d8320aee63cd71ff193452670c1f8eef6aada591bb5f9 0000df83f982116d96e18e42fede4ff4a35bdfcef2621d3851831e06f42753f4 +133120 02b5824cb8f84f35b6b02240c5d07ad0266080bdb9b475721be85cd1eb05b0f5 b1455db8a0cd8bf95515afaf9820947b0d2d34ad493d316c5f33c6cb081d446d 00002cd6460374377dd24d5c132faf5c71f0ddf55d9ed0b6911e4ac8ff977fa4 +133280 036ee9d3212f484c5d350db5bdb86532ae03fbf8651c1a1ae948c4590263cca9 74927ae4270e3d0a46a2f0b65c882f3a128097c142c6ff4077135a7d23259a53 0000043d077a70a6f4095b80c15bf8cdbbf96f89ab7d968be63fc99bdd924d8d +133440 00009b07ceb26e5105b814a67632c86fa4b19c036a9ecaaf010d68d4d9ad84da 7f7cbc816c7bff4c3d73197505b3901428601a917149eb8ad501f8171ebf9925 087397ab3593ee6691985b02c529c63b780cec64b339661f84840aa5f607bded +133600 05819499c6f600360b4d4021123651d21e122cc6ddedec4c3d3e14ff7ed1aaf7 678bdde49e52fb2a15268a1116ff149375fd9775209227bb87b7ca7da15191d5 0e51f78420798da9ce0f81dd85a34406f8adac5d7eef582f11cb450a55984850 +133760 02fc041b15f71d09dbfa7aee77a00db09583e35ba50e0598360b77054e152e1e 2ab4129d8518a7ea42e8b3d331bb4877f46a77d0a99a3df2fae51ce7a7b15149 05177dc101996e32ecd4c216f4a9f982ba79a7fef474840b103d873e95118a3c +133920 00004f59b64f143a3b6538dfd1678a25037a3a19a33e57c89744678b58f83475 b05bad64420e268ef18260f27cbbd625dc50496d9a4b72684bb4644e06aa5b4a 0419cf1a42e4a5d4fcfaed0780cad6fc77347e1b8fef3f83f20c08b15bae9f77 +134080 07d950409e27717c97d82e26b36ad60ff63c7e667596084589ac396d24e50cf1 24169af8f055116ebec6751dcfcdc2b0c58b3e9fc86d5b3f54232adeadfe2d58 000279c6fdb9bf71d9df1f8cfdc1c034ede2dce63d2fa294e7cc8e2c70fab728 +134240 06546b309ee68b2462a8865a47b249d3ef9cdca267285276bfc591264b8f5bc6 d5e95a8b6a5c562d5301f9217001bb78008d99aa5d764318dc945e6415ee10ad 00005ac7f2a1684899159f0bce7fc7f96d6faddcb667ba3baa49390f4df78c95 +134400 0992bf73f1dcdf5465536d247c1c0e9d08d318f63f4b45c117c13aa18b04aa50 d982acb0d14cb0e9e91663b4e4ffca696d92e7f7e5d643e441be71117a17c065 0000637af4b07658f2232e8ff357757bbf7eee3426f1128830d3c525c1e1899c +134560 045c3aa054ea5c44a6a498902d8ecf895ef1733fee3c25a1365b1411733edf19 ed152c2f2057c7d1797b8d9d89b5136781ff009f7196bd5c26f5c5285d0f65ef 07ae859677022011c3a9b206cc9f35d040423bf8b2ca0431acbe005e46bd8801 +134720 0b01220f73dbd184d6007e8bc1ac9b43d263490d5791c4ec05f11faf81ecb918 ac330ba7c86a553764639b06f77b3ccd2acb4ac4004dff2aad1673ff92aa4da4 00002f78de7faf5bc93cbbd0d4c2a03c7a5a7650a0bf02ea3ec56aab19470b5e +134880 0a1dadfa39a9171dd08c2c67fc8d7cbafb00e64b1a0f40f64299be0f65ee09f8 1c77774293b0ec23b6022903e43e1564751e758b1778a42d64c614d88ace15b3 0000a5f748f5b52fe38adeb9bbfa5377885baf51540353f20aeaa6a06e9cea6c +135040 011a578577a354e6943844517840bb81900f0893ec6069de4a1531556d9cf712 9c92c1e8b1c89363994c8686fb0d18be88929d02d2034fae773efc12ba74a88f 0cc15bfab92e34a25a6950059942fdf8dc35a3f77f9711551b33807393e1f32a +135200 0cd8442608edc895122bba14277e9a05a894b8e78257ef1c13970cf3169c79c5 a248e51ac3f3e518181dcbcd9e5e0f0e874931ea341b5115958af7d77c5adc58 098974fddf5ed592bc1fc5c06f46e1f888e5425503bd7135ce8d6ed2f44f63e4 +135360 006183b7e17e6e4cc9b1d2933fc566feebde4b05472bd261a138c1bc87576b1f f8afb356bea5ab7de5d1a5de62d59857040d93f7af4b60a7082a556937ff2e23 0b24335d4e08eb1de73b58f04b28a99c9ba0f608b997691567770df578616ba1 +135520 0524559fc6d0af801d501ba97ef1d28b87399adcbefd0c1b3d6855a24ef92438 36d75272141bdfd39bcef0d5cb0f834db223da0b946fd27b3f1b358d48c36db6 000099ad3082d1eee50bb491510b506e126ee9530593a2cab30bfd44208d54ee +135680 05c6de13cb8ea4d5a14b69c21c4688af2dcab1cfaf8e9dd4a8c7c83cbd187132 8bf73b6ddb2707e3eb77e06ac6903a7535828d775ecda9bc9f2cb7be50218d57 069ad46d0c6a2c804d8e9f7d9dfccf9d1beb2f1abc9de0fc36d6b1e41fe9daa0 +135840 0a5cb92854780381add64f3c17c266cce5a134d88718b711d49c7cf7b7de41e6 7b979b24829b7e1fea319ca8a5fd8cb7d4e40f77dccf28174fc0502732de30af 08f36a4b0d9460fbfd20483ff752240fc104d486d04e2fdd8a64f504c989c6aa +136000 0001069f355b1ad80de5c2a2516425e5f1efd134f26de28669d168309b84bf7d c9957bab9b7ba6b955dff6ca73df21993abe018b68b482d644db4bc268ba3b0d 00010a052cf8b7ba99d3e64b3f9c47c529cae9436293c293d339c6a37495eeb5 +136160 0b49a85da34e2b5db7157a94ae1629cd66e278abb51c4f7e1c008591019b8674 89eed8b0290f3b21306456d3b6203113a4f263478b399da221d95766c712204f 00013cd9adbe525451472c9de3cc1653f9eb0a2442b59fb4271ad4aafe46350a +136320 04fb0d82d570b43c91873aa2a3f7ebeff81233c1a8ea6bf4bc48f77928ca6b31 62b76769c96539d7948c0ed630ddf73bd5835abb468ce4afd93426904b1c3b79 0000987a519d5a43c28ccb42ee31f924012ec64885e3b38149a12cd9b96a51a2 +136480 00007536439b36322582a4e90294c48f365219220294567d0257b296cb076e87 bfab66f16c6f787e66ffd4bb76e0c10777ce22f3a27b6571ddb6abd8b3fbb5a7 06d2706b0906c7c3712829b4d22cbfa8ab037c3dec46c819d5c03378a5652ccc +136640 08ff787db436d15f47929361dd5a583ad4a595943eac0a3166396ba303250f28 dd6be0f7cf26d0b5d27efad7a22fb06eaa4143e879a120953ef423af9baa20fa 0585771d810e753eeafbdb5e354aad83386aa98fa2e38a64215d71d09d507539 +136800 0d41769e566bf971ac1a2ab47df114585d947bd80920bd016559a510f3183cdb 4d9d4f4a67d37b38f9bf7ff04ed7eee386b5d029fa6bb9deaf48a5374abc4738 050a623bbb6718a2877f8682afe0bab190cb810ba00ae9b7123b5573bd0b9a97 +136960 000003163dbc937ace26c8e710cb3d4ffbf57afc50d2f5aade80b078364b94f1 fbe0f964a61c6f5fe64d9fd8bb73882d46d702e71e7276afebb12b47781815d0 000073c162a781c29b8a7c1960236897a02c1a3a8c78f0291494b37ebc4e1bac +137120 0243d8c2fd82ffd3486799efcfd1adc8445dea8f041bfe3dc4611d471e6cf64b 6731e7415524a14e29a3f0150d123909412032eb1130556d5bf71a263471c030 04c6770b1d5c72ea2b45c6106816c4211685d19d2deda51bfb8fc843a1fc8f01 +137280 0b2a5b151c5cc41d7bd5f9b3e8104f0d09fad5d0dc5fc79a144e2c7c21c981b2 ad2cd0af54846f6dfad9ef37baee4bd7c6b18de268653b2222e5a42a95e7c90e 0d8663a67a5560afa8b86c45a500ede7fc4cc0974ae82fa1407f72f081493c0a +137440 0be4142ba7e06cd5b0f1e7b198a260d9fd713ca7dabfc388f2cadc8b736f77f5 190f047a5dfcf58bd5fa7a868c5bcd169eb109f82fcdab17321736cde3af6aa0 011cae96ddb9472763a88b58c6728379262a0e663061637e743214b101fdf918 +137600 045a838f638cd02a56972d49c3e35a5fc7ea0181617411e95b66edc5935c0ca8 67e56b6f2f97c1668ba76ec07687220496a0f3d3cc11a6cbf667254622eea6f4 00dad44b45e33c849122b772994c969eee78c2729928dc70f87a4f6b36f7636b +137760 0000797d5b19eba6b818126bcf072aa543c7ac9095b99671eded526fffe8c203 432d893f11723f044c2198bf89daf12dcd5a24b374bb46a6f49cf87d97f75d4a 06c22b09c8803127432d031d85db712ef0205747d088ad4282a2003e53003aaf +137920 0000471ab4e9da17d2003252658d574955c0e5e3dfee6397041c996b9a80a9b8 ca36884639e30e5dfeaa08ae78bb834749ce0c960fa5a18d60d845653543b1c4 000092c74103de6f94338be3e719caea01dc5abe246a0bbedafbcdd9f7dc8b90 +138080 000058d082799e0ec8cea5dea7ee95efbcf2f4baf39bd419cec1539caa1877e7 b6133a7ff056494c744aad0b9181d9ee14043baeb0920a7122e3beaf486a3c46 000039e5fbd49e7d744b4051bdd85d1cd4135b6c18e4fefa3778611d17a5825f +138240 0b3c8f54a6d50deef3bc7dec6c8caa378f0becfa6902627d32c63c5768c7435e 2ad8d3b92ede177b7f83d369274326449f4a43657be3f23362315e08b45c153f 08bf288de53756066be3c2963c00222f0df1857c988de96d78719a53112440a0 +138400 0836f048b0c38d1f903f720d1727f964eaa56ed0a60972da6ca4fa1cbb27e69d 081182924abda754db784a724569a377f9d3ffc1a3168c74f8569017378dec7b 0000991721f807d539afbc3b69554a1b414263f70e6a3b6d1ebfcccfa5d6c7dd +138560 0a6336a0639c45a34380fcdb49f72c5fb823c56e24d7b5416b609eb8643e4cff 822aaf46d43decf48d0aef18dd06f8336c8c30a142d790d047665ca6af938313 086e5ef65d2eb94429a39b71c9e294e1f55dc2b73c71b5e38c76a0d08e75435c +138720 0000b1efd8795a38cffc8a5e7ff80709ddc25e854ec4bb83fbe79a8e79399ce3 9be30471c0bbe7dfb52f0c222b0630da001c0b8db802d447a22b95b8da4419ab 07a417dcc68b33c15c72271e58a19dda7a254d17e0da6b3a2ef117824bff40e6 +138880 0000f2fcfff2868c764518cf41c9840a161980f5dcde63934ad559ce299f0b37 cf9ac70485a4a9ced5b8c79d7c50809a17f5d8f1a72d17bdc120734f54fba10e 0000e68f6fa1cc7611f4b909285267ccf42cc29ce73a83ccfa42c4ee32dab8dc +139040 0ec416e5b6ce853f7e5ae32fff9d6db35363f8ca986606f1b1d7b03d59fc12a4 01b00343e14b52e9934c71d8898b13ca509a193d9929f1c00909594af5508f8b 0cece5955c28d38b4bc2edce7ce2711acda26f6922818e8095168e8266ed1aa8 +139200 0edb079a17aa5b357dc84ef181e570e0f65b6896c0efed45ff38a0488bb20e2a e789ba1e6cf322b581c1b697d8298fb240f6ed4738b185936e7144625c9c83d3 038e96ee4f3708aa77c41820b9442e2558fd75290d24e6c5d821179814a4c8c4 +139360 0000bc1df772c81052142c18d0b5bf00f70542e67cb29dbb582b12f04d2e553d 8438b0bfe242af365786039df7a8ac7eb0ea724db3e262a3522296714828a158 05e9ca331846b7a6dfe10be3d29660fa903e5ceaea2e3587335b830dc810abe1 +139520 000094b503c48957a23ad275c31f7eb61c4ccbc2117ea16bb936e88c052590e4 2aeb3e6d02e07233473f1b7dcb461c24a4e1fb74452c6b227eb2a5e2f25187c3 0c8b52de9c6d3635a4ae48afd0abde926ecf5d25dfdc8ba45efc6766865f67be +139680 013449bbffc2289e47f50a507114ebe5b977ece2f392d036a4f42119c02ac1cb caa12ba2288ed38fc19c342780cb7bde41d8bc5995ebf31b6ffea72a067c2062 08743d64f73a75509275e89ecf89b5a7bf87bb2f1f06b24503982ce74ffcd729 +139840 0c54b4c79fff66931487b74214bd38fc299066f9cadc073676018aa75236380f 3fb20e4b2ce37c5e514d89344c5c3641d216b41c5d390e4d4b3c9809135254df 02a842e5944830d2e41cc61f22b61fa7ec106474ef9fdc326a38ee887151920d +140000 0e6db36fd8a9d1b7baf359c8bd5c76635d0bcada973a75b5d2028ca3baea4961 5dc2f9c8eb70c60dbe49bba7ea71033194f30b7bd56b61910c31f5666fa56726 00007089fe4fb6b73112ddf55c225a413bc0fe5d9c1834302c545b07f2ec7497 +140160 000109434587d9b1ffdf0c51ca540e0654c6c3f5c6a0e600ddc80bcf6b1c518b 0f43c684c605a059a44f1ff30939d2ddcac33662f7efac26b1fc740ec4fdced7 069acfc4718b2337b39c97050393e5878f1c2ca7aeeab8c435f7707f80583ac7 +140320 037a3f92fd14e19213f28baae04a017551c7c93dde02cc75689f419098955736 46d19454f7779877a96ea7acdec5f0d6aea150fcdcfac28c1b4dc23fb52079f8 000117b7ff2c5e1454dc5b99d7b5cec7bc9f0f04f79ddb5767ad57fd33080db4 +140480 0d692808774abee13643758284b575f494f85a968ca7b85c72a258c26b68d2c8 67a1f7093defc44984c819f81cc64c4defb00208dc8687852a6d7e7e0953f421 02473e93905576ab1e8dc7855a26dc3c7e9a004c8ee0f79491e3a2566fefa918 +140640 093011f938a265d1656912720f19cca4e075ae66dcf3effc86ff8d6b6d26bd9d 29ee87dd0de9ab10d2eac56c6a5d4b3a54297a43e6adfea97014b143a9ab2d26 03bd6d5ecacd7d05f99246ec24a15dabda90b2f7491b970cb355c0ba94246429 +140800 063782e11a63f50ec2797252fc39351e55a533f3503b84827f0a2ea55c3cc0e1 6467838d37d82cf79ccbd874d2c1b178eb7598eabb753959422bf76b35078cc6 0000317d34e6b70e1137fb5524ac3e963201683fa54a78e11a6bdbe3f88ebe62 +140960 00a2f84dfc9ef06932e6d7231d222bfe44aed8943189b9d578cc252d4ae52843 ca6ef901e036854fbc4db728f98a9a3126c72642768c995bf42f2a4398657f3a 0000d04cf7f7c0ad2bf50671a25ea3b346494f99ad9eea7c1c9ead90679bc5a2 +141120 0b45639fd451982a52c64fef7627c1fa920f367b115788d8abf1984d8617a963 febe3d93f02b67fb1915a28ba9f25c4486bd55fa5fa13f3b91b4b8777b32fe2d 000059b11142a6324d27357860174a5444c32bfda214dbbac2e8e4acc11de559 +141280 0000ce759bb7113935387c2b9120cd3aeadd432af869f754572c2957dc6ee892 b3d9e84f5a58e2dcf16bf810727854049f6dea7f2281d5efa7affc325f4a9a6f 0604e190da81ff908c67be369789e6c76ad157859f187c7514b59cc80734774e +141440 08ade26db04a903493300df074a55ac85fa28f6cb7401b0ebaa0103c1384f746 05e9281f8124373be570b6000260be91a8e39f90f285300239c52ab113ed0852 0e35d7a8f97ef1402dbab4940cdee64a4b6c2536e7a277efdd7d2fb404a55d3f +141600 04ced645d03b894896bc539103b1d97f710e624a626a1201f43fa504bf2f6af9 39344cb3f0764ffa57dea41db83a81d6da78cd41a3dfcdd91fff9470c0f4869f 00008df414bf2dc73c9a274a8a642a483b6240e783b06b36ddb58a7face7f67a +141760 0000e09729cda6ea281424142342d11827ddc2dca76383d639a456332fdb20d8 642583d4db04aa50e189ead817a8f02cd0798a45d2ddaa02daac636a74f71fe2 0000cdba2c9175450314f0463bafeb19e680d47f8bc045935412df7478384724 +141920 00000b08cb188acd40f4141acf00a68d0988950636d50e11f79654e2178d813b c0a6efb98215b6dfc469dfe1adb515aabe0daf413a856f7de78d1b76e617bcc9 0000eccbebab690173374311d1d284b487a7c0f9cfb4ea924048b5e57794f838 +142080 062af4a780076cfb85a5ee53968cad21cb51b4d9d981ff74e90bbd5902bd7add f79ca82153ab044ec8447283adb246d3761cbecf6b765f08eaa95033ee569d2c 0655b3750d24d029ba996ce0e9c706c38403943f20ccd9e5fed094534ba6239b +142240 000053ef05ee6ae968451e4f5021a5b68c51a825cad092bf1525e1ed3d9a7ed7 e65a0db2a712cdc7dfd04443b61064d8cb06e8e136d3ee17a2776e4cb73486b3 063397d4f826d6d6270b3788f870f637c0968fd1dad599815a7b95db3b0bceaf +142400 00007c120a6dd0d9e6bfeb450ddaba3db876a12cf4635948e915fd032a63a42e a27a36e2811336af0c4e1ecb16b31ae3b18a7f913add227433d69407c3de4a51 032ef4637897e63b7b4700974f9a21141859954303e40621fa6c89dfb8f10fa4 +142560 015361d5d3c05e478f915276cec9521c294e1ab8b8f252fb6c7d7f5acb250754 9e47612044f5b8953961eae6679398f1e4c8d6530ae0454af95292abd6f4ed1f 00993c563cc1f6906a02c560cb6fca09590a269d00359c462b738eb51c624923 +142720 0eb07551f114ee27648714d33b5aa237bf93826d2b75597d325e5d634ee30262 2a38c54fbc88624948f357f4a97a0de9ed39fad6981037bd46226a6b0b1fab9f 0128206a2e283f5444c07635692eac77b46180b6a2e243f3423177f376cf9837 +142880 04759c9fa8d010816ac57a9d7dda7e9bf2a1cc05e1c52b4a94095c203c127bbf f6d118c7d696cd3df1b443237cca60024ea601780a53b77e576879ff740a0909 0000c31132b06112feba119fb2850a0abed2dc63e58f53cae070cfcf6bf85867 +143040 0000b00e25dbabbcdb8c7cc5c4e6a37f8b8c706353ccd9f02275089602174d78 f8f3c9bb7ae37aa88f99a8517b23a6049a3c0f2e24725c5d607056a2599be0fd 00003402339d5c157f30c70ce770834340a1ea6691f5cc2d3ca7226c9006e839 +143200 0e60b99e29f6145b043b7ba8b1cbca52c118f427b917d7ec29b790248fe66c9a c05415fd07383143b4dc5e306662dd274fb2208c3a4710aa5cfb118ecb7e24c8 065a1e31b43135871d56fbb11e47d10b902deb8c961a644419dc69f3e7ab4992 +143360 096e5aadebe7d8bed9599e95008c25e16277e4da04b1bf0a1d451ccdb0992e92 ac44184c9bc44d7f0c4b23843cfc38b6cb03aa2e9e2693c2fa5e3daf0a64ec0f 0000927403d012c66ad4f5310618f8695781571e1733e8bce4aeefee51884635 +143520 01e00e29f03917a5042e7a85b9d1b7483c229b948174623a8a74c047c217fc96 f1295ea3ca1f8d41a3b9117bfc959ceee660254a1ac42b5e16733f2f80e09554 01c8b0cfa02e8eaf5e61be56afcfb98aff238f93274b27ef092e244a65031244 +143680 097c443652e62b6a3808d3f1e977e3e17dddcfa8d26ddbde3384bdb9e3e8adaf fc2a354efef22b7989ad2d4c66bd4bf02b045a36e1e1fb083be17e403835a013 0e5e8f67170fa4ecb420b82290ec7bdd4094cb2fd078dac89c8aa9b9f4af5264 +143840 000079cf55aadfb01223f1b5b6563c95d8a8b389c8519cc37dd54a4c81593b03 0c2682b5119962860823359ad163fe8ff545d29f5afd7385e98740ed6d340696 0cfa996d032d51ccb9bf7a1b5a956bf9fdd3890a77195160176bf1b626e9ad6e +144000 0e56b7e58e0becac41f014c5be9b5e0def170ed46e03e277200efe6fa5b7500e c101a89fe25a336cd5679f220be338d076d5bcb2085df7b956703a9f7a606fc1 00002705686fe85418748ef3e74fc804954bad03c0bb9df1512cc08098c4f1c1 +144160 0aaf7e549889ec2bb77af8eb5153cd0cba00bcade7d3508a43b38c19462a113f ee529247919548f20b1fd2118541aea5d6bfc11b63ee2cc1e1793916d41c4e94 087ab10aee57352de1d5fb8a0f8508c9360145122c5495d3b92f2f5c36788b83 +144320 000066d8da4739a9c66b95ee859e4947a8883827cd9e1961c7ae1d47d7f39ad1 43046b08a879253a3e20a3edc2f5b6b373a1e2a53bd7c7ac8a6db36076dcd2bc 0d32eab7a8319b02ab984e370941fb8be1a31fdda2a336a2d2921f48e2728a04 +144480 0d9cc7d31722de1b3d49502f71ab3a3abd719966a5b16056c62f194953fd1ec1 135222834c12387bc9e65f8c2c9526f9da2ac4d7ae144da6807b0d79b9fc0fd0 00007fa9af394e8483798feae7ffe6b73dec222a10ba9cff4955412ac17f5f6d +144640 02dd95beee11ca55cd655a194d47cd942bc4c3b5f33f67ca4e642ff483edc6e4 2b2b1c3a270da9c13bc30ca5b628558c2322e31b4ce87ff5c9454122907cbeaa 03c5560274efff2d4099b25548ab1d3edfd1bd8281f09bbf7594e014cca90cb3 +144800 07e8f6926ef51af69ec9e5e178e20dea03bd6793317f8f2ab2e97120727ffa1e 60cf58797f6f9267d73cf6dce613e2b10dd0b82e7f8785d0e8c645c0030c62d4 00002a1f4b594a2722ebcbb3385919a4bc4edff9bac0d1b58f81752b9470da4b +144960 0000284b29a2628c270424cbd207e75617997a8a56dc57934b5b03d4f6296902 66129f5f465e7799b175f5979e2c1dd88ca1312f124ae61cbd4c2c5c8da47075 0db0413671f960660436587ee1e9861afb21c7e2ee78272742f7294ebaa4038b +145120 0b99d4f95068036945d2d59deb4fc5f22af31e52069bd54f17cbe155bc060a9e 7327bd74c7c2a4a69803c2a73f73e0f63ee2420f01db36fc18f207124add978d 004eb5e95c0c647c0913b1aa17d7858fa9a855bb034fc9fc99dfc259b8223303 +145280 00007d9894d24e1c0ae8e67b414f8f55a6d65b85e483509a19e3bf3e85326de0 5b834bd442f2a5654176b12f1de3e4be5a84a82e73309bcb49baed87a93f4a57 00b33ad336e6b34f3e3015bf56aaeeb38f9ce9b194ac73474ddf4e935f542b3e +145440 05de63de3f30ecd7b4e62043f1286fb67b867593d01d96e28037cbf8c370bf6e 722619c0e74e3d222be931fc2edcb4c7455227f1df57c27219f4f3071a85e5e8 00008dac27bd1d69c08dbf05c6f02a53c5c670b3e0782d8f4b6e36c491643b27 +145600 04401bad3b5c5c07b19027bf2030fb126b8683bec0ede86678d431c5b6306088 00b9402768147796cdf30e7e64a99bab437e9a72fdac9f89cbfd6783a6c02d38 0a013b7b7ccd6b80f0d1590af5d24d7636402c378740aab7208945d75f549ee2 +145760 0000f79348dd8a9ae1aaad1600b6cf9577f27fe0adc5daa59e57142aa13e0e59 0a29f45153fcba76a8db9edbb163bb9bfa7aab46fb7877c41608c919c0684d97 07f749424c2efc60e212ecfd06d58437761c86eeaf588f2cd08679d302672e89 +145920 00002e80ab868095a77ed94749d2386b6050cd1de31c40f1872ee5310029c1a4 ebb25c4209fd3113af6d6f598408fcf1f7ec1e7656af4ee364ffc59c8653ec85 0d3fb7038beb751da6752ad06855df70e1f9c2d1b26a1311302ed2b11ac63e36 +146080 08232c0383e9b3107c829e92746ec956dc4048f429b18c6def0f209fd1d2d22a 4ae74d1ef1b7f9ccfb7b0e2723b6cfa19068afccf7bad2ee5b68f22e007f0f44 0001cf5f2dcdf77e0a246880aaab50f0a2d2416c50621f1ddf3111564596c4e1 +146240 000092fcb3d77f03fe020de87c683a3e503e5449048fffb9905b3bd198a8486e d03e93d1c7af8f688f936a448e6317a368a0611368a7ad50b54ccf410a766bae 061a7210616613d056ecfdbe4af60a7ca20a8d29a0ffa5981bec219a4ff28ce8 +146400 09d54085014091dd0ba1b6a7c6921068013d0210790dbc55e0c24993aeb5aa30 af3b23cb38232e48ce56f3b00ffd9b61db99c4c545f3fe126a4e88fd6869ee98 00001bb10c1be2dac5b36dc1d7445cb8c35b2fea4bff3685ce7655e67eccadd4 +146560 03ca7f432d5212b7382807a220d529727f0f538f603c576cffc95620d6046aff ca69880a5c34b1b365f68e2829012760f04c594b5ce36acdc937d308563549a5 0b8e5523ebb803dbd82f4760440f04f2266858394eeacc64f996db8da308bf99 +146720 0013ebfb2ea4d34fc86f57db5a1d790bf756167601de8067aeaa41150d83e8c2 45c246066d2436ac6a0f6fb4e975b4de447892c0817a0f9687c6c7403762df11 08970e1606d0f3da19a0a68de17cb0e569222cf6b58714e65261e1ef0e6c5c77 +146880 0d6bc0a27c8339bb1e1a1e5ae51590bfcb24bc35e555c854482e13339b84544a 423db02bea46857787284e388b37d48374704ac82eaba8b88e8dfc3fbab3785d 0000355d78de9b94599507426cb11e361438498e94c4d87d6cc5a0155bce6c65 +147040 00000b0e9023d6d7912d55756500bae8c35fe1484527ea072278a2d6c71b4e44 35edd4192cbb0ebfa26a9affe8e82036b7450ed503077e8905e2917532113a62 06003a4cb7e497ab519eac85704fe33efb3216ff73fad5da03581a8777d12569 +147200 0bb9e7fef3ad2ce44b37ec0620abb960630c4f2c94b154ab3c96307c7b35cc18 3ce156e40c5423cd900ec88a4e92e306dc4a23c6794c9f468246aa20c2fb7759 0951aaf807be0b553f52cdac84e4d710e0df1f5d184af38676b130b2c4334d86 +147360 002f6a99feca5b44e196f8452906b5441d71e02ade5c5f59be71aad22db741fd ec975f392ea6cd77a75ddc19c7465e9a9e2b80737690a730617e1b3ee68683fd 005e5e191f40a74bde9a57afbc42fa99ab807221e06f303261e28eef6983c5c3 +147520 06b204152a2ee2489674534b317e7a92d6421bf1a6d78d368fd1d4ddb8c3af8b 8a3b1cb881dc70eb83dab1f32a40bb82c5467faf30a397a6f2b822a8738baa85 00005833372d8916ded456c9a0c25318fd35f58e8248c868a49745d63d5da666 +147680 000097afa30811772ee74fe593265214c6847d8ab18b63bd19fb09f1af44bf20 0228c2ca309cff044c658eeea2a7e1907d88ad4e4278272bffa5e96ad04e7fcb 0000d28ed1a0ada4bf32cbd89204b36910828dc9668aeb08ea2157e539cde543 +147840 061bb1b7d597f56dea7f3d41b97003b9a21ee04c2652ffd5a5000eddd0ffb9fe 573448993027630a6ef6f18445fe4d4612e00c666dd06105fde0253ad61f59b0 0cc9b6cee49f5693c08e1921bd0b69843fb7e07820cfbf4816325f9963f4ae9f +148000 000067b2f1a871479fda169211ac8c6f0966fb17de83fdd3fec496549742eef8 a3b772c672ace97ba647b8600b19edbaa23567a709d29735af9ed7e61e451ccd 00007f0e64b4d9d701acc1164922e16b17cd80f8f7510a46bfee8a52bfa76d53 +148160 06f386d1a9ab788b5713d484b378c35f01fe3efa743936505b71e6bf761051e0 12c3de173850d9970ac37b39ba62d3a5c6d95b1be1b255c939aba22e5e093b9f 000069205c5121493823deba9b67686ffd6735bcc74a0d31f1bc8ffbf7b204b7 +148320 0d6389ceeb593795fecd9ab57156cbf938e8b302f37e22f1ea72e697d0828349 ed69f2b02e859df4907b3782c6330d9ba5eb2728ced013aa380f6cb0756d3f09 0e4222b4727aff24da9de0ae4284c6722e1dea0423dba544793871390a381061 +148480 098e35438a628fdc6f9967ae4ff3704ccf4eb15e5c3623ca6e68ef462d7a775f 29fca665f7b8e0eb49c9cb1a94c386753c3db293f0db1e3936c5f423f7141186 00001c7606fa15ddaea857b3a67ec97d3cc21a8b842017d2d6ea18bd6b9a8df4 +148640 04eea7a9002f342eecb57ed7a29ece3671df637c61628c2d58df33f5c62da1be c4d75a699258ec9a64ccb73649fed68249d70bc85b63bf6c2008696877ce076f 0655e5a39351b15429eeaf18d6bb70b846a81b248717dc8d128d4fe48fd47649 +148800 034c1ff3a78113d3c6940f6bcb24d9ec5aaaefecf0e5ecab5c64bd114ab68ecc 162d4c309fd2273ac26260a9fcbfe2130f341652722a8f368984cd0ec82ebc01 008e4e6423203b1ce48341b1afd9f04b68ab9146f253902055858d683d2b08c4 +148960 0b00f2bf09b3dc9cda4a8b4a9529a534122c5ac6ba82aa37f3499c7380e83eb3 10ad7f9290bd2684d70dbe3b5db757d55c473f8c018b420ff8bb1249d6dd5677 09d67d53c9abd29d86de47d5bb8b41f7bafc2ee22eb5398c442ed981eb8e9ac1 +149120 0000b9910704c360b353c27e0e546eac302cae0df71ec4c38ec44fb71bcb3a2b f2d95ce8ad88823bdf9ef6f07ea3380477840ce903f7953813db08d3c96e8e3f 0d02c4820294b9258f24f45f0db6e6d1bb6d7988343524db74a2b871bcdd9d5b +149280 0db6b1c2838434ed9dde40809b5811ed5f7cb546248e0b0239e78e5c26f52a11 e1d732842cb5ca630e4d881d824d63ba0e33668803aa843f640fd404a7a4b63c 0880d197c7b96d67d37fc179073bb3d47335c4fcb1d7f16a9616ccaf933df54d +149440 0b69494be694f3faddfc1d74ebaf0fbd8fd8e16ab0ef02ac78323cab61d13dcf c35f35322c1f558e1a830988a5787c7207039e1ddce1366a6fca6216306bfd65 08032d3bf9cd26f2d5e40366f98a67c4940a921562cb28779ed559677dc9d838 +149600 0f07f246ecb8a67e94213489ff1a126a3dfa15346b80f664b9affd45dca28c64 157e103417bc1e6b888f1ab1ffb90b6dbf5c1e27ee1e6041010e2742cf510c89 0543701ebf9b7b9b93c6087d13c9e7b016a0cbae9aa95cf58f233bf5839acefd +149760 0b629d276bd9d2d3e78cc84213e9b35b1396b182996fb0391c78b32cec1eff3d 177626a6cd2f390f8fd67fe69e99e3fabbc4f49064010b3ebdff97309f1de63d 0d70e190b02455598dc01eddf390823908b5d63993b34c01ff72787796918fdc +149920 005b96e7857aeefe649d52ada9ab3bb508980d2dc2fbacb992a6c9359b51966c 6650bd3143971f01dd260bb1b123592f5048c570076de4338080a7c717827260 08c490954c08b2154f6d10038b7ee7ece834c00147778ad9f20468a6f92fa751 +150080 0000ca2568fbf0158ee5719b3369c9febef16edda14900bef34fc15246a6dd6b a0e7bca0ec7602308f9f9b12da231656da469f5dc05a101a5250fddb213a5003 02865417a5ef5493eb3ca9a6f64307fce178c4840fd303c23b9455f7b65776a0 +150240 03a1dfef56cfaf83264d97d57ed0777d15d52fbfdd8eca5ec13bd7bb336f1a86 7d06c478e064919d493fe32e54a8533f73a4528698d4f76f85ce20737b4b969d 0000ccc569243393ada880f366013ebd37b2c95d471e4ceea68913befa0dde8c +150400 0000883dba1dbbec10c3bc094e62ba12c90d28c484accf86d9cd7e33d3925b40 e371a696e0377bb0e0e2e525e9a9e5fc8440fad293a11bb9d9070fb724ce9487 0bdf99d1fe31344ab6850c64cd89e32cd69182f1cb23d0994487c55492bc6f6f +150560 05db8992ca821621143c9270e8cd467021a2801379897ddb4ae0f55ac04205fe 68e6fc62546ae736c4cd36e0655815367af395ae6c4fba1b2ccfae396b934ea1 0000829d583dd753f78a701012c8054dba6e177174c4b29ffec7ad4ae81cf838 +150720 0c3302e719ebc81ac4450b8ed4a1921fb2e747a94e0e1301097d738ff45836f8 a8756649b3834aa52fe86d09e3fa2d212f3e449b5b5163b84eeda9f653b4952a 0000975c53533efd90cfb544e112fb422777a7268fdb8faec66c42911af452b2 +150880 09383b0c47c5ad7949753dd2a2663ddae43ed3d80c44a51b9b03c3aa2b98e2bf 84c84162b00a5c046822e39253cf79b6e3c4a961c2df50c869be09060affb7bf 000010abc387b00e83b01ed357ea9f9aa49101b7d3da38a3f8698ff851892efa +151040 00004c1b9cc7e4aedb76492a565ce5051483b2ce8a71e33287a0cccc5e072081 9f3ef95691402bf0ae5fbbcd72614e9a1197fbbe604fe8e8d74f1fb265031167 056d8db1faee1c1e5ed4ae14199c37210d50f14f029d3f31fdd5cc4191fb53bc +151200 0000043d61c5e7ef1bb7492146e2a6ec131febe1eb27916df4fe34b6c4583b62 cb2271de9eac61c0398d2dc0d77df0376c8cc5eaca3332b371803baf41d07221 0cc4b66bb34e651abfa0bab973def3f3004d6328149dc38f81f7467ec9b7b556 +151360 0cb85df87a12fc817230a44bffb48d78d3ff5d8e176a70b1bf26ad24dc38ac2f 7f5a26a2bbb22767815f54ec488bfed5b303d8f5ddc5fdacab72f6e223e9c967 0000403c2fc764a1a2b8d1e7b30365cf040aaed52aba4b9f6c9e630468d89c29 +151520 0b57c153ca4eebe034e323a82f56f00ef79f9be053f98f1743358065f54d6c83 97e6368a004caa3d0720e9ce93865ff43b1a5a6180830b98f46eaf25d3883d7b 0c416999a1e5481afb1526c0dbfc2b0d776d004354e5046933cd461b50baf30c +151680 0857d4f5691906d36cc9c7de1e373673ead02f964b096d60d9ad152815d902a1 85dca1d8ec48a56686798386cf9cdcf35572d423fc4fa51757292a24cf280cfc 02dc78ab67f61532f9b6b6f05c1acd86d7759f284289205c39b66a5685d19c32 +151840 00006ee4812fcff5d841db75f56b6a40f1452bfc22e26a4762416572dec02710 a915ef0f8e398c36ee151ae51937f281a97325b97f920dabde3e6ecf95d9946b 0b52f10c443851190c0535d2b9ac8a7fd82c436a12a69127d779d4d460646cc4 +152000 0717303c4c1b2be760174dc9774f23f580159022c043de45c13e9bff56c040e3 d22960899aede72f4375847990f974650782ba0bfbfd2cca0c8d5b7e04112cbd 0000488eaa93c8c36d321cec9909f6c0fdf03f1c19005fbe3991c03739229ad2 +152160 006935f7fba169e339aed89a3149d73e13759434b3cc15823243194b96f8115d bc81e0f3eb80fca41f0c8ee1354450a10ec05b78311e244a926fb0ee5c966690 0d6e5dce22dcdc476418f6b706b1a13aeffc45774a65d6c694afbb7aff0327b3 +152320 00007859dcdd9dedcaaaee8b8812094c0034872eda568f722e6cea4090504d64 e13ca6ad5321e15e6712575934b1fc9f5ac285fbeeef381eba09139e3b1eee2b 082feee330b2ecb4909dc68fc228da2062546cb5858dc431bcfa9a58a2af3015 +152480 0000b264f4b5777bc474b0a5fa5ca60bc8347c8efa8f5b432ffc702fe22063bf 74e3aa9a56087d35f40bde14797ec9952c5246a30253252aa9f9835e33acc2a5 000079ff597bbd7cefbb62405103a53df18068f2b22150e989db3c7783517221 +152640 038291d4d44921ec240681dfd9cbd5a522935b0347735fae5b4c6fc701f0518a 9d8a8b5802bd9c7da4c4e88b1bab2480e2f37095b47676eda6d453fed6191f3c 0001225dcc2379504a7e493838ba097cb913c471ed46d8e09d43190a971c12b7 +152800 000003a60acf48675f52cfe9e2fdb728f4e459c126a31265434d5561f36cd6e8 dd49ebdf5b7d25537685b5c25f8ab301b4f3de0545593ad8c4522319d05b5df9 0bcfbe463582a7f413ce3b56933490783b9addc7060fc573e47990366cc8bc51 +152960 07c10969a946a9e5065d65a5c2f6a78ab7db0b777e84b627f739f100e246d5f9 be2380d7c825824e0908c34b3150f1900f2348451b44d50e147e19e774917df4 0a7ccbfc6afb14433fee4d1de526a50464f5c6e5e99203c9f08a1bed5e72a0ce +153120 0806bc1420ed6eb82675a61dd113389cb2442f8925da0ec3c5bba7ba3744ce05 0018d781f8cd24dddf455d42eb577733d90ad988510e75739b2a271f034ec58b 0d7f30ca0152e16cb892b0e2ced61a7383d000c01bfc7be72f4cf3d96bcd79b1 +153280 03ddcf30b41cd71798519e6d4e35a75518af6895a19739f1246a0163588cf40f c1d5942f6286e392eaaa4031de63ba63534ce2235785614ec272a9f44faa8343 00000c521c411cb7fa0b02838b4798ed04f61180756698d8c757b8a77f1eca00 +153440 0e5e21a22b6fbea4a6d59ec43febb07e8a4c0c277490f4760e358e9eb716c207 75d80b4e054d98ac6a9c8f2f5d35d16274e7eb80c783028f2c562830927e70b3 018afb3dd2ac437591744b884ba6b337475a58767fd61c2e752ed229f58a52b5 +153600 000093a4fa485f1de06456c68c4adbe7efd7186340c69265698b45ffafe2fd90 226c3aac181e141d29d7555d3a6bbb12e47dedc3ce31fb97478164c790e690f2 01121b3fdb08dc93ccf35bf982997cb067ca694fdc26fa0fa12e381ea9f91c13 +153760 0039e02695b2849b43ddf958bcf09c46551756236274fe8626a50bccef000134 d9642ff770ed35c39e880522dc9b3bd3547921132ed55ca5764280b7768238d8 000068c1e0a8c9996f989a69f7e895440ac97c3a3d7786fc18833718c881b827 +153920 00009461832af995e1d29fe6708b11a3c31ab4a2fd61251d5c5d8070aeeddcc4 e0dca49795d4e4371fd74c9680a2505013d9c58c3f74c20f293f96ad29652fb6 00f59007ec16cb6334fe91c67fe915c6f78d4db056f3af3c0d5bed6197aab724 +154080 04873144a593fd036867e2ed5209483ee50d077105844f0ad72ad8cc3ddab31b 29c3cac12556f0cd3c5e7976f9e2e714ce4a504e06069e907c41eff55088453d 0898b16d7af4ba4e0452048aca7b599a17e42e4340625d6dbd23ebfc3b5bb0ff +154240 07aa2324436bf5456985d1dbe5423da21a4dbe66ee24c0a36cd89b32624bb2a8 348548aeca5c9c222fd91daee9f05e3c72cff1326135e374980999c94f3d3899 03cdf72b713378a8f33982664158ddd8564848820586224aaf8e138be800b6a2 +154400 05ee44aa96cb0ae2f2e6648ce62e7ca8a8e31f62a084567bba1f305e3e85b643 fbe18a1697fced0e57b79e8fe836d28d8153e664ec6653b641f373c4c3c0af47 0b4c0107ade0800cda2ed2eaa65a8b329be7f643e94de7f93e6d53d89edaf4ae +154560 000060b07a1c1c12ad0410d8735d029cfb97f15474d87570d02368b952af5393 7cb11c92b6aff48696c357fb4325ecfe0ac0de7cb08ee3a852ad0ccc22ba0939 0704ba81fdbf74510b136e06edfffe81eed4b777e3e88f92747c1016b81ce315 +154720 008a0d5145379dfe59b85bf3ff17c7faeca303e7b54cef58709bde75e6d2c5e1 a4d52dd2994cf37f1a76ec3ab5ec3acdcb5738f7b58f65f0b799831371d839b9 0ca58fe8f472bcd5e04998cf5ba68cca6ca5234753795e24e800148607fc9471 +154880 04e33dd6f918ee6a38b1d5200807634be0dcfe576e2ff3d72126cdc8ee9b6334 cc81c7b2d76352ff681721c1974ba21e6fe07e53d155c72f875933ee1678f72f 013c8a1cf83c25d397b5577d8157f5f5ad967241685a551bf20613c4012ec265 +155040 00007a4bb88c01744f4b975dc3ad5e969d8e3ba18725906f0357fd4ae6a83f07 9aaa1dbe34ef9fdc2b49ecdad5c6f8bec1677e979a35a1b15eb5a009257b46d6 0d5df97b67940197fe68e555dcc9be96669db711124d5e7513a9557d9bca9fc9 +155200 083fddac6645a1b8c1f481451c88203abb674a98690bc7800561c095655bd71a 8e6ed240ffb6bc977b0c876efa6a3e9880a1dbb2075849d20ce62f906498cdff 0673df732c48e3e5276c0f02d4e13cb631b362976f3ed054c2da563433fefd23 +155360 0e81f68d33c6b45c07e96fec5954c4101d715b15b1194ac993154c6775911706 56cb2171ec6374c668565e651eaee5198d08a479fcc64a5d6e8cec7258621f84 0000e7f9363719f5983a1ca380a041725499fc862476248d04e218d251d02e9a +155520 0ba2eccd3bc76210c6eb51c4b40d5d143a10d541ec77b36bb5a3efc1b6f43739 d1139adb0184c80e09247a6658acd2499cc26b79fb9a421fcd4b5bf9f2f5e23b 000001cf0a1f8012bb3d13a8cc9458d21d179fda895e965d1785a3294fd8d0e6 +155680 0b0e4097c810b9b8db551b5b4859fafe465ccb64ad84112c00182607d2e453ef 8a8741c381dba26abf8f13d6c0582358e43e6ca406f361819d1bb6ed964d0d6d 0a1d5d3b4431a18cd4190864d457672ff398265d537b3c011cbfc2af821f2f24 +155840 077b749c506a3a5ef9ca7503f8da37fff1d416509bb1c5f438c85edec6c934ed 0d9937fb362cd8a0e37fb61e3adcb5fe04ff7dccfb9237b45ad9ebfb79efebb0 0245657d2b346eed3519e0bdb045a2fac4485edb11ee300abc094ceff3d777cc +156000 0604b171a2e5e916afbd1331016a5d60406c87c5e22b70fb1812fe8248e2db6f b958826078973953d31c0da71f4ba6dbb06b0f7fe5b55e6f55ef59dff78834ae 00004f773f07ecd682c1c05b25b3e0ebe80e7693201123864b012b0c3a3332de +156160 00008c4b0350cfcd617cf0e94b3f9cb122368709308245a9370ab7ed88417ce0 51548121db7b6270e456ff8769cbb048a8b90cf89dcc29c2d89230af7c135193 073df134e7a21dd23cf70dcbbbbd5dcebb683acc647c3b3741aee1439ec3734a +156320 03b64cd52097fd75941d28ee152869f2aafda110098e2aa31ebdbc6e274b9f83 0b674726794c58291a69a58d2d8538e748160df17aa4b45bd76876e9ff719340 074a7514bee1eed928213cbacf42c9189d92db88415c48205a3bddf1730e55ff +156480 0ecbad387aff0e4ccced604a618151744b493a8003664c5a48f75574431569b9 fa33ebe8044b891d412f1239d84d0780f2757dac4d1171f950657977a2d7334c 000017a2b64e65ec4ecdbaab703c9ed86a96ba60548bf13a85475dc54bda06c5 +156640 000049067b71741e25b00c211df64e07da538b59663bd0029dbaae971806538d 5118a549f258ef6d2d51b7db45b33bb16568995ed32ae1c15654915ed2ccf60f 000045ab561908d69bc3b87b63e71dbeabb59be68f059e019e0fe6c30fc5ad30 +156800 0d6dffb1c99bfed69fe83d42ece8c4576297be252383a3b810dd443b4d8ffa6b 8214c1256e1fe3fbfa471433dd35cd4831d145b5fc25dc8820a9372e4741cb02 000019758dd0350087146189d18232eeacdccc1964cb59682024edebe7237467 +156960 0e221732245826d2ff5507cef2c8c046ef0e0458b0d396e157464869b32a57cc 4f295547edb8868ab8f9c2947dfee739a0721694ea0d4eef0a7907e188af19f7 0000a1adf4555ddd63ee1f3f1d8aaafc50100cf5dc598f3a87a05eef920bc947 +157120 088f9bc4e21e0f13d1bf43cb20229f10b11943d63b40c4726361c009e25c5700 0db729e0e9980c585fbb99e7dceda0af9850ed25b4bc08628eee82e47fa80960 0334201a8bfa370d1411c435c741f8cb8d1f0d333896df1dc97db0855d78c896 +157280 0000c8d6dc87ba36a2ba6a44f6fa84553d21d0b5568512cb34aa7dee1f74ad9f f3d7b5cad659e833411ac928935224375272c9ed527d211afdf30541fb0e37e9 000024e1b11d44f89060a787e10ecf6886bd5e7c9035f1634a55d8484200001a +157440 09bc08bdb8879d67001e874d61b6607392462db1ee07fe9ca83c1aadf5674cfc 9c76f284f0da9d94ac66a0c1c66317d85eb1a5afeb2dca84e5bdca933e3e2297 0d01ef74a7bf698303809ed8c91b6f2bac4f14dcb892da4830711c5e64d9da25 +157600 01a91c6e482a8bbafd803e17f169cd9ebd71197c0646b84aa967e9f9a607075a da8db6c4f2f28c8ff0d741626d1aa6b94125bc0d758b7269a13ac7729ad11844 0b482d1bf41689e19eb234d2402e6dff344f5c6cb8ed8f948165ed34361c2e48 +157760 0e7404f0f37d6320419b5341c2a5b7c8247b225125ab0a186bbf38da1a3bb0d8 f43d1069063f3a73cc12f986b5bbbe0e7cdab4fcdb7a697aec9c93ae1d3990b2 01dc932e8848a066a35005cc56740235368a7b480bab903cc57a201c735e5efb +157920 0b214e80387c3a23bcbf36ef4f162b7febd6c25c8f1ba5585ae19c78ed85e678 99180c40e9a21c69c9404f652bcb04920960f70619945415672ec2fc4902e6b1 001892cb014b44050be198174f786c025d959c8148ab7e4c5d87c5a2410c5e94 +158080 07494cfb5aa63e6d5724a96a83aa1f8864d3bfd98c293f61dec0d42da3671157 b998c63141a65d0eafe9cff86d59ba3c33cb9b9e81d95030ab56b8df7f72d6fd 00016692ba0fce8f66e2d72551f32285838b873f60da95078fa3361402754acd +158240 0000b370aeb2f5a15d0afa729f65fb94637a2f188e99c92b50aa7abd588c4531 b718f6283683255cdb2a146bf87a41fbf85ef1a85d70616b4fcc02c0538cc0cd 0000ebc2dc9a2043edf8abd22c40354719c3b86739e238d698a4ea56d521a2f9 +158400 095fd52168e3d814e17fc44329fcd7ec09bef76d4a32be3df75322318ccf7b42 4830e9c5c4e9f06c29e6451b49421b6ffb1dd32a21740b2ed8a639151e782220 081a92a8bd313dc69721cc1146631def2f3889e91157801b407e09812d567448 +158560 01d2336d82110952ace395ed4f9ba799de4e5ae26562efd012ee0cb8b5382b1a 1b720546ea92b3d37a1cb81244763fe3de7865a41f8bb6a4007034a9da445de3 0000b8db67b616e2192b2ff21adf21bb3b276b082fbaee18ee57b89abc813d54 +158720 07b193d2defe1b48fec7cb9a54dba8149235b0d3b15f4bbc4ae048d31662b024 2cde0a52c09e5216ea37999820f970081d55d14f3ebf0b3df69be8f744076098 02bf28e4559a5a42e2385b957dccd9acf10338906627757e272a0b3d75baa59c +158880 00002fd39fd953891555d3f48d625ead5a724ebb337394094dc1debe36eec867 e097d7edf61c1c8f97add60fbea96309ac5fe02692595f9085c7882b8cdfdb72 0354fc8fe6e33cb75a0df4003ba3c6b6c008e83e46a862fcadccc4420d847695 +159040 000016a813c8d06ca43a57daf31267c44244abd7249626546923057827b517b2 e872b6c3126043ddeda32210497a1dfb82e498308cdac3af1219e7ce17eec672 0c79636e66d800f9d0fb88b15573558bfc791c2c15eb3213dce58353dd41c23e +159200 00005d69e02aa34c5324986dcccaabedf65b1085f79850c26d8821dbb57282c9 7d1e7b34a17f07f3df25677f8e4029f336125daaf4d425f01385291b0dd32125 0deefdb3607666b6cc335acedbbee2aa11d8f0e3cd8bdde9f2d33c50dc73112f +159360 0843ec75590b7d3e58dd7ee3e5a78e6c56ad31a46fcafc6dc1f480d162970c21 67f9ac5d4340f7c92a76118565d03cff821f1bbd1352a2433ebc05983e8609c6 000077f3ba799826387776e02b5f3e4e1d746b1fe9bc97653c35b2afd7ac2a76 +159520 0000bb5e02d9e7790542518e0715d8c157975f7958c42586fc06bfcd6b034c91 61e32fb0a325612b96a9956478e3969ef92eeaf0a8ba3f78a8d572347710f14e 0a0bec7a70aa486425719e5b945837ac4798c45ae067b4520be09f664433494e +159680 00000d5fb3b6cda42eca7fcf71d09e28dde77705ea2cdeebcddd699c11e3936c 92d708b9b13ccbc76ca984367c0519c675bd0aaf7cd80fc8344086813f081046 049a035e95e164d7501da645eac20ffe1b240a5f9de2a903aae267d1eeadb9f3 +159840 06380d61762439070397f0123a07046837f3129e88d13f395d78c4d30d53a86c e96c7207fcab6761e5818bcb876bca09f84c48e0ac8881bcd17b4bbc363cd9e5 0000e18d35641c065815b2086248b3ae7a4f4b91c02165ea4ab18715fb4d9010 +160000 00003a09f26ae9fb7ebbfa3ef589b81ccd8909a82430f7414bc68d5a5a3316ab 7e3656dd6b96aaca3fc2f53ce0b70830fba543604bf43ba4ef8cec212da88577 000072884708b4e1ecc010e5707cacaf5fd21438d0e70bc0fbfeff14e729e385 +160160 0860f603c88f4eac5920340c41b347a9a65cdf900f7da363be72f5558ebd8047 0f25e76f65f475cb1edfcaf92416ea2874ebe9b81fa4274185bc11fd9d5b8c82 0b0945b4daecc5723da973c994475940e340d59c3be8d8ebcfd22fcae7236be4 +160320 03a41787ac63e232af42e9507dd077fdffbb6daabb704533cbc6d251017078f4 c4bf3fcadeff62fa5b24aec552368fb4c2c4fc7066065e917671b0061bfe1752 01c0fa6654e6e594aa6d28c1b95ae9b29f4ebbd3b76b0802492625ded6ea5904 +160480 0e4260d3f5c4c00e857234677150449db6cb6410e356944c5f10460e0fa46c8c d25d21926efcb221caba52ec0434467d633434486d98b49497bc222748c1e570 0000df62876a091decf756ff467a9edf37d88e7b7e26053872d3948be27c2214 +160640 000006d2cc319e0f7bc77218cfd1e4c46a3133a9a3b3369c6ebcd26071c98372 1a3a22f036e79da191c78226da6058bd4e0758724cdaa524e45c6bef547ccaf9 05b1919304d801b7eced7280b7d69555817b8571d71c9690e3da9a4d3f96889a +160800 0b4bd0523969473bc62bb3169178c79cb28deadeaa7f332dd8ffe79a6855f621 663da015178ae8ba4c3c8654f5f5e33adcc1f1a94c02a39eaa885df04338bcd9 0b38c15c14d0546e6991f29d5b50c11e639fc409d44be47e7fe036854d4f1e64 +160960 0d94e00b566dfa957f667924cdca29699d2329e2fe819cd4b97ac67a2ce4cefa e7bd8f5f931393c75e54067274bf1901639d421ee274da3f7b32bf3ee624628c 0075139bbef5a8d23a08cfa6f94351dc0f0ef079359248f21fd6685ec5eba841 +161120 010d30fad464d3a6f0d242b9f1d8a990b31403f11039e7d080f779ef332ad774 f0d9a1f5c218dee2533f7a2560669f33f48dfce5491469bb8f89686806951d2a 02406376884c7756aaf24699523f9dae72b7cdfe7adcdaec1f6f5b8a2d9c7c9e +161280 079ad7637d4321bb999c768ff221f7f28dc9b76852f748fc268e8c1a044b92a1 4cddf0f6022a216736282ed23aab93dc0f0c2bd40f484ff5d93cfaa404806c8c 0e5087283b31723dcb6f35025b0a3ba1f5ee176e8bd31ce3f1aff44cfc6025bc +161440 058ef8dea82bafee22bbcdf09c7c899691031b013233347c3467330fbd6d89e2 82c306ae5d0d7449a516169fdce1f63a93c03c23f34de20278a126cf5dd7b8c0 03b120aafba48f0210dc81508220f53f383d34c00a356705a4c5ea47fefa4d44 +161600 08d5fd9c8654e56daab8dd0bce5d7fe3c879fdbc22e1b358d504708a19c9a6f5 c533b79da02c19bed2a7deb6ca53217aa29b63b0eaa95cb24c91ea7148c8a307 00002ce09af356ba1b4aada46e9b6c19667cd0a9f25b3158821b1d00ea8a62a3 +161760 000036e8fb1efbd83ead2f7a62d8414bfdcd2c0aeb6fbd8120e6aca61a6e1e1b 401b4483819a9b2bcff135f3d5c32cddc929014db5007b1ba214555683bd0fc7 03e0bc715e38319dbbba243ce102154a843b0a551e02678bcea2f032a6b94cb4 +161920 00008f4638f3aa36b34006af9c6a9eb2dfbb521087e98afc5233af5532502a15 71a9d7e2686178b1a937f2ea0abd72a09588c5304fdd1e1f1b10ce2e1a080ba4 06b558812451e4d2c4f16a8923f67b6ca9890b0224ee4a2a5261e74931db8b70 +162080 04877cb7960c62d1d9e1df796830571fd027805f6c061c2c4cce1b32d25e8b3e 1ed241811153886ea250dd8f708711efc52e79678880156024dff4d9bc492c2d 00017e90e8f943fffc1ec29ce723a6efdfe2bf4aa536e448ae4dc53b245a7b2a +162240 02d6ab99c1e385596ac987321fec0d0209682c74bdbaea5c6080ea9cd3a36371 1bbee55b3e4e7bef63603edea8fc3bc413b327bf49248d4b20d8573980ffb1b5 05b32e1fcf72f137fc4a1ca1c02e3a1c570a73ece33037bc690c3974607c1f92 +162400 04a3a1dfb772cf6d68ab2ba7f2d389f1c9f9a8c00cc87f08ea53a5c99263fe8c a952b1c6827732a75009b0c658c3227faef6cd7a9c265c4f6e82fe69dae683e9 0000a4348e313d80a16cce89217ca1d0895c88349a0580686a243227d29b2be5 +162560 00002a81b75a6ff7c3174320e1845b465733c46fcaa27ba3814e0dcb26b7af02 0b8b0c090cbc26e740466c341da15950f2c7ff078882a3cb1214782971c74fd8 00007a6a9d78a004e271cc6b6d5d18b1b4465aa2707694e4ed7dca98c9cdf81b +162720 00003d811a948cb3d207e2328f9ac447855d568b7efbce246cf51e153f9aef09 68ff2d029da69ce22ddb7d68c8c3fef5bcb9b61517b07a785dbc5c1598b070db 00000759f43d32ff7e66b1ee7bf5b607cab9fd8042a22a37197eb3c8657bb57f +162880 000039543459dc2b1d5020357ca8e7dbfa23c48b4bc1e867eb6729f097f0e2ba e6af073bfa2ec76a6a4a5190c4d9bdb2994d17c25c2ad704047b2e99d997f6b1 0d13243b63c267a8dc601c45a8b96f274997ae3d654ccfd980b6143ebdf69d4b +163040 0000159700cdd518b5f092889c2186bc46aef84cc85463c5f362a8406235d0f4 485a253506049988156230ced394de787ebc875b65f14c08f94ce0d501b69155 05ca0489d05ef1ca236f19b8c810309b1a8596a5146c60e21204b73809895f7c +163200 0000dd187af644246dcf6b4769c58c4219adcb59e00c9ce1afc7daaa7a15b3f9 b299b794e060c522b171c418d2bbbcdc20a33443d69cc081f4c124f60bc372a8 0000882945340d7603f989aba70bfce6ef43e9f196099e3aa9969614213d3589 +163360 009a4ca5b608b705754daeee474f175ee24b2bb8652fbc8c9e2889705bd99c57 e109c3d8cf34ccf58b27f33b1610d1cf1bf49f7ade8993a50ec17431f9068e6c 00003bb0b06fb449c5beb4cd978874fbe8f7b5856957a70b88a1faea68f9421f +163520 0000b1643fece52595f0996aadffd2b0234159de1d35e49c7c56c691aed0f2ae 119805733d0ec7397dc0dd9a5e24a5f544a00a0e339d2db5acc0ece647febdcc 00001df9babceea3e1e4cf577715b7c86fd37c2c5ec1e2e0a52f6ba41014d678 +163680 096b71281b4e87a5487e555a1179dbab7466c45f92548f49f4fecf132fbc06d9 354c041fcaa0579e143c6ef6841c6061e6c9cb0bfedb1e2c55a0e85711fb3719 0703101d57dbf63e139b7805dbf7a4377ed01aa44c1249382cae0b0bdc47a72b +163840 02fa4d64bcac123aeeffac5cb2395e69b354b96b356199d53481d3d0acd57cc3 33a6dea60ac7fa6ea3722dafee9890a94ea41aa78d29802a3fbb7d4bd4fdffde 00013eb8dfc9c4ff755696d266b6b217b792bf8cf98886f615db88254c8c1d08 +164000 04a675993b093c6dc5383432fe22a1b420789e0a4f6391e8f08e1de855200abc 906f466c54bcaece4cfe55e0e557ba7df1b075dfe8535b4364cba9389b424a53 00008971932afa982e21ee727a2943a2d4794edd0590874e4554942ad397739b +164160 00002eead91d95fa2d67f0e0d6ecc4668f5604a6910d9d5d6e36c41f23dc4fcc a16929fe81a4042bbc5dfdc7687bc0ed70df380368fa5d898c431c03a7cd87ae 00f8a6f39906554aa8a8fcb7c2db955024aab8509cc80897440b74909c6c49d5 +164320 000076b68857aea526ca53b96cf5f193151cce7e4e5dd71c3dad462183b052eb 4004c7b82a5dd1e4306c4e45fac4617259ec7997164f10d16c9793a4786736b2 07867da0ed1a003d60d01f8b41097756ee207084fe93331f9badce2d7478f380 +164480 0000680664e0496f91b01ecd4441e40b649784cdec9a0a2a2b9782d1d85836e8 563ab8619f5decf347fdc62b698199ba0db1aca271534283f5a3dfce44b055be 00000bc7aee1436da2fb4678da67937260ecf33f7d1e6b8f283704de0839400b +164640 0000f7868fc6df55d89e504ca07a6f558652bb7530952fd5df2a871950481fab 7fc1e70467882a26d66dfc483acea4479dc87bb3b4a58deb46f43ac23353c7e0 0000ede1f3af93169df138952e19ee1463dff0e337f164f016395bd3e24cd832 +164800 0eb8d2cd7ab26bde008a9549c64ccab22c5ec62ad82db519c1c6c3e865dfa4ab ae0ccd48c8e4ef32628b7d2f7574683956353a6a7534ef27e121f8df355a4174 05b7a3cbd7a35a95b0f7ca2a8f0bd52c512ff3f73bdff02a9b93abe8523a7168 +164960 0000007b41aebebfbe9a69614c1361c3ec811ab018c63099de5e6425444dc4f2 a11c0f604255eba3a8d6deb8f7759885f5f43ac4bc75b62475a6866de472e73c 072f3366f534029d6c204ebb25c060b23219bceef48df00428322c4f689bcbed +165120 0000026d2cd3649ecf570492e41539805a5969f92eeebdc51785fc9380bde354 0d694a69d6f0ed64c6371b243e61c361ed39266f97fee894f28424606e27e719 000102549f88bc287d7bc775973589f18c31521db5f55b9db94799ba956a5a09 +165280 0a4717ce17ece44f0dfd02a9da76c8f91c553af24fa26c3867b7bcdd773bc86c 5c5ffe3e99d6ec1954f224001a384ec51e80840648ac7c5d096067e1ac772a37 0000018280587ac6487b12372c5d42d06db2c174944963f4e70c9d220f17d6b6 +165440 03fc5a828f6e92c408ff04be8e80a2307ae11db7c3bb52fd06691ecc4f3f4a8c 038793391c8ebae698f6f12221790b034d4f6ec4d9bbc6a26b4f41d8e4482fcb 000027f0859a367b850ed2912422cf469b24786fa5ada91052974178c01565ae +165600 068d5384ec37c297dd06cda606a2f64ccb306883df167f36a1fc125575ad8d53 69622d12a1daf4ffded5f2685ab5d3293a45bece20df4ad4a1606c983c4f3432 0000292b02e6c603d7807b23b66d034fa6dcbb91353a2411dbf3469f43cf4902 +165760 09a2d3356cc3294720b2bd112053cb62dbb651ee3d187ef9b6eea3c99b409353 f4affa4f87d15b37fe90baccfa0c8664bb766b9371d042caa8311dcde57edf37 068c91ee703080b55dee616488b8e498a454a2065c5cc0b864233aee2ad5ab3d +165920 00009dd8fea9006fd29c0b3561ba69c0b24d4bdabb185ada4caf52c2709db4f1 bf48c4af1942ef8f114f554aebba53fb390294c1eb2d104a790ab1e92d0d30a4 00008dde5218404212d2651ee698b446839b6b52b7476237a7395ef6d6f7b236 +166080 000087c2e21b756893638808d98103fe67443f8d583648452582590b0cccb550 0744b494540a031c540a799f62257bf6d198a7a23c2ec82c987da490f42b29e2 0c6403ce7c4987874e81a73822481093b2bf65e2755336aa520fd149386765a7 +166240 000031a7689583bd07515b21ec55aca1c5d8605ceee17a6c0d96636da3501257 f43eefc0d1be9cd4ec9511e0fe0fce68117c3372aeec39f520daa448fe892687 00004122ebb518d0c8ed928bb8d5e7e43e954c615c9ebf445a693e41f1da9cb5 +166400 000037a95216409f42704aa82316bb748c1f4d67467cfc3f5ebe8d893ca52b9e b46d7c382e016db0c1e93bc7187f38763f0a2669160b8901e75b5d08ddf45aba 080ecd6b7fe26e0fd8cf017339d047069592d28c113598e2c3d7cfc3a94690c9 +166560 00007066f889da110b4a5daa29fb67cb44c935420020778ba3bb3b38ddd8cbb8 bec389d960a9f0c15c78d63ec2ad06004758d8ccb270ad8f77aeb06af108b2c1 0d24bfb85ca9487725e8e57ae0c1a2f67e4e0cf5ce63d1deeb9d1a2aa3f175ba +166720 0ea4278e5e86f18243390801b60bf87990039501e76b077f1433a3dfb45f7eb7 62bfda57ea5b7ac6c5087355ee231b965c3a33d39a0ef4844fd35a52a1b667e7 0118074257d729e97e59445887e03a98fc347aecdb02d68ed5b2d31b64acb0ff +166880 0b2afcc2061714458f3339b5e46b929c4719519f25b589964f0df965a69a2326 0603f8022a6970b9287b866783f1ce58ac307faaaa10a40272943c143b188827 04ebeaea3dc27111a213f9ff14c51e66faf766ad2f19e79266eba34edf5a0043 +167040 00006d52b7ca21ff24dff0784176793a888b99c4be7c81fc56d29d24af1e3774 83e11367136324a90bae79746d1be9d36f2ba6c3a3146ec4090dc21e4bbff13c 0852915e03faffd15da5f2446b785f69473f0c881dc8c5b80496cd3e967b80c8 +167200 0c59d29f46ad04f7b420235ec95549b0d8903370ea189fc28ca066ad1732eb97 b8d233c5c5c821d8a83b0b122e3a18dda676334f8e08a334d7478965e3791da5 039ac11706c4160a79dcec81571a9f39ff397ae710527e97331d9d5525ba6ff5 +167360 06a4f7ad11dbf4197bddd7e0899912579dfef6bb5f0de0c7a0c7db4b55748906 39b3b88d4db22b23034b1a26d745c4366cc5c81820c8b03eebb61f9521b661fa 0e2078168914bb44f22afbd84b1243b48ed0ffb234d6768dec20c9e268e553fe +167520 00db374579048f3c896c39fd299ef6694728ed30ed6451dc410756d7ec7e7150 951d1a53874b429911f5f6cadc302481b1b747ff6460bba943ab6dcb720e7937 000036143dacd5388ffc1e70b8b0479710102f694910a6c8ba164eb085e449b5 +167680 00001390e2b2d3feea6d128da965df6df12a609cb3ae67b892ced7ec8790ab05 ad110161b8749a1d3059c674fab6d1d05f76e3507bfe374a4b2f99f2ab3b1f73 0000138116a2f5799d682413b8b1258f4ed2fc03b9093fa3b70a2c7c75f89e84 +167840 0d8bc23a245e8699fc210c9a539b402b98ed7141567bba66cdfe9a462b30b813 e13aff22a4809fc5f5ebe055544a6a48f21432c4db2783882adb52a678f9695f 0000308c312c9f97852d3f775c6081132920b49f0a55d3838ca80fbbcd4234b7 +168000 0eb34709e518d8cd800d9793152e1938b2456f08eafda26779a51d7b2b70c2ad 1244d08df3b3ce24f9098b74da058cc8de43bce120f113bce6f3ec35344f2e99 000056e34f249112d67c4b3fd0b0285915e776d74044fdcb86fe64b99a320d73 +168160 09335b1210e14a320405de18dac871418f35a95abd55e3b8f530ecc7272bc913 d49c0fd7118c13c0fe3594d48be128188f19025327757b38dca679ebd960179b 0e9c0c1ce5cbac50648ca81d5407716431cfc93a43d16536f338e55a6495da86 +168320 0c5dbad89316822153a599f6ebefbc18b80cd4ce18f34fce1d73527d1e540d01 a9d17f7b5f69bb5fbde78a89ae89b8c190cb00f7e6eeef861ba5368fc10710d1 0ccfdaaf01b41a77c2e42b081548fcbd1ae57a8031f3892e9816b62b5c123bb8 +168480 0a393e6f1eb40134a63d4256463c4d11e5087cf51c74c378f1176d41798912b9 bb67562ebc6abab32ac8603a6478f09291641cc1a4de0707e76cf7673f9c2682 0e22357053d8afdafae0ffddd20f0ea2497fce3a0326623b27beabad5b13d73e +168640 0e9aedcbe26c7bd9cad817453e8efdb674b4fe4820a64d646e89ad52c0b37fd8 8cf49548616d876f909049620e987a073cdf8be485a1997c3a8ab10209393dc9 0bc3eace9f21cee8fe9d749060c3136d4afb2cb23af38d3d0eeb495306b154a6 +168800 065da48403aec93080a03753071d735e8b0f60058cbb2abcdb80f38e660e5e94 316fca2b4c1ebddfbf71e2eebe95d736c571c1d0f7cba1e21c58b4e680e8c221 097b050e79426ff27769e34d9aae5ebfb26f03f089af732e485cea21c9e9e157 +168960 02907769c389bed38548cc32841695949b7f0da8b1f42461f7bc252ddb77fa95 e8d34e721e4b788c23694e1207e0801235238eef57d2213ca66a6396263f2c75 08ab02077770eb118e0ba00bb5d75871ce1be9e9ed7874e66dae12bbc50d6618 +169120 055350bc48af658a6fa03836291d6393dfb5a7aaa396ab8e46a2318496cb54e3 2f1f1bb128db83538229fb786b00025cc8744d685d0a9ad34ca2c3b1b4e328df 078d9d259122ddf1df4067bfff2dfb6f67aaa323c3e3d0e6d9e31a4a2aec94c8 +169280 000003409e3719089dbadb6ee09e56a4dad32a0694307dd65508eba95d3c4bdc 0ff3c01ff28a3fec968e56e2741690d19902bce1aab0f8a2ea99c2943d02cdf5 0b96570fe5d0af4231b844396ac4b548f72768ccc746ec72faec973e9b3bc55b +169440 000007baa036b9311a1306293618df8dc2f828bc80fcf6857845f8726f67f2c8 8eb1f22acc7073c6e60fc023c98c9b6b93cbb18a0666a01e69c45be17c3a3f73 0e34abd3b0d75323dbade2612b86741d73fd234729c8fa612e3c34ebdf3f252e +169600 026d4dedfde78930dd382b1e42305f17722527e4bc9682f321b6e0c6df558dd1 d08d3893c5732417b38602edd836fd7d10d9822d9da24b44c756874af924ef53 0e24087ec4293fe3d803e8f8c6cb34a251934980361cba9fc5c6113f91bd9c0f +169760 024834d987377fc5fd97fac3fecb7705ed433e55e1a9ce937b1694a3c5535c0d fcc9be68466a0bdea9b5fa447d22b61a27e023d642f0838ff31d9538fe2cd04b 000deb1170c0a8bc3ea7356e4ebb6a7090f00202f267c985767ae062cb6cb729 +169920 0e13aaa0ee145a5e61454156ef225274637cce2c6838e6ccf5dfc9760b1ac873 79cbd02bd97e770ac4b49e973afce7eb5d339b111beb7f56f89798f7a3532021 0057d3c6a74fe723d80cd86003014fb1347c73e6fe73e9202a011d7a46e145a6 +170080 01843d961ec6ce3f8e41c8bedffb6a892c936f74b134d51b22fd668c994cce93 6e6102ed50dcd8b5e3135bd9866252ba0a1359de9b8358a48c1f264b4df4d22d 039adc034e7fd130954013a408f75493220c5ead85f38e19d64de2cc3bae0c99 +170240 0e2e32dd5890833a646b94a78d679730206d9c7cd36c5c934baaf9bde1ab0b11 130b1ed00c9867d45f9ab75c64aa9b0982306c3db5130c0092e089645179642b 028d90203374b6e2ff71e0f5273ba01dc6859435b215b7d632432da67b1679df +170400 0c573ea725728c3393a4bd99f45e49ce783a59c774ef0755d3d8e4b383bad0a5 d91f34a5352c5be1ef416e17de7a355fa638f36db8f258f38d7bd06116ce10c6 0ac30068d77868b2aa68700a43c15ef0737007846f9f485c0965fd977f971a48 +170560 0327d27ca1ee19e9a9cabe3c6b1d316d5ebe973bcc8b1f5786496c97ffa7f2cc 0eca2b0118425244d5cdd321ebe275a33d82cf8f98db800702d1553f06c0856f 00002446d0bd2d5f0c4d53d3f674815ab1b756a1aa68c7269f6ebe1a7e04d607 +170720 09b6d0dbf782979a5493706292db8794c260d8da08b93c2f01a49bdf0a58aa41 6c616179977f2d416246cba18c80d3636e40ba2fd6bb5add64d6db5fa8a4ae08 0ad489c5563b9d4de6d66f0ac2220644f5fc7d1ff8871d0872f5612812bad656 +170880 03b82b39b599f46a49fa4fca4780069d9219d39761f0f73fe4066e46459cad59 388ddc0c9113da373a8149446dbde5b0aab8e8924e09e737cc4bbfcb2f990b3a 0000146579e867a6613c648d83dbb49dcac50c87f95e6ec9f9ad6491a5fc5b93 +171040 0a0dd14a38fcf50dfa05b429f93c01d79ddf929f92c4a5a14af271c11375f068 a64b578e23ac3ab4e9545a5e10d34e3a793085e5e5dd8be33d930619b84ed705 00000ee6e5af2bcc052543720c68d439415dc27c3770b3c4de31e3f0aa82278d +171200 000019b8008eba1714a1b072a5402b08b16c3c41f374c7c84ed6f24d14cb4669 25a6282a28fac6ca032444962dbbfd290e803118482673abae3b145e46cfe1ca 0000078cffdeffab975a781911b196fcb5a4841290d269916177cfd96e198603 +171360 01426b273d021ebde10550730dde498a8f338b2f366b8aa6140c1a50b5096724 9f6f5394760b798e779b3aaf17e97569ff4b5a6b75acf6a5361978cd00a82a3f 02d2aaa846d7ce7df554e63c0aeacea30a62a2e004705e46fd4d211b88c524fa +171520 07afb60b1f5029bc2009d96f66e5e8c37ab5580ea31fd52cc89358d0acdec137 1fece6b32d7dcb13a21fa0b6d45448836411b24904159e8e763ea65a1bc6cffc 06220ff80b820b9d12ae4544c917d08292265b786b2062099d92bc919e39659d +171680 0bd9c63e7f22931cb043ce16f226ddb37deef5eb17efeee2073ba2f536b7a84d 8bb01cd3a868acf874d059bac7f5c17dedda3af4551309daa39d3b5d6feee876 0b9263c16bce05018b3e22b811efdf6449fad173a810917dcaf29986d67cb6a9 +171840 0eab1a4578166e4dd3e832b15199648bd6ae2b413b087db7482ab9d770f014cf 55b4b0876afba1b960aa333b3c3ce74a27ef6d68382b17833c30a51a4249fde8 04b9c8f366b0d12b9a78aa14c235f8e6e3c2b259aa3f62b7bf6a725da578e5f3 +172000 03919a07f72ae96d605ec8225b63c89462bc3fd25997cb0fb891e0d600b4c45b 911ce73a1ecdb806adc72c2757247c9ef0b8fbf97f8e6dc6b7b1903e0b7e4e67 000000604f17448c4ff99b2f7ea56e7aeb248fa0338cacae01f807d9f8022216 +172160 000043dd46d0c07115a7ea834b0b2ce080da16c92ec4dee482a0c6432bb59a72 9d028b885142770920837ec073d99215f5994e6e7fbbfca9a318b09bb7748dd2 00002456471bf85ffe02a15e053ee04d9913cc946fe75f4a6ecf26b4f41bb64b +172320 0000064cda3e29624e2cae7f10d080cde3907571453bb713dce0e0b8b96b1662 79af319d273bdbcb4f49263bf11ed087011f1da2317fd2d643a782e14829f4f4 0000037b3172503616386320b6a9d43aae9f0f0e5428166c63946acf8c4a7035 +172480 09e995910e826fcd71571038f8c23011c7fec23526014552b91cf158b153a4f6 cb26cf6a1cb1fd70517282251469537b6df4829a331721e8740cb1f9f40e7b7c 0000271a76545ed82db578eb561b1ee350a63964f31539bdeb3fd5ecc3dd450a +172640 000023a15a5c3841f30b195e6540ef1a8e93541bdd1808684529378af5c819f5 d1c5af5b9cbaea6dd38c17a5d750fa83de14805f54ca75b0b272a3055d4385b1 0bfb2031a526360744389a7c9b4bf3081f573992a3b4cb4533a78b0f13c3c651 +172800 00000f4e6d68ec5abbb303684f5833ce1dc5fba965f021a2798553386219c0a5 20e61f13a9eb8afedf93d9cfa00e1ec87e7df82da99664ad9f75c9ed92f5d06b 00001fc65bff0bc61a1ddfba79c99e3b654c1f6c43fbffa7ae8fae53f11156bc +172960 0ba38c99a630dd088cf89ec3e9a573c373c21627d73ad0c35a7113ce0fd6ac9c b34dc6c774af062e1231f865d6fbb3958b1416af56eb90b3229147474998e0ce 04b9e5b7f1e5f6b3131d6e4c14707586c6de9a05e113a8666d5f1a49419652a6 +173120 0910a73b22938a68e5199697c3feb05f4961570e1bb13b41f4941c0ef5f5b95f b8e5137ba3be33693a64e1184b50a55ed837d99c11e21edc2e2107b703644aeb 0000057afb9a57805e8b750f8ec8bea004acf7c830c1ef724fd7c8c00000778d +173280 00001ec6d1003a60d578723ab58e7f90110974333c99ec68b946b1cd51dcc5be cce577c453d0a0163418efe0d537941e3c5717c59dfe5b4c61849e0b69b8699a 00ab526d984fa97aaa3cbe0d6272bc0b73271e2042f5f5bfd8e47ac7d959b7aa +173440 09d7ef7b0aedcc22ee6cb068c3a168f80cf6fe7c129dcdf04a55f0beb481f4e0 e6bb3d53d090aadfbd664362668daf7fdfb2e3add78f028c6b977e223613c940 000026e3c65f838a5de1ef3ca6ba62607c193059adae88040d22f166e20385c7 +173600 0000189639d3c75d24a259b201a515ca7a4b173d40a492a50fba1b4489bb5d26 e76329a996504b912a2e826bf406bad5a449f0edd254296db5cbd8b096451171 029dc7335fd2b2e6d0ed11803a116d13016853d8309a56afdae88c0ee04f5851 +173760 014a5ac270e4fa352acb751718d7d88cc7a3ac268ff4c526b36902a2bd1f0bae 144ca70f50d9a8658fc44a6958991552bd515daf39fd5e78f89dbe7f1692f51e 00756542b82541878c02c5e6afe1a4d807351c3ac631ecb2e2c5f3a935fc947a +173920 0551a363693d41cc14c6b43c7812bf5b01db8843159a5b82489421cc7720585b c00373a6555363b6ae985c124ecfd310d915fadb7b3744edfd7d872ceb38afa6 00004e21962066dccddd0652de078ee55c9e27cada841fb0134ab1dcb0cb3fdc +174080 00008d975f4ebc841fae7c802669f89d6ad9a6c85d23b4e24f3081067e2ef2d9 beb761b4cab9fcdae314862db70ade78aaf8e74ba5d60d553af948da91a5a569 08cfc183bc579c2f3469a7308d3331ad9851a8514297eef7ad285ec7b1155626 +174240 0000300e447dfd8560d9dae31695bc02f9a3df6caa746accca13c751e9d41e38 79dc2c4549e5f22b20249c0ad01e38b694e4a6c090f440077ee2729836099982 079fcf10471e796f7a868b8ff2e4f398e081bc1f593bbe0f1638e7137cf4bf94 +174400 0d6a0a31fc06614d3b93ba0993071bf478993ba5e06ee619ab2238bd02681ec5 4f3f981319630bc747255c602a3cba20b342771c270d15fce8c48bbddbc7f12a 0e14382883daa233d075c920aba419676d8eb40fdf232fa8153d69195b111b93 +174560 00001091659a15ca1635651dc1e5eb7784f757cd559c762ed1ebc38571beab2e 6c8b99531087d128f3ff5daff214ea5d0909b8c166a583e947cbf2687ec5d6f7 0375163efbd527c31c1e1a059b1d11a669e24a43abe2dd4bf555ac84d5ddebe2 +174720 00000731531fa068ce4d573a86cec4ca5cf4d47960addca1e773daf17e9b60b9 6414b308d9056ff62bfa3adcaa4a7f9eb0420faec1031e94cf91a5e04eaf874f 000dd2b7579a7979d07a3b6442ac340e0784ea5c7fb7e9d9aa131c48d4219760 +174880 00000141f8d7c30e9c1005d3838687b1f1853bd05785f124471030db3300da4a diff --git a/iguana/confs/KMD_peers.txt b/iguana/confs/KMD_peers.txt new file mode 100644 index 000000000..bb6b1ba37 --- /dev/null +++ b/iguana/confs/KMD_peers.txt @@ -0,0 +1,15 @@ +148.251.57.148 +149.56.28.84 +176.9.26.39 +94.102.63.199 +5.9.102.210 +88.198.65.74 +94.102.63.200 +78.47.196.146 +104.255.64.3 +221.121.144.140 +103.18.58.150 +103.18.58.146 +213.202.253.10 +185.106.121.32 +27.100.36.201 diff --git a/iguana/confs/SXC_peers.txt b/iguana/confs/SXC_peers.txt new file mode 100644 index 000000000..30a2a2bc4 --- /dev/null +++ b/iguana/confs/SXC_peers.txt @@ -0,0 +1,11 @@ +104.238.221.17:16814 +148.163.102.28:16814 +167.160.36.152:16814 +192.227.158.136:16814 +213.46.197.237:16814 +87.204.149.94:16814 +45.43.26.103:16814 +172.110.18.177:16814 +172.110.18.178:16814 +185.116.238.204:16814 +84.242.207.225:16814 diff --git a/iguana/confs/TAZ_peers.txt b/iguana/confs/TAZ_peers.txt new file mode 100644 index 000000000..816f4ffa1 --- /dev/null +++ b/iguana/confs/TAZ_peers.txt @@ -0,0 +1,3 @@ +176.9.26.39 +5.9.102.210 +78.47.196.146 diff --git a/iguana/confs/UNO_peers.txt b/iguana/confs/UNO_peers.txt index 1be6bbfac..67210bb1d 100644 --- a/iguana/confs/UNO_peers.txt +++ b/iguana/confs/UNO_peers.txt @@ -1,8 +1,8 @@ 195.154.223.134 -216.146.143.177 -173.183.179.144 -144.76.176.12 -87.189.45.29 -188.138.94.6 -144.76.239.66 -144.76.64.123 +85.25.217.233 +104.172.24.79 +188.165.42.51 +45.32.244.201 +52.23.179.46 +192.95.29.72 +185.50.213.123 diff --git a/iguana/dPoW.h b/iguana/dPoW.h new file mode 100755 index 000000000..ba9e5c00e --- /dev/null +++ b/iguana/dPoW.h @@ -0,0 +1,216 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef INCLUDE_DPOW_H +#define INCLUDE_DPOW_H + +#define DPOW_FIRSTRATIFY 1000 + +#define DPOW_CHECKPOINTFREQ 10 +#define DPOW_MINSIGS 13 +#define DPOW_MIN_ASSETCHAIN_SIGS 11 +//#define DPOW_M(bp) ((bp)->minsigs) // (((bp)->numnotaries >> 1) + 1) +#define DPOW_MODIND(bp,offset) (((((bp)->height / DPOW_CHECKPOINTFREQ) % (bp)->numnotaries) + (offset)) % (bp)->numnotaries) +#define DPOW_VERSION 0x0781 +#define DPOW_UTXOSIZE 50000 +#define DPOW_MINOUTPUT 6000 +#define DPOW_DURATION 600 +#define DPOW_RATIFYDURATION (3600 * 24) + +//#define DPOW_ENTRIESCHANNEL ('e' | ('n' << 8) | ('t' << 16) | ('r' << 24)) +//#define DPOW_BTCENTRIESCHANNEL (~DPOW_ENTRIESCHANNEL) +//#define DPOW_UTXOCHANNEL ('d' | ('P' << 8) | ('o' << 16) | ('W' << 24)) +#define DPOW_SIGCHANNEL ('s' | ('i' << 8) | ('g' << 16) | ('s' << 24)) +#define DPOW_SIGBTCCHANNEL (~DPOW_SIGCHANNEL) +#define DPOW_TXIDCHANNEL ('t' | ('x' << 8) | ('i' << 16) | ('d' << 24)) +#define DPOW_BTCTXIDCHANNEL (~DPOW_TXIDCHANNEL) + + +#define DPOW_FIFOSIZE 64 +#define DPOW_MAXTX 8192 +#define DPOW_THIRDPARTY_CONFIRMS 0 +#define DPOW_KOMODOCONFIRMS 10 +#define DPOW_BTCCONFIRMS 1 +#define DPOW_MAXRELAYS 64 +#define DPOW_MAXSIGLEN 128 + +#define DEX_VERSION 0x0105 +#define DPOW_SOCK 7775 +#define DEX_SOCK 7774 +#define PUB_SOCK 7773 +#define REP_SOCK 7772 + +#define DPOW_EPOCHDURATION 600 + +struct dpow_coinentry +{ + bits256 prev_hash; + uint8_t siglens[DPOW_MAXRELAYS],sigs[DPOW_MAXRELAYS][DPOW_MAXSIGLEN]; + int32_t prev_vout; +}; + +struct dpow_utxoentry +{ + bits256 srchash,desthash,commit,hashmsg; + uint64_t recvmask,othermasks[DPOW_MAXRELAYS]; + int32_t srcvout,destvout,height; + int8_t bestk; uint8_t pubkey[33]; +}; + +struct dpow_entry +{ + bits256 commit,beacon,ratifysrcutxo,ratifydestutxo; + uint64_t masks[2][DPOW_MAXRELAYS],recvmask,othermask,bestmask,ratifyrecvmask,ratifybestmask; + int32_t height; uint32_t pendingcrcs[2],paxwdcrc; + uint16_t ratifysrcvout,ratifydestvout; + int8_t bestk,ratifybestk; + uint8_t pubkey[33],ratifysigs[2][DPOW_MAXSIGLEN],ratifysiglens[2]; + struct dpow_coinentry src,dest; +}; + +struct dpow_sigentry +{ + bits256 beacon; + uint64_t mask; + int32_t refcount; + uint8_t senderind,lastk,siglen,sig[DPOW_MAXSIGLEN],senderpub[33]; +}; + +struct komodo_notaries +{ + struct basilisk_relay RELAYS[DPOW_MAXRELAYS]; + int32_t NUMRELAYS,RELAYID; +}; + +struct dpow_hashheight { bits256 hash; int32_t height; }; + +struct dpow_checkpoint +{ + struct dpow_hashheight blockhash,approved; + bits256 miner; uint32_t blocktime,timestamp; +}; + +struct dpow_block +{ + bits256 hashmsg,desttxid,srctxid,beacon,commit; + struct iguana_info *srccoin,*destcoin; char *opret_symbol; + uint64_t destsigsmasks[DPOW_MAXRELAYS],srcsigsmasks[DPOW_MAXRELAYS]; + uint64_t recvmask,bestmask,ratifybestmask,ratifyrecvmask,pendingbestmask,pendingratifybestmask,ratifysigmasks[2]; + struct dpow_entry notaries[DPOW_MAXRELAYS]; + uint32_t state,starttime,timestamp,waiting,sigcrcs[2],txidcrcs[2],utxocrcs[2],lastepoch,paxwdcrc; + int32_t rawratifiedlens[2],height,numnotaries,numerrors,completed,minsigs,duration,numratified,isratify,require0,scores[DPOW_MAXRELAYS]; + int8_t myind,bestk,ratifybestk,pendingbestk,pendingratifybestk; + cJSON *ratified; + uint8_t ratified_pubkeys[DPOW_MAXRELAYS][33],ratifysigs[2][DPOW_MAXSIGLEN],ratifysiglens[2]; + char handles[DPOW_MAXRELAYS][32]; + char signedtx[32768]; uint8_t ratifyrawtx[2][32768]; uint32_t pendingcrcs[2]; +}; + +struct pax_transaction +{ + UT_hash_handle hh; + bits256 txid; + uint64_t komodoshis,fiatoshis; + int32_t marked,height,kmdheight; + uint16_t vout; + char symbol[16],coinaddr[64]; uint8_t rmd160[20],shortflag; +}; + +struct dpow_info +{ + char symbol[16],dest[16]; uint8_t minerkey33[33],minerid; uint64_t lastrecvmask; + struct dpow_checkpoint checkpoint,last,destchaintip,srcfifo[DPOW_FIFOSIZE],destfifo[DPOW_FIFOSIZE]; + struct dpow_hashheight approved[DPOW_FIFOSIZE],notarized[DPOW_FIFOSIZE]; + bits256 activehash,lastnotarized,srctx[DPOW_MAXTX],desttx[DPOW_MAXTX]; + uint32_t SRCREALTIME,lastsrcupdate,destupdated,srcconfirms,numdesttx,numsrctx,lastsplit,cancelratify; + int32_t lastheight,maxblocks,SRCHEIGHT,SHORTFLAG,ratifying; + struct pax_transaction *PAX; + portable_mutex_t paxmutex,dexmutex; + uint32_t ipbits[128],numipbits; + struct dpow_block **blocks; +}; +uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp); +int32_t dpow_paxpending(uint8_t *hex,uint32_t *paxwdcrcp); +void dex_updateclient(struct supernet_info *myinfo); +char *dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *data,int32_t datalen,int32_t M,char *field); +char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping,uint32_t duration); +int32_t dpow_getchaintip(struct supernet_info *myinfo,bits256 *blockhashp,uint32_t *blocktimep,bits256 *txs,uint32_t *numtxp,struct iguana_info *coin); +void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgbits,uint8_t *data,int32_t datalen); +int32_t dpow_nanomsg_update(struct supernet_info *myinfo); +int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr); +void komodo_assetcoins(int32_t fullnode,uint64_t mask); +int32_t iguana_isnotarychain(char *symbol); + +cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin); +cJSON *dpow_gettransaction(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid); +cJSON *dpow_getblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash); +bits256 dpow_getblockhash(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height); +bits256 dpow_getbestblockhash(struct supernet_info *myinfo,struct iguana_info *coin); +char *dpow_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx); +cJSON *dpow_gettxout(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout); +char *dpow_importaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address); +char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address); +cJSON *dpow_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); +cJSON *dpow_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,int32_t count,int32_t skip); +char *dpow_alladdresses(struct supernet_info *myinfo,struct iguana_info *coin); +cJSON *dpow_kvupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *key,char *value,int32_t flags); +cJSON *dpow_kvsearch(struct supernet_info *myinfo,struct iguana_info *coin,char *key); +void init_alladdresses(struct supernet_info *myinfo,struct iguana_info *coin); +cJSON *dpow_getmessage(struct supernet_info *myinfo,char *jsonstr); +cJSON *dpow_addmessage(struct supernet_info *myinfo,char *jsonstr); +cJSON *dpow_psock(struct supernet_info *myinfo,char *jsonstr); + +char *_dex_getinfo(struct supernet_info *myinfo,char *symbol); +char *_dex_getrawtransaction(struct supernet_info *myinfo,char *symbol,bits256 txid); +char *_dex_getblock(struct supernet_info *myinfo,char *symbol,bits256 hash2); +char *_dex_getblockhash(struct supernet_info *myinfo,char *symbol,int32_t height); +char *_dex_getbestblockhash(struct supernet_info *myinfo,char *symbol); +char *_dex_sendrawtransaction(struct supernet_info *myinfo,char *symbol,char *signedtx); +char *_dex_gettxout(struct supernet_info *myinfo,char *symbol,bits256 txid,int32_t vout); +char *_dex_gettxin(struct supernet_info *myinfo,char *symbol,bits256 txid,int32_t vout); +char *_dex_importaddress(struct supernet_info *myinfo,char *symbol,char *address); +char *_dex_validateaddress(struct supernet_info *myinfo,char *symbol,char *address); +char *_dex_getmessage(struct supernet_info *myinfo,char *jsonstr); +char *_dex_listunspent(struct supernet_info *myinfo,char *symbol,char *address); +char *_dex_listunspent2(struct supernet_info *myinfo,char *symbol,char *address); +char *_dex_listspent(struct supernet_info *myinfo,char *symbol,char *address); +char *_dex_getbalance(struct supernet_info *myinfo,char *symbol,char *address); +char *_dex_listtransactions(struct supernet_info *myinfo,char *symbol,char *coinaddr,int32_t count,int32_t skip); +char *_dex_listtransactions2(struct supernet_info *myinfo,char *symbol,char *coinaddr,int32_t count,int32_t skip); +char *_dex_alladdresses(struct supernet_info *myinfo,char *symbol); +int32_t _dex_getheight(struct supernet_info *myinfo,char *symbol); +char *_dex_getnotaries(struct supernet_info *myinfo,char *symbol); +char *_dex_kvupdate(struct supernet_info *myinfo,char *symbol,char *key,char *value,int32_t flags); +char *_dex_kvsearch(struct supernet_info *myinfo,char *symbol,char *key); +char *_dex_psock(struct supernet_info *myinfo,char *jsonstr); + +int32_t komodo_notaries(char *symbol,uint8_t pubkeys[64][33],int32_t height); +cJSON *dpow_checkaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address); + +void dex_channelsend(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen); +void kmd_bitcoinscan(); +cJSON *kmd_getbalance(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); +struct iguana_info *iguana_coinfind(char *symbol); +cJSON *kmd_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,int32_t count,int32_t skip); +cJSON *kmd_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); +cJSON *kmd_listspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); +cJSON *kmd_gettxin(struct iguana_info *coin,bits256 txid,int32_t vout); + +cJSON *dpow_listspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); +cJSON *dpow_getbalance(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); +cJSON *dpow_gettxin(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout); + + +#endif diff --git a/iguana/dexscripts.win32/1-client.cmd b/iguana/dexscripts.win32/1-client.cmd new file mode 100644 index 000000000..21bec2717 --- /dev/null +++ b/iguana/dexscripts.win32/1-client.cmd @@ -0,0 +1,16 @@ +@echo off +set USERHOME=%APPDATA:\=\\% +rem [!] Coins config now taked from coins.json file, no need to put in environment variable +rem --------------------------------------------------------------------------------------- +rem set COINS=[{\"coin\":\"REVS\",\"active\":1,\"asset\":\"REVS\",\"rpcport\":10196}] +rem marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"mypassphrase\", \"coins\":%COINS%}" + +set COINS=\"\" +set /p PASSPHRASE= marketmaker.log 2>&1 +marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"%USERHOME%\", \"passphrase\":\"%PASSPHRASE%\"}" + + + + diff --git a/iguana/dexscripts.win32/2-getuserpass.cmd b/iguana/dexscripts.win32/2-getuserpass.cmd new file mode 100644 index 000000000..87e633339 --- /dev/null +++ b/iguana/dexscripts.win32/2-getuserpass.cmd @@ -0,0 +1,7 @@ +@echo off +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":null,\"method\":\"enable\",\"coin\":\" \"}" -s > userpass.json +for /f "tokens=2 delims=:," %%a in (' find "userpass" "userpass.json" ') do ( +echo UserPass: %%~a +echo %%~a > userpass +) +del userpass.json \ No newline at end of file diff --git a/iguana/dexscripts.win32/balance.cmd b/iguana/dexscripts.win32/balance.cmd new file mode 100644 index 000000000..551d1234a --- /dev/null +++ b/iguana/dexscripts.win32/balance.cmd @@ -0,0 +1,4 @@ +@echo off +set /p TMPUSERPASS= UTXO PAIRS to understand the basics. This script is just for example how you can split your coins in (X, X/777) to start trading them. + +## F.A.Q. ## + +**Q.** Is any simple way how i can display JSON results returned by all scripts, like orderbook and others, in human readable form? + +**A.** Yes, you can use this service [JSON Editor Online](http://jsoneditoronline.org/), just copy and paste output of script in left column and see structured output in right. + +**Q.** I see an output like this when i'm start `1-client.cmd` : + + bind(0.0.0.0) port.7783 failed: No error sock.1468. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1516. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1444. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1484. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1412. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1524. errno.0 + bind(0.0.0.0) port.7783 failed: No error sock.1008. errno.0 + +And nothing works. + +**A.** Before run `1-client.cmd` make sure in Task Manager that you haven't already running `marketmaker.exe`. If have - kill this process via Task Manager or via command line command `taskkill /f /im taskkill.exe` . + +**Q.** How can i pretty print JSON answers of marketmaker? + +**A.** You can get best results with 2 tools - [conemu](https://conemu.github.io/) and [jq](https://stedolan.github.io/jq/), conemu supports ANSI X3.64 and Xterm 256 colors and jq allow you to pretty-print json output with colors, like this: + +![](./images/conemu_jq.png) + +Also i'm always recommend to install [Far Manager](https://www.farmanager.com/index.php?l=en) - this is powerful console file manager for Windows, like Midnight Commander in *nix. + +**Q.** What additional dependencies required by marketmaker? + +**A.** Currently marketmaker (Windows) used the following DLLs: + +*32 bit:* +- libcrypto-1_1.dll +- libcurl.dll +- libssl-1_1.dll +- nanomsg.dll +- pthreadvc2.dll + +*64-bit:* +- libcurl.dll +- nanomsg.dll + +It already included in repo and in archive with release. \ No newline at end of file diff --git a/iguana/dexscripts.win32/images/conemu_jq.png b/iguana/dexscripts.win32/images/conemu_jq.png new file mode 100644 index 000000000..e8eeaf523 Binary files /dev/null and b/iguana/dexscripts.win32/images/conemu_jq.png differ diff --git a/iguana/dexscripts.win32/images/userpass.png b/iguana/dexscripts.win32/images/userpass.png new file mode 100644 index 000000000..9134e8ed5 Binary files /dev/null and b/iguana/dexscripts.win32/images/userpass.png differ diff --git a/iguana/dexscripts.win32/images/userpass_usage.png b/iguana/dexscripts.win32/images/userpass_usage.png new file mode 100644 index 000000000..157251a4b Binary files /dev/null and b/iguana/dexscripts.win32/images/userpass_usage.png differ diff --git a/iguana/dexscripts.win32/inventory.cmd b/iguana/dexscripts.win32/inventory.cmd new file mode 100644 index 000000000..c1e02c0a0 --- /dev/null +++ b/iguana/dexscripts.win32/inventory.cmd @@ -0,0 +1,4 @@ +@echo off +set /p TMPUSERPASS= withdraw.txt +type withdraw.txt diff --git a/iguana/dexscripts.win32/withdraw_10_send.cmd b/iguana/dexscripts.win32/withdraw_10_send.cmd new file mode 100644 index 000000000..44a947787 --- /dev/null +++ b/iguana/dexscripts.win32/withdraw_10_send.cmd @@ -0,0 +1,14 @@ +@echo off +set /p TMPUSERPASS= withdraw.txt +type withdraw.txt +timeout /t 5 /nobreak +for /f "tokens=4 delims=:," %%a in (' find "hex" "withdraw.txt" ') do ( +rem echo [%%~a] +curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"%COIN%\",\"signedtx\":\"%%~a\"}" +) diff --git a/iguana/dexscripts.win32/withdraw_send.cmd b/iguana/dexscripts.win32/withdraw_send.cmd new file mode 100644 index 000000000..a26b9bf56 --- /dev/null +++ b/iguana/dexscripts.win32/withdraw_send.cmd @@ -0,0 +1,14 @@ +@echo off +set /p TMPUSERPASS= withdraw.txt +type withdraw.txt +timeout /t 5 /nobreak +for /f "tokens=4 delims=:," %%a in (' find "hex" "withdraw.txt" ') do ( +rem echo [%%~a] +curl -s --url "http://127.0.0.1:7783" --data "{\"userpass\":\"%USERPASS%\",\"method\":\"sendrawtransaction\",\"coin\":\"%COIN%\",\"signedtx\":\"%%~a\"}" +) + diff --git a/iguana/dexscripts/.marker b/iguana/dexscripts/.marker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/dpow/dpow_fsm.c b/iguana/dpow/dpow_fsm.c new file mode 100755 index 000000000..effcf3914 --- /dev/null +++ b/iguana/dpow/dpow_fsm.c @@ -0,0 +1,468 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +struct dpow_entry *dpow_notaryfind(struct supernet_info *myinfo,struct dpow_block *bp,int32_t height,int32_t *senderindp,uint8_t *senderpub) +{ + int32_t i; + *senderindp = -1; + for (i=0; inumnotaries; i++) + { + if ( memcmp(bp->notaries[i].pubkey,senderpub,33) == 0 ) + { + //printf("matches notary.%d\n",i); + *senderindp = i; + return(&bp->notaries[i]); + } + } + return(0); +} + +void dpow_utxo2entry(struct dpow_block *bp,struct dpow_entry *ep,struct dpow_utxoentry *up) +{ + int32_t i; + for (i=0; inumnotaries; i++) + bp->notaries[i].othermask |= up->othermasks[i]; + ep->commit = up->commit; + ep->height = up->height; + ep->recvmask |= up->recvmask; + ep->bestk = up->bestk; + ep->src.prev_hash = up->srchash; + ep->dest.prev_hash = up->desthash; + ep->src.prev_vout = up->srcvout; + ep->dest.prev_vout = up->destvout; +} + +void dpow_entry2utxo(struct dpow_utxoentry *up,struct dpow_block *bp,struct dpow_entry *ep) +{ + int32_t i; + up->commit = bp->commit; + up->hashmsg = bp->hashmsg; + up->height = bp->height; + up->recvmask = bp->recvmask; + up->bestk = bp->bestk; + for (i=0; inumnotaries; i++) + up->othermasks[i] = bp->notaries[i].recvmask; + for (i=0; i<33; i++) + up->pubkey[i] = ep->pubkey[i]; + up->commit = ep->commit; + up->height = ep->height; + up->recvmask = ep->recvmask; + up->bestk = ep->bestk; + up->srchash = ep->src.prev_hash; + up->desthash = ep->dest.prev_hash; + up->srcvout = ep->src.prev_vout; + up->destvout = ep->dest.prev_vout; +} + +int32_t dpow_datahandler(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint8_t nn_senderind,uint32_t channel,uint32_t height,uint8_t *data,int32_t datalen) +{ + int32_t i,src_or_dest,myind = -1; bits256 txid,srchash; struct iguana_info *coin; char str[65],str2[65]; + memset(srchash.bytes,0,sizeof(srchash)); + dpow_notaryfind(myinfo,bp,height,&myind,dp->minerkey33); + if ( myind < 0 ) + { + //printf("couldnt find myind height.%d | this means your pubkey for this node is not registered and needs to be ratified by majority vote of all notaries\n",height); + return(-1); + } + for (i=0; i<32; i++) + srchash.bytes[i] = dp->minerkey33[i+1]; + if ( channel == DPOW_TXIDCHANNEL || channel == DPOW_BTCTXIDCHANNEL ) + { + src_or_dest = (channel == DPOW_BTCTXIDCHANNEL); + coin = (src_or_dest != 0) ? bp->destcoin : bp->srccoin; + //printf("bp.%p datalen.%d\n",bp,datalen); + for (i=0; i<32; i++) + srchash.bytes[i] = data[i]; + txid = bits256_doublesha256(0,&data[32],datalen-32); + init_hexbytes_noT(bp->signedtx,&data[32],datalen-32); + if ( bits256_cmp(txid,srchash) == 0 ) + { + //printf("verify (%s) it is properly signed! set ht.%d signedtxid to %s\n",coin->symbol,height,bits256_str(str,txid)); + /*if ( channel == DPOW_BTCTXIDCHANNEL ) + { + if ( bp->state < 1000 ) + { + bp->desttxid = txid; + bp->state = 1000; + dp->destupdated = 0; + dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,0,bp->isratify); + //dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0); + } + } + else + { + if ( bp->state != 0xffffffff ) + { + bp->srctxid = txid; + printf("set state elapsed %d COMPLETED %s.(%s) %s.(%s)\n",(int32_t)(time(NULL) - bp->starttime),dp->symbol,bits256_str(str,bp->desttxid),dp->dest,bits256_str(str2,txid)); + bp->state = 0xffffffff; + } + }*/ + } + else + { + init_hexbytes_noT(bp->signedtx,data,datalen); + printf("txidchannel txid %s mismatch %s (%s)\n",bits256_str(str,txid),bits256_str(str2,srchash),bp->signedtx); + bp->signedtx[0] = 0; + } + } //else printf("unhandled channel.%x\n",channel); + return(0); +} + +int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr) +{ + int32_t haveutxo,completed,minutxo,n; bits256 signedtxid; cJSON *addresses; char *rawtx,*sendtx; + if ( strcmp("BTC",coin->symbol) == 0 ) + { + minutxo = 199; + n = 10; + } + else + { + minutxo = 49; + n = 10; + } + if ( (haveutxo= dpow_haveutxo(myinfo,coin,txidp,voutp,coinaddr)) <= minutxo && time(NULL) > dp->lastsplit+bp->duration && (bp->myind != 0 || dp->ratifying == 0) ) + { + addresses = cJSON_CreateArray(); + jaddistr(addresses,coinaddr); + if ( (rawtx= iguana_utxoduplicates(myinfo,coin,dp->minerkey33,DPOW_UTXOSIZE,n,&completed,&signedtxid,0,addresses)) != 0 ) + { + if ( (sendtx= dpow_sendrawtransaction(myinfo,coin,rawtx)) != 0 ) + { + printf("sendrawtransaction.(%s)\n",sendtx); + free(sendtx); + } + free(rawtx); + } + free_json(addresses); + dp->lastsplit = (uint32_t)time(NULL); + } + if ( bits256_nonz(*txidp) == 0 ) + return(-1); + return(haveutxo); +} + +void dpow_statemachinestart(void *ptr) +{ + void **ptrs = ptr; + struct supernet_info *myinfo; struct dpow_info *dp; struct dpow_checkpoint checkpoint; + int32_t i,j,ht,extralen,destprevvout0,srcprevvout0,numratified=0,kmdheight,myind = -1; uint8_t extras[10000],pubkeys[64][33]; cJSON *ratified=0,*item; struct iguana_info *src,*dest; char *jsonstr,*handle,*hexstr,str[65],str2[65],srcaddr[64],destaddr[64]; bits256 zero,srchash,destprevtxid0,srcprevtxid0; struct dpow_block *bp; struct dpow_entry *ep = 0; uint32_t duration,minsigs,starttime,srctime; + memset(&zero,0,sizeof(zero)); + srcprevtxid0 = destprevtxid0 = zero; + srcprevvout0 = destprevvout0 = -1; + myinfo = ptrs[0]; + dp = ptrs[1]; + minsigs = (uint32_t)(long)ptrs[2]; + duration = (uint32_t)(long)ptrs[3]; + jsonstr = ptrs[4]; + kmdheight = -1; + memcpy(&checkpoint,&ptrs[5],sizeof(checkpoint)); + src = iguana_coinfind(dp->symbol); + dest = iguana_coinfind(dp->dest); + dpow_getchaintip(myinfo,&srchash,&srctime,dp->srctx,&dp->numsrctx,src); + dpow_getchaintip(myinfo,&srchash,&srctime,dp->desttx,&dp->numdesttx,dest); + if ( src == 0 || dest == 0 ) + { + printf("null coin ptr? (%s %p or %s %p)\n",dp->symbol,src,dp->dest,dest); + return; + } + if ( strcmp(src->symbol,"KMD") == 0 ) + kmdheight = checkpoint.blockhash.height; + else if ( strcmp(dest->symbol,"KMD") == 0 ) + kmdheight = dest->longestchain; + if ( (bp= dp->blocks[checkpoint.blockhash.height]) == 0 ) + { + bp = calloc(1,sizeof(*bp)); + bp->minsigs = minsigs; + bp->duration = duration; + bp->srccoin = src; + bp->destcoin = dest; + bp->myind = -1; + bp->opret_symbol = dp->symbol; + if ( jsonstr != 0 && (ratified= cJSON_Parse(jsonstr)) != 0 ) + { + bp->isratify = 1; + if ( (numratified= cJSON_GetArraySize(ratified)) > 0 ) + { + if ( numratified > 64 ) + { + fprintf(stderr,"cant ratify more than 64 notaries ratified has %d\n",numratified); + return; + } + for (i=0; iratified_pubkeys[i],33,hexstr); + for (j=0; jratified_pubkeys[j],bp->ratified_pubkeys[i],33) == 0 ) + { + printf("ratification.%d is the same as %d, reject this donkey\n",j,i); + exit(-1); + } + if ( (handle= jstr(item,"handle")) != 0 ) + safecopy(bp->handles[i],handle,sizeof(bp->handles[i])); + if ( i == 0 ) + { + destprevtxid0 = jbits256(item,"destprevtxid0"); + destprevvout0 = jint(item,"destprevvout0"); + srcprevtxid0 = jbits256(item,"srcprevtxid0"); + srcprevvout0 = jint(item,"srcprevvout0"); + if ( bits256_nonz(destprevtxid0) != 0 && bits256_nonz(srcprevtxid0) != 0 ) + bp->require0 = 1; + } + } + else + { + printf("break loop hexstr.%p handle.%p\n",hexstr,handle); + break; + } + } + if ( i == numratified ) + { + bp->numratified = numratified; + bp->ratified = ratified; + printf("numratified.%d %s\n",numratified,jprint(ratified,0)); + } + else + { + printf("i.%d numratified.%d\n",i,numratified); + free_json(ratified); + } + } + } + bp->bestk = -1; + dp->blocks[checkpoint.blockhash.height] = bp; + bp->beacon = rand256(0); + vcalc_sha256(0,bp->commit.bytes,bp->beacon.bytes,sizeof(bp->beacon)); + /*if ( checkpoint.blockhash.height >= DPOW_FIRSTRATIFY && dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY] != 0 ) + { + printf("purge %s.%d\n",dp->dest,checkpoint.blockhash.height - DPOW_FIRSTRATIFY); + free(dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY]); + dp->blocks[checkpoint.blockhash.height - DPOW_FIRSTRATIFY] = 0; + }*/ + } + if ( bp->isratify != 0 && dp->ratifying != 0 ) + { + printf("new ratification starting dp->ratifying.%d\n",dp->ratifying); + dp->ratifying++; + while ( dp->ratifying > 1 ) + sleep(3); + printf("other ratifications stopped\n"); + } + if ( dp->ratifying != 0 && bp->isratify == 0 ) + { + printf("skip notarization ht.%d when ratifying\n",bp->height); + free(ptr); + return; + } + dp->ratifying += bp->isratify; + bitcoin_address(srcaddr,src->chain->pubtype,dp->minerkey33,33); + bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33); + if ( kmdheight >= 0 ) + { + ht = kmdheight;///strcmp("KMD",src->symbol) == 0 ? kmdheight : bp->height; + if ( strcmp("KMD",dest->symbol) == 0 ) + { + bp->numnotaries = komodo_notaries(dest->symbol,pubkeys,ht); + } + else + { + if ( ht == 0 ) + ht = strcmp("KMD",src->symbol) == 0 ? src->longestchain : dest->longestchain; + bp->numnotaries = komodo_notaries(src->symbol,pubkeys,ht); + } + for (i=0; inumnotaries; i++) + { + //int32_t j; for (j=0; j<33; j++) + // printf("%02x",pubkeys[i][j]); + //printf(" <= pubkey[%d]\n",i); + memcpy(bp->notaries[i].pubkey,pubkeys[i],33); + if ( strcmp("KMD",src->symbol) == 0 ) + memcpy(myinfo->notaries[i],pubkeys[i],33); + if ( memcmp(bp->notaries[i].pubkey,dp->minerkey33,33) == 0 ) + { + myind = i; + ep = &bp->notaries[myind]; + for (j=0; j<33; j++) + printf("%02x",dp->minerkey33[j]); + printf(" MYIND.%d <<<<<<<<<<<<<<<<<<<<<<\n",myind); + } + } + if ( strcmp("KMD",src->symbol) == 0 ) + myinfo->numnotaries = bp->numnotaries; + if ( myind < 0 || ep == 0 ) + { + printf("minerkey33-> "); + for (i=0; i<33; i++) + printf("%02x",dp->minerkey33[i]); + printf(" statemachinestart this node %s %s is not official notary numnotaries.%d kmdht.%d bpht.%d\n",srcaddr,destaddr,bp->numnotaries,kmdheight,bp->height); + free(ptr); + dp->ratifying -= bp->isratify; + return; + } + printf("myind.%d\n",myind); + } + else + { + printf("statemachinestart no kmdheight.%d\n",kmdheight); + free(ptr); + dp->ratifying -= bp->isratify; + return; + } + bp->myind = myind; + printf("[%d] notarize %s->%s %s ht.%d minsigs.%d duration.%d start.%u\n",bp->myind,dp->symbol,dp->dest,bits256_str(str,checkpoint.blockhash.hash),checkpoint.blockhash.height,minsigs,duration,checkpoint.timestamp); + if ( bp->isratify != 0 && memcmp(bp->notaries[0].pubkey,bp->ratified_pubkeys[0],33) != 0 ) + { + for (i=0; i<33; i++) + printf("%02x",bp->notaries[0].pubkey[i]); + printf(" current vs "); + for (i=0; i<33; i++) + printf("%02x",bp->ratified_pubkeys[0][i]); + printf(" new, cant change notary0\n"); + dp->ratifying -= bp->isratify; + return; + } + //printf(" myind.%d myaddr.(%s %s)\n",myind,srcaddr,destaddr); + if ( myind == 0 && bits256_nonz(destprevtxid0) != 0 && bits256_nonz(srcprevtxid0) != 0 && destprevvout0 >= 0 && srcprevvout0 >= 0 ) + { + ep->dest.prev_hash = destprevtxid0; + ep->dest.prev_vout = destprevvout0; + ep->src.prev_hash = srcprevtxid0; + ep->src.prev_vout = srcprevvout0; + bp->notaries[myind].ratifysrcutxo = srcprevtxid0; + bp->notaries[myind].ratifysrcvout = srcprevvout0; + bp->notaries[myind].ratifydestutxo = destprevtxid0; + bp->notaries[myind].ratifydestvout = destprevvout0; + printf("Use override utxo %s/v%d %s/v%d\n",bits256_str(str,destprevtxid0),destprevvout0,bits256_str(str2,srcprevtxid0),srcprevvout0); + } + else + { + if ( dpow_checkutxo(myinfo,dp,bp,bp->destcoin,&ep->dest.prev_hash,&ep->dest.prev_vout,destaddr) < 0 ) + { + printf("dont have %s %s utxo, please send funds\n",dp->dest,destaddr); + free(ptr); + dp->ratifying -= bp->isratify; + return; + } + if ( dpow_checkutxo(myinfo,dp,bp,bp->srccoin,&ep->src.prev_hash,&ep->src.prev_vout,srcaddr) < 0 ) + { + printf("dont have %s %s utxo, please send funds\n",dp->symbol,srcaddr); + free(ptr); + dp->ratifying -= bp->isratify; + return; + } + if ( bp->isratify != 0 ) + { + bp->notaries[myind].ratifysrcutxo = ep->src.prev_hash; + bp->notaries[myind].ratifysrcvout = ep->src.prev_vout; + bp->notaries[myind].ratifydestutxo = ep->dest.prev_hash; + bp->notaries[myind].ratifydestvout = ep->dest.prev_vout; + } + } + bp->recvmask |= (1LL << myind); + bp->notaries[myind].othermask |= (1LL << myind); + dp->checkpoint = checkpoint; + bp->height = checkpoint.blockhash.height; + bp->timestamp = checkpoint.timestamp; + bp->hashmsg = checkpoint.blockhash.hash; + bp->myind = myind; + while ( bp->isratify == 0 && dp->destupdated == 0 ) + { + if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) + { + printf("abort %s ht.%d due to new checkpoint.%d\n",dp->symbol,checkpoint.blockhash.height,dp->checkpoint.blockhash.height); + dp->ratifying -= bp->isratify; + return; + } + sleep(1); + } + starttime = (uint32_t)time(NULL); + if ( bp->isratify == 0 ) + { + //if ( (starttime= checkpoint.timestamp) == 0 ) + bp->starttime = starttime; + extralen = dpow_paxpending(extras,&bp->paxwdcrc); + bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; + } + printf("PAXWDCRC.%x myind.%d isratify.%d DPOW.%s statemachine checkpoint.%d %s start.%u+dur.%d vs %ld\n",bp->paxwdcrc,bp->myind,bp->isratify,src->symbol,checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash),starttime,bp->duration,time(NULL)); + for (i=0; iminerkey33[i+1]; + //printf("start utxosync start.%u %u\n",starttime,(uint32_t)time(NULL)); + //dpow_utxosync(myinfo,dp,bp,0,myind,srchash); + //printf("done utxosync start.%u %u\n",starttime,(uint32_t)time(NULL)); + while ( time(NULL) < starttime+bp->duration && src != 0 && dest != 0 && bp->state != 0xffffffff ) + { + if ( bp->isratify == 0 ) + { + if ( myinfo->DPOWS[0].ratifying != 0 ) + { + printf("break due to already ratifying\n"); + break; + } + extralen = dpow_paxpending(extras,&bp->paxwdcrc); + bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; + } + sleep(13); + if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) + { + if ( bp->isratify == 0 ) + { + printf("abort %s ht.%d due to new checkpoint.%d\n",dp->symbol,checkpoint.blockhash.height,dp->checkpoint.blockhash.height); + break; + } + } + if ( dp->ratifying > 1 ) + { + printf("new ratification started. abort ht.%d\n",bp->height); + break; + } + if ( bp->isratify == 0 ) + { + bits256 checkhash; + checkhash = dpow_getblockhash(myinfo,bp->srccoin,bp->height); + if ( bits256_cmp(checkhash,bp->hashmsg) != 0 ) + { + printf("%s ht.%d %s got reorged to %s, abort notarization\n",bp->srccoin->symbol,bp->height,bits256_str(str,bp->hashmsg),bits256_str(str2,checkhash)); + bp->state = 0xffffffff; + } + } + if ( bp->state != 0xffffffff ) + { + dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,0,bp->height,(void *)"ping",0); + dpow_nanomsg_update(myinfo); + } + else + { + dp->lastnotarized = checkpoint.blockhash.hash; + printf("notarized %s %s\n",dp->symbol,bits256_str(str,checkpoint.blockhash.hash)); + } + if ( 0 && dp->cancelratify != 0 && bp->isratify != 0 ) + { + printf("abort pending ratify\n"); + break; + } + } + printf("END isratify.%d:%d bestk.%d %llx sigs.%llx state.%x machine ht.%d completed state.%x %s.%s %s.%s recvmask.%llx paxwdcrc.%x %p %p\n",bp->isratify,dp->ratifying,bp->bestk,(long long)bp->bestmask,(long long)(bp->bestk>=0?bp->destsigsmasks[bp->bestk]:0),bp->state,bp->height,bp->state,dp->dest,bits256_str(str,bp->desttxid),dp->symbol,bits256_str(str2,bp->srctxid),(long long)bp->recvmask,bp->paxwdcrc,src,dest); + bp->state = 0xffffffff; + dp->lastrecvmask = bp->recvmask; + dp->ratifying -= bp->isratify; + dp->blocks[bp->height] = 0; + free(ptr); +} + diff --git a/iguana/dpow/dpow_network.c b/iguana/dpow/dpow_network.c new file mode 100755 index 000000000..0f6fb2c6a --- /dev/null +++ b/iguana/dpow/dpow_network.c @@ -0,0 +1,2405 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +struct signed_nnpacket +{ + uint8_t sig64[64]; + bits256 packethash; + uint32_t nonce,packetlen; + uint8_t packet[]; +} PACKED; + + +void dex_init(struct supernet_info *myinfo) +{ + int32_t i,j,mask = 0; char *seeds[] = { "78.47.196.146", "5.9.102.210", "149.56.29.163", "191.235.80.138", "88.198.65.74", "94.102.63.226", "129.232.225.202", "104.255.64.3", "52.72.135.200", "149.56.28.84", "103.18.58.150", "221.121.144.140", "123.249.79.12", "103.18.58.146", "27.50.93.252", "176.9.0.233", "94.102.63.227", "167.114.227.223", "27.50.68.219", "192.99.233.217", "94.102.63.217", "45.64.168.216" }; + OS_randombytes((void *)&i,sizeof(i)); + srand(i); + for (i=0; idexseed_ipaddrs)/sizeof(*myinfo->dexseed_ipaddrs); i++) + { + while ( 1 ) + { + j = (rand() % (sizeof(seeds)/sizeof(*seeds))); + if ( i < 2 ) + j = i; + if ( ((1 << j) & mask) == 0 ) + break; + } + mask |= (1 << j); +#ifdef NOTARY_TESTMODE + seeds[j] = NOTARY_TESTMODE; +#endif + printf("seed.[%d] <- %s\n",i,seeds[j]); + strcpy(myinfo->dexseed_ipaddrs[i],seeds[j]); + myinfo->dexipbits[i] = (uint32_t)calc_ipbits(myinfo->dexseed_ipaddrs[i]); + } + myinfo->numdexipbits = i; + portable_mutex_init(&myinfo->dexmutex); +} + +int32_t signed_nn_send(struct supernet_info *myinfo,void *ctx,bits256 privkey,int32_t sock,void *packet,int32_t size) +{ + int32_t i,j,sentbytes,siglen = 0; uint8_t sig[65],pubkey33[33],signpubkey33[33]; struct signed_nnpacket *sigpacket; + if ( (sigpacket= calloc(1,size + sizeof(*sigpacket))) != 0 ) + { + sigpacket->packetlen = size; + memcpy(sigpacket->packet,packet,size); + for (i=0; i<10000; i++) + { + sigpacket->nonce = i; + vcalc_sha256(0,sigpacket->packethash.bytes,(void *)&sigpacket->nonce,(int32_t)(size+sizeof(sigpacket->nonce)+sizeof(sigpacket->packetlen))); + if ( sigpacket->packethash.bytes[0] == 0 ) + break; + } + bitcoin_pubkey33(ctx,signpubkey33,privkey); + for (j=0; j<33; j++) + { + if ( i < 10000 && (siglen= bitcoin_sign(ctx,"nnsend",sig,sigpacket->packethash,privkey,1)) > 0 && siglen == 65 ) + { + memcpy(sigpacket->sig64,sig+1,64); + if ( bitcoin_recoververify(ctx,"nnrecv",sigpacket->sig64,sigpacket->packethash,pubkey33,33) == 0 ) + { + //for (i=0; i<33; i++) + // printf("%02x",pubkey33[i]); + //printf(" signed pubkey\n"); + if ( memcmp(pubkey33,signpubkey33,33) == 0 ) + { + sentbytes = nn_send(sock,sigpacket,size + sizeof(*sigpacket),0); + //for (i=0; ireqsock; + pfd.events = NN_POLLIN; + if ( nn_poll(&pfd,1,100) > 0 ) + break; + usleep(1000); + } + if ( i == 100 ) + recvbytes = 0; + else*/ if ( (recvbytes= nn_recv(sock,&sigpacket,NN_MSG,0)) > 0 ) + { + //for (i=0; ipacketlen == recvbytes-sizeof(*sigpacket)); + } + if ( sigpacket != 0 && recvbytes > sizeof(*sigpacket) && sigpacket->packetlen == recvbytes-sizeof(*sigpacket) ) + { + vcalc_sha256(0,packethash.bytes,(void *)&sigpacket->nonce,(int32_t)(sigpacket->packetlen+sizeof(sigpacket->nonce)+sizeof(sigpacket->packetlen))); + if ( bits256_cmp(packethash,sigpacket->packethash) == 0 && sigpacket->packethash.bytes[0] == 0 ) + { + if ( bitcoin_recoververify(myinfo->ctx,"nnrecv",sigpacket->sig64,sigpacket->packethash,pubkey33,33) == 0 ) + { + char *notary0 = "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828"; + // expand to official notaries + decode_hex(pubkey0,33,notary0); + if ( memcmp(pubkey0,pubkey33,33) == 0 ) + { + *(void **)packetp = (void **)((uint64_t)sigpacket + sizeof(*sigpacket)); + *freeptrp = sigpacket; + //printf("got signed packet from notary0\n"); + return((int32_t)(recvbytes - sizeof(*sigpacket))); + } + for (i=0; inonce,sigpacket->packetlen); + } else printf("hash mismatch or bad nonce.%u packetlen.%d\n",sigpacket->nonce,sigpacket->packetlen); + } else if ( recvbytes > 0 ) + printf("recvbytes.%d mismatched packetlen.%d + %ld\n",recvbytes,sigpacket!=0?sigpacket->packetlen:-1,sizeof(*sigpacket)); + //printf("free sigpacket.%p freeptrp.%p packetp.%p\n",sigpacket,*freeptrp,*(void **)packetp); + if ( sigpacket != 0 ) + nn_freemsg(sigpacket), sigpacket = 0; + *freeptrp = sigpacket; + *(void **)packetp = sigpacket; + return(0); +} + +struct dex_nanomsghdr +{ + uint32_t crc32,size,datalen,timestamp; + char handler[8]; + uint8_t version0,version1,packet[]; +} PACKED; + +struct dex_request { bits256 hash; int32_t intarg; uint16_t shortarg; char name[15]; uint8_t func; }; + +int32_t dex_rwrequest(int32_t rwflag,uint8_t *serialized,struct dex_request *dexreq) +{ + int32_t len = 0; + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(dexreq->hash),dexreq->hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(dexreq->intarg),&dexreq->intarg); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(dexreq->shortarg),&dexreq->shortarg); + if ( rwflag != 0 ) + { + memcpy(&serialized[len],dexreq->name,sizeof(dexreq->name)), len += sizeof(dexreq->name); + serialized[len++] = dexreq->func; + } + else + { + memcpy(dexreq->name,&serialized[len],sizeof(dexreq->name)), len += sizeof(dexreq->name); + dexreq->func = serialized[len++]; + } + return(len); +} + +char *nanomsg_tcpname(struct supernet_info *myinfo,char *str,char *ipaddr,uint16_t port) +{ + if ( myinfo != 0 ) // bind path) + { + if ( myinfo->bindaddr[0] != 0 && strcmp(ipaddr,myinfo->ipaddr) == 0 ) + ipaddr = myinfo->bindaddr; + } + sprintf(str,"tcp://%s:%u",ipaddr,port); + return(str); +} + +void dpow_psockloop(void *_ptr) +{ + int32_t i,nonz,size,sentbytes; uint32_t now; struct psock *ptr; void *buf; struct supernet_info *myinfo = _ptr; + while ( 1 ) + { + now = (uint32_t)time(NULL); + for (i=nonz=0; inumpsocks; i++) // change to nn_poll! + { + portable_mutex_lock(&myinfo->psockmutex); + if ( i < myinfo->numpsocks ) + { + ptr = &myinfo->PSOCKS[i]; + if ( (size= nn_recv(ptr->pullsock,&buf,NN_MSG,0)) > 0 ) + { + ptr->lasttime = now; + if ( (sentbytes= nn_send(ptr->pubsock,buf,size,0)) > 0 ) + { + //printf("PSOCKS[%d] of %d (%u %u) -> %d/%d bytes\n",i,myinfo->numpsocks,ptr->pushport,ptr->subport,size,sentbytes); + nonz++; + } + } + else if ( now > ptr->lasttime+PSOCK_IDLETIMEOUT ) + { + printf("PSOCKS[%d] of %d (%u %u) lag.%d IDLETIMEOUT\n",i,myinfo->numpsocks,ptr->pushport,ptr->subport,now - ptr->lasttime); + nn_close(ptr->pullsock); + nn_close(ptr->pubsock); + if ( myinfo->numpsocks > 1 ) + { + myinfo->PSOCKS[i] = myinfo->PSOCKS[--myinfo->numpsocks]; + memset(&myinfo->PSOCKS[myinfo->numpsocks],0,sizeof(*ptr)); + } else myinfo->numpsocks = 0; + } + if ( buf != 0 ) + nn_freemsg(buf), buf = 0; + } + portable_mutex_unlock(&myinfo->psockmutex); + } + if ( nonz == 0 ) + usleep(100000); + } +} + +void dpow_psockadd(struct supernet_info *myinfo,int32_t pullsock,uint16_t pushport,int32_t pubsock,uint16_t subport) +{ + struct psock *ptr; + portable_mutex_lock(&myinfo->psockmutex); + myinfo->PSOCKS = realloc(myinfo->PSOCKS,sizeof(*myinfo->PSOCKS) * (myinfo->numpsocks + 1)); + ptr = &myinfo->PSOCKS[myinfo->numpsocks++]; + ptr->pullsock = pullsock; + ptr->pushport = pushport; + ptr->pubsock = pubsock; + ptr->subport = subport; + ptr->lasttime = (uint32_t)time(NULL); + portable_mutex_unlock(&myinfo->psockmutex); +} + +cJSON *dpow_psock(struct supernet_info *myinfo,char *jsonstr) +{ + char pushaddr[128],subaddr[128]; uint16_t i,pushport,subport; int32_t timeout,maxsize,pullsock=-1,pubsock=-1; cJSON *retjson=0; + retjson = cJSON_CreateObject(); + pushport = myinfo->psockport++; + subport = myinfo->psockport++; + for (i=0; i<100; i++) + { + pullsock = pubsock = -1; + nanomsg_tcpname(myinfo,pushaddr,myinfo->ipaddr,pushport), pushport += 2; + nanomsg_tcpname(myinfo,subaddr,myinfo->ipaddr,subport), subport += 2; + if ( (pullsock= nn_socket(AF_SP,NN_PULL)) >= 0 && (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 ) + { + if ( nn_bind(pullsock,pushaddr) >= 0 && nn_bind(pubsock,subaddr) >= 0 ) + { + timeout = 10; + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + timeout = 1; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + timeout = 1; + maxsize = 1024 * 1024; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize)); + dpow_psockadd(myinfo,pullsock,pushport,pubsock,subport); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"pushaddr",pushaddr); + jaddstr(retjson,"subaddr",subaddr); + break; + } + if ( pullsock >= 0 ) + nn_close(pullsock); + if ( pubsock >= 0 ) + nn_close(pubsock); + } + if ( pushport < 1000 ) + pushport = 1001; + if ( subport < 1000 ) + subport = 1001; + } + if ( i == 100 ) + jaddstr(retjson,"error","cant find psock ports"); + return(retjson); +} + +static int _increasing_ipbits(const void *a,const void *b) +{ +#define uint32_a (*(uint32_t *)a) +#define uint32_b (*(uint32_t *)b) + if ( uint32_b > uint32_a ) + return(-1); + else if ( uint32_b < uint32_a ) + return(1); + return(0); +#undef uint32_a +#undef uint32_b +} + +void dex_packet(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp,int32_t size) +{ + char *retstr; int32_t datalen; struct dex_request dexreq; //struct iguana_info *coin; + //for (i=0; ihandler,"DEX") == 0 && dexp->datalen > BASILISK_KEYSIZE ) + { + printf(" uniq.%s DEX_PACKET.[%d] crc.%x lag.%d (%d %d)\n",dexp->handler,size,calc_crc32(0,dexp->packet,dexp->datalen),(int32_t)(time(NULL)-dexp->timestamp),dexp->size,dexp->datalen); + if ( (retstr= basilisk_respond_addmessage(myinfo,dexp->packet,BASILISK_KEYSIZE,&dexp->packet[BASILISK_KEYSIZE],dexp->datalen-BASILISK_KEYSIZE,0,BASILISK_DEXDURATION)) != 0 ) + free(retstr); + } + else if ( strcmp(dexp->handler,"request") == 0 ) + { + datalen = dex_rwrequest(0,dexp->packet,&dexreq); + /*if ( myinfo->IAMNOTARY != 0 && dexreq.func == 'A' && (coin= iguana_coinfind(dexreq.name)) != 0 ) + { + if ( (retstr= dpow_importaddress(myinfo,coin,(char *)&dexp->packet[datalen])) != 0 ) + free(retstr); + printf("process broadcast importaddress.(%s) [%s]\n",(char *)&dexp->packet[datalen],dexreq.name); + }*/ + } +} + +char *_dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen) +{ + struct dex_nanomsghdr *dexp; cJSON *retjson; char ipaddr[64],str[128]; int32_t prio,timeout,i,n,size,recvbytes,sentbytes = 0,reqsock,subsock; uint32_t *retptr,ipbits; void *freeptr; char *retstr = 0; + portable_mutex_lock(&myinfo->dexmutex); + subsock = myinfo->subsock; + reqsock = myinfo->reqsock; + if ( reqsock < 0 && (reqsock= nn_socket(AF_SP,NN_REQ)) >= 0 ) + { + if ( reqsock >= 0 ) + { + timeout = 1000; + nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + timeout = 1000; + nn_setsockopt(reqsock,NN_TCP,NN_RECONNECT_IVL,&timeout,sizeof(timeout)); + timeout = 10000; + nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + for (i=0; idexseed_ipaddrs)/sizeof(*myinfo->dexseed_ipaddrs); i++) + { + prio = (i/2) + 1; + //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_SNDPRIO,&prio,sizeof(prio)); + //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVPRIO,&prio,sizeof(prio)); + if ( nn_connect(reqsock,nanomsg_tcpname(0,str,myinfo->dexseed_ipaddrs[i],REP_SOCK)) < 0 ) + { + nn_close(reqsock); + reqsock = -1; + break; + } + } + } + if ( reqsock >= 0 ) + { + if ( myinfo->IAMNOTARY == 0 && subsock < 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) + { + for (i=0; idexseed_ipaddrs)/sizeof(*myinfo->dexseed_ipaddrs); i++) + if ( nn_connect(subsock,nanomsg_tcpname(0,str,myinfo->dexseed_ipaddrs[i],PUB_SOCK)) < 0 ) + { + nn_close(reqsock); + reqsock = -1; + nn_close(subsock); + subsock = -1; + break; + } + if ( reqsock >= 0 && subsock >= 0 ) + { + timeout = 1; + nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + printf("CLIENT sockets req.%d sub.%d\n",reqsock,subsock); + //timeout = 5000; + //nn_setsockopt(reqsock,NN_TCP,NN_RECONNECT_IVL,&timeout,sizeof(timeout)); + //timeout = 10000; + //nn_setsockopt(reqsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + } + } + } + } + if ( myinfo->subsock != subsock ) + myinfo->subsock = subsock; + if ( myinfo->reqsock != reqsock ) + myinfo->reqsock = reqsock; + portable_mutex_unlock(&myinfo->dexmutex); + if ( myinfo->reqsock >= 0 ) + { + size = (int32_t)(sizeof(*dexp) + keylen + datalen); + dexp = calloc(1,size); // endian dependent! + safecopy(dexp->handler,handler,sizeof(dexp->handler)); + dexp->size = size; + dexp->datalen = datalen + keylen; + dexp->timestamp = (uint32_t)time(NULL); + dexp->version0 = DEX_VERSION & 0xff; + dexp->version1 = (DEX_VERSION >> 8) & 0xff; + if ( key != 0 && keylen != 0 ) + { + memcpy(dexp->packet,key,keylen); + memcpy(&dexp->packet[keylen],data,datalen); + dexp->crc32 = calc_crc32(calc_crc32(0,key,keylen),data,datalen); + } + else + { + memcpy(dexp->packet,data,datalen); + dexp->crc32 = calc_crc32(0,data,datalen); + } + for (i=0; i<100; i++) + { + struct nn_pollfd pfd; + pfd.fd = myinfo->reqsock; + pfd.events = NN_POLLOUT; + if ( nn_poll(&pfd,1,100) > 0 ) + { + sentbytes = nn_send(myinfo->reqsock,dexp,size,0); + //printf(" [%d] sent.%d:%d datalen.%d crc.%08x\n",i,sentbytes,size,datalen,calc_crc32(0,(void *)dexp,size)); + break; + } + usleep(1000); + } + //for (i=0; inotaries,myinfo->numnotaries,myinfo->reqsock,&retptr)) >= 0 ) + { + //printf("req returned.[%d]\n",recvbytes); + portable_mutex_lock(&myinfo->dexmutex); + ipbits = 0; + if ( strcmp(handler,"DEX") == 0 ) + { + if ( retptr != 0 ) + ipbits = *retptr; + } + else if ( retptr != 0 ) + { + retstr = clonestr((char *)retptr); + //printf("GOT.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + ipbits = juint(retjson,"randipbits"); + free_json(retjson); + if ( 0 && ipbits != 0 ) + printf("GOT randipbits.%08x\n",ipbits); + } + } + if ( ipbits != 0 ) + { + expand_ipbits(ipaddr,ipbits); + n = myinfo->numdexipbits; + for (i=0; idexipbits[i] ) + break; + if ( i == n && n < 64 ) + { + myinfo->dexipbits[n++] = ipbits; + qsort(myinfo->dexipbits,n,sizeof(uint32_t),_increasing_ipbits); + if ( (myinfo->numdexipbits= n) < 3 ) + { + if ( myinfo->IAMNOTARY == 0 && myinfo->subsock >= 0 ) + { + nn_connect(myinfo->subsock,nanomsg_tcpname(0,str,ipaddr,PUB_SOCK)); + printf("%d: subscribe connect (%s)\n",myinfo->numdexipbits,str); + } + } +#ifndef NOTARY_TESTMODE + if ( (rand() % 100) < 40 ) + { + nanomsg_tcpname(0,str,ipaddr,REP_SOCK); + nn_connect(myinfo->reqsock,str); + printf("%d: req connect (%s)\n",myinfo->numdexipbits,str); + } +#endif + } + } + if ( freeptr != 0 ) + nn_freemsg(freeptr), freeptr = 0, retptr = 0; + portable_mutex_unlock(&myinfo->dexmutex); + } + else + { + //retval = -2; + printf("no rep return? recvbytes.%d\n",recvbytes); + } + //printf("DEXREQ.[%d] crc32.%08x datalen.%d sent.%d recv.%d timestamp.%u\n",size,dexp->crc32,datalen,sentbytes,recvbytes,dexp->timestamp); + free(dexp); + } //else retval = -1; + return(retstr); +} + +void dex_channelsend(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen) +{ + int32_t keylen; uint8_t key[BASILISK_KEYSIZE]; char *retstr; + keylen = basilisk_messagekey(key,channel,msgid,srchash,desthash); + if ( (retstr= _dex_reqsend(myinfo,"DEX",key,keylen,data,datalen)) != 0 ) + free(retstr); +} + +void dpow_randipbits(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson) +{ + int32_t m; uint32_t ipbits; char *coinstr; cJSON *infojson; + if ( is_cJSON_Array(retjson) == 0 ) + { + if ( (m= myinfo->numdpowipbits) > 0 ) + { + ipbits = myinfo->dpowipbits[(uint32_t)rand() % m]; + jaddnum(retjson,"randipbits",ipbits); + //printf("add randipbits.%08x\n",ipbits); + } + if ( (coinstr= jstr(retjson,"coin")) == 0 ) + jaddstr(retjson,"coin",coin->symbol); + if ( (infojson= dpow_getinfo(myinfo,coin)) != 0 ) + { + jaddnum(retjson,"notaryheight",juint(infojson,"blocks")); + free_json(infojson); + } + } +} + +char *dex_response(int32_t *broadcastflagp,struct supernet_info *myinfo,struct dex_nanomsghdr *dexp) +{ + char buf[65],*retstr = 0; int32_t i,datalen; bits256 hash2; cJSON *retjson=0; struct iguana_info *coin; struct dex_request dexreq; + *broadcastflagp = 0; +return(clonestr("{\"error\":\"basilisk disabled\"}")); + + if ( strcmp(dexp->handler,"request") == 0 ) + { + datalen = dex_rwrequest(0,dexp->packet,&dexreq); + //printf("dex_response.%s (%c)\n",dexreq.name,dexreq.func); + if ( (coin= iguana_coinfind(dexreq.name)) != 0 ) + { + if ( dexreq.func == 'T' ) + { + if ( (retjson= dpow_gettransaction(myinfo,coin,dexreq.hash)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'O' ) + { + if ( (retjson= dpow_gettxout(myinfo,coin,dexreq.hash,dexreq.shortarg)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'x' ) + { + if ( (retjson= dpow_gettxin(myinfo,coin,dexreq.hash,dexreq.shortarg)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'H' ) + { + hash2 = dpow_getblockhash(myinfo,coin,dexreq.intarg); + //printf("getblockhash %d -> (%s)\n",dexreq.intarg,bits256_str(buf,hash2)); + bits256_str(buf,hash2); + retstr = clonestr(buf); + } + else if ( dexreq.func == 'B' ) + { + if ( (retjson= dpow_getblock(myinfo,coin,dexreq.hash)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'b' ) + { + if ( (retjson= dpow_getbalance(myinfo,coin,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'I' ) + { + if ( (retjson= dpow_getinfo(myinfo,coin)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'k' ) + { + if ( strcmp(coin->symbol,"BTC") == 0 || strcmp(coin->symbol,"ZEC") == 0 || coin->chain->zcash == 0 ) + retstr = clonestr("{\"error\":\"only komodod chains support KV\"}"); + else if ( (retjson= dpow_kvsearch(myinfo,coin,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'K' ) + { + if ( strcmp(coin->symbol,"BTC") == 0 || strcmp(coin->symbol,"ZEC") == 0 || coin->chain->zcash == 0 ) + retstr = clonestr("{\"error\":\"only komodod chains support KV\"}"); + else if ( (retjson= dpow_kvupdate(myinfo,coin,(char *)&dexp->packet[datalen],(char *)&dexp->packet[datalen+dexreq.shortarg],dexreq.intarg)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'U' ) + { + if ( (retjson= dpow_listunspent(myinfo,coin,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'u' ) + { + if ( (retjson= kmd_listunspent(myinfo,coin,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + //printf("RETURN.(%s)\n",retstr); + } + } + else if ( dexreq.func == 's' ) + { + if ( (retjson= dpow_listspent(myinfo,coin,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'P' ) + { + hash2 = dpow_getbestblockhash(myinfo,coin); + bits256_str(buf,hash2); + retstr = clonestr(buf); + } + else if ( dexreq.func == 'S' ) + { + retstr = dpow_sendrawtransaction(myinfo,coin,(char *)&dexp->packet[datalen]); + } + else if ( dexreq.func == '*' ) + { + retstr = dpow_alladdresses(myinfo,coin); + } + else if ( dexreq.func == 'L' ) + { + //printf("call list.(%s %d %d)\n",(char *)&dexp->packet[datalen],dexreq.shortarg,dexreq.intarg); + if ( (retjson= dpow_listtransactions(myinfo,coin,(char *)&dexp->packet[datalen],dexreq.shortarg,dexreq.intarg)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == '2' ) + { + //printf("call list.(%s %d %d)\n",(char *)&dexp->packet[datalen],dexreq.shortarg,dexreq.intarg); + if ( (retjson= kmd_listtransactions(myinfo,coin,(char *)&dexp->packet[datalen],dexreq.shortarg,dexreq.intarg)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'C' ) + { + if ( (retjson= dpow_checkaddress(myinfo,coin,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'A' ) + { + retstr = dpow_importaddress(myinfo,coin,(char *)&dexp->packet[datalen]); + if ( retstr == 0 ) + { + //*broadcastflagp = 1; + retstr = dpow_validateaddress(myinfo,coin,(char *)&dexp->packet[datalen]); + } + else + { + printf("funcA.(%s)\n",retstr); + } + if ( retstr != 0 && (retjson= cJSON_Parse(retstr)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + free(retstr); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'V' ) + { + retstr = dpow_validateaddress(myinfo,coin,(char *)&dexp->packet[datalen]); + if ( retstr != 0 && (retjson= cJSON_Parse(retstr)) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + free(retstr); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'M' ) + { + if ( (retjson= dpow_getmessage(myinfo,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'Z' ) + { + if ( (retjson= dpow_psock(myinfo,(char *)&dexp->packet[datalen])) != 0 ) + { + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( 0 && dexreq.func == 'a' ) + { + if ( (retjson= dpow_addmessage(myinfo,(char *)&dexp->packet[datalen])) != 0 ) + { + *broadcastflagp = 1; + dpow_randipbits(myinfo,coin,retjson); + retstr = jprint(retjson,1); + } + } + else if ( dexreq.func == 'N' ) + { + uint8_t pubkeys[64][33]; char str[128]; int32_t numnotaries; cJSON *array,*item; + if ( (numnotaries= komodo_notaries("KMD",pubkeys,-1)) > 0 && numnotaries <= 64 ) + { + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (i=0; i (%s)\n",retstr); + } + } + else + { + static uint32_t counter; + if ( counter++ < 10 ) + printf("request came in from GUI for (%s) that is not active\n",dexreq.name); + } + if ( retstr == 0 ) + return(clonestr("{\"error\":\"null return\"}")); + } + return(retstr); +} + +char *dex_reqsend(struct supernet_info *myinfo,char *handler,uint8_t *data,int32_t datalen,int32_t M,char *field) +{ + char *retstrs[64],*origretstr0 = 0; cJSON *retjson; int32_t err,i,j,max = myinfo->numdexipbits; + memset(retstrs,0,sizeof(retstrs)); + for (i=j=0; i<=max; i++) + { + if ( (retstrs[j]= _dex_reqsend(myinfo,handler,0,0,data,datalen)) != 0 ) + { +//printf("j.%d of max.%d M.%d (%s)\n",j,max,M,retstrs[j]); + if ( strncmp(retstrs[j],"{\"error\":\"null return\"}",strlen("{\"error\":\"null return\"}")) != 0 && strncmp(retstrs[j],"[]",strlen("[]")) != 0 && strcmp("0",retstrs[j]) != 0 ) + { + if ( ++j == M ) + break; + } + else if ( i < max ) + free(retstrs[j]); + } + //printf("automatic retry.%d of %d\n",i,max); + } + if ( j == 1 ) + { + //printf("return.(%s)\n",retstrs[0]); + return(retstrs[0]); + } + else if ( j >= M ) + { + origretstr0 = retstrs[0]; + err = 0; + if ( strcmp(field,"*") != 0 ) + { + for (i=0; iname) >= 0 ) + { + datalen = dex_rwrequest(1,packet,dexreq); + return(dex_reqsend(myinfo,"request",packet,datalen,M,field)); + } else return(clonestr("{\"error\":\"not notarychain\"}")); +} + +char *_dex_sendrequeststr(struct supernet_info *myinfo,struct dex_request *dexreq,char *str,int32_t slen,int32_t M,char *field) +{ + uint8_t *packet; int32_t datalen; char *retstr; + if ( iguana_isnotarychain(dexreq->name) >= 0 ) + { + if ( slen == 0 ) + slen = (int32_t)strlen(str)+1; + packet = calloc(1,sizeof(*dexreq)+slen); + datalen = dex_rwrequest(1,packet,dexreq); + memcpy((char *)&packet[datalen],str,slen); + datalen += slen; + retstr = dex_reqsend(myinfo,"request",packet,datalen,M,field); + free(packet); + return(retstr); + } else return(clonestr("{\"error\":\"not notarychain\"}")); +} + +char *_dex_getrawtransaction(struct supernet_info *myinfo,char *symbol,bits256 txid) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.hash = txid; + dexreq.func = 'T'; + return(_dex_sendrequest(myinfo,&dexreq,1,"")); +} + +char *_dex_gettxout(struct supernet_info *myinfo,char *symbol,bits256 txid,int32_t vout) +{ + struct dex_request dexreq; + //char str[65]; printf("gettxout(%s %s %d)\n",symbol,bits256_str(str,txid),vout); + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.hash = txid; + dexreq.shortarg = vout; + dexreq.func = 'O'; + return(_dex_sendrequest(myinfo,&dexreq,3,"value")); +} + +char *_dex_gettxin(struct supernet_info *myinfo,char *symbol,bits256 txid,int32_t vout) +{ + struct dex_request dexreq; + //char str[65]; printf("gettxout(%s %s %d)\n",symbol,bits256_str(str,txid),vout); + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.hash = txid; + dexreq.shortarg = vout; + dexreq.func = 'x'; + return(_dex_sendrequest(myinfo,&dexreq,1,"")); +} + +char *_dex_kvupdate(struct supernet_info *myinfo,char *symbol,char *key,char *value,int32_t flags) +{ + struct dex_request dexreq; char keyvalue[IGUANA_MAXSCRIPTSIZE]; int32_t keylen,valuesize; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'K'; + dexreq.intarg = flags; + keylen = (int32_t)strlen(key); + memcpy(keyvalue,key,keylen+1); + valuesize = (int32_t)strlen(value); + dexreq.shortarg = keylen+1; + memcpy(&keyvalue[dexreq.shortarg],value,valuesize+1); + //printf("_DEX.(%s) -> (%s) flags.%d\n",key,value,flags); + return(_dex_sendrequeststr(myinfo,&dexreq,keyvalue,keylen+valuesize+2,1,"")); +} + +char *_dex_kvsearch(struct supernet_info *myinfo,char *symbol,char *key) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'k'; + return(_dex_sendrequeststr(myinfo,&dexreq,key,0,1,"")); +} + +char *_dex_getinfo(struct supernet_info *myinfo,char *symbol) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'I'; + return(_dex_sendrequest(myinfo,&dexreq,1,"")); +} + +int32_t _dex_getheight(struct supernet_info *myinfo,char *symbol) +{ + char *retstr; cJSON *retjson; int32_t height = -1; + if ( (retstr= _dex_getinfo(myinfo,symbol)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + height = jint(retjson,"blocks") - 1; + free_json(retjson); + } + free(retstr); + } + return(height); +} + +char *_dex_getnotaries(struct supernet_info *myinfo,char *symbol) +{ + struct dex_request dexreq; char *retstr,*pubkeystr; cJSON *retjson,*array,*item; int32_t i,n; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'N'; + dexreq.intarg = -1; + if ( (retstr= _dex_sendrequest(myinfo,&dexreq,1,"")) != 0 ) + { + if ( myinfo->numnotaries <= 0 && (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (myinfo->numnotaries= jint(retjson,"numnotaries")) != 0 && (array= jarray(&n,retjson,"notaries")) != 0 && n == myinfo->numnotaries ) + { + for (i=0; inotaries[i],33,pubkeystr); + } + } + else + { + extern const char *Notaries_elected[][2]; + myinfo->numnotaries = 64;//sizeof(Notaries_elected)/sizeof(*Notaries_elected); + for (i=0; inumnotaries; i++) + { + decode_hex(myinfo->notaries[i],33,(char *)Notaries_elected[i][1]); + } + printf("default to elected.%d\n",myinfo->numnotaries); + } + free_json(retjson); + } + } + return(retstr); +} + +char *_dex_alladdresses(struct supernet_info *myinfo,char *symbol) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = '*'; + return(_dex_arrayreturn(_dex_sendrequest(myinfo,&dexreq,1,""))); +} + +char *_dex_getblock(struct supernet_info *myinfo,char *symbol,bits256 hash2) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.hash = hash2; + dexreq.func = 'B'; + return(_dex_sendrequest(myinfo,&dexreq,1,"")); +} + +char *_dex_getblockhash(struct supernet_info *myinfo,char *symbol,int32_t height) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.intarg = height; + dexreq.func = 'H'; + return(_dex_sendrequest(myinfo,&dexreq,3,"*")); +} + +char *_dex_getbestblockhash(struct supernet_info *myinfo,char *symbol) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'P'; + return(_dex_sendrequest(myinfo,&dexreq,1,"")); +} + +char *_dex_sendrawtransaction(struct supernet_info *myinfo,char *symbol,char *signedtx) +{ + struct dex_request dexreq; char *retstr; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'S'; + retstr = _dex_sendrequeststr(myinfo,&dexreq,signedtx,0,1,"*"); + //printf("RET.(%s)\n",retstr); + return(retstr); +} + +char *_dex_importaddress(struct supernet_info *myinfo,char *symbol,char *address) +{ + struct dex_request dexreq; +return(clonestr("{\"error\":\"importaddress deprecated\"}")); + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'A'; + return(_dex_sendrequeststr(myinfo,&dexreq,address,0,1,"")); +} + +char *_dex_checkaddress(struct supernet_info *myinfo,char *symbol,char *address) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'C'; + return(_dex_sendrequeststr(myinfo,&dexreq,address,0,3,"address")); +} + +char *_dex_validateaddress(struct supernet_info *myinfo,char *symbol,char *address) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'V'; + return(_dex_sendrequeststr(myinfo,&dexreq,address,0,1,"")); +} + +char *_dex_getmessage(struct supernet_info *myinfo,char *jsonstr) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,"KMD",sizeof(dexreq.name)); + dexreq.func = 'M'; + return(_dex_sendrequeststr(myinfo,&dexreq,jsonstr,0,1,"")); +} + +char *_dex_sendmessage(struct supernet_info *myinfo,char *jsonstr) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,"KMD",sizeof(dexreq.name)); + dexreq.func = 'a'; + return(_dex_sendrequeststr(myinfo,&dexreq,jsonstr,0,1,"")); +} + +char *_dex_psock(struct supernet_info *myinfo,char *jsonstr) +{ + struct dex_request dexreq; + if ( jsonstr == 0 ) + jsonstr = "{}"; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,"KMD",sizeof(dexreq.name)); + dexreq.func = 'Z'; + return(_dex_sendrequeststr(myinfo,&dexreq,jsonstr,0,1,"")); +} + +char *_dex_listunspentarg(struct supernet_info *myinfo,char *symbol,char *address,uint8_t arg) +{ + struct dex_request dexreq; char *retstr; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = arg; + if ( (retstr= _dex_sendrequeststr(myinfo,&dexreq,address,0,1,"")) != 0 ) + { + //printf("_dex_listunspentarg: %s UNSPENTS.(%s)\n",symbol,retstr); + } + return(_dex_arrayreturn(retstr)); +} + +char *_dex_listunspent(struct supernet_info *myinfo,char *symbol,char *address) +{ + char *retstr; + retstr = _dex_listunspentarg(myinfo,symbol,address,'u'); // 'U' old variant + //printf("_dex_listunspent.(%s)\n",retstr); + return(retstr); +} + +char *_dex_listunspent2(struct supernet_info *myinfo,char *symbol,char *address) +{ + return(_dex_listunspentarg(myinfo,symbol,address,'u')); +} + +char *_dex_listspent(struct supernet_info *myinfo,char *symbol,char *address) +{ + struct dex_request dexreq; char *retstr; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 's'; + if ( (retstr= _dex_sendrequeststr(myinfo,&dexreq,address,0,1,"")) != 0 ) + { + //printf("UNSPENTS.(%s)\n",retstr); + } + return(_dex_arrayreturn(retstr)); +} + +char *_dex_getbalance(struct supernet_info *myinfo,char *symbol,char *address) +{ + struct dex_request dexreq; char *retstr; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.func = 'b'; + if ( (retstr= _dex_sendrequeststr(myinfo,&dexreq,address,0,1,"")) != 0 ) + { + //printf("UNSPENTS.(%s)\n",retstr); + } + return(_dex_arrayreturn(retstr)); +} + +char *_dex_listtransactions(struct supernet_info *myinfo,char *symbol,char *address,int32_t count,int32_t skip) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.intarg = skip; + dexreq.shortarg = count; + dexreq.func = '2';//'L'; + return(_dex_arrayreturn(_dex_sendrequeststr(myinfo,&dexreq,address,0,1,""))); +} + +char *_dex_listtransactions2(struct supernet_info *myinfo,char *symbol,char *address,int32_t count,int32_t skip) +{ + struct dex_request dexreq; + memset(&dexreq,0,sizeof(dexreq)); + safecopy(dexreq.name,symbol,sizeof(dexreq.name)); + dexreq.intarg = skip; + dexreq.shortarg = count; + dexreq.func = '2'; + return(_dex_arrayreturn(_dex_sendrequeststr(myinfo,&dexreq,address,0,1,""))); +} + +int32_t dex_crc32find(struct supernet_info *myinfo,uint32_t crc32) +{ + int32_t i,firstz = -1; + for (i=0; idexcrcs)/sizeof(*myinfo->dexcrcs); i++) + { + if ( myinfo->dexcrcs[i] == crc32 ) + { + //printf("NANODUPLICATE.%08x\n",crc32); + return(-1); + } + else if ( firstz < 0 && myinfo->dexcrcs[i] == 0 ) + firstz = i; + } + if ( firstz < 0 ) + firstz = (rand() % (sizeof(myinfo->dexcrcs)/sizeof(*myinfo->dexcrcs))); + myinfo->dexcrcs[firstz] = crc32; + return(firstz); +} + +int32_t dex_packetcheck(struct supernet_info *myinfo,struct dex_nanomsghdr *dexp,int32_t size) +{ + uint32_t crc32; //int32_t firstz=-1; + if ( dexp->version0 == (DEX_VERSION & 0xff) && dexp->version1 == ((DEX_VERSION >> 8) & 0xff) ) + { + if ( dexp->datalen == (size - sizeof(*dexp)) ) + { + crc32 = calc_crc32(0,dexp->packet,dexp->datalen);//(void *)((long)dexp + sizeof(dexp->crc32)),(int32_t)(size - sizeof(dexp->crc32))); + if ( dexp->crc32 == crc32 )//&& (firstz= dex_crc32find(myinfo,crc32)) >= 0 ) + return(0); + //else printf("dexp %08x != %08x || firstz.%d < 0\n",dexp->crc32,crc32,firstz); + } else printf("datalen.%d != (%d - %ld)\n",dexp->datalen,size,sizeof(*dexp)); + } + return(-1); +} + +int32_t dex_subsock_poll(struct supernet_info *myinfo) +{ + int32_t size= -1; struct dex_nanomsghdr *dexp; void *freeptr; + //return(0); + //fprintf(stderr,"subsock.%d\n",myinfo->subsock); + if ( myinfo->subsock >= 0 && (size= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->subsock,&dexp)) >= 0 ) + { + if ( dexp != 0 ) + { + //printf("SUBSOCK.%08x recv.%d datalen.%d\n",dexp->crc32,size,dexp->datalen); + if ( dex_packetcheck(myinfo,dexp,size) == 0 ) + dex_packet(myinfo,dexp,size); + } //else printf("size.%d\n",size); + if ( freeptr != 0 ) + nn_freemsg(freeptr), dexp = 0, freeptr = 0; + } + return(size); +} + +void dex_updateclient(struct supernet_info *myinfo) +{ + int32_t i; + if ( myinfo->IAMNOTARY == 0 ) + { + for (i=0; i<1000; i++) + if ( dex_subsock_poll(myinfo) <= 0 ) + break; + } +} + +#if ISNOTARYNODE +struct dpow_nanoutxo +{ + bits256 srcutxo,destutxo; + uint64_t bestmask,recvmask; + uint32_t pendingcrcs[2],paxwdcrc; + uint16_t srcvout,destvout; + uint8_t sigs[2][DPOW_MAXSIGLEN],siglens[2],pad,bestk; +} PACKED; + +struct dpow_nanomsghdr +{ + bits256 srchash,desthash; + struct dpow_nanoutxo ratify,notarize; + uint32_t channel,height,size,datalen,crc32,myipbits,numipbits,ipbits[128]; + char symbol[16]; + uint8_t senderind,version0,version1,packet[]; +} PACKED; + + +uint64_t dpow_ratifybest(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp); +struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height); +int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t myind,uint32_t deprec,int32_t src_or_dest,int32_t useratified); +void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,int32_t myind,int32_t src_or_dest,int8_t bestk,uint64_t bestmask,uint8_t pubkeys[64][33],int32_t numratified); + +int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *ipaddr) +{ + char str[512]; uint32_t ipbits,*ptr; int32_t i,iter,n,retval = -1; + if ( myinfo->IAMNOTARY == 0 ) + return(-1); + portable_mutex_lock(&myinfo->notarymutex); + if ( myinfo->dpowsock >= 0 && myinfo->dexsock >= 0 ) + { + ipbits = (uint32_t)calc_ipbits(ipaddr); + for (iter=0; iter<2; iter++) + { + if ( iter == 0 ) + { + n = myinfo->numdpowipbits; + ptr = myinfo->dpowipbits; + } + else + { + n = dp->numipbits; + ptr = dp->ipbits; + } + for (i=0; iipaddr) != 0 ) + { + retval = nn_connect(myinfo->dpowsock,nanomsg_tcpname(0,str,ipaddr,DPOW_SOCK)); + printf("NN_CONNECT to (%s)\n",str); + retval = nn_connect(myinfo->dexsock,nanomsg_tcpname(0,str,ipaddr,DEX_SOCK)); + } + n++; + qsort(ptr,n,sizeof(uint32_t),_increasing_ipbits); + if ( iter == 0 ) + myinfo->numdpowipbits = n; + else dp->numipbits = n; + //for (i=0; inumdpowipbits,dp!=0?dp->numipbits:-1,iter); + } + if ( dp == 0 ) + break; + } + } + portable_mutex_unlock(&myinfo->notarymutex); + return(retval); +} + +void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr) +{ + char str[512]; int32_t timeout,retval,maxsize,dpowsock,dexsock,repsock,pubsock; + if ( myinfo->ipaddr[0] == 0 ) + { + printf("need to set ipaddr before nanomsg\n"); + return; + } + if ( myinfo->IAMNOTARY == 0 ) + return; + portable_mutex_lock(&myinfo->notarymutex); + dpowsock = myinfo->dpowsock; + dexsock = myinfo->dexsock; + repsock = myinfo->repsock; + pubsock = myinfo->pubsock; + if ( dpowsock < 0 && (dpowsock= nn_socket(AF_SP,NN_BUS)) >= 0 ) + { + if ( nn_bind(dpowsock,nanomsg_tcpname(myinfo,str,myinfo->ipaddr,DPOW_SOCK)) < 0 ) + { + printf("error binding to dpowsock (%s)\n",nanomsg_tcpname(myinfo,str,myinfo->ipaddr,DPOW_SOCK)); + nn_close(dpowsock); + dpowsock = -1; + } + else + { + printf("NN_BIND to %s\n",str); + if ( dexsock < 0 && (dexsock= nn_socket(AF_SP,NN_BUS)) >= 0 ) + { + if ( nn_bind(dexsock,nanomsg_tcpname(myinfo,str,myinfo->ipaddr,DEX_SOCK)) < 0 ) + { + printf("error binding to dexsock (%s)\n",nanomsg_tcpname(myinfo,str,myinfo->ipaddr,DEX_SOCK)); + nn_close(dexsock); + dexsock = -1; + nn_close(dpowsock); + dpowsock = -1; + } + else + { + if ( pubsock < 0 && (pubsock= nn_socket(AF_SP,NN_PUB)) >= 0 ) + { + if ( nn_bind(pubsock,nanomsg_tcpname(myinfo,str,myinfo->ipaddr,PUB_SOCK)) < 0 ) + { + printf("error binding to pubsock (%s)\n",nanomsg_tcpname(myinfo,str,myinfo->ipaddr,PUB_SOCK)); + nn_close(pubsock); + pubsock = -1; + nn_close(dexsock); + dexsock = -1; + nn_close(dpowsock); + dpowsock = -1; + } + else + { + if ( repsock < 0 && (repsock= nn_socket(AF_SP,NN_REP)) >= 0 ) + { + if ( nn_bind(repsock,nanomsg_tcpname(myinfo,str,myinfo->ipaddr,REP_SOCK)) < 0 ) + { + printf("error binding to repsock (%s)\n",nanomsg_tcpname(myinfo,str,myinfo->ipaddr,REP_SOCK)); + nn_close(repsock); + repsock = -1; + nn_close(pubsock); + pubsock = -1; + nn_close(dexsock); + dexsock = -1; + nn_close(dpowsock); + dpowsock = -1; + } + else + { + timeout = 100; + nn_setsockopt(repsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(dexsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + timeout = 1; + nn_setsockopt(dexsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + timeout = 1; + nn_setsockopt(repsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + maxsize = 1024 * 1024; + printf("RCVBUF.%d\n",nn_setsockopt(dexsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize))); + printf("RCVBUF.%d\n",nn_setsockopt(repsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize))); + printf("DEXINIT dpow.%d dex.%d rep.%d\n",dpowsock,dexsock,repsock); + } + } + } + } + } + } + myinfo->dpowipbits[0] = (uint32_t)calc_ipbits(myinfo->ipaddr); + myinfo->numdpowipbits = 1; + timeout = 1; + nn_setsockopt(dpowsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + maxsize = 1024 * 1024; + printf("RCVBUF.%d\n",nn_setsockopt(dpowsock,NN_SOL_SOCKET,NN_RCVBUF,&maxsize,sizeof(maxsize))); + + myinfo->nanoinit = (uint32_t)time(NULL); + } + } //else printf("error creating nanosocket\n"); + if ( myinfo->dpowsock != dpowsock ) + myinfo->dpowsock = dpowsock; + if ( myinfo->dexsock != dexsock ) + myinfo->dexsock = dexsock; + if ( myinfo->repsock != repsock ) + myinfo->repsock = repsock; + if ( myinfo->pubsock != pubsock ) + myinfo->pubsock = pubsock; + portable_mutex_unlock(&myinfo->notarymutex); + dpow_addnotary(myinfo,0,ipaddr); +} + +void dpow_bestconsensus(struct dpow_block *bp) +{ + int8_t bestks[64]; int32_t counts[64],i,j,numcrcs=0,numdiff,besti,best,bestmatches = 0,matches = 0; uint64_t masks[64],matchesmask,recvmask; uint32_t crcval=0; char srcaddr[64],destaddr[64]; + memset(masks,0,sizeof(masks)); + memset(bestks,0xff,sizeof(bestks)); + memset(counts,0,sizeof(counts)); + recvmask = 0; + for (numdiff=i=0; inumnotaries; i++) + { + if ( bits256_nonz(bp->notaries[i].src.prev_hash) != 0 && bits256_nonz(bp->notaries[i].dest.prev_hash) != 0 ) + recvmask |= (1LL << i); + if ( bp->notaries[i].bestk < 0 || bp->notaries[i].bestmask == 0 ) + continue; + //if ( bp->require0 != 0 && (bp->notaries[i].bestmask & 1) == 0 ) + // continue; + for (j=0; jnotaries[i].bestk == bestks[j] && bp->notaries[i].bestmask == masks[j] ) + { + counts[j]++; + break; + } + if ( j == numdiff && bp->notaries[i].bestk >= 0 && bp->notaries[i].bestmask != 0 ) + { + masks[numdiff] = bp->notaries[i].bestmask; + bestks[numdiff] = bp->notaries[i].bestk; + counts[numdiff]++; + //printf("j.%d numdiff.%d (%d %llx).%d\n",j,numdiff,bp->notaries[i].bestk,(long long)bp->notaries[i].bestmask,counts[numdiff]); + numdiff++; + } + } + besti = -1, best = 0; + for (i=0; i best && bitweight(masks[i]) >= bp->minsigs ) + { + best = counts[i]; + besti = i; + } + } + if ( besti >= 0 && bestks[besti] >= 0 && masks[besti] != 0 && (recvmask & masks[besti]) == masks[besti] ) + { + bp->notaries[bp->myind].bestmask = bp->bestmask = masks[besti]; + bp->notaries[bp->myind].bestk = bp->bestk = bestks[besti]; + //printf("set best.%d to (%d %llx) recv.%llx\n",best,bp->bestk,(long long)bp->bestmask,(long long)recvmask); + } + bp->recvmask |= recvmask; + if ( bp->bestmask == 0 )//|| (time(NULL) / 180) != bp->lastepoch ) + { + bp->bestmask = dpow_notarybestk(bp->recvmask,bp,&bp->bestk); + if ( 0 && (time(NULL) / 180) != bp->lastepoch ) + { + bp->lastepoch = (uint32_t)(time(NULL) / 180); + printf("epoch %u\n",bp->lastepoch % bp->numnotaries); + sleep(1 + (rand() % 3)); + } + } +} + +void dpow_nanoutxoset(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_nanoutxo *np,struct dpow_block *bp,int32_t isratify) +{ + int32_t i,err,vout; cJSON *ujson; char coinaddr[64],str[65]; + if ( bp->myind < 0 ) + return; + if ( isratify != 0 ) + { + np->srcutxo = bp->notaries[bp->myind].ratifysrcutxo; + np->srcvout = bp->notaries[bp->myind].ratifysrcvout; + np->destutxo = bp->notaries[bp->myind].ratifydestutxo; + np->destvout = bp->notaries[bp->myind].ratifydestvout; + if ( bp->myind != 0 ) + { + err = 0; + if ( (ujson= dpow_gettxout(myinfo,bp->srccoin,np->srcutxo,np->srcvout)) != 0 ) + { + if ( (uint64_t)(jdouble(ujson,"value") * SATOSHIDEN) == 0 ) + { + //printf("(%s)\n",jprint(ujson,0)); + err = 1; + } + free_json(ujson); + } else err = 1; + if ( err != 0 ) + { + bitcoin_address(coinaddr,bp->srccoin->chain->pubtype,dp->minerkey33,33); + if ( dpow_haveutxo(myinfo,bp->srccoin,&bp->notaries[bp->myind].ratifysrcutxo,&vout,coinaddr) > 0 ) + { + bp->notaries[bp->myind].ratifysrcvout = vout; + np->srcutxo = bp->notaries[bp->myind].ratifysrcutxo; + np->srcvout = bp->notaries[bp->myind].ratifysrcvout; + printf("Replace UTXO.%s < %s/v%d\n",bp->srccoin->symbol,bits256_str(str,np->srcutxo),vout); + } else printf("cant find utxo.%s\n",bp->srccoin->symbol); + } + err = 0; + if ( (ujson= dpow_gettxout(myinfo,bp->destcoin,np->destutxo,np->destvout)) != 0 ) + { + if ( (uint64_t)(jdouble(ujson,"value") * SATOSHIDEN) == 0 ) + err = 1; + free_json(ujson); + } else err = 1; + if ( err != 0 ) + { + bitcoin_address(coinaddr,bp->destcoin->chain->pubtype,dp->minerkey33,33); + if ( dpow_haveutxo(myinfo,bp->destcoin,&bp->notaries[bp->myind].ratifydestutxo,&vout,coinaddr) > 0 ) + { + bp->notaries[bp->myind].ratifydestvout = vout; + np->destutxo = bp->notaries[bp->myind].ratifydestutxo; + np->destvout = bp->notaries[bp->myind].ratifydestvout; + printf("Replace UTXO.%s < %s/v%d\n",bp->destcoin->symbol,bits256_str(str,np->destutxo),vout); + } else printf("cant find utxo.%s\n",bp->destcoin->symbol); + } + } + np->bestmask = bp->ratifybestmask; + np->recvmask = bp->ratifyrecvmask; + //printf("send ratify best.(%d %llx) siglens.(%d %d)\n", bp->ratifybestk,(long long)bp->ratifybestmask,bp->ratifysiglens[0],bp->ratifysiglens[1]); + if ( (np->bestk= bp->ratifybestk) >= 0 ) + { + for (i=0; i<2; i++) + { + if ( (np->siglens[i]= bp->ratifysiglens[i]) > 0 ) + memcpy(np->sigs[i],bp->ratifysigs[i],np->siglens[i]); + } + } + } + else + { + dpow_bestconsensus(bp); + np->srcutxo = bp->notaries[bp->myind].src.prev_hash; + np->srcvout = bp->notaries[bp->myind].src.prev_vout; + np->destutxo = bp->notaries[bp->myind].dest.prev_hash; + np->destvout = bp->notaries[bp->myind].dest.prev_vout; + if ( (np->recvmask= bp->recvmask) == 0 ) + np->recvmask = bp->notaries[bp->myind].recvmask; + if ( (np->bestmask= bp->pendingbestmask) == 0 ) + { + if ( (np->bestmask= bp->notaries[bp->myind].bestmask) == 0 ) + np->bestmask = bp->bestmask, np->bestk = bp->bestk; + else np->bestk = bp->notaries[bp->myind].bestk; + } else np->bestk = bp->pendingbestk; + if ( (int8_t)np->bestk >= 0 ) + { + if ( (np->siglens[0]= bp->notaries[bp->myind].src.siglens[bp->bestk]) > 0 ) + memcpy(np->sigs[0],bp->notaries[bp->myind].src.sigs[bp->bestk],np->siglens[0]); + if ( (np->siglens[1]= bp->notaries[bp->myind].dest.siglens[bp->bestk]) > 0 ) + memcpy(np->sigs[1],bp->notaries[bp->myind].dest.sigs[bp->bestk],np->siglens[1]); + } + } +} + +void dpow_ratify_update(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint8_t senderind,int8_t bestk,uint64_t bestmask,uint64_t recvmask,bits256 srcutxo,uint16_t srcvout,bits256 destutxo,uint16_t destvout,uint8_t siglens[2],uint8_t sigs[2][DPOW_MAXSIGLEN],uint32_t pendingcrcs[2]) +{ + int8_t bestks[64]; int32_t counts[64],i,j,numcrcs=0,numdiff,besti,best,bestmatches = 0,matches = 0; uint64_t masks[64],matchesmask; uint32_t crcval=0; char srcaddr[64],destaddr[64]; + //char str[65],str2[65]; + //printf("senderind.%d num.%d %s %s\n",senderind,bp->numnotaries,bits256_str(str,srcutxo),bits256_str(str2,destutxo)); + if ( bp->myind < 0 ) + return; + if ( bp->isratify != 0 && senderind >= 0 && senderind < bp->numnotaries && bits256_nonz(srcutxo) != 0 && bits256_nonz(destutxo) != 0 ) + { + memset(masks,0,sizeof(masks)); + memset(bestks,0xff,sizeof(bestks)); + memset(counts,0,sizeof(counts)); + for (i=0; i<2; i++) + bp->notaries[senderind].pendingcrcs[i] = pendingcrcs[i]; + bp->notaries[senderind].ratifysrcutxo = srcutxo; + bp->notaries[senderind].ratifysrcvout = srcvout; + bp->notaries[senderind].ratifydestutxo = destutxo; + bp->notaries[senderind].ratifydestvout = destvout; + bp->notaries[senderind].ratifybestmask = bestmask; + bp->notaries[senderind].ratifyrecvmask = recvmask; + if ( (bp->notaries[senderind].ratifybestk= bestk) >= 0 ) + { + for (i=0; i<2; i++) + { + if ( (bp->notaries[senderind].ratifysiglens[i]= siglens[i]) != 0 ) + { + memcpy(bp->notaries[senderind].ratifysigs[i],sigs[i],siglens[i]); + if ( bestk == bp->pendingratifybestk && bestmask == bp->pendingratifybestmask ) + { + if ( ((1LL << senderind) & bestmask) != 0 ) + bp->ratifysigmasks[i] |= (1LL << senderind); + } else bp->ratifysigmasks[i] &= ~(1LL << senderind); + } + } + } + //printf("RECV from %d best.(%d %llx) sigs.(%d %d) %llx %llx\n",senderind,bestk,(long long)bestmask,siglens[0],siglens[1],(long long)bp->ratifysigmasks[0],(long long)bp->ratifysigmasks[1]); + bp->ratifyrecvmask = 0; + bp->ratifybestmask = 0; + bp->ratifybestk = -1; + for (numdiff=i=0; inumnotaries; i++) + { + if ( bits256_nonz(bp->notaries[i].ratifysrcutxo) != 0 && bits256_nonz(bp->notaries[i].ratifydestutxo) != 0 ) + bp->ratifyrecvmask |= (1LL << i); + if ( bp->notaries[i].ratifybestk < 0 || bp->notaries[i].ratifybestmask == 0 ) + continue; + if ( bp->require0 != 0 && (bp->notaries[i].ratifybestmask & 1) == 0 ) + continue; + for (j=0; jnotaries[i].ratifybestk == bestks[j] && bp->notaries[i].ratifybestmask == masks[j] ) + { + counts[j]++; + break; + } + if ( j == numdiff && bp->notaries[i].ratifybestk >= 0 && bp->notaries[i].ratifybestmask != 0 ) + { + masks[numdiff] = bp->notaries[i].ratifybestmask; + bestks[numdiff] = bp->notaries[i].ratifybestk; + counts[numdiff]++; + //printf("j.%d numdiff.%d (%d %llx).%d\n",j,numdiff,bp->notaries[i].ratifybestk,(long long)bp->notaries[i].ratifybestmask,counts[numdiff]); + numdiff++; + } + } + besti = -1, best = 0; + for (i=0; i best ) + { + best = counts[i]; + besti = i; + } + } + if ( besti >= 0 && bestks[besti] >= 0 && masks[besti] != 0 && (bp->ratifyrecvmask & masks[besti]) == masks[besti] ) + bp->ratifybestmask = masks[besti], bp->ratifybestk = bestks[besti]; + //printf("numdiff.%d besti.%d numbest.%d (%d %llx) vs (%d %llx)\n",numdiff,besti,best,besti>=0?bestks[besti]:-1,(long long)(besti>=0?masks[besti]:0),bestk,(long long)bestmask); + if ( bp->ratifybestmask == 0 || (time(NULL) / DPOW_EPOCHDURATION) != bp->lastepoch ) + { + bp->ratifybestmask = dpow_ratifybest(bp->ratifyrecvmask,bp,&bp->ratifybestk); + if ( (time(NULL) / DPOW_EPOCHDURATION) != bp->lastepoch ) + { + bp->lastepoch = (uint32_t)(time(NULL) / DPOW_EPOCHDURATION); + printf("epoch %u\n",bp->lastepoch % bp->numnotaries); + sleep(2 + (rand() % 7)); + } + } + bp->notaries[bp->myind].ratifybestk = bp->ratifybestk; + bp->notaries[bp->myind].ratifybestmask = bp->ratifybestmask; + bp->notaries[bp->myind].ratifyrecvmask = bp->ratifyrecvmask; + if ( bp->ratifybestk >= 0 ) + { + for (matchesmask=i=0; inumnotaries; i++) + { + if ( bp->ratifybestk >= 0 && bp->notaries[i].ratifybestk == bp->ratifybestk && bp->notaries[i].ratifybestmask == bp->ratifybestmask ) + { + matches++; + if ( ((1LL << i) & bp->ratifybestmask) != 0 ) + { + matchesmask |= (1LL << i); + bestmatches++; + } + } + } + crcval = 0; + numcrcs = 0; + for (i=0; inumnotaries; i++) + { + if ( ((1LL << i) & matchesmask) != 0 ) + { + if ( bp->notaries[i].pendingcrcs[bp->state < 1000] == 0 ) + continue; + if ( numcrcs == 0 ) + numcrcs++, crcval = bp->notaries[i].pendingcrcs[bp->state < 1000]; + else if ( numcrcs > 0 && crcval == bp->notaries[i].pendingcrcs[bp->state < 1000] ) + numcrcs++; + } + } + //printf("crcval.%x numcrcs.%d bestmatches.%d matchesmask.%llx\n",crcval,numcrcs,bestmatches,(long long)matchesmask); + if ( bestmatches >= bp->minsigs )//&& numcrcs >= bp->minsigs ) + { + if ( bp->pendingratifybestk != bp->ratifybestk || bp->pendingratifybestmask != bp->ratifybestmask ) + { + printf("new PENDING RATIFY BESTK (%d %llx) crcval.%08x num.%d\n",bp->ratifybestk,(long long)bp->ratifybestmask,crcval,numcrcs); + bp->pendingratifybestk = bp->ratifybestk; + bp->pendingratifybestmask = bp->ratifybestmask; + memset(bp->notaries[bp->myind].ratifysigs,0,sizeof(bp->notaries[bp->myind].ratifysigs)); + memset(bp->notaries[bp->myind].ratifysiglens,0,sizeof(bp->notaries[bp->myind].ratifysiglens)); + memset(bp->ratifysigmasks,0,sizeof(bp->ratifysigmasks)); + dpow_signedtxgen(myinfo,dp,bp->destcoin,bp,bp->ratifybestk,bp->ratifybestmask,bp->myind,DPOW_SIGBTCCHANNEL,1,1); + for (i=0; inumnotaries; i++) + { + if ( i != bp->myind ) + { + memset(&bp->notaries[i].ratifysrcutxo,0,sizeof(bp->notaries[i].ratifysrcutxo)); + memset(&bp->notaries[i].ratifydestutxo,0,sizeof(bp->notaries[i].ratifydestutxo)); + bp->notaries[i].ratifybestmask = bp->notaries[i].ratifyrecvmask = 0; + } + else if ( bp->require0 == 0 ) + { + bitcoin_address(srcaddr,bp->srccoin->chain->pubtype,dp->minerkey33,33); + bitcoin_address(destaddr,bp->destcoin->chain->pubtype,dp->minerkey33,33); + if ( dpow_checkutxo(myinfo,dp,bp,bp->destcoin,&bp->notaries[i].dest.prev_hash,&bp->notaries[i].dest.prev_vout,destaddr) < 0 ) + { + printf("dont have %s %s utxo, please send funds\n",dp->dest,destaddr); + } + if ( dpow_checkutxo(myinfo,dp,bp,bp->srccoin,&bp->notaries[i].src.prev_hash,&bp->notaries[i].src.prev_vout,srcaddr) < 0 ) + { + printf("dont have %s %s utxo, please send funds\n",dp->symbol,srcaddr); + } + } + } + } + if ( bp->ratifysigmasks[1] == bp->pendingratifybestmask ) // have all sigs + { + if ( bp->state < 1000 ) + { + dpow_sigscheck(myinfo,dp,bp,bp->myind,1,bp->pendingratifybestk,bp->pendingratifybestmask,bp->ratified_pubkeys,bp->numratified); + } + if ( bp->ratifysigmasks[0] == bp->pendingratifybestmask ) // have all sigs + { + if ( bp->state != 0xffffffff ) + dpow_sigscheck(myinfo,dp,bp,bp->myind,0,bp->pendingratifybestk,bp->pendingratifybestmask,bp->ratified_pubkeys,bp->numratified); + } + else if ( ((1LL << bp->myind) & bp->ratifybestmask) != 0 && (rand() % 100) == 0 ) + { + dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bp->ratifybestk,bp->ratifybestmask,bp->myind,DPOW_SIGCHANNEL,0,1); + } + //else printf("ratify srcmask.%llx != bestmask.%llx\n",(long long)bp->ratifysigmasks[0],(long long)bp->bestmask); + } + else if ( ((1LL << bp->myind) & bp->ratifybestmask) != 0 && (rand() % 100) == 0 ) + { + dpow_signedtxgen(myinfo,dp,bp->destcoin,bp,bp->ratifybestk,bp->ratifybestmask,bp->myind,DPOW_SIGBTCCHANNEL,1,1); + } + //else printf("ratify destmask.%llx != bestmask.%llx\n",(long long)bp->ratifysigmasks[1],(long long)bp->bestmask); + } + } + if ( (rand() % 100) == 0 ) + printf("[%d] numips.%d %s RATIFY.%d matches.%d bestmatches.%d bestk.%d %llx recv.%llx %llx sigmasks.(%llx %llx) crcval.%x num.%d\n",bp->myind,dp->numipbits,dp->symbol,bp->minsigs,matches,bestmatches,bp->ratifybestk,(long long)bp->ratifybestmask,(long long)bp->ratifyrecvmask,(long long)matchesmask,(long long)bp->ratifysigmasks[1],(long long)bp->ratifysigmasks[0],crcval,numcrcs); + } +} + +void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint8_t senderind,int8_t bestk,uint64_t bestmask,uint64_t recvmask,bits256 srcutxo,uint16_t srcvout,bits256 destutxo,uint16_t destvout,uint8_t siglens[2],uint8_t sigs[2][DPOW_MAXSIGLEN],uint32_t paxwdcrc) +{ + bits256 srchash; int32_t i,flag,bestmatches = 0,matches = 0,paxmatches = 0,paxbestmatches = 0; + if ( bp->myind < 0 ) + return; + if ( bp->isratify == 0 && bp->state != 0xffffffff && senderind >= 0 && senderind < bp->numnotaries && bits256_nonz(srcutxo) != 0 && bits256_nonz(destutxo) != 0 ) + { + if ( bits256_nonz(srcutxo) != 0 ) + { + bp->notaries[senderind].src.prev_hash = srcutxo; + bp->notaries[senderind].src.prev_vout = srcvout; + } + if ( bits256_nonz(destutxo) != 0 ) + { + bp->notaries[senderind].dest.prev_hash = destutxo; + bp->notaries[senderind].dest.prev_vout = destvout; + } + if ( bestmask != 0 ) + bp->notaries[senderind].bestmask = bestmask; + if ( recvmask != 0 ) + bp->notaries[senderind].recvmask |= recvmask; + if ( (bp->notaries[senderind].paxwdcrc= paxwdcrc) != 0 ) + { + //fprintf(stderr,"{%d %x} ",senderind,paxwdcrc); + } + if ( (bp->notaries[senderind].bestk= bestk) >= 0 ) + { + if ( (bp->notaries[senderind].src.siglens[bestk]= siglens[0]) != 0 ) + { + memcpy(bp->notaries[senderind].src.sigs[bestk],sigs[0],siglens[0]); + if ( bestk == bp->bestk && bestmask == bp->bestmask ) + bp->srcsigsmasks[bestk] |= (1LL << senderind); + else bp->srcsigsmasks[bestk] &= ~(1LL << senderind); + } + if ( (bp->notaries[senderind].dest.siglens[bestk]= siglens[1]) != 0 ) + { + memcpy(bp->notaries[senderind].dest.sigs[bestk],sigs[1],siglens[1]); + if ( bestk == bp->bestk && bestmask == bp->bestmask ) + bp->destsigsmasks[bestk] |= (1LL << senderind); + else bp->destsigsmasks[bestk] &= ~(1LL << senderind); + } + } + bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc; + if ( bp->bestmask == 0 ) + { + bp->recvmask |= (1LL << senderind) | (1LL << bp->myind); + bp->bestmask = dpow_maskmin(bp->recvmask,bp,&bp->bestk); + } + dpow_bestconsensus(bp); + if ( bp->bestk >= 0 ) + bp->notaries[bp->myind].bestk = bp->bestk; + if ( bp->bestmask != 0 ) + bp->notaries[bp->myind].bestmask = bp->bestmask; + if ( bp->recvmask != 0 ) + bp->notaries[bp->myind].recvmask = bp->recvmask; + if ( bp->bestk >= 0 ) + { + flag = -1; + for (i=0; inumnotaries; i++) + { + if ( bp->paxwdcrc == bp->notaries[i].paxwdcrc ) + paxmatches++; + if ( bp->bestk >= 0 && bp->notaries[i].bestk == bp->bestk && bp->notaries[i].bestmask == bp->bestmask ) + { + matches++; + if ( ((1LL << i) & bp->bestmask) != 0 ) + { + if ( bp->paxwdcrc == bp->notaries[i].paxwdcrc ) + { + bestmatches++; + paxbestmatches++; + } //else printf("?%x ",bp->notaries[i].paxwdcrc); + } + } + else if ( i == senderind && ((1LL << bp->myind) & bp->bestmask) != 0 && ((1LL << i) & bp->bestmask) != 0 && ((1LL << bp->myind) & bp->notaries[i].recvmask) == 0 ) + flag = senderind; + if ( 0 && bp->myind <= 1 && bp->notaries[i].paxwdcrc != 0 ) + printf("%d.(%x %d %llx r%llx) ",i,bp->notaries[i].paxwdcrc,bp->notaries[i].bestk,(long long)bp->notaries[i].bestmask,(long long)bp->notaries[i].recvmask); + } + if ( flag >= 0 ) + { + //printf("flag.%d -> send\n",flag); + for (i=0; iminerkey33[i+1]; + dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,0,bp->height,(void *)"ping",0); + } + if ( 0 && bp->myind <= 1 ) + printf("recv.%llx best.(%d %llx) m.%d p.%d:%d b.%d\n",(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask,matches,paxmatches,paxbestmatches,bestmatches); + if ( bestmatches >= bp->minsigs && paxbestmatches >= bp->minsigs ) + { + if ( bp->pendingbestk != bp->bestk || bp->pendingbestmask != bp->bestmask ) + { + printf("new PENDING BESTK (%d %llx) state.%d\n",bp->bestk,(long long)bp->bestmask,bp->state); + bp->pendingbestk = bp->bestk; + bp->pendingbestmask = bp->bestmask; + dpow_signedtxgen(myinfo,dp,bp->destcoin,bp,bp->bestk,bp->bestmask,bp->myind,DPOW_SIGBTCCHANNEL,1,0); + printf("finished signing\n"); + } + if ( bp->destsigsmasks[bp->bestk] == bp->bestmask ) // have all sigs + { + if ( bp->state < 1000 ) + dpow_sigscheck(myinfo,dp,bp,bp->myind,1,bp->bestk,bp->bestmask,0,0); + if ( bp->srcsigsmasks[bp->bestk] == bp->bestmask ) // have all sigs + { + if ( bp->state != 0xffffffff ) + dpow_sigscheck(myinfo,dp,bp,bp->myind,0,bp->bestk,bp->bestmask,0,0); + } //else printf("srcmask.%llx != bestmask.%llx\n",(long long)bp->srcsigsmasks[bp->bestk],(long long)bp->bestmask); + } //else printf("destmask.%llx != bestmask.%llx\n",(long long)bp->destsigsmasks[bp->bestk],(long long)bp->bestmask); + } + } + else + { + for (i=0; inumnotaries; i++) + { + if ( bp->paxwdcrc == bp->notaries[i].paxwdcrc ) + paxmatches++; + else if ( 0 && bp->myind <= 1 ) + printf("%x.%d ",bp->notaries[i].paxwdcrc,i); + } + if ( 0 && bp->myind <= 1 ) + printf("mypaxcrc.%x\n",bp->paxwdcrc); + } + if ( (rand() % 130) == 0 ) + printf("%p ht.%d [%d] ips.%d %s NOTARIZE.%d matches.%d paxmatches.%d bestmatches.%d bestk.%d %llx recv.%llx sigmasks.(%llx %llx) senderind.%d state.%x (%x %x %x) pax.%x\n",bp,bp->height,bp->myind,dp->numipbits,dp->symbol,bp->minsigs,matches,paxmatches,bestmatches,bp->bestk,(long long)bp->bestmask,(long long)bp->recvmask,(long long)(bp->bestk>=0?bp->destsigsmasks[bp->bestk]:0),(long long)(bp->bestk>=0?bp->srcsigsmasks[bp->bestk]:0),senderind,bp->state,bp->hashmsg.uints[0],bp->desttxid.uints[0],bp->srctxid.uints[0],bp->paxwdcrc); + } +} + +void dpow_nanoutxoget(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,struct dpow_nanoutxo *np,int32_t isratify,int8_t senderind,uint32_t channel) +{ + if ( isratify != 0 ) + { + dpow_ratify_update(myinfo,dp,bp,senderind,(int8_t)np->bestk,np->bestmask,np->recvmask,np->srcutxo,np->srcvout,np->destutxo,np->destvout,np->siglens,np->sigs,np->pendingcrcs); + } + else + { + dpow_notarize_update(myinfo,dp,bp,senderind,(int8_t)np->bestk,np->bestmask,np->recvmask,np->srcutxo,np->srcvout,np->destutxo,np->destvout,np->siglens,np->sigs,np->paxwdcrc); + if ( 0 && bp->myind <= 2 ) + printf("lag.[%d] RECV.%d r%llx (%d %llx) %llx/%llx\n",(int32_t)(time(NULL)-channel),senderind,(long long)np->recvmask,(int8_t)np->bestk,(long long)np->bestmask,(long long)np->srcutxo.txid,(long long)np->destutxo.txid); + } + //dpow_bestmask_update(myinfo,dp,bp,nn_senderind,nn_bestk,nn_bestmask,nn_recvmask); +} + +void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgbits,uint8_t *data,int32_t datalen) +{ + struct dpow_nanomsghdr *np; int32_t i,size,extralen=0,sentbytes = 0; uint32_t crc32,paxwdcrc; uint8_t extras[10000]; + if ( bp->myind < 0 ) + return; + if ( time(NULL) < myinfo->nanoinit+5 ) + return; + crc32 = calc_crc32(0,data,datalen); + //dp->crcs[firstz] = crc32; + size = (int32_t)(sizeof(*np) + datalen); + np = calloc(1,size); // endian dependent! + if ( (np->numipbits= dp->numipbits) == 0 ) + { + dp->ipbits[0] = myinfo->myaddr.myipbits; + np->numipbits = dp->numipbits = 1; + } + np->senderind = bp->myind; + memcpy(np->ipbits,dp->ipbits,dp->numipbits * sizeof(*dp->ipbits)); + //for (i=0; inumipbits; i++) + // printf("%08x ",np->ipbits[i]); + //printf(" dpow_send.(%d) size.%d numipbits.%d myind.%d\n",datalen,size,np->numipbits,bp->myind); + if ( bp->isratify == 0 ) + { + extralen = dpow_paxpending(extras,&paxwdcrc); + bp->paxwdcrc = bp->notaries[bp->myind].paxwdcrc = np->notarize.paxwdcrc = paxwdcrc; + //dpow_bestconsensus(bp); + dpow_nanoutxoset(myinfo,dp,&np->notarize,bp,0); + } + else + { + bp->paxwdcrc = bp->notaries[bp->myind].paxwdcrc = np->notarize.paxwdcrc = 0; + dpow_nanoutxoset(myinfo,dp,&np->ratify,bp,1); + } + np->size = size; + np->datalen = datalen; + np->crc32 = crc32; + for (i=0; i<2; i++) + np->ratify.pendingcrcs[i] = bp->pendingcrcs[i]; + for (i=0; i<32; i++) + np->srchash.bytes[i] = dp->minerkey33[i+1]; + np->desthash = desthash; + np->channel = channel; + np->height = bp->height;//msgbits; + np->myipbits = myinfo->myaddr.myipbits; + strcpy(np->symbol,dp->symbol); + np->version0 = DPOW_VERSION & 0xff; + np->version1 = (DPOW_VERSION >> 8) & 0xff; + memcpy(np->packet,data,datalen); + sentbytes = -1; + // deadlocks! portable_mutex_lock(&myinfo->dpowmutex); + for (i=0; i<100; i++) + { + struct nn_pollfd pfd; + pfd.fd = myinfo->dpowsock; + pfd.events = NN_POLLOUT; + if ( nn_poll(&pfd,1,100) > 0 ) + { + sentbytes = signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dpowsock,np,size); + break; + } + usleep(1000); + } + //portable_mutex_unlock(&myinfo->dpowmutex); + free(np); + if ( 0 && bp->myind <= 2 ) + printf("%d NANOSEND.%d ht.%d channel.%08x (%d) pax.%08x datalen.%d (%d %llx) (%d %llx) recv.%llx\n",i,sentbytes,np->height,np->channel,size,np->notarize.paxwdcrc,datalen,(int8_t)np->notarize.bestk,(long long)np->notarize.bestmask,bp->notaries[bp->myind].bestk,(long long)bp->notaries[bp->myind].bestmask,(long long)bp->recvmask); +} + +void dpow_ipbitsadd(struct supernet_info *myinfo,struct dpow_info *dp,uint32_t *ipbits,int32_t numipbits,int32_t maxipbits,int32_t fromid,uint32_t senderipbits) +{ + int32_t i,j,matched,missing,n; char ipaddr[64]; + if ( numipbits >= maxipbits ) + { + static int32_t counter; + if ( counter++ < 100 ) + printf("dpow_ipbitsadd reject from.%d numipbits.%d\n",fromid,numipbits); + return; + } + n = dp->numipbits; + matched = missing = 0; + //for (i=0; iipbits[j] ) + { + matched++; + ipbits[i] = 0; + break; + } + if ( j == n ) + missing++; + } + if ( (numipbits == 1 || missing < matched || matched > 0) && missing > 0 ) + { + for (i=0; i 0 ) + printf("IGNORE from.%d RECV numips.%d numipbits.%d matched.%d missing.%d\n",fromid,numipbits,n,matched,missing); + expand_ipbits(ipaddr,senderipbits); + dpow_addnotary(myinfo,dp,ipaddr); + expand_ipbits(ipaddr,myinfo->myaddr.myipbits); + dpow_addnotary(myinfo,dp,ipaddr); + //printf("recv numips.(%d %d)\n",myinfo->numdpowipbits,dp->numipbits); +} + +int32_t dpow_nanomsg_update(struct supernet_info *myinfo) +{ + int32_t i,n,num,num2,flags=0,size,iter,lastval=0,broadcastflag,firstz = -1; char *retstr; uint32_t crc32,r,m; struct dpow_nanomsghdr *np=0; struct dpow_info *dp; struct dpow_block *bp; struct dex_nanomsghdr *dexp = 0; void *freeptr; + if ( time(NULL) < myinfo->nanoinit+5 || (myinfo->dpowsock < 0 && myinfo->dexsock < 0 && myinfo->repsock < 0) ) + return(-1); + if ( myinfo->IAMNOTARY != 0 && myinfo->numnotaries <= 0 ) + { + myinfo->numnotaries = komodo_notaries("KMD",myinfo->notaries,-1); + printf("INIT with %d notaries\n",myinfo->numnotaries); + } + portable_mutex_lock(&myinfo->dpowmutex); + num = num2 = n = 0; + for (iter=0; iter<100; iter++) + { + freeptr = 0; + if ( (flags & 1) == 0 && (size= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->dpowsock,&np)) > 0 ) + { + num++; + if ( size >= sizeof(*np) ) + { + //fprintf(stderr,"%d ",size); + if ( np->version0 == (DPOW_VERSION & 0xff) && np->version1 == ((DPOW_VERSION >> 8) & 0xff) ) + { + //printf("v.%02x %02x datalen.%d size.%d %d vs %d\n",np->version0,np->version1,np->datalen,size,np->datalen,(int32_t)(size - sizeof(*np))); + if ( np->datalen == (size - sizeof(*np)) ) + { + crc32 = calc_crc32(0,np->packet,np->datalen); + dp = 0; + for (i=0; inumdpows; i++) + { + if ( strcmp(np->symbol,myinfo->DPOWS[i].symbol) == 0 ) + { + dp = &myinfo->DPOWS[i]; + break; + } + } + if ( dp != 0 && crc32 == np->crc32 ) + { + if ( i == myinfo->numdpows ) + printf("received nnpacket for (%s)\n",np->symbol); + else + { + dpow_ipbitsadd(myinfo,dp,np->ipbits,np->numipbits,sizeof(np->ipbits)/sizeof(*np->ipbits),np->senderind,np->myipbits); + if ( (bp= dpow_heightfind(myinfo,dp,np->height)) != 0 && bp->state != 0xffffffff && bp->myind >= 0 ) + { + //char str[65]; printf("%s RECV ht.%d ch.%08x (%d) crc32.%08x:%08x datalen.%d:%d firstz.%d i.%d senderind.%d myind.%d\n",bits256_str(str,np->srchash),np->height,np->channel,size,np->crc32,crc32,np->datalen,(int32_t)(size - sizeof(*np)),firstz,i,np->senderind,bp->myind); + if ( np->senderind >= 0 && np->senderind < bp->numnotaries ) + { + if ( memcmp(bp->notaries[np->senderind].pubkey+1,np->srchash.bytes,32) == 0 && bits256_nonz(np->srchash) != 0 ) + { + if ( bp->isratify == 0 ) + dpow_nanoutxoget(myinfo,dp,bp,&np->notarize,0,np->senderind,np->channel); + else dpow_nanoutxoget(myinfo,dp,bp,&np->ratify,1,np->senderind,np->channel); + dpow_datahandler(myinfo,dp,bp,np->senderind,np->channel,np->height,np->packet,np->datalen); + } else printf("wrong senderind.%d\n",np->senderind); + } + } //else printf("height.%d bp.%p state.%x senderind.%d\n",np->height,bp,bp!=0?bp->state:0,np->senderind); + //dp->crcs[firstz] = crc32; + } + } //else printf("crc error from.%d %x vs %x or no dp.%p [%s]\n",np->senderind,crc32,np->crc32,dp,np->symbol); + } else printf("ignore.%d np->datalen.%d %d (size %d - %ld) [%s]\n",np->senderind,np->datalen,(int32_t)(size-sizeof(*np)),size,sizeof(*np),np->symbol); + } //else printf("wrong version from.%d %02x %02x size.%d [%s]\n",np->senderind,np->version0,np->version1,size,np->symbol); + } + } else flags |= 1; + if ( freeptr != 0 ) + nn_freemsg(freeptr), np = 0, freeptr = 0; + if ( myinfo->dexsock >= 0 ) // from servers + { + freeptr = 0; + if ( (flags & 2) == 0 && (size= signed_nn_recv(&freeptr,myinfo,myinfo->notaries,myinfo->numnotaries,myinfo->dexsock,&dexp)) > 0 ) + { + //fprintf(stderr,"%d ",size); + n++; + if ( dex_packetcheck(myinfo,dexp,size) == 0 ) + { + //printf("FROM BUS.%08x -> pub\n",dexp->crc32); + //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); + dex_packet(myinfo,dexp,size); + } + //printf("GOT DEX bus PACKET.%d\n",size); + } else flags |= 2; + if ( freeptr != 0 ) + nn_freemsg(freeptr), dexp = 0, freeptr = 0; + } + if ( myinfo->repsock >= 0 ) // from clients + { + dexp = 0; + if ( (flags & 4) == 0 && (size= nn_recv(myinfo->repsock,&dexp,NN_MSG,0)) > 0 ) + { + num2++; + //printf("REP got %d crc.%08x\n",size,calc_crc32(0,(void *)dexp,size)); + if ( (retstr= dex_response(&broadcastflag,myinfo,dexp)) != 0 ) + { + signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->repsock,retstr,(int32_t)strlen(retstr)+1); + //printf("send back[%ld]\n",strlen(retstr)+1); + free(retstr); + if ( broadcastflag != 0 ) + { + printf("BROADCAST dexp request.[%d]\n",size); + signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size); + //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); + } + } + else + { + if ( (m= myinfo->numdpowipbits) > 0 ) + { + r = myinfo->dpowipbits[rand() % m]; + signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->repsock,&r,sizeof(r)); + printf("REP.%08x <- rand ip m.%d %x\n",dexp->crc32,m,r); + } else printf("illegal state without dpowipbits?\n"); + if ( dex_packetcheck(myinfo,dexp,size) == 0 ) + { + //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->dexsock,dexp,size); + //signed_nn_send(myinfo,myinfo->ctx,myinfo->persistent_priv,myinfo->pubsock,dexp,size); + //printf("REP.%08x -> dexbus and pub, t.%d lag.%d\n",dexp->crc32,dexp->timestamp,(int32_t)(time(NULL)-dexp->timestamp)); + dex_packet(myinfo,dexp,size); + } //else printf("failed dexpacketcheck\n"); + } + //printf("GOT DEX rep PACKET.%d\n",size); + //if ( freeptr != 0 ) + // nn_freemsg(freeptr), dexp = 0, freeptr = 0; + //if ( num > 1000 ) + // break; + } else flags |= 4; + if ( dexp != 0 ) + nn_freemsg(dexp), dexp = 0; + } + if ( (num + n + num2) != lastval ) + { + //printf("lastval.%d: num.%d n.%d num2.%d rep packets\n",lastval,num,n,num2); + lastval = (num + n + num2); + } else break; + } + portable_mutex_unlock(&myinfo->dpowmutex); + return(num+n+num2); +} +#else + +void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr) { } + +void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgbits,uint8_t *data,int32_t datalen) +{ + return; +} + +int32_t dpow_nanomsg_update(struct supernet_info *myinfo) { return(0); } + +#endif + +int32_t dpow_opreturnscript(uint8_t *script,uint8_t *opret,int32_t opretlen) +{ + int32_t offset = 0; + script[offset++] = 0x6a; + if ( opretlen >= 0x4c ) + { + if ( opretlen > 0xff ) + { + script[offset++] = 0x4d; + script[offset++] = opretlen & 0xff; + script[offset++] = (opretlen >> 8) & 0xff; + } + else + { + script[offset++] = 0x4c; + script[offset++] = opretlen; + } + } else script[offset++] = opretlen; + memcpy(&script[offset],opret,opretlen); + return(opretlen + offset); +} + +int32_t dpow_rwopret(int32_t rwflag,uint8_t *opret,bits256 *hashmsg,int32_t *heightmsgp,char *src,uint8_t *extras,int32_t extralen,struct dpow_block *bp,int32_t src_or_dest) +{ + int32_t i,opretlen = 0; //bits256 beacon,beacons[DPOW_MAXRELAYS]; + opretlen += iguana_rwbignum(rwflag,&opret[opretlen],sizeof(*hashmsg),hashmsg->bytes); + opretlen += iguana_rwnum(rwflag,&opret[opretlen],sizeof(*heightmsgp),(uint32_t *)heightmsgp); + if ( src_or_dest == 0 ) + { + //char str[65]; printf("src_or_dest.%d opreturn add %s\n",src_or_dest,bits256_str(str,bp->desttxid)); + if ( bits256_nonz(bp->desttxid) == 0 ) + { + printf("no desttxid\n"); + return(-1); + } + opretlen += iguana_rwbignum(rwflag,&opret[opretlen],sizeof(bp->desttxid),bp->desttxid.bytes); + } + /*else if ( 0 ) + { + memset(beacons,0,sizeof(beacons)); + for (i=0; inumnotaries; i++) + { + if ( ((1LL << i) & bp->bestmask) != 0 ) + beacons[i] = bp->notaries[i].beacon; + } + vcalc_sha256(0,beacon.bytes,beacons[0].bytes,sizeof(*beacons) * bp->numnotaries); + opretlen += iguana_rwbignum(rwflag,&opret[opretlen],sizeof(beacon),beacon.bytes); + }*/ + if ( rwflag != 0 ) + { + if ( src != 0 ) + { + for (i=0; src[i]!=0; i++) + opret[opretlen++] = src[i]; + } + opret[opretlen++] = 0; + if ( extras != 0 && extralen > 0 ) + { + memcpy(&opret[opretlen],extras,extralen); + opretlen += extralen; + printf("added extra.%d opreturn for withdraws paxwdcrc.%08x\n",extralen,calc_crc32(0,extras,extralen)); + } + } + else + { + if ( src != 0 ) + { + for (i=0; opret[opretlen]!=0; i++) + src[i] = opret[opretlen++]; + src[i] = 0; + } + opretlen++; + } + return(opretlen); +} + +int32_t dpow_rwsigentry(int32_t rwflag,uint8_t *data,struct dpow_sigentry *dsig) +{ + int32_t i,len = 0; + if ( rwflag != 0 ) + { + data[len++] = dsig->senderind; + data[len++] = dsig->lastk; + len += iguana_rwnum(rwflag,&data[len],sizeof(dsig->mask),(uint8_t *)&dsig->mask); + data[len++] = dsig->siglen; + memcpy(&data[len],dsig->sig,dsig->siglen), len += dsig->siglen; + for (i=0; ibeacon); i++) + data[len++] = dsig->beacon.bytes[i]; + for (i=0; i<33; i++) + data[len++] = dsig->senderpub[i]; + } + else + { + memset(dsig,0,sizeof(*dsig)); + dsig->senderind = data[len++]; + if ( dsig->senderind < 0 || dsig->senderind >= DPOW_MAXRELAYS ) + return(-1); + dsig->lastk = data[len++]; + len += iguana_rwnum(rwflag,&data[len],sizeof(dsig->mask),(uint8_t *)&dsig->mask); + dsig->siglen = data[len++]; + memcpy(dsig->sig,&data[len],dsig->siglen), len += dsig->siglen; + for (i=0; ibeacon); i++) + dsig->beacon.bytes[i] = data[len++]; + for (i=0; i<33; i++) + dsig->senderpub[i] = data[len++]; + } + return(len); +} + +void dpow_sigsend(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,int32_t myind,int8_t bestk,uint64_t bestmask,bits256 srchash,uint32_t sigchannel) +{ + struct dpow_sigentry dsig; int32_t i,len; uint8_t data[4096]; struct dpow_entry *ep; + if ( bp->myind < 0 ) + return; + if ( ((1LL << myind) & bestmask) == 0 ) + return; + ep = &bp->notaries[myind]; + if ( bestk >= 0 ) + { + if ( sigchannel == DPOW_SIGCHANNEL ) + bp->srcsigsmasks[bestk] |= (1LL << myind); + else bp->destsigsmasks[bestk] |= (1LL << myind); + } + //printf("ht.%d sigsend.%s: myind.%d bestk.%d %llx >>>>>> best.(%d %llx) recv.%llx sigs.%llx\n",bp->height,sigchannel == DPOW_SIGCHANNEL ? bp->srccoin->symbol : bp->destcoin->symbol,myind,bestk,(long long)bestmask,bestk,(long long)(bestk>=0?bestmask:0),(long long)bp->recvmask,(long long)(bestk>=0?bp->destsigsmasks[bestk]:0)); + memset(&dsig,0,sizeof(dsig)); + for (i=0; i<33; i++) + dsig.senderpub[i] = dp->minerkey33[i]; + dsig.lastk = bestk; + dsig.mask = bestmask; + dsig.senderind = myind; + dsig.beacon = bp->beacon; + if ( sigchannel == DPOW_SIGBTCCHANNEL ) + { + dsig.siglen = ep->dest.siglens[bestk]; + memcpy(dsig.sig,ep->dest.sigs[bestk],ep->dest.siglens[bestk]); + } + else + { + dsig.siglen = ep->src.siglens[bestk]; + memcpy(dsig.sig,ep->src.sigs[bestk],ep->src.siglens[bestk]); + } + memcpy(dsig.senderpub,dp->minerkey33,33); + len = dpow_rwsigentry(1,data,&dsig); + dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,sigchannel,bp->height,data,len); +} + +uint32_t komodo_assetmagic(char *symbol,uint64_t supply) +{ + uint8_t buf[512]; int32_t len = 0; + len = iguana_rwnum(1,&buf[len],sizeof(supply),(void *)&supply); + strcpy((char *)&buf[len],symbol); + len += strlen(symbol); + return(calc_crc32(0,buf,len)); +} + +/*int32_t komodo_shortflag(char *symbol) +{ + int32_t i,shortflag = 0; + if ( symbol[0] == '-' ) + { + shortflag = 1; + for (i=0; symbol[i+1]!=0; i++) + symbol[i] = symbol[i+1]; + symbol[i] = 0; + } + return(shortflag); +}*/ + +uint16_t komodo_assetport(uint32_t magic) +{ + return(8000 + (magic % 7777)); +} + +uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp) +{ + *magicp = komodo_assetmagic(symbol,supply); + return(komodo_assetport(*magicp)); +} + +#define MAX_CURRENCIES 32 +extern char CURRENCIES[][8]; + +void komodo_assetcoins(int32_t fullnode,uint64_t mask) +{ + uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *userhome,char *coindir,char *confname); + int32_t i,j; uint32_t magic; cJSON *json; uint16_t port; long filesize; char *userhome,confstr[16],jsonstr[512],magicstr[9],path[512]; struct iguana_info *coin; + if ( (userhome= OS_filestr(&filesize,"userhome.txt")) == 0 ) + userhome = "root"; + else + { + while ( userhome[strlen(userhome)-1] == '\r' || userhome[strlen(userhome)-1] == '\n' ) + userhome[strlen(userhome)-1] = 0; + } + for (i=0; iFULLNODE = fullnode; + coin->chain->rpcport = port + 1; + coin->chain->pubtype = 60; + coin->chain->p2shtype = 85; + coin->chain->wiftype = 188; + if ( fullnode < 0 ) + { + sprintf(confstr,"%s.conf",CURRENCIES[i]); + sprintf(path,"%s/.komodo/%s",userhome,CURRENCIES[i]); + extract_userpass(coin->chain->serverport,coin->chain->userpass,CURRENCIES[i],coin->chain->userhome,path,confstr); + } + } + printf("(%s %u) ",CURRENCIES[i],port); + } + printf("ports\n"); +} diff --git a/iguana/dpow/dpow_prices.c b/iguana/dpow/dpow_prices.c new file mode 100755 index 000000000..d83da8dd1 --- /dev/null +++ b/iguana/dpow/dpow_prices.c @@ -0,0 +1,1968 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "../exchanges777.h" + +#define USD 0 +#define EUR 1 +#define JPY 2 +#define GBP 3 +#define AUD 4 +#define CAD 5 +#define CHF 6 +#define NZD 7 +#define CNY 8 +#define RUB 9 + +#define NZDUSD 0 +#define NZDCHF 1 +#define NZDCAD 2 +#define NZDJPY 3 +#define GBPNZD 4 +#define EURNZD 5 +#define AUDNZD 6 +#define CADJPY 7 +#define CADCHF 8 +#define USDCAD 9 +#define EURCAD 10 +#define GBPCAD 11 +#define AUDCAD 12 +#define USDCHF 13 +#define CHFJPY 14 +#define EURCHF 15 +#define GBPCHF 16 +#define AUDCHF 17 +#define EURUSD 18 +#define EURAUD 19 +#define EURJPY 20 +#define EURGBP 21 +#define GBPUSD 22 +#define GBPJPY 23 +#define GBPAUD 24 +#define USDJPY 25 +#define AUDJPY 26 +#define AUDUSD 27 + +#define USDNUM 28 +#define EURNUM 29 +#define JPYNUM 30 +#define GBPNUM 31 +#define AUDNUM 32 +#define CADNUM 33 +#define CHFNUM 34 +#define NZDNUM 35 + +#define NUM_CONTRACTS 28 +#define NUM_CURRENCIES 8 +#define NUM_COMBINED (NUM_CONTRACTS + NUM_CURRENCIES) +#define MAX_SPLINES 64 +#define MAX_LOOKAHEAD 72 +#define MAX_CURRENCIES 32 + +#define SATOSHIDEN ((uint64_t)100000000L) +#define dstr(x) ((double)(x) / SATOSHIDEN) +#define SMALLVAL 0.000000000000001 +#define PRICE_RESOLUTION_ROOT ((int64_t)3163) +#define PRICE_RESOLUTION (PRICE_RESOLUTION_ROOT * PRICE_RESOLUTION_ROOT) // 10004569 +#define PRICE_RESOLUTION2 (PRICE_RESOLUTION * PRICE_RESOLUTION) // 100091400875761 +#define PRICE_RESOLUTION_MAXPVAL ((int64_t)3037000500u) // 303.5613528178975 vs 64 bits: 4294967295 429.30058206405493, +#define PRICE_RESOLUTION_MAXUNITS ((int16_t)((int64_t)0x7fffffffffffffffLLu / (SATOSHIDEN * PRICE_RESOLUTION))) // 9219 +#define SCALED_PRICE(val,scale) (((scale) * (val)) / PRICE_RESOLUTION) +#define Pval(r) ((double)(r)->Pval / PRICE_RESOLUTION) // for display only! +#define PERCENTAGE(perc) (((perc) * PRICE_RESOLUTION) / 100) + +#ifndef MAX +#define MAX(a,b) ((a) >= (b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +struct price_resolution { int64_t Pval; }; + +struct PAX_spline { char name[64]; int32_t splineid,lasti,basenum,num,firstx,dispincr,spline32[MAX_SPLINES][4]; uint32_t utc32[MAX_SPLINES]; int64_t spline64[MAX_SPLINES][4]; double dSplines[MAX_SPLINES][4],pricevals[MAX_SPLINES+MAX_LOOKAHEAD],lastutc,lastval,aveslopeabs; }; + +struct PAX_data +{ + uint32_t ttimestamps[128]; double tbids[128],tasks[128]; + uint32_t ftimestamps[128]; double fbids[128],fasks[128]; + uint32_t itimestamps[128]; double ibids[128],iasks[128]; + char edate[128]; double ecbmatrix[MAX_CURRENCIES][MAX_CURRENCIES],dailyprices[MAX_CURRENCIES * MAX_CURRENCIES],metals[4]; + uint32_t lastupdate; + int32_t ecbdatenum,ecbyear,ecbmonth,ecbday; double RTmatrix[MAX_CURRENCIES][MAX_CURRENCIES],RTprices[128],RTmetals[4]; + double basevals[MAX_CURRENCIES],cryptovols[2][9][2],BTCDBTC,BTCUSD,KMDBTC,CNYUSD,btcusd,kmdbtc,cryptos[8]; + struct PAX_spline splines[128]; +}; + +#define _extrapolate_Spline(Splines,gap) ((double)(Splines)[0] + ((gap) * ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3])))))) +#define _extrapolate_Slope(Splines,gap) ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3])))) + +#define PRICE_BLEND(oldval,newval,decay,oppodecay) ((oldval == 0.) ? newval : ((oldval * decay) + (oppodecay * newval))) +#define PRICE_BLEND64(oldval,newval,decay,oppodecay) ((oldval == 0) ? newval : ((oldval * decay) + (oppodecay * newval) + 0.499)) + +#define dto64(x) ((int64_t)((x) * (double)SATOSHIDEN * SATOSHIDEN)) +#define dto32(x) ((int32_t)((x) * (double)SATOSHIDEN)) +#define i64tod(x) ((double)(x) / ((double)SATOSHIDEN * SATOSHIDEN)) +#define i32tod(x) ((double)(x) / (double)SATOSHIDEN) +#define _extrapolate_spline64(spline64,gap) ((double)i64tod((spline64)[0]) + ((gap) * ((double)i64tod(.001*.001*(spline64)[1]) + ((gap) * ((double)i64tod(.001*.001*.001*.001*(spline64)[2]) + ((gap) * (double)i64tod(.001*.001*.001*.001*.001*.001*(spline64)[3]))))))) +#define _extrapolate_spline32(spline32,gap) ((double)i32tod((spline32)[0]) + ((gap) * ((double)i32tod(.001*.001*(spline32)[1]) + ((gap) * ((double)i32tod(.001*.001*.001*.001*(spline32)[2]) + ((gap) * (double)i32tod(.001*.001*.001*.001*.001*.001*(spline32)[3]))))))) + +int32_t sprimes[168] = +{ + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, + 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, + 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, + 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, + 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, + 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, + 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, + 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, + 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, + 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, + 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997 +}; + +int32_t Peggy_inds[539] = {289, 404, 50, 490, 59, 208, 87, 508, 366, 288, 13, 38, 159, 440, 120, 480, 361, 104, 534, 195, 300, 362, 489, 108, 143, 220, 131, 244, 133, 473, 315, 439, 210, 456, 219, 352, 153, 444, 397, 491, 286, 479, 519, 384, 126, 369, 155, 427, 373, 360, 135, 297, 256, 506, 322, 425, 501, 251, 75, 18, 420, 537, 443, 438, 407, 145, 173, 78, 340, 240, 422, 160, 329, 32, 127, 128, 415, 495, 372, 522, 60, 238, 129, 364, 471, 140, 171, 215, 378, 292, 432, 526, 252, 389, 459, 350, 233, 408, 433, 51, 423, 19, 62, 115, 211, 22, 247, 197, 530, 7, 492, 5, 53, 318, 313, 283, 169, 464, 224, 282, 514, 385, 228, 175, 494, 237, 446, 105, 150, 338, 346, 510, 6, 348, 89, 63, 536, 442, 414, 209, 216, 227, 380, 72, 319, 259, 305, 334, 236, 103, 400, 176, 267, 355, 429, 134, 257, 527, 111, 287, 386, 15, 392, 535, 405, 23, 447, 399, 291, 112, 74, 36, 435, 434, 330, 520, 335, 201, 478, 17, 162, 483, 33, 130, 436, 395, 93, 298, 498, 511, 66, 487, 218, 65, 309, 419, 48, 214, 377, 409, 462, 139, 349, 4, 513, 497, 394, 170, 307, 241, 185, 454, 29, 367, 465, 194, 398, 301, 229, 212, 477, 303, 39, 524, 451, 116, 532, 30, 344, 85, 186, 202, 517, 531, 515, 230, 331, 466, 147, 426, 234, 304, 64, 100, 416, 336, 199, 383, 200, 166, 258, 95, 188, 246, 136, 90, 68, 45, 312, 354, 184, 314, 518, 326, 401, 269, 217, 512, 81, 88, 272, 14, 413, 328, 393, 198, 226, 381, 161, 474, 353, 337, 294, 295, 302, 505, 137, 207, 249, 46, 98, 27, 458, 482, 262, 253, 71, 25, 0, 40, 525, 122, 341, 107, 80, 165, 243, 168, 250, 375, 151, 503, 124, 52, 343, 371, 206, 178, 528, 232, 424, 163, 273, 191, 149, 493, 177, 144, 193, 388, 1, 412, 265, 457, 255, 475, 223, 41, 430, 76, 102, 132, 96, 97, 316, 472, 213, 263, 3, 317, 324, 274, 396, 486, 254, 205, 285, 101, 21, 279, 58, 467, 271, 92, 538, 516, 235, 332, 117, 500, 529, 113, 445, 390, 358, 79, 34, 488, 245, 83, 509, 203, 476, 496, 347, 280, 12, 84, 485, 323, 452, 10, 146, 391, 293, 86, 94, 523, 299, 91, 164, 363, 402, 110, 321, 181, 138, 192, 469, 351, 276, 308, 277, 428, 182, 260, 55, 152, 157, 382, 121, 507, 225, 61, 431, 31, 106, 327, 154, 16, 49, 499, 73, 70, 449, 460, 187, 24, 248, 311, 275, 158, 387, 125, 67, 284, 35, 463, 190, 179, 266, 376, 221, 42, 26, 290, 357, 268, 43, 167, 99, 374, 242, 156, 239, 403, 339, 183, 320, 180, 306, 379, 441, 20, 481, 141, 77, 484, 69, 410, 502, 172, 417, 118, 461, 261, 47, 333, 450, 296, 453, 368, 359, 437, 421, 264, 504, 281, 270, 114, 278, 56, 406, 448, 411, 521, 418, 470, 123, 455, 148, 356, 468, 109, 204, 533, 365, 8, 345, 174, 370, 28, 57, 11, 2, 231, 310, 196, 119, 82, 325, 44, 342, 37, 189, 142, 222, 9, 54, }; + +uint64_t Currencymasks[NUM_CURRENCIES+1]; + +short Contract_base[NUM_COMBINED+1] = { 7, 7, 7, 7, 3, 1, 4, 5, 5, 0, 1, 3, 4, 0, 6, 1, 3, 4, 1, 1, 1, 1, 3, 3, 3, 0, 4, 4, 0,1,2,3,4,5,6,7, 8 };// Contract_base }; +short Contract_rel[NUM_COMBINED+1] = { 0, 6, 5, 2, 7, 7, 7, 2, 6, 5, 5, 5, 5, 6, 2, 6, 6, 6, 0, 4, 2, 3, 0, 2, 4, 2, 2, 0, 0,1,2,3,4,5,6,7,8 };// Contract_rel + +short Baserel_contractdir[NUM_CURRENCIES+1][NUM_CURRENCIES+1] = +{ + { 1, -1, 1, -1, -1, 1, 1, -1, -1 }, + { 1, 1, 1, 1, 1, 1, 1, 1, -1 }, + { -1, -1, 1, -1, -1, -1, -1, -1, 0 }, + { 1, -1, 1, 1, 1, 1, 1, 1, -1 }, + { 1, -1, 1, -1, 1, 1, 1, 1, -1 }, + { -1, -1, 1, -1, -1, 1, 1, -1, 0 }, + { -1, -1, 1, -1, -1, -1, 1, -1, -1 }, + { 1, -1, 1, -1, -1, 1, 1, 1, 0 }, + { -1, -1, 0, -1, -1, 0, -1, 0, 1 }, +}; + +short Currency_contracts[NUM_CURRENCIES+1][NUM_CURRENCIES] = +{ + { 0, 9, 13, 18, 22, 25, 27, 28, }, + { 5, 10, 15, 18, 19, 20, 21, 29, }, + { 3, 7, 14, 20, 23, 25, 26, 30, }, + { 4, 11, 16, 21, 22, 23, 24, 31, }, + { 6, 12, 17, 19, 24, 26, 27, 32, }, + { 2, 7, 8, 9, 10, 11, 12, 33, }, + { 1, 8, 13, 14, 15, 16, 17, 34, }, + { 0, 1, 2, 3, 4, 5, 6, 35, }, + { 36, 37, -1, 38, 39, -1, 40, 41, }, +}; + +short Currency_contractothers[NUM_CURRENCIES+1][NUM_CURRENCIES] = // buggy! +{ + { 7, 5, 6, 1, 3, 2, 4, 0, }, + { 7, 5, 6, 0, 4, 2, 3, 1, }, + { 7, 5, 6, 1, 3, 0, 4, 2, }, + { 7, 5, 6, 1, 0, 2, 4, 3, }, + { 7, 5, 6, 1, 3, 2, 0, 4, }, + { 7, 2, 6, 0, 1, 3, 4, 5, }, + { 7, 5, 0, 2, 1, 3, 4, 6, }, + { 0, 6, 5, 2, 1, 3, 4, 7, }, + { 0, 1,-1, 3, 4,-1, 5,-1, }, +}; + +short Baserel_contractnum[NUM_CURRENCIES+1][NUM_CURRENCIES+1] = +{ + { 28, 18, 25, 22, 27, 9, 13, 0, 36 }, + { 18, 29, 20, 21, 19, 10, 15, 5, 37 }, + { 25, 20, 30, 23, 26, 7, 14, 3, -1 }, + { 22, 21, 23, 31, 24, 11, 16, 4, 38 }, + { 27, 19, 26, 24, 32, 12, 17, 6, 39 }, + { 9, 10, 7, 11, 12, 33, 8, 2, -1 }, + { 13, 15, 14, 16, 17, 8, 34, 1, 40 }, + { 0, 5, 3, 4, 6, 2, 1, 35, -1 }, + { 36, 37, -1, 38, 39, -1, 40, -1, 74 }, +}; + +short Currency_contractdirs[NUM_CURRENCIES+1][NUM_CURRENCIES] = +{ + { -1, 1, 1, -1, -1, 1, -1, 1 }, + { 1, 1, 1, 1, 1, 1, 1, 1 }, + { -1, -1, -1, -1, -1, -1, -1, 1 }, + { 1, 1, 1, -1, 1, 1, 1, 1 }, + { 1, 1, 1, -1, -1, 1, 1, 1 }, + { -1, 1, 1, -1, -1, -1, -1, 1 }, + { -1, -1, -1, 1, -1, -1, -1, 1 }, + { 1, 1, 1, 1, -1, -1, -1, 1 }, + { 1, 1, 1, 1, 1, 1, 1, 1 }, +}; + +char *PAX_bases[64] = +{ + "KMD", "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies + "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", + "BTCUSD", "NXTBTC", "SuperNET", "ETHBTC", "ETCBTC", "XMRBTC", "KMDBTC", "XCPBTC", // BTC priced + "XAUUSD", "XAGUSD", "XPTUSD", "XPDUSD", "COPPER", "NGAS", "UKOIL", "USOIL", // USD priced + "BUND", "NAS100", "SPX500", "US30", "EUSTX50", "UK100", "JPN225", "GER30", "SUI30", "AUS200", "HKG33", "XAUUSD", "BTCRUB", "BTCCNY", "BTCUSD" // abstract +}; + +uint64_t M1SUPPLY[] = { 3317900000000, 6991604000000, 667780000000000, 1616854000000, 331000000000, 861909000000, 584629000000, 46530000000, // major currencies + 45434000000000, 16827000000000, 3473357229000, 306435000000, 27139000000000, 2150641000000, 347724099000, 1469583000000, 749543000000, 1826110000000, 2400434000000, 1123925000000, 3125276000000, 13975000000000, 317657000000, 759706000000000, 354902000000, 2797061000000, 162189000000, 163745000000, 1712000000000, 39093000000, 1135490000000000, 80317000000, + 100000000 }; + +#define MIND 1000 +uint32_t MINDENOMS[] = { MIND, MIND, 100*MIND, MIND, MIND, MIND, MIND, MIND, // major currencies + 10*MIND, 100*MIND, 10*MIND, MIND, 100*MIND, 10*MIND, MIND, 10*MIND, MIND, 10*MIND, 10*MIND, 10*MIND, 10*MIND, 100*MIND, MIND, 1000*MIND, MIND, 10*MIND, MIND, MIND, 10*MIND, MIND, 10000*MIND, 10*MIND, // end of currencies + 10*MIND, +}; + +uint64_t komodo_paxvol(uint64_t volume,uint64_t price) +{ + if ( volume < 10000000000 ) + return((volume * price) / 1000000000); + else if ( volume < (uint64_t)10 * 10000000000 ) + return((volume * (price / 10)) / 100000000); + else if ( volume < (uint64_t)100 * 10000000000 ) + return(((volume / 10) * (price / 10)) / 10000000); + else if ( volume < (uint64_t)1000 * 10000000000 ) + return(((volume / 10) * (price / 100)) / 1000000); + else if ( volume < (uint64_t)10000 * 10000000000 ) + return(((volume / 100) * (price / 100)) / 100000); + else if ( volume < (uint64_t)100000 * 10000000000 ) + return(((volume / 100) * (price / 1000)) / 10000); + else if ( volume < (uint64_t)1000000 * 10000000000 ) + return(((volume / 1000) * (price / 1000)) / 1000); + else if ( volume < (uint64_t)10000000 * 10000000000 ) + return(((volume / 1000) * (price / 10000)) / 100); + else return(((volume / 10000) * (price / 10000)) / 10); +} + +void pax_rank(uint64_t *ranked,uint32_t *pvals) +{ + int32_t i; uint64_t vals[32],sum = 0; + for (i=0; i<32; i++) + { + vals[i] = komodo_paxvol(M1SUPPLY[i] / MINDENOMS[i],pvals[i]); + sum += vals[i]; + } + for (i=0; i<32; i++) + { + ranked[i] = (vals[i] * 1000000000) / sum; + printf("%.6f ",(double)ranked[i]/1000000000.); + } +}; + +#define YAHOO_METALS "XAU", "XAG", "XPT", "XPD" +static char *Yahoo_metals[] = { YAHOO_METALS }; + +char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies + "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies + "XAU", "XAG", "XPT", "XPD", // metals, gold must be first + "BTCD", "BTC", "NXT", "ETC", "ETH", "KMD", "BTS", "MAID", "XCP", "XMR" // cryptos +}; + +char CONTRACTS[][16] = { "NZDUSD", "NZDCHF", "NZDCAD", "NZDJPY", "GBPNZD", "EURNZD", "AUDNZD", "CADJPY", "CADCHF", "USDCAD", "EURCAD", "GBPCAD", "AUDCAD", "USDCHF", "CHFJPY", "EURCHF", "GBPCHF", "AUDCHF", "EURUSD", "EURAUD", "EURJPY", "EURGBP", "GBPUSD", "GBPJPY", "GBPAUD", "USDJPY", "AUDJPY", "AUDUSD", "USDCNY", "USDHKD", "USDMXN", "USDZAR", "USDTRY", "EURTRY", "TRYJPY", "USDSGD", "EURNOK", "USDNOK","USDSEK","USDDKK","EURSEK","EURDKK","NOKJPY","SEKJPY","USDPLN","EURPLN","USDILS", // no more currencies + "XAUUSD", "XAGUSD", "XPTUSD", "XPDUSD", "COPPER", "NGAS", "UKOIL", "USOIL", // commodities + // cryptos + "NAS100", "SPX500", "US30", "BUND", "EUSTX50", "UK100", "JPN225", "GER30", "SUI30", "AUS200", "HKG33", "FRA40", "ESP35", "ITA40", "USDOLLAR", // indices + "SuperNET" // assets +}; + +int32_t isdecimalstr(char *str) +{ + int32_t i; + if ( str == 0 || str[0] == 0 ) + return(0); + for (i=0; str[i]!=0; i++) + if ( str[i] < '0' || str[i] > '9' ) + return(0); + return(i); +} + +int32_t PAX_ispair(char *base,char *rel,char *contract) +{ + int32_t i,j; + base[0] = rel[0] = 0; + for (i=0; i 0.655564 + USDCNY 6.204146 -> 0.652686 + USDHKD 7.753400 -> 0.749321 + USDHKD 7.746396 -> 0.746445 + USDZAR 12.694000 -> 1.101688 + USDZAR 12.682408 -> 1.098811 + USDTRY 2.779700 -> 0.341327 + EURTRY 3.048500 -> 0.386351 + TRYJPY 44.724000 -> 0.690171 + TRYJPY 44.679966 -> 0.687290 + USDSGD 1.375200 -> 0.239415*/ + //if ( strcmp(contract,"USDCNY") == 0 || strcmp(contract,"TRYJPY") == 0 || strcmp(contract,"USDZAR") == 0 ) + // printf("i.%d j.%d base.%s rel.%s\n",i,j,base,rel); + return((i<<8) | j); + } + break; + } + } + return(-1); +} + +int32_t PAX_basenum(char *_base) +{ + int32_t i,j; char base[64]; + strcpy(base,_base); + touppercase(base); + if ( 1 ) + { + for (i=0; i=3; numprimes--) + { + for (p=1; p SMALLVAL ) + printf("x.%d error %.20f != %.20f [%.20f]\n",x,smoothbuf[5000 - x],smoothbuf[5000 + x],smoothbuf[5000 - x] - smoothbuf[5000 + x]); + _coeffs[x-1] = (smoothbuf[5000 - x] + smoothbuf[5000 + x]) / 2.; + } + sum = 0.; + for (x=0; x= 64 ) + return(10000); + else if ( PAX_bases[i] != 0 ) + { + if ( isdecimalstr(PAX_bases[i]+strlen(PAX_bases[i])-2) != 0 || strcmp(PAX_bases[i],"BTCRUB") == 0 ) + minmils = 1; + else if ( strncmp(PAX_bases[i],"XAU",3) == 0 || strcmp(PAX_bases[i],"BTCCNY") == 0 || strcmp(PAX_bases[i],"BTCUSD") == 0 || strncmp(PAX_bases[i],"XPD",3) == 0 || strncmp(PAX_bases[i],"XPT",3) == 0 ) + minmils = 10; + else if ( strcmp(PAX_bases[i],"BUND") == 0 || strcmp(PAX_bases[i],"UKOIL") == 0 || strcmp(PAX_bases[i],"USOIL") == 0 ) + minmils = 100; + else if ( strncmp(PAX_bases[i],"ETC",3) == 0 || strcmp(PAX_bases[i],"SuperNET") == 0 || strncmp(PAX_bases[i],"XAG",3) == 0 || strncmp(PAX_bases[i],"ETH",3) == 0 || strncmp(PAX_bases[i],"XCP",3) == 0 ) + minmils = 1000; + else if ( strncmp(PAX_bases[i],"XMR",3) == 0 ) + minmils = 10000; + else if ( strncmp(PAX_bases[i],"NXT",3) == 0 || strncmp(PAX_bases[i],"BTS",3) == 0 ) + minmils = 1000000; + else if ( strncmp(PAX_bases[i],"KMD",5) == 0 ) + minmils = 1000; + else minmils = 10000; + } + return(minmils); +} + +int32_t peggy_prices(struct price_resolution prices[64],double btcusd,double kmdbtc,char *contracts[],int32_t num,double *cprices,double *basevals) +{ + double kmdusd,price_in_kmd,dprice,usdcny,usdrub,btccny,btcrub,xauusd,usdprice=0.,usdval,btcprice=0.; int32_t contractnum,base,nonz = 0; + if ( btcusd > SMALLVAL && (usdval= basevals[0]) > SMALLVAL ) + { + xauusd = usdcny = usdrub = btccny = btcrub = 0.; + for (contractnum=0; contractnum SMALLVAL ) + { + usdcny = (basevals[0] * peggy_mils(8)) / (basevals[8] * peggy_mils(0)); + btccny = 1000 * btcusd * usdcny; + } + if ( basevals[9] > SMALLVAL ) + { + usdrub = (basevals[0] * peggy_mils(9)) / (basevals[9] * peggy_mils(0)); + btcrub = 1000 * btcusd * usdrub; + } + if ( kmdbtc < SMALLVAL ) + kmdbtc = 0.0001; + kmdusd = (btcusd * kmdbtc); + printf("xauusd %f usdval %f %f %f usdcny %f usdrub %f btcusd %f kmdbtc %f kmdusd %f btccny %f btcrub %f\n",xauusd,usdval,basevals[8],basevals[9],usdcny,usdrub,btcusd,kmdbtc,kmdusd,btccny,btcrub); + prices[0].Pval = (PRICE_RESOLUTION * 100. * kmdbtc); + for (base=0,contractnum=1; base<32; base++,contractnum++) + { + if ( strcmp(contracts[contractnum],CURRENCIES[base]) == 0 ) + { + if ( (dprice= basevals[base]) > SMALLVAL ) + { + nonz++; + if ( base == 0 ) + usdprice = price_in_kmd = (1. / kmdusd); + else price_in_kmd = (dprice / (kmdusd * usdval)); + prices[contractnum].Pval = (PRICE_RESOLUTION * price_in_kmd); + } + } else printf("unexpected list entry %s vs %s at %d\n",contracts[contractnum],CURRENCIES[base],contractnum); + } + if ( strcmp(contracts[contractnum],"BTCUSD") != 0 ) + printf("unexpected contract (%s) at %d\n",contracts[contractnum],contractnum); + btcprice = (1. / kmdbtc); + prices[contractnum++].Pval = (PRICE_RESOLUTION / kmdbtc) / 1000.; + printf("btcprice %f = 1/%f %llu\n",btcprice,1./kmdbtc,(long long)prices[contractnum-1].Pval); + for (; contractnum<64; contractnum++) + { + //dprice = 0; + if ( contractnum == 63 && strcmp(contracts[contractnum],"BTCUSD") == 0 ) + dprice = btcusd; + else if ( contractnum == 62 && strcmp(contracts[contractnum],"BTCCNY") == 0 ) + dprice = btccny; + else if ( contractnum == 61 && strcmp(contracts[contractnum],"BTCRUB") == 0 ) + dprice = btcrub; + else if ( contractnum == 60 && strcmp(contracts[contractnum],"XAUUSD") == 0 ) + dprice = xauusd; + else + { + dprice = cprices[contractnum]; + if ( dprice > SMALLVAL && strlen(contracts[contractnum]) > 3 ) + { + if ( strcmp(contracts[contractnum]+strlen(contracts[contractnum])-3,"USD") == 0 || strcmp(contracts[contractnum],"COPPER") == 0 || strcmp(contracts[contractnum],"NGAS") == 0 || strcmp(contracts[contractnum],"UKOIL") == 0 || strcmp(contracts[contractnum],"USOIL") == 0 ) + dprice *= usdprice; + else if ( strcmp(contracts[contractnum],"SuperNET") == 0 ) + { + printf("SuperNET %f -> %f\n",dprice,dprice*btcprice); + dprice *= btcprice; + } + else if ( strcmp(contracts[contractnum]+strlen(contracts[contractnum])-3,"BTC") == 0 ) + dprice *= btcprice; + } + } + prices[contractnum].Pval = (uint64_t)((PRICE_RESOLUTION * dprice) * ((double)peggy_mils(contractnum) / 10000.)); + //if ( Debuglevel > 2 ) + { + struct price_resolution tmp; + tmp = peggy_scaleprice(prices[contractnum],peggy_mils(contractnum)); + printf("%.8f btcprice %.6f %f -->>> %s %.6f -> %llu %.6f mils.%d\n",cprices[contractnum],btcprice,cprices[contractnum]*btcprice,contracts[contractnum],Pval(&tmp),(long long)prices[contractnum].Pval,Pval(&prices[contractnum]),peggy_mils(contractnum)); + } + } + } + return(nonz); +} + +void init_Currencymasks() +{ + int32_t base,j,c; uint64_t basemask; + for (base=0; base= 0 ) + { + basemask |= (1L << c); + //printf("(%s %lx) ",CONTRACTS[c],1L<num - 1); + if ( timestamp >= spline->utc32[ind] ) + { + gap = (timestamp - spline->utc32[ind]); + if ( gap < lookahead ) + return(_extrapolate_spline64(spline->spline64[ind],gap)); + else return(0.); + } + else if ( timestamp <= spline->utc32[0] ) + { + gap = (spline->utc32[0] - timestamp); + if ( gap < lookahead ) + return(_extrapolate_spline64(spline->spline64[0],gap)); + else return(0.); + } + for (i=0; inum-1; i++) + { + ind = (i + spline->lasti) % (spline->num - 1); + if ( timestamp >= spline->utc32[ind] && timestamp < spline->utc32[ind+1] ) + { + spline->lasti = ind; + return(_extrapolate_spline64(spline->spline64[ind],timestamp - spline->utc32[ind])); + } + } + return(0.); +} + +double PAX_calcspline(struct PAX_spline *spline,double *outputs,double *slopes,int32_t dispwidth,uint32_t *utc32,double *splinevals,int32_t num) +{ + static double errsums[3]; static int errcount; + double c[MAX_SPLINES],f[MAX_SPLINES],dd[MAX_SPLINES],dl[MAX_SPLINES],du[MAX_SPLINES],gaps[MAX_SPLINES]; + int32_t n,i,lasti,x,numsplines,nonz; double vx,vy,vw,vz,gap,sum,xval,yval,abssum,lastval,lastxval,yval64,yval32,yval3; uint32_t gap32; + sum = lastxval = n = lasti = nonz = 0; + for (i=0; i 0 ) + { + if ( (gaps[n-1]= utc32[i] - lastxval) < 0 ) + { + printf("illegal gap %f to t%d\n",lastxval,utc32[i]); + return(0); + } + } + spline->utc32[n] = lastxval = utc32[i]; + n++; + } + } + if ( (numsplines= n) < 4 ) + return(0); + for (i=0; i=0; i--) + c[i] -= c[i+1] * du[i]; + //tridiagonal(n-2, dl, dd, du, c); + + for (i=n-3; i>=0; i--) + c[i+1] = c[i]; + c[0] = (1.0 + (double)gaps[0] / gaps[1]) * c[1] - ((double)gaps[0] / gaps[1] * c[2]); + c[n-1] = (1.0 + (double)gaps[n-2] / gaps[n-3] ) * c[n-2] - ((double)gaps[n-2] / gaps[n-3] * c[n-3]); + //printf("c[n-1] %f, n-2 %f, n-3 %f\n",c[n-1],c[n-2],c[n-3]); + abssum = nonz = lastval = 0; + outputs[spline->firstx] = f[0]; + spline->num = numsplines; + for (i=0; iutc32[i],(vx),vy*1000*1000,vz*1000*1000*1000*1000,vw*1000*1000*1000*1000*1000*1000,gap,conv_unixtime(&tmp,spline->utc32[i])); + spline->dSplines[i][0] = vx, spline->dSplines[i][1] = vy, spline->dSplines[i][2] = vz, spline->dSplines[i][3] = vw; + spline->spline64[i][0] = dto64(vx), spline->spline64[i][1] = dto64(vy*1000*1000), spline->spline64[i][2] = dto64(vz*1000*1000*1000*1000), spline->spline64[i][3] = dto64(vw*1000*1000*1000*1000*1000*1000); + spline->spline32[i][0] = dto32(vx), spline->spline32[i][1] = dto32(vy*1000*1000), spline->spline32[i][2] = dto32(vz*1000*1000*1000*1000), spline->spline32[i][3] = dto32(vw*1000*1000*1000*1000*1000*1000); + gap32 = gap = spline->dispincr; + xval = spline->utc32[i] + gap; + lastval = vx; + while ( i < n-1 ) + { + x = spline->firstx + ((xval - spline->utc32[0]) / spline->dispincr); + if ( x > dispwidth-1 ) x = dispwidth-1; + if ( x < 0 ) x = 0; + if ( (i < n-2 && gap > gaps[i] + spline->dispincr) ) + break; + if ( i == n-2 && xval > spline->utc32[n-1] + MAX_LOOKAHEAD*spline->dispincr ) + { + //printf("x.%d dispwidth.%d xval %f > utc[n-1] %f + %f\n",x,dispwidth,xval,utc[n-1],MAX_LOOKAHEAD*incr); + break; + } + if ( x >= 0 ) + { + yval = _extrapolate_Spline(spline->dSplines[i],gap); + yval64 = _extrapolate_spline64(spline->spline64[i],gap32); + if ( (yval3 = PAX_splineval(spline,gap32 + spline->utc32[i],MAX_LOOKAHEAD*spline->dispincr)) != 0 ) + { + yval32 = _extrapolate_spline32(spline->spline32[i],gap32); + errsums[0] += fabs(yval - yval64), errsums[1] += fabs(yval - yval32), errsums[2] += fabs(yval - yval3), errcount++; + if ( fabs(yval - yval3) > SMALLVAL ) + printf("(%.10f vs %.10f %.10f %.10f [%.16f %.16f %.16f]) ",yval,yval64,yval32,yval3, errsums[0]/errcount,errsums[1]/errcount,errsums[2]/errcount); + } + if ( yval > 5000. ) yval = 5000.; + else if ( yval < -5000. ) yval = -5000.; + if ( isnan(yval) == 0 ) + { + outputs[x] = yval; + spline->lastval = outputs[x], spline->lastutc = xval; + if ( 1 && fabs(lastval) > SMALLVAL ) + { + if ( lastval != 0 && outputs[x] != 0 ) + { + if ( slopes != 0 ) + slopes[x] = (outputs[x] - lastval), abssum += fabs(slopes[x]); + nonz++; + } + } + } + //else outputs[x] = 0.; + //printf("x.%-4d %d %f %f %f i%-4d: gap %9.6f %9.6f last %9.6f slope %9.6f | %9.1f [%9.1f %9.6f %9.6f %9.6f %9.6f]\n",x,firstx,xval,utc[0],incr,i,gap,yval,lastval,slopes[x],xval,utc[i+1],dSplines[i][0],dSplines[i][1]*1000*1000,dSplines[i][2]*1000*1000*1000*1000,dSplines[i][3]*1000*1000*1000*1000*1000*1000); + } + gap32 += spline->dispincr, gap += spline->dispincr, xval += spline->dispincr; + } + //double pred = (i>0) ? _extrapolate_Spline(dSplines[i-1],gaps[i-1]) : 0.; + //printf("%2d: w%8.1f [gap %f -> %9.6f | %9.6f %9.6f %9.6f %9.6f %9.6f]\n",i,weekinds[i],gap,pred,f[i],dSplines[i].x,1000000*dSplines[i].y,1000000*1000000*dSplines[i].z,1000000*1000000*1000*dSplines[i].w); + } + if ( nonz != 0 ) + abssum /= nonz; + spline->aveslopeabs = abssum; + return(lastval); +} + +int32_t PAX_genspline(struct PAX_spline *spline,int32_t splineid,char *name,uint32_t *utc32,double *splinevals,int32_t maxsplines,double *refvals) +{ + int32_t i; double output[2048],slopes[2048],origvals[MAX_SPLINES]; + memset(spline,0,sizeof(*spline)), memset(output,0,sizeof(output)), memset(slopes,0,sizeof(slopes)); + spline->dispincr = 3600, spline->basenum = splineid, strcpy(spline->name,name); + memcpy(origvals,splinevals,sizeof(*splinevals) * MAX_SPLINES); + spline->lastval = PAX_calcspline(spline,output,slopes,sizeof(output)/sizeof(*output),utc32,splinevals,maxsplines); + for (i=0; inum; i++) + { + if ( i < spline->num ) + { + if ( 0 && refvals[i] != 0 && output[i * 24] != refvals[i] ) + printf("{%.8f != %.8f}.%d ",output[i * 24],refvals[i],i); + spline->pricevals[i] = output[i * 24]; + } + } + //printf("spline.%s num.%d\n",name,spline->num); + return(spline->num); +} + +int32_t PAX_calcmatrix(double matrix[MAX_CURRENCIES][MAX_CURRENCIES]) +{ + int32_t basenum,relnum,nonz,vnum,iter,numbase,numerrs = 0; double sum,vsum,price,price2,basevals[32],errsum=0; + memset(basevals,0,sizeof(basevals)); + for (iter=0; iter<2; iter++) + { + numbase = MAX_CURRENCIES; + for (basenum=0; basenum price ) + // printf("base.%d rel.%d price2 %f vs %f\n",basenum,relnum,1/price2,price); + } + } + if ( iter == 0 ) + sum += 1., vsum += 1.; + if ( nonz != 0 ) + sum /= nonz; + if ( vnum != 0 ) + vsum /= vnum; + if ( iter == 0 ) + basevals[basenum] = (sum + 1./vsum) / 2.; + else errsum += (sum + vsum)/2, numerrs++;//, printf("(%.8f %.8f) ",sum,vsum); + //printf("date.%d (%.8f/%d %.8f/%d).%02d -> %.8f\n",i,sum,nonz,vsum,vnum,basenum,basevals[basenum]); + } + if ( iter == 0 ) + { + for (sum=relnum=0; relnumecbmatrix,sizeof(dp->ecbmatrix)); + PAX_calcmatrix(Hmatrix); + /*for (i=0; i<32; i++) + { + for (j=0; j<32; j++) + printf("%.6f ",Hmatrix[i][j]); + printf("%s\n",CURRENCIES[i]); + }*/ + btcusd = dp->btcusd; + kmdbtc = dp->kmdbtc; + if ( btcusd > SMALLVAL ) + dxblend(&dp->BTCUSD,btcusd,.9); + if ( kmdbtc > SMALLVAL ) + dxblend(&dp->KMDBTC,kmdbtc,.9); + // char *cryptostrs[8] = { "btc", "nxt", "unity", "eth", "ltc", "xmr", "bts", "xcp" }; + // "BTCUSD", "NXTBTC", "SuperNET", "ETHBTC", "ETCBTC", "XMRBTC", "KMDBTC", "XCPBTC", // BTC priced + for (i=0; iBTCUSD; + continue; + } + else if ( i == num-2 && strcmp(contracts[i],"BTCCNY") == 0 ) + { + continue; + } + else if ( i == num-3 && strcmp(contracts[i],"BTCRUB") == 0 ) + { + continue; + } + else if ( i == num-4 && strcmp(contracts[i],"XAUUSD") == 0 ) + { + continue; + } + if ( strcmp(contracts[i],"NXTBTC") == 0 ) + RTprices[i] = dp->cryptos[1]; + else if ( strcmp(contracts[i],"SuperNET") == 0 ) + RTprices[i] = dp->cryptos[2]; + else if ( strcmp(contracts[i],"ETHBTC") == 0 ) + RTprices[i] = dp->cryptos[3]; + else if ( strcmp(contracts[i],"ETCBTC") == 0 ) + RTprices[i] = dp->cryptos[4]; + else if ( strcmp(contracts[i],"XMRBTC") == 0 ) + RTprices[i] = dp->cryptos[5]; + else if ( strcmp(contracts[i],"KMDBTC") == 0 ) + RTprices[i] = dp->cryptos[6]; + else if ( strcmp(contracts[i],"XCPBTC") == 0 ) + RTprices[i] = dp->cryptos[7]; + else if ( i < MAX_CURRENCIES ) + { + dp->RTmatrix[i][i] = basevals[i] = Hmatrix[i][i]; + //if ( Debuglevel > 2 ) + //printf("(%s %f).%d ",CURRENCIES[i],basevals[i],i); + } + else if ( (c= PAX_contractnum(contracts[i],0)) >= 0 ) + { + RTprices[i] = dp->RTprices[c]; + //if ( isdecimalstr(contracts[i]+strlen(contracts[i])-2) != 0 ) + // cprices[i] *= .0001; + } + else + { + for (j=0; jRTmetals[j]; + break; + } + } + } + if ( Debuglevel > 2 ) + printf("(%f %f) i.%d num.%d %s %f\n",dp->BTCUSD,dp->KMDBTC,i,num,contracts[i],RTprices[i]); + //printf("RT.(%s %f) ",contracts[i],RTprices[i]); + } + return(dp->ecbdatenum); +} + +int32_t PAX_emitprices(uint32_t pvals[32],struct PAX_data *dp) +{ + double matrix[MAX_CURRENCIES][MAX_CURRENCIES],RTmatrix[MAX_CURRENCIES][MAX_CURRENCIES],cprices[64],basevals[64]; struct price_resolution prices[256]; int32_t i,nonz = 0; + memset(cprices,0,sizeof(cprices)); + if ( PAX_getmatrix(basevals,dp,matrix,cprices+1,PAX_bases+1,sizeof(PAX_bases)/sizeof(*PAX_bases)-1) > 0 ) + { + cprices[0] = dp->KMDBTC; + /*for (i=0; i<32; i++) + dp->RTmatrix[i][i] = basevals[i]; + for (i=0; i<32; i++) + printf("%.6f ",basevals[i]); + printf("basevals\n"); + for (i=0; i<64; i++) + printf("%.6f ",cprices[i]); + printf("cprices\n");*/ + memset(prices,0,sizeof(prices)); + memset(matrix,0,sizeof(matrix)); + memset(RTmatrix,0,sizeof(RTmatrix)); + //peggy_prices(prices,dp->BTCUSD,dp->KMDBTC,PAX_bases,sizeof(PAX_bases)/sizeof(*PAX_bases),cprices,basevals); + for (i=0; i 0xffffffff ) + printf("Pval[%d] overflow error %lld\n",i,(long long)prices[i].Pval); + else pvals[i] = (uint32_t)prices[i].Pval; + } + if ( Debuglevel > 2 ) + printf("{%s %.6f %u}.%d ",PAX_bases[i],Pval(&prices[i]),(uint32_t)prices[i].Pval,peggy_mils(i)); + } + } else printf("pricematrix returned null\n"); + //printf("nonz.%d\n",nonz); + return(nonz); +} + +double PAX_baseprice(struct PAX_spline splines[],uint32_t timestamp,int32_t basenum) +{ + double btc,kmd,kmdusd,usdval; + btc = 1000. * _pairaved(PAX_splineval(&splines[MAX_CURRENCIES+0],timestamp,0),PAX_splineval(&splines[MAX_CURRENCIES+1],timestamp,0)); + kmd = .01 * PAX_splineval(&splines[MAX_CURRENCIES+2],timestamp,0); + if ( btc != 0. && kmd != 0. ) + { + kmdusd = (btc * kmd); + usdval = PAX_splineval(&splines[USD],timestamp,0); + if ( basenum == USD ) + return(1. / kmdusd); + else return(PAX_splineval(&splines[basenum],timestamp,0) / (kmdusd * usdval)); + } + return(0.); +} + +double PAX_getprice(char *retbuf,char *base,char *rel,char *contract,struct PAX_data *dp) +{ + int32_t i,c,basenum,relnum,n = 0; double yprice,daily,revdaily,price; + price = yprice = daily = revdaily = 0.; + PAX_ispair(base,rel,contract); + if ( base[0] != 0 && rel[0] != 0 ) + { + basenum = PAX_basenum(base), relnum = PAX_basenum(rel); + if ( basenum >= 0 && relnum >= 0 && basenum < MAX_CURRENCIES && relnum < MAX_CURRENCIES ) + daily = dp->dailyprices[basenum*MAX_CURRENCIES + relnum], revdaily = dp->dailyprices[relnum*MAX_CURRENCIES + basenum]; + } + for (i=0; imetals[i]; + break; + } + sprintf(retbuf,"{\"result\":\"success\",\"contract\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\"",contract,base,rel); + if ( (c= PAX_contractnum(contract,0)) >= 0 ) + { + if ( dp->tbids[c] != 0. && dp->tasks[c] != 0. ) + { + price += (dp->tbids[c] + dp->tasks[c]), n += 2; + sprintf(retbuf+strlen(retbuf),",\"truefx\":{\"timestamp\":\"%u\",\"bid\":%.8f,\"ask\":%.8f}",dp->ttimestamps[c],dp->tbids[c],dp->tasks[c]); + } + if ( dp->fbids[c] != 0. && dp->fasks[c] != 0. ) + { + price += (dp->fbids[c] + dp->fasks[c]), n += 2; + sprintf(retbuf+strlen(retbuf),",\"fxcm\":{\"bid\":%.8f,\"ask\":%.8f}",dp->fbids[c],dp->fasks[c]); + } + /*if ( dp->ibids[c] != 0. && dp->iasks[c] != 0. ) + { + price += (dp->ibids[c] + dp->iasks[c]), n += 2; + sprintf(retbuf+strlen(retbuf),",\"instaforex\":{\"timestamp\":%u,\"bid\":%.8f,\"ask\":%.8f}",dp->itimestamps[c],dp->ibids[c],dp->iasks[c]); + }*/ + if ( yprice != 0. ) + sprintf(retbuf+strlen(retbuf),",\"yahoo\":{\"price\":%.8f}",yprice); + if ( daily != 0. || revdaily != 0. ) + sprintf(retbuf+strlen(retbuf),",\"ecb\":{\"date\":\"%s\",\"daily\":%.8f,\"reverse\":%.8f}",dp->edate,daily,revdaily); + } + if ( n > 0 ) + price /= n; + sprintf(retbuf+strlen(retbuf),",\"aveprice\":%.8f,\"n\":%d}",price,n); + return(price); +} + +/*double PAX_aveprice(struct supernet_info *myinfo,char *base) +{ + struct peggy_info *PEGS; int32_t basenum; + if ( (PEGS= myinfo->PEGS) != 0 && (basenum= PAX_basenum(base)) >= 0 ) + { + return(PEGS->data.RTmatrix[basenum][basenum]); + } + return(0.); +}*/ +cJSON *url_json(char *url) +{ + char *jsonstr; cJSON *json = 0; + if ( (jsonstr= issue_curl(url)) != 0 ) + { + //printf("(%s) -> (%s)\n",url,jsonstr); + json = cJSON_Parse(jsonstr); + free(jsonstr); + } + return(json); +} + +cJSON *url_json2(char *url) +{ + char *jsonstr; cJSON *json = 0; + if ( (jsonstr= issue_curl(url)) != 0 ) + { + //printf("(%s) -> (%s)\n",url,jsonstr); + json = cJSON_Parse(jsonstr); + free(jsonstr); + } + return(json); +} + +double PAX_yahoo(char *metal) +{ + // http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json + // http://finance.yahoo.com/webservice/v1/symbols/EUR=USD/quote?format=json + // http://finance.yahoo.com/webservice/v1/symbols/XAU=X/quote?format=json + // http://finance.yahoo.com/webservice/v1/symbols/XAG=X/quote?format=json + // http://finance.yahoo.com/webservice/v1/symbols/XPT=X/quote?format=json + // http://finance.yahoo.com/webservice/v1/symbols/XPD=X/quote?format=json + char url[1024],*jsonstr; cJSON *json,*obj,*robj,*item,*field; double price = 0.; + sprintf(url,"http://finance.yahoo.com/webservice/v1/symbols/%s=X/quote?&format=json",metal); + if ( (jsonstr= issue_curl(url)) != 0 ) + { + //printf("(%s)\n",jsonstr); + if ( (json= cJSON_Parse(jsonstr)) != 0 ) + { + if ( (obj= jobj(json,"list")) != 0 && (robj= jobj(obj,"resources")) != 0 && (item= jitem(robj,0)) != 0 ) + { + if ( (robj= jobj(item,"resource")) != 0 && (field= jobj(robj,"fields")) != 0 && (price= jdouble(field,"price")) != 0 ) + price = 1. / price; + } + free_json(json); + } + free(jsonstr); + } + if ( Debuglevel > 2 ) + printf("(%s %f) ",metal,price); + dpow_price("yahoo",metal,price,price); + return(price); +} + +void PAX_btcprices(struct PAX_data *dp,int32_t enddatenum,int32_t numdates) +{ + int32_t i,n,year,month,day,seconds,datenum; char url[1024],url2[1024],date[64],*dstr,*str; + uint32_t timestamp,utc32[MAX_SPLINES]; struct tai t; + cJSON *coindesk,*quandl,*kmdhist,*bpi,*array,*item; + double kmddaily[MAX_SPLINES],cdaily[MAX_SPLINES],qdaily[MAX_SPLINES],ask,high,low,bid,close,vol,quotevol,open,price = 0.; + coindesk = url_json("http://api.coindesk.com/v1/bpi/historical/close.json"); + sprintf(url,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_KMD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); + sprintf(url2,"https://poloniex.com/public?command=returnChartData¤cyPair=BTC_BTCD&start=%ld&end=9999999999&period=86400",(long)(time(NULL)-numdates*3600*24)); + if ( (bpi= jobj(coindesk,"bpi")) != 0 ) + { + datenum = enddatenum; + memset(utc32,0,sizeof(utc32)); + memset(cdaily,0,sizeof(cdaily)); + if ( datenum == 0 ) + { + datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); + printf("got datenum.%d %d %d %d\n",datenum,seconds/3600,(seconds/60)%24,seconds%60); + } + for (i=0; isplines[MAX_CURRENCIES],MAX_CURRENCIES,"coindesk",utc32,cdaily,numdates,cdaily); + + } else printf("no bpi\n"); + quandl = url_json("https://www.quandl.com/api/v1/datasets/BAVERAGE/USD.json?rows=64"); + if ( 0 && (str= jstr(quandl,"updated_at")) != 0 && (datenum= conv_date(&seconds,str)) > 0 && (array= jarray(&n,quandl,"data")) != 0 ) + { + printf("datenum.%d data.%d %d\n",datenum,n,cJSON_GetArraySize(array)); + memset(utc32,0,sizeof(utc32)), memset(qdaily,0,sizeof(qdaily)); + for (i=0; i 2 ) + printf("(%s) ",cJSON_Print(item)); + if ( (dstr= jstr(jitem(item,0),0)) != 0 && (datenum= conv_date(&seconds,dstr)) > 0 ) + { + price = jdouble(jitem(item,1),0), ask = jdouble(jitem(item,2),0), bid = jdouble(jitem(item,3),0); + close = jdouble(jitem(item,4),0), vol = jdouble(jitem(item,5),0); + if ( Debuglevel > 2 ) + fprintf(stderr,"%d.[%d %f %f %f %f %f].%d ",i,datenum,price,ask,bid,close,vol,n); + utc32[numdates - 1 - i] = OS_conv_datenum(datenum,12,0,0), qdaily[numdates - 1 - i] = price * .001; + if ( i == n-1 ) + dpow_price("quandl","BTCUSD",bid,ask); + } + } + PAX_genspline(&dp->splines[MAX_CURRENCIES+1],MAX_CURRENCIES+1,"quandl",utc32,qdaily,n 2 ) + printf("[%u %d %f]",timestamp,OS_conv_unixtime(&t,&seconds,timestamp),price); + utc32[i] = timestamp - 12*3600, kmddaily[i] = price * 100.; + } + if ( Debuglevel > 2 ) + printf("poloniex.%d\n",n); + PAX_genspline(&dp->splines[MAX_CURRENCIES+2],MAX_CURRENCIES+2,"kmdhist",utc32,kmddaily,n 2 ) + printf("(%s)\n",jsonstr); + if ( (json= cJSON_Parse(jsonstr)) != 0 ) + { + if ( jobj(json,"error") != 0 || jobj(json,"date") == 0 ) + { + printf("Got error from fixer.io (%s)\n",jsonstr); + sleep(10); + } + else + { + copy_cJSON(&tmp,jobj(json,"date")), safecopy(date,tmp.buf,64); + if ( (basestr= jstr(json,"base")) != 0 && strcmp(basestr,CURRENCIES[basenum]) == 0 && (ratesobj= jobj(json,"rates")) != 0 && (item= ratesobj->child) != 0 ) + { + while ( item != 0 ) + { + if ( (relstr= get_cJSON_fieldname(item)) != 0 && (relnum= PAX_basenum(relstr)) >= 0 ) + { + i = basenum*MAX_CURRENCIES + relnum; + prices[i] = item->valuedouble; + //if ( basenum == JPYNUM ) + // prices[i] *= 100.; + // else if ( relnum == JPYNUM ) + // prices[i] /= 100.; + count++; + if ( Debuglevel > 2 ) + printf("(%02d:%02d %f) ",basenum,relnum,prices[i]); + sprintf(name,"%s%s",CURRENCIES[basenum],CURRENCIES[relnum]); + } else printf("cant find.(%s)\n",relstr);//, getchar(); + item = item->next; + } + } + } + free_json(json); + } + free(jsonstr); + } + return(count); +} + +int32_t PAX_ecbprices(char *date,double *prices,int32_t year,int32_t month,int32_t day) +{ + // http://api.fixer.io/latest?base=CNH + // http://api.fixer.io/2000-01-03?base=USD + // "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD" + char baseurl[512],tmpdate[64],url[512],checkdate[16]; int32_t basenum,count,i,iter,nonz; + checkdate[0] = 0; + if ( year == 0 ) + strcpy(baseurl,"http://api.fixer.io/latest?base="); + else + { + sprintf(checkdate,"%d-%02d-%02d",year,month,day); + sprintf(baseurl,"http://api.fixer.io/%s?base=",checkdate); + } + count = 0; + for (iter=0; iter<2; iter++) + { + for (basenum=0; basenum= MAX_CURRENCIES ) + break; + if ( iter == 0 ) + { + sprintf(url,"%s%s",baseurl,CURRENCIES[basenum]); + count += PAX_ecbparse(basenum == 0 ? date : tmpdate,prices,url,basenum); + usleep(100000); + if ( (basenum != 0 && strcmp(tmpdate,date) != 0) || (checkdate[0] != 0 && strcmp(checkdate,date) != 0) ) + { + //printf("date mismatch (%s) != (%s) or checkdate.(%s)\n",tmpdate,date,checkdate); + return(-1); + } + } + else + { + for (nonz=i=0; i= MAX_CURRENCIES ) + break; + if ( prices[MAX_CURRENCIES*basenum + i] != 0. ) + nonz++; + if ( Debuglevel > 2 ) + printf("%8.5f ",prices[MAX_CURRENCIES*basenum + i]); + } + if ( Debuglevel > 2 ) + printf("%s.%d %d\n",CURRENCIES[basenum],basenum,nonz); + } + } + } + return(count); +} + +int32_t ecb_matrix(double basevals[MAX_CURRENCIES],double matrix[MAX_CURRENCIES][MAX_CURRENCIES],char *date) +{ + FILE *fp=0; double price,bid,ask; int32_t n=0,datenum,relid,baseid,year=0,seconds,month=0,day=0,loaded = 0; char name[16],fname[64],_date[64]; + if ( date == 0 ) + date = _date, memset(_date,0,sizeof(_date)); + //printf("ecb_matrix(%s)\n",date); + sprintf(fname,"%s/ECB/%s",GLOBAL_DBDIR,date), OS_compatible_path(fname); + if ( date[0] != 0 && (fp= fopen(fname,"rb")) != 0 ) + { + if ( fread(matrix,1,sizeof(matrix[0][0])*MAX_CURRENCIES*MAX_CURRENCIES,fp) == sizeof(matrix[0][0])*MAX_CURRENCIES*MAX_CURRENCIES ) + loaded = 1; + else printf("fread error\n"); + fclose(fp); + } else printf("ecb_matrix.(%s) load error fp.%p\n",fname,fp); + datenum = conv_date(&seconds,date); + year = datenum / 10000, month = (datenum / 100) % 100, day = (datenum % 100); + if ( loaded == 0 ) + { + if ( (n= PAX_ecbprices(date,&matrix[0][0],year,month,day)) > 0 ) + { + sprintf(fname,"%s/ECB/%s",GLOBAL_DBDIR,date), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(matrix,1,sizeof(matrix[0][0])*MAX_CURRENCIES*MAX_CURRENCIES,fp) == sizeof(matrix[0][0])*MAX_CURRENCIES*MAX_CURRENCIES ) + loaded = 1; + fclose(fp); + } + } //else printf("peggy_matrix error loading %d.%d.%d\n",year,month,day); + } + else + { + PAX_calcmatrix(matrix); + for (baseid=0; baseid SMALLVAL ) + price = 1. / price; + if ( matrix[baseid][relid] > SMALLVAL && matrix[baseid][relid] < price ) + bid = matrix[baseid][relid], ask = price; + else bid = price, ask = matrix[baseid][relid]; + if ( bid > SMALLVAL && ask > SMALLVAL ) + { + dpow_price("ecb",name,bid,ask); + n++; + } + } + for (baseid=0; baseid 0 && (array= jarray(&n,quandl,"data")) != 0 ) + { + //printf("datenum.%d data.%d %d\n",datenum,n,cJSON_GetArraySize(array)); + for (i=0; i<1; i++) + { + // ["Date","24h Average","Ask","Bid","Last","Total Volume"] + // ["2015-07-25",289.27,288.84,288.68,288.87,44978.61] + item = jitem(array,i); + if ( (dstr= jstr(jitem(item,0),0)) != 0 && (datenum= conv_date(&seconds,dstr)) > 0 ) + { + btcusd = price = jdouble(jitem(item,1),0), ask = jdouble(jitem(item,2),0), bid = jdouble(jitem(item,3),0); + close = jdouble(jitem(item,4),0), vol = jdouble(jitem(item,5),0); + //fprintf(stderr,"%d.[%d %f %f %f %f %f].%d ",i,datenum,price,ask,bid,close,vol,n); + } + } + } + if ( 1 ) + { + double USD_average,avebid,aveask,bidvol,askvol,highbid,lowask,CMC_average,changes[3]; //struct exchange_quote sortbuf[512]; struct supernet_info *myinfo = SuperNET_MYINFO(0); cJSON *argjson = cJSON_Parse("{}"); + //aveask = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&askvol,"KMD","BTC",1,argjson); + //avebid = instantdex_aveprice(myinfo,sortbuf,(int32_t)(sizeof(sortbuf)/sizeof(*sortbuf)),&bidvol,"KMD","BTC",-1,argjson); + if ( 0 && avebid > SMALLVAL && aveask > SMALLVAL ) + { + price = (avebid*bidvol + aveask*askvol) / (bidvol + askvol); + *kmdbtcp = price; + printf("set KMD price %f\n",price); + dp->KMDBTC = price; + } + else if ( (dp->KMDBTC= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,"komodo","KMD","BTC",&USD_average)) > SMALLVAL ) + *kmdbtcp = dp->KMDBTC; + else + { + for (iter=1; iter<2; iter++) + { + kmdhist = url_json(iter == 0 ? url : url2); + //{"date":1406160000,"high":0.01,"low":0.00125,"open":0.01,"close":0.001375,"volume":1.50179994,"quoteVolume":903.58818412,"weightedAverage":0.00166204}, + if ( kmdhist != 0 && (array= jarray(&n,kmdhist,0)) != 0 ) + { + //printf("GOT.(%s)\n",cJSON_Print(array)); + for (i=0; i<1; i++) + { + item = jitem(array,i); + timestamp = juint(item,"date"), high = jdouble(item,"high"), low = jdouble(item,"low"), open = jdouble(item,"open"); + close = jdouble(item,"close"), vol = jdouble(item,"volume"), quotevol = jdouble(item,"quoteVolume"), price = jdouble(item,"weightedAverage"); + //printf("[%u %f %f %f %f %f %f %f]",timestamp,high,low,open,close,vol,quotevol,price); + //printf("[%u %d %f]",timestamp,OS_conv_unixtime(&seconds,timestamp),price); + if ( price != 0 ) + { + if ( iter == 0 ) + dp->KMDBTC = *kmdbtcp = kmddaily; + else dp->BTCDBTC = price; + } + } + //printf("poloniex.%d\n",n); + } + if ( kmdhist != 0 ) + free_json(kmdhist); + } + } + } + if ( (*kmdbtcp= dp->KMDBTC) == 0. ) + *kmdbtcp = dp->BTCDBTC / 50.22; + if ( (rand() % 100) == 0 ) + printf("KMD/BTC %.8f\n",*kmdbtcp); + if ( btctrades != 0 && (array= jarray(&n,btctrades,0)) != 0 ) + { + //printf("GOT.(%s)\n",cJSON_Print(array)); + for (i=0; i<1; i++) + { + item = jitem(array,i); + timestamp = juint(item,"date"); + //printf("[%u %f %f %f %f %f %f %f]",timestamp,high,low,open,close,vol,quotevol,price); + //printf("[%u %d %f]",timestamp,OS_conv_unixtime(&seconds,timestamp),price); + *btcusdp = jdouble(item,"rate"); + //printf("(%s) -> %f\n",jprint(item,0),btcusd); + } + free(btctrades); + //printf("poloniex.%d\n",n); + } + if ( 0 && bitcoinave != 0 ) + { + if ( (price= jdouble(bitcoinave,"24h_avg")) > SMALLVAL ) + { + //printf("bitcoinave %f %f\n",btcusd,price); + dpow_price("bitcoinave","BTCUSD",price,price); + dxblend(&btcusd,price,0.5); + } + free_json(bitcoinave); + } + if ( quandl != 0 ) + free_json(quandl); + if ( coindesk != 0 ) + free_json(coindesk); + if ( blockchaininfo != 0 ) + { + if ( (item= jobj(blockchaininfo,"USD")) != 0 && item != 0 && (price= jdouble(item,"15m")) > SMALLVAL ) + { + dpow_price("blockchain.info","BTCUSD",price,price); + printf("blockchaininfo %f %f\n",btcusd,price); + dxblend(&btcusd,price,0.5); + } + free_json(blockchaininfo); + } +} + +double blend_price(double *volp,double wtA,cJSON *jsonA,double wtB,cJSON *jsonB) +{ + //A.{"ticker":{"base":"BTS","target":"CNY","price":"0.02958291","volume":"3128008.39295500","change":"0.00019513","markets":[{"market":"BTC38","price":"0.02960000","volume":3051650.682955},{"market":"Bter","price":"0.02890000","volume":76357.71}]},"timestamp":1438490881,"success":true,"error":""} + // B.{"id":"bts\/cny","price":"0.02940000","price_before_24h":"0.02990000","volume_first":"3048457.6857147217","volume_second":"90629.45859575272","volume_btc":"52.74","best_market":"btc38","latest_trade":"2015-08-02 03:57:38","coin1":"BitShares","coin2":"CNY","markets":[{"market":"btc38","price":"0.02940000","volume":"3048457.6857147217","volume_btc":"52.738317962865"},{"market":"bter","price":"0.04350000","volume":"0","volume_btc":"0"}]} + double priceA,priceB,priceB24,price,volA,volB; cJSON *obj; + priceA = priceB = priceB24= price = volA = volB = 0.; + if ( jsonA != 0 && (obj= jobj(jsonA,"ticker")) != 0 ) + { + priceA = jdouble(obj,"price"); + volA = jdouble(obj,"volume"); + } + if ( jsonB != 0 ) + { + priceB = jdouble(jsonB,"price"); + priceB24 = jdouble(jsonB,"price_before_24h"); + volB = jdouble(jsonB,"volume_first"); + } + //printf("priceA %f volA %f, priceB %f %f volB %f\n",priceA,volA,priceB,priceB24,volB); + if ( priceB > SMALLVAL && priceB24 > SMALLVAL ) + priceB = (priceB * .1) + (priceB24 * .9); + else if ( priceB < SMALLVAL ) + priceB = priceB24; + if ( priceA*volA < SMALLVAL ) + price = priceB; + else if ( priceB*volB < SMALLVAL ) + price = priceA; + else price = (wtA * priceA) + (wtB * priceB); + *volp = (volA + volB); + return(price); +} + +void _crypto_update(double cryptovols[2][9][2],struct PAX_data *dp,int32_t selector) +{ + char *cryptonatorA = "https://www.cryptonator.com/api/full/%s-%s"; //unity-btc + char *cryptocoinchartsB = "http://api.cryptocoincharts.info/tradingPair/%s_%s"; //bts_btc + char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "kmd", "xmr", "bts", "xcp", "etc" }; + int32_t iter,i,j; double btcusd,kmdbtc,cnyusd,prices[9][2],volumes[9][2]; + char base[16],rel[16],url[512],name[16],*str; cJSON *jsonA,*jsonB; + cnyusd = dp->CNYUSD; + btcusd = dp->BTCUSD; + if ( (kmdbtc= dp->KMDBTC) == 0. ) + ;//kmdbtc = dp->BTCDBTC / 50.22; + printf("DEPRECATED: update with btcusd %f kmd %f cnyusd %f cnybtc %f\n",btcusd,kmdbtc,cnyusd,cnyusd/btcusd); + return; + if ( btcusd < SMALLVAL || kmdbtc < SMALLVAL ) + { + PAX_update(dp,&btcusd,&kmdbtc); + //printf("PAX_update with btcusd %f kmd %f\n",btcusd,kmdbtc); + } + memset(prices,0,sizeof(prices)); + memset(volumes,0,sizeof(volumes)); + for (j=0; j SMALLVAL ) + break; + i = 3; + } else*/ + i = j; + for (iter=0; iter<1; iter++) + { + if ( i == 0 && iter == 0 ) + strcpy(base,"kmd"), strcpy(rel,"btc"); + else strcpy(base,str), strcpy(rel,iter==0?"btc":"cny"); + sprintf(name,"%s%s",base,rel); + //if ( selector == 0 ) + { + sprintf(url,cryptonatorA,base,rel); + jsonA = url_json(url); + } + //else + { + sprintf(url,cryptocoinchartsB,base,rel); + jsonB = url_json(url); + } + prices[i][iter] = blend_price(&volumes[i][iter],0.4,jsonA,0.6,jsonB); + if ( iter == 1 ) + { + if ( btcusd > SMALLVAL ) + { + prices[i][iter] *= cnyusd / btcusd; + volumes[i][iter] *= cnyusd / btcusd; + } else prices[i][iter] = volumes[i][iter] = 0.; + } + cryptovols[0][i][iter] = _pairaved(cryptovols[0][i][iter],prices[i][iter]); + //cryptovols[1][i][iter] = _pairaved(cryptovols[1][i][iter],volumes[i][iter]); + dpow_price("cryptonator",name,prices[i][iter],prices[i][iter]); + if ( Debuglevel > 2 ) + printf("(%f %f).%d:%d ",cryptovols[0][i][iter],cryptovols[1][i][iter],i,iter); + //if ( cnyusd < SMALLVAL || btcusd < SMALLVAL ) + // break; + } + } +} + +void PAX_RTupdate(double cryptovols[2][9][2],double RTmetals[4],double *RTprices,struct PAX_data *dp) +{ + char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "etc", "kmd", "xmr", "bts", "xcp" }; + int32_t iter,i,c,baserel,basenum,relnum; double cnyusd,btcusd,kmdbtc,bid=0.,ask=0.,price,vol,prices[8][2],volumes[8][2]; + char base[16],rel[16]; + PAX_update(dp,&btcusd,&kmdbtc); + memset(prices,0,sizeof(prices)); + memset(volumes,0,sizeof(volumes)); + for (i=0; i SMALLVAL ) + dxblend(&kmdbtc,prices[0][0],.9); + dxblend(&dp->kmdbtc,kmdbtc,.995); + if ( dp->KMDBTC < SMALLVAL ) + dp->KMDBTC = dp->kmdbtc; + if ( (cnyusd= dp->CNYUSD) > SMALLVAL ) + { + if ( prices[0][1] > SMALLVAL ) + { + //printf("cnyusd %f, btccny %f -> btcusd %f %f\n",cnyusd,prices[0][1],prices[0][1]*cnyusd,btcusd); + btcusd = prices[0][1] * cnyusd; + if ( dp->btcusd < SMALLVAL ) + dp->btcusd = btcusd; + else dxblend(&dp->btcusd,btcusd,.995); + if ( dp->BTCUSD < SMALLVAL ) + dp->BTCUSD = dp->btcusd; + printf("cnyusd %f, btccny %f -> btcusd %f %f -> %f %f %f\n",cnyusd,prices[0][1],prices[0][1]*cnyusd,btcusd,dp->btcusd,dp->btcusd,dp->BTCUSD); + } + } + for (i=1; i SMALLVAL ) + { + price = ((prices[i][0] * volumes[i][0]) + (prices[i][1] * volumes[i][1])) / vol; + if ( Debuglevel > 2 ) + printf("%s %f v%f + %f v%f -> %f %f\n",cryptostrs[i],prices[i][0],volumes[i][0],prices[i][1],volumes[i][1],price,dp->cryptos[i]); + dxblend(&dp->cryptos[i],price,.995); + } + } + btcusd = dp->BTCUSD; + kmdbtc = dp->KMDBTC; + if ( Debuglevel > 2 ) + printf(" update with btcusd %f kmd %f\n",btcusd,kmdbtc); + if ( btcusd < SMALLVAL || kmdbtc < SMALLVAL ) + { + PAX_update(dp,&btcusd,&kmdbtc); + if ( Debuglevel > 2 ) + printf(" price777_update with btcusd %f kmd %f\n",btcusd,kmdbtc); + } else dp->BTCUSD = btcusd, dp->KMDBTC = kmdbtc; + for (c=0; ctbids[c], ask = dp->tasks[c]; break; + case 1: bid = dp->fbids[c], ask = dp->fasks[c]; break; + case 2: bid = dp->ibids[c], ask = dp->iasks[c]; break; + } + if ( (price= _pairaved(bid,ask)) > SMALLVAL ) + { + if ( Debuglevel > 2 ) + printf("%.6f ",price); + dxblend(&RTprices[c],price,.995); + if ( 0 && (baserel= PAX_ispair(base,rel,CONTRACTS[c])) >= 0 ) + { + basenum = (baserel >> 8) & 0xff, relnum = baserel & 0xff; + if ( basenum < 32 && relnum < 32 ) + { + //printf("%s.%d %f <- %f\n",CONTRACTS[c],c,RTmatrix[basenum][relnum],RTprices[c]); + //dxblend(&RTmatrix[basenum][relnum],RTprices[c],.999); + } + } + if ( strcmp(CONTRACTS[c],"XAUUSD") == 0 ) + dxblend(&RTmetals[0],price,.995); + } + } + } + for (i=0; imetals[i] != 0 ) + dxblend(&RTmetals[i],dp->metals[i],.995); +} + +void PAX_bidask(struct exchange_info *exchange,uint32_t *timestamps,double *bids,double *asks,int32_t baseid,int32_t relid) +{ + int32_t contractnum; struct exchange_quote bidasks[2]; + contractnum = Baserel_contractnum[baseid][relid]; + (*exchange->issue.price)(exchange,CURRENCIES[baseid],CURRENCIES[relid],bidasks,1,0.,0,0); + //bids[contractnum] = bidasks[0].price; + //asks[contractnum] = bidasks[1].price; + //timestamps[contractnum] = bidasks[0].timestamp; + //printf("%s%s.(%s %.6f) %s\n",CURRENCIES[baseid],CURRENCIES[relid],CONTRACTS[contractnum],_pairaved(bids[contractnum],asks[contractnum]),exchange->name); +} + +struct exchange_info *PAX_bidasks(char *exchangestr,uint32_t *timestamps,double *bids,double *asks) +{ + int32_t baseid,relid; struct exchange_info *exchange; + if ( (exchange= exchanges777_find(exchangestr)) != 0 ) + { + for (baseid=0; baseid<8; baseid++) + { + for (relid=0; relid<8; relid++) + { + if ( Currency_contractdirs[baseid][relid] > 0 ) + PAX_bidask(exchange,timestamps,bids,asks,baseid,relid); + } + } + } else printf("cant find (%s) exchange\n",exchangestr); + return(exchange); +} + +void dpow_price(char *exchange,char *name,double bid,double ask) +{ + // adjust MAX_CURRENCIES, btcusd, btccny + //printf("%-12s %16.8f %16.8f %s\n",name,bid,ask,exchange); +} + +uint32_t PAX_val32(double val) +{ + uint32_t val32 = 0; struct price_resolution price; + if ( (price.Pval= val*1000000000) != 0 ) + { + if ( price.Pval > 0xffffffff ) + printf("Pval overflow error %lld\n",(long long)price.Pval); + else val32 = (uint32_t)price.Pval; + } + return(val32); +} + +double PAX_val(uint32_t pval,int32_t baseid) +{ + if ( baseid >= 0 && baseid < MAX_CURRENCIES ) + return(((double)pval / 1000000000.) / MINDENOMS[baseid]); + return(0.); +} + +void PAX_genecbsplines(struct PAX_data *dp) +{ + static portable_mutex_t mutex; static int32_t initflag; + int32_t i,j,datenum,seconds,numsamples; double prices[128][MAX_SPLINES],splineval,diff; uint32_t pvals[MAX_CURRENCIES],utc32[MAX_SPLINES],timestamp; struct tai t; + if ( initflag == 0 ) + { + portable_mutex_init(&mutex); + initflag = 1; + } + portable_mutex_lock(&mutex); + for (i=numsamples=0; i<28; i++) + { + datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)-(28-i+1)*24*3600); + expand_datenum(dp->edate,datenum); + timestamp = OS_conv_datenum(datenum,12,0,0); + printf("i.%d datenum.%d %s t%u\n",i,datenum,dp->edate,timestamp); + if ( (datenum= ecb_matrix(dp->basevals,dp->ecbmatrix,dp->edate)) > 0 ) + { + utc32[numsamples] = timestamp; + for (j=0; jbasevals[j]); + prices[j][numsamples] = dp->basevals[j]; + } + numsamples++; + } + } + for (j=0; j<3; j++) + utc32[numsamples + j] = utc32[numsamples + j - 1] + (24 * 3600); + for (j=0; jsplines[j],j,CURRENCIES[j],utc32,prices[j],numsamples,prices[j]); + splineval = PAX_splineval(&dp->splines[j],utc32[numsamples-1]- 8*3600,1); + diff = (prices[j][numsamples-1] - splineval); + prices[j][numsamples] = prices[j][numsamples-1] + diff; + diff += prices[j][numsamples-1] - PAX_splineval(&dp->splines[j],utc32[numsamples-1] - 12*3600,1); + prices[j][numsamples+1] = prices[j][numsamples-1] + diff; + diff += prices[j][numsamples-1] - PAX_splineval(&dp->splines[j],utc32[numsamples-1] - 16*3600,1); + prices[j][numsamples+2] = prices[j][numsamples-1] + diff; + //printf("%s splineval %f vs %f %f %f\n",CURRENCIES[j],prices[j][numsamples-1],prices[j][numsamples],prices[j][numsamples+1],prices[j][numsamples+2]); + PAX_genspline(&dp->splines[j],j,CURRENCIES[j],utc32,prices[j],numsamples+3,prices[j]); + } + portable_mutex_unlock(&mutex); +} + +#define BTCFACTOR_TIMESTAMP 1503746319 +#define BTCFACTOR_HEIGHT 466266 + +int32_t PAX_idle(struct supernet_info *myinfo)//struct PAX_data *argdp,int32_t idlegap) +{ + static double lastupdate,lastdayupdate; static uint32_t didinit; static char *userhome; int32_t idlegap = 10; + FILE *fp; long filesize; char fname[512]; double splineval; uint32_t pvals[128],timestamp; int32_t i,datenum,seconds,c; struct tai t; struct PAX_data *dp; uint8_t data[512]; + if ( Currencymasks[0] == 0 ) + return(0); + if ( time(NULL) > didinit+12*3600 ) + { + if ( (userhome= OS_filestr(&filesize,"userhome.txt")) == 0 ) + userhome = "root"; + else + { + while ( (c= userhome[strlen(userhome)-1]) == '\r' || c == '\n' || c == ' ' || c == '\t' ) + { + userhome[strlen(userhome)-1] = 0; + } + } + if ( myinfo->PAXDATA == 0 ) + myinfo->PAXDATA = calloc(1,sizeof(*dp)); + dp = myinfo->PAXDATA; + PAX_genecbsplines(dp); + printf("generated splines\n"); + didinit = (uint32_t)time(NULL); + datenum = OS_conv_unixtime(&t,&seconds,didinit); + expand_datenum(dp->edate,datenum); + } + dp = myinfo->PAXDATA; + /*if ( 0 && time(NULL) > dp->lastupdate+10 ) + { + _crypto_update(dp->cryptovols,dp,1); + dp->lastupdate = (uint32_t)time(NULL); + }*/ + if ( OS_milliseconds() > lastupdate + (1000*idlegap) ) + { + lastupdate = OS_milliseconds(); + if ( OS_milliseconds() > lastdayupdate + 60000*60 ) + { + lastdayupdate = OS_milliseconds(); + datenum = OS_conv_unixtime(&t,&seconds,(uint32_t)time(NULL)); + expand_datenum(dp->edate,datenum); + if ( (datenum= ecb_matrix(dp->basevals,dp->ecbmatrix,dp->edate)) > 0 && datenum != dp->ecbdatenum ) + { + dp->ecbdatenum = datenum; + dp->ecbyear = dp->ecbdatenum / 10000, dp->ecbmonth = (dp->ecbdatenum / 100) % 100, dp->ecbday = (dp->ecbdatenum % 100); + expand_datenum(dp->edate,datenum); + memcpy(dp->RTmatrix,dp->ecbmatrix,sizeof(dp->RTmatrix)); + PAX_genecbsplines(dp); + } + } + if ( 0 ) + { + for (i=0; imetals[i] = PAX_yahoo(Yahoo_metals[i]); + PAX_bidasks("truefx",dp->ttimestamps,dp->tbids,dp->tasks); + PAX_bidasks("fxcm",dp->ftimestamps,dp->fbids,dp->fasks); + /*if ( (exchange= PAX_bidasks("instaforex",dp->itimestamps,dp->ibids,dp->iasks)) != 0 ) + { + if ( (contractnum= PAX_contractnum("XAU","USD")) >= 0 ) + { + (*exchange->issue.price)(exchange,"XAU","USD",bidasks,1,0.,0,0); + dp->ibids[contractnum] = bidasks[0].price; + dp->iasks[contractnum] = bidasks[1].price; + dp->itimestamps[contractnum] = bidasks[0].timestamp; + } + }*/ + //printf("BTCUSD %f %f %f\n",btcusd,dp->btcusd,dp->BTCUSD); + if ( dp->ecbmatrix[USD][USD] > SMALLVAL && dp->ecbmatrix[CNY][CNY] > SMALLVAL ) + dp->CNYUSD = (dp->ecbmatrix[CNY][CNY] / dp->ecbmatrix[USD][USD]); + PAX_RTupdate(dp->cryptovols,dp->RTmetals,dp->RTprices,dp); + PAX_emitprices(pvals,dp); + } + timestamp = (uint32_t)time(NULL); + int32_t dispflag = ((rand() % 6) == 0); + //printf("PAX_IDLE.%d %.8f %.8f\n",dispflag,dp->kmdbtc,dp->btcusd); + if ( dp->kmdbtc == 0 || dp->btcusd == 0 || dispflag != 0 ) + { + PAX_update(dp,&dp->btcusd,&dp->kmdbtc); + for (i=0; isplines[i],timestamp,0); + pvals[6+i] = PAX_val32(splineval); + if ( dispflag != 0 ) + printf("%u ",pvals[6+i]); + } + if ( pvals[6+CNY] != 0 && pvals[6+USD] != 0 ) + dp->CNYUSD = ((double)pvals[6 + CNY] / pvals[6 + USD]) * MINDENOMS[USD] / MINDENOMS[CNY]; + pvals[1] = timestamp; + pvals[2] = MAX_CURRENCIES + 3; + pvals[3] = PAX_val32(dp->kmdbtc * 1000); + double btcfactor; + //if ( time(NULL) > BTCFACTOR_TIMESTAMP ) + btcfactor = .00001; + //else btcfactor = .001; + pvals[4] = PAX_val32(dp->btcusd * btcfactor); + pvals[5] = PAX_val32(dp->CNYUSD); + sprintf(fname,"/%s/.komodo/komodofeed",userhome); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + for (i=1; ikmdbtc,dp->btcusd,dp->CNYUSD,1./dp->CNYUSD,pvals[4]); + } + } + } + return(0); +} + +void PAX_init() +{ + static int32_t didinit; //double commission = 0.; + if ( didinit == 0 ) + { + init_Currencymasks(); + //calc_smooth_code(127,7); + //tradebot_monitorall(0,0,0,0,"fxcm",commission); + //tradebot_monitorall(0,0,0,0,"truefx",commission); + //tradebot_monitorall(0,0,0,0,"instaforex",commission); + exchange_create("PAX",0); + didinit = 1; + } +} diff --git a/iguana/dpow/dpow_rpc.c b/iguana/dpow/dpow_rpc.c new file mode 100755 index 000000000..5f695f84a --- /dev/null +++ b/iguana/dpow/dpow_rpc.c @@ -0,0 +1,1285 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0,0) + +cJSON *dpow_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) +{ + char buf[128],*retstr=0; cJSON *json = 0; + if ( coin->FULLNODE < 0 ) + { + buf[0] = 0; + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",buf); + usleep(10000); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + retstr = bitcoinrpc_getinfo(myinfo,coin,0,0); + } + else + { + return(0); + } + if ( retstr != 0 ) + { + json = cJSON_Parse(retstr); + free(retstr); + if ( strcmp(coin->symbol,"BTC") == 0 ) + { + sprintf(buf,"[%d]",2); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"estimatefee",buf)) != 0 ) + { + if ( atof(retstr) > SMALLVAL ) + jaddnum(json,"estimatefee",atof(retstr)); + free(retstr); + } + } + } + return(json); +} +const char *Notaries_elected[][2] = +{ + { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + { "0_jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, + { "0_kolo_testA", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, + { "artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, + { "artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, + { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + { "artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, + { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, + { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, + { "crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, // 10 + { "crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, + { "crackers_SH", "02be28310e6312d1dd44651fd96f6a44ccc269a321f907502aae81d246fabdb03e" }, + { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, + { "etszombi_AR", "031c79168d15edabf17d9ec99531ea9baa20039d0cdc14d9525863b83341b210e9" }, + { "etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, + { "etszombi_SH", "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" }, + { "farl4web_EU", "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" }, + { "farl4web_SH", "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" }, + { "fullmoon_AR", "0254b1d64840ce9ff6bec9dd10e33beb92af5f7cee628f999cb6bc0fea833347cc" }, + { "fullmoon_NA", "031fb362323b06e165231c887836a8faadb96eda88a79ca434e28b3520b47d235b" }, // 20 + { "fullmoon_SH", "030e12b42ec33a80e12e570b6c8274ce664565b5c3da106859e96a7208b93afd0d" }, + { "grewal_NA", "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" }, + { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, + { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + { "jsgalt_NA", "027b3fb6fede798cd17c30dbfb7baf9332b3f8b1c7c513f443070874c410232446" }, + { "karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, // 30 + { "kashifali_EU", "033777c52a0190f261c6f66bd0e2bb299d30f012dcb8bfff384103211edb8bb207" }, + { "kolo_AR", "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" }, + { "kolo_SH", "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" }, + { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + { "movecrypto_AR", "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" }, + { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, + { "movecrypto_NA", "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" }, + { "movecrypto_SH", "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" }, + { "muros_AR", "022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" }, + { "noashh_AR", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, // 40 + { "noashh_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, + { "noashh_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, + { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, + { "polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + { "pondsea_AR", "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" }, + { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, + { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, + { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, + { "popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, + { "popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, // 50 + { "ptytrader_NA", "0328c61467148b207400b23875234f8a825cce65b9c4c9b664f47410b8b8e3c222" }, + { "ptytrader_SH", "0250c93c492d8d5a6b565b90c22bee07c2d8701d6118c6267e99a4efd3c7748fa4" }, + { "rnr_AR", "029bdb08f931c0e98c2c4ba4ef45c8e33a34168cb2e6bf953cef335c359d77bfcd" }, + { "rnr_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, + { "rnr_NA", "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" }, + { "rnr_SH", "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" }, + { "titomane_AR", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, + { "titomane_EU", "02e41feded94f0cc59f55f82f3c2c005d41da024e9a805b41105207ef89aa4bfbd" }, + { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, + { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 60 + { "xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, + { "xxspot1_XX", "02ef445a392fcaf3ad4176a5da7f43580e8056594e003eba6559a713711a27f955" }, + { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } +}; + +int32_t komodo_notaries(char *symbol,uint8_t pubkeys[64][33],int32_t height) +{ + int32_t i,num=-1; struct iguana_info *coin; char params[256],*retstr,*pubkeystr; cJSON *retjson,*item,*array; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( height < 0 ) + { + if ( (retjson= dpow_getinfo(SuperNET_MYINFO(0),coin)) != 0 ) + { + height = jint(retjson,"blocks") - 1; + free_json(retjson); +//printf("komodo_notaries height.%d\n",height); + } + } + if ( height >= 180000 ) + { + for (i=0; iFULLNODE < 0 ) + { + sprintf(params,"[\"%d\"]",height); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"notaries",params)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { +//printf("%s\n",retstr); + if ( (array= jarray(&num,retjson,"notaries")) != 0 ) + { + if ( num > 64 ) + { + printf("warning: numnotaries.%d? > 64?\n",num); + num = 64; + } + for (i=0; iFULLNODE < 0 ) + { + if ( coin->lastbesthashtime+2 > time(NULL) && bits256_nonz(coin->lastbesthash) != 0 ) + return(coin->lastbesthash); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getbestblockhash","")) != 0 ) + { + if ( 0 && strcmp(coin->symbol,"USD") == 0 ) + printf("%s getbestblockhash.(%s)\n",coin->symbol,retstr); + if ( is_hexstr(retstr,0) == sizeof(blockhash)*2 ) + decode_hex(blockhash.bytes,sizeof(blockhash),retstr); + free(retstr); + } + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + blockhash = coin->blocks.hwmchain.RO.hash2; + } + else + { + + } + if ( bits256_nonz(blockhash) != 0 ) + { + coin->lastbesthash = blockhash; + coin->lastbesthashtime = (uint32_t)time(NULL); + } + return(blockhash); +} + +int32_t dpow_paxpending(uint8_t *hex,uint32_t *paxwdcrcp) +{ + struct iguana_info *coin; char *retstr,*hexstr; cJSON *retjson; int32_t n=0; uint32_t paxwdcrc; + paxwdcrc = 0; + if ( (coin= iguana_coinfind("KMD")) != 0 ) + { + if ( coin->FULLNODE < 0 ) + { + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"paxpending","")) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (hexstr= jstr(retjson,"withdraws")) != 0 && (n= is_hexstr(hexstr,0)) > 1 ) + { + n >>= 1; + //printf("PAXPENDING.(%s)\n",hexstr); + decode_hex(hex,n,hexstr); + paxwdcrc = calc_crc32(0,hex,n) & 0xffffff00; + paxwdcrc |= (n & 0xff); + } + free_json(retjson); + } else printf("dpow_paxpending: parse error.(%s)\n",retstr); + free(retstr); + } else printf("dpow_paxpending: paxwithdraw null return\n"); + } else printf("dpow_paxpending: KMD FULLNODE.%d\n",coin->FULLNODE); + } else printf("dpow_paxpending: cant find KMD\n"); + if ( *paxwdcrcp != paxwdcrc ) + *paxwdcrcp = paxwdcrc; + return(n); +} + +bits256 dpow_getblockhash(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height) +{ + char buf[128],*retstr=0; bits256 blockhash; + memset(blockhash.bytes,0,sizeof(blockhash)); + if ( coin->FULLNODE < 0 ) + { + sprintf(buf,"%d",height); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getblockhash",buf); + //printf("%s ht.%d -> getblockhash.(%s)\n",coin->symbol,height,retstr); + usleep(10000); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + printf("test iguana mode getblockhash\n"); + retstr = bitcoinrpc_getblockhash(myinfo,coin,0,0,height); + } + else + { + return(blockhash); + } + if ( retstr != 0 ) + { + if ( strlen(retstr) == 64 ) + decode_hex(blockhash.bytes,32,retstr); + free(retstr); + } + return(blockhash); +} + +cJSON *dpow_getblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash) +{ + char buf[128],str[65],*retstr=0; cJSON *json = 0; + if ( coin->FULLNODE < 0 ) + { + sprintf(buf,"\"%s\"",bits256_str(str,blockhash)); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getblock",buf); + if ( 0 && strcmp(coin->symbol,"USD") == 0 ) + printf("%s getblock.(%s)\n",coin->symbol,retstr); + usleep(10000); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + retstr = bitcoinrpc_getblock(myinfo,coin,0,0,blockhash,1,0); + } + else + { + return(0); + } + if ( retstr != 0 ) + { + json = cJSON_Parse(retstr); + free(retstr); + } + return(json); +} + +char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address) +{ + char buf[128],*retstr=0; + if ( coin->FULLNODE < 0 ) + { + sprintf(buf,"\"%s\"",address); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"validateaddress",buf); + usleep(10000); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + retstr = bitcoinrpc_validateaddress(myinfo,coin,0,0,address); + } + else + { + return(0); + } + return(retstr); +} + +cJSON *dpow_gettxout(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout) +{ + char buf[128],str[65],*retstr=0; cJSON *json = 0; + sprintf(buf,"\"%s\", %d",bits256_str(str,txid),vout); + if ( coin->FULLNODE < 0 ) + { + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"gettxout",buf); + usleep(10000); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + printf("need to test following call\n"); + retstr = bitcoinrpc_gettxout(myinfo,coin,0,buf,txid,1,0); // untested + } + else + { + return(0); + } + if ( retstr != 0 ) + { + json = cJSON_Parse(retstr); + free(retstr); + } + //printf("dpow_gettxout.(%s)\n",retstr); + return(json); +} + +char *dpow_decoderawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx) +{ + char *retstr,*paramstr; cJSON *array; + if ( coin->FULLNODE < 0 ) + { + array = cJSON_CreateArray(); + jaddistr(array,rawtx); + paramstr = jprint(array,1); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"decoderawtransaction",paramstr); + //printf("%s decoderawtransaction.(%s) <- (%s)\n",coin->symbol,retstr,paramstr); + free(paramstr); + usleep(10000); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + retstr = bitcoinrpc_decoderawtransaction(myinfo,coin,0,0,rawtx,1); + } + else + { + return(0); + } + return(retstr); +} + +cJSON *dpow_gettransaction(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid) +{ + char buf[128],str[65],*retstr=0; cJSON *json = 0; + if ( coin->FULLNODE < 0 ) + { + sprintf(buf,"[\"%s\", 1]",bits256_str(str,txid)); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",buf)) != 0 ) + { + } + usleep(10000); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + retstr = bitcoinrpc_getrawtransaction(myinfo,coin,0,0,txid,1); + } + else + { + return(0); + } + if ( retstr != 0 ) + { + json = cJSON_Parse(retstr); + free(retstr); + } + return(json); +} + +cJSON *dpow_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) +{ + char buf[128],*retstr; cJSON *array,*json = 0; + if ( coin->FULLNODE < 0 ) + { + sprintf(buf,"1, 99999999, [\"%s\"]",coinaddr); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",buf)) != 0 ) + { + json = cJSON_Parse(retstr); + //printf("%s (%s) listunspent.(%s)\n",coin->symbol,buf,retstr); + free(retstr); + } else printf("%s null retstr from (%s)n",coin->symbol,buf); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + array = cJSON_CreateArray(); + jaddistr(array,coinaddr); + json = iguana_listunspents(myinfo,coin,array,1,coin->longestchain,""); + free_json(array); + } + else + { + return(0); + } + return(json); +} + +cJSON *dpow_listspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) +{ + if ( myinfo->DEXEXPLORER != 0 ) + return(kmd_listspent(myinfo,coin,coinaddr)); + else + { + return(0); + } +} + +cJSON *dpow_getbalance(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) +{ + if ( myinfo->DEXEXPLORER != 0 ) + return(kmd_getbalance(myinfo,coin,coinaddr)); + else + { + return(0); + } +} + +cJSON *dpow_gettxin(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout) +{ + if ( myinfo->DEXEXPLORER != 0 ) + return(kmd_gettxin(coin,txid,vout)); + else + { + return(0); + } +} + +cJSON *dpow_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,int32_t count,int32_t skip) +{ + char buf[128],*retstr; cJSON *json = 0; + if ( coin->FULLNODE < 0 ) + { + if ( count == 0 ) + count = 100; + sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip); + if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listtransactions",buf)) != 0 ) + { + //printf("LIST.(%s)\n",retstr); + json = cJSON_Parse(retstr); + free(retstr); + return(json); + } else printf("%s null retstr from (%s)n",coin->symbol,buf); + } + return(0); +} + +char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,cJSON *vins) +{ + cJSON *array,*privkeys,*item; char *wifstr,*str,*paramstr,*retstr; uint8_t script[256]; int32_t i,n,len,hashtype; struct vin_info V; struct iguana_waddress *waddr; struct iguana_waccount *wacct; + if ( coin->FULLNODE < 0 ) + { + array = cJSON_CreateArray(); + jaddistr(array,rawtx); + jaddi(array,jduplicate(vins)); + paramstr = jprint(array,1); + //printf("signrawtransaction\n"); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"signrawtransaction",paramstr); + //printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr); + free(paramstr); + usleep(10000); + return(retstr); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + privkeys = cJSON_CreateArray(); + if ( (n= cJSON_GetArraySize(vins)) > 0 ) + { + for (i=0; i 0 && strlen(str) < sizeof(script)*2 ) + { + len = (int32_t)strlen(str) >> 1; + decode_hex(script,len,str); + V.spendlen = len; + memcpy(V.spendscript,script,len); + if ( (hashtype= _iguana_calcrmd160(coin,&V)) >= 0 && V.coinaddr[0] != 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,V.coinaddr)) != 0 ) + { + if ( bits256_nonz(waddr->privkey) != 0 ) + { + if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) + { + wifstr = waddr->wifstr; + } + } + } + } + } + jaddistr(privkeys,wifstr); + } + } + retstr = bitcoinrpc_signrawtransaction(myinfo,coin,0,0,rawtx,vins,privkeys,"ALL"); + printf("call sign.(%s) vins.(%s) privs.(%s) -> (%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),retstr); + free_json(privkeys); + return(retstr); + } + else + { + return(0); + } +} + +cJSON *dpow_kvupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *key,char *value,int32_t flags) +{ + char params[IGUANA_MAXSCRIPTSIZE+256],*retstr; cJSON *retjson; + if ( coin->FULLNODE < 0 ) + { + sprintf(params,"[\"%s\", \"%s\", \"%d\"]",key,value,flags); + //printf("KVUPDATE.%s\n",params); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"kvupdate",params); + if ( (retjson= cJSON_Parse(retstr)) == 0 ) + { + free(retstr); + return(cJSON_Parse("{\"error\":\"couldnt parse kvupdate return\"}")); + } + free(retstr); + return(retjson); + } else return(cJSON_Parse("{\"error\":\"only native komodod supports KV\"}")); +} + +cJSON *dpow_kvsearch(struct supernet_info *myinfo,struct iguana_info *coin,char *key) +{ + char params[IGUANA_MAXSCRIPTSIZE+256],*retstr; cJSON *retjson; + if ( coin->FULLNODE < 0 ) + { + sprintf(params,"[\"%s\"]",key); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"kvsearch",params); + if ( (retjson= cJSON_Parse(retstr)) == 0 ) + { + free(retstr); + return(cJSON_Parse("{\"error\":\"couldnt parse kvupdate return\"}")); + } + free(retstr); + return(retjson); + } else return(cJSON_Parse("{\"error\":\"only native komodod supports KV\"}")); +} + + +char *dpow_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx) +{ + bits256 txid; cJSON *json,*array; char *paramstr,*retstr; + if ( coin->FULLNODE < 0 ) + { + array = cJSON_CreateArray(); + jaddistr(array,signedtx); + paramstr = jprint(array,1); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"sendrawtransaction",paramstr); + printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr); + free(paramstr); + return(retstr); + } + else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + txid = iguana_sendrawtransaction(myinfo,coin,signedtx); + json = cJSON_CreateObject(); + jaddbits256(json,"result",txid); + return(jprint(json,1)); + } + else + { + return(0); + } +} + +char *dpow_alladdresses(struct supernet_info *myinfo,struct iguana_info *coin) +{ + char *retstr,fname[1024]; long filesize; + sprintf(fname,"%s/alladdresses.%s",GLOBAL_CONFSDIR,coin->symbol), OS_compatible_path(fname); + retstr = OS_filestr(&filesize,fname); + return(retstr); +} + +void update_alladdresses(struct supernet_info *myinfo,struct iguana_info *coin,char *address) +{ + struct hashstr_item *hashstr,*tmp; cJSON *alljson; char *outstr,*instr,fname[1024]; int32_t i,n,saveflag = 0; + HASH_FIND(hh,coin->alladdresses,address,strlen(address),hashstr); + if ( hashstr == 0 ) + { + hashstr = calloc(1,sizeof(*hashstr)); + strncpy(hashstr->address,address,sizeof(hashstr->address)); + HASH_ADD_KEYPTR(hh,coin->alladdresses,hashstr->address,strlen(address),hashstr); + saveflag = 1; + } + if ( saveflag != 0 ) + { + FILE *fp; + if ( (instr= dpow_alladdresses(myinfo,coin)) != 0 ) + { + if ( (alljson= cJSON_Parse(instr)) != 0 ) + { + n = cJSON_GetArraySize(alljson); + for (i=0; ialladdresses,address,strlen(address),hashstr); + if ( hashstr == 0 ) + { + hashstr = calloc(1,sizeof(*hashstr)); + strncpy(hashstr->address,address,sizeof(hashstr->address)); + HASH_ADD_KEYPTR(hh,coin->alladdresses,hashstr->address,strlen(address),hashstr); + } + } + free_json(alljson); + } + free(instr); + } + alljson = cJSON_CreateArray(); + HASH_ITER(hh,coin->alladdresses,hashstr,tmp) + { + jaddistr(alljson,hashstr->address); + } + outstr = jprint(alljson,0); + sprintf(fname,"%s/alladdresses.%s",GLOBAL_CONFSDIR,coin->symbol), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(outstr,1,strlen(outstr)+1,fp); + fclose(fp); + printf("importaddress.(%s) -> alladdresses.%s\n",address,coin->symbol); + } + free(outstr); + } +} + +cJSON *dpow_checkaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address) +{ + int32_t isvalid=0,doneflag=0; char *retstr; cJSON *validatejson,*retjson = cJSON_CreateObject(); + if ( (retstr= dpow_validateaddress(myinfo,coin,address)) != 0 ) + { + if ( (validatejson= cJSON_Parse(retstr)) != 0 ) + { + if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 ) + { + if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 ) + doneflag = 1; + } + free_json(validatejson); + } + free(retstr); + retstr = 0; + } + if ( isvalid == 0 ) + jaddstr(retjson,"error","invalid address"); + else if ( doneflag != 0 ) + { + jaddstr(retjson,"coin",coin->symbol); + jaddstr(retjson,"address",address); + } + return(retjson); +} + +char *dpow_importaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address) +{ + char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0; + if ( (retstr= dpow_validateaddress(myinfo,coin,address)) != 0 ) + { + if ( (validatejson= cJSON_Parse(retstr)) != 0 ) + { + if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 ) + { + if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 ) + doneflag = 1; + } + free_json(validatejson); + } + free(retstr); + retstr = 0; + } + if ( isvalid == 0 ) + return(clonestr("{\"isvalid\":false}")); + update_alladdresses(myinfo,coin,address); + if ( doneflag != 0 ) + return(0); // success + if ( coin->FULLNODE < 0 ) + { + sprintf(buf,"[\"%s\", \"%s\", false]",address,address); + retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"importaddress",buf); + printf("%s importaddress.(%s) -> (%s)\n",coin->symbol,address,retstr); + return(retstr); + } + else return(0); +} + +void init_alladdresses(struct supernet_info *myinfo,struct iguana_info *coin) +{ + char *alladdresses,*retstr; cJSON *alljson; int32_t i,n; + if ( (alladdresses= dpow_alladdresses(myinfo,coin)) != 0 ) + { + printf("(%s) ALL.(%s)\n",coin->symbol,alladdresses); + if ( (alljson= cJSON_Parse(alladdresses)) != 0 ) + { + if ( is_cJSON_Array(alljson) != 0 && (n= cJSON_GetArraySize(alljson)) > 0 ) + { + for (i=0; ilastbesthash; + *blockhashp = besthash = dpow_getbestblockhash(myinfo,coin); + if ( bits256_nonz(besthash) != 0 && bits256_cmp(oldhash,besthash) != 0 ) + { + if ( (json= dpow_getblock(myinfo,coin,besthash)) != 0 ) + { + if ( (height= juint(json,"height")) != 0 && (*blocktimep= juint(json,"time")) != 0 ) + { + coin->lastbestheight = height; + if ( height > coin->longestchain ) + coin->longestchain = height; + if ( txs != 0 && numtxp != 0 && (array= jarray(&n,json,"tx")) != 0 ) + { + for (i=0; isymbol,"USD") == 0 ) + printf("dpow_getchaintip %s ht.%d time.%u numtx.%d\n",coin->symbol,height,*blocktimep,n); + *numtxp = n; + } + } else height = -1; + free_json(json); + } + } + return(coin->lastbestheight); +} + +int32_t dpow_vini_ismine(struct supernet_info *myinfo,struct dpow_info *dp,cJSON *item) +{ + cJSON *sobj; char *hexstr; int32_t len; uint8_t data[35]; + if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 ) + { + len = (int32_t)strlen(hexstr) >> 1; + if ( len <= sizeof(data) ) + { + decode_hex(data,len,hexstr); + if ( len == 35 && data[34] == CHECKSIG && data[0] == 33 && memcmp(data+1,dp->minerkey33,33) == 0 ) + return(0); + } + } + return(-1); +} + +int32_t dpow_haveutxo(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr) +{ + int32_t vout,haveutxo = 0; uint32_t i,j,n,r; bits256 txid; cJSON *unspents,*item; uint64_t satoshis; char *str,*address; uint8_t script[35]; + memset(txidp,0,sizeof(*txidp)); + *voutp = -1; + if ( (unspents= dpow_listunspent(myinfo,coin,coinaddr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(unspents)) > 0 ) + { + /*{ + "txid" : "34bc21b40d6baf38e2db5be5353dd0bcc9fe416485a2a68753541ed2f9c194b1", + "vout" : 0, + "address" : "RFBmvBaRybj9io1UpgWM4pzgufc3E4yza7", + "scriptPubKey" : "21039a3f7373ae91588b9edd76a9088b2871f62f3438d172b9f18e0581f64887404aac", + "amount" : 3.00000000, + "confirmations" : 4282, + "spendable" : true + },*/ + //r = 0; + //memcpy(&r,coin->symbol,3); + //r = calc_crc32(0,(void *)&r,sizeof(r)); + OS_randombytes((uint8_t *)&r,sizeof(r)); + for (j=0; j= 0 ) + { + if ( *voutp < 0 || (rand() % (n/2+1)) == 0 ) + { + *voutp = vout; + *txidp = txid; + } + haveutxo++; + } + } + } + } + if ( haveutxo == 0 ) + printf("no %s utxo: need to fund address.(%s) or wait for splitfund to confirm\n",coin->symbol,coinaddr); + } //else printf("null utxo array size\n"); + free_json(unspents); + } else printf("null return from dpow_listunspent\n"); + if ( 0 && haveutxo > 0 ) + printf("%s haveutxo.%d\n",coin->symbol,haveutxo); + return(haveutxo); +} + +char *dpow_issuemethod(char *userpass,char *method,char *params,uint16_t port) +{ + char url[512],*retstr=0,*retstr2=0,postdata[8192]; + if ( params == 0 || params[0] == 0 ) + params = (char *)"[]"; + if ( strlen(params) < sizeof(postdata)-128 ) + { + sprintf(url,(char *)"http://127.0.0.1:%u",port); + sprintf(postdata,"{\"method\":\"%s\",\"params\":%s}",method,params); + //printf("postdata.(%s) USERPASS.(%s)\n",postdata,KMDUSERPASS); + retstr2 = bitcoind_RPC(&retstr,(char *)"debug",url,userpass,method,params,0); + } + return(retstr2); +} + +uint64_t dpow_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume) +{ + char params[512],*retstr; uint64_t satoshis = 0; cJSON *retjson,*result; struct iguana_info *kmdcoin; + kmdcoin = iguana_coinfind("KMD"); + *seedp = 0; + sprintf(params,"[\"%s\", \"%s\", \"%d\", \"%.8f\"]",base,rel,height,(double)basevolume/SATOSHIDEN); + if ( kmdcoin != 0 && (retstr= dpow_issuemethod(kmdcoin->chain->userpass,"paxprice",params,kmdcoin->chain->rpcport)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (result= jobj(retjson,"result")) != 0 ) + { + satoshis = jdouble(result,"relvolume") * SATOSHIDEN; + *seedp = j64bits(result,"seed"); + } + free_json(retjson); + } + //printf("dpow_paxprice.(%s) -> %s %.8f\n",params,retstr,dstr(satoshis)); + } + return(satoshis); +} + +#define KOMODO_PUBTYPE 60 + +int32_t PAX_pubkey(int32_t rwflag,uint8_t *pubkey33,uint8_t *addrtypep,uint8_t rmd160[20],char fiat[4],uint8_t *shortflagp,int64_t *fiatoshisp) +{ + if ( rwflag != 0 ) + { + memset(pubkey33,0,33); + pubkey33[0] = 0x02 | (*shortflagp != 0); + memcpy(&pubkey33[1],fiat,3); + iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp); + pubkey33[12] = *addrtypep; + memcpy(&pubkey33[13],rmd160,20); + } + else + { + *shortflagp = (pubkey33[0] == 0x03); + memcpy(fiat,&pubkey33[1],3); + fiat[3] = 0; + iguana_rwnum(rwflag,&pubkey33[4],sizeof(*fiatoshisp),(void *)fiatoshisp); + if ( *shortflagp != 0 ) + *fiatoshisp = -(*fiatoshisp); + *addrtypep = pubkey33[12]; + memcpy(rmd160,&pubkey33[13],20); + } + return(33); +} + +uint64_t PAX_fiatdest(uint64_t *seedp,int32_t tokomodo,char *destaddr,uint8_t pubkey33[33],char *coinaddr,int32_t kmdheight,char *origbase,int64_t fiatoshis) +{ + uint8_t shortflag=0; char base[4]; int32_t i; uint8_t addrtype,rmd160[20]; int64_t komodoshis=0; + for (i=0; i<3; i++) + base[i] = toupper((int32_t)origbase[i]); + base[i] = 0; + if ( strcmp(base,"KMD") == 0 ) + return(0); + if ( fiatoshis < 0 ) + shortflag = 1, fiatoshis = -fiatoshis; + komodoshis = dpow_paxprice(seedp,kmdheight,base,(char *)"KMD",(uint64_t)fiatoshis); + if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == 20 ) + { + PAX_pubkey(1,pubkey33,&addrtype,rmd160,base,&shortflag,tokomodo != 0 ? &komodoshis : &fiatoshis); + bitcoin_address(destaddr,KOMODO_PUBTYPE,pubkey33,33); + } + return(komodoshis); +} + +int32_t dpow_scriptitemlen(int32_t *opretlenp,uint8_t *script) +{ + int32_t opretlen,len = 0; + if ( (opretlen= script[len++]) >= 0x4c ) + { + if ( opretlen == 0x4c ) + opretlen = script[len++]; + else if ( opretlen == 0x4d ) + { + opretlen = script[len++]; + opretlen = (opretlen << 8) | script[len++]; + } + } + *opretlenp = opretlen; + return(len); +} + +cJSON *dpow_paxjson(struct pax_transaction *pax) +{ + uint8_t addrtype,rmd160[20]; int32_t i; char rmdstr[41]; cJSON *item = cJSON_CreateObject(); + if ( pax != 0 ) + { + jaddbits256(item,"prev_hash",pax->txid); + jaddnum(item,"prev_vout",pax->vout); + if ( pax->shortflag != 0 ) + jaddnum(item,"short",pax->shortflag); + jaddnum(item,pax->symbol,dstr(pax->fiatoshis)); + jaddstr(item,"fiat",pax->symbol); + jaddnum(item,"kmdheight",pax->kmdheight); + jaddnum(item,"height",pax->height); + jaddnum(item,"KMD",dstr(pax->komodoshis)); + jaddstr(item,"address",pax->coinaddr); + bitcoin_addr2rmd160(&addrtype,rmd160,pax->coinaddr); + for (i=0; i<20; i++) + sprintf(&rmdstr[i<<1],"%02x",rmd160[i]); + rmdstr[40] = 0; + jaddstr(item,"rmd160",rmdstr); + } + return(item); +} + +uint64_t dpow_paxtotal(struct dpow_info *dp) +{ + struct pax_transaction *pax,*tmp; uint64_t total = 0; + pthread_mutex_lock(&dp->paxmutex); + /*if ( dp->PAX != 0 ) + { + tmp = 0; + pax= dp->PAX->hh.next; + while ( pax != 0 && pax != tmp ) + { + if ( pax->marked == 0 ) + total += pax->komodoshis; + tmp = pax; + pax = pax->hh.next; + } + }*/ + HASH_ITER(hh,dp->PAX,pax,tmp) + { + if ( pax->marked == 0 ) + total += pax->komodoshis; + } + pthread_mutex_unlock(&dp->paxmutex); + return(total); +} + +struct pax_transaction *dpow_paxfind(struct dpow_info *dp,struct pax_transaction *space,bits256 txid,uint16_t vout) +{ + struct pax_transaction *pax; + pthread_mutex_lock(&dp->paxmutex); + HASH_FIND(hh,dp->PAX,&txid,sizeof(txid),pax); + if ( pax != 0 ) + memcpy(space,pax,sizeof(*pax)); + pthread_mutex_unlock(&dp->paxmutex); + return(pax); +} + +struct pax_transaction *dpow_paxmark(struct dpow_info *dp,struct pax_transaction *space,bits256 txid,uint16_t vout,int32_t mark) +{ + struct pax_transaction *pax; + pthread_mutex_lock(&dp->paxmutex); + HASH_FIND(hh,dp->PAX,&txid,sizeof(txid),pax); + if ( pax == 0 ) + { + pax = (struct pax_transaction *)calloc(1,sizeof(*pax)); + pax->txid = txid; + pax->vout = vout; + HASH_ADD_KEYPTR(hh,dp->PAX,&pax->txid,sizeof(pax->txid),pax); + } + if ( pax != 0 ) + { + pax->marked = mark; + int32_t i; for (i=0; i<32; i++) + printf("%02x",((uint8_t *)&txid)[i]); + printf(" paxmark.ht %d vout%d\n",mark,vout); + memcpy(space,pax,sizeof(*pax)); + } + pthread_mutex_unlock(&dp->paxmutex); + return(pax); +} + +cJSON *dpow_withdraws_pending(struct dpow_info *dp) +{ + struct pax_transaction *pax,*tmp; cJSON *retjson = cJSON_CreateArray(); + pthread_mutex_lock(&dp->paxmutex); + /*if ( dp->PAX != 0 ) + { + tmp = 0; + pax = dp->PAX->hh.next; + while ( pax != 0 && pax != tmp ) + { + if ( pax->marked == 0 ) + jaddi(retjson,dpow_paxjson(pax)); + tmp = pax; + pax = pax->hh.next; + } + }*/ + HASH_ITER(hh,dp->PAX,pax,tmp) + { + if ( pax->marked == 0 ) + jaddi(retjson,dpow_paxjson(pax)); + } + pthread_mutex_unlock(&dp->paxmutex); + return(retjson); +} + +void dpow_issuer_withdraw(struct dpow_info *dp,char *coinaddr,uint64_t fiatoshis,int32_t shortflag,char *symbol,uint64_t komodoshis,uint8_t *rmd160,bits256 txid,uint16_t vout,int32_t kmdheight,int32_t height) // assetchain context +{ + struct pax_transaction *pax; + pthread_mutex_lock(&dp->paxmutex); + HASH_FIND(hh,dp->PAX,&txid,sizeof(txid),pax); + if ( pax == 0 ) + { + pax = (struct pax_transaction *)calloc(1,sizeof(*pax)); + pax->txid = txid; + pax->vout = vout; + HASH_ADD_KEYPTR(hh,dp->PAX,&pax->txid,sizeof(pax->txid),pax); + } + pthread_mutex_unlock(&dp->paxmutex); + if ( coinaddr != 0 ) + { + strcpy(pax->coinaddr,coinaddr); + pax->komodoshis = komodoshis; + pax->shortflag = shortflag; + strcpy(pax->symbol,symbol); + pax->fiatoshis = fiatoshis; + memcpy(pax->rmd160,rmd160,20); + pax->kmdheight = kmdheight; + pax->height = height; + if ( pax->marked == 0 ) + printf("ADD WITHDRAW %s %.8f -> %s %.8f TO PAX kht.%d ht.%d\n",symbol,dstr(pax->fiatoshis),coinaddr,dstr(pax->komodoshis),kmdheight,height); + else printf("MARKED WITHDRAW %s %.8f -> %s %.8f TO PAX kht.%d ht.%d\n",symbol,dstr(pax->fiatoshis),coinaddr,dstr(pax->komodoshis),kmdheight,height); + } + else + { + pax->marked = height; + printf("MARK WITHDRAW ht.%d\n",height); + } +} + +void dpow_issuer_voutupdate(struct dpow_info *dp,char *symbol,int32_t isspecial,int32_t height,int32_t txi,bits256 txid,int32_t vout,int32_t numvouts,int64_t fiatoshis,uint8_t *script,int32_t len) +{ + char base[16],destaddr[64],coinaddr[64]; uint8_t addrtype,shortflag,rmd160[20],pubkey33[33]; int64_t checktoshis,komodoshis; uint64_t seed; struct pax_transaction space; int32_t i,kmdheight,opretlen,offset = 0; + if ( script[offset++] == 0x6a ) + { + memset(base,0,sizeof(base)); + offset += dpow_scriptitemlen(&opretlen,&script[offset]); + if ( script[offset] == 'W' && strcmp(dp->symbol,"KMD") != 0 ) + { + // if valid add to pricefeed for issue + printf("WITHDRAW ht.%d txi.%d vout.%d %.8f opretlen.%d\n",height,txi,vout,dstr(fiatoshis),opretlen); + if ( opretlen == 38 ) // any KMD tx + { + offset++; + offset += PAX_pubkey(0,&script[offset],&addrtype,rmd160,base,&shortflag,&komodoshis); + iguana_rwnum(0,&script[offset],sizeof(kmdheight),&kmdheight); + if ( komodoshis < 0 ) + komodoshis = -komodoshis; + bitcoin_address(coinaddr,addrtype,rmd160,20); + checktoshis = PAX_fiatdest(&seed,1,destaddr,pubkey33,coinaddr,kmdheight,base,fiatoshis); + for (i=0; i<32; i++) + printf("%02x",((uint8_t *)&txid)[i]); + printf(" <- txid.v%u ",vout); + for (i=0; i<33; i++) + printf("%02x",pubkey33[i]); + printf(" checkpubkey fiat %.8f check %.8f vs komodoshis %.8f dest.(%s) kmdheight.%d ht.%d seed.%llu\n",dstr(fiatoshis),dstr(checktoshis),dstr(komodoshis),destaddr,kmdheight,height,(long long)seed); + if ( shortflag == 0 ) + { + if ( seed == 0 || checktoshis >= komodoshis ) + { + if ( dpow_paxfind(dp,&space,txid,vout) == 0 ) + dpow_issuer_withdraw(dp,coinaddr,fiatoshis,shortflag,base,komodoshis,rmd160,txid,vout,kmdheight,height); + } + } + else // short + { + printf("shorting not yet, wait for pax2\n"); + /*for (i=0; isymbol,"KMD") == 0 ) + { + printf("WITHDRAW issued ht.%d txi.%d vout.%d %.8f\n",height,txi,vout,dstr(fiatoshis)); + if ( opretlen == 46 ) // any KMD tx + { + offset++; + offset += PAX_pubkey(0,&script[offset],&addrtype,rmd160,base,&shortflag,&fiatoshis); + iguana_rwnum(0,&script[offset],sizeof(kmdheight),&kmdheight); + iguana_rwnum(0,&script[offset],sizeof(height),&height); + if ( fiatoshis < 0 ) + fiatoshis = -fiatoshis; + bitcoin_address(coinaddr,addrtype,rmd160,20); + checktoshis = PAX_fiatdest(&seed,1,destaddr,pubkey33,coinaddr,kmdheight,base,fiatoshis); + for (i=0; i<32; i++) + printf("%02x",((uint8_t *)&txid)[i]); + printf(" <- txid.v%u ",vout); + for (i=0; i<33; i++) + printf("%02x",pubkey33[i]); + printf(" checkpubkey check %.8f v %.8f dest.(%s) height.%d\n",dstr(checktoshis),dstr(fiatoshis),destaddr,height); + if ( shortflag == 0 ) + { + if ( seed == 0 || checktoshis > fiatoshis ) + { + dpow_paxmark(dp,&space,txid,vout,height); + } + } + else + { + printf("shorting not yet, wait for pax2\n"); + } + } + } + } +} + +int32_t dpow_issuer_tx(int32_t *isspecialp,struct dpow_info *dp,struct iguana_info *coin,int32_t height,int32_t txi,char *txidstr,uint32_t port) +{ + char *retstr,params[256],*hexstr; uint8_t script[16384]; cJSON *json,*oldpub,*newpub,*result,*vouts,*item,*sobj; int32_t vout,n,len,retval = -1; uint64_t value; bits256 txid; + sprintf(params,"[\"%s\", 1]",txidstr); + *isspecialp = 0; + if ( (retstr= dpow_issuemethod(coin->chain->userpass,(char *)"getrawtransaction",params,port)) != 0 ) + { + if ( (json= cJSON_Parse(retstr)) != 0 ) + { + //printf("TX.(%s)\n",retstr); + if ( (result= jobj(json,(char *)"result")) != 0 ) + { + oldpub = jobj(result,(char *)"vpub_old"); + newpub = jobj(result,(char *)"vpub_new"); + retval = 0; + if ( oldpub == 0 && newpub == 0 && (vouts= jarray(&n,result,(char *)"vout")) != 0 ) + { + txid = jbits256(result,(char *)"txid"); + for (vout=0; vout> 1; + if ( vout == 0 && ((memcmp(&hexstr[2],CRYPTO777_PUBSECPSTR,66) == 0 && len == 35) || (memcmp(&hexstr[6],CRYPTO777_RMD160STR,40) == 0 && len == 25)) ) + *isspecialp = 1; + else if ( len <= sizeof(script) ) + { + decode_hex(script,len,hexstr); + dpow_issuer_voutupdate(dp,coin->symbol,*isspecialp,height,txi,txid,vout,n,value,script,len); + } + } + } + } + } + } else printf("error getting txids.(%s)\n",retstr); + free_json(json); + } + free(retstr); + } + return(retval); +} + +int32_t dpow_issuer_block(struct dpow_info *dp,struct iguana_info *coin,int32_t height,uint16_t port) +{ + char *retstr,*retstr2,params[128],*txidstr; int32_t i,isspecial,n,retval = -1; cJSON *json,*tx=0,*result=0,*result2; + sprintf(params,"[%d]",height); + if ( (retstr= dpow_issuemethod(coin->chain->userpass,(char *)"getblockhash",params,port)) != 0 ) + { + if ( (result= cJSON_Parse(retstr)) != 0 ) + { + if ( (txidstr= jstr(result,(char *)"result")) != 0 && strlen(txidstr) == 64 ) + { + sprintf(params,"[\"%s\"]",txidstr); + if ( (retstr2= dpow_issuemethod(coin->chain->userpass,(char *)"getblock",params,port)) != 0 ) + { + //printf("getblock.(%s)\n",retstr2); + if ( (json= cJSON_Parse(retstr2)) != 0 ) + { + if ( (result2= jobj(json,(char *)"result")) != 0 && (tx= jarray(&n,result2,(char *)"tx")) != 0 ) + { + for (i=0; ichain->rpcport; + if ( height <= 0 ) + height = 1; + *isrealtimep = 0; + if ( (retstr= dpow_issuemethod(coin->chain->userpass,(char *)"getinfo",0,port)) != 0 ) + { + if ( (infoobj= cJSON_Parse(retstr)) != 0 ) + { + if ( (result= jobj(infoobj,(char *)"result")) != 0 && (currentheight= jint(result,(char *)"blocks")) != 0 ) + { + for (i=0; i<500 && height<=currentheight; i++,height++) + { + /*fprintf(stderr,"%s.%d ",coin->symbol,height); + if ( (height % 10) == 0 ) + { + if ( (height % 100) == 0 ) + fprintf(stderr,"%s.%d ",coin->symbol,height); + memset(&zero,0,sizeof(zero)); + komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,0,0,0,0,0); + }*/ + if ( dpow_issuer_block(dp,coin,height,port) < 0 ) + { + printf("error height %d\n",height); + break; + } + usleep(10000); + } + if ( height >= currentheight ) + *isrealtimep = (uint32_t)time(NULL); + } + free_json(infoobj); + } + //printf("GETINFO.(%s)\n",retstr); + free(retstr); + } + else + { + printf("error from %s height.%d currentheight.%d\n",coin->symbol,height,currentheight); + usleep(100000); + } + //printf("[%s -> %s] %s ht.%d current.%d\n",dp->symbol,dp->dest,coin->symbol,height,currentheight); + return(height); +} + diff --git a/iguana/dpow/dpow_tx.c b/iguana/dpow/dpow_tx.c new file mode 100755 index 000000000..fac9033af --- /dev/null +++ b/iguana/dpow/dpow_tx.c @@ -0,0 +1,620 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#define DPOW_BLACKLIST -100000 + +void dpow_bestmask_update(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint8_t nn_senderind,int8_t nn_bestk,uint64_t nn_bestmask,uint64_t nn_recvmask) +{ + int32_t startscore; + if ( nn_senderind < 0 || nn_senderind >= bp->numnotaries ) + return; + bp->notaries[nn_senderind].bestk = nn_bestk; + bp->notaries[nn_senderind].bestmask = nn_bestmask; + bp->notaries[nn_senderind].recvmask |= nn_recvmask; + startscore = bp->scores[nn_senderind]; + if ( bp->bestk >= 0 ) + { + if ( nn_bestk < 0 ) + bp->scores[nn_senderind] -= 10; + else if ( nn_bestk != bp->bestk ) + bp->scores[nn_senderind]--; + else if ( nn_bestmask != bp->bestmask ) + bp->scores[nn_senderind]--; + else if ( bp->scores[nn_senderind] < 1 ) + bp->scores[nn_senderind] = 1; + else bp->scores[nn_senderind]++; + if ( startscore > DPOW_BLACKLIST && bp->scores[nn_senderind] <= DPOW_BLACKLIST ) + printf(">>>>>>>>>>>>> nn_senderind.%d %llx MIA, skip this node for now\n",nn_senderind,(long long)(1LL << nn_senderind)); + } +} + +uint64_t dpow_lastk_mask(struct dpow_block *bp,int8_t *lastkp) +{ + int32_t j,m,k; uint64_t mask = bp->require0; + *lastkp = -1; + m = bp->require0; + for (j=0; jnumnotaries; j++) + { + k = DPOW_MODIND(bp,j); + if ( (bp->require0 == 0 || k != 0) && bp->scores[k] < DPOW_BLACKLIST ) + continue; + if ( bits256_nonz(bp->notaries[k].src.prev_hash) != 0 && bits256_nonz(bp->notaries[k].dest.prev_hash) != 0 ) + { + bp->recvmask |= (1LL << k); + mask |= (1LL << k); + if ( ++m >= bp->minsigs ) + { + *lastkp = k; + break; + } + } + } + return(mask); +} + +int32_t dpow_bestk(struct dpow_block *bp,uint64_t *maskp) +{ + int8_t lastk; uint64_t mask; + *maskp = 0; + mask = dpow_lastk_mask(bp,&lastk); + if ( lastk < 0 ) + return(-1); + *maskp = mask; + return(lastk); +} + +uint64_t dpow_ratifybest(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp) +{ + int32_t m,j,k; uint64_t bestmask,mask = bp->require0; + bestmask = 0; + *lastkp = -1; + for (m=j=0; jnumnotaries; j++) + { + k = (j + ((uint32_t)time(NULL) / DPOW_EPOCHDURATION)) % bp->numnotaries;//DPOW_MODIND(bp,j); + if ( bp->require0 != 0 && k == 0 ) + continue; + if ( bits256_nonz(bp->notaries[k].ratifysrcutxo) != 0 && bits256_nonz(bp->notaries[k].ratifydestutxo) != 0 ) + { + mask |= (1LL << k); + if ( ++m == bp->minsigs-bp->require0 ) + { + *lastkp = k; + bestmask = mask | bp->require0; + //printf("m.%d == minsigs.%d (%d %llx)\n",m,bp->minsigs,k,(long long)bestmask); + } + } + } + return(bestmask); +} + +uint64_t dpow_notarybestk(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp) +{ + int32_t m,j,k; uint64_t bestmask,mask = 0;//bp->require0; + bestmask = 0; + *lastkp = -1; + for (m=j=0; jnumnotaries; j++) + { + //k = (j + ((uint32_t)time(NULL) / 180)) % bp->numnotaries; + k = (j + (bp->height/DPOW_CHECKPOINTFREQ)) % bp->numnotaries; + //if ( bp->require0 != 0 && k == 0 ) + // continue; + if ( bits256_nonz(bp->notaries[k].src.prev_hash) != 0 && bits256_nonz(bp->notaries[k].dest.prev_hash) != 0 && bp->paxwdcrc == bp->notaries[k].paxwdcrc ) + { + mask |= (1LL << k); + if ( ++m == bp->minsigs )//-bp->require0 ) + { + *lastkp = k; + bestmask = mask;// | bp->require0; + //printf("m.%d == minsigs.%d (%d %llx)\n",m,bp->minsigs,k,(long long)bestmask); + } + } + } + return(bestmask); +} + +uint64_t dpow_maskmin(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp) +{ + int32_t j,m,k; uint64_t bestmask,mask = 0;//bp->require0; + bestmask = 0; + *lastkp = -1; + m = 0;//bp->require0; + for (j=0; jnumnotaries; j++) + { + k = DPOW_MODIND(bp,j); + //if ( (bp->require0 == 0 || k != 0) && bp->scores[k] < DPOW_BLACKLIST ) + // continue; + if ( bits256_nonz(bp->notaries[k].src.prev_hash) != 0 && bits256_nonz(bp->notaries[k].dest.prev_hash) != 0 && bp->paxwdcrc == bp->notaries[k].paxwdcrc ) + { + mask |= (1LL << k); + if ( ++m == bp->minsigs ) + { + *lastkp = k; + bestmask = mask; + } + } + } + bp->recvmask |= mask; + if ( *lastkp >= 0 ) + { + for (mask=j=0; jnumnotaries; j++) + { + if ( bp->notaries[j].src.siglens[*lastkp] > 0 ) + mask |= (1LL << j); + } + bp->srcsigsmasks[*lastkp] |= mask; + for (mask=j=0; jnumnotaries; j++) + { + if ( bp->notaries[j].dest.siglens[*lastkp] > 0 ) + mask |= (1LL << j); + } + bp->destsigsmasks[*lastkp] |= mask; + } + return(bestmask); +} + +struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height) +{ + int32_t r,h,incr = 100000; struct dpow_block *bp = 0; + if ( height > dp->maxblocks ) + { + dp->blocks = realloc(dp->blocks,sizeof(*dp->blocks) * (dp->maxblocks + incr)); + memset(&dp->blocks[dp->maxblocks],0,sizeof(*dp->blocks) * incr); + dp->maxblocks += incr; + } + if ( height < dp->maxblocks ) + bp = dp->blocks!=0 ? dp->blocks[height] : 0; + if ( bp == 0 && height < DPOW_FIRSTRATIFY ) + { + r = (rand() % DPOW_FIRSTRATIFY); + for (h=0; hblocks[height]) != 0 ) + return(bp); + } + } + if ( bp != 0 && bp->state == 0xffffffff ) + bp = 0; + return(bp); +} + +int32_t dpow_voutstandard(struct dpow_block *bp,uint8_t *serialized,int32_t m,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) +{ + uint32_t paxwdcrc=0,locktime=0,numvouts; uint64_t satoshis,satoshisB; int32_t i,n=0,opretlen,len=0; uint8_t opret[16384],data[16384],extras[16384]; + numvouts = 2; + if ( pubkeys == 0 || numratified <= 0 ) + { + satoshis = DPOW_UTXOSIZE * m * .76; + if ( (satoshisB= DPOW_UTXOSIZE * m - 10000) < satoshis ) + satoshis = satoshisB; + } + else + { + satoshis = DPOW_MINOUTPUT; + numvouts += numratified; + } + len += iguana_rwvarint32(1,&serialized[len],&numvouts); + len += iguana_rwnum(1,&serialized[len],sizeof(satoshis),&satoshis); + serialized[len++] = 35; + serialized[len++] = 33; + decode_hex(&serialized[len],33,CRYPTO777_PUBSECPSTR), len += 33; + serialized[len++] = CHECKSIG; + if ( pubkeys != 0 && numratified != 0 ) + { + satoshis = DPOW_MINOUTPUT; + for (i=0; idestcoin->symbol,"BTC") != 0) && (n= dpow_paxpending(extras,&paxwdcrc)) > 0 ) + { + for (i=0; iisratify != 0 ) + opretlen = dpow_rwopret(1,opret,&bp->hashmsg,&bp->height,bp->srccoin->symbol,0,0,bp,src_or_dest); + else opretlen = dpow_rwopret(1,opret,&bp->hashmsg,&bp->height,bp->srccoin->symbol,extras,n,bp,src_or_dest); + if ( opretlen < 0 ) + { + printf("negative opretlen.%d src_or_dest.%d\n",opretlen,src_or_dest); + return(-1); + } + opretlen = dpow_opreturnscript(data,opret,opretlen); + if ( opretlen < 0xfd ) + serialized[len++] = opretlen; + else + { + serialized[len++] = 0xfd; + serialized[len++] = opretlen & 0xff; + serialized[len++] = (opretlen >> 8) & 0xff; + } + memcpy(&serialized[len],data,opretlen), len += opretlen; + len += iguana_rwnum(1,&serialized[len],sizeof(locktime),&locktime); + return(len); +} + +bits256 dpow_notarytx(char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) +{ + uint32_t k,m,numsigs,version,vout,crcval,sequenceid = 0xffffffff; bits256 zero; int32_t n,siglen,len; uint8_t serialized[32768],*sig; bits256 txid; struct dpow_entry *ep; struct dpow_coinentry *cp; + signedtx[0] = 0; + *numsigsp = 0; + memset(zero.bytes,0,sizeof(zero)); + len = numsigs = 0; + version = 1; + len += iguana_rwnum(1,&serialized[len],sizeof(version),&version); + if ( isPoS != 0 ) + len += iguana_rwnum(1,&serialized[len],sizeof(bp->timestamp),&bp->timestamp); + m = bp->minsigs; + len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&m); + for (k=m=0; knumnotaries; k++) + { + siglen = 0; + sig = 0; + if ( ((1LL << k) & bestmask) != 0 ) + { + if ( pubkeys != 0 && numratified > 0 ) + { + if ( src_or_dest != 0 ) + { + txid = bp->notaries[k].ratifydestutxo; + vout = bp->notaries[k].ratifydestvout; + } + else + { + txid = bp->notaries[k].ratifysrcutxo; + vout = bp->notaries[k].ratifysrcvout; + } + if ( bestk >= 0 ) + { + siglen = bp->notaries[k].ratifysiglens[src_or_dest]; + sig = bp->notaries[k].ratifysigs[src_or_dest]; + } + //char str[65]; printf("j.%d k.%d m.%d vin.(%s) v%d siglen.%d\n",j,k,m,bits256_str(str,txid),vout,siglen); + } + else + { + ep = &bp->notaries[k]; + cp = (src_or_dest != 0) ? &bp->notaries[k].dest : &bp->notaries[k].src; + if ( bits256_nonz(cp->prev_hash) == 0 ) + { + printf("null prevhash k.%d m.%d src_or_dest.%d\n",k,m,src_or_dest); + return(zero); + } + txid = cp->prev_hash; + vout = cp->prev_vout; + if ( bestk >= 0 ) + { + siglen = cp->siglens[bestk]; + sig = cp->sigs[bestk]; + } + } + len += iguana_rwbignum(1,&serialized[len],sizeof(txid),txid.bytes); + len += iguana_rwnum(1,&serialized[len],sizeof(vout),&vout); + if ( usesigs != 0 && bestk >= 0 ) + { + len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&siglen); + if ( siglen > 0 && siglen <= sizeof(cp->sigs[bestk]) ) + { + memcpy(&serialized[len],sig,siglen); + len += siglen; + numsigs++; + } else printf("Missing sig from k.%d\n",k); + } else serialized[len++] = 0; + len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid); + //printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j); + m++; + if ( m == bp->minsigs )//&& k == bestk ) + break; + } + } + if ( (n= dpow_voutstandard(bp,&serialized[len],m,src_or_dest,pubkeys,numratified)) < 0 ) + { + printf("error dpow_voutstandard m.%d src_or_dest.%d\n",m,src_or_dest); + return(zero); + } + len += n; + init_hexbytes_noT(signedtx,serialized,len); + //printf("notarytx.(%s) opretlen.%d\n",signedtx,opretlen); + if ( usesigs == 0 && bestk >= 0 ) + { + crcval = calc_crc32(0,bp->ratifyrawtx[src_or_dest],bp->rawratifiedlens[src_or_dest]); + if ( crcval != bp->pendingcrcs[src_or_dest] ) + { + printf("new crcval.[%d] %x != %x\n",src_or_dest,crcval,bp->pendingcrcs[src_or_dest]); + bp->pendingcrcs[src_or_dest] = crcval; + } + bp->notaries[bp->myind].pendingcrcs[src_or_dest] = bp->pendingcrcs[src_or_dest]; + } + *numsigsp = numsigs; + return(bits256_doublesha256(0,serialized,len)); +} + +cJSON *dpow_vins(struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,int32_t useratified) +{ + int32_t k,m; bits256 txid; uint16_t vout; uint8_t script[35]; char scriptstr[256]; cJSON *vins=0,*item; struct dpow_entry *ep; struct dpow_coinentry *cp; + vins = cJSON_CreateArray(); + for (m=k=0; knumnotaries; k++) + { + if ( ((1LL << k) & bestmask) != 0 ) + { + ep = &bp->notaries[k]; + if ( useratified != 0 ) + { + if ( src_or_dest != 0 ) + { + txid = bp->notaries[k].ratifydestutxo; + vout = bp->notaries[k].ratifydestvout; + } + else + { + txid = bp->notaries[k].ratifysrcutxo; + vout = bp->notaries[k].ratifysrcvout; + } + } + else + { + cp = (src_or_dest != 0) ? &bp->notaries[k].dest : &bp->notaries[k].src; + txid = cp->prev_hash; + vout = cp->prev_vout; + } + if ( bits256_nonz(txid) != 0 ) + { + item = cJSON_CreateObject(); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + if ( k == 0 && bp->require0 != 0 ) + { + script[0] = 0x76; + script[1] = 0xa9; + script[2] = 0x14; + calc_rmd160_sha256(&script[3],ep->pubkey,33); // 8ee61a3161993f4f7b7081259bf5f3322d65d3f8 + script[23] = 0x88; + script[24] = 0xac; + init_hexbytes_noT(scriptstr,script,25); + /*int32_t z; + for (z=0; z<25; z++) + printf("%02x",script[z]); + printf(" <- script0\n");*/ + } + else + { + script[0] = 33; + memcpy(script+1,ep->pubkey,33); + script[34] = CHECKSIG; + init_hexbytes_noT(scriptstr,script,35); + } + jaddstr(item,"scriptPubKey",scriptstr); + jaddi(vins,item); + //printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j); + m++; + if ( m == bp->minsigs )//&& k == bestk ) + break; + } + else + { + printf("null txid slot k.%d m.%d minsigs.%d\n",k,m,bp->minsigs); + free_json(vins); + return(0); + } + } + } + return(vins); +} + +void dpow_rawtxsign(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,struct dpow_block *bp,char *rawtx,cJSON *vins,int8_t bestk,uint64_t bestmask,int32_t myind,int32_t src_or_dest) +{ + int32_t j,m=0,valid,retval=-1; char *jsonstr,*signedtx,*rawtx2,*sigstr,*pubstr; cJSON *signobj,*vinitem,*sobj,*txobj2,*item,*vin; uint8_t pubkey33[33]; bits256 srchash; struct dpow_entry *ep; struct dpow_coinentry *cp; + if ( bestk < 0 ) + return; + for (j=0; jminerkey33[j+1]; + memset(srchash.bytes,0,sizeof(srchash)); + m = 0; + ep = &bp->notaries[myind]; + cp = (src_or_dest != 0) ? &bp->notaries[myind].dest : &bp->notaries[myind].src; + if ( (jsonstr= dpow_signrawtransaction(myinfo,coin,rawtx,vins)) != 0 ) + { + if ( (signobj= cJSON_Parse(jsonstr)) != 0 ) + { + if ( ((signedtx= jstr(signobj,"hex")) != 0 || (signedtx= jstr(signobj,"result")) != 0) && (rawtx2= dpow_decoderawtransaction(myinfo,coin,signedtx)) != 0 ) + { + if ( (txobj2= cJSON_Parse(rawtx2)) != 0 ) + { + if ( (vin= jarray(&m,txobj2,"vin")) != 0 ) + { + for (j=0; j 32 ) + { + valid = 0; + if ( dp->ratifying != 0 && j == 0 && bp->myind == 0 ) + valid = 1; + else if ( (pubstr= jstr(vinitem,"scriptPubKey")) != 0 && is_hexstr(pubstr,0) == 70 ) + { + decode_hex(pubkey33,33,&pubstr[2]); + if ( memcmp(pubkey33,dp->minerkey33,33) == 0 ) + valid = 1; + else + { + int32_t z; + for (z=0; z<33; z++) + printf("%02x",dp->minerkey33[z]); + printf(" minerkey33 doesnt match\n"); + for (z=0; z<33; z++) + printf("%02x",pubkey33[z]); + printf(" scriptPubKey\n"); + } + } + if ( valid != 0 ) + { + printf("bestk.%d %llx %s height.%d mod.%d VINI.%d myind.%d MINE.(%s) j.%d\n",bestk,(long long)bestmask,(src_or_dest != 0) ? bp->destcoin->symbol : bp->srccoin->symbol,bp->height,DPOW_MODIND(bp,0),j,myind,jprint(item,0),j); + cp->siglens[bestk] = (int32_t)strlen(sigstr) >> 1; + if ( src_or_dest != 0 ) + bp->destsigsmasks[bestk] |= (1LL << myind); + else bp->srcsigsmasks[bestk] |= (1LL << myind); + decode_hex(cp->sigs[bestk],cp->siglens[bestk],sigstr); + ep->masks[src_or_dest][bestk] = bestmask; + ep->beacon = bp->beacon; + dpow_sigsend(myinfo,dp,bp,myind,bestk,bestmask,srchash,src_or_dest != 0 ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL); + retval = 0; + break; + } else printf("sig.%d of %d didnt match pubkey? (%s)\n",j,m,jprint(vinitem,0)); + } // else printf("notmine.(%s)\n",jprint(item,0)); + } + } else printf("no vin[] (%s)\n",jprint(txobj2,0)); + free_json(txobj2); + } else printf("cant parse.(%s)\n",rawtx2); + free(rawtx2); + } //else printf("error decoding (%s) %s\n",signedtx==0?"":signedtx,jsonstr); + free_json(signobj); + } else printf("error parsing.(%s)\n",jsonstr); + free(jsonstr); + } +} + +int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t myind,uint32_t deprec,int32_t src_or_dest,int32_t useratified) +{ + int32_t j,m,numsigs,len,siglen,retval=-1; char rawtx[32768],*jsonstr,*rawtx2,*signedtx,*sigstr; cJSON *item,*sobj,*vins,*vin,*txobj2,*signobj; bits256 txid,srchash,zero; struct dpow_entry *ep; + ep = &bp->notaries[myind]; + memset(&zero,0,sizeof(zero)); + if ( bestk < 0 ) + return(-1); + for (j=0; jminerkey33[j+1]; + if ( (vins= dpow_vins(coin,bp,bestk,bestmask,1,src_or_dest,useratified)) != 0 ) + { + txid = dpow_notarytx(rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,useratified*bp->numratified); + //char str[65]; printf("signedtxgen %s src_or_dest.%d (%d %llx) useratified.%d raw.(%s)\n",bits256_str(str,txid),src_or_dest,bestk,(long long)bestmask,useratified,rawtx); + if ( bits256_nonz(txid) != 0 && rawtx[0] != 0 ) // send tx to share utxo set + { + if ( useratified != 0 ) + { + len = (int32_t)strlen(rawtx) >> 1; + if ( len <= sizeof(bp->ratifyrawtx[src_or_dest]) ) + { + decode_hex(bp->ratifyrawtx[src_or_dest],len,rawtx),bp->rawratifiedlens[src_or_dest] = len; + } + if ( (jsonstr= dpow_signrawtransaction(myinfo,coin,rawtx,vins)) != 0 ) + { + if ( (signobj= cJSON_Parse(jsonstr)) != 0 ) + { + if ( ((signedtx= jstr(signobj,"hex")) != 0 || (signedtx= jstr(signobj,"result")) != 0) && (rawtx2= dpow_decoderawtransaction(myinfo,coin,signedtx)) != 0 ) + { + if ( (txobj2= cJSON_Parse(rawtx2)) != 0 ) + { + if ( (vin= jarray(&m,txobj2,"vin")) != 0 ) + { + for (j=0; j 32 ) + { + siglen = (int32_t)strlen(sigstr) >> 1; + bp->ratifysiglens[src_or_dest] = siglen; + decode_hex(bp->ratifysigs[src_or_dest],siglen,sigstr); + bp->notaries[bp->myind].ratifysiglens[src_or_dest] = siglen; + memcpy(bp->notaries[bp->myind].ratifysigs[src_or_dest],bp->ratifysigs[src_or_dest],siglen); + bp->ratifysigmasks[src_or_dest] |= (1LL << bp->myind); + printf("RATIFYSIG[%d] <- set notaryid.%d siglen.%d (%s).%d\n",src_or_dest,bp->myind,bp->ratifysiglens[src_or_dest],sigstr,siglen); + break; + } + } + } + } + } + } + } + else + { + printf("signrawtransaction error vins.(%s) rawtx.(%s)\n",jprint(vins,0),rawtx); + } + } else dpow_rawtxsign(myinfo,dp,coin,bp,rawtx,vins,bestk,bestmask,myind,src_or_dest); + } else printf("signedtxgen zero txid or null rawtx\n"); + free_json(vins); + } + else if ( (bestmask & bp->recvmask) != bestmask ) + printf("signedtxgen error generating vins bestk.%d %llx recv.%llx need to recv %llx\n",bestk,(long long)bestmask,(long long)bp->recvmask,(long long)(bestmask & ~bp->recvmask)); + return(retval); +} + +void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,int32_t myind,int32_t src_or_dest,int8_t bestk,uint64_t bestmask,uint8_t pubkeys[64][33],int32_t numratified) +{ + bits256 txid,srchash,zero,signedtxid; struct iguana_info *coin; int32_t j,len,numsigs; char *retstr=0,str[65],str2[65]; uint8_t txdata[32768]; uint32_t channel,state; + coin = (src_or_dest != 0) ? bp->destcoin : bp->srccoin; + memset(zero.bytes,0,sizeof(zero)); + memset(txid.bytes,0,sizeof(txid)); + channel = (src_or_dest != 0) ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL; + if ( bestk >= 0 && bp->state != 0xffffffff && coin != 0 ) + { + dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,pubkeys,numratified); // setcrcval + signedtxid = dpow_notarytx(bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,1,src_or_dest,pubkeys,numratified); + //printf("src_or_dest.%d bestk.%d %llx %s numsigs.%d signedtx.(%s)\n",src_or_dest,bestk,(long long)bestmask,bits256_str(str,signedtxid),numsigs,bp->signedtx); + bp->state = 1; + if ( bits256_nonz(signedtxid) != 0 && numsigs == bp->minsigs ) + { + if ( (retstr= dpow_sendrawtransaction(myinfo,coin,bp->signedtx)) != 0 ) + { + //printf("sendrawtransaction.(%s)\n",retstr); + if ( is_hexstr(retstr,0) == sizeof(txid)*2 ) + { + decode_hex(txid.bytes,sizeof(txid),retstr); + if ( bits256_cmp(txid,signedtxid) == 0 ) + { + if ( src_or_dest != 0 ) + { + bp->desttxid = txid; + dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bestk,bestmask,myind,DPOW_SIGCHANNEL,0,numratified != 0); + } else bp->srctxid = txid; + len = (int32_t)strlen(bp->signedtx) >> 1; + decode_hex(txdata+32,len,bp->signedtx); + for (j=0; jstate < state ) + { + bp->state = state; + dpow_send(myinfo,dp,bp,txid,bp->hashmsg,(src_or_dest != 0) ? DPOW_BTCTXIDCHANNEL : DPOW_TXIDCHANNEL,bp->height,txdata,len+32); + printf("complete statemachine.%s ht.%d state.%d (%x %x)\n",coin->symbol,bp->height,bp->state,bp->hashmsg.uints[0],txid.uints[0]); + } + } else printf("sendtxid mismatch got %s instead of %s\n",bits256_str(str,txid),bits256_str(str2,signedtxid)); + } + else + { + bp->state = 0xffffffff; + printf("dpow_sigscheck: mismatched txid.%s vs %s\n",bits256_str(str,txid),retstr); + } + free(retstr); + retstr = 0; + } + else + { + printf("NULL return from sendrawtransaction. abort\n"); + bp->state = 0xffffffff; + } + } else printf("numsigs.%d vs required.%d\n",numsigs,bp->minsigs); + } +} + diff --git a/iguana/example.js b/iguana/example.js index d8d59f6a8..d2a5b1b69 100755 --- a/iguana/example.js +++ b/iguana/example.js @@ -121,18 +121,13 @@ function domContentLoaded(name, tc, config, width, height) { window.requestFileSystem(PERSISTENT, bytes, function(fs) { console.log('Opened file system: ' + fs.name); fileSystem = fs; - copyHelpFiles().done(function() { - common.updateStatus( + common.updateStatus( 'Allocated ' + bytes + ' bytes of persistent storage. Running the first time will take 17 seconds to load'); common.attachDefaultListeners(); common.createNaClModule(name, tc, config, width, height); - }); - /*dirReader = fs.root.createReader(); - dirReader.readEntries(function(results) { - console.log(results); - }, function(){ - console.log('File IO error'); - });*/ + setTimeout(function(){ + copyHelpFiles(); + },2000); }, errorHandler); }, function(e) { diff --git a/iguana/exchanges/DB/.tmpmarker b/iguana/exchanges/DB/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/ECB/.tmpmarker b/iguana/exchanges/DB/ECB/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/PRICES/.tmpmarker b/iguana/exchanges/DB/PRICES/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/SWAPS/.tmpmarker b/iguana/exchanges/DB/SWAPS/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/TRANSACTIONS/.tmpmarker b/iguana/exchanges/DB/TRANSACTIONS/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/purgeable/.tmpmarker b/iguana/exchanges/DB/purgeable/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/purgeable/BTC/.tmpmarker b/iguana/exchanges/DB/purgeable/BTC/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DB/purgeable/BTCD/.tmpmarker b/iguana/exchanges/DB/purgeable/BTCD/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/DEXstats.h b/iguana/exchanges/DEXstats.h new file mode 100644 index 000000000..dc1f89864 --- /dev/null +++ b/iguana/exchanges/DEXstats.h @@ -0,0 +1,959 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// DEXstats.h +// marketmaker +// + +#ifndef DEXstats_h +#define DEXstats_h + +#define LEFTMARGIN 40 +#define MAX_SPLINES 1024 +#define MAX_LOOKAHEAD 7 + +struct stats_spline { char name[64]; int32_t splineid,lasti,basenum,num,firstx,dispincr,spline32[MAX_SPLINES][4]; uint32_t utc32[MAX_SPLINES]; int64_t spline64[MAX_SPLINES][4]; double dSplines[MAX_SPLINES][4],pricevals[MAX_SPLINES+MAX_LOOKAHEAD],lastutc,lastval,aveslopeabs; }; + +#define _extrapolate_Spline(Splines,gap) ((double)(Splines)[0] + ((gap) * ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3])))))) +#define _extrapolate_Slope(Splines,gap) ((double)(Splines)[1] + ((gap) * ((double)(Splines)[2] + ((gap) * (double)(Splines)[3])))) + +#define dto64(x) ((int64_t)((x) * (double)SATOSHIDEN * SATOSHIDEN)) +#define dto32(x) ((int32_t)((x) * (double)SATOSHIDEN)) +#define i64tod(x) ((double)(x) / ((double)SATOSHIDEN * SATOSHIDEN)) +#define i32tod(x) ((double)(x) / (double)SATOSHIDEN) +#define _extrapolate_spline64(spline64,gap) ((double)i64tod((spline64)[0]) + ((gap) * ((double)i64tod(.001*.001*(spline64)[1]) + ((gap) * ((double)i64tod(.001*.001*.001*.001*(spline64)[2]) + ((gap) * (double)i64tod(.001*.001*.001*.001*.001*.001*(spline64)[3]))))))) +#define _extrapolate_spline32(spline32,gap) ((double)i32tod((spline32)[0]) + ((gap) * ((double)i32tod(.001*.001*(spline32)[1]) + ((gap) * ((double)i32tod(.001*.001*.001*.001*(spline32)[2]) + ((gap) * (double)i32tod(.001*.001*.001*.001*.001*.001*(spline32)[3]))))))) + +uint32_t forex_colors[16]; +double Display_scale = 0.25; + +struct DEXstats_disp { double pricesum,volumesum; }; + +struct DEXstats_pricepoint +{ + double price,volume; + uint32_t height; + uint16_t seconds; + int8_t hour,dir; +}; + +struct DEXstats_pairinfo +{ + char dest[128]; + int32_t numprices; + struct DEXstats_pricepoint *prices; +}; + +struct DEXstats_datenuminfo +{ + int32_t numpairs,datenum; + struct DEXstats_pairinfo *pairs; +}; + +struct DEXstats_priceinfo +{ + char symbol[128]; + int32_t firstdatenum,numdates; + struct DEXstats_datenuminfo *dates; +} Prices[1024]; +int32_t Num_priceinfos; + +void stats_pricepoint(int32_t dir,struct DEXstats_pricepoint *ptr,uint8_t hour,uint16_t seconds,int32_t height,double volume,double price) +{ + ptr->price = price; + ptr->volume = volume; + ptr->height = height; + ptr->hour = hour; + ptr->dir = dir; + ptr->seconds = seconds; +} + +void stats_pairupdate(int32_t dir,struct DEXstats_datenuminfo *date,char *symbol,char *dest,int32_t datenum,int32_t hour,int32_t seconds,int32_t height,double volume,double price) +{ + int32_t i; struct DEXstats_pairinfo *pair = 0; + if ( date->datenum != datenum || seconds < 0 || seconds >= 3600 || hour < 0 || hour >= 24 ) + { + printf("date->datenum %d != %d? hour.%d seconds.%d\n",date->datenum,datenum,hour,seconds); + return; + } + //printf("%d numpairs.%d %p %p\n",date->datenum,date->numpairs,date,date->pairs); + for (i=0; inumpairs; i++) + if ( strcmp(dest,date->pairs[i].dest) == 0 ) + { + pair = &date->pairs[i]; + break; + } + if ( date->pairs == 0 || i == date->numpairs ) + { + date->pairs = realloc(date->pairs,sizeof(*date->pairs) * (date->numpairs + 1)); + pair = &date->pairs[date->numpairs++]; + memset(pair,0,sizeof(*pair)); + strcpy(pair->dest,dest); + printf("%d new pair.%d (%s) -> dest.(%s)\n",date->datenum,date->numpairs,symbol,dest); + } + pair->prices = realloc(pair->prices,sizeof(*pair->prices) * (pair->numprices+1)); + stats_pricepoint(dir,&pair->prices[pair->numprices++],hour,seconds,height,volume,price); + //printf("(%s/%s).%d numprices.%d h.%d s.%-4d %.8f %.6f\n",symbol,dest,date->datenum,pair->numprices,hour,seconds,price,volume); +} + +void stats_datenumupdate(int32_t dir,struct DEXstats_priceinfo *pp,int32_t datenum,int32_t hour,int32_t seconds,int32_t height,double volume,char *dest,double price) +{ + int32_t offset,i,n; struct DEXstats_datenuminfo *date; + if ( (offset= datenum - pp->firstdatenum) < 0 ) + { + printf("illegal datenum.%d for %s when 1st.%d\n",datenum,pp->symbol,pp->firstdatenum); + return; + } + if ( offset == 0 || offset > pp->numdates ) + { + pp->dates = realloc(pp->dates,sizeof(*pp->dates) * (offset+1)); + n = (offset - pp->numdates); + printf("allocate %s.[%d to %d]\n",pp->symbol,pp->numdates,pp->numdates+n); + for (i=0; i<=n; i++) + { + date = &pp->dates[pp->numdates + i]; + if ( date->datenum != pp->firstdatenum + pp->numdates + i ) + { + memset(date,0,sizeof(*date)); + date->datenum = pp->firstdatenum + pp->numdates + i; + } + } + pp->numdates = offset; + } + stats_pairupdate(dir,&pp->dates[offset],pp->symbol,dest,datenum,hour,seconds,height,volume,price); +} + +struct DEXstats_priceinfo *stats_priceinfo(char *symbol,int32_t datenum) +{ + int32_t i; struct DEXstats_priceinfo *pp = 0; + if ( Num_priceinfos >= sizeof(Prices)/sizeof(*Prices) ) + return(0); + for (i=0; isymbol,symbol); + pp->firstdatenum = datenum; + } + return(pp); +} + +void stats_LPpubkeyupdate(char *LPpubkey,uint32_t timestamp) +{ + printf("LP.(%s) t.%u\n",LPpubkey,timestamp); +} + +void stats_priceupdate(int32_t datenum,int32_t hour,int32_t seconds,uint32_t timestamp,int32_t height,char *key,char *LPpubkey,cJSON *tradejson) +{ + int32_t dir = 0; uint64_t srcamount,destamount; char *source,*dest; double price; struct DEXstats_priceinfo *pp; + if ( LPpubkey != 0 ) + stats_LPpubkeyupdate(LPpubkey,timestamp); + if ( tradejson != 0 ) + { + source = jstr(jitem(tradejson,0),0); + srcamount = SATOSHIDEN * jdouble(jitem(tradejson,1),0); + dest = jstr(jitem(tradejson,2),0); + destamount = SATOSHIDEN * jdouble(jitem(tradejson,3),0); + if ( srcamount != 0 && destamount != 0 ) + { + price = (double)destamount / srcamount; + if ( key != 0 ) + { + dir = 1; + if ( (pp= stats_priceinfo(source,datenum)) != 0 ) + stats_datenumupdate(-1,pp,datenum,hour,seconds,height,dstr(srcamount),dest,price); + if ( (pp= stats_priceinfo(dest,datenum)) != 0 ) + stats_datenumupdate(1,pp,datenum,hour,seconds,height,dstr(destamount),source,1. / price); + } + else if ( (pp= stats_priceinfo(source,datenum)) != 0 ) + stats_datenumupdate(0,pp,datenum,hour,seconds,height,dstr(srcamount),dest,price); + } else price = 0.; + if ( dir != 0 ) + printf("dir.%-2d %d.%02d.%04d ht.%-4d %s (%s %12.8f) -> (%s %12.8f) %16.8f %16.8f\n",dir,datenum,hour,seconds,height,key!=0?key:"",source,dstr(srcamount),dest,dstr(destamount),price,1./price); + } +} + +double _pairaved(double valA,double valB) +{ + if ( valA != 0. && valB != 0. ) + return((valA + valB) / 2.); + else if ( valA != 0. ) return(valA); + else return(valB); +} + +double calc_loganswer(double pastlogprice,double futurelogprice) +{ + if ( fabs(pastlogprice) < .0000001 || fabs(futurelogprice) < .0000001 ) + return(0); + return(10000. * (exp(futurelogprice - pastlogprice)-1.)); +} + +double _pairdiff(register double valA,register double valB) +{ + if ( valA != 0. && valB != 0. ) + return((valA - valB)); + else return(0.); +} + +double balanced_ave(double buf[],int32_t i,int32_t width) +{ + register int32_t nonz,j; register double sum,price; + nonz = 0; + sum = 0.0; + for (j=-width; j<=width; j++) + { + price = buf[i + j]; + if ( price != 0.0 ) + { + sum += price; + nonz++; + } + } + if ( nonz != 0 ) + sum /= nonz; + return(sum); +} + +void buf_trioave(double dest[],double src[],int32_t n) +{ + register int32_t i,j,width = 3; + for (i=0; i<128; i++) + src[i] = 0; + //for (i=n-width-1; i>width; i--) + // dest[i] = balanced_ave(src,i,width); + //for (i=width; i>0; i--) + // dest[i] = balanced_ave(src,i,i); + for (i=1; i>16)&0x0ff) + (float)((color>>8)&0x0ff) + (float)((color>>0)&0x0ff))/0x300); +} + +int32_t pixel_ratios(uint32_t red,uint32_t green,uint32_t blue) +{ + float max; + /*if ( red > green ) + max = red; + else + max = green; + if ( blue > max ) + max = blue;*/ + max = (red + green + blue); + if ( max == 0. ) + return(0); + if ( max > 0xff ) + { + red = (uint32_t)(((float)red / max) * 0xff); + green = (uint32_t)(((float)green / max) * 0xff); + blue = (uint32_t)(((float)blue / max) * 0xff); + } + + if ( red > 0xff ) + red = 0xff; + if ( green > 0xff ) + green = 0xff; + if ( blue > 0xff ) + blue = 0xff; + return((red << 16) | (green << 8) | blue); +} + +int32_t conv_yval_to_y(register float yval,register int32_t height) +{ + register int32_t y; + height = (height>>1) - 2; + y = (int32_t)-yval; + if ( y > height ) + y = height; + else if ( y < -height ) + y = -height; + + y += height; + if ( y < 0 ) + y = 0; + height <<= 1; + if ( y >= height-1 ) + y = height-1; + return(y); +} + +uint32_t scale_color(uint32_t color,float strength) +{ + int32_t red,green,blue; + if ( strength < 0. ) + strength = -strength; + red = (color>>16) & 0xff; + green = (color>>8) & 0xff; + blue = color & 0xff; + + red = (int32_t)((float)red * (strength/100.f)); + green = (int32_t)((float)green * (strength/100.f)); + blue = (int32_t)((float)blue * (strength/100.f)); + if ( red > 0xff ) + red = 0xff; + if ( green > 0xff ) + green = 0xff; + if ( blue > 0xff ) + blue = 0xff; + return((red<<16) | (green<<8) | blue); +} + +uint32_t pixel_blend(uint32_t pixel,uint32_t color)//,int32_t groupsize) +{ + int32_t red,green,blue,sum,n,n2,groupsize = 1; + float red2,green2,blue2,sum2; + if ( color == 0 ) + return(pixel); + if ( pixel == 0 ) + { + return((1<<24) | scale_color(color,100.f/(float)groupsize)); + } + n = (pixel>>24) & 0xff; + if ( n == 0 ) + n = 1; + pixel &= 0xffffff; + red = (pixel>>16) & 0xff; + green = (pixel>>8) & 0xff; + blue = pixel & 0xff; + sum = red + green + blue; + + n2 = (color>>24) & 0xff; + if ( n2 == 0 ) + n2 = 1; + red2 = ((float)((color>>16) & 0xff)) / groupsize; + green2 = ((float)((color>>8) & 0xff)) / groupsize; + blue2 = ((float)(color & 0xff)) / groupsize; + sum2 = (red2 + green2 + blue2); + + //printf("gs %d (%d x %d,%d,%d: %d) + (%d x %.1f,%.1f,%.1f: %.1f) = ",groupsize,n,red,green,blue,sum,n2,red2,green2,blue2,sum2); + red = (uint32_t)(((((((float)red / (float) sum) * n) + (((float)red2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + green = (uint32_t)(((((((float)green / (float) sum) * n) + (((float)green2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + blue = (uint32_t)(((((((float)blue / (float) sum) * n) + (((float)blue2 / (float) sum2) * n2)) / (n+n2)) * ((sum+sum2)/2))); + + n += n2; + if ( n > 0xff ) + n = 0xff; + ///printf("%x (%d,%d,%d) ",color,red,green,blue); + color = (n<<24) | pixel_ratios(red,green,blue);//pixel_overflow(&red,&green,&blue); + + //printf("%x (%d,%d,%d)\n",color,(color>>16)&0xff,(color>>8)&0xff,color&0xff); + return(color); +} + +void init_forex_colors(uint32_t *forex_colors) +{ + int32_t i; + forex_colors[0] = 0x00ff00; + forex_colors[1] = 0x0033ff; + forex_colors[2] = 0xff0000; + forex_colors[3] = 0x00ffff; + forex_colors[4] = 0xffff00; + forex_colors[5] = 0xff00ff; + forex_colors[6] = 0xffffff; + forex_colors[7] = 0xff8800; + forex_colors[8] = 0xff88ff; + for (i=9; i<16; i++) + forex_colors[i] = pixel_blend(forex_colors[i-8],0xffffff); +} + +int32_t is_primary_color(register uint32_t color) +{ + static uint32_t forex_colors[16]; + register int32_t i; + if ( forex_colors[0] == 0 ) + init_forex_colors(forex_colors); + for (i=0; i<8; i++) + if ( color == forex_colors[i] ) + return(1); + return(0); +} + +void disp_yval(register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + register int32_t y; + if ( forex_colors[0] == 0 ) + init_forex_colors(forex_colors); + x += LEFTMARGIN; + if ( x < 0 || x >= rowwidth ) + return; + //y = conv_yval_to_y(yval,height/Display_scale) * Display_scale; + y = conv_yval_to_y(yval * Display_scale,height); + if ( 1 && is_primary_color(color) != 0 ) + { + bitmap[y*rowwidth + x] = color; + //printf("(%d, %d) <- %x, ",x,y,color); + return; + } + //if ( pixelwt(color) > pixelwt(bitmap[y*rowwidth + x]) ) + bitmap[y*rowwidth + x] = pixel_blend(bitmap[y*rowwidth + x],color); + return; + //if ( is_primary_color(color) != 0 || (is_primary_color(bitmap[y*rowwidth+x]) == 0 && pixelwt(color) > pixelwt(bitmap[y*rowwidth + x])) ) + // bitmap[y*rowwidth + x] = color; +} + +void disp_yvalsum(register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + int32_t y,red,green,blue,dispcolor; + x += LEFTMARGIN; + if ( x < 0 || x >= rowwidth ) + return; + y = conv_yval_to_y(yval * Display_scale,height); + red = (color>>16) & 0xff; + green = (color>>8) & 0xff; + blue = color & 0xff; + dispcolor = bitmap[y*rowwidth + x]; + red += (dispcolor>>16) & 0xff; + green += (dispcolor>>8) & 0xff; + blue += dispcolor & 0xff; + bitmap[y*rowwidth + x] = pixel_ratios(red,green,blue); +} + +void disp_dot(register float radius,register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) +{ + register float i,j,sq,val; + if ( radius > 1 ) + { + sq = radius * radius; + for (i=-radius; i<=radius; i++) + { + for (j=-radius; j<=radius; j++) + { + val = ((j*j + i*i) / sq); + if ( val <= 1. ) + { + val = 1. - val; + disp_yval(scale_color(color,(100 * val * val * val * val)),yval+j,bitmap,x+i,rowwidth,height); + } + } + } + } + else disp_yval(color,yval,bitmap,x,rowwidth,height); +} + +void horizline(int32_t calclogflag,int32_t rowwidth,int32_t height,uint32_t *bitmap,double rawprice,double ave) +{ + int32_t x; + double yval; + if ( calclogflag != 0 ) + yval = _calc_pricey(log(rawprice),log(ave)); + else yval = _calc_pricey(rawprice,ave); + for (x=0; x %f) ",val,yval); + if ( fabs(yval) > .0000000001 ) + { + aveabs += fabs(yval); + nonz++; + if ( color != 0 ) + disp_yval(color,yval,bitmap,x,rowwidth,height); + } + } else yval = 0.; + output[x] = yval; + } + if ( nonz != 0 ) + aveabs /= nonz; + return(aveabs); + // + //printf("ave %f rowwidth.%d\n",ave,rowwidth); +} + +double stats_splineval(struct stats_spline *spline,uint32_t timestamp,int32_t lookahead) +{ + int32_t i,gap,ind = (spline->num - 1); + if ( timestamp >= spline->utc32[ind] ) + { + gap = (timestamp - spline->utc32[ind]); + if ( gap < lookahead ) + return(_extrapolate_spline64(spline->spline64[ind],gap)); + else return(0.); + } + else if ( timestamp <= spline->utc32[0] ) + { + gap = (spline->utc32[0] - timestamp); + if ( gap < lookahead ) + return(_extrapolate_spline64(spline->spline64[0],gap)); + else return(0.); + } + for (i=0; inum-1; i++) + { + ind = (i + spline->lasti) % (spline->num - 1); + if ( timestamp >= spline->utc32[ind] && timestamp < spline->utc32[ind+1] ) + { + spline->lasti = ind; + return(_extrapolate_spline64(spline->spline64[ind],timestamp - spline->utc32[ind])); + } + } + return(0.); +} + +double stats_calcspline(struct stats_spline *spline,double *outputs,double *slopes,int32_t dispwidth,uint32_t *utc32,double *splinevals,int32_t num) +{ + static double errsums[3]; static int errcount; + double c[MAX_SPLINES],f[MAX_SPLINES],dd[MAX_SPLINES],dl[MAX_SPLINES],du[MAX_SPLINES],gaps[MAX_SPLINES]; + int32_t n,i,lasti,x,numsplines,nonz; double vx,vy,vw,vz,gap,sum,xval,yval,abssum,lastval,lastxval,yval64,yval32,yval3; uint32_t gap32; + sum = lastxval = n = lasti = nonz = 0; + for (i=0; i 0 ) + { + if ( (gaps[n-1]= utc32[i] - lastxval) < 0 ) + { + printf("illegal gap %f to t%d\n",lastxval,utc32[i]); + return(0); + } + } + spline->utc32[n] = lastxval = utc32[i]; + n++; + } + } + if ( (numsplines= n) < 4 ) + return(0); + for (i=0; i=0; i--) + c[i] -= c[i+1] * du[i]; + //tridiagonal(n-2, dl, dd, du, c); + + for (i=n-3; i>=0; i--) + c[i+1] = c[i]; + c[0] = (1.0 + (double)gaps[0] / gaps[1]) * c[1] - ((double)gaps[0] / gaps[1] * c[2]); + c[n-1] = (1.0 + (double)gaps[n-2] / gaps[n-3] ) * c[n-2] - ((double)gaps[n-2] / gaps[n-3] * c[n-3]); + //printf("c[n-1] %f, n-2 %f, n-3 %f\n",c[n-1],c[n-2],c[n-3]); + abssum = nonz = lastval = 0; + outputs[spline->firstx] = f[0]; + spline->num = numsplines; + for (i=0; iutc32[i],(vx),vy*1000*1000,vz*1000*1000*1000*1000,vw*1000*1000*1000*1000*1000*1000,gap,conv_unixtime(&tmp,spline->utc32[i])); + spline->dSplines[i][0] = vx, spline->dSplines[i][1] = vy, spline->dSplines[i][2] = vz, spline->dSplines[i][3] = vw; + spline->spline64[i][0] = dto64(vx), spline->spline64[i][1] = dto64(vy*1000*1000), spline->spline64[i][2] = dto64(vz*1000*1000*1000*1000), spline->spline64[i][3] = dto64(vw*1000*1000*1000*1000*1000*1000); + spline->spline32[i][0] = dto32(vx), spline->spline32[i][1] = dto32(vy*1000*1000), spline->spline32[i][2] = dto32(vz*1000*1000*1000*1000), spline->spline32[i][3] = dto32(vw*1000*1000*1000*1000*1000*1000); + gap32 = gap = spline->dispincr; + xval = spline->utc32[i] + gap; + lastval = vx; + while ( i < n-1 ) + { + x = spline->firstx + ((xval - spline->utc32[0]) / spline->dispincr); + if ( x > dispwidth-1 ) x = dispwidth-1; + if ( x < 0 ) x = 0; + if ( (i < n-2 && gap > gaps[i] + spline->dispincr) ) + break; + if ( i == n-2 && xval > spline->utc32[n-1] + MAX_LOOKAHEAD*spline->dispincr ) + { + //printf("x.%d dispwidth.%d xval %f > utc[n-1] %f + %f\n",x,dispwidth,xval,utc[n-1],MAX_LOOKAHEAD*incr); + break; + } + if ( x >= 0 ) + { + yval = _extrapolate_Spline(spline->dSplines[i],gap); + yval64 = _extrapolate_spline64(spline->spline64[i],gap32); + if ( (yval3 = stats_splineval(spline,gap32 + spline->utc32[i],MAX_LOOKAHEAD*spline->dispincr)) != 0 ) + { + yval32 = _extrapolate_spline32(spline->spline32[i],gap32); + errsums[0] += fabs(yval - yval64), errsums[1] += fabs(yval - yval32), errsums[2] += fabs(yval - yval3), errcount++; + if ( fabs(yval - yval3) > SMALLVAL ) + printf("(%.10f vs %.10f %.10f %.10f [%.16f %.16f %.16f]) ",yval,yval64,yval32,yval3, errsums[0]/errcount,errsums[1]/errcount,errsums[2]/errcount); + } + if ( yval > 5000. ) yval = 5000.; + else if ( yval < -5000. ) yval = -5000.; + if ( isnan(yval) == 0 ) + { + outputs[x] = yval; + spline->lastval = outputs[x], spline->lastutc = xval; + if ( 1 && fabs(lastval) > SMALLVAL ) + { + if ( lastval != 0 && outputs[x] != 0 ) + { + if ( slopes != 0 ) + slopes[x] = (outputs[x] - lastval), abssum += fabs(slopes[x]); + nonz++; + } + } + } + //else outputs[x] = 0.; + //printf("x.%-4d %d %f %f %f i%-4d: gap %9.6f %9.6f last %9.6f slope %9.6f | %9.1f [%9.1f %9.6f %9.6f %9.6f %9.6f]\n",x,firstx,xval,utc[0],incr,i,gap,yval,lastval,slopes[x],xval,utc[i+1],dSplines[i][0],dSplines[i][1]*1000*1000,dSplines[i][2]*1000*1000*1000*1000,dSplines[i][3]*1000*1000*1000*1000*1000*1000); + } + gap32 += spline->dispincr, gap += spline->dispincr, xval += spline->dispincr; + } + //double pred = (i>0) ? _extrapolate_Spline(dSplines[i-1],gaps[i-1]) : 0.; + //printf("%2d: w%8.1f [gap %f -> %9.6f | %9.6f %9.6f %9.6f %9.6f %9.6f]\n",i,weekinds[i],gap,pred,f[i],dSplines[i].x,1000000*dSplines[i].y,1000000*1000000*dSplines[i].z,1000000*1000000*1000*dSplines[i].w); + } + if ( nonz != 0 ) + abssum /= nonz; + spline->aveslopeabs = abssum; + return(lastval); +} + +int32_t stats_genspline(double output[2048],double slopes[2048],struct stats_spline *spline,int32_t splineid,char *name,uint32_t *utc32,double *splinevals,int32_t numsplines,double *refvals) +{ + int32_t i; double origvals[MAX_SPLINES]; + if ( numsplines > MAX_SPLINES ) + { + printf("numsplines.%d > MAX_SPLINES.%d\n",numsplines,MAX_SPLINES); + return(-1); + } + memset(spline,0,sizeof(*spline)), memset(output,0,sizeof(*output)*2048), memset(slopes,0,sizeof(*slopes)*2048); + spline->dispincr = 3600, spline->basenum = splineid, strcpy(spline->name,name); + memcpy(origvals,splinevals,sizeof(*splinevals) * MAX_SPLINES); + spline->lastval = stats_calcspline(spline,output,slopes,2048,utc32,splinevals,numsplines); + if ( refvals != 0 ) + { + for (i=0; inum; i++) + { + if ( i < spline->num ) + { + if ( 0 && refvals[i] != 0 && output[i * 24] != refvals[i] ) + printf("{%.8f != %.8f}.%d ",output[i * 24],refvals[i],i); + spline->pricevals[i] = output[i * 24]; + } + } + } + //printf("spline.%s num.%d\n",name,spline->num); + return(spline->num); +} + +void output_line(int32_t calclogflag,double ave,double *buf,int32_t n,int32_t color,uint32_t *bitmap,int32_t rowwidth,int32_t height) +{ + double src[1024],dest[1024]; int32_t i; + memset(src,0,sizeof(src)); + memset(dest,0,sizeof(dest)); + if ( (1) ) + { + for (i=0; i<1024; i++) + src[1023-i] = dest[1023-i] = buf[i]; + smooth1024(dest,src,3); + for (i=0; i<1024; i++) + src[1023-i] = dest[i]; + } + else + { + for (i=0; i<1024; i++) + src[i] = buf[i]; + } + _output_line(calclogflag,ave,buf,src,1024,color,bitmap,rowwidth,height); +} + +void stats_updatedisp(struct DEXstats_disp *disp,double price,double volume) +{ + if ( price > SMALLVAL && volume > SMALLVAL ) + { + disp->pricesum += (price * volume); + disp->volumesum += volume; + } +} + +void stats_dispprices(struct DEXstats_disp *prices,int32_t leftdatenum,int32_t numdates,struct DEXstats_datenuminfo *date,char *dest,int32_t current_daysecond) +{ + int32_t i,j,offset,datenum = date->datenum; struct DEXstats_pairinfo *pair; struct DEXstats_pricepoint *ptr; uint32_t timestamp,lefttimestamp,righttimestamp; + offset = datenum - leftdatenum; + lefttimestamp = OS_conv_datenum(leftdatenum,0,0,0); + righttimestamp = OS_conv_datenum(leftdatenum+numdates,0,0,0); + //printf("search dest.%s datenum.%d vs leftdatenum.%d numdates.%d offset.%d numpairs.%d\n",dest,datenum,leftdatenum,numdates,offset,date->numpairs); + for (i=0; inumpairs; i++) + { + if ( strcmp(dest,date->pairs[i].dest) == 0 ) + { + pair = &date->pairs[i]; + //printf("found dest.(%s) numprices.%d\n",dest,pair->numprices); + for (j=0; jnumprices; j++) + { + ptr = &pair->prices[j]; + timestamp = OS_conv_datenum(date->datenum,ptr->hour,ptr->seconds/60,ptr->seconds%60); + timestamp += (24*3600 - current_daysecond); + offset = (timestamp - lefttimestamp) / (24*3600); + if ( offset >= 0 && offset < numdates ) + { + //printf("found dest.(%s) numprices.%d offset.%d (%.8f %.6f)\n",dest,pair->numprices,offset,ptr->price,ptr->volume); + stats_updatedisp(&prices[offset],ptr->price,ptr->volume); + } + } + break; + } + } +} + +#include "../../crypto777/jpeg/jinclude.h" +#include "../../crypto777/jpeg/jpeglib.h" +#include "../../crypto777/jpeg/jerror.h" + +void gen_jpegfile(char *fname,int32_t quality,uint8_t *bitmap,int32_t width,int32_t height) +{ + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE * outfile; /* target file */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + if ( (outfile= fopen(fname,"wb")) == NULL) + { + fprintf(stderr, "can't open %s\n", fname); + return; + } + jpeg_stdio_dest(&cinfo, outfile); + cinfo.image_width = width; /* image width and height, in pixels */ + cinfo.image_height = height; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); + jpeg_start_compress(&cinfo, TRUE); + row_stride = width * 3; /* JSAMPLEs per row in image_buffer */ + while (cinfo.next_scanline < cinfo.image_height) + { + row_pointer[0] = &bitmap[cinfo.next_scanline * row_stride]; + (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + jpeg_finish_compress(&cinfo); + fclose(outfile); + jpeg_destroy_compress(&cinfo); +} + +char *stats_prices(char *symbol,char *dest,struct DEXstats_disp *prices,int32_t leftdatenum,int32_t numdates) +{ + int32_t i,j,n; struct DEXstats_priceinfo *pp; uint32_t *utc32,tmp,timestamp,lefttimestamp,righttimestamp; double *splinevals,total; char fname[1024]; cJSON *retjson,*array,*item; + timestamp = (uint32_t)time(NULL); + if ( Num_priceinfos >= sizeof(Prices)/sizeof(*Prices) ) + return(0); + lefttimestamp = OS_conv_datenum(leftdatenum-1,0,0,0); + righttimestamp = OS_conv_datenum(leftdatenum+numdates,0,0,0); + for (i=0; inumdates; j++) + { + timestamp = OS_conv_datenum(pp->firstdatenum+j,0,0,0); + if ( timestamp < lefttimestamp ) // can speed up by calculating offset 0 + { + //printf("skip (%s) datenums %d %d %d\n",symbol,datenum,pp->firstdatenum,pp->firstdatenum+pp->numdates); + continue; + } + stats_dispprices(prices,leftdatenum,numdates,&pp->dates[j],dest,timestamp % (3600*24)); + } + break; + } + tmp = OS_conv_datenum(leftdatenum,0,0,0); + utc32 = calloc(sizeof(*utc32),numdates); + splinevals = calloc(sizeof(*splinevals),numdates); + for (total=i=n=0; i 3 ) + { + double output[2048],slopes[2048],sum = 0.; struct stats_spline spline; int32_t splineid = 0; + memset(&spline,0,sizeof(spline)); + stats_genspline(output,slopes,&spline,splineid,"spline",utc32,splinevals,n,0); + array = cJSON_CreateArray(); + for (i=0; i> 8) & 0xff; + blue = (val >> 16) & 0xff; + *tmpptr++ = red; + *tmpptr++ = green; + *tmpptr++ = blue; + } + sprintf(fname,"%s/bitmaps/%s_%s.jpg",STATS_DESTDIR,symbol,dest), OS_portable_path(fname); + gen_jpegfile(fname,100,bytemap,numdates*24,height); + free(bitmap), free(bytemap); + jaddstr(retjson,"bitmap",fname); + jadd(retjson,"hourly",array); + jaddnum(retjson,"average",sum); + } + free(utc32); + free(splinevals); + return(jprint(retjson,1)); +} + +#ifndef FROM_MARKETMAKER +#ifndef FROM_PRIVATEBET +char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port) +{ + char *method,*agent,*retstr,*source,*dest; struct tai T; uint32_t endtimestamp; struct DEXstats_disp prices[365]; int32_t leftdatenum,seconds,numdates; + if ( (method= jstr(argjson,"method")) == 0 ) + return(clonestr("{\"error\":\"need method in request\"}")); + if ( (agent= jstr(argjson,"agent")) == 0 ) + agent = "stats"; + if ( strcmp(method,"bitmap") == 0 ) + { + if ( (endtimestamp= juint(argjson,"endtimestamp")) == 0 ) + endtimestamp = (uint32_t)time(NULL); + if ( (source= jstr(argjson,"source")) == 0 ) + source = "KMD"; + if ( (dest= jstr(argjson,"dest")) == 0 ) + dest = "USD"; + if ( (numdates= jint(argjson,"numdates")) <= 0 || numdates > 1024/24 ) + numdates = 1024/24; + leftdatenum = OS_conv_unixtime(&T,&seconds,endtimestamp - numdates*24*3600); + printf("(%s/%s) endtimestamp.%u: leftdatenum.%d\n",source,dest,endtimestamp,leftdatenum); + memset(prices,0,sizeof(prices)); + if ( (retstr= stats_prices(source,dest,prices,leftdatenum,numdates+1)) != 0 ) + return(retstr); + } + return(clonestr(jprint(argjson,0))); +} +#endif +#endif + +#endif /* DEXstats_h */ diff --git a/iguana/exchanges/LP_NXT.c b/iguana/exchanges/LP_NXT.c new file mode 100644 index 000000000..88626ec0f --- /dev/null +++ b/iguana/exchanges/LP_NXT.c @@ -0,0 +1,343 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_NXT.c +// marketmaker +// + + +char *NXTnodes[] = { "62.75.159.113", "91.44.203.238", "82.114.88.225", "78.63.207.76", "188.174.110.224", "91.235.72.49", "213.144.130.91", "209.222.98.250", "216.155.128.10", "178.33.203.157", "162.243.122.251", "69.163.47.173", "193.151.106.129", "78.94.2.74", "192.3.196.10", "173.33.112.87", "104.198.173.28", "35.184.154.126", "174.140.167.239", "23.88.113.131", "198.71.84.173", "178.150.207.53", "23.88.61.53", "192.157.233.106", "192.157.241.212", "23.89.192.88", "23.89.200.27", "192.157.241.139", "23.89.200.63", "23.89.192.98", "163.172.214.102", "176.9.85.5", "80.150.243.88", "80.150.243.92", "80.150.243.98", "109.70.186.198", "146.148.84.237", "104.155.56.82", "104.197.157.140", "37.48.73.249", "146.148.77.226", "84.57.170.200", "107.161.145.131", "80.150.243.97", "80.150.243.93", "80.150.243.100", "80.150.243.95", "80.150.243.91", "80.150.243.99", "80.150.243.96", "93.231.187.177", "212.237.23.85", "35.158.179.254", "46.36.66.41", "185.170.113.79", "163.172.68.112", "78.47.35.210", "77.90.90.75", "94.177.196.134", "212.237.22.215", "94.177.234.11", "167.160.180.199", "54.68.189.9", "94.159.62.14", "195.181.221.89", "185.33.145.94", "195.181.209.245", "195.181.221.38", "195.181.221.162", "185.33.145.12", "185.33.145.176", "178.79.128.235", "94.177.214.120", "94.177.199.41", "94.177.214.200", "94.177.213.201", "212.237.13.162", "195.181.221.236", "195.181.221.185", "185.28.103.187", "185.33.146.244", "217.61.123.71", "195.181.214.45", "195.181.212.99", "195.181.214.46", "195.181.214.215", "195.181.214.68", "217.61.123.118", "195.181.214.79", "217.61.123.14", "217.61.124.100", "195.181.214.111", "85.255.0.176", "81.2.254.116", "217.61.123.184", "195.181.212.231", "94.177.214.110", "195.181.209.164", "104.129.56.238", "85.255.13.64", "167.160.180.206", "217.61.123.226", "167.160.180.208", "93.186.253.127", "212.237.6.208", "94.177.207.190", "217.61.123.119", "85.255.1.245", "217.61.124.157", "37.59.57.141", "167.160.180.58", "104.223.53.14", "217.61.124.69", "195.181.212.103", "85.255.13.141", "104.207.133.204", "71.90.7.107", "107.150.18.108", "23.94.134.161", "80.150.243.13", "80.150.243.11", "185.81.165.52", "80.150.243.8" }; + +static char *assetids[][4] = +{ + { "13502152099823770958", "SUPERNETx2", "10000", "10000" }, + { "12071612744977229797", "SUPERNET", "10000", "10000" }, + { "12071612744977229797", "UNITY", "10000", "10000" }, + { "15344649963748848799", "DEX", "1", "100000000" }, + { "6883271355794806507", "PANGEA", "10000", "10000" }, + { "17911762572811467637", "JUMBLR", "10000", "10000" }, + { "17083334802666450484", "BET", "10000", "10000" }, + { "13476425053110940554", "CRYPTO", "1000", "100000" }, + { "6932037131189568014", "HODL", "1", "100000000" }, + //{ "3006420581923704757", "SHARK", "10000", "10000" }, + { "3006420581923704757", "MSHARK", "10", "10000000" }, + { "17571711292785902558", "BOTS", "1", "100000000" }, + { "10524562908394749924", "MGW", "1", "100000000" }, + { "8217222248380501882", "MESH", "10000", "10000" }, + { "15641806960898178066", "TOKEN", "1", "100000000" }, +}; + +void LP_sendtoaddress_line(char *validaddress,char *assetname,uint64_t satoshis,uint64_t txnum) +{ + char line[1024],lowerstr[64]; + if ( strcmp(assetname,"SUPERNETx2") == 0 ) + { + sprintf(line,"fiat/supernet sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum); + printf("%s\n",line); + sprintf(line,"fiat/revs sendtoaddress %s %.8f # txnum.%llu",validaddress,dstr(satoshis),(long long)txnum); + } + else + { + if ( strcmp(assetname,"TOKEN") == 0 ) + strcpy(lowerstr,"supernet"); + else strcpy(lowerstr,assetname); + tolowercase(lowerstr); + sprintf(line,"sleep 1; fiat/%s sendtoaddress %s %.8f # txnum.%llu",lowerstr,validaddress,dstr(satoshis),(long long)txnum); + } + printf("%s\n",line); +} + +uint64_t LP_assetid_mult(int32_t *assetindp,char *name,uint64_t assetid) +{ + int32_t i; uint64_t mult = 0; + name[0] = 0; + *assetindp = -1; + for (i=0; i= 1 ) + { + if ( strcmp(account,"NXT-XRK4-5HYK-5965-9FH4Z") != 0 ) + { + sum += (long long)(qtyA * ratio); + sprintf(url,"requestType=transferAsset&secretPhrase=%s&recipient=%s&asset=%llu&quantityQNT=%llu&feeNQT=100000000&deadline=60",passphrase,account,(long long)assetid,(long long)(qtyA * ratio)); + if ( (retstr2= curl_post(&cHandle,"http://127.0.0.1:7876/nxt","",url,"","","","")) != 0 ) + { + if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) + { + txid = j64bits(retjson2,"transaction"); + printf("%s %.6f %8llu QNT %s -> %llu %.8f txid %llu\n",account,ratio,(long long)qtyA,assetids[j][2],(long long)(qtyA * ratio),((double)(long long)(qtyA * ratio))/decimals,(long long)txid); + free_json(retjson2); + } + free(retstr2); + } + usleep(250000); + } + } + } + printf("%s distribution total %llu QNT %.8f\n",assetids[j][2],(long long)sum,(double)sum/decimals); + } + } + free_json(retjson); + } + printf("NXTventure assethodlers.%d\n",n); + free(retstr); + } +} + +cJSON *LP_NXT_redeems() +{ + char url[1024],*retstr,*recv,*method,*msgstr,assetname[128]; uint64_t totals[2][sizeof(assetids)/sizeof(*assetids)],mult,txnum,assetid,qty; int32_t i,ind,numtx=0,past_marker=0; cJSON *item,*attach,*decjson,*array,*msgjson,*encjson,*retjson=0; + uint64_t txnum_marker = calc_nxt64bits("4114304329372848717"); // 8537615468620726612"); // set to most recent processed + uint64_t txnum_marker2 = calc_nxt64bits("7256847492742571143"); // dont change, end marker + char *passphrase = ""; + char *account = "NXT-MRBN-8DFH-PFMK-A4DBM"; + memset(totals,0,sizeof(totals)); + sprintf(url,"http://127.0.0.1:7876/nxt?requestType=getBlockchainTransactions&account=%s",account); + //printf("calling (%s)\n",url); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + //printf("got.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (array= jarray(&numtx,retjson,"transactions")) != 0 ) + { + for (i=0; i= 0 ) + totals[past_marker][ind] += qty * mult; + if ( msgstr != 0 && assetname[0] != 0 && qty != 0 ) + { + char validaddress[64]; int32_t z,n; + n = (int32_t)strlen(msgstr); + for (z=0; z= 34 ) + strncpy(validaddress,&msgstr[z],34); + if ( txnum == calc_nxt64bits("4545341872872347590") ) + strcpy(validaddress,"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni"); + if ( past_marker == 0 ) + { + if ( strlen(validaddress) == 34 || strlen(validaddress) == 33 ) + { + //printf("%-4d: (%34s) <- %13.5f %10s tx.%llu past_marker.%d\n",i,validaddress,dstr(qty * mult),assetname,(long long)txnum,past_marker); + LP_sendtoaddress_line(validaddress,assetname,(qty * mult),txnum); + } else printf("%-4d: (%34s) <- %13.5f %10s tx.%llu\n",i,msgstr!=0?msgstr:jprint(item,0),dstr(qty * mult),assetname,(long long)txnum); + } + } + if ( msgjson != 0 ) + free_json(msgjson); + if ( decjson != 0 ) + free_json(decjson); + } + if ( txnum == txnum_marker2 ) + break; + } + } + //free_json(retjson); + } + free(retstr); + } else printf("null return from NXT api call\n"); + printf("\nTotal redeemed.%d\n",numtx); + for (past_marker=0; past_marker<2; past_marker++) + { + for (i=0; i>>>>>>>>> already processed:\n"); + } + return(retjson); +} + +cJSON *LP_assethbla(char *assetid) +{ + char url[1024],*retstr; int32_t n; cJSON *array,*bid=0,*ask=0,*retjson; + sprintf(url,"http://%s:7876/nxt?requestType=getBidOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[LP_rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + bid = cJSON_Parse(retstr); + free(retstr); + } + sprintf(url,"http://%s:7876/nxt?requestType=getAskOrders&asset=%s&firstIndex=0&lastIndex=0",NXTnodes[LP_rand() % (sizeof(NXTnodes)/sizeof(*NXTnodes))],assetid); + if ( (retstr= issue_curlt(url,LP_HTTP_TIMEOUT)) != 0 ) + { + ask = cJSON_Parse(retstr); + free(retstr); + } + retjson = cJSON_CreateObject(); + if ( bid != 0 && ask != 0 ) + { + if ( (array= jarray(&n,bid,"bidOrders")) != 0 ) + jadd(retjson,"bid",jduplicate(jitem(array,0))); + if ( (array= jarray(&n,ask,"askOrders")) != 0 ) + jadd(retjson,"ask",jduplicate(jitem(array,0))); + } + if ( bid != 0 ) + free_json(bid); + if ( ask != 0 ) + free_json(ask); + return(retjson); +} + diff --git a/iguana/exchanges/LP_RTmetrics.c b/iguana/exchanges/LP_RTmetrics.c new file mode 100644 index 000000000..3d37c8a2e --- /dev/null +++ b/iguana/exchanges/LP_RTmetrics.c @@ -0,0 +1,305 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_RTmetrics.c +// marketmaker +// + +struct LP_metricinfo +{ + double metric; + double price,balance,minvol; + bits256 pubkey; + double maxvol; + int32_t ind,numutxos,age,pendingswaps; +}; + +#define LP_NUMRT 1024 +struct LP_RTmetrics_pendings +{ + char refbase[128],refrel[128]; + int64_t pending_kmdvalue[LP_NUMRT]; + int32_t numswaps,numavoidtxids,numwhitelist,numblacklist,numpendings,pending_swaps[LP_NUMRT]; + bits256 avoidtxids[8192],whitelist[LP_NUMRT],blacklist[LP_NUMRT],pending_pubkeys[LP_NUMRT]; +} LP_RTmetrics; + +int32_t LP_bits256_find(bits256 *list,int32_t num,bits256 val) +{ + int32_t i; + if ( bits256_nonz(val) != 0 ) + { + for (i=0; i= 0 ) + { + LP_RTmetrics.pending_swaps[ind]++; + LP_RTmetrics.pending_kmdvalue[ind] += kmdvalue; + } + return(ind); +} + +int32_t LP_RTmetrics_pendingswaps(bits256 pubkey) +{ + int32_t ind; + if ( (ind= LP_bits256_find(LP_RTmetrics.pending_pubkeys,LP_RTmetrics.numpendings,pubkey)) >= 0 ) + return(LP_RTmetrics.pending_swaps[ind]); + else return(0); +} + +int32_t LP_RTmetrics_avoidtxid(bits256 txid) +{ + return(LP_bits256_find(LP_RTmetrics.avoidtxids,LP_RTmetrics.numavoidtxids,txid)); +} + +int32_t LP_RTmetrics_whitelisted(bits256 pubkey) +{ + return(LP_bits256_find(LP_RTmetrics.whitelist,LP_RTmetrics.numwhitelist,pubkey)); +} + +int32_t LP_RTmetrics_blacklisted(bits256 pubkey) +{ + return(LP_bits256_find(LP_RTmetrics.blacklist,LP_RTmetrics.numblacklist,pubkey)); +} + +void LP_RTmetrics_swapsinfo(char *refbase,char *refrel,cJSON *swaps,int32_t numswaps) +{ + int32_t i; char *base,*rel,*retstr; cJSON *item,*swapjson; bits256 srcpub,destpub; uint64_t aliceid,basesatoshis,relsatoshis; uint32_t requestid,quoteid; double price; + for (i=0; iistrusted > 0 ) + LP_RTmetrics_whitelistadd(pubp->pubkey); + else if ( pubp->istrusted < 0 ) + LP_RTmetrics_blacklistadd(pubp->pubkey); + pubp->swaps_kmdvalue = 0; + } + futuretime = (uint32_t)time(NULL) + 3600*100; + memset(zero.bytes,0,sizeof(zero)); + if ( (statsjson= LP_statslog_disp(futuretime,futuretime,"",zero,0,0)) != 0 ) + { + if ( (swaps= jarray(&numswaps,statsjson,"swaps")) != 0 ) + { + //printf("LP_RTmetrics_update for (%s)\n",jprint(swaps,0)); + if ( numswaps > 0 ) + LP_RTmetrics_swapsinfo("","",swaps,numswaps); + } + free_json(statsjson); + } + for (i=0; i LP_MAXPENDING_SWAPS ) + { + char str[65]; printf("%s has %d pending swaps! which is more than %d\n",bits256_str(str,pubkey),LP_RTmetrics.pending_swaps[i],LP_MAXPENDING_SWAPS); + LP_RTmetrics_blacklistadd(pubkey); + } + else if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) + { + char str[65]; printf("%s has %d pending swaps %.8f kmdvalue\n",bits256_str(str,pubkey),LP_RTmetrics.pending_swaps[i],dstr(LP_RTmetrics.pending_kmdvalue[i])); + pubp->swaps_kmdvalue = LP_RTmetrics.pending_kmdvalue[i]; + } + } + //printf("%d pubkeys have pending swaps, whitelist.%d blacklist.%d avoidtxids.%d\n",LP_RTmetrics.numpendings,LP_RTmetrics.numwhitelist,LP_RTmetrics.numblacklist,LP_RTmetrics.numavoidtxids); +}*/ + + + +double _LP_RTmetric_calc(struct LP_metricinfo *mp,double bestprice,double maxprice,double relvolume) +{ + int32_t n; double metric,origmetric = (mp->price / bestprice); + metric = origmetric; + if ( mp->numutxos == 0 || relvolume == 0. || mp->maxvol == 0. || mp->balance == 0. ) + { + //printf("skip i.%d as no info\n",mp->ind); + return(metric * 100.); + } + if ( relvolume < mp->minvol ) + { + metric *= (mp->minvol / relvolume); + //printf("relvolume < minvol %.8f\n",(mp->minvol / relvolume)); + } + else if ( relvolume > mp->maxvol ) + { + metric *= (relvolume / mp->maxvol); + //printf("relvolume > minvol %.8f\n",(relvolume / mp->maxvol)); + } + if ( relvolume < mp->balance/LP_MINVOL ) + { + metric *= (mp->balance / relvolume); + //printf("relvolume < balance %.8f\n",(mp->balance / relvolume)); + } + else if ( relvolume > mp->balance/mp->numutxos ) + { + metric *= (relvolume / (mp->balance/mp->numutxos)); + //printf("relvolume < ave %.8f\n",(relvolume / (mp->balance/mp->numutxos))); + } + if ( mp->age > LP_ORDERBOOK_DURATION*0.8 ) + metric *= 2; + else if ( mp->age > 60 ) + metric *= 1.03; + if ( (n= mp->pendingswaps) > 0 ) + while ( n-- > 0 ) + metric *= 1.1; + //if ( metric != origmetric ) + printf("i.%d price %.8f orig %.8f -> %.8f relvol %.8f min %.8f max %.8f bal %.8f age.%d pend.%d\n",mp->ind,mp->price,origmetric,metric,relvolume,mp->minvol,mp->maxvol,mp->balance,mp->age,mp->pendingswaps); + return(metric); +} + +void LP_RTmetric_calc(struct LP_metricinfo *sortbuf,int32_t ind,cJSON *item,double bestprice,double maxprice,double relvolume,double prevdepth) +{ + sortbuf[ind].pubkey = jbits256(item,"pubkey"); + sortbuf[ind].price = jdouble(item,"price"); + sortbuf[ind].maxvol = jdouble(item,"maxvolume"); + sortbuf[ind].minvol = jdouble(item,"minvolume"); + sortbuf[ind].balance = jdouble(item,"depth") - prevdepth; + sortbuf[ind].numutxos = juint(item,"numutxos"); + sortbuf[ind].age = juint(item,"age"); + sortbuf[ind].ind = ind; + sortbuf[ind].pendingswaps = LP_RTmetrics_pendingswaps(sortbuf[ind].pubkey); + sortbuf[ind].metric = _LP_RTmetric_calc(&sortbuf[ind],bestprice,maxprice,relvolume); +} + +int _increasing_metrics(const void *a,const void *b) +{ +#define ptr_a ((struct LP_metricinfo *)a) +#define ptr_b ((struct LP_metricinfo *)b) + if ( ptr_b->metric > ptr_a->metric ) + return(-1); + else if ( ptr_b->metric < ptr_a->metric ) + return(1); + return(0); +#undef ptr_a +#undef ptr_b +} + +cJSON *LP_RTmetrics_sort(char *base,char *rel,cJSON *rawasks,int32_t numasks,double maxprice,double relvolume) +{ + cJSON *array=rawasks,*item; int32_t i,num,groupi; double price,prevdepth,bestprice; struct LP_metricinfo *sortbuf; + groupi = -1; + bestprice = 0.; + for (num=i=0; i maxprice ) + break; + if ( i == 0 ) + bestprice = price; + else if ( price < bestprice*LP_RTMETRICS_TOPGROUP ) + groupi = i; + num++; + } + if ( groupi > 0 ) + { + sortbuf = calloc(groupi+1,sizeof(*sortbuf)); + prevdepth = 0.; + for (i=0; i<=groupi; i++) + { + item = jitem(rawasks,i); + LP_RTmetric_calc(sortbuf,i,item,bestprice,maxprice,relvolume,prevdepth); + prevdepth = jdouble(item,"depth"); + //printf("%.8f ",sortbuf[i].metric); + } + qsort(&sortbuf[0].metric,groupi+1,sizeof(*sortbuf),_increasing_metrics); + array = cJSON_CreateArray(); + for (i=0; i<=groupi; i++) + { + printf("(%d <- %d %.3f) ",i,sortbuf[i].ind,sortbuf[i].metric); + item = jitem(rawasks,sortbuf[i].ind); + jaddi(array,jduplicate(item)); + } + for (; i=0; i--) + { + x <<= 8; + x |= serialized[i]; + } + switch ( len ) + { + case 1: *(uint8_t *)endianedp = (uint8_t)x; break; + case 2: *(uint16_t *)endianedp = (uint16_t)x; break; + case 4: *(uint32_t *)endianedp = (uint32_t)x; break; + case 8: *(uint64_t *)endianedp = (uint64_t)x; break; + } + } + else + { + x = 0; + switch ( len ) + { + case 1: x = *(uint8_t *)endianedp; break; + case 2: x = *(uint16_t *)endianedp; break; + case 4: x = *(uint32_t *)endianedp; break; + case 8: x = *(uint64_t *)endianedp; break; + } + for (i=0; i>= 8) + serialized[i] = (uint8_t)(x & 0xff); + } + return(len); +} + +int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp) +{ + int32_t i; + if ( rwflag == 0 ) + { + for (i=0; i> 8) & 0xff; + } + return(serialized); +} + +uint8_t *iguana_varint32(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p) +{ + serialized = iguana_varint16(rwflag,serialized,varint16p); + serialized = iguana_varint16(rwflag,serialized,&varint16p[1]); + return(serialized); +} + +uint8_t *iguana_varint64(int32_t rwflag,uint8_t *serialized,uint32_t *varint32p) +{ + serialized = iguana_varint32(rwflag,serialized,(uint16_t *)varint32p); + serialized = iguana_varint32(rwflag,serialized,(uint16_t *)&varint32p[1]); + return(serialized); +} + +int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p) +{ + uint64_t n; int32_t vlen = 1; + if ( rwflag == 0 ) + { + *varint64p = 0; + if ( (n= *serialized++) >= 0xfd ) + { + if ( n == 0xfd ) + { + n = 0; + iguana_varint16(rwflag,serialized,(uint16_t *)&n); + vlen += 2; + } + else if ( n == 0xfe ) + { + n = 0; + iguana_varint32(rwflag,serialized,(uint16_t *)&n); + vlen += 4; + } + else if ( n == 0xff ) + { + n = 0; + iguana_varint64(rwflag,serialized,(uint32_t *)&n); + vlen += 8; + } + } + *varint64p = n; + } + else + { + n = *varint64p; + if ( n < 0xfd ) + *serialized++ = (uint8_t)n; + else if ( n <= 0xffff ) + { + *serialized++ = 0xfd; + iguana_varint16(rwflag,serialized,(uint16_t *)varint64p); + vlen += 2; + } + else if ( n <= 0xffffffff ) + { + *serialized++ = 0xfe; + iguana_varint32(rwflag,serialized,(uint16_t *)varint64p); + vlen += 4; + } + else + { + *serialized++ = 0xff; + iguana_varint64(rwflag,serialized,(uint32_t *)varint64p); + vlen += 8; + } + } + return(vlen); +} + +int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p) +{ + int32_t len; uint64_t x = 0; + if ( rwflag != 0 ) + x = *int32p; + len = iguana_rwvarint(rwflag,serialized,&x); + if ( rwflag == 0 ) + *int32p = (int32_t)x; + return(len); +} + +int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp) +{ + int32_t vlen; uint64_t n; + if ( rwflag == 0 ) + { + vlen = iguana_rwvarint(rwflag,serialized,&n); + memcpy(endianedp,&serialized[vlen],n); + ((uint8_t *)endianedp)[n] = 0; + } + else + { + n = strlen(endianedp); + if ( n > maxlen ) + n = maxlen; + vlen = iguana_rwvarint(rwflag,serialized,&n); + memcpy(&serialized[vlen],endianedp,n); + } + return((int32_t)(n + vlen)); +} + +int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp) +{ + if ( rwflag == 0 ) + memcpy(endianedp,serialized,len); + else memcpy(serialized,endianedp,len); + return(len); +} + +const char *get_opname(uint8_t *stackitemsp,uint8_t *flagsp,int32_t *extralenp,enum opcodetype opcode) +{ + *extralenp = 0; + switch ( opcode ) + { + // push value + case OP_0 : return "0"; + case OP_PUSHDATA1 : *extralenp = 1; return "OP_PUSHDATA1"; + case OP_PUSHDATA2 : *extralenp = 2; return "OP_PUSHDATA2"; + case OP_PUSHDATA4 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_PUSHDATA4"; + case OP_1NEGATE : return "-1"; + case OP_RESERVED : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED"; + case OP_1 : return "1"; + case OP_2 : return "2"; + case OP_3 : return "3"; + case OP_4 : return "4"; + case OP_5 : return "5"; + case OP_6 : return "6"; + case OP_7 : return "7"; + case OP_8 : return "8"; + case OP_9 : return "9"; + case OP_10 : return "10"; + case OP_11 : return "11"; + case OP_12 : return "12"; + case OP_13 : return "13"; + case OP_14 : return "14"; + case OP_15 : return "15"; + case OP_16 : return "16"; + + // control + case OP_NOP : *flagsp = IGUANA_NOPFLAG; return "OP_NOP"; + case OP_VER : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_VER"; + case OP_IF : *flagsp = IGUANA_CONTROLFLAG; *stackitemsp = 1; return "OP_IF"; + case OP_NOTIF : *flagsp = IGUANA_CONTROLFLAG; *stackitemsp = 1; return "OP_NOTIF"; + case OP_VERIF : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_VERIF"; + case OP_VERNOTIF : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_VERNOTIF"; + case OP_ELSE : *flagsp = IGUANA_CONTROLFLAG; return "OP_ELSE"; + case OP_ENDIF : *flagsp = IGUANA_CONTROLFLAG; return "OP_ENDIF"; + case OP_VERIFY : *flagsp = IGUANA_POSTVERIFY; return "OP_VERIFY"; + case OP_RETURN : *flagsp = IGUANA_CONTROLFLAG; return "OP_RETURN"; + + // stack ops + case OP_TOALTSTACK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_TOALTSTACK"; + case OP_FROMALTSTACK : *flagsp = IGUANA_STACKFLAG; return "OP_FROMALTSTACK"; + case OP_2DROP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_2DROP"; + case OP_2DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_2DUP"; + case OP_3DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 3; return "OP_3DUP"; + case OP_2OVER : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 4; return "OP_2OVER"; + case OP_2ROT : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 6; return "OP_2ROT"; + case OP_2SWAP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 4; return "OP_2SWAP"; + case OP_IFDUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_IFDUP"; + case OP_DEPTH : *flagsp = IGUANA_STACKFLAG; return "OP_DEPTH"; + case OP_DROP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_DROP"; + case OP_DUP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_DUP"; + case OP_NIP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_NIP"; + case OP_OVER : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_OVER"; + case OP_PICK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_PICK"; + case OP_ROLL : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 1; return "OP_ROLL"; + case OP_ROT : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 3; return "OP_ROT"; + case OP_SWAP : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_SWAP"; + case OP_TUCK : *flagsp = IGUANA_STACKFLAG; *stackitemsp = 2; return "OP_TUCK"; + + // splice ops + case OP_CAT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_CAT"; + case OP_SUBSTR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_SUBSTR"; + case OP_LEFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_LEFT"; + case OP_RIGHT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_RIGHT"; + case OP_SIZE : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_SIZE"; + + // bit logic + case OP_INVERT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_INVERT"; + case OP_AND : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_AND"; + case OP_OR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_OR"; + case OP_XOR : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_XOR"; + case OP_EQUAL : *stackitemsp = 2; return "OP_EQUAL"; + case OP_EQUALVERIFY : *stackitemsp = 2; *flagsp = IGUANA_POSTVERIFY; return "OP_EQUALVERIFY"; + case OP_RESERVED1 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED1"; + case OP_RESERVED2 : *flagsp = IGUANA_EXECUTIONILLEGAL; return "OP_RESERVED2"; + + // numeric + case OP_1ADD : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_1ADD"; + case OP_1SUB : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_1SUB"; + case OP_2MUL : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_2MUL"; + case OP_2DIV : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_2DIV"; + case OP_NEGATE : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_NEGATE"; + case OP_ABS : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_ABS"; + case OP_NOT : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_NOT"; + case OP_0NOTEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 1; return "OP_0NOTEQUAL"; + case OP_ADD : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_ADD"; + case OP_SUB : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_SUB"; + case OP_MUL : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_MUL"; + case OP_DIV : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_DIV"; + case OP_MOD : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_MOD"; + case OP_LSHIFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_LSHIFT"; + case OP_RSHIFT : *flagsp = IGUANA_ALWAYSILLEGAL; return "OP_RSHIFT"; + case OP_BOOLAND : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_BOOLAND"; + case OP_BOOLOR : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_BOOLOR"; + case OP_NUMEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_NUMEQUAL"; + case OP_NUMEQUALVERIFY: *flagsp = IGUANA_MATHFLAG | IGUANA_POSTVERIFY; *stackitemsp = 2; return "OP_NUMEQUALVERIFY"; + case OP_NUMNOTEQUAL : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_NUMNOTEQUAL"; + case OP_LESSTHAN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_LESSTHAN"; + case OP_GREATERTHAN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_GREATERTHAN"; + case OP_LESSTHANOREQUAL: *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_LESSTHANOREQUAL"; + case OP_GREATERTHANOREQUAL: *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_GREATERTHANOREQUAL"; + case OP_MIN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_MIN"; + case OP_MAX : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 2; return "OP_MAX"; + case OP_WITHIN : *flagsp = IGUANA_MATHFLAG; *stackitemsp = 3; return "OP_WITHIN"; + + // crypto + case OP_RIPEMD160 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_RIPEMD160"; + case OP_SHA1 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_SHA1"; + case OP_SHA256 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_SHA256"; + case OP_HASH160 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_HASH160"; + case OP_HASH256 : *stackitemsp = 1; *flagsp = IGUANA_CRYPTOFLAG; return "OP_HASH256"; + case OP_CODESEPARATOR: return "OP_CODESEPARATOR"; + case OP_CHECKSIG : *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKSIG"; + case OP_CHECKSIGVERIFY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKSIGVERIFY"; + case OP_CHECKMULTISIG: *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKMULTISIG"; + case OP_CHECKMULTISIGVERIFY: *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKMULTISIGVERIFY"; + case OP_COMBINEPUBKEYS: *flagsp = IGUANA_CRYPTOFLAG; return "OP_COMBINEPUBKEYS"; + case OP_CHECKSCHNORR: *stackitemsp = 3; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKSCHNORR"; + case OP_CHECKSCHNORRVERIFY: *stackitemsp = 3; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKSCHNORRVERIFY"; + case OP_CHECKPRIVATEKEY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKPRIVATEKEY"; + case OP_CHECKPRIVATEKEYVERIFY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKPRIVATEKEYVERIFY"; + + // expanson + case OP_NOP1 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP1"; + case OP_CHECKLOCKTIMEVERIFY: *stackitemsp = 1; return "OP_CHECKLOCKTIMEVERIFY"; + case OP_CHECKSEQUENCEVERIFY: *stackitemsp = 1; return "OP_CHECKSEQUENCEVERIFY"; + case OP_NOP4 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP4"; + case OP_NOP5 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP5"; + case OP_NOP6 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP6"; + case OP_NOP7 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP7"; + case OP_NOP8 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP8"; + case OP_NOP9 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP9"; + case OP_NOP10 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP10"; + + case OP_INVALIDOPCODE: return "OP_INVALIDOPCODE"; + default: return "OP_UNKNOWN"; + } +} + +void iguana_optableinit() +{ + int32_t i,extralen; uint8_t stackitems,flags; char *opname; struct bitcoin_opcode *op; + if ( OPTABLE == 0 ) + { + for (i=0; i<0x100; i++) + OPCODES[i] = "OP_UNKNOWN"; + for (i=0; i<0x100; i++) + { + extralen = stackitems = flags = 0; + opname = (char *)get_opname(&stackitems,&flags,&extralen,i); + if ( strcmp("OP_UNKNOWN",opname) != 0 ) + { + op = calloc(1,sizeof(*op)); + HASH_ADD_KEYPTR(hh,OPTABLE,opname,strlen(opname),op); + //printf("{%-16s %02x} ",opname,i); + op->opcode = i; + op->flags = flags; + op->stackitems = stackitems; + op->extralen = extralen; + OPCODES[i] = (char *)op->hh.key; + OPCODELENS[i] = (int32_t)strlen(OPCODES[i]); + } + } + //printf("bitcoin opcodes\n"); + } +} + +int32_t bitcoin_pubkeylen(const uint8_t *pubkey) +{ + if ( pubkey[0] == 2 || pubkey[0] == 3 ) + return(33); + else if ( pubkey[0] == 4 ) + return(65); + else + { + //printf("illegal pubkey.[%02x] %llx\n",pubkey[0],*(long long *)pubkey); + return(-1); + } +} + +int32_t iguana_expandscript(char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen) +{ + int32_t len,n,j,i = 0; uint8_t opcode; uint32_t val,extraflag; + iguana_optableinit(); + asmstr[0] = len = 0; + while ( i < scriptlen ) + { + val = extraflag = 0; + opcode = script[i++]; + if ( opcode > 0 && opcode < 76 ) + { + for (j=0; j= IGUANA_OP_1 && opcode <= IGUANA_OP_16 ) + { + sprintf(&asmstr[len],"%d",opcode - IGUANA_OP_1 + 1); + len += strlen(&asmstr[len]); + } + else if ( opcode == IGUANA_OP_0 ) + { + strcpy(&asmstr[len],"OP_FALSE"); + len += 8; + } + else if ( opcode == IGUANA_OP_1NEGATE ) + { + asmstr[len++] = '-'; + asmstr[len++] = '1'; + } + else + { + //printf("dest.%p <- %p %02x\n",&asmstr[len],OPCODES[opcode],opcode); + strcpy(&asmstr[len],OPCODES[opcode]); + len += OPCODELENS[opcode]; + } + if ( i < scriptlen ) + asmstr[len++] = ' '; + if ( opcode == IGUANA_OP_PUSHDATA1 ) + { + n = script[i++]; + for (j=0; jstack[--stacks->stackdepth]; + memset(&stacks->stack[stacks->stackdepth],0,sizeof(Snum)); + return(Snum); +} + +static int32_t iguana_altpush(struct iguana_interpreter *stacks,struct iguana_stackdata Snum) +{ + stacks->stack[2*IGUANA_MAXSTACKITEMS - ++stacks->altstackdepth] = Snum; + return(stacks->altstackdepth); +} + +static struct iguana_stackdata iguana_altpop(struct iguana_interpreter *stacks) +{ + struct iguana_stackdata Snum,*ptr; + ptr = &stacks->stack[2*IGUANA_MAXSTACKITEMS - --stacks->altstackdepth]; + Snum = *ptr; + memset(ptr,0,sizeof(Snum)); + return(Snum); +} + +static struct iguana_stackdata iguana_clone(struct iguana_stackdata Snum) +{ + struct iguana_stackdata clone; + clone = Snum; + if ( Snum.data != 0 ) + { + clone.data = malloc(Snum.size); + memcpy(clone.data,Snum.data,Snum.size); + } + return(clone); +} + +static int32_t iguana_isnonz(struct iguana_stackdata Snum) +{ + uint8_t *buf; int32_t i; + if ( Snum.size == sizeof(int32_t) ) + return(Snum.U.val != 0); + else if ( Snum.size == sizeof(int64_t) ) + return(Snum.U.val64 != 0); + else if ( Snum.size == 20 ) + buf = Snum.U.rmd160; + else if ( Snum.size == sizeof(bits256) ) + buf = Snum.U.hash2.bytes; + else if ( Snum.size == 33 ) + buf = Snum.U.pubkey; + else if ( Snum.size < 74 ) + buf = Snum.U.sig; + else buf = Snum.data; + for (i=0; ilastpath[stacks->ifdepth] < 0 ) + return(0); + //printf("PUSH.(%lld %p %d)\n",(long long)num64,numbuf,numlen); + if ( stacks->maxstackdepth > 0 ) + { + if ( numbuf != 0 ) + { + int32_t i; for (i=0; istackdepth < stacks->maxstackdepth ) + { + if ( stacks->logarray != 0 ) + item = cJSON_CreateObject(); + memset(&Snum,0,sizeof(Snum)); + if ( numbuf != 0 ) + { + if ( numlen <= sizeof(int32_t) ) + { + iguana_rwnum(1,(void *)&num,numlen,numbuf); + numlen = sizeof(num); + Snum.U.val = num; + } + else if ( numlen <= sizeof(int64_t) ) + { + iguana_rwnum(1,(void *)&num64,numlen,numbuf); + numlen = sizeof(num64); + Snum.U.val64 = num64; + } + else if ( numlen == 20 ) + memcpy(Snum.U.rmd160,numbuf,20); + else if ( numlen == sizeof(bits256) ) + iguana_rwbignum(1,Snum.U.hash2.bytes,sizeof(Snum.U.hash2),numbuf); + else if ( numlen == 33 ) + memcpy(Snum.U.pubkey,numbuf,numlen); + else if ( numlen < 74 ) + memcpy(Snum.U.sig,numbuf,numlen); + else + { + Snum.data = malloc(numlen); + memcpy(Snum.data,numbuf,numlen); + if ( item != 0 ) + jaddnum(item,"push",numlen); + } + Snum.size = numlen; + if ( item != 0 ) + { + init_hexbytes_noT(tmpstr,numbuf,numlen); + jaddstr(item,"push",tmpstr); + } + } + else if ( num64 <= 0xffffffff ) // what about negative numbers? + { + Snum.U.val = num, Snum.size = sizeof(num); + if ( item != 0 ) + jaddnum(item,"push",Snum.U.val); + } + else + { + Snum.U.val64 = num64, Snum.size = sizeof(num64); + if ( item != 0 ) + jaddnum(item,"push",Snum.U.val64); + } + if ( item != 0 ) + { + jaddnum(item,"depth",stacks->stackdepth); + if ( stacks->logarray != 0 ) + jaddi(stacks->logarray,item); + } + stacks->stack[stacks->stackdepth++] = Snum; + } else return(-1); + } else stacks->stackdepth++; + return(0); +} + +int32_t iguana_databuf(uint8_t *databuf,struct iguana_stackdata Snum) +{ + if ( Snum.size == 4 ) + memcpy(databuf,&Snum.U.val,4); + else if ( Snum.size == 8 ) + memcpy(databuf,&Snum.U.val64,8); + else if ( Snum.size == 20 ) + memcpy(databuf,&Snum.U.rmd160,20); + else if ( Snum.size == 32 ) + memcpy(databuf,&Snum.U.hash2.bytes,32); + else if ( Snum.size == 33 ) + memcpy(databuf,&Snum.U.pubkey,33); + else if ( Snum.size < 74 ) + memcpy(databuf,&Snum.U.sig,Snum.size); + else memcpy(databuf,&Snum.data,Snum.size); + return(Snum.size); +} + +static int32_t iguana_cmp(struct iguana_stackdata *a,struct iguana_stackdata *b) +{ + if ( a->size == b->size ) + { + if ( a->size == 4 ) + return(a->U.val != b->U.val); + else if ( a->size == 8 ) + return(a->U.val64 != b->U.val64); + else if ( a->size == 20 ) + return(memcmp(a->U.rmd160,b->U.rmd160,sizeof(a->U.rmd160))); + else if ( a->size == 32 ) + return(memcmp(a->U.hash2.bytes,b->U.hash2.bytes,sizeof(a->U.hash2))); + else if ( a->size == 33 ) + return(memcmp(a->U.pubkey,b->U.pubkey,33)); + else if ( a->size < 74 ) + return(memcmp(a->U.sig,b->U.sig,a->size)); + else return(memcmp(a->data,b->data,sizeof(a->size))); + } + return(-1); +} + +static int32_t iguana_dataparse(struct iguana_interpreter *stacks,uint8_t *script,int32_t k,char *str,int32_t *lenp) +{ + int32_t n,c,len; char tmp[4]; + *lenp = 0; + c = str[0]; + n = is_hexstr(str,0); + if ( n > 0 ) + { + if ( (n & 1) != 0 ) + len = (n+1) >> 1; + else len = n >> 1; + if ( len > 0 && len < 76 ) + { + if ( len == 1 ) + { + if ( n == 1 ) + { + tmp[0] = '0'; + tmp[1] = c; + tmp[2] = 0; + decode_hex(&script[k],1,tmp), (*lenp) = 1; + iguana_pushdata(stacks,script[k],0,0); + if ( script[k] != 0 ) + script[k++] += (IGUANA_OP_1 - 1); + return(k); + } + else if ( n == 2 && c == '1' && str[1] == '0' && is_delim(str[2]) != 0 ) + { + script[k++] = (IGUANA_OP_1 - 1) + 0x10, (*lenp) = 2; + iguana_pushdata(stacks,0x10,0,0); + return(k); + } + else if ( n == 2 && c == '8' && is_delim(str[2]) != 0 ) + { + if ( str[1] == '1' ) + { + script[k++] = IGUANA_OP_1NEGATE, (*lenp) = 2; + iguana_pushdata(stacks,-1,0,0); + return(k); + } + else if ( str[1] == '0' ) + { + script[k++] = IGUANA_OP_0, (*lenp) = 2; + iguana_pushdata(stacks,0,0,0); + return(k); + } + } + } + if ( len != 0 ) + script[k++] = len; + } + else if ( len <= 0xff ) + { + script[k++] = IGUANA_OP_PUSHDATA1; + script[k++] = len; + } + else if ( len <= 0xffff ) + { + if ( len <= MAX_SCRIPT_ELEMENT_SIZE ) + { + script[k++] = IGUANA_OP_PUSHDATA2; + script[k++] = (len & 0xff); + script[k++] = ((len >> 8) & 0xff); + } + else + { + printf("len.%d > MAX_SCRIPT_ELEMENT_SIZE.%d, offset.%d\n",len,MAX_SCRIPT_ELEMENT_SIZE,k); + return(-1); + } + } + else + { + printf("len.%d > MAX_SCRIPT_ELEMENT_SIZE.%d, offset.%d\n",len,MAX_SCRIPT_ELEMENT_SIZE,k); + return(-1); + } + if ( len != 0 ) + { + uint8_t *numstart; int32_t numlen; + numstart = &script[k], numlen = len; + if ( (n & 1) != 0 ) + { + tmp[0] = '0'; + tmp[1] = c; + tmp[2] = 0; + decode_hex(&script[k++],1,tmp), *lenp = 1; + len--; + } + if ( len != 0 ) + { + decode_hex(&script[k],len,str), (*lenp) += (len << 1); + k += len; + } + iguana_pushdata(stacks,0,numstart,numlen); + } + return(k); + } + return(0); +} + +void iguana_stack(struct iguana_interpreter *stacks,struct iguana_stackdata *args,int32_t num,char *pushstr,char *clonestr) +{ + int32_t i,c; + while ( (c= *pushstr++) != 0 ) + stacks->stack[stacks->stackdepth++] = args[c - '0']; + while ( (c= *clonestr++) != 0 ) + stacks->stack[stacks->stackdepth++] = iguana_clone(args[c - '0']); + if ( num > 0 ) + { + for (i=0; i 0 && siglen > 0 && siglen < 74 ) + { + if ( (retval= (bitcoin_verify(ctx,sig,siglen-1,sigtxid,pubkey,plen) == 0)) == 0 ) + { + } + if ( (0) ) + { + int32_t i; char str[65]; + for (i=0; i 0 && privlen == 32 ) + { + bitcoin_pubkey33(ctx,checkpub,*(bits256 *)privkey); + return(memcmp(checkpub,pubkey,33) == 0); + } + return(0); +} + +int32_t iguana_checkschnorrsig(void *ctx,int64_t M,struct iguana_stackdata pubkeyarg,struct iguana_stackdata sigarg,bits256 sigtxid) +{ + /*uint8_t combined_pub[MAX_SCRIPT_ELEMENT_SIZE],sig[MAX_SCRIPT_ELEMENT_SIZE]; int32_t plen,siglen; + plen = iguana_databuf(combined_pub,pubkeyarg); + siglen = iguana_databuf(sig,sigarg); + if ( bitcoin_pubkeylen(combined_pub) == 33 && siglen == 64 ) + return(bitcoin_schnorr_verify(ctx,sig,sigtxid,combined_pub,33) == 0);*/ + return(0); +} + +int32_t iguana_checkmultisig(void *ctx,struct iguana_interpreter *stacks,int32_t M,int32_t N,bits256 txhash2) +{ + int32_t i,j=0,len,n,m,valid=0,numsigners = 0,siglens[MAX_PUBKEYS_PER_MULTISIG]; uint8_t pubkeys[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE],sigs[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE]; + if ( M <= N && N <= MAX_PUBKEYS_PER_MULTISIG ) + { + if ( stacks->stackdepth <= 0 ) + return(0); + n = (int32_t)iguana_num(iguana_pop(stacks)); + if ( n != N ) + { + printf("iguana_checkmultisig n.%d != N.%d\n",n,N); + return(0); + } + //printf("n.%d stackdepth.%d\n",n,stacks->stackdepth); + for (i=0; istackdepth <= 0 ) + return(0); + len = iguana_databuf(pubkeys[i],iguana_pop(stacks)); + if ( len == bitcoin_pubkeylen(pubkeys[i]) ) + { + numsigners++; + //for (j=0; j<33; j++) + // printf("%02x",pubkeys[i][j]); + //printf(" <- pubkey.[%d]\n",i); + } + else + { + printf("nonpubkey on stack\n"); + return(0); + memcpy(sigs[0],pubkeys[i],len); + siglens[0] = len; + break; + } + } + if ( stacks->stackdepth <= 0 ) + return(0); + m = (int32_t)iguana_num(iguana_pop(stacks)); + //printf("m.%d stackdepth.%d\n",m,stacks->stackdepth); + + if ( m != M ) + { + printf("iguana_checkmultisig m.%d != M.%d\n",m,M); + return(0); + } + for (i=0; istackdepth <= 0 ) + return(0); + siglens[i] = iguana_databuf(sigs[i],iguana_pop(stacks)); + if ( siglens[i] <= 0 || siglens[i] > 74 ) + break; + //for (j=0; jstackdepth,bits256_str(str,txhash2)); + if ( stacks->stackdepth > 0 ) + iguana_pop(stacks); // for backward compatibility + j = numsigners-1; + for (i=numsigners-1; i>=0; i--) + { + for (; j>=0; j--) + { + if ( bitcoin_verify(ctx,sigs[i],siglens[i]-1,txhash2,pubkeys[j],bitcoin_pubkeylen(pubkeys[j])) == 0 ) + { + if ( ++valid >= M ) + return(1); + j--; + break; + } + } + } + } + } + printf("checkmultisig: valid.%d j.%d M.%d N.%d numsigners.%d\n",valid,j,M,N,numsigners); + return(0); +} + +#define LOCKTIME_THRESHOLD 500000000 +int32_t iguana_checklocktimeverify(void *ctx,int64_t tx_lockval,uint32_t nSequence,struct iguana_stackdata Snum) +{ + int64_t nLockTime = iguana_num(Snum); + if ( nLockTime < 0 || tx_lockval < 0 ) + { + printf("CLTV.0 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); + return(-1); + } + else if ( ((tx_lockval < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (tx_lockval >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)) == 0 ) + { + printf("CLTV.1 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); + return(-1); + } + else if ( nLockTime > tx_lockval ) + { + printf("CLTV.2 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); + return(-1); + } + return(0); +} + +int32_t iguana_checksequenceverify(void *ctx,int64_t nLockTime,uint32_t nSequence,struct iguana_stackdata Snum) +{ + return(0); +} + +cJSON *iguana_spendasm(uint8_t *spendscript,int32_t spendlen) +{ + char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; cJSON *spendasm = cJSON_CreateObject(); + iguana_expandscript(asmstr,sizeof(asmstr),spendscript,spendlen); + //int32_t i; for (i=0; i (%s)\n",asmstr); + jaddstr(spendasm,"interpreter",asmstr); + return(spendasm); +} + +int32_t bitcoin_assembler(void *ctx,cJSON *logarray,uint8_t script[IGUANA_MAXSCRIPTSIZE],cJSON *interpreter,int32_t interpret,int64_t nLockTime,struct vin_info *V) +{ + struct bitcoin_opcode *op; cJSON *array = 0; struct iguana_interpreter STACKS,*stacks = &STACKS; + struct iguana_stackdata args[MAX_PUBKEYS_PER_MULTISIG]; + uint8_t databuf[MAX_SCRIPT_ELEMENT_SIZE]; char *asmstr,*str,*hexstr; cJSON *item; + int32_t c,numops,dlen,plen,numvars,numused,numargs=0,i,j,k,n=0,len,datalen,errs=0; int64_t val; + iguana_optableinit(); + if ( (asmstr= jstr(interpreter,"interpreter")) == 0 || asmstr[0] == 0 ) + return(0); + if ( (numvars= juint(interpreter,"numvars")) > 0 ) + { + if ( (array= jarray(&n,interpreter,"args")) == 0 || (interpret != 0 && n != numvars) ) + return(-2); + } + str = asmstr; + if ( interpret != 0 ) + { + stacks = calloc(1,sizeof(*stacks) + sizeof(*stacks->stack)*2*IGUANA_MAXSTACKITEMS); + stacks->maxstackdepth = IGUANA_MAXSTACKITEMS; + if ( (stacks->logarray= logarray) != 0 ) + item = cJSON_CreateObject(); + else item = 0; + if ( V->M == 0 && V->N == 0 ) + V->N = V->M = 1; + for (i=0; iN; i++) + { + if ( V->signers[i].siglen != 0 ) + { + iguana_pushdata(stacks,0,V->signers[i].sig,V->signers[i].siglen); + if ( bitcoin_pubkeylen(V->signers[i].pubkey) <= 0 ) + { + printf("missing pubkey.[%d]\n",i); + free(stacks); + return(-1); + } + //printf("pushdata siglen.%d depth.%d\n",V->signers[i].siglen,stacks->stackdepth); + } + } + for (i=0; iN; i++) + { + if ( V->signers[i].siglen != 0 ) + { + plen = bitcoin_pubkeylen(V->signers[i].pubkey); + if ( V->suppress_pubkeys == 0 && (V->spendscript[0] != plen || V->spendscript[V->spendlen - 1] != IGUANA_OP_CHECKSIG || bitcoin_pubkeylen(&V->spendscript[1]) <= 0) ) + { + iguana_pushdata(stacks,0,V->signers[i].pubkey,plen); + //printf(">>>>>>>>> suppress.%d pushdata [%02x %02x] plen.%d depth.%d\n",V->suppress_pubkeys,V->signers[i].pubkey[0],V->signers[i].pubkey[1],plen,stacks->stackdepth); + } // else printf("<<<<<<<<<< skip pubkey push %d script[0].%d spendlen.%d depth.%d\n",plen,V->spendscript[0],V->spendlen,stacks->stackdepth); + } + } + if ( V->userdatalen != 0 ) + { + len = 0; + while ( len < V->userdatalen ) + { + dlen = V->userdata[len++]; + if ( dlen > 0 && dlen < 76 ) + iguana_pushdata(stacks,0,&V->userdata[len],dlen), len += dlen; + else if ( dlen >= IGUANA_OP_1 && dlen <= IGUANA_OP_16 ) + { + dlen -= (IGUANA_OP_1 - 1); + iguana_pushdata(stacks,dlen,0,0); + } + else if ( dlen == IGUANA_OP_PUSHDATA1 ) + { + iguana_pushdata(stacks,V->userdata[len++],0,0); + } + else if ( dlen == IGUANA_OP_PUSHDATA2 ) + { + iguana_pushdata(stacks,V->userdata[len] + ((int32_t)V->userdata[len+1]<<8),0,0); + len += 2; + } + else if ( dlen == IGUANA_OP_0 ) + iguana_pushdata(stacks,0,0,0); + else if ( dlen == IGUANA_OP_1NEGATE ) + iguana_pushdata(stacks,-1,0,0); + else + { + printf("invalid data opcode %02x\n",dlen); + free(stacks); + return(-1); + } + //printf("user data stackdepth.%d dlen.%d\n",stacks->stackdepth,dlen); + } + if ( len != V->userdatalen ) + { + printf("mismatched userdatalen %d vs %d\n",len,V->userdatalen); + free(stacks); + return(-1); + } + } + if ( item != 0 && stacks->logarray != 0 ) + { + jaddstr(item,"spendasm",asmstr); + jaddi(stacks->logarray,item); + } + if ( V->extras != 0 ) + { + if ( (n= cJSON_GetArraySize(V->extras)) > 0 ) + { + for (i=0; iextras,i),0)) != 0 && (len= is_hexstr(hexstr,0)) > 0 ) + { + len >>= 1; + decode_hex(databuf,len,hexstr); + iguana_pushdata(stacks,0,databuf,len); + } + } + } + } + } else memset(stacks,0,sizeof(*stacks)); + stacks->lastpath[0] = 1; + k = numops = numused = 0; + script[k] = 0; + while ( (c= *str++) != 0 ) + { + if ( is_delim(c) != 0 ) + { + //if ( c == 0 ) + // break; + continue; + } + if ( c == '/' && *str == '/' ) // support // + break; + else if ( c == '-' && *str == '1' && is_delim(str[1]) != 0 ) + { + script[k++] = IGUANA_OP_1NEGATE, str += 3; // OP_1NEGATE; + iguana_pushdata(stacks,-1,0,0); + continue; + } + else if ( c == '%' && *str == 's' ) + { + str++; + if ( numused < numvars && (hexstr= jstr(jitem(array,numused++),0)) != 0 ) + { + if ( (n= iguana_dataparse(stacks,script,k,str,&len)) > 0 ) + { + k += n; + continue; + } + } + printf("dataparse error.%d, numused.%d >= numvars.%d\n",n,numused,numvars); + errs++; + break; + } + else + { + str--; + if ( (n= iguana_dataparse(stacks,script,k,str,&len)) > 0 ) + { + k = n; + str += len; + continue; + } + else if ( n < 0 ) + { + printf("dataparse negative n.%d\n",n); + errs++; + break; + } + } + for (j=0; j<32; j++) + if ( is_delim(str[j]) != 0 ) + break; + if ( j == 32 ) + { + printf("too long opcode.%s at offset.%ld\n",str,(long)str-(long)asmstr); + errs++; + break; + } + HASH_FIND(hh,OPTABLE,str,j,op); + printf("{%s}\n",str); + str += j; + if ( op != 0 ) + { + if ( numargs > 0 ) + { + for (i=0; iopcode; + if ( (op->flags & IGUANA_CONTROLFLAG) != 0 ) + { + //printf("control opcode depth.%d\n",stacks->stackdepth); + switch ( op->opcode ) + { + case IGUANA_OP_IF: case IGUANA_OP_NOTIF: + if ( stacks->ifdepth >= IGUANA_MAXSTACKDEPTH ) + { + printf("ifdepth.%d >= MAXSTACKDEPTH.%d\n",stacks->ifdepth,IGUANA_MAXSTACKDEPTH); + errs++; + } + else + { + if ( stacks->stackdepth <= 0 ) + { + printf("if invalid stackdepth %d\n",stacks->stackdepth); + errs++; + } + else + { + args[0] = iguana_pop(stacks); + if ( iguana_isnonz(args[0]) == (op->opcode == IGUANA_OP_IF) ) + { + val = 1; + //printf("OP_IF enabled depth.%d\n",stacks->stackdepth); + } + else + { + val = -1; + //printf("OP_IF disabled depth.%d\n",stacks->stackdepth); + } + stacks->lastpath[++stacks->ifdepth] = val; + } + } + break; + case IGUANA_OP_ELSE: + /*if ( stacks->stackdepth <= 0 ) + { + printf("else invalid stackdepth %d\n",stacks->stackdepth); + errs++; + } + else*/ + { + if ( stacks->ifdepth <= stacks->elsedepth ) + { + printf("unhandled opcode.%02x stacks->ifdepth %d <= %d stacks->elsedepth\n",op->opcode,stacks->ifdepth,stacks->elsedepth); + errs++; + } + stacks->lastpath[stacks->ifdepth] *= -1; + //printf("OP_ELSE status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); + } + break; + case IGUANA_OP_ENDIF: + if ( stacks->ifdepth <= 0 ) + { + printf("endif without if offset.%ld\n",(long)str-(long)asmstr); + errs++; + } + stacks->ifdepth--; + //printf("OP_ENDIF status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); + break; + case IGUANA_OP_VERIFY: + break; + case IGUANA_OP_RETURN: + iguana_pushdata(stacks,0,0,0); + errs++; + break; + } + if ( errs != 0 ) + break; + continue; + } + if ( stacks->lastpath[stacks->ifdepth] != 0 ) + { + if ( stacks->lastpath[stacks->ifdepth] < 0 ) + { + //printf("SKIP opcode.%02x depth.%d\n",op->opcode,stacks->stackdepth); + if ( stacks->logarray ) + jaddistr(stacks->logarray,"skip"); + continue; + } + //printf("conditional opcode.%02x stackdepth.%d\n",op->opcode,stacks->stackdepth); + } + if ( op->opcode <= IGUANA_OP_16 || ++numops <= MAX_OPS_PER_SCRIPT ) + { + if ( (op->flags & IGUANA_ALWAYSILLEGAL) != 0 ) + { + printf("disabled opcode.%s at offset.%ld\n",str,(long)str-(long)asmstr); + errs++; + break; + } + else if ( op->extralen > 0 ) + { + if ( is_delim(*str) != 0 ) + str++; + if ( is_hexstr(str,0) != (op->extralen<<1) ) + { + printf("expected extralen.%d of hex, got.(%s) at offset.%ld\n",op->extralen,str,(long)str-(long)asmstr); + errs++; + break; + } + decode_hex(&script[k],op->extralen,str), str += (op->extralen << 1); + if ( op->extralen == 1 ) + iguana_pushdata(stacks,script[k],0,0); + else if ( op->extralen == 2 ) + iguana_pushdata(stacks,script[k] + ((uint32_t)script[k]<<8),0,0); + k += op->extralen; + continue; + } + if ( interpret == 0 || V == 0 ) + continue; + if ( (op->flags & IGUANA_NOPFLAG) != 0 ) + continue; + if ( (numargs= op->stackitems) > 0 ) + { + if ( stacks->stackdepth < op->stackitems ) + { + //printf("stackdepth.%d needed.%d (%s) at offset.%ld\n",stacks->stackdepth,op->stackitems,str,(long)str-(long)asmstr); + errs++; + break; + } + for (i=0; iopcode,numargs,stacks->stackdepth); + if ( stacks->logarray != 0 ) + { + char tmpstr[1096]; + item = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (i=0; ihh.key,array); + jaddi(stacks->logarray,item); + } + if ( (op->flags & IGUANA_EXECUTIONILLEGAL) != 0 ) + { + printf("opcode not allowed to run.%s at %ld\n",(char *)op->hh.key,(long)str-(long)asmstr); + errs++; + break; + } + else if ( op->opcode == IGUANA_OP_EQUALVERIFY || op->opcode == IGUANA_OP_EQUAL ) + { + if ( iguana_cmp(&args[0],&args[1]) == 0 ) + iguana_pushdata(stacks,1,0,0); + else + { + iguana_pushdata(stacks,0,0,0); + for (i=0; iopcode,args[0].size,args[1].size); + } + } + else if ( (op->flags & IGUANA_CRYPTOFLAG) != 0 ) + { + uint8_t rmd160[20],revdatabuf[MAX_SCRIPT_ELEMENT_SIZE]; bits256 hash; + datalen = iguana_databuf(databuf,args[0]); + for (i=0; iopcode ) + { + case IGUANA_OP_RIPEMD160: + calc_rmd160(0,rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_SHA1: + calc_sha1(0,rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_HASH160: + /*if ( datalen == 32 ) + { + revcalc_rmd160_sha256(rmd160,*(bits256 *)databuf); + printf("SPECIAL CASE REVERSE\n"); + } else + for (i=0; i<32; i++) + printf("%02x",databuf[i]); + printf(" <- databuf\n"); + for (i=0; i<32; i++) + printf("%02x",revdatabuf[i]); + printf(" <- revdatabuf\n"); + calc_rmd160_sha256(rmd160,revdatabuf,datalen); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 revdatabuf\n"); + revcalc_rmd160_sha256(rmd160,*(bits256 *)databuf); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 special\n"); + calc_rmd160_sha256(rmd160,databuf,datalen); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 databuf\n");*/ + if ( datalen == 32 ) + calc_rmd160_sha256(rmd160,revdatabuf,datalen); + else calc_rmd160_sha256(rmd160,databuf,datalen); + iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); + break; + case IGUANA_OP_SHA256: + vcalc_sha256(0,hash.bytes,databuf,datalen); + for (i=0; i sha256 %s\n",bits256_str(str,hash)); + iguana_pushdata(stacks,0,hash.bytes,sizeof(hash)); + break; + case IGUANA_OP_HASH256: + hash = bits256_doublesha256(0,databuf,datalen); + iguana_pushdata(stacks,0,hash.bytes,sizeof(hash)); + break; + case IGUANA_OP_CHECKSIG: case IGUANA_OP_CHECKSIGVERIFY: + iguana_pushdata(stacks,iguana_checksig(ctx,args[1],args[0],V->sigtxid),0,0); + break; + case IGUANA_OP_CHECKMULTISIG: case IGUANA_OP_CHECKMULTISIGVERIFY: + iguana_pushdata(stacks,iguana_checkmultisig(ctx,stacks,V->M,V->N,V->sigtxid),0,0); + break; + case IGUANA_OP_CHECKSCHNORR: case IGUANA_OP_CHECKSCHNORRVERIFY: + iguana_pushdata(stacks,iguana_checkschnorrsig(ctx,iguana_num(args[2]),args[1],args[0],V->sigtxid),0,0); + break; + case IGUANA_OP_CHECKPRIVATEKEY: case IGUANA_OP_CHECKPRIVATEKEYVERIFY: + iguana_pushdata(stacks,iguana_checkprivatekey(ctx,args[1],args[0]),0,0); + break; + } + } + else if ( op->opcode == IGUANA_OP_CHECKLOCKTIMEVERIFY ) // former OP_NOP2 + { + if ( V->ignore_cltverr == 0 && iguana_checklocktimeverify(ctx,nLockTime,V->sequence,args[0]) < 0 ) + { + iguana_stack(stacks,args,1,"0",""); + errs++; + break; + } + iguana_stack(stacks,args,1,"0",""); + continue; + } + else if ( op->opcode == IGUANA_OP_CHECKSEQUENCEVERIFY ) // former OP_NOP3 + { + if ( iguana_checksequenceverify(ctx,nLockTime,V->sequence,args[0]) < 0 ) + { + iguana_stack(stacks,args,1,"0",""); + errs++; + break; + } + iguana_stack(stacks,args,1,"0",""); + continue; + } + else if ( (op->flags & IGUANA_STACKFLAG) != 0 ) + { + val = 0; + if ( op->opcode == IGUANA_OP_PICK || op->opcode == IGUANA_OP_ROLL ) + { + if ( interpret != 0 && stacks->stackdepth < (val= iguana_num(args[0])) ) + { + printf("stack not deep enough %d < %lld\n",stacks->stackdepth,(long long)iguana_num(args[0])); + errs++; + break; + } + if ( op->opcode == IGUANA_OP_PICK ) + { + stacks->stack[stacks->stackdepth] = iguana_clone(stacks->stack[stacks->stackdepth - 1 - val]); + stacks->stackdepth++; + } + else + { + args[1] = stacks->stack[stacks->stackdepth - 1 - val]; + for (i=(int32_t)(stacks->stackdepth-1-val); istackdepth-1; i++) + stacks->stack[i] = stacks->stack[i+1]; + stacks->stack[stacks->stackdepth - 1] = args[1]; + } + } + else + { + switch ( op->opcode ) + { + case IGUANA_OP_TOALTSTACK: + if ( stacks->altstackdepth < stacks->maxstackdepth ) + { + iguana_altpush(stacks,args[0]); + memset(&args[0],0,sizeof(args[0])); + } + else + { + printf("altstack overflow %d vs %d\n",stacks->altstackdepth,stacks->maxstackdepth); + errs++; + } + break; + case IGUANA_OP_FROMALTSTACK: + stacks->stack[stacks->stackdepth++] = iguana_altpop(stacks); + break; + case IGUANA_OP_DEPTH: iguana_pushdata(stacks,stacks->stackdepth,0,0); break; + case IGUANA_OP_DROP: case IGUANA_OP_2DROP: break; + case IGUANA_OP_3DUP: iguana_stack(stacks,args,3,"012","012"); break; + case IGUANA_OP_2OVER: iguana_stack(stacks,args,4,"0123","01"); break; + case IGUANA_OP_2ROT: iguana_stack(stacks,args,6,"234501",""); break; + case IGUANA_OP_2SWAP: iguana_stack(stacks,args,4,"2301",""); break; + case IGUANA_OP_IFDUP: + if ( iguana_isnonz(args[0]) != 0 ) + iguana_stack(stacks,args,0,"","0"); + iguana_stack(stacks,args,1,"0",""); + break; + case IGUANA_OP_DUP: iguana_stack(stacks,args,1,"0","0"); break; + case IGUANA_OP_2DUP: iguana_stack(stacks,args,2,"01","01"); break; + case IGUANA_OP_NIP: + if ( args[0].data != 0 ) + free(args[0].data); + iguana_stack(stacks,args,2,"1",""); + break; + case IGUANA_OP_OVER: iguana_stack(stacks,args,2,"01","0"); break; + case IGUANA_OP_ROT: iguana_stack(stacks,args,3,"120",""); break; + case IGUANA_OP_SWAP: iguana_stack(stacks,args,2,"10",""); break; + case IGUANA_OP_TUCK: iguana_stack(stacks,args,2,"10","1"); break; + } + } + } + else if ( (op->flags & IGUANA_MATHFLAG) != 0 ) + { + int64_t numA=0,numB=0,numC=0; + for (i=0; istackitems; i++) + { + if ( args[i].size != sizeof(int32_t) ) + break; + if ( i == 0 ) + numA = iguana_num(args[i]); + else if ( i == 1 ) + numB = iguana_num(args[i]); + else if ( i == 2 ) + numC = iguana_num(args[i]); + } + if ( i != op->stackitems ) + { + printf("math script non-int32_t arg[%d] of %d\n",i,op->stackitems); + errs++; + break; + } + switch ( op->opcode ) + { + case IGUANA_OP_1ADD: iguana_pushdata(stacks,numA + 1,0,0); break; + case IGUANA_OP_1SUB: iguana_pushdata(stacks,numA - 1,0,0); break; + case IGUANA_OP_NEGATE: iguana_pushdata(stacks,-numA,0,0); break; + case IGUANA_OP_ABS: iguana_pushdata(stacks,numA<0?-numA:numA,0,0); break; + case IGUANA_OP_NOT: iguana_pushdata(stacks,numA == 0,0,0); break; + case IGUANA_OP_0NOTEQUAL: iguana_pushdata(stacks,numA != 0,0,0); break; + case IGUANA_OP_ADD: iguana_pushdata(stacks,numA + numB,0,0); break; + case IGUANA_OP_SUB: iguana_pushdata(stacks,numA - numB,0,0); break; + case IGUANA_OP_BOOLAND:iguana_pushdata(stacks,numA != 0 && numB != 0,0,0); break; + case IGUANA_OP_BOOLOR: iguana_pushdata(stacks,numA != 0 || numB != 0,0,0); break; + case IGUANA_OP_NUMEQUAL: case IGUANA_OP_NUMEQUALVERIFY: + iguana_pushdata(stacks,numA == numB,0,0); break; + case IGUANA_OP_NUMNOTEQUAL:iguana_pushdata(stacks,numA != numB,0,0); break; + case IGUANA_OP_LESSTHAN: iguana_pushdata(stacks,numA < numB,0,0); break; + case IGUANA_OP_GREATERTHAN:iguana_pushdata(stacks,numA > numB,0,0); break; + case IGUANA_OP_LESSTHANOREQUAL:iguana_pushdata(stacks,numA <= numB,0,0); break; + case IGUANA_OP_GREATERTHANOREQUAL:iguana_pushdata(stacks,numA >= numB,0,0); break; + case IGUANA_OP_MIN: iguana_pushdata(stacks,numA <= numB ? numA : numB,0,0); break; + case IGUANA_OP_MAX: iguana_pushdata(stacks,numA >= numB ? numA : numB,0,0); break; + case IGUANA_OP_WITHIN: iguana_pushdata(stacks,numB <= numA && numA < numC,0,0); break; + } + } + else if ( op->opcode == IGUANA_OP_CODESEPARATOR ) + { + if ( stacks != 0 ) + stacks->codeseparator = k; + continue; + } + else + { + printf("unhandled opcode.%02x (%s)\n",op->opcode,str); + errs++; + break; + } + if ( (op->flags & IGUANA_POSTVERIFY) != 0 ) + { + if ( stacks->stackdepth < 1 ) + { + printf("empty stack at offset.%ld\n",(long)str - (long)asmstr); + errs++; + break; + } + if ( iguana_isnonz(stacks->stack[stacks->stackdepth-1]) == 0 ) + break; + iguana_pop(stacks); + } + } + else + { + printf("too many ops opcode.%s at offset.%ld\n",str,(long)str - (long)asmstr); + errs++; + break; + } + } + else + { + printf("unknown opcode.%s at offset.%ld\n",str,(long)str - (long)asmstr); + errs++; + break; + } + } + if ( stacks != &STACKS ) + { + if ( jobj(interpreter,"result") != 0 ) + jdelete(interpreter,"result"); + if ( stacks->stackdepth <= 0 ) + { + errs++; + printf("empty stack error\n"); + jaddstr(interpreter,"error","empty stack"); + jadd(interpreter,"result",jfalse()); + } + else if ( iguana_isnonz(stacks->stack[--stacks->stackdepth]) != 0 ) + { + //printf("Evaluate true, depth.%d errs.%d k.%d\n",stacks->stackdepth,errs,k); + if ( errs == 0 ) + jadd(interpreter,"result",jtrue()); + else jadd(interpreter,"result",jfalse()); + } + else + { + jadd(interpreter,"result",jfalse()); + printf("Evaluate FALSE, depth.%d errs.%d [0] size.%d val.%d\n",stacks->stackdepth,errs,stacks->stack[0].size,stacks->stack[0].U.val); + errs++; + if ( stacks->logarray != 0 ) + printf("LOG.(%s)\n\n",jprint(stacks->logarray,0)); + } + if ( numargs > 0 ) + { + for (i=0; i OP_EQUALVERIFY OP_CHECKSIG +int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) +{ + script[n++] = SCRIPT_OP_DUP; + script[n++] = SCRIPT_OP_HASH160; + script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14; + script[n++] = SCRIPT_OP_EQUALVERIFY; + script[n++] = SCRIPT_OP_CHECKSIG; + return(n); +} + +int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime) +{ + script[n++] = 4; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff; + script[n++] = SCRIPT_OP_CHECKLOCKTIMEVERIFY; + script[n++] = SCRIPT_OP_DROP; + return(n); +} + +int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint32_t timestamp) +{ + n = bitcoin_checklocktimeverify(script,n,timestamp); + n = bitcoin_standardspend(script,n,rmd160); + return(n); +} + +int32_t bitcoin_performancebond(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,uint32_t unlocktimestamp,uint8_t *cltvpub33,uint8_t *elsepub33) +{ + script[n++] = SCRIPT_OP_IF; + n = bitcoin_checklocktimeverify(script,n,unlocktimestamp); + n = bitcoin_pubkeyspend(script,n,cltvpub33); + script[n++] = SCRIPT_OP_ELSE; + n = bitcoin_pubkeyspend(script,n,elsepub33); + script[n++] = SCRIPT_OP_ENDIF; + calc_rmd160_sha256(p2sh_rmd160,script,n); + return(n); +} + +int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp) +{ + int32_t i,plen; + script[n++] = 0x50 + vp->M; + for (i=0; iN; i++) + { + if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 ) + return(-1); + script[n++] = plen; + memcpy(&script[n],vp->signers[i].pubkey,plen); + n += plen; + } + script[n++] = 0x50 + vp->N; + script[n++] = SCRIPT_OP_CHECKMULTISIG; + calc_rmd160_sha256(p2sh_rmd160,script,n); + return(n); +} + +int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,const int32_t p2shlen) +{ + if ( p2shlen >= 0xfd ) + { + script[n++] = 0x4d; + script[n++] = (p2shlen & 0xff); + script[n++] = ((p2shlen >> 8) & 0xff); + } + else if ( p2shlen > 76 ) + { + script[n++] = 0x4c; + script[n++] = p2shlen; + } else script[n++] = p2shlen; + memcpy(&script[n],p2shscript,p2shlen), n += p2shlen; + return(n); +} + +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) +{ + if ( userpass[0] == 0 ) + return(clonestr("{\"error\":\"no rpcusername rpcpassword in coin.conf\"}")); + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,4)); +} + +char *bitcoind_passthrut(char *coinstr,char *serverport,char *userpass,char *method,char *params,int32_t timeout) +{ + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,timeout)); +} + +bits256 bits256_calctxid(char *symbol,uint8_t *serialized,int32_t len) +{ + bits256 txid,revtxid; int32_t i; + memset(txid.bytes,0,sizeof(txid)); + if ( strcmp(symbol,"GRS") != 0 ) + txid = bits256_doublesha256(0,serialized,len); + else + { + vcalc_sha256(0,revtxid.bytes,serialized,len); + for (i=0; i<32; i++) + txid.bytes[i] = revtxid.bytes[31 - i]; + } + return(txid); +} + +bits256 bits256_calcaddrhash(char *symbol,uint8_t *serialized,int32_t len) +{ + bits256 hash; + if ( strcmp(symbol,"GRS") != 0 ) + hash = bits256_doublesha256(0,serialized,len); + else + { + HashGroestl(hash.bytes,serialized,len); + /*int32_t i; char str[65]; + for (i=0; i %s\n",len,bits256_str(str,hash));*/ + } + return(hash); +} + +int32_t bitcoin_addr2rmd160(char *symbol,uint8_t taddr,uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) +{ + bits256 hash; uint8_t *buf,_buf[26],data5[128],rmd21[21]; char prefixaddr[64],hrp[64]; int32_t len,len5,offset; + if ( coinaddr == 0 || coinaddr[0] == 0 ) + { + *addrtypep = 0; + memset(rmd160,0,20); + return(0); + } + if ( strcmp(symbol,"BCH") == 0 )//&& strlen(coinaddr) == 42 ) + { + char *bchprefix = "bitcoincash:"; + if ( strncmp(coinaddr,bchprefix,strlen(bchprefix)) != 0 ) + { + strcpy(prefixaddr,bchprefix); + strcat(prefixaddr,coinaddr); + } else strcpy(prefixaddr,coinaddr); + if ( bech32_decode(hrp,data5,&len5,prefixaddr) == 0 ) + { + printf("bitcoin_addr2rmd160 bech32_decode error.(%s)\n",prefixaddr); + return(0); + } + len = 0; + if ( bech32_convert_bits(rmd21,&len,8,data5,len5,5,0) == 0 ) + printf("error converting data5\n"); + *addrtypep = rmd21[0] == 0 ? 0 : 5; + memcpy(rmd160,&rmd21[1],20); + return(20); + } + offset = 1 + (taddr != 0); + memset(rmd160,0,20); + *addrtypep = 0; + buf = _buf; + if ( (len= bitcoin_base58decode(buf,coinaddr)) >= 4 ) + { + // validate with trailing hash, then remove hash + hash = bits256_calcaddrhash(symbol,buf,20+offset); + *addrtypep = (taddr == 0) ? *buf : buf[1]; + memcpy(rmd160,buf+offset,20); + if ( strcmp(symbol,"GRS") != 0 && (buf[20+offset]&0xff) == hash.bytes[31] && (buf[21+offset]&0xff) == hash.bytes[30] && (buf[22+offset]&0xff) == hash.bytes[29] && (buf[23+offset]&0xff) == hash.bytes[28] ) + { + //printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep); + return(20); + } + else if ( strcmp(symbol,"GRS") == 0 && (buf[20+offset]&0xff) == hash.bytes[0] && (buf[21+offset]&0xff) == hash.bytes[1] && (buf[22+offset]&0xff) == hash.bytes[2] && (buf[23+offset]&0xff) == hash.bytes[3] ) + return(20); + else + { + int32_t i; + //if ( len > 20 ) + // hash = bits256_calcaddrhash(symbol,buf,len); + for (i=0; i "); + hash = bits256_calcaddrhash(symbol,data,(int32_t)data_len+offset); + //for (i=0; i<32; i++) + // printf("%02x",hash.bytes[i]); + //printf(" checkhash\n"); + if ( strcmp(symbol,"GRS") != 0 ) + { + for (i=0; i<4; i++) + data[data_len+i+offset] = hash.bytes[31-i]; + } + else + { + for (i=0; i<4; i++) + data[data_len+i+offset] = hash.bytes[i]; + } + return(data_len + 4 + offset); +} + +int32_t bitcoin_wif2priv(char *symbol,uint8_t wiftaddr,uint8_t *addrtypep,bits256 *privkeyp,char *wifstr) +{ + int32_t offset,len = -1; bits256 hash; uint8_t buf[256],*ptr; + offset = 1 + (wiftaddr != 0); + memset(buf,0,sizeof(buf)); + memset(privkeyp,0,sizeof(*privkeyp)); + if ( (len= bitcoin_base58decode(buf,wifstr)) >= 4 ) + { + if ( len >= 32+offset ) + { + memcpy(privkeyp,buf+offset,32); + /*if ( len > 32+offset ) + printf("wif %s: extra byte %d len.%d vs %d addrtype.%d\n",wifstr,buf[32+offset],len,32+offset,(wiftaddr == 0) ? buf[0] : buf[1]); + else printf("%s is for uncompressed\n",wifstr);*/ + } + else + { + printf("wif %s -> buf too short len.%d\n",wifstr,len); + return(-1); + } + ptr = buf; + hash = bits256_calcaddrhash(symbol,ptr,len - 4); + *addrtypep = (wiftaddr == 0) ? *ptr : ptr[1]; + if ( strcmp(symbol,"GRS") != 0 && (ptr[len - 4]&0xff) == hash.bytes[31] && (ptr[len - 3]&0xff) == hash.bytes[30] &&(ptr[len - 2]&0xff) == hash.bytes[29] && (ptr[len - 1]&0xff) == hash.bytes[28] ) + { + //int32_t i; for (i=0; i wif.(%s) addrtype.%02x -> %02x (%s)\n",bits256_str(str,privkey),wifstr,addrtype,checktype,bits256_str(str2,checkpriv)); + } + } + return((int32_t)strlen(wifstr)); +} + +int32_t bitcoin_priv2wiflong(char *symbol,uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype) +{ + uint8_t data[128]; int32_t offset,len = 32; + offset = 1 + (wiftaddr != 0); + memcpy(data+offset,privkey.bytes,sizeof(privkey)); + len = base58encode_checkbuf(symbol,wiftaddr,addrtype,data,len); + if ( bitcoin_base58encode(wifstr,data,len) == 0 ) + return(-1); + if ( 0 ) + { + uint8_t checktype; bits256 checkpriv; char str[65],str2[65]; + if ( bitcoin_wif2priv(symbol,wiftaddr,&checktype,&checkpriv,wifstr) == sizeof(bits256) ) + { + if ( checktype != addrtype || bits256_cmp(checkpriv,privkey) != 0 ) + printf("(%s) -> wif.(%s) addrtype.%02x -> %02x (%s)\n",bits256_str(str,privkey),wifstr,addrtype,checktype,bits256_str(str2,checkpriv)); + } + } + return((int32_t)strlen(wifstr)); +} + +char *_setVsigner(char *symbol,uint8_t wiftaddr,uint8_t pubtype,struct vin_info *V,int32_t ind,char *pubstr,char *wifstr) +{ + uint8_t addrtype; + decode_hex(V->signers[ind].pubkey,(int32_t)strlen(pubstr)/2,pubstr); + bitcoin_wif2priv(symbol,wiftaddr,&addrtype,&V->signers[ind].privkey,wifstr); + if ( addrtype != pubtype ) + return(clonestr("{\"error\":\"invalid wifA\"}")); + else return(0); +} + +uint8_t iguana_addrtype(uint8_t pubtype,uint8_t p2shtype,uint8_t script_type) +{ + if ( script_type == IGUANA_SCRIPT_76A988AC || script_type == IGUANA_SCRIPT_AC || script_type == IGUANA_SCRIPT_76AC ) + return(pubtype); + else + { + //printf("P2SH type.%d\n",script_type); + return(p2shtype); + } +} + +int32_t iguana_scriptgen(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi) +{ + uint8_t addrtype; char rmd160str[41],pubkeystr[256]; int32_t plen,i,m,n,flag = 0,scriptlen = 0; + m = n = 0; + if ( asmstr != 0 ) + asmstr[0] = 0; + addrtype = iguana_addrtype(pubtype,p2shtype,type); + if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH ) + { + init_hexbytes_noT(rmd160str,rmd160,20); + bitcoin_address(symbol,coinaddr,taddr,addrtype,rmd160,20); + } + switch ( type ) + { + case IGUANA_SCRIPT_NULL: + if ( asmstr != 0 ) + strcpy(asmstr,txi == 0 ? "coinbase " : "PoSbase "); + flag++; + coinaddr[0] = 0; + break; + case IGUANA_SCRIPT_76AC: + case IGUANA_SCRIPT_AC: + if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) < 0 ) + return(0); + init_hexbytes_noT(pubkeystr,(uint8_t *)vp->signers[0].pubkey,plen); + if ( asmstr != 0 ) + { + if ( type == IGUANA_SCRIPT_76AC ) + strcpy(asmstr,"OP_DUP "); + sprintf(asmstr + strlen(asmstr),"%s OP_CHECKSIG // %s",pubkeystr,coinaddr); + } + if ( type == IGUANA_SCRIPT_76AC ) + script[scriptlen++] = 0x76; + scriptlen = bitcoin_pubkeyspend(script,scriptlen,(uint8_t *)vp->signers[0].pubkey); + //printf("[%02x] type.%d scriptlen.%d\n",vp->signers[0].pubkey[0],type,scriptlen); + break; + case IGUANA_SCRIPT_76A988AC: + if ( asmstr != 0 ) + sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr); + scriptlen = bitcoin_standardspend(script,0,rmd160); + break; + case IGUANA_SCRIPT_P2SH: + if ( asmstr != 0 ) + sprintf(asmstr,"OP_HASH160 %s OP_EQUAL // %s",rmd160str,coinaddr); + scriptlen = bitcoin_p2shspend(script,0,rmd160); + break; + case IGUANA_SCRIPT_OPRETURN: + if ( asmstr != 0 ) + strcpy(asmstr,"OP_RETURN "); + bitcoin_address(symbol,coinaddr,taddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + case IGUANA_SCRIPT_3of3: m = 3, n = 3; break; + case IGUANA_SCRIPT_2of3: m = 2, n = 3; break; + case IGUANA_SCRIPT_1of3: m = 1, n = 3; break; + case IGUANA_SCRIPT_2of2: m = 2, n = 2; break; + case IGUANA_SCRIPT_1of2: m = 1, n = 2; break; + case IGUANA_SCRIPT_1of1: m = 1, n = 1; break; + case IGUANA_SCRIPT_MSIG: m = vp->M, n = vp->N; break; + case IGUANA_SCRIPT_DATA: + if ( asmstr != 0 ) + strcpy(asmstr,"DATA ONLY"); + bitcoin_address(symbol,coinaddr,taddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + case IGUANA_SCRIPT_STRANGE: + if ( asmstr != 0 ) + strcpy(asmstr,"STRANGE SCRIPT "); + bitcoin_address(symbol,coinaddr,taddr,addrtype,(uint8_t *)&vp->spendscript[0],vp->spendlen); + flag++; + break; + default: break;//printf("unexpected script type.%d\n",type); break; + } + if ( n > 0 ) + { + scriptlen = bitcoin_MofNspendscript(rmd160,script,0,vp); + bitcoin_address(symbol,coinaddr,taddr,p2shtype,script,scriptlen); + if ( asmstr != 0 ) + { + sprintf(asmstr,"%d ",m); + for (i=0; isigners[i].pubkey)) > 0 ) + { + init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->signers[i].pubkey,plen); + if ( asmstr != 0 ) + strcat(asmstr," "); + } + else if ( asmstr != 0 ) + strcat(asmstr,"NOPUBKEY "); + sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n); + for (i=0; isigners[i].coinaddr,ispendlen > 0 ) + init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->spendscript,vp->spendlen); + *Mp = m, *nump = n; + return(scriptlen); +} + +int32_t bitcoin_scriptget(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype,int32_t zcash) +{ + int32_t j,n,siglen,plen; uint8_t *p2shscript; + j = n = 0; + *userdatap = 0; + *userdatalenp = *pubkeysizep = *sigsizep = 0; + *hashtypep = LP_sighash(symbol,zcash); + while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) + { + vp->signers[j].siglen = siglen; + memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen); + if ( j == 0 ) + *hashtypep = vp->signers[j].sig[siglen-1]; + else if ( vp->signers[j].sig[siglen-1] != (*hashtypep & (~SIGHASH_FORKID)) ) + { + //printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); + break; + } + (*sigsizep) += siglen; + //printf("sigsize %d [%02x]\n",*sigsizep,vp->signers[j].sig[siglen-1]); + n += (siglen + 1); + j++; + if ( spendtype == 0 && j > 1 ) + spendtype = IGUANA_SCRIPT_MSIG; + } + vp->numsigs = j; + vp->type = spendtype; + if ( j == 0 ) + { + //*userdatalenp = len; + vp->spendlen = len; + return(vp->spendlen); + } + j = 0; + while ( ((plen= scriptsig[n]) == 33 || plen == 65) && j < 16 && plen+n <= len ) + { + memcpy(vp->signers[j].pubkey,&scriptsig[n+1],plen); + calc_rmd160_sha256(vp->signers[j].rmd160,vp->signers[j].pubkey,plen); + if ( j == 0 ) + memcpy(vp->rmd160,vp->signers[j].rmd160,20); + n += (plen + 1); + (*pubkeysizep) += plen; + j++; + } + vp->numpubkeys = j; + *userdatap = &scriptsig[n]; + if ( len > n ) + *userdatalenp = (len - n); + p2shscript = 0; + while ( n < len ) + { + if ( n+2 < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) + { + if ( scriptsig[n] == 0x4c ) + vp->p2shlen = scriptsig[n+1], n += 2; + else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; + //printf("p2sh opcode.%02x %02x %02x scriptlen.%d\n",scriptsig[n],scriptsig[n+1],scriptsig[n+2],vp->p2shlen); + if ( vp->p2shlen < IGUANA_MAXSCRIPTSIZE && n+vp->p2shlen <= len ) + { + p2shscript = &scriptsig[n]; + memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); + n += vp->p2shlen; + vp->type = IGUANA_SCRIPT_P2SH; + } else vp->p2shlen = 0; + } + } + if ( *userdatap == p2shscript ) + *userdatap = 0; + vp->spendlen = iguana_scriptgen(symbol,taddr,pubtype,p2shtype,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,0,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); + return(vp->spendlen); +} + +int32_t _iguana_calcrmd160(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct vin_info *vp) +{ + static uint8_t zero_rmd160[20]; + char hexstr[8192]; uint8_t *script,type; int32_t i,n,m,plen; + if ( vp->N == 0 ) + vp->N = 1; + if ( vp->M == 0 ) + vp->M = 1; + type = IGUANA_SCRIPT_STRANGE; + init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); + //char str[65]; printf("script.(%s).%d in %s len.%d plen.%d spendlen.%d cmp.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen,bitcoin_pubkeylen(&vp->spendscript[1]),vp->spendlen,vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG); + if ( vp->spendlen == 0 ) + { + if ( zero_rmd160[0] == 0 ) + { + calc_rmd160_sha256(zero_rmd160,vp->spendscript,vp->spendlen); + //vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + //calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb + init_hexbytes_noT(hexstr,zero_rmd160,20); + } + memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_NULL); + } + else if ( vp->spendscript[0] == SCRIPT_OP_RETURN ) + type = IGUANA_SCRIPT_OPRETURN; + else if ( vp->spendscript[0] == SCRIPT_OP_DUP && vp->spendscript[1] == SCRIPT_OP_HASH160 && vp->spendscript[2] == 20 && vp->spendscript[vp->spendscript[2]+3] == SCRIPT_OP_EQUALVERIFY && vp->spendscript[vp->spendscript[2]+4] == SCRIPT_OP_CHECKSIG ) + { + //printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d vp->spendlen\n",vp->spendscript[2]+4,vp->spendlen); + // 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac + memcpy(vp->rmd160,&vp->spendscript[3],20); + if ( (plen= vp->spendscript[2]+5) != vp->spendlen ) + { + return(IGUANA_SCRIPT_STRANGE); + /*while ( plen < vp->spendlen ) + if ( vp->spendscript[plen++] != 0x61 ) // nop + return(IGUANA_SCRIPT_STRANGE);*/ + } + return(IGUANA_SCRIPT_76A988AC); + } + // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac + else if ( vp->spendscript[0] == SCRIPT_OP_DUP && (plen= bitcoin_pubkeylen(&vp->spendscript[2])) > 0 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == plen && vp->spendlen == plen+3 ) + { + memcpy(vp->signers[0].pubkey,&vp->spendscript[2],plen); + calc_rmd160_sha256(vp->rmd160,vp->signers[0].pubkey,plen); + //printf("found IGUANA_SCRIPT_76AC\n"); + return(IGUANA_SCRIPT_76AC); + } + else if ( (plen= bitcoin_pubkeylen(&vp->spendscript[1])) > 0 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == plen && vp->spendlen == plen+2 ) + { + memcpy(vp->signers[0].pubkey,&vp->spendscript[1],plen); + calc_rmd160_sha256(vp->rmd160,vp->signers[0].pubkey,plen); + //printf("found IGUANA_SCRIPT_AC\n"); + return(IGUANA_SCRIPT_AC); + } + else if ( vp->spendscript[0] == SCRIPT_OP_HASH160 && vp->spendscript[1] == 0x14 && vp->spendlen == 23 && vp->spendscript[22] == SCRIPT_OP_EQUAL ) + { + memcpy(vp->rmd160,vp->spendscript+2,20); + return(IGUANA_SCRIPT_P2SH); + } + else if ( vp->spendlen > 34 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKMULTISIG && (n= vp->spendscript[vp->spendlen-2]) >= 0x51 && n <= 0x60 && (m= vp->spendscript[0]) >= 0x51 && m <= n ) // m of n multisig + { + m -= 0x50, n -= 0x50; + script = vp->spendscript+1; + for (i=0; isigners[i].pubkey,script,plen); + calc_rmd160_sha256(vp->signers[i].rmd160,vp->signers[i].pubkey,plen); + bitcoin_address(symbol,vp->signers[i].coinaddr,taddr,pubtype,vp->signers[i].pubkey,plen); + } + if ( (int32_t)((long)script - (long)vp->spendscript) == vp->spendlen-2 ) + { + vp->N = n; + vp->M = m; + //printf("M.%d N.%d\n",m,n); + } + calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); + if ( n == 3 ) + { + if ( m == 3 ) + return(IGUANA_SCRIPT_3of3); + else if ( m == 2 ) + return(IGUANA_SCRIPT_2of3); + else if ( m == 1 ) + return(IGUANA_SCRIPT_1of3); + } + else if ( n == 2 ) + { + if ( m == 2 ) + return(IGUANA_SCRIPT_2of2); + else if ( m == 1 ) + return(IGUANA_SCRIPT_1of2); + } + else if ( m == 1 && n == 1 ) + return(IGUANA_SCRIPT_1of1); + //printf("strange msig M.%d of N.%d\n",m,n); + return(IGUANA_SCRIPT_MSIG); + } + else if ( vp->spendlen == vp->spendscript[0]+1 ) + { + //printf("just data.%d\n",vp->spendlen); + memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_DATA); + } + if ( type != IGUANA_SCRIPT_OPRETURN && type != IGUANA_SCRIPT_DATA ) + { + if ( vp->spendlen > 0 && vp->spendlen < sizeof(hexstr)/2-1 ) + { + static FILE *fp; + init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); + //char str[65]; printf("unparsed script.(%s).%d in %s len.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen); + if ( 1 && fp == 0 ) + fp = fopen("unparsed.txt","w"); + if ( fp != 0 ) + fprintf(fp,"%s\n",hexstr), fflush(fp); + } else sprintf(hexstr,"pkscript overflowed %ld\n",(long)sizeof(hexstr)); + } + calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); + return(type); +} + +int32_t iguana_calcrmd160(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,char *asmstr,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence) +{ + int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; + memset(vp,0,sizeof(*vp)); + vp->vin.prev_hash = debugtxid, vp->vin.prev_vout = vout; + vp->spendlen = pk_scriptlen; + vp->vin.sequence = sequence; + memcpy(vp->spendscript,pk_script,pk_scriptlen); + if ( (vp->type= _iguana_calcrmd160(symbol,taddr,pubtype,p2shtype,vp)) >= 0 ) + { + scriptlen = iguana_scriptgen(symbol,taddr,pubtype,p2shtype,&vp->M,&vp->N,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vout); + if ( vp->M == 0 && vp->N == 0 ) + { + vp->M = vp->N = 1; + strcpy(vp->signers[0].coinaddr,vp->coinaddr); + memcpy(vp->signers[0].rmd160,vp->rmd160,20); + } + if ( scriptlen != pk_scriptlen || (scriptlen != 0 && memcmp(script,pk_script,scriptlen) != 0) ) + { + if ( vp->type != IGUANA_SCRIPT_OPRETURN && vp->type != IGUANA_SCRIPT_DATA && vp->type != IGUANA_SCRIPT_STRANGE ) + { + int32_t i; + printf("\n--------------------\n"); + for (i=0; itype,scriptlen,pk_scriptlen); + } + } + } + return(vp->type); +} + +cJSON *bitcoin_txscript(char *asmstr,char **vardata,int32_t numvars) +{ + int32_t i; cJSON *scriptjson,*array; + scriptjson = cJSON_CreateObject(); + if ( asmstr != 0 ) + jaddstr(scriptjson,"asm",asmstr); + jaddnum(scriptjson,"numvars",numvars); + if ( numvars > 0 ) + { + array = cJSON_CreateArray(); + for (i=0; i= 0 ) + { + if ( (n= V.N) == 0 ) + n = 1; + for (i=0; i 0 ) + init_hexbytes_noT(pubkeystr,V.signers[i].pubkey,plen); + else pubkeystr[0] = 0; + jaddistr(pubkeys,pubkeystr); + } + } + return(pubkeys); +} + +void iguana_addscript(cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname) +{ + char *scriptstr,scriptbuf[8192+256]; int32_t maxlen; cJSON *scriptobj; + if ( scriptlen < 0 || scriptlen > IGUANA_MAXSCRIPTSIZE || scriptlen > sizeof(scriptbuf) ) + return; + scriptstr = scriptbuf, maxlen = sizeof(scriptbuf); + init_hexbytes_noT(scriptstr,script,scriptlen); + //if ( strcmp(fieldname,"userdata") == 0 ) + // printf("SCRIPT_USERDATA.(%s)\n",scriptstr); + if ( strcmp(fieldname,"coinbase") == 0 ) + jaddstr(dest,"coinbase",scriptstr); + else + { + scriptobj = cJSON_CreateObject(); + jaddstr(scriptobj,"hex",scriptstr); + iguana_expandscript(scriptstr,maxlen,script,scriptlen); + if ( scriptstr[0] != 0 ) + jaddstr(scriptobj,"asm",scriptstr); + if ( scriptstr != scriptbuf ) + free(scriptstr); + jadd(dest,fieldname,scriptobj); + } +} + +cJSON *iguana_pubkeysjson(uint8_t *pubkeyptrs[],int32_t numpubkeys) +{ + int32_t i,plen; char pubkeystr[256]; cJSON *pubkeysjson = cJSON_CreateArray(); + for (i=0; i 0 ) + init_hexbytes_noT(pubkeystr,pubkeyptrs[i],plen); + else pubkeystr[0] = 0; + jaddistr(pubkeysjson,pubkeystr); + } + return(pubkeysjson); +} + +cJSON *bitcoin_txinput(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys,uint8_t *sig,int32_t siglen) +{ + cJSON *item,*vins; char p2shscriptstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t *script,len=0; + vins = jduplicate(jobj(txobj,"vin")); + jdelete(txobj,"vin"); + item = cJSON_CreateObject(); + if ( sig != 0 && siglen > 0 ) + iguana_addscript(item,sig,siglen,"scriptSig"); + if ( spendscript != 0 && spendscript > 0 ) + { + iguana_addscript(item,spendscript,spendlen,"scriptPubKey"); + script = spendscript, len = spendlen; + } + else if ( redeemscript != 0 && p2shlen > 0 ) + { + init_hexbytes_noT(p2shscriptstr,redeemscript,p2shlen); + jaddstr(item,"redeemScript",p2shscriptstr); + script = redeemscript, len = p2shlen; + } else script = 0; + if ( script != 0 && numpubkeys == 0 ) + jadd(item,"pubkeys",iguana_scriptpubkeys(symbol,taddr,pubtype,p2shtype,script,len,txid,vout,sequenceid)); + else if ( pubkeys != 0 && numpubkeys > 0 ) + jadd(item,"pubkeys",iguana_pubkeysjson(pubkeys,numpubkeys)); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + jaddnum(item,"sequence",sequenceid); + jaddi(vins,item); + jadd(txobj,"vin",vins); + //printf("addvin -> (%s)\n",jprint(txobj,0)); + return(txobj); +} + +cJSON *bitcoin_txcreate(char *symbol,int32_t isPoS,int64_t locktime,uint32_t txversion,uint32_t timestamp) +{ + cJSON *json = cJSON_CreateObject(); + jaddnum(json,"version",txversion); + if ( locktime == 0 && strcmp(symbol,"KMD") == 0 ) + locktime = (uint32_t)time(NULL); + jaddnum(json,"locktime",locktime); + if ( isPoS != 0 ) + jaddnum(json,"timestamp",timestamp == 0 ? time(NULL) : timestamp); + jadd(json,"vin",cJSON_CreateArray()); + jadd(json,"vout",cJSON_CreateArray()); + return(json); +} + +cJSON *bitcoin_txoutput(cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis) +{ + char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout")); + jdelete(txobj,"vout"); + item = cJSON_CreateObject(); + jadd64bits(item,"satoshis",satoshis); + skey = cJSON_CreateObject(); + hexstr = malloc(len*2 + 1); + init_hexbytes_noT(hexstr,paymentscript,len); + jaddstr(skey,"hex",hexstr); + //printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0)); + free(hexstr); + jadd(item,"scriptPubKey",skey); + jaddi(vouts,item); + jadd(txobj,"vout",vouts); + return(txobj); +} + +int32_t bitcoin_txaddspend(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,cJSON *txobj,char *destaddress,uint64_t satoshis) +{ + uint8_t outputscript[128],addrtype,rmd160[20]; int32_t scriptlen; + if ( bitcoin_validaddress(symbol,taddr,pubtype,p2shtype,destaddress) == 0 && satoshis != 0 ) + { + bitcoin_addr2rmd160(symbol,taddr,&addrtype,rmd160,destaddress); + scriptlen = bitcoin_standardspend(outputscript,0,rmd160); + bitcoin_txoutput(txobj,outputscript,scriptlen,satoshis); + return(0); + } else return(-1); +} + +int32_t iguana_vinparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg) +{ + int32_t p2shlen,len = 0; uint32_t tmp; + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); + //char str[65]; printf("prev_hash.(%s) v%d\n",bits256_str(str,msg->prev_hash),msg->prev_vout); + if ( rwflag == 1 ) + { + tmp = msg->scriptlen + msg->userdatalen + msg->p2shlen; + if ( msg->p2shlen != 0 ) + { + if ( msg->p2shlen < 76 ) + tmp++; + else if ( msg->p2shlen < 0x100 ) + tmp += 2; + else tmp += 3; + } + } + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + if ( rwflag == 0 ) + { + /*if ( msg->p2shlen != 0 ) + { + if ( msg->p2shlen < 76 ) + tmp++; + else if ( msg->p2shlen < 0x100 ) + tmp += 2; + else tmp += 3; + }*/ + msg->scriptlen = tmp; + } + if ( msg->scriptlen > IGUANA_MAXSCRIPTSIZE ) + { + printf("iguana_vinparse illegal scriptlen.%d\n",msg->scriptlen); + return(-1); + } + //printf("len.%d scriptlen.%d user.%d p2sh.%d\n",len,msg->scriptlen,msg->userdatalen,msg->p2shlen); + if ( rwflag == 0 ) + { + msg->vinscript = &serialized[len]; + len += msg->scriptlen; + } + else + { + if ( msg->vinscript != 0 && msg->scriptlen > 0 ) + memcpy(&serialized[len],msg->vinscript,msg->scriptlen), len += msg->scriptlen; // pubkeys here + if ( msg->userdatalen > 0 && msg->userdata != 0 ) + { + //printf("userdata.%d scriptlen.%d\n",msg->userdatalen,msg->scriptlen); + memcpy(&serialized[len],msg->userdata,msg->userdatalen); + len += msg->userdatalen; + } + if ( (p2shlen= msg->p2shlen) > 0 && msg->redeemscript != 0 ) + { + if ( p2shlen < 76 ) + serialized[len++] = p2shlen; + else if ( p2shlen <= 0xff ) + { + serialized[len++] = 0x4c; + serialized[len++] = p2shlen; + } + else if ( p2shlen <= 0xffff ) + { + serialized[len++] = 0x4d; + serialized[len++] = (p2shlen & 0xff); + serialized[len++] = ((p2shlen >> 8) & 0xff); + } else return(-1); + memcpy(&serialized[len],msg->redeemscript,p2shlen), len += p2shlen; + if ( (0) ) + { + int32_t j; + for (j=0; jredeemscript[j]); + printf(" p2shlen.%d %x\n",p2shlen,p2shlen); + } + } + } + //printf("sequence starts.%d %08x\n",len,*(int32_t *)&serialized[len]); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); + if ( (0) ) + { + int32_t i; char str[65]; + for (i=0; isequence,bits256_str(str,msg->prev_hash),msg->prev_vout,msg->vinscript,msg->scriptlen,rwflag); + } + return(len); +} + +int32_t iguana_voutparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvout *msg) +{ + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value),&msg->value); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->pk_scriptlen); + if ( msg->pk_scriptlen > IGUANA_MAXSCRIPTSIZE ) + { + printf("iguana_voutparse illegal scriptlen.%d\n",msg->pk_scriptlen); + return(-1); + } + if ( rwflag == 0 ) + msg->pk_script = &serialized[len]; + else if ( msg->pk_scriptlen > 0 ) + { + memcpy(&serialized[len],msg->pk_script,msg->pk_scriptlen); + if ( (0) ) + { + int32_t i; + for (i=0; ipk_scriptlen; i++) + printf("%02x",msg->pk_script[i]); + printf(" [%p] scriptlen.%d rwflag.%d %.8f\n",msg->pk_script,msg->pk_scriptlen,rwflag,dstr(msg->value)); + } + } // else serialized[len++] = 0; + len += msg->pk_scriptlen; + return(len); +} + +cJSON *iguana_vinjson(struct iguana_msgvin *vin,bits256 sigtxid) +{ + char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject(); + vout = vin->prev_vout; + jaddnum(json,"sequence",vin->sequence); + if ( vout < 0 && bits256_nonz(vin->prev_hash) == 0 ) + iguana_addscript(json,vin->vinscript,vin->scriptlen,"coinbase"); + else + { + jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); + jaddnum(json,"vout",vout); + if ( bits256_nonz(sigtxid) != 0 ) + jaddbits256(json,"sigtxid",sigtxid); + if ( vin->scriptlen > 0 && vin->vinscript != 0 ) // sigs + iguana_addscript(json,vin->vinscript,vin->scriptlen,"scriptSig"); + if ( vin->userdatalen > 0 && vin->userdata != 0 ) + iguana_addscript(json,vin->userdata,vin->userdatalen,"userdata"); + if ( vin->p2shlen > 0 && vin->redeemscript != 0 ) + iguana_addscript(json,vin->redeemscript,vin->p2shlen,"redeemScript"); + if ( vin->spendlen > 0 && vin->spendscript != 0 ) + iguana_addscript(json,vin->spendscript,vin->spendlen,"scriptPubKey"); + } + return(json); +} + +int32_t iguana_parsehexstr(uint8_t **destp,uint16_t *lenp,uint8_t *dest2,int32_t *len2p,uint8_t *serialized,char *hexstr) +{ + int32_t n; + n = (int32_t)strlen(hexstr) >> 1; + //printf("addhex.(%s) %d\n",hexstr,n); + if ( serialized == 0 ) + { + if ( (serialized= *destp) == 0 ) + printf("iguana_parsehexstr null serialized and destp\n"); + } + if ( serialized != 0 ) + { + decode_hex(serialized,n,hexstr); + *destp = serialized; + *lenp = n; + if ( dest2 != 0 && len2p != 0 ) + { + *len2p = n; + memcpy(dest2,serialized,n); + } + } + return(n); +} + +int32_t iguana_scriptnum(uint8_t opcode) +{ + if ( opcode == 0x00 ) + return(0); + else if ( opcode >= 0x51 && opcode < 0x60 ) + return(opcode - 0x50); + else return(-1); +} + +int32_t iguana_parsevinobj(uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V) +{ + //struct iguana_outpoint outpt; struct iguana_waddress *waddr; struct iguana_waccount *wacct; + uint8_t lastbyte; uint32_t tmp=0; int32_t i,n,starti,suppress_pubkeys,siglen,plen,m,endi,rwflag=1,len = 0; char *userdata=0,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; + //printf("PARSEVIN.(%s) vin.%p\n",jprint(vinobj,0),vin); + if ( V == 0 ) + memset(vin,0,sizeof(*vin)); + vin->prev_vout = -1; + suppress_pubkeys = juint(vinobj,"suppress"); + if ( jobj(vinobj,"sequence") != 0 ) + vin->sequence = juint(vinobj,"sequence"); + else vin->sequence = 0xffffffff; + if ( (hexstr= jstr(vinobj,"coinbase")) == 0 ) + { + vin->prev_hash = jbits256(vinobj,"txid"); + //char str[65]; printf("vin->prev_hash.(%s)\n",bits256_str(str,vin->prev_hash)); + vin->prev_vout = jint(vinobj,"vout"); + if ( (scriptjson= jobj(vinobj,"scriptSig")) != 0 ) + hexstr = jstr(scriptjson,"hex"); + if ( ((spendstr= jstr(vinobj,"scriptPub")) == 0 && (spendstr= jstr(vinobj,"scriptPubKey")) == 0) || is_hexstr(spendstr,(int32_t)strlen(spendstr)) <= 0 ) + { + if ( (obj= jobj(vinobj,"scriptPub")) != 0 || (obj= jobj(vinobj,"scriptPubKey")) != 0 ) + { + spendstr = jstr(obj,"hex"); + if ( spendstr[0] != 0 ) + { + lastbyte = _decode_hex(&spendstr[strlen(spendstr)-2]); + //if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) + // need_op0 = 1; + if ( V != 0 ) + { + V->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(V->spendscript,V->spendlen,spendstr); + } + } + } + } + if ( (redeemstr= jstr(vinobj,"redeemScript")) == 0 || is_hexstr(redeemstr,(int32_t)strlen(redeemstr)) <= 0 ) + { + if ( (obj= jobj(vinobj,"redeemScript")) != 0 ) + { + redeemstr = jstr(obj,"hex"); + lastbyte = _decode_hex(&redeemstr[strlen(redeemstr)-2]); + //if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) + // need_op0 = 1; + } + } + if ( (userdata= jstr(vinobj,"userdata")) == 0 || is_hexstr(userdata,(int32_t)strlen(userdata)) <= 0 ) + { + if ( (obj= jobj(vinobj,"userdata")) != 0 ) + userdata = jstr(obj,"hex"); + } + } + //char str[65]; printf("rw.%d prevhash.(%s)\n",rwflag,bits256_str(str,vin->prev_hash)); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(vin->prev_hash),vin->prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->prev_vout),&vin->prev_vout); + if ( V != 0 ) + { + V->suppress_pubkeys = suppress_pubkeys; + if ( vin->vinscript == 0 && V->spendlen == 0 ) + { + /*if ( iguana_RTunspentindfind(coin,&outpt,V->coinaddr,spendscript,&spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1,0) == 0 ) + { + V->unspentind = outpt.unspentind; + if ( V->coinaddr[0] != 0 && (waddr= iguana_waddresssearch(&wacct,V->coinaddr)) != 0 ) + { + plen = bitcoin_pubkeylen(waddr->pubkey); + for (z=0; zsigners[0].pubkey[z] = waddr->pubkey[z]; + } + //printf("V %.8f (%s) spendscript.[%d]\n",dstr(V->amount),V->coinaddr,V->spendlen); + } + if ( spendlen != 0 && V->spendlen == 0 ) + { + V->spendlen = spendlen; + memcpy(V->spendscript,spendscript,spendlen); + }*/ + } + } + tmp = IGUANA_MAXSCRIPTSIZE; + starti = len; + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + endi = len; + //printf("rwflag.%d len.%d tmp.%d\n",rwflag,len,tmp); + //if ( need_op0 != 0 ) + // serialized[len++] = 0; // hack for bug for bug backward compatibility + if ( hexstr != 0 ) + { + n = (int32_t)strlen(hexstr) >> 1; + //printf("add.(%s) offset.%d\n",hexstr,len); + vin->vinscript = &serialized[len]; + decode_hex(&serialized[len],n,hexstr); + vin->scriptlen = n;// + need_op0; + if ( V != 0 ) + { + i = m = 0; + while ( m < n ) + { + siglen = serialized[len + m++]; + //if ( i == 0 && m == 1 && siglen == 0 ) // multisig backward compatible + // continue; + if ( ((serialized[len + m + siglen - 1] & ~SIGHASH_FORKID) & 0xff) == SIGHASH_ALL ) + memcpy(V->signers[i++].sig,&serialized[len + m],siglen); + if ( (0) ) + { + int32_t j; + for (j=0; jvinscript != 0 ) + { + /*if ( vin->vinscript == 0 ) + { + vin->vinscript = serialized; + vin->vinscript[0] = 0; + vin->scriptlen = 1; + }*/ + for (i=0; i> 1) > 0 ) + { + if ( V != 0 ) + { + memcpy(V->signers[i].pubkey,&vin->vinscript[vin->scriptlen],plen); + if ( V->spendlen == 35 && V->spendscript[0] == 33 && V->spendscript[34] == 0xac ) + suppress_pubkeys = 1; + } + if ( suppress_pubkeys == 0 ) + { + printf("addpub.(%s)\n",pubkeystr); + vin->vinscript[vin->scriptlen++] = plen; + decode_hex(&vin->vinscript[vin->scriptlen],plen,pubkeystr); + vin->scriptlen += plen; + serialized[len++] = plen; + memcpy(&serialized[len],&vin->vinscript[vin->scriptlen],plen), len += plen; + } + } + } + } + //printf("userdata len.%d: ",len); + if ( userdata != 0 ) + { + n = iguana_parsehexstr(&vin->userdata,&vin->userdatalen,V!=0?V->userdata:0,V!=0?&V->userdatalen:0,&serialized[len],userdata); + //printf("parsed userdata.%d\n",n); + len += n; + } + //printf("redeemlen.%d: ",len); + if ( redeemstr != 0 ) + { + n = (int32_t)strlen(redeemstr) >> 1; + if ( n < 76 ) + serialized[len++] = n; + else if ( n <= 0xff ) + { + serialized[len++] = 0x4c; + serialized[len++] = n; + } + else + { + serialized[len++] = 0x4d; + serialized[len++] = n & 0xff; + serialized[len++] = (n >> 8) & 0xff; + } + n = iguana_parsehexstr(&vin->redeemscript,&vin->p2shlen,V!=0?V->p2shscript:0,V!=0?&V->p2shlen:0,&serialized[len],redeemstr); + len += n; + if ( vin->redeemscript[vin->p2shlen-1] == SCRIPT_OP_CHECKMULTISIG ) + { + V->M = iguana_scriptnum(vin->redeemscript[0]); + V->N = iguana_scriptnum(vin->redeemscript[vin->p2shlen-2]); + } + } + tmp = (len - endi); + if ( tmp < 0xfd ) + { + serialized[starti] = tmp; + for (i=starti+1; i> 8) & 0xff); + } + //printf("len.%d tmp.%d output sequence.[%d] <- %x\n",len,tmp,len,vin->sequence); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->sequence),&vin->sequence); + if ( spendstr != 0 ) + { + if ( V != 0 ) + { + if ( V->spendlen == 0 ) + { + V->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(V->spendscript,V->spendlen,spendstr); + } + if ( vin->spendscript == 0 ) + vin->spendscript = V->spendscript; + } + if ( vin->spendlen == 0 && vin->spendscript != 0 ) + { + vin->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(vin->spendscript,vin->spendlen,spendstr); + } + //printf("serialized.%p len.%d\n",serialized,len); + //n = iguana_parsehexstr(&vin->spendscript,&vin->spendlen,V!=0?V->spendscript:0,V!=0?&V->spendlen:0,&serialized[len],spendstr); + //len += n; + } + return(len); +} + +int32_t iguana_parsevoutobj(uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj) +{ + int32_t n,len = 0,rwflag = 1; cJSON *skey; char *hexstr; + memset(vout,0,sizeof(*vout)); + if ( jobj(voutobj,"satoshis") != 0 ) + vout->value = j64bits(voutobj,"satoshis"); + else vout->value = jdouble(voutobj,"value") * SATOSHIDEN; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vout->value),&vout->value); + if ( (skey= jobj(voutobj,"scriptPubKey")) != 0 ) + { + if ( (hexstr= jstr(skey,"hex")) != 0 ) + { + n = (int32_t)strlen(hexstr) >> 1; + vout->pk_scriptlen = n; + len += iguana_rwvarint32(rwflag,&serialized[len],&vout->pk_scriptlen); + decode_hex(&serialized[len],n,hexstr); + vout->pk_script = &serialized[len]; + len += n; + } // else serialized[len++] = 0; + } //else serialized[len++] = 0; + return(len); +} + +cJSON *iguana_voutjson(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,struct iguana_msgvout *vout,int32_t txi,bits256 txid) +{ + // 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG + char scriptstr[IGUANA_MAXSCRIPTSIZE+1]; int32_t i,m,n,scriptlen,asmtype; struct vin_info *vp; + uint8_t space[8192]; cJSON *addrs,*skey,*json = cJSON_CreateObject(); + vp = calloc(1,sizeof(*vp)); + jadd64bits(json,"satoshis",vout->value); + jaddnum(json,"value",dstr(vout->value)); + jaddnum(json,"n",txi); + //"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]} + if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) ) + { + memset(vp,0,sizeof(*vp)); + if ( (asmtype= iguana_calcrmd160(symbol,taddr,pubtype,p2shtype,0,vp,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 ) + { + skey = cJSON_CreateObject(); + scriptlen = iguana_scriptgen(symbol,taddr,pubtype,p2shtype,&m,&n,vp->coinaddr,space,0,vp->rmd160,asmtype,vp,txi); + //if ( asmstr[0] != 0 ) + // jaddstr(skey,"asm",asmstr); + addrs = cJSON_CreateArray(); + if ( vp->N == 1 ) + { + if ( asmtype == 2 ) + { + jaddnum(skey,"reqSigs",1); + jaddstr(skey,"type","pubkeyhash"); + } + if ( vp->coinaddr[0] != 0 ) + jaddistr(addrs,vp->coinaddr); + } + else + { + jaddnum(skey,"reqSigs",vp->M); + for (i=0; iN; i++) + { + //btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey); + jaddistr(addrs,vp->signers[i].coinaddr); + } + } + jadd(skey,"addresses",addrs); + init_hexbytes_noT(scriptstr,vout->pk_script,vout->pk_scriptlen); + if ( scriptstr[0] != 0 ) + jaddstr(skey,"hex",scriptstr); + jadd(json,"scriptPubKey",skey); + } + } + free(vp); + return(json); +} + +void iguana_vinobjset(struct iguana_msgvin *vin,cJSON *item,uint8_t *spendscript,int32_t maxsize) +{ + char *redeemstr,*hexstr=0; cJSON *sobj; + if ( (redeemstr= jstr(item,"redeemScript")) != 0 && is_hexstr(redeemstr,0) > 0 ) + { + vin->p2shlen = (int32_t)strlen(redeemstr) >> 1; + vin->spendlen = vin->p2shlen; + vin->redeemscript = calloc(1,vin->p2shlen); + decode_hex(vin->redeemscript,vin->p2shlen,redeemstr); + hexstr = redeemstr; + //printf("VINOBJSET.(%s)\n",redeemstr); + } + else if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 && (vin->spendlen == 0 || vin->spendscript == 0) ) + { + vin->spendlen = (int32_t)strlen(hexstr) >> 1; + } + if ( hexstr != 0 && vin->spendlen != 0 ) + { + if ( vin->spendlen < maxsize ) + { + if ( vin->spendscript == 0 ) + vin->spendscript = spendscript; + decode_hex(vin->spendscript,vin->spendlen,hexstr); + } + } +} + +int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout) +{ + bits256 array_txid; cJSON *item; int32_t array_vout,i,n = cJSON_GetArraySize(vinarray); + for (i=0; ivins,dest.tx_in * sizeof(*dest.vins)); + memcpy(dest.vouts,msgtx->vouts,dest.tx_out * sizeof(*dest.vouts)); + memset(sigtxid.bytes,0,sizeof(sigtxid)); + if ( strcmp(symbol,"SBTC") == 0 ) + sbtcflag = 1; + if ( ((hashtype & ~SIGHASH_FORKID) & 0xff) != SIGHASH_ALL ) + { + printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); + return(sigtxid); + } + if ( (hashtype & SIGHASH_FORKID) == 0 || sbtcflag != 0 ) + { + for (i=0; i 0 ) + { +#ifdef BTC2_VERSION + if ( height >= BTC2_HARDFORK_HEIGHT ) + hashtype |= (0x777 << 20); +#endif + len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); + if ( sbtcflag != 0 ) + { + serialized[len++] = 4; + memcpy(&serialized[len],"sbtc",4); + len += 4; + } + } + revsigtxid = bits256_calctxid(symbol,serialized,len); + for (i=0; i(scriptCode); + ss << amount; + ss << txTo.vin[nIn].nSequence; + // Outputs (none/one/all, depending on flags) + ss << hashOutputs; + // Locktime + ss << txTo.nLockTime; + // Sighash type + ss << ((GetForkId() << 8) | nHashType); + return ss.GetHash(); + } + Computation of midstates: + + uint256 GetPrevoutHash(const CTransaction &txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].prevout; + } + + return ss.GetHash(); + } + + uint256 GetSequenceHash(const CTransaction &txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].nSequence; + } + + return ss.GetHash(); + } + + uint256 GetOutputsHash(const CTransaction &txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vout.size(); n++) { + ss << txTo.vout[n]; + } + + return ss.GetHash(); + } + */ + bits256 prevouthash,seqhash,outputhash; + for (i=len=0; i sighash.fc55acc3666c43b8f75908ca06ea2d343cd09eb846f14c5d7d0748a11e081a9d*/ + len = 0; + len += iguana_rwnum(1,&serialized[len],sizeof(dest.version),&dest.version); + len += iguana_rwbignum(1,&serialized[len],sizeof(prevouthash),prevouthash.bytes); + len += iguana_rwbignum(1,&serialized[len],sizeof(seqhash),seqhash.bytes); + len += iguana_rwbignum(1,&serialized[len],sizeof(dest.vins[vini].prev_hash),dest.vins[vini].prev_hash.bytes); + len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[vini].prev_vout),&dest.vins[vini].prev_vout); + serialized[len++] = spendlen; + memcpy(&serialized[len],spendscript,spendlen), len += spendlen; + len += iguana_rwnum(1,&serialized[len],sizeof(spendamount),&spendamount); + len += iguana_rwnum(1,&serialized[len],sizeof(dest.vins[vini].sequence),&dest.vins[vini].sequence); + len += iguana_rwbignum(1,&serialized[len],sizeof(outputhash),outputhash.bytes); + len += iguana_rwnum(1,&serialized[len],sizeof(dest.lock_time),&dest.lock_time); + len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); + //for (i=0; ivpub_old),&msg->vpub_old); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->vpub_new),&msg->vpub_new); + + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->anchor),msg->anchor.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->nullifiers[0]),msg->nullifiers[0].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->nullifiers[1]),msg->nullifiers[1].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->commitments[0]),msg->commitments[0].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->commitments[1]),msg->commitments[1].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->ephemeralkey),msg->ephemeralkey.bytes); + if ( rwflag == 1 ) + memcpy(&serialized[len],msg->ciphertexts,sizeof(msg->ciphertexts)); + else memcpy(msg->ciphertexts,&serialized[len],sizeof(msg->ciphertexts)); + len += sizeof(msg->ciphertexts); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->randomseed),msg->randomseed.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[0]),msg->vmacs[0].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[1]),msg->vmacs[1].bytes); + if ( rwflag == 1 ) + memcpy(&serialized[len],msg->zkproof,sizeof(msg->zkproof)); + else memcpy(msg->zkproof,&serialized[len],sizeof(msg->zkproof)); + len += sizeof(msg->zkproof); + return(len); +} + +uint32_t LP_sighash(char *symbol,int32_t zcash) +{ + uint32_t sighash; + sighash = SIGHASH_ALL; + if ( zcash == LP_IS_BITCOINCASH ) + sighash |= SIGHASH_FORKID; + else if ( zcash == LP_IS_BITCOINGOLD ) + { + sighash |= SIGHASH_FORKID; + sighash |= (LP_IS_BITCOINGOLD << 8); + } + else if ( strcmp(symbol,"SBTC") == 0 ) + sighash |= SIGHASH_FORKID; + return(sighash); +} + +int32_t iguana_rwmsgtx(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) +{ + int32_t i,j,n,segtxlen,len = 0,extraused=0; uint32_t tmp,segitems; uint8_t *segtx=0,segwitflag=0,spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; uint64_t spendamount; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; + + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); + if ( json != 0 ) + { + jaddnum(json,"version",msg->version); + vinarray = cJSON_CreateArray(); + voutarray = cJSON_CreateArray(); + if ( rwflag == 0 ) + sigser = calloc(1,maxsize*2); + //printf("json.%p array.%p sigser.%p\n",json,vinarray,sigser); + } + //printf("version.%d\n",msg->version); + if ( isPoS != 0 ) + { + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); + //char str[65]; printf("version.%d timestamp.%08x %u %s\n",msg->version,msg->timestamp,msg->timestamp,utc_str(str,msg->timestamp)); + if ( json != 0 ) + jaddnum(json,"timestamp",msg->timestamp); + } + if ( rwflag == 0 && zcash == 0 ) + { + /* + normal: nVersion|txins|txouts|nLockTime. + segwit + nVersion|marker|flag|txins|txouts|witness|nLockTime + Format of nVersion, txins, txouts, and nLockTime are same as the original format + The marker MUST be 0x00 + The flag MUST be 0x01 + */ + if ( serialized[len] == 0x00 && (segwitflag= serialized[len+1]) == 0x01 ) + { + len += 2; + //printf("SEGWIT transaction\n"); + } + } + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); + if ( rwflag == 0 ) + { + if ( msg->vins == 0 ) + { + if ( sizeof(struct iguana_msgvin)*msg->tx_in > extralen ) + { + printf("(size.%d * tx_in.%d) > extralen.%d\n",(int32_t)sizeof(struct iguana_msgvin),msg->tx_in,extralen); + return(-1); + } + msg->vins = (struct iguana_msgvin *)extraspace; + extraused += (sizeof(struct iguana_msgvin) * msg->tx_in); + } else printf("unexpected non-null msg->vins.%p\n",msg->vins); + memset(msg->vins,0,sizeof(struct iguana_msgvin) * msg->tx_in); + } + for (i=0; itx_in; i++) + { + //printf("vin.%d starts offset.%d numvins.%d\n",i,len,msg->tx_in); + if ( vins != 0 && jitem(vins,i) != 0 ) + iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); + if ( (n= iguana_vinparse(rwflag,&serialized[len],&msg->vins[i])) < 0 ) + return(-1); + //printf("serialized vin.[%02x %02x %02x]\n",serialized[len],serialized[len+1],serialized[len+2]); + if ( msg->vins[i].spendscript == spendscript ) + msg->vins[i].spendscript = 0; + //printf("vin.%d n.%d len.%d\n",i,n,len); + len += n; + if ( len > maxsize ) + { + printf("invalid tx_in.%d len.%d vs maxsize.%d\n",msg->tx_in,len,maxsize); + return(-1); + } + } + //for (i=-3; i<7; i++) + // printf("%02x",serialized[len+i]); + //printf(" prev 3 bytes before tx_out rw.%d\n",rwflag); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); + if ( rwflag == 0 ) + { + if ( msg->vouts == 0 ) + { + if ( (extraused & 0xf) != 0 ) + extraused += 0xf - (extraused & 0xf); + if ( extraused + sizeof(struct iguana_msgvout)*msg->tx_out > extralen ) + { + printf("extraused.%d + tx_out.%d > extralen.%d\n",extraused,msg->tx_out,extralen); + return(-1); + } + msg->vouts = (struct iguana_msgvout *)&extraspace[extraused]; + extraused += (sizeof(struct iguana_msgvout) * msg->tx_out); + } else printf("unexpected non-null msg->vouts %p\n",msg->vouts); + memset(msg->vouts,0,sizeof(struct iguana_msgvout) * msg->tx_out); + } + for (i=0; itx_out; i++) + { + //printf("rwflag.%d vout.%d starts %d numvouts.%d\n",rwflag,i,len,msg->tx_out); + if ( (n= iguana_voutparse(rwflag,&serialized[len],&msg->vouts[i])) < 0 ) + return(-1); + len += n; + if ( len > maxsize ) + { + printf("invalidC tx_out.%d of %d len.%d vs maxsize.%d n.%d\n",i,msg->tx_out,len,maxsize,n); + return(-1); + } + if ( voutarray != 0 ) + jaddi(voutarray,iguana_voutjson(symbol,taddr,pubtype,p2shtype,&msg->vouts[i],i,*txidp)); + } + if ( segwitflag != 0 ) + { + segtxlen = len - 2 + sizeof(msg->lock_time); + segtx = malloc(segtxlen); + memcpy(segtx,serialized,sizeof(int32_t)); + memcpy(&segtx[sizeof(int32_t)],&serialized[sizeof(int32_t)+2],len-2-sizeof(int32_t)); + + //printf("tx_out %d, tx_in %d %02x %02x %02x\n",msg->tx_out,msg->tx_in,serialized[len],serialized[len+1],serialized[len+2]); + if ( rwflag != 0 ) + printf("unsupported rwflag.%d when segwitflag\n",rwflag); + else + { + for (i=0; itx_in; i++) + { + len += iguana_rwvarint32(rwflag,&serialized[len],&segitems); + //printf("vini.%d (%d:",i,segitems); + for (j=0; j= maxsize ) + { + printf("vini.%d of %d, j.%d of segitems.%d overflowed %d+%d >= max.%d\n",i,msg->tx_in,j,segitems,len,tmp,maxsize); + break; + } else len += tmp; + } + //printf("), "); + } + memcpy(&segtx[segtxlen-sizeof(int32_t)],&serialized[len],sizeof(int32_t)); + *txidp = bits256_calctxid(symbol,segtx,segtxlen); + free(segtx); + //char str[65]; printf("witness sum %d vs max.%d txid %s\n",len,maxsize,bits256_str(str,txid)); + } + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + //printf("lock_time.%08x len.%d\n",msg->lock_time,len); + if ( zcash == LP_IS_ZCASHPROTOCOL && msg->version > 1 ) + { + uint32_t numjoinsplits; struct iguana_msgjoinsplit joinsplit; uint8_t joinsplitpubkey[33],joinsplitsig[64]; + len += iguana_rwvarint32(rwflag,&serialized[len],&numjoinsplits); + if ( numjoinsplits > 0 ) + { + for (i=0; itx_in; i++) + { + memset(sigtxid.bytes,0,sizeof(sigtxid)); + if ( vins != 0 && jitem(vins,i) != 0 ) + { + uint32_t sighash; + iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); + sighash = LP_sighash(symbol,zcash); + spendamount = LP_outpoint_amount(symbol,msg->vins[i].prev_hash,msg->vins[i].prev_vout); + sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,spendamount,sighash,vpnstr,suppress_pubkeys,zcash); + //printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); + if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) + jaddi(vinarray,iguana_vinjson(&msg->vins[i],sigtxid)); + if ( msg->vins[i].spendscript == spendscript ) + msg->vins[i].spendscript = 0; + } else if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) + jaddi(vinarray,iguana_vinjson(&msg->vins[i],sigtxid)); + } + free(sigser); + jadd(json,"vin",vinarray); + msg->tx_in = cJSON_GetArraySize(vinarray); + jaddnum(json,"numvins",msg->tx_in); + } + if ( voutarray != 0 ) + { + jadd(json,"vout",voutarray); + jaddnum(json,"numvouts",msg->tx_out); + } + if ( segwitflag == 0 ) + *txidp = bits256_calctxid(symbol,txstart,len); + if ( json != 0 ) + { + jaddnum(json,"locktime",msg->lock_time); + jaddnum(json,"size",len); + jaddbits256(json,"txid",*txidp); + //printf("TX.(%s) %p\n",jprint(json,0),json); + } + msg->allocsize = len; + return(len); +} + +bits256 iguana_parsetxobj(char *symbol,uint8_t isPoS,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V) +{ + int32_t i,n,numvins,numvouts,len = 0,rwflag=1; cJSON *array=0; bits256 txid; char vpnstr[64]; + memset(&txid,0,sizeof(txid)); + memset(msg,0,sizeof(*msg)); + *txstartp = 0; + if ( txobj == 0 ) + return(txid); + vpnstr[0] = 0; + if ( (msg->version= juint(txobj,"version")) == 0 ) + msg->version = 1; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); + if ( isPoS != 0 ) + { + if ( (msg->timestamp= juint(txobj,"timestamp")) == 0 ) + msg->timestamp = (uint32_t)time(NULL); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); + } + if ( (array= jarray(&numvins,txobj,"vin")) != 0 ) + { + msg->tx_in = numvins; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); + if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) + return(txid); + maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); + msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; + memset(msg->vins,0,sizeof(struct iguana_msgvin) * msg->tx_in); + if ( msg->tx_in > 0 && msg->tx_in*sizeof(struct iguana_msgvin) < maxsize ) + { + for (i=0; itx_in; i++) + { + n = iguana_parsevinobj(&serialized[len],maxsize,&msg->vins[i],jitem(array,i),V!=0?&V[i]:0); + //for (j=0; j<8; j++) + // printf("%02x",serialized[len+j]); + //char str[65]; printf(" <- vinobj.%d starts offset.%d %s\n",i,len,bits256_str(str,msg->vins[i].prev_hash)); + len += n; + } + } + } + if ( (array= jarray(&numvouts,txobj,"vout")) != 0 ) + { + msg->tx_out = numvouts; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); + if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) + return(txid); + maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); + msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; + memset(msg->vouts,0,sizeof(struct iguana_msgvout) * msg->tx_out); + if ( msg->tx_out > 0 && msg->tx_out*sizeof(struct iguana_msgvout) < maxsize ) + { + for (i=0; itx_out; i++) + { + //printf("parsetxobj parsevout.%d starts %d\n",i,len); + len += iguana_parsevoutobj(&serialized[len],maxsize,&msg->vouts[i],jitem(array,i)); + } + } + } + msg->lock_time = jint(txobj,"locktime"); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + //msg->txid = jbits256(txobj,"txid"); + *txstartp = 0; + msg->allocsize = len; + msg->txid = txid = bits256_calctxid(symbol,serialized,len); + return(txid); +} + +char *iguana_rawtxbytes(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys,int32_t zcash) +{ + int32_t n; char *txbytes = 0,vpnstr[64]; uint8_t *serialized; + serialized = malloc(IGUANA_MAXPACKETSIZE); + vpnstr[0] = 0; + //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); + if ( (n= iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr,0,0,0,suppress_pubkeys,zcash)) > 0 ) + { + txbytes = malloc(n*2+1); + init_hexbytes_noT(txbytes,serialized,n); + } + free(serialized); + return(txbytes); +} + +char *bitcoin_json2hex(char *symbol,uint8_t isPoS,bits256 *txidp,cJSON *txjson,struct vin_info *V) +{ + int32_t txstart; uint8_t *serialized; struct iguana_msgtx msgtx; char *txbytes = 0; + if ( txjson == 0 ) + { + memset(txidp,0,sizeof(*txidp)); + return(0); + } + serialized = malloc(IGUANA_MAXPACKETSIZE*1.5); + *txidp = iguana_parsetxobj(symbol,isPoS,&txstart,serialized,IGUANA_MAXPACKETSIZE*1.5,&msgtx,txjson,V); + if ( msgtx.allocsize > 0 ) + { + txbytes = malloc(msgtx.allocsize*2 + 1); + init_hexbytes_noT(txbytes,&serialized[txstart],msgtx.allocsize); + } else printf("bitcoin_txtest: zero msgtx allocsize.(%s)\n",jprint(txjson,0)); + free(serialized); + return(txbytes); +} + +cJSON *bitcoin_data2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash) +{ + int32_t n; char vpnstr[64]; struct iguana_msgtx M; cJSON *txobj; + if ( serialized == 0 ) + return(0); + txobj = cJSON_CreateObject(); + if ( msgtx == 0 ) + msgtx = &M; + memset(msgtx,0,sizeof(M)); + vpnstr[0] = 0; + memset(txidp,0,sizeof(*txidp)); + if ( (n= iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,txobj,serialized,len,msgtx,txidp,vpnstr,extraspace,extralen,vins,suppress_pubkeys,zcash)) <= 0 ) + { + printf("errortxobj.(%s)\n",jprint(txobj,0)); + free_json(txobj); + txobj = cJSON_CreateObject(); + jaddstr(txobj,"error","couldnt decode transaction"); + } + //printf("msgtx.(%s)\n",jprint(txobj,0)); + if ( n != len ) + { + int32_t i; + for (i=0; i> 1; + if ( (serialized= origserialized) == 0 ) + serialized = calloc(1,len+4096); + decode_hex(serialized,len,txbytes); + txobj = bitcoin_data2json(symbol,taddr,pubtype,p2shtype,isPoS,height,txidp,msgtx,extraspace,extralen,serialized,len,vins,suppress_pubkeys,zcash); + if ( serialized != origserialized ) + free(serialized); + return(txobj); +} diff --git a/iguana/exchanges/LP_cache.c b/iguana/exchanges/LP_cache.c new file mode 100644 index 000000000..365a46107 --- /dev/null +++ b/iguana/exchanges/LP_cache.c @@ -0,0 +1,350 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_cache.c +// marketmaker +// + +cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len) +{ + uint8_t *extraspace; cJSON *txobj; char str[65],str2[65]; struct iguana_msgtx msgtx; bits256 checktxid; + extraspace = calloc(1,4000000); + memset(&msgtx,0,sizeof(msgtx)); + txobj = bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->height,&checktxid,&msgtx,extraspace,4000000,serialized,len,0,0,coin->zcash); + //printf("TX.(%s) match.%d\n",jprint(txobj,0),bits256_cmp(txid,checktxid)); + free(extraspace); + if ( bits256_cmp(txid,checktxid) != 0 ) + { + printf("%s LP_transaction_fromdata mismatched txid %s vs %s\n",coin->symbol,bits256_str(str,txid),bits256_str(str2,checktxid)); + free_json(txobj); + txobj = 0; + } + return(txobj); +} + +struct LP_transaction *LP_create_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len,int32_t height,long fpos) +{ + cJSON *txobj; bits256 spenttxid; int32_t i,spentvout,numvins,numvouts; cJSON *vout,*vin,*vins,*vouts; struct LP_transaction *tx; char str[65]; + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + return(tx); + if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) + { + vins = jarray(&numvins,txobj,"vin"); + vouts = jarray(&numvouts,txobj,"vout"); + tx = LP_transactionadd(coin,txid,height,numvouts,numvins); + tx->serialized = serialized, tx->len = len; + // free(serialized), tx->len = 0; + tx->fpos = fpos; + tx->SPV = tx->height = height; + //printf("tx.%s numvins.%d numvouts.%d\n",bits256_str(str,txid),numvins,numvouts); + for (i=0; ioutpoints[i].value = LP_value_extract(vout,0); + tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); + LP_destaddr(tx->outpoints[i].coinaddr,vout); + //printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_create_transaction",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); + } + for (i=0; inumvouts ) + { + if ( tx->outpoints[spentvout].spendheight <= 0 ) + { + tx->outpoints[spentvout].spendtxid = txid; + tx->outpoints[spentvout].spendvini = i; + tx->outpoints[spentvout].spendheight = height > 0 ? height : 1; + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); + if ( 0 && strcmp(coin->symbol,"REVS") == 0 ) + printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); + } + } else printf("LP_transactioninit: %s spentvout.%d < numvouts.%d spendheight.%d\n",bits256_str(str,spenttxid),spentvout,tx->numvouts,tx->outpoints[spentvout].spendheight); + } //else printf("LP_transactioninit: couldnt find (%s) ht.%d %s\n",bits256_str(str,spenttxid),height,jprint(vin,0)); + if ( bits256_cmp(spenttxid,txid) == 0 ) + printf("spending same tx's %p vout ht.%d %s.[%d] s%d\n",tx,height,bits256_str(str,txid),tx!=0?tx->numvouts:0,spentvout); + } + free_json(txobj); + } + return(tx); +} + +void LP_SPV_store(struct iguana_info *coin,bits256 txid,int32_t height) +{ + FILE *fp; char fname[512]; struct LP_transaction *tx = 0; + if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 && tx->len > 0 && tx->fpos == 0 ) + { + sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); + if ( (fp= OS_appendfile(fname)) != 0 ) + { + fwrite(&tx->txid,1,sizeof(tx->txid),fp); + fwrite(&tx->len,1,sizeof(tx->len),fp); + fwrite(&tx->height,1,sizeof(tx->height),fp); + tx->fpos = ftell(fp); + fwrite(tx->serialized,1,tx->len,fp); + fclose(fp); + } + } //else printf("cant store %s %s tx.%p [%d] fpos.%ld SPV.%d\n",coin->symbol,bits256_str(str,txid),tx,tx!=0?tx->len:-1,tx!=0?tx->fpos:-1,tx!=0?tx->SPV:-1); +} + +int32_t LP_cacheitem(struct iguana_info *coin,FILE *fp) +{ + bits256 txid,hash; long fpos; int32_t offset,retval,height,len; uint8_t *serialized; char str[65],str2[65]; + fpos = ftell(fp); + if ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) && fread(&len,1,sizeof(len),fp) == sizeof(len) && fread(&height,1,sizeof(height),fp) == sizeof(height) && len < 100000 ) + { + offset = (int32_t)(sizeof(txid) + sizeof(len) + sizeof(height)); + serialized = malloc(len); + if ( (retval= (int32_t)fread(serialized,1,len,fp)) == len ) + { + hash = bits256_calctxid(coin->symbol,serialized,len); + if ( bits256_cmp(hash,txid) == 0 ) + { + //printf("%s validated in cache\n",bits256_str(str,hash)); + LP_create_transaction(coin,txid,serialized,len,height,fpos+offset); + return((int32_t)(ftell(fp) - fpos)); + } + printf("%s vs %s did not validated in cache\n",bits256_str(str,hash),bits256_str(str2,txid)); + } else printf("retval.%d vs len.%d\n",retval,len); + } else printf("fread error\n"); + return(-1); +} + +void LP_cacheptrs_init(struct iguana_info *coin) +{ + char fname[1024]; FILE *fp; int32_t count,tflag=0; long n,fsize=0,len = 0; + sprintf(fname,"%s/UNSPENTS/%s.SPV",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); + fp = fopen(fname,"rb"); + count = 0; + if ( fp != 0 ) + { + fseek(fp,0,SEEK_END); + fsize = ftell(fp); + rewind(fp); + while ( len < fsize ) + { + if ( (n= LP_cacheitem(coin,fp)) < 0 ) + { + printf("cacheitem error at %s offset.%ld when fsize.%ld\n",coin->symbol,len,fsize); + tflag = 1; + break; + } + count++; + len += n; + } + printf("loaded %s %d entries total len.%ld\n",fname,count,len); + fclose(fp); + } //else printf("couldnt find.(%s)\n",fname); + if ( tflag != 0 ) + OS_truncate(fname,len); +} + +bits256 iguana_merkle(char *symbol,bits256 *tree,int32_t txn_count) +{ + int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; + if ( txn_count == 1 ) + return(tree[0]); + prev = 0; + while ( txn_count > 1 ) + { + if ( (txn_count & 1) != 0 ) + tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; + n += txn_count; + for (i=0; i> 1)] = bits256_calctxid(symbol,serialized,sizeof(serialized)); + } + prev = n; + txn_count >>= 1; + } + return(tree[n]); +} + +bits256 validate_merkle(int32_t pos,bits256 txid,cJSON *proofarray,int32_t proofsize) +{ + int32_t i; uint8_t serialized[sizeof(bits256) * 2]; bits256 hash,proof; + hash = txid; + for (i=0; i>= 1; + } + return(hash); +} + +bits256 LP_merkleroot(struct iguana_info *coin,struct electrum_info *ep,int32_t height) +{ + cJSON *hdrobj; bits256 merkleroot; + memset(merkleroot.bytes,0,sizeof(merkleroot)); + if ( coin->cachedmerkleheight == height ) + return(coin->cachedmerkle); + if ( (hdrobj= electrum_getheader(coin->symbol,ep,&hdrobj,height)) != 0 ) + { + if ( jobj(hdrobj,"merkle_root") != 0 ) + { + merkleroot = jbits256(hdrobj,"merkle_root"); + if ( bits256_nonz(merkleroot) != 0 ) + { + coin->cachedmerkle = merkleroot; + coin->cachedmerkleheight = height; + } + } + free_json(hdrobj); + } else printf("couldnt get header for ht.%d\n",height); + return(merkleroot); +} + +int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height) +{ + struct LP_transaction *tx=0; cJSON *merkobj,*merkles,*retjson; bits256 roothash,merkleroot; int32_t m,ht=0,SPV = 0; + if ( height <= 0 ) + return(0); + if ( (tx= LP_transactionfind(coin,txid)) == 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) + { + if ( (retjson= electrum_transaction(&ht,coin->symbol,ep,&retjson,txid,0)) != 0 ) + free_json(retjson); + } + if ( tx != 0 ) + { + if ( tx->height == 0 ) + { + if ( height != 0 ) + tx->height = height; + else if ( ht != 0 ) + tx->height = ht; + height = tx->height; + } + if ( tx->SPV > 0 ) + return(tx->SPV); + } + if ( (merkobj= electrum_getmerkle(coin->symbol,ep,&merkobj,txid,height)) != 0 ) + { + char str[65],str2[65],str3[65]; + SPV = 0; + memset(roothash.bytes,0,sizeof(roothash)); + if ( (merkles= jarray(&m,merkobj,"merkle")) != 0 ) + { + roothash = validate_merkle(jint(merkobj,"pos"),txid,merkles,m); + merkleroot = LP_merkleroot(coin,ep,height); + if ( bits256_nonz(merkleroot) != 0 ) + { + if ( bits256_cmp(merkleroot,roothash) == 0 ) + { + SPV = height; + LP_SPV_store(coin,txid,height); + if ( tx != 0 ) + { + tx->SPV = height; + if ( strcmp(coinaddr,coin->smartaddr) != 0 && tx->serialized != 0 ) + { + free(tx->serialized); + tx->serialized = 0; + tx->len = 0; + } + } + //printf("validated MERK %s ht.%d -> %s root.(%s)\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash)); + } + else + { + SPV = -1; + printf("ERROR MERK %s ht.%d -> %s root.(%s) vs %s\n",bits256_str(str,txid),height,jprint(merkobj,0),bits256_str(str2,roothash),bits256_str(str3,merkleroot)); + } + } else SPV = 0; + } + if ( SPV < 0 ) + { + printf("MERKLE DIDNT VERIFY.%s %s ht.%d (%s)\n",coin->symbol,bits256_str(str,txid),height,jprint(merkobj,0)); + if ( jobj(merkobj,"error") != 0 ) + SPV = 0; // try again later + } + free_json(merkobj); + } + return(SPV); +} + +char *LP_unspents_filestr(char *symbol,char *addr) +{ + char fname[1024]; long fsize; + sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + return(OS_filestr(&fsize,fname)); +} + +void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag) +{ + char fname[1024]; FILE *fp=0; + sprintf(fname,"%s/UNSPENTS/%s_%s",GLOBAL_DBDIR,symbol,addr), OS_portable_path(fname); + //printf("unspents cache.(%s) for %s %s, updated.%d\n",fname,symbol,addr,updatedflag); + if ( updatedflag == 0 && (fp= fopen(fname,"rb")) == 0 ) + updatedflag = 1; + else if ( fp != 0 ) + fclose(fp); + if ( updatedflag != 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(arraystr,1,strlen(arraystr),fp); + fclose(fp); + } +} + +uint64_t LP_unspents_load(char *symbol,char *addr) +{ + char *arraystr; uint64_t balance = 0; int32_t i,n; bits256 zero; cJSON *retjson,*item; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( (arraystr= LP_unspents_filestr(symbol,addr)) != 0 ) + { + if ( (retjson= cJSON_Parse(arraystr)) != 0 ) + { + //printf("PROCESS UNSPENTS %s\n",arraystr); + if ( (n= cJSON_GetArraySize(retjson)) > 0 ) + { + for (i=0; ielectrum,addr,retjson,1,zero,zero); + free_json(retjson); + } + free(arraystr); + } + } + return(balance); +} + + + diff --git a/iguana/exchanges/LP_coins.c b/iguana/exchanges/LP_coins.c new file mode 100644 index 000000000..f4c3681e9 --- /dev/null +++ b/iguana/exchanges/LP_coins.c @@ -0,0 +1,526 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_coins.c +// marketmaker +// + +char *portstrs[][3] = { { "BTC", "8332" }, { "KMD", "7771" } }; + +uint16_t LP_rpcport(char *symbol) +{ + int32_t i; + if ( symbol != 0 && symbol[0] != 0 ) + { + for (i=0; isymbol); + if ( showwif != 0 ) + { + bitcoin_priv2wif(coin->symbol,coin->wiftaddr,wifstr,G.LP_privkey,coin->wiftype); + bitcoin_wif2priv(coin->symbol,coin->wiftaddr,&tmptype,&checkkey,wifstr); + if ( bits256_cmp(G.LP_privkey,checkkey) == 0 ) + jaddstr(item,"wif",wifstr); + else jaddstr(item,"wif","error creating wif"); + } + jadd(item,"installed",coin->userpass[0] == 0 ? jfalse() : jtrue()); + if ( coin->userpass[0] != 0 ) + { + jaddnum(item,"height",LP_getheight(¬arized,coin)); + if ( notarized > 0 ) + jaddnum(item,"notarized",notarized); + if ( coin->electrum != 0 ) + balance = LP_unspents_load(coin->symbol,coin->smartaddr); + else balance = LP_RTsmartbalance(coin); + jaddnum(item,"balance",dstr(balance)); + jaddnum(item,"KMDvalue",dstr(LP_KMDvalue(coin,balance))); + } + else + { + jaddnum(item,"height",-1); + jaddnum(item,"balance",0); + } + if ( coin->inactive != 0 ) + { + jaddstr(item,"status","inactive"); + } + else jaddstr(item,"status","active"); + if ( coin->isPoS != 0 ) + jaddstr(item,"type","PoS"); + if ( (ep= coin->electrum) != 0 ) + { + sprintf(ipaddr,"%s:%u",ep->ipaddr,ep->port); + jaddstr(item,"electrum",ipaddr); + } + jaddstr(item,"smartaddress",coin->smartaddr); + jaddstr(item,"rpc",coin->serverport); + jaddnum(item,"pubtype",coin->pubtype); + jaddnum(item,"p2shtype",coin->p2shtype); + jaddnum(item,"wiftype",coin->wiftype); + jaddnum(item,"txfee",strcmp(coin->symbol,"BTC") != 0 ? coin->txfee : LP_txfeecalc(coin,0,0)); + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + if ( strcmp(coin->smartaddr,coin->instantdex_address) != 0 ) + { + LP_instantdex_depositadd(coin->smartaddr,zero); + strcpy(coin->instantdex_address,coin->smartaddr); + } + jaddnum(item,"zcredits",dstr(LP_myzcredits())); + jadd(item,"zdebits",LP_myzdebits()); + } + return(item); +} + +struct iguana_info *LP_conflicts_find(struct iguana_info *refcoin) +{ + struct iguana_info *coin=0,*tmp; + if ( refcoin != 0 ) + { + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( coin->inactive != 0 || coin->electrum != 0 || coin == refcoin ) + continue; + if ( strcmp(coin->serverport,refcoin->serverport) == 0 ) + break; + } + } + return(coin); +} + +cJSON *LP_coinsjson(int32_t showwif) +{ + struct iguana_info *coin,*tmp; cJSON *array = cJSON_CreateArray(); + HASH_ITER(hh,LP_coins,coin,tmp) + { + jaddi(array,LP_coinjson(coin,showwif)); + } + return(array); +} + +char *LP_getcoin(char *symbol) +{ + int32_t numenabled,numdisabled; struct iguana_info *coin,*tmp; cJSON *item=0,*retjson; + retjson = cJSON_CreateObject(); + if ( symbol != 0 && symbol[0] != 0 ) + { + numenabled = numdisabled = 0; + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( strcmp(symbol,coin->symbol) == 0 ) + item = LP_coinjson(coin,0); + if ( coin->inactive == 0 ) + numenabled++; + else numdisabled++; + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"enabled",numenabled); + jaddnum(retjson,"disabled",numdisabled); + if ( item == 0 ) + item = cJSON_CreateObject(); + jadd(retjson,"coin",item); + } + return(jprint(retjson,1)); +} + +struct iguana_info *LP_coinsearch(char *symbol) +{ + struct iguana_info *coin = 0; + if ( symbol != 0 && symbol[0] != 0 ) + { + portable_mutex_lock(&LP_coinmutex); + HASH_FIND(hh,LP_coins,symbol,strlen(symbol),coin); + portable_mutex_unlock(&LP_coinmutex); + } + return(coin); +} + +struct iguana_info *LP_coinadd(struct iguana_info *cdata) +{ + struct iguana_info *coin = calloc(1,sizeof(*coin)); + *coin = *cdata; + portable_mutex_init(&coin->txmutex); + portable_mutex_init(&coin->addrmutex); + portable_mutex_init(&coin->addressutxo_mutex); + portable_mutex_lock(&LP_coinmutex); + HASH_ADD_KEYPTR(hh,LP_coins,coin->symbol,strlen(coin->symbol),coin); + portable_mutex_unlock(&LP_coinmutex); + return(coin); +} + +uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath) +{ + static void *ctx; + char *name2; uint16_t origport = port; + memset(coin,0,sizeof(*coin)); + safecopy(coin->symbol,symbol,sizeof(coin->symbol)); + if ( strcmp(symbol,"PART") == 0 ) + coin->txversion = 160; + else coin->txversion = 1; + coin->updaterate = (uint32_t)time(NULL); + coin->isPoS = isPoS; + coin->taddr = taddr; + coin->wiftaddr = wiftaddr; + coin->longestchain = longestchain; + if ( (coin->txfee= txfee) > 0 && txfee < LP_MIN_TXFEE ) + coin->txfee = LP_MIN_TXFEE; + coin->pubtype = pubtype; + coin->p2shtype = p2shtype; + coin->wiftype = wiftype; + coin->inactive = (uint32_t)time(NULL); + //coin->bussock = LP_coinbus(busport); + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + coin->ctx = ctx; + if ( assetname != 0 && strcmp(name,assetname) == 0 ) + { + //printf("%s is assetchain\n",symbol); + coin->isassetchain = 1; + } + if ( strcmp(symbol,"KMD") == 0 || (assetname != 0 && assetname[0] != 0) ) + name2 = 0; + else name2 = name; + if ( strcmp(symbol,"XVG") == 0 || strcmp(symbol,"CLOAK") == 0 || strcmp(symbol,"PPC") == 0 || strcmp(symbol,"BCC") == 0 || strcmp(symbol,"ORB") == 0 ) + { + coin->noimportprivkey_flag = 1; + printf("truncate importprivkey for %s\n",symbol); + } +#ifndef FROM_JS + port = LP_userpass(coin->userpass,symbol,assetname,name,name2,confpath,port); +#endif + sprintf(coin->serverport,"127.0.0.1:%u",port); + if ( port != origport ) + printf("set curl path for %s to %s\n",symbol,coin->serverport); + if ( strcmp(symbol,"KMD") == 0 || coin->isassetchain != 0 || taddr != 0 ) + coin->zcash = LP_IS_ZCASHPROTOCOL; + else if ( strcmp(symbol,"BCH") == 0 ) + { + coin->zcash = LP_IS_BITCOINCASH; + //printf("set coin.%s <- LP_IS_BITCOINCASH %d\n",symbol,coin->zcash); + } + else if ( strcmp(symbol,"BTG") == 0 ) + { + coin->zcash = LP_IS_BITCOINGOLD; + printf("set coin.%s <- LP_IS_BITCOINGOLD %d\n",symbol,coin->zcash); + } + return(port); +} + +int32_t LP_isdisabled(char *base,char *rel) +{ + struct iguana_info *coin; + if ( base != 0 && (coin= LP_coinsearch(base)) != 0 && coin->inactive != 0 ) + return(1); + else if ( rel != 0 && (coin= LP_coinsearch(rel)) != 0 && coin->inactive != 0 ) + return(1); + else return(0); +} + +struct iguana_info *LP_coinfind(char *symbol) +{ + struct iguana_info *coin,cdata; int32_t isinactive,isPoS,longestchain = 1; uint16_t port,busport; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name,*assetname; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + if ( (coin= LP_coinsearch(symbol)) != 0 ) + return(coin); + if ( (port= LP_rpcport(symbol)) == 0 ) + return(0); + if ( (busport= LP_busport(port)) == 0 ) + return(0); + isPoS = 0; + txfee = LP_MIN_TXFEE; + estimatedrate = 20; + pubtype = 60; + p2shtype = 85; + wiftype = 188; + assetname = ""; + if ( strcmp(symbol,"BTC") == 0 ) + { + txfee = 0; + estimatedrate = 300; + pubtype = 0; + p2shtype = 5; + wiftype = 128; + name = "bitcoin"; + } + else if ( strcmp(symbol,"KMD") == 0 ) + name = "komodo"; + else return(0); + port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0); + if ( port == 0 ) + isinactive = 1; + else isinactive = 0; + if ( (coin= LP_coinadd(&cdata)) != 0 ) + { + coin->inactive = isinactive * (uint32_t)time(NULL); + /*if ( strcmp(symbol,"KMD") == 0 ) + coin->inactive = 0; + else*/ if ( strcmp(symbol,"BTC") == 0 ) + { + coin->inactive = (uint32_t)time(NULL) * !IAMLP; + printf("BTC inactive.%u\n",coin->inactive); + } + } + return(coin); +} + +// "coins":[{"coin":"", "rpcport":pppp}, {"coin":"LTC", "name":"litecoin", "rpcport":9332, "pubtype":48, "p2shtype":5, "wiftype":176, "txfee":100000 }] +// {"coin":"HUSH", "name":"hush", "rpcport":8822, "taddr":28, "pubtype":184, "p2shtype":189, "wiftype":128, "txfee":10000 } + +struct iguana_info *LP_coincreate(cJSON *item) +{ + struct iguana_info cdata,*coin=0; int32_t isPoS,longestchain = 1; uint16_t port; uint64_t txfee; double estimatedrate; uint8_t pubtype,p2shtype,wiftype; char *name=0,*symbol,*assetname=0; + if ( (symbol= jstr(item,"coin")) != 0 && symbol[0] != 0 && strlen(symbol) < 16 && LP_coinfind(symbol) == 0 && (port= juint(item,"rpcport")) != 0 ) + { + isPoS = jint(item,"isPoS"); + txfee = j64bits(item,"txfee"); + if ( (estimatedrate= jdouble(item,"estimatedrate")) == 0. ) + estimatedrate = 20; + pubtype = juint(item,"pubtype"); + if ( (p2shtype= juint(item,"p2shtype")) == 0 ) + p2shtype = 85; + if ( (wiftype= juint(item,"wiftype")) == 0 ) + wiftype = 188; + if ( (assetname= jstr(item,"asset")) != 0 ) + { + name = assetname; + pubtype = 60; + } + else if ( (name= jstr(item,"name")) == 0 ) + name = symbol; + if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath")) < 0 ) + { + coin = LP_coinadd(&cdata); + coin->inactive = (uint32_t)time(NULL); + } else coin = LP_coinadd(&cdata); + } else if ( symbol != 0 && jobj(item,"rpcport") == 0 ) + printf("SKIP %s, missing rpcport field in coins array\n",symbol); + if ( coin != 0 && item != 0 ) + { + if ( strcmp("KMD",coin->symbol) != 0 ) + { + if ( jobj(item,"active") != 0 ) + coin->inactive = !jint(item,"active"); + else + { + if ( IAMLP == 0 || assetname != name ) + coin->inactive = (uint32_t)time(NULL); + else coin->inactive = 0; + } + } else coin->inactive = 0; + } + if ( 0 && coin != 0 && coin->inactive != 0 ) + printf("LPnode.%d %s inactive.%u %p vs %p\n",IAMLP,coin->symbol,coin->inactive,assetname,name); + return(0); +} + +void LP_otheraddress(char *destcoin,char *otheraddr,char *srccoin,char *coinaddr) +{ + uint8_t addrtype,rmd160[20]; struct iguana_info *src,*dest; + if ( (src= LP_coinfind(srccoin)) != 0 && (dest= LP_coinfind(destcoin)) != 0 ) + { + bitcoin_addr2rmd160(srccoin,src->taddr,&addrtype,rmd160,coinaddr); + bitcoin_address(destcoin,otheraddr,dest->taddr,dest->pubtype,rmd160,20); + } else printf("couldnt find %s or %s\n",srccoin,destcoin); +} diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c new file mode 100644 index 000000000..ba9024bff --- /dev/null +++ b/iguana/exchanges/LP_commands.c @@ -0,0 +1,788 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_commands.c +// marketmaker +// + +char *LP_numutxos() +{ + cJSON *retjson = cJSON_CreateObject(); + if ( LP_mypeer != 0 ) + { + jaddstr(retjson,"ipaddr",LP_mypeer->ipaddr); + jaddnum(retjson,"port",LP_mypeer->port); + //jaddnum(retjson,"numutxos",LP_mypeer->numutxos); + jaddnum(retjson,"numpeers",LP_mypeer->numpeers); + jaddnum(retjson,"session",G.LP_sessionid); + } else jaddstr(retjson,"error","client node"); + return(jprint(retjson,1)); +} + +char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port) // from rpc port +{ + char *method,*userpass,*base,*rel,*coin,*passphrase,*retstr = 0; int32_t authenticated=0,changed,flag = 0; cJSON *retjson,*reqjson = 0; struct iguana_info *ptr; + method = jstr(argjson,"method"); + if ( method != 0 && (strcmp(method,"addr_unspents") == 0 || strcmp(method,"uitem") == 0 || strcmp(method,"postutxos") == 0) ) + return(0); +//printf("stats_JSON.(%s)\n",jprint(argjson,0)); + /*if ( (ipaddr= jstr(argjson,"ipaddr")) != 0 && (argport= juint(argjson,"port")) != 0 && (method == 0 || strcmp(method,"electrum") != 0) ) + { + if ( strcmp(ipaddr,"127.0.0.1") != 0 && argport >= 1000 ) + { + flag = 1; + if ( (pushport= juint(argjson,"push")) == 0 ) + pushport = argport + 1; + if ( (subport= juint(argjson,"sub")) == 0 ) + subport = argport + 2; + if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),argport)) != 0 ) + { + if ( 0 && (otherpeers= jint(argjson,"numpeers")) > peer->numpeers ) + peer->numpeers = otherpeers; + if ( peer->sessionid == 0 ) + peer->sessionid = juint(argjson,"session"); + //printf("peer.(%s) found (%d %d) (%d %d) (%s)\n",peer->ipaddr,peer->numpeers,peer->numutxos,otherpeers,othernumutxos,jprint(argjson,0)); + } else LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,argport,pushport,subport,jint(argjson,"numpeers"),jint(argjson,"numutxos"),juint(argjson,"session")); + } + }*/ + if ( method == 0 ) + { + if ( is_cJSON_Array(argjson) != 0 ) + printf("RAWARRAY command? %s\n",jprint(argjson,0)); + if ( flag == 0 || jobj(argjson,"result") != 0 ) + printf("stats_JSON no method: (%s)\n",jprint(argjson,0)); + return(0); + } + if ( strcmp(method,"hello") == 0 ) + { + //int32_t i; cJSON *array = cJSON_CreateArray(); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"status","got hello"); + //for (i=0; i<10000; i++) + // jaddinum(array,i); + //jadd(retjson,"array",array); + return(jprint(retjson,1)); + //printf("got hello from %s:%u\n",ipaddr!=0?ipaddr:"",argport); + //return(clonestr("{\"result\":\"success\",\"status\":\"got hello\"}")); + } + /*else if ( strcmp(method,"sendmessage") == 0 && jobj(argjson,"userpass") == 0 ) + { + static char *laststr; + char *newstr; bits256 pubkey = jbits256(argjson,"pubkey"); + if ( bits256_nonz(pubkey) == 0 || bits256_cmp(pubkey,G.LP_mypub25519) == 0 ) + { + newstr = jprint(argjson,0); + if ( laststr == 0 || strcmp(laststr,newstr) != 0 ) + { + printf("got message.(%s) from %s:%u\n",newstr,ipaddr!=0?ipaddr:"",argport); + if ( laststr != 0 ) + free(laststr); + laststr = newstr; + LP_gotmessage(argjson); + retstr = clonestr(laststr); + } + } else retstr = clonestr("{\"error\":\"duplicate message\"}"); + }*/ + //else if ( strcmp(method,"nn_tests") == 0 ) + // return(clonestr("{\"result\":\"success\"}")); + else if ( strcmp(method,"help") == 0 ) + return(clonestr("{\"result\":\" \ +available localhost RPC commands: \n \ +setprice(base, rel, price, broadcast=1)\n\ +autoprice(base, rel, fixed, minprice, maxprice, margin, refbase, refrel, factor, offset)*\n\ +goal(coin=*, val=)\n\ +myprice(base, rel)\n\ +enable(coin)\n\ +disable(coin)\n\ +notarizations(coin)\n\ +statsdisp(starttime=0, endtime=0, gui="", pubkey="", base="", rel="")\n\ +ticker(base="", rel="")\n\ +tradesarray(base, rel, starttime=-timescale*1024, endtime=, timescale=60) -> [timestamp, high, low, open, close, relvolume, basevolume, aveprice, numtrades]\n\ +pricearray(base, rel, starttime=0, endtime=0, timescale=60) -> [timestamp, avebid, aveask, highbid, lowask]\n\ +getrawtransaction(coin, txid)\n\ +inventory(coin, reset=0, [passphrase=])\n\ +lastnonce()\n\ +buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\ +sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\ +withdraw(coin, outputs[])\n\ +sendrawtransaction(coin, signedtx)\n\ +swapstatus(pending=0)\n\ +swapstatus(coin, limit=10)\n\ +swapstatus(base, rel, limit=10)\n\ +swapstatus(requestid, quoteid, pending=0)\n\ +recentswaps(limit=3)\n\ +notarizations(coin)\n\ +public API:\n \ +getcoins()\n\ +getcoin(coin)\n\ +portfolio()\n\ +getpeers()\n\ +passphrase(passphrase, gui, netid=0, seednode="")\n\ +listunspent(coin, address)\n\ +setconfirms(coin, numconfirms, maxconfirms=6)\n\ +trust(pubkey, trust) # positive to trust, 0 for normal, negative to blacklist\n\ +balance(coin, address)\n\ +balances(address)\n\ +fundvalue(address="", holdings=[], divisor=0)\n\ +orderbook(base, rel, duration=3600)\n\ +getprices()\n\ +getmyprice(base, rel)\n\ +getprice(base, rel)\n\ +//sendmessage(base=coin, rel="", pubkey=zero, )\n\ +//getmessages(firsti=0, num=100)\n\ +//deletemessages(firsti=0, num=100)\n\ +secretaddresses(prefix='secretaddress', passphrase, num=10, pubtype=60, taddr=0)\n\ +electrum(coin, ipaddr, port)\n\ +snapshot(coin, height)\n\ +snapshot_balance(coin, height, addresses[])\n\ +dividends(coin, height, )\n\ +stop()\n\ +bot_list()\n\ +bot_statuslist()\n\ +bot_buy(base, rel, maxprice, relvolume) -> botid\n\ +bot_sell(base, rel, minprice, basevolume) -> botid\n\ +bot_settings(botid, newprice, newvolume)\n\ +bot_status(botid)\n\ +bot_stop(botid)\n\ +bot_pause(botid)\n\ +instantdex_deposit(weeks, amount, broadcast=1)\n\ +instantdex_claim()\n\ +jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\ +\"}")); + //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ + + if ( (base= jstr(argjson,"base")) == 0 ) + base = ""; + if ((rel= jstr(argjson,"rel")) == 0 ) + rel = ""; + if ( (coin= jstr(argjson,"coin")) == 0 ) + coin = ""; + if ( G.USERPASS[0] != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 && port != 0 && strcmp(method,"psock") != 0 ) // protected localhost + { + if ( G.USERPASS_COUNTER == 0 ) + { + char pub33str[67]; + G.USERPASS_COUNTER = 1; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"userpass",G.USERPASS); + jaddbits256(retjson,"mypubkey",G.LP_mypub25519); + init_hexbytes_noT(pub33str,G.LP_pubsecp,33); + jaddstr(retjson,"pubsecp",pub33str); + jadd(retjson,"coins",LP_coinsjson(LP_showwif)); + LP_cmdcount++; + return(jprint(retjson,1)); + } + // if passphrase api and passphrase is right, ignore userpass, use hass of passphrase + if ( strcmp(method,"passphrase") == 0 && (passphrase= jstr(argjson,"passphrase")) != 0 ) + { + bits256 passhash; char str[65],str2[65]; + vcalc_sha256(0,passhash.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + if ( bits256_cmp(passhash,G.LP_passhash) == 0 ) + authenticated = 1; + else printf("passhash %s != G %s\n",bits256_str(str,passhash),bits256_str(str2,G.LP_passhash)); + } + if ( authenticated == 0 && ((userpass= jstr(argjson,"userpass")) == 0 || strcmp(userpass,G.USERPASS) != 0) ) + return(clonestr("{\"error\":\"authentication error you need to make sure userpass is set\"}")); + if ( jobj(argjson,"userpass") != 0 ) + jdelete(argjson,"userpass"); + LP_cmdcount++; + if ( strcmp(method,"passphrase") == 0 ) + { + char coinaddr[64],pub33str[67]; + G.USERPASS_COUNTER = 1; + if ( LP_passphrase_init(jstr(argjson,"passphrase"),jstr(argjson,"gui"),juint(argjson,"netid"),jstr(argjson,"seednode")) < 0 ) + return(clonestr("{\"error\":\"couldnt change passphrase\"}")); + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"userpass",G.USERPASS); + jaddbits256(retjson,"mypubkey",G.LP_mypub25519); + init_hexbytes_noT(pub33str,G.LP_pubsecp,33); + jaddstr(retjson,"pubsecp",pub33str); + bitcoin_address("KMD",coinaddr,0,60,G.LP_myrmd160,20); + jaddstr(retjson,"KMD",coinaddr); + bitcoin_address("BTC",coinaddr,0,0,G.LP_myrmd160,20); + jaddstr(retjson,"BTC",coinaddr); + jaddstr(retjson,"NXT",G.LP_NXTaddr); + jadd(retjson,"coins",LP_coinsjson(LP_showwif)); + return(jprint(retjson,1)); + } + } + else if ( strcmp(method,"instantdex_deposit") == 0 ) + { + if ( (ptr= LP_coinsearch("KMD")) != 0 ) + { + if ( jint(argjson,"weeks") <= 0 || jdouble(argjson,"amount") < 10. ) + return(clonestr("{\"error\":\"instantdex_deposit needs to have weeks and amount\"}")); + else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1)); + } + return(clonestr("{\"error\":\"cant find KMD\"}")); + } + else if ( strcmp(method,"instantdex_claim") == 0 ) + { + if ( (ptr= LP_coinsearch("KMD")) != 0 ) + { + return(LP_instantdex_claim(ptr)); + } + return(clonestr("{\"error\":\"cant find KMD\"}")); + } + else if ( strcmp(method,"jpg") == 0 ) + { + return(LP_jpg(jstr(argjson,"srcfile"),jstr(argjson,"destfile"),jint(argjson,"power2"),jstr(argjson,"password"),jstr(argjson,"data"),jint(argjson,"required"),juint(argjson,"ind"))); + } + /*else if ( strcmp(method,"sendmessage") == 0 ) + { + if ( jobj(argjson,"method2") == 0 ) + { + LP_broadcast_message(LP_mypubsock,base!=0?base:coin,rel,jbits256(argjson,"pubkey"),jprint(argjson,0)); + } + return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"getmessages") == 0 ) + { + if ( (retjson= LP_getmessages(jint(argjson,"firsti"),jint(argjson,"num"))) != 0 ) + return(jprint(retjson,1)); + else return(clonestr("{\"error\":\"null messages\"}")); + } + else if ( strcmp(method,"deletemessages") == 0 ) + { + LP_deletemessages(jint(argjson,"firsti"),jint(argjson,"num")); + return(clonestr("{\"result\":\"success\"}")); + }*/ + else if ( strcmp(method,"recentswaps") == 0 ) + { + return(LP_recent_swaps(jint(argjson,"limit"))); + } + else if ( strcmp(method,"stop") == 0 ) + { + printf("DEBUG stop\n"); + LP_STOP_RECEIVED = 1; + return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"millis") == 0 ) + { + LP_millistats_update(0); + return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"getprices") == 0 ) + return(LP_prices()); + else if ( strcmp(method,"getpeers") == 0 ) + return(LP_peers()); + else if ( strcmp(method,"getcoins") == 0 ) + return(jprint(LP_coinsjson(0),1)); + else if ( strcmp(method,"notarizations") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"coin",coin); + jaddnum(retjson,"lastnotarization",ptr->notarized); + jaddnum(retjson,"bestheight",ptr->height); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"cant find coin\"}")); + } + else if ( strcmp(method,"portfolio") == 0 ) + { + return(LP_portfolio()); + } + else if ( strcmp(method,"statsdisp") == 0 ) + { + return(jprint(LP_statslog_disp(juint(argjson,"starttime"),juint(argjson,"endtime"),jstr(argjson,"gui"),jbits256(argjson,"pubkey"),jstr(argjson,"base"),jstr(argjson,"rel")),1)); + } + else if ( strcmp(method,"ticker") == 0 ) + { + return(LP_ticker(jstr(argjson,"base"),jstr(argjson,"rel"))); + } + else if ( strcmp(method,"secretaddresses") == 0 ) + { + uint8_t taddr,pubtype; + pubtype = (jobj(argjson,"pubtype") == 0) ? 60 : juint(argjson,"pubtype"); + taddr = (jobj(argjson,"taddr") == 0) ? 0 : juint(argjson,"taddr"); + return(LP_secretaddresses(ctx,jstr(argjson,"prefix"),jstr(argjson,"passphrase"),juint(argjson,"num"),taddr,pubtype)); + } + else if ( strcmp(method,"swapstatus") == 0 ) + { + uint32_t requestid,quoteid; + if ( (requestid= juint(argjson,"requestid")) != 0 && (quoteid= juint(argjson,"quoteid")) != 0 ) + return(basilisk_swapentry(requestid,quoteid,1)); + else if ( coin[0] != 0 ) + return(basilisk_swapentries(coin,0,jint(argjson,"limit"))); + else if ( base[0] != 0 && rel[0] != 0 ) + return(basilisk_swapentries(base,rel,jint(argjson,"limit"))); + else return(basilisk_swaplist(0,0,0,jint(argjson,"pending"))); + } + else if ( strcmp(method,"dynamictrust") == 0 ) + { + struct LP_address *ap; char *coinaddr; + if ( (ptr= LP_coinsearch("KMD")) != 0 && (coinaddr= jstr(argjson,"address")) != 0 ) + { + //LP_zeroconf_deposits(ptr); + if ( (ap= LP_addressfind(ptr,coinaddr)) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",coinaddr); + jaddnum(retjson,"zcredits",dstr(ap->instantdex_credits)); + return(jprint(retjson,1)); + } + } + return(clonestr("{\"error\":\"cant find address\"}")); + } + else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 ) + return(retstr); + if ( base[0] != 0 && rel[0] != 0 ) + { + double price,bid,ask; + if ( strcmp(method,"autoprice") == 0 ) + { + if ( LP_autoprice(ctx,base,rel,argjson) < 0 ) + return(clonestr("{\"error\":\"couldnt set autoprice\"}")); + else return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"pricearray") == 0 ) + { + uint32_t firsttime; + if ( base[0] != 0 && rel[0] != 0 ) + { + if ( (firsttime= juint(argjson,"starttime")) < time(NULL)-30*24*3600 ) + firsttime = (uint32_t)(time(NULL)-30*24*3600); + return(jprint(LP_pricearray(base,rel,firsttime,juint(argjson,"endtime"),jint(argjson,"timescale")),1)); + } else return(clonestr("{\"error\":\"pricearray needs base and rel\"}")); + } + else if ( strcmp(method,"tradesarray") == 0 ) + { + return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); + } + if ( IAMLP == 0 && LP_isdisabled(base,rel) != 0 ) + return(clonestr("{\"error\":\"at least one of coins disabled\"}")); + price = jdouble(argjson,"price"); + if ( strcmp(method,"setprice") == 0 ) + { + if ( LP_mypriceset(&changed,base,rel,price) < 0 ) + return(clonestr("{\"error\":\"couldnt set price\"}")); + //else if ( LP_mypriceset(&changed,rel,base,1./price) < 0 ) + // return(clonestr("{\"error\":\"couldnt set price\"}")); + else if ( price == 0. || jobj(argjson,"broadcast") == 0 || jint(argjson,"broadcast") != 0 ) + return(LP_pricepings(ctx,myipaddr,LP_mypubsock,base,rel,price * LP_profitratio)); + else return(clonestr("{\"result\":\"success\"}")); + } + else if ( strcmp(method,"orderbook") == 0 ) + return(LP_orderbook(base,rel,jint(argjson,"duration"))); + else if ( strcmp(method,"myprice") == 0 ) + { + if ( LP_myprice(&bid,&ask,base,rel) > SMALLVAL ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"bid",bid); + jaddnum(retjson,"ask",ask); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no price set\"}")); + } + else if ( strcmp(method,"buy") == 0 ) + { + //* + if ( price > SMALLVAL ) + { + return(LP_autobuy(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0)); + } else return(clonestr("{\"error\":\"no price set\"}")); + } + else if ( strcmp(method,"sell") == 0 ) + { + //* + if ( price > SMALLVAL ) + { + return(LP_autobuy(ctx,myipaddr,pubsock,rel,base,1./price,jdouble(argjson,"basevolume"),jint(argjson,"timeout"),jint(argjson,"duration"),jstr(argjson,"gui"),juint(argjson,"nonce"),jbits256(argjson,"destpubkey"),0)); + } else return(clonestr("{\"error\":\"no price set\"}")); + } + } + /*else if ( rel[0] != 0 && strcmp(method,"bestfit") == 0 ) + { + double relvolume; + if ( (relvolume= jdouble(argjson,"relvolume")) > SMALLVAL ) + return(LP_bestfit(rel,relvolume)); + else return(clonestr("{\"error\":\"no relvolume set\"}")); + }*/ + else if ( coin[0] != 0 ) + { + if ( strcmp(method,"enable") == 0 ) + { + //* + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + if ( ptr->userpass[0] == 0 && strcmp(ptr->symbol,"ETH") != 0 ) + { + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error",LP_DONTCHANGE_ERRMSG0); + jaddstr(retjson,"coin",coin); + return(jprint(retjson,1)); + } + if ( LP_conflicts_find(ptr) == 0 ) + { + ptr->inactive = 0; + cJSON *array; int32_t notarized; + if ( strcmp(ptr->symbol,"ETH") != 0 && LP_getheight(¬arized,ptr) <= 0 ) + { + ptr->inactive = (uint32_t)time(NULL); + return(clonestr("{\"error\":\"coin cant be activated till synced\"}")); + } + else + { + if ( ptr->smartaddr[0] != 0 ) + LP_unspents_load(coin,ptr->smartaddr); + LP_unspents_load(coin,ptr->smartaddr); + if ( strcmp(ptr->symbol,"KMD") == 0 ) + LP_importaddress("KMD",BOTS_BONDADDRESS); + } + array = cJSON_CreateArray(); + jaddi(array,LP_coinjson(ptr,0)); + return(jprint(array,1)); + } else return(clonestr("{\"error\":\"coin port conflicts with existing coin\"}")); + } else return(clonestr("{\"error\":\"couldnt find coin\"}")); + } + else if ( strcmp(method,"disable") == 0 ) + { + //* + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + ptr->inactive = (uint32_t)time(NULL); + cJSON *array = cJSON_CreateArray(); + jaddi(array,LP_coinjson(ptr,0)); + return(jprint(array,1)); + } else return(clonestr("{\"error\":\"couldnt find coin\"}")); + } + else if ( strcmp(method,"listunspent") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + char *coinaddr; bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + if ( (coinaddr= jstr(argjson,"address")) != 0 ) + { + if ( coinaddr[0] != 0 ) + { + LP_address(ptr,coinaddr); + if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) + { + LP_listunspent_issue(coin,coinaddr,2,zero,zero); + //LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); + } + return(jprint(LP_listunspent(coin,coinaddr,zero,zero),1)); + } + } + return(clonestr("{\"error\":\"no address specified\"}")); + } else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"balance") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(jprint(LP_address_balance(ptr,jstr(argjson,"address"),1),1)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"electrum") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + ptr->inactive = 0; + return(jprint(LP_electrumserver(ptr,jstr(argjson,"ipaddr"),juint(argjson,"port")),1)); + } else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"sendrawtransaction") == 0 ) + { + return(LP_sendrawtransaction(coin,jstr(argjson,"signedtx"))); + } + else if ( strcmp(method,"getrawtransaction") == 0 ) + { + return(jprint(LP_gettx(coin,jbits256(argjson,"txid"),0),1)); + } + else if ( strcmp(method,"withdraw") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + if ( jobj(argjson,"outputs") == 0 ) + return(clonestr("{\"error\":\"withdraw needs to have outputs\"}")); + else return(LP_withdraw(ptr,argjson)); + } + return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"setconfirms") == 0 ) + { + int32_t n; + n = jint(argjson,"numconfirms"); + if ( n < 0 ) + return(clonestr("{\"error\":\"illegal numconfirms\"}")); + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + ptr->userconfirms = n; + if ( (n= jint(argjson,"maxconfirms")) > 0 ) + ptr->maxconfirms = n; + if ( ptr->maxconfirms > 0 && ptr->userconfirms > ptr->maxconfirms ) + ptr->userconfirms = ptr->maxconfirms; + return(clonestr("{\"result\":\"success\"}")); + } else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"snapshot") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(jprint(LP_snapshot(ptr,juint(argjson,"height")),1)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"dividends") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(LP_dividends(ptr,juint(argjson,"height"),argjson)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } + else if ( strcmp(method,"snapshot_balance") == 0 ) + { + if ( (ptr= LP_coinsearch(coin)) != 0 ) + return(LP_snapshot_balance(ptr,juint(argjson,"height"),argjson)); + else return(clonestr("{\"error\":\"cant find coind\"}")); + } + if ( LP_isdisabled(coin,0) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"error",LP_DONTCHANGE_ERRMSG1); + return(jprint(retjson,1)); + } + if ( strcmp(method,"inventory") == 0 ) + { + struct iguana_info *ptr; + if ( (ptr= LP_coinfind(coin)) != 0 ) + { + LP_address(ptr,ptr->smartaddr); + if ( jint(argjson,"reset") != 0 ) + { + ptr->privkeydepth = 0; + LP_address_utxo_reset(ptr); + LP_passphrase_init(jstr(argjson,"passphrase"),G.gui,G.netid,G.seednode); + } + if ( bits256_nonz(G.LP_privkey) != 0 ) + LP_privkey_init(-1,ptr,G.LP_privkey,G.LP_mypub25519); + else printf("no LP_privkey\n"); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"coin",coin); + jaddnum(retjson,"timestamp",time(NULL)); + jadd(retjson,"alice",cJSON_Parse("[]")); + //jadd(retjson,"alice",LP_inventory(coin)); + //jadd(retjson,"bob",LP_inventory(coin,1)); + //LP_smartutxos_push(ptr); + LP_address_utxo_reset(ptr); + return(jprint(retjson,1)); + } + } + else if ( strcmp(method,"goal") == 0 ) + return(LP_portfolio_goal(coin,jdouble(argjson,"val"))); + else if ( strcmp(method,"getcoin") == 0 ) + return(LP_getcoin(coin)); + } + else if ( strcmp(method,"goal") == 0 ) + return(LP_portfolio_goal("*",100.)); + else if ( strcmp(method,"lastnonce") == 0 ) + { + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"lastnonce",LP_lastnonce); + return(jprint(retjson,1)); + } + else if ( strcmp(method,"myprices") == 0 ) + return(LP_myprices()); + else if ( strcmp(method,"trust") == 0 ) + return(LP_pubkey_trustset(jbits256(argjson,"pubkey"),jint(argjson,"trust"))); + else if ( strcmp(method,"trusted") == 0 ) + return(LP_pubkey_trusted()); + } // end of protected localhost commands + if ( IAMLP == 0 ) + { + if ( (reqjson= LP_dereference(argjson,"broadcast")) != 0 ) + { + if ( jobj(reqjson,"method2") != 0 ) + { + jdelete(reqjson,"method"); + method = jstr(reqjson,"method2"); + jaddstr(reqjson,"method",method); + } + argjson = reqjson; + } + if ( strcmp(method,"getdPoW") == 0 ) + retstr = clonestr("{\"result\":\"success\"}"); + } + else + { + if ( strcmp(method,"tradesarray") == 0 ) + { + return(jprint(LP_tradesarray(base,rel,juint(argjson,"starttime"),juint(argjson,"endtime"),jint(argjson,"timescale")),1)); + } + else if ( strcmp(method,"getdPoW") == 0 ) + { + if ( (ptr= LP_coinfind(jstr(argjson,"coin"))) != 0 ) + LP_dPoW_broadcast(ptr); + retstr = clonestr("{\"result\":\"success\"}"); + } + } + // received response + if ( strcmp(method,"swapstatus") == 0 ) + return(LP_swapstatus_recv(argjson)); + else if ( strcmp(method,"gettradestatus") == 0 ) + { + retstr = clonestr("{\"error\":\"deprecated\"}"); + //return(LP_gettradestatus(j64bits(argjson,"aliceid"),juint(argjson,"requestid"),juint(argjson,"quoteid"))); + } + else if ( strcmp(method,"postprice") == 0 ) + return(LP_postprice_recv(argjson)); + else if ( strcmp(method,"uitem") == 0 ) + return(LP_uitem_recv(argjson)); + else if ( strcmp(method,"dPoW") == 0 ) + return(LP_dPoW_recv(argjson)); + else if ( strcmp(method,"notify") == 0 ) + return(LP_notify_recv(argjson)); + else if ( strcmp(method,"getpeers") == 0 ) + return(LP_peers()); + else if ( strcmp(method,"balances") == 0 ) + return(jprint(LP_balances(jstr(argjson,"address")),1)); + else if ( strcmp(method,"fundvalue") == 0 ) + return(jprint(LP_fundvalue(argjson),1)); + else if ( strcmp(method,"getprice") == 0 || strcmp(method,"getmyprice") == 0 ) + { + double price,bid,ask; + if ( strcmp(method,"getprice") == 0 ) + { + ask = LP_price(base,rel); + if ( (bid= LP_price(rel,base)) > SMALLVAL ) + bid = 1./bid; + } + else + { + ask = LP_getmyprice(base,rel); + if ( (bid= LP_getmyprice(rel,base)) > SMALLVAL ) + bid = 1./bid; + } + price = _pairaved(bid,ask); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"timestamp",time(NULL)); + jaddnum(retjson,"bid",bid); + jaddnum(retjson,"ask",ask); + jaddnum(retjson,"price",price); + return(jprint(retjson,1)); + } + /*else if ( strcmp(method,"getpeers") == 0 ) + { + char *tmpstr; + if ( (tmpstr= jstr(argjson,"LPnode")) != 0 ) + LP_addpeer(LP_mypeer,LP_mypubsock,tmpstr,RPC_port,RPC_port+10,RPC_port+20,1,G.LP_sessionid); + if ( IAMLP != 0 ) + { + printf("send peers list %s\n",LP_peers()); + bits256 zero; memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,LP_peers()); + } + retstr = clonestr("{\"result\":\"success\"}"); + }*/ + // end received response + + else if ( strcmp(method,"tradestatus") == 0 ) + { + LP_tradecommand_log(argjson); + //printf("%-4d tradestatus | aliceid.%llu RT.%d %d\n",(uint32_t)time(NULL) % 3600,(long long)j64bits(argjson,"aliceid"),LP_RTcount,LP_swapscount); + retstr = clonestr("{\"result\":\"success\"}"); + } + else if ( strcmp(method,"wantnotify") == 0 ) + { + bits256 pub; static uint32_t lastnotify; + pub = jbits256(argjson,"pub"); + //char str[65]; printf("got wantnotify.(%s) vs %s\n",jprint(argjson,0),bits256_str(str,G.LP_mypub25519)); + if ( bits256_cmp(pub,G.LP_mypub25519) == 0 && time(NULL) > lastnotify+60 ) + { + lastnotify = (uint32_t)time(NULL); + //printf("wantnotify for me!\n"); + LP_notify_pubkeys(ctx,LP_mypubsock); + } + retstr = clonestr("{\"result\":\"success\"}"); + } + else if ( strcmp(method,"addr_unspents") == 0 ) + { + //printf("GOT ADDR_UNSPENTS %s %s\n",jstr(argjson,"coin"),jstr(argjson,"address")); + if ( (ptr= LP_coinsearch(coin)) != 0 ) + { + char *coinaddr; + if ( (coinaddr= jstr(argjson,"address")) != 0 ) + { + if ( coinaddr[0] != 0 ) + { + LP_address(ptr,coinaddr); + if ( strcmp(coinaddr,ptr->smartaddr) == 0 && bits256_nonz(G.LP_privkey) != 0 ) + { + //printf("ADDR_UNSPENTS %s %s is my address being asked for!\n",ptr->symbol,coinaddr); + if ( ptr->lastpushtime > 0 && ptr->addr_listunspent_requested > (uint32_t)time(NULL)-10 ) + ptr->lastpushtime -= LP_ORDERBOOK_DURATION*0.1; + ptr->addr_listunspent_requested = (uint32_t)time(NULL); + } + } + } + } + retstr = clonestr("{\"result\":\"success\"}"); + } + else if ( strcmp(method,"encrypted") == 0 ) + retstr = clonestr("{\"result\":\"success\"}"); + else // psock requests/response + { + if ( IAMLP != 0 ) + { + if ( strcmp(method,"psock") == 0 ) + { + int32_t psock; + if ( myipaddr == 0 || myipaddr[0] == 0 || strcmp(myipaddr,"127.0.0.1") == 0 ) + { + if ( LP_mypeer != 0 ) + myipaddr = LP_mypeer->ipaddr; + else printf("LP_psock dont have actual ipaddr?\n"); + } + if ( jint(argjson,"ispaired") != 0 ) + { + retstr = LP_psock(&psock,myipaddr,1,jint(argjson,"cmdchannel"),jbits256(argjson,"pubkey")); + //printf("LP_commands.(%s)\n",retstr); + return(retstr); + } + else return(clonestr("{\"error\":\"you are running an obsolete version, update\"}")); + } + } + else + { + if ( strcmp(method,"psock") == 0 ) + { + //printf("nonLP got (%s)\n",jprint(argjson,0)); + retstr = clonestr("{\"result\":\"success\"}"); + } + } + } + if ( retstr == 0 ) + printf("ERROR.(%s)\n",jprint(argjson,0)); + if ( reqjson != 0 ) + free_json(reqjson); + if ( retstr != 0 ) + { + free(retstr); + return(0); + } + return(0); +} diff --git a/iguana/exchanges/LP_forwarding.c b/iguana/exchanges/LP_forwarding.c new file mode 100644 index 000000000..749cf2f2e --- /dev/null +++ b/iguana/exchanges/LP_forwarding.c @@ -0,0 +1,351 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_forwarding.c +// marketmaker +// + +cJSON *LP_dereference(cJSON *argjson,char *excludemethod) +{ + cJSON *reqjson = 0; + if ( jstr(argjson,"method2") != 0 && strncmp(excludemethod,jstr(argjson,"method2"),strlen(excludemethod)) != 0 ) + { + reqjson = jduplicate(argjson); + jdelete(reqjson,"method"); + jaddstr(reqjson,"method",jstr(argjson,"method2")); + } + return(reqjson); +} + +/* +struct LP_forwardinfo +{ + UT_hash_handle hh; + bits256 pubkey; + char pushaddr[64]; + int32_t pushsock; + uint32_t lasttime,hello; +} *LP_forwardinfos; +#define LP_KEEPALIVE (3600 * 24) + +struct LP_forwardinfo *LP_forwardfind(bits256 pubkey) +{ + struct LP_forwardinfo *ptr=0; + portable_mutex_lock(&LP_forwardmutex); + HASH_FIND(hh,LP_forwardinfos,&pubkey,sizeof(pubkey),ptr); + portable_mutex_unlock(&LP_forwardmutex); + if ( ptr != 0 && ptr->lasttime > time(NULL)-LP_KEEPALIVE ) + return(ptr); + else return(0); +} + +char *LP_lookup(bits256 pubkey) +{ + if ( bits256_nonz(pubkey) == 0 ) + return(clonestr("{\"result\":\"illegal pubkey\"}")); + if ( LP_forwardfind(pubkey) != 0 ) + return(clonestr("{\"result\":\"success\",\"forwarding\":1}")); + else return(clonestr("{\"result\":\"notfound\"}")); +} + +int32_t LP_hello(struct LP_forwardinfo *ptr) +{ + int32_t i,n=10; char msg[512]; struct nn_pollfd pfd; + if ( bits256_cmp(ptr->pubkey,LP_mypubkey) != 0 ) + { + pfd.fd = ptr->pushsock; + pfd.events = NN_POLLOUT; + for (i=0; i 0 ) + { + sprintf(msg,"{\"method\":\"hello\",\"from\":\"%s\"}",LP_mypeer != 0 ? LP_mypeer->ipaddr : ""); + //printf("HELLO sent.%d bytes to %s on i.%d\n",LP_send(ptr->pushsock,msg,0),ptr->pushaddr,i); + ptr->hello = (uint32_t)time(NULL); + return(i); + } + } + //printf("%d iterations on nn_poll and %s pushsock still not ready\n",i,ptr->pushaddr); + return(-1); + } + return(0); +} + +int32_t LP_hellos() +{ + struct LP_forwardinfo *ptr,*tmp; int32_t nonz = 0; + HASH_ITER(hh,LP_forwardinfos,ptr,tmp) + { + if ( ptr->hello == 0 && LP_hello(ptr) >= 0 ) + nonz++; + } + return(nonz); +} + +int32_t LP_pushsock_create(struct LP_forwardinfo *ptr,char *pushaddr) +{ + int32_t pushsock,timeout; + if ( (pushsock= nn_socket(AF_SP,LP_COMMAND_SENDSOCK)) < 0 ) + { + printf("LP_pushsock_create couldnt allocate socket for %s\n",pushaddr); + return(-1); + } + else if ( nn_connect(pushsock,pushaddr) < 0 ) + { + nn_close(pushsock); + printf("LP_pushsock_create couldnt connect to %s\n",pushaddr); + return(-1); + } + timeout = 1; + nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + if ( ptr != 0 ) + LP_hello(ptr); + return(pushsock); +} + +char *LP_register(bits256 pubkey,char *ipaddr,uint16_t port) +{ + struct LP_forwardinfo *ptr=0; int32_t pushsock; char pushaddr[64]; + if ( ipaddr == 0 || ipaddr[0] == 0 || is_ipaddr(ipaddr) == 0 || bits256_nonz(pubkey) == 0 ) + return(clonestr("{\"result\":\"illegal ipaddr or null pubkey\"}")); + nanomsg_transportname(0,pushaddr,ipaddr,port); + //char str[65]; printf("register.(%s) %s\n",pushaddr,bits256_str(str,pubkey)); + if ( (ptr= LP_forwardfind(pubkey)) != 0 ) + { + ptr->lasttime = (uint32_t)time(NULL); + if ( ptr->pushsock >= 0 ) + { + if ( strcmp(pushaddr,ptr->pushaddr) != 0 ) + { + nn_close(ptr->pushsock); + if ( LP_psockmark(ptr->pushaddr) < 0 ) + { + //printf("cant mark (%s)\n",ptr->pushaddr); + } + char str[65]; printf("%u recreate pushsock for %s <- %s %s\n",(uint32_t)time(NULL),ptr->pushaddr,pushaddr,bits256_str(str,pubkey)); + strcpy(ptr->pushaddr,pushaddr); + if ( (ptr->pushsock= LP_pushsock_create(ptr,pushaddr)) < 0 ) + return(clonestr("{\"result\":\"success\",\"status\":\"couldnt recreate pushsock\",\"registered\":0}")); + } //else printf("no need to create identical endpoint\n"); + } + return(clonestr("{\"result\":\"success\",\"status\":\"already registered\",\"registered\":1}")); + } + else if ( (pushsock= LP_pushsock_create(0,pushaddr)) < 0 ) + return(clonestr("{\"result\":\"success\",\"status\":\"couldnt create pushsock\"}")); + else + { + ptr = calloc(1,sizeof(*ptr)); + ptr->pubkey = pubkey; + strcpy(ptr->pushaddr,pushaddr); + ptr->pushsock = pushsock; + ptr->lasttime = (uint32_t)time(NULL); + portable_mutex_lock(&LP_forwardmutex); + HASH_ADD_KEYPTR(hh,LP_forwardinfos,&ptr->pubkey,sizeof(ptr->pubkey),ptr); + portable_mutex_unlock(&LP_forwardmutex); + //char str[65]; printf("registered (%s) -> (%s) pushsock.%d\n",bits256_str(str,pubkey),pushaddr,ptr->pushsock); + LP_hello(ptr); + return(LP_lookup(pubkey)); + } +} + +int32_t LP_forwarding_register(bits256 pubkey,char *publicaddr,uint16_t publicport,int32_t max) +{ + char *argstr,ipaddr[64]; cJSON *argjson; struct LP_peerinfo *peer,*tmp; int32_t j,n=0,arglen; + if ( publicaddr == 0 || publicaddr[0] == 0 || bits256_nonz(pubkey) == 0 ) + { + char str[65]; printf("LP_forwarding_register illegal publicaddr.(%s):%u or null pubkey (%s)\n",publicaddr,publicport,bits256_str(str,pubkey)); + return(0); + } + for (j=0; publicaddr[j]!=0; j++) + if ( publicaddr[j] >= '0' && publicaddr[j] <= '9' ) + break; + parse_ipaddr(ipaddr,publicaddr+j); + argjson = cJSON_CreateObject(); + jaddstr(argjson,"agent","stats"); + jaddstr(argjson,"method","register"); + jaddbits256(argjson,"client",pubkey); + jaddstr(argjson,"pushaddr",ipaddr); + jaddnum(argjson,"pushport",publicport); + argstr = jprint(argjson,1); + arglen = (int32_t)strlen(argstr) + 1; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( strcmp(LP_myipaddr,peer->ipaddr) == 0 ) + continue; + if ( peer->pushsock >= 0 ) + { + if ( LP_send(peer->pushsock,argstr,arglen,0) != arglen ) + { + if ( strncmp(peer->ipaddr,"5.9.253",strlen("5.9.253")) == 0 ) + printf("error registering with %s:%u\n",peer->ipaddr,peer->port); + } + n++; + } + //printf("register.(%s) %s %u with (%s)\n",publicaddr,ipaddr,publicport,peer->ipaddr); + } + free(argstr); + return(n); +} + +char *LP_registerall(int32_t numnodes) +{ + int32_t i,maxnodes,n=0; cJSON *retjson; + if ( numnodes < sizeof(default_LPnodes)/sizeof(*default_LPnodes) ) + numnodes = (int32_t)(sizeof(default_LPnodes)/sizeof(*default_LPnodes)); + if ( (maxnodes= LP_numpeers()) < numnodes ) + numnodes = maxnodes; + for (i=0; i= numnodes ) + break; + retjson = cJSON_CreateObject(); + if ( i == numnodes ) + jaddstr(retjson,"error","not enough nodes"); + jaddnum(retjson,"numnodes",numnodes); + jaddnum(retjson,"registered",n); + jaddnum(retjson,"iters",i); + return(jprint(retjson,1)); +} + +char *LP_forwardhex(void *ctx,int32_t pubsock,bits256 pubkey,char *hexstr) +{ + struct LP_forwardinfo *ptr=0; uint8_t *data; int32_t datalen=0,sentbytes=0; char *msg,*retstr=0; cJSON *retjson=0,*argjson=0,*reqjson=0; + if ( hexstr == 0 || hexstr[0] == 0 ) + return(clonestr("{\"result\":\"nohex\"}")); + datalen = (int32_t)strlen(hexstr) >> 1; + data = malloc(datalen); + decode_hex(data,datalen,hexstr); + if ( (argjson= cJSON_Parse((char *)data)) != 0 ) + reqjson = LP_dereference(argjson,"forward"); + if ( bits256_nonz(pubkey) == 0 || bits256_cmp(pubkey,LP_mypubkey) == 0 ) + { + if ( reqjson != 0 ) + { + retstr = LP_command_process(ctx,LP_mypeer != 0 ? LP_mypeer->ipaddr : "127.0.0.1",LP_mypubsock,reqjson,0,0,LP_profitratio - 1.); + //printf("LP_forwardhex.(%s) -> (%s)\n",jprint(reqjson,0),retstr!=0?retstr:""); + if ( pubsock >= 0 ) + { + msg = jprint(reqjson,0); + LP_send(pubsock,msg,(int32_t)strlen(msg)+1,0); + } + } else printf("LP_forwardhex couldnt parse (%s)\n",(char *)data); + } + else if ( (ptr= LP_forwardfind(pubkey)) != 0 ) + { + if ( ptr->pushsock >= 0 ) + { + printf("%s forwardhex.(%s)\n",ptr->pushaddr,(char *)data); + sentbytes = LP_send(ptr->pushsock,(char *)data,datalen,0); + } + retjson = cJSON_CreateObject(); + if ( sentbytes >= 0 ) + { + jaddstr(retjson,"result","success"); + if ( sentbytes == datalen ) + jaddnum(retjson,"forwarded",sentbytes); + else if ( sentbytes == 0 ) + jaddnum(retjson,"queued",sentbytes); + else jaddnum(retjson,"mismatch",sentbytes); + retstr = jprint(retjson,1); + } + else + { + jaddstr(retjson,"error","send error"); + jaddnum(retjson,"sentbytes",sentbytes); + jaddnum(retjson,"datalen",datalen); + jaddnum(retjson,"hello",ptr->hello); + retstr = jprint(retjson,1); + } + } + else + { + char str[65]; printf("couldnt find %s to forward to\n",bits256_str(str,pubkey)); + if ( pubsock >= 0 ) + { + msg = jprint(reqjson,0); + LP_send(pubsock,msg,(int32_t)strlen(msg)+1,1); + } + retstr = clonestr("{\"result\":\"notfound\"}"); + } + free(data); + if ( reqjson != 0 ) + free_json(reqjson); + if ( argjson != 0 ) + free_json(argjson); + return(retstr); +} + +int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,bits256 pubkey,char *jsonstr,int32_t freeflag) +{ + struct LP_forwardinfo *ptr; struct LP_peerinfo *peer,*tmp; char *msg,*hexstr,*retstr; int32_t len,n=0,mlen; cJSON *reqjson,*argjson; + if ( jsonstr == 0 || jsonstr[0] == 0 ) + return(-1); + len = (int32_t)strlen(jsonstr) + 1; + if ( bits256_nonz(pubkey) != 0 ) + { + if ( bits256_cmp(pubkey,LP_mypubkey) == 0 ) + { + printf("GOT FORWARDED.(%s)\n",myipaddr); + if ( (argjson= cJSON_Parse(jsonstr)) != 0 ) + { + if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,0,0)) != 0 ) + free(retstr); + free_json(argjson); + } + if ( freeflag != 0 ) + free(jsonstr); + return(1); + } + else if ( IAMLP != 0 && (ptr= LP_forwardfind(pubkey)) != 0 && ptr->pushsock >= 0 ) + { + printf("GOT FORWARDED.(%s) -> pushsock.%d\n",jsonstr,ptr->pushsock); + if ( LP_send(ptr->pushsock,jsonstr,len,freeflag) == len ) + return(1); + } + } + hexstr = malloc(len*2 + 1); + init_hexbytes_noT(hexstr,(uint8_t *)jsonstr,len); + if ( freeflag != 0 ) + free(jsonstr); + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","forwardhex"); + jaddstr(reqjson,"hex",hexstr); + free(hexstr); + msg = jprint(reqjson,1); + mlen = (int32_t)strlen(msg) + 1; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + //printf("found LPnode.(%s) forward.(%s)\n",peer->ipaddr,msg); + if ( LP_send(peer->pushsock,msg,mlen,0) == mlen ) + n++; + if ( n >= 8 )//sizeof(default_LPnodes)/sizeof(*default_LPnodes) ) + break; + } + if ( msg != 0 ) + free(msg); + if ( n == 0 ) + return(-1); + else return(n-1); +} + + +char *LP_broadcasted(cJSON *argjson) +{ + printf("RECV BROADCAST.(%s)\n",jprint(argjson,0)); + return(clonestr("{\"result\":\"need to update broadcast messages\"}")); +} +*/ + diff --git a/iguana/exchanges/LP_include.h b/iguana/exchanges/LP_include.h new file mode 100644 index 000000000..e0f794da8 --- /dev/null +++ b/iguana/exchanges/LP_include.h @@ -0,0 +1,574 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_include.h +// marketmaker +// + +#ifndef LP_INCLUDE_H +#define LP_INCLUDE_H + +#ifndef LP_TECHSUPPORT +#define LP_TECHSUPPORT 0 +#endif + +#define LP_DONT_CMDCHANNEL + +#ifdef FROMGUI +#define printf dontprintf + +voind dontprintf(char *formatstr,...) {} +#endif + +#define LP_MAJOR_VERSION "0" +#define LP_MINOR_VERSION "1" +#define LP_BUILD_NUMBER "17763" +#define LP_BARTERDEX_VERSION 1 +#define LP_MAGICBITS 1 + +#define LP_DONT_IMPORTPRIVKEY + +#ifdef FROM_JS +#include +#define sleep(x) emscripten_usleep((x) * 1000000) +void emscripten_usleep(int32_t x); // returns immediate, no sense for sleeping +#define usleep(x) emscripten_usleep(x) +// ./autogen.sh +// emconfigure ./configure CFLAGS="-s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -O2" +// Edit src/core/sock.c and add here #include for INT_MAX support +// emmake make +// cp .libs/libnanomsg.a ~/SuperNET/OSlibs/js +#endif +//#define LP_STRICTPEERS + +//#define LP_DISABLE_DISTCOMBINE + +#define LP_MAXVINS 64 +#define LP_HTTP_TIMEOUT 3 // 1 is too small due to edge cases of time(NULL) +#define LP_AUTOTRADE_TIMEOUT 180 +#define LP_RESERVETIME 600 //(LP_AUTOTRADE_TIMEOUT * 2) +#define ELECTRUM_TIMEOUT 13 +#define LP_ELECTRUM_KEEPALIVE 60 +#define LP_ELECTRUM_MAXERRORS 777 +#define LP_MEMPOOL_TIMEINCR 10 +#define LP_SCREENWIDTH 1024 + +#define LP_MIN_PEERS 8 +#define LP_MAX_PEERS 32 + +#define LP_MAXDESIRED_UTXOS (IAMLP != 0 ? 256 : 64) +#define LP_MINDESIRED_UTXOS (IAMLP != 0 ? 64 : 16) +#define LP_DUSTCOMBINE_THRESHOLD 1000000 + +// RTmetrics +#define LP_RTMETRICS_TOPGROUP 1.01 +//#define LP_MAXPENDING_SWAPS 13 +#define LP_CLIENT_STATSPARSE (90 * 1024 * 1024) + +#define LP_COMMAND_SENDSOCK NN_PUSH +#define LP_COMMAND_RECVSOCK NN_PULL + +#define DPOW_MIN_ASSETCHAIN_SIGS 11 +#define LP_ENCRYPTED_MAXSIZE (16384 + 2 + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES) + +#define LP_MAXPUBKEY_ERRORS 10 +#define PSOCK_KEEPALIVE 3600 +#define MAINLOOP_PERSEC 100 +#define MAX_PSOCK_PORT 60000 +#define MIN_PSOCK_PORT 10000 +#define LP_GETINFO_INCR 30 +#define LP_ORDERBOOK_DURATION 180 + +#define LP_MAXPEER_ERRORS 3 +#define LP_MINPEER_GOOD 20 +#define LP_PEERGOOD_ERRORDECAY 0.9 + +#define LP_SWAPSTEP_TIMEOUT 30 +#define LP_MIN_TXFEE 1000 +#define LP_MINVOL 20 +#define LP_MINCLIENTVOL 200 +#define LP_MINSIZE_TXFEEMULT 10 +#define LP_REQUIRED_TXFEE 0.8 + +#define LP_DEXFEE(destsatoshis) ((destsatoshis) / INSTANTDEX_INSURANCEDIV) +#define LP_DEPOSITSATOSHIS(satoshis) ((satoshis) + (satoshis >> 3)) + +#define INSTANTDEX_DECKSIZE 1000 +#define INSTANTDEX_LOCKTIME (3600*2 + 300*2) +#define INSTANTDEX_INSURANCEDIV 777 +#define INSTANTDEX_PUBKEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" +#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" +#define JUMBLR_RMD160 "5177f8b427e5f47342a4b8ab5dac770815d4389e" +#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" +#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" +#define INSTANTDEX_KMD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" +#define BOTS_BONDADDRESS "RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P" +#define BOTS_BONDPUBKEY33 "03e641d22e1ff5a7d45c8880537e0b0a114d7b9fee2c18a6b4a8a80b6285292990" +#define LP_WEEKMULTBAD (7 * 24 * 2600) +#define LP_WEEKMULT (7 * 24 * 3600) +#define LP_FIRSTWEEKTIME 1510790400 // must be 0 mod LP_WEEKMULT + +//#define BASILISK_DISABLEWAITTX +//#define BASILISK_DISABLESENDTX +#define LP_RPCPORT 7783 + +#define LP_PROPAGATION_SLACK 100 // txid ordering is not enforced, so getting extra recent txid +#define LP_AVETXSIZE 256 +#define LP_CACHEDURATION 60 +#define BASILISK_DEFAULT_NUMCONFIRMS 1 +#define BASILISK_DEFAULT_MAXCONFIRMS 6 +#define DEX_SLEEP 3 +#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2)) + +#define LP_IS_ZCASHPROTOCOL 1 +#define LP_IS_BITCOINCASH 2 +#define LP_IS_BITCOINGOLD 79 + +#define SIGHASH_FORKID 0x40 +#define ZKSNARK_PROOF_SIZE 296 +#define ZCASH_SOLUTION_ELEMENTS 1344 + +#define LP_REQUEST 0 +#define LP_RESERVED 1 +#define LP_CONNECT 2 +#define LP_CONNECTED 3 + +#define LP_DONTCHANGE_ERRMSG0 "couldnt find coin locally installed" +#define LP_DONTCHANGE_ERRMSG1 "coin is disabled" + +extern char GLOBAL_DBDIR[]; +extern int32_t IAMLP; + +struct iguana_msgvin +{ + bits256 prev_hash; + uint8_t *vinscript,*userdata,*spendscript,*redeemscript; + uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; +}; + +struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; + +struct iguana_msgtx +{ + uint32_t version,tx_in,tx_out,lock_time; + struct iguana_msgvin *vins; + struct iguana_msgvout *vouts; + bits256 txid; + int32_t allocsize,timestamp,numinputs,numoutputs; + int64_t inputsum,outputsum,txfee; + uint8_t *serialized; +}; + +struct iguana_msgjoinsplit +{ + uint64_t vpub_old,vpub_new; + bits256 anchor,nullifiers[2],commitments[2],ephemeralkey; + bits256 randomseed,vmacs[2]; + uint8_t zkproof[ZKSNARK_PROOF_SIZE]; + uint8_t ciphertexts[2][601]; +}; + +struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; + +struct vin_info +{ + struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; + int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,userdatalen,suppress_pubkeys,ignore_cltverr; + uint32_t sequence,unspentind,hashtype; struct vin_signer signers[16]; char coinaddr[65]; + uint8_t rmd160[20],spendscript[10000],p2shscript[10000],userdata[10000]; +}; + +/*struct basilisk_swapmessage +{ + bits256 srchash,desthash; + uint32_t crc32,msgbits,quoteid,datalen; + uint8_t *data; +};*/ + +struct basilisk_swap; + +struct basilisk_rawtxinfo +{ + char destaddr[64]; + bits256 txid,signedtxid,actualtxid; + int64_t amount,change,inputsum; + int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; + uint32_t locktime,crcs[2]; + uint8_t addrtype,pubkey33[33],rmd160[20]; +}; + +struct basilisk_request +{ + uint32_t requestid,timestamp,quoteid,quotetime; // 0 to 15 + int64_t srcamount,unused; // 16 to 31 + bits256 srchash; // 32 to 63 + bits256 desthash; + char src[68],dest[68]; + uint64_t destamount; + int32_t optionhours,DEXselector; +}; + +struct basilisk_rawtx +{ + char name[32],symbol[65]; + struct iguana_msgtx msgtx; + struct basilisk_rawtxinfo I; + char vinstr[8192],p2shaddr[64]; + cJSON *vins; + bits256 utxotxid; int32_t utxovout; + uint8_t txbytes[16384],spendscript[512],redeemscript[1024],extraspace[4096],pubkey33[33]; +}; + +struct basilisk_swapinfo +{ + struct basilisk_request req; + char bobstr[128],alicestr[128]; + bits256 myhash,otherhash,orderhash; + uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; + int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms; + int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee; + + bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; + uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2]; + int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate,pad2; + uint8_t secretAm[20],secretBn[20]; + uint8_t secretAm256[32],secretBn256[32]; + uint8_t userdata_aliceclaim[256],userdata_aliceclaimlen; + uint8_t userdata_alicereclaim[256],userdata_alicereclaimlen; + uint8_t userdata_alicespend[256],userdata_alicespendlen; + uint8_t userdata_bobspend[256],userdata_bobspendlen; + uint8_t userdata_bobreclaim[256],userdata_bobreclaimlen; + uint8_t userdata_bobrefund[256],userdata_bobrefundlen; +}; + +#define BASILISK_ALICESPEND 0 +#define BASILISK_BOBSPEND 1 +#define BASILISK_BOBPAYMENT 2 +#define BASILISK_ALICEPAYMENT 3 +#define BASILISK_BOBDEPOSIT 4 +#define BASILISK_OTHERFEE 5 +#define BASILISK_MYFEE 6 +#define BASILISK_BOBREFUND 7 +#define BASILISK_BOBRECLAIM 8 +#define BASILISK_ALICERECLAIM 9 +#define BASILISK_ALICECLAIM 10 +//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 +char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" }; + +struct LP_swap_remember +{ + bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)]; + uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid; + int64_t values[sizeof(txnames)/sizeof(*txnames)]; + uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate; + int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)]; + uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],Predeemscript[1024],Dredeemscript[1024],pubkey33[33],other33[33]; + char Agui[65],Bgui[65],gui[65],src[65],dest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)]; +}; + +struct LP_outpoint +{ + bits256 spendtxid; + uint64_t value,interest; + int32_t spendvini,spendheight; + char coinaddr[64]; +}; + +struct LP_transaction +{ + UT_hash_handle hh; + bits256 txid; + long fpos; + int32_t height,numvouts,numvins,len,SPV; + uint8_t *serialized; + struct LP_outpoint outpoints[]; +}; + +struct iguana_info +{ + UT_hash_handle hh; + portable_mutex_t txmutex,addrmutex,addressutxo_mutex; struct LP_transaction *transactions; struct LP_address *addresses; + uint64_t txfee; + int32_t numutxos,notarized,longestchain,firstrefht,firstscanht,lastscanht,height; uint16_t busport,did_addrutxo_reset; + uint32_t txversion,dPoWtime,lastresetutxo,loadedcache,electrumlist,lastunspent,importedprivkey,lastpushtime,lastutxosync,addr_listunspent_requested,lastutxos,updaterate,counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor,obooktime; + uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag,userconfirms,isassetchain,maxconfirms; + char symbol[128],smartaddr[64],userpass[1024],serverport[128],instantdex_address[64]; + // portfolio + double price_kmd,force,perc,goal,goalperc,relvolume,rate; + void *electrum; void *ctx; + uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB; + uint8_t pubkey33[33],zcash; + int32_t privkeydepth; + bits256 cachedtxid,notarizationtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen; + bits256 cachedmerkle,notarizedhash; int32_t cachedmerkleheight; +}; + +struct _LP_utxoinfo { bits256 txid; uint64_t value; int32_t vout,height; }; + +struct LP_utxostats { uint32_t sessionid,lasttime,errors,swappending,spentflag,lastspentcheck,bestflag; }; + +struct LP_utxobob { struct _LP_utxoinfo utxo,deposit; }; + +struct LP_utxoalice { struct _LP_utxoinfo utxo,fee; }; + +//struct LP_utxoswap { bits256 otherpubkey; uint64_t satoshis; }; + +struct LP_utxoinfo +{ + UT_hash_handle hh,hh2; + bits256 pubkey; + struct _LP_utxoinfo payment,deposit,fee; + struct LP_utxostats T; + int64_t swap_satoshis; + //struct LP_utxoswap S; + int32_t iambob,iamlp; + uint8_t key[sizeof(bits256) + sizeof(int32_t)]; + uint8_t key2[sizeof(bits256) + sizeof(int32_t)]; + char coin[65],coinaddr[64],gui[16];//spendscript[256]; +}; + +struct LP_address_utxo +{ + struct LP_address_utxo *next,*prev; + struct _LP_utxoinfo U; + int32_t SPV,spendheight; + //uint32_t timestamp; +}; + +struct LP_address +{ + UT_hash_handle hh; + struct LP_address_utxo *utxos; + bits256 pubkey; + int64_t balance,total,instantdex_credits; + uint32_t timestamp,n,unspenttime,instantdextime; + int32_t unspentheight; + char coinaddr[64]; + uint8_t pubsecp[33],didinstantdex; +}; + +struct LP_peerinfo +{ + UT_hash_handle hh; + bits256 pubkey; + uint64_t ip_port; + uint32_t recvtime,numrecv,ipbits,errortime,errors,numpeers,needping,lasttime,connected,lastutxos,lastpeers,diduquery,good,sessionid; + int32_t pushsock,subsock,isLP,pairsock; + uint16_t port,netid; + char ipaddr[64]; +}; + +struct LP_quoteinfo +{ + struct basilisk_request R; + bits256 srchash,desthash,txid,txid2,desttxid,feetxid,privkey; + int64_t othercredits; + uint64_t satoshis,txfee,destsatoshis,desttxfee,aliceid; + uint32_t timestamp,quotetime,tradeid; + int32_t vout,vout2,destvout,feevout,pair; + char srccoin[65],coinaddr[64],destcoin[65],destaddr[64],gui[64]; +}; + +struct LP_endpoint { int32_t pair; char ipaddr[64]; uint16_t port; }; + +struct basilisk_swap +{ + void *ctx; //struct LP_utxoinfo *utxo; + struct LP_endpoint N; + void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob); + int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; + uint32_t lasttime,aborted,tradeid; + FILE *fp; + bits256 persistent_privkey,persistent_pubkey; + struct basilisk_swapinfo I; + struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; + bits256 privkeys[INSTANTDEX_DECKSIZE]; + //struct basilisk_swapmessage *messages; int32_t nummessages,sentflag; + char Bdeposit[64],Bpayment[64]; + uint64_t aliceid,otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; + uint8_t persistent_pubkey33[33],persistent_other33[33],changermd160[20],pad[15],verifybuf[100000]; +}; + +struct LP_pubkey_quote +{ + struct LP_pubkey_quote *next,*prev; + float price; + uint32_t maxutxo,aveutxo; + uint8_t baseind,relind,numutxos,scale; +}; + +struct LP_swapstats +{ + UT_hash_handle hh; + struct LP_quoteinfo Q; + bits256 bobdeposit,alicepayment,bobpayment,paymentspent,Apaymentspent,depositspent; + int32_t bobdeposit_ht,alicepayment_ht,bobpayment_ht,paymentspent_ht,Apaymentspent_ht,depositspent_ht; + double qprice; + uint64_t aliceid; + int32_t bobneeds_dPoW,aliceneeds_dPoW; + uint32_t ind,methodind,finished,expired,lasttime,dPoWfinished; + char alicegui[65],bobgui[65]; +}; + +struct LP_pubswap { struct LP_pubswap *next,*prev; struct LP_swapstats *swap; }; + +#define LP_MAXPRICEINFOS 256 +struct LP_pubkey_info +{ + UT_hash_handle hh; + bits256 pubkey; + struct LP_pubkey_quote *quotes; + struct LP_pubswap *bobswaps,*aliceswaps; + int64_t dynamictrust,unconfcredits; + uint32_t timestamp,numerrors,lasttime,slowresponse; + int32_t istrusted,pairsock; + uint8_t rmd160[20],sig[65],pubsecp[33],siglen; +}; + +struct electrum_info +{ + queue_t sendQ,pendingQ; + portable_mutex_t mutex,txmutex; + struct electrum_info *prev; + int32_t bufsize,sock,*heightp,numerrors; + struct iguana_info *coin; + uint32_t stratumid,lasttime,keepalive,pending,*heighttimep; + char ipaddr[64],symbol[66]; + uint16_t port; + uint8_t buf[]; +}; + +struct LP_trade +{ + struct LP_trade *next,*prev; + UT_hash_handle hh; + uint64_t aliceid; + int64_t besttrust,bestunconfcredits; + double bestprice; + uint32_t negotiationdone,bestresponse,connectsent,firsttime,lasttime,firstprocessed,lastprocessed,newtime; + char pairstr[64],funcid,iambob; + struct LP_quoteinfo Qs[4],Q; +}; + +uint32_t LP_sighash(char *symbol,int32_t zcash); +int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item); +int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp); +int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson); +struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr); +void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,uint8_t *data,int32_t datalen,int32_t vout); +void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx); +uint32_t basilisk_requestid(struct basilisk_request *rp); +uint32_t basilisk_quoteid(struct basilisk_request *rp); +struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust); +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params); +uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend); +int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys); +void LP_quotesinit(char *base,char *rel); +int32_t LP_forward(void *ctx,char *myipaddr,int32_t pubsock,bits256 pubkey,char *jsonstr,int32_t freeflag); +struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port); +uint64_t LP_value_extract(cJSON *obj,int32_t addinterest); +int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout); +char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,int32_t stats_JSONonly); +int64_t LP_kmdvalue(char *symbol,int64_t satoshis); +int64_t LP_komodo_interest(bits256 txid,int64_t value); +void LP_availableset(bits256 txid,int32_t vout); +int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2); +int32_t LP_pullsock_check(void *ctx,char **retstrp,char *myipaddr,int32_t pubsock,int32_t pullsock); +int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item); +void LP_unspents_cache(char *symbol,char *addr,char *arraystr,int32_t updatedflag); +uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired,int32_t cmdchannel,char *ipaddr); +//void LP_utxo_clientpublish(struct LP_utxoinfo *utxo); +//int32_t LP_coinbus(uint16_t coin_busport); +int32_t LP_nanomsg_recvs(void *ctx); +int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool); +void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid); +void LP_autoprices_update(char *method,char *base,double basevol,char *rel,double relvol); +cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len); +cJSON *LP_transaction_fromdata(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len); +uint64_t LP_RTsmartbalance(struct iguana_info *coin); +int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin); +int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,char *msg); +struct iguana_info *LP_coinfind(char *symbol); +int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32); +char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price); +int32_t LP_merkleproof(struct iguana_info *coin,char *coinaddr,struct electrum_info *ep,bits256 txid,int32_t height); +cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid); +cJSON *LP_myzdebits(); +int32_t _LP_utxos_remove(bits256 txid,int32_t vout); +int32_t LP_utxos_remove(bits256 txid,int32_t vout); +struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins); +void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid); +uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen); +struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr); +struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr); +struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr); +int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash); +//void LP_butxo_swapfields_set(struct LP_utxoinfo *butxo); +struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout); +int64_t LP_myzcredits(); +void test_validate(struct iguana_info *coin,char *signedtx); +void LP_instantdex_depositadd(char *coinaddr,bits256 txid); +int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr,char *origcoinaddr); +void LP_ports(uint16_t *pullportp,uint16_t *pubportp,uint16_t *busportp,uint16_t netid); +int32_t LP_destaddr(char *destaddr,cJSON *item); +int32_t LP_waitmempool(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t duration); +cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel); +uint32_t LP_heighttime(char *symbol,int32_t height); +uint64_t LP_unspents_load(char *symbol,char *addr); +int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout); +struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid); +cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj); +int32_t LP_mempoolscan(char *symbol,bits256 searchtxid); +int32_t LP_txheight(struct iguana_info *coin,bits256 txid); +int32_t LP_numpeers(); +double LP_CMCbtcprice(double *price_usdp,char *symbol); +char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid,int32_t forceflag); +int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance); +int32_t LP_address_utxoadd(int32_t skipsearch,uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight); +void LP_smartutxos_push(struct iguana_info *coin); +void LP_cacheptrs_init(struct iguana_info *coin); +cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret); +cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout); +void LP_postutxos(char *symbol,char *coinaddr); +int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag); +uint16_t LP_randpeer(char *destip); +void LP_tradebot_pauseall(); +void LP_portfolio_reset(); +struct LP_pubkey_info *LP_pubkeyadd(bits256 pubkey); +uint32_t LP_atomic_locktime(char *base,char *rel); +struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey); +char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired,int32_t cmdchannel); +char *LP_unspents_filestr(char *symbol,char *addr); +cJSON *bitcoin_data2json(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys,int32_t zcash); +//int32_t LP_butxo_findeither(bits256 txid,int32_t vout); +cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxid2); +int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid); +double LP_getestimatedrate(struct iguana_info *coin); +struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout); +struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid,int32_t vout); +int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue); +struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr); +int64_t LP_outpoint_amount(char *symbol,bits256 txid,int32_t vout); +void LP_initpeers(int32_t pubsock,struct LP_peerinfo *mypeer,char *myipaddr,uint16_t myport,uint16_t netid,char *seednode); + +void LP_listunspent_query(char *symbol,char *coinaddr); +int32_t bitcoin_priv2wif(char *symbol,uint8_t wiftaddr,char *wifstr,bits256 privkey,uint8_t addrtype); +int bech32_convert_bits(uint8_t *out,int32_t *outlen,int outbits,const uint8_t *in,int32_t inlen,int inbits,int pad); +int bech32_decode(char *hrp,uint8_t *data,int32_t *data_len,const char *input); +int bech32_encode(char *output,const char *hrp,const uint8_t *data,int32_t data_len); +void HashGroestl(void * buf, const void * pbegin, int len); + +#endif diff --git a/iguana/exchanges/LP_instantdex.c b/iguana/exchanges/LP_instantdex.c new file mode 100644 index 000000000..4dd519de7 --- /dev/null +++ b/iguana/exchanges/LP_instantdex.c @@ -0,0 +1,659 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// +// LP_instantdex.c +// marketmaker +// + +void LP_instantdex_txidaddfname(char *fname,char *afname,char *coinaddr) +{ + if ( coinaddr == 0 || coinaddr[0] == 0 ) + { + sprintf(fname,"%s/instantdex.json",GLOBAL_DBDIR); + sprintf(afname,"%s/instantdex_append.json",GLOBAL_DBDIR); + } + else + { + sprintf(fname,"%s/instantdex_%s.json",GLOBAL_DBDIR,coinaddr); + sprintf(afname,"%s/instantdex_%s_append.json",GLOBAL_DBDIR,coinaddr); + } +} + +cJSON *LP_instantdex_txids(int32_t appendonly,char *coinaddr) +{ + char *filestr,fname[1024],afname[1024]; long fsize; cJSON *retjson=0; + LP_instantdex_txidaddfname(fname,afname,coinaddr); + if ( (filestr= OS_filestr(&fsize,appendonly != 0 ? afname : fname)) != 0 ) + { + retjson = cJSON_Parse(filestr); + free(filestr); + } else printf("couldnt open (%s) or (%s)\n",fname,afname); + return(retjson); +} + +void LP_instantdex_filewrite(int32_t appendfile,cJSON *array,char *coinaddr) +{ + FILE *fp; char *filestr,fname[1024],afname[1024]; + LP_instantdex_txidaddfname(fname,afname,coinaddr); + if ( (fp= fopen(appendfile == 0 ? fname : afname,"wb")) != 0 ) + { + filestr = jprint(array,0); + fwrite(filestr,1,strlen(filestr)+1,fp); + fclose(fp); + free(filestr); + } +} + +void LP_instantdex_deposituniq(FILE *fp,bits256 txid) +{ + int32_t i,n; bits256 prevtxid; char str[65]; + n = (int32_t)(ftell(fp) / sizeof(txid)); + for (i=0; i 0 ) + { + for (i=0; i 0 ) + { + LP_instantdex_deposituniq(fp,prevtxid); + fflush(fp); + } + } + } + free_json(array); + } + } + } + } else fseek(fp,0,SEEK_END); + if ( fp != 0 && bits256_nonz(txid) != 0 ) + { + LP_instantdex_deposituniq(fp,txid); + fclose(fp); + } + LP_instantdex_filescreate(coinaddr); +} + +int32_t LP_deposit_addr(char *symbol,char *p2shaddr,uint8_t *script,uint8_t taddr,uint8_t p2shtype,uint32_t timestamp,uint8_t *pubsecp33) +{ + uint8_t elsepub33[33],p2sh_rmd160[20]; int32_t n; + decode_hex(elsepub33,33,BOTS_BONDPUBKEY33); + n = bitcoin_performancebond(p2sh_rmd160,script,0,timestamp,pubsecp33,elsepub33); + bitcoin_address(symbol,p2shaddr,taddr,p2shtype,script,n); + return(n); +} + +char *LP_instantdex_deposit(struct iguana_info *coin,int32_t weeks,double amount,int32_t broadcast) +{ + char p2shaddr[64],*retstr,*hexstr; uint8_t script[512]; int32_t weeki,scriptlen; cJSON *argjson,*retjson,*array,*item,*obj; uint32_t timestamp; bits256 txid,sendtxid; uint64_t amount64; + if ( strcmp(coin->symbol,"KMD") != 0 ) + return(clonestr("{\"error\":\"instantdex deposit must be in KMD\"}")); + if ( amount < 10.0 ) + return(clonestr("{\"error\":\"minimum instantdex deposit is 10 KMD\"}")); + if ( weeks <= 0 || weeks > 52 ) + return(clonestr("{\"error\":\"weeks must be between 1 and 52\"}")); + if ( weeks > 0 ) + { + timestamp = (uint32_t)time(NULL); + timestamp /= LP_WEEKMULT; + timestamp += weeks+2; + timestamp *= LP_WEEKMULT; + weeki = (timestamp - LP_FIRSTWEEKTIME) / LP_WEEKMULT; + if ( weeks >= 10000 ) + return(clonestr("{\"error\":\"numweeks must be less than 10000\"}")); + } else timestamp = (uint32_t)time(NULL) + 300, weeki = 0; + scriptlen = LP_deposit_addr(coin->symbol,p2shaddr,script,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp); + argjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,p2shaddr,amount); + jaddi(array,item); + item = cJSON_CreateObject(); + amount64 = (amount * SATOSHIDEN) / 1000; + amount64 = (amount64 / 10000) * 10000 + weeki; + jaddnum(item,BOTS_BONDADDRESS,dstr(amount64)); + jaddi(array,item); + item = cJSON_CreateObject(); + jaddnum(item,coin->smartaddr,0.0001); + jaddi(array,item); + jadd(argjson,"outputs",array); + //printf("deposit.(%s)\n",jprint(argjson,0)); + if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"result") != 0 ) + jdelete(retjson,"result"); + jaddstr(retjson,"address",p2shaddr); + jaddnum(retjson,"expiration",timestamp); + jaddnum(retjson,"deposit",amount); + if ( (obj= jobj(retjson,"complete")) != 0 && is_cJSON_True(obj) != 0 && (hexstr= jstr(retjson,"hex")) != 0 ) + { + txid = jbits256(retjson,"txid"); + if ( broadcast != 0 ) + { + if (bits256_nonz(txid) != 0 ) + { + sendtxid = LP_broadcast("deposit","KMD",hexstr,txid); + if ( bits256_cmp(sendtxid,txid) != 0 ) + { + jaddstr(retjson,"error","broadcast txid mismatch"); + jaddbits256(retjson,"broadcast",sendtxid); + free(retstr); + return(jprint(retjson,1)); + } + else + { + jaddstr(retjson,"result","success"); + jaddbits256(retjson,"broadcast",sendtxid); + LP_instantdex_depositadd(coin->smartaddr,txid); + free(retstr); + return(jprint(retjson,1)); + } + } + else + { + jaddstr(retjson,"error","couldnt broadcast since no txid created"); + free(retstr); + return(jprint(retjson,1)); + } + } + else + { + jaddstr(retjson,"result","success"); + free(retstr); + return(jprint(retjson,1)); + } + } + else + { + jaddstr(retjson,"error","couldnt create deposit txid"); + free(retstr); + return(jprint(retjson,1)); + } + free_json(retjson); + } + free(retstr); + } + return(clonestr("{\"error\":\"error with LP_withdraw for instantdex deposit\"}")); +} + +int64_t LP_claimtx(void *ctx,struct iguana_info *coin,bits256 *claimtxidp,bits256 utxotxid,int32_t utxovout,uint64_t satoshis,char *vinaddr,uint32_t claimtime,uint8_t *redeemscript,int32_t redeemlen) +{ + uint8_t userdata[2]; char *signedtx; bits256 signedtxid,sendtxid; int32_t isbots,userdatalen; int64_t destamount,sum = 0; + if ( strcmp(coin->smartaddr,BOTS_BONDADDRESS) == 0 ) + isbots = 1; + else isbots = 0; + userdata[0] = (isbots == 0) ? 0x51 : 0; + userdatalen = 1; + utxovout = 0; + memset(claimtxidp,0,sizeof(*claimtxidp)); + char str[65]; printf("LP_claimtx satoshis %.8f %s/v%d\n",dstr(satoshis),bits256_str(str,utxotxid),utxovout); + if ( (signedtx= basilisk_swap_bobtxspend(&signedtxid,10000,"instantdexclaim",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,G.LP_privkey,0,redeemscript,redeemlen,userdata,userdatalen,utxotxid,utxovout,coin->smartaddr,G.LP_pubsecp,0,claimtime,&destamount,0,0,vinaddr,1,coin->zcash)) != 0 ) + { + printf("signedtx.(%s)\n",signedtx); + sendtxid = LP_broadcast("claim","KMD",signedtx,signedtxid); + if ( bits256_cmp(sendtxid,signedtxid) == 0 ) + { + *claimtxidp = sendtxid; + sum += (satoshis - coin->txfee); + } + else printf("error sending %s\n",bits256_str(str,signedtxid)); + free(signedtx); + } else printf("error claiming instantdex deposit %s/v%d %.8f\n",bits256_str(str,utxotxid),utxovout,dstr(satoshis)); + return(sum); +} + +int32_t LP_claim_submit(void *ctx,cJSON *txids,int64_t *sump,struct iguana_info *coin,bits256 utxotxid) +{ + uint8_t redeemscript[512]; bits256 claimtxid; cJSON *txjson,*vout0,*vout1,*vout2,*vouts,*item; int32_t numvouts; char str[65],vinaddr[64],destaddr[64],checkaddr[64]; int32_t j,utxovout,flagi = 0,redeemlen,weeki,iter; int64_t weeksatoshis,satoshis; uint32_t expiration,claimtime; + if ( (txjson= LP_gettx(coin->symbol,utxotxid,1)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && numvouts >= 3 ) + { + vout0 = jitem(vouts,0); + LP_destaddr(vinaddr,vout0); + satoshis = LP_value_extract(vout0,1); + vout2 = jitem(vouts,2); + LP_destaddr(destaddr,vout2); + if ( strcmp(destaddr,coin->smartaddr) == 0 ) + { + vout1 = jitem(vouts,1); + weeksatoshis = LP_value_extract(vout1,0); + weeki = (int32_t)(weeksatoshis % 10000); + for (iter=0; iter<2; iter++) + for (j=-168; j<=168; j++) + { + if ( iter == 1 ) + expiration = ((weeki * LP_WEEKMULTBAD + j*3600) + LP_FIRSTWEEKTIME); + else expiration = ((weeki * LP_WEEKMULT + j*3600) + LP_FIRSTWEEKTIME); + redeemlen = LP_deposit_addr(coin->symbol,checkaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp); + if ( strcmp(checkaddr,vinaddr) == 0 ) + { + flagi = 1; + claimtime = (uint32_t)time(NULL)-777; + item = cJSON_CreateObject(); + jaddbits256(item,"txid",utxotxid); + jaddnum(item,"deposit",dstr(LP_value_extract(vout0,0))); + if ( coin->electrum == 0 ) + jaddnum(item,"interest",dstr(satoshis)-dstr(LP_value_extract(vout0,0))); + else jaddnum(item,"interest",dstr(LP_komodo_interest(utxotxid,satoshis))); + if ( claimtime <= expiration ) + { + printf("iter.%d j.%d claimtime.%u vs %u, wait %d seconds to %s claim %.8f\n",iter,j,claimtime,expiration,(int32_t)expiration-claimtime,bits256_str(str,utxotxid),dstr(satoshis)); + jaddnum(item,"waittime",(int32_t)expiration-claimtime); + jaddi(txids,item); + break; + } + else + { + utxovout = 0; + *sump += LP_claimtx(ctx,coin,&claimtxid,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); + if ( bits256_nonz(claimtxid) != 0 ) + { + jaddbits256(item,"claimtxid",claimtxid); + jaddi(txids,item); + } + } + } //else printf("expiration.%u j.%d checkaddr.(%s) != vinaddr.%s\n",expiration,j,checkaddr,vinaddr); + if ( flagi != 0 ) + break; + } + } else printf("vout2 dest.(%s) != %s\n",destaddr,coin->smartaddr); + } else printf("numvouts %d != 3\n",numvouts); + free_json(txjson); + } else printf("cant get transaction flagi.%d\n",flagi); + return(flagi); +} + +char *LP_instantdex_claim(struct iguana_info *coin) +{ + static void *ctx; static int32_t firsttime = 1; + int32_t i,n; cJSON *array,*txids,*newarray,*retjson; int64_t sum; bits256 utxotxid; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + if ( strcmp(coin->symbol,"KMD") != 0 ) + return(clonestr("{\"error\":\"instantdex deposit must be in KMD\"}")); + sum = 0; + txids = cJSON_CreateArray(); + newarray = cJSON_CreateArray(); + if ( (array= LP_instantdex_txids(firsttime,coin->smartaddr)) != 0 ) + { + printf("claiming from.(%s)\n",jprint(array,0)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 ) + LP_instantdex_filewrite(0,newarray,coin->smartaddr); + free_json(newarray); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"claimed",dstr(sum)); + jadd(retjson,"txids",txids); + return(jprint(retjson,1)); +} + +int64_t LP_instantdex_credit(int32_t dispflag,char *coinaddr,int64_t satoshis,int32_t weeki,char *p2shaddr,bits256 txid) +{ + uint32_t timestamp; struct LP_address *ap; struct iguana_info *coin = LP_coinfind("KMD"); + if ( coin != 0 ) + { + timestamp = LP_FIRSTWEEKTIME + weeki*LP_WEEKMULT; + if ( (ap= LP_address(coin,coinaddr)) != 0 && time(NULL) < timestamp-60*3600 ) + { + ap->instantdex_credits += satoshis; + ap->didinstantdex = 1; + if ( 0 && dispflag != 0 ) + printf("InstantDEX credit.(%s) %.8f weeki.%d (%s) -> sum %.8f\n",coinaddr,dstr(satoshis),weeki,p2shaddr,dstr(ap->instantdex_credits)); + return(satoshis); + } //else printf("null ap.%p or expired %ld\n",ap,time(NULL) - (timestamp-60*3600)); + } + return(0); +} + +int64_t LP_instantdex_creditcalc(struct iguana_info *coin,int32_t dispflag,bits256 txid,char *refaddr,char *origcoinaddr) +{ + cJSON *txjson,*vouts,*txobj,*item; int64_t satoshis=0,amount64; int32_t weeki,numvouts; char destaddr[64],p2shaddr[64]; + if ( (txjson= LP_gettx(coin->symbol,txid,0)) != 0 ) + { + // vout0 deposit, vout1 botsfee, vout2 smartaddress + if ( (vouts= jarray(&numvouts,txjson,"vout")) > 0 && numvouts >= 3 && LP_destaddr(destaddr,jitem(vouts,2)) == 0 ) + { + if ( refaddr != 0 && strcmp(refaddr,destaddr) != 0 ) + { + printf("LP_instantdex_creditcalc for (%s) but deposit sent for orig.(%s) (%s)\n",refaddr,origcoinaddr,destaddr); + } + else + { + amount64 = LP_value_extract(jitem(vouts,1),0); + weeki = (amount64 % 10000); + item = jitem(vouts,0); + satoshis = LP_value_extract(item,0); + //char str[65]; printf("%s %s funded %.8f weeki.%d (%s)\n",bits256_str(str,txid),destaddr,dstr(satoshis),weeki,jprint(item,0)); + if ( LP_destaddr(p2shaddr,item) == 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,p2shaddr,txid,0)) != 0 ) + { + free_json(txobj); + LP_instantdex_credit(dispflag,destaddr,satoshis,weeki,p2shaddr,txid); + } //else printf("already spent\n"); + } else printf("error getting p2shaddr.(%s)\n",p2shaddr); + } + } + free_json(txjson); + } + return(satoshis); +} + +#ifdef bruteforce +/*void LP_instantdex_deposits(struct iguana_info *coin) +{ + static int dispflag = 1; + cJSON *array,*item; int32_t i,n,height,vout; bits256 txid; struct LP_address *ap,*tmp; + if ( coin->electrum != 0 )//&& coin->electruminstantdex != 0 ) + return; + HASH_ITER(hh,coin->addresses,ap,tmp) + { + ap->instantdex_credits = 0; + } + if ( (array= LP_listreceivedbyaddress("KMD",BOTS_BONDADDRESS)) != 0 ) + { + //printf("instantdex.(%s)\n",jprint(array,0)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ielectrum != 0 ) + { + item = jitem(array,i); + LP_listunspent_parseitem(coin,&txid,&vout,&height,item); + } else txid = jbits256i(array,i); + LP_instantdex_creditcalc(coin,dispflag,txid,0); + } + } + free_json(array); + } + dispflag = 0; +}*/ +#endif + +int64_t LP_dynamictrust(int64_t credits,bits256 pubkey,int64_t kmdvalue) +{ + struct LP_pubswap *ptr,*tmp; struct LP_swapstats *sp; struct LP_pubkey_info *pubp; struct LP_address *ap; char coinaddr[64]; struct iguana_info *coin; int64_t swaps_kmdvalue = 0; + if ( (coin= LP_coinfind("KMD")) != 0 && (pubp= LP_pubkeyfind(pubkey)) != 0 ) + { + bitcoin_address(coin->symbol,coinaddr,coin->taddr,coin->pubtype,pubp->pubsecp,33); + DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + swaps_kmdvalue += LP_kmdvalue(sp->Q.srccoin,sp->Q.satoshis); + } + DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + swaps_kmdvalue += LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); + } + if ( credits == 0 && (ap= LP_address(coin,coinaddr)) != 0 ) + credits = ap->instantdex_credits; + if ( credits != 0 && (swaps_kmdvalue+kmdvalue) > credits ) + { + if ( 0 ) + { + DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + printf("unfinished bob %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); + } + DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + printf("unfinished alice %llu r%u-r%u src.%s %.8f dest.%s %.8f -> price %.8f value %.8f\n",(long long)sp->aliceid,sp->Q.R.requestid,sp->Q.R.quoteid,sp->Q.srccoin,dstr(sp->Q.satoshis),sp->Q.destcoin,dstr(sp->Q.destsatoshis),(double)sp->Q.destsatoshis/(sp->Q.satoshis+1),dstr(LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis))); + } + } + //printf("REJECT: %s instantdex_credits %.8f vs (%.8f + current %.8f)\n",coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue)); + } + if ( 0 && credits != 0 ) + printf("%s %s othercredits %.8f debits %.8f + %.8f -> %.8f\n",coin->symbol,coinaddr,dstr(credits),dstr(swaps_kmdvalue),dstr(kmdvalue),dstr(credits - (swaps_kmdvalue+kmdvalue))); + return(credits - (swaps_kmdvalue+kmdvalue)); + } + return(0); +} + +int64_t LP_instantdex_proofcheck(char *symbol,char *coinaddr,cJSON *proof,int32_t num) +{ + uint8_t rmd160[20],addrtype,taddr=0; int64_t credits=0; int32_t i,j; bits256 prevtxid,txid; char othersmartaddr[64]; struct iguana_info *coin,*origcoin; struct LP_address *ap = 0; + if ( (coin= LP_coinfind("KMD")) != 0 ) + { + if ( (origcoin= LP_coinfind(symbol)) != 0 ) + taddr = origcoin->taddr; + bitcoin_addr2rmd160(symbol,taddr,&addrtype,rmd160,coinaddr); + bitcoin_address("KMD",othersmartaddr,coin->taddr,coin->pubtype,rmd160,20); + //printf("proofcheck addrtype.%d (%s) -> %s\n",addrtype,coinaddr,othersmartaddr); + if ((ap= LP_address(coin,othersmartaddr)) != 0 ) + { + if ( time(NULL) < ap->instantdextime+300 ) + return(ap->instantdex_credits); + ap->instantdextime = (uint32_t)time(NULL); + ap->instantdex_credits = 0; + for (i=0; iinstantdex_credits; + ap->didinstantdex = 1; + ap->instantdextime = (uint32_t)time(NULL); + if ( 0 && ap->instantdex_credits > 0 ) + printf("validated instantdex %s.[%d] proof.(%s) credits %.8f\n",othersmartaddr,num,jprint(proof,0),dstr(ap->instantdex_credits)); + } //else printf("cant find ap.%p or already did %d %.8f\n",ap,ap!=0?ap->didinstantdex:-1,ap!=0?dstr(ap->instantdex_credits):-1); + } + return(credits); +} + +int64_t LP_myzcredits() +{ + cJSON *proof; struct iguana_info *coin; int64_t zcredits; + if ( (coin= LP_coinfind("KMD")) != 0 ) + { + if ( (proof= LP_instantdex_txids(0,coin->smartaddr)) != 0 ) + { + zcredits = LP_instantdex_proofcheck(coin->symbol,coin->smartaddr,proof,cJSON_GetArraySize(proof)); + free_json(proof); + return(zcredits); + } + } + return(0); +} + +cJSON *LP_swapstats_item(struct LP_swapstats *sp,int32_t iambob) +{ + struct iguana_info *bob,*alice; int32_t flag = 0; char *retstr,*swapstr; bits256 zero; cJSON *item,*reqjson,*swapjson; + item = cJSON_CreateObject(); + jaddnum(item,"iambob",iambob); + jaddnum(item,"aliceid",sp->aliceid); + jaddnum(item,"requestid",sp->Q.R.requestid); + jaddnum(item,"quoteid",sp->Q.R.quoteid); + jaddstr(item,"base",sp->Q.srccoin); + jaddnum(item,"satoshis",sp->Q.satoshis); + jaddstr(item,"rel",sp->Q.destcoin); + jaddnum(item,"destsatoshis",sp->Q.destsatoshis); + jaddnum(item,"price",sp->Q.destsatoshis/((double)sp->Q.satoshis+1)); + if ( LP_swap_finished(sp,1) == 0 ) + { + jaddnum(item,"finished",sp->finished); + if ( sp->bobneeds_dPoW != 0 && (bob= LP_coinfind(sp->Q.srccoin)) != 0 ) + { + jaddnum(item,"bobneeds_dPoW",sp->bobneeds_dPoW); + jaddnum(item,"bob_dPoWheight",bob->notarized); + if ( sp->bobneeds_dPoW == 1 ) + flag = 1; + if ( bob->notarized == 0 ) + LP_dPoW_request(bob); + } + if ( sp->aliceneeds_dPoW != 0 && (alice= LP_coinfind(sp->Q.destcoin)) != 0 ) + { + jaddnum(item,"aliceneeds_dPoW",sp->aliceneeds_dPoW); + jaddnum(item,"alice_dPoWheight",alice->notarized); + if ( sp->aliceneeds_dPoW == 1 ) + flag = 1; + if ( alice->notarized == 0 ) + LP_dPoW_request(alice); + } + if ( flag != 0 ) + { + if ( 0 ) + { + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","gettradestatus"); + jadd64bits(reqjson,"aliceid",sp->aliceid); + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + } + if ( (swapstr= basilisk_swapentry(sp->Q.R.requestid,sp->Q.R.quoteid,0)) != 0 ) + { + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) + { + if ( (retstr= LP_swapstatus_recv(swapjson)) != 0 ) + free(retstr); + free_json(swapjson); + } + free(swapstr); + } + } + } + return(item); +} + +cJSON *LP_myzdebits() +{ + struct LP_pubswap *ptr,*tmp; struct LP_pubkey_info *pubp; struct LP_swapstats *sp; int64_t kmdvalue,swaps_kmdvalue = 0; struct iguana_info *coin; cJSON *retjson,*array,*item; + array = cJSON_CreateArray(); + if ( (coin= LP_coinfind("KMD")) != 0 ) + { + if ( (pubp= LP_pubkeyfind(G.LP_mypub25519)) != 0 ) + { + DL_FOREACH_SAFE(pubp->bobswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + { + kmdvalue = LP_kmdvalue(sp->Q.srccoin,sp->Q.satoshis); + item = LP_swapstats_item(sp,1); + jaddnum(item,"kmdvalue",dstr(kmdvalue)); + jaddi(array,item); + swaps_kmdvalue += kmdvalue; + } + } + DL_FOREACH_SAFE(pubp->aliceswaps,ptr,tmp) + { + if ( (sp= ptr->swap) != 0 && LP_swap_finished(sp,1) == 0 ) + { + kmdvalue = LP_kmdvalue(sp->Q.destcoin,sp->Q.destsatoshis); + item = LP_swapstats_item(sp,0); + jaddnum(item,"kmdvalue",dstr(kmdvalue)); + jaddi(array,item); + swaps_kmdvalue += kmdvalue; + } + } + } + } + retjson = cJSON_CreateObject(); + jadd(retjson,"swaps",array); + jaddnum(retjson,"pendingswaps",dstr(swaps_kmdvalue)); + return(retjson); +} diff --git a/iguana/exchanges/LP_messages.c b/iguana/exchanges/LP_messages.c new file mode 100644 index 000000000..80847ee5c --- /dev/null +++ b/iguana/exchanges/LP_messages.c @@ -0,0 +1,97 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_messages.c +// marketmaker +// + +struct LP_messageinfo { struct LP_messageinfo *next,*prev; cJSON *msgjson; int32_t ind; } *LP_MSGS; +int32_t Num_messages; + +void LP_gotmessage(cJSON *argjson) +{ + struct LP_messageinfo *msg = calloc(1,sizeof(*msg)); + msg->msgjson = jduplicate(argjson); + msg->ind = Num_messages++; + portable_mutex_lock(&LP_messagemutex); + DL_APPEND(LP_MSGS,msg); + portable_mutex_unlock(&LP_messagemutex); +} + +void LP_deletemessages(int32_t firsti,int32_t num) +{ + struct LP_messageinfo *msg,*tmp; int32_t lasti; + if ( num == 0 ) + num = 100; + if ( firsti < 0 ) + firsti = 0; + else if ( firsti >= Num_messages ) + return; + lasti = firsti + num - 1; + if ( lasti < Num_messages-1 ) + lasti = Num_messages - 1; + DL_FOREACH_SAFE(LP_MSGS,msg,tmp) + { + if ( msg->ind >= firsti && msg->ind <= lasti ) + { + portable_mutex_lock(&LP_messagemutex); + DL_DELETE(LP_MSGS,msg); + portable_mutex_unlock(&LP_messagemutex); + free_json(msg->msgjson); + free(msg); + } + } +} + +cJSON *LP_getmessages(int32_t firsti,int32_t num) +{ + struct LP_messageinfo *msg,*tmp; int32_t lasti,n=0,maxi=-1,mini=-1; cJSON *retjson,*item,*array = cJSON_CreateArray(); + retjson = cJSON_CreateObject(); + if ( num == 0 ) + num = 100; + if ( firsti < 0 ) + firsti = 0; + else if ( firsti >= Num_messages ) + { + jadd(retjson,"messages",array); + return(retjson); + } + lasti = firsti + num - 1; + if ( lasti < Num_messages-1 ) + lasti = Num_messages - 1; + DL_FOREACH_SAFE(LP_MSGS,msg,tmp) + { + if ( msg->ind >= firsti && msg->ind <= lasti ) + { + item = cJSON_CreateObject(); + jaddnum(item,"ind",msg->ind); + jadd(item,"msg",jduplicate(msg->msgjson)); + jaddi(array,item); + if ( mini == -1 || msg->ind < mini ) + mini = msg->ind; + if ( maxi == -1 || msg->ind > maxi ) + maxi = msg->ind; + n++; + } + } + jadd(retjson,"messages",array); + jaddnum(retjson,"firsti",firsti); + jaddnum(retjson,"lasti",lasti); + jaddnum(retjson,"minind",mini); + jaddnum(retjson,"maxind",maxi); + jaddnum(retjson,"num",n); + return(retjson); +} diff --git a/iguana/exchanges/LP_mmjson.c b/iguana/exchanges/LP_mmjson.c new file mode 100644 index 000000000..bf2f7f670 --- /dev/null +++ b/iguana/exchanges/LP_mmjson.c @@ -0,0 +1,710 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_mmjson.c +// marketmaker +// +#define MMJSON_IPADDR 255 +#define MMJSON_BITS256 254 +#define MMJSON_SECP33 253 +#define MMJSON_SIG 252 +#define MMJSON_RMD160 251 +#define MMJSON_DECIMAL8 250 +#define MMJSON_DECIMAL8STR 249 +#define MMJSON_DECIMAL16 248 +#define MMJSON_DECIMAL16STR 247 +#define MMJSON_DECIMAL24 246 +#define MMJSON_DECIMAL24STR 245 +#define MMJSON_DECIMAL32 244 +#define MMJSON_DECIMAL32STR 243 +#define MMJSON_DECIMAL40 242 +#define MMJSON_DECIMAL40STR 241 +#define MMJSON_DECIMAL48 240 +#define MMJSON_DECIMAL48STR 239 +#define MMJSON_DOUBLE 238 +#define MMJSON_DECIMAL64 237 +#define MMJSON_DECIMAL64STR 236 +#define MMJSON_TIMESTAMP 235 +#define MMJSON_TIMEDIFF8 234 +#define MMJSON_TIMEDIFF16 233 +#define MMJSON_ZERO 232 +#define MMJSON_ZEROSTR 231 +#define MMJSON_COIN 230 +#define MMJSON_STRING 229 +#define MMJSON_ARRAY8 228 +#define MMJSON_ARRAY16 227 +#define MMJSON_ARRAY32 226 +#define MMJSON_BOUNDARY 98 + +int32_t MM_numfields; +char *MM_fields[256] = +{ + "timestamp", "getdPoW", "dPoW", "aliceid", "src", "base", "basevol", "dest", "rel", "relvol", "price", "requestid", "quoteid", "finished", "expired", "bobdeposit", "alicepayment", "bobpayment", "paymentspent", "Apaymentspent", "depositspent", "ind", "method", "swapstatus", "method2", "gettradestatus", "coin", "rmd160", "pub", "pubsecp", "sig", "session", "notify", "pubkey", "price64", "credits", "utxocoin", "n", "bal", "min", "max", "postprice", "notarized", "notarizedhash", "notarizationtxid", "wantnotify", "isLP", "gui", "nogui", "tradeid", "address", "txid", "vout", "srchash", "txfee", "quotetime", "satoshis", "desthash", "txid2", "vout2", "destaddr", "desttxid", "destvout", "feetxid", "feevout", "desttxfee", "destsatoshis", "pending", "reserved", "broadcast", "ismine", "simplegui", "request", "proof", "connect", "expiration", "iambob", "Bgui", "", "Agui", "bob", "srcamount", "bobtxfee", "alice", "destamount", "alicetxfee", "sentflags", "values", "result", "success", "status", "finishtime", "tradestatus", "pair", "connected", "warning", "critical", "endcritical", +}; + +char *MM_coins[256] = +{ + "KMD", "BTC", "CRC", "VOT", "INN", "MOON", "CRW", "EFL", "GBX", "BCO", "BLK", "BTG", "BCH", "ABY", "STAK", "XZC", "QTUM", "PURA", "DSR", "MNZ", "BTCZ", "MAGA", "BSD", "IOP", "BLOCK", "CHIPS", "888", "ARG", "GLT", "ZER", "HODLC", "UIS", "HUC", "PIVX", "BDL", "ARC", "ZCL", "VIA", "ERC", "FAIR", "FLO", "SXC", "CREA", "TRC", "BTA", "SMC", "NMC", "NAV", "EMC2", "SYS", "I0C", "DASH", "STRAT", "MUE", "MONA", "XMY", "MAC", "BTX", "XRE", "LBC", "SIB", "VTC", "REVS", "JUMBLR", "DOGE", "HUSH", "ZEC", "DGB", "ZET", "GAME", "LTC", "SUPERNET", "WLC", "PANGEA", "DEX", "BET", "CRYPTO", "HODL", "MSHARK", "BOTS", "MGW", "COQUI", "KV", "CEAL", "MESH", +}; + +int32_t mmjson_coinfind(char *symbol) +{ + int32_t i; + for (i=0; i>= 8; + } + } + else + { + for (i=n-1; i>=0; i--) + { + l <<= 8; + l |= buf[i]; + } + *longp = l; + } + return(n); +} + +int32_t MMJSON_decodeitem(cJSON *lineobj,uint8_t *linebuf,int32_t i,int32_t len,char *fieldstr,uint32_t *timestampp) +{ + int32_t c,valind,j; char tmpstr[64],ipaddr[64],hexstr[256],arbstr[8192]; uint64_t l; + switch ( (valind= linebuf[i++]) ) + { + case MMJSON_IPADDR: + i += MMJSON_rwnum(0,&linebuf[i],&l,4); + expand_ipbits(ipaddr,(uint32_t)l); + jaddstr(lineobj,fieldstr,ipaddr); + break; + case MMJSON_BITS256: + init_hexbytes_noT(hexstr,&linebuf[i],32); + i += 32; + jaddstr(lineobj,fieldstr,hexstr); + break; + case MMJSON_SECP33: + init_hexbytes_noT(hexstr,&linebuf[i],33); + i += 33; + jaddstr(lineobj,fieldstr,hexstr); + break; + case MMJSON_SIG: + init_hexbytes_noT(hexstr,&linebuf[i],65); + i += 65; + jaddstr(lineobj,fieldstr,hexstr); + break; + case MMJSON_RMD160: + init_hexbytes_noT(hexstr,&linebuf[i],20); + i += 20; + jaddstr(lineobj,fieldstr,hexstr); + break; + case MMJSON_DECIMAL8: + l = linebuf[i++]; + jaddnum(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL8STR: + l = linebuf[i++]; + jadd64bits(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL16: + i += MMJSON_rwnum(0,&linebuf[i],&l,2); + jaddnum(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL16STR: + i += MMJSON_rwnum(0,&linebuf[i],&l,2); + jadd64bits(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL24: + i += MMJSON_rwnum(0,&linebuf[i],&l,3); + jaddnum(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL24STR: + i += MMJSON_rwnum(0,&linebuf[i],&l,3); + sprintf(tmpstr,"%llu",(long long)l); + jaddstr(lineobj,fieldstr,tmpstr); + break; + case MMJSON_DECIMAL32: + i += MMJSON_rwnum(0,&linebuf[i],&l,4); + //printf("decimal32.%u %08x\n",(uint32_t)l,(uint32_t)l); + jaddnum(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL32STR: + i += MMJSON_rwnum(0,&linebuf[i],&l,4); + //printf("decimal32.%u %08x\n",(uint32_t)l,(uint32_t)l); + jadd64bits(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL40: + i += MMJSON_rwnum(0,&linebuf[i],&l,5); + jaddnum(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL40STR: + i += MMJSON_rwnum(0,&linebuf[i],&l,5); + jadd64bits(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL48: + i += MMJSON_rwnum(0,&linebuf[i],&l,6); + jaddnum(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL48STR: + i += MMJSON_rwnum(0,&linebuf[i],&l,6); + jadd64bits(lineobj,fieldstr,l); + break; + case MMJSON_DOUBLE: + i += MMJSON_rwnum(0,&linebuf[i],&l,8); + //printf("double %llu -> %.8f\n",(long long)l,dstr(l)); + jaddnum(lineobj,fieldstr,dstr(l)); + break; + case MMJSON_DECIMAL64: + i += MMJSON_rwnum(0,&linebuf[i],&l,8); + jadd64bits(lineobj,fieldstr,l); + break; + case MMJSON_DECIMAL64STR: + i += MMJSON_rwnum(0,&linebuf[i],&l,8); + jadd64bits(lineobj,fieldstr,l); + break; + case MMJSON_TIMESTAMP: + if ( *timestampp == 0 ) + { + i += MMJSON_rwnum(0,&linebuf[i],&l,4); + *timestampp = (uint32_t)l; + jaddnum(lineobj,fieldstr,l); + } + else + { + printf("timestamp %u already exists\n",*timestampp); + free_json(lineobj); + return(-1); + } + break; + case MMJSON_TIMEDIFF8: + jaddnum(lineobj,fieldstr,*timestampp + linebuf[i++]); + break; + case MMJSON_TIMEDIFF16: + i += MMJSON_rwnum(0,&linebuf[i],&l,2); + jaddnum(lineobj,fieldstr,*timestampp + l); + break; + case MMJSON_ZERO: + jaddnum(lineobj,fieldstr,0); + break; + case MMJSON_ZEROSTR: + //printf("%s.zerostr\n",fieldstr); + jadd64bits(lineobj,fieldstr,0); + break; + case MMJSON_COIN: + jaddstr(lineobj,fieldstr,MM_coins[linebuf[i++]]); + break; + case MMJSON_STRING: + j = 0; + while ( (c= linebuf[i++]) != 0 ) + { + if ( i > len ) + { + printf("string overflow i.%d vs len.%d\n",i,len); + free_json(lineobj); + return(-1); + } + arbstr[j++] = c; + } + arbstr[j] = 0; + jaddstr(lineobj,fieldstr,arbstr); + break; + default: + if ( valind < MMJSON_BOUNDARY ) + jaddstr(lineobj,fieldstr,MM_fields[valind]); + else + { + printf("%s unhandled valind.%d k.%d len.%d (%s)\n",fieldstr,valind,i,len,jprint(lineobj,0)); + free_json(lineobj); + return(-1); + } + break; + } + return(i); +} + +char *MMJSON_decode(uint8_t *linebuf,int32_t len) +{ + uint32_t timestamp = 0; char *fieldstr; uint64_t l; int32_t ind,i=0,j,m=-1; cJSON *obj,*item,*array,*lineobj = cJSON_CreateObject(); + while ( i+1 < len ) + { + //printf("ind.%d i.%d vs len.%d\n",linebuf[i],i,len); + if ( (ind= linebuf[i++]) >= MMJSON_BOUNDARY ) + { + if ( ind != MMJSON_STRING ) + { + printf("illegal field ind.%d (%s)\n",ind,jprint(lineobj,0)); + free_json(lineobj); + return(0); + } + else + { + fieldstr = (char *)&linebuf[i++]; + while ( linebuf[i] != 0 ) + i++; + i++; + } + } else fieldstr = MM_fields[ind]; + if ( linebuf[i] == MMJSON_ARRAY8 ) + { + i++; + m = linebuf[i++]; + } + else if ( linebuf[i] == MMJSON_ARRAY16 ) + { + i++; + i += MMJSON_rwnum(0,&linebuf[i],&l,2); + m = (int32_t)l; + } + else if ( linebuf[i] == MMJSON_ARRAY32 ) + { + i++; + i += MMJSON_rwnum(0,&linebuf[i],&l,4); + m = (int32_t)l; + } else m = -1; + if ( m >= 0 ) + { + //printf("%s i.%d m.%d\n",fieldstr,i,m); + array = cJSON_CreateArray(); + for (j=0; j= 0 ) + { + fieldstr = MM_fields[ind]; + if ( strcmp("utxocoin",fieldstr) == 0 || strcmp("alice",fieldstr) == 0 || strcmp("bob",fieldstr) == 0 || strcmp("base",fieldstr) == 0 || strcmp("rel",fieldstr) == 0 || strcmp("coin",fieldstr) == 0 || strcmp("txfee",fieldstr) == 0 || strcmp("desttxfee",fieldstr) == 0 || strcmp("price64",fieldstr) == 0 || strcmp("satoshis",fieldstr) == 0 || strcmp("destsatoshis",fieldstr) == 0 ) + isstr = 1; + else isstr = 0; + } + //printf("%s.(%s) k.%d\n",fieldstr,v,k); + if ( (valind= mmfind(v)) >= 0 ) + { + linebuf[k++] = valind; + return(k); + } + else if ( strcmp("0",v) == 0 ) + { + if ( isstr != 0 ) + linebuf[k++] = MMJSON_ZEROSTR; + else linebuf[k++] = MMJSON_ZERO; + return(k); + } + for (j=dots=0; v[j]!=0; j++) + { + if ( (v[j] < '0' || v[j] > '9') && v[j] != '.' ) + break; + else if ( v[j] == '.' ) + dots++; + } + if ( dots == 3 && v[j] == 0 && strlen(v) < 17 && is_ipaddr(v) != 0 ) + { + //printf(" "); + linebuf[k++] = MMJSON_IPADDR; + l = calc_ipbits(v); + k += MMJSON_rwnum(1,&linebuf[k],&l,4); + } + else if ( dots == 1 && v[j] == 0 ) + { + if ( (val= atof(v)) > SMALLVAL ) + { + l = SATOSHIDEN * (val + 0.000000005); + sprintf(checkstr,"%.8f",dstr(l)); + if ( strcmp(checkstr,v) == 0 ) + { + //printf(" "); + linebuf[k++] = MMJSON_DOUBLE; + k += MMJSON_rwnum(1,&linebuf[k],&l,8); + } else printf("ERR.<%s %s> ",v,checkstr); + } + } + else if ( (len= is_hexstr(v,0)) == 64 ) + { + //printf(" "); + linebuf[k++] = MMJSON_BITS256; + decode_hex(&linebuf[k],32,v), k += 32; + } + else if ( len == 66 ) + { + //printf(" "); + linebuf[k++] = MMJSON_SECP33; + decode_hex(&linebuf[k],33,v), k += 33; + } + else if ( len == 65*2 ) + { + //printf(" "); + linebuf[k++] = MMJSON_SIG; + decode_hex(&linebuf[k],65,v), k += 65; + } + else if ( len == 40 ) + { + //printf(" "); + linebuf[k++] = MMJSON_RMD160; + decode_hex(&linebuf[k],20,v), k += 20; + } + else if ( len > 40 ) + { + printf("ERR. ",len/2); + } + else if ( is_decimalstr(v) != 0 && (l= calc_nxt64bits(v)) > 0 ) + { + if ( l < 0x100 ) + { + //printf(" "); + if ( l == 0 ) + { + linebuf[k++] = isstr != 0 ? MMJSON_ZEROSTR : MMJSON_ZERO; + } + else + { + linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL8STR : MMJSON_DECIMAL8; + linebuf[k++] = (uint8_t)l; + } + } + else if ( l < 0x10000 ) + { + //printf(" "); + linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL16STR : MMJSON_DECIMAL16; + k += MMJSON_rwnum(1,&linebuf[k],&l,2); + } + else if ( l < 0x1000000 ) + { + linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL24STR : MMJSON_DECIMAL24; + //printf("decimal24 %llu %s (%s) %d\n",(long long)l,v,fieldstr,linebuf[k-1]); + k += MMJSON_rwnum(1,&linebuf[k],&l,3); + } + else if ( l < 0x100000000LL ) + { + if ( v[0] != '"' && *timestampp == 0 && strcmp(fieldstr,"timestamp") == 0 ) + { + *timestampp = (uint32_t)atol(v); + //printf(" "); + linebuf[k++] = MMJSON_TIMESTAMP; + l = *timestampp; + k += MMJSON_rwnum(1,&linebuf[k],&l,4); + } + else if ( v[0] != '"' && *timestampp != 0 && (diff= ((uint32_t)atol(v)-*timestampp)) < 0x100 && diff >= 0 ) + { + //printf(" "); + linebuf[k++] = MMJSON_TIMEDIFF8; + linebuf[k++] = (uint8_t)diff; + } + else if ( v[0] != '"' && *timestampp != 0 && (diff= ((uint32_t)atol(v)-*timestampp)) < 0x10000 && diff >= 0 ) + { + //printf(" "); + linebuf[k++] = MMJSON_TIMEDIFF16; + l = diff; + k += MMJSON_rwnum(1,&linebuf[k],&l,2); + } + else + { + //printf(".%u %08x\n",(uint32_t)l,(uint32_t)l); + linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL32STR : MMJSON_DECIMAL32; + k += MMJSON_rwnum(1,&linebuf[k],&l,4); + } + } + else if ( l < 0x10000000000LL ) + { + //printf(" "); + linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL40STR : MMJSON_DECIMAL40; + k += MMJSON_rwnum(1,&linebuf[k],&l,5); + } + else if ( l < 0x1000000000000LL ) + { + //printf(" "); + linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL48STR : MMJSON_DECIMAL48; + k += MMJSON_rwnum(1,&linebuf[k],&l,6); + } + //else if ( l < 0x100000000000000LL ) + // printf(" "); + else + { + //printf(" "); + linebuf[k++] = isstr != 0 ? MMJSON_DECIMAL64STR : MMJSON_DECIMAL64; + k += MMJSON_rwnum(1,&linebuf[k],&l,8); + } + } + else + { + if ( (ind= mmfind(v)) >= 0 ) + linebuf[k++] = ind; + else + { + for (j=0; v[j]!=0; j++) + { + if ( v[j] >= 'a' && v[j] <= 'z' ) + continue; + else break; + } + if ( v[j] == 0 ) + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("unexpected missing string value.(%s)\n",v); + //ind = mmadd(v); + //printf("%s.<%s>.%d ",s,v,ind); + //linebuf[k++] = ind; + linebuf[k++] = MMJSON_STRING; + memcpy(&linebuf[k],v,strlen(v)+1); + k += (int32_t)strlen(v) + 1; + } + else + { + for (j=0; v[j]!=0; j++) + { + if ( v[j] >= 'A' && v[j] <= 'Z' ) + continue; + else break; + } + if ( v[j] == 0 && (coinind= mmjson_coinfind(v)) >= 0 ) + { + //printf(" "); + linebuf[k++] = MMJSON_COIN; + linebuf[k++] = coinind; + } + /*else if ( strlen(v) == 34 ) + { + printf(" "); + k += 22; + }*/ + else + { + linebuf[k++] = MMJSON_STRING; + if ( v[0] == '"' ) + { + v++; + v[strlen(v)-1] = 0; + } + //printf("str.<%s> ",v); + memcpy(&linebuf[k],v,strlen(v)+1); + k += (int32_t)strlen(v) + 1; + } + } + } + } + return(k); +} + +int32_t MMJSON_encode(uint8_t *linebuf,char *line) +{ + uint32_t timestamp; uint64_t l; char *decodestr,*s,*v=0; cJSON *lineobj,*array,*ptr; int32_t k=0,m,i,asize,ind,z,allocv_flag; + timestamp = 0; + if ( (lineobj= cJSON_Parse(line)) != 0 ) + { + if ( line[strlen(line)-1] == '\n' ) + line[strlen(line)-1] = 0; + //printf("%s\n",jprint(lineobj,0)); + if ( (m= cJSON_GetArraySize(lineobj)) > 0 ) + { + ptr = lineobj->child; + for (i=0; inext) + { + allocv_flag = 0; + s = jfieldname(ptr); + if ( (ind= mmfind(s)) < 0 ) + { + printf("missing field.(%s) add to MM_fields[]\n",s); + linebuf[k++] = MMJSON_STRING; + memcpy(&linebuf[k],s,strlen(s)+1); + k += (int32_t)strlen(s) + 1; + //ind = mmadd(s); + } else linebuf[k++] = ind; + //printf("%s ",s); + if ( (array= jobj(lineobj,s)) != 0 && is_cJSON_Array(array) != 0 ) + { + asize = cJSON_GetArraySize(array); + if ( asize < 0x100 ) + { + linebuf[k++] = MMJSON_ARRAY8; + linebuf[k++] = asize; + } + else if ( asize < 0x10000 ) + { + linebuf[k++] = MMJSON_ARRAY16; + l = asize; + k += MMJSON_rwnum(1,&linebuf[k],&l,2); + } + else + { + linebuf[k++] = MMJSON_ARRAY32; + l = asize; + k += MMJSON_rwnum(1,&linebuf[k],&l,4); + } + for (z=0; z (%s)\n",k,line,decodestr==0?"":decodestr); + if ( decodestr != 0 ) + free(decodestr); + return(-1); + } //else printf("decoded\n"); + free(decodestr); + } + return(k); +} + +#ifndef FROM_MARKETMAKER +#define packetout "/Users/mac/mmjson/packet.out" +#define packetlog "/Users/mac/mmjson/packet.log" + +int main(int argc, const char * argv[]) +{ + FILE *fp,*outfp; uint8_t linebuf[8192]; char line[8192],str[65]; int32_t i,k,compressed=0,n=0,total = 0; + outfp = fopen(packetout,"wb"); + if ( (fp= fopen(packetlog,"rb")) != 0 ) + { + while ( fgets(line,sizeof(line),fp) > 0 ) + { + n++; + total += strlen(line); + if ( (k= MMJSON_encode(linebuf,line)) > 0 ) + { + //printf("\n"); + if ( outfp != 0 ) + fwrite(linebuf,1,k,outfp); + compressed += k; + } + else + { + compressed += strlen(line); + //printf("error parsing.(%s)\n",line); + } + } + fclose(fp); + if ( outfp != 0 ) + { + uint8_t *data,*bits; int32_t numbits; bits256 seed; long fsize = ftell(outfp); + fclose(outfp); + if ( (0) && (outfp= fopen(packetout,"rb")) != 0 ) + { + data = calloc(1,fsize); + bits = calloc(1,fsize); + if ( fread(data,1,fsize,outfp) == fsize ) + { + memset(seed.bytes,0,sizeof(seed)); + decode_hex(seed.bytes,32,"ffffff070000810478800084000800b200101400002001400404844402d29fc4"); + numbits = ramcoder_compress(bits,(int32_t)fsize,data,(int32_t)fsize,seed); + fclose(outfp); + printf("numbits.%d %d bytes %.1f seed.%s\n",numbits,numbits/8+1,(double)compressed/(numbits/8),bits256_str(str,seed)); + } + } + } + } else printf("cant find packet.log\n"); + printf("char *MM_fields[256] = \n{\n"); + for (i=0; i 4: KMD notarized, 5: BTC notarized, after next notary elections +// bigendian architectures need to use little endian for sighash calcs +// improve critical section detection when parallel trades +// use electrum in case of addr change in swap +// locktime claiming on sporadic assetchains +// there is an issue about waiting for notarization for a swap that never starts (expiration ok) + +#include + +long LP_cjson_allocated,LP_cjson_total,LP_cjson_count; + +struct LP_millistats +{ + double lastmilli,millisum,threshold; + uint32_t count; + char name[64]; +} LP_psockloop_stats,LP_reserved_msgs_stats,utxosQ_loop_stats,command_rpcloop_stats,queue_loop_stats,prices_loop_stats,LP_coinsloop_stats,LP_coinsloopBTC_stats,LP_coinsloopKMD_stats,LP_pubkeysloop_stats,LP_swapsloop_stats,LP_gcloop_stats,LP_tradesloop_stats; +extern int32_t IAMLP; +char LP_methodstr[64]; + +void LP_millistats_update(struct LP_millistats *mp) +{ + double elapsed,millis; + if ( mp == 0 ) + { + if ( IAMLP != 0 ) + { + mp = &LP_psockloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + } + mp = &LP_reserved_msgs_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &utxosQ_loop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &command_rpcloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &queue_loop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &prices_loop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloopBTC_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_coinsloopKMD_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_pubkeysloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_tradesloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_swapsloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + mp = &LP_gcloop_stats, printf("%32s lag %10.2f millis, threshold %10.2f, ave %10.2f millis, count.%u\n",mp->name,OS_milliseconds() - mp->lastmilli,mp->threshold,mp->millisum/(mp->count > 0 ? mp->count: 1),mp->count); + } + else + { + if ( mp->lastmilli == 0. ) + mp->lastmilli = OS_milliseconds(); + else + { + mp->count++; + millis = OS_milliseconds(); + elapsed = (millis - mp->lastmilli); + mp->millisum += elapsed; + if ( mp->threshold != 0. && elapsed > mp->threshold ) + { + //if ( IAMLP == 0 ) + printf("%32s elapsed %10.2f millis > threshold %10.2f, ave %10.2f millis, count.%u %s\n",mp->name,elapsed,mp->threshold,mp->millisum/mp->count,mp->count,LP_methodstr); + } + mp->lastmilli = millis; + } + } +} + +#include "LP_include.h" +portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex; +int32_t LP_canbind; +char *Broadcaststr,*Reserved_msgs[2][1000]; +int32_t num_Reserved_msgs[2],max_Reserved_msgs[2]; +struct LP_peerinfo *LP_peerinfos,*LP_mypeer; +struct LP_forwardinfo *LP_forwardinfos; +struct iguana_info *LP_coins; +struct LP_pubkey_info *LP_pubkeyinfos; +struct rpcrequest_info *LP_garbage_collector; +struct LP_address_utxo *LP_garbage_collector2; +struct LP_trade *LP_trades,*LP_tradesQ; + +//uint32_t LP_deadman_switch; +uint16_t LP_fixed_pairport;//,LP_publicport; +uint32_t LP_lastnonce,LP_swap_endcritical,LP_swap_critical,LP_RTcount,LP_swapscount; +int32_t LP_STOP_RECEIVED,LP_numactive_LP;//,LP_mybussock = -1; +int32_t LP_mypubsock = -1; +int32_t LP_cmdcount,LP_mypullsock = -1; +int32_t LP_numfinished,LP_showwif,IAMLP = 0; +double LP_profitratio = 1.; + +struct LP_privkey { bits256 privkey; uint8_t rmd160[20]; }; + +struct LP_globals +{ + //struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2]; + bits256 LP_mypub25519,LP_privkey,LP_mypriv25519,LP_passhash; + uint64_t LP_skipstatus[10000]; + uint16_t netid; + uint8_t LP_myrmd160[20],LP_pubsecp[33]; + uint32_t LP_sessionid,counter; + int32_t LP_IAMLP,LP_pendingswaps,USERPASS_COUNTER,LP_numprivkeys,initializing,waiting,LP_numskips; + char seednode[64],USERPASS[65],USERPASS_WIFSTR[64],LP_myrmd160str[41],gui[65],LP_NXTaddr[64]; + struct LP_privkey LP_privkeys[100]; +} G; + +uint32_t LP_rand() +{ + uint32_t retval; + retval = rand(); + retval = (retval << 7) ^ (retval >> 17) ^ rand(); + retval = (retval << 13) ^ (retval >> 13) ^ rand(); + retval = (retval << 17) ^ (retval >> 7) ^ rand(); + return(retval); +} + +#include "LP_network.c" + +char *activecoins[] = { "BTC", "KMD" }; +char GLOBAL_DBDIR[] = { "DB" }; +char LP_myipaddr[64],USERHOME[512] = { "/root" }; +char LP_gui[65] = { "cli" }; + +char *default_LPnodes[] = { "5.9.253.195", "173.212.225.176", "136.243.45.140", "23.254.202.142", "45.32.19.196" + //"24.54.206.138", "107.72.162.127", "72.50.16.86", "51.15.202.191", "173.228.198.88", + //"51.15.203.171", "51.15.86.136", "51.15.94.249", "51.15.80.18", "51.15.91.40", "51.15.54.2", "51.15.86.31", "51.15.82.29", "51.15.89.155", "173.212.225.176", "136.243.45.140" +}; + +// stubs + +void tradebot_swap_balancingtrade(struct basilisk_swap *swap,int32_t iambob) +{ + +} + +void tradebot_pendingadd(cJSON *tradejson,char *base,double basevolume,char *rel,double relvolume) +{ + // add to trades +} + +char *LP_getdatadir() +{ + return(USERHOME); +} + +char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip) +{ + return(0); +} + +#include "LP_mmjson.c" +#include "LP_socket.c" +#include "LP_secp.c" +#include "LP_bitcoin.c" +#include "LP_coins.c" +#include "LP_rpc.c" +#include "LP_NXT.c" +#include "LP_cache.c" +#include "LP_RTmetrics.c" +#include "LP_utxo.c" +#include "LP_prices.c" +#include "LP_scan.c" +#include "LP_transaction.c" +#include "LP_stats.c" +#include "LP_remember.c" +#include "LP_instantdex.c" +#include "LP_swap.c" +#include "LP_peers.c" +#include "LP_privkey.c" +#include "LP_forwarding.c" +#include "LP_signatures.c" +#include "LP_ordermatch.c" +#include "LP_tradebots.c" +#include "LP_portfolio.c" +#include "LP_messages.c" +#include "LP_commands.c" + +char *LP_command_process(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen,int32_t stats_JSONonly) +{ + char *retstr=0; cJSON *retjson; bits256 zero; + if ( jobj(argjson,"result") != 0 || jobj(argjson,"error") != 0 ) + return(0); + if ( stats_JSONonly != 0 || LP_tradecommand(ctx,myipaddr,pubsock,argjson,data,datalen) <= 0 ) + { + if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,"127.0.0.1",stats_JSONonly)) != 0 ) + { + //printf("%s PULL.[%d]-> (%s)\n",myipaddr != 0 ? myipaddr : "127.0.0.1",datalen,retstr); + //if ( pubsock >= 0 ) //strncmp("{\"error\":",retstr,strlen("{\"error\":")) != 0 && + //LP_send(pubsock,retstr,(int32_t)strlen(retstr)+1,0); + } + } + else if ( LP_statslog_parse() > 0 && 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + if ( (retjson= LP_statslog_disp(2000000000,2000000000,"",zero,0,0))) // pending swaps + free_json(retjson); + } + return(retstr); +} + +char *LP_decrypt(uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES],uint8_t *ptr,int32_t *recvlenp) +{ + uint8_t *nonce,*cipher; int32_t recvlen,cipherlen; char *jsonstr = 0; + recvlen = *recvlenp; + nonce = &ptr[2]; + cipher = &ptr[2 + crypto_box_NONCEBYTES]; + cipherlen = recvlen - (2 + crypto_box_NONCEBYTES); + if ( cipherlen > 0 && cipherlen <= LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES ) + { + if ( (jsonstr= (char *)_SuperNET_decipher(nonce,cipher,decoded,cipherlen,GENESIS_PUBKEY,G.LP_mypriv25519)) != 0 ) + { + recvlen = (cipherlen - crypto_box_ZEROBYTES); + if ( strlen(jsonstr)+1 != recvlen ) + { + printf("unexpected len %d vs recvlen.%d\n",(int32_t)strlen(jsonstr)+1,recvlen); + jsonstr = 0; + } //else printf("decrypted (%s)\n",jsonstr); + } + } else printf("cipher.%d too big for %d\n",cipherlen,LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES); + *recvlenp = recvlen; + return(jsonstr); +} + +char *LP_process_message(void *ctx,char *typestr,char *myipaddr,int32_t pubsock,uint8_t *ptr,int32_t recvlen,int32_t recvsock) +{ + static uint32_t dup,uniq; + uint8_t jdecoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES]; int32_t i,len,cipherlen,datalen=0,duplicate=0,encrypted=0; char *method,*method2,*tmp,*cipherstr,*retstr=0,*jsonstr=0; cJSON *argjson; uint32_t crc32; + //double millis = OS_milliseconds(); + crc32 = calc_crc32(0,&ptr[2],recvlen-2); + if ( (crc32 & 0xff) == ptr[0] && ((crc32>>8) & 0xff) == ptr[1] ) + encrypted = 1; + i = LP_crc32find(&duplicate,-1,crc32); + if ( duplicate != 0 ) + dup++; + else uniq++; + portable_mutex_lock(&LP_commandmutex); + if ( (LP_rand() % 100000) == 0 ) + printf("%s dup.%d (%u / %u) %.1f%% encrypted.%d recv.%u [%02x %02x] vs %02x %02x\n",typestr,duplicate,dup,dup+uniq,(double)100*dup/(dup+uniq),encrypted,crc32,ptr[0],ptr[1],crc32&0xff,(crc32>>8)&0xff); + if ( duplicate == 0 ) + { + if ( i >= 0 ) + LP_crc32find(&duplicate,i,crc32); + if ( encrypted != 0 ) + jsonstr = LP_decrypt(jdecoded,ptr,&recvlen); + else if ( (datalen= is_hexstr((char *)ptr,0)) > 0 ) + { + datalen >>= 1; + jsonstr = malloc(datalen + 1); + decode_hex((void *)jsonstr,datalen,(char *)ptr); + jsonstr[datalen] = 0; + } else jsonstr = (char *)ptr; + if ( jsonstr != 0 && (argjson= cJSON_Parse(jsonstr)) != 0 ) + { + uint8_t decoded[LP_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES]; + //printf("[%s]\n",jsonstr); + cipherlen = 0; + if ( (cipherstr= jstr(argjson,"cipher")) != 0 && (cipherlen= is_hexstr(cipherstr,0)) > 32 && cipherlen <= sizeof(decoded)*2 ) + { + method2 = jstr(argjson,"method2"); + if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"encrypted") == 0 ||(method2 != 0 && strcmp(method2,"encrypted") == 0)) ) + { + cipherlen >>= 1; + decode_hex(decoded,cipherlen,cipherstr); + crc32 = calc_crc32(0,&decoded[2],cipherlen-2); + if ( (tmp= LP_decrypt(jdecoded,decoded,&cipherlen)) != 0 ) + { + jsonstr = tmp; + free_json(argjson); + argjson = cJSON_Parse(jsonstr); + recvlen = cipherlen; + encrypted = 1; + if ( (crc32 & 0xff) == decoded[0] && ((crc32>>8) & 0xff) == decoded[1] ) + { + i = LP_crc32find(&duplicate,-1,crc32); + if ( duplicate == 0 && i >= 0 ) + LP_crc32find(&duplicate,i,crc32); + } + printf("%02x %02x %08x duplicate.%d decrypted.(%s)\n",decoded[0],decoded[1],crc32,duplicate,jsonstr); + } + else + { + //printf("packet not for this node %u\n",crc32); + } + } else printf("error (%s) method is %s\n",jsonstr,method); + } + if ( jsonstr != 0 && argjson != 0 ) + { + len = (int32_t)strlen(jsonstr) + 1; + if ( (method= jstr(argjson,"method")) != 0 && strcmp(method,"gettradestatus") != 0 && strcmp(method,"psock") != 0 && strcmp(method,"broadcast") == 0 ) + { + bits256 zero; cJSON *reqjson; char *cipherstr; int32_t cipherlen; uint8_t cipher[LP_ENCRYPTED_MAXSIZE]; + if ( (reqjson= LP_dereference(argjson,"broadcast")) != 0 ) + { + Broadcaststr = jprint(reqjson,0); + if ( (cipherstr= jstr(reqjson,"cipher")) != 0 ) + { + cipherlen = (int32_t)strlen(cipherstr) >> 1; + if ( cipherlen <= sizeof(cipher) ) + { + decode_hex(cipher,cipherlen,cipherstr); + LP_queuesend(calc_crc32(0,&cipher[2],cipherlen-2),LP_mypubsock,"","",cipher,cipherlen); + } else retstr = clonestr("{\"error\":\"cipher too big\"}"); + } + else + { + memset(zero.bytes,0,sizeof(zero)); + if ( 0 && (method= jstr(reqjson,"method")) != 0 && (strcmp(method,"tradestatus") == 0) ) + printf("broadcast.(%s)\n",Broadcaststr); + LP_reserved_msg(0,"","",zero,jprint(reqjson,0)); + } + retstr = clonestr("{\"result\":\"success\"}"); + free_json(reqjson); + } else retstr = clonestr("{\"error\":\"couldnt dereference sendmessage\"}"); + } + else + { + LP_queuecommand(0,jsonstr,pubsock,0); + //if ( (retstr= LP_command_process(ctx,myipaddr,pubsock,argjson,&((uint8_t *)ptr)[len],recvlen - len)) != 0 ) + //{ + //} + } + } + if ( argjson != 0 ) + free_json(argjson); + } + } //else printf("DUPLICATE.(%s)\n",(char *)ptr); + portable_mutex_unlock(&LP_commandmutex); + if ( jsonstr != 0 && (void *)jsonstr != (void *)ptr && encrypted == 0 ) + free(jsonstr); + return(retstr); +} + +int32_t LP_sock_check(char *typestr,void *ctx,char *myipaddr,int32_t pubsock,int32_t sock,char *remoteaddr,int32_t maxdepth) +{ + static char *line; + int32_t recvlen=1,msglen,nonz = 0; cJSON *recvjson; void *ptr,*msg; char methodstr[64],*decodestr,*retstr,*str; struct nn_pollfd pfd; + if ( line == 0 ) + line = calloc(1,1024*1024); + if ( sock >= 0 ) + { + while ( nonz < maxdepth && recvlen > 0 ) + { + decodestr = 0; + nonz++; + memset(&pfd,0,sizeof(pfd)); + pfd.fd = sock; + pfd.events = NN_POLLIN; + if ( nn_poll(&pfd,1,1) != 1 ) + break; + ptr = 0; + if ( (recvlen= nn_recv(sock,&ptr,NN_MSG,0)) > 0 ) + { + //printf("%s nn_recv.%d\n",typestr,recvlen); + decodestr = 0; + if ( recvlen > 32768 ) + { + printf("unexpectedly large packet\n"); + } + else + { + msg = ptr; + msglen = recvlen; + if ( (recvjson= cJSON_Parse((char *)ptr)) == 0 ) + { + if ( (decodestr= MMJSON_decode(ptr,recvlen)) != 0 ) + { + if ( (recvjson= cJSON_Parse(decodestr)) != 0 ) + { + msg = decodestr; + msglen = (int32_t)strlen(decodestr) + 1; + } + //printf("decoded.(%s)\n",decodestr); + } else printf("couldnt decode linebuf[%d]\n",recvlen); + } + methodstr[0] = 0; + if ( recvjson != 0 ) + { + safecopy(LP_methodstr,jstr(recvjson,"method"),sizeof(LP_methodstr)); + free_json(recvjson); + } + int32_t validreq = 1; + /*if ( strlen((char *)ptr)+sizeof(bits256) <= recvlen ) + { + if ( LP_magic_check(ptr,recvlen,remoteaddr) <= 0 ) + { + //printf("magic check error\n"); + } else validreq = 1; + recvlen -= sizeof(bits256); + }*/ + if ( validreq != 0 ) + { + if ( (retstr= LP_process_message(ctx,typestr,myipaddr,pubsock,msg,msglen,sock)) != 0 ) + free(retstr); + + if ( Broadcaststr != 0 ) + { + //printf("self broadcast.(%s)\n",Broadcaststr); + str = Broadcaststr; + Broadcaststr = 0; + LP_queuecommand(0,str,pubsock,0); + /*if ( (argjson= cJSON_Parse(str)) != 0 ) + { + //portable_mutex_lock(&LP_commandmutex); + if ( LP_tradecommand(ctx,myipaddr,pubsock,argjson,0,0) <= 0 ) + { + if ( (retstr= stats_JSON(ctx,myipaddr,pubsock,argjson,remoteaddr,0)) != 0 ) + free(retstr); + } + //portable_mutex_unlock(&LP_commandmutex); + free_json(argjson); + }*/ + free(str); + } + } + } + } + if ( ptr != 0 ) + { + nn_freemsg(ptr), ptr = 0; + //free(buf); + } + if ( decodestr != 0 ) + free(decodestr); + } + } + return(nonz); +} + +int32_t LP_nanomsg_recvs(void *ctx) +{ + int32_t n=0,nonz = 0; char *origipaddr; struct LP_peerinfo *peer,*tmp; + if ( (origipaddr= LP_myipaddr) == 0 ) + origipaddr = "127.0.0.1"; + portable_mutex_lock(&LP_nanorecvsmutex); + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( n++ > 0 && peer->errors >= LP_MAXPEER_ERRORS ) + { + if ( (LP_rand() % 10000) == 0 ) + peer->errors--; + else + { + //printf("skip %s\n",peer->ipaddr); + continue; + } + } + nonz += LP_sock_check("SUB",ctx,origipaddr,LP_mypubsock,peer->subsock,peer->ipaddr,1); + } + /*HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht + { + if ( coin->inactive != 0 ) + continue; + if ( coin->bussock >= 0 ) + nonz += LP_sock_check(coin->symbol,ctx,origipaddr,-1,coin->bussock,LP_profitratio - 1.); + }*/ + if ( LP_mypullsock >= 0 ) + { + nonz += LP_sock_check("PULL",ctx,origipaddr,-1,LP_mypullsock,"127.0.0.1",1); + } + portable_mutex_unlock(&LP_nanorecvsmutex); + return(nonz); +} + +void command_rpcloop(void *ctx) +{ + int32_t nonz = 0; + strcpy(command_rpcloop_stats.name,"command_rpcloop"); + command_rpcloop_stats.threshold = 2500.; + while ( LP_STOP_RECEIVED == 0 ) + { + LP_millistats_update(&command_rpcloop_stats); + nonz = LP_nanomsg_recvs(ctx); + //if ( LP_mybussock >= 0 ) + // nonz += LP_sock_check("BUS",ctx,origipaddr,-1,LP_mybussock); + if ( nonz == 0 ) + { + if ( IAMLP != 0 ) + usleep(10000); + else usleep(50000); + } + else if ( IAMLP == 0 ) + usleep(1000); + } +} + +void LP_coinsloop(void *_coins) +{ + struct LP_address *ap=0,*atmp; struct LP_transaction *tx; cJSON *retjson; struct LP_address_utxo *up,*tmp; struct iguana_info *coin,*ctmp; char str[65]; struct electrum_info *ep,*backupep=0; bits256 zero; int32_t notarized,oldht,j,nonz; char *coins = _coins; + if ( strcmp("BTC",coins) == 0 ) + { + strcpy(LP_coinsloopBTC_stats.name,"BTC coin loop"); + LP_coinsloopBTC_stats.threshold = 20000.; + } + else if ( strcmp("KMD",coins) == 0 ) + { + strcpy(LP_coinsloopKMD_stats.name,"KMD coin loop"); + LP_coinsloopKMD_stats.threshold = 10000.; + } + else + { + strcpy(LP_coinsloop_stats.name,"other coins loop"); + LP_coinsloop_stats.threshold = 5000.; + } + while ( LP_STOP_RECEIVED == 0 ) + { + if ( strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + { + sleep(10); + continue; + } + if ( strcmp("BTC",coins) == 0 ) + LP_millistats_update(&LP_coinsloopBTC_stats); + else if ( strcmp("KMD",coins) == 0 ) + LP_millistats_update(&LP_coinsloopKMD_stats); + else LP_millistats_update(&LP_coinsloop_stats); + nonz = 0; + HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht + { + if ( coins != 0 ) + { + if ( coins[0] != 0 ) + { + if ( strcmp(coins,coin->symbol) != 0 ) + continue; + } + else // avoid hardcode special case LP_coinsloop + { + if ( strcmp("BTC",coin->symbol) == 0 || strcmp("KMD",coin->symbol) == 0 ) + continue; + } + } + if ( coin->smartaddr[0] == 0 ) + { + printf("%s has no smartaddress??\n",coin->symbol); + continue; + } + memset(&zero,0,sizeof(zero)); + if ( coin->inactive != 0 ) + continue; + if ( coin->did_addrutxo_reset == 0 ) + { + LP_address_utxo_reset(coin); + coin->did_addrutxo_reset = 1; + } + if ( coin->longestchain == 1 ) // special init value + coin->longestchain = LP_getheight(¬arized,coin); + if ( (ep= coin->electrum) != 0 ) + { + /*if ( strcmp("KMD",coin->symbol) == 0 && coin->electrumzeroconf == 0 ) + { + LP_zeroconf_deposits(coin); + coin->electrumzeroconf = (uint32_t)time(NULL); + }*/ + if ( (backupep= ep->prev) == 0 ) + backupep = ep; + if ( (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,coin->smartaddr,1,zero,zero)) != 0 ) + free_json(retjson); + HASH_ITER(hh,coin->addresses,ap,atmp) + { + break; + //printf("call unspent %s\n",ap->coinaddr); + if ( strcmp(coin->smartaddr,ap->coinaddr) != 0 && (retjson= electrum_address_listunspent(coin->symbol,ep,&retjson,ap->coinaddr,1,zero,zero)) != 0 ) + free_json(retjson); + } + if ( (ap= LP_addressfind(coin,coin->smartaddr)) != 0 ) + { + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->U.height > 0 && up->spendheight < 0 ) + { + if ( up->SPV == 0 ) + { + nonz++; + up->SPV = LP_merkleproof(coin,coin->smartaddr,backupep,up->U.txid,up->U.height); + if ( up->SPV > 0 ) + { + if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && tx->SPV == 0 ) + { + tx->SPV = up->SPV; + //printf("%s %s: SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); + } + } + } + else if ( up->SPV == -1 ) + { + nonz++; + printf("SPV failure for %s %s\n",coin->symbol,bits256_str(str,up->U.txid)); + oldht = up->U.height; + LP_txheight_check(coin,ap->coinaddr,up->U.txid); + if ( oldht != up->U.height ) + up->SPV = LP_merkleproof(coin,coin->smartaddr,backupep,up->U.txid,up->U.height); + if ( up->SPV <= 0 ) + up->SPV = -2; + else printf("%s %s: corrected SPV.%d\n",coin->symbol,bits256_str(str,up->U.txid),up->SPV); + } + } + } + } + while ( ep != 0 ) + { + if ( time(NULL) > ep->keepalive+LP_ELECTRUM_KEEPALIVE ) + { + //printf("%s electrum.%p needs a keepalive: lag.%d\n",ep->symbol,ep,(int32_t)(time(NULL) - ep->keepalive)); + if ( (retjson= electrum_banner(coin->symbol,ep,&retjson)) != 0 ) + free_json(retjson); + ep->keepalive = (uint32_t)time(NULL); + } + ep = ep->prev; + } + continue; + } + if ( coin->firstrefht == 0 ) + continue; + else if ( coin->firstscanht == 0 ) + coin->lastscanht = coin->firstscanht = coin->firstrefht; + else if ( coin->firstrefht < coin->firstscanht ) + { + printf("detected %s firstrefht.%d < firstscanht.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht); + coin->lastscanht = coin->firstscanht = coin->firstrefht; + } + if ( coin->lastscanht == coin->longestchain+1 ) + { + //printf("%s lastscanht.%d is longest.%d + 1\n",coin->symbol,coin->lastscanht,coin->longestchain); + continue; + } + else if ( coin->lastscanht > coin->longestchain+1 ) + { + printf("detected chain rewind lastscanht.%d vs longestchain.%d, first.%d ref.%d\n",coin->lastscanht,coin->longestchain,coin->firstscanht,coin->firstrefht); + LP_undospends(coin,coin->longestchain-1); + //LP_mempoolscan(coin->symbol,zero); + coin->lastscanht = coin->longestchain - 1; + if ( coin->firstscanht < coin->lastscanht ) + coin->lastscanht = coin->firstscanht; + continue; + } + if ( strcmp(coin->symbol,"BTC") != 0 && strcmp(coin->symbol,"KMD") != 0 ) // SPV as backup + { + nonz++; + if ( strcmp("BTC",coins) == 0 )//&& coin->lastscanht < coin->longestchain-3 ) + printf("[%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); + for (j=0; j<100; j++) + { + if ( LP_blockinit(coin,coin->lastscanht) < 0 ) + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("blockinit.%s %d error\n",coin->symbol,coin->lastscanht); + break; + } + coin->lastscanht++; + if ( coin->lastscanht == coin->longestchain+1 || strcmp("BTC",coins) == 0 ) + break; + } + if ( strcmp("BTC",coins) == 0 ) + printf("done [%s]: %s ref.%d scan.%d to %d, longest.%d\n",coins,coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); + } + } + if ( coins == 0 ) + return; + if ( nonz == 0 ) + usleep(100000); + } +} + +int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int32_t pubsock) +{ + static uint32_t counter;//,didinstantdex; + struct iguana_info *coin,*ctmp; char *origipaddr; uint32_t now; int32_t notarized,height,nonz = 0; + if ( (origipaddr= myipaddr) == 0 ) + origipaddr = "127.0.0.1"; + if ( mypeer == 0 ) + myipaddr = "127.0.0.1"; + HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht + { + now = (uint32_t)time(NULL); +#ifdef bruteforce + if ( IAMLP != 0 && coin->inactive == 0 && coin->electrum == 0 && didinstantdex == 0 && strcmp("KMD",coin->symbol) == 0 ) + { + LP_instantdex_deposits(coin); + didinstantdex = now; + } +#endif + /*if ( (coin->addr_listunspent_requested != 0 && now > coin->lastpushtime+LP_ORDERBOOK_DURATION*.5) || now > coin->lastpushtime+LP_ORDERBOOK_DURATION*5 ) + { + //printf("PUSH addr_listunspent_requested %u\n",coin->addr_listunspent_requested); + coin->lastpushtime = (uint32_t)now; + LP_smartutxos_push(coin); + coin->addr_listunspent_requested = 0; + }*/ + if ( coin->electrum == 0 && coin->inactive == 0 && now > coin->lastgetinfo+LP_GETINFO_INCR ) + { + nonz++; + if ( (height= LP_getheight(¬arized,coin)) > coin->longestchain ) + { + coin->longestchain = height; + if ( notarized != 0 && notarized > coin->notarized ) + { + coin->notarized = notarized; + if ( IAMLP != 0 ) + LP_dPoW_broadcast(coin); + } + if ( 0 && coin->firstrefht != 0 ) + printf(">>>>>>>>>> set %s longestchain %d (ref.%d [%d, %d])\n",coin->symbol,height,coin->firstrefht,coin->firstscanht,coin->lastscanht); + } //else LP_mempoolscan(coin->symbol,zero); + coin->lastgetinfo = (uint32_t)now; + } + } + counter++; + return(nonz); +} + +int my_strncasecmp(const char *s1,const char *s2,size_t n) +{ + size_t i = 0; + while ( i < n ) + { + char c1 = s1[i]; + char c2 = s2[i]; + if ( c1 >= 'A' && c1 <= 'Z') + c1 = (c1 - 'A') + 'a'; + if ( c2 >= 'A' && c2 <= 'Z') + c2 = (c2 - 'A') + 'a'; + if ( c1 < c2 ) + return(-1); + if ( c1 > c2 ) + return(1); + if ( c1 == 0 ) + return(0); + ++i; + } + return(0); +} + +void bech32_tests() +{ + //char *test = "an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs"; + //char *test = "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"; + //char *test = "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"; + //char *test = "prefix:x64nx6hz"; + char *test = "bitcoincash:pq4p38fll9uuh2mzkesqhmgt66du4u0zzy92jchqqa"; // 35Xbnq3kLoNsjN67knFewiRc9fqewrCzMW + uint8_t data[82],data2[64],rmd160[21],addrtype; char rebuild[92],hrp[84]; int32_t data_len,data_len2; int32_t i; + if ( bech32_decode(hrp,data,&data_len,test) == 0 ) + { + printf("bech32_decode fails: '%s'\n",test); + } + else + { + bitcoin_addr2rmd160("BCH",0,&addrtype,rmd160,"pq4p38fll9uuh2mzkesqhmgt66du4u0zzy92jchqqa"); + bitcoin_address("BTC",rebuild,0,5,rmd160,20); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf("addr2rmd160 %d -> %s\n",addrtype,rebuild); + + data_len2 = 0; + if ( bech32_convert_bits(data2,&data_len2,8,data,data_len,5,0) == 0 ) + printf("error converting data5\n"); + for (i=0; i %d\n",data_len2); + bitcoin_addr2rmd160("BTC",0,&addrtype,rmd160+1,"35Xbnq3kLoNsjN67knFewiRc9fqewrCzMW"); + for (i=0; i ",(int32_t)data_len,test,"35Xbnq3kLoNsjN67knFewiRc9fqewrCzMW"); + for (i=0; i<20; i++) + printf("%02x",rmd160[i+1]); + printf("\n"); + } + data_len2 = 0; + rmd160[0] = (1 << 3); + bech32_convert_bits(data2,&data_len2,5,rmd160,21,8,1); + for (i=0; i hrp.(%s) datalen.%d\n",test,hrp,(int32_t)data_len); + } + if ( my_strncasecmp(rebuild,test,92)) + { + printf("bech32_encode produces incorrect result: '%s' vs (%s)\n",test,rebuild); + } + printf("end of bech32 tests\n"); +} + +void LP_initcoins(void *ctx,int32_t pubsock,cJSON *coins) +{ + int32_t i,n,notarized; cJSON *item; char *symbol; struct iguana_info *coin; + for (i=0; iinactive = (uint32_t)time(NULL); + else + { + LP_unspents_load(coin->symbol,coin->smartaddr); + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + LP_importaddress("KMD",BOTS_BONDADDRESS); + LP_dPoW_request(coin); + } + } + if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) + coin->txfee = LP_MIN_TXFEE; + } + } + if ( (n= cJSON_GetArraySize(coins)) > 0 ) + { + for (i=0; iinactive = (uint32_t)time(NULL); + else LP_unspents_load(coin->symbol,coin->smartaddr); + if ( coin->txfee == 0 && strcmp(coin->symbol,"BTC") != 0 ) + coin->txfee = LP_MIN_TXFEE; + if ( 0 && strcmp(coin->symbol,"BCH") == 0 ) + { + bech32_tests(); + } + } + } + } + for (i=0; i 0 && netid < 9) && (seednode == 0 || seednode[0] == 0) ) + { + sprintf(fixedseed,"5.9.253.%d",195 + netid); + seednode = fixedseed; + } + if ( seednode == 0 || seednode[0] == 0 ) + { + printf("default seed nodes for netid.%d\n",netid); + OS_randombytes((void *)&r,sizeof(r)); + r = 0; + for (j=0; j lasttime+100 ) + { + //printf("LP_pubkeysloop %u\n",(uint32_t)time(NULL)); + LP_notify_pubkeys(ctx,LP_mypubsock); + lasttime = (uint32_t)time(NULL); + } + } + sleep(3); + } +} + +void LP_swapsloop(void *ctx) +{ + char *retstr; + strcpy(LP_swapsloop_stats.name,"LP_swapsloop"); + LP_swapsloop_stats.threshold = 605000.; + sleep(50); + while ( LP_STOP_RECEIVED == 0 ) + { + if ( strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") != 0 ) + { + LP_millistats_update(&LP_swapsloop_stats); + if ( (retstr= basilisk_swapentry(0,0,0)) != 0 ) + free(retstr); + sleep(600); + } else sleep(10); + } +} + +void gc_loop(void *ctx) +{ + uint32_t now; struct LP_address_utxo *up,*utmp; struct rpcrequest_info *req,*rtmp; int32_t flag = 0; + strcpy(LP_gcloop_stats.name,"gc_loop"); + LP_gcloop_stats.threshold = 11000.; + while ( LP_STOP_RECEIVED == 0 ) + { + flag = 0; + LP_millistats_update(&LP_gcloop_stats); + portable_mutex_lock(&LP_gcmutex); + DL_FOREACH_SAFE(LP_garbage_collector,req,rtmp) + { + DL_DELETE(LP_garbage_collector,req); + //printf("garbage collect ipbits.%x\n",req->ipbits); + free(req); + flag++; + } + now = (uint32_t)time(NULL); + DL_FOREACH_SAFE(LP_garbage_collector2,up,utmp) + { + if ( now > (uint32_t)up->spendheight+120 ) + { + DL_DELETE(LP_garbage_collector2,up); + //char str[65]; printf("garbage collect %s/v%d lag.%d\n",bits256_str(str,up->U.txid),up->U.vout,now-up->spendheight); + free(up); + } + flag++; + } + portable_mutex_unlock(&LP_gcmutex); + if ( 0 && flag != 0 ) + printf("gc_loop.%d\n",flag); + sleep(10); + } +} + +void queue_loop(void *ctx) +{ + struct LP_queue *ptr,*tmp; cJSON *json; uint8_t linebuf[32768]; int32_t k,sentbytes,nonz,flag,duplicate,n=0; + strcpy(queue_loop_stats.name,"queue_loop"); + queue_loop_stats.threshold = 1000.; + while ( LP_STOP_RECEIVED == 0 ) + { + LP_millistats_update(&queue_loop_stats); + //printf("LP_Q.%p next.%p prev.%p\n",LP_Q,LP_Q!=0?LP_Q->next:0,LP_Q!=0?LP_Q->prev:0); + n = nonz = flag = 0; + DL_FOREACH_SAFE(LP_Q,ptr,tmp) + { + n++; + flag = 0; + if ( ptr->sock >= 0 ) + { + if ( ptr->notready == 0 || (LP_rand() % ptr->notready) == 0 ) + { + if ( LP_sockcheck(ptr->sock) > 0 ) + { + //bits256 magic; + //magic = LP_calc_magic(ptr->msg,(int32_t)(ptr->msglen - sizeof(bits256))); + //memcpy(&ptr->msg[ptr->msglen - sizeof(bits256)],&magic,sizeof(magic)); + if ( 0 ) + { + static FILE *fp; + if ( fp == 0 ) + fp = fopen("packet.log","wb"); + if ( fp != 0 ) + { + fprintf(fp,"%s\n",(char *)ptr->msg); + fflush(fp); + } + } + if ( (json= cJSON_Parse((char *)ptr->msg)) != 0 ) + { + if ( 1 && ptr->msglen < sizeof(linebuf) ) + { + if ( (k= MMJSON_encode(linebuf,(char *)ptr->msg)) > 0 ) + { + if ( (sentbytes= nn_send(ptr->sock,linebuf,k,0)) != k ) + printf("%d LP_send mmjson sent %d instead of %d\n",n,sentbytes,k); + else flag++; + } + //printf("k.%d SEND.(%s) sock.%d\n",k,(char *)ptr->msg,ptr->sock); + } + free_json(json); + } + if ( flag == 0 ) + { + //printf("len.%d SEND.(%s) sock.%d\n",ptr->msglen,(char *)ptr->msg,ptr->sock); + if ( (sentbytes= nn_send(ptr->sock,ptr->msg,ptr->msglen,0)) != ptr->msglen ) + printf("%d LP_send sent %d instead of %d\n",n,sentbytes,ptr->msglen); + else flag++; + } + ptr->sock = -1; + if ( ptr->peerind > 0 ) + ptr->starttime = (uint32_t)time(NULL); + } + else + { + if ( ptr->notready++ > 1000 ) + flag = 1; + } + } + } + else if ( 0 && time(NULL) > ptr->starttime+13 ) + { + LP_crc32find(&duplicate,-1,ptr->crc32); + if ( duplicate > 0 ) + { + LP_Qfound++; + if ( (LP_Qfound % 100) == 0 ) + printf("found.%u Q.%d err.%d match.%d\n",ptr->crc32,LP_Qenqueued,LP_Qerrors,LP_Qfound); + flag++; + } + else if ( 0 ) // too much beyond duplicate filter when network is busy + { + printf("couldnt find.%u peerind.%d Q.%d err.%d match.%d\n",ptr->crc32,ptr->peerind,LP_Qenqueued,LP_Qerrors,LP_Qfound); + ptr->peerind++; + if ( (ptr->sock= LP_peerindsock(&ptr->peerind)) < 0 ) + { + printf("%d no more peers to try at peerind.%d %p Q_LP.%p\n",n,ptr->peerind,ptr,LP_Q); + flag++; + LP_Qerrors++; + } + } + } + if ( flag != 0 ) + { + nonz++; + portable_mutex_lock(&LP_networkmutex); + DL_DELETE(LP_Q,ptr); + portable_mutex_unlock(&LP_networkmutex); + free(ptr); + ptr = 0; + break; + } + } + if ( nonz == 0 ) + { + if ( IAMLP == 0 ) + usleep(50000); + else usleep(10000); + } + } +} + +void LP_reserved_msgs(void *ignore) +{ + bits256 zero; int32_t flag,nonz; struct nn_pollfd pfd; + memset(zero.bytes,0,sizeof(zero)); + strcpy(LP_reserved_msgs_stats.name,"LP_reserved_msgs"); + LP_reserved_msgs_stats.threshold = 1000.; + while ( LP_STOP_RECEIVED == 0 ) + { + nonz = 0; + LP_millistats_update(&LP_reserved_msgs_stats); + if ( num_Reserved_msgs[1] > 0 ) + { + nonz++; + portable_mutex_lock(&LP_reservedmutex); + if ( num_Reserved_msgs[1] > 0 ) + { + num_Reserved_msgs[1]--; + //printf("PRIORITY BROADCAST.(%s)\n",Reserved_msgs[1][num_Reserved_msgs[1]]); + LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[1][num_Reserved_msgs[1]]); + Reserved_msgs[1][num_Reserved_msgs[1]] = 0; + } + portable_mutex_unlock(&LP_reservedmutex); + } + else if ( num_Reserved_msgs[0] > 0 ) + { + nonz++; + flag = 0; + if ( flag == 0 && LP_mypubsock >= 0 ) + { + memset(&pfd,0,sizeof(pfd)); + pfd.fd = LP_mypubsock; + pfd.events = NN_POLLOUT; + if ( nn_poll(&pfd,1,1) == 1 ) + flag = 1; + } else flag = 1; + if ( flag == 1 ) + { + portable_mutex_lock(&LP_reservedmutex); + num_Reserved_msgs[0]--; + //printf("BROADCAST.(%s)\n",Reserved_msgs[0][num_Reserved_msgs[0]]); + LP_broadcast_message(LP_mypubsock,"","",zero,Reserved_msgs[0][num_Reserved_msgs[0]]); + Reserved_msgs[0][num_Reserved_msgs[0]] = 0; + portable_mutex_unlock(&LP_reservedmutex); + } + } + if ( ignore == 0 ) + break; + if ( nonz == 0 ) + usleep(5000); + } +} + +int32_t LP_reserved_msg(int32_t priority,char *base,char *rel,bits256 pubkey,char *msg) +{ + struct LP_pubkey_info *pubp; uint32_t timestamp; char *method; cJSON *argjson; int32_t skip,sentbytes,n = 0; + skip = 0; + if ( (argjson= cJSON_Parse(msg)) != 0 ) + { + if ( (method= jstr(argjson,"method")) != 0 ) + { + if ( strcmp(method,"gettradestatus") == 0 || strcmp(method,"wantnotify") == 0 || strcmp(method,"getdPoW") == 0 ) + skip = 1; + } + if ( (timestamp= juint(argjson,"timestamp")) != 0 && time(NULL) > timestamp+60 ) + skip = 1; + free_json(argjson); + } + if ( skip != 0 ) + return(-1); + if ( strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + return(-1); + if ( priority > 0 && bits256_nonz(pubkey) != 0 ) + { + if ( (pubp= LP_pubkeyfind(pubkey)) != 0 ) + { + if ( pubp->pairsock >= 0 ) + { + if ( (sentbytes= nn_send(pubp->pairsock,msg,(int32_t)strlen(msg)+1,0)) < 0 ) + { + //pubp->pairsock = -1; + //LP_peer_pairsock(pubkey); + //printf("mark cmdchannel %d closed sentbytes.%d\n",pubp->pairsock,sentbytes); + } + else + { + printf("sent %d bytes to cmdchannel.%d\n",sentbytes,pubp->pairsock); + return(sentbytes); + } + } + } + } + portable_mutex_lock(&LP_reservedmutex); + if ( num_Reserved_msgs[priority] < sizeof(Reserved_msgs[priority])/sizeof(*Reserved_msgs[priority]) ) + { + Reserved_msgs[priority][num_Reserved_msgs[priority]++] = msg; + n = num_Reserved_msgs[priority]; + } //else LP_broadcast_message(LP_mypubsock,base,rel,pubkey,msg); + if ( num_Reserved_msgs[priority] > max_Reserved_msgs[priority] ) + { + max_Reserved_msgs[priority] = num_Reserved_msgs[priority]; + //if ( (max_Reserved_msgs[priority] % 100) == 0 ) + printf("New priority.%d max_Reserved_msgs.%d\n",priority,max_Reserved_msgs[priority]); + } + portable_mutex_unlock(&LP_reservedmutex); + return(n); +} + +extern int32_t bitcoind_RPC_inittime; + +void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson) +{ + char *myipaddr=0,version[64]; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx(); + sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request)); + bitcoind_RPC_inittime = 1; + printf("%s %u\n",version,calc_crc32(0,version,(int32_t)strlen(version))); + if ( LP_MAXPRICEINFOS > 256 ) + { + printf("LP_MAXPRICEINFOS %d wont fit in a uint8_t, need to increase the width of the baseind and relind for struct LP_pubkey_quote\n",LP_MAXPRICEINFOS); + exit(-1); + } + LP_showwif = juint(argjson,"wif"); + if ( passphrase == 0 || passphrase[0] == 0 ) + { + printf("jeezy says we cant use the nullstring as passphrase and I agree\n"); + exit(-1); + } + IAMLP = !amclient; +#ifndef __linux__ + if ( IAMLP != 0 ) + { + printf("must run a unix node for LP node\n"); + exit(-1); + } +#endif + OS_randombytes((void *)&n,sizeof(n)); + srand((uint32_t)n); + if ( jobj(argjson,"gui") != 0 ) + safecopy(LP_gui,jstr(argjson,"gui"),sizeof(LP_gui)); + if ( jobj(argjson,"canbind") == 0 ) + { +#ifndef __linux__ + LP_canbind = IAMLP; +#else + LP_canbind = IAMLP; +#endif + } + else + { + LP_canbind = jint(argjson,"canbind"); + printf(">>>>>>>>>>> set LP_canbind.%d\n",LP_canbind); + } + if ( LP_canbind > 1000 && LP_canbind < 65536 ) + LP_fixed_pairport = LP_canbind; + if ( LP_canbind != 0 ) + LP_canbind = 1; + srand((int32_t)n); + if ( userhome != 0 && userhome[0] != 0 ) + { + safecopy(USERHOME,userhome,sizeof(USERHOME)); +#ifdef __APPLE__ + strcat(USERHOME,"/Library/Application Support"); +#endif + } + portable_mutex_init(&LP_peermutex); + portable_mutex_init(&LP_utxomutex); + portable_mutex_init(&LP_UTXOmutex); + portable_mutex_init(&LP_commandmutex); + portable_mutex_init(&LP_swaplistmutex); + portable_mutex_init(&LP_cachemutex); + portable_mutex_init(&LP_networkmutex); + portable_mutex_init(&LP_gcmutex); + portable_mutex_init(&LP_forwardmutex); + portable_mutex_init(&LP_inusemutex); + portable_mutex_init(&LP_psockmutex); + portable_mutex_init(&LP_coinmutex); + portable_mutex_init(&LP_pubkeymutex); + portable_mutex_init(&LP_electrummutex); + portable_mutex_init(&LP_messagemutex); + portable_mutex_init(&LP_portfoliomutex); + portable_mutex_init(&LP_butxomutex); + portable_mutex_init(&LP_reservedmutex); + portable_mutex_init(&LP_nanorecvsmutex); + portable_mutex_init(&LP_tradebotsmutex); + portable_mutex_init(&LP_cJSONmutex); + portable_mutex_init(&LP_logmutex); + portable_mutex_init(&LP_statslogmutex); + portable_mutex_init(&LP_tradesmutex); + portable_mutex_init(&LP_commandQmutex); + myipaddr = clonestr("127.0.0.1"); +#ifndef _WIN32 +#ifndef FROM_JS + if ( system("curl -s4 checkip.amazonaws.com > myipaddr") == 0 ) + { + char ipfname[64]; + strcpy(ipfname,"myipaddr"); + if ( (myipaddr= OS_filestr(&filesize,ipfname)) != 0 && myipaddr[0] != 0 ) + { + n = strlen(myipaddr); + if ( myipaddr[n-1] == '\n' ) + myipaddr[--n] = 0; + strcpy(LP_myipaddr,myipaddr); + } else printf("error getting myipaddr\n"); + } else printf("error issuing curl\n"); +#else + IAMLP = 0; +#endif +#endif + if ( IAMLP != 0 ) + { + G.netid = juint(argjson,"netid"); + LP_mypubsock = -1; + nanomsg_transportname(0,subaddr,myipaddr,mypubport); + nanomsg_transportname(1,bindaddr,myipaddr,mypubport); + valid = 0; + if ( (LP_mypubsock= nn_socket(AF_SP,NN_PUB)) >= 0 ) + { + valid = 0; + if ( nn_bind(LP_mypubsock,bindaddr) >= 0 ) + valid++; + if ( valid > 0 ) + { + timeout = 100; + nn_setsockopt(LP_mypubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + //timeout = 10; + //nn_setsockopt(LP_mypubsock,NN_SOL_SOCKET,NN_MAXTTL,&timeout,sizeof(timeout)); + } + else + { + printf("error binding to (%s).%d\n",subaddr,LP_mypubsock); + if ( LP_mypubsock >= 0 ) + nn_close(LP_mypubsock), LP_mypubsock = -1; + } + } else printf("error getting pubsock %d\n",LP_mypubsock); + printf(">>>>>>>>> myipaddr.(%s) (%s) valid.%d pubbindaddr.%s pubsock.%d\n",bindaddr,subaddr,valid,bindaddr,LP_mypubsock); + LP_mypullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0); + } + if ( (coinsjson= jobj(argjson,"coins")) == 0 ) + { + if ( (coins_str= OS_filestr(&filesize,"coins.json")) != 0 || (coins_str= OS_filestr(&filesize,"exchanges/coins.json")) != 0 ) + { + unstringify(coins_str); + printf("UNSTRINGIFIED.(%s)\n",coins_str); + coinsjson = cJSON_Parse(coins_str); + free(coins_str); + // yes I know this coinsjson is not freed, not sure about if it is referenced + } + } + if ( coinsjson == 0 ) + { + printf("no coins object or coins.json file, must abort\n"); + exit(-1); + } + LP_initcoins(ctx,LP_mypubsock,coinsjson); + RPC_port = myport; + G.waiting = 1; + LP_initpeers(LP_mypubsock,LP_mypeer,LP_myipaddr,RPC_port,juint(argjson,"netid"),jstr(argjson,"seednode")); + //LP_mypullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0); + //strcpy(LP_publicaddr,pushaddr); + //LP_publicport = mypullport; + //LP_mybussock = LP_coinbus(mybusport); + printf("got %s, initpeers. LP_mypubsock.%d pullsock.%d RPC_port.%u mypullport.%d mypubport.%d pushaddr.%s\n",myipaddr,LP_mypubsock,LP_mypullsock,RPC_port,mypullport,mypubport,pushaddr); + LP_passphrase_init(passphrase,jstr(argjson,"gui"),juint(argjson,"netid"),jstr(argjson,"seednode")); +#ifndef FROM_JS + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_psockloop,(void *)myipaddr) != 0 ) + { + printf("error launching LP_psockloop for (%s)\n",myipaddr); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_reserved_msgs,(void *)myipaddr) != 0 ) + { + printf("error launching LP_reserved_msgs for (%s)\n",myipaddr); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)command_rpcloop,ctx) != 0 ) + { + printf("error launching command_rpcloop for ctx.%p\n",ctx); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)queue_loop,ctx) != 0 ) + { + printf("error launching queue_loop for ctx.%p\n",ctx); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)gc_loop,ctx) != 0 ) + { + printf("error launching gc_loop for port.%p\n",ctx); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)prices_loop,ctx) != 0 ) + { + printf("error launching prices_loop for ctx.%p\n",ctx); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"") != 0 ) + { + printf("error launching LP_coinsloop for (%s)\n",""); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"BTC") != 0 ) + { + printf("error launching LP_coinsloop for (%s)\n","BTC"); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_coinsloop,(void *)"KMD") != 0 ) + { + printf("error launching LP_coinsloop for (%s)\n","KMD"); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_pubkeysloop,ctx) != 0 ) + { + printf("error launching LP_pubkeysloop for ctx.%p\n",ctx); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_tradesloop,ctx) != 0 ) + { + printf("error launching LP_tradessloop for ctx.%p\n",ctx); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_swapsloop,ctx) != 0 ) + { + printf("error launching LP_swapsloop for ctx.%p\n",ctx); + exit(-1); + } + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_commandQ_loop,ctx) != 0 ) + { + printf("error launching LP_commandQ_loop for ctx.%p\n",ctx); + exit(-1); + } + int32_t nonz,didremote=0; + LP_statslog_parse(); + bitcoind_RPC_inittime = 0; + while ( LP_STOP_RECEIVED == 0 ) + { + nonz = 0; + G.waiting = 1; + while ( G.initializing != 0 && strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + { + //fprintf(stderr,"."); + sleep(3); + } + if ( LP_mainloop_iter(ctx,myipaddr,mypeer,LP_mypubsock) != 0 ) + nonz++; + if ( didremote == 0 && LP_cmdcount > 0 ) + { + didremote = 1; + uint16_t myport2 = RPC_port-1; + printf("start remote port\n"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport2) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } + } + if ( nonz == 0 ) + usleep(1000); + else if ( IAMLP == 0 ) + usleep(1000); + } +#endif + printf("marketmaker exiting in 5 seconds\n"); + sleep(5); + exit(0); +} + +#ifdef FROM_JS +extern void *Nanomsg_threadarg; +void *nn_thread_main_routine(void *arg); + +void emscripten_usleep(int32_t x) +{ +} + +char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout) +{ + static uint32_t counter; char fname[512],*retstr; long fsize; + if ( strncmp("http://",url,strlen("http://")) != 0 ) + return(clonestr("{\"error\":\"only http allowed\"}")); + sprintf(fname,"bitcoind_RPC/request.%d",counter % 10); + counter++; + //printf("issue.(%s)\n",url); + emscripten_wget(url,fname); + retstr = OS_filestr(&fsize,fname); + //printf("bitcoind_RPC(%s) -> fname.(%s) %s\n",url,fname,retstr); + return(retstr); +} + +char *barterDEX(char *argstr) +{ + static void *ctx; + cJSON *argjson; char *retstr; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + printf("barterDEX.(%s)\n",argstr); + if ( (argjson= cJSON_Parse(argstr)) != 0 ) + { + LP_queuecommand(&retstr,argstr,LP_mypubsock); + //retstr = LP_command_process(ctx,LP_myipaddr,LP_mypubsock,argjson,(uint8_t *)argstr,(int32_t)strlen(argstr)); + while ( retstr == 0 ) + usleep(50000); + free_json(argjson); + } else retstr = clonestr("{\"error\":\"couldnt parse request\"}"); + return(retstr); +} + +void LP_fromjs_iter() +{ + static void *ctx; char *retstr; + if ( G.initializing != 0 ) + { + printf("LP_fromjs_iter during G.initializing, skip\n"); + return; + } + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + //if ( Nanomsg_threadarg != 0 ) + // nn_thread_main_routine(Nanomsg_threadarg); + //LP_pubkeys_query(); + //LP_utxosQ_process(); + //LP_nanomsg_recvs(ctx); + LP_mainloop_iter(ctx,LP_myipaddr,0,LP_mypubsock); + //queue_loop(0); + if ( 0 ) // 10 seconds + { + LP_coinsloop(0); + if ( 0 ) // 100 seconds + { + LP_notify_pubkeys(ctx,LP_mypubsock); + LP_privkey_updates(ctx,LP_mypubsock,0); + if ( (retstr= basilisk_swapentry(0,0,0)) != 0 ) + free(retstr); + } + } +} + +#endif + +#undef calloc +#undef free +#undef realloc +#undef clonestr + +struct LP_memory_list +{ + struct LP_memory_list *next,*prev; + uint32_t timestamp,len; + void *ptr; +} *LP_memory_list; +int32_t zeroval() { return(0); } + +void *LP_alloc(uint64_t len) +{ +//return(calloc(1,len)); + LP_cjson_allocated += len; + LP_cjson_total += len; + LP_cjson_count++; + struct LP_memory_list *mp; + mp = calloc(1,sizeof(*mp) + len); + mp->ptr = calloc(1,len); + //printf(">>>>>>>>>>> LP_alloc mp.%p ptr.%p len.%llu %llu\n",mp,mp->ptr,(long long)len,(long long)LP_cjson_allocated); + mp->timestamp = (uint32_t)time(NULL); + mp->len = (uint32_t)len; + portable_mutex_lock(&LP_cJSONmutex); + DL_APPEND(LP_memory_list,mp); + portable_mutex_unlock(&LP_cJSONmutex); + return(mp->ptr); +} + +void LP_free(void *ptr) +{ + static uint32_t lasttime,unknown; static int64_t lasttotal; +//free(ptr); return; + uint32_t now; char str[65]; int32_t n,lagging; uint64_t total = 0; struct LP_memory_list *mp,*tmp; + if ( (now= (uint32_t)time(NULL)) > lasttime+1 ) + { + n = lagging = 0; + DL_FOREACH_SAFE(LP_memory_list,mp,tmp) + { + total += mp->len; + n++; + if ( 0 && now > mp->timestamp+120 ) + { + lagging++; + if ( now > mp->timestamp+240 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_memory_list,mp); + portable_mutex_unlock(&LP_cJSONmutex); + free(mp->ptr); + free(mp); + } + } + } + printf("[%lld] total %d allocated total %llu/%llu [%llu %llu] %.1f ave %s unknown.%u lagging.%d\n",(long long)(total-lasttotal),n,(long long)total,(long long)LP_cjson_allocated,(long long)LP_cjson_total,(long long)LP_cjson_count,(double)LP_cjson_total/LP_cjson_count,mbstr(str,total),unknown,lagging); + lasttime = (uint32_t)time(NULL); + lasttotal = total; + } + DL_FOREACH_SAFE(LP_memory_list,mp,tmp) + { + if ( mp->ptr == ptr ) + break; + mp = 0; + } + if ( mp != 0 ) + { + LP_cjson_allocated -= mp->len; + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_memory_list,mp); + portable_mutex_unlock(&LP_cJSONmutex); + //printf(">>>>>>>>>>> LP_free ptr.%p mp.%p len.%u %llu\n",ptr,mp,mp->len,(long long)LP_cjson_allocated); + free(mp->ptr); + free(mp); + } else unknown++; // free from source file with #define redirect for alloc that wasnt +} + +/*char *LP_clonestr(char *str) +{ + char *retstr = LP_alloc(strlen(str)+1); + strcpy(retstr,str); + return(retstr); +} + +void *LP_realloc(void *ptr,uint64_t len) +{ + return(realloc(ptr,len)); +}*/ + + diff --git a/iguana/exchanges/LP_network.c b/iguana/exchanges/LP_network.c new file mode 100644 index 000000000..4ad8662f2 --- /dev/null +++ b/iguana/exchanges/LP_network.c @@ -0,0 +1,941 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_network.c +// marketmaker +// + +struct psock +{ + uint32_t lasttime,lastping,errors; + int32_t publicsock,sendsock,ispaired,cmdchannel; + uint16_t publicport,sendport; + char sendaddr[128],publicaddr[128]; +} *PSOCKS; + +uint16_t Numpsocks,Psockport = MIN_PSOCK_PORT,Pcmdport = MAX_PSOCK_PORT; + +#ifdef FROM_JS + +int32_t nn_socket(int domain, int protocol) +{ + return(0); +} + +int32_t nn_close(int s) +{ + return(0); +} + +int32_t nn_setsockopt(int s, int level, int option, const void *optval,size_t optvallen) +{ + return(0); +} + +int32_t nn_getsockopt(int s, int level, int option, void *optval,size_t *optvallen) +{ + return(0); +} + +int32_t nn_bind(int s, const char *addr) +{ + return(-1); +} + +int32_t nn_connect(int s, const char *addr) +{ + if ( strncmp("ws://",addr,strlen("ws://")) != 0 ) + return(-1); + return(0); +} + +int32_t nn_shutdown(int s, int how) +{ + return(0); +} + +int32_t nn_send(int s, const void *buf, size_t len, int flags) +{ + printf("JS cant nn_send (%s)\n",(char *)buf); + return(0); +} + +int32_t nn_recv(int s, void *buf, size_t len, int flags) +{ + return(0); +} + +int32_t nn_errno(void) +{ + return(-11); +} + +const char *nn_strerror(int errnum) +{ + return("nanomsg error"); +} + +int32_t nn_poll(struct nn_pollfd *fds, int nfds, int timeout) +{ + return(0); +} + + +#endif + +char *nanomsg_transportname(int32_t bindflag,char *str,char *ipaddr,uint16_t port) +{ + sprintf(str,"tcp://%s:%u",bindflag == 0 ? ipaddr : "*",port); + return(str); +} + +/*char *nanomsg_transportname2(int32_t bindflag,char *str,char *ipaddr,uint16_t port) +{ + sprintf(str,"ws://%s:%u",bindflag == 0 ? ipaddr : "*",port+10); + return(str); +} + +int32_t _LP_send(int32_t sock,void *msg,int32_t sendlen,int32_t freeflag) +{ + int32_t sentbytes; + if ( sock < 0 ) + { + printf("LP_send.(%s) to illegal socket\n",(char *)msg); + if ( freeflag != 0 ) + free(msg); + return(-1); + } + if ( (sentbytes= nn_send(sock,msg,sendlen,0)) != sendlen ) + printf("LP_send sent %d instead of %d\n",sentbytes,sendlen); + else printf("SENT.(%s)\n",(char *)msg); + if ( freeflag != 0 ) + free(msg); + return(sentbytes); +}*/ + +int32_t LP_sockcheck(int32_t sock) +{ + struct nn_pollfd pfd; + pfd.fd = sock; + pfd.events = NN_POLLOUT; + if ( nn_poll(&pfd,1,1) > 0 ) + return(1); + else return(-1); +} + +struct LP_queue +{ + struct LP_queue *next,*prev; + int32_t sock,peerind,msglen; + uint32_t starttime,crc32,notready; + uint8_t msg[]; +} *LP_Q; +int32_t LP_Qenqueued,LP_Qerrors,LP_Qfound; + +void _LP_sendqueueadd(uint32_t crc32,int32_t sock,uint8_t *msg,int32_t msglen,int32_t peerind) +{ + struct LP_queue *ptr; + ptr = calloc(1,sizeof(*ptr) + msglen + sizeof(bits256)); + ptr->crc32 = crc32; + ptr->sock = sock; + ptr->peerind = peerind; + ptr->msglen = (int32_t)(msglen + 0*sizeof(bits256)); + memcpy(ptr->msg,msg,msglen); // sizeof(bits256) at the end all zeroes + DL_APPEND(LP_Q,ptr); + LP_Qenqueued++; + //printf("Q.%p: peerind.%d msglen.%d sock.%d\n",ptr,peerind,msglen,sock); +} + +uint32_t _LP_magic_check(bits256 hash,bits256 magic) +{ + bits256 pubkey,shared; + pubkey = curve25519(magic,curve25519_basepoint9()); + shared = curve25519(hash,pubkey); + return(shared.uints[1] & ((1 << LP_MAGICBITS)-1)); +} + +bits256 LP_calc_magic(uint8_t *msg,int32_t len) +{ + static uint32_t maxn,counter,nsum; static double sum; + bits256 magic,hash; int32_t n = 0; double millis; + vcalc_sha256(0,hash.bytes,msg,len); + millis = OS_milliseconds(); + while ( 1 ) + { + magic = rand256(1); + if ( _LP_magic_check(hash,magic) == LP_BARTERDEX_VERSION ) + break; + n++; + } + sum += (OS_milliseconds() - millis); + nsum += n; + counter++; + if ( n > maxn || (LP_rand() % 10000) == 0 ) + { + if ( n > maxn ) + { + printf("LP_calc_magic maxn.%d <- %d | ",maxn,n); + maxn = n; + } + printf("millis %.3f ave %.3f, aveiters %.1f\n",OS_milliseconds() - millis,sum/counter,(double)nsum/counter); + } + return(magic); +} + +int32_t LP_magic_check(uint8_t *msg,int32_t recvlen,char *remoteaddr) +{ + bits256 magic,hash; uint32_t val; + recvlen -= sizeof(bits256); + if ( recvlen > 0 ) + { + vcalc_sha256(0,hash.bytes,msg,recvlen); + memcpy(magic.bytes,&msg[recvlen],sizeof(magic)); + val = _LP_magic_check(hash,magic); + if ( val != LP_BARTERDEX_VERSION ) + printf("magicval = %x from %s\n",val,remoteaddr); + return(val == LP_BARTERDEX_VERSION); + } + return(-1); +} + +int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32) +{ + static uint32_t crcs[16384]; static unsigned long dup,total; + int32_t i; + *duplicatep = 0; + if ( ind < 0 ) + { + total++; + for (i=0; i 0 ) + { + crcs[i] = crcs[i >> 1]; + crcs[i >> 1] = crc32; + dup++; + //printf("duplicate %u in slot %d -> slot %d (%lu / %lu)\n",crc32,i,i>>1,dup,total); + } + *duplicatep = 1; + break; + } + else if ( crcs[i] == 0 ) + break; + } + if ( i >= sizeof(crcs)/sizeof(*crcs) ) + i = (LP_rand() % (sizeof(crcs)/sizeof(*crcs))); + return(i); + } + else + { + crcs[ind] = crc32; + return(ind); + } +} + +int32_t LP_peerindsock(int32_t *peerindp) +{ + struct LP_peerinfo *peer,*tmp; int32_t peerind = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + peerind++; + if ( peer->errors < LP_MAXPEER_ERRORS && peer->pushsock >= 0 ) + { + if ( peerind < *peerindp ) + continue; + *peerindp = peerind; + //printf("peerind.%d -> sock %d\n",peerind,peer->pushsock); + return(peer->pushsock); + } + } + return(-1); +} + +void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack) +{ + int32_t maxind,peerind = 0; //sentbytes, + if ( sock0 < 0 && sock1 < 0 ) + { + if ( (maxind= LP_numpeers()) > 0 ) + peerind = (LP_rand() % maxind) + 1; + else peerind = 1; + sock0 = LP_peerindsock(&peerind); + if ( (maxind= LP_numpeers()) > 0 ) + peerind = (LP_rand() % maxind) + 1; + else peerind = 1; + sock1 = LP_peerindsock(&peerind); + } + if ( sock0 >= 0 ) + _LP_sendqueueadd(crc32,sock0,msg,msglen,needack * peerind); + if ( sock1 >= 0 ) + _LP_sendqueueadd(crc32,sock1,msg,msglen,needack); +} + +void LP_queuesend(uint32_t crc32,int32_t pubsock,char *base,char *rel,uint8_t *msg,int32_t msglen) +{ + portable_mutex_lock(&LP_networkmutex); + if ( pubsock >= 0 ) + _LP_queuesend(crc32,pubsock,-1,msg,msglen,0); + else _LP_queuesend(crc32,-1,-1,msg,msglen,1); + portable_mutex_unlock(&LP_networkmutex); +} + +// first 2 bytes == (crc32 & 0xffff) if encrypted, then nonce is next crypto_box_NONCEBYTES +// GENESIS_PRIVKEY is always the sender + +void LP_broadcast_finish(int32_t pubsock,char *base,char *rel,uint8_t *msg,cJSON *argjson,uint32_t crc32) +{ + int32_t msglen; char *method; + if ( (method= jstr(argjson,"method")) == 0 ) + return; + msg = (void *)jprint(argjson,0); + msglen = (int32_t)strlen((char *)msg) + 1; + if ( crc32 == 0 ) + crc32 = calc_crc32(0,&msg[2],msglen - 2); + //printf("crc32.%x IAMLP.%d pubsock.%d\n",crc32,G.LP_IAMLP,pubsock); +#ifdef FROM_MARKETMAKER + if ( (G.LP_IAMLP == 0 || pubsock < 0) && strcmp(method,"psock") != 0 ) +#else + if ( (IAMLP == 0 || pubsock < 0 && strcmp(method,"psock") != 0 ) +#endif + { + free(msg); +//printf("broadcast %s\n",jstr(argjson,"method")); + jdelete(argjson,"method"); + jaddstr(argjson,"method","broadcast"); + if ( jobj(argjson,"timestamp") == 0 ) + jaddnum(argjson,"timestamp",(uint32_t)time(NULL)); + // add signature here + msg = (void *)jprint(argjson,0); + msglen = (int32_t)strlen((char *)msg) + 1; + LP_queuesend(crc32,-1,base,rel,msg,msglen); + if ( pubsock >= 0 ) + LP_queuesend(crc32,pubsock,base,rel,msg,msglen); + } + else + { + LP_queuesend(crc32,pubsock,base,rel,msg,msglen); + } + free(msg); +} + +void LP_broadcast_message(int32_t pubsock,char *base,char *rel,bits256 destpub25519,char *msgstr) +{ + uint8_t encoded[LP_ENCRYPTED_MAXSIZE],space[sizeof(encoded)],*msg,*nonce,*cipher; int32_t encrypted=0,msglen; uint32_t crc32=0; cJSON *argjson; char *methodstr,method[64],cipherstr[LP_ENCRYPTED_MAXSIZE*2+1]; + msglen = (int32_t)strlen(msgstr) + 1; + msg = (void *)msgstr; + if ( bits256_nonz(destpub25519) != 0 ) + { + nonce = &encoded[2]; + OS_randombytes(nonce,crypto_box_NONCEBYTES); + cipher = &encoded[2 + crypto_box_NONCEBYTES]; + msglen = _SuperNET_cipher(nonce,&encoded[2 + crypto_box_NONCEBYTES],msg,msglen,destpub25519,GENESIS_PRIVKEY,space); + msglen += crypto_box_NONCEBYTES; + crc32 = calc_crc32(0,&encoded[2],msglen); + encoded[0] = crc32 & 0xff; + encoded[1] = (crc32 >> 8) & 0xff; + msg = encoded; + msglen += 2; + encrypted = 1; + //printf("msgstr.(%s)\n",msgstr); + free(msgstr), msgstr = 0; + } + if ( encrypted == 0 ) + { + if ( (argjson= cJSON_Parse(msgstr)) != 0 ) + { + if ( (methodstr= jstr(argjson,"method")) != 0 && strlen(methodstr) <= sizeof(method) ) + { + strcpy(method,methodstr); + jdelete(argjson,"method"); + if ( jobj(argjson,"method2") != 0 ) + jdelete(argjson,"method2"); + jaddstr(argjson,"method2",method); + jaddstr(argjson,"method",method); + //if ( strncmp(method,"connect",7) == 0 || strcmp(method,"reserved") == 0 ) + // printf("CRC32.%u (%s)\n",crc32,msgstr); + LP_broadcast_finish(pubsock,base,rel,msg,argjson,0); + //if ( strncmp(method,"connect",7) == 0 || strcmp(method,"reserved") == 0 ) + // printf("finished %u\n",crc32); + } // else printf("no valid method in (%s)\n",msgstr); + free_json(argjson); + } else printf("couldnt parse %p (%s)\n",msgstr,msgstr); + } + else + { + argjson = cJSON_CreateObject(); + init_hexbytes_noT(cipherstr,msg,msglen); + jaddstr(argjson,"cipher",cipherstr); + jaddstr(argjson,"method2","encrypted"); + jaddstr(argjson,"method","encrypted"); + LP_broadcast_finish(pubsock,base,rel,msg,argjson,crc32); + free_json(argjson); + } + if ( msgstr != 0 ) + free(msgstr); +} + +uint32_t LP_swapsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2]) +{ + uint8_t *buf; int32_t sentbytes,offset=0,i; + buf = malloc(datalen + sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2); + for (i=0; i<32; i++) + buf[offset++] = swap->I.myhash.bytes[i]; + for (i=0; i<32; i++) + buf[offset++] = swap->I.otherhash.bytes[i]; + offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); + if ( datalen > 0 ) + memcpy(&buf[offset],data,datalen), offset += datalen; + if ( (sentbytes= nn_send(pairsock,buf,offset,0)) != offset ) + { + printf("sentbytes.%d vs offset.%d\n",sentbytes,offset); + if ( sentbytes < 0 ) + { + } + } + //printf("sent %d bytes\n",sentbytes); + //else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data); + free(buf); + return(nextbits); +} + +struct LP_queuedcommand +{ + struct LP_queuedcommand *next,*prev; + char **retstrp; + int32_t responsesock,msglen,stats_JSONonly; + char msg[]; +} *LP_commandQ; + +void LP_commandQ_loop(void *ctx) +{ + struct LP_queuedcommand *ptr,*tmp; int32_t size,nonz; char *retstr; cJSON *argjson; + while ( LP_STOP_RECEIVED == 0 ) + { + nonz = 0; + DL_FOREACH_SAFE(LP_commandQ,ptr,tmp) + { + nonz++; + portable_mutex_lock(&LP_commandQmutex); + DL_DELETE(LP_commandQ,ptr); + portable_mutex_unlock(&LP_commandQmutex); + if ( (argjson= cJSON_Parse(ptr->msg)) != 0 ) + { + if ( (retstr= LP_command_process(ctx,"127.0.0.1",ptr->responsesock,argjson,(uint8_t *)ptr->msg,ptr->msglen,ptr->stats_JSONonly)) != 0 ) + { + //printf("processed.(%s)\n",retstr); + if ( ptr->responsesock >= 0 && (size= nn_send(ptr->responsesock,retstr,(int32_t)strlen(retstr)+1,0)) <= 0 ) + printf("error sending result\n"); + if ( ptr->retstrp != 0 ) + (*ptr->retstrp) = retstr; + else free(retstr); + } + else if ( ptr->retstrp != 0 ) + (*ptr->retstrp) = clonestr("{\"error\":\"timeout\"}"); + free_json(argjson); + } + free(ptr); + } + if ( nonz == 0 ) + usleep(50000); + } +} + +void LP_queuecommand(char **retstrp,char *buf,int32_t responsesock,int32_t stats_JSONonly) +{ + struct LP_queuedcommand *ptr; int32_t msglen; + msglen = (int32_t)strlen(buf) + 1; + portable_mutex_lock(&LP_commandQmutex); + ptr = calloc(1,sizeof(*ptr) + msglen); + if ( (ptr->retstrp= retstrp) != 0 ) + *retstrp = 0; + ptr->responsesock = responsesock; + ptr->msglen = msglen; + ptr->stats_JSONonly = stats_JSONonly; + memcpy(ptr->msg,buf,msglen); + DL_APPEND(LP_commandQ,ptr); + portable_mutex_unlock(&LP_commandQmutex); +} + +void mynn_close(int32_t sock) +{ + struct nn_pollfd pfd; int32_t n; void *buf; + if ( sock >= 0 ) + { + while ( (n= nn_recv(sock,&buf,NN_MSG,0)) > 0 ) + printf("got n.%d bytes from nn_close(%d)\n",n,sock); + pfd.fd = sock; + pfd.events = POLLOUT; + while ( nn_poll(&pfd,1,100) > 0 ) + { + printf("cant send to nn_close(%d)\n",sock); + sleep(1); + } + if ( IAMLP != 0 ) + nn_close(sock); + } +} + +void LP_psockloop(void *_ptr) +{ + static struct nn_pollfd *pfds; + int32_t nexti=0,j,i,n,nonz,iter,retval,sentbytes,size=0,sendsock = -1; uint32_t now; struct psock *ptr=0; void *buf=0; char keepalive[512]; + strcpy(LP_psockloop_stats.name,"LP_psockloop"); + LP_psockloop_stats.threshold = 1000.; + while ( LP_STOP_RECEIVED == 0 ) + { + LP_millistats_update(&LP_psockloop_stats); + now = (uint32_t)time(NULL); + if ( buf != 0 && ptr != 0 && sendsock >= 0 ) + { + if ( size > 0 ) + { + if ( (sentbytes= nn_send(sendsock,buf,size,0)) != size ) // need tight loop + printf("LP_psockloop sent %d instead of %d\n",sentbytes,size); + if ( buf != 0 ) + { + if ( buf != keepalive ) + nn_freemsg(buf); + buf = 0; + size = 0; + ptr = 0; + sendsock = -1; + } + } + } + else if ( Numpsocks > 0 ) + { + if ( pfds == 0 ) + pfds = calloc(MAX_PSOCK_PORT,sizeof(*pfds)); + nexti = (rand() % Numpsocks); + portable_mutex_lock(&LP_psockmutex); + memset(pfds,0,sizeof(*pfds) * ((Numpsocks*2 <= MAX_PSOCK_PORT) ? Numpsocks*2 : MAX_PSOCK_PORT)); + for (iter=j=0; iter<2; iter++) + { + for (j=n=0; jpublicsock; + //printf("check sock.%d\n",ptr->publicsock); + pfds[n].events = POLLIN; + } + else + { + if ( pfds[n].fd != ptr->publicsock ) + { + printf("unexpected fd.%d mismatched publicsock.%d\n",pfds[n].fd,ptr->publicsock); + break; + } + else if ( (pfds[n].revents & POLLIN) != 0 ) + { + //printf("cmd.%d publicsock.%d %s has pollin\n",ptr->cmdchannel,ptr->publicsock,ptr->publicaddr); + buf = 0; + if ( (size= nn_recv(ptr->publicsock,&buf,NN_MSG,0)) > 0 ) + { + ptr->lasttime = now; + if ( ptr->cmdchannel == 0 ) + { + sendsock = ptr->sendsock; + break; + } else LP_queuecommand(0,(char *)buf,ptr->publicsock,0); + } + if ( buf != 0 ) + { + nn_freemsg(buf); + buf = 0; + size = 0; + } + } + } + n++; + if ( ptr->sendsock > 0 ) + { + if ( iter == 0 ) + { + pfds[n].fd = ptr->sendsock; + pfds[n].events = POLLIN; + } + else + { + if ( pfds[n].fd != ptr->sendsock ) + { + printf("unexpected fd.%d mismatched sendsock.%d\n",pfds[n].fd,ptr->sendsock); + break; + } + else if ( (pfds[n].revents & POLLIN) != 0 ) + { + if ( (size= nn_recv(ptr->sendsock,&buf,NN_MSG,0)) > 0 ) + { + //printf("%s paired has pollin (%s)\n",ptr->sendaddr,(char *)buf); + ptr->lasttime = now; + if ( ptr->ispaired != 0 ) + { + sendsock = ptr->publicsock; + break; + } + } + if ( buf != 0 ) + { + nn_freemsg(buf); + buf = 0; + size = 0; + } + } + } + n++; + } + } + if ( iter == 0 ) + { + if ( (retval= nn_poll(pfds,n,1)) <= 0 ) + { + //if ( retval != 0 ) + // printf("nn_poll retval.%d\n",retval); + break; + } // else printf("num pfds.%d retval.%d\n",n,retval); + } + } + if ( IAMLP != 0 && sendsock < 0 ) + { + usleep(30000); + for (i=nonz=0; icmdchannel == 0 && now > ptr->lasttime+PSOCK_KEEPALIVE ) + { + printf("PSOCKS[%d] of %d (%u %u) lag.%d IDLETIMEOUT\n",i,Numpsocks,ptr->publicport,ptr->sendport,now - ptr->lasttime); + if ( ptr->sendsock != ptr->publicsock && ptr->sendsock >= 0 ) + nn_close(ptr->sendsock), ptr->sendsock = -1; + if ( ptr->publicsock >= 0 ) + nn_close(ptr->publicsock), ptr->publicsock = -1; + nonz++; + } + } + if ( nonz > 0 ) + { + n = Numpsocks; + for (i=0; isendsock < 0 && ptr->publicsock < 0 ) + { + for (j=i; jispaired = ispaired; + ptr->cmdchannel = cmdchannel; + ptr->publicsock = publicsock; + ptr->publicport = recvport; + ptr->sendsock = sendsock; + ptr->sendport = sendport; + safecopy(ptr->sendaddr,subaddr,sizeof(ptr->sendaddr)); + safecopy(ptr->publicaddr,publicaddr,sizeof(ptr->publicaddr)); + ptr->lasttime = (uint32_t)time(NULL); + portable_mutex_unlock(&LP_psockmutex); +} + +int32_t LP_psockmark(char *publicaddr) +{ + int32_t i,retval = -1; struct psock *ptr; + portable_mutex_lock(&LP_psockmutex); + for (i=0; ipublicaddr) == 0 ) + { + printf("mark PSOCKS[%d] %s for deletion\n",i,publicaddr); + ptr->lasttime = 0; + retval = i; + break; + } + } + portable_mutex_unlock(&LP_psockmutex); + return(retval); +} + +char *_LP_psock_create(int32_t *pullsockp,int32_t *pubsockp,char *ipaddr,uint16_t publicport,uint16_t subport,int32_t ispaired,int32_t cmdchannel,bits256 pubkey) +{ + int32_t i,pullsock,bindflag=(IAMLP != 0),pubsock,arg; struct LP_pubkey_info *pubp; char pushaddr[128],subaddr[128]; cJSON *retjson = 0; + pullsock = pubsock = -1; + *pullsockp = *pubsockp = -1; + if ( cmdchannel != 0 && bits256_nonz(pubkey) == 0 ) + { + printf("ignore cmdchannel request without pubkey\n"); + return(clonestr("{\"error\":\"cmdchannel needs pubkey\"}")); + } + if ( IAMLP != 0 && bits256_nonz(pubkey) != 0 ) + { + if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) + { + if ( pubp->pairsock >= 0 ) + { + //printf("%s already has pairsock.%d\n",bits256_str(str,pubkey),pubp->pairsock); + portable_mutex_lock(&LP_psockmutex); + for (i=0; ipairsock ) + { + //PSOCKS[i].lasttime = (uint32_t)time(NULL) - PSOCK_KEEPALIVE - 1; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"LPipaddr",ipaddr); + jaddstr(retjson,"connectaddr",PSOCKS[i].sendaddr); + jaddnum(retjson,"connectport",PSOCKS[i].sendport); + jaddnum(retjson,"ispaired",PSOCKS[i].ispaired); + jaddnum(retjson,"cmdchannel",PSOCKS[i].cmdchannel); + jaddstr(retjson,"publicaddr",PSOCKS[i].publicaddr); + jaddnum(retjson,"publicport",PSOCKS[i].publicport); + //printf("cmd.%d publicaddr.(%s) for subaddr.(%s), pullsock.%d pubsock.%d\n",cmdchannel,pushaddr,subaddr,pullsock,pubsock); + *pullsockp = pullsock; + *pubsockp = pubsock; + portable_mutex_unlock(&LP_psockmutex); + return(jprint(retjson,1)); + } + portable_mutex_unlock(&LP_psockmutex); + } + //printf("pairsock for %s <- %d\n",bits256_str(str,pubkey),pullsock); + //pubp->pairsock = pullsock; + } + } + nanomsg_transportname(bindflag,pushaddr,ipaddr,publicport); + nanomsg_transportname(bindflag,subaddr,ipaddr,subport); + if ( (pullsock= nn_socket(AF_SP,ispaired!=0?NN_PAIR:NN_PULL)) >= 0 && (cmdchannel != 0 ||(pubsock= nn_socket(AF_SP,ispaired!=0?NN_PAIR:NN_PAIR)) >= 0) ) + { + if ( nn_bind(pullsock,pushaddr) >= 0 && (cmdchannel != 0 || nn_bind(pubsock,subaddr) >= 0) ) + { + arg = 100; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_SNDTIMEO,&arg,sizeof(arg)); + if ( pubsock >= 0 ) + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_SNDTIMEO,&arg,sizeof(arg)); + arg = 1; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&arg,sizeof(arg)); + if ( pubsock >= 0 ) + nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_RCVTIMEO,&arg,sizeof(arg)); + //arg = 2; + //nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_MAXTTL,&arg,sizeof(arg)); + //if ( pubsock >= 0 ) + // nn_setsockopt(pubsock,NN_SOL_SOCKET,NN_MAXTTL,&arg,sizeof(arg)); + nanomsg_transportname(0,pushaddr,ipaddr,publicport); + nanomsg_transportname(0,subaddr,ipaddr,subport); + LP_psockadd(ispaired,pullsock,publicport,pubsock,subport,subaddr,pushaddr,cmdchannel); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"LPipaddr",ipaddr); + jaddstr(retjson,"connectaddr",subaddr); + jaddnum(retjson,"connectport",subport); + jaddnum(retjson,"ispaired",ispaired); + jaddnum(retjson,"cmdchannel",cmdchannel); + jaddstr(retjson,"publicaddr",pushaddr); + jaddnum(retjson,"publicport",publicport); + if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) + pubp->pairsock = pullsock; + char str[65]; printf("PSOCK %s cmd.%d publicaddr.(%s) for subaddr.(%s), pullsock.%d pubsock.%d\n",bits256_str(str,pubkey),cmdchannel,pushaddr,subaddr,pullsock,pubsock); + *pullsockp = pullsock; + *pubsockp = pubsock; + return(jprint(retjson,1)); + } //else printf("bind error on %s or %s\n",pushaddr,subaddr); + if ( pullsock >= 0 ) + nn_close(pullsock); + if ( pubsock >= 0 ) + nn_close(pubsock); + } + return(0); +} + +char *LP_psock(int32_t *pullsockp,char *ipaddr,int32_t ispaired,int32_t cmdchannel,bits256 pubkey) +{ + char *retstr=0; uint16_t i,publicport,subport,maxport; int32_t pubsock=-1; + *pullsockp = -1; + //printf("LP_psock ipaddr.%s ispaird.%d cmdchannel.%d\n",ipaddr,ispaired,cmdchannel); + if ( cmdchannel == 0 ) + { + maxport = MAX_PSOCK_PORT; + publicport = Psockport++; + subport = Psockport++; + } + else + { + if ( cmdchannel != 0 && bits256_nonz(pubkey) == 0 ) + return(clonestr("{\"error\",\"cant do pairsock for null pubkey\"}")); + maxport = 65534; + publicport = subport = Pcmdport++; + } + for (i=0; i= MAX_PSOCK_PORT ) + Psockport = MIN_PSOCK_PORT; + if ( Pcmdport >= 65534 ) + Pcmdport = MAX_PSOCK_PORT; + return(clonestr("{\"error\",\"cant find psock ports\"}")); +} + +/* + LP_pushaddr_get makes transparent the fact that most nodes cannot bind()! + + The idea is to create an LP node NN_PAIR sock that the LP node binds to and client node connects to. Additionally, the LP node creates an NN_PULL that other nodes can NN_PUSH to and returns this address in pushaddr/retval for the client node to register with. The desired result is that other than the initial LP node, all the other nodes do a normal NN_PUSH, requiring no change to the NN_PUSH/NN_PULL logic. Of course, the initial LP node needs to autoforward all packets from the public NN_PULL to the NN_PUB + + similar to LP_pushaddr_get, create an NN_PAIR for DEX atomic data, can be assumed to have a max lifetime of 2*INSTANTDEX_LOCKTIME + + both are combined in LP_psock_get + +*/ + +char *issue_LP_psock(char *destip,uint16_t destport,int32_t ispaired,int32_t cmdchannel) +{ + char str[65],url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/psock?ispaired=%d&cmdchannel=%d&pubkey=%s",destip,destport-1,ispaired,cmdchannel,bits256_str(str,G.LP_mypub25519)); + //return(LP_issue_curl("psock",destip,destport,url)); + retstr = issue_curlt(url,LP_HTTP_TIMEOUT*10); + printf("issue_LP_psock got (%s) from %s\n",retstr,url); // this is needed?! + return(retstr); +} + +uint16_t LP_psock_get(char *connectaddr,char *publicaddr,int32_t ispaired,int32_t cmdchannel,char *ipaddr) +{ + uint16_t publicport = 0; char *retstr,*addr; cJSON *retjson; struct LP_peerinfo *peer,*tmp; + connectaddr[0] = publicaddr[0] = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( ipaddr != 0 && strcmp(ipaddr,peer->ipaddr) != 0 ) + continue; + connectaddr[0] = publicaddr[0] = 0; + if ( peer->errors < LP_MAXPEER_ERRORS && (retstr= issue_LP_psock(peer->ipaddr,peer->port,ispaired,cmdchannel)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("from %s:%u (%s)\n",peer->ipaddr,peer->port,retstr); + if ( (addr= jstr(retjson,"publicaddr")) != 0 ) + safecopy(publicaddr,addr,128); + if ( (addr= jstr(retjson,"connectaddr")) != 0 ) + safecopy(connectaddr,addr,128); + if ( publicaddr[0] != 0 && connectaddr[0] != 0 ) + publicport = juint(retjson,"publicport"); + free_json(retjson); + } + //printf("got.(%s) connect.%s public.%s publicport.%u\n",retstr,connectaddr,publicaddr,publicport); + free(retstr); + return(publicport); + } //else printf("error psock from %s:%u\n",peer->ipaddr,peer->port); + } + return(0); +} + +int32_t LP_initpublicaddr(void *ctx,uint16_t *mypullportp,char *publicaddr,char *myipaddr,uint16_t mypullport,int32_t ispaired) +{ + int32_t nntype,pullsock,timeout; char bindaddr[128],connectaddr[128]; + *mypullportp = mypullport; + if ( ispaired == 0 ) + { + if ( LP_canbind != 0 ) + nntype = LP_COMMAND_RECVSOCK; + else nntype = NN_PAIR;//NN_SUB; + } else nntype = NN_PAIR; + if ( LP_canbind != 0 ) + { + nanomsg_transportname(0,publicaddr,myipaddr,mypullport); + nanomsg_transportname(1,bindaddr,myipaddr,mypullport); + } + else + { + *mypullportp = 0; + if ( ispaired == 0 ) + { + sprintf(publicaddr,"127.0.0.1:%u",mypullport); + return(-1); + } + while ( *mypullportp == 0 ) + { + if ( (*mypullportp= LP_psock_get(connectaddr,publicaddr,ispaired,0,0)) != 0 ) + break; + sleep(10); + printf("try to get publicaddr again\n"); + } + } + while ( 1 ) + { + if ( (pullsock= nn_socket(AF_SP,nntype)) >= 0 ) + { + if ( LP_canbind == 0 ) + { + if ( nn_connect(pullsock,connectaddr) < 0 ) + { + printf("bind to %s error for %s: %s\n",connectaddr,publicaddr,nn_strerror(nn_errno())); + exit(-1); + } + else + { + printf("nntype.%d NN_PAIR.%d connect to %s connectsock.%d\n",nntype,NN_PAIR,connectaddr,pullsock); + } + } + else + { + if ( nn_bind(pullsock,bindaddr) < 0 ) + { + printf("bind to %s error for %s: %s\n",bindaddr,publicaddr,nn_strerror(nn_errno())); + exit(-1); + } + } + timeout = 100; + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(pullsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + if ( nntype == NN_SUB ) + nn_setsockopt(pullsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + } + //if ( LP_canbind != 0 || ispaired != 0 || nn_tests(ctx,pullsock,publicaddr,NN_PUSH) >= 0 ) + // break; + //printf("nn_tests failed, try again\n"); + //sleep(3); + break; + if ( pullsock >= 0 ) + nn_close(pullsock); + } + return(pullsock); +} diff --git a/iguana/exchanges/LP_ordermatch.c b/iguana/exchanges/LP_ordermatch.c new file mode 100644 index 000000000..f858c7e3b --- /dev/null +++ b/iguana/exchanges/LP_ordermatch.c @@ -0,0 +1,1394 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// +// LP_ordermatch.c +// marketmaker +// +struct LP_quoteinfo LP_Alicequery,LP_Alicereserved; +double LP_Alicemaxprice; +bits256 LP_Alicedestpubkey,LP_bobs_reserved; +uint32_t Alice_expiration,Bob_expiration; +struct { uint64_t aliceid; double bestprice; uint32_t starttime,counter; } Bob_competition[512]; + +double LP_bob_competition(int32_t *counterp,uint64_t aliceid,double price,int32_t counter) +{ + int32_t i,firsti = -1; uint32_t now = (uint32_t)time(NULL); + *counterp = 0; + for (i=0; i Bob_competition[i].starttime+LP_AUTOTRADE_TIMEOUT ) + { + //printf("aliceid.%llu expired\n",(long long)aliceid); + Bob_competition[i].bestprice = 0.; + Bob_competition[i].starttime = now; + Bob_competition[i].counter = 0; + } + if ( price != 0. && (Bob_competition[i].bestprice == 0. || price < Bob_competition[i].bestprice) ) + { + Bob_competition[i].bestprice = price; + //printf("Bob competition aliceid.%llu <- bestprice %.8f\n",(long long)aliceid,price); + } + Bob_competition[i].counter += counter; + *counterp = Bob_competition[i].counter; + return(Bob_competition[i].bestprice); + } + else if ( Bob_competition[i].aliceid == 0 ) + firsti = i; + } + if ( firsti < 0 ) + firsti = (LP_rand() % (sizeof(Bob_competition)/sizeof(*Bob_competition))); + Bob_competition[firsti].starttime = (uint32_t)time(NULL); + Bob_competition[firsti].counter = counter; + Bob_competition[firsti].aliceid = aliceid; + Bob_competition[firsti].bestprice = price; + *counterp = counter; + //printf("Bob competition aliceid.%llu %.8f\n",(long long)aliceid,price); + return(price); +} + +uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee,int32_t txlen) +{ + if ( coin != 0 ) + { + if ( strcmp(coin->symbol,"BTC") == 0 ) + { + if ( txlen == 0 ) + txlen = LP_AVETXSIZE; + coin->rate = LP_getestimatedrate(coin); + if ( (txfee= SATOSHIDEN * coin->rate * txlen) <= LP_MIN_TXFEE ) + { + coin->rate = -1.; + coin->rate = _LP_getestimatedrate(coin); + if ( (txfee= SATOSHIDEN * coin->rate * txlen) <= LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + } + } else txfee = coin->txfee; + if ( txfee < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + } + return(txfee); +} + +int32_t LP_quote_checkmempool(struct LP_quoteinfo *qp,struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo) +{ + int32_t selector,spendvini; bits256 spendtxid; + if ( butxo != 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,qp->srccoin,qp->coinaddr,qp->txid,qp->vout,qp->txid2,qp->vout2)) >= 0 ) + { + char str[65]; printf("LP_tradecommand selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); + return(-1); + } + if ( autxo != 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout,qp->feetxid,qp->feevout)) >= 0 ) + { + char str[65]; printf("LP_tradecommand dest selector.%d in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); + return(-1); + } + return(0); +} + +double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp,int32_t iambob) +{ + double qprice=0.; char str[65]; cJSON *txout; uint64_t txfee,desttxfee,srcvalue=0,srcvalue2=0,destvalue=0,destvalue2=0; + //printf(">>>>>>> quote satoshis.(%.8f %.8f) %s %.8f -> %s %.8f\n",dstr(qp->satoshis),dstr(qp->destsatoshis),qp->srccoin,dstr(qp->satoshis),qp->destcoin,dstr(qp->destsatoshis)); + if ( butxo != 0 ) + { + if ( LP_iseligible(&srcvalue,&srcvalue2,1,qp->srccoin,qp->txid,qp->vout,qp->satoshis,qp->txid2,qp->vout2) == 0 ) + { + //printf("bob not eligible %s (%.8f %.8f)\n",jprint(LP_quotejson(qp),1),dstr(srcvalue),dstr(srcvalue2)); + return(-2); + } + if ( (txout= LP_gettxout(qp->srccoin,qp->coinaddr,qp->txid,qp->vout)) != 0 ) + free_json(txout); + else + { + printf("%s %s payment %s/v%d is spent\n",qp->srccoin,qp->coinaddr,bits256_str(str,qp->txid),qp->vout); + return(-21); + } + if ( (txout= LP_gettxout(qp->srccoin,qp->coinaddr,qp->txid2,qp->vout2)) != 0 ) + free_json(txout); + else + { + printf("%s %s deposit %s/v%d is spent\n",qp->srccoin,qp->coinaddr,bits256_str(str,qp->txid2),qp->vout2); + return(-22); + } + if ( bits256_cmp(butxo->deposit.txid,qp->txid2) != 0 || butxo->deposit.vout != qp->vout2 ) + { + char str[65],str2[65]; printf("%s != %s v%d != %d\n",bits256_str(str,butxo->deposit.txid),bits256_str(str2,qp->txid2),butxo->deposit.vout,qp->vout2); + return(-6); + } + if ( strcmp(butxo->coinaddr,qp->coinaddr) != 0 ) + { + printf("(%s) != (%s)\n",butxo->coinaddr,qp->coinaddr); + return(-7); + } + } + if ( autxo != 0 ) + { + if ( LP_iseligible(&destvalue,&destvalue2,0,qp->destcoin,qp->desttxid,qp->destvout,qp->destsatoshis,qp->feetxid,qp->feevout) == 0 ) + { + //alice not eligible 0.36893923 -> dest 0.55020000 1.49130251 (0.61732249 0.00104324) 14b8b74808d2d34a70e5eddd1cad47d855858f8b23cac802576d4d37b5f8af8f/v1 abec6e76169bcb738235ca67fab02cc55390f39e422aa71f1badf8747c290cc4/v1 + //char str[65],str2[65]; printf("alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d\n",dstr(qp->satoshis),dstr(qp->destsatoshis),(double)qp->destsatoshis/qp->satoshis,dstr(destvalue),dstr(destvalue2),bits256_str(str,qp->desttxid),qp->destvout,bits256_str(str2,qp->feetxid),qp->feevout); + return(-3); + } + if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout)) != 0 ) + free_json(txout); + else + { + printf("%s %s Apayment %s/v%d is spent\n",qp->destcoin,qp->destaddr,bits256_str(str,qp->desttxid),qp->destvout); + return(-23); + } + if ( (txout= LP_gettxout(qp->destcoin,qp->destaddr,qp->feetxid,qp->feevout)) != 0 ) + free_json(txout); + else + { + printf("%s %s dexfee %s/v%d is spent\n",qp->destcoin,qp->destaddr,bits256_str(str,qp->feetxid),qp->feevout); + return(-24); + } + } + //printf("checked autxo and butxo\n"); + if ( LP_quote_checkmempool(qp,autxo,butxo) < 0 ) + return(-4); + if ( iambob == 0 && autxo != 0 ) + { + if ( bits256_cmp(autxo->fee.txid,qp->feetxid) != 0 || autxo->fee.vout != qp->feevout ) + return(-9); + if ( strcmp(autxo->coinaddr,qp->destaddr) != 0 ) + return(-10); + } + if ( autxo != 0 && destvalue < qp->desttxfee+qp->destsatoshis ) + { + printf("destvalue %.8f destsatoshis %.8f is too small txfee %.8f?\n",dstr(destvalue),dstr(qp->destsatoshis),dstr(qp->desttxfee)); + return(-11); + } + if ( butxo != 0 && srcvalue < qp->txfee+qp->satoshis ) + { + printf("srcvalue %.8f [%.8f] satoshis %.8f is too small txfee %.8f?\n",dstr(srcvalue),dstr(srcvalue) - dstr(qp->txfee+qp->satoshis),dstr(qp->satoshis),dstr(qp->txfee)); + return(-33); + } + if ( qp->satoshis != 0 ) + qprice = ((double)qp->destsatoshis / (qp->satoshis-qp->txfee)); + LP_txfees(&txfee,&desttxfee,qp->srccoin,qp->destcoin); + if ( txfee < qp->txfee ) + txfee = qp->txfee; + if ( desttxfee < qp->desttxfee ) + desttxfee = qp->desttxfee; + //printf("qprice %.8f <- %.8f/%.8f txfees.(%.8f %.8f) vs (%.8f %.8f)\n",qprice,dstr(qp->destsatoshis),dstr(qp->satoshis),dstr(qp->txfee),dstr(qp->desttxfee),dstr(txfee),dstr(desttxfee)); + if ( qp->txfee < LP_REQUIRED_TXFEE*txfee || qp->desttxfee < LP_REQUIRED_TXFEE*desttxfee ) + return(-14); + if ( butxo != 0 ) + { + if ( qp->satoshis < (srcvalue / LP_MINVOL) || srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT ) + { + printf("utxo payment %.8f is less than %f covered by Q %.8f or <10x txfee %.8f [%d %d]\n",dstr(srcvalue),1./LP_MINVOL,dstr(qp->satoshis),dstr(qp->txfee),qp->satoshis < (srcvalue / LP_MINVOL),srcvalue < qp->txfee*LP_MINSIZE_TXFEEMULT); + return(-12); + } + } + if ( autxo != 0 ) + { + if ( qp->destsatoshis < (destvalue / LP_MINCLIENTVOL) || destvalue < qp->desttxfee*LP_MINSIZE_TXFEEMULT ) + { + printf("destsatoshis %.8f is less than %f of value %.8f or < 10x txfee %.8f\n",dstr(qp->destsatoshis),1./LP_MINCLIENTVOL,dstr(destvalue),dstr(qp->desttxfee)); + return(-13); + } + } + return(qprice); +} + +int32_t LP_arrayfind(cJSON *array,bits256 txid,int32_t vout) +{ + int32_t i,n = cJSON_GetArraySize(array); cJSON *item; + for (i=0; ipair\n"); + else + { + for (i=0; i<10000; i++) + { + r = (10000 + (LP_rand() % 50000)) & 0xffff; + if ( LP_fixed_pairport != 0 ) + r = LP_fixed_pairport; + nanomsg_transportname(0,pairstr,LP_myipaddr,r); + nanomsg_transportname(1,bindaddr,LP_myipaddr,r); + if ( nn_bind(pairsock,bindaddr) >= 0 ) + { + //timeout = 1; + //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + //printf("nanobind %s to %d\n",pairstr,pairsock); + return(pairsock); + } // else printf("error binding to %s for %s\n",bindaddr,pairstr); + if ( LP_fixed_pairport != 0 ) + break; + } + printf("%d ports all used\n",i); + nn_close(pairsock); + pairsock = -1; + } + } else pairsock = LP_initpublicaddr(ctx,&mypullport,pairstr,"127.0.0.1",0,1); + return(pairsock); +} + +int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_address_utxo **utxos,int32_t n,uint64_t targetval) +{ + int32_t i,replacei,bestheight,mini = -1; struct LP_address_utxo *up,*bestup; struct electrum_info *backupep=0,*ep; int64_t dist,bestdist; uint64_t mindist = (1LL << 60); + if ( (ep= coin->electrum) != 0 ) + { + if ( (backupep= ep->prev) == 0 ) + backupep = ep; + } + //printf("LP_nearest_utxovalue %s %s utxos[%d] target %.8f\n",coin->symbol,coinaddr,n,dstr(targetval)); + for (i=0; iU.value - targetval); + //printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight); + if ( up->spendheight <= 0 ) + { + if ( dist >= 0 && dist < mindist ) + { + //printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini); + mini = i; + mindist = dist; + } + } + } + } + if ( mini >= 0 && (bestup= utxos[mini]) != 0 ) + { + bestdist = (bestup->U.value - targetval); + replacei = -1; + bestheight = bestup->U.height; + for (i=0; iU.value - targetval); + if ( dist > 0 && up->U.height < bestheight ) + { + if ( (double)dist/bestdist < sqrt(((double)bestheight - up->U.height)/1000) ) + { + replacei = i; + bestheight = up->U.height; + } //else printf("almost ratio %.3f dist %.8f vs best %.8f, ht %d vs best ht %d\n",(double)dist/bestdist,dstr(dist),dstr(bestdist),up->U.height,bestheight); + } + } + } + if ( replacei >= 0 ) + { + printf("REPLACE bestdist %.8f height %d with dist %.8f height %d\n",dstr(bestdist),bestup->U.height,dstr(utxos[replacei]->U.value - targetval),utxos[replacei]->U.height); + return(replacei); + } + } + //printf("return mini.%d\n",mini); + return(mini); +} + +void LP_butxo_set(struct LP_utxoinfo *butxo,int32_t iambob,struct iguana_info *coin,struct LP_address_utxo *up,struct LP_address_utxo *up2,int64_t satoshis) +{ + butxo->pubkey = G.LP_mypub25519; + safecopy(butxo->coin,coin->symbol,sizeof(butxo->coin)); + safecopy(butxo->coinaddr,coin->smartaddr,sizeof(butxo->coinaddr)); + butxo->payment.txid = up->U.txid; + butxo->payment.vout = up->U.vout; + butxo->payment.value = up->U.value; + if ( (butxo->iambob= iambob) != 0 ) + { + butxo->deposit.txid = up2->U.txid; + butxo->deposit.vout = up2->U.vout; + butxo->deposit.value = up2->U.value; + } + else + { + butxo->fee.txid = up2->U.txid; + butxo->fee.vout = up2->U.vout; + butxo->fee.value = up2->U.value; + } + butxo->swap_satoshis = satoshis; +} + +void LP_abutxo_set(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,struct LP_quoteinfo *qp) +{ + if ( butxo != 0 ) + { + memset(butxo,0,sizeof(*butxo)); + butxo->pubkey = qp->srchash; + safecopy(butxo->coin,qp->srccoin,sizeof(butxo->coin)); + safecopy(butxo->coinaddr,qp->coinaddr,sizeof(butxo->coinaddr)); + butxo->payment.txid = qp->txid; + butxo->payment.vout = qp->vout; + //butxo->payment.value = qp->value; + butxo->iambob = 1; + butxo->deposit.txid = qp->txid2; + butxo->deposit.vout = qp->vout2; + //butxo->deposit.value = up2->U.value; + butxo->swap_satoshis = qp->satoshis; + } + if ( autxo != 0 ) + { + memset(autxo,0,sizeof(*autxo)); + autxo->pubkey = qp->desthash; + safecopy(autxo->coin,qp->destcoin,sizeof(autxo->coin)); + safecopy(autxo->coinaddr,qp->destaddr,sizeof(autxo->coinaddr)); + autxo->payment.txid = qp->desttxid; + autxo->payment.vout = qp->destvout; + //autxo->payment.value = qp->value; + autxo->iambob = 0; + autxo->fee.txid = qp->feetxid; + autxo->fee.vout = qp->feevout; + //autxo->deposit.value = up2->U.value; + autxo->swap_satoshis = qp->destsatoshis; + } +} + +uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t desttxfee) +{ + //printf("basesatoshis %.8f (rel %.8f / price %.8f)\n",dstr(SATOSHIDEN * ((relvolume) / price) + 2*txfee),relvolume,price); + if ( relvolume > dstr(desttxfee) && price > SMALLVAL ) + return(SATOSHIDEN * (relvolume / price) + 2*txfee); + else return(0); +} + +struct LP_utxoinfo *LP_address_myutxopair(struct LP_utxoinfo *butxo,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct iguana_info *coin,char *coinaddr,uint64_t txfee,double relvolume,double price,uint64_t desttxfee) +{ + struct LP_address *ap; uint64_t fee,targetval,targetval2; int32_t m,mini; struct LP_address_utxo *up,*up2; double ratio; + memset(butxo,0,sizeof(*butxo)); + if ( iambob != 0 ) + { + targetval = LP_basesatoshis(relvolume,price,txfee,desttxfee) + 3*txfee; + targetval2 = (targetval / 8) * 9 + 3*txfee; + fee = txfee; + ratio = LP_MINVOL; + } + else + { + targetval = relvolume*SATOSHIDEN + 3*desttxfee; + targetval2 = (targetval / 777) + 3*desttxfee; + fee = desttxfee; + ratio = LP_MINCLIENTVOL; + } + if ( coin != 0 && (ap= LP_address(coin,coinaddr)) != 0 ) + { + if ( (m= LP_address_utxo_ptrs(coin,iambob,utxos,max,ap,coinaddr)) > 1 ) + { + if ( 0 ) + { + int32_t i; + for (i=0; iU.value >= targetval ) + printf("%.8f ",dstr(utxos[i]->U.value)); + printf("targetval %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval),relvolume,price,dstr(fee),coin->symbol,coinaddr); + } + while ( 1 ) + { + mini = -1; + if ( targetval != 0 && (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,targetval+fee)) >= 0 ) + { + up = utxos[mini]; + utxos[mini] = 0; + //printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval); + if ( (double)up->U.value/targetval < ratio-1 ) + + { + if ( 0 ) + { + int32_t i; + for (i=0; iU.value >= targetval2 ) + printf("%.8f ",dstr(utxos[i]->U.value)); + printf("targetval2 %.8f vol %.8f price %.8f txfee %.8f %s %s\n",dstr(targetval2),relvolume,price,dstr(fee),coin->symbol,coinaddr); + } + if ( (mini= LP_nearest_utxovalue(coin,coinaddr,utxos,m,(targetval2+2*fee) * 1.01)) >= 0 ) + { + if ( up != 0 && (up2= utxos[mini]) != 0 ) + { + LP_butxo_set(butxo,iambob,coin,up,up2,targetval); + return(butxo); + } else printf("cant find utxos[mini %d]\n",mini); + } //else printf("cant find targetval2 %.8f\n",dstr(targetval2)); + } else printf("failed ratio test %.8f\n",(double)up->U.value/targetval); + } else if ( targetval != 0 && mini >= 0 ) + printf("targetval %.8f mini.%d\n",dstr(targetval),mini); + if ( targetval == 0 || mini < 0 ) + break; + } + } else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr); + } else printf("address_myutxopair couldnt find %s %s\n",coin->symbol,coinaddr); + return(0); +} + +int32_t LP_connectstartbob(void *ctx,int32_t pubsock,char *base,char *rel,double price,struct LP_quoteinfo *qp) +{ + char pairstr[512],otheraddr[64]; cJSON *reqjson; bits256 privkey; int32_t pair=-1,retval = -1,DEXselector = 0; int64_t dtrust; struct basilisk_swap *swap; struct iguana_info *coin,*kmdcoin; + qp->quotetime = (uint32_t)time(NULL); + if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) + { + printf("cant find coin.%s\n",qp->srccoin); + return(-1); + } + privkey = LP_privkey(coin->symbol,coin->smartaddr,coin->taddr); + if ( bits256_nonz(privkey) != 0 && bits256_cmp(G.LP_mypub25519,qp->srchash) == 0 ) + { + LP_requestinit(&qp->R,qp->srchash,qp->desthash,base,qp->satoshis-qp->txfee,rel,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); + /*if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 ) + { + printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); + return(-1); + }*/ + dtrust = LP_dynamictrust(qp->othercredits,qp->desthash,LP_kmdvalue(qp->destcoin,qp->destsatoshis)); + if ( (swap= LP_swapinit(1,0,privkey,&qp->R,qp,dtrust > 0)) == 0 ) + { + printf("cant initialize swap\n"); + return(-1); + } + if ( (pair= LP_nanobind(ctx,pairstr)) >= 0 ) + { + swap->N.pair = pair; + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_bobloop,(void *)swap) == 0 ) + { + reqjson = LP_quotejson(qp); + jaddstr(reqjson,"method","connected"); + jaddstr(reqjson,"pair",pairstr); + if ( (kmdcoin= LP_coinfind("KMD")) != 0 ) + jadd(reqjson,"proof",LP_instantdex_txids(0,kmdcoin->smartaddr)); + //char str[65]; printf("BOB pubsock.%d binds to %d (%s)\n",pubsock,pair,bits256_str(str,qp->desthash)); + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); + if ( 0 ) + { + LP_reserved_msg(1,base,rel,zero,jprint(reqjson,0)); + LP_reserved_msg(0,base,rel,zero,jprint(reqjson,0)); + } + free_json(reqjson); + LP_importaddress(qp->destcoin,qp->destaddr); + LP_otheraddress(qp->srccoin,otheraddr,qp->destcoin,qp->destaddr); + LP_importaddress(qp->srccoin,otheraddr); + retval = 0; + } else printf("error launching swaploop\n"); + } else printf("couldnt bind to any port %s\n",pairstr); + } + if ( retval < 0 ) + { + if ( pair >= 0 ) + nn_close(pair); + LP_availableset(qp->txid,qp->vout); + LP_availableset(qp->txid2,qp->vout2); + } + return(retval); +} + +char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp,double maxprice,int32_t timeout,int32_t duration,uint32_t tradeid,bits256 destpubkey) +{ + double price; + price = 0.; + memset(qp->txid.bytes,0,sizeof(qp->txid)); + qp->txid2 = qp->txid; + qp->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); + if ( (qp->tradeid= tradeid) == 0 ) + qp->tradeid = LP_rand(); + qp->srchash = destpubkey; + LP_query(ctx,myipaddr,mypubsock,"request",qp); + LP_Alicequery = *qp, LP_Alicemaxprice = maxprice, Alice_expiration = qp->timestamp + timeout, LP_Alicedestpubkey = destpubkey; + char str[65]; printf("LP_trade %s/%s %.8f vol %.8f dest.(%s) maxprice %.8f\n",qp->srccoin,qp->destcoin,dstr(qp->satoshis),dstr(qp->destsatoshis),bits256_str(str,LP_Alicedestpubkey),maxprice); + return(LP_recent_swaps(0)); +} + +int32_t LP_quotecmp(int32_t strictflag,struct LP_quoteinfo *qp,struct LP_quoteinfo *qp2) +{ + if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) + { + if (bits256_cmp(LP_Alicedestpubkey,qp->srchash) != 0 ) + { + printf("reject quote from non-matching pubkey\n"); + return(-1); + } else printf("dont reject quote from destpubkey\n"); + } + if ( bits256_cmp(qp->desthash,qp2->desthash) == 0 && strcmp(qp->srccoin,qp2->srccoin) == 0 && strcmp(qp->destcoin,qp2->destcoin) == 0 && bits256_cmp(qp->desttxid,qp2->desttxid) == 0 && qp->destvout == qp2->destvout && bits256_cmp(qp->feetxid,qp2->feetxid) == 0 && qp->feevout == qp2->feevout && qp->destsatoshis == qp2->destsatoshis && qp->txfee >= qp2->txfee && qp->desttxfee == qp2->desttxfee ) + { + if ( strictflag == 0 || (qp->aliceid == qp2->aliceid && qp->R.requestid == qp2->R.requestid && qp->R.quoteid == qp2->R.quoteid && qp->vout == qp2->vout && qp->vout2 == qp2->vout2 && qp->satoshis == qp2->satoshis && bits256_cmp(qp->txid,qp2->txid) == 0 && bits256_cmp(qp->txid2,qp2->txid2) == 0 && bits256_cmp(qp->srchash,qp2->srchash) == 0) ) + return(0); + else printf("strict compare failure\n"); + } + return(-1); +} + +void LP_alicequery_clear() +{ + memset(&LP_Alicequery,0,sizeof(LP_Alicequery)); + memset(&LP_Alicedestpubkey,0,sizeof(LP_Alicedestpubkey)); + LP_Alicemaxprice = 0.; + Alice_expiration = 0; +} + +int32_t LP_alice_eligible(uint32_t quotetime) +{ + if ( Alice_expiration != 0 && quotetime > Alice_expiration ) + { + printf("time expired for Alice_request\n"); + LP_alicequery_clear(); + } + return(Alice_expiration == 0 || time(NULL) < Alice_expiration); +} + +char *LP_connectedalice(struct LP_quoteinfo *qp,char *pairstr) // alice +{ + cJSON *retjson; char otheraddr[64]; double bid,ask,price,qprice; int32_t pairsock = -1; int32_t DEXselector = 0; struct LP_utxoinfo *autxo,A,B,*butxo; struct basilisk_swap *swap; struct iguana_info *coin; + /*if ( LP_quoteparse(&Q,argjson) < 0 ) + { + LP_aliceid(Q.tradeid,Q.aliceid,"error0",0,0); + clonestr("{\"error\":\"cant parse quote\"}"); + }*/ + if ( bits256_cmp(qp->desthash,G.LP_mypub25519) != 0 ) + { + LP_aliceid(qp->tradeid,qp->aliceid,"error1",0,0); + return(clonestr("{\"result\",\"update stats\"}")); + } + printf("CONNECTED numpending.%d tradeid.%u requestid.%u quoteid.%u pairstr.%s\n",G.LP_pendingswaps,qp->tradeid,qp->R.requestid,qp->R.quoteid,pairstr!=0?pairstr:""); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-qp->txfee,qp->destcoin,qp->destsatoshis-qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); + //printf("calculated requestid.%u quoteid.%u\n",qp->R.requestid,qp->R.quoteid); + /*if ( LP_pendingswap(qp->R.requestid,qp->R.quoteid) > 0 ) + { + printf("requestid.%u quoteid.%u is already in progres\n",qp->R.requestid,qp->R.quoteid); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","swap already in progress"); + return(jprint(retjson,1)); + }*/ + /*if ( LP_quotecmp(1,qp,&LP_Alicereserved) == 0 ) + { + printf("mismatched between reserved and connected\n"); + }*/ + memset(&LP_Alicereserved,0,sizeof(LP_Alicereserved)); + LP_aliceid(qp->tradeid,qp->aliceid,"connected",qp->R.requestid,qp->R.quoteid); + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,qp); + if ( (qprice= LP_quote_validate(autxo,butxo,qp,0)) <= SMALLVAL ) + { + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + LP_aliceid(qp->tradeid,qp->aliceid,"error4",0,0); + printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice); + return(clonestr("{\"error\":\"quote validation error\"}")); + } + if ( LP_myprice(&bid,&ask,qp->srccoin,qp->destcoin) <= SMALLVAL || bid <= SMALLVAL ) + { + printf("this node has no price for %s/%s (%.8f %.8f)\n",qp->destcoin,qp->srccoin,bid,ask); + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + LP_aliceid(qp->tradeid,qp->aliceid,"error5",0,0); + return(clonestr("{\"error\":\"no price set\"}")); + } + //LP_RTmetrics_update(qp->srccoin,qp->destcoin); + printf("%s/%s bid %.8f ask %.8f values %.8f %.8f\n",qp->srccoin,qp->destcoin,bid,ask,dstr(butxo->payment.value),dstr(butxo->deposit.value)); + price = bid; + if ( (coin= LP_coinfind(qp->destcoin)) == 0 ) + { + LP_aliceid(qp->tradeid,qp->aliceid,"error6",0,0); + return(clonestr("{\"error\":\"cant get alicecoin\"}")); + } + qp->privkey = LP_privkey(coin->symbol,qp->destaddr,coin->taddr); + if ( bits256_nonz(qp->privkey) != 0 )//&& qp->quotetime >= qp->timestamp-3 ) + { + retjson = cJSON_CreateObject(); + if ( (swap= LP_swapinit(0,0,qp->privkey,&qp->R,qp,LP_dynamictrust(qp->othercredits,qp->srchash,LP_kmdvalue(qp->srccoin,qp->satoshis)) > 0)) == 0 ) + { + jaddstr(retjson,"error","couldnt swapinit"); + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + LP_aliceid(qp->tradeid,qp->aliceid,"error7",qp->R.requestid,qp->R.quoteid); + return(jprint(retjson,1)); + } + if ( pairstr == 0 || pairstr[0] == 0 || (pairsock= nn_socket(AF_SP,NN_PAIR)) < 0 ) + { + LP_aliceid(qp->tradeid,qp->aliceid,"error8",qp->R.requestid,qp->R.quoteid); + jaddstr(retjson,"error","couldnt create pairsock"); + } + else if ( nn_connect(pairsock,pairstr) >= 0 ) + { + //timeout = 1; + //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + //nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + swap->tradeid = qp->tradeid; + swap->N.pair = pairsock; + //autxo->S.swap = swap; + //swap->utxo = autxo; + LP_importaddress(qp->srccoin,qp->coinaddr); + LP_otheraddress(qp->destcoin,otheraddr,qp->srccoin,qp->coinaddr); + LP_importaddress(qp->srccoin,otheraddr); + LP_aliceid(qp->tradeid,qp->aliceid,"started",qp->R.requestid,qp->R.quoteid); + printf("alice pairstr.(%s) pairsock.%d pthread_t %ld\n",pairstr,pairsock,sizeof(pthread_t)); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_aliceloop,(void *)swap) == 0 ) + { + retjson = LP_quotejson(qp); + jaddstr(retjson,"result","success"); + //jaddnum(retjson,"requestid",qp->R.requestid); + //jaddnum(retjson,"quoteid",qp->R.quoteid); + } + else + { + LP_aliceid(qp->tradeid,qp->aliceid,"error9",qp->R.requestid,qp->R.quoteid); + jaddstr(retjson,"error","couldnt aliceloop"); + } + } + else + { + LP_aliceid(qp->tradeid,qp->aliceid,"error10",qp->R.requestid,qp->R.quoteid); + printf("connect error %s\n",nn_strerror(nn_errno())); + } + //printf("connected result.(%s)\n",jprint(retjson,0)); + if ( jobj(retjson,"error") != 0 ) + { + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + } + return(jprint(retjson,1)); + } + else + { + LP_availableset(qp->desttxid,qp->vout); + LP_availableset(qp->feetxid,qp->feevout); + LP_aliceid(qp->tradeid,qp->aliceid,"error11",0,0); + printf("no privkey found coin.%s %s taddr.%u\n",qp->destcoin,qp->destaddr,coin->taddr); + return(clonestr("{\"error\",\"no privkey\"}")); + } +} + +int32_t LP_aliceonly(char *symbol) +{ + if ( strcmp(symbol,"GAME") == 0 ) + return(1); + else return(0); +} + +int32_t LP_validSPV(char *symbol,char *coinaddr,bits256 txid,int32_t vout) +{ + struct electrum_info *ep,*backupep; cJSON *txobj; struct LP_address_utxo *up; struct iguana_info *coin; int32_t height; struct LP_transaction *tx; + coin = LP_coinfind(symbol); + if ( coin != 0 && (ep= coin->electrum) != 0 ) + { + if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) == 0 ) + { + if ( (txobj= electrum_transaction(&height,symbol,ep,&txobj,txid,coinaddr)) != 0 ) + free_json(txobj); + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + { + if ( vout < tx->numvouts && tx->height > 0 ) + { + printf("added missing utxo for SPV checking\n"); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_validSPV",coin,coinaddr,txid,vout,tx->outpoints[vout].value,tx->height,-1); + } + } + } + if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) + { + if ( up->SPV > 0 ) + return(0); + if ( up->SPV < 0 ) + return(-1); + if ( (backupep= ep->prev) == 0 ) + backupep = ep; + up->SPV = LP_merkleproof(coin,coinaddr,backupep,up->U.txid,up->U.height); + if ( up->SPV < 0 ) + return(-1); + } + } + return(0); +} + +double LP_trades_alicevalidate(void *ctx,struct LP_quoteinfo *qp) +{ + double qprice; struct LP_utxoinfo A,B,*autxo,*butxo; char str[65]; + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,qp); + if ( (qprice= LP_quote_validate(autxo,butxo,qp,0)) <= SMALLVAL ) + { + printf("reserved quote validate error %.0f\n",qprice); + return((int32_t)qprice); + } + if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid,qp->vout) < 0 ) + { + sleep(1); + if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid,qp->vout) < 0 ) + { + printf("LP_trades_alicevalidate %s src %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid)); + return(-44); + } + } + else if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid2,qp->vout2) < 0 ) + { + sleep(1); + if ( LP_validSPV(qp->srccoin,qp->coinaddr,qp->txid2,qp->vout2) < 0 ) + { + printf("LP_trades_alicevalidate %s src2 %s failed SPV check\n",qp->srccoin,bits256_str(str,qp->txid2)); + return(-55); + } + } + return(qprice); +} + +void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *qp) +{ + double price=0.,maxprice = LP_Alicemaxprice; + //if ( LP_quotecmp(0,qp,&LP_Alicequery) == 0 ) + { + price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout); + if ( LP_pricevalid(price) > 0 && maxprice > SMALLVAL && price <= maxprice ) + { + qp->tradeid = LP_Alicequery.tradeid; + LP_Alicereserved = *qp; + LP_alicequery_clear(); + //printf("send CONNECT\n"); + LP_query(ctx,myipaddr,mypubsock,"connect",qp); + } else printf("LP_reserved %llu price %.8f vs maxprice %.8f\n",(long long)qp->aliceid,price,maxprice); + } //else printf("probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n",LP_alice_eligible(qp->quotetime),price,maxprice); +} + +double LP_trades_bobprice(double *bidp,double *askp,struct LP_quoteinfo *qp) +{ + double price; struct iguana_info *coin; char str[65]; + price = LP_myprice(bidp,askp,qp->srccoin,qp->destcoin); + if ( (coin= LP_coinfind(qp->srccoin)) == 0 || price <= SMALLVAL || *askp <= SMALLVAL ) + { + //printf("this node has no price for %s/%s\n",qp->srccoin,qp->destcoin); + return(0.); + } + price = *askp; + //printf("MYPRICE %s/%s %.8f vs qprice %.8f\n",qp->srccoin,qp->destcoin,price,(double)qp->destsatoshis/qp->satoshis); + if ( LP_validSPV(qp->destcoin,qp->destaddr,qp->desttxid,qp->destvout) < 0 ) + { + printf("LP_trades_bobprice %s dest %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->desttxid)); + return(0.); + } + else if (LP_validSPV(qp->destcoin,qp->destaddr,qp->feetxid,qp->feevout) < 0 ) + { + printf("LP_trades_bobprice %s dexfee %s failed SPV check\n",qp->destcoin,bits256_str(str,qp->feetxid)); + return(0.); + } + return(*askp); +} + +double LP_trades_pricevalidate(struct LP_quoteinfo *qp,struct iguana_info *coin,double price) +{ + double qprice; struct LP_utxoinfo A,B,*autxo,*butxo; + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,qp); + if ( strcmp(qp->coinaddr,coin->smartaddr) != 0 ) + { + printf("bob is patching qp->coinaddr %s mismatch != %s\n",qp->coinaddr,coin->smartaddr); + strcpy(qp->coinaddr,coin->smartaddr); + } + if ( butxo == 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 || butxo->payment.vout < 0 || butxo->deposit.vout < 0 ) + { + char str[65],str2[65]; printf("couldnt find bob utxos for autxo %s/v%d %s/v%d %.8f -> %.8f\n",bits256_str(str,qp->txid),qp->vout,bits256_str(str2,qp->txid2),qp->vout2,dstr(qp->satoshis),dstr(qp->destsatoshis)); + return(-66); + } + if ( (qprice= LP_quote_validate(autxo,butxo,qp,1)) <= SMALLVAL ) + { + printf("quote %s/%s validate error %.0f\n",qp->srccoin,qp->destcoin,qprice); + return(-3); + } + if ( qprice < (price - 0.00000001) * 0.998 ) + { + printf(" quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f\n",qprice,price,qp->srccoin,qp->destcoin,qprice,(price - 0.00000001) * 0.998); + return(-77); + } + return(qprice); +} + +struct LP_quoteinfo *LP_trades_gotrequest(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) +{ + double price,qprice,myprice,bestprice,range,bid,ask; struct iguana_info *coin; struct LP_utxoinfo A,B,*autxo,*butxo; cJSON *reqjson; char str[65]; struct LP_address_utxo *utxos[1000]; int32_t r,counter,max = (int32_t)(sizeof(utxos)/sizeof(*utxos)); + *newqp = *qp; + qp = newqp; + //printf("bob %s received REQUEST.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) + return(0); + if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) + return(0); + autxo = &A; + butxo = &B; + memset(autxo,0,sizeof(*autxo)); + memset(butxo,0,sizeof(*butxo)); + LP_abutxo_set(autxo,butxo,qp); + if ( bits256_nonz(qp->srchash) == 0 || bits256_cmp(qp->srchash,G.LP_mypub25519) == 0 ) + { + qprice = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); + strcpy(qp->gui,G.gui); + strcpy(qp->coinaddr,coin->smartaddr); + strcpy(butxo->coinaddr,coin->smartaddr); + qp->srchash = G.LP_mypub25519; + memset(&qp->txid,0,sizeof(qp->txid)); + memset(&qp->txid2,0,sizeof(qp->txid2)); + qp->vout = qp->vout2 = -1; + } else return(0); + if ( qprice > myprice ) + { + r = (LP_rand() % 100); + range = (qprice - myprice); + price = myprice + (r * range) / 100.; + bestprice = LP_bob_competition(&counter,qp->aliceid,price,0); + printf("%llu >>>>>>> qprice %.8f r.%d range %.8f -> %.8f, bestprice %.8f counter.%d\n",(long long)qp->aliceid,qprice,r,range,price,bestprice,counter); + if ( counter > 3 && price > bestprice+SMALLVAL ) // skip if late or bad price + return(0); + } else return(0); + //LP_RTmetrics_update(qp->srccoin,qp->destcoin); + if ( LP_RTmetrics_blacklisted(qp->desthash) >= 0 ) + { + printf("request from blacklisted %s, ignore\n",bits256_str(str,qp->desthash)); + return(0); + } + //printf("LP_address_utxo_reset.%s\n",coin->symbol); + //LP_address_utxo_reset(coin); + //printf("done LP_address_utxo_reset.%s\n",coin->symbol); + if ( (butxo= LP_address_myutxopair(butxo,1,utxos,max,LP_coinfind(qp->srccoin),qp->coinaddr,qp->txfee,dstr(qp->destsatoshis),price,qp->desttxfee)) != 0 ) + { + strcpy(qp->gui,G.gui); + strcpy(qp->coinaddr,coin->smartaddr); + qp->srchash = G.LP_mypub25519; + qp->txid = butxo->payment.txid; + qp->vout = butxo->payment.vout; + qp->txid2 = butxo->deposit.txid; + qp->vout2 = butxo->deposit.vout; + qp->satoshis = butxo->swap_satoshis;// + qp->txfee; + qp->quotetime = (uint32_t)time(NULL); + } + else + { + //printf("cant find utxopair aliceid.%llu %s/%s %.8f -> relvol %.8f\n",(long long)qp->aliceid,qp->srccoin,qp->destcoin,dstr(LP_basesatoshis(dstr(qp->destsatoshis),price,qp->txfee,qp->desttxfee)),dstr(qp->destsatoshis)); + return(0); + } + if ( (qprice= LP_trades_pricevalidate(qp,coin,myprice)) < 0. ) + return(0); + if ( LP_allocated(qp->txid,qp->vout) == 0 && LP_allocated(qp->txid2,qp->vout2) == 0 ) + { + reqjson = LP_quotejson(qp); + LP_unavailableset(qp->txid,qp->vout,qp->timestamp + LP_RESERVETIME,qp->desthash); + LP_unavailableset(qp->txid2,qp->vout2,qp->timestamp + LP_RESERVETIME,qp->desthash); + if ( qp->quotetime == 0 ) + qp->quotetime = (uint32_t)time(NULL); + jaddnum(reqjson,"quotetime",qp->quotetime); + jaddnum(reqjson,"pending",qp->timestamp + LP_RESERVETIME); + jaddstr(reqjson,"method","reserved"); + //LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->desthash,jprint(reqjson,0)); + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,jprint(reqjson,0)); + free_json(reqjson); + //printf("Send RESERVED id.%llu\n",(long long)qp->aliceid); + return(qp); + } else printf("request processing selected ineligible utxos?\n"); + return(0); +} + +struct LP_quoteinfo *LP_trades_gotreserved(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp) +{ + char *retstr; + //char str[65]; printf("alice %s received RESERVED.(%llu) %.8f\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid,(double)qp->destsatoshis/(qp->satoshis+1)); + *newqp = *qp; + qp = newqp; + if ( LP_trades_alicevalidate(ctx,qp) > 0. ) + { + LP_aliceid(qp->tradeid,qp->aliceid,"reserved",0,0); + if ( (retstr= LP_quotereceived(qp)) != 0 ) + free(retstr); + return(qp); + } + return(0); +} + +struct LP_quoteinfo *LP_trades_gotconnect(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) +{ + double myprice,qprice,bid,ask; struct iguana_info *coin; + char str[65]; printf("bob %s received CONNECT.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + *newqp = *qp; + qp = newqp; + if ( (coin= LP_coinfind(qp->srccoin)) == 0 ) + return(0); + if ( (myprice= LP_trades_bobprice(&bid,&ask,qp)) == 0. ) + return(0); + if ( (qprice= LP_trades_pricevalidate(qp,coin,myprice)) < 0. ) + return(0); + if ( LP_reservation_check(qp->txid,qp->vout,qp->desthash) == 0 && LP_reservation_check(qp->txid2,qp->vout2,qp->desthash) == 0 ) + { + LP_connectstartbob(ctx,LP_mypubsock,qp->srccoin,qp->destcoin,qprice,qp); + return(qp); + } else printf("connect message from non-reserved (%llu)\n",(long long)qp->aliceid); + return(0); +} + +struct LP_quoteinfo *LP_trades_gotconnected(void *ctx,struct LP_quoteinfo *qp,struct LP_quoteinfo *newqp,char *pairstr) +{ + char *retstr; + //char str[65]; printf("alice %s received CONNECTED.(%llu)\n",bits256_str(str,G.LP_mypub25519),(long long)qp->aliceid); + *newqp = *qp; + qp = newqp; + if ( LP_trades_alicevalidate(ctx,qp) > 0. ) + { + //printf("LP_trades_alicevalidate fine\n"); + LP_aliceid(qp->tradeid,qp->aliceid,"connected",0,0); + if ( (retstr= LP_connectedalice(qp,pairstr)) != 0 ) + free(retstr); + return(qp); + } + //printf("LP_trades_alicevalidate error\n"); + return(0); +} + +int32_t LP_trades_bestpricecheck(void *ctx,struct LP_trade *tp) +{ + double qprice; int32_t flag = 0; struct LP_quoteinfo Q; int64_t dynamictrust; char *retstr; struct LP_pubkey_info *pubp; + Q = tp->Q; + //printf("check bestprice %.8f vs new price %.8f\n",tp->bestprice,(double)Q.destsatoshis/Q.satoshis); + if ( Q.satoshis != 0 && (pubp= LP_pubkeyadd(Q.srchash)) != 0 )//(qprice= LP_trades_alicevalidate(ctx,&Q)) > 0. ) + { + qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); + LP_aliceid(Q.tradeid,tp->aliceid,"reserved",0,0); + if ( (retstr= LP_quotereceived(&Q)) != 0 ) + free(retstr); + //LP_trades_gotreserved(ctx,&Q,&tp->Qs[LP_RESERVED]); + dynamictrust = LP_dynamictrust(Q.othercredits,Q.srchash,LP_kmdvalue(Q.srccoin,Q.satoshis)); + if ( tp->bestprice == 0. ) + flag = 1; + else if ( qprice < tp->bestprice && pubp->slowresponse <= tp->bestresponse*1.05 ) + flag = 1; + else if ( qprice < tp->bestprice*1.01 && dynamictrust > tp->besttrust && pubp->slowresponse <= tp->bestresponse*1.1 ) + flag = 1; + else if ( qprice <= tp->bestprice && pubp->unconfcredits > tp->bestunconfcredits && pubp->slowresponse <= tp->bestresponse ) + flag = 1; + if ( flag != 0 ) + { + tp->Qs[LP_CONNECT] = tp->Q; + tp->bestprice = qprice; + tp->besttrust = dynamictrust; + tp->bestunconfcredits = pubp->unconfcredits; + tp->bestresponse = pubp->slowresponse; + printf("aliceid.%llu got new bestprice %.8f dynamictrust %.8f (unconf %.8f) slowresponse.%d\n",(long long)tp->aliceid,tp->bestprice,dstr(dynamictrust),dstr(tp->bestunconfcredits),tp->bestresponse); + return(qprice); + } //else printf("qprice %.8f dynamictrust %.8f not good enough\n",qprice,dstr(dynamictrust)); + } else printf("alice didnt validate\n"); + return(0); +} + +void LP_tradesloop(void *ctx) +{ + struct LP_trade *qtp,*tp,*tmp; struct LP_quoteinfo *qp,Q; uint32_t now; int32_t timeout,funcid,flag,nonz; struct iguana_info *coin; struct LP_pubkey_info *pubp; + strcpy(LP_tradesloop_stats.name,"LP_tradesloop"); + LP_tradesloop_stats.threshold = 30000; + sleep(5); + while ( LP_STOP_RECEIVED == 0 ) + { + LP_millistats_update(&LP_tradesloop_stats); + nonz = 0; + HASH_ITER(hh,LP_trades,tp,tmp) + { + if ( tp->negotiationdone != 0 ) + continue; + timeout = LP_AUTOTRADE_TIMEOUT; + if ( (coin= LP_coinfind(tp->Q.srccoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + if ( (coin= LP_coinfind(tp->Q.destcoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + now = (uint32_t)time(NULL); + if ( now > tp->lastprocessed ) + { + if ( tp->iambob == 0 ) + { + if ( tp->bestprice > 0. ) + { + if ( tp->connectsent == 0 ) + { + LP_Alicemaxprice = tp->bestprice; + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT + tp->connectsent = now; + //printf("send LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + } + else if ( now < tp->firstprocessed+timeout && ((tp->firstprocessed - now) % 20) == 19 ) + { + //LP_Alicemaxprice = tp->bestprice; + //LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&tp->Qs[LP_CONNECT]); // send LP_CONNECT + //printf("mark slow LP_connect aliceid.%llu %.8f\n",(long long)tp->aliceid,tp->bestprice); + if ( (pubp= LP_pubkeyfind(tp->Qs[LP_CONNECT].srchash)) != 0 ) + pubp->slowresponse++; + } + } + } + } + } + now = (uint32_t)time(NULL); + HASH_ITER(hh,LP_trades,tp,tmp) + { + timeout = LP_AUTOTRADE_TIMEOUT; + if ( (coin= LP_coinfind(tp->Q.srccoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + if ( (coin= LP_coinfind(tp->Q.destcoin)) != 0 && coin->electrum != 0 ) + timeout += LP_AUTOTRADE_TIMEOUT * .5; + if ( now > tp->firstprocessed+timeout*10 ) + { + //printf("purge swap aliceid.%llu\n",(long long)tp->aliceid); + portable_mutex_lock(&LP_tradesmutex); + HASH_DELETE(hh,LP_trades,tp); + portable_mutex_unlock(&LP_tradesmutex); + free(tp); + } + } + DL_FOREACH_SAFE(LP_tradesQ,qtp,tmp) + { + now = (uint32_t)time(NULL); + Q = qtp->Q; + funcid = qtp->funcid; +//printf("dequeue %p funcid.%d aliceid.%llu iambob.%d\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob); + portable_mutex_lock(&LP_tradesmutex); + DL_DELETE(LP_tradesQ,qtp); + HASH_FIND(hh,LP_trades,&qtp->aliceid,sizeof(qtp->aliceid),tp); + if ( tp == 0 ) + { + if ( now > Q.timestamp+LP_AUTOTRADE_TIMEOUT*2 ) // eat expired + free(qtp); + else + { + tp = qtp; + HASH_ADD(hh,LP_trades,aliceid,sizeof(tp->aliceid),tp); + portable_mutex_unlock(&LP_tradesmutex); + if ( tp->iambob != 0 && funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED + { + if ( (qp= LP_trades_gotrequest(ctx,&Q,&tp->Qs[LP_REQUEST],tp->pairstr)) != 0 ) + tp->Qs[LP_RESERVED] = Q; + } + else if ( tp->iambob == 0 && funcid == LP_RESERVED ) // alice maybe sends LP_CONNECT + { + LP_trades_bestpricecheck(ctx,tp); + } + else if ( tp->iambob == 0 && funcid == LP_CONNECTED ) + { + tp->negotiationdone = now; + //printf("alice sets negotiationdone.%u\n",now); + LP_trades_gotconnected(ctx,&tp->Q,&tp->Qs[LP_CONNECTED],tp->pairstr); + } + nonz++; + tp->firstprocessed = tp->lastprocessed = (uint32_t)time(NULL); + if ( funcid == LP_CONNECT && tp->negotiationdone == 0 ) // bob all done + { + tp->negotiationdone = now; + //printf("bob sets negotiationdone.%u\n",now); + LP_trades_gotconnect(ctx,&tp->Q,&tp->Qs[LP_CONNECT],tp->pairstr); + } + } + continue; + } + portable_mutex_unlock(&LP_tradesmutex); + tp->Q = qtp->Q; + if ( qtp->iambob == tp->iambob && qtp->pairstr[0] != 0 ) + safecopy(tp->pairstr,qtp->pairstr,sizeof(tp->pairstr)); +//printf("finished dequeue %p funcid.%d aliceid.%llu iambob.%d/%d done.%u\n",qtp,funcid,(long long)qtp->aliceid,qtp->iambob,tp->iambob,tp->negotiationdone); + free(qtp); + flag = 0; + if ( tp->iambob == 0 ) + { + if ( funcid == LP_RESERVED ) + { + if ( tp->connectsent == 0 ) + flag = LP_trades_bestpricecheck(ctx,tp); + } + else if ( funcid == LP_CONNECTED && tp->negotiationdone == 0 ) // alice all done tp->connectsent != 0 && + { + flag = 1; + tp->negotiationdone = now; + LP_trades_gotconnected(ctx,&tp->Q,&tp->Qs[LP_CONNECTED],tp->pairstr); + } + } + else + { + if ( funcid == LP_REQUEST ) // bob maybe sends LP_RESERVED + { + if ( (qp= LP_trades_gotrequest(ctx,&Q,&tp->Qs[LP_REQUEST],tp->pairstr)) != 0 ) + { + tp->Qs[LP_RESERVED] = Q; + flag = 1; + } + } + else if ( funcid == LP_CONNECT && tp->negotiationdone == 0 ) // bob all done + { + flag = 1; + tp->negotiationdone = now; + //printf("bob sets negotiationdone.%u\n",now); + LP_trades_gotconnect(ctx,&tp->Q,&tp->Qs[LP_CONNECT],tp->pairstr); + } + } + if ( flag != 0 ) + { + tp->lastprocessed = (uint32_t)time(NULL); + nonz++; + } + } + if ( nonz == 0 ) + sleep(1); + } +} + +void LP_tradecommandQ(struct LP_quoteinfo *qp,char *pairstr,int32_t funcid) +{ + struct LP_trade *qtp; uint64_t aliceid; int32_t iambob; + if ( funcid < 0 || funcid >= sizeof(qtp->Qs)/sizeof(*qtp->Qs) ) + return; + if ( funcid == LP_REQUEST || funcid == LP_CONNECT ) + iambob = 1; + else iambob = 0; + aliceid = qp->aliceid; + portable_mutex_lock(&LP_tradesmutex); + qtp = calloc(1,sizeof(*qtp)); + qtp->funcid = funcid; + qtp->iambob = iambob; + qtp->aliceid = aliceid; + qtp->newtime = (uint32_t)time(NULL); + qtp->Q = *qp; + if ( pairstr != 0 ) + safecopy(qtp->pairstr,pairstr,sizeof(qtp->pairstr)); + DL_APPEND(LP_tradesQ,qtp); + portable_mutex_unlock(&LP_tradesmutex); + //printf("queue.%d %p\n",funcid,qtp); +} + +int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,uint8_t *data,int32_t datalen) +{ + int32_t Qtrades = 1; + char *method,str[65]; int32_t i,num,DEXselector = 0; uint64_t aliceid; double qprice,bestprice,price,bid,ask; cJSON *proof; uint64_t rq; struct iguana_info *coin; struct LP_quoteinfo Q,Q2; int32_t counter,retval=-1; + if ( (method= jstr(argjson,"method")) != 0 && (strcmp(method,"reserved") == 0 ||strcmp(method,"connected") == 0 || strcmp(method,"request") == 0 || strcmp(method,"connect") == 0) ) + { + LP_quoteparse(&Q,argjson); + LP_requestinit(&Q.R,Q.srchash,Q.desthash,Q.srccoin,Q.satoshis-Q.txfee,Q.destcoin,Q.destsatoshis-Q.desttxfee,Q.timestamp,Q.quotetime,DEXselector); + LP_tradecommand_log(argjson); + rq = ((uint64_t)Q.R.requestid << 32) | Q.R.quoteid; + if ( Q.timestamp > 0 && time(NULL) > Q.timestamp + LP_AUTOTRADE_TIMEOUT*20 ) // eat expired packets, some old timestamps floating about? + { + printf("aliceid.%llu is expired by %d\n",(long long)Q.aliceid,(uint32_t)time(NULL) - (Q.timestamp + LP_AUTOTRADE_TIMEOUT*20)); + return(1); + } + printf("%-4d (%-10u %10u) %12s id.%-20llu %5s/%-5s %12.8f -> %12.8f (%11.8f) | RT.%d %d n%d\n",(uint32_t)time(NULL) % 3600,Q.R.requestid,Q.R.quoteid,method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis,LP_RTcount,LP_swapscount,G.netid); + retval = 1; + aliceid = j64bits(argjson,"aliceid"); + qprice = jdouble(argjson,"price"); + if ( strcmp(method,"reserved") == 0 ) + { + bestprice = LP_bob_competition(&counter,aliceid,qprice,1); + //printf("%s lag %ld: aliceid.%llu price %.8f -> bestprice %.8f Alice max %.8f\n",jprint(argjson,0),Q.quotetime - (time(NULL)-20),(long long)aliceid,qprice,bestprice,LP_Alicemaxprice); + if ( 1 ) + { + if ( LP_Alicemaxprice == 0. ) + return(retval); + if ( bits256_nonz(LP_Alicedestpubkey) != 0 ) + { + if (bits256_cmp(LP_Alicedestpubkey,Q.srchash) != 0 ) + { + printf("got reserved response from different node %s\n",bits256_str(str,Q.srchash)); + return(retval); + } else printf("got reserved response from destpubkey %s\n",bits256_str(str,Q.srchash)); + } + } + if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) // alice + { + if ( Qtrades == 0 ) + { + if ( Q.quotetime > time(NULL)-20 && LP_alice_eligible(Q.quotetime) > 0 ) + { + LP_trades_gotreserved(ctx,&Q,&Q2); + if ( LP_quotecmp(0,&Q,&LP_Alicequery) == 0 ) + LP_reserved(ctx,LP_myipaddr,LP_mypubsock,&Q); + } + } else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_RESERVED); + } + } + else if ( strcmp(method,"connected") == 0 ) + { + bestprice = LP_bob_competition(&counter,aliceid,qprice,1000); + if ( bits256_cmp(G.LP_mypub25519,Q.desthash) == 0 && bits256_cmp(G.LP_mypub25519,Q.srchash) != 0 ) // alice + { + static uint64_t rqs[1024]; + for (i=0; i 0 ) + Q.othercredits = LP_instantdex_proofcheck(Q.srccoin,Q.coinaddr,proof,num); + if ( Qtrades == 0 ) + LP_trades_gotconnected(ctx,&Q,&Q2,jstr(argjson,"pair")); + else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECTED); + } + } + price = LP_myprice(&bid,&ask,Q.srccoin,Q.destcoin); + if ( (coin= LP_coinfind(Q.srccoin)) == 0 || coin->inactive != 0 ) + { + //printf("%s is not active\n",Q.srccoin); + return(retval); + } + if ( price <= SMALLVAL || ask <= SMALLVAL ) + { + //printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin); + return(retval); + } + if ( LP_aliceonly(Q.srccoin) > 0 ) + { + printf("{\"error\":\"GAME can only be alice coin\"}\n"); + return(retval); + } + if ( strcmp(method,"request") == 0 ) // bob + { + bestprice = LP_bob_competition(&counter,aliceid,qprice,-1); + if ( Qtrades == 0 )//|| (bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0) ) + LP_trades_gotrequest(ctx,&Q,&Q2,jstr(argjson,"pair")); + else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_REQUEST); + } + else if ( strcmp(method,"connect") == 0 ) + { + LP_bob_competition(&counter,aliceid,qprice,1000); + if ( bits256_cmp(G.LP_mypub25519,Q.srchash) == 0 && bits256_cmp(G.LP_mypub25519,Q.desthash) != 0 ) // bob + { + static uint64_t rqs[1024]; + for (i=0; i 0 ) + Q.othercredits = LP_instantdex_proofcheck(Q.destcoin,Q.destaddr,proof,num); + if ( Qtrades == 0 ) + LP_trades_gotconnect(ctx,&Q,&Q2,jstr(argjson,"pair")); + else LP_tradecommandQ(&Q,jstr(argjson,"pair"),LP_CONNECT); + } + } + return(retval); + } + return(retval); +} + +char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration,char *gui,uint32_t nonce,bits256 destpubkey,uint32_t tradeid) +{ + uint64_t desttxfee,txfee; uint32_t lastnonce; int64_t bestsatoshis=0,destsatoshis; struct iguana_info *basecoin,*relcoin; struct LP_utxoinfo *autxo,B,A; struct LP_quoteinfo Q; bits256 pubkeys[100]; struct LP_address_utxo *utxos[1000]; int32_t max=(int32_t)(sizeof(utxos)/sizeof(*utxos)); + basecoin = LP_coinfind(base); + relcoin = LP_coinfind(rel); + if ( gui == 0 ) + gui = "nogui"; + if ( basecoin == 0 || basecoin->inactive != 0 || relcoin == 0 || relcoin->inactive != 0 ) + return(clonestr("{\"error\":\"base or rel not found or inactive\"}")); + if ( LP_aliceonly(base) > 0 ) + return(clonestr("{\"error\":\"GAME can only be alice coin\"}")); + printf("LP_autobuy %s/%s price %.8f vol %.8f nonce %u\n",base,rel,maxprice,relvolume,nonce); + if ( (lastnonce= LP_lastnonce) != 0 && nonce <= lastnonce ) + { + printf("nonce.%u not bigger than lastnonce.%u\n",nonce,lastnonce); + return(clonestr("{\"error\":\"invalid nonce\"}")); + } + LP_lastnonce = nonce; + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + if ( timeout <= 0 ) + timeout = LP_AUTOTRADE_TIMEOUT; + if ( basecoin->electrum != 0 && relcoin->electrum != 0 ) + { + if ( timeout < 2*LP_AUTOTRADE_TIMEOUT ) + timeout = 2*LP_AUTOTRADE_TIMEOUT; + } + else if ( basecoin->electrum != 0 || relcoin->electrum != 0 ) + { + if ( timeout < 1.5*LP_AUTOTRADE_TIMEOUT ) + timeout = 1.5*LP_AUTOTRADE_TIMEOUT; + } + if ( time(NULL) < Alice_expiration ) + { + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","only one pending request at a time"); + jaddnum(retjson,"wait",Alice_expiration-time(NULL)); + return(jprint(retjson,1)); + } else LP_alicequery_clear(); + if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) + return(clonestr("{\"error\":\"invalid parameter\"}")); + if ( strcmp("BTC",rel) == 0 ) + maxprice *= 1.01; + else maxprice *= 1.001; + memset(pubkeys,0,sizeof(pubkeys)); + LP_txfees(&txfee,&desttxfee,base,rel); + destsatoshis = SATOSHIDEN * relvolume + 2*desttxfee; + memset(&A,0,sizeof(A)); + LP_address_utxo_reset(relcoin); + if ( (autxo= LP_address_myutxopair(&A,0,utxos,max,relcoin,relcoin->smartaddr,txfee,dstr(destsatoshis),maxprice,desttxfee)) == 0 ) + return(clonestr("{\"error\":\"cant find a deposit that is close enough in size. make another deposit that is just a bit larger than what you want to trade\"}")); + //printf("bestfit selected alice (%.8f %.8f) for %.8f sats %.8f\n",dstr(autxo->payment.value),dstr(autxo->fee.value),dstr(destsatoshis),dstr(autxo->swap_satoshis)); + if ( destsatoshis - desttxfee < autxo->swap_satoshis ) + { + destsatoshis -= desttxfee; + autxo->swap_satoshis = destsatoshis; + //printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis)); + } + else if ( autxo->swap_satoshis - desttxfee < destsatoshis ) + { + autxo->swap_satoshis -= desttxfee; + destsatoshis = autxo->swap_satoshis; + printf("second path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->swap_satoshis)); + } + if ( destsatoshis < (autxo->payment.value / LP_MINCLIENTVOL) || autxo->payment.value < desttxfee*LP_MINSIZE_TXFEEMULT ) + { + printf("destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13\n",dstr(destsatoshis),dstr(autxo->payment.value)); + return(clonestr("{\"error\":\"cant find a deposit that is close enough in size. make another deposit that is just a bit larger than what you want to trade\"}")); + } + bestsatoshis = 1.001 * LP_basesatoshis(dstr(destsatoshis),maxprice,txfee,desttxfee); + memset(&B,0,sizeof(B)); + strcpy(B.coin,base); + if ( LP_quoteinfoinit(&Q,&B,rel,maxprice,bestsatoshis,destsatoshis) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); + if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,G.LP_mypub25519,autxo->coinaddr) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); + int32_t changed; + LP_mypriceset(&changed,autxo->coin,base,1. / maxprice); + LP_mypriceset(&changed,base,autxo->coin,0.); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); +} + + diff --git a/iguana/exchanges/LP_peers.c b/iguana/exchanges/LP_peers.c new file mode 100644 index 000000000..ced058f37 --- /dev/null +++ b/iguana/exchanges/LP_peers.c @@ -0,0 +1,349 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_peers.c +// marketmaker +// + +struct LP_peerinfo *LP_peerfind(uint32_t ipbits,uint16_t port) +{ + struct LP_peerinfo *peer=0; uint64_t ip_port; + ip_port = ((uint64_t)port << 32) | ipbits; + portable_mutex_lock(&LP_peermutex); + HASH_FIND(hh,LP_peerinfos,&ip_port,sizeof(ip_port),peer); + portable_mutex_unlock(&LP_peermutex); + return(peer); +} + +cJSON *LP_peerjson(struct LP_peerinfo *peer) +{ + cJSON *item = cJSON_CreateObject(); + jaddstr(item,"isLP",peer->ipaddr); + jaddnum(item,"remoteport",peer->port-1); + jaddnum(item,"netid",peer->netid); + if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) + { + jaddnum(item,"session",G.LP_sessionid); + //if ( LP_mypeer != 0 ) + // jaddnum(item,"numutxos",LP_mypeer->numutxos); + } else jaddnum(item,"session",peer->sessionid); + //jaddnum(item,"profit",peer->profitmargin); + return(item); +} + +char *LP_peers() +{ + struct LP_peerinfo *peer,*tmp; cJSON *peersjson = cJSON_CreateArray(); + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + //if ( peer->errors < LP_MAXPEER_ERRORS ) + if ( peer->isLP != 0 ) + jaddi(peersjson,LP_peerjson(peer)); + } + return(jprint(peersjson,1)); +} + +void LP_cmdchannel(struct LP_peerinfo *peer) +{ + char *hellostr = "{\"method\":\"hello\"}"; + char connectaddr[128],publicaddr[128],*retstr; int32_t pairsock=-1,pubsock,sentbytes=-2; uint16_t cmdport; +#ifdef LP_DONT_CMDCHANNEL + return; +#endif + if ( bits256_nonz(G.LP_mypub25519) == 0 || strcmp(G.USERPASS,"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f") == 0 ) + return; + if ( (cmdport= LP_psock_get(connectaddr,publicaddr,1,1,peer->ipaddr)) != 0 ) + { + if ( (retstr= _LP_psock_create(&pairsock,&pubsock,peer->ipaddr,cmdport,cmdport,1,1,G.LP_mypub25519)) != 0 ) + { + if ( nn_connect(pairsock,connectaddr) < 0 ) + printf("error connecting cmdchannel with %s\n",connectaddr); + else + { + peer->pairsock = pairsock; + sentbytes = nn_send(peer->pairsock,hellostr,(int32_t)strlen(hellostr)+1,0); + printf("cmdchannel %d created %s sent.%d\n",peer->pairsock,retstr,sentbytes); + } + free(retstr); + } + } else printf("error getting cmdchannel with %s\n",peer->ipaddr); +} + +void LP_cmdchannels() +{ + struct LP_peerinfo *peer,*tmp; + if ( IAMLP == 0 ) + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->pairsock < 0 ) + LP_cmdchannel(peer); + } + } +} + +void LP_peer_pairsock(bits256 pubkey) +{ + struct LP_peerinfo *peer,*tmp; + if ( IAMLP == 0 ) + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( bits256_cmp(pubkey,peer->pubkey) == 0 ) + { + peer->pairsock = -1; + break; + } + } + } +} + +struct LP_peerinfo *LP_addpeer(struct LP_peerinfo *mypeer,int32_t mypubsock,char *ipaddr,uint16_t port,uint16_t pushport,uint16_t subport,int32_t isLP,uint32_t sessionid,uint16_t netid) +{ + uint32_t ipbits; int32_t valid,pushsock,subsock,timeout; char checkip[64],pushaddr[64],subaddr[64]; struct LP_peerinfo *peer = 0; +#ifdef LP_STRICTPEERS + if ( strncmp("5.9.253",ipaddr,strlen("5.9.253")) != 0 ) + return(0); +#endif + ipbits = (uint32_t)calc_ipbits(ipaddr); + expand_ipbits(checkip,ipbits); + if ( strcmp(checkip,ipaddr) == 0 ) + { + if ( (peer= LP_peerfind(ipbits,port)) != 0 ) + { + if ( peer->netid != netid ) + { + printf("netid mismatch for %s? %d vs %d\n",peer->ipaddr,peer->netid,G.netid); + return(0); + } + if ( isLP != 0 && peer->isLP == 0 ) + { + if ( (peer->isLP= isLP) != 0 ) + LP_numactive_LP++; + } + if ( IAMLP == 0 && peer->pairsock < 0 ) + LP_cmdchannel(peer); + /*if ( numpeers > peer->numpeers ) + peer->numpeers = numpeers; + if ( numutxos > peer->numutxos ) + peer->numutxos = numutxos; + if ( peer->sessionid == 0 ) + peer->sessionid = sessionid;*/ + } + else if ( IAMLP != 0 || LP_numactive_LP < 10 ) + { + //printf("addpeer (%s:%u) pushport.%u subport.%u\n",ipaddr,port,pushport,subport); + peer = calloc(1,sizeof(*peer)); + peer->pairsock = -1; + if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) + peer->sessionid = G.LP_sessionid; + else peer->sessionid = sessionid; + peer->pushsock = peer->subsock = pushsock = subsock = -1; + strcpy(peer->ipaddr,ipaddr); + peer->netid = netid; + //peer->profitmargin = profitmargin; + peer->ipbits = ipbits; + if ( (peer->isLP= isLP) != 0 ) + LP_numactive_LP++; + peer->port = port; + peer->ip_port = ((uint64_t)port << 32) | ipbits; + if ( pushport != 0 && subport != 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 ) + { + nanomsg_transportname(0,pushaddr,peer->ipaddr,pushport); + valid = 0; + if ( nn_connect(pushsock,pushaddr) >= 0 ) + valid++; + if ( valid > 0 ) + { + //timeout = 10; + //nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_MAXTTL,&timeout,sizeof(timeout)); + timeout = 100; + nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + printf("connected to push.(%s) pushsock.%d valid.%d | ",pushaddr,pushsock,valid); + peer->connected = (uint32_t)time(NULL); + peer->pushsock = pushsock; + if ( (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) + { + timeout = 100; + nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + nanomsg_transportname(0,subaddr,peer->ipaddr,subport); + valid = 0; + if ( nn_connect(subsock,subaddr) >= 0 ) + valid++; + if ( valid > 0 ) + { + peer->subsock = subsock; + printf("connected to sub.(%s) subsock.%d valid.%d numactive.%d\n",subaddr,peer->subsock,valid,LP_numactive_LP); + } + else + { + printf("error connecting to subsock.%d (%s)\n",subsock,subaddr); + nn_close(subsock); + subsock = -1; + } + } + } + else + { + nn_close(pushsock); + pushsock = -1; + printf("error connecting to push.(%s)\n",pushaddr); + } + } else printf("%s pushport.%u subport.%u pushsock.%d isLP.%d\n",ipaddr,pushport,subport,pushsock,isLP); + if ( peer->pushsock >= 0 && peer->subsock >= 0 ) + { + //printf("add peer %s isLP.%d\n",peer->ipaddr,peer->isLP); + portable_mutex_lock(&LP_peermutex); + HASH_ADD(hh,LP_peerinfos,ip_port,sizeof(peer->ip_port),peer); + if ( mypeer != 0 ) + { + mypeer->numpeers++; + printf("_LPaddpeer %s -> numpeers.%d mypubsock.%d other.(%d)\n",ipaddr,mypeer->numpeers,mypubsock,isLP); + } else peer->numpeers = 1; // will become mypeer + portable_mutex_unlock(&LP_peermutex); + if ( IAMLP == 0 && peer->pairsock < 0 ) + LP_cmdchannel(peer); + } else printf("%s invalid pushsock.%d or subsock.%d\n",peer->ipaddr,peer->pushsock,peer->subsock); + } + } else printf("LP_addpeer: checkip.(%s) vs (%s)\n",checkip,ipaddr); + return(peer); +} + +void LP_closepeers() +{ + struct LP_peerinfo *peer,*tmp; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + portable_mutex_lock(&LP_peermutex); + HASH_DELETE(hh,LP_peerinfos,peer); + portable_mutex_unlock(&LP_peermutex); + if ( peer->pushsock >= 0 ) + nn_close(peer->pushsock), peer->pushsock = -1; + if ( peer->subsock >= 0 ) + nn_close(peer->subsock), peer->subsock = -1; + // free(peer); a small memleak to avoid freein inflight requests + } +} + +/*int32_t LP_coinbus(uint16_t coin_busport) +{ + struct LP_peerinfo *peer,*tmp; char busaddr[64]; int32_t timeout,bussock = -1; + return(-1); + if ( IAMLP != 0 && LP_mypeer != 0 && (bussock= nn_socket(AF_SP,NN_BUS)) >= 0 ) + { + timeout = 1; + nn_setsockopt(bussock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + nn_setsockopt(bussock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); + nanomsg_transportname(0,busaddr,LP_mypeer->ipaddr,coin_busport); + if ( nn_bind(bussock,busaddr) < 0 ) + { + printf("error binding to coin_busport.%s\n",busaddr); + nn_close(bussock); + } + else + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( LP_mypeer->port != peer->port || strcmp(LP_mypeer->ipaddr,peer->ipaddr) != 0 ) + { + nanomsg_transportname(0,busaddr,peer->ipaddr,coin_busport); + nn_connect(bussock,busaddr); + } + } + } + } + return(bussock); +}*/ + +void LP_peer_recv(char *ipaddr,int32_t ismine,struct LP_pubkey_info *pubp) +{ + struct LP_peerinfo *peer; + if ( (peer= LP_peerfind((uint32_t)calc_ipbits(ipaddr),RPC_port)) != 0 ) + { + peer->numrecv++; + if ( ismine != 0 && bits256_cmp(G.LP_mypub25519,pubp->pubkey) != 0 && (bits256_nonz(peer->pubkey) == 0 || pubp->pairsock < 0) ) + { + peer->pubkey = pubp->pubkey; + pubp->pairsock = peer->pairsock; + char str[65]; printf("set pubkey for %s <- %s, pairsock.%d\n",ipaddr,bits256_str(str,pubp->pubkey),pubp->pairsock); + } + peer->recvtime = (uint32_t)time(NULL); + } +} + +int32_t LP_numpeers() +{ + struct LP_peerinfo *peer,*tmp; int32_t numpeers = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->isLP != 0 ) + numpeers++; + } + return(numpeers); +} + +uint16_t LP_randpeer(char *destip) +{ + struct LP_peerinfo *peer,*tmp; uint16_t port = 0; int32_t n,r,numpeers = 0; + destip[0] = 0; + numpeers = LP_numpeers(); + if ( numpeers > 0 ) + { + r = LP_rand() % numpeers; + n = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->isLP != 0 ) + { + if ( n++ == r ) + { + strcpy(destip,peer->ipaddr); + port = peer->port; + break; + } + } + } + } + return(port); +} + +uint16_t LP_rarestpeer(char *destip) +{ + struct LP_peerinfo *peer,*tmp,*rarest = 0; int32_t iter; uint32_t now; + now = (uint32_t)time(NULL); + destip[0] = 0; + for (iter=0; iter<2; iter++) + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( strcmp(peer->ipaddr,LP_myipaddr) != 0 && iter == 0 && peer->recvtime < now-3600 ) + continue; + if ( peer->isLP != 0 ) + { + if ( rarest == 0 || peer->numrecv < rarest->numrecv ) + rarest = peer; + } + } + if ( rarest != 0 ) + break; + } + if ( rarest == 0 ) + LP_randpeer(destip); + else strcpy(destip,rarest->ipaddr); + return(rarest != 0 ? rarest->port : RPC_port); +} + diff --git a/iguana/exchanges/LP_portfolio.c b/iguana/exchanges/LP_portfolio.c new file mode 100644 index 000000000..ead40b27c --- /dev/null +++ b/iguana/exchanges/LP_portfolio.c @@ -0,0 +1,889 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_portfolio.c +// marketmaker +// + +struct LP_portfoliotrade { double metric; char buycoin[65],sellcoin[65]; }; + +struct LP_autoprice_ref +{ + char refbase[65],refrel[65],base[65],rel[65],fundbid[16],fundask[16]; + double buymargin,sellmargin,factor,offset,lastbid,lastask; + cJSON *fundvalue; + uint32_t count; +} LP_autorefs[1024]; + +int32_t LP_autoprices,num_LP_autorefs; +char LP_portfolio_base[128],LP_portfolio_rel[128]; +double LP_portfolio_relvolume; + +void LP_portfolio_reset() +{ + struct iguana_info *coin,*tmp; cJSON *fundjson; int32_t i; struct LP_autoprice_ref *ptr; + for (i=0; ifundvalue) != 0 ) + { + ptr->fundvalue = 0; + free_json(fundjson); + } + } + memset(LP_autorefs,0,sizeof(LP_autorefs)); + LP_autoprices = 0; + num_LP_autorefs = 0; + strcpy(LP_portfolio_base,""); + strcpy(LP_portfolio_rel,""); + LP_portfolio_relvolume = 0.; + HASH_ITER(hh,LP_coins,coin,tmp) + { + coin->maxamount = 0; + coin->perc = 0; + coin->goal = 0; + coin->goalperc = 0; + coin->relvolume = 0; + coin->force = 0; + coin->balanceA = 0; + coin->valuesumA = 0; + coin->balanceB = 0; + coin->valuesumB = 0; + } +} + +cJSON *LP_portfolio_entry(struct iguana_info *coin) +{ + cJSON *item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddstr(item,"address",coin->smartaddr); + jaddnum(item,"amount",dstr(coin->maxamount)); + jaddnum(item,"price",coin->price_kmd); + jaddnum(item,"kmd_equiv",dstr(coin->kmd_equiv)); + jaddnum(item,"perc",coin->perc); + jaddnum(item,"goal",coin->goal); + jaddnum(item,"goalperc",coin->goalperc); + jaddnum(item,"relvolume",coin->relvolume); + jaddnum(item,"force",coin->force); + jaddnum(item,"balanceA",dstr(coin->balanceA)); + jaddnum(item,"valuesumA",dstr(coin->valuesumA)); + if ( coin->valuesumA != 0 ) + jaddnum(item,"aliceutil",100. * (double)coin->balanceA/coin->valuesumA); + jaddnum(item,"balanceB",dstr(coin->balanceB)); + jaddnum(item,"valuesumB",dstr(coin->valuesumB)); + jaddnum(item,"balance",dstr(coin->maxamount)); + if ( coin->valuesumB != 0 ) + jaddnum(item,"bobutil",100. * (double)coin->balanceB/coin->valuesumB); + return(item); +} + +uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr) +{ + cJSON *array,*item; bits256 zero; int32_t i,n; uint64_t valuesum,satoshisum,value; + valuesum = satoshisum = 0; + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_listunspent(symbol,coinaddr,zero,zero)) != 0 ) + { + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 && is_cJSON_Array(array) != 0 ) + { + for (i=0; iinactive != 0 )//|| (coin->electrum != 0 && coin->obooktime == 0) ) + continue; + if ( iter == 0 ) + { + //printf("from portfolio\n"); + //LP_privkey_init(-1,coin,G.LP_privkey,G.LP_mypub25519); + coin->balanceA = LP_balance(&coin->valuesumA,0,coin->symbol,coin->smartaddr); + coin->balanceB = LP_balance(&coin->valuesumB,1,coin->symbol,coin->smartaddr); + if ( strcmp(coin->symbol,"KMD") != 0 ) + coin->price_kmd = LP_price(coin->symbol,"KMD"); + else coin->price_kmd = 1.; + coin->maxamount = coin->valuesumA; + if ( coin->valuesumB > coin->maxamount ) + coin->maxamount = coin->valuesumB; + coin->kmd_equiv = coin->maxamount * coin->price_kmd; + kmdsum += coin->kmd_equiv; + goalsum += coin->goal; + } + else + { + coin->relvolume = 0.; + if ( kmdsum > SMALLVAL ) + coin->perc = 100. * coin->kmd_equiv / kmdsum; + if ( goalsum > SMALLVAL && coin->goal > SMALLVAL ) + { + coin->goalperc = 100. * coin->goal / goalsum; + if ( (coin->force= (coin->goalperc - coin->perc)) < 0. ) + { + coin->force *= -coin->force; + if ( coin->price_kmd > SMALLVAL ) + coin->relvolume = (dstr(coin->maxamount) * (coin->perc - coin->goalperc)) / 100.; + } else coin->force *= coin->force; + if ( coin->force > maxval ) + { + maxval = coin->force; + buycoin = coin; + } + if ( coin->force < minval ) + { + minval = coin->force; + sellcoin = coin; + } + } else coin->goalperc = coin->force = 0.; + jaddi(array,LP_portfolio_entry(coin)); + } + } + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"kmd_equiv",dstr(kmdsum)); + if ( buycoin != 0 ) + { + jaddstr(retjson,"buycoin",buycoin->symbol); + jaddnum(retjson,"buyforce",maxval); + } + if ( sellcoin != 0 ) + { + jaddstr(retjson,"sellcoin",sellcoin->symbol); + jaddnum(retjson,"sellforce",minval); + } + if ( LP_portfolio_relvolume > SMALLVAL ) + { + jaddstr(retjson,"base",LP_portfolio_base); + jaddstr(retjson,"rel",LP_portfolio_rel); + jaddnum(retjson,"relvolume",LP_portfolio_relvolume); + } + jadd(retjson,"portfolio",array); + return(jprint(retjson,1)); +} + +char *LP_portfolio_goal(char *symbol,double goal) +{ + struct iguana_info *coin,*tmp; int32_t iter,n = 0; double kmdbtc = 50.; + if ( strcmp(symbol,"*") == 0 ) + { + for (iter=0; iter<2; iter++) + { + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( coin->inactive != 0 ) + continue; + if ( iter == 0 ) + coin->goal = 0; + if ( coin->inactive == 0 && strcmp(coin->symbol,"KMD") != 0 && strcmp(coin->symbol,"BTC") != 0 ) + { + if ( iter == 0 ) + n++; + else coin->goal = (100. - kmdbtc) / n; + } + } + if ( n == 0 ) + break; + } + if ( (coin= LP_coinfind("KMD")) != 0 && coin->inactive == 0 ) + coin->goal = kmdbtc * 0.5; + if ( (coin= LP_coinfind("BTC")) != 0 && coin->inactive == 0 ) + coin->goal = kmdbtc * 0.5; + if ( coin->goal != 0 ) + coin->obooktime = (uint32_t)time(NULL); + return(LP_portfolio()); + } + else if ( (coin= LP_coinfind(symbol)) != 0 && coin->inactive == 0 ) + { + coin->goal = goal; + printf("set %s goal %f\n",coin->symbol,goal); + if ( coin->goal != 0 ) + coin->obooktime = (uint32_t)time(NULL); + return(LP_portfolio()); + } else return(clonestr("{\"error\":\"cant set goal for inactive coin\"}")); +} + +/*int32_t LP_autofill(char *base,char *rel,double maxprice,double totalrelvolume) +{ + struct LP_priceinfo *basepp,*relpp; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + basepp->maxprices[relpp->ind] = maxprice; + basepp->relvols[relpp->ind] = totalrelvolume; + LP_autofills++; + return(0); + } + return(-1); +}*/ + +void LP_autopriceset(int32_t ind,void *ctx,int32_t dir,struct LP_priceinfo *basepp,struct LP_priceinfo *relpp,double price,char *refbase,char *refrel) +{ + static uint32_t lasttime; + double margin,minprice,newprice,oppomargin,fixedprice,factor,offset; double bid,ask; int32_t changed; + margin = basepp->sellmargins[relpp->ind]; + oppomargin = basepp->buymargins[relpp->ind]; + if ( (fixedprice= basepp->fixedprices[relpp->ind]) > SMALLVAL ) + { + LP_mypriceset(&changed,relpp->symbol,basepp->symbol,fixedprice); + //printf("autoprice FIXED %s/%s <- %.8f\n",basepp->symbol,relpp->symbol,fixedprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,fixedprice); + return; + } + if ( margin != 0. || oppomargin != 0. ) + { + offset = basepp->offsets[relpp->ind]; + factor = basepp->factors[relpp->ind]; + if ( fabs(price) < SMALLVAL && refbase != 0 && refrel != 0 ) + { + price = LP_myprice(&bid,&ask,refbase,refrel); + //printf("%s/%s USE ref %s/%s %.8f factor %.8f offset %.8f margin %.8f/%.8f\n",basepp->symbol,relpp->symbol,refbase,refrel,price,factor,offset,oppomargin,margin); + } + if ( LP_pricevalid(price) > 0 ) + { + if ( factor > SMALLVAL ) + { + //double tmp = (price * factor) + offset; + //printf("price %.8f -> %.8f factor %.8f offset %.8f margin %.8f [%.8f %.8f] [%.8f %.8f]\n",price,tmp,factor,offset,margin,(tmp * (1. + margin)),1./(tmp * (1. - margin)),(tmp * (1. - margin)),1./(tmp * (1. + margin))); + price = (price * factor) + offset; + } + if ( margin == 0. ) + margin = oppomargin; + //printf("min %.8f %s/%s %.8f dir.%d margin %.8f (%.8f %.8f)\n",basepp->minprices[relpp->ind],relpp->symbol,basepp->symbol,price,dir,margin,1. / (price * (1. - margin)),(price * (1. + margin))); + if ( dir > 0 ) + newprice = (1. / price) * (1. + margin); + else newprice = (price * (1. + margin)); + if ( (minprice= basepp->minprices[relpp->ind]) == 0. || price >= minprice ) + { + if ( ind >= 0 ) + { + if ( LP_autorefs[ind].lastask < SMALLVAL ) + LP_autorefs[ind].lastask = newprice; + else LP_autorefs[ind].lastask = (LP_autorefs[ind].lastask * 0.99) + (0.01 *newprice); + newprice = LP_autorefs[ind].lastask; + //printf("autopriceset %s/%s <- %.8f %.8f (%.8f %.8f)\n",basepp->symbol,relpp->symbol,price,newprice,LP_autorefs[ind].lastbid,LP_autorefs[ind].lastask); + } + LP_mypriceset(&changed,relpp->symbol,basepp->symbol,newprice); + if ( changed != 0 || time(NULL) > lasttime+LP_ORDERBOOK_DURATION*.777) + { + lasttime = (uint32_t)time(NULL); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,newprice); + } + } + } + } +} + +double LP_pricesparse(void *ctx,int32_t trexflag,char *retstr,struct LP_priceinfo *btcpp) +{ + //{"success":true,"message":"","result":[{"MarketName":"BTC-KMD","High":0.00040840,"Low":0.00034900,"Volume":328042.46061669,"Last":0.00037236,"BaseVolume":123.36439511,"TimeStamp":"2017-07-15T13:50:21.87","Bid":0.00035721,"Ask":0.00037069,"OpenBuyOrders":343,"OpenSellOrders":1690,"PrevDay":0.00040875,"Created":"2017-02-11T23:04:01.853"}, + //{"TradePairId":4762,"Label":"WAVES/BTC","AskPrice":0.00099989,"BidPrice":0.00097350,"Low":0.00095000,"High":0.00108838,"Volume":6501.24403100,"LastPrice":0.00098028,"BuyVolume":1058994.86554882,"SellVolume":2067.87377158,"Change":-7.46,"Open":0.00105926,"Close":0.00098028,"BaseVolume":6.52057452,"BuyBaseVolume":2.33098660,"SellBaseVolume":1167.77655709}, + int32_t i,j,n,iter; double price,kmdbtc,bid,ask,nxtkmd=0.; struct LP_priceinfo *coinpp,*refpp; char symbol[65],*name,*refcoin; cJSON *retjson,*array,*item; + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("got.(%s)\n",retstr); + kmdbtc = 0.; + refcoin = "BTC"; + refpp = btcpp; + if ( (array= jarray(&n,retjson,trexflag != 0 ? "result" : "Data")) != 0 ) + { + for (iter=0; iter<2; iter++) + { + for (i=0; i SMALLVAL && strcmp(symbol,"NXT") == 0 ) + nxtkmd = 0.5 * (bid + ask) / kmdbtc; + if ( (coinpp= LP_priceinfofind(symbol)) != 0 ) + { + coinpp->high[trexflag] = jdouble(item,"High"); + coinpp->low[trexflag] = jdouble(item,"Low"); + //coinpp->volume = jdouble(item,"Volume"); + //coinpp->btcvolume = jdouble(item,"BaseVolume"); + coinpp->last[trexflag] = jdouble(item,trexflag != 0 ? "Last" : "LastPrice"); + coinpp->bid[trexflag] = bid; + coinpp->ask[trexflag] = ask; + //coinpp->prevday = jdouble(item,"PrevDay"); + //printf("iter.%d trexflag.%d %s high %.8f, low %.8f, last %.8f hbla.(%.8f %.8f)\n",iter,trexflag,symbol,coinpp->high[trexflag],coinpp->low[trexflag],coinpp->last[trexflag],coinpp->bid[trexflag],coinpp->ask[trexflag]); + if ( coinpp->bid[trexflag] > SMALLVAL && coinpp->ask[trexflag] > SMALLVAL ) + { + price = 0.5 * (coinpp->bid[trexflag] + coinpp->ask[trexflag]); + if ( iter == 0 ) + { + if ( strcmp(symbol,"KMD") == 0 ) + kmdbtc = price; + } + else + { + if ( strcmp(symbol,"KMD") == 0 ) + continue; + //printf("(%s/%s) iter.%d trexflag.%d %s %.8f %.8f\n",refpp->symbol,coinpp->symbol,iter,trexflag,symbol,price,price/kmdbtc); + price /= kmdbtc; + } + if ( trexflag == 0 && coinpp->bid[1] > SMALLVAL && coinpp->ask[1] > SMALLVAL ) + { + //printf("have trex: iter.%d trexflag.%d %s %.8f %.8f\n",iter,trexflag,symbol,coinpp->bid[1],coinpp->ask[1]); + continue; + } + LP_autopriceset(-1,ctx,1,coinpp,refpp,price,0,0); + LP_autopriceset(-1,ctx,-1,refpp,coinpp,price,0,0); + } + } + } + } + } + refcoin = "KMD"; + if ( kmdbtc == 0. || (refpp= LP_priceinfofind("KMD")) == 0 ) + break; + } + } + free_json(retjson); + } + return(nxtkmd); +} + +double LP_autoprice_newprice(int32_t bidask,double price,double newprice) +{ + double gap; int32_t r; + if ( price > SMALLVAL && ((bidask == 0 && newprice < price) || (bidask != 0 && newprice > price)) ) + { + gap = fabs(newprice - price) * 2; + r = (rand() % 100); + if ( bidask == 0 ) + price -= (gap * r) / 100.; + else price += (gap * r) / 100.; + } + else if ( price > SMALLVAL ) + price = (price * 0.95) + (0.05 * newprice); + else price = newprice; + return(price); +} + +double LP_tickered_price(int32_t bidask,char *base,char *rel,double price,cJSON *tickerjson) +{ + int32_t i,n; cJSON *item; double basevol,relvol,itemprice; + //printf("%s %s/%s %.8f -> ",bidask == 0 ? "bid" : "ask",base,rel,price); + if ( (n= cJSON_GetArraySize(tickerjson)) > 0 ) + { + for (i=n-1; i>=0; i--) + { + // {"timestamp":1513235320,"KMD":860.45202538,"SUPERNET":20.00010000,"price":0.02324371} + item = jitem(tickerjson,i); + if ( (basevol= jdouble(item,base)) > SMALLVAL && (relvol= jdouble(item,rel)) > SMALLVAL ) + { + itemprice = (relvol / basevol); + //printf("%.8f ",itemprice); + price = LP_autoprice_newprice(bidask,price,itemprice); + } + } + } + //printf("-> %.8f\n",price); + return(price); +} + +void LP_autoprice_iter(void *ctx,struct LP_priceinfo *btcpp) +{ + static cJSON *tickerjson; static uint32_t lasttime; + char *retstr,*base,*rel; cJSON *retjson,*bid,*ask,*fundjson,*argjson; uint64_t bidsatoshis,asksatoshis; int32_t i,changed; double bidprice,askprice,bch_usd,bch_btc,nxtkmd,price,factor,offset,newprice,buymargin,sellmargin,price_btc,price_usd,kmd_btc,kmd_usd; struct LP_priceinfo *kmdpp,*fiatpp,*nxtpp,*basepp,*relpp; + if ( (retstr= issue_curlt("https://bittrex.com/api/v1.1/public/getmarketsummaries",LP_HTTP_TIMEOUT*10)) == 0 ) + { + printf("trex error getting marketsummaries\n"); + sleep(60); + return; + } + nxtkmd = LP_pricesparse(ctx,1,retstr,btcpp); + free(retstr); + if ( (retstr= issue_curlt("https://www.cryptopia.co.nz/api/GetMarkets",LP_HTTP_TIMEOUT*10)) == 0 ) + { + printf("cryptopia error getting marketsummaries\n"); + sleep(60); + return; + } + LP_pricesparse(ctx,0,retstr,btcpp); + free(retstr); + if ( (kmdpp= LP_priceinfofind("KMD")) != 0 ) + { + for (i=0; i<32; i++) + {break; + if ( (fiatpp= LP_priceinfofind(CURRENCIES[i])) != 0 ) + { + if ( (retjson= LP_paxprice(CURRENCIES[i])) != 0 ) + { + //printf("(%s %.8f %.8f) ",CURRENCIES[i],jdouble(retjson,"price"),jdouble(retjson,"invprice")); + price = jdouble(retjson,"price"); + LP_autopriceset(-1,ctx,1,fiatpp,kmdpp,price,0,0); + LP_autopriceset(-1,ctx,-1,kmdpp,fiatpp,price,0,0); + free_json(retjson); + } + } + } + } + if ( 0 && nxtkmd > SMALLVAL ) + { + for (i=0; i (%s) nxtkmd %.8f %.8f %.8f\n",assetids[i][1],assetids[i][0],jprint(retjson,0),nxtkmd,0.5*dstr(bidsatoshis + asksatoshis),price); + free_json(retjson); + } + } + } + } + if ( time(NULL) > lasttime+60 ) + { + if ( tickerjson != 0 ) + free_json(tickerjson); + if ( (retstr= LP_ticker("","")) != 0 ) + { + tickerjson = cJSON_Parse(retstr); + free(retstr); + } + } + kmd_btc = LP_CMCbtcprice(&kmd_usd,"komodo"); + bch_btc = LP_CMCbtcprice(&bch_usd,"bitcoin-cash"); + for (i=0; i SMALLVAL && LP_autorefs[i].fundask[0] != 0 && (askprice= jdouble(fundjson,LP_autorefs[i].fundask)) > SMALLVAL ) + { + price = (bidprice + askprice) * 0.5; + bidprice = (1. / price * (1. + buymargin)); + askprice = price * (1. + sellmargin); + LP_mypriceset(&changed,rel,base,bidprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,bidprice); + LP_mypriceset(&changed,base,rel,askprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,askprice); + //printf("price %.8f -> %.8f %.8f\n",price,bidprice,askprice); + } + LP_autorefs[i].count++; + } + free_json(fundjson); + } + } + else if ( strcmp(LP_autorefs[i].refrel,"coinmarketcap") == 0 ) + { + //printf("%s/%s for %s/%s margin %.8f/%.8f\n",base,rel,LP_autorefs[i].refbase,LP_autorefs[i].refrel,buymargin,sellmargin); + if ( (price_btc= LP_CMCbtcprice(&price_usd,LP_autorefs[i].refbase)) > SMALLVAL ) + { + if ( strcmp(rel,"KMD") == 0 && kmd_btc > SMALLVAL ) + price = kmd_btc / price_btc; + else if ( strcmp(rel,"BCH") == 0 && bch_btc > SMALLVAL ) + price = bch_btc / price_btc; + else if ( strcmp(rel,"BTC") == 0 ) + price = 1. / price_btc; + else continue; + if ( factor > 0. ) + price = (price * factor) + offset; + newprice = (price * (1. + buymargin)); + if ( LP_autorefs[i].lastbid < SMALLVAL ) + LP_autorefs[i].lastbid = newprice; + else LP_autorefs[i].lastbid = (LP_autorefs[i].lastbid * 0.99) + (0.01 * newprice); + newprice = LP_autorefs[i].lastbid; + LP_mypriceset(&changed,rel,base,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,rel,base,newprice); + //printf("%s/%s price %.8f margin %.8f/%.8f newprice %.8f %.8f\n",base,rel,price,buymargin,sellmargin,newprice,(1. / newprice) * (1. + sellmargin)); + newprice = (1. / price) * (1. + sellmargin); + if ( LP_autorefs[i].lastask < SMALLVAL ) + LP_autorefs[i].lastask = newprice; + else LP_autorefs[i].lastask = (LP_autorefs[i].lastask * 0.99) + (0.01 * newprice); + newprice = LP_autorefs[i].lastask; + LP_mypriceset(&changed,base,rel,newprice); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,base,rel,newprice); + } + } + else + { + basepp = LP_priceinfofind(base); + relpp = LP_priceinfofind(rel); + if ( basepp != 0 && relpp != 0 ) + { + //printf("check ref-autoprice %s/%s %f %f (%.8f %.8f)\n",LP_autorefs[i].refbase,LP_autorefs[i].refrel,relpp->fixedprices[basepp->ind],basepp->fixedprices[relpp->ind],LP_autorefs[i].lastbid,LP_autorefs[i].lastask); + LP_autopriceset(i,ctx,1,basepp,relpp,0.,LP_autorefs[i].refbase,LP_autorefs[i].refrel); + } + } + } +} + +void LP_autoprices_update(char *method,char *base,double basevol,char *rel,double relvol) +{ + int32_t i; double price,newprice; + if ( basevol > 0. && relvol > 0. ) + { + price = relvol/basevol; + for (i=0; i 0 ) + { + //printf("%s: autoprice ask update %s/%s %.8f vs myprice %.8f/%.8f -> %.8f\n",method,base,rel,price,LP_autorefs[i].lastbid,LP_autorefs[i].lastask,newprice); + LP_autorefs[i].lastask = newprice; + } // else printf("%s: autoprice ask skip update %s/%s %.8f vs myprice %.8f/%.8f -> %.8f\n",method,base,rel,price,LP_autorefs[i].lastbid,LP_autorefs[i].lastask,newprice); + } + else if ( strcmp(LP_autorefs[i].rel,base) == 0 && strcmp(rel,LP_autorefs[i].base) == 0 ) + { + newprice = (LP_autorefs[i].lastbid * 0.9) + (0.1 * price); + if ( LP_autorefs[i].lastbid > 0 ) + { + //printf("%s: autoprice bid update %s/%s %.8f vs myprice %.8f/%.8f -> %.8f\n",method,base,rel,price,LP_autorefs[i].lastbid,LP_autorefs[i].lastask,newprice); + LP_autorefs[i].lastbid = newprice; + } // else printf("%s: autoprice bid skip update %s/%s %.8f vs myprice %.8f/%.8f -> %.8f\n",method,base,rel,price,LP_autorefs[i].lastbid,LP_autorefs[i].lastask,newprice); + } + } + } +} + +int32_t LP_autoprice(void *ctx,char *base,char *rel,cJSON *argjson) +{ + //curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.1,\"refbase\":\"KMD\",\refrel\":\"BTC\",\"factor\":15000,\"margin\":0.01}" + struct LP_priceinfo *basepp,*relpp; int32_t i,retval = -1; char *fundvalue_bid,*fundvalue_ask,*refbase="",*refrel=""; double margin,minprice,buymargin,sellmargin,offset,factor,fixedprice; cJSON *fundvalue; + //printf("autoprice.(%s %s) %s\n",base,rel,jprint(argjson,0)); + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + if ( jobj(argjson,"minprice") != 0 ) + minprice = jdouble(argjson,"minprice"); + else minprice = 0.; + if ( (margin= jdouble(argjson,"margin")) == 0. ) + { + buymargin = jdouble(argjson,"buymargin"); + sellmargin = jdouble(argjson,"sellmargin"); + } + else + { + buymargin = margin; + sellmargin = margin; + } + offset = jdouble(argjson,"offset"); + factor = jdouble(argjson,"factor"); + fixedprice = jdouble(argjson,"fixed"); + basepp->fixedprices[relpp->ind] = fixedprice; + basepp->minprices[relpp->ind] = minprice; + if ( jobj(argjson,"maxprice") != 0 ) + relpp->minprices[basepp->ind] = 1. / jdouble(argjson,"maxprice"); + basepp->buymargins[relpp->ind] = buymargin; + basepp->sellmargins[relpp->ind] = sellmargin; + basepp->offsets[relpp->ind] = offset; + basepp->factors[relpp->ind] = factor; + refbase = jstr(argjson,"refbase"); + refrel = jstr(argjson,"refrel"); + fundvalue_bid = jstr(argjson,"fundvalue_bid"); + fundvalue_ask = jstr(argjson,"fundvalue_ask"); + if ( fundvalue_bid != 0 || fundvalue_ask != 0 || fixedprice > SMALLVAL || (refbase != 0 && refrel != 0) ) + { + if ( fixedprice > SMALLVAL ) + { + refbase = base; + refrel = rel; + } + for (i=0; isymbol,sell->symbol); + requestid = quoteid = 0; + LP_myprice(&bid,&ask,buy->symbol,sell->symbol); + maxprice = ask; + if ( setbaserel != 0 ) + { + strcpy(LP_portfolio_base,""); + strcpy(LP_portfolio_rel,""); + LP_portfolio_relvolume = 0.; + } + printf("pending.%d base buy.%s, rel sell.%s relvolume %f maxprice %.8f (%.8f %.8f)\n",G.LP_pendingswaps,buy->symbol,sell->symbol,sell->relvolume,maxprice,bid,ask); + if ( LP_pricevalid(maxprice) > 0 ) + { + relvolume = sell->relvolume; + for (iter=0; iter<2; iter++) + { + if ( relvolume < dstr(LP_MIN_TXFEE) ) + break; + if ( LP_address_myutxopair(&A,0,utxos,max,sell,sell->symbol,txfee,relvolume,maxprice,desttxfee) == 0 ) + //if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + if ( (retstr2= LP_autobuy(ctx,"127.0.0.1",-1,buy->symbol,sell->symbol,maxprice,relvolume,60,24*3600,gui,LP_lastnonce+1,zero,1)) != 0 ) + { + if ( (retjson2= cJSON_Parse(retstr2)) != 0 ) + { + if ( (requestid= juint(retjson2,"requestid")) != 0 && (quoteid= juint(retjson2,"quoteid")) != 0 ) + { + + } + free_json(retjson2); + } + printf("%s relvolume %.8f LP_autotrade.(%s)\n",sell->symbol,relvolume,retstr2); + free(retstr2); + } + if ( requestid != 0 && quoteid != 0 ) + break; + } else printf("cant find alice %.8f %s\n",relvolume,sell->symbol); + if ( iter == 0 ) + { + for (i=0; i<100; i++) + { + relvolume *= .99; + if ( LP_address_myutxopair(&A,0,utxos,max,sell,sell->symbol,txfee,relvolume,maxprice,desttxfee) == 0 ) + //if ( LP_utxo_bestfit(sell->symbol,SATOSHIDEN * relvolume) != 0 ) + { + printf("i.%d relvolume %.8f from %.8f\n",i,relvolume,sell->relvolume); + break; + } + } + } + } + } + else if ( setbaserel != 0 ) + { + strcpy(LP_portfolio_base,buy->symbol); + strcpy(LP_portfolio_rel,sell->symbol); + LP_portfolio_relvolume = sell->relvolume; + } + *requestidp = requestid; + *quoteidp = quoteid; + if ( requestid != 0 && quoteid != 0 ) + return(0); + else return(-1); +} + +int32_t LP_portfolio_order(struct LP_portfoliotrade *trades,int32_t max,cJSON *array) +{ + int32_t i,j,m,n = 0; cJSON *item; struct LP_portfoliotrade coins[256]; + memset(coins,0,sizeof(coins)); + if ( (m= cJSON_GetArraySize(array)) > 0 ) + { + for (i=j=0; i SMALLVAL && coins[j].buycoin[0] != 0 ) + j++; + } + if ( (m= j) > 1 ) + { + for (i=n=0; i 0. ) + { + trades[n].metric = (coins[i].metric - coins[j].metric); + strcpy(trades[n].buycoin,coins[i].buycoin); + strcpy(trades[n].sellcoin,coins[j].buycoin); + printf("buy %s %f, sell %s %f -> %f\n",trades[n].buycoin,coins[i].metric,trades[n].sellcoin,coins[j].metric,trades[n].metric); + } + else + { + trades[n].metric = (coins[j].metric - coins[i].metric); + strcpy(trades[n].buycoin,coins[j].buycoin); + strcpy(trades[n].sellcoin,coins[i].buycoin); + printf("buy %s %f, sell %s %f -> %f\n",trades[n].buycoin,coins[j].metric,trades[n].sellcoin,coins[i].metric,trades[n].metric); + } + n++; + if ( n >= max ) + break; + } + revsortds((void *)trades,n,sizeof(*trades)); + for (i=0; i %f\n",i,trades[i].buycoin,trades[i].sellcoin,trades[i].metric); + } + } + return(n); +} + +void prices_loop(void *ctx) +{ + char *retstr; cJSON *retjson,*array; char *buycoin,*sellcoin; struct iguana_info *buy,*sell; uint32_t requestid,quoteid; int32_t i,n,m; struct LP_portfoliotrade trades[256]; struct LP_priceinfo *btcpp; + strcpy(prices_loop_stats.name,"prices_loop"); + prices_loop_stats.threshold = 191000.; + while ( LP_STOP_RECEIVED == 0 ) + { + //printf("prices loop autoprices.%d autorefs.%d\n",LP_autoprices,num_LP_autorefs); + LP_millistats_update(&prices_loop_stats); + LP_tradebots_timeslice(ctx); + if ( (btcpp= LP_priceinfofind("BTC")) == 0 ) + { + printf("prices_loop BTC not in LP_priceinfofind\n"); + sleep(60); + continue; + } + if ( LP_autoprices != 0 ) + LP_autoprice_iter(ctx,btcpp); + if ( (retstr= LP_portfolio()) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (buycoin= jstr(retjson,"buycoin")) != 0 && (buy= LP_coinfind(buycoin)) != 0 && (sellcoin= jstr(retjson,"sellcoin")) != 0 && (sell= LP_coinfind(sellcoin)) != 0 && buy->inactive == 0 && sell->inactive == 0 ) + { + if ( LP_portfolio_trade(ctx,&requestid,"eid,buy,sell,sell->relvolume,1,"portfolio") < 0 ) + { + array = jarray(&m,retjson,"portfolio"); + if ( array != 0 && (n= LP_portfolio_order(trades,(int32_t)(sizeof(trades)/sizeof(*trades)),array)) > 0 ) + { + for (i=0; irelvolume,0,"portfolio") == 0 ) + break; + } + } + } + } + } + free_json(retjson); + } + free(retstr); + } + sleep(30); + } +} + + diff --git a/iguana/exchanges/LP_prices.c b/iguana/exchanges/LP_prices.c new file mode 100644 index 000000000..a887331da --- /dev/null +++ b/iguana/exchanges/LP_prices.c @@ -0,0 +1,1275 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_prices.c +// marketmaker +// + +struct LP_orderbookentry +{ + bits256 pubkey; + double price; + int64_t avesatoshis,maxsatoshis,depth,dynamictrust; + uint32_t timestamp; + int32_t numutxos; + char coinaddr[64]; +}; + +struct LP_priceinfo +{ + char symbol[68]; + uint64_t coinbits; + int32_t ind,pad; + double diagval,high[2],low[2],last[2],bid[2],ask[2]; + double relvals[LP_MAXPRICEINFOS]; + double myprices[LP_MAXPRICEINFOS]; + double minprices[LP_MAXPRICEINFOS]; // autoprice + double fixedprices[LP_MAXPRICEINFOS]; // fixedprices + double buymargins[LP_MAXPRICEINFOS]; + double sellmargins[LP_MAXPRICEINFOS]; + double offsets[LP_MAXPRICEINFOS]; + double factors[LP_MAXPRICEINFOS]; +} LP_priceinfos[LP_MAXPRICEINFOS]; +int32_t LP_numpriceinfos; + +struct LP_cacheinfo +{ + UT_hash_handle hh; + struct LP_quoteinfo Q; + uint8_t key[sizeof(bits256)+sizeof(uint64_t)*2+sizeof(int32_t)]; + double price; + uint32_t timestamp; +} *LP_cacheinfos; + +void LP_priceinfos_clear() +{ + int32_t i; struct LP_priceinfo *pp; + for (i=0; imyprices,0,sizeof(pp->myprices)); + memset(pp->minprices,0,sizeof(pp->minprices)); + memset(pp->fixedprices,0,sizeof(pp->fixedprices)); + memset(pp->buymargins,0,sizeof(pp->buymargins)); + memset(pp->sellmargins,0,sizeof(pp->sellmargins)); + memset(pp->offsets,0,sizeof(pp->offsets)); + memset(pp->factors,0,sizeof(pp->factors)); + } +} + +float LP_pubkey_price(int32_t *numutxosp,int64_t *avesatoshisp,int64_t *maxsatoshisp,struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind) +{ + struct LP_pubkey_quote *pq,*tmp; int32_t scale; int64_t scale64; + *numutxosp = 0; + *avesatoshisp = *maxsatoshisp = 0; + DL_FOREACH_SAFE(pubp->quotes,pq,tmp) + { + if ( baseind == pq->baseind && relind == pq->relind ) + { + if ( (scale= pq->scale) == 0 ) + pq->scale = scale = 6; + scale64 = 1; + while ( scale > 0 ) + { + scale64 *= 10; + scale--; + } + *numutxosp = pq->numutxos; + *avesatoshisp = pq->aveutxo * scale64; + *maxsatoshisp = pq->maxutxo * scale64; + return(pq->price); + } + } + return(0); +} + +void LP_pubkey_update(struct LP_pubkey_info *pubp,uint32_t baseind,uint32_t relind,float price,int64_t balance,char *utxocoin,int32_t numutxos,int64_t minutxo,int64_t maxutxo) +{ + struct LP_pubkey_quote *pq,*tmp; int64_t aveutxo,scale64,ave64,max64; int32_t scale; + DL_FOREACH_SAFE(pubp->quotes,pq,tmp) + { + if ( baseind == pq->baseind && relind == pq->relind ) + break; + pq = 0; + } + if ( pq == 0 ) + { + pq = calloc(1,sizeof(*pq)); + pq->baseind = baseind; + pq->relind = relind; + pq->scale = 6; // millions of SATOSHIS, ie. 0.01 + DL_APPEND(pubp->quotes,pq); // already serialized as only path is via stats_JSON() + //printf("create pubp quotes %d/%d\n",baseind,relind); + } + //printf("%d/%d price %.8f balance %.8f %s num.%d %.8f %.8f\n",baseind,relind,price,dstr(balance),utxocoin,numutxos,dstr(minutxo),dstr(maxutxo)); + pq->price = price; + if ( utxocoin != 0 && utxocoin[0] != 0 ) + { + if ( (scale= pq->scale) == 0 ) + pq->scale = scale = 6; + scale64 = 1; + while ( scale > 0 ) + { + scale64 *= 10; + scale--; + } + if ( numutxos >= 256 ) + pq->numutxos = 255; + else pq->numutxos = numutxos; + aveutxo = (balance + (scale64>>1)) / numutxos; + if ( (ave64= (aveutxo / scale64)) >= (1LL << 32) ) + ave64 = (1LL << 32) - 1; + max64 = ((maxutxo + (scale64>>1)) / scale64); + if ( max64 >= (1LL << 32) ) + max64 = (1LL << 32) - 1; + pq->aveutxo = (uint32_t)ave64; + pq->maxutxo = (uint32_t)max64; + if ( 0 ) + { + printf("price %.8f base.%s rel.%s utxocoin.%s balance %.8f numutxos.%u %u scale64 = %llu, ave %llu, ave32 %u (%llu) max32 %u (%llu)\n",price,LP_priceinfos[baseind].symbol,LP_priceinfos[relind].symbol,utxocoin,dstr(balance),numutxos,pq->numutxos,(long long)scale64,(long long)aveutxo,pq->aveutxo,(long long)pq->aveutxo * scale64,pq->maxutxo,(long long)pq->maxutxo * scale64); + int64_t avesatoshis,maxsatoshis; + price = LP_pubkey_price(&numutxos,&avesatoshis,&maxsatoshis,pubp,baseind,relind); + printf("checkprice %.8f numutxos.%d ave %.8f max %.8f\n",price,numutxos,dstr(avesatoshis),dstr(maxsatoshis)); + } + } +} + +struct LP_priceinfo *LP_priceinfo(int32_t ind) +{ + if ( ind < 0 || ind >= LP_MAXPRICEINFOS ) + return(0); + else return(&LP_priceinfos[ind]); +} + +char *LP_priceinfostr(int32_t ind) +{ + if ( ind < 0 || ind >= LP_MAXPRICEINFOS ) + return("UNKNOWN"); + else return(LP_priceinfos[ind].symbol); +} + +int32_t LP_pricevalid(double price) +{ + if ( price > SMALLVAL && isnan(price) == 0 && price < SATOSHIDEN ) + return(1); + else return(0); +} + +struct LP_priceinfo *LP_priceinfofind(char *symbol) +{ + int32_t i; struct LP_priceinfo *pp; uint64_t coinbits; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + if ( LP_numpriceinfos > 0 ) + { + coinbits = stringbits(symbol); + pp = LP_priceinfos; + for (i=0; icoinbits == coinbits ) + return(pp); + } + return(0); +} + +int32_t LP_priceinfoind(char *symbol) +{ + struct LP_priceinfo *pp; + if ( (pp= LP_priceinfofind(symbol)) != 0 ) + return(pp->ind); + else return(-1); +} + +struct LP_priceinfo *LP_priceinfoptr(int32_t *indp,char *base,char *rel) +{ + struct LP_priceinfo *basepp,*relpp; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + *indp = relpp->ind; + return(basepp); + } + else + { + *indp = -1; + return(0); + } +} + +int32_t LP_cachekey(uint8_t *key,char *base,char *rel,bits256 txid,int32_t vout) +{ + uint64_t basebits,relbits; int32_t offset = 0; + basebits = stringbits(base); + relbits = stringbits(rel); + memcpy(&key[offset],&basebits,sizeof(basebits)), offset += sizeof(basebits); + memcpy(&key[offset],&relbits,sizeof(relbits)), offset += sizeof(relbits); + memcpy(&key[offset],&txid,sizeof(txid)), offset += sizeof(txid); + memcpy(&key[offset],&vout,sizeof(vout)), offset += sizeof(vout); + return(offset); +} + +struct LP_cacheinfo *LP_cachefind(char *base,char *rel,bits256 txid,int32_t vout) +{ + struct LP_cacheinfo *ptr=0; uint8_t key[sizeof(bits256)+sizeof(uint64_t)*2+sizeof(vout)]; + if ( base == 0 || rel == 0 ) + return(0); + if ( LP_cachekey(key,base,rel,txid,vout) == sizeof(key) ) + { + portable_mutex_lock(&LP_cachemutex); + HASH_FIND(hh,LP_cacheinfos,key,sizeof(key),ptr); + portable_mutex_unlock(&LP_cachemutex); + } else printf("LP_cachefind keysize mismatch?\n"); + if ( 0 && ptr != 0 && ptr->timestamp != 0 && ptr->timestamp < time(NULL)-LP_CACHEDURATION ) + { + printf("expire price %.8f\n",ptr->price); + ptr->price = 0.; + ptr->timestamp = 0; + memset(&ptr->Q,0,sizeof(ptr->Q)); + } + return(ptr); +} + +struct LP_pubkey_info *LP_pubkey_rmd160find(uint8_t rmd160[20]) +{ + struct LP_pubkey_info *pubp=0,*tmp; + portable_mutex_lock(&LP_pubkeymutex); + HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) + { + if ( memcmp(rmd160,pubp->rmd160,sizeof(pubp->rmd160)) == 0 ) + break; + pubp = 0; + } + portable_mutex_unlock(&LP_pubkeymutex); + return(pubp); +} + +struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr) +{ + uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkey_info *pubp; + HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap); + if ( ap != 0 && bits256_nonz(ap->pubkey) == 0 ) + { + bitcoin_addr2rmd160(coin->symbol,coin->taddr,&addrtype,rmd160,coinaddr); + if ( (pubp= LP_pubkey_rmd160find(rmd160)) != 0 ) + { + ap->pubkey = pubp->pubkey; + memcpy(ap->pubsecp,pubp->pubsecp,sizeof(ap->pubsecp)); + } + } + return(ap); +} + +struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr) +{ + uint8_t rmd160[20],addrtype; struct LP_address *ap; struct LP_pubkey_info *pubp; + ap = calloc(1,sizeof(*ap)); + safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr)); + bitcoin_addr2rmd160(coin->symbol,coin->taddr,&addrtype,rmd160,coinaddr); + if ( (pubp= LP_pubkey_rmd160find(rmd160)) != 0 ) + { + ap->pubkey = pubp->pubkey; + memcpy(ap->pubsecp,pubp->pubsecp,sizeof(ap->pubsecp)); + } + //printf("LP_ADDRESS %s ADD.(%s)\n",coin->symbol,coinaddr); + HASH_ADD_KEYPTR(hh,coin->addresses,ap->coinaddr,strlen(ap->coinaddr),ap); + return(ap); +} + +struct LP_pubkey_info *LP_pubkeyfind(bits256 pubkey) +{ + struct LP_pubkey_info *pubp=0; + portable_mutex_lock(&LP_pubkeymutex); + HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp); + portable_mutex_unlock(&LP_pubkeymutex); + return(pubp); +} + +struct LP_pubkey_info *LP_pubkeyadd(bits256 pubkey) +{ + char str[65]; struct LP_pubkey_info *pubp=0; + portable_mutex_lock(&LP_pubkeymutex); + HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp); + if ( pubp == 0 ) + { + pubp = calloc(1,sizeof(*pubp)); + pubp->pubkey = pubkey; + pubp->pairsock = -1; + if ( bits256_cmp(G.LP_mypub25519,pubkey) == 0 ) + { + memcpy(pubp->rmd160,G.LP_myrmd160,sizeof(pubp->rmd160)); + memcpy(pubp->pubsecp,G.LP_pubsecp,sizeof(pubp->pubsecp)); + } + HASH_ADD_KEYPTR(hh,LP_pubkeyinfos,&pubp->pubkey,sizeof(pubp->pubkey),pubp); + HASH_FIND(hh,LP_pubkeyinfos,&pubkey,sizeof(pubkey),pubp); + if ( pubp == 0 ) + printf("pubkeyadd find %s error after add\n",bits256_str(str,pubp->pubkey)); + } + portable_mutex_unlock(&LP_pubkeymutex); + return(pubp); +} + +int32_t LP_pubkey_istrusted(bits256 pubkey) +{ + struct LP_pubkey_info *pubp; + if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) + return(pubp->istrusted != 0); + return(0); +} + +char *LP_pubkey_trustset(bits256 pubkey,uint32_t trustval) +{ + struct LP_pubkey_info *pubp; + if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) + { + pubp->istrusted = trustval; + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"pubkey not found\"}")); +} + +char *LP_pubkey_trusted() +{ + struct LP_pubkey_info *pubp,*tmp; cJSON *array = cJSON_CreateArray(); + HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) + { + if ( pubp->istrusted != 0 ) + jaddibits256(array,pubp->pubkey); + } + return(jprint(array,1)); +} + +int64_t LP_unspents_metric(struct iguana_info *coin,char *coinaddr) +{ + cJSON *array,*item; int32_t i,n; int64_t metric=0,total; + //LP_listunspent_both(coin->symbol,coinaddr,0); + if ( (array= LP_address_utxos(coin,coinaddr,1)) != 0 ) + { + total = 0; + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; imatrix[baseid][relid]; + if ( LP_pricevalid(price) > 0 ) + { + item = cJSON_CreateArray(); + jaddistr(item,base); + jaddistr(item,LP_priceinfos[relid].symbol); + jaddinum(item,price); + jaddi(array,item); + } + } + } + jaddbits256(obj,"pubkey",pubp->pubkey); + init_hexbytes_noT(hexstr,pubp->rmd160,sizeof(pubp->rmd160)); + jaddstr(obj,"rmd160",hexstr); + init_hexbytes_noT(hexstr2,pubp->pubsecp,sizeof(pubp->pubsecp)); + jaddstr(obj,"pubsecp",hexstr2); + init_hexbytes_noT(sigstr,pubp->sig,pubp->siglen); + jaddstr(obj,"sig",sigstr); + jaddnum(obj,"timestamp",pubp->timestamp); + jadd(obj,"asks",array); + if ( pubp->istrusted != 0 ) + jaddnum(obj,"istrusted",pubp->istrusted); + return(obj); +} + +char *LP_prices() +{ + struct LP_pubkey_info *pubp,*tmp; cJSON *array = cJSON_CreateArray(); + HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) + { + jaddi(array,LP_pubkeyjson(pubp)); + } + return(jprint(array,1)); +} + +double LP_pricecache(struct LP_quoteinfo *qp,char *base,char *rel,bits256 txid,int32_t vout) +{ + struct LP_cacheinfo *ptr; + if ( (ptr= LP_cachefind(base,rel,txid,vout)) != 0 ) + { + if ( qp != 0 ) + (*qp) = ptr->Q; + if ( ptr->price == 0. && ptr->Q.satoshis > ptr->Q.txfee ) + { + ptr->price = (double)ptr->Q.destsatoshis / (ptr->Q.satoshis - ptr->Q.txfee); + if ( LP_pricevalid(ptr->price) <= 0 ) + ptr->price = 0.; + printf("LP_pricecache: set %s/%s ptr->price %.8f\n",base,rel,ptr->price); + } + //printf(">>>>>>>>>> found %s/%s %.8f\n",base,rel,ptr->price); + return(ptr->price); + } + //char str[65]; printf("cachemiss %s/%s %s/v%d\n",base,rel,bits256_str(str,txid),vout); + return(0.); +} + +void LP_priceinfoupdate(char *base,char *rel,double price) +{ + struct LP_priceinfo *basepp,*relpp; + if ( LP_pricevalid(price) > 0 ) + { + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + dxblend(&basepp->relvals[relpp->ind],price,0.9); + dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); + //basepp->relvals[relpp->ind] = price; + //relpp->relvals[basepp->ind] = 1. / price; + } + } +} + +double LP_myprice(double *bidp,double *askp,char *base,char *rel) +{ + struct LP_priceinfo *basepp,*relpp; double val; + *bidp = *askp = 0.; + if ( (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + *askp = basepp->myprices[relpp->ind]; + if ( LP_pricevalid(*askp) > 0 ) + { + val = relpp->myprices[basepp->ind]; + if ( LP_pricevalid(val) > 0 ) + { + *bidp = 1. / val; + return((*askp + *bidp) * 0.5); + } + else + { + *bidp = 0.; + return(*askp); + } + } + else + { + val = relpp->myprices[basepp->ind]; + if ( LP_pricevalid(val) > 0 ) + { + *bidp = 1. / val; + *askp = 0.; + return(*bidp); + } + } + } + return(0.); +} + +char *LP_myprices() +{ + int32_t baseid,relid; double bid,ask; char *base,*rel; cJSON *item,*array; + array = cJSON_CreateArray(); + for (baseid=0; baseid SMALLVAL ) + { + item = cJSON_CreateObject(); + jaddstr(item,"base",base); + jaddstr(item,"rel",rel); + jaddnum(item,"bid",bid); + jaddnum(item,"ask",ask); + jaddi(array,item); + } + } + } + return(jprint(array,1)); +} + +int32_t LP_mypriceset(int32_t *changedp,char *base,char *rel,double price) +{ + struct LP_priceinfo *basepp,*relpp; struct LP_pubkey_info *pubp; double minprice,maxprice; + *changedp = 0; + //if ( strcmp("DEX",base) == 0 || strcmp("DEX",rel) == 0 ) + // printf("%s/%s setprice %.8f\n",base,rel,price); + if ( base != 0 && rel != 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + + if ( price == 0. || fabs(basepp->myprices[relpp->ind] - price)/price > 0.001 ) + *changedp = 1; + if ( price == 0. ) + { + relpp->minprices[basepp->ind] = 0.; + relpp->fixedprices[basepp->ind] = 0.; + relpp->buymargins[basepp->ind] = 0.; + relpp->sellmargins[basepp->ind] = 0.; + relpp->offsets[basepp->ind] = 0.; + relpp->factors[basepp->ind] = 0.; + } + else if ( (minprice= basepp->minprices[relpp->ind]) > SMALLVAL && price < minprice ) + { + printf("%s/%s price %.8f less than minprice %.8f\n",base,rel,price,minprice); + price = minprice; + } + else if ( (maxprice= relpp->minprices[basepp->ind]) > SMALLVAL ) + { + if ( price > (1. / maxprice) ) + { + printf("%s/%s price %.8f less than maxprice %.8f, more than %.8f\n",base,rel,price,maxprice,1./maxprice); + price = (1. / maxprice); + } + } + /*else if ( basepp->myprices[relpp->ind] > SMALLVAL ) + { + price = (basepp->myprices[relpp->ind] * 0.9) + (0.1 * price); + }*/ + basepp->myprices[relpp->ind] = price; // ask + //printf("LP_mypriceset base.%s rel.%s <- price %.8f\n",base,rel,price); + //relpp->myprices[basepp->ind] = (1. / price); // bid + if ( (pubp= LP_pubkeyadd(G.LP_mypub25519)) != 0 ) + { + pubp->timestamp = (uint32_t)time(NULL); + LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,0,0,0,0,0); + //pubp->matrix[basepp->ind][relpp->ind] = price; + //pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; + //pubp->matrix[relpp->ind][basepp->ind] = (1. / price); + } + return(0); + } else return(-1); +} + +double LP_price(char *base,char *rel) +{ + struct LP_priceinfo *basepp; int32_t relind; double price = 0.; + if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 ) + { + if ( (price= basepp->myprices[relind]) == 0. ) + { + price = basepp->relvals[relind]; + } + } + return(price); +} + +double LP_getmyprice(char *base,char *rel) +{ + struct LP_priceinfo *basepp; int32_t relind; double price = 0.; + if ( (basepp= LP_priceinfoptr(&relind,base,rel)) != 0 ) + { + if ( (price= basepp->myprices[relind]) == 0. ) + { + } + } + return(price); +} + +cJSON *LP_priceinfomatrix(int32_t usemyprices) +{ + int32_t i,j,n,m; double total,sum,val; struct LP_priceinfo *pp; uint32_t now; struct LP_cacheinfo *ptr,*tmp; cJSON *vectorjson = cJSON_CreateObject(); + now = (uint32_t)time(NULL); + HASH_ITER(hh,LP_cacheinfos,ptr,tmp) + { + if ( ptr->timestamp < now-3600*2 || ptr->price == 0. ) + continue; + LP_priceinfoupdate(ptr->Q.srccoin,ptr->Q.destcoin,ptr->price); + } + pp = LP_priceinfos; + total = m = 0; + for (i=0; idiagval = sum = n = 0; + for (j=0; jmyprices[j]) == 0. ) + val = pp->relvals[j]; + if ( val > SMALLVAL ) + { + sum += val; + n++; + } + } + if ( n > 0 ) + { + pp->diagval = sum / n; + total += pp->diagval, m++; + } + } + if ( m > 0 ) + { + pp = LP_priceinfos; + for (i=0; idiagval > SMALLVAL ) + { + pp->diagval /= total; + jaddnum(vectorjson,pp->symbol,pp->diagval); + } + } + } + return(vectorjson); +} + +struct LP_priceinfo *LP_priceinfoadd(char *symbol) +{ + struct LP_priceinfo *pp; cJSON *retjson; + if ( symbol == 0 ) + return(0); + if ( LP_numpriceinfos >= sizeof(LP_priceinfos)/sizeof(*LP_priceinfos) ) + { + printf("cant add any more priceinfos\n"); + return(0); + } + pp = &LP_priceinfos[LP_numpriceinfos]; + memset(pp,0,sizeof(*pp)); + safecopy(pp->symbol,symbol,sizeof(pp->symbol)); + pp->coinbits = stringbits(symbol); + pp->ind = LP_numpriceinfos++; + LP_numpriceinfos++; + if ( (retjson= LP_priceinfomatrix(0)) != 0 ) + free_json(retjson); + return(pp); +} + +struct LP_cacheinfo *LP_cacheadd(char *base,char *rel,bits256 txid,int32_t vout,double price,struct LP_quoteinfo *qp) +{ + char str[65]; struct LP_cacheinfo *ptr=0; + if ( base == 0 || rel == 0 ) + return(0); + if ( LP_pricevalid(price) > 0 ) + { + if ( (ptr= LP_cachefind(base,rel,txid,vout)) == 0 ) + { + ptr = calloc(1,sizeof(*ptr)); + if ( LP_cachekey(ptr->key,base,rel,txid,vout) == sizeof(ptr->key) ) + { + portable_mutex_lock(&LP_cachemutex); + HASH_ADD(hh,LP_cacheinfos,key,sizeof(ptr->key),ptr); + portable_mutex_unlock(&LP_cachemutex); + } else printf("LP_cacheadd keysize mismatch?\n"); + } + ptr->Q = *qp; + ptr->timestamp = (uint32_t)time(NULL); + if ( price != ptr->price ) + { + ptr->price = price; + LP_priceinfoupdate(base,rel,price); + printf("updated %s/v%d %s/%s %llu price %.8f\n",bits256_str(str,txid),vout,base,rel,(long long)qp->satoshis,price); + } else ptr->price = price; + } + return(ptr); +} + +static int _cmp_orderbook(const void *a,const void *b) +{ + int32_t retval = 0; +#define ptr_a (*(struct LP_orderbookentry **)a)->price +#define ptr_b (*(struct LP_orderbookentry **)b)->price + if ( ptr_b > ptr_a ) + retval = -1; + else if ( ptr_b < ptr_a ) + retval = 1; + else + { +#undef ptr_a +#undef ptr_b +#define ptr_a ((struct LP_orderbookentry *)a)->maxsatoshis +#define ptr_b ((struct LP_orderbookentry *)b)->maxsatoshis + if ( ptr_b > ptr_a ) + return(-1); + else if ( ptr_b < ptr_a ) + return(1); + } + // printf("%.8f vs %.8f -> %d\n",ptr_a,ptr_b,retval); + return(retval); +#undef ptr_a +#undef ptr_b +} + +static int _revcmp_orderbook(const void *a,const void *b) +{ + int32_t retval = 0; +#define ptr_a (*(struct LP_orderbookentry **)a)->price +#define ptr_b (*(struct LP_orderbookentry **)b)->price + if ( ptr_b > ptr_a ) + retval = 1; + else if ( ptr_b < ptr_a ) + retval = -1; + else + { +#undef ptr_a +#undef ptr_b +#define ptr_a ((struct LP_orderbookentry *)a)->maxsatoshis +#define ptr_b ((struct LP_orderbookentry *)b)->maxsatoshis + if ( ptr_b > ptr_a ) + return(-1); + else if ( ptr_b < ptr_a ) + return(1); + } + // printf("%.8f vs %.8f -> %d\n",ptr_a,ptr_b,retval); + return(retval); +#undef ptr_a +#undef ptr_b +} + +cJSON *LP_orderbookjson(char *symbol,struct LP_orderbookentry *op) +{ + cJSON *item = cJSON_CreateObject(); + if ( LP_pricevalid(op->price) > 0 ) + { + jaddstr(item,"coin",symbol); + jaddstr(item,"address",op->coinaddr); + jaddnum(item,"price",op->price); + jaddnum(item,"numutxos",op->numutxos); + jaddnum(item,"avevolume",dstr(op->avesatoshis)*0.8); + jaddnum(item,"maxvolume",dstr(op->maxsatoshis)*0.8); + jaddnum(item,"depth",dstr(op->depth)*0.8); + jaddbits256(item,"pubkey",op->pubkey); + jaddnum(item,"age",time(NULL)-op->timestamp); + jaddnum(item,"zcredits",dstr(op->dynamictrust)); + } + return(item); +} + +struct LP_orderbookentry *LP_orderbookentry(char *address,char *base,char *rel,double price,int32_t numutxos,int64_t avesatoshis,int64_t maxsatoshis,bits256 pubkey,uint32_t timestamp,int64_t balance,int64_t dynamictrust) +{ + struct LP_orderbookentry *op; + if ( (op= calloc(1,sizeof(*op))) != 0 ) + { + safecopy(op->coinaddr,address,sizeof(op->coinaddr)); + op->price = price; + op->numutxos = numutxos; + op->avesatoshis = avesatoshis; + op->maxsatoshis = maxsatoshis; + op->pubkey = pubkey; + op->timestamp = timestamp; + op->depth = balance; + op->dynamictrust = dynamictrust; + } + return(op); +} + +void LP_pubkeys_query() +{ + uint8_t zeroes[20]; bits256 zero; cJSON *reqjson; struct LP_pubkey_info *pubp=0,*tmp; + memset(zero.bytes,0,sizeof(zero)); + memset(zeroes,0,sizeof(zeroes)); + HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) + { + if ( memcmp(zeroes,pubp->rmd160,sizeof(pubp->rmd160)) == 0 && time(NULL) > pubp->lasttime+60 ) + { + pubp->lasttime = (uint32_t)time(NULL); + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","wantnotify"); + jaddbits256(reqjson,"pub",pubp->pubkey); + //printf("LP_pubkeys_query %s\n",jprint(reqjson,0)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + } + } +} + +int32_t LP_orderbook_utxoentries(uint32_t now,int32_t polarity,char *base,char *rel,struct LP_orderbookentry *(**arrayp),int32_t num,int32_t cachednum,int32_t duration) +{ + char coinaddr[64]; uint8_t zeroes[20]; struct LP_pubkey_info *pubp=0,*tmp; struct LP_priceinfo *basepp; struct LP_orderbookentry *op; struct LP_address *ap; struct iguana_info *basecoin; uint32_t oldest; double price; int32_t baseid,relid,n; int64_t maxsatoshis,balance,avesatoshis; + if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) + baseid = basepp->ind; + else return(num); + if ( (basecoin= LP_coinfind(base)) == 0 ) + return(-1); + now = (uint32_t)time(NULL); + oldest = now - duration; + memset(zeroes,0,sizeof(zeroes)); + HASH_ITER(hh,LP_pubkeyinfos,pubp,tmp) + { + if ( memcmp(zeroes,pubp->rmd160,sizeof(pubp->rmd160)) == 0 ) + { + //printf("skip pubp since no rmd160\n"); + continue; + } + if ( pubp->timestamp < oldest ) + continue; + bitcoin_address(base,coinaddr,basecoin->taddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); + avesatoshis = maxsatoshis = n = 0; + ap = 0; + if ( (price= LP_pubkey_price(&n,&avesatoshis,&maxsatoshis,pubp,baseid,relid)) > SMALLVAL ) //pubp->matrix[baseid][relid]) > SMALLVAL )//&& pubp->timestamps[baseid][relid] >= oldest ) + { + balance = avesatoshis * n; + //if ( (ap= LP_addressfind(basecoin,coinaddr)) != 0 ) + { + //n = LP_address_minmax(&balance,&minsatoshis,&maxsatoshis,ap); + if ( polarity > 0 ) + { + balance *= price; + avesatoshis *= price; + maxsatoshis *= price; + } + //printf("%s/%s %s n.%d ap->n.%d %.8f\n",base,rel,coinaddr,n,ap->n,dstr(ap->total)); + } + if ( (op= LP_orderbookentry(coinaddr,base,rel,polarity > 0 ? price : 1./price,n,avesatoshis,maxsatoshis,pubp->pubkey,pubp->timestamp,balance,pubp->dynamictrust)) != 0 ) + { + *arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1)); + (*arrayp)[num++] = op; + } + } + //printf("pubp.(%s) %.8f %p\n",coinaddr,price,ap); + } + return(num); +} + +char *LP_orderbook(char *base,char *rel,int32_t duration) +{ + uint32_t now,i; int64_t depth,askdepth=0,biddepth=0; struct LP_priceinfo *basepp=0,*relpp=0; struct LP_orderbookentry **bids = 0,**asks = 0; cJSON *retjson,*array; struct iguana_info *basecoin,*relcoin; int32_t n,numbids=0,numasks=0,cachenumbids,cachenumasks,baseid,relid,suppress_prefetch=0; + basecoin = LP_coinfind(base); + relcoin = LP_coinfind(rel); + if ( basecoin == 0 || relcoin == 0 ) + return(clonestr("{\"error\":\"base or rel not added\"}")); + if ( (basepp= LP_priceinfofind(base)) == 0 || (relpp= LP_priceinfofind(rel)) == 0 ) + return(clonestr("{\"error\":\"base or rel not added\"}")); + if ( duration <= 0 ) + { + if ( duration < 0 ) + suppress_prefetch = 1; + duration = LP_ORDERBOOK_DURATION; + } + //LP_pubkeys_query(); + baseid = basepp->ind; + relid = relpp->ind; + now = (uint32_t)time(NULL); + basecoin->obooktime = now; + relcoin->obooktime = now; + cachenumbids = numbids, cachenumasks = numasks; + //printf("start cache.(%d %d) numbids.%d numasks.%d\n",cachenumbids,cachenumasks,numbids,numasks); + numasks = LP_orderbook_utxoentries(now,1,base,rel,&asks,numasks,cachenumasks,duration); + numbids = LP_orderbook_utxoentries(now,-1,rel,base,&bids,numbids,cachenumbids,duration); + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + if ( numbids > 1 ) + { + qsort(bids,numbids,sizeof(*bids),_revcmp_orderbook); + depth = 0; + for (i=0; idepth; + bids[i]->depth = depth; + } + } + if ( numasks > 1 ) + { + qsort(asks,numasks,sizeof(*asks),_cmp_orderbook); + depth = 0; + for (i=0; idepth; + asks[i]->depth = depth; + } + } + for (i=n=0; idepth; + jaddi(array,LP_orderbookjson(rel,bids[i])); + if ( suppress_prefetch == 0 && n < 3 && bids[i]->numutxos == 0 ) + { + //printf("bid ping %s %s\n",rel,bids[i]->coinaddr); + LP_address(relcoin,bids[i]->coinaddr); + /*if ( 0 && relcoin->electrum == 0 ) + { + LP_listunspent_issue(rel,bids[i]->coinaddr,0); + //else if ( (tmpjson= LP_listunspent(rel,bids[i]->coinaddr)) != 0 ) + // free_json(tmpjson); + LP_listunspent_query(rel,bids[i]->coinaddr); + }*/ + n++; + } + if ( i == 0 ) + { + LP_priceinfoupdate(rel,base,1. / bids[i]->price); + //printf("update %s/%s %.8f [%.8f]\n",rel,base,1./bids[i]->price,bids[i]->price); + } + free(bids[i]); + bids[i] = 0; + } + if ( n > 0 && relcoin->lastmonitor > 3600 ) + relcoin->lastmonitor -= 3600; + jadd(retjson,"bids",array); + jaddnum(retjson,"numbids",numbids); + jaddnum(retjson,"biddepth",dstr(biddepth)); + array = cJSON_CreateArray(); + for (i=n=0; idepth; + jaddi(array,LP_orderbookjson(base,asks[i])); + if ( suppress_prefetch == 0 && n < 3 && asks[i]->numutxos == 0 ) + { + //printf("ask ping %s %s\n",base,asks[i]->coinaddr); + LP_address(basecoin,asks[i]->coinaddr); + /*if ( 0 && basecoin->electrum == 0 ) + { + LP_listunspent_issue(base,asks[i]->coinaddr,0); + //else if ( (tmpjson= LP_listunspent(base,asks[i]->coinaddr)) != 0 ) + // free_json(tmpjson); + LP_listunspent_query(base,asks[i]->coinaddr); + }*/ + n++; + } + if ( i == 0 ) + { + LP_priceinfoupdate(base,rel,asks[i]->price); + //printf("update %s/%s %.8f [%.8f]\n",base,rel,asks[i]->price,1./asks[i]->price); + } + free(asks[i]); + asks[i] = 0; + } + if ( n > 0 && basecoin->lastmonitor > 3600 ) + basecoin->lastmonitor -= 3600; + jadd(retjson,"asks",array); + jaddnum(retjson,"numasks",numasks); + jaddnum(retjson,"askdepth",dstr(askdepth)); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"timestamp",now); + jaddnum(retjson,"netid",G.netid); + if ( bids != 0 ) + free(bids); + if ( asks != 0 ) + free(asks); + return(jprint(retjson,1)); +} + +int64_t LP_KMDvalue(struct iguana_info *coin,int64_t balance) +{ + double price = 0.; int64_t KMDvalue=0; + if ( balance != 0 ) + { + if ( strcmp(coin->symbol,"KMD") == 0 ) + KMDvalue = balance; + else + { + if ( (price= LP_price(coin->symbol,"KMD")) > SMALLVAL ) + KMDvalue = price * balance; + } + } + return(KMDvalue); +} + +int64_t LP_kmdvalue(char *symbol,int64_t satoshis) +{ + struct iguana_info *coin; int64_t kmdvalue = 0; + if ( (coin= LP_coinfind(symbol)) != 0 ) + kmdvalue = LP_KMDvalue(coin,satoshis); + if ( kmdvalue == 0 ) + kmdvalue = satoshis; + return(kmdvalue); +} + +void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]) +{ + LP_priceinfoupdate(base,rel,price); +} + +void LP_pricefname(char *fname,char *base,char *rel) +{ + sprintf(fname,"%s/PRICES/%s_%s",GLOBAL_DBDIR,base,rel); + OS_compatible_path(fname); +} + +void LP_priceitemadd(cJSON *retarray,uint32_t timestamp,double avebid,double aveask,double highbid,double lowask) +{ + cJSON *item = cJSON_CreateArray(); + jaddinum(item,timestamp); + jaddinum(item,avebid); + jaddinum(item,aveask); + jaddinum(item,highbid); + jaddinum(item,lowask); + jaddi(retarray,item); +} + +cJSON *LP_pricearray(char *base,char *rel,uint32_t firsttime,uint32_t lasttime,int32_t timescale) +{ + cJSON *retarray; char askfname[1024],bidfname[1024]; int64_t bidprice64,askprice64; uint32_t bidnow,asknow,bidi,aski,lastbidi,lastaski; int32_t numbids,numasks; double bidemit,askemit,bidsum,asksum,bid,ask,highbid,lowbid,highask,lowask,bidemit2,askemit2; FILE *askfp=0,*bidfp=0; + if ( timescale <= 0 ) + timescale = 60; + if ( lasttime == 0 ) + lasttime = (uint32_t)-1; + LP_pricefname(askfname,base,rel); + LP_pricefname(bidfname,rel,base); + retarray = cJSON_CreateArray(); + lastbidi = lastaski = 0; + numbids = numasks = 0; + bidsum = asksum = askemit = bidemit = highbid = lowbid = highask = lowask = 0.; + if ( (bidfp= fopen(bidfname,"rb")) != 0 && (askfp= fopen(askfname,"rb")) != 0 ) + { + while ( bidfp != 0 || askfp != 0 ) + { + bidi = aski = 0; + bidemit = askemit = bidemit2 = askemit2 = 0.; + if ( bidfp != 0 && fread(&bidnow,1,sizeof(bidnow),bidfp) == sizeof(bidnow) && fread(&bidprice64,1,sizeof(bidprice64),bidfp) == sizeof(bidprice64) ) + { + //printf("bidnow.%u %.8f\n",bidnow,dstr(bidprice64)); + if ( bidnow != 0 && bidprice64 != 0 && bidnow >= firsttime && bidnow <= lasttime ) + { + bidi = bidnow / timescale; + if ( bidi != lastbidi ) + { + if ( bidsum != 0. && numbids != 0 ) + { + bidemit = bidsum / numbids; + bidemit2 = highbid; + } + bidsum = highbid = lowbid = 0.; + numbids = 0; + } + if ( (bid= 1. / dstr(bidprice64)) != 0. ) + { + if ( bid > highbid ) + highbid = bid; + if ( lowbid == 0. || bid < lowbid ) + lowbid = bid; + bidsum += bid; + numbids++; + //printf("bidi.%u num.%d %.8f [%.8f %.8f]\n",bidi,numbids,bid,lowbid,highbid); + } + } + } else fclose(bidfp), bidfp = 0; + if ( askfp != 0 && fread(&asknow,1,sizeof(asknow),askfp) == sizeof(asknow) && fread(&askprice64,1,sizeof(askprice64),askfp) == sizeof(askprice64) ) + { + //printf("asknow.%u %.8f\n",asknow,dstr(askprice64)); + if ( asknow != 0 && askprice64 != 0 && asknow >= firsttime && asknow <= lasttime ) + { + aski = asknow / timescale; + if ( aski != lastaski ) + { + if ( asksum != 0. && numasks != 0 ) + { + askemit = asksum / numasks; + askemit2 = lowask; + } + asksum = highask = lowask = 0.; + numasks = 0; + } + if ( (ask= dstr(askprice64)) != 0. ) + { + if ( ask > highask ) + highask = ask; + if ( lowask == 0. || ask < lowask ) + lowask = ask; + asksum += ask; + numasks++; + //printf("aski.%u num.%d %.8f [%.8f %.8f]\n",aski,numasks,ask,lowask,highask); + } + } + } else fclose(askfp), askfp = 0; + if ( bidemit != 0. || askemit != 0. ) + { + if ( bidemit != 0. && askemit != 0. && lastbidi == lastaski ) + { + LP_priceitemadd(retarray,lastbidi * timescale,bidemit,askemit,bidemit2,askemit2); + highbid = lowbid = highask = lowask = 0.; + } + else + { + if ( bidemit != 0. ) + { + printf("bidonly %.8f %.8f\n",bidemit,highbid); + LP_priceitemadd(retarray,lastbidi * timescale,bidemit,0.,bidemit2,0.); + highbid = lowbid = 0.; + } + if ( askemit != 0. ) + { + printf("askonly %.8f %.8f\n",askemit,lowask); + LP_priceitemadd(retarray,lastaski * timescale,0.,askemit,0.,askemit2); + highask = lowask = 0.; + } + } + } + if ( bidi != 0 ) + lastbidi = bidi; + if ( aski != 0 ) + lastaski = aski; + } + } else printf("couldnt open either %s %p or %s %p\n",bidfname,bidfp,askfname,askfp); + if ( bidfp != 0 ) + fclose(bidfp); + if ( askfp != 0 ) + fclose(askfp); + return(retarray); +} + +void LP_pricefeedupdate(bits256 pubkey,char *base,char *rel,double price,char *utxocoin,int32_t numrelutxos,int64_t balance,int64_t minutxo,int64_t maxutxo,int64_t unconfcredits) +{ + struct LP_priceinfo *basepp,*relpp; uint32_t now; int64_t price64; struct LP_pubkey_info *pubp; char str[65],fname[512]; FILE *fp; + //printf("check PRICEFEED UPDATE.(%s/%s) %.8f %s\n",base,rel,price,bits256_str(str,pubkey)); + if ( LP_pricevalid(price) > 0 && (basepp= LP_priceinfofind(base)) != 0 && (relpp= LP_priceinfofind(rel)) != 0 ) + { + //if ( (fp= basepp->fps[relpp->ind]) == 0 ) + { + LP_pricefname(fname,base,rel); + fp = OS_appendfile(fname); //basepp->fps[relpp->ind] = + } + if ( fp != 0 ) + { + now = (uint32_t)time(NULL); + price64 = price * SATOSHIDEN; + fwrite(&now,1,sizeof(now),fp); + fwrite(&price64,1,sizeof(price64),fp); + fclose(fp); + } + //if ( (fp= relpp->fps[basepp->ind]) == 0 ) + { + sprintf(fname,"%s/PRICES/%s_%s",GLOBAL_DBDIR,rel,base); + fp = OS_appendfile(fname); //relpp->fps[basepp->ind] = + } + if ( fp != 0 ) + { + now = (uint32_t)time(NULL); + price64 = (1. / price) * SATOSHIDEN; + fwrite(&now,1,sizeof(now),fp); + fwrite(&price64,1,sizeof(price64),fp); + fclose(fp); + } + if ( (pubp= LP_pubkeyadd(pubkey)) != 0 ) + { + if ( (LP_rand() % 1000) == 0 ) + printf("PRICEFEED UPDATE.(%-6s/%6s) %12.8f %s %12.8f\n",base,rel,price,bits256_str(str,pubkey),1./price); + if ( unconfcredits > pubp->unconfcredits ) + pubp->unconfcredits = unconfcredits; + pubp->timestamp = (uint32_t)time(NULL); + LP_pubkey_update(pubp,basepp->ind,relpp->ind,price,balance,utxocoin,numrelutxos,minutxo,maxutxo); + //pubp->depthinfo[basepp->ind][relpp->ind] = LP_depthinfo_compact(); + //if ( fabs(pubp->matrix[basepp->ind][relpp->ind] - price) > SMALLVAL ) + { + //pubp->matrix[basepp->ind][relpp->ind] = price; + //pubp->timestamps[basepp->ind][relpp->ind] = pubp->timestamp; + dxblend(&basepp->relvals[relpp->ind],price,0.9); + dxblend(&relpp->relvals[basepp->ind],1. / price,0.9); + } + } else printf("error finding pubkey entry %s, ok if rare\n",bits256_str(str,pubkey)); + } + //else if ( (rand() % 100) == 0 ) + // printf("error finding %s/%s %.8f\n",base,rel,price); +} + +double LP_CMCbtcprice(double *price_usdp,char *symbol) +{ + char *retstr; cJSON *ticker,*item; double price_btc = 0.; + *price_usdp = 0.; + if ( (retstr= cmc_ticker(symbol)) != 0 ) + { + if ( (ticker= cJSON_Parse(retstr)) != 0 ) + { + item = jitem(ticker,0); + price_btc = jdouble(item,"price_btc"); + *price_usdp = jdouble(item,"price_usd"); + //printf("%.8f item.(%s)\n",price_btc,jprint(item,0)); + free_json(ticker); + } + free(retstr); + } + return(price_btc); +} + +cJSON *LP_fundvalue(cJSON *argjson) +{ + cJSON *holdings,*item,*newitem,*array,*retjson; int32_t i,iter,n,missing=0; double usdprice,divisor,btcprice,balance,btcsum,KMDholdings,numKMD; struct iguana_info *coin; char *symbol,*coinaddr; int64_t fundvalue,KMDvalue = 0; + fundvalue = 0; + KMDholdings = btcsum = 0.; + array = cJSON_CreateArray(); + for (iter=0; iter<2; iter++) + { + if ( iter == 0 ) + holdings = jarray(&n,argjson,"holdings"); + else + { + if ( (coinaddr= jstr(argjson,"address")) != 0 ) + { + holdings = LP_balances(coinaddr); + n = cJSON_GetArraySize(holdings); + } else break; + } + if ( holdings != 0 ) + { + for (i=0; i SMALLVAL ) + { + newitem = cJSON_CreateObject(); + jaddstr(newitem,"coin",symbol); + jaddnum(newitem,"balance",balance); + if ( (coin= LP_coinfind(symbol)) != 0 && (KMDvalue= LP_KMDvalue(coin,SATOSHIDEN * balance)) > 0 ) + { + jaddnum(newitem,"KMD",dstr(KMDvalue)); + fundvalue += KMDvalue; + if ( strcmp(symbol,"KMD") == 0 ) + KMDholdings += dstr(KMDvalue); + } + else if ( iter == 0 && (btcprice= LP_CMCbtcprice(&usdprice,symbol)) > SMALLVAL ) + { + btcsum += btcprice * balance; + jaddnum(newitem,"BTC",btcprice * balance); + } + else jaddstr(newitem,"error","no price source"); + jaddi(array,newitem); + } else missing++; + } + } + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"missing",missing); + jadd(retjson,"holdings",array); + btcprice = LP_CMCbtcprice(&usdprice,"komodo"); + divisor = jdouble(argjson,"divisor"); + jaddnum(retjson,"KMDholdings",KMDholdings); + if ( btcsum != 0 ) + { + if ( btcprice > SMALLVAL ) + { + numKMD = (btcsum / btcprice); + fundvalue += numKMD * SATOSHIDEN; + jaddnum(retjson,"KMD_BTC",btcprice); + jaddnum(retjson,"btcsum",btcsum); + numKMD += KMDholdings; + jaddnum(retjson,"btc2kmd",numKMD); + if ( divisor != 0 ) + { + jaddnum(retjson,"NAV_KMD",numKMD/divisor); + jaddnum(retjson,"NAV_BTC",(btcsum + (KMDholdings * btcprice))/divisor); + jaddnum(retjson,"NAV_USD",(usdprice * numKMD)/divisor); + } + } + } + jaddnum(retjson,"fundvalue",dstr(fundvalue)); + if ( divisor != 0 ) + { + jaddnum(retjson,"divisor",divisor); + numKMD = dstr(fundvalue); + jaddnum(retjson,"assetNAV_KMD",numKMD/divisor); + jaddnum(retjson,"assetNAV_BTC",(btcprice * numKMD)/divisor); + jaddnum(retjson,"assetNAV_USD",(usdprice * numKMD)/divisor); + } + return(retjson); +} + diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c new file mode 100644 index 000000000..9c3c3ae47 --- /dev/null +++ b/iguana/exchanges/LP_privkey.c @@ -0,0 +1,749 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_utxos.c +// marketmaker +// + +int32_t LP_privkey_init(int32_t mypubsock,struct iguana_info *coin,bits256 myprivkey,bits256 mypub) +{ + int32_t enable_utxos = 0; + char *script,destaddr[64]; cJSON *array,*item; bits256 txid,deposittxid,zero; int32_t used,i,flag=0,height,n,cmpflag,iambob,vout,depositvout; uint64_t *values=0,satoshis,txfee,biggerval,value,total = 0; int64_t targetval; //struct LP_utxoinfo *utxo; + if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) + { + //printf("coin not active\n"); + return(0); + } + if ( coin->privkeydepth > 0 ) + return(0); + coin->privkeydepth++; + LP_address(coin,coin->smartaddr); + //if ( coin->inactive == 0 ) + // LP_listunspent_issue(coin->symbol,coin->smartaddr,0); + memset(zero.bytes,0,sizeof(zero)); + array = LP_listunspent(coin->symbol,coin->smartaddr,zero,zero); + if ( array != 0 ) + { + txfee = LP_txfeecalc(coin,0,0); + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + coin->numutxos = n; + //printf("LP_privkey_init %s %d\n",coin->symbol,n); + for (iambob=0; iambob<=1; iambob++) + { + if ( iambob == 0 ) + values = calloc(n,sizeof(*values)); + else memset(values,0,n * sizeof(*values)); + used = 0; + for (i=0; isymbol,txid,vout); + if ( satoshis != 0 && satoshis != value ) + printf("%s %s privkey_init value %.8f vs %.8f (%s) %.8f %.8f\n",coin->symbol,coin->smartaddr,dstr(satoshis),dstr(value),jprint(item,0),jdouble(item,"amount"),jdouble(item,"interest")); + if ( coin->electrum != 0 || LP_inventory_prevent(iambob,coin->symbol,txid,vout) == 0 )//&& height > 0 ) + { + values[i] = satoshis; + //flag += LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,height,-1); + } else used++; + } + //printf("array.%d\n",n); + while ( used < n-1 ) + { + //for (i=0; i= 0 ) + { + item = jitem(array,i); + if ( coin->electrum == 0 ) + { + deposittxid = jbits256(item,"txid"); + depositvout = juint(item,"vout"); + script = jstr(item,"scriptPubKey"); + } + else + { + deposittxid = jbits256(item,"tx_hash"); + depositvout = juint(item,"tx_pos"); + script = coin->smartaddr; + } + biggerval = values[i]; + values[i] = 0, used++; + if ( iambob == 0 ) + targetval = (biggerval / 776) + txfee; + else targetval = (biggerval / 9) * 8 + 2*txfee; + if ( targetval < txfee*2 ) + targetval = txfee*2; + //printf("iambob.%d i.%d deposit %.8f min %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr((1+LP_MINSIZE_TXFEEMULT)*txfee),dstr(targetval)); + if ( biggerval < (1+LP_MINSIZE_TXFEEMULT)*txfee ) + continue; + i = -1; + if ( iambob != 0 ) + { + if ( (i= LP_nearestvalue(iambob,values,n,targetval)) < 0 ) + targetval /= 4; + if ( targetval < txfee*(1+LP_MINSIZE_TXFEEMULT) ) + continue; + } + if ( i >= 0 || (i= LP_nearestvalue(iambob,values,n,targetval)) >= 0 ) + { + //printf("iambob.%d i.%d %.8f target %.8f\n",iambob,i,dstr(biggerval),dstr(targetval)); + item = jitem(array,i); + cmpflag = 0; + if ( coin->electrum == 0 ) + { + txid = jbits256(item,"txid"); + vout = juint(item,"vout"); + if ( jstr(item,"scriptPubKey") != 0 && strcmp(script,jstr(item,"scriptPubKey")) == 0 ) + cmpflag = 1; + } + else + { + txid = jbits256(item,"tx_hash"); + vout = juint(item,"tx_pos"); + cmpflag = 1; + } + if ( cmpflag != 0 ) + { + value = values[i]; + values[i] = 0, used++; + /*portable_mutex_lock(&LP_UTXOmutex); + if ( iambob != 0 ) + { + if ( (utxo= LP_utxoadd(1,coin->symbol,txid,vout,value,deposittxid,depositvout,biggerval,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,value)) != 0 ) + { + } + } + else + { + //printf("call utxoadd\n"); + if ( (utxo= LP_utxoadd(0,coin->symbol,deposittxid,depositvout,biggerval,txid,vout,value,coin->smartaddr,mypub,LP_gui,G.LP_sessionid,biggerval)) != 0 ) + { + } + } + portable_mutex_unlock(&LP_UTXOmutex);*/ + total += value; + } // else printf("scriptmismatch.(%s) vs %s\n",script,jprint(item,0)); + } //else printf("nothing near i.%d\n",i); + } else break; + } + if ( enable_utxos == 0 ) + break; + } + } + free_json(array); + if ( 0 && flag != 0 ) + LP_postutxos(coin->symbol,coin->smartaddr); + } + if ( values != 0 ) + free(values); + if ( coin->privkeydepth > 0 ) + coin->privkeydepth--; + //printf("privkey.%s %.8f\n",symbol,dstr(total)); + return(flag); +} + +char *LP_secretaddresses(void *ctx,char *prefix,char *passphrase,int32_t n,uint8_t taddr,uint8_t pubtype) +{ + int32_t i; uint8_t tmptype,pubkey33[33],rmd160[20]; char output[777*45],str[65],str2[65],buf[8192],wifstr[128],coinaddr[64]; bits256 checkprivkey,privkey,pubkey; cJSON *retjson; + retjson = cJSON_CreateObject(); + if ( prefix == 0 || prefix[0] == 0 ) + prefix = "secretaddress"; + if ( passphrase == 0 || passphrase[0] == 0 ) + passphrase = "password"; + if ( n <= 0 ) + n = 16; + else if ( n > 777 ) + n = 777; + conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + bitcoin_priv2pub(ctx,"KMD",pubkey33,coinaddr,privkey,taddr,pubtype); + printf("generator (%s) secrets.[%d] <%s> t.%u p.%u\n",coinaddr,n,passphrase,taddr,pubtype); + sprintf(output,"\"addresses\":["); + for (i=0; i %s vs %s?\n",wifstr,bits256_str(str,privkey),bits256_str(str2,checkprivkey)); + free_json(retjson); + return(clonestr("{\"error\":\"couldnt validate wifstr\"}")); + } + else if ( tmptype != pubtype ) + { + printf("checktype.%d != pubtype.%d\n",tmptype,pubtype); + free_json(retjson); + return(clonestr("{\"error\":\"couldnt validate pubtype\"}")); + } + jaddstr(retjson,coinaddr,wifstr); + sprintf(output+strlen(output),"\\\"%s\\\"%c ",coinaddr,i 54 ) + { + //printf("len.%d is wrong for wif %s\n",len,wifstr); + return(0); + } + memset(privkey.bytes,0,sizeof(privkey)); + memset(cmpkey.bytes,0,sizeof(cmpkey)); + for (i=n=a=A=0; wifstr[i]!=0; i++) + { + if ( strchr(base58_chars,wifstr[i]) == 0 ) + return(0); + if ( wifstr[i] >= '1' && wifstr[i] <= '9' ) + n++; + else if ( wifstr[i] >= 'A' && wifstr[i] <= 'Z' ) + A++; + else if ( wifstr[i] >= 'a' && wifstr[i] <= 'z' ) + a++; + } + if ( n == 0 || A == 0 || a == 0 ) + return(0); + if ( A > 5*a || a > 5*A || a > n*20 || A > n*20 ) // unlikely it is a real wif + { + printf("reject wif %s due to n.%d a.%d A.%d (%d %d %d %d)\n",wifstr,n,a,A,A > 5*a,a < 5*A,a > n*20,A > n*20); + return(0); + } + bitcoin_wif2priv(symbol,0,&wiftype,&privkey,wifstr); + bitcoin_priv2wif(symbol,0,cmpstr,privkey,wiftype); + if ( strcmp(cmpstr,wifstr) == 0 ) + { + //printf("%s is valid wif\n",wifstr); + return(1); + } + else if ( bits256_nonz(privkey) != 0 ) + { + bitcoin_wif2priv(symbol,0,&wiftype,&cmpkey,cmpstr); + bitcoin_priv2wiflong(symbol,0,cmpstr2,privkey,wiftype); + if ( bits256_cmp(privkey,cmpkey) == 0 ) + return(1); + char str[65],str2[65]; printf("%s mismatched wifstr %s -> %s -> %s %s %s\n",symbol,wifstr,bits256_str(str,privkey),cmpstr,bits256_str(str2,cmpkey),cmpstr2); + } + char str[65]; printf("%s is not a wif, privkey.%s\n",wifstr,bits256_str(str,privkey)); + return(0); +} + +bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr) +{ + //static uint32_t counter; + bits256 privkey,userpub,zero,userpass,checkkey,tmpkey; char str[65],str2[65],tmpstr[128]; cJSON *retjson; uint8_t tmptype,sig[128]; int32_t notarized,siglen; uint64_t nxtaddr; + if ( (wifstr == 0 || wifstr[0] == 0) && LP_wifstr_valid(coin->symbol,passphrase) > 0 ) + { + wifstr = passphrase; + passphrase = 0; + } + if ( passphrase != 0 && passphrase[0] != 0 ) + { + calc_NXTaddr(G.LP_NXTaddr,userpub.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + privkey.bytes[0] &= 248, privkey.bytes[31] &= 127, privkey.bytes[31] |= 64; + //vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + //printf("SHA256.(%s) ",bits256_str(pstr,checkkey)); + //printf("privkey.(%s)\n",bits256_str(pstr,privkey)); + bitcoin_priv2wif(coin->symbol,coin->wiftaddr,tmpstr,privkey,coin->wiftype); + bitcoin_wif2priv(coin->symbol,coin->wiftaddr,&tmptype,&checkkey,tmpstr); + if ( bits256_cmp(privkey,checkkey) != 0 ) + { + char str[65],str2[65]; printf("mismatched privkeys from wif conversion: %s -> %s -> %s\n",bits256_str(str,privkey),tmpstr,bits256_str(str2,checkkey)); + exit(1); + } + } + else + { + bitcoin_wif2priv(coin->symbol,coin->wiftaddr,&tmptype,&privkey,wifstr); + bitcoin_priv2wif(coin->symbol,coin->wiftaddr,tmpstr,privkey,tmptype); + if ( strcmp(tmpstr,wifstr) != 0 ) + { + bitcoin_wif2priv(coin->symbol,coin->wiftaddr,&tmptype,&tmpkey,tmpstr); + if ( bits256_cmp(tmpkey,privkey) != 0 ) + { + char str[65]; printf("%s error reproducing the wifstr, likely edge case like non-supported uncompressed pubkey privkey.%s\n",coin->symbol,bits256_str(str,privkey)); + exit(1); + } + } + tmpkey = privkey; + nxtaddr = conv_NXTpassword(tmpkey.bytes,pubkeyp->bytes,0,0); + RS_encode(G.LP_NXTaddr,nxtaddr); + } + bitcoin_priv2pub(ctx,coin->symbol,coin->pubkey33,coin->smartaddr,privkey,coin->taddr,coin->pubtype); + OS_randombytes(tmpkey.bytes,sizeof(tmpkey)); + if ( bits256_nonz(privkey) == 0 || (siglen= bitcoin_sign(ctx,coin->symbol,sig,tmpkey,privkey,0)) <= 0 ) + { + printf("illegal privkey %s\n",bits256_str(str,privkey)); + exit(0); + } + if ( bitcoin_verify(ctx,sig,siglen,tmpkey,coin->pubkey33,33) != 0 ) + { + printf("signature.[%d] for %s by %s didnt verify\n",siglen,bits256_str(str,tmpkey),bits256_str(str2,privkey)); + exit(0); + } + if ( coin->counter == 0 ) + { + coin->counter++; + memcpy(G.LP_pubsecp,coin->pubkey33,33); + bitcoin_priv2wif(coin->symbol,coin->wiftaddr,tmpstr,privkey,coin->wiftype); + bitcoin_addr2rmd160(coin->symbol,coin->taddr,&tmptype,G.LP_myrmd160,coin->smartaddr); + LP_privkeyadd(privkey,G.LP_myrmd160); + G.LP_privkey = privkey; + if ( G.counter++ == 0 ) + { + bitcoin_priv2wif(coin->symbol,coin->wiftaddr,G.USERPASS_WIFSTR,privkey,188); + bitcoin_wif2priv(coin->symbol,coin->wiftaddr,&tmptype,&checkkey,G.USERPASS_WIFSTR); + if ( bits256_cmp(checkkey,privkey) != 0 ) + { + char str[65],str2[65]; + printf("FATAL ERROR converting USERPASS_WIFSTR %s -> %s != %s\n",G.USERPASS_WIFSTR,bits256_str(str,checkkey),bits256_str(str2,privkey)); + exit(-1); + } + conv_NXTpassword(userpass.bytes,pubkeyp->bytes,(uint8_t *)G.USERPASS_WIFSTR,(int32_t)strlen(G.USERPASS_WIFSTR)); + userpub = curve25519(userpass,curve25519_basepoint9()); + printf("userpass.(%s)\n",bits256_str(G.USERPASS,userpub)); + } + } + if ( strcmp(coin->smartaddr,"RPZVpjptzfZnFZZoLnuSbfLexjtkhe6uvn") != 0 && coin->importedprivkey == 0 && coin->electrum == 0 && coin->userpass[0] != 0 && LP_getheight(¬arized,coin) > 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + LP_listunspent_issue(coin->symbol,coin->smartaddr,0,zero,zero); + if ( (retjson= LP_importprivkey(coin->symbol,tmpstr,coin->smartaddr,-1)) != 0 ) + { + if ( jobj(retjson,"error") != 0 ) + { + printf("cant importprivkey.%s %s -> (%s), abort session\n",coin->symbol,coin->smartaddr,jprint(retjson,1)); + exit(-1); + } + free_json(retjson); + } + coin->importedprivkey = (uint32_t)time(NULL); + } + vcalc_sha256(0,checkkey.bytes,privkey.bytes,sizeof(privkey)); + checkkey.bytes[0] &= 248, checkkey.bytes[31] &= 127, checkkey.bytes[31] |= 64; + G.LP_mypub25519 = *pubkeyp = curve25519(checkkey,curve25519_basepoint9()); + G.LP_mypriv25519 = checkkey; + LP_pubkeyadd(G.LP_mypub25519); + return(privkey); +} + +void LP_privkey_updates(void *ctx,int32_t pubsock,char *passphrase) +{ + struct iguana_info *coin,*tmp; bits256 pubkey,privkey; uint8_t pubkey33[33]; int32_t initonly; + initonly = (passphrase != 0); + memset(privkey.bytes,0,sizeof(privkey)); + memset(pubkey.bytes,0,sizeof(pubkey)); + //printf("Total coins: %d\n", HASH_COUNT(LP_coins)); + //int num_iter = 0; + HASH_ITER(hh,LP_coins,coin,tmp) + { + //printf("LP_privkey_updates [%02d / %02d]\n", num_iter++, HASH_COUNT(LP_coins)); + if ( initonly != 0 ) + { + coin->counter = 0; + memset(coin->smartaddr,0,sizeof(coin->smartaddr)); + if ( bits256_nonz(privkey) == 0 || coin->smartaddr[0] == 0 ) + privkey = LP_privkeycalc(ctx,pubkey33,&pubkey,coin,passphrase,""); + } + //printf("i.%d of %d\n",i,LP_numcoins); + else if ( IAMLP == 0 || coin->inactive == 0 ) + { + //printf("from updates %s\n",coin->symbol); + if ( 0 && LP_privkey_init(pubsock,coin,G.LP_privkey,G.LP_mypub25519) == 0 && (LP_rand() % 10) == 0 ) + { + //LP_postutxos(coin->symbol,coin->smartaddr); + } + } + } +} + +int32_t LP_passphrase_init(char *passphrase,char *gui,uint16_t netid,char *seednode) +{ + static void *ctx; struct iguana_info *coin,*tmp; int32_t counter; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + if ( G.LP_pendingswaps != 0 ) + return(-1); + if ( netid != G.netid ) + { + if ( IAMLP != 0 ) + { + printf("sorry, LP nodes can only set netid during startup\n"); + return(-1); + } + else + { + printf(">>>>>>>>>>>>> netid.%d vs G.netid %d\n",netid,G.netid); + LP_closepeers(); + LP_initpeers(LP_mypubsock,LP_mypeer,LP_myipaddr,RPC_port,netid,seednode); + } + } + G.initializing = 1; + if ( gui == 0 ) + gui = "cli"; + counter = G.USERPASS_COUNTER; + HASH_ITER(hh,LP_coins,coin,tmp) + { + coin->importedprivkey = 0; + } + while ( G.waiting == 0 ) + { + printf("waiting for G.waiting\n"); + sleep(5); + } + memset(&G,0,sizeof(G)); + G.netid = netid; + safecopy(G.seednode,seednode,sizeof(G.seednode)); + vcalc_sha256(0,G.LP_passhash.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + LP_privkey_updates(ctx,LP_mypubsock,passphrase); + init_hexbytes_noT(G.LP_myrmd160str,G.LP_myrmd160,20); + G.LP_sessionid = (uint32_t)time(NULL); + safecopy(G.gui,gui,sizeof(G.gui)); + LP_tradebot_pauseall(); + LP_portfolio_reset(); + LP_priceinfos_clear(); + G.USERPASS_COUNTER = counter; + G.initializing = 0; + //LP_cmdchannels(); + return(0); +} + +void LP_privkey_tests() +{ + char wifstr[64],str[65],str2[65]; bits256 privkey,checkkey; int32_t i; uint8_t tmptype; + for (i=0; i<200000000; i++) + { + privkey = rand256(0); + bitcoin_priv2wif("KMD",0,wifstr,privkey,0xff); + bitcoin_wif2priv("KMD",0,&tmptype,&checkkey,wifstr); + if ( bits256_cmp(privkey,checkkey) != 0 ) + { + printf("i.%d: %s vs %s\n",i,bits256_str(str,privkey),bits256_str(str2,checkkey)); + exit(-1); + } + if ( (i % 1000000) == 0 ) + fprintf(stderr,"%.1f%% ",100.*(double)i/200000000); + } + printf("%d privkeys checked\n",i); +} + + +#define JPG_ENCRYPTED_MAXSIZE 32768 + +int32_t JPG_encrypt(uint16_t ind,uint8_t encoded[JPG_ENCRYPTED_MAXSIZE],uint8_t *msg,int32_t msglen,bits256 privkey) +{ + bits256 pubkey; int32_t len = 2; uint8_t space[JPG_ENCRYPTED_MAXSIZE],*nonce,*cipher; + pubkey = acct777_pubkey(privkey); + encoded[len++] = ind & 0xff; + encoded[len++] = (ind >> 8) & 0xff; + nonce = &encoded[len]; + OS_randombytes(nonce,crypto_box_NONCEBYTES); + cipher = &encoded[len + crypto_box_NONCEBYTES]; + msglen = _SuperNET_cipher(nonce,&encoded[len + crypto_box_NONCEBYTES],msg,msglen,pubkey,privkey,space); + msglen += crypto_box_NONCEBYTES; + msg = encoded; + msglen += len; + encoded[0] = msglen & 0xff; + encoded[1] = (msglen >> 8) & 0xff; + int32_t i; for (i=0; i 0 && cipherlen <= JPG_ENCRYPTED_MAXSIZE + crypto_box_ZEROBYTES ) + { + if ( (extracted= _SuperNET_decipher(nonce,cipher,space,cipherlen,pubkey,privkey)) != 0 ) + { + int32_t i; for (i=0; i JPG_ENCRYPTED_MAXSIZE-60 ) + return(-1); + data = calloc(1,required/8+512); + vcalc_sha256(0,privkey.bytes,(uint8_t *)password,(int32_t)strlen(password)); + if ( origdata != 0 ) + { + msglen = JPG_encrypt(*indp,data,origdata,required/8,privkey); + required = msglen * 8; + { + space = calloc(1,JPG_ENCRYPTED_MAXSIZE); + if ( (decrypted= JPG_decrypt(&checkind,&recvlen,space,data,privkey)) == 0 || recvlen != origrequired/8 || checkind != *indp || memcmp(decrypted,origdata,origrequired/8) != 0 ) + printf("A decryption error: checkind.%d vs %d, recvlen.%d vs %d, decrypted.%p\n",checkind,*indp,recvlen,origrequired/8,decrypted); + else + { + for (i=0; i 30 ) + power2 = 7; + limit = 1; + while ( power2 > 0 ) + { + limit <<= 1; + power2--; + } + // Initialize the JPEG compression and decompression objects with default error handling + inputinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&inputinfo); + // Specify data source for decompression and recompression + jpeg_stdio_src(&inputinfo, input_file); + (void) jpeg_read_header(&inputinfo, TRUE); + for (compnum=0; compnummem->alloc_barray)((j_common_ptr)&inputinfo,JPOOL_IMAGE,inputinfo.comp_info[compnum].width_in_blocks,inputinfo.comp_info[compnum].height_in_blocks); + coef_arrays = jpeg_read_coefficients(&inputinfo); + // Copy DCT coeffs to a new array + int num_components = inputinfo.num_components; + size_t *block_row_size;//[num_components]; + int *width_in_blocks;//[num_components]; + int *height_in_blocks;//[num_components]; + block_row_size = calloc(sizeof(*block_row_size),num_components); + width_in_blocks = calloc(sizeof(*width_in_blocks),num_components); + height_in_blocks = calloc(sizeof(*height_in_blocks),num_components); + *capacityp = modified = emit = totalrows = 0; + if ( decoded != 0 ) + memset(decoded,0,required/8+1); + for (compnum=0; compnummem->access_virt_barray)((j_common_ptr)&inputinfo,coef_arrays[compnum],rownum,(JDIMENSION)1,FALSE); + for (blocknum=0; blocknum= limit ) + { + if ( (*capacityp) < required ) + { + if ( (val & 1) != 0 ) + SETBIT(decoded,(*capacityp)); + //printf("%c",(val&1)!=0?'1':'0'); + } + (*capacityp)++; + } + coef_buffers[compnum][rownum][blocknum][i] = val; + } + } + } + } + if ( password != 0 && password[0] != 0 ) + { + space = calloc(1,JPG_ENCRYPTED_MAXSIZE); + if ( (decrypted= JPG_decrypt(indp,&recvlen,space,decoded,privkey)) != 0 && recvlen == origrequired/8 ) + { + for (i=0; i required && outputfname != 0 && outputfname[0] != 0 ) + { + if ((output_file = fopen(outputfname, WRITE_BINARY)) == NULL) { + fprintf(stderr, "Can't open %s\n", outputfname); + if ( data != origdata ) + free(data); + return(-1); + } + outputinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&outputinfo); + jpeg_stdio_dest(&outputinfo, output_file); + jpeg_copy_critical_parameters(&inputinfo,&outputinfo); + // Print out or modify DCT coefficients + for (compnum=0; compnum= limit ) + { + val &= ~1; + if (GETBIT(data,emit) != 0 )//|| (emit >= required && (rand() & 1) != 0) ) + val |= 1; + //printf("%c",(val&1)!=0?'1':'0'); + coef_buffers[compnum][rownum][blocknum][i] = val; + emit++; + } + //printf("%i,", coef_buffers[compnum][rownum][blocknum][i]); + } + } + } + } + //printf(" emit.%d\n",emit); + // Output the new DCT coeffs to a JPEG file + modified = 0; + for (compnum=0; compnummem->access_virt_barray)((j_common_ptr)&outputinfo,coef_arrays[compnum],rownum,(JDIMENSION)1,TRUE); + if ( memcmp(row_ptrs[compnum][0][0],coef_buffers[compnum][rownum][0],block_row_size[compnum]) != 0 ) + { + memcpy(row_ptrs[compnum][0][0],coef_buffers[compnum][rownum][0],block_row_size[compnum]); + modified++; + } + totalrows++; + } + } + // Write to the output file + jpeg_write_coefficients(&outputinfo, coef_arrays); + // Finish compression and release memory + jpeg_finish_compress(&outputinfo); + jpeg_destroy_compress(&outputinfo); + fclose(output_file); + } + jpeg_finish_decompress(&inputinfo); + jpeg_destroy_decompress(&inputinfo); + fclose(input_file); + if ( modified != 0 ) + { + printf("New DCT coefficients successfully written to %s, capacity %d modifiedrows.%d/%d emit.%d\n",outputfname,*capacityp,modified,totalrows,emit); + } + free(block_row_size); + free(width_in_blocks); + free(height_in_blocks); + if ( data != origdata ) + free(data); + return(modified); +} + +char *LP_jpg(char *srcfile,char *destfile,int32_t power2,char *passphrase,char *datastr,int32_t required,uint16_t ind) +{ + cJSON *retjson; int32_t len=0,modified,capacity; char *decodedstr; uint8_t *data=0,*decoded=0; + if ( srcfile != 0 && srcfile[0] != 0 ) + { + retjson = cJSON_CreateObject(); + if ( datastr != 0 && datastr[0] != 0 ) + { + if ( (len= is_hexstr(datastr,0)) > 0 ) + { + len >>= 1; + data = calloc(1,len); + decode_hex(data,len,datastr); + required = len * 8; + //int32_t i; for (i=0; i 0 ) + decoded = calloc(1,len+required); + if ( (modified= LP_jpg_process(&capacity,srcfile,destfile,decoded,data,required,power2,passphrase,&ind)) < 0 ) + jaddstr(retjson,"error","file not found"); + else + { + jaddstr(retjson,"result","success"); + jaddnum(retjson,"modifiedrows",modified); + if ( modified != 0 ) + jaddstr(retjson,"outputfile",destfile); + jaddnum(retjson,"power2",power2); + jaddnum(retjson,"capacity",capacity); + jaddnum(retjson,"required",required); + jaddnum(retjson,"ind",ind); + } + if ( decoded != 0 ) + { + if ( capacity > 0 ) + { + //printf("len.%d required.%d capacity.%d\n",len,required,capacity); + decodedstr = calloc(1,(len+required)*2+1); + init_hexbytes_noT(decodedstr,decoded,required/8); + jaddstr(retjson,"decoded",decodedstr); + free(decodedstr); + } + free(decoded); + } + if ( data != 0 ) + free(data); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no source file error\"}")); +} + + + + diff --git a/iguana/exchanges/LP_remember.c b/iguana/exchanges/LP_remember.c new file mode 100644 index 000000000..2aad1afb5 --- /dev/null +++ b/iguana/exchanges/LP_remember.c @@ -0,0 +1,1607 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_remember.c +// marketmaker +// + +void basilisk_dontforget_userdata(char *userdataname,FILE *fp,uint8_t *script,int32_t scriptlen) +{ + int32_t i; char scriptstr[513]; + if ( scriptlen != 0 ) + { + for (i=0; iI.req.requestid,swap->I.req.quoteid,rawtx->name), OS_compatible_path(fname); + bobcoin = LP_coinfind(swap->I.bobstr); + alicecoin = LP_coinfind(swap->I.alicestr); + coinaddr[0] = secretAmstr[0] = secretAm256str[0] = secretBnstr[0] = secretBn256str[0] = 0; + memset(zeroes,0,sizeof(zeroes)); + if ( alicecoin != 0 && bobcoin != 0 && rawtx != 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fprintf(fp,"{\"name\":\"%s\",\"coin\":\"%s\"",rawtx->name,rawtx->symbol); + if ( rawtx->I.datalen > 0 ) + { + fprintf(fp,",\"tx\":\""); + for (i=0; iI.datalen; i++) + fprintf(fp,"%02x",rawtx->txbytes[i]); + fprintf(fp,"\",\"txid\":\"%s\"",bits256_str(str,bits256_calctxid(rawtx->symbol,rawtx->txbytes,rawtx->I.datalen))); + if ( rawtx == &swap->bobdeposit || rawtx == &swap->bobpayment ) + { + LP_swap_coinaddr(bobcoin,coinaddr,0,rawtx->txbytes,rawtx->I.datalen,0); + if ( coinaddr[0] != 0 ) + { + LP_importaddress(swap->I.bobstr,coinaddr); + if ( rawtx == &swap->bobdeposit ) + safecopy(swap->Bdeposit,coinaddr,sizeof(swap->Bdeposit)); + else safecopy(swap->Bpayment,coinaddr,sizeof(swap->Bpayment)); + } + } + } + if ( swap->Bdeposit[0] != 0 ) + fprintf(fp,",\"%s\":\"%s\"","Bdeposit",swap->Bdeposit); + if ( swap->Bpayment[0] != 0 ) + fprintf(fp,",\"%s\":\"%s\"","Bpayment",swap->Bpayment); + fprintf(fp,",\"expiration\":%u",swap->I.expiration); + fprintf(fp,",\"iambob\":%d",swap->I.iambob); + fprintf(fp,",\"bobcoin\":\"%s\"",swap->I.bobstr); + fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr); + fprintf(fp,",\"lock\":%u",locktime); + fprintf(fp,",\"amount\":%.8f",dstr(rawtx->I.amount)); + if ( bits256_nonz(triggertxid) != 0 ) + fprintf(fp,",\"trigger\":\"%s\"",bits256_str(str,triggertxid)); + if ( bits256_nonz(swap->I.pubAm) != 0 && bits256_nonz(swap->I.pubBn) != 0 ) + { + basilisk_alicescript(alicecoin->symbol,redeemscript,&len,script,0,coinaddr,alicecoin->taddr,alicecoin->p2shtype,swap->I.pubAm,swap->I.pubBn); + LP_importaddress(swap->I.alicestr,coinaddr); + fprintf(fp,",\"Apayment\":\"%s\"",coinaddr); + } + if ( rawtx->I.redeemlen > 0 ) + { + char scriptstr[2049]; + init_hexbytes_noT(scriptstr,rawtx->redeemscript,rawtx->I.redeemlen); + fprintf(fp,",\"redeem\":\"%s\"",scriptstr); + } + /*basilisk_dontforget_userdata("Aclaim",fp,swap->I.userdata_aliceclaim,swap->I.userdata_aliceclaimlen); + basilisk_dontforget_userdata("Areclaim",fp,swap->I.userdata_alicereclaim,swap->I.userdata_alicereclaimlen); + basilisk_dontforget_userdata("Aspend",fp,swap->I.userdata_alicespend,swap->I.userdata_alicespendlen); + basilisk_dontforget_userdata("Bspend",fp,swap->I.userdata_bobspend,swap->I.userdata_bobspendlen); + basilisk_dontforget_userdata("Breclaim",fp,swap->I.userdata_bobreclaim,swap->I.userdata_bobreclaimlen); + basilisk_dontforget_userdata("Brefund",fp,swap->I.userdata_bobrefund,swap->I.userdata_bobrefundlen);*/ + fprintf(fp,"}\n"); + fclose(fp); + } + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fprintf(fp,"{\"tradeid\":%u,\"aliceid\":\"%llu\",\"src\":\"%s\",\"srcamount\":%.8f,\"dest\":\"%s\",\"destamount\":%.8f,\"requestid\":%u,\"quoteid\":%u,\"iambob\":%d,\"state\":%u,\"otherstate\":%u,\"expiration\":%u,\"dlocktime\":%u,\"plocktime\":%u,\"Atxfee\":%llu,\"Btxfee\":%llu",swap->tradeid,(long long)swap->aliceid,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.requestid,swap->I.req.quoteid,swap->I.iambob,swap->I.statebits,swap->I.otherstatebits,swap->I.expiration,swap->bobdeposit.I.locktime,swap->bobpayment.I.locktime,(long long)swap->I.Atxfee,(long long)swap->I.Btxfee); + if ( swap->I.iambob == 0 ) + fprintf(fp,",\"Agui\":\"%s\"",G.gui); + else fprintf(fp,",\"Bgui\":\"%s\"",G.gui); + fprintf(fp,",\"gui\":\"%s\"",G.gui); + if ( memcmp(zeroes,swap->I.secretAm,20) != 0 ) + { + init_hexbytes_noT(secretAmstr,swap->I.secretAm,20); + fprintf(fp,",\"secretAm\":\"%s\"",secretAmstr); + } + if ( memcmp(zeroes,swap->I.secretAm256,32) != 0 ) + { + init_hexbytes_noT(secretAm256str,swap->I.secretAm256,32); + fprintf(fp,",\"secretAm256\":\"%s\"",secretAm256str); + } + if ( memcmp(zeroes,swap->I.secretBn,20) != 0 ) + { + init_hexbytes_noT(secretBnstr,swap->I.secretBn,20); + fprintf(fp,",\"secretBn\":\"%s\"",secretBnstr); + } + if ( memcmp(zeroes,swap->I.secretBn256,32) != 0 ) + { + init_hexbytes_noT(secretBn256str,swap->I.secretBn256,32); + fprintf(fp,",\"secretBn256\":\"%s\"",secretBn256str); + } + for (i=0; i<2; i++) + if ( bits256_nonz(swap->I.myprivs[i]) != 0 ) + fprintf(fp,",\"myprivs%d\":\"%s\"",i,bits256_str(str,swap->I.myprivs[i])); + if ( bits256_nonz(swap->I.privAm) != 0 ) + fprintf(fp,",\"privAm\":\"%s\"",bits256_str(str,swap->I.privAm)); + if ( bits256_nonz(swap->I.privBn) != 0 ) + fprintf(fp,",\"privBn\":\"%s\"",bits256_str(str,swap->I.privBn)); + if ( bits256_nonz(swap->I.pubA0) != 0 ) + fprintf(fp,",\"pubA0\":\"%s\"",bits256_str(str,swap->I.pubA0)); + if ( bits256_nonz(swap->I.pubB0) != 0 ) + fprintf(fp,",\"pubB0\":\"%s\"",bits256_str(str,swap->I.pubB0)); + if ( bits256_nonz(swap->I.pubB1) != 0 ) + fprintf(fp,",\"pubB1\":\"%s\"",bits256_str(str,swap->I.pubB1)); + if ( bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 ) + fprintf(fp,",\"Bdeposit\":\"%s\"",bits256_str(str,swap->bobdeposit.I.actualtxid)); + if ( bits256_nonz(swap->bobrefund.I.actualtxid) != 0 ) + fprintf(fp,",\"Brefund\":\"%s\"",bits256_str(str,swap->bobrefund.I.actualtxid)); + if ( bits256_nonz(swap->aliceclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Aclaim\":\"%s\"",bits256_str(str,swap->aliceclaim.I.actualtxid)); + + if ( bits256_nonz(swap->bobpayment.I.actualtxid) != 0 ) + fprintf(fp,",\"Bpayment\":\"%s\"",bits256_str(str,swap->bobpayment.I.actualtxid)); + if ( bits256_nonz(swap->alicespend.I.actualtxid) != 0 ) + fprintf(fp,",\"Aspend\":\"%s\"",bits256_str(str,swap->alicespend.I.actualtxid)); + if ( bits256_nonz(swap->bobreclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Breclaim\":\"%s\"",bits256_str(str,swap->bobreclaim.I.actualtxid)); + + if ( bits256_nonz(swap->alicepayment.I.actualtxid) != 0 ) + fprintf(fp,",\"Apayment\":\"%s\"",bits256_str(str,swap->alicepayment.I.actualtxid)); + if ( bits256_nonz(swap->bobspend.I.actualtxid) != 0 ) + fprintf(fp,",\"Bspend\":\"%s\"",bits256_str(str,swap->bobspend.I.actualtxid)); + if ( bits256_nonz(swap->alicereclaim.I.actualtxid) != 0 ) + fprintf(fp,",\"Areclaim\":\"%s\"",bits256_str(str,swap->alicereclaim.I.actualtxid)); + + if ( bits256_nonz(swap->otherfee.I.actualtxid) != 0 ) + fprintf(fp,",\"otherfee\":\"%s\"",bits256_str(str,swap->otherfee.I.actualtxid)); + if ( bits256_nonz(swap->myfee.I.actualtxid) != 0 ) + fprintf(fp,",\"myfee\":\"%s\"",bits256_str(str,swap->myfee.I.actualtxid)); + fprintf(fp,",\"other33\":\""); + for (i=0; i<33; i++) + fprintf(fp,"%02x",swap->persistent_other33[i]); + fprintf(fp,"\",\"dest33\":\""); + for (i=0; i<33; i++) + fprintf(fp,"%02x",swap->persistent_pubkey33[i]); + fprintf(fp,"\"}\n"); + fclose(fp); + } +} + +void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) +{ + bits256 triggertxid; + memset(triggertxid.bytes,0,sizeof(triggertxid)); + if ( rawtx == 0 ) + { + basilisk_dontforget(swap,0,0,triggertxid); + return; + } + if ( rawtx == &swap->myfee ) + basilisk_dontforget(swap,&swap->myfee,0,triggertxid); + else if ( rawtx == &swap->otherfee ) + basilisk_dontforget(swap,&swap->otherfee,0,triggertxid); + else if ( rawtx == &swap->bobdeposit ) + { + basilisk_dontforget(swap,&swap->bobdeposit,0,triggertxid); + basilisk_dontforget(swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid); + } + else if ( rawtx == &swap->bobrefund ) + basilisk_dontforget(swap,&swap->bobrefund,swap->bobdeposit.I.locktime,triggertxid); + else if ( rawtx == &swap->aliceclaim ) + { + basilisk_dontforget(swap,&swap->bobrefund,0,triggertxid); + basilisk_dontforget(swap,&swap->aliceclaim,0,swap->bobrefund.I.actualtxid); + } + else if ( rawtx == &swap->alicepayment ) + { + basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + } + else if ( rawtx == &swap->bobspend ) + { + basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + basilisk_dontforget(swap,&swap->bobspend,0,swap->alicepayment.I.actualtxid); + } + else if ( rawtx == &swap->alicereclaim ) + { + basilisk_dontforget(swap,&swap->alicepayment,0,swap->bobdeposit.I.actualtxid); + basilisk_dontforget(swap,&swap->alicereclaim,0,swap->bobrefund.I.actualtxid); + } + else if ( rawtx == &swap->bobpayment ) + { + basilisk_dontforget(swap,&swap->bobpayment,0,triggertxid); + basilisk_dontforget(swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); + } + else if ( rawtx == &swap->alicespend ) + { + basilisk_dontforget(swap,&swap->bobpayment,0,triggertxid); + basilisk_dontforget(swap,&swap->alicespend,0,triggertxid); + } + else if ( rawtx == &swap->bobreclaim ) + basilisk_dontforget(swap,&swap->bobreclaim,swap->bobpayment.I.locktime,triggertxid); +} + +bits256 basilisk_swap_privbob_extract(char *symbol,bits256 spendtxid,int32_t vini,int32_t revflag) +{ + bits256 privkey; int32_t i,scriptlen,siglen; uint8_t script[1024]; // from Bob refund of Bob deposit + memset(&privkey,0,sizeof(privkey)); + if ( (scriptlen= basilisk_swap_getsigscript(symbol,script,(int32_t)sizeof(script),spendtxid,vini)) > 0 ) + { + siglen = script[0]; + for (i=0; i<32; i++) + { + if ( revflag != 0 ) + privkey.bytes[31 - i] = script[siglen+2+i]; + else privkey.bytes[i] = script[siglen+2+i]; + } + //char str[65]; printf("extracted privbob.(%s)\n",bits256_str(str,privkey)); + } + return(privkey); +} + +bits256 basilisk_swap_privBn_extract(bits256 *bobrefundp,char *bobcoin,bits256 bobdeposit,bits256 privBn) +{ + char destaddr[64]; + destaddr[0] = 0; + if ( bits256_nonz(privBn) == 0 ) + { + if ( bits256_nonz(bobdeposit) != 0 ) + *bobrefundp = LP_swap_spendtxid(bobcoin,destaddr,bobdeposit,0); + if ( bits256_nonz(*bobrefundp) != 0 ) + privBn = basilisk_swap_privbob_extract(bobcoin,*bobrefundp,0,0); + } + return(privBn); +} + +bits256 basilisk_swap_spendupdate(int32_t iambob,char *symbol,char *spentaddr,int32_t *sentflags,bits256 *txids,int32_t utxoind,int32_t alicespent,int32_t bobspent,int32_t utxovout,char *aliceaddr,char *bobaddr,char *Adest,char *dest) +{ + bits256 spendtxid,txid; char destaddr[64],str[65]; int32_t i,n; struct iguana_info *coin; cJSON *array,*txobj; + memset(&spendtxid,0,sizeof(spendtxid)); + destaddr[0] = 0; + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(spendtxid); + //printf("spentaddr.%s aliceaddr.%s bobaddr.%s Adest.%s Bdest.%s\n",spentaddr,aliceaddr,bobaddr,Adest,dest); + if ( coin->electrum != 0 ) + { + if ( (array= electrum_address_gethistory(symbol,coin->electrum,&array,spentaddr,txids[utxoind])) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i %s\n",bits256_str(str,txid),destaddr); + sentflags[alicespent] = 1; + sentflags[bobspent] = 0; + txids[alicespent] = spendtxid; + } + else if ( bobaddr != 0 && (strcmp(destaddr,bobaddr) == 0 || strcmp(dest,destaddr) == 0) ) + { + //printf("BOB spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + sentflags[bobspent] = 1; + sentflags[alicespent] = 0; + txids[bobspent] = spendtxid; + } + else + { + printf("OTHER dest spent.(%s) -> %s\n",bits256_str(str,txid),destaddr); + if ( iambob == 0 ) + { + sentflags[bobspent] = 1; + sentflags[alicespent] = 0; + txids[bobspent] = spendtxid; + } + else + { + sentflags[alicespent] = 1; + sentflags[bobspent] = 0; + txids[alicespent] = spendtxid; + } + } + } //else printf("no spend of %s/v%d detected\n",bits256_str(str,txid),vout); + } //else printf("utxoind.%d null txid\n",utxoind); + return(spendtxid); +} + +int32_t basilisk_isbobcoin(int32_t iambob,int32_t ind) +{ + switch ( ind ) + { + case BASILISK_MYFEE: return(iambob); break; + case BASILISK_OTHERFEE: return(!iambob); break; + case BASILISK_BOBSPEND: + case BASILISK_ALICEPAYMENT: + case BASILISK_ALICERECLAIM: + case BASILISK_ALICECLAIM: return(0); + break; + case BASILISK_BOBDEPOSIT: + case BASILISK_ALICESPEND: + case BASILISK_BOBPAYMENT: + case BASILISK_BOBREFUND: + case BASILISK_BOBRECLAIM: return(1); + break; + default: return(-1); break; + } +} + +int32_t basilisk_swap_isfinished(int32_t iambob,bits256 *txids,int32_t *sentflags,bits256 paymentspent,bits256 Apaymentspent,bits256 depositspent) +{ + int32_t i,n = 0; + for (i=0; i>= 1; + decode_hex(redeem,len,redeemstr); + t = redeem[5]; + t = (t << 8) | redeem[4]; + t = (t << 8) | redeem[3]; + t = (t << 8) | redeem[2]; + //printf("extracted timestamp.%u\n",t); + } + free_json(json); + } + free(filestr); + } + return(t); +} + +void LP_totals_update(int32_t iambob,char *alicecoin,char *bobcoin,int64_t *KMDtotals,int64_t *BTCtotals,int32_t *sentflags,int64_t *values) // update to handle all coins +{ + values[BASILISK_OTHERFEE] = 0; + if ( iambob == 0 ) + { + if ( strcmp(alicecoin,"BTC") == 0 ) + { + BTCtotals[BASILISK_ALICEPAYMENT] -= values[BASILISK_ALICEPAYMENT] * sentflags[BASILISK_ALICEPAYMENT]; + BTCtotals[BASILISK_ALICERECLAIM] += values[BASILISK_ALICEPAYMENT] * sentflags[BASILISK_ALICERECLAIM]; + BTCtotals[BASILISK_MYFEE] -= values[BASILISK_MYFEE] * sentflags[BASILISK_MYFEE]; + } + else if ( strcmp(alicecoin,"KMD") == 0 ) + { + KMDtotals[BASILISK_ALICEPAYMENT] -= values[BASILISK_ALICEPAYMENT] * sentflags[BASILISK_ALICEPAYMENT]; + KMDtotals[BASILISK_ALICERECLAIM] += values[BASILISK_ALICEPAYMENT] * sentflags[BASILISK_ALICERECLAIM]; + KMDtotals[BASILISK_MYFEE] -= values[BASILISK_MYFEE] * sentflags[BASILISK_MYFEE]; + } + if ( strcmp(bobcoin,"KMD") == 0 ) + { + KMDtotals[BASILISK_ALICESPEND] += values[BASILISK_BOBPAYMENT] * sentflags[BASILISK_ALICESPEND]; + KMDtotals[BASILISK_ALICECLAIM] += values[BASILISK_BOBDEPOSIT] * sentflags[BASILISK_ALICECLAIM]; + } + else if ( strcmp(bobcoin,"BTC") == 0 ) + { + BTCtotals[BASILISK_ALICESPEND] += values[BASILISK_BOBPAYMENT] * sentflags[BASILISK_ALICESPEND]; + BTCtotals[BASILISK_ALICECLAIM] += values[BASILISK_BOBDEPOSIT] * sentflags[BASILISK_ALICECLAIM]; + } + } + else + { + if ( strcmp(bobcoin,"BTC") == 0 ) + { + BTCtotals[BASILISK_BOBPAYMENT] -= values[BASILISK_BOBPAYMENT] * sentflags[BASILISK_BOBPAYMENT]; + BTCtotals[BASILISK_BOBDEPOSIT] -= values[BASILISK_BOBDEPOSIT] * sentflags[BASILISK_BOBDEPOSIT]; + BTCtotals[BASILISK_BOBREFUND] += values[BASILISK_BOBREFUND] * sentflags[BASILISK_BOBREFUND]; + BTCtotals[BASILISK_BOBRECLAIM] += values[BASILISK_BOBRECLAIM] * sentflags[BASILISK_BOBRECLAIM]; + BTCtotals[BASILISK_MYFEE] -= values[BASILISK_MYFEE] * sentflags[BASILISK_MYFEE]; + } + else if ( strcmp(bobcoin,"KMD") == 0 ) + { + KMDtotals[BASILISK_BOBPAYMENT] -= values[BASILISK_BOBPAYMENT] * sentflags[BASILISK_BOBPAYMENT]; + KMDtotals[BASILISK_BOBDEPOSIT] -= values[BASILISK_BOBDEPOSIT] * sentflags[BASILISK_BOBDEPOSIT]; + KMDtotals[BASILISK_BOBREFUND] += values[BASILISK_BOBDEPOSIT] * sentflags[BASILISK_BOBREFUND]; + KMDtotals[BASILISK_BOBRECLAIM] += values[BASILISK_BOBPAYMENT] * sentflags[BASILISK_BOBRECLAIM]; + KMDtotals[BASILISK_MYFEE] -= values[BASILISK_MYFEE] * sentflags[BASILISK_MYFEE]; + } + if ( strcmp(alicecoin,"KMD") == 0 ) + { + KMDtotals[BASILISK_BOBSPEND] += values[BASILISK_BOBSPEND] * sentflags[BASILISK_BOBSPEND]; + } + else if ( strcmp(alicecoin,"BTC") == 0 ) + { + BTCtotals[BASILISK_BOBSPEND] += values[BASILISK_ALICEPAYMENT] * sentflags[BASILISK_BOBSPEND]; + } + } +} + +cJSON *LP_swap_json(struct LP_swap_remember *rswap) +{ + cJSON *item,*array; int32_t i; + item = cJSON_CreateObject(); + if ( LP_swap_endcritical < LP_swap_critical ) + { + jaddstr(item,"warning","swaps in critical section, dont exit now"); + jaddnum(item,"critical",LP_swap_critical); + jaddnum(item,"endcritical",LP_swap_endcritical); + } + jaddnum(item,"expiration",rswap->expiration);// - INSTANTDEX_LOCKTIME*2); + jaddnum(item,"tradeid",rswap->tradeid); + jaddnum(item,"requestid",rswap->requestid); + jaddnum(item,"quoteid",rswap->quoteid); + jaddnum(item,"iambob",rswap->iambob); + jaddstr(item,"Bgui",rswap->Bgui); + jaddstr(item,"Agui",rswap->Agui); + jaddstr(item,"gui",rswap->gui); + jaddstr(item,"bob",rswap->src); + jaddnum(item,"srcamount",dstr(rswap->srcamount)); + jaddnum(item,"bobtxfee",dstr(rswap->Btxfee)); + jaddstr(item,"alice",rswap->dest); + jaddnum(item,"destamount",dstr(rswap->destamount)); + jaddnum(item,"alicetxfee",dstr(rswap->Atxfee)); + jadd64bits(item,"aliceid",rswap->aliceid); + array = cJSON_CreateArray(); + for (i=0; isentflags[i] != 0 ) + jaddistr(array,txnames[i]); + if ( rswap->txbytes[i] != 0 ) + free(rswap->txbytes[i]), rswap->txbytes[i] = 0; + } + jadd(item,"sentflags",array); + array = cJSON_CreateArray(); + for (i=0; ivalues[i])); + jadd(item,"values",array); + jaddstr(item,"result","success"); + if ( rswap->finishedflag != 0 ) + { + jaddstr(item,"status","finished"); + jaddnum(item,"finishtime",rswap->finishtime); + } + else jaddstr(item,"status","pending"); + jaddbits256(item,"bobdeposit",rswap->txids[BASILISK_BOBDEPOSIT]); + jaddbits256(item,"alicepayment",rswap->txids[BASILISK_ALICEPAYMENT]); + jaddbits256(item,"bobpayment",rswap->txids[BASILISK_BOBPAYMENT]); + jaddbits256(item,"paymentspent",rswap->paymentspent); + jaddbits256(item,"Apaymentspent",rswap->Apaymentspent); + jaddbits256(item,"depositspent",rswap->depositspent); + return(item); +} + +int32_t LP_rswap_init(struct LP_swap_remember *rswap,uint32_t requestid,uint32_t quoteid,int32_t forceflag) +{ + char fname[1024],*fstr,*secretstr,*srcstr,*deststr,*dest33,*txname; long fsize; cJSON *item,*txobj,*array; bits256 privkey; struct iguana_info *coin; uint32_t r,q; int32_t i,j,n; uint8_t other33[33]; + memset(rswap,0,sizeof(*rswap)); + rswap->requestid = requestid; + rswap->quoteid = quoteid; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) + { + if ( (item= cJSON_Parse(fstr)) != 0 ) + { + rswap->iambob = jint(item,"iambob"); + safecopy(rswap->Bgui,jstr(item,"Bgui"),sizeof(rswap->Bgui)); + safecopy(rswap->Agui,jstr(item,"Agui"),sizeof(rswap->Agui)); + safecopy(rswap->gui,jstr(item,"gui"),sizeof(rswap->gui)); + rswap->tradeid = juint(item,"tradeid"); + rswap->aliceid = j64bits(item,"aliceid"); + if ( (secretstr= jstr(item,"secretAm")) != 0 && strlen(secretstr) == 40 ) + decode_hex(rswap->secretAm,20,secretstr); + if ( (secretstr= jstr(item,"secretAm256")) != 0 && strlen(secretstr) == 64 ) + decode_hex(rswap->secretAm256,32,secretstr); + if ( (secretstr= jstr(item,"secretBn")) != 0 && strlen(secretstr) == 40 ) + decode_hex(rswap->secretBn,20,secretstr); + if ( (secretstr= jstr(item,"secretBn256")) != 0 && strlen(secretstr) == 64 ) + decode_hex(rswap->secretBn256,32,secretstr); + if ( (srcstr= jstr(item,"src")) != 0 ) + safecopy(rswap->src,srcstr,sizeof(rswap->src)); + if ( (deststr= jstr(item,"dest")) != 0 ) + safecopy(rswap->dest,deststr,sizeof(rswap->dest)); + if ( (dest33= jstr(item,"dest33")) != 0 && strlen(dest33) == 66 ) + { + decode_hex(rswap->pubkey33,33,dest33); + if ( rswap->iambob != 0 && (coin= LP_coinfind(rswap->src)) != 0 ) + bitcoin_address(coin->symbol,rswap->destaddr,coin->taddr,coin->pubtype,rswap->pubkey33,33); + else if ( rswap->iambob == 0 && (coin= LP_coinfind(rswap->dest)) != 0 ) + bitcoin_address(coin->symbol,rswap->Adestaddr,coin->taddr,coin->pubtype,rswap->pubkey33,33); + //for (i=0; i<33; i++) + // printf("%02x",pubkey33[i]); + //printf(" <- %s dest33\n",dest33); + } + if ( (dest33= jstr(item,"other33")) != 0 && strlen(dest33) == 66 ) + { + decode_hex(other33,33,dest33); + for (i=0; i<33; i++) + if ( other33[i] != 0 ) + break; + if ( i < 33 ) + memcpy(rswap->other33,other33,33); + if ( rswap->iambob != 0 && (coin= LP_coinfind(rswap->dest)) != 0 ) + bitcoin_address(coin->symbol,rswap->Adestaddr,coin->taddr,coin->pubtype,rswap->other33,33); + else if ( rswap->iambob == 0 && (coin= LP_coinfind(rswap->src)) != 0 ) + bitcoin_address(coin->symbol,rswap->destaddr,coin->taddr,coin->pubtype,rswap->other33,33); + //printf("(%s, %s) <- %s other33\n",rswap->destaddr,rswap->Adestaddr,dest33); + } + if ( (rswap->plocktime= juint(item,"plocktime")) == 0 ) + rswap->plocktime = LP_extract(requestid,quoteid,fname,"plocktime"); + if ( (rswap->dlocktime= juint(item,"dlocktime")) == 0 ) + rswap->dlocktime = LP_extract(requestid,quoteid,fname,"dlocktime"); + r = juint(item,"requestid"); + q = juint(item,"quoteid"); + rswap->Atxfee = j64bits(item,"Atxfee"); + rswap->Btxfee = j64bits(item,"Btxfee"); + rswap->pubA0 = jbits256(item,"pubA0"); + rswap->pubB0 = jbits256(item,"pubB0"); + rswap->pubB1 = jbits256(item,"pubB1"); + privkey = jbits256(item,"myprivs0"); + if ( bits256_nonz(privkey) != 0 ) + rswap->myprivs[0] = privkey; + privkey = jbits256(item,"myprivs1"); + if ( bits256_nonz(privkey) != 0 ) + rswap->myprivs[1] = privkey; + privkey = jbits256(item,"privAm"); + if ( bits256_nonz(privkey) != 0 ) + { + rswap->privAm = privkey; + //printf("set privAm <- %s\n",bits256_str(str,privAm)); + } + privkey = jbits256(item,"privBn"); + if ( bits256_nonz(privkey) != 0 ) + { + rswap->privBn = privkey; + //printf("set privBn <- %s\n",bits256_str(str,privBn)); + } + rswap->expiration = juint(item,"expiration"); + rswap->state = jint(item,"state"); + rswap->otherstate = jint(item,"otherstate"); + rswap->srcamount = SATOSHIDEN * jdouble(item,"srcamount"); + rswap->destamount = SATOSHIDEN * jdouble(item,"destamount"); + rswap->txids[BASILISK_BOBDEPOSIT] = jbits256(item,"Bdeposit"); + rswap->txids[BASILISK_BOBREFUND] = jbits256(item,"Brefund"); + rswap->txids[BASILISK_ALICECLAIM] = jbits256(item,"Aclaim"); + rswap->txids[BASILISK_BOBPAYMENT] = jbits256(item,"Bpayment"); + rswap->txids[BASILISK_ALICESPEND] = jbits256(item,"Aspend"); + rswap->txids[BASILISK_BOBRECLAIM] = jbits256(item,"Breclaim"); + rswap->txids[BASILISK_ALICEPAYMENT] = jbits256(item,"Apayment"); + rswap->txids[BASILISK_BOBSPEND] = jbits256(item,"Bspend"); + rswap->txids[BASILISK_ALICERECLAIM] = jbits256(item,"Areclaim"); + rswap->txids[BASILISK_MYFEE] = jbits256(item,"myfee"); + rswap->txids[BASILISK_OTHERFEE] = jbits256(item,"otherfee"); + free_json(item); + } + free(fstr); + } + sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) + { + //printf("%s -> (%s)\n",fname,fstr); + if ( (txobj= cJSON_Parse(fstr)) != 0 ) + { + rswap->paymentspent = jbits256(txobj,"paymentspent"); + rswap->Apaymentspent = jbits256(txobj,"Apaymentspent"); + rswap->depositspent = jbits256(txobj,"depositspent"); + if ( (array= jarray(&n,txobj,"values")) != 0 ) + for (i=0; ivalues[i] = SATOSHIDEN * jdouble(jitem(array,i),0); + if ( (array= jarray(&n,txobj,"sentflags")) != 0 ) + { + for (i=0; isentflags[j] = 1; + //printf("finished.%s\n",txnames[j]); + break; + } + } + } + } + free_json(txobj); + } + rswap->origfinishedflag = basilisk_swap_isfinished(rswap->iambob,rswap->txids,rswap->sentflags,rswap->paymentspent,rswap->Apaymentspent,rswap->depositspent); + rswap->finishedflag = rswap->origfinishedflag; + if ( forceflag != 0 ) + rswap->finishedflag = rswap->origfinishedflag = 0; + free(fstr); + } + return(rswap->iambob); +} + +int32_t _LP_refht_update(struct iguana_info *coin,bits256 txid,int32_t refht) +{ + refht -= 9; + if ( refht > 10 && (coin->firstrefht == 0 || refht < coin->firstrefht) ) + { + char str[65]; printf(">>>>>>>>. 1st refht %s %s <- %d, scan %d %d\n",coin->symbol,bits256_str(str,txid),refht,coin->firstscanht,coin->lastscanht); + if ( coin->firstscanht == 0 || refht < coin->firstscanht ) + coin->firstscanht = coin->lastscanht = refht; + coin->firstrefht = refht; + return(1); + } + return(0); +} + +int32_t LP_refht_update(char *symbol,bits256 txid) +{ + int32_t refht; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 ) + { + if ( (refht= LP_txheight(coin,txid)) > 0 && refht > 0 ) + return(_LP_refht_update(coin,txid,refht)); + } + return(0); +} + +int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag) +{ + int32_t i,needflag,addflag; long fsize; char fname[1024],*fstr,*symbol,*rstr; cJSON *txobj,*sentobj,*fileobj; bits256 txid,checktxid; uint64_t value; + rswap->iambob = -1; + sprintf(fname,"%s/SWAPS/%u-%u.finished",GLOBAL_DBDIR,rswap->requestid,rswap->quoteid), OS_compatible_path(fname); + if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) + { + if ( (fileobj= cJSON_Parse(fstr)) != 0 ) + { + rswap->finishtime = juint(fileobj,"finishtime"); + if ( forceflag == 0 ) + rswap->origfinishedflag = rswap->finishedflag = 1; + free_json(fileobj); + } + free(fstr); + } + for (i=0; irequestid,rswap->quoteid,txnames[i]), OS_compatible_path(fname); + if ( (fstr= OS_filestr(&fsize,fname)) != 0 ) + { + if ( 0 && rswap->finishedflag == 0 ) + printf("%s\n",fname); + //printf("%s -> (%s)\n",fname,fstr); + if ( (txobj= cJSON_Parse(fstr)) != 0 ) + { + //printf("TXOBJ.(%s)\n",jprint(txobj,0)); + if ( jobj(txobj,"iambob") != 0 ) + rswap->iambob = jint(txobj,"iambob"); + txid = jbits256(txobj,"txid"); + if ( bits256_nonz(txid) == 0 ) + { + free(fstr); + free_json(txobj); + continue; + } + rswap->txids[i] = txid; + if ( jstr(txobj,"Apayment") != 0 ) + safecopy(rswap->alicepaymentaddr,jstr(txobj,"Apayment"),sizeof(rswap->alicepaymentaddr)); + if ( jstr(txobj,"Bpayment") != 0 ) + safecopy(rswap->bobpaymentaddr,jstr(txobj,"Bpayment"),sizeof(rswap->bobpaymentaddr)); + if ( jstr(txobj,"Bdeposit") != 0 ) + safecopy(rswap->bobdepositaddr,jstr(txobj,"Bdeposit"),sizeof(rswap->bobdepositaddr)); + if ( jobj(txobj,"tx") != 0 ) + { + rswap->txbytes[i] = clonestr(jstr(txobj,"tx")); + //printf("[%s] TX.(%s)\n",txnames[i],txbytes[i]); + } + if ( strcmp(txnames[i],"bobpayment") == 0 && (rstr= jstr(txobj,"redeem")) != 0 && (rswap->Predeemlen= is_hexstr(rstr,0)) > 0 ) + { + rswap->Predeemlen >>= 1; + decode_hex(rswap->Predeemscript,rswap->Predeemlen,rstr); + } + else if ( strcmp(txnames[i],"bobdeposit") == 0 && (rstr= jstr(txobj,"redeem")) != 0 && (rswap->Dredeemlen= is_hexstr(rstr,0)) > 0 ) + { + rswap->Dredeemlen >>= 1; + decode_hex(rswap->Dredeemscript,rswap->Dredeemlen,rstr); + } + rswap->values[i] = value = LP_value_extract(txobj,1); + if ( (symbol= jstr(txobj,"src")) != 0 ) + { + safecopy(rswap->src,symbol,sizeof(rswap->src)); + if ( rswap->iambob >= 0 ) + { + if ( rswap->iambob > 0 ) + safecopy(rswap->bobcoin,symbol,sizeof(rswap->bobcoin)); + else safecopy(rswap->alicecoin,symbol,sizeof(rswap->alicecoin)); + } + } + if ( (symbol= jstr(txobj,"dest")) != 0 ) + { + safecopy(rswap->dest,symbol,sizeof(rswap->dest)); + if ( rswap->iambob >= 0 ) + { + if ( rswap->iambob == 0 ) + safecopy(rswap->bobcoin,symbol,sizeof(rswap->bobcoin)); + else safecopy(rswap->alicecoin,symbol,sizeof(rswap->alicecoin)); + } + } + if ( (symbol= jstr(txobj,"coin")) != 0 ) + { + if ( i == BASILISK_ALICESPEND || i == BASILISK_BOBPAYMENT || i == BASILISK_BOBDEPOSIT || i == BASILISK_BOBREFUND || i == BASILISK_BOBRECLAIM || i == BASILISK_ALICECLAIM ) + safecopy(rswap->bobcoin,symbol,sizeof(rswap->bobcoin)); + else if ( i == BASILISK_BOBSPEND || i == BASILISK_ALICEPAYMENT || i == BASILISK_ALICERECLAIM ) + safecopy(rswap->alicecoin,symbol,sizeof(rswap->alicecoin)); + if ( rswap->finishedflag == 0 ) + { + if ( (sentobj= LP_gettx(symbol,txid,1)) == 0 ) + { + char str2[65]; printf("%s %s ready to broadcast %s r%u q%u\n",symbol,bits256_str(str2,txid),txnames[i],rswap->requestid,rswap->quoteid); + } + else + { + checktxid = jbits256(sentobj,"txid"); + if ( bits256_nonz(checktxid) == 0 ) + checktxid = jbits256(sentobj,"hash"); + LP_refht_update(symbol,txid); + if ( bits256_cmp(checktxid,txid) == 0 ) + { + //printf(">>>>>> %s txid %s\n",jprint(sentobj,0),bits256_str(str,txid)); + rswap->sentflags[i] = 1; + } + free_json(sentobj); + } + //printf("%s %s %.8f\n",txnames[i],bits256_str(str,txid),dstr(value)); + } + } + free_json(txobj); + } //else printf("no symbol\n"); + free(fstr); + } else if ( 0 && rswap->finishedflag == 0 ) + printf("%s not finished\n",fname); + } + if ( rswap->bobcoin[0] == 0 ) + strcpy(rswap->bobcoin,rswap->src); + if ( rswap->alicecoin[0] == 0 ) + strcpy(rswap->alicecoin,rswap->dest); + if ( rswap->src[0] == 0 ) + strcpy(rswap->src,rswap->bobcoin); + if ( rswap->dest[0] == 0 ) + strcpy(rswap->dest,rswap->alicecoin); + return(rswap->finishedflag); +} + +void LP_txbytes_update(char *name,char *symbol,char *txbytes,bits256 *txidp,bits256 *ptr,int32_t *flagp) +{ + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + if ( txbytes != 0 ) + { + *txidp = LP_broadcast(name,symbol,txbytes,zero); + if ( bits256_nonz(*txidp) != 0 ) + { + *flagp = 1; + if ( ptr != 0 ) + *ptr = *txidp; + } + } +} + +int32_t LP_rswap_checktx(struct LP_swap_remember *rswap,char *symbol,int32_t txi) +{ + int32_t ht; struct iguana_info *coin; //char str[65]; + if ( rswap->sentflags[txi] == 0 && bits256_nonz(rswap->txids[txi]) != 0 ) + { + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( (ht= LP_txheight(coin,rswap->txids[txi])) > 0 ) + { + rswap->sentflags[txi] = 1; + _LP_refht_update(coin,rswap->txids[txi],ht); + } else LP_refht_update(symbol,rswap->txids[txi]); + //printf("[%s] %s txbytes.%p %s ht.%d\n",txnames[txi],txnames[txi],rswap->txbytes[txi],bits256_str(str,rswap->txids[txi]),ht); + } + } //else printf("sent.%d %s txi.%d\n",rswap->sentflags[txi],bits256_str(str,rswap->txids[txi]),txi); + return(0); +} + +int32_t LP_spends_set(struct LP_swap_remember *rswap) +{ + int32_t numspent = 0; + if ( bits256_nonz(rswap->paymentspent) == 0 ) + { + if ( bits256_nonz(rswap->txids[BASILISK_ALICESPEND]) != 0 ) + rswap->paymentspent = rswap->txids[BASILISK_ALICESPEND]; + else rswap->paymentspent = rswap->txids[BASILISK_BOBRECLAIM]; + } else numspent++; + if ( bits256_nonz(rswap->depositspent) == 0 ) + { + if ( bits256_nonz(rswap->txids[BASILISK_BOBREFUND]) != 0 ) + rswap->depositspent = rswap->txids[BASILISK_BOBREFUND]; + else rswap->depositspent = rswap->txids[BASILISK_ALICECLAIM]; + } else numspent++; + if ( bits256_nonz(rswap->Apaymentspent) == 0 ) + { + if ( bits256_nonz(rswap->txids[BASILISK_BOBSPEND]) != 0 ) + rswap->Apaymentspent = rswap->txids[BASILISK_BOBSPEND]; + else rswap->Apaymentspent = rswap->txids[BASILISK_ALICERECLAIM]; + } else numspent++; + return(numspent); +} + +cJSON *basilisk_remember(int64_t *KMDtotals,int64_t *BTCtotals,uint32_t requestid,uint32_t quoteid,int32_t forceflag,int32_t pendingonly) +{ + static void *ctx; + struct LP_swap_remember rswap; int32_t i,j,flag,numspent,len,secretstart,redeemlen; char str[65],*srcAdest,*srcBdest,*destAdest,*destBdest,otheraddr[64]; cJSON *item,*txoutobj; bits256 rev,signedtxid,zero,deadtxid; uint32_t claimtime; struct iguana_info *bob=0,*alice=0; uint8_t redeemscript[1024],userdata[1024]; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + if ( requestid == 0 || quoteid == 0 ) + return(cJSON_Parse("{\"error\":\"null requestid or quoteid\"}")); + if ( (rswap.iambob= LP_rswap_init(&rswap,requestid,quoteid,forceflag)) < 0 ) + return(cJSON_Parse("{\"error\":\"couldnt initialize rswap, are all coins active?\"}")); + decode_hex(deadtxid.bytes,32,"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + LP_swap_load(&rswap,forceflag); + memset(zero.bytes,0,sizeof(zero)); + otheraddr[0] = 0; + claimtime = (uint32_t)time(NULL) - 777; + srcAdest = srcBdest = destAdest = destBdest = 0; + if ( rswap.bobcoin[0] == 0 || rswap.alicecoin[0] == 0 || strcmp(rswap.bobcoin,rswap.src) != 0 || strcmp(rswap.alicecoin,rswap.dest) != 0 ) + { + //printf("legacy r%u-q%u DB SWAPS.(%u %u) %llu files BOB.(%s) Alice.(%s) src.(%s) dest.(%s)\n",requestid,quoteid,rswap.requestid,rswap.quoteid,(long long)rswap.aliceid,rswap.bobcoin,rswap.alicecoin,rswap.src,rswap.dest); + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","swap never started"); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + return(retjson); + //return(cJSON_Parse("{\"error\":\"mismatched bob/alice vs src/dest coins??\"}")); + } + alice = LP_coinfind(rswap.alicecoin); + bob = LP_coinfind(rswap.bobcoin); + rswap.Atxfee = LP_txfeecalc(alice,rswap.Atxfee,0); + rswap.Btxfee = LP_txfeecalc(bob,rswap.Btxfee,0); + if ( rswap.iambob == 0 ) + { + if ( alice != 0 ) + { + bitcoin_address(alice->symbol,otheraddr,alice->taddr,alice->pubtype,rswap.other33,33); + destBdest = otheraddr; + destAdest = rswap.Adestaddr; + if ( LP_TECHSUPPORT == 0 && strcmp(alice->smartaddr,rswap.Adestaddr) != 0 ) + { + printf("this isnt my swap! alice.(%s vs %s)\n",alice->smartaddr,rswap.Adestaddr); + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","swap for different account"); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + return(retjson); + } + } + if ( (bob= LP_coinfind(rswap.bobcoin)) != 0 ) + { + bitcoin_address(bob->symbol,rswap.Sdestaddr,bob->taddr,bob->pubtype,rswap.pubkey33,33); + srcAdest = rswap.Sdestaddr; + } + srcBdest = rswap.destaddr; + } + else + { + if ( bob != 0 ) + { + bitcoin_address(bob->symbol,otheraddr,bob->taddr,bob->pubtype,rswap.other33,33); + srcAdest = otheraddr; + srcBdest = rswap.destaddr; + if ( LP_TECHSUPPORT == 0 && strcmp(bob->smartaddr,rswap.destaddr) != 0 ) + { + printf("this isnt my swap! bob.(%s vs %s)\n",bob->smartaddr,rswap.destaddr); + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","swap for different account"); + jaddnum(retjson,"requestid",requestid); + jaddnum(retjson,"quoteid",quoteid); + return(retjson); + } + } + if ( (alice= LP_coinfind(rswap.alicecoin)) != 0 ) + { + bitcoin_address(alice->symbol,rswap.Sdestaddr,alice->taddr,alice->pubtype,rswap.pubkey33,33); + destBdest = rswap.Sdestaddr; + } + destAdest = rswap.Adestaddr; + } + if ( bob == 0 || alice == 0 ) + { + printf("Bob.%p is null or Alice.%p is null\n",bob,alice); + return(cJSON_Parse("{\"error\":\"null bob or alice coin\"}")); + } + //printf("src.(Adest %s, Bdest %s), dest.(Adest %s, Bdest %s)\n",srcAdest,srcBdest,destAdest,destBdest); + //printf("iambob.%d finishedflag.%d %s %.8f txfee, %s %.8f txfee\n",rswap.iambob,rswap.finishedflag,rswap.alicecoin,dstr(rswap.Atxfee),rswap.bobcoin,dstr(rswap.Btxfee)); + //printf("privAm.(%s) %p/%p\n",bits256_str(str,rswap.privAm),Adest,AAdest); + //printf("privBn.(%s) %p/%p\n",bits256_str(str,rswap.privBn),Bdest,ABdest); + if ( rswap.finishedflag == 0 && rswap.bobcoin[0] != 0 && rswap.alicecoin[0] != 0 ) + { + //printf("ALICE.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.Adestaddr,alice->symbol,alice->firstrefht,alice->firstscanht,alice->lastscanht); + //printf("BOB.(%s) 1st refht %s <- %d, scan %d %d\n",rswap.destaddr,bob->symbol,bob->firstrefht,bob->firstscanht,bob->lastscanht); + if ( alice->inactive != 0 || bob->inactive != 0 ) + { + printf("Alice.%s inactive.%u or Bob.%s inactive.%u\n",rswap.alicecoin,alice->inactive,rswap.bobcoin,bob->inactive); + return(cJSON_Parse("{\"error\":\"inactive bob or alice coin\"}")); + } + LP_rswap_checktx(&rswap,rswap.alicecoin,BASILISK_ALICEPAYMENT); + LP_rswap_checktx(&rswap,rswap.bobcoin,BASILISK_BOBPAYMENT); + LP_rswap_checktx(&rswap,rswap.bobcoin,BASILISK_BOBDEPOSIT); + rswap.paymentspent = basilisk_swap_spendupdate(rswap.iambob,rswap.bobcoin,rswap.bobpaymentaddr,rswap.sentflags,rswap.txids,BASILISK_BOBPAYMENT,BASILISK_ALICESPEND,BASILISK_BOBRECLAIM,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr); + rswap.Apaymentspent = basilisk_swap_spendupdate(rswap.iambob,rswap.alicecoin,rswap.alicepaymentaddr,rswap.sentflags,rswap.txids,BASILISK_ALICEPAYMENT,BASILISK_ALICERECLAIM,BASILISK_BOBSPEND,0,destAdest,destBdest,rswap.Adestaddr,rswap.destaddr); + rswap.depositspent = basilisk_swap_spendupdate(rswap.iambob,rswap.bobcoin,rswap.bobdepositaddr,rswap.sentflags,rswap.txids,BASILISK_BOBDEPOSIT,BASILISK_ALICECLAIM,BASILISK_BOBREFUND,0,srcAdest,srcBdest,rswap.Adestaddr,rswap.destaddr); + rswap.finishedflag = basilisk_swap_isfinished(rswap.iambob,rswap.txids,rswap.sentflags,rswap.paymentspent,rswap.Apaymentspent,rswap.depositspent); + LP_spends_set(&rswap); + if ( rswap.iambob == 0 ) + { + if ( rswap.sentflags[BASILISK_ALICESPEND] == 0 ) + { + if ( rswap.sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(rswap.paymentspent) == 0 ) + { + flag = 0; + if ( bob->electrum == 0 ) + { + if ( (txoutobj= LP_gettxout(rswap.bobcoin,rswap.bobpaymentaddr,rswap.txids[BASILISK_BOBPAYMENT],0)) != 0 ) + free_json(txoutobj), flag = 0; + else flag = -1, rswap.paymentspent = deadtxid; + } + if ( flag == 0 ) + { + if ( bits256_nonz(rswap.txids[BASILISK_BOBPAYMENT]) != 0 ) + { + // alicespend + memset(rev.bytes,0,sizeof(rev)); + for (j=0; j<32; j++) + rev.bytes[j] = rswap.privAm.bytes[31 - j]; + //revcalc_rmd160_sha256(secretAm,rev);//privAm); + //vcalc_sha256(0,secretAm256,rev.bytes,sizeof(rev)); + if ( rswap.Predeemlen != 0 ) + redeemlen = rswap.Predeemlen, memcpy(redeemscript,rswap.Predeemscript,rswap.Predeemlen); + else redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,rswap.plocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rev,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); + len = basilisk_swapuserdata(userdata,rev,0,rswap.myprivs[0],redeemscript,redeemlen); + { + char privaddr[64]; uint8_t privpub33[33]; + bitcoin_pubkey33(ctx,privpub33,rswap.myprivs[0]); + bitcoin_address(rswap.bobcoin,privaddr,0,60,privpub33,33); + printf("alicespend len.%d redeemlen.%d priv0addr.(%s) priv0.(%s)\n",len,redeemlen,privaddr,bits256_str(str,rswap.myprivs[0])); + } + for (j=0; j<32; j++) + rev.bytes[j] = rswap.myprivs[0].bytes[31 - j]; + if ( (rswap.txbytes[BASILISK_ALICESPEND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"alicespend",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_ALICESPEND],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + { + //printf("alicespend.(%s)\n",rswap.txbytes[BASILISK_ALICESPEND]); + } + } + LP_txbytes_update("alicespend",rswap.bobcoin,rswap.txbytes[BASILISK_ALICESPEND],&rswap.txids[BASILISK_ALICESPEND],&rswap.paymentspent,&rswap.sentflags[BASILISK_ALICESPEND]); + } + } + } + if ( rswap.sentflags[BASILISK_ALICECLAIM] == 0 && rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(rswap.depositspent) == 0 ) + { + if ( time(NULL) > rswap.expiration+777 ) + { + flag = 0; + if ( bob->electrum == 0 ) + { + if ( (txoutobj= LP_gettxout(rswap.bobcoin,rswap.bobdepositaddr,rswap.txids[BASILISK_BOBDEPOSIT],0)) != 0 ) + free_json(txoutobj), flag = 0; + else flag = -1, rswap.depositspent = deadtxid; + } + //if ( flag == 0 ) + { + if ( rswap.Dredeemlen != 0 ) + redeemlen = rswap.Dredeemlen, memcpy(redeemscript,rswap.Dredeemscript,rswap.Dredeemlen); + else redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,zero,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); + if ( redeemlen > 0 ) + { + len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[0],redeemscript,redeemlen); + if ( (rswap.txbytes[BASILISK_ALICECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"aliceclaim",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,0,claimtime,&rswap.values[BASILISK_ALICECLAIM],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + printf("claimtime.%u aliceclaim.(%s)\n",claimtime,rswap.txbytes[BASILISK_ALICECLAIM]); + } + LP_txbytes_update("aliceclaim",rswap.bobcoin,rswap.txbytes[BASILISK_ALICECLAIM],&rswap.txids[BASILISK_ALICECLAIM],&rswap.depositspent,&rswap.sentflags[BASILISK_ALICECLAIM]); + } + } else printf("now %u before expiration %u\n",(uint32_t)time(NULL),rswap.expiration); + } + if ( rswap.sentflags[BASILISK_ALICEPAYMENT] != 0 && bits256_nonz(rswap.Apaymentspent) == 0 && rswap.sentflags[BASILISK_ALICECLAIM] == 0 ) + { + flag = 0; + if ( alice->electrum == 0 ) + { + if ( (txoutobj= LP_gettxout(rswap.alicecoin,rswap.alicepaymentaddr,rswap.txids[BASILISK_ALICEPAYMENT],0)) != 0 ) + free_json(txoutobj), flag = 0; + else flag = -1, rswap.Apaymentspent = deadtxid; + } + if ( flag == 0 ) + { + rswap.privBn = basilisk_swap_privBn_extract(&rswap.txids[BASILISK_BOBREFUND],rswap.bobcoin,rswap.txids[BASILISK_BOBDEPOSIT],rswap.privBn); + if ( bits256_nonz(rswap.txids[BASILISK_ALICEPAYMENT]) != 0 && bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 ) + { + if ( (rswap.txbytes[BASILISK_ALICERECLAIM]= basilisk_swap_Aspend("alicereclaim",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_ALICERECLAIM],rswap.alicepaymentaddr,alice->zcash)) != 0 ) + printf("alicereclaim.(%s)\n",rswap.txbytes[BASILISK_ALICERECLAIM]); + } + LP_txbytes_update("alicereclaim",rswap.alicecoin,rswap.txbytes[BASILISK_ALICERECLAIM],&rswap.txids[BASILISK_ALICERECLAIM],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_ALICERECLAIM]); + } + } + } + else if ( rswap.iambob == 1 ) + { + if ( rswap.sentflags[BASILISK_BOBSPEND] == 0 && bits256_nonz(rswap.Apaymentspent) == 0 ) + { + //printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,rswap.txids[BASILISK_ALICESPEND]),bits256_nonz(rswap.privAm)); + if ( bits256_nonz(rswap.txids[BASILISK_ALICESPEND]) != 0 || bits256_nonz(rswap.privAm) != 0 ) + { + flag = 0; + if ( alice->electrum == 0 ) + { + if ( (txoutobj= LP_gettxout(rswap.alicecoin,rswap.alicepaymentaddr,rswap.txids[BASILISK_ALICEPAYMENT],0)) != 0 ) + free_json(txoutobj), flag = 0; + else flag = -1, rswap.Apaymentspent = deadtxid; + } + if ( flag == 0 ) + { + if ( bits256_nonz(rswap.privAm) == 0 ) + { + rswap.privAm = basilisk_swap_privbob_extract(rswap.bobcoin,rswap.txids[BASILISK_ALICESPEND],0,1); + //printf("try to bobspend aspend.%s have privAm.%d\n",bits256_str(str,rswap.txids[BASILISK_ALICESPEND]),bits256_nonz(rswap.privAm)); + } + if ( bits256_nonz(rswap.privAm) != 0 && bits256_nonz(rswap.privBn) != 0 ) + { + if ( (rswap.txbytes[BASILISK_BOBSPEND]= basilisk_swap_Aspend("bobspend",rswap.alicecoin,rswap.Atxfee,alice->wiftaddr,alice->taddr,alice->pubtype,alice->p2shtype,alice->isPoS,alice->wiftype,ctx,rswap.privAm,rswap.privBn,rswap.txids[BASILISK_ALICEPAYMENT],0,rswap.pubkey33,rswap.expiration,&rswap.values[BASILISK_BOBSPEND],rswap.alicepaymentaddr,alice->zcash)) != 0 ) + { + //printf("bobspend.(%s)\n",rswap.txbytes[BASILISK_BOBSPEND]); + } + } + LP_txbytes_update("bobspend",rswap.alicecoin,rswap.txbytes[BASILISK_BOBSPEND],&rswap.txids[BASILISK_BOBSPEND],&rswap.Apaymentspent,&rswap.sentflags[BASILISK_BOBSPEND]); + } + } + } + if ( rswap.sentflags[BASILISK_BOBRECLAIM] == 0 && rswap.sentflags[BASILISK_BOBPAYMENT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBPAYMENT]) != 0 && bits256_nonz(rswap.paymentspent) == 0 ) + { + flag = 0; + if ( bob->electrum == 0 ) + { + if ( (txoutobj= LP_gettxout(rswap.bobcoin,rswap.bobpaymentaddr,rswap.txids[BASILISK_BOBPAYMENT],0)) != 0 ) + free_json(txoutobj), flag = 0; + else flag = -1, rswap.paymentspent = deadtxid; + } + if ( time(NULL) > rswap.expiration+777 ) + { + // bobreclaim + redeemlen = basilisk_swap_bobredeemscript(0,&secretstart,redeemscript,rswap.plocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,zero,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); + if ( redeemlen > 0 ) + { + len = basilisk_swapuserdata(userdata,zero,1,rswap.myprivs[1],redeemscript,redeemlen); + if ( (rswap.txbytes[BASILISK_BOBRECLAIM]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[1],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBPAYMENT],0,0,rswap.pubkey33,0,claimtime,&rswap.values[BASILISK_BOBRECLAIM],0,0,rswap.bobpaymentaddr,1,bob->zcash)) != 0 ) + { + //int32_t z; + //for (z=0; z<20; z++) + // printf("%02x",rswap.secretAm[z]); + //printf(" secretAm, myprivs[1].(%s) bobreclaim.(%s)\n",bits256_str(str,rswap.myprivs[1]),rswap.txbytes[BASILISK_BOBRECLAIM]); + } + } + LP_txbytes_update("bobreclaim",rswap.bobcoin,rswap.txbytes[BASILISK_BOBRECLAIM],&rswap.txids[BASILISK_BOBRECLAIM],&rswap.paymentspent,&rswap.sentflags[BASILISK_BOBRECLAIM]); + } + else if ( flag == 0 ) + { + //printf("bobpayment: now.%u < expiration %u\n",(uint32_t)time(NULL),rswap.expiration); + } + } + if ( rswap.sentflags[BASILISK_BOBREFUND] == 0 && rswap.sentflags[BASILISK_BOBDEPOSIT] != 0 && bits256_nonz(rswap.txids[BASILISK_BOBDEPOSIT]) != 0 && bits256_nonz(rswap.depositspent) == 0 ) + { + flag = 0; + if ( bob->electrum == 0 ) + { + if ( (txoutobj= LP_gettxout(rswap.bobcoin,rswap.bobdepositaddr,rswap.txids[BASILISK_BOBDEPOSIT],0)) != 0 ) + free_json(txoutobj), flag = 0; + else flag = -1, rswap.depositspent = deadtxid; + } + if ( bits256_nonz(rswap.Apaymentspent) != 0 || time(NULL) > rswap.expiration+777 ) + { + //printf("do the refund! paymentspent.%s now.%u vs expiration.%u\n",bits256_str(str,rswap.paymentspent),(uint32_t)time(NULL),rswap.expiration); + //if ( txbytes[BASILISK_BOBREFUND] == 0 ) + { + revcalc_rmd160_sha256(rswap.secretBn,rswap.privBn); + vcalc_sha256(0,rswap.secretBn256,rswap.privBn.bytes,sizeof(rswap.privBn)); + redeemlen = basilisk_swap_bobredeemscript(1,&secretstart,redeemscript,rswap.dlocktime,rswap.pubA0,rswap.pubB0,rswap.pubB1,rswap.privAm,rswap.privBn,rswap.secretAm,rswap.secretAm256,rswap.secretBn,rswap.secretBn256); + len = basilisk_swapuserdata(userdata,rswap.privBn,0,rswap.myprivs[0],redeemscript,redeemlen); + if ( (rswap.txbytes[BASILISK_BOBREFUND]= basilisk_swap_bobtxspend(&signedtxid,rswap.Btxfee,"bobrefund",rswap.bobcoin,bob->wiftaddr,bob->taddr,bob->pubtype,bob->p2shtype,bob->isPoS,bob->wiftype,ctx,rswap.myprivs[0],0,redeemscript,redeemlen,userdata,len,rswap.txids[BASILISK_BOBDEPOSIT],0,0,rswap.pubkey33,1,rswap.expiration,&rswap.values[BASILISK_BOBREFUND],0,0,rswap.bobdepositaddr,1,bob->zcash)) != 0 ) + { + //printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,rswap.pubB1),rswap.txbytes[BASILISK_BOBREFUND]); + } + } + LP_txbytes_update("bobrefund",rswap.bobcoin,rswap.txbytes[BASILISK_BOBREFUND],&rswap.txids[BASILISK_BOBREFUND],&rswap.depositspent,&rswap.sentflags[BASILISK_BOBREFUND]); + } + else if ( 0 && flag == 0 ) + printf("bobrefund's time %u vs expiration %u\n",(uint32_t)time(NULL),rswap.expiration); + } + } + } + //printf("finish.%d iambob.%d REFUND %d %d %d %d\n",finishedflag,iambob,sentflags[BASILISK_BOBREFUND] == 0,sentflags[BASILISK_BOBDEPOSIT] != 0,bits256_nonz(txids[BASILISK_BOBDEPOSIT]) != 0,bits256_nonz(depositspent) == 0); + if ( rswap.sentflags[BASILISK_ALICESPEND] != 0 || rswap.sentflags[BASILISK_BOBRECLAIM] != 0 ) + rswap.sentflags[BASILISK_BOBPAYMENT] = 1; + if ( rswap.sentflags[BASILISK_ALICERECLAIM] != 0 || rswap.sentflags[BASILISK_BOBSPEND] != 0 ) + rswap.sentflags[BASILISK_ALICEPAYMENT] = 1; + if ( rswap.sentflags[BASILISK_ALICECLAIM] != 0 || rswap.sentflags[BASILISK_BOBREFUND] != 0 ) + rswap.sentflags[BASILISK_BOBDEPOSIT] = 1; + for (i=0; itxfee,"satinder",coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,priv1,0,redeemscript,redeemlen,userdata,len,utxotxid,0,0,pubkey33,0,expiration,&satoshis,0,0,paymentaddr,1,coin->zcash)) != 0 ) + { + char str[65]; printf("satinder %s signedtx.(%s)\n",bits256_str(str,signedtxid),signedtx); + } else printf("error with satinder tx\n"); +} + +char *basilisk_swaplist(uint32_t origrequestid,uint32_t origquoteid,int32_t forceflag,int32_t pendingonly) +{ + uint64_t ridqids[4096],ridqid; char fname[512]; FILE *fp; cJSON *item,*retjson,*array,*totalsobj; uint32_t r,q,quoteid,requestid; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS],Btotal,Ktotal; int32_t i,j,count=0; + portable_mutex_lock(&LP_swaplistmutex); + memset(ridqids,0,sizeof(ridqids)); + memset(KMDtotals,0,sizeof(KMDtotals)); + memset(BTCtotals,0,sizeof(BTCtotals)); + //,statebits; int32_t optionduration; struct basilisk_request R; bits256 privkey; + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + if ( origrequestid != 0 && origquoteid != 0 ) + { + //printf("orig req.%u q.%u\n",origrequestid,origquoteid); + if ( (item= basilisk_remember(KMDtotals,BTCtotals,origrequestid,origquoteid,forceflag,0)) != 0 ) + jaddi(array,item); + //printf("got.(%s)\n",jprint(item,0)); + } + else + { + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + //struct basilisk_swap *swap; + int32_t flag = 0; + while ( fread(&requestid,1,sizeof(requestid),fp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),fp) == sizeof(quoteid) ) + { + flag = 0; + if ( pendingonly == 0 ) + { + for (i=0; i> 32); + q = (uint32_t)G.LP_skipstatus[i]; + if ( r == requestid && q == quoteid ) + { + item = cJSON_CreateObject(); + jaddstr(item,"status","realtime"); + jaddnum(item,"requestid",r); + jaddnum(item,"quoteid",q); + jaddi(array,item); + flag = 1; + break; + } + } + } + if ( flag == 0 ) + { + ridqid = ((uint64_t)requestid << 32) | quoteid; + for (j=0; j 0 ) + { + totalsobj = cJSON_CreateObject(); + for (Btotal=i=0; i 0 && Btotal < 0 ) + jaddnum(retjson,"avebuy",(double)-Btotal/Ktotal); + else if ( Ktotal < 0 && Btotal > 0 ) + jaddnum(retjson,"avesell",(double)-Btotal/Ktotal); + } + portable_mutex_unlock(&LP_swaplistmutex); + return(jprint(retjson,1)); +} + +char *basilisk_swapentry(uint32_t requestid,uint32_t quoteid,int32_t forceflag) +{ + cJSON *item; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; + memset(KMDtotals,0,sizeof(KMDtotals)); + memset(BTCtotals,0,sizeof(BTCtotals)); + if ( (item= basilisk_remember(KMDtotals,BTCtotals,requestid,quoteid,forceflag,0)) != 0 ) + return(jprint(item,1)); + else return(clonestr("{\"error\":\"cant find requestid-quoteid\"}")); +} + +extern struct LP_quoteinfo LP_Alicequery; +extern uint32_t Alice_expiration; + +char *LP_recent_swaps(int32_t limit) +{ + char fname[512],*retstr,*base,*rel,*statusstr; long fsize,offset; FILE *fp; int32_t baseind,relind,i=0; uint32_t requestid,quoteid; cJSON *array,*item,*retjson,*subitem,*swapjson; int64_t KMDtotals[LP_MAXPRICEINFOS],BTCtotals[LP_MAXPRICEINFOS]; double srcamount,destamount,netamounts[LP_MAXPRICEINFOS]; + memset(KMDtotals,0,sizeof(KMDtotals)); + memset(BTCtotals,0,sizeof(BTCtotals)); + memset(netamounts,0,sizeof(netamounts)); + if ( limit <= 0 ) + limit = 3; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + array = cJSON_CreateArray(); + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + fsize = ftell(fp); + offset = (sizeof(requestid) + sizeof(quoteid)); + while ( offset <= fsize && i < limit ) + { + i++; + offset = i * (sizeof(requestid) + sizeof(quoteid)); + fseek(fp,fsize-offset,SEEK_SET); + if ( ftell(fp) == fsize-offset ) + { + if ( fread(&requestid,1,sizeof(requestid),fp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),fp) == sizeof(quoteid) ) + { + item = cJSON_CreateArray(); + jaddinum(item,requestid); + jaddinum(item,quoteid); + if ( (retstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) + { + if ( (swapjson= cJSON_Parse(retstr)) != 0 ) + { + base = jstr(swapjson,"bob"); + rel = jstr(swapjson,"alice"); + statusstr = jstr(swapjson,"status"); + baseind = relind = -1; + if ( base != 0 && rel != 0 && statusstr != 0 && strcmp(statusstr,"finished") == 0 && (baseind= LP_priceinfoind(base)) >= 0 && (relind= LP_priceinfoind(rel)) >= 0 ) + { + srcamount = jdouble(swapjson,"srcamount"); + destamount = jdouble(swapjson,"destamount"); + if ( jint(swapjson,"iambob") != 0 ) + srcamount = -srcamount; + else destamount = -destamount; + if ( srcamount != 0. && destamount != 0. ) + { + netamounts[baseind] += srcamount; + netamounts[relind] += destamount; + subitem = cJSON_CreateObject(); + jaddnum(subitem,base,srcamount); + jaddnum(subitem,rel,destamount); + jaddnum(subitem,"price",-destamount/srcamount); + jaddi(item,subitem); + } + } //else printf("base.%p rel.%p statusstr.%p baseind.%d relind.%d\n",base,rel,statusstr,baseind,relind); + free_json(swapjson); + } else printf("error parsing.(%s)\n",retstr); + free(retstr); + } + jaddi(array,item); + } else break; + } else break; + } + fclose(fp); + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jadd(retjson,"swaps",array); + array = cJSON_CreateArray(); + for (i=0; i %16llx\n",requestid,quoteid,(long long)ridqid); + } + return(ridqid); +} + +char *basilisk_swapentries(char *refbase,char *refrel,int32_t limit) +{ + uint64_t ridqids[1024],ridqid; char *liststr,*retstr2; cJSON *retjson,*array,*pending,*swapjson,*item,*retarray; int32_t i,j,n,count = 0; uint32_t requestid,quoteid; + if ( limit <= 0 ) + limit = 10; + memset(ridqids,0,sizeof(ridqids)); + retarray = cJSON_CreateArray(); + if ( (liststr= basilisk_swaplist(0,0,0,0)) != 0 ) + { + //printf("swapentry.(%s)\n",liststr); + if ( (retjson= cJSON_Parse(liststr)) != 0 ) + { + if ( (array= jarray(&n,retjson,"swaps")) != 0 ) + { + for (i=0; i 0 ) + { + if ( count < sizeof(ridqids)/sizeof(*ridqids) ) + { + ridqids[count++] = ridqid; + //printf("add ridqid.%16llx\n",(long long)ridqid); + } + jaddi(retarray,jduplicate(item)); + } + } + } + free_json(retjson); + } + free(liststr); + } + if ( (liststr= LP_recent_swaps(limit)) != 0 ) + { + if ( (retjson= cJSON_Parse(liststr)) != 0 ) + { + if ( (array= jarray(&n,retjson,"swaps")) != 0 ) + { + for (i=0; i 0 ) + { + if ( count < sizeof(ridqids)/sizeof(*ridqids) ) + ridqids[count++] = ridqid; + jaddi(retarray,swapjson); + } else free_json(swapjson); + } + free(retstr2); + } + } + } + } + if ( (pending= jobj(retjson,"pending")) != 0 ) + { + requestid = juint(pending,"requestid"); + quoteid = juint(pending,"quoteid"); + j = 0; + if ( (ridqid= ((uint64_t)requestid << 32) | quoteid) != 0 ) + { + for (j=0; j 0 ) + jaddi(retarray,pending); + else free_json(pending); + } else free_json(pending); + } + free_json(retjson); + } + free(liststr); + } + return(jprint(retarray,1)); +} + +int32_t LP_pendingswap(uint32_t requestid,uint32_t quoteid) +{ + cJSON *retjson,*array,*pending,*item; uint32_t r,q; char *retstr; int32_t i,n,retval = 0; + if ( (retstr= LP_recent_swaps(1000)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (array= jarray(&n,retjson,"swaps")) != 0 ) + { + for (i=0; iipaddr) == 0 && LP_mypeer->port == destport ) + { + //printf("no need to notify ourselves\n"); + return(clonestr("{\"result\":\"success\"}")); + } else return(0); +} + +char *LP_apicall(struct iguana_info *coin,char *method,char *params) +{ + cJSON *retjson; char *retstr; + if ( coin == 0 ) + return(0); + if ( coin->electrum != 0 ) + { + if ( (retjson= electrum_submit(coin->symbol,coin->electrum,&retjson,method,params,ELECTRUM_TIMEOUT)) != 0 ) + { + retstr = jprint(retjson,1); + //printf("got.%p (%s)\n",retjson,retstr); + return(retstr); + } return(clonestr("{\"error\":\"electrum no response\"}")); + } else return(bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,params)); +} + +cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) +{ + cJSON *retjson = 0; char *retstr; + // "getinfo", "getrawmempool", "paxprice", "gettxout", "getrawtransaction", "getblock", "listunspent", "listtransactions", "validateaddress", "importprivkey" + // bitcoind_passthru callers: "importaddress", "estimatefee", "getblockhash", "sendrawtransaction", "signrawtransaction" + if ( coin != 0 ) + { + //printf("issue.(%s, %s, %s, %s, %s)\n",coin->symbol,coin->serverport,coin->userpass,method,params); + if ( coin->electrum != 0 && (strcmp(method,"getblock") == 0 || strcmp(method,"paxprice") == 0 || strcmp(method,"getrawmempool") == 0) ) + return(cJSON_Parse("{\"error\":\"illegal electrum call\"}")); + if ( coin->inactive == 0 || strcmp(method,"importprivkey") == 0 || strcmp(method,"validateaddress") == 0 || strcmp(method,"getrawtransaction") == 0 || strcmp(method,"getblock") == 0 || strcmp(method,"getinfo") == 0 ) + { + if ( coin->electrum == 0 ) + { + retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,params); + if ( 0 && strcmp("KMD",coin->symbol) == 0 ) + printf("%s.(%s %s): %s.%s -> (%s)\n",coin->symbol,coin->serverport,coin->userpass,method,params,retstr); + if ( retstr != 0 && retstr[0] != 0 ) + { + retjson = cJSON_Parse(retstr); + free(retstr); + } + } + else + { + if ( (retjson= electrum_submit(coin->symbol,coin->electrum,&retjson,method,params,ELECTRUM_TIMEOUT)) != 0 ) + { + if ( jobj(retjson,"error") != 0 ) + { + free_json(retjson); + retjson = 0; + } + } + } + } else retjson = cJSON_Parse("{\"result\":\"disabled\"}"); + } else printf("bitcoin_json cant talk to NULL coin\n"); + return(retjson); +} + +void LP_unspents_mark(char *symbol,cJSON *vins) +{ + //printf("LOCK (%s)\n",jprint(vins,0)); +} + +int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin) +{ + cJSON *retjson; char *retstr,*method = "getinfo"; int32_t height; + *notarizedp = 0; + if ( coin == 0 ) + return(-1); + height = coin->height; + if ( coin->electrum == 0 && time(NULL) > coin->heighttime+60 && coin->userpass[0] != 0 ) + { + if ( strcmp(coin->symbol,"BTC") == 0 ) + method = "getblockchaininfo"; + retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,method,"[]"); + if ( retstr != 0 && retstr[0] != 0 ) + { + retjson = cJSON_Parse(retstr); + coin->height = height = jint(retjson,"blocks"); + if ( (*notarizedp= jint(retjson,"notarized")) != 0 && *notarizedp != coin->notarized ) + { + //printf("new notarized %s %d -> %d\n",coin->symbol,coin->notarized,*notarizedp); + coin->notarized = *notarizedp; + coin->notarizationtxid = jbits256(retjson,"notarizedtxid"); + coin->notarizedhash = jbits256(retjson,"notarizedhash"); + } + free_json(retjson); + if ( coin->height > 0 ) + coin->heighttime = (uint32_t)time(NULL); + free(retstr); + } + } + return(height); +} + +uint64_t LP_RTsmartbalance(struct iguana_info *coin) +{ + cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value; + valuesum = 0; + sprintf(buf,"[0, 99999999, [\"%s\"]]",coin->smartaddr); + retstr = bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,"listunspent",buf); + if ( retstr != 0 && retstr[0] != 0 ) + { + array = cJSON_Parse(retstr); + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ielectrum != 0 && coinaddr == 0) ) + return(cJSON_Parse("{\"error\":\"no native coin\"}")); + if ( coin->electrum == 0 ) + return(bitcoin_json(coin,"getrawmempool","[]")); + else return(electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr,txid,txid2)); +} + +cJSON *LP_paxprice(char *fiat) +{ + char buf[128],lfiat[65]; struct iguana_info *coin = LP_coinfind("KMD"); + strcpy(lfiat,fiat); + tolowercase(lfiat); + sprintf(buf,"[\"%s\", \"kmd\"]",lfiat); + return(bitcoin_json(coin,"paxprice",buf)); +} + +cJSON *LP_gettx(char *symbol,bits256 txid,int32_t suppress_errors) +{ + struct iguana_info *coin; char buf[512],str[65]; int32_t height; cJSON *retjson; + //printf("LP_gettx %s %s\n",symbol,bits256_str(str,txid)); + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 ) + return(cJSON_Parse("{\"error\":\"no coin\"}")); + if ( bits256_nonz(txid) == 0 ) + return(cJSON_Parse("{\"error\":\"null txid\"}")); + if ( coin->electrum == 0 ) + { + sprintf(buf,"[\"%s\", 1]",bits256_str(str,txid)); + retjson = bitcoin_json(coin,"getrawtransaction",buf); + return(retjson); + } + else + { + if ( (retjson= electrum_transaction(&height,symbol,coin->electrum,&retjson,txid,0)) != 0 ) + return(retjson); + else if ( suppress_errors == 0 ) + printf("failed blockchain.transaction.get %s %s\n",coin->symbol,bits256_str(str,txid)); + return(cJSON_Parse("{\"error\":\"no transaction bytes\"}")); + } +} + +uint32_t LP_locktime(char *symbol,bits256 txid) +{ + cJSON *txobj; uint32_t locktime = 0; + if ( (txobj= LP_gettx(symbol,txid,0)) != 0 ) + { + locktime = juint(txobj,"locktime"); + free_json(txobj); + } + return(locktime); +} + +cJSON *LP_gettxout_json(bits256 txid,int32_t vout,int32_t height,char *coinaddr,uint64_t value) +{ + cJSON *retjson,*addresses,*sobj; + retjson = cJSON_CreateObject(); + jaddnum(retjson,"value",dstr(value)); + jaddnum(retjson,"height",height); + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + addresses = cJSON_CreateArray(); + jaddistr(addresses,coinaddr); + sobj = cJSON_CreateObject(); + jaddnum(sobj,"reqSigs",1); + jaddstr(sobj,"type","pubkey"); + jadd(sobj,"addresses",addresses); + jadd(retjson,"scriptPubKey",sobj); + //printf("GETTXOUT.(%s)\n",jprint(retjson,0)); + return(retjson); +} + +cJSON *LP_gettxout(char *symbol,char *coinaddr,bits256 txid,int32_t vout) +{ + char buf[128],str[65]; cJSON *item,*array,*vouts,*txobj,*retjson=0; int32_t i,v,height,n; bits256 t,zero; struct iguana_info *coin; struct LP_transaction *tx; struct LP_address_utxo *up; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(cJSON_Parse("{\"error\":\"no coin\"}")); + if ( bits256_nonz(txid) == 0 ) + return(cJSON_Parse("{\"error\":\"null txid\"}")); + if ( coin->electrum == 0 ) + { + sprintf(buf,"[\"%s\", %d, true]",bits256_str(str,txid),vout); + return(bitcoin_json(coin,"gettxout",buf)); + } + else + { + if ( (tx= LP_transactionfind(coin,txid)) != 0 && vout < tx->numvouts ) + { + if ( tx->outpoints[vout].spendheight > 0 ) + return(0); + //return(LP_gettxout_json(txid,vout,tx->height,tx->outpoints[vout].coinaddr,tx->outpoints[vout].value)); + } + if ( coinaddr[0] == 0 ) + { + if ( (txobj= electrum_transaction(&height,symbol,coin->electrum,&txobj,txid,0)) != 0 ) + { + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 ) + LP_destaddr(coinaddr,jitem(vouts,vout)); + free_json(txobj); + } + } + if ( coinaddr[0] != 0 ) + { + if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) + { + if ( up->spendheight > 0 ) + return(0); + //return(LP_gettxout_json(txid,vout,up->U.height,coinaddr,up->U.value)); + } + memset(zero.bytes,0,sizeof(zero)); + if ( (array= electrum_address_listunspent(coin->symbol,0,&array,coinaddr,1,txid,zero)) != 0 ) + { + //printf("array.(%s)\n",jprint(array,0)); + if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ielectrum != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"address",address); + bitcoin_addr2rmd160(symbol,coin->taddr,&addrtype,rmd160,address); + bitcoin_address(symbol,checkaddr,coin->taddr,addrtype,rmd160,20); + if ( addrtype != coin->pubtype && addrtype != coin->p2shtype ) + { + jadd(retjson,"isvalid",cJSON_CreateFalse()); + return(retjson); + } + jadd(retjson,"isvalid",strcmp(address,checkaddr)==0 ? cJSON_CreateTrue() : cJSON_CreateFalse()); + if ( addrtype == coin->pubtype ) + { + strcpy(script,"76a914"); + for (i=0; i<20; i++) + sprintf(&script[i*2+6],"%02x",rmd160[i]); + script[i*2+6] = 0; + strcat(script,"88ac"); + jaddstr(retjson,"scriptPubKey",script); + } + bitcoin_address(symbol,coinaddr,coin->taddr,coin->pubtype,G.LP_myrmd160,20); + jadd(retjson,"ismine",strcmp(coinaddr,coin->smartaddr) == 0 ? cJSON_CreateTrue() : cJSON_CreateFalse()); + jadd(retjson,"iswatchonly",cJSON_CreateTrue()); + jadd(retjson,"isscript",addrtype == coin->p2shtype ? cJSON_CreateTrue() : cJSON_CreateFalse()); + return(retjson); + } + else + { + sprintf(buf,"[\"%s\"]",address); + return(bitcoin_json(coin,"validateaddress",buf)); + } +} + +int32_t LP_address_ismine(char *symbol,char *address) +{ + int32_t doneflag = 0; cJSON *retjson,*obj; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) + { + if ( (obj= jobj(retjson,"ismine")) != 0 && is_cJSON_True(obj) != 0 ) + { + doneflag = 1; + //printf("%s ismine (%s)\n",address,jprint(retjson,0)); + } + //printf("%s\n",jprint(retjson,0)); + free_json(retjson); + } + return(doneflag); +} + +int32_t LP_address_iswatchonly(char *symbol,char *address) +{ + int32_t doneflag = 0; cJSON *retjson,*obj; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) + { + if ( (obj= jobj(retjson,"iswatchonly")) != 0 && is_cJSON_True(obj) != 0 ) + { + doneflag = 1; + //printf("%s iswatchonly (%s)\n",address,jprint(retjson,0)); + } + //printf("%s\n",jprint(retjson,0)); + free_json(retjson); + } + return(doneflag); +} + +int32_t LP_address_isvalid(char *symbol,char *address) +{ + int32_t isvalid = 0; cJSON *retjson; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) + { + if ( jobj(retjson,"isvalid") != 0 && is_cJSON_True(jobj(retjson,"isvalid")) != 0 ) + { + isvalid = 1; + //printf("%s ismine (%s)\n",address,jprint(retjson,0)); + } + //printf("%s\n",jprint(retjson,0)); + free_json(retjson); + } + return(isvalid); +} + +cJSON *LP_listunspent(char *symbol,char *coinaddr,bits256 reftxid,bits256 reftxid2) +{ + char buf[128],*retstr; struct LP_address *ap; cJSON *retjson; int32_t numconfs,usecache=1; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) + return(cJSON_Parse("{\"error\":\"no coin\"}")); + if ( coin->electrum == 0 ) + { + if ( (ap= LP_addressfind(coin,coinaddr)) != 0 ) + { + if ( ap->unspenttime == 0 ) + usecache = 0; + else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+1 ) + usecache = 0; + if ( usecache != 0 && (retstr= LP_unspents_filestr(symbol,coinaddr)) != 0 ) + { + retjson = cJSON_Parse(retstr); + free(retstr); + return(retjson); + } + } + //printf("%s %s usecache.%d iswatched.%d\n",coin->symbol,coinaddr,usecache,LP_address_iswatchonly(symbol,coinaddr)); + if ( LP_address_ismine(symbol,coinaddr) > 0 || LP_address_iswatchonly(symbol,coinaddr) > 0 ) + { + if ( strcmp(symbol,"BTC") == 0 ) + numconfs = 0; + else numconfs = 1; + sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); +//printf("LP_listunspent.(%s %s)\n",symbol,coinaddr); + retjson = bitcoin_json(coin,"listunspent",buf); + retstr = jprint(retjson,0); + LP_unspents_cache(coin->symbol,coinaddr,retstr,1); + free(retstr); + if ( ap != 0 ) + ap->unspenttime = (uint32_t)time(NULL); + return(retjson); + } else return(LP_address_utxos(coin,coinaddr,0)); + } else return(electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,1,reftxid,reftxid2)); +} + +cJSON *LP_listreceivedbyaddress(char *symbol,char *coinaddr) +{ + char buf[128],*addr; bits256 zero; cJSON *retjson,*array,*item; int32_t i,n; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 || (IAMLP == 0 && coin->inactive != 0) ) + return(cJSON_Parse("{\"error\":\"no coin\"}")); + memset(zero.bytes,0,sizeof(zero)); + if ( coin->electrum == 0 ) + { + sprintf(buf,"[1, false, true]"); + if ( (array= bitcoin_json(coin,"listreceivedbyaddress",buf)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ielectrum,&retjson,coinaddr,zero)); +} + +int64_t LP_listunspent_parseitem(struct iguana_info *coin,bits256 *txidp,int32_t *voutp,int32_t *heightp,cJSON *item) +{ + int64_t satoshis = 0; + if ( coin->electrum == 0 ) + { + *txidp = jbits256(item,"txid"); + *voutp = juint(item,"vout"); + satoshis = LP_value_extract(item,0); + *heightp = LP_txheight(coin,*txidp); + } + else + { + *txidp = jbits256(item,"tx_hash"); + *voutp = juint(item,"tx_pos"); + satoshis = j64bits(item,"value"); + *heightp = jint(item,"height"); + } + return(satoshis); +} + +int32_t LP_listunspent_issue(char *symbol,char *coinaddr,int32_t fullflag,bits256 reftxid,bits256 reftxid2) +{ + struct iguana_info *coin; struct LP_address *ap; int32_t n = 0; cJSON *retjson=0; char *retstr=0; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( coin->electrum != 0 ) + { + if ( (retjson= electrum_address_listunspent(symbol,coin->electrum,&retjson,coinaddr,fullflag,reftxid,reftxid2)) != 0 ) + { + n = cJSON_GetArraySize(retjson); + //printf("LP_listunspent_issue.%s %s.%d %s\n",symbol,coinaddr,n,jprint(retjson,0)); + } + } + else + { + if ( fullflag == 2 && (ap= LP_addressfind(coin,coinaddr)) != 0 ) + ap->unspenttime = 0; + retjson = LP_listunspent(symbol,coinaddr,reftxid,reftxid2); + coin->numutxos = cJSON_GetArraySize(retjson); + if ( retjson != 0 ) + { + n = cJSON_GetArraySize(retjson); + if ( electrum_process_array(coin,0,coinaddr,retjson,1,reftxid,reftxid2) != 0 ) + { + //LP_postutxos(symbol,coinaddr); // might be good to not saturate + } + } + } + //printf("issue listunspent %s (%s)\n",coinaddr,jprint(retjson,0)); + if ( retjson != 0 ) + free_json(retjson); + if ( retstr != 0 ) + free(retstr); + } + return(n); +} + +int32_t LP_importaddress(char *symbol,char *address) +{ + char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(-2); + coin = LP_coinfind(symbol); + if ( coin == 0 ) + return(-2); + if ( coin->electrum != 0 ) + { + /*if ( (retjson= electrum_address_subscribe(symbol,coin->electrum,&retjson,address)) != 0 ) + { + printf("importaddress.(%s) -> %s\n",address,jprint(retjson,0)); + free_json(retjson); + }*/ + return(0); + } + else + { + if ( (validatejson= LP_validateaddress(symbol,address)) != 0 ) + { + if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 ) + { + if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 ) + doneflag = 1; + } + free_json(validatejson); + } + if ( isvalid == 0 ) + return(-1); + if ( doneflag != 0 ) + return(0); // success + sprintf(buf,"[\"%s\", \"%s\", false]",address,address); + if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"importaddress",buf)) != 0 ) + { + //printf("importaddress.(%s %s) -> (%s)\n",symbol,address,retstr); + free(retstr); + } //else printf("importaddress.(%s %s)\n",symbol,address); + return(1); + } +} + +cJSON *LP_importprivkey(char *symbol,char *wifstr,char *label,int32_t flag) +{ + static void *ctx; + char buf[512],address[64]; cJSON *retjson; struct iguana_info *coin; int32_t doneflag = 0; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 ) + return(cJSON_Parse("{\"error\":\"no coin\"}")); + if ( coin->electrum != 0 ) + return(cJSON_Parse("{\"result\":\"electrum should have local wallet\"}")); + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + bitcoin_wif2addr(ctx,symbol,coin->wiftaddr,coin->taddr,coin->pubtype,address,wifstr); +#ifdef LP_DONT_IMPORTPRIVKEY + bitcoin_wif2addr(ctx,symbol,coin->wiftaddr,coin->taddr,coin->pubtype,address,wifstr); + if ( LP_importaddress(symbol,address) < 0 ) + { + printf("%s importaddress %s from %s failed, isvalid.%d\n",symbol,address,wifstr,bitcoin_validaddress(symbol,coin->taddr,coin->pubtype,coin->p2shtype,address)); + return(cJSON_Parse("{\"error\":\"couldnt import\"}")); + } + else return(cJSON_Parse("{\"result\":\"success\"}")); +#endif + if ( (retjson= LP_validateaddress(symbol,address)) != 0 ) + { + if ( jobj(retjson,"ismine") != 0 && is_cJSON_True(jobj(retjson,"ismine")) != 0 ) + { + doneflag = 1; + //printf("%s already ismine\n",address); + } + //printf("%s\n",jprint(retjson,0)); + free_json(retjson); + } + if ( doneflag == 0 ) + { + if ( coin->noimportprivkey_flag != 0 ) + sprintf(buf,"[\"%s\"]",wifstr); + else sprintf(buf,"\"%s\", \"%s\", %s",wifstr,label,flag < 0 ? "false" : "true"); + return(bitcoin_json(coin,"importprivkey",buf)); + } else return(cJSON_Parse("{\"result\":\"success\"}")); +} + +double _LP_getestimatedrate(struct iguana_info *coin) +{ + char buf[512],*retstr=0; int32_t numblocks; cJSON *errjson,*retjson; double rate = 0.00000020; + if ( coin->rate < 0. || time(NULL) > coin->ratetime+30 ) + { + numblocks = strcmp(coin->symbol,"BTC") == 0 ? 6 : 2; + if ( coin->electrum == 0 ) + { + sprintf(buf,"[%d]",numblocks); + retstr = LP_apicall(coin,"estimatefee",buf); + } + else + { + if ( (retjson= electrum_estimatefee(coin->symbol,coin->electrum,&retjson,numblocks)) != 0 ) + retstr = jprint(retjson,1); + } + if ( retstr != 0 ) + { + if ( retstr[0] == '{' && (errjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(errjson,"error") != 0 ) + rate = 0.; + free_json(errjson); + } + else if ( retstr[0] != '-' ) + { + rate = atof(retstr) / 1024.; + if ( rate < 0.00000020 ) + rate = 0.00000020; + rate *= 1.5; + if ( coin->electrum != 0 ) + rate *= 1.5; + if ( fabs(rate - coin->rate) > SMALLVAL ) + printf("t%u estimated rate.(%s) (%s) -> %.8f %.8f\n",coin->ratetime,coin->symbol,retstr,rate,coin->rate); + coin->rate = rate; + coin->ratetime = (uint32_t)time(NULL); + } + free(retstr); + } else rate = coin->rate; + } else rate = coin->rate; + return(rate); +} + +double LP_getestimatedrate(struct iguana_info *coin) +{ + double rate = 0.00000020; + if ( coin == 0 ) + return(rate); + if ( (rate= _LP_getestimatedrate(coin)) <= 0. ) + rate = dstr(coin->txfee) / LP_AVETXSIZE; + return(rate); +} + +char *LP_sendrawtransaction(char *symbol,char *signedtx) +{ + cJSON *array,*errobj; char *paramstr,*tmpstr,*retstr=0; int32_t n,alreadyflag = 0; cJSON *retjson; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 || signedtx == 0 || signedtx[0] == 0 ) + { + printf("LP_sendrawtransaction null symbol %p or signedtx.%p\n",symbol,signedtx); + return(0); + } + coin = LP_coinfind(symbol); + if ( coin == 0 ) + { + printf("LP_sendrawtransaction null coin\n"); + return(0); + } + if ( coin->electrum == 0 ) + { + array = cJSON_CreateArray(); + jaddistr(array,signedtx); + paramstr = jprint(array,1); + retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"sendrawtransaction",paramstr); + //printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr); + free(paramstr); + } + else + { + if ( (retjson= electrum_sendrawtransaction(symbol,coin->electrum,&retjson,signedtx)) != 0 ) + { + retstr = jprint(retjson,1); + //electrum sendrawtx (the transaction was rejected by network rules.\n\ntransaction already in block chain) + if ( strstr(retstr,"already in block") != 0 ) + alreadyflag = 1; + //printf("electrum sendrawtx.(%s) -> %s already.%d\n",signedtx,retstr,alreadyflag); + if ( alreadyflag != 0 ) + { + errobj = cJSON_CreateObject(); + jaddstr(errobj,"error","rejected"); + jaddnum(errobj,"code",-27); + free(retstr); + retstr = jprint(errobj,1); + } + else + { + n = (int32_t)strlen(retstr); + if ( retstr[0] == '"' && retstr[n-1] == '"' ) + { + retstr[n-1] = 0; + tmpstr = clonestr(retstr+1); + free(retstr); + retstr = tmpstr; + } + } + } + } + return(retstr); +} + +char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkeys,struct vin_info *V) +{ + cJSON *array,*json,*retjson; int32_t len; uint8_t *data; char str[65],*paramstr,*retstr,*hexstr,*signedtx=0; struct iguana_msgtx msgtx; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + coin = LP_coinfind(symbol); + memset(signedtxidp,0,sizeof(*signedtxidp)); + *completedp = 0; + if ( coin == 0 ) + { + printf("LP_signrawtx cant find coin.(%s)\n",symbol); + return(0); + } + //int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson) + memset(&msgtx,0,sizeof(msgtx)); + signedtx = 0; + memset(signedtxidp,0,sizeof(*signedtxidp)); + //printf("locktime.%u sequenceid.%x rawtx.(%s) vins.(%s)\n",locktime,sequenceid,rawtxbytes,jprint(vins,0)); + if ( (*completedp= iguana_signrawtransaction(coin->ctx,symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,1000000,&msgtx,&signedtx,signedtxidp,V,16,rawtx,vins,privkeys,coin->zcash)) < 0 ) + //if ( (signedtx= LP_signrawtx(symbol,signedtxidp,&completed,vins,rawtxbytes,privkeys,V)) == 0 ) + printf("couldnt sign transaction.%s %s\n",rawtx,bits256_str(str,*signedtxidp)); + else if ( *completedp == 0 ) + { + printf("incomplete signing %s (%s)\n",rawtx,jprint(vins,0)); + if ( signedtx != 0 ) + free(signedtx), signedtx = 0; + } // else printf("basilisk_swap_bobtxspend %s -> %s\n",rawtx,bits256_str(str,*signedtxidp)); + if ( signedtx == 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","couldnt sign tx"); + jaddstr(retjson,"coin",coin->symbol); + jaddstr(retjson,"rawtx",rawtx); + jadd(retjson,"vins",vins); + jadd(retjson,"privkeys",privkeys); + return(jprint(retjson,1)); + } + return(signedtx); + if ( (0) ) + { + array = cJSON_CreateArray(); + jaddistr(array,rawtx); + jaddi(array,jduplicate(vins)); + jaddi(array,jduplicate(privkeys)); + paramstr = jprint(array,1); + //printf("signrawtransaction\n"); + if ( (retstr= bitcoind_passthru(symbol,coin->serverport,coin->userpass,"signrawtransaction",paramstr)) != 0 ) + { + if ( (json= cJSON_Parse(retstr)) != 0 ) + { + if ( (hexstr= jstr(json,"hex")) != 0 ) + { + len = (int32_t)strlen(hexstr); + signedtx = calloc(1,len+1); + strcpy(signedtx,hexstr); + *completedp = is_cJSON_True(jobj(json,"complete")); + len >>= 1; + data = malloc(len); + decode_hex(data,len,hexstr); + *signedtxidp = bits256_calctxid(coin->symbol,data,len); + } + //else + printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr); + free_json(json); + } + free(retstr); + } + free(paramstr); + return(signedtx); + } +} + +cJSON *LP_getblock(char *symbol,bits256 txid) +{ + char buf[128],str[65]; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 || coin->electrum != 0 ) + return(cJSON_Parse("{\"error\":\"no native coin\"}")); + sprintf(buf,"[\"%s\"]",bits256_str(str,txid)); + return(bitcoin_json(coin,"getblock",buf)); +} + +// not in electrum path +uint64_t LP_txfee(char *symbol) +{ + uint64_t txfee = 0; + if ( symbol == 0 || symbol[0] == 0 ) + return(LP_MIN_TXFEE); + if ( strcmp(symbol,"BTC") != 0 ) + txfee = LP_MIN_TXFEE; + return(txfee); +} + +bits256 LP_getbestblockhash(struct iguana_info *coin) +{ + char *retstr; bits256 blockhash; + memset(blockhash.bytes,0,sizeof(blockhash)); + if ( coin->electrum == 0 ) + { + if ( (retstr= bitcoind_passthru(coin->symbol,coin->serverport,coin->userpass,"getbestblockhash","")) != 0 ) + { + if ( is_hexstr(retstr,0) == sizeof(blockhash)*2 ) + decode_hex(blockhash.bytes,sizeof(blockhash),retstr); + free(retstr); + } + } else printf("electrum mode doesnt support block level scanning\n"); + return(blockhash); +} + +char *LP_blockhashstr(char *symbol,int32_t height) +{ + char params[64],*retstr; struct iguana_info *coin; //cJSON *array; + if ( symbol == 0 || symbol[0] == 0 ) + return(0); + coin = LP_coinfind(symbol); + if ( coin == 0 || coin->electrum != 0 ) + return(0); + //array = cJSON_CreateArray(); + //jaddinum(array,height); + //paramstr = jprint(array,1); + sprintf(params,"[%d]",height); + retstr = bitcoind_passthru(symbol,coin->serverport,coin->userpass,"getblockhash",params); + //free(paramstr); + //printf("blockhashstr.(%s)\n",retstr); + return(retstr); +} + +cJSON *LP_getblockhashstr(char *symbol,char *blockhashstr) +{ + char buf[128]; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 || coin->electrum != 0 ) + return(cJSON_Parse("{\"error\":\"no native coin daemon\"}")); + sprintf(buf,"[\"%s\"]",blockhashstr); + return(bitcoin_json(coin,"getblock",buf)); +} + +uint32_t LP_heighttime(char *symbol,int32_t height) +{ + struct electrum_info *ep; uint32_t timestamp = 0; cJSON *retjson; char *blockhashstr; struct iguana_info *coin = LP_coinfind(symbol); + if ( coin != 0 ) + { + if ( (ep= coin->electrum) == 0 ) + { + if ( (blockhashstr= LP_blockhashstr(symbol,height)) != 0 ) + { + if ( (retjson= cJSON_Parse(blockhashstr)) != 0 ) + { + //printf("height.(%s)\n",jprint(retjson,0)); + timestamp = juint(retjson,"time"); + free_json(retjson); + } + free(blockhashstr); + } + } + else + { + if ( (retjson= electrum_getheader(coin->symbol,ep,&retjson,height)) != 0 ) + { + //printf("%s\n",jprint(retjson,0)); + timestamp = juint(retjson,"timestamp"); + free_json(retjson); + } + } + } + return(timestamp); +} + +cJSON *LP_blockjson(int32_t *heightp,char *symbol,char *blockhashstr,int32_t height) +{ + cJSON *json = 0; int32_t flag = 0; struct iguana_info *coin; + if ( symbol == 0 || symbol[0] == 0 ) + return(cJSON_Parse("{\"error\":\"null symbol\"}")); + coin = LP_coinfind(symbol); + if ( coin == 0 || coin->electrum != 0 ) + { + printf("unexpected electrum path for %s\n",symbol); + return(0); + } + if ( blockhashstr == 0 ) + blockhashstr = LP_blockhashstr(symbol,height), flag = 1; + if ( blockhashstr != 0 ) + { + if ( (json= LP_getblockhashstr(symbol,blockhashstr)) != 0 ) + { + if ( *heightp != 0 ) + { + *heightp = juint(json,"height"); + if ( height >= 0 && *heightp != height ) + { + //printf("unexpected height %d vs %d for %s (%s)\n",*heightp,height,blockhashstr,jprint(json,0)); + *heightp = -1; + free_json(json); + json = 0; + } + } + } + if ( flag != 0 && blockhashstr != 0 ) + free(blockhashstr); + } + return(json); +} + +const char *Notaries_elected[][2] = +{ + { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, + { "0_jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, + { "0_kolo_testA", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, + { "artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, + { "artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, + { "artik_NA", "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" }, + { "artik_SH", "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" }, + { "badass_EU", "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" }, + { "badass_NA", "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" }, + { "badass_SH", "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" }, + { "crackers_EU", "03bc819982d3c6feb801ec3b720425b017d9b6ee9a40746b84422cbbf929dc73c3" }, // 10 + { "crackers_NA", "03205049103113d48c7c7af811b4c8f194dafc43a50d5313e61a22900fc1805b45" }, + { "crackers_SH", "02be28310e6312d1dd44651fd96f6a44ccc269a321f907502aae81d246fabdb03e" }, + { "durerus_EU", "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" }, + { "etszombi_AR", "031c79168d15edabf17d9ec99531ea9baa20039d0cdc14d9525863b83341b210e9" }, + { "etszombi_EU", "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" }, + { "etszombi_SH", "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" }, + { "farl4web_EU", "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" }, + { "farl4web_SH", "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" }, + { "fullmoon_AR", "0254b1d64840ce9ff6bec9dd10e33beb92af5f7cee628f999cb6bc0fea833347cc" }, + { "fullmoon_NA", "031fb362323b06e165231c887836a8faadb96eda88a79ca434e28b3520b47d235b" }, // 20 + { "fullmoon_SH", "030e12b42ec33a80e12e570b6c8274ce664565b5c3da106859e96a7208b93afd0d" }, + { "grewal_NA", "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" }, + { "grewal_SH", "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" }, + { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + { "jeezy_EU", "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" }, + { "jsgalt_NA", "027b3fb6fede798cd17c30dbfb7baf9332b3f8b1c7c513f443070874c410232446" }, + { "karasugoi_NA", "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" }, // 30 + { "kashifali_EU", "033777c52a0190f261c6f66bd0e2bb299d30f012dcb8bfff384103211edb8bb207" }, + { "kolo_AR", "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" }, + { "kolo_SH", "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" }, + { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + { "movecrypto_AR", "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" }, + { "movecrypto_EU", "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" }, + { "movecrypto_NA", "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" }, + { "movecrypto_SH", "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" }, + { "muros_AR", "022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" }, + { "noashh_AR", "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" }, // 40 + { "noashh_EU", "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" }, + { "noashh_NA", "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" }, + { "nxtswe_EU", "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" }, + { "polycryptoblog_NA", "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" }, + { "pondsea_AR", "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" }, + { "pondsea_EU", "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" }, + { "pondsea_NA", "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" }, + { "pondsea_SH", "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" }, + { "popcornbag_AR", "02761f106fb34fbfc5ddcc0c0aa831ed98e462a908550b280a1f7bd32c060c6fa3" }, + { "popcornbag_NA", "03c6085c7fdfff70988fda9b197371f1caf8397f1729a844790e421ee07b3a93e8" }, // 50 + { "ptytrader_NA", "0328c61467148b207400b23875234f8a825cce65b9c4c9b664f47410b8b8e3c222" }, + { "ptytrader_SH", "0250c93c492d8d5a6b565b90c22bee07c2d8701d6118c6267e99a4efd3c7748fa4" }, + { "rnr_AR", "029bdb08f931c0e98c2c4ba4ef45c8e33a34168cb2e6bf953cef335c359d77bfcd" }, + { "rnr_EU", "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" }, + { "rnr_NA", "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" }, + { "rnr_SH", "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" }, + { "titomane_AR", "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" }, + { "titomane_EU", "02e41feded94f0cc59f55f82f3c2c005d41da024e9a805b41105207ef89aa4bfbd" }, + { "titomane_SH", "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" }, + { "vanbreuk_EU", "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" }, // 60 + { "xrobesx_NA", "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" }, + { "xxspot1_XX", "02ef445a392fcaf3ad4176a5da7f43580e8056594e003eba6559a713711a27f955" }, + { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } +}; + +int32_t LP_txhasnotarization(bits256 *notarizedhashp,struct iguana_info *coin,bits256 txid) +{ + cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[1024]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; + memset(notarizedhashp,0,sizeof(*notarizedhashp)); + if ( (txobj= LP_gettx(coin->symbol,txid,0)) != 0 ) + { + if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) + { + if ( numvins >= DPOW_MIN_ASSETCHAIN_SIGS ) + { + notarymask = numnotaries = 0; + for (i=0; isymbol,spenttxid,0)) != 0 ) + { + if ( (vouts= jarray(&numvouts,spentobj,"vout")) != 0 ) + { + if ( spentvout < numvouts ) + { + vout = jitem(vouts,spentvout); + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) == 35*2 ) + { + len >>= 1; + decode_hex(script,len,hexstr); + if ( script[0] == 33 && script[34] == 0xac ) + { + for (j=0; j 0 ) + { + if ( numnotaries >= DPOW_MIN_ASSETCHAIN_SIGS ) + hasnotarization = 1; + //printf("numnotaries.%d %s hasnotarization.%d\n",numnotaries,coin->symbol,hasnotarization); + } + } + } + if ( (vouts= jarray(&numvouts,txobj,"vout")) != 0 ) + { + vout = jitem(vouts,1); + if ( (sobj= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && (len= is_hexstr(hexstr,0)) >= 35 ) + { + len >>= 1; + decode_hex(script,len,hexstr); + iguana_rwbignum(0,&script[2],32,(uint8_t *)notarizedhashp); + } + } + free_json(txobj); + } + return(hasnotarization); +} + +int32_t LP_notarization_validate(char *symbol,int32_t notarized,bits256 notarizedhash,bits256 notarizationtxid) +{ + struct iguana_info *coin; int32_t valid = 0; cJSON *blockjson; bits256 notarizedhash2; char str[65],str2[65]; + if ( strcmp(symbol,"KMD") == 0 ) + coin = LP_coinfind("BTC"); + else coin = LP_coinfind("KMD"); + if ( coin != 0 ) + { + if (LP_txhasnotarization(¬arizedhash2,coin,notarizationtxid) == 0 ) + { + printf("missing %s notarization txid %s\n",symbol,bits256_str(str,notarizationtxid)); + return(-1); + } + else if ( bits256_cmp(notarizedhash,notarizedhash2) != 0 ) + { + printf("mismatched %s notarizedhash %s vs %s\n",symbol,bits256_str(str,notarizedhash),bits256_str(str2,notarizedhash2)); + return(-1); + } + } + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( coin->electrum == 0 ) + { + if ( (blockjson= LP_getblock(coin->symbol,notarizedhash)) != 0 ) + { + if ( jint(blockjson,"height") != notarized ) + valid = 1; + free_json(blockjson); + } + } + else + { + if ( (blockjson= electrum_getheader(symbol,coin->electrum,&blockjson,notarized+1)) != 0 ) + { + notarizedhash2 = jbits256(blockjson,"prev_block_hash"); + if ( bits256_cmp(notarizedhash,notarizedhash2) == 0 ) + valid = 1; + free_json(blockjson); + } + } + } + if ( valid == 1 ) + return(0); + else return(-1); +} + +int32_t LP_hasnotarization(struct iguana_info *coin,cJSON *blockjson) +{ + int32_t i,n,hasnotarization = 0; bits256 txid,notarizedhash; cJSON *txarray; + if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) + { + for (i=0; isymbol,blockhash)) != 0 ) + { + if ( *bestheightp < 0 ) + *bestheightp = jint(blockjson,"height"); + if ( (hasnotarization= LP_hasnotarization(coin,blockjson)) > 0 ) + { + height = jint(blockjson,"height"); + //char str[65]; printf("%s height.%d\n",bits256_str(str,blockhash),height); + } + else + { + blockhash = jbits256(blockjson,"previousblockhash"); + if ( bits256_nonz(blockhash) == 0 ) + { + //printf("null prev.(%s)\n",jprint(blockjson,0)); + free_json(blockjson); + break; + } + } + free_json(blockjson); + if ( height > 0 ) + break; + } + } else break; + } + return(height); +} diff --git a/iguana/exchanges/LP_scan.c b/iguana/exchanges/LP_scan.c new file mode 100644 index 000000000..fdb3801cd --- /dev/null +++ b/iguana/exchanges/LP_scan.c @@ -0,0 +1,531 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_scan.c +// marketmaker +// + + +int32_t LP_blockinit(struct iguana_info *coin,int32_t height) +{ + int32_t i,iter,numtx,checkht=-1; cJSON *blockobj,*txs,*txobj; bits256 txid; struct LP_transaction *tx; + if ( (blockobj= LP_blockjson(&checkht,coin->symbol,0,height)) != 0 && checkht == height ) + { + if ( (txs= jarray(&numtx,blockobj,"tx")) != 0 ) + { + //printf("LP_blockinit %s ht.%d numtx.%d\n",coin->symbol,height,numtx); + for (iter=0; iter<2; iter++) + { + txobj = 0; + for (i=0; iheight == 0 ) + tx->height = height; + else if ( tx->height != height ) + { + printf("LP_blockinit: tx->height %d != %d\n",tx->height,height); + tx->height = height; + } + if ( iter == 1 ) + txobj = LP_transactioninit(coin,txid,iter,0); + } else txobj = LP_transactioninit(coin,txid,iter,0); + if ( txobj != 0 ) + free_json(txobj), txobj = 0; + } + } + } + free_json(blockobj); + } + if ( checkht == height ) + return(0); + else return(-1); +} + +int32_t LP_scanblockchain(struct iguana_info *coin,int32_t startheight,int32_t endheight) +{ + int32_t ht,n = 0; + for (ht=startheight; ht<=endheight; ht++) + { + if ( LP_blockinit(coin,ht) < 0 ) + { + printf("error loading block.%d of (%d, %d)\n",ht,startheight,endheight); + return(ht-1); + } + n++; + if ( (n % 1000) == 0 ) + printf("%.1f%% ",100. * (double)n/(endheight-startheight+1)); + } + return(endheight); +} + +char *banned_txids[] = +{ + "78cb4e21245c26b015b888b14c4f5096e18137d2741a6de9734d62b07014dfca", //233559 + "00697be658e05561febdee1aafe368b821ca33fbb89b7027365e3d77b5dfede5", //234172 + "e909465788b32047c472d73e882d79a92b0d550f90be008f76e1edaee6d742ea", //234187 + "f56c6873748a327d0b92b8108f8ec8505a2843a541b1926022883678fb24f9dc", //234188 + "abf08be07d8f5b3a433ddcca7ef539e79a3571632efd6d0294ec0492442a0204", //234213 + "3b854b996cc982fba8c06e76cf507ae7eed52ab92663f4c0d7d10b3ed879c3b0", //234367 + "fa9e474c2cda3cb4127881a40eb3f682feaba3f3328307d518589024a6032cc4", //234635 + "ca746fa13e0113c4c0969937ea2c66de036d20274efad4ce114f6b699f1bc0f3", //234662 + "43ce88438de4973f21b1388ffe66e68fda592da38c6ef939be10bb1b86387041", //234697 + "0aeb748de82f209cd5ff7d3a06f65543904c4c17387c9d87c65fd44b14ad8f8c", //234899 + "bbd3a3d9b14730991e1066bd7c626ca270acac4127131afe25f877a5a886eb25", //235252 + "fa9943525f2e6c32cbc243294b08187e314d83a2870830180380c3c12a9fd33c", //235253 + "a01671c8775328a41304e31a6693bbd35e9acbab28ab117f729eaba9cb769461", //235265 + "2ef49d2d27946ad7c5d5e4ab5c089696762ff04e855f8ab48e83bdf0cc68726d", //235295 + "c85dcffb16d5a45bd239021ad33443414d60224760f11d535ae2063e5709efee", //235296 + // all vouts banned + "c4ea1462c207547cd6fb6a4155ca6d042b22170d29801a465db5c09fec55b19d", //246748 + "305dc96d8bc23a69d3db955e03a6a87c1832673470c32fe25473a46cc473c7d1", //247204 +}; + +int32_t komodo_bannedset(int32_t *indallvoutsp,bits256 *array,int32_t max) +{ + int32_t i; + if ( sizeof(banned_txids)/sizeof(*banned_txids) > max ) + { + printf("komodo_bannedset: buffer too small %ld vs %d\n",(long)sizeof(banned_txids)/sizeof(*banned_txids),max); + exit(-1); + } + for (i=0; i b) + */ + aval = ((struct LP_address *)a)->balance; + bval = ((struct LP_address *)b)->balance; + //printf("%.8f vs %.8f -> %d\n",dstr(aval),dstr(bval),(int32_t)(bval - aval)); + return((aval == bval) ? 0 : ((aval < bval) ? 1 : -1)); +} + +// a primitive restore can be done by loading the previous snapshot and creating a virtual tx for all the balance at height-1. this wont allow anything but new snapshots, but for many use cases that is all that is needed + +cJSON *LP_snapshot(struct iguana_info *coin,int32_t height) +{ + static bits256 bannedarray[64]; static int32_t numbanned,indallvouts,maxsnapht; static char lastcoin[65]; + struct LP_transaction *tx,*tmp; struct LP_address *ap,*atmp; int32_t isKMD,i,j,n,skipflag=0,startht,endht,ht; uint64_t banned_balance=0,balance=0,noaddr_balance=0; cJSON *retjson,*array,*item; + if ( bannedarray[0].txid == 0 ) + numbanned = komodo_bannedset(&indallvouts,bannedarray,(int32_t)(sizeof(bannedarray)/sizeof(*bannedarray))); + startht = 1; + endht = height-1; + if ( strcmp(coin->symbol,lastcoin) == 0 ) + { + if ( maxsnapht > height ) + skipflag = 1; + else startht = maxsnapht+1; + } + else + { + maxsnapht = 0; + strcpy(lastcoin,coin->symbol); + } + retjson = cJSON_CreateObject(); + if ( skipflag == 0 && startht < endht ) + { + if ( (ht= LP_scanblockchain(coin,startht,endht)) < endht ) + { + if ( ht > maxsnapht ) + { + maxsnapht = ht; + printf("maxsnapht.%d for %s\n",maxsnapht,coin->symbol); + } + sleep(10); + if ( (ht= LP_scanblockchain(coin,maxsnapht+1,endht)) < endht ) + { + if ( ht > maxsnapht ) + { + maxsnapht = ht; + printf("maxsnapht.%d for %s\n",maxsnapht,coin->symbol); + } + jaddstr(retjson,"error","blockchain scan error"); + return(retjson); + } + } + if ( ht > maxsnapht ) + { + maxsnapht = ht; + printf("maxsnapht.%d for %s\n",maxsnapht,coin->symbol); + } + } + portable_mutex_lock(&coin->txmutex); + portable_mutex_lock(&coin->addrmutex); + HASH_ITER(hh,coin->addresses,ap,atmp) + { + ap->balance = 0; + } + isKMD = (strcmp(coin->symbol,"KMD") == 0) ? 1 : 0; + HASH_ITER(hh,coin->transactions,tx,tmp) + { + if ( tx->height < height ) + { + if ( isKMD != 0 ) + { + for (j=0; jtxid) == 0 ) + break; + if ( j < numbanned ) + { + for (i=0; inumvouts; i++) + banned_balance += tx->outpoints[i].value; + //char str[256]; printf("skip banned %s bannedtotal: %.8f\n",bits256_str(str,tx->txid),dstr(banned_balance)); + continue; + } + } + for (i=0; inumvouts; i++) + { + if ( (ht=tx->outpoints[i].spendheight) > 0 && ht < height ) + continue; + if ( tx->outpoints[i].coinaddr[0] != 0 && (ap= _LP_address(coin,tx->outpoints[i].coinaddr)) != 0 ) + { + balance += tx->outpoints[i].value; + ap->balance += tx->outpoints[i].value; + //printf("(%s/%s) %.8f %.8f\n",tx->outpoints[i].coinaddr,ap->coinaddr,dstr(tx->outpoints[i].value),dstr(ap->balance)); + } else noaddr_balance += tx->outpoints[i].value; + } + } + } + HASH_SORT(coin->addresses,sort_balance); + portable_mutex_unlock(&coin->addrmutex); + portable_mutex_unlock(&coin->txmutex); + printf("%s balance %.8f at height.%d\n",coin->symbol,dstr(balance),height); + array = cJSON_CreateArray(); + n = 0; + HASH_ITER(hh,coin->addresses,ap,atmp) + { + if ( ap->balance != 0 ) + { + item = cJSON_CreateObject(); + jaddnum(item,ap->coinaddr,dstr(ap->balance)); + jaddi(array,item); + n++; + } + } + jadd(retjson,"balances",array); + jaddstr(retjson,"coin",coin->symbol); + jaddnum(retjson,"height",height); + jaddnum(retjson,"numaddresses",n); + jaddnum(retjson,"total",dstr(balance)); + jaddnum(retjson,"noaddr_total",dstr(noaddr_balance)); + return(retjson); +} + +char *LP_snapshot_balance(struct iguana_info *coin,int32_t height,cJSON *argjson) +{ + cJSON *snapjson,*retjson,*balances,*array,*addrs,*child,*item,*item2; char *coinaddr,*refaddr; int32_t i,n,j,m; uint64_t total=0,value,balance = 0; + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + if ( (snapjson= LP_snapshot(coin,height)) != 0 ) + { + total = jdouble(snapjson,"total") * SATOSHIDEN; + if ( (addrs= jarray(&m,argjson,"addresses")) != 0 ) + { + if ( (balances= jarray(&n,snapjson,"balances")) != 0 ) + { + for (i=0; ichild) != 0 ) + { + value = (uint64_t)(child->valuedouble * SATOSHIDEN); + if ( (refaddr= get_cJSON_fieldname(child)) != 0 ) + { + //printf("check %s %.8f against %d\n",refaddr,dstr(value),m); + for (j=0; jsymbol); + jaddnum(retjson,"height",height); + jaddnum(retjson,"balance",dstr(balance)); + jaddnum(retjson,"total",dstr(total)); + return(jprint(retjson,1)); +} + +char *LP_dividends(struct iguana_info *coin,int32_t height,cJSON *argjson) +{ + cJSON *array,*retjson,*item,*child,*exclude=0; int32_t i,j,emitted=0,dusted=0,n,execflag=0,flag,iter,numexcluded=0; char buf[1024],*field,*prefix="",*suffix=""; uint64_t dustsum=0,excluded=0,total=0,dividend=0,value,val,emit=0,dust=0; double ratio = 1.; + if ( (retjson= LP_snapshot(coin,height)) != 0 ) + { + //printf("SNAPSHOT.(%s)\n",retstr); + if ( (array= jarray(&n,retjson,"balances")) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) != 0 ) + { + if ( argjson != 0 ) + { + exclude = jarray(&numexcluded,argjson,"exclude"); + dust = (uint64_t)(jdouble(argjson,"dust") * SATOSHIDEN); + dividend = (uint64_t)(jdouble(argjson,"dividend") * SATOSHIDEN); + if ( jstr(argjson,"prefix") != 0 ) + prefix = jstr(argjson,"prefix"); + if ( jstr(argjson,"suffix") != 0 ) + suffix = jstr(argjson,"suffix"); + execflag = jint(argjson,"system"); + } + for (iter=0; iter<2; iter++) + { + for (i=0; ichild) != 0 ) + { + value = (uint64_t)(child->valuedouble * SATOSHIDEN); + if ( (field= get_cJSON_fieldname(child)) != 0 ) + { + for (j=0; j= dust ) + { + sprintf(buf,"%s %s %.8f %s",prefix,field,dstr(val),suffix); + if ( execflag != 0 ) + { + if ( system(buf) != 0 ) + printf("error system.(%s)\n",buf); + } + else printf("%s\n",buf); + emit += val; + emitted++; + } else dustsum += val, dusted++; + } + } + } + } + if ( iter == 0 ) + { + if ( total > 0 ) + { + if ( dividend == 0 ) + dividend = total; + ratio = (double)dividend / total; + } else break; + } + } + } + } + free_json(retjson); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"coin",coin->symbol); + jaddnum(retjson,"height",height); + jaddnum(retjson,"total",dstr(total)); + jaddnum(retjson,"emitted",emitted); + jaddnum(retjson,"excluded",dstr(excluded)); + if ( dust != 0 ) + { + jaddnum(retjson,"dust",dstr(dust)); + jaddnum(retjson,"dusted",dusted); + } + if ( dustsum != 0 ) + jaddnum(retjson,"dustsum",dstr(dustsum)); + jaddnum(retjson,"dividend",dstr(dividend)); + jaddnum(retjson,"dividends",dstr(emit)); + jaddnum(retjson,"ratio",ratio); + if ( execflag != 0 ) + jaddnum(retjson,"system",execflag); + /*if ( prefix[0] != 0 ) + jaddstr(retjson,"prefix",prefix); + if ( suffix[0] != 0 ) + jaddstr(retjson,"suffix",suffix);*/ + return(jprint(retjson,1)); + } + return(clonestr("{\"error\":\"symbol not found\"}")); +} + +int32_t LP_spendsearch(char *coinaddr,bits256 *spendtxidp,int32_t *indp,char *symbol,bits256 searchtxid,int32_t searchvout) +{ + struct LP_transaction *tx; struct iguana_info *coin; + *indp = -1; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(-1); + memset(spendtxidp,0,sizeof(*spendtxidp)); + if ( (tx= LP_transactionfind(coin,searchtxid)) != 0 ) + { + if ( searchvout < tx->numvouts && tx->outpoints[searchvout].spendvini >= 0 ) + { + *spendtxidp = tx->outpoints[searchvout].spendtxid; + *indp = tx->outpoints[searchvout].spendvini; + LP_swap_getcoinaddr(symbol,coinaddr,*spendtxidp,*indp); + return(tx->outpoints[searchvout].spendheight); + } + } + return(-1); +} + +int32_t LP_mempoolscan(char *symbol,bits256 searchtxid) +{ + int32_t i,n; cJSON *array,*txobj; bits256 txid,zero; struct iguana_info *coin; struct LP_transaction *tx; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 || coin->electrum != 0 ) + return(-1); + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_getmempool(symbol,0,searchtxid,zero)) != 0 ) + { + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; iinactive != 0 ) + { + printf("LP_waitmempool missing coin.%p or inactive\n",coin); + return(-1); + } + expiration = (uint32_t)time(NULL) + duration; + while ( LP_STOP_RECEIVED == 0 ) + { + if ( LP_gettx_presence(symbol,txid) != 0 ) + numconfirms = 0; + else + { + if ( coin->electrum == 0 ) + { + if ( LP_mempoolscan(symbol,txid) >= 0 ) + numconfirms = 0; + } + else + { + memset(zero.bytes,0,sizeof(zero)); + if ( (array= electrum_address_getmempool(symbol,coin->electrum,&array,coinaddr,txid,zero)) != 0 ) + { + //char str[65]; printf("check %s mempool.(%s)\n",bits256_str(str,txid),jprint(array,0)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; isymbol,coinaddr,1,txid,zero); + struct LP_address_utxo *up; + if ( (up= LP_address_utxofind(coin,coinaddr,txid,vout)) != 0 ) + { + char str[65]; printf("address_utxofind found confirmed %s %s %s ht.%d vs %d\n",symbol,coinaddr,bits256_str(str,txid),up->U.height,coin->height); + if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr,txid)) != 0 ) + free_json(array); + if ( coin->height >= up->U.height ) + numconfirms = (coin->height - up->U.height + 1); + } + } + } + if ( time(NULL) > expiration || numconfirms >= 0 ) + break; + sleep(10); + } + //if ( numconfirms <= 0 ) + // numconfirms = LP_numconfirms(symbol,coinaddr,txid,vout,1); // no, no recursion occurs! + return(numconfirms); +} + +int32_t LP_mempool_vinscan(bits256 *spendtxidp,int32_t *spendvinp,char *symbol,char *coinaddr,bits256 searchtxid,int32_t searchvout,bits256 searchtxid2,int32_t searchvout2) +{ + struct iguana_info *coin; int32_t selector; cJSON *array; char addr[64]; + if ( symbol == 0 || symbol[0] == 0 || bits256_nonz(searchtxid) == 0 || bits256_nonz(searchtxid2) == 0 ) + return(-1); + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(-1); + if ( time(NULL) > coin->lastmempool+LP_MEMPOOL_TIMEINCR ) + { + if ( (array= LP_getmempool(symbol,coinaddr,searchtxid,searchtxid2)) != 0 ) + { + free_json(array); + coin->lastmempool = (uint32_t)time(NULL); + } + } + if ( (selector= LP_spendsearch(addr,spendtxidp,spendvinp,symbol,searchtxid,searchvout)) >= 0 ) + return(selector); + else if ( (selector= LP_spendsearch(addr,spendtxidp,spendvinp,symbol,searchtxid2,searchvout2)) >= 0 ) + return(selector); + return(-1); +} + + diff --git a/iguana/exchanges/LP_secp.c b/iguana/exchanges/LP_secp.c new file mode 100644 index 000000000..fe8e2e937 --- /dev/null +++ b/iguana/exchanges/LP_secp.c @@ -0,0 +1,193 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_secp.c +// marketmaker +// + + +#include +#include +#include +#include +#include "../../includes/curve25519.h" +#include "../secp256k1/include/secp256k1.h" +#include "../secp256k1/include/secp256k1_ecdh.h" +#include "../secp256k1/include/secp256k1_schnorr.h" +#include "../secp256k1/include/secp256k1_rangeproof.h" +#include "../secp256k1/include/secp256k1_recovery.h" + +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; + +#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) + +#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 ) +#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx); + +void *bitcoin_ctx() +{ + void *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pedersen_context_initialize(ctx); + secp256k1_rangeproof_context_initialize(ctx); + return(ctx); +} + +bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey) +{ + size_t plen; bits256 pubkey; secp256k1_pubkey secppub; + memset(pubkey.bytes,0,sizeof(pubkey)); + SECP_ENSURE_CTX + { + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) + { + //printf("bitcoin_sign illegal privkey\n"); + return(pubkey); + } + if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) != 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED); + if ( plen == 33 ) + memcpy(pubkey.bytes,data+1,sizeof(pubkey)); + } + ENDSECP_ENSURE_CTX + } + return(pubkey); +} + +bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even) +{ + bits256 pub256; uint8_t pubkey[33]; int32_t i; + for (i=0; i<100; i++) + { + *privkeyp = rand256(0); + pub256 = bitcoin_pubkey33(ctx,pubkey,*privkeyp); + if ( pubkey[0] == odd_even+2 ) + return(pub256); + } + printf("bitcoin_pub256 couldnt generate pubkey.%d\n",odd_even+2); + memset(pub256.bytes,0,sizeof(pub256)); + return(pub256); +} + +int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag) +{ + int32_t fCompressed = 1; + secp256k1_ecdsa_signature SIG; void *funcp; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; uint8_t *entropy; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; + seed = rand256(0); + extra_entropy = rand256(0); + SECP_ENSURE_CTX + { + funcp = secp256k1_nonce_function_rfc6979; + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) + { + printf("bitcoin_sign illegal privkey\n"); + return(-1); + } + if ( strcmp(symbol,"BCH") == 0 || strcmp(symbol,"BTG") == 0 ) + { + char str[65]; printf("BCH/BTG deterministic signature %s\n",bits256_str(str,txhash2)); + funcp = 0; + entropy = 0; + } else entropy = extra_entropy.bytes; + if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 ) + { + if ( recoverflag != 0 ) + { + if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,funcp,entropy) != 0 ) + { + recid = -1; + secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG); + if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) != 0 ) + { + if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) != 0 ) + { + if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 ) + { + sig[0] = 27 + recid + (fCompressed != 0 ? 4 : 0); + retval = 64 + 1; + //size_t i,plen = 33; uint8_t pubkey[33]; + //secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&CHECKPUB,SECP256K1_EC_COMPRESSED); + //for (i=0; i<33; i++) + // printf("%02x",pubkey[i]); + //printf(" bitcoin_sign's pubkey\n"); + + } //else printf("secpub mismatch\n"); + } else printf("pubkey create error\n"); + } //else printf("recover error\n"); + } else printf("secp256k1_ecdsa_sign_recoverable error\n"); + } + else + { + if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,funcp,entropy) != 0 ) + { + if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 ) + retval = (int32_t)siglen; + } + } + } + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen) +{ + int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; + pubkey[0] = 0; + SECP_ENSURE_CTX + { + if ( plen == 0 ) + { + plen = (sig[0] <= 31) ? 65 : 33; + sig++; + } + secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig,0); + secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG); + if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) != 0 ) + { + plen = 33; + memset(pubkey,0,33); + secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED);//plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED); + if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) != 0 ) + { + retval = 0; + /*if ( pubkey[0] == 4 ) // experimentally looks like 04 is set + pubkey[0] = 2; + else if ( pubkey[0] != 2 ) + pubkey[0] = 3;*/ + } else printf("secp256k1_ecdsa_verify error\n"); + } else printf("secp256k1_ecdsa_recover error\n"); + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen) +{ + int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; + SECP_ENSURE_CTX + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 ) + { + secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen); + if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) != 0 ) + retval = 0; + } else printf("error parsing pubkey\n"); + ENDSECP_ENSURE_CTX + } + return(retval); +} diff --git a/iguana/exchanges/LP_signatures.c b/iguana/exchanges/LP_signatures.c new file mode 100644 index 000000000..9e48d5c29 --- /dev/null +++ b/iguana/exchanges/LP_signatures.c @@ -0,0 +1,690 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// +// LP_signatures.c +// marketmaker +// + +struct basilisk_request *LP_requestinit(struct basilisk_request *rp,bits256 srchash,bits256 desthash,char *src,uint64_t srcsatoshis,char *dest,uint64_t destsatoshis,uint32_t timestamp,uint32_t quotetime,int32_t DEXselector) +{ + struct basilisk_request R; + memset(rp,0,sizeof(*rp)); + rp->srchash = srchash; + rp->srcamount = srcsatoshis; + rp->timestamp = timestamp; + rp->DEXselector = DEXselector; + safecopy(rp->src,src,sizeof(rp->src)); + safecopy(rp->dest,dest,sizeof(rp->dest)); + R = *rp; + rp->requestid = basilisk_requestid(rp); + rp->quotetime = quotetime; + rp->desthash = desthash; + rp->destamount = destsatoshis; + rp->quoteid = basilisk_quoteid(rp); + //printf("r.%u %u, q.%u %u: %s %.8f -> %s %.8f\n",rp->timestamp,rp->requestid,rp->quotetime,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount)); + return(rp); +} + +cJSON *LP_quotejson(struct LP_quoteinfo *qp) +{ + double price; cJSON *retjson = cJSON_CreateObject(); + if ( jobj(retjson,"gui") == 0 ) + jaddstr(retjson,"gui",qp->gui[0] != 0 ? qp->gui : LP_gui); + jadd64bits(retjson,"aliceid",qp->aliceid); + jaddnum(retjson,"tradeid",qp->tradeid); + jaddstr(retjson,"base",qp->srccoin); + jaddstr(retjson,"rel",qp->destcoin); + if ( qp->coinaddr[0] != 0 ) + jaddstr(retjson,"address",qp->coinaddr); + if ( qp->timestamp != 0 ) + jaddnum(retjson,"timestamp",qp->timestamp); + if ( bits256_nonz(qp->txid) != 0 ) + { + jaddbits256(retjson,"txid",qp->txid); + jaddnum(retjson,"vout",qp->vout); + } + if ( bits256_nonz(qp->srchash) != 0 ) + jaddbits256(retjson,"srchash",qp->srchash); + if ( qp->txfee != 0 ) + jadd64bits(retjson,"txfee",qp->txfee); + if ( qp->quotetime != 0 ) + jaddnum(retjson,"quotetime",qp->quotetime); + if ( qp->satoshis != 0 ) + jadd64bits(retjson,"satoshis",qp->satoshis); + if ( bits256_nonz(qp->desthash) != 0 ) + jaddbits256(retjson,"desthash",qp->desthash); + if ( bits256_nonz(qp->txid2) != 0 ) + { + jaddbits256(retjson,"txid2",qp->txid2); + jaddnum(retjson,"vout2",qp->vout2); + } + if ( bits256_nonz(qp->desttxid) != 0 ) + { + if ( qp->destaddr[0] != 0 ) + jaddstr(retjson,"destaddr",qp->destaddr); + jaddbits256(retjson,"desttxid",qp->desttxid); + jaddnum(retjson,"destvout",qp->destvout); + } + if ( bits256_nonz(qp->feetxid) != 0 ) + { + jaddbits256(retjson,"feetxid",qp->feetxid); + jaddnum(retjson,"feevout",qp->feevout); + } + if ( qp->desttxfee != 0 ) + jadd64bits(retjson,"desttxfee",qp->desttxfee); + if ( qp->destsatoshis != 0 ) + { + jadd64bits(retjson,"destsatoshis",qp->destsatoshis); + if ( qp->satoshis != 0 ) + { + price = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); + jaddnum(retjson,"price",price); + } + } + if ( qp->R.requestid != 0 ) + jaddnum(retjson,"requestid",qp->R.requestid); + if ( qp->R.quoteid != 0 ) + jaddnum(retjson,"quoteid",qp->R.quoteid); + return(retjson); +} + +int32_t LP_quoteparse(struct LP_quoteinfo *qp,cJSON *argjson) +{ + uint32_t rid,qid; + memset(qp,0,sizeof(*qp)); + safecopy(qp->gui,LP_gui,sizeof(qp->gui)); + safecopy(qp->srccoin,jstr(argjson,"base"),sizeof(qp->srccoin)); + safecopy(qp->coinaddr,jstr(argjson,"address"),sizeof(qp->coinaddr)); + safecopy(qp->destcoin,jstr(argjson,"rel"),sizeof(qp->destcoin)); + safecopy(qp->destaddr,jstr(argjson,"destaddr"),sizeof(qp->destaddr)); + qp->aliceid = j64bits(argjson,"aliceid"); + qp->tradeid = juint(argjson,"tradeid"); + qp->timestamp = juint(argjson,"timestamp"); + qp->quotetime = juint(argjson,"quotetime"); + qp->txid = jbits256(argjson,"txid"); + qp->txid2 = jbits256(argjson,"txid2"); + qp->vout = jint(argjson,"vout"); + qp->vout2 = jint(argjson,"vout2"); + qp->feevout = jint(argjson,"feevout"); + qp->srchash = jbits256(argjson,"srchash"); + qp->desttxid = jbits256(argjson,"desttxid"); + qp->feetxid = jbits256(argjson,"feetxid"); + qp->destvout = jint(argjson,"destvout"); + qp->desthash = jbits256(argjson,"desthash"); + qp->satoshis = j64bits(argjson,"satoshis"); + qp->destsatoshis = j64bits(argjson,"destsatoshis"); + qp->txfee = j64bits(argjson,"txfee"); + qp->desttxfee = j64bits(argjson,"desttxfee"); + qp->R.requestid = juint(argjson,"requestid"); + qp->R.quoteid = juint(argjson,"quoteid"); + if ( qp->R.requestid == 0 ) + { + rid = basilisk_requestid(&qp->R); + if ( qp->R.requestid != 0 && qp->R.requestid != rid ) + printf("requestid.%u -> %u\n",qp->R.requestid,rid); + qp->R.requestid = rid; + } + if ( qp->R.quoteid == 0 ) + { + qid = basilisk_quoteid(&qp->R); + if ( qp->R.quoteid != 0 && qp->R.quoteid != qid ) + printf("quoteid.%u -> %u\n",qp->R.quoteid,qid); + qp->R.quoteid = qid; + } + return(0); +} + +void LP_txfees(uint64_t *txfeep,uint64_t *desttxfeep,char *base,char *rel) +{ + *txfeep = LP_txfeecalc(LP_coinfind(base),0,0); + *desttxfeep = LP_txfeecalc(LP_coinfind(rel),0,0); + //printf("LP_txfees(%.8f %.8f)\n",dstr(*txfeep),dstr(*desttxfeep)); +} + +int32_t LP_quoteinfoinit(struct LP_quoteinfo *qp,struct LP_utxoinfo *utxo,char *destcoin,double price,uint64_t satoshis,uint64_t destsatoshis) +{ + memset(qp,0,sizeof(*qp)); + if ( qp->timestamp == 0 ) + qp->timestamp = (uint32_t)time(NULL); + safecopy(qp->destcoin,destcoin,sizeof(qp->destcoin)); + LP_txfees(&qp->txfee,&qp->desttxfee,utxo->coin,qp->destcoin); + qp->satoshis = satoshis;//(destsatoshis / price) + 0.49; + qp->destsatoshis = destsatoshis; + /*if ( qp->txfee >= qp->satoshis || qp->txfee >= utxo->deposit.value || utxo->deposit.value < LP_DEPOSITSATOSHIS(qp->satoshis) ) //utxo->iambob == 0 || + { + printf("quoteinit error.(%d %d %d %d) %.8f vs %.8f\n",utxo->iambob == 0,qp->txfee >= qp->satoshis,qp->txfee >= utxo->deposit.value,utxo->deposit.value < LP_DEPOSITSATOSHIS(qp->satoshis),dstr(utxo->deposit.value),dstr(LP_DEPOSITSATOSHIS(qp->satoshis))); + return(-1); + }*/ + qp->txid = utxo->payment.txid; + qp->vout = utxo->payment.vout; + qp->txid2 = utxo->deposit.txid; + qp->vout2 = utxo->deposit.vout; + if ( qp->desttxfee >= qp->destsatoshis ) + { + printf("quoteinit desttxfee %.8f < %.8f destsatoshis\n",dstr(qp->desttxfee),dstr(qp->destsatoshis)); + return(-2); + } + safecopy(qp->srccoin,utxo->coin,sizeof(qp->srccoin)); + safecopy(qp->coinaddr,utxo->coinaddr,sizeof(qp->coinaddr)); + qp->srchash = utxo->pubkey; + return(0); +} + +int32_t LP_quotedestinfo(struct LP_quoteinfo *qp,bits256 desttxid,int32_t destvout,bits256 feetxid,int32_t feevout,bits256 desthash,char *destaddr) +{ + qp->desttxid = desttxid; + qp->destvout = destvout; + qp->desthash = desthash; + qp->feetxid = feetxid; + qp->feevout = feevout; + safecopy(qp->destaddr,destaddr,sizeof(qp->destaddr)); + return(0); +} + +char *LP_quotereceived(struct LP_quoteinfo *qp) +{ + struct LP_cacheinfo *ptr; double price; + //LP_quoteparse(&Q,argjson); + price = (double)qp->destsatoshis / (qp->satoshis - qp->txfee); + if ( (ptr= LP_cacheadd(qp->srccoin,qp->destcoin,qp->txid,qp->vout,price,qp)) != 0 ) + { + ptr->Q = *qp; + printf(">>>>>>>>>> received quote %s/%s %.8f\n",qp->srccoin,qp->destcoin,price); + return(clonestr("{\"result\":\"updated\"}")); + } else return(clonestr("{\"error\":\"nullptr\"}")); +} + +int32_t LP_bitcoinsig_add(cJSON *item,bits256 priv,uint8_t *pubsecp,bits256 sighash) +{ + static void *ctx; int32_t i,j,siglen; uint8_t pub33[33],sig[65]; char sigstr[256]; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + for (j=0; j<100; j++) + { + if ( (siglen= bitcoin_sign(ctx,"sigadd",sig,sighash,priv,1)) > 0 && siglen == 65 ) + { + memset(pub33,0,33); + if ( bitcoin_recoververify(ctx,"test",sig,sighash,pub33,0) == 0 && memcmp(pub33,pubsecp,33) == 0 ) + { + init_hexbytes_noT(sigstr,sig,siglen); + jaddstr(item,"sig",sigstr); + return(siglen); + } + if ( 0 ) + { + for (i=0; i<33; i++) + printf("%02x",pubsecp[i]); + printf(" pubsecp -> "); + for (i=0; i<33; i++) + printf("%02x",pub33[i]); + printf(" mismatched recovered pubkey.%d of %d\n",j,100); + } + } + } + return(-1); +} + +bits256 LP_price_sighash(uint32_t timestamp,uint8_t *pubsecp,bits256 pubkey,char *base,char *rel,uint64_t price64) +{ + uint8_t buf[sizeof(pubkey) + 33 + sizeof(uint64_t)*3 + sizeof(timestamp)]; uint64_t basebits,relbits; bits256 sighash; + basebits = stringbits(base); + relbits = stringbits(rel); + memcpy(buf,pubkey.bytes,sizeof(pubkey)); + memcpy(&buf[sizeof(pubkey)],pubsecp,33); + memcpy(&buf[sizeof(pubkey)+33],&price64,sizeof(price64)); + memcpy(&buf[sizeof(pubkey)+33+sizeof(price64)],&basebits,sizeof(basebits)); + memcpy(&buf[sizeof(pubkey)+33+sizeof(price64)+sizeof(basebits)],&relbits,sizeof(relbits)); + memcpy(&buf[sizeof(pubkey)+33+sizeof(price64)+sizeof(basebits)+sizeof(relbits)],×tamp,sizeof(timestamp)); + vcalc_sha256(0,sighash.bytes,buf,sizeof(buf)); + return(sighash); +} + +bits256 LP_pubkey_sighash(uint32_t timestamp,bits256 pubkey,uint8_t *rmd160,uint8_t *pubsecp) +{ + uint8_t buf[sizeof(pubkey) + 20 + 33 + sizeof(timestamp)]; bits256 sighash; + memcpy(buf,pubkey.bytes,sizeof(pubkey)); + memcpy(&buf[sizeof(pubkey)],rmd160,20); + memcpy(&buf[sizeof(pubkey)+20],pubsecp,33); + memcpy(&buf[sizeof(pubkey)+20+33],×tamp,sizeof(timestamp)); + vcalc_sha256(0,sighash.bytes,buf,sizeof(buf)); + return(sighash); +} + +bits256 LP_utxos_sighash(uint32_t timestamp,uint8_t *pubsecp,bits256 pubkey,bits256 utxoshash) +{ + uint8_t buf[sizeof(pubkey)+sizeof(utxoshash)+33+sizeof(timestamp)]; bits256 sighash; + memcpy(buf,pubkey.bytes,sizeof(pubkey)); + memcpy(&buf[sizeof(pubkey)],pubsecp,33); + memcpy(&buf[sizeof(pubkey)+33],×tamp,sizeof(timestamp)); + memcpy(&buf[sizeof(pubkey)+33+sizeof(timestamp)],utxoshash.bytes,sizeof(utxoshash)); + vcalc_sha256(0,sighash.bytes,buf,sizeof(buf)); + return(sighash); +} + +int32_t LP_utxos_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,bits256 utxoshash) +{ + static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; char str[65]; struct LP_pubkey_info *pubp; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + pubp = LP_pubkeyfind(pubkey); + if ( (pubp == 0 || pubp->numerrors < LP_MAXPUBKEY_ERRORS) && sigstr != 0 && pubsecpstr != 0 && strlen(sigstr) == 65*2 && strlen(pubsecpstr) == 33 *2 ) + { + decode_hex(sig,65,sigstr); + decode_hex(pubsecp,33,pubsecpstr); + sighash = LP_utxos_sighash(timestamp,pubsecp,pubkey,utxoshash); + retval = bitcoin_recoververify(ctx,"utxos",sig,sighash,pub33,0); + if ( memcmp(pub33,pubsecp,33) != 0 || retval != 0 ) + { + static uint32_t counter; + if ( counter++ <= LP_MAXPUBKEY_ERRORS ) + { + if ( pubp != 0 ) + pubp->numerrors++; + if ( pubp != 0 && pubp->numerrors > LP_MAXPUBKEY_ERRORS/2 ) + printf("LP_utxos_sigcheck failure.%d, probably from %s with older version\n",pubp!=0?pubp->numerrors:-1,bits256_str(str,pubkey)); + } + retval = -1; + } else retval = 0; + } + return(retval); +} + +bits256 LP_utxoshash_calc(cJSON *array) +{ + int32_t i,j,n; bits256 utxoshash,txid; cJSON *item; + memset(utxoshash.bytes,0,sizeof(utxoshash)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ismartaddr); + if ( cJSON_GetArraySize(array) == 0 ) + free_json(array); + else + { + memset(zero.bytes,0,sizeof(zero)); + jaddstr(reqjson,"method","postutxos"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"coinaddr",coinaddr); + jadd(reqjson,"utxos",array); + timestamp = (uint32_t)time(NULL); + jaddnum(reqjson,"timetamp",timestamp); + init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33); + jaddstr(reqjson,"pubsecp",pubsecpstr); + jaddbits256(reqjson,"pubkey",G.LP_mypub25519); + utxoshash = LP_utxoshash_calc(array); + //char str[65]; printf("utxoshash add %s\n",bits256_str(str,utxoshash)); + LP_utxos_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,utxoshash); + //printf("post (%s) -> %d\n",msg,LP_mypubsock); + LP_reserved_msg(0,symbol,symbol,zero,jprint(reqjson,1)); + } + } +} + +int32_t LP_price_sigcheck(uint32_t timestamp,char *sigstr,char *pubsecpstr,bits256 pubkey,char *base,char *rel,uint64_t price64) +{ + static void *ctx; int32_t retval=-1; uint8_t pub33[33],pubsecp[33],sig[65]; bits256 sighash; struct LP_pubkey_info *pubp; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + pubp = LP_pubkeyfind(pubkey); + if ( (pubp == 0 || pubp->numerrors < LP_MAXPUBKEY_ERRORS) && sigstr != 0 && pubsecpstr != 0 && strlen(sigstr) == 65*2 && strlen(pubsecpstr) == 33 *2 ) + { + decode_hex(sig,65,sigstr); + decode_hex(pubsecp,33,pubsecpstr); + sighash = LP_price_sighash(timestamp,pubsecp,pubkey,base,rel,price64); + retval = bitcoin_recoververify(ctx,"price",sig,sighash,pub33,0); + if ( memcmp(pub33,pubsecp,33) != 0 || retval != 0 ) + { + if ( pubp != 0 ) + pubp->numerrors++; + printf("LP_price_sigcheck failure\n"); + retval = -1; + } + else + { + retval = 0; + //printf("valid price sig %s/%s %.8f\n",base,rel,dstr(price64)); + } + } + return(retval); +} + +int32_t LP_price_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,uint8_t *pubsecp,bits256 pubkey,char *base,char *rel,uint64_t price64) +{ + bits256 sighash; + sighash = LP_price_sighash(timestamp,pubsecp,pubkey,base,rel,price64); + return(LP_bitcoinsig_add(item,priv,pubsecp,sighash)); +} + +char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price) +{ + struct iguana_info *basecoin,*relcoin,*kmd; struct LP_address *ap; char pubsecpstr[67]; uint32_t numutxos,timestamp; uint64_t price64,balance,minsize,maxsize; bits256 zero; cJSON *reqjson; + reqjson = cJSON_CreateObject(); + // LP_addsig + if ( (basecoin= LP_coinfind(base)) != 0 && (relcoin= LP_coinfind(rel)) != 0 )//&& basecoin->electrum == 0 )//&& relcoin->electrum == 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + jaddbits256(reqjson,"pubkey",G.LP_mypub25519); + jaddstr(reqjson,"base",base); + jaddstr(reqjson,"rel",rel); + price64 = price * SATOSHIDEN + 0.0000000049; + jaddnum(reqjson,"price",price); + jadd64bits(reqjson,"price64",price64); + jaddstr(reqjson,"method","postprice"); + timestamp = (uint32_t)time(NULL); + jaddnum(reqjson,"timestamp",timestamp); + init_hexbytes_noT(pubsecpstr,G.LP_pubsecp,33); + jaddstr(reqjson,"pubsecp",pubsecpstr); + if ( (kmd= LP_coinfind("KMD")) != 0 && (ap= LP_address(kmd,kmd->smartaddr)) != 0 && ap->instantdex_credits != 0 ) + jaddnum(reqjson,"credits",dstr(ap->instantdex_credits)); + if ( (numutxos= LP_address_minmax(&balance,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 ) + { + //printf("send %s numutxos.%d balance %.8f min %.8f max %.8f\n",base,numutxos,dstr(balance),dstr(minsize),dstr(maxsize)); + jaddstr(reqjson,"utxocoin",base); + jaddnum(reqjson,"n",numutxos); + jaddnum(reqjson,"bal",dstr(balance)); + jaddnum(reqjson,"min",dstr(minsize)); + jaddnum(reqjson,"max",dstr(maxsize)); + } + LP_price_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_pubsecp,G.LP_mypub25519,base,rel,price64); + LP_reserved_msg(0,base,rel,zero,jprint(reqjson,1)); + return(clonestr("{\"result\":\"success\"}")); + } else return(clonestr("{\"error\":\"electrum node cant post bob asks\"}")); +} + +char *LP_postprice_recv(cJSON *argjson) +{ + bits256 pubkey; double price; char *base,*rel; + //printf("PRICE POSTED.(%s)\n",jprint(argjson,0)); + if ( (base= jstr(argjson,"base")) != 0 && (rel= jstr(argjson,"rel")) != 0 && (price= jdouble(argjson,"price")) > SMALLVAL ) + { + pubkey = jbits256(argjson,"pubkey"); + if ( bits256_nonz(pubkey) != 0 ) + { + if ( LP_price_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,base,rel,j64bits(argjson,"price64")) == 0 ) + { + //printf("call pricefeed update\n"); + LP_pricefeedupdate(pubkey,base,rel,price,jstr(argjson,"utxocoin"),jint(argjson,"n"),jdouble(argjson,"bal")*SATOSHIDEN,jdouble(argjson,"min")*SATOSHIDEN,jdouble(argjson,"max")*SATOSHIDEN,jdouble(argjson,"credits")*SATOSHIDEN); + return(clonestr("{\"result\":\"success\"}")); + } + else + { + printf("sig failure\n"); + return(clonestr("{\"error\":\"sig failure\"}")); + } + } + } + return(clonestr("{\"error\":\"missing fields in posted price\"}")); +} + +int32_t _LP_pubkey_sigcheck(uint8_t *sig,int32_t siglen,uint32_t timestamp,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp) +{ + static void *ctx; uint8_t pub33[33]; bits256 sighash; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + sighash = LP_pubkey_sighash(timestamp,pub,rmd160,pubsecp); + return(bitcoin_recoververify(ctx,"pubkey",sig,sighash,pub33,0)); +} + +int32_t LP_pubkey_sigadd(cJSON *item,uint32_t timestamp,bits256 priv,bits256 pub,uint8_t *rmd160,uint8_t *pubsecp) +{ + bits256 sighash; + sighash = LP_pubkey_sighash(timestamp,pub,rmd160,pubsecp); + return(LP_bitcoinsig_add(item,priv,pubsecp,sighash)); +} + +int32_t LP_pubkey_sigcheck(struct LP_pubkey_info *pubp,cJSON *item) +{ + int32_t i,len,siglen,retval=-1; uint8_t rmd160[20],checkrmd160[20],pubsecp[33],sig[65],zeroes[20]; char *sigstr,*hexstr,*pubsecpstr; + if ( (hexstr= jstr(item,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) ) + { + decode_hex(rmd160,sizeof(rmd160),hexstr); + memset(zeroes,0,sizeof(zeroes)); + if ( memcmp(zeroes,rmd160,sizeof(rmd160)) != 0 ) + { + //if ( memcmp(rmd160,pubp->rmd160,20) != 0 ) + { + if ( (pubsecpstr= jstr(item,"pubsecp")) != 0 && is_hexstr(pubsecpstr,0) == 66 ) + { + decode_hex(pubsecp,sizeof(pubsecp),pubsecpstr); + calc_rmd160_sha256(checkrmd160,pubsecp,33); + if ( memcmp(checkrmd160,rmd160,20) == 0 ) + { + if ( (sigstr= jstr(item,"sig")) != 0 && (len= is_hexstr(sigstr,0)) == 65*2 ) + { + siglen = len >> 1; + decode_hex(sig,siglen,sigstr); + if ( _LP_pubkey_sigcheck(sig,siglen,juint(item,"timestamp"),pubp->pubkey,rmd160,pubsecp) == 0 ) + { + if ( memcmp(rmd160,pubp->rmd160,20) != 0 ) + { + //for (i=0; i<20; i++) + // printf("%02x",pubp->rmd160[i]); + memcpy(pubp->rmd160,rmd160,sizeof(pubp->rmd160)); + memcpy(pubp->pubsecp,pubsecp,sizeof(pubp->pubsecp)); + memcpy(pubp->sig,sig,sizeof(pubp->sig)); + pubp->siglen = siglen; + //char str[65]; printf(" -> rmd160.(%s) for %s (%s) sig.%s\n",hexstr,bits256_str(str,pubp->pubkey),pubsecpstr,sigstr); + } + pubp->timestamp = juint(item,"timestamp"); + retval = 0; + } else pubp->numerrors++; + } + } + else if ( 0 ) + { + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" rmd160 vs "); + for (i=0; i<20; i++) + printf("%02x",checkrmd160[i]); + printf(" for %s\n",pubsecpstr); + } + } + } + } + } + return(retval); +} + +void LP_notify_pubkeys(void *ctx,int32_t pubsock) +{ + bits256 zero; uint32_t timestamp; char LPipaddr[64],secpstr[67]; cJSON *reqjson = cJSON_CreateObject(); + memset(zero.bytes,0,sizeof(zero)); + jaddstr(reqjson,"method","notify"); + jaddstr(reqjson,"rmd160",G.LP_myrmd160str); + jaddbits256(reqjson,"pub",G.LP_mypub25519); + init_hexbytes_noT(secpstr,G.LP_pubsecp,33); + jaddstr(reqjson,"pubsecp",secpstr); + timestamp = (uint32_t)time(NULL); + jaddnum(reqjson,"timestamp",timestamp); + LP_pubkey_sigadd(reqjson,timestamp,G.LP_privkey,G.LP_mypub25519,G.LP_myrmd160,G.LP_pubsecp); + if ( IAMLP != 0 ) + { + if ( LP_rarestpeer(LPipaddr) != 0 ) + { + jaddstr(reqjson,"isLP",LPipaddr); + if ( strcmp(LPipaddr,LP_myipaddr) == 0 ) + jaddnum(reqjson,"ismine",1); + //printf("notify send isLP.%s ismine.%d\n",LPipaddr,strcmp(LPipaddr,LP_myipaddr) == 0); + } else printf("no LPipaddr\n"); + } + jaddnum(reqjson,"session",G.LP_sessionid); + LP_reserved_msg(1,"","",zero,jprint(reqjson,1)); +} + +char *LP_notify_recv(cJSON *argjson) +{ + bits256 pub; struct LP_pubkey_info *pubp; char *ipaddr; + pub = jbits256(argjson,"pub"); + if ( bits256_nonz(pub) != 0 ) + { + if ( (pubp= LP_pubkeyadd(pub)) != 0 ) + LP_pubkey_sigcheck(pubp,argjson); + if ( (ipaddr= jstr(argjson,"isLP")) != 0 ) + { + //printf("notify got isLP %s %d\n",ipaddr,jint(argjson,"ismine")); + LP_peer_recv(ipaddr,jint(argjson,"ismine"),pubp); + if ( IAMLP != 0 && G.LP_IAMLP == 0 && strcmp(ipaddr,LP_myipaddr) == 0 ) + { + if ( bits256_cmp(pub,G.LP_mypub25519) != 0 ) + { + char str[65]; printf("that's me! and it is from %s which isnt me\n",bits256_str(str,pub)); + G.LP_IAMLP = 1; + } + } + LP_addpeer(LP_mypeer,LP_mypubsock,ipaddr,RPC_port,RPC_port+10,RPC_port+20,1,juint(argjson,"session"),G.netid); + } + //char str[65]; printf("%.3f NOTIFIED pub %s rmd160 %s\n",OS_milliseconds()-millis,bits256_str(str,pub),rmd160str); + } + return(clonestr("{\"result\":\"success\",\"notify\":\"received\"}")); +} + +void LP_smartutxos_push(struct iguana_info *coin) +{ + uint64_t value; bits256 zero,txid; int32_t i,vout,height,n; cJSON *array,*item,*req; +return; + if ( coin->smartaddr[0] == 0 ) + return; + //LP_notify_pubkeys(coin->ctx,LP_mypubsock); + if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + //printf("PUSH %s %s\n",coin->symbol,coin->smartaddr); + for (i=0; isymbol); + jaddstr(req,"coinaddr",coin->smartaddr); + jaddbits256(req,"txid",txid); + jaddnum(req,"vout",vout); + jaddnum(req,"ht",height); + jadd64bits(req,"value",value); + //printf("ADDR_UNSPENTS[] <- %s\n",jprint(req,0)); + LP_reserved_msg(0,"","",zero,jprint(req,1)); + } + } + free_json(array); + } +} + +char *LP_uitem_recv(cJSON *argjson) +{ + bits256 txid; int32_t vout,height; uint64_t value; struct iguana_info *coin; char *coinaddr,*symbol; +printf("LP_uitem_recv deprecated\n"); + txid = jbits256(argjson,"txid"); + vout = jint(argjson,"vout"); + height = jint(argjson,"ht"); + value = j64bits(argjson,"value"); + coinaddr = jstr(argjson,"coinaddr"); + if ( (symbol= jstr(argjson,"coin")) != 0 && coinaddr != 0 && (coin= LP_coinfind(symbol)) != 0 ) + { + //char str[65]; printf("uitem %s %s %s/v%d %.8f ht.%d\n",symbol,coinaddr,bits256_str(str,txid),vout,dstr(value),height); + if ( strcmp(coin->smartaddr,coinaddr) != 0 ) + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_uitem_recv",coin,coinaddr,txid,vout,value,height,-1); + //else printf("ignore external uitem %s %s\n",symbol,coin->smartaddr); + } + return(clonestr("{\"result\":\"success\"}")); +} + +void LP_listunspent_query(char *symbol,char *coinaddr) +{ + bits256 zero; cJSON *reqjson = cJSON_CreateObject(); + memset(zero.bytes,0,sizeof(zero)); + jaddstr(reqjson,"method","addr_unspents"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"address",coinaddr); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); +} + +void LP_query(void *ctx,char *myipaddr,int32_t mypubsock,char *method,struct LP_quoteinfo *qp) +{ + cJSON *reqjson; bits256 zero; char *msg; struct iguana_info *coin; int32_t flag = 0; + if ( strcmp(method,"request") == 0 ) + { + if ( LP_allocated(qp->desttxid,qp->destvout) == 0 && LP_allocated(qp->feetxid,qp->feevout) == 0 ) + { + LP_unavailableset(qp->desttxid,qp->destvout,qp->timestamp+LP_AUTOTRADE_TIMEOUT*4,qp->srchash); + LP_unavailableset(qp->feetxid,qp->feevout,qp->timestamp+LP_AUTOTRADE_TIMEOUT*4,qp->srchash); + } + else + { + printf("couldnt find my txid to make request\n"); + return; + } + } + reqjson = LP_quotejson(qp); + if ( bits256_nonz(qp->desthash) != 0 ) + flag = 1; + jaddbits256(reqjson,"pubkey",qp->srchash); + jaddstr(reqjson,"method",method); + if ( jobj(reqjson,"timestamp") == 0 ) + jaddnum(reqjson,"timestamp",time(NULL)); + if ( strcmp(method,"connect") == 0 ) + { + if ( (coin= LP_coinfind("KMD")) != 0 ) + jadd(reqjson,"proof",LP_instantdex_txids(0,coin->smartaddr)); + } + msg = jprint(reqjson,1); + //printf("QUERY.(%s)\n",msg); + //if ( bits256_nonz(qp->srchash) == 0 || strcmp(method,"request") != 0 ) + { + memset(&zero,0,sizeof(zero)); + if ( bits256_nonz(qp->srchash) != 0 ) + LP_reserved_msg(1,qp->srccoin,qp->destcoin,qp->srchash,clonestr(msg)); + LP_reserved_msg(1,qp->srccoin,qp->destcoin,zero,clonestr(msg)); + free(msg); + /*portable_mutex_lock(&LP_reservedmutex); + if ( num_Reserved_msgs[1] < sizeof(Reserved_msgs[1])/sizeof(*Reserved_msgs[1])-2 ) + Reserved_msgs[1][num_Reserved_msgs[1]++] = msg; + if ( num_Reserved_msgs[0] < sizeof(Reserved_msgs[0])/sizeof(*Reserved_msgs[0])-2 ) + Reserved_msgs[0][num_Reserved_msgs[0]++] = msg2; + portable_mutex_unlock(&LP_reservedmutex);*/ + } //else LP_broadcast_message(LP_mypubsock,qp->srccoin,qp->destcoin,qp->srchash,msg); +} + diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c new file mode 100644 index 000000000..b823c3c80 --- /dev/null +++ b/iguana/exchanges/LP_socket.c @@ -0,0 +1,1164 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +/** + * - we need to include WinSock2.h header to correctly use windows structure + * as the application is still using 32bit structure from mingw so, we need to + * add the include based on checking + * @author - fadedreamz@gmail.com + * @remarks - #if (defined(_M_X64) || defined(__amd64__)) && defined(WIN32) + * is equivalent to #if defined(_M_X64) as _M_X64 is defined for MSVC only + */ +#if defined(_M_X64) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port) +{ + int32_t opt,sock,result; char ipaddr[64],checkipaddr[64]; struct timeval timeout; + struct sockaddr_in saddr; socklen_t addrlen,slen; + addrlen = sizeof(saddr); + struct hostent *hostent; + + /** + * gethostbyname() is deprecated and cause crash on x64 windows + * the solution is to implement similar functionality by using getaddrinfo() + * it is standard posix function and is correctly supported in win32/win64/linux + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + struct addrinfo *addrresult = NULL; + struct addrinfo *returnptr = NULL; + struct addrinfo hints; + struct sockaddr_in * sockaddr_ipv4; + int retVal; + int found = 0; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; +#endif + + if ( parse_ipaddr(ipaddr,hostname) != 0 ) + port = parse_ipaddr(ipaddr,hostname); + +#if defined(_M_X64) + retVal = getaddrinfo(ipaddr, NULL, &hints, &addrresult); + for (returnptr = addrresult; returnptr != NULL && found == 0; returnptr = returnptr->ai_next) { + switch (returnptr->ai_family) { + case AF_INET: + sockaddr_ipv4 = (struct sockaddr_in *) returnptr->ai_addr; + // we want to break from the loop after founding the first ipv4 address + found = 1; + break; + } + } + + // if we iterate through the loop and didn't find anything, + // that means we failed in the dns lookup + if (found == 0) { + printf("getaddrinfo(%s) returned error\n", hostname); + freeaddrinfo(addrresult); + return(-1); + } +#else + hostent = gethostbyname(ipaddr); + if ( hostent == NULL ) + { + printf("gethostbyname(%s) returned error: %d port.%d ipaddr.(%s)\n",hostname,errno,port,ipaddr); + return(-1); + } +#endif + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + //#ifdef _WIN32 + // saddr.sin_addr.s_addr = (uint32_t)calc_ipbits("127.0.0.1"); + //#else + +#if defined(_M_X64) + saddr.sin_addr.s_addr = sockaddr_ipv4->sin_addr.s_addr; + // graceful cleanup + sockaddr_ipv4 = NULL; + freeaddrinfo(addrresult); +#else + memcpy(&saddr.sin_addr.s_addr,hostent->h_addr_list[0],hostent->h_length); +#endif + expand_ipbits(checkipaddr,saddr.sin_addr.s_addr); + if ( strcmp(ipaddr,checkipaddr) != 0 ) + printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)\n",bindflag,checkipaddr,ipaddr); + //#endif + if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) + { + if ( errno != ETIMEDOUT ) + printf("socket() failed: %s errno.%d", strerror(errno),errno); + return(-1); + } + opt = 1; + slen = sizeof(opt); + //printf("set keepalive.%d\n",setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,slen)); +#ifndef _WIN32 + if ( 1 )//&& bindflag != 0 ) + { + opt = 0; + getsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,&slen); + opt = 1; + //printf("keepalive.%d\n",opt); + } + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)); +#ifdef __APPLE__ + setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); +#endif +#endif + if ( bindflag == 0 ) + { + //printf("call connect sock.%d\n",sock); + result = connect(sock,(struct sockaddr *)&saddr,addrlen); + //printf("called connect result.%d\n",result); + timeout.tv_sec = 2; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + if ( result != 0 ) + { + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + } + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + } + else + { + while ( (result= bind(sock,(struct sockaddr*)&saddr,addrlen)) != 0 ) + { + if ( errno == EADDRINUSE ) + { + sleep(1); + printf("ERROR BINDING PORT.%d. this is normal tcp timeout, unless another process is using port\n",port); + fflush(stdout); + sleep(3); + printf("%s(%s) port.%d try again: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + if ( bindflag == 1 ) + { + closesocket(sock); + return(-1); + } + sleep(13); + //continue; + } + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + closesocket(sock); + return(-1); + } + } + if ( listen(sock,64) != 0 ) + { + printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + } +#ifdef __APPLE__ + //timeout.tv_sec = 0; + //timeout.tv_usec = 30000; + //setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(void *)&timeout,sizeof(timeout)); +#endif + return(sock); +} + +int32_t LP_socketsend(int32_t sock,uint8_t *serialized,int32_t len) +{ + int32_t numsent,remains,flags = 0; +#ifndef _WIN32 + flags = MSG_NOSIGNAL; +#endif + remains = len; + while ( sock >= 0 && remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,serialized,remains,flags)) < 0 ) + { + if ( errno == EAGAIN || errno == EWOULDBLOCK ) + { + sleep(1); + continue; + } + printf("(%s): numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",serialized,numsent,remains,len,errno,strerror(errno),sock); + return(-errno); + } + else if ( remains > 0 ) + { + remains -= numsent; + serialized += numsent; + if ( remains > 0 ) + printf("%d LP_socket sent.%d remains.%d of len.%d\n",sock,numsent,remains,len); + } + //printf("numsent.%d vs remains.%d len.%d sock.%d\n",numsent,remains,len,sock); + } + return(len); +} + +int32_t LP_socketrecv(int32_t sock,uint8_t *recvbuf,int32_t maxlen) +{ + int32_t recvlen = -1; + while ( sock >= 0 ) + { + if ( (recvlen= (int32_t)recv(sock,recvbuf,maxlen,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + //printf("%s recv errno.%d %s len.%d remains.%d\n",ipaddr,errno,strerror(errno),len,remains); + //printf("EAGAIN for len %d, remains.%d\n",len,remains); + sleep(1); + } else return(-errno); + } else break; + } + return(recvlen); +} + +struct electrum_info *Electrums[8192]; +int32_t Num_electrums; + +struct electrum_info *electrum_server(char *symbol,struct electrum_info *ep) +{ + struct electrum_info *rbuf[128],*recent_ep; uint32_t recent,mostrecent = 0; int32_t i,n = 0; + portable_mutex_lock(&LP_electrummutex); + if ( ep == 0 ) + { + //printf("find random electrum.%s from %d\n",symbol,Num_electrums); + memset(rbuf,0,sizeof(rbuf)); + recent_ep = 0; + recent = (uint32_t)time(NULL) - 300; + for (i=0; isymbol) == 0 && ep->sock >= 0 ) + { + if ( ep->lasttime > recent ) + { + rbuf[n++] = ep; + if ( n == sizeof(rbuf)/sizeof(*rbuf) ) + break; + } + else if ( ep->lasttime > mostrecent ) + { + mostrecent = ep->lasttime; + recent_ep = ep; + } + } + } + ep = recent_ep; + if ( n > 0 ) + { + i = (LP_rand() % n); + ep = rbuf[i]; + } + } + else if ( Num_electrums < sizeof(Electrums)/sizeof(*Electrums) ) + Electrums[Num_electrums++] = ep; + else printf("Electrum server pointer buf overflow %d\n",Num_electrums); + portable_mutex_unlock(&LP_electrummutex); + return(ep); +} + +int32_t electrum_process_array(struct iguana_info *coin,struct electrum_info *ep,char *coinaddr,cJSON *array,int32_t electrumflag,bits256 reftxid,bits256 reftxid2) +{ + int32_t i,v,n,ht,flag = 0; char str[65]; uint64_t value; bits256 txid; cJSON *item,*retjson,*txobj; struct LP_transaction *tx; + if ( array != 0 && coin != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + //printf("PROCESS %s/%s %s num.%d\n",coin->symbol,ep!=0?ep->symbol:"nanolistunspent",coinaddr,n); + for (i=0; isymbol,coinaddr,txid,v)) != 0 ) + free_json(retjson); + else + { + //printf("external unspent has no gettxout\n"); + flag += LP_address_utxoadd(0,(uint32_t)time(NULL),"electrum process",coin,coinaddr,txid,v,value,0,1); + } + } + else + { + txid = jbits256(item,"tx_hash"); + v = jint(item,"tx_pos"); + value = j64bits(item,"value"); + ht = jint(item,"height"); + } + if ( bits256_nonz(txid) == 0 ) + continue; + if ( (tx= LP_transactionfind(coin,txid)) == 0 ) + { + if ( (bits256_nonz(reftxid) == 0 || bits256_cmp(reftxid,txid) == 0) && (bits256_nonz(reftxid2) == 0 || bits256_cmp(reftxid2,txid) == 0) ) + { + txobj = LP_transactioninit(coin,txid,0,0); + LP_transactioninit(coin,txid,1,txobj); + free_json(txobj); + tx = LP_transactionfind(coin,txid); + } + } + if ( tx != 0 ) + { + if (tx->height <= 0 ) + { + tx->height = ht; + if ( ep != 0 && coin != 0 && tx->SPV == 0 ) + { + if ( 0 && strcmp(coinaddr,coin->smartaddr) == 0 ) + tx->SPV = LP_merkleproof(coin,coin->smartaddr,ep,txid,tx->height); + //printf("%s %s >>>>>>>>>> set %s <- height %d\n",coin->symbol,coinaddr,bits256_str(str,txid),tx->height); + } + } + if ( v >= 0 && v < tx->numvouts ) + { + if ( tx->outpoints[v].value == 0 && value != tx->outpoints[v].value ) + { + printf("%s %s >>>>>>>>>> set %s/v%d <- %.8f vs %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),v,dstr(value),dstr(tx->outpoints[v].value)); + tx->outpoints[v].value = value; + } + } + if ( tx->height > 0 ) + { + //printf("from electrum_process_array\n"); + flag += LP_address_utxoadd(0,(uint32_t)time(NULL),"electrum process2",coin,coinaddr,txid,v,value,tx->height,-1); + } + //printf("v.%d numvouts.%d %.8f (%s)\n",v,tx->numvouts,dstr(tx->outpoints[jint(item,"tx_pos")].value),jprint(item,0)); + } //else printf("cant find tx\n"); + } + } + return(flag); +} + +cJSON *electrum_version(char *symbol,struct electrum_info *ep,cJSON **retjsonp); +cJSON *electrum_headers_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp); + +struct stritem *electrum_sitem(struct electrum_info *ep,char *stratumreq,int32_t timeout,cJSON **retjsonp) +{ + struct stritem *sitem = (struct stritem *)queueitem(stratumreq); + sitem->expiration = timeout; + sitem->DL.type = ep->stratumid++; + sitem->retptrp = (void **)retjsonp; + queue_enqueue("sendQ",&ep->sendQ,&sitem->DL); + return(sitem); +} + +void electrum_initial_requests(struct electrum_info *ep) +{ + cJSON *retjson; char stratumreq[1024]; + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"blockchain.headers.subscribe","[]"); + electrum_sitem(ep,stratumreq,3,&retjson); + + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"server.version","[\"barterDEX\", [\"1.1\", \"1.1\"]]"); + electrum_sitem(ep,stratumreq,3,&retjson); + + retjson = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,"blockchain.estimatefee","[2]"); + electrum_sitem(ep,stratumreq,3,&retjson); +} + +int32_t electrum_kickstart(struct electrum_info *ep) +{ + closesocket(ep->sock);//, ep->sock = -1; + if ( (ep->sock= LP_socket(0,ep->ipaddr,ep->port)) < 0 ) + { + printf("error RE-connecting to %s:%u\n",ep->ipaddr,ep->port); + return(-1); + } + else + { + ep->stratumid = 0; + electrum_initial_requests(ep); + printf("RECONNECT ep.%p %s numerrors.%d too big -> new %s:%u sock.%d\n",ep,ep->symbol,ep->numerrors,ep->ipaddr,ep->port,ep->sock); + ep->numerrors = 0; + } + return(0); +} + +int32_t zeroval(); + +cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *params,int32_t timeout) +{ + // queue id and string and callback + char stratumreq[16384]; uint32_t expiration; struct stritem *sitem; + if ( ep == 0 ) + ep = electrum_server(symbol,0); + while ( ep != 0 ) + { + if ( strcmp(ep->symbol,symbol) != 0 ) + { + printf("electrum_submit ep.%p %s %s:%u called for [%s]???\n",ep,ep->symbol,ep->ipaddr,ep->port,symbol); + } + if ( ep != 0 && ep->sock >= 0 && retjsonp != 0 ) + { + *retjsonp = 0; + sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); +//printf("%s %s",symbol,stratumreq); + memset(ep->buf,0,ep->bufsize); + sitem = electrum_sitem(ep,stratumreq,timeout,retjsonp); + portable_mutex_lock(&ep->mutex); // this helps performance! + expiration = (uint32_t)time(NULL) + timeout + 1; + while ( *retjsonp == 0 && time(NULL) <= expiration ) + usleep(15000); + portable_mutex_unlock(&ep->mutex); + if ( *retjsonp == 0 || jobj(*retjsonp,"error") != 0 ) + { + if ( ++ep->numerrors >= LP_ELECTRUM_MAXERRORS ) + { + // electrum_kickstart(ep); seems to hurt more than help + } + } else if ( ep->numerrors > 0 ) + ep->numerrors--; + if ( ep->prev == 0 ) + { + if ( *retjsonp == 0 ) + { + //printf("unexpected %s timeout with null retjson: %s %s\n",ep->symbol,method,params); + *retjsonp = cJSON_Parse("{\"error\":\"timeout\"}"); + } + return(*retjsonp); + } + } //else printf("couldnt find electrum server for (%s %s) or no retjsonp.%p\n",method,params,retjsonp); + ep = ep->prev; + //if ( ep != 0 ) + // printf("using prev ep.%s\n",ep->symbol); + } + return(0); +} + +cJSON *electrum_noargs(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,int32_t timeout) +{ + cJSON *retjson; + if ( retjsonp == 0 ) + retjsonp = &retjson; + return(electrum_submit(symbol,ep,retjsonp,method,"[]",timeout)); +} + +cJSON *electrum_strarg(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,char *arg,int32_t timeout) +{ + char params[16384]; cJSON *retjson; + if ( strlen(arg) < sizeof(params) ) + { + if ( retjsonp == 0 ) + retjsonp = &retjson; + sprintf(params,"[\"%s\"]",arg); + return(electrum_submit(symbol,ep,retjsonp,method,params,timeout)); + } else return(0); +} + +cJSON *electrum_intarg(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,int32_t arg,int32_t timeout) +{ + char params[64]; cJSON *retjson; + if ( retjsonp == 0 ) + retjsonp = &retjson; + sprintf(params,"[\"%d\"]",arg); + return(electrum_submit(symbol,ep,retjsonp,method,params,timeout)); +} + +cJSON *electrum_hasharg(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *method,bits256 arg,int32_t timeout) +{ + char params[128],str[65]; cJSON *retjson; + if ( retjsonp == 0 ) + retjsonp = &retjson; + sprintf(params,"[\"%s\"]",bits256_str(str,arg)); + return(electrum_submit(symbol,ep,retjsonp,method,params,timeout)); +} + +cJSON *electrum_version(char *symbol,struct electrum_info *ep,cJSON **retjsonp) +{ + char params[128]; cJSON *retjson; + if ( retjsonp == 0 ) + retjsonp = &retjson; + sprintf(params,"[\"barterDEX\", [\"1.1\", \"1.1\"]]"); + return(electrum_submit(symbol,ep,retjsonp,"server.version",params,ELECTRUM_TIMEOUT)); +} + + +cJSON *electrum_banner(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"server.banner",ELECTRUM_TIMEOUT)); } +cJSON *electrum_donation(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"server.donation_address",ELECTRUM_TIMEOUT)); } +cJSON *electrum_peers(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"server.peers.subscribe",ELECTRUM_TIMEOUT)); } +cJSON *electrum_features(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"server.features",ELECTRUM_TIMEOUT)); } +cJSON *electrum_headers_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp) { return(electrum_noargs(symbol,ep,retjsonp,"blockchain.headers.subscribe",ELECTRUM_TIMEOUT)); } + +cJSON *electrum_script_getbalance(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *script) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.scripthash.get_balance",script,ELECTRUM_TIMEOUT)); } +cJSON *electrum_script_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *script) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.scripthash.get_history",script,ELECTRUM_TIMEOUT)); } +cJSON *electrum_script_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *script) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.scripthash.get_mempool",script,ELECTRUM_TIMEOUT)); } +cJSON *electrum_script_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *script) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.scripthash.listunspent",script,ELECTRUM_TIMEOUT)); } +cJSON *electrum_script_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *script) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.scripthash.subscribe",script,ELECTRUM_TIMEOUT)); } + +cJSON *electrum_address_subscribe(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) +{ + cJSON *retjson; + if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.subscribe",addr,ELECTRUM_TIMEOUT)) != 0 ) + { + //printf("subscribe.(%s)\n",jprint(retjson,0)); + } + return(retjson); +} + +cJSON *electrum_address_gethistory(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid) +{ + char str[65]; struct LP_transaction *tx; cJSON *retjson,*txobj,*item; int32_t i,n,height; bits256 txid; struct iguana_info *coin = LP_coinfind(symbol); + retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_history",addr,ELECTRUM_TIMEOUT); + //printf("history.(%s)\n",jprint(retjson,0)); + if ( retjson != 0 && (n= cJSON_GetArraySize(retjson)) > 0 ) + { + for (i=0; i 0 ) + { + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + { + if ( tx->height > 0 && tx->height != height ) + printf("update %s height.%d <- %d\n",bits256_str(str,txid),tx->height,height); + tx->height = height; + LP_address_utxoadd(0,(uint32_t)time(NULL),"electrum history",coin,addr,txid,0,0,height,-1); + } + } + } + } + } + return(retjson); +} + +int32_t LP_txheight_check(struct iguana_info *coin,char *coinaddr,bits256 txid) +{ + cJSON *retjson; + if ( coin->electrum != 0 ) + { + if ( (retjson= electrum_address_gethistory(coin->symbol,coin->electrum,&retjson,coinaddr,txid)) != 0 ) + free_json(retjson); + } + return(0); +} + +cJSON *electrum_address_getmempool(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,bits256 reftxid,bits256 reftxid2) +{ + cJSON *retjson; struct iguana_info *coin = LP_coinfind(symbol); + retjson = electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_mempool",addr,ELECTRUM_TIMEOUT); + //printf("MEMPOOL.(%s)\n",jprint(retjson,0)); + electrum_process_array(coin,ep,addr,retjson,1,reftxid,reftxid2); + return(retjson); +} + +cJSON *electrum_address_listunspent(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr,int32_t electrumflag,bits256 txid,bits256 txid2) +{ + cJSON *retjson=0; char *retstr; struct LP_address *ap; struct iguana_info *coin; int32_t updatedflag,height,usecache=1; + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(0); + if ( strcmp(addr,INSTANTDEX_KMD) == 0 ) + return(cJSON_Parse("[]")); + if ( ep == 0 || ep->heightp == 0 ) + height = coin->longestchain; + else height = *(ep->heightp); + if ( (ap= LP_address(coin,addr)) != 0 ) + { + if ( ap->unspenttime == 0 ) + usecache = 0; + else if ( ap->unspentheight < height ) + usecache = 0; + else if ( G.LP_pendingswaps != 0 && time(NULL) > ap->unspenttime+13 ) + usecache = 0; + } + if ( usecache == 0 || electrumflag > 1 ) + { + if ( (retjson= electrum_strarg(symbol,ep,retjsonp,"blockchain.address.listunspent",addr,ELECTRUM_TIMEOUT)) != 0 ) + { + if ( jobj(retjson,"error") == 0 && is_cJSON_Array(retjson) != 0 ) + { + if ( 0 && electrumflag > 1 ) + printf("%s.%d u.%u/%d t.%ld %s LISTUNSPENT.(%d)\n",coin->symbol,height,ap->unspenttime,ap->unspentheight,time(NULL),addr,(int32_t)strlen(jprint(retjson,0))); + updatedflag = 0; + if ( electrum_process_array(coin,ep,addr,retjson,electrumflag,txid,txid2) != 0 ) + { + //LP_postutxos(coin->symbol,addr); + updatedflag = 1; + } + retstr = jprint(retjson,0); + LP_unspents_cache(coin->symbol,addr,retstr,1); + free(retstr); + if ( ap != 0 ) + { + ap->unspenttime = (uint32_t)time(NULL); + ap->unspentheight = height; + } + } + else + { + free_json(retjson); + retjson = 0; + } + } + } + if ( retjson == 0 ) + { + if ( (retstr= LP_unspents_filestr(symbol,addr)) != 0 ) + { + retjson = cJSON_Parse(retstr); + free(retstr); + } else retjson = LP_address_utxos(coin,addr,1); + } + return(retjson); +} + +cJSON *electrum_address_getbalance(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *addr) +{ + return(electrum_strarg(symbol,ep,retjsonp,"blockchain.address.get_balance",addr,ELECTRUM_TIMEOUT)); +} + +cJSON *electrum_addpeer(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *endpoint) { return(electrum_strarg(symbol,ep,retjsonp,"server.add_peer",endpoint,ELECTRUM_TIMEOUT)); } +cJSON *electrum_sendrawtransaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,char *rawtx) { return(electrum_strarg(symbol,ep,retjsonp,"blockchain.transaction.broadcast",rawtx,ELECTRUM_TIMEOUT)); } + +cJSON *electrum_estimatefee(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t numblocks) +{ + return(electrum_intarg(symbol,ep,retjsonp,"blockchain.estimatefee",numblocks,ELECTRUM_TIMEOUT)); +} + +cJSON *electrum_getchunk(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) { return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_chunk",n,ELECTRUM_TIMEOUT)); } + +cJSON *electrum_getheader(char *symbol,struct electrum_info *ep,cJSON **retjsonp,int32_t n) +{ + return(electrum_intarg(symbol,ep,retjsonp,"blockchain.block.get_header",n,ELECTRUM_TIMEOUT)); +} + +cJSON *LP_cache_transaction(struct iguana_info *coin,bits256 txid,uint8_t *serialized,int32_t len) +{ + cJSON *txobj; struct LP_transaction *tx; + if ( (txobj= LP_transaction_fromdata(coin,txid,serialized,len)) != 0 ) + { + if ( (tx= LP_transactionfind(coin,txid)) == 0 || tx->serialized == 0 ) + { + txobj = LP_transactioninit(coin,txid,0,txobj); + LP_transactioninit(coin,txid,1,txobj); + tx = LP_transactionfind(coin,txid); + } + if ( tx != 0 ) + { + tx->serialized = serialized; + tx->len = len; + } + else + { + char str[65]; printf("unexpected couldnt find tx %s %s\n",coin->symbol,bits256_str(str,txid)); + free(serialized); + } + } + return(txobj); +} + +cJSON *_electrum_transaction(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid) +{ + char *hexstr,str[65]; int32_t len; cJSON *hexjson,*txobj=0; struct iguana_info *coin; uint8_t *serialized; struct LP_transaction *tx; + //printf("electrum_transaction %s %s\n",symbol,bits256_str(str,txid)); + if ( bits256_nonz(txid) != 0 && (coin= LP_coinfind(symbol)) != 0 ) + { + if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->serialized != 0 ) + { + //char str[65]; printf("%s cache hit -> TRANSACTION.(%s)\n",symbol,bits256_str(str,txid)); + if ( (txobj= LP_transaction_fromdata(coin,txid,tx->serialized,tx->len)) != 0 ) + { + *retjsonp = txobj; + return(txobj); + } + } + if ( bits256_cmp(txid,coin->cachedtxid) == 0 ) + { + if ( (txobj= LP_transaction_fromdata(coin,txid,coin->cachedtxiddata,coin->cachedtxidlen)) != 0 ) + { + *retjsonp = txobj; + return(txobj); + } + } + hexjson = electrum_hasharg(symbol,ep,&hexjson,"blockchain.transaction.get",txid,ELECTRUM_TIMEOUT); + hexstr = jprint(hexjson,0); + if ( strlen(hexstr) > 100000 ) + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("rawtransaction %s %s too big %d\n",coin->symbol,bits256_str(str,txid),(int32_t)strlen(hexstr)); + free(hexstr); + free_json(hexjson); + *retjsonp = cJSON_Parse("{\"error\":\"transaction too big\"}"); + return(*retjsonp); + } + if ( hexstr[0] == '"' && hexstr[strlen(hexstr)-1] == '"' ) + hexstr[strlen(hexstr)-1] = 0; + if ( (len= is_hexstr(hexstr+1,0)) > 2 ) + { + len = (int32_t)strlen(hexstr+1) >> 1; + serialized = malloc(len); + if ( coin->cachedtxiddata != 0 ) + free(coin->cachedtxiddata); + coin->cachedtxiddata = malloc(len); + coin->cachedtxidlen = len; + decode_hex(serialized,len,hexstr+1); + memcpy(coin->cachedtxiddata,serialized,len); + free(hexstr); + //printf("DATA.(%s) from (%s)\n",hexstr+1,jprint(hexjson,0)); + *retjsonp = LP_cache_transaction(coin,txid,serialized,len); // eats serialized + free_json(hexjson); + //printf("return from electrum_transaction\n"); + return(*retjsonp); + } //else printf("%s %s non-hex tx.(%s)\n",coin->symbol,bits256_str(str,txid),jprint(hexjson,0)); + free(hexstr); + free_json(hexjson); + } + *retjsonp = 0; + return(*retjsonp); +} + +cJSON *electrum_transaction(int32_t *heightp,char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,char *SPVcheck) +{ + cJSON *retjson,*array; bits256 zero; struct LP_transaction *tx=0; struct iguana_info *coin; + coin = LP_coinfind(symbol); + *heightp = 0; + if ( ep != 0 ) + portable_mutex_lock(&ep->txmutex); + retjson = _electrum_transaction(symbol,ep,retjsonp,txid); + if ( (tx= LP_transactionfind(coin,txid)) != 0 && ep != 0 && coin != 0 && SPVcheck != 0 && SPVcheck[0] != 0 ) + { + if ( tx->height <= 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + if ( (array= electrum_address_listunspent(symbol,ep,&array,SPVcheck,2,txid,zero)) != 0 ) + { + printf("SPVcheck.%s got %d unspents\n",SPVcheck,cJSON_GetArraySize(array)); + free_json(array); + } + } + if ( tx->height > 0 ) + { + if ( tx->SPV == 0 ) + tx->SPV = LP_merkleproof(coin,SPVcheck,ep,txid,tx->height); + *heightp = tx->height; + } + char str[65]; printf("%s %s %s SPV height %d SPV %d\n",coin->symbol,SPVcheck,bits256_str(str,txid),tx->height,tx->SPV); + } else if ( tx != 0 ) + *heightp = tx->height; + if ( ep != 0 ) + portable_mutex_unlock(&ep->txmutex); + return(retjson); +} + +cJSON *electrum_getmerkle(char *symbol,struct electrum_info *ep,cJSON **retjsonp,bits256 txid,int32_t height) +{ + char params[128],str[65]; + sprintf(params,"[\"%s\", %d]",bits256_str(str,txid),height); + if ( bits256_nonz(txid) == 0 ) + return(cJSON_Parse("{\"error\":\"null txid\"}")); + return(electrum_submit(symbol,ep,retjsonp,"blockchain.transaction.get_merkle",params,ELECTRUM_TIMEOUT)); +} + +void electrum_test() +{ + cJSON *retjson; int32_t height; bits256 hash,zero; struct electrum_info *ep = 0; char *addr,*script,*symbol = "BTC"; + while ( Num_electrums == 0 ) + { + sleep(1); + printf("Num_electrums %p -> %d\n",&Num_electrums,Num_electrums); + } + memset(zero.bytes,0,sizeof(zero)); + printf("found electrum server\n"); + if ( (retjson= electrum_version(symbol,ep,0)) != 0 ) + printf("electrum_version %s\n",jprint(retjson,1)); + if ( (retjson= electrum_banner(symbol,ep,0)) != 0 ) + printf("electrum_banner %s\n",jprint(retjson,1)); + if ( (retjson= electrum_donation(symbol,ep,0)) != 0 ) + printf("electrum_donation %s\n",jprint(retjson,1)); + if ( (retjson= electrum_features(symbol,ep,0)) != 0 ) + printf("electrum_features %s\n",jprint(retjson,1)); + if ( (retjson= electrum_estimatefee(symbol,ep,0,6)) != 0 ) + printf("electrum_estimatefee %s\n",jprint(retjson,1)); + decode_hex(hash.bytes,sizeof(hash),"0000000000000000005087f8845f9ed0282559017e3c6344106de15e46c07acd"); + if ( (retjson= electrum_getheader(symbol,ep,0,3)) != 0 ) + printf("electrum_getheader %s\n",jprint(retjson,1)); + //if ( (retjson= electrum_getchunk(symbol,ep,0,3)) != 0 ) + // printf("electrum_getchunk %s\n",jprint(retjson,1)); + decode_hex(hash.bytes,sizeof(hash),"b967a7d55889fe11e993430921574ec6379bc8ce712a652c3fcb66c6be6e925c"); + if ( (retjson= electrum_getmerkle(symbol,ep,0,hash,403000)) != 0 ) + printf("electrum_getmerkle %s\n",jprint(retjson,1)); + if ( (retjson= electrum_transaction(&height,symbol,ep,0,hash,0)) != 0 ) + printf("electrum_transaction %s\n",jprint(retjson,1)); + addr = "14NeevLME8UAANiTCVNgvDrynUPk1VcQKb"; + if ( (retjson= electrum_address_gethistory(symbol,ep,0,addr,zero)) != 0 ) + printf("electrum_address_gethistory %s\n",jprint(retjson,1)); + if ( (retjson= electrum_address_getmempool(symbol,ep,0,addr,zero,zero)) != 0 ) + printf("electrum_address_getmempool %s\n",jprint(retjson,1)); + if ( (retjson= electrum_address_getbalance(symbol,ep,0,addr)) != 0 ) + printf("electrum_address_getbalance %s\n",jprint(retjson,1)); + if ( (retjson= electrum_address_listunspent(symbol,ep,0,addr,1,zero,zero)) != 0 ) + printf("electrum_address_listunspent %s\n",jprint(retjson,1)); + if ( (retjson= electrum_addpeer(symbol,ep,0,"electrum.be:50001")) != 0 ) + printf("electrum_addpeer %s\n",jprint(retjson,1)); + if ( (retjson= electrum_sendrawtransaction(symbol,ep,0,"0100000001b7e6d69a0fd650926bd5fbe63cc8578d976c25dbdda8dd61db5e05b0de4041fe000000006b483045022100de3ae8f43a2a026bb46f6b09b890861f8aadcb16821f0b01126d70fa9ae134e4022000925a842073484f1056c7fc97399f2bbddb9beb9e49aca76835cdf6e9c91ef3012103cf5ce3233e6d6e22291ebef454edff2b37a714aed685ce94a7eb4f83d8e4254dffffffff014c4eaa0b000000001976a914b598062b55362952720718e7da584a46a27bedee88ac00000000")) != 0 ) + printf("electrum_sendrawtransaction %s\n",jprint(retjson,1)); + + if ( 0 ) + { + script = "76a914b598062b55362952720718e7da584a46a27bedee88ac"; + if ( (retjson= electrum_script_gethistory(symbol,ep,0,script)) != 0 ) + printf("electrum_script_gethistory %s\n",jprint(retjson,1)); + if ( (retjson= electrum_script_getmempool(symbol,ep,0,script)) != 0 ) + printf("electrum_script_getmempool %s\n",jprint(retjson,1)); + if ( (retjson= electrum_script_getbalance(symbol,ep,0,script)) != 0 ) + printf("electrum_script_getbalance %s\n",jprint(retjson,1)); + if ( (retjson= electrum_script_listunspent(symbol,ep,0,script)) != 0 ) + printf("electrum_script_listunspent %s\n",jprint(retjson,1)); + if ( (retjson= electrum_script_subscribe(symbol,ep,0,script)) != 0 ) + printf("electrum_script_subscribe %s\n",jprint(retjson,1)); + } + if ( (retjson= electrum_headers_subscribe(symbol,ep,0)) != 0 ) + printf("electrum_headers %s\n",jprint(retjson,1)); + if ( (retjson= electrum_peers(symbol,ep,0)) != 0 ) + printf("electrum_peers %s\n",jprint(retjson,1)); + if ( (retjson= electrum_address_subscribe(symbol,ep,0,addr)) != 0 ) + printf("electrum_address_subscribe %s\n",jprint(retjson,1)); +} + +struct electrum_info *LP_electrum_info(int32_t *alreadyp,char *symbol,char *ipaddr,uint16_t port,int32_t bufsize) +{ + struct electrum_info *ep=0; int32_t i,sock; struct stritem *sitem; char name[512],*str = "init string"; + *alreadyp = 0; + portable_mutex_lock(&LP_electrummutex); + for (i=0; isymbol,ep->ipaddr,ep->port,symbol,ipaddr,port); + if ( strcmp(ep->ipaddr,ipaddr) == 0 && ep->port == port && strcmp(ep->symbol,symbol) == 0 ) + { + *alreadyp = 1; + printf("%s.(%s:%u) already an electrum server\n",symbol,ipaddr,port); + break; + } + ep = 0; + } + portable_mutex_unlock(&LP_electrummutex); + if ( ep == 0 ) + { + if ( (sock= LP_socket(0,ipaddr,port)) < 0 ) + { + printf("error connecting to %s:%u\n",ipaddr,port); + return(0); + } + ep = calloc(1,sizeof(*ep) + bufsize); + portable_mutex_init(&ep->mutex); + portable_mutex_init(&ep->txmutex); + ep->sock = sock; + safecopy(ep->symbol,symbol,sizeof(ep->symbol)); + safecopy(ep->ipaddr,ipaddr,sizeof(ep->ipaddr)); + ep->port = port; + ep->bufsize = bufsize; + ep->coin = LP_coinfind(symbol); + ep->lasttime = (uint32_t)time(NULL); + sprintf(name,"%s_%s_%u_electrum_sendQ",symbol,ipaddr,port); + queue_enqueue(name,&ep->sendQ,queueitem(str)); + if ( (sitem= queue_dequeue(&ep->sendQ)) == 0 && strcmp(sitem->str,str) != 0 ) + printf("error with string sendQ sitem.%p (%s)\n",sitem,sitem==0?0:sitem->str); + sprintf(name,"%s_%s_%u_electrum_pendingQ",symbol,ipaddr,port); + queue_enqueue(name,&ep->pendingQ,queueitem(str)); + if ( (sitem= queue_dequeue(&ep->pendingQ)) == 0 && strcmp(sitem->str,str) != 0 ) + printf("error with string pendingQ sitem.%p (%s)\n",sitem,sitem==0?0:sitem->str); + electrum_server(symbol,ep); + } + return(ep); +} + +int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len) +{ + cJSON *strjson,*errjson,*resultjson,*paramsjson; char *method; int32_t i,n,height; uint32_t idnum=0; struct stritem *stritem; struct iguana_info *coin; struct queueitem *tmp,*item = 0; + if ( str == 0 || len == 0 ) + return(-1); + ep->lasttime = (uint32_t)time(NULL); + if ( (strjson= cJSON_Parse(str)) != 0 ) + { + //printf("%s RECV.(%ld) id.%d (%s)\n",ep->symbol,strlen(str),jint(strjson,"id"),jint(strjson,"id")==0?str:""); + resultjson = jobj(strjson,"result"); + //printf("strjson.(%s)\n",jprint(strjson,0)); + if ( (method= jstr(strjson,"method")) != 0 ) + { + if ( strcmp(method,"blockchain.headers.subscribe") == 0 ) + { + //printf("%p headers.(%s)\n",strjson,jprint(strjson,0)); + if ( (paramsjson= jarray(&n,strjson,"params")) != 0 ) + { + for (i=0; icoin,resultjson); + }*/ + } + if ( resultjson != 0 ) + { + if ( (height= jint(resultjson,"block_height")) > 0 && ep->heightp != 0 && ep->heighttimep != 0 ) + { + if ( height > *(ep->heightp) ) + *(ep->heightp) = height; + *(ep->heighttimep) = (uint32_t)time(NULL); + if ( (coin= LP_coinfind(ep->symbol)) != 0 ) + coin->updaterate = (uint32_t)time(NULL); + //printf("%s ELECTRUM >>>>>>>>> set height.%d\n",ep->symbol,height); + } + } + idnum = juint(strjson,"id"); + portable_mutex_lock(&ep->pendingQ.mutex); + if ( ep->pendingQ.list != 0 ) + { + DL_FOREACH_SAFE(ep->pendingQ.list,item,tmp) + { + stritem = (struct stritem *)item; + if ( item->type == idnum ) + { + DL_DELETE(ep->pendingQ.list,item); + if ( resultjson != 0 ) + *((cJSON **)stritem->retptrp) = jduplicate(resultjson); + else *((cJSON **)stritem->retptrp) = strjson, strjson = 0; + //printf("matched idnum.%d result.(%s)\n",idnum,jprint(*((cJSON **)stritem->retptrp),0)); + //resultjson = strjson = 0; + free(item); + break; + } + if ( stritem->expiration < ep->lasttime ) + { + DL_DELETE(ep->pendingQ.list,item); + if ( 0 ) + { + printf("expired %s (%s)\n",ep->symbol,stritem->str); + errjson = cJSON_CreateObject(); + jaddnum(errjson,"id",item->type); + jaddstr(errjson,"error","timeout"); + *((cJSON **)stritem->retptrp) = errjson; + } + free(item); + } + } + } + portable_mutex_unlock(&ep->pendingQ.mutex); + if ( strjson != 0 ) + free_json(strjson); + } + return(item != 0); +} + +void LP_dedicatedloop(void *arg) +{ + struct pollfd fds; int32_t i,len,n,flag,timeout = 10; struct iguana_info *coin; struct stritem *sitem; struct electrum_info *ep = arg; + if ( (coin= LP_coinfind(ep->symbol)) != 0 ) + ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; + electrum_initial_requests(ep); + printf("LP_dedicatedloop ep.%p sock.%d for %s:%u num.%d %p %s ht.%d\n",ep,ep->sock,ep->ipaddr,ep->port,Num_electrums,&Num_electrums,ep->symbol,*ep->heightp); + while ( ep->sock >= 0 ) + { + flag = 0; + memset(&fds,0,sizeof(fds)); + fds.fd = ep->sock; + fds.events |= (POLLOUT | POLLIN); + if ( poll(&fds,1,timeout) > 0 && (fds.revents & POLLOUT) != 0 && ep->pending == 0 && (sitem= queue_dequeue(&ep->sendQ)) != 0 ) + { + ep->pending = (uint32_t)time(NULL); + if ( LP_socketsend(ep->sock,(uint8_t *)sitem->str,(int32_t)strlen(sitem->str)) <= 0 ) + { + printf("%s:%u is dead\n",ep->ipaddr,ep->port); + closesocket(ep->sock); + ep->sock = -1; + break; + } + ep->keepalive = (uint32_t)time(NULL); + if ( sitem->expiration != 0 ) + sitem->expiration += (uint32_t)time(NULL); + else sitem->expiration = (uint32_t)time(NULL) + ELECTRUM_TIMEOUT; + queue_enqueue("pendingQ",&ep->pendingQ,&sitem->DL); + flag++; + } + if ( flag == 0 ) + { + if ( (fds.revents & POLLIN) != 0 ) + { + len = 0; + while ( len+65536 < ep->bufsize ) + { + if ( (n= LP_socketrecv(ep->sock,&ep->buf[len],ep->bufsize-len)) > 0 ) + { + len += n; + if ( ep->buf[len - 1] == '\n' ) + break; + memset(&fds,0,sizeof(fds)); + fds.fd = ep->sock; + fds.events = POLLIN; + if ( poll(&fds,1,1000) <= 0 ) + { + printf("no more electrum data after a second\n"); + electrum_kickstart(ep); + break; + } + } + else + { +#ifndef _WIN32 + printf("no more electrum data when expected2\n"); + electrum_kickstart(ep); +#endif + break; + } + } + if ( len > 0 ) + { + ep->pending = 0; + LP_recvfunc(ep,(char *)ep->buf,len); + flag++; + } + } + if ( flag == 0 ) + usleep(100000); + } + } + if ( coin->electrum == ep ) + { + coin->electrum = ep->prev; + printf("set %s electrum to %p\n",coin->symbol,coin->electrum); + } else printf("backup electrum server closing\n"); + printf(">>>>>>>>>> electrum close %s:%u\n",ep->ipaddr,ep->port); + if ( Num_electrums > 0 ) + { + portable_mutex_lock(&LP_electrummutex); + for (i=0; isock = -1; + //free(ep); +} + +cJSON *LP_electrumserver(struct iguana_info *coin,char *ipaddr,uint16_t port) +{ + struct electrum_info *ep,*prev; int32_t kickval,already; cJSON *retjson,*array,*item; + if ( ipaddr == 0 || ipaddr[0] == 0 || port == 0 ) + { + ep = coin->electrum; + coin->electrum = 0; + coin->inactive = (uint32_t)time(NULL); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"status","electrum mode disabled, now in disabled native coin mode"); + if ( ep != 0 ) + { + array = cJSON_CreateArray(); + while ( ep != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"ipaddr",ep->ipaddr); + jaddnum(item,"port",ep->port); + jaddnum(item,"kickstart",electrum_kickstart(ep)); + jaddi(array,item); + prev = ep->prev; + ep->prev = 0; + ep = prev; + } + jadd(retjson,"electrums",array); + } + //printf("would have disabled %s electrum here\n",coin->symbol); + return(retjson); + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"ipaddr",ipaddr); + jaddnum(retjson,"port",port); + if ( (ep= LP_electrum_info(&already,coin->symbol,ipaddr,port,IGUANA_MAXPACKETSIZE)) == 0 ) + { + jaddstr(retjson,"error","couldnt connect to electrum server"); + return(retjson); + } + if ( already == 0 ) + { + if ( ep != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_dedicatedloop,(void *)ep) != 0 ) + { + printf("error launching LP_dedicatedloop %s.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port); + jaddstr(retjson,"error","couldnt launch electrum thread"); + } + else + { + //printf("launched %s electrum.(%s:%u)\n",coin->symbol,ep->ipaddr,ep->port); + jaddstr(retjson,"result","success"); + ep->prev = coin->electrum; + coin->electrum = ep; + if ( coin->loadedcache == 0 ) + { + LP_cacheptrs_init(coin); + coin->loadedcache = (uint32_t)time(NULL); + } + if ( 0 && strcmp(coin->symbol,"ZEC") == 0 ) + { + void for_satinder(); + sleep(3); + for_satinder(); + getchar(); + } + } + } + else + { + if ( coin->electrum == 0 ) + { + coin->electrum = ep; + ep->prev = 0; + } + jaddstr(retjson,"result","success"); + jaddstr(retjson,"status","already there"); + if ( ep->numerrors > 0 ) + { + kickval = electrum_kickstart(ep); + jaddnum(retjson,"restart",kickval); + } + } + //printf("(%s)\n",jprint(retjson,0)); + return(retjson); +} + diff --git a/iguana/exchanges/LP_statemachine.c b/iguana/exchanges/LP_statemachine.c new file mode 100644 index 000000000..be24f44ed --- /dev/null +++ b/iguana/exchanges/LP_statemachine.c @@ -0,0 +1,5122 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_statemachine.c +// marketmaker +// +char DEX_baseaddr[64],DEX_reladdr[64]; +struct mmpending_order +{ + double price,volume; + int32_t dir; + uint32_t pending,completed,canceled,cancelstarted,reported; + cJSON *errorjson; + char exchange[16],base[65],rel[65],orderid[64]; +} *Pending_orders; +int32_t Num_Pending; + +#define IGUANA_URL "http://127.0.0.1:7778" + +/*char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies + "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies + };*/ +double PAXPRICES[sizeof(CURRENCIES)/sizeof(*CURRENCIES)]; +uint32_t PAXACTIVE; + + +char *DEX_swapstatus() +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"getswaplist\"}"); + return(bitcoind_RPC(0,"InstantDEX",url,0,"getswaplist",postdata,0)); +} + +char *DEX_amlp(char *blocktrail) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"amlp\",\"blocktrail\":\"%s\"}",blocktrail); + return(bitcoind_RPC(0,"tradebot",url,0,"amlp",postdata,0)); +} + +char *DEX_openorders(char *exchange) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"openorders\",\"exchange\":\"%s\"}",exchange); + return(bitcoind_RPC(0,"InstantDEX",url,0,"openorders",postdata,0)); +} + +char *DEX_tradehistory(char *exchange) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"tradehistory\",\"exchange\":\"%s\"}",exchange); + return(bitcoind_RPC(0,"InstantDEX",url,0,"tradehistory",postdata,0)); +} + +char *DEX_orderstatus(char *exchange,char *orderid) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid); + return(bitcoind_RPC(0,"InstantDEX",url,0,"orderstatus",postdata,0)); +} + +char *DEX_cancelorder(char *exchange,char *orderid) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid); + return(bitcoind_RPC(0,"InstantDEX",url,0,"cancelorder",postdata,0)); +} + +char *DEX_balance(char *exchange,char *base,char *coinaddr) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + if ( strcmp(exchange,"DEX") == 0 ) + { + sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"%s\",\"symbol\":\"%s\"}",coinaddr,base); + return(bitcoind_RPC(0,"dex",url,0,"getbalance",postdata,0)); + } + else + { + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"balance\",\"exchange\":\"%s\",\"base\":\"%s\"}",exchange,base); + return(bitcoind_RPC(0,"InstantDEX",url,0,"balance",postdata,0)); + } +} + +char *DEX_apikeypair(char *exchange,char *apikey,char *apisecret) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"apikeypair\",\"exchange\":\"%s\",\"apikey\":\"%s\",\"apisecret\":\"%s\"}",exchange,apikey,apisecret); + return(bitcoind_RPC(0,"InstantDEX",url,0,"apikeypair",postdata,0)); +} + +char *DEX_setuserid(char *exchange,char *userid,char *tradepassword) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"setuserid\",\"exchange\":\"%s\",\"userid\":\"%s\",\"tradepassword\":\"%s\"}",exchange,userid,tradepassword); + return(bitcoind_RPC(0,"InstantDEX",url,0,"setuserid",postdata,0)); +} + +char *DEX_trade(char *exchange,char *base,char *rel,int32_t dir,double price,double volume) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"exchange\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"price\":%.8f,\"volume\":%.8f,\"dotrade\":1}",dir>0?"buy":"sell",exchange,base,rel,price,volume); + //printf("DEX_trade.(%s)\n",postdata); + return(bitcoind_RPC(0,"InstantDEX",url,0,dir>0?"buy":"sell",postdata,0)); +} + +char *DEX_withdraw(char *exchange,char *base,char *destaddr,double amount) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"withdraw\",\"exchange\":\"%s\",\"destaddr\":\"%s\",\"amount\":%.8f}",exchange,destaddr,amount); + return(bitcoind_RPC(0,"InstantDEX",url,0,"withdraw",postdata,0)); +} + +char *iguana_walletpassphrase(char *passphrase,int32_t timeout) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/coin=KMD&agent=bitcoinrpc&method=walletpassphrase?",IGUANA_URL); + sprintf(postdata,"[\"%s\", %d]",passphrase,timeout); + return(bitcoind_RPC(0,"",url,0,"walletpassphrase",postdata,0)); +} + +/*char *iguana_listunspent(char *coin,char *coinaddr) + { + char url[512],postdata[1024]; + sprintf(url,"%s/coin=%s&agent=bitcoinrpc&method=listunspent?",IGUANA_URL,coin); + sprintf(postdata,"[\"%s\"]",coinaddr); + return(bitcoind_RPC(0,"",url,0,"listunspent",postdata)); + }*/ + +/*char *issue_LP_intro(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers) + { + char url[512]; + sprintf(url,"http://%s:%u/api/stats/intro?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers); + printf("(%s)\n",url); + return(issue_curl(url)); + }*/ + +// +// http://127.0.0.1:7779/api/stats/getpeers + +char *DEX_listunspent(char *coin,char *coinaddr) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"%s\",\"symbol\":\"%s\",\"timeout\":60000}",coinaddr,coin); + return(bitcoind_RPC(0,"dex",url,0,"listunspent",postdata,0)); +} + +bits256 iguana_wif2privkey(char *wifstr) +{ + char url[512],postdata[1024],*retstr,*privstr; bits256 privkey; cJSON *retjson; + memset(privkey.bytes,0,sizeof(privkey)); + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"SuperNET\",\"method\":\"wif2priv\",\"wif\":\"%s\"}",wifstr); + if ( (retstr= bitcoind_RPC(0,"SuperNET",url,0,"wif2priv",postdata,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (privstr= jstr(retjson,"privkey")) != 0 ) + { + if ( strlen(privstr) == 64 ) + decode_hex(privkey.bytes,32,privstr); + } + free_json(retjson); + } + free(retstr); + } + return(privkey); +} + +double bittrex_balance(char *base,char *coinaddr) +{ + char *retstr; cJSON *retjson; double balance = 0.; + if ( (retstr= DEX_balance("bittrex",base,coinaddr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + balance = jdouble(retjson,"balance"); + free_json(retjson); + } + free(retstr); + } + return(balance); +} + +double dex_balance(char *base,char *coinaddr) +{ + char *retstr; cJSON *retjson; double balance = 0.; + if ( (retstr= DEX_balance("DEX",base,coinaddr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + balance = jdouble(retjson,"balance"); + free_json(retjson); + } + free(retstr); + } + return(balance); +} + +int32_t komodo_baseid(char *base) +{ + int32_t i; + for (i=0; i 0 ) + { + for (i=0; i SMALLVAL && (name= jstr(item,"name")) != 0 && strncmp(name,"USD/",4) == 0 ) + { + if ( (baseid= komodo_baseid(name+4)) >= 0 && baseid < 32 ) + { + if ( ((1LL << baseid) & mask) == 0 ) + { + _marketmaker_fiatupdate(baseid,price); + mask |= (1LL << baseid); + } else if ( fabs(price*PAXPRICES[0] - PAXPRICES[baseid]) > SMALLVAL ) + printf("DUPLICATE PRICE? %s %.8f vs %.8f\n",name+4,price*PAXPRICES[0],PAXPRICES[baseid]); + } + } + } + } + } + printf("pax mask.%x\n",(uint32_t)mask); + return((uint32_t)mask); +} + +void marketmaker_cancel(struct mmpending_order *ptr) +{ + char *retstr; cJSON *retjson; + if ( ptr->pending != 0 && ptr->cancelstarted == 0 ) + { + ptr->cancelstarted = (uint32_t)time(NULL); + if ( (retstr= DEX_cancelorder(ptr->exchange,ptr->orderid)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + printf("cancel %s (%s/%s) %.8f vol %.8f dir.%d -> (%s)\n",ptr->exchange,ptr->base,ptr->rel,ptr->price,ptr->volume,ptr->dir,jprint(retjson,0)); + free_json(retjson); + ptr->pending = 0; + ptr->canceled = (uint32_t)time(NULL); + } + free(retstr); + } + } +} + +void marketmaker_queue(char *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *retjson) +{ + struct mmpending_order *ptr; char *orderid; + //DEX_trade.({"success":true,"message":"","result":{"uuid":"d5faa9e4-660d-436f-a257-2c6a40442d8c"},"tag":"11271578410079391025"} + if ( is_cJSON_True(jobj(retjson,"success")) != 0 && jobj(retjson,"result") != 0 ) + retjson = jobj(retjson,"result"); + printf("QUEUE.%s %s/%s dir.%d %.8f %.6f (%s)\n",exchange,base,rel,dir,price,volume,jprint(retjson,0)); + Pending_orders = realloc(Pending_orders,(1 + Num_Pending) * sizeof(*Pending_orders)); + ptr = &Pending_orders[Num_Pending++]; + memset(ptr,0,sizeof(*ptr)); + ptr->price = price; + ptr->volume = volume; + ptr->dir = dir; + ptr->pending = (uint32_t)time(NULL); + strcpy(ptr->exchange,exchange); + strcpy(ptr->base,base); + strcpy(ptr->rel,rel); + if ( (orderid= jstr(retjson,"OrderUuid")) != 0 || (orderid= jstr(retjson,"uuid")) != 0 ) + strcpy(ptr->orderid,orderid); + else strcpy(ptr->orderid,"0"); +} + +void marketmaker_pendingupdate(char *exchange,char *base,char *rel) +{ + char *retstr; cJSON *retjson,*obj; int32_t i; struct mmpending_order *ptr; + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( ptr->completed == 0 && (retstr= DEX_orderstatus(exchange,ptr->orderid)) != 0 ) + { + //printf("%s status.(%s)\n",ptr->orderid,retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + obj = jobj(retjson,"result"); + if ( is_cJSON_Array(obj) != 0 ) + obj = jitem(retjson,0); + if ( jdouble(obj,"QuantityRemaining") == 0. || is_cJSON_True(jobj(obj,"IsOpen")) == 0 ) + { + //{"Uuid":null,"OrderUuid":"e7b0789c-0c4e-413b-a768-3d5734d9cbe5","Exchange":"BTC-KMD","OrderType":"LIMIT_SELL","Quantity":877.77700000,"QuantityRemaining":462.50512234,"Limit":0.00011770,"CommissionPaid":0.00012219,"Price":0.04887750,"PricePerUnit":0.00011769,"Opened":"2017-02-20T13:16:22.29","Closed":null,"CancelInitiated":false,"ImmediateOrCancel":false,"IsConditional":false,"Condition":"NONE","ConditionTarget":null} printf("uuid.(%s) finished.(%s)\n",ptr->orderid,jprint(retjson,0)); + ptr->completed = (uint32_t)time(NULL); + ptr->pending = 0; + } + free_json(retjson); + } + free(retstr); + } + } +} + +void marketmaker_pendinginit(char *exchange,char *base,char *rel) +{ + char *retstr,*orderid,*pairstr,relbase[65]; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr; + sprintf(relbase,"%s-%s",rel,base); + if ( (retstr= DEX_openorders(exchange)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("%s\n",jprint(retjson,0)); + if ( is_cJSON_True(jobj(retjson,"success")) != 0 && (array= jarray(&n,retjson,"result")) != 0 ) + { + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( strcmp(ptr->orderid,orderid) == 0 ) + { + ptr->pending = (uint32_t)time(NULL); + ptr->completed = 0; + printf("%s pending\n",orderid); + break; + } + } + if ( j == Num_Pending ) + { + if ( jstr(item,"OrderType") != 0 ) + { + if ( strcmp(jstr(item,"OrderType"),"LIMIT_BUY") == 0 ) + dir = 1; + else if ( strcmp(jstr(item,"OrderType"),"LIMIT_SELL") == 0 ) + dir = -1; + else dir = 0; + if ( dir != 0 ) + marketmaker_queue(exchange,base,rel,dir,jdouble(item,"Limit"),jdouble(item,"QuantityRemaining"),item); + else printf("no dir (%s) (%s)\n",jprint(item,0),jstr(item,"OrderType")); + } + } + } + } + } + free_json(retjson); + } + free(retstr); + } +} + +double marketmaker_filled(char *exchange,char *base,char *rel,double *buyvolp,double *sellvolp,double *pendingbidsp,double *pendingasksp) +{ + double pricesum = 0.,volsum = 0.; struct mmpending_order *ptr; int32_t i; + *pendingbidsp = *pendingasksp = 0.; + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( ptr->completed != 0 ) + { + if ( ptr->reported == 0 ) + { + if ( ptr->dir > 0 ) + (*buyvolp) += ptr->volume; + else if ( ptr->dir < 0 ) + (*sellvolp) += ptr->volume; + pricesum += ptr->volume * ptr->price; + volsum += ptr->volume; + ptr->reported = (uint32_t)time(NULL); + printf("REPORT dir.%d vol %.8f\n",ptr->dir,ptr->volume); + } + } + else if ( ptr->pending != 0 ) // alternative is error or cancelled + { + if ( ptr->dir > 0 ) + (*pendingbidsp) += ptr->volume; + else if ( ptr->dir < 0 ) + (*pendingasksp) += ptr->volume; + } + } + if ( volsum != 0. ) + pricesum /= volsum; + return(pricesum); +} + +int32_t marketmaker_prune(char *exchange,char *base,char *rel,int32_t polarity,double bid,double ask,double separation) +{ + int32_t i,n = 0; struct mmpending_order *ptr; + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( ptr->pending != 0 && ptr->cancelstarted == 0 ) + { + if ( polarity != 0 ) + { + if ( ((ptr->dir*polarity > 0 && ptr->price < bid-separation) || (ptr->dir*polarity < 0 && ptr->price > ask+separation)) ) + { + printf("polarity.%d dir.%d price.%f bid.%f ask.%f\n",polarity,ptr->dir,ptr->price,bid,ask); + marketmaker_cancel(ptr), n++; + } + } + /*else + {,*prunebid=0,*pruneask=0; double lowbid=0.,highask=0. + if ( ptr->dir > 0 && (lowbid == 0. || ptr->price < lowbid) ) + { + lowbid = ptr->price; + prunebid = ptr; + } + else if ( ptr->dir < 0 && (highask == 0. || ptr->price > highask) ) + { + highask = ptr->price; + pruneask = ptr; + } + }*/ + } + } + /*if ( polarity == 0 ) + { + if ( prunebid != 0 && fabs(prunebid->price - bid) > separation ) + marketmaker_cancel(prunebid), n++; + if ( pruneask != 0 && fabs(pruneask->price - ask) > separation ) + marketmaker_cancel(pruneask), n++; + }*/ + return(n); +} + +void marketmaker_volumeset(double *bidincrp,double *askincrp,double incr,double buyvol,double pendingbids,double sellvol,double pendingasks,double maxexposure) +{ + *bidincrp = *askincrp = incr; + //if ( pendingbids >= pendingasks+maxexposure ) + // *bidincrp = 0.; + //else if ( pendingasks >= pendingbids+maxexposure ) + // *askincrp = 0.; + if ( *bidincrp > 0. && pendingbids + *bidincrp > maxexposure ) + *bidincrp = (maxexposure - *bidincrp); + if ( *askincrp > 0. && pendingasks + *askincrp > maxexposure ) + *askincrp = (maxexposure - *askincrp); + if ( *bidincrp < 0. ) + *bidincrp = 0.; + if ( *askincrp < 0. ) + *askincrp = 0.; +} + +int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double bidvol,double ask,double askvol,double separation) +{ + int32_t nearflags[2],i,n = 0; struct mmpending_order *ptr; cJSON *retjson,*vals; char *retstr,postdata[1024],url[128]; double vol,spread_ratio; + memset(nearflags,0,sizeof(nearflags)); + if ( strcmp("DEX",exchange) != 0 ) + { + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( ptr->pending != 0 && ptr->cancelstarted == 0 ) + { + if ( bid > SMALLVAL && bidvol > SMALLVAL && ptr->dir > 0 && fabs(bid - ptr->price) < separation ) + { + //printf("bid %.8f near %.8f\n",bid,ptr->price); + nearflags[0]++; + } + if ( ask > SMALLVAL && askvol > SMALLVAL && ptr->dir < 0 && fabs(ask - ptr->price) < separation ) + { + //printf("%.8f near %.8f\n",ask,ptr->price); + nearflags[1]++; + } + } + } + } + //printf("spread.%s (%.8f %.6f) (%.8f %.6f)\n",exchange,bid,bidvol,ask,askvol); + if ( bid > SMALLVAL && bidvol > SMALLVAL && nearflags[0] == 0 ) + { + if ( strcmp("DEX",exchange) == 0 && strcmp(base,"KMD") == 0 && strcmp(rel,"BTC") == 0 ) + { + if ( ask > SMALLVAL && askvol > SMALLVAL ) + { + /*li.profit = jdouble(vals,"profit"); + li.refprice = jdouble(vals,"refprice"); + li.bid = jdouble(vals,"bid"); + li.ask = jdouble(vals,"ask"); + if ( (li.minvol= jdouble(vals,"minvol")) <= 0. ) + li.minvol = (strcmp("BTC",base) == 0) ? 0.0001 : 0.001; + if ( (li.maxvol= jdouble(vals,"maxvol")) < li.minvol ) + li.maxvol = li.minvol;*/ + //curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MVP\",\"vals\":{\"rel\":\"USD\",\"bid\":0.09,\"ask\":0.11,\"maxvol\":100}}" + vals = cJSON_CreateObject(); + jaddstr(vals,"rel","BTC"); + jaddnum(vals,"bid",bid); + jaddnum(vals,"ask",ask); + vol = bidvol > askvol ? askvol : bidvol; + jaddnum(vals,"maxvol",vol); + jaddnum(vals,"minvol",vol*0.1 > 100 ? 100 : vol * 0.1); + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}",base,jprint(vals,1)); + //printf("(%s)\n",postdata); + if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 ) + { + //printf("(%s) -> (%s)\n",postdata,retstr); + free(retstr); + } + spread_ratio = .5 * ((ask - bid) / (bid + ask)); + for (i=0; i SMALLVAL ) + { + vals = cJSON_CreateObject(); + jaddstr(vals,"rel",CURRENCIES[i]); + jaddnum(vals,"bid",PAXPRICES[i] * (1. - spread_ratio)); + jaddnum(vals,"ask",PAXPRICES[i] * (1. + spread_ratio)); + jaddnum(vals,"maxvol",vol * PAXPRICES[i]); + jaddnum(vals,"minvol",MAX(1,(int32_t)(vol * 0.01 * PAXPRICES[i]))); + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}","KMD",jprint(vals,1)); + if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 ) + { + //printf("(%s) -> (%s)\n",postdata,retstr); + free(retstr); + } + } + //break; + } + } else printf("unsupported ask only for DEX %s/%s\n",base,rel); + } + else if ( (retstr= DEX_trade(exchange,base,rel,1,bid,bidvol)) != 0 ) + { + //printf("DEX_trade.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + marketmaker_queue(exchange,base,rel,1,bid,bidvol,retjson); + free_json(retjson); + } + free(retstr); + } //else printf("skip bid %s %.8f vol %f\n",exchange,bid,bidvol); + } + if ( ask > SMALLVAL && askvol > SMALLVAL && nearflags[1] == 0 && strcmp("DEX",exchange) != 0 ) + { + if ( (retstr= DEX_trade(exchange,base,rel,-1,ask,askvol)) != 0 ) + { + //printf("DEX_trade.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + marketmaker_queue(exchange,base,rel,-1,ask,askvol,retjson); + free_json(retjson); + } + free(retstr); + } + } //else printf("skip ask %s %.8f vol %f\n",exchange,bid,bidvol); + return(n); +} + +double marketmaker_updateprice(char *name,char *base,char *rel,double theoretical,double *incrp) +{ + static uint32_t counter; + cJSON *fiatjson; double USD_average=0.,usdprice=0.,CMC_average=0.,avebid=0.,aveask=0.,val,changes[3],highbid=0.,lowask=0.; + if ( (val= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,name,base,rel,&USD_average)) != 0. ) + { + if ( theoretical == 0. ) + { + theoretical = val; + if ( *incrp > 2 ) + { + *incrp = (int32_t)*incrp; + *incrp += 0.777; + } + } else theoretical = (theoretical + val) * 0.5; + if ( (counter++ % 12) == 0 ) + { + if ( USD_average > SMALLVAL && CMC_average > SMALLVAL && theoretical > SMALLVAL ) + { + usdprice = USD_average * (theoretical / CMC_average); + printf("USD %.4f <- (%.6f * (%.8f / %.8f))\n",usdprice,USD_average,theoretical,CMC_average); + PAXPRICES[0] = usdprice; + if ( (fiatjson= yahoo_allcurrencies()) != 0 ) + { + marketmaker_fiatupdate(fiatjson); + free_json(fiatjson); + } + } + } + LP_priceupdate(base,rel,theoretical,avebid,aveask,highbid,lowask,PAXPRICES); + } + return(theoretical); +} + +void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double start_BASE,double start_REL,double profitmargin,double maxexposure,double ratioincr,char *exchange,char *name,char *base,char *rel) +{ + char *retstr; double bid,ask,start_DEXbase,start_DEXrel,DEX_base = 0.,DEX_rel = 0.,balance_base=0.,balance_rel=0.,mmbid,mmask,aveprice,incr,pendingbids,pendingasks,buyvol,sellvol,bidincr,askincr,filledprice,avebid=0.,aveask=0.,highbid=0.,lowask=0.,theoretical = 0.; uint32_t lasttime = 0; + incr = maxexposure * ratioincr; + buyvol = sellvol = 0.; + start_DEXbase = dex_balance(base,baseaddr); + start_DEXrel = dex_balance(rel,reladdr); + while ( 1 ) + { + if ( time(NULL) > lasttime+60 ) + { + if ( (theoretical= marketmaker_updateprice(name,base,rel,theoretical,&incr)) != 0. ) + { + if ( lasttime == 0 ) + maxexposure /= theoretical; + } + if ( strcmp(exchange,"bittrex") == 0 ) + { + balance_base = bittrex_balance(base,""); + balance_rel = bittrex_balance(rel,""); + DEX_base = dex_balance(base,baseaddr); + DEX_rel = dex_balance(rel,reladdr); + } else printf("add support for %s balance\n",exchange); + lasttime = (uint32_t)time(NULL); + } + marketmaker_pendingupdate(exchange,base,rel); + if ( theoretical > SMALLVAL && avebid > SMALLVAL && aveask > SMALLVAL ) + { + aveprice = (avebid + aveask) * 0.5; + // if order is filled, theoretical <- filled (theoretical + price)/2 + if ( (filledprice= marketmaker_filled(exchange,base,rel,&buyvol,&sellvol,&pendingbids,&pendingasks)) != 0. ) + theoretical = (theoretical + filledprice) * 0.5; + buyvol = sellvol = 0; + if ( (balance_base + DEX_base) < (start_BASE + start_DEXbase) ) + sellvol += ((start_BASE + start_DEXbase) - (balance_base + DEX_base)); + else buyvol += ((balance_base + DEX_base) - (start_BASE + start_DEXbase)); + if ( (balance_rel + DEX_rel) < (start_REL + start_DEXrel) ) + buyvol += ((start_REL + start_DEXrel) - (balance_rel + DEX_rel)) / theoretical; + else sellvol += ((balance_rel + DEX_rel) - (start_REL + start_DEXrel)) / theoretical; + mmbid = theoretical - theoretical*profitmargin; + mmask = theoretical + theoretical*profitmargin; + // if any existing order exceeds double margin distance, cancel + marketmaker_prune(exchange,base,rel,1,mmbid - theoretical*profitmargin,mmask + theoretical*profitmargin,0.); + // if new prices crosses existing order, cancel old order first + marketmaker_prune(exchange,base,rel,-1,mmbid,mmask,0.); + //printf("(%.8f %.8f) ",mmbid,mmask); + if ( (1) ) + { + if ( mmbid >= lowask || (maxbid > SMALLVAL && mmbid > maxbid) ) //mmbid < highbid || + { + printf("clear mmbid %.8f lowask %.8f maxbid %.8f\n",mmbid,lowask,maxbid); + mmbid = 0.; + } + if ( mmask <= highbid || (minask > SMALLVAL && mmask < minask) ) // mmask > lowask || + mmask = 0.; + } + marketmaker_volumeset(&bidincr,&askincr,incr,buyvol,pendingbids,sellvol,pendingasks,maxexposure); + printf("AVE.(%.8f %.8f) hbla %.8f %.8f bid %.8f ask %.8f theory %.8f buys.(%.6f %.6f) sells.(%.6f %.6f) incr.(%.6f %.6f) balances.(%.8f + %.8f, %.8f + %.8f) test %f\n",avebid,aveask,highbid,lowask,mmbid,mmask,theoretical,buyvol,pendingbids,sellvol,pendingasks,bidincr,askincr,balance_base,DEX_base,balance_rel,DEX_rel,(aveask - avebid)/aveprice); + if ( (retstr= DEX_swapstatus()) != 0 ) + printf("%s\n",retstr), free(retstr); + printf("%s %s %s, %s %s %s\n",base,DEX_baseaddr,DEX_balance("DEX",base,DEX_baseaddr),rel,DEX_reladdr,DEX_balance("DEX",rel,DEX_reladdr)); + if ( (aveask - avebid)/aveprice > profitmargin ) + bid = highbid * (1 - profitmargin), ask = lowask * (1 + profitmargin); + else bid = avebid - profitmargin*aveprice, ask = avebid + profitmargin*aveprice; + marketmaker_spread("DEX",base,rel,bid,incr,ask,incr,profitmargin*aveprice*0.5); + if ( (pendingbids + buyvol) > (pendingasks + sellvol) && (pendingbids + buyvol) > bidincr ) + { + bidincr *= ((double)(pendingasks + sellvol) / ((pendingbids + buyvol) + (pendingasks + sellvol))); + printf("bidincr %f buy.(%f + %f) sell.(%f + %f)\n",bidincr,pendingbids,buyvol,pendingasks,sellvol); + if ( bidincr < 0.1*incr ) + bidincr = 0.1*incr; + if ( bidincr > 1. ) + bidincr = (int32_t)bidincr + 0.777; + } + if ( (pendingbids + buyvol) < (pendingasks + sellvol) && (pendingasks + sellvol) > askincr ) + { + askincr *= (double)(pendingbids + buyvol) / ((pendingbids + buyvol) + (pendingasks + sellvol)); + if ( askincr < 0.1*incr ) + askincr = 0.1*incr; + if ( askincr > 1. ) + askincr = (int32_t)askincr + 0.777; + } + //printf("mmbid %.8f %.6f, mmask %.8f %.6f\n",mmbid,bidincr,mmask,askincr); + marketmaker_spread(exchange,base,rel,mmbid,bidincr,mmask,askincr,profitmargin*aveprice*0.5); + sleep(60); + } + } +} +profitmargin = jdouble(retjson,"profitmargin"); +minask = jdouble(retjson,"minask"); +maxbid = jdouble(retjson,"maxbid"); +maxexposure = jdouble(retjson,"maxexposure"); +incrratio = jdouble(retjson,"lotratio"); +start_base = jdouble(retjson,"start_base"); +start_rel = jdouble(retjson,"start_rel"); +apikey = jstr(retjson,"apikey"); +apisecret = jstr(retjson,"apisecret"); +base = jstr(retjson,"base"); +name = jstr(retjson,"name"); +rel = jstr(retjson,"rel"); +blocktrail = jstr(retjson,"blocktrail"); +exchange = jstr(retjson,"exchange"); +//PAXACTIVE = juint(retjson,"paxactive"); +if ( profitmargin < 0. || maxexposure <= 0. || incrratio <= 0. || apikey == 0 || apisecret == 0 || base == 0 || name == 0 || rel == 0 || exchange == 0 || blocktrail == 0 ) +{ + printf("illegal parameter (%s)\n",jprint(retjson,0)); + exit(-1); +} +if ( (retstr= iguana_walletpassphrase(passphrase,999999)) != 0 ) +{ + printf("(%s/%s) login.(%s)\n",base,rel,retstr); + if ( (loginjson= cJSON_Parse(retstr)) != 0 ) + { + if ( PAXACTIVE != 0 ) + { + for (i=0; i<32; i++) + { + if ( ((1< 0 ) + { + ptr = (uint8_t *)tx.vout[numvouts - 1].scriptPubKey.data(); + len = tx.vout[numvouts - 1].scriptPubKey.size(); + retval = komodo_verifynotarizedscript(height,ptr,len,NOTARIZED_HASH); + printf("direct verify ht.%d -> %d\n",height,retval); + return(retval); + } +} + +/*struct LP_cacheinfo *ptr,*tmp; + HASH_ITER(hh,LP_cacheinfos,ptr,tmp) + { + if ( ptr->timestamp < now-3600*2 || ptr->price == 0. ) + continue; + if ( strcmp(ptr->Q.srccoin,base) == 0 && strcmp(ptr->Q.destcoin,rel) == 0 ) + { + asks = realloc(asks,sizeof(*asks) * (numasks+1)); + if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 ) + asks[numasks++] = op; + } + else if ( strcmp(ptr->Q.srccoin,rel) == 0 && strcmp(ptr->Q.destcoin,base) == 0 ) + { + bids = realloc(bids,sizeof(*bids) * (numbids+1)); + if ( (op= LP_orderbookentry(base,rel,ptr->Q.txid,ptr->Q.vout,ptr->Q.txid2,ptr->Q.vout2,1./ptr->price,ptr->Q.satoshis,ptr->Q.srchash)) != 0 ) + bids[numbids++] = op; + } + }*/ + +/*void basilisk_swaps_init(struct supernet_info *myinfo) + { + char fname[512]; uint32_t iter,swapcompleted,requestid,quoteid,optionduration,statebits; FILE *fp; bits256 privkey;struct basilisk_request R; struct basilisk_swapmessage M; struct basilisk_swap *swap = 0; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (myinfo->swapsfp= fopen(fname,"rb+")) != 0 ) + { + while ( fread(&requestid,1,sizeof(requestid),myinfo->swapsfp) == sizeof(requestid) && fread("eid,1,sizeof(quoteid),myinfo->swapsfp) == sizeof(quoteid) ) + { + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + printf("%s\n",fname); + if ( (fp= fopen(fname,"rb+")) != 0 ) // check to see if completed + { + memset(&M,0,sizeof(M)); + swapcompleted = 1; + for (iter=0; iter<2; iter++) + { + if ( fread(privkey.bytes,1,sizeof(privkey),fp) == sizeof(privkey) && + fread(&R,1,sizeof(R),fp) == sizeof(R) && + fread(&statebits,1,sizeof(statebits),fp) == sizeof(statebits) && + fread(&optionduration,1,sizeof(optionduration),fp) == sizeof(optionduration) ) + { + while ( 0 && fread(&M,1,sizeof(M),fp) == sizeof(M) ) + { + M.data = 0; + //printf("entry iter.%d crc32.%x datalen.%d\n",iter,M.crc32,M.datalen); + if ( M.datalen < 100000 ) + { + M.data = malloc(M.datalen); + if ( fread(M.data,1,M.datalen,fp) == M.datalen ) + { + if ( calc_crc32(0,M.data,M.datalen) == M.crc32 ) + { + if ( iter == 1 ) + { + if ( swap == 0 ) + { + swap = basilisk_thread_start(privkey,&R,statebits,optionduration,1); + swap->I.choosei = swap->I.otherchoosei = -1; + } + if ( swap != 0 ) + basilisk_swapgotdata(swap,M.crc32,M.srchash,M.desthash,M.quoteid,M.msgbits,M.data,M.datalen,1); + } + } else printf("crc mismatch %x vs %x\n",calc_crc32(0,M.data,M.datalen),M.crc32); + } else printf("error reading M.datalen %d\n",M.datalen); + free(M.data), M.data = 0; + } + } + } + if ( swapcompleted != 0 ) + break; + rewind(fp); + } + } + } + } else myinfo->swapsfp = fopen(fname,"wb+"); + }*/ + +FILE *basilisk_swap_save(struct basilisk_swap *swap,bits256 privkey,struct basilisk_request *rp,uint32_t statebits,int32_t optionduration,int32_t reinit) +{ + FILE *fp=0; /*char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,rp->requestid,rp->quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) == 0 ) + { + if ( (fp= fopen(fname,"wb+")) != 0 ) + { + fwrite(privkey.bytes,1,sizeof(privkey),fp); + fwrite(rp,1,sizeof(*rp),fp); + fwrite(&statebits,1,sizeof(statebits),fp); + fwrite(&optionduration,1,sizeof(optionduration),fp); + fflush(fp); + } + } + else if ( reinit != 0 ) + { + }*/ + return(fp); +} +//printf("VOUT.(%s)\n",jprint(vout,0)); +/*if ( (skey= jobj(vout,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) + { + item = jitem(addresses,0); + //printf("item.(%s)\n",jprint(item,0)); + if ( (addr= jstr(item,0)) != 0 ) + { + safecopy(coinaddr,addr,64); + //printf("extracted.(%s)\n",coinaddr); + } + }*/ + +/*if ( IAMLP != 0 && time(NULL) > lasthello+600 ) + { + char *hellostr,*retstr; cJSON *retjson; int32_t allgood,sock = LP_bindsock; + allgood = 0; + if ( (retstr= issue_hello(myport)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (hellostr= jstr(retjson,"status")) != 0 && strcmp(hellostr,"got hello") == 0 ) + allgood = 1; + else printf("strange return.(%s)\n",jprint(retjson,0)); + free_json(retjson); + } else printf("couldnt parse hello return.(%s)\n",retstr); + free(retstr); + } else printf("issue_hello NULL return\n"); + lasthello = (uint32_t)time(NULL); + if ( allgood == 0 ) + { + printf("RPC port got stuck, would have close bindsocket\n"); + if ( 0 ) + { + LP_bindsock = -1; + closesocket(sock); + LP_bindsock_reset++; + sleep(10); + printf("launch new rpcloop\n"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&myport) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",myport); + exit(-1); + } + } + } + }*/ +/* + now = (uint32_t)time(NULL); + numpeers = LP_numpeers(); + needpings = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->errors >= LP_MAXPEER_ERRORS ) + { + if ( (LP_rand() % 10000) == 0 ) + { + peer->errors--; + if ( peer->errors < LP_MAXPEER_ERRORS ) + peer->diduquery = 0; + } + if ( IAMLP == 0 ) + continue; + } + if ( now > peer->lastpeers+LP_ORDERBOOK_DURATION*.777 || (LP_rand() % 100000) == 0 ) + { + if ( strcmp(peer->ipaddr,myipaddr) != 0 ) + { + nonz++; + //issue_LP_getpeers(peer->ipaddr,peer->port); + //LP_peersquery(mypeer,pubsock,peer->ipaddr,peer->port,myipaddr,myport); + //if ( peer->diduquery == 0 ) + // LP_peer_pricesquery(peer); + //LP_utxos_sync(peer); + needpings++; + } + peer->lastpeers = now; + } + if ( peer->needping != 0 ) + { + peer->diduquery = now; + nonz++; + if ( (retstr= issue_LP_notify(peer->ipaddr,peer->port,"127.0.0.1",0,numpeers,G.LP_sessionid,G.LP_myrmd160str,G.LP_mypub25519)) != 0 ) + free(retstr); + peer->needping = 0; + needpings++; + } + }*/ + +#ifdef oldway +int32_t LP_peersparse(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *retstr,uint32_t now) +{ + struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t numpeers,i,n=0; + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i numpeers) ) + peer = LP_addpeer(mypeer,mypubsock,argipaddr,argport,pushport,subport,jint(item,"numpeers"),jint(item,"numutxos"),juint(item,"session")); + } + if ( peer != 0 ) + { + peer->lasttime = now; + if ( strcmp(argipaddr,destipaddr) == 0 && destport == argport && peer->numpeers != n ) + peer->numpeers = n; + } + } + } + } + free_json(array); + } + return(n); +} +void issue_LP_getpeers(char *destip,uint16_t destport) +{ + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","getpeers"); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/getpeers?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers); + retstr = LP_issue_curl("getpeers",destip,port,url); + //printf("%s -> getpeers.(%s)\n",destip,retstr); + return(retstr);*/ +} + +void LP_peer_request(char *destip,uint16_t destport,cJSON *argjson) +{ + struct LP_peerinfo *peer; uint8_t *msg; int32_t msglen; uint32_t crc32; + peer = LP_peerfind((uint32_t)calc_ipbits(destip),destport); + msg = (void *)jprint(argjson,0); + msglen = (int32_t)strlen((char *)msg) + 1; + crc32 = calc_crc32(0,&msg[2],msglen - 2); + LP_queuesend(crc32,peer->pushsock,"","",msg,msglen); + free_json(argjson); +}void LP_peersquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *myipaddr,uint16_t myport) +{ + char *retstr; struct LP_peerinfo *peer,*tmp; bits256 zero; uint32_t now,flag = 0; + peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); + if ( (retstr= issue_LP_getpeers(destipaddr,destport,myipaddr,myport,mypeer!=0?mypeer->numpeers:0)) != 0 ) + { + //printf("got.(%s)\n",retstr); + now = (uint32_t)time(NULL); + LP_peersparse(mypeer,mypubsock,destipaddr,destport,retstr,now); + free(retstr); + if ( IAMLP != 0 ) + { + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + if ( peer->lasttime != now ) + { + printf("{%s:%u}.%d ",peer->ipaddr,peer->port,peer->lasttime - now); + flag++; + memset(&zero,0,sizeof(zero)); + if ( (retstr= issue_LP_notify(destipaddr,destport,peer->ipaddr,peer->port,peer->numpeers,peer->sessionid,0,zero)) != 0 ) + free(retstr); + } + } + if ( flag != 0 ) + printf(" <- missing peers\n"); + } + } +} +void issue_LP_notify(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,uint32_t sessionid,char *rmd160str,bits256 pub) +{ + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","notify"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"coinaddr",coinaddr); + jaddbits256(reqjson,"txid",txid); + jaddnum(reqjson,"vout",vout); + jaddnum(reqjson,"ht",height); + jadd64bits(reqjson,"value",value); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr,str[65]; + if ( (retstr= LP_isitme(destip,destport)) != 0 ) + return(retstr); + sprintf(url,"http://%s:%u/api/stats/notify?ipaddr=%s&port=%u&numpeers=%d&session=%u",destip,destport,ipaddr,port,numpeers,sessionid); + if ( rmd160str != 0 && bits256_nonz(pub) != 0 ) + { + sprintf(url+strlen(url),"&rmd160=%s&pub=%s",rmd160str,bits256_str(str,pub)); + //printf("SEND (%s)\n",url); + } + return(LP_issue_curl("notify",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT));*/ +} + +char *issue_hello(uint16_t port) +{ + char url[512]; + sprintf(url,"http://127.0.0.1:%u/api/stats/hello",port); + //printf("getutxo.(%s)\n",url); + return(issue_curlt(url,600)); // might be starting a trade +} + + +void issue_LP_uitem(char *destip,uint16_t destport,char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t height,uint64_t value) +{ + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","uitem"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"coinaddr",coinaddr); + jaddbits256(reqjson,"txid",txid); + jaddnum(reqjson,"vout",vout); + jaddnum(reqjson,"ht",height); + jadd64bits(reqjson,"value",value); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr,str[65]; + if ( (retstr= LP_isitme(destip,destport)) != 0 ) + return(retstr); + sprintf(url,"http://%s:%u/api/stats/uitem?coin=%s&coinaddr=%s&txid=%s&vout=%d&ht=%d&value=%llu",destip,destport,symbol,coinaddr,bits256_str(str,txid),vout,height,(long long)value); + retstr = LP_issue_curl("uitem",destip,destport,url); + //printf("uitem.(%s)\n",retstr); + return(retstr);*/ +} + +/*if ( (liststr= basilisk_swaplist(requestid,quoteid)) != 0 ) + { + //printf("swapentry.(%s)\n",liststr); + if ( (retjson= cJSON_Parse(liststr)) != 0 ) + { + if ( (array= jarray(&n,retjson,"swaps")) != 0 ) + { + for (i=0; itimestamp = (uint32_t)time(NULL); + ptr->item = item; + item->cjsonid = LP_rand(); + ptr->cjsonid = item->cjsonid; + portable_mutex_lock(&LP_cJSONmutex); + DL_APPEND(LP_cJSONlist,ptr); + portable_mutex_unlock(&LP_cJSONmutex); + } + + void cJSON_unregister(cJSON *item) + { + static uint32_t lasttime; + int32_t n; char *tmpstr; uint64_t total = 0; struct cJSON_list *ptr,*tmp; uint32_t now; + if ( (now= (uint32_t)time(NULL)) > lasttime+6 ) + { + n = 0; + DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) + { + if ( ptr->item != 0 && ptr->item->child != 0 && ptr->cjsonid != 0 ) + { + if ( (tmpstr= jprint(ptr->item,0)) != 0 ) + { + total += strlen(tmpstr); + free(tmpstr); + } + } + n++; + } + printf("total %d cJSON pending\n",n); + lasttime = (uint32_t)time(NULL); + } + DL_FOREACH_SAFE(LP_cJSONlist,ptr,tmp) + { + if ( ptr->cjsonid == item->cjsonid ) + break; + else if ( now > ptr->timestamp+60 && item->cjsonid != 0 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_cJSONlist,ptr); + portable_mutex_unlock(&LP_cJSONmutex); + printf("free expired\n"); + cJSON_Delete(ptr->item); + free(ptr); + } + ptr = 0; + } + if ( ptr != 0 ) + { + portable_mutex_lock(&LP_cJSONmutex); + DL_DELETE(LP_cJSONlist,ptr); + free(ptr); + portable_mutex_unlock(&LP_cJSONmutex); + } //else printf("cJSON_unregister of unknown %p %u\n",item,item->cjsonid); + }*/ + +void LP_instantdex_txidadd(bits256 txid) +{ + cJSON *array; int32_t i,n; + if ( (array= LP_instantdex_txids()) == 0 ) + array = cJSON_CreateArray(); + if ( (n= cJSON_GetArraySize(array)) >= 0 ) + { + for (i=0; i a_value ) + destsatoshis = a_value; + if ( maxdestsatoshis != 0 && destsatoshis > maxdestsatoshis-desttxfee-1 ) + destsatoshis = maxdestsatoshis-desttxfee-1; + satoshis = (destsatoshis / price + 0.49) - txfee; + *destsatoshisp = destsatoshis; + *satoshisp = satoshis; + if ( satoshis > 0 ) + return((double)destsatoshis / satoshis); + else return(0.); + }*/ + +/*for (iambob=0; iambob<2; iambob++) + { + if ( G.LP_utxoinfos[iambob] != 0 ) + { + HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) + { + HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); + //free(utxo); + } + } + if ( G.LP_utxoinfos2[iambob] != 0 ) + { + G.LP_utxoinfos2[iambob] = 0; + //HASH_ITER(hh,G.LP_utxoinfos2[iambob],utxo,tmp) + //{ + // HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); + // free(utxo); + //} + } + }*/ + +char *issue_LP_getprices(char *destip,uint16_t destport) +{ + char url[512]; + sprintf(url,"http://%s:%u/api/stats/getprices",destip,destport); + //printf("getutxo.(%s)\n",url); + return(LP_issue_curl("getprices",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT)); +} +/*if ( fullflag != 0 ) + { + if ( (destport= LP_randpeer(destip)) > 0 ) + { + retstr = issue_LP_listunspent(destip,destport,symbol,coinaddr); + //printf("issue %s %s %s -> (%s)\n",coin->symbol,coinaddr,destip,retstr); + retjson = cJSON_Parse(retstr); + } else printf("LP_listunspent_issue couldnt get a random peer?\n"); + }*/ + +void issue_LP_listunspent(char *destip,uint16_t destport,char *symbol,char *coinaddr) +{ + cJSON *reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","listunspent"); + jaddstr(reqjson,"coin",symbol); + jaddstr(reqjson,"address",coinaddr); + LP_peer_request(destip,destport,reqjson); + /*char url[512],*retstr; + sprintf(url,"http://%s:%u/api/stats/listunspent?coin=%s&address=%s",destip,destport,symbol,coinaddr); + retstr = LP_issue_curl("listunspent",destip,destport,url); + //printf("listunspent.(%s) -> (%s)\n",url,retstr); + return(retstr);*/ +} + +int32_t LP_listunspent_both(char *symbol,char *coinaddr,int32_t fullflag) +{ + int32_t i,v,numconfs,height,n=0; uint64_t value; bits256 txid; char buf[512]; cJSON *array,*item; uint32_t now; struct iguana_info *coin = LP_coinfind(symbol); + if ( coin != 0 )//&& (IAMLP != 0 || coin->inactive == 0) ) + { + if ( coin->electrum != 0 || LP_address_ismine(symbol,coinaddr) <= 0 ) + { + //printf("issue path electrum.%p\n",coin->electrum); + //if ( coin->electrum != 0 && (array= electrum_address_gethistory(symbol,coin->electrum,&array,coinaddr)) != 0 ) + // free_json(array); + n = LP_listunspent_issue(symbol,coinaddr,fullflag); + } + else + { + if ( strcmp(symbol,"BTC") == 0 ) + numconfs = 0; + else numconfs = 1; + //printf("my coin electrum.%p\n",coin->electrum); + sprintf(buf,"[%d, 99999999, [\"%s\"]]",numconfs,coinaddr); + if ( (array= bitcoin_json(coin,"listunspent",buf)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + now = (uint32_t)time(NULL); + for (i=0; iinactive:-1); + return(n); +} +char *LP_bestfit(char *rel,double relvolume) +{ + struct LP_utxoinfo *autxo; + if ( relvolume <= 0. || LP_priceinfofind(rel) == 0 ) + return(clonestr("{\"error\":\"invalid parameter\"}")); + if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) + return(clonestr("{\"error\":\"cant find utxo that is close enough in size\"}")); + return(jprint(LP_utxojson(autxo),1)); +} +int32_t LP_utxos_sync(struct LP_peerinfo *peer) +{ + int32_t i,j,n=0,m,v,posted=0; bits256 txid; cJSON *array,*item,*item2,*array2; uint64_t total,total2; struct iguana_info *coin,*ctmp; char *retstr,*retstr2; + if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) + return(0); + HASH_ITER(hh,LP_coins,coin,ctmp) + { + if ( IAMLP == 0 && coin->inactive != 0 ) + continue; + if ( coin->smartaddr[0] == 0 ) + continue; + total = 0; + if ( (j= LP_listunspent_both(coin->symbol,coin->smartaddr,0)) == 0 ) + continue; + if ( (array= LP_address_utxos(coin,coin->smartaddr,1)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 && total > 0 && (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr)) != 0 ) + { + //printf("UTXO sync.%d %s n.%d total %.8f -> %s (%s)\n",j,coin->symbol,n,dstr(total),peer->ipaddr,retstr); + total2 = 0; + if ( (array2= cJSON_Parse(retstr)) != 0 ) + { + if ( (m= cJSON_GetArraySize(array2)) > 0 ) + { + for (i=0; iipaddr,coin->symbol,jprint(item,0)); + issue_LP_uitem(peer->ipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value")); + posted++; + } + } + if ( 0 && posted != 0 ) + printf(">>>>>>>> %s compare %s %s (%.8f n%d) (%.8f m%d)\n",peer->ipaddr,coin->symbol,coin->smartaddr,dstr(total),n,dstr(total2),m); + } //else printf("%s matches %s\n",peer->ipaddr,coin->symbol); + free_json(array2); + } else printf("parse error (%s)\n",retstr); + free(retstr); + } + else if ( n != 0 && total != 0 ) + { + //printf("no response from %s for %s %s\n",peer->ipaddr,coin->symbol,coin->smartaddr); + for (i=0; iipaddr,peer->port,coin->symbol,coin->smartaddr,txid,v,jint(item,"height"),j64bits(item,"value")); + } + } + free_json(array); + } + } + return(posted); +} +/*char *issue_LP_notifyutxo(char *destip,uint16_t destport,struct LP_utxoinfo *utxo) + { + char url[4096],str[65],str2[65],str3[65],*retstr; struct _LP_utxoinfo u; uint64_t val,val2; + if ( (retstr= LP_isitme(destip,destport)) != 0 ) + return(retstr); + if ( utxo->iambob == 0 ) + { + printf("issue_LP_notifyutxo trying to send Alice %s/v%d\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout); + return(0); + } + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) > 0 ) + { + sprintf(url,"http://%s:%u/api/stats/notified?iambob=%d&pubkey=%s&coin=%s&txid=%s&vout=%d&value=%llu&txid2=%s&vout2=%d&value2=%llu&script=%s&address=%s×tamp=%u&gui=%s",destip,destport,utxo->iambob,bits256_str(str3,utxo->pubkey),utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,(long long)utxo->payment.value,bits256_str(str2,utxo->deposit.txid),utxo->deposit.vout,(long long)utxo->deposit.value,utxo->spendscript,utxo->coinaddr,(uint32_t)time(NULL),utxo->gui); + if ( strlen(url) > 1024 ) + printf("WARNING long url.(%s)\n",url); + return(LP_issue_curl("notifyutxo",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT)); + } + else + { + printf("issue_LP_notifyutxo: ineligible utxo iambob.%d %.8f %.8f\n",utxo->iambob,dstr(val),dstr(val2)); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + return(0); + } + }*/ + +/*char *issue_LP_lookup(char *destip,uint16_t destport,bits256 pubkey) + { + char url[512],str[65]; + sprintf(url,"http://%s:%u/api/stats/lookup?client=%s",destip,destport,bits256_str(str,pubkey)); + //printf("getutxo.(%s)\n",url); + return(LP_issue_curl("lookup",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT)); + }*/ + + +/*if ( LP_canbind == 0 ) + { + //printf("check deadman %u vs %u\n",LP_deadman_switch,(uint32_t)time(NULL)); + if ( LP_deadman_switch < time(NULL)-PSOCK_KEEPALIVE ) + { + printf("DEAD man's switch %u activated at %u lag.%d, register forwarding again\n",LP_deadman_switch,(uint32_t)time(NULL),(uint32_t)(time(NULL) - LP_deadman_switch)); + if ( pullsock >= 0 ) + nn_close(pullsock); + pullsock = LP_initpublicaddr(ctx,&mypullport,pushaddr,myipaddr,mypullport,0); + LP_deadman_switch = (uint32_t)time(NULL); + strcpy(LP_publicaddr,pushaddr); + LP_publicport = mypullport; + LP_forwarding_register(LP_mypubkey,pushaddr,mypullport,MAX_PSOCK_PORT); + } + }*/ +/*if ( lastforward < now-3600 ) + { + if ( (retstr= LP_registerall(0)) != 0 ) + free(retstr); + //LP_forwarding_register(LP_mypubkey,pushaddr,pushport,10); + lastforward = now; + }*/ +//if ( IAMLP != 0 && (counter % 600) == 42 ) +// LP_hellos(); +/*if ( 0 && LP_canbind == 0 && (counter % (PSOCK_KEEPALIVE*MAINLOOP_PERSEC/2)) == 13 ) + { + char keepalive[128]; + sprintf(keepalive,"{\"method\":\"keepalive\"}"); + //printf("send keepalive to %s pullsock.%d\n",pushaddr,pullsock); + if ( /LP_send(pullsock,keepalive,(int32_t)strlen(keepalive)+1,0) < 0 ) + { + //LP_deadman_switch = 0; + } + }*/ + +/*int32_t nn_tests(void *ctx,int32_t pullsock,char *pushaddr,int32_t nnother) + { + int32_t sock,n,m,timeout,retval = -1; char msg[512],*retstr; + printf("nn_tests.(%s)\n",pushaddr); + if ( (sock= nn_socket(AF_SP,nnother)) >= 0 ) + { + if ( nn_connect(sock,pushaddr) < 0 ) + printf("connect error %s\n",nn_strerror(nn_errno())); + else + { + sleep(3); + timeout = 1; + nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); + sprintf(msg,"{\"method\":\"nn_tests\",\"ipaddr\":\"%s\"}",pushaddr); + n = /LP_send(sock,msg,(int32_t)strlen(msg)+1,0); + sleep(3); + LP_pullsock_check(ctx,&retstr,"127.0.0.1",-1,pullsock,0.); + sprintf(msg,"{\"method\":\"nn_tests2\",\"ipaddr\":\"%s\"}",pushaddr); + m = /LP_send(pullsock,msg,(int32_t)strlen(msg)+1,0); + printf(">>>>>>>>>>>>>>>>>>>>>> sent %d+%d bytes -> pullsock.%d retstr.(%s)\n",n,m,pullsock,retstr!=0?retstr:""); + if ( retstr != 0 ) + { + free(retstr); + retval = 0; + } + } + nn_close(sock); + } + return(retval); + }*/ + +int32_t basilisk_swap_load(uint32_t requestid,uint32_t quoteid,bits256 *privkeyp,struct basilisk_request *rp,uint32_t *statebitsp,int32_t *optiondurationp) +{ + FILE *fp=0; char fname[512]; int32_t retval = -1; + sprintf(fname,"%s/SWAPS/%u-%u",GLOBAL_DBDIR,requestid,quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb+")) != 0 ) + { + if ( fread(privkeyp,1,sizeof(*privkeyp),fp) == sizeof(*privkeyp) && + fread(rp,1,sizeof(*rp),fp) == sizeof(*rp) && + fread(statebitsp,1,sizeof(*statebitsp),fp) == sizeof(*statebitsp) && + fread(optiondurationp,1,sizeof(*optiondurationp),fp) == sizeof(*optiondurationp) ) + retval = 0; + fclose(fp); + } + return(retval); +} + +void basilisk_swap_saveupdate(struct basilisk_swap *swap) +{ + FILE *fp; char fname[512]; + sprintf(fname,"%s/SWAPS/%u-%u.swap",GLOBAL_DBDIR,swap->I.req.requestid,swap->I.req.quoteid), OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(&swap->I,1,sizeof(swap->I),fp); + /*fwrite(&swap->bobdeposit,1,sizeof(swap->bobdeposit),fp); + fwrite(&swap->bobpayment,1,sizeof(swap->bobpayment),fp); + fwrite(&swap->alicepayment,1,sizeof(swap->alicepayment),fp); + fwrite(&swap->myfee,1,sizeof(swap->myfee),fp); + fwrite(&swap->otherfee,1,sizeof(swap->otherfee),fp); + fwrite(&swap->aliceclaim,1,sizeof(swap->aliceclaim),fp); + fwrite(&swap->alicespend,1,sizeof(swap->alicespend),fp); + fwrite(&swap->bobreclaim,1,sizeof(swap->bobreclaim),fp); + fwrite(&swap->bobspend,1,sizeof(swap->bobspend),fp); + fwrite(&swap->bobrefund,1,sizeof(swap->bobrefund),fp); + fwrite(&swap->alicereclaim,1,sizeof(swap->alicereclaim),fp);*/ + fwrite(swap->privkeys,1,sizeof(swap->privkeys),fp); + fwrite(swap->otherdeck,1,sizeof(swap->otherdeck),fp); + fwrite(swap->deck,1,sizeof(swap->deck),fp); + fclose(fp); + } +} + +void basilisk_swap_sendabort(struct basilisk_swap *swap) +{ + uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0; + memset(buf,0,sizeof(buf)); + offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); + if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset ) + { + if ( sentbytes < 0 ) + { + if ( swap->pushsock >= 0 ) // + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) // + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; + } + } else printf("basilisk_swap_sendabort\n"); +} + +void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp); + +void basilisk_swapgotdata(struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit) +{ + int32_t i; struct basilisk_swapmessage *mp; + for (i=0; inummessages; i++) + if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 ) + return; + //printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data); + swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1)); + mp = &swap->messages[swap->nummessages++]; + mp->crc32 = crc32; + mp->srchash = srchash; + mp->desthash = desthash; + mp->msgbits = msgbits; + mp->quoteid = quoteid; + mp->data = malloc(datalen); + mp->datalen = datalen; + memcpy(mp->data,data,datalen); + if ( reinit == 0 && swap->fp != 0 ) + { + fwrite(mp,1,sizeof(*mp),swap->fp); + fwrite(data,1,datalen,swap->fp); + fflush(swap->fp); + } +} + +int32_t basilisk_swapget(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(void *ptr,uint8_t *data,int32_t datalen)) +{ + uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0; + while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,NN_DONTWAIT)) >= 0 ) + { + swap->lasttime = (uint32_t)time(NULL); + memset(srchash.bytes,0,sizeof(srchash)); + memset(desthash.bytes,0,sizeof(desthash)); + //printf("gotmsg.[%d] crc.%x\n",size,crc32); + offset = 0; + for (i=0; i<32; i++) + srchash.bytes[i] = ptr[offset++]; + for (i=0; i<32; i++) + desthash.bytes[i] = ptr[offset++]; + offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),"eid); + offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits); + if ( size > offset ) + { + crc32 = calc_crc32(0,&ptr[offset],size-offset); + if ( size > offset ) + { + //printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset); + basilisk_swapgotdata(swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0); + } + } + else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 ) + { + if ( swap->aborted == 0 ) + { + swap->aborted = (uint32_t)time(NULL); + printf("got abort signal from other side\n"); + } + } else printf("basilisk_swapget: got strange packet\n"); + if ( ptr != 0 ) + nn_freemsg(ptr), ptr = 0; + } + //char str[65],str2[65]; + for (i=0; inummessages; i++) + { + //printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash)); + if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 ) + { + if ( swap->messages[i].msgbits == msgbits ) + { + if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 ) + { + printf("nothing received for a while from Bob, try new sockets\n"); + if ( swap->pushsock >= 0 ) // + nn_close(swap->pushsock), swap->pushsock = -1; + if ( swap->subsock >= 0 ) // + nn_close(swap->subsock), swap->subsock = -1; + swap->connected = 0; + basilisk_psockinit(swap,swap->I.iambob != 0); + } + mp = &swap->messages[i]; + if ( msgbits != 0x80000000 ) + break; + } + } + } + if ( mp != 0 ) + retval = (*basilisk_verify_func)(swap,mp->data,mp->datalen); + //printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash)); + return(retval); +} + +int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp) +{ + int32_t keylen = 0; + keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),channelp); + keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),msgidp); + keylen += iguana_rwbignum(0,&key[keylen],sizeof(*srchashp),srchashp->bytes); + keylen += iguana_rwbignum(0,&key[keylen],sizeof(*desthashp),desthashp->bytes); + return(keylen); +} + +int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash) +{ + int32_t keylen = 0; + keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel); + keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid); + keylen += iguana_rwbignum(1,&key[keylen],sizeof(srchash),srchash.bytes); + keylen += iguana_rwbignum(1,&key[keylen],sizeof(desthash),desthash.bytes); + return(keylen); +} + +void LP_channelsend(bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen) +{ + int32_t keylen; uint8_t key[BASILISK_KEYSIZE]; //char *retstr; + keylen = basilisk_messagekey(key,channel,msgid,srchash,desthash); + //if ( (retstr= _dex_reqsend(myinfo,"DEX",key,keylen,data,datalen)) != 0 ) + // free(retstr); +} + + +#ifdef adfafds +void iguana_ensure_privkey(struct iguana_info *coin,bits256 privkey) +{ + uint8_t pubkey33[33]; struct iguana_waccount *wacct; struct iguana_waddress *waddr,addr; char coinaddr[128]; + bitcoin_pubkey33(swap->ctx,pubkey33,privkey); + bitcoin_address(coinaddr,coin->pubtype,pubkey33,33); + //printf("privkey for (%s)\n",coinaddr); + if ( myinfo->expiration != 0 && ((waddr= iguana_waddresssearch(&wacct,coinaddr)) == 0 || bits256_nonz(waddr->privkey) == 0) ) + { + if ( waddr == 0 ) + { + memset(&addr,0,sizeof(addr)); + iguana_waddresscalc(coin->pubtype,coin->wiftype,&addr,privkey); + if ( (wacct= iguana_waccountfind("default")) != 0 ) + waddr = iguana_waddressadd(coin,wacct,&addr,0); + } + if ( waddr != 0 ) + { + waddr->privkey = privkey; + if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->wiftype) > 0 ) + { + if ( (0) && waddr->wiftype != coin->wiftype ) + printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->wiftype); + if ( (0) && waddr->addrtype != coin->pubtype ) + printf("ensurepriv warning: mismatched addrtype %02x != %02x\n",waddr->addrtype,coin->pubtype); + } + } + } +} + + +int32_t basilisk_rawtx_return(struct basilisk_rawtx *rawtx,cJSON *item,int32_t lockinputs,struct vin_info *V) +{ + char *signedtx,*txbytes; cJSON *vins,*privkeyarray; int32_t i,n,retval = -1; + if ( (txbytes= jstr(item,"rawtx")) != 0 && (vins= jobj(item,"vins")) != 0 ) + { + privkeyarray = cJSON_CreateArray(); + jaddistr(privkeyarray,wifstr); + if ( (signedtx= LP_signrawtx(rawtx->coin->symbol,&rawtx->I.signedtxid,&rawtx->I.completed,vins,txbytes,privkeyarray,V)) != 0 ) + { + if ( lockinputs != 0 ) + { + //printf("lockinputs\n"); + LP_unspentslock(rawtx->coin->symbol,vins); + if ( (n= cJSON_GetArraySize(vins)) != 0 ) + { + bits256 txid; int32_t vout; + for (i=0; iI.datalen = (int32_t)strlen(signedtx) >> 1; + //rawtx->txbytes = calloc(1,rawtx->I.datalen); + decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); + //printf("%s SIGNEDTX.(%s)\n",rawtx->name,signedtx); + free(signedtx); + retval = 0; + } else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll + free_json(privkeyarray); + } + return(retval); +} +#endif + +cJSON *LP_createvins(struct basilisk_rawtx *dest,struct vin_info *V,struct basilisk_rawtx *rawtx,uint8_t *userdata,int32_t userdatalen,uint32_t sequenceid) +{ + cJSON *vins,*item,*sobj; char hexstr[8192]; + vins = cJSON_CreateArray(); + item = cJSON_CreateObject(); + if ( userdata != 0 && userdatalen > 0 ) + { + memcpy(V[0].userdata,userdata,userdatalen); + V[0].userdatalen = userdatalen; + init_hexbytes_noT(hexstr,userdata,userdatalen); + jaddstr(item,"userdata",hexstr); +#ifdef DISABLE_CHECKSIG + needsig = 0; +#endif + } + //printf("rawtx B\n"); + if ( bits256_nonz(rawtx->I.actualtxid) != 0 ) + jaddbits256(item,"txid",rawtx->I.actualtxid); + else jaddbits256(item,"txid",rawtx->I.signedtxid); + jaddnum(item,"vout",0); + //sobj = cJSON_CreateObject(); + init_hexbytes_noT(hexstr,rawtx->spendscript,rawtx->I.spendlen); + //jaddstr(sobj,"hex",hexstr); + //jadd(item,"scriptPubKey",sobj); + jaddstr(item,"scriptPubKey",hexstr); + jaddnum(item,"suppress",dest->I.suppress_pubkeys); + jaddnum(item,"sequence",sequenceid); + if ( (dest->I.redeemlen= rawtx->I.redeemlen) != 0 ) + { + init_hexbytes_noT(hexstr,rawtx->redeemscript,rawtx->I.redeemlen); + memcpy(dest->redeemscript,rawtx->redeemscript,rawtx->I.redeemlen); + jaddstr(item,"redeemScript",hexstr); + } + jaddi(vins,item); + return(vins); +} + +int32_t _basilisk_rawtx_gen(char *str,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay,bits256 privkey) +{ + char scriptstr[1024],wifstr[256],coinaddr[64],*signedtx,*rawtxbytes; uint32_t basilisktag; int32_t retval = -1; cJSON *vins,*privkeys,*addresses,*valsobj; struct vin_info *V; + init_hexbytes_noT(scriptstr,script,scriptlen); + basilisktag = (uint32_t)LP_rand(); + valsobj = cJSON_CreateObject(); + jaddstr(valsobj,"coin",rawtx->coin->symbol); + jaddstr(valsobj,"spendscript",scriptstr); + jaddstr(valsobj,"changeaddr",rawtx->coin->smartaddr); + jadd64bits(valsobj,"satoshis",rawtx->I.amount); + if ( strcmp(rawtx->coin->symbol,"BTC") == 0 && txfee > 0 && txfee < 50000 ) + txfee = 50000; + jadd64bits(valsobj,"txfee",txfee); + jaddnum(valsobj,"minconf",minconf); + if ( locktime == 0 ) + locktime = (uint32_t)time(NULL) - 777; + jaddnum(valsobj,"locktime",locktime); + jaddnum(valsobj,"timeout",30000); + jaddnum(valsobj,"timestamp",swapstarted+delay); + addresses = cJSON_CreateArray(); + bitcoin_address(coinaddr,rawtx->coin->pubtype,pubkey33,33); + jaddistr(addresses,coinaddr); + jadd(valsobj,"addresses",addresses); + rawtx->I.locktime = locktime; + printf("%s locktime.%u\n",rawtx->name,locktime); + V = calloc(256,sizeof(*V)); + privkeys = cJSON_CreateArray(); + bitcoin_priv2wif(wifstr,privkey,rawtx->coin->wiftype); + jaddistr(privkeys,wifstr); + vins = LP_createvins(rawtx,V,rawtx,0,0,0xffffffff); + rawtx->vins = jduplicate(vins); + jdelete(valsobj,"vin"); + jadd(valsobj,"vin",vins); + if ( (rawtxbytes= bitcoin_json2hex(rawtx->coin->isPoS,&rawtx->I.txid,valsobj,V)) != 0 ) + { + //printf("rawtx.(%s) vins.%p\n",rawtxbytes,vins); + if ( (signedtx= LP_signrawtx(rawtx->coin->symbol,&rawtx->I.signedtxid,&rawtx->I.completed,vins,rawtxbytes,privkeys,V)) != 0 ) + { + rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1; + if ( rawtx->I.datalen <= sizeof(rawtx->txbytes) ) + decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); + else printf("DEX tx is too big %d vs %d\n",rawtx->I.datalen,(int32_t)sizeof(rawtx->txbytes)); + if ( signedtx != rawtxbytes ) + free(signedtx); + if ( rawtx->I.completed != 0 ) + retval = 0; + else printf("couldnt complete sign transaction %s\n",rawtx->name); + } else printf("error signing\n"); + free(rawtxbytes); + } else printf("error making rawtx\n"); + free_json(privkeys); + free_json(valsobj); + free(V); + return(retval); +} + +int32_t _basilisk_rawtx_sign(char *symbol,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,struct basilisk_swap *swap,uint32_t timestamp,uint32_t locktime,uint32_t sequenceid,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr) +{ + char *rawtxbytes=0,*signedtx=0,wifstr[128]; cJSON *txobj,*vins,*privkeys; int32_t needsig=1,retval = -1; struct vin_info *V; + V = calloc(256,sizeof(*V)); + V[0].signers[0].privkey = privkey; + bitcoin_pubkey33(swap->ctx,V[0].signers[0].pubkey,privkey); + privkeys = cJSON_CreateArray(); + bitcoin_priv2wif(wifstr,privkey,wiftype); + jaddistr(privkeys,wifstr); + if ( privkey2 != 0 ) + { + V[0].signers[1].privkey = *privkey2; + bitcoin_pubkey33(swap->ctx,V[0].signers[1].pubkey,*privkey2); + bitcoin_priv2wif(wifstr,*privkey2,wiftype); + jaddistr(privkeys,wifstr); + V[0].N = V[0].M = 2; + //char str[65]; printf("add second privkey.(%s) %s\n",jprint(privkeys,0),bits256_str(str,*privkey2)); + } else V[0].N = V[0].M = 1; + V[0].suppress_pubkeys = dest->I.suppress_pubkeys; + V[0].ignore_cltverr = ignore_cltverr; + if ( dest->I.redeemlen != 0 ) + memcpy(V[0].p2shscript,dest->redeemscript,dest->I.redeemlen), V[0].p2shlen = dest->I.redeemlen; + txobj = bitcoin_txcreate(symbol,isPoS,locktime,userdata == 0 ? 1 : 1,timestamp);//rawtx->coin->locktime_txversion); + vins = LP_createvins(dest,V,rawtx,userdata,userdatalen,sequenceid); + jdelete(txobj,"vin"); + jadd(txobj,"vin",vins); + //printf("basilisk_rawtx_sign locktime.%u/%u for %s spendscript.%s -> %s, suppress.%d\n",rawtx->I.locktime,dest->I.locktime,rawtx->name,hexstr,dest->name,dest->I.suppress_pubkeys); + txobj = bitcoin_txoutput(txobj,dest->spendscript,dest->I.spendlen,dest->I.amount); + if ( (rawtxbytes= bitcoin_json2hex(isPoS,&dest->I.txid,txobj,V)) != 0 ) + { + //printf("rawtx.(%s) vins.%p\n",rawtxbytes,vins); + if ( needsig == 0 ) + signedtx = rawtxbytes; + if ( signedtx != 0 || (signedtx= LP_signrawtx(symbol,&dest->I.signedtxid,&dest->I.completed,vins,rawtxbytes,privkeys,V)) != 0 ) + { + dest->I.datalen = (int32_t)strlen(signedtx) >> 1; + if ( dest->I.datalen <= sizeof(dest->txbytes) ) + decode_hex(dest->txbytes,dest->I.datalen,signedtx); + else printf("DEX tx is too big %d vs %d\n",dest->I.datalen,(int32_t)sizeof(dest->txbytes)); + if ( signedtx != rawtxbytes ) + free(signedtx); + if ( dest->I.completed != 0 ) + retval = 0; + else printf("couldnt complete sign transaction %s\n",rawtx->name); + } else printf("error signing\n"); + free(rawtxbytes); + } else printf("error making rawtx\n"); + free_json(privkeys); + free_json(txobj); + free(V); + return(retval); +} + +int32_t basilisk_process_swapverify(void *ptr,int32_t (*internal_func)(void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration) +{ + struct basilisk_swap *swap = ptr; + if ( internal_func != 0 ) + return((*internal_func)(swap,data,datalen)); + else return(0); +} + +int32_t basilisk_priviextract(struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout) +{ + /*bits256 txid; char str[65]; int32_t i,vini,scriptlen; uint8_t rmd160[20],scriptsig[IGUANA_MAXSCRIPTSIZE]; + memset(privkey.bytes,0,sizeof(privkey)); + // use dex_listtransactions! + if ( (vini= iguana_vinifind(coin,&txid,srctxid,srcvout)) >= 0 ) + { + if ( (scriptlen= iguana_scriptsigextract(coin,scriptsig,sizeof(scriptsig),txid,vini)) > 32 ) + { + for (i=0; i<32; i++) + privkey.bytes[i] = scriptsig[scriptlen - 33 + i]; + revcalc_rmd160_sha256(rmd160,privkey);//.bytes,sizeof(privkey)); + if ( memcmp(secret160,rmd160,sizeof(rmd160)) == sizeof(rmd160) ) + { + *destp = privkey; + printf("basilisk_priviextract found privi %s (%s)\n",name,bits256_str(str,privkey)); + return(0); + } + } + }*/ + return(-1); +} +int32_t basilisk_verify_privi(void *ptr,uint8_t *data,int32_t datalen); + +int32_t basilisk_privBn_extract(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + if ( basilisk_priviextract(&swap->bobcoin,"privBn",&swap->I.privBn,swap->I.secretBn,swap->bobrefund.I.actualtxid,0) == 0 ) + { + printf("extracted privBn from blockchain\n"); + } + else if ( basilisk_swapget(swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) + { + } + if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.I.datalen == 0 ) + { + char str[65]; printf("got privBn.%s\n",bits256_str(str,swap->I.privBn)); + return(basilisk_alicepayment_spend(swap,&swap->alicereclaim)); + } + return(-1); +} + +int32_t basilisk_privAm_extract(struct basilisk_swap *swap) +{ + if ( basilisk_priviextract(&swap->bobcoin,"privAm",&swap->I.privAm,swap->I.secretAm,swap->bobpayment.I.actualtxid,0) == 0 ) + { + printf("extracted privAm from blockchain\n"); + } + if ( bits256_nonz(swap->I.privAm) != 0 && swap->bobspend.I.datalen == 0 ) + { + char str[65]; printf("got privAm.%s\n",bits256_str(str,swap->I.privAm)); + return(basilisk_alicepayment_spend(swap,&swap->bobspend)); + } + return(-1); +} + +int32_t basilisk_verify_otherstatebits(void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t retval; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(swap->I.otherstatebits) ) + { + retval = iguana_rwnum(0,data,sizeof(swap->I.otherstatebits),&swap->I.otherstatebits); + return(retval); + } else return(-1); +} + +int32_t basilisk_verify_statebits(void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t retval = -1; uint32_t statebits; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(swap->I.statebits) ) + { + retval = iguana_rwnum(0,data,sizeof(swap->I.statebits),&statebits); + if ( statebits != swap->I.statebits ) + { + printf("statebits.%x != %x\n",statebits,swap->I.statebits); + return(-1); + } + } + return(retval); +} + +void basilisk_sendstate(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t datalen=0; + datalen = iguana_rwnum(1,data,sizeof(swap->I.statebits),&swap->I.statebits); + LP_swapsend(swap,0x80000000,data,datalen,0,0); +} + +int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t j,datalen,retval = 0; uint32_t savestatebits=0,saveotherbits=0; + if ( swap->I.iambob != 0 ) + swap->I.statebits |= 0x80; + while ( swap->aborted == 0 && ((swap->I.otherstatebits & 0x80) == 0 || (swap->I.statebits & 0x80) == 0) && retval == 0 && time(NULL) < swap->I.expiration ) + { + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + printf("D r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); + if ( swap->I.iambob != 0 && (swap->I.statebits & 0x80) == 0 ) // wait for fee + { + if ( basilisk_swapget(swap,0x80,data,maxlen,basilisk_verify_otherfee) == 0 ) + { + // verify and submit otherfee + swap->I.statebits |= 0x80; + basilisk_sendstate(swap,data,maxlen); + } + } + else if ( swap->I.iambob == 0 ) + swap->I.statebits |= 0x80; + basilisk_sendstate(swap,data,maxlen); + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + if ( (swap->I.otherstatebits & 0x80) != 0 && (swap->I.statebits & 0x80) != 0 ) + break; + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + basilisk_sendstate(swap,data,maxlen); + if ( (swap->I.otherstatebits & 0x80) == 0 ) + LP_swapdata_rawtxsend(swap,0x80,data,maxlen,&swap->myfee,0x40,0); + } + basilisk_swap_saveupdate(swap); + while ( swap->aborted == 0 && retval == 0 && time(NULL) < swap->I.expiration ) // both sides have setup required data and paid txfee + { + basilisk_swap_saveupdate(swap); + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + //if ( (LP_rand() % 30) == 0 ) + printf("E r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); + if ( swap->I.iambob != 0 ) + { + //printf("BOB\n"); + if ( (swap->I.statebits & 0x100) == 0 ) + { + printf("send bobdeposit\n"); + swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0); + } + // [BLOCKING: altfound] make sure altpayment is confirmed and send payment + else if ( (swap->I.statebits & 0x1000) == 0 ) + { + printf("check alicepayment\n"); + if ( basilisk_swapget(swap,0x1000,data,maxlen,basilisk_verify_alicepaid) == 0 ) + { + swap->I.statebits |= 0x1000; + printf("got alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); + } + } + else if ( (swap->I.statebits & 0x2000) == 0 ) + { + if ( (swap->I.aliceconfirms == 0 && swap->aliceunconf != 0) || LP_numconfirms(swap,&swap->alicepayment,1) >= swap->I.aliceconfirms ) + { + swap->I.statebits |= 0x2000; + printf("alicepayment confirmed\n"); + } + } + else if ( (swap->I.statebits & 0x4000) == 0 ) + { + basilisk_bobscripts_set(swap,0,1); + printf("send bobpayment\n"); + swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0); + } + // [BLOCKING: privM] Bob waits for privAm either from Alice or alice blockchain + else if ( (swap->I.statebits & 0xc0000) != 0xc0000 ) + { + if ( basilisk_swapget(swap,0x40000,data,maxlen,basilisk_verify_privi) == 0 || basilisk_privAm_extract(swap) == 0 ) // divulges privAm + { + //printf("got privi spend alicepayment, dont divulge privBn until bobspend propagated\n"); + basilisk_alicepayment_spend(swap,&swap->bobspend); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobspend,0x40000,1) == 0 ) + printf("Bob error spending alice payment\n"); + else + { + tradebot_swap_balancingtrade(swap,1); + printf("Bob spends alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); + swap->I.statebits |= 0x40000; + if ( LP_numconfirms(swap,&swap->bobspend,1) >= swap->I.aliceconfirms ) + { + printf("bobspend confirmed\n"); + swap->I.statebits |= 0x80000; + printf("Bob confirming spend of Alice's payment\n"); + sleep(DEX_SLEEP); + } + retval = 1; + } + } + } + if ( swap->bobpayment.I.locktime != 0 && time(NULL) > swap->bobpayment.I.locktime ) + { + // submit reclaim of payment + printf("bob reclaims bobpayment\n"); + swap->I.statebits |= (0x40000 | 0x80000); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobreclaim,0,0) == 0 ) + printf("Bob error reclaiming own payment after alice timed out\n"); + else + { + printf("Bob reclaimed own payment\n"); + while ( 0 && (swap->I.statebits & 0x100000) == 0 ) // why wait for own tx? + { + if ( LP_numconfirms(swap,&swap->bobreclaim,1) >= 1 ) + { + printf("bobreclaim confirmed\n"); + swap->I.statebits |= 0x100000; + printf("Bob confirms reclain of payment\n"); + break; + } + } + retval = 1; + } + } + } + else + { + //printf("ALICE\n"); + // [BLOCKING: depfound] Alice waits for deposit to confirm and sends altpayment + if ( (swap->I.statebits & 0x200) == 0 ) + { + printf("checkfor deposit\n"); + if ( basilisk_swapget(swap,0x200,data,maxlen,basilisk_verify_bobdeposit) == 0 ) + { + // verify deposit and submit, set confirmed height + printf("got bobdeposit\n"); + swap->I.statebits |= 0x200; + } else printf("no valid deposit\n"); + } + else if ( (swap->I.statebits & 0x400) == 0 ) + { + if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->depositunconf != 0) || LP_numconfirms(swap,&swap->bobdeposit,1) >= swap->I.bobconfirms ) + { + printf("bobdeposit confirmed\n"); + swap->I.statebits |= 0x400; + } + } + else if ( (swap->I.statebits & 0x800) == 0 ) + { + printf("send alicepayment\n"); + swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0); + } + // [BLOCKING: payfound] make sure payment is confrmed and send in spend or see bob's reclaim and claim + else if ( (swap->I.statebits & 0x8000) == 0 ) + { + if ( basilisk_swapget(swap,0x8000,data,maxlen,basilisk_verify_bobpaid) == 0 ) + { + printf("got bobpayment\n"); + tradebot_swap_balancingtrade(swap,0); + // verify payment and submit, set confirmed height + swap->I.statebits |= 0x8000; + } + } + else if ( (swap->I.statebits & 0x10000) == 0 ) + { + if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->paymentunconf != 0) || LP_numconfirms(swap,&swap->bobpayment,1) >= swap->I.bobconfirms ) + { + printf("bobpayment confirmed\n"); + swap->I.statebits |= 0x10000; + } + } + else if ( (swap->I.statebits & 0x20000) == 0 ) + { + printf("alicespend bobpayment\n"); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->alicespend,0x20000,0) != 0 )//&& (swap->aliceunconf != 0 || basilisk_numconfirms(swap,&swap->alicespend) > 0) ) + { + swap->I.statebits |= 0x20000; + } + } + else if ( (swap->I.statebits & 0x40000) == 0 ) + { + int32_t numconfs; + if ( (numconfs= LP_numconfirms(swap,&swap->alicespend,1)) >= swap->I.bobconfirms ) + { + for (j=datalen=0; j<32; j++) + data[datalen++] = swap->I.privAm.bytes[j]; + printf("send privAm %x\n",swap->I.statebits); + swap->I.statebits |= LP_swapsend(swap,0x40000,data,datalen,0x20000,swap->I.crcs_mypriv); + printf("Alice confirms spend of Bob's payment\n"); + retval = 1; + } else printf("alicespend numconfs.%d < %d\n",numconfs,swap->I.bobconfirms); + } + if ( swap->bobdeposit.I.locktime != 0 && time(NULL) > swap->bobdeposit.I.locktime ) + { + printf("Alice claims deposit\n"); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->aliceclaim,0,0) == 0 ) + printf("Alice couldnt claim deposit\n"); + else + { + printf("Alice claimed deposit\n"); + retval = 1; + } + } + else if ( swap->aborted != 0 || basilisk_privBn_extract(swap,data,maxlen) == 0 ) + { + printf("Alice reclaims her payment\n"); + swap->I.statebits |= 0x40000000; + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->alicereclaim,0x40000000,0) == 0 ) + printf("Alice error sending alicereclaim\n"); + else + { + printf("Alice reclaimed her payment\n"); + retval = 1; + } + } + } + if ( (LP_rand() % 30) == 0 ) + printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits); + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + basilisk_sendstate(swap,data,maxlen); + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + } + return(retval); +} + +int32_t swapcompleted(struct basilisk_swap *swap) +{ + if ( swap->I.iambob != 0 ) + return(swap->I.bobspent); + else return(swap->I.alicespent); +} + +cJSON *swapjson(struct basilisk_swap *swap) +{ + cJSON *retjson = cJSON_CreateObject(); + return(retjson); +} + +int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp) +{ + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->requestid),&rp->requestid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->timestamp),&rp->timestamp); // must be 2nd + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quoteid),&rp->quoteid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quotetime),&rp->quotetime); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->optionhours),&rp->optionhours); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->srcamount),&rp->srcamount); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->unused),&rp->unused); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->srchash),rp->srchash.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->desthash),rp->desthash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->destamount),&rp->destamount); + if ( rwflag != 0 ) + { + memcpy(&serialized[len],rp->src,sizeof(rp->src)), len += sizeof(rp->src); + memcpy(&serialized[len],rp->dest,sizeof(rp->dest)), len += sizeof(rp->dest); + } + else + { + memcpy(rp->src,&serialized[len],sizeof(rp->src)), len += sizeof(rp->src); + memcpy(rp->dest,&serialized[len],sizeof(rp->dest)), len += sizeof(rp->dest); + } + //len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->DEXselector),&rp->DEXselector); + //len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->extraspace),&rp->extraspace); + if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) + printf(" basilisk_rwDEXquote.%d: quoteid.%u mismatch calc %u rp.%p\n",rwflag,rp->quoteid,basilisk_quoteid(rp),rp); + if ( basilisk_requestid(rp) != rp->requestid ) + printf(" basilisk_rwDEXquote.%d: requestid.%u mismatch calc %u rp.%p\n",rwflag,rp->requestid,basilisk_requestid(rp),rp); + return(len); +} + +struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson) +{ + uint32_t requestid,quoteid; + memset(rp,0,sizeof(*rp)); + rp->srchash = jbits256(reqjson,"srchash"); + rp->desthash = jbits256(reqjson,"desthash"); + rp->srcamount = j64bits(reqjson,"srcamount"); + //rp->minamount = j64bits(reqjson,"minamount"); + //rp->destamount = j64bits(reqjson,"destamount"); + rp->destamount = j64bits(reqjson,"destsatoshis"); + //printf("parse DESTSATOSHIS.%llu (%s)\n",(long long)rp->destamount,jprint(reqjson,0)); + requestid = juint(reqjson,"requestid"); + quoteid = juint(reqjson,"quoteid"); + //if ( jstr(reqjson,"relay") != 0 ) + // rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay")); + rp->timestamp = juint(reqjson,"timestamp"); + rp->quotetime = juint(reqjson,"quotetime"); + safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src)); + safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest)); + if ( quoteid != 0 ) + { + rp->quoteid = basilisk_quoteid(rp); + if ( quoteid != rp->quoteid ) + printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid); + } + rp->requestid = basilisk_requestid(rp); + if ( requestid != rp->requestid ) + { + int32_t i; for (i=0; irequestid); + } + return(rp); +} + +cJSON *basilisk_requestjson(struct basilisk_request *rp) +{ + cJSON *item = cJSON_CreateObject(); + /*if ( rp->relaybits != 0 ) + { + expand_ipbits(ipaddr,rp->relaybits); + jaddstr(item,"relay",ipaddr); + }*/ + jaddbits256(item,"srchash",rp->srchash); + if ( bits256_nonz(rp->desthash) != 0 ) + jaddbits256(item,"desthash",rp->desthash); + jaddstr(item,"src",rp->src); + if ( rp->srcamount != 0 ) + jadd64bits(item,"srcamount",rp->srcamount); + //if ( rp->minamount != 0 ) + // jadd64bits(item,"minamount",rp->minamount); + jaddstr(item,"dest",rp->dest); + if ( rp->destamount != 0 ) + { + //jadd64bits(item,"destamount",rp->destamount); + jadd64bits(item,"destsatoshis",rp->destamount); + //printf("DESTSATOSHIS.%llu\n",(long long)rp->destamount); + } + jaddnum(item,"quotetime",rp->quotetime); + jaddnum(item,"timestamp",rp->timestamp); + jaddnum(item,"requestid",rp->requestid); + jaddnum(item,"quoteid",rp->quoteid); + //jaddnum(item,"DEXselector",rp->DEXselector); + jaddnum(item,"optionhours",rp->optionhours); + //jaddnum(item,"profit",(double)rp->profitmargin / 1000000.); + if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) + printf("quoteid mismatch %u vs %u\n",basilisk_quoteid(rp),rp->quoteid); + if ( basilisk_requestid(rp) != rp->requestid ) + printf("requestid mismatch %u vs calc %u\n",rp->requestid,basilisk_requestid(rp)); + { + int32_t i; struct basilisk_request R; + if ( basilisk_parsejson(&R,item) != 0 ) + { + if ( memcmp(&R,rp,sizeof(*rp)-sizeof(uint32_t)) != 0 ) + { + for (i=0; iI.req.requestid); + jaddnum(item,"quoteid",swap->I.req.quoteid); + jaddnum(item,"state",swap->I.statebits); + jaddnum(item,"otherstate",swap->I.otherstatebits); + jadd(item,"request",basilisk_requestjson(&swap->I.req)); + return(item); +} + +#ifdef later + +cJSON *basilisk_privkeyarray(struct iguana_info *coin,cJSON *vins) +{ + cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],typestr[64],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid,privkey; double bidasks[2]; + privkeyarray = cJSON_CreateArray(); + if ( (n= cJSON_GetArraySize(vins)) > 0 ) + { + for (i=0; i= 0 ) + { + iguana_txidcategory(coin,account,coinaddr,txid,vout); + if ( coinaddr[0] == 0 && (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 ) + { + len = (int32_t)strlen(hexstr) >> 1; + if ( len < (sizeof(script) << 1) ) + { + decode_hex(script,len,hexstr); + if ( len == 25 && script[0] == 0x76 && script[1] == 0xa9 && script[2] == 0x14 ) + bitcoin_address(coinaddr,coin->chain->pubtype,script+3,20); + } + } + if ( coinaddr[0] != 0 ) + { + if ( (waddr= iguana_waddresssearch(&wacct,coinaddr)) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype); + jaddistr(privkeyarray,waddr->wifstr); + } + else if ( smartaddress(typestr,bidasks,&privkey,coin->symbol,coinaddr) >= 0 ) + { + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + jaddistr(privkeyarray,wifstr); + } + else printf("cant find (%s) in wallet\n",coinaddr); + } else printf("cant coinaddr from (%s).v%d\n",bits256_str(str,txid),vout); + } else printf("invalid txid/vout %d of %d\n",i,n); + } + } + return(privkeyarray); +} + + +#endif + + +#ifdef old +void basilisk_swaploop(void *_utxo) +{ + uint8_t *data; uint32_t expiration,savestatebits=0,saveotherbits=0; uint32_t channel; int32_t iters,retval=0,j,datalen,maxlen; struct basilisk_swap *swap; struct LP_utxoinfo *utxo = _utxo; + swap = utxo->swap; + //fprintf(stderr,"start swap iambob.%d\n",swap->I.iambob); + maxlen = 1024*1024 + sizeof(*swap); + data = malloc(maxlen); + expiration = (uint32_t)time(NULL) + 300; + //myinfo->DEXactive = expiration; + channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + while ( swap->aborted == 0 && (swap->I.statebits & (0x08|0x02)) != (0x08|0x02) && time(NULL) < expiration ) + { + LP_channelsend(swap->I.req.srchash,swap->I.req.desthash,channel,0x4000000,(void *)&swap->I.req.requestid,sizeof(swap->I.req.requestid)); //,60); + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + if ( swap->connected > 0 ) + { + printf("A r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); + basilisk_sendstate(swap,data,maxlen); + basilisk_sendpubkeys(swap,data,maxlen); // send pubkeys + if ( basilisk_checkdeck(swap,data,maxlen) == 0) // check for other deck 0x02 + basilisk_sendchoosei(swap,data,maxlen); + basilisk_waitchoosei(swap,data,maxlen); // wait for choosei 0x08 + if ( (swap->I.statebits & (0x08|0x02)) == (0x08|0x02) ) + break; + } + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + } + if ( swap->connected == 0 ) + { + printf("couldnt establish connection\n"); + retval = -1; + } + while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x20) == 0 ) + { + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + printf("B r%u/q%u swapstate.%x\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits); + basilisk_sendstate(swap,data,maxlen); + basilisk_sendchoosei(swap,data,maxlen); + basilisk_sendmostprivs(swap,data,maxlen); + if ( basilisk_swapget(swap,0x20,data,maxlen,basilisk_verify_privkeys) == 0 ) + { + swap->I.statebits |= 0x20; + break; + } + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + if ( time(NULL) > expiration ) + break; + } + //myinfo->DEXactive = swap->I.expiration; + if ( time(NULL) >= expiration ) + { + retval = -1; + //myinfo->DEXactive = 0; + } + if ( swap->aborted != 0 ) + { + printf("swap aborted before tx sent\n"); + retval = -1; + } + printf("C r%u/q%u swapstate.%x retval.%d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,retval); + iters = 0; + while ( swap->aborted == 0 && retval == 0 && (swap->I.statebits & 0x40) == 0 && iters++ < 10 ) // send fee + { + if ( swap->connected == 0 ) + basilisk_psockinit(swap,swap->I.iambob != 0); + //printf("sendstate.%x\n",swap->I.statebits); + basilisk_sendstate(swap,data,maxlen); + //printf("swapget\n"); + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + //printf("after swapget\n"); + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) + { + printf("bobscripts set\n"); + if ( basilisk_bobscripts_set(swap,1,1) < 0 ) + { + sleep(DEX_SLEEP); + printf("bobscripts set error\n"); + continue; + } + } + if ( swap->I.iambob == 0 ) + { + /*for (i=0; i<20; i++) + printf("%02x",swap->secretAm[i]); + printf(" <- secretAm\n"); + for (i=0; i<32; i++) + printf("%02x",swap->secretAm256[i]); + printf(" <- secretAm256\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubAm.bytes[i]); + printf(" <- pubAm\n"); + for (i=0; i<20; i++) + printf("%02x",swap->secretBn[i]); + printf(" <- secretBn\n"); + for (i=0; i<32; i++) + printf("%02x",swap->secretBn256[i]); + printf(" <- secretBn256\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubBn.bytes[i]); + printf(" <- pubBn\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubA0.bytes[i]); + printf(" <- pubA0\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubA1.bytes[i]); + printf(" <- pubA1\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubB0.bytes[i]); + printf(" <- pubB0\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubB1.bytes[i]); + printf(" <- pubB1\n");*/ + if ( (retval= basilisk_alicetxs(swap,data,maxlen)) != 0 ) + { + printf("basilisk_alicetxs error\n"); + break; + } + } + } + if ( swap->I.iambob == 0 && (swap->I.statebits & 0x40) == 0 ) + { + printf("couldnt send fee\n"); + retval = -8; + } + if ( retval == 0 ) + { + if ( swap->I.iambob == 0 && (swap->myfee.I.datalen == 0 || swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.datalen == 0) ) + { + printf("ALICE's error %d %d %d\n",swap->myfee.I.datalen,swap->alicepayment.I.datalen,swap->alicepayment.I.datalen); + retval = -7; + } + else if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen == 0 ) //swap->bobpayment.I.datalen == 0 + { + printf("BOB's error %d %d %d\n",swap->myfee.I.datalen,swap->bobpayment.I.datalen,swap->bobdeposit.I.datalen); + retval = -7; + } + } + while ( swap->aborted == 0 && retval == 0 && basilisk_swapiteration(swap,data,maxlen) == 0 ) + { + if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) + sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); + savestatebits = swap->I.statebits; + saveotherbits = swap->I.otherstatebits; + basilisk_sendstate(swap,data,maxlen); + basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + basilisk_swap_saveupdate(swap); + if ( time(NULL) > swap->I.expiration ) + break; + } + if ( swap->I.iambob != 0 && swap->bobdeposit.I.datalen != 0 && bits256_nonz(swap->bobdeposit.I.actualtxid) != 0 ) + { + printf("BOB waiting for confirm state.%x\n",swap->I.statebits); + sleep(60); // wait for confirm/propagation of msig + printf("BOB reclaims refund\n"); + basilisk_bobdeposit_refund(swap,0); + if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobrefund,0x40000000,0) == 0 ) // use secretBn + { + printf("Bob submit error getting refund of deposit\n"); + } + else + { + // maybe wait for bobrefund to be confirmed + for (j=datalen=0; j<32; j++) + data[datalen++] = swap->I.privBn.bytes[j]; + LP_swapsend(swap,0x40000000,data,datalen,0x40000000,swap->I.crcs_mypriv); + } + basilisk_swap_saveupdate(swap); + } + if ( retval != 0 ) + basilisk_swap_sendabort(swap); + printf("end of atomic swap\n"); + if ( swapcompleted(swap) > 0 ) // only if swap completed + { + if ( swap->I.iambob != 0 ) + tradebot_pendingadd(swapjson(swap),swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount)); + else tradebot_pendingadd(swapjson(swap),swap->I.req.dest,dstr(swap->I.req.destamount),swap->I.req.src,dstr(swap->I.req.srcamount)); + } + printf("%s swap finished statebits %x\n",swap->I.iambob!=0?"BOB":"ALICE",swap->I.statebits); + basilisk_swap_purge(swap); + free(data); +} +#endif + +int32_t bitcoin_coinptrs(bits256 pubkey,struct iguana_info **bobcoinp,struct iguana_info **alicecoinp,char *src,char *dest,bits256 srchash,bits256 desthash) +{ + struct iguana_info *coin = LP_coinfind(src); + if ( coin == 0 || LP_coinfind(dest) == 0 ) + return(0); + *bobcoinp = *alicecoinp = 0; + *bobcoinp = LP_coinfind(dest); + *alicecoinp = LP_coinfind(src); + if ( bits256_cmp(pubkey,srchash) == 0 ) + { + if ( strcmp(src,(*bobcoinp)->symbol) == 0 ) + return(1); + else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 ) + return(-1); + else return(0); + } + else if ( bits256_cmp(pubkey,desthash) == 0 ) + { + if ( strcmp(src,(*bobcoinp)->symbol) == 0 ) + return(-1); + else if ( strcmp(dest,(*alicecoinp)->symbol) == 0 ) + return(1); + else return(0); + } + return(0); +} + +struct LP_utxoinfo *LP_utxopairfind(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; struct _LP_utxoinfo u; + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 ) + { + u = (iambob != 0) ? utxo->deposit : utxo->fee; + if (vout2 == u.vout && bits256_cmp(u.txid,txid2) == 0 ) + return(utxo); + } + return(0); +} + +void LP_utxosetkey(uint8_t *key,bits256 txid,int32_t vout) +{ + memcpy(key,txid.bytes,sizeof(txid)); + memcpy(&key[sizeof(txid)],&vout,sizeof(vout)); +} + +struct LP_utxoinfo *_LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo=0; uint8_t key[sizeof(txid) + sizeof(vout)]; + LP_utxosetkey(key,txid,vout); + HASH_FIND(hh,G.LP_utxoinfos[iambob!=0],key,sizeof(key),utxo); + return(utxo); +} + +void _LP_utxo_delete(int32_t iambob,struct LP_utxoinfo *utxo) +{ + HASH_DELETE(hh,G.LP_utxoinfos[iambob],utxo); +} + +void _LP_utxo2_delete(int32_t iambob,struct LP_utxoinfo *utxo) +{ + HASH_DELETE(hh,G.LP_utxoinfos2[iambob],utxo); +} + +struct LP_utxoinfo *_LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; uint8_t key2[sizeof(txid2) + sizeof(vout2)]; + LP_utxosetkey(key2,txid2,vout2); + HASH_FIND(hh2,G.LP_utxoinfos2[iambob],key2,sizeof(key2),utxo); + return(utxo); +} + +struct LP_utxoinfo *LP_utxofind(int32_t iambob,bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo=0; + /*if ( iambob != 0 ) + { + printf("LP_utxofind deprecated iambob\n"); + return(0); + }*/ + portable_mutex_lock(&LP_utxomutex); + utxo = _LP_utxofind(iambob,txid,vout); + portable_mutex_unlock(&LP_utxomutex); + return(utxo); +} + +struct LP_utxoinfo *LP_utxo2find(int32_t iambob,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo=0; + /*if ( iambob != 0 ) + { + printf("LP_utxo2find deprecated iambob\n"); + return(0); + }*/ + portable_mutex_lock(&LP_utxomutex); + utxo = _LP_utxo2find(iambob,txid2,vout2); + portable_mutex_unlock(&LP_utxomutex); + return(utxo); +} + +/*void LP_privkeysloop(void *ctx) + { + strcpy(LP_privkeysloop_stats.name,"LP_privkeysloop"); + LP_privkeysloop_stats.threshold = (LP_ORDERBOOK_DURATION * .8 * 1000) + 10000; + sleep(20); + while ( 1 ) + { + LP_millistats_update(&LP_privkeysloop_stats); + //printf("LP_privkeysloop %u\n",LP_counter); + LP_privkey_updates(ctx,LP_mypubsock,0); + sleep(LP_ORDERBOOK_DURATION * .777); + } + }*/ +/*void basilisk_swap_purge(struct basilisk_swap *swap) + { + int32_t i,n; + // while still in orderbook, wait + //return; + portable_mutex_lock(&myinfo->DEX_swapmutex); + n = myinfo->numswaps; + for (i=0; iswaps[i] == swap ) + { + myinfo->swaps[i] = myinfo->swaps[--myinfo->numswaps]; + myinfo->swaps[myinfo->numswaps] = 0; + basilisk_swap_finished(swap); + break; + } + portable_mutex_unlock(&myinfo->DEX_swapmutex); + }*/ +/*if ( bits256_nonz(Q.srchash) == 0 || bits256_cmp(Q.srchash,G.LP_mypub25519) == 0 || strcmp(butxo->coinaddr,coin->smartaddr) != 0 || bits256_nonz(butxo->payment.txid) == 0 || bits256_nonz(butxo->deposit.txid) == 0 ) + { + qprice = (double)Q.destsatoshis / Q.satoshis; + strcpy(Q.gui,G.gui); + strcpy(Q.coinaddr,coin->smartaddr); + strcpy(butxo->coinaddr,coin->smartaddr); + Q.srchash = G.LP_mypub25519; + memset(&Q.txid,0,sizeof(Q.txid)); + memset(&Q.txid2,0,sizeof(Q.txid2)); + Q.vout = Q.vout2 = -1; + recalc = 1; + } + else if ( (qprice= LP_quote_validate(autxo,butxo,&Q,1)) < SMALLVAL ) + recalc = 1; + else if ( price < qprice ) + { + char tmp[64]; + if ( bits256_nonz(Q.txid) != 0 ) + LP_utxos_remove(Q.txid,Q.vout); + else recalc = 1; + if ( bits256_nonz(Q.txid2) != 0 ) + LP_utxos_remove(Q.txid2,Q.vout2); + else recalc = 1; + //printf("price %.8f qprice %.8f\n",price,qprice); + if ( recalc == 0 ) + { + value = LP_txvalue(tmp,Q.srccoin,Q.txid,Q.vout); + value2 = LP_txvalue(tmp,Q.srccoin,Q.txid2,Q.vout2); + //printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2)); + if ( (butxo= LP_utxoadd(1,coin->symbol,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,G.gui,0,Q.satoshis)) == 0 ) + recalc = 1; + else if ( bits256_cmp(Q.txid,butxo->payment.txid) != 0 || Q.vout != butxo->payment.vout || bits256_cmp(Q.txid2,butxo->deposit.txid) != 0 || Q.vout2 != butxo->deposit.vout ) + recalc = 1; + } + } else return(retval);*/ + +int32_t LP_isavailable(struct LP_utxoinfo *utxo) +{ + struct _LP_utxoinfo u; + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( LP_allocated(utxo->payment.txid,utxo->payment.vout) == 0 && LP_allocated(u.txid,u.vout) == 0 ) + return(1); + else return(0); +} +/*int32_t LP_priceping(int32_t pubsock,struct LP_utxoinfo *utxo,char *rel,double origprice) + { + double price,bid,ask; uint32_t now; cJSON *retjson; struct LP_quoteinfo Q; char *retstr; + if ( (now= (uint32_t)time(NULL)) > utxo->T.swappending && utxo->S.swap == 0 ) + utxo->T.swappending = 0; + if ( now > utxo->T.published+60 && LP_isavailable(utxo) && (price= LP_myprice(&bid,&ask,utxo->coin,rel)) != 0. ) + { + if ( origprice < price ) + price = origprice; + if ( LP_quoteinfoinit(&Q,utxo,rel,price) < 0 ) + return(-1); + Q.timestamp = (uint32_t)time(NULL); + retjson = LP_quotejson(&Q); + jaddstr(retjson,"method","quote"); + retstr = jprint(retjson,1); + //printf("PING.(%s)\n",retstr); + if ( pubsock >= 0 ) + LP_send(pubsock,retstr,1); + else + { + // verify it is in list + // push if it isnt + } + utxo->T.published = now; + return(0); + } + return(-1); + }*/ +/*if ( (butxo= LP_utxopairfind(1,Q.txid,Q.vout,Q.txid2,Q.vout2)) == 0 ) + { + value = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid,Q.vout); + value2 = LP_txvalue(Q.coinaddr,Q.srccoin,Q.txid2,Q.vout2); + if ( value == 0 || value2 == 0 ) + { + printf("zero value %.8f or value2 %.8f\n",dstr(value),dstr(value2)); + return(clonestr("{\"error\":\"spent txid or txid2 for bob?\"}")); + } + if ( (butxo= LP_utxoadd(1,Q.srccoin,Q.txid,Q.vout,value,Q.txid2,Q.vout2,value2,Q.coinaddr,Q.srchash,LP_gui,0)) == 0 ) + { + printf("cant find or create butxo\n"); + return(clonestr("{\"error\":\"cant find or create butxo\"}")); + } + if ( value < Q.satoshis ) + { + printf("butxo value %.8f less satoshis %.8f\n",dstr(value),dstr(Q.satoshis)); + return(clonestr("{\"error\":\"butxo value less than satoshis\"}")); + } + }*/ + +/*if ( addflag != 0 && LP_utxofind(1,Q.txid,Q.vout) == 0 ) + { + LP_utxoadd(1,-1,Q.srccoin,Q.txid,Q.vout,Q.value,Q.txid2,Q.vout2,Q.value2,"",Q.srcaddr,Q.srchash,0.); + LP_utxoadd(0,-1,Q.destcoin,Q.desttxid,Q.destvout,Q.destvalue,Q.feetxid,Q.feevout,Q.feevalu,"",Q.destaddr,Q.desthash,0.); + }*/ + +/*struct LP_utxoinfo *utxo,*tmp; + HASH_ITER(hh,LP_utxoinfos[1],utxo,tmp) + { + if ( LP_ismine(utxo) > 0 && strcmp(utxo->coin,base) == 0 ) + LP_priceping(LP_mypubsock,utxo,rel,price * LP_profitratio); + }*/ + +int32_t LP_ismine(struct LP_utxoinfo *utxo) +{ + if ( utxo != 0 && bits256_cmp(utxo->pubkey,G.LP_mypub25519) == 0 ) + return(1); + else return(0); +} + +queue_t utxosQ; +struct LP_utxos_qitem { struct queueitem DL; cJSON *argjson; }; + +char *LP_postutxos_recv(cJSON *argjson) +{ + struct LP_utxos_qitem *uitem; struct iguana_info *coin; char *coinaddr,*symbol; bits256 utxoshash,pubkey; cJSON *obj; struct LP_pubkey_info *pubp; + printf("LP_postutxos_recv deprecated\n"); + pubkey = jbits256(argjson,"pubkey"); + pubp = LP_pubkeyfind(pubkey); + if ( pubp != 0 && pubp->numerrors > LP_MAXPUBKEY_ERRORS ) + return(clonestr("{\"error\":\"blacklisted\"}")); + if ( (coinaddr= jstr(argjson,"coinaddr")) != 0 && (symbol= jstr(argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 ) + { + if ( strcmp(coinaddr,coin->smartaddr) == 0 ) + { + //printf("ignore my utxo from external source %s %s\n",symbol,coinaddr); + return(clonestr("{\"result\":\"success\"}")); + } + } + if ( (obj= jobj(argjson,"utxos")) != 0 ) + { + utxoshash = LP_utxoshash_calc(obj); + //char str[65]; //printf("got utxoshash %s\n",bits256_str(str,utxoshash)); + if ( LP_utxos_sigcheck(juint(argjson,"timestamp"),jstr(argjson,"sig"),jstr(argjson,"pubsecp"),pubkey,utxoshash) == 0 ) + { + uitem = calloc(1,sizeof(*uitem)); + uitem->argjson = jduplicate(argjson); + queue_enqueue("utxosQ",&utxosQ,&uitem->DL); + return(clonestr("{\"result\":\"success\"}")); + } //else printf("valid utxos sig %s\n",bits256_str(str,pubp->pubkey)); + } + return(clonestr("{\"error\":\"sig failure\"}")); +} + +/*MERK d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a ht.518777 -> {"pos":1,"merkle":["526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8", "f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd"],"block_height":518777} root.(0000000000000000000000000000000000000000000000000000000000000000) + MERK c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 ht.518777 -> {"pos":2,"merkle":["fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501", "8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7"],"block_height":518777} root.(0000000000000000000000000000000000000000000000000000000000000000)*/ +/*526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8 + d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a + c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 + fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501*/ + +/*0: 526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8 + 1: d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a + 2: c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543 + 3: fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501 + 4: 8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7 + 5: f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd + 6: a87ee259560f20b20182760c0e7cc7896d44381f0ad58a2e755a2b6b895b01ec*/ + +/* + 0 1 2 3 + 4 5 + 6 + + 1 -> [0, 5] + 2 -> [3, 4] + + if odd -> right, else left + then /= 2 + */ + +/*void testmerk() + { + bits256 tree[256],roothash,txid; int32_t i; char str[65]; + memset(tree,0,sizeof(tree)); + decode_hex(tree[0].bytes,32,"526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8"); + decode_hex(tree[1].bytes,32,"d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a"); + decode_hex(tree[2].bytes,32,"c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543"); + decode_hex(tree[3].bytes,32,"fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501"); + roothash = iguana_merkle(tree,4); + for (i=0; i<256; i++) + { + if ( bits256_nonz(tree[i]) == 0 ) + break; + printf("%d: %s\n",i,bits256_str(str,tree[i])); + } + memset(tree,0,sizeof(tree)); + decode_hex(tree[0].bytes,32,"526f8be81718beccc16a541a2c550b612123218d80fa884d9f080f18284e2bd8"); + decode_hex(tree[1].bytes,32,"f68b03a7b6e418c9b306d8d8b21917ae5a584696f9b0b8cb0741733d7097fdfd"); + decode_hex(txid.bytes,32,"d6071f9b03d1428b648d51ae1268f1605d97f44422ed55ad0335b13fa655f61a"); + roothash = validate_merkle(1,txid,tree,2); + printf("validate 1: %s\n",bits256_str(str,roothash)); + memset(tree,0,sizeof(tree)); + decode_hex(tree[0].bytes,32,"fdff0962fb95120a86a07ddf1ec784fcc5554a2d0a3791a8db2083d593920501"); + decode_hex(tree[1].bytes,32,"8c116e974c842ad3ad8b3ddbd71da3debb150e3fe692f5bd628381bc167311a7"); + decode_hex(txid.bytes,32,"c007e9c1881a83be453cb6ed3d1bd3bda85efd3b5ce60532c2e20ae3f8a82543"); + roothash = validate_merkle(2,txid,tree,2); + printf("validate 2: %s\n",bits256_str(str,roothash)); + }*/ + +/*else if ( (retstr= LP_orderbook(coin->symbol,"KMD",-1)) != 0 ) + { + if ( (orderbook= cJSON_Parse(retstr)) != 0 ) + { + if ( (asks= jarray(&numasks,orderbook,"asks")) != 0 && numasks > 0 ) + { + item = jitem(asks,0); + price = ask = jdouble(item,"price"); + //printf("%s/%s ask %.8f\n",coin->symbol,"KMD",ask); + } + if ( (bids= jarray(&numbids,orderbook,"bids")) != 0 && numbids > 0 ) + { + item = jitem(asks,0); + bid = jdouble(item,"price"); + if ( price == 0. ) + price = bid; + else price = (bid + ask) * 0.5; + //printf("%s/%s bid %.8f ask %.8f price %.8f\n",coin->symbol,"KMD",bid,ask,price); + } + KMDvalue = price * balance; + free_json(orderbook); + } + free(retstr); + }*/ + +int32_t LP_utxosQ_process() +{ + struct LP_utxos_qitem *uitem; int32_t n; char *symbol,*coinaddr; struct LP_address *ap; struct iguana_info *coin; cJSON *array; + if ( (uitem= queue_dequeue(&utxosQ)) != 0 ) + { + //printf("LP_utxosQ_process.(%s)\n",jprint(uitem->argjson,0)); + if ( (coinaddr= jstr(uitem->argjson,"coinaddr")) != 0 && (symbol= jstr(uitem->argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 ) // addsig + { + if ( coin->electrum == 0 || (ap= LP_addressfind(coin,coinaddr)) != 0 ) + { + if ( (array= jarray(&n,uitem->argjson,"utxos")) != 0 ) + LP_unspents_array(coin,coinaddr,array); + } + else if ( (array= electrum_address_listunspent(symbol,coin->electrum,&array,coinaddr,1)) != 0 ) + free_json(array); + } + free_json(uitem->argjson); + free(uitem); + return(1); + } + return(0); +} +else if ( strcmp(method,"postutxos") == 0 ) +return(LP_postutxos_recv(argjson)); + +void utxosQ_loop(void *myipaddr) +{ + strcpy(utxosQ_loop_stats.name,"utxosQ_loop"); + utxosQ_loop_stats.threshold = 5000.; + while ( 1 ) + { + LP_millistats_update(&utxosQ_loop_stats); + if ( LP_utxosQ_process() == 0 ) + usleep(50000); + } +} +if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)utxosQ_loop,(void *)myipaddr) != 0 ) +{ + printf("error launching utxosQ_loop for (%s)\n",myipaddr); + exit(-1); +} + +/* +bestprice = 0.; +if ( (array= LP_tradecandidates(base)) != 0 ) +{ + printf("candidates.(%s)\nn.%d\n",jprint(array,0),cJSON_GetArraySize(array)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + memset(prices,0,sizeof(prices)); + memset(Q,0,sizeof(Q)); + for (i=0; icoin,zero); + Q[i].destsatoshis = price * Q[i].satoshis; + } + if ( (prices[i]= price) > SMALLVAL && (bestprice == 0. || price < bestprice) ) + bestprice = price; + char str[65]; printf("i.%d of %d: (%s) -> txid.%s price %.8f best %.8f dest %.8f\n",i,n,jprint(item,0),bits256_str(str,Q[i].txid),price,bestprice,dstr(Q[i].destsatoshis)); + } + if ( bestprice > SMALLVAL ) + { + bestmetric = 0.; + besti = -1; + for (i=0; i SMALLVAL && myutxo->S.satoshis >= Q[i].destsatoshis+Q[i].desttxfee ) + { + metric = price / bestprice; + printf("%f %f %f %f ",price,metric,dstr(Q[i].destsatoshis),metric * metric * metric); + if ( metric < 1.1 ) + { + metric = dstr(Q[i].destsatoshis) * metric * metric * metric; + printf("%f\n",metric); + if ( bestmetric == 0. || metric < bestmetric ) + { + besti = i; + bestmetric = metric; + } + } + } else printf("(%f %f) ",dstr(myutxo->S.satoshis),dstr(Q[i].destsatoshis)); + } + printf("metrics, best %f\n",bestmetric); +*/ + +int32_t LP_utxosquery(struct LP_peerinfo *mypeer,int32_t mypubsock,char *destipaddr,uint16_t destport,char *coin,int32_t lastn,char *myipaddr,uint16_t myport,int32_t maxentries) +{ + char *retstr; struct LP_peerinfo *peer; uint32_t now; int32_t retval = -1; + printf("deprecated LP_utxosquery\n"); + return(-1); + peer = LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport); + if ( coin == 0 ) + coin = ""; + //printf("utxo query.(%s)\n",destipaddr); + if ( IAMLP != 0 ) + retstr = issue_LP_getutxos(destipaddr,destport,coin,lastn,myipaddr,myport,mypeer != 0 ? mypeer->numpeers : 0,maxentries); + else retstr = issue_LP_clientgetutxos(destipaddr,destport,coin,maxentries); + if ( retstr != 0 ) + { + now = (uint32_t)time(NULL); + retval = LP_utxosparse(destipaddr,destport,retstr,now); + //printf("got.(%s)\n",retstr); + free(retstr); + } + return(retval); +} + +char *issue_LP_numutxos(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos) +{ + char url[512],*retstr; + printf("deprecated issue_LP_numutxos\n"); + return(0); + sprintf(url,"http://%s:%u/api/stats/numutxos?ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,ipaddr,port,numpeers,numutxos); + retstr = LP_issue_curl("numutxos",destip,port,url); + //printf("%s -> getpeers.(%s)\n",destip,retstr); + return(retstr); +} + +char *issue_LP_getutxos(char *destip,uint16_t destport,char *coin,int32_t lastn,char *ipaddr,uint16_t port,int32_t numpeers,int32_t numutxos) +{ + char url[512]; + printf("deprecated issue_LP_getutxos\n"); + return(0); + sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=%s&port=%u&numpeers=%d&numutxos=%d",destip,destport,coin,lastn,ipaddr,port,numpeers,numutxos); + return(LP_issue_curl("getutxos",destip,destport,url)); + //return(issue_curlt(url,LP_HTTP_TIMEOUT)); +} + +char *issue_LP_clientgetutxos(char *destip,uint16_t destport,char *coin,int32_t lastn) +{ + char url[512];//,*retstr; + printf("deprecated issue_LP_clientgetutxos\n"); + return(0); + sprintf(url,"http://%s:%u/api/stats/getutxos?coin=%s&lastn=%d&ipaddr=127.0.0.1&port=0",destip,destport,coin,lastn); + return(LP_issue_curl("clientgetutxos",destip,destport,url)); + //retstr = issue_curlt(url,LP_HTTP_TIMEOUT); + //printf("%s clientgetutxos.(%s)\n",url,retstr); + //return(retstr); +} +void LP_address_monitor(struct LP_pubkeyinfo *pubp) +{ + struct iguana_info *coin,*tmp; char coinaddr[64]; cJSON *retjson; struct LP_address *ap; + return; + HASH_ITER(hh,LP_coins,coin,tmp) + { + bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); + portable_mutex_lock(&coin->addrmutex); + if ( (ap= _LP_address(coin,coinaddr)) != 0 ) + { + ap->monitor = (uint32_t)time(NULL); + } + portable_mutex_unlock(&coin->addrmutex); + if ( coin->electrum != 0 ) + { + if ( (retjson= electrum_address_subscribe(coin->symbol,coin->electrum,&retjson,coinaddr)) != 0 ) + { + printf("%s MONITOR.(%s) -> %s\n",coin->symbol,coinaddr,jprint(retjson,0)); + free_json(retjson); + } + } + } +} + +/*else if ( strcmp(method,"ordermatch") == 0 ) + { + if ( price > SMALLVAL ) + return(LP_ordermatch(base,j64bits(argjson,"txfee"),price,jdouble(argjson,"relvolume"),rel,jbits256(argjson,"txid"),jint(argjson,"vout"),jbits256(argjson,"feetxid"),jint(argjson,"feevout"),j64bits(argjson,"desttxfee"),jint(argjson,"duration"))); + else return(clonestr("{\"error\":\"no price set\"}")); + } + else if ( strcmp(method,"trade") == 0 ) + { + struct LP_quoteinfo Q; + if ( price > SMALLVAL || jobj(argjson,"quote") != 0 ) + { + LP_quoteparse(&Q,jobj(argjson,"quote")); + return(LP_trade(ctx,myipaddr,pubsock,&Q,price,jint(argjson,"timeout"),jint(argjson,"duration"))); + } else return(clonestr("{\"error\":\"no price set or no quote object\"}")); + } + else if ( strcmp(method,"autotrade") == 0 ) + { + if ( price > SMALLVAL ) + { + return(LP_autotrade(ctx,myipaddr,pubsock,base,rel,price,jdouble(argjson,"relvolume"),jint(argjson,"timeout"),jint(argjson,"duration"))); + } else return(clonestr("{\"error\":\"no price set\"}")); + }*/ +if ( flag != 0 ) +{ + // need to find the requestid/quoteid for aliceid + if ( (retstr= basilisk_swapentries(bot->base,bot->rel,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retjson)) != 0 ) + { + for (flag=j=0; jnumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid == 0 && tp->quoteid == 0 ) + { + if ( tp->aliceid == aliceid ) + { + tp->requestid = juint(item,"requestid"); + tp->quoteid = juint(item,"quoteid"); + printf("found aliceid.%llx to set requestid.%u quoteid.%u\n",(long long)aliceid,tp->requestid,tp->quoteid); + flag = 1; + break; + } + } + } + } + } + free_json(retjson); + } + free(retstr); + } +} +// check for finished pending swap +for (i=0; inumtrades; i++) +{ + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->requestid != 0 && tp->quoteid != 0 ) + { + if ( (retstr= basilisk_swapentry(tp->requestid,tp->quoteid)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (status= jstr(retjson,"status")) != 0 && strcmp(status,"finished") == 0 ) + { + bot->pendbasesum -= tp->basevol, bot->basesum += tp->basevol; + bot->pendrelsum -= tp->relvol, bot->relsum += tp->relvol; + bot->numpending--, bot->completed++; + printf("detected completion aliceid.%llx r.%u q.%u\n",(long long)tp->aliceid,tp->requestid,tp->quoteid); + tp->finished = (uint32_t)time(NULL); + } + free_json(retjson); + } + free(retstr); + } + } +} +} + +int32_t LP_utxopurge(int32_t allutxos) +{ + char str[65]; struct LP_utxoinfo *utxo,*tmp; int32_t iambob,n = 0; + printf("LP_utxopurge mypub.(%s)\n",bits256_str(str,LP_mypub25519)); + portable_mutex_lock(&LP_utxomutex); + for (iambob=0; iambob<=1; iambob++) + { + HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp) + { + if ( LP_isavailable(utxo) > 0 ) + { + if ( allutxos != 0 || LP_ismine(utxo) > 0 ) + { + printf("iambob.%d delete.(%s)\n",iambob,bits256_str(str,utxo->payment.txid)); + HASH_DELETE(hh,LP_utxoinfos[iambob],utxo); + //free(utxo); let the LP_utxoinfos2 free the utxo, should be 1:1 + } else n++; + } else n++; + } + HASH_ITER(hh,LP_utxoinfos2[iambob],utxo,tmp) + { + if ( LP_isavailable(utxo) > 0 ) + { + if ( allutxos != 0 || LP_ismine(utxo) > 0 ) + { + printf("iambob.%d delete2.(%s)\n",iambob,bits256_str(str,utxo->payment.txid)); + HASH_DELETE(hh2,LP_utxoinfos2[iambob],utxo); + free(utxo); + } else n++; + } else n++; + } + } + portable_mutex_unlock(&LP_utxomutex); + return(n); +} +/*struct LP_utxoinfo *_LP_butxo_find(struct LP_utxoinfo *butxo) + { + int32_t i; struct LP_utxoinfo *utxo=0; uint32_t now = (uint32_t)time(NULL); + //portable_mutex_lock(&LP_butxomutex); + for (i=0; ipayment.vout == utxo->payment.vout && butxo->deposit.vout == utxo->deposit.vout && bits256_nonz(butxo->payment.txid) != 0 && bits256_nonz(butxo->deposit.txid) != 0 && bits256_cmp(butxo->payment.txid,utxo->payment.txid) == 0 && bits256_cmp(butxo->deposit.txid,utxo->deposit.txid) == 0 ) + break; + if ( utxo->S.swap == 0 && now > utxo->T.swappending ) + memset(utxo,0,sizeof(*utxo)); + utxo = 0; + } + //portable_mutex_unlock(&LP_butxomutex); + return(utxo); + } + + struct LP_utxoinfo *LP_butxo_add(struct LP_utxoinfo *butxo) + { + static struct LP_utxoinfo zeroes; + int32_t i; struct LP_utxoinfo *utxo=0; + portable_mutex_lock(&LP_butxomutex); + if ( (utxo= _LP_butxo_find(butxo)) == 0 ) + { + for (i=0; iS = srcutxo->S; + destutxo->T = srcutxo->T; + } + + void LP_butxo_swapfields(struct LP_utxoinfo *butxo) + { + struct LP_utxoinfo *getutxo=0; + portable_mutex_lock(&LP_butxomutex); + if ( (getutxo= _LP_butxo_find(butxo)) != 0 ) + LP_butxo_swapfields_copy(butxo,getutxo); + portable_mutex_unlock(&LP_butxomutex); + } + + void LP_butxo_swapfields_set(struct LP_utxoinfo *butxo) + { + struct LP_utxoinfo *setutxo; + if ( (setutxo= LP_butxo_add(butxo)) != 0 ) + { + LP_butxo_swapfields_copy(setutxo,butxo); + } + }*/ +/*struct LP_utxoinfo BUTXOS[100]; + + int32_t LP_butxo_findeither(bits256 txid,int32_t vout) + { + struct LP_utxoinfo *utxo; int32_t i,retval = 0; + portable_mutex_lock(&LP_butxomutex); + for (i=0; ipayment.vout && bits256_cmp(txid,utxo->payment.txid)) == 0 || (vout == utxo->deposit.vout && bits256_cmp(txid,utxo->deposit.txid) == 0) ) + { + retval = 1; + break; + } + } + portable_mutex_unlock(&LP_butxomutex); + return(retval); + }*/ + +struct LP_utxoinfo *LP_utxoaddjson(int32_t iambob,int32_t pubsock,cJSON *argjson) +{ + struct LP_utxoinfo *utxo; + if ( jobj(argjson,"iambob") == 0 || iambob != jint(argjson,"iambob") ) + { + printf("LP_utxoaddjson: iambob.%d != arg.%d obj.%p (%s)\n",iambob,jint(argjson,"iambob"),jobj(argjson,"iambob"),jprint(argjson,0)); + return(0); + } + portable_mutex_lock(&LP_UTXOmutex); + utxo = LP_utxoadd(iambob,pubsock,jstr(argjson,"coin"),jbits256(argjson,"txid"),jint(argjson,"vout"),j64bits(argjson,"value"),jbits256(argjson,"txid2"),jint(argjson,"vout2"),j64bits(argjson,"value2"),jstr(argjson,"script"),jstr(argjson,"address"),jbits256(argjson,"pubkey"),jstr(argjson,"gui"),juint(argjson,"session")); + if ( LP_ismine(utxo) > 0 && utxo->T.lasttime == 0 ) + { + utxo->T.lasttime = (uint32_t)time(NULL); + printf("set lasttime!\n"); + } + portable_mutex_unlock(&LP_UTXOmutex); + return(utxo); +} + + +int32_t LP_utxosparse(char *destipaddr,uint16_t destport,char *retstr,uint32_t now) +{ + struct LP_peerinfo *peer; uint32_t argipbits; char *argipaddr; uint16_t argport,pushport,subport; cJSON *array,*item; int32_t i,n=0; bits256 txid; struct LP_utxoinfo *utxo; + //printf("parse.(%s)\n",retstr); + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; iT.lasttime = now; + } + } + if ( (destpeer= LP_peerfind((uint32_t)calc_ipbits(destipaddr),destport)) != 0 ) + { + destpeer->numutxos = n; + } + } + free_json(array); + } + return(n); +} +void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) +{ + //cJSON *argjson; struct _LP_utxoinfo u; char *msg; + if ( utxo == 0 ) + return; + utxo->T.spentflag = (uint32_t)time(NULL); + /*if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 ) + LP_mypeer->numutxos--; + if ( LP_mypubsock >= 0 ) + { + argjson = cJSON_CreateObject(); + jaddstr(argjson,"method","checktxid"); + jaddbits256(argjson,"txid",utxo->payment.txid); + jaddnum(argjson,"vout",utxo->payment.vout); + if ( selector != 0 ) + { + if ( bits256_nonz(utxo->deposit.txid) != 0 ) + u = utxo->deposit; + else u = utxo->fee; + jaddbits256(argjson,"checktxid",u.txid); + jaddnum(argjson,"checkvout",u.vout); + } + msg = jprint(argjson,1); + /LP_send(LP_mypubsock,msg,(int32_t)strlen(msg)+1,1); + }*/ +} +char *LP_utxos(int32_t iambob,struct LP_peerinfo *mypeer,char *symbol,int32_t lastn) +{ + int32_t i,n,m; uint64_t val,val2; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo,*tmp; cJSON *utxosjson = cJSON_CreateArray(); + printf("deprecated! LP_utxos\n"); + //n = mypeer != 0 ? mypeer->numutxos : 0; + if ( lastn <= 0 ) + lastn = LP_PROPAGATION_SLACK * 2; + HASH_ITER(hh,LP_utxoinfos[iambob],utxo,tmp) + { + //char str[65]; printf("check %s.%s\n",utxo->coin,bits256_str(str,utxo->payment.txid)); + if ( (symbol == 0 || symbol[0] == 0 || strcmp(symbol,utxo->coin) == 0) && utxo->T.spentflag == 0 ) + { + u = (iambob != 0) ? utxo->deposit : utxo->fee; + if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) == 0 ) + { + char str[65]; printf("iambob.%d not eligible (%.8f %.8f) %s %s/v%d\n",iambob,dstr(val),dstr(val2),utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout); + continue; + } else jaddi(utxosjson,LP_utxojson(utxo)); + } + } + if ( (n= cJSON_GetArraySize(utxosjson)) > lastn ) + { + m = n - lastn; + for (i=0; icoin)) == 0 ) + return(0); + if ( (up= LP_address_utxofind(coin,utxo->coinaddr,utxo->payment.txid,utxo->payment.vout)) != 0 && up->spendheight > 0 ) + { + utxo->T.spentflag = up->spendheight; + return(0); + } + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( (up= LP_address_utxofind(coin,utxo->coinaddr,u.txid,u.vout)) != 0 && up->spendheight > 0 ) + { + utxo->T.spentflag = up->spendheight; + return(0); + } + if ( utxo != 0 && utxo->T.spentflag == 0 && LP_isavailable(utxo) > 0 ) + return(1); + else return(0); +} + +void LP_utxo_clientpublish(struct LP_utxoinfo *utxo) +{ + bits256 zero; char *msg; + if ( 0 && LP_isunspent(utxo) > 0 ) + { + memset(zero.bytes,0,sizeof(zero)); + msg = jprint(LP_utxojson(utxo),1); + LP_broadcast_message(LP_mypubsock,utxo->coin,"",zero,msg); + } +} + +/*char *LP_spentcheck(cJSON *argjson) + { + bits256 txid,checktxid; int32_t vout,checkvout; struct LP_utxoinfo *utxo; int32_t iambob,retval = 0; + txid = jbits256(argjson,"txid"); + vout = jint(argjson,"vout"); + for (iambob=0; iambob<=1; iambob++) + { + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 && utxo->T.spentflag == 0 ) + { + if ( jobj(argjson,"check") == 0 ) + checktxid = txid, checkvout = vout; + else + { + checktxid = jbits256(argjson,"checktxid"); + checkvout = jint(argjson,"checkvout"); + } + if ( LP_txvalue(0,utxo->coin,checktxid,checkvout) == 0 ) + { + //if ( LP_mypeer != 0 && LP_mypeer->numutxos > 0 ) + // LP_mypeer->numutxos--; + utxo->T.spentflag = (uint32_t)time(NULL); + retval++; + printf("indeed txid was spent\n"); + } + } + } + if ( retval > 0 ) + return(clonestr("{\"result\":\"marked as spent\"}")); + return(clonestr("{\"error\":\"cant find txid to check spent status\"}")); + }*/ + + +/*char *LP_pricestr(char *base,char *rel,double origprice) + { + cJSON *retjson; double price = 0.; + if ( base != 0 && base[0] != 0 && rel != 0 && rel[0] != 0 ) + { + price = LP_price(base,rel); + if ( origprice > SMALLVAL && origprice < price ) + price = origprice; + } + if ( LP_pricevalid(price) > 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"method","postprice"); + jaddbits256(retjson,"pubkey",G.LP_mypub25519); + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddnum(retjson,"price",price); + jadd(retjson,"theoretical",LP_priceinfomatrix(0)); + jadd(retjson,"quotes",LP_priceinfomatrix(1)); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"cant find baserel pair\"}")); + }*/ +void LP_utxo_spentcheck(int32_t pubsock,struct LP_utxoinfo *utxo) +{ + struct _LP_utxoinfo u; struct iguana_info *coin; char str[65]; uint32_t now = (uint32_t)time(NULL); + if ( IAMLP != 0 && (coin= LP_coinfind(utxo->coin)) != 0 && coin->inactive != 0 ) + return; + //printf("%s lag.%d\n",bits256_str(str,utxo->txid),now-utxo->lastspentcheck); + if ( utxo->T.spentflag == 0 && now > utxo->T.lastspentcheck+60 ) + { + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + utxo->T.lastspentcheck = now; + if ( LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) == 0 ) + { + printf("txid.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(utxo->payment.value)); + LP_spentnotify(utxo,0); + } + else if ( LP_txvalue(0,utxo->coin,u.txid,u.vout) == 0 ) + { + printf("txid2.%s %s/v%d %.8f has been spent\n",utxo->coin,bits256_str(str,u.txid),u.vout,dstr(u.value)); + LP_spentnotify(utxo,1); + } + } +} + +int32_t LP_peer_utxosquery(struct LP_peerinfo *mypeer,uint16_t myport,int32_t pubsock,struct LP_peerinfo *peer,uint32_t now,int32_t interval,int32_t maxentries) +{ + int32_t lastn,n = -1; + if ( peer->lastutxos < now-interval ) + { + //lastn = peer->numutxos - mypeer->numutxos + LP_PROPAGATION_SLACK; + //if ( lastn < LP_PROPAGATION_SLACK * 2 ) + lastn = LP_PROPAGATION_SLACK * 2; + if ( mypeer == 0 || strcmp(peer->ipaddr,mypeer->ipaddr) != 0 ) + { + peer->lastutxos = now; + //printf("query utxos from %s\n",peer->ipaddr); + n = LP_utxosquery(mypeer,pubsock,peer->ipaddr,peer->port,"",lastn,mypeer != 0 ? mypeer->ipaddr : "127.0.0.1",myport,maxentries); + } + } //else printf("LP_peer_utxosquery skip.(%s) %u\n",peer->ipaddr,peer->lastutxos); + return(n); +} +bestitem = LP_quotejson(qp); +if ( LP_pricevalid(price) > 0 ) +{ + if ( price <= maxprice ) + { + LP_query(ctx,myipaddr,mypubsock,"connect",qp); + //price = LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout); + LP_requestinit(&qp->R,qp->srchash,qp->desthash,qp->srccoin,qp->satoshis-2*qp->txfee,qp->destcoin,qp->destsatoshis-2*qp->desttxfee,qp->timestamp,qp->quotetime,DEXselector); + while ( time(NULL) < expiration ) + { + if ( aliceutxo->S.swap != 0 ) + break; + sleep(3); + } + jaddnum(bestitem,"quotedprice",price); + jaddnum(bestitem,"maxprice",maxprice); + if ( (swap= aliceutxo->S.swap) == 0 ) + { + if ( (pubp= LP_pubkeyadd(qp->srchash)) != 0 ) + pubp->numerrors++; + jaddstr(bestitem,"status","couldnt establish connection"); + } + else + { + jaddstr(bestitem,"status","connected"); + jaddnum(bestitem,"requestid",swap->I.req.requestid); + jaddnum(bestitem,"quoteid",swap->I.req.quoteid); + printf("Alice r.%u qp->%u\n",swap->I.req.requestid,swap->I.req.quoteid); + } + } + else + { + jaddnum(bestitem,"quotedprice",price); + jaddnum(bestitem,"maxprice",maxprice); + jaddstr(bestitem,"status","too expensive"); + } +} +else +{ + printf("invalid price %.8f\n",price); + jaddnum(bestitem,"maxprice",maxprice); + jaddstr(bestitem,"status","no response to request"); +} +uint32_t LP_allocated(bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo; + if ( (utxo= _LP_utxofind(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxo2find(0,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxofind(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available\n",bits256_str(str,txid),vout); + return(utxo); + } + if ( (utxo= _LP_utxo2find(1,txid,vout)) != 0 && LP_isavailable(utxo) == 0 ) + { + //char str[65]; printf("%s/v%d not available2\n",bits256_str(str,txid),vout); + return(utxo); + } + return(0); +} + +int32_t LP_isavailable(struct LP_utxoinfo *utxo) +{ + if ( time(NULL) > utxo->T.swappending ) + utxo->T.swappending = 0; + if ( utxo != 0 && utxo->T.swappending == 0 && utxo->S.swap == 0 ) + return(1); + else return(0); +} + +int32_t LP_utxoaddptrs(struct LP_utxoinfo *ptrs[],int32_t n,struct LP_utxoinfo *utxo) +{ + int32_t i; + for (i=0; ipayment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + if ( (utxo= _LP_utxo2find(iambob,refutxo->payment.txid,refutxo->payment.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + u = (refutxo->iambob != 0) ? refutxo->deposit : refutxo->fee; + if ( (utxo= _LP_utxofind(iambob,u.txid,u.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + if ( (utxo= _LP_utxo2find(iambob,u.txid,u.vout)) != 0 && utxo != refutxo ) + n = LP_utxoaddptrs(ptrs,n,utxo); + } + portable_mutex_unlock(&LP_utxomutex); + if ( 0 && n > 0 ) + printf("LP_utxocollisions n.%d\n",n); + return(n); +} + +int32_t _LP_availableset(struct LP_utxoinfo *utxo) +{ + int32_t flag = 0; + if ( utxo != 0 ) + { + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + flag = 1, memset(&utxo->S.otherpubkey,0,sizeof(utxo->S.otherpubkey)); + if ( utxo->S.swap != 0 ) + flag = 1, utxo->S.swap = 0; + if ( utxo->T.swappending != 0 ) + flag = 1, utxo->T.swappending = 0; + return(flag); + } + return(0); +} + +void _LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) +{ + if ( utxo != 0 ) + { + utxo->T.swappending = (uint32_t)(time(NULL) + LP_RESERVETIME); + utxo->S.otherpubkey = otherpubkey; + } +} + +void LP_unavailableset(struct LP_utxoinfo *utxo,bits256 otherpubkey) +{ + struct LP_utxoinfo *ptrs[8]; int32_t i,n; struct _LP_utxoinfo u; + memset(ptrs,0,sizeof(ptrs)); + if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) + { + for (i=0; iiambob != 0) ? utxo->deposit : utxo->fee; + char str[65],str2[65]; printf("UTXO.[%d] RESERVED %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n); + _LP_unavailableset(utxo,otherpubkey); +} + +void LP_availableset(struct LP_utxoinfo *utxo) +{ + struct LP_utxoinfo *ptrs[8]; int32_t i,n,count = 0; struct _LP_utxoinfo u; + if ( utxo != 0 ) + { + memset(ptrs,0,sizeof(ptrs)); + if ( (n= LP_utxocollisions(ptrs,utxo)) > 0 ) + { + for (i=0; i 0 ) + { + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + char str[65],str2[65]; printf("UTXO.[%d] AVAIL %s/v%d %s/v%d collisions.%d\n",utxo->iambob,bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,u.txid),u.vout,n); + } + } +} + + +cJSON *LP_inventoryjson(cJSON *item,struct LP_utxoinfo *utxo) +{ + struct _LP_utxoinfo u; + //jaddstr(item,"method","oldutxo"); + if ( utxo == 0 ) + return(item); + if ( utxo->gui[0] != 0 ) + jaddstr(item,"gui",utxo->gui); + jaddstr(item,"coin",utxo->coin); + //jaddnum(item,"now",time(NULL)); + jaddnum(item,"iambob",utxo->iambob); + jaddstr(item,"address",utxo->coinaddr); + jaddbits256(item,"txid",utxo->payment.txid); + jaddnum(item,"vout",utxo->payment.vout); + jadd64bits(item,"value",utxo->payment.value); + jadd64bits(item,"satoshis",utxo->S.satoshis); + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( bits256_nonz(u.txid) != 0 ) + { + jaddbits256(item,"txid2",u.txid); + jaddnum(item,"vout2",u.vout); + jadd64bits(item,"value2",u.value); + } + if ( utxo->T.swappending != 0 ) + jaddnum(item,"pending",utxo->T.swappending); + if ( utxo->iambob != 0 ) + { + jaddbits256(item,"srchash",utxo->pubkey);//LP_mypub25519); + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + jaddbits256(item,"desthash",utxo->S.otherpubkey); + } + else + { + jaddbits256(item,"desthash",utxo->pubkey);//LP_mypub25519); + if ( bits256_nonz(utxo->S.otherpubkey) != 0 ) + jaddbits256(item,"srchash",utxo->S.otherpubkey); + } + //if ( utxo->S.swap != 0 ) + // jaddstr(item,"swap","in progress"); + if ( utxo->T.spentflag != 0 ) + jaddnum(item,"spent",utxo->T.spentflag); + jaddnum(item,"session",utxo->T.sessionid); + return(item); +} + +cJSON *LP_utxojson(struct LP_utxoinfo *utxo) +{ + cJSON *item = cJSON_CreateObject(); + item = LP_inventoryjson(item,utxo); + jaddbits256(item,"pubkey",utxo->pubkey); + //jaddnum(item,"profit",utxo->S.profitmargin); + jaddstr(item,"base",utxo->coin); + //jaddstr(item,"script",utxo->spendscript); + return(item); +} + +struct LP_utxoinfo *LP_utxo_bestfit(char *symbol,uint64_t destsatoshis) +{ + uint64_t srcvalue,srcvalue2; struct LP_utxoinfo *utxo,*tmp,*bestutxo = 0; int32_t bestsize,iambob = 0; + if ( symbol == 0 || destsatoshis == 0 ) + { + printf("LP_utxo_bestfit error symbol.%p %.8f\n",symbol,dstr(destsatoshis)); + return(0); + } + HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) + { + if ( strcmp(symbol,utxo->coin) != 0 ) + continue; + if ( LP_isavailable(utxo) > 0 && LP_ismine(utxo) > 0 ) + { + //printf("(%.8f %.8f %.8f)\n",dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); + //char str[65]; printf("s%u %d [%.8f vs %.8f] check %s.%s avail.%d ismine.%d >= %d\n",utxo->T.spentflag,LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout),dstr(destsatoshis),dstr(utxo->S.satoshis),utxo->coin,bits256_str(str,utxo->payment.txid),LP_isavailable(utxo) > 0,LP_ismine(utxo) > 0,utxo->S.satoshis >= destsatoshis); + bestsize = 0; + if ( bestutxo == 0 ) + { + if ( utxo->S.satoshis > destsatoshis/LP_MINCLIENTVOL ) + bestsize = 1; + } + else + { + if ( bestutxo->S.satoshis < destsatoshis ) + { + if ( utxo->S.satoshis > destsatoshis ) + bestsize = 1; + else if ( utxo->S.satoshis > bestutxo->S.satoshis ) + bestsize = 1; + } + else + { + if ( utxo->S.satoshis > destsatoshis && utxo->S.satoshis < bestutxo->S.satoshis ) + bestsize = 1; + } + } + if ( bestsize > 0 ) + { + //printf("bestsize.%d %.8f %.8f -> %.8f\n",bestsize,dstr(utxo->payment.value),dstr(utxo->fee.value),dstr(utxo->S.satoshis)); + if ( LP_iseligible(&srcvalue,&srcvalue2,utxo->iambob,symbol,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->fee.txid,utxo->fee.vout) == 0 ) + { + //if ( utxo->T.spentflag == 0 ) + // utxo->T.spentflag = (uint32_t)time(NULL); + continue; + } + bestutxo = utxo; + } //else printf("skip alice utxo %.8f vs dest %.8f, bestsize.%d %p\n",dstr(utxo->S.satoshis),dstr(destsatoshis),bestsize,bestutxo); + } + } + return(bestutxo); +} + +void LP_spentnotify(struct LP_utxoinfo *utxo,int32_t selector) +{ + if ( utxo == 0 ) + return; + utxo->T.spentflag = (uint32_t)time(NULL); +} + +struct LP_utxoinfo *LP_utxofinds(int32_t iambob,bits256 txid,int32_t vout,bits256 txid2,int32_t vout2) +{ + struct LP_utxoinfo *utxo; + if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxofind(iambob,txid2,vout2)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid2,vout2)) != 0 ) + return(utxo); + else return(0); +} + +struct LP_utxoinfo *LP_utxoadd(int32_t iambob,char *symbol,bits256 txid,int32_t vout,int64_t value,bits256 txid2,int32_t vout2,int64_t value2,char *coinaddr,bits256 pubkey,char *gui,uint32_t sessionid,uint64_t satoshis) +{ + uint64_t val,val2=0,txfee; int32_t spendvini,numconfirms,selector; bits256 spendtxid; struct iguana_info *coin; struct _LP_utxoinfo u; struct LP_utxoinfo *utxo = 0; + if ( symbol == 0 || symbol[0] == 0 || coinaddr == 0 || coinaddr[0] == 0 || bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 || vout < 0 || vout2 < 0 || value <= 0 || value2 <= 0 )//|| sessionid == 0 ) + { + char str[65],str2[65]; printf("REJECT (%s) iambob.%d %s utxoadd.(%.8f %.8f) %s/v%d %s/v%d\n",coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2); + printf("session.%u addutxo %d %d %d %d %d %d %d %d\n",sessionid,symbol == 0,coinaddr == 0,bits256_nonz(txid) == 0,bits256_nonz(txid2) == 0,vout < 0,vout2 < 0,value <= 0,value2 <= 0); + return(0); + } + if ( (coin= LP_coinfind(symbol)) == 0 || (IAMLP == 0 && coin->inactive != 0) ) + { + //printf("LP_utxoadd reject inactive %s\n",symbol); + return(0); + } + txfee = LP_txfeecalc(coin,0,0); + char str[65],str2[65],dispflag = 0;//(iambob == 0); + if ( iambob == 0 && bits256_cmp(pubkey,G.LP_mypub25519) != 0 ) + { + printf("trying to add Alice utxo when not mine? %s/v%d\n",bits256_str(str,txid),vout); + return(0); + } + if ( coin->inactive == 0 ) + { + if ( LP_iseligible(&val,&val2,iambob,symbol,txid,vout,satoshis,txid2,vout2) <= 0 ) + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("iambob.%d utxoadd %s inactive.%u got ineligible txid value %.8f:%.8f, value2 %.8f:%.8f, tmpsatoshis %.8f\n",iambob,symbol,coin->inactive,dstr(value),dstr(val),dstr(value2),dstr(val2),dstr(satoshis)); + return(0); + } + if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid,vout,0)) <= 0 ) + { + printf("LP_utxoadd reject numconfirms.%d %s.%s\n",numconfirms,symbol,bits256_str(str,txid)); + return(0); + } + if ( (numconfirms= LP_numconfirms(symbol,coinaddr,txid2,vout2,0)) <= 0 ) + { + printf("LP_utxoadd reject2 numconfirms.%d %s %s/v%d\n",numconfirms,symbol,bits256_str(str,txid2),vout2); + return(0); + } + } + else + { + val = value; + val2 = value2; + } + dispflag = 0; + if ( dispflag != 0 ) + printf("%.8f %.8f %s iambob.%d %s utxoadd.(%.8f %.8f) %s %s\n",dstr(val),dstr(val2),coinaddr,iambob,symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); + dispflag = 1; + if ( (utxo= LP_utxofinds(iambob,txid,vout,txid2,vout2)) != 0 ) + { + if ( 0 && LP_ismine(utxo) == 0 ) + { + char str2[65],str3[65]; printf("iambob.%d %s %s utxoadd.(%.8f %.8f) %s %s\n",iambob,bits256_str(str3,pubkey),symbol,dstr(value),dstr(value2),bits256_str(str,txid),bits256_str(str2,txid2)); + printf("duplicate %.8f %.8f %.8f vs utxo.(%.8f %.8f %.8f)\n",dstr(value),dstr(value2),dstr(satoshis),dstr(utxo->payment.value),dstr(utxo->deposit.value),dstr(utxo->S.satoshis)); + } + u = (utxo->iambob != 0) ? utxo->deposit : utxo->fee; + if ( bits256_cmp(txid,utxo->payment.txid) != 0 || bits256_cmp(txid2,u.txid) != 0 || vout != utxo->payment.vout || value != utxo->payment.value || satoshis != utxo->S.satoshis || vout2 != u.vout || value2 != u.value || strcmp(symbol,utxo->coin) != 0 || strcmp(coinaddr,utxo->coinaddr) != 0 || bits256_cmp(pubkey,utxo->pubkey) != 0 ) + { + utxo->T.errors++; + char str[65],str2[65],str3[65],str4[65],str5[65],str6[65]; + if ( utxo->T.spentflag != 0 || LP_txvalue(0,utxo->coin,utxo->payment.txid,utxo->payment.vout) < utxo->payment.value || LP_txvalue(0,utxo->coin,u.txid,u.vout) < u.value ) + { + //if ( utxo->T.spentflag == 0 ) + // utxo->T.spentflag = (uint32_t)time(NULL); + printf("original utxo pair not valid\n"); + if ( dispflag != 0 ) + printf("error on subsequent utxo iambob.%d %.8f %.8f add.(%s %s) when.(%s %s) %d %d %d %d %d %d %d %d %d %d pubkeys.(%s vs %s)\n",iambob,dstr(val),dstr(val2),bits256_str(str,txid),bits256_str(str2,txid2),bits256_str(str3,utxo->payment.txid),bits256_str(str4,utxo->deposit.txid),bits256_cmp(txid,utxo->payment.txid) != 0,bits256_cmp(txid2,u.txid) != 0,vout != utxo->payment.vout,satoshis != utxo->S.satoshis,vout2 != u.vout,value2 != u.value,strcmp(symbol,utxo->coin) != 0,strcmp(coinaddr,utxo->coinaddr) != 0,bits256_cmp(pubkey,utxo->pubkey) != 0,value != utxo->payment.value,bits256_str(str5,pubkey),bits256_str(str6,utxo->pubkey)); + utxo = 0; + } + } + if ( utxo != 0 ) + { + if ( utxo->T.sessionid == 0 ) + utxo->T.sessionid = sessionid; + //else if ( profitmargin > SMALLVAL ) + // utxo->S.profitmargin = profitmargin; + utxo->T.lasttime = (uint32_t)time(NULL); + //printf("return existing utxo[%d] %s %s\n",iambob,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid)); + return(utxo); + } + } + utxo = calloc(1,sizeof(*utxo)); + //utxo->S.profitmargin = profitmargin; + utxo->pubkey = pubkey; + safecopy(utxo->gui,gui,sizeof(utxo->gui)); + safecopy(utxo->coin,symbol,sizeof(utxo->coin)); + safecopy(utxo->coinaddr,coinaddr,sizeof(utxo->coinaddr)); + //safecopy(utxo->spendscript,spendscript,sizeof(utxo->spendscript)); + utxo->payment.txid = txid; + utxo->payment.vout = vout; + utxo->payment.value = value; + utxo->S.satoshis = satoshis; + if ( (utxo->iambob= iambob) != 0 ) + { + utxo->deposit.txid = txid2; + utxo->deposit.vout = vout2; + utxo->deposit.value = value2; + } + else + { + utxo->fee.txid = txid2; + utxo->fee.vout = vout2; + utxo->fee.value = value2; + } + LP_utxosetkey(utxo->key,txid,vout); + LP_utxosetkey(utxo->key2,txid2,vout2); + if ( LP_ismine(utxo) > 0 ) + utxo->T.sessionid = G.LP_sessionid; + else utxo->T.sessionid = sessionid; + if ( coin->inactive == 0 && (selector= LP_mempool_vinscan(&spendtxid,&spendvini,symbol,coinaddr,txid,vout,txid2,vout2)) >= 0 ) + { + printf("utxoadd selector.%d spent in mempool %s vini.%d",selector,bits256_str(str,spendtxid),spendvini); + utxo->T.spentflag = (uint32_t)time(NULL); + } + //printf(" %s %.8f %.8f %p addutxo.%d (%s %s) session.%u iambob.%d <<<<<<<<<<<<<<< %.8f\n",symbol,dstr(value),dstr(value2),utxo,LP_ismine(utxo) > 0,bits256_str(str,utxo->payment.txid),bits256_str(str2,iambob != 0 ? utxo->deposit.txid : utxo->fee.txid),utxo->T.sessionid,iambob,dstr(satoshis)); + portable_mutex_lock(&LP_utxomutex); + HASH_ADD_KEYPTR(hh,G.LP_utxoinfos[iambob],utxo->key,sizeof(utxo->key),utxo); + if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) + HASH_ADD_KEYPTR(hh2,G.LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo); + portable_mutex_unlock(&LP_utxomutex); + if ( iambob != 0 ) + { + if ( LP_ismine(utxo) > 0 ) + { + //LP_utxo_clientpublish(utxo); + if ( LP_mypeer != 0 ) + utxo->T.lasttime = (uint32_t)time(NULL); + } + } + return(utxo); +} + +int32_t _LP_utxos_remove(bits256 txid,int32_t vout) +{ + struct LP_utxoinfo *utxo,*utxo2; int32_t retval = 0,iambob = 1; + utxo = utxo2 = 0; + if ( (utxo= _LP_utxofind(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo) == 0 ) + retval = -1; + else + { + if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo) == 0 ) + retval = -1; + else + { + _LP_utxo_delete(iambob,utxo); + _LP_utxo2_delete(iambob,utxo2); + } + } + } + } + else if ( (utxo2= _LP_utxo2find(iambob,txid,vout)) != 0 ) + { + if ( LP_isavailable(utxo2) == 0 ) + retval = -1; + else _LP_utxo2_delete(iambob,utxo2); + } + return(retval); +} + +int32_t LP_utxos_remove(bits256 txid,int32_t vout) +{ + int32_t retval; + portable_mutex_lock(&LP_utxomutex); + retval = _LP_utxos_remove(txid,vout); + portable_mutex_unlock(&LP_utxomutex); + return(retval); +} + +cJSON *LP_inventory(char *symbol) +{ + struct LP_utxoinfo *utxo,*tmp; struct _LP_utxoinfo u; char *myipaddr; cJSON *array; uint64_t val,val2; int32_t iambob = 0; struct iguana_info *coin; + array = cJSON_CreateArray(); + if ( LP_mypeer != 0 ) + myipaddr = LP_mypeer->ipaddr; + else myipaddr = "127.0.0.1"; + if ( (coin= LP_coinfind(symbol)) != 0 ) + LP_listunspent_both(symbol,coin->smartaddr,0); + HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,tmp) + { + char str[65]; + //printf("iambob.%d iterate %s\n",iambob,bits256_str(str,LP_mypub25519)); + if ( LP_isunspent(utxo) != 0 && strcmp(symbol,utxo->coin) == 0 && utxo->iambob == iambob && LP_ismine(utxo) > 0 ) + { + u = (iambob != 0) ? utxo->deposit : utxo->fee; + if ( LP_iseligible(&val,&val2,iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,u.txid,u.vout) == 0 ) + { + //if ( utxo->T.spentflag == 0 ) + // utxo->T.spentflag = (uint32_t)time(NULL); + //printf("%s %s ineligible %.8f %.8f\n",utxo->coin,bits256_str(str,u.txid),dstr(val),dstr(val2)); + continue; + } + //if ( iambob != 0 ) + // LP_utxo_clientpublish(utxo); + jaddi(array,LP_inventoryjson(cJSON_CreateObject(),utxo)); + } + else if ( 0 && LP_ismine(utxo) > 0 && strcmp(symbol,utxo->coin) == 0 ) + printf("skip %s %s %d %d %d %d\n",utxo->coin,bits256_str(str,utxo->payment.txid),LP_isunspent(utxo) != 0,strcmp(symbol,utxo->coin) == 0,utxo->iambob == iambob,LP_ismine(utxo) > 0); + } + return(array); +} + +/*while ( time(NULL) < expiration ) + { + if ( (price= LP_pricecache(qp,qp->srccoin,qp->destcoin,qp->txid,qp->vout)) > SMALLVAL ) + { + printf("break out of price %.8f %s/%s\n",price,qp->srccoin,qp->destcoin); + break; + } + sleep(1); + }*/ +//struct LP_pubkey_info *pubp,*ptmp; //cJSON *retjson; struct iguana_info *coin,*tmp; +/*HASH_ITER(hh,LP_coins,coin,tmp) // firstrefht,firstscanht,lastscanht + { + if ( coin->electrum != 0 && time(NULL) > coin->lastunspent+30 ) + { + //printf("call electrum listunspent.%s\n",coin->symbol); + if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coin->smartaddr,2)) != 0 ) + free_json(retjson); + coin->lastunspent = (uint32_t)time(NULL); + } + }*/ +/*HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) + { + pubp->dynamictrust = LP_dynamictrust(pubp->pubkey,0); + }*/ +/*void LP_prices_parse(struct LP_peerinfo *peer,cJSON *obj) + { + struct LP_pubkey_info *pubp; struct LP_priceinfo *basepp,*relpp; uint32_t timestamp; bits256 pubkey; cJSON *asks,*item; uint8_t rmd160[20]; int32_t i,n,relid,mismatch; char *base,*rel,*hexstr; double askprice; uint32_t now; + now = (uint32_t)time(NULL); + pubkey = jbits256(obj,"pubkey"); + if ( bits256_nonz(pubkey) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 ) + { + if ( (hexstr= jstr(obj,"rmd160")) != 0 && strlen(hexstr) == 2*sizeof(rmd160) ) + decode_hex(rmd160,sizeof(rmd160),hexstr); + if ( memcmp(pubp->rmd160,rmd160,sizeof(rmd160)) != 0 ) + mismatch = 1; + else mismatch = 0; + if ( bits256_cmp(pubkey,G.LP_mypub25519) == 0 && mismatch == 0 ) + peer->needping = 0; + LP_pubkey_sigcheck(pubp,obj); + timestamp = juint(obj,"timestamp"); + if ( timestamp > now ) + timestamp = now; + if ( timestamp >= pubp->timestamp && (asks= jarray(&n,obj,"asks")) != 0 ) + { + for (i=0; i 0 ) + { + if ( (basepp= LP_priceinfoptr(&relid,base,rel)) != 0 ) + { + //char str[65]; printf("gotprice %s %s/%s (%d/%d) %.8f\n",bits256_str(str,pubkey),base,rel,basepp->ind,relid,askprice); + pubp->matrix[basepp->ind][relid] = askprice; + //pubp->timestamps[basepp->ind][relid] = timestamp; + if ( (relpp= LP_priceinfofind(rel)) != 0 ) + { + dxblend(&basepp->relvals[relpp->ind],askprice,0.9); + dxblend(&relpp->relvals[basepp->ind],1. / askprice,0.9); + } + } + } + } + } + } + } + + void LP_peer_pricesquery(struct LP_peerinfo *peer) + { + char *retstr; cJSON *array; int32_t i,n; + if ( strcmp(peer->ipaddr,LP_myipaddr) == 0 ) + return; + peer->needping = (uint32_t)time(NULL); + if ( (retstr= issue_LP_getprices(peer->ipaddr,peer->port)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(array) && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ineedping != 0 ) + { + //printf("%s needs ping\n",peer->ipaddr); + } + }*/ + +if ( aliceutxo->S.swap == 0 ) +LP_availableset(aliceutxo); +return(jprint(bestitem,0)); +} +if ( 0 && (retstr= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,"")) != 0 ) +{ + if ( (array2= cJSON_Parse(retstr)) != 0 ) + { + if ( (m= cJSON_GetArraySize(array2)) > 0 ) + { + for (j=0; j %.8f n.%d\n",coinaddr,dstr(metric>>16),(uint16_t)metric); + if ( (ap= LP_addressfind(coin,coinaddr)) == 0 || _LP_unspents_metric(ap->total,ap->n) != metric ) + { + if ( ap == 0 || ap->n < (metric & 0xffff) ) + { + if ( (retstr2= issue_LP_listunspent(peer->ipaddr,peer->port,coin->symbol,coinaddr)) != 0 ) + { + if ( (array3= cJSON_Parse(retstr2)) != 0 ) + { + LP_unspents_array(coin,coinaddr,array3); + //printf("pulled.(%s)\n",retstr2); + free_json(array3); + } + free(retstr2); + } + } //else printf("wait for %s to pull %d vs %d\n",peer->ipaddr,ap!=0?ap->n:-1,(uint16_t)metric); + } + } + } + } + free_json(array2); + } + //printf("processed.(%s)\n",retstr); + free(retstr); +} +/*if ( time(NULL) > coin->lastmonitor+60 ) + { + //portable_mutex_lock(&coin->addrmutex); + HASH_ITER(hh,coin->addresses,ap,atmp) + { + if ( coin->electrum == 0 ) + { + LP_listunspent_issue(coin->symbol,ap->coinaddr); + DL_FOREACH_SAFE(ap->utxos,up,utmp) + { + if ( up->spendheight <= 0 ) + { + if ( LP_txvalue(0,coin->symbol,up->U.txid,up->U.vout) == 0 ) + up->spendheight = 1; + } + } + } + } + //portable_mutex_unlock(&coin->addrmutex); + coin->lastmonitor = (uint32_t)time(NULL); + }*/ + +/*cJSON *LP_tradecandidates(char *base) + { + struct LP_peerinfo *peer,*tmp; struct LP_quoteinfo Q; char *utxostr,coinstr[16]; cJSON *array,*retarray=0,*item; int32_t i,n,totaladded,added; + totaladded = 0; + HASH_ITER(hh,LP_peerinfos,peer,tmp) + { + printf("%s:%u %s\n",peer->ipaddr,peer->port,base); + n = added = 0; + if ( (utxostr= issue_LP_clientgetutxos(peer->ipaddr,peer->port,base,100)) != 0 ) + { + printf("%s:%u %s %s\n",peer->ipaddr,peer->port,base,utxostr); + if ( (array= cJSON_Parse(utxostr)) != 0 ) + { + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + retarray = cJSON_CreateArray(); + for (i=0; i 0 ) + { + memset(&Q,0,sizeof(Q)); + for (i=0; i 0 ) + { + printf("iterate through all locally generated quotes and update, or change to price feed\n"); + // jl777: iterated Q's + if ( strcmp(utxo->coin,"KMD") == 0 ) + LP_priceping(pubsock,utxo,"BTC",profitmargin); + else LP_priceping(pubsock,utxo,"KMD",profitmargin); + }*/ +/*if ( LP_txvalue(destaddr,symbol,searchtxid,searchvout) > 0 ) + return(0); + if ( (txobj= LP_gettx(symbol,searchtxid)) == 0 ) + return(0); + hash = jbits256(txobj,"blockhash"); + free_json(txobj); + if ( bits256_nonz(hash) == 0 ) + return(0); + if ( (blockjson= LP_getblock(symbol,hash)) == 0 ) + return(0); + loadheight = jint(blockjson,"height"); + free_json(blockjson); + if ( loadheight <= 0 ) + return(0); + while ( errs == 0 && *indp < 0 ) + { + //printf("search %s ht.%d\n",symbol,loadheight); + if ( (blockjson= LP_blockjson(&h,symbol,0,loadheight)) != 0 && h == loadheight ) + { + if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 ) + { + for (i=0; i= 0 ) + break; + } + } + free_json(blockjson); + } else errs++; + loadheight++; + } + char str[65]; printf("reached %s ht.%d %s/v%d\n",symbol,loadheight,bits256_str(str,*spendtxidp),*indp); + if ( bits256_nonz(*spendtxidp) != 0 && *indp >= 0 ) + return(loadheight); + else return(0);*/ + +/*if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i= 0 ) + return(selector); + } + }*/ + +/*int32_t LP_orderbookfind(struct LP_orderbookentry **array,int32_t num,bits256 txid,int32_t vout) + { + int32_t i; + for (i=0; ivout == vout && bits256_cmp(array[i]->txid,txid) == 0) || (array[i]->vout2 == vout && bits256_cmp(array[i]->txid2,txid) == 0) ) + return(i); + return(-1); + }*/ +//char str[65],str2[65]; printf("check utxo.%s/v%d from %s\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,bits256_str(str2,utxo->pubkey)); +//if ( strcmp(base,utxo->coin) == 0 && LP_isavailable(utxo) > 0 && pubp != 0 && (price= pubp->matrix[baseid][relid]) > SMALLVAL ) +//if ( polarity > 0 ) +// minsatoshis = utxo->S.satoshis; +//else minsatoshis = utxo->S.satoshis * price; +/*if ( LP_orderbookfind(*arrayp,cachednum,utxo->payment.txid,utxo->payment.vout) < 0 ) + { + if ( LP_iseligible(&val,&val2,utxo->iambob,utxo->coin,utxo->payment.txid,utxo->payment.vout,utxo->S.satoshis,utxo->deposit.txid,utxo->deposit.vout) == 0 ) + continue; + if ( polarity > 0 ) + basesatoshis = utxo->S.satoshis; + else basesatoshis = utxo->S.satoshis * price; + //char str[65]; printf("found utxo not in orderbook %s/v%d %.8f %.8f\n",bits256_str(str,utxo->payment.txid),utxo->payment.vout,dstr(basesatoshis),polarity > 0 ? price : 1./price); + if ( (op= LP_orderbookentry(base,rel,utxo->payment.txid,utxo->payment.vout,utxo->deposit.txid,utxo->deposit.vout,polarity > 0 ? price : 1./price,basesatoshis,utxo->pubkey,now - pubp->timestamp)) != 0 ) + { + *arrayp = realloc(*arrayp,sizeof(*(*arrayp)) * (num+1)); + (*arrayp)[num++] = op; + if ( LP_ismine(utxo) > 0 && utxo->T.lasttime == 0 ) + LP_utxo_clientpublish(utxo); + } + }*/ +void LP_price_broadcastloop(void *ctx) +{ + struct LP_priceinfo *basepp,*relpp; double price; int32_t baseind,relind; + sleep(30); + while ( 1 ) + { + for (baseind=0; baseindsymbol[0] == 0 ) + continue; + for (relind=0; relindsymbol[0] == 0 ) + continue; + if ( basepp != 0 && relpp != 0 && (price= relpp->myprices[basepp->ind]) > SMALLVAL) + { + //printf("automated price broadcast %s/%s %.8f\n",relpp->symbol,basepp->symbol,price); + LP_pricepings(ctx,LP_myipaddr,LP_mypubsock,relpp->symbol,basepp->symbol,price); + } + } + } + sleep(LP_ORDERBOOK_DURATION * .9); + } +} +/*if ( expiration != 0 ) + { + redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,expiration,G.LP_pubsecp); + if ( strcmp(depositaddr,vinaddr) == 0 ) + { + claimtime = (uint32_t)time(NULL)-777; + if ( claimtime <= expiration ) + { + printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,timestamp,(int32_t)timestamp-claimtime); + return(clonestr("{\"error\":\"need to wait to claim\"}")); + } + sum += LP_claimtx(ctx,coin,txids,utxotxid,utxovout,satoshis,vinaddr,claimtime,redeemscript,redeemlen); + + }*/ +/*timestamp = (now / LP_WEEKMULT) * LP_WEEKMULT + LP_WEEKMULT; + while ( timestamp > LP_FIRSTWEEKTIME ) + { + if ( expiration != 0 ) + timestamp = expiration; + else timestamp -= LP_WEEKMULT; + redeemlen = LP_deposit_addr(vinaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,G.LP_pubsecp); + if ( strcmp(depositaddr,vinaddr) == 0 ) + { + claimtime = (uint32_t)time(NULL)-777; + if ( claimtime <= timestamp ) + { + printf("claimtime.%u vs locktime.%u, need to wait %d seconds\n",claimtime,timestamp,(int32_t)timestamp-claimtime); + } + else + { + printf("found %s at timestamp.%u\n",vinaddr,timestamp); + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_listunspent(coin->symbol,vinaddr,zero,zero)) != 0 ) + { + //printf("unspents.(%s)\n",jprint(array,0)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 ) + { + for (i=0; i> 1; + if ( cipherlen <= sizeof(cipher) ) + { + decode_hex(cipher,cipherlen,cipherstr); + LP_queuesend(calc_crc32(0,&cipher[2],cipherlen-2),LP_mypubsock,base,rel,cipher,cipherlen); + } else retstr = clonestr("{\"error\":\"cipher too big\"}"); + } + else + { + memset(zero.bytes,0,sizeof(zero)); + //printf("broadcast.(%s)\n",Broadcaststr); + LP_reserved_msg(base!=0?base:jstr(argjson,"coin"),rel,zero,jprint(reqjson,0)); + } + retstr = clonestr("{\"result\":\"success\"}"); + } else retstr = clonestr("{\"error\":\"couldnt dereference sendmessage\"}"); + } + else*/ + +/*relvol = bot->totalrelvolume * .1; + p = LP_pricevol_invert(&v,bot->maxprice,relvol); + if ( bot->dispdir > 0 ) + { + printf("simulated trade buy %s/%s maxprice %.8f volume %.8f, %.8f %s -> %s, price %.8f relvol %.8f\n",bot->base,bot->rel,bot->maxprice,bot->totalrelvolume - bot->relsum,relvol,bot->rel,bot->base,bot->maxprice,relvol); + } + else + { + minprice = LP_pricevol_invert(&basevol,bot->maxprice,bot->totalrelvolume - bot->relsum); + printf("simulated trade sell %s/%s minprice %.8f volume %.8f, %.8f %s -> %s price %.8f relvol %.8f\n",bot->rel,bot->base,minprice,basevol,v,bot->base,bot->rel,p,relvol); + } + if ( (LP_rand() % 2) == 0 ) + { + bot->relsum += relvol; + bot->basesum += v; + bot->completed++; + } + else + { + bot->pendrelsum += relvol; + bot->pendbasesum += v; + bot->numpending++; + } + bot->numtrades++; + */ +#ifdef FROM_JS +int32_t sentbytes,sock,peerind,maxind; +if ( (maxind= LP_numpeers()) > 0 ) +peerind = (LP_rand() % maxind) + 1; +else peerind = 1; +sock = LP_peerindsock(&peerind); +if ( sock >= 0 ) +{ + if ( (sentbytes= nn_send(sock,msg,msglen,0)) != msglen ) + printf("LP_send sent %d instead of %d\n",sentbytes,msglen); + else printf("sent %d bytes of %d to sock.%d\n",sentbytes,msglen,sock); + } else printf("couldnt get valid sock\n"); +#else + +void _LP_queuesend(uint32_t crc32,int32_t sock0,int32_t sock1,uint8_t *msg,int32_t msglen,int32_t needack) +{ + int32_t maxind,peerind = 0; //sentbytes, + if ( sock0 >= 0 || sock1 >= 0 ) + { + /* if ( sock0 >= 0 && LP_sockcheck(sock0) > 0 ) + { + if ( (sentbytes= nn_send(sock0,msg,msglen,0)) != msglen ) + printf("_LP_queuesend0 sent %d instead of %d\n",sentbytes,msglen); + else + { + printf("Q sent %u msglen.%d (%s)\n",crc32,msglen,msg); + sock0 = -1; + } + } + if ( sock1 >= 0 && LP_sockcheck(sock1) > 0 ) + { + if ( (sentbytes= nn_send(sock1,msg,msglen,0)) != msglen ) + printf("_LP_queuesend1 sent %d instead of %d\n",sentbytes,msglen); + else + { + printf("Q sent1 %u msglen.%d (%s)\n",crc32,msglen,msg); + sock1 = -1; + } + } + if ( sock0 < 0 && sock1 < 0 ) + return;*/ + } + else + { + if ( (maxind= LP_numpeers()) > 0 ) + peerind = (LP_rand() % maxind) + 1; + else peerind = 1; + sock0 = LP_peerindsock(&peerind); + if ( (maxind= LP_numpeers()) > 0 ) + peerind = (LP_rand() % maxind) + 1; + else peerind = 1; + sock1 = LP_peerindsock(&peerind); + } + if ( sock0 >= 0 ) + _LP_sendqueueadd(crc32,sock0,msg,msglen,needack * peerind); + if ( sock1 >= 0 ) + _LP_sendqueueadd(crc32,sock1,msg,msglen,needack); +} + +if ( 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_price_broadcastloop,(void *)ctx) != 0 ) +{ + printf("error launching LP_swapsloop for port.%u\n",myport); + exit(-1); +} +void LP_queuesend(uint32_t crc32,int32_t pubsock,char *base,char *rel,uint8_t *msg,int32_t msglen) +{ + //struct iguana_info *coin; int32_t flag=0,socks[2]; + portable_mutex_lock(&LP_networkmutex); + if ( pubsock >= 0 ) + { + //socks[0] = socks[1] = -1; + //if ( rel != 0 && rel[0] != 0 && (coin= LP_coinfind(rel)) != 0 && coin->bussock >= 0 ) + // socks[flag++] = coin->bussock; + //if ( base != 0 && base[0] != 0 && (coin= LP_coinfind(base)) != 0 && coin->bussock >= 0 ) + // socks[flag++] = coin->bussock; + //if ( flag == 0 && pubsock >= 0 ) + _LP_queuesend(crc32,pubsock,-1,msg,msglen,0); + //else _LP_queuesend(socks[0],socks[1],msg,msglen,0); + } else _LP_queuesend(crc32,-1,-1,msg,msglen,1); + portable_mutex_unlock(&LP_networkmutex); +} +#ifdef oldway +struct LP_utxoinfo *LP_bestutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,uint64_t maxdestsatoshis) +{ + int64_t satoshis,destsatoshis; uint64_t val,val2; bits256 txid,pubkey; char *obookstr; cJSON *orderbook,*asks,*item; struct LP_utxoinfo *butxo,*bestutxo = 0; int32_t i,n,j,vout,numasks; double bestmetric=0.,metric,vol,price,qprice,bestprice = 0.; struct LP_pubkeyinfo *pubp; + *ordermatchpricep = 0.; + *bestsatoshisp = *bestdestsatoshisp = 0; + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + if ( maxprice <= 0. || LP_priceinfofind(base) == 0 ) + return(0); + LP_txfees(&txfee,&desttxfee,base,autxo->coin); + if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) + { + if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) + { + if ( (asks= jarray(&numasks,orderbook,"asks")) != 0 ) + { + for (i=0; i 0 && price <= maxprice ) + { + //price *= 1.0001; + //if ( price > maxprice ) + // price = maxprice; + pubkey = jbits256(item,"pubkey"); + if ( bits256_cmp(pubkey,LP_mypub25519) != 0 && (pubp= LP_pubkeyadd(pubkey)) != 0 && pubp->numerrors < LP_MAXPUBKEY_ERRORS ) + { + if ( bestprice == 0. ) // assumes price ordered asks + bestprice = price; + printf("item.[%d] %s\n",i,jprint(item,0)); + txid = jbits256(item,"txid"); + vout = jint(item,"vout"); + vol = jdouble(item,"volume"); + metric = price / bestprice; + printf("maxdest %.8f metric %f vol %f add pings numutxos.%d min %.8f max %.8f\n",dstr(maxdestsatoshis),metric,vol,jint(item,"numutxos"),jdouble(item,"minvolume"),jdouble(item,"maxvolume")); + // check utxos > 1 for pubkey, SPV validate recv'ed + /*if ( (butxo= LP_utxofind(1,txid,vout)) != 0 && (long long)(vol*SATOSHIDEN) == butxo->S.satoshis && LP_isavailable(butxo) > 0 && LP_ismine(butxo) == 0 && butxo->T.bestflag == 0 ) + { + printf("got butxo? %p\n",butxo); + if ( LP_iseligible(&val,&val2,butxo->iambob,butxo->coin,butxo->payment.txid,butxo->payment.vout,butxo->S.satoshis,butxo->deposit.txid,butxo->deposit.vout) > 0 ) + { + destsatoshis = ((butxo->S.satoshis - txfee) * price); + satoshis = (destsatoshis / price + 0.49) - txfee; + if ( satoshis <= 0 ) + continue; + qprice = (double)destsatoshis / satoshis; + n = (int32_t)((double)destsatoshis / desttxfee); + if ( n < 10 ) + n = 10; + else n = 3; + for (j=0; jS.satoshis,txfee,autxo->payment.value,maxdestsatoshis,desttxfee)) > price+SMALLVAL ) + break; + } + //printf("j.%d/%d qprice %.8f vs price %.8f best.(%.8f %.8f)\n",j,n,qprice,price,dstr(satoshis),dstr(destsatoshis)); + if ( metric < 1.2 && destsatoshis > desttxfee && destsatoshis-desttxfee > (autxo->payment.value / LP_MINCLIENTVOL) && satoshis-txfee > (butxo->S.satoshis / LP_MINVOL) && satoshis <= butxo->payment.value-txfee ) + { + printf("value %.8f price %.8f/%.8f best %.8f destsatoshis %.8f * metric %.8f -> (%f)\n",dstr(autxo->payment.value),price,bestprice,bestmetric,dstr(destsatoshis),metric,dstr(destsatoshis) * metric * metric * metric); + metric = dstr(destsatoshis) * metric * metric * metric; + if ( bestmetric == 0. || metric < bestmetric ) + { + bestutxo = butxo; + *ordermatchpricep = price; + *bestdestsatoshisp = destsatoshis; + *bestsatoshisp = satoshis; + bestmetric = metric; + printf("set best!\n"); + } + } // else printf("skip.(%d %d %d %d %d) metric %f destsatoshis %.8f value %.8f destvalue %.8f txfees %.8f %.8f sats %.8f\n",metric < 1.2,destsatoshis > desttxfee,destsatoshis-desttxfee > (autxo->payment.value / LP_MINCLIENTVOL),satoshis-txfee > (butxo->S.satoshis / LP_MINVOL),satoshis < butxo->payment.value-txfee,metric,dstr(destsatoshis),dstr(butxo->S.satoshis),dstr(autxo->payment.value),dstr(txfee),dstr(desttxfee),dstr(satoshis)); + } + else + { + printf("ineligible.(%.8f %.8f)\n",price,dstr(butxo->S.satoshis)); + //if ( butxo->T.spentflag == 0 ) + // butxo->T.spentflag = (uint32_t)time(NULL); + } + } + else + { + if ( butxo != 0 ) + printf("%llu %llu %d %d %d: ",(long long)(vol*SATOSHIDEN),(long long)butxo->S.satoshis,vol*SATOSHIDEN == butxo->S.satoshis,LP_isavailable(butxo) > 0,LP_ismine(butxo) == 0); + printf("cant find butxo.%p or value mismatch %.8f != %.8f or bestflag.%d\n",butxo,vol,butxo!=0?dstr(butxo->S.satoshis):0,butxo->T.bestflag); + }*/ + } else printf("self trading or blacklisted peer\n"); + } + else + { + if ( i == 0 ) + printf("maxprice %.8f vs %.8f\n",maxprice,price); + break; + } + } + if ( bestutxo == 0 ) + { + int32_t numrestraints; + for (i=numrestraints=0; iT.bestflag = 0; + //pubp->numerrors = 0; + } + } + } + printf("no bob utxo found -> cleared %d restraints\n",numrestraints); + } + } + free_json(orderbook); + } + free(obookstr); + } + printf("bestutxo.%p %.8f %.8f\n",bestutxo,*ordermatchpricep,dstr(*bestdestsatoshisp)); + if ( bestutxo == 0 || *ordermatchpricep == 0. || *bestdestsatoshisp == 0 ) + return(0); + bestutxo->T.bestflag = 1; + int32_t changed; + LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep); + return(bestutxo); +} +if ( (0) ) +{ + ep = LP_electrum_info(&already,"BTC","88.198.241.196",50001,IGUANA_MAXPACKETSIZE * 10); + if ( ep != 0 && OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_dedicatedloop,(void *)ep) != 0 ) + { + printf("error launching LP_dedicatedloop (%s:%u)\n",ep->ipaddr,ep->port); + exit(-1); + } else printf("launched.(%s:%u)\n",ep->ipaddr,ep->port); + electrum_test(); + } + +/*static int _LP_metric_eval(const void *a,const void *b) + { + #define aptr (*(struct LP_metricinfo **)a) + #define bptr (*(struct LP_metricinfo **)b) + if ( bptr->metric > aptr->metric ) + return(1); + else if ( bptr->metric < aptr->metric ) + return(-1); + return(0); + #undef aptr + #undef bptr + }*/ +/*if ( (utxo= LP_utxoadd(1,coin->symbol,up->U.txid,up->U.vout,up->U.value,up2->U.txid,up2->U.vout,up2->U.value,coinaddr,ap->pubkey,G.gui,0,targetval)) != 0 ) + { + utxo->S.satoshis = targetval; + char str[65],str2[65]; printf("butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s\n",utxo,dstr(targetval),dstr(up->U.value),bits256_str(str,utxo->payment.txid),dstr(targetval2),dstr(up2->U.value),bits256_str(str2,utxo->deposit.txid)); + return(butxo); + }*/ + +/*if ( (sobj= jobj(v,"scriptPubKey")) != 0 ) + { + if ( (scriptstr= jstr(sobj,"hex")) != 0 ) + { + printf("amount64 %.8f vout.%d (%s) weeki.%d %.8f (%s)\n",dstr(amount64),vout,jprint(v,0),weeki,dstr(satoshis),scriptstr); + len = (int32_t)strlen(scriptstr) >> 1; + if ( len <= sizeof(spendscript)/sizeof(*spendscript) ) + { + decode_hex(spendscript,len,scriptstr); + if ( spendscript[11] == 33 ) + { + pub33 = &spendscript[12]; + redeemlen = LP_deposit_addr(p2shaddr,redeemscript,coin->taddr,coin->p2shtype,timestamp,pub33); + if ( len == redeemlen && (timestamp % LP_WEEKMULT) == 0 ) + { + bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pub33,33); + printf("%s -> matched %s script t.%u weeki.%d deposit %.8f\n",coinaddr,p2shaddr,timestamp,(timestamp-LP_FIRSTWEEKTIME)/LP_WEEKMULT,dstr(satoshis)); + // add to pubp->credits; + } + } + } + } + }*/ + +/*portable_mutex_lock(&ep->pendingQ.mutex); + if ( ep->pendingQ.list != 0 ) + { + printf("list %p\n",ep->pendingQ.list); + DL_FOREACH_SAFE(ep->pendingQ.list,item,tmp) + { + printf("item.%p\n",item); + if ( item->type == 0xffffffff ) + { + printf("%p purge %s",item,((struct stritem *)item)->str); + DL_DELETE(ep->pendingQ.list,item); + free(item); + } + } + } + DL_APPEND(ep->pendingQ.list,&sitem->DL); + portable_mutex_unlock(&ep->pendingQ.mutex);*/ +//printf("%p SENT.(%s) to %s:%u\n",sitem,sitem->str,ep->ipaddr,ep->port); + +#ifdef oldway +struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t max,double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct iguana_info *basecoin,char *coinaddr,uint64_t asatoshis,double price,uint64_t txfee,uint64_t desttxfee,bits256 pubkey,char *gui) +{ + uint64_t basesatoshis; struct LP_utxoinfo *bestutxo; + basesatoshis = LP_basesatoshis(dstr(asatoshis),price,txfee,desttxfee); + //printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee)); + if ( basesatoshis != 0 && (bestutxo= LP_address_utxopair(0,utxos,max,basecoin,coinaddr,txfee,dstr(basesatoshis)*price,price,desttxfee)) != 0 ) + { + bestutxo->pubkey = pubkey; + safecopy(bestutxo->gui,gui,sizeof(bestutxo->gui)); + *bestsatoshisp = basesatoshis; + *ordermatchpricep = price; + *bestdestsatoshisp = asatoshis; + return(bestutxo); + } + return(0); +} + +struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,int64_t *bestdestsatoshisp,struct LP_utxoinfo *autxo,char *base,double maxprice,int32_t duration,uint64_t txfee,uint64_t desttxfee,char *gui,bits256 *avoids,int32_t numavoids,bits256 destpubkey) +{ + bits256 pubkey; char *obookstr,coinaddr[64]; cJSON *orderbook,*asks,*rawasks,*item; int32_t maxiters,i,j,numasks,max; struct LP_address_utxo **utxos; double price; struct LP_pubkey_info *pubp; uint64_t asatoshis; struct iguana_info *basecoin; struct LP_utxoinfo *bestutxo = 0; + maxiters = 100; + *ordermatchpricep = 0.; + *bestsatoshisp = *bestdestsatoshisp = 0; + basecoin = LP_coinfind(base); + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + if ( maxprice <= 0. || LP_priceinfofind(base) == 0 || basecoin == 0 ) + return(0); + if ( basecoin->electrum == 0 ) + max = 1000; + else max = LP_MAXDESIRED_UTXOS; + utxos = calloc(max,sizeof(*utxos)); + LP_txfees(&txfee,&desttxfee,base,autxo->coin); + printf("LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee)); + if ( (obookstr= LP_orderbook(base,autxo->coin,duration)) != 0 ) + { + if ( (orderbook= cJSON_Parse(obookstr)) != 0 ) + { + if ( (rawasks= jarray(&numasks,orderbook,"asks")) != 0 ) + { + if ( (asks= LP_RTmetrics_sort(base,autxo->coin,rawasks,numasks,maxprice,dstr(autxo->S.satoshis))) == 0 ) + asks = rawasks; + for (i=0; i maxprice*0.8) + // price = price * 0.9 + 0.1 * maxprice; + //else price *= 1.005; + pubkey = jbits256(item,"pubkey"); + if ( bits256_nonz(destpubkey) != 0 && bits256_cmp(destpubkey,pubkey) != 0 ) + continue; + if ( LP_RTmetrics_blacklisted(pubkey) >= 0 ) + continue; + //printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis)); + if ( LP_pricevalid(price) > 0 && price <= maxprice ) + { + if ( bits256_nonz(destpubkey) == 0 ) + { + for (j=0; jtaddr,basecoin->pubtype,pubp->rmd160,sizeof(pubp->rmd160)); + asatoshis = autxo->S.satoshis; + //LP_listunspent_query(base,coinaddr); + for (j=0; jpubkey,gui)) != 0 ) + { + //printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee)); + break; + } + asatoshis = (asatoshis / 64) * 63; + } + if ( j < maxiters ) + break; + } else printf("self trading or blacklisted peer\n"); + } + else + { + if ( i == 0 ) + printf("too expensive maxprice %.8f vs %.8f\n",maxprice,price); + break; + } + } + if ( asks != 0 && asks != rawasks ) + free_json(asks); + } + free_json(orderbook); + } + free(obookstr); + } + free(utxos); + if ( *ordermatchpricep == 0. || *bestdestsatoshisp == 0 ) + return(0); + int32_t changed; + LP_mypriceset(&changed,autxo->coin,base,1. / *ordermatchpricep); + return(bestutxo); +} +#endif +#ifdef oldway +//LP_RTmetrics_update(base,rel); +while ( 1 ) +{ + if ( (bestutxo= LP_buyutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,gui,pubkeys,numpubs,destpubkey)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + { + printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis)); + return(clonestr("{\"error\":\"cant find ordermatch utxo, need to change relvolume to be closer to available\"}")); + } + pubkeys[numpubs++] = bestutxo->pubkey; + if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); + if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,G.LP_mypub25519,autxo->coinaddr) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); + maxiters = 200; + qprice = 1. / SMALLVAL; + for (i=0; i maxprice ) + { + printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f, no acceptable quote for this pubkey\n",i,maxiters,dstr(qprice),dstr(maxprice)); + if ( bits256_nonz(destpubkey) == 0 ) + continue; + else return(clonestr("{\"error\":\"cant ordermatch to destpubkey\"}")); + } + printf("i.%d maxiters.%d qprice %.8f vs maxprice %.8f\n",i,maxiters,dstr(qprice),dstr(maxprice)); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration,tradeid,destpubkey)); +} +return(clonestr("{\"error\":\"cant get here\"}")); +#endif + +if ( 0 ) +{ + char *p2sh = "bJVtQF2o8B6sdNjeXupzNw5rnidJUNwPJD",p2shaddr[64]; uint8_t script[512],pub33[33]; uint32_t timestamp; + decode_hex(pub33,33,"03fe754763c176e1339a3f62ee6b9484720e17ee4646b65a119e9f6370c7004abc"); + for (timestamp=1510934803-3600*24; timestamp<1510934803+3600*24; timestamp++) + { + LP_deposit_addr(p2shaddr,script,0,85,timestamp,pub33); + if ( strcmp(p2shaddr,p2sh) == 0 ) + { + printf("matched timestamp.%u\n",timestamp); + break; + } else printf("%s ",p2shaddr); + } +} + +/*DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->spendheight <= 0 ) + { + if ( up->U.value > *maxp ) + *maxp = up->U.value; + if ( *minp == 0 || up->U.value < *minp ) + *minp = up->U.value; + *balancep += up->U.value; + n++; + } + }*/ + +char *LP_ordermatch(char *base,int64_t txfee,double maxprice,double maxvolume,char *rel,bits256 txid,int32_t vout,bits256 feetxid,int32_t feevout,int64_t desttxfee,int32_t duration) +{ + struct LP_quoteinfo Q; int64_t bestsatoshis=0,bestdestsatoshis = 0; double ordermatchprice = 0.; struct LP_utxoinfo *autxo,*bestutxo; + txfee = LP_txfeecalc(LP_coinfind(base),txfee); + desttxfee = LP_txfeecalc(LP_coinfind(rel),desttxfee); + if ( (autxo= LP_utxopairfind(0,txid,vout,feetxid,feevout)) == 0 ) + return(clonestr("{\"error\":\"cant find alice utxopair\"}")); + if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,SATOSHIDEN*maxvolume)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); + if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); + if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypub25519,autxo->coinaddr) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); + return(jprint(LP_quotejson(&Q),1)); +} + +char *LP_autotrade(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel,double maxprice,double relvolume,int32_t timeout,int32_t duration) +{ + uint64_t desttxfee,txfee; int64_t bestsatoshis=0,bestdestsatoshis=0; struct LP_utxoinfo *autxo,*butxo,*bestutxo = 0; double qprice,ordermatchprice=0.; struct LP_quoteinfo Q; + if ( duration <= 0 ) + duration = LP_ORDERBOOK_DURATION; + if ( timeout <= 0 ) + timeout = LP_AUTOTRADE_TIMEOUT; + if ( maxprice <= 0. || relvolume <= 0. || LP_priceinfofind(base) == 0 || LP_priceinfofind(rel) == 0 ) + return(clonestr("{\"error\":\"invalid parameter\"}")); + if ( (autxo= LP_utxo_bestfit(rel,SATOSHIDEN * relvolume)) == 0 ) + return(clonestr("{\"error\":\"cant find utxo that is big enough\"}")); + LP_txfees(&txfee,&desttxfee,base,rel); + if ( (bestutxo= LP_bestutxo(&ordermatchprice,&bestsatoshis,&bestdestsatoshis,autxo,base,maxprice,duration,txfee,desttxfee,SATOSHIDEN*relvolume)) == 0 || ordermatchprice == 0. || bestdestsatoshis == 0 ) + { + printf("bestutxo.%p ordermatchprice %.8f bestdestsatoshis %.8f\n",bestutxo,ordermatchprice,dstr(bestdestsatoshis)); + return(clonestr("{\"error\":\"cant find ordermatch utxo\"}")); + } + if ( LP_quoteinfoinit(&Q,bestutxo,rel,ordermatchprice,bestsatoshis,bestdestsatoshis) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote\"}")); + if ( LP_quotedestinfo(&Q,autxo->payment.txid,autxo->payment.vout,autxo->fee.txid,autxo->fee.vout,LP_mypub25519,autxo->coinaddr) < 0 ) + return(clonestr("{\"error\":\"cant set ordermatch quote info\"}")); + if ( (qprice= LP_quote_validate(&autxo,&butxo,&Q,0)) <= SMALLVAL ) + { + printf("quote validate error %.0f\n",qprice); + return(clonestr("{\"error\":\"quote validation error\"}")); + } + printf("do quote.(%s)\n",jprint(LP_quotejson(&Q),1)); + return(LP_trade(ctx,myipaddr,mypubsock,&Q,maxprice,timeout,duration)); +} +#endif + + diff --git a/iguana/exchanges/LP_stats.c b/iguana/exchanges/LP_stats.c new file mode 100644 index 000000000..87ce4a6e4 --- /dev/null +++ b/iguana/exchanges/LP_stats.c @@ -0,0 +1,946 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_stats.c +// marketmaker +// + +#define LP_STATSLOG_FNAME "stats.log" + +struct LP_swapstats *LP_swapstats,*LP_RTstats; +int32_t LP_statslog_parsequote(char *method,cJSON *lineobj); + +char *LP_stats_methods[] = { "unknown", "request", "reserved", "connect", "connected", "tradestatus" }; +#define LP_TRADESTATUS_METHODIND 5 + +static uint32_t LP_requests,LP_reserveds,LP_connects,LP_connecteds,LP_tradestatuses,LP_parse_errors,LP_unknowns,LP_duplicates,LP_aliceids; + +void LP_dPoW_request(struct iguana_info *coin) +{ + bits256 zero; cJSON *reqjson; + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","getdPoW"); + jaddstr(reqjson,"coin",coin->symbol); + memset(zero.bytes,0,sizeof(zero)); + //printf("request %s\n",jprint(reqjson,0)); + LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); +} + +void LP_dPoW_broadcast(struct iguana_info *coin) +{ + bits256 zero; cJSON *reqjson; + if ( time(NULL) > coin->dPoWtime+60 && (coin->isassetchain != 0 || strcmp(coin->symbol,"KMD") == 0) ) + { + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","dPoW"); + jaddstr(reqjson,"coin",coin->symbol); + jaddnum(reqjson,"notarized",coin->notarized); + jaddbits256(reqjson,"notarizedhash",coin->notarizedhash); + jaddbits256(reqjson,"notarizationtxid",coin->notarizationtxid); + memset(zero.bytes,0,sizeof(zero)); + //printf("broadcast %s\n",jprint(reqjson,0)); + LP_reserved_msg(0,coin->symbol,coin->symbol,zero,jprint(reqjson,1)); + coin->dPoWtime = (uint32_t)time(NULL); + } +} + +char *LP_dPoW_recv(cJSON *argjson) +{ + int32_t notarized; bits256 notarizedhash,notarizationtxid; char *symbol; struct iguana_info *coin; + if ( (symbol= jstr(argjson,"coin")) != 0 && (coin= LP_coinfind(symbol)) != 0 && coin->electrum != 0 ) + { + notarized = jint(argjson,"notarized"); + notarizedhash = jbits256(argjson,"notarizedhash"); + notarizationtxid = jbits256(argjson,"notarizationtxid"); + //printf("dPoW %s\n",jprint(argjson,0)); + if ( notarized > coin->notarized && LP_notarization_validate(symbol,notarized,notarizedhash,notarizationtxid) == 0 ) + { + coin->notarized = notarized; + coin->notarizedhash = notarizedhash; + coin->notarizationtxid = notarizationtxid; + printf("VALIDATED dPoW %s\n",jprint(argjson,0)); + } + } + return(clonestr("{\"result\":\"success\"}")); +} + +/*int32_t LP_dPoWheight(struct iguana_info *coin) // get dPoW protected height +{ + int32_t notarized,oldnotarized; + if ( coin->electrum == 0 ) + { + coin->heighttime = (uint32_t)(time(NULL) - 61); + oldnotarized = coin->notarized; + LP_getheight(¬arized,coin); + if ( notarized != 0 && notarized != oldnotarized ) + { + printf("dPoWheight.%s %d <- %d\n",coin->symbol,oldnotarized,notarized); + coin->notarized = notarized; + } + } + else if ( coin->notarized == 0 ) + LP_dPoW_request(coin); + return(coin->notarized); +}*/ + +void LP_tradecommand_log(cJSON *argjson) +{ + static FILE *logfp; char *jsonstr; + if ( logfp == 0 ) + { +#ifndef _WIN32 + if ( (logfp= fopen(LP_STATSLOG_FNAME,"rb+")) != 0 ) + fseek(logfp,0,SEEK_END); + else +#endif + logfp = fopen(LP_STATSLOG_FNAME,"wb"); + } + if ( logfp != 0 ) + { + jsonstr = jprint(argjson,0); + fprintf(logfp,"%s\n",jsonstr); + free(jsonstr); + fflush(logfp); + } +} + +void LP_statslog_parseline(cJSON *lineobj) +{ + char *method; cJSON *obj; + if ( (method= jstr(lineobj,"method")) != 0 ) + { + if ( strcmp(method,"request") == 0 ) + LP_requests++; + else if ( strcmp(method,"reserved") == 0 ) + LP_reserveds++; + else if ( strcmp(method,"connect") == 0 ) + { + if ( (obj= jobj(lineobj,"trade")) == 0 ) + obj = lineobj; + LP_statslog_parsequote(method,obj); + LP_connects++; + } + else if ( strcmp(method,"connected") == 0 ) + { + LP_statslog_parsequote(method,lineobj); + LP_connecteds++; + } + else if ( strcmp(method,"tradestatus") == 0 ) + { + LP_statslog_parsequote(method,lineobj); + LP_tradestatuses++; + } + else + { + LP_unknowns++; + printf("parseline unknown method.(%s) (%s)\n",method,jprint(lineobj,0)); + } + } else printf("parseline no method.(%s)\n",jprint(lineobj,0)); +} + +int32_t LP_statslog_parse() +{ + static long lastpos; + FILE *fp; long fpos; char line[8192]; cJSON *lineobj; int32_t c,n = 0; + if ( (fp= fopen(LP_STATSLOG_FNAME,"rb")) != 0 ) + { + if ( lastpos > 0 ) + { + fseek(fp,0,SEEK_END); + if ( ftell(fp) >= lastpos ) + fseek(fp,lastpos,SEEK_SET); + else + { + fclose(fp); + return(0); + } + } + else if ( 1 ) + { + if ( IAMLP == 0 ) + { + fseek(fp,0,SEEK_END); + if ( (fpos= ftell(fp)) > LP_CLIENT_STATSPARSE ) + { + fseek(fp,fpos-LP_CLIENT_STATSPARSE,SEEK_SET); + while ( (c= fgetc(fp)) >= 0 && c != '\n' ) + ; + printf("start scanning %s from %ld, found boundary %ld\n",LP_STATSLOG_FNAME,fpos-LP_CLIENT_STATSPARSE,ftell(fp)); + } else rewind(fp); + } + } + while ( fgets(line,sizeof(line),fp) > 0 ) + { + lastpos = ftell(fp); + if ( (lineobj= cJSON_Parse(line)) != 0 ) + { + n++; + LP_statslog_parseline(lineobj); + //printf("%s\n",jprint(lineobj,0)); + free_json(lineobj); + } + } + fclose(fp); + } + return(n); +} + +struct LP_swapstats *LP_swapstats_find(uint64_t aliceid) +{ + struct LP_swapstats *sp; + portable_mutex_lock(&LP_statslogmutex); + HASH_FIND(hh,LP_RTstats,&aliceid,sizeof(aliceid),sp); + if ( sp == 0 ) + HASH_FIND(hh,LP_swapstats,&aliceid,sizeof(aliceid),sp); + portable_mutex_unlock(&LP_statslogmutex); + return(sp); +} + +struct LP_swapstats *LP_swapstats_add(uint64_t aliceid,int32_t RTflag) +{ + struct LP_swapstats *sp; + if ( (sp= LP_swapstats_find(aliceid)) == 0 ) + { + sp = calloc(1,sizeof(*sp)); + sp->aliceid = aliceid; + portable_mutex_lock(&LP_statslogmutex); + if ( RTflag != 0 ) + HASH_ADD(hh,LP_RTstats,aliceid,sizeof(aliceid),sp); + else HASH_ADD(hh,LP_swapstats,aliceid,sizeof(aliceid),sp); + portable_mutex_unlock(&LP_statslogmutex); + } + return(LP_swapstats_find(aliceid)); +} + +uint64_t LP_aliceid_calc(bits256 desttxid,int32_t destvout,bits256 feetxid,int32_t feevout) +{ + return((((uint64_t)desttxid.uints[0] << 48) | ((uint64_t)destvout << 32) | ((uint64_t)feetxid.uints[0] << 16) | (uint32_t)feevout)); +} + +void LP_swapstats_line(int32_t *numtrades,uint64_t *basevols,uint64_t *relvols,char *line,struct LP_swapstats *sp) +{ + char tstr[64]; int32_t baseind,relind; + if ( (baseind= LP_priceinfoind(sp->Q.srccoin)) >= 0 ) + basevols[baseind] += sp->Q.satoshis, numtrades[baseind]++; + if ( (relind= LP_priceinfoind(sp->Q.destcoin)) >= 0 ) + relvols[relind] += sp->Q.destsatoshis, numtrades[relind]++; + sprintf(line,"%s (%s).(%s) %-4d %9s %22llu: (%.8f %5s) -> (%.8f %5s) %.8f finished.%u expired.%u",utc_str(tstr,sp->Q.timestamp),sp->alicegui,sp->bobgui,sp->ind,LP_stats_methods[sp->methodind],(long long)sp->aliceid,dstr(sp->Q.satoshis),sp->Q.srccoin,dstr(sp->Q.destsatoshis),sp->Q.destcoin,sp->qprice,sp->finished,sp->expired); +} + +bits256 LP_swapstats_txid(cJSON *argjson,char *name,bits256 oldtxid) +{ + bits256 txid,deadtxid; + decode_hex(deadtxid.bytes,32,"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + txid = jbits256(argjson,name); + if ( bits256_nonz(txid) != 0 ) + { + if ( bits256_cmp(deadtxid,txid) == 0 ) + { + if ( bits256_nonz(oldtxid) == 0 ) + return(deadtxid); + else return(oldtxid); + } else return(txid); + } else return(oldtxid); +} + +int32_t LP_swapstats_update(struct LP_swapstats *sp,struct LP_quoteinfo *qp,cJSON *lineobj) +{ + char *statusstr,*base,*rel,gui[64]; uint32_t requestid,quoteid; uint64_t satoshis,destsatoshis; + sp->lasttime = (uint32_t)time(NULL); + safecopy(gui,sp->Q.gui,sizeof(gui)); + if ( strcmp(LP_stats_methods[sp->methodind],"tradestatus") == 0 ) + { + base = jstr(lineobj,"bob"); + rel = jstr(lineobj,"alice"); + requestid = juint(lineobj,"requestid"); + quoteid = juint(lineobj,"quoteid"); + satoshis = jdouble(lineobj,"srcamount") * SATOSHIDEN; + destsatoshis = jdouble(lineobj,"destamount") * SATOSHIDEN; + if ( base != 0 && strcmp(base,sp->Q.srccoin) == 0 && rel != 0 && strcmp(rel,sp->Q.destcoin) == 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid && llabs((int64_t)(satoshis+2*sp->Q.txfee) - (int64_t)sp->Q.satoshis) <= sp->Q.txfee && llabs((int64_t)(destsatoshis+2*sp->Q.desttxfee) - (int64_t)sp->Q.destsatoshis) <= sp->Q.desttxfee ) + { + sp->bobdeposit = LP_swapstats_txid(lineobj,"bobdeposit",sp->bobdeposit); + sp->alicepayment = LP_swapstats_txid(lineobj,"alicepayment",sp->alicepayment); + sp->bobpayment = LP_swapstats_txid(lineobj,"bobpayment",sp->bobpayment); + sp->paymentspent = LP_swapstats_txid(lineobj,"paymentspent",sp->paymentspent); + sp->Apaymentspent = LP_swapstats_txid(lineobj,"Apaymentspent",sp->Apaymentspent); + sp->depositspent = LP_swapstats_txid(lineobj,"depositspent",sp->depositspent); + if ( (statusstr= jstr(lineobj,"status")) != 0 && strcmp(statusstr,"finished") == 0 ) + { + if ( (sp->finished= juint(lineobj,"timestamp")) == 0 ) + sp->finished = (uint32_t)time(NULL); + } + if ( sp->finished == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(base,rel)*2 ) + sp->expired = (uint32_t)time(NULL); + return(0); + } + else + { + if ( 0 && requestid == sp->Q.R.requestid && quoteid == sp->Q.R.quoteid ) + printf("mismatched tradestatus aliceid.%22llu b%s/%s r%s/%s r%u/%u q%u/%u %.8f/%.8f -> %.8f/%.8f\n",(long long)sp->aliceid,base,sp->Q.srccoin,rel,sp->Q.destcoin,requestid,sp->Q.R.requestid,quoteid,sp->Q.R.quoteid,dstr(satoshis+2*sp->Q.txfee),dstr(sp->Q.satoshis),dstr(destsatoshis+2*sp->Q.desttxfee),dstr(sp->Q.destsatoshis)); + return(-1); + } + + } else sp->Q = *qp; + if ( sp->Q.gui[0] == 0 || strcmp(sp->Q.gui,"nogui") == 0 ) + strcpy(sp->Q.gui,gui); + return(0); +} + +int32_t LP_finished_lastheight(struct LP_swapstats *sp) +{ + int32_t height = 1; struct iguana_info *bob,*alice; //char str[65]; + if ( (bob= LP_coinfind(sp->Q.srccoin)) != 0 && (alice= LP_coinfind(sp->Q.destcoin)) != 0 ) + { + if ( strcmp(bob->symbol,"BTC") == 0 ) + sp->bobneeds_dPoW = 0; + if ( strcmp(alice->symbol,"BTC") == 0 ) + sp->aliceneeds_dPoW = 0; + if ( sp->bobneeds_dPoW != 0 ) + { + if ( bits256_nonz(sp->bobdeposit) != 0 && sp->bobdeposit_ht == 0 ) + { + if ( (sp->bobdeposit_ht= LP_txheight(bob,sp->bobdeposit)) > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = sp->bobdeposit_ht; + //printf("%s bobdeposit.%d height.%d\n",bits256_str(str,sp->bobdeposit),ht,sp->bobneeds_dPoW); + } + if ( bits256_nonz(sp->bobpayment) != 0 && sp->bobpayment_ht == 0 ) + { + if ( (sp->bobpayment_ht= LP_txheight(bob,sp->bobpayment)) > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = sp->bobpayment_ht; + //printf("%s bobpayment.%d height.%d\n",bits256_str(str,sp->bobpayment),ht,sp->bobneeds_dPoW); + } + if ( bits256_nonz(sp->paymentspent) != 0 && sp->paymentspent_ht == 0 ) + { + if ( (sp->paymentspent_ht= LP_txheight(bob,sp->paymentspent)) > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = sp->paymentspent_ht; + //printf("%s paymentspent.%d height.%d\n",bits256_str(str,sp->paymentspent),ht,sp->bobneeds_dPoW); + } + if ( bits256_nonz(sp->depositspent) != 0 && sp->depositspent_ht == 0 ) + { + if ( (sp->depositspent_ht= LP_txheight(bob,sp->depositspent)) > sp->bobneeds_dPoW ) + sp->bobneeds_dPoW = sp->depositspent_ht; + //printf("%s depositspent.%d height.%d\n",bits256_str(str,sp->depositspent),ht,sp->bobneeds_dPoW); + } + } + if ( sp->aliceneeds_dPoW != 0 ) + { + if ( bits256_nonz(sp->alicepayment) != 0 && sp->alicepayment_ht == 0 ) + { + if ( (sp->alicepayment_ht= LP_txheight(alice,sp->alicepayment)) > sp->aliceneeds_dPoW ) + sp->aliceneeds_dPoW = sp->alicepayment_ht; + //printf("%s alicepayment.%d height.%d\n",bits256_str(str,sp->alicepayment),ht,sp->aliceneeds_dPoW); + } + if ( bits256_nonz(sp->Apaymentspent) != 0 && sp->Apaymentspent_ht == 0 ) + { + if ( (sp->Apaymentspent_ht= LP_txheight(alice,sp->Apaymentspent)) > sp->aliceneeds_dPoW ) + sp->aliceneeds_dPoW = sp->Apaymentspent_ht; + //printf("%s Apaymentspent.%d height.%d\n",bits256_str(str,sp->Apaymentspent),ht,sp->aliceneeds_dPoW); + } + } + } + return(height); +} + +int32_t LP_swap_finished(struct LP_swapstats *sp,int32_t dPoWflag) +{ + struct iguana_info *bob,*alice; + if ( sp->dPoWfinished != 0 || sp->expired != 0 ) + return(1); + else if ( dPoWflag == 0 && sp->finished != 0 ) + return(1); + if ( (bob= LP_coinfind(sp->Q.srccoin)) == 0 ) + { + //printf("no bobcoin.%s\n",sp->Q.srccoin); + return(0); + } + if ( (alice= LP_coinfind(sp->Q.destcoin)) == 0 ) + { + //printf("no alicecoin.%s\n",sp->Q.destcoin); + return(0); + } + if ( dPoWflag != 0 ) + { + if ( sp->finished != 0 ) + { + LP_finished_lastheight(sp); + if ( 0 && IAMLP == 0 ) + printf("bob needs %d @ %d, alice needs %d @ %d\n",sp->bobneeds_dPoW,bob->notarized,sp->aliceneeds_dPoW,alice->notarized); + } + if ( (sp->bobneeds_dPoW == 0 || (sp->bobneeds_dPoW > 1 && bob->notarized >= sp->bobneeds_dPoW)) && (sp->aliceneeds_dPoW == 0 || (sp->aliceneeds_dPoW > 1 && alice->notarized >= sp->aliceneeds_dPoW)) ) + { + sp->dPoWfinished = (uint32_t)time(NULL); + return(1); + } + } + return(0); +} + +struct LP_swapstats *LP_swapstats_create(uint64_t aliceid,int32_t RTflag,struct LP_quoteinfo *qp,double qprice,int32_t methodind) +{ + struct LP_pubswap *ptr; struct iguana_info *alice,*bob; struct LP_pubkey_info *pubp; char *base,*rel; struct LP_swapstats *sp = 0; + base = qp->srccoin, rel = qp->destcoin; + if ( (sp= LP_swapstats_add(aliceid,RTflag)) != 0 ) + { + sp->Q = *qp; + sp->qprice = qprice; + sp->methodind = methodind; + sp->ind = LP_aliceids++; + sp->lasttime = (uint32_t)time(NULL); + if ( sp->lasttime > sp->Q.timestamp+LP_atomic_locktime(base,rel)*2 ) + sp->expired = sp->lasttime; + else + { + if ( (alice= LP_coinfind(rel)) != 0 && (alice->isassetchain != 0 || strcmp("KMD",alice->symbol) == 0) ) + sp->aliceneeds_dPoW = 1; + if ( (bob= LP_coinfind(rel)) != 0 && (bob->isassetchain != 0 || strcmp(bob->symbol,"KMD") == 0) ) + sp->bobneeds_dPoW = 1; + } + strcpy(sp->bobgui,"nogui"); + strcpy(sp->alicegui,"nogui"); + if ( LP_swap_finished(sp,1) == 0 ) //sp->finished == 0 && sp->expired == 0 ) + { + if ( (pubp= LP_pubkeyadd(qp->srchash)) != 0 ) + { + ptr = calloc(1,sizeof(*ptr)); + ptr->swap = sp; + DL_APPEND(pubp->bobswaps,ptr); + } + if ( (pubp= LP_pubkeyadd(qp->desthash)) != 0 ) + { + ptr = calloc(1,sizeof(*ptr)); + ptr->swap = sp; + DL_APPEND(pubp->aliceswaps,ptr); + } + } + } else printf("unexpected LP_swapstats_add failure\n"); + return(sp); +} + +int32_t LP_statslog_parsequote(char *method,cJSON *lineobj) +{ + static uint32_t unexpected; + struct LP_swapstats *sp,*tmp; double qprice; uint32_t requestid,quoteid,timestamp; int32_t i,RTflag,flag,numtrades[LP_MAXPRICEINFOS],methodind,destvout,feevout,duplicate=0; char *statusstr,*gui,*base,*rel; uint64_t aliceid,txfee,satoshis,destsatoshis; bits256 desttxid,feetxid; struct LP_quoteinfo Q; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + memset(numtrades,0,sizeof(numtrades)); + memset(basevols,0,sizeof(basevols)); + memset(relvols,0,sizeof(relvols)); + memset(&Q,0,sizeof(Q)); + for (i=methodind=0; imethodind = methodind; + sp->Q.R.requestid = requestid; + sp->Q.R.quoteid = quoteid; + if ( LP_swapstats_update(sp,&Q,lineobj) == 0 ) + flag = 1; + //else printf("LP_swapstats_update error\n"); + } + if ( flag == 0 ) + { + HASH_ITER(hh,LP_swapstats,sp,tmp) + { + static uint32_t counter; + if ( sp->Q.R.requestid == requestid && sp->Q.R.quoteid == quoteid ) + { + sp->methodind = methodind; + if ( LP_swapstats_update(sp,&Q,lineobj) == 0 ) + { + flag = 1; + break; + } + if ( counter++ < 1 ) + printf("error after delayed match\n"); + } + } + } + if ( flag == 0 ) + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("unexpected.%d tradestatus aliceid.%llu requestid.%u quoteid.%u\n",unexpected++,(long long)aliceid,requestid,quoteid);//,jprint(lineobj,0)); + } + return(0); + } + if ( LP_quoteparse(&Q,lineobj) < 0 ) + { + printf("quoteparse_error.(%s)\n",jprint(lineobj,0)); + LP_parse_errors++; + return(-1); + } + else + { + gui = jstr(lineobj,"gui"); + if ( gui == 0 || gui[0] == 0 ) + gui = "nogui"; + base = jstr(lineobj,"base"); + rel = jstr(lineobj,"rel"); + satoshis = j64bits(lineobj,"satoshis"); + if ( base == 0 || rel == 0 || satoshis == 0 ) + { + printf("quoteparse_error.(%s)\n",jprint(lineobj,0)); + LP_parse_errors++; + return(-1); + } + txfee = j64bits(lineobj,"txfee"); + timestamp = juint(lineobj,"timestamp"); + destsatoshis = j64bits(lineobj,"destsatoshis"); + desttxid = jbits256(lineobj,"desttxid"); + destvout = jint(lineobj,"destvout"); + feetxid = jbits256(lineobj,"feetxid"); + feevout = jint(lineobj,"feevout"); + if ( (statusstr= jstr(lineobj,"status")) != 0 && strcmp(statusstr,"finished") == 0 ) + RTflag = 0; + else RTflag = 1; + qprice = ((double)destsatoshis / (satoshis - txfee)); + //printf("%s/v%d %s/v%d\n",bits256_str(str,desttxid),destvout,bits256_str(str2,feetxid),feevout); + aliceid = LP_aliceid_calc(desttxid,destvout,feetxid,feevout); + if ( (sp= LP_swapstats_find(aliceid)) != 0 ) + { + if ( methodind > sp->methodind ) + { + sp->methodind = methodind; + LP_swapstats_update(sp,&Q,lineobj); + } + duplicate = 1; + LP_duplicates++; + } + else + { + sp = LP_swapstats_create(aliceid,RTflag,&Q,qprice,methodind); + //printf("create aliceid.%llu\n",(long long)aliceid); + } + if ( sp != 0 ) + { + if ( strcmp(gui,"nogui") != 0 ) + { + if ( jint(lineobj,"iambob") != 0 ) + strcpy(sp->bobgui,gui); + else strcpy(sp->alicegui,gui); + } + } + } + return(duplicate == 0); +} + +cJSON *LP_swapstats_json(struct LP_swapstats *sp) +{ + cJSON *item = cJSON_CreateObject(); + jaddnum(item,"timestamp",sp->Q.timestamp); + jadd64bits(item,"aliceid",sp->aliceid); + jaddbits256(item,"src",sp->Q.srchash); + jaddstr(item,"base",sp->Q.srccoin); + jaddnum(item,"basevol",dstr(sp->Q.satoshis)); + jaddbits256(item,"dest",sp->Q.desthash); + jaddstr(item,"rel",sp->Q.destcoin); + jaddnum(item,"relvol",dstr(sp->Q.destsatoshis)); + jaddnum(item,"price",sp->qprice); + jaddnum(item,"requestid",sp->Q.R.requestid); + jaddnum(item,"quoteid",sp->Q.R.quoteid); + jaddnum(item,"finished",sp->finished); + jaddnum(item,"expired",sp->expired); + if ( bits256_nonz(sp->bobdeposit) != 0 ) + jaddbits256(item,"bobdeposit",sp->bobdeposit); + if ( bits256_nonz(sp->alicepayment) != 0 ) + jaddbits256(item,"alicepayment",sp->alicepayment); + if ( bits256_nonz(sp->bobpayment) != 0 ) + jaddbits256(item,"bobpayment",sp->bobpayment); + if ( bits256_nonz(sp->paymentspent) != 0 ) + jaddbits256(item,"paymentspent",sp->paymentspent); + if ( bits256_nonz(sp->Apaymentspent) != 0 ) + jaddbits256(item,"Apaymentspent",sp->Apaymentspent); + if ( bits256_nonz(sp->depositspent) != 0 ) + jaddbits256(item,"depositspent",sp->depositspent); + if ( sp->finished == 0 && sp->expired == 0 ) + jaddnum(item,"expires",sp->Q.timestamp + LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 - time(NULL)); + jaddnum(item,"ind",sp->methodind); + //jaddstr(item,"line",line); + return(item); +} + +char *LP_swapstatus_recv(cJSON *argjson) +{ + struct LP_swapstats *sp; char *statusstr; uint64_t aliceid; double qprice; struct LP_quoteinfo Q; int32_t methodind,RTflag; bits256 txid; //char str[65]; + if ( (aliceid= j64bits(argjson,"aliceid")) == 0 ) + return(clonestr("{\"error\":\"LP_swapstatus_recv null aliceid\"}")); + if ( (sp= LP_swapstats_find(aliceid)) == 0 ) + { + LP_quoteparse(&Q,argjson); + if ( Q.satoshis > Q.txfee ) + return(clonestr("{\"error\":\"LP_swapstatus_recv null satoshis\"}")); + qprice = (double)Q.destsatoshis / (Q.satoshis - Q.txfee); + if ( (statusstr= jstr(argjson,"status")) != 0 && strcmp(statusstr,"finished") == 0 ) + RTflag = 0; + else RTflag = 1; + sp = LP_swapstats_create(aliceid,RTflag,&Q,qprice,LP_TRADESTATUS_METHODIND); + //printf("create swapstatus from recv\n"); + } + if ( sp != 0 ) + { + if ( 0 && IAMLP == 0 ) + printf("swapstatus.(%s)\n",jprint(argjson,0)); + sp->lasttime = (uint32_t)time(NULL); + if ( (methodind= jint(argjson,"ind")) > sp->methodind && methodind < sizeof(LP_stats_methods)/sizeof(*LP_stats_methods) ) + { + if ( 0 && sp->finished == 0 && sp->expired == 0 ) + printf("SWAPSTATUS updated %llu %s %u %u\n",(long long)sp->aliceid,LP_stats_methods[sp->methodind],juint(argjson,"finished"),juint(argjson,"expired")); + sp->methodind = methodind; + sp->finished = juint(argjson,"finished"); + sp->expired = juint(argjson,"expired"); + txid = jbits256(argjson,"bobdeposit"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->bobdeposit) == 0 ) + { + sp->bobdeposit = txid; + //printf("set aliceid.%llu bobdeposit %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"alicepayment"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->alicepayment) == 0 ) + { + sp->alicepayment = txid; + //printf("set aliceid.%llu alicepayment %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"bobpayment"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->bobpayment) == 0 ) + { + sp->bobpayment = txid; + //printf("set aliceid.%llu bobpayment %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"paymentspent"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->paymentspent) == 0 ) + { + sp->paymentspent = txid; + //printf("set aliceid.%llu paymentspent %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"Apaymentspent"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->Apaymentspent) == 0 ) + { + sp->Apaymentspent = txid; + //printf("set aliceid.%llu Apaymentspent %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + txid = jbits256(argjson,"depositspent"); + if ( bits256_nonz(txid) != 0 && bits256_nonz(sp->depositspent) == 0 ) + { + sp->depositspent = txid; + //printf("set aliceid.%llu depositspent %s\n",(long long)sp->aliceid,bits256_str(str,txid)); + } + } + } + return(clonestr("{\"result\":\"success\"}")); +} + +char *LP_gettradestatus(uint64_t aliceid,uint32_t requestid,uint32_t quoteid) +{ + struct LP_swapstats *sp; struct iguana_info *bob,*alice; char *swapstr,*statusstr; cJSON *reqjson,*swapjson; bits256 zero; + //printf("gettradestatus.(%llu)\n",(long long)aliceid); + if ( IAMLP != 0 ) + { + if ( (sp= LP_swapstats_find(aliceid)) != 0 && sp->Q.satoshis != 0 && sp->Q.destsatoshis != 0 && bits256_nonz(sp->bobdeposit) != 0 ) + { + if ( time(NULL) > sp->lasttime+60 ) + { + if ( (reqjson= LP_swapstats_json(sp)) != 0 ) + { + jaddstr(reqjson,"method","swapstatus"); + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + } + if ( (bob= LP_coinfind(sp->Q.srccoin)) != 0 ) + LP_dPoW_broadcast(bob); + if ( (alice= LP_coinfind(sp->Q.destcoin)) != 0 ) + LP_dPoW_broadcast(alice); + } + return(clonestr("{\"result\":\"success\"}")); + } + } + if ( (swapstr= basilisk_swapentry(requestid,quoteid,0)) != 0 ) + { + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) + { + if ( (statusstr= jstr(swapjson,"status")) != 0 && strcmp(statusstr,"finished") == 0 ) + { + jaddstr(swapjson,"method","swapstatus"); + memset(zero.bytes,0,sizeof(zero)); + printf("send local swapstatus\n"); + LP_reserved_msg(0,"","",zero,jprint(swapjson,0)); + } + free_json(swapjson); + } + free(swapstr); + } + return(clonestr("{\"result\":\"success\"}")); +} + +int32_t LP_stats_dispiter(cJSON *array,struct LP_swapstats *sp,uint32_t starttime,uint32_t endtime,char *refbase,char *refrel,char *refgui,bits256 refpubkey) +{ + int32_t dispflag,retval = 0; + if ( sp->finished == 0 && sp->expired == 0 && time(NULL) > sp->Q.timestamp+LP_atomic_locktime(sp->Q.srccoin,sp->Q.destcoin)*2 ) + sp->expired = (uint32_t)time(NULL); + if ( LP_swap_finished(sp,1) > 0 ) + retval = 1; + dispflag = 0; + if ( starttime == 0 && endtime == 0 ) + dispflag = 1; + else if ( starttime > time(NULL) && endtime == starttime && sp->finished == 0 && sp->expired == 0 ) + dispflag = 1; + else if ( sp->Q.timestamp >= starttime && sp->Q.timestamp <= endtime ) + dispflag = 1; + if ( refbase != 0 && refbase[0] != 0 && strcmp(refbase,sp->Q.srccoin) != 0 && strcmp(refbase,sp->Q.destcoin) != 0 ) + dispflag = 0; + if ( refrel != 0 && refrel[0] != 0 && strcmp(refrel,sp->Q.srccoin) != 0 && strcmp(refrel,sp->Q.destcoin) != 0 ) + dispflag = 0; + if ( dispflag != 0 ) + { + dispflag = 0; + if ( refgui == 0 || refgui[0] == 0 || strcmp(refgui,sp->bobgui) == 0 || strcmp(refgui,sp->alicegui) == 0 ) + { + if ( bits256_nonz(refpubkey) == 0 || bits256_cmp(refpubkey,sp->Q.srchash) == 0 || bits256_cmp(refpubkey,sp->Q.desthash) == 0 ) + dispflag = 1; + } + } + if ( dispflag != 0 ) + jaddi(array,LP_swapstats_json(sp)); + return(retval); +} + +cJSON *LP_statslog_disp(uint32_t starttime,uint32_t endtime,char *refgui,bits256 refpubkey,char *refbase,char *refrel) +{ + static int32_t rval; + cJSON *retjson,*array,*item; struct LP_pubkey_info *pubp,*ptmp; uint32_t now; struct LP_swapstats *sp,*tmp; int32_t i,n,numtrades[LP_MAXPRICEINFOS]; uint64_t basevols[LP_MAXPRICEINFOS],relvols[LP_MAXPRICEINFOS]; + if ( rval == 0 ) + rval = (LP_rand() % 300) + 60; + if ( starttime > endtime ) + starttime = endtime; + n = LP_statslog_parse(); + memset(basevols,0,sizeof(basevols)); + memset(relvols,0,sizeof(relvols)); + memset(numtrades,0,sizeof(numtrades)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"newlines",n); + array = cJSON_CreateArray(); + LP_RTcount = LP_swapscount = 0; + now = (uint32_t)time(NULL); + HASH_ITER(hh,LP_RTstats,sp,tmp) + { + if ( LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey) > 0 ) + { + portable_mutex_lock(&LP_statslogmutex); + HASH_DELETE(hh,LP_RTstats,sp); + HASH_ADD(hh,LP_swapstats,aliceid,sizeof(sp->aliceid),sp); + portable_mutex_unlock(&LP_statslogmutex); + } + else + { + LP_RTcount++; + /*if ( now > sp->lasttime+rval ) + { + reqjson = cJSON_CreateObject(); + jaddstr(reqjson,"method","gettradestatus"); + jadd64bits(reqjson,"aliceid",sp->aliceid); + memset(zero.bytes,0,sizeof(zero)); + LP_reserved_msg(0,"","",zero,jprint(reqjson,1)); + }*/ + } + } + HASH_ITER(hh,LP_swapstats,sp,tmp) + { + LP_stats_dispiter(array,sp,starttime,endtime,refbase,refrel,refgui,refpubkey); + LP_swapscount++; + } + HASH_ITER(hh,LP_pubkeyinfos,pubp,ptmp) + { + pubp->dynamictrust = LP_dynamictrust(0,pubp->pubkey,0); + } + //printf("RT.%d completed.%d\n",LP_RTcount,LP_swapscount); + jadd(retjson,"swaps",array); + jaddnum(retjson,"RTcount",LP_RTcount); + jaddnum(retjson,"swapscount",LP_swapscount); + array = cJSON_CreateArray(); + for (i=0; i=0; i--) + { + item = jitem(swapsjson,i); + retitem = cJSON_CreateObject(); + if ( (base= jstr(item,"base")) != 0 && (rel= jstr(item,"rel")) != 0 && (basevol= jdouble(item,"basevol")) > SMALLVAL ) + { + relvol = jdouble(item,"relvol"); + jaddnum(retitem,"timestamp",juint(item,"timestamp")); + jaddnum(retitem,base,basevol); + jaddnum(retitem,rel,relvol); + jaddnum(retitem,"price",relvol/basevol); + } + jaddi(retjson,retitem); + } + } + free_json(logjson); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"couldnt get logjson\"}")); +} + +struct LP_ohlc +{ + uint32_t timestamp,firsttime,lasttime,numtrades; + double high,low,open,close,relsum,basesum; +}; + +cJSON *LP_ohlc_json(struct LP_ohlc *bar,struct LP_ohlc *prevbar) +{ + cJSON *item; struct LP_ohlc tmp; + memset(&tmp,0,sizeof(tmp)); + if ( bar->numtrades == 0 ) + { + memset(&tmp,0,sizeof(tmp)); + tmp.timestamp = bar->timestamp; + tmp.open = tmp.high = tmp.low = tmp.close = prevbar->close; + tmp.numtrades = 0; + tmp.relsum = tmp.basesum = 0.; + } else tmp = *bar; + bar = &tmp; + item = cJSON_CreateArray(); + jaddinum(item,bar->timestamp); + jaddinum(item,bar->high); + jaddinum(item,bar->low); + jaddinum(item,bar->open); + jaddinum(item,bar->close); + jaddinum(item,bar->relsum); + jaddinum(item,bar->basesum); + if ( bar->basesum != 0 ) + jaddinum(item,bar->relsum / bar->basesum); + else jaddinum(item,0); + jaddinum(item,bar->numtrades); + return(item); +} + +void LP_ohlc_update(struct LP_ohlc *bar,uint32_t timestamp,double basevol,double relvol) +{ + double price; + if ( basevol > SMALLVAL && relvol > SMALLVAL ) + { + price = relvol / basevol; + if ( bar->firsttime == 0 || timestamp < bar->firsttime ) + { + bar->firsttime = timestamp; + bar->open = price; + } + if ( bar->lasttime == 0 || timestamp > bar->lasttime ) + { + bar->lasttime = timestamp; + bar->close = price; + } + if ( bar->low == 0. || price < bar->low ) + bar->low = price; + if ( bar->high == 0. || price > bar->high ) + bar->high = price; + bar->basesum += basevol; + bar->relsum += relvol; + bar->numtrades++; + //printf("%d %.8f/%.8f -> %.8f\n",bar->numtrades,basevol,relvol,price); + } +} + +cJSON *LP_tradesarray(char *refbase,char *refrel,uint32_t starttime,uint32_t endtime,int32_t timescale) +{ + struct LP_ohlc *bars,nonz; cJSON *array,*item,*statsjson,*swaps; uint32_t timestamp; bits256 zero; char *base,*rel; int32_t i,n,numbars,bari; + if ( timescale < 60 ) + return(cJSON_Parse("{\"error\":\"one minute is shortest timescale\"}")); + memset(zero.bytes,0,sizeof(zero)); + if ( endtime == 0 ) + endtime = (((uint32_t)time(NULL) / timescale) * timescale); + if ( starttime == 0 || starttime >= endtime ) + starttime = (endtime - LP_SCREENWIDTH*timescale); + numbars = ((endtime - starttime) / timescale) + 1; + bars = calloc(numbars,sizeof(*bars)); + for (bari=0; bari= starttime && timestamp <= endtime ) + { + bari = (timestamp - starttime) / timescale; + base = jstr(item,"base"); + rel = jstr(item,"rel"); + if ( strcmp(base,refbase) == 0 && strcmp(rel,refrel) == 0 ) + LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"basevol"),jdouble(item,"relvol")); + else if ( strcmp(rel,refbase) == 0 && strcmp(base,refrel) == 0 ) + LP_ohlc_update(&bars[bari],timestamp,jdouble(item,"relvol"),jdouble(item,"basevol")); + } else printf("skip.(%s)\n",jprint(item,0)); + } + } + free_json(statsjson); + } + array = cJSON_CreateArray(); + memset(&nonz,0,sizeof(nonz)); + for (bari=0; bari 0 ) + nonz = bars[bari]; + } + } + free(bars); + return(array); +} + diff --git a/iguana/exchanges/LP_swap.c b/iguana/exchanges/LP_swap.c new file mode 100644 index 000000000..f125ed589 --- /dev/null +++ b/iguana/exchanges/LP_swap.c @@ -0,0 +1,1227 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_swap.c +// marketmaker +// + +/* + make sure to broadcast deposit before claiming refund, or to just skip it if neither is done + */ + + +// included from basilisk.c +/* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 + https://bitcointalk.org/index.php?topic=1364951 + Tier Nolan's approach is followed with the following changes: + a) instead of cutting 1000 keypairs, only INSTANTDEX_DECKSIZE are a + b) instead of sending the entire 256 bits, it is truncated to 64 bits. With odds of collision being so low, it is dwarfed by the ~0.1% insurance factor. + c) D is set to ~100x the insurance rate of 1/777 12.87% + BTC amount + d) insurance is added to Bob's payment, which is after the deposit and bailin + e) BEFORE Bob broadcasts deposit, Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed + */ + +//#define DISABLE_CHECKSIG // unsolved MITM (evil peer) + +/* + both fees are standard payments: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG + + Alice altpayment: OP_2 OP_2 OP_CHECKMULTISIG + + Bob deposit: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + + Bob paytx: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + + Naming convention are pubAi are alice's pubkeys (seems only pubA0 and not pubA1) + pubBi are Bob's pubkeys + + privN is Bob's privkey from the cut and choose deck as selected by Alice + privM is Alice's counterpart + pubN and pubM are the corresponding pubkeys for these chosen privkeys + + Alice timeout event is triggered if INSTANTDEX_LOCKTIME elapses from the start of a FSM instance. Bob timeout event is triggered after INSTANTDEX_LOCKTIME*2 + */ + +/* + Bob sends bobdeposit and waits for alicepayment to confirm before sending bobpayment + Alice waits for bobdeposit to confirm and sends alicepayment + + Alice spends bobpayment immediately divulging privAm + Bob spends alicepayment immediately after getting privAm and divulges privBn + + Bob will spend bobdeposit after end of trade or INSTANTDEX_LOCKTIME, divulging privBn + Alice spends alicepayment as soon as privBn is seen + + Bob will spend bobpayment after INSTANTDEX_LOCKTIME + Alice spends bobdeposit in 2*INSTANTDEX_LOCKTIME + */ + +//Bobdeposit includes a covered put option for alicecoin, duration INSTANTDEX_LOCKTIME +//alicepayment includes a covered call option for alicecoin, duration (2*INSTANTDEX_LOCKTIME - elapsed) + + +/* in case of following states, some funds remain unclaimable, but all identified cases are due to one or both sides not spending when they were the only eligible party: + + Bob failed to claim deposit during exclusive period and since alice put in the claim, the alicepayment is unspendable. if alice is nice, she can send privAm to Bob. + Apaymentspent.(0000000000000000000000000000000000000000000000000000000000000000) alice.0 bob.0 + paymentspent.(f91da4e001360b95276448e7b01904d9ee4d15862c5af7f5c7a918df26030315) alice.0 bob.1 + depositspent.(f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add) alice.1 bob.0 + + */ + + +uint32_t LP_atomic_locktime(char *base,char *rel) +{ + if ( strcmp(base,"BTC") != 0 && strcmp(rel,"BTC") != 0 ) + return(INSTANTDEX_LOCKTIME); + else return(INSTANTDEX_LOCKTIME * 10); +} + +void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) +{ + if ( rawtx->vins != 0 ) + free_json(rawtx->vins), rawtx->vins = 0; + //if ( rawtx->txbytes != 0 ) + // free(rawtx->txbytes), rawtx->txbytes = 0; +} + +void basilisk_swap_finished(struct basilisk_swap *swap) +{ + /*int32_t i; + if ( swap->utxo != 0 && swap->sentflag == 0 ) + { + LP_availableset(swap->utxo); + swap->utxo = 0; + //LP_butxo_swapfields_set(swap->utxo); + } + swap->I.finished = (uint32_t)time(NULL);*/ + if ( swap->I.finished == 0 ) + { + if ( swap->I.iambob != 0 ) + { + LP_availableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout); + LP_availableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout); + } + else + { + LP_availableset(swap->alicepayment.utxotxid,swap->alicepayment.utxovout); + LP_availableset(swap->myfee.utxotxid,swap->myfee.utxovout); + } + } + // save to permanent storage + basilisk_rawtx_purge(&swap->bobdeposit); + basilisk_rawtx_purge(&swap->bobpayment); + basilisk_rawtx_purge(&swap->alicepayment); + basilisk_rawtx_purge(&swap->myfee); + basilisk_rawtx_purge(&swap->otherfee); + basilisk_rawtx_purge(&swap->aliceclaim); + basilisk_rawtx_purge(&swap->alicespend); + basilisk_rawtx_purge(&swap->bobreclaim); + basilisk_rawtx_purge(&swap->bobspend); + basilisk_rawtx_purge(&swap->bobrefund); + basilisk_rawtx_purge(&swap->alicereclaim); + /*for (i=0; inummessages; i++) + if ( swap->messages[i].data != 0 ) + free(swap->messages[i].data), swap->messages[i].data = 0; + free(swap->messages), swap->messages = 0; + swap->nummessages = 0;*/ + if ( swap->N.pair >= 0 ) + nn_close(swap->N.pair), swap->N.pair = -1; +} + +uint32_t basilisk_quoteid(struct basilisk_request *rp) +{ + struct basilisk_request R; + R = *rp; + R.unused = R.requestid = R.quoteid = R.DEXselector = 0; + return(calc_crc32(0,(void *)&R,sizeof(R))); +} + +uint32_t basilisk_requestid(struct basilisk_request *rp) +{ + struct basilisk_request R; + R = *rp; + R.requestid = R.quoteid = R.quotetime = R.DEXselector = 0; + R.destamount = R.unused = 0; + memset(R.desthash.bytes,0,sizeof(R.desthash.bytes)); + if ( 0 ) + { + int32_t i; + for (i=0; i %s %.8f %s crc.%u q%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.srchash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R)),basilisk_quoteid(&R)); + } + return(calc_crc32(0,(void *)&R,sizeof(R))); +} + +int32_t LP_pubkeys_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,datalen = 0; + datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.requestid),&swap->I.req.requestid); + datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); + data[datalen++] = swap->I.aliceconfirms; + data[datalen++] = swap->I.bobconfirms; + data[datalen++] = swap->I.alicemaxconfirms; + data[datalen++] = swap->I.bobmaxconfirms; + data[datalen++] = swap->I.otheristrusted; + for (i=0; i<33; i++) + data[datalen++] = swap->persistent_pubkey33[i]; + for (i=0; ideck)/sizeof(swap->deck[0][0]); i++) + datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->deck[i>>1][i&1]),&swap->deck[i>>1][i&1]); + printf("send >>>>>>>>> r.%u q.%u datalen.%d\n",swap->I.req.requestid,swap->I.req.quoteid,datalen); + return(datalen); +} + +int32_t LP_pubkeys_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + uint32_t requestid,quoteid; int32_t i,nonz=0,alicemaxconfirms,bobmaxconfirms,aliceconfirms,bobconfirms,len = 0; uint8_t other33[33]; + if ( datalen == sizeof(swap->otherdeck)+38+sizeof(uint32_t)*2 ) + { + len += iguana_rwnum(0,&data[len],sizeof(requestid),&requestid); + len += iguana_rwnum(0,&data[len],sizeof(quoteid),"eid); + if ( requestid != swap->I.req.requestid || quoteid != swap->I.req.quoteid ) + { + printf("SWAP requestid.%u quoteid.%u mismatch received r.%u q.%u\n",swap->I.req.requestid,swap->I.req.quoteid,requestid,quoteid); + return(-1); + } + aliceconfirms = data[len++]; + bobconfirms = data[len++]; + alicemaxconfirms = data[len++]; + bobmaxconfirms = data[len++]; + if ( aliceconfirms != swap->I.aliceconfirms || bobconfirms != swap->I.bobconfirms ) + { + printf("MISMATCHED required confirms me.(%d %d) vs (%d %d) max.(%d %d) othermax.(%d %d)\n",swap->I.aliceconfirms,swap->I.bobconfirms,aliceconfirms,bobconfirms,swap->I.alicemaxconfirms,swap->I.bobmaxconfirms,alicemaxconfirms,bobmaxconfirms); + if ( alicemaxconfirms > swap->I.alicemaxconfirms ) + alicemaxconfirms = swap->I.alicemaxconfirms; + if ( bobmaxconfirms > swap->I.bobmaxconfirms ) + bobmaxconfirms = swap->I.bobmaxconfirms; + if ( swap->I.aliceconfirms < aliceconfirms ) + swap->I.aliceconfirms = aliceconfirms; + if ( swap->I.bobconfirms < bobconfirms ) + swap->I.bobconfirms = bobconfirms; + if ( swap->I.aliceconfirms > swap->I.alicemaxconfirms || swap->I.bobconfirms > swap->I.bobmaxconfirms ) + { + printf("numconfirms (%d %d) exceeds max (%d %d)\n",swap->I.aliceconfirms,swap->I.bobconfirms,swap->I.alicemaxconfirms,swap->I.bobmaxconfirms); + return(-1); + } + } + if ( (swap->I.otherstrust= data[len++]) != 0 ) + { + if ( swap->I.otheristrusted != 0 ) + { + swap->I.aliceconfirms = swap->I.bobconfirms = 0; + printf("mutually trusted swap, adjust required confirms to: alice.%d bob.%d\n",swap->I.aliceconfirms,swap->I.bobconfirms); + } + } + printf("NUMCONFIRMS for SWAP alice.%d bob.%d, otheristrusted.%d othertrusts.%d\n",swap->I.aliceconfirms,swap->I.bobconfirms,swap->I.otheristrusted,swap->I.otherstrust); + for (i=0; i<33; i++) + if ( (other33[i]= data[len++]) != 0 ) + nonz++; + if ( nonz > 8 ) + memcpy(swap->persistent_other33,other33,33); + for (i=0; iotherdeck)/sizeof(swap->otherdeck[0][0]); i++) + len += iguana_rwnum(0,&data[len],sizeof(swap->otherdeck[i>>1][i&1]),&swap->otherdeck[i>>1][i&1]); + return(0); + } + printf("pubkeys verify size mismatch %d != %d\n",datalen,(int32_t)(sizeof(swap->otherdeck)+38+sizeof(uint32_t)*2)); + return(-1); +} + +int32_t LP_choosei_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,datalen; char str[65]; + datalen = iguana_rwnum(1,data,sizeof(swap->I.choosei),&swap->I.choosei); + if ( swap->I.iambob != 0 ) + { + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubB0.bytes[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubB1.bytes[i]; + printf("SEND pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); + } + else + { + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubA0.bytes[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubA1.bytes[i]; + printf("SEND pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); + } + return(datalen); +} + +int32_t LP_choosei_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + int32_t otherchoosei=-1,i,len = 0; uint8_t pubkey33[33]; + if ( datalen == sizeof(otherchoosei)+sizeof(bits256)*2 ) + { + len += iguana_rwnum(0,data,sizeof(otherchoosei),&otherchoosei); + if ( otherchoosei >= 0 && otherchoosei < INSTANTDEX_DECKSIZE ) + { + swap->I.otherchoosei = otherchoosei; + if ( swap->I.iambob != 0 ) + { + for (i=0; i<32; i++) + swap->I.pubA0.bytes[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.pubA1.bytes[i] = data[len++]; + //printf("GOT pubA0/1 %s\n",bits256_str(str,swap->I.pubA0)); + swap->I.privBn = swap->privkeys[swap->I.otherchoosei]; + memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei])); + revcalc_rmd160_sha256(swap->I.secretBn,swap->I.privBn);//.bytes,sizeof(swap->privBn)); + vcalc_sha256(0,swap->I.secretBn256,swap->I.privBn.bytes,sizeof(swap->I.privBn)); + swap->I.pubBn = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privBn); + //printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); + //basilisk_bobscripts_set(swap,1,1); + } + else + { + for (i=0; i<32; i++) + swap->I.pubB0.bytes[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.pubB1.bytes[i] = data[len++]; + //printf("GOT pubB0/1 %s\n",bits256_str(str,swap->I.pubB0)); + swap->I.privAm = swap->privkeys[swap->I.otherchoosei]; + memset(&swap->privkeys[swap->I.otherchoosei],0,sizeof(swap->privkeys[swap->I.otherchoosei])); + revcalc_rmd160_sha256(swap->I.secretAm,swap->I.privAm);//.bytes,sizeof(swap->privAm)); + vcalc_sha256(0,swap->I.secretAm256,swap->I.privAm.bytes,sizeof(swap->I.privAm)); + swap->I.pubAm = bitcoin_pubkey33(swap->ctx,pubkey33,swap->I.privAm); + //printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); + swap->bobdeposit.I.pubkey33[0] = 2; + swap->bobpayment.I.pubkey33[0] = 2; + for (i=0; i<32; i++) + swap->bobpayment.I.pubkey33[i+1] = swap->bobdeposit.I.pubkey33[i+1] = swap->I.pubA0.bytes[i]; + //printf("SET bobdeposit pubkey33.(02%s)\n",bits256_str(str,swap->I.pubA0)); + //basilisk_bobscripts_set(swap,0); + } + return(0); + } + } + printf("illegal otherchoosei.%d datalen.%d vs %d\n",otherchoosei,datalen,(int32_t)(sizeof(otherchoosei)+sizeof(bits256)*2)); + return(-1); +} + +int32_t LP_mostprivs_data(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,j,datalen; + datalen = 0; + for (i=0; iprivkeys)/sizeof(*swap->privkeys); i++) + { + for (j=0; j<32; j++) + data[datalen++] = (i == swap->I.otherchoosei) ? 0 : swap->privkeys[i].bytes[j]; + } + if ( swap->I.iambob != 0 ) + { + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubBn.bytes[i]; + for (i=0; i<20; i++) + data[datalen++] = swap->I.secretBn[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.secretBn256[i]; + } + else + { + for (i=0; i<32; i++) + data[datalen++] = swap->I.pubAm.bytes[i]; + for (i=0; i<20; i++) + data[datalen++] = swap->I.secretAm[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->I.secretAm256[i]; + } + return(datalen); +} + +int32_t basilisk_verify_pubpair(int32_t *wrongfirstbytep,struct basilisk_swap *swap,int32_t ind,uint8_t pub0,bits256 pubi,uint64_t txid) +{ + if ( pub0 != (swap->I.iambob ^ 1) + 0x02 ) + { + (*wrongfirstbytep)++; + printf("wrongfirstbyte[%d] %02x\n",ind,pub0); + return(-1); + } + else if ( swap->otherdeck[ind][1] != pubi.txid ) + { + printf("otherdeck[%d] priv ->pub mismatch %llx != %llx\n",ind,(long long)swap->otherdeck[ind][1],(long long)pubi.txid); + return(-1); + } + else if ( swap->otherdeck[ind][0] != txid ) + { + printf("otherdeck[%d] priv mismatch %llx != %llx\n",ind,(long long)swap->otherdeck[ind][0],(long long)txid); + return(-1); + } + return(0); +} + +int32_t basilisk_verify_privi(void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t j,wrongfirstbyte,len = 0; bits256 privkey,pubi; char str[65],str2[65]; uint8_t secret160[20],pubkey33[33]; uint64_t txid; struct basilisk_swap *swap = ptr; + memset(privkey.bytes,0,sizeof(privkey)); + if ( datalen == sizeof(bits256) ) + { + for (j=0; j<32; j++) + privkey.bytes[j] = data[len++]; + revcalc_rmd160_sha256(secret160,privkey);//.bytes,sizeof(privkey)); + memcpy(&txid,secret160,sizeof(txid)); + pubi = bitcoin_pubkey33(swap->ctx,pubkey33,privkey); + if ( basilisk_verify_pubpair(&wrongfirstbyte,swap,swap->I.choosei,pubkey33[0],pubi,txid) == 0 ) + { + if ( swap->I.iambob != 0 ) + { + swap->I.privAm = privkey; + vcalc_sha256(0,swap->I.secretAm256,privkey.bytes,sizeof(privkey)); + printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256)); + basilisk_bobscripts_set(swap,0,1); + } + else + { + swap->I.privBn = privkey; + vcalc_sha256(0,swap->I.secretBn256,privkey.bytes,sizeof(privkey)); + printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256)); + } + basilisk_dontforget_update(swap,0); + char str[65]; printf("privi verified.(%s)\n",bits256_str(str,privkey)); + return(0); + } else printf("pubpair doesnt verify privi\n"); + } else printf("verify privi size mismatch %d != %d\n",datalen,(int32_t)sizeof(bits256)); + return(-1); +} + +int32_t LP_mostprivs_verify(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + int32_t i,j,wrongfirstbyte=0,errs=0,len = 0; bits256 otherpriv,pubi; uint8_t secret160[20],otherpubkey[33]; uint64_t txid; + //printf("verify privkeys choosei.%d otherchoosei.%d datalen.%d vs %d\n",swap->choosei,swap->otherchoosei,datalen,(int32_t)sizeof(swap->privkeys)+20+32); + memset(otherpriv.bytes,0,sizeof(otherpriv)); + if ( swap->I.cutverified == 0 && swap->I.otherchoosei >= 0 && datalen == sizeof(swap->privkeys)+20+2*32 ) + { + for (i=errs=0; iprivkeys)/sizeof(*swap->privkeys); i++) + { + for (j=0; j<32; j++) + otherpriv.bytes[j] = data[len++]; + if ( i != swap->I.choosei ) + { + pubi = bitcoin_pubkey33(swap->ctx,otherpubkey,otherpriv); + revcalc_rmd160_sha256(secret160,otherpriv);//.bytes,sizeof(otherpriv)); + memcpy(&txid,secret160,sizeof(txid)); + errs += basilisk_verify_pubpair(&wrongfirstbyte,swap,i,otherpubkey[0],pubi,txid); + } + } + if ( errs == 0 && wrongfirstbyte == 0 ) + { + swap->I.cutverified = 1, printf("CUT VERIFIED\n"); + if ( swap->I.iambob != 0 ) + { + for (i=0; i<32; i++) + swap->I.pubAm.bytes[i] = data[len++]; + for (i=0; i<20; i++) + swap->I.secretAm[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.secretAm256[i] = data[len++]; + //basilisk_bobscripts_set(swap,1,1); + } + else + { + for (i=0; i<32; i++) + swap->I.pubBn.bytes[i] = data[len++]; + for (i=0; i<20; i++) + swap->I.secretBn[i] = data[len++]; + for (i=0; i<32; i++) + swap->I.secretBn256[i] = data[len++]; + //basilisk_bobscripts_set(swap,0); + } + } else printf("failed verification: wrong firstbyte.%d errs.%d\n",wrongfirstbyte,errs); + } + //printf("privkeys errs.%d wrongfirstbyte.%d\n",errs,wrongfirstbyte); + return(errs); +} + +int32_t LP_waitfor(int32_t pairsock,struct basilisk_swap *swap,int32_t timeout,int32_t (*verify)(struct basilisk_swap *swap,uint8_t *data,int32_t datalen)) +{ + struct nn_pollfd pfd; void *data; int32_t datalen,retval = -1; uint32_t expiration = (uint32_t)time(NULL) + timeout; + while ( time(NULL) < expiration ) + { + memset(&pfd,0,sizeof(pfd)); + pfd.fd = pairsock; + pfd.events = NN_POLLIN; + if ( nn_poll(&pfd,1,1) > 0 ) + { + //printf("start wait\n"); + if ( (datalen= nn_recv(pairsock,&data,NN_MSG,0)) >= 0 ) + { + //printf("wait for got.%d\n",datalen); + retval = (*verify)(swap,data,datalen); + nn_freemsg(data); + //printf("retval.%d\n",retval); + return(retval); + } // else printf("error nn_recv\n"); + } + } + printf("waitfor timedout aliceid.%llu requestid.%u quoteid.%u\n",(long long)swap->aliceid,swap->I.req.requestid,swap->I.req.quoteid); + return(retval); +} + +int32_t swap_nn_send(int32_t sock,uint8_t *data,int32_t datalen,uint32_t flags,int32_t timeout) +{ + struct nn_pollfd pfd; int32_t i; + for (i=0; i 0 ) + return(nn_send(sock,data,datalen,flags)); + usleep(1000); + } + return(-1); +} + +int32_t LP_waitsend(char *statename,int32_t timeout,int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,int32_t (*verify)(struct basilisk_swap *swap,uint8_t *data,int32_t datalen),int32_t (*datagen)(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)) +{ + int32_t datalen,sendlen,retval = -1; + //printf("waitsend.%s timeout.%d\n",statename,timeout); + if ( LP_waitfor(pairsock,swap,timeout,verify) == 0 ) + { + //printf("waited for %s\n",statename); + if ( (datalen= (*datagen)(swap,data,maxlen)) > 0 ) + { + if ( (sendlen= swap_nn_send(pairsock,data,datalen,0,timeout)) == datalen ) + { + //printf("sent.%d after waitfor.%s\n",sendlen,statename); + retval = 0; + } else printf("send %s error\n",statename); + } else printf("%s datagen no data\n",statename); + } else printf("didnt get valid data after %d\n",timeout); + return(retval); +} + +int32_t LP_sendwait(char *statename,int32_t timeout,int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,int32_t (*verify)(struct basilisk_swap *swap,uint8_t *data,int32_t datalen),int32_t (*datagen)(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen)) +{ + int32_t datalen,sendlen,retval = -1; + //printf("sendwait.%s\n",statename); + if ( (datalen= (*datagen)(swap,data,maxlen)) > 0 ) + { + //printf("generated %d for %s, timeout.%d\n",datalen,statename,timeout); + if ( (sendlen= swap_nn_send(pairsock,data,datalen,0,timeout)) == datalen ) + { + //printf("sendwait.%s sent %d\n",statename,sendlen); + if ( LP_waitfor(pairsock,swap,timeout,verify) == 0 ) + { + //printf("waited! sendwait.%s sent %d\n",statename,sendlen); + retval = 0; + } else printf("didnt get %s\n",statename); + } else printf("send %s error\n",statename); + } else printf("no datagen for %s\n",statename); + return(retval); +} + +void LP_swapsfp_update(struct basilisk_request *rp) +{ + static FILE *swapsfp; + if ( swapsfp == 0 ) + { + char fname[512]; + sprintf(fname,"%s/SWAPS/list",GLOBAL_DBDIR), OS_compatible_path(fname); + if ( (swapsfp= fopen(fname,"rb+")) == 0 ) + swapsfp = fopen(fname,"wb+"); + else fseek(swapsfp,0,SEEK_END); + //printf("LIST fp.%p\n",swapsfp); + } + if ( swapsfp != 0 ) + { + fwrite(&rp->requestid,1,sizeof(rp->requestid),swapsfp); + fwrite(&rp->quoteid,1,sizeof(rp->quoteid),swapsfp); + fflush(swapsfp); + } +} + +struct basilisk_rawtx *LP_swapdata_rawtx(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx) +{ + if ( rawtx->I.datalen != 0 && rawtx->I.datalen <= maxlen ) + { + memcpy(data,rawtx->txbytes,rawtx->I.datalen); + return(rawtx); + } + printf("swapdata rawtx has null txbytes\n"); + return(0); +} + +int32_t LP_rawtx_spendscript(struct basilisk_swap *swap,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *recvbuf,int32_t recvlen,int32_t suppress_pubkeys) +{ + bits256 otherhash,myhash,txid; int64_t txfee,val; int32_t i,offset=0,datalen=0,retval=-1,hexlen,n; uint8_t *data; cJSON *txobj,*skey,*vouts,*vout; char *hexstr,redeemaddr[64],checkaddr[64]; uint32_t quoteid,msgbits; struct iguana_info *coin; + if ( (coin= LP_coinfind(rawtx->symbol)) == 0 ) + { + printf("LP_rawtx_spendscript couldnt find coin.(%s)\n",rawtx->symbol); + return(-1); + } + for (i=0; i<32; i++) + otherhash.bytes[i] = recvbuf[offset++]; + for (i=0; i<32; i++) + myhash.bytes[i] = recvbuf[offset++]; + offset += iguana_rwnum(0,&recvbuf[offset],sizeof(quoteid),"eid); + offset += iguana_rwnum(0,&recvbuf[offset],sizeof(msgbits),&msgbits); + datalen = recvbuf[offset++]; + datalen += (int32_t)recvbuf[offset++] << 8; + if ( datalen > 1024 ) + { + printf("LP_rawtx_spendscript %s datalen.%d too big\n",rawtx->name,datalen); + return(-1); + } + rawtx->I.redeemlen = recvbuf[offset++]; + data = &recvbuf[offset]; + if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 ) + { + memcpy(rawtx->redeemscript,&data[datalen],rawtx->I.redeemlen); + //for (i=0; iI.redeemlen; i++) + // printf("%02x",rawtx->redeemscript[i]); + bitcoin_address(coin->symbol,redeemaddr,coin->taddr,coin->p2shtype,rawtx->redeemscript,rawtx->I.redeemlen); + //printf(" received redeemscript.(%s) %s taddr.%d\n",redeemaddr,coin->symbol,coin->taddr); + LP_swap_coinaddr(coin,checkaddr,0,data,datalen,0); + if ( strcmp(redeemaddr,checkaddr) != 0 ) + { + printf("REDEEMADDR MISMATCH??? %s != %s\n",redeemaddr,checkaddr); + return(-1); + } + } + //printf("recvlen.%d datalen.%d redeemlen.%d\n",recvlen,datalen,rawtx->redeemlen); + if ( rawtx->I.datalen == 0 ) + { + //for (i=0; itxbytes,data,datalen); + rawtx->I.datalen = datalen; + } + else if ( datalen != rawtx->I.datalen || memcmp(rawtx->txbytes,data,datalen) != 0 ) + { + for (i=0; iI.datalen; i++) + printf("%02x",rawtx->txbytes[i]); + printf(" <- rawtx\n"); + printf("%s rawtx data compare error, len %d vs %d <<<<<<<<<< warning\n",rawtx->name,rawtx->I.datalen,datalen); + return(-1); + } + if ( recvlen != datalen+rawtx->I.redeemlen+75 ) + printf("RECVLEN %d != %d + %d\n",recvlen,datalen,rawtx->I.redeemlen); + txid = bits256_calctxid(coin->symbol,data,datalen); + //char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid)); + if ( bits256_cmp(txid,rawtx->I.actualtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) + rawtx->I.actualtxid = txid; + if ( (txobj= bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,height,&rawtx->I.signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 ) + { + rawtx->I.actualtxid = rawtx->I.signedtxid; + rawtx->I.locktime = rawtx->msgtx.lock_time; + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && v < n ) + { + vout = jitem(vouts,v); + if ( strcmp("BTC",coin->symbol) == 0 && rawtx == &swap->otherfee ) + txfee = LP_MIN_TXFEE; + else + { + if ( strcmp(coin->symbol,swap->I.bobstr) == 0 ) + txfee = swap->I.Btxfee; + else if ( strcmp(coin->symbol,swap->I.alicestr) == 0 ) + txfee = swap->I.Atxfee; + else txfee = LP_MIN_TXFEE; + } + if ( rawtx->I.amount > 2*txfee) + val = rawtx->I.amount-2*txfee; + else val = 1; + if ( j64bits(vout,"satoshis") >= val && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) + { + if ( (hexlen= (int32_t)strlen(hexstr) >> 1) < sizeof(rawtx->spendscript) ) + { + decode_hex(rawtx->spendscript,hexlen,hexstr); + rawtx->I.spendlen = hexlen; + //if ( swap != 0 ) + // basilisk_txlog(swap->myinfoptr,swap,rawtx,-1); // bobdeposit, bobpayment or alicepayment + retval = 0; + if ( rawtx == &swap->otherfee ) + { + LP_swap_coinaddr(coin,rawtx->p2shaddr,0,data,datalen,0); + //printf("got %s txid.%s (%s) -> %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),jprint(txobj,0),rawtx->p2shaddr); + } else bitcoin_address(coin->symbol,rawtx->p2shaddr,coin->taddr,coin->p2shtype,rawtx->spendscript,hexlen); + } + } else printf("%s satoshis %.8f ERROR.(%s) txfees.[%.8f %.8f: %.8f] amount.%.8f -> %.8f\n",rawtx->name,dstr(j64bits(vout,"satoshis")),jprint(txobj,0),dstr(swap->I.Atxfee),dstr(swap->I.Btxfee),dstr(txfee),dstr(rawtx->I.amount),dstr(rawtx->I.amount)-dstr(txfee)); + } + free_json(txobj); + } + return(retval); +} + +uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits,int32_t suppress_swapsend) +{ + uint8_t sendbuf[32768]; int32_t sendlen,retval = -1; + if ( LP_swapdata_rawtx(swap,data,maxlen,rawtx) != 0 ) + { + if ( bits256_nonz(rawtx->I.signedtxid) != 0 && bits256_nonz(rawtx->I.actualtxid) == 0 ) + { + rawtx->I.actualtxid = LP_broadcast_tx(rawtx->name,rawtx->symbol,rawtx->txbytes,rawtx->I.datalen); + if ( bits256_cmp(rawtx->I.actualtxid,rawtx->I.signedtxid) != 0 ) + { + char str[65],str2[65]; + printf("%s rawtxsend.[%d] %s vs %s\n",rawtx->name,rawtx->I.datalen,bits256_str(str,rawtx->I.signedtxid),bits256_str(str2,rawtx->I.actualtxid)); + if ( bits256_nonz(rawtx->I.signedtxid) != 0 ) + rawtx->I.actualtxid = rawtx->I.signedtxid; + else rawtx->I.signedtxid = rawtx->I.actualtxid; + } + if ( bits256_nonz(rawtx->I.actualtxid) != 0 && msgbits != 0 ) + { + sendlen = 0; + sendbuf[sendlen++] = rawtx->I.datalen & 0xff; + sendbuf[sendlen++] = (rawtx->I.datalen >> 8) & 0xff; + sendbuf[sendlen++] = rawtx->I.redeemlen; + //int32_t z; for (z=0; zI.datalen; z++) printf("%02x",rawtx->txbytes[z]); printf(" >>>>>>> send.%d %s\n",rawtx->I.datalen,rawtx->name); + //printf("datalen.%d redeemlen.%d\n",rawtx->I.datalen,rawtx->I.redeemlen); + memcpy(&sendbuf[sendlen],rawtx->txbytes,rawtx->I.datalen), sendlen += rawtx->I.datalen; + if ( rawtx->I.redeemlen > 0 && rawtx->I.redeemlen < 0x100 ) + { + memcpy(&sendbuf[sendlen],rawtx->redeemscript,rawtx->I.redeemlen); + sendlen += rawtx->I.redeemlen; + } + basilisk_dontforget_update(swap,rawtx); + //printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen); + if ( suppress_swapsend == 0 ) + { + retval = LP_swapsend(pairsock,swap,msgbits,sendbuf,sendlen,nextbits,rawtx->I.crcs); + if ( LP_waitmempool(rawtx->symbol,rawtx->I.destaddr,rawtx->I.signedtxid,0,LP_SWAPSTEP_TIMEOUT*10) < 0 ) + { + char str[65]; printf("failed to find %s %s %s in the mempool?\n",rawtx->name,rawtx->I.destaddr,bits256_str(str,rawtx->I.actualtxid)); + retval = -1; + } + return(retval); + } + else + { + printf("suppress swapsend %x\n",msgbits); + return(0); + } + } + } + return(nextbits); + } //else if ( swap->I.iambob == 0 ) + printf("error from basilisk_swapdata_rawtx.%s %p len.%d\n",rawtx->name,rawtx->txbytes,rawtx->I.datalen); + return(0); +} + +int32_t LP_swapwait(struct basilisk_swap *swap,uint32_t requestid,uint32_t quoteid,int32_t duration,int32_t sleeptime) +{ + char *retstr; cJSON *retjson=0; uint32_t expiration = (uint32_t)(time(NULL) + duration); + printf("wait %d:%d for SWAP.(r%u/q%u) to complete\n",duration,sleeptime,requestid,quoteid); + sleep(sleeptime/3); + //if ( sleeptime < divisor*60 ) + // sleeptime = divisor * 60; + while ( time(NULL) < expiration ) + { + if ( (retstr= basilisk_swapentry(requestid,quoteid,1)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jstr(retjson,"status") != 0 && strcmp(jstr(retjson,"status"),"finished") == 0 ) + { + swap->I.finished = (uint32_t)time(NULL); + break; + } + //else printf("NOT FINISHED.(%s)\n",jprint(retjson,0)); + free_json(retjson); + retjson = 0; + } + free(retstr); + } + sleep(sleeptime); + //sleep(sleeptime/divisor); + //if ( divisor > 1 ) + // divisor--; + } + if ( retjson != 0 ) + { + printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>\nSWAP completed! %u-%u %s\n",requestid,quoteid,jprint(retjson,0)); + free_json(retjson); + if ( 0 && (retstr= basilisk_swapentry(requestid,quoteid,1)) != 0 ) + { + printf("second call.(%s)\n",retstr); + free(retstr); + } + return(0); + } else return(-1); +} + +void LP_bobloop(void *_swap) +{ + uint8_t *data; int32_t maxlen,m,n; uint32_t expiration; struct basilisk_swap *swap = _swap; + G.LP_pendingswaps++; + printf("start swap iambob\n"); + maxlen = 1024*1024 + sizeof(*swap); + data = malloc(maxlen); + expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; + if ( swap != 0 ) + { + if ( LP_waitsend("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) + printf("error waitsend pubkeys\n"); + else if ( LP_waitsend("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) + printf("error waitsend choosei\n"); + else if ( LP_waitsend("mostprivs",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 ) + printf("error waitsend mostprivs\n"); + else if ( basilisk_bobscripts_set(swap,1,1) < 0 ) + printf("error bobscripts deposit\n"); + else + { + swap->bobrefund.utxovout = 0; + swap->bobrefund.utxotxid = swap->bobdeposit.I.signedtxid; + basilisk_bobdeposit_refund(swap,swap->I.putduration); + //printf("depositlen.%d\n",swap->bobdeposit.I.datalen); + LP_swapsfp_update(&swap->I.req); + LP_swap_critical = (uint32_t)time(NULL); + if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_otherfee) < 0 ) + printf("error waiting for alicefee\n"); + else if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0) == 0 ) + printf("error sending bobdeposit\n"); + else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_alicepayment) < 0 ) + printf("error waiting for alicepayment\n"); + else + { + LP_swap_critical = (uint32_t)time(NULL); + if ( basilisk_bobscripts_set(swap,0,1) < 0 ) + printf("error bobscripts payment\n"); + else + { + /*if ( strcmp(swap->I.alicestr,"BTC") == 0 ) + m = 0; + else*/ m = swap->I.aliceconfirms; + while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) // sync with alice + { + LP_swap_critical = (uint32_t)time(NULL); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); + sleep(10); + } + LP_swap_critical = (uint32_t)time(NULL); + if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0) == 0 ) + printf("error sending bobpayment\n"); + //if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_alicespend) < 0 ) + // printf("error waiting for alicespend\n"); + //swap->sentflag = 1; + swap->bobreclaim.utxovout = 0; + swap->bobreclaim.utxotxid = swap->bobpayment.I.signedtxid; + basilisk_bobpayment_reclaim(swap,swap->I.callduration); + if ( swap->N.pair >= 0 ) + nn_close(swap->N.pair), swap->N.pair = -1; + LP_swap_endcritical = (uint32_t)time(NULL); + LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); + } + } + } + } else printf("swap timed out\n"); + G.LP_pendingswaps--; + basilisk_swap_finished(swap); + free(swap); + free(data); +} + +void LP_aliceloop(void *_swap) +{ + uint8_t *data; int32_t maxlen,n,m; uint32_t expiration; struct basilisk_swap *swap = _swap; + G.LP_pendingswaps++; + maxlen = 1024*1024 + sizeof(*swap); + data = malloc(maxlen); + expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT; + if ( swap != 0 ) + { + printf("start swap iamalice pair.%d\n",swap->N.pair); + if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 ) + printf("error LP_sendwait pubkeys\n"); + else if ( LP_sendwait("choosei",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_choosei_verify,LP_choosei_data) < 0 ) + printf("error LP_sendwait choosei\n"); + else if ( LP_sendwait("mostprivs",LP_SWAPSTEP_TIMEOUT,swap->N.pair,swap,data,maxlen,LP_mostprivs_verify,LP_mostprivs_data) < 0 ) + printf("error LP_sendwait mostprivs\n"); + else if ( basilisk_alicetxs(swap->N.pair,swap,data,maxlen) != 0 ) + printf("basilisk_alicetxs error\n"); + else + { + LP_swapsfp_update(&swap->I.req); + LP_swap_critical = (uint32_t)time(NULL); + if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 ) + printf("error sending alicefee\n"); + else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobdeposit) < 0 ) + printf("error waiting for bobdeposit\n"); + else + { + /*if ( strcmp(swap->I.bobstr,"BTC") == 0 ) + m = 0; + else*/ m = swap->I.bobconfirms; + while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,1)) < m ) + { + LP_swap_critical = (uint32_t)time(NULL); + char str[65];printf("%d wait for bobdeposit %s numconfs.%d %s %s\n",n,swap->bobdeposit.I.destaddr,m,swap->I.bobstr,bits256_str(str,swap->bobdeposit.I.signedtxid)); + sleep(10); + } + if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0) == 0 ) + printf("error sending alicepayment\n"); + else + { + /*if ( strcmp(swap->I.alicestr,"BTC") == 0 ) + m = 0; + else*/ m = swap->I.aliceconfirms; + while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,1)) < m ) + { + LP_swap_critical = (uint32_t)time(NULL); + char str[65];printf("%d wait for alicepayment %s numconfs.%d %s %s\n",n,swap->alicepayment.I.destaddr,m,swap->I.alicestr,bits256_str(str,swap->alicepayment.I.signedtxid)); + sleep(10); + } + //swap->sentflag = 1; + LP_swap_critical = (uint32_t)time(NULL); + if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 ) + printf("error waiting for bobpayment\n"); + else + { + LP_swap_endcritical = (uint32_t)time(NULL); + while ( (n= LP_numconfirms(swap->I.bobstr,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,1)) < swap->I.bobconfirms ) + { + char str[65];printf("%d wait for bobpayment %s numconfs.%d %s %s\n",n,swap->bobpayment.I.destaddr,swap->I.bobconfirms,swap->I.bobstr,bits256_str(str,swap->bobpayment.I.signedtxid)); + sleep(10); + } + /*if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x20000,data,maxlen,&swap->alicespend,0x40000,0) == 0 ) + printf("error sending alicespend\n"); + while ( (n= LP_numconfirms(swap->I.alicestr,swap->alicespend.I.destaddr,swap->alicespend.I.signedtxid,0,1)) < swap->I.aliceconfirms ) + { + char str[65];printf("%d wait for alicespend %s numconfs.%d %s %s\n",n,swap->alicespend.I.destaddr,swap->I.aliceconfirms,swap->I.bobstr,bits256_str(str,swap->alicespend.I.signedtxid)); + sleep(LP_SWAPSTEP_TIMEOUT); + }*/ + if ( swap->N.pair >= 0 ) + nn_close(swap->N.pair), swap->N.pair = -1; + LP_swap_endcritical = (uint32_t)time(NULL); + LP_swapwait(swap,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*2,swap->I.aliceconfirms == 0 ? 3 : 30); + } + } + } + } + } + free(data); + basilisk_swap_finished(swap); + free(swap); + G.LP_pendingswaps--; +} + +bits256 instantdex_derivekeypair(void *ctx,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) +{ + bits256 sharedsecret; + sharedsecret = curve25519_shared(privkey,orderhash); + vcalc_sha256cat(newprivp->bytes,orderhash.bytes,sizeof(orderhash),sharedsecret.bytes,sizeof(sharedsecret)); + return(bitcoin_pubkey33(ctx,pubkey,*newprivp)); +} + +bits256 basilisk_revealkey(bits256 privkey,bits256 pubkey) +{ + bits256 reveal; +#ifdef DISABLE_CHECKSIG + vcalc_sha256(0,reveal.bytes,privkey.bytes,sizeof(privkey)); + //reveal = revcalc_sha256(privkey); + char str[65],str2[65]; printf("priv.(%s) -> reveal.(%s)\n",bits256_str(str,privkey),bits256_str(str2,reveal)); +#else + reveal = pubkey; +#endif + return(reveal); +} + +int32_t instantdex_pubkeyargs(struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) +{ + char buf[3]; int32_t i,n,m,len=0; bits256 pubi,reveal; uint64_t txid; uint8_t secret160[20],pubkey[33]; + sprintf(buf,"%c0",'A' - 0x02 + firstbyte); + if ( numpubs > 2 ) + { + if ( swap->I.numpubs+2 >= numpubs ) + return(numpubs); + //printf(">>>>>> start generating %s\n",buf); + } + for (i=n=m=0; ictx,&privkey,pubkey,privkey,hash); + //printf("i.%d n.%d numpubs.%d %02x vs %02x\n",i,n,numpubs,pubkey[0],firstbyte); + if ( pubkey[0] != firstbyte ) + continue; + if ( n < 2 ) + { + if ( bits256_nonz(swap->I.mypubs[n]) == 0 ) + { + swap->I.myprivs[n] = privkey; + memcpy(swap->I.mypubs[n].bytes,pubkey+1,sizeof(bits256)); + reveal = basilisk_revealkey(privkey,swap->I.mypubs[n]); + if ( swap->I.iambob != 0 ) + { + if ( n == 0 ) + swap->I.pubB0 = reveal; + else if ( n == 1 ) + swap->I.pubB1 = reveal; + } + else if ( swap->I.iambob == 0 ) + { + if ( n == 0 ) + swap->I.pubA0 = reveal; + else if ( n == 1 ) + swap->I.pubA1 = reveal; + } + } + } + if ( m < INSTANTDEX_DECKSIZE ) + { + swap->privkeys[m] = privkey; + revcalc_rmd160_sha256(secret160,privkey);//.bytes,sizeof(privkey)); + memcpy(&txid,secret160,sizeof(txid)); + len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][0],sizeof(txid),&txid); + len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][1],sizeof(pubi.txid),&pubi.txid); + m++; + if ( m > swap->I.numpubs ) + swap->I.numpubs = m; + } + n++; + } + //if ( n > 2 || m > 2 ) + // printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->I.numpubs); + return(n); +} + +void basilisk_rawtx_setparms(char *name,uint32_t quoteid,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33,int32_t jumblrflag) +{ +#ifdef BASILISK_DISABLEWAITTX + numconfirms = 0; +#endif + strcpy(rawtx->name,name); + //printf("set coin.%s %s -> %s\n",coin->symbol,coin->smartaddr,name); + strcpy(rawtx->symbol,coin->symbol); + rawtx->I.numconfirms = numconfirms; + if ( (rawtx->I.amount= satoshis) < LP_MIN_TXFEE ) + rawtx->I.amount = LP_MIN_TXFEE; + rawtx->I.vintype = vintype; // 0 -> std, 2 -> 2of2, 3 -> spend bobpayment, 4 -> spend bobdeposit + rawtx->I.vouttype = vouttype; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit + if ( rawtx->I.vouttype == 0 ) + { + if ( strcmp(coin->symbol,"BTC") == 0 && (quoteid % 10) == 0 ) + decode_hex(rawtx->I.rmd160,20,TIERNOLAN_RMD160); + else decode_hex(rawtx->I.rmd160,20,INSTANTDEX_RMD160); + bitcoin_address(coin->symbol,rawtx->I.destaddr,coin->taddr,coin->pubtype,rawtx->I.rmd160,20); + } + if ( pubkey33 != 0 ) + { + memcpy(rawtx->I.pubkey33,pubkey33,33); + bitcoin_address(coin->symbol,rawtx->I.destaddr,coin->taddr,coin->pubtype,rawtx->I.pubkey33,33); + bitcoin_addr2rmd160(coin->symbol,coin->taddr,&rawtx->I.addrtype,rawtx->I.rmd160,rawtx->I.destaddr); + } + if ( rawtx->I.vouttype <= 1 && rawtx->I.destaddr[0] != 0 ) + { + rawtx->I.spendlen = bitcoin_standardspend(rawtx->spendscript,0,rawtx->I.rmd160); + //printf("%s spendlen.%d %s <- %.8f\n",name,rawtx->I.spendlen,rawtx->I.destaddr,dstr(rawtx->I.amount)); + } //else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr); +} + +struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256 pubkey25519,struct basilisk_swap *swap,int32_t optionduration,uint32_t statebits,struct LP_quoteinfo *qp,int32_t dynamictrust) +{ + //FILE *fp; char fname[512]; + uint8_t *alicepub33=0,*bobpub33=0; int32_t jumblrflag=-2,x = -1; struct iguana_info *bobcoin,*alicecoin; + strcpy(swap->I.bobstr,swap->I.req.src); + strcpy(swap->I.alicestr,swap->I.req.dest); + if ( (alicecoin= LP_coinfind(swap->I.alicestr)) == 0 ) + { + printf("missing alicecoin src.%p dest.%p\n",LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + free(swap); + return(0); + } + if ( (bobcoin= LP_coinfind(swap->I.bobstr)) == 0 ) + { + printf("missing bobcoin src.%p dest.%p\n",LP_coinfind(swap->I.req.src),LP_coinfind(swap->I.req.dest)); + free(swap); + return(0); + } + if ( (swap->I.Atxfee= qp->desttxfee) < 0 ) + { + printf("bitcoin_swapinit %s Atxfee %.8f rejected\n",swap->I.req.dest,dstr(swap->I.Atxfee)); + return(0); + } + if ( (swap->I.Btxfee= qp->txfee) < 0 ) + { + printf("bitcoin_swapinit %s Btxfee %.8f rejected\n",swap->I.req.src,dstr(swap->I.Btxfee)); + return(0); + } + swap->I.putduration = swap->I.callduration = LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr); + if ( optionduration < 0 ) + swap->I.putduration -= optionduration; + else if ( optionduration > 0 ) + swap->I.callduration += optionduration; + if ( (swap->I.bobsatoshis= swap->I.req.srcamount) <= 0 ) + { + printf("bitcoin_swapinit %s bobsatoshis %.8f rejected\n",swap->I.req.src,dstr(swap->I.bobsatoshis)); + return(0); + } + if ( (swap->I.alicesatoshis= swap->I.req.destamount) <= 0 ) + { + printf("bitcoin_swapinit %s alicesatoshis %.8f rejected\n",swap->I.req.dest,dstr(swap->I.alicesatoshis)); + return(0); + } + if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) + swap->I.bobinsurance = LP_MIN_TXFEE; + if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE ) + swap->I.aliceinsurance = LP_MIN_TXFEE; + swap->I.started = qp->timestamp;//(uint32_t)time(NULL); + swap->I.expiration = swap->I.req.timestamp + swap->I.putduration + swap->I.callduration; + OS_randombytes((uint8_t *)&swap->I.choosei,sizeof(swap->I.choosei)); + if ( swap->I.choosei < 0 ) + swap->I.choosei = -swap->I.choosei; + swap->I.choosei %= INSTANTDEX_DECKSIZE; + swap->I.otherchoosei = -1; + swap->I.myhash = pubkey25519; + if ( statebits != 0 ) + { + swap->I.iambob = 0; + swap->I.otherhash = swap->I.req.desthash; + swap->I.aliceistrusted = 1; + if ( dynamictrust == 0 && LP_pubkey_istrusted(swap->I.req.srchash) != 0 ) + dynamictrust = 1; + swap->I.otheristrusted = swap->I.bobistrusted = dynamictrust; + } + else + { + swap->I.iambob = 1; + swap->I.otherhash = swap->I.req.srchash; + swap->I.bobistrusted = 1; + if ( dynamictrust == 0 && LP_pubkey_istrusted(swap->I.req.desthash) != 0 ) + dynamictrust = 1; + swap->I.otheristrusted = swap->I.aliceistrusted = dynamictrust; + } + if ( bits256_nonz(privkey) == 0 || (x= instantdex_pubkeyargs(swap,2 + INSTANTDEX_DECKSIZE,privkey,swap->I.orderhash,0x02+swap->I.iambob)) != 2 + INSTANTDEX_DECKSIZE ) + { + char str[65]; printf("couldnt generate privkeys %d %s\n",x,bits256_str(str,privkey)); + return(0); + } + if ( strcmp("BTC",swap->I.bobstr) == 0 ) + { + swap->I.bobconfirms = 1;//(1 + sqrt(dstr(swap->I.bobsatoshis) * .1)); + swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + } + else if ( strcmp("BTC",swap->I.alicestr) == 0 ) + { + swap->I.aliceconfirms = 1;//(1 + sqrt(dstr(swap->I.alicesatoshis) * .1)); + swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + } + else + { + swap->I.bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + swap->I.aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS; + } + if ( bobcoin->isassetchain != 0 ) + swap->I.bobconfirms = 1; + if ( alicecoin->isassetchain != 0 ) + swap->I.aliceconfirms = 1; + if ( bobcoin->userconfirms > 0 ) + swap->I.bobconfirms = bobcoin->userconfirms; + if ( alicecoin->userconfirms > 0 ) + swap->I.aliceconfirms = alicecoin->userconfirms; + if ( (swap->I.bobmaxconfirms= bobcoin->maxconfirms) == 0 ) + swap->I.bobmaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS; + if ( (swap->I.alicemaxconfirms= alicecoin->maxconfirms) == 0 ) + swap->I.alicemaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS; + if ( swap->I.bobconfirms > swap->I.bobmaxconfirms ) + swap->I.bobconfirms = swap->I.bobmaxconfirms; + if ( swap->I.aliceconfirms > swap->I.alicemaxconfirms ) + swap->I.aliceconfirms = swap->I.alicemaxconfirms; + if ( strcmp("BAY",swap->I.req.src) != 0 && strcmp("BAY",swap->I.req.dest) != 0 ) + { + swap->I.bobconfirms *= !swap->I.bobistrusted; + swap->I.aliceconfirms *= !swap->I.aliceistrusted; + } + printf(">>>>>>>>>> jumblrflag.%d <<<<<<<<< r.%u q.%u, %.8f bobconfs.%d, %.8f aliceconfs.%d taddr.%d %d\n",jumblrflag,swap->I.req.requestid,swap->I.req.quoteid,dstr(swap->I.bobsatoshis),swap->I.bobconfirms,dstr(swap->I.alicesatoshis),swap->I.aliceconfirms,bobcoin->taddr,alicecoin->taddr); + if ( swap->I.iambob != 0 ) + { + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*bobcoin->txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*alicecoin->txfee,0,0,jumblrflag); + bobpub33 = pubkey33; + } + else + { + basilisk_rawtx_setparms("otherfee",swap->I.req.quoteid,&swap->otherfee,bobcoin,0,0,LP_DEXFEE(swap->I.bobsatoshis) + 0*bobcoin->txfee,0,0,jumblrflag); + basilisk_rawtx_setparms("myfee",swap->I.req.quoteid,&swap->myfee,alicecoin,0,0,LP_DEXFEE(swap->I.alicesatoshis) + 0*alicecoin->txfee,0,0,jumblrflag); + alicepub33 = pubkey33; + } + swap->myfee.I.locktime = swap->I.started + 1; + swap->otherfee.I.locktime = swap->I.started + 1; + basilisk_rawtx_setparms("bobdeposit",swap->I.req.quoteid,&swap->bobdeposit,bobcoin,swap->I.bobconfirms,0,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis) + 2*bobcoin->txfee,4,0,jumblrflag); + basilisk_rawtx_setparms("bobrefund",swap->I.req.quoteid,&swap->bobrefund,bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,bobpub33,jumblrflag); + swap->bobrefund.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("aliceclaim",swap->I.req.quoteid,&swap->aliceclaim,bobcoin,1,4,LP_DEPOSITSATOSHIS(swap->I.bobsatoshis),1,alicepub33,jumblrflag); + swap->aliceclaim.I.suppress_pubkeys = 1; + swap->aliceclaim.I.locktime = swap->I.started + swap->I.putduration+swap->I.callduration + 1; + + basilisk_rawtx_setparms("bobpayment",swap->I.req.quoteid,&swap->bobpayment,bobcoin,swap->I.bobconfirms,0,swap->I.bobsatoshis + 2*bobcoin->txfee,3,0,jumblrflag); + basilisk_rawtx_setparms("alicespend",swap->I.req.quoteid,&swap->alicespend,bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,alicepub33,jumblrflag); + swap->alicespend.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("bobreclaim",swap->I.req.quoteid,&swap->bobreclaim,bobcoin,swap->I.bobconfirms,3,swap->I.bobsatoshis,1,bobpub33,jumblrflag); + swap->bobreclaim.I.suppress_pubkeys = 1; + swap->bobreclaim.I.locktime = swap->I.started + swap->I.putduration + 1; + basilisk_rawtx_setparms("alicepayment",swap->I.req.quoteid,&swap->alicepayment,alicecoin,swap->I.aliceconfirms,0,swap->I.alicesatoshis + 2*alicecoin->txfee,2,0,jumblrflag); + basilisk_rawtx_setparms("bobspend",swap->I.req.quoteid,&swap->bobspend,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,bobpub33,jumblrflag); + swap->bobspend.I.suppress_pubkeys = 1; + basilisk_rawtx_setparms("alicereclaim",swap->I.req.quoteid,&swap->alicereclaim,alicecoin,swap->I.aliceconfirms,2,swap->I.alicesatoshis,1,alicepub33,jumblrflag); + swap->alicereclaim.I.suppress_pubkeys = 1; + swap->bobpayment.utxotxid = qp->txid, swap->bobpayment.utxovout = qp->vout; + swap->bobdeposit.utxotxid = qp->txid2, swap->bobdeposit.utxovout = qp->vout2; + swap->alicepayment.utxotxid = qp->desttxid, swap->alicepayment.utxovout = qp->destvout; + LP_mark_spent(swap->I.bobstr,qp->txid,qp->vout); + LP_mark_spent(swap->I.bobstr,qp->txid2,qp->vout2); + LP_mark_spent(swap->I.alicestr,qp->desttxid,qp->destvout); + if ( swap->I.iambob != 0 ) + swap->otherfee.utxotxid = qp->feetxid, swap->otherfee.utxovout = qp->feevout; + else + { + swap->myfee.utxotxid = qp->feetxid, swap->myfee.utxovout = qp->feevout; + LP_mark_spent(swap->I.alicestr,qp->feetxid,qp->feevout); + } + //char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s [%s %s]\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid),swap->I.bobstr,swap->I.alicestr); + return(swap); +} + +struct basilisk_swap *LP_swapinit(int32_t iambob,int32_t optionduration,bits256 privkey,struct basilisk_request *rp,struct LP_quoteinfo *qp,int32_t dynamictrust) +{ + struct basilisk_swap *swap; bits256 pubkey25519; uint8_t pubkey33[33]; + swap = calloc(1,sizeof(*swap)); + swap->aliceid = LP_aliceid_calc(qp->desttxid,qp->destvout,qp->feetxid,qp->feevout); + swap->I.req.quoteid = rp->quoteid; + swap->ctx = bitcoin_ctx(); + vcalc_sha256(0,swap->I.orderhash.bytes,(uint8_t *)rp,sizeof(*rp)); + swap->I.req = *rp; + G.LP_skipstatus[G.LP_numskips] = ((uint64_t)rp->requestid << 32) | rp->quoteid; + if ( G.LP_numskips < sizeof(G.LP_skipstatus)/sizeof(*G.LP_skipstatus) ) + G.LP_numskips++; + printf("LP_swapinit request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid); + bitcoin_pubkey33(swap->ctx,pubkey33,privkey); + pubkey25519 = curve25519(privkey,curve25519_basepoint9()); + swap->persistent_pubkey = pubkey25519; + swap->persistent_privkey = privkey; + memcpy(swap->persistent_pubkey33,pubkey33,33); + calc_rmd160_sha256(swap->changermd160,pubkey33,33); + if ( bitcoin_swapinit(privkey,pubkey33,pubkey25519,swap,optionduration,!iambob,qp,dynamictrust) == 0 ) + { + printf("error doing swapinit\n"); + free(swap); + swap = 0; + } + return(swap); +} + diff --git a/iguana/exchanges/LP_tradebots.c b/iguana/exchanges/LP_tradebots.c new file mode 100644 index 000000000..39526c2be --- /dev/null +++ b/iguana/exchanges/LP_tradebots.c @@ -0,0 +1,694 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_tradebots.c +// marketmaker +// + +#define TRADEBOTS_GAPTIME 120 +#define LP_TRADEBOTS_MAXTRADES 10 + +struct LP_tradebot_trade +{ + double maxprice,totalrelvolume,basevol,relvol; + uint64_t aliceid; + int32_t dispdir; + uint32_t started,finished,requestid,quoteid,tradeid,expired; + char base[65],rel[65],event[32]; +}; + +struct LP_tradebot +{ + struct LP_tradebot *next,*prev; + char name[128],base[65],rel[65]; + int32_t numtrades,numpending,completed,dispdir; + double maxprice,totalrelvolume,totalbasevolume,basesum,relsum,pendbasesum,pendrelsum; + uint32_t lasttime,dead,pause,userpause,started,id; + struct LP_tradebot_trade *trades[LP_TRADEBOTS_MAXTRADES]; +} *LP_tradebots; + +void LP_tradebot_pauseall() +{ + struct LP_tradebot *bot,*tmp; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + bot->userpause = bot->pause = (uint32_t)time(NULL); + } +} + +void LP_tradebot_updatestats(struct LP_tradebot *bot,struct LP_tradebot_trade *tp) +{ + char *swapstr,*status; int32_t flag; cJSON *swapjson; + if ( (swapstr= basilisk_swapentry(tp->requestid,tp->quoteid,1)) != 0 ) + { + flag = 0; + if ( (swapjson= cJSON_Parse(swapstr)) != 0 ) + { + tp->basevol = dstr(j64bits(swapjson,"satoshis")); + tp->relvol = dstr(j64bits(swapjson,"destsatoshis")); + tp->aliceid = j64bits(swapjson,"aliceid"); + if ( (status= jstr(swapjson,"status")) != 0 ) + { + if ( strcmp(status,"finished") == 0 ) + { + if ( tp->finished == 0 ) + tp->finished = (uint32_t)time(NULL); + } + } + free_json(swapjson); + } + free(swapstr); + } +} + +void LP_tradebot_calcstats(struct LP_tradebot *bot) +{ + int32_t i; struct LP_tradebot_trade *tp; + bot->basesum = bot->relsum = bot->pendbasesum = bot->pendrelsum = 0.; + bot->numpending = bot->completed = 0; + for (i=0; inumtrades; i++) + { + if ( (tp= bot->trades[i]) == 0 ) + continue; + if ( tp->finished == 0 && time(NULL) > tp->started+LP_atomic_locktime(bot->base,bot->rel)*2 ) + { + tp->expired = tp->finished = (uint32_t)time(NULL); + printf("tradeid.%u expired\n",tp->tradeid); + } + if ( tp->finished != 0 ) + { + if ( tp->expired == 0 ) + { + bot->basesum += tp->basevol; + bot->relsum += tp->relvol; + bot->completed++; + } + } + else + { + if ( tp->requestid != 0 && tp->quoteid != 0 ) + { + bot->pendbasesum += tp->basevol; + bot->pendrelsum += tp->relvol; + bot->numpending++; + } + } + //LP_tradebot_updatestats(bot,bot->trades[i]); + } + //printf("completed.%d (%.8f / %.8f) pending.%d (%.8f / %.8f)\n",bot->completed,bot->basesum,bot->relsum,bot->numpending,bot->pendbasesum,bot->pendrelsum); +} + +double LP_pricevol_invert(double *basevolumep,double maxprice,double relvolume) +{ + double price; + *basevolumep = 0.; + if ( maxprice > SMALLVAL && maxprice < SATOSHIDEN ) + { + price = (1. / maxprice); + *basevolumep = (relvolume * price); + return(price); + } + return(0.); +} + +cJSON *LP_tradebot_tradejson(struct LP_tradebot_trade *tp,int32_t dispflag) +{ + double price,basevol; cJSON *item = cJSON_CreateObject(); + if ( tp == 0 ) + return(cJSON_Parse("{}")); + if ( tp->event[0] != 0 ) + jaddstr(item,"status",tp->event); + if ( tp->requestid != 0 && tp->quoteid != 0 ) + { + jaddnum(item,"requestid",tp->requestid); + jaddnum(item,"quoteid",tp->quoteid); + } else jaddnum(item,"tradeid",tp->tradeid); + if ( tp->aliceid != 0 ) + jadd64bits(item,"aliceid",tp->aliceid); + if ( tp->basevol > SMALLVAL && tp->relvol > SMALLVAL ) + { + if ( dispflag > 0 ) + { + jaddnum(item,"price",tp->relvol/tp->basevol); + jaddnum(item,"volume",tp->relvol); + } + else + { + price = LP_pricevol_invert(&basevol,tp->relvol / tp->basevol,tp->relvol); + jaddnum(item,"price",price); + jaddnum(item,"volume",basevol); + } + } + return(item); +} + +cJSON *LP_tradebot_json(struct LP_tradebot *bot) +{ + int32_t i; double aveprice,basevolume,vol; cJSON *json,*array; + LP_tradebot_calcstats(bot); + json = cJSON_CreateObject(); + jaddstr(json,"result","success"); + jaddstr(json,"name",bot->name); + jaddnum(json,"botid",bot->id); + jaddnum(json,"started",bot->started); + if ( bot->pause != 0 || bot->userpause != 0 ) + jaddnum(json,"paused",bot->userpause != 0 ? bot->userpause : bot->pause); + if ( bot->dead != 0 ) + jaddnum(json,"stopped",bot->dead); + if ( bot->dispdir > 0 ) + { + jaddstr(json,"action","buy"); + jaddstr(json,"base",bot->base); + jaddstr(json,"rel",bot->rel); + jaddnum(json,"maxprice",bot->maxprice); + jaddnum(json,"totalrelvolume",bot->totalrelvolume); + jaddnum(json,"totalbasevolume",bot->totalbasevolume); + if ( (vol= bot->relsum) > SMALLVAL && bot->basesum > SMALLVAL ) + { + jaddnum(json,"aveprice",vol/bot->basesum); + jaddnum(json,"volume",vol); + } + } + else + { + jaddstr(json,"action","sell"); + jaddstr(json,"base",bot->rel); + jaddstr(json,"rel",bot->base); + aveprice = LP_pricevol_invert(&basevolume,bot->maxprice,bot->totalrelvolume); + jaddnum(json,"minprice",aveprice); + jaddnum(json,"totalbasevolume",bot->totalrelvolume); + jaddnum(json,"totalrelvolume",basevolume); + if ( (vol= bot->relsum) > SMALLVAL && bot->basesum > SMALLVAL ) + { + aveprice = LP_pricevol_invert(&basevolume,vol/bot->basesum,vol); + jaddnum(json,"aveprice",aveprice); + jaddnum(json,"volume",basevolume); + } + } + array = cJSON_CreateArray(); + for (i=0; inumtrades; i++) + jaddi(array,LP_tradebot_tradejson(bot->trades[i],bot->dispdir)); + jadd(json,"trades",array); + if ( bot->basesum > SMALLVAL && bot->relsum > SMALLVAL && bot->completed > 0 ) + { + jadd(json,"complete",bot->completed!=0?jtrue():jfalse()); + jaddnum(json,"percentage",100. * (bot->relsum / bot->totalrelvolume)); + if ( bot->dispdir > 0 ) + { + jaddnum(json,"aveprice",bot->relsum / bot->basesum); + jaddnum(json,"volume",bot->relsum); + } + else + { + jaddnum(json,"aveprice",bot->basesum / bot->relsum); + jaddnum(json,"volume",bot->basesum); + } + } + if ( bot->pendbasesum > SMALLVAL && bot->pendrelsum > SMALLVAL && bot->numpending > 0 ) + { + jaddnum(json,"pending",bot->numpending); + if ( bot->dispdir > 0 ) + { + jaddnum(json,"pendingprice",bot->pendrelsum / bot->pendbasesum); + jaddnum(json,"pendingvolume",bot->pendrelsum); + } + else + { + jaddnum(json,"pendingprice",bot->pendbasesum / bot->pendrelsum); + jaddnum(json,"pendingvolume",bot->pendbasesum); + } + } + return(json); +} + +struct LP_tradebot *_LP_tradebotfind(uint32_t botid) +{ + struct LP_tradebot *tmp,*bot,*retbot = 0; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + if ( botid == bot->id ) + { + retbot = bot; + break; + } + } + return(retbot); +} + +struct LP_tradebot *LP_tradebotfind(uint32_t botid) +{ + struct LP_tradebot *retbot = 0; + portable_mutex_lock(&LP_tradebotsmutex); + retbot = _LP_tradebotfind(botid); + portable_mutex_unlock(&LP_tradebotsmutex); + return(retbot); +} + +void LP_tradebotadd(struct LP_tradebot *bot) +{ + portable_mutex_lock(&LP_tradebotsmutex); + while ( _LP_tradebotfind(bot->id) != 0 ) + { + printf("BOT collision at %u, ok if rare\n",bot->id); + bot->id++; + } + DL_APPEND(LP_tradebots,bot); + portable_mutex_unlock(&LP_tradebotsmutex); +} + +struct LP_tradebot_trade *LP_tradebot_pending(struct LP_tradebot *bot,cJSON *pending,uint32_t tradeid) +{ + struct LP_tradebot_trade *tp; + tp = calloc(1,sizeof(*tp)); + tp->tradeid = tradeid; + tp->maxprice = bot->maxprice; + tp->totalrelvolume = bot->totalrelvolume; + tp->started = (uint32_t)time(NULL); + tp->dispdir = bot->dispdir; + strcpy(tp->base,bot->base); + strcpy(tp->rel,bot->rel); + tp->aliceid = j64bits(pending,"aliceid"); + tp->basevol = jdouble(pending,"basevalue"); + tp->relvol = jdouble(pending,"relvalue"); + printf("tradebot pending basevol %.8f relvol %.8f\n",tp->basevol,tp->relvol); + return(tp); +} + +double LP_orderbook_maxrel(char *base,char *rel,double maxprice) +{ + char *retstr; int32_t i,numasks; cJSON *retjson,*asks,*item; double maxvol,maxrel = 0.; + if ( (retstr= LP_orderbook(base,rel,0)) != 0 ) + { + //printf("maxprice %.8f %s/%s\n",maxprice,base,rel); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (asks= jarray(&numasks,retjson,"asks")) != 0 ) + { + for (i=0; i maxprice ) + break; + maxvol = jdouble(item,"maxvolume"); + //printf("(%s) -> %.8f\n",jprint(item,0),maxvol); + if ( maxvol > maxrel ) + maxrel = maxvol; + } + } + free_json(retjson); + } + free(retstr); + } + return(maxrel); +} + +void LP_tradebot_timeslice(void *ctx,struct LP_tradebot *bot) +{ + double remaining,maxrel; struct LP_tradebot_trade *tp; int32_t i,maxiters = 10; uint32_t tradeid; bits256 destpubkey; char *retstr,*liststr; cJSON *retjson,*retjson2,*pending; + memset(destpubkey.bytes,0,sizeof(destpubkey)); + LP_tradebot_calcstats(bot); + if ( bot->dead == 0 && bot->pause == 0 && bot->userpause == 0 && bot->numtrades < sizeof(bot->trades)/sizeof(*bot->trades) ) + { + if ( (liststr= LP_recent_swaps(0)) != 0 ) + { + if ( (retjson= cJSON_Parse(liststr)) != 0 ) + { + if ( jobj(retjson,"pending") == 0 ) + { + remaining = bot->totalrelvolume - (bot->relsum + bot->pendrelsum); + maxrel = LP_orderbook_maxrel(bot->base,bot->rel,bot->maxprice); + printf("try autobuy %s/%s remaining %.8f maxprice %.8f maxrel %.8f\n",bot->base,bot->rel,remaining,bot->maxprice,maxrel); + if ( maxrel < remaining ) + remaining = maxrel; + tradeid = LP_rand(); + for (i=1; i<=maxiters; i++) + { + if ( remaining < 0.001 ) + break; + if ( (retstr= LP_autobuy(ctx,LP_myipaddr,LP_mypubsock,bot->base,bot->rel,bot->maxprice,remaining/i,0,0,G.gui,0,destpubkey,tradeid)) != 0 ) + { + if ( (retjson2= cJSON_Parse(retstr)) != 0 ) + { + if ( (pending= jobj(retjson2,"pending")) != 0 && juint(pending,"tradeid") == tradeid ) + { + bot->trades[bot->numtrades++] = tp = LP_tradebot_pending(bot,pending,tradeid); + printf("issued bot trade.%u %s\n",tradeid,retstr); + free_json(retjson2); + free(retstr); + break; + } else printf("iter.%d/%d %.8f didnt get any trade pending %s %s\n\n",i,maxiters,remaining/i,bot->name,retstr); + free_json(retjson2); + } else printf("iter.%d/%d %.8f %s\n",i,maxiters,remaining/i,retstr); + free(retstr); + } + } + LP_tradebot_calcstats(bot); + } + free_json(retjson); + } + free(liststr); + } + } + else if ( bot->pause == 0 ) + bot->pause = (uint32_t)time(NULL); +} + +void LP_aliceid(uint32_t tradeid,uint64_t aliceid,char *event,uint32_t requestid,uint32_t quoteid) +{ + struct LP_tradebot *bot,*tmp; int32_t i,matched = 0; struct LP_tradebot_trade *tp; + if ( tradeid == 0 ) + return; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + for (i=0; inumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 ) + { + if ( tp->finished == 0 && tp->tradeid == tradeid ) + { + tp->aliceid = aliceid; + printf("bot event tradeid.%u aliceid.%llu (%s) r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); + if ( requestid != 0 && quoteid != 0 ) + { + tp->requestid = requestid; + tp->quoteid = quoteid; + } + strcpy(tp->event,event); + matched = 1; + break; + } else printf("tradeid.%u finished.%u\n",tp->tradeid,tp->finished); + } + } + if ( matched != 0 ) + break; + } + if ( 0 && matched == 0 ) + printf("NO MATCH: bot event tradeid.%u aliceid.%llu (%s) r.%u q.%u\n",tradeid,(long long)aliceid,event,requestid,quoteid); +} + +void LP_tradebot_finished(uint32_t tradeid,uint32_t requestid,uint32_t quoteid) +{ + struct LP_tradebot *bot,*tmp; int32_t i; struct LP_tradebot_trade *tp; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + for (i=0; inumtrades; i++) + { + if ( (tp= bot->trades[i]) != 0 && tp->finished == 0 && tp->tradeid == tradeid ) + { + tp->requestid = requestid; + tp->quoteid = quoteid; + printf("bot.%u detected completion tradeid.%u aliceid.%llu r.%u q.%u, numpending.%d completed.%d\n",bot->id,tp->tradeid,(long long)tp->aliceid,tp->requestid,tp->quoteid,bot->numpending,bot->completed); + tp->finished = (uint32_t)time(NULL); + strcpy(tp->event,"finished"); + break; + } + } + } +} + +void LP_tradebots_timeslice(void *ctx) +{ + static uint32_t lastnumfinished = 0; + struct iguana_info *relcoin; bits256 zero; struct LP_tradebot *bot,*tmp; + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + memset(zero.bytes,0,sizeof(zero)); + if ( (relcoin= LP_coinfind(bot->rel)) != 0 ) + LP_listunspent_issue(bot->rel,relcoin->smartaddr,1,zero,zero); + if ( bot->relsum >= 0.99*bot->totalrelvolume-SMALLVAL || bot->basesum >= 0.99*bot->totalbasevolume-SMALLVAL ) + bot->dead = (uint32_t)time(NULL); + else if ( (bot->pendrelsum+bot->relsum) >= 0.99*bot->totalrelvolume-SMALLVAL || (bot->basesum+bot->pendbasesum) >= 0.99*bot->totalbasevolume-SMALLVAL ) + bot->pause = (uint32_t)time(NULL); + else if ( bot->userpause == 0 ) + bot->pause = 0; + if ( bot->numpending == 0 && time(NULL) > bot->lasttime+TRADEBOTS_GAPTIME ) + { + LP_tradebot_timeslice(ctx,bot); + bot->lasttime = (uint32_t)time(NULL); + } + } + lastnumfinished = LP_numfinished; +} + +char *LP_tradebot_list(void *ctx,int32_t pubsock,cJSON *argjson) +{ + struct LP_tradebot *bot,*tmp; cJSON *array = cJSON_CreateArray(); + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + jaddinum(array,bot->id); + } + return(jprint(array,1)); +} + +char *LP_tradebot_statuslist(void *ctx,int32_t pubsock,cJSON *argjson) +{ + struct LP_tradebot *bot,*tmp; cJSON *array = cJSON_CreateArray(); + DL_FOREACH_SAFE(LP_tradebots,bot,tmp) + { + jaddi(array,LP_tradebot_json(bot)); + } + return(jprint(array,1)); +} + +char *LP_tradebot_buy(int32_t dispdir,char *base,char *rel,double maxprice,double relvolume) +{ + struct LP_tradebot *bot; char *retstr; double shortfall; cJSON *retjson; uint64_t sum,txfee,txfees,balance=0,abalance=0; struct iguana_info *basecoin,*relcoin; + basecoin = LP_coinfind(base); + relcoin = LP_coinfind(rel); + if ( basecoin == 0 || relcoin == 0 || basecoin->inactive != 0 || relcoin->inactive != 0 ) + return(clonestr("{\"error\":\"one or more coins inactive\"}")); + /*if ( (array= LP_inventory(rel)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 && is_cJSON_Array(array) != 0 ) + { + for (i=0; ielectrum != 0 ) + balance = LP_unspents_load(relcoin->symbol,relcoin->smartaddr); + else balance = LP_RTsmartbalance(relcoin); + sum = (SATOSHIDEN*relvolume+2*dstr(txfees)) + 3 * ((SATOSHIDEN*relvolume+2*dstr(txfees))/777); + printf("%s inventory balance %.8f, relvolume %.8f + txfees %.8f, utxobal %.8f sum %.8f\n",rel,dstr(abalance),relvolume,dstr(txfees),dstr(balance),dstr(sum)); + //if ( (abalance < SATOSHIDEN*relvolume + txfees) || ((balance-abalance) < (uint64_t)(SATOSHIDEN*relvolume)/777 + txfees) ) + if ( balance < sum+2*txfee ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","not enough funds"); + jaddstr(retjson,"coin",rel); + jaddnum(retjson,"abalance",dstr(abalance)); + jaddnum(retjson,"balance",dstr(balance)); + jaddnum(retjson,"relvolume",relvolume); + jaddnum(retjson,"txfees",dstr(txfees)); + shortfall = (relvolume + dstr(txfees)) - dstr(balance); + jaddnum(retjson,"shortfall",shortfall); + /*if ( balance > sum+2*txfee ) + { + char *withdrawstr; cJSON *outputjson,*withdrawjson,*outputs,*item; + outputjson = cJSON_CreateObject(); + outputs = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,relcoin->smartaddr,relvolume+2*dstr(txfees)); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,relcoin->smartaddr,(relvolume+2*dstr(txfees))/777); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,relcoin->smartaddr,(relvolume+2*dstr(txfees))/777); + jaddi(outputs,item); + item = cJSON_CreateObject(); + jaddnum(item,relcoin->smartaddr,(relvolume+2*dstr(txfees))/777); + jaddi(outputs,item); + jadd(outputjson,"outputs",outputs); + if ( (withdrawstr= LP_withdraw(relcoin,outputjson)) != 0 ) + { + if ( (withdrawjson= cJSON_Parse(withdrawstr)) != 0 ) + jadd(retjson,"withdraw",withdrawjson); + free(withdrawstr); + } + free_json(outputjson); + }*/ + return(jprint(retjson,1)); + } + printf("disp.%d tradebot_buy(%s / %s) maxprice %.8f relvolume %.8f\n",dispdir,base,rel,maxprice,relvolume); + if ( (bot= calloc(1,sizeof(*bot))) != 0 ) + { + safecopy(bot->base,base,sizeof(bot->base)); + safecopy(bot->rel,rel,sizeof(bot->rel)); + bot->dispdir = dispdir; + bot->maxprice = maxprice; + bot->totalrelvolume = relvolume; + LP_pricevol_invert(&bot->totalbasevolume,maxprice,relvolume); + bot->started = (uint32_t)time(NULL); + if ( dispdir > 0 ) + sprintf(bot->name,"buy_%s_%s.%d",base,rel,bot->started); + else sprintf(bot->name,"sell_%s_%s.%d",rel,base,bot->started); + bot->id = calc_crc32(0,(uint8_t *)bot,sizeof(*bot)); + LP_tradebotadd(bot); + return(jprint(LP_tradebot_json(bot),1)); + } + return(0); +} + +char *LP_tradebot_limitbuy(void *ctx,int32_t pubsock,cJSON *argjson) +{ + double relvolume,maxprice; char *base,*rel; + base = jstr(argjson,"base"); + rel = jstr(argjson,"rel"); + maxprice = jdouble(argjson,"maxprice"); + relvolume = jdouble(argjson,"relvolume"); + printf("limit buy %s/%s %.8f %.8f\n",base,rel,maxprice,relvolume); + if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && maxprice > SMALLVAL && maxprice < SATOSHIDEN && relvolume > 0.0001 && relvolume < SATOSHIDEN ) + return(LP_tradebot_buy(1,base,rel,maxprice,relvolume)); + return(clonestr("{\"error\":\"invalid parameter\"}")); +} + +char *LP_tradebot_limitsell(void *ctx,int32_t pubsock,cJSON *argjson) +{ + double relvolume,maxprice,price,basevolume,p,v; char *base,*rel; + base = jstr(argjson,"base"); + rel = jstr(argjson,"rel"); + price = jdouble(argjson,"minprice"); + basevolume = jdouble(argjson,"basevolume"); + if ( LP_priceinfofind(base) != 0 && LP_priceinfofind(rel) != 0 && price > SMALLVAL && price < SATOSHIDEN && basevolume > 0.0001 && basevolume < SATOSHIDEN ) + { + maxprice = price; + relvolume = (price * basevolume); + p = LP_pricevol_invert(&v,maxprice,relvolume); + printf("minprice %.8f basevolume %.8f -> (%.8f %.8f) -> (%.8f %.8f)\n",price,basevolume,maxprice,relvolume,1./p,v); + return(LP_tradebot_buy(-1,rel,base,p,v)); + } + return(clonestr("{\"error\":\"invalid parameter\"}")); +} + +char *LP_tradebot_settings(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; double newprice,newvolume; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + newprice = jdouble(argjson,"newprice"); + newvolume = jdouble(argjson,"newvolume"); + if ( (newprice > SMALLVAL && newprice < SATOSHIDEN) || (newvolume > 0.0001 && newvolume < SATOSHIDEN) ) + { + if ( bot->dispdir < 0 ) + { + if ( newprice > SMALLVAL ) + bot->maxprice = 1. / newprice; + if ( newvolume > SMALLVAL ) + bot->totalrelvolume = (bot->maxprice * newvolume); + } + else + { + if ( newprice > SMALLVAL ) + bot->maxprice = newprice; + if ( newvolume > SMALLVAL ) + bot->totalrelvolume = newvolume; + } + } + return(jprint(LP_tradebot_json(bot),1)); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_status(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + return(jprint(LP_tradebot_json(bot),1)); + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_stop(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + bot->dead = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_pause(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + bot->userpause = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_tradebot_resume(void *ctx,int32_t pubsock,cJSON *argjson,uint32_t botid) +{ + struct LP_tradebot *bot; + if ( (bot= LP_tradebotfind(botid)) != 0 ) + { + if ( bot->dead != 0 ) + return(clonestr("{\"error\":\"botid aleady stopped\"}")); + if ( bot->userpause == 0 ) + return(clonestr("{\"result\":\"success\",\"status\":\"botid not paused\"}")); + bot->userpause = 0; + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"couldnt find botid\"}")); +} + +char *LP_istradebots_command(void *ctx,int32_t pubsock,char *method,cJSON *argjson) +{ + uint32_t botid; + //printf("LP_istradebots_command check %s\n",method); + if ( strncmp("bot_",method,strlen("bot_")) != 0 ) + return(0); + if ( strcmp(method,"bot_list") == 0 ) + return(LP_tradebot_list(ctx,pubsock,argjson)); + else if ( strcmp(method,"bot_statuslist") == 0 ) + return(LP_tradebot_statuslist(ctx,pubsock,argjson)); + else if ( strcmp(method,"bot_buy") == 0 ) + return(LP_tradebot_limitbuy(ctx,pubsock,argjson)); + else if ( strcmp(method,"bot_sell") == 0 ) + return(LP_tradebot_limitsell(ctx,pubsock,argjson)); + if ( (botid= juint(argjson,"botid")) == 0 ) + return(clonestr("{\"error\":\"no botid specified\"}")); + else + { + if ( strcmp(method,"bot_status") == 0 ) + return(LP_tradebot_status(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_settings") == 0 ) + return(LP_tradebot_settings(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_stop") == 0 ) + return(LP_tradebot_stop(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_pause") == 0 ) + return(LP_tradebot_pause(ctx,pubsock,argjson,botid)); + else if ( strcmp(method,"bot_resume") == 0 ) + return(LP_tradebot_resume(ctx,pubsock,argjson,botid)); + } + return(0); +} + diff --git a/iguana/exchanges/LP_transaction.c b/iguana/exchanges/LP_transaction.c new file mode 100644 index 000000000..9be0e469c --- /dev/null +++ b/iguana/exchanges/LP_transaction.c @@ -0,0 +1,2258 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// +// LP_transaction.c +// marketmaker +// +bits256 LP_privkeyfind(uint8_t rmd160[20]) +{ + int32_t i; static bits256 zero; + for (i=0; i no privkey\n"); + return(zero); +} + +int32_t LP_privkeyadd(bits256 privkey,uint8_t rmd160[20]) +{ + bits256 tmpkey; + tmpkey = LP_privkeyfind(rmd160); + if ( bits256_nonz(tmpkey) != 0 ) + return(-bits256_cmp(privkey,tmpkey)); + G.LP_privkeys[G.LP_numprivkeys].privkey = privkey; + memcpy(G.LP_privkeys[G.LP_numprivkeys].rmd160,rmd160,20); + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //char str[65]; printf(" -> add privkey.(%s)\n",bits256_str(str,privkey)); + G.LP_numprivkeys++; + return(G.LP_numprivkeys); +} + +bits256 LP_privkey(char *symbol,char *coinaddr,uint8_t taddr) +{ + bits256 privkey; uint8_t addrtype,rmd160[20]; + bitcoin_addr2rmd160(symbol,taddr,&addrtype,rmd160,coinaddr); + privkey = LP_privkeyfind(rmd160); + return(privkey); +} + +bits256 LP_pubkey(bits256 privkey) +{ + bits256 pubkey; + pubkey = curve25519(privkey,curve25519_basepoint9()); + return(pubkey); +} + +int32_t LP_gettx_presence(char *symbol,bits256 expectedtxid) +{ + cJSON *txobj; bits256 txid; int32_t flag = 0; + if ( (txobj= LP_gettx(symbol,expectedtxid,0)) != 0 ) + { + txid = jbits256(txobj,"txid"); + if ( jobj(txobj,"error") == 0 && bits256_cmp(txid,expectedtxid) == 0 ) + { + //char str[65]; printf("%s already in gettx (%s)\n",bits256_str(str,txid),jprint(txobj,0)); + flag = 1; + } + free_json(txobj); + } + return(flag); +} + +bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid) +{ + char *retstr,*errstr; bits256 txid; uint8_t *ptr; cJSON *retjson,*errorobj; struct iguana_info *coin; int32_t i,totalretries=0,len,sentflag = 0; + coin = LP_coinfind(symbol); + memset(&txid,0,sizeof(txid)); + if ( txbytes == 0 || txbytes[0] == 0 ) + return(txid); + if ( bits256_nonz(expectedtxid) == 0 ) + { + len = (int32_t)strlen(txbytes) >> 1; + ptr = malloc(len); + decode_hex(ptr,len,txbytes); + expectedtxid = bits256_calctxid(symbol,ptr,len); + free(ptr); + } + for (i=0; i<2; i++) + { + //char str[65]; printf("LP_broadcast.%d (%s) %s i.%d sentflag.%d\n",i,symbol,bits256_str(str,expectedtxid),i,sentflag); + if ( sentflag == 0 && LP_gettx_presence(symbol,expectedtxid) != 0 ) + sentflag = 1; + if ( sentflag == 0 && (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 ) + { + if ( is_hexstr(retstr,0) == 64 ) + { + decode_hex(txid.bytes,32,retstr); + if ( bits256_cmp(txid,expectedtxid) == 0 || (bits256_nonz(expectedtxid) == 0 && bits256_nonz(txid) != 0) ) + { + sentflag = 1; + expectedtxid = txid; + } + } + else if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (errorobj= jobj(retjson,"error")) != 0 ) + { + if ( jint(errorobj,"code") == -27 ) // "transaction already in block chain" + { + txid = expectedtxid; + sentflag = 1; + } + else if ( (errstr= jstr(retjson,"error")) != 0 && strcmp(errstr,"timeout") == 0 && coin != 0 && coin->electrum != 0 ) + { + if ( totalretries < 4 ) + { + printf("time error with electrum, retry.%d\n",totalretries); + totalretries++; + i--; + } + } + else printf("broadcast error.(%s)\n",retstr); + } + free_json(retjson); + } + //char str[65]; printf("sentflag.%d [%s] %s RETSTR.(%s) %s.%s\n",sentflag,txname,txbytes,retstr,symbol,bits256_str(str,txid)); + free(retstr); + } + if ( sentflag != 0 ) + break; + sleep(3); + } + if ( sentflag != 0 ) + return(expectedtxid); + return(txid); +} + +bits256 LP_broadcast_tx(char *name,char *symbol,uint8_t *data,int32_t datalen) +{ + bits256 txid; char *signedtx; + memset(txid.bytes,0,sizeof(txid)); + if ( data != 0 && datalen != 0 ) + { + signedtx = malloc(datalen*2 + 1); + init_hexbytes_noT(signedtx,data,datalen); + txid = bits256_calctxid(symbol,data,datalen); +#ifdef BASILISK_DISABLESENDTX + char str[65]; printf("%s <- dont sendrawtransaction (%s) %s\n",name,bits256_str(str,txid),signedtx); +#else + txid = LP_broadcast(name,symbol,signedtx,txid); +#endif + free(signedtx); + } + return(txid); +} + +int32_t iguana_msgtx_Vset(uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,struct vin_info *V) +{ + int32_t vini,j,scriptlen,p2shlen,userdatalen,siglen,plen,need_op0=0,len = 0; uint8_t *script,*redeemscript=0,*userdata=0; struct vin_info *vp; + for (vini=0; vinitx_in; vini++) + { + vp = &V[vini]; + if ( (userdatalen= vp->userdatalen) == 0 ) + { + userdatalen = vp->userdatalen = msgtx->vins[vini].userdatalen; + userdata = msgtx->vins[vini].userdata; + } else userdata = vp->userdata; + if ( (p2shlen= vp->p2shlen) == 0 ) + { + p2shlen = vp->p2shlen = msgtx->vins[vini].p2shlen; + redeemscript = msgtx->vins[vini].redeemscript; + } + else + { + redeemscript = vp->p2shscript; + msgtx->vins[vini].redeemscript = redeemscript; + } + if ( msgtx->vins[vini].spendlen > 33 && msgtx->vins[vini].spendscript[msgtx->vins[vini].spendlen - 1] == SCRIPT_OP_CHECKMULTISIG ) + { + need_op0 = 1; + printf("found multisig spendscript\n"); + } + if ( redeemscript != 0 && p2shlen > 33 && redeemscript[p2shlen - 1] == SCRIPT_OP_CHECKMULTISIG ) + { + need_op0 = 1; + //printf("found multisig redeemscript\n"); + } + msgtx->vins[vini].vinscript = script = &serialized[len]; + msgtx->vins[vini].vinscript[0] = 0; + scriptlen = need_op0; + for (j=0; jN; j++) + { + if ( (siglen= vp->signers[j].siglen) > 0 ) + { + script[scriptlen++] = siglen; + memcpy(&script[scriptlen],vp->signers[j].sig,siglen); + scriptlen += siglen; + } + } + msgtx->vins[vini].scriptlen = scriptlen; + if ( vp->suppress_pubkeys == 0 && (vp->N > 1 || bitcoin_pubkeylen(&vp->spendscript[1]) != vp->spendscript[0] || vp->spendscript[vp->spendlen-1] != 0xac) ) + { + for (j=0; jN; j++) + { + if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) > 0 ) + { + script[scriptlen++] = plen; + memcpy(&script[scriptlen],vp->signers[j].pubkey,plen); + scriptlen += plen; + } + } + msgtx->vins[vini].scriptlen = scriptlen; + } + if ( userdatalen != 0 ) + { + memcpy(&script[scriptlen],userdata,userdatalen); + msgtx->vins[vini].userdata = &script[scriptlen]; + msgtx->vins[vini].userdatalen = userdatalen; + scriptlen += userdatalen; + } + //printf("USERDATALEN.%d scriptlen.%d redeemlen.%d\n",userdatalen,scriptlen,p2shlen); + if ( p2shlen != 0 ) + { + if ( p2shlen < 76 ) + script[scriptlen++] = p2shlen; + else if ( p2shlen <= 0xff ) + { + script[scriptlen++] = 0x4c; + script[scriptlen++] = p2shlen; + } + else if ( p2shlen <= 0xffff ) + { + script[scriptlen++] = 0x4d; + script[scriptlen++] = (p2shlen & 0xff); + script[scriptlen++] = ((p2shlen >> 8) & 0xff); + } else return(-1); + msgtx->vins[vini].p2shlen = p2shlen; + memcpy(&script[scriptlen],redeemscript,p2shlen); + scriptlen += p2shlen; + } + len += scriptlen; + } + if ( (0) ) + { + int32_t i; for (i=0; i 0 ) + { + activescript = V[vini].p2shscript; + activescriptlen = V[vini].p2shlen; + } + else + { + activescript = V[vini].spendscript; + activescriptlen = V[vini].spendlen; + } + memcpy(V[vini].spendscript,activescript,activescriptlen); + V[vini].spendlen = activescriptlen; + spendscript = iguana_spendasm(activescript,activescriptlen); + if ( activescriptlen < 16 ) + continue; + //printf("interpreter.(%s)\n",jprint(spendscript,0)); + //printf("bitcoin_assembler ignore_cltverr.%d suppress.%d\n",V[vini].ignore_cltverr,V[vini].suppress_pubkeys); + if ( (scriptlen= bitcoin_assembler(coin,logarray,script,spendscript,1,nLockTime,&V[vini])) < 0 ) + { + //printf("bitcoin_assembler error scriptlen.%d\n",scriptlen); + errs++; + } + else if ( scriptlen != activescriptlen || memcmp(script,activescript,scriptlen) != 0 ) + { + if ( logarray != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"error","script reconstruction failed"); + } + init_hexbytes_noT(str,activescript,activescriptlen); + //printf("activescript.(%s)\n",str); + if ( logarray != 0 && item != 0 ) + jaddstr(item,"original",str); + init_hexbytes_noT(str,script,scriptlen); + //printf("reconstructed.(%s)\n",str); + if ( logarray != 0 ) + { + jaddstr(item,"reconstructed",str); + jaddi(logarray,item); + } else printf(" scriptlen mismatch.%d vs %d or miscompare\n",scriptlen,activescriptlen); + errs++; + } + memcpy(V[vini].spendscript,savescript,savelen); + V[vini].spendlen = savelen; + } + free(str); + free(script); + free(savescript); + if ( errs != 0 ) + return(-errs); + if ( logarray != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"result","success"); + jaddi(logarray,item); + } + return(0); +} + +bits256 iguana_str2priv(char *symbol,uint8_t wiftaddr,char *str) +{ + bits256 privkey; int32_t n; uint8_t addrtype; //struct iguana_waccount *wacct=0; struct iguana_waddress *waddr; + memset(&privkey,0,sizeof(privkey)); + if ( str != 0 ) + { + n = (int32_t)strlen(str) >> 1; + if ( n == sizeof(bits256) && is_hexstr(str,sizeof(bits256)) > 0 ) + decode_hex(privkey.bytes,sizeof(privkey),str); + else if ( bitcoin_wif2priv(symbol,wiftaddr,&addrtype,&privkey,str) != sizeof(bits256) ) + { + //if ( (waddr= iguana_waddresssearch(&wacct,str)) != 0 ) + // privkey = waddr->privkey; + //else memset(privkey.bytes,0,sizeof(privkey)); + } + } + return(privkey); +} + +int32_t iguana_vininfo_create(char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msgtx,cJSON *vins,int32_t numinputs,struct vin_info *V) +{ + int32_t i,plen,finalized = 1,len = 0; struct vin_info *vp; //struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,userdatalen; + msgtx->tx_in = numinputs; + maxsize -= (sizeof(struct iguana_msgvin) * msgtx->tx_in); + msgtx->vins = (struct iguana_msgvin *)&serialized[maxsize]; + memset(msgtx->vins,0,sizeof(struct iguana_msgvin) * msgtx->tx_in); + if ( msgtx->tx_in > 0 && msgtx->tx_in*sizeof(struct iguana_msgvin) < maxsize ) + { + for (i=0; itx_in; i++) + { + vp = &V[i]; + //printf("VINS.(%s)\n",jprint(jitem(vins,i),0)); + len += iguana_parsevinobj(&serialized[len],maxsize,&msgtx->vins[i],jitem(vins,i),vp); + if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) + finalized = 0; + if ( msgtx->vins[i].spendscript == 0 ) + { + /*if ( iguana_RTunspentindfind(coin,&outpt,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,0) == 0 ) + { + vp->unspentind = outpt.unspentind; + msgtx->vins[i].spendscript = vp->spendscript; + msgtx->vins[i].spendlen = vp->spendlen; + vp->hashtype = iguana_vinscriptparse(coin,vp,&sigsize,&pubkeysize,&p2shsize,&userdatalen,vp->spendscript,vp->spendlen); + vp->userdatalen = userdatalen; + printf("V %.8f (%s) spendscript.[%d] userdatalen.%d\n",dstr(vp->amount),vp->coinaddr,vp->spendlen,userdatalen); + }*/ + } + else + { + memcpy(vp->spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); + vp->spendlen = msgtx->vins[i].spendlen; + _iguana_calcrmd160(symbol,taddr,pubtype,p2shtype,vp); + if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) > 0 ) + bitcoin_address(symbol,vp->coinaddr,taddr,pubtype,vp->signers[0].pubkey,plen); + } + if ( vp->M == 0 && vp->N == 0 ) + vp->M = vp->N = 1; + /*if ( vp->coinaddr[i] != 0 && (waddr= iguana_waddresssearch(&wacct,vp->coinaddr)) != 0 ) + { + vp->signers[0].privkey = waddr->privkey; + if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) != vp->spendscript[1] || vp->spendscript[vp->spendlen-1] != 0xac ) + { + if ( plen > 0 && plen < sizeof(vp->signers[0].pubkey) ) + memcpy(vp->signers[0].pubkey,waddr->pubkey,plen); + } + }*/ + } + } + return(finalized); +} + +int32_t bitcoin_verifyvins(void *ctx,char *symbol,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,uint32_t sighash,int32_t signtx,int32_t suppress_pubkeys,int32_t zcash) +{ + bits256 sigtxid; int64_t spendamount; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs; + numvouts = msgtx->tx_out; + vpnstr[0] = 0; + *signedtx = 0; + memset(signedtxidp,0,sizeof(*signedtxidp)); +//printf("bitcoin_verifyvins numvins.%d numvouts.%d signtx.%d privkey.%d M.%d N.%d\n",msgtx->tx_in,numvouts,signtx,bits256_nonz(V[0].signers[0].privkey),V[0].M,V[0].N); + for (vini=0; vinitx_in; vini++) + { + if ( V->p2shscript[0] != 0 && V->p2shlen != 0 ) + { + script = V->p2shscript; + scriptlen = V->p2shlen; + } + else + { + script = msgtx->vins[vini].spendscript; + scriptlen = msgtx->vins[vini].spendlen; + } + spendamount = LP_outpoint_amount(symbol,msgtx->vins[vini].prev_hash,msgtx->vins[vini].prev_vout); + sigtxid = bitcoin_sigtxid(symbol,taddr,pubtype,p2shtype,isPoS,height,serialized,maxlen,msgtx,vini,script,scriptlen,spendamount,sighash,vpnstr,suppress_pubkeys,zcash); + if ( bits256_nonz(sigtxid) != 0 ) + { + vp = &V[vini]; + vp->sigtxid = sigtxid; + for (j=numsigs=0; jN; j++) + { + sig = vp->signers[j].sig; + siglen = vp->signers[j].siglen; + if ( signtx != 0 && bits256_nonz(vp->signers[j].privkey) != 0 ) + { + siglen = bitcoin_sign(ctx,symbol,sig,sigtxid,vp->signers[j].privkey,0); + //if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) + bitcoin_pubkey33(ctx,vp->signers[j].pubkey,vp->signers[j].privkey); + sig[siglen++] = sighash; + vp->signers[j].siglen = siglen; + /*char str[65]; printf("SIGTXID.(%s) ",bits256_str(str,sigtxid)); + int32_t i; for (i=0; isigners[j].pubkey[i]); + // s2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1; + printf(" SIGNEDTX.[%02x] siglen.%d priv.%s\n",sig[siglen-1],siglen,bits256_str(str,vp->signers[j].privkey));*/ + } + if ( sig == 0 || siglen == 0 ) + { + memset(vp->signers[j].pubkey,0,sizeof(vp->signers[j].pubkey)); + char str[65]; printf("no sig.%p or siglen.%d zero priv.(%s)\n",sig,siglen,bits256_str(str,vp->signers[j].privkey)); + continue; + } + if ( bitcoin_verify(ctx,sig,siglen-1,sigtxid,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 ) + { + int32_t k; for (k=0; ksigners[j].pubkey); k++) + printf("%02x",vp->signers[j].pubkey[k]); + printf(" SIG.%d.%d ERROR siglen.%d\n",vini,j,siglen); + } + else + { + flag++; + numsigs++; + /*int32_t z; char tmpaddr[64]; + for (z=0; zsigners[j].pubkey[z]); + bitcoin_address(tmpaddr,0,0,vp->signers[j].pubkey,33); + printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d %s\n",vini,j,numsigs,vp->M,tmpaddr);*/ + } + } + if ( numsigs >= vp->M ) + complete = 1; + } else if ( signtx != 0 ) + printf("bitcoin_verifyvins cant without privkey\n"); + } + iguana_msgtx_Vset(serialized,maxlen,msgtx,V); + cJSON *txobj = 0;//cJSON_CreateObject(); + *signedtx = iguana_rawtxbytes(symbol,taddr,pubtype,p2shtype,isPoS,height,txobj,msgtx,suppress_pubkeys,zcash); + //printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); + *signedtxidp = msgtx->txid; + return(complete); +} + +int64_t iguana_lockval(int32_t finalized,int64_t locktime) +{ + int64_t lockval = -1; + if ( finalized == 0 ) + return(locktime); + return(lockval); +} + +int32_t iguana_signrawtransaction(void *ctx,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson,int32_t zcash) +{ + uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 100000; char *privkeystr,*signedtx = 0; uint32_t sighash; bits256 privkeys[LP_MAXVINS],privkey,txid; cJSON *item; cJSON *txobj = 0; + maxsize = 1000000; + memset(privkey.bytes,0,sizeof(privkey)); + if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) + { + serialized = malloc(maxsize); + serialized2 = malloc(maxsize); + serialized3 = malloc(maxsize); + serialized4 = malloc(maxsize); + extraspace = malloc(extralen); + memset(msgtx,0,sizeof(*msgtx)); + decode_hex(serialized,len,rawtx); + if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys,zcash)) != 0 ) + { + //printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0)); + } else printf("no txobj from bitcoin_hex2json\n"); + //printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) + { + //printf("numinputs.%d (%s) msgtx.%d\n",numinputs,jprint(vins,0),msgtx->tx_in); + memset(msgtx,0,sizeof(*msgtx)); + if ( iguana_rwmsgtx(symbol,taddr,pubtype,p2shtype,isPoS,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,extralen,vins,V->suppress_pubkeys,zcash) > 0 && numinputs == msgtx->tx_in ) + { + memset(pubkeys,0,sizeof(pubkeys)); + memset(privkeys,0,sizeof(privkeys)); + if ( (n= cJSON_GetArraySize(privkeysjson)) > 0 ) + { + for (i=0; itx_in); + for (i=0; itx_in; i++) + { + if ( msgtx->vins[i].p2shlen != 0 ) + { + char coinaddr[64]; uint32_t userdatalen,hashtype,sigsize,pubkeysize; uint8_t *userdata; int32_t j,k,type,flag; struct vin_info mvin,mainvin; bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + coinaddr[0] = 0; + sigsize = 0; + flag = (msgtx->vins[i].vinscript[0] == 0); + type = bitcoin_scriptget(symbol,taddr,pubtype,p2shtype,&hashtype,&sigsize,&pubkeysize,&userdata,&userdatalen,&mainvin,msgtx->vins[i].vinscript+flag,msgtx->vins[i].scriptlen-flag,0,zcash); + //printf("i.%d flag.%d type.%d scriptlen.%d\n",i,flag,type,msgtx->vins[i].scriptlen); + if ( msgtx->vins[i].redeemscript != 0 ) + { + //for (j=0; jvins[i].p2shlen; j++) + // printf("%02x",msgtx->vins[i].redeemscript[j]); + bitcoin_address(symbol,coinaddr,taddr,p2shtype,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen); + type = iguana_calcrmd160(symbol,taddr,pubtype,p2shtype,0,&mvin,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen,zero,0,0); + for (j=0; jsuppress_pubkeys == 0 ) + { + for (z=0; z<33; z++) + V[i].signers[j].pubkey[z] = mvin.signers[j].pubkey[z]; + } + if ( flag != 0 && pubkeysize == 33 && mainvin.signers[0].siglen != 0 ) // jl777: need to generalize + { + if ( memcmp(mvin.signers[j].pubkey,mainvin.signers[0].pubkey,33) == 0 ) + { + for (z=0; zsuppress_pubkeys == 0 ) + { + for (z=0; z<33; z++) + V[i].signers[j].pubkey[z] = pubkeys[k][z]; + } + //printf("%s -> V[%d].signer.[%d] <- privkey.%d\n",mvin.signers[j].coinaddr,i,j,k); + break; + } + } + } + //printf("type.%d p2sh.[%d] -> %s M.%d N.%d\n",type,i,mvin.coinaddr,mvin.M,mvin.N); + } + } + if ( i < V->N ) + V->signers[i].privkey = privkey; + if ( i < numinputs ) + V[i].signers[0].privkey = privkey; + plen = bitcoin_pubkeylen(V->signers[i].pubkey); + if ( V->suppress_pubkeys == 0 && plen <= 0 ) + { + if ( i < numinputs ) + { + for (z=0; zsigners[i].pubkey[z]; + } + } + } + finalized = iguana_vininfo_create(symbol,taddr,pubtype,p2shtype,isPoS,serialized2,maxsize,msgtx,vins,numinputs,V); + //printf("finalized.%d ignore_cltverr.%d suppress.%d\n",finalized,V[0].ignore_cltverr,V[0].suppress_pubkeys); + sighash = LP_sighash(symbol,zcash); + if ( (complete= bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,sighash,1,V->suppress_pubkeys,zcash)) > 0 && signedtx != 0 ) + { + /*int32_t tmp; //char str[65]; + if ( (tmp= iguana_interpreter(ctx,cJSON_CreateArray(),iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 ) + { + printf("iguana_interpreter %d error.(%s)\n",tmp,signedtx); + complete = 0; + } else printf("interpreter passed\n");*/ + } else printf("complete.%d\n",complete); + } else printf("rwmsgtx error\n"); + } else printf("no inputs in vins.(%s)\n",vins!=0?jprint(vins,0):"null"); + free(extraspace); + free(serialized), free(serialized2), free(serialized3), free(serialized4); + } else return(-1); + if ( txobj != 0 ) + free_json(txobj); + *signedtxp = signedtx; + return(complete); +} + +char *iguana_validaterawtx(void *ctx,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys,int32_t zcash) +{ + bits256 signedtxid; cJSON *item,*vins,*vouts,*txobj,*retjson,*sobj; char *scriptsig,*signedtx; uint32_t sighash; int32_t sigsize,slen,height,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2,scriptbuf[256]; int64_t inputsum,outputsum; struct iguana_msgvout vout; + char *symbol; uint8_t wiftaddr,taddr,pubtype,p2shtype,isPoS; + height = coin->longestchain; + symbol = coin->symbol; + wiftaddr = coin->wiftaddr; + taddr = coin->taddr; + pubtype = coin->pubtype; + p2shtype = coin->p2shtype; + isPoS = coin->isPoS; + retjson = cJSON_CreateObject(); + inputsum = outputsum = numinputs = numoutputs = 0; + if ( rawtx != 0 && rawtx[0] != 0 ) + { + if ( (strlen(rawtx) & 1) != 0 ) + return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); + memset(msgtx,0,sizeof(*msgtx)); + if ( (txobj= bitcoin_hex2json(symbol,taddr,pubtype,p2shtype,isPoS,height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys,zcash)) != 0 ) + { + maxsize = (int32_t)strlen(rawtx); + serialized = malloc(maxsize); + serialized2 = malloc(maxsize); + if ( (vouts= jarray(&numoutputs,txobj,"vout")) > 0 ) + { + for (i=0; i 0 ) + outputsum += vout.value; + } + } + if ( (vins= jarray(&numinputs,txobj,"vin")) > 0 ) + { + V = calloc(numinputs,sizeof(*V)); + len = 0; + for (i=0; ilock_time = 0; + V[i].amount = 2746715; + strcpy(V[i].coinaddr,"19Cq6MBaD8LY7trqs99ypqKAms3GcLs6J9"); + V[i].suppress_pubkeys = 0; + decode_hex(msgtx->vins[i].prev_hash.bytes,32,"b19ce2c564f7dc57b3f95593e2b287c72d388e86de12dc562d9f8a6bea65b310"); + msgtx->vins[i].prev_vout = 1; + msgtx->vins[i].sequence = 0xffffffff; + sobj = cJSON_CreateObject(); + jaddstr(sobj,"hex","76a91459fdba29ea85c65ad90f6d38f7a6646476b26b1688ac"); + jadd(item,"scriptPubKey",sobj); + printf("match special txid B\n"); + V[i].signers[0].privkey = G.LP_privkey; + } + msgtx->vins[i].spendscript = V[i].spendscript; + msgtx->vins[i].spendlen = V[i].spendlen; + if ( (sobj= jobj(item,"scriptSig")) != 0 ) + { + if ( (scriptsig= jstr(sobj,"hex")) != 0 ) + { + slen = (int32_t)strlen(scriptsig) >> 1; + if ( slen <= sizeof(scriptbuf) ) + { + msgtx->vins[i].scriptlen = slen; + msgtx->vins[i].vinscript = scriptbuf; + decode_hex(scriptbuf,slen,scriptsig); + if ( (sigsize= scriptbuf[0]) >= 70 && sigsize < 76 ) + { + memcpy(V[i].signers[0].sig,scriptbuf+1,sigsize-1); + V[i].signers[0].siglen = sigsize - 1; + V[i].hashtype = scriptbuf[1 + sigsize-1]; + if ( scriptbuf[sigsize+1] == 33 ) + { + memcpy(V[i].signers[0].pubkey,&scriptbuf[sigsize+2],33); + uint8_t rmd160[20]; char rmdstr[42]; + calc_rmd160(rmdstr,rmd160,V[i].signers[0].pubkey,33); + printf("RMD160.%s\n",rmdstr); + } + } else printf("sigsize.%d unexpected\n",sigsize); + } + } + } + inputsum += V[i].amount; + if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) + finalized = 0; + } + sighash = LP_sighash(symbol,zcash); + complete = bitcoin_verifyvins(ctx,symbol,taddr,pubtype,p2shtype,isPoS,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,sighash,0,V[0].suppress_pubkeys,zcash); + msgtx->txid = signedtxid; + /*cJSON *log = cJSON_CreateArray(); + if ( iguana_interpreter(ctx,log,0,V,numinputs) < 0 ) + jaddstr(retjson,"error","interpreter rejects tx"); + else complete = 1; + jadd(retjson,"interpreter",log);*/ + jadd(retjson,"complete",complete!=0?jtrue():jfalse()); + if ( signedtx != 0 ) + free(signedtx); + free(V); + } + free(serialized), free(serialized2); + } + //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); + } + msgtx->inputsum = inputsum; + msgtx->numinputs = numinputs; + msgtx->outputsum = outputsum; + msgtx->numoutputs = numoutputs; + msgtx->txfee = (inputsum - outputsum); + return(jprint(retjson,1)); +} + +void test_validate(struct iguana_info *coin,char *signedtx) +{ + char *retstr; uint8_t extraspace[8192]; int32_t mempool=0; struct iguana_msgtx msgtx; + retstr = iguana_validaterawtx(bitcoin_ctx(),coin,&msgtx,extraspace,sizeof(extraspace),signedtx,mempool,0,coin->zcash); + printf("validate test.(%s)\n",retstr); +} + +char *basilisk_swap_bobtxspend(bits256 *signedtxidp,uint64_t txfee,char *name,char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privkey,bits256 *privkey2p,uint8_t *redeemscript,int32_t redeemlen,uint8_t *userdata,int32_t userdatalen,bits256 utxotxid,int32_t utxovout,char *destaddr,uint8_t *pubkey33,int32_t finalseqid,uint32_t expiration,int64_t *destamountp,uint64_t satoshis,char *changeaddr,char *vinaddr,int32_t suppress_pubkeys,int32_t zcash) +{ + char *rawtxbytes=0,*signedtx=0,tmpaddr[64],hexstr[999],wifstr[128],_destaddr[64]; uint8_t spendscript[512],addrtype,rmd160[20]; cJSON *txobj,*vins,*obj,*vouts,*item,*privkeys; int32_t completed,spendlen,n,ignore_cltverr=1; struct vin_info V[8]; uint32_t timestamp,locktime = 0,sequenceid = 0xffffffff * finalseqid; bits256 txid; uint64_t value=0,change = 0; struct iguana_msgtx msgtx; struct iguana_info *coin; + LP_mark_spent(symbol,utxotxid,utxovout); + *destamountp = 0; + memset(signedtxidp,0,sizeof(*signedtxidp)); + if ( finalseqid == 0 ) + locktime = expiration; + //printf("bobtxspend.%s redeem.[%d]\n",symbol,redeemlen); + if ( redeemlen < 0 ) + return(0); + value = 0; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( txfee > 0 && txfee < coin->txfee ) + txfee = coin->txfee; +#ifndef BASILISK_DISABLESENDTX + if ( (txobj= LP_gettx(symbol,utxotxid,0)) != 0 ) + { + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && utxovout < n ) + { + obj = jitem(vouts,utxovout); + value = LP_value_extract(obj,1); + //printf("value in vout.%d %.8f (%s)\n",vout,dstr(value),jprint(txobj,0)); + } + free_json(txobj); + } else printf("cant gettx\n"); + if ( value == 0 ) + { + //printf("basilisk_swap_bobtxspend.%s %s utxo.(%s).v%d already spent or doesnt exist\n",name,symbol,bits256_str(str,utxotxid),utxovout); + return(0); + } +#endif + } + if ( txfee > 0 && txfee < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + if ( satoshis != 0 ) + { + if ( value < satoshis+txfee ) + { + if ( (value-satoshis) > 3*txfee/4 ) + { + satoshis = value - 3*txfee/4; + printf("reduce satoshis %.8f by txfee %.8f to value %.8f\n",dstr(satoshis),dstr(txfee),dstr(value)); + } + else if ( value == satoshis && (double)txfee/value < 0.25 ) + { + satoshis = value - txfee; + //printf("txfee allocation from value %.8f identical to satoshis: %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); + } + else + { + printf("utxo %.8f too small for %.8f + %.8f\n",dstr(value),dstr(satoshis),dstr(txfee)); + return(0); + } + } + if ( value > satoshis+txfee ) + change = value - (satoshis + txfee); + //printf("utxo %.8f, destamount %.8f change %.8f txfee %.8f\n",dstr(value),dstr(satoshis),dstr(change),dstr(txfee)); + } else if ( value > txfee ) + satoshis = value - txfee; + else + { + printf("unexpected small value %.8f vs txfee %.8f\n",dstr(value),dstr(txfee)); + change = 0; + satoshis = value >> 1; + txfee = (value - satoshis); + printf("unexpected small value %.8f vs txfee %.8f -> %.8f %.8f\n",dstr(value),dstr(txfee),dstr(satoshis),dstr(txfee)); + } + if ( change < 6000 ) + { + satoshis += change; + change = 0; + } + if ( destamountp != 0 ) + *destamountp = satoshis; + timestamp = (uint32_t)time(NULL); + memset(V,0,sizeof(V)); + privkeys = cJSON_CreateArray(); + if ( privkey2p != 0 ) + { + V[0].signers[1].privkey = *privkey2p; + bitcoin_pubkey33(ctx,V[0].signers[1].pubkey,*privkey2p); + bitcoin_priv2wif(symbol,wiftaddr,wifstr,*privkey2p,wiftype); + jaddistr(privkeys,wifstr); + V[0].N = V[0].M = 2; + } else V[0].N = V[0].M = 1; + V[0].signers[0].privkey = privkey; + bitcoin_pubkey33(ctx,V[0].signers[0].pubkey,privkey); + bitcoin_priv2wif(symbol,wiftaddr,wifstr,privkey,wiftype); + jaddistr(privkeys,wifstr); + V[0].suppress_pubkeys = suppress_pubkeys; + V[0].ignore_cltverr = ignore_cltverr; + if ( redeemlen != 0 ) + memcpy(V[0].p2shscript,redeemscript,redeemlen), V[0].p2shlen = redeemlen; + txobj = bitcoin_txcreate(symbol,isPoS,locktime,coin->txversion,timestamp); + vins = cJSON_CreateArray(); + item = cJSON_CreateObject(); + if ( userdata != 0 && userdatalen > 0 ) + { + memcpy(V[0].userdata,userdata,userdatalen); + V[0].userdatalen = userdatalen; + init_hexbytes_noT(hexstr,userdata,userdatalen); + jaddstr(item,"userdata",hexstr); + } + jaddbits256(item,"txid",utxotxid); + jaddnum(item,"vout",utxovout); + bitcoin_address(symbol,tmpaddr,taddr,pubtype,pubkey33,33); + bitcoin_addr2rmd160(symbol,taddr,&addrtype,rmd160,tmpaddr); + if ( redeemlen != 0 ) + { + init_hexbytes_noT(hexstr,redeemscript,redeemlen); + jaddstr(item,"redeemScript",hexstr); + if ( vinaddr != 0 ) + bitcoin_addr2rmd160(symbol,taddr,&addrtype,rmd160,vinaddr); + spendlen = bitcoin_p2shspend(spendscript,0,rmd160); + //printf("P2SH path.%s\n",vinaddr!=0?vinaddr:0); + } else spendlen = bitcoin_standardspend(spendscript,0,rmd160); + init_hexbytes_noT(hexstr,spendscript,spendlen); + jaddstr(item,"scriptPubKey",hexstr); + jaddnum(item,"suppress",suppress_pubkeys); + jaddnum(item,"sequence",sequenceid); + jaddi(vins,item); + jdelete(txobj,"vin"); + jadd(txobj,"vin",vins); + if ( destaddr == 0 ) + { + destaddr = _destaddr; + bitcoin_address(symbol,destaddr,taddr,pubtype,pubkey33,33); + } + bitcoin_addr2rmd160(symbol,taddr,&addrtype,rmd160,destaddr); + if ( addrtype == p2shtype ) + spendlen = bitcoin_p2shspend(spendscript,0,rmd160); + else spendlen = bitcoin_standardspend(spendscript,0,rmd160); + if ( change != 0 && strcmp(changeaddr,destaddr) == 0 ) + { + printf("combine change %.8f -> %s\n",dstr(change),changeaddr); + satoshis += change; + change = 0; + } + txobj = bitcoin_txoutput(txobj,spendscript,spendlen,satoshis); + if ( change != 0 ) + { + int32_t changelen; uint8_t changescript[1024],changetype,changermd160[20]; + bitcoin_addr2rmd160(symbol,taddr,&changetype,changermd160,changeaddr); + changelen = bitcoin_standardspend(changescript,0,changermd160); + txobj = bitcoin_txoutput(txobj,changescript,changelen,change); + } + if ( (rawtxbytes= bitcoin_json2hex(symbol,isPoS,&txid,txobj,V)) != 0 ) + { + char str[65]; + completed = 0; + memset(signedtxidp,0,sizeof(*signedtxidp)); + //printf("locktime.%u sequenceid.%x rawtx.(%s) vins.(%s)\n",locktime,sequenceid,rawtxbytes,jprint(vins,0)); + if ( (completed= iguana_signrawtransaction(ctx,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,1000000,&msgtx,&signedtx,signedtxidp,V,1,rawtxbytes,vins,privkeys,zcash)) < 0 ) + //if ( (signedtx= LP_signrawtx(symbol,signedtxidp,&completed,vins,rawtxbytes,privkeys,V)) == 0 ) + printf("couldnt sign transaction.%s %s\n",name,bits256_str(str,*signedtxidp)); + else if ( completed == 0 ) + { + printf("incomplete signing suppress.%d %s (%s)\n",suppress_pubkeys,name,jprint(vins,0)); + if ( signedtx != 0 ) + free(signedtx), signedtx = 0; + } // else printf("basilisk_swap_bobtxspend %s -> %s\n",name,bits256_str(str,*signedtxidp)); + free(rawtxbytes); + } else printf("error making rawtx suppress.%d\n",suppress_pubkeys); + free_json(privkeys); + free_json(txobj); + return(signedtx); +} + +int32_t LP_vin_select(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct LP_address_utxo **utxos,int32_t numunspents,uint64_t value,int32_t maxmode) +{ + int32_t i,abovei,belowi; int64_t above,below,gap,atx_value; + abovei = belowi = -1; + for (above=below=i=0; iU.value) <= 0 ) + { + //printf("illegal value.%d\n",i); + continue; + } + if ( atx_value == value ) + { + *aboveip = *belowip = i; + *abovep = *belowp = 0; + return(i); + } + else if ( atx_value > value ) + { + gap = (atx_value - value); + if ( above == 0 || gap < above ) + { + above = gap; + abovei = i; + } + } + else + { + gap = (value - atx_value); + if ( below == 0 || gap < below ) + { + below = gap; + belowi = i; + } + } + //printf("value %.8f gap %.8f abovei.%d %.8f belowi.%d %.8f\n",dstr(value),dstr(gap),abovei,dstr(above),belowi,dstr(below)); + } + *aboveip = abovei; + *abovep = above; + *belowip = belowi; + *belowp = below; + //printf("above.%d below.%d\n",abovei,belowi); + if ( abovei >= 0 && belowi >= 0 ) + { + if ( above < (below >> 1) ) + return(abovei); + else return(belowi); + } + else if ( abovei >= 0 ) + return(abovei); + else return(belowi); + //return(abovei >= 0 && above < (below>>1) ? abovei : belowi); +} + +cJSON *LP_inputjson(bits256 txid,int32_t vout,char *spendscriptstr) +{ + cJSON *sobj,*item = cJSON_CreateObject(); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + sobj = cJSON_CreateObject(); + jaddstr(sobj,"hex",spendscriptstr); + jadd(item,"scriptPubKey",sobj); + //printf("vin.%s\n",jprint(item,0)); + return(item); +} + +int64_t LP_hodlcoin_interest(int32_t coinheight,int32_t utxoheight,bits256 txid,int64_t nValue) +{ + int64_t interest = 0; int32_t minutes,htdiff; + if ( coinheight > utxoheight ) + { + htdiff = (coinheight - utxoheight); + if ( htdiff > 16830 ) + htdiff = 16830; + minutes = (htdiff * 154) / 60; + interest = nValue * htdiff * 0.000000238418; + //interest = ((nValue * minutes) / 10743920); + } + return(interest); +} + +uint64_t _komodo_interestnew(uint64_t nValue,uint32_t nLockTime,uint32_t tiptime) +{ + int32_t minutes; uint64_t interest = 0; + if ( tiptime > nLockTime && (minutes= (tiptime - nLockTime) / 60) >= 60 ) + { + //minutes.71582779 tiptime.1511292969 locktime.1511293505 + printf("minutes.%d tiptime.%u locktime.%u\n",minutes,tiptime,nLockTime); + if ( minutes > 365 * 24 * 60 ) + minutes = 365 * 24 * 60; + minutes -= 59; + interest = ((nValue / 10512000) * minutes); + } + return(interest); +} + +int64_t LP_komodo_interest(bits256 txid,int64_t value) +{ + uint32_t nLockTime; uint32_t tiptime; int64_t interest = 0; + if ( value >= 10*SATOSHIDEN ) + { + if ( (nLockTime= LP_locktime("KMD",txid)) >= 500000000 ) + { + tiptime = (uint32_t)time(NULL) - 777; + interest = _komodo_interestnew(value,nLockTime,tiptime); + } + } + return(interest); +} + +int32_t LP_vins_select(void *ctx,struct iguana_info *coin,int64_t *totalp,int64_t amount,struct vin_info *V,struct LP_address_utxo **utxos,int32_t numunspents,int32_t suppress_pubkeys,int32_t ignore_cltverr,bits256 privkey,cJSON *privkeys,cJSON *vins,uint8_t *script,int32_t scriptlen,bits256 utxotxid,int32_t utxovout,int32_t dustcombine) +{ + char wifstr[128],spendscriptstr[128],str[65]; int32_t i,j,maxiters,n,numpre,ind,abovei,belowi,maxmode=0; struct vin_info *vp; cJSON *txobj; struct LP_address_utxo *up,*min0,*min1,*preselected[3]; int64_t value,interest,interestsum,above,below,remains = amount,total = 0; + *totalp = 0; + interestsum = 0; + init_hexbytes_noT(spendscriptstr,script,scriptlen); + bitcoin_priv2wif(coin->symbol,coin->wiftaddr,wifstr,privkey,coin->wiftype); + n = 0; + min0 = min1 = 0; + memset(preselected,0,sizeof(preselected)); + for (j=numpre=0; jU.vout && bits256_cmp(utxotxid,up->U.txid) == 0 ) + { + preselected[numpre++] = up; + printf("found utxotxid in slot.%d\n",j); + utxos[j] = 0; + continue; + } + if ( up->spendheight <= 0 && up->U.height > 0 && up->U.value != 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout)) == 0 ) + { + up->spendheight = 1; + utxos[j] = 0; + } + else + { + if ( LP_inventory_prevent(1,coin->symbol,up->U.txid,up->U.vout) == 0 ) + { + if ( min1 == 0 || up->U.value < min1->U.value ) + { + if ( min0 == 0 || up->U.value < min0->U.value ) + { + min1 = min0; + min0 = up; + } else min1 = up; + } + } else utxos[j] = 0; + if ( 0 && utxos[j] != 0 ) + printf("gettxout j.%d %s/v%d (%s)\n",j,bits256_str(str,up->U.txid),up->U.vout,jprint(txobj,0)); + free_json(txobj); + } + } else utxos[j] = 0; + } + if ( bits256_nonz(utxotxid) != 0 && numpre == 0 ) + { + up = LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout); + //printf("have utxotxid but wasnt found up.%p\n",up); + if ( up == 0 ) + { + value = LP_txvalue(0,coin->symbol,utxotxid,utxovout); + LP_address_utxoadd(0,(uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); + //printf("added after not finding\n"); + } + if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 ) + preselected[numpre++] = up; + else + { + printf("couldnt add address_utxo after not finding\n"); + sleep(1); + value = LP_txvalue(0,coin->symbol,utxotxid,utxovout); + LP_address_utxoadd(0,(uint32_t)time(NULL),"withdraw",coin,coin->smartaddr,utxotxid,utxovout,value,1,-1); + if ( (up= LP_address_utxofind(coin,coin->smartaddr,utxotxid,utxovout)) != 0 ) + preselected[numpre++] = up; + else printf("second couldnt add address_utxo after not finding\n"); + //return(0); + } + } + if ( dustcombine >= 1 && min0 != 0 && min0->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min0->SPV > 0) ) + { + for (j=0; j= 2 && min1 != 0 && min1->U.value < LP_DUSTCOMBINE_THRESHOLD && (coin->electrum == 0 || min1->SPV > 0) ) + { + for (j=0; jU.txid),up->U.vout,dstr(up->U.value)); + } + else + { + below = above = 0; + abovei = belowi = -1; + if ( LP_vin_select(&abovei,&above,&belowi,&below,utxos,numunspents,remains,maxmode) < 0 ) + { + printf("error finding unspent i.%d of %d, %.8f vs %.8f\n",i,numunspents,dstr(remains),dstr(amount)); + return(0); + } + if ( belowi < 0 || abovei >= 0 ) + ind = abovei; + else ind = belowi; + if ( ind < 0 ) + { + printf("error finding unspent i.%d of %d, %.8f vs %.8f, abovei.%d belowi.%d ind.%d\n",i,numunspents,dstr(remains),dstr(amount),abovei,belowi,ind); + return(0); + } + up = utxos[ind]; + utxos[ind] = utxos[--numunspents]; + utxos[numunspents] = 0; + for (j=0; jsymbol,coin->smartaddr,up->U.txid,up->U.vout) < 0 ) + continue; + } + if ( bits256_cmp(utxotxid,up->U.txid) != 0 && LP_allocated(up->U.txid,up->U.vout) != 0 ) + continue; + up->spendheight = 1; + total += up->U.value; + remains -= up->U.value; + interest = 0; + if ( up->U.height < 7777777 && strcmp(coin->symbol,"KMD") == 0 ) + { + if ( (interest= LP_komodo_interest(up->U.txid,up->U.value)) > 0 ) + { + interestsum += interest; + char str[65]; printf("%s/%d %.8f interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); + } + } + else if ( strcmp(coin->symbol,"HODLC") == 0 ) + { + if ( (interest= LP_hodlcoin_interest(coin->height,up->U.height,up->U.txid,up->U.value)) > 0 ) + { + interestsum += interest; + char str[65]; printf("%s/%d %.8f hodl interest %.8f -> sum %.8f\n",bits256_str(str,up->U.txid),up->U.vout,dstr(up->U.value),dstr(interest),dstr(interestsum)); + } + } + printf("numunspents.%d vini.%d value %.8f, total %.8f remains %.8f interest %.8f sum %.8f %s/v%d\n",numunspents,n,dstr(up->U.value),dstr(total),dstr(remains),dstr(interest),dstr(interestsum),bits256_str(str,up->U.txid),up->U.vout); + vp = &V[n++]; + vp->N = vp->M = 1; + vp->signers[0].privkey = privkey; + jaddistr(privkeys,wifstr); + bitcoin_pubkey33(ctx,vp->signers[0].pubkey,privkey); + vp->suppress_pubkeys = suppress_pubkeys; + vp->ignore_cltverr = ignore_cltverr; + jaddi(vins,LP_inputjson(up->U.txid,up->U.vout,spendscriptstr)); + LP_unavailableset(up->U.txid,up->U.vout,(uint32_t)time(NULL)+LP_RESERVETIME,G.LP_mypub25519); + if ( remains <= 0 && i >= numpre-1 ) + break; + if ( numunspents < 0 || n >= LP_MAXVINS ) + { + printf("total %.8f not enough for amount %.8f\n",dstr(total),dstr(amount)); + return(0); + } + } + *totalp = total + interestsum; + return(n); +} + +char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_info *coin,struct vin_info *V,int32_t max,bits256 privkey,cJSON *outputs,cJSON *vins,cJSON *privkeys,int64_t txfee,bits256 utxotxid,int32_t utxovout,uint32_t locktime) +{ + static void *ctx; + cJSON *txobj,*item; uint8_t addrtype,rmd160[20],script[64],spendscript[256]; char *coinaddr,*rawtxbytes; bits256 txid; uint32_t timestamp; int64_t change=0,adjust=0,total,value,amount = 0; int32_t i,dustcombine,scriptlen,spendlen,suppress_pubkeys,ignore_cltverr,numvouts=0,numvins=0,numutxos=0; struct LP_address_utxo *utxos[LP_MAXVINS*256]; struct LP_address *ap; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + *numvinsp = 0; + *txobjp = 0; + /*if ( sizeof(utxos)/sizeof(*utxos) != max ) + { + printf("LP_createrawtransaction: internal error %d != max.%d\n",(int32_t)(sizeof(utxos)/sizeof(*utxos)),max); + return(0); + }*/ + if ( coin == 0 || outputs == 0 || (numvouts= cJSON_GetArraySize(outputs)) <= 0 ) + { + printf("LP_createrawtransaction: illegal coin.%p outputs.%p or arraysize.%d, error\n",coin,outputs,numvouts); + return(0); + } + if ( coin->numutxos < LP_MINDESIRED_UTXOS ) + dustcombine = 0; + else if ( coin->numutxos >= LP_MAXDESIRED_UTXOS ) + dustcombine = 2; + else dustcombine = 1; +#ifdef LP_DISABLE_DISTCOMBINE + dustcombine = 0; +#endif + amount = txfee; + for (i=0; isymbol,coinaddr) <= 0 ) + { + printf("%s LP_createrawtransaction %s i.%d of %d is invalid\n",coin->symbol,coinaddr,i,numvouts); + return(0); + } + if ( (value= SATOSHIDEN * jdouble(item,coinaddr)) <= 0 ) + { + printf("cant get value %s i.%d of %d %s\n",coinaddr,i,numvouts,jprint(outputs,0)); + return(0); + } + amount += value; + //printf("vout.%d %.8f -> total %.8f\n",i,dstr(value),dstr(amount)); + } + else + { + printf("cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0)); + return(0); + } + } + if ( (ap= LP_address(coin,coin->smartaddr)) == 0 ) + { + printf("LP_createrawtransaction LP_address null?\n"); + return(0); + } + memset(utxos,0,sizeof(utxos)); + if ( (numutxos= LP_address_utxo_ptrs(coin,0,utxos,(int32_t)(sizeof(utxos)/sizeof(*utxos)),ap,coin->smartaddr)) <= 0 ) + { + if ( bits256_nonz(utxotxid) == 0 ) + { + printf("LP_createrawtransaction: address_utxo_ptrs %d, error\n",numutxos); + return(0); + } + } + //char str[65]; + //for (i=0; iU.txid),utxos[i]->U.vout,dstr(utxos[i]->U.value)); + + ignore_cltverr = 0; + suppress_pubkeys = 1; + scriptlen = bitcoin_standardspend(script,0,G.LP_myrmd160); + numvins = LP_vins_select(ctx,coin,&total,amount,V,utxos,numutxos,suppress_pubkeys,ignore_cltverr,privkey,privkeys,vins,script,scriptlen,utxotxid,utxovout,dustcombine); + if ( numvins <= 0 || total < amount ) + { + printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d, txfee %.8f\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts,dstr(txfee)); + printf("not enough inputs %.8f < for amount %.8f txfee %.8f\n",dstr(total),dstr(amount),dstr(txfee)); + return(0); + } + change = (total - amount); + timestamp = (uint32_t)time(NULL); + if ( locktime == 0 && strcmp("KMD",coin->symbol) == 0 ) + locktime = timestamp - 777; + txobj = bitcoin_txcreate(coin->symbol,coin->isPoS,locktime,coin->txversion,timestamp); + jdelete(txobj,"vin"); + jadd(txobj,"vin",jduplicate(vins)); + //printf("change %.8f = total %.8f - amount %.8f, adjust %.8f numvouts.%d\n",dstr(change),dstr(total),dstr(amount),dstr(adjust),numvouts); + for (i=0; isymbol,coin->taddr,&addrtype,rmd160,coinaddr); + if ( addrtype == coin->pubtype ) + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + else spendlen = bitcoin_p2shspend(spendscript,0,rmd160); + if ( i == numvouts-1 && strcmp(coinaddr,coin->smartaddr) == 0 && change != 0 ) + { + printf("combine last vout %.8f with change %.8f\n",dstr(value+adjust),dstr(change)); + value += change; + change = 0; + } + txobj = bitcoin_txoutput(txobj,spendscript,spendlen,value + adjust); + } + else + { + printf("cant get fieldname.%d of %d %s\n",i,numvouts,jprint(outputs,0)); + free_json(txobj); + return(0); + } + } + if ( change < 6000 ) + { + //adjust = change / numvouts; adjust messes up vout encoding! + change = 0; + } + if ( change != 0 ) + txobj = bitcoin_txoutput(txobj,script,scriptlen,change); + if ( (rawtxbytes= bitcoin_json2hex(coin->symbol,coin->isPoS,&txid,txobj,V)) != 0 ) + { + } else printf("error making rawtx suppress.%d\n",suppress_pubkeys); + *txobjp = txobj; + *numvinsp = numvins; + return(rawtxbytes); +} + +char *LP_withdraw(struct iguana_info *coin,cJSON *argjson) +{ + static void *ctx; + int32_t iter,i,utxovout,autofee,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; struct LP_address *ap; char changeaddr[64],vinaddr[64],str[65],*signedtx=0,*rawtx=0; struct vin_info *V; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 ) + { + printf("no outputs in argjson (%s)\n",jprint(argjson,0)); + return(clonestr("{\"error\":\"no outputs specified\"}")); + } + utxotxid = jbits256(argjson,"utxotxid"); + utxovout = jint(argjson,"utxovout"); + locktime = juint(argjson,"locktime"); + txfee = juint(argjson,"txfee"); + autofee = (strcmp(coin->symbol,"BTC") == 0); + if ( txfee == 0 ) + { + autofee = 1; + txfee = coin->txfee; + if ( txfee > 0 && txfee < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + } else autofee = 0; + suppress_pubkeys = 0; + memset(signedtxid.bytes,0,sizeof(signedtxid)); + safecopy(changeaddr,coin->smartaddr,sizeof(changeaddr)); + safecopy(vinaddr,coin->smartaddr,sizeof(vinaddr)); + privkey = LP_privkey(coin->symbol,vinaddr,coin->taddr); + maxV = LP_MAXVINS; + V = malloc(maxV * sizeof(*V)); + for (iter=0; iter<2; iter++) + { + if ( (ap= LP_address_utxo_reset(coin)) == 0 ) + { + printf("LP_withdraw error utxo reset %s\n",coin->symbol); + free(V); + return(0); + } + privkeys = cJSON_CreateArray(); + vins = cJSON_CreateArray(); + memset(V,0,sizeof(*V) * maxV); + numvins = 0; + if ( (rawtx= LP_createrawtransaction(&txobj,&numvins,coin,V,maxV,privkey,outputs,vins,privkeys,iter == 0 ? txfee : newtxfee,utxotxid,utxovout,locktime)) != 0 ) + { + completed = 0; + memset(&msgtx,0,sizeof(msgtx)); + memset(signedtxid.bytes,0,sizeof(signedtxid)); + if ( (completed= iguana_signrawtransaction(ctx,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&msgtx,&signedtx,&signedtxid,V,numvins,rawtx,vins,privkeys,coin->zcash)) < 0 ) + printf("couldnt sign withdraw %s\n",bits256_str(str,signedtxid)); + else if ( completed == 0 ) + { + printf("incomplete signing withdraw (%s)\n",jprint(vins,0)); + if ( signedtx != 0 ) + free(signedtx), signedtx = 0; + } //else printf("LP_withdraw.%s %s -> %s\n",coin->symbol,jprint(argjson,0),bits256_str(str,signedtxid)); + if ( signedtx == 0 ) + break; + datalen = (int32_t)strlen(signedtx) / 2; + if ( iter == 0 && strcmp(coin->symbol,"BTC") == 0 ) + { + newtxfee = LP_txfeecalc(coin,0,datalen); + printf("txfee %.8f -> newtxfee %.8f, numvins.%d\n",dstr(txfee),dstr(newtxfee),numvins); + for (i=0; i 0 ) + { + + for (i=0; isymbol)) == 0 ) + return(-1); + if ( strcmp(coin->smartaddr,vinaddr) != 0 ) + { + printf("???????????????????????? basilisk_rawtx_gen mismatched %s %s vinaddr.%s != (%s)\n",rawtx->symbol,coin->symbol,vinaddr,coin->smartaddr); + return(-1); + } + argjson = cJSON_CreateObject(); + jaddbits256(argjson,"utxotxid",rawtx->utxotxid); + jaddnum(argjson,"utxovout",rawtx->utxovout); + jaddnum(argjson,"locktime",locktime); + jadd64bits(argjson,"txfee",txfee); + outputs = cJSON_CreateArray(); + item = cJSON_CreateObject(); + jaddnum(item,rawtx->I.destaddr,dstr(rawtx->I.amount)); + jaddi(outputs,item); + jadd(argjson,"outputs",outputs); + //printf("call LP_withdraw.(%s)\n",jprint(argjson,0)); + if ( (retstr= LP_withdraw(coin,argjson)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (obj= jobj(retjson,"complete")) != 0 && is_cJSON_True(obj) != 0 && (hexstr= jstr(retjson,"hex")) != 0 && (len= is_hexstr(hexstr,0)) > 16 ) + { + rawtx->I.datalen = len >> 1; + decode_hex(rawtx->txbytes,rawtx->I.datalen,hexstr); + rawtx->I.completed = 1; + rawtx->I.signedtxid = jbits256(retjson,"txid"); + retval = 0; + } else printf("rawtx withdraw error? (%s)\n",jprint(argjson,0)); + free_json(retjson); + } + free(retstr); + } + free_json(argjson); + return(retval); +/*#ifdef old + int32_t retval=-1,iter; char *signedtx,*changeaddr = 0,_changeaddr[64]; struct iguana_info *coin; int64_t newtxfee=0,destamount; + char str2[65]; printf("%s rawtxgen.(%s/v%d)\n",rawtx->name,bits256_str(str2,rawtx->utxotxid),rawtx->utxovout); + if ( (coin= rawtx->coin) == 0 ) + return(-1); + //return(_basilisk_rawtx_gen(str,swapstarted,pubkey33,iambob,lockinputs,rawtx,locktime,script,scriptlen,txfee,minconf,delay,privkey)); + if ( changermd160 != 0 ) + { + changeaddr = _changeaddr; + bitcoin_address(changeaddr,coin->taddr,coin->pubtype,changermd160,20); + //printf("changeaddr.(%s) vs destaddr.(%s)\n",changeaddr,rawtx->I.destaddr); + } + if ( strcmp(str,"myfee") == 0 && strcmp(coin->symbol,"BTC") == 0 ) + txfee = LP_MIN_TXFEE; + for (iter=0; iter<2; iter++) + { + if ( (signedtx= basilisk_swap_bobtxspend(&rawtx->I.signedtxid,iter == 0 ? txfee : newtxfee,str,coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,ctx,privkey,0,0,0,0,0,rawtx->utxotxid,rawtx->utxovout,rawtx->I.destaddr,pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,rawtx->I.suppress_pubkeys,coin->zcash)) != 0 ) + { + rawtx->I.datalen = (int32_t)strlen(signedtx) >> 1; + if ( rawtx->I.datalen <= sizeof(rawtx->txbytes) ) + { + decode_hex(rawtx->txbytes,rawtx->I.datalen,signedtx); + rawtx->I.completed = 1; + retval = 0; + } + free(signedtx); + if ( strcmp(coin->symbol,"BTC") != 0 ) + return(retval); + newtxfee = LP_txfeecalc(coin,0,rawtx->I.datalen); + printf("txfee %.8f -> newtxfee %.8f\n",dstr(txfee),dstr(newtxfee)); + } else break; + if ( strcmp(str,"myfee") == 0 ) + break; + } + return(retval); +#endif*/ +} + +int32_t basilisk_rawtx_sign(char *symbol,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen,int32_t ignore_cltverr,uint8_t *changermd160,char *vinaddr,int32_t zcash) +{ + char *signedtx,*changeaddr = 0,_changeaddr[64]; int64_t txfee,newtxfee=0,destamount; uint32_t timestamp,locktime=0,sequenceid = 0xffffffff; int32_t iter,retval = -1; double estimatedrate; + //char str2[65]; printf("%s rawtxsign.(%s/v%d)\n",dest->name,bits256_str(str2,dest->utxotxid),dest->utxovout); + timestamp = swap->I.started; + if ( dest == &swap->aliceclaim ) + locktime = swap->bobdeposit.I.locktime + 1, sequenceid = 0; + else if ( dest == &swap->bobreclaim ) + locktime = swap->bobpayment.I.locktime + 1, sequenceid = 0; + txfee = strcmp("BTC",symbol) == 0 ? 0 : LP_MIN_TXFEE; + if ( changermd160 != 0 ) + { + changeaddr = _changeaddr; + bitcoin_address(symbol,changeaddr,taddr,pubtype,changermd160,20); + //printf("changeaddr.(%s)\n",changeaddr); + } + for (iter=0; iter<2; iter++) + { + if ( (signedtx= basilisk_swap_bobtxspend(&dest->I.signedtxid,iter == 0 ? txfee : newtxfee,rawtx->name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,swap->ctx,privkey,privkey2,rawtx->redeemscript,rawtx->I.redeemlen,userdata,userdatalen,dest->utxotxid,dest->utxovout,dest->I.destaddr,rawtx->I.pubkey33,1,0,&destamount,rawtx->I.amount,changeaddr,vinaddr,dest->I.suppress_pubkeys,zcash)) != 0 ) + { + dest->I.datalen = (int32_t)strlen(signedtx) >> 1; + if ( dest->I.datalen <= sizeof(dest->txbytes) ) + { + decode_hex(dest->txbytes,dest->I.datalen,signedtx); + dest->I.completed = 1; + retval = 0; + } + free(signedtx); + if ( strcmp(symbol,"BTC") != 0 ) + return(retval); + estimatedrate = LP_getestimatedrate(LP_coinfind(symbol)); + newtxfee = estimatedrate * dest->I.datalen; + } else break; + } + return(retval); + //return(_basilisk_rawtx_sign(symbol,pubtype,p2shtype,isPoS,wiftype,swap,timestamp,locktime,sequenceid,dest,rawtx,privkey,privkey2,userdata,userdatalen,ignore_cltverr)); +} + +int32_t basilisk_alicescript(char *symbol,uint8_t *redeemscript,int32_t *redeemlenp,uint8_t *script,int32_t n,char *msigaddr,uint8_t taddr,uint8_t altps2h,bits256 pubAm,bits256 pubBn) +{ + uint8_t p2sh160[20]; struct vin_info V; + memset(&V,0,sizeof(V)); + memcpy(&V.signers[0].pubkey[1],pubAm.bytes,sizeof(pubAm)), V.signers[0].pubkey[0] = 0x02; + memcpy(&V.signers[1].pubkey[1],pubBn.bytes,sizeof(pubBn)), V.signers[1].pubkey[0] = 0x03; + V.M = V.N = 2; + *redeemlenp = bitcoin_MofNspendscript(p2sh160,redeemscript,n,&V); + bitcoin_address(symbol,msigaddr,taddr,altps2h,p2sh160,sizeof(p2sh160)); + n = bitcoin_p2shspend(script,0,p2sh160); + //for (i=0; i<*redeemlenp; i++) + // printf("%02x",redeemscript[i]); + //printf(" <- redeemscript alicetx\n"); + return(n); +} + +char *basilisk_swap_Aspend(char *name,char *symbol,uint64_t Atxfee,uint8_t wiftaddr,uint8_t taddr,uint8_t pubtype,uint8_t p2shtype,uint8_t isPoS,uint8_t wiftype,void *ctx,bits256 privAm,bits256 privBn,bits256 utxotxid,int32_t utxovout,uint8_t pubkey33[33],uint32_t expiration,int64_t *destamountp,char *vinaddr,int32_t zcash) +{ + char msigaddr[64],*signedtx = 0; int32_t spendlen,redeemlen; uint8_t tmp33[33],redeemscript[512],spendscript[128]; bits256 pubAm,pubBn,signedtxid; uint64_t txfee; + if ( bits256_nonz(privAm) != 0 && bits256_nonz(privBn) != 0 ) + { + pubAm = bitcoin_pubkey33(ctx,tmp33,privAm); + pubBn = bitcoin_pubkey33(ctx,tmp33,privBn); + //char str[65]; + //printf("pubAm.(%s)\n",bits256_str(str,pubAm)); + //printf("pubBn.(%s)\n",bits256_str(str,pubBn)); + spendlen = basilisk_alicescript(symbol,redeemscript,&redeemlen,spendscript,0,msigaddr,taddr,p2shtype,pubAm,pubBn); + if ( (txfee= Atxfee) == 0 ) + { + if ( (txfee= LP_getestimatedrate(LP_coinfind(symbol)) * LP_AVETXSIZE) < LP_MIN_TXFEE ) + txfee = LP_MIN_TXFEE; + } + signedtx = basilisk_swap_bobtxspend(&signedtxid,txfee,name,symbol,wiftaddr,taddr,pubtype,p2shtype,isPoS,wiftype,ctx,privAm,&privBn,redeemscript,redeemlen,0,0,utxotxid,utxovout,0,pubkey33,1,expiration,destamountp,0,0,vinaddr,1,zcash); + LP_mark_spent(symbol,utxotxid,utxovout); + } + return(signedtx); +} + +int32_t LP_swap_getcoinaddr(char *symbol,char *coinaddr,bits256 txid,int32_t vout) +{ + cJSON *retjson; + coinaddr[0] = 0; + if ( (retjson= LP_gettx(symbol,txid,0)) != 0 ) + { + LP_txdestaddr(coinaddr,txid,vout,retjson); + free_json(retjson); + } + return(coinaddr[0] != 0); +} + +int32_t basilisk_swap_getsigscript(char *symbol,uint8_t *script,int32_t maxlen,bits256 txid,int32_t vini) +{ + cJSON *retjson,*vins,*item,*skey; int32_t n,scriptlen = 0; char *hexstr; + if ( (retjson= LP_gettx(symbol,txid,0)) != 0 ) + { + if ( (vins= jarray(&n,retjson,"vin")) != 0 && vini < n ) + { + item = jitem(vins,vini); + if ( (skey= jobj(item,"scriptSig")) != 0 && (hexstr= jstr(skey,"hex")) != 0 && (scriptlen= (int32_t)strlen(hexstr)) < maxlen*2 ) + { + scriptlen >>= 1; + decode_hex(script,scriptlen,hexstr); + //char str[65]; printf("%s/v%d sigscript.(%s)\n",bits256_str(str,txid),vini,hexstr); + } + } + free_json(retjson); + } + return(scriptlen); +} + +#ifdef notnow +bits256 _LP_swap_spendtxid(char *symbol,char *destaddr,char *coinaddr,bits256 utxotxid,int32_t vout) +{ + char *retstr,*addr; cJSON *array,*item,*array2; int32_t i,n,m; bits256 spendtxid,txid; + memset(&spendtxid,0,sizeof(spendtxid)); + if ( (retstr= blocktrail_listtransactions(symbol,coinaddr,100,0)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i %s\n",bits256_str(str,spendtxid),destaddr); + break; + } + } + } + } + free_json(array); + } + free(retstr); + } + return(spendtxid); +} +#endif + +bits256 LP_swap_spendtxid(char *symbol,char *destaddr,bits256 utxotxid,int32_t utxovout) +{ + bits256 spendtxid,txid,vintxid; int32_t spendvin,i,j,m,n; char coinaddr[64]; cJSON *array,*vins,*vin,*txobj; struct iguana_info *coin; + // listtransactions or listspents + coinaddr[0] = 0; + memset(&spendtxid,0,sizeof(spendtxid)); + if ( LP_spendsearch(destaddr,&spendtxid,&spendvin,symbol,utxotxid,utxovout) > 0 ) + { + //char str[65]; printf("%s dest.%s spend of %s/v%d detected\n",symbol,destaddr,bits256_str(str,utxotxid),utxovout); + } + else if ( (coin= LP_coinfind(symbol)) != 0 && coin->electrum == 0 ) + { + //printf("get received by %s\n",destaddr); + if ( (array= LP_listreceivedbyaddress(symbol,destaddr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; istarted + swap->putduration + swap->callduration; + else *locktimep = swap->started + swap->putduration; + *redeemlenp = n = basilisk_swap_bobredeemscript(depositflag,secretstartp,redeemscript,*locktimep,swap->pubA0,swap->pubB0,swap->pubB1,swap->privAm,swap->privBn,swap->secretAm,swap->secretAm256,swap->secretBn,swap->secretBn256); + if ( n > 0 ) + { + calc_rmd160_sha256(rmd160,redeemscript,n); + n = bitcoin_p2shspend(script,0,rmd160); + //int32_t i; for (i=0; i if path, 0 -> else path + return(len); +} + +/*Bob paytx: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF*/ + +int32_t basilisk_bobpayment_reclaim(struct basilisk_swap *swap,int32_t delay) +{ + static bits256 zero; + uint8_t userdata[512]; int32_t retval,len = 0; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + //printf("basilisk_bobpayment_reclaim\n"); + len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[1],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + memcpy(swap->I.userdata_bobreclaim,userdata,len); + swap->I.userdata_bobreclaimlen = len; + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->bobreclaim,&swap->bobpayment,swap->I.myprivs[1],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,coin->zcash)) == 0 ) + { + //for (i=0; ibobreclaim.I.datalen; i++) + // printf("%02x",swap->bobreclaim.txbytes[i]); + //printf(" <- bobreclaim\n"); + //basilisk_txlog(swap,&swap->bobreclaim,delay); + return(retval); + } + } else printf("basilisk_bobpayment_reclaim cant find (%s)\n",swap->I.bobstr); + return(-1); +} + +int32_t basilisk_bobdeposit_refund(struct basilisk_swap *swap,int32_t delay) +{ + uint8_t userdata[512]; int32_t i,retval,len = 0; char str[65]; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + len = basilisk_swapuserdata(userdata,swap->I.privBn,0,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + memcpy(swap->I.userdata_bobrefund,userdata,len); + swap->I.userdata_bobrefundlen = len; + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->bobrefund,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,0,swap->changermd160,swap->bobdeposit.I.destaddr,coin->zcash)) == 0 ) + { + for (i=0; ibobrefund.I.datalen; i++) + printf("%02x",swap->bobrefund.txbytes[i]); + printf(" <- bobrefund.(%s)\n",bits256_str(str,swap->bobrefund.I.txid)); + //basilisk_txlog(swap,&swap->bobrefund,delay); + return(retval); + } + } else printf("basilisk_bobdeposit_refund cant find (%s)\n",swap->I.bobstr); + + return(-1); +} + +void LP_swap_coinaddr(struct iguana_info *coin,char *coinaddr,uint64_t *valuep,uint8_t *data,int32_t datalen,int32_t v) +{ + cJSON *txobj,*vouts,*vout; uint8_t extraspace[32768]; bits256 signedtxid; struct iguana_msgtx msgtx; int32_t n,suppress_pubkeys = 0; + if ( valuep != 0 ) + *valuep = 0; + if ( (txobj= bitcoin_data2json(coin->symbol,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->longestchain,&signedtxid,&msgtx,extraspace,sizeof(extraspace),data,datalen,0,suppress_pubkeys,coin->zcash)) != 0 ) + { + //char str[65]; printf("got txid.%s (%s)\n",bits256_str(str,signedtxid),jprint(txobj,0)); + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n > 0 ) + { + vout = jitem(vouts,v); + if ( valuep != 0 ) + *valuep = LP_value_extract(vout,1); + LP_destaddr(coinaddr,vout); + } + free_json(txobj); + } +} + +int32_t basilisk_bobscripts_set(struct basilisk_swap *swap,int32_t depositflag,int32_t genflag) +{ + char coinaddr[64],checkaddr[64]; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + bitcoin_address(coin->symbol,coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); + if ( genflag != 0 && swap->I.iambob == 0 ) + printf("basilisk_bobscripts_set WARNING: alice generating BOB tx\n"); + if ( depositflag == 0 ) + { + swap->bobpayment.I.spendlen = basilisk_bobscript(swap->bobpayment.I.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.I.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.I.locktime,&swap->bobpayment.I.secretstart,&swap->I,0); + bitcoin_address(coin->symbol,swap->bobpayment.p2shaddr,coin->taddr,coin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); + //LP_importaddress(coin->symbol,swap->bobpayment.I.destaddr); + //int32_t i; for (i=0; ibobpayment.I.redeemlen; i++) + // printf("%02x",swap->bobpayment.redeemscript[i]); + //printf(" <- bobpayment redeem %d %s\n",i,swap->bobpayment.I.destaddr); + if ( genflag != 0 && bits256_nonz(*(bits256 *)swap->I.secretBn256) != 0 && swap->bobpayment.I.datalen == 0 ) + { + basilisk_rawtx_gen(swap->ctx,"payment",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobpayment,swap->bobpayment.I.locktime,swap->bobpayment.spendscript,swap->bobpayment.I.spendlen,coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); + if ( swap->bobpayment.I.spendlen == 0 || swap->bobpayment.I.datalen == 0 ) + { + printf("error bob generating %p payment.%d\n",swap->bobpayment.txbytes,swap->bobpayment.I.spendlen); + sleep(DEX_SLEEP); + } + else + { + /*for (j=0; jbobpayment.I.datalen; j++) + printf("%02x",swap->bobpayment.txbytes[j]); + printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); + for (j=0; jbobpayment.I.redeemlen; j++) + printf("%02x",swap->bobpayment.redeemscript[j]); + printf(" <- redeem.%d\n",swap->bobpayment.I.redeemlen); + printf(" <- GENERATED BOB PAYMENT.%d destaddr.(%s)\n",swap->bobpayment.I.datalen,swap->bobpayment.I.destaddr);*/ + LP_swap_coinaddr(coin,checkaddr,0,swap->bobpayment.txbytes,swap->bobpayment.I.datalen,0); + if ( strcmp(swap->bobpayment.I.destaddr,checkaddr) != 0 ) + { + printf("BOBPAYMENT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobpayment.I.destaddr,checkaddr); + return(-1); + } + LP_unspents_mark(coin->symbol,swap->bobpayment.vins); + //printf("bobscripts set completed\n"); + return(0); + } + } + } + else + { + swap->bobdeposit.I.spendlen = basilisk_bobscript(swap->bobdeposit.I.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.I.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.I.locktime,&swap->bobdeposit.I.secretstart,&swap->I,1); + bitcoin_address(coin->symbol,swap->bobdeposit.p2shaddr,coin->taddr,coin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); + //int32_t i; for (i=0; ibobdeposit.I.redeemlen; i++) + // printf("%02x",swap->bobdeposit.redeemscript[i]); + //printf(" <- bobdeposit redeem %d %s\n",i,swap->bobdeposit.I.destaddr); + if ( genflag != 0 && (swap->bobdeposit.I.datalen == 0 || swap->bobrefund.I.datalen == 0) ) + { + basilisk_rawtx_gen(swap->ctx,"deposit",swap->I.started,swap->persistent_pubkey33,1,1,&swap->bobdeposit,swap->bobdeposit.I.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.I.spendlen,coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); + if ( swap->bobdeposit.I.datalen == 0 || swap->bobdeposit.I.spendlen == 0 ) + { + printf("error bob generating %p deposit.%d\n",swap->bobdeposit.txbytes,swap->bobdeposit.I.spendlen); + sleep(DEX_SLEEP); + } + else + { + //for (j=0; jbobdeposit.I.datalen; j++) + // printf("%02x",swap->bobdeposit.txbytes[j]); + //printf(" <- GENERATED BOB DEPOSIT.%d (%s)\n",swap->bobdeposit.I.datalen,swap->bobdeposit.I.destaddr); + LP_swap_coinaddr(coin,checkaddr,0,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen,0); + if ( strcmp(swap->bobdeposit.I.destaddr,checkaddr) != 0 ) + { + printf("BOBDEPOSIT REDEEMADDR MISMATCH??? %s != %s\n",swap->bobdeposit.I.destaddr,checkaddr); + return(-1); + } + LP_unspents_mark(coin->symbol,swap->bobdeposit.vins); + //printf("bobscripts set completed\n"); + return(0); + } + } + } + } else printf("bobscripts set cant find (%s)\n",swap->I.bobstr); + return(0); +} + +/* + +#ifdef old +int32_t basilisk_alicepayment_spend(struct basilisk_swap *swap,struct basilisk_rawtx *dest) +{ + int32_t i,retval; + printf("alicepayment_spend\n"); + swap->alicepayment.I.spendlen = basilisk_alicescript(swap->alicepayment.redeemscript,&swap->alicepayment.I.redeemlen,swap->alicepayment.spendscript,0,swap->alicepayment.I.destaddr,coin->p2shtype,swap->I.pubAm,swap->I.pubBn); + printf("alicepayment_spend len.%d\n",swap->alicepayment.I.spendlen); + if ( swap->I.iambob == 0 ) + { + memcpy(swap->I.userdata_alicereclaim,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); + swap->I.userdata_alicereclaimlen = swap->alicepayment.I.spendlen; + } + else + { + memcpy(swap->I.userdata_bobspend,swap->alicepayment.redeemscript,swap->alicepayment.I.spendlen); + swap->I.userdata_bobspendlen = swap->alicepayment.I.spendlen; + } + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,dest,&swap->alicepayment,swap->I.privAm,&swap->I.privBn,0,0,1,swap->changermd160)) == 0 ) + { + for (i=0; iI.datalen; i++) + printf("%02x",dest->txbytes[i]); + printf(" <- msigspend\n\n"); + if ( dest == &swap->bobspend ) + swap->I.bobspent = 1; + //basilisk_txlog(swap,dest,0); // bobspend or alicereclaim + return(retval); + } + return(-1); +} +#endif*/ + +void basilisk_alicepayment(struct basilisk_swap *swap,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn) +{ + char coinaddr[64]; + alicepayment->I.spendlen = basilisk_alicescript(coin->symbol,alicepayment->redeemscript,&alicepayment->I.redeemlen,alicepayment->spendscript,0,alicepayment->I.destaddr,coin->taddr,coin->p2shtype,pubAm,pubBn); + bitcoin_address(coin->symbol,coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); + //printf("%s suppress.%d fee.%d\n",coinaddr,alicepayment->I.suppress_pubkeys,swap->myfee.I.suppress_pubkeys); + basilisk_rawtx_gen(swap->ctx,"alicepayment",swap->I.started,swap->persistent_pubkey33,0,1,alicepayment,alicepayment->I.locktime,alicepayment->spendscript,alicepayment->I.spendlen,swap->I.Atxfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr); +} + +int32_t basilisk_alicetxs(int32_t pairsock,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + char coinaddr[64]; int32_t retval = -1; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + { + if ( swap->alicepayment.I.datalen == 0 ) + basilisk_alicepayment(swap,coin,&swap->alicepayment,swap->I.pubAm,swap->I.pubBn); + if ( swap->alicepayment.I.datalen == 0 || swap->alicepayment.I.spendlen == 0 ) + printf("error alice generating payment.%d\n",swap->alicepayment.I.spendlen); + else + { + bitcoin_address(coin->symbol,swap->alicepayment.I.destaddr,coin->taddr,coin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); + //LP_importaddress(coin->symbol,swap->alicepayment.I.destaddr); + strcpy(swap->alicepayment.p2shaddr,swap->alicepayment.I.destaddr); + retval = 0; + //for (i=0; ialicepayment.I.datalen; i++) + // printf("%02x",swap->alicepayment.txbytes[i]); + //printf(" ALICE PAYMENT created.(%s)\n",swap->alicepayment.I.destaddr); + LP_unspents_mark(coin->symbol,swap->alicepayment.vins); + //LP_importaddress(coin->symbol,swap->alicepayment.I.destaddr); + //basilisk_txlog(swap,&swap->alicepayment,-1); + } + if ( swap->myfee.I.datalen == 0 ) + { + //printf("%s generate fee %.8f from.%s\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee),coin->smartaddr); + bitcoin_address(coin->symbol,coinaddr,coin->taddr,coin->pubtype,swap->changermd160,20); + if ( basilisk_rawtx_gen(swap->ctx,"myfee",swap->I.started,swap->persistent_pubkey33,swap->I.iambob,1,&swap->myfee,swap->myfee.I.locktime,swap->myfee.spendscript,swap->myfee.I.spendlen,strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee,1,0,swap->persistent_privkey,swap->changermd160,coinaddr) == 0 ) + { + //printf("rawtxsend %s %.8f\n",coin->symbol,dstr(strcmp(coin->symbol,"BTC") == 0 ? LP_MIN_TXFEE : coin->txfee)); + swap->I.statebits |= LP_swapdata_rawtxsend(pairsock,swap,0x80,data,maxlen,&swap->myfee,0x40,0); + LP_unspents_mark(swap->I.iambob!=0?coin->symbol:coin->symbol,swap->myfee.vins); + //basilisk_txlog(swap,&swap->myfee,-1); + //for (i=0; imyfee.I.datalen; i++) + // printf("%02x",swap->myfee.txbytes[i]); + //printf(" <- fee state.%x\n",swap->I.statebits); + swap->I.statebits |= 0x40; + } + else + { + printf("error creating myfee\n"); + return(-2); + } + } + if ( swap->alicepayment.I.datalen != 0 && swap->alicepayment.I.spendlen > 0 && swap->myfee.I.datalen != 0 && swap->myfee.I.spendlen > 0 ) + { + //printf("fee sent\n"); + return(0); + } + } else printf("basilisk alicetx cant find (%s)\n",swap->I.alicestr); + return(-1); +} + +int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + int32_t diff; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.iambob != 0 ? swap->I.alicestr : swap->I.bobstr)) != 0 ) + { + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->otherfee,0,data,datalen,0) == 0 ) + { + //printf("otherfee amount %.8f -> %s vs %s locktime %u vs %u\n",dstr(swap->otherfee.I.amount),swap->otherfee.p2shaddr,swap->otherfee.I.destaddr,swap->otherfee.I.locktime,swap->I.started+1); + if ( strcmp(swap->otherfee.I.destaddr,swap->otherfee.p2shaddr) == 0 ) + { + diff = swap->otherfee.I.locktime - (swap->I.started+1); + if ( diff < 0 ) + diff = -diff; + if ( diff < LP_AUTOTRADE_TIMEOUT ) + { + //printf("dexfee verified\n"); + } + else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1); + return(0); + } else printf("destaddress mismatch in other fee, reject (%s) vs (%s)\n",swap->otherfee.I.destaddr,swap->otherfee.p2shaddr); + } + } else printf("cant find other coin iambob.%d\n",swap->I.iambob); + return(-1); +} + +int32_t LP_verify_alicespend(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + { + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->alicespend,0,data,datalen,0) == 0 ) + { + printf("alicespend amount %.8f -> %s vs %s\n",dstr(swap->alicespend.I.amount),swap->alicespend.p2shaddr,swap->alicespend.I.destaddr); + if ( strcmp(swap->alicespend.I.destaddr,swap->alicespend.p2shaddr) == 0 ) + { + printf("alicespend verified\n"); + return(0); + } + } + } else printf("verify alicespend cant find (%s)\n",swap->I.alicestr); + return(-1); +} + +/* Bob deposit: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF*/ + +int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + static bits256 zero; + uint8_t userdata[512]; int32_t retval=-1,len = 0; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->bobdeposit,0,data,datalen,0) == 0 ) + { + swap->aliceclaim.utxovout = 0; + swap->bobdeposit.I.signedtxid = LP_broadcast_tx(swap->bobdeposit.name,coin->symbol,swap->bobdeposit.txbytes,swap->bobdeposit.I.datalen); + if ( bits256_nonz(swap->bobdeposit.I.signedtxid) != 0 ) + swap->depositunconf = 1; + else swap->bobdeposit.I.signedtxid = swap->bobdeposit.I.actualtxid; + len = basilisk_swapuserdata(userdata,zero,1,swap->I.myprivs[0],swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + swap->aliceclaim.utxotxid = swap->bobdeposit.I.signedtxid; + memcpy(swap->I.userdata_aliceclaim,userdata,len); + swap->I.userdata_aliceclaimlen = len; + bitcoin_address(coin->symbol,swap->bobdeposit.p2shaddr,coin->taddr,coin->p2shtype,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + strcpy(swap->bobdeposit.I.destaddr,swap->bobdeposit.p2shaddr); + basilisk_dontforget_update(swap,&swap->bobdeposit); + //int32_t i; char str[65]; for (i=0; ibobdeposit.I.datalen; i++) + // printf("%02x",swap->bobdeposit.txbytes[i]); + //printf(" <- bobdeposit.%d %s\n",swap->bobdeposit.I.datalen,bits256_str(str,swap->bobdeposit.I.signedtxid)); + //for (i=0; ibobdeposit.I.redeemlen; i++) + // printf("%02x",swap->bobdeposit.redeemscript[i]); + //printf(" <- bobdeposit redeem %d %s suppress.%d\n",i,swap->bobdeposit.I.destaddr,swap->aliceclaim.I.suppress_pubkeys); + memcpy(swap->aliceclaim.redeemscript,swap->bobdeposit.redeemscript,swap->bobdeposit.I.redeemlen); + swap->aliceclaim.I.redeemlen = swap->bobdeposit.I.redeemlen; + memcpy(swap->aliceclaim.I.pubkey33,swap->persistent_pubkey33,33); + bitcoin_address(coin->symbol,swap->aliceclaim.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33); + retval = 0; + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->aliceclaim,&swap->bobdeposit,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobdeposit.I.destaddr,coin->zcash)) == 0 ) + { + /*int32_t i; for (i=0; ibobdeposit.I.datalen; i++) + printf("%02x",swap->bobdeposit.txbytes[i]); + printf(" <- bobdeposit\n"); + for (i=0; ialiceclaim.I.datalen; i++) + printf("%02x",swap->aliceclaim.txbytes[i]); + printf(" <- aliceclaim\n");*/ + //basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); + return(LP_waitmempool(coin->symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60)); + } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr); + } + } else printf("verify bob depositcant find bob coin (%s)\n",swap->I.bobstr); + printf("error with bobdeposit\n"); + return(retval); +} + +int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.alicestr)) != 0 ) + { + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->alicepayment,0,data,datalen,0) == 0 ) + { + swap->bobspend.utxovout = 0; + swap->bobspend.utxotxid = swap->alicepayment.I.signedtxid = LP_broadcast_tx(swap->alicepayment.name,coin->symbol,swap->alicepayment.txbytes,swap->alicepayment.I.datalen); + bitcoin_address(coin->symbol,swap->alicepayment.p2shaddr,coin->taddr,coin->p2shtype,swap->alicepayment.redeemscript,swap->alicepayment.I.redeemlen); + strcpy(swap->alicepayment.I.destaddr,swap->alicepayment.p2shaddr); + if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 ) + swap->aliceunconf = 1; + basilisk_dontforget_update(swap,&swap->alicepayment); + return(LP_waitmempool(coin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60)); + //printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr); + //LP_importaddress(coin->symbol,swap->alicepayment.p2shaddr); + return(0); + } + } else printf("verify alicepayment couldnt find coin.(%s)\n",swap->I.alicestr); + printf("error validating alicepayment\n"); + return(-1); +} + +int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t datalen) +{ + uint8_t userdata[512]; int32_t i,retval=-1,len = 0; bits256 revAm; struct iguana_info *coin; + if ( (coin= LP_coinfind(swap->I.bobstr)) != 0 ) + { + memset(revAm.bytes,0,sizeof(revAm)); + if ( LP_rawtx_spendscript(swap,coin->longestchain,&swap->bobpayment,0,data,datalen,0) == 0 ) + { + swap->alicespend.utxovout = 0; + swap->alicespend.utxotxid = swap->bobpayment.I.signedtxid = LP_broadcast_tx(swap->bobpayment.name,coin->symbol,swap->bobpayment.txbytes,swap->bobpayment.I.datalen); + if ( bits256_nonz(swap->bobpayment.I.signedtxid) != 0 ) + swap->paymentunconf = 1; + for (i=0; i<32; i++) + revAm.bytes[i] = swap->I.privAm.bytes[31-i]; + len = basilisk_swapuserdata(userdata,revAm,0,swap->I.myprivs[0],swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + bitcoin_address(coin->symbol,swap->bobpayment.p2shaddr,coin->taddr,coin->p2shtype,swap->bobpayment.redeemscript,swap->bobpayment.I.redeemlen); + strcpy(swap->bobpayment.I.destaddr,swap->bobpayment.p2shaddr); + basilisk_dontforget_update(swap,&swap->bobpayment); + //LP_importaddress(coin->symbol,swap->bobpayment.I.destaddr); + /*for (i=0; ibobpayment.I.datalen; i++) + printf("%02x",swap->bobpayment.txbytes[i]); + printf(" <- bobpayment.%d\n",swap->bobpayment.I.datalen); + for (i=0; ibobpayment.I.redeemlen; i++) + printf("%02x",swap->bobpayment.redeemscript[i]); + printf(" <- bobpayment redeem %d %s %s\n",i,swap->bobpayment.I.destaddr,bits256_str(str,swap->bobpayment.I.signedtxid));*/ + memcpy(swap->I.userdata_alicespend,userdata,len); + swap->I.userdata_alicespendlen = len; + retval = 0; + memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33); + bitcoin_address(coin->symbol,swap->alicespend.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33); + //char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0])); + if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,coin->zcash)) == 0 ) + { + /*for (i=0; ibobpayment.I.datalen; i++) + printf("%02x",swap->bobpayment.txbytes[i]); + printf(" <- bobpayment\n"); + for (i=0; ialicespend.I.datalen; i++) + printf("%02x",swap->alicespend.txbytes[i]); + printf(" <- alicespend\n\n");*/ + swap->I.alicespent = 1; + return(LP_waitmempool(coin->symbol,swap->bobpayment.I.destaddr,swap->bobpayment.I.signedtxid,0,60)); + } else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->alicespend.I.suppress_pubkeys,swap->bobpayment.I.destaddr); + } + } else printf("verify bobpayment cant find (%s)\n",swap->I.bobstr); + printf("error validating bobpayment\n"); + return(-1); +} diff --git a/iguana/exchanges/LP_utxo.c b/iguana/exchanges/LP_utxo.c new file mode 100644 index 000000000..f33d8b32f --- /dev/null +++ b/iguana/exchanges/LP_utxo.c @@ -0,0 +1,1229 @@ + +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// LP_utxo.c +// marketmaker +// + + +struct LP_inuse_info +{ + bits256 txid,otherpub; + uint32_t expiration; + int32_t vout,ind; +} LP_inuse[1024]; +int32_t LP_numinuse; + +struct LP_inuse_info *_LP_inuse_find(bits256 txid,int32_t vout) +{ + int32_t i; + if ( bits256_nonz(txid) != 0 ) + { + for (i=0; iind; + if ( LP_numinuse > 0 ) + *lp = LP_inuse[--LP_numinuse]; + lp->ind = ind; + memset(&LP_inuse[LP_numinuse],0,sizeof(struct LP_inuse_info)); + //printf("_LP_inuse_delete mark as free %s/v%d find.%p\n",bits256_str(str,txid),vout,_LP_inuse_find(txid,vout)); + for (ind=0; ind= sizeof(LP_inuse)/sizeof(*LP_inuse) ) + { + now = (uint32_t)time(NULL); + n = 0; + oldesti = -1; + oldest = 0; + for (i=0; i lp->expiration ) + _LP_inuse_delete(lp->txid,lp->vout), n++; + else if ( oldest == 0 || lp->expiration < oldest ) + { + oldest = lp->expiration; + oldesti = i; + } + } + if ( n == 0 ) + { + printf("_LP_inuse_add out of slots error, pick oldesti %d\n",oldesti); + lp = &LP_inuse[oldesti]; + _LP_inuse_delete(lp->txid,lp->vout); + } else printf("expired %d inuse slots\n",n); + } + if ( bits256_nonz(txid) != 0 ) + { + if ( (lp= _LP_inuse_find(txid,vout)) == 0 ) + { + lp = &LP_inuse[LP_numinuse]; + memset(lp,0,sizeof(*lp)); + lp->txid = txid; + lp->vout = vout; + lp->expiration = expiration; + lp->otherpub = otherpub; + lp->ind = LP_numinuse++; + } + else + { + if ( bits256_nonz(otherpub) != 0 ) + lp->otherpub = otherpub; + //if ( expiration > lp->expiration || expiration == 0 ) + lp->expiration = expiration; + } + char str[65]; printf("set inuse until %u lag.%d for %s/v%d\n",expiration,(int32_t)(expiration-(uint32_t)time(NULL)),bits256_str(str,txid),vout); + return(lp); + } else printf("_LP_inuse_add [%d] overflow\n",LP_numinuse); + return(0); +} + +int32_t LP_reservation_check(bits256 txid,int32_t vout,bits256 pubkey) +{ + struct LP_inuse_info *lp; int32_t retval = -1; + if ( bits256_nonz(pubkey) != 0 ) + { + portable_mutex_lock(&LP_inusemutex); + if ( (lp= _LP_inuse_find(txid,vout)) != 0 ) + { + if ( bits256_cmp(lp->otherpub,pubkey) == 0 ) + retval = 0; + } + portable_mutex_unlock(&LP_inusemutex); + } + return(retval); +} + +uint32_t LP_allocated(bits256 txid,int32_t vout) +{ + struct LP_inuse_info *lp; uint32_t now,duration = 0; + now = (uint32_t)time(NULL); + portable_mutex_lock(&LP_inusemutex); + if ( (lp= _LP_inuse_find(txid,vout)) != 0 ) + { + if ( lp->expiration != 0 && now < lp->expiration ) + duration = (lp->expiration - now); + } + portable_mutex_unlock(&LP_inusemutex); + return(duration); +} + +void LP_unavailableset(bits256 txid,int32_t vout,uint32_t expiration,bits256 otherpub) +{ + portable_mutex_lock(&LP_inusemutex); + _LP_inuse_add(expiration,otherpub,txid,vout); + portable_mutex_unlock(&LP_inusemutex); +} + +void LP_availableset(bits256 txid,int32_t vout) +{ + portable_mutex_lock(&LP_inusemutex); + _LP_inuse_delete(txid,vout); + portable_mutex_unlock(&LP_inusemutex); +} + +int32_t LP_maxvalue(uint64_t *values,int32_t n) +{ + int32_t i,maxi = -1; uint64_t maxval = 0; + for (i=0; i maxval ) + { + maxi = i; + maxval = values[i]; + } + return(maxi); +} + +int32_t LP_nearestvalue(int32_t iambob,uint64_t *values,int32_t n,uint64_t targetval) +{ + int32_t i,mini = -1; int64_t dist; uint64_t mindist = (1 << 31); + for (i=0; i= 0 && dist < mindist ) + { + mini = i; + mindist = dist; + } + } + return(mini); +} + +uint64_t LP_value_extract(cJSON *obj,int32_t addinterest) +{ + double val = 0.; uint64_t value = 0; int32_t electrumflag; + electrumflag = (jobj(obj,"tx_hash") != 0); + if ( electrumflag == 0 ) + { + if ( (val= jdouble(obj,"amount")) < SMALLVAL ) + val = jdouble(obj,"value"); + value = (val + 0.0000000049) * SATOSHIDEN; + } else value = j64bits(obj,"value"); + if ( value != 0 ) + { + if ( addinterest != 0 && jobj(obj,"interest") != 0 ) + value += (jdouble(obj,"interest") * SATOSHIDEN); + } + return(value); +} + +int32_t LP_destaddr(char *destaddr,cJSON *item) +{ + int32_t m,retval = -1; cJSON *addresses,*skey; char *addr; + if ( (skey= jobj(item,"scriptPubKey")) != 0 && (addresses= jarray(&m,skey,"addresses")) != 0 ) + { + item = jitem(addresses,0); + if ( (addr= jstr(item,0)) != 0 ) + { + safecopy(destaddr,addr,64); + retval = 0; + } + //printf("item.(%s) -> dest.(%s)\n",jprint(item,0),destaddr); + } + return(retval); +} + +int32_t LP_txdestaddr(char *destaddr,bits256 txid,int32_t vout,cJSON *txobj) +{ + int32_t n,retval = -1; cJSON *vouts; + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) + retval = LP_destaddr(destaddr,jitem(vouts,vout)); + return(retval); +} + +struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap = 0; + if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 ) + { + ap = _LP_addressadd(coin,coinaddr); + //printf("LP_address %s %s\n",coin->symbol,coinaddr); + } + return(ap); +} + +struct LP_address *LP_addressfind(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap = 0; + if ( coin != 0 ) + { + portable_mutex_lock(&coin->addrmutex); + ap = _LP_addressfind(coin,coinaddr); + portable_mutex_unlock(&coin->addrmutex); + } + return(ap); +} + +struct LP_address *LP_address(struct iguana_info *coin,char *coinaddr) +{ + struct LP_address *ap = 0; + if ( coin != 0 ) + { + portable_mutex_lock(&coin->addrmutex); + ap = _LP_address(coin,coinaddr); + portable_mutex_unlock(&coin->addrmutex); + } + return(ap); +} + +int32_t LP_address_minmax(uint64_t *balancep,uint64_t *minp,uint64_t *maxp,struct iguana_info *coin,char *coinaddr) +{ + cJSON *array,*item; bits256 txid,zero; int64_t value; int32_t i,vout,height,n = 0; + *minp = *maxp = *balancep = 0; + memset(zero.bytes,0,sizeof(zero)); + if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 ) + { + //printf("address minmax.(%s)\n",jprint(array,0)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i *maxp ) + *maxp = value; + if ( *minp == 0 || value < *minp ) + *minp = value; + *balancep += value; + } + } + free_json(array); + } + return(n); +} + +int32_t LP_address_utxo_ptrs(struct iguana_info *coin,int32_t iambob,struct LP_address_utxo **utxos,int32_t max,struct LP_address *ap,char *coinaddr) +{ + struct LP_address_utxo *up,*tmp; struct LP_transaction *tx; cJSON *txout; int32_t n = 0; + if ( strcmp(ap->coinaddr,coinaddr) != 0 ) + printf("UNEXPECTED coinaddr mismatch (%s) != (%s)\n",ap->coinaddr,coinaddr); + //portable_mutex_lock(&LP_utxomutex); + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + //char str[65]; printf("LP_address_utxo_ptrs %s n.%d %.8f %s v%d spendheight.%d allocated.%d\n",ap->coinaddr,n,dstr(up->U.value),bits256_str(str,up->U.txid),up->U.vout,up->spendheight,LP_allocated(up->U.txid,up->U.vout)); + if ( up->spendheight <= 0 && LP_RTmetrics_avoidtxid(up->U.txid) < 0 ) + { + if ( coin->electrum == 0 ) + { + if ( (txout= LP_gettxout(coin->symbol,coinaddr,up->U.txid,up->U.vout)) != 0 ) + { + if ( LP_value_extract(txout,0) == 0 ) + { + //printf("LP_address_utxo_ptrs skip zero value %s/v%d\n",bits256_str(str,up->U.txid),up->U.vout); + free_json(txout); + up->spendheight = 1; + if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) + tx->outpoints[up->U.vout].spendheight = 1; + continue; + } + free_json(txout); + } + else + { + //printf("LP_address_utxo_ptrs skips %s %s payment %s/v%d is spent\n",coin->symbol,coinaddr,bits256_str(str,up->U.txid),up->U.vout); + up->spendheight = 1; + if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) + tx->outpoints[up->U.vout].spendheight = 1; + continue; + } + } + else + { + if ( up->SPV < 0 || up->U.height == 0 ) + { +//printf("LP_address_utxo_ptrs skips %s/v%u due to SPV.%d ht.%d\n",bits256_str(str,up->U.txid),up->U.vout,up->SPV,up->U.height); + if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) + tx->outpoints[up->U.vout].spendheight = 1; + continue; + } + } + if ( LP_allocated(up->U.txid,up->U.vout) == 0 ) + { + utxos[n++] = up; + if ( n >= max ) + break; + } //else printf("LP_allocated skip %u\n",LP_allocated(up->U.txid,up->U.vout)); + } + else + { + if ( (tx= LP_transactionfind(coin,up->U.txid)) != 0 && up->U.vout < tx->numvouts ) + tx->outpoints[up->U.vout].spendheight = 1; + } + } + //portable_mutex_unlock(&LP_utxomutex); + //printf("return n.%d for %s %s\n",n,coin->symbol,coinaddr); + return(n); +} + +struct LP_address_utxo *LP_address_utxofind(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout) +{ + struct LP_address *ap; struct LP_address_utxo *up,*tmp; + //printf("LP_address_utxofind %s add addr.%s\n",coin->symbol,coinaddr); + if ( (ap= _LP_address(coin,coinaddr)) != 0 ) + { + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( vout == up->U.vout && bits256_cmp(up->U.txid,txid) == 0 ) + return(up); + } + } + return(0); +} + +void LP_mark_spent(char *symbol,bits256 txid,int32_t vout) +{ + struct iguana_info *coin; struct LP_transaction *tx; struct LP_address_utxo *up; + if ( (coin= LP_coinfind(symbol)) != 0 ) + { + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + { + if ( vout < tx->numvouts ) + { + tx->outpoints[vout].spendheight = 1; + if ( (up= LP_address_utxofind(coin,tx->outpoints[vout].coinaddr,txid,vout)) != 0 ) + up->spendheight = 1; + } + } + } +} + +int32_t LP_address_utxoadd(int32_t skipsearch,uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight) +{ + struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65]; + if ( coin == 0 ) + return(0); + if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about + ap = LP_addressfind(coin,coinaddr); + else ap = LP_address(coin,coinaddr); + //printf("%s add addr.%s ht.%d ap.%p\n",coin->symbol,coinaddr,height,ap); + if ( ap != 0 ) + { + flag = 0; + if ( skipsearch == 0 ) + { + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( vout == up->U.vout && bits256_cmp(up->U.txid,txid) == 0 ) + { + flag = 1; + if ( height > 0 && up->U.height != height ) + up->U.height = height, flag |= 2; + if ( spendheight > 0 && up->spendheight != spendheight ) + up->spendheight = spendheight, flag |= 4; + if ( value != 0 && up->U.value == 0 && up->U.value != value ) + up->U.value = value, flag |= 8; + //up->timestamp = timestamp; + //char str[65]; printf("found >>>>>>>>>> %s %s %s/v%d ht.%d %.8f\n",coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); + break; + } + } + } + if ( flag == 0 && value != 0 ) + { + if ( coin->electrum == 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) == 0 ) + { + //char str[65]; printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout); + return(0); + } else free_json(txobj); + } + up = calloc(1,sizeof(*up)); + up->U.txid = txid; + up->U.vout = vout; + up->U.height = height; + up->U.value = value; + up->spendheight = spendheight; + //up->timestamp = timestamp; + retval = 1; + if ( (tx= LP_transactionfind(coin,txid)) != 0 && tx->SPV > 0 ) + { + up->SPV = tx->SPV; + } + char str[65]; + if ( 0 && strcmp(coin->smartaddr,coinaddr) == 0 && strcmp("KMD",coin->symbol) == 0 ) + printf("%s ADD UTXO >> %s %s %s/v%d ht.%d %.8f\n",debug,coin->symbol,coinaddr,bits256_str(str,txid),vout,height,dstr(value)); + portable_mutex_lock(&coin->addrmutex); + DL_APPEND(ap->utxos,up); + portable_mutex_unlock(&coin->addrmutex); + } + } // else printf("cant get ap %s %s\n",coin->symbol,coinaddr); + //printf("done %s add addr.%s ht.%d\n",coin->symbol,coinaddr,height); + return(retval); +} + +struct LP_address *LP_address_utxo_reset(struct iguana_info *coin) +{ + struct LP_address *ap; struct LP_address_utxo *up,*tmp; int32_t i,n,m,vout,height; cJSON *array,*item,*txobj; bits256 zero; int64_t value; bits256 txid; uint32_t now; + LP_address(coin,coin->smartaddr); + memset(zero.bytes,0,sizeof(zero)); + LP_listunspent_issue(coin->symbol,coin->smartaddr,2,zero,zero); + if ( (ap= LP_addressfind(coin,coin->smartaddr)) == 0 ) + { + printf("LP_address_utxo_reset: cant find address data\n"); + return(0); + } + if ( IAMLP != 0 && time(NULL) < coin->lastresetutxo+10 ) + return(ap); + coin->lastresetutxo = (uint32_t)time(NULL); + portable_mutex_lock(&coin->addressutxo_mutex); + if ( (array= LP_listunspent(coin->symbol,coin->smartaddr,zero,zero)) != 0 ) + { + printf("reset %s ap->utxos\n",coin->symbol); + portable_mutex_lock(&coin->addrmutex); + portable_mutex_lock(&LP_gcmutex); + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + DL_DELETE(ap->utxos,up); + up->spendheight = (int32_t)time(NULL); + DL_APPEND(LP_garbage_collector2,up); + } + portable_mutex_unlock(&coin->addrmutex); + portable_mutex_unlock(&LP_gcmutex); + now = (uint32_t)time(NULL); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + char str[65]; + for (i=m=0; isymbol,coin->smartaddr,txid,vout)) == 0 ) + continue; + else free_json(txobj); + if ( LP_numconfirms(coin->symbol,coin->smartaddr,txid,vout,0) <= 0 ) + continue; + } + LP_address_utxoadd(1,now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1); + if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 ) + printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value)); + else + { + m++; + //printf("%.8f ",dstr(value)); + } + } + printf("added %d from %s listunspents\n",m,coin->symbol); + } + free_json(array); + } + portable_mutex_unlock(&coin->addressutxo_mutex); + return(ap); +} + +cJSON *LP_address_item(struct iguana_info *coin,struct LP_address_utxo *up,int32_t electrumret) +{ + int32_t notarized; cJSON *item = cJSON_CreateObject(); + if ( electrumret == 0 ) + { + jaddbits256(item,"txid",up->U.txid); + jaddnum(item,"vout",up->U.vout); + if ( up->U.height > 0 ) + jaddnum(item,"confirmations",LP_getheight(¬arized,coin) - up->U.height + 1); + jaddnum(item,"amount",dstr(up->U.value)); + jaddstr(item,"scriptPubKey",""); + } + else + { + jaddbits256(item,"tx_hash",up->U.txid); + jaddnum(item,"tx_pos",up->U.vout); + jaddnum(item,"height",up->U.height); + jadd64bits(item,"value",up->U.value); + if ( up->U.value == 0 ) + printf("ERROR LP_address_item illegal.(%s)\n",jprint(item,0)); + } + return(item); +} + +uint64_t _LP_unspents_metric(uint64_t total,int32_t n) { return((total<<16) | (n & 0xffff)); } + +cJSON *LP_address_utxos(struct iguana_info *coin,char *coinaddr,int32_t electrumret) +{ + cJSON *array,*item; int32_t n; uint64_t total; struct LP_address *ap=0,*atmp; struct LP_address_utxo *up,*tmp; cJSON *txobj; + array = cJSON_CreateArray(); + if ( coinaddr != 0 && coinaddr[0] != 0 ) + { + //portable_mutex_lock(&coin->addrmutex); + if ( (ap= _LP_addressfind(coin,coinaddr)) != 0 ) + { + total = n = 0; + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->spendheight <= 0 && up->U.height > 0 ) + { + if ( coin->electrum == 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,coinaddr,up->U.txid,up->U.vout)) == 0 ) + up->spendheight = 1; + else free_json(txobj); + } + if ( up->spendheight <= 0 && up->U.value != 0 ) + { + if ( LP_allocated(up->U.txid,up->U.vout) != 0 ) + { + //printf("%s %s/v%d allocated\n",coin->symbol,bits256_str(str,up->U.txid),up->U.vout); + } + else if ( coin->electrum == 0 || up->SPV > 0 ) + { + jaddi(array,LP_address_item(coin,up,electrumret)); + n++; + total += up->U.value; + } + } + //printf("new array %s\n",jprint(array,0)); + } + } + ap->total = total; + ap->n = n; + } + //portable_mutex_unlock(&coin->addrmutex); + } + else + { + HASH_ITER(hh,coin->addresses,ap,atmp) + { + if ( ap->total > 0 && ap->n > 0 ) + { + item = cJSON_CreateObject(); + jadd64bits(item,ap->coinaddr,_LP_unspents_metric(ap->total,ap->n)); + jaddi(array,item); + } + } + } + //printf("%s %s utxos.(%s) ap.%p\n",coin->symbol,coinaddr,jprint(array,0),ap); + return(array); +} + +cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electrumret) +{ + cJSON *array,*retjson,*item; bits256 zero; int32_t i,n; uint64_t balance = 0; + memset(zero.bytes,0,sizeof(zero)); + if ( coin->electrum == 0 ) + { + if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ismartaddr,coinaddr) != 0 ) + { + if ( (retjson= electrum_address_listunspent(coin->symbol,coin->electrum,&retjson,coinaddr,2,zero,zero)) != 0 ) + free_json(retjson); + } + balance = LP_unspents_load(coin->symbol,coinaddr); + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"coin",coin->symbol); + jaddstr(retjson,"address",coinaddr); + jaddnum(retjson,"balance",dstr(balance)); + if ( strcmp(coin->symbol,"KMD") == 0 && strcmp(coin->smartaddr,coinaddr) == 0 ) + { + jaddnum(retjson,"zcredits",dstr(LP_myzcredits())); + jadd(retjson,"zdebits",LP_myzdebits()); + } + return(retjson); +} + +cJSON *LP_balances(char *coinaddr) +{ + struct iguana_info *coin,*tmp; char address[64]; uint8_t taddr,addrtype,rmd160[20]; uint64_t balance,KMDvalue,sum = 0; cJSON *array,*item,*retjson; + if ( coinaddr != 0 && coinaddr[0] == 't' && (coinaddr[1] == '1' || coinaddr[1] == '3') ) + taddr = 1; + else taddr = 0; + array = cJSON_CreateArray(); + HASH_ITER(hh,LP_coins,coin,tmp) + { + if ( coin->electrum != 0 || (coinaddr != 0 && coinaddr[0] != 0 && strcmp(coinaddr,coin->smartaddr) != 0) ) + { + if ( coinaddr == 0 || coinaddr[0] == 0 ) + strcpy(address,coin->smartaddr); + else + { + bitcoin_addr2rmd160("KMD",taddr,&addrtype,rmd160,coinaddr); + bitcoin_address(coin->symbol,address,coin->taddr,coin->pubtype,rmd160,20); + //printf("%s taddr.%d addrtype.%u %s -> %s [%c %c].%d\n",coin->symbol,taddr,addrtype,coinaddr,address,coinaddr[0],coinaddr[1],coinaddr[0] == 't' && (coinaddr[1] == '1' || coinaddr[1] == '3')); + } + if ( (retjson= LP_address_balance(coin,address,1)) != 0 ) + { + if ( (balance= jdouble(retjson,"balance")*SATOSHIDEN) > 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddnum(item,"balance",dstr(balance)); + if ( (KMDvalue= LP_KMDvalue(coin,balance)) != 0 ) + { + jaddnum(item,"KMDvalue",dstr(KMDvalue)); + sum += KMDvalue; + } + if ( coin->electrum != 0 && strcmp(address,coin->smartaddr) == 0 && strcmp(coin->symbol,"KMD") == 0 ) + { + jaddnum(item,"zcredits",dstr(LP_myzcredits())); + //jadd(item,"zdebits",LP_myzdebits()); + } + jaddi(array,item); + } + free_json(retjson); + } + } + else + { + if ( (balance= LP_RTsmartbalance(coin)) != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jaddnum(item,"balance",dstr(balance)); + if ( (KMDvalue= LP_KMDvalue(coin,balance)) != 0 ) + { + jaddnum(item,"KMDvalue",dstr(KMDvalue)); + sum += KMDvalue; + } + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + jaddnum(item,"zcredits",dstr(LP_myzcredits())); + //jadd(item,"zdebits",LP_myzdebits()); + } + jaddi(array,item); + } + } + } + if ( sum != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"coin","total"); + jaddnum(item,"balance",dstr(sum)); + jaddi(array,item); + } + return(array); +} + +int32_t LP_unspents_array(struct iguana_info *coin,char *coinaddr,cJSON *array) +{ + int32_t i,n,v,errs,height,count=0; uint64_t value,val; cJSON *item,*txobj; bits256 txid; + if ( (n= cJSON_GetArraySize(array)) <= 0 ) + return(0); + //printf("%s %s LP_unspents.(%s)\n",coin->symbol,coinaddr,jprint(array,0)); + for (i=0; ielectrum == 0 && (txobj= LP_gettxout(coin->symbol,coinaddr,txid,v)) != 0 ) + { + value = LP_value_extract(txobj,0); + if ( value != 0 && value != val ) + { + char str[65]; printf("REJECT %s %s/v%d value.%llu vs %llu (%s)\n",coin->symbol,bits256_str(str,txid),v,(long long)value,(long long)val,jprint(txobj,0)); + errs++; + } + //ht = LP_txheight(coin,txid); + //if ( coin->height != 0 ) + // ht = LP_getheight(coin) - jint(txobj,"confirmations") + 1; + //else ht = 0; + /*if ( ht != 0 && ht < height-2 ) + { + printf("REJECT %s %s/v%d ht.%d vs %d confs.%d (%s)\n",symbol,bits256_str(str,txid),v,ht,height,jint(txobj,"confirmations"),jprint(item,0)); + errs++; + }*/ + free_json(txobj); + } + if ( errs == 0 ) + { + //printf("from LP_unspents_array\n"); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_unspents_array",coin,coinaddr,txid,v,val,height,-1); + count++; + } + } + return(count); +} + +struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid) +{ + struct LP_transaction *tx; + portable_mutex_lock(&coin->txmutex); + HASH_FIND(hh,coin->transactions,txid.bytes,sizeof(txid),tx); + portable_mutex_unlock(&coin->txmutex); + return(tx); +} + +struct LP_transaction *LP_transactionadd(struct iguana_info *coin,bits256 txid,int32_t height,int32_t numvouts,int32_t numvins) +{ + static long totalsize; + struct LP_transaction *tx; int32_t i; //char str[65]; + if ( (tx= LP_transactionfind(coin,txid)) == 0 ) + { + //if ( bits256_nonz(txid) == 0 && tx->height == 0 ) + // getchar(); + tx = calloc(1,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts)); + totalsize += sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts); + //char str[65]; printf("%s ht.%d NEW TXID.(%s) vouts.[%d] size.%ld total %ld\n",coin->symbol,height,bits256_str(str,txid),numvouts,sizeof(*tx) + (sizeof(*tx->outpoints) * numvouts),totalsize); + for (i=0; ioutpoints[i].spendvini = -1; + tx->height = height; + tx->numvouts = numvouts; + tx->numvins = numvins; + //tx->timestamp = timestamp; + tx->txid = txid; + portable_mutex_lock(&coin->txmutex); + HASH_ADD_KEYPTR(hh,coin->transactions,tx->txid.bytes,sizeof(tx->txid),tx); + portable_mutex_unlock(&coin->txmutex); + } //else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid)); + return(tx); +} + +cJSON *LP_transactioninit(struct iguana_info *coin,bits256 txid,int32_t iter,cJSON *txobj) +{ + struct LP_transaction *tx; int32_t i,height,numvouts,numvins,spentvout; cJSON *vins,*vouts,*vout,*vin; bits256 spenttxid; char str[65]; + if ( coin->inactive != 0 ) + return(0); + if ( txobj != 0 || (txobj= LP_gettx(coin->symbol,txid,0)) != 0 ) + { + if ( coin->electrum == 0 ) + height = LP_txheight(coin,txid); + else height = -1; + vins = jarray(&numvins,txobj,"vin"); + vouts = jarray(&numvouts,txobj,"vout"); + // maybe filter so only addresses we care about are using RAM + if ( iter == 0 && vouts != 0 && (tx= LP_transactionadd(coin,txid,height,numvouts,numvins)) != 0 ) + { + //printf("create txid %s numvouts.%d numvins.%d\n",bits256_str(str,txid),numvouts,numvins); + for (i=0; ioutpoints[i].value = LP_value_extract(vout,0); + tx->outpoints[i].interest = SATOSHIDEN * jdouble(vout,"interest"); + LP_destaddr(tx->outpoints[i].coinaddr,vout); + //printf("from transaction init %s %s %s/v%d <- %.8f\n",coin->symbol,tx->outpoints[i].coinaddr,bits256_str(str,txid),i,dstr(tx->outpoints[i].value)); + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_transactioninit iter0",coin,tx->outpoints[i].coinaddr,txid,i,tx->outpoints[i].value,height,-1); + } + //printf("numvouts.%d\n",numvouts); + } + if ( iter == 1 && vins != 0 ) + { + for (i=0; inumvouts ) + { + if ( tx->outpoints[spentvout].spendheight <= 0 ) + { + tx->outpoints[spentvout].spendtxid = txid; + tx->outpoints[spentvout].spendvini = i; + tx->outpoints[spentvout].spendheight = height > 0 ? height : 1; + LP_address_utxoadd(0,(uint32_t)time(NULL),"LP_transactioninit iter1",coin,tx->outpoints[spentvout].coinaddr,spenttxid,spentvout,tx->outpoints[spentvout].value,-1,height>0?height:1); + if ( 0 && strcmp(coin->symbol,"REVS") == 0 ) + printf("spend %s %s/v%d at ht.%d\n",coin->symbol,bits256_str(str,tx->txid),spentvout,height); + } + } else printf("LP_transactioninit: %s spentvout.%d < numvouts.%d spendheight.%d\n",bits256_str(str,spenttxid),spentvout,tx->numvouts,tx->outpoints[spentvout].spendheight); + } //else printf("LP_transactioninit: couldnt find (%s) ht.%d %s\n",bits256_str(str,spenttxid),height,jprint(vin,0)); + if ( bits256_cmp(spenttxid,txid) == 0 ) + printf("spending same tx's %p vout ht.%d %s.[%d] s%d\n",tx,height,bits256_str(str,txid),tx!=0?tx->numvouts:0,spentvout); + } + } + return(txobj); + } //else printf("LP_transactioninit error for %s %s\n",coin->symbol,bits256_str(str,txid)); + return(0); +} + +int32_t LP_txheight(struct iguana_info *coin,bits256 txid) +{ + bits256 blockhash; struct LP_transaction *tx; cJSON *blockobj,*retjson,*txobj; int32_t height = 0; + if ( coin == 0 ) + return(-1); + if ( coin->electrum == 0 ) + { + if ( (txobj= LP_gettx(coin->symbol,txid,0)) != 0 ) + { + //*timestampp = juint(txobj,"locktime"); + //*blocktimep = juint(txobj,"blocktime"); + blockhash = jbits256(txobj,"blockhash"); + if ( bits256_nonz(blockhash) != 0 && (blockobj= LP_getblock(coin->symbol,blockhash)) != 0 ) + { + height = jint(blockobj,"height"); + //char str[65]; + //if ( strcmp(coin->symbol,"CHIPS") != 0 && strcmp(coin->symbol,"BTC") != 0 ) + // printf("%s %s LP_txheight.%d\n",coin->symbol,bits256_str(str,txid),height); + free_json(blockobj); + } // else printf("%s LP_txheight error (%s)\n",coin->symbol,jprint(txobj,0)); likely just unconfirmed + free_json(txobj); + } + } + else + { + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + height = tx->height; + if ( height == 0 ) + { + if ( (retjson= electrum_transaction(&height,coin->symbol,coin->electrum,&retjson,txid,0)) != 0 ) + { + //printf("process %s\n",jprint(retjson,0)); + free_json(retjson); + } + if ( (tx= LP_transactionfind(coin,txid)) != 0 ) + height = tx->height; + } + } + return(height); +} + +int32_t LP_numconfirms(char *symbol,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool) +{ + struct iguana_info *coin; bits256 zero; int32_t ht,notarized,numconfirms = 100; + cJSON *txobj; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(-1); + if ( coin->electrum == 0 ) + { + numconfirms = -1; + if ( (txobj= LP_gettxout(symbol,coinaddr,txid,vout)) != 0 ) + { + numconfirms = jint(txobj,"confirmations"); + free_json(txobj); + } + else if ( mempool != 0 && LP_mempoolscan(symbol,txid) >= 0 ) + numconfirms = 0; + else if ( (txobj= LP_gettx(symbol,txid,1)) != 0 ) + { + numconfirms = jint(txobj,"confirmations"); + free_json(txobj); + } + } + else + { + memset(zero.bytes,0,sizeof(zero)); + LP_listunspent_issue(symbol,coinaddr,1,txid,zero); + if ( (ht= LP_txheight(coin,txid)) > 0 && ht <= coin->height ) + numconfirms = (LP_getheight(¬arized,coin) - ht + 1); + else if ( mempool != 0 ) + { + if ( LP_waitmempool(symbol,coinaddr,txid,vout,30) >= 0 ) + numconfirms = 0; + } + } + return(numconfirms); +} + +uint64_t LP_txinterestvalue(uint64_t *interestp,char *destaddr,struct iguana_info *coin,bits256 txid,int32_t vout) +{ + uint64_t interest,value = 0; cJSON *txobj; + *interestp = 0; + destaddr[0] = 0; + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) != 0 ) + { + if ( (value= LP_value_extract(txobj,0)) == 0 ) + { + char str[65]; printf("%s LP_txvalue.%s strange utxo.(%s) vout.%d\n",coin->symbol,bits256_str(str,txid),jprint(txobj,0),vout); + } + else if ( strcmp(coin->symbol,"KMD") == 0 ) + { + if ( coin->electrum == 0 ) + { + if ((interest= jdouble(txobj,"interest")) != 0. ) + { + //printf("add interest of %.8f to %.8f\n",interest,dstr(value)); + *interestp = SATOSHIDEN * interest; + } + } else *interestp = LP_komodo_interest(txid,value); + } + LP_destaddr(destaddr,txobj); + //char str[65]; printf("dest.(%s) %.8f <- %s.(%s) txobj.(%s)\n",destaddr,dstr(value),coin->symbol,bits256_str(str,txid),jprint(txobj,0)); + free_json(txobj); + } //else { char str[65]; printf("null gettxout return %s/v%d\n",bits256_str(str,txid),vout); } + return(value); +} + +int64_t basilisk_txvalue(char *symbol,bits256 txid,int32_t vout) +{ + char destaddr[64]; uint64_t value,interest = 0; struct iguana_info *coin; + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(0); + //char str[65]; printf("%s txvalue.(%s)\n",symbol,bits256_str(str,txid)); + value = LP_txinterestvalue(&interest,destaddr,coin,txid,vout); + return(value + interest); +} + +uint64_t LP_txvalue(char *coinaddr,char *symbol,bits256 txid,int32_t vout) +{ + struct LP_transaction *tx; cJSON *txobj=0; struct iguana_info *coin; + if ( bits256_nonz(txid) == 0 ) + return(0); + if ( (coin= LP_coinfind(symbol)) == 0 || coin->inactive != 0 ) + return(0); + if ( coinaddr != 0 ) + coinaddr[0] = 0; + if ( (tx= LP_transactionfind(coin,txid)) == 0 ) + { + txobj = LP_transactioninit(coin,txid,0,0); + txobj = LP_transactioninit(coin,txid,1,txobj); + if ( txobj != 0 ) + free_json(txobj); + tx = LP_transactionfind(coin,txid); + } + if ( tx != 0 ) + { + if ( vout < tx->numvouts ) + { + /*if ( bits256_nonz(tx->outpoints[vout].spendtxid) != 0 ) + { + //printf("LP_txvalue %s/v%d is spent at %s\n",bits256_str(str,txid),vout,bits256_str(str2,tx->outpoints[vout].spendtxid)); + return(0); + } + else + { + if ( coinaddr != 0 ) + { + //if ( tx->outpoints[vout].coinaddr[0] == 0 ) + // tx->outpoints[vout].value = LP_txinterestvalue(&tx->outpoints[vout].interest,tx->outpoints[vout].coinaddr,coin,txid,vout); + strcpy(coinaddr,tx->outpoints[vout].coinaddr); + //printf("(%s) return value %.8f + interest %.8f\n",coinaddr,dstr(tx->outpoints[vout].value),dstr(tx->outpoints[vout].interest)); + } + return(tx->outpoints[vout].value + 0*tx->outpoints[vout].interest); + }*/ + return(tx->outpoints[vout].value); + } else printf("LP_txvalue vout.%d >= tx->numvouts.%d\n",vout,tx->numvouts); + } + else if ( coin->electrum == 0 ) + { + uint64_t value; + if ( (txobj= LP_gettxout(coin->symbol,coinaddr,txid,vout)) != 0 ) + { + value = LP_value_extract(txobj,0);//SATOSHIDEN * (jdouble(txobj,"value") + jdouble(txobj,"interest")); + if ( coinaddr != 0 ) + LP_destaddr(coinaddr,txobj); + //printf("pruned node? LP_txvalue couldnt find %s tx %s, but gettxout %.8f\n",coin->symbol,bits256_str(str,txid),dstr(value)); + if ( value != 0 ) + { + free_json(txobj); + return(value); + } + } + //printf("pruned node? LP_txvalue couldnt find %s tx %s/v%d (%s)\n",coin->symbol,bits256_str(str,txid),vout,txobj!=0?jprint(txobj,0):""); + if ( txobj != 0 ) + free_json(txobj); + } + return(0); +} + +int64_t LP_outpoint_amount(char *symbol,bits256 txid,int32_t vout) +{ + int64_t amount=0; int32_t numvouts; char coinaddr[64]; cJSON *vouts,*txjson; + if ( (amount= LP_txvalue(coinaddr,symbol,txid,vout)) != 0 ) + return(amount); + else + { + if ( (txjson= LP_gettx(symbol,txid,1)) != 0 ) + { + if ( (vouts= jarray(&numvouts,txjson,"vout")) != 0 && vout < numvouts ) + amount = LP_value_extract(jitem(vouts,vout),0); + free_json(txjson); + } + } + return(amount); +} + +int32_t LP_iseligible(uint64_t *valp,uint64_t *val2p,int32_t iambob,char *symbol,bits256 txid,int32_t vout,uint64_t satoshis,bits256 txid2,int32_t vout2) +{ + uint64_t val,val2=0,txfee,threshold=0; cJSON *txobj; int32_t bypass = 0; char destaddr[64],destaddr2[64]; struct iguana_info *coin = LP_coinfind(symbol); + if ( bits256_nonz(txid) == 0 || bits256_nonz(txid2) == 0 ) + { + printf("null txid not eligible\n"); + return(-1); + } + destaddr[0] = destaddr2[0] = 0; + if ( coin != 0 && IAMLP != 0 && coin->inactive != 0 ) + bypass = 1; + if ( bypass != 0 ) + val = satoshis; + else val = LP_txvalue(destaddr,symbol,txid,vout); + txfee = LP_txfeecalc(LP_coinfind(symbol),0,0); + if ( val >= satoshis && val > (1+LP_MINSIZE_TXFEEMULT)*txfee ) + { + threshold = (iambob != 0) ? LP_DEPOSITSATOSHIS(satoshis) : (LP_DEXFEE(satoshis) + txfee); + if ( bypass != 0 ) + val2 = threshold; + else val2 = LP_txvalue(destaddr2,symbol,txid2,vout2); + if ( val2 >= threshold ) + { + if ( bypass == 0 && strcmp(destaddr,destaddr2) != 0 ) + printf("mismatched %s destaddr (%s) vs (%s)\n",symbol,destaddr,destaddr2); + else + { + *valp = val; + *val2p = val2; + if ( destaddr[0] == 0 ) + strcpy(destaddr,destaddr2); + if ( coin != 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid,vout)) == 0 ) + return(0); + else free_json(txobj); + if ( (txobj= LP_gettxout(coin->symbol,destaddr,txid2,vout2)) == 0 ) + return(0); + else free_json(txobj); + if ( LP_numconfirms(coin->symbol,destaddr,txid,vout,0) <= 0 ) + return(0); + if ( LP_numconfirms(coin->symbol,destaddr,txid2,vout2,0) <= 0 ) + return(0); + } + return(1); + } + } else printf("no val2 %.8f < threshold %.8f\n",dstr(val),dstr(threshold)); + } + /*char str2[65]; + if ( val != 0 && val2 != 0 ) + printf("spent.%d %s txid or value %.8f < %.8f or val2 %.8f < %.8f, %s/v%d %s/v%d or < 10x txfee %.8f\n",iambob,symbol,dstr(val),dstr(satoshis),dstr(val2),dstr(threshold),bits256_str(str,txid),vout,bits256_str(str2,txid2),vout2,dstr(txfee)); + if ( val == 0 ) + LP_address_utxoadd(coin,destaddr,txid,vout,satoshis,-1,1); + if ( val2 == 0 ) + LP_address_utxoadd(coin,destaddr,txid2,vout2,threshold,-1,1); + for (iter=0; iter<2; iter++) + { + if ( (utxo= LP_utxofind(iter,txid,vout)) != 0 ) + { + //printf("iambob.%d case 00\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxo2find(iter,txid,vout)) != 0 ) + { + //printf("iambob.%d case 01\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxofind(iter,txid2,vout2)) != 0 ) + { + //printf("iambob.%d case 10\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + if ( (utxo= LP_utxo2find(iter,txid2,vout2)) != 0 ) + { + //printf("iambob.%d case 11\n",iter); + if ( utxo->T.spentflag == 0 ) + utxo->T.spentflag = (uint32_t)time(NULL); + } + }*/ + *valp = val; + *val2p = val2; + return(0); +} + +int32_t LP_inventory_prevent(int32_t iambob,char *symbol,bits256 txid,int32_t vout) +{ + struct LP_address_utxo *up; struct iguana_info *coin; //struct LP_utxoinfo *utxo; struct LP_transaction *tx; + if ( (coin= LP_coinfind(symbol)) == 0 ) + return(1); + if ( LP_allocated(txid,vout) != 0 ) + return(1); + /*if ( (utxo= LP_utxofind(iambob,txid,vout)) != 0 || (utxo= LP_utxo2find(iambob,txid,vout)) != 0 ) + { + if ( coin != 0 && (tx= LP_transactionfind(coin,txid)) != 0 ) + { + if ( tx->outpoints[vout].spendheight > 0 ) + utxo->T.spentflag = tx->outpoints[vout].spendheight; + else utxo->T.spentflag = 0; + } + if ( utxo->T.spentflag != 0 ) + { + //char str[65]; printf("prevent adding iambob.%d %s/v%d to inventory\n",iambob,bits256_str(str,txid),vout); + return(1); + } + }*/ + if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) != 0 && up->spendheight > 0 ) + return(1); + return(0); +} + +cJSON *LP_dustcombine_item(struct LP_address_utxo *up) +{ + cJSON *item = cJSON_CreateObject(); + jaddbits256(item,"txid",up->U.txid); + jaddnum(item,"vout",up->U.vout); + return(item); +} + +uint64_t LP_dustcombine(struct LP_address_utxo *ups[2],int32_t dustcombine,struct iguana_info *coin) +{ + struct LP_address *ap=0; struct LP_address_utxo *up,*tmp,*min0,*min1; cJSON *txobj; + if ( coin == 0 || coin->electrum != 0 || dustcombine <= 0 || dustcombine > 2 ) + return(0); + min1 = min0 = 0; + ups[0] = ups[1] = 0; + if ( (ap= _LP_addressfind(coin,coin->smartaddr)) != 0 ) + { + DL_FOREACH_SAFE(ap->utxos,up,tmp) + { + if ( up->spendheight <= 0 && up->U.height > 0 && up->U.value != 0 ) + { + if ( (txobj= LP_gettxout(coin->symbol,coin->smartaddr,up->U.txid,up->U.vout)) == 0 ) + up->spendheight = 1; + else + { + free_json(txobj); + if ( LP_inventory_prevent(1,coin->symbol,up->U.txid,up->U.vout) == 0 ) + { + if ( min1 == 0 || up->U.value < min1->U.value ) + { + if ( min0 == 0 || up->U.value < min0->U.value ) + { + min1 = min0; + min0 = up; + } else min1 = up; + } + } + } + } + } + } + if ( min0 != 0 ) + { + ups[0] = min0; + if ( dustcombine == 2 && min1 != 0 ) + { + ups[1] = min1; + return(min0->U.value + min1->U.value); + } else return(min0->U.value); + } + return(0); +} + +int32_t LP_undospends(struct iguana_info *coin,int32_t lastheight) +{ + int32_t i,ht,num = 0; struct LP_transaction *tx,*tmp; + HASH_ITER(hh,coin->transactions,tx,tmp) + { + for (i=0; inumvouts; i++) + { + if ( bits256_nonz(tx->outpoints[i].spendtxid) == 0 ) + continue; + if ( (ht= tx->outpoints[i].spendheight) == 0 ) + { + tx->outpoints[i].spendheight = LP_txheight(coin,tx->outpoints[i].spendtxid); + } + if ( (ht= tx->outpoints[i].spendheight) != 0 && ht > lastheight ) + { + char str[65]; printf("clear spend %s/v%d at ht.%d > lastheight.%d\n",bits256_str(str,tx->txid),i,ht,lastheight); + tx->outpoints[i].spendheight = 0; + tx->outpoints[i].spendvini = -1; + memset(tx->outpoints[i].spendtxid.bytes,0,sizeof(bits256)); + } + } + } + return(num); +} diff --git a/iguana/exchanges/Makefile b/iguana/exchanges/Makefile new file mode 100644 index 000000000..be75a297c --- /dev/null +++ b/iguana/exchanges/Makefile @@ -0,0 +1,15 @@ +#cd .. +#emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc + +#include ../crypto777/crypto777.sources +#emcc -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=134217728 --preload-file coins.json -D__PNACL -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c $(CRYPTO777_SRCS) mini-gmp.c secp256k1/src/secp256k1.c -lm -lc + +#emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + +#emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_barterDEX', '_main']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/index.hmtl exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + +#emcc -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -I../includes -I../crypto777 -o /var/www/html/barterDEX.js exchanges/barterDEX.c + +all: + emcc -s WASM=1 -s EXPORTED_FUNCTIONS="['_main', '_barterDEX']" -s ABORTING_MALLOC=0 -s ASSERTIONS=1 -s ASYNCIFY=1 -s TOTAL_MEMORY=167772160 --embed-file coins.json -DFROM_JS -O2 -I../includes -I../crypto777 -o /var/www/html/index.html exchanges/mm.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c mini-gmp.c secp256k1/src/secp256k1.c -lm + diff --git a/iguana/exchanges/PAX.c b/iguana/exchanges/PAX.c index fa2536654..4718e6973 100755 --- a/iguana/exchanges/PAX.c +++ b/iguana/exchanges/PAX.c @@ -30,7 +30,7 @@ #define FUNCS PAX ## _funcs #define BASERELS PAX ## _baserels -#include "../peggy.h" +#include "../PAX/peggy.h" char *peggy_bases[64] = { diff --git a/iguana/exchanges/README.md b/iguana/exchanges/README.md new file mode 100644 index 000000000..eab6d5720 --- /dev/null +++ b/iguana/exchanges/README.md @@ -0,0 +1,77 @@ +Latest Readme is at http://pad.supernet.org/barterdex-readme + +DEPENDENCIES +First of all you are going to need to have the komodod daemon and the assetchains running. +Install dependency packages: +sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool libncurses5-dev unzip git python zlib1g-dev wget bsdmainutils automake libboost-all-dev libssl-dev libprotobuf-dev protobuf-compiler libqt4-dev libqrencode-dev libdb++-dev ntp ntpdate vim software-properties-common curl libcurl4-gnutls-dev cmake clang +Some Linux machines are now providing nanomsg package version 1.0. If it is available via package manager, you can install it from there. Else, you should use github repo of nanomsg and compile it yourself. +For Ubuntu 14.04 you need to install it yourself +cd /tmp +wget https://github.com/nanomsg/nanomsg/archive/1.0.0.tar.gz -O nanomsg-1.0.0.tar.gz +tar -xzvf nanomsg-1.0.0.tar.gz +cd nanomsg-1.0.0 +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=/usr +cmake --build . +sudo cmake --build . --target install +sudo ldconfig +Or the following for 16.04 +git clone https://github.com/nanomsg/nanomsg +cd nanomsg +cmake . +make +sudo make install +sudo ldconfig +COMPILE LP NODE +To compile the BarterDEX you need to build iguana one time: +cd ~ +git clone https://github.com/jl777/SuperNET +cd SuperNET/iguana +git checkout dev +./m_LP +IGUANA DAEMON STARTUP +Then launch the iguana daemon by executing: +../agents/iguana & +Now iguana should be running and providing port 7778 API: 127.0.0.1:7778 page in the browser will show the API testpage, but for marketmaker these functions are not used very much. it is port 7779 that is used and the marketmaker program is what provides those functions. +BarterDEX EXCHANGE INSTALL +cd ~/SuperNET/iguana/exchanges +./install +Now, move to ~/SuperNET/iguana/dexscripts: +cd ~/SuperNET/iguana/dexscripts +Now in the ~/SuperNET/iguana/dexscripts directory you will have example scripts that you can change without new git updates overwriting them. These scripts will have example commands that you will need to customize to work with the coins you want to trade. Of course, if a new update to a script is made and you dont run install again then you wont have the latest versions. +For example: if you want to enable the JUMBLR coin, you need to edit the enable file: +nano ~SuperNET/iguana/dexscripts/enable +copy the default command and paste it below but with the coin edited to JUMBLR in this case: +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JUMBLR\"}" +The same will happen for any other script in the dexscripts directory. You will need to edit the scripts to include or exclude the coins you want to trade. +IMPORTANT: All these scripts are expecting a userpass file, which contains the definition of the $userpass variable to authenticate API access. This avoids evil webpages that try to issue port 7779 calls to steal your money. At first you wont know the value of userpass. To find out, just run any API script. The first one will return all the required data, the "userpass" field is first and you can copy that value and put it into ~/SuperNET/iguana/dexscripts/userpass file. If you dont, all subsequent API calls will get authorization errors.The userpass variable is linked to each passphrase and that is defined in the passphrase file. Put your passphrase in that file. You can find templates for these two files in the iguana/exchanges dir. (you need to copy the edited version of these files to ~/SuperNET/iguana/dexscripts). +cd ~/SuperNET/iguana/dexscripts +./enable +(look for the userpass passphrase that will be generated and copy it) +Now you have to paste the passphrase in both userpass and passphrase files: +nano ./userpass +nano ./passphrase +( paste the passphrase generated into the files where it says: “”) +EXCHANGE CLIENT STARTUP +Next step is to actually start the marketmaker from ~/SuperNET/iguana/dexscripts. + cd ~/SuperNET/iguana/dexscripts + ./client (for client mode) or + ./run (for LPnode mode) +Assuming you created the userpass file properly, you can now issue barterDEX api calls using all the scripts in the dexscripts dir. Please look at these scripts, they are simple curl invocations of a couple lines. Nothing scary and should be self explanatory. +The help script displays all the api endpoints you should need. You can customize any of the dexscripts for your desired usage, make sure you edit them with the right coins, as if you issue a script for BTC it will do it for BTC instead of the coin you wanted. These scripts wont read your mind, they just do what is in them +FUNDING SMARTADDRESS +In order to start trading, you need to fund your smartaddress (as listed on the first API call return) from the getcoins API call. +To see which is your smart address go to ~/SuperNET/iguana/dexscritps and execute: +./getcoins +To make sure you have utxo pairs for both the bob and alice usage, it is best to send utxo in triplets of X, 1.2 X and 0.01 X. So if X is 10, send 10, 12, and 0.1 coins using sendtoaddress to your smartaddress. This means you will have to send 3 different transactions to the same address with 3 different quantities +for example: +If i want to fund my komodo smartaddress with 100 komodo i need to first send a tx with 100kmd then another tx with 120kmd and a third tx with only 10kmd +After this, it should appear in the inventory. To see the inventory you need to execute: +./inv +SETTING PRICE + To set price you need to edit the ./setprice script in the dexscripts folder. This scripts contains a curl command that looks like this: +curl --url "http://127.0.0.1:7779" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234}" +In this command you should edit the coin (in this case is REVS) and then set the price per coin based in Komodo. In the command above we are setting a price of 1.23KMD per REVS. +After you setprice (./setprice), then it will appear in orderbooks with that coin in either the base or rel. + diff --git a/iguana/exchanges/SVM/.tmpmarker b/iguana/exchanges/SVM/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/SVM/models/.tmpmarker b/iguana/exchanges/SVM/models/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/SVM/rawfeatures/.tmpmarker b/iguana/exchanges/SVM/rawfeatures/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/assetchains.old b/iguana/exchanges/assetchains.old new file mode 100755 index 000000000..e7584afcd --- /dev/null +++ b/iguana/exchanges/assetchains.old @@ -0,0 +1,89 @@ +#!/bin/bash +set -x +delay=60 +source pubkey.txt +echo $pubkey + +./komodod -pubkey=$pubkey -ac_name=REVS -ac_supply=1300000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=SUPERNET -ac_supply=816061 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=DEX -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=PANGEA -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=JUMBLR -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=BET -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=CRYPTO -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=HODL -ac_supply=9999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=SHARK -ac_supply=1401 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=BOTS -ac_supply=999999 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=MGW -ac_supply=999999 -addnode=78.47.196.146 $1 & +#./komodod -pubkey=$pubkey -ac_name=MVP -ac_supply=1000000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=COQUI -ac_supply=72000000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=WLC -ac_supply=210000000 -addnode=148.251.190.89 $1 & +./komodod -pubkey=$pubkey -ac_name=KV -ac_supply=1000000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=CEAL -ac_supply=366666666 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=MESH -ac_supply=1000007 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=MNZ -ac_supply=257142858 -addnode=51.15.138.138 $1 & +sleep $delay + +./komodod -pubkey=$pubkey -ac_name=USD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=EUR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=JPY -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=GBP -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=AUD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=CAD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=CHF -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=NZD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=CNY -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=RUB -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=MXN -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=BRL -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=INR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=HKD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=TRY -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=ZAR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=PLN -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=NOK -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=SEK -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=DKK -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=CZK -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=HUF -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=ILS -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=KRW -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=MYR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=PHP -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=RON -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=SGD -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=THB -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=BGN -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=IDR -addnode=78.47.196.146 $1 & +sleep $delay +./komodod -pubkey=$pubkey -ac_name=HRK -addnode=78.47.196.146 $1 & diff --git a/iguana/exchanges/auto_chipsbtc b/iguana/exchanges/auto_chipsbtc new file mode 100755 index 000000000..06c5282e9 --- /dev/null +++ b/iguana/exchanges/auto_chipsbtc @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.00002,\"maxprice\":0.0001,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"BTC\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" diff --git a/iguana/exchanges/auto_chipskmd b/iguana/exchanges/auto_chipskmd new file mode 100755 index 000000000..c259a8cff --- /dev/null +++ b/iguana/exchanges/auto_chipskmd @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.04,\"maxprice\":0.1,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\",\"margin\":0.05,\"refbase\":\"chips\",\"refrel\":\"coinmarketcap\"}" diff --git a/iguana/exchanges/auto_grskmd b/iguana/exchanges/auto_grskmd new file mode 100755 index 000000000..59ad21afa --- /dev/null +++ b/iguana/exchanges/auto_grskmd @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"minprice\":0.05,\"maxprice\":0.2,\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"GRS\",\"rel\":\"KMD\",\"margin\":0.05,\"refbase\":\"groestlcoin\",\"refrel\":\"coinmarketcap\"}" diff --git a/iguana/exchanges/autoprice b/iguana/exchanges/autoprice new file mode 100755 index 000000000..21369b468 --- /dev/null +++ b/iguana/exchanges/autoprice @@ -0,0 +1,12 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":0.03}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTC\",\"rel\":\"KMD\",\"margin\":0.03}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"HUSH\",\"margin\":0.01}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"HUSH\",\"rel\":\"KMD\",\"margin\":0.01}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"USD\",\"margin\":0.01}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"USD\",\"rel\":\"KMD\",\"margin\":0.01}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"JUMBLR\",\"margin\":0.01}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"JUMBLR\",\"rel\":\"KMD\",\"margin\":0.01}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"MNZ\",\"rel\":\"KMD\",\"offset\":0.0,\"refbase\":\"BTC\",\"refrel\":\"KMD\",\"factor\":0.00006667,\"margin\":-0.2}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"MNZ\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"BTC\",\"factor\":15000,\"margin\":-0.2}" diff --git a/iguana/exchanges/balance b/iguana/exchanges/balance new file mode 100755 index 000000000..22f84cdee --- /dev/null +++ b/iguana/exchanges/balance @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balance\",\"coin\":\"KMD\",\"address\":\"RHV2As4rox97BuE3LK96vMeNY8VsGRTmBj\"}" diff --git a/iguana/exchanges/balance_loop b/iguana/exchanges/balance_loop new file mode 100755 index 000000000..ad28ac741 --- /dev/null +++ b/iguana/exchanges/balance_loop @@ -0,0 +1,12 @@ +#!/bin/bash +source userpass +ht=$1 +while true +do +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot\",\"coin\":\"KMD\",\"height\":$ht}" +ht=`curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot\",\"coin\":\"KMD\"}" | jq .blocks` + +echo next height $ht +sleep 600 +done + diff --git a/iguana/exchanges/balances b/iguana/exchanges/balances new file mode 100755 index 000000000..1eb527b8f --- /dev/null +++ b/iguana/exchanges/balances @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\"}" diff --git a/iguana/exchanges/barterDEX.c b/iguana/exchanges/barterDEX.c new file mode 100644 index 000000000..976016bc2 --- /dev/null +++ b/iguana/exchanges/barterDEX.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +char *barterDEX(char *jsonstr) +{ +char *retstr,*str = "{\"result\":\"success\"}"; +printf("barterDEX.(%s)\n",jsonstr); +retstr = malloc(strlen(str)+1); +strcpy(retstr,str); +return(retstr); +} + diff --git a/iguana/exchanges/baserelswaps b/iguana/exchanges/baserelswaps new file mode 100755 index 000000000..abea1c80e --- /dev/null +++ b/iguana/exchanges/baserelswaps @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"swapstatus\",\"base\":\"MNZ\",\"rel\":\"KMD\"}" diff --git a/iguana/exchanges/beertest b/iguana/exchanges/beertest new file mode 100755 index 000000000..61b600820 --- /dev/null +++ b/iguana/exchanges/beertest @@ -0,0 +1,2 @@ +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BEER\",\"rel\":\"KMD\",\"fixed\":1.28700,\"margin\":0.00001}" diff --git a/iguana/exchanges/bestfit b/iguana/exchanges/bestfit new file mode 100755 index 000000000..bae6a79ac --- /dev/null +++ b/iguana/exchanges/bestfit @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bestfit\",\"rel\":\"KMD\",\"relvolume\":1.01}" diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index 89b6ce232..62c0ed592 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -19,7 +19,7 @@ cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap); char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) { - return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params)); + return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,0)); } int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) @@ -107,29 +107,40 @@ int32_t base58encode_checkbuf(uint8_t addrtype,uint8_t *data,int32_t data_len) int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr) { - int32_t len = -1; bits256 hash; uint8_t buf[64]; + int32_t len = -1; bits256 hash; uint8_t buf[256]; + memset(buf,0,sizeof(buf)); if ( (len= bitcoin_base58decode(buf,wifstr)) >= 4 ) { // validate with trailing hash, then remove hash + if ( len < 38 ) + len = 38; hash = bits256_doublesha256(0,buf,len - 4); *addrtypep = *buf; memcpy(privkeyp,buf+1,32); - if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] &&(buf[len - 1]&0xff) == hash.bytes[28] ) + if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] && (buf[len - 1]&0xff) == hash.bytes[28] ) { - //printf("coinaddr.(%s) valid checksum\n",coinaddr); + //int32_t i; for (i=0; i vouts collision, purgeable - // - return(0); + uint8_t data[128]; int32_t len = 32; + memcpy(data+1,privkey.bytes,sizeof(privkey)); + len = base58encode_checkbuf(addrtype,data,len); + if ( bitcoin_base58encode(wifstr,data,len) == 0 ) + return(-1); + if ( 1 ) + { + uint8_t checktype; bits256 checkpriv; char str[65],str2[65]; + if ( bitcoin_wif2priv(&checktype,&checkpriv,wifstr) == sizeof(bits256) ) + { + if ( checktype != addrtype || bits256_cmp(checkpriv,privkey) != 0 ) + printf("(%s) -> wif.(%s) addrtype.%02x -> %02x (%s)\n",bits256_str(str,privkey),wifstr,addrtype,checktype,bits256_str(str2,checkpriv)); + } + } + return((int32_t)strlen(wifstr)); } -#ifdef bitcoincancalulatebalances uint64_t bitcoin_parseunspent(struct iguana_info *coin,struct bitcoin_unspent *unspent,double minconfirms,char *account,cJSON *item) { char *hexstr,coinaddr[64]; @@ -299,6 +320,7 @@ struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana ptr = spend->inputs; for (i=0; i=0; mode--) if ( (up= iguana_bestfit(coin,ups,totalunspents,remains,mode)) != 0 ) break; @@ -339,7 +361,7 @@ cJSON *bitcoin_vout(uint64_t satoshis,char *paymentscriptstr) skey = cJSON_CreateObject(); jaddstr(skey,"hex",paymentscriptstr); //printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0)); - jadd(item,"scriptPubkey",skey); + jadd(item,"scriptPubKey",skey); return(item); } @@ -393,7 +415,6 @@ char *bitcoin_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJ printf("need to patch locktime\n"); return(rawtx); } -#endif #define EXCHANGE_NAME "bitcoin" #define UPDATE bitcoin ## _price diff --git a/iguana/exchanges/bitcoin.h b/iguana/exchanges/bitcoin.h index 2bb2c5d9c..ad362a5a2 100755 --- a/iguana/exchanges/bitcoin.h +++ b/iguana/exchanges/bitcoin.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -33,7 +33,9 @@ #define SCRIPT_OP_ENDIF 0x68 #define SCRIPT_OP_DROP 0x75 #define SCRIPT_OP_EQUALVERIFY 0x88 +#define SCRIPT_OP_SHA256 0xa8 #define SCRIPT_OP_HASH160 0xa9 + #define SCRIPT_OP_EQUAL 0x87 #define SCRIPT_OP_CHECKSIG 0xac #define SCRIPT_OP_CHECKMULTISIG 0xae @@ -49,7 +51,6 @@ int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]); int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); -int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]); int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); int32_t bitcoin_pubkeylen(const uint8_t *pubkey); diff --git a/iguana/exchanges/bitfinex.c b/iguana/exchanges/bitfinex.c index 764167ca3..6643fff89 100755 --- a/iguana/exchanges/bitfinex.c +++ b/iguana/exchanges/bitfinex.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/bitstamp.c b/iguana/exchanges/bitstamp.c index 30c9b9a5a..36e928a34 100755 --- a/iguana/exchanges/bitstamp.c +++ b/iguana/exchanges/bitstamp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/bittrex.c b/iguana/exchanges/bittrex.c index f032b764b..d0e5025e9 100755 --- a/iguana/exchanges/bittrex.c +++ b/iguana/exchanges/bittrex.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -77,7 +77,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang { cJSON *json,*obj; char *jsonstr,market[128],url[1024]; double hbla = 0.; sprintf(market,"%s-%s",rel,base); - sprintf(url,"https://bittrex.com/api/v1.1/public/getorderbook?market=%s&type=both&depth=%d",market,maxdepth); + sprintf(url,"http://bittrex.com/api/v1.1/public/getorderbook?market=%s&type=both&depth=%d",market,maxdepth); jsonstr = issue_curl(url); if ( jsonstr != 0 ) { @@ -166,8 +166,11 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha return(0); } sprintf(payload,"https://bittrex.com/api/v1.1/market/%slimit?apikey=%s&nonce=%llu&market=%s&rate=%.8f&quantity=%.8f",dir>0?"buy":"sell",exchange->apikey,(long long)exchange_nonce(exchange),pairstr,price,volume); - if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,payload,payload)) != 0 ) + if ( //CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && + (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,payload,payload)) != 0 ) { + if ( 0 && *retstrp != 0 ) + printf("SIGNPOST returned.(%s) %s\n",*retstrp,jprint(json,0)); if ( is_cJSON_True(cJSON_GetObjectItem(json,"success")) != 0 && (resultobj= cJSON_GetObjectItem(json,"result")) != 0 ) { copy_cJSON(&uuidstr,cJSON_GetObjectItem(resultobj,"uuid")); @@ -176,13 +179,13 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha uuidstr.buf[j++] = uuidstr.buf[i]; uuidstr.buf[j] = 0; n = (int32_t)strlen(uuidstr.buf); - printf("-> uuidstr.(%s).%d\n",uuidstr.buf,n); + //printf("-> uuidstr.(%s).%d\n",uuidstr.buf,n); decode_hex(databuf,n/2,uuidstr.buf); if ( n >= 16 ) for (i=0; i<8; i++) databuf[i] ^= databuf[8 + i]; memcpy(&txid,databuf,8); - printf("-> %llx\n",(long long)txid); + //printf("-> %llx\n",(long long)txid); } free_json(json); } @@ -191,8 +194,13 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson) { - char payload[1024],*retstr = 0; cJSON *json; - sprintf(payload,"https://bittrex.com/api/v1.1/account/getorder?apikey=%s&nonce=%llu&uuid=%llu",exchange->apikey,(long long)exchange_nonce(exchange),(long long)quoteid); + char payload[1024],*orderstr=0,orderbuf[512],*retstr = 0; cJSON *json; + if ( argjson != 0 ) + orderstr = jstr(argjson,"uuid");//, printf("status.(%s)\n",jprint(argjson,0)); + if ( orderstr == 0 ) + sprintf(orderbuf,"%llu",(long long)quoteid); + else strcpy(orderbuf,jstr(argjson,"uuid")); + sprintf(payload,"https://bittrex.com/api/v1.1/account/getorder?apikey=%s&nonce=%llu&uuid=%s",exchange->apikey,(long long)exchange_nonce(exchange),orderbuf); if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,payload)) != 0 ) { free_json(json); @@ -202,8 +210,13 @@ char *ORDERSTATUS(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson char *CANCELORDER(struct exchange_info *exchange,uint64_t quoteid,cJSON *argjson) { - char payload[1024],*retstr = 0; cJSON *json; - sprintf(payload,"https://bittrex.com/api/v1.1/market/cancel?apikey=%s&nonce=%llu&uuid=%llu",exchange->apikey,(long long)exchange_nonce(exchange),(long long)quoteid); + char payload[1024],*orderstr=0,orderbuf[512],*retstr = 0; cJSON *json; + if ( argjson != 0 ) + orderstr = jstr(argjson,"uuid");//, printf("cancel.(%s)\n",jprint(argjson,0)); + if ( orderstr == 0 ) + sprintf(orderbuf,"%llu",(long long)quoteid); + else strcpy(orderbuf,jstr(argjson,"uuid")); + sprintf(payload,"https://bittrex.com/api/v1.1/market/cancel?apikey=%s&nonce=%llu&uuid=%s",exchange->apikey,(long long)exchange_nonce(exchange),orderbuf); if ( (json= SIGNPOST(&exchange->cHandle,1,&retstr,exchange,payload,payload)) != 0 ) { free_json(json); diff --git a/iguana/exchanges/bot_buy b/iguana/exchanges/bot_buy new file mode 100755 index 000000000..d26f5a8f7 --- /dev/null +++ b/iguana/exchanges/bot_buy @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_buy\",\"base\":\"REVS\",\"rel\":\"KMD\",\"maxprice\":3,\"relvolume\":10.0}" diff --git a/iguana/exchanges/bot_list b/iguana/exchanges/bot_list new file mode 100755 index 000000000..40cb49145 --- /dev/null +++ b/iguana/exchanges/bot_list @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_list\"}" diff --git a/iguana/exchanges/bot_pause b/iguana/exchanges/bot_pause new file mode 100755 index 000000000..ed9323e71 --- /dev/null +++ b/iguana/exchanges/bot_pause @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_pause\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_resume b/iguana/exchanges/bot_resume new file mode 100755 index 000000000..6d161b155 --- /dev/null +++ b/iguana/exchanges/bot_resume @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_resume\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_sell b/iguana/exchanges/bot_sell new file mode 100755 index 000000000..3613db3cb --- /dev/null +++ b/iguana/exchanges/bot_sell @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_sell\",\"base\":\"REVS\",\"rel\":\"KMD\",\"minprice\":2,\"basevolume\":5.0}" diff --git a/iguana/exchanges/bot_settings b/iguana/exchanges/bot_settings new file mode 100755 index 000000000..f02ca3016 --- /dev/null +++ b/iguana/exchanges/bot_settings @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_settings\",\"botid\":$1,\"newprice\":$2,\"newvolume\":$3}" diff --git a/iguana/exchanges/bot_status b/iguana/exchanges/bot_status new file mode 100755 index 000000000..e64bc5ae7 --- /dev/null +++ b/iguana/exchanges/bot_status @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_status\",\"botid\":$1}" diff --git a/iguana/exchanges/bot_statuslist b/iguana/exchanges/bot_statuslist new file mode 100755 index 000000000..14b7e3522 --- /dev/null +++ b/iguana/exchanges/bot_statuslist @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_statuslist\"}" diff --git a/iguana/exchanges/bot_stop b/iguana/exchanges/bot_stop new file mode 100755 index 000000000..665e2ac9e --- /dev/null +++ b/iguana/exchanges/bot_stop @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"bot_stop\",\"botid\":$1}" diff --git a/iguana/exchanges/bots b/iguana/exchanges/bots new file mode 100755 index 000000000..b64e65088 --- /dev/null +++ b/iguana/exchanges/bots @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P\",\"divisor\":1000000}" diff --git a/iguana/exchanges/btc38.c b/iguana/exchanges/btc38.c index 268dce776..493d3fa0d 100755 --- a/iguana/exchanges/btc38.c +++ b/iguana/exchanges/btc38.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/btce.c b/iguana/exchanges/btce.c index c7a255b06..b1d5a1291 100755 --- a/iguana/exchanges/btce.c +++ b/iguana/exchanges/btce.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/buy b/iguana/exchanges/buy new file mode 100755 index 000000000..cf83a91df --- /dev/null +++ b/iguana/exchanges/buy @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"buy\",\"base\":\"KMD\",\"rel\":\"BTC\",\"relvolume\":0.005,\"price\":0.0005}" diff --git a/iguana/exchanges/cancelorder b/iguana/exchanges/cancelorder new file mode 100755 index 000000000..31fe7ea8c --- /dev/null +++ b/iguana/exchanges/cancelorder @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":9999999.99}" diff --git a/iguana/exchanges/claim b/iguana/exchanges/claim new file mode 100755 index 000000000..85cd18c15 --- /dev/null +++ b/iguana/exchanges/claim @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"instantdex_claim\"}" diff --git a/iguana/exchanges/client b/iguana/exchanges/client new file mode 100755 index 000000000..3b33a363a --- /dev/null +++ b/iguana/exchanges/client @@ -0,0 +1,10 @@ +#!/bin/bash +source passphrase +source coins +./stop +git pull; +cd ..; +./m_mm; +pkill -15 marketmaker; +./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & + diff --git a/iguana/exchanges/client_osx b/iguana/exchanges/client_osx new file mode 100755 index 000000000..463a08eb4 --- /dev/null +++ b/iguana/exchanges/client_osx @@ -0,0 +1,9 @@ +#!/bin/bash +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +./m_mm; +./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}/Library/Application\ Support\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & + diff --git a/iguana/exchanges/coinbase.c b/iguana/exchanges/coinbase.c index 1a0fd190d..528df90a2 100755 --- a/iguana/exchanges/coinbase.c +++ b/iguana/exchanges/coinbase.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/coins b/iguana/exchanges/coins new file mode 100644 index 000000000..2b7061065 --- /dev/null +++ b/iguana/exchanges/coins @@ -0,0 +1,3 @@ +export coins="[{\"coin\":\"BAY\",\"name\":\"bitbay\",\"isPoS\":1,\"rpcport\":19915,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":10000}, {\"coin\":\"OOT\",\"asset\":\"OOT\",\"rpcport\":12467}, {\"coin\":\"ZOI\",\"name\":\"zoin\",\"rpcport\":8255,\"pubtype\":80,\"p2shtype\":7,\"wiftype\":208,\"txfee\":1000}, {\"coin\": \"PIZZA\",\"asset\": \"PIZZA\",\"rpcport\": 11116},{\"coin\": \"BEER\",\"asset\": \"BEER\",\"rpcport\": 8923}, {\"coin\":\"GRS\",\"name\":\"groestlcoin\",\"rpcport\":1441,\"pubtype\":36,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"XMCC\",\"name\":\"monoeci\",\"confpath\":\"${HOME#}/.monoeciCore/monoeci.conf\",\"rpcport\":24156,\"pubtype\":50,\"p2shtype\":73,\"wiftype\":77,\"txfee\":10000}, {\"coin\":\"BTCH\",\"asset\":\"BTCH\",\"rpcport\":8800},{\"coin\":\"ETOMIC\",\"asset\":\"ETOMIC\",\"rpcport\":10271},{\"coin\":\"AXO\",\"asset\":\"AXO\",\"rpcport\":12927},{\"coin\":\"CRC\",\"name\":\"crowdcoin\",\"confpath\":\"${HOME#}/.crowdcoincore/crowdcoin.conf\",\"rpcport\":11998,\"pubtype\":28,\"p2shtype\":88,\"wiftype\":0,\"txfee\":10000}, {\"coin\":\"VOT\",\"name\":\"votecoin\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"INN\",\"name\":\"innova\",\"confpath\":\"${HOME#}/.innovacore/innova.conf\",\"rpcport\":8818,\"pubtype\":102,\"p2shtype\":20,\"wiftype\":195,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":28,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"EFL\",\"name\":\"egulden\",\"confpath\":\"${HOME#}/.egulden/coin.conf\",\"rpcport\":21015,\"pubtype\":48,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"GBX\",\"name\":\"gobyte\",\"confpath\":\"${HOME#}/.gobytecore/gobyte.conf\",\"rpcport\":12454,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"BCO\",\"name\":\"bridgecoin\",\"rpcport\":6332,\"pubtype\":27,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BLK\",\"name\":\"blackcoin\",\"confpath\":\"${HOME#}/.lore/blackcoin.conf\",\"isPoS\":1,\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":100000}, {\"coin\":\"BTG\",\"name\":\"bitcoingold\",\"rpcport\":8332,\"pubtype\":38,\"p2shtype\":23,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BCH\",\"name\":\"bch\",\"rpcport\":33333,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"ABY\",\"name\":\"applebyte\",\"rpcport\":8607,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":100000}, {\"coin\":\"STAK\",\"name\":\"straks\",\"rpcport\":7574,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"XZC\",\"name\":\"zcoin\",\"rpcport\":8888,\"pubtype\":82,\"p2shtype\":7,\"wiftype\":210,\"txfee\":10000}, {\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":100000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":10000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"MSHARK\",\"asset\":\"MSHARK\",\"rpcport\":8846}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}]" +#, {\"coin\":\"AUD\",\"asset\":\"AUD\",\"rpcport\":8045}, {\"coin\":\"BGN\",\"asset\":\"BGN\",\"rpcport\":9110}, {\"coin\":\"CAD\",\"asset\":\"CAD\",\"rpcport\":8720}, {\"coin\":\"CHF\",\"asset\":\"CHF\",\"rpcport\":15312}, {\"coin\":\"CNY\",\"asset\":\"CNY\",\"rpcport\":10384}, {\"coin\":\"CZK\",\"asset\":\"CZK\",\"rpcport\":9482}, {\"coin\":\"DKK\",\"asset\":\"DKK\",\"rpcport\":13830}, {\"coin\":\"EUR\",\"asset\":\"EUR\",\"rpcport\":8065}, {\"coin\":\"GBP\",\"asset\":\"GBP\",\"rpcport\":11505}, {\"coin\":\"HKD\",\"asset\":\"HKD\",\"rpcport\":15409}, {\"coin\":\"HRK\",\"asset\":\"HRK\",\"rpcport\":12617}, {\"coin\":\"HUF\",\"asset\":\"HUF\",\"rpcport\":13699}, {\"coin\":\"IDR\",\"asset\":\"IDR\",\"rpcport\":14459}, {\"coin\":\"ILS\",\"asset\":\"ILS\",\"rpcport\":14638}, {\"coin\":\"INR\",\"asset\":\"INR\",\"rpcport\":10536}, {\"coin\":\"JPY\",\"asset\":\"JPY\",\"rpcport\":13145}, {\"coin\":\"KRW\",\"asset\":\"KRW\",\"rpcport\":14020}, {\"coin\":\"MXN\",\"asset\":\"MXN\",\"rpcport\":13970}, {\"coin\":\"MYR\",\"asset\":\"MYR\",\"rpcport\":10688}, {\"coin\":\"NOK\",\"asset\":\"NOK\",\"rpcport\":11588}, {\"coin\":\"NZD\",\"asset\":\"NZD\",\"rpcport\":10915}, {\"coin\":\"PHP\",\"asset\":\"PHP\",\"rpcport\":11181}, {\"coin\":\"PLN\",\"asset\":\"PLN\",\"rpcport\":13493}, {\"coin\":\"BRL\",\"asset\":\"BRL\",\"rpcport\":9914}, {\"coin\":\"RON\",\"asset\":\"RON\",\"rpcport\":8675}, {\"coin\":\"RUB\",\"asset\":\"RUB\",\"rpcport\":8199}, {\"coin\":\"SEK\",\"asset\":\"SEK\",\"rpcport\":11447}, {\"coin\":\"SGD\",\"asset\":\"SGD\",\"rpcport\":14475}, {\"coin\":\"THB\",\"asset\":\"THB\",\"rpcport\":11847}, {\"coin\":\"TRY\",\"asset\":\"TRY\",\"rpcport\":13924}, {\"coin\":\"USD\",\"asset\":\"USD\",\"rpcport\":13967}, {\"coin\":\"ZAR\",\"asset\":\"ZAR\",\"rpcport\":15160}]" +#{\"coin\":\"PIVX\",\"name\":\"pivx\",\"rpcport\":51473,\"pubtype\":30,\"p2shtype\":13,\"wiftype\":212,\"txfee\":10000}, diff --git a/iguana/exchanges/coins.json b/iguana/exchanges/coins.json new file mode 100644 index 000000000..6c61ab8af --- /dev/null +++ b/iguana/exchanges/coins.json @@ -0,0 +1 @@ +[{\"coin\":\"XMCC\",\"name\":\"monoeci\",\"confpath\":\"${HOME#}/.monoeciCore/monoeci.conf\",\"rpcport\":24156,\"pubtype\":50,\"p2shtype\":73,\"wiftype\":77,\"txfee\":10000}, {\"coin\":\"BTCH\",\"asset\":\"BTCH\",\"rpcport\":8800},{\"coin\":\"ETOMIC\",\"asset\":\"ETOMIC\",\"rpcport\":10271},{\"coin\":\"AXO\",\"asset\":\"AXO\",\"rpcport\":12927},{\"coin\":\"CRC\",\"name\":\"crowdcoin\",\"confpath\":\"${HOME#}/.crowdcoincore/crowdcoin.conf\",\"rpcport\":9998,\"pubtype\":28,\"p2shtype\":88,\"wiftype\":0,\"txfee\":10000}, {\"coin\":\"VOT\",\"name\":\"votecoin\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"INN\",\"name\":\"innova\",\"confpath\":\"${HOME#}/.innovacore/innova.conf\",\"rpcport\":8818,\"pubtype\":102,\"p2shtype\":20,\"wiftype\":195,\"txfee\":10000}, {\"coin\":\"MOON\",\"name\":\"mooncoin\",\"rpcport\":44663,\"pubtype\":3,\"p2shtype\":22,\"wiftype\":131,\"txfee\":100000}, {\"coin\":\"CRW\",\"name\":\"crown\",\"rpcport\":9341,\"pubtype\":0,\"p2shtype\":28,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"EFL\",\"name\":\"egulden\",\"confpath\":\"${HOME#}/.egulden/coin.conf\",\"rpcport\":21015,\"pubtype\":48,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"GBX\",\"name\":\"gobyte\",\"confpath\":\"${HOME#}/.gobytecore/gobyte.conf\",\"rpcport\":12454,\"pubtype\":38,\"p2shtype\":10,\"wiftype\":198,\"txfee\":10000}, {\"coin\":\"BCO\",\"name\":\"bridgecoin\",\"rpcport\":6332,\"pubtype\":27,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BLK\",\"name\":\"blackcoin\",\"confpath\":\"${HOME#}/.lore/blackcoin.conf\",\"isPoS\":1,\"rpcport\":15715,\"pubtype\":25,\"p2shtype\":85,\"wiftype\":153,\"txfee\":100000}, {\"coin\":\"BTG\",\"name\":\"bitcoingold\",\"rpcport\":8332,\"pubtype\":38,\"p2shtype\":23,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BCH\",\"name\":\"bch\",\"rpcport\":33333,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"ABY\",\"name\":\"applebyte\",\"rpcport\":8607,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":100000}, {\"coin\":\"STAK\",\"name\":\"straks\",\"rpcport\":7574,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"XZC\",\"name\":\"zcoin\",\"rpcport\":8888,\"pubtype\":82,\"p2shtype\":7,\"wiftype\":210,\"txfee\":10000}, {\"coin\":\"QTUM\",\"name\":\"qtum\",\"rpcport\":3889,\"pubtype\":58,\"p2shtype\":50,\"wiftype\":128,\"txfee\":400000}, {\"coin\":\"PURA\",\"name\":\"pura\",\"rpcport\":55555,\"pubtype\":55,\"p2shtype\":16,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"DSR\",\"name\":\"desire\",\"confpath\":\"${HOME#}/.desirecore/desire.conf\",\"rpcport\":9918,\"pubtype\":30,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"MNZ\",\"asset\":\"MNZ\",\"rpcport\":14337},{\"coin\":\"BTCZ\",\"name\":\"bitcoinz\",\"rpcport\":1979,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"MAGA\",\"name\":\"magacoin\",\"rpcport\":5332,\"pubtype\":23,\"p2shtype\":50,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"BSD\",\"name\":\"bitsend\",\"rpcport\":8800,\"pubtype\":102,\"p2shtype\":5,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"IOP\",\"name\":\"IoP\",\"rpcport\":8337,\"pubtype\":117,\"p2shtype\":174,\"wiftype\":49,\"txfee\":10000}, {\"coin\":\"BLOCK\",\"name\":\"blocknetdx\",\"rpcport\":41414,\"pubtype\":26,\"p2shtype\":28,\"wiftype\":154,\"txfee\":10000}, {\"coin\":\"CHIPS\", \"name\": \"chips\", \"rpcport\":57776,\"pubtype\":60, \"p2shtype\":85, \"wiftype\":188, \"txfee\":10000}, {\"coin\":\"888\",\"name\":\"octocoin\",\"rpcport\":22888,\"pubtype\":18,\"p2shtype\":5,\"wiftype\":176,\"txfee\":2000000}, {\"coin\":\"ARG\",\"name\":\"argentum\",\"rpcport\":13581,\"pubtype\":23,\"p2shtype\":5,\"wiftype\":151,\"txfee\":50000}, {\"coin\":\"GLT\",\"name\":\"globaltoken\",\"rpcport\":9320,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":166,\"txfee\":10000}, {\"coin\":\"ZER\",\"name\":\"zero\",\"rpcport\":23801,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"HODLC\",\"name\":\"hodlcoin\",\"rpcport\":11989,\"pubtype\":40,\"p2shtype\":5,\"wiftype\":168,\"txfee\":5000}, {\"coin\":\"UIS\",\"name\":\"unitus\",\"rpcport\":50604,\"pubtype\":68,\"p2shtype\":10,\"wiftype\":132,\"txfee\":2000000}, {\"coin\":\"HUC\",\"name\":\"huntercoin\",\"rpcport\":8399,\"pubtype\":40,\"p2shtype\":13,\"wiftype\":168,\"txfee\":100000}, {\"coin\":\"BDL\",\"name\":\"bitdeal\",\"rpcport\":9332,\"pubtype\":38,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"ARC\",\"name\":\"arcticcoin\",\"confpath\":\"${HOME#}/.arcticcore/arcticcoin.conf\",\"rpcport\":7208,\"pubtype\":23,\"p2shtype\":8,\"wiftype\":176,\"txfee\":10000}, {\"coin\":\"ZCL\",\"name\":\"zclassic\",\"rpcport\":8023,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"VIA\",\"name\":\"viacoin\",\"rpcport\":5222,\"pubtype\":71,\"p2shtype\":33,\"wiftype\":199,\"txfee\":100000}, {\"coin\":\"ERC\",\"name\":\"europecoin\",\"rpcport\":11989,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":168,\"txfee\":10000},{\"coin\":\"FAIR\",\"name\":\"faircoin\",\"confpath\":\"${HOME#}/.faircoin2/faircoin.conf\",\"rpcport\":40405,\"pubtype\":95,\"p2shtype\":36,\"wiftype\":223,\"txfee\":1000000}, {\"coin\":\"FLO\",\"name\":\"florincoin\",\"rpcport\":7313,\"pubtype\":35,\"p2shtype\":8,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"SXC\",\"name\":\"sexcoin\",\"rpcport\":9561,\"pubtype\":62,\"p2shtype\":5,\"wiftype\":190,\"txfee\":100000}, {\"coin\":\"CREA\",\"name\":\"creativecoin\",\"rpcport\":17711,\"pubtype\":28,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000}, {\"coin\":\"TRC\",\"name\":\"terracoin\",\"confpath\":\"${HOME#}/.terracoincore/terracoin.conf\",\"rpcport\":13332,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"BTA\",\"name\":\"bata\",\"rpcport\":5493,\"pubtype\":25,\"p2shtype\":5,\"wiftype\":188,\"txfee\":100000}, {\"coin\":\"SMC\",\"name\":\"smartcoin\",\"rpcport\":58583,\"pubtype\":63,\"p2shtype\":5,\"wiftype\":191,\"txfee\":1000000}, {\"coin\":\"NMC\",\"name\":\"namecoin\",\"rpcport\":8336,\"pubtype\":52,\"p2shtype\":13,\"wiftype\":180,\"txfee\":100000}, {\"coin\":\"NAV\",\"name\":\"navcoin\",\"isPoS\":1,\"confpath\":\"${HOME#}/.navcoin4/navcoin.conf\",\"rpcport\":44444,\"pubtype\":53,\"p2shtype\":85,\"wiftype\":150,\"txfee\":10000}, {\"coin\":\"EMC2\",\"name\":\"einsteinium\",\"rpcport\":41879,\"pubtype\":33,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"SYS\",\"name\":\"syscoin\",\"rpcport\":8370,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"I0C\",\"name\":\"i0coin\",\"rpcport\":7332,\"pubtype\":105,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"DASH\",\"confpath\":\"${HOME#}/.dashcore/dash.conf\",\"name\":\"dashcore\",\"rpcport\":9998,\"pubtype\":76,\"p2shtype\":16,\"wiftype\":204,\"txfee\":10000}, {\"coin\":\"STRAT\", \"name\": \"stratis\", \"active\":0, \"rpcport\":16174,\"pubtype\":63, \"p2shtype\":125, \"wiftype\":191, \"txfee\":10000}, {\"confpath\":\"${HOME#}/.muecore/mue.conf\",\"coin\":\"MUE\",\"name\":\"muecore\",\"rpcport\":29683,\"pubtype\":16,\"p2shtype\":76,\"wiftype\":126,\"txfee\":10000}, {\"coin\":\"MONA\",\"name\":\"monacoin\",\"rpcport\":9402,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":176,\"txfee\":100000},{\"coin\":\"XMY\",\"name\":\"myriadcoin\",\"rpcport\":10889,\"pubtype\":50,\"p2shtype\":9,\"wiftype\":178,\"txfee\":5000}, {\"coin\":\"MAC\",\"name\":\"machinecoin\",\"rpcport\":40332,\"pubtype\":50,\"p2shtype\":5,\"wiftype\":178,\"txfee\":100000}, {\"coin\":\"BTX\",\"name\":\"bitcore\",\"rpcport\":8556,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":50000}, {\"coin\":\"XRE\",\"name\":\"revolvercoin\",\"rpcport\":8775,\"pubtype\":0,\"p2shtype\":5,\"wiftype\":128,\"txfee\":1000}, {\"coin\":\"LBC\",\"name\":\"lbrycrd\",\"rpcport\":9245,\"pubtype\":85,\"p2shtype\":122,\"wiftype\":28,\"txfee\":1000}, {\"coin\":\"SIB\",\"name\":\"sibcoin\",\"rpcport\":1944,\"pubtype\":63,\"p2shtype\":40,\"wiftype\":128,\"txfee\":10000}, {\"coin\":\"VTC\", \"name\":\"vertcoin\", \"rpcport\":5888, \"pubtype\":71, \"p2shtype\":5, \"wiftype\":128, \"txfee\":100000 }, {\"coin\":\"REVS\",\"active\":0, \"asset\":\"REVS\",\"rpcport\":10196}, {\"coin\":\"JUMBLR\",\"active\":0, \"asset\":\"JUMBLR\",\"rpcport\":15106}, {\"coin\":\"DOGE\",\"name\":\"dogecoin\",\"rpcport\":22555,\"pubtype\":30,\"p2shtype\":22,\"wiftype\":158,\"txfee\":100000000}, {\"coin\":\"HUSH\",\"name\":\"hush\",\"rpcport\":8822,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":1000 }, {\"active\":0,\"coin\":\"ZEC\",\"name\":\"zcash\",\"rpcport\":8232,\"taddr\":28,\"pubtype\":184,\"p2shtype\":189,\"wiftype\":128,\"txfee\":10000 }, {\"coin\":\"DGB\",\"name\":\"digibyte\",\"rpcport\":14022,\"pubtype\":30,\"p2shtype\":5,\"wiftype\":128,\"txfee\":100000}, {\"coin\":\"ZET\", \"name\":\"zetacoin\", \"pubtype\":80, \"p2shtype\":9,\"rpcport\":8332, \"wiftype\":224, \"txfee\":10000}, {\"coin\":\"GAME\", \"rpcport\":40001, \"name\":\"gamecredits\", \"pubtype\":38, \"p2shtype\":5, \"wiftype\":166, \"txfee\":100000}, {\"coin\":\"LTC\", \"name\":\"litecoin\", \"rpcport\":9332, \"pubtype\":48, \"p2shtype\":5, \"wiftype\":176, \"txfee\":100000 }, {\"coin\":\"SUPERNET\",\"asset\":\"SUPERNET\",\"rpcport\":11341}, {\"coin\":\"WLC\",\"asset\":\"WLC\",\"rpcport\":12167}, {\"coin\":\"PANGEA\",\"asset\":\"PANGEA\",\"rpcport\":14068}, {\"coin\":\"DEX\",\"asset\":\"DEX\",\"rpcport\":11890}, {\"coin\":\"BET\",\"asset\":\"BET\",\"rpcport\":14250}, {\"coin\":\"CRYPTO\",\"asset\":\"CRYPTO\",\"rpcport\":8516}, {\"coin\":\"HODL\",\"asset\":\"HODL\",\"rpcport\":14431}, {\"coin\":\"MSHARK\",\"asset\":\"MSHARK\",\"rpcport\":8846}, {\"coin\":\"BOTS\",\"asset\":\"BOTS\",\"rpcport\":11964}, {\"coin\":\"MGW\",\"asset\":\"MGW\",\"rpcport\":12386}, {\"coin\":\"COQUI\",\"asset\":\"COQUI\",\"rpcport\":14276}, {\"coin\":\"KV\",\"asset\":\"KV\",\"rpcport\":8299}, {\"coin\":\"CEAL\",\"asset\":\"CEAL\",\"rpcport\":11116}, {\"coin\":\"MESH\",\"asset\":\"MESH\",\"rpcport\":9455}] diff --git a/iguana/exchanges/coinswaps b/iguana/exchanges/coinswaps new file mode 100755 index 000000000..7d87697f9 --- /dev/null +++ b/iguana/exchanges/coinswaps @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"swapstatus\",\"coin\":\"CHIPS\"}" diff --git a/iguana/exchanges/confs/.tmpmarker b/iguana/exchanges/confs/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/debug b/iguana/exchanges/debug new file mode 100755 index 000000000..a4f2297a3 --- /dev/null +++ b/iguana/exchanges/debug @@ -0,0 +1,9 @@ +#!/bin/bash +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +./m_mm; +gdb -args ./marketmaker "{\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" + diff --git a/iguana/exchanges/deletemessages b/iguana/exchanges/deletemessages new file mode 100755 index 000000000..5aba784a4 --- /dev/null +++ b/iguana/exchanges/deletemessages @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"deletemessages\",\"firsti\":0,\"num\":10}" diff --git a/iguana/exchanges/deposit1 b/iguana/exchanges/deposit1 new file mode 100755 index 000000000..9b2e411b7 --- /dev/null +++ b/iguana/exchanges/deposit1 @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"instantdex_deposit\",\"weeks\":1,\"amount\":10.0,\"broadcast\":1}" diff --git a/iguana/exchanges/deposit10 b/iguana/exchanges/deposit10 new file mode 100755 index 000000000..f0ba9bcf7 --- /dev/null +++ b/iguana/exchanges/deposit10 @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"instantdex_deposit\",\"weeks\":10,\"amount\":10.0,\"broadcast\":1}" diff --git a/iguana/exchanges/dex b/iguana/exchanges/dex new file mode 100755 index 000000000..721768833 --- /dev/null +++ b/iguana/exchanges/dex @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf\",\"divisor\":1000000}" diff --git a/iguana/exchanges/disable b/iguana/exchanges/disable new file mode 100755 index 000000000..636fc952f --- /dev/null +++ b/iguana/exchanges/disable @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"disable\",\"coin\":\"REVS\"}" diff --git a/iguana/exchanges/dividends b/iguana/exchanges/dividends new file mode 100755 index 000000000..5385b9454 --- /dev/null +++ b/iguana/exchanges/dividends @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"dividends\",\"coin\":\"KMD\",\"height\":$1,\"prefix\":\"fiat/jumblr sendtoaddress\",\"suffix\":\"\",\"dividend\":50000,\"dust\":1}" diff --git a/iguana/exchanges/dynamictrust b/iguana/exchanges/dynamictrust new file mode 100755 index 000000000..0a22e9fd9 --- /dev/null +++ b/iguana/exchanges/dynamictrust @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"dynamictrust\",\"address\":\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\"}" diff --git a/iguana/exchanges/electrum b/iguana/exchanges/electrum new file mode 100755 index 000000000..375d3d8f4 --- /dev/null +++ b/iguana/exchanges/electrum @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"BTC\",\"ipaddr\":\"173.212.225.176\",\"port\":50001}" diff --git a/iguana/exchanges/electrum.chips b/iguana/exchanges/electrum.chips new file mode 100755 index 000000000..f5cd61e8c --- /dev/null +++ b/iguana/exchanges/electrum.chips @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"CHIPS\",\"ipaddr\":\"173.212.225.176\",\"port\":50076}" diff --git a/iguana/exchanges/electrum.chips2 b/iguana/exchanges/electrum.chips2 new file mode 100755 index 000000000..2be709e78 --- /dev/null +++ b/iguana/exchanges/electrum.chips2 @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"CHIPS\",\"ipaddr\":\"136.243.45.140\",\"port\":50076}" diff --git a/iguana/exchanges/electrum.kmd b/iguana/exchanges/electrum.kmd new file mode 100755 index 000000000..865205062 --- /dev/null +++ b/iguana/exchanges/electrum.kmd @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"96.44.166.176\",\"port\":8777}" diff --git a/iguana/exchanges/electrum.kmd2 b/iguana/exchanges/electrum.kmd2 new file mode 100755 index 000000000..40bd30c93 --- /dev/null +++ b/iguana/exchanges/electrum.kmd2 @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"173.212.225.176\",\"port\":50011}" diff --git a/iguana/exchanges/electrum.kmd3 b/iguana/exchanges/electrum.kmd3 new file mode 100755 index 000000000..4bf1a6c10 --- /dev/null +++ b/iguana/exchanges/electrum.kmd3 @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"136.243.45.140\",\"port\":50011}" diff --git a/iguana/exchanges/electrums b/iguana/exchanges/electrums new file mode 100755 index 000000000..a4cabe5e3 --- /dev/null +++ b/iguana/exchanges/electrums @@ -0,0 +1,39 @@ +#!/bin/bash +source userpass + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"REVS\",\"ipaddr\":\"173.212.225.176\",\"port\":50050}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"CHIPS\",\"ipaddr\":\"173.212.225.176\",\"port\":50076}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"ARG\",\"ipaddr\":\"173.212.225.176\",\"port\":50081}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"BTC\",\"ipaddr\":\"136.243.45.140\",\"port\":50001}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"BTC\",\"ipaddr\":\"173.212.225.176\",\"port\":50001}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"CRW\",\"ipaddr\":\"173.212.225.176\",\"port\":50041}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"DASH\",\"ipaddr\":\"173.212.225.176\",\"port\":50098}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"DGB\",\"ipaddr\":\"136.243.45.140\",\"port\":50022}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"DGB\",\"ipaddr\":\"173.212.225.176\",\"port\":50022}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"DOGE\",\"ipaddr\":\"173.212.225.176\",\"port\":50015}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"FAIR\",\"ipaddr\":\"173.212.225.176\",\"port\":50005}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"HUSH\",\"ipaddr\":\"173.212.225.176\",\"port\":50013}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"136.243.45.140\",\"port\":50011}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"KMD\",\"ipaddr\":\"173.212.225.176\",\"port\":50011}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"LTC\",\"ipaddr\":\"173.212.225.176\",\"port\":50012}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"MONA\",\"ipaddr\":\"173.212.225.176\",\"port\":50002}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"NMC\",\"ipaddr\":\"173.212.225.176\",\"port\":50036}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"VTC\",\"ipaddr\":\"173.212.225.176\",\"port\":50088}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"ZEC\",\"ipaddr\":\"173.212.225.176\",\"port\":50032}" + diff --git a/iguana/exchanges/enable b/iguana/exchanges/enable new file mode 100755 index 000000000..f682b9343 --- /dev/null +++ b/iguana/exchanges/enable @@ -0,0 +1,25 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BEER\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"PIZZA\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"REVS\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"KMD\"}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BTC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"CHIPS\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"SUPERNET\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"CRYPTO\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"DEX\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BOTS\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BET\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"HODL\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MSHARK\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"MGW\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"PANGEA\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JUMBLR\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"HUSH\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BTCH\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"HUSH\",\"ipaddr\":\"173.212.225.176\",\"port\":50013}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"BTCH\",\"ipaddr\":\"electrum1.cipig.net\",\"port\":10020}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"electrum\",\"coin\":\"BTC\",\"ipaddr\":\"node1.komodo.rocks\",\"port\":50001}" + diff --git a/iguana/exchanges/exchange_supports.h b/iguana/exchanges/exchange_supports.h index 083630bc1..fc7c854d2 100755 --- a/iguana/exchanges/exchange_supports.h +++ b/iguana/exchanges/exchange_supports.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/exchange_undefs.h b/iguana/exchanges/exchange_undefs.h index 20862bce8..6d115147d 100755 --- a/iguana/exchanges/exchange_undefs.h +++ b/iguana/exchanges/exchange_undefs.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/fundLP b/iguana/exchanges/fundLP new file mode 100755 index 000000000..9dcf3eab8 --- /dev/null +++ b/iguana/exchanges/fundLP @@ -0,0 +1,2 @@ +fiat/$1 sendmany \"\" "{\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2,\"RMfQwu5ey23eWJ4as2ckd8dqsQJwo836ny\":$2,\"RQzkkncY8ehpRg8M4kvKmDMcbFxcJvohgk\":$2,\"RXUF132uyPVTVUdLn16zCgvYoFXya3pyVb\":$2,\"RNyBS6ryQtPPQnJhavKn9o94U2RNExLZon\":$2,\"RPMpwKpzWyg5KoMcsuy3mZucUWNdcP2ndD\":$2,\"RVPcbafNSi6uMaKDyss9epGpHCHbbzUFMd\":$2,\"RAzheh3L7QtBL7oNKByVa43CtgALht6bbT\":$2,\"RMdjuxKBhyr87yhKp6BLUg2p9673NMcPAu\":$2,\"RUPX5RWQL1qurMLmF4fFB4JAgRfwcNww4b\":$2,\"RQLn2QYwXDemFN3DNigU5qv3wUrA3WqquA\":$2}" 0 + diff --git a/iguana/exchanges/fundvalue b/iguana/exchanges/fundvalue new file mode 100755 index 000000000..3e46662f6 --- /dev/null +++ b/iguana/exchanges/fundvalue @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":13000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":650000}" diff --git a/iguana/exchanges/fxcm.c b/iguana/exchanges/fxcm.c index 02e98fea1..15aede1cd 100755 --- a/iguana/exchanges/fxcm.c +++ b/iguana/exchanges/fxcm.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -99,7 +99,7 @@ int32_t fxcm_setcontracts() { if ( (json= cJSON_Parse(xmlstr)) != 0 ) { - /* + /* 123.763 123.786 123.956 @@ -131,6 +131,7 @@ int32_t fxcm_setcontracts() if ( strcmp(name,"USDCNH") == 0 ) strcpy(name,"USDCNY"); FXCM_contracts[num++] = clonestr(name); + printf("FXCM[%d] = %s\n",num-1,name); } } } @@ -152,6 +153,7 @@ int32_t fxcm_ensure() char *ALLPAIRS(struct exchange_info *exchange,cJSON *argjson) { int32_t i,c,n; char base[32],rel[32]; cJSON *json,*item,*array = cJSON_CreateArray(); + n = 0; if ( fxcm_ensure() == 0 ) { for (i=0; i SMALLVAL && ask > SMALLVAL ) + { + //printf("%d.{%.6f %.6f}.%s ",c,bid,ask,name); return((bid + ask) * .5); + } } } return(0); diff --git a/iguana/exchanges/genesis/.tmpmarker b/iguana/exchanges/genesis/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/get_supernet b/iguana/exchanges/get_supernet new file mode 100755 index 000000000..2d43c6ba9 --- /dev/null +++ b/iguana/exchanges/get_supernet @@ -0,0 +1,15 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"REVS\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"KMD\",\"rel\":\"BTC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"SUPERNET\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"CRYPTO\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"DEX\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"BOTS\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"BET\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"HODL\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"MSHARK\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"MGW\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"PANGEA\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprice\",\"base\":\"JUMBLR\",\"rel\":\"KMD\"}" diff --git a/iguana/exchanges/getcoin b/iguana/exchanges/getcoin new file mode 100755 index 000000000..b37ccc666 --- /dev/null +++ b/iguana/exchanges/getcoin @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getcoin\",\"coin\":\"LTC\"}" diff --git a/iguana/exchanges/getcoins b/iguana/exchanges/getcoins new file mode 100755 index 000000000..64b1d7461 --- /dev/null +++ b/iguana/exchanges/getcoins @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getcoins\"}" diff --git a/iguana/exchanges/getmessages b/iguana/exchanges/getmessages new file mode 100755 index 000000000..121e8ec0b --- /dev/null +++ b/iguana/exchanges/getmessages @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmessages\",\"firsti\":0,\"num\":10}" diff --git a/iguana/exchanges/getpeers b/iguana/exchanges/getpeers new file mode 100755 index 000000000..9ed1daf77 --- /dev/null +++ b/iguana/exchanges/getpeers @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getpeers\"}" diff --git a/iguana/exchanges/getpeersIP b/iguana/exchanges/getpeersIP new file mode 100755 index 000000000..8fd44da30 --- /dev/null +++ b/iguana/exchanges/getpeersIP @@ -0,0 +1,11 @@ +#!/bin/bash +curl --url "http://5.9.253.195:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.196:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.197:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.198:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.199:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.200:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.201:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.202:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.203:7782" --data "{\"method\":\"getpeers\"}" +curl --url "http://5.9.253.204:7782" --data "{\"method\":\"getpeers\"}" diff --git a/iguana/exchanges/getprices b/iguana/exchanges/getprices new file mode 100755 index 000000000..57031035c --- /dev/null +++ b/iguana/exchanges/getprices @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getprices\",\"coin\":\"REVS\"}" diff --git a/iguana/exchanges/getrawtransaction b/iguana/exchanges/getrawtransaction new file mode 100755 index 000000000..c9d042c65 --- /dev/null +++ b/iguana/exchanges/getrawtransaction @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getrawtransaction\",\"coin\":\"KMD\",\"txid\":\"107a2683abbfa9188f78e17d3bcba66ece5bd7cbe105ab5bbaae79364159e84d\"}" diff --git a/iguana/exchanges/getutxos b/iguana/exchanges/getutxos new file mode 100755 index 000000000..4782c9a0a --- /dev/null +++ b/iguana/exchanges/getutxos @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getutxos\",\"coin\":\"REVS\"}" diff --git a/iguana/exchanges/goal b/iguana/exchanges/goal new file mode 100755 index 000000000..74fd1fcda --- /dev/null +++ b/iguana/exchanges/goal @@ -0,0 +1,5 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"goal\",\"coin\":\"KMD\",\"val\":99}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"goal\",\"coin\":\"BTC\",\"val\":10}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"goal\",\"coin\":\"REVS\",\"val\":1}" diff --git a/iguana/exchanges/goals b/iguana/exchanges/goals new file mode 100755 index 000000000..22f31bab8 --- /dev/null +++ b/iguana/exchanges/goals @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"goal\"}" diff --git a/iguana/exchanges/guistats b/iguana/exchanges/guistats new file mode 100755 index 000000000..98384f32a --- /dev/null +++ b/iguana/exchanges/guistats @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"statsdisp\",\"starttime\":0,\"endtime\":0,\"gui\":\"buildog\"}" diff --git a/iguana/exchanges/help b/iguana/exchanges/help new file mode 100755 index 000000000..a16fa1181 --- /dev/null +++ b/iguana/exchanges/help @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"help\"}" diff --git a/iguana/exchanges/hodl b/iguana/exchanges/hodl new file mode 100755 index 000000000..b70cf5456 --- /dev/null +++ b/iguana/exchanges/hodl @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RNcUaMUEFLxVwtTo7rgruhwYanGk1jTkeU\",\"holdings\":[{\"coin\":\"siacoin\",\"balance\":185000000,\"comment\":\"using siafunds equal to million siacoin\"}],\"divisor\":10000000}" diff --git a/iguana/exchanges/huobi.c b/iguana/exchanges/huobi.c index 402049a7c..02cc6f941 100755 --- a/iguana/exchanges/huobi.c +++ b/iguana/exchanges/huobi.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/instaforex.c b/iguana/exchanges/instaforex.c index 4a5ba5c0f..babcec86f 100755 --- a/iguana/exchanges/instaforex.c +++ b/iguana/exchanges/instaforex.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -44,7 +44,7 @@ void prices777_instaforex(uint32_t timestamps[NUM_INSTAFOREX],double bids[NUM_IN jsonstr = issue_curl("https://quotes.instaforex.com/get_quotes.php?q=NZDUSD,NZDCHF,NZDCAD,NZDJPY,GBPNZD,EURNZD,AUDNZD,CADJPY,CADCHF,USDCAD,EURCAD,GBPCAD,AUDCAD,USDCHF,CHFJPY,EURCHF,GBPCHF,AUDCHF,EURUSD,EURAUD,EURJPY,EURGBP,GBPUSD,GBPJPY,GBPAUD,USDJPY,AUDJPY,AUDUSD,XAUUSD&m=json"); if ( jsonstr != 0 ) { - // printf("(%s)\n",jsonstr); + printf("(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { for (i=0; i +#include +#ifndef NATIVE_WINDOWS +#include "OS_portable.h" +#else +#include "../../crypto777/OS_portable.h" +#endif // !_WIN_32 + +uint32_t DOCKERFLAG; +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); +#include "stats.c" +void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]); + +//defined(__APPLE__) || +#ifdef FROM_JS // defined(WIN32) || defined(USE_STATIC_NANOMSG) +#include "../../crypto777/nanosrc/nn.h" +#include "../../crypto777/nanosrc/bus.h" +#include "../../crypto777/nanosrc/pubsub.h" +#include "../../crypto777/nanosrc/pipeline.h" +#include "../../crypto777/nanosrc/reqrep.h" +#include "../../crypto777/nanosrc/tcp.h" +#include "../../crypto777/nanosrc/pair.h" +#else +#if defined(WIN32) || defined(USE_STATIC_NANOMSG) + #include "../../crypto777/nanosrc/nn.h" + #include "../../crypto777/nanosrc/bus.h" + #include "../../crypto777/nanosrc/pubsub.h" + #include "../../crypto777/nanosrc/pipeline.h" + #include "../../crypto777/nanosrc/reqrep.h" + #include "../../crypto777/nanosrc/tcp.h" + #include "../../crypto777/nanosrc/pair.h" +#else + #include "/usr/local/include/nanomsg/nn.h" + #include "/usr/local/include/nanomsg/bus.h" + #include "/usr/local/include/nanomsg/pubsub.h" + #include "/usr/local/include/nanomsg/pipeline.h" + #include "/usr/local/include/nanomsg/reqrep.h" + #include "/usr/local/include/nanomsg/tcp.h" + #include "/usr/local/include/nanomsg/pair.h" +#endif +#endif + +char DEX_baseaddr[64],DEX_reladdr[64]; +struct mmpending_order +{ + double price,volume; + int32_t dir; + uint32_t pending,completed,canceled,cancelstarted,reported; + cJSON *errorjson; + char exchange[16],base[65],rel[65],orderid[64]; +} *Pending_orders; +int32_t Num_Pending; + +#define IGUANA_URL "http://127.0.0.1:7778" + +/*char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies + "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies +};*/ +double PAXPRICES[sizeof(CURRENCIES)/sizeof(*CURRENCIES)]; +uint32_t PAXACTIVE; + +char *DEX_swapstatus() +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"getswaplist\"}"); + return(bitcoind_RPC(0,"InstantDEX",url,0,"getswaplist",postdata,0)); +} + +char *DEX_amlp(char *blocktrail) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"amlp\",\"blocktrail\":\"%s\"}",blocktrail); + return(bitcoind_RPC(0,"tradebot",url,0,"amlp",postdata,0)); +} + +char *DEX_openorders(char *exchange) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"openorders\",\"exchange\":\"%s\"}",exchange); + return(bitcoind_RPC(0,"InstantDEX",url,0,"openorders",postdata,0)); +} + +char *DEX_tradehistory(char *exchange) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"tradehistory\",\"exchange\":\"%s\"}",exchange); + return(bitcoind_RPC(0,"InstantDEX",url,0,"tradehistory",postdata,0)); +} + +char *DEX_orderstatus(char *exchange,char *orderid) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid); + return(bitcoind_RPC(0,"InstantDEX",url,0,"orderstatus",postdata,0)); +} + +char *DEX_cancelorder(char *exchange,char *orderid) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"exchange\":\"%s\",\"orderid\":\"%s\"}",exchange,orderid); + return(bitcoind_RPC(0,"InstantDEX",url,0,"cancelorder",postdata,0)); +} + +char *DEX_balance(char *exchange,char *base,char *coinaddr) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + if ( strcmp(exchange,"DEX") == 0 ) + { + sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"%s\",\"symbol\":\"%s\"}",coinaddr,base); + return(bitcoind_RPC(0,"dex",url,0,"getbalance",postdata,0)); + } + else + { + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"balance\",\"exchange\":\"%s\",\"base\":\"%s\"}",exchange,base); + return(bitcoind_RPC(0,"InstantDEX",url,0,"balance",postdata,0)); + } +} + +char *DEX_apikeypair(char *exchange,char *apikey,char *apisecret) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"apikeypair\",\"exchange\":\"%s\",\"apikey\":\"%s\",\"apisecret\":\"%s\"}",exchange,apikey,apisecret); + return(bitcoind_RPC(0,"InstantDEX",url,0,"apikeypair",postdata,0)); +} + +char *DEX_setuserid(char *exchange,char *userid,char *tradepassword) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"setuserid\",\"exchange\":\"%s\",\"userid\":\"%s\",\"tradepassword\":\"%s\"}",exchange,userid,tradepassword); + return(bitcoind_RPC(0,"InstantDEX",url,0,"setuserid",postdata,0)); +} + +char *DEX_trade(char *exchange,char *base,char *rel,int32_t dir,double price,double volume) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"exchange\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"price\":%.8f,\"volume\":%.8f,\"dotrade\":1}",dir>0?"buy":"sell",exchange,base,rel,price,volume); + //printf("DEX_trade.(%s)\n",postdata); + return(bitcoind_RPC(0,"InstantDEX",url,0,dir>0?"buy":"sell",postdata,0)); +} + +char *DEX_withdraw(char *exchange,char *base,char *destaddr,double amount) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"InstantDEX\",\"method\":\"withdraw\",\"exchange\":\"%s\",\"destaddr\":\"%s\",\"amount\":%.8f}",exchange,destaddr,amount); + return(bitcoind_RPC(0,"InstantDEX",url,0,"withdraw",postdata,0)); +} + +char *iguana_walletpassphrase(char *passphrase,int32_t timeout) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/coin=KMD&agent=bitcoinrpc&method=walletpassphrase?",IGUANA_URL); + sprintf(postdata,"[\"%s\", %d]",passphrase,timeout); + return(bitcoind_RPC(0,"",url,0,"walletpassphrase",postdata,0)); +} + +/*char *iguana_listunspent(char *coin,char *coinaddr) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/coin=%s&agent=bitcoinrpc&method=listunspent?",IGUANA_URL,coin); + sprintf(postdata,"[\"%s\"]",coinaddr); + return(bitcoind_RPC(0,"",url,0,"listunspent",postdata)); +}*/ + +/*char *issue_LP_intro(char *destip,uint16_t destport,char *ipaddr,uint16_t port,int32_t numpeers) +{ + char url[512]; + sprintf(url,"http://%s:%u/api/stats/intro?ipaddr=%s&port=%u&numpeers=%d",destip,destport,ipaddr,port,numpeers); + printf("(%s)\n",url); + return(issue_curl(url)); +}*/ + +// +// http://127.0.0.1:7779/api/stats/getpeers + +char *DEX_listunspent(char *coin,char *coinaddr) +{ + char url[512],postdata[1024]; + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"%s\",\"symbol\":\"%s\",\"timeout\":60000}",coinaddr,coin); + return(bitcoind_RPC(0,"dex",url,0,"listunspent",postdata,0)); +} + +bits256 iguana_wif2privkey(char *wifstr) +{ + char url[512],postdata[1024],*retstr,*privstr; bits256 privkey; cJSON *retjson; + memset(privkey.bytes,0,sizeof(privkey)); + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"SuperNET\",\"method\":\"wif2priv\",\"wif\":\"%s\"}",wifstr); + if ( (retstr= bitcoind_RPC(0,"SuperNET",url,0,"wif2priv",postdata,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (privstr= jstr(retjson,"privkey")) != 0 ) + { + if ( strlen(privstr) == 64 ) + decode_hex(privkey.bytes,32,privstr); + } + free_json(retjson); + } + free(retstr); + } + return(privkey); +} + +double bittrex_balance(char *base,char *coinaddr) +{ + char *retstr; cJSON *retjson; double balance = 0.; + if ( (retstr= DEX_balance("bittrex",base,coinaddr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + balance = jdouble(retjson,"balance"); + free_json(retjson); + } + free(retstr); + } + return(balance); +} + +double dex_balance(char *base,char *coinaddr) +{ + char *retstr; cJSON *retjson; double balance = 0.; + if ( (retstr= DEX_balance("DEX",base,coinaddr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + balance = jdouble(retjson,"balance"); + free_json(retjson); + } + free(retstr); + } + return(balance); +} + +int32_t komodo_baseid(char *base) +{ + int32_t i; + for (i=0; i 0 ) + { + for (i=0; i SMALLVAL && (name= jstr(item,"name")) != 0 && strncmp(name,"USD/",4) == 0 ) + { + if ( (baseid= komodo_baseid(name+4)) >= 0 && baseid < 32 ) + { + if ( ((1LL << baseid) & mask) == 0 ) + { + _marketmaker_fiatupdate(baseid,price); + mask |= (1LL << baseid); + } else if ( fabs(price*PAXPRICES[0] - PAXPRICES[baseid]) > SMALLVAL ) + printf("DUPLICATE PRICE? %s %.8f vs %.8f\n",name+4,price*PAXPRICES[0],PAXPRICES[baseid]); + } + } + } + } + } + printf("pax mask.%x\n",(uint32_t)mask); + return((uint32_t)mask); +} + +void marketmaker_cancel(struct mmpending_order *ptr) +{ + char *retstr; cJSON *retjson; + if ( ptr->pending != 0 && ptr->cancelstarted == 0 ) + { + ptr->cancelstarted = (uint32_t)time(NULL); + if ( (retstr= DEX_cancelorder(ptr->exchange,ptr->orderid)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + printf("cancel %s (%s/%s) %.8f vol %.8f dir.%d -> (%s)\n",ptr->exchange,ptr->base,ptr->rel,ptr->price,ptr->volume,ptr->dir,jprint(retjson,0)); + free_json(retjson); + ptr->pending = 0; + ptr->canceled = (uint32_t)time(NULL); + } + free(retstr); + } + } +} + +void marketmaker_queue(char *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *retjson) +{ + struct mmpending_order *ptr; char *orderid; + //DEX_trade.({"success":true,"message":"","result":{"uuid":"d5faa9e4-660d-436f-a257-2c6a40442d8c"},"tag":"11271578410079391025"} + if ( is_cJSON_True(jobj(retjson,"success")) != 0 && jobj(retjson,"result") != 0 ) + retjson = jobj(retjson,"result"); + printf("QUEUE.%s %s/%s dir.%d %.8f %.6f (%s)\n",exchange,base,rel,dir,price,volume,jprint(retjson,0)); + Pending_orders = realloc(Pending_orders,(1 + Num_Pending) * sizeof(*Pending_orders)); + ptr = &Pending_orders[Num_Pending++]; + memset(ptr,0,sizeof(*ptr)); + ptr->price = price; + ptr->volume = volume; + ptr->dir = dir; + ptr->pending = (uint32_t)time(NULL); + strcpy(ptr->exchange,exchange); + strcpy(ptr->base,base); + strcpy(ptr->rel,rel); + if ( (orderid= jstr(retjson,"OrderUuid")) != 0 || (orderid= jstr(retjson,"uuid")) != 0 ) + strcpy(ptr->orderid,orderid); + else strcpy(ptr->orderid,"0"); +} + +void marketmaker_pendingupdate(char *exchange,char *base,char *rel) +{ + char *retstr; cJSON *retjson,*obj; int32_t i; struct mmpending_order *ptr; + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( ptr->completed == 0 && (retstr= DEX_orderstatus(exchange,ptr->orderid)) != 0 ) + { + //printf("%s status.(%s)\n",ptr->orderid,retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + obj = jobj(retjson,"result"); + if ( is_cJSON_Array(obj) != 0 ) + obj = jitem(retjson,0); + if ( jdouble(obj,"QuantityRemaining") == 0. || is_cJSON_True(jobj(obj,"IsOpen")) == 0 ) + { +//{"Uuid":null,"OrderUuid":"e7b0789c-0c4e-413b-a768-3d5734d9cbe5","Exchange":"BTC-KMD","OrderType":"LIMIT_SELL","Quantity":877.77700000,"QuantityRemaining":462.50512234,"Limit":0.00011770,"CommissionPaid":0.00012219,"Price":0.04887750,"PricePerUnit":0.00011769,"Opened":"2017-02-20T13:16:22.29","Closed":null,"CancelInitiated":false,"ImmediateOrCancel":false,"IsConditional":false,"Condition":"NONE","ConditionTarget":null} printf("uuid.(%s) finished.(%s)\n",ptr->orderid,jprint(retjson,0)); + ptr->completed = (uint32_t)time(NULL); + ptr->pending = 0; + } + free_json(retjson); + } + free(retstr); + } + } +} + +void marketmaker_pendinginit(char *exchange,char *base,char *rel) +{ + char *retstr,*orderid,*pairstr,relbase[65]; cJSON *retjson,*array,*item; int32_t i,j,n,dir; struct mmpending_order *ptr; + sprintf(relbase,"%s-%s",rel,base); + if ( (retstr= DEX_openorders(exchange)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("%s\n",jprint(retjson,0)); + if ( is_cJSON_True(jobj(retjson,"success")) != 0 && (array= jarray(&n,retjson,"result")) != 0 ) + { + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( strcmp(ptr->orderid,orderid) == 0 ) + { + ptr->pending = (uint32_t)time(NULL); + ptr->completed = 0; + printf("%s pending\n",orderid); + break; + } + } + if ( j == Num_Pending ) + { + if ( jstr(item,"OrderType") != 0 ) + { + if ( strcmp(jstr(item,"OrderType"),"LIMIT_BUY") == 0 ) + dir = 1; + else if ( strcmp(jstr(item,"OrderType"),"LIMIT_SELL") == 0 ) + dir = -1; + else dir = 0; + if ( dir != 0 ) + marketmaker_queue(exchange,base,rel,dir,jdouble(item,"Limit"),jdouble(item,"QuantityRemaining"),item); + else printf("no dir (%s) (%s)\n",jprint(item,0),jstr(item,"OrderType")); + } + } + } + } + } + free_json(retjson); + } + free(retstr); + } +} + +double marketmaker_filled(char *exchange,char *base,char *rel,double *buyvolp,double *sellvolp,double *pendingbidsp,double *pendingasksp) +{ + double pricesum = 0.,volsum = 0.; struct mmpending_order *ptr; int32_t i; + *pendingbidsp = *pendingasksp = 0.; + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( ptr->completed != 0 ) + { + if ( ptr->reported == 0 ) + { + if ( ptr->dir > 0 ) + (*buyvolp) += ptr->volume; + else if ( ptr->dir < 0 ) + (*sellvolp) += ptr->volume; + pricesum += ptr->volume * ptr->price; + volsum += ptr->volume; + ptr->reported = (uint32_t)time(NULL); + printf("REPORT dir.%d vol %.8f\n",ptr->dir,ptr->volume); + } + } + else if ( ptr->pending != 0 ) // alternative is error or cancelled + { + if ( ptr->dir > 0 ) + (*pendingbidsp) += ptr->volume; + else if ( ptr->dir < 0 ) + (*pendingasksp) += ptr->volume; + } + } + if ( volsum != 0. ) + pricesum /= volsum; + return(pricesum); +} + +int32_t marketmaker_prune(char *exchange,char *base,char *rel,int32_t polarity,double bid,double ask,double separation) +{ + int32_t i,n = 0; struct mmpending_order *ptr; + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( ptr->pending != 0 && ptr->cancelstarted == 0 ) + { + if ( polarity != 0 ) + { + if ( ((ptr->dir*polarity > 0 && ptr->price < bid-separation) || (ptr->dir*polarity < 0 && ptr->price > ask+separation)) ) + { + printf("polarity.%d dir.%d price.%f bid.%f ask.%f\n",polarity,ptr->dir,ptr->price,bid,ask); + marketmaker_cancel(ptr), n++; + } + } + /*else + {,*prunebid=0,*pruneask=0; double lowbid=0.,highask=0. + if ( ptr->dir > 0 && (lowbid == 0. || ptr->price < lowbid) ) + { + lowbid = ptr->price; + prunebid = ptr; + } + else if ( ptr->dir < 0 && (highask == 0. || ptr->price > highask) ) + { + highask = ptr->price; + pruneask = ptr; + } + }*/ + } + } + /*if ( polarity == 0 ) + { + if ( prunebid != 0 && fabs(prunebid->price - bid) > separation ) + marketmaker_cancel(prunebid), n++; + if ( pruneask != 0 && fabs(pruneask->price - ask) > separation ) + marketmaker_cancel(pruneask), n++; + }*/ + return(n); +} + +void marketmaker_volumeset(double *bidincrp,double *askincrp,double incr,double buyvol,double pendingbids,double sellvol,double pendingasks,double maxexposure) +{ + *bidincrp = *askincrp = incr; + //if ( pendingbids >= pendingasks+maxexposure ) + // *bidincrp = 0.; + //else if ( pendingasks >= pendingbids+maxexposure ) + // *askincrp = 0.; + if ( *bidincrp > 0. && pendingbids + *bidincrp > maxexposure ) + *bidincrp = (maxexposure - *bidincrp); + if ( *askincrp > 0. && pendingasks + *askincrp > maxexposure ) + *askincrp = (maxexposure - *askincrp); + if ( *bidincrp < 0. ) + *bidincrp = 0.; + if ( *askincrp < 0. ) + *askincrp = 0.; +} + +int32_t marketmaker_spread(char *exchange,char *base,char *rel,double bid,double bidvol,double ask,double askvol,double separation) +{ + int32_t nearflags[2],i,n = 0; struct mmpending_order *ptr; cJSON *retjson,*vals; char *retstr,postdata[1024],url[128]; double vol,spread_ratio; + memset(nearflags,0,sizeof(nearflags)); + if ( strcmp("DEX",exchange) != 0 ) + { + for (i=0; iexchange) != 0 || strcmp(base,ptr->base) != 0 || strcmp(rel,ptr->rel) != 0 ) + continue; + if ( ptr->pending != 0 && ptr->cancelstarted == 0 ) + { + if ( bid > SMALLVAL && bidvol > SMALLVAL && ptr->dir > 0 && fabs(bid - ptr->price) < separation ) + { + //printf("bid %.8f near %.8f\n",bid,ptr->price); + nearflags[0]++; + } + if ( ask > SMALLVAL && askvol > SMALLVAL && ptr->dir < 0 && fabs(ask - ptr->price) < separation ) + { + //printf("%.8f near %.8f\n",ask,ptr->price); + nearflags[1]++; + } + } + } + } + //printf("spread.%s (%.8f %.6f) (%.8f %.6f)\n",exchange,bid,bidvol,ask,askvol); + if ( bid > SMALLVAL && bidvol > SMALLVAL && nearflags[0] == 0 ) + { + if ( strcmp("DEX",exchange) == 0 && strcmp(base,"KMD") == 0 && strcmp(rel,"BTC") == 0 ) + { + if ( ask > SMALLVAL && askvol > SMALLVAL ) + { + /*li.profit = jdouble(vals,"profit"); + li.refprice = jdouble(vals,"refprice"); + li.bid = jdouble(vals,"bid"); + li.ask = jdouble(vals,"ask"); + if ( (li.minvol= jdouble(vals,"minvol")) <= 0. ) + li.minvol = (strcmp("BTC",base) == 0) ? 0.0001 : 0.001; + if ( (li.maxvol= jdouble(vals,"maxvol")) < li.minvol ) + li.maxvol = li.minvol;*/ + //curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MVP\",\"vals\":{\"rel\":\"USD\",\"bid\":0.09,\"ask\":0.11,\"maxvol\":100}}" + vals = cJSON_CreateObject(); + jaddstr(vals,"rel","BTC"); + jaddnum(vals,"bid",bid); + jaddnum(vals,"ask",ask); + vol = bidvol > askvol ? askvol : bidvol; + jaddnum(vals,"maxvol",vol); + jaddnum(vals,"minvol",vol*0.1 > 100 ? 100 : vol * 0.1); + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}",base,jprint(vals,1)); + //printf("(%s)\n",postdata); + if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 ) + { + //printf("(%s) -> (%s)\n",postdata,retstr); + free(retstr); + } + spread_ratio = .5 * ((ask - bid) / (bid + ask)); + for (i=0; i SMALLVAL ) + { + vals = cJSON_CreateObject(); + jaddstr(vals,"rel",CURRENCIES[i]); + jaddnum(vals,"bid",PAXPRICES[i] * (1. - spread_ratio)); + jaddnum(vals,"ask",PAXPRICES[i] * (1. + spread_ratio)); + jaddnum(vals,"maxvol",vol * PAXPRICES[i]); + jaddnum(vals,"minvol",MAX(1,(int32_t)(vol * 0.01 * PAXPRICES[i]))); + sprintf(url,"%s/?",IGUANA_URL); + sprintf(postdata,"{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"%s\",\"vals\":%s}","KMD",jprint(vals,1)); + if ( (retstr= bitcoind_RPC(0,"tradebot",url,0,"liqudity",postdata,0)) != 0 ) + { + //printf("(%s) -> (%s)\n",postdata,retstr); + free(retstr); + } + } +//break; + } + } else printf("unsupported ask only for DEX %s/%s\n",base,rel); + } + else if ( (retstr= DEX_trade(exchange,base,rel,1,bid,bidvol)) != 0 ) + { + //printf("DEX_trade.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + marketmaker_queue(exchange,base,rel,1,bid,bidvol,retjson); + free_json(retjson); + } + free(retstr); + } //else printf("skip bid %s %.8f vol %f\n",exchange,bid,bidvol); + } + if ( ask > SMALLVAL && askvol > SMALLVAL && nearflags[1] == 0 && strcmp("DEX",exchange) != 0 ) + { + if ( (retstr= DEX_trade(exchange,base,rel,-1,ask,askvol)) != 0 ) + { + //printf("DEX_trade.(%s)\n",retstr); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + marketmaker_queue(exchange,base,rel,-1,ask,askvol,retjson); + free_json(retjson); + } + free(retstr); + } + } //else printf("skip ask %s %.8f vol %f\n",exchange,bid,bidvol); + return(n); +} + +double marketmaker_updateprice(char *name,char *base,char *rel,double theoretical,double *incrp) +{ + static uint32_t counter; + cJSON *fiatjson; double USD_average=0.,usdprice=0.,CMC_average=0.,avebid=0.,aveask=0.,val,changes[3],highbid=0.,lowask=0.; + if ( (val= get_theoretical(&avebid,&aveask,&highbid,&lowask,&CMC_average,changes,name,base,rel,&USD_average)) != 0. ) + { + if ( theoretical == 0. ) + { + theoretical = val; + if ( *incrp > 2 ) + { + *incrp = (int32_t)*incrp; + *incrp += 0.777; + } + } else theoretical = (theoretical + val) * 0.5; + if ( (counter++ % 12) == 0 ) + { + if ( USD_average > SMALLVAL && CMC_average > SMALLVAL && theoretical > SMALLVAL ) + { + usdprice = USD_average * (theoretical / CMC_average); + printf("USD %.4f <- (%.6f * (%.8f / %.8f))\n",usdprice,USD_average,theoretical,CMC_average); + PAXPRICES[0] = usdprice; + if ( (fiatjson= yahoo_allcurrencies()) != 0 ) + { + marketmaker_fiatupdate(fiatjson); + free_json(fiatjson); + } + } + } + LP_priceupdate(base,rel,theoretical,avebid,aveask,highbid,lowask,PAXPRICES); + } + return(theoretical); +} + +void marketmaker(double minask,double maxbid,char *baseaddr,char *reladdr,double start_BASE,double start_REL,double profitmargin,double maxexposure,double ratioincr,char *exchange,char *name,char *base,char *rel) +{ + char *retstr; double bid,ask,start_DEXbase,start_DEXrel,DEX_base = 0.,DEX_rel = 0.,balance_base=0.,balance_rel=0.,mmbid,mmask,aveprice,incr,pendingbids,pendingasks,buyvol,sellvol,bidincr,askincr,filledprice,avebid=0.,aveask=0.,highbid=0.,lowask=0.,theoretical = 0.; uint32_t lasttime = 0; + incr = maxexposure * ratioincr; + buyvol = sellvol = 0.; + start_DEXbase = dex_balance(base,baseaddr); + start_DEXrel = dex_balance(rel,reladdr); + while ( 1 ) + { + if ( time(NULL) > lasttime+60 ) + { + if ( (theoretical= marketmaker_updateprice(name,base,rel,theoretical,&incr)) != 0. ) + { + if ( lasttime == 0 ) + maxexposure /= theoretical; + } + if ( strcmp(exchange,"bittrex") == 0 ) + { + balance_base = bittrex_balance(base,""); + balance_rel = bittrex_balance(rel,""); + DEX_base = dex_balance(base,baseaddr); + DEX_rel = dex_balance(rel,reladdr); + } else printf("add support for %s balance\n",exchange); + lasttime = (uint32_t)time(NULL); + } + marketmaker_pendingupdate(exchange,base,rel); + if ( theoretical > SMALLVAL && avebid > SMALLVAL && aveask > SMALLVAL ) + { + aveprice = (avebid + aveask) * 0.5; + // if order is filled, theoretical <- filled (theoretical + price)/2 + if ( (filledprice= marketmaker_filled(exchange,base,rel,&buyvol,&sellvol,&pendingbids,&pendingasks)) != 0. ) + theoretical = (theoretical + filledprice) * 0.5; + buyvol = sellvol = 0; + if ( (balance_base + DEX_base) < (start_BASE + start_DEXbase) ) + sellvol += ((start_BASE + start_DEXbase) - (balance_base + DEX_base)); + else buyvol += ((balance_base + DEX_base) - (start_BASE + start_DEXbase)); + if ( (balance_rel + DEX_rel) < (start_REL + start_DEXrel) ) + buyvol += ((start_REL + start_DEXrel) - (balance_rel + DEX_rel)) / theoretical; + else sellvol += ((balance_rel + DEX_rel) - (start_REL + start_DEXrel)) / theoretical; + mmbid = theoretical - theoretical*profitmargin; + mmask = theoretical + theoretical*profitmargin; + // if any existing order exceeds double margin distance, cancel + marketmaker_prune(exchange,base,rel,1,mmbid - theoretical*profitmargin,mmask + theoretical*profitmargin,0.); + // if new prices crosses existing order, cancel old order first + marketmaker_prune(exchange,base,rel,-1,mmbid,mmask,0.); + //printf("(%.8f %.8f) ",mmbid,mmask); + if ( (1) ) + { + if ( mmbid >= lowask || (maxbid > SMALLVAL && mmbid > maxbid) ) //mmbid < highbid || + { + printf("clear mmbid %.8f lowask %.8f maxbid %.8f\n",mmbid,lowask,maxbid); + mmbid = 0.; + } + if ( mmask <= highbid || (minask > SMALLVAL && mmask < minask) ) // mmask > lowask || + mmask = 0.; + } + marketmaker_volumeset(&bidincr,&askincr,incr,buyvol,pendingbids,sellvol,pendingasks,maxexposure); + printf("AVE.(%.8f %.8f) hbla %.8f %.8f bid %.8f ask %.8f theory %.8f buys.(%.6f %.6f) sells.(%.6f %.6f) incr.(%.6f %.6f) balances.(%.8f + %.8f, %.8f + %.8f) test %f\n",avebid,aveask,highbid,lowask,mmbid,mmask,theoretical,buyvol,pendingbids,sellvol,pendingasks,bidincr,askincr,balance_base,DEX_base,balance_rel,DEX_rel,(aveask - avebid)/aveprice); + if ( (retstr= DEX_swapstatus()) != 0 ) + printf("%s\n",retstr), free(retstr); + printf("%s %s %s, %s %s %s\n",base,DEX_baseaddr,DEX_balance("DEX",base,DEX_baseaddr),rel,DEX_reladdr,DEX_balance("DEX",rel,DEX_reladdr)); + if ( (aveask - avebid)/aveprice > profitmargin ) + bid = highbid * (1 - profitmargin), ask = lowask * (1 + profitmargin); + else bid = avebid - profitmargin*aveprice, ask = avebid + profitmargin*aveprice; + marketmaker_spread("DEX",base,rel,bid,incr,ask,incr,profitmargin*aveprice*0.5); + if ( (pendingbids + buyvol) > (pendingasks + sellvol) && (pendingbids + buyvol) > bidincr ) + { + bidincr *= ((double)(pendingasks + sellvol) / ((pendingbids + buyvol) + (pendingasks + sellvol))); + printf("bidincr %f buy.(%f + %f) sell.(%f + %f)\n",bidincr,pendingbids,buyvol,pendingasks,sellvol); + if ( bidincr < 0.1*incr ) + bidincr = 0.1*incr; + if ( bidincr > 1. ) + bidincr = (int32_t)bidincr + 0.777; + } + if ( (pendingbids + buyvol) < (pendingasks + sellvol) && (pendingasks + sellvol) > askincr ) + { + askincr *= (double)(pendingbids + buyvol) / ((pendingbids + buyvol) + (pendingasks + sellvol)); + if ( askincr < 0.1*incr ) + askincr = 0.1*incr; + if ( askincr > 1. ) + askincr = (int32_t)askincr + 0.777; + } + //printf("mmbid %.8f %.6f, mmask %.8f %.6f\n",mmbid,bidincr,mmask,askincr); + marketmaker_spread(exchange,base,rel,mmbid,bidincr,mmask,askincr,profitmargin*aveprice*0.5); + sleep(60); + } + } +} + +#include "LP_nativeDEX.c" + +void LP_main(void *ptr) +{ + char *passphrase; double profitmargin; uint16_t port; cJSON *argjson = ptr; + if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) + { + profitmargin = jdouble(argjson,"profitmargin"); + LP_profitratio += profitmargin; + if ( (port= juint(argjson,"rpcport")) < 1000 ) + port = LP_RPCPORT; + LPinit(port,LP_RPCPORT+10,LP_RPCPORT+20,LP_RPCPORT+30,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson); + } +} + +int main(int argc, const char * argv[]) +{ + char dirname[512],*base,*rel,*name,*exchange,*apikey,*apisecret,*blocktrail,*retstr,*baseaddr,*reladdr,*passphrase; + double profitmargin,maxexposure,incrratio,start_rel,start_base,minask,maxbid,incr; + cJSON *retjson,*loginjson; int32_t i; + OS_init(); + if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 ) + { + uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64]; + bitcoin_addr2rmd160(0,&addrtype,rmd160,(char *)argv[1]); + if ( addrtype == 0 ) + { + bitcoin_address(coinaddr,0,60,rmd160,20); + bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr); + bitcoin_address(coinaddr2,0,0,rmd160b,20); + } + else if ( addrtype == 60 ) + { + bitcoin_address(coinaddr,0,0,rmd160,20); + bitcoin_addr2rmd160(0,&addrtype,rmd160b,coinaddr); + bitcoin_address(coinaddr2,0,60,rmd160b,20); + } + printf("(%s) -> %s -> %s\n",(char *)argv[1],coinaddr,coinaddr2); + if ( strcmp((char *)argv[1],coinaddr2) != 0 ) + printf("ERROR\n"); + exit(0); + } + sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/PRICES",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/UNSPENTS",GLOBAL_DBDIR), OS_ensure_directory(dirname); +#ifdef FROM_JS + argc = 2; + retjson = cJSON_Parse("{\"client\":1,\"passphrase\":\"test\"}"); + printf("calling LP_main(%s)\n",jprint(retjson,0)); + LP_main(retjson); + emscripten_set_main_loop(LP_fromjs_iter,1,0); +#else + if ( argc == 1 ) + { + LP_NXT_redeems(); + sleep(3); + return(0); + } + if ( argc > 1 && (retjson= cJSON_Parse(argv[1])) != 0 ) + { + if ( jint(retjson,"docker") == 1 ) + DOCKERFLAG = 1; + else if ( jstr(retjson,"docker") != 0 ) + DOCKERFLAG = (uint32_t)calc_ipbits(jstr(retjson,"docker")); + if ( (passphrase= jstr(retjson,"passphrase")) == 0 ) + jaddstr(retjson,"passphrase","test"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_main,(void *)retjson) != 0 ) + { + printf("error launching LP_main (%s)\n",jprint(retjson,0)); + exit(-1); + } //else printf("(%s) launched.(%s)\n",argv[1],passphrase); + incr = 100.; + while ( (1) ) + sleep(100000); + profitmargin = jdouble(retjson,"profitmargin"); + minask = jdouble(retjson,"minask"); + maxbid = jdouble(retjson,"maxbid"); + maxexposure = jdouble(retjson,"maxexposure"); + incrratio = jdouble(retjson,"lotratio"); + start_base = jdouble(retjson,"start_base"); + start_rel = jdouble(retjson,"start_rel"); + apikey = jstr(retjson,"apikey"); + apisecret = jstr(retjson,"apisecret"); + base = jstr(retjson,"base"); + name = jstr(retjson,"name"); + rel = jstr(retjson,"rel"); + blocktrail = jstr(retjson,"blocktrail"); + exchange = jstr(retjson,"exchange"); + PAXACTIVE = juint(retjson,"paxactive"); + if ( profitmargin < 0. || maxexposure <= 0. || incrratio <= 0. || apikey == 0 || apisecret == 0 || base == 0 || name == 0 || rel == 0 || exchange == 0 || blocktrail == 0 ) + { + printf("illegal parameter (%s)\n",jprint(retjson,0)); + exit(-1); + } + if ( (retstr= iguana_walletpassphrase(passphrase,999999)) != 0 ) + { + printf("(%s/%s) login.(%s)\n",base,rel,retstr); + if ( (loginjson= cJSON_Parse(retstr)) != 0 ) + { + if ( PAXACTIVE != 0 ) + { + for (i=0; i<32; i++) + { + if ( ((1< +#include +#ifndef NATIVE_WINDOWS +#include "OS_portable.h" +#else +#include "../../crypto777/OS_portable.h" +#endif // !_WIN_32 + +uint32_t DOCKERFLAG; +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); +#include "stats.c" +void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]); + +//defined(__APPLE__) || +#ifdef FROM_JS // defined(WIN32) || defined(USE_STATIC_NANOMSG) +#include "../../crypto777/nanosrc/nn.h" +#include "../../crypto777/nanosrc/bus.h" +#include "../../crypto777/nanosrc/pubsub.h" +#include "../../crypto777/nanosrc/pipeline.h" +#include "../../crypto777/nanosrc/reqrep.h" +#include "../../crypto777/nanosrc/tcp.h" +#include "../../crypto777/nanosrc/pair.h" +#else +#if defined(WIN32) || defined(USE_STATIC_NANOMSG) + #include "../../crypto777/nanosrc/nn.h" + #include "../../crypto777/nanosrc/bus.h" + #include "../../crypto777/nanosrc/pubsub.h" + #include "../../crypto777/nanosrc/pipeline.h" + #include "../../crypto777/nanosrc/reqrep.h" + #include "../../crypto777/nanosrc/tcp.h" + #include "../../crypto777/nanosrc/pair.h" +#else + #include "/usr/local/include/nanomsg/nn.h" + #include "/usr/local/include/nanomsg/bus.h" + #include "/usr/local/include/nanomsg/pubsub.h" + #include "/usr/local/include/nanomsg/pipeline.h" + #include "/usr/local/include/nanomsg/reqrep.h" + #include "/usr/local/include/nanomsg/tcp.h" + #include "/usr/local/include/nanomsg/pair.h" +#endif +#endif + + +#include "LP_nativeDEX.c" + +void LP_ports(uint16_t *pullportp,uint16_t *pubportp,uint16_t *busportp,uint16_t netid) +{ + int32_t netmod,netdiv; uint16_t otherports; + *pullportp = *pubportp = *busportp = 0; + if ( netid < 0 ) + netid = 0; + else if ( netid > (65535-40-LP_RPCPORT)/4 ) + { + printf("netid.%d overflow vs max netid.%d 14420?\n",netid,(65535-40-LP_RPCPORT)/4); + exit(-1); + } + if ( netid != 0 ) + { + netmod = (netid % 10); + netdiv = (netid / 10); + otherports = (netdiv * 40) + (LP_RPCPORT + netmod); + } else otherports = LP_RPCPORT; + *pullportp = otherports + 10; + *pubportp = otherports + 20; + *busportp = otherports + 30; + printf("RPCport.%d remoteport.%d, nanoports %d %d %d\n",RPC_port,RPC_port-1,*pullportp,*pubportp,*busportp); +} + +void LP_main(void *ptr) +{ + char *passphrase; double profitmargin; uint16_t netid=0,port,pullport,pubport,busport; cJSON *argjson = ptr; + if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) + { + profitmargin = jdouble(argjson,"profitmargin"); + LP_profitratio += profitmargin; + if ( (port= juint(argjson,"rpcport")) < 1000 ) + port = LP_RPCPORT; + if ( jobj(argjson,"netid") != 0 ) + netid = juint(argjson,"netid"); + LP_ports(&pullport,&pubport,&busport,netid); + LPinit(port,pullport,pubport,busport,passphrase,jint(argjson,"client"),jstr(argjson,"userhome"),argjson); + } +} + +int main(int argc, const char * argv[]) +{ + char dirname[512],*passphrase; double incr; cJSON *retjson; + OS_init(); + if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 ) + { + uint8_t addrtype,rmd160[20],rmd160b[20]; char coinaddr[64],coinaddr2[64]; + bitcoin_addr2rmd160("BTC",0,&addrtype,rmd160,(char *)argv[1]); + if ( addrtype == 0 ) + { + bitcoin_address("KMD",coinaddr,0,60,rmd160,20); + bitcoin_addr2rmd160("KMD",0,&addrtype,rmd160b,coinaddr); + bitcoin_address("BTC",coinaddr2,0,0,rmd160b,20); + } + else if ( addrtype == 60 ) + { + bitcoin_address("BTC",coinaddr,0,0,rmd160,20); + bitcoin_addr2rmd160("BTC",0,&addrtype,rmd160b,coinaddr); + bitcoin_address("KMD",coinaddr2,0,60,rmd160b,20); + } + printf("(%s) -> %s -> %s\n",(char *)argv[1],coinaddr,coinaddr2); + if ( strcmp((char *)argv[1],coinaddr2) != 0 ) + printf("ERROR\n"); + exit(0); + } + else if ( argv[1] != 0 && strcmp(argv[1],"hush") == 0 ) + { + uint32_t timestamp; char str[65],wifstr[128]; bits256 privkey; int32_t i; + timestamp = (uint32_t)time(NULL); + //printf("start hush vanitygen t.%u\n",timestamp); + for (i=0; i<1000000000; i++) + { + OS_randombytes(privkey.bytes,sizeof(privkey)); + privkey.bytes[0] = 0x0e; + privkey.bytes[1] = 0x5b; + privkey.bytes[2] = 0xf9; + privkey.bytes[3] = 0xc6; + privkey.bytes[4] = 0x06; + privkey.bytes[5] = 0xdd; + privkey.bytes[6] = 0xbb; + bitcoin_priv2wiflong("HUSH",0xab,wifstr,privkey,0x36); + if ( wifstr[2] == 'x' && wifstr[4] == 'H' && wifstr[5] == 'u' && wifstr[6] == 's' )//&& wifstr[3] == 'x' ) + { + if ( wifstr[7] == 'h' && wifstr[8] == 'L' && wifstr[9] == 'i' ) + { + //printf("i.%d %s -> wif.%s\n",i,bits256_str(str,privkey),wifstr); + if ( wifstr[10] == 's' && wifstr[11] == 't' ) + { + printf("{\"iters\":%d,\"privkey\":\"%s\",\"wif\":\"%s\"}\n",i,bits256_str(str,privkey),wifstr); + break; + } + } + } //else printf("failed %s\n",wifstr); + } + //printf("done hush vanitygen done %u elapsed %d\n",(uint32_t)time(NULL),(uint32_t)time(NULL) - timestamp); + exit(0); + } + else if ( argv[1] != 0 && strcmp(argv[1],"vanity") == 0 && argv[2] != 0 ) + { + uint32_t timestamp; uint8_t pubkey33[33]; char str[65],coinaddr[64],wifstr[128]; bits256 privkey; int32_t i,len; void *ctx; + ctx = bitcoin_ctx(); + len = (int32_t)strlen(argv[2]); + timestamp = (uint32_t)time(NULL); + printf("start vanitygen (%s).%d t.%u\n",argv[2],len,timestamp); + for (i=0; i<1000000000; i++) + { + OS_randombytes(privkey.bytes,sizeof(privkey)); + bitcoin_priv2pub(ctx,"KMD",pubkey33,coinaddr,privkey,0,60); + if ( strncmp(coinaddr+1,argv[2],len-1) == 0 ) + { + bitcoin_priv2wif("KMD",0,wifstr,privkey,188); + printf("i.%d %s -> %s wif.%s\n",i,bits256_str(str,privkey),coinaddr,wifstr); + if ( coinaddr[1+len-1] == argv[2][len-1] ) + break; + } //else printf("failed %s\n",wifstr); + } + printf("done vanitygen.(%s) done %u elapsed %d\n",argv[2],(uint32_t)time(NULL),(uint32_t)time(NULL) - timestamp); + exit(0); + } + else if ( argv[1] != 0 && strcmp(argv[1],"airdropH") == 0 && argv[2] != 0 ) + { + FILE *fp; double val,total = 0.; uint8_t checktype,addrtype,rmd160[21],checkrmd160[21]; char buf[256],checkaddr[64],coinaddr[64],manystrs[64][128],cmd[64*128]; int32_t n,i,num; char *flag; + if ( (fp= fopen(argv[2],"rb")) != 0 ) + { + num = 0; + while ( fgets(buf,sizeof(buf),fp) > 0 ) + { + if ( (n= (int32_t)strlen(buf)) > 0 ) + buf[--n] = 0; + flag = 0; + for (i=0; i (%s).%d -> (%s) %.8f?\n",buf,addrtype,coinaddr,checktype,checkaddr,atof(flag)); + } + else + { + val = atof(flag); + sprintf(manystrs[num++],"\\\"%s\\\":%0.8f",coinaddr,val); + if ( num >= sizeof(manystrs)/sizeof(*manystrs) ) + { + sprintf(cmd,"fiat/btch sendmany \\\"\\\" \"{"); + for (i=0; i 0 ) + { + sprintf(cmd,"fiat/btch sendmany \\\"\\\" \"{"); + for (i=0; i 1 && (retjson= cJSON_Parse(argv[1])) != 0 ) + { + if ( jint(retjson,"docker") == 1 ) + DOCKERFLAG = 1; + else if ( jstr(retjson,"docker") != 0 ) + DOCKERFLAG = (uint32_t)calc_ipbits(jstr(retjson,"docker")); + if ( jobj(retjson,"passphrase") != 0 ) + jdelete(retjson,"passphrase"); + if ( (passphrase= jstr(retjson,"passphrase")) == 0 ) + jaddstr(retjson,"passphrase","default"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)LP_main,(void *)retjson) != 0 ) + { + printf("error launching LP_main (%s)\n",jprint(retjson,0)); + exit(-1); + } //else printf("(%s) launched.(%s)\n",argv[1],passphrase); + incr = 100.; + while ( LP_STOP_RECEIVED == 0 ) + sleep(100000); + } +#endif + return 0; +} diff --git a/iguana/exchanges/mnzservers b/iguana/exchanges/mnzservers new file mode 100755 index 000000000..40f904b49 --- /dev/null +++ b/iguana/exchanges/mnzservers @@ -0,0 +1,12 @@ +#!/bin/bash +source userpass + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"b4a6361506d847817205a8e51374eb129fc33c3b5466235afdbc65f2291ffb4c\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"bd0c69da4ec3ed61613734f9f681f846fde5d8efc894c82dafbeeb7a01844872\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"8f7782b532808a30a1fe6ffc1fa3c55fea6d734f000763fa88d42ccfed60d213\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"d80a74847cd60899afdd673570f8b698e4089e5ad4d6e9e205b5e5891ec0c84f\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"322e236db07484b31aea9400a6f3f5ed972e29c6d4115c63aaedaa541d41e758\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"8579b74435093690d3d7680ecdac0dd1b892dc5ecd4fb603f0e22fd003176342\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"c4e3c95bd9612cce3fe1cfcc0a0e9c625bab7e4b83bc68f0ede73633e6a8c17f\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"43467b51e07fae3b19101fca7fe1bf250d34c8deecfd493c723f87d5eda1a64b\",\"method\":\"trust\",\"trust\":1}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"e900c42a0d883d098f382b59cf5655dd1d92b2c94f6580095a4f6382514f7a59\",\"method\":\"trust\",\"trust\":1}" diff --git a/iguana/exchanges/mshark b/iguana/exchanges/mshark new file mode 100755 index 000000000..ef73ca3cf --- /dev/null +++ b/iguana/exchanges/mshark @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":145}],\"divisor\":1400000}" diff --git a/iguana/exchanges/myprice b/iguana/exchanges/myprice new file mode 100755 index 000000000..6dfac2dbb --- /dev/null +++ b/iguana/exchanges/myprice @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"myprice\",\"base\":\"REVS\",\"rel\":\"KMD\"}" diff --git a/iguana/exchanges/myprices b/iguana/exchanges/myprices new file mode 100755 index 000000000..1c82512c0 --- /dev/null +++ b/iguana/exchanges/myprices @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"myprices\"}" diff --git a/iguana/exchanges/nodeinstall b/iguana/exchanges/nodeinstall new file mode 100644 index 000000000..737de1e99 --- /dev/null +++ b/iguana/exchanges/nodeinstall @@ -0,0 +1,16 @@ +cd /var/www/html/ +node install http-server -g + +#start http-server to start current directory serving via http://127.0.0.1:8080 +http-server . + +node install node-nanomsg + +# test.js +#var nano = require('nanomsg'); +#var sub = nano.socket('sub'); +#var addr = 'ws://5.9.253.197:7785' +#sub.connect(addr); +#sub.on('data', function (buf) { +#console.log(String(buf)); +#}); diff --git a/iguana/exchanges/notarizations b/iguana/exchanges/notarizations new file mode 100755 index 000000000..9484aa5e0 --- /dev/null +++ b/iguana/exchanges/notarizations @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"notarizations\",\"coin\":\"$1\"}" diff --git a/iguana/exchanges/numutxos b/iguana/exchanges/numutxos new file mode 100755 index 000000000..9455dd239 --- /dev/null +++ b/iguana/exchanges/numutxos @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"numutxos\"}" diff --git a/iguana/exchanges/nxtae.c b/iguana/exchanges/nxtae.c index 592532f30..d6fe1080c 100755 --- a/iguana/exchanges/nxtae.c +++ b/iguana/exchanges/nxtae.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,7 +14,7 @@ ******************************************************************************/ #define DEFAULT_NXT_DEADLINE 720 -#define issue_NXTPOST(cmdstr) bitcoind_RPC(0,"curl",myinfo->NXTAPIURL,0,0,cmdstr) +#define issue_NXTPOST(cmdstr) bitcoind_RPC(0,"curl",myinfo->NXTAPIURL,0,0,cmdstr,0) #define NXT_MSTYPE 5 #define NXT_ASSETTYPE 2 #define NXT_GENESISTIME 1385294400 diff --git a/iguana/exchanges/okcoin.c b/iguana/exchanges/okcoin.c index 2ab09f883..af2fe5184 100755 --- a/iguana/exchanges/okcoin.c +++ b/iguana/exchanges/okcoin.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -44,7 +44,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang { fprintf(stderr,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FATAL ERROR OKCOIN.(%s) only supports USD\n",url); printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FATAL ERROR OKCOIN.(%s) only supports USD\n",url); - exit(-1); + //exit(-1); return(0); } return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert)); diff --git a/iguana/exchanges/orderbook b/iguana/exchanges/orderbook new file mode 100755 index 000000000..a61784991 --- /dev/null +++ b/iguana/exchanges/orderbook @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"orderbook\",\"base\":\"REVS\",\"rel\":\"KMD\"}" diff --git a/iguana/exchanges/ordermatch b/iguana/exchanges/ordermatch new file mode 100755 index 000000000..f4b2ca61c --- /dev/null +++ b/iguana/exchanges/ordermatch @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +#ordermatch(base, txfee=0, rel, desttxfee=0, price, txid, vout, feetxid, feevout, duration=3600)\n\ +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"ordermatch\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234,\"duration\":600,\"txfee\":0,\"desttxfee\":0,\"txid\":\"$1\",\"vout\":$2,\"feetxid\":\"$3\",\"feevout\":$4}" diff --git a/iguana/exchanges/parselog b/iguana/exchanges/parselog new file mode 100755 index 000000000..c594944e9 --- /dev/null +++ b/iguana/exchanges/parselog @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"parselog\"}" diff --git a/iguana/exchanges/passphrase b/iguana/exchanges/passphrase new file mode 100644 index 000000000..eb00095d6 --- /dev/null +++ b/iguana/exchanges/passphrase @@ -0,0 +1 @@ +export passphrase="" diff --git a/iguana/exchanges/pendings b/iguana/exchanges/pendings new file mode 100755 index 000000000..a2aa46c83 --- /dev/null +++ b/iguana/exchanges/pendings @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"statsdisp\",\"starttime\":2000000000,\"endtime\":2000000000}" diff --git a/iguana/exchanges/pendingswaps b/iguana/exchanges/pendingswaps new file mode 100755 index 000000000..6cd5f50dd --- /dev/null +++ b/iguana/exchanges/pendingswaps @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"swapstatus\",\"pending\":1}" diff --git a/iguana/exchanges/poloniex.c b/iguana/exchanges/poloniex.c index 186fa51b6..a45c3e343 100755 --- a/iguana/exchanges/poloniex.c +++ b/iguana/exchanges/poloniex.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -72,20 +72,29 @@ int32_t SUPPORTS(struct exchange_info *exchange,char *base,char *rel,cJSON *argj { //char *baserels[][2] = { {"btc","usd"} }; //return(baserel_polarity(baserels,(int32_t)(sizeof(baserels)/sizeof(*baserels)),base,rel)); - if ( strlen(base) > 5 || strlen(rel) > 5 || strcmp(rel,"CNY") == 0 || strcmp(base,"CNY") == 0 || strcmp(rel,"USD") == 0 || strcmp(base,"USD") == 0 ) + if ( strlen(base) > 5 || strlen(rel) > 5 || strcmp(rel,"CNY") == 0 || strcmp(base,"CNY") == 0 ) return(0); - if ( strcmp(rel,"BTC") == 0 ) + if ( strcmp(base,"BTC") == 0 && strcmp(rel,"USD") == 0 ) + return(1); + else if ( strcmp(rel,"BTC") == 0 && strcmp(base,"USD") == 0 ) + return(-1); + else if ( strcmp(rel,"BTC") == 0 ) return(1); else if ( strcmp(base,"BTC") == 0 ) return(-1); else return(0); } -double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert) +double UPDATE(struct exchange_info *exchange,char *_base,char *_rel,struct exchange_quote *quotes,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert) { - char market[128],url[1024]; - sprintf(market,"%s_%s",rel,base); + char market[128],url[1024],base[16],rel[16]; + strcpy(base,_base), touppercase(base); + strcpy(rel,_rel), touppercase(rel); + if ( strcmp(rel,"USD") == 0 ) + sprintf(market,"USDT_%s",base); + else sprintf(market,"%s_%s",rel,base); sprintf(url,"https://poloniex.com/public?command=returnOrderBook¤cyPair=%s&depth=%d",market,maxdepth); + //printf("URL.(%s)\n",url); return(exchanges777_standardprices(exchange,commission,base,rel,url,quotes,0,0,maxdepth,0,invert)); } @@ -157,9 +166,11 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha typestr = (dir > 0) ? "marginBuy":"marginSell"; else typestr = (dir > 0) ? "buy":"sell"; sprintf(payload,"command=%s&nonce=%lld¤cyPair=%s&rate=%.8f&amount=%.8f",typestr,(long long)nonce,pairstr,price,volume); - if ( CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,EXCHANGE_AUTHURL,payload)) != 0 ) + if ( //CHECKBALANCE(retstrp,dotrade,exchange,dir,base,rel,price,volume,argjson) == 0 && + (json= SIGNPOST(&exchange->cHandle,dotrade,retstrp,exchange,EXCHANGE_AUTHURL,payload)) != 0 ) { txid = (get_API_nxt64bits(cJSON_GetObjectItem(json,"orderNumber")) << 32) | get_API_nxt64bits(cJSON_GetObjectItem(json,"tradeID")); + printf("poloniex.%llu (%s) %s\n",(long long)txid,jprint(json,0),*retstrp!=0?*retstrp:""); free_json(json); } return(txid); diff --git a/iguana/exchanges/portfolio b/iguana/exchanges/portfolio new file mode 100755 index 000000000..b22adbc06 --- /dev/null +++ b/iguana/exchanges/portfolio @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"portfolio\"}" diff --git a/iguana/exchanges/pricearray b/iguana/exchanges/pricearray new file mode 100755 index 000000000..dc812dba6 --- /dev/null +++ b/iguana/exchanges/pricearray @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"pricearray\",\"base\":\"KMD\",\"rel\":\"BTC\",\"timescale\":60}" diff --git a/iguana/exchanges/prices/autoprice b/iguana/exchanges/prices/autoprice new file mode 100755 index 000000000..f387d45d8 --- /dev/null +++ b/iguana/exchanges/prices/autoprice @@ -0,0 +1,50 @@ +#!/bin/bash +margin=0.05 +source userpass +./auto_chipskmd +./auto_chipsbtc +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"margin\":$margin,\"refbase\":\"komodo\",\"refrel\":\"coinmarketcap\"}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTC\",\"rel\":\"KMD\",\"fixed\":0.00025,\"margin\":$margin}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTC\",\"fixed\":4000,\"margin\":$margin}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"MNZ\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"BTC\",\"factor\":15000,\"margin\":-0.2}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"HUSH\",\"rel\":\"KMD\",\"margin\":$margin,\"refbase\":\"hush\",\"refrel\":\"coinmarketcap\"}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"BTCH\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"HUSH\",\"factor\":1.44,\"buymargin\":0.05,\"sellmargin\":0.05}" +#curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BTCH\",\"rel\":\"KMD\",\"offset\":0.0,\"refbase\":\"HUSH\",\"refrel\":\"KMD\",\"factor\":0.7,\"buymargin\":0.05,\"sellmargin\":0.05}" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BEER\",\"rel\":\"PIZZA\",\"fixed\":0.0001,\"margin\":0.00001}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"BEER\",\"rel\":\"ETOMIC\",\"fixed\":10,\"margin\":0.00001}" + +source crypto +source trackbtc + +#source jumblr +#source trackbtc + +source pangea +source trackbtc + +source bet +source trackbtc + +#source revs +#source trackbtc + +sharkholdings="{\"coin\":\"iota\",\"balance\":1500000}, {\"coin\":\"bitcoin-cash\",\"balance\":1200}, {\"coin\":\"bitcoin\",\"balance\":145}" +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"MSHARK\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"margin\":$margin,\"address\":\"RTu3JZZKLJTcfNwBa19dWRagEfQq49STqC\",\"holdings\":[$sharkholdings],\"divisor\":1400000}" + + +curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"SUPERNET\",\"rel\":\"KMD\",\"fundvalue_bid\":\"NAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" + +curl --url "http://127.0.0.1:7783" --data "{\"margin\":$margin,\"base\":\"HODL\",\"rel\":\"KMD\",\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RNcUaMUEFLxVwtTo7rgruhwYanGk1jTkeU\",\"holdings\":[{\"coin\":\"siacoin\",\"balance\":185000000,\"comment\":\"using siafunds equal to million siacoin\"}],\"divisor\":10000000}" + +dexholdings="{\"coin\":\"blocknet\",\"balance\":4975836}" +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"DEX\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf\",\"holdings\":[$dexholdings],\"divisor\":1000000}" + +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"BOTS\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RNdqHx26GWy9bk8MtmH1UiXjQcXE4RKK2P\",\"holdings\":[$dexholdings],\"divisor\":3333333}" + +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"JUMBLR\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"address\":\"RGhxXpXSSBTBm9EvNsXnTQczthMCxHX91t\",\"holdings\":[$dexholdings],\"divisor\":3333333}" + +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"MGW\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"holdings\":[$dexholdings],\"divisor\":13000000}" + +curl --url "http://127.0.0.1:7783" --data "{\"base\":\"REVS\",\"rel\":\"KMD\",\"margin\":$margin,\"fundvalue_bid\":\"assetNAV_KMD\",\"fundvalue_ask\":\"assetNAV_KMD\",\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"holdings\":[$dexholdings],\"divisor\":9000000}" diff --git a/iguana/exchanges/prices/bet b/iguana/exchanges/prices/bet new file mode 100644 index 000000000..94cea0420 --- /dev/null +++ b/iguana/exchanges/prices/bet @@ -0,0 +1,3 @@ +coin=BET +price=0.0005 +invprice=2000 diff --git a/iguana/exchanges/prices/bots b/iguana/exchanges/prices/bots new file mode 100644 index 000000000..5a0c892ca --- /dev/null +++ b/iguana/exchanges/prices/bots @@ -0,0 +1,3 @@ +coin=BOTS +price=0.001 +invprice=1000 diff --git a/iguana/exchanges/prices/crypto b/iguana/exchanges/prices/crypto new file mode 100644 index 000000000..7cd57178c --- /dev/null +++ b/iguana/exchanges/prices/crypto @@ -0,0 +1,3 @@ +coin=CRYPTO +price=0.002666666 +invprice=375 diff --git a/iguana/exchanges/prices/gets b/iguana/exchanges/prices/gets new file mode 100755 index 000000000..d540ce5de --- /dev/null +++ b/iguana/exchanges/prices/gets @@ -0,0 +1,18 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"REVS\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"CHIPS\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"KMD\",\"rel\":\"BTC\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"SUPERNET\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"CRYPTO\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"DEX\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"BOTS\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"MGW\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"BET\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"PANGEA\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"HODL\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"MSHARK\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"JUMBLR\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"HUSH\",\"rel\":\"KMD\"}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"getmyprice\",\"base\":\"BTCH\",\"rel\":\"KMD\"}" + diff --git a/iguana/exchanges/prices/jumblr b/iguana/exchanges/prices/jumblr new file mode 100644 index 000000000..98b9a70f3 --- /dev/null +++ b/iguana/exchanges/prices/jumblr @@ -0,0 +1,3 @@ +coin=JUMBLR +price=0.002 +invprice=500 diff --git a/iguana/exchanges/prices/mgw b/iguana/exchanges/prices/mgw new file mode 100644 index 000000000..09b4d0cc3 --- /dev/null +++ b/iguana/exchanges/prices/mgw @@ -0,0 +1,3 @@ +coin=MGW +price=0.00015 +invprice=6666 diff --git a/iguana/exchanges/prices/pangea b/iguana/exchanges/prices/pangea new file mode 100644 index 000000000..deaab24c6 --- /dev/null +++ b/iguana/exchanges/prices/pangea @@ -0,0 +1,3 @@ +coin=PANGEA +price=0.001 +invprice=1000 diff --git a/iguana/exchanges/prices/revs b/iguana/exchanges/prices/revs new file mode 100644 index 000000000..2ec12f391 --- /dev/null +++ b/iguana/exchanges/prices/revs @@ -0,0 +1,3 @@ +coin=REVS +price=0.0005 +invprice=2000 diff --git a/iguana/exchanges/processfiles b/iguana/exchanges/processfiles new file mode 100755 index 000000000..9404f967a --- /dev/null +++ b/iguana/exchanges/processfiles @@ -0,0 +1,3 @@ +ls -l /proc/$1/fd +echo sockstat +cat /proc/$1/net/sockstat diff --git a/iguana/exchanges/profile b/iguana/exchanges/profile new file mode 100755 index 000000000..50c1df851 --- /dev/null +++ b/iguana/exchanges/profile @@ -0,0 +1 @@ +gprof -b ../marketmaker ../gmon.out diff --git a/iguana/exchanges/pub b/iguana/exchanges/pub new file mode 100755 index 000000000..2e3241fee --- /dev/null +++ b/iguana/exchanges/pub @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"6578099f6474d9b8bd66a7a136b922029a989818ec0309aee962dd6ac1862b74\",\"method\":\"forward\",\"method2\":\"publish\",\"data\":\"nonsense\"}" diff --git a/iguana/exchanges/pubkeystats b/iguana/exchanges/pubkeystats new file mode 100755 index 000000000..6897c0a51 --- /dev/null +++ b/iguana/exchanges/pubkeystats @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"statsdisp\",\"starttime\":0,\"endtime\":0,\"pubkey\":\"a2593155464e37fcc88245780240a412a38cf3d316809445aad73f4e7789187d\"}" diff --git a/iguana/exchanges/quadriga.c b/iguana/exchanges/quadriga.c index 6347c5118..e686c9787 100755 --- a/iguana/exchanges/quadriga.c +++ b/iguana/exchanges/quadriga.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/recentswaps b/iguana/exchanges/recentswaps new file mode 100755 index 000000000..d24b99840 --- /dev/null +++ b/iguana/exchanges/recentswaps @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"recentswaps\",\"limit\":1}" diff --git a/iguana/exchanges/reset_mutex b/iguana/exchanges/reset_mutex new file mode 100755 index 000000000..f129e208f --- /dev/null +++ b/iguana/exchanges/reset_mutex @@ -0,0 +1,4 @@ +#!/bin/sh +strace -f -o $HOME/strace.out -p `pidof marketmaker` & +sleep 2 +killall strace diff --git a/iguana/exchanges/run b/iguana/exchanges/run new file mode 100755 index 000000000..0954a5c1a --- /dev/null +++ b/iguana/exchanges/run @@ -0,0 +1,9 @@ +#!/bin/bash +source passphrase +source coins +./stop +git pull; +cd ..; +./m_mm; +pkill -15 marketmaker; + $1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & diff --git a/iguana/exchanges/run_osx b/iguana/exchanges/run_osx new file mode 100755 index 000000000..970217843 --- /dev/null +++ b/iguana/exchanges/run_osx @@ -0,0 +1,8 @@ +#!/bin/bash +source passphrase +source coins +pkill -15 marketmaker; +git pull; +cd ..; +./m_mm; +$1 ./marketmaker "{\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}/Library/Application\ Support\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" & diff --git a/iguana/exchanges/secretaddresses b/iguana/exchanges/secretaddresses new file mode 100755 index 000000000..29ebd0041 --- /dev/null +++ b/iguana/exchanges/secretaddresses @@ -0,0 +1,6 @@ +#!/bin/bash +source userpass +echo "usage: ./secretaddresses 'passphrase'" + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"secretaddresses\",\"num\":16,\"passphrase\":\"$1\"}" + diff --git a/iguana/exchanges/sell b/iguana/exchanges/sell new file mode 100755 index 000000000..ddbff6118 --- /dev/null +++ b/iguana/exchanges/sell @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"KMD\",\"rel\":\"BTC\",\"basevolume\":10.0,\"price\":0.0005}" diff --git a/iguana/exchanges/sendrawtransaction b/iguana/exchanges/sendrawtransaction new file mode 100755 index 000000000..c3c2b09a0 --- /dev/null +++ b/iguana/exchanges/sendrawtransaction @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sendrawtransaction\",\"coin\":\"KMD\",\"signedtx\":\"$1\"}" diff --git a/iguana/exchanges/setconfirms b/iguana/exchanges/setconfirms new file mode 100755 index 000000000..78905f158 --- /dev/null +++ b/iguana/exchanges/setconfirms @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setconfirms\",\"coin\":\"REVS\",\"numconfirms\":1}" diff --git a/iguana/exchanges/setpassphrase b/iguana/exchanges/setpassphrase new file mode 100755 index 000000000..ad170a572 --- /dev/null +++ b/iguana/exchanges/setpassphrase @@ -0,0 +1,4 @@ +#!/bin/bash +source userpass +source passphrase +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f\",\"method\":\"passphrase\",\"passphrase\":\"$passphrase\",\"gui\":\"nogui\"}" diff --git a/iguana/exchanges/setprice b/iguana/exchanges/setprice new file mode 100755 index 000000000..40b88e0a5 --- /dev/null +++ b/iguana/exchanges/setprice @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"REVS\",\"rel\":\"KMD\",\"price\":1.234}" diff --git a/iguana/exchanges/snapshot b/iguana/exchanges/snapshot new file mode 100755 index 000000000..75a0a60aa --- /dev/null +++ b/iguana/exchanges/snapshot @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot\",\"coin\":\"KMD\",\"height\":$1}" diff --git a/iguana/exchanges/snapshot_balance b/iguana/exchanges/snapshot_balance new file mode 100644 index 000000000..b66f1a9e4 --- /dev/null +++ b/iguana/exchanges/snapshot_balance @@ -0,0 +1,5 @@ +#!/bin/bash +source userpass +ht=$1 +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot_balance\",\"coin\":\"KMD\",\"height\":$ht,\"addresses\":[\"RSAzPFzgTZHNcxLNLdGyVPbjbMA8PRY7Ss\", \"RBgD5eMGwZppid4x7PTEC2Wg1AzvxbsQqB\"]}" + diff --git a/iguana/exchanges/snapshot_loop b/iguana/exchanges/snapshot_loop new file mode 100755 index 000000000..05bedaa82 --- /dev/null +++ b/iguana/exchanges/snapshot_loop @@ -0,0 +1,12 @@ +#!/bin/bash +source userpass +ht=$1 +while true +do +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"snapshot\",\"coin\":\"KMD\",\"height\":$ht}" +#ht=`komodo-cli getinfo | jq .blocks` +ht=$(( $ht + 1000 )) +echo next height $ht +sleep 1 +done + diff --git a/iguana/exchanges/stats.c b/iguana/exchanges/stats.c new file mode 100644 index 000000000..53f2748f2 --- /dev/null +++ b/iguana/exchanges/stats.c @@ -0,0 +1,1249 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +// +// main.c +// stats +// +// Copyright © 2017 SuperNET. All rights reserved. +// + + + +#include +#include +#include "../../crypto777/OS_portable.h" +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define STATS_DESTDIR "/var/www/html" +#define STATS_DEST "/var/www/html/DEXstats.json" +#include "DEXstats.h" +char *stats_JSON(void *ctx,char *myipaddr,int32_t mypubsock,cJSON *argjson,char *remoteaddr,uint16_t port); +void LP_queuecommand(char **retstrp,char *buf,int32_t responsesock,int32_t stats_JSONonly); +extern uint32_t DOCKERFLAG; + +char *stats_validmethods[] = +{ + "psock", "ticker", "balances", "getprice", "notify", "getpeers", // from issue_ "uitem", "listunspent", + "orderbook", "statsdisp", "fundvalue", "help", "getcoins", "pricearray", "balance", "tradesarray" +}; + +int32_t LP_valid_remotemethod(cJSON *argjson) +{ + char *method; int32_t i; + if ( DOCKERFLAG != 0 ) + return(1); + if ( (method= jstr(argjson,"method")) != 0 ) + { + for (i=0; iai_next) { + switch (returnptr->ai_family) { + case AF_INET: + sockaddr_ipv4 = (struct sockaddr_in *) returnptr->ai_addr; + // we want to break from the loop after founding the first ipv4 address + found = 1; + break; + } + } + + // if we iterate through the loop and didn't find anything, + // that means we failed in the dns lookup + if (found == 0) { + printf("getaddrinfo(%s) returned error\n", hostname); + freeaddrinfo(addrresult); + return(-1); + } +#else + hostent = gethostbyname(ipaddr); + if ( hostent == NULL ) + { + printf("gethostbyname(%s) returned error: %d port.%d ipaddr.(%s)\n",hostname,errno,port,ipaddr); + return(-1); + } +#endif + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + //#ifdef _WIN32 + // saddr.sin_addr.s_addr = (uint32_t)calc_ipbits("127.0.0.1"); + //#else + +#if defined(_M_X64) + saddr.sin_addr.s_addr = sockaddr_ipv4->sin_addr.s_addr; + // graceful cleanup + sockaddr_ipv4 = NULL; + freeaddrinfo(addrresult); +#else + memcpy(&saddr.sin_addr.s_addr,hostent->h_addr_list[0],hostent->h_length); +#endif + expand_ipbits(checkipaddr,saddr.sin_addr.s_addr); + if ( strcmp(ipaddr,checkipaddr) != 0 ) + printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)?\n",bindflag,checkipaddr,ipaddr); + //#endif + if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) + { + if ( errno != ETIMEDOUT ) + printf("socket() failed: %s errno.%d", strerror(errno),errno); + return(-1); + } + opt = 1; + slen = sizeof(opt); + //printf("set keepalive.%d\n",setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,slen)); +#ifndef _WIN32 + if ( 1 )//&& bindflag != 0 ) + { + opt = 0; + getsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,&slen); + opt = 1; + //printf("keepalive.%d\n",opt); + } + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)); +#ifdef __APPLE__ + setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); +#endif +#endif + if ( bindflag == 0 ) + { + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + result = connect(sock,(struct sockaddr *)&saddr,addrlen); + if ( result != 0 ) + { + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + } + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + timeout.tv_sec = 10000000; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + } + else + { + while ( (result= bind(sock,(struct sockaddr*)&saddr,addrlen)) != 0 ) + { + if ( errno == EADDRINUSE ) + { + sleep(1); + printf("ERROR BINDING PORT.%d. this is normal tcp timeout, unless another process is using port\n",port); + sleep(3); + printf("%s(%s) port.%d try again: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + if ( bindflag == 1 ) + { + closesocket(sock); + return(-1); + } + sleep(13); + //continue; + } + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + closesocket(sock); + return(-1); + } + } + if ( listen(sock,512) != 0 ) + { + printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + } +#ifdef __APPLE__ + //timeout.tv_sec = 0; + //timeout.tv_usec = 30000; + //setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(void *)&timeout,sizeof(timeout)); +#endif + return(sock); +} + +int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) +{ + int32_t a,b,c,n = 0; //char *origkey=key,*origvalue=value; + key[0] = value[0] = 0; + while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) + n++; + while ( (c= src[n]) != ':' && c != 0 ) + { + *key++ = c; + //printf("(%c) ",c); + if ( ++n >= keymax-1 ) + { + *key = 0; + printf("lineparse overflow key.(%s)\n",src); + return(-1); + } + } + *key = 0; + //printf("-> key.(%s)\n",origkey); + if ( src[n] != ':' ) + return(n); + n++; + while ( (c= src[n]) == ' ' || c == '\t' ) + n++; + while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) + { + if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) + c = ((unhex(a) << 4) | unhex(b)), n += 2; + *value++ = c; + n++; + if ( n >= valuemax-1 ) + { + *value = 0; + printf("lineparse overflow.(%s)\n",src); + return(-1); + } + } + *value = 0; + if ( src[n] != 0 ) + { + n++; + while ( (c= src[n]) == '\r' || c == '\n' ) + n++; + } + //printf("key.(%s) value.(%s)\n",origkey,origvalue); + return(n); +} + +cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +{ + int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; + json = cJSON_CreateObject(); + array = cJSON_CreateArray(); + totallen = (int32_t)strlen(urlstr); + while ( 1 ) + { + for (i=len; urlstr[i]!=0; i++) + if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) + break; + if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + { + len++; + continue; + } + urlstr[i] = 0; + //printf("URLSTR[%d]=%s\n",i,&urlstr[len]); + if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) + { + if ( value[0] != 0 ) + jaddstr(json,key,value); + else jaddistr(array,key); + len += (n + 1); + if ( (strcmp(key,"Content-Length") == 0 || strcmp(key,"content-length") == 0) && (datalen= atoi(value)) > 0 ) + { + data = &urlstr[totallen - datalen]; + data[-1] = 0; + //printf("post.(%s) (%c)\n",data,data[0]); + jaddstr(json,"POST",data); + } + } else break; + } + jadd(json,"lines",array); + //printf("urlconv.(%s)\n",jprint(json,0)); + return(json); +} + +extern void *bitcoin_ctx(); + +char *stats_rpcparse(char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port) +{ + static void *ctx; + cJSON *tokens,*argjson,*origargjson,*tmpjson=0,*json = 0; long filesize; char symbol[64],buf[4096],*userpass=0,urlmethod[16],*data,url[8192],furl[8192],*retstr=0,*filestr,*token = 0; int32_t i,j,n,num=0; + if ( ctx == 0 ) + ctx = bitcoin_ctx(); + for (i=0; i0; i--) + if ( url[i] == '.' || url[i] == '/' ) + break; + if ( url[i] == '.' ) + strcpy(filetype,url+i+1); + //printf("return filetype.(%s) size.%ld\n",filetype,filesize); + return(filestr); + }*/ + if ( strncmp(&url[i],"/api",strlen("/api")) == 0 ) + { + *jsonflagp = 1; + i += strlen("/api"); + } else *jsonflagp = 0; + if ( strcmp(url,"/favicon.ico") == 0 ) + { + *jsonflagp = 1; + return(0); + } + if ( url[i] != '/' ) + token = &url[i]; + n = i; + tokens = cJSON_CreateArray(); + for (; url[i]!=0; i++) + { + //printf("i.%d (%c)\n",i,url[i]); + if ( url[i] == '/' ) + { + url[i] = 0; + if ( token != 0 ) + { + //printf("TOKEN.(%s) i.%d\n",token,i); + jaddistr(tokens,token); + num++; + } + token = &url[i+1]; + i++; + //printf("new token.(%s) i.%d\n",token,i+1); + continue; + } + } + if ( token != 0 ) + { + //printf("add token.(%s)\n",token); + jaddistr(tokens,token); + num++; + } + argjson = cJSON_CreateObject(); + if ( num > 0 ) + jaddstr(argjson,"agent",jstri(tokens,0)); + if ( num > 1 ) + jaddstr(argjson,"method",jstri(tokens,1)); + if ( (json= SuperNET_urlconv(retbuf,bufsize,urlstr+n)) != 0 ) + { + jadd(json,"tokens",tokens); + jaddstr(json,"urlmethod",urlmethod); + if ( (data= jstr(json,"POST")) != 0 ) + { + free_json(argjson); + argjson = cJSON_Parse(data); + //printf("data.(%s)\n",data); + } + if ( argjson != 0 ) + { + userpass = jstr(argjson,"userpass"); + //printf("userpass.(%s)\n",userpass); + if ( (n= cJSON_GetArraySize(tokens)) > 0 ) + { + if ( n > 1 ) + { + if ( jstri(tokens,1) != 0 ) + { + char *key,*value; + strcpy(buf,jstri(tokens,1)); + key = value = 0; + i = 0; + for (; buf[i]!=0; i++) + { + if ( buf[i] == '?' ) + { + buf[i] = 0; + jdelete(argjson,"method"); + jaddstr(argjson,"method",buf); + i++; + key = &buf[i]; + break; + } + } + while ( buf[i] != 0 ) + { + //printf("iter.[%s]\n",&buf[i]); + if ( buf[i] != 0 && key != 0 ) + { + for (; buf[i]!=0; i++) + { + if ( buf[i] == '=' ) + { + buf[i] = 0; + i++; + //printf("got key.(%s)\n",key); + value = &buf[i]; + break; + } + } + if ( buf[i] != 0 && value != 0 ) + { + for (; buf[i]!=0; i++) + { + if ( buf[i] == '&' ) + { + buf[i] = 0; + jaddstr(argjson,key,value); + i++; + //printf("got value.(%s)\n",value); + value = 0; + key = &buf[i]; + break; + } + else if ( buf[i] == '+' ) + buf[i] = ' '; + } + } + } + } + if ( key != 0 && value != 0 ) + jaddstr(argjson,key,value); + } + else + { + //jdelete(argjson,"method"); + //jaddstr(argjson,"method",buf); + } + } + for (i=2; i 0 ) + { + cJSON *retitem,*retarray = cJSON_CreateArray(); + origargjson = argjson; + symbol[0] = 0; + for (i=0; i 0 ) + { + //buf = jprint(argjson,0); + //LP_queuecommand(&retstr,buf,-1,1); + //free(buf); + //while ( retstr == 0 ) + // usleep(10000); + if ( (retstr= stats_JSON(ctx,"127.0.0.1",-1,argjson,remoteaddr,port)) != 0 ) + { + if ( (retitem= cJSON_Parse(retstr)) != 0 ) + jaddi(retarray,retitem); + free(retstr); + } + } else retstr = clonestr("{\"error\":\"invalid remote method\"}"); +#else + //buf = jprint(argjson,0); + //LP_queuecommand(&retstr,buf,-1,1); + //free(buf); + //while ( retstr == 0 ) + // usleep(10000); + if ( (retstr= stats_JSON(ctx,myipaddr,-1,argjson,remoteaddr,port)) != 0 ) + { + if ( (retitem= cJSON_Parse(retstr)) != 0 ) + jaddi(retarray,retitem); + free(retstr); + } +#endif + //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),jprint(json,0),*postflagp,retstr); + } + free_json(origargjson); + retstr = jprint(retarray,1); + } + else + { + cJSON *arg; //char *buf; + if ( jstr(argjson,"agent") != 0 && strcmp(jstr(argjson,"agent"),"bitcoinrpc") != 0 && jobj(argjson,"params") != 0 ) + { + arg = jobj(argjson,"params"); + if ( is_cJSON_Array(arg) != 0 && cJSON_GetArraySize(arg) == 1 ) + arg = jitem(arg,0); + } else arg = argjson; + //printf("ARGJSON.(%s)\n",jprint(arg,0)); + if ( userpass != 0 && jstr(arg,"userpass") == 0 ) + jaddstr(arg,"userpass",userpass); +#ifdef FROM_MARKETMAKER + if ( strcmp(remoteaddr,"127.0.0.1") == 0 || LP_valid_remotemethod(arg) > 0 ) + { + //buf = jprint(arg,0); + //LP_queuecommand(&retstr,buf,-1,1); + //free(buf); + //while ( retstr == 0 ) + // usleep(10000); + retstr = stats_JSON(ctx,"127.0.0.1",-1,arg,remoteaddr,port); + } else retstr = clonestr("{\"error\":\"invalid remote method\"}"); +#else + //buf = jprint(arg,0); + //LP_queuecommand(&retstr,buf,-1,1); + //free(buf); + //while ( retstr == 0 ) + // usleep(10000); + retstr = stats_JSON(ctx,myipaddr,-1,arg,remoteaddr,port); +#endif + } + free_json(argjson); + } + free_json(json); + if ( tmpjson != 0 ) + free(tmpjson); +//printf("stats_JSON rpc return.(%s)\n",retstr); + return(retstr); + } + free_json(argjson); + if ( tmpjson != 0 ) + free_json(tmpjson); + if ( tokens != 0 ) + free_json(tokens); + *jsonflagp = 1; + return(clonestr("{\"error\":\"couldnt process packet\"}")); +} + +int32_t iguana_getcontentlen(char *buf,int32_t recvlen) +{ + char *str,*clenstr = "Content-Length: ",*clenstr2 = "content-length: "; int32_t len = -1; + if ( (str= strstr(buf,clenstr)) != 0 || (str= strstr(buf,clenstr2)) != 0 ) + { + //printf("strstr.(%s)\n",str); + str += strlen(clenstr); + len = atoi(str); + //printf("len.%d\n",len); + } + return(len); +} + +int32_t iguana_getheadersize(char *buf,int32_t recvlen) +{ + char *str,*delim = "\r\n\r\n"; + if ( (str= strstr(buf,delim)) != 0 ) + return((int32_t)(((long)str - (long)buf) + strlen(delim))); + return(recvlen); +} + +uint16_t RPC_port; +extern portable_mutex_t LP_commandmutex,LP_gcmutex; +extern struct rpcrequest_info *LP_garbage_collector; + +void LP_rpc_processreq(void *_ptr) +{ + static uint32_t spawned,maxspawned; + char filetype[128],content_type[128]; + int32_t recvlen,flag,postflag=0,contentlen,remains,sock,numsent,jsonflag=0,hdrsize,len; + char helpname[512],remoteaddr[64],*buf,*retstr,space[8192],space2[32786],*jsonbuf; struct rpcrequest_info *req = _ptr; + uint32_t ipbits,i,size = IGUANA_MAXPACKETSIZE + 512; + ipbits = req->ipbits;; + expand_ipbits(remoteaddr,ipbits); + sock = req->sock; + recvlen = flag = 0; + retstr = 0; + //space = calloc(1,size); + jsonbuf = calloc(1,size); + //printf("alloc jsonbuf.%p\n",jsonbuf); + remains = size-1; + buf = jsonbuf; + spawned++; + if ( spawned > maxspawned ) + { + printf("max rpc threads spawned and alive %d <- %d\n",maxspawned,spawned); + maxspawned = spawned; + } + while ( remains > 0 ) + { + //printf("flag.%d remains.%d recvlen.%d\n",flag,remains,recvlen); + if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + printf("EAGAIN for len %d, remains.%d\n",len,remains); + usleep(10000); + } + //printf("errno.%d len.%d remains.%d\n",errno,len,remains); + break; + } + else + { + //printf("received len.%d\n%s\n",len,buf); + if ( len > 0 ) + { + buf[len] = 0; + if ( recvlen == 0 ) + { + if ( (contentlen= iguana_getcontentlen(buf,recvlen)) > 0 ) + { + hdrsize = iguana_getheadersize(buf,recvlen); + if ( hdrsize > 0 ) + { + if ( len < (hdrsize + contentlen) ) + { + remains = (hdrsize + contentlen) - len; + buf = &buf[len]; + flag = 1; + //printf("got.(%s) %d remains.%d of len.%d contentlen.%d hdrsize.%d remains.%d\n",buf,recvlen,remains,len,contentlen,hdrsize,(hdrsize+contentlen)-len); + continue; + } + } + } + } + recvlen += len; + remains -= len; + buf = &buf[len]; + if ( flag == 0 || remains <= 0 ) + break; + } + else + { + usleep(10000); + printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len); + if ( flag == 0 ) + break; + } + } + } + content_type[0] = 0; + if ( recvlen > 0 ) + { + jsonflag = postflag = 0; + //portable_mutex_lock(&LP_commandmutex); + retstr = stats_rpcparse(space,size,&jsonflag,&postflag,jsonbuf,remoteaddr,filetype,req->port); + //portable_mutex_unlock(&LP_commandmutex); + if ( filetype[0] != 0 ) + { + static cJSON *mimejson; char *tmp,*typestr=0; long tmpsize; + sprintf(helpname,"%s/mime.json",GLOBAL_HELPDIR); + if ( (tmp= OS_filestr(&tmpsize,helpname)) != 0 ) + { + mimejson = cJSON_Parse(tmp); + free(tmp); + } + if ( mimejson != 0 ) + { + if ( (typestr= jstr(mimejson,filetype)) != 0 ) + sprintf(content_type,"Content-Type: %s\r\n",typestr); + } else printf("parse error.(%s)\n",tmp); + //printf("filetype.(%s) json.%p type.%p tmp.%p [%s]\n",filetype,mimejson,typestr,tmp,content_type); + } + } + if ( retstr != 0 ) + { + char *response,hdrs[1024]; + //printf("RETURN.(%s) jsonflag.%d postflag.%d\n",retstr,jsonflag,postflag); + if ( jsonflag != 0 || postflag != 0 ) + { + if ( strlen(retstr)+1024+1+1 < sizeof(space2) ) + response = space2; + else + { + response = malloc(strlen(retstr)+1024+1+1); + //printf("alloc response.%p\n",response); + } + sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)+1); + response[0] = '\0'; + strcat(response,hdrs); + strcat(response,retstr); + strcat(response,"\n"); + if ( retstr != space ) + { + //printf("free retstr0.%p\n",retstr); + free(retstr); + } + retstr = response; + //printf("RET.(%s)\n",retstr); + } + remains = (int32_t)strlen(retstr); + i = 0; + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) + { + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); + break; + } + } + else if ( remains > 0 ) + { + remains -= numsent; + i += numsent; + if ( remains > 0 ) + printf("iguana sent.%d remains.%d of recvlen.%d (%s)\n",numsent,remains,recvlen,jsonbuf); + } + } + if ( retstr != space && retstr != space2 ) + { + //printf("free retstr.%p\n",retstr); + free(retstr); + } + } + //free(space); + //printf("free jsonbuf.%p\n",jsonbuf); + free(jsonbuf); + closesocket(sock); + if ( 1 ) + { + portable_mutex_lock(&LP_gcmutex); + DL_APPEND(LP_garbage_collector,req); + portable_mutex_unlock(&LP_gcmutex); + } + else + { + //printf("free req.%p\n",req); + free(req); + } + spawned--; +} + +extern int32_t IAMLP,LP_STOP_RECEIVED; +//int32_t LP_bindsock_reset,LP_bindsock = -1; + +void stats_rpcloop(void *args) +{ + uint16_t port; int32_t retval,sock=-1,bindsock=-1; socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits,localhostbits; struct rpcrequest_info *req; + if ( (port= *(uint16_t *)args) == 0 ) + port = 7779; + printf("Start stats_rpcloop.%u\n",port); + localhostbits = (uint32_t)calc_ipbits("127.0.0.1"); + //initial_bindsock_reset = LP_bindsock_reset; + while ( LP_STOP_RECEIVED == 0 )//LP_bindsock_reset == initial_bindsock_reset ) + { + //printf("LP_bindsock.%d\n",LP_bindsock); + if ( bindsock < 0 ) + { + while ( (bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) + usleep(10000); +#ifndef _WIN32 + //fcntl(bindsock, F_SETFL, fcntl(bindsock, F_GETFL, 0) | O_NONBLOCK); +#endif + //if ( counter++ < 1 ) + printf(">>>>>>>>>> DEX stats 127.0.0.1:%d bind sock.%d DEX stats API enabled at unixtime.%u <<<<<<<<<\n",port,bindsock,(uint32_t)time(NULL)); + } + //printf("after sock.%d\n",sock); + clilen = sizeof(cli_addr); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); +//#ifdef _WIN32 + if ( sock < 0 ) + { + printf("iguana_rpcloop ERROR on accept port.%u usock.%d errno %d %s\n",port,sock,errno,strerror(errno)); + closesocket(bindsock); + bindsock = -1; + continue; + } +/*#else + if ( sock < 0 ) + { + //fprintf(stderr,"."); + if ( IAMLP == 0 ) + usleep(50000); + else usleep(2500); + continue; + } +#endif*/ + memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); +//printf("port.%u got incoming from %x\n",port,ipbits); + if ( DOCKERFLAG != 0 && (DOCKERFLAG == 1 || ipbits == DOCKERFLAG) ) + ipbits = localhostbits; + if ( port == RPC_port && ipbits != localhostbits ) + { + //printf("port.%u RPC_port.%u ipbits %x != %x\n",port,RPC_port,ipbits,localhostbits); + closesocket(sock); + continue; + } + req = calloc(1,sizeof(*req)); + //printf("alloc req.%p\n",req); + req->sock = sock; + req->ipbits = ipbits; + req->port = port; + LP_rpc_processreq(req); + continue; + // this might lead to "cant open file errors" + if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) + { + printf("error launching rpc handler on port %d, retval.%d\n",port,retval); + LP_rpc_processreq(req); + /*portable_mutex_lock(&LP_gcmutex); + DL_FOREACH_SAFE(LP_garbage_collector,req2,rtmp) + { + DL_DELETE(LP_garbage_collector,req2); + free(req2); + } + portable_mutex_unlock(&LP_gcmutex); + if ( (retval= OS_thread_create(&req->T,NULL,(void *)LP_rpc_processreq,req)) != 0 ) + { + printf("error2 launching rpc handler on port %d, retval.%d\n",port,retval); + LP_rpc_processreq(req); + }*/ + } + } + printf("i got killed\n"); +} + +#ifndef FROM_MARKETMAKER + +portable_mutex_t LP_commandmutex; +uint16_t LP_RPCPORT = 7763; + +void stats_kvjson(FILE *logfp,int32_t height,int32_t savedheight,uint32_t timestamp,char *key,cJSON *kvjson,bits256 pubkey,bits256 sigprev) +{ + struct tai T; int32_t seconds,datenum,n; + datenum = OS_conv_unixtime(&T,&seconds,timestamp); + jaddstr(kvjson,"key",key); + jaddnum(kvjson,"datenum",datenum); + jaddnum(kvjson,"hour",seconds/3600); + jaddnum(kvjson,"seconds",seconds % 3600); + jaddnum(kvjson,"height",height); + //printf("(%s)\n",jprint(kvjson,0)); + if ( logfp != 0 ) + { + stats_priceupdate(datenum,seconds/3600,seconds % 3600,timestamp,height,key,jstr(kvjson,"pubkey"),jarray(&n,kvjson,"trade")); + fprintf(logfp,"%s\n",jprint(kvjson,0)); + fflush(logfp); + } +} + +void komodo_kvupdate(FILE *logfp,struct komodo_state *sp,int32_t ht,bits256 txid,int32_t vout,uint8_t *opretbuf,int32_t opretlen,uint64_t value) +{ + //static bits256 zeroes; + uint32_t flags; bits256 pubkey,sig; cJSON *kvjson; char decodestr[10000]; int32_t i,hassig,coresize,haspubkey,height; uint16_t keylen,valuesize; uint8_t *key,*valueptr; // bits256 refpubkey; int32_t refvaluesize,kvheight; uint16_t newflag = 0; uint8_t keyvalue[10000]; + iguana_rwnum(0,&opretbuf[1],sizeof(keylen),&keylen); + iguana_rwnum(0,&opretbuf[3],sizeof(valuesize),&valuesize); + iguana_rwnum(0,&opretbuf[5],sizeof(height),&height); + iguana_rwnum(0,&opretbuf[9],sizeof(flags),&flags); + key = &opretbuf[13]; + if ( keylen+13 > opretlen ) + { + printf("komodo_kvupdate: keylen.%d + 13 > opretlen.%d\n",keylen,opretlen); + return; + } + valueptr = &key[keylen]; + coresize = (int32_t)(sizeof(flags)+sizeof(height)+sizeof(keylen)+sizeof(valuesize)+keylen+valuesize+1); + if ( opretlen == coresize || opretlen == coresize+sizeof(bits256) || opretlen == coresize+2*sizeof(bits256) ) + { + memset(&pubkey,0,sizeof(pubkey)); + memset(&sig,0,sizeof(sig)); + if ( (haspubkey= (opretlen >= coresize+sizeof(bits256))) != 0 ) + { + for (i=0; i<32; i++) + ((uint8_t *)&pubkey)[i] = opretbuf[coresize+i]; + } + if ( (hassig= (opretlen == coresize+sizeof(bits256)*2)) != 0 ) + { + for (i=0; i<32; i++) + ((uint8_t *)&sig)[i] = opretbuf[coresize+sizeof(bits256)+i]; + } + /*if ( (refvaluesize= komodo_kvsearch((bits256 *)&refpubkey,height,&flags,&kvheight,&keyvalue[keylen],key,keylen)) >= 0 ) + { + if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) + { + if ( komodo_kvsigverify(keyvalue,keylen+refvaluesize,refpubkey,sig) < 0 ) + { + //printf("komodo_kvsigverify error [%d]\n",coresize-13); + return; + } + } + }*/ + //for (i=0; i "); + //printf(" (%s) [%d] %s/v%d ht.%d height.%d\n",decodestr,valuesize,bits256_str(str,txid),vout,ht,height); + key[keylen] = 0; + stats_kvjson(logfp,ht,sp->SAVEDHEIGHT,sp->SAVEDTIMESTAMP,(char *)key,kvjson,pubkey,sig); + free_json(kvjson); + } + } +} + +void komodo_eventadd_opreturn(FILE *logfp,struct komodo_state *sp,char *symbol,int32_t height,bits256 txid,uint64_t value,uint16_t vout,uint8_t *opretbuf,uint16_t opretlen) +{ + if ( sp != 0 ) + { + if ( opretbuf[0] == 'K' && opretlen != 40 ) + { + komodo_kvupdate(logfp,sp,height,txid,vout,opretbuf,opretlen,value); + } + } +} + +void komodo_setkmdheight(struct komodo_state *sp,int32_t kmdheight,uint32_t timestamp) +{ + if ( sp != 0 ) + { + if ( kmdheight > sp->SAVEDHEIGHT ) + { + sp->SAVEDHEIGHT = kmdheight; + sp->SAVEDTIMESTAMP = timestamp; + //printf("ht.%d t.%u\n",kmdheight,timestamp); + } + if ( kmdheight > sp->CURRENT_HEIGHT ) + sp->CURRENT_HEIGHT = kmdheight; + } +} + +void komodo_eventadd_kmdheight(struct komodo_state *sp,char *symbol,int32_t height,int32_t kmdheight,uint32_t timestamp) +{ + uint32_t buf[2]; + if ( kmdheight > 0 ) + { + buf[0] = (uint32_t)kmdheight; + buf[1] = timestamp; + //komodo_eventadd(sp,height,symbol,KOMODO_EVENT_KMDHEIGHT,(uint8_t *)buf,sizeof(buf)); + if ( sp != 0 ) + komodo_setkmdheight(sp,kmdheight,timestamp); + } + else + { + kmdheight = -kmdheight; + //komodo_eventadd(sp,height,symbol,KOMODO_EVENT_REWIND,(uint8_t *)&height,sizeof(height)); + //if ( sp != 0 ) + // komodo_event_rewind(sp,symbol,height); + } +} + +void stats_pricefeed(struct komodo_state *sp,char *symbol,int32_t ht,uint32_t *pvals,int32_t numpvals) +{ + struct tai T; int32_t seconds,datenum; cJSON *argjson; + if ( ht > 300000 && pvals[32] != 0 ) + { + datenum = OS_conv_unixtime(&T,&seconds,sp->SAVEDTIMESTAMP); + //printf("(%s)\n",jprint(kvjson,0)); + argjson = cJSON_CreateArray(); + jaddistr(argjson,"KMD"); + jaddinum(argjson,1); + jaddistr(argjson,"BTC"); + jaddinum(argjson,dstr(pvals[32]) / 10000.); + stats_priceupdate(datenum,seconds/3600,seconds % 3600,sp->SAVEDTIMESTAMP,sp->SAVEDHEIGHT,0,0,argjson); + free_json(argjson); + } +} + +int32_t komodo_parsestatefile(FILE *logfp,struct komodo_state *sp,FILE *fp,char *symbol,int32_t iter) +{ + static int32_t errs; + int32_t func,ht,notarized_height,num,matched=0; bits256 notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; + if ( (func= fgetc(fp)) != EOF ) + { + if ( ASSETCHAINS_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) + matched = 1; + else matched = (strcmp(symbol,ASSETCHAINS_SYMBOL) == 0); + if ( fread(&ht,1,sizeof(ht),fp) != sizeof(ht) ) + errs++; + //printf("fpos.%ld func.(%d %c) ht.%d ",ftell(fp),func,func,ht); + if ( func == 'P' ) + { + if ( (num= fgetc(fp)) <= 64 ) + { + if ( fread(pubkeys,33,num,fp) != num ) + errs++; + else + { + //printf("updated %d pubkeys at %s ht.%d\n",num,symbol,ht); + //if ( (KOMODO_EXTERNAL_NOTARIES != 0 && matched != 0) || (strcmp(symbol,"KMD") == 0 && KOMODO_EXTERNAL_NOTARIES == 0) ) + // komodo_eventadd_pubkeys(sp,symbol,ht,num,pubkeys); + } + } else printf("illegal num.%d\n",num); + } + else if ( func == 'N' ) + { + if ( fread(¬arized_height,1,sizeof(notarized_height),fp) != sizeof(notarized_height) ) + errs++; + if ( fread(¬arized_hash,1,sizeof(notarized_hash),fp) != sizeof(notarized_hash) ) + errs++; + if ( fread(¬arized_desttxid,1,sizeof(notarized_desttxid),fp) != sizeof(notarized_desttxid) ) + errs++; + //if ( matched != 0 ) global independent states -> inside *sp + //komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height); + } + else if ( func == 'U' ) // deprecated + { + uint8_t n,nid; bits256 hash; uint64_t mask; + n = fgetc(fp); + nid = fgetc(fp); + //printf("U %d %d\n",n,nid); + if ( fread(&mask,1,sizeof(mask),fp) != sizeof(mask) ) + errs++; + if ( fread(&hash,1,sizeof(hash),fp) != sizeof(hash) ) + errs++; + //if ( matched != 0 ) + // komodo_eventadd_utxo(sp,symbol,ht,nid,hash,mask,n); + } + else if ( func == 'K' ) + { + int32_t kheight; + if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) + errs++; + //if ( matched != 0 ) global independent states -> inside *sp + //printf("%s.%d load[%s] ht.%d\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight); + komodo_eventadd_kmdheight(sp,symbol,ht,kheight,0); + } + else if ( func == 'T' ) + { + int32_t kheight,ktimestamp; + if ( fread(&kheight,1,sizeof(kheight),fp) != sizeof(kheight) ) + errs++; + if ( fread(&ktimestamp,1,sizeof(ktimestamp),fp) != sizeof(ktimestamp) ) + errs++; + //if ( matched != 0 ) global independent states -> inside *sp + //printf("%s.%d load[%s] ht.%d t.%u\n",ASSETCHAINS_SYMBOL,ht,symbol,kheight,ktimestamp); + komodo_eventadd_kmdheight(sp,symbol,ht,kheight,ktimestamp); + } + else if ( func == 'R' ) + { + uint16_t olen,v; uint64_t ovalue; bits256 txid; uint8_t opret[16384]; + if ( fread(&txid,1,sizeof(txid),fp) != sizeof(txid) ) + errs++; + if ( fread(&v,1,sizeof(v),fp) != sizeof(v) ) + errs++; + if ( fread(&ovalue,1,sizeof(ovalue),fp) != sizeof(ovalue) ) + errs++; + if ( fread(&olen,1,sizeof(olen),fp) != sizeof(olen) ) + errs++; + if ( olen < sizeof(opret) ) + { + if ( fread(opret,1,olen,fp) != olen ) + errs++; + if ( (0) && matched != 0 ) + { + int32_t i; for (i=0; i global PAX + } else + { + int32_t i; + for (i=0; i global PVALS + //printf("load pvals ht.%d numpvals.%d\n",ht,numpvals); + } else printf("error loading pvals[%d]\n",numpvals); + } + else printf("[%s] %s illegal func.(%d %c)\n",ASSETCHAINS_SYMBOL,symbol,func,func); + return(func); + } else return(-1); +} + +int32_t stats_stateupdate(FILE *logfp,char *destdir,char *statefname,int32_t maxseconds,char *komodofile) +{ + static long lastpos[2]; + char symbol[65],base[65]; int32_t iter,n; FILE *fp; uint32_t starttime; struct komodo_state *sp; + starttime = (uint32_t)time(NULL); + strcpy(base,"KV"); + strcpy(symbol,"KV"); + n = 0; + for (iter=0; iter<2; iter++) + { + sp = &KOMODO_STATE[iter]; + if ( (fp= fopen(iter == 0 ? statefname : komodofile,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + if ( ftell(fp) > lastpos[iter] ) + { + fseek(fp,lastpos[iter],SEEK_SET); + while ( komodo_parsestatefile(logfp,sp,fp,symbol,iter) >= 0 && n < 100000 ) + { + if ( n == 99999 ) + { + if ( time(NULL) < starttime+maxseconds ) + n = 0; + else break; + } + n++; + } + lastpos[iter] = ftell(fp); + } + fclose(fp); + } + strcpy(base,"KMD"); + strcpy(symbol,"KMD"); + } + return(n); +} + +char *stats_update(FILE *logfp,char *destdir,char *statefname,char *komodofname) +{ + int32_t i; + cJSON *retjson = cJSON_CreateArray(); + for (i=0; i<100; i++) + if ( stats_stateupdate(logfp,destdir,statefname,10,komodofname) <= 0 ) + break; + return(jprint(retjson,1)); +} + +#ifndef FROM_PRIVATEBET +int main(int argc, const char * argv[]) +{ + struct tai T; uint32_t timestamp; struct DEXstats_disp prices[365]; int32_t i,n,seconds,leftdatenum; FILE *fp,*logfp; char *filestr,*retstr,*statefname,logfname[512],komodofile[512]; uint16_t port = LP_RPCPORT; + if ( argc < 2 ) + { + statefname = "/root/.komodo/KV/komodostate"; + strcpy(komodofile,"/root/.komodo/komodostate"); + } + else + { + statefname = (char *)argv[1]; + strcpy(komodofile,statefname); + n = (int32_t)strlen(komodofile); + for (i=0; i<=strlen("komodostate"); i++) + komodofile[n-14+i] = komodofile[n-11+i]; + printf("komodofile.(%s)\n",komodofile); + } + sprintf(logfname,"%s/logfile",STATS_DESTDIR), OS_portable_path(logfname); + logfp = fopen(logfname,"wb"); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)stats_rpcloop,(void *)&port) != 0 ) + { + printf("error launching stats rpcloop for port.%u\n",port); + exit(-1); + } + printf("DEX stats running\n"); + while ( LP_STOP_RECEIVED == 0 ) + { + if ( (filestr= stats_update(logfp,STATS_DEST,statefname,komodofile)) != 0 ) + { + timestamp = (uint32_t)time(NULL); + leftdatenum = OS_conv_unixtime(&T,&seconds,timestamp - 30*24*3600); + //printf("%u: leftdatenum.%d %s\n",timestamp,leftdatenum,filestr); + memset(prices,0,sizeof(prices)); + if ( (retstr= stats_prices("KMD","BTC",prices,leftdatenum,30+1)) != 0 ) + { + //printf("%s\n",retstr); + free(retstr); + } + if ( (fp= fopen(STATS_DEST,"wb")) != 0 ) + { + fwrite(filestr,1,strlen(filestr)+1,fp); + fclose(fp); + } + free(filestr); + } + sleep(60); + } + return 0; +} +#endif +#endif diff --git a/iguana/exchanges/statsdisp b/iguana/exchanges/statsdisp new file mode 100755 index 000000000..768c4e8b2 --- /dev/null +++ b/iguana/exchanges/statsdisp @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"statsdisp\",\"starttime\":0,\"endtime\":0}" diff --git a/iguana/exchanges/status b/iguana/exchanges/status new file mode 100755 index 000000000..9f89cb314 --- /dev/null +++ b/iguana/exchanges/status @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"pending\":1,\"userpass\":\"$userpass\",\"method\":\"swapstatus\"}" diff --git a/iguana/exchanges/stop b/iguana/exchanges/stop new file mode 100755 index 000000000..d13a70243 --- /dev/null +++ b/iguana/exchanges/stop @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"stop\"}" diff --git a/iguana/exchanges/supernet b/iguana/exchanges/supernet new file mode 100755 index 000000000..25e6af7e4 --- /dev/null +++ b/iguana/exchanges/supernet @@ -0,0 +1,20 @@ +#!/bin/bash +source userpass +# this will only work for watchonly addresses that have been rescanned and with active coins +echo mshark +./mshark +echo hodl +./hodl +echo dex +./dex +echo jumblr +./jumblr +echo bots +./bots +echo supernet + +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"balances\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\"}" +echo supernet +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" + +#curl --url "http://5.9.253.196:7782" --data "{\"userpass\":\"$userpass\",\"method\":\"fundvalue\",\"address\":\"RRyyejME7LRTuvdziWsXkAbSW1fdiohGwK\",\"holdings\":[{\"coin\":\"iota\",\"balance\":11000000}, {\"coin\":\"stratis\",\"balance\":1300000}, {\"coin\":\"zcash\",\"balance\":10000}, {\"coin\":\"syscoin\",\"balance\":20000000}, {\"coin\":\"waves\",\"balance\":700000}, {\"coin\":\"bitcoin\",\"balance\":625}, {\"coin\":\"bitcoin-cash\",\"balance\":1500}, {\"coin\":\"heat-ledger\",\"balance\":2323851 }, {\"coin\":\"decred\",\"balance\":20000}, {\"coin\":\"vericoin\",\"balance\":2199368 }, {\"coin\":\"byteball\",\"balance\":4238}, {\"coin\":\"iocoin\",\"balance\":150000}, {\"coin\":\"quantum-resistant-ledger\",\"balance\":375000}, {\"coin\":\"chips\",\"balance\":2577006 }, {\"coin\":\"hush\",\"balance\":100000 }, {\"coin\":\"mobilego\",\"balance\":100000 }],\"divisor\":816016}" diff --git a/iguana/exchanges/swapstatus b/iguana/exchanges/swapstatus new file mode 100755 index 000000000..abc6dbb64 --- /dev/null +++ b/iguana/exchanges/swapstatus @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"swapstatus\",\"requestid\":2291973695,\"quoteid\":3387529385}" diff --git a/iguana/exchanges/ticker b/iguana/exchanges/ticker new file mode 100755 index 000000000..2c1766600 --- /dev/null +++ b/iguana/exchanges/ticker @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"ticker\",\"base\":\"REVS\",\"rel\":\"KMD\"}" diff --git a/iguana/exchanges/tmp/.tmpmarker b/iguana/exchanges/tmp/.tmpmarker new file mode 100644 index 000000000..e69de29bb diff --git a/iguana/exchanges/to_etomic b/iguana/exchanges/to_etomic new file mode 100755 index 000000000..b2f74ec70 --- /dev/null +++ b/iguana/exchanges/to_etomic @@ -0,0 +1,4 @@ +rm /usr/bin/g++ +ln /usr/bin/g++-7 /usr/bin/g++ +rm /usr/bin/gcc +ln /usr/bin/gcc-7 /usr/bin/gcc diff --git a/iguana/exchanges/to_zcash b/iguana/exchanges/to_zcash new file mode 100755 index 000000000..c294ea474 --- /dev/null +++ b/iguana/exchanges/to_zcash @@ -0,0 +1,4 @@ +rm /usr/bin/g++ +ln /usr/bin/g++-5 /usr/bin/g++ +rm /usr/bin/gcc +ln /usr/bin/gcc-5 /usr/bin/gcc diff --git a/iguana/exchanges/trackbtc b/iguana/exchanges/trackbtc new file mode 100644 index 000000000..79366a1c4 --- /dev/null +++ b/iguana/exchanges/trackbtc @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"KMD\",\"rel\":\"$coin\",\"offset\":0.0,\"refbase\":\"KMD\",\"refrel\":\"BTC\",\"factor\":$invprice,\"margin\":$margin}" +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"autoprice\",\"base\":\"$coin\",\"rel\":\"KMD\",\"offset\":0.0,\"refbase\":\"BTC\",\"refrel\":\"KMD\",\"factor\":$price,\"margin\":$margin}" diff --git a/iguana/exchanges/trade b/iguana/exchanges/trade new file mode 100755 index 000000000..1bad74aa9 --- /dev/null +++ b/iguana/exchanges/trade @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"trade\",\"price\":1.234,\"base\":\"REVS\",\"rel\":\"KMD\",\"quote\":{}}" diff --git a/iguana/exchanges/tradesarray b/iguana/exchanges/tradesarray new file mode 100755 index 000000000..982bdca7c --- /dev/null +++ b/iguana/exchanges/tradesarray @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"tradesarray\",\"base\":\"REVS\",\"rel\":\"KMD\",\"timescale\":3600}" diff --git a/iguana/exchanges/truefx.c b/iguana/exchanges/truefx.c index 8b04ec6df..1d0049543 100755 --- a/iguana/exchanges/truefx.c +++ b/iguana/exchanges/truefx.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -38,11 +38,13 @@ uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,doubl // static uint32_t lasttime; static char *laststr; char *truefxfmt = "http://webrates.truefx.com/rates/connect.html?f=csv&id=%s:%s:poll:%llu&c=EUR/USD,USD/JPY,GBP/USD,EUR/GBP,USD/CHF,AUD/NZD,CAD/CHF,CHF/JPY,EUR/AUD,EUR/CAD,EUR/JPY,EUR/CHF,USD/CAD,AUD/USD,GBP/JPY,AUD/CAD,AUD/CHF,AUD/JPY,EUR/NOK,EUR/NZD,GBP/CAD,GBP/CHF,NZD/JPY,NZD/USD,USD/NOK,USD/SEK"; // EUR/USD,1437569931314,1.09,034,1.09,038,1.08922,1.09673,1.09384 USD/JPY,1437569932078,123.,778,123.,781,123.569,123.903,123.860 GBP/USD,1437569929008,1.56,332,1.56,337,1.55458,1.56482,1.55538 EUR/GBP,1437569931291,0.69,742,0.69,750,0.69710,0.70383,0.70338 USD/CHF,1437569932237,0.96,142,0.96,153,0.95608,0.96234,0.95748 EUR/JPY,1437569932237,134.,960,134.,972,134.842,135.640,135.476 EUR/CHF,1437569930233,1.04,827,1.04,839,1.04698,1.04945,1.04843 USD/CAD,1437569929721,1.30,231,1.30,241,1.29367,1.30340,1.29466 AUD/USD,1437569931700,0.73,884,0.73,890,0.73721,0.74395,0.74200 GBP/JPY,1437569931924,193.,500,193.,520,192.298,193.670,192.649 - char url[1024],userpass[1024],buf[128],base[64],rel[64],*str=0; cJSON *array; - int32_t jpyflag,i,n=0; double pre,pre2,bid,ask,openval,high,low; long millistamp; + char url[1024],userpass[1024],buf[128],name[16],base[64],rel[64],*str=0; cJSON *array; + int32_t maxlen,count,jpyflag,i,n=0; double pre,pre2,bid,ask,openval,high,low; long millistamp; millistamp = pre = pre2 = bid = ask = openval = high = low = 0; //printf("truefx.(%s)(%s).%llu\n",username,password,(long long)idnum); url[0] = 0; + *millistampp = 0; + *bidp = *askp = *openp = *highp = *lowp = *closep = 0.; if ( username[0] != 0 && password[0] != 0 ) { if ( sessionid == 0 ) @@ -79,6 +81,8 @@ uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,doubl if ( str != 0 ) { //printf("(%s) -> (%s)\n",url,str); + maxlen = (int32_t)strlen(str); + count = 0; /*EUR/USD,1454354222037,1.08,997,1.09,000,1.08142,1.09130,1.08333 USD/JPY,1454354221120,121.,049,121.,053,120.676,121.496,121.289 GBP/USD,1454354221048,1.44,242,1.44,254,1.42280,1.44305,1.42483 @@ -91,7 +95,7 @@ uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,doubl GBP/JPY,1454354221581,174.,602,174.,621,172.408,174.730,172.805 */ - while ( str[n + 0] != 0 && str[n] != '\n' && str[n] != '\r' ) + while ( str[n + 0] != 0 && str[n] != '\n' && str[n] != '\r' && count++ < 10 ) { for (i=jpyflag=0; str[n + i]!=' '&&str[n + i]!='\n'&&str[n + i]!='\r'&&str[n + i]!=0; i++) { @@ -108,7 +112,7 @@ uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,doubl memcpy(rel,str+n+4,3), rel[3] = 0; str[n + i] = 0; sprintf(buf,"[%s]",str+n+7+1); - //printf("str.(%s) (%s/%s) %d n.%d i.%d |%s|\n",str+n,base,rel,str[n],n,i,buf); + //printf("%d: str.(%s) (%s/%s) %d n.%d i.%d |%s|\n",count,str+n,base,rel,str[n],n,i,buf); n += i + 1; if ( (array= cJSON_Parse(buf)) != 0 ) { @@ -130,7 +134,9 @@ uint64_t prices777_truefx(char *reqbase,char *reqrel,uint64_t *millistampp,doubl *bidp = bid, *askp = ask, *openp = openval, *highp = high, *lowp = low; *closep = 0; *millistampp = millistamp; - //printf("(%f %f)\n ",bid,ask); + sprintf(name,"%s%s",reqbase,reqrel); + dpow_price("truefx",name,bid,ask); + //printf("[%s%s %f %f] buf.(%s) (%ld)\n ",base,rel,bid,ask,buf,strlen(&str[n])); break; } } @@ -154,6 +160,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang numbids = numasks = 0; bid = exchange_setquote(bidasks,&numbids,&numasks,0,invert,bid,volume,commission,0,(uint32_t)(millistamp/1000),0); ask = exchange_setquote(bidasks,&numbids,&numasks,1,invert,ask,volume,commission,0,(uint32_t)(millistamp/1000),0); + //printf("[%s/%s %.6f %.6f] ",base,rel,bid,ask); if ( bid > SMALLVAL && ask > SMALLVAL ) return((bid + ask) * .5); else return(0); diff --git a/iguana/exchanges/trust b/iguana/exchanges/trust new file mode 100755 index 000000000..6461f04c7 --- /dev/null +++ b/iguana/exchanges/trust @@ -0,0 +1,4 @@ +#!/bin/bash +echo "usage: ./trust " +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"pubkey\":\"$1\",\"method\":\"trust\",\"trust\":1}" diff --git a/iguana/exchanges/trusted b/iguana/exchanges/trusted new file mode 100755 index 000000000..fe96516e2 --- /dev/null +++ b/iguana/exchanges/trusted @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"trusted\"}" diff --git a/iguana/exchanges/unconf.c b/iguana/exchanges/unconf.c index d0cea56ab..951b6419d 100755 --- a/iguana/exchanges/unconf.c +++ b/iguana/exchanges/unconf.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/iguana/exchanges/userpass b/iguana/exchanges/userpass new file mode 100644 index 000000000..d097e0445 --- /dev/null +++ b/iguana/exchanges/userpass @@ -0,0 +1,2 @@ +#export userpass="" +export userpass="c3d8c2a364b7d18c1f9d7321d017b92e9f9c791e4f5c741214fefdea8a071256" diff --git a/iguana/exchanges/withdraw b/iguana/exchanges/withdraw new file mode 100755 index 000000000..8a78fa5a1 --- /dev/null +++ b/iguana/exchanges/withdraw @@ -0,0 +1,3 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"withdraw\",\"coin\":\"KMD\",\"outputs\":[{\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.001}, {\"RUgW6fLfVsLJ87Ng4zJTqNedJSKYQ9ToAf\":0.002}]}" diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index 1b713c8df..960e500c3 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -44,9 +44,9 @@ #define INSTANTDEX_OFFERDURATION 600 //#define INSTANTDEX_LOCKTIME 3600 -#define EXCHANGES777_MINPOLLGAP 1 +#define EXCHANGES777_MINPOLLGAP 3 #define EXCHANGES777_MAXDEPTH 200 -#define EXCHANGES777_DEFAULT_TIMEOUT 30 +#define EXCHANGES777_DEFAULT_TIMEOUT 60 typedef void CURL; struct exchange_info; struct exchange_quote; @@ -83,10 +83,10 @@ struct exchange_info struct instantdex_msghdr { - struct acct777_sig sig __attribute__((packed)); + struct acct777_sig sig; // __attribute__((packed)) char cmd[8]; uint8_t serialized[]; -} __attribute__((packed)); +}; // __attribute__((packed)) #define NXT_ASSETID ('N' + ((uint64_t)'X'<<8) + ((uint64_t)'T'<<16)) // 5527630 #define INSTANTDEX_ACCT "4383817337783094122" @@ -179,7 +179,7 @@ char *exchanges777_Qtrade(struct exchange_info *exchange,char *base,char *rel,in struct exchange_request *exchanges777_baserelfind(struct exchange_info *exchange,char *base,char *rel,int32_t func); struct exchange_info *exchanges777_find(char *exchangestr); -void prices777_processprice(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth); +void tradebots_processprices(struct supernet_info *myinfo,struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t numbids,int32_t numasks); double truefx_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert); double fxcm_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert); @@ -195,5 +195,6 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n); struct bitcoin_statetx *instantdex_feetx(struct supernet_info *myinfo,struct instantdex_accept *A,struct bitcoin_swapinfo *swap,struct iguana_info *coin); void instantdex_statemachine_iter(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap); void instantdex_historyadd(struct exchange_info *exchange,struct bitcoin_swapinfo *swap); +void dpow_price(char *exchange,char *name,double bid,double ask); #endif diff --git a/iguana/genbtcloop b/iguana/genbtcloop index 1b8e2d987..7cdd03750 100755 --- a/iguana/genbtcloop +++ b/iguana/genbtcloop @@ -2,5 +2,6 @@ while true do ../agents/iguana coins/genbtc.json sleep 3 +rm -rf tmp done diff --git a/iguana/genbtcloop8 b/iguana/genbtcloop8 new file mode 100755 index 000000000..64686708e --- /dev/null +++ b/iguana/genbtcloop8 @@ -0,0 +1,7 @@ +while true +do +../agents/iguana coins/genbtc8.json +sleep 3 +rm -rf tmp +done + diff --git a/iguana/groestl.c b/iguana/groestl.c new file mode 100644 index 000000000..0b7b20e03 --- /dev/null +++ b/iguana/groestl.c @@ -0,0 +1,3143 @@ +/* $Id: groestl.c 260 2011-07-21 01:02:38Z tp $ */ +/* + * Groestl implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#include +#include + +#include "groestl.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_GROESTL +#define SPH_SMALL_FOOTPRINT_GROESTL 1 +#endif + +/* + * Apparently, the 32-bit-only version is not faster than the 64-bit + * version unless using the "small footprint" code on a 32-bit machine. + */ +#if !defined SPH_GROESTL_64 +#if SPH_SMALL_FOOTPRINT_GROESTL && !SPH_64_TRUE +#define SPH_GROESTL_64 0 +#else +#define SPH_GROESTL_64 1 +#endif +#endif + +#if !SPH_64 +#undef SPH_GROESTL_64 +#endif + +#ifdef _MSC_VER +#pragma warning (disable: 4146) +#endif + +/* + * The internal representation may use either big-endian or + * little-endian. Using the platform default representation speeds up + * encoding and decoding between bytes and the matrix columns. + */ + +#undef USE_LE +#if SPH_GROESTL_LITTLE_ENDIAN +#define USE_LE 1 +#elif SPH_GROESTL_BIG_ENDIAN +#define USE_LE 0 +#elif SPH_LITTLE_ENDIAN +#define USE_LE 1 +#endif + +#if USE_LE + +#define C32e(x) ((SPH_C32(x) >> 24) \ + | ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \ + | ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \ + | ((SPH_C32(x) << 24) & SPH_C32(0xFF000000))) +#define dec32e_aligned sph_dec32le_aligned +#define enc32e sph_enc32le +#define B32_0(x) ((x) & 0xFF) +#define B32_1(x) (((x) >> 8) & 0xFF) +#define B32_2(x) (((x) >> 16) & 0xFF) +#define B32_3(x) ((x) >> 24) + +#define R32u(u, d) SPH_T32(((u) << 16) | ((d) >> 16)) +#define R32d(u, d) SPH_T32(((u) >> 16) | ((d) << 16)) + +#define PC32up(j, r) ((sph_u32)((j) + (r))) +#define PC32dn(j, r) 0 +#define QC32up(j, r) SPH_C32(0xFFFFFFFF) +#define QC32dn(j, r) (((sph_u32)(r) << 24) ^ SPH_T32(~((sph_u32)(j) << 24))) + +#if SPH_64 +#define C64e(x) ((SPH_C64(x) >> 56) \ + | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ + | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \ + | ((SPH_C64(x) >> 8) & SPH_C64(0x00000000FF000000)) \ + | ((SPH_C64(x) << 8) & SPH_C64(0x000000FF00000000)) \ + | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \ + | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \ + | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) +#define dec64e_aligned sph_dec64le_aligned +#define enc64e sph_enc64le +#define B64_0(x) ((x) & 0xFF) +#define B64_1(x) (((x) >> 8) & 0xFF) +#define B64_2(x) (((x) >> 16) & 0xFF) +#define B64_3(x) (((x) >> 24) & 0xFF) +#define B64_4(x) (((x) >> 32) & 0xFF) +#define B64_5(x) (((x) >> 40) & 0xFF) +#define B64_6(x) (((x) >> 48) & 0xFF) +#define B64_7(x) ((x) >> 56) +#define R64 SPH_ROTL64 +#define PC64(j, r) ((sph_u64)((j) + (r))) +#define QC64(j, r) (((sph_u64)(r) << 56) ^ SPH_T64(~((sph_u64)(j) << 56))) +#endif + +#else + +#define C32e(x) SPH_C32(x) +#define dec32e_aligned sph_dec32be_aligned +#define enc32e sph_enc32be +#define B32_0(x) ((x) >> 24) +#define B32_1(x) (((x) >> 16) & 0xFF) +#define B32_2(x) (((x) >> 8) & 0xFF) +#define B32_3(x) ((x) & 0xFF) + +#define R32u(u, d) SPH_T32(((u) >> 16) | ((d) << 16)) +#define R32d(u, d) SPH_T32(((u) << 16) | ((d) >> 16)) + +#define PC32up(j, r) ((sph_u32)((j) + (r)) << 24) +#define PC32dn(j, r) 0 +#define QC32up(j, r) SPH_C32(0xFFFFFFFF) +#define QC32dn(j, r) ((sph_u32)(r) ^ SPH_T32(~(sph_u32)(j))) + +#if SPH_64 +#define C64e(x) SPH_C64(x) +#define dec64e_aligned sph_dec64be_aligned +#define enc64e sph_enc64be +#define B64_0(x) ((x) >> 56) +#define B64_1(x) (((x) >> 48) & 0xFF) +#define B64_2(x) (((x) >> 40) & 0xFF) +#define B64_3(x) (((x) >> 32) & 0xFF) +#define B64_4(x) (((x) >> 24) & 0xFF) +#define B64_5(x) (((x) >> 16) & 0xFF) +#define B64_6(x) (((x) >> 8) & 0xFF) +#define B64_7(x) ((x) & 0xFF) +#define R64 SPH_ROTR64 +#define PC64(j, r) ((sph_u64)((j) + (r)) << 56) +#define QC64(j, r) ((sph_u64)(r) ^ SPH_T64(~(sph_u64)(j))) +#endif + +#endif + +#if SPH_GROESTL_64 + +static const sph_u64 T0[] = { + C64e(0xc632f4a5f497a5c6), C64e(0xf86f978497eb84f8), + C64e(0xee5eb099b0c799ee), C64e(0xf67a8c8d8cf78df6), + C64e(0xffe8170d17e50dff), C64e(0xd60adcbddcb7bdd6), + C64e(0xde16c8b1c8a7b1de), C64e(0x916dfc54fc395491), + C64e(0x6090f050f0c05060), C64e(0x0207050305040302), + C64e(0xce2ee0a9e087a9ce), C64e(0x56d1877d87ac7d56), + C64e(0xe7cc2b192bd519e7), C64e(0xb513a662a67162b5), + C64e(0x4d7c31e6319ae64d), C64e(0xec59b59ab5c39aec), + C64e(0x8f40cf45cf05458f), C64e(0x1fa3bc9dbc3e9d1f), + C64e(0x8949c040c0094089), C64e(0xfa68928792ef87fa), + C64e(0xefd03f153fc515ef), C64e(0xb29426eb267febb2), + C64e(0x8ece40c94007c98e), C64e(0xfbe61d0b1ded0bfb), + C64e(0x416e2fec2f82ec41), C64e(0xb31aa967a97d67b3), + C64e(0x5f431cfd1cbefd5f), C64e(0x456025ea258aea45), + C64e(0x23f9dabfda46bf23), C64e(0x535102f702a6f753), + C64e(0xe445a196a1d396e4), C64e(0x9b76ed5bed2d5b9b), + C64e(0x75285dc25deac275), C64e(0xe1c5241c24d91ce1), + C64e(0x3dd4e9aee97aae3d), C64e(0x4cf2be6abe986a4c), + C64e(0x6c82ee5aeed85a6c), C64e(0x7ebdc341c3fc417e), + C64e(0xf5f3060206f102f5), C64e(0x8352d14fd11d4f83), + C64e(0x688ce45ce4d05c68), C64e(0x515607f407a2f451), + C64e(0xd18d5c345cb934d1), C64e(0xf9e1180818e908f9), + C64e(0xe24cae93aedf93e2), C64e(0xab3e9573954d73ab), + C64e(0x6297f553f5c45362), C64e(0x2a6b413f41543f2a), + C64e(0x081c140c14100c08), C64e(0x9563f652f6315295), + C64e(0x46e9af65af8c6546), C64e(0x9d7fe25ee2215e9d), + C64e(0x3048782878602830), C64e(0x37cff8a1f86ea137), + C64e(0x0a1b110f11140f0a), C64e(0x2febc4b5c45eb52f), + C64e(0x0e151b091b1c090e), C64e(0x247e5a365a483624), + C64e(0x1badb69bb6369b1b), C64e(0xdf98473d47a53ddf), + C64e(0xcda76a266a8126cd), C64e(0x4ef5bb69bb9c694e), + C64e(0x7f334ccd4cfecd7f), C64e(0xea50ba9fbacf9fea), + C64e(0x123f2d1b2d241b12), C64e(0x1da4b99eb93a9e1d), + C64e(0x58c49c749cb07458), C64e(0x3446722e72682e34), + C64e(0x3641772d776c2d36), C64e(0xdc11cdb2cda3b2dc), + C64e(0xb49d29ee2973eeb4), C64e(0x5b4d16fb16b6fb5b), + C64e(0xa4a501f60153f6a4), C64e(0x76a1d74dd7ec4d76), + C64e(0xb714a361a37561b7), C64e(0x7d3449ce49face7d), + C64e(0x52df8d7b8da47b52), C64e(0xdd9f423e42a13edd), + C64e(0x5ecd937193bc715e), C64e(0x13b1a297a2269713), + C64e(0xa6a204f50457f5a6), C64e(0xb901b868b86968b9), + C64e(0x0000000000000000), C64e(0xc1b5742c74992cc1), + C64e(0x40e0a060a0806040), C64e(0xe3c2211f21dd1fe3), + C64e(0x793a43c843f2c879), C64e(0xb69a2ced2c77edb6), + C64e(0xd40dd9bed9b3bed4), C64e(0x8d47ca46ca01468d), + C64e(0x671770d970ced967), C64e(0x72afdd4bdde44b72), + C64e(0x94ed79de7933de94), C64e(0x98ff67d4672bd498), + C64e(0xb09323e8237be8b0), C64e(0x855bde4ade114a85), + C64e(0xbb06bd6bbd6d6bbb), C64e(0xc5bb7e2a7e912ac5), + C64e(0x4f7b34e5349ee54f), C64e(0xedd73a163ac116ed), + C64e(0x86d254c55417c586), C64e(0x9af862d7622fd79a), + C64e(0x6699ff55ffcc5566), C64e(0x11b6a794a7229411), + C64e(0x8ac04acf4a0fcf8a), C64e(0xe9d9301030c910e9), + C64e(0x040e0a060a080604), C64e(0xfe66988198e781fe), + C64e(0xa0ab0bf00b5bf0a0), C64e(0x78b4cc44ccf04478), + C64e(0x25f0d5bad54aba25), C64e(0x4b753ee33e96e34b), + C64e(0xa2ac0ef30e5ff3a2), C64e(0x5d4419fe19bafe5d), + C64e(0x80db5bc05b1bc080), C64e(0x0580858a850a8a05), + C64e(0x3fd3ecadec7ead3f), C64e(0x21fedfbcdf42bc21), + C64e(0x70a8d848d8e04870), C64e(0xf1fd0c040cf904f1), + C64e(0x63197adf7ac6df63), C64e(0x772f58c158eec177), + C64e(0xaf309f759f4575af), C64e(0x42e7a563a5846342), + C64e(0x2070503050403020), C64e(0xe5cb2e1a2ed11ae5), + C64e(0xfdef120e12e10efd), C64e(0xbf08b76db7656dbf), + C64e(0x8155d44cd4194c81), C64e(0x18243c143c301418), + C64e(0x26795f355f4c3526), C64e(0xc3b2712f719d2fc3), + C64e(0xbe8638e13867e1be), C64e(0x35c8fda2fd6aa235), + C64e(0x88c74fcc4f0bcc88), C64e(0x2e654b394b5c392e), + C64e(0x936af957f93d5793), C64e(0x55580df20daaf255), + C64e(0xfc619d829de382fc), C64e(0x7ab3c947c9f4477a), + C64e(0xc827efacef8bacc8), C64e(0xba8832e7326fe7ba), + C64e(0x324f7d2b7d642b32), C64e(0xe642a495a4d795e6), + C64e(0xc03bfba0fb9ba0c0), C64e(0x19aab398b3329819), + C64e(0x9ef668d16827d19e), C64e(0xa322817f815d7fa3), + C64e(0x44eeaa66aa886644), C64e(0x54d6827e82a87e54), + C64e(0x3bdde6abe676ab3b), C64e(0x0b959e839e16830b), + C64e(0x8cc945ca4503ca8c), C64e(0xc7bc7b297b9529c7), + C64e(0x6b056ed36ed6d36b), C64e(0x286c443c44503c28), + C64e(0xa72c8b798b5579a7), C64e(0xbc813de23d63e2bc), + C64e(0x1631271d272c1d16), C64e(0xad379a769a4176ad), + C64e(0xdb964d3b4dad3bdb), C64e(0x649efa56fac85664), + C64e(0x74a6d24ed2e84e74), C64e(0x1436221e22281e14), + C64e(0x92e476db763fdb92), C64e(0x0c121e0a1e180a0c), + C64e(0x48fcb46cb4906c48), C64e(0xb88f37e4376be4b8), + C64e(0x9f78e75de7255d9f), C64e(0xbd0fb26eb2616ebd), + C64e(0x43692aef2a86ef43), C64e(0xc435f1a6f193a6c4), + C64e(0x39dae3a8e372a839), C64e(0x31c6f7a4f762a431), + C64e(0xd38a593759bd37d3), C64e(0xf274868b86ff8bf2), + C64e(0xd583563256b132d5), C64e(0x8b4ec543c50d438b), + C64e(0x6e85eb59ebdc596e), C64e(0xda18c2b7c2afb7da), + C64e(0x018e8f8c8f028c01), C64e(0xb11dac64ac7964b1), + C64e(0x9cf16dd26d23d29c), C64e(0x49723be03b92e049), + C64e(0xd81fc7b4c7abb4d8), C64e(0xacb915fa1543faac), + C64e(0xf3fa090709fd07f3), C64e(0xcfa06f256f8525cf), + C64e(0xca20eaafea8fafca), C64e(0xf47d898e89f38ef4), + C64e(0x476720e9208ee947), C64e(0x1038281828201810), + C64e(0x6f0b64d564ded56f), C64e(0xf073838883fb88f0), + C64e(0x4afbb16fb1946f4a), C64e(0x5cca967296b8725c), + C64e(0x38546c246c702438), C64e(0x575f08f108aef157), + C64e(0x732152c752e6c773), C64e(0x9764f351f3355197), + C64e(0xcbae6523658d23cb), C64e(0xa125847c84597ca1), + C64e(0xe857bf9cbfcb9ce8), C64e(0x3e5d6321637c213e), + C64e(0x96ea7cdd7c37dd96), C64e(0x611e7fdc7fc2dc61), + C64e(0x0d9c9186911a860d), C64e(0x0f9b9485941e850f), + C64e(0xe04bab90abdb90e0), C64e(0x7cbac642c6f8427c), + C64e(0x712657c457e2c471), C64e(0xcc29e5aae583aacc), + C64e(0x90e373d8733bd890), C64e(0x06090f050f0c0506), + C64e(0xf7f4030103f501f7), C64e(0x1c2a36123638121c), + C64e(0xc23cfea3fe9fa3c2), C64e(0x6a8be15fe1d45f6a), + C64e(0xaebe10f91047f9ae), C64e(0x69026bd06bd2d069), + C64e(0x17bfa891a82e9117), C64e(0x9971e858e8295899), + C64e(0x3a5369276974273a), C64e(0x27f7d0b9d04eb927), + C64e(0xd991483848a938d9), C64e(0xebde351335cd13eb), + C64e(0x2be5ceb3ce56b32b), C64e(0x2277553355443322), + C64e(0xd204d6bbd6bfbbd2), C64e(0xa9399070904970a9), + C64e(0x07878089800e8907), C64e(0x33c1f2a7f266a733), + C64e(0x2decc1b6c15ab62d), C64e(0x3c5a66226678223c), + C64e(0x15b8ad92ad2a9215), C64e(0xc9a96020608920c9), + C64e(0x875cdb49db154987), C64e(0xaab01aff1a4fffaa), + C64e(0x50d8887888a07850), C64e(0xa52b8e7a8e517aa5), + C64e(0x03898a8f8a068f03), C64e(0x594a13f813b2f859), + C64e(0x09929b809b128009), C64e(0x1a2339173934171a), + C64e(0x651075da75cada65), C64e(0xd784533153b531d7), + C64e(0x84d551c65113c684), C64e(0xd003d3b8d3bbb8d0), + C64e(0x82dc5ec35e1fc382), C64e(0x29e2cbb0cb52b029), + C64e(0x5ac3997799b4775a), C64e(0x1e2d3311333c111e), + C64e(0x7b3d46cb46f6cb7b), C64e(0xa8b71ffc1f4bfca8), + C64e(0x6d0c61d661dad66d), C64e(0x2c624e3a4e583a2c) +}; + +#if !SPH_SMALL_FOOTPRINT_GROESTL + +static const sph_u64 T1[] = { + C64e(0xc6c632f4a5f497a5), C64e(0xf8f86f978497eb84), + C64e(0xeeee5eb099b0c799), C64e(0xf6f67a8c8d8cf78d), + C64e(0xffffe8170d17e50d), C64e(0xd6d60adcbddcb7bd), + C64e(0xdede16c8b1c8a7b1), C64e(0x91916dfc54fc3954), + C64e(0x606090f050f0c050), C64e(0x0202070503050403), + C64e(0xcece2ee0a9e087a9), C64e(0x5656d1877d87ac7d), + C64e(0xe7e7cc2b192bd519), C64e(0xb5b513a662a67162), + C64e(0x4d4d7c31e6319ae6), C64e(0xecec59b59ab5c39a), + C64e(0x8f8f40cf45cf0545), C64e(0x1f1fa3bc9dbc3e9d), + C64e(0x898949c040c00940), C64e(0xfafa68928792ef87), + C64e(0xefefd03f153fc515), C64e(0xb2b29426eb267feb), + C64e(0x8e8ece40c94007c9), C64e(0xfbfbe61d0b1ded0b), + C64e(0x41416e2fec2f82ec), C64e(0xb3b31aa967a97d67), + C64e(0x5f5f431cfd1cbefd), C64e(0x45456025ea258aea), + C64e(0x2323f9dabfda46bf), C64e(0x53535102f702a6f7), + C64e(0xe4e445a196a1d396), C64e(0x9b9b76ed5bed2d5b), + C64e(0x7575285dc25deac2), C64e(0xe1e1c5241c24d91c), + C64e(0x3d3dd4e9aee97aae), C64e(0x4c4cf2be6abe986a), + C64e(0x6c6c82ee5aeed85a), C64e(0x7e7ebdc341c3fc41), + C64e(0xf5f5f3060206f102), C64e(0x838352d14fd11d4f), + C64e(0x68688ce45ce4d05c), C64e(0x51515607f407a2f4), + C64e(0xd1d18d5c345cb934), C64e(0xf9f9e1180818e908), + C64e(0xe2e24cae93aedf93), C64e(0xabab3e9573954d73), + C64e(0x626297f553f5c453), C64e(0x2a2a6b413f41543f), + C64e(0x08081c140c14100c), C64e(0x959563f652f63152), + C64e(0x4646e9af65af8c65), C64e(0x9d9d7fe25ee2215e), + C64e(0x3030487828786028), C64e(0x3737cff8a1f86ea1), + C64e(0x0a0a1b110f11140f), C64e(0x2f2febc4b5c45eb5), + C64e(0x0e0e151b091b1c09), C64e(0x24247e5a365a4836), + C64e(0x1b1badb69bb6369b), C64e(0xdfdf98473d47a53d), + C64e(0xcdcda76a266a8126), C64e(0x4e4ef5bb69bb9c69), + C64e(0x7f7f334ccd4cfecd), C64e(0xeaea50ba9fbacf9f), + C64e(0x12123f2d1b2d241b), C64e(0x1d1da4b99eb93a9e), + C64e(0x5858c49c749cb074), C64e(0x343446722e72682e), + C64e(0x363641772d776c2d), C64e(0xdcdc11cdb2cda3b2), + C64e(0xb4b49d29ee2973ee), C64e(0x5b5b4d16fb16b6fb), + C64e(0xa4a4a501f60153f6), C64e(0x7676a1d74dd7ec4d), + C64e(0xb7b714a361a37561), C64e(0x7d7d3449ce49face), + C64e(0x5252df8d7b8da47b), C64e(0xdddd9f423e42a13e), + C64e(0x5e5ecd937193bc71), C64e(0x1313b1a297a22697), + C64e(0xa6a6a204f50457f5), C64e(0xb9b901b868b86968), + C64e(0x0000000000000000), C64e(0xc1c1b5742c74992c), + C64e(0x4040e0a060a08060), C64e(0xe3e3c2211f21dd1f), + C64e(0x79793a43c843f2c8), C64e(0xb6b69a2ced2c77ed), + C64e(0xd4d40dd9bed9b3be), C64e(0x8d8d47ca46ca0146), + C64e(0x67671770d970ced9), C64e(0x7272afdd4bdde44b), + C64e(0x9494ed79de7933de), C64e(0x9898ff67d4672bd4), + C64e(0xb0b09323e8237be8), C64e(0x85855bde4ade114a), + C64e(0xbbbb06bd6bbd6d6b), C64e(0xc5c5bb7e2a7e912a), + C64e(0x4f4f7b34e5349ee5), C64e(0xededd73a163ac116), + C64e(0x8686d254c55417c5), C64e(0x9a9af862d7622fd7), + C64e(0x666699ff55ffcc55), C64e(0x1111b6a794a72294), + C64e(0x8a8ac04acf4a0fcf), C64e(0xe9e9d9301030c910), + C64e(0x04040e0a060a0806), C64e(0xfefe66988198e781), + C64e(0xa0a0ab0bf00b5bf0), C64e(0x7878b4cc44ccf044), + C64e(0x2525f0d5bad54aba), C64e(0x4b4b753ee33e96e3), + C64e(0xa2a2ac0ef30e5ff3), C64e(0x5d5d4419fe19bafe), + C64e(0x8080db5bc05b1bc0), C64e(0x050580858a850a8a), + C64e(0x3f3fd3ecadec7ead), C64e(0x2121fedfbcdf42bc), + C64e(0x7070a8d848d8e048), C64e(0xf1f1fd0c040cf904), + C64e(0x6363197adf7ac6df), C64e(0x77772f58c158eec1), + C64e(0xafaf309f759f4575), C64e(0x4242e7a563a58463), + C64e(0x2020705030504030), C64e(0xe5e5cb2e1a2ed11a), + C64e(0xfdfdef120e12e10e), C64e(0xbfbf08b76db7656d), + C64e(0x818155d44cd4194c), C64e(0x1818243c143c3014), + C64e(0x2626795f355f4c35), C64e(0xc3c3b2712f719d2f), + C64e(0xbebe8638e13867e1), C64e(0x3535c8fda2fd6aa2), + C64e(0x8888c74fcc4f0bcc), C64e(0x2e2e654b394b5c39), + C64e(0x93936af957f93d57), C64e(0x5555580df20daaf2), + C64e(0xfcfc619d829de382), C64e(0x7a7ab3c947c9f447), + C64e(0xc8c827efacef8bac), C64e(0xbaba8832e7326fe7), + C64e(0x32324f7d2b7d642b), C64e(0xe6e642a495a4d795), + C64e(0xc0c03bfba0fb9ba0), C64e(0x1919aab398b33298), + C64e(0x9e9ef668d16827d1), C64e(0xa3a322817f815d7f), + C64e(0x4444eeaa66aa8866), C64e(0x5454d6827e82a87e), + C64e(0x3b3bdde6abe676ab), C64e(0x0b0b959e839e1683), + C64e(0x8c8cc945ca4503ca), C64e(0xc7c7bc7b297b9529), + C64e(0x6b6b056ed36ed6d3), C64e(0x28286c443c44503c), + C64e(0xa7a72c8b798b5579), C64e(0xbcbc813de23d63e2), + C64e(0x161631271d272c1d), C64e(0xadad379a769a4176), + C64e(0xdbdb964d3b4dad3b), C64e(0x64649efa56fac856), + C64e(0x7474a6d24ed2e84e), C64e(0x141436221e22281e), + C64e(0x9292e476db763fdb), C64e(0x0c0c121e0a1e180a), + C64e(0x4848fcb46cb4906c), C64e(0xb8b88f37e4376be4), + C64e(0x9f9f78e75de7255d), C64e(0xbdbd0fb26eb2616e), + C64e(0x4343692aef2a86ef), C64e(0xc4c435f1a6f193a6), + C64e(0x3939dae3a8e372a8), C64e(0x3131c6f7a4f762a4), + C64e(0xd3d38a593759bd37), C64e(0xf2f274868b86ff8b), + C64e(0xd5d583563256b132), C64e(0x8b8b4ec543c50d43), + C64e(0x6e6e85eb59ebdc59), C64e(0xdada18c2b7c2afb7), + C64e(0x01018e8f8c8f028c), C64e(0xb1b11dac64ac7964), + C64e(0x9c9cf16dd26d23d2), C64e(0x4949723be03b92e0), + C64e(0xd8d81fc7b4c7abb4), C64e(0xacacb915fa1543fa), + C64e(0xf3f3fa090709fd07), C64e(0xcfcfa06f256f8525), + C64e(0xcaca20eaafea8faf), C64e(0xf4f47d898e89f38e), + C64e(0x47476720e9208ee9), C64e(0x1010382818282018), + C64e(0x6f6f0b64d564ded5), C64e(0xf0f073838883fb88), + C64e(0x4a4afbb16fb1946f), C64e(0x5c5cca967296b872), + C64e(0x3838546c246c7024), C64e(0x57575f08f108aef1), + C64e(0x73732152c752e6c7), C64e(0x979764f351f33551), + C64e(0xcbcbae6523658d23), C64e(0xa1a125847c84597c), + C64e(0xe8e857bf9cbfcb9c), C64e(0x3e3e5d6321637c21), + C64e(0x9696ea7cdd7c37dd), C64e(0x61611e7fdc7fc2dc), + C64e(0x0d0d9c9186911a86), C64e(0x0f0f9b9485941e85), + C64e(0xe0e04bab90abdb90), C64e(0x7c7cbac642c6f842), + C64e(0x71712657c457e2c4), C64e(0xcccc29e5aae583aa), + C64e(0x9090e373d8733bd8), C64e(0x0606090f050f0c05), + C64e(0xf7f7f4030103f501), C64e(0x1c1c2a3612363812), + C64e(0xc2c23cfea3fe9fa3), C64e(0x6a6a8be15fe1d45f), + C64e(0xaeaebe10f91047f9), C64e(0x6969026bd06bd2d0), + C64e(0x1717bfa891a82e91), C64e(0x999971e858e82958), + C64e(0x3a3a536927697427), C64e(0x2727f7d0b9d04eb9), + C64e(0xd9d991483848a938), C64e(0xebebde351335cd13), + C64e(0x2b2be5ceb3ce56b3), C64e(0x2222775533554433), + C64e(0xd2d204d6bbd6bfbb), C64e(0xa9a9399070904970), + C64e(0x0707878089800e89), C64e(0x3333c1f2a7f266a7), + C64e(0x2d2decc1b6c15ab6), C64e(0x3c3c5a6622667822), + C64e(0x1515b8ad92ad2a92), C64e(0xc9c9a96020608920), + C64e(0x87875cdb49db1549), C64e(0xaaaab01aff1a4fff), + C64e(0x5050d8887888a078), C64e(0xa5a52b8e7a8e517a), + C64e(0x0303898a8f8a068f), C64e(0x59594a13f813b2f8), + C64e(0x0909929b809b1280), C64e(0x1a1a233917393417), + C64e(0x65651075da75cada), C64e(0xd7d784533153b531), + C64e(0x8484d551c65113c6), C64e(0xd0d003d3b8d3bbb8), + C64e(0x8282dc5ec35e1fc3), C64e(0x2929e2cbb0cb52b0), + C64e(0x5a5ac3997799b477), C64e(0x1e1e2d3311333c11), + C64e(0x7b7b3d46cb46f6cb), C64e(0xa8a8b71ffc1f4bfc), + C64e(0x6d6d0c61d661dad6), C64e(0x2c2c624e3a4e583a) +}; + +static const sph_u64 T2[] = { + C64e(0xa5c6c632f4a5f497), C64e(0x84f8f86f978497eb), + C64e(0x99eeee5eb099b0c7), C64e(0x8df6f67a8c8d8cf7), + C64e(0x0dffffe8170d17e5), C64e(0xbdd6d60adcbddcb7), + C64e(0xb1dede16c8b1c8a7), C64e(0x5491916dfc54fc39), + C64e(0x50606090f050f0c0), C64e(0x0302020705030504), + C64e(0xa9cece2ee0a9e087), C64e(0x7d5656d1877d87ac), + C64e(0x19e7e7cc2b192bd5), C64e(0x62b5b513a662a671), + C64e(0xe64d4d7c31e6319a), C64e(0x9aecec59b59ab5c3), + C64e(0x458f8f40cf45cf05), C64e(0x9d1f1fa3bc9dbc3e), + C64e(0x40898949c040c009), C64e(0x87fafa68928792ef), + C64e(0x15efefd03f153fc5), C64e(0xebb2b29426eb267f), + C64e(0xc98e8ece40c94007), C64e(0x0bfbfbe61d0b1ded), + C64e(0xec41416e2fec2f82), C64e(0x67b3b31aa967a97d), + C64e(0xfd5f5f431cfd1cbe), C64e(0xea45456025ea258a), + C64e(0xbf2323f9dabfda46), C64e(0xf753535102f702a6), + C64e(0x96e4e445a196a1d3), C64e(0x5b9b9b76ed5bed2d), + C64e(0xc27575285dc25dea), C64e(0x1ce1e1c5241c24d9), + C64e(0xae3d3dd4e9aee97a), C64e(0x6a4c4cf2be6abe98), + C64e(0x5a6c6c82ee5aeed8), C64e(0x417e7ebdc341c3fc), + C64e(0x02f5f5f3060206f1), C64e(0x4f838352d14fd11d), + C64e(0x5c68688ce45ce4d0), C64e(0xf451515607f407a2), + C64e(0x34d1d18d5c345cb9), C64e(0x08f9f9e1180818e9), + C64e(0x93e2e24cae93aedf), C64e(0x73abab3e9573954d), + C64e(0x53626297f553f5c4), C64e(0x3f2a2a6b413f4154), + C64e(0x0c08081c140c1410), C64e(0x52959563f652f631), + C64e(0x654646e9af65af8c), C64e(0x5e9d9d7fe25ee221), + C64e(0x2830304878287860), C64e(0xa13737cff8a1f86e), + C64e(0x0f0a0a1b110f1114), C64e(0xb52f2febc4b5c45e), + C64e(0x090e0e151b091b1c), C64e(0x3624247e5a365a48), + C64e(0x9b1b1badb69bb636), C64e(0x3ddfdf98473d47a5), + C64e(0x26cdcda76a266a81), C64e(0x694e4ef5bb69bb9c), + C64e(0xcd7f7f334ccd4cfe), C64e(0x9feaea50ba9fbacf), + C64e(0x1b12123f2d1b2d24), C64e(0x9e1d1da4b99eb93a), + C64e(0x745858c49c749cb0), C64e(0x2e343446722e7268), + C64e(0x2d363641772d776c), C64e(0xb2dcdc11cdb2cda3), + C64e(0xeeb4b49d29ee2973), C64e(0xfb5b5b4d16fb16b6), + C64e(0xf6a4a4a501f60153), C64e(0x4d7676a1d74dd7ec), + C64e(0x61b7b714a361a375), C64e(0xce7d7d3449ce49fa), + C64e(0x7b5252df8d7b8da4), C64e(0x3edddd9f423e42a1), + C64e(0x715e5ecd937193bc), C64e(0x971313b1a297a226), + C64e(0xf5a6a6a204f50457), C64e(0x68b9b901b868b869), + C64e(0x0000000000000000), C64e(0x2cc1c1b5742c7499), + C64e(0x604040e0a060a080), C64e(0x1fe3e3c2211f21dd), + C64e(0xc879793a43c843f2), C64e(0xedb6b69a2ced2c77), + C64e(0xbed4d40dd9bed9b3), C64e(0x468d8d47ca46ca01), + C64e(0xd967671770d970ce), C64e(0x4b7272afdd4bdde4), + C64e(0xde9494ed79de7933), C64e(0xd49898ff67d4672b), + C64e(0xe8b0b09323e8237b), C64e(0x4a85855bde4ade11), + C64e(0x6bbbbb06bd6bbd6d), C64e(0x2ac5c5bb7e2a7e91), + C64e(0xe54f4f7b34e5349e), C64e(0x16ededd73a163ac1), + C64e(0xc58686d254c55417), C64e(0xd79a9af862d7622f), + C64e(0x55666699ff55ffcc), C64e(0x941111b6a794a722), + C64e(0xcf8a8ac04acf4a0f), C64e(0x10e9e9d9301030c9), + C64e(0x0604040e0a060a08), C64e(0x81fefe66988198e7), + C64e(0xf0a0a0ab0bf00b5b), C64e(0x447878b4cc44ccf0), + C64e(0xba2525f0d5bad54a), C64e(0xe34b4b753ee33e96), + C64e(0xf3a2a2ac0ef30e5f), C64e(0xfe5d5d4419fe19ba), + C64e(0xc08080db5bc05b1b), C64e(0x8a050580858a850a), + C64e(0xad3f3fd3ecadec7e), C64e(0xbc2121fedfbcdf42), + C64e(0x487070a8d848d8e0), C64e(0x04f1f1fd0c040cf9), + C64e(0xdf6363197adf7ac6), C64e(0xc177772f58c158ee), + C64e(0x75afaf309f759f45), C64e(0x634242e7a563a584), + C64e(0x3020207050305040), C64e(0x1ae5e5cb2e1a2ed1), + C64e(0x0efdfdef120e12e1), C64e(0x6dbfbf08b76db765), + C64e(0x4c818155d44cd419), C64e(0x141818243c143c30), + C64e(0x352626795f355f4c), C64e(0x2fc3c3b2712f719d), + C64e(0xe1bebe8638e13867), C64e(0xa23535c8fda2fd6a), + C64e(0xcc8888c74fcc4f0b), C64e(0x392e2e654b394b5c), + C64e(0x5793936af957f93d), C64e(0xf25555580df20daa), + C64e(0x82fcfc619d829de3), C64e(0x477a7ab3c947c9f4), + C64e(0xacc8c827efacef8b), C64e(0xe7baba8832e7326f), + C64e(0x2b32324f7d2b7d64), C64e(0x95e6e642a495a4d7), + C64e(0xa0c0c03bfba0fb9b), C64e(0x981919aab398b332), + C64e(0xd19e9ef668d16827), C64e(0x7fa3a322817f815d), + C64e(0x664444eeaa66aa88), C64e(0x7e5454d6827e82a8), + C64e(0xab3b3bdde6abe676), C64e(0x830b0b959e839e16), + C64e(0xca8c8cc945ca4503), C64e(0x29c7c7bc7b297b95), + C64e(0xd36b6b056ed36ed6), C64e(0x3c28286c443c4450), + C64e(0x79a7a72c8b798b55), C64e(0xe2bcbc813de23d63), + C64e(0x1d161631271d272c), C64e(0x76adad379a769a41), + C64e(0x3bdbdb964d3b4dad), C64e(0x5664649efa56fac8), + C64e(0x4e7474a6d24ed2e8), C64e(0x1e141436221e2228), + C64e(0xdb9292e476db763f), C64e(0x0a0c0c121e0a1e18), + C64e(0x6c4848fcb46cb490), C64e(0xe4b8b88f37e4376b), + C64e(0x5d9f9f78e75de725), C64e(0x6ebdbd0fb26eb261), + C64e(0xef4343692aef2a86), C64e(0xa6c4c435f1a6f193), + C64e(0xa83939dae3a8e372), C64e(0xa43131c6f7a4f762), + C64e(0x37d3d38a593759bd), C64e(0x8bf2f274868b86ff), + C64e(0x32d5d583563256b1), C64e(0x438b8b4ec543c50d), + C64e(0x596e6e85eb59ebdc), C64e(0xb7dada18c2b7c2af), + C64e(0x8c01018e8f8c8f02), C64e(0x64b1b11dac64ac79), + C64e(0xd29c9cf16dd26d23), C64e(0xe04949723be03b92), + C64e(0xb4d8d81fc7b4c7ab), C64e(0xfaacacb915fa1543), + C64e(0x07f3f3fa090709fd), C64e(0x25cfcfa06f256f85), + C64e(0xafcaca20eaafea8f), C64e(0x8ef4f47d898e89f3), + C64e(0xe947476720e9208e), C64e(0x1810103828182820), + C64e(0xd56f6f0b64d564de), C64e(0x88f0f073838883fb), + C64e(0x6f4a4afbb16fb194), C64e(0x725c5cca967296b8), + C64e(0x243838546c246c70), C64e(0xf157575f08f108ae), + C64e(0xc773732152c752e6), C64e(0x51979764f351f335), + C64e(0x23cbcbae6523658d), C64e(0x7ca1a125847c8459), + C64e(0x9ce8e857bf9cbfcb), C64e(0x213e3e5d6321637c), + C64e(0xdd9696ea7cdd7c37), C64e(0xdc61611e7fdc7fc2), + C64e(0x860d0d9c9186911a), C64e(0x850f0f9b9485941e), + C64e(0x90e0e04bab90abdb), C64e(0x427c7cbac642c6f8), + C64e(0xc471712657c457e2), C64e(0xaacccc29e5aae583), + C64e(0xd89090e373d8733b), C64e(0x050606090f050f0c), + C64e(0x01f7f7f4030103f5), C64e(0x121c1c2a36123638), + C64e(0xa3c2c23cfea3fe9f), C64e(0x5f6a6a8be15fe1d4), + C64e(0xf9aeaebe10f91047), C64e(0xd06969026bd06bd2), + C64e(0x911717bfa891a82e), C64e(0x58999971e858e829), + C64e(0x273a3a5369276974), C64e(0xb92727f7d0b9d04e), + C64e(0x38d9d991483848a9), C64e(0x13ebebde351335cd), + C64e(0xb32b2be5ceb3ce56), C64e(0x3322227755335544), + C64e(0xbbd2d204d6bbd6bf), C64e(0x70a9a93990709049), + C64e(0x890707878089800e), C64e(0xa73333c1f2a7f266), + C64e(0xb62d2decc1b6c15a), C64e(0x223c3c5a66226678), + C64e(0x921515b8ad92ad2a), C64e(0x20c9c9a960206089), + C64e(0x4987875cdb49db15), C64e(0xffaaaab01aff1a4f), + C64e(0x785050d8887888a0), C64e(0x7aa5a52b8e7a8e51), + C64e(0x8f0303898a8f8a06), C64e(0xf859594a13f813b2), + C64e(0x800909929b809b12), C64e(0x171a1a2339173934), + C64e(0xda65651075da75ca), C64e(0x31d7d784533153b5), + C64e(0xc68484d551c65113), C64e(0xb8d0d003d3b8d3bb), + C64e(0xc38282dc5ec35e1f), C64e(0xb02929e2cbb0cb52), + C64e(0x775a5ac3997799b4), C64e(0x111e1e2d3311333c), + C64e(0xcb7b7b3d46cb46f6), C64e(0xfca8a8b71ffc1f4b), + C64e(0xd66d6d0c61d661da), C64e(0x3a2c2c624e3a4e58) +}; + +static const sph_u64 T3[] = { + C64e(0x97a5c6c632f4a5f4), C64e(0xeb84f8f86f978497), + C64e(0xc799eeee5eb099b0), C64e(0xf78df6f67a8c8d8c), + C64e(0xe50dffffe8170d17), C64e(0xb7bdd6d60adcbddc), + C64e(0xa7b1dede16c8b1c8), C64e(0x395491916dfc54fc), + C64e(0xc050606090f050f0), C64e(0x0403020207050305), + C64e(0x87a9cece2ee0a9e0), C64e(0xac7d5656d1877d87), + C64e(0xd519e7e7cc2b192b), C64e(0x7162b5b513a662a6), + C64e(0x9ae64d4d7c31e631), C64e(0xc39aecec59b59ab5), + C64e(0x05458f8f40cf45cf), C64e(0x3e9d1f1fa3bc9dbc), + C64e(0x0940898949c040c0), C64e(0xef87fafa68928792), + C64e(0xc515efefd03f153f), C64e(0x7febb2b29426eb26), + C64e(0x07c98e8ece40c940), C64e(0xed0bfbfbe61d0b1d), + C64e(0x82ec41416e2fec2f), C64e(0x7d67b3b31aa967a9), + C64e(0xbefd5f5f431cfd1c), C64e(0x8aea45456025ea25), + C64e(0x46bf2323f9dabfda), C64e(0xa6f753535102f702), + C64e(0xd396e4e445a196a1), C64e(0x2d5b9b9b76ed5bed), + C64e(0xeac27575285dc25d), C64e(0xd91ce1e1c5241c24), + C64e(0x7aae3d3dd4e9aee9), C64e(0x986a4c4cf2be6abe), + C64e(0xd85a6c6c82ee5aee), C64e(0xfc417e7ebdc341c3), + C64e(0xf102f5f5f3060206), C64e(0x1d4f838352d14fd1), + C64e(0xd05c68688ce45ce4), C64e(0xa2f451515607f407), + C64e(0xb934d1d18d5c345c), C64e(0xe908f9f9e1180818), + C64e(0xdf93e2e24cae93ae), C64e(0x4d73abab3e957395), + C64e(0xc453626297f553f5), C64e(0x543f2a2a6b413f41), + C64e(0x100c08081c140c14), C64e(0x3152959563f652f6), + C64e(0x8c654646e9af65af), C64e(0x215e9d9d7fe25ee2), + C64e(0x6028303048782878), C64e(0x6ea13737cff8a1f8), + C64e(0x140f0a0a1b110f11), C64e(0x5eb52f2febc4b5c4), + C64e(0x1c090e0e151b091b), C64e(0x483624247e5a365a), + C64e(0x369b1b1badb69bb6), C64e(0xa53ddfdf98473d47), + C64e(0x8126cdcda76a266a), C64e(0x9c694e4ef5bb69bb), + C64e(0xfecd7f7f334ccd4c), C64e(0xcf9feaea50ba9fba), + C64e(0x241b12123f2d1b2d), C64e(0x3a9e1d1da4b99eb9), + C64e(0xb0745858c49c749c), C64e(0x682e343446722e72), + C64e(0x6c2d363641772d77), C64e(0xa3b2dcdc11cdb2cd), + C64e(0x73eeb4b49d29ee29), C64e(0xb6fb5b5b4d16fb16), + C64e(0x53f6a4a4a501f601), C64e(0xec4d7676a1d74dd7), + C64e(0x7561b7b714a361a3), C64e(0xface7d7d3449ce49), + C64e(0xa47b5252df8d7b8d), C64e(0xa13edddd9f423e42), + C64e(0xbc715e5ecd937193), C64e(0x26971313b1a297a2), + C64e(0x57f5a6a6a204f504), C64e(0x6968b9b901b868b8), + C64e(0x0000000000000000), C64e(0x992cc1c1b5742c74), + C64e(0x80604040e0a060a0), C64e(0xdd1fe3e3c2211f21), + C64e(0xf2c879793a43c843), C64e(0x77edb6b69a2ced2c), + C64e(0xb3bed4d40dd9bed9), C64e(0x01468d8d47ca46ca), + C64e(0xced967671770d970), C64e(0xe44b7272afdd4bdd), + C64e(0x33de9494ed79de79), C64e(0x2bd49898ff67d467), + C64e(0x7be8b0b09323e823), C64e(0x114a85855bde4ade), + C64e(0x6d6bbbbb06bd6bbd), C64e(0x912ac5c5bb7e2a7e), + C64e(0x9ee54f4f7b34e534), C64e(0xc116ededd73a163a), + C64e(0x17c58686d254c554), C64e(0x2fd79a9af862d762), + C64e(0xcc55666699ff55ff), C64e(0x22941111b6a794a7), + C64e(0x0fcf8a8ac04acf4a), C64e(0xc910e9e9d9301030), + C64e(0x080604040e0a060a), C64e(0xe781fefe66988198), + C64e(0x5bf0a0a0ab0bf00b), C64e(0xf0447878b4cc44cc), + C64e(0x4aba2525f0d5bad5), C64e(0x96e34b4b753ee33e), + C64e(0x5ff3a2a2ac0ef30e), C64e(0xbafe5d5d4419fe19), + C64e(0x1bc08080db5bc05b), C64e(0x0a8a050580858a85), + C64e(0x7ead3f3fd3ecadec), C64e(0x42bc2121fedfbcdf), + C64e(0xe0487070a8d848d8), C64e(0xf904f1f1fd0c040c), + C64e(0xc6df6363197adf7a), C64e(0xeec177772f58c158), + C64e(0x4575afaf309f759f), C64e(0x84634242e7a563a5), + C64e(0x4030202070503050), C64e(0xd11ae5e5cb2e1a2e), + C64e(0xe10efdfdef120e12), C64e(0x656dbfbf08b76db7), + C64e(0x194c818155d44cd4), C64e(0x30141818243c143c), + C64e(0x4c352626795f355f), C64e(0x9d2fc3c3b2712f71), + C64e(0x67e1bebe8638e138), C64e(0x6aa23535c8fda2fd), + C64e(0x0bcc8888c74fcc4f), C64e(0x5c392e2e654b394b), + C64e(0x3d5793936af957f9), C64e(0xaaf25555580df20d), + C64e(0xe382fcfc619d829d), C64e(0xf4477a7ab3c947c9), + C64e(0x8bacc8c827efacef), C64e(0x6fe7baba8832e732), + C64e(0x642b32324f7d2b7d), C64e(0xd795e6e642a495a4), + C64e(0x9ba0c0c03bfba0fb), C64e(0x32981919aab398b3), + C64e(0x27d19e9ef668d168), C64e(0x5d7fa3a322817f81), + C64e(0x88664444eeaa66aa), C64e(0xa87e5454d6827e82), + C64e(0x76ab3b3bdde6abe6), C64e(0x16830b0b959e839e), + C64e(0x03ca8c8cc945ca45), C64e(0x9529c7c7bc7b297b), + C64e(0xd6d36b6b056ed36e), C64e(0x503c28286c443c44), + C64e(0x5579a7a72c8b798b), C64e(0x63e2bcbc813de23d), + C64e(0x2c1d161631271d27), C64e(0x4176adad379a769a), + C64e(0xad3bdbdb964d3b4d), C64e(0xc85664649efa56fa), + C64e(0xe84e7474a6d24ed2), C64e(0x281e141436221e22), + C64e(0x3fdb9292e476db76), C64e(0x180a0c0c121e0a1e), + C64e(0x906c4848fcb46cb4), C64e(0x6be4b8b88f37e437), + C64e(0x255d9f9f78e75de7), C64e(0x616ebdbd0fb26eb2), + C64e(0x86ef4343692aef2a), C64e(0x93a6c4c435f1a6f1), + C64e(0x72a83939dae3a8e3), C64e(0x62a43131c6f7a4f7), + C64e(0xbd37d3d38a593759), C64e(0xff8bf2f274868b86), + C64e(0xb132d5d583563256), C64e(0x0d438b8b4ec543c5), + C64e(0xdc596e6e85eb59eb), C64e(0xafb7dada18c2b7c2), + C64e(0x028c01018e8f8c8f), C64e(0x7964b1b11dac64ac), + C64e(0x23d29c9cf16dd26d), C64e(0x92e04949723be03b), + C64e(0xabb4d8d81fc7b4c7), C64e(0x43faacacb915fa15), + C64e(0xfd07f3f3fa090709), C64e(0x8525cfcfa06f256f), + C64e(0x8fafcaca20eaafea), C64e(0xf38ef4f47d898e89), + C64e(0x8ee947476720e920), C64e(0x2018101038281828), + C64e(0xded56f6f0b64d564), C64e(0xfb88f0f073838883), + C64e(0x946f4a4afbb16fb1), C64e(0xb8725c5cca967296), + C64e(0x70243838546c246c), C64e(0xaef157575f08f108), + C64e(0xe6c773732152c752), C64e(0x3551979764f351f3), + C64e(0x8d23cbcbae652365), C64e(0x597ca1a125847c84), + C64e(0xcb9ce8e857bf9cbf), C64e(0x7c213e3e5d632163), + C64e(0x37dd9696ea7cdd7c), C64e(0xc2dc61611e7fdc7f), + C64e(0x1a860d0d9c918691), C64e(0x1e850f0f9b948594), + C64e(0xdb90e0e04bab90ab), C64e(0xf8427c7cbac642c6), + C64e(0xe2c471712657c457), C64e(0x83aacccc29e5aae5), + C64e(0x3bd89090e373d873), C64e(0x0c050606090f050f), + C64e(0xf501f7f7f4030103), C64e(0x38121c1c2a361236), + C64e(0x9fa3c2c23cfea3fe), C64e(0xd45f6a6a8be15fe1), + C64e(0x47f9aeaebe10f910), C64e(0xd2d06969026bd06b), + C64e(0x2e911717bfa891a8), C64e(0x2958999971e858e8), + C64e(0x74273a3a53692769), C64e(0x4eb92727f7d0b9d0), + C64e(0xa938d9d991483848), C64e(0xcd13ebebde351335), + C64e(0x56b32b2be5ceb3ce), C64e(0x4433222277553355), + C64e(0xbfbbd2d204d6bbd6), C64e(0x4970a9a939907090), + C64e(0x0e89070787808980), C64e(0x66a73333c1f2a7f2), + C64e(0x5ab62d2decc1b6c1), C64e(0x78223c3c5a662266), + C64e(0x2a921515b8ad92ad), C64e(0x8920c9c9a9602060), + C64e(0x154987875cdb49db), C64e(0x4fffaaaab01aff1a), + C64e(0xa0785050d8887888), C64e(0x517aa5a52b8e7a8e), + C64e(0x068f0303898a8f8a), C64e(0xb2f859594a13f813), + C64e(0x12800909929b809b), C64e(0x34171a1a23391739), + C64e(0xcada65651075da75), C64e(0xb531d7d784533153), + C64e(0x13c68484d551c651), C64e(0xbbb8d0d003d3b8d3), + C64e(0x1fc38282dc5ec35e), C64e(0x52b02929e2cbb0cb), + C64e(0xb4775a5ac3997799), C64e(0x3c111e1e2d331133), + C64e(0xf6cb7b7b3d46cb46), C64e(0x4bfca8a8b71ffc1f), + C64e(0xdad66d6d0c61d661), C64e(0x583a2c2c624e3a4e) +}; + +#endif + +static const sph_u64 T4[] = { + C64e(0xf497a5c6c632f4a5), C64e(0x97eb84f8f86f9784), + C64e(0xb0c799eeee5eb099), C64e(0x8cf78df6f67a8c8d), + C64e(0x17e50dffffe8170d), C64e(0xdcb7bdd6d60adcbd), + C64e(0xc8a7b1dede16c8b1), C64e(0xfc395491916dfc54), + C64e(0xf0c050606090f050), C64e(0x0504030202070503), + C64e(0xe087a9cece2ee0a9), C64e(0x87ac7d5656d1877d), + C64e(0x2bd519e7e7cc2b19), C64e(0xa67162b5b513a662), + C64e(0x319ae64d4d7c31e6), C64e(0xb5c39aecec59b59a), + C64e(0xcf05458f8f40cf45), C64e(0xbc3e9d1f1fa3bc9d), + C64e(0xc00940898949c040), C64e(0x92ef87fafa689287), + C64e(0x3fc515efefd03f15), C64e(0x267febb2b29426eb), + C64e(0x4007c98e8ece40c9), C64e(0x1ded0bfbfbe61d0b), + C64e(0x2f82ec41416e2fec), C64e(0xa97d67b3b31aa967), + C64e(0x1cbefd5f5f431cfd), C64e(0x258aea45456025ea), + C64e(0xda46bf2323f9dabf), C64e(0x02a6f753535102f7), + C64e(0xa1d396e4e445a196), C64e(0xed2d5b9b9b76ed5b), + C64e(0x5deac27575285dc2), C64e(0x24d91ce1e1c5241c), + C64e(0xe97aae3d3dd4e9ae), C64e(0xbe986a4c4cf2be6a), + C64e(0xeed85a6c6c82ee5a), C64e(0xc3fc417e7ebdc341), + C64e(0x06f102f5f5f30602), C64e(0xd11d4f838352d14f), + C64e(0xe4d05c68688ce45c), C64e(0x07a2f451515607f4), + C64e(0x5cb934d1d18d5c34), C64e(0x18e908f9f9e11808), + C64e(0xaedf93e2e24cae93), C64e(0x954d73abab3e9573), + C64e(0xf5c453626297f553), C64e(0x41543f2a2a6b413f), + C64e(0x14100c08081c140c), C64e(0xf63152959563f652), + C64e(0xaf8c654646e9af65), C64e(0xe2215e9d9d7fe25e), + C64e(0x7860283030487828), C64e(0xf86ea13737cff8a1), + C64e(0x11140f0a0a1b110f), C64e(0xc45eb52f2febc4b5), + C64e(0x1b1c090e0e151b09), C64e(0x5a483624247e5a36), + C64e(0xb6369b1b1badb69b), C64e(0x47a53ddfdf98473d), + C64e(0x6a8126cdcda76a26), C64e(0xbb9c694e4ef5bb69), + C64e(0x4cfecd7f7f334ccd), C64e(0xbacf9feaea50ba9f), + C64e(0x2d241b12123f2d1b), C64e(0xb93a9e1d1da4b99e), + C64e(0x9cb0745858c49c74), C64e(0x72682e343446722e), + C64e(0x776c2d363641772d), C64e(0xcda3b2dcdc11cdb2), + C64e(0x2973eeb4b49d29ee), C64e(0x16b6fb5b5b4d16fb), + C64e(0x0153f6a4a4a501f6), C64e(0xd7ec4d7676a1d74d), + C64e(0xa37561b7b714a361), C64e(0x49face7d7d3449ce), + C64e(0x8da47b5252df8d7b), C64e(0x42a13edddd9f423e), + C64e(0x93bc715e5ecd9371), C64e(0xa226971313b1a297), + C64e(0x0457f5a6a6a204f5), C64e(0xb86968b9b901b868), + C64e(0x0000000000000000), C64e(0x74992cc1c1b5742c), + C64e(0xa080604040e0a060), C64e(0x21dd1fe3e3c2211f), + C64e(0x43f2c879793a43c8), C64e(0x2c77edb6b69a2ced), + C64e(0xd9b3bed4d40dd9be), C64e(0xca01468d8d47ca46), + C64e(0x70ced967671770d9), C64e(0xdde44b7272afdd4b), + C64e(0x7933de9494ed79de), C64e(0x672bd49898ff67d4), + C64e(0x237be8b0b09323e8), C64e(0xde114a85855bde4a), + C64e(0xbd6d6bbbbb06bd6b), C64e(0x7e912ac5c5bb7e2a), + C64e(0x349ee54f4f7b34e5), C64e(0x3ac116ededd73a16), + C64e(0x5417c58686d254c5), C64e(0x622fd79a9af862d7), + C64e(0xffcc55666699ff55), C64e(0xa722941111b6a794), + C64e(0x4a0fcf8a8ac04acf), C64e(0x30c910e9e9d93010), + C64e(0x0a080604040e0a06), C64e(0x98e781fefe669881), + C64e(0x0b5bf0a0a0ab0bf0), C64e(0xccf0447878b4cc44), + C64e(0xd54aba2525f0d5ba), C64e(0x3e96e34b4b753ee3), + C64e(0x0e5ff3a2a2ac0ef3), C64e(0x19bafe5d5d4419fe), + C64e(0x5b1bc08080db5bc0), C64e(0x850a8a050580858a), + C64e(0xec7ead3f3fd3ecad), C64e(0xdf42bc2121fedfbc), + C64e(0xd8e0487070a8d848), C64e(0x0cf904f1f1fd0c04), + C64e(0x7ac6df6363197adf), C64e(0x58eec177772f58c1), + C64e(0x9f4575afaf309f75), C64e(0xa584634242e7a563), + C64e(0x5040302020705030), C64e(0x2ed11ae5e5cb2e1a), + C64e(0x12e10efdfdef120e), C64e(0xb7656dbfbf08b76d), + C64e(0xd4194c818155d44c), C64e(0x3c30141818243c14), + C64e(0x5f4c352626795f35), C64e(0x719d2fc3c3b2712f), + C64e(0x3867e1bebe8638e1), C64e(0xfd6aa23535c8fda2), + C64e(0x4f0bcc8888c74fcc), C64e(0x4b5c392e2e654b39), + C64e(0xf93d5793936af957), C64e(0x0daaf25555580df2), + C64e(0x9de382fcfc619d82), C64e(0xc9f4477a7ab3c947), + C64e(0xef8bacc8c827efac), C64e(0x326fe7baba8832e7), + C64e(0x7d642b32324f7d2b), C64e(0xa4d795e6e642a495), + C64e(0xfb9ba0c0c03bfba0), C64e(0xb332981919aab398), + C64e(0x6827d19e9ef668d1), C64e(0x815d7fa3a322817f), + C64e(0xaa88664444eeaa66), C64e(0x82a87e5454d6827e), + C64e(0xe676ab3b3bdde6ab), C64e(0x9e16830b0b959e83), + C64e(0x4503ca8c8cc945ca), C64e(0x7b9529c7c7bc7b29), + C64e(0x6ed6d36b6b056ed3), C64e(0x44503c28286c443c), + C64e(0x8b5579a7a72c8b79), C64e(0x3d63e2bcbc813de2), + C64e(0x272c1d161631271d), C64e(0x9a4176adad379a76), + C64e(0x4dad3bdbdb964d3b), C64e(0xfac85664649efa56), + C64e(0xd2e84e7474a6d24e), C64e(0x22281e141436221e), + C64e(0x763fdb9292e476db), C64e(0x1e180a0c0c121e0a), + C64e(0xb4906c4848fcb46c), C64e(0x376be4b8b88f37e4), + C64e(0xe7255d9f9f78e75d), C64e(0xb2616ebdbd0fb26e), + C64e(0x2a86ef4343692aef), C64e(0xf193a6c4c435f1a6), + C64e(0xe372a83939dae3a8), C64e(0xf762a43131c6f7a4), + C64e(0x59bd37d3d38a5937), C64e(0x86ff8bf2f274868b), + C64e(0x56b132d5d5835632), C64e(0xc50d438b8b4ec543), + C64e(0xebdc596e6e85eb59), C64e(0xc2afb7dada18c2b7), + C64e(0x8f028c01018e8f8c), C64e(0xac7964b1b11dac64), + C64e(0x6d23d29c9cf16dd2), C64e(0x3b92e04949723be0), + C64e(0xc7abb4d8d81fc7b4), C64e(0x1543faacacb915fa), + C64e(0x09fd07f3f3fa0907), C64e(0x6f8525cfcfa06f25), + C64e(0xea8fafcaca20eaaf), C64e(0x89f38ef4f47d898e), + C64e(0x208ee947476720e9), C64e(0x2820181010382818), + C64e(0x64ded56f6f0b64d5), C64e(0x83fb88f0f0738388), + C64e(0xb1946f4a4afbb16f), C64e(0x96b8725c5cca9672), + C64e(0x6c70243838546c24), C64e(0x08aef157575f08f1), + C64e(0x52e6c773732152c7), C64e(0xf33551979764f351), + C64e(0x658d23cbcbae6523), C64e(0x84597ca1a125847c), + C64e(0xbfcb9ce8e857bf9c), C64e(0x637c213e3e5d6321), + C64e(0x7c37dd9696ea7cdd), C64e(0x7fc2dc61611e7fdc), + C64e(0x911a860d0d9c9186), C64e(0x941e850f0f9b9485), + C64e(0xabdb90e0e04bab90), C64e(0xc6f8427c7cbac642), + C64e(0x57e2c471712657c4), C64e(0xe583aacccc29e5aa), + C64e(0x733bd89090e373d8), C64e(0x0f0c050606090f05), + C64e(0x03f501f7f7f40301), C64e(0x3638121c1c2a3612), + C64e(0xfe9fa3c2c23cfea3), C64e(0xe1d45f6a6a8be15f), + C64e(0x1047f9aeaebe10f9), C64e(0x6bd2d06969026bd0), + C64e(0xa82e911717bfa891), C64e(0xe82958999971e858), + C64e(0x6974273a3a536927), C64e(0xd04eb92727f7d0b9), + C64e(0x48a938d9d9914838), C64e(0x35cd13ebebde3513), + C64e(0xce56b32b2be5ceb3), C64e(0x5544332222775533), + C64e(0xd6bfbbd2d204d6bb), C64e(0x904970a9a9399070), + C64e(0x800e890707878089), C64e(0xf266a73333c1f2a7), + C64e(0xc15ab62d2decc1b6), C64e(0x6678223c3c5a6622), + C64e(0xad2a921515b8ad92), C64e(0x608920c9c9a96020), + C64e(0xdb154987875cdb49), C64e(0x1a4fffaaaab01aff), + C64e(0x88a0785050d88878), C64e(0x8e517aa5a52b8e7a), + C64e(0x8a068f0303898a8f), C64e(0x13b2f859594a13f8), + C64e(0x9b12800909929b80), C64e(0x3934171a1a233917), + C64e(0x75cada65651075da), C64e(0x53b531d7d7845331), + C64e(0x5113c68484d551c6), C64e(0xd3bbb8d0d003d3b8), + C64e(0x5e1fc38282dc5ec3), C64e(0xcb52b02929e2cbb0), + C64e(0x99b4775a5ac39977), C64e(0x333c111e1e2d3311), + C64e(0x46f6cb7b7b3d46cb), C64e(0x1f4bfca8a8b71ffc), + C64e(0x61dad66d6d0c61d6), C64e(0x4e583a2c2c624e3a) +}; + +#if !SPH_SMALL_FOOTPRINT_GROESTL + +static const sph_u64 T5[] = { + C64e(0xa5f497a5c6c632f4), C64e(0x8497eb84f8f86f97), + C64e(0x99b0c799eeee5eb0), C64e(0x8d8cf78df6f67a8c), + C64e(0x0d17e50dffffe817), C64e(0xbddcb7bdd6d60adc), + C64e(0xb1c8a7b1dede16c8), C64e(0x54fc395491916dfc), + C64e(0x50f0c050606090f0), C64e(0x0305040302020705), + C64e(0xa9e087a9cece2ee0), C64e(0x7d87ac7d5656d187), + C64e(0x192bd519e7e7cc2b), C64e(0x62a67162b5b513a6), + C64e(0xe6319ae64d4d7c31), C64e(0x9ab5c39aecec59b5), + C64e(0x45cf05458f8f40cf), C64e(0x9dbc3e9d1f1fa3bc), + C64e(0x40c00940898949c0), C64e(0x8792ef87fafa6892), + C64e(0x153fc515efefd03f), C64e(0xeb267febb2b29426), + C64e(0xc94007c98e8ece40), C64e(0x0b1ded0bfbfbe61d), + C64e(0xec2f82ec41416e2f), C64e(0x67a97d67b3b31aa9), + C64e(0xfd1cbefd5f5f431c), C64e(0xea258aea45456025), + C64e(0xbfda46bf2323f9da), C64e(0xf702a6f753535102), + C64e(0x96a1d396e4e445a1), C64e(0x5bed2d5b9b9b76ed), + C64e(0xc25deac27575285d), C64e(0x1c24d91ce1e1c524), + C64e(0xaee97aae3d3dd4e9), C64e(0x6abe986a4c4cf2be), + C64e(0x5aeed85a6c6c82ee), C64e(0x41c3fc417e7ebdc3), + C64e(0x0206f102f5f5f306), C64e(0x4fd11d4f838352d1), + C64e(0x5ce4d05c68688ce4), C64e(0xf407a2f451515607), + C64e(0x345cb934d1d18d5c), C64e(0x0818e908f9f9e118), + C64e(0x93aedf93e2e24cae), C64e(0x73954d73abab3e95), + C64e(0x53f5c453626297f5), C64e(0x3f41543f2a2a6b41), + C64e(0x0c14100c08081c14), C64e(0x52f63152959563f6), + C64e(0x65af8c654646e9af), C64e(0x5ee2215e9d9d7fe2), + C64e(0x2878602830304878), C64e(0xa1f86ea13737cff8), + C64e(0x0f11140f0a0a1b11), C64e(0xb5c45eb52f2febc4), + C64e(0x091b1c090e0e151b), C64e(0x365a483624247e5a), + C64e(0x9bb6369b1b1badb6), C64e(0x3d47a53ddfdf9847), + C64e(0x266a8126cdcda76a), C64e(0x69bb9c694e4ef5bb), + C64e(0xcd4cfecd7f7f334c), C64e(0x9fbacf9feaea50ba), + C64e(0x1b2d241b12123f2d), C64e(0x9eb93a9e1d1da4b9), + C64e(0x749cb0745858c49c), C64e(0x2e72682e34344672), + C64e(0x2d776c2d36364177), C64e(0xb2cda3b2dcdc11cd), + C64e(0xee2973eeb4b49d29), C64e(0xfb16b6fb5b5b4d16), + C64e(0xf60153f6a4a4a501), C64e(0x4dd7ec4d7676a1d7), + C64e(0x61a37561b7b714a3), C64e(0xce49face7d7d3449), + C64e(0x7b8da47b5252df8d), C64e(0x3e42a13edddd9f42), + C64e(0x7193bc715e5ecd93), C64e(0x97a226971313b1a2), + C64e(0xf50457f5a6a6a204), C64e(0x68b86968b9b901b8), + C64e(0x0000000000000000), C64e(0x2c74992cc1c1b574), + C64e(0x60a080604040e0a0), C64e(0x1f21dd1fe3e3c221), + C64e(0xc843f2c879793a43), C64e(0xed2c77edb6b69a2c), + C64e(0xbed9b3bed4d40dd9), C64e(0x46ca01468d8d47ca), + C64e(0xd970ced967671770), C64e(0x4bdde44b7272afdd), + C64e(0xde7933de9494ed79), C64e(0xd4672bd49898ff67), + C64e(0xe8237be8b0b09323), C64e(0x4ade114a85855bde), + C64e(0x6bbd6d6bbbbb06bd), C64e(0x2a7e912ac5c5bb7e), + C64e(0xe5349ee54f4f7b34), C64e(0x163ac116ededd73a), + C64e(0xc55417c58686d254), C64e(0xd7622fd79a9af862), + C64e(0x55ffcc55666699ff), C64e(0x94a722941111b6a7), + C64e(0xcf4a0fcf8a8ac04a), C64e(0x1030c910e9e9d930), + C64e(0x060a080604040e0a), C64e(0x8198e781fefe6698), + C64e(0xf00b5bf0a0a0ab0b), C64e(0x44ccf0447878b4cc), + C64e(0xbad54aba2525f0d5), C64e(0xe33e96e34b4b753e), + C64e(0xf30e5ff3a2a2ac0e), C64e(0xfe19bafe5d5d4419), + C64e(0xc05b1bc08080db5b), C64e(0x8a850a8a05058085), + C64e(0xadec7ead3f3fd3ec), C64e(0xbcdf42bc2121fedf), + C64e(0x48d8e0487070a8d8), C64e(0x040cf904f1f1fd0c), + C64e(0xdf7ac6df6363197a), C64e(0xc158eec177772f58), + C64e(0x759f4575afaf309f), C64e(0x63a584634242e7a5), + C64e(0x3050403020207050), C64e(0x1a2ed11ae5e5cb2e), + C64e(0x0e12e10efdfdef12), C64e(0x6db7656dbfbf08b7), + C64e(0x4cd4194c818155d4), C64e(0x143c30141818243c), + C64e(0x355f4c352626795f), C64e(0x2f719d2fc3c3b271), + C64e(0xe13867e1bebe8638), C64e(0xa2fd6aa23535c8fd), + C64e(0xcc4f0bcc8888c74f), C64e(0x394b5c392e2e654b), + C64e(0x57f93d5793936af9), C64e(0xf20daaf25555580d), + C64e(0x829de382fcfc619d), C64e(0x47c9f4477a7ab3c9), + C64e(0xacef8bacc8c827ef), C64e(0xe7326fe7baba8832), + C64e(0x2b7d642b32324f7d), C64e(0x95a4d795e6e642a4), + C64e(0xa0fb9ba0c0c03bfb), C64e(0x98b332981919aab3), + C64e(0xd16827d19e9ef668), C64e(0x7f815d7fa3a32281), + C64e(0x66aa88664444eeaa), C64e(0x7e82a87e5454d682), + C64e(0xabe676ab3b3bdde6), C64e(0x839e16830b0b959e), + C64e(0xca4503ca8c8cc945), C64e(0x297b9529c7c7bc7b), + C64e(0xd36ed6d36b6b056e), C64e(0x3c44503c28286c44), + C64e(0x798b5579a7a72c8b), C64e(0xe23d63e2bcbc813d), + C64e(0x1d272c1d16163127), C64e(0x769a4176adad379a), + C64e(0x3b4dad3bdbdb964d), C64e(0x56fac85664649efa), + C64e(0x4ed2e84e7474a6d2), C64e(0x1e22281e14143622), + C64e(0xdb763fdb9292e476), C64e(0x0a1e180a0c0c121e), + C64e(0x6cb4906c4848fcb4), C64e(0xe4376be4b8b88f37), + C64e(0x5de7255d9f9f78e7), C64e(0x6eb2616ebdbd0fb2), + C64e(0xef2a86ef4343692a), C64e(0xa6f193a6c4c435f1), + C64e(0xa8e372a83939dae3), C64e(0xa4f762a43131c6f7), + C64e(0x3759bd37d3d38a59), C64e(0x8b86ff8bf2f27486), + C64e(0x3256b132d5d58356), C64e(0x43c50d438b8b4ec5), + C64e(0x59ebdc596e6e85eb), C64e(0xb7c2afb7dada18c2), + C64e(0x8c8f028c01018e8f), C64e(0x64ac7964b1b11dac), + C64e(0xd26d23d29c9cf16d), C64e(0xe03b92e04949723b), + C64e(0xb4c7abb4d8d81fc7), C64e(0xfa1543faacacb915), + C64e(0x0709fd07f3f3fa09), C64e(0x256f8525cfcfa06f), + C64e(0xafea8fafcaca20ea), C64e(0x8e89f38ef4f47d89), + C64e(0xe9208ee947476720), C64e(0x1828201810103828), + C64e(0xd564ded56f6f0b64), C64e(0x8883fb88f0f07383), + C64e(0x6fb1946f4a4afbb1), C64e(0x7296b8725c5cca96), + C64e(0x246c70243838546c), C64e(0xf108aef157575f08), + C64e(0xc752e6c773732152), C64e(0x51f33551979764f3), + C64e(0x23658d23cbcbae65), C64e(0x7c84597ca1a12584), + C64e(0x9cbfcb9ce8e857bf), C64e(0x21637c213e3e5d63), + C64e(0xdd7c37dd9696ea7c), C64e(0xdc7fc2dc61611e7f), + C64e(0x86911a860d0d9c91), C64e(0x85941e850f0f9b94), + C64e(0x90abdb90e0e04bab), C64e(0x42c6f8427c7cbac6), + C64e(0xc457e2c471712657), C64e(0xaae583aacccc29e5), + C64e(0xd8733bd89090e373), C64e(0x050f0c050606090f), + C64e(0x0103f501f7f7f403), C64e(0x123638121c1c2a36), + C64e(0xa3fe9fa3c2c23cfe), C64e(0x5fe1d45f6a6a8be1), + C64e(0xf91047f9aeaebe10), C64e(0xd06bd2d06969026b), + C64e(0x91a82e911717bfa8), C64e(0x58e82958999971e8), + C64e(0x276974273a3a5369), C64e(0xb9d04eb92727f7d0), + C64e(0x3848a938d9d99148), C64e(0x1335cd13ebebde35), + C64e(0xb3ce56b32b2be5ce), C64e(0x3355443322227755), + C64e(0xbbd6bfbbd2d204d6), C64e(0x70904970a9a93990), + C64e(0x89800e8907078780), C64e(0xa7f266a73333c1f2), + C64e(0xb6c15ab62d2decc1), C64e(0x226678223c3c5a66), + C64e(0x92ad2a921515b8ad), C64e(0x20608920c9c9a960), + C64e(0x49db154987875cdb), C64e(0xff1a4fffaaaab01a), + C64e(0x7888a0785050d888), C64e(0x7a8e517aa5a52b8e), + C64e(0x8f8a068f0303898a), C64e(0xf813b2f859594a13), + C64e(0x809b12800909929b), C64e(0x173934171a1a2339), + C64e(0xda75cada65651075), C64e(0x3153b531d7d78453), + C64e(0xc65113c68484d551), C64e(0xb8d3bbb8d0d003d3), + C64e(0xc35e1fc38282dc5e), C64e(0xb0cb52b02929e2cb), + C64e(0x7799b4775a5ac399), C64e(0x11333c111e1e2d33), + C64e(0xcb46f6cb7b7b3d46), C64e(0xfc1f4bfca8a8b71f), + C64e(0xd661dad66d6d0c61), C64e(0x3a4e583a2c2c624e) +}; + +static const sph_u64 T6[] = { + C64e(0xf4a5f497a5c6c632), C64e(0x978497eb84f8f86f), + C64e(0xb099b0c799eeee5e), C64e(0x8c8d8cf78df6f67a), + C64e(0x170d17e50dffffe8), C64e(0xdcbddcb7bdd6d60a), + C64e(0xc8b1c8a7b1dede16), C64e(0xfc54fc395491916d), + C64e(0xf050f0c050606090), C64e(0x0503050403020207), + C64e(0xe0a9e087a9cece2e), C64e(0x877d87ac7d5656d1), + C64e(0x2b192bd519e7e7cc), C64e(0xa662a67162b5b513), + C64e(0x31e6319ae64d4d7c), C64e(0xb59ab5c39aecec59), + C64e(0xcf45cf05458f8f40), C64e(0xbc9dbc3e9d1f1fa3), + C64e(0xc040c00940898949), C64e(0x928792ef87fafa68), + C64e(0x3f153fc515efefd0), C64e(0x26eb267febb2b294), + C64e(0x40c94007c98e8ece), C64e(0x1d0b1ded0bfbfbe6), + C64e(0x2fec2f82ec41416e), C64e(0xa967a97d67b3b31a), + C64e(0x1cfd1cbefd5f5f43), C64e(0x25ea258aea454560), + C64e(0xdabfda46bf2323f9), C64e(0x02f702a6f7535351), + C64e(0xa196a1d396e4e445), C64e(0xed5bed2d5b9b9b76), + C64e(0x5dc25deac2757528), C64e(0x241c24d91ce1e1c5), + C64e(0xe9aee97aae3d3dd4), C64e(0xbe6abe986a4c4cf2), + C64e(0xee5aeed85a6c6c82), C64e(0xc341c3fc417e7ebd), + C64e(0x060206f102f5f5f3), C64e(0xd14fd11d4f838352), + C64e(0xe45ce4d05c68688c), C64e(0x07f407a2f4515156), + C64e(0x5c345cb934d1d18d), C64e(0x180818e908f9f9e1), + C64e(0xae93aedf93e2e24c), C64e(0x9573954d73abab3e), + C64e(0xf553f5c453626297), C64e(0x413f41543f2a2a6b), + C64e(0x140c14100c08081c), C64e(0xf652f63152959563), + C64e(0xaf65af8c654646e9), C64e(0xe25ee2215e9d9d7f), + C64e(0x7828786028303048), C64e(0xf8a1f86ea13737cf), + C64e(0x110f11140f0a0a1b), C64e(0xc4b5c45eb52f2feb), + C64e(0x1b091b1c090e0e15), C64e(0x5a365a483624247e), + C64e(0xb69bb6369b1b1bad), C64e(0x473d47a53ddfdf98), + C64e(0x6a266a8126cdcda7), C64e(0xbb69bb9c694e4ef5), + C64e(0x4ccd4cfecd7f7f33), C64e(0xba9fbacf9feaea50), + C64e(0x2d1b2d241b12123f), C64e(0xb99eb93a9e1d1da4), + C64e(0x9c749cb0745858c4), C64e(0x722e72682e343446), + C64e(0x772d776c2d363641), C64e(0xcdb2cda3b2dcdc11), + C64e(0x29ee2973eeb4b49d), C64e(0x16fb16b6fb5b5b4d), + C64e(0x01f60153f6a4a4a5), C64e(0xd74dd7ec4d7676a1), + C64e(0xa361a37561b7b714), C64e(0x49ce49face7d7d34), + C64e(0x8d7b8da47b5252df), C64e(0x423e42a13edddd9f), + C64e(0x937193bc715e5ecd), C64e(0xa297a226971313b1), + C64e(0x04f50457f5a6a6a2), C64e(0xb868b86968b9b901), + C64e(0x0000000000000000), C64e(0x742c74992cc1c1b5), + C64e(0xa060a080604040e0), C64e(0x211f21dd1fe3e3c2), + C64e(0x43c843f2c879793a), C64e(0x2ced2c77edb6b69a), + C64e(0xd9bed9b3bed4d40d), C64e(0xca46ca01468d8d47), + C64e(0x70d970ced9676717), C64e(0xdd4bdde44b7272af), + C64e(0x79de7933de9494ed), C64e(0x67d4672bd49898ff), + C64e(0x23e8237be8b0b093), C64e(0xde4ade114a85855b), + C64e(0xbd6bbd6d6bbbbb06), C64e(0x7e2a7e912ac5c5bb), + C64e(0x34e5349ee54f4f7b), C64e(0x3a163ac116ededd7), + C64e(0x54c55417c58686d2), C64e(0x62d7622fd79a9af8), + C64e(0xff55ffcc55666699), C64e(0xa794a722941111b6), + C64e(0x4acf4a0fcf8a8ac0), C64e(0x301030c910e9e9d9), + C64e(0x0a060a080604040e), C64e(0x988198e781fefe66), + C64e(0x0bf00b5bf0a0a0ab), C64e(0xcc44ccf0447878b4), + C64e(0xd5bad54aba2525f0), C64e(0x3ee33e96e34b4b75), + C64e(0x0ef30e5ff3a2a2ac), C64e(0x19fe19bafe5d5d44), + C64e(0x5bc05b1bc08080db), C64e(0x858a850a8a050580), + C64e(0xecadec7ead3f3fd3), C64e(0xdfbcdf42bc2121fe), + C64e(0xd848d8e0487070a8), C64e(0x0c040cf904f1f1fd), + C64e(0x7adf7ac6df636319), C64e(0x58c158eec177772f), + C64e(0x9f759f4575afaf30), C64e(0xa563a584634242e7), + C64e(0x5030504030202070), C64e(0x2e1a2ed11ae5e5cb), + C64e(0x120e12e10efdfdef), C64e(0xb76db7656dbfbf08), + C64e(0xd44cd4194c818155), C64e(0x3c143c3014181824), + C64e(0x5f355f4c35262679), C64e(0x712f719d2fc3c3b2), + C64e(0x38e13867e1bebe86), C64e(0xfda2fd6aa23535c8), + C64e(0x4fcc4f0bcc8888c7), C64e(0x4b394b5c392e2e65), + C64e(0xf957f93d5793936a), C64e(0x0df20daaf2555558), + C64e(0x9d829de382fcfc61), C64e(0xc947c9f4477a7ab3), + C64e(0xefacef8bacc8c827), C64e(0x32e7326fe7baba88), + C64e(0x7d2b7d642b32324f), C64e(0xa495a4d795e6e642), + C64e(0xfba0fb9ba0c0c03b), C64e(0xb398b332981919aa), + C64e(0x68d16827d19e9ef6), C64e(0x817f815d7fa3a322), + C64e(0xaa66aa88664444ee), C64e(0x827e82a87e5454d6), + C64e(0xe6abe676ab3b3bdd), C64e(0x9e839e16830b0b95), + C64e(0x45ca4503ca8c8cc9), C64e(0x7b297b9529c7c7bc), + C64e(0x6ed36ed6d36b6b05), C64e(0x443c44503c28286c), + C64e(0x8b798b5579a7a72c), C64e(0x3de23d63e2bcbc81), + C64e(0x271d272c1d161631), C64e(0x9a769a4176adad37), + C64e(0x4d3b4dad3bdbdb96), C64e(0xfa56fac85664649e), + C64e(0xd24ed2e84e7474a6), C64e(0x221e22281e141436), + C64e(0x76db763fdb9292e4), C64e(0x1e0a1e180a0c0c12), + C64e(0xb46cb4906c4848fc), C64e(0x37e4376be4b8b88f), + C64e(0xe75de7255d9f9f78), C64e(0xb26eb2616ebdbd0f), + C64e(0x2aef2a86ef434369), C64e(0xf1a6f193a6c4c435), + C64e(0xe3a8e372a83939da), C64e(0xf7a4f762a43131c6), + C64e(0x593759bd37d3d38a), C64e(0x868b86ff8bf2f274), + C64e(0x563256b132d5d583), C64e(0xc543c50d438b8b4e), + C64e(0xeb59ebdc596e6e85), C64e(0xc2b7c2afb7dada18), + C64e(0x8f8c8f028c01018e), C64e(0xac64ac7964b1b11d), + C64e(0x6dd26d23d29c9cf1), C64e(0x3be03b92e0494972), + C64e(0xc7b4c7abb4d8d81f), C64e(0x15fa1543faacacb9), + C64e(0x090709fd07f3f3fa), C64e(0x6f256f8525cfcfa0), + C64e(0xeaafea8fafcaca20), C64e(0x898e89f38ef4f47d), + C64e(0x20e9208ee9474767), C64e(0x2818282018101038), + C64e(0x64d564ded56f6f0b), C64e(0x838883fb88f0f073), + C64e(0xb16fb1946f4a4afb), C64e(0x967296b8725c5cca), + C64e(0x6c246c7024383854), C64e(0x08f108aef157575f), + C64e(0x52c752e6c7737321), C64e(0xf351f33551979764), + C64e(0x6523658d23cbcbae), C64e(0x847c84597ca1a125), + C64e(0xbf9cbfcb9ce8e857), C64e(0x6321637c213e3e5d), + C64e(0x7cdd7c37dd9696ea), C64e(0x7fdc7fc2dc61611e), + C64e(0x9186911a860d0d9c), C64e(0x9485941e850f0f9b), + C64e(0xab90abdb90e0e04b), C64e(0xc642c6f8427c7cba), + C64e(0x57c457e2c4717126), C64e(0xe5aae583aacccc29), + C64e(0x73d8733bd89090e3), C64e(0x0f050f0c05060609), + C64e(0x030103f501f7f7f4), C64e(0x36123638121c1c2a), + C64e(0xfea3fe9fa3c2c23c), C64e(0xe15fe1d45f6a6a8b), + C64e(0x10f91047f9aeaebe), C64e(0x6bd06bd2d0696902), + C64e(0xa891a82e911717bf), C64e(0xe858e82958999971), + C64e(0x69276974273a3a53), C64e(0xd0b9d04eb92727f7), + C64e(0x483848a938d9d991), C64e(0x351335cd13ebebde), + C64e(0xceb3ce56b32b2be5), C64e(0x5533554433222277), + C64e(0xd6bbd6bfbbd2d204), C64e(0x9070904970a9a939), + C64e(0x8089800e89070787), C64e(0xf2a7f266a73333c1), + C64e(0xc1b6c15ab62d2dec), C64e(0x66226678223c3c5a), + C64e(0xad92ad2a921515b8), C64e(0x6020608920c9c9a9), + C64e(0xdb49db154987875c), C64e(0x1aff1a4fffaaaab0), + C64e(0x887888a0785050d8), C64e(0x8e7a8e517aa5a52b), + C64e(0x8a8f8a068f030389), C64e(0x13f813b2f859594a), + C64e(0x9b809b1280090992), C64e(0x39173934171a1a23), + C64e(0x75da75cada656510), C64e(0x533153b531d7d784), + C64e(0x51c65113c68484d5), C64e(0xd3b8d3bbb8d0d003), + C64e(0x5ec35e1fc38282dc), C64e(0xcbb0cb52b02929e2), + C64e(0x997799b4775a5ac3), C64e(0x3311333c111e1e2d), + C64e(0x46cb46f6cb7b7b3d), C64e(0x1ffc1f4bfca8a8b7), + C64e(0x61d661dad66d6d0c), C64e(0x4e3a4e583a2c2c62) +}; + +static const sph_u64 T7[] = { + C64e(0x32f4a5f497a5c6c6), C64e(0x6f978497eb84f8f8), + C64e(0x5eb099b0c799eeee), C64e(0x7a8c8d8cf78df6f6), + C64e(0xe8170d17e50dffff), C64e(0x0adcbddcb7bdd6d6), + C64e(0x16c8b1c8a7b1dede), C64e(0x6dfc54fc39549191), + C64e(0x90f050f0c0506060), C64e(0x0705030504030202), + C64e(0x2ee0a9e087a9cece), C64e(0xd1877d87ac7d5656), + C64e(0xcc2b192bd519e7e7), C64e(0x13a662a67162b5b5), + C64e(0x7c31e6319ae64d4d), C64e(0x59b59ab5c39aecec), + C64e(0x40cf45cf05458f8f), C64e(0xa3bc9dbc3e9d1f1f), + C64e(0x49c040c009408989), C64e(0x68928792ef87fafa), + C64e(0xd03f153fc515efef), C64e(0x9426eb267febb2b2), + C64e(0xce40c94007c98e8e), C64e(0xe61d0b1ded0bfbfb), + C64e(0x6e2fec2f82ec4141), C64e(0x1aa967a97d67b3b3), + C64e(0x431cfd1cbefd5f5f), C64e(0x6025ea258aea4545), + C64e(0xf9dabfda46bf2323), C64e(0x5102f702a6f75353), + C64e(0x45a196a1d396e4e4), C64e(0x76ed5bed2d5b9b9b), + C64e(0x285dc25deac27575), C64e(0xc5241c24d91ce1e1), + C64e(0xd4e9aee97aae3d3d), C64e(0xf2be6abe986a4c4c), + C64e(0x82ee5aeed85a6c6c), C64e(0xbdc341c3fc417e7e), + C64e(0xf3060206f102f5f5), C64e(0x52d14fd11d4f8383), + C64e(0x8ce45ce4d05c6868), C64e(0x5607f407a2f45151), + C64e(0x8d5c345cb934d1d1), C64e(0xe1180818e908f9f9), + C64e(0x4cae93aedf93e2e2), C64e(0x3e9573954d73abab), + C64e(0x97f553f5c4536262), C64e(0x6b413f41543f2a2a), + C64e(0x1c140c14100c0808), C64e(0x63f652f631529595), + C64e(0xe9af65af8c654646), C64e(0x7fe25ee2215e9d9d), + C64e(0x4878287860283030), C64e(0xcff8a1f86ea13737), + C64e(0x1b110f11140f0a0a), C64e(0xebc4b5c45eb52f2f), + C64e(0x151b091b1c090e0e), C64e(0x7e5a365a48362424), + C64e(0xadb69bb6369b1b1b), C64e(0x98473d47a53ddfdf), + C64e(0xa76a266a8126cdcd), C64e(0xf5bb69bb9c694e4e), + C64e(0x334ccd4cfecd7f7f), C64e(0x50ba9fbacf9feaea), + C64e(0x3f2d1b2d241b1212), C64e(0xa4b99eb93a9e1d1d), + C64e(0xc49c749cb0745858), C64e(0x46722e72682e3434), + C64e(0x41772d776c2d3636), C64e(0x11cdb2cda3b2dcdc), + C64e(0x9d29ee2973eeb4b4), C64e(0x4d16fb16b6fb5b5b), + C64e(0xa501f60153f6a4a4), C64e(0xa1d74dd7ec4d7676), + C64e(0x14a361a37561b7b7), C64e(0x3449ce49face7d7d), + C64e(0xdf8d7b8da47b5252), C64e(0x9f423e42a13edddd), + C64e(0xcd937193bc715e5e), C64e(0xb1a297a226971313), + C64e(0xa204f50457f5a6a6), C64e(0x01b868b86968b9b9), + C64e(0x0000000000000000), C64e(0xb5742c74992cc1c1), + C64e(0xe0a060a080604040), C64e(0xc2211f21dd1fe3e3), + C64e(0x3a43c843f2c87979), C64e(0x9a2ced2c77edb6b6), + C64e(0x0dd9bed9b3bed4d4), C64e(0x47ca46ca01468d8d), + C64e(0x1770d970ced96767), C64e(0xafdd4bdde44b7272), + C64e(0xed79de7933de9494), C64e(0xff67d4672bd49898), + C64e(0x9323e8237be8b0b0), C64e(0x5bde4ade114a8585), + C64e(0x06bd6bbd6d6bbbbb), C64e(0xbb7e2a7e912ac5c5), + C64e(0x7b34e5349ee54f4f), C64e(0xd73a163ac116eded), + C64e(0xd254c55417c58686), C64e(0xf862d7622fd79a9a), + C64e(0x99ff55ffcc556666), C64e(0xb6a794a722941111), + C64e(0xc04acf4a0fcf8a8a), C64e(0xd9301030c910e9e9), + C64e(0x0e0a060a08060404), C64e(0x66988198e781fefe), + C64e(0xab0bf00b5bf0a0a0), C64e(0xb4cc44ccf0447878), + C64e(0xf0d5bad54aba2525), C64e(0x753ee33e96e34b4b), + C64e(0xac0ef30e5ff3a2a2), C64e(0x4419fe19bafe5d5d), + C64e(0xdb5bc05b1bc08080), C64e(0x80858a850a8a0505), + C64e(0xd3ecadec7ead3f3f), C64e(0xfedfbcdf42bc2121), + C64e(0xa8d848d8e0487070), C64e(0xfd0c040cf904f1f1), + C64e(0x197adf7ac6df6363), C64e(0x2f58c158eec17777), + C64e(0x309f759f4575afaf), C64e(0xe7a563a584634242), + C64e(0x7050305040302020), C64e(0xcb2e1a2ed11ae5e5), + C64e(0xef120e12e10efdfd), C64e(0x08b76db7656dbfbf), + C64e(0x55d44cd4194c8181), C64e(0x243c143c30141818), + C64e(0x795f355f4c352626), C64e(0xb2712f719d2fc3c3), + C64e(0x8638e13867e1bebe), C64e(0xc8fda2fd6aa23535), + C64e(0xc74fcc4f0bcc8888), C64e(0x654b394b5c392e2e), + C64e(0x6af957f93d579393), C64e(0x580df20daaf25555), + C64e(0x619d829de382fcfc), C64e(0xb3c947c9f4477a7a), + C64e(0x27efacef8bacc8c8), C64e(0x8832e7326fe7baba), + C64e(0x4f7d2b7d642b3232), C64e(0x42a495a4d795e6e6), + C64e(0x3bfba0fb9ba0c0c0), C64e(0xaab398b332981919), + C64e(0xf668d16827d19e9e), C64e(0x22817f815d7fa3a3), + C64e(0xeeaa66aa88664444), C64e(0xd6827e82a87e5454), + C64e(0xdde6abe676ab3b3b), C64e(0x959e839e16830b0b), + C64e(0xc945ca4503ca8c8c), C64e(0xbc7b297b9529c7c7), + C64e(0x056ed36ed6d36b6b), C64e(0x6c443c44503c2828), + C64e(0x2c8b798b5579a7a7), C64e(0x813de23d63e2bcbc), + C64e(0x31271d272c1d1616), C64e(0x379a769a4176adad), + C64e(0x964d3b4dad3bdbdb), C64e(0x9efa56fac8566464), + C64e(0xa6d24ed2e84e7474), C64e(0x36221e22281e1414), + C64e(0xe476db763fdb9292), C64e(0x121e0a1e180a0c0c), + C64e(0xfcb46cb4906c4848), C64e(0x8f37e4376be4b8b8), + C64e(0x78e75de7255d9f9f), C64e(0x0fb26eb2616ebdbd), + C64e(0x692aef2a86ef4343), C64e(0x35f1a6f193a6c4c4), + C64e(0xdae3a8e372a83939), C64e(0xc6f7a4f762a43131), + C64e(0x8a593759bd37d3d3), C64e(0x74868b86ff8bf2f2), + C64e(0x83563256b132d5d5), C64e(0x4ec543c50d438b8b), + C64e(0x85eb59ebdc596e6e), C64e(0x18c2b7c2afb7dada), + C64e(0x8e8f8c8f028c0101), C64e(0x1dac64ac7964b1b1), + C64e(0xf16dd26d23d29c9c), C64e(0x723be03b92e04949), + C64e(0x1fc7b4c7abb4d8d8), C64e(0xb915fa1543faacac), + C64e(0xfa090709fd07f3f3), C64e(0xa06f256f8525cfcf), + C64e(0x20eaafea8fafcaca), C64e(0x7d898e89f38ef4f4), + C64e(0x6720e9208ee94747), C64e(0x3828182820181010), + C64e(0x0b64d564ded56f6f), C64e(0x73838883fb88f0f0), + C64e(0xfbb16fb1946f4a4a), C64e(0xca967296b8725c5c), + C64e(0x546c246c70243838), C64e(0x5f08f108aef15757), + C64e(0x2152c752e6c77373), C64e(0x64f351f335519797), + C64e(0xae6523658d23cbcb), C64e(0x25847c84597ca1a1), + C64e(0x57bf9cbfcb9ce8e8), C64e(0x5d6321637c213e3e), + C64e(0xea7cdd7c37dd9696), C64e(0x1e7fdc7fc2dc6161), + C64e(0x9c9186911a860d0d), C64e(0x9b9485941e850f0f), + C64e(0x4bab90abdb90e0e0), C64e(0xbac642c6f8427c7c), + C64e(0x2657c457e2c47171), C64e(0x29e5aae583aacccc), + C64e(0xe373d8733bd89090), C64e(0x090f050f0c050606), + C64e(0xf4030103f501f7f7), C64e(0x2a36123638121c1c), + C64e(0x3cfea3fe9fa3c2c2), C64e(0x8be15fe1d45f6a6a), + C64e(0xbe10f91047f9aeae), C64e(0x026bd06bd2d06969), + C64e(0xbfa891a82e911717), C64e(0x71e858e829589999), + C64e(0x5369276974273a3a), C64e(0xf7d0b9d04eb92727), + C64e(0x91483848a938d9d9), C64e(0xde351335cd13ebeb), + C64e(0xe5ceb3ce56b32b2b), C64e(0x7755335544332222), + C64e(0x04d6bbd6bfbbd2d2), C64e(0x399070904970a9a9), + C64e(0x878089800e890707), C64e(0xc1f2a7f266a73333), + C64e(0xecc1b6c15ab62d2d), C64e(0x5a66226678223c3c), + C64e(0xb8ad92ad2a921515), C64e(0xa96020608920c9c9), + C64e(0x5cdb49db15498787), C64e(0xb01aff1a4fffaaaa), + C64e(0xd8887888a0785050), C64e(0x2b8e7a8e517aa5a5), + C64e(0x898a8f8a068f0303), C64e(0x4a13f813b2f85959), + C64e(0x929b809b12800909), C64e(0x2339173934171a1a), + C64e(0x1075da75cada6565), C64e(0x84533153b531d7d7), + C64e(0xd551c65113c68484), C64e(0x03d3b8d3bbb8d0d0), + C64e(0xdc5ec35e1fc38282), C64e(0xe2cbb0cb52b02929), + C64e(0xc3997799b4775a5a), C64e(0x2d3311333c111e1e), + C64e(0x3d46cb46f6cb7b7b), C64e(0xb71ffc1f4bfca8a8), + C64e(0x0c61d661dad66d6d), C64e(0x624e3a4e583a2c2c) +}; + +#endif + +#define DECL_STATE_SMALL \ + sph_u64 H[8]; + +#define READ_STATE_SMALL(sc) do { \ + memcpy(H, (sc)->state.wide, sizeof H); \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + memcpy((sc)->state.wide, H, sizeof H); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ R64(T0[B64_1(a[b1])], 8) \ + ^ R64(T0[B64_2(a[b2])], 16) \ + ^ R64(T0[B64_3(a[b3])], 24) \ + ^ T4[B64_4(a[b4])] \ + ^ R64(T4[B64_5(a[b5])], 8) \ + ^ R64(T4[B64_6(a[b6])], 16) \ + ^ R64(T4[B64_7(a[b7])], 24); \ + } while (0) + +#else + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ T1[B64_1(a[b1])] \ + ^ T2[B64_2(a[b2])] \ + ^ T3[B64_3(a[b3])] \ + ^ T4[B64_4(a[b4])] \ + ^ T5[B64_5(a[b5])] \ + ^ T6[B64_6(a[b6])] \ + ^ T7[B64_7(a[b7])]; \ + } while (0) + +#endif + +#define ROUND_SMALL_P(a, r) do { \ + sph_u64 t[8]; \ + a[0] ^= PC64(0x00, r); \ + a[1] ^= PC64(0x10, r); \ + a[2] ^= PC64(0x20, r); \ + a[3] ^= PC64(0x30, r); \ + a[4] ^= PC64(0x40, r); \ + a[5] ^= PC64(0x50, r); \ + a[6] ^= PC64(0x60, r); \ + a[7] ^= PC64(0x70, r); \ + RSTT(0, a, 0, 1, 2, 3, 4, 5, 6, 7); \ + RSTT(1, a, 1, 2, 3, 4, 5, 6, 7, 0); \ + RSTT(2, a, 2, 3, 4, 5, 6, 7, 0, 1); \ + RSTT(3, a, 3, 4, 5, 6, 7, 0, 1, 2); \ + RSTT(4, a, 4, 5, 6, 7, 0, 1, 2, 3); \ + RSTT(5, a, 5, 6, 7, 0, 1, 2, 3, 4); \ + RSTT(6, a, 6, 7, 0, 1, 2, 3, 4, 5); \ + RSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#define ROUND_SMALL_Q(a, r) do { \ + sph_u64 t[8]; \ + a[0] ^= QC64(0x00, r); \ + a[1] ^= QC64(0x10, r); \ + a[2] ^= QC64(0x20, r); \ + a[3] ^= QC64(0x30, r); \ + a[4] ^= QC64(0x40, r); \ + a[5] ^= QC64(0x50, r); \ + a[6] ^= QC64(0x60, r); \ + a[7] ^= QC64(0x70, r); \ + RSTT(0, a, 1, 3, 5, 7, 0, 2, 4, 6); \ + RSTT(1, a, 2, 4, 6, 0, 1, 3, 5, 7); \ + RSTT(2, a, 3, 5, 7, 1, 2, 4, 6, 0); \ + RSTT(3, a, 4, 6, 0, 2, 3, 5, 7, 1); \ + RSTT(4, a, 5, 7, 1, 3, 4, 6, 0, 2); \ + RSTT(5, a, 6, 0, 2, 4, 5, 7, 1, 3); \ + RSTT(6, a, 7, 1, 3, 5, 6, 0, 2, 4); \ + RSTT(7, a, 0, 2, 4, 6, 7, 1, 3, 5); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_P(a, r); \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_Q(a, r); \ + } while (0) + +#else + +/* + * Apparently, unrolling more than that confuses GCC, resulting in + * lower performance, even though L1 cache would be no problem. + */ +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_P(a, r + 0); \ + ROUND_SMALL_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_Q(a, r + 0); \ + ROUND_SMALL_Q(a, r + 1); \ + } \ + } while (0) + +#endif + +#define COMPRESS_SMALL do { \ + sph_u64 g[8], m[8]; \ + size_t u; \ + for (u = 0; u < 8; u ++) { \ + m[u] = dec64e_aligned(buf + (u << 3)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_SMALL_P(g); \ + PERM_SMALL_Q(m); \ + for (u = 0; u < 8; u ++) \ + H[u] ^= g[u] ^ m[u]; \ + } while (0) + +#define FINAL_SMALL do { \ + sph_u64 x[8]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_SMALL_P(x); \ + for (u = 0; u < 8; u ++) \ + H[u] ^= x[u]; \ + } while (0) + +#define DECL_STATE_BIG \ + sph_u64 H[16]; + +#define READ_STATE_BIG(sc) do { \ + memcpy(H, (sc)->state.wide, sizeof H); \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + memcpy((sc)->state.wide, H, sizeof H); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define RBTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ R64(T0[B64_1(a[b1])], 8) \ + ^ R64(T0[B64_2(a[b2])], 16) \ + ^ R64(T0[B64_3(a[b3])], 24) \ + ^ T4[B64_4(a[b4])] \ + ^ R64(T4[B64_5(a[b5])], 8) \ + ^ R64(T4[B64_6(a[b6])], 16) \ + ^ R64(T4[B64_7(a[b7])], 24); \ + } while (0) + +#else + +#define RBTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0[B64_0(a[b0])] \ + ^ T1[B64_1(a[b1])] \ + ^ T2[B64_2(a[b2])] \ + ^ T3[B64_3(a[b3])] \ + ^ T4[B64_4(a[b4])] \ + ^ T5[B64_5(a[b5])] \ + ^ T6[B64_6(a[b6])] \ + ^ T7[B64_7(a[b7])]; \ + } while (0) + +#endif + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define ROUND_BIG_P(a, r) do { \ + sph_u64 t[16]; \ + size_t u; \ + a[0x0] ^= PC64(0x00, r); \ + a[0x1] ^= PC64(0x10, r); \ + a[0x2] ^= PC64(0x20, r); \ + a[0x3] ^= PC64(0x30, r); \ + a[0x4] ^= PC64(0x40, r); \ + a[0x5] ^= PC64(0x50, r); \ + a[0x6] ^= PC64(0x60, r); \ + a[0x7] ^= PC64(0x70, r); \ + a[0x8] ^= PC64(0x80, r); \ + a[0x9] ^= PC64(0x90, r); \ + a[0xA] ^= PC64(0xA0, r); \ + a[0xB] ^= PC64(0xB0, r); \ + a[0xC] ^= PC64(0xC0, r); \ + a[0xD] ^= PC64(0xD0, r); \ + a[0xE] ^= PC64(0xE0, r); \ + a[0xF] ^= PC64(0xF0, r); \ + for (u = 0; u < 16; u += 4) { \ + RBTT(u + 0, a, u + 0, (u + 1) & 0xF, \ + (u + 2) & 0xF, (u + 3) & 0xF, (u + 4) & 0xF, \ + (u + 5) & 0xF, (u + 6) & 0xF, (u + 11) & 0xF); \ + RBTT(u + 1, a, u + 1, (u + 2) & 0xF, \ + (u + 3) & 0xF, (u + 4) & 0xF, (u + 5) & 0xF, \ + (u + 6) & 0xF, (u + 7) & 0xF, (u + 12) & 0xF); \ + RBTT(u + 2, a, u + 2, (u + 3) & 0xF, \ + (u + 4) & 0xF, (u + 5) & 0xF, (u + 6) & 0xF, \ + (u + 7) & 0xF, (u + 8) & 0xF, (u + 13) & 0xF); \ + RBTT(u + 3, a, u + 3, (u + 4) & 0xF, \ + (u + 5) & 0xF, (u + 6) & 0xF, (u + 7) & 0xF, \ + (u + 8) & 0xF, (u + 9) & 0xF, (u + 14) & 0xF); \ + } \ + memcpy(a, t, sizeof t); \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + sph_u64 t[16]; \ + size_t u; \ + a[0x0] ^= QC64(0x00, r); \ + a[0x1] ^= QC64(0x10, r); \ + a[0x2] ^= QC64(0x20, r); \ + a[0x3] ^= QC64(0x30, r); \ + a[0x4] ^= QC64(0x40, r); \ + a[0x5] ^= QC64(0x50, r); \ + a[0x6] ^= QC64(0x60, r); \ + a[0x7] ^= QC64(0x70, r); \ + a[0x8] ^= QC64(0x80, r); \ + a[0x9] ^= QC64(0x90, r); \ + a[0xA] ^= QC64(0xA0, r); \ + a[0xB] ^= QC64(0xB0, r); \ + a[0xC] ^= QC64(0xC0, r); \ + a[0xD] ^= QC64(0xD0, r); \ + a[0xE] ^= QC64(0xE0, r); \ + a[0xF] ^= QC64(0xF0, r); \ + for (u = 0; u < 16; u += 4) { \ + RBTT(u + 0, a, (u + 1) & 0xF, (u + 3) & 0xF, \ + (u + 5) & 0xF, (u + 11) & 0xF, (u + 0) & 0xF, \ + (u + 2) & 0xF, (u + 4) & 0xF, (u + 6) & 0xF); \ + RBTT(u + 1, a, (u + 2) & 0xF, (u + 4) & 0xF, \ + (u + 6) & 0xF, (u + 12) & 0xF, (u + 1) & 0xF, \ + (u + 3) & 0xF, (u + 5) & 0xF, (u + 7) & 0xF); \ + RBTT(u + 2, a, (u + 3) & 0xF, (u + 5) & 0xF, \ + (u + 7) & 0xF, (u + 13) & 0xF, (u + 2) & 0xF, \ + (u + 4) & 0xF, (u + 6) & 0xF, (u + 8) & 0xF); \ + RBTT(u + 3, a, (u + 4) & 0xF, (u + 6) & 0xF, \ + (u + 8) & 0xF, (u + 14) & 0xF, (u + 3) & 0xF, \ + (u + 5) & 0xF, (u + 7) & 0xF, (u + 9) & 0xF); \ + } \ + memcpy(a, t, sizeof t); \ + } while (0) + +#else + +#define ROUND_BIG_P(a, r) do { \ + sph_u64 t[16]; \ + a[0x0] ^= PC64(0x00, r); \ + a[0x1] ^= PC64(0x10, r); \ + a[0x2] ^= PC64(0x20, r); \ + a[0x3] ^= PC64(0x30, r); \ + a[0x4] ^= PC64(0x40, r); \ + a[0x5] ^= PC64(0x50, r); \ + a[0x6] ^= PC64(0x60, r); \ + a[0x7] ^= PC64(0x70, r); \ + a[0x8] ^= PC64(0x80, r); \ + a[0x9] ^= PC64(0x90, r); \ + a[0xA] ^= PC64(0xA0, r); \ + a[0xB] ^= PC64(0xB0, r); \ + a[0xC] ^= PC64(0xC0, r); \ + a[0xD] ^= PC64(0xD0, r); \ + a[0xE] ^= PC64(0xE0, r); \ + a[0xF] ^= PC64(0xF0, r); \ + RBTT(0x0, a, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xB); \ + RBTT(0x1, a, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xC); \ + RBTT(0x2, a, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xD); \ + RBTT(0x3, a, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xE); \ + RBTT(0x4, a, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xF); \ + RBTT(0x5, a, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0x0); \ + RBTT(0x6, a, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x1); \ + RBTT(0x7, a, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0x2); \ + RBTT(0x8, a, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0x3); \ + RBTT(0x9, a, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x4); \ + RBTT(0xA, a, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x5); \ + RBTT(0xB, a, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x6); \ + RBTT(0xC, a, 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x7); \ + RBTT(0xD, a, 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x8); \ + RBTT(0xE, a, 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9); \ + RBTT(0xF, a, 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xA); \ + a[0x0] = t[0x0]; \ + a[0x1] = t[0x1]; \ + a[0x2] = t[0x2]; \ + a[0x3] = t[0x3]; \ + a[0x4] = t[0x4]; \ + a[0x5] = t[0x5]; \ + a[0x6] = t[0x6]; \ + a[0x7] = t[0x7]; \ + a[0x8] = t[0x8]; \ + a[0x9] = t[0x9]; \ + a[0xA] = t[0xA]; \ + a[0xB] = t[0xB]; \ + a[0xC] = t[0xC]; \ + a[0xD] = t[0xD]; \ + a[0xE] = t[0xE]; \ + a[0xF] = t[0xF]; \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + sph_u64 t[16]; \ + a[0x0] ^= QC64(0x00, r); \ + a[0x1] ^= QC64(0x10, r); \ + a[0x2] ^= QC64(0x20, r); \ + a[0x3] ^= QC64(0x30, r); \ + a[0x4] ^= QC64(0x40, r); \ + a[0x5] ^= QC64(0x50, r); \ + a[0x6] ^= QC64(0x60, r); \ + a[0x7] ^= QC64(0x70, r); \ + a[0x8] ^= QC64(0x80, r); \ + a[0x9] ^= QC64(0x90, r); \ + a[0xA] ^= QC64(0xA0, r); \ + a[0xB] ^= QC64(0xB0, r); \ + a[0xC] ^= QC64(0xC0, r); \ + a[0xD] ^= QC64(0xD0, r); \ + a[0xE] ^= QC64(0xE0, r); \ + a[0xF] ^= QC64(0xF0, r); \ + RBTT(0x0, a, 0x1, 0x3, 0x5, 0xB, 0x0, 0x2, 0x4, 0x6); \ + RBTT(0x1, a, 0x2, 0x4, 0x6, 0xC, 0x1, 0x3, 0x5, 0x7); \ + RBTT(0x2, a, 0x3, 0x5, 0x7, 0xD, 0x2, 0x4, 0x6, 0x8); \ + RBTT(0x3, a, 0x4, 0x6, 0x8, 0xE, 0x3, 0x5, 0x7, 0x9); \ + RBTT(0x4, a, 0x5, 0x7, 0x9, 0xF, 0x4, 0x6, 0x8, 0xA); \ + RBTT(0x5, a, 0x6, 0x8, 0xA, 0x0, 0x5, 0x7, 0x9, 0xB); \ + RBTT(0x6, a, 0x7, 0x9, 0xB, 0x1, 0x6, 0x8, 0xA, 0xC); \ + RBTT(0x7, a, 0x8, 0xA, 0xC, 0x2, 0x7, 0x9, 0xB, 0xD); \ + RBTT(0x8, a, 0x9, 0xB, 0xD, 0x3, 0x8, 0xA, 0xC, 0xE); \ + RBTT(0x9, a, 0xA, 0xC, 0xE, 0x4, 0x9, 0xB, 0xD, 0xF); \ + RBTT(0xA, a, 0xB, 0xD, 0xF, 0x5, 0xA, 0xC, 0xE, 0x0); \ + RBTT(0xB, a, 0xC, 0xE, 0x0, 0x6, 0xB, 0xD, 0xF, 0x1); \ + RBTT(0xC, a, 0xD, 0xF, 0x1, 0x7, 0xC, 0xE, 0x0, 0x2); \ + RBTT(0xD, a, 0xE, 0x0, 0x2, 0x8, 0xD, 0xF, 0x1, 0x3); \ + RBTT(0xE, a, 0xF, 0x1, 0x3, 0x9, 0xE, 0x0, 0x2, 0x4); \ + RBTT(0xF, a, 0x0, 0x2, 0x4, 0xA, 0xF, 0x1, 0x3, 0x5); \ + a[0x0] = t[0x0]; \ + a[0x1] = t[0x1]; \ + a[0x2] = t[0x2]; \ + a[0x3] = t[0x3]; \ + a[0x4] = t[0x4]; \ + a[0x5] = t[0x5]; \ + a[0x6] = t[0x6]; \ + a[0x7] = t[0x7]; \ + a[0x8] = t[0x8]; \ + a[0x9] = t[0x9]; \ + a[0xA] = t[0xA]; \ + a[0xB] = t[0xB]; \ + a[0xC] = t[0xC]; \ + a[0xD] = t[0xD]; \ + a[0xE] = t[0xE]; \ + a[0xF] = t[0xF]; \ + } while (0) + +#endif + +#define PERM_BIG_P(a) do { \ + int r; \ + for (r = 0; r < 14; r += 2) { \ + ROUND_BIG_P(a, r + 0); \ + ROUND_BIG_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_BIG_Q(a) do { \ + int r; \ + for (r = 0; r < 14; r += 2) { \ + ROUND_BIG_Q(a, r + 0); \ + ROUND_BIG_Q(a, r + 1); \ + } \ + } while (0) + +/* obsolete +#if SPH_SMALL_FOOTPRINT_GROESTL +#define COMPRESS_BIG do { \ + sph_u64 g[16], m[16], *ya; \ + const sph_u64 *yc; \ + size_t u; \ + int i; \ + for (u = 0; u < 16; u ++) { \ + m[u] = dec64e_aligned(buf + (u << 3)); \ + g[u] = m[u] ^ H[u]; \ + } \ + ya = g; \ + yc = CP; \ + for (i = 0; i < 2; i ++) { \ + PERM_BIG(ya, yc); \ + ya = m; \ + yc = CQ; \ + } \ + for (u = 0; u < 16; u ++) { \ + H[u] ^= g[u] ^ m[u]; \ + } \ + } while (0) +#else +*/ + +#define COMPRESS_BIG do { \ + sph_u64 g[16], m[16]; \ + size_t u; \ + for (u = 0; u < 16; u ++) { \ + m[u] = dec64e_aligned(buf + (u << 3)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_BIG_P(g); \ + PERM_BIG_Q(m); \ + for (u = 0; u < 16; u ++) { \ + H[u] ^= g[u] ^ m[u]; \ + } \ + } while (0) + +/* obsolete +#endif +*/ + +#define FINAL_BIG do { \ + sph_u64 x[16]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_BIG_P(x); \ + for (u = 0; u < 16; u ++) \ + H[u] ^= x[u]; \ + } while (0) + +#else + +static const sph_u32 T0up[] = { + C32e(0xc632f4a5), C32e(0xf86f9784), C32e(0xee5eb099), C32e(0xf67a8c8d), + C32e(0xffe8170d), C32e(0xd60adcbd), C32e(0xde16c8b1), C32e(0x916dfc54), + C32e(0x6090f050), C32e(0x02070503), C32e(0xce2ee0a9), C32e(0x56d1877d), + C32e(0xe7cc2b19), C32e(0xb513a662), C32e(0x4d7c31e6), C32e(0xec59b59a), + C32e(0x8f40cf45), C32e(0x1fa3bc9d), C32e(0x8949c040), C32e(0xfa689287), + C32e(0xefd03f15), C32e(0xb29426eb), C32e(0x8ece40c9), C32e(0xfbe61d0b), + C32e(0x416e2fec), C32e(0xb31aa967), C32e(0x5f431cfd), C32e(0x456025ea), + C32e(0x23f9dabf), C32e(0x535102f7), C32e(0xe445a196), C32e(0x9b76ed5b), + C32e(0x75285dc2), C32e(0xe1c5241c), C32e(0x3dd4e9ae), C32e(0x4cf2be6a), + C32e(0x6c82ee5a), C32e(0x7ebdc341), C32e(0xf5f30602), C32e(0x8352d14f), + C32e(0x688ce45c), C32e(0x515607f4), C32e(0xd18d5c34), C32e(0xf9e11808), + C32e(0xe24cae93), C32e(0xab3e9573), C32e(0x6297f553), C32e(0x2a6b413f), + C32e(0x081c140c), C32e(0x9563f652), C32e(0x46e9af65), C32e(0x9d7fe25e), + C32e(0x30487828), C32e(0x37cff8a1), C32e(0x0a1b110f), C32e(0x2febc4b5), + C32e(0x0e151b09), C32e(0x247e5a36), C32e(0x1badb69b), C32e(0xdf98473d), + C32e(0xcda76a26), C32e(0x4ef5bb69), C32e(0x7f334ccd), C32e(0xea50ba9f), + C32e(0x123f2d1b), C32e(0x1da4b99e), C32e(0x58c49c74), C32e(0x3446722e), + C32e(0x3641772d), C32e(0xdc11cdb2), C32e(0xb49d29ee), C32e(0x5b4d16fb), + C32e(0xa4a501f6), C32e(0x76a1d74d), C32e(0xb714a361), C32e(0x7d3449ce), + C32e(0x52df8d7b), C32e(0xdd9f423e), C32e(0x5ecd9371), C32e(0x13b1a297), + C32e(0xa6a204f5), C32e(0xb901b868), C32e(0x00000000), C32e(0xc1b5742c), + C32e(0x40e0a060), C32e(0xe3c2211f), C32e(0x793a43c8), C32e(0xb69a2ced), + C32e(0xd40dd9be), C32e(0x8d47ca46), C32e(0x671770d9), C32e(0x72afdd4b), + C32e(0x94ed79de), C32e(0x98ff67d4), C32e(0xb09323e8), C32e(0x855bde4a), + C32e(0xbb06bd6b), C32e(0xc5bb7e2a), C32e(0x4f7b34e5), C32e(0xedd73a16), + C32e(0x86d254c5), C32e(0x9af862d7), C32e(0x6699ff55), C32e(0x11b6a794), + C32e(0x8ac04acf), C32e(0xe9d93010), C32e(0x040e0a06), C32e(0xfe669881), + C32e(0xa0ab0bf0), C32e(0x78b4cc44), C32e(0x25f0d5ba), C32e(0x4b753ee3), + C32e(0xa2ac0ef3), C32e(0x5d4419fe), C32e(0x80db5bc0), C32e(0x0580858a), + C32e(0x3fd3ecad), C32e(0x21fedfbc), C32e(0x70a8d848), C32e(0xf1fd0c04), + C32e(0x63197adf), C32e(0x772f58c1), C32e(0xaf309f75), C32e(0x42e7a563), + C32e(0x20705030), C32e(0xe5cb2e1a), C32e(0xfdef120e), C32e(0xbf08b76d), + C32e(0x8155d44c), C32e(0x18243c14), C32e(0x26795f35), C32e(0xc3b2712f), + C32e(0xbe8638e1), C32e(0x35c8fda2), C32e(0x88c74fcc), C32e(0x2e654b39), + C32e(0x936af957), C32e(0x55580df2), C32e(0xfc619d82), C32e(0x7ab3c947), + C32e(0xc827efac), C32e(0xba8832e7), C32e(0x324f7d2b), C32e(0xe642a495), + C32e(0xc03bfba0), C32e(0x19aab398), C32e(0x9ef668d1), C32e(0xa322817f), + C32e(0x44eeaa66), C32e(0x54d6827e), C32e(0x3bdde6ab), C32e(0x0b959e83), + C32e(0x8cc945ca), C32e(0xc7bc7b29), C32e(0x6b056ed3), C32e(0x286c443c), + C32e(0xa72c8b79), C32e(0xbc813de2), C32e(0x1631271d), C32e(0xad379a76), + C32e(0xdb964d3b), C32e(0x649efa56), C32e(0x74a6d24e), C32e(0x1436221e), + C32e(0x92e476db), C32e(0x0c121e0a), C32e(0x48fcb46c), C32e(0xb88f37e4), + C32e(0x9f78e75d), C32e(0xbd0fb26e), C32e(0x43692aef), C32e(0xc435f1a6), + C32e(0x39dae3a8), C32e(0x31c6f7a4), C32e(0xd38a5937), C32e(0xf274868b), + C32e(0xd5835632), C32e(0x8b4ec543), C32e(0x6e85eb59), C32e(0xda18c2b7), + C32e(0x018e8f8c), C32e(0xb11dac64), C32e(0x9cf16dd2), C32e(0x49723be0), + C32e(0xd81fc7b4), C32e(0xacb915fa), C32e(0xf3fa0907), C32e(0xcfa06f25), + C32e(0xca20eaaf), C32e(0xf47d898e), C32e(0x476720e9), C32e(0x10382818), + C32e(0x6f0b64d5), C32e(0xf0738388), C32e(0x4afbb16f), C32e(0x5cca9672), + C32e(0x38546c24), C32e(0x575f08f1), C32e(0x732152c7), C32e(0x9764f351), + C32e(0xcbae6523), C32e(0xa125847c), C32e(0xe857bf9c), C32e(0x3e5d6321), + C32e(0x96ea7cdd), C32e(0x611e7fdc), C32e(0x0d9c9186), C32e(0x0f9b9485), + C32e(0xe04bab90), C32e(0x7cbac642), C32e(0x712657c4), C32e(0xcc29e5aa), + C32e(0x90e373d8), C32e(0x06090f05), C32e(0xf7f40301), C32e(0x1c2a3612), + C32e(0xc23cfea3), C32e(0x6a8be15f), C32e(0xaebe10f9), C32e(0x69026bd0), + C32e(0x17bfa891), C32e(0x9971e858), C32e(0x3a536927), C32e(0x27f7d0b9), + C32e(0xd9914838), C32e(0xebde3513), C32e(0x2be5ceb3), C32e(0x22775533), + C32e(0xd204d6bb), C32e(0xa9399070), C32e(0x07878089), C32e(0x33c1f2a7), + C32e(0x2decc1b6), C32e(0x3c5a6622), C32e(0x15b8ad92), C32e(0xc9a96020), + C32e(0x875cdb49), C32e(0xaab01aff), C32e(0x50d88878), C32e(0xa52b8e7a), + C32e(0x03898a8f), C32e(0x594a13f8), C32e(0x09929b80), C32e(0x1a233917), + C32e(0x651075da), C32e(0xd7845331), C32e(0x84d551c6), C32e(0xd003d3b8), + C32e(0x82dc5ec3), C32e(0x29e2cbb0), C32e(0x5ac39977), C32e(0x1e2d3311), + C32e(0x7b3d46cb), C32e(0xa8b71ffc), C32e(0x6d0c61d6), C32e(0x2c624e3a) +}; + +static const sph_u32 T0dn[] = { + C32e(0xf497a5c6), C32e(0x97eb84f8), C32e(0xb0c799ee), C32e(0x8cf78df6), + C32e(0x17e50dff), C32e(0xdcb7bdd6), C32e(0xc8a7b1de), C32e(0xfc395491), + C32e(0xf0c05060), C32e(0x05040302), C32e(0xe087a9ce), C32e(0x87ac7d56), + C32e(0x2bd519e7), C32e(0xa67162b5), C32e(0x319ae64d), C32e(0xb5c39aec), + C32e(0xcf05458f), C32e(0xbc3e9d1f), C32e(0xc0094089), C32e(0x92ef87fa), + C32e(0x3fc515ef), C32e(0x267febb2), C32e(0x4007c98e), C32e(0x1ded0bfb), + C32e(0x2f82ec41), C32e(0xa97d67b3), C32e(0x1cbefd5f), C32e(0x258aea45), + C32e(0xda46bf23), C32e(0x02a6f753), C32e(0xa1d396e4), C32e(0xed2d5b9b), + C32e(0x5deac275), C32e(0x24d91ce1), C32e(0xe97aae3d), C32e(0xbe986a4c), + C32e(0xeed85a6c), C32e(0xc3fc417e), C32e(0x06f102f5), C32e(0xd11d4f83), + C32e(0xe4d05c68), C32e(0x07a2f451), C32e(0x5cb934d1), C32e(0x18e908f9), + C32e(0xaedf93e2), C32e(0x954d73ab), C32e(0xf5c45362), C32e(0x41543f2a), + C32e(0x14100c08), C32e(0xf6315295), C32e(0xaf8c6546), C32e(0xe2215e9d), + C32e(0x78602830), C32e(0xf86ea137), C32e(0x11140f0a), C32e(0xc45eb52f), + C32e(0x1b1c090e), C32e(0x5a483624), C32e(0xb6369b1b), C32e(0x47a53ddf), + C32e(0x6a8126cd), C32e(0xbb9c694e), C32e(0x4cfecd7f), C32e(0xbacf9fea), + C32e(0x2d241b12), C32e(0xb93a9e1d), C32e(0x9cb07458), C32e(0x72682e34), + C32e(0x776c2d36), C32e(0xcda3b2dc), C32e(0x2973eeb4), C32e(0x16b6fb5b), + C32e(0x0153f6a4), C32e(0xd7ec4d76), C32e(0xa37561b7), C32e(0x49face7d), + C32e(0x8da47b52), C32e(0x42a13edd), C32e(0x93bc715e), C32e(0xa2269713), + C32e(0x0457f5a6), C32e(0xb86968b9), C32e(0x00000000), C32e(0x74992cc1), + C32e(0xa0806040), C32e(0x21dd1fe3), C32e(0x43f2c879), C32e(0x2c77edb6), + C32e(0xd9b3bed4), C32e(0xca01468d), C32e(0x70ced967), C32e(0xdde44b72), + C32e(0x7933de94), C32e(0x672bd498), C32e(0x237be8b0), C32e(0xde114a85), + C32e(0xbd6d6bbb), C32e(0x7e912ac5), C32e(0x349ee54f), C32e(0x3ac116ed), + C32e(0x5417c586), C32e(0x622fd79a), C32e(0xffcc5566), C32e(0xa7229411), + C32e(0x4a0fcf8a), C32e(0x30c910e9), C32e(0x0a080604), C32e(0x98e781fe), + C32e(0x0b5bf0a0), C32e(0xccf04478), C32e(0xd54aba25), C32e(0x3e96e34b), + C32e(0x0e5ff3a2), C32e(0x19bafe5d), C32e(0x5b1bc080), C32e(0x850a8a05), + C32e(0xec7ead3f), C32e(0xdf42bc21), C32e(0xd8e04870), C32e(0x0cf904f1), + C32e(0x7ac6df63), C32e(0x58eec177), C32e(0x9f4575af), C32e(0xa5846342), + C32e(0x50403020), C32e(0x2ed11ae5), C32e(0x12e10efd), C32e(0xb7656dbf), + C32e(0xd4194c81), C32e(0x3c301418), C32e(0x5f4c3526), C32e(0x719d2fc3), + C32e(0x3867e1be), C32e(0xfd6aa235), C32e(0x4f0bcc88), C32e(0x4b5c392e), + C32e(0xf93d5793), C32e(0x0daaf255), C32e(0x9de382fc), C32e(0xc9f4477a), + C32e(0xef8bacc8), C32e(0x326fe7ba), C32e(0x7d642b32), C32e(0xa4d795e6), + C32e(0xfb9ba0c0), C32e(0xb3329819), C32e(0x6827d19e), C32e(0x815d7fa3), + C32e(0xaa886644), C32e(0x82a87e54), C32e(0xe676ab3b), C32e(0x9e16830b), + C32e(0x4503ca8c), C32e(0x7b9529c7), C32e(0x6ed6d36b), C32e(0x44503c28), + C32e(0x8b5579a7), C32e(0x3d63e2bc), C32e(0x272c1d16), C32e(0x9a4176ad), + C32e(0x4dad3bdb), C32e(0xfac85664), C32e(0xd2e84e74), C32e(0x22281e14), + C32e(0x763fdb92), C32e(0x1e180a0c), C32e(0xb4906c48), C32e(0x376be4b8), + C32e(0xe7255d9f), C32e(0xb2616ebd), C32e(0x2a86ef43), C32e(0xf193a6c4), + C32e(0xe372a839), C32e(0xf762a431), C32e(0x59bd37d3), C32e(0x86ff8bf2), + C32e(0x56b132d5), C32e(0xc50d438b), C32e(0xebdc596e), C32e(0xc2afb7da), + C32e(0x8f028c01), C32e(0xac7964b1), C32e(0x6d23d29c), C32e(0x3b92e049), + C32e(0xc7abb4d8), C32e(0x1543faac), C32e(0x09fd07f3), C32e(0x6f8525cf), + C32e(0xea8fafca), C32e(0x89f38ef4), C32e(0x208ee947), C32e(0x28201810), + C32e(0x64ded56f), C32e(0x83fb88f0), C32e(0xb1946f4a), C32e(0x96b8725c), + C32e(0x6c702438), C32e(0x08aef157), C32e(0x52e6c773), C32e(0xf3355197), + C32e(0x658d23cb), C32e(0x84597ca1), C32e(0xbfcb9ce8), C32e(0x637c213e), + C32e(0x7c37dd96), C32e(0x7fc2dc61), C32e(0x911a860d), C32e(0x941e850f), + C32e(0xabdb90e0), C32e(0xc6f8427c), C32e(0x57e2c471), C32e(0xe583aacc), + C32e(0x733bd890), C32e(0x0f0c0506), C32e(0x03f501f7), C32e(0x3638121c), + C32e(0xfe9fa3c2), C32e(0xe1d45f6a), C32e(0x1047f9ae), C32e(0x6bd2d069), + C32e(0xa82e9117), C32e(0xe8295899), C32e(0x6974273a), C32e(0xd04eb927), + C32e(0x48a938d9), C32e(0x35cd13eb), C32e(0xce56b32b), C32e(0x55443322), + C32e(0xd6bfbbd2), C32e(0x904970a9), C32e(0x800e8907), C32e(0xf266a733), + C32e(0xc15ab62d), C32e(0x6678223c), C32e(0xad2a9215), C32e(0x608920c9), + C32e(0xdb154987), C32e(0x1a4fffaa), C32e(0x88a07850), C32e(0x8e517aa5), + C32e(0x8a068f03), C32e(0x13b2f859), C32e(0x9b128009), C32e(0x3934171a), + C32e(0x75cada65), C32e(0x53b531d7), C32e(0x5113c684), C32e(0xd3bbb8d0), + C32e(0x5e1fc382), C32e(0xcb52b029), C32e(0x99b4775a), C32e(0x333c111e), + C32e(0x46f6cb7b), C32e(0x1f4bfca8), C32e(0x61dad66d), C32e(0x4e583a2c) +}; + +static const sph_u32 T1up[] = { + C32e(0xc6c632f4), C32e(0xf8f86f97), C32e(0xeeee5eb0), C32e(0xf6f67a8c), + C32e(0xffffe817), C32e(0xd6d60adc), C32e(0xdede16c8), C32e(0x91916dfc), + C32e(0x606090f0), C32e(0x02020705), C32e(0xcece2ee0), C32e(0x5656d187), + C32e(0xe7e7cc2b), C32e(0xb5b513a6), C32e(0x4d4d7c31), C32e(0xecec59b5), + C32e(0x8f8f40cf), C32e(0x1f1fa3bc), C32e(0x898949c0), C32e(0xfafa6892), + C32e(0xefefd03f), C32e(0xb2b29426), C32e(0x8e8ece40), C32e(0xfbfbe61d), + C32e(0x41416e2f), C32e(0xb3b31aa9), C32e(0x5f5f431c), C32e(0x45456025), + C32e(0x2323f9da), C32e(0x53535102), C32e(0xe4e445a1), C32e(0x9b9b76ed), + C32e(0x7575285d), C32e(0xe1e1c524), C32e(0x3d3dd4e9), C32e(0x4c4cf2be), + C32e(0x6c6c82ee), C32e(0x7e7ebdc3), C32e(0xf5f5f306), C32e(0x838352d1), + C32e(0x68688ce4), C32e(0x51515607), C32e(0xd1d18d5c), C32e(0xf9f9e118), + C32e(0xe2e24cae), C32e(0xabab3e95), C32e(0x626297f5), C32e(0x2a2a6b41), + C32e(0x08081c14), C32e(0x959563f6), C32e(0x4646e9af), C32e(0x9d9d7fe2), + C32e(0x30304878), C32e(0x3737cff8), C32e(0x0a0a1b11), C32e(0x2f2febc4), + C32e(0x0e0e151b), C32e(0x24247e5a), C32e(0x1b1badb6), C32e(0xdfdf9847), + C32e(0xcdcda76a), C32e(0x4e4ef5bb), C32e(0x7f7f334c), C32e(0xeaea50ba), + C32e(0x12123f2d), C32e(0x1d1da4b9), C32e(0x5858c49c), C32e(0x34344672), + C32e(0x36364177), C32e(0xdcdc11cd), C32e(0xb4b49d29), C32e(0x5b5b4d16), + C32e(0xa4a4a501), C32e(0x7676a1d7), C32e(0xb7b714a3), C32e(0x7d7d3449), + C32e(0x5252df8d), C32e(0xdddd9f42), C32e(0x5e5ecd93), C32e(0x1313b1a2), + C32e(0xa6a6a204), C32e(0xb9b901b8), C32e(0x00000000), C32e(0xc1c1b574), + C32e(0x4040e0a0), C32e(0xe3e3c221), C32e(0x79793a43), C32e(0xb6b69a2c), + C32e(0xd4d40dd9), C32e(0x8d8d47ca), C32e(0x67671770), C32e(0x7272afdd), + C32e(0x9494ed79), C32e(0x9898ff67), C32e(0xb0b09323), C32e(0x85855bde), + C32e(0xbbbb06bd), C32e(0xc5c5bb7e), C32e(0x4f4f7b34), C32e(0xededd73a), + C32e(0x8686d254), C32e(0x9a9af862), C32e(0x666699ff), C32e(0x1111b6a7), + C32e(0x8a8ac04a), C32e(0xe9e9d930), C32e(0x04040e0a), C32e(0xfefe6698), + C32e(0xa0a0ab0b), C32e(0x7878b4cc), C32e(0x2525f0d5), C32e(0x4b4b753e), + C32e(0xa2a2ac0e), C32e(0x5d5d4419), C32e(0x8080db5b), C32e(0x05058085), + C32e(0x3f3fd3ec), C32e(0x2121fedf), C32e(0x7070a8d8), C32e(0xf1f1fd0c), + C32e(0x6363197a), C32e(0x77772f58), C32e(0xafaf309f), C32e(0x4242e7a5), + C32e(0x20207050), C32e(0xe5e5cb2e), C32e(0xfdfdef12), C32e(0xbfbf08b7), + C32e(0x818155d4), C32e(0x1818243c), C32e(0x2626795f), C32e(0xc3c3b271), + C32e(0xbebe8638), C32e(0x3535c8fd), C32e(0x8888c74f), C32e(0x2e2e654b), + C32e(0x93936af9), C32e(0x5555580d), C32e(0xfcfc619d), C32e(0x7a7ab3c9), + C32e(0xc8c827ef), C32e(0xbaba8832), C32e(0x32324f7d), C32e(0xe6e642a4), + C32e(0xc0c03bfb), C32e(0x1919aab3), C32e(0x9e9ef668), C32e(0xa3a32281), + C32e(0x4444eeaa), C32e(0x5454d682), C32e(0x3b3bdde6), C32e(0x0b0b959e), + C32e(0x8c8cc945), C32e(0xc7c7bc7b), C32e(0x6b6b056e), C32e(0x28286c44), + C32e(0xa7a72c8b), C32e(0xbcbc813d), C32e(0x16163127), C32e(0xadad379a), + C32e(0xdbdb964d), C32e(0x64649efa), C32e(0x7474a6d2), C32e(0x14143622), + C32e(0x9292e476), C32e(0x0c0c121e), C32e(0x4848fcb4), C32e(0xb8b88f37), + C32e(0x9f9f78e7), C32e(0xbdbd0fb2), C32e(0x4343692a), C32e(0xc4c435f1), + C32e(0x3939dae3), C32e(0x3131c6f7), C32e(0xd3d38a59), C32e(0xf2f27486), + C32e(0xd5d58356), C32e(0x8b8b4ec5), C32e(0x6e6e85eb), C32e(0xdada18c2), + C32e(0x01018e8f), C32e(0xb1b11dac), C32e(0x9c9cf16d), C32e(0x4949723b), + C32e(0xd8d81fc7), C32e(0xacacb915), C32e(0xf3f3fa09), C32e(0xcfcfa06f), + C32e(0xcaca20ea), C32e(0xf4f47d89), C32e(0x47476720), C32e(0x10103828), + C32e(0x6f6f0b64), C32e(0xf0f07383), C32e(0x4a4afbb1), C32e(0x5c5cca96), + C32e(0x3838546c), C32e(0x57575f08), C32e(0x73732152), C32e(0x979764f3), + C32e(0xcbcbae65), C32e(0xa1a12584), C32e(0xe8e857bf), C32e(0x3e3e5d63), + C32e(0x9696ea7c), C32e(0x61611e7f), C32e(0x0d0d9c91), C32e(0x0f0f9b94), + C32e(0xe0e04bab), C32e(0x7c7cbac6), C32e(0x71712657), C32e(0xcccc29e5), + C32e(0x9090e373), C32e(0x0606090f), C32e(0xf7f7f403), C32e(0x1c1c2a36), + C32e(0xc2c23cfe), C32e(0x6a6a8be1), C32e(0xaeaebe10), C32e(0x6969026b), + C32e(0x1717bfa8), C32e(0x999971e8), C32e(0x3a3a5369), C32e(0x2727f7d0), + C32e(0xd9d99148), C32e(0xebebde35), C32e(0x2b2be5ce), C32e(0x22227755), + C32e(0xd2d204d6), C32e(0xa9a93990), C32e(0x07078780), C32e(0x3333c1f2), + C32e(0x2d2decc1), C32e(0x3c3c5a66), C32e(0x1515b8ad), C32e(0xc9c9a960), + C32e(0x87875cdb), C32e(0xaaaab01a), C32e(0x5050d888), C32e(0xa5a52b8e), + C32e(0x0303898a), C32e(0x59594a13), C32e(0x0909929b), C32e(0x1a1a2339), + C32e(0x65651075), C32e(0xd7d78453), C32e(0x8484d551), C32e(0xd0d003d3), + C32e(0x8282dc5e), C32e(0x2929e2cb), C32e(0x5a5ac399), C32e(0x1e1e2d33), + C32e(0x7b7b3d46), C32e(0xa8a8b71f), C32e(0x6d6d0c61), C32e(0x2c2c624e) +}; + +static const sph_u32 T1dn[] = { + C32e(0xa5f497a5), C32e(0x8497eb84), C32e(0x99b0c799), C32e(0x8d8cf78d), + C32e(0x0d17e50d), C32e(0xbddcb7bd), C32e(0xb1c8a7b1), C32e(0x54fc3954), + C32e(0x50f0c050), C32e(0x03050403), C32e(0xa9e087a9), C32e(0x7d87ac7d), + C32e(0x192bd519), C32e(0x62a67162), C32e(0xe6319ae6), C32e(0x9ab5c39a), + C32e(0x45cf0545), C32e(0x9dbc3e9d), C32e(0x40c00940), C32e(0x8792ef87), + C32e(0x153fc515), C32e(0xeb267feb), C32e(0xc94007c9), C32e(0x0b1ded0b), + C32e(0xec2f82ec), C32e(0x67a97d67), C32e(0xfd1cbefd), C32e(0xea258aea), + C32e(0xbfda46bf), C32e(0xf702a6f7), C32e(0x96a1d396), C32e(0x5bed2d5b), + C32e(0xc25deac2), C32e(0x1c24d91c), C32e(0xaee97aae), C32e(0x6abe986a), + C32e(0x5aeed85a), C32e(0x41c3fc41), C32e(0x0206f102), C32e(0x4fd11d4f), + C32e(0x5ce4d05c), C32e(0xf407a2f4), C32e(0x345cb934), C32e(0x0818e908), + C32e(0x93aedf93), C32e(0x73954d73), C32e(0x53f5c453), C32e(0x3f41543f), + C32e(0x0c14100c), C32e(0x52f63152), C32e(0x65af8c65), C32e(0x5ee2215e), + C32e(0x28786028), C32e(0xa1f86ea1), C32e(0x0f11140f), C32e(0xb5c45eb5), + C32e(0x091b1c09), C32e(0x365a4836), C32e(0x9bb6369b), C32e(0x3d47a53d), + C32e(0x266a8126), C32e(0x69bb9c69), C32e(0xcd4cfecd), C32e(0x9fbacf9f), + C32e(0x1b2d241b), C32e(0x9eb93a9e), C32e(0x749cb074), C32e(0x2e72682e), + C32e(0x2d776c2d), C32e(0xb2cda3b2), C32e(0xee2973ee), C32e(0xfb16b6fb), + C32e(0xf60153f6), C32e(0x4dd7ec4d), C32e(0x61a37561), C32e(0xce49face), + C32e(0x7b8da47b), C32e(0x3e42a13e), C32e(0x7193bc71), C32e(0x97a22697), + C32e(0xf50457f5), C32e(0x68b86968), C32e(0x00000000), C32e(0x2c74992c), + C32e(0x60a08060), C32e(0x1f21dd1f), C32e(0xc843f2c8), C32e(0xed2c77ed), + C32e(0xbed9b3be), C32e(0x46ca0146), C32e(0xd970ced9), C32e(0x4bdde44b), + C32e(0xde7933de), C32e(0xd4672bd4), C32e(0xe8237be8), C32e(0x4ade114a), + C32e(0x6bbd6d6b), C32e(0x2a7e912a), C32e(0xe5349ee5), C32e(0x163ac116), + C32e(0xc55417c5), C32e(0xd7622fd7), C32e(0x55ffcc55), C32e(0x94a72294), + C32e(0xcf4a0fcf), C32e(0x1030c910), C32e(0x060a0806), C32e(0x8198e781), + C32e(0xf00b5bf0), C32e(0x44ccf044), C32e(0xbad54aba), C32e(0xe33e96e3), + C32e(0xf30e5ff3), C32e(0xfe19bafe), C32e(0xc05b1bc0), C32e(0x8a850a8a), + C32e(0xadec7ead), C32e(0xbcdf42bc), C32e(0x48d8e048), C32e(0x040cf904), + C32e(0xdf7ac6df), C32e(0xc158eec1), C32e(0x759f4575), C32e(0x63a58463), + C32e(0x30504030), C32e(0x1a2ed11a), C32e(0x0e12e10e), C32e(0x6db7656d), + C32e(0x4cd4194c), C32e(0x143c3014), C32e(0x355f4c35), C32e(0x2f719d2f), + C32e(0xe13867e1), C32e(0xa2fd6aa2), C32e(0xcc4f0bcc), C32e(0x394b5c39), + C32e(0x57f93d57), C32e(0xf20daaf2), C32e(0x829de382), C32e(0x47c9f447), + C32e(0xacef8bac), C32e(0xe7326fe7), C32e(0x2b7d642b), C32e(0x95a4d795), + C32e(0xa0fb9ba0), C32e(0x98b33298), C32e(0xd16827d1), C32e(0x7f815d7f), + C32e(0x66aa8866), C32e(0x7e82a87e), C32e(0xabe676ab), C32e(0x839e1683), + C32e(0xca4503ca), C32e(0x297b9529), C32e(0xd36ed6d3), C32e(0x3c44503c), + C32e(0x798b5579), C32e(0xe23d63e2), C32e(0x1d272c1d), C32e(0x769a4176), + C32e(0x3b4dad3b), C32e(0x56fac856), C32e(0x4ed2e84e), C32e(0x1e22281e), + C32e(0xdb763fdb), C32e(0x0a1e180a), C32e(0x6cb4906c), C32e(0xe4376be4), + C32e(0x5de7255d), C32e(0x6eb2616e), C32e(0xef2a86ef), C32e(0xa6f193a6), + C32e(0xa8e372a8), C32e(0xa4f762a4), C32e(0x3759bd37), C32e(0x8b86ff8b), + C32e(0x3256b132), C32e(0x43c50d43), C32e(0x59ebdc59), C32e(0xb7c2afb7), + C32e(0x8c8f028c), C32e(0x64ac7964), C32e(0xd26d23d2), C32e(0xe03b92e0), + C32e(0xb4c7abb4), C32e(0xfa1543fa), C32e(0x0709fd07), C32e(0x256f8525), + C32e(0xafea8faf), C32e(0x8e89f38e), C32e(0xe9208ee9), C32e(0x18282018), + C32e(0xd564ded5), C32e(0x8883fb88), C32e(0x6fb1946f), C32e(0x7296b872), + C32e(0x246c7024), C32e(0xf108aef1), C32e(0xc752e6c7), C32e(0x51f33551), + C32e(0x23658d23), C32e(0x7c84597c), C32e(0x9cbfcb9c), C32e(0x21637c21), + C32e(0xdd7c37dd), C32e(0xdc7fc2dc), C32e(0x86911a86), C32e(0x85941e85), + C32e(0x90abdb90), C32e(0x42c6f842), C32e(0xc457e2c4), C32e(0xaae583aa), + C32e(0xd8733bd8), C32e(0x050f0c05), C32e(0x0103f501), C32e(0x12363812), + C32e(0xa3fe9fa3), C32e(0x5fe1d45f), C32e(0xf91047f9), C32e(0xd06bd2d0), + C32e(0x91a82e91), C32e(0x58e82958), C32e(0x27697427), C32e(0xb9d04eb9), + C32e(0x3848a938), C32e(0x1335cd13), C32e(0xb3ce56b3), C32e(0x33554433), + C32e(0xbbd6bfbb), C32e(0x70904970), C32e(0x89800e89), C32e(0xa7f266a7), + C32e(0xb6c15ab6), C32e(0x22667822), C32e(0x92ad2a92), C32e(0x20608920), + C32e(0x49db1549), C32e(0xff1a4fff), C32e(0x7888a078), C32e(0x7a8e517a), + C32e(0x8f8a068f), C32e(0xf813b2f8), C32e(0x809b1280), C32e(0x17393417), + C32e(0xda75cada), C32e(0x3153b531), C32e(0xc65113c6), C32e(0xb8d3bbb8), + C32e(0xc35e1fc3), C32e(0xb0cb52b0), C32e(0x7799b477), C32e(0x11333c11), + C32e(0xcb46f6cb), C32e(0xfc1f4bfc), C32e(0xd661dad6), C32e(0x3a4e583a) +}; + +static const sph_u32 T2up[] = { + C32e(0xa5c6c632), C32e(0x84f8f86f), C32e(0x99eeee5e), C32e(0x8df6f67a), + C32e(0x0dffffe8), C32e(0xbdd6d60a), C32e(0xb1dede16), C32e(0x5491916d), + C32e(0x50606090), C32e(0x03020207), C32e(0xa9cece2e), C32e(0x7d5656d1), + C32e(0x19e7e7cc), C32e(0x62b5b513), C32e(0xe64d4d7c), C32e(0x9aecec59), + C32e(0x458f8f40), C32e(0x9d1f1fa3), C32e(0x40898949), C32e(0x87fafa68), + C32e(0x15efefd0), C32e(0xebb2b294), C32e(0xc98e8ece), C32e(0x0bfbfbe6), + C32e(0xec41416e), C32e(0x67b3b31a), C32e(0xfd5f5f43), C32e(0xea454560), + C32e(0xbf2323f9), C32e(0xf7535351), C32e(0x96e4e445), C32e(0x5b9b9b76), + C32e(0xc2757528), C32e(0x1ce1e1c5), C32e(0xae3d3dd4), C32e(0x6a4c4cf2), + C32e(0x5a6c6c82), C32e(0x417e7ebd), C32e(0x02f5f5f3), C32e(0x4f838352), + C32e(0x5c68688c), C32e(0xf4515156), C32e(0x34d1d18d), C32e(0x08f9f9e1), + C32e(0x93e2e24c), C32e(0x73abab3e), C32e(0x53626297), C32e(0x3f2a2a6b), + C32e(0x0c08081c), C32e(0x52959563), C32e(0x654646e9), C32e(0x5e9d9d7f), + C32e(0x28303048), C32e(0xa13737cf), C32e(0x0f0a0a1b), C32e(0xb52f2feb), + C32e(0x090e0e15), C32e(0x3624247e), C32e(0x9b1b1bad), C32e(0x3ddfdf98), + C32e(0x26cdcda7), C32e(0x694e4ef5), C32e(0xcd7f7f33), C32e(0x9feaea50), + C32e(0x1b12123f), C32e(0x9e1d1da4), C32e(0x745858c4), C32e(0x2e343446), + C32e(0x2d363641), C32e(0xb2dcdc11), C32e(0xeeb4b49d), C32e(0xfb5b5b4d), + C32e(0xf6a4a4a5), C32e(0x4d7676a1), C32e(0x61b7b714), C32e(0xce7d7d34), + C32e(0x7b5252df), C32e(0x3edddd9f), C32e(0x715e5ecd), C32e(0x971313b1), + C32e(0xf5a6a6a2), C32e(0x68b9b901), C32e(0x00000000), C32e(0x2cc1c1b5), + C32e(0x604040e0), C32e(0x1fe3e3c2), C32e(0xc879793a), C32e(0xedb6b69a), + C32e(0xbed4d40d), C32e(0x468d8d47), C32e(0xd9676717), C32e(0x4b7272af), + C32e(0xde9494ed), C32e(0xd49898ff), C32e(0xe8b0b093), C32e(0x4a85855b), + C32e(0x6bbbbb06), C32e(0x2ac5c5bb), C32e(0xe54f4f7b), C32e(0x16ededd7), + C32e(0xc58686d2), C32e(0xd79a9af8), C32e(0x55666699), C32e(0x941111b6), + C32e(0xcf8a8ac0), C32e(0x10e9e9d9), C32e(0x0604040e), C32e(0x81fefe66), + C32e(0xf0a0a0ab), C32e(0x447878b4), C32e(0xba2525f0), C32e(0xe34b4b75), + C32e(0xf3a2a2ac), C32e(0xfe5d5d44), C32e(0xc08080db), C32e(0x8a050580), + C32e(0xad3f3fd3), C32e(0xbc2121fe), C32e(0x487070a8), C32e(0x04f1f1fd), + C32e(0xdf636319), C32e(0xc177772f), C32e(0x75afaf30), C32e(0x634242e7), + C32e(0x30202070), C32e(0x1ae5e5cb), C32e(0x0efdfdef), C32e(0x6dbfbf08), + C32e(0x4c818155), C32e(0x14181824), C32e(0x35262679), C32e(0x2fc3c3b2), + C32e(0xe1bebe86), C32e(0xa23535c8), C32e(0xcc8888c7), C32e(0x392e2e65), + C32e(0x5793936a), C32e(0xf2555558), C32e(0x82fcfc61), C32e(0x477a7ab3), + C32e(0xacc8c827), C32e(0xe7baba88), C32e(0x2b32324f), C32e(0x95e6e642), + C32e(0xa0c0c03b), C32e(0x981919aa), C32e(0xd19e9ef6), C32e(0x7fa3a322), + C32e(0x664444ee), C32e(0x7e5454d6), C32e(0xab3b3bdd), C32e(0x830b0b95), + C32e(0xca8c8cc9), C32e(0x29c7c7bc), C32e(0xd36b6b05), C32e(0x3c28286c), + C32e(0x79a7a72c), C32e(0xe2bcbc81), C32e(0x1d161631), C32e(0x76adad37), + C32e(0x3bdbdb96), C32e(0x5664649e), C32e(0x4e7474a6), C32e(0x1e141436), + C32e(0xdb9292e4), C32e(0x0a0c0c12), C32e(0x6c4848fc), C32e(0xe4b8b88f), + C32e(0x5d9f9f78), C32e(0x6ebdbd0f), C32e(0xef434369), C32e(0xa6c4c435), + C32e(0xa83939da), C32e(0xa43131c6), C32e(0x37d3d38a), C32e(0x8bf2f274), + C32e(0x32d5d583), C32e(0x438b8b4e), C32e(0x596e6e85), C32e(0xb7dada18), + C32e(0x8c01018e), C32e(0x64b1b11d), C32e(0xd29c9cf1), C32e(0xe0494972), + C32e(0xb4d8d81f), C32e(0xfaacacb9), C32e(0x07f3f3fa), C32e(0x25cfcfa0), + C32e(0xafcaca20), C32e(0x8ef4f47d), C32e(0xe9474767), C32e(0x18101038), + C32e(0xd56f6f0b), C32e(0x88f0f073), C32e(0x6f4a4afb), C32e(0x725c5cca), + C32e(0x24383854), C32e(0xf157575f), C32e(0xc7737321), C32e(0x51979764), + C32e(0x23cbcbae), C32e(0x7ca1a125), C32e(0x9ce8e857), C32e(0x213e3e5d), + C32e(0xdd9696ea), C32e(0xdc61611e), C32e(0x860d0d9c), C32e(0x850f0f9b), + C32e(0x90e0e04b), C32e(0x427c7cba), C32e(0xc4717126), C32e(0xaacccc29), + C32e(0xd89090e3), C32e(0x05060609), C32e(0x01f7f7f4), C32e(0x121c1c2a), + C32e(0xa3c2c23c), C32e(0x5f6a6a8b), C32e(0xf9aeaebe), C32e(0xd0696902), + C32e(0x911717bf), C32e(0x58999971), C32e(0x273a3a53), C32e(0xb92727f7), + C32e(0x38d9d991), C32e(0x13ebebde), C32e(0xb32b2be5), C32e(0x33222277), + C32e(0xbbd2d204), C32e(0x70a9a939), C32e(0x89070787), C32e(0xa73333c1), + C32e(0xb62d2dec), C32e(0x223c3c5a), C32e(0x921515b8), C32e(0x20c9c9a9), + C32e(0x4987875c), C32e(0xffaaaab0), C32e(0x785050d8), C32e(0x7aa5a52b), + C32e(0x8f030389), C32e(0xf859594a), C32e(0x80090992), C32e(0x171a1a23), + C32e(0xda656510), C32e(0x31d7d784), C32e(0xc68484d5), C32e(0xb8d0d003), + C32e(0xc38282dc), C32e(0xb02929e2), C32e(0x775a5ac3), C32e(0x111e1e2d), + C32e(0xcb7b7b3d), C32e(0xfca8a8b7), C32e(0xd66d6d0c), C32e(0x3a2c2c62) +}; + +static const sph_u32 T2dn[] = { + C32e(0xf4a5f497), C32e(0x978497eb), C32e(0xb099b0c7), C32e(0x8c8d8cf7), + C32e(0x170d17e5), C32e(0xdcbddcb7), C32e(0xc8b1c8a7), C32e(0xfc54fc39), + C32e(0xf050f0c0), C32e(0x05030504), C32e(0xe0a9e087), C32e(0x877d87ac), + C32e(0x2b192bd5), C32e(0xa662a671), C32e(0x31e6319a), C32e(0xb59ab5c3), + C32e(0xcf45cf05), C32e(0xbc9dbc3e), C32e(0xc040c009), C32e(0x928792ef), + C32e(0x3f153fc5), C32e(0x26eb267f), C32e(0x40c94007), C32e(0x1d0b1ded), + C32e(0x2fec2f82), C32e(0xa967a97d), C32e(0x1cfd1cbe), C32e(0x25ea258a), + C32e(0xdabfda46), C32e(0x02f702a6), C32e(0xa196a1d3), C32e(0xed5bed2d), + C32e(0x5dc25dea), C32e(0x241c24d9), C32e(0xe9aee97a), C32e(0xbe6abe98), + C32e(0xee5aeed8), C32e(0xc341c3fc), C32e(0x060206f1), C32e(0xd14fd11d), + C32e(0xe45ce4d0), C32e(0x07f407a2), C32e(0x5c345cb9), C32e(0x180818e9), + C32e(0xae93aedf), C32e(0x9573954d), C32e(0xf553f5c4), C32e(0x413f4154), + C32e(0x140c1410), C32e(0xf652f631), C32e(0xaf65af8c), C32e(0xe25ee221), + C32e(0x78287860), C32e(0xf8a1f86e), C32e(0x110f1114), C32e(0xc4b5c45e), + C32e(0x1b091b1c), C32e(0x5a365a48), C32e(0xb69bb636), C32e(0x473d47a5), + C32e(0x6a266a81), C32e(0xbb69bb9c), C32e(0x4ccd4cfe), C32e(0xba9fbacf), + C32e(0x2d1b2d24), C32e(0xb99eb93a), C32e(0x9c749cb0), C32e(0x722e7268), + C32e(0x772d776c), C32e(0xcdb2cda3), C32e(0x29ee2973), C32e(0x16fb16b6), + C32e(0x01f60153), C32e(0xd74dd7ec), C32e(0xa361a375), C32e(0x49ce49fa), + C32e(0x8d7b8da4), C32e(0x423e42a1), C32e(0x937193bc), C32e(0xa297a226), + C32e(0x04f50457), C32e(0xb868b869), C32e(0x00000000), C32e(0x742c7499), + C32e(0xa060a080), C32e(0x211f21dd), C32e(0x43c843f2), C32e(0x2ced2c77), + C32e(0xd9bed9b3), C32e(0xca46ca01), C32e(0x70d970ce), C32e(0xdd4bdde4), + C32e(0x79de7933), C32e(0x67d4672b), C32e(0x23e8237b), C32e(0xde4ade11), + C32e(0xbd6bbd6d), C32e(0x7e2a7e91), C32e(0x34e5349e), C32e(0x3a163ac1), + C32e(0x54c55417), C32e(0x62d7622f), C32e(0xff55ffcc), C32e(0xa794a722), + C32e(0x4acf4a0f), C32e(0x301030c9), C32e(0x0a060a08), C32e(0x988198e7), + C32e(0x0bf00b5b), C32e(0xcc44ccf0), C32e(0xd5bad54a), C32e(0x3ee33e96), + C32e(0x0ef30e5f), C32e(0x19fe19ba), C32e(0x5bc05b1b), C32e(0x858a850a), + C32e(0xecadec7e), C32e(0xdfbcdf42), C32e(0xd848d8e0), C32e(0x0c040cf9), + C32e(0x7adf7ac6), C32e(0x58c158ee), C32e(0x9f759f45), C32e(0xa563a584), + C32e(0x50305040), C32e(0x2e1a2ed1), C32e(0x120e12e1), C32e(0xb76db765), + C32e(0xd44cd419), C32e(0x3c143c30), C32e(0x5f355f4c), C32e(0x712f719d), + C32e(0x38e13867), C32e(0xfda2fd6a), C32e(0x4fcc4f0b), C32e(0x4b394b5c), + C32e(0xf957f93d), C32e(0x0df20daa), C32e(0x9d829de3), C32e(0xc947c9f4), + C32e(0xefacef8b), C32e(0x32e7326f), C32e(0x7d2b7d64), C32e(0xa495a4d7), + C32e(0xfba0fb9b), C32e(0xb398b332), C32e(0x68d16827), C32e(0x817f815d), + C32e(0xaa66aa88), C32e(0x827e82a8), C32e(0xe6abe676), C32e(0x9e839e16), + C32e(0x45ca4503), C32e(0x7b297b95), C32e(0x6ed36ed6), C32e(0x443c4450), + C32e(0x8b798b55), C32e(0x3de23d63), C32e(0x271d272c), C32e(0x9a769a41), + C32e(0x4d3b4dad), C32e(0xfa56fac8), C32e(0xd24ed2e8), C32e(0x221e2228), + C32e(0x76db763f), C32e(0x1e0a1e18), C32e(0xb46cb490), C32e(0x37e4376b), + C32e(0xe75de725), C32e(0xb26eb261), C32e(0x2aef2a86), C32e(0xf1a6f193), + C32e(0xe3a8e372), C32e(0xf7a4f762), C32e(0x593759bd), C32e(0x868b86ff), + C32e(0x563256b1), C32e(0xc543c50d), C32e(0xeb59ebdc), C32e(0xc2b7c2af), + C32e(0x8f8c8f02), C32e(0xac64ac79), C32e(0x6dd26d23), C32e(0x3be03b92), + C32e(0xc7b4c7ab), C32e(0x15fa1543), C32e(0x090709fd), C32e(0x6f256f85), + C32e(0xeaafea8f), C32e(0x898e89f3), C32e(0x20e9208e), C32e(0x28182820), + C32e(0x64d564de), C32e(0x838883fb), C32e(0xb16fb194), C32e(0x967296b8), + C32e(0x6c246c70), C32e(0x08f108ae), C32e(0x52c752e6), C32e(0xf351f335), + C32e(0x6523658d), C32e(0x847c8459), C32e(0xbf9cbfcb), C32e(0x6321637c), + C32e(0x7cdd7c37), C32e(0x7fdc7fc2), C32e(0x9186911a), C32e(0x9485941e), + C32e(0xab90abdb), C32e(0xc642c6f8), C32e(0x57c457e2), C32e(0xe5aae583), + C32e(0x73d8733b), C32e(0x0f050f0c), C32e(0x030103f5), C32e(0x36123638), + C32e(0xfea3fe9f), C32e(0xe15fe1d4), C32e(0x10f91047), C32e(0x6bd06bd2), + C32e(0xa891a82e), C32e(0xe858e829), C32e(0x69276974), C32e(0xd0b9d04e), + C32e(0x483848a9), C32e(0x351335cd), C32e(0xceb3ce56), C32e(0x55335544), + C32e(0xd6bbd6bf), C32e(0x90709049), C32e(0x8089800e), C32e(0xf2a7f266), + C32e(0xc1b6c15a), C32e(0x66226678), C32e(0xad92ad2a), C32e(0x60206089), + C32e(0xdb49db15), C32e(0x1aff1a4f), C32e(0x887888a0), C32e(0x8e7a8e51), + C32e(0x8a8f8a06), C32e(0x13f813b2), C32e(0x9b809b12), C32e(0x39173934), + C32e(0x75da75ca), C32e(0x533153b5), C32e(0x51c65113), C32e(0xd3b8d3bb), + C32e(0x5ec35e1f), C32e(0xcbb0cb52), C32e(0x997799b4), C32e(0x3311333c), + C32e(0x46cb46f6), C32e(0x1ffc1f4b), C32e(0x61d661da), C32e(0x4e3a4e58) +}; + +static const sph_u32 T3up[] = { + C32e(0x97a5c6c6), C32e(0xeb84f8f8), C32e(0xc799eeee), C32e(0xf78df6f6), + C32e(0xe50dffff), C32e(0xb7bdd6d6), C32e(0xa7b1dede), C32e(0x39549191), + C32e(0xc0506060), C32e(0x04030202), C32e(0x87a9cece), C32e(0xac7d5656), + C32e(0xd519e7e7), C32e(0x7162b5b5), C32e(0x9ae64d4d), C32e(0xc39aecec), + C32e(0x05458f8f), C32e(0x3e9d1f1f), C32e(0x09408989), C32e(0xef87fafa), + C32e(0xc515efef), C32e(0x7febb2b2), C32e(0x07c98e8e), C32e(0xed0bfbfb), + C32e(0x82ec4141), C32e(0x7d67b3b3), C32e(0xbefd5f5f), C32e(0x8aea4545), + C32e(0x46bf2323), C32e(0xa6f75353), C32e(0xd396e4e4), C32e(0x2d5b9b9b), + C32e(0xeac27575), C32e(0xd91ce1e1), C32e(0x7aae3d3d), C32e(0x986a4c4c), + C32e(0xd85a6c6c), C32e(0xfc417e7e), C32e(0xf102f5f5), C32e(0x1d4f8383), + C32e(0xd05c6868), C32e(0xa2f45151), C32e(0xb934d1d1), C32e(0xe908f9f9), + C32e(0xdf93e2e2), C32e(0x4d73abab), C32e(0xc4536262), C32e(0x543f2a2a), + C32e(0x100c0808), C32e(0x31529595), C32e(0x8c654646), C32e(0x215e9d9d), + C32e(0x60283030), C32e(0x6ea13737), C32e(0x140f0a0a), C32e(0x5eb52f2f), + C32e(0x1c090e0e), C32e(0x48362424), C32e(0x369b1b1b), C32e(0xa53ddfdf), + C32e(0x8126cdcd), C32e(0x9c694e4e), C32e(0xfecd7f7f), C32e(0xcf9feaea), + C32e(0x241b1212), C32e(0x3a9e1d1d), C32e(0xb0745858), C32e(0x682e3434), + C32e(0x6c2d3636), C32e(0xa3b2dcdc), C32e(0x73eeb4b4), C32e(0xb6fb5b5b), + C32e(0x53f6a4a4), C32e(0xec4d7676), C32e(0x7561b7b7), C32e(0xface7d7d), + C32e(0xa47b5252), C32e(0xa13edddd), C32e(0xbc715e5e), C32e(0x26971313), + C32e(0x57f5a6a6), C32e(0x6968b9b9), C32e(0x00000000), C32e(0x992cc1c1), + C32e(0x80604040), C32e(0xdd1fe3e3), C32e(0xf2c87979), C32e(0x77edb6b6), + C32e(0xb3bed4d4), C32e(0x01468d8d), C32e(0xced96767), C32e(0xe44b7272), + C32e(0x33de9494), C32e(0x2bd49898), C32e(0x7be8b0b0), C32e(0x114a8585), + C32e(0x6d6bbbbb), C32e(0x912ac5c5), C32e(0x9ee54f4f), C32e(0xc116eded), + C32e(0x17c58686), C32e(0x2fd79a9a), C32e(0xcc556666), C32e(0x22941111), + C32e(0x0fcf8a8a), C32e(0xc910e9e9), C32e(0x08060404), C32e(0xe781fefe), + C32e(0x5bf0a0a0), C32e(0xf0447878), C32e(0x4aba2525), C32e(0x96e34b4b), + C32e(0x5ff3a2a2), C32e(0xbafe5d5d), C32e(0x1bc08080), C32e(0x0a8a0505), + C32e(0x7ead3f3f), C32e(0x42bc2121), C32e(0xe0487070), C32e(0xf904f1f1), + C32e(0xc6df6363), C32e(0xeec17777), C32e(0x4575afaf), C32e(0x84634242), + C32e(0x40302020), C32e(0xd11ae5e5), C32e(0xe10efdfd), C32e(0x656dbfbf), + C32e(0x194c8181), C32e(0x30141818), C32e(0x4c352626), C32e(0x9d2fc3c3), + C32e(0x67e1bebe), C32e(0x6aa23535), C32e(0x0bcc8888), C32e(0x5c392e2e), + C32e(0x3d579393), C32e(0xaaf25555), C32e(0xe382fcfc), C32e(0xf4477a7a), + C32e(0x8bacc8c8), C32e(0x6fe7baba), C32e(0x642b3232), C32e(0xd795e6e6), + C32e(0x9ba0c0c0), C32e(0x32981919), C32e(0x27d19e9e), C32e(0x5d7fa3a3), + C32e(0x88664444), C32e(0xa87e5454), C32e(0x76ab3b3b), C32e(0x16830b0b), + C32e(0x03ca8c8c), C32e(0x9529c7c7), C32e(0xd6d36b6b), C32e(0x503c2828), + C32e(0x5579a7a7), C32e(0x63e2bcbc), C32e(0x2c1d1616), C32e(0x4176adad), + C32e(0xad3bdbdb), C32e(0xc8566464), C32e(0xe84e7474), C32e(0x281e1414), + C32e(0x3fdb9292), C32e(0x180a0c0c), C32e(0x906c4848), C32e(0x6be4b8b8), + C32e(0x255d9f9f), C32e(0x616ebdbd), C32e(0x86ef4343), C32e(0x93a6c4c4), + C32e(0x72a83939), C32e(0x62a43131), C32e(0xbd37d3d3), C32e(0xff8bf2f2), + C32e(0xb132d5d5), C32e(0x0d438b8b), C32e(0xdc596e6e), C32e(0xafb7dada), + C32e(0x028c0101), C32e(0x7964b1b1), C32e(0x23d29c9c), C32e(0x92e04949), + C32e(0xabb4d8d8), C32e(0x43faacac), C32e(0xfd07f3f3), C32e(0x8525cfcf), + C32e(0x8fafcaca), C32e(0xf38ef4f4), C32e(0x8ee94747), C32e(0x20181010), + C32e(0xded56f6f), C32e(0xfb88f0f0), C32e(0x946f4a4a), C32e(0xb8725c5c), + C32e(0x70243838), C32e(0xaef15757), C32e(0xe6c77373), C32e(0x35519797), + C32e(0x8d23cbcb), C32e(0x597ca1a1), C32e(0xcb9ce8e8), C32e(0x7c213e3e), + C32e(0x37dd9696), C32e(0xc2dc6161), C32e(0x1a860d0d), C32e(0x1e850f0f), + C32e(0xdb90e0e0), C32e(0xf8427c7c), C32e(0xe2c47171), C32e(0x83aacccc), + C32e(0x3bd89090), C32e(0x0c050606), C32e(0xf501f7f7), C32e(0x38121c1c), + C32e(0x9fa3c2c2), C32e(0xd45f6a6a), C32e(0x47f9aeae), C32e(0xd2d06969), + C32e(0x2e911717), C32e(0x29589999), C32e(0x74273a3a), C32e(0x4eb92727), + C32e(0xa938d9d9), C32e(0xcd13ebeb), C32e(0x56b32b2b), C32e(0x44332222), + C32e(0xbfbbd2d2), C32e(0x4970a9a9), C32e(0x0e890707), C32e(0x66a73333), + C32e(0x5ab62d2d), C32e(0x78223c3c), C32e(0x2a921515), C32e(0x8920c9c9), + C32e(0x15498787), C32e(0x4fffaaaa), C32e(0xa0785050), C32e(0x517aa5a5), + C32e(0x068f0303), C32e(0xb2f85959), C32e(0x12800909), C32e(0x34171a1a), + C32e(0xcada6565), C32e(0xb531d7d7), C32e(0x13c68484), C32e(0xbbb8d0d0), + C32e(0x1fc38282), C32e(0x52b02929), C32e(0xb4775a5a), C32e(0x3c111e1e), + C32e(0xf6cb7b7b), C32e(0x4bfca8a8), C32e(0xdad66d6d), C32e(0x583a2c2c) +}; + +static const sph_u32 T3dn[] = { + C32e(0x32f4a5f4), C32e(0x6f978497), C32e(0x5eb099b0), C32e(0x7a8c8d8c), + C32e(0xe8170d17), C32e(0x0adcbddc), C32e(0x16c8b1c8), C32e(0x6dfc54fc), + C32e(0x90f050f0), C32e(0x07050305), C32e(0x2ee0a9e0), C32e(0xd1877d87), + C32e(0xcc2b192b), C32e(0x13a662a6), C32e(0x7c31e631), C32e(0x59b59ab5), + C32e(0x40cf45cf), C32e(0xa3bc9dbc), C32e(0x49c040c0), C32e(0x68928792), + C32e(0xd03f153f), C32e(0x9426eb26), C32e(0xce40c940), C32e(0xe61d0b1d), + C32e(0x6e2fec2f), C32e(0x1aa967a9), C32e(0x431cfd1c), C32e(0x6025ea25), + C32e(0xf9dabfda), C32e(0x5102f702), C32e(0x45a196a1), C32e(0x76ed5bed), + C32e(0x285dc25d), C32e(0xc5241c24), C32e(0xd4e9aee9), C32e(0xf2be6abe), + C32e(0x82ee5aee), C32e(0xbdc341c3), C32e(0xf3060206), C32e(0x52d14fd1), + C32e(0x8ce45ce4), C32e(0x5607f407), C32e(0x8d5c345c), C32e(0xe1180818), + C32e(0x4cae93ae), C32e(0x3e957395), C32e(0x97f553f5), C32e(0x6b413f41), + C32e(0x1c140c14), C32e(0x63f652f6), C32e(0xe9af65af), C32e(0x7fe25ee2), + C32e(0x48782878), C32e(0xcff8a1f8), C32e(0x1b110f11), C32e(0xebc4b5c4), + C32e(0x151b091b), C32e(0x7e5a365a), C32e(0xadb69bb6), C32e(0x98473d47), + C32e(0xa76a266a), C32e(0xf5bb69bb), C32e(0x334ccd4c), C32e(0x50ba9fba), + C32e(0x3f2d1b2d), C32e(0xa4b99eb9), C32e(0xc49c749c), C32e(0x46722e72), + C32e(0x41772d77), C32e(0x11cdb2cd), C32e(0x9d29ee29), C32e(0x4d16fb16), + C32e(0xa501f601), C32e(0xa1d74dd7), C32e(0x14a361a3), C32e(0x3449ce49), + C32e(0xdf8d7b8d), C32e(0x9f423e42), C32e(0xcd937193), C32e(0xb1a297a2), + C32e(0xa204f504), C32e(0x01b868b8), C32e(0x00000000), C32e(0xb5742c74), + C32e(0xe0a060a0), C32e(0xc2211f21), C32e(0x3a43c843), C32e(0x9a2ced2c), + C32e(0x0dd9bed9), C32e(0x47ca46ca), C32e(0x1770d970), C32e(0xafdd4bdd), + C32e(0xed79de79), C32e(0xff67d467), C32e(0x9323e823), C32e(0x5bde4ade), + C32e(0x06bd6bbd), C32e(0xbb7e2a7e), C32e(0x7b34e534), C32e(0xd73a163a), + C32e(0xd254c554), C32e(0xf862d762), C32e(0x99ff55ff), C32e(0xb6a794a7), + C32e(0xc04acf4a), C32e(0xd9301030), C32e(0x0e0a060a), C32e(0x66988198), + C32e(0xab0bf00b), C32e(0xb4cc44cc), C32e(0xf0d5bad5), C32e(0x753ee33e), + C32e(0xac0ef30e), C32e(0x4419fe19), C32e(0xdb5bc05b), C32e(0x80858a85), + C32e(0xd3ecadec), C32e(0xfedfbcdf), C32e(0xa8d848d8), C32e(0xfd0c040c), + C32e(0x197adf7a), C32e(0x2f58c158), C32e(0x309f759f), C32e(0xe7a563a5), + C32e(0x70503050), C32e(0xcb2e1a2e), C32e(0xef120e12), C32e(0x08b76db7), + C32e(0x55d44cd4), C32e(0x243c143c), C32e(0x795f355f), C32e(0xb2712f71), + C32e(0x8638e138), C32e(0xc8fda2fd), C32e(0xc74fcc4f), C32e(0x654b394b), + C32e(0x6af957f9), C32e(0x580df20d), C32e(0x619d829d), C32e(0xb3c947c9), + C32e(0x27efacef), C32e(0x8832e732), C32e(0x4f7d2b7d), C32e(0x42a495a4), + C32e(0x3bfba0fb), C32e(0xaab398b3), C32e(0xf668d168), C32e(0x22817f81), + C32e(0xeeaa66aa), C32e(0xd6827e82), C32e(0xdde6abe6), C32e(0x959e839e), + C32e(0xc945ca45), C32e(0xbc7b297b), C32e(0x056ed36e), C32e(0x6c443c44), + C32e(0x2c8b798b), C32e(0x813de23d), C32e(0x31271d27), C32e(0x379a769a), + C32e(0x964d3b4d), C32e(0x9efa56fa), C32e(0xa6d24ed2), C32e(0x36221e22), + C32e(0xe476db76), C32e(0x121e0a1e), C32e(0xfcb46cb4), C32e(0x8f37e437), + C32e(0x78e75de7), C32e(0x0fb26eb2), C32e(0x692aef2a), C32e(0x35f1a6f1), + C32e(0xdae3a8e3), C32e(0xc6f7a4f7), C32e(0x8a593759), C32e(0x74868b86), + C32e(0x83563256), C32e(0x4ec543c5), C32e(0x85eb59eb), C32e(0x18c2b7c2), + C32e(0x8e8f8c8f), C32e(0x1dac64ac), C32e(0xf16dd26d), C32e(0x723be03b), + C32e(0x1fc7b4c7), C32e(0xb915fa15), C32e(0xfa090709), C32e(0xa06f256f), + C32e(0x20eaafea), C32e(0x7d898e89), C32e(0x6720e920), C32e(0x38281828), + C32e(0x0b64d564), C32e(0x73838883), C32e(0xfbb16fb1), C32e(0xca967296), + C32e(0x546c246c), C32e(0x5f08f108), C32e(0x2152c752), C32e(0x64f351f3), + C32e(0xae652365), C32e(0x25847c84), C32e(0x57bf9cbf), C32e(0x5d632163), + C32e(0xea7cdd7c), C32e(0x1e7fdc7f), C32e(0x9c918691), C32e(0x9b948594), + C32e(0x4bab90ab), C32e(0xbac642c6), C32e(0x2657c457), C32e(0x29e5aae5), + C32e(0xe373d873), C32e(0x090f050f), C32e(0xf4030103), C32e(0x2a361236), + C32e(0x3cfea3fe), C32e(0x8be15fe1), C32e(0xbe10f910), C32e(0x026bd06b), + C32e(0xbfa891a8), C32e(0x71e858e8), C32e(0x53692769), C32e(0xf7d0b9d0), + C32e(0x91483848), C32e(0xde351335), C32e(0xe5ceb3ce), C32e(0x77553355), + C32e(0x04d6bbd6), C32e(0x39907090), C32e(0x87808980), C32e(0xc1f2a7f2), + C32e(0xecc1b6c1), C32e(0x5a662266), C32e(0xb8ad92ad), C32e(0xa9602060), + C32e(0x5cdb49db), C32e(0xb01aff1a), C32e(0xd8887888), C32e(0x2b8e7a8e), + C32e(0x898a8f8a), C32e(0x4a13f813), C32e(0x929b809b), C32e(0x23391739), + C32e(0x1075da75), C32e(0x84533153), C32e(0xd551c651), C32e(0x03d3b8d3), + C32e(0xdc5ec35e), C32e(0xe2cbb0cb), C32e(0xc3997799), C32e(0x2d331133), + C32e(0x3d46cb46), C32e(0xb71ffc1f), C32e(0x0c61d661), C32e(0x624e3a4e) +}; + +#define DECL_STATE_SMALL \ + sph_u32 H[16]; + +#define READ_STATE_SMALL(sc) do { \ + memcpy(H, (sc)->state.narrow, sizeof H); \ + } while (0) + +#define WRITE_STATE_SMALL(sc) do { \ + memcpy((sc)->state.narrow, H, sizeof H); \ + } while (0) + +#define XCAT(x, y) XCAT_(x, y) +#define XCAT_(x, y) x ## y + +#define RSTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d0] = T0up[B32_0(a[b0])] \ + ^ T1up[B32_1(a[b1])] \ + ^ T2up[B32_2(a[b2])] \ + ^ T3up[B32_3(a[b3])] \ + ^ T0dn[B32_0(a[b4])] \ + ^ T1dn[B32_1(a[b5])] \ + ^ T2dn[B32_2(a[b6])] \ + ^ T3dn[B32_3(a[b7])]; \ + t[d1] = T0dn[B32_0(a[b0])] \ + ^ T1dn[B32_1(a[b1])] \ + ^ T2dn[B32_2(a[b2])] \ + ^ T3dn[B32_3(a[b3])] \ + ^ T0up[B32_0(a[b4])] \ + ^ T1up[B32_1(a[b5])] \ + ^ T2up[B32_2(a[b6])] \ + ^ T3up[B32_3(a[b7])]; \ + } while (0) + +#define ROUND_SMALL_P(a, r) do { \ + sph_u32 t[16]; \ + a[0x0] ^= PC32up(0x00, r); \ + a[0x1] ^= PC32dn(0x00, r); \ + a[0x2] ^= PC32up(0x10, r); \ + a[0x3] ^= PC32dn(0x10, r); \ + a[0x4] ^= PC32up(0x20, r); \ + a[0x5] ^= PC32dn(0x20, r); \ + a[0x6] ^= PC32up(0x30, r); \ + a[0x7] ^= PC32dn(0x30, r); \ + a[0x8] ^= PC32up(0x40, r); \ + a[0x9] ^= PC32dn(0x40, r); \ + a[0xA] ^= PC32up(0x50, r); \ + a[0xB] ^= PC32dn(0x50, r); \ + a[0xC] ^= PC32up(0x60, r); \ + a[0xD] ^= PC32dn(0x60, r); \ + a[0xE] ^= PC32up(0x70, r); \ + a[0xF] ^= PC32dn(0x70, r); \ + RSTT(0x0, 0x1, a, 0x0, 0x2, 0x4, 0x6, 0x9, 0xB, 0xD, 0xF); \ + RSTT(0x2, 0x3, a, 0x2, 0x4, 0x6, 0x8, 0xB, 0xD, 0xF, 0x1); \ + RSTT(0x4, 0x5, a, 0x4, 0x6, 0x8, 0xA, 0xD, 0xF, 0x1, 0x3); \ + RSTT(0x6, 0x7, a, 0x6, 0x8, 0xA, 0xC, 0xF, 0x1, 0x3, 0x5); \ + RSTT(0x8, 0x9, a, 0x8, 0xA, 0xC, 0xE, 0x1, 0x3, 0x5, 0x7); \ + RSTT(0xA, 0xB, a, 0xA, 0xC, 0xE, 0x0, 0x3, 0x5, 0x7, 0x9); \ + RSTT(0xC, 0xD, a, 0xC, 0xE, 0x0, 0x2, 0x5, 0x7, 0x9, 0xB); \ + RSTT(0xE, 0xF, a, 0xE, 0x0, 0x2, 0x4, 0x7, 0x9, 0xB, 0xD); \ + memcpy(a, t, sizeof t); \ + } while (0) + +#define ROUND_SMALL_Q(a, r) do { \ + sph_u32 t[16]; \ + a[0x0] ^= QC32up(0x00, r); \ + a[0x1] ^= QC32dn(0x00, r); \ + a[0x2] ^= QC32up(0x10, r); \ + a[0x3] ^= QC32dn(0x10, r); \ + a[0x4] ^= QC32up(0x20, r); \ + a[0x5] ^= QC32dn(0x20, r); \ + a[0x6] ^= QC32up(0x30, r); \ + a[0x7] ^= QC32dn(0x30, r); \ + a[0x8] ^= QC32up(0x40, r); \ + a[0x9] ^= QC32dn(0x40, r); \ + a[0xA] ^= QC32up(0x50, r); \ + a[0xB] ^= QC32dn(0x50, r); \ + a[0xC] ^= QC32up(0x60, r); \ + a[0xD] ^= QC32dn(0x60, r); \ + a[0xE] ^= QC32up(0x70, r); \ + a[0xF] ^= QC32dn(0x70, r); \ + RSTT(0x0, 0x1, a, 0x2, 0x6, 0xA, 0xE, 0x1, 0x5, 0x9, 0xD); \ + RSTT(0x2, 0x3, a, 0x4, 0x8, 0xC, 0x0, 0x3, 0x7, 0xB, 0xF); \ + RSTT(0x4, 0x5, a, 0x6, 0xA, 0xE, 0x2, 0x5, 0x9, 0xD, 0x1); \ + RSTT(0x6, 0x7, a, 0x8, 0xC, 0x0, 0x4, 0x7, 0xB, 0xF, 0x3); \ + RSTT(0x8, 0x9, a, 0xA, 0xE, 0x2, 0x6, 0x9, 0xD, 0x1, 0x5); \ + RSTT(0xA, 0xB, a, 0xC, 0x0, 0x4, 0x8, 0xB, 0xF, 0x3, 0x7); \ + RSTT(0xC, 0xD, a, 0xE, 0x2, 0x6, 0xA, 0xD, 0x1, 0x5, 0x9); \ + RSTT(0xE, 0xF, a, 0x0, 0x4, 0x8, 0xC, 0xF, 0x3, 0x7, 0xB); \ + memcpy(a, t, sizeof t); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_P(a, r); \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r ++) \ + ROUND_SMALL_Q(a, r); \ + } while (0) + +#else + +#define PERM_SMALL_P(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_P(a, r + 0); \ + ROUND_SMALL_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + int r; \ + for (r = 0; r < 10; r += 2) { \ + ROUND_SMALL_Q(a, r + 0); \ + ROUND_SMALL_Q(a, r + 1); \ + } \ + } while (0) + +#endif + +#define COMPRESS_SMALL do { \ + sph_u32 g[16], m[16]; \ + size_t u; \ + for (u = 0; u < 16; u ++) { \ + m[u] = dec32e_aligned(buf + (u << 2)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_SMALL_P(g); \ + PERM_SMALL_Q(m); \ + for (u = 0; u < 16; u ++) \ + H[u] ^= g[u] ^ m[u]; \ + } while (0) + +#define FINAL_SMALL do { \ + sph_u32 x[16]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_SMALL_P(x); \ + for (u = 0; u < 16; u ++) \ + H[u] ^= x[u]; \ + } while (0) + +#define DECL_STATE_BIG \ + sph_u32 H[32]; + +#define READ_STATE_BIG(sc) do { \ + memcpy(H, (sc)->state.narrow, sizeof H); \ + } while (0) + +#define WRITE_STATE_BIG(sc) do { \ + memcpy((sc)->state.narrow, H, sizeof H); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define RBTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + sph_u32 fu2 = T0up[B32_2(a[b2])]; \ + sph_u32 fd2 = T0dn[B32_2(a[b2])]; \ + sph_u32 fu3 = T1up[B32_3(a[b3])]; \ + sph_u32 fd3 = T1dn[B32_3(a[b3])]; \ + sph_u32 fu6 = T0up[B32_2(a[b6])]; \ + sph_u32 fd6 = T0dn[B32_2(a[b6])]; \ + sph_u32 fu7 = T1up[B32_3(a[b7])]; \ + sph_u32 fd7 = T1dn[B32_3(a[b7])]; \ + t[d0] = T0up[B32_0(a[b0])] \ + ^ T1up[B32_1(a[b1])] \ + ^ R32u(fu2, fd2) \ + ^ R32u(fu3, fd3) \ + ^ T0dn[B32_0(a[b4])] \ + ^ T1dn[B32_1(a[b5])] \ + ^ R32d(fu6, fd6) \ + ^ R32d(fu7, fd7); \ + t[d1] = T0dn[B32_0(a[b0])] \ + ^ T1dn[B32_1(a[b1])] \ + ^ R32d(fu2, fd2) \ + ^ R32d(fu3, fd3) \ + ^ T0up[B32_0(a[b4])] \ + ^ T1up[B32_1(a[b5])] \ + ^ R32u(fu6, fd6) \ + ^ R32u(fu7, fd7); \ + } while (0) + +#else + +#define RBTT(d0, d1, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d0] = T0up[B32_0(a[b0])] \ + ^ T1up[B32_1(a[b1])] \ + ^ T2up[B32_2(a[b2])] \ + ^ T3up[B32_3(a[b3])] \ + ^ T0dn[B32_0(a[b4])] \ + ^ T1dn[B32_1(a[b5])] \ + ^ T2dn[B32_2(a[b6])] \ + ^ T3dn[B32_3(a[b7])]; \ + t[d1] = T0dn[B32_0(a[b0])] \ + ^ T1dn[B32_1(a[b1])] \ + ^ T2dn[B32_2(a[b2])] \ + ^ T3dn[B32_3(a[b3])] \ + ^ T0up[B32_0(a[b4])] \ + ^ T1up[B32_1(a[b5])] \ + ^ T2up[B32_2(a[b6])] \ + ^ T3up[B32_3(a[b7])]; \ + } while (0) + +#endif + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define ROUND_BIG_P(a, r) do { \ + sph_u32 t[32]; \ + size_t u; \ + a[0x00] ^= PC32up(0x00, r); \ + a[0x01] ^= PC32dn(0x00, r); \ + a[0x02] ^= PC32up(0x10, r); \ + a[0x03] ^= PC32dn(0x10, r); \ + a[0x04] ^= PC32up(0x20, r); \ + a[0x05] ^= PC32dn(0x20, r); \ + a[0x06] ^= PC32up(0x30, r); \ + a[0x07] ^= PC32dn(0x30, r); \ + a[0x08] ^= PC32up(0x40, r); \ + a[0x09] ^= PC32dn(0x40, r); \ + a[0x0A] ^= PC32up(0x50, r); \ + a[0x0B] ^= PC32dn(0x50, r); \ + a[0x0C] ^= PC32up(0x60, r); \ + a[0x0D] ^= PC32dn(0x60, r); \ + a[0x0E] ^= PC32up(0x70, r); \ + a[0x0F] ^= PC32dn(0x70, r); \ + a[0x10] ^= PC32up(0x80, r); \ + a[0x11] ^= PC32dn(0x80, r); \ + a[0x12] ^= PC32up(0x90, r); \ + a[0x13] ^= PC32dn(0x90, r); \ + a[0x14] ^= PC32up(0xA0, r); \ + a[0x15] ^= PC32dn(0xA0, r); \ + a[0x16] ^= PC32up(0xB0, r); \ + a[0x17] ^= PC32dn(0xB0, r); \ + a[0x18] ^= PC32up(0xC0, r); \ + a[0x19] ^= PC32dn(0xC0, r); \ + a[0x1A] ^= PC32up(0xD0, r); \ + a[0x1B] ^= PC32dn(0xD0, r); \ + a[0x1C] ^= PC32up(0xE0, r); \ + a[0x1D] ^= PC32dn(0xE0, r); \ + a[0x1E] ^= PC32up(0xF0, r); \ + a[0x1F] ^= PC32dn(0xF0, r); \ + for (u = 0; u < 32; u += 8) { \ + RBTT(u + 0x00, (u + 0x01) & 0x1F, a, \ + u + 0x00, (u + 0x02) & 0x1F, \ + (u + 0x04) & 0x1F, (u + 0x06) & 0x1F, \ + (u + 0x09) & 0x1F, (u + 0x0B) & 0x1F, \ + (u + 0x0D) & 0x1F, (u + 0x17) & 0x1F); \ + RBTT(u + 0x02, (u + 0x03) & 0x1F, a, \ + u + 0x02, (u + 0x04) & 0x1F, \ + (u + 0x06) & 0x1F, (u + 0x08) & 0x1F, \ + (u + 0x0B) & 0x1F, (u + 0x0D) & 0x1F, \ + (u + 0x0F) & 0x1F, (u + 0x19) & 0x1F); \ + RBTT(u + 0x04, (u + 0x05) & 0x1F, a, \ + u + 0x04, (u + 0x06) & 0x1F, \ + (u + 0x08) & 0x1F, (u + 0x0A) & 0x1F, \ + (u + 0x0D) & 0x1F, (u + 0x0F) & 0x1F, \ + (u + 0x11) & 0x1F, (u + 0x1B) & 0x1F); \ + RBTT(u + 0x06, (u + 0x07) & 0x1F, a, \ + u + 0x06, (u + 0x08) & 0x1F, \ + (u + 0x0A) & 0x1F, (u + 0x0C) & 0x1F, \ + (u + 0x0F) & 0x1F, (u + 0x11) & 0x1F, \ + (u + 0x13) & 0x1F, (u + 0x1D) & 0x1F); \ + } \ + memcpy(a, t, sizeof t); \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + sph_u32 t[32]; \ + size_t u; \ + a[0x00] ^= QC32up(0x00, r); \ + a[0x01] ^= QC32dn(0x00, r); \ + a[0x02] ^= QC32up(0x10, r); \ + a[0x03] ^= QC32dn(0x10, r); \ + a[0x04] ^= QC32up(0x20, r); \ + a[0x05] ^= QC32dn(0x20, r); \ + a[0x06] ^= QC32up(0x30, r); \ + a[0x07] ^= QC32dn(0x30, r); \ + a[0x08] ^= QC32up(0x40, r); \ + a[0x09] ^= QC32dn(0x40, r); \ + a[0x0A] ^= QC32up(0x50, r); \ + a[0x0B] ^= QC32dn(0x50, r); \ + a[0x0C] ^= QC32up(0x60, r); \ + a[0x0D] ^= QC32dn(0x60, r); \ + a[0x0E] ^= QC32up(0x70, r); \ + a[0x0F] ^= QC32dn(0x70, r); \ + a[0x10] ^= QC32up(0x80, r); \ + a[0x11] ^= QC32dn(0x80, r); \ + a[0x12] ^= QC32up(0x90, r); \ + a[0x13] ^= QC32dn(0x90, r); \ + a[0x14] ^= QC32up(0xA0, r); \ + a[0x15] ^= QC32dn(0xA0, r); \ + a[0x16] ^= QC32up(0xB0, r); \ + a[0x17] ^= QC32dn(0xB0, r); \ + a[0x18] ^= QC32up(0xC0, r); \ + a[0x19] ^= QC32dn(0xC0, r); \ + a[0x1A] ^= QC32up(0xD0, r); \ + a[0x1B] ^= QC32dn(0xD0, r); \ + a[0x1C] ^= QC32up(0xE0, r); \ + a[0x1D] ^= QC32dn(0xE0, r); \ + a[0x1E] ^= QC32up(0xF0, r); \ + a[0x1F] ^= QC32dn(0xF0, r); \ + for (u = 0; u < 32; u += 8) { \ + RBTT(u + 0x00, (u + 0x01) & 0x1F, a, \ + (u + 0x02) & 0x1F, (u + 0x06) & 0x1F, \ + (u + 0x0A) & 0x1F, (u + 0x16) & 0x1F, \ + (u + 0x01) & 0x1F, (u + 0x05) & 0x1F, \ + (u + 0x09) & 0x1F, (u + 0x0D) & 0x1F); \ + RBTT(u + 0x02, (u + 0x03) & 0x1F, a, \ + (u + 0x04) & 0x1F, (u + 0x08) & 0x1F, \ + (u + 0x0C) & 0x1F, (u + 0x18) & 0x1F, \ + (u + 0x03) & 0x1F, (u + 0x07) & 0x1F, \ + (u + 0x0B) & 0x1F, (u + 0x0F) & 0x1F); \ + RBTT(u + 0x04, (u + 0x05) & 0x1F, a, \ + (u + 0x06) & 0x1F, (u + 0x0A) & 0x1F, \ + (u + 0x0E) & 0x1F, (u + 0x1A) & 0x1F, \ + (u + 0x05) & 0x1F, (u + 0x09) & 0x1F, \ + (u + 0x0D) & 0x1F, (u + 0x11) & 0x1F); \ + RBTT(u + 0x06, (u + 0x07) & 0x1F, a, \ + (u + 0x08) & 0x1F, (u + 0x0C) & 0x1F, \ + (u + 0x10) & 0x1F, (u + 0x1C) & 0x1F, \ + (u + 0x07) & 0x1F, (u + 0x0B) & 0x1F, \ + (u + 0x0F) & 0x1F, (u + 0x13) & 0x1F); \ + } \ + memcpy(a, t, sizeof t); \ + } while (0) + +#else + +#define ROUND_BIG_P(a, r) do { \ + sph_u32 t[32]; \ + a[0x00] ^= PC32up(0x00, r); \ + a[0x01] ^= PC32dn(0x00, r); \ + a[0x02] ^= PC32up(0x10, r); \ + a[0x03] ^= PC32dn(0x10, r); \ + a[0x04] ^= PC32up(0x20, r); \ + a[0x05] ^= PC32dn(0x20, r); \ + a[0x06] ^= PC32up(0x30, r); \ + a[0x07] ^= PC32dn(0x30, r); \ + a[0x08] ^= PC32up(0x40, r); \ + a[0x09] ^= PC32dn(0x40, r); \ + a[0x0A] ^= PC32up(0x50, r); \ + a[0x0B] ^= PC32dn(0x50, r); \ + a[0x0C] ^= PC32up(0x60, r); \ + a[0x0D] ^= PC32dn(0x60, r); \ + a[0x0E] ^= PC32up(0x70, r); \ + a[0x0F] ^= PC32dn(0x70, r); \ + a[0x10] ^= PC32up(0x80, r); \ + a[0x11] ^= PC32dn(0x80, r); \ + a[0x12] ^= PC32up(0x90, r); \ + a[0x13] ^= PC32dn(0x90, r); \ + a[0x14] ^= PC32up(0xA0, r); \ + a[0x15] ^= PC32dn(0xA0, r); \ + a[0x16] ^= PC32up(0xB0, r); \ + a[0x17] ^= PC32dn(0xB0, r); \ + a[0x18] ^= PC32up(0xC0, r); \ + a[0x19] ^= PC32dn(0xC0, r); \ + a[0x1A] ^= PC32up(0xD0, r); \ + a[0x1B] ^= PC32dn(0xD0, r); \ + a[0x1C] ^= PC32up(0xE0, r); \ + a[0x1D] ^= PC32dn(0xE0, r); \ + a[0x1E] ^= PC32up(0xF0, r); \ + a[0x1F] ^= PC32dn(0xF0, r); \ + RBTT(0x00, 0x01, a, \ + 0x00, 0x02, 0x04, 0x06, 0x09, 0x0B, 0x0D, 0x17); \ + RBTT(0x02, 0x03, a, \ + 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x0F, 0x19); \ + RBTT(0x04, 0x05, a, \ + 0x04, 0x06, 0x08, 0x0A, 0x0D, 0x0F, 0x11, 0x1B); \ + RBTT(0x06, 0x07, a, \ + 0x06, 0x08, 0x0A, 0x0C, 0x0F, 0x11, 0x13, 0x1D); \ + RBTT(0x08, 0x09, a, \ + 0x08, 0x0A, 0x0C, 0x0E, 0x11, 0x13, 0x15, 0x1F); \ + RBTT(0x0A, 0x0B, a, \ + 0x0A, 0x0C, 0x0E, 0x10, 0x13, 0x15, 0x17, 0x01); \ + RBTT(0x0C, 0x0D, a, \ + 0x0C, 0x0E, 0x10, 0x12, 0x15, 0x17, 0x19, 0x03); \ + RBTT(0x0E, 0x0F, a, \ + 0x0E, 0x10, 0x12, 0x14, 0x17, 0x19, 0x1B, 0x05); \ + RBTT(0x10, 0x11, a, \ + 0x10, 0x12, 0x14, 0x16, 0x19, 0x1B, 0x1D, 0x07); \ + RBTT(0x12, 0x13, a, \ + 0x12, 0x14, 0x16, 0x18, 0x1B, 0x1D, 0x1F, 0x09); \ + RBTT(0x14, 0x15, a, \ + 0x14, 0x16, 0x18, 0x1A, 0x1D, 0x1F, 0x01, 0x0B); \ + RBTT(0x16, 0x17, a, \ + 0x16, 0x18, 0x1A, 0x1C, 0x1F, 0x01, 0x03, 0x0D); \ + RBTT(0x18, 0x19, a, \ + 0x18, 0x1A, 0x1C, 0x1E, 0x01, 0x03, 0x05, 0x0F); \ + RBTT(0x1A, 0x1B, a, \ + 0x1A, 0x1C, 0x1E, 0x00, 0x03, 0x05, 0x07, 0x11); \ + RBTT(0x1C, 0x1D, a, \ + 0x1C, 0x1E, 0x00, 0x02, 0x05, 0x07, 0x09, 0x13); \ + RBTT(0x1E, 0x1F, a, \ + 0x1E, 0x00, 0x02, 0x04, 0x07, 0x09, 0x0B, 0x15); \ + memcpy(a, t, sizeof t); \ + } while (0) + +#define ROUND_BIG_Q(a, r) do { \ + sph_u32 t[32]; \ + a[0x00] ^= QC32up(0x00, r); \ + a[0x01] ^= QC32dn(0x00, r); \ + a[0x02] ^= QC32up(0x10, r); \ + a[0x03] ^= QC32dn(0x10, r); \ + a[0x04] ^= QC32up(0x20, r); \ + a[0x05] ^= QC32dn(0x20, r); \ + a[0x06] ^= QC32up(0x30, r); \ + a[0x07] ^= QC32dn(0x30, r); \ + a[0x08] ^= QC32up(0x40, r); \ + a[0x09] ^= QC32dn(0x40, r); \ + a[0x0A] ^= QC32up(0x50, r); \ + a[0x0B] ^= QC32dn(0x50, r); \ + a[0x0C] ^= QC32up(0x60, r); \ + a[0x0D] ^= QC32dn(0x60, r); \ + a[0x0E] ^= QC32up(0x70, r); \ + a[0x0F] ^= QC32dn(0x70, r); \ + a[0x10] ^= QC32up(0x80, r); \ + a[0x11] ^= QC32dn(0x80, r); \ + a[0x12] ^= QC32up(0x90, r); \ + a[0x13] ^= QC32dn(0x90, r); \ + a[0x14] ^= QC32up(0xA0, r); \ + a[0x15] ^= QC32dn(0xA0, r); \ + a[0x16] ^= QC32up(0xB0, r); \ + a[0x17] ^= QC32dn(0xB0, r); \ + a[0x18] ^= QC32up(0xC0, r); \ + a[0x19] ^= QC32dn(0xC0, r); \ + a[0x1A] ^= QC32up(0xD0, r); \ + a[0x1B] ^= QC32dn(0xD0, r); \ + a[0x1C] ^= QC32up(0xE0, r); \ + a[0x1D] ^= QC32dn(0xE0, r); \ + a[0x1E] ^= QC32up(0xF0, r); \ + a[0x1F] ^= QC32dn(0xF0, r); \ + RBTT(0x00, 0x01, a, \ + 0x02, 0x06, 0x0A, 0x16, 0x01, 0x05, 0x09, 0x0D); \ + RBTT(0x02, 0x03, a, \ + 0x04, 0x08, 0x0C, 0x18, 0x03, 0x07, 0x0B, 0x0F); \ + RBTT(0x04, 0x05, a, \ + 0x06, 0x0A, 0x0E, 0x1A, 0x05, 0x09, 0x0D, 0x11); \ + RBTT(0x06, 0x07, a, \ + 0x08, 0x0C, 0x10, 0x1C, 0x07, 0x0B, 0x0F, 0x13); \ + RBTT(0x08, 0x09, a, \ + 0x0A, 0x0E, 0x12, 0x1E, 0x09, 0x0D, 0x11, 0x15); \ + RBTT(0x0A, 0x0B, a, \ + 0x0C, 0x10, 0x14, 0x00, 0x0B, 0x0F, 0x13, 0x17); \ + RBTT(0x0C, 0x0D, a, \ + 0x0E, 0x12, 0x16, 0x02, 0x0D, 0x11, 0x15, 0x19); \ + RBTT(0x0E, 0x0F, a, \ + 0x10, 0x14, 0x18, 0x04, 0x0F, 0x13, 0x17, 0x1B); \ + RBTT(0x10, 0x11, a, \ + 0x12, 0x16, 0x1A, 0x06, 0x11, 0x15, 0x19, 0x1D); \ + RBTT(0x12, 0x13, a, \ + 0x14, 0x18, 0x1C, 0x08, 0x13, 0x17, 0x1B, 0x1F); \ + RBTT(0x14, 0x15, a, \ + 0x16, 0x1A, 0x1E, 0x0A, 0x15, 0x19, 0x1D, 0x01); \ + RBTT(0x16, 0x17, a, \ + 0x18, 0x1C, 0x00, 0x0C, 0x17, 0x1B, 0x1F, 0x03); \ + RBTT(0x18, 0x19, a, \ + 0x1A, 0x1E, 0x02, 0x0E, 0x19, 0x1D, 0x01, 0x05); \ + RBTT(0x1A, 0x1B, a, \ + 0x1C, 0x00, 0x04, 0x10, 0x1B, 0x1F, 0x03, 0x07); \ + RBTT(0x1C, 0x1D, a, \ + 0x1E, 0x02, 0x06, 0x12, 0x1D, 0x01, 0x05, 0x09); \ + RBTT(0x1E, 0x1F, a, \ + 0x00, 0x04, 0x08, 0x14, 0x1F, 0x03, 0x07, 0x0B); \ + memcpy(a, t, sizeof t); \ + } while (0) + +#endif + +#if SPH_SMALL_FOOTPRINT_GROESTL + +#define PERM_BIG_P(a) do { \ + int r; \ + for (r = 0; r < 14; r ++) \ + ROUND_BIG_P(a, r); \ + } while (0) + +#define PERM_BIG_Q(a) do { \ + int r; \ + for (r = 0; r < 14; r ++) \ + ROUND_BIG_Q(a, r); \ + } while (0) + +#else + +#define PERM_BIG_P(a) do { \ + int r; \ + for (r = 0; r < 14; r += 2) { \ + ROUND_BIG_P(a, r + 0); \ + ROUND_BIG_P(a, r + 1); \ + } \ + } while (0) + +#define PERM_BIG_Q(a) do { \ + int r; \ + for (r = 0; r < 14; r += 2) { \ + ROUND_BIG_Q(a, r + 0); \ + ROUND_BIG_Q(a, r + 1); \ + } \ + } while (0) + +#endif + +#define COMPRESS_BIG do { \ + sph_u32 g[32], m[32]; \ + size_t u; \ + for (u = 0; u < 32; u ++) { \ + m[u] = dec32e_aligned(buf + (u << 2)); \ + g[u] = m[u] ^ H[u]; \ + } \ + PERM_BIG_P(g); \ + PERM_BIG_Q(m); \ + for (u = 0; u < 32; u ++) \ + H[u] ^= g[u] ^ m[u]; \ + } while (0) + +#define FINAL_BIG do { \ + sph_u32 x[32]; \ + size_t u; \ + memcpy(x, H, sizeof x); \ + PERM_BIG_P(x); \ + for (u = 0; u < 32; u ++) \ + H[u] ^= x[u]; \ + } while (0) + +#endif + +static void +groestl_small_init(sph_groestl_small_context *sc, unsigned out_size) +{ + size_t u; + + sc->ptr = 0; +#if SPH_GROESTL_64 + for (u = 0; u < 7; u ++) + sc->state.wide[u] = 0; +#if USE_LE + sc->state.wide[7] = ((sph_u64)(out_size & 0xFF) << 56) + | ((sph_u64)(out_size & 0xFF00) << 40); +#else + sc->state.wide[7] = (sph_u64)out_size; +#endif +#else + for (u = 0; u < 15; u ++) + sc->state.narrow[u] = 0; +#if USE_LE + sc->state.narrow[15] = ((sph_u32)(out_size & 0xFF) << 24) + | ((sph_u32)(out_size & 0xFF00) << 8); +#else + sc->state.narrow[15] = (sph_u32)out_size; +#endif +#endif +#if SPH_64 + sc->count = 0; +#else + sc->count_high = 0; + sc->count_low = 0; +#endif +} + +static void +groestl_small_core(sph_groestl_small_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE_SMALL + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE_SMALL(sc); + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - ptr; + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + ptr += clen; + data = (const unsigned char *)data + clen; + len -= clen; + if (ptr == sizeof sc->buf) { + COMPRESS_SMALL; +#if SPH_64 + sc->count ++; +#else + if ((sc->count_low = SPH_T32(sc->count_low + 1)) == 0) + sc->count_high = SPH_T32(sc->count_high + 1); +#endif + ptr = 0; + } + } + WRITE_STATE_SMALL(sc); + sc->ptr = ptr; +} + +static void +groestl_small_close(sph_groestl_small_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_len) +{ + unsigned char *buf; + unsigned char pad[72]; + size_t u, ptr, pad_len; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif + unsigned z; + DECL_STATE_SMALL + + buf = sc->buf; + ptr = sc->ptr; + z = 0x80 >> n; + pad[0] = ((ub & -z) | z) & 0xFF; + if (ptr < 56) { + pad_len = 64 - ptr; +#if SPH_64 + count = SPH_T64(sc->count + 1); +#else + count_low = SPH_T32(sc->count_low + 1); + count_high = SPH_T32(sc->count_high); + if (count_low == 0) + count_high = SPH_T32(count_high + 1); +#endif + } else { + pad_len = 128 - ptr; +#if SPH_64 + count = SPH_T64(sc->count + 2); +#else + count_low = SPH_T32(sc->count_low + 2); + count_high = SPH_T32(sc->count_high); + if (count_low <= 1) + count_high = SPH_T32(count_high + 1); +#endif + } + memset(pad + 1, 0, pad_len - 9); +#if SPH_64 + sph_enc64be(pad + pad_len - 8, count); +#else + sph_enc64be(pad + pad_len - 8, count_high); + sph_enc64be(pad + pad_len - 4, count_low); +#endif + groestl_small_core(sc, pad, pad_len); + READ_STATE_SMALL(sc); + FINAL_SMALL; +#if SPH_GROESTL_64 + for (u = 0; u < 4; u ++) + enc64e(pad + (u << 3), H[u + 4]); +#else + for (u = 0; u < 8; u ++) + enc32e(pad + (u << 2), H[u + 8]); +#endif + memcpy(dst, pad + 32 - out_len, out_len); + groestl_small_init(sc, (unsigned)out_len << 3); +} + +static void +groestl_big_init(sph_groestl_big_context *sc, unsigned out_size) +{ + size_t u; + + sc->ptr = 0; +#if SPH_GROESTL_64 + for (u = 0; u < 15; u ++) + sc->state.wide[u] = 0; +#if USE_LE + sc->state.wide[15] = ((sph_u64)(out_size & 0xFF) << 56) + | ((sph_u64)(out_size & 0xFF00) << 40); +#else + sc->state.wide[15] = (sph_u64)out_size; +#endif +#else + for (u = 0; u < 31; u ++) + sc->state.narrow[u] = 0; +#if USE_LE + sc->state.narrow[31] = ((sph_u32)(out_size & 0xFF) << 24) + | ((sph_u32)(out_size & 0xFF00) << 8); +#else + sc->state.narrow[31] = (sph_u32)out_size; +#endif +#endif +#if SPH_64 + sc->count = 0; +#else + sc->count_high = 0; + sc->count_low = 0; +#endif +} + +static void +groestl_big_core(sph_groestl_big_context *sc, const void *data, size_t len) +{ + unsigned char *buf; + size_t ptr; + DECL_STATE_BIG + + buf = sc->buf; + ptr = sc->ptr; + if (len < (sizeof sc->buf) - ptr) { + memcpy(buf + ptr, data, len); + ptr += len; + sc->ptr = ptr; + return; + } + + READ_STATE_BIG(sc); + while (len > 0) { + size_t clen; + + clen = (sizeof sc->buf) - ptr; + if (clen > len) + clen = len; + memcpy(buf + ptr, data, clen); + ptr += clen; + data = (const unsigned char *)data + clen; + len -= clen; + if (ptr == sizeof sc->buf) { + COMPRESS_BIG; +#if SPH_64 + sc->count ++; +#else + if ((sc->count_low = SPH_T32(sc->count_low + 1)) == 0) + sc->count_high = SPH_T32(sc->count_high + 1); +#endif + ptr = 0; + } + } + WRITE_STATE_BIG(sc); + sc->ptr = ptr; +} + +static void +groestl_big_close(sph_groestl_big_context *sc, + unsigned ub, unsigned n, void *dst, size_t out_len) +{ + unsigned char *buf; + unsigned char pad[136]; + size_t ptr, pad_len, u; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif + unsigned z; + DECL_STATE_BIG + + buf = sc->buf; + ptr = sc->ptr; + z = 0x80 >> n; + pad[0] = ((ub & -z) | z) & 0xFF; + if (ptr < 120) { + pad_len = 128 - ptr; +#if SPH_64 + count = SPH_T64(sc->count + 1); +#else + count_low = SPH_T32(sc->count_low + 1); + count_high = SPH_T32(sc->count_high); + if (count_low == 0) + count_high = SPH_T32(count_high + 1); +#endif + } else { + pad_len = 256 - ptr; +#if SPH_64 + count = SPH_T64(sc->count + 2); +#else + count_low = SPH_T32(sc->count_low + 2); + count_high = SPH_T32(sc->count_high); + if (count_low <= 1) + count_high = SPH_T32(count_high + 1); +#endif + } + memset(pad + 1, 0, pad_len - 9); +#if SPH_64 + sph_enc64be(pad + pad_len - 8, count); +#else + sph_enc64be(pad + pad_len - 8, count_high); + sph_enc64be(pad + pad_len - 4, count_low); +#endif + groestl_big_core(sc, pad, pad_len); + READ_STATE_BIG(sc); + FINAL_BIG; +#if SPH_GROESTL_64 + for (u = 0; u < 8; u ++) + enc64e(pad + (u << 3), H[u + 8]); +#else + for (u = 0; u < 16; u ++) + enc32e(pad + (u << 2), H[u + 16]); +#endif + memcpy(dst, pad + 64 - out_len, out_len); + groestl_big_init(sc, (unsigned)out_len << 3); +} + +/* see sph_groestl.h */ +void +sph_groestl224_init(void *cc) +{ + groestl_small_init(cc, 224); +} + +/* see sph_groestl.h */ +void +sph_groestl224(void *cc, const void *data, size_t len) +{ + groestl_small_core(cc, data, len); +} + +/* see sph_groestl.h */ +void +sph_groestl224_close(void *cc, void *dst) +{ + groestl_small_close(cc, 0, 0, dst, 28); +} + +/* see sph_groestl.h */ +void +sph_groestl224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + groestl_small_close(cc, ub, n, dst, 28); +} + +/* see sph_groestl.h */ +void +sph_groestl256_init(void *cc) +{ + groestl_small_init(cc, 256); +} + +/* see sph_groestl.h */ +void +sph_groestl256(void *cc, const void *data, size_t len) +{ + groestl_small_core(cc, data, len); +} + +/* see sph_groestl.h */ +void +sph_groestl256_close(void *cc, void *dst) +{ + groestl_small_close(cc, 0, 0, dst, 32); +} + +/* see sph_groestl.h */ +void +sph_groestl256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + groestl_small_close(cc, ub, n, dst, 32); +} + +/* see sph_groestl.h */ +void +sph_groestl384_init(void *cc) +{ + groestl_big_init(cc, 384); +} + +/* see sph_groestl.h */ +void +sph_groestl384(void *cc, const void *data, size_t len) +{ + groestl_big_core(cc, data, len); +} + +/* see sph_groestl.h */ +void +sph_groestl384_close(void *cc, void *dst) +{ + groestl_big_close(cc, 0, 0, dst, 48); +} + +/* see sph_groestl.h */ +void +sph_groestl384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + groestl_big_close(cc, ub, n, dst, 48); +} + +/* see sph_groestl.h */ +void +sph_groestl512_init(void *cc) +{ + groestl_big_init(cc, 512); +} + +/* see sph_groestl.h */ +void +sph_groestl512(void *cc, const void *data, size_t len) +{ + groestl_big_core(cc, data, len); +} + +/* see sph_groestl.h */ +void +sph_groestl512_close(void *cc, void *dst) +{ + groestl_big_close(cc, 0, 0, dst, 64); +} + +/* see sph_groestl.h */ +void +sph_groestl512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst) +{ + groestl_big_close(cc, ub, n, dst, 64); +} + +void HashGroestl(void * buf, const void * pbegin, int len) +{ + sph_groestl512_context ctx_gr[2]; unsigned int i; + static unsigned char pblank[1]; + char hash[64]; + char hash2[64]; + + sph_groestl512_init(&ctx_gr[0]); + sph_groestl512 (&ctx_gr[0], (len <= 0 ? pblank : (unsigned char*)pbegin), len); + sph_groestl512_close(&ctx_gr[0], hash); + + sph_groestl512_init(&ctx_gr[1]); + sph_groestl512(&ctx_gr[1],hash,64); + sph_groestl512_close(&ctx_gr[1],hash2); + + for (i = 0; i < 32; i++){ + ((char*)buf)[i] = hash2[i]; + } + +} + + +#ifdef __cplusplus +} +#endif diff --git a/iguana/groestl.h b/iguana/groestl.h new file mode 100644 index 000000000..495f05e21 --- /dev/null +++ b/iguana/groestl.h @@ -0,0 +1,329 @@ +/* $Id: sph_groestl.h 216 2010-06-08 09:46:57Z tp $ */ +/** + * Groestl interface. This code implements Groestl with the recommended + * parameters for SHA-3, with outputs of 224, 256, 384 and 512 bits. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_groestl.h + * @author Thomas Pornin + */ + +#ifndef SPH_GROESTL_H__ +#define SPH_GROESTL_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#include +#include "sph_types.h" + +/** + * Output size (in bits) for Groestl-224. + */ +#define SPH_SIZE_groestl224 224 + +/** + * Output size (in bits) for Groestl-256. + */ +#define SPH_SIZE_groestl256 256 + +/** + * Output size (in bits) for Groestl-384. + */ +#define SPH_SIZE_groestl384 384 + +/** + * Output size (in bits) for Groestl-512. + */ +#define SPH_SIZE_groestl512 512 + +/** + * This structure is a context for Groestl-224 and Groestl-256 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a Groestl computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running Groestl + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[64]; /* first field, for alignment */ + size_t ptr; + union { +#if SPH_64 + sph_u64 wide[8]; +#endif + sph_u32 narrow[16]; + } state; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_groestl_small_context; + +/** + * This structure is a context for Groestl-224 computations. It is + * identical to the common sph_groestl_small_context. + */ +typedef sph_groestl_small_context sph_groestl224_context; + +/** + * This structure is a context for Groestl-256 computations. It is + * identical to the common sph_groestl_small_context. + */ +typedef sph_groestl_small_context sph_groestl256_context; + +/** + * This structure is a context for Groestl-384 and Groestl-512 computations: + * it contains the intermediate values and some data from the last + * entered block. Once a Groestl computation has been performed, the + * context can be reused for another computation. + * + * The contents of this structure are private. A running Groestl + * computation can be cloned by copying the context (e.g. with a simple + * memcpy()). + */ +typedef struct { +#ifndef DOXYGEN_IGNORE + unsigned char buf[128]; /* first field, for alignment */ + size_t ptr; + union { +#if SPH_64 + sph_u64 wide[16]; +#endif + sph_u32 narrow[32]; + } state; +#if SPH_64 + sph_u64 count; +#else + sph_u32 count_high, count_low; +#endif +#endif +} sph_groestl_big_context; + +/** + * This structure is a context for Groestl-384 computations. It is + * identical to the common sph_groestl_small_context. + */ +typedef sph_groestl_big_context sph_groestl384_context; + +/** + * This structure is a context for Groestl-512 computations. It is + * identical to the common sph_groestl_small_context. + */ +typedef sph_groestl_big_context sph_groestl512_context; + +/** + * Initialize a Groestl-224 context. This process performs no memory allocation. + * + * @param cc the Groestl-224 context (pointer to a + * sph_groestl224_context) + */ +void sph_groestl224_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Groestl-224 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_groestl224(void *cc, const void *data, size_t len); + +/** + * Terminate the current Groestl-224 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (28 bytes). The context is automatically + * reinitialized. + * + * @param cc the Groestl-224 context + * @param dst the destination buffer + */ +void sph_groestl224_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (28 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Groestl-224 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_groestl224_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Groestl-256 context. This process performs no memory allocation. + * + * @param cc the Groestl-256 context (pointer to a + * sph_groestl256_context) + */ +void sph_groestl256_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Groestl-256 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_groestl256(void *cc, const void *data, size_t len); + +/** + * Terminate the current Groestl-256 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (32 bytes). The context is automatically + * reinitialized. + * + * @param cc the Groestl-256 context + * @param dst the destination buffer + */ +void sph_groestl256_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (32 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Groestl-256 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_groestl256_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Groestl-384 context. This process performs no memory allocation. + * + * @param cc the Groestl-384 context (pointer to a + * sph_groestl384_context) + */ +void sph_groestl384_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Groestl-384 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_groestl384(void *cc, const void *data, size_t len); + +/** + * Terminate the current Groestl-384 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (48 bytes). The context is automatically + * reinitialized. + * + * @param cc the Groestl-384 context + * @param dst the destination buffer + */ +void sph_groestl384_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (48 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Groestl-384 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_groestl384_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +/** + * Initialize a Groestl-512 context. This process performs no memory allocation. + * + * @param cc the Groestl-512 context (pointer to a + * sph_groestl512_context) + */ +void sph_groestl512_init(void *cc); + +/** + * Process some data bytes. It is acceptable that len is zero + * (in which case this function does nothing). + * + * @param cc the Groestl-512 context + * @param data the input data + * @param len the input data length (in bytes) + */ +void sph_groestl512(void *cc, const void *data, size_t len); + +/** + * Terminate the current Groestl-512 computation and output the result into + * the provided buffer. The destination buffer must be wide enough to + * accomodate the result (64 bytes). The context is automatically + * reinitialized. + * + * @param cc the Groestl-512 context + * @param dst the destination buffer + */ +void sph_groestl512_close(void *cc, void *dst); + +/** + * Add a few additional bits (0 to 7) to the current computation, then + * terminate it and output the result in the provided buffer, which must + * be wide enough to accomodate the result (64 bytes). If bit number i + * in ub has value 2^i, then the extra bits are those + * numbered 7 downto 8-n (this is the big-endian convention at the byte + * level). The context is automatically reinitialized. + * + * @param cc the Groestl-512 context + * @param ub the extra bits + * @param n the number of extra bits (0 to 7) + * @param dst the destination buffer + */ +void sph_groestl512_addbits_and_close( + void *cc, unsigned ub, unsigned n, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/iguana/help/InstantDEX_DEXratio.json b/iguana/help/InstantDEX_DEXratio.json new file mode 100644 index 000000000..cc7bbd980 --- /dev/null +++ b/iguana/help/InstantDEX_DEXratio.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"DEXratio","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_DEXratio_test.py"}]} diff --git a/iguana/help/InstantDEX_accept.json b/iguana/help/InstantDEX_accept.json new file mode 100644 index 000000000..92c1d4521 --- /dev/null +++ b/iguana/help/InstantDEX_accept.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"accept","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_accept_test.py"}]} diff --git a/iguana/help/InstantDEX_allcoins.json b/iguana/help/InstantDEX_allcoins.json new file mode 100644 index 000000000..41d3a3ac3 --- /dev/null +++ b/iguana/help/InstantDEX_allcoins.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"allcoins","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_allcoins_test.py"}]} diff --git a/iguana/help/InstantDEX_allexchanges.json b/iguana/help/InstantDEX_allexchanges.json new file mode 100644 index 000000000..1d3e588fa --- /dev/null +++ b/iguana/help/InstantDEX_allexchanges.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"allexchanges","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_allexchanges_test.py"}]} diff --git a/iguana/help/InstantDEX_allpairs.json b/iguana/help/InstantDEX_allpairs.json new file mode 100644 index 000000000..80b71c2b9 --- /dev/null +++ b/iguana/help/InstantDEX_allpairs.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"allpairs","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_allpairs_test.py"}]} diff --git a/iguana/help/InstantDEX_apikeypair.json b/iguana/help/InstantDEX_apikeypair.json new file mode 100644 index 000000000..ed6a4d911 --- /dev/null +++ b/iguana/help/InstantDEX_apikeypair.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"apikeypair","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_apikeypair_test.py"}]} diff --git a/iguana/help/InstantDEX_automatched.json b/iguana/help/InstantDEX_automatched.json new file mode 100644 index 000000000..b9626ec23 --- /dev/null +++ b/iguana/help/InstantDEX_automatched.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"automatched","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_automatched_test.py"}]} diff --git a/iguana/help/InstantDEX_available.json b/iguana/help/InstantDEX_available.json new file mode 100644 index 000000000..18ed08484 --- /dev/null +++ b/iguana/help/InstantDEX_available.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"available","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_available_test.py"}]} diff --git a/iguana/help/InstantDEX_balance.json b/iguana/help/InstantDEX_balance.json new file mode 100644 index 000000000..c70d5b99f --- /dev/null +++ b/iguana/help/InstantDEX_balance.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"balance","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_balance_test.py"}]} diff --git a/iguana/help/InstantDEX_buy.json b/iguana/help/InstantDEX_buy.json new file mode 100644 index 000000000..1c3636e07 --- /dev/null +++ b/iguana/help/InstantDEX_buy.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"buy","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_buy_test.py"}]} diff --git a/iguana/help/InstantDEX_cancelorder.json b/iguana/help/InstantDEX_cancelorder.json new file mode 100644 index 000000000..ea397f36d --- /dev/null +++ b/iguana/help/InstantDEX_cancelorder.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"cancelorder","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_cancelorder_test.py"}]} diff --git a/iguana/help/InstantDEX_getswaplist.json b/iguana/help/InstantDEX_getswaplist.json new file mode 100644 index 000000000..59caa393b --- /dev/null +++ b/iguana/help/InstantDEX_getswaplist.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"getswaplist","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_getswaplist_test.py"}]} diff --git a/iguana/help/InstantDEX_incoming.json b/iguana/help/InstantDEX_incoming.json new file mode 100644 index 000000000..f698f45d7 --- /dev/null +++ b/iguana/help/InstantDEX_incoming.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"incoming","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_incoming_test.py"}]} diff --git a/iguana/help/InstantDEX_init.json b/iguana/help/InstantDEX_init.json new file mode 100644 index 000000000..1caaab76f --- /dev/null +++ b/iguana/help/InstantDEX_init.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"init","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_init_test.py"}]} diff --git a/iguana/help/InstantDEX_openorders.json b/iguana/help/InstantDEX_openorders.json new file mode 100644 index 000000000..dfd406ecd --- /dev/null +++ b/iguana/help/InstantDEX_openorders.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"openorders","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_openorders_test.py"}]} diff --git a/iguana/help/InstantDEX_orderbook.json b/iguana/help/InstantDEX_orderbook.json new file mode 100644 index 000000000..beff23123 --- /dev/null +++ b/iguana/help/InstantDEX_orderbook.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"orderbook","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_orderbook_test.py"}]} diff --git a/iguana/help/InstantDEX_orderstatus.json b/iguana/help/InstantDEX_orderstatus.json new file mode 100644 index 000000000..613e54400 --- /dev/null +++ b/iguana/help/InstantDEX_orderstatus.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"orderstatus","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_orderstatus_test.py"}]} diff --git a/iguana/help/InstantDEX_pollgap.json b/iguana/help/InstantDEX_pollgap.json new file mode 100644 index 000000000..b90628331 --- /dev/null +++ b/iguana/help/InstantDEX_pollgap.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"pollgap","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_pollgap_test.py"}]} diff --git a/iguana/help/InstantDEX_request.json b/iguana/help/InstantDEX_request.json new file mode 100644 index 000000000..9dde5538e --- /dev/null +++ b/iguana/help/InstantDEX_request.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"request","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_request_test.py"}]} diff --git a/iguana/help/InstantDEX_sell.json b/iguana/help/InstantDEX_sell.json new file mode 100644 index 000000000..57a939570 --- /dev/null +++ b/iguana/help/InstantDEX_sell.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"sell","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_sell_test.py"}]} diff --git a/iguana/help/InstantDEX_setuserid.json b/iguana/help/InstantDEX_setuserid.json new file mode 100644 index 000000000..0b2dd819c --- /dev/null +++ b/iguana/help/InstantDEX_setuserid.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"setuserid","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_setuserid_test.py"}]} diff --git a/iguana/help/InstantDEX_smartaddress.json b/iguana/help/InstantDEX_smartaddress.json new file mode 100644 index 000000000..18924dca4 --- /dev/null +++ b/iguana/help/InstantDEX_smartaddress.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"smartaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_smartaddress_test.py"}]} diff --git a/iguana/help/InstantDEX_smartaddresses.json b/iguana/help/InstantDEX_smartaddresses.json new file mode 100644 index 000000000..39f3f1d20 --- /dev/null +++ b/iguana/help/InstantDEX_smartaddresses.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"smartaddresses","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_smartaddresses_test.py"}]} diff --git a/iguana/help/InstantDEX_supports.json b/iguana/help/InstantDEX_supports.json new file mode 100644 index 000000000..254fea7aa --- /dev/null +++ b/iguana/help/InstantDEX_supports.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"supports","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_supports_test.py"}]} diff --git a/iguana/help/InstantDEX_tradehistory.json b/iguana/help/InstantDEX_tradehistory.json new file mode 100644 index 000000000..5feba4639 --- /dev/null +++ b/iguana/help/InstantDEX_tradehistory.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"tradehistory","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_tradehistory_test.py"}]} diff --git a/iguana/help/InstantDEX_withdraw.json b/iguana/help/InstantDEX_withdraw.json new file mode 100644 index 000000000..45aa88599 --- /dev/null +++ b/iguana/help/InstantDEX_withdraw.json @@ -0,0 +1 @@ +{"agent":"InstantDEX","method":"withdraw","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"InstantDEX_withdraw_test.py"}]} diff --git a/iguana/help/SuperNET_activehandle.json b/iguana/help/SuperNET_activehandle.json new file mode 100644 index 000000000..1530b8c01 --- /dev/null +++ b/iguana/help/SuperNET_activehandle.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"activehandle","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_activehandle_test.py"}]} diff --git a/iguana/help/SuperNET_addr2rmd160.json b/iguana/help/SuperNET_addr2rmd160.json new file mode 100644 index 000000000..a3a40aac4 --- /dev/null +++ b/iguana/help/SuperNET_addr2rmd160.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"addr2rmd160","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_addr2rmd160_test.py"}]} diff --git a/iguana/help/SuperNET_bitcoinrpc.json b/iguana/help/SuperNET_bitcoinrpc.json new file mode 100644 index 000000000..46422d4d7 --- /dev/null +++ b/iguana/help/SuperNET_bitcoinrpc.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"bitcoinrpc","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_bitcoinrpc_test.py"}]} diff --git a/iguana/help/SuperNET_broadcastcipher.json b/iguana/help/SuperNET_broadcastcipher.json new file mode 100644 index 000000000..7d762494d --- /dev/null +++ b/iguana/help/SuperNET_broadcastcipher.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"broadcastcipher","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_broadcastcipher_test.py"}]} diff --git a/iguana/help/SuperNET_broadcastdecipher.json b/iguana/help/SuperNET_broadcastdecipher.json new file mode 100644 index 000000000..d0c9a482a --- /dev/null +++ b/iguana/help/SuperNET_broadcastdecipher.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"broadcastdecipher","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_broadcastdecipher_test.py"}]} diff --git a/iguana/help/SuperNET_cipher.json b/iguana/help/SuperNET_cipher.json new file mode 100644 index 000000000..fe40ca2b7 --- /dev/null +++ b/iguana/help/SuperNET_cipher.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"cipher","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_cipher_test.py"}]} diff --git a/iguana/help/SuperNET_decipher.json b/iguana/help/SuperNET_decipher.json new file mode 100644 index 000000000..e9f3afeb0 --- /dev/null +++ b/iguana/help/SuperNET_decipher.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"decipher","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_decipher_test.py"}]} diff --git a/iguana/help/SuperNET_decryptjson.json b/iguana/help/SuperNET_decryptjson.json new file mode 100644 index 000000000..99f744a30 --- /dev/null +++ b/iguana/help/SuperNET_decryptjson.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"decryptjson","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_decryptjson_test.py"}]} diff --git a/iguana/help/SuperNET_encryptjson.json b/iguana/help/SuperNET_encryptjson.json new file mode 100644 index 000000000..ab8e48167 --- /dev/null +++ b/iguana/help/SuperNET_encryptjson.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"encryptjson","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_encryptjson_test.py"}]} diff --git a/iguana/help/SuperNET_getpeers.json b/iguana/help/SuperNET_getpeers.json new file mode 100644 index 000000000..0b0668d7c --- /dev/null +++ b/iguana/help/SuperNET_getpeers.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"getpeers","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_getpeers_test.py"}]} diff --git a/iguana/help/SuperNET_help.json b/iguana/help/SuperNET_help.json new file mode 100644 index 000000000..6e15f801c --- /dev/null +++ b/iguana/help/SuperNET_help.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"help","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_help_test.py"}]} diff --git a/iguana/help/SuperNET_html.json b/iguana/help/SuperNET_html.json new file mode 100644 index 000000000..b964098e9 --- /dev/null +++ b/iguana/help/SuperNET_html.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"html","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_html_test.py"}]} diff --git a/iguana/help/SuperNET_keypair.json b/iguana/help/SuperNET_keypair.json new file mode 100644 index 000000000..cdd91ae55 --- /dev/null +++ b/iguana/help/SuperNET_keypair.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"keypair","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_keypair_test.py"}]} diff --git a/iguana/help/SuperNET_layer.json b/iguana/help/SuperNET_layer.json new file mode 100644 index 000000000..fe4ecf3d4 --- /dev/null +++ b/iguana/help/SuperNET_layer.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"layer","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_layer_test.py"}]} diff --git a/iguana/help/SuperNET_login.json b/iguana/help/SuperNET_login.json new file mode 100644 index 000000000..c95a70f88 --- /dev/null +++ b/iguana/help/SuperNET_login.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"login","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_login_test.py"}]} diff --git a/iguana/help/SuperNET_logout.json b/iguana/help/SuperNET_logout.json new file mode 100644 index 000000000..c81c52c82 --- /dev/null +++ b/iguana/help/SuperNET_logout.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"logout","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_logout_test.py"}]} diff --git a/iguana/help/SuperNET_multicastcipher.json b/iguana/help/SuperNET_multicastcipher.json new file mode 100644 index 000000000..f12acca5c --- /dev/null +++ b/iguana/help/SuperNET_multicastcipher.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"multicastcipher","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_multicastcipher_test.py"}]} diff --git a/iguana/help/SuperNET_multicastdecipher.json b/iguana/help/SuperNET_multicastdecipher.json new file mode 100644 index 000000000..6c7a28c63 --- /dev/null +++ b/iguana/help/SuperNET_multicastdecipher.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"multicastdecipher","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_multicastdecipher_test.py"}]} diff --git a/iguana/help/SuperNET_myipaddr.json b/iguana/help/SuperNET_myipaddr.json new file mode 100644 index 000000000..ca58efd1b --- /dev/null +++ b/iguana/help/SuperNET_myipaddr.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"myipaddr","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_myipaddr_test.py"}]} diff --git a/iguana/help/SuperNET_mypeers.json b/iguana/help/SuperNET_mypeers.json new file mode 100644 index 000000000..461a59d53 --- /dev/null +++ b/iguana/help/SuperNET_mypeers.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"mypeers","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_mypeers_test.py"}]} diff --git a/iguana/help/SuperNET_priv2pub.json b/iguana/help/SuperNET_priv2pub.json new file mode 100644 index 000000000..279268c76 --- /dev/null +++ b/iguana/help/SuperNET_priv2pub.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"priv2pub","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_priv2pub_test.py"}]} diff --git a/iguana/help/SuperNET_priv2wif.json b/iguana/help/SuperNET_priv2wif.json new file mode 100644 index 000000000..8fc080527 --- /dev/null +++ b/iguana/help/SuperNET_priv2wif.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"priv2wif","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_priv2wif_test.py"}]} diff --git a/iguana/help/SuperNET_rmd160conv.json b/iguana/help/SuperNET_rmd160conv.json new file mode 100644 index 000000000..831ff50f7 --- /dev/null +++ b/iguana/help/SuperNET_rmd160conv.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"rmd160conv","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_rmd160conv_test.py"}]} diff --git a/iguana/help/SuperNET_rosetta.json b/iguana/help/SuperNET_rosetta.json new file mode 100644 index 000000000..58c3ef933 --- /dev/null +++ b/iguana/help/SuperNET_rosetta.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"rosetta","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_rosetta_test.py"}]} diff --git a/iguana/help/SuperNET_saveconf.json b/iguana/help/SuperNET_saveconf.json new file mode 100644 index 000000000..e78fbf542 --- /dev/null +++ b/iguana/help/SuperNET_saveconf.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"saveconf","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_saveconf_test.py"}]} diff --git a/iguana/help/SuperNET_setmyipaddr.json b/iguana/help/SuperNET_setmyipaddr.json new file mode 100644 index 000000000..02a73f5d8 --- /dev/null +++ b/iguana/help/SuperNET_setmyipaddr.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"setmyipaddr","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_setmyipaddr_test.py"}]} diff --git a/iguana/help/SuperNET_stop.json b/iguana/help/SuperNET_stop.json new file mode 100644 index 000000000..29f40aadd --- /dev/null +++ b/iguana/help/SuperNET_stop.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"stop","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_stop_test.py"}]} diff --git a/iguana/help/SuperNET_utc2utime.json b/iguana/help/SuperNET_utc2utime.json new file mode 100644 index 000000000..f5fa3556f --- /dev/null +++ b/iguana/help/SuperNET_utc2utime.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"utc2utime","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_utc2utime_test.py"}]} diff --git a/iguana/help/SuperNET_utime2utc.json b/iguana/help/SuperNET_utime2utc.json new file mode 100644 index 000000000..000d81603 --- /dev/null +++ b/iguana/help/SuperNET_utime2utc.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"utime2utc","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_utime2utc_test.py"}]} diff --git a/iguana/help/SuperNET_wif2priv.json b/iguana/help/SuperNET_wif2priv.json new file mode 100644 index 000000000..e0447b36b --- /dev/null +++ b/iguana/help/SuperNET_wif2priv.json @@ -0,0 +1 @@ +{"agent":"SuperNET","method":"wif2priv","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"SuperNET_wif2priv_test.py"}]} diff --git a/iguana/help/basilisk_addrelay.json b/iguana/help/basilisk_addrelay.json new file mode 100644 index 000000000..a0faa2c84 --- /dev/null +++ b/iguana/help/basilisk_addrelay.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"addrelay","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_addrelay_test.py"}]} diff --git a/iguana/help/basilisk_balances.json b/iguana/help/basilisk_balances.json new file mode 100644 index 000000000..85bdf0f7f --- /dev/null +++ b/iguana/help/basilisk_balances.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"balances","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_balances_test.py"}]} diff --git a/iguana/help/basilisk_cancelrefresh.json b/iguana/help/basilisk_cancelrefresh.json new file mode 100644 index 000000000..1d2db83c9 --- /dev/null +++ b/iguana/help/basilisk_cancelrefresh.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"cancelrefresh","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_cancelrefresh_test.py"}]} diff --git a/iguana/help/basilisk_dispatch.json b/iguana/help/basilisk_dispatch.json new file mode 100644 index 000000000..395902152 --- /dev/null +++ b/iguana/help/basilisk_dispatch.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"dispatch","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_dispatch_test.py"}]} diff --git a/iguana/help/basilisk_forward.json b/iguana/help/basilisk_forward.json new file mode 100644 index 000000000..868424a14 --- /dev/null +++ b/iguana/help/basilisk_forward.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"forward","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_forward_test.py"}]} diff --git a/iguana/help/basilisk_geckoblock.json b/iguana/help/basilisk_geckoblock.json new file mode 100644 index 000000000..ed730f081 --- /dev/null +++ b/iguana/help/basilisk_geckoblock.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"geckoblock","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_geckoblock_test.py"}]} diff --git a/iguana/help/basilisk_geckoget.json b/iguana/help/basilisk_geckoget.json new file mode 100644 index 000000000..ddb097fab --- /dev/null +++ b/iguana/help/basilisk_geckoget.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"geckoget","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_geckoget_test.py"}]} diff --git a/iguana/help/basilisk_geckoheaders.json b/iguana/help/basilisk_geckoheaders.json new file mode 100644 index 000000000..30b600d6f --- /dev/null +++ b/iguana/help/basilisk_geckoheaders.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"geckoheaders","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_geckoheaders_test.py"}]} diff --git a/iguana/help/basilisk_geckotx.json b/iguana/help/basilisk_geckotx.json new file mode 100644 index 000000000..b55cf8582 --- /dev/null +++ b/iguana/help/basilisk_geckotx.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"geckotx","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_geckotx_test.py"}]} diff --git a/iguana/help/basilisk_genesis_opreturn.json b/iguana/help/basilisk_genesis_opreturn.json new file mode 100644 index 000000000..25c7e3277 --- /dev/null +++ b/iguana/help/basilisk_genesis_opreturn.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"genesis_opreturn","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_genesis_opreturn_test.py"}]} diff --git a/iguana/help/basilisk_getmessage.json b/iguana/help/basilisk_getmessage.json new file mode 100644 index 000000000..e4dbd9cdd --- /dev/null +++ b/iguana/help/basilisk_getmessage.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"getmessage","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_getmessage_test.py"}]} diff --git a/iguana/help/basilisk_history.json b/iguana/help/basilisk_history.json new file mode 100644 index 000000000..fd91aa8bc --- /dev/null +++ b/iguana/help/basilisk_history.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"history","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_history_test.py"}]} diff --git a/iguana/help/basilisk_mailbox.json b/iguana/help/basilisk_mailbox.json new file mode 100644 index 000000000..4eceaf50a --- /dev/null +++ b/iguana/help/basilisk_mailbox.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"mailbox","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_mailbox_test.py"}]} diff --git a/iguana/help/basilisk_paxfiats.json b/iguana/help/basilisk_paxfiats.json new file mode 100644 index 000000000..26a27c6cb --- /dev/null +++ b/iguana/help/basilisk_paxfiats.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"paxfiats","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_paxfiats_test.py"}]} diff --git a/iguana/help/basilisk_publish.json b/iguana/help/basilisk_publish.json new file mode 100644 index 000000000..1c0d9469c --- /dev/null +++ b/iguana/help/basilisk_publish.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"publish","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_publish_test.py"}]} diff --git a/iguana/help/basilisk_rawtx.json b/iguana/help/basilisk_rawtx.json new file mode 100644 index 000000000..73682aa14 --- /dev/null +++ b/iguana/help/basilisk_rawtx.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"rawtx","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_rawtx_test.py"}]} diff --git a/iguana/help/basilisk_refresh.json b/iguana/help/basilisk_refresh.json new file mode 100644 index 000000000..fc3ee50a8 --- /dev/null +++ b/iguana/help/basilisk_refresh.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"refresh","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_refresh_test.py"}]} diff --git a/iguana/help/basilisk_sendmessage.json b/iguana/help/basilisk_sendmessage.json new file mode 100644 index 000000000..96a8fab9e --- /dev/null +++ b/iguana/help/basilisk_sendmessage.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"sendmessage","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_sendmessage_test.py"}]} diff --git a/iguana/help/basilisk_subscribe.json b/iguana/help/basilisk_subscribe.json new file mode 100644 index 000000000..2369fefb9 --- /dev/null +++ b/iguana/help/basilisk_subscribe.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"subscribe","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_subscribe_test.py"}]} diff --git a/iguana/help/basilisk_utxocombine.json b/iguana/help/basilisk_utxocombine.json new file mode 100644 index 000000000..4ef0423ec --- /dev/null +++ b/iguana/help/basilisk_utxocombine.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"utxocombine","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_utxocombine_test.py"}]} diff --git a/iguana/help/basilisk_utxorawtx.json b/iguana/help/basilisk_utxorawtx.json new file mode 100644 index 000000000..f44828007 --- /dev/null +++ b/iguana/help/basilisk_utxorawtx.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"utxorawtx","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_utxorawtx_test.py"}]} diff --git a/iguana/help/basilisk_value.json b/iguana/help/basilisk_value.json new file mode 100644 index 000000000..2f3575ad8 --- /dev/null +++ b/iguana/help/basilisk_value.json @@ -0,0 +1 @@ +{"agent":"basilisk","method":"value","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"basilisk_value_test.py"}]} diff --git a/iguana/help/bitcoinrpc_addmultisigaddress.json b/iguana/help/bitcoinrpc_addmultisigaddress.json new file mode 100644 index 000000000..453eedab1 --- /dev/null +++ b/iguana/help/bitcoinrpc_addmultisigaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"addmultisigaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_addmultisigaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_backupwallet.json b/iguana/help/bitcoinrpc_backupwallet.json new file mode 100644 index 000000000..49d4977f6 --- /dev/null +++ b/iguana/help/bitcoinrpc_backupwallet.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"backupwallet","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_backupwallet_test.py"}]} diff --git a/iguana/help/bitcoinrpc_checkwallet.json b/iguana/help/bitcoinrpc_checkwallet.json new file mode 100644 index 000000000..7873ec3e3 --- /dev/null +++ b/iguana/help/bitcoinrpc_checkwallet.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"checkwallet","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_checkwallet_test.py"}]} diff --git a/iguana/help/bitcoinrpc_createmultisig.json b/iguana/help/bitcoinrpc_createmultisig.json new file mode 100644 index 000000000..1fc0af008 --- /dev/null +++ b/iguana/help/bitcoinrpc_createmultisig.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"createmultisig","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_createmultisig_test.py"}]} diff --git a/iguana/help/bitcoinrpc_createrawtransaction.json b/iguana/help/bitcoinrpc_createrawtransaction.json new file mode 100644 index 000000000..36a955996 --- /dev/null +++ b/iguana/help/bitcoinrpc_createrawtransaction.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"createrawtransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_createrawtransaction_test.py"}]} diff --git a/iguana/help/bitcoinrpc_decoderawtransaction.json b/iguana/help/bitcoinrpc_decoderawtransaction.json new file mode 100644 index 000000000..772f96900 --- /dev/null +++ b/iguana/help/bitcoinrpc_decoderawtransaction.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"decoderawtransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_decoderawtransaction_test.py"}]} diff --git a/iguana/help/bitcoinrpc_decodescript.json b/iguana/help/bitcoinrpc_decodescript.json new file mode 100644 index 000000000..9be4a77bf --- /dev/null +++ b/iguana/help/bitcoinrpc_decodescript.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"decodescript","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_decodescript_test.py"}]} diff --git a/iguana/help/bitcoinrpc_dumpprivkey.json b/iguana/help/bitcoinrpc_dumpprivkey.json new file mode 100644 index 000000000..b28fe7185 --- /dev/null +++ b/iguana/help/bitcoinrpc_dumpprivkey.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"dumpprivkey","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_dumpprivkey_test.py"}]} diff --git a/iguana/help/bitcoinrpc_dumpwallet.json b/iguana/help/bitcoinrpc_dumpwallet.json new file mode 100644 index 000000000..d0f3ed4f1 --- /dev/null +++ b/iguana/help/bitcoinrpc_dumpwallet.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"dumpwallet","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_dumpwallet_test.py"}]} diff --git a/iguana/help/bitcoinrpc_encryptwallet.json b/iguana/help/bitcoinrpc_encryptwallet.json new file mode 100644 index 000000000..3919c40a4 --- /dev/null +++ b/iguana/help/bitcoinrpc_encryptwallet.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"encryptwallet","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_encryptwallet_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getaccount.json b/iguana/help/bitcoinrpc_getaccount.json new file mode 100644 index 000000000..b0ecd2a9e --- /dev/null +++ b/iguana/help/bitcoinrpc_getaccount.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getaccount","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getaccount_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getaccountaddress.json b/iguana/help/bitcoinrpc_getaccountaddress.json new file mode 100644 index 000000000..cf3842825 --- /dev/null +++ b/iguana/help/bitcoinrpc_getaccountaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getaccountaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getaccountaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getaddressesbyaccount.json b/iguana/help/bitcoinrpc_getaddressesbyaccount.json new file mode 100644 index 000000000..12d42c814 --- /dev/null +++ b/iguana/help/bitcoinrpc_getaddressesbyaccount.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getaddressesbyaccount","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getaddressesbyaccount_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getbalance.json b/iguana/help/bitcoinrpc_getbalance.json new file mode 100644 index 000000000..22f234744 --- /dev/null +++ b/iguana/help/bitcoinrpc_getbalance.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getbalance","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getbalance_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getbestblockhash.json b/iguana/help/bitcoinrpc_getbestblockhash.json new file mode 100644 index 000000000..e2c5fd0a7 --- /dev/null +++ b/iguana/help/bitcoinrpc_getbestblockhash.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getbestblockhash","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getbestblockhash_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getblock.json b/iguana/help/bitcoinrpc_getblock.json new file mode 100644 index 000000000..2f23841f5 --- /dev/null +++ b/iguana/help/bitcoinrpc_getblock.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getblock","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getblock_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getblockcount.json b/iguana/help/bitcoinrpc_getblockcount.json new file mode 100644 index 000000000..1c1a14959 --- /dev/null +++ b/iguana/help/bitcoinrpc_getblockcount.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getblockcount","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getblockcount_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getblockhash.json b/iguana/help/bitcoinrpc_getblockhash.json new file mode 100644 index 000000000..4c7877840 --- /dev/null +++ b/iguana/help/bitcoinrpc_getblockhash.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getblockhash","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getblockhash_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getdifficulty.json b/iguana/help/bitcoinrpc_getdifficulty.json new file mode 100644 index 000000000..5950fb6f5 --- /dev/null +++ b/iguana/help/bitcoinrpc_getdifficulty.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getdifficulty","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getdifficulty_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getinfo.json b/iguana/help/bitcoinrpc_getinfo.json new file mode 100644 index 000000000..22be35c69 --- /dev/null +++ b/iguana/help/bitcoinrpc_getinfo.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getinfo","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getinfo_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getnewaddress.json b/iguana/help/bitcoinrpc_getnewaddress.json new file mode 100644 index 000000000..3d6875a2a --- /dev/null +++ b/iguana/help/bitcoinrpc_getnewaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getnewaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getnewaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getrawchangeaddress.json b/iguana/help/bitcoinrpc_getrawchangeaddress.json new file mode 100644 index 000000000..3d4128a2f --- /dev/null +++ b/iguana/help/bitcoinrpc_getrawchangeaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getrawchangeaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getrawchangeaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getrawtransaction.json b/iguana/help/bitcoinrpc_getrawtransaction.json new file mode 100644 index 000000000..93c727b87 --- /dev/null +++ b/iguana/help/bitcoinrpc_getrawtransaction.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getrawtransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getrawtransaction_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getreceivedbyaccount.json b/iguana/help/bitcoinrpc_getreceivedbyaccount.json new file mode 100644 index 000000000..defd762d9 --- /dev/null +++ b/iguana/help/bitcoinrpc_getreceivedbyaccount.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getreceivedbyaccount","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getreceivedbyaccount_test.py"}]} diff --git a/iguana/help/bitcoinrpc_getreceivedbyaddress.json b/iguana/help/bitcoinrpc_getreceivedbyaddress.json new file mode 100644 index 000000000..edb272cb7 --- /dev/null +++ b/iguana/help/bitcoinrpc_getreceivedbyaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"getreceivedbyaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_getreceivedbyaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_gettransaction.json b/iguana/help/bitcoinrpc_gettransaction.json new file mode 100644 index 000000000..480f1e86f --- /dev/null +++ b/iguana/help/bitcoinrpc_gettransaction.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"gettransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_gettransaction_test.py"}]} diff --git a/iguana/help/bitcoinrpc_gettxout.json b/iguana/help/bitcoinrpc_gettxout.json new file mode 100644 index 000000000..98324561b --- /dev/null +++ b/iguana/help/bitcoinrpc_gettxout.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"gettxout","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_gettxout_test.py"}]} diff --git a/iguana/help/bitcoinrpc_gettxoutsetinfo.json b/iguana/help/bitcoinrpc_gettxoutsetinfo.json new file mode 100644 index 000000000..3d1926383 --- /dev/null +++ b/iguana/help/bitcoinrpc_gettxoutsetinfo.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"gettxoutsetinfo","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_gettxoutsetinfo_test.py"}]} diff --git a/iguana/help/bitcoinrpc_importaddress.json b/iguana/help/bitcoinrpc_importaddress.json new file mode 100644 index 000000000..37e9c4a0d --- /dev/null +++ b/iguana/help/bitcoinrpc_importaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"importaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_importaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_importprivkey.json b/iguana/help/bitcoinrpc_importprivkey.json new file mode 100644 index 000000000..4efae987e --- /dev/null +++ b/iguana/help/bitcoinrpc_importprivkey.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"importprivkey","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_importprivkey_test.py"}]} diff --git a/iguana/help/bitcoinrpc_importwallet.json b/iguana/help/bitcoinrpc_importwallet.json new file mode 100644 index 000000000..8bf5ce1ae --- /dev/null +++ b/iguana/help/bitcoinrpc_importwallet.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"importwallet","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_importwallet_test.py"}]} diff --git a/iguana/help/bitcoinrpc_listaccounts.json b/iguana/help/bitcoinrpc_listaccounts.json new file mode 100644 index 000000000..635508cf5 --- /dev/null +++ b/iguana/help/bitcoinrpc_listaccounts.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"listaccounts","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_listaccounts_test.py"}]} diff --git a/iguana/help/bitcoinrpc_listaddressgroupings.json b/iguana/help/bitcoinrpc_listaddressgroupings.json new file mode 100644 index 000000000..21f7d8b3e --- /dev/null +++ b/iguana/help/bitcoinrpc_listaddressgroupings.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"listaddressgroupings","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_listaddressgroupings_test.py"}]} diff --git a/iguana/help/bitcoinrpc_listlockunspent.json b/iguana/help/bitcoinrpc_listlockunspent.json new file mode 100644 index 000000000..23ee5ccb9 --- /dev/null +++ b/iguana/help/bitcoinrpc_listlockunspent.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"listlockunspent","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_listlockunspent_test.py"}]} diff --git a/iguana/help/bitcoinrpc_listreceivedbyaccount.json b/iguana/help/bitcoinrpc_listreceivedbyaccount.json new file mode 100644 index 000000000..a7f59f51f --- /dev/null +++ b/iguana/help/bitcoinrpc_listreceivedbyaccount.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"listreceivedbyaccount","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_listreceivedbyaccount_test.py"}]} diff --git a/iguana/help/bitcoinrpc_listreceivedbyaddress.json b/iguana/help/bitcoinrpc_listreceivedbyaddress.json new file mode 100644 index 000000000..6150f1a3b --- /dev/null +++ b/iguana/help/bitcoinrpc_listreceivedbyaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"listreceivedbyaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_listreceivedbyaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_listsinceblock.json b/iguana/help/bitcoinrpc_listsinceblock.json new file mode 100644 index 000000000..66beb661a --- /dev/null +++ b/iguana/help/bitcoinrpc_listsinceblock.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"listsinceblock","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_listsinceblock_test.py"}]} diff --git a/iguana/help/bitcoinrpc_listtransactions.json b/iguana/help/bitcoinrpc_listtransactions.json new file mode 100644 index 000000000..ddb55511c --- /dev/null +++ b/iguana/help/bitcoinrpc_listtransactions.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"listtransactions","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_listtransactions_test.py"}]} diff --git a/iguana/help/bitcoinrpc_listunspent.json b/iguana/help/bitcoinrpc_listunspent.json new file mode 100644 index 000000000..0c11033b4 --- /dev/null +++ b/iguana/help/bitcoinrpc_listunspent.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"listunspent","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_listunspent_test.py"}]} diff --git a/iguana/help/bitcoinrpc_lockunspent.json b/iguana/help/bitcoinrpc_lockunspent.json new file mode 100644 index 000000000..61c9d7db8 --- /dev/null +++ b/iguana/help/bitcoinrpc_lockunspent.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"lockunspent","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_lockunspent_test.py"}]} diff --git a/iguana/help/bitcoinrpc_move.json b/iguana/help/bitcoinrpc_move.json new file mode 100644 index 000000000..b96af5b84 --- /dev/null +++ b/iguana/help/bitcoinrpc_move.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"move","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_move_test.py"}]} diff --git a/iguana/help/bitcoinrpc_repairwallet.json b/iguana/help/bitcoinrpc_repairwallet.json new file mode 100644 index 000000000..4b6f7f080 --- /dev/null +++ b/iguana/help/bitcoinrpc_repairwallet.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"repairwallet","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_repairwallet_test.py"}]} diff --git a/iguana/help/bitcoinrpc_sendfrom.json b/iguana/help/bitcoinrpc_sendfrom.json new file mode 100644 index 000000000..6cec10d79 --- /dev/null +++ b/iguana/help/bitcoinrpc_sendfrom.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"sendfrom","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_sendfrom_test.py"}]} diff --git a/iguana/help/bitcoinrpc_sendmany.json b/iguana/help/bitcoinrpc_sendmany.json new file mode 100644 index 000000000..5115347f4 --- /dev/null +++ b/iguana/help/bitcoinrpc_sendmany.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"sendmany","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_sendmany_test.py"}]} diff --git a/iguana/help/bitcoinrpc_sendrawtransaction.json b/iguana/help/bitcoinrpc_sendrawtransaction.json new file mode 100644 index 000000000..fa9c4182f --- /dev/null +++ b/iguana/help/bitcoinrpc_sendrawtransaction.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"sendrawtransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_sendrawtransaction_test.py"}]} diff --git a/iguana/help/bitcoinrpc_sendtoaddress.json b/iguana/help/bitcoinrpc_sendtoaddress.json new file mode 100644 index 000000000..0553170c9 --- /dev/null +++ b/iguana/help/bitcoinrpc_sendtoaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"sendtoaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_sendtoaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_setaccount.json b/iguana/help/bitcoinrpc_setaccount.json new file mode 100644 index 000000000..e73220bf2 --- /dev/null +++ b/iguana/help/bitcoinrpc_setaccount.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"setaccount","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_setaccount_test.py"}]} diff --git a/iguana/help/bitcoinrpc_settxfee.json b/iguana/help/bitcoinrpc_settxfee.json new file mode 100644 index 000000000..d3cc05812 --- /dev/null +++ b/iguana/help/bitcoinrpc_settxfee.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"settxfee","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_settxfee_test.py"}]} diff --git a/iguana/help/bitcoinrpc_signmessage.json b/iguana/help/bitcoinrpc_signmessage.json new file mode 100644 index 000000000..c5e335545 --- /dev/null +++ b/iguana/help/bitcoinrpc_signmessage.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"signmessage","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_signmessage_test.py"}]} diff --git a/iguana/help/bitcoinrpc_signrawtransaction.json b/iguana/help/bitcoinrpc_signrawtransaction.json new file mode 100644 index 000000000..5f693247a --- /dev/null +++ b/iguana/help/bitcoinrpc_signrawtransaction.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"signrawtransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_signrawtransaction_test.py"}]} diff --git a/iguana/help/bitcoinrpc_submitblock.json b/iguana/help/bitcoinrpc_submitblock.json new file mode 100644 index 000000000..03e5c711e --- /dev/null +++ b/iguana/help/bitcoinrpc_submitblock.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"submitblock","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_submitblock_test.py"}]} diff --git a/iguana/help/bitcoinrpc_validateaddress.json b/iguana/help/bitcoinrpc_validateaddress.json new file mode 100644 index 000000000..2226a7767 --- /dev/null +++ b/iguana/help/bitcoinrpc_validateaddress.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"validateaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_validateaddress_test.py"}]} diff --git a/iguana/help/bitcoinrpc_validatepubkey.json b/iguana/help/bitcoinrpc_validatepubkey.json new file mode 100644 index 000000000..bfd1d8c5b --- /dev/null +++ b/iguana/help/bitcoinrpc_validatepubkey.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"validatepubkey","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_validatepubkey_test.py"}]} diff --git a/iguana/help/bitcoinrpc_validaterawtransaction.json b/iguana/help/bitcoinrpc_validaterawtransaction.json new file mode 100644 index 000000000..ffcec8df8 --- /dev/null +++ b/iguana/help/bitcoinrpc_validaterawtransaction.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"validaterawtransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_validaterawtransaction_test.py"}]} diff --git a/iguana/help/bitcoinrpc_verifymessage.json b/iguana/help/bitcoinrpc_verifymessage.json new file mode 100644 index 000000000..9cc4a7ee7 --- /dev/null +++ b/iguana/help/bitcoinrpc_verifymessage.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"verifymessage","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_verifymessage_test.py"}]} diff --git a/iguana/help/bitcoinrpc_walletlock.json b/iguana/help/bitcoinrpc_walletlock.json new file mode 100644 index 000000000..d3375ba94 --- /dev/null +++ b/iguana/help/bitcoinrpc_walletlock.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"walletlock","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_walletlock_test.py"}]} diff --git a/iguana/help/bitcoinrpc_walletpassphrase.json b/iguana/help/bitcoinrpc_walletpassphrase.json new file mode 100644 index 000000000..e196e4171 --- /dev/null +++ b/iguana/help/bitcoinrpc_walletpassphrase.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"walletpassphrase","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_walletpassphrase_test.py"}]} diff --git a/iguana/help/bitcoinrpc_walletpassphrasechange.json b/iguana/help/bitcoinrpc_walletpassphrasechange.json new file mode 100644 index 000000000..c18bc1a12 --- /dev/null +++ b/iguana/help/bitcoinrpc_walletpassphrasechange.json @@ -0,0 +1 @@ +{"agent":"bitcoinrpc","method":"walletpassphrasechange","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"bitcoinrpc_walletpassphrasechange_test.py"}]} diff --git a/iguana/help/dex_alladdresses.json b/iguana/help/dex_alladdresses.json new file mode 100644 index 000000000..71b30968d --- /dev/null +++ b/iguana/help/dex_alladdresses.json @@ -0,0 +1 @@ +{"agent":"dex","method":"alladdresses","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_alladdresses_test.py"}]} diff --git a/iguana/help/dex_checkaddress.json b/iguana/help/dex_checkaddress.json new file mode 100644 index 000000000..c651f71f9 --- /dev/null +++ b/iguana/help/dex_checkaddress.json @@ -0,0 +1 @@ +{"agent":"dex","method":"checkaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_checkaddress_test.py"}]} diff --git a/iguana/help/dex_explorer.json b/iguana/help/dex_explorer.json new file mode 100644 index 000000000..f48b9eb44 --- /dev/null +++ b/iguana/help/dex_explorer.json @@ -0,0 +1 @@ +{"agent":"dex","method":"explorer","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_explorer_test.py"}]} diff --git a/iguana/help/dex_getbalance.json b/iguana/help/dex_getbalance.json new file mode 100644 index 000000000..39c086891 --- /dev/null +++ b/iguana/help/dex_getbalance.json @@ -0,0 +1 @@ +{"agent":"dex","method":"getbalance","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_getbalance_test.py"}]} diff --git a/iguana/help/dex_getbestblockhash.json b/iguana/help/dex_getbestblockhash.json new file mode 100644 index 000000000..ab3625a38 --- /dev/null +++ b/iguana/help/dex_getbestblockhash.json @@ -0,0 +1 @@ +{"agent":"dex","method":"getbestblockhash","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_getbestblockhash_test.py"}]} diff --git a/iguana/help/dex_getblock.json b/iguana/help/dex_getblock.json new file mode 100644 index 000000000..9f74e1ba6 --- /dev/null +++ b/iguana/help/dex_getblock.json @@ -0,0 +1 @@ +{"agent":"dex","method":"getblock","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_getblock_test.py"}]} diff --git a/iguana/help/dex_getblockhash.json b/iguana/help/dex_getblockhash.json new file mode 100644 index 000000000..87fbff94d --- /dev/null +++ b/iguana/help/dex_getblockhash.json @@ -0,0 +1 @@ +{"agent":"dex","method":"getblockhash","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_getblockhash_test.py"}]} diff --git a/iguana/help/dex_getinfo.json b/iguana/help/dex_getinfo.json new file mode 100644 index 000000000..89b6f79fa --- /dev/null +++ b/iguana/help/dex_getinfo.json @@ -0,0 +1 @@ +{"agent":"dex","method":"getinfo","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_getinfo_test.py"}]} diff --git a/iguana/help/dex_getmessage.json b/iguana/help/dex_getmessage.json new file mode 100644 index 000000000..4b0aa5d4e --- /dev/null +++ b/iguana/help/dex_getmessage.json @@ -0,0 +1 @@ +{"agent":"dex","method":"getmessage","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_getmessage_test.py"}]} diff --git a/iguana/help/dex_getnotaries.json b/iguana/help/dex_getnotaries.json new file mode 100644 index 000000000..b3280498e --- /dev/null +++ b/iguana/help/dex_getnotaries.json @@ -0,0 +1 @@ +{"agent":"dex","method":"getnotaries","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_getnotaries_test.py"}]} diff --git a/iguana/help/dex_gettransaction.json b/iguana/help/dex_gettransaction.json new file mode 100644 index 000000000..4b3df0094 --- /dev/null +++ b/iguana/help/dex_gettransaction.json @@ -0,0 +1 @@ +{"agent":"dex","method":"gettransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_gettransaction_test.py"}]} diff --git a/iguana/help/dex_gettxin.json b/iguana/help/dex_gettxin.json new file mode 100644 index 000000000..868ffd753 --- /dev/null +++ b/iguana/help/dex_gettxin.json @@ -0,0 +1 @@ +{"agent":"dex","method":"gettxin","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_gettxin_test.py"}]} diff --git a/iguana/help/dex_gettxout.json b/iguana/help/dex_gettxout.json new file mode 100644 index 000000000..13169702d --- /dev/null +++ b/iguana/help/dex_gettxout.json @@ -0,0 +1 @@ +{"agent":"dex","method":"gettxout","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_gettxout_test.py"}]} diff --git a/iguana/help/dex_importaddress.json b/iguana/help/dex_importaddress.json new file mode 100644 index 000000000..c0961635f --- /dev/null +++ b/iguana/help/dex_importaddress.json @@ -0,0 +1 @@ +{"agent":"dex","method":"importaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_importaddress_test.py"}]} diff --git a/iguana/help/dex_kvsearch.json b/iguana/help/dex_kvsearch.json new file mode 100644 index 000000000..3b3f22ac5 --- /dev/null +++ b/iguana/help/dex_kvsearch.json @@ -0,0 +1 @@ +{"agent":"dex","method":"kvsearch","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_kvsearch_test.py"}]} diff --git a/iguana/help/dex_kvupdate.json b/iguana/help/dex_kvupdate.json new file mode 100644 index 000000000..8303eaad1 --- /dev/null +++ b/iguana/help/dex_kvupdate.json @@ -0,0 +1 @@ +{"agent":"dex","method":"kvupdate","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_kvupdate_test.py"}]} diff --git a/iguana/help/dex_listspent.json b/iguana/help/dex_listspent.json new file mode 100644 index 000000000..22767b773 --- /dev/null +++ b/iguana/help/dex_listspent.json @@ -0,0 +1 @@ +{"agent":"dex","method":"listspent","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_listspent_test.py"}]} diff --git a/iguana/help/dex_listtransactions.json b/iguana/help/dex_listtransactions.json new file mode 100644 index 000000000..be95c75ff --- /dev/null +++ b/iguana/help/dex_listtransactions.json @@ -0,0 +1 @@ +{"agent":"dex","method":"listtransactions","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_listtransactions_test.py"}]} diff --git a/iguana/help/dex_listtransactions2.json b/iguana/help/dex_listtransactions2.json new file mode 100644 index 000000000..234b9b8df --- /dev/null +++ b/iguana/help/dex_listtransactions2.json @@ -0,0 +1 @@ +{"agent":"dex","method":"listtransactions2","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_listtransactions2_test.py"}]} diff --git a/iguana/help/dex_listunspent.json b/iguana/help/dex_listunspent.json new file mode 100644 index 000000000..0f50ca06e --- /dev/null +++ b/iguana/help/dex_listunspent.json @@ -0,0 +1 @@ +{"agent":"dex","method":"listunspent","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_listunspent_test.py"}]} diff --git a/iguana/help/dex_listunspent2.json b/iguana/help/dex_listunspent2.json new file mode 100644 index 000000000..9ccc2a1e4 --- /dev/null +++ b/iguana/help/dex_listunspent2.json @@ -0,0 +1 @@ +{"agent":"dex","method":"listunspent2","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_listunspent2_test.py"}]} diff --git a/iguana/help/dex_psock.json b/iguana/help/dex_psock.json new file mode 100644 index 000000000..74a3a8dfa --- /dev/null +++ b/iguana/help/dex_psock.json @@ -0,0 +1 @@ +{"agent":"dex","method":"psock","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_psock_test.py"}]} diff --git a/iguana/help/dex_send.json b/iguana/help/dex_send.json new file mode 100644 index 000000000..ccd3cc2bd --- /dev/null +++ b/iguana/help/dex_send.json @@ -0,0 +1 @@ +{"agent":"dex","method":"send","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_send_test.py"}]} diff --git a/iguana/help/dex_sendrawtransaction.json b/iguana/help/dex_sendrawtransaction.json new file mode 100644 index 000000000..20261d219 --- /dev/null +++ b/iguana/help/dex_sendrawtransaction.json @@ -0,0 +1 @@ +{"agent":"dex","method":"sendrawtransaction","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_sendrawtransaction_test.py"}]} diff --git a/iguana/help/dex_validateaddress.json b/iguana/help/dex_validateaddress.json new file mode 100644 index 000000000..7387dc024 --- /dev/null +++ b/iguana/help/dex_validateaddress.json @@ -0,0 +1 @@ +{"agent":"dex","method":"validateaddress","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dex_validateaddress_test.py"}]} diff --git a/iguana/help/dpow_active.json b/iguana/help/dpow_active.json new file mode 100644 index 000000000..b639a3ada --- /dev/null +++ b/iguana/help/dpow_active.json @@ -0,0 +1 @@ +{"agent":"dpow","method":"active","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dpow_active_test.py"}]} diff --git a/iguana/help/dpow_bindaddr.json b/iguana/help/dpow_bindaddr.json new file mode 100644 index 000000000..65f0052f7 --- /dev/null +++ b/iguana/help/dpow_bindaddr.json @@ -0,0 +1 @@ +{"agent":"dpow","method":"bindaddr","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dpow_bindaddr_test.py"}]} diff --git a/iguana/help/dpow_cancelratify.json b/iguana/help/dpow_cancelratify.json new file mode 100644 index 000000000..33a872463 --- /dev/null +++ b/iguana/help/dpow_cancelratify.json @@ -0,0 +1 @@ +{"agent":"dpow","method":"cancelratify","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dpow_cancelratify_test.py"}]} diff --git a/iguana/help/dpow_fundnotaries.json b/iguana/help/dpow_fundnotaries.json new file mode 100644 index 000000000..4e2854714 --- /dev/null +++ b/iguana/help/dpow_fundnotaries.json @@ -0,0 +1 @@ +{"agent":"dpow","method":"fundnotaries","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dpow_fundnotaries_test.py"}]} diff --git a/iguana/help/dpow_notarychains.json b/iguana/help/dpow_notarychains.json new file mode 100644 index 000000000..daee37348 --- /dev/null +++ b/iguana/help/dpow_notarychains.json @@ -0,0 +1 @@ +{"agent":"dpow","method":"notarychains","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dpow_notarychains_test.py"}]} diff --git a/iguana/help/dpow_pending.json b/iguana/help/dpow_pending.json new file mode 100644 index 000000000..1a524af58 --- /dev/null +++ b/iguana/help/dpow_pending.json @@ -0,0 +1 @@ +{"agent":"dpow","method":"pending","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dpow_pending_test.py"}]} diff --git a/iguana/help/dpow_ratify.json b/iguana/help/dpow_ratify.json new file mode 100644 index 000000000..c449a8888 --- /dev/null +++ b/iguana/help/dpow_ratify.json @@ -0,0 +1 @@ +{"agent":"dpow","method":"ratify","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"dpow_ratify_test.py"}]} diff --git a/iguana/help/hash_NXT.json b/iguana/help/hash_NXT.json new file mode 100644 index 000000000..85fae7d76 --- /dev/null +++ b/iguana/help/hash_NXT.json @@ -0,0 +1 @@ +{"agent":"hash","method":"NXT","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_NXT_test.py"}]} diff --git a/iguana/help/hash_base64_decode.json b/iguana/help/hash_base64_decode.json new file mode 100644 index 000000000..eadde2571 --- /dev/null +++ b/iguana/help/hash_base64_decode.json @@ -0,0 +1 @@ +{"agent":"hash","method":"base64_decode","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_base64_decode_test.py"}]} diff --git a/iguana/help/hash_base64_encode.json b/iguana/help/hash_base64_encode.json new file mode 100644 index 000000000..171e50200 --- /dev/null +++ b/iguana/help/hash_base64_encode.json @@ -0,0 +1 @@ +{"agent":"hash","method":"base64_encode","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_base64_encode_test.py"}]} diff --git a/iguana/help/hash_crc32.json b/iguana/help/hash_crc32.json new file mode 100644 index 000000000..3891c7bdf --- /dev/null +++ b/iguana/help/hash_crc32.json @@ -0,0 +1 @@ +{"agent":"hash","method":"crc32","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_crc32_test.py"}]} diff --git a/iguana/help/hash_curve25519.json b/iguana/help/hash_curve25519.json new file mode 100644 index 000000000..c9205f92b --- /dev/null +++ b/iguana/help/hash_curve25519.json @@ -0,0 +1 @@ +{"agent":"hash","method":"curve25519","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_curve25519_test.py"}]} diff --git a/iguana/help/hash_curve25519_pair.json b/iguana/help/hash_curve25519_pair.json new file mode 100644 index 000000000..f1e183ead --- /dev/null +++ b/iguana/help/hash_curve25519_pair.json @@ -0,0 +1 @@ +{"agent":"hash","method":"curve25519_pair","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_curve25519_pair_test.py"}]} diff --git a/iguana/help/hash_hex.json b/iguana/help/hash_hex.json new file mode 100644 index 000000000..467d9579b --- /dev/null +++ b/iguana/help/hash_hex.json @@ -0,0 +1 @@ +{"agent":"hash","method":"hex","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_hex_test.py"}]} diff --git a/iguana/help/hash_md2.json b/iguana/help/hash_md2.json new file mode 100644 index 000000000..995e6bb7f --- /dev/null +++ b/iguana/help/hash_md2.json @@ -0,0 +1 @@ +{"agent":"hash","method":"md2","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_md2_test.py"}]} diff --git a/iguana/help/hash_md4.json b/iguana/help/hash_md4.json new file mode 100644 index 000000000..696b4a22b --- /dev/null +++ b/iguana/help/hash_md4.json @@ -0,0 +1 @@ +{"agent":"hash","method":"md4","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_md4_test.py"}]} diff --git a/iguana/help/hash_md5.json b/iguana/help/hash_md5.json new file mode 100644 index 000000000..cd50b763a --- /dev/null +++ b/iguana/help/hash_md5.json @@ -0,0 +1 @@ +{"agent":"hash","method":"md5","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_md5_test.py"}]} diff --git a/iguana/help/hash_rmd128.json b/iguana/help/hash_rmd128.json new file mode 100644 index 000000000..c1fe35027 --- /dev/null +++ b/iguana/help/hash_rmd128.json @@ -0,0 +1 @@ +{"agent":"hash","method":"rmd128","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_rmd128_test.py"}]} diff --git a/iguana/help/hash_rmd160.json b/iguana/help/hash_rmd160.json new file mode 100644 index 000000000..448febe13 --- /dev/null +++ b/iguana/help/hash_rmd160.json @@ -0,0 +1 @@ +{"agent":"hash","method":"rmd160","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_rmd160_test.py"}]} diff --git a/iguana/help/hash_rmd160_sha256.json b/iguana/help/hash_rmd160_sha256.json new file mode 100644 index 000000000..d20a37caa --- /dev/null +++ b/iguana/help/hash_rmd160_sha256.json @@ -0,0 +1 @@ +{"agent":"hash","method":"rmd160_sha256","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_rmd160_sha256_test.py"}]} diff --git a/iguana/help/hash_rmd256.json b/iguana/help/hash_rmd256.json new file mode 100644 index 000000000..7b5476766 --- /dev/null +++ b/iguana/help/hash_rmd256.json @@ -0,0 +1 @@ +{"agent":"hash","method":"rmd256","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_rmd256_test.py"}]} diff --git a/iguana/help/hash_rmd320.json b/iguana/help/hash_rmd320.json new file mode 100644 index 000000000..d710f49d8 --- /dev/null +++ b/iguana/help/hash_rmd320.json @@ -0,0 +1 @@ +{"agent":"hash","method":"rmd320","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_rmd320_test.py"}]} diff --git a/iguana/help/hash_sha1.json b/iguana/help/hash_sha1.json new file mode 100644 index 000000000..03a4fe9a3 --- /dev/null +++ b/iguana/help/hash_sha1.json @@ -0,0 +1 @@ +{"agent":"hash","method":"sha1","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_sha1_test.py"}]} diff --git a/iguana/help/hash_sha224.json b/iguana/help/hash_sha224.json new file mode 100644 index 000000000..a3b3f0840 --- /dev/null +++ b/iguana/help/hash_sha224.json @@ -0,0 +1 @@ +{"agent":"hash","method":"sha224","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_sha224_test.py"}]} diff --git a/iguana/help/hash_sha256.json b/iguana/help/hash_sha256.json new file mode 100644 index 000000000..f7350d129 --- /dev/null +++ b/iguana/help/hash_sha256.json @@ -0,0 +1 @@ +{"agent":"hash","method":"sha256","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_sha256_test.py"}]} diff --git a/iguana/help/hash_sha256_sha256.json b/iguana/help/hash_sha256_sha256.json new file mode 100644 index 000000000..7f750db03 --- /dev/null +++ b/iguana/help/hash_sha256_sha256.json @@ -0,0 +1 @@ +{"agent":"hash","method":"sha256_sha256","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_sha256_sha256_test.py"}]} diff --git a/iguana/help/hash_sha384.json b/iguana/help/hash_sha384.json new file mode 100644 index 000000000..9c3a29487 --- /dev/null +++ b/iguana/help/hash_sha384.json @@ -0,0 +1 @@ +{"agent":"hash","method":"sha384","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_sha384_test.py"}]} diff --git a/iguana/help/hash_sha512.json b/iguana/help/hash_sha512.json new file mode 100644 index 000000000..1b43f3a27 --- /dev/null +++ b/iguana/help/hash_sha512.json @@ -0,0 +1 @@ +{"agent":"hash","method":"sha512","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_sha512_test.py"}]} diff --git a/iguana/help/hash_tiger192_3.json b/iguana/help/hash_tiger192_3.json new file mode 100644 index 000000000..e48f284fb --- /dev/null +++ b/iguana/help/hash_tiger192_3.json @@ -0,0 +1 @@ +{"agent":"hash","method":"tiger192_3","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_tiger192_3_test.py"}]} diff --git a/iguana/help/hash_unhex.json b/iguana/help/hash_unhex.json new file mode 100644 index 000000000..860f3c3c8 --- /dev/null +++ b/iguana/help/hash_unhex.json @@ -0,0 +1 @@ +{"agent":"hash","method":"unhex","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_unhex_test.py"}]} diff --git a/iguana/help/hash_whirlpool.json b/iguana/help/hash_whirlpool.json new file mode 100644 index 000000000..6c84f55b0 --- /dev/null +++ b/iguana/help/hash_whirlpool.json @@ -0,0 +1 @@ +{"agent":"hash","method":"whirlpool","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hash_whirlpool_test.py"}]} diff --git a/iguana/help/hmac_md2.json b/iguana/help/hmac_md2.json new file mode 100644 index 000000000..3a39c448b --- /dev/null +++ b/iguana/help/hmac_md2.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"md2","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_md2_test.py"}]} diff --git a/iguana/help/hmac_md4.json b/iguana/help/hmac_md4.json new file mode 100644 index 000000000..fdb646593 --- /dev/null +++ b/iguana/help/hmac_md4.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"md4","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_md4_test.py"}]} diff --git a/iguana/help/hmac_md5.json b/iguana/help/hmac_md5.json new file mode 100644 index 000000000..cd9021def --- /dev/null +++ b/iguana/help/hmac_md5.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"md5","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_md5_test.py"}]} diff --git a/iguana/help/hmac_rmd128.json b/iguana/help/hmac_rmd128.json new file mode 100644 index 000000000..a5c10722b --- /dev/null +++ b/iguana/help/hmac_rmd128.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"rmd128","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_rmd128_test.py"}]} diff --git a/iguana/help/hmac_rmd160.json b/iguana/help/hmac_rmd160.json new file mode 100644 index 000000000..114d560d9 --- /dev/null +++ b/iguana/help/hmac_rmd160.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"rmd160","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_rmd160_test.py"}]} diff --git a/iguana/help/hmac_rmd256.json b/iguana/help/hmac_rmd256.json new file mode 100644 index 000000000..836887c38 --- /dev/null +++ b/iguana/help/hmac_rmd256.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"rmd256","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_rmd256_test.py"}]} diff --git a/iguana/help/hmac_rmd320.json b/iguana/help/hmac_rmd320.json new file mode 100644 index 000000000..a7f0a94f8 --- /dev/null +++ b/iguana/help/hmac_rmd320.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"rmd320","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_rmd320_test.py"}]} diff --git a/iguana/help/hmac_sha1.json b/iguana/help/hmac_sha1.json new file mode 100644 index 000000000..beef6ef79 --- /dev/null +++ b/iguana/help/hmac_sha1.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"sha1","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_sha1_test.py"}]} diff --git a/iguana/help/hmac_sha224.json b/iguana/help/hmac_sha224.json new file mode 100644 index 000000000..e665184e1 --- /dev/null +++ b/iguana/help/hmac_sha224.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"sha224","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_sha224_test.py"}]} diff --git a/iguana/help/hmac_sha256.json b/iguana/help/hmac_sha256.json new file mode 100644 index 000000000..ae082aa6d --- /dev/null +++ b/iguana/help/hmac_sha256.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"sha256","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_sha256_test.py"}]} diff --git a/iguana/help/hmac_sha384.json b/iguana/help/hmac_sha384.json new file mode 100644 index 000000000..cadfef49d --- /dev/null +++ b/iguana/help/hmac_sha384.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"sha384","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_sha384_test.py"}]} diff --git a/iguana/help/hmac_sha512.json b/iguana/help/hmac_sha512.json new file mode 100644 index 000000000..c2aed013b --- /dev/null +++ b/iguana/help/hmac_sha512.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"sha512","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_sha512_test.py"}]} diff --git a/iguana/help/hmac_tiger192_3.json b/iguana/help/hmac_tiger192_3.json new file mode 100644 index 000000000..c7b776d69 --- /dev/null +++ b/iguana/help/hmac_tiger192_3.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"tiger192_3","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_tiger192_3_test.py"}]} diff --git a/iguana/help/hmac_whirlpool.json b/iguana/help/hmac_whirlpool.json new file mode 100644 index 000000000..b85e3940e --- /dev/null +++ b/iguana/help/hmac_whirlpool.json @@ -0,0 +1 @@ +{"agent":"hmac","method":"whirlpool","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"hmac_whirlpool_test.py"}]} diff --git a/iguana/help/iguana_PoSweights.json b/iguana/help/iguana_PoSweights.json new file mode 100644 index 000000000..d5597f13c --- /dev/null +++ b/iguana/help/iguana_PoSweights.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"PoSweights","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_PoSweights_test.py"}]} diff --git a/iguana/help/iguana_addcoin.json b/iguana/help/iguana_addcoin.json new file mode 100644 index 000000000..0bfaaf6de --- /dev/null +++ b/iguana/help/iguana_addcoin.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"addcoin","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_addcoin_test.py"}]} diff --git a/iguana/help/iguana_addnode.json b/iguana/help/iguana_addnode.json new file mode 100644 index 000000000..1dcf66ce8 --- /dev/null +++ b/iguana/help/iguana_addnode.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"addnode","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_addnode_test.py"}]} diff --git a/iguana/help/iguana_addnotary.json b/iguana/help/iguana_addnotary.json new file mode 100644 index 000000000..c57b97435 --- /dev/null +++ b/iguana/help/iguana_addnotary.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"addnotary","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_addnotary_test.py"}]} diff --git a/iguana/help/iguana_balance.json b/iguana/help/iguana_balance.json new file mode 100644 index 000000000..b84a65f42 --- /dev/null +++ b/iguana/help/iguana_balance.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"balance","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_balance_test.py"}]} diff --git a/iguana/help/iguana_bundleaddresses.json b/iguana/help/iguana_bundleaddresses.json new file mode 100644 index 000000000..f80caee90 --- /dev/null +++ b/iguana/help/iguana_bundleaddresses.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"bundleaddresses","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_bundleaddresses_test.py"}]} diff --git a/iguana/help/iguana_bundlehashes.json b/iguana/help/iguana_bundlehashes.json new file mode 100644 index 000000000..2eddf7a38 --- /dev/null +++ b/iguana/help/iguana_bundlehashes.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"bundlehashes","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_bundlehashes_test.py"}]} diff --git a/iguana/help/iguana_dividends.json b/iguana/help/iguana_dividends.json new file mode 100644 index 000000000..222489389 --- /dev/null +++ b/iguana/help/iguana_dividends.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"dividends","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_dividends_test.py"}]} diff --git a/iguana/help/iguana_dpow.json b/iguana/help/iguana_dpow.json new file mode 100644 index 000000000..6e54c8629 --- /dev/null +++ b/iguana/help/iguana_dpow.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"dpow","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_dpow_test.py"}]} diff --git a/iguana/help/iguana_getconnectioncount.json b/iguana/help/iguana_getconnectioncount.json new file mode 100644 index 000000000..4b3ee5ad7 --- /dev/null +++ b/iguana/help/iguana_getconnectioncount.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"getconnectioncount","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_getconnectioncount_test.py"}]} diff --git a/iguana/help/iguana_initfastfind.json b/iguana/help/iguana_initfastfind.json new file mode 100644 index 000000000..1de530d85 --- /dev/null +++ b/iguana/help/iguana_initfastfind.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"initfastfind","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_initfastfind_test.py"}]} diff --git a/iguana/help/iguana_makekeypair.json b/iguana/help/iguana_makekeypair.json new file mode 100644 index 000000000..1d70e412e --- /dev/null +++ b/iguana/help/iguana_makekeypair.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"makekeypair","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_makekeypair_test.py"}]} diff --git a/iguana/help/iguana_maxpeers.json b/iguana/help/iguana_maxpeers.json new file mode 100644 index 000000000..0f67ebfe4 --- /dev/null +++ b/iguana/help/iguana_maxpeers.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"maxpeers","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_maxpeers_test.py"}]} diff --git a/iguana/help/iguana_nodestatus.json b/iguana/help/iguana_nodestatus.json new file mode 100644 index 000000000..e3937827a --- /dev/null +++ b/iguana/help/iguana_nodestatus.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"nodestatus","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_nodestatus_test.py"}]} diff --git a/iguana/help/iguana_oneshot.json b/iguana/help/iguana_oneshot.json new file mode 100644 index 000000000..5157a0be7 --- /dev/null +++ b/iguana/help/iguana_oneshot.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"oneshot","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_oneshot_test.py"}]} diff --git a/iguana/help/iguana_passthru.json b/iguana/help/iguana_passthru.json new file mode 100644 index 000000000..a7203ba08 --- /dev/null +++ b/iguana/help/iguana_passthru.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"passthru","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_passthru_test.py"}]} diff --git a/iguana/help/iguana_pausecoin.json b/iguana/help/iguana_pausecoin.json new file mode 100644 index 000000000..ada16880b --- /dev/null +++ b/iguana/help/iguana_pausecoin.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"pausecoin","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_pausecoin_test.py"}]} diff --git a/iguana/help/iguana_peers.json b/iguana/help/iguana_peers.json new file mode 100644 index 000000000..75a498b7e --- /dev/null +++ b/iguana/help/iguana_peers.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"peers","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_peers_test.py"}]} diff --git a/iguana/help/iguana_persistent.json b/iguana/help/iguana_persistent.json new file mode 100644 index 000000000..14953397f --- /dev/null +++ b/iguana/help/iguana_persistent.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"persistent","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_persistent_test.py"}]} diff --git a/iguana/help/iguana_prices.json b/iguana/help/iguana_prices.json new file mode 100644 index 000000000..a1b02f625 --- /dev/null +++ b/iguana/help/iguana_prices.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"prices","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_prices_test.py"}]} diff --git a/iguana/help/iguana_rate.json b/iguana/help/iguana_rate.json new file mode 100644 index 000000000..94cfec4ab --- /dev/null +++ b/iguana/help/iguana_rate.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"rate","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_rate_test.py"}]} diff --git a/iguana/help/iguana_rates.json b/iguana/help/iguana_rates.json new file mode 100644 index 000000000..678f86b90 --- /dev/null +++ b/iguana/help/iguana_rates.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"rates","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_rates_test.py"}]} diff --git a/iguana/help/iguana_removecoin.json b/iguana/help/iguana_removecoin.json new file mode 100644 index 000000000..e33676b7f --- /dev/null +++ b/iguana/help/iguana_removecoin.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"removecoin","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_removecoin_test.py"}]} diff --git a/iguana/help/iguana_removenode.json b/iguana/help/iguana_removenode.json new file mode 100644 index 000000000..9af62606d --- /dev/null +++ b/iguana/help/iguana_removenode.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"removenode","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_removenode_test.py"}]} diff --git a/iguana/help/iguana_snapshot.json b/iguana/help/iguana_snapshot.json new file mode 100644 index 000000000..c5bd5c3c9 --- /dev/null +++ b/iguana/help/iguana_snapshot.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"snapshot","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_snapshot_test.py"}]} diff --git a/iguana/help/iguana_spendmsig.json b/iguana/help/iguana_spendmsig.json new file mode 100644 index 000000000..7e987d790 --- /dev/null +++ b/iguana/help/iguana_spendmsig.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"spendmsig","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_spendmsig_test.py"}]} diff --git a/iguana/help/iguana_splitfunds.json b/iguana/help/iguana_splitfunds.json new file mode 100644 index 000000000..bdea50ac5 --- /dev/null +++ b/iguana/help/iguana_splitfunds.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"splitfunds","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_splitfunds_test.py"}]} diff --git a/iguana/help/iguana_stakers.json b/iguana/help/iguana_stakers.json new file mode 100644 index 000000000..8fb613dd6 --- /dev/null +++ b/iguana/help/iguana_stakers.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"stakers","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_stakers_test.py"}]} diff --git a/iguana/help/iguana_startcoin.json b/iguana/help/iguana_startcoin.json new file mode 100644 index 000000000..b0a52eaf7 --- /dev/null +++ b/iguana/help/iguana_startcoin.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"startcoin","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_startcoin_test.py"}]} diff --git a/iguana/help/iguana_stopcoin.json b/iguana/help/iguana_stopcoin.json new file mode 100644 index 000000000..802470c20 --- /dev/null +++ b/iguana/help/iguana_stopcoin.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"stopcoin","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_stopcoin_test.py"}]} diff --git a/iguana/help/iguana_validate.json b/iguana/help/iguana_validate.json new file mode 100644 index 000000000..555ed8534 --- /dev/null +++ b/iguana/help/iguana_validate.json @@ -0,0 +1 @@ +{"agent":"iguana","method":"validate","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"iguana_validate_test.py"}]} diff --git a/iguana/help/jumblr_runsilent.json b/iguana/help/jumblr_runsilent.json new file mode 100644 index 000000000..071654a08 --- /dev/null +++ b/iguana/help/jumblr_runsilent.json @@ -0,0 +1 @@ +{"agent":"jumblr","method":"runsilent","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"jumblr_runsilent_test.py"}]} diff --git a/iguana/help/jumblr_setpassphrase.json b/iguana/help/jumblr_setpassphrase.json new file mode 100644 index 000000000..abb67bed0 --- /dev/null +++ b/iguana/help/jumblr_setpassphrase.json @@ -0,0 +1 @@ +{"agent":"jumblr","method":"setpassphrase","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"jumblr_setpassphrase_test.py"}]} diff --git a/iguana/help/jumblr_status.json b/iguana/help/jumblr_status.json new file mode 100644 index 000000000..a245ba5db --- /dev/null +++ b/iguana/help/jumblr_status.json @@ -0,0 +1 @@ +{"agent":"jumblr","method":"status","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"jumblr_status_test.py"}]} diff --git a/iguana/help/jumblr_totransparent.json b/iguana/help/jumblr_totransparent.json new file mode 100644 index 000000000..22d1f678d --- /dev/null +++ b/iguana/help/jumblr_totransparent.json @@ -0,0 +1 @@ +{"agent":"jumblr","method":"totransparent","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"jumblr_totransparent_test.py"}]} diff --git a/iguana/help/keyboard_key.json b/iguana/help/keyboard_key.json new file mode 100644 index 000000000..941a0517f --- /dev/null +++ b/iguana/help/keyboard_key.json @@ -0,0 +1 @@ +{"agent":"keyboard","method":"key","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"keyboard_key_test.py"}]} diff --git a/iguana/help/komodo_passthru.json b/iguana/help/komodo_passthru.json new file mode 100644 index 000000000..91e0fc86c --- /dev/null +++ b/iguana/help/komodo_passthru.json @@ -0,0 +1 @@ +{"agent":"komodo","method":"passthru","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"komodo_passthru_test.py"}]} diff --git a/iguana/help/mouse_change.json b/iguana/help/mouse_change.json new file mode 100644 index 000000000..e94100130 --- /dev/null +++ b/iguana/help/mouse_change.json @@ -0,0 +1 @@ +{"agent":"mouse","method":"change","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"mouse_change_test.py"}]} diff --git a/iguana/help/mouse_click.json b/iguana/help/mouse_click.json new file mode 100644 index 000000000..5400603ea --- /dev/null +++ b/iguana/help/mouse_click.json @@ -0,0 +1 @@ +{"agent":"mouse","method":"click","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"mouse_click_test.py"}]} diff --git a/iguana/help/mouse_close.json b/iguana/help/mouse_close.json new file mode 100644 index 000000000..465a680c4 --- /dev/null +++ b/iguana/help/mouse_close.json @@ -0,0 +1 @@ +{"agent":"mouse","method":"close","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"mouse_close_test.py"}]} diff --git a/iguana/help/mouse_image.json b/iguana/help/mouse_image.json new file mode 100644 index 000000000..0fe91b3b0 --- /dev/null +++ b/iguana/help/mouse_image.json @@ -0,0 +1 @@ +{"agent":"mouse","method":"image","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"mouse_image_test.py"}]} diff --git a/iguana/help/mouse_leave.json b/iguana/help/mouse_leave.json new file mode 100644 index 000000000..0102f7c1e --- /dev/null +++ b/iguana/help/mouse_leave.json @@ -0,0 +1 @@ +{"agent":"mouse","method":"leave","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"mouse_leave_test.py"}]} diff --git a/iguana/help/passthru_paxfiats.json b/iguana/help/passthru_paxfiats.json new file mode 100644 index 000000000..48b2d7b57 --- /dev/null +++ b/iguana/help/passthru_paxfiats.json @@ -0,0 +1 @@ +{"agent":"passthru","method":"paxfiats","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"passthru_paxfiats_test.py"}]} diff --git a/iguana/help/pax_start.json b/iguana/help/pax_start.json new file mode 100644 index 000000000..1f053e4f3 --- /dev/null +++ b/iguana/help/pax_start.json @@ -0,0 +1 @@ +{"agent":"pax","method":"start","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"pax_start_test.py"}]} diff --git a/iguana/help/tradebot_accumulate.json b/iguana/help/tradebot_accumulate.json new file mode 100644 index 000000000..e46ec03c3 --- /dev/null +++ b/iguana/help/tradebot_accumulate.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"accumulate","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_accumulate_test.py"}]} diff --git a/iguana/help/tradebot_activebots.json b/iguana/help/tradebot_activebots.json new file mode 100644 index 000000000..1eb5e73e3 --- /dev/null +++ b/iguana/help/tradebot_activebots.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"activebots","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_activebots_test.py"}]} diff --git a/iguana/help/tradebot_allbalances.json b/iguana/help/tradebot_allbalances.json new file mode 100644 index 000000000..93c51ec2b --- /dev/null +++ b/iguana/help/tradebot_allbalances.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"allbalances","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_allbalances_test.py"}]} diff --git a/iguana/help/tradebot_amlp.json b/iguana/help/tradebot_amlp.json new file mode 100644 index 000000000..35f83ec0d --- /dev/null +++ b/iguana/help/tradebot_amlp.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"amlp","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_amlp_test.py"}]} diff --git a/iguana/help/tradebot_anchor.json b/iguana/help/tradebot_anchor.json new file mode 100644 index 000000000..22a7256ae --- /dev/null +++ b/iguana/help/tradebot_anchor.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"anchor","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_anchor_test.py"}]} diff --git a/iguana/help/tradebot_aveprice.json b/iguana/help/tradebot_aveprice.json new file mode 100644 index 000000000..74f8bc1ab --- /dev/null +++ b/iguana/help/tradebot_aveprice.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"aveprice","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_aveprice_test.py"}]} diff --git a/iguana/help/tradebot_divest.json b/iguana/help/tradebot_divest.json new file mode 100644 index 000000000..013d6b795 --- /dev/null +++ b/iguana/help/tradebot_divest.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"divest","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_divest_test.py"}]} diff --git a/iguana/help/tradebot_gensvm.json b/iguana/help/tradebot_gensvm.json new file mode 100644 index 000000000..445aad5db --- /dev/null +++ b/iguana/help/tradebot_gensvm.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"gensvm","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_gensvm_test.py"}]} diff --git a/iguana/help/tradebot_goals.json b/iguana/help/tradebot_goals.json new file mode 100644 index 000000000..eadeab3f1 --- /dev/null +++ b/iguana/help/tradebot_goals.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"goals","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_goals_test.py"}]} diff --git a/iguana/help/tradebot_liquidity.json b/iguana/help/tradebot_liquidity.json new file mode 100644 index 000000000..dc1461790 --- /dev/null +++ b/iguana/help/tradebot_liquidity.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"liquidity","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_liquidity_test.py"}]} diff --git a/iguana/help/tradebot_monitor.json b/iguana/help/tradebot_monitor.json new file mode 100644 index 000000000..31df1db48 --- /dev/null +++ b/iguana/help/tradebot_monitor.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"monitor","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_monitor_test.py"}]} diff --git a/iguana/help/tradebot_monitorall.json b/iguana/help/tradebot_monitorall.json new file mode 100644 index 000000000..16ea650ae --- /dev/null +++ b/iguana/help/tradebot_monitorall.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"monitorall","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_monitorall_test.py"}]} diff --git a/iguana/help/tradebot_notlp.json b/iguana/help/tradebot_notlp.json new file mode 100644 index 000000000..ed462ecf4 --- /dev/null +++ b/iguana/help/tradebot_notlp.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"notlp","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_notlp_test.py"}]} diff --git a/iguana/help/tradebot_openliquidity.json b/iguana/help/tradebot_openliquidity.json new file mode 100644 index 000000000..961e6f424 --- /dev/null +++ b/iguana/help/tradebot_openliquidity.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"openliquidity","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_openliquidity_test.py"}]} diff --git a/iguana/help/tradebot_pause.json b/iguana/help/tradebot_pause.json new file mode 100644 index 000000000..81c641f28 --- /dev/null +++ b/iguana/help/tradebot_pause.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"pause","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_pause_test.py"}]} diff --git a/iguana/help/tradebot_portfolio.json b/iguana/help/tradebot_portfolio.json new file mode 100644 index 000000000..50b646579 --- /dev/null +++ b/iguana/help/tradebot_portfolio.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"portfolio","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_portfolio_test.py"}]} diff --git a/iguana/help/tradebot_resume.json b/iguana/help/tradebot_resume.json new file mode 100644 index 000000000..745666320 --- /dev/null +++ b/iguana/help/tradebot_resume.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"resume","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_resume_test.py"}]} diff --git a/iguana/help/tradebot_status.json b/iguana/help/tradebot_status.json new file mode 100644 index 000000000..1289541a5 --- /dev/null +++ b/iguana/help/tradebot_status.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"status","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_status_test.py"}]} diff --git a/iguana/help/tradebot_stop.json b/iguana/help/tradebot_stop.json new file mode 100644 index 000000000..d948d48c6 --- /dev/null +++ b/iguana/help/tradebot_stop.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"stop","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_stop_test.py"}]} diff --git a/iguana/help/tradebot_unmonitor.json b/iguana/help/tradebot_unmonitor.json new file mode 100644 index 000000000..992a768ef --- /dev/null +++ b/iguana/help/tradebot_unmonitor.json @@ -0,0 +1 @@ +{"agent":"tradebot","method":"unmonitor","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"tradebot_unmonitor_test.py"}]} diff --git a/iguana/help/zcash_passthru.json b/iguana/help/zcash_passthru.json new file mode 100644 index 000000000..657b16dfd --- /dev/null +++ b/iguana/help/zcash_passthru.json @@ -0,0 +1 @@ +{"agent":"zcash","method":"passthru","field0":"put in helpful info field0","field1":"put in helpful info for field1","help":"put helpful info here","teststatus":[{"tester":"bob","result":"put result here","notes":"put useful notes here","automated":"notyet","sourcefile":"zcash_passthru_test.py"}]} diff --git a/iguana/iguana.sources b/iguana/iguana.sources index 0c258c886..c186c10dd 100755 --- a/iguana/iguana.sources +++ b/iguana/iguana.sources @@ -1,2 +1,2 @@ -SOURCES := iguana_bundles.c iguana_mofn.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c ../gecko/gecko.c ../basilisk/basilisk.c ../datachain/datachain.c secp256k1/src/secp256k1.c \ No newline at end of file +SOURCES := iguana_notary.c iguana_bundles.c iguana_mofn.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c iguana_exchanges.c iguana_recv.c pangea_bets.c SuperNET_keys.c iguana_rpc.c pangea_hand.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c iguana777.c iguana_tradebots.c pangea_summary.c iguana_accept.c iguana_json.c iguana_tx.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c ../gecko/gecko.c ../basilisk/basilisk.c ../datachain/datachain.c secp256k1/src/secp256k1.c \ No newline at end of file diff --git a/iguana/iguana.vcxproj b/iguana/iguana.vcxproj new file mode 100644 index 000000000..6bb9c2eaa --- /dev/null +++ b/iguana/iguana.vcxproj @@ -0,0 +1,297 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B} + Win32Proj + ConsoleApplication3 + 8.1 + iguana + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level2 + Disabled + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 1Byte + + + Console + true + Ws2_32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 1Byte + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;%(PreprocessorDefinitions) + + + Console + true + true + true + Ws2_32.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;%(PreprocessorDefinitions) + 1Byte + + + Console + true + true + true + Ws2_32.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iguana/iguana.vcxproj.filters b/iguana/iguana.vcxproj.filters new file mode 100644 index 000000000..da9ab88db --- /dev/null +++ b/iguana/iguana.vcxproj.filters @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 1ed4b4101..d998b4b81 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -27,7 +27,9 @@ struct iguana_info *iguana_coinfind(char *symbol) struct iguana_info *coin=0; uint32_t symbolcrc; struct supernet_info *myinfo = SuperNET_MYINFO(0); while ( myinfo->allcoins_being_added != 0 ) { - printf("wait for coinadd to complete, OK if rare\n"); + sleep(1); + if ( myinfo->allcoins_being_added != 0 ) + printf("wait for coinadd to complete, OK if rare\n"); sleep(1); } symbolcrc = calc_crc32(0,symbol,(int32_t)strlen(symbol)); @@ -55,7 +57,9 @@ struct iguana_info *iguana_coinadd(char *symbol,char *name,cJSON *argjson,int32_ } else { - coin->chain = iguana_chainfind((char *)symbol,argjson,1); + coin->chain = iguana_chainfind(myinfo,(char *)symbol,argjson,1); + //if ( coin->FULLNODE >= 0 ) + // coin->chain->userpass[0] = 0; coin->peers = calloc(1,sizeof(*coin->peers)); for (j=0; jallcoins_numvirts); coin->symbolcrc = symbolcrc = calc_crc32(0,symbol,(int32_t)strlen(symbol)); //portable_mutex_lock(&myinfo->allcoins_mutex); - HASH_ADD(hh,myinfo->allcoins,symbolcrc,sizeof(coin->symbolcrc),coin); + coin->coinid = myinfo->totalcoins++; + HASH_ADD(hh,myinfo->allcoins,symbolcrc,sizeof(coin->symbolcrc),coin); //portable_mutex_unlock(&myinfo->allcoins_mutex); struct iguana_info *virt,*tmp; HASH_ITER(hh,myinfo->allcoins,virt,tmp) @@ -100,25 +105,6 @@ void iguana_recvalloc(struct iguana_info *coin,int32_t numitems) //coin->blocks.maxbits = numitems; } -static int _decreasing_double(const void *a,const void *b) -{ -#define double_a (*(double *)a) -#define double_b (*(double *)b) - if ( double_b > double_a ) - return(1); - else if ( double_b < double_a ) - return(-1); - return(0); -#undef double_a -#undef double_b -} - -static int32_t revsortds(double *buf,uint32_t num,int32_t size) -{ - qsort(buf,num,size,_decreasing_double); - return(0); -} - double iguana_metric(struct iguana_peer *addr,uint32_t now,double decay) { int32_t duration; double metric = addr->recvblocks * addr->recvtotal; @@ -164,7 +150,7 @@ int32_t iguana_peermetrics(struct supernet_info *myinfo,struct iguana_info *coin { coin->peers->topmetrics[i] = sortbuf[i*2]; ind = (int32_t)sortbuf[i*2 +1]; - coin->peers->ranked[i] = &coin->peers->active[ind]; + coin->peers->ranked[i] = addr = &coin->peers->active[ind]; if ( sortbuf[i*2] > SMALLVAL && (double)i/n > .8 && (time(NULL) - addr->ready) > 77 ) slowest = coin->peers->ranked[i]; //printf("(%.5f %s) ",sortbuf[i*2],coin->peers->ranked[i]->ipaddr); @@ -174,7 +160,7 @@ int32_t iguana_peermetrics(struct supernet_info *myinfo,struct iguana_info *coin } coin->peers->numranked = n; portable_mutex_unlock(&coin->peers_mutex); - //printf("NUMRANKED.%d\n",n); + //printf("peer metrics NUMRANKED.%d\n",n); if ( i > 0 ) { coin->peers->avemetric = (sum / i); @@ -228,7 +214,7 @@ uint32_t iguana_updatemetrics(struct supernet_info *myinfo,struct iguana_info *c { expand_ipbits(ipaddr,(uint32_t)addr->ipbits); fprintf(fp,"%s\n",ipaddr); - if ( 0 && addr->msgcounts.verack == 0 ) + if ( (0) && addr->msgcounts.verack == 0 ) { printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); iguana_send_version(coin,addr,coin->myservices); @@ -241,7 +227,8 @@ uint32_t iguana_updatemetrics(struct supernet_info *myinfo,struct iguana_info *c printf("new peers.txt %ld vs (%s) %ld (%s)\n",ftell(fp),fname,(long)OS_filesize(fname),GLOBAL_CONFSDIR); fclose(fp); OS_renamefile(fname,oldfname); - OS_copyfile(tmpfname,fname,1); + OS_renamefile(tmpfname,fname); + //OS_copyfile(tmpfname,fname,1); } else fclose(fp); } else @@ -262,26 +249,40 @@ void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp) ptr->type = 'E'; ptr->starttime = (uint32_t)time(NULL); //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); - queue_enqueue("emitQ",&emitQ,&ptr->DL,0); + queue_enqueue("emitQ",&emitQ,&ptr->DL); } -void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit) +void iguana_bundleQ(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit) { - struct iguana_helper *ptr; - if ( 0 && bp->queued == 0 && bp->emitfinish <= 1 && iguana_bundleready(coin,bp,0) == bp->n ) + struct iguana_helper *ptr; struct iguana_bundle *tmp; int32_t i,n = 0; + if ( (0) && bp->queued == 0 && bp->emitfinish <= 1 && iguana_bundleready(myinfo,coin,bp,0) == bp->n ) printf("bundle.[%d] is ready\n",bp->hdrsi); - bp->queued = (uint32_t)time(NULL); - ptr = mycalloc('q',1,sizeof(*ptr)); - ptr->allocsize = sizeof(*ptr); - ptr->coin = coin; - ptr->bp = bp, ptr->hdrsi = bp->hdrsi; - ptr->type = 'B'; - ptr->starttime = (uint32_t)time(NULL); - ptr->timelimit = timelimit; - coin->numbundlesQ++; - if ( 0 && bp->hdrsi > 170 ) - printf("%s %p bundle.%d[%d] ht.%d emitfinish.%u\n",coin->symbol,bp,ptr->hdrsi,bp->n,bp->bundleheight,bp->emitfinish); - queue_enqueue("bundlesQ",&bundlesQ,&ptr->DL,0); + if ( bp->queued != 0 ) + return; + for (i=n=0; ibundlescount; i++) + { + if ( (tmp= coin->bundles[i]) != 0 && tmp->queued != 0 ) + n++; + } + if ( n < coin->MAXBUNDLES ) + { + bp->queued = (uint32_t)time(NULL); + ptr = mycalloc('q',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 'B'; + ptr->starttime = (uint32_t)time(NULL); + ptr->timelimit = timelimit; + coin->numbundlesQ++; + // printf("%s.%d %p bundle.%d[%d] ht.%d emitfinish.%u\n",coin->symbol,n,bp,ptr->hdrsi,bp->n,bp->bundleheight,bp->emitfinish); + queue_enqueue("bundlesQ",&bundlesQ,&ptr->DL); + } + else + { + bp->queued = 0; + //printf("MAXBUNDLES.%d reached.%d\n",coin->MAXBUNDLES,n); + } } void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp) @@ -302,19 +303,23 @@ void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp) }*/ } -int32_t iguana_emitfinished(struct iguana_info *coin,int32_t queueincomplete) +int32_t iguana_emitfinished(struct supernet_info *myinfo,struct iguana_info *coin,int32_t queueincomplete) { struct iguana_bundle *bp; int32_t i,n = 0; for (i=0; ibundlescount-1; i++) { if ( (bp= coin->bundles[i]) != 0 ) { + if ( bp->emitfinish == 0 && bp->ramchain.H.data != 0 ) + bp->emitfinish = (uint32_t)time(NULL); if ( bp->emitfinish > 1 ) n++; - else if ( bp->emitfinish == 0 && bp->queued == 0 ) - iguana_bundleQ(coin,bp,1000); + //printf("%u ",bp->emitfinish); + //else if ( bp->emitfinish == 0 && bp->queued == 0 ) + // iguana_bundleQ(myinfo,coin,bp,1000); } } + //printf("emitfinished.%d\n",n); return(n); } @@ -364,21 +369,22 @@ int32_t iguana_validated(struct iguana_info *coin) int32_t iguana_helperA(struct supernet_info *myinfo,struct iguana_info *coin,int32_t helperid,struct iguana_bundle *bp,int32_t convertflag) { - int32_t retval,num = 0; + int32_t retval,numXspends,num = 0; if ( bp == 0 ) { printf("iguana_helperA unexpected null bp\n"); return(-1); } //printf("helperid.%d validate gen utxo.[%d] utxofinish.%u\n",helperid,bp->hdrsi,bp->utxofinish); - if ( strcmp("BTC",coin->symbol) == 0 || iguana_bundlevalidate(coin,bp,0) == bp->n ) // + if ( iguana_bundlevalidate(myinfo,coin,bp,0) == bp->n ) // { retval = 0; if ( bp->utxofinish > 1 || (retval= iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,convertflag,0)) >= 0 ) { if ( retval > 0 ) { - printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - bp->startutxo); + numXspends = iguana_Xspendmap(coin,&bp->ramchain,bp); + printf("GENERATED UTXO.%d for ht.%d duration %d seconds numXspends.%d\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - bp->startutxo,numXspends); num++; } bp->utxofinish = (uint32_t)time(NULL); @@ -387,7 +393,7 @@ int32_t iguana_helperA(struct supernet_info *myinfo,struct iguana_info *coin,int else { printf("error validating.[%d], restart iguana\n",bp->hdrsi); - exit(-1); + iguana_exit(myinfo,bp); } return(num); } @@ -413,9 +419,11 @@ int32_t iguana_helperB(struct iguana_info *coin,int32_t helperid,struct iguana_b return(0); } -void iguana_update_balances(struct iguana_info *coin) +int32_t iguana_utxogen(struct supernet_info *myinfo,struct iguana_info *coin,int32_t helperid,int32_t convertflag); + +void iguana_update_balances(struct supernet_info *myinfo,struct iguana_info *coin) { - int32_t i,hdrsi,max; struct iguana_bundle *bp; char fname[1024]; + int32_t i,hdrsi,max,retval,numXspends,convertflag = 1; struct iguana_bundle *bp; char fname[1024]; if ( coin->RTheight > 0 ) { printf("Need to restart iguana to generate new balances files\n"); @@ -423,9 +431,29 @@ void iguana_update_balances(struct iguana_info *coin) return; } max = coin->bundlescount; - if ( coin->bundles[max-1] == coin->current || coin->bundles[max-1] == 0 || (coin->bundles[max-1] != 0 && coin->bundles[max-1]->emitfinish <= 1) ) + if ( coin->bundles[max-1] == coin->current || coin->bundles[max-1] == 0 || (coin->bundles[max-1] != 0 && coin->bundles[max-1]->utxofinish <= 1) ) max--; - //coin->spendvectorsaved = 0; + if ( 1 && coin->chain->zcash != 0 ) + { + coin->spendvectorsaved = 0; + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) == 0 ) + continue; + if ( (retval= iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,convertflag,0)) >= 0 ) //bp->utxofinish > 1 || + { + if ( retval > 0 ) + { + numXspends = iguana_Xspendmap(coin,&bp->ramchain,bp); + printf("GENERATED UTXO.%d for ht.%d duration %d seconds numX.%d\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - bp->startutxo,numXspends); + } + bp->utxofinish = (uint32_t)time(NULL); + } + } + } + coin->spendvectorsaved = (uint32_t)time(NULL); + //if ( coin->chain->zcash != 0 ) + // iguana_utxogen(myinfo,coin,0,1); if ( iguana_balancefinished(coin) < max && iguana_spendvectorsaves(coin) == 0 ) // { if ( coin->origbalanceswritten <= 1 ) @@ -436,10 +464,11 @@ void iguana_update_balances(struct iguana_info *coin) { iguana_volatilespurge(coin,&bp->ramchain); sprintf(fname,"%s/%s/accounts/debits.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); - OS_removefile(fname,0); + OS_removefile(fname,0); sprintf(fname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); - OS_removefile(fname,0); + OS_removefile(fname,0); iguana_volatilesalloc(coin,&bp->ramchain,0);//i < hdrsi); + //iguana_Xspendmap(coin,&bp->ramchain,bp); } printf("accounts files purged\n"); sleep(3); @@ -466,6 +495,15 @@ void iguana_update_balances(struct iguana_info *coin) sleep(3); }// else printf("skip flush when max.%d and orig.%d\n",max,coin->origbalanceswritten); } + else + { + for (i=0; ibundles[i]) != 0 && bp != coin->current ) + { + iguana_volatilespurge(coin,&bp->ramchain); + iguana_volatilesmap(myinfo,coin,&bp->ramchain); + } + } } int32_t iguana_utxogen(struct supernet_info *myinfo,struct iguana_info *coin,int32_t helperid,int32_t convertflag) @@ -476,51 +514,25 @@ int32_t iguana_utxogen(struct supernet_info *myinfo,struct iguana_info *coin,int printf("skip utxogen as spendvectorsaved.%u\n",coin->spendvectorsaved); return(0); } - //if ( (incr= IGUANA_NUMHELPERS) > 8 ) - // incr = 8; incr = IGUANA_NUMHELPERS; max = coin->bundlescount; - if ( coin->bundles[max-1] == coin->current || coin->bundles[max-1] == 0 || (coin->bundles[max-1] != 0 && coin->bundles[max-1]->emitfinish <= 1) ) + if ( coin->bundles[max-1] == coin->current || coin->bundles[max-1] == 0 || (coin->bundles[max-1] != 0 && coin->bundles[max-1]->utxofinish <= 1) ) max--; - printf("helperid.%d start %s utxogen bundlescount.%d max.%d\n",helperid,coin->symbol,coin->bundlescount,max); + //printf("helperid.%d start %s utxogen bundlescount.%d max.%d\n",helperid,coin->symbol,coin->bundlescount,max); if ( helperid < incr ) { for (hdrsi=helperid; hdrsibundles[hdrsi]->utxofinish = 1; num += iguana_helperA(myinfo,coin,helperid,coin->bundles[hdrsi],convertflag); + } } while ( (n= iguana_utxofinished(coin)) < max ) { - printf("helperid.%d utxofinished.%d vs %d\n",helperid,n,max); + printf("helperid.%d %s utxofinished.%d vs %d\n",helperid,coin->symbol,n,max); sleep(IGUANA_NUMHELPERS+3); } - if ( helperid < incr ) - { - for (hdrsi=helperid; hdrsibundles[hdrsi],convertflag); - } - while ( (n= iguana_convertfinished(coin)) < max ) - { - //printf("helperid.%d convertfinished.%d vs max %d bundlescount.%d\n",helperid,n,max,coin->bundlescount); - sleep(IGUANA_NUMHELPERS+3); - } - if ( helperid == 0 ) - { - printf("start iguana_update_balances\n"); - iguana_update_balances(coin); - printf("iguana_update_balances completed\n"); - if ( 1 ) - { - for (i=0; ibundles[i]) != 0 ) - { - iguana_volatilespurge(coin,&bp->ramchain); - iguana_volatilesmap(coin,&bp->ramchain); - } - } - } - while ( iguana_balancefinished(coin) < max || coin->balanceflush != 0 ) - sleep(3); - if ( helperid < incr ) + /*if ( helperid < incr ) { for (hdrsi=helperid; hdrsin ) + if ( iguana_bundlevalidate(myinfo,coin,bp,0) != bp->n ) { printf("validate.[%d] error. refresh page or restart iguana and it should regenerate\n",bp->hdrsi); - exit(-1); + iguana_exit(myinfo); } // else printf("%s helperid.%d validated.[%d]\n",coin->symbol,helperid,hdrsi); } } @@ -540,7 +552,37 @@ int32_t iguana_utxogen(struct supernet_info *myinfo,struct iguana_info *coin,int { printf("%s helperid.%d waiting for spendvectorsaved.%u v.%d u.%d b.%d vs max.%d\n",coin->symbol,helperid,coin->spendvectorsaved,iguana_validated(coin),iguana_utxofinished(coin),iguana_balancefinished(coin),max); sleep(2*IGUANA_NUMHELPERS+3); + }*/ + if ( convertflag == 0 ) + { + if ( helperid < incr ) + { + for (hdrsi=helperid; hdrsibundles[hdrsi],convertflag); + } + while ( (n= iguana_convertfinished(coin)) < max ) + { + //printf("helperid.%d convertfinished.%d vs max %d bundlescount.%d\n",helperid,n,max,coin->bundlescount); + sleep(IGUANA_NUMHELPERS+3); + } + } + if ( helperid == 0 ) + { + printf("%s start iguana_update_balances\n",coin->symbol); + iguana_update_balances(myinfo,coin); + printf("%s iguana_update_balances completed\n",coin->symbol); + if ( 1 ) + { + for (i=0; ibundles[i]) != 0 ) + { + iguana_volatilespurge(coin,&bp->ramchain); + iguana_volatilesmap(myinfo,coin,&bp->ramchain); + } + } } + while ( iguana_balancefinished(coin) < max || coin->balanceflush != 0 ) + sleep(3); //printf("helper.%d check validates\n",helperid); //incr = IGUANA_NUMHELPERS; //incr = 1; @@ -555,7 +597,7 @@ int32_t iguana_utxogen(struct supernet_info *myinfo,struct iguana_info *coin,int if ( iguana_utxoaddr_gen(myinfo,coin,(coin->bundlescount - 1) * coin->chain->bundlesize) == 0 ) { printf("restart iguana: fatal error generating ledger file for %s\n",coin->symbol); - exit(1); + iguana_exit(myinfo,0); } } } @@ -568,7 +610,7 @@ int32_t iguana_utxogen(struct supernet_info *myinfo,struct iguana_info *coin,int return(num); } -int32_t iguana_coin_mainiter(struct iguana_info *coin,int32_t *numpeersp) +int32_t iguana_coin_mainiter(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numpeersp,struct OS_memspace *mem,struct OS_memspace *memB) { int32_t n,j,isRT = 0; struct iguana_bundle *bp; if ( coin->RTheight == 0 && coin->firstRTheight == 0 && coin->current != 0 && coin->active != 0 && coin->started != 0 ) @@ -576,36 +618,52 @@ int32_t iguana_coin_mainiter(struct iguana_info *coin,int32_t *numpeersp) isRT *= (coin->RTheight > 0); if ( coin->peers != 0 ) *numpeersp += coin->peers->numranked; - if ( 0 && (rand() % 10) == 0 ) + if ( (0) && (rand() % 10) == 0 ) printf("%s main.%u vs %u, svs %u %d vs %d\n",coin->symbol,(uint32_t)time(NULL),coin->startutc+10,coin->spendvectorsaved ,coin->blocks.hwmchain.height/coin->chain->bundlesize,(coin->longestchain-coin->minconfirms)/coin->chain->bundlesize); - if ( time(NULL) > coin->startutc+60 && coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-coin->chain->bundlesize)/coin->chain->bundlesize ) + if ( time(NULL) > coin->startutc+60 ) { + //if ( (bp= coin->current) != 0 && bp->numsaved >= coin->chain->bundlesize && bp->startutxo == 0 ) + // iguana_bundlefinalize(myinfo,coin,bp,mem,memB); n = coin->bundlescount-1; - //printf("%s n.%d emitfinished.%d coin->spendvectorsaved %d\n",coin->symbol,n,iguana_emitfinished(coin,1),coin->spendvectorsaved); - if ( iguana_emitfinished(coin,1) >= n ) + if ( coin->matchedfiles == 0 && coin->spendvectorsaved == 0 && coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-coin->chain->bundlesize)/coin->chain->bundlesize ) { - if ( coin->PREFETCHLAG >= 0 && coin->fastfind == 0 ) + //printf("%s n.%d emitfinished.%d coin->spendvectorsaved %d\n",coin->symbol,n,iguana_emitfinished(myinfo,coin,1),coin->spendvectorsaved); + if ( iguana_emitfinished(myinfo,coin,1) >= n ) { - for (j=0; jbundles[j] != 0 ) - iguana_alloctxbits(coin,&coin->bundles[j]->ramchain); - sleep(3); - } - if ( iguana_validated(coin) < n || iguana_utxofinished(coin) < n || iguana_balancefinished(coin) < n ) - { - coin->spendvectorsaved = 1; - //printf("update volatile data, need.%d vs utxo.%d balances.%d validated.%d\n",n,iguana_utxofinished(coin),iguana_balancefinished(coin),iguana_validated(coin)); - } - else - { - coin->spendvectorsaved = (uint32_t)time(NULL); - //printf("already done UTXOGEN (%d %d) (%d %d)\n",iguana_utxofinished(coin),n,iguana_balancefinished(coin),n); + /*if ( coin->PREFETCHLAG >= 0 && coin->fastfind == 0 ) + { + for (j=0; jbundles[j] != 0 ) + iguana_alloctxbits(coin,&coin->bundles[j]->ramchain); + sleep(3); + }*/ + if ( iguana_utxofinished(coin) < n )//|| iguana_balancefinished(coin) < n || iguana_validated(coin) < n) ) + { + //printf("About to generate tables\n"), getchar(); + iguana_fastfindreset(coin); + iguana_fastfindcreate(coin); + if ( coin->fastfind == 0 ) + { + for (j=0; jbundles[j] != 0 ) + iguana_alloctxbits(coin,&coin->bundles[j]->ramchain); + sleep(3); + } + coin->spendvectorsaved = 1; + printf("update volatile data, need.%d vs utxo.%d balances.%d validated.%d\n",n,iguana_utxofinished(coin),iguana_balancefinished(coin),iguana_validated(coin)); + } + else + { + iguana_update_balances(myinfo,coin); + coin->spendvectorsaved = (uint32_t)time(NULL); + printf("already done UTXOGEN (%d %d %d) n.%d\n",iguana_utxofinished(coin),iguana_validated(coin),iguana_balancefinished(coin),n); + } } - } //else printf("only emit.%d vs %d\n",iguana_emitfinished(coin),n); + } } if ( (bp= coin->current) != 0 && coin->stucktime != 0 && coin->isRT == 0 && coin->RTheight == 0 && (time(NULL) - coin->stucktime) > coin->MAXSTUCKTIME ) { - if ( 0 ) + if ( (0) ) { printf("%s is stuck too long, restarting due to %d\n",coin->symbol,bp->hdrsi); if ( coin->started != 0 ) @@ -628,7 +686,7 @@ int32_t iguana_coin_mainiter(struct iguana_info *coin,int32_t *numpeersp) void iguana_helper(void *arg) { static uint64_t helperidbits; - cJSON *argjson=0; int32_t iter,n,j,numpeers,polltimeout,type,helperid=rand(),flag,allcurrent,idle=0; + cJSON *argjson=0; int32_t iter,n,i,j,retval,numpeers,polltimeout,type,helperid=rand(),flag,allcurrent,idle=0; struct iguana_helper *ptr; struct iguana_info *coin,*tmp; struct OS_memspace MEM,*MEMB; struct iguana_bundle *bp; struct supernet_info *myinfo = SuperNET_MYINFO(0); helperid %= 64; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) @@ -660,26 +718,67 @@ void iguana_helper(void *arg) { if ( coin->firstRTheight == 0 ) { - if ( coin->spendvectorsaved == 1 ) - iguana_utxogen(myinfo,coin,helperid,0); + if ( coin->spendvectorsaved == 1 )//&& coin->chain->zcash == 0 ) + iguana_utxogen(myinfo,coin,helperid,1); else if ( coin->spendvectorsaved > 1 && (coin->spendvalidated & (1 << helperid)) == 0 ) { //printf("%s spendvectorsaved.%u helperid.%d validate\n",coin->symbol,coin->spendvectorsaved,helperid); for (j=helperid; jbundlescount-1; j+=IGUANA_NUMHELPERS) if ( (bp= coin->bundles[j]) != 0 ) - iguana_bundlevalidate(coin,bp,0); + iguana_bundlevalidate(myinfo,coin,bp,0); coin->spendvalidated |= (1 << helperid); //printf("DONE %s spendvectorsaved.%u helperid.%d validate\n",coin->symbol,coin->spendvectorsaved,helperid); } + else + { + for (j=helperid; jbundlescount; j+=IGUANA_NUMHELPERS) + { + if ( (bp= coin->bundles[j]) != 0 ) + { + if ( bp->emitfinish == 0 && bp->numsaved >= coin->chain->bundlesize && iguana_bundleready(myinfo,coin,bp,0) == bp->n ) + iguana_bundlefinalize(myinfo,coin,bp,&MEM,MEMB); + if ( bp->emitfinish != 0 && time(NULL) > bp->emitfinish+60 ) + { + if ( bp->validated == 0 ) + { + for (i=0; ibundles[i] == 0 || coin->bundles[i]->validated <= 1 ) + break; + if ( i == j ) + iguana_bundlevalidate(myinfo,coin,bp,0); + } + if ( bp->validated > 1 )//&& coin->chain->zcash == 0 ) + { + for (i=0; ibundles[i] == 0 || coin->bundles[i]->utxofinish <= 1 ) + break; + retval = 1; + if ( bp->utxofinish == 0 ) + { + bp->startutxo = (uint32_t)time(NULL); + if ( (retval= iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,1,0)) >= 0 ) + { + if ( retval > 0 ) + { + printf(" GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - bp->startutxo); + bp->utxofinish = (uint32_t)time(NULL); + } + } + } + } + } + } + } + } + if ( (helperid % IGUANA_NUMHELPERS) == (coin->coinid % IGUANA_NUMHELPERS) ) + iguana_coin_mainiter(myinfo,coin,&numpeers,&MEM,MEMB); } - if ( helperid == 0 ) - iguana_coin_mainiter(coin,&numpeers); } //portable_mutex_unlock(&myinfo->allcoins_mutex); n = queue_size(&bundlesQ); for (iter=0; itercoin; @@ -691,7 +790,7 @@ void iguana_helper(void *arg) allcurrent = 0; //printf("h.%d [%d] bundleQ size.%d lag.%ld\n",helperid,bp->hdrsi,queue_size(&bundlesQ),time(NULL) - bp->nexttime); coin->numbundlesQ--; - if ( coin->started != 0 && (bp->nexttime == 0 || time(NULL) > bp->nexttime) && coin->active != 0 ) + if ( bp->startutxo == 0 && coin->started != 0 && time(NULL) > bp->nexttime && coin->active != 0 ) { flag += iguana_bundleiters(myinfo,ptr->coin,&MEM,MEMB,bp,ptr->timelimit,IGUANA_DEFAULTLAG); } @@ -699,7 +798,7 @@ void iguana_helper(void *arg) { //printf("skip.[%d] nexttime.%u lag.%ld coin->active.%d\n",bp->hdrsi,bp->nexttime,time(NULL)-bp->nexttime,coin->active); allcurrent--; - iguana_bundleQ(coin,bp,1000); + iguana_bundleQ(myinfo,coin,bp,1000); } } else //if ( coin->active != 0 ) @@ -721,7 +820,7 @@ void iguana_helper(void *arg) void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin) { - struct iguana_bundle *bp; int32_t bundlei; bits256 zero; char dirname[512],*symbol; + struct iguana_bundle *bp; struct iguana_peer *addr; int32_t bundlei; bits256 zero; char dirname[512],*symbol; iguana_rwiAddrind(coin,0,0,0); //for (i=0; ichain); i++) // printf("%02x",((uint8_t *)coin->chain)[i]); @@ -742,23 +841,38 @@ void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin) } sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname); sprintf(dirname,"%s/%s/RT",GLOBAL_TMPDIR,coin->symbol), OS_ensure_directory(dirname); - iguana_coinstart(coin,coin->initialheight,coin->mapflags); + printf("CALL MARKINIT.%s\n",coin->symbol); + iguana_unspents_markinit(myinfo,coin); + iguana_coinstart(myinfo,coin,coin->initialheight,coin->mapflags); coin->chain->minconfirms = coin->minconfirms; coin->started = coin; coin->startutc = (uint32_t)time(NULL); memset(zero.bytes,0,sizeof(zero)); if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) bp->bundleheight = 0; + if ( coin->FULLNODE != 0 ) + coin->notarychain = -1; + addr = &coin->peers->active[IGUANA_MAXPEERS-2]; + iguana_initpeer(coin,addr,(uint32_t)calc_ipbits(coin->seedipaddr)); + printf("SEED_IPADDR initpeer.(%s) notarychain.%d\n",addr->ipaddr,coin->notarychain); + iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); } void iguana_coinloop(void *arg) { - struct supernet_info *myinfo; int32_t flag,i,n; bits256 zero; uint32_t now; struct iguana_info *coin,**coins = arg; + struct supernet_info *myinfo; int32_t flag,i,j,n; struct iguana_peer *addr; bits256 zero; uint32_t now; struct iguana_info *coin,**coins = arg; myinfo = SuperNET_MYINFO(0); n = (int32_t)(long)coins[0]; coins++; coin = coins[0]; - printf("begin coinloop[%d] %s\n",n,coin->symbol); + if ( (coin->notarychain= iguana_isnotarychain(coin->symbol)) >= 0 ) + { + coin->VALIDATENODE = 0; + coin->DEXEXPLORER = myinfo->DEXEXPLORER; + } + //if ( coin->FULLNODE > 0 ) + // coin->notarychain = -1; + printf("begin coinloop[%d] %s notarychain.%d DEXEXPLORER.%d\n",n,coin->symbol,coin->notarychain,coin->DEXEXPLORER); memset(zero.bytes,0,sizeof(zero)); while ( 1 ) { @@ -767,13 +881,27 @@ void iguana_coinloop(void *arg) { if ( (coin= coins[i]) != 0 ) { + if ( coin->didaddresses == 0 ) + { + coin->didaddresses = 1; + if ( coin->notarychain >= 0 && myinfo->IAMNOTARY != 0 ) + init_alladdresses(myinfo,coin); + } + if ( coin->FULLNODE < 0 )//|| (coin->notarychain >= 0 && coin->FULLNODE == 0) ) + { + continue; + } + /*if ( strcmp(coin->symbol,"RELAY") == 0 ) + { + if ( myinfo->expiration != 0 && (myinfo->IAMLP != 0 || myinfo->DEXactive > now) ) + basilisk_requests_poll(myinfo); + }*/ if ( n > 1 && coin->RTheight > 0 && (rand() % 10) != 0 ) continue; if ( coin->peers == 0 ) { printf("FATAL lack of peers struct\n"); - exit(-1); - iguana_launchpeer(coin,"127.0.0.1",1); + iguana_exit(myinfo,0); } if ( coin->virtualchain == 0 ) { @@ -789,10 +917,34 @@ void iguana_coinloop(void *arg) if ( coin->started == 0 && coin->active != 0 ) { iguana_callcoinstart(myinfo,coin); + /*if ( 0 && strcmp("BTC",coin->symbol) == 0 ) + { + char *txstr = "0100000001d378ebd1b0c230b4d078288cf95fe28d7b3032d28c47de22ed6140d845dcb01f00000000d147304402204dd322834ff15cf1526dae3940521bb504b365b194515725d9c0f81dfbeae68d02205fb8fd269e3f2ddf7d0a17b056d2904ce572b8f22edeb39cd4c209fcf5244645011d74c7e7d8a2041be600e74708276d79ff001e754269b6e868ccf517f87f3d004c674c6763040cd6e557b175210326af93b75917b4903d7acdf8e2a560357ce18b7615cc7de02ade4f62861a57dfac67a9149c41c06aac6a7fcfd29eef87c4a633b9126b8b09882102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac68ffffffff01127b0000000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000"; + cJSON *txobj = cJSON_Parse("{\"version\":1,\"locktime\":1474666158,\"vin\":[{\"userdata\":\"51\",\"txid\":\"fc97c3675c83c09723e0b14292ddec73820cb7352166ace4fe81ed62568315f2\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a914b7a2e599edb55d3f78ebcbfd49e82dd9a12adc2487\"},\"suppress\":1,\"sequence\":0,\"redeemScript\":\"6304ae9ee557b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a914adfad35d6646a0514011ba6ab53462319b651f96882103225046c9947222ab04acdefe2ed5dec4dcb593c5e6ae58e2c61c7ace14d81b70ac68\"}],\"vout\":[{\"satoshis\":\"36042\",\"scriptPubkey\":{\"hex\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}}]}"); + cJSON *txobj4 = cJSON_Parse("{\"version\":1,\"locktime\":0,\"timestamp\":1474721847,\"vin\":[{\"txid\":\"a18e779a1daf22e9c427dc01dea0c268345a6b619da2eb7cdefd692719bdafdc\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a9149a8254cc4499a340209e7ca699fe6a096f79b31087\"},\"suppress\":1,\"redeemScript\":\"522102f563272bd62384d1813c1d30e774e6da6efa5822178a3ab64d6f3ed9e4cfb77e210387edb0a5895e772788c3e010b46c6145a0bafe862f098d6b74dc2f443408827b52ae\"}],\"vout\":[{\"satoshis\":\"9990000\",\"scriptPubkey\":{\"hex\":\"76a9148ee61a3161993f4f7b7081259bf5f3322d65d3f888ac\"}}]}"); + cJSON *privkeys = cJSON_Parse("[\"UwqPATeGVau5GeevspxCsvjnusCrEkU8To8NKLv91GU4mbZCQKeT\", \"Uu4AEVHrgFv4trDfj24kDTgKhaEdDkV7sNpH8MgTKTxEATF9YEcv\"]"); + cJSON *txobj2 = cJSON_Parse("{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"20491d74c7e7d8a2041be600e74708276d79ff001e754269b6e868ccf517f87f3d00\",\"txid\":\"1fb0dc45d84061ed22de478cd232307b8de25ff98c2878d0b430c2b0d1eb78d3\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a9144bf88c2ce8b9a40e3863bf1d4a5fb443d3e1bfe487\"},\"suppress\":1,\"redeemScript\":\"63040cd6e557b175210326af93b75917b4903d7acdf8e2a560357ce18b7615cc7de02ade4f62861a57dfac67a9149c41c06aac6a7fcfd29eef87c4a633b9126b8b09882102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac68\"}],\"vout\":[{\"satoshis\":\"31506\",\"scriptPubkey\":{\"hex\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}}]}"); + cJSON *txobj3 = cJSON_Parse("{\"version\":1,\"timestamp\":1474672690,\"vin\":[{\"sequence\":4294967214,\"txid\":\"119ec1a65f530c751e53b4af0505e960cf47680859c5f3ee3981ebe883207186\",\"vout\":0,\"scriptSig\":{\"hex\":\"483045022100880a1e3eafade4d4a24dd0bde2f31178d43978beacd63da1ee54760e0651f3b2022061dd05a66b65dc40fb729d95d2205dbf054ceb0bc4eb55c42088d0684a4c5a6701483045022100b4498798fc3a61de0b6df83ea4f6b67f89c5683124c2a3a981bd070826d7d1590220121d73d362b796583baa73c8c78eb851f78dc8f1cc75cb5bb3dfb14d6b843742012102ed1e99e73093c70c6156bce5954cb3e04215405ac06aa525ff942b74b8416efc2103a013a5f01afb3f0f00a657bb76fb30fd38437c80b52d9248b50738c96902e78747522102ed1e99e73093c70c6156bce5954cb3e04215405ac06aa525ff942b74b8416efc2103a013a5f01afb3f0f00a657bb76fb30fd38437c80b52d9248b50738c96902e78752ae\",\"asm\":\"3045022100880a1e3eafade4d4a24dd0bde2f31178d43978beacd63da1ee54760e0651f3b2022061dd05a66b65dc40fb729d95d2205dbf054ceb0bc4eb55c42088d0684a4c5a6701 3045022100b4498798fc3a61de0b6df83ea4f6b67f89c5683124c2a3a981bd070826d7d1590220121d73d362b796583baa73c8c78eb851f78dc8f1cc75cb5bb3dfb14d6b84374201 02ed1e99e73093c70c6156bce5954cb3e04215405ac06aa525ff942b74b8416efc 03a013a5f01afb3f0f00a657bb76fb30fd38437c80b52d9248b50738c96902e787 522102ed1e99e73093c70c6156bce5954cb3e04215405ac06aa525ff942b74b8416efc2103a013a5f01afb3f0f00a657bb76fb30fd38437c80b52d9248b50738c96902e78752ae\"}}],\"numvins\":1}"); + cJSON *txobj5 = cJSON_Parse("{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"204b0b2033ca8888a52554e0312f72849c72897ef8500e6019a46fd9e51e39816d00\",\"txid\":\"e4a22b8f7d63ed1cdcece6269acde409c2f6d473595f22875baf64b686762ce1\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a91478d98e781618f50be5fa6e340aba02026737888487\"},\"suppress\":1,\"redeemScript\":\"63048615e757b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a91417f583c86c4ea3d7cd7776b1ac95fb430722a6f3882103225046c9947222ab04acdefe2ed5dec4dcb593c5e6ae58e2c61c7ace14d81b70ac68\"}],\"vout\":[{\"satoshis\":\"36010\",\"scriptPubkey\":{\"hex\":\"76a9148ee61a3161993f4f7b7081259bf5f3322d65d3f888ac\"}}]}"); + cJSON *txobj7 = cJSON_Parse("{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"204b0b2033ca8888a52554e0312f72849c72897ef8500e6019a46fd9e51e39816d00\",\"txid\":\"e4a22b8f7d63ed1cdcece6269acde409c2f6d473595f22875baf64b686762ce1\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a91478d98e781618f50be5fa6e340aba02026737888487\"},\"suppress\":1,\"redeemScript\":\"63048615e757b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a91417f583c86c4ea3d7cd7776b1ac95fb430722a6f3882103225046c9947222ab04acdefe2ed5dec4dcb593c5e6ae58e2c61c7ace14d81b70ac68\"}],\"vout\":[{\"satoshis\":\"36010\",\"scriptPubkey\":{\"hex\":\"76a9148ee61a3161993f4f7b7081259bf5f3322d65d3f888ac\"}}]}"); + //0100000001e12c7686b664af5b87225f5973d4f6c209e4cd9a26e6ecdc1ced637d8f2ba2e400000000d147304402200c7c428181b4a87f60e6a6a40dc14000a54e4286dc0c2c72a5f7b649591144d102206b7b376190e857c18c5764070e9d378b09aa0405cda691a1b68df7a2a6ccc2da01204b0b2033ca8888a52554e0312f72849c72897ef8500e6019a46fd9e51e39816d004c6763048615e757b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a91417f583c86c4ea3d7cd7776b1ac95fb430722a6f3882103225046c9947222ab04acdefe2ed5dec4dcb593c5e6ae58e2c61c7ace14d81b70ac68ffffffff01aa8c0000000000001976a9148ee61a3161993f4f7b7081259bf5f3322d65d3f888ac00000000 + struct vin_info V[3]; int32_t completed; char *signedtx; bits256 txid,signedtxid,checktxid; uint8_t *extraspace; struct iguana_info *coin = iguana_coinfind("BTC"); + memset(V,0,sizeof(V)); + cJSON *tx = txobj7; + char *txbytes = bitcoin_json2hex(myinfo,coin,&txid,tx,V); + printf("rawtx.(%s)\n",txbytes); + extraspace = calloc(1,65536); + txobj = bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&checktxid,0,txbytes,extraspace,65536,0,jobj(tx,"vin"),1); + printf("\nTXOBJ.(%s)\n\n",jprint(txobj,0)); + if ( (signedtx= iguana_signrawtx(myinfo,coin,1000000,&signedtxid,&completed,jobj(txobj,"vin"),txbytes,privkeys,V)) != 0 ) + printf("signedtx.(%s)\n",signedtx); + free(extraspace); + //getchar(); + }*/ } now = (uint32_t)time(NULL); coin->idletime = 0; - if ( coin->started != 0 && coin->active != 0 ) + if ( coin->started != 0 && coin->active != 0 && (coin->notarychain < 0 || coin->FULLNODE == 0) ) { //printf("%s numranked.%d isRT.%d numsaved.%d M.%d L.%d numverified.%d hdrsi.%d\n",coin->symbol,coin->peers->numranked,coin->isRT,coin->numsaved,coin->blocks.hwmchain.height,coin->longestchain,coin->numverified,coin->current!=0?coin->current->hdrsi:-1); if ( coin->peers->numranked > 4 && coin->isRT == 0 && now > coin->startutc+77 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) @@ -804,13 +956,7 @@ void iguana_coinloop(void *arg) if ( coin->MAXPEERS > IGUANA_MINPEERS ) coin->MAXPEERS = IGUANA_MINPEERS; } - /*if ( coin->isRT != 0 && coin->current != 0 && coin->numverified >= coin->current->hdrsi ) - { - //static int32_t saved; - //if ( saved++ == 0 ) - // iguana_coinflush(coin,1); - }*/ - if ( RELAYID >= 0 ) + if ( myinfo->NOTARY.RELAYID < 0 ) { if ( coin->bindsock >= 0 ) { @@ -826,8 +972,25 @@ void iguana_coinloop(void *arg) { if ( coin->MAXPEERS > 1 && coin->peers->numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible+10 ) { - if ( coin->peers->numranked > 0 && (now % 60) == 0 ) - iguana_send_ping(myinfo,coin,coin->peers->ranked[rand() % coin->peers->numranked]); + if ( coin->peers != 0 ) + { + for (j=0; jpeers->active[(i+j) % IGUANA_MAXPEERS]; + if ( addr->usock >= 0 && addr->msgcounts.verack == 0 ) + { + //printf("i.%d j.%d mainloop %s\n",i,j,addr->ipaddr); + iguana_send_version(coin,addr,coin->myservices); + break; + } + } + } + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) + { + if ( coin->peers->numranked > 0 ) + iguana_send_ping(myinfo,coin,coin->peers->ranked[rand() % coin->peers->numranked]); + } coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers } } @@ -836,21 +999,24 @@ void iguana_coinloop(void *arg) coin->peers->lastmetrics = iguana_updatemetrics(myinfo,coin); // ranks peers } } - if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 || coin->MAXPEERS == 1 ) + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 || coin->MAXPEERS == 1 ) { - portable_mutex_lock(&coin->allcoins_mutex); + //portable_mutex_lock(&coin->allcoins_mutex); + coin->busy_processing = 1; flag += iguana_processrecv(myinfo,coin); - portable_mutex_unlock(&coin->allcoins_mutex); - if ( strcmp(coin->symbol,"BTCD") == 0 && coin->RTheight > 0 && coin->RTheight > coin->chain->bundlesize ) + coin->busy_processing = 0; + //portable_mutex_unlock(&coin->allcoins_mutex); + /*if ( strcmp(coin->symbol,"BTCD") == 0 && coin->RTheight > 0 && coin->RTheight > coin->chain->bundlesize ) { int32_t hdrsi,nonz,errs; struct iguana_pkhash *refP; struct iguana_bundle *bp; hdrsi = (coin->RTheight / coin->chain->bundlesize) - 1; if ( 0 && (bp= coin->bundles[hdrsi]) != 0 && bp->weights == 0 ) bp->weights = iguana_PoS_weights(myinfo,coin,&refP,&bp->supply,&bp->numweights,&nonz,&errs,bp->bundleheight); - } + }*/ } } coin->idletime = (uint32_t)time(NULL); + iguana_jsonQ(myinfo,coin); } } //iguana_jsonQ(); @@ -897,6 +1063,7 @@ void iguana_nameset(char name[64],char *symbol,cJSON *json) struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json,int32_t virtcoin) { struct iguana_chain *iguana_createchain(cJSON *json); + struct supernet_info *myinfo = SuperNET_MYINFO(0); struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char name[64]; cJSON *peers; mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS; iguana_nameset(name,symbol,json); @@ -912,7 +1079,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, if ( (coin->MAXRECVCACHE= maxrecvcache) == 0 ) coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; if ( (coin->MAXPENDINGREQUESTS= maxrequests) <= 0 ) - coin->MAXPENDINGREQUESTS = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDINGREQUESTS : IGUANA_PENDINGREQUESTS; + coin->MAXPENDINGREQUESTS = (strcmp(symbol,"BTC") == 0) ? IGUANA_BTCPENDINGREQUESTS : IGUANA_PENDINGREQUESTS; if ( jobj(json,"prefetchlag") != 0 ) coin->PREFETCHLAG = jint(json,"prefetchlag"); else if ( strcmp("BTC",coin->symbol) == 0 ) @@ -920,6 +1087,8 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, else coin->PREFETCHLAG = -1; if ( (coin->MAXSTUCKTIME= juint(json,"maxstuck")) == 0 ) coin->MAXSTUCKTIME = _IGUANA_MAXSTUCKTIME; + if ( myinfo != 0 && myinfo->seedipaddr[0] != 0 ) + safecopy(coin->seedipaddr,myinfo->seedipaddr,sizeof(coin->seedipaddr)); if ( (coin->startPEND= juint(json,"startpend")) == 0 ) { if ( strcmp("BTCD",coin->symbol) == 0 ) @@ -945,6 +1114,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->startPEND = coin->endPEND = 1; #endif } else coin->MAXPEERS = 0; + coin->notarychain = iguana_isnotarychain(coin->symbol); coin->myservices = services; coin->initialheight = initialheight; coin->mapflags = mapflags; @@ -963,23 +1133,25 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) coin->polltimeout = IGUANA_DEFAULT_POLLTIMEOUT; coin->active = juint(json,"active"); - if ( (coin->minconfirms = minconfirms) == 0 ) + if ( (coin->minconfirms= minconfirms) == 0 ) coin->minconfirms = (strcmp(symbol,"BTC") == 0) ? 3 : 10; + if ( jobj(json,"RELAY") != 0 ) + coin->FULLNODE = jint(json,"RELAY"); + else coin->FULLNODE = (strcmp(coin->symbol,"BTCD") == 0); + if ( jobj(json,"VALIDATE") != 0 ) + coin->VALIDATENODE = juint(json,"VALIDATE"); + else coin->VALIDATENODE = (strcmp(coin->symbol,"BTCD") == 0); + if ( coin->VALIDATENODE > 0 || coin->FULLNODE > 0 ) + SuperNET_MYINFO(0)->IAMRELAY++; if ( coin->chain == 0 && (coin->chain= iguana_createchain(json)) == 0 ) { printf("cant initialize chain.(%s)\n",jstr(json,0)); strcpy(coin->name,"illegalcoin"); + //if ( coin->FULLNODE >= 0 ) + // coin->chain->userpass[0] = 0; coin->symbol[0] = 0; return(0); } - if ( jobj(json,"RELAY") != 0 ) - coin->FULLNODE = juint(json,"RELAY"); - else coin->FULLNODE = (strcmp(coin->symbol,"BTCD") == 0); - if ( jobj(json,"VALIDATE") != 0 ) - coin->VALIDATENODE = juint(json,"VALIDATE"); - else coin->VALIDATENODE = (strcmp(coin->symbol,"BTCD") == 0); - if ( coin->VALIDATENODE != 0 || coin->FULLNODE != 0 ) - SuperNET_MYINFO(0)->IAMRELAY++; #ifdef __PNACL coin->VALIDATENODE = coin->FULLNODE = 0; #endif @@ -1023,10 +1195,13 @@ int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json, coins = mycalloc('A',1+1,sizeof(*coins)); if ( (coin= iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,json,virtcoin)) != 0 ) { - coins[0] = (void *)((long)1); - coins[1] = coin; - printf("launch.%p coinloop for.%s services.%llx started.%p peers.%p\n",coin,coin->symbol,(long long)services,coin->started,coin->peers); - coin->launched = iguana_launch(coin,"iguana_coinloop",iguana_coinloop,coins,IGUANA_PERMTHREAD); + if ( iguana_isnotarychain(coin->symbol) < 0 || coin->FULLNODE >= 0 ) + { + coins[0] = (void *)((long)1); + coins[1] = coin; + printf("launch.%p coinloop for.%s services.%llx started.%p peers.%p\n",coin,coin->symbol,(long long)services,coin->started,coin->peers); + coin->launched = iguana_launch(coin,"iguana_coinloop",iguana_coinloop,coins,IGUANA_PERMTHREAD); + } coin->active = 1; coin->started = 0; return(1); @@ -1100,3 +1275,4 @@ char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *dest printf("busdata_sync.(%s)\n",jsonstr); return(0); } + diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 7768f23ef..eb058e620 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,18 +13,53 @@ * * ******************************************************************************/ +/* + adding assetchain coin: copy genCOIN to SuperNET/iguana/coins, make a _7776 variant with RELAY=-1 and VALIDATE=0 + copy that into basilisk as coin, changing RELAY -> 0 + */ + +/* + To add a new dPoW'ed assetchain with DEX* API support: + 1. add to komodo/src: assetchains, assetchains.old, dpowassets, fiat-cli + 2. add to end of NOTARY_CURRENCIES[] array in fundnotaries (iguana_notary.c) + 3. create fiat/ + 4. add to m_notary coins/ get gen_acname from where komodod was launched, change RELAY:-1 and port to 7776 and make _7776 variant + 5. make coins/basilisk/ + 6. launch from a single node with -gen, launch a second node using -addnode= but without -gen + 7. from a single node, fundnotaries to get notaries able to dPoW + 8. m_splitfunds + + */ + #ifndef iguana777_net_h #define iguana777_net_h +#if defined(_WIN32) || defined(_WIN64) +#ifndef WIN32 +#define WIN32 +#endif +#endif + #if (defined(_WIN32) || defined(__WIN32__)) && \ !defined(WIN32) && !defined(__SYMBIAN32__) +#ifndef WIN32 #define WIN32 +#endif +#endif + +#ifdef WIN32 +#define __MINGW + + #else #ifndef __MINGW #include #endif #endif +#define LOCKTIME_THRESHOLD 500000000 +#define KOMODO_INTEREST ((uint64_t)(0.05 * SATOSHIDEN)) // 5% CANNOT CHANGE as komodo_interest.h div 20 + //#define BTC2_VERSION #define BTC2_HARDFORK_HEIGHT 444444 #define BTC2_SIGHASH_FORKID 0xcf @@ -32,6 +67,28 @@ #define BTC2_DEFAULT_PORT 8222 #define BTC2_DIFF_WINDOW 60 +/*#ifdef __APPLE__ +#define ISNOTARYNODE 1 +#include "nn.h" +#include "bus.h" +#else*/ +//#ifdef __APPLE__ +#if defined(__APPLE__) || defined(WIN32) || defined(USE_STATIC_NANOMSG) +#include "../crypto777/nanosrc/nn.h" +#include "../crypto777/nanosrc/bus.h" +#include "../crypto777/nanosrc/pubsub.h" +#include "../crypto777/nanosrc/pipeline.h" +#include "../crypto777/nanosrc/reqrep.h" +#include "../crypto777/nanosrc/tcp.h" +#else +#include "/usr/local/include/nanomsg/nn.h" +#include "/usr/local/include/nanomsg/bus.h" +#include "/usr/local/include/nanomsg/pubsub.h" +#include "/usr/local/include/nanomsg/pipeline.h" +#include "/usr/local/include/nanomsg/reqrep.h" +#include "/usr/local/include/nanomsg/tcp.h" +#endif + struct supernet_info; struct exchange_info; @@ -41,11 +98,8 @@ struct exchange_info; #include "../includes/iguana_defines.h" #include "../includes/iguana_types.h" #include "../includes/iguana_structs.h" -#include "../includes/iguana_funcs.h" -#include "../includes/iguana_globals.h" #include "../basilisk/basilisk.h" -#include "../gecko/gecko.h" - +#include "dPoW.h" struct supernet_address { @@ -54,37 +108,126 @@ struct supernet_address char NXTADDR[32],BTC[64],BTCD[64]; }; -struct liquidity_info { char base[64],rel[64]; double profit,refprice; }; +struct smartaddress_symbol { double maxbid,minask,srcavail,destamount; char symbol[16]; }; + +struct smartaddress +{ + bits256 privkey,pubkey; + int32_t numsymbols; + uint8_t pubkey33[33],rmd160[20]; + char typestr[16]; + struct smartaddress_symbol *symbols; +}; + +struct pending_trade { UT_hash_handle hh; double basevolume,relvolume,dir; char base[32],rel[32]; }; + +#define PSOCK_IDLETIMEOUT 600 +struct psock { uint32_t lasttime; int32_t pullsock,pubsock; uint16_t pushport,subport; }; + +#define JUMBLR_DEPOSITPREFIX "deposit " +struct jumblr_item +{ + UT_hash_handle hh; + int64_t amount,fee,txfee; + uint32_t spent,pad; + char opid[64],src[128],dest[128],status; +}; + +struct liquidity_info +{ + char base[16],rel[16],exchange[16]; + uint64_t assetid; + double profit,refprice,bid,ask,minvol,maxvol,totalvol; +}; + struct message_info { int32_t msgcount; bits256 refhash,msghashes[64]; uint32_t timestamps[64]; }; struct supernet_info { struct supernet_address myaddr; - bits256 persistent_priv,privkey; + bits256 persistent_priv,privkey,jumblr_pubkey,jumblr_depositkey; uint8_t persistent_pubkey33[33]; - char ipaddr[64],NXTAPIURL[512],secret[4096],password[4096],rpcsymbol[64],handle[1024],permanentfile[1024]; + char ipaddr[64],NXTAPIURL[512],secret[4096],password[4096],rpcsymbol[64],handle[1024],permanentfile[1024],jumblr_passphrase[1024]; char *decryptstr; - int32_t maxdelay,IAMRELAY,IAMLP,publicRPC,basilisk_busy,genesisresults; - uint32_t expiration,dirty,DEXactive; + void (*liquidity_command)(struct supernet_info *myinfo,char *base,bits256 hash,cJSON *vals); + double (*liquidity_active)(struct supernet_info *myinfo,double *refpricep,char *exchange,char *base,char *rel,double volume); + int32_t maxdelay,IAMRELAY,IAMNOTARY,IAMLP,publicRPC,basilisk_busy,genesisresults,remoteorigin; + uint32_t expiration,dirty,DEXactive,DEXpoll,totalcoins,nanoinit,lastdexrequestid,dexcrcs[1024]; uint16_t argport,rpcport; struct basilisk_info basilisks; + struct jumblr_item *jumblrs; struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges; struct iguana_waccount *wallet; struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; - portable_mutex_t bu_mutex,allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex; - struct queueitem *DEX_quotes; + portable_mutex_t bu_mutex,allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex,smart_mutex; + struct queueitem *DEX_quotes; cJSON *Cunspents,*Cspends; struct basilisk_swap *swaps[256]; int32_t numswaps; - struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ; + struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ,p2pQ; void *ctx; uint8_t *pingbuf; + struct basilisk_request DEXaccept; + FILE *dexfp; + struct dpow_info DPOWS[128]; int32_t numdpows,dpowsock,dexsock,pubsock,repsock,subsock,reqsock; struct delayedPoW_info dPoW; struct basilisk_spend *spends; int32_t numspends; - struct peggy_info *PEGS; - struct liquidity_info linfos[64]; + char bindaddr[64]; + char blocktrail_apikey[256]; + struct peggy_info *PEGS; + void *PAXDATA; + struct liquidity_info linfos[512]; cJSON *liquidity_currencies; struct pending_trade *trades; portable_mutex_t pending_mutex; + struct komodo_notaries NOTARY; + char seedipaddr[64]; uint32_t dpowipbits[128]; int32_t numdpowipbits; portable_mutex_t notarymutex,dpowmutex; +#ifdef NOTARY_TESTMODE + char dexseed_ipaddrs[1][64]; +#else + char dexseed_ipaddrs[4][64]; +#endif + uint32_t dexipbits[128]; int32_t numdexipbits; portable_mutex_t dexmutex; // compatibility bits256 pangea_category,instantdex_category; uint8_t logs[256],exps[510]; struct message_info msgids[8192]; + double *svmfeatures; + uint16_t psockport,numpsocks; struct psock *PSOCKS; portable_mutex_t psockmutex; + uint8_t notaries[64][33]; int32_t numnotaries,DEXEXPLORER; + FILE *swapsfp; + double DEXratio; + struct smartaddress smartaddrs[64]; int32_t numsmartaddrs,cancelrefresh,runsilent,DEXtrades; +}; + +struct basilisk_swapmessage +{ + bits256 srchash,desthash; + uint32_t crc32,msgbits,quoteid,datalen; + uint8_t *data; }; +struct basilisk_swap +{ + struct supernet_info *myinfoptr; struct iguana_info *bobcoin,*alicecoin; + void (*balancingtrade)(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob); + int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; uint32_t lasttime,aborted; + FILE *fp; + bits256 persistent_privkey,persistent_pubkey; + struct basilisk_swapinfo I; + struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; + bits256 privkeys[INSTANTDEX_DECKSIZE]; + struct basilisk_swapmessage *messages; int32_t nummessages; + char Bdeposit[64],Bpayment[64]; + uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; + uint8_t persistent_pubkey33[33],pad[15],verifybuf[65536]; + +}; + +#include "../includes/iguana_funcs.h" +#include "../includes/iguana_globals.h" +#include "../gecko/gecko.h" + +#ifndef MAX +#define MAX(a,b) ((a) >= (b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + #endif diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 6e2895a33..2463a09a8 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,6 +13,19 @@ * * ******************************************************************************/ + /** + * - we need to include WinSock2.h header to correctly use windows structure + * as the application is still using 32bit structure from mingw so, we need to + * add the include based on checking + * @author - fadedreamz@gmail.com + * @remarks - #if (defined(_M_X64) || defined(__amd64__)) && defined(WIN32) + * is equivalent to #if defined(_M_X64) as _M_X64 is defined for MSVC only + */ +#if defined(_M_X64) +#define WIN32_LEAN_AND_MEAN +#include +#endif + #include "iguana777.h" #include "exchanges777.h" @@ -20,10 +33,28 @@ struct iguana_accept { struct queueitem DL; char ipaddr[64]; uint32_t ipbits; in int32_t iguana_acceptspoll(uint8_t *buf,int32_t bufsize,struct iguana_accept *accepts,int32_t num,int32_t timeout) { + /** + * This solution is for win64 + * 2^11*sizeof(struct fd) for win64 bit gives a very big number + * for that reason it cannot allocate memory from stack + * so the solution is to allocate memory from heap, instead of stack + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + struct pollfd * fds; + int32_t i, j, n, r, nonz, flag; struct iguana_accept *ptr; + if (num == 0) + return(0);; + fds = (struct pollfd *) malloc(sizeof(struct pollfd) * IGUANA_MAXPEERS); + if (NULL == fds) + return -1; + memset(fds, 0, sizeof(struct pollfd) * IGUANA_MAXPEERS); +#else struct pollfd fds[IGUANA_MAXPEERS]; int32_t i,j,n,r,nonz,flag; struct iguana_accept *ptr; if ( num == 0 ) return(0);; memset(fds,0,sizeof(fds)); +#endif flag = 0; r = (rand() % num); for (j=n=nonz=0; jrpcport ) // return; sleep(5); } @@ -98,18 +138,21 @@ void iguana_acceptloop(void *args) } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(ipaddr,ipbits); - printf("incoming (%s:%u)\n",ipaddr,cli_addr.sin_port); + //printf("incoming %s (%s:%u)\n",coin->symbol,ipaddr,cli_addr.sin_port); for (i=flag=0; ipeers->active[i].ipbits == (uint32_t)ipbits && coin->peers->active[i].usock >= 0 ) + addr = &coin->peers->active[i]; + if ( addr->ipbits == (uint32_t)ipbits && addr->usock >= 0 ) { - printf("found existing peer.(%s) in slot[%d]\n",ipaddr,i); - close(coin->peers->active[i].usock); - coin->peers->active[i].dead = 0; - coin->peers->active[i].usock = sock; - coin->peers->active[i].A.port = cli_addr.sin_port; - coin->peers->active[i].ready = (uint32_t)time(NULL); + //printf("found existing %s peer.(%s) in slot[%d]\n",coin->symbol,ipaddr,i); + close(addr->usock); + addr->dead = 0; + addr->usock = sock; + addr->A.port = cli_addr.sin_port; + addr->ready = (uint32_t)time(NULL); flag = 1; + iguana_send_version(coin,addr,coin->myservices); + //instantdex_peerhas_clear(coin,&coin->peers->active[i]); //iguana_iAkill(coin,&coin->peers->active[i],0); //sleep(1); @@ -118,7 +161,7 @@ void iguana_acceptloop(void *args) } if ( flag != 0 ) continue; - printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); + printf("%s NEWSOCK.%d for %x (%s)\n",coin->symbol,sock,ipbits,ipaddr); /*if ( (uint32_t)ipbits == myinfo->myaddr.myipbits ) { @@ -131,11 +174,11 @@ void iguana_acceptloop(void *args) ptr->sock = sock; ptr->port = cli_addr.sin_port; printf("queue PENDING ACCEPTS\n"); - queue_enqueue("acceptQ",&coin->acceptQ,&ptr->DL,0); + queue_enqueue("acceptQ",&coin->acceptQ,&ptr->DL); } else { - printf("LAUNCH DEDICATED THREAD for %s:%u\n",ipaddr,cli_addr.sin_port); + printf("LAUNCH %s DEDICATED THREAD for %s:%u\n",coin->symbol,ipaddr,cli_addr.sin_port); addr->usock = sock; addr->dead = 0; addr->A.port = cli_addr.sin_port; @@ -149,18 +192,18 @@ void iguana_acceptloop(void *args) int32_t iguana_pendingaccept(struct iguana_info *coin) { struct iguana_accept *ptr; char ipaddr[64]; struct iguana_peer *addr; - if ( (ptr= queue_dequeue(&coin->acceptQ,0)) != 0 ) + if ( (ptr= queue_dequeue(&coin->acceptQ)) != 0 ) { if ( (addr= iguana_peerslot(coin,ptr->ipbits,0)) != 0 ) { expand_ipbits(ipaddr,ptr->ipbits); - printf("iguana_pendingaccept LAUNCH DEDICATED THREAD for %s\n",ipaddr); + printf("iguana_pendingaccept %s LAUNCH DEDICATED THREAD for %s\n",coin->symbol,ipaddr); addr->usock = ptr->sock; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); myfree(ptr,sizeof(*ptr)); return(1); - } else queue_enqueue("requeue_acceptQ",&coin->acceptQ,&ptr->DL,0); + } else queue_enqueue("requeue_acceptQ",&coin->acceptQ,&ptr->DL); } return(0); } @@ -182,13 +225,13 @@ void iguana_msgrequestQ(struct iguana_info *coin,struct iguana_peer *addr,int32_ msg->addr = addr; msg->hash2 = hash2; msg->type = type; - queue_enqueue("msgrequest",&coin->msgrequestQ,&msg->DL,0); + queue_enqueue("msgrequest",&coin->msgrequestQ,&msg->DL); } int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin) { struct iguana_peermsgrequest *msg; int32_t height,len,flag = 0; bits256 checktxid; struct iguana_txid *tx,T; struct iguana_peer *addr; - if ( (msg= queue_dequeue(&coin->msgrequestQ,0)) != 0 ) + if ( (msg= queue_dequeue(&coin->msgrequestQ)) != 0 ) { flag = 1; if ( msg->addr != 0 ) @@ -196,9 +239,9 @@ int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_in //char str[65]; printf("send type.%d %s -> (%s)\n",msg->type,bits256_str(str,msg->hash2),msg->addr->ipaddr); if ( msg->type == MSG_BLOCK ) { - if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) { - if ( (addr= msg->addr) != 0 && (len= iguana_peerblockrequest(coin,coin->blockspace,(int32_t)(coin->blockspacesize - sizeof(struct iguana_msghdr)),0,msg->hash2,0)) > 0 ) + if ( (addr= msg->addr) != 0 && (len= iguana_peerblockrequest(myinfo,coin,coin->blockspace,(int32_t)(coin->blockspacesize - sizeof(struct iguana_msghdr)),0,msg->hash2,0)) > 0 ) { //char str[65]; printf("msg Sendlen.%d block %s to %s\n",len,bits256_str(str,msg->hash2),addr->ipaddr); iguana_queue_send(addr,0,coin->blockspace,"block",len); @@ -207,7 +250,7 @@ int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_in } else if ( msg->type == MSG_TX ) { - if ( coin->FULLNODE != 0 || coin->VALIDATENODE ) + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) { if ( (tx= iguana_txidfind(coin,&height,&T,msg->hash2,coin->bundlescount-1)) != 0 ) { @@ -288,11 +331,11 @@ int32_t iguana_inv2packet(uint8_t *serialized,int32_t maxsize,int32_t type,bits2 return(len - sizeof(struct iguana_msghdr)); } -int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block) +int32_t iguana_headerget(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block) { - bits256 checkhash2; struct iguana_msgblock msgB; int32_t len = 0; - iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&msgB,block,1); - if ( (len= iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&serialized[sizeof(struct iguana_msghdr)],&msgB,(int32_t)(maxsize-sizeof(struct iguana_msghdr)))) < 0 ) + bits256 checkhash2; struct iguana_msgzblock zmsgB; int32_t len = 0; + iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&zmsgB,(void *)block,1); + if ( (len= iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&serialized[sizeof(struct iguana_msghdr)],&zmsgB,(int32_t)(maxsize-sizeof(struct iguana_msghdr)))) < 0 ) return(-1); if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) { @@ -305,8 +348,8 @@ int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t ma int32_t iguana_peerhdrrequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2) { - int32_t len=0,i,flag=0,height,n,hdrsi,bundlei,bundlesize,firstvout,retval=-1; struct iguana_block *block; struct iguana_bundle *bp; - if ( coin->RTheight > 0 && (firstvout= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,hash2,0,coin->bundlescount-1,0)) != 0 ) + int32_t len=0,i,flag=0,height,n,hdrsi,bundlei,bundlesize,retval=-1; struct iguana_block *block; struct iguana_bundle *bp; struct iguana_outpoint outpt; + if ( coin->RTheight > 0 && iguana_RTunspentindfind(myinfo,coin,&outpt,0,0,0,0,&height,hash2,0,coin->bundlescount-1,0) == 0 ) { bundlesize = coin->chain->bundlesize; hdrsi = (height / bundlesize); @@ -317,7 +360,7 @@ int32_t iguana_peerhdrrequest(struct supernet_info *myinfo,struct iguana_info *c { if ( (block= bp->blocks[i]) != 0 ) { - if ( (n= iguana_headerget(coin,&serialized[len],maxsize-len,block)) < 0 ) + if ( (n= iguana_headerget(myinfo,coin,&serialized[len],maxsize-len,block)) < 0 ) { printf("%s error getting header ht.%d\n",coin->symbol,block->height); continue; @@ -326,7 +369,7 @@ int32_t iguana_peerhdrrequest(struct supernet_info *myinfo,struct iguana_info *c } else printf("cant find block at ht.%d\n",height+i); } } - if ( 0 && flag != 0 && strcmp("BTCD",coin->symbol) != 0 ) + if ( (0) && flag != 0 && strcmp("BTCD",coin->symbol) != 0 ) retval = iguana_queue_send(addr,0,serialized,"headers",len); //printf("hdrs request retval.%d len.%d\n",retval,len); } //else printf("couldnt find header\n"); @@ -350,7 +393,7 @@ int32_t iguana_peergetrequest(struct supernet_info *myinfo,struct iguana_info *c break; if ( flag == 0 ) { - if ( getblock != 0 && iguana_peerblockrequest(coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,hash2,0) > 0 ) + if ( getblock != 0 && iguana_peerblockrequest(myinfo,coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,hash2,0) > 0 ) flag = 1; else if ( getblock == 0 && iguana_peerhdrrequest(myinfo,coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,hash2) > 0 ) flag = 1; @@ -403,4 +446,4 @@ int32_t iguana_peeraddrrequest(struct iguana_info *coin,struct iguana_peer *addr if ( x == 0 ) return(-1); return(sendlen); -} \ No newline at end of file +} diff --git a/iguana/iguana_bitmap.c b/iguana/iguana_bitmap.c index 51f97f3e9..89effe210 100755 --- a/iguana/iguana_bitmap.c +++ b/iguana/iguana_bitmap.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -116,6 +116,7 @@ void gen_ppmfile(char *fname,int32_t binaryflag,uint8_t *bitmap,int32_t width,in void gen_jpegfile(char *fname,int32_t quality,uint8_t *bitmap,int32_t width,int32_t height) { +#ifdef later struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE * outfile; /* target file */ @@ -126,7 +127,7 @@ void gen_jpegfile(char *fname,int32_t quality,uint8_t *bitmap,int32_t width,int3 if ( (outfile= fopen(fname,"wb")) == NULL) { fprintf(stderr, "can't open %s\n", fname); - exit(1); + iguana_exit(0,0); } jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = width; /* image width and height, in pixels */ @@ -145,6 +146,7 @@ void gen_jpegfile(char *fname,int32_t quality,uint8_t *bitmap,int32_t width,int3 jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); +#endif } /* @@ -399,8 +401,8 @@ void disp_yval(register int32_t color,register float yval,register uint32_t *bit //if ( pixelwt(color) > pixelwt(bitmap[y*rowwidth + x]) ) bitmap[y*rowwidth + x] = pixel_blend(bitmap[y*rowwidth + x],color); return; - if ( is_primary_color(color) != 0 || (is_primary_color(bitmap[y*rowwidth+x]) == 0 && pixelwt(color) > pixelwt(bitmap[y*rowwidth + x])) ) - bitmap[y*rowwidth + x] = color; + //if ( is_primary_color(color) != 0 || (is_primary_color(bitmap[y*rowwidth+x]) == 0 && pixelwt(color) > pixelwt(bitmap[y*rowwidth + x])) ) + // bitmap[y*rowwidth + x] = color; } void disp_yvalsum(register int32_t color,register float yval,register uint32_t *bitmap,register int32_t x,register int32_t rowwidth,register int32_t height) @@ -507,7 +509,7 @@ void output_line(int32_t calclogflag,double ave,float *buf,int32_t n,int32_t col double src[1024],dest[1024]; int32_t i; memset(src,0,sizeof(src)); memset(dest,0,sizeof(dest)); - if ( 1 ) + if ( (1) ) { for (i=0; i<1024; i++) src[1023-i] = dest[1023-i] = buf[i]; @@ -1083,7 +1085,7 @@ void iguana_bitmapbundle(struct iguana_info *coin,uint8_t *rect,int32_t rowwidth struct iguana_bitmap *iguana_bitmapfind(char *name) { - struct iguana_info *coin; int32_t width,height,n,hdrsi,x,y; + struct iguana_info *coin; int32_t width=1,height=1,n,hdrsi,x,y; if ( ((coin= iguana_coinfind(name)) != 0 || (coin= iguana_coinfind("BTCD")) != 0) && coin->screen != 0 ) { strcpy(coin->screen->name,coin->symbol); @@ -1160,42 +1162,3 @@ void iguana_bitmap(char *space,int32_t max,char *name) } } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -STRING_AND_TWOINTS(mouse,change,name,x,y) -{ - printf("mouse (%s) x.%d y.%d\n",name,x,y); - return(clonestr("{\"result\":\"changed\"}")); -} - -STRING_ARG(mouse,leave,name) -{ - printf("mouse (%s) leave\n",name); - return(clonestr("{\"result\":\"left\"}")); -} - -STRING_AND_TWOINTS(mouse,click,name,x,y) -{ - printf("mouse (%s) x.%d y.%d click\n",name,x,y); - return(clonestr("{\"result\":\"click\"}")); -} - -STRING_AND_INT(keyboard,key,name,c) -{ - printf(" KEY.(%s) c.%d (%c)\n",name,c,c); - return(clonestr("{\"result\":\"key\"}")); -} - -STRING_AND_TWOINTS(mouse,image,name,x,y) -{ - printf("mouse CREATE (%s) x.%d y.%d\n",name,x,y); - return(clonestr("{\"result\":\"opened\"}")); -} - -STRING_ARG(mouse,close,name) -{ - printf("mouse CLOSE (%s)\n",name); - return(clonestr("{\"result\":\"closed\"}")); -} -#include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 511303f6f..3c65b069c 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -17,49 +17,74 @@ #define iguana_blockfind(str,coin,hash2) iguana_blockhashset(str,coin,-1,hash2,0) -void iguana_blockconv(uint8_t zcash,uint8_t auxpow,struct iguana_block *dest,struct iguana_msgblock *msg,bits256 hash2,int32_t height) //uint32_t numtxids,uint32_t numunspents,uint32_t numspends,double PoW) +int32_t iguana_blockconv(uint8_t zcash,uint8_t auxpow,struct iguana_zblock *zdest,struct iguana_msgzblock *zmsg,bits256 hash2,int32_t height) //uint32_t numtxids,uint32_t numunspents,uint32_t numspends,double PoW) { - int32_t i; - memset(dest,0,sizeof(*dest)); - dest->RO.version = msg->H.version; - dest->RO.prev_block = msg->H.prev_block; - dest->RO.merkle_root = msg->H.merkle_root; - dest->RO.timestamp = msg->H.timestamp; - dest->RO.bits = msg->H.bits; - dest->RO.txn_count = msg->txn_count; - dest->height = height; - dest->RO.hash2 = hash2; + int32_t i; struct iguana_block *dest = (void *)zdest; struct iguana_msgblock *msg = (void *)zmsg; if ( zcash == 0 ) + { + memset(dest,0,sizeof(*dest)); + dest->RO.version = msg->H.version; + dest->RO.prev_block = msg->H.prev_block; + dest->RO.merkle_root = msg->H.merkle_root; + dest->RO.timestamp = msg->H.timestamp; + dest->RO.bits = msg->H.bits; + dest->RO.txn_count = msg->txn_count; + dest->height = height; + dest->RO.hash2 = hash2; dest->RO.nonce = msg->H.nonce; + return(msg->txn_count); + } else { - dest->RO.allocsize = (int32_t)(sizeof(*dest) + sizeof(*dest->zRO)); - dest->zRO[0].bignonce = msg->zH.bignonce; + zdest->RO.allocsize = (int32_t)sizeof(struct iguana_zblock); + zdest->RO.txn_count = zmsg->txn_count; + zdest->RO.hash2 = hash2; + zdest->height = height; + zdest->RO.version = zmsg->zH.version; + zdest->RO.prev_block = zmsg->zH.prev_block; + zdest->RO.merkle_root = zmsg->zH.merkle_root; + zdest->RO.timestamp = zmsg->zH.timestamp; + zdest->RO.bits = zmsg->zH.bits; + zdest->zRO.bignonce = zmsg->zH.bignonce; + if ( iguana_rwvarint32(0,zmsg->zH.var_numelements,&zdest->zRO.numelements) != sizeof(zmsg->zH.var_numelements) ) + printf("unexpected varint size for zmsg.zH.numelements <- %d\n",zdest->zRO.numelements); for (i=0; izRO[0].solution[i] = msg->zH.solution[i]; + zdest->zRO.solution[i] = zmsg->zH.solution[i]; + return(zmsg->txn_count); } } -void iguana_blockunconv(uint8_t zcash,uint8_t auxpow,struct iguana_msgblock *msg,struct iguana_block *src,int32_t cleartxn_count) +void iguana_blockunconv(uint8_t zcash,uint8_t auxpow,struct iguana_msgzblock *zmsg,struct iguana_zblock *zsrc,int32_t cleartxn_count) { - int32_t i; - memset(msg,0,sizeof(*msg)); - msg->H.version = src->RO.version; - msg->H.prev_block = src->RO.prev_block; - msg->H.merkle_root = src->RO.merkle_root; - msg->H.timestamp = src->RO.timestamp; - msg->H.bits = src->RO.bits; - if ( zcash == 0 ) - msg->H.nonce = src->RO.nonce; + int32_t i; struct iguana_msgblock *msg = (void *)zmsg; struct iguana_block *src = (void *)zsrc; + if ( zcash != 0 ) + { + memset(zmsg,0,sizeof(*zmsg)); + zmsg->zH.version = zsrc->RO.version; + zmsg->zH.prev_block = zsrc->RO.prev_block; + zmsg->zH.merkle_root = zsrc->RO.merkle_root; + zmsg->zH.timestamp = zsrc->RO.timestamp; + zmsg->zH.bits = zsrc->RO.bits; + zmsg->zH.bignonce = zsrc->zRO.bignonce; + if ( iguana_rwvarint32(1,zmsg->zH.var_numelements,&zsrc->zRO.numelements) != sizeof(zmsg->zH.var_numelements) ) + printf("unexpected varint size for zmsg.zH.numelements <- %d\n",zsrc->zRO.numelements); + for (i=0; izRO.numelements; i++) + zmsg->zH.solution[i] = zsrc->zRO.solution[i]; + if ( cleartxn_count == 0 ) + zmsg->txn_count = zsrc->RO.txn_count; + } else { - msg->zH.bignonce = src->zRO[0].bignonce; - msg->zH.numelements = ZCASH_SOLUTION_ELEMENTS; - for (i=0; izH.solution[i] = src->zRO[0].solution[i]; + memset(msg,0,sizeof(*msg)); + msg->H.version = src->RO.version; + msg->H.prev_block = src->RO.prev_block; + msg->H.merkle_root = src->RO.merkle_root; + msg->H.timestamp = src->RO.timestamp; + msg->H.bits = src->RO.bits; + msg->H.nonce = src->RO.nonce; + if ( cleartxn_count == 0 ) + msg->txn_count = src->RO.txn_count; } - if ( cleartxn_count == 0 ) - msg->txn_count = src->RO.txn_count; } void iguana_blockcopy(uint8_t zcash,uint8_t auxpow,struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock) @@ -100,11 +125,14 @@ void iguana_blockcopy(uint8_t zcash,uint8_t auxpow,struct iguana_info *coin,stru iguana_blocksizecheck("blockcopy src",coin->chain->zcash,origblock); if ( block->RO.allocsize != origblock->RO.allocsize ) printf("missing space for zcash block.%d origblock.%d\n",block->RO.allocsize,origblock->RO.allocsize); - else + //else { - block->zRO[0].bignonce = origblock->zRO[0].bignonce; + struct iguana_zblock *zblock = (void *)block; + struct iguana_zblock *origzblock = (void *)origblock; + zblock->zRO.bignonce = origzblock->zRO.bignonce; + zblock->zRO.numelements = origzblock->zRO.numelements; for (i=0; izRO[0].solution[i] = origblock->zRO[0].solution[i]; + zblock->zRO.solution[i] = origzblock->zRO.solution[i]; } } } @@ -150,7 +178,7 @@ void _iguana_blocklink(struct iguana_info *coin,struct iguana_block *prev,struct if ( memcmp(block->RO.prev_block.bytes,prev->RO.hash2.bytes,sizeof(bits256)) != 0 ) { printf("illegal blocklink mismatched hashes\n"); - exit(-1); + iguana_exit(0,0); return; } block->hh.prev = prev; @@ -175,39 +203,20 @@ void _iguana_blocklink(struct iguana_info *coin,struct iguana_block *prev,struct struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin,int32_t height,bits256 hash2,int32_t createflag) { struct iguana_block *block,*prev; int32_t size; - /*if ( height > 0 && height > coin->blocks.maxbits ) - { - printf("%s: illegal height.%d when max.%d, or nonz depth.%d\n",debugstr,height,coin->blocks.maxbits,coin->blockdepth); - //getchar(); - return(0); - }*/ - while ( coin->blockdepth > 0 ) - { - usleep(100000); - if ( coin->blockdepth > 0 ) - printf("A %s >>>>>>>>>> OK only if rare %s blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); - //fprintf(stderr,">>>>>>>>>> OK only if rare %s blockhashset.%d depth.%d\n",debugstr,height,depth); - //printf("%d\n",1/(1 - depth/depth)); - } +#ifndef __APPLE__ +#endif + portable_mutex_lock(&coin->blocks_mutex); coin->blockdepth++; HASH_FIND(hh,coin->blocks.hash,&hash2,sizeof(hash2),block); if ( block != 0 ) { if ( coin->blockdepth > 0 ) coin->blockdepth--; - while ( coin->blockdepth > 0 ) - { - usleep(100000); - if ( coin->blockdepth > 0 ) - printf("B %s >>>>>>>>>> OK only if rare %s match blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); - //fprintf(stderr,">>>>>>>>>> OK only if rare%s match blockhashset.%d depth.%d\n",debugstr,height,depth); - //printf("%d\n",1/(1 - depth/depth)); - } + portable_mutex_unlock(&coin->blocks_mutex); return(block); } if ( createflag > 0 ) { - portable_mutex_lock(&coin->blocks_mutex); size = (int32_t)((coin->chain->zcash != 0) ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block)); block = calloc(1,size); block->RO.hash2 = hash2; @@ -233,18 +242,18 @@ struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin if ( tmp != block ) printf("%s height.%d search error %p != %p\n",str,height,block,tmp); } - portable_mutex_unlock(&coin->blocks_mutex); } if ( coin->blockdepth > 0 ) coin->blockdepth--; - while ( coin->blockdepth > 0 ) + portable_mutex_unlock(&coin->blocks_mutex); + /* while ( coin->blockdepth > 0 ) { usleep(100000); if ( coin->blockdepth > 0 ) printf("C %s >>>>>>>>>> OK only if rare %s create blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); //fprintf(stderr,">>>>>>>>>> OK only if rare%s create blockhashset.%d depth.%d\n",debugstr,height,depth); //printf("%d\n",1/(1 - depth/depth)); - } + }*/ return(block); } @@ -298,14 +307,27 @@ int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block * int32_t iguana_blockROsize(uint8_t zcash) { - return((int32_t)(sizeof(struct iguana_blockRO) + zcash*sizeof(struct iguana_msgblockhdr_zcash))); + return((int32_t)(sizeof(struct iguana_blockRO) + zcash*sizeof(struct iguana_msgzblockhdr))); } void *iguana_blockzcopyRO(uint8_t zcash,struct iguana_blockRO *dest,int32_t desti,struct iguana_blockRO *src,int32_t srci) { int32_t bROsize = iguana_blockROsize(zcash); +/** +* The memory address calculation was done in a non-portable way using +* long value which has 4 bytes in 64bit windows (causing invalide memory address) +* due to data truncation, +* the solution is to use portable way to calculate the address +* in all platform sizeof(char) / sizeof(uchar) == 1 +* @author - fadedreamz@gmail.com +*/ +#if defined(_M_X64) + dest = (void *)((unsigned char *)dest + desti*bROsize); + src = (void *)((unsigned char *)src + srci*bROsize); +#else dest = (void *)((long)dest + desti*bROsize); src = (void *)((long)src + srci*bROsize); +#endif memcpy(dest,src,bROsize); return(src); } @@ -325,11 +347,17 @@ void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_blo } } -int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct iguana_block *block,int32_t dispflag) +int32_t iguana_blockvalidate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *validp,struct iguana_block *block,int32_t dispflag) { - bits256 hash2; uint8_t serialized[sizeof(struct iguana_msgblock) + 4096]; + bits256 hash2; int32_t len; uint8_t serialized[sizeof(struct iguana_msgblock) + 32768]; + if ( coin->chain->debug != 0 || coin->chain->zcash != 0 ) + { + *validp = 1; + return(0); + } *validp = 0; - iguana_serialize_block(coin->chain,&hash2,serialized,block); + if ( (len= iguana_serialize_block(myinfo,coin->chain,&hash2,serialized,block)) < 0 ) + return(-1); *validp = (memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0); block->valid = *validp; iguana_blocksizecheck("blockvalidate",coin->chain->zcash,block); @@ -339,8 +367,10 @@ int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct igu if ( dispflag != 0 ) { static uint32_t counter; - if ( (counter++ % 10000) == 9999 ) - printf("iguana_blockvalidate: %s miscompare.%d (%s) vs (%s)\n",coin->symbol,counter,bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); + //for (i=0; iheight,coin->symbol,counter,bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); //getchar(); } return(-1); @@ -377,16 +407,16 @@ void iguana_blockmerge(struct iguana_block *dest,struct iguana_prevdep *destlp,s double PoW_from_compact(uint32_t nBits,uint8_t unitval) // NOT consensus safe, but most of the time will be correct { - uint32_t nbytes,nbits,i,n; double PoW; uint64_t mult; + uint32_t nbytes,nbits; int32_t i,n; double PoW; uint64_t mult; nbytes = (nBits >> 24) & 0xFF; nbits = (8 * (nbytes - 3)); PoW = (nBits & 0xFFFFFF); - if ( 0 && nbytes > unitval ) + if ( (0) && nbytes > unitval ) { printf("illegal nBits.%x unitval.%02x\n",nBits,unitval); return(0.); } - if ( (n= ((8 * (unitval-3)) - nbits)) != 0 ) // 0x1d00ffff is genesis nBits so we map that to 1. + if ( (n= ((8 * (unitval-3)) - nbits)) > 0 ) // 0x1d00ffff is genesis nBits so we map that to 1. { //printf("nbits.%d -> n.%d\n",nbits,n); if ( n < 64 ) @@ -396,7 +426,7 @@ double PoW_from_compact(uint32_t nBits,uint8_t unitval) // NOT consensus safe, b for (i=0; iblocks.hwmchain.height; while ( 1 ) //(block= iguana_blockfind("main",coin,iguana_blockhash(coin,height))) != 0 ) { @@ -431,25 +461,25 @@ int32_t iguana_walkchain(struct iguana_info *coin,int32_t skipflag) bundlei = (height % coin->chain->bundlesize); if ( (bp= coin->bundles[hdrsi]) == 0 || (block= bp->blocks[bundlei]) == 0 ) { - printf("walk error [%d:%d] %p vs %p\n",hdrsi,bundlei,block,bp->blocks[bundlei]); + printf("%s walk error [%d:%d] %p vs %p\n",coin->symbol,hdrsi,bundlei,block,bp->blocks[bundlei]); break; } else if ( block->height >= 0 && block->height != height ) - printf("walkchain height mismatch %d vs %d\n",block->height,height); + printf("%s walkchain height mismatch %d vs %d\n",coin->symbol,block->height,height); iguana_blocksizecheck("walkchain",coin->chain->zcash,block); if ( bits256_nonz(iguana_blockhash(coin,height)) != 0 && bits256_cmp(iguana_blockhash(coin,height),block->RO.hash2) != 0 ) { - printf("walk error blockhash error at %d %s\n",height,bits256_str(str,iguana_blockhash(coin,height))); + printf("%s walk error blockhash error at %d %s\n",coin->symbol,height,bits256_str(str,iguana_blockhash(coin,height))); break; } else if ( bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) { - printf("walk error [%d:%d] %s vs %s\n",hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str,block->RO.hash2)); + printf("%s walk error [%d:%d] %s vs %s\n",coin->symbol,hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str,block->RO.hash2)); break; } else if ( block->hdrsi != hdrsi || block->bundlei != bundlei ) { - printf("walk error [%d:%d] vs [%d:%d]\n",hdrsi,bundlei,block->hdrsi,block->bundlei); + printf("%s walk error [%d:%d] vs [%d:%d]\n",coin->symbol,hdrsi,bundlei,block->hdrsi,block->bundlei); break; } if ( height == 0 ) @@ -494,7 +524,7 @@ struct iguana_block *iguana_fastlink(struct iguana_info *coin,int32_t hwmheight) if ( prev != 0 && bits256_nonz(block->RO.prev_block) == 0 ) { block->RO.prev_block = prev->RO.hash2; - printf("PATCH.[%d:%d] prev is null\n",bp->hdrsi,bundlei); + printf("%s PATCH.[%d:%d] prev is null\n",coin->symbol,bp->hdrsi,bundlei); break; } bp->blocks[bundlei] = block; @@ -535,6 +565,8 @@ struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguan { int32_t valid,bundlei,height=-1; struct iguana_block *hwmchain,*block = 0,*prev=0; bits256 *hash2p=0; double prevPoW = 0.; + if ( coin->blocks.hwmchain.height < 0 ) + iguana_genesis(myinfo,coin,coin->chain); if ( newblock == 0 || newblock->RO.timestamp == 0 || bits256_nonz(newblock->RO.prev_block) == 0 ) return(0); iguana_blocksizecheck("chainlink new",coin->chain->zcash,newblock); @@ -555,10 +587,10 @@ struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguan { //if ( memcmp(prev->RO.hash2.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) // prev->mainchain = 1; - if ( bits256_nonz(prev->RO.hash2) == 0 || (prev->valid == 0 && iguana_blockvalidate(coin,&valid,prev,0) < 0) ) + if ( bits256_nonz(prev->RO.hash2) == 0 || (prev->valid == 0 && iguana_blockvalidate(myinfo,coin,&valid,prev,0) < 0) ) { char str[65]; - if ( 0 && bits256_nonz(prev->RO.hash2) != 0 ) + if ( (0) && bits256_nonz(prev->RO.hash2) != 0 ) printf("(%s) notready v.%d m.%d h.%d\n",bits256_str(str,prev->RO.hash2),prev->valid,prev->mainchain,prev->height); return(0); } else prev->valid = 1; @@ -588,7 +620,7 @@ struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguan return(0); } //char str[65]; printf("extend? %s.h%d: %.15f vs %.15f ht.%d vs %d\n",bits256_str(str,block->RO.hash2),height,block->PoW,coin->blocks.hwmchain.PoW,height,coin->blocks.hwmchain.height); - if ( iguana_blockvalidate(coin,&valid,newblock,0) < 0 || valid == 0 ) + if ( height < 0 || iguana_blockvalidate(myinfo,coin,&valid,newblock,0) < 0 || valid == 0 ) return(0); block->height = height; block->valid = 1; @@ -613,15 +645,17 @@ struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguan else str2[0] = 0; if ( coin->blocks.maxblocks > coin->longestchain ) coin->longestchain = coin->blocks.maxblocks; - if ( 0 && (block->height % coin->chain->bundlesize) == 0 ) + if ( (0) && (block->height % coin->chain->bundlesize) == 0 ) { printf("EXTENDMAIN %s %d <- (%s) n.%u max.%u PoW %f numtx.%d valid.%d\n",str,block->height,str2,hwmchain->height+1,coin->blocks.maxblocks,block->PoW,block->RO.txn_count,block->valid); //iguana_walkchain(coin); } struct iguana_bundle *bp; int32_t hdrsi; - if ( (block->height % coin->chain->bundlesize) == 0 ) + bundlei = (block->height % coin->chain->bundlesize); + hdrsi = (block->height / coin->chain->bundlesize); + if ( bundlei == 0 ) { - if ( (hdrsi= block->height/coin->chain->bundlesize) < coin->bundlescount ) + if ( hdrsi < coin->bundlescount ) { if ( (bp= coin->bundles[hdrsi]) != 0 && bits256_cmp(block->RO.hash2,bp->hashes[0]) != 0 ) { @@ -638,18 +672,21 @@ struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguan } else { - if ( (bp= coin->bundles[block->height / coin->chain->bundlesize]) != 0 ) + if ( (bp= coin->bundles[hdrsi]) != 0 ) { - if ( memcmp(bp->hashes[block->height % coin->chain->bundlesize].bytes,block->RO.hash2.bytes,sizeof(bits256)) != 0 || block != bp->blocks[block->height % coin->chain->bundlesize] ) + if ( memcmp(bp->hashes[bundlei].bytes,block->RO.hash2.bytes,sizeof(bits256)) != 0 || block != bp->blocks[bundlei] ) { - if ( bits256_nonz(bp->hashes[block->height % coin->chain->bundlesize]) != 0 ) + if ( bits256_nonz(bp->hashes[bundlei]) != 0 ) { - if ( bp->blocks[block->height % coin->chain->bundlesize] == 0 && block != 0 ) - bp->blocks[block->height % coin->chain->bundlesize] = block; + if ( bp->blocks[bundlei] == 0 && block != 0 ) + bp->blocks[bundlei] = block; else { - char str[65],str2[65]; - printf("ERROR: need to fix up bundle for height.%d (%p %p) (%s %s)\n",block->height,block,bp->blocks[block->height % coin->chain->bundlesize],bits256_str(str,block->RO.hash2),bits256_str(str2,bp->hashes[block->height % coin->chain->bundlesize])); + //char str[65],str2[65]; + //printf("ERROR: need to fix up bundle for height.%d (%p %p) (%s %s)\n",block->height,block,bp->blocks[bundlei],bits256_str(str,block->RO.hash2),bits256_str(str2,bp->hashes[bundlei])); + bp->blocks[bundlei] = block; + bp->hashes[bundlei] = block->RO.hash2; + //if ( bp == coin->current && coin->RTheight > 0 ) // coin->RTdatabad = 1; //iguana_bundleremove(coin,bp->hdrsi,0); @@ -657,10 +694,16 @@ struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguan //getchar(); } } - iguana_blockunmark(coin,block,bp,block->height % coin->chain->bundlesize,0); - iguana_bundlehash2add(coin,0,bp,block->height % coin->chain->bundlesize,block->RO.hash2); + iguana_blockunmark(coin,block,bp,bundlei,0); + iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); } - if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == coin->minconfirms && (block->height > coin->longestchain-coin->chain->bundlesize*2 || ((block->height / coin->chain->bundlesize) % 100) == 9) ) + else + { + bp->blocks[bundlei] = block; + bp->hashes[bundlei] = block->RO.hash2; + iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); + } + if ( coin->started != 0 && bundlei == coin->minconfirms && (block->height > coin->longestchain-coin->chain->bundlesize*2 || ((block->height / coin->chain->bundlesize) % 10) == 9) ) { //printf("savehdrs.[%d] ht.%d\n",bp->hdrsi,block->height); iguana_savehdrs(coin); @@ -677,7 +720,15 @@ struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguan process_iguanablock(block->serdata,CHAINPARMS); }*/ iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,block); - iguana_RTnewblock(myinfo,coin,block); + if ( coin->RTheight > 0 ) + iguana_RTnewblock(myinfo,coin,block); + block->hdrsi = hdrsi; + block->bundlei = bundlei; + if ( (0) && (bp= coin->bundles[hdrsi]) != 0 ) + { + if ( bp->blocks[bundlei] != block || bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) + printf("new hwm [%d:%d] mismatched bundle block\n",hdrsi,bundlei); + } return(block); } } @@ -706,7 +757,7 @@ struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguan int32_t iguana_chainextend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *newblock) { struct iguana_block *block,*prev; int32_t valid,oldhwm; char str[65]; - if ( iguana_blockvalidate(coin,&valid,newblock,0) < 0 || valid == 0 ) + if ( iguana_blockvalidate(myinfo,coin,&valid,newblock,0) < 0 || valid == 0 ) { printf("chainextend: newblock.%s didnt validate\n",bits256_str(str,newblock->RO.hash2)); return(-1); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index f84969741..e7c53ae73 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -21,6 +21,7 @@ static uint16_t iguana_primes[] = { 65353, 65357, 65371, 65381, 65393, 65407, 65 struct iguana_bloominds iguana_calcbloom(bits256 hash2) { int32_t i,j,k; struct iguana_bloominds bit; + memset(&bit,0,sizeof(bit)); k = (int32_t)(sizeof(bit)/sizeof(uint16_t)) - 1; j = 15; for (i=0; i 0 && memcmp(newhash2.bytes,orighash2p,sizeof(bits256)) != 0 ) { - char str2[65],str3[65]; - bits256_str(str2,*orighash2p), bits256_str(str3,newhash2); - printf("WARNING iguana_hash2set overwrite avoided [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); - return(-1); + static uint32_t counter; + if ( counter++ < 3 ) + { + char str2[65],str3[65]; + bits256_str(str2,*orighash2p), bits256_str(str3,newhash2); + printf("WARNING iguana_hash2set overwrite %s [%s] %s with %s [%d:%d]\n",coin->symbol,debugstr,str2,str3,bp->hdrsi,bundlei); + } //*orighash2p = newhash2; - // getchar(); - // return(-1); + return(-1); } if ( isinside != 0 ) { @@ -156,7 +159,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu { // printf("bloomset (%s) -> [%d:%d]\n",bits256_str(str,newhash2),bp->hdrsi,bundlei); iguana_bloomset(coin,&bp->bloom,0,bit); - if ( 0 ) + if ( (0) ) { int32_t i; if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) @@ -204,7 +207,9 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo *blockp = 0; if ( bp == 0 || bits256_nonz(hash2) == 0 ) { - printf("iguana_bundlehash2add null hash2\n"); + static uint32_t counter; + if ( counter++ < 100 ) + printf("iguana_bundlehash2add %s null hash2 bp.%p\n",coin->symbol,bp); return(-1111); } if ( bits256_nonz(hash2) != 0 && (block= iguana_blockhashset("bundlehash2add",coin,-1,hash2,1)) != 0 ) @@ -213,9 +218,10 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo { if ( block->mainchain != 0 && (block->height % coin->chain->bundlesize) == bundlei && (block->height / coin->chain->bundlesize) == bp->hdrsi ) { - printf("would have bundle block override [%d:%d]\n",bp->hdrsi,bundlei); - //bp->blocks[bundlei] = block; - //bp->hashes[bundlei] = block->RO.hash2; + char str[65],str2[65]; + printf("bundle block override [%d:%d] %s <- %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->blocks[bundlei]->RO.hash2),bits256_str(str2,block->RO.hash2)); + bp->blocks[bundlei] = block; + bp->hashes[bundlei] = block->RO.hash2; } else if ( block->mainchain == 0 ) { @@ -240,7 +246,7 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo return(-1); } } - if ( 0 && bits256_nonz(bp->hashes[bundlei]) != 0 && bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) + if ( (0) && bits256_nonz(bp->hashes[bundlei]) != 0 && bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) { //char str[65],str2[65]; //printf("B bp.[%d]->hashes[%d] mismatch %s != %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":""); @@ -264,9 +270,9 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo bp->n = bundlesize;//(bundlei < bundlesize-1) ? bundlesize : (bundlei + 1); if ( (setval= iguana_hash2set(coin,"blockadd",bp,bundlei,hash2)) == 0 ) { - if ( (block->hdrsi != bp->hdrsi || block->bundlei != bundlei) && (block->hdrsi != 0 || block->bundlei != 0) ) + if ( block->bundlei >= 0 && ((block->hdrsi != bp->hdrsi || block->bundlei != bundlei) && (block->hdrsi != 0 || block->bundlei != 0)) ) { - char str[65]; printf("blockadd warning: %d[%d] main.%d prevent <- %d[%d] %s\n",block->hdrsi,block->bundlei,block->mainchain,bp->hdrsi,bundlei,bits256_str(str,hash2)); + //char str[65]; printf("blockadd warning: %d[%d] main.%d prevent <- %d[%d] %s\n",block->hdrsi,block->bundlei,block->mainchain,bp->hdrsi,bundlei,bits256_str(str,hash2)); //iguana_blockunmark(coin,block,bp,bundlei,block->mainchain != 0); err |= 2; return(-1); @@ -314,7 +320,9 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo } else if ( setval < 0 ) { - printf("neg setval error\n"); + static uint32_t counter; + if ( counter++ < 100 ) + printf("%s neg setval error\n",coin->symbol); err |= 64; } if ( err == 0 && blockp != 0 ) @@ -323,7 +331,7 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo if ( err != 0 ) { static uint32_t counter; - if ( counter++ < 100 ) + if ( counter++ < 10 ) printf("bundlehash2add err.%d\n",err); //return(0); } @@ -379,7 +387,7 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund if ( issueflag != 0 ) { iguana_blockQ("bundlecreate",coin,bp,0,bundlehash2,1); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); + //queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } if ( bp->hdrsi >= coin->bundlescount ) coin->bundlescount = (bp->hdrsi + 1); @@ -428,7 +436,11 @@ struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundl iguana_peerfname(coin,&hdrsi,iter==0?"DB/ro":"DB",fname,0,bp->hashes[0],zero,bp->n,1); if ( (fp= fopen(fname,"rb")) != 0 ) { +#if defined(_M_X64) + fseek(fp, (uint64_t)&rdata.Toffset - (uint64_t)&rdata, SEEK_SET); +#else fseek(fp,(long)&rdata.Toffset - (long)&rdata,SEEK_SET); +#endif if ( fread(&Toffset,1,sizeof(Toffset),fp) == sizeof(Toffset) ) { fseek(fp,Toffset + sizeof(struct iguana_txid) * txidind,SEEK_SET); @@ -450,7 +462,7 @@ char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi) uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; cJSON *retjson; char rmdstr[41]; if ( (bp= coin->bundles[hdrsi]) != 0 ) { - if ( 0 && coin->RTramchain_busy != 0 ) + if ( (0) && coin->RTramchain_busy != 0 ) { printf("iguana_bundleaddrs: unexpected access when RTramchain_busy\n"); return(0); @@ -509,7 +521,7 @@ void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp) sprintf(fname,"%s/%s/%d/%d",GLOBAL_TMPDIR,coin->symbol,subdir,bp->bundleheight), OS_remove_directory(fname); //printf("purged hdrsi.[%d] subdir.%d lag.%ld\n",bp->hdrsi,subdir,time(NULL) - bp->emitfinish); bp->purgetime = (uint32_t)time(NULL); - if ( 0 ) + if ( (0) ) { for (i=subdir*IGUANA_SUBDIRDIVISOR; i<(subdir+1)*IGUANA_SUBDIRDIVISOR; i++) { @@ -562,7 +574,7 @@ struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p } } else return(0); } - if ( block != 0 || (block= bp->blocks[i]) != 0 )//|| bits256_nonz(bp->hashes[i]) != 0 )//&& (block= iguana_blockfind("bundleblock2",coin,bp->hashes[i])) != 0) ) + if ( (block= bp->blocks[i]) != 0 && bits256_nonz(block->RO.hash2) != 0 ) { *hash2p = block->RO.hash2; return(block); @@ -570,7 +582,7 @@ struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[i]) != 0 ) { *hash2p = bp->speculative[i]; - block = bp->blocks[i];//iguana_blockfind("speculative",coin,bp->speculative[i]); + //block = bp->blocks[i];//iguana_blockfind("speculative",coin,bp->speculative[i]); //char str[65]; printf("[%d:%d] %s\n",bp->hdrsi,i,bits256_str(str,*hash2p)); } return(block); @@ -587,7 +599,7 @@ struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p if ( len > (sizeof(int32_t) + sizeof(*hashes))*n + 1024 ) { printf("FATAL ERROR iguana_sendhashes: len.%d size.%ld\n",len,(sizeof(int32_t) + sizeof(*hashes))*n + 1024); - exit(-1); + iguana_exit(myinfo); } iguana_send(coin,addr,serialized,len); coin->numreqsent += n; @@ -611,37 +623,37 @@ struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p return(n); }*/ -int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult) +int32_t iguana_bundleissuemissing(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult) { - int32_t i,max,nonz,starti,lasti,firsti,lag,num,n=0; uint32_t now; bits256 hash2; double aveduration; struct iguana_peer *addr; + int32_t i,max,nonz,starti,lasti,firsti,lag,num,n=0; uint32_t now; bits256 hash2; double aveduration; struct iguana_peer *addr; char str[65]; //struct iguana_block *block; if ( coin->peers == 0 ) + { + printf("%s has no peers\n",coin->symbol); return(0); + } starti = coin->current == 0 ? 0 : coin->current->hdrsi; - lasti = coin->lastpending == 0 ? starti+coin->MAXBUNDLES : coin->lastpending->hdrsi; - if ( bp->hdrsi < starti || bp->hdrsi > lasti || bp->emitfinish != 0 || ((priority > 0 || bp == coin->current) && time(NULL) < bp->missingstime+3) || time(NULL) < bp->missingstime+30 ) + lasti = coin->lastpending == 0 ? coin->bundlescount-1 : coin->lastpending->hdrsi; + if ( bp->hdrsi < starti || bp->hdrsi > lasti || bp->emitfinish != 0 )//|| ((priority > 0 || bp == coin->current) && time(NULL) < bp->missingstime+3) ) + { + //printf("bp->hdrsi %d < %d starti || bp->hdrsi %d > %d lasti || bp->emitfinish %d != 0\n",bp->hdrsi,starti,bp->hdrsi,lasti,bp->emitfinish); return(0); + } bp->missingstime = (uint32_t)time(NULL); if ( bp->durationscount != 0 ) { aveduration = (double)bp->totaldurations / bp->durationscount; - if ( (rand() % 10000) == 0 ) + if ( (rand() % 100000) == 0 ) printf("priority.%d [%d] durations %.2f counts[%d %d] \n",priority,bp->hdrsi,aveduration,(int32_t)bp->durationscount,bp->duplicatescount); } else aveduration = IGUANA_DEFAULTLAG; lag = aveduration * mult; - if ( coin->PREFETCHLAG < 0 ) - { - if ( bp != coin->current && lag < 60 ) - lag = 60; - else if ( lag < 30 ) - lag = 30; - } - else if ( lag < 120 && coin->enableCACHE == 0 ) - { - if ( bp != coin->current ) - lag = 120; - else if ( lag < 60 ) - lag = 60; - } + if ( bp != coin->current && lag < 60 ) + lag = 60; + else if ( lag < 30 ) + lag = 30; + if ( strcmp(coin->symbol,"BTC") != 0 ) + lag /= 10; + if ( (num= coin->peers->numranked) == 0 ) + iguana_updatemetrics(myinfo,coin); if ( (num= coin->peers->numranked) != 0 ) { if ( num > 64 ) @@ -655,53 +667,53 @@ int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle lasti = firsti = -1; for (i=nonz=0; in; i++) { + //if ( (block= bp->blocks[i]) != 0 && block->txvalid != 0 && block->mainchain != 0 ) + // continue; if ( GETBIT(bp->haveblock,i) != 0 ) continue; nonz++; if ( firsti < 0 ) firsti = i; lasti = i; - if ( priority > 2 || bp->numsaved > bp->n-10 || ((bp->issued[i] == 0 || bp->issued[i] > 1) && now > bp->issued[i]+lag) ) + if ( 1 ) { iguana_bundleblock(coin,&hash2,bp,i); if ( bits256_nonz(hash2) != 0 ) { - if ( (addr= coin->peers->ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 ) + if ( (addr= coin->peers->ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 && addr->msgcounts.verack > 0 ) { - struct iguana_blockreq *req = 0; - if ( 0 && bp == coin->current ) - printf("iguana_bundleissuemissing.[%d:%d]\n",bp->hdrsi,i); - if ( priority > 2 || bp->numsaved > bp->n-10 ) - iguana_sendblockreqPT(coin,0,bp,i,hash2,0); - else - { - req = mycalloc('y',1,sizeof(*req)); - req->hash2 = hash2; - req->bp = bp; - req->height = bp->bundleheight + i; - req->bundlei = i; - queue_enqueue("missing",&coin->priorityQ,&req->DL,0); - } - bp->issued[i] = 1; - n++; + iguana_sendblockreqPT(coin,0,bp,i,hash2,0); } - } - } + struct iguana_blockreq *req = 0; + req = mycalloc('y',1,sizeof(*req)); + req->hash2 = hash2; + req->bp = bp; + req->height = bp->bundleheight + i; + req->bundlei = i; + queue_enqueue("missing",&coin->priorityQ,&req->DL); + bp->issued[i] = 1; + n++; + if ( (0) && bp == coin->current ) + printf("%s issuemissing.[%d:%d]\n",bits256_str(str,hash2),bp->hdrsi,i); + } //else printf("[z%d] ",i); + } //else printf("%d ",now - (bp->issued[i]+lag)); } - if ( priority <= 2 && firsti >= 0 && bp->issued[firsti] != 1 && (strcmp("BTC",coin->symbol) != 0 || bp == coin->current) ) + if ( firsti >= 0 )//&& bp == coin->current ) { - //printf("[%d] first missing.%d of %d\n",bp->hdrsi,firsti,nonz); + if ( (0) && bp == coin->current ) + printf("%s [%d] first missing.%d of %d\n",bits256_str(str,hash2),bp->hdrsi,firsti,nonz); iguana_bundleblock(coin,&hash2,bp,firsti); if ( bits256_nonz(hash2) != 0 ) { - if ( (addr= coin->peers->ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 ) + if ( (addr= coin->peers->ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 && addr->msgcounts.verack > 0 ) { //if ( bp == coin->current ) // printf("iguana_bundleissuemissing.[%d:%d]\n",bp->hdrsi,i); n++; + //printf("send reqPT [%d:%d]\n",bp->hdrsi,firsti); iguana_sendblockreqPT(coin,0,bp,firsti,hash2,0); } - } + } // else printf("no hash for [%d:%d]\n",bp->hdrsi,firsti); } } //if ( n > 0 || bp == coin->current ) @@ -742,7 +754,7 @@ int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr) req->bp = bp; req->height = bp->bundleheight + i; req->bundlei = i; - queue_enqueue("blast",&coin->priorityQ,&req->DL,0); + queue_enqueue("blast",&coin->priorityQ,&req->DL); } } if ( n > m ) @@ -756,13 +768,13 @@ int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr) return(n); } -int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag) +int32_t iguana_bundleready(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag) { static bits256 zero; int32_t i,ready,valid; char fname[1024]; struct iguana_block *block; int32_t sum[0x100],counts[0x100]; struct iguana_blockRO *B; struct iguana_bundle *nextbp; void *ptr; long filesize; struct iguana_ramchain R; bits256 prevhash2; memset(sum,0,sizeof(sum)); memset(counts,0,sizeof(counts)); - if ( 0 && bp->queued == 0 ) + if ( (0) && bp->queued == 0 ) { for (i=ready=0; in; i++) if ( (block= bp->blocks[i]) == 0 ) @@ -781,7 +793,7 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int bp->blocks[i] = iguana_blockhashset("ready",coin,bp->bundleheight+i,prevhash2,1); iguana_hash2set(coin,"ready",bp,i,prevhash2); prevhash2 = zero; - if ( (ptr= iguana_bundlefile(coin,fname,&filesize,bp,i)) != 0 ) + if ( (ptr= iguana_bundlefile(coin,fname,&filesize,bp,i,0)) != 0 ) { if ( iguana_mapchaininit(fname,coin,&R,bp,i,block,ptr,filesize) >= 0 ) { @@ -809,12 +821,12 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int counts[block->peerid]++; } //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); - if ( block->txvalid == 0 || block->fpipbits == 0 || block->fpos < 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) + if ( block->txvalid == 0 || block->fpipbits == 0 || block->fpos < 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(myinfo,coin,&valid,block,1) < 0 ) { char str[65]; if ( requiredflag != 0 ) printf(">>>>>>> block contents error at ht.%d [%d:%d]\n",bp->bundleheight+i,bp->hdrsi,i); - if ( 0 && bits256_nonz(block->RO.hash2) != 0 ) + if ( (0) && bits256_nonz(block->RO.hash2) != 0 ) printf("patch.%d and reissue prev.%s %d\n",bp->bundleheight+i,bits256_str(str,block->RO.prev_block),i); iguana_blockunmark(coin,block,bp,i,1); } @@ -834,16 +846,16 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int } fclose(fp); } - else if ( 0 ) + else if ( (0) ) //#endif { iguana_blockunmark(coin,block,bp,i,1); - if ( 0 && requiredflag != 0 ) - printf("not ready altpath.(%d %d %d %d %d) [%d:%d]\n",block->txvalid == 0,block->fpipbits == 0 ,block->fpos < 0,(bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0),iguana_blockvalidate(coin,&valid,block,1) < 0,bp->hdrsi,i); + if ( (0) && requiredflag != 0 ) + printf("not ready altpath.(%d %d %d %d %d) [%d:%d]\n",block->txvalid == 0,block->fpipbits == 0 ,block->fpos < 0,(bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0),iguana_blockvalidate(myinfo,coin,&valid,block,1) < 0,bp->hdrsi,i); } else { - iguana_blockunmark(coin,block,bp,i,0); + //iguana_blockunmark(coin,block,bp,i,0); //printf("cant find (%s)\n",fname); } } @@ -863,10 +875,10 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int return(ready); } -int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti) +int32_t iguana_bundlehdr(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti) { - int32_t i,dist,counter=0; char str[64]; - if ( 0 && bp->isRT == 0 && (bp->hdrsi == coin->bundlescount-1 || bp == coin->current) ) + int32_t i,dist,counter=0; char str[65]; + if ( (0) && bp->isRT == 0 && (bp->hdrsi == coin->bundlescount-1 || bp == coin->current) ) printf("hdr ITERATE.%d bundle.%d vs %d: h.%d n.%d r.%d s.%d c.%d finished.%d spec.%p[%d]\n",bp->hdrsi,bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->numcached,bp->emitfinish,bp->speculative,bp->numspec); dist = 30 + (coin->current != 0 ? bp->hdrsi - coin->current->hdrsi : 0); if ( bp == coin->current ) @@ -874,9 +886,9 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 if ( time(NULL) > bp->hdrtime+dist && (bp == coin->current || bp->hdrsi >= coin->bundlescount-2 || (strcmp("BTC",coin->symbol) != 0 && bp->numhashes < bp->n && (bp->speculative == 0 || bp->hdrsi >= coin->longestchain/bp->n))) ) { bp->hdrtime = (uint32_t)time(NULL); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0]))); } - if ( strcmp("BTC",coin->symbol) != 0 && (bp == coin->current || bp->hdrsi == coin->bundlescount-1) && bits256_nonz(bp->nextbundlehash2) == 0 ) + if ( time(NULL) > bp->hdrtime+dist && strcmp("BTC",coin->symbol) != 0 && (bp == coin->current || bp->hdrsi == coin->bundlescount-1) && bits256_nonz(bp->nextbundlehash2) == 0 ) { if ( bp->numhashes < bp->n && bp->numcached < bp->n ) { @@ -884,9 +896,10 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 for (i=0; in; i++) if ( GETBIT(bp->haveblock,i) == 0 ) bp->issued[i] = 0; - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + bp->hdrtime = (uint32_t)time(NULL); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0]))); } - iguana_bundleissuemissing(coin,bp,3,1.); + iguana_bundleissuemissing(myinfo,coin,bp,3,3.); /*if ( bp == coin->current ) { mult = 1.; @@ -929,10 +942,10 @@ int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) return(coin->MAXBUNDLES); } -int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag) +int64_t iguana_bundlecalcs(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag) { int32_t bundlei,numhashes,numsaved,numrecv,numcached,minrequests; int64_t datasize; struct iguana_block *block; - if ( bp->emitfinish > 0 && (bp->ramchain.H.data != 0 || iguana_bundleready(coin,bp,0) == bp->n) ) + if ( bp->emitfinish > 0 && (bp->ramchain.H.data != 0 || iguana_bundleready(myinfo,coin,bp,0) == bp->n) ) { memset(bp->haveblock,0xff,sizeof(bp->haveblock)); bp->numhashes = bp->numsaved = bp->numcached = bp->numrecv = bp->n; @@ -964,7 +977,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int datasize += block->RO.recvlen; } } - else if ( 0 && bits256_nonz(block->RO.hash2) != 0 && bits256_nonz(bp->hashes[bundlei]) != 0 ) + else if ( (0) && bits256_nonz(block->RO.hash2) != 0 && bits256_nonz(bp->hashes[bundlei]) != 0 ) { printf("hash mismatch [%d:%d]\n",bp->hdrsi,bundlei); iguana_blockunmark(coin,block,bp,bundlei,1); @@ -984,7 +997,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int } } bp->numcached = numcached; - if ( 0 && bp->numcached != numsaved ) + if ( (0) && bp->numcached != numsaved ) printf("[%d] emit.%u ramchain.%p numcached.%d vs numsaved.%d numhashes.%d\n",bp->hdrsi,bp->emitfinish,bp->ramchain.H.data,bp->numcached,numsaved,numhashes); bp->datasize = datasize; bp->numhashes = numhashes; @@ -1027,18 +1040,24 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int int32_t iguana_bundlefinalize(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,struct OS_memspace *mem,struct OS_memspace *memB) { - int32_t i; struct iguana_bundle *tmpbp; - if ( coin->firstRTheight == 0 && iguana_bundleready(coin,bp,0) == bp->n ) + int32_t i; struct iguana_bundle *tmpbp; struct iguana_blockreq *breq; + if ( coin->firstRTheight == 0 && iguana_bundleready(myinfo,coin,bp,0) == bp->n ) { - printf(">>>>>>>>>>>>>> EMIT.[%3d] %s | 1st.%-3d h.%-3d c.%-3d s.[%3d] maxB.%d NET.(h%d b%d) %ld:%02ld\n",bp->hdrsi,coin->symbol,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numcached:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,netBLOCKS,(time(NULL)-coin->startutc)/60,(time(NULL)-coin->startutc)%60); + printf(">>>>>>>>>>>>>> EMIT.[%3d] %s | 1st.%-3d h.%-3d c.%-3d s.[%3d] maxB.%d NET.(h%d b%d) %u:%02u\n",bp->hdrsi,coin->symbol,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numcached:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,queue_size(&coin->priorityQ),(uint32_t)(time(NULL)-coin->startutc)/60,(uint32_t)(time(NULL)-coin->startutc)%60); + if ( queue_size(&coin->priorityQ) > 10000 ) + { + while ( (breq= queue_dequeue(&coin->priorityQ)) != 0 ) + myfree(breq,sizeof(*breq)); + //printf("cleared priorityQ\n"); + } if ( bp->emitfinish != 0 ) { printf("already EMIT for bundle.%d\n",bp->hdrsi); - return(0); + //return(0); } bp->emitfinish = 1; usleep(100000); // make sure new incoming packet didnt overwrite - if ( iguana_bundleready(coin,bp,1) == bp->n ) + if ( iguana_bundleready(myinfo,coin,bp,1) == bp->n ) { usleep(100000); // make sure new incoming packet didnt overwrite coin->emitbusy++; @@ -1054,12 +1073,13 @@ int32_t iguana_bundlefinalize(struct supernet_info *myinfo,struct iguana_info *c printf("GENESIS block validated\n"); else printf("GENESIS didnt validate bp.%p\n",bp);*/ //if ( strcmp("BTC",coin->symbol) != 0 ) - coin->spendvectorsaved = 0; - for (i=bp->hdrsi; ibundlescount; i++) + coin->RTheight = coin->firstRTheight = 0; + //coin->spendvectorsaved = 0; + for (i=0; ibundlescount; i++) if ( (tmpbp= coin->bundles[i]) != 0 ) - tmpbp->converted = tmpbp->balancefinish = tmpbp->validated = 0; + tmpbp->converted = tmpbp->balancefinish = 0; #ifdef __PNACL__ - iguana_bundlevalidate(coin,bp,1); + iguana_bundlevalidate(myinfo,coin,bp,1); #endif } else @@ -1093,7 +1113,7 @@ int32_t iguana_bundleiters(struct supernet_info *myinfo,struct iguana_info *coin { printf("%s not ready yet\n",coin->symbol); bp->nexttime = (uint32_t)time(NULL) + 1; - iguana_bundleQ(coin,bp,1000); + iguana_bundleQ(myinfo,coin,bp,1000); return(retval); } if ( coin->current == 0 ) @@ -1104,17 +1124,17 @@ int32_t iguana_bundleiters(struct supernet_info *myinfo,struct iguana_info *coin starti = currentbp == 0 ? 0 : currentbp->hdrsi; lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; range = lasti - starti + 1; - iguana_bundlecalcs(coin,bp,lag); + iguana_bundlecalcs(myinfo,coin,bp,lag); if ( coin->blockdepth == 0 && coin->blockdepth == 0 && bp->hdrsi == coin->bundlescount-1 ) - iguana_autoextend(coin,bp); - if ( 0 && bp->hdrsi == 0 ) + iguana_autoextend(myinfo,coin,bp); + if ( (0) && bp->hdrsi == 0 ) printf("ITER utxo.%u now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->utxofinish,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); bp->nexttime = (uint32_t)time(NULL) + ((bp->hdrsi > starti) ? 0 : -2); if ( bp->hdrsi == coin->bundlescount-1 || (bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize) ) - iguana_bundlehdr(coin,bp,starti); + iguana_bundlehdr(myinfo,coin,bp,starti); else if ( bp->emitfinish == 0 && bp->numsaved >= bp->n ) { - if ( coin->virtualchain != 0 || iguana_bundlefinalize(myinfo,coin,bp,mem,memB) > 0 ) + if ( coin->virtualchain != 0 )//|| iguana_bundlefinalize(myinfo,coin,bp,mem,memB) > 0 ) { //printf("bundlefinalized done.[%d]\n",bp->hdrsi); return(0); @@ -1124,12 +1144,12 @@ int32_t iguana_bundleiters(struct supernet_info *myinfo,struct iguana_info *coin else if ( bp->hdrsi == starti || (bp->hdrsi >= starti && bp->hdrsi <= starti+range) ) { max = bp->n; - counter = iguana_bundleissuemissing(coin,bp,1,3.); - if ( 0 && counter > 0 ) + counter = iguana_bundleissuemissing(myinfo,coin,bp,1,3.); + if ( (0) && counter > 0 ) printf("starti.%d range.%d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",starti,range,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); } else bp->nexttime++; - if ( bp->emitfinish <= 1 ) - iguana_bundleQ(coin,bp,1000); + if ( (0) && bp->emitfinish <= 1 ) + iguana_bundleQ(myinfo,coin,bp,1000); else { //printf("[%d] not queued\n",bp->hdrsi); @@ -1157,7 +1177,7 @@ static int32_t revsortds(double *buf,uint32_t num,int32_t size) return(0); }*/ -int32_t iguana_cacheprocess(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei) +int32_t iguana_cacheprocess(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei) { int32_t recvlen; struct iguana_msghdr H; uint8_t *data; struct iguana_block *block; if ( (data= bp->speculativecache[bundlei]) != 0 && bp->speculative != 0 && (block= iguana_blockfind("cacheprocess",coin,bp->speculative[bundlei])) != 0 && block->processed == 0 ) @@ -1170,13 +1190,8 @@ int32_t iguana_cacheprocess(struct iguana_info *coin,struct iguana_bundle *bp,in memset(&H,0,sizeof(H)); if ( iguana_sethdr(&H,coin->chain->netmagic,"block",&data[sizeof(recvlen)],recvlen) > 0 ) { - if ( coin->internaladdr.RAWMEM.ptr == 0 ) - iguana_meminit(&coin->internaladdr.RAWMEM,"cache",0,IGUANA_MAXPACKETSIZE + 65536*3,0); - if ( coin->TXMEM.ptr == 0 ) - iguana_meminit(&coin->internaladdr.TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE*1.5,0); - if ( coin->internaladdr.HASHMEM.ptr == 0 ) - iguana_meminit(&coin->internaladdr.HASHMEM,"HASHPTRS",0,256,0); - if ( iguana_msgparser(coin,&coin->internaladdr,&coin->internaladdr.RAWMEM,&coin->internaladdr.TXDATA,&coin->internaladdr.HASHMEM,&H,&data[sizeof(recvlen)],recvlen,1) < 0 ) + iguana_peer_meminit(coin,&coin->internaladdr); + if ( iguana_msgparser(myinfo,coin,&coin->internaladdr,&coin->internaladdr.RAWMEM,&coin->internaladdr.TXDATA,&coin->internaladdr.HASHMEM,&H,&data[sizeof(recvlen)],recvlen,1) < 0 ) printf("error parsing speculativecache.[%d:%d]\n",bp->hdrsi,bundlei); } free(data); @@ -1204,20 +1219,19 @@ void iguana_unstickhdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t } } -void iguana_bundlemissings(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t now) +void iguana_bundlemissings(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,uint32_t now) { int32_t mult = 7,n=0,priority = 1; - if ( now > bp->missingstime+10 ) + if ( now > bp->missingstime+13 ) { if ( coin->current != 0 ) + { mult = bp->hdrsi - coin->current->hdrsi; - else if ( strcmp("BTC",coin->symbol) != 0 ) - mult = 1; - else mult = 3; - if ( mult < 4 ) - mult = 4; - else if ( mult > 7 ) - mult = 7; + if ( mult < 4 ) + mult = 4; + else if ( mult > 7 ) + mult = 7; + } else mult = 2; if ( coin->bandwidth < .7*coin->maxbandwidth ) { mult--; @@ -1241,7 +1255,7 @@ void iguana_bundlemissings(struct iguana_info *coin,struct iguana_bundle *bp,uin if ( mult < 1 ) mult = 1; } - if ( (n= iguana_bundleissuemissing(coin,bp,priority,mult)) > 0 ) + if ( (n= iguana_bundleissuemissing(myinfo,coin,bp,priority,mult)) > 0 ) { //printf("bundle.[%d] n.%d issued.%d lag.%d\n",bp->hdrsi,n,bp->numissued,now-bp->missingstime); bp->numissued += n; @@ -1293,7 +1307,7 @@ int32_t iguana_bundlehash2_check(struct iguana_info *coin,bits256 hash2) void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,char *str,int32_t lag) { - int32_t i,n,m,j,numv,numconverted,count,starti,lasti,pending,capacity,displag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; struct iguana_block *block; bits256 hash2; + int32_t i,n,m,j,numv,numconverted,count,starti,lasti,pending,capacity,displag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit,numbQ=0; struct iguana_block *block; bits256 hash2; struct iguana_blockreq *breq; int64_t spaceused=0,estsize = 0; struct iguana_bundle *currentbp,*lastbp,*bp,*lastpending = 0,*firstgap = 0; uint32_t now; if ( coin->bundlescount <= 0 ) return; @@ -1313,6 +1327,8 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch { if ( bp->converted != 0 ) numconverted++; + if ( bp->queued != 0 ) + numbQ++; if ( bp == coin->current && coin->blocks.hwmchain.height >= bp->bundleheight && coin->blocks.hwmchain.height < bp->bundleheight+bp->n ) { for (j=coin->blocks.hwmchain.height-bp->bundleheight+1; j<=bp->n; j++) @@ -1333,8 +1349,6 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch } else { - if ( bp->hdrsi >= starti && bp->hdrsi < lasti ) - iguana_bundlemissings(coin,bp,now); if ( coin->enableCACHE != 0 ) { for (j=0; jn; j++) @@ -1342,16 +1356,20 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch if ( ((block= bp->blocks[j]) == 0 || bp == coin->current) && bp->speculativecache[j] != 0 ) { if ( (block != 0 || (block= iguana_blockhashset("bundlestats3",coin,-1,bp->speculative[j],1)) != 0) && block->processed == 0 ) - iguana_cacheprocess(coin,bp,j); + iguana_cacheprocess(myinfo,coin,bp,j); numcached++; } + if ( block != 0 && block->issued > 1 ) + bp->issued[j] = block->issued; } } + if ( bp->hdrsi >= starti && bp->hdrsi < lasti ) + iguana_bundlemissings(myinfo,coin,bp,now); } bp->metric = coin->bundlescount - bp->hdrsi; if ( done > coin->bundlescount*IGUANA_HEADPERCENTAGE && bp->hdrsi > coin->bundlescount*IGUANA_TAILPERCENTAGE ) bp->metric *= 1000; - iguana_bundlecalcs(coin,bp,lag); + iguana_bundlecalcs(myinfo,coin,bp,lag); estsize += bp->estsize; numhashes += bp->numhashes; numcached += bp->numcached; @@ -1363,6 +1381,8 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch numbalances++; if ( bp->validated > 1 ) numv++; + if ( bp->emitfinish == 0 && bp->ramchain.H.data != 0 ) + bp->emitfinish = (uint32_t)time(NULL); if ( bp->emitfinish >= 1 ) { if ( bp->emitfinish == 1 ) @@ -1376,20 +1396,20 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch } else { - if ( firstgap == 0 && bp->numsaved < bp->n && bp->numcached < bp->n && (bp->ramchain.H.data == 0 || bp->hdrsi == coin->longestchain/coin->chain->bundlesize || iguana_bundleready(coin,bp,bp->numsaved == bp->n) != bp->n) ) + if ( firstgap == 0 && bp->queued == 0 && bp->numsaved < bp->n ) + iguana_bundleQ(myinfo,coin,bp,1000); + if ( firstgap == 0 && bp->numsaved < bp->n && bp->numcached < bp->n && (bp->ramchain.H.data == 0 || bp->hdrsi == coin->longestchain/coin->chain->bundlesize || iguana_bundleready(myinfo,coin,bp,bp->numsaved == bp->n) != bp->n) ) { //printf("firstgap <- [%d] emit.%u bp->n.%d numsaved.%d numcached.%d numhashes.%d\n",bp->hdrsi,bp->emitfinish,bp->n,bp->numsaved,bp->numcached,bp->numhashes); firstgap = bp; - if ( bp->queued == 0 ) - iguana_bundleQ(coin,bp,1000); } //else printf("[%d] emit.%u bp->n.%d numsaved.%d numcached.%d numhashes.%d\n",bp->hdrsi,bp->emitfinish,bp->n,bp->numsaved,bp->numcached,bp->numhashes); if ( bp->emitfinish == 0 ) { if ( lastpending == 0 && bp->queued == 0 ) - iguana_bundleQ(coin,bp,1000); - if ( firstgap != 0 && ++pending == coin->MAXBUNDLES ) + iguana_bundleQ(myinfo,coin,bp,1000); + if ( firstgap != 0 && bp->numsaved < bp->n && ++pending == coin->MAXBUNDLES ) { lastpending = bp; //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); @@ -1398,27 +1418,12 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch //sortbuf[m*2] = bp->metric; //sortbuf[m*2 + 1] = i; m++; - if ( 0 && lastpending == 0 ) + if ( (0) && lastpending == 0 ) printf("%d ",bp->numsaved); } } } } - //printf("lastbp.[%d]\n",lastpending!=0?lastpending->hdrsi:-1); - /*if ( m > 0 ) - { - revsortds(sortbuf,m,sizeof(*sortbuf)*2); - for (i=0; ibundles[(int32_t)sortbuf[i*2 + 1]]) != 0 ) - { - bp->rank = i + 1; - if ( coin->peers.numranked > 0 && i < coin->peers.numranked && (addr= coin->peers.ranked[i]) != 0 ) - addr->bp = bp; - } - } - } - free(sortbuf);*/ coin->numremain = n; coin->blocksrecv = numrecv; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); @@ -1433,15 +1438,20 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch tmp = (difft.millis * 1000000); tmp %= 1000000000; difft.millis = ((double)tmp / 1000000.); - if ( (bp= firstgap) != 0 )//&& coin->PREFETCHLAG < 0 ) + if ( (bp= firstgap) != 0 ) { if ( bp != coin->current ) - printf("new 1st.%d\n",bp->hdrsi); - //else printf("issue 1st.%d\n",bp->hdrsi); - for (i=0; in; i++) + { + printf("%s new 1st.%d\n",coin->symbol,bp->hdrsi); + iguana_bundleissuemissing(myinfo,coin,bp,3,1.); + if ( bp->queued == 0 ) + iguana_bundleQ(myinfo,coin,bp,0); + } + for (i=j=0; in; i++) if ( GETBIT(bp->haveblock,i) == 0 ) - bp->issued[i] = 0; - iguana_bundleissuemissing(coin,bp,1 + (rand() % 3),1.); + bp->issued[i] = 0, j++; + n = iguana_bundleissuemissing(myinfo,coin,bp,3,1.); + //printf("issued 1st.[%d] %d of %d\n",bp->hdrsi,n,j); } if ( (coin->current= firstgap) == 0 ) { @@ -1471,7 +1481,7 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch } else if ( coin->stucktime != 0 ) { - struct iguana_blockreq *breq; int32_t n,lag; //priority=3, + int32_t n,lag; //priority=3, lag = (int32_t)time(NULL) - coin->stucktime; //printf("NONZ stucktime.%u lag.%d iters.%d vs %d metric.%d\n",coin->stucktime,lag,coin->stuckiters,lag/coin->MAXSTUCKTIME,smetric); if ( (lag/coin->MAXSTUCKTIME) > coin->stuckiters ) @@ -1481,9 +1491,9 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch coin->stuckiters = (int32_t)(lag/coin->MAXSTUCKTIME); if ( coin->stuckiters > 2 ) { - while ( (breq= queue_dequeue(&coin->blocksQ,0)) != 0 ) + while ( (breq= queue_dequeue(&coin->blocksQ)) != 0 ) myfree(breq,sizeof(*breq)); - while ( (breq= queue_dequeue(&coin->priorityQ,0)) != 0 ) + while ( (breq= queue_dequeue(&coin->priorityQ)) != 0 ) myfree(breq,sizeof(*breq)); for (i=0; in; i++) { @@ -1494,8 +1504,8 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch for (i=0; in; i++) if ( GETBIT(bp->haveblock,i) == 0 ) bp->issued[i] = 0; - if ( (n= iguana_bundleissuemissing(coin,bp,3,1.)) > 0 ) - printf("issued %d priority requests [%d] to unstick stuckiters.%d lag.%d\n",n,bp->hdrsi,coin->stuckiters,lag); + if ( (n= iguana_bundleissuemissing(myinfo,coin,bp,3,1.)) > 0 ) + printf("%s issued %d priority requests [%d] to unstick stuckiters.%d lag.%d\n",coin->symbol,n,bp->hdrsi,coin->stuckiters,lag); //else printf("no bundlerequests issued\n"); } } //else printf("stuck metric.%d\n",smetric); @@ -1504,7 +1514,7 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch coin->stucktime = coin->stuckiters = 0; if ( coin->stucktime != 0 && time(NULL)-coin->stucktime > coin->maxstuck ) coin->maxstuck = (uint32_t)time(NULL) - coin->stucktime; - sprintf(str,"%s.RT%d u.%d+c.%d b.%d v.%d (%d+%d/%d 1st.%d).s%d to %d N[%d] h.%d r.%d c.%d s.%d d.%d E.%d maxB.%d peers.%d/%d Q.(%d %d) (L.%d %d:%d) M.%d %s ledger.%08llx supply %.8f",coin->symbol,coin->RTheight,numutxo,numconverted,numbalances,iguana_validated(coin),firstgap!=0?firstgap->numcached:-1,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->numhashes:-1,firstgap!=0?firstgap->hdrsi:-1,firstgap!=0?firstgap->numspec:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,numhashes,coin->blocksrecv,numcached,numsaved,done,numemit,coin->MAXBUNDLES,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->longestchain/coin->chain->bundlesize,coin->longestchain%coin->chain->bundlesize,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2),(long long)coin->utxoaddrhash.txid,dstr(coin->histbalance)+dstr(coin->RTcredits)-dstr(coin->RTdebits)); + sprintf(str,"%s.RT%d u.%d+c.%d b.%d v.%d (%d+%d/%d 1st.%d).s%d to %d N[%d] h.%d r.%d c.%d s.%d d.%d E.%d maxB.%d peers.%d/%d Q.(%d %d) (L.%d %d:%d) M.%d %s ledger.%08llx supply %.8f sigs %u:%u",coin->symbol,coin->RTheight,numutxo,numconverted,numbalances,iguana_validated(coin),firstgap!=0?firstgap->numcached:-1,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->numhashes:-1,firstgap!=0?firstgap->hdrsi:-1,firstgap!=0?firstgap->numspec:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,numhashes,coin->blocksrecv,numcached,numsaved,done,numemit,coin->MAXBUNDLES,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->longestchain/coin->chain->bundlesize,coin->longestchain%coin->chain->bundlesize,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2),(long long)coin->utxoaddrhash.txid,dstr(coin->histbalance)+dstr(coin->RTcredits)-dstr(coin->RTdebits),coin->sigserrs,coin->sigsvalidated); //if( strcmp("BTC",coin->symbol) == 0 ) // printf("%s\n",str); if ( coin->current != 0 && coin->current->hdrsi == coin->longestchain/coin->chain->bundlesize && numemit == coin->current->hdrsi && numutxo == coin->bundlescount-1 ) @@ -1521,7 +1531,7 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch //printf("bundleQ.[%d]\n",j); bp->balancefinish = bp->startutxo = 0; bp->utxofinish = 1; - iguana_bundleQ(coin,bp,1000); + iguana_bundleQ(myinfo,coin,bp,1000); } } } @@ -1533,16 +1543,17 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch logfp = fopen("debug.log","wb"); if ( logfp != 0 ) { - fprintf(logfp,"%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); + fprintf(logfp,"%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,numbQ,(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); fflush(logfp); } - //printf("%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); + if ( coin->RTheight == 0 ) + printf("%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,numbQ,(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); strcpy(coin->lastdispstr,str); if ( (rand() % 100) == 0 ) myallocated(0,0); coin->lastdisp = (uint32_t)time(NULL); } - if ( 0 && (bp= coin->current) != 0 && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n ) + if ( (0) && (bp= coin->current) != 0 && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n ) { for (i=coin->RTheight-bp->bundleheight; in; i++) { @@ -1554,5 +1565,11 @@ void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,ch iguana_setmaxbundles(coin); strcpy(coin->statusstr,str); coin->estsize = estsize; + if ( queue_size(&coin->priorityQ) > 10000 ) + { + while ( (breq= queue_dequeue(&coin->priorityQ)) != 0 ) + myfree(breq,sizeof(*breq)); + //printf("cleared priorityQ\n"); + } } diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index d2c05b78f..4fc5a0b76 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -125,13 +125,13 @@ int32_t blockhash_scrypt(uint8_t *blockhashp,uint8_t *serialized,int32_t len) blockhashfunc iguana_hashalgo(char *hashalgostr) { - return(blockhash_sha256); // all coins seem to use this for the actual blockchain data - if ( hashalgostr == 0 || hashalgostr[0] == 0 || strcmp(hashalgostr,"sha256") == 0 ) +return(blockhash_sha256); // all coins seem to use this for genesis + /*if ( hashalgostr == 0 || hashalgostr[0] == 0 || strcmp(hashalgostr,"sha256") == 0 ) return(blockhash_sha256); else if ( strcmp(hashalgostr,"scrypt") == 0 ) return(blockhash_scrypt); else printf("unsupported blockhash algo.(%s)\n",hashalgostr); - return(0); + return(0);*/ } bits256 iguana_calcblockhash(char *symbol,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),uint8_t *serialized,int32_t len) @@ -161,21 +161,21 @@ bits256 iguana_calcblockhash(char *symbol,int32_t (*hashalgo)(uint8_t *blockhash return(hash2); } -bits256 iguana_chaingenesis(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root) +bits256 iguana_chaingenesis(struct supernet_info *myinfo,char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root) { - struct iguana_msgblock msg; int32_t len; bits256 hash2; char blockhashstr[256]; uint8_t serialized[8192]; - memset(&msg,0,sizeof(msg)); - msg.H.version = version; - msg.H.merkle_root = merkle_root; - msg.H.timestamp = timestamp; - msg.H.bits = nBits; - msg.H.nonce = nonce; + struct iguana_msgzblock zmsg; struct iguana_msgblock *msg = (void *)&zmsg; int32_t len; bits256 hash2; char blockhashstr[256]; uint8_t serialized[8192]; + memset(&zmsg,0,sizeof(zmsg)); + msg->H.version = version; + msg->H.merkle_root = merkle_root; + msg->H.timestamp = timestamp; + msg->H.bits = nBits; + msg->H.nonce = nonce; if ( zcash != 0 ) printf("need to handle zcash genesis\n"); if ( hashalgostr != 0 && strcmp(hashalgostr,"sha256") != 0 ) hashalgo = iguana_hashalgo(hashalgostr); else hashalgo = blockhash_sha256; - len = iguana_rwblock(symbol,zcash,auxpow,hashalgo,1,&hash2,serialized,&msg,sizeof(1024)); + len = iguana_rwblock(myinfo,symbol,zcash,auxpow,hashalgo,1,&hash2,serialized,&zmsg,sizeof(1024)); blockhashstr[0] = 0; init_hexbytes_noT(blockhashstr,hash2.bytes,sizeof(hash2)); char str[65],str2[65]; @@ -189,8 +189,8 @@ bits256 iguana_chaingenesis(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (* char *parse_conf_line(char *line,char *field) { line += strlen(field); - for (; *line!='='&&*line!=0; line++) - break; + while ( (*line) != '=' && (*line) != 0 ) + line++; if ( *line == 0 ) return(0); if ( *line == '=' ) @@ -232,7 +232,12 @@ void set_coinconfname(char *fname,char *coinstr,char *userhome,char *coindir,cha sprintf(confname,"%s.conf",buf); } printf("userhome.(%s) coindir.(%s) confname.(%s)\n",userhome,coindir,confname); - sprintf(fname,"%s/%s/%s",userhome,coindir,confname); +#ifdef WIN32 + if ( userhome == 0 || userhome[0] == 0 ) + sprintf(fname,"%s/%s",coindir,confname); + else +#endif + sprintf(fname,"%s/%s/%s",userhome,coindir,confname); } uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *userhome,char *coindir,char *confname) @@ -273,7 +278,7 @@ uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *us sprintf(serverport,"127.0.0.1:%s",rpcport); free(rpcport); } - if ( Debuglevel > 1 ) + if ( 0 && Debuglevel > 1 ) printf("-> (%s):(%s) userpass.(%s) serverport.(%s)\n",rpcuser,rpcpassword,userpass,serverport); if ( rpcuser != 0 ) free(rpcuser); @@ -284,7 +289,7 @@ uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *us return(port); } -void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) +void iguana_chainparms(struct supernet_info *myinfo,struct iguana_chain *chain,cJSON *argjson) { extern char Userhome[]; char *path,conf[512],*hexstr,genesisblock[1024]; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; uint32_t nBits; uint8_t tmp[4]; @@ -303,14 +308,10 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) chain->estblocktime = juint(argjson,"blocktime"); if ( chain->estblocktime == 0 ) chain->estblocktime = 60; - if ( chain->havecltv == 0 ) - chain->havecltv = juint(argjson,"havecltv"); path = jstr(argjson,"path"); if ( jobj(argjson,"conf") == 0 ) conf[0] = 0; else safecopy(conf,jstr(argjson,"conf"),sizeof(conf)); - if ( conf[0] != 0 ) - printf("CONF.(%s)\n",conf); safecopy(chain->name,jstr(argjson,"name"),sizeof(chain->name)); //chain->dust = j64bits(argjson,"dust"); if ( jobj(argjson,"txfee_satoshis") != 0 ) @@ -318,10 +319,19 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) if ( chain->txfee == 0 ) chain->txfee = (uint64_t)(SATOSHIDEN * jdouble(argjson,"txfee")); chain->use_addmultisig = juint(argjson,"useaddmultisig"); + if ( (port= extract_userpass(chain->serverport,chain->userpass,chain->symbol,chain->userhome,path,conf)) != 0 ) + chain->rpcport = port; + //if ( conf[0] != 0 ) + printf("PATH.(%s) CONF.(%s)\n",path!=0?path:"",conf); if ( juint(argjson,"p2p") != 0 ) chain->portp2p = juint(argjson,"p2p"); else chain->portp2p = juint(argjson,"portp2p"); - if ( (chain->rpcport= juint(argjson,"rpc")) == 0 ) + if ( jstr(argjson,"rpchost") != 0 ) + safecopy(chain->serverport,jstr(argjson,"rpchost"),sizeof(chain->serverport)); + if ( jstr(argjson,"userpass") != 0 ) + safecopy(chain->userpass,jstr(argjson,"userpass"),sizeof(chain->userpass)); + chain->rpcport = juint(argjson,"rpcport"); + if ( chain->rpcport == 0 && (chain->rpcport= juint(argjson,"rpc")) == 0 && strcmp(chain->symbol,"RELAY") != 0 ) { if ( chain->portp2p != 0 ) chain->rpcport = chain->portp2p-1; @@ -341,6 +351,10 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) chain->rpcport = 14632; } chain->zcash = juint(argjson,"zcash"); + if ( chain->havecltv == 0 ) + chain->havecltv = juint(argjson,"havecltv") || chain->zcash; + chain->debug = juint(argjson,"debug"); + chain->fixit = juint(argjson,"fixit"); if ( (chain->normal_txversion= juint(argjson,"normal_txversion")) == 0 ) chain->normal_txversion = IGUANA_NORMAL_TXVERSION; if ( (chain->locktime_txversion= juint(argjson,"locktime_txversion")) == 0 ) @@ -357,8 +371,6 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) chain->targetspacing = NTARGETSPACING; if ( (chain->targettimespan= jint(argjson,"targettimespan")) == 0 ) chain->targettimespan = NTARGETSPACING * 60; - if ( (port= extract_userpass(chain->serverport,chain->userpass,chain->symbol,chain->userhome,path,conf)) != 0 ) - chain->rpcport = port; if ( jobj(argjson,"halving") != 0 ) chain->halvingduration = juint(argjson,"halving"); else chain->halvingduration = 210000; @@ -384,7 +396,7 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) decode_hex((uint8_t *)&chain->wiftype,1,hexstr); } } - printf("addrtypes.(%02x %02x %02x) (%d %d %d)\n",chain->pubtype,chain->p2shtype,chain->wiftype,chain->pubtype,chain->p2shtype,chain->wiftype); + printf("MINCONFIRMS.%d addrtypes.(%02x %02x %02x) (%d %d %d)\n",chain->minconfirms,chain->pubtype,chain->p2shtype,chain->wiftype,chain->pubtype,chain->p2shtype,chain->wiftype); if ( (hexstr= jstr(argjson,"netmagic")) != 0 && strlen(hexstr) == 8 ) decode_hex((uint8_t *)chain->netmagic,4,hexstr); if ( (hexstr= jstr(argjson,"unitval")) != 0 && strlen(hexstr) == 2 ) @@ -411,7 +423,7 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) chain->nBits = nBits; chain->unitval = (nBits >> 24); printf("NETMAGIC %08x unitval.%02x nBits.%08x\n",*(uint32_t *)chain->netmagic,chain->unitval,chain->nBits); - chain->genesishash2 = iguana_chaingenesis(chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,chain->genesishash2,genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),nBits,juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); + chain->genesishash2 = iguana_chaingenesis(myinfo,chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,chain->genesishash2,genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),nBits,juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); memcpy(chain->genesis_hashdata,chain->genesishash2.bytes,32); char str[65]; init_hexbytes_noT(str,chain->genesis_hashdata,32); chain->genesis_hash = clonestr(str); @@ -433,7 +445,7 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) if ( (hexstr= jstr(argjson,"genesisblock")) != 0 ) { uint8_t hexbuf[1024],*ptr,*data; int32_t datalen,hdrsize; - hdrsize = chain->zcash != 0 ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); + hdrsize = chain->zcash != 0 ? sizeof(struct iguana_msgzblockhdr) : sizeof(struct iguana_msgblockhdr); chain->genesis_hex = clonestr(hexstr); data = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,hexbuf,sizeof(hexbuf),hexstr); chain->genesishash2 = iguana_calcblockhash(chain->symbol,chain->hashalgo,data,hdrsize); @@ -456,11 +468,11 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) } } sprintf(chain->messagemagic,"%s Signed Message:\n",chain->name); - printf("COIN.%s serverport.(%s) userpass.(%s) RPCport.%u P2P.%u magic.%08x\n",chain->symbol,chain->serverport,chain->userpass,chain->rpcport,chain->portp2p,*(uint32_t *)chain->netmagic); + printf("COIN.%s serverport.(%s) RPCport.%u P2P.%u magic.%08x\n",chain->symbol,chain->serverport,chain->rpcport,chain->portp2p,*(uint32_t *)chain->netmagic); } } -void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjson) +void iguana_chaininit(struct supernet_info *myinfo,struct iguana_chain *chain,int32_t hasheaders,cJSON *argjson) { int32_t i; if ( chain->hashalgo != 0 ) @@ -479,14 +491,14 @@ void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjs if ( strcmp(chain->symbol,"BTC") == 0 ) { chain->unitval = 0x1d; - chain->txfee = 10000; + chain->txfee = 50000; chain->havecltv = 1; } - else chain->txfee = 1000000; + else chain->txfee = 10000; if ( chain->unitval == 0 ) chain->unitval = 0x1e; if ( argjson != 0 ) - iguana_chainparms(chain,argjson); + iguana_chainparms(myinfo,chain,argjson); if ( hasheaders != 0 ) { strcpy(chain->gethdrsmsg,"getheaders"); @@ -497,14 +509,16 @@ void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjs strcpy(chain->gethdrsmsg,"getblocks"); chain->bundlesize = _IGUANA_BLOCKHASHES; } + if ( chain->zcash != 0 ) + chain->bundlesize = 160; if ( strcmp(chain->symbol,"BTC") == 0 ) chain->bundlesize = 100; decode_hex((uint8_t *)chain->genesis_hashdata,32,(char *)chain->genesis_hash); - if ( chain->rpcport == 0 ) + if ( chain->rpcport == 0 && strcmp(chain->symbol,"RELAY") != 0 ) chain->rpcport = chain->portp2p + 1; } -struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createflag) +struct iguana_chain *iguana_chainfind(struct supernet_info *myinfo,char *name,cJSON *argjson,int32_t createflag) { struct iguana_chain *chain; uint32_t i; for (i=0; isymbol,"BTCD") != 0,argjson); + iguana_chaininit(myinfo,chain,strcmp(chain->symbol,"BTCD") != 0,argjson); return(chain); } continue; } if ( strcmp(name,chain->symbol) == 0 ) { - iguana_chaininit(chain,strcmp(chain->symbol,"BTCD") != 0,argjson); + iguana_chaininit(myinfo,chain,strcmp(chain->symbol,"BTCD") != 0,argjson); return(chain); } } chain = calloc(1,sizeof(*chain)); - iguana_chaininit(chain,1,argjson); + strcpy(chain->name,name); + strcpy(chain->symbol,name); + iguana_chaininit(myinfo,chain,1,argjson); return(chain); } -struct iguana_chain *iguana_findmagic(uint8_t netmagic[4]) +struct iguana_chain *iguana_findmagic(struct supernet_info *myinfo,uint8_t netmagic[4]) { struct iguana_chain *chain; uint8_t i; for (i=0; iname[0] == 0 || chain->genesis_hash == 0 ) continue; if ( memcmp(netmagic,chain->netmagic,4) == 0 ) - return(iguana_chainfind((char *)chain->symbol,0,0)); + return(iguana_chainfind(myinfo,(char *)chain->symbol,0,0)); } return NULL; } @@ -558,7 +574,7 @@ uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum) return(reward); } -struct iguana_chain *iguana_createchain(cJSON *json) +struct iguana_chain *iguana_createchain(struct supernet_info *myinfo,cJSON *json) { char *symbol,*name; struct iguana_chain *chain = 0; if ( ((symbol= jstr(json,"newcoin")) != 0 || (symbol= jstr(json,"name")) != 0) && strlen(symbol) < 8 ) @@ -567,7 +583,7 @@ struct iguana_chain *iguana_createchain(cJSON *json) strcpy(chain->symbol,symbol); if ( (name= jstr(json,"description")) != 0 && strlen(name) < 32 ) strcpy(chain->name,name); - iguana_chaininit(chain,juint(json,"hasheaders"),json); + iguana_chaininit(myinfo,chain,juint(json,"hasheaders"),json); } return(chain); } diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index c7839bebb..d2cd1c267 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,7 +14,7 @@ ******************************************************************************/ #include "exchanges777.h" -#include "peggy.h" +//#include "peggy.h" #define EXCHANGE777_DONE 1 #define EXCHANGE777_ISPENDING 2 @@ -22,16 +22,20 @@ //char *Exchange_names[] = { "poloniex", "bittrex", "btc38", "huobi", "bitstamp", "bitfinex", "btce", "coinbase", "okcoin", "lakebtc", "quadriga", "truefx", "ecb", "instaforex", "fxcm", "yahoo" }; -int32_t instantdex_updatesources(struct exchange_info *exchange,struct exchange_quote *sortbuf,int32_t n,int32_t max,int32_t ind,int32_t dir,struct exchange_quote *quotes,int32_t numquotes) +int32_t instantdex_updatesources(struct exchange_info *exchange,struct exchange_quote *sortbuf,int32_t n,int32_t max,int32_t ind,int32_t dir,struct exchange_quote *quotes,int32_t numquotes,double offset,double factor) { int32_t i; struct exchange_quote *quote; - //printf("instantdex_updatesources.%s update dir.%d numquotes.%d\n",exchange->name,dir,numquotes); + //printf("instantdex_updatesources.%s update dir.%d numquotes.%d offset %.6f\n",exchange->name,dir,numquotes,offset); for (i=0; iprice,quote->volume); if ( quote->price > SMALLVAL ) { + //printf("%s n.%d ind.%d i.%d dir.%d price %.8f vol %.8f offset %.6f\n",exchange->name,n,ind,i,dir,quote->price+offset,quote->volume,offset); + quote->price += offset; + quote->price /= factor; + quote->volume *= factor; + quote->satoshis = quote->price * SATOSHIDEN; sortbuf[n] = *quote; sortbuf[n].val = ind; sortbuf[n].exchangebits = exchange->exchangebits; @@ -45,7 +49,7 @@ int32_t instantdex_updatesources(struct exchange_info *exchange,struct exchange_ double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double basevolume,cJSON *argjson) { - char *str; double totalvol,pricesum; uint32_t timestamp; + char *str; double totalvol,pricesum,hblas[64][2],refbid,refask,factor = 1.; uint32_t timestamp; struct exchange_quote quote; int32_t i,n,dir,num,depth = 100; struct exchange_info *exchange; struct exchange_request *req,*active[64]; if ( myinfo == 0 ) @@ -64,6 +68,10 @@ double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *s memset(sortbuf,0,sizeof(*sortbuf) * max); if ( base != 0 && rel != 0 && basevolume > SMALLVAL ) { + if ( strcmp(base,"KMD") == 0 ) + base = "BTCD", factor = 50; + else if ( strcmp(rel,"KMD") == 0 ) + rel = "BTCD", factor = 0.02; for (i=num=0; inumexchanges && num < sizeof(active)/sizeof(*active); i++) { if ( (exchange= myinfo->tradingexchanges[i]) != 0 ) @@ -86,26 +94,55 @@ double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *s } } } + memset(hblas,0,sizeof(hblas)); + refbid = refask = 0.; + if ( strcmp(rel,"USD") == 0 ) + { + for (i=0; inumbids > 0 && active[i]->numasks > 0 ) + { + hblas[i][0] = active[i]->bidasks[0].price; + hblas[i][1] = active[i]->bidasks[1].price; + if ( active[i]->exchange != 0 && strcmp("poloniex",active[i]->exchange->name) == 0 ) + refbid = active[i]->bidasks[0].price, refask = active[i]->bidasks[1].price; + //printf("(%6f %.6f) ",hblas[i][0],hblas[i][1]); + } + } + //printf(" refbid %.6f refask %.7f\n",refbid,refask); + if ( refbid != 0. && refask != 0. ) + { + for (i=0; inumbids > 0 ) - n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,1,active[i]->bidasks,active[i]->numbids); + n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,1,active[i]->bidasks,active[i]->numbids,hblas[i][0],factor); else if ( dir > 0 && active[i]->numasks > 0 ) - n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,-1,&active[i]->bidasks[1],active[i]->numasks); + n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,-1,&active[i]->bidasks[1],active[i]->numasks,hblas[i][1],factor); } //printf("numexchanges.%d dir.%d %s/%s numX.%d n.%d\n",myinfo->numexchanges,dir,base,rel,num,n); if ( dir < 0 ) revsort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf)); else sort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf)); + //for (i=0; iexchange->name,pricesum/totalvol,totalvol); + //printf("dir.%d i.%d of %d %12.8f vol %.8f %s | aveprice %.8f total vol %.8f\n",dir,i,n,sortbuf[i].price,quote.volume,active[quote.val]->exchange->name,pricesum/totalvol,totalvol); } } if ( totalvol > 0. ) @@ -147,11 +184,6 @@ double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *_ else return(0); } -void prices777_processprice(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth) -{ - -} - cJSON *exchanges777_allpairs(char *baserels[][2],int32_t num) { int32_t i; char str[32]; cJSON *json,*item,*array = cJSON_CreateArray(); @@ -302,11 +334,11 @@ double exchange_setquote(struct exchange_quote *bidasks,int32_t *numbidsp,int32_ } if ( commission != 0. ) { - //printf("price %f fee %f -> ",price,prices->commission * price); + printf("price %f fee %f -> ",price,commission * price); if ( bidask == 0 ) price -= commission * price; else price += commission * price; - //printf("%f\n",price); + printf("%f\n",price); } quote = (bidask == 0) ? &bidasks[(*numbidsp)<<1] : &bidasks[((*numasksp)<<1) + 1]; quote->price = price, quote->volume = volume, quote->timestamp = timestamp, quote->orderid = orderid, quote->offerNXT = offerNXT; @@ -363,6 +395,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,double commission,c if ( strcmp(exchange->name,"kraken") == 0 ) timestamp = juint(jitem(item,2),0); else orderid = j64bits(jitem(item,2),0); + //printf("{%s} (%.8f %.8f) %f\n",jprint(item,0),price,volume,commission); } else { @@ -419,7 +452,7 @@ double exchanges777_standardprices(struct exchange_info *exchange,double commiss if ( (jsonstr= issue_curl(url)) != 0 ) { //if ( strcmp(exchangestr,"btc38") == 0 ) - //printf("(%s) -> (%s)\n",url,jsonstr); + //printf("%f (%s) -> (%s)\n",commission,url,jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { hbla = exchanges777_json_orderbook(exchange,commission,base,rel,quotes,maxdepth,json,field,"bids","asks",price,volume,invert); @@ -736,7 +769,7 @@ void exchanges777_loop(void *ptr) int32_t flag,retval,i; struct exchange_request *req; char *retstr; myinfo = SuperNET_MYINFO(0); #ifdef INCLUDE_PAX - struct peggy_info *PEGS=0; int32_t peggyflag = 0; + /*struct peggy_info *PEGS=0; int32_t peggyflag = 0; if ( strcmp(exchange->name,"PAX") == 0 ) { if ( (PEGS= myinfo->PEGS) != 0 ) @@ -746,26 +779,16 @@ void exchanges777_loop(void *ptr) _crypto_update(PEGS,PEGS->cryptovols,&PEGS->data,1,peggyflag); PEGS->lastupdate = (uint32_t)time(NULL); } - } + }*/ #endif printf("exchanges loop.(%s)\n",exchange->name); while ( 1 ) { -#ifdef INCLUDE_PAX - if ( peggyflag != 0 && PEGS != 0 ) - { - //printf("nonz peggy\n"); - PAX_idle(PEGS,peggyflag,3); - if ( time(NULL) > PEGS->lastupdate+100 ) - { - _crypto_update(PEGS,PEGS->cryptovols,&PEGS->data,1,peggyflag); - PEGS->lastupdate = (uint32_t)time(NULL); - } - } -#endif + if ( strcmp("bitcoin",exchange->name) == 0 ) + PAX_idle(myinfo); flag = retval = 0; retstr = 0; - if ( (req= queue_dequeue(&exchange->requestQ,0)) != 0 ) + if ( (req= queue_dequeue(&exchange->requestQ)) != 0 ) { //printf("dequeued %s.%c\n",exchange->name,req->func); if ( req->dead == 0 ) @@ -793,7 +816,7 @@ void exchanges777_loop(void *ptr) // queue_enqueue("Xpending",&exchange->pendingQ,&req->DL,0), flag++; //else if ( retval == EXCHANGE777_REQUEUE ) - queue_enqueue("requeue",&exchange->requestQ,&req->DL,0); + queue_enqueue("requeue",&exchange->requestQ,&req->DL); else { printf("exchanges777_process: illegal retval.%d\n",retval); @@ -816,7 +839,7 @@ void exchanges777_loop(void *ptr) iguana_statemachineupdate(myinfo,exchange); //printf("InstantDEX call update\n"); }*/ - if ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 ) + if ( (req= queue_dequeue(&exchange->pricesQ)) != 0 ) { //printf("check %s pricesQ (%s %s)\n",exchange->name,req->base,req->rel); if ( req->dead == 0 ) @@ -832,10 +855,10 @@ void exchanges777_loop(void *ptr) for (i=req->numasks=0; idepth; i++) if ( req->bidasks[(i << 1) + 1].price > SMALLVAL ) req->numasks++; - //printf("%-10s %s/%s numbids.%d numasks.%d\n",exchange->name,req->base,req->rel,req->numbids,req->numasks); - prices777_processprice(exchange,req->base,req->rel,req->bidasks,req->depth); +//printf("%-10s %s/%s numbids.%d numasks.%d\n",exchange->name,req->base,req->rel,req->numbids,req->numasks); + tradebots_processprices(myinfo,exchange,req->base,req->rel,req->bidasks,req->numbids,req->numasks); } - queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0); + queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL); } else { @@ -854,12 +877,12 @@ struct exchange_request *exchanges777_baserelfind(struct exchange_info *exchange { struct exchange_request PAD,*req,*retreq=0; memset(&PAD,0,sizeof(PAD)); - queue_enqueue("pricesQ",&exchange->pricesQ,&PAD.DL,0); - while ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 && req != &PAD ) + queue_enqueue("pricesQ",&exchange->pricesQ,&PAD.DL); + while ( (req= queue_dequeue(&exchange->pricesQ)) != 0 && req != &PAD ) { if ( ((req->invert == 0 && strcmp(base,req->base) == 0 && strcmp(rel,req->rel) == 0) || (req->invert != 0 && strcmp(rel,req->base) == 0 && strcmp(base,req->rel) == 0)) && (func < 0 || req->func == func) ) retreq = req; - queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0); + queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL); } return(retreq); } @@ -886,7 +909,7 @@ char *exchanges777_submit(struct exchange_info *exchange,struct exchange_request maxseconds = EXCHANGES777_DEFAULT_TIMEOUT; retstrp = req->retstrp; //printf("submit to %p\n",&exchange->requestQ); - queue_enqueue("exchangeQ",&exchange->requestQ,&req->DL,0); + queue_enqueue("exchangeQ",&exchange->requestQ,&req->DL); for (i=0; iissue.supports)(exchange,base,rel,argjson)) == 0 ) { - //printf("%s invalid (%s) or (%s)\n",exchange->name,base,rel); + printf("%s invalid (%s) or (%s)\n",exchange->name,base,rel); return(clonestr("{\"error\":\"invalid base or rel\"}")); } if ( depth <= 0 ) @@ -951,14 +974,14 @@ char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,i req->commission = exchange->commission; if ( monitor == 0 ) { - printf("%s submit (%s) (%s)\n",exchange->name,base,rel); + //printf("%s submit (%s) (%s)\n",exchange->name,base,rel); return(exchanges777_submit(exchange,req,'Q',maxseconds)); } else { req->func = 'M'; //printf("Monitor.%s (%s %s) invert.%d\n",exchange->name,base,rel,req->invert); - queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0); + queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL); return(clonestr("{\"result\":\"start monitoring\"}")); } } @@ -973,6 +996,7 @@ char *exchanges777_Qrequest(struct exchange_info *exchange,int32_t func,char *ba safecopy(req->rel,rel,sizeof(req->rel)); req->retstrp = calloc(1,sizeof(void *)); req->orderid = orderid; + req->argjson = jduplicate(argjson); //printf("Qrequest\n"); return(exchanges777_submit(exchange,req,func,maxseconds)); } @@ -1020,7 +1044,7 @@ void iguana_gotquotesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 //printf("got %d quotes from %s\n",n,addr->ipaddr); req = iguana_bundlereq(coin,addr,'Q',0,0); req->hashes = quotes, req->n = n; - queue_enqueue("recvQ",&exchange->recvQ,&req->DL,0); + queue_enqueue("recvQ",&exchange->recvQ,&req->DL); } struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) @@ -1035,7 +1059,7 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) if ( stringbits((char *)Exchange_funcs[i]->name) == stringbits((char *)Exchange_funcs[j]->name) ) { printf("FIRST 8 chars of Exchange_func[].name must be unique: %d.(%s) vs %d.(%s)\n",i,Exchange_funcs[i]->name,j,Exchange_funcs[j]->name); - exit(-1); + iguana_exit(0,0); } } didinit = 1; @@ -1072,18 +1096,21 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) exchange->exchangeid = exchangeid; safecopy(exchange->name,exchangestr,sizeof(exchange->name)); exchange->exchangebits = stringbits(exchange->name); - if ( (exchange->pollgap= juint(argjson,"pollgap")) < EXCHANGES777_MINPOLLGAP ) - exchange->pollgap = EXCHANGES777_MINPOLLGAP; - if ( (key= jstr(argjson,"apikey")) != 0 || (key= jstr(argjson,"key")) != 0 ) - safecopy(exchange->apikey,key,sizeof(exchange->apikey)); - if ( (secret= jstr(argjson,"apisecret")) != 0 || (secret= jstr(argjson,"secret")) != 0 ) - safecopy(exchange->apisecret,secret,sizeof(exchange->apisecret)); - if ( (userid= jstr(argjson,"userid")) != 0 ) - safecopy(exchange->userid,userid,sizeof(exchange->userid)); - if ( (tradepassword= jstr(argjson,"tradepassword")) != 0 ) - safecopy(exchange->tradepassword,tradepassword,sizeof(exchange->tradepassword)); - if ( (exchange->commission= jdouble(argjson,"commission")) > 0. ) - exchange->commission *= .01; + if ( argjson != 0 ) + { + if ( (exchange->pollgap= juint(argjson,"pollgap")) < EXCHANGES777_MINPOLLGAP ) + exchange->pollgap = EXCHANGES777_MINPOLLGAP; + if ( (key= jstr(argjson,"apikey")) != 0 || (key= jstr(argjson,"key")) != 0 ) + safecopy(exchange->apikey,key,sizeof(exchange->apikey)); + if ( (secret= jstr(argjson,"apisecret")) != 0 || (secret= jstr(argjson,"secret")) != 0 ) + safecopy(exchange->apisecret,secret,sizeof(exchange->apisecret)); + if ( (userid= jstr(argjson,"userid")) != 0 ) + safecopy(exchange->userid,userid,sizeof(exchange->userid)); + if ( (tradepassword= jstr(argjson,"tradepassword")) != 0 ) + safecopy(exchange->tradepassword,tradepassword,sizeof(exchange->tradepassword)); + if ( (exchange->commission= jdouble(argjson,"commission")) > 0. ) + exchange->commission *= .01; + } printf("ADDEXCHANGE.(%s) [%s, %s, %s] commission %.3f%% -> exchangeid.%d\n",exchangestr,exchange->apikey,exchange->userid,exchange->apisecret,exchange->commission * 100.,exchangeid); Exchanges[exchangeid] = exchange; //instantdex_FSMinit(); @@ -1104,7 +1131,7 @@ struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSO sleep(sleepflag); } } - if ( 0 && exchange != 0 ) + if ( (0) && exchange != 0 ) printf("found exchange.(%s) %p %p %p\n",exchange->name,exchange->issue.supports,exchange->issue.price,exchange->issue.allpairs); return(exchange); } @@ -1130,9 +1157,12 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle for (i=0; iname)) == 0 ) { - if ( strcmp(Exchange_funcs[i]->name,"PAX") == 0 || strcmp(Exchange_funcs[i]->name,"truefx") == 0 || strcmp(Exchange_funcs[i]->name,"fxcm") == 0 || strcmp(Exchange_funcs[i]->name,"instaforx") == 0 ) + if ( strcmp(Exchange_funcs[i]->name,"PAX") == 0 || strcmp(Exchange_funcs[i]->name,"truefx") == 0 || strcmp(Exchange_funcs[i]->name,"fxcm") == 0 || strcmp(Exchange_funcs[i]->name,"instaforex") == 0 ) + { + exchange->pollgap = 60; continue; - if ( ((exchange= exchanges777_find(Exchange_funcs[i]->name)) == 0 && (exchange= exchange_create(Exchange_funcs[i]->name,item)) != 0) || (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) + } + if ( ((exchange= exchanges777_find(Exchange_funcs[i]->name)) == 0 && (exchange= exchange_create(Exchange_funcs[i]->name,0)) != 0) || (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; } free_json(argjson); @@ -1146,6 +1176,8 @@ cJSON *iguana_pricesarray(struct supernet_info *myinfo,char *exchange,char *base } #include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfields,ignore) { @@ -1215,26 +1247,42 @@ TWO_STRINGS(InstantDEX,balance,exchange,base) TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid) { - struct exchange_info *ptr; + struct exchange_info *ptr; cJSON *argjson; char *retstr; uint64_t num = 0; if ( remoteaddr == 0 ) { if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'P',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); + { + argjson = cJSON_CreateObject(); + jaddstr(argjson,"uuid",orderid); + if ( is_decimalstr(orderid) != 0 ) + num = calc_nxt64bits(orderid); + retstr = exchanges777_Qrequest(ptr,'P',0,0,juint(json,"maxseconds"),num,0,0,argjson); + free_json(argjson); + return(retstr); + } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } else return(clonestr("{\"error\":\"no remote for this API\"}")); } TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid) { - struct exchange_info *ptr; + struct exchange_info *ptr; cJSON *argjson; char *retstr; uint64_t num = 0; if ( remoteaddr == 0 ) { if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qrequest(ptr,'C',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); + { + argjson = cJSON_CreateObject(); + jaddstr(argjson,"uuid",orderid); + if ( is_decimalstr(orderid) != 0 ) + num = calc_nxt64bits(orderid); + retstr = exchanges777_Qrequest(ptr,'C',0,0,juint(json,"maxseconds"),num,0,0,argjson); + free_json(argjson); + return(retstr); + } else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } else return(clonestr("{\"error\":\"no remote for this API\"}")); } diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index c9e2bfa04..bb3c92135 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -17,12 +17,14 @@ void iguana_initQ(queue_t *Q,char *name) { - char *tst,*str = "need to init each Q when single threaded"; + struct stritem *tst,*item; memset(Q,0,sizeof(*Q)); + item = calloc(1,sizeof(*item)+100); + strcpy(item->str,"hello, world"); strcpy(Q->name,name); - queue_enqueue(name,Q,queueitem(str),1); - if ( (tst= queue_dequeue(Q,1)) != 0 ) - free_queueitem(tst); + queue_enqueue(name,Q,&item->DL); + if ( (tst= queue_dequeue(Q)) != 0 ) + free(tst); } void iguana_initQs(struct iguana_info *coin) @@ -36,6 +38,8 @@ void iguana_initQs(struct iguana_info *coin) iguana_initQ(&coin->msgrequestQ,"msgrequestQ"); iguana_initQ(&coin->cacheQ,"cacheQ"); iguana_initQ(&coin->recvQ,"recvQ"); + iguana_initQ(&coin->jsonQ,"jsonQ"); + iguana_initQ(&coin->finishedQ,"finishedQ"); if ( coin->MAXPEERS > 0 && coin->peers != 0 ) { for (i=0; isymbol), OS_portable_path(dirname); portable_mutex_init(&coin->RTmutex); + portable_mutex_init(&coin->kmdmutex); portable_mutex_init(&coin->peers_mutex); portable_mutex_init(&coin->blocks_mutex); portable_mutex_init(&coin->special_mutex); @@ -70,6 +75,7 @@ void iguana_initcoin(struct iguana_info *coin,cJSON *argjson) iguana_meminit(&coin->blockMEM,"blockMEM",coin->blockspace,coin->blockspacesize,0); iguana_initQs(coin); coin->bindsock = -1; + coin->notarychain = -1; OS_randombytes((unsigned char *)&coin->instance_nonce,sizeof(coin->instance_nonce)); coin->startutc = (uint32_t)time(NULL); while ( time(NULL) == coin->startutc ) @@ -89,7 +95,7 @@ void iguana_initcoin(struct iguana_info *coin,cJSON *argjson) bits256 iguana_genesis(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_chain *chain) { - struct iguana_block *block,*ptr; struct iguana_msgblock msg; bits256 hash2; char str[65],str2[65]; uint8_t buf[8192],blockspace[sizeof(*block)+sizeof(*block->zRO)]; int32_t height,auxback; + struct iguana_block *block,*ptr; struct iguana_msgzblock zmsg; bits256 hash2; char str[65],str2[65]; uint8_t buf[8192],blockspace[sizeof(*block)+sizeof(struct iguana_zblock)]; int32_t height,auxback; if ( coin == 0 || chain == 0 ) return(GENESIS_PUBKEY); block = (void *)blockspace; @@ -103,37 +109,42 @@ bits256 iguana_genesis(struct supernet_info *myinfo,struct iguana_info *coin,str return(hash2); } decode_hex(buf,(int32_t)strlen(chain->genesis_hex)/2,(char *)chain->genesis_hex); - hash2 = iguana_calcblockhash(coin->symbol,coin->chain->hashalgo,buf,sizeof(struct iguana_msgblockhdr)); - auxback = coin->chain->auxpow, coin->chain->auxpow = 0; - iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,buf,&msg,sizeof(buf)); - coin->chain->auxpow = auxback; + hash2 = iguana_calcblockhash(coin->symbol,coin->chain->hashalgo,buf,chain->zcash == 0 ? sizeof(struct iguana_msgblockhdr) : sizeof(struct iguana_msgzblockhdr)); + auxback = chain->auxpow, chain->auxpow = 0; + iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,chain->auxpow,chain->hashalgo,0,&hash2,buf,(void *)&zmsg,sizeof(buf)); + chain->auxpow = auxback; if ( coin->virtualchain == 0 && coin->MAXPEERS > 1 ) { - if ( memcmp(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)) != 0 ) + if ( chain->debug == 0 && memcmp(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)) != 0 ) { bits256_str(str,hash2); - printf("genesis mismatch? zcash.%d calculated %s vs %s\n",coin->chain->zcash,str,bits256_str(str2,*(bits256 *)chain->genesis_hashdata)); + printf("genesis mismatch? zcash.%d calculated %s vs %s\n",chain->zcash,str,bits256_str(str2,*(bits256 *)chain->genesis_hashdata)); memcpy(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)); } + if ( coin->chain->debug != 0 ) + memcpy(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)); } else memcpy(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)); bits256_str(str,hash2); - printf("genesis.(%s) zcash.%d len.%d hash.%s\n",chain->genesis_hex,coin->chain->zcash,(int32_t)sizeof(msg.H),str); - iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,block,&msg,hash2,0); + if ( chain->debug != 0 ) + printf("genesis.(%s) zcash.%d len.%d hash.%s\n",chain->genesis_hex,chain->zcash,(int32_t)sizeof(zmsg.zH),str); + iguana_blockconv(chain->zcash,chain->auxpow,(void *)block,&zmsg,hash2,0); block->RO.txn_count = 1; block->RO.numvouts = 1; - block->RO.allocsize = (int32_t)(sizeof(*block) + coin->chain->zcash*sizeof(*block->zRO)); + if ( chain->zcash != 0 ) + block->RO.allocsize = sizeof(struct iguana_zblock); + else block->RO.allocsize = (int32_t)sizeof(*block); iguana_gotdata(coin,0,0); if ( (ptr= iguana_blockhashset("genesis0",coin,0,hash2,1)) != 0 ) { - iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,ptr,block); - iguana_blocksizecheck("genesis ptr",coin->chain->zcash,ptr); + iguana_blockcopy(chain->zcash,chain->auxpow,coin,ptr,block); + iguana_blocksizecheck("genesis ptr",chain->zcash,ptr); ptr->mainchain = 1; ptr->height = 0; //coin->blocks.RO[0] = block.RO; if ( coin->virtualchain != 0 || (height= iguana_chainextend(myinfo,coin,ptr)) == 0 ) { - iguana_blockzcopy(coin->chain->zcash,block,ptr); - iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,ptr); + iguana_blockzcopy(chain->zcash,block,ptr); + iguana_blockzcopy(chain->zcash,(void *)&coin->blocks.hwmchain,ptr); printf("size.%d genesis block PoW %f ptr %f\n",block->RO.allocsize,block->PoW,ptr->PoW); coin->blocks.recvblocks = coin->blocks.issuedblocks = 1; } else printf("genesis block doesnt validate for %s ht.%d\n",coin->symbol,height); @@ -144,7 +155,7 @@ bits256 iguana_genesis(struct supernet_info *myinfo,struct iguana_info *coin,str int32_t iguana_savehdrs(struct iguana_info *coin) { char fname[512],shastr[65],tmpfname[512],tmpfname2[512],str2[65],str[65],oldfname[512]; - bits256 sha256all; FILE *fp,*fp2; struct iguana_bundle *bp; int32_t hdrsi,n,retval = 0; + bits256 sha256all; FILE *fp=0,*fp2=0; struct iguana_bundle *bp; int32_t hdrsi,n,retval = 0; n = coin->blocks.hwmchain.height + 1; sprintf(tmpfname,"%s/%s/hdrs.txt",GLOBAL_TMPDIR,coin->symbol), OS_compatible_path(tmpfname); sprintf(tmpfname2,"%s/%s/hdrs.h",GLOBAL_TMPDIR,coin->symbol), OS_compatible_path(tmpfname); @@ -191,7 +202,8 @@ int32_t iguana_savehdrs(struct iguana_info *coin) printf("new hdrs.txt %ld vs (%s) %ld\n",ftell(fp),fname,(long)OS_filesize(fname)); fclose(fp); OS_renamefile(fname,oldfname); - OS_copyfile(tmpfname,fname,1); + OS_renamefile(tmpfname,fname); + //OS_copyfile(tmpfname,fname,1); } else fclose(fp); if ( fp2 != 0 ) { @@ -207,7 +219,7 @@ int32_t iguana_savehdrs(struct iguana_info *coin) return(retval); } -int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,int32_t height,bits256 hash2,bits256 hash1) +int32_t iguana_bundleinitmap(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t height,bits256 hash2,bits256 hash1) { char str[65]; struct iguana_block *block; bp->bundleheight = height; @@ -223,7 +235,7 @@ int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,i coin->current = coin->bundles[0] = bp; if ( (block= iguana_blockfind("parse",coin,hash2)) != 0 ) block->mainchain = 1, block->height = height; - if ( iguana_bundleload(coin,&bp->ramchain,bp,2) != 0 ) + if ( iguana_bundleload(myinfo,coin,&bp->ramchain,bp,2) != 0 ) { if ( coin->current != 0 && coin->current->hdrsi+1 == bp->hdrsi ) coin->current = bp; @@ -237,7 +249,7 @@ int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,i bp->emitfinish = 0; iguana_blockQ("init",coin,bp,0,hash2,1); //printf("init reqhdrs.%d\n",bp->bundleheight); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); + //queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); memset(&hash2,0,sizeof(hash2)); bp->emitfinish = 0; return(-1); @@ -246,10 +258,14 @@ int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,i void iguana_parseline(struct supernet_info *myinfo,struct iguana_info *coin,int32_t iter,FILE *fp) { - int32_t j,k,m,c,flag,bundlei,lastheight,height = -1; char checkstr[1024],line[1024]; + int32_t j,k,m,c,flag,bundlei,lastheight=0,missing=0,height = -1; char checkstr[1024],line[1024]; struct iguana_peer *addr; struct iguana_bundle *bp; bits256 allhash,hash2,hash1,zero,lastbundle; if ( coin->FULLNODE == 0 && coin->VALIDATENODE == 0 && iter > 0 ) return; + OS_randombytes((uint8_t *)&j,sizeof(j)); + if ( j < 0 ) + j = -j; + srand(j); memset(&zero,0,sizeof(zero)); lastbundle = zero; if ( coin->MAXPEERS > IGUANA_MAXPEERS ) @@ -289,22 +305,26 @@ void iguana_parseline(struct supernet_info *myinfo,struct iguana_info *coin,int3 //printf("parse line.(%s) maxpeers.%d\n",line,coin->MAXPEERS); if ( iter == 0 ) { - if ( m < 32 || (m < coin->MAXPEERS/2 && strcmp("BTCD",coin->symbol) != 0) )//&& m < 77.7 ) + if ( m < coin->MAXPEERS/2 ) { - if ( 0 && m == 0 ) + if ( (0) && m == 0 && coin->seedipaddr[0] != 0 ) { addr = &coin->peers->active[m++]; - iguana_initpeer(coin,addr,(uint32_t)calc_ipbits("127.0.0.1")); - //printf("call initpeer.(%s)\n",addr->ipaddr); + iguana_initpeer(coin,addr,(uint32_t)calc_ipbits(coin->seedipaddr)); + printf("SEED_IPADDR initpeer.(%s)\n",addr->ipaddr); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); } #ifndef IGUANA_DISABLEPEERS - addr = &coin->peers->active[m++]; - iguana_initpeer(coin,addr,(uint32_t)calc_ipbits(line)); - //printf("call initpeer.(%s)\n",addr->ipaddr); - iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); + //if ( (rand() % 2) == 0 ) + { + addr = &coin->peers->active[m++]; + iguana_initpeer(coin,addr,(uint32_t)calc_ipbits(line)); + //printf("call initpeer.(%s)\n",addr->ipaddr); + iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); + } //else #endif } + iguana_possible_peer(coin,line); } else { @@ -330,7 +350,7 @@ void iguana_parseline(struct supernet_info *myinfo,struct iguana_info *coin,int3 { //printf("created bundle.%d\n",bp->hdrsi); memset(hash1.bytes,0,sizeof(hash1)); - iguana_bundleinitmap(coin,bp,height,hash2,hash1); + iguana_bundleinitmap(myinfo,coin,bp,height,hash2,hash1); lastbundle = hash2; } } @@ -359,8 +379,13 @@ void iguana_parseline(struct supernet_info *myinfo,struct iguana_info *coin,int3 } if ( height >= lastheight ) { - if ( iguana_bundleinitmap(coin,bp,height,hash2,hash1) == 0 ) + if ( iguana_bundleinitmap(myinfo,coin,bp,height,hash2,hash1) == 0 ) lastbundle = hash2, lastheight = height; + else if ( missing++ > coin->MAXBUNDLES && strcmp("BTCD",coin->symbol) != 0 ) + { + printf("missing.%d\n",missing); + break; + } } } } @@ -378,14 +403,18 @@ void iguana_parseline(struct supernet_info *myinfo,struct iguana_info *coin,int3 long iguana_bundlesload(struct supernet_info *myinfo,struct iguana_info *coin) { - char fname[1024]; int32_t iter = 1; FILE *fp; long fpos = -1; - sprintf(fname,"%s/%s_%s.txt",GLOBAL_CONFSDIR,coin->symbol,(iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); - if ( (fp= fopen(fname,"r")) != 0 ) + char fname[1024]; int32_t iter; FILE *fp; long fpos = -1; + for (iter=0; iter<2; iter++) { - iguana_parseline(myinfo,coin,iter,fp); - printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos); - fpos = ftell(fp); - fclose(fp); + sprintf(fname,"%s/%s_%s.txt",GLOBAL_CONFSDIR,coin->symbol,(iter == 0) ? "hdrs" : "oldhdrs"), OS_compatible_path(fname); + if ( (fp= fopen(fname,"r")) != 0 ) + { + iguana_parseline(myinfo,coin,1,fp); + printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos); + fpos = ftell(fp); + fclose(fp); + break; + } } return(fpos); } @@ -438,41 +467,35 @@ void iguana_blockspurge(struct iguana_info *coin) } coin->blocks.hash = 0; } - /*if ( coin->blocks.RO != 0 ) - { - printf("deprecated coin->blocks.RO used??\n"); - myfree(coin->blocks.RO,coin->blocks.maxbits * sizeof(*coin->blocks.RO)); - coin->blocks.RO = 0; - } - coin->blocks.maxbits = */coin->blocks.maxblocks = coin->blocks.initblocks = coin->blocks.hashblocks = coin->blocks.issuedblocks = coin->blocks.recvblocks = coin->blocks.emitblocks = coin->blocks.parsedblocks = coin->blocks.dirty = 0; + coin->blocks.maxblocks = coin->blocks.initblocks = coin->blocks.hashblocks = coin->blocks.issuedblocks = coin->blocks.recvblocks = coin->blocks.emitblocks = coin->blocks.parsedblocks = coin->blocks.dirty = 0; printf("clear hwmchain\n"); memset(&coin->blocks.hwmchain,0,sizeof(coin->blocks.hwmchain)); } void iguana_coinpurge(struct iguana_info *coin) { - int32_t i,saved; struct iguana_bundle *bp; char *hashstr; struct iguana_bundlereq *req; struct iguana_blockreq *breq; struct iguana_helper *ptr; + int32_t i,saved; struct iguana_bundle *bp; struct iguana_bundlereq *req; struct iguana_blockreq *breq; struct iguana_helper *ptr; struct stritem *hashitem; saved = coin->active, coin->active = 0; coin->started = 0; while ( coin->idletime == 0 && coin->emitbusy > 0 ) { - printf("coinpurge.%s waiting for idle %lu emitbusy.%d\n",coin->symbol,time(NULL),coin->emitbusy); + printf("coinpurge.%s waiting for idle %u emitbusy.%d\n",coin->symbol,(uint32_t)time(NULL),coin->emitbusy); sleep(1); } coin->RTgenesis = 0; - while ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) + while ( (ptr= queue_dequeue(&bundlesQ)) != 0 ) myfree(ptr,ptr->allocsize); if ( 1 ) { - while ( (hashstr= queue_dequeue(&coin->hdrsQ,1)) != 0 ) - free_queueitem(hashstr); - while ( (breq= queue_dequeue(&coin->blocksQ,0)) != 0 ) + while ( (hashitem= queue_dequeue(&coin->hdrsQ)) != 0 ) + free(hashitem); + while ( (breq= queue_dequeue(&coin->blocksQ)) != 0 ) myfree(breq,sizeof(*breq)); - while ( (breq= queue_dequeue(&coin->priorityQ,0)) != 0 ) + while ( (breq= queue_dequeue(&coin->priorityQ)) != 0 ) myfree(breq,sizeof(*breq)); - while ( (req= queue_dequeue(&coin->cacheQ,0)) != 0 ) + while ( (req= queue_dequeue(&coin->cacheQ)) != 0 ) myfree(req,req->allocsize); - while ( (req= queue_dequeue(&coin->recvQ,0)) != 0 ) + while ( (req= queue_dequeue(&coin->recvQ)) != 0 ) { if ( req->blocks != 0 ) myfree(req->blocks,sizeof(*req->blocks) * req->n), req->blocks = 0; @@ -493,9 +516,32 @@ void iguana_coinpurge(struct iguana_info *coin) coin->active = saved; } -struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags) +int32_t iguana_isnotarychain(char *symbol) { - FILE *fp; char fname[512],*symbol; int32_t iter; long fpos; bits256 lastbundle; struct supernet_info *myinfo = SuperNET_MYINFO(0); + int32_t i,n,notarychain = -1; char *jsonstr; cJSON *chains; + if ( (jsonstr= dpow_notarychains(0,0,0,0)) != 0 ) + { + if ( (chains= cJSON_Parse(jsonstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(chains)) > 0 ) + { + for (i=0; ipeers == 0 ) { printf("cant start privatechain directly\n"); @@ -518,7 +564,7 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei printf("%s MYSERVICES.%llx\n",coin->symbol,(long long)coin->myservices); if ( coin->virtualchain == 0 && coin->peers != 0 ) { - if ( (coin->myservices & NODE_NETWORK) != 0 || (coin->FULLNODE != 0 || coin->VALIDATENODE != 0) ) + if ( myinfo->IAMNOTARY != 0 || (coin->myservices & NODE_NETWORK) != 0 || (coin->FULLNODE > 0 || coin->VALIDATENODE > 0) ) { if ( coin->peers->acceptloop == 0 && coin->peers->localaddr == 0 ) { @@ -531,7 +577,7 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei } } } - if ( coin->FULLNODE != 0 && coin->rpcloop == 0 ) + if ( coin->rpcloop == 0 && strcmp(coin->chain->symbol,"RELAY") != 0 ) { myinfo->argport = coin->chain->rpcport; coin->rpcloop = malloc(sizeof(pthread_t)); @@ -542,6 +588,11 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei printf("error launching rpcloop for %s port.%u\n",coin->symbol,coin->chain->rpcport); } } + } + if ( (coin->notarychain= iguana_isnotarychain(coin->symbol)) >= 0 && coin->FULLNODE == 0 ) + { + printf("SET %s NOTARYCHAIN.%d\n",coin->symbol,coin->notarychain); + return(coin); } //coin->firstblock = coin->blocks.parsedblocks + 1; iguana_genesis(myinfo,coin,coin->chain); @@ -588,21 +639,36 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei { } #endif - sprintf(fname,"%s/%s_%s.txt",GLOBAL_CONFSDIR,coin->symbol,(iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); - //sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); - //sprintf(fname,"tmp/%s/%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); - OS_compatible_path(fname); - if ( (fp= fopen(fname,"r")) != 0 ) + fpos = -1; + for (j=0; j<2; j++) { - if ( coin->virtualchain == 0 || iter > 0 ) + + /** + * macro switch for easy debug from Visual Studio IDE + * @author-fadedreamz@gmail.com + */ +#if defined(WIN32) && defined(_DEBUG) + sprintf(fname, "%s/%s/%s_%s%s.txt", "iguana", GLOBAL_CONFSDIR, coin->symbol, j == 0 ? "" : "old", (iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); +#else + sprintf(fname,"%s/%s_%s%s.txt",GLOBAL_CONFSDIR,coin->symbol,j==0?"":"old",(iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); +#endif + //sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); + //sprintf(fname,"tmp/%s/%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); + OS_compatible_path(fname); + printf("check.(%s)\n",fname); + if ( (fp= fopen(fname,"r")) != 0 ) { - printf("parsefile.%d %s\n",iter,fname); - iguana_parseline(myinfo,coin,iter,fp); - printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos); + if ( coin->virtualchain == 0 || iter > 0 ) + { + printf("parsefile.%d %s\n",iter,fname); + iguana_parseline(myinfo,coin,iter,fp); + printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos); + } + fpos = ftell(fp); + fclose(fp); + break; } - fpos = ftell(fp); - fclose(fp); - } else fpos = -1; + } } #ifndef IGUANA_DEDICATED_THREADS coin->peers->peersloop = iguana_launch("peersloop",iguana_peersloop,coin,IGUANA_PERMTHREAD); diff --git a/iguana/iguana_interpreter.c b/iguana/iguana_interpreter.c index 0ad66ed15..d979752f6 100755 --- a/iguana/iguana_interpreter.c +++ b/iguana/iguana_interpreter.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -498,7 +498,7 @@ static int32_t iguana_pushdata(struct iguana_interpreter *stacks,int64_t num64,u struct iguana_stackdata Snum; cJSON *item = 0; char tmpstr[2048]; int32_t num = (int32_t)num64; if ( stacks->lastpath[stacks->ifdepth] < 0 ) return(0); - printf("PUSH.(%lld %p %d)\n",(long long)num64,numbuf,numlen); + //printf("PUSH.(%lld %p %d)\n",(long long)num64,numbuf,numlen); if ( stacks->maxstackdepth > 0 ) { /*if ( numbuf != 0 ) @@ -726,17 +726,26 @@ void iguana_stack(struct iguana_interpreter *stacks,struct iguana_stackdata *arg int32_t iguana_checksig(struct iguana_info *coin,struct iguana_stackdata pubkeyarg,struct iguana_stackdata sigarg,bits256 sigtxid) { - uint8_t pubkey[MAX_SCRIPT_ELEMENT_SIZE],sig[MAX_SCRIPT_ELEMENT_SIZE]; int32_t plen,siglen; + uint8_t pubkey[MAX_SCRIPT_ELEMENT_SIZE],sig[MAX_SCRIPT_ELEMENT_SIZE]; int32_t retval,plen,siglen; plen = iguana_databuf(pubkey,pubkeyarg); siglen = iguana_databuf(sig,sigarg); - int32_t i; for (i=0; i 0 && siglen > 0 && siglen < 74 ) - return(bitcoin_verify(coin->ctx,sig,siglen-1,sigtxid,pubkey,plen) == 0); + { + if ( (retval= (bitcoin_verify(coin->ctx,sig,siglen-1,sigtxid,pubkey,plen) == 0)) == 0 ) + { + } + if ( (0) ) + { + int32_t i; char str[65]; + for (i=0; istackdepth); for (i=0; istackdepth <= 0 ) @@ -800,6 +810,8 @@ int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter if ( stacks->stackdepth <= 0 ) return(0); m = (int32_t)iguana_num(iguana_pop(stacks)); +//printf("m.%d stackdepth.%d\n",m,stacks->stackdepth); + if ( m != M ) { printf("iguana_checkmultisig m.%d != M.%d\n",m,M); @@ -818,7 +830,7 @@ int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter } if ( i == numsigners ) { - //char str[65]; printf("sigtxid.(%s)\n",bits256_str(str,txhash2)); + //char str[65]; printf("depth.%d sigtxid.(%s)\n",stacks->stackdepth,bits256_str(str,txhash2)); if ( stacks->stackdepth > 0 ) iguana_pop(stacks); // for backward compatibility j = numsigners-1; @@ -837,7 +849,7 @@ int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter } } } - printf("valid.%d j.%d M.%d N.%d numsigners.%d\n",valid,j,M,N,numsigners); + printf("checkmultisig: valid.%d j.%d M.%d N.%d numsigners.%d\n",valid,j,M,N,numsigners); return(0); } @@ -846,12 +858,21 @@ int32_t iguana_checklocktimeverify(struct iguana_info *coin,int64_t tx_lockval,u { int64_t nLockTime = iguana_num(Snum); if ( nLockTime < 0 || tx_lockval < 0 ) + { + printf("CLTV.0 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); return(-1); + } else if ( ((tx_lockval < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || (tx_lockval >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)) == 0 ) + { + printf("CLTV.1 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); return(-1); + } else if ( nLockTime > tx_lockval ) + { + printf("CLTV.2 nLockTime.%lld tx_lockval.%lld\n",(long long)nLockTime,(long long)tx_lockval); return(-1); + } return(0); } @@ -949,9 +970,12 @@ int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen n = (n << 8) | script[i++]; n = (n << 8) | script[i++]; n = (n << 8) | script[i++]; - for (j=0; j 0 ) { if ( (array= jarray(&n,interpreter,"args")) == 0 || (interpret != 0 && n != numvars) ) @@ -1017,8 +1041,8 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip if ( V->suppress_pubkeys == 0 && (V->spendscript[0] != plen || V->spendscript[V->spendlen - 1] != IGUANA_OP_CHECKSIG || bitcoin_pubkeylen(&V->spendscript[1]) <= 0) ) { iguana_pushdata(stacks,0,V->signers[i].pubkey,plen); - printf(">>>>>>>>> suppress.%d pushdata plen.%d depth.%d\n",V->suppress_pubkeys,plen,stacks->stackdepth); - } else printf("<<<<<<<<<< skip pubkey push %d script[0].%d spendlen.%d depth.%d\n",plen,V->spendscript[0],V->spendlen,stacks->stackdepth); + //printf(">>>>>>>>> suppress.%d pushdata [%02x %02x] plen.%d depth.%d\n",V->suppress_pubkeys,V->signers[i].pubkey[0],V->signers[i].pubkey[1],plen,stacks->stackdepth); + } // else printf("<<<<<<<<<< skip pubkey push %d script[0].%d spendlen.%d depth.%d\n",plen,V->spendscript[0],V->spendlen,stacks->stackdepth); } } if ( V->userdatalen != 0 ) @@ -1053,7 +1077,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip free(stacks); return(-1); } - printf("user data stackdepth.%d dlen.%d\n",stacks->stackdepth,dlen); + //printf("user data stackdepth.%d dlen.%d\n",stacks->stackdepth,dlen); } if ( len != V->userdatalen ) { @@ -1143,7 +1167,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip break; } HASH_FIND(hh,OPTABLE,str,j,op); - printf("{%s}\n",str); + //printf("{%s}\n",str); str += j; if ( op != 0 ) { @@ -1276,7 +1300,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip { if ( stacks->stackdepth < op->stackitems ) { - printf("stackdepth.%d needed.%d (%s) at offset.%ld\n",stacks->stackdepth,op->stackitems,str,(long)str-(long)asmstr); + //printf("stackdepth.%d needed.%d (%s) at offset.%ld\n",stacks->stackdepth,op->stackitems,str,(long)str-(long)asmstr); errs++; break; } @@ -1310,20 +1334,22 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip iguana_pushdata(stacks,1,0,0); else { + iguana_pushdata(stacks,0,0,0); for (i=0; iopcode,args[0].size,args[1].size); } } else if ( (op->flags & IGUANA_CRYPTOFLAG) != 0 ) { - uint8_t rmd160[20]; bits256 hash; + uint8_t rmd160[20],revdatabuf[MAX_SCRIPT_ELEMENT_SIZE]; bits256 hash; datalen = iguana_databuf(databuf,args[0]); + for (i=0; iopcode ) { case IGUANA_OP_RIPEMD160: @@ -1335,11 +1361,39 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); break; case IGUANA_OP_HASH160: + /*if ( datalen == 32 ) + { + revcalc_rmd160_sha256(rmd160,*(bits256 *)databuf); + printf("SPECIAL CASE REVERSE\n"); + } else + for (i=0; i<32; i++) + printf("%02x",databuf[i]); + printf(" <- databuf\n"); + for (i=0; i<32; i++) + printf("%02x",revdatabuf[i]); + printf(" <- revdatabuf\n"); + calc_rmd160_sha256(rmd160,revdatabuf,datalen); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 revdatabuf\n"); + revcalc_rmd160_sha256(rmd160,*(bits256 *)databuf); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 special\n"); calc_rmd160_sha256(rmd160,databuf,datalen); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" <- rmd160 databuf\n");*/ + if ( datalen == 32 ) + calc_rmd160_sha256(rmd160,revdatabuf,datalen); + else calc_rmd160_sha256(rmd160,databuf,datalen); iguana_pushdata(stacks,0,rmd160,sizeof(rmd160)); break; case IGUANA_OP_SHA256: vcalc_sha256(0,hash.bytes,databuf,datalen); + for (i=0; i sha256 %s\n",bits256_str(str,hash)); iguana_pushdata(stacks,0,hash.bytes,sizeof(hash)); break; case IGUANA_OP_HASH256: @@ -1362,7 +1416,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip } else if ( op->opcode == IGUANA_OP_CHECKLOCKTIMEVERIFY ) // former OP_NOP2 { - if ( iguana_checklocktimeverify(coin,nLockTime,V->sequence,args[0]) < 0 ) + if ( V->ignore_cltverr == 0 && iguana_checklocktimeverify(coin,nLockTime,V->sequence,args[0]) < 0 ) { iguana_stack(stacks,args,1,"0",""); errs++; @@ -1384,6 +1438,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip } else if ( (op->flags & IGUANA_STACKFLAG) != 0 ) { + val = 0; if ( op->opcode == IGUANA_OP_PICK || op->opcode == IGUANA_OP_ROLL ) { if ( interpret != 0 && stacks->stackdepth < (val= iguana_num(args[0])) ) @@ -1451,7 +1506,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip } else if ( (op->flags & IGUANA_MATHFLAG) != 0 ) { - int64_t numA,numB,numC; + int64_t numA=0,numB=0,numC=0; for (i=0; istackitems; i++) { if ( args[i].size != sizeof(int32_t) ) @@ -1545,7 +1600,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip } else if ( iguana_isnonz(stacks->stack[--stacks->stackdepth]) != 0 ) { - printf("Evaluate true, depth.%d errs.%d k.%d\n",stacks->stackdepth,errs,k); + //printf("Evaluate true, depth.%d errs.%d k.%d\n",stacks->stackdepth,errs,k); if ( errs == 0 ) jadd(interpreter,"result",jtrue()); else jadd(interpreter,"result",jfalse()); @@ -1554,9 +1609,9 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip { jadd(interpreter,"result",jfalse()); printf("Evaluate FALSE, depth.%d errs.%d [0] size.%d num.%d\n",stacks->stackdepth,errs,stacks->stack[0].size,stacks->stack[0].U.val); + if ( stacks->logarray != 0 ) + printf("LOG.(%s)\n\n",jprint(stacks->logarray,0)); } - //if ( stacks->logarray != 0 ) - // printf("LOG.(%s)\n",jprint(stacks->logarray,0)); if ( numargs > 0 ) { for (i=0; irpcport,agentstr,method); + sprintf(curl,"curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"%s\\\",\\\"method\\\":\\\"%s\\\"",myinfo->rpcport,agentstr,method); if ( methodargs != 0 && (n= cJSON_GetArraySize(methodargs)) > 0 ) { //printf("method.%s n.%d %s\n",method,n,jprint(methodargs,0)); @@ -128,6 +128,7 @@ cJSON *SuperNET_helpjson() #define IGUANA_HELP_HH(agent,name,hash,hash2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#hash2,"hash"))) #define IGUANA_HELP_HA(agent,name,hash,obj) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#obj,"array"))) #define IGUANA_HELP_HS(agent,name,hash,str) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#str,"str"))) +#define IGUANA_HELP_HSI(agent,name,hash,str,val) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#str,"str"),helpitem(#val,"int"))) #define IGUANA_HELP_HII(agent,name,hash,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#val,"int"),helpitem(#val2,"int"))) #define IGUANA_HELP_HHS(agent,name,hash,hash2,str) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#hash2,"hash"),helpitem(#str,"str"))) #define IGUANA_HELP_HAS(agent,name,hash,obj,str) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#obj,"array"),helpitem(#str,"str"))) @@ -152,6 +153,7 @@ cJSON *SuperNET_helpjson() #define STRING_AND_INT IGUANA_HELP_SI #define STRING_AND_TWOINTS IGUANA_HELP_SII #define HASH_AND_STRING IGUANA_HELP_HS +#define HASH_AND_STRING_AND_INT IGUANA_HELP_HSI #define HASH_AND_INT IGUANA_HELP_HI #define HASH_AND_TWOINTS IGUANA_HELP_HII #define DOUBLE_ARG IGUANA_HELP_D @@ -189,7 +191,10 @@ cJSON *SuperNET_helpjson() #include "../includes/iguana_apideclares.h" +#undef IGUANA_ARGS +#undef _IGUANA_APIDEC_H_ #include "../includes/iguana_apiundefs.h" + if ( array != 0 ) jadd(json,"API",array); jadd(json,"agents",agents); @@ -198,7 +203,7 @@ cJSON *SuperNET_helpjson() int32_t agentform(FILE *fp,char *form,int32_t max,char *agent,cJSON *methoditem) { - cJSON *item,*fieldsarray; int32_t j,m,width,size = 0; + cJSON *item,*fieldsarray; int32_t j,m,width=1,size = 0; struct supernet_info *myinfo = SuperNET_MYINFO(0); char *methodstr,*typestr,outstr[2048],outstr2[2048],fields[8192],str[2],agent_method[256],*fieldname; form[0] = 0; if ( (methodstr= jstr(methoditem,"method")) == 0 ) @@ -247,7 +252,7 @@ int32_t agentform(FILE *fp,char *form,int32_t max,char *agent,cJSON *methoditem) //printf("fields[%d] (%s)\n",j,fields); } } else sprintf(fields+strlen(fields),"%s ",agent_method); - sprintf(&form[size],"
%s
",agent,methodstr,outstr,fields,outstr2,methodstr); + sprintf(&form[size],"
%s
",myinfo->rpcport,agent,methodstr,outstr,fields,outstr2,methodstr); if ( fp != 0 ) fprintf(fp,"%s\n",&form[size]); //printf("%s\n",&form[size]); @@ -263,7 +268,11 @@ int32_t template_emit(char *retbuf,int32_t maxsize,char *template,char *varname, varnamelen = (int32_t)strlen(varname); while ( (match= strstr(varname,&template[offset])) != 0 ) { +#if defined(_M_X64) + position = (int32_t)((uint64_t)match - (uint64_t)&template[offset]); +#else position = (int32_t)((long)match - (long)&template[offset]); +#endif printf("found match.(%s) at %d offset.%d\n",varname,position,offset); if ( size + (valuelen + position) > maxsize ) return(-1); @@ -287,7 +296,7 @@ int32_t templates_emit(char *retbuf,int32_t maxsize,char *template,char *agent,c int32_t pretty_form(FILE *fp,char *formheader,char *formfooter,char *fieldtemplate,char *agent,cJSON *methoditem,cJSON *helpitem,char *suffix) { - cJSON *item,*fieldsarray; int32_t j,m,formsize,fieldsize,iter,width,size = 0; + cJSON *item,*fieldsarray; int32_t j,m,formsize,fieldsize,iter,width=1,size = 0; char *methodstr,*typestr,*fieldname,*helpstr,*curlstr,*urlstr,*itemhelp; char outstr[2048],outstr2[2048],str[2],widthstr[16],both[512]; if ( (methodstr= jstr(methoditem,"method")) == 0 ) @@ -487,416 +496,13 @@ char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr) return(OS_filestr(&filesize,"index7778.html")); } -cJSON *iguana_peerjson(struct iguana_info *coin,struct iguana_peer *addr) -{ - cJSON *array,*json = cJSON_CreateObject(); - jaddstr(json,"ipaddr",addr->ipaddr); - if ( addr->supernet != 0 ) - jaddstr(json,"ipaddr",addr->ipaddr); - jaddstr(json,"supernet","yes"); - jaddnum(json,"protover",addr->protover); - jaddnum(json,"relay",addr->relayflag); - jaddnum(json,"height",addr->height); - jaddnum(json,"rank",addr->rank); - jaddnum(json,"usock",addr->usock); - if ( addr->dead != 0 ) - jaddnum(json,"dead",addr->dead); - jaddnum(json,"ready",addr->ready); - jaddnum(json,"recvblocks",addr->recvblocks); - jaddnum(json,"recvtotal",addr->recvtotal); - jaddnum(json,"lastcontact",addr->lastcontact); - if ( addr->numpings > 0 ) - jaddnum(json,"aveping",addr->pingsum/addr->numpings); - array = cJSON_CreateObject(); - jaddnum(array,"version",addr->msgcounts.version); - jaddnum(array,"verack",addr->msgcounts.verack); - jaddnum(array,"getaddr",addr->msgcounts.getaddr); - jaddnum(array,"addr",addr->msgcounts.addr); - jaddnum(array,"inv",addr->msgcounts.inv); - jaddnum(array,"getdata",addr->msgcounts.getdata); - jaddnum(array,"notfound",addr->msgcounts.notfound); - jaddnum(array,"getblocks",addr->msgcounts.getblocks); - jaddnum(array,"getheaders",addr->msgcounts.getheaders); - jaddnum(array,"headers",addr->msgcounts.headers); - jaddnum(array,"tx",addr->msgcounts.tx); - jaddnum(array,"block",addr->msgcounts.block); - jaddnum(array,"mempool",addr->msgcounts.mempool); - jaddnum(array,"ping",addr->msgcounts.ping); - jaddnum(array,"pong",addr->msgcounts.pong); - jaddnum(array,"reject",addr->msgcounts.reject); - jaddnum(array,"filterload",addr->msgcounts.filterload); - jaddnum(array,"filteradd",addr->msgcounts.filteradd); - jaddnum(array,"filterclear",addr->msgcounts.filterclear); - jaddnum(array,"merkleblock",addr->msgcounts.merkleblock); - jaddnum(array,"alert",addr->msgcounts.alert); - jadd(json,"msgcounts",array); - return(json); -} - -cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly) -{ - cJSON *retjson,*array; int32_t i; struct iguana_peer *addr; - if ( coin == 0 || coin->peers == 0 ) - return(0); - array = cJSON_CreateArray(); - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers->active[i]; - if ( addr->usock >= 0 && addr->ipbits != 0 && addr->ipaddr[0] != 0 ) - { - if ( addronly != 0 ) - jaddistr(array,addr->ipaddr); - else jaddi(array,iguana_peerjson(coin,addr)); - } - } - if ( addronly == 0 ) - { - retjson = cJSON_CreateObject(); - jadd(retjson,"peers",array); - jaddnum(retjson,"maxpeers",coin->MAXPEERS); - jaddstr(retjson,"coin",coin->symbol); - return(retjson); - } - else return(array); -} - -#include "../includes/iguana_apidefs.h" - -STRING_ARG(iguana,peers,activecoin) -{ - if ( coin != 0 ) - return(jprint(iguana_peersjson(coin,0),1)); - else return(clonestr("{\"error\":\"peers needs coin\"}")); -} - -STRING_ARG(iguana,getconnectioncount,activecoin) -{ - int32_t i,num = 0; char buf[512]; - if ( coin != 0 && coin->peers != 0 ) - { - for (i=0; ipeers->active)/sizeof(*coin->peers->active); i++) - if ( coin->peers->active[i].usock >= 0 ) - num++; - sprintf(buf,"{\"result\":\"%d\"}",num); - return(clonestr(buf)); - } else return(clonestr("{\"error\":\"getconnectioncount needs coin\"}")); -} - -ZERO_ARGS(bitcoinrpc,getdifficulty) -{ - char buf[512]; - if ( coin != 0 ) - { - sprintf(buf,"{\"result\":\"success\",\"proof-of-work\":\"%.8f\",\"search-interval\": 0}",PoW_from_compact(coin->blocks.hwmchain.RO.bits,coin->chain->unitval)); - return(clonestr(buf)); - } else return(clonestr("{\"error\":\"getdifficulty needs coin\"}")); -} - -STRING_ARG(iguana,addcoin,newcoin) -{ - char *symbol; int32_t retval; - if ( (symbol= newcoin) == 0 && coin != 0 ) - symbol = coin->symbol; - if ( symbol != 0 ) - { - printf(">> addcoin.%s\n",symbol); -#ifdef __PNACL__ -// if ( strcmp(symbol,"BTC") == 0 ) -// return(clonestr("{\"result\":\"BTC for chrome app is not yet\"}")); +#ifdef WIN32 +/** +* workaround for MSVS compiler bug - +* instead of going on if-else-if block split the if-else-if into two function +*/ +char *SuperNET_parser2(struct supernet_info *myinfo, char *agentstr, char *method, cJSON *json, char *remoteaddr); #endif - if ( (retval= iguana_launchcoin(myinfo,symbol,json,0)) > 0 ) - { - if ( myinfo->rpcsymbol[0] == 0 ) - safecopy(myinfo->rpcsymbol,symbol,sizeof(myinfo->rpcsymbol)); - return(clonestr("{\"result\":\"coin added\"}")); - } - else if ( retval == 0 ) - return(clonestr("{\"result\":\"coin already there\"}")); - else return(clonestr("{\"error\":\"error adding coin\"}")); - } else return(clonestr("{\"error\":\"addcoin needs newcoin\"}")); -} - -STRING_ARG(iguana,startcoin,activecoin) -{ - if ( coin != 0 ) - { - coin->active = 1; - return(clonestr("{\"result\":\"coin started\"}")); - } else return(clonestr("{\"error\":\"startcoin needs coin\"}")); -} - -STRING_ARG(iguana,stopcoin,activecoin) -{ - if ( activecoin[0] != 0 ) - coin = iguana_coinfind(activecoin); - if ( coin != 0 ) - { - coin->active = 0; - //iguana_coinpurge(coin); - return(clonestr("{\"result\":\"coin stopped\"}")); - } else return(clonestr("{\"error\":\"stopcoin needs coin\"}")); -} - -STRING_ARG(iguana,pausecoin,activecoin) -{ - if ( coin != 0 ) - { - coin->active = 0; - return(clonestr("{\"result\":\"coin paused\"}")); - } else return(clonestr("{\"error\":\"pausecoin needs coin\"}")); -} - -TWO_STRINGS(iguana,addnode,activecoin,ipaddr) -{ - struct iguana_peer *addr; int32_t i,n; - if ( coin == 0 ) - coin = iguana_coinfind(activecoin); - printf("coin.%p.[%s] addnode.%s -> %s\n",coin,coin!=0?coin->symbol:"",activecoin,ipaddr); - if ( coin != 0 && coin->peers != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 ) - { - //iguana_possible_peer(coin,ipaddr); - if ( (addr= iguana_peerslot(coin,(uint32_t)calc_ipbits(ipaddr),1)) != 0 ) - { - addr->supernet = 1; - if ( addr->usock >= 0 ) - { - if ( (n= coin->peers->numranked) != 0 ) - { - for (i=0; ipeers->ranked[i] ) - break; - } - if ( i == n ) - { - if ( i == IGUANA_MAXPEERS ) - i--; - else coin->peers->numranked = n+1; - coin->peers->ranked[i] = addr; - addr->recvblocks = coin->peers->ranked[0]->recvblocks + 100; - addr->recvtotal = coin->peers->ranked[0]->recvtotal*1.1 + 100; - printf("set (%s) -> slot.%d numranked.%d\n",ipaddr,i,coin->peers->numranked); - } else printf("(%s) is already peer.%d\n",ipaddr,i); - } - return(clonestr("{\"result\":\"peer was already connected\"}")); - } - if ( addr->pending == 0 ) - { - addr->pending = (uint32_t)time(NULL); - iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); - return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"result\":\"addnode connection was already pending\"}")); - } else return(clonestr("{\"result\":\"addnode cant find peer slot\"}")); - } - else if ( coin == 0 ) - return(clonestr("{\"error\":\"addnode needs active coin, do an addcoin first\"}")); - else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); -} - -TWO_STRINGS(iguana,persistent,activecoin,ipaddr) -{ - int32_t i; - if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) - { - for (i=0; ipeers->active[i].ipaddr,ipaddr) == 0 ) - { - coin->peers->active[i].persistent_peer = juint(json,"interval")+3; - return(clonestr("{\"result\":\"node marked as persistent\"}")); - } - } - return(clonestr("{\"result\":\"node wasnt active\"}")); - } else return(clonestr("{\"error\":\"persistent needs coin and ipaddr\"}")); -} - -TWO_STRINGS(iguana,removenode,activecoin,ipaddr) -{ - int32_t i; - if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) - { - for (i=0; ipeers->active[i].ipaddr,ipaddr) == 0 ) - { - coin->peers->active[i].rank = 0; - coin->peers->active[i].dead = (uint32_t)time(NULL); - return(clonestr("{\"result\":\"node marked as dead\"}")); - } - } - return(clonestr("{\"result\":\"node wasnt active\"}")); - } else return(clonestr("{\"error\":\"removenode needs coin and ipaddr\"}")); -} - -TWO_STRINGS(iguana,oneshot,activecoin,ipaddr) -{ - if ( coin != 0 && ipaddr != 0 ) - { - iguana_possible_peer(coin,ipaddr); - return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"error\":\"addnode needs coin and ipaddr\"}")); -} - -TWO_STRINGS(iguana,nodestatus,activecoin,ipaddr) -{ - int32_t i; struct iguana_peer *addr; - if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) - { - for (i=0; iMAXPEERS; i++) - { - addr = &coin->peers->active[i]; - if ( strcmp(addr->ipaddr,ipaddr) == 0 ) - return(jprint(iguana_peerjson(coin,addr),1)); - } - return(clonestr("{\"result\":\"nodestatus couldnt find ipaddr\"}")); - } else return(clonestr("{\"error\":\"nodestatus needs ipaddr\"}")); -} - -STRING_AND_INT(iguana,maxpeers,activecoin,max) -{ - cJSON *retjson; int32_t i; struct iguana_peer *addr; - if ( coin != 0 && coin->peers != 0 ) - { - retjson = cJSON_CreateObject(); - if ( max > IGUANA_MAXPEERS ) - max = IGUANA_MAXPEERS; - if ( max > coin->MAXPEERS ) - { - for (i=max; iMAXPEERS; i++) - if ( (addr= coin->peers->ranked[i]) != 0 ) - addr->dead = 1; - } - coin->MAXPEERS = max; - jaddnum(retjson,"maxpeers",coin->MAXPEERS); - jaddstr(retjson,"coin",coin->symbol); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"maxpeers needs coin\"}")); -} - -char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message),char *name,char *message,char *password) -{ - char hexstr[1025]; cJSON *json; - if ( message != 0 && password != 0 && message[0] != 0 && password[0] != 0 ) - { - memset(hexstr,0,sizeof(hexstr)); - (*hmacfunc)(hexstr,password,password==0?0:(int32_t)strlen(password),message); - json = cJSON_CreateObject(); - jaddstr(json,"result","hmac calculated"); - jaddstr(json,"message",message); - jaddstr(json,name,hexstr); - return(jprint(json,1)); - } else return(clonestr("{\"error\":\"hmac needs message and passphrase\"}")); -} - -char *hash_dispatch(void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len),char *name,char *message) -{ - char hexstr[65537]; uint8_t databuf[32768]; cJSON *json; - if ( message != 0 && message[0] != 0 ) - { - memset(hexstr,0,sizeof(hexstr)); - (*hashfunc)(hexstr,databuf,(uint8_t *)message,(int32_t)strlen(message)); - json = cJSON_CreateObject(); - jaddstr(json,"result","hash calculated"); - jaddstr(json,"message",message); - jaddstr(json,name,hexstr); - return(jprint(json,1)); - } else return(clonestr("{\"error\":\"hash needs message\"}")); -} - -TWO_HASHES(hash,curve25519_pair,element,scalar) -{ - cJSON *retjson = cJSON_CreateObject(); - jaddbits256(retjson,"result",curve25519(element,scalar)); - return(jprint(retjson,1)); -} - -STRING_ARG(hash,NXT,passphrase) { return(hash_dispatch(calc_NXTaddr,"NXT",passphrase)); } -STRING_ARG(hash,curve25519,pubkey) { return(hash_dispatch(calc_curve25519_str,"curve25519",pubkey)); } -STRING_ARG(hash,crc32,message) { return(hash_dispatch(calc_crc32str,"crc32",message)); } -STRING_ARG(hash,base64_encode,message) { return(hash_dispatch(calc_base64_encodestr,"base64_encode",message)); } -STRING_ARG(hash,base64_decode,message) { return(hash_dispatch(calc_base64_decodestr,"base64_decode",message)); } -STRING_ARG(hash,rmd160_sha256,message) { return(hash_dispatch(rmd160ofsha256,"rmd160_sha256",message)); } -STRING_ARG(hash,sha256_sha256,message) { return(hash_dispatch(sha256_sha256,"sha256_sha256",message)); } -STRING_ARG(hash,hex,message) { return(hash_dispatch(calc_hexstr,"hex",message)); } -STRING_ARG(hash,unhex,message) { return(hash_dispatch(calc_unhexstr,"unhex",message)); } - -STRING_ARG(hash,sha224,message) { return(hash_dispatch(calc_sha224,"sha224",message)); } -STRING_ARG(hash,sha256,message) { return(hash_dispatch(vcalc_sha256,"sha256",message)); } -STRING_ARG(hash,sha384,message) { return(hash_dispatch(calc_sha384,"sha384",message)); } -STRING_ARG(hash,sha512,message) { return(hash_dispatch(calc_sha512,"sha512",message)); } -STRING_ARG(hash,rmd128,message) { return(hash_dispatch(calc_rmd128,"rmd128",message)); } -STRING_ARG(hash,rmd160,message) { return(hash_dispatch(calc_rmd160,"rmd160",message)); } -STRING_ARG(hash,rmd256,message) { return(hash_dispatch(calc_rmd256,"rmd256",message)); } -STRING_ARG(hash,rmd320,message) { return(hash_dispatch(calc_rmd320,"rmd320",message)); } -STRING_ARG(hash,sha1,message) { return(hash_dispatch(calc_sha1,"sha1",message)); } -STRING_ARG(hash,md2,message) { return(hash_dispatch(calc_md2str,"md2",message)); } -STRING_ARG(hash,md4,message) { return(hash_dispatch(calc_md4str,"md4",message)); } -STRING_ARG(hash,md5,message) { return(hash_dispatch(calc_md5str,"md5",message)); } -STRING_ARG(hash,tiger192_3,message) { return(hash_dispatch(calc_tiger,"tiger",message)); } -STRING_ARG(hash,whirlpool,message) { return(hash_dispatch(calc_whirlpool,"whirlpool",message)); } -TWO_STRINGS(hmac,sha224,message,passphrase) { return(hmac_dispatch(hmac_sha224_str,"sha224",message,passphrase)); } -TWO_STRINGS(hmac,sha256,message,passphrase) { return(hmac_dispatch(hmac_sha256_str,"sha256",message,passphrase)); } -TWO_STRINGS(hmac,sha384,message,passphrase) { return(hmac_dispatch(hmac_sha384_str,"sha384",message,passphrase)); } -TWO_STRINGS(hmac,sha512,message,passphrase) { return(hmac_dispatch(hmac_sha512_str,"sha512",message,passphrase)); } -TWO_STRINGS(hmac,rmd128,message,passphrase) { return(hmac_dispatch(hmac_rmd128_str,"rmd128",message,passphrase)); } -TWO_STRINGS(hmac,rmd160,message,passphrase) { return(hmac_dispatch(hmac_rmd160_str,"rmd160",message,passphrase)); } -TWO_STRINGS(hmac,rmd256,message,passphrase) { return(hmac_dispatch(hmac_rmd256_str,"rmd256",message,passphrase)); } -TWO_STRINGS(hmac,rmd320,message,passphrase) { return(hmac_dispatch(hmac_rmd320_str,"rmd320",message,passphrase)); } -TWO_STRINGS(hmac,sha1,message,passphrase) { return(hmac_dispatch(hmac_sha1_str,"sha1",message,passphrase)); } -TWO_STRINGS(hmac,md2,message,passphrase) { return(hmac_dispatch(hmac_md2_str,"md2",message,passphrase)); } -TWO_STRINGS(hmac,md4,message,passphrase) { return(hmac_dispatch(hmac_md4_str,"md4",message,passphrase)); } -TWO_STRINGS(hmac,md5,message,passphrase) { return(hmac_dispatch(hmac_md5_str,"md5",message,passphrase)); } -TWO_STRINGS(hmac,tiger192_3,message,passphrase) { return(hmac_dispatch(hmac_tiger_str,"tiger",message,passphrase)); } -TWO_STRINGS(hmac,whirlpool,message,passphrase) { return(hmac_dispatch(hmac_whirlpool_str,"whirlpool",message,passphrase)); } - -STRING_ARG(SuperNET,bitcoinrpc,setcoin) -{ - char buf[1024]; - if ( setcoin != 0 && setcoin[0] != 0 ) - { - strcpy(myinfo->rpcsymbol,setcoin); - touppercase(myinfo->rpcsymbol); - printf("bitcoinrpc.%s\n",myinfo->rpcsymbol); - if ( iguana_launchcoin(myinfo,myinfo->rpcsymbol,json,0) < 0 ) - return(clonestr("{\"error\":\"error creating coin\"}")); - else - { - sprintf(buf,"{\"result\":\"success\",\"setcoin\":\"%s\"}",setcoin); - return(clonestr(buf)); - } - } else return(clonestr("{\"error\":\"bitcoinrpc needs setcoin value\"}")); -} - -ZERO_ARGS(SuperNET,help) -{ - cJSON *helpjson,*retjson; - if ( (helpjson= SuperNET_helpjson()) != 0 ) - { - retjson = cJSON_CreateObject(); - jadd(retjson,"result",helpjson); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"cant get helpjson\"}")); -} - -TWO_STRINGS(SuperNET,html,agentform,htmlfile) -{ - char *htmlstr; cJSON *retjson; int32_t max = 4*1024*1024; - if ( htmlfile == 0 || htmlfile[0] == 0 ) - htmlfile = "forms.html"; - //if ( (fp= fopen(htmlfile,"w")) == 0 ) - // printf("error opening htmlfile.(%s)\n",htmlfile); - htmlstr = malloc(max); - htmlstr = SuperNET_htmlstr(htmlfile,htmlstr,max,agentform); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",htmlstr); - free(htmlstr); - //if ( fp != 0 ) - // fclose(fp); - return(jprint(retjson,1)); -} - -#undef IGUANA_ARGS -#include "../includes/iguana_apiundefs.h" char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,cJSON *json,char *remoteaddr) { @@ -908,7 +514,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c if ( coinstr != 0 && coinstr[0] != 0 ) coin = iguana_coinfind(coinstr); if ( strcmp(agentstr,"bitcoinrpc") == 0 && coin == 0 ) - return(clonestr("{\"error\":\"bitcoinrpc needs coin\"}")); + return(clonestr("{\"error\":\"bitcoinrpc needs coin that is active\"}")); #define IGUANA_ARGS myinfo,coin,json,remoteaddr #define IGUANA_DISPATCH0(agent,name) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS)) #define IGUANA_DISPATCH_S(agent,name,str) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str))) @@ -952,6 +558,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define IGUANA_DISPATCH_HH(agent,name,hash,hash2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),jbits256(json,#hash2))) #define IGUANA_DISPATCH_HA(agent,name,hash,array) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),jobj(json,#array))) #define IGUANA_DISPATCH_HS(agent,name,hash,str) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),jstr(json,#str))) +#define IGUANA_DISPATCH_HSI(agent,name,hash,str,val) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),jstr(json,#str),jint(json,#val))) #define IGUANA_DISPATCH_HII(agent,name,hash,val,val2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),juint(json,#val),juint(json,#val2))) #define IGUANA_DISPATCH_HHS(agent,name,hash,hash2,str) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),jbits256(json,#hash2),jstr(json,#str))) #define IGUANA_DISPATCH_HAS(agent,name,hash,array,str) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),jobj(json,#array),jstr(json,#str))) @@ -977,6 +584,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define STRING_AND_TWOINTS IGUANA_DISPATCH_SII #define HASH_AND_INT IGUANA_DISPATCH_HI #define HASH_AND_STRING IGUANA_DISPATCH_HS +#define HASH_AND_STRING_AND_INT IGUANA_DISPATCH_HSI #define HASH_AND_TWOINTS IGUANA_DISPATCH_HII #define DOUBLE_ARG IGUANA_DISPATCH_D #define STRING_AND_ARRAY IGUANA_DISPATCH_SA @@ -1012,12 +620,31 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define STRING_ARRAY_OBJ_STRING IGUANA_DISPATCH_SAOS #include "../includes/iguana_apideclares.h" -//#undef IGUANA_ARGS - +#ifdef WIN32 +return SuperNET_parser2(myinfo, agentstr, method, json, remoteaddr); +#else +#undef IGUANA_ARGS +#undef _IGUANA_APIDEC_H_ #include "../includes/iguana_apiundefs.h" char errstr[512]; sprintf(errstr,"{\"error\":\"unsupported call\",\"agent\":\"%s\",\"method\":\"%s\"}",agentstr,method); return(clonestr(errstr)); +#endif } +#ifdef WIN32 +char *SuperNET_parser2(struct supernet_info *myinfo, char *agentstr, char *method, cJSON *json, char *remoteaddr) { + char *coinstr; struct iguana_info *coin = 0; + if (remoteaddr != 0 && (remoteaddr[0] == 0 || strcmp(remoteaddr, "127.0.0.1") == 0)) + remoteaddr = 0; +#include "../includes/iguana_apideclares2.h" +#undef IGUANA_ARGS +#undef _IGUANA_APIDEC_H_ +#include "../includes/iguana_apiundefs.h" + char errstr[512]; + sprintf(errstr, "{\"error\":\"unsupported call\",\"agent\":\"%s\",\"method\":\"%s\"}", agentstr, method); + return(clonestr(errstr)); +} + +#endif diff --git a/iguana/iguana_mofn.c b/iguana/iguana_mofn.c index 51c82eee4..b4d34230d 100755 --- a/iguana/iguana_mofn.c +++ b/iguana/iguana_mofn.c @@ -238,6 +238,22 @@ int32_t gfshare_test(struct supernet_info *myinfo,int32_t M,int32_t N,int32_t da return ok!=1; } +void *bitcoin_ctx() +{ + void *ptr; + ptr = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pedersen_context_initialize(ptr); + secp256k1_rangeproof_context_initialize(ptr); + return(ptr); +} + +void iguana_fixsecp(struct supernet_info *myinfo) +{ + myinfo->ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pedersen_context_initialize(myinfo->ctx); + secp256k1_rangeproof_context_initialize(myinfo->ctx); +} + void libgfshare_init(struct supernet_info *myinfo,uint8_t _logs[256],uint8_t _exps[510]) { uint32_t i,x = 1; @@ -255,7 +271,7 @@ void libgfshare_init(struct supernet_info *myinfo,uint8_t _logs[256],uint8_t _ex for (i=255; i<510; i++) _exps[i] = _exps[i % 255]; _logs[0] = 0; // can't log(0) so just set it neatly to 0 - if ( 0 ) + if ( (0) ) { void test_mofn(struct supernet_info *myinfo); gfshare_test(myinfo,6,11,32); @@ -309,7 +325,7 @@ int maingen(int argc,char **argv) } /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -563,10 +579,17 @@ int32_t test_mofn256(struct supernet_info *myinfo,int32_t M,int32_t N) if ( m >= M ) printf("%s %s error m.%d vs M.%d N.%d\n",bits256_str(str,secret),bits256_str(str2,recover),m,mofn->M,mofn->N); } +#if defined(_M_X64) + if (((uint64_t)mofn - (uint64_t)space) >= sizeof(space) || ((uint64_t)mofn - (uint64_t)space) < 0) + free(mofn); + if (((uint64_t)cmp - (uint64_t)space) >= sizeof(space) || ((uint64_t)cmp - (uint64_t)space) < 0) + free(cmp); +#else if ( ((long)mofn - (long)space) >= sizeof(space) || ((long)mofn - (long)space) < 0 ) free(mofn); if ( ((long)cmp - (long)space) >= sizeof(space) || ((long)cmp - (long)space) < 0 ) free(cmp); +#endif return(retval); } @@ -588,7 +611,7 @@ void test_mofn(struct supernet_info *myinfo) { if ( memcmp(secret.bytes,recover.bytes,sizeof(secret)) != 0 ) printf("FAILED m.%d M.%d N.%d\n",m,M,N); - else if ( 0 ) + else if ( (0) ) { char str[65]; printf("%s PASSED m.%d M.%d N.%d\n",bits256_str(str,recover),m,M,N); @@ -644,6 +667,7 @@ int32_t iguana_schnorr_peersign(void *ctx,uint8_t *allpub33,uint8_t *partialsig6 bits256 iguana_schnorr_noncepair(void *ctx,bits256 *pubkey,uint8_t odd_even,bits256 msg256,bits256 privkey,int32_t maxj) { bits256 privnonce; int32_t j; uint8_t pubkey33[33]; + memset(privnonce.bytes,0,sizeof(privnonce)); for (j=0; jctx,sig64,msg256,allpub2,33) < 0 ) printf("allpub2 error verifying combined sig k.%d\n",k); - else if ( 0 ) // doesnt replicate with subsets + else if ( (0) ) // doesnt replicate with subsets { if ( bitcoin_pubkey_combine(myinfo->ctx,allpub,0,pubkeys,n,0,0) == 0 ) { diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 8db7a25b9..bbdd7a6d6 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -91,46 +91,60 @@ int32_t iguana_rwmerklebranch(int32_t rwflag,uint8_t *serialized,struct iguana_m return(len); } -int32_t iguana_rwzsolution(int32_t rwflag,uint8_t *serialized,uint32_t *solution,int32_t n) +int32_t iguana_rwzsolution(int32_t rwflag,uint8_t *serialized,uint8_t *solution,int32_t n) { int32_t i,len = 0; - for (i=0; iH.version),&msg->H.version); - len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->H.prev_block),msg->H.prev_block.bytes); - len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->H.merkle_root),msg->H.merkle_root.bytes); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.timestamp),&msg->H.timestamp); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.bits),&msg->H.bits); + struct iguana_msgzblockhdr zH; uint32_t tmp; struct iguana_msgblock *msg = (void *)zmsg; int32_t len = 0; if ( zcash == 0 ) + { + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.version),&msg->H.version); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->H.prev_block),msg->H.prev_block.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->H.merkle_root),msg->H.merkle_root.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.timestamp),&msg->H.timestamp); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.bits),&msg->H.bits); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.nonce),&msg->H.nonce); + } else { - len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->zH.bignonce),msg->zH.bignonce.bytes); + if ( rwflag != 0 ) + zH = zmsg->zH; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(zH.version),&zH.version); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(zH.prev_block),zH.prev_block.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(zH.merkle_root),zH.merkle_root.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(zH.reserved),zH.reserved.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(zH.timestamp),&zH.timestamp); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(zH.bits),&zH.bits); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(zH.bignonce),zH.bignonce.bytes); //char str[65]; printf("prev.(%s) len.%d [%d %d %d]\n",bits256_str(str,msg->H.prev_block),len,serialized[len],serialized[len+1],serialized[len+2]); if ( rwflag != 0 ) - tmp = msg->zH.numelements; - len += iguana_rwvarint32(rwflag,&serialized[len],(uint32_t *)&tmp); - if ( rwflag == 0 ) - msg->zH.numelements = tmp; - if ( msg->zH.numelements != ZCASH_SOLUTION_ELEMENTS ) + memcpy(&serialized[len],zH.var_numelements,sizeof(zH.var_numelements)); + else memcpy(zH.var_numelements,&serialized[len],sizeof(zH.var_numelements)); + //printf("numelements: (%02x %02x %02x)\n",serialized[len],serialized[len+1],serialized[len+2]); + len += sizeof(zH.var_numelements); + if ( iguana_rwvarint32(0,zH.var_numelements,(uint32_t *)&tmp) != sizeof(zH.var_numelements) ) + printf("rw.%d unexpected varint size for zmsg.zH.numelements <- %d %d %d\n",rwflag,zH.var_numelements[0],zH.var_numelements[1],zH.var_numelements[2]); + if ( tmp != ZCASH_SOLUTION_ELEMENTS ) { int32_t i; for (i=0; i<157; i++) printf("%02x",serialized[i]); - printf(" unexpected ZCASH_SOLUTION_ELEMENTS, got %d vs %d len.%d\n",msg->zH.numelements,ZCASH_SOLUTION_ELEMENTS,len); + printf(" rw.%d unexpected ZCASH_SOLUTION_ELEMENTS, (%02x %02x %02x) expected %d tmp.%d len.%d\n",rwflag,zH.var_numelements[0],zH.var_numelements[1],zH.var_numelements[2],ZCASH_SOLUTION_ELEMENTS,tmp,len); return(-1); } - len += iguana_rwzsolution(rwflag,&serialized[len],msg->zH.solution,ZCASH_SOLUTION_ELEMENTS); + len += iguana_rwzsolution(rwflag,&serialized[len],zH.solution,tmp); + if ( rwflag == 0 ) + zmsg->zH = zH; } return(len); } -int32_t iguana_eatauxpow(int32_t rwflag,char *symbol,uint8_t zcash,uint8_t *serialized,int32_t maxlen) +int32_t iguana_eatauxpow(struct supernet_info *myinfo,int32_t rwflag,char *symbol,uint8_t zcash,uint8_t *serialized,int32_t maxlen) { int32_t len = 0; void *ptr; struct iguana_msgtx msg; struct OS_memspace MEM; bits256 auxhash2,coinbasetxid; struct iguana_msgmerkle *coinbase_branch,*blockchain_branch; struct iguana_msgblock parentblock; struct iguana_info *coin; if ( rwflag == 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->chain->auxpow != 0 ) @@ -142,7 +156,7 @@ int32_t iguana_eatauxpow(int32_t rwflag,char *symbol,uint8_t zcash,uint8_t *seri memset(&MEM,0,sizeof(MEM)); ptr = calloc(1,1000000); iguana_meminit(&MEM,"auxpow",ptr,1000000,0); - len += iguana_rwtx(coin->chain->zcash,rwflag,&MEM,&serialized[len],&msg,(int32_t)MEM.totalsize,&coinbasetxid,coin->chain->isPoS,0); + len += iguana_rwtx(myinfo,coin->chain->zcash,rwflag,coin,&MEM,&serialized[len],&msg,(int32_t)MEM.totalsize,&coinbasetxid,coin->chain->isPoS,0); if ( len > maxlen ) return(-1); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(auxhash2),auxhash2.bytes); @@ -154,7 +168,7 @@ int32_t iguana_eatauxpow(int32_t rwflag,char *symbol,uint8_t zcash,uint8_t *seri len += iguana_rwmerklebranch(rwflag,&serialized[len],blockchain_branch); if ( len > maxlen ) return(-1); - len += iguana_rwblockhdr(rwflag,zcash,&serialized[len],&parentblock); + len += iguana_rwblockhdr(rwflag,zcash,&serialized[len],(void *)&parentblock); if ( len > maxlen ) return(-1); free(ptr); @@ -164,7 +178,7 @@ int32_t iguana_eatauxpow(int32_t rwflag,char *symbol,uint8_t zcash,uint8_t *seri return(len); } -int32_t iguana_blockhdrsize(char *symbol,uint8_t zcash,uint8_t auxpow)//,uint8_t *serialized,int32_t maxlen) +int32_t iguana_blockhdrsize(char *symbol,uint8_t zcash,uint8_t auxpow) { int32_t len = 0; if ( zcash == 0 ) @@ -175,59 +189,83 @@ int32_t iguana_blockhdrsize(char *symbol,uint8_t zcash,uint8_t auxpow)//,uint8_t return(sizeof(struct iguana_msgblockhdr) + len); //else return(-1); - } else return((int32_t)(sizeof(struct iguana_msgblockhdr) - sizeof(uint32_t) + sizeof(struct iguana_msgblockhdr_zcash) + auxpow*sizeof(bits256))); + } else return((int32_t)(sizeof(struct iguana_msgzblockhdr) + auxpow*sizeof(bits256))); } -int32_t iguana_rwblock(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct iguana_msgblock *msg,int32_t maxlen) +int32_t iguana_rwblock(struct supernet_info *myinfo,char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct iguana_msgzblock *zmsg,int32_t maxlen) { - int32_t len = 0; uint64_t x; - if ( (len= iguana_rwblockhdr(rwflag,zcash,serialized,msg)) < 0 ) + int32_t len = 0; uint64_t x; struct iguana_msgblock *msg = (void *)zmsg; + if ( (len= iguana_rwblockhdr(rwflag,zcash,serialized,zmsg)) < 0 ) { - printf("error rw.%d blockhdr zcash.%d\n",rwflag,zcash); + int32_t i; + for (i=0; iH.version,msg->H.timestamp,msg->H.bits,msg->H.nonce,bits256_str(str,msg->H.prev_block),(long long)msg->H.merkle_root.txid,bits256_str(str2,*hash2p)); if ( auxpow != 0 && (msg->H.version & 0x100) != 0 ) - len += iguana_eatauxpow(rwflag,symbol,zcash,&serialized[len],maxlen-len); + len += iguana_eatauxpow(myinfo,rwflag,symbol,zcash,&serialized[len],maxlen-len); if ( rwflag == 1 ) - x = msg->txn_count; + { + if ( zcash == 0 ) + x = msg->txn_count; + else x = zmsg->txn_count; + } + //char str[65],str2[65]; printf("zcash.%d len.%d: block version.%d timestamp.%u bits.%x nonce.%u prev.(%s) %llx hash2.%s zlen.%d\n",zcash,len,msg->H.version,msg->H.timestamp,msg->H.bits,msg->H.nonce,bits256_str(str,msg->H.prev_block),(long long)msg->H.merkle_root.txid,bits256_str(str2,*hash2p),(int32_t)sizeof(struct iguana_msgzblockhdr)); len += iguana_rwvarint(rwflag,&serialized[len],&x); if ( rwflag == 0 ) { char str[65]; bits256_str(str,*hash2p); if ( x < 65536 ) - msg->txn_count = (uint16_t)x; - else printf("txn_count overflow.%lld for %s\n",(long long)x,str); + { + if ( zcash != 0 ) + zmsg->txn_count = (uint16_t)x; + else msg->txn_count = (uint16_t)x; + } else printf("txn_count overflow.%lld for %s\n",(long long)x,str); } // ? txns tx[] Block transactions, in format of "tx" command return(len); } -int32_t iguana_serialize_block(struct iguana_chain *chain,bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgblock)],struct iguana_block *block) +int32_t iguana_serialize_block(struct supernet_info *myinfo,struct iguana_chain *chain,bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgzblock)],struct iguana_block *block) { - struct iguana_msgblock msg; int32_t i,len; - memset(&msg,0,sizeof(msg)); - msg.H.version = block->RO.version; - msg.H.prev_block = block->RO.prev_block; - msg.H.merkle_root = block->RO.merkle_root; - msg.H.timestamp = block->RO.timestamp; - msg.H.bits = block->RO.bits; + struct iguana_msgzblock zmsg; struct iguana_msgblock *msg = (void *)&zmsg; struct iguana_zblock *zblock; int32_t i,len; if ( chain->zcash == 0 ) - msg.H.nonce = block->RO.nonce; + { + memset(msg,0,sizeof(*msg)); + msg->H.version = block->RO.version; + msg->H.prev_block = block->RO.prev_block; + msg->H.merkle_root = block->RO.merkle_root; + msg->H.timestamp = block->RO.timestamp; + msg->H.bits = block->RO.bits; + msg->H.nonce = block->RO.nonce; + msg->txn_count = block->RO.txn_count; + len = iguana_rwblock(myinfo,chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,1,hash2p,serialized,(void *)msg,IGUANA_MAXPACKETSIZE); + } else { - if ( block->RO.allocsize == sizeof(struct iguana_zblock) ) + memset(&zmsg,0,sizeof(zmsg)); + zblock = (void *)block; + zmsg.zH.version = zblock->RO.version; + zmsg.zH.prev_block = zblock->RO.prev_block; + zmsg.zH.merkle_root = zblock->RO.merkle_root; + zmsg.zH.timestamp = zblock->RO.timestamp; + zmsg.zH.bits = zblock->RO.bits; + zmsg.zH.bignonce = zblock->zRO.bignonce; + if ( iguana_rwvarint32(1,zmsg.zH.var_numelements,(uint32_t *)&zblock->zRO.numelements) != sizeof(zmsg.zH.var_numelements) ) + { + // printf("unexpected varint size for zmsg.zH.numelements <- %d %d %d\n",zmsg.zH.var_numelements[0],zmsg.zH.var_numelements[1],zmsg.zH.var_numelements[2]); + } + if ( zblock->zRO.numelements == ZCASH_SOLUTION_ELEMENTS ) { - msg.zH.bignonce = block->zRO[0].bignonce; - msg.zH.numelements = ZCASH_SOLUTION_ELEMENTS; for (i=0; izRO[0].solution[i]; - } else printf("iguana_serialize_block has missing zRO\n"); + zmsg.zH.solution[i] = zblock->zRO.solution[i]; + zmsg.txn_count = block->RO.txn_count; + len = iguana_rwblock(myinfo,chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,1,hash2p,serialized,(void *)&zmsg,IGUANA_MAXPACKETSIZE); + } else return(-1); } - msg.txn_count = block->RO.txn_count; - len = iguana_rwblock(chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,1,hash2p,serialized,&msg,IGUANA_MAXPACKETSIZE); return(len); } @@ -287,7 +325,7 @@ int32_t iguana_rwmsgalert(struct iguana_info *coin,int32_t rwflag,uint8_t *seria printf("%02x",coin->chain->alertpubkey[i]); char str[65]; printf(" alertpubkey.%d, alerthash2.%s\n",plen,bits256_str(str,alerthash2)); } else msg->siglen = 0; - printf(" ALERT v.%d relay.%lld expires.%lld ID.%d cancel.%d numlist.%d minver.%d maxver.%d subver.(%s) priority.%d comment.(%s) STATUS.(%s) reserved.(%s)\n",msg->version,(long long)msg->relayuntil,(long long)msg->expiration,msg->ID,msg->cancel,msg->numcancellist,msg->minver,msg->maxver,msg->subver,msg->priority,msg->comment,msg->statusbar,msg->reserved); + //printf(" ALERT v.%d relay.%lld expires.%lld ID.%d cancel.%d numlist.%d minver.%d maxver.%d subver.(%s) priority.%d comment.(%s) STATUS.(%s) reserved.(%s)\n",msg->version,(long long)msg->relayuntil,(long long)msg->expiration,msg->ID,msg->cancel,msg->numcancellist,msg->minver,msg->maxver,msg->subver,msg->priority,msg->comment,msg->statusbar,msg->reserved); return(len); } @@ -310,17 +348,15 @@ int32_t iguana_rwmsgalert(struct iguana_info *coin,int32_t rwflag,uint8_t *seria void iguana_gotversion(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgversion *vers) { - uint8_t serialized[sizeof(struct iguana_msghdr)]; char *retstr; + uint8_t serialized[sizeof(struct iguana_msghdr)]; //printf("gotversion from %s: starting height.%d services.%llx proto.%d (%s)\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion,vers->strSubVer); - if ( 0 && strncmp(vers->strSubVer,"/iguana",strlen("/iguana")) == 0 ) - { + if ( strncmp(vers->strSubVer,"/iguana",strlen("/iguana")) == 0 ) addr->supernet = 1, addr->basilisk = 0; - if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)addr->ipbits,GENESIS_PUBKEY)) != 0 ) - free(retstr); - } else if ( strncmp(vers->strSubVer,"/basilisk",strlen("/basilisk")) == 0 ) + { addr->basilisk = 1, addr->supernet = 0; - if ( (vers->nServices & NODE_NETWORK) != 0 ) + } + //if ( (vers->nServices & NODE_NETWORK) != 0 ) { addr->protover = (vers->nVersion < PROTOCOL_VERSION) ? vers->nVersion : PROTOCOL_VERSION; //printf("(%s) proto.%d -> %d\n",addr->ipaddr,vers->nVersion,addr->protover); @@ -328,11 +364,8 @@ void iguana_gotversion(struct supernet_info *myinfo,struct iguana_info *coin,str addr->height = vers->nStartingHeight; addr->relayflag = 1; iguana_gotdata(coin,addr,addr->height); - iguana_queue_send(addr,0,serialized,"verack",0); - //iguana_send_ping(coin,addr); } - else if ( 0 && addr->supernet == 0 && addr->basilisk == 0 )//|| (addr->basilisk != 0 && myinfo->IAMRELAY == 0) ) - addr->dead = (uint32_t)time(NULL); + iguana_queue_send(addr,0,serialized,"verack",0); if ( addr->supernet != 0 || addr->basilisk != 0 ) printf("height.%d nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d basilisk.%d longest.%u\n",vers->nStartingHeight,(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet,addr->basilisk,vers->nStartingHeight); if ( (int32_t)vers->nStartingHeight > coin->longestchain ) @@ -343,6 +376,8 @@ void iguana_gotversion(struct supernet_info *myinfo,struct iguana_info *coin,str addr->dead = 1; } //else coin->longestchain = vers->nStartingHeight; } + if ( addr->msgcounts.verack == 0 && time(NULL) > addr->ready+600 ) + iguana_send_version(coin,addr,coin->myservices); iguana_queue_send(addr,0,serialized,"getaddr",0); } @@ -354,7 +389,7 @@ int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,ui msg.nServices = (myservices & NODE_NETWORK); msg.nTime = (int64_t)time(NULL); msg.nonce = coin->instance_nonce; - if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) sprintf(msg.strSubVer,"/iguana 0.00/"); else sprintf(msg.strSubVer,"/basilisk 0.00/"); //printf("SEND.(%s) -> (%s)\n",msg.strSubVer,addr->ipaddr); @@ -373,7 +408,7 @@ int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr msg.nServices = (myservices & NODE_NETWORK); msg.nTime = (int64_t)time(NULL); msg.nonce = 0;//coin->instance_nonce; - if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) sprintf(msg.strSubVer,"/iguana 0.00/"); else sprintf(msg.strSubVer,"/basilisk 0.00/"); msg.nStartingHeight = coin->blocks.hwmchain.height; @@ -385,7 +420,7 @@ void iguana_supernet_ping(struct supernet_info *myinfo,struct iguana_info *coin, { if ( addr->supernet != 0 || addr->basilisk != 0 ) { - //if ( coin->FULLNODE != 0 ) + //if ( coin->FULLNODE > 0 ) // basilisk_relays_send(myinfo,addr); //printf("send getpeers to %s\n",addr->ipaddr); //printf("maybe send basilisk ping here?\n"); @@ -398,7 +433,8 @@ void iguana_gotverack(struct supernet_info *myinfo,struct iguana_info *coin,stru uint8_t serialized[sizeof(struct iguana_msghdr)]; if ( addr != 0 ) { - //printf("gotverack from %s\n",addr->ipaddr); + if ( addr->supernet != 0 || addr->basilisk != 0 ) + printf(">>>>>>>>>> supernet.%d basilisk.%d gotverack from %s\n",addr->supernet,addr->basilisk,addr->ipaddr); addr->A.nTime = (uint32_t)time(NULL); iguana_queue_send(addr,0,serialized,"getaddr",0); iguana_supernet_ping(myinfo,coin,addr); @@ -413,7 +449,7 @@ void iguana_gotaddr(struct iguana_info *coin,struct iguana_peer *addr,struct igu expand_ipbits(ipaddr,ipbits); if ( port != 0 ) sprintf(ipport,"%s:%d",ipaddr,port); - if ( 0 ) + if ( (0) ) { int32_t i; printf("{{"); @@ -423,8 +459,8 @@ void iguana_gotaddr(struct iguana_info *coin,struct iguana_peer *addr,struct igu } if ( strcmp(coin->symbol,"BTC") != 0 || (rand() % 10) == 0 ) iguana_possible_peer(coin,ipport); - if ( 0 && strncmp("BTC",coin->symbol,3) != 0 ) - printf("%s\n",ipaddr); + if ( (0) && strcmp("TAZ",coin->symbol) == 0 ) + printf("iguana_gotaddr: %s from %s\n",ipaddr,addr->ipaddr); } void iguana_gotping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce,uint8_t *data) @@ -440,6 +476,16 @@ void iguana_gotping(struct supernet_info *myinfo,struct iguana_info *coin,struct int32_t iguana_send_ping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr) { int32_t len; uint64_t nonce; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)]; + if ( coin->FULLNODE <= 0 ) + return(0); + if ( addr->msgcounts.verack == 0 ) + { + if ( strcmp(addr->ipaddr,myinfo->ipaddr) != 0 ) + { + printf("%s send version instead of ping to %s\n",coin->symbol,addr->ipaddr); + return(iguana_send_version(coin,addr,coin->myservices)); + } + } if ( (nonce= addr->pingnonce) == 0 ) { OS_randombytes((uint8_t *)&nonce,sizeof(nonce)); @@ -507,7 +553,7 @@ int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type } int32_t debugtest; -int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg) +int32_t iguana_rwvin(int32_t rwflag,struct iguana_info *coin,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg,int32_t vini) { int32_t len = 0; uint32_t tmp; len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->prev_hash),msg->prev_hash.bytes); @@ -518,7 +564,9 @@ int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized, if ( rwflag == 0 ) { msg->scriptlen = tmp; - msg->vinscript = iguana_memalloc(mem,msg->scriptlen,1); + if ( msg->scriptlen < IGUANA_MAXSCRIPTSIZE ) + msg->vinscript = iguana_memalloc(mem,msg->scriptlen,1); + else return(0); } len += iguana_rwmem(rwflag,&serialized[len],msg->scriptlen,msg->vinscript); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); @@ -538,7 +586,7 @@ int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value),&msg->value); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->pk_scriptlen); if ( msg->pk_scriptlen > IGUANA_MAXSCRIPTSIZE ) - return(-1); + return(0); if ( rwflag == 0 ) msg->pk_script = iguana_memalloc(mem,msg->pk_scriptlen,1); len += iguana_rwmem(rwflag,&serialized[len],msg->pk_scriptlen,msg->pk_script); @@ -557,6 +605,7 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj int32_t len = 0; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->vpub_old),&msg->vpub_old); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->vpub_new),&msg->vpub_new); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->anchor),msg->anchor.bytes); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->nullifiers[0]),msg->nullifiers[0].bytes); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->nullifiers[1]),msg->nullifiers[1].bytes); @@ -577,7 +626,7 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj return(len); } -int32_t iguana_rwtx(uint8_t zcash,int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin) +int32_t iguana_rwtx(struct supernet_info *myinfo,uint8_t zcash,int32_t rwflag,struct iguana_info *coin,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin) { int32_t i,n,len = 0; uint8_t *txstart = serialized; char txidstr[65]; if ( maxsize < sizeof(msg->version) ) @@ -591,7 +640,7 @@ int32_t iguana_rwtx(uint8_t zcash,int32_t rwflag,struct OS_memspace *mem,uint8_t len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); } len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); - if ( rwflag == 0 ) + if ( rwflag == 0 && msg->tx_in > 0 ) msg->vins = iguana_memalloc(mem,msg->tx_in * sizeof(*msg->vins),1); if ( maxsize-len <= 0 ) return(-1); @@ -604,7 +653,7 @@ int32_t iguana_rwtx(uint8_t zcash,int32_t rwflag,struct OS_memspace *mem,uint8_t return(-1); } } - if ( (n= iguana_rwvin(rwflag,mem,&serialized[len],&msg->vins[i])) >= 0 ) + if ( (n= iguana_rwvin(rwflag,coin,mem,&serialized[len],&msg->vins[i],i)) >= 0 ) len += n; if ( n < 0 || len+sizeof(int32_t) > maxsize ) { @@ -612,22 +661,25 @@ int32_t iguana_rwtx(uint8_t zcash,int32_t rwflag,struct OS_memspace *mem,uint8_t return(-1); } } + //for (i=-3; i<7; i++) + // printf("%02x",serialized[len+i]); + //printf(" prev 3 bytes before tx_out\n"); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); if ( len + msg->tx_out*8 > maxsize ) { - printf("invalid tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); + printf("invalidA tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); return(-1); } //printf("numvouts.%d ",msg->tx_out); - if ( rwflag == 0 ) + if ( rwflag == 0 && msg->tx_out > 0 ) msg->vouts = iguana_memalloc(mem,msg->tx_out * sizeof(*msg->vouts),1); for (i=0; itx_out; i++) { - if ( (n= iguana_rwvout(rwflag,mem,&serialized[len],&msg->vouts[i])) >= 0 ) + if ( (n= iguana_rwvout(rwflag,mem,&serialized[len],&msg->vouts[i])) > 0 ) len += n; - if ( n < 0 || len > maxsize ) + if ( n <= 0 || len > maxsize ) { - printf("invalid tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); + printf("invalidB tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); return(-1); } } @@ -639,48 +691,96 @@ int32_t iguana_rwtx(uint8_t zcash,int32_t rwflag,struct OS_memspace *mem,uint8_t for (; serialized[len]!=0&&lenversion == 2 ) + if ( zcash != 0 && msg->version > 1 ) { uint32_t numjoinsplits; struct iguana_msgjoinsplit joinsplit; uint8_t joinsplitpubkey[33],joinsplitsig[64]; len += iguana_rwvarint32(rwflag,&serialized[len],&numjoinsplits); - char str[65]; - printf("numjoinsplits.%d version.%d numvins.%d numvouts.%d locktime.%u %s\n",numjoinsplits,msg->version,msg->tx_in,msg->tx_out,msg->lock_time,bits256_str(str,*txidp)); if ( numjoinsplits > 0 ) { for (i=0; iversion,msg->tx_in,msg->tx_out,msg->lock_time,bits256_str(str,*txidp)); } + } + *txidp = bits256_doublesha256(txidstr,txstart,len); + msg->allocsize = len; + if ( coin->VALIDATENODE > 1 && rwflag == 0 && coin->RTheight > 0 ) + { + int32_t sigsvalid; struct iguana_block *block; + if ( (block= iguana_blockfind("sig",coin,msg->txid)) != 0 && block->sigsvalid != 0 ) + sigsvalid = 1; + else if ( iguana_validatesigs(myinfo,coin,txstart,len) == 0 ) + sigsvalid = 1; else { - memcpy(joinsplitpubkey,&serialized[len],33), len += 33; - memcpy(joinsplitsig,&serialized[len],64), len += 64; + static FILE *fp; + if ( block != 0 ) + block->sigsvalid = 1; + if ( fp == 0 ) + fp = fopen("validates","wb"); + if ( fp != 0 ) + { + char str[65]; + printf("error %s validating\n",bits256_str(str,*txidp)); + for (i=0; iallocsize = len; return(len); } -char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid) +char *iguana_txscan(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid) { - struct iguana_msgtx tx; bits256 hash2; struct iguana_block *block; struct iguana_msgblock msg; - int32_t i,n,len,extralen = 65356; char *txbytes,vpnstr[64]; uint8_t *extraspace,blockspace[sizeof(*block)+sizeof(*block->zRO)]; + struct iguana_msgtx tx; bits256 hash2; struct iguana_zblock *zblock; struct iguana_block *block; struct iguana_msgzblock zmsg; struct iguana_msgblock *msg = (void *)&zmsg; + int32_t i,n,len,txn_count,extralen = 65356; char *txbytes,vpnstr[64]; uint8_t *extraspace,blockspace[sizeof(*block)+sizeof(struct iguana_zblock)]; + zblock = (void *)blockspace; block = (void *)blockspace; - memset(&msg,0,sizeof(msg)); + memset(&zmsg,0,sizeof(zmsg)); vpnstr[0] = 0; extraspace = calloc(1,extralen); - len = iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,data,&msg,recvlen); - iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,block,&msg,hash2,-1); - for (i=0; ichain->zcash == 0 ) + { + len = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,data,(void *)msg,recvlen); + iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,(void *)block,(void *)msg,hash2,-1); + txn_count = msg->txn_count; + } + else + { + len = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,data,(void *)&zmsg,recvlen); + iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,zblock,&zmsg,hash2,-1); + txn_count = zmsg.txn_count; + } + for (i=0; iblocks.hwmchain.height,0,0,&data[len],recvlen - len,&tx,&tx.txid,vpnstr,extraspace,extralen,0,0)) < 0 ) break; - char str[65]; printf("%d of %d: %s len.%d\n",i,msg.txn_count,bits256_str(str,tx.txid),len); + char str[65]; printf("%d of %d: %s len.%d\n",i,txn_count,bits256_str(str,tx.txid),len); if ( bits256_cmp(txid,tx.txid) == 0 ) { if ( (n= iguana_rwmsgtx(coin,coin->blocks.hwmchain.height,0,json,&data[len],recvlen - len,&tx,&tx.txid,vpnstr,extraspace,extralen,0,0)) > 0 ) @@ -696,30 +796,30 @@ char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t r return(0); } -int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txdata,int32_t *lenp,uint8_t *data,int32_t recvlen) +int32_t iguana_gentxarray(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txdata,int32_t *lenp,uint8_t *data,int32_t recvlen) { - struct iguana_msgtx *tx; bits256 hash2; struct iguana_msgblock msg; int32_t i,n,hdrlen,len,numvouts,numvins; char str[65]; - memset(&msg,0,sizeof(msg)); - len = iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,data,&msg,recvlen); + struct iguana_msgtx *tx; bits256 hash2; struct iguana_msgzblock zmsg; int32_t txn_count,i,n,hdrlen,len,numvouts,numvins; char str[65]; + memset(&zmsg,0,sizeof(zmsg)); + len = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,data,(void *)&zmsg,recvlen); hdrlen = len; if ( len > recvlen ) { printf("gentxarray error len.%d > recvlen.%d\n",len,recvlen); return(-1); } - iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,(struct iguana_block *)&txdata->zblock,&msg,hash2,-1); + txn_count = iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,(void *)&txdata->zblock,&zmsg,hash2,-1); numvins = numvouts = 0; - if ( msg.txn_count > 0 ) + if ( txn_count > 0 ) { - tx = iguana_memalloc(mem,msg.txn_count*sizeof(*tx),1); - for (i=0; i recvlen ) { printf("gentxarrayB error len.%d > recvlen.%d\n",len,recvlen); return(-1); } - if ( (n= iguana_rwtx(coin->chain->zcash,0,mem,&data[len],&tx[i],recvlen - len,&tx[i].txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0)) < 0 ) + if ( (n= iguana_rwtx(myinfo,coin->chain->zcash,0,coin,mem,&data[len],&tx[i],recvlen - len,&tx[i].txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0)) < 0 ) { //for (i=0; iextralen = 0; } if ( coin->chain->auxpow != 0 && len != recvlen ) - printf("numtx.%d %s hdrlen.%d len.%d vs recvlen.%d v.%08x\n",msg.txn_count,bits256_str(str,hash2),hdrlen,len,recvlen,txdata->zblock.RO.version); + printf("numtx.%d %s hdrlen.%d len.%d vs recvlen.%d v.%08x\n",txn_count,bits256_str(str,hash2),hdrlen,len,recvlen,txdata->zblock.RO.version); txdata->recvlen = len; - txdata->numtxids = msg.txn_count; + txdata->numtxids = txn_count; txdata->numunspents = numvouts; txdata->numspends = numvins; return(len); @@ -834,10 +934,9 @@ int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int3 //printf("intvectors.%c recvlen.%d\n",intvectors,recvlen); } -int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,int32_t fromcache) +int32_t iguana_msgparser(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,int32_t fromcache) { - uint8_t serialized[16384]; char *ipaddr; struct supernet_info *myinfo = SuperNET_MYINFO(0); - int32_t i,n=0,retval=-1,ishost,srvmsg,bloom,sendlen=0,intvectors,len= -100; uint64_t nonce,x; bits256 hash2; + uint8_t serialized[16384]; char *ipaddr; int32_t i,n=0,retval=-1,ishost,srvmsg,bloom,sendlen=0,intvectors,len= -100; uint64_t nonce,x; bits256 hash2; bloom = intvectors = srvmsg = -1; if ( strncmp(H->command+1,"uperNET",strlen("uperNET")) == 0 || strncmp(H->command,"uperNet",strlen("uperNet")) == 0 ) { @@ -851,13 +950,13 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } else ipaddr = 0; len = recvlen; //printf("GOT.(%s) len.%d from %s\n",H->command,recvlen,addr->ipaddr); - basilisk_p2p(myinfo,addr,ipaddr,data,recvlen,&H->command[strlen("SuperNET")],H->command[6] == 'e' && H->command[7] == 't'); + basilisk_p2p(myinfo,coin,addr,ipaddr,data,recvlen,&H->command[strlen("SuperNET")],H->command[6] == 'e' && H->command[7] == 't'); return(0); } if ( addr != 0 ) { - if ( 0 && strcmp("DOGE",coin->symbol) == 0 ) - printf("iguana_msgparser from (%s) parse.(%s) len.%d\n",addr->ipaddr,H->command,recvlen); + if ( (0) && addr->msgcounts.verack == 0 ) + printf("iguana_msgparser verack.%d from (%s) parse.(%s) len.%d\n",addr->msgcounts.verack,addr->ipaddr,H->command,recvlen); //iguana_peerblockrequest(coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,iguana_blockhash(coin,100),0); addr->lastcontact = (uint32_t)time(NULL); strcpy(addr->lastcommand,H->command); @@ -871,17 +970,19 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc memset(&txdata,0,sizeof(txdata)); if ( ishost == 0 ) { - if ( 0 && coin->chain->auxpow != 0 ) + if ( coin->chain->debug != 0 ) { - int32_t i; for (i=0; ichain->zcash == 0 ? 80 : sizeof(struct iguana_msgzblockhdr); + for (i=0; imsgcounts.block++; - if ( (n= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen || n == recvlen-1 ) + if ( (n= iguana_gentxarray(myinfo,coin,rawmem,&txdata,&len,data,recvlen)) == recvlen || n == recvlen-1 ) { len = n; - iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen,fromcache); + iguana_gotblockM(myinfo,coin,addr,&txdata,rawmem->ptr,H,data,recvlen,fromcache,0*coin->chain->zcash); } else { @@ -909,7 +1010,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc else { intvectors = 'I', addr->msgcounts.inv++; - if ( 0 && strcmp(H->command,"inv2") == 0 ) + if ( (0) && strcmp(H->command,"inv2") == 0 ) printf("GOT INV2.%d\n",recvlen); len = iguana_intvectors(coin,addr,1,data,recvlen); // indirectly issues getdata } @@ -917,20 +1018,18 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } else if ( (ishost= (strcmp(H->command,"getheaders") == 0)) || strcmp(H->command,"headers") == 0 ) { - struct iguana_msgblock msg; struct iguana_zblock *zblocks; uint32_t tmp,n=0; + struct iguana_msgzblock zmsg; struct iguana_msgblock *msg = (void *)&zmsg; struct iguana_zblock *zblocks; uint32_t tmp,n=0; len = 0; - if ( addr != 0 && recvlen >= sizeof(bits256) && strcmp("BTCD",coin->symbol) != 0 ) + if ( addr != 0 && recvlen >= sizeof(bits256) && strcmp("RELAY",coin->symbol) != 0 ) { if ( ishost == 0 ) { len = iguana_rwvarint32(0,data,&n); if ( n <= IGUANA_MAXINV ) { - bits256 auxhash2,prevhash2; struct iguana_msgtx *tx; struct iguana_msgmerkle *coinbase_branch,*blockchain_branch; struct iguana_msgblock parentblock; - coinbase_branch = calloc(1,sizeof(*coinbase_branch)); - blockchain_branch = calloc(1,sizeof(*blockchain_branch)); + bits256 auxhash2,prevhash2; struct iguana_msgtx *tx; struct iguana_msgmerkle *coinbase_branch=0,*blockchain_branch=0; struct iguana_msgblock parentblock; if ( rawmem->totalsize == 0 ) - iguana_meminit(rawmem,"bighdrs",0,IGUANA_MAXPACKETSIZE * 2,0); + iguana_meminit(rawmem,"bighdrs",0,IGUANA_MAXPACKETSIZE * 3,0); memset(prevhash2.bytes,0,sizeof(prevhash2)); zblocks = mycalloc('z',1,(int32_t)(sizeof(struct iguana_zblock) * n)); //printf("%s got %d headers len.%d\n",coin->symbol,n,recvlen); @@ -938,32 +1037,38 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc { if ( coin->chain->auxpow != 0 ) { - tmp = iguana_rwblockhdr(0,coin->chain->zcash,&data[len],&msg); + if ( coinbase_branch == 0 ) + coinbase_branch = calloc(1,sizeof(*coinbase_branch)); + if ( blockchain_branch == 0 ) + blockchain_branch = calloc(1,sizeof(*blockchain_branch)); + tmp = iguana_rwblockhdr(0,coin->chain->zcash,&data[len],(void *)msg); hash2 = iguana_calcblockhash(coin->symbol,coin->chain->hashalgo,&data[len],tmp); len += tmp; - if ( (msg.H.version & 0x100) != 0 ) + if ( (msg->H.version & 0x100) != 0 ) { iguana_memreset(rawmem); tx = iguana_memalloc(rawmem,sizeof(*tx),1); - len += iguana_rwtx(coin->chain->zcash,0,rawmem,&data[len],tx,recvlen-len,&tx->txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0); + len += iguana_rwtx(myinfo,coin->chain->zcash,0,coin,rawmem,&data[len],tx,recvlen-len,&tx->txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0); len += iguana_rwbignum(0,&data[len],sizeof(auxhash2),auxhash2.bytes); len += iguana_rwmerklebranch(0,&data[len],coinbase_branch); len += iguana_rwmerklebranch(0,&data[len],blockchain_branch); - len += iguana_rwblockhdr(0,coin->chain->zcash,&data[len],&parentblock); + len += iguana_rwblockhdr(0,coin->chain->zcash,&data[len],(void *)&parentblock); } len += iguana_rwvarint32(0,&data[len],&tmp); char str[65],str2[65]; - if ( 0 && coin->chain->auxpow != 0 ) - printf("%d %d of %d: %s %s v.%08x numtx.%d cmp.%d\n",len,i,n,bits256_str(str,hash2),bits256_str(str2,msg.H.prev_block),msg.H.version,tmp,bits256_cmp(prevhash2,msg.H.prev_block)); - } else len += iguana_rwblock(coin->chain->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,&data[len],&msg,recvlen); - iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,(struct iguana_block *)&zblocks[i],&msg,hash2,-1); + if ( (0) && coin->chain->auxpow != 0 ) + printf("%d %d of %d: %s %s v.%08x numtx.%d cmp.%d\n",len,i,n,bits256_str(str,hash2),bits256_str(str2,zmsg.zH.prev_block),zmsg.zH.version,tmp,bits256_cmp(prevhash2,zmsg.zH.prev_block)); + } + else len += iguana_rwblock(myinfo,coin->chain->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,&data[len],(void *)&zmsg,recvlen); + iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,(void *)&zblocks[i],&zmsg,hash2,-1); prevhash2 = hash2; } - free(coinbase_branch); - free(blockchain_branch); + if ( coinbase_branch != 0 ) + free(coinbase_branch); + if ( blockchain_branch != 0 ) + free(blockchain_branch); if ( iguana_gotheadersM(coin,addr,zblocks,n) < 0 ) myfree(zblocks,(int32_t)(sizeof(struct iguana_zblock) * n)); - //myfree(blocks,sizeof(*blocks) * n); if ( len == recvlen && addr != 0 ) addr->msgcounts.headers++; } else printf("got unexpected n.%d for headers\n",n); @@ -1046,7 +1151,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc len = 0; if ( (sendlen= iguana_peeraddrrequest(coin,addr,&addr->blockspace[sizeof(H)],IGUANA_MAXPACKETSIZE)) > 0 ) { - if ( 0 ) + if ( (0) ) { int32_t checklen; uint32_t checkbits; char checkaddr[64]; checklen = iguana_rwvarint(0,&addr->blockspace[sizeof(H)],&x); @@ -1093,7 +1198,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc struct iguana_msgtx *tx; iguana_memreset(rawmem); tx = iguana_memalloc(rawmem,sizeof(*tx),1);//mycalloc('u',1,sizeof(*tx)); - len = iguana_rwtx(coin->chain->zcash,0,rawmem,data,tx,recvlen,&tx->txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0); + len = iguana_rwtx(myinfo,coin->chain->zcash,0,coin,rawmem,data,tx,recvlen,&tx->txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0); if ( addr != 0 ) { iguana_gotunconfirmedM(coin,addr,tx,data,recvlen); @@ -1114,9 +1219,9 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc addr->headerserror++; else { - for (i=0; iipaddr,addr->protover); + printf("%s reject.(%s) recvlen.%d %s proto.%d\n",coin->symbol,data+1,recvlen,addr->ipaddr,addr->protover); addr->msgcounts.reject++; } } @@ -1148,7 +1253,7 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc //printf("error.(%s) (%s): len.%d != recvlen.%d\n",H->command,addr->ipaddr,len,recvlen); //for (i=0; icommand,"addr") != 0 && (coin->chain->auxpow == 0 || strcmp(H->command,"headers") != 0) ) + if ( len != 0 && strcmp(H->command,"addr") != 0 && (coin->chain->auxpow == 0 || strcmp(H->command,"headers") != 0) && strcmp(H->command,"alert") != 0 ) printf("%s %s.%s len mismatch %d != %d\n",coin->symbol,addr!=0?addr->ipaddr:"local",H->command,len,recvlen); } else if ( len != recvlen && recvlen > 1 ) @@ -1158,4 +1263,4 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } } return(retval); -} \ No newline at end of file +} diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c new file mode 100755 index 000000000..b4a1cdef1 --- /dev/null +++ b/iguana/iguana_notary.c @@ -0,0 +1,1142 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + + +// Todo list: +// q) investigate if rebroadcast reorged local chain notary tx and scanning mempool is needed + +#define CHECKSIG 0xac + +#include "iguana777.h" +#include "notaries.h" + +int32_t dpow_datahandler(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint8_t nn_senderind,uint32_t channel,uint32_t height,uint8_t *data,int32_t datalen); +uint64_t dpow_maskmin(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp); +int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr); + +#include "dpow/dpow_network.c" +#include "dpow/dpow_rpc.c" +#include "dpow/dpow_tx.c" +#include "dpow/dpow_fsm.c" +#include "dpow/dpow_prices.c" + +void dpow_fifoupdate(struct supernet_info *myinfo,struct dpow_checkpoint *fifo,struct dpow_checkpoint tip) +{ + int32_t i,ind; struct dpow_checkpoint newfifo[DPOW_FIFOSIZE]; + memset(newfifo,0,sizeof(newfifo)); + for (i=DPOW_FIFOSIZE-1; i>0; i--) + { + if ( (0) && bits256_nonz(fifo[i-1].blockhash.hash) != 0 && (tip.blockhash.height - fifo[i-1].blockhash.height) != i ) + printf("(%d != %d) ",(tip.blockhash.height - fifo[i-1].blockhash.height),i); + if ( (ind= (tip.blockhash.height - fifo[i-1].blockhash.height)) >= 0 && ind < DPOW_FIFOSIZE ) + newfifo[ind] = fifo[i-1]; + } + newfifo[0] = tip; + memcpy(fifo,newfifo,sizeof(newfifo)); + //for (i=0; itimestamp = timestamp; + checkpoint->blocktime = blocktime; + checkpoint->blockhash.hash = hash; + checkpoint->blockhash.height = height; +} + +int32_t dpow_txhasnotarization(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid) +{ + cJSON *txobj,*vins,*vin,*vouts,*vout,*spentobj,*sobj; char *hexstr; uint8_t script[35]; bits256 spenttxid; uint64_t notarymask; int32_t i,j,numnotaries,len,spentvout,numvins,numvouts,hasnotarization = 0; + if ( (txobj= dpow_gettransaction(myinfo,coin,txid)) != 0 ) + { + if ( (vins= jarray(&numvins,txobj,"vin")) != 0 ) + { + if ( numvins >= DPOW_MIN_ASSETCHAIN_SIGS ) + { + notarymask = numnotaries = 0; + for (i=0; i>= 1; + decode_hex(script,len,hexstr); + if ( script[0] == 33 && script[34] == 0xac ) + { + for (j=0; j 0 ) + { + if ( numnotaries >= DPOW_MIN_ASSETCHAIN_SIGS ) + hasnotarization = 1; + printf("numnotaries.%d %s hasnotarization.%d\n",numnotaries,coin->symbol,hasnotarization); + } + } + } + free_json(txobj); + } + return(hasnotarization); +} + +int32_t dpow_hasnotarization(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *blockjson) +{ + int32_t i,n,hasnotarization = 0; bits256 txid; cJSON *txarray; + if ( (txarray= jarray(&n,blockjson,"tx")) != 0 ) + { + for (i=0; ilast,height,hash,timestamp,blocktime); + checkpoint = dp->srcfifo[dp->srcconfirms]; + if ( strcmp("BTC",dp->dest) == 0 ) + { + freq = DPOW_CHECKPOINTFREQ; + minsigs = DPOW_MINSIGS; + } + else + { + minsigs = DPOW_MIN_ASSETCHAIN_SIGS; + if ( strcmp("CHIPS",dp->symbol) == 0 ) + freq = 100; + else freq = 1; + } + dpow_fifoupdate(myinfo,dp->srcfifo,dp->last); + if ( strcmp(dp->dest,"KMD") == 0 ) + { + //if ( dp->SRCREALTIME == 0 ) + // return; + if ( (coin= iguana_coinfind(dp->symbol)) != 0 ) + { + hash = dpow_getbestblockhash(myinfo,coin); + if ( bits256_nonz(hash) != 0 ) + { + if ( (blockjson= dpow_getblock(myinfo,coin,hash)) != 0 ) + { + if ( dpow_hasnotarization(myinfo,coin,blockjson) <= 0 ) + { + height = jint(blockjson,"height"); + blocktime = juint(blockjson,"time"); + free_json(blockjson); + if ( height > 0 && blocktime > 0 ) + { + dpow_checkpointset(myinfo,&dp->last,height,hash,timestamp,blocktime); + //printf("dynamic set %s/%s %s <- height.%d\n",dp->symbol,dp->dest,bits256_str(str,hash),height); + checkpoint = dp->last; + } else return; + if ( bits256_nonz(dp->activehash) != 0 && bits256_cmp(dp->activehash,checkpoint.blockhash.hash) == 0 ) + { + printf("activehash.(%s) is current checkpoint, skip\n",bits256_str(str,dp->activehash)); + return; + } + else if ( bits256_nonz(dp->lastnotarized) != 0 && bits256_cmp(dp->lastnotarized,checkpoint.blockhash.hash) == 0 ) + { + printf("lastnotarized.(%s) is current checkpoint, skip\n",bits256_str(str,dp->lastnotarized)); + return; + } + //printf("checkpoint.(%s) is not active and not lastnotarized\n",bits256_str(str,checkpoint.blockhash.hash)); + } else return; + } else return; + } else return; + } else return; + } + if ( bits256_nonz(checkpoint.blockhash.hash) != 0 && (checkpoint.blockhash.height % freq) == 0 ) + { + //printf("%s/%s src ht.%d dest.%u nonz.%d %s minsigs.%d\n",dp->symbol,dp->dest,checkpoint.blockhash.height,dp->destupdated,bits256_nonz(checkpoint.blockhash.hash),bits256_str(str,dp->last.blockhash.hash),minsigs); + dpow_heightfind(myinfo,dp,checkpoint.blockhash.height + 1000); + ptrs = calloc(1,sizeof(void *)*5 + sizeof(struct dpow_checkpoint)); + ptrs[0] = (void *)myinfo; + ptrs[1] = (void *)dp; + ptrs[2] = (void *)(uint64_t)minsigs; + if ( strcmp(dp->dest,"KMD") == 0 ) + ptrs[3] = (void *)(DPOW_DURATION * 60); // essentially try forever for assetchains + else ptrs[3] = (void *)DPOW_DURATION; + ptrs[4] = 0; + memcpy(&ptrs[5],&checkpoint,sizeof(checkpoint)); + dp->activehash = checkpoint.blockhash.hash; + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_statemachinestart,(void *)ptrs) != 0 ) + { + } + } +} + +void dpow_approvedset(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_checkpoint *checkpoint,bits256 *txs,int32_t numtx) +{ + int32_t i,j; bits256 txid; + if ( txs != 0 ) + { + for (i=0; iapproved[j].hash) == 0 ) + { + if ( bits256_nonz(checkpoint->approved.hash) == 0 || dp->approved[j].height >= checkpoint->approved.height ) + checkpoint->approved = dp->approved[j]; + } + } + } + } + } +} + +void dpow_destconfirm(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_checkpoint *checkpoint) +{ + int32_t i; + if ( bits256_nonz(checkpoint->approved.hash) != 0 ) + { + for (i=DPOW_FIFOSIZE-1; i>0; i--) + dp->notarized[i] = dp->notarized[i-1]; + dp->notarized[0] = checkpoint->approved; + } +} + +void dpow_destupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime) +{ + dp->destupdated = timestamp; + dpow_checkpointset(myinfo,&dp->destchaintip,height,hash,timestamp,blocktime); + dpow_approvedset(myinfo,dp,&dp->destchaintip,dp->desttx,dp->numdesttx); + dpow_fifoupdate(myinfo,dp->destfifo,dp->destchaintip); + if ( strcmp(dp->dest,"BTC") == 0 ) + { + printf("%s destupdate ht.%d\n",dp->dest,height); + dpow_destconfirm(myinfo,dp,&dp->destfifo[DPOW_BTCCONFIRMS]); + } + else dpow_destconfirm(myinfo,dp,&dp->destfifo[DPOW_KOMODOCONFIRMS*2]); // todo: change to notarized KMD depth +} + +void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) +{ + int32_t height,num; uint32_t blocktime; bits256 blockhash; struct iguana_info *src,*dest; + //fprintf(stderr,"dp.%p dPoWupdate (%s -> %s)\n",dp,dp!=0?dp->symbol:"",dp!=0?dp->dest:""); + //if ( strcmp(dp->symbol,"KMD") == 0 ) + { + num = dpow_nanomsg_update(myinfo); + //fprintf(stderr,"%d ",num); + } + src = iguana_coinfind(dp->symbol); + dest = iguana_coinfind(dp->dest); + if ( src != 0 && dest != 0 ) + { + dp->numdesttx = sizeof(dp->desttx)/sizeof(*dp->desttx); + if ( (height= dpow_getchaintip(myinfo,&blockhash,&blocktime,dp->desttx,&dp->numdesttx,dest)) != dp->destchaintip.blockhash.height && height >= 0 ) + { + char str[65]; + if ( strcmp(dp->symbol,"KMD") == 0 )//|| height != dp->destchaintip.blockhash.height+1 ) + printf("[%s].%d %s %s height.%d vs last.%d\n",dp->symbol,dp->SRCHEIGHT,dp->dest,bits256_str(str,blockhash),height,dp->destchaintip.blockhash.height); + if ( height <= dp->destchaintip.blockhash.height ) + { + printf("iguana_dPoWupdate dest.%s reorg detected %d vs %d\n",dp->dest,height,dp->destchaintip.blockhash.height); + if ( height == dp->destchaintip.blockhash.height && bits256_cmp(blockhash,dp->destchaintip.blockhash.hash) != 0 ) + printf("UNEXPECTED ILLEGAL BLOCK in dest chaintip\n"); + } else dpow_destupdate(myinfo,dp,height,blockhash,(uint32_t)time(NULL),blocktime); + } // else printf("error getchaintip for %s\n",dp->dest); + dp->numsrctx = sizeof(dp->srctx)/sizeof(*dp->srctx); + if ( strcmp(dp->dest,"KMD") == 0 && dp->SRCHEIGHT < src->longestchain ) + { + //fprintf(stderr,"[I "); + dp->SRCHEIGHT = dpow_issuer_iteration(dp,src,dp->SRCHEIGHT,&dp->SRCREALTIME); + //fprintf(stderr," %d] ",dp->SRCHEIGHT); + } + if ( (height= dpow_getchaintip(myinfo,&blockhash,&blocktime,dp->srctx,&dp->numsrctx,src)) != dp->last.blockhash.height && height >= 0 ) + { + //char str[65]; printf("[%s].%d %s %s height.%d vs last.%d\n",dp->dest,dp->SRCHEIGHT,dp->symbol,bits256_str(str,blockhash),height,dp->last.blockhash.height); + if ( dp->lastheight == 0 ) + dp->lastheight = height-1; + if ( height < dp->last.blockhash.height ) + { + printf("iguana_dPoWupdate src.%s reorg detected %d vs %d approved.%d notarized.%d\n",dp->symbol,height,dp->last.blockhash.height,dp->approved[0].height,dp->notarized[0].height); + if ( height <= dp->approved[0].height ) + { + if ( bits256_cmp(blockhash,dp->last.blockhash.hash) != 0 ) + printf("UNEXPECTED ILLEGAL BLOCK in src chaintip\n"); + } + else + { + while ( dp->lastheight <= height ) + { + blockhash = dpow_getblockhash(myinfo,src,dp->lastheight); + dpow_srcupdate(myinfo,dp,dp->lastheight++,blockhash,(uint32_t)time(NULL),blocktime); + } + } + } + else if ( strcmp(dp->symbol,"KMD") == 0 ) + { + while ( dp->lastheight <= height ) + { + blockhash = dpow_getblockhash(myinfo,src,dp->lastheight); + dpow_srcupdate(myinfo,dp,dp->lastheight++,blockhash,(uint32_t)time(NULL),blocktime); + } + } + else if ( time(NULL) > dp->lastsrcupdate+60 || height != dp->lastheight ) + { + dp->lastsrcupdate = (uint32_t)time(NULL); + dp->lastheight = height; + blockhash = dpow_getblockhash(myinfo,src,dp->lastheight); + dpow_srcupdate(myinfo,dp,dp->lastheight,blockhash,(uint32_t)time(NULL),blocktime); + } + } //else printf("error getchaintip for %s\n",dp->symbol); + } else printf("iguana_dPoWupdate missing src.(%s) %p or dest.(%s) %p\n",dp->symbol,src,dp->dest,dest); +} + +void dpow_addresses() +{ + int32_t i; char coinaddr[64]; uint8_t pubkey[33]; + for (i=0; iDPOWS[myinfo->numdpows]; + destvalid = srcvalid = 0; + if ( myinfo->NOTARY.RELAYID < 0 ) + { + if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(myinfo->ipaddr),myinfo->myaddr.persistent)) != 0 ) + { + printf("addrelay.(%s)\n",retstr); + free(retstr); + } + if ( myinfo->NOTARY.RELAYID < 0 ) + return(clonestr("{\"error\":\"must be running as notary node\"}")); + } + if ( dp->symbol[0] != 0 ) + return(clonestr("{\"error\":\"cant dPoW more than one coin at a time\"}")); + if ( pubkey == 0 || pubkey[0] == 0 || is_hexstr(pubkey,0) != 66 ) + return(clonestr("{\"error\":\"need 33 byte pubkey\"}")); + if ( symbol == 0 || symbol[0] == 0 ) + symbol = "KMD"; + //if ( myinfo->numdpows == 1 ) + // komodo_assetcoins(-1); + if ( iguana_coinfind(symbol) == 0 ) + return(clonestr("{\"error\":\"cant dPoW an inactive coin\"}")); + if ( strcmp(symbol,"KMD") == 0 && iguana_coinfind("BTC") == 0 ) + return(clonestr("{\"error\":\"cant dPoW KMD without BTC\"}")); + else if ( myinfo->numdpows == 0 && strcmp(symbol,"KMD") != 0 && iguana_coinfind("KMD") == 0 ) + return(clonestr("{\"error\":\"cant dPoW without KMD\"}")); + if ( myinfo->numdpows > 1 ) + { + if ( strcmp(symbol,"KMD") == 0 || iguana_coinfind("BTC") == 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"cant dPoW KMD or BTC again\"}")); + } + for (i=1; inumdpows; i++) + if ( strcmp(symbol,myinfo->DPOWS[i].symbol) == 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"cant dPoW same coin again\"}")); + } + } + strcpy(dp->symbol,symbol); + if ( strcmp(dp->symbol,"KMD") == 0 ) + { + strcpy(dp->dest,"BTC"); + dp->srcconfirms = DPOW_KOMODOCONFIRMS; + } + else + { + strcpy(dp->dest,"KMD"); + dp->srcconfirms = DPOW_THIRDPARTY_CONFIRMS; + } + if ( dp->srcconfirms > DPOW_FIFOSIZE ) + dp->srcconfirms = DPOW_FIFOSIZE; + src = iguana_coinfind(dp->symbol); + dest = iguana_coinfind(dp->dest); + if ( src == 0 || dest == 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"source coin or dest coin not there\"}")); + } + char tmp[67]; + safecopy(tmp,pubkey,sizeof(tmp)); + decode_hex(dp->minerkey33,33,tmp); + bitcoin_address(srcaddr,src->chain->pubtype,dp->minerkey33,33); + if ( (retstr= dpow_validateaddress(myinfo,src,srcaddr)) != 0 ) + { + json = cJSON_Parse(retstr); + if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) + srcvalid = 1; + else srcvalid = 0; + free(retstr); + retstr = 0; + } + bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33); + if ( (retstr= dpow_validateaddress(myinfo,dest,destaddr)) != 0 ) + { + json = cJSON_Parse(retstr); + if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) + destvalid = 1; + else destvalid = 0; + free(retstr); + retstr = 0; + } + for (i=0; i<33; i++) + printf("%02x",dp->minerkey33[i]); + printf(" DPOW with pubkey.(%s) %s.valid%d %s -> %s %s.valid%d\n",tmp,srcaddr,srcvalid,dp->symbol,dp->dest,destaddr,destvalid); + if ( srcvalid <= 0 || destvalid <= 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"source address or dest address has no privkey, importprivkey\"}")); + } + if ( bitcoin_pubkeylen(dp->minerkey33) <= 0 ) + { + dp->symbol[0] = 0; + return(clonestr("{\"error\":\"illegal pubkey\"}")); + } + if ( dp->blocks == 0 ) + { + dp->maxblocks = 1000000; + dp->blocks = calloc(dp->maxblocks,sizeof(*dp->blocks)); + } + portable_mutex_init(&dp->paxmutex); + portable_mutex_init(&dp->dexmutex); + PAX_init(); + //printf(">>>>>>>>>>>>>>> call paxpending\n"); + //uint8_t buf[32768]; + //dpow_paxpending(buf); + myinfo->numdpows++; + return(clonestr("{\"result\":\"success\"}")); +} + +char *dpow_passthru(struct iguana_info *coin,char *function,char *hex) +{ + char params[32768]; int32_t len = 0; + if ( hex != 0 && hex[0] != 0 ) + { + len = (int32_t)strlen(hex) >> 1; + if ( len < sizeof(params)-1 ) + decode_hex((uint8_t *)params,(int32_t)strlen(hex),hex); + else len = 0; + } + params[len] = 0; + return(bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,function,params)); +} + +TWO_STRINGS(zcash,passthru,function,hex) +{ + if ( (coin= iguana_coinfind("ZEC")) != 0 ) + return(dpow_passthru(coin,function,hex)); + else return(clonestr("{\"error\":\"ZEC not active, start in bitcoind mode\"}")); +} + +TWO_STRINGS(komodo,passthru,function,hex) +{ + if ( (coin= iguana_coinfind("KMD")) != 0 ) + return(dpow_passthru(coin,function,hex)); + else return(clonestr("{\"error\":\"KMD not active, start in bitcoind mode\"}")); +} + +THREE_STRINGS(iguana,passthru,asset,function,hex) +{ + if ( asset != 0 && (coin= iguana_coinfind(asset)) != 0 ) + return(dpow_passthru(coin,function,hex)); + else return(clonestr("{\"error\":\"assetchain not active, start in bitcoind mode\"}")); +} + +TWO_STRINGS(dex,send,hex,handler) +{ + uint8_t data[8192]; int32_t datalen; char *retstr; + if ( hex != 0 && (datalen= is_hexstr(hex,0)) > 0 && (datalen>>1) < sizeof(data) ) + { + datalen >>= 1; + decode_hex(data,datalen,hex); + if ( handler == 0 || handler[0] == 0 ) + handler = "DEX"; + if ( (retstr= dex_reqsend(myinfo,handler,data,datalen,1,"")) == 0 ) + return(clonestr("{\"result\":\"success\"}")); + else return(retstr); + } else return(clonestr("{\"error\":\"dex send: invalid hex\"}")); +} + +STRING_ARG(dpow,pending,fiat) +{ + struct dpow_info *dp; char base[64]; int32_t i; + if ( fiat != 0 && fiat[0] != 0 ) + { + for (i=0; fiat[i]!=0; i++) + base[i] = toupper((int32_t)fiat[i]); + base[i] = 0; + for (i=0; inumdpows; i++) + { + dp = &myinfo->DPOWS[i]; + if ( strcmp(dp->symbol,base) == 0 ) + return(jprint(dpow_withdraws_pending(dp),1)); + } + } + return(clonestr("[]")); +} + +STRING_ARG(dpow,bindaddr,ipaddr) +{ + uint32_t ipbits; char checkbuf[64]; + if ( ipaddr != 0 && ipaddr[0] != 0 ) + { + ipbits = (uint32_t)calc_ipbits(ipaddr); + expand_ipbits(checkbuf,ipbits); + if ( strcmp(ipaddr,checkbuf) == 0 ) + { + strcpy(myinfo->bindaddr,ipaddr); + return(clonestr("{\"result\":\"success\"}")); + } else return(clonestr("{\"error\":\"invalid bind ipaddr\"}")); + } else return(clonestr("{\"error\":\"no bind ipaddr\"}")); +} + +STRING_ARG(iguana,addnotary,ipaddr) +{ + static int32_t didinit; + if ( didinit == 0 ) + { + dpow_addresses(); + didinit = 1; + } + printf("addnotary (%s) -> (%s)\n",ipaddr,myinfo->ipaddr); + dpow_nanomsginit(myinfo,ipaddr); + return(clonestr("{\"result\":\"notary node added\"}")); +} + +char NOTARY_CURRENCIES[][16] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", + "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", + "REVS", "SUPERNET", "DEX", "PANGEA", "JUMBLR", "BET", "CRYPTO", "HODL", "BOTS", "MGW", "COQUI", "WLC", "KV", "CEAL", "MESH", "MNZ", "CHIPS", "MSHARK", "AXO", "ETOMIC", "BTCH" }; // "LTC", + +void _iguana_notarystats(char *fname,int32_t totals[64],int32_t dispflag) +{ + FILE *fp; uint64_t signedmask; long fpos,startfpos; int32_t i,height,iter,prevheight; + if ( (fp= fopen(fname,"rb")) != 0 ) + { + printf("opened %s\n",fname); + startfpos = 0; + prevheight = -1; + for (iter=0; iter<2; iter++) + { + while ( 1 ) + { + fpos = ftell(fp); + if (fread(&height,1,sizeof(height),fp) == sizeof(height) && fread(&signedmask,1,sizeof(signedmask),fp) == sizeof(signedmask) ) + { + //printf("%6d %016llx\n",height,(long long)signedmask); + if ( height < prevheight ) + { + startfpos = fpos; + if ( iter == 0 ) + printf("found reversed height %d vs %d\n",height,prevheight); + else printf("fpos.%ld fatal unexpected height reversal %d vs %d\n",fpos,height,prevheight); + } + if ( iter == 1 && (height >= 180000 || strcmp(fname,"signedmasks") != 0) ) + { + for (i=0; i<64; i++) + { + if ( ((1LL << i) & signedmask) != 0 ) + { + totals[i]++; + if ( dispflag > 1 ) + printf("%2d ",i); + } + } + if ( dispflag > 1 ) + printf("height.%d %016llx %s\n",height,(long long)signedmask,fname); + } + prevheight = height; + } else break; + } + if ( iter == 0 ) + { + prevheight = -1; + fseek(fp,startfpos,SEEK_SET); + printf("set startfpos %ld\n",startfpos); + } + } + fclose(fp); + if ( dispflag != 0 ) + { + printf("after %s\n",fname); + for (i=0; i<64; i++) + { + if ( totals[i] != 0 ) + printf("%s, %d\n",Notaries_elected[i][0],totals[i]); + } + } + } else printf("couldnt open.(%s)\n",fname); +} + +void iguana_notarystats(int32_t totals[64],int32_t dispflag) +{ + int32_t i; char fname[512]; + _iguana_notarystats("signedmasks",totals,dispflag); + for (i=0; i current - numblocks ) + { + printf("ht.%d %llx vs current.%d - %d\n",height,(long long)signedmask,current,numblocks); + for (j=0; j<64; j++) + if ( ((1LL << j) & signedmask) != 0 ) + vals[j] += (double)DPOW_UTXOSIZE / SATOSHIDEN; + } + } else break; + } + fclose(fp); + } else return(clonestr("{\"error\":\"cant open signedmasks\"}")); + for (sum=j=0; j 0. ) + { + bitcoin_address(coinaddr,0,pubkeys[j],33); // fixed + sprintf(cmd,"bitcoin-cli sendtoaddress %s %f\n",coinaddr,val); + if ( sendflag != 0 && system(cmd) != 0 ) + printf("ERROR with (%s)\n",cmd); + else + { + printf("%s\n",cmd); + sum += val; + } + } + } + printf("%s sent %.8f BTC\n",sendflag!=0?"":"would have",sum); + return(clonestr("{\"result\":\"success\"}")); + } + else return(clonestr("{\"error\":\"cant find BTC\"}")); + } + for (i=0; iDPOWS[0].lastrecvmask; + for (i=0; i<64; i++) + { + if ( ((1LL << i) & mask) != 0 ) + { + printf("(%d %llx %s) ",i,(long long)(1LL << i),Notaries[i][0]); + jaddistr(array,Notaries[i][0]); + } + } + retjson = cJSON_CreateObject(); + jadd64bits(retjson,"recvmask",mask); + jadd(retjson,"notaries",array); + return(jprint(retjson,1)); + } + printf("dpow active (%s)\n",maskhex); + if ( (len= (int32_t)strlen(maskhex)) <= 16 ) + { + len >>= 1; + memset(data,0,sizeof(data)); + decode_hex(data,len,maskhex); + for (i=0; iDPOWS[0].cancelratify = 1; + return(clonestr("{\"result\":\"queued dpow cancel ratify\"}")); +} + +TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified) +{ + void **ptrs; bits256 zero; int32_t i; char *source; struct dpow_checkpoint checkpoint; + if ( ratified == 0 ) + return(clonestr("{\"error\":\"no ratified list for dpow ratify\"}")); + memset(zero.bytes,0,sizeof(zero)); + dpow_checkpointset(myinfo,&checkpoint,0,zero,timestamp,timestamp); + ptrs = calloc(1,sizeof(void *)*5 + sizeof(struct dpow_checkpoint)); + ptrs[0] = (void *)myinfo; + if ( (source= jstr(json,"source")) == 0 ) + source = "KMD"; + ptrs[1] = (void *)&myinfo->DPOWS[0]; + for (i=0; inumdpows; i++) + if ( strcmp(myinfo->DPOWS[0].symbol,source) == 0 ) + { + ptrs[1] = (void *)&myinfo->DPOWS[i]; + break; + } + ptrs[2] = (void *)(long)minsigs; + ptrs[3] = (void *)DPOW_RATIFYDURATION; + ptrs[4] = (void *)jprint(ratified,0); + memcpy(&ptrs[5],&checkpoint,sizeof(checkpoint)); + myinfo->DPOWS[0].cancelratify = 0; + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_statemachinestart,(void *)ptrs) != 0 ) + { + } + return(clonestr("{\"result\":\"started ratification\"}")); +} + +HASH_AND_STRING(dex,gettransaction,txid,symbol) +{ + /*char str[65],url[1024],*retstr; + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/transaction/%s?api_key=%s",bits256_str(str,txid),myinfo->blocktrail_apikey); + + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unspent-outputs?api_key=%s",address,myinfo->blocktrail_apikey); + }*/ + return(_dex_getrawtransaction(myinfo,symbol,txid)); +} + +HASH_AND_STRING_AND_INT(dex,gettxout,txid,symbol,vout) +{ + /*char str[65],url[1024],*retstr; + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/transaction/%s?api_key=%s",bits256_str(str,txid),myinfo->blocktrail_apikey); + }*/ + return(_dex_gettxout(myinfo,symbol,txid,vout)); +} + +TWO_STRINGS(dex,listunspent,symbol,address) +{ + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + char url[1024],*retstr,*coinaddr,*script; int32_t i,n,vout; cJSON *retjson,*data,*item,*item3,*data3; bits256 txid; uint64_t val; + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unspent-outputs?api_key=%s",address,myinfo->blocktrail_apikey); + if ( (retstr= issue_curl(url)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + data = jarray(&n,retjson,"data"); + data3 = cJSON_CreateArray(); + //[{"hash":"e0a40dac21103e92e0dc9311a0233640489afc5beb5ba3b009848a8e9151dc55","time":"2017-02-21T16:48:28+0000","confirmations":1,"is_coinbase":false,"value":4100000,"index":1,"address":"19rjYdJtRN3qoammX3r1gxy9bvh8p8DmRc","type":"pubkeyhash","multisig":null,"script":"OP_DUP OP_HASH160 6128e7459989d35d530bcd4066c9aaf1f925430a OP_EQUALVERIFY OP_CHECKSIG","script_hex":"76a9146128e7459989d35d530bcd4066c9aaf1f925430a88ac"}] + /*{ + "txid" : "e95d3083baf733dfda2fcd1110fe2937cb3580f8b1b237aad547528440dfa873", + "vout" : 1, + "address" : "RNgdefRo2iRLWqDXEogJrsTw35MgDPQP4R", + "account" : "", + "scriptPubKey" : "76a91493088c5f3546225e0ef6ba9c9c6a74d4c2df877388ac", + "amount" : 150.00000000, + "interest" : 0.30000000, + "confirmations" : 20599, + "spendable" : true + }*/ + for (i=0; iFULLNODE < 0 ) + return(jprint(dpow_listunspent(myinfo,coin,address),1)); + //printf("call _dex_listunspent\n"); + return(_dex_listunspent(myinfo,symbol,address)); +} + +TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions,symbol,address,count,skip) +{ + if ( symbol != 0 && strcmp(symbol,"BTC") == 0 && (coin= iguana_coinfind("BTC")) != 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + char url[1024],*retstr,*retstr2; cJSON *retjson,*retjson2,*retjson3,*data,*data2; int32_t i,n; + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/transactions?api_key=%s",address,myinfo->blocktrail_apikey); + if ( (retstr= issue_curl(url)) != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s/unconfirmed-transactions?api_key=%s",address,myinfo->blocktrail_apikey); + if ( (retstr2= issue_curl(url)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 && (retjson2= cJSON_Parse(retstr2)) != 0 ) + { + data = jarray(&n,retjson,"data"); + data2 = jarray(&n,retjson2,"data"); + retjson3 = jduplicate(data); + if ( n > 0 ) + { + for (i=0; i (%s)\n",retstr,retstr2,jprint(retjson3,0)); + free(retstr); + free(retstr2); + free_json(retjson); + free_json(retjson2); + return(jprint(retjson3,1)); + } + } + } + } + return(_dex_listtransactions(myinfo,symbol,address,count,skip)); +} + +STRING_ARG(dex,getinfo,symbol) +{ + return(_dex_getinfo(myinfo,symbol)); +} + +STRING_ARG(dex,getbestblockhash,symbol) +{ + return(_dex_getbestblockhash(myinfo,symbol)); +} + +STRING_ARG(dex,alladdresses,symbol) +{ + return(_dex_alladdresses(myinfo,symbol)); +} + +STRING_AND_INT(dex,getblockhash,symbol,height) +{ + return(_dex_getblockhash(myinfo,symbol,height)); +} + +HASH_AND_STRING(dex,getblock,hash,symbol) +{ + return(_dex_getblock(myinfo,symbol,hash)); +} + +TWO_STRINGS(dex,sendrawtransaction,symbol,signedtx) +{ + return(_dex_sendrawtransaction(myinfo,symbol,signedtx)); +} + +TWO_STRINGS(dex,importaddress,symbol,address) +{ + return(_dex_importaddress(myinfo,symbol,address)); +} + +TWO_STRINGS(dex,checkaddress,symbol,address) +{ + return(_dex_checkaddress(myinfo,symbol,address)); +} + +TWO_STRINGS(dex,validateaddress,symbol,address) +{ + return(_dex_validateaddress(myinfo,symbol,address)); +} + +STRING_ARG(dex,getmessage,argstr) +{ + return(_dex_getmessage(myinfo,argstr)); +} + +STRING_ARG(dex,psock,argstr) +{ + return(_dex_psock(myinfo,argstr)); +} + +STRING_ARG(dex,getnotaries,symbol) +{ + return(_dex_getnotaries(myinfo,symbol)); +} + +TWO_STRINGS(dex,kvsearch,symbol,key) +{ + if ( key == 0 || key[0] == 0 ) + return(clonestr("{\"error\":\"kvsearch parameter error\"}")); + return(_dex_kvsearch(myinfo,symbol,key)); +} + +THREE_STRINGS_AND_THREE_INTS(dex,kvupdate,symbol,key,value,flags,unused,unusedb) +{ + // need to have some micropayments between client/server, otherwise receiving server incurs costs + if ( key == 0 || key[0] == 0 || value == 0 || value[0] == 0 ) + return(clonestr("{\"error\":\"kvupdate parameter error\"}")); + if ( strcmp(symbol,"KV") == 0 ) + { + if ( flags > 1 ) + return(clonestr("{\"error\":\"only single duration updates via remote access\"}")); + else if ( strlen(key) > 64 || strlen(value) > 256 ) + return(clonestr("{\"error\":\"only keylen <=64 and valuesize <= 256 allowed via remote access\"}")); + else + { + //printf("call _dex_kvupdate.(%s) -> (%s) flags.%d\n",key,value,flags); + return(_dex_kvupdate(myinfo,symbol,key,value,flags)); + } + } else return(clonestr("{\"error\":\"free updates only on KV chain\"}")); +} + +#include "kmd_lookup.h" + +TWO_STRINGS(dex,listunspent2,symbol,address) +{ + cJSON *retjson; + if ( myinfo->DEXEXPLORER != 0 ) + { + if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + if ( strcmp(coin->symbol,"BTC") == 0 || coin->DEXEXPLORER == 0 ) + return(clonestr("[]")); + if ( (retjson= kmd_listunspent(myinfo,coin,address)) != 0 ) + return(jprint(retjson,1)); + } + } + if ( symbol != 0 && address != 0 ) + return(_dex_listunspent2(myinfo,symbol,address)); + else return(clonestr("{\"error\":\"dex listunspent2 null symbol, address or coin\"}")); +} + +TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions2,symbol,address,count,skip) +{ + cJSON *retjson; + if ( myinfo->DEXEXPLORER != 0 ) + { + if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + if ( strcmp(coin->symbol,"BTC") == 0 || coin->DEXEXPLORER == 0 ) + return(clonestr("[]")); + if ( (retjson= kmd_listtransactions(myinfo,coin,address,count,skip)) != 0 ) + return(jprint(retjson,1)); + } + } + if ( symbol != 0 && address != 0 ) + return(_dex_listtransactions2(myinfo,symbol,address,count,skip)); + else return(clonestr("{\"error\":\"dex listunspent2 null symbol, address or coin\"}")); +} + +HASH_AND_STRING_AND_INT(dex,gettxin,txid,symbol,vout) +{ + if ( myinfo->DEXEXPLORER != 0 ) + { + if ( symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->DEXEXPLORER != 0 ) + return(jprint(kmd_gettxin(coin,txid,vout),1)); + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + } + if ( symbol != 0 ) + return(_dex_gettxin(myinfo,symbol,txid,vout)); + else return(clonestr("{\"error\":\"dex gettxin null symbolor coin\"}")); +} + +TWO_STRINGS(dex,listspent,symbol,address) +{ + if ( myinfo->DEXEXPLORER != 0 ) + { + if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->DEXEXPLORER != 0 ) + return(jprint(kmd_listspent(myinfo,coin,address),1)); + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + } + if ( symbol != 0 && address != 0 ) + return(_dex_listspent(myinfo,symbol,address)); + else return(clonestr("{\"error\":\"dex listspent null symbol, address or coin\"}")); +} + +TWO_STRINGS(dex,getbalance,symbol,address) +{ + char url[512],*retstr; cJSON *retjson; uint64_t val; + if ( myinfo->DEXEXPLORER != 0 ) + { + //printf("DEXEXPLORER\n"); + if ( symbol != 0 && address != 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->DEXEXPLORER != 0 ) + return(jprint(kmd_getbalance(myinfo,coin,address),1)); + if ( coin != 0 ) + coin->DEXEXPLORER = myinfo->DEXEXPLORER * myinfo->IAMNOTARY * (iguana_isnotarychain(coin->symbol) >= 0); + } + if ( symbol != 0 && address != 0 ) + { + if ( strcmp(symbol,"BTC") == 0 && myinfo->blocktrail_apikey[0] != 0 ) + { + sprintf(url,"https://api.blocktrail.com/v1/btc/address/%s?api_key=%s",address,myinfo->blocktrail_apikey); + if ( (retstr= issue_curl(url)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + //printf("balance\n"); + if ( (val= j64bits(retjson,"balance")) != 0 ) + { + jdelete(retjson,"balance"); + jaddnum(retjson,"balance",dstr(val)); + } + //printf("sent\n"); + if ( (val= j64bits(retjson,"sent")) != 0 ) + { + jdelete(retjson,"sent"); + jaddnum(retjson,"sent",dstr(val)); + } + //printf("received\n"); + if ( (val= j64bits(retjson,"received")) != 0 ) + { + jdelete(retjson,"received"); + jaddnum(retjson,"received",dstr(val)); + } + //printf("unconfirmed_sent\n"); + if ( (val= j64bits(retjson,"unconfirmed_sent")) != 0 ) + { + jdelete(retjson,"unconfirmed_sent"); + jaddnum(retjson,"unconfirmed_sent",dstr(val)); + } + //printf("unconfirmed_received\n"); + if ( (val= j64bits(retjson,"unconfirmed_received")) != 0 ) + { + jdelete(retjson,"unconfirmed_received"); + jaddnum(retjson,"unconfirmed_received",dstr(val)); + } + //printf("blocktrail.(%s) -> (%s)\n",retstr,jprint(retjson,0)); + free(retstr); + retstr = jprint(retjson,1); + } + } + return(retstr); + } + return(_dex_getbalance(myinfo,symbol,address)); + } else return(clonestr("{\"error\":\"dex getbalance null symbol, address or coin\"}")); +} + +STRING_ARG(dex,explorer,symbol) +{ + if ( symbol != 0 && (coin= iguana_coinfind(symbol)) != 0 ) + { + myinfo->DEXEXPLORER = 1; + coin->DEXEXPLORER = 1; + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"coin not active\"}")); +} + +#include "../includes/iguana_apiundefs.h" + + diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 79f58a38c..cbc23aa6c 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -162,45 +162,62 @@ cJSON *iguana_scriptobj(struct iguana_info *coin,uint8_t rmd160[20],char *coinad return(scriptobj); } -int32_t iguana_RTbestunspent(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct iguana_outpoint *unspents,int32_t numunspents,uint64_t value) +int32_t iguana_RTbestunspent(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct iguana_outpoint *unspents,int32_t numunspents,uint64_t value,int32_t maxmode) { - int32_t i,abovei,belowi; int64_t above,below,gap,atx_value; + int32_t i,abovei,belowi; int64_t above,below,gap,atx_value,maxvalue = 0; abovei = belowi = -1; for (above=below=i=0; i value ) + { + gap = (atx_value - value); + if ( above == 0 || gap < above ) + { + above = gap; + abovei = i; + } + } else gap = (value - atx_value); + if ( below == 0 || gap < below ) + { + below = gap; + belowi = i; + } } - else if ( atx_value > value ) + else { - gap = (atx_value - value); - if ( above == 0 || gap < above ) + //printf("(%.8f vs %.8f)\n",dstr(atx_value),dstr(maxvalue)); + if ( atx_value > maxvalue ) { - above = gap; + maxvalue = atx_value; + above = (atx_value - value); abovei = i; } - } else gap = (value - atx_value); - if ( below == 0 || gap < below ) - { - below = gap; - belowi = i; } } *aboveip = abovei; *abovep = above; *belowip = belowi; *belowp = below; + //printf("above.%d below.%d\n",abovei,belowi); return(abovei >= 0 ? abovei : belowi); } @@ -216,15 +233,15 @@ cJSON *iguana_inputjson(bits256 txid,int32_t vout,uint8_t *spendscript,int32_t s return(item); } -cJSON *iguana_RTinputsjson(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *totalp,uint64_t amount,struct iguana_outpoint *unspents,int32_t num) +cJSON *iguana_RTinputsjson(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *totalp,uint64_t amount,struct iguana_outpoint *unspents,int32_t num,int32_t maxmode) { - cJSON *vins; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE]; struct iguana_txid *T; struct iguana_unspent *U,*u; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; char coinaddr[64]; int32_t vout,height,abovei,belowi,i,spendlen,ind; uint32_t txidind; struct iguana_ramchaindata *rdata; bits256 txid; int64_t above,below,total = 0; struct iguana_outpoint outpt; int64_t remains = amount; + struct iguana_outpoint outpt; cJSON *vins; int32_t abovei,belowi,i,ind; int64_t above,below,total = 0,remains = amount; *totalp = 0; vins = cJSON_CreateArray(); for (i=0; iFULLNODE == 0 && coin->VALIDATENODE == 0 ) - { - if ( (spendlen= basilisk_unspentfind(myinfo,coin,&txid,&vout,spendscript,outpt,outpt.value)) > 0 ) - { - jaddi(vins,iguana_inputjson(txid,vout,spendscript,spendlen)); - total += outpt.value; - remains -= outpt.value; - //printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains)); - if ( remains <= 0 ) - break; - } - continue; - } - if ( (spendlen= _iguana_RTunspentfind(myinfo,coin,&txid,&vout,spendscript,outpt,outpt.value)) > 0 ) - { - jaddi(vins,iguana_inputjson(txid,vout,spendscript,spendlen)); - total += outpt.value; - remains -= outpt.value; - //printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains)); - if ( remains <= 0 ) - break; - continue; - } - if ( (bp= coin->bundles[outpt.hdrsi]) == 0 ) - { - printf("no bundle.[%d]\n",outpt.hdrsi); - free_json(vins); - return(0); - } - ramchain = &bp->ramchain; - if ( (rdata= ramchain->H.data) == 0 ) - continue; - U = RAMCHAIN_PTR(rdata,Uoffset); - T = RAMCHAIN_PTR(rdata,Toffset); - if ( outpt.unspentind > 0 && outpt.unspentind < rdata->numunspents ) - { - u = &U[outpt.unspentind]; - if ( (txidind= u->txidind) > 0 && txidind < rdata->numtxids ) - { - if ( iguana_unspentindfind(myinfo,coin,coinaddr,spendscript,&spendlen,&amount,&height,T[txidind].txid,u->vout,coin->bundlescount-1,0) == outpt.unspentind && spendlen > 0 ) - { - jaddi(vins,iguana_inputjson(T[txidind].txid,u->vout,spendscript,spendlen)); - total += outpt.value; - remains -= outpt.value; - //printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains)); - if ( remains <= 0 ) - break; - } - else - { - char str[65];printf("couldnt get script for %s.%d\n",bits256_str(str,T[txidind].txid),u->vout); - free_json(vins); - return(0); - } - } - else - { - printf("illegal txidind.%d [%d]\n",txidind,outpt.hdrsi); - free_json(vins); - return(0); - } - } - else - { - printf("%s illegal unspentind.u%d [%d]\n",coin->symbol,outpt.unspentind,outpt.hdrsi); - free_json(vins); - return(0); - } + jaddi(vins,iguana_inputjson(outpt.txid,outpt.vout,outpt.spendscript,outpt.spendlen)); + total += outpt.value; + remains -= outpt.value; + //printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains)); + if ( remains <= 0 ) + break; } *totalp = total; return(vins); @@ -319,29 +274,53 @@ char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,int memset(&msgtx,0,sizeof(msgtx)); if ( V == 0 ) V = calloc(numinputs,sizeof(*V)), flagV = 1; - //printf("SIGN.(%s) priv.(%s) %llx %llx\n",jprint(vins,0),jprint(privkeys,0),(long long)V->signers[0].privkey.txid,(long long)V->signers[1].privkey.txid); + //printf("SIGN.(%s) priv.(%s) %llx %llx (%s)\n",jprint(vins,0),jprint(privkeys,0),(long long)V->signers[0].privkey.txid,(long long)V->signers[1].privkey.txid,vins!=0?jprint(vins,0):"no vins"); if ( V != 0 ) { if ( iguana_signrawtransaction(myinfo,coin,height,&msgtx,&signedtx,signedtxidp,V,numinputs,rawtx,vins,privkeys) > 0 ) *completedp = 1; else printf("signrawtransaction incomplete\n"); + //for (i=0; i> 1; serialized = calloc(1,sizeof(struct iguana_msghdr) + len); decode_hex(&serialized[sizeof(struct iguana_msghdr)],len,signedtx); txid = bits256_doublesha256(0,&serialized[sizeof(struct iguana_msghdr)],len); + if ( coin->FULLNODE < 0 || coin->notarychain >= 0 ) + { + if ( coin->FULLNODE < 0 ) + str = dpow_sendrawtransaction(myinfo,coin,signedtx); + else str = _dex_sendrawtransaction(myinfo,coin->symbol,signedtx); + if ( str != 0 ) + { + if ( is_hexstr(str,0) == sizeof(checktxid)*2 ) + { + decode_hex(checktxid.bytes,sizeof(checktxid),str); + if ( bits256_cmp(txid,checktxid) == 0 ) + { + free(str); + return(txid); + } + } + free(str); + memset(txid.bytes,0,sizeof(txid)); + return(txid); + } + } if ( coin->peers != 0 && (n= coin->peers->numranked) > 0 ) { for (i=0; i<8 && i= 7777777 ) + return(0); + if ( (minutes= ((uint32_t)time(NULL) - 60 - txlocktime) / 60) >= 60 ) + { + if ( minutes > 365 * 24 * 60 ) + minutes = 365 * 24 * 60; + if ( txheight >= 250000 ) + minutes -= 59; + denominator = (((uint64_t)365 * 24 * 60) / minutes); + if ( denominator == 0 ) + denominator = 1; // max KOMODO_INTEREST per transfer, do it at least annually! + if ( value > 25000LL*SATOSHIDEN && txheight > 155949 ) + { + numerator = (value / 20); // assumes 5%! + if ( txheight < 250000 ) + interest = (numerator / denominator); + else interest = (numerator * minutes) / ((uint64_t)365 * 24 * 60); + } + else if ( value >= 10*SATOSHIDEN ) + { + /*numerator = (value * KOMODO_INTEREST); + if ( txheight < 250000 || numerator * minutes < 365 * 24 * 60 ) + interest = (numerator / denominator) / SATOSHIDEN; + else interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)) / SATOSHIDEN;*/ + numerator = (value * KOMODO_INTEREST); + if ( txheight < 250000 || now < activation ) + { + if ( txheight < 250000 || numerator * minutes < 365 * 24 * 60 ) + interest = (numerator / denominator) / SATOSHIDEN; + else interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)) / SATOSHIDEN; + } + else + { + numerator = (value / 20); // assumes 5%! + interest = ((numerator * minutes) / ((uint64_t)365 * 24 * 60)); + //fprintf(stderr,"interest %llu %.8f <- numerator.%llu minutes.%d\n",(long long)interest,(double)interest/COIN,(long long)numerator,(int32_t)minutes); + } + } + //fprintf(stderr,"komodo_interest.%d %lld %.8f nLockTime.%u tiptime.%u minutes.%d interest %lld %.8f (%llu / %llu)\n",txheight,(long long)value,(double)value/SATOSHIDEN,txlocktime,now,minutes,(long long)interest,(double)interest/SATOSHIDEN,(long long)numerator,(long long)denominator); + } + return(interest); +} + +uint64_t iguana_interest(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout,uint64_t value) +{ + char *retstr; int32_t height; cJSON *retjson=0; struct iguana_txid T,*tx; uint64_t interest=0; + if ( coin->FULLNODE < 0 ) // komodod is running + { + if ( (retjson= dpow_gettxout(myinfo,coin,txid,vout)) != 0 ) + { + interest = jdouble(retjson,"interest") * SATOSHIDEN; + free_json(retjson); + } + } + else if ( coin->FULLNODE == 0 ) // basilisk mode -> use DEX* API + { + if ( (retstr= _dex_gettxout(myinfo,coin->symbol,txid,vout)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + interest = jdouble(retjson,"interest") * SATOSHIDEN; + free_json(retjson); + } + free(retstr); + } + } + else // we have it local + { + if ( (tx= iguana_txidfind(coin,&height,&T,txid,coin->bundlescount)) != 0 && tx->locktime > LOCKTIME_THRESHOLD ) + { + interest = _iguana_interest((uint32_t)time(NULL),coin->longestchain,tx->locktime,value); + } + } + return(interest); +} + +uint64_t iguana_interests(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) { - uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; int32_t max,num,spendlen; char *rawtx=0; bits256 txid; cJSON *vins=0; uint64_t avail,total,change; struct iguana_outpoint *unspents = 0; struct vin_info *V=0; + int32_t i,n; cJSON *item; uint64_t value,interest = 0; + if ( is_cJSON_Array(vins) != 0 && (n= cJSON_GetArraySize(vins)) > 0 ) + { + for (i=0; i 0 ) + { + for (j=0; jFULLNODE != 0 && is_cJSON_False(jobj(item,"spendable")) != 0 ) + continue; + if ( (spendscriptstr= jstr(item,"scriptPubKey")) == 0 ) + { + printf("no spendscriptstr %d.(%s)\n",i,jprint(array,0)); + continue; + } + unspents = realloc(unspents,(1 + max) * sizeof(*unspents)); + value = jdouble(item,"amount") * SATOSHIDEN; + if ( (0) && jdouble(item,"interest") != 0 ) + printf("utxo has interest of %.8f\n",jdouble(item,"interest")); + iguana_outptset(myinfo,coin,&unspents[max++],jbits256(item,"txid"),jint(item,"vout"),value,spendscriptstr); + avail += value; + } + } + free_json(array); + } + } + if ( unspents == 0 ) + return(0); + num = max; + /*unspents = calloc(max,sizeof(*unspents)); if ( (num= iguana_RTunspentslists(myinfo,coin,&avail,unspents,max,satoshis+txfee,minconf,addresses,remoteaddr)) <= 0 ) { free(unspents); return(0); - } + }*/ + printf("avail %.8f satoshis %.8f, txfee %.8f burnamount %.8f vin0.scriptlen %d num.%d\n",dstr(avail),dstr(satoshis),dstr(txfee),dstr(burnamount),unspents[0].spendlen,num); if ( txobj != 0 && avail >= satoshis+txfee ) { - if ( (vins= iguana_RTinputsjson(myinfo,coin,&total,satoshis + txfee,unspents,num)) != 0 ) + if ( (vins= iguana_RTinputsjson(myinfo,coin,&total,satoshis + txfee,unspents,num,maxmode)) != 0 ) { + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + if ( (interest= iguana_interests(myinfo,coin,vins)) != 0 ) + { + total += interest; + printf("boost total by interest %.8f\n",dstr(interest)); + } + } if ( total < (satoshis + txfee) ) { free_json(vins); @@ -385,7 +502,7 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS printf("insufficient total %.8f vs (%.8f + %.8f)\n",dstr(total),dstr(satoshis),dstr(txfee)); return(0); } - if ( (change= (total - (satoshis + txfee))) > 0 && (changeaddr == 0 || changeaddr[0] == 0) ) + if ( (change= (total - (satoshis + txfee))) > 10000 && (changeaddr == 0 || changeaddr[0] == 0) ) { printf("no changeaddr for %.8f\n",dstr(change)); free_json(vins); @@ -393,7 +510,7 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS return(0); } iguana_createvins(myinfo,coin,txobj,vins); - if ( change > 0 ) + if ( change > 10000 ) { if ( iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) { @@ -405,21 +522,115 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); spendlen = bitcoin_standardspend(spendscript,0,rmd160); bitcoin_txoutput(txobj,spendscript,spendlen,change); - int32_t i; for (i=0; i 16 ) + { + + } + else if ( (sobj= jobj(item,"scriptPubKey")) == 0 || (spendscriptstr= jstr(sobj,"hex")) == 0 ) + { + printf("no spendscript (%s)\n",jprint(item,0)); + continue; + } + unspents = realloc(unspents,(1 + max) * sizeof(*unspents)); + if ( (value= jdouble(item,"value") * SATOSHIDEN) == 0 ) + value = jdouble(item,"amount") * SATOSHIDEN; + interests += SATOSHIDEN * jdouble(item,"interest"); + //printf("(%s) ",jprint(item,0)); + iguana_outptset(myinfo,coin,&unspents[max++],jbits256(item,"txid"),jint(item,"vout"),value,spendscriptstr); + avail += value; + } + if ( unspents == 0 ) + return(0); + num = max; + printf("avail %.8f interests %.8f satoshis %.8f, txfee %.8f vin0.scriptlen %d\n",dstr(avail),dstr(interests),dstr(satoshis),dstr(txfee),unspents[0].spendlen); + if ( txobj != 0 && avail >= satoshis+txfee ) + { + if ( (vins= iguana_RTinputsjson(myinfo,coin,&total,satoshis + txfee,unspents,num,maxmode)) != 0 ) + { + if ( strcmp(coin->symbol,"KMD") == 0 ) + { + if ( (interests= iguana_interests(myinfo,coin,vins)) != 0 ) + { + total += interests; + printf("boost total by interest %.8f\n",dstr(interests)); + } + } + if ( total < (satoshis + txfee) ) + { + free_json(vins); + free(unspents); + printf("insufficient total %.8f vs (%.8f + %.8f)\n",dstr(total),dstr(satoshis),dstr(txfee)); + return(0); + } + if ( (change= (total - (satoshis + txfee))) > 10000 && (changeaddr == 0 || changeaddr[0] == 0) ) + { + printf("no changeaddr for %.8f\n",dstr(change)); + free_json(vins); + free(unspents); + return(0); + } + iguana_createvins(myinfo,coin,txobj,vins); + if ( change > 10000 ) + { + if ( iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) + { + free_json(vins); + free(unspents); + printf("illegal destination address.(%s)\n",changeaddr); + return(0); + } + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + bitcoin_txoutput(txobj,spendscript,spendlen,change); + } + if ( vins != 0 && V == 0 ) + { + V = calloc(cJSON_GetArraySize(vins),sizeof(*V)), allocflag = 1; + //iguana_vinprivkeys(myinfo,coin,V,vins); + } rawtx = bitcoin_json2hex(myinfo,coin,&txid,txobj,V); - if ( V != 0 ) + if ( allocflag != 0 ) free(V); } } @@ -431,7 +642,7 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS void iguana_RTunspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) { struct iguana_outpoint spentpt; char coinaddr[64]; int32_t i,RTspentflag,num,spentheight,lockedflag; - if ( coin->MAXPEERS == 1 || coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + if ( coin->MAXPEERS == 1 || coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) { num = cJSON_GetArraySize(vins); for (i=0; i [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y + if ( coin->RTheight == 0 && coin->FULLNODE != 0 ) + return(clonestr("{\"error\":\"need to get to realtime blocks to send transaction\"}")); if ( account == 0 || account[0] == 0 ) account = "*"; addresses = iguana_getaddressesbyaccount(myinfo,coin,account); if ( coin->changeaddr[0] == 0 ) { - //if ( (waddr= iguana_getaccountaddress(myinfo,coin,0,0,coin->changeaddr,"change")) == 0 ) - // return(clonestr("{\"error\":\"no change address specified\"}")); bitcoin_address(coin->changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); printf("%s change %s\n",coin->symbol,coin->changeaddr); } - if ( coinaddr != 0 && coinaddr[0] != 0 && satoshis != 0 ) + if ( destaddr != 0 && destaddr[0] != 0 && satoshis != 0 ) { - if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,destaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); - bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + bitcoin_addr2rmd160(&addrtype,rmd160,destaddr); spendlen = bitcoin_standardspend(spendscript,0,rmd160); init_hexbytes_noT(spendscriptstr,spendscript,spendlen); basilisktag = (uint32_t)rand(); @@ -475,15 +686,15 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char * jaddnum(valsobj,"basilisktag",basilisktag); jaddnum(valsobj,"locktime",locktime); jaddnum(valsobj,"timeout",30000); - if ( 0 && comment != 0 && is_hexstr(comment,0) > 0 ) + if ( (0) && comment != 0 && is_hexstr(comment,0) > 0 ) jaddstr(valsobj,"opreturn",comment); - if ( (retstr= basilisk_bitcoinrawtx(myinfo,coin,remoteaddr,basilisktag,jint(valsobj,"timeout"),valsobj)) != 0 ) + if ( (retstr= basilisk_bitcoinrawtx(myinfo,coin,remoteaddr,basilisktag,jint(valsobj,"timeout"),valsobj,V)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (rawtx= jstr(retjson,"rawtx")) != 0 && (vins= jobj(retjson,"vins")) != 0 ) { - if ( (signedtx= iguana_signrawtx(myinfo,coin,coin->blocks.hwmchain.height,&signedtxid,&completed,vins,rawtx,0,0)) != 0 ) + if ( (signedtx= iguana_signrawtx(myinfo,coin,coin->blocks.hwmchain.height,&signedtxid,&completed,vins,rawtx,0,V)) != 0 ) { iguana_RTunspentslock(myinfo,coin,vins); retjson = cJSON_CreateObject(); @@ -494,8 +705,10 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char * { senttxid = iguana_sendrawtransaction(myinfo,coin,signedtx); if ( bits256_cmp(senttxid,signedtxid) == 0 ) + { jaddstr(retjson,"sendrawtransaction","success"); - else jaddbits256(retjson,"senderror",senttxid); + iguana_unspents_mark(myinfo,coin,vins); + } else jaddbits256(retjson,"senderror",senttxid); } free_json(vins); free(signedtx); @@ -518,12 +731,15 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char * #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees) { cJSON *retjson = cJSON_CreateObject(); bits256 txid; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_sendrawtransaction(myinfo,coin->symbol,rawtx)); txid = iguana_sendrawtransaction(myinfo,coin,rawtx); jaddbits256(retjson,"result",txid); return(jprint(retjson,1)); @@ -597,6 +813,7 @@ INT_ARRAY_STRING(bitcoinrpc,createmultisig,M,pubkeys,ignore) if ( n < 0 || n > 16 || M < 0 || M > n ) return(clonestr("{\"error\":\"illegal number of pubkeys\"}")); memset(&V,0,sizeof(V)); + //printf("create M.%d of N.%d (%s)\n",M,n,jprint(pubkeys,0)); V.M = M, V.N = n; pkjson = cJSON_CreateArray(); addresses = cJSON_CreateArray(); @@ -633,6 +850,7 @@ INT_ARRAY_STRING(bitcoinrpc,createmultisig,M,pubkeys,ignore) jaddstr(retjson,"error","couldnt get all pubkeys"); free_json(pkjson); } + //printf("CREATEMULTISIG.(%s)\n",jprint(retjson,0)); return(jprint(retjson,1)); } @@ -646,7 +864,6 @@ INT_ARRAY_STRING(bitcoinrpc,addmultisigaddress,M,pubkeys,account) // myinfo->expiration++; if ( (retstr= bitcoinrpc_createmultisig(IGUANA_CALLARGS,M,pubkeys,account)) != 0 ) { - //printf("CREATEMULTISIG.(%s)\n",retstr); if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( (msigaddr= jstr(retjson,"address")) != 0 ) @@ -678,18 +895,25 @@ INT_ARRAY_STRING(bitcoinrpc,addmultisigaddress,M,pubkeys,account) // HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool) { - uint8_t script[IGUANA_MAXSCRIPTSIZE],rmd160[20],pubkey33[33]; char coinaddr[128],asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; struct iguana_bundle *bp; int32_t minconf,scriptlen,unspentind,height,spentheight; int64_t RTspend; int64_t value; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P; struct iguana_txid *T; struct iguana_unspent *U; struct iguana_outpoint outpt; struct iguana_ramchain *ramchain; cJSON *scriptobj,*retjson = cJSON_CreateObject(); + uint8_t script[IGUANA_MAXSCRIPTSIZE],rmd160[20],pubkey33[33]; char coinaddr[128],asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; struct iguana_bundle *bp; int32_t firstslot,minconf,scriptlen,unspentind,height,spentheight=-1; struct iguana_RTtxid *ptr; uint64_t RTspend,value; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P; struct iguana_txid *T; struct iguana_unspent *U; struct iguana_outpoint outpt; struct iguana_ramchain *ramchain; cJSON *scriptobj,*retjson = cJSON_CreateObject(); if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( coin != 0 ) { - if ( (value= _RTgettxout(coin,&height,&scriptlen,script,rmd160,coinaddr,txid,vout,mempool)) > 0 ) + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_gettxout(myinfo,coin->symbol,txid,vout)); + if ( (value= _RTgettxout(coin,&ptr,&height,&scriptlen,script,rmd160,coinaddr,txid,vout,mempool)) > 0 ) { jaddbits256(retjson,"bestblock",coin->blocks.hwmchain.RO.hash2); jaddnum(retjson,"bestheight",coin->blocks.hwmchain.height); jaddnum(retjson,"height",height); + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); jaddnum(retjson,"confirmations",coin->blocks.hwmchain.height - height + 1); jaddnum(retjson,"value",dstr(value)); + jaddnum(retjson,"amount",dstr(value)); + if ( strcmp(coin->symbol,"KMD") == 0 ) + jaddnum(retjson,"interest",dstr(iguana_interest(myinfo,coin,txid,vout,value))); if ( (height % coin->chain->bundlesize) == 0 && vout == 0 ) jadd(retjson,"coinbase",jtrue()); else jadd(retjson,"coinbase",jfalse()); @@ -699,8 +923,9 @@ HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool) return(jprint(retjson,1)); } minconf = (mempool != 0) ? 0 : 1; - if ( (unspentind= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) != 0 ) + if ( iguana_RTunspentindfind(myinfo,coin,&outpt,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0) == 0 && outpt.isptr == 0 ) { + unspentind = outpt.unspentind; if ( height >= 0 && height < coin->longestchain && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 ) { ramchain = &bp->ramchain; @@ -713,7 +938,7 @@ HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool) memset(&outpt,0,sizeof(outpt)); outpt.hdrsi = bp->hdrsi; outpt.unspentind = unspentind; - if ( iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,ramchain,outpt,height,minconf,coin->longestchain,U[unspentind].value) == 0 ) + if ( iguana_markedunspents_find(coin,&firstslot,txid,vout) < 0 && iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,ramchain,outpt,height,minconf,coin->longestchain,U[unspentind].value) == 0 ) { jaddbits256(retjson,"bestblock",coin->blocks.hwmchain.RO.hash2); jaddnum(retjson,"bestheight",coin->blocks.hwmchain.height); @@ -813,7 +1038,7 @@ THREE_STRINGS(bitcoinrpc,verifymessage,address,sig,message) // printf("%02x",sigbuf[i]); //printf(" siglen.%d [%d] address.(%s) sig.(%s) message.(%s)\n",len,sigbuf[0],address,sig,message); hash2 = iguana_messagehash2(message,coin->chain->messagemagic); - if ( bitcoin_recoververify(myinfo->ctx,coin->symbol,sigbuf,hash2,pubkey) == 0 ) + if ( bitcoin_recoververify(myinfo->ctx,coin->symbol,sigbuf,hash2,pubkey,0) == 0 ) jadd(retjson,"result",jtrue()); else jadd(retjson,"result",jfalse()); jaddstr(retjson,"coin",coin->symbol); @@ -831,12 +1056,54 @@ THREE_STRINGS(bitcoinrpc,verifymessage,address,sig,message) } else return(clonestr("{\"error\":\"sig is too long\"}")); } +int64_t iguana_txdetails(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *item,bits256 txid,int32_t vout,int32_t height) +{ + struct iguana_block *block; bits256 hash2; uint64_t amount = 0; char coinaddr[64],account[512]; + /*{ + "category": "receive", + "amount": 0.50000000, + "label": "", + "confirmations": 24466, + "blockhash": "00000000000000000517ce625737579f91162c46ad9eaccad0f52ca13715b156", + "blockindex": 78, + "blocktime": 1448045745, + }*/ + jaddbits256(item,"txid",txid); + if ( vout >= 0 ) + { + jaddnum(item,"vout",vout); + if ( (amount= iguana_txidamount(myinfo,coin,coinaddr,txid,vout)) != 0 ) + jaddnum(item,"amount",dstr(amount)); + jaddstr(item,"category",iguana_txidcategory(myinfo,coin,account,coinaddr,txid,vout)); + } + else + { + if ( vout == -1 ) + jadd(item,"coinbase",jtrue()); + vout = 0; + } + if ( account[0] != 0 && jobj(item,"account") == 0 ) + jaddstr(item,"account",account); + if ( coinaddr[0] != 0 ) + jaddstr(item,"address",coinaddr); + hash2 = iguana_blockhash(coin,height); + jaddbits256(item,"blockhash",hash2); + if ( (block= iguana_blockfind("rawtx",coin,hash2)) != 0 ) + jaddnum(item,"blocktime",block->RO.timestamp); + jaddnum(item,"height",height); + jaddnum(item,"confirmations",coin->blocks.hwmchain.height - height); + return(amount); +} + HASH_AND_INT(bitcoinrpc,getrawtransaction,txid,verbose) { - struct iguana_txid *tx,T; char *txbytes; bits256 checktxid; int32_t len=0,height,extralen=65536; cJSON *retjson,*txobj; uint8_t *extraspace; struct iguana_block *block; bits256 hash2; struct iguana_RTtxid *RTptr; + struct iguana_txid *tx,T; char *txbytes; bits256 checktxid; int32_t len=0,height,extralen=65536; cJSON *retjson,*txobj; uint8_t *extraspace; struct iguana_RTtxid *RTptr; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_getrawtransaction(myinfo,coin->symbol,txid)); HASH_FIND(hh,coin->RTdataset,txid.bytes,sizeof(txid),RTptr); + memset(checktxid.bytes,0,sizeof(checktxid)); if ( RTptr != 0 && RTptr->rawtxbytes != 0 && RTptr->txlen > 0 ) { checktxid = RTptr->txid; @@ -861,12 +1128,7 @@ HASH_AND_INT(bitcoinrpc,getrawtransaction,txid,verbose) free(txbytes); if ( txobj != 0 ) { - hash2 = iguana_blockhash(coin,height); - jaddbits256(txobj,"blockhash",hash2); - if ( (block= iguana_blockfind("rawtx",coin,hash2)) != 0 ) - jaddnum(txobj,"blocktime",block->RO.timestamp); - jaddnum(txobj,"height",height); - jaddnum(txobj,"confirmations",coin->blocks.hwmchain.height - height); + iguana_txdetails(myinfo,coin,txobj,checktxid,-2,height); return(jprint(txobj,1)); } } @@ -888,20 +1150,25 @@ HASH_AND_INT(bitcoinrpc,getrawtransaction,txid,verbose) datalen = (int32_t)(strlen(blockstr) >> 1); data = malloc(datalen); decode_hex(data,datalen,blockstr); - if ( (txbytes= iguana_txscan(coin,verbose != 0 ? retjson : 0,data,datalen,txid)) != 0 ) + if ( (txbytes= iguana_txscan(myinfo,coin,verbose != 0 ? retjson : 0,data,datalen,txid)) != 0 ) { jaddstr(retjson,"result",txbytes); jaddbits256(retjson,"blockhash",blockhash); jaddnum(retjson,"height",height); free(txbytes); - } else jaddstr(retjson,"error","cant find txid in block"); + } + else if ( coin->RTheight > 0 ) + jaddstr(retjson,"error","cant find txid in block"); + else jaddstr(retjson,"error","not in realtime mode yet"); free(blockstr); free(data); } else jaddstr(retjson,"error","cant find blockhash"); return(jprint(retjson,1)); } } - return(clonestr("{\"error\":\"cant find txid\"}")); + if ( coin->RTheight > 0 ) + return(clonestr("{\"error\":\"cant find txid\"}")); + else return(clonestr("{\"error\":\"not in realtime mode yet\"}")); } int64_t iguana_lockval(int32_t finalized,int64_t locktime) @@ -914,7 +1181,7 @@ int64_t iguana_lockval(int32_t finalized,int64_t locktime) char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys) { - bits256 signedtxid,txid; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *checkstr,*signedtx; int32_t finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum,lockval; + bits256 signedtxid,txid; struct iguana_outpoint outpt; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *checkstr,*signedtx; int32_t plen,finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum,lockval; retjson = cJSON_CreateObject(); inputsum = outputsum = numinputs = numoutputs = 0; if ( rawtx != 0 && rawtx[0] != 0 && coin != 0 ) @@ -925,8 +1192,9 @@ char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin if ( (txobj= bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys)) != 0 ) { //printf("txobj.(%s)\n",jprint(txobj,0)); - if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) + if ( (0) && (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) { + // no guarantee byte for byte identical tx is recreated if ( strcmp(rawtx,checkstr) != 0 ) { jaddstr(retjson,"error","converting from hex2json and json2hex mismatch"); @@ -937,7 +1205,7 @@ char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin break; jaddnum(retjson,"mismatch position",i); jadd(retjson,"origtx",txobj); - if ( (txobj= bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&txid,msgtx,checkstr,extraspace,extralen,0,0,suppress_pubkeys)) != 0 ) + if ( (0) && (txobj= bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&txid,msgtx,checkstr,extraspace,extralen,0,0,suppress_pubkeys)) != 0 ) jadd(retjson,"checktx",txobj); free(checkstr); return(jprint(retjson,1)); @@ -963,34 +1231,48 @@ char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin for (i=0; ivins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,mempool)) > 0 ) + if ( iguana_RTunspentindfind(myinfo,coin,&outpt,V[i].coinaddr,V[i].spendscript,&V[i].spendlen,&V[i].amount,&V[i].height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,mempool) == 0 ) { + V[i].suppress_pubkeys = suppress_pubkeys; + V[i].unspentind = outpt.unspentind; inputsum += V[i].amount; msgtx->vins[i].spendscript = V[i].spendscript; - msgtx->vins[i].spendlen = V[i].spendlen; + if ( (msgtx->vins[i].spendlen= V[i].spendlen) == 35 ) + { + if ( (plen= bitcoin_pubkeylen(msgtx->vins[i].spendscript+1)) > 0 ) + { + memcpy(V[i].signers[0].pubkey,msgtx->vins[i].spendscript+1,plen); + V[i].suppress_pubkeys = 1; + } + } V[i].hashtype = iguana_vinscriptparse(coin,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); + //if ( (V[i].signers[0].siglen= sigsize) > 0 ) + // memcpy(V[i].signers[0].sig,msgtx->vins[i].vinscript+1,sigsize); V[i].userdatalen = suffixlen; memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); V[i].spendlen = msgtx->vins[i].spendlen; if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) finalized = 0; - //printf("V %.8f (%s) spendscript.[%d] scriptlen.%d\n",dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen); - } - } - V[0].suppress_pubkeys = suppress_pubkeys; - if ( (complete= bitcoin_verifyvins(coin,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,1,0,suppress_pubkeys)) > 0 && signedtx != 0 ) - { - msgtx->txid = signedtxid; - log = cJSON_CreateArray(); - lockval = iguana_lockval(finalized,jint(txobj,"locktime")); - if ( iguana_interpreter(coin,log,lockval,V,numinputs) < 0 ) - { - jaddstr(retjson,"error","interpreter rejects tx"); - } - jadd(retjson,"interpreter",log); + if ( V[i].M == 0 ) + V[i].M = 1; + if ( V[i].N < V[i].M ) + V[i].N = V[i].M; + //printf("V %dof%d %.8f (%s) spendscript.[%d] scriptlen.%d\n",V[i].M,V[i].N,dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen); + } else printf("couldnt find spendscript\n"); } + complete = 0; + bitcoin_verifyvins(coin,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,1,0,suppress_pubkeys); + msgtx->txid = signedtxid; + log = cJSON_CreateArray(); + lockval = iguana_lockval(finalized,jint(txobj,"locktime")); + if ( iguana_interpreter(coin,log,lockval,V,numinputs) < 0 ) + jaddstr(retjson,"error","interpreter rejects tx"); + else complete = 1; + jadd(retjson,"interpreter",log); jaddnum(retjson,"complete",complete); free(serialized), free(serialized2); + if ( signedtx != 0 ) + free(signedtx); } } //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); @@ -1005,27 +1287,47 @@ char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin STRING_AND_INT(bitcoinrpc,validaterawtransaction,rawtx,suppress) { - uint8_t *extraspace; int32_t extralen=65536;// char *retstr; struct iguana_msgtx msgtx; + uint8_t *extraspace; int32_t extralen=65536; char *retstr; struct iguana_msgtx msgtx; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - - //cJSON *txobj; char *teststr= "{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"20fe936da3707c8c4cc7eb0352160ec3f50b9454d46425df6347b2fbc5b2ec87ea00\",\"txid\":\"ee12e50b629d5d45438570fff841d1a2ba7d27f356de4aa06900c9a5e38cf141\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a9145cc47cc123e3f9b7dce0230009b9d3013a9e0c9687\"},\"suppress\":1,\"redeemScript\":\"6304165daa57b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a9143805600256ed8498ca1ec426759212e5835e8dc2882103a7b696908f77d69ec89887f8c4a0423b9e80b5974dc43301bd7d8abad07e1211ac68\"}],\"vout\":[{\"satoshis\":\"21821\",\"scriptPubkey\":{\"hex\":\"76a9143ef4734c1141725c095342095f6e0e7748b6c16588ac\"}}]}"; - - cJSON *txobj; char *teststr= "{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"206efad760ee54b9b2e2a038a821ef9f950eb0e248545ac202c3e2074cd14f92cb00\",\"txid\":\"3f4759381a62154f2f0eefed1e4433342548ad7b269f912820383b715a39273c\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a91446dcccef39c1d8c6da2ccc35dce2bfa7ec0d168887\"},\"suppress\":1,\"redeemScript\":\"63041c60aa57b1752103175cf93574c31637b8c2d8acd5319e3cd23761b5e418d32c6bcb194972ba9273ac67a9142d75daf71325feaa593b8f30989e462892189914882102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac68\"}],\"vout\":[{\"satoshis\":\"18625\",\"scriptPubkey\":{\"hex\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}}]}"; - // 01000000013c27395a713b382028919f267bad48253433441eedef0e2f4f15621a3859473f00000000d147304402207ecd423b55c1aa45a994c4eb4337ff0891692fbb69954a9ba024745a99c5272d02207cea696425feb5388153ab7f2608d66a66e4c95cfda2d44e98bc56e25994d3f701206efad760ee54b9b2e2a038a821ef9f950eb0e248545ac202c3e2074cd14f92cb004c6763041c60aa57b1752103175cf93574c31637b8c2d8acd5319e3cd23761b5e418d32c6bcb194972ba9273ac67a9142d75daf71325feaa593b8f30989e462892189914882102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac68ffffffff01c1480000000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000 - // 01000000013c27395a713b382028919f267bad48253433441eedef0e2f4f15621a3859473f00000000fd8b00206efad760ee54b9b2e2a038a821ef9f950eb0e248545ac202c3e2074cd14f92cb004c6763041c60aa57b1752103175cf93574c31637b8c2d8acd5319e3cd23761b5e418d32c6bcb194972ba9273ac67a9142d75daf71325feaa593b8f30989e462892189914882102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac68ffffffff01c1480000000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000 - //cJSON *txobj; char *teststr= "{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"20ae439d344513eab8e718d8214fe6ae8133b8b5b594afd64da21d0e40b9c37cdd00\",\"txid\":\"2c1320315f4fb519cbf2b4d7b67855013b9a09a85e515df43b41d407a0083b09\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a9142e7674400d04217f770f2222126dc7fee44b06b487\"},\"suppress\":1,\"redeemScript\":\"63041686a657b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a914ed74c61c27656abc6c20687c3a9212ffdc6f34cd88210398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcbf4baac68\"}],\"vout\":[{\"satoshis\":\"16733\",\"scriptPubkey\":{\"hex\":\"76a91454a752f0d71b89d7c014ed0be29ca231c9546f9f88ac\"}}]}"; extraspace = calloc(1,extralen); - if ( (txobj= cJSON_Parse(teststr)) != 0 ) + retstr = iguana_validaterawtx(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,extraspace,extralen,rawtx,0,suppress); + free(extraspace); + return(rawtx); +} + +int32_t iguana_validatesigs(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t datalen) +{ + uint8_t *extraspace; cJSON *retjson; int32_t extralen=65536; char *retstr,*rawtx; struct iguana_msgtx msgtx; int32_t suppress=0,retval = -1; + rawtx = calloc(1,datalen*2 + 1); + init_hexbytes_noT(rawtx,serialized,datalen); + extraspace = calloc(1,extralen); + for (suppress=0; suppress<1; suppress++) { - bits256 txid; - rawtx = bitcoin_json2hex(myinfo,coin,&txid,txobj,0); - txobj = bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&txid,0,rawtx,extraspace,extralen,0,0,suppress); - printf("RAWTX.(%s) -> (%s)\n",rawtx,jprint(txobj,0)); + if ( (retstr= iguana_validaterawtx(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,extraspace,extralen,rawtx,0,suppress)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"error") == 0 ) + { + retval = 0; + //char str[65]; printf("%s %s sigs validated\n",coin->symbol,bits256_str(str,msgtx.txid)); + coin->sigsvalidated++; + break; + } + else + { + printf("ERROR.(%s)\n",retstr); + coin->sigserrs++; + } + free_json(retjson); + } + free(retstr); + } } - //retstr = iguana_validaterawtx(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,extraspace,extralen,rawtx,0,suppress); + free(rawtx); free(extraspace); - return(rawtx); + return(retval); } STRING_AND_INT(bitcoinrpc,decoderawtransaction,rawtx,suppress) @@ -1056,7 +1358,7 @@ HASH_ARG(bitcoinrpc,gettransaction,txid) cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *txobj,cJSON *vins) { - int32_t i,n,vout,p2shlen=0,spendlen=0,unspentind,height; uint64_t satoshis; char coinaddr[128],pubkeystr[256],scriptstr[IGUANA_MAXSCRIPTSIZE*2],*str,*hexstr; cJSON *pubkeys,*item,*obj,*newvin,*newvins; uint32_t sequenceid; bits256 txid; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE],redeemscript[IGUANA_MAXSCRIPTSIZE]; struct iguana_waccount *wacct; struct iguana_waddress *waddr; + int32_t i,j,n,vout,p2shlen=0,spendlen=0,height; uint64_t satoshis; char coinaddr[128],pubkeystr[256],scriptstr[IGUANA_MAXSCRIPTSIZE*2],*str,*hexstr; cJSON *pubkeys,*item,*obj,*newvin,*newvins; uint32_t sequenceid; bits256 txid; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE],redeemscript[IGUANA_MAXSCRIPTSIZE]; struct iguana_waccount *wacct; struct iguana_waddress *waddr; struct iguana_outpoint outpt; newvins = cJSON_CreateArray(); if ( (n= cJSON_GetArraySize(vins)) > 0 ) { @@ -1070,17 +1372,46 @@ cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,c jaddbits256(newvin,"txid",txid); jaddnum(newvin,"vout",vout); p2shlen = spendlen = 0; - if ( ((str= jstr(item,"scriptPub")) != 0 || (str= jstr(item,"scriptPubkey")) != 0) && is_hexstr(str,(int32_t)strlen(str)) > 0 ) + if ( ((str= jstr(item,"scriptPub")) != 0 || (str= jstr(item,"scriptPubKey")) != 0) && is_hexstr(str,(int32_t)strlen(str)) > 0 ) { spendlen = (int32_t)strlen(str) >> 1; decode_hex(spendscript,spendlen,str); } - else if ( ((obj= jobj(item,"scriptPub")) != 0 || (obj= jobj(item,"scriptPubkey")) != 0) && (hexstr= jstr(obj,"hex")) != 0 ) + else if ( ((obj= jobj(item,"scriptPub")) != 0 || (obj= jobj(item,"scriptPubKey")) != 0) && (hexstr= jstr(obj,"hex")) != 0 ) { spendlen = (int32_t)strlen(hexstr) >> 1; decode_hex(spendscript,spendlen,hexstr); } - if ( (unspentind= iguana_RTunspentindfind(myinfo,coin,coinaddr,spendscript,&spendlen,&satoshis,&height,txid,vout,coin->bundlescount-1,0)) > 0 ) + if ( coin->FULLNODE == 0 && coin->notarychain >= 0 ) + { + char *retstr; cJSON *txoutjson,*sobj,*array; int32_t numaddrs; + if ( (retstr= _dex_gettxout(myinfo,coin->symbol,txid,vout)) != 0 ) + { + // {"bestblock":"000000000000000002a530b32efce4cb4ee01b401d58592ce36939d84c9f94b9","confirmations":109,"value":0.00120000,"scriptPubKey":{"asm":"OP_DUP OP_HASH160 971f98b33fb838faee190e2fab799440d8c51702 OP_EQUALVERIFY OP_CHECKSIG","hex":"76a914971f98b33fb838faee190e2fab799440d8c5170288ac","reqSigs":1,"type":"pubkeyhash","addresses":["1En4tL4drN5qAZDtu1BCC7DThj58yrx7cX"]},"version":1,"coinbase":false,"randipbits":847292520,"coin":"BTC","tag":"18220985608713355389"} + + if ( (txoutjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (sobj= jobj(txoutjson,"scriptPubKey")) != 0 && (array= jarray(&numaddrs,txoutjson,"addresses")) != 0 ) + { + for (j=0; jpubkey,bitcoin_pubkeylen(waddr->pubkey)); + jaddistr(pubkeys,pubkeystr); + //printf("pubkeys[%d] <- (%s)\n",j,pubkeystr); + } + } + } + } + free_json(txoutjson); + } + free(retstr); + } + } + else if ( iguana_RTunspentindfind(myinfo,coin,&outpt,coinaddr,spendscript,&spendlen,&satoshis,&height,txid,vout,coin->bundlescount-1,0) == 0 ) { //printf("[%d] unspentind.%d (%s) spendlen.%d %.8f\n",height/coin->chain->bundlesize,unspentind,coinaddr,spendlen,dstr(satoshis)); if ( coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) @@ -1092,7 +1423,7 @@ cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,c if ( spendlen > 0 ) { init_hexbytes_noT(scriptstr,spendscript,spendlen); - jaddstr(newvin,"scriptPub",scriptstr); + jaddstr(newvin,"scriptPubKey",scriptstr); } if ( (str= jstr(item,"redeemScript")) != 0 ) { @@ -1110,7 +1441,7 @@ cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,c else sequenceid = 0xffffffff; } jaddnum(newvin,"sequence",sequenceid); - bitcoin_txinput(coin,txobj,txid,vout,sequenceid,spendscript,spendlen,redeemscript,p2shlen,0,0); + bitcoin_txinput(coin,txobj,txid,vout,sequenceid,spendscript,spendlen,redeemscript,p2shlen,0,0,0,0); jadd(newvin,"pubkeys",pubkeys); jaddi(newvins,newvin); } @@ -1123,7 +1454,7 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) bits256 txid; int32_t offset,spendlen=0,n; uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint64_t satoshis; char *hexstr,*field,*txstr; cJSON *txobj,*item,*obj,*retjson = cJSON_CreateObject(); if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( coin != 0 && (txobj= bitcoin_txcreate(coin->chain->isPoS,locktime,locktime==0?coin->chain->normal_txversion:coin->chain->locktime_txversion)) != 0 ) + if ( coin != 0 && (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,locktime,1,0)) != 0 ) { iguana_createvins(myinfo,coin,txobj,vins); if ( (n= cJSON_GetArraySize(vouts)) > 0 ) @@ -1201,21 +1532,32 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) return(jprint(retjson,1)); } -TWOINTS_AND_ARRAY(bitcoinrpc,listunspent,minconf,maxconf,array) +cJSON *iguana_listunspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,char *remoteaddr) { - //int32_t numrmds,numunspents=0; uint8_t *rmdarray; cJSON *retjson = cJSON_CreateArray(); - cJSON *argarray,*retjson; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); + cJSON *retjson; int32_t flag = 0; + if ( array == 0 || is_cJSON_Array(array) == 0 || cJSON_GetArraySize(array) <= 0 ) + { + array = iguana_getaddressesbyaccount(myinfo,coin,"*"); + flag = 1; + //printf("listunspent.(%s)\n",jprint(array,0)); + } if ( minconf == 0 ) minconf = 1; if ( maxconf == 0 ) maxconf = (1 << 30); - if ( (argarray= array) == 0 || cJSON_GetArraySize(array) == 0 ) - argarray = iguana_getaddressesbyaccount(myinfo,coin,"*"); - retjson = iguana_RTlistunspent(myinfo,coin,argarray,minconf,maxconf,remoteaddr); - if ( argarray != array ) - free_json(argarray); + retjson = iguana_RTlistunspent(myinfo,coin,array,minconf,maxconf,remoteaddr,0); + if ( array != 0 && flag != 0 ) + free_json(array); + return(retjson); +} + +TWOINTS_AND_ARRAY(bitcoinrpc,listunspent,minconf,maxconf,array) +{ + //int32_t numrmds,numunspents=0; uint8_t *rmdarray; cJSON *retjson = cJSON_CreateArray(); + cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = iguana_listunspents(myinfo,coin,array,minconf,maxconf,remoteaddr); return(jprint(retjson,1)); } @@ -1230,7 +1572,7 @@ ZERO_ARGS(bitcoinrpc,getrawchangeaddress) INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array) { - struct iguana_outpoint outpt; int32_t RTspendflag,vout,i,n,height,spentheight,lockedflag; cJSON *item,*retjson; bits256 txid; uint32_t unspentind; + struct iguana_outpoint outpt; int32_t RTspendflag,vout,i,n,height,spentheight,lockedflag; cJSON *item,*retjson; bits256 txid; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); retjson = cJSON_CreateObject(); @@ -1243,11 +1585,10 @@ INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array) { txid = jbits256(item,"txid"); vout = jint(item,"vout"); - if ( (unspentind= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) != 0 ) + if ( iguana_RTunspentindfind(myinfo,coin,&outpt,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0) == 0 ) { - memset(&outpt,0,sizeof(outpt)); - outpt.hdrsi = height / coin->chain->bundlesize; - outpt.unspentind = unspentind; + //outpt.hdrsi = height / coin->chain->bundlesize; + //outpt.unspentind = unspentind; iguana_RTutxofunc(coin,&spentheight,&lockedflag,outpt,&RTspendflag,!flag,0); } } @@ -1298,13 +1639,16 @@ DOUBLE_ARG(bitcoinrpc,settxfee,amount) S_D_SS(bitcoinrpc,sendtoaddress,address,amount,comment,comment2) { + char *retstr; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); myinfo->expiration++; //iguana_unspentset(myinfo,coin); - return(sendtoaddress(myinfo,coin,remoteaddr,address,amount * SATOSHIDEN,coin->txfee,comment,comment2,coin->minconfirms,0)); + if ( (retstr= sendtoaddress(myinfo,coin,remoteaddr,address,amount * SATOSHIDEN,coin->txfee,comment,comment2,coin->minconfirms,0)) != 0 ) + printf("SEND.(%s)\n",retstr); + return(retstr); } SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2) @@ -1329,6 +1673,7 @@ S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment) //iguana_unspentset(myinfo,coin); n = cJSON_GetArraySize(payments); item = payments->child; + retjson = cJSON_CreateArray(); for (required=i=0; istring) != 0 ) @@ -1338,15 +1683,133 @@ S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment) printf("(%s %.8f) ",coinaddr,dstr(val)); if ( (str= sendtoaddress(myinfo,coin,remoteaddr,coinaddr,val,coin->txfee,comment,"",minconf,fromaccount)) != 0 ) { - free(str); + jaddistr(retjson,str); } required += val; } item = item->next; } printf("required %.8f\n",dstr(required)); + return(jprint(retjson,1)); +} + +THREE_INTS(iguana,splitfunds,satoshis,duplicates,sendflag) +{ + char *rawtx; uint8_t pubkey33[33]; int32_t completed; cJSON *retjson,*addresses; bits256 signedtxid; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( coin == 0 ) + return(clonestr("{\"error\":\"need active coin\"}")); + retjson = cJSON_CreateObject(); + bitcoin_pubkey33(myinfo->ctx,pubkey33,myinfo->persistent_priv); + addresses = iguana_getaddressesbyaccount(myinfo,coin,"*"); + if ( (rawtx= iguana_utxoduplicates(myinfo,coin,pubkey33,satoshis,duplicates,&completed,&signedtxid,sendflag,addresses)) != 0 ) + { + jaddstr(retjson,"result",rawtx); + jaddbits256(retjson,"txid",signedtxid); + jadd(retjson,"completed",completed != 0 ? jtrue() : jfalse()); + free(rawtx); + } else jaddstr(retjson,"error","couldnt create duplicates tx"); + if ( addresses != 0 ) + free_json(addresses); + return(jprint(retjson,1)); +} + +P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount,destaddress2,destamount2,M,N,pubA,wifA,pubB,wifB,pubC,wifC) +{ + struct vin_info V; uint8_t p2sh_rmd160[20],serialized[2096],spendscript[32],pubkeys[3][65],*pubkeyptrs[3]; int32_t spendlen,height = 0; + char msigaddr[64],*retstr; cJSON *retjson,*txobj; struct iguana_info *active; + bits256 signedtxid; char *signedtx; + struct iguana_msgtx msgtx; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( (active= iguana_coinfind(activecoin)) == 0 ) + return(clonestr("{\"error\":\"activecoin isnt active\"}")); + if ( M > N || N > 3 ) + return(clonestr("{\"error\":\"illegal M or N\"}")); + memset(&V,0,sizeof(V)); + txobj = bitcoin_txcreate(active->symbol,active->chain->isPoS,0,coin->chain->normal_txversion,0); + if ( destaddress[0] != 0 && destamount > 0. ) + bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); + if ( destaddress2[0] != 0 && destamount2 > 0. ) + bitcoin_txaddspend(active,txobj,destaddress2,destamount2 * SATOSHIDEN); + if ( pubA[0] != 0 && (retstr= _setVsigner(active,&V,0,pubA,wifA)) != 0 ) + return(retstr); + if ( N >= 2 && pubB[0] != 0 && (retstr= _setVsigner(active,&V,1,pubB,wifB)) != 0 ) + return(retstr); + if ( N == 3 && pubC[0] != 0 && (retstr= _setVsigner(active,&V,2,pubC,wifC)) != 0 ) + return(retstr); + V.M = M, V.N = N, V.type = IGUANA_SCRIPT_P2SH; + V.p2shlen = bitcoin_MofNspendscript(p2sh_rmd160,V.p2shscript,0,&V); + spendlen = bitcoin_p2shspend(spendscript,0,p2sh_rmd160); + if ( pubA[0] != 0 ) + { + decode_hex(pubkeys[0],(int32_t)strlen(pubA)>>1,pubA); + pubkeyptrs[0] = pubkeys[0]; + } + if ( pubB[0] != 0 ) + { + decode_hex(pubkeys[1],(int32_t)strlen(pubB)>>1,pubB); + pubkeyptrs[1] = pubkeys[1]; + } + if ( pubC[0] != 0 ) + { + decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC); + pubkeyptrs[2] = pubkeys[2]; + } + bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N,0,0); + bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); retjson = cJSON_CreateObject(); + if ( bitcoin_verifyvins(active,height,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL,1,V.suppress_pubkeys) == 0 ) + { + jaddstr(retjson,"result","msigtx"); + if ( signedtx != 0 ) + jaddstr(retjson,"signedtx",signedtx), free(signedtx); + jaddbits256(retjson,"txid",signedtxid); + } else jaddstr(retjson,"error","couldnt sign tx"); + jaddstr(retjson,"msigaddr",msigaddr); return(jprint(retjson,1)); } +STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) +{ + char *signedtx = 0; struct vin_info *V; bits256 signedtxid; int32_t complete,numinputs = 1; struct iguana_msgtx msgtx; cJSON *retjson; int uselessbitcoin_error = 0; + retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + //printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash); + if ( sighash == 0 || sighash[0] == 0 ) + sighash = "ALL"; + if ( strcmp(sighash,"ALL") != 0 ) + jaddstr(retjson,"error","only sighash all (ALL) supported for now"); + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) + { + V = calloc(numinputs,sizeof(*V)); + memset(&msgtx,0,sizeof(msgtx)); + if ( (complete= iguana_signrawtransaction(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) + { + if ( signedtx != 0 ) + { + jaddstr(retjson,"result",signedtx); + jadd(retjson,"complete",complete!=0?jtrue():jfalse()); + free(signedtx); + } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins"); + } + else if ( complete == -2 ) + jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error"); + else if ( complete == -1 ) + jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs"); + free(V); + //for (i=0; i +#endif + #include "iguana777.h" #define _iguana_hashfind(coin,ipbits) _iguana_hashset(coin,ipbits,-1) @@ -88,7 +101,10 @@ struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint32_t ipbits,in ptr = iguana_memalloc(mem,allocsize,1); else ptr = mycalloc('t',1,allocsize); if ( ptr == 0 ) - printf("fatal alloc errorA in hashset\n"), exit(-1); + { + printf("fatal alloc errorA in hashset\n"); + iguana_exit(0,0); + } //printf("ptr.%p allocsize.%d key.%p keylen.%d itemind.%d\n",ptr,allocsize,key,keylen,itemind); ptr->hh.itemind = itemind; ptr->ipbits = ipbits; @@ -114,7 +130,7 @@ struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_ if ( iA == 0 || iA->ipbits == 0 ) { printf("null iA.%p or ipbits.%llx ind.%d status.%d\n",iA,iA!=0?(long long)iA->ipbits:0,iA!=0?iA->hh.itemind:0,iA!=0?iA->status:0); - exit(-1); + iguana_exit(0,0); return(0); } portable_mutex_lock(&coin->peers_mutex); @@ -189,7 +205,10 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana { ptr = mycalloc('t',1,sizeof(*ptr)); if ( ptr == 0 ) - printf("fatal alloc errorB in hashset\n"), exit(-1); + { + printf("fatal alloc errorB in hashset\n"); + iguana_exit(0,0); + } ptr->hh.itemind = m; ptr->ipbits = tmp.ipbits; HASH_ADD(hh,coin->iAddrs,ipbits,sizeof(ipbits),ptr); @@ -316,7 +335,7 @@ void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t mar return; if ( addr->ipbits == 0 ) { - printf("cant iAkill null ipbits\n"); + //printf("cant iAkill null ipbits\n"); return; } rank = addr->rank; @@ -351,20 +370,74 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) struct sockaddr_in saddr; socklen_t addrlen,slen; addrlen = sizeof(saddr); struct hostent *hostent; + + /** + * gethostbyname() is deprecated and cause crash on x64 windows + * the solution is to implement similar functionality by using getaddrinfo() + * it is standard posix function and is correctly supported in win32/win64/linux + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + struct addrinfo *addrresult = NULL; + struct addrinfo *returnptr = NULL; + struct addrinfo hints; + struct sockaddr_in * sockaddr_ipv4; + int retVal; + int found = 0; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; +#endif + if ( parse_ipaddr(ipaddr,hostname) != 0 ) port = parse_ipaddr(ipaddr,hostname); + +#if defined(_M_X64) + retVal = getaddrinfo(ipaddr, NULL, &hints, &addrresult); + for (returnptr = addrresult; returnptr != NULL && found == 0; returnptr = returnptr->ai_next) { + switch (returnptr->ai_family) { + case AF_INET: + sockaddr_ipv4 = (struct sockaddr_in *) returnptr->ai_addr; + // we want to break from the loop after founding the first ipv4 address + found = 1; + break; + } + } + + // if we iterate through the loop and didn't find anything, + // that means we failed in the dns lookup + if (found == 0) { + printf("getaddrinfo(%s) returned error\n", hostname); + freeaddrinfo(addrresult); + return(-1); + } +#else hostent = gethostbyname(ipaddr); if ( hostent == NULL ) { printf("gethostbyname(%s) returned error: %d port.%d ipaddr.(%s)\n",hostname,errno,port,ipaddr); return(-1); } +#endif saddr.sin_family = AF_INET; saddr.sin_port = htons(port); + //#ifdef WIN32 + // saddr.sin_addr.s_addr = (uint32_t)calc_ipbits("127.0.0.1"); + //#else + +#if defined(_M_X64) + saddr.sin_addr.s_addr = sockaddr_ipv4->sin_addr.s_addr; + // graceful cleanup + sockaddr_ipv4 = NULL; + freeaddrinfo(addrresult); +#else memcpy(&saddr.sin_addr.s_addr,hostent->h_addr_list[0],hostent->h_length); +#endif expand_ipbits(checkipaddr,saddr.sin_addr.s_addr); if ( strcmp(ipaddr,checkipaddr) != 0 ) printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)?\n",bindflag,checkipaddr,ipaddr); + //#endif if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) { if ( errno != ETIMEDOUT ) @@ -374,24 +447,24 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) opt = 1; slen = sizeof(opt); //printf("set keepalive.%d\n",setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,slen)); +#ifndef WIN32 if ( 1 )//&& bindflag != 0 ) { - if ( 1 ) - { - timeout.tv_sec = 0; - timeout.tv_usec = 30000; - setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); - } opt = 0; getsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,&slen); opt = 1; //printf("keepalive.%d\n",opt); - } else setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)); + } + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)); #ifdef __APPLE__ setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); +#endif #endif if ( bindflag == 0 ) { + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); result = connect(sock,(struct sockaddr *)&saddr,addrlen); if ( result != 0 ) { @@ -403,6 +476,9 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) closesocket(sock); return(-1); } + timeout.tv_sec = 10000000; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); } else { @@ -412,6 +488,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) { sleep(1); printf("ERROR BINDING PORT.%d. this is normal tcp timeout, unless another process is using port\n",port); + fflush(stdout); sleep(3); printf("%s(%s) port.%d try again: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); if ( bindflag == 1 ) @@ -421,7 +498,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) } sleep(13); //continue; - } + } if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) { printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); @@ -437,6 +514,14 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) return(-1); } } +#ifdef __APPLE__ + //timeout.tv_sec = 0; + //timeout.tv_usec = 30000; + //setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(void *)&timeout,sizeof(timeout)); +#endif return(sock); } @@ -472,6 +557,7 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s //printf("skip.(%s) since no verack yet\n",cmdstr); return(-1); } + //printf("%s -> %s\n",cmdstr,addr->ipaddr); if ( strcmp(cmdstr,"ping") == 0 ) addr->sendmillis = OS_milliseconds(); if ( len > IGUANA_MAXPACKETSIZE ) @@ -483,28 +569,34 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s #ifdef _WIN32 if ( (numsent= (int32_t)send(usock,serialized,remains,0)) < 0 ) #else - if ( (numsent= (int32_t)send(usock,serialized,remains,MSG_NOSIGNAL)) < 0 ) + if ( (numsent= (int32_t)send(usock,serialized,remains,MSG_NOSIGNAL)) < 0 ) #endif - { - printf("send errno.%d %s\n",errno,strerror(errno)); - if ( errno != EAGAIN && errno != EWOULDBLOCK ) { - printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",serialized+4,addr->ipaddr,numsent,remains,len,errno,strerror(errno),addr->usock); - printf("bad errno.%d %s zombify.%p\n",errno,strerror(errno),&addr->dead); - addr->dead = (uint32_t)time(NULL); - return(-errno); - } //else usleep(*sleeptimep), *sleeptimep *= 1.1; - } - else if ( remains > 0 ) - { - remains -= numsent; - serialized += numsent; - if ( remains > 0 ) - printf("%s iguana sent.%d remains.%d of len.%d\n",addr->ipaddr,numsent,remains,len); - } + if ( errno == EAGAIN || errno == EWOULDBLOCK ) + { + //addr->persistent_peer = 1; + sleep(1); + continue; + } + //if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",serialized+4,addr->ipaddr,numsent,remains,len,errno,strerror(errno),addr->usock); + printf("bad errno.%d %s zombify.%p\n",errno,strerror(errno),&addr->dead); + addr->dead = (uint32_t)time(NULL); + return(-errno); + } + } + else if ( remains > 0 ) + { + remains -= numsent; + serialized += numsent; + if ( remains > 0 ) + printf("%s iguana sent.%d remains.%d of len.%d\n",addr->ipaddr,numsent,remains,len); + } } addr->totalsent += len; - //printf(" (%s) sent.%d bytes to %s\n",cmdstr,len,addr->ipaddr);// getchar(); + if ( (0) && addr->basilisk != 0 ) + printf("verack.%d (%s) sent.%d bytes to %s\n",addr->msgcounts.verack,cmdstr,len,addr->ipaddr); return(len); } @@ -514,7 +606,7 @@ int32_t iguana_queue_send(struct iguana_peer *addr,int32_t delay,uint8_t *serial if ( addr == 0 ) { printf("iguana_queue_send null addr\n"); - exit(-1); + iguana_exit(0,0); return(-1); } if ( (datalen= iguana_sethdr((void *)serialized,addr->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len)) < 0 ) @@ -532,8 +624,9 @@ int32_t iguana_queue_send(struct iguana_peer *addr,int32_t delay,uint8_t *serial packet->embargo.millis += delay; } memcpy(packet->serialized,serialized,datalen); - //printf("%p queue send.(%s) %d to (%s)\n",packet,serialized+4,datalen,addr->ipaddr); - queue_enqueue("sendQ",&addr->sendQ,&packet->DL,0); + if ( (0) && addr->supernet != 0 ) + printf("%p queue send.(%s) %d to (%s)\n",packet,serialized+4,datalen,addr->ipaddr); + queue_enqueue("sendQ",&addr->sendQ,&packet->DL); return(datalen); } @@ -566,23 +659,29 @@ int32_t iguana_recv(char *ipaddr,int32_t usock,uint8_t *recvbuf,int32_t len) return(len); } -void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len,int32_t fromcache) +void iguana_peer_meminit(struct iguana_info *coin,struct iguana_peer *addr) +{ + if ( addr->RAWMEM.ptr == 0 ) + iguana_meminit(&addr->RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE * 3,0); + if ( addr->TXDATA.ptr == 0 ) + iguana_meminit(&addr->TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE * 3,0); + if ( addr->HASHMEM.ptr == 0 ) + iguana_meminit(&addr->HASHMEM,"HASHPTRS",0,256,0);//IGUANA_MAXPACKETSIZE*16,0); + //printf("Init %s memory %p %p %p\n",addr->ipaddr,addr->RAWMEM.ptr,addr->TXDATA.ptr,addr->HASHMEM.ptr); + iguana_memreset(&addr->RAWMEM); + iguana_memreset(&addr->TXDATA); + iguana_memreset(&addr->HASHMEM); +} + +void iguana_parsebuf(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len,int32_t fromcache) { struct iguana_msghdr checkH; memset(&checkH,0,sizeof(checkH)); if ( iguana_sethdr(&checkH,coin->chain->netmagic,H->command,buf,len) > 0 && memcmp(&checkH,H,sizeof(checkH)) == 0 ) { if ( strcmp(H->command,"block") == 0 || strcmp(H->command,"getblocks") == 0 || strcmp(H->command,"tx") == 0 ) - { - if ( addr->RAWMEM.ptr == 0 ) - iguana_meminit(&addr->RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE * 2,0); - if ( addr->TXDATA.ptr == 0 ) - iguana_meminit(&addr->TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE * 2,0); - if ( addr->HASHMEM.ptr == 0 ) - iguana_meminit(&addr->HASHMEM,"HASHPTRS",0,256,0);//IGUANA_MAXPACKETSIZE*16,0); - //printf("Init %s memory %p %p %p\n",addr->ipaddr,addr->RAWMEM.ptr,addr->TXDATA.ptr,addr->HASHMEM.ptr); - } - if ( iguana_msgparser(coin,addr,&addr->RAWMEM,&addr->TXDATA,&addr->HASHMEM,H,buf,len,fromcache) < 0 || addr->dead != 0 ) + iguana_peer_meminit(coin,addr); + if ( iguana_msgparser(myinfo,coin,addr,&addr->RAWMEM,&addr->TXDATA,&addr->HASHMEM,H,buf,len,fromcache) < 0 || addr->dead != 0 ) { printf("%p addr->dead.%d or parser break at %u\n",&addr->dead,addr->dead,(uint32_t)time(NULL)); addr->dead = (uint32_t)time(NULL); @@ -604,7 +703,7 @@ void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct ig } } -void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_peer *addr,uint8_t *_buf,int32_t maxlen) +void _iguana_processmsg(struct supernet_info *myinfo,struct iguana_info *coin,int32_t usock,struct iguana_peer *addr,uint8_t *_buf,int32_t maxlen) { int32_t len,recvlen; void *buf = _buf; struct iguana_msghdr H; if ( (coin->peers != 0 && coin->peers->shuttingdown != 0) || addr->dead != 0 ) @@ -634,11 +733,15 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee printf("%s recv error on (%s) len.%d errno.%d (%s)\n",addr->ipaddr,H.command,len,-recvlen,strerror(-recvlen)); if ( buf != _buf ) myfree(buf,len); - //addr->dead = (uint32_t)time(NULL); + if ( addr->numrecverrs++ > 10 ) + { + addr->dead = (uint32_t)time(NULL); + addr->numrecverrs = 0; + } return; } } - iguana_parsebuf(coin,addr,&H,buf,len,0); + iguana_parsebuf(myinfo,coin,addr,&H,buf,len,0); if ( buf != _buf ) myfree(buf,len); return; @@ -652,7 +755,7 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee } //addr->dead = 1; } - // printf("%s recv error on hdr errno.%d (%s) -> zombify\n",addr->ipaddr,-recvlen,strerror(-recvlen)); + // printf("%s recv error on hdr errno.%d (%s) -> zombify\n",addr->ipaddr,-recvlen,strerror(-recvlen)); #ifndef IGUANA_DEDICATED_THREADS addr->dead = 1; #endif @@ -695,7 +798,7 @@ void iguana_startconnection(void *arg) addr->addrind = (int32_t)(((long)addr - (long)&coin->peers->active[0]) / sizeof(*addr)); if ( addr->usock >= 0 ) { - printf("%s usock.%d skip connection\n",addr->ipaddr,addr->usock); + //printf("%s usock.%d skip connection\n",addr->ipaddr,addr->usock); return; } if ( strcmp(coin->name,addr->coinname) != 0 ) @@ -703,12 +806,6 @@ void iguana_startconnection(void *arg) printf("iguana_startconnection.%s:%04x mismatched coin.%p (%s) vs (%s)\n",addr->ipaddr,coin->chain->portp2p,coin,coin->symbol,addr->coinname); return; } - if ( strcmp("85.25.217.233",addr->ipaddr) == 0 ) - { - printf("temp blacklist %s\n",addr->ipaddr); - iguana_iAkill(coin,addr,1); - return; - } //printf("%s iguana_startconnection.%s:%04x\n",coin->symbol,addr->ipaddr,coin->chain->portp2p); if ( strcmp("127.0.0.1",addr->ipaddr) == 0 )//&& (coin->myservices & NODE_NETWORK) != 0 ) { @@ -716,7 +813,7 @@ void iguana_startconnection(void *arg) printf("avoid self-loopback\n"); return; } - //printf("startconnection.(%s) pending.%u usock.%d addrind.%d\n",addr->ipaddr,addr->pending,addr->usock,addr->addrind); + //printf(">>>>>>>> %s startconnection.(%s) pending.%u usock.%d addrind.%d\n",coin->symbol,addr->ipaddr,addr->pending,addr->usock,addr->addrind); addr->pending = (uint32_t)time(NULL); if ( (port= (uint16_t)(addr->ipbits >> 32)) == 0 ) port = coin->chain->portp2p; @@ -824,16 +921,15 @@ void iguana_launchpeer(struct iguana_info *coin,char *ipaddr,int32_t forceflag) else printf("iguana_launchpeer skip %s\n",ipaddr); } -void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) +void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA,struct iguana_peer *addr) { - struct iguana_peer *addr = 0; if ( coin->virtualchain != 0 ) return(0); if ( iA != 0 && iA->ipbits != 0 && iguana_numthreads(coin,1 << IGUANA_CONNTHREAD) < IGUANA_MAXCONNTHREADS && iA->status == IGUANA_PEER_ELIGIBLE ) { //printf("%x\n",iA->ipbits); //portable_mutex_unlock(&coin->peers_mutex); - if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 ) + if ( addr != 0 || (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 ) { addr->ipbits = iA->ipbits; //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,(uint32_t)addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); @@ -860,10 +956,10 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) //else printf("connector null iA\n"); return(0); } - + uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) { - char checkaddr[64]; uint64_t ipbits; uint32_t now = (uint32_t)time(NULL); int32_t i,n; struct iguana_iAddr *iA; + char checkaddr[64],_ipaddr[64]; uint64_t ipbits; uint32_t now = (uint32_t)time(NULL); int32_t i,n; struct iguana_iAddr *iA; struct iguana_peer *addr; struct stritem *sitem; if ( coin->virtualchain != 0 || coin->peers == 0 ) return(0); if ( ipaddr != 0 && ipaddr[0] != 0 && coin->peers != 0 ) @@ -873,39 +969,35 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) for (i=n=0; ipeers->active[i].ipaddr) == 0 ) { - printf("%s possible peer.(%s) %x already there\n",coin->symbol,ipaddr,(uint32_t)coin->peers->active[i].ipbits); + //printf("%s possible peer.(%s) %x already there\n",coin->symbol,ipaddr,(uint32_t)coin->peers->active[i].ipbits); return(0); } //printf("%s Q possible.(%s)\n",coin->symbol,ipaddr); - queue_enqueue("possibleQ",&coin->possibleQ,queueitem(ipaddr),1); + queue_enqueue("possibleQ",&coin->possibleQ,queueitem(ipaddr)); return((uint32_t)time(NULL)); } else if ( iguana_pendingaccept(coin) != 0 ) return((uint32_t)time(NULL)); - else if ( (ipaddr= queue_dequeue(&coin->possibleQ,1)) == 0 ) + else if ( (sitem= queue_dequeue(&coin->possibleQ)) == 0 ) return((uint32_t)time(NULL)); + safecopy(_ipaddr,sitem->str,sizeof(_ipaddr)); + free(sitem); + ipaddr = _ipaddr; #ifdef IGUANA_DISABLEPEERS if ( strcmp(ipaddr,"127.0.0.1") != 0 ) - { - free_queueitem(ipaddr); return((uint32_t)time(NULL)); - } #endif ipbits = (uint32_t)calc_ipbits(ipaddr); - //printf("%s check possible peer.(%s)\n",coin->symbol,ipaddr); - if ( iguana_peerslot(coin,(uint32_t)ipbits,0) != 0 ) + if ( (addr= iguana_peerslot(coin,(uint32_t)ipbits,0)) == 0 ) return((uint32_t)time(NULL)); - for (i=n=0; ipeers->active[i].ipaddr) == 0 ) - { - //printf("(%s) already active\n",ipaddr); - free_queueitem(ipaddr); - return((uint32_t)time(NULL)); - } - else if ( coin->peers->active[i].ipaddr[0] != 0 ) - n++; - } + /*for (i=n=0; ipeers->active[i].ipaddr) == 0 ) + return((uint32_t)time(NULL)); + else if ( coin->peers->active[i].ipaddr[0] != 0 ) + n++; + }*/ + n = coin->peers->numranked; if ( n >= coin->MAXPEERS-(coin->MAXPEERS>>3)-1 || coin->peers->numranked >= coin->MAXPEERS ) return((uint32_t)time(NULL)); if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) @@ -916,6 +1008,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) ipaddr[i] = 0; break; } + //printf("%s check possible peer.(%s)\n",coin->symbol,ipaddr); if ( (ipbits= calc_ipbits(ipaddr)) != 0 ) { expand_ipbits(checkaddr,ipbits); @@ -931,14 +1024,13 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) iA->status = IGUANA_PEER_ELIGIBLE; if ( iguana_rwiAddrind(coin,1,iA,iA->hh.itemind) == 0 ) printf("error updating status for (%s) ind.%d\n",ipaddr,iA->hh.itemind); - iguana_iAddriterator(coin,iA); + iguana_iAddriterator(coin,iA,addr); } else printf("ignore.(%s) lastconnect.%u lastkilled.%u numconnects.%d\n",ipaddr,iA->lastconnect,iA->lastkilled,iA->numconnects); } else printf("skip.(%s) ind.%d status.%d\n",ipaddr,iA->hh.itemind,iA->status); } else printf("cant find (%s) which should have been created\n",ipaddr); } else printf("%s reject ipaddr.(%s) vs checkaddr.(%s)\n",coin->symbol,ipaddr,checkaddr); } } - free_queueitem(ipaddr); return((uint32_t)time(NULL)); } @@ -950,16 +1042,16 @@ void iguana_processmsg(void *ptr) printf("iguana_processmsg cant find addr.%p symbol.%s\n",addr,addr!=0?addr->symbol:0); return; } - _iguana_processmsg(coin,addr->usock,addr,buf,sizeof(buf)); + _iguana_processmsg(SuperNET_MYINFO(0),coin,addr->usock,addr,buf,sizeof(buf)); addr->startrecv = 0; } int32_t iguana_pollsendQ(struct iguana_info *coin,struct iguana_peer *addr) { struct iguana_packet *packet; - if ( (packet= queue_dequeue(&addr->sendQ,0)) != 0 ) + if ( (packet= queue_dequeue(&addr->sendQ)) != 0 ) { - if ( 0 && (addr->supernet != 0 || strcmp((char *)&packet->serialized[4],"SuperNET") == 0) ) + if ( (0) && (addr->supernet != 0 || strcmp((char *)&packet->serialized[4],"SuperNET") == 0) ) printf("%s: send.(%s).%d usock.%d dead.%u ready.%u supernet.%d\n",addr->ipaddr,packet->serialized+4,packet->datalen,addr->usock,addr->dead,addr->ready,addr->supernet); if ( strcmp((char *)&packet->serialized[4],"getdata") == 0 ) { @@ -975,13 +1067,13 @@ int32_t iguana_pollsendQ(struct iguana_info *coin,struct iguana_peer *addr) else { //printf("embargo.x %llu %f\n",(long long)packet->embargo.x,tai_diff(packet->embargo,tai_now())); - queue_enqueue("embargo",&addr->sendQ,&packet->DL,0); + queue_enqueue("embargo",&addr->sendQ,&packet->DL); } } return(0); } -int32_t iguana_pollrecv(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *buf,int32_t bufsize) +int32_t iguana_pollrecv(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint8_t *buf,int32_t bufsize) { #ifndef IGUANA_DEDICATED_THREADS strcpy(addr->symbol,coin->symbol); @@ -992,7 +1084,7 @@ int32_t iguana_pollrecv(struct iguana_info *coin,struct iguana_peer *addr,uint8_ } else #endif - _iguana_processmsg(coin,addr->usock,addr,buf,bufsize); + _iguana_processmsg(myinfo,coin,addr->usock,addr,buf,bufsize); return(1); } @@ -1076,7 +1168,7 @@ int64_t iguana_peerfree(struct iguana_info *coin,struct iguana_peer *addr,void * if ( iguana_memfree(mem,ptr,datalen) < 0 || (avail= iguana_peerallocated(coin,addr)) < 0 ) { printf("iguana_peerfree: corrupted mem avail.%lld ptr.%p %d\n",(long long)avail,ptr,datalen); - exit(-1); + iguana_exit(myinfo); } return(avail); } @@ -1116,6 +1208,7 @@ int32_t iguana_vinsfname(struct iguana_info *coin,int32_t roflag,char *fname,int if ( roflag != 0 ) sprintf(fname,"%s/ro/%s/purgeable/%04d.vins",coin->VALIDATEDIR,coin->symbol,slotid); else sprintf(fname,"%s/%s/%04d.vins",coin->VALIDATEDIR,coin->symbol,slotid); + OS_compatible_path(fname); return((int32_t)strlen(fname)); } @@ -1133,7 +1226,7 @@ int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,in printf("iguana_peerslotinit cant create.(%s)\n",fname); return(-1); } - if ( coin->MAXPEERS == 1 || coin->VALIDATENODE != 0 || coin->FULLNODE != 0 ) + if ( coin->MAXPEERS == 1 || coin->VALIDATENODE > 0 || coin->FULLNODE > 0 ) { iguana_vinsfname(coin,0,fname,addr->addrind); if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) @@ -1174,12 +1267,12 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin, iguana_memreset(mem[i]); } #endif - //addr->pubkey = GENESIS_PUBKEY; + //addr->pubkey = GENESIS_PUBKEY; ipbits = (uint32_t)addr->ipbits; vcalc_sha256(0,addr->iphash.bytes,(uint8_t *)&ipbits,sizeof(ipbits)); //char str[65]; printf("start dedicatedloop.%s addrind.%d %s\n",addr->ipaddr,addr->addrind,bits256_str(str,addr->iphash)); - addr->maxfilehash2 = IGUANA_MAXFILEITEMS; - bufsize = IGUANA_MAXPACKETSIZE; + //addr->maxfilehash2 = IGUANA_MAXFILEITEMS; + bufsize = IGUANA_MAXPACKETSIZE * 2; if ( addr->blockspace == 0 ) addr->blockspace = mycalloc('r',1,bufsize + 8192); buf = mycalloc('r',1,bufsize); @@ -1190,19 +1283,20 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin, } else { + sleep(1 + (rand() % 3)); + //printf("greeting send version myservices.%llu to (%s)\n",(long long)coin->myservices,addr->ipaddr); iguana_send_version(coin,addr,coin->myservices); - //printf("send version myservices.%llu to (%s)\n",(long long)coin->myservices,addr->ipaddr); } //sleep(1+(rand()%5)); run = 0; while ( addr->usock >= 0 && addr->dead == 0 && coin->peers->shuttingdown == 0 ) { - if ( (req= queue_dequeue(&coin->cacheQ,0)) != 0 ) + if ( (req= queue_dequeue(&coin->cacheQ)) != 0 ) { if ( req->datalen != 0 ) { //char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->zblock.RO.hash2)); - iguana_parsebuf(coin,addr,&req->H,req->serializeddata,req->recvlen,1); + iguana_parsebuf(myinfo,coin,addr,&req->H,req->serializeddata,req->recvlen,1); } else printf("CACHE error no datalen\n"); coin->cachefreed++; myfree(req,req->allocsize); @@ -1212,7 +1306,8 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin, memset(&fds,0,sizeof(fds)); fds.fd = addr->usock; fds.events |= (POLLOUT | POLLIN); - if ( poll(&fds,1,timeout) > 0 && (fds.revents & POLLOUT) != 0 ) + + if ( poll(&fds,1,timeout) > 0 && (fds.revents & POLLOUT) != 0 ) { flag += iguana_pollsendQ(coin,addr); if ( addr->dead != 0 ) @@ -1225,7 +1320,7 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin, { if ( (fds.revents & POLLIN) != 0 ) { - flag += iguana_pollrecv(coin,addr,buf,bufsize); + flag += iguana_pollrecv(myinfo,coin,addr,buf,bufsize); if ( addr->dead != 0 ) { printf("%s is dead\n",addr->ipaddr); @@ -1263,10 +1358,10 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin, if ( flag != 0 ) run = 0; /*else if ( 0 && addr->supernet != 0 && time(NULL) > lastping+SUPERNET_PINGGAP ) - { - iguana_send_supernet(addr,SUPERNET_GETPEERSTR,0); - lastping = (uint32_t)time(NULL); - }*/ + { + iguana_send_supernet(addr,SUPERNET_GETPEERSTR,0); + lastping = (uint32_t)time(NULL); + }*/ if ( addr->persistent_peer != 0 ) { if ( addr->usock < 0 || addr->dead != 0 ) @@ -1291,18 +1386,18 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin, } } //printf(">>>>>>>>>>>>>> finish %s dedicatedloop.%s\n",coin->symbol,addr->ipaddr); - if ( 0 ) + if ( (0) ) { if ( addr->vinsfp != 0 ) fclose(addr->vinsfp), addr->vinsfp = 0; if ( addr->voutsfp != 0 ) - fclose(addr->voutsfp), addr->voutsfp = 0; + fclose(addr->voutsfp), addr->voutsfp = 0; } iguana_iAkill(coin,addr,addr->dead != 0); myfree(buf,bufsize); - if ( addr->filehash2 != 0 ) - myfree(addr->filehash2,addr->maxfilehash2*sizeof(*addr->filehash2)), addr->filehash2 = 0; - if ( 0 ) + //if ( addr->filehash2 != 0 ) + // myfree(addr->filehash2,addr->maxfilehash2*sizeof(*addr->filehash2)), addr->filehash2 = 0; + if ( (0) ) { iguana_mempurge(&addr->RAWMEM); iguana_mempurge(&addr->TXDATA); diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index 19e9817f1..ab73a9502 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -52,8 +52,11 @@ struct iguana_kvitem *iguana_hashsetPT(struct iguana_ramchain *ramchain,int32_t printf("alloc.%d\n",allocsize); } if ( ptr == 0 ) - printf("fatal alloc errorC in hashset\n"), exit(-1); - if ( 0 && ramchain->expanded && selector == 'T' ) + { + printf("fatal alloc errorC in hashset\n"); + iguana_exit(0,0); + } + if ( (0) && ramchain->expanded && selector == 'T' ) printf("hashmem.%p selector.%c added.(%s) itemind.%x ptr.%p\n",ramchain->hashmem,selector,str,itemind,ptr); if ( selector == 'T' ) HASH_ADD_KEYPTR(hh,ramchain->txids,key,keylen,ptr); @@ -61,18 +64,22 @@ struct iguana_kvitem *iguana_hashsetPT(struct iguana_ramchain *ramchain,int32_t ptr->hh.itemind = itemind; //if ( strcmp(str,"0000000000000000000000000000000000000000000000000000000000000000") == 0 ) // printf("added null txid?\n"), getchar(); - if ( 0 && ramchain->expanded && selector == 'T' ) + if ( (0) && ramchain->expanded && selector == 'T' ) printf("selector.%c added.(%s) itemind.%x ptr.%p tmp.%p\n",selector,str,itemind,ptr,tmp); if ( itemind == 0 ) - printf("negative itemind\n"), exit(-1); - if ( 0 ) + { + printf("negative itemind\n"); + iguana_exit(0,0); + } + if ( (1) ) { if ( selector == 'T' ) HASH_FIND(hh,ramchain->txids,key,keylen,tmp); else HASH_FIND(hh,ramchain->pkhashes,key,keylen,tmp); if ( tmp != ptr ) { - printf("(%s) hashmem.%p selector.%c %s search error %p != %p itemind.%x\n",str,ramchain->hashmem,selector,str,ptr,tmp,itemind), exit(-1); + printf("(%s) hashmem.%p selector.%c %s search error %p != %p itemind.%x\n",str,ramchain->hashmem,selector,str,ptr,tmp,itemind); + iguana_exit(0,0); } } } @@ -81,7 +88,7 @@ struct iguana_kvitem *iguana_hashsetPT(struct iguana_ramchain *ramchain,int32_t void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain) { - if ( 0 && coin->virtualchain != 0 ) + if ( (0) && coin->virtualchain != 0 ) printf("iguana_blocksetcounters.%s 1st txidind.%u <- ht.%d\n",coin->symbol,ramchain->H.txidind,block->height); block->RO.firsttxidind = ramchain->H.txidind; block->RO.firstvout = ramchain->H.unspentind; @@ -103,11 +110,10 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, bp = 0, bundlei = -2; if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 ) { - if ( 0 && dispflag != 0 ) + if ( (0) && dispflag != 0 ) printf("iguana_peerfname %s error finding.(%s) spec.%p bp.%p\n",coin->symbol,bits256_str(str,hash2),bp!=0?bp->speculative:0,bp); return(-2); - } - else bundlei++; + } else bundlei++; } hash2 = bp->hashes[0], *hdrsip = bp->hdrsi; subdir = bp->bundleheight / IGUANA_SUBDIRDIVISOR; @@ -127,9 +133,9 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, { sprintf(fname,"%s/%s/%d",dirname,coin->symbol,subdir), OS_ensure_directory(fname); sprintf(fname,"%s/%s/%d/%s_%d.%u",dirname,coin->symbol,subdir,bits256_str(str,hash2),numblocks,ipbits>1?ipbits:*hdrsip); -//#ifndef __PNACL__ -// sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits>1?ipbits:*hdrsip); -//#endif + //#ifndef __PNACL__ + // sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits>1?ipbits:*hdrsip); + //#endif } //else sprintf(fname,"%s/%s.%u",dirname,bits256_str(str,hash2),bp->bundleheight); OS_compatible_path(fname); return(bundlei); @@ -163,6 +169,7 @@ int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr #define RAMCHAIN_DESTARG dest,destB,destT,destU,destS,destP,destA,destX,destUx,destSx,destTXbits,destPKbits,destKspace #define RAMCHAIN_DESTPTRS dest,&destB,&destT,&destU,&destS,&destP,&destA,&destX,&destUx,&destSx,&destTXbits,&destPKbits,&destKspace #define RAMCHAIN_DESTDECLARE struct iguana_blockRO *destB; struct iguana_txid *destT; struct iguana_unspent20 *destU; struct iguana_spend256 *destS; struct iguana_pkhash *destP; struct iguana_account *destA; bits256 *destX; struct iguana_unspent *destUx; struct iguana_spend *destSx; uint8_t *destTXbits,*destPKbits,*destKspace; +#define RAMCHAIN_DESTZEROES destB = 0, destUx = 0, destSx = 0, destP = 0, destA = 0, destX = 0, destKspace = destTXbits = destPKbits = 0, destU = 0, destS = 0, destT = 0 uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 txid,int32_t numvouts,int32_t numvins,uint32_t locktime,uint32_t version,uint32_t timestamp,int16_t bundlei) { @@ -177,14 +184,14 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 { if ( t->txidind != txidind || memcmp(t->txid.bytes,txid.bytes,sizeof(bits256)) != 0 || t->numvouts != numvouts || t->numvins != numvins || t->firstvout != ramchain->H.unspentind || t->firstvin != ramchain->H.spendind || t->locktime != locktime || t->version != version || t->timestamp != timestamp ) { - printf("iguana_ramchain_addtxid.RO: addtxid mismatch (%d %d %d %d %d) vs. (%d %d %d %d %d)\n",t->txidind,t->numvouts,t->numvins,t->firstvout,t->firstvin,txidind,numvouts,numvins,ramchain->H.unspentind,ramchain->H.spendind); + printf("iguana_ramchain_addtxid.RO: addtxid mismatch b.%d (%u %d %d %u %u) vs. (%d %d %d %d %d)\n",bundlei,(uint32_t)t->txidind,t->numvouts,t->numvins,(uint32_t)t->firstvout,(uint32_t)t->firstvin,txidind,numvouts,numvins,ramchain->H.unspentind,ramchain->H.spendind); //getchar(); return(0); } } else { - if ( 0 && ramchain->expanded != 0 ) + if ( (0) && ramchain->expanded != 0 ) printf("T.%p txidind.%d numvouts.%d numvins.%d\n",T,txidind,numvouts,numvins); t->txidind = txidind, t->txid = txid, t->numvouts = numvouts, t->numvins = numvins; t->bundlei = bundlei; @@ -192,7 +199,7 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 t->locktime = locktime, t->version = version, t->timestamp = timestamp; if ( t->txidind != txidind || t->firstvout != ramchain->H.unspentind || t->firstvin != ramchain->H.spendind || t->bundlei != bundlei ) { - printf("addtxid error: t->txidind %u != %u txidind || t->firstvout %u != %u ramchain->H.unspentind || t->firstvin %u != %u ramchain->H.spendind || t->bundlei %u != %u bundlei\n",t->txidind,txidind,t->firstvout,ramchain->H.unspentind,t->firstvin,ramchain->H.spendind,t->bundlei,bundlei); + printf("addtxid error: t->txidind %u != %u txidind || t->firstvout %u != %u ramchain->H.unspentind || t->firstvin %u != %u ramchain->H.spendind || t->bundlei %u != %u bundlei\n",(uint32_t)t->txidind,txidind,(uint32_t)t->firstvout,ramchain->H.unspentind,(uint32_t)t->firstvin,ramchain->H.spendind,(uint32_t)t->bundlei,bundlei); return(0); } if ( ramchain->expanded != 0 && (rdata= ramchain->H.data) != 0 ) @@ -225,7 +232,7 @@ uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_ if ( P[pkind].pkind != pkind ) //unspentind != 0 && (P[pkind].firstunspentind != unspentind || { printf("iguana_ramchain_addpkhash error mismatched pkind.(%x %x) unspentind.%d\n",pkind,P[pkind].pkind,unspentind); - exit(-1); + iguana_exit(0,0); return(0); } if ( memcmp(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)) != 0 ) @@ -247,11 +254,13 @@ uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_ pkind = ramchain->pkind++; P[pkind].pkind = pkind; /*if ( P[pkind].firstunspentind == 0 && unspentind != 0 ) - { - P[pkind].firstunspentind = unspentind; - printf("%p P[%d] <- firstunspent.%d\n",&P[pkind],pkind,unspentind); - }*/ - memcpy(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)); + { + P[pkind].firstunspentind = unspentind; + printf("%p P[%d] <- firstunspent.%d\n",&P[pkind],pkind,unspentind); + }*/ + //memcpy(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)); + for (i=0; i<20; i++) + P[pkind].rmd160[i] = rmd160[i]; //for (i=0; i<20; i++) // printf("%02x",rmd160[i]); //printf(" -> rmd160 pkind.%d \n",pkind); @@ -269,7 +278,7 @@ uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_peer *addr,RAMCHAIN_FUNC,uint64_t value,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,int8_t type,struct iguana_bundle *bp,uint8_t rmd160[20]) { - uint32_t unspentind; struct iguana_unspent20 *u; long scriptpos; struct vin_info V; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; + uint32_t unspentind,i; struct iguana_unspent20 *u; long scriptpos; struct vin_info V; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; unspentind = ramchain->H.unspentind++; u = &U[unspentind]; if ( scriptlen > 0 ) @@ -280,14 +289,16 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee type = iguana_calcrmd160(coin,asmstr,&V,script,scriptlen,txid,vout,0xffffffff); if ( (type == 12 && scriptlen == 0) || (type == 1 && bitcoin_pubkeylen(script+1) <= 0) ) { - int32_t i; for (i=0; iH.ROflag != 0 ) @@ -302,7 +313,9 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee { u->value = value; u->type = type; - memcpy(u->rmd160,rmd160,sizeof(u->rmd160)); + //memcpy(u->rmd160,rmd160,sizeof(u->rmd160)); + for (i=0; i<20; i++) + u->rmd160[i] = rmd160[i]; if ( type == IGUANA_SCRIPT_76AC ) { static uint64_t totalsize; @@ -332,7 +345,15 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee fputc(0,addr->voutsfp), u->scriptpos++, scriptpos++; if ( u->scriptpos != scriptpos || fwrite(script,1,scriptlen,addr->voutsfp) != scriptlen ) printf("error writing vout scriptlen.%d errno.%d or scriptpos.%lld != %u\n",scriptlen,errno,(long long)scriptpos,u->scriptpos); - else addr->dirty[0]++; + else + { + fflush(addr->voutsfp); + if ( coin->chain->fixit != 0 ) + { + usleep(1000); + } + addr->dirty[0]++; + } #ifdef __PNACL__ //portable_mutex_unlock(&mutex); #endif @@ -341,14 +362,14 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee } } u->txidind = ramchain->H.txidind; - if ( 0 && vout > 0 ) + if ( coin->chain->fixit != 0 && vout > 0 ) { int32_t i; for (i=0; i<20; i++) printf("%02x",rmd160[i]); printf(" rmd160 "); for (i=0; i<20; i++) printf("%02x",u->rmd160[i]); - char str[65]; printf(" u->rmd160 type.%d scriptlen.%d:%d (%s).v%d ht.%d\n",u->type,scriptlen,u->scriptlen,bits256_str(str,txid),vout,bp->bundleheight); + char str[65]; printf(" u->rmd160 type.%d scriptpos.%d scriptlen.%d:%d (%s).v%d ht.%d\n",u->type,u->scriptpos,scriptlen,u->scriptlen,bits256_str(str,txid),vout,bp->bundleheight); } } return(unspentind); @@ -361,10 +382,10 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 if ( rmd160[i] != 0 ) break; /*if ( i == 20 && vout > 0 ) - { - printf("iguana_ramchain_addunspent: null rmd160 warning txi.%d vout.%d\n",txi,vout); - //return(0); - }*/ + { + printf("iguana_ramchain_addunspent: null rmd160 warning txi.%d vout.%d\n",txi,vout); + //return(0); + }*/ unspentind = ramchain->H.unspentind++; u = &Ux[unspentind]; if ( (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) @@ -378,17 +399,17 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 if ( ramchain->H.ROflag != 0 ) { /*if ( Kspace != 0 && ((u->scriptoffset != 0 && scriptlen > 0) || type == IGUANA_SCRIPT_76AC) ) - { - checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspace,u->type,_script,u->scriptoffset,P[pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[pkind].pubkeyoffset : 0); - if ( checklen != scriptlen || (script != 0 && checkscript != 0 && memcmp(checkscript,script,scriptlen) != 0) ) - { - printf("script mismatch len.%d vs %d or cmp error.%d\n",scriptlen,checklen,(checkscript != 0 && script != 0) ? memcmp(checkscript,script,scriptlen):0); - } //else printf("RO spendscript match.%d\n",scriptlen); - }*/ + { + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspace,u->type,_script,u->scriptoffset,P[pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[pkind].pubkeyoffset : 0); + if ( checklen != scriptlen || (script != 0 && checkscript != 0 && memcmp(checkscript,script,scriptlen) != 0) ) + { + printf("script mismatch len.%d vs %d or cmp error.%d\n",scriptlen,checklen,(checkscript != 0 && script != 0) ? memcmp(checkscript,script,scriptlen):0); + } //else printf("RO spendscript match.%d\n",scriptlen); + }*/ if ( u->fileid != fileid || u->scriptpos != fpos || u->scriptlen != scriptlen || u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastunspentind) || u->vout != vout || u->hdrsi != hdrsi ) { printf("iguana_ramchain_addunspent: (%d %d %d) vs (%d %d %d) mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->fileid,u->scriptpos,u->scriptlen,fileid,fpos,scriptlen,u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastunspentind,vout,hdrsi); - exit(-1); + iguana_exit(0,0); return(0); } } @@ -449,8 +470,8 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 { external = 1; txidind = ramchain->externalind++; - if ( 0 && ramchain->expanded != 0 ) - { char str[65]; printf("%p X[%d] <- %s\n",X,txidind,bits256_str(str,prev_hash)); } + if ( (0) && ramchain->expanded != 0 ) + { char str[65]; printf("%p X[%d] <- %s\n",X,txidind,bits256_str(str,prev_hash)); } if ( ramchain->H.ROflag != 0 ) { if ( memcmp(X[txidind].bytes,prev_hash.bytes,sizeof(prev_hash)) != 0 ) @@ -483,7 +504,12 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 return(0); } } else printf("addspend illegal unspentind.%d vs %d\n",unspentind,rdata->numunspents); - } else printf("addspend illegal txidind.%d vs %d\n",txidind,rdata->numtxids), exit(-1); + } + else + { + printf("addspend illegal txidind.%d vs %d\n",txidind,rdata->numtxids); + iguana_exit(0,0); + } } if ( ramchain->H.ROflag != 0 ) { @@ -493,21 +519,6 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 char str[65],str2[65]; printf("ramchain_addspend RO value mismatch diffseq.%x v %x (%d) vs (%d) %s vs %s\n",s->sequenceid,sequence,s->prevout,prev_vout,bits256_str(str,txid),bits256_str(str2,prev_hash)); return(0); } - /*if ( (checklen= iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[rdata->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) ) - { - static uint64_t counter; - if ( counter++ < 100 ) - { - for (i=0; iH.scriptoffset += metalen; } else { @@ -517,36 +528,6 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 s->fileid = fileid; s->scriptpos = scriptpos; s->scriptlen = vinscriptlen; - /*static uint64_t good,bad; - if ( 0 && iguana_metascript(coin,RAMCHAIN_ARG,s,vinscript,vinscriptlen,0) < 0 ) - { - static long errlen,err2len; char errbuf[1024]; - errlen += vinscriptlen; - if ( iguana_metascript(coin,RAMCHAIN_ARG,s,vinscript,vinscriptlen,1) < 0 ) - { - err2len += vinscriptlen; - errbuf[0] = 0; - for (i=0; i 138 ) - { - errbuf[0] = 0; - for (i=0; ihdrsi = hdrsi; - //s->bundlei = bundlei; - //char str[65]; printf("%s set prevout.%d -> %d\n",bits256_str(str,prev_hash),prev_vout,s->prevout); - //if ( pkind != 0 ) - // s->prevspendind = A[pkind].lastspendind; } if ( pkind != 0 ) { @@ -567,7 +548,7 @@ uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer { if ( vinscriptlen != s->vinscriptlen || s->sequenceid != sequence || memcmp(s->prevhash2.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout ) //|| s->hdrsi != hdrsi { - char str[65],str2[65]; printf("check offset %llu (%d %d) addspend.%d v %d RO value mismatch sequenceid.%x seq.%x prev_vout(%d vs %d) %s vs %s\n",(long long)s->scriptpos,vinscriptlen,s->vinscriptlen,spendind,s->spendind,s->sequenceid,sequence,s->prevout,prev_vout,bits256_str(str,s->prevhash2),bits256_str(str2,prev_hash)); + char str[65],str2[65]; printf("check offset %llu (%d %d) addspend.%d v %d RO value mismatch sequenceid.%x seq.%x prev_vout(%d vs %d) %s vs %s\n",(long long)s->scriptpos,vinscriptlen,(int32_t)s->vinscriptlen,spendind,s->spendind,s->sequenceid,sequence,s->prevout,prev_vout,bits256_str(str,s->prevhash2),bits256_str(str2,prev_hash)); //printf("check addspend.%d vs %d RO value mismatch (%d %d:%d) vs (%d %d:%d)\n",spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei,prev_vout,hdrsi,bundlei); //exit(-1); return(0); @@ -590,15 +571,23 @@ uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer fputc(0,addr->vinsfp), s->scriptpos++; if ( (err= (int32_t)fwrite(vinscript,1,vinscriptlen,addr->vinsfp)) != vinscriptlen ) printf("error.%d writing vinscriptlen.%d errno.%d addrind.%d\n",err,vinscriptlen,errno,addr->addrind); - else addr->dirty[1]++; + else + { + addr->dirty[1]++; + fflush(addr->vinsfp); + if ( coin->chain->fixit != 0 ) + { + usleep(1000); + } + } #ifdef __PNACL__ //portable_mutex_unlock(&mutex); #endif } else s->scriptpos = 0; //else printf("spend256 scriptfpos.%d\n",s->scriptfpos); char str[65]; - if ( 0 && coin->virtualchain != 0 ) - printf("W.%p s.%d vout.%d/%d [%d] %s fpos.%u slen.%d\n",s,spendind,s->prevout,prev_vout,bp->hdrsi,bits256_str(str,prev_hash),(uint32_t)s->scriptpos,s->vinscriptlen); + if ( (0) && coin->virtualchain != 0 ) + printf("W.%p s.%d vout.%d/%d [%d] %s fpos.%u slen.%d\n",s,spendind,s->prevout,prev_vout,bp->hdrsi,bits256_str(str,prev_hash),(uint32_t)s->scriptpos,(int32_t)s->vinscriptlen); } return(spendind); } @@ -689,6 +678,7 @@ void *iguana_ramchain_offset(char *fname,void *dest,uint8_t *lhash,FILE *fp,uint #endif startfpos = ftell(fp); err = fwrite(srcptr,1,len,fp); + fflush(fp); #ifdef __PNACL__ //portable_mutex_unlock(&mutex); #endif @@ -709,8 +699,8 @@ void *iguana_ramchain_offset(char *fname,void *dest,uint8_t *lhash,FILE *fp,uint int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t flag) { RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; - struct iguana_pkhash p; struct iguana_unspent u; struct iguana_txid txid; uint32_t i,numpkinds,numtxids,numunspents,numexternal,tlen,plen,nonz=0; uint8_t *ptr; struct iguana_ramchaindata *rdata; -//return(0); + struct iguana_pkhash p; struct iguana_unspent u; struct iguana_txid txid; uint32_t i,j,numpkinds,numtxids,numunspents,numexternal,tlen,plen,nonz=0; uint8_t *ptr; struct iguana_ramchaindata *rdata; + //return(0); if ( (rdata= ramchain->H.data) != 0 ) { //printf("start PREFETCH.[%d] flag.%d -> nonz.%d\n",rdata->height,flag,nonz); @@ -732,16 +722,18 @@ int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain tlen = (rdata->numtxsparse * rdata->txsparsebits) >> 3; for (i=0; i %s\n",&X[1],bits256_str(str,X[1])); X = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_EXTERNALS),fparg,fpos,X,&offset,(sizeof(bits256) * numexternaltxids),srcsize); TXbits = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_TXBITS),fparg,fpos,TXbits,&offset,hconv_bitlen(txbits),srcsize); @@ -839,7 +831,7 @@ int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHAS { Ux = destptr, Sx = destptr, P = destptr, A = destptr, X = destptr, TXbits = destptr, PKbits = destptr, Kspace = destptr; //U2 = destptr, P2 = destptr, U = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_UNSPENTS),fparg,fpos,U,&offset,(sizeof(struct iguana_unspent20) * numunspents),srcsize); - if ( 0 && lhashes != 0 ) + if ( (0) && lhashes != 0 ) printf("iter.%d lhashes.%p offset.%ld destptr.%p len.%ld fparg.%p fpos.%ld srcsize.%ld\n",iter,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),(long)offset,destptr,(long)sizeof(struct iguana_spend256) * numspends,fparg,(long)fpos,(long)srcsize); S = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),fparg,fpos,S,&offset,(sizeof(struct iguana_spend256) * numspends),srcsize); } @@ -887,7 +879,7 @@ int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHAS int64_t iguana_ramchain_action(char *fname,RAMCHAIN_FUNC,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],struct iguana_ramchaindata *destdata,uint64_t fpos,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace,uint8_t zcash) { - if ( 0 && ramchain->expanded == 0 ) + if ( (0) && ramchain->expanded == 0 ) printf("action.%p (%p %p %p) %ld allocated.%ld [%d:%d %d:%d]\n",srcdata,fp,lhashes,destdata,(long)fpos,(long)srcdata->allocsize,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse); return(_iguana_rdata_action(fname,fp,lhashes,destdata,fpos,ramchain->expanded,srcdata->numtxids,srcdata->numunspents,srcdata->numspends,srcdata->numpkinds,srcdata->numexternaltxids,scriptspace,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse,srcdata->allocsize,RAMCHAIN_ARG,numblocks,zcash)); } @@ -898,7 +890,7 @@ int64_t iguana_ramchain_size(char *fname,RAMCHAIN_FUNC,int32_t numblocks,int32_t if ( (rdata= ramchain->H.data) != 0 ) { allocsize = iguana_ramchain_action(fname,RAMCHAIN_ARG,0,0,0,0,rdata,numblocks,scriptspace,zcash); - if ( 0 && ramchain->expanded != 0 ) + if ( (0) && ramchain->expanded != 0 ) printf("%p iguana_ramchain_size.expanded.%d %u: Koffset.%u scriptoffset.%u stacksize.%u stackspace.%u [%u]\n",ramchain,ramchain->expanded,(int32_t)allocsize,(int32_t)rdata->Koffset,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)rdata->stackspace,scriptspace); } return(allocsize); @@ -918,7 +910,7 @@ long iguana_ramchain_setsize(char *fname,struct iguana_ramchain *ramchain,struct rdata->scriptspace = ramchain->H.scriptoffset; rdata->stackspace = ramchain->H.stacksize; rdata->allocsize = iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,rdata->scriptspace,zcash); - if ( 0 && rdata->scriptspace != 0 ) + if ( (0) && rdata->scriptspace != 0 ) printf("iguana_ramchain_setsize: Koffset.%d scriptspace.%d stackspace.%d (scriptoffset.%d stacksize.%d) allocsize.%d\n",(int32_t)rdata->Koffset,(int32_t)rdata->scriptspace,(int32_t)rdata->stackspace,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)rdata->allocsize); ramchain->datasize = rdata->allocsize; return((long)rdata->allocsize); @@ -945,7 +937,7 @@ int64_t iguana_ramchain_saveaction(char *fname,RAMCHAIN_FUNC,FILE *fp,struct igu before = ftell(fp); iguana_ramchain_action(fname,RAMCHAIN_ARG,fp,0,rdata,0,rdata,numblocks,scriptspace,zcash); after = ftell(fp); - if ( 0 && ramchain->expanded == 0 ) + if ( (0) && ramchain->expanded == 0 ) { int32_t i; for (i=0; iallocsize; - if ( 0 && expanded != 0 ) + if ( (0) && expanded != 0 ) printf("init T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)offset); if ( rdata->allocsize != iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace,zcash) ) { printf("offset.%ld scriptspace.%d allocsize.%ld vs memsize.%ld\n",(long)offset,scriptspace,(long)rdata->allocsize,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace,zcash)); - exit(-1); + iguana_exit(0,0); } if ( offset <= mem->totalsize ) iguana_memreset(mem); @@ -1001,7 +993,7 @@ int64_t iguana_ramchain_init(char *fname,struct iguana_ramchain *ramchain,struct if ( rdata->allocsize > mem->totalsize ) { printf("init.(%d %d %d %d %d) rdata->allocsize.%ld mem->totalsize.%ld hashmemsize.%ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)rdata->allocsize,mem->totalsize,hashmem!=0?hashmem->totalsize:0); - exit(-1); + iguana_exit(0,0); } return(offset); } @@ -1013,17 +1005,17 @@ int32_t iguana_ramchain_alloc(char *fname,struct iguana_info *coin,struct iguana memset(ramchain,0,sizeof(*ramchain)); ramchain->height = height; allocsize = _iguana_rdata_action(fname,0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks,zcash); - if ( 0 && ramchain->expanded != 0 ) + if ( (0) && ramchain->expanded != 0 ) printf("T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)allocsize); memset(mem,0,sizeof(*mem)); memset(hashmem,0,sizeof(*hashmem)); hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace); - while ( 0 && (x= (myallocated(0,-1)+hashsize+allocsize + 65536)) > coin->MAXMEM ) + while ( (0) && (x= (myallocated(0,-1)+hashsize+allocsize + 65536)) > coin->MAXMEM ) { char str[65],str2[65]; fprintf(stderr,"ht.%d wait for allocated %s < MAXMEM %s | elapsed %.2f minutes hashsize.%ld allocsize.%ld\n",height,mbstr(str,myallocated(0,-1)+hashsize+allocsize),mbstr(str2,coin->MAXMEM),(double)(time(NULL)-coin->startutc)/60.,(long)hashsize,(long)allocsize); sleep(13); } - iguana_meminit(hashmem,"ramhashmem",0,hashsize + 65536,0); + iguana_meminit(hashmem,"ramhashmem",0,2*hashsize + 65536,0); iguana_meminit(mem,"ramchain",0,allocsize + 65536,0); mem->alignflag = sizeof(uint32_t); hashmem->alignflag = sizeof(uint32_t); @@ -1034,13 +1026,13 @@ int32_t iguana_ramchain_alloc(char *fname,struct iguana_info *coin,struct iguana long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,struct iguana_bundle *bp,uint8_t zcash) { - struct iguana_ramchaindata *rdata,tmp; char fname[1024]; long fpos = -1; int32_t hdrsi,checki; FILE *fp; + struct iguana_ramchaindata *rdata,tmp; char fname[1024]; long fpos = -1; int32_t hdrsi,checki = 0; FILE *fp; if ( (rdata= ramchain->H.data) == 0 ) { printf("ramchainsave no data ptr\n"); return(-1); } - if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?GLOBAL_DBDIR:GLOBAL_TMPDIR,fname,ipbits,hash2,prevhash2,ramchain->numblocks,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + if ( (bundlei >= 0 && (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?GLOBAL_DBDIR:GLOBAL_TMPDIR,fname,ipbits,hash2,prevhash2,ramchain->numblocks,1)) != bundlei) || bundlei >= coin->chain->bundlesize ) { printf(" wont save.(%s) bundlei.%d != checki.%d\n",fname,bundlei,checki); return(-1); @@ -1061,7 +1053,7 @@ long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits iguana_ramchain_lhashes(fname,RAMCHAIN_ARG,rdata,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset,zcash); tmp = *rdata; iguana_ramchain_compact(fname,RAMCHAIN_ARG,&tmp,rdata,bp!=0?bp->n:1,zcash); - if ( 0 && ramchain->expanded != 0 ) + if ( (0) && ramchain->expanded != 0 ) printf("compact.%s: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",fname,(int32_t)rdata->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)rdata->allocsize); if ( fwrite(&tmp,1,sizeof(tmp),fp) != sizeof(tmp) ) { @@ -1069,12 +1061,14 @@ long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits fpos = -1; } else iguana_ramchain_saveaction(fname,RAMCHAIN_ARG,fp,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset,zcash); *rdata = tmp; + fflush(fp); fclose(fp); + //sleep(3); } #ifdef __PNACL__ //portable_mutex_unlock(&mutex); #endif - return(fpos); + return(fpos); } int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain *ramchain) @@ -1092,18 +1086,18 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * t = &T[ramchain->H.txidind]; if ( t->txidind != ramchain->H.txidind ) { - printf("firsti.%d t->txidind.%d != txidind.%d\n",rdata->firsti,t->txidind,ramchain->H.txidind); + printf("firsti.%d t->txidind.%u != txidind.%u\n",rdata->firsti,(uint32_t)t->txidind,(uint32_t)ramchain->H.txidind); return(-1); } if ( t->firstvout != ramchain->H.unspentind ) { - printf("%p txidind.%d firstvout.%d != unspentind.%d\n",t,ramchain->H.txidind,t->firstvout,ramchain->H.unspentind); + printf("%p txidind.%u firstvout.%u != unspentind.%u\n",t,(uint32_t)ramchain->H.txidind,(uint32_t)t->firstvout,(uint32_t)ramchain->H.unspentind); //exit(-1); return(-4); } if ( t->firstvin != ramchain->H.spendind ) { - printf("t[%d] firstvin.%d vs spendind.%d\n",t->txidind,t->firstvin,ramchain->H.spendind); + printf("t[%u] firstvin.%u vs spendind.%d\n",(uint32_t)t->txidind,(uint32_t)t->firstvin,ramchain->H.spendind); return(-5); } if ( ramchain->expanded != 0 ) @@ -1115,7 +1109,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * if ( strcmp(coin->symbol,"BTC") == 0 ) { bits256 duptxid,duptxid2; - decode_hex(duptxid.bytes,sizeof(duptxid),"e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468"); // BTC.tx0: 91722, 91880 + decode_hex(duptxid.bytes,sizeof(duptxid),"e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468"); // BTC.tx0: 91722, 91880 decode_hex(duptxid2.bytes,sizeof(duptxid2),"d5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599"); // BTC.tx0 91812, 91842 if ( memcmp(duptxid.bytes,t->txid.bytes,sizeof(duptxid)) == 0 || memcmp(duptxid2.bytes,t->txid.bytes,sizeof(duptxid2)) == 0 ) printf("BIP 0 detected\n"); @@ -1132,7 +1126,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * return(-3); } } - for (k=0; knumvouts; k++,ramchain->H.unspentind++) + for (k=0; knumvouts; k++) { u = &Ux[ramchain->H.unspentind]; if ( u->txidind != ramchain->H.txidind ) @@ -1154,17 +1148,19 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * printf("%p itemind.%d pkind.%d %d unspentind?\n",p,ptr->hh.itemind,pkind,ramchain->H.unspentind); return(-9); } + ramchain->H.unspentind++; } } else { - for (k=0; knumvouts; k++,ramchain->H.unspentind++) + for (k=0; knumvouts; k++) { if ( U[ramchain->H.unspentind].txidind != ramchain->H.txidind ) { printf(" k.%d U.%d u->txidind.%x != txidind.%d\n",k,ramchain->H.unspentind,U[ramchain->H.unspentind].txidind,ramchain->H.txidind); return(-6); } + ramchain->H.unspentind++; } } ramchain->H.spendind += t->numvins; @@ -1173,7 +1169,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { t = &T[ramchain->H.txidind]; - for (k=0; knumvins; k++,ramchain->H.spendind++) + for (k=0; knumvins; k++) { if ( ramchain->expanded != 0 ) { @@ -1196,6 +1192,7 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * } } } + ramchain->H.spendind++; } } if ( ramchain->expanded != 0 && ramchain->A != ramchain->creditsA ) @@ -1220,14 +1217,14 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag) { struct iguana_kvitem *item,*tmp; struct iguana_ramchaindata *rdata; - if ( (rdata= ramchain->H.data) == 0 ) - return(-1); - if ( ramchain->H.ROflag != 0 && ramchain->hashmem == 0 ) + //if ( (rdata= ramchain->H.data) == 0 ) + // return(-1); + if ( (rdata= ramchain->H.data) != 0 && ramchain->H.ROflag != 0 && ramchain->hashmem == 0 ) { if ( ramchain->A != ramchain->creditsA ) { //printf("hashmem.%p Free A %p %p, numpkinds.%d %ld\n",ramchain->hashmem,ramchain->A,ramchain->creditsA,rdata->numpkinds,sizeof(*ramchain->A) * rdata->numpkinds); - if ( deleteflag != 0 ) + if ( deleteflag != 0 && ramchain->A != 0 ) myfree(ramchain->A,sizeof(*ramchain->A) * rdata->numpkinds), ramchain->A = 0; } //if ( ramchain->U2 != ramchain->roU2 ) @@ -1255,16 +1252,16 @@ int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ra myfree(item,sizeof(*item)); } } - if ( ramchain->txbits != 0 ) - { - free(ramchain->txbits); - ramchain->txbits = 0; - } - if ( ramchain->cacheT != 0 ) - { - free(ramchain->cacheT); - ramchain->cacheT = 0; - } + } + if ( ramchain->txbits != 0 ) + { + free(ramchain->txbits); + ramchain->txbits = 0; + } + if ( ramchain->cacheT != 0 ) + { + free(ramchain->cacheT); + ramchain->cacheT = 0; } ramchain->txids = 0; ramchain->pkhashes = 0; @@ -1284,8 +1281,8 @@ int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ra ramchain->Xspendinds = 0; } //iguana_volatilespurge(coin,ramchain); - if ( deleteflag != 0 ) - memset(ramchain,0,sizeof(*ramchain)); + //if ( deleteflag != 0 ) + // memset(ramchain,0,sizeof(*ramchain)); return(0); } @@ -1294,26 +1291,27 @@ int32_t iguana_bundleremove(struct iguana_info *coin,int32_t hdrsi,int32_t tmpfi struct iguana_bundle *bp; int32_t i; char fname[1024],str[65]; if ( hdrsi >= 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 ) { - printf("delete bundle.[%d]\n",hdrsi); + iguana_volatilespurge(coin,&bp->ramchain); + printf("%s delete bundle.[%d]\n",coin->symbol,hdrsi); + if ( iguana_bundlefname(coin,bp,fname) == 0 ) + OS_removefile(fname,0); if ( tmpfiles != 0 ) { for (i=0; in; i++) iguana_blockunmark(coin,bp->blocks[i],bp,i,1); } - iguana_ramchain_free(coin,&bp->ramchain,0); - if ( iguana_bundlefname(coin,bp,fname) == 0 ) - OS_removefile(fname,0); sprintf(fname,"%s/%s/spends/%s.%d",GLOBAL_DBDIR,coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight), OS_removefile(fname,0); sprintf(fname,"%s/%s/accounts/debits.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight), OS_removefile(fname,0); sprintf(fname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight), OS_removefile(fname,0); sprintf(fname,"%s/%s/validated/%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight), OS_removefile(fname,0); bp->utxofinish = bp->startutxo = bp->balancefinish = bp->validated = bp->emitfinish = bp->converted = 0; + //iguana_ramchain_free(coin,&bp->ramchain,1); return(0); } return(-1); } -int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) +int32_t iguana_ramchain_extras(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { RAMCHAIN_DECLARE; int32_t err=0; struct iguana_ramchaindata *rdata; if ( ramchain->expanded != 0 && (rdata= ramchain->H.data) != 0 ) @@ -1326,7 +1324,7 @@ int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain * else printf("alloc ramchain->A %d\n",(int32_t)(sizeof(struct iguana_account) * rdata->numpkinds)); ramchain->A = (hashmem != 0 && hashmem->ptr != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * rdata->numpkinds,1) : mycalloc('p',rdata->numpkinds,sizeof(struct iguana_account)); ramchain->Uextras = (hashmem != 0 && hashmem->ptr != 0) ? iguana_memalloc(hashmem,sizeof(*ramchain->Uextras) * rdata->numunspents,1) : mycalloc('p',rdata->numunspents,sizeof(*ramchain->Uextras)); - } else err = iguana_volatilesmap(coin,ramchain); + } else err = iguana_volatilesmap(myinfo,coin,ramchain); } return(err); } @@ -1339,7 +1337,16 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha sprintf(fname,"%s/%s%s/spends/%s.%d",GLOBAL_DBDIR,iter==0?"ro/":"",coin->symbol,bits256_str(str,bp->hashes[0]),bp->bundleheight); if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) { +#if defined(_M_X64) + /* + * calculate the address in a portable manner + * in all platform sizeof(char) / sizeof(uchar) == 1 + * @author - fadedreamz@gmail.com + */ + ramchain->Xspendinds = (void *)((unsigned char *)ptr + sizeof(sha256)); +#else ramchain->Xspendinds = (void *)((long)ptr + sizeof(sha256)); +#endif if ( bp->Xvalid == 0 ) vcalc_sha256(0,sha256.bytes,(void *)ramchain->Xspendinds,(int32_t)(filesize - sizeof(sha256))); ramchain->from_roX = (iter == 0); @@ -1350,7 +1357,7 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); if ( bp->Xvalid == 0 ) { - if ( (rand() % 10) == 0 ) + if ( (0) && (rand() % 10) == 0 ) printf("[%d] filesize %ld Xspendptr.%p %p num.%d\n",bp->hdrsi,filesize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); bp->Xvalid = 1; } @@ -1366,24 +1373,24 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha ramchain->Xspendinds = 0; } } - else if ( 0 && iter == 1 ) + else if ( (0) && iter == 1 ) printf("couldnt map.(%s)\n",fname); } return(ramchain->numXspends); } -struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded,uint8_t zcash) +struct iguana_ramchain *_iguana_ramchain_map(struct supernet_info *myinfo,struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded,uint8_t zcash) { - RAMCHAIN_DECLARE; int32_t valid,iter,i,checki,hdrsi; long filesize; void *ptr; char str[65],str2[65],dirstr[64]; struct iguana_block *block; struct iguana_zblockRO zRO; struct iguana_ramchaindata *rdata; + RAMCHAIN_DECLARE; int32_t valid,iter,i,checki,hdrsi; long filesize=0; void *ptr; char str[65],str2[65],dirstr[65]; struct iguana_block *block; struct iguana_zblockRO zRO; struct iguana_ramchaindata *rdata; /*if ( ramchain->expanded != 0 && (ramchain->sigsfileptr == 0 || ramchain->sigsfilesize == 0) ) - { - sprintf(sigsfname,"sigs/%s/%s",coin->symbol,bits256_str(str,hash2)); - if ( (ramchain->sigsfileptr= OS_mapfile(sigsfname,&ramchain->sigsfilesize,0)) == 0 ) - { - printf("couldnt map.(%s)\n",sigsfname); - return(0); - } - }*/ + { + sprintf(sigsfname,"sigs/%s/%s",coin->symbol,bits256_str(str,hash2)); + if ( (ramchain->sigsfileptr= OS_mapfile(sigsfname,&ramchain->sigsfilesize,0)) == 0 ) + { + printf("couldnt map.(%s)\n",sigsfname); + return(0); + } + }*/ if ( ramchain->fileptr == 0 || ramchain->filesize <= 0 ) { for (iter=0; iter<2; iter++) @@ -1412,19 +1419,29 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam if ( ramchain->fileptr != 0 && ramchain->filesize > 0 ) { // verify hashes + + /* + * calculate the address in a portable manner + * in all platform sizeof(char) / sizeof(uchar) == 1 + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + ramchain->H.data = rdata = (void *)((unsigned char *)ramchain->fileptr + fpos); +#else ramchain->H.data = rdata = (void *)(long)((long)ramchain->fileptr + fpos); +#endif ramchain->H.ROflag = 1; ramchain->expanded = expanded; ramchain->numblocks = (bp == 0) ? 1 : bp->n; //printf("ptr.%p exp.%d extra.%d %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,expanded,allocextras,rdata,(int32_t)rdata->Poffset,(int32_t)fpos,(long)rdata->allocsize,(long)(fpos + rdata->allocsize),ramchain->filesize,rscriptoffset,rdata->scriptspace,rstacksize,rdata->stackspace); - if ( 0 && bp != 0 ) + if ( (0) && bp != 0 ) { /*blocksRO = (struct iguana_blockRO *)rdata; - for (i=0; in; i++) - { - printf("%p ",&blocksRO[i]); - bp->hashes[i] = blocksRO[i].hash2; - if ( (bp->blocks[i]= iguana_blockhashset(coin,-1,blocksRO[i].hash2,1)) == 0 ) + for (i=0; in; i++) + { + printf("%p ",&blocksRO[i]); + bp->hashes[i] = blocksRO[i].hash2; + if ( (bp->blocks[i]= iguana_blockhashset(coin,-1,blocksRO[i].hash2,1)) == 0 ) { printf("Error getting blockptr\n"); return(0); @@ -1432,8 +1449,8 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam bp->blocks[i]->RO = blocksRO[i]; } rdata = (void *)&blocksRO[bp->n];*/ - for (valid=0,i=bp->n-1; i>=0; i--) - { + for (valid=0,i=bp->n-1; i>=0; i--) + { if ( (block= bp->blocks[i]) != 0 ) { if ( memcmp(block->RO.hash2.bytes,bp->hashes[i].bytes,sizeof(block->RO.hash2)) == 0 ) @@ -1469,7 +1486,7 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam if ( allocextras > 0 ) { ramchain->height = rdata->height; - if ( iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras) == 0 && bp != 0 ) + if ( iguana_ramchain_extras(myinfo,coin,ramchain,ramchain->hashmem,allocextras) == 0 && bp != 0 ) { bp->balancefinish = (uint32_t)time(NULL); //printf("found balances for %d\n",bp->hdrsi); @@ -1480,7 +1497,7 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam { for (i=0; in; i++) { - iguana_blockzcopyRO(zcash,(void *)&zRO,0,B,i); + iguana_blockzcopyRO(0*zcash,(void *)&zRO,0,B,i); if ( bp->blocks[i] == 0 && (bp->blocks[i]= iguana_blockhashset("mapchain",coin,-1,zRO.RO.hash2,1)) == 0 ) { printf("Error getting blockptr\n"); @@ -1490,14 +1507,14 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam { bp->hashes[i] = zRO.RO.hash2; //bp->blocks[i]->RO = zRO.RO; - iguana_blockzcopyRO(zcash,&bp->blocks[i]->RO,0,(void *)&zRO,0); + iguana_blockzcopyRO(0*zcash,&bp->blocks[i]->RO,0,(void *)&zRO,0); } - /* if ( (bRO= iguana_blockzcopyRO(zcash,&bp->blocks[i]->RO,0,B,i)) != 0 ) - { - //memcpy(&bp->blocks[i]->RO,bRO,bROsize);//coin->blocks.RO[bp->bundleheight + i]; - //coin->blocks.RO[bp->bundleheight+i] = B[i]; - bp->hashes[i] = bRO->hash2; - }*/ + /* if ( (bRO= iguana_blockzcopyRO(zcash,&bp->blocks[i]->RO,0,B,i)) != 0 ) + { + //memcpy(&bp->blocks[i]->RO,bRO,bROsize);//coin->blocks.RO[bp->bundleheight + i]; + //coin->blocks.RO[bp->bundleheight+i] = B[i]; + bp->hashes[i] = bRO->hash2; + }*/ } } //printf("iguana_ramchain_map.(%s) size %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks,rdata->scriptspace),(long)rdata->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+rdata->allocsize)); @@ -1508,7 +1525,7 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam return(0); } -struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) +struct iguana_ramchain *iguana_ramchain_map(struct supernet_info *myinfo,struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) { struct iguana_ramchain *retptr; #ifdef __PNACL__ @@ -1516,7 +1533,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname //portable_mutex_lock(&mutex); #endif ramchain->height = bp->bundleheight; - retptr = _iguana_ramchain_map(coin,fname,bp,numblocks,ramchain,hashmem,ipbits,hash2,prevhash2,bundlei,fpos,allocextras,expanded,coin->chain->zcash); + retptr = _iguana_ramchain_map(myinfo,coin,fname,bp,numblocks,ramchain,hashmem,ipbits,hash2,prevhash2,bundlei,fpos,allocextras,expanded,coin->chain->zcash); #ifdef __PNACL__ //portable_mutex_unlock(&mutex); #endif @@ -1567,36 +1584,36 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, { if ( A->expanded != 0 ) { - for (i=A->H.data->firsti; iH.data->numspends; i++) - if ( memcmp(&Sxa[i],&Sxb[i],sizeof(Sxa[i])) != 0 ) - return(-3); - /*for (i=A->H.data->firsti; iH.data->numunspents; i++) - {break; - int32_t j,metalen,checklen; uint8_t _script[8129],*checkscript; - if ( memcmp(&Uxa[i],&Uxb[i],sizeof(Uxa[i])) != 0 ) - return(-4); - checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspacea,Uxa[i].type,_script,Uxa[i].scriptoffset,0); - for (j=0; jH.data->firsti; iH.data->numpkinds; i++) - { - //if ( memcmp(&P2a[i],&P2b[i],sizeof(P2a[i])) != 0 ) - // return(-6); - if ( memcmp(&ACCTa[i],&ACCTb[i],sizeof(ACCTa[i])) != 0 ) - return(-7); - } - for (i=0; iH.data->numexternaltxids; i++) - if ( memcmp(&Xa[i],&Xb[i],sizeof(Xa[i])) != 0 ) + for (i=A->H.data->firsti; iH.data->numspends; i++) + if ( memcmp(&Sxa[i],&Sxb[i],sizeof(Sxa[i])) != 0 ) + return(-3); + /*for (i=A->H.data->firsti; iH.data->numunspents; i++) + {break; + int32_t j,metalen,checklen; uint8_t _script[8129],*checkscript; + if ( memcmp(&Uxa[i],&Uxb[i],sizeof(Uxa[i])) != 0 ) + return(-4); + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspacea,Uxa[i].type,_script,Uxa[i].scriptoffset,0); + for (j=0; jH.data->firsti; iH.data->numpkinds; i++) { - bits256_str(str2,Xb[i]); - bits256_str(str,Xa[i]); - printf("X[%d] A.%s B.%s\n",i,str,str2); - return(-8); + //if ( memcmp(&P2a[i],&P2b[i],sizeof(P2a[i])) != 0 ) + // return(-6); + if ( memcmp(&ACCTa[i],&ACCTb[i],sizeof(ACCTa[i])) != 0 ) + return(-7); } + for (i=0; iH.data->numexternaltxids; i++) + if ( memcmp(&Xa[i],&Xb[i],sizeof(Xa[i])) != 0 ) + { + bits256_str(str2,Xb[i]); + bits256_str(str,Xa[i]); + printf("X[%d] A.%s B.%s\n",i,str,str2); + return(-8); + } } else { @@ -1607,15 +1624,15 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, if ( memcmp(&Ua[i],&Ub[i],sizeof(Ua[i])) != 0 ) return(-10); /*for (i=A->H.data->firsti; iH.data->numunspents; i++) - {break; - int32_t j,metalen,checklen; uint8_t _script[8129],*checkscript; - checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspacea,Ua[i].type,_script,Ua[i].scriptoffset,0); - for (j=0; jfirsti != 1 ) + printf("unexpected firsti.%d %s.%d\n",rdata->firsti,coin->symbol,bundlei); if ( dest != 0 ) { // required to do one block at a time, all vins/vouts the same height are assumed to happen simultaneously with vouts before vins @@ -1661,7 +1680,7 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info { if ( coin->active == 0 ) return(-1);; - if ( 0 && ramchain->expanded == 0 && dest != 0 ) + if ( (0) && ramchain->expanded == 0 && dest != 0 ) printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",rdata->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); tx = &T[ramchain->H.txidind]; if ( iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp,bundlei) == 0 ) @@ -1672,7 +1691,7 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info if ( dest->expanded != 0 ) iguana_opreturn(myinfo,1,coin,tx->timestamp,bp,0,bp->bundleheight + bundlei,(((uint64_t)bp->hdrsi << 32) | dest->H.unspentind),0,0,0,0); //char str[65]; - if ( 0 && ramchain->expanded == 0 ) + if ( (0) && ramchain->expanded == 0 ) printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",rdata->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp,bundlei) == 0 ) return(-2); @@ -1683,6 +1702,7 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info if ( coin->active == 0 ) return(-1); fileid = 0; + unspentind = 0; scriptpos = 0; scriptlen = 0; memset(rmd160,0,sizeof(rmd160)); @@ -1702,10 +1722,10 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info memcpy(rmd160,P[u->pkind].rmd160,20); //printf("EXPANDED scriptpos.%u scriptlen.%d type.%d %.8f\n",(uint32_t)scriptpos,scriptlen,type,dstr(value)); /*scriptlen = 0; - if ( u->scriptoffset != 0 || type == IGUANA_SCRIPT_76AC ) - { - scriptdata = iguana_ramchain_scriptdecode(&metalen,&scriptlen,Kspace,type,_script,u->scriptoffset,P[u->pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[u->pkind].pubkeyoffset : 0); - }*/ + if ( u->scriptoffset != 0 || type == IGUANA_SCRIPT_76AC ) + { + scriptdata = iguana_ramchain_scriptdecode(&metalen,&scriptlen,Kspace,type,_script,u->scriptoffset,P[u->pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[u->pkind].pubkeyoffset : 0); + }*/ //fprintf(stderr,"iter add %p[%d] type.%d\n",scriptdata,scriptlen,type); if ( (unspentind= iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,fileid,(uint32_t)scriptpos,scriptlen,ramchain->H.txidind-rdata->firsti)) == 0 ) return(-3); @@ -1722,19 +1742,19 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info scriptlen = U[ramchain->H.unspentind].scriptlen; //printf("scriptpos.%u scriptlen.%d type.%d %.8f\n",(uint32_t)scriptpos,scriptlen,type,dstr(value)); /*if ( U[ramchain->H.unspentind].scriptoffset != 0 ) - { - scriptdata = &Kspace[U[ramchain->H.unspentind].scriptoffset]; - scriptlen = U[ramchain->H.unspentind].scriptlen; - } - if ( 0 && scriptdata != 0 && scriptlen > 0 ) - { - int32_t i; for (i=0; iH.unspentind,U[ramchain->H.unspentind].scriptoffset); - } //else printf("no script\n");*/ + { + scriptdata = &Kspace[U[ramchain->H.unspentind].scriptoffset]; + scriptlen = U[ramchain->H.unspentind].scriptlen; + } + if ( 0 && scriptdata != 0 && scriptlen > 0 ) + { + int32_t i; for (i=0; iH.unspentind,U[ramchain->H.unspentind].scriptoffset); + } //else printf("no script\n");*/ if ( (unspentind= iguana_ramchain_addunspent20(coin,0,RAMCHAIN_ARG,value,0,scriptlen,tx->txid,j,type,bp,rmd160)) == 0 ) return(-4); - if ( 0 ) + if ( (0) ) { int32_t i; for (i=0; i<20; i++) printf("%02x",rmd160[i]); @@ -1778,7 +1798,7 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info fileid = Sx[ramchain->H.spendind].fileid; scriptpos = Sx[ramchain->H.spendind].scriptpos; scriptlen = Sx[ramchain->H.spendind].scriptlen; - //scriptlen = iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[rdata->scriptspace],Kspace,&Sx[ramchain->H.spendind]); + //scriptlen = iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[rdata->scriptspace],Kspace,&Sx[ramchain->H.spendind]); //scriptdata = _script; prevout = iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); //fprintf(stderr,"from expanded iter\n"); @@ -1803,16 +1823,16 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info scriptpos = S[ramchain->H.spendind].scriptpos; scriptlen = S[ramchain->H.spendind].vinscriptlen; /*if ( S[ramchain->H.spendind].scriptoffset != 0 ) - { - scriptdata = &Kspace[S[ramchain->H.spendind].scriptoffset]; - scriptlen = S[ramchain->H.spendind].vinscriptlen; - }*/ + { + scriptdata = &Kspace[S[ramchain->H.spendind].scriptoffset]; + scriptlen = S[ramchain->H.spendind].vinscriptlen; + }*/ /*if ( scriptdata != 0 && scriptlen > 0 ) - { - int32_t i; for (i=0; iH.spendind); - }*/ + { + int32_t i; for (i=0; iH.spendind); + }*/ if ( iguana_ramchain_addspend256(coin,0,RAMCHAIN_ARG,prevhash,prevout,0,scriptlen,sequenceid,bp) == 0 ) return(-8); } @@ -1830,96 +1850,41 @@ int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info return(0); } -long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen) +long iguana_ramchain_data(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen,struct iguana_bundle *bp,struct iguana_block *block) { - static uint64_t totalrecv; int32_t verifyflag = 0; - RAMCHAIN_DECLARE; uint32_t addr_ipbits; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain; struct iguana_msgtx *tx; char fname[1024]; uint8_t rmd160[20]; struct iguana_ramchaindata *rdata; int32_t i,j,fpos,pubkeysize,msize,sigsize,subdir,firsti=1,err,flag,bundlei = -2; bits256 merkle_root; struct iguana_bundle *bp = 0; struct iguana_block *block; uint32_t scriptspace,stackspace; - totalrecv += recvlen; -#ifdef __PNACL__ - //verifyflag = 1; -#endif - if ( addr == 0 || (addr_ipbits= (uint32_t)addr->ipbits) == 0 ) - addr_ipbits = 1; - if ( bits256_nonz(origtxdata->zblock.RO.merkle_root) == 0 ) - { - memset(&origtxdata->zblock.RO.prev_block,0,sizeof(bits256)); - origtxdata->zblock.RO.recvlen = 0; - origtxdata->zblock.issued = 0; - return(-1); - } - if ( addr != 0 ) - { - for (i=0; idirty)/sizeof(*addr->dirty); i++) - addr->dirty[i] = 0; - } - msize = (int32_t)sizeof(bits256) * (txn_count+1) * 2; - if ( msize <= addr->TXDATA.totalsize ) - { - bits256 *tree = addr->TXDATA.ptr; - iguana_memreset(&addr->TXDATA); - for (i=0; izblock.RO.merkle_root) != 0 ) - { - char str[65],str2[65]; - printf(">>>>>>>>>> %s %s merkle mismatch.[%d] calc.(%s) vs (%s)\n",addr->ipaddr,coin->symbol,txn_count,bits256_str(str,merkle_root),bits256_str(str2,origtxdata->zblock.RO.merkle_root)); - origtxdata->zblock.RO.recvlen = 0; - origtxdata->zblock.issued = 0; - return(-1); - } //else printf("matched merkle.%d\n",txn_count); - } else printf("not enough memory for merkle verify %d vs %lu\n",(int32_t)(sizeof(bits256)*(txn_count+1)),(long)addr->TXDATA.totalsize); - bp = 0, bundlei = -2; - if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->zblock.RO.hash2) == 0 ) - { - bp = 0, bundlei = -2; - if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->zblock.RO.prev_block) == 0 ) - { - origtxdata->zblock.RO.recvlen = 0; - origtxdata->zblock.issued = 0; - return(-1); - } - else if ( bundlei < coin->chain->bundlesize-1 ) - bundlei++; - else - { - origtxdata->zblock.issued = 0; - origtxdata->zblock.RO.recvlen = 0; - char str[65]; printf("ramchain data: error finding block %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); - return(-1); - } - } - if ( (block= bp->blocks[bundlei]) == 0 || bits256_cmp(block->RO.hash2,origtxdata->zblock.RO.hash2) != 0 || bits256_cmp(bp->hashes[bundlei],origtxdata->zblock.RO.hash2) != 0 ) + RAMCHAIN_DECLARE; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain; struct iguana_msgtx *tx; char fname[1024]; uint8_t rmd160[20]; struct iguana_ramchaindata *rdata; int32_t i,j,fpos,pubkeysize,sigsize,subdir,firsti=1,err,flag,bundlei=0; uint32_t scriptspace,stackspace; struct iguana_blockRO RO; + if ( block == 0 || bp == 0 || addr == 0 || (block != 0 && (bundlei= block->bundlei) < 0) ) { - char str[65]; - if ( 0 && block != 0 ) - printf("%d:%d has no block ptr.%p %s or wrong hash\n",bp->hdrsi,bundlei,block,bits256_str(str,origtxdata->zblock.RO.hash2)); + //printf("iguana_ramchain_data: null ptr %p %p %p\n",block,bp,addr); return(-1); } - block->txvalid = 1; - if ( block->fpipbits != 0 && block->fpos >= 0 ) - { - static int32_t numredundant; static double redundantsize; static uint32_t lastdisp; - char str[65],str2[65]; - numredundant++, redundantsize += recvlen; - if ( time(NULL) > lastdisp+30 ) - { - lastdisp = (uint32_t)time(NULL); - printf("ramchaindata have %d:%d at %d | %d blocks %s redundant xfers total %s %.2f%% wasted\n",bp->hdrsi,bundlei,block->fpos,numredundant,mbstr(str,redundantsize),mbstr(str2,totalrecv),100.*redundantsize/totalrecv); - } - return(block->fpos); - } +#ifdef __PNACL__ + //verifyflag = 1; +#endif sigsize = pubkeysize = 0; scriptspace = 1;//iguana_scriptspaceraw(coin,&scriptsize,&sigsize,&pubkeysize,txarray,txn_count); + for (i=0; idirty)/sizeof(*addr->dirty); i++) + addr->dirty[i] = 0; if ( iguana_ramchain_init(fname,ramchain,&addr->TXDATA,&addr->HASHMEM,1,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0,(scriptspace+sigsize+pubkeysize)*1.1,0,1,coin->chain->zcash) == 0 ) { - if ( block->fpipbits == 0 ) + if ( block != 0 && block->fpipbits == 0 ) block->issued = block->RO.recvlen = 0, block->fpos = -1; return(-1); } - block->fpos = fpos = -1; - iguana_ramchain_link(ramchain,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,0); + if ( block != 0 ) + { + RO = block->RO; + block->fpos = -1; + } + else + { + memset(&RO,0,sizeof(RO)); + RO.hash2 = origtxdata->zblock.RO.hash2; + RO.prev_block = origtxdata->zblock.RO.prev_block; + } + fpos = -1; + iguana_ramchain_link(ramchain,origtxdata->zblock.RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,0); if ( (rdata= ramchain->H.data) != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); @@ -1929,16 +1894,26 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru //printf("Kspace.%p bp.[%d:%d] <- scriptspace.%d expanded.%d\n",Kspace,bp->hdrsi,bundlei,scriptspace,ramchain->expanded); if ( T == 0 || U == 0 || S == 0 || B == 0 ) { - block->issued = 0; - block->RO.recvlen = 0; + if ( block != 0 ) + { + block->issued = 0; + block->RO.recvlen = 0; + } printf("fatal error getting txdataptrs %p %p %p %p\n",T,U,S,B); return(-1); } - block->fpipbits = 1; - for (i=0; iH.txidind++) + if ( block != 0 ) + block->fpipbits = 1; + for (i=0; itxid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,bundlei); + if ( tx->tx_out == 0 ) + { + if ( coin->chain->zcash == 0 ) + printf("strange tx without any inputs or outputs? ht.%d\n",bp->bundleheight); + continue; + } for (j=0; jtx_out; j++) { memset(rmd160,0,sizeof(rmd160)); @@ -1946,18 +1921,20 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru iguana_ramchain_addunspent20(coin,addr,RAMCHAIN_ARG,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,-1,bp,rmd160); } ramchain->H.spendind += tx->tx_in; + ramchain->H.txidind++; } //printf("scriptoffset.%d after %d txids\n",ramchain->H.scriptoffset,txn_count); ramchain->H.txidind = ramchain->H.spendind = rdata->firsti; - for (i=0; iH.txidind++) + for (i=0; itx_in; j++) { iguana_ramchain_addspend256(coin,addr,RAMCHAIN_ARG,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->vins[j].sequence,bp);//,bp->hdrsi,bundlei); } + ramchain->H.txidind++; } - rdata->prevhash2 = block->RO.prev_block; + rdata->prevhash2 = origtxdata->zblock.RO.prev_block; rdata->scriptspace = scriptspace = ramchain->H.scriptoffset; rdata->stackspace = stackspace = ramchain->H.stacksize; iguana_ramchain_setsize(fname,ramchain,rdata,1,coin->chain->zcash); @@ -1965,18 +1942,21 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru if ( ramchain->H.txidind != rdata->numtxids || ramchain->H.unspentind != rdata->numunspents || ramchain->H.spendind != rdata->numspends ) { printf("error creating PT ramchain.[%d:%d] ramchain->txidind %d != %d ramchain->data->numtxids || ramchain->unspentind %d != %d ramchain->data->numunspents || ramchain->spendind %d != %d ramchain->data->numspends space.(%d v %d)\n",bp->hdrsi,bp->bundleheight,ramchain->H.txidind,rdata->numtxids,ramchain->H.unspentind,rdata->numunspents,ramchain->H.spendind,rdata->numspends,ramchain->H.scriptoffset,rdata->scriptspace); - block->fpipbits = 0; - block->issued = 0; - block->RO.recvlen = 0; + if ( block != 0 ) + { + block->fpipbits = 0; + block->issued = 0; + block->RO.recvlen = 0; + } } else { if ( (err= iguana_ramchain_verify(coin,ramchain)) == 0 ) { - iguana_blockzcopyRO(coin->chain->zcash,B,0,&block->RO,0); + iguana_blockzcopyRO(0*coin->chain->zcash,B,0,&RO,0); rdata->scriptspace = ramchain->H.scriptoffset = scriptspace; rdata->stackspace = ramchain->H.stacksize = stackspace; - if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,0,coin->chain->zcash)) >= 0 ) + if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,(uint32_t)addr->ipbits,RO.hash2,RO.prev_block,bundlei,0,coin->chain->zcash)) >= 0 ) { origtxdata->datalen = (int32_t)rdata->allocsize; //char str[65]; printf("saved.%s [%d:%d] fpos.%d datalen.%d\n",bits256_str(str,block->RO.hash2),bp->hdrsi,bundlei,fpos,origtxdata->datalen); @@ -1987,7 +1967,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru if ( addr->dirty[1] != 0 && addr->vinsfp != 0 ) fflush(addr->vinsfp); memset(&R,0,sizeof(R)); - if ( verifyflag != 0 && (mapchain= iguana_ramchain_map(coin,fname,0,1,&R,0,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,fpos,1,0)) == 0 ) + if ( verifyflag != 0 && (mapchain= iguana_ramchain_map(myinfo,coin,fname,0,1,&R,0,(uint32_t)addr->ipbits,RO.hash2,RO.prev_block,bundlei,fpos,1,0)) == 0 ) { printf("delete unverified [%d:%d]\n",bp->hdrsi,bundlei); iguana_ramchain_free(coin,&R,1); @@ -2000,8 +1980,8 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru bp->numspends += rdata->numspends; //bp->rawscriptspace += rdata->scriptspace; } - if ( fpos >= 0 ) - block->fpos = fpos, block->fpipbits = addr_ipbits; + if ( block != 0 && fpos >= 0 ) + block->fpos = fpos, block->fpipbits = (uint32_t)addr->ipbits; } else printf("save error\n"); } else @@ -2011,11 +1991,11 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru } } } - if ( fpos < 0 ) + if ( fpos < 0 && block != 0 ) iguana_blockunmark(coin,block,bp,bundlei,1); //fprintf(stderr,"finished with hdrsi.%d ht.%d scripts.%u:%u\n",bp->hdrsi,bp->bundleheight,ramchain->H.scriptoffset,rdata->scriptspace); ramchain->H.ROflag = 0; - iguana_ramchain_free(coin,ramchain,0); + iguana_ramchain_free(coin,ramchain,1); return(fpos); } @@ -2038,27 +2018,52 @@ void iguana_ramchain_disp(struct iguana_ramchain *ramchain) init_hexbytes_noT(str,U[unspentind].rmd160,20); printf("(%.8f %s) ",dstr(U[unspentind].value),str); } - printf("txid.[%d] %s (%d:%d %d:%d)\n",txidind,bits256_str(str,tx->txid),tx->firstvout,tx->numvouts,tx->firstvin,tx->numvins); + printf("txid.[%d] %s (%u:%d %u:%d)\n",txidind,bits256_str(str,tx->txid),(uint32_t)tx->firstvout,tx->numvouts,(uint32_t)tx->firstvin,tx->numvins); } } } +void iguana_blockdelete(struct iguana_info *coin,bits256 hash2,int32_t i) +{ + char fname[512]; int32_t checki,hdrsi; bits256 zero; + memset(&zero,0,sizeof(zero)); + fname[0] = 0; + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,hash2,zero,1,1)) != i ) + { + //printf("checki.%d vs %d mismatch? %s\n",checki,i,fname); + } + if ( fname[0] != 0 ) + { + OS_removefile(fname,0); +/*#ifndef WIN32 + strcat(fname,".tmp"); + OS_removefile(fname,0); +#endif*/ + } +} + void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,struct iguana_bundle *bp,int32_t i,int32_t deletefile) { - void *ptr; int32_t recvlen,hdrsi,checki; char fname[1024]; static const bits256 zero; - if ( 0 && bp != 0 ) + void *ptr; int32_t recvlen,height = -1; + if ( (0) && bp != 0 ) printf("UNMARK.[%d:%d]\n",bp->hdrsi,i); if ( block != 0 ) { + height = block->height; block->queued = 0; block->fpipbits = 0; block->fpos = -1; block->txvalid = 0; block->issued = 0; + block->mainchain = 0; } if ( bp != 0 && i >= 0 && i < bp->n ) { + if ( height < 0 || bp->bundleheight+i < height ) + height = bp->bundleheight+i; bp->issued[i] = 0; + bp->blocks[i] = 0; + memset(&bp->hashes[i],0,sizeof(bp->hashes[i])); if ( (ptr= bp->speculativecache[i]) != 0 ) { memcpy(&recvlen,ptr,sizeof(recvlen)); @@ -2066,15 +2071,13 @@ void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,stru bp->speculativecache[i] = 0; } } - if ( deletefile != 0 ) + if ( deletefile != 0 && block != 0 ) + iguana_blockdelete(coin,block->RO.hash2,i); + if ( (0) && coin->RTheight > 0 && height > 0 && height < coin->blocks.hwmchain.height ) { - fname[0] = 0; - if ( block != 0 && (checki= iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,block->RO.hash2,zero,1,1)) != i ) - { - //printf("checki.%d vs %d mismatch? %s\n",checki,i,fname); - } - if ( fname[0] != 0 ) - OS_removefile(fname,0); + printf("reduce %s HWM height from %d to %d\n",coin->symbol,coin->blocks.hwmchain.height,height); + if ( (block= iguana_blockfind("unmark",coin,iguana_blockhash(coin,height))) != 0 ) + iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,(struct iguana_block *)&coin->blocks.hwmchain,block); } } @@ -2118,9 +2121,9 @@ int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **p return(num); } -void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei) +void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei,int32_t renameflag) { - int32_t checki,hdrsi; void *ptr = 0; FILE *fp; static const bits256 zero; + int32_t checki,hdrsi; long checksize; void *ptr = 0; FILE *fp; static const bits256 zero; //char renamed[1024]; *filesizep = 0; fname[0] = 0; if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[bundlei],zero,1,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) @@ -2132,12 +2135,39 @@ void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,str return(0); else { + fseek(fp,0,SEEK_END); + checksize = ftell(fp); fclose(fp); +/*#ifndef WIN32 + if ( renameflag != 0 ) + { + sprintf(renamed,"%s.tmp",fname); + OS_copyfile(fname,renamed,1); + strcpy(fname,renamed); + } +//#endif*/ if ( (ptr= OS_mapfile(fname,filesizep,0)) == 0 ) { printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); return(0); } + if ( *filesizep != checksize ) + { + printf("%s *filesizep %ld != %ld\n",fname,*filesizep,checksize); + OS_releasemap(ptr,*filesizep); + sleep(1); + if ( (ptr= OS_mapfile(fname,filesizep,0)) == 0 ) + { + printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); + return(0); + } + if ( *filesizep != checksize ) + { + printf("second %s failure *filesizep %ld != %ld\n",fname,*filesizep,checksize); + OS_releasemap(ptr,*filesizep); + return(0); + } + } } //printf("mapped.(%s) bundlei.[%d:%d] %p[%ld]\n",fname,hdrsi,bundlei,ptr,*filesizep); return(ptr); @@ -2148,7 +2178,7 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs int32_t bundlei,num = 0; char fname[1024]; for (bundlei=starti; bundlei<=endi; bundlei++) { - if ( (ptrs[num]= iguana_bundlefile(coin,fname,&filesizes[num],bp,bundlei)) != 0 ) + if ( (ptrs[num]= iguana_bundlefile(coin,fname,&filesizes[num],bp,bundlei,1)) != 0 ) num++; else { @@ -2175,7 +2205,6 @@ void iguana_bundlemapfree(struct iguana_info *coin,struct OS_memspace *mem,struc { for (j=starti; j<=endi; j++) { - //printf("R[%d]\n",j); R[j].fileptr = 0; R[j].filesize = 0; iguana_ramchain_free(coin,&R[j],1); @@ -2251,10 +2280,10 @@ int32_t iguana_ramchain_expandedsave(struct supernet_info *myinfo,struct iguana_ bundlei = 0; if ( cmpflag == 0 ) iguana_memreset(hashmem); - if ( (mapchain= iguana_ramchain_map(coin,fname,bp,numblocks,&checkR,cmpflag==0?hashmem:0,0,firsthash2,zero,bundlei,0,0,1)) != 0 ) + if ( (mapchain= iguana_ramchain_map(myinfo,coin,fname,bp,numblocks,&checkR,cmpflag==0?hashmem:0,0,firsthash2,zero,bundlei,0,0,1)) != 0 ) { iguana_ramchain_link(mapchain,firsthash2,hdrsi,height,0,numblocks,firsti,1); - iguana_ramchain_extras(coin,mapchain,hashmem,0); + iguana_ramchain_extras(myinfo,coin,mapchain,hashmem,0); //printf("expSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)mapchain->H.data->Koffset,mapchain->H.scriptoffset,mapchain->H.stacksize,(int32_t)mapchain->H.data->allocsize); if ( (err= iguana_ramchain_iterate(myinfo,coin,0,mapchain,bp,bundlei)) != 0 ) printf("err.%d iterate mapped dest\n",err); @@ -2269,7 +2298,7 @@ int32_t iguana_ramchain_expandedsave(struct supernet_info *myinfo,struct iguana_ } } //printf("%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %llx ht.%d bundlehashes.%s\n",mapchain->H.data->lhashes[0].uints[0],mapchain->H.data->lhashes[1].uints[0],mapchain->H.data->lhashes[2].uints[0],mapchain->H.data->lhashes[3].uints[0],mapchain->H.data->lhashes[4].uints[0],mapchain->H.data->lhashes[5].uints[0],mapchain->H.data->lhashes[6].uints[0],mapchain->H.data->lhashes[7].uints[0],mapchain->H.data->lhashes[8].uints[0],mapchain->H.data->lhashes[9].uints[0],(long long)mapchain->H.data->sha256.txid,mapchain->height,coin->symbol); - iguana_ramchain_free(coin,mapchain,cmpflag); + iguana_ramchain_free(coin,mapchain,1); } iguana_mempurge(hashmem); } @@ -2281,17 +2310,20 @@ int32_t iguana_ramchain_expandedsave(struct supernet_info *myinfo,struct iguana_ return(retval); } -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag) +struct iguana_ramchain *iguana_bundleload(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag) { static const bits256 zero; struct iguana_blockRO *B; struct iguana_txid *T; int32_t i,firsti = 1; char fname[512]; - struct iguana_block *block,*prev,*prev2; struct iguana_ramchain *mapchain; struct iguana_ramchaindata *rdata; + struct iguana_block *block,*prev,*prev2; struct iguana_ramchain *mapchain; struct iguana_ramchaindata *rdata; uint32_t firsttxidind; + if ( bp->emitfinish > 1 ) + return(ramchain); memset(ramchain,0,sizeof(*ramchain)); - if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,extraflag,1)) != 0 ) + if ( (mapchain= iguana_ramchain_map(myinfo,coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,extraflag,1)) != 0 ) { iguana_ramchain_link(mapchain,bp->hashes[0],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,1); //char str[65]; printf("%s bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",coin->symbol,bp->hdrsi,mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,mbstr(str,mapchain->H.data->allocsize),mapchain->H.data); //ramcoder_test(mapchain->H.data,mapchain->H.data->allocsize); + firsttxidind = 1; if ( (rdata= ramchain->H.data) != 0 ) { B = RAMCHAIN_PTR(rdata,Boffset); @@ -2313,10 +2345,13 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana block->hdrsi = bp->hdrsi; block->bundlei = i; block->fpipbits = (uint32_t)calc_ipbits("127.0.0.1"); - iguana_blockzcopyRO(coin->chain->zcash,&block->RO,0,B,i); + iguana_blockzcopyRO(0*coin->chain->zcash,&block->RO,0,B,i); //printf("%x ",(int32_t)B[i].hash2.ulongs[3]); - iguana_hash2set(coin,"bundleload",bp,i,block->RO.hash2); bp->blocks[i] = block; + bp->hashes[i] = block->RO.hash2; + block->RO.firsttxidind = firsttxidind; + bp->firsttxidinds[i] = firsttxidind; + iguana_hash2set(coin,"bundleload",bp,i,block->RO.hash2); if ( (prev= block->hh.prev) != 0 ) { prev2 = prev->hh.prev; @@ -2324,7 +2359,7 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana } if ( prev2 != 0 && prev != 0 && strcmp(coin->symbol,"BTCD") == 0 && bp->bundleheight > 20000 && prev != 0 && iguana_targetbits(coin,block,prev,prev2,1,coin->chain->targetspacing,coin->chain->targettimespan) != block->RO.bits ) { - printf("nbits target error %x != %x ht.%d\n",iguana_targetbits(coin,block,prev,prev2,1,coin->chain->targetspacing,coin->chain->targettimespan),block->RO.bits,block->height); + printf("warning: nbits target mismatch %x != %x ht.%d, this is normal during parallel sync\n",iguana_targetbits(coin,block,prev,prev2,1,coin->chain->targetspacing,coin->chain->targettimespan),block->RO.bits,block->height); } //else printf(">>>>>>>>>> matched nbits %x ht.%d\n",block->RO.bits,block->height); if ( bp->bundleheight+i == coin->blocks.hwmchain.height+1 ) { @@ -2332,12 +2367,14 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana //_iguana_chainlink(coin,block); //wrong context } prev2 = prev, prev = block; + //printf("%p.%d ",block,block->RO.txn_count); + firsttxidind += block->RO.txn_count; } } } - //printf("mapped bundle.%d\n",bp->bundleheight); + //printf("mapped bundle.[%d] numtxn.%d\n",bp->hdrsi,firsttxidind); bp->emitfinish = (uint32_t)time(NULL) + 1; - iguana_bundlecalcs(coin,bp,60); + iguana_bundlecalcs(myinfo,coin,bp,60); } else { @@ -2352,9 +2389,9 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana return(mapchain); } -int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2) +int64_t iguana_ramchainopen(struct supernet_info *myinfo,char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2) { - RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; int32_t i,numblocks = coin->chain->bundlesize; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t hashsize,allocsize; + RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; int32_t i,numblocks = coin->chain->bundlesize; uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata=0; int64_t hashsize,allocsize; //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; mem->alignflag = sizeof(uint32_t); hashmem->alignflag = sizeof(uint32_t); @@ -2376,10 +2413,10 @@ int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_r if ( rdata->scriptspace > scriptspace ) scriptspace = rdata->scriptspace; } -#ifndef __APPLE__ +//#ifndef __APPLE__ numtxids *= 1.25; numexternaltxids *= 1.25, scriptspace *= 1.25; numunspents *= 1.25, numspends *= 1.25, numpkinds *= 1.25; -#endif +//#endif if ( mem->ptr == 0 ) { while ( (allocsize= _iguana_rdata_action(fname,0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks,coin->chain->zcash)) > 2*1024LL*1024L*1024L ) @@ -2405,7 +2442,7 @@ int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_r ramchain->expanded = 1; ramchain->H.scriptoffset = 1; _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - iguana_ramchain_extras(coin,ramchain,hashmem,0); + iguana_ramchain_extras(myinfo,coin,ramchain,hashmem,0); printf("%s ramchaininit %p ramchain.%p\n",coin->symbol,ramchain->H.data,ramchain); } if ( rdata != 0 ) @@ -2419,7 +2456,17 @@ int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_r memset(mapchain,0,sizeof(*mapchain)); mapchain->fileptr = ptr; mapchain->filesize = filesize; + + /* + * calculate the address in a portable manner + * in all platform sizeof(char) / sizeof(uchar) == 1 + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + mapchain->H.data = (void *)((unsigned char *)ptr + block->fpos); +#else mapchain->H.data = (void *)(long)((long)ptr + block->fpos); +#endif mapchain->H.ROflag = 1; if ( ptr == 0 || block->fpos > filesize ) { @@ -2447,14 +2494,18 @@ int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_r // helper threads: NUM_HELPERS int32_t iguana_bundlesaveHT(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread { - static int depth; static const bits256 zero; - RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; + static int depth; + RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; static struct iguana_blockRO *_destB; void **ptrs; long *filesizes; uint32_t *ipbits; char fname[1024]; struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits; bits256 prevhash2; int32_t i,starti,endi,bp_n,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_block *block; long fpos; - struct OS_memspace HASHMEM; int32_t err,j,num,hdrsi,bundlei,firsti= 1,retval = -1; + struct OS_memspace HASHMEM; int32_t err,j,num,bundlei,firsti= 1,retval = -1; memset(&HASHMEM,0,sizeof(HASHMEM)); starti = 0, endi = bp->n - 1; + if ( _destB == 0 ) + _destB = malloc(sizeof(*_destB) * 2000); + destB = _destB; + memset(destB,0,sizeof(*destB) * bp->n); //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; R = mycalloc('s',bp->n,sizeof(*R)); ptrs = mycalloc('w',bp->n,sizeof(*ptrs)); @@ -2540,7 +2591,7 @@ int32_t iguana_bundlesaveHT(struct supernet_info *myinfo,struct iguana_info *coi dest->expanded = 1; dest->H.scriptoffset = 1; _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(coin,dest,&HASHMEM,0); + iguana_ramchain_extras(myinfo,coin,dest,&HASHMEM,0); for (i=starti; i<=endi; i++) { if ( coin->active == 0 ) @@ -2552,14 +2603,14 @@ int32_t iguana_bundlesaveHT(struct supernet_info *myinfo,struct iguana_info *coi { if ( bits256_nonz(block->RO.prev_block) == 0 && i > 0 ) block->RO.prev_block = bp->hashes[i-1]; - if ( (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) + if ( (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(myinfo,coin,&valid,block,1) < 0 ) { char str[65]; printf("null prevblock error at ht.%d patch.(%s)\n",bp->bundleheight+i,bits256_str(str,bp->hashes[i-1])); iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); iguana_blockunmark(coin,block,bp,i,1); return(-1); } - iguana_blockzcopyRO(coin->chain->zcash,destB,i,&block->RO,0); + iguana_blockzcopyRO(0*coin->chain->zcash,destB,i,&block->RO,0); //destB[i] = block->RO; } else printf("bundlesave error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,bp->blocks[i]); } @@ -2574,7 +2625,7 @@ int32_t iguana_bundlesaveHT(struct supernet_info *myinfo,struct iguana_info *coi { iguana_blocksetcounters(coin,block,dest); //coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; - iguana_blockzcopyRO(coin->chain->zcash,destB,bundlei,&block->RO,0); + iguana_blockzcopyRO(0*coin->chain->zcash,destB,bundlei,&block->RO,0); //destB[bundlei] = block->RO; //fprintf(stderr,"(%d %d).%d ",R[bundlei].H.data->numtxids,dest->H.txidind,bundlei); if ( (err= iguana_ramchain_iterate(myinfo,coin,dest,&R[bundlei],bp,bundlei)) != 0 ) @@ -2614,16 +2665,17 @@ int32_t iguana_bundlesaveHT(struct supernet_info *myinfo,struct iguana_info *coi { //char dirname[1024]; //printf("delete %d files hdrs.[%d] retval.%d bp_n.%d\n",num,bp->hdrsi,retval,bp_n); - if ( iguana_bundleload(coin,&newchain,bp,0) == 0 ) + if ( iguana_bundleload(myinfo,coin,&newchain,bp,0) == 0 ) retval = -1; - else if ( bp_n == bp->n && bp->n == coin->chain->bundlesize && bp->hdrsi < coin->bundlescount-3 ) + else //if ( bp_n == bp->n && bp->n == coin->chain->bundlesize && bp->hdrsi < coin->bundlescount-3 ) { for (j=starti; j<=endi; j++) - { - if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 && coin->peers != 0 ) - coin->peers->numfiles -= OS_removefile(fname,0); - else printf("error removing.(%s)\n",fname); - } + iguana_blockdelete(coin,bp->hashes[j],j); + /*{ + if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 && coin->peers != 0 ) + coin->peers->numfiles -= OS_removefile(fname,0); + else printf("error removing.(%s)\n",fname); + }*/ //sprintf(dirname,"%s/%s/%d",GLOBAL_TMPDIR,coin->symbol,bp->bundleheight), OS_portable_rmdir(dirname,1); } //sleep(1); @@ -2665,11 +2717,11 @@ int32_t iguana_bundlemergeHT(struct supernet_info *myinfo,char *fname,struct igu iguana_meminit(&HASHMEMB,"hashmemB",0,iguana_hashmemsize(nextbp->ramchain.H.txidind,nextbp->ramchain.H.unspentind,nextbp->ramchain.H.spendind,nextbp->ramchain.pkind,nextbp->ramchain.externalind,nextbp->ramchain.H.data->scriptspace) + IGUANA_MAXSCRIPTSIZE,0); memset(&_Achain,0,sizeof(_Achain)); A = &_Achain; memset(&_Bchain,0,sizeof(_Bchain)); B = &_Bchain; - if ( (A= iguana_ramchain_map(coin,fnameA,bp,bp->ramchain.numblocks,A,&HASHMEMA,0,bp->hashes[0],zero,0,0,1,1)) != 0 ) + if ( (A= iguana_ramchain_map(myinfo,coin,fnameA,bp,bp->ramchain.numblocks,A,&HASHMEMA,0,bp->hashes[0],zero,0,0,1,1)) != 0 ) { iguana_ramchain_link(A,bp->hashes[0],bp->hdrsi,bp->bundleheight,0,bp->ramchain.numblocks,firsti,1); } - if ( (B= iguana_ramchain_map(coin,fnameB,bp,nextbp->ramchain.numblocks,B,&HASHMEMB,0,nextbp->hashes[0],zero,0,0,1,1)) != 0 ) + if ( (B= iguana_ramchain_map(myinfo,coin,fnameB,bp,nextbp->ramchain.numblocks,B,&HASHMEMB,0,nextbp->hashes[0],zero,0,0,1,1)) != 0 ) { iguana_ramchain_link(B,bp->hashes[0],nextbp->hdrsi,nextbp->bundleheight,0,nextbp->ramchain.numblocks,firsti,1); } @@ -2683,14 +2735,14 @@ int32_t iguana_bundlemergeHT(struct supernet_info *myinfo,char *fname,struct igu { if ( iguana_ramchain_alloc(fname,coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->H.data->scriptspace,A->height,A->numblocks + B->numblocks,coin->chain->zcash) < 0 ) { - printf("depth.%d ht.%d fsize.%s ERROR alloc lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); + printf("depth.%d ht.%d fsize.%s ERROR alloc lag.%d elapsed.%d\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,(int32_t)(time(NULL)-now)); iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); return(-1); } depth++; iguana_ramchain_link(dest,A->H.data->firsthash2,A->H.hdrsi,A->height,0,A->numblocks+B->numblocks,firsti,0); _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(coin,dest,&HASHMEM,0); + iguana_ramchain_extras(myinfo,coin,dest,&HASHMEM,0); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = 0; if ( (err= iguana_ramchain_iterate(myinfo,coin,dest,A,bp,-1)) != 0 ) @@ -2700,7 +2752,7 @@ int32_t iguana_bundlemergeHT(struct supernet_info *myinfo,char *fname,struct igu else if ( iguana_ramchain_expandedsave(myinfo,coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,0) == 0 ) { printf("merging isnt setup to save the blockROs\n"); - printf("depth.%d ht.%d fsize.%s MERGED %d[%d] and %d[%d] lag.%d elapsed.%ld bp.%d -> %d\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),A->height,A->numblocks,B->height,B->numblocks,now-starttime,time(NULL)-now,bp->bundleheight,nextbp->bundleheight); + printf("depth.%d ht.%d fsize.%s MERGED %d[%d] and %d[%d] lag.%d elapsed.%d bp.%d -> %d\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),A->height,A->numblocks,B->height,B->numblocks,now-starttime,(int32_t)(time(NULL)-now),bp->bundleheight,nextbp->bundleheight); iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); bp->mergefinish = 0; nextbp->mergefinish = (uint32_t)time(NULL); @@ -2767,93 +2819,4 @@ void iguana_ramchainmerge(struct iguana_info *coin) // jl777: verify prev/next h } #endif -void iguana_RTvout(struct iguana_info *coin,int64_t polarity,struct iguana_RTtxid *RTptr,struct iguana_block *block,bits256 txid,int32_t j,struct iguana_msgvout *vout) -{ - int32_t scriptlen,type,k; uint8_t *script; struct vin_info V; char coinaddr[64]; - script = vout->pk_script; - scriptlen = vout->pk_scriptlen; - type = iguana_calcrmd160(coin,0,&V,script,scriptlen,txid,j,0xffffffff); - if ( (type == 12 && scriptlen == 0) || (type == 1 && bitcoin_pubkeylen(script+1) <= 0) ) - { - for (k=0; kchain->pubtype,V.rmd160,sizeof(V.rmd160)); - iguana_RTunspent(coin,RTptr,block,polarity,coinaddr,V.rmd160,type,script,scriptlen,txid,j,vout->value); -} -int32_t iguana_RTramchaindata(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *TXDATA,struct OS_memspace *HASHMEM,int64_t polarity,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t txn_count) -{ - RAMCHAIN_DECLARE; struct iguana_ramchain R,*ramchain = &R; struct iguana_msgtx *tx; char fname[1024]; struct iguana_ramchaindata *rdata; struct iguana_RTtxid *RTptr; int32_t iter,hdrsi,bundlei,i,j,firsti = 1; - if ( block->RO.txn_count != txn_count ) - { - printf("txn_count mismatch ht.%d %d != %d\n",block->height,block->RO.txn_count,txn_count); - return(-1); - } - hdrsi = (block->height / coin->chain->bundlesize); - bundlei = (block->height % coin->chain->bundlesize); - if ( iguana_ramchain_init(fname,ramchain,TXDATA,HASHMEM,1,block->RO.txn_count,block->RO.numvouts,block->RO.numvins,0,0,1,0,1,coin->chain->zcash) == 0 ) - { - printf("error iguana_ramchain_init\n"); - return(-1); - } - iguana_ramchain_link(ramchain,block->RO.hash2,hdrsi,block->height,bundlei,1,firsti,0); - if ( (rdata= ramchain->H.data) != 0 ) - { - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); - if ( T == 0 || U == 0 || S == 0 || B == 0 ) - { - printf("fatal error getting txdataptrs %p %p %p %p\n",T,U,S,B); - return(-1); - } - for (iter=0; iter<2; iter++) - { - ramchain->H.txidind = ramchain->H.spendind = ramchain->H.unspentind = rdata->firsti; - for (i=0; iH.txidind++) - { - tx = &txarray[i]; - RTptr = iguana_RTtxid_create(coin,block,polarity,i,txn_count,tx->txid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,tx->serialized,tx->allocsize); - if ( polarity > 0 ) - { - if ( iter == 0 ) - { - for (j=0; jtx_out; j++) - iguana_RTvout(coin,polarity,RTptr,block,tx->txid,j,&tx->vouts[j]); - ramchain->H.spendind += tx->tx_in; - } - else - { - for (j=0; jtx_in; j++) - { - iguana_RTspend(myinfo,coin,RTptr,block,polarity,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->txid,j,tx->vins[j].prev_hash,tx->vins[j].prev_vout); - } - ramchain->H.unspentind += tx->tx_out; - } - } - else - { - if ( iter == 0 ) - { - for (j=tx->tx_in-1; j>=0; j--) - { - iguana_RTspend(myinfo,coin,RTptr,block,polarity,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->txid,j,tx->vins[j].prev_hash,tx->vins[j].prev_vout); - } - ramchain->H.unspentind += tx->tx_out; - } - else - { - for (j=tx->tx_out-1; j>=0; j--) - iguana_RTvout(coin,polarity,RTptr,block,tx->txid,j,&tx->vouts[j]); - ramchain->H.spendind += tx->tx_in; - } - } - } - } - //printf("scriptoffset.%d after %d txids\n",ramchain->H.scriptoffset,txn_count); - iguana_ramchain_free(coin,ramchain,0); - return(0); - } - iguana_ramchain_free(coin,ramchain,0); - return(-1); -} diff --git a/iguana/iguana_realtime.c b/iguana/iguana_realtime.c index 36b558747..ddd6d1685 100755 --- a/iguana/iguana_realtime.c +++ b/iguana/iguana_realtime.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,457 +16,6 @@ // verify undo cases for hhutxo, and all 4 permutations of setting #include "iguana777.h" -//#define ENABLE_RAMCHAIN - -#ifdef oldway -void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp) -{ - //return; -#ifdef ENABLE_RAMCHAIN - int32_t hdrsi; - //portable_mutex_lock(&coin->RTmutex); - if ( coin->utxotable != 0 ) - { - printf("free RTramchain\n"); - //iguana_utxoupdate(coin,-1,0,0,0,0,-1,0); // free hashtables - coin->lastRTheight = coin->RTheight = 0;//(coin->bundlescount-1) * coin->chain->bundlesize; - coin->RTgenesis = 0; - iguana_utxoaddrs_purge(coin); - iguana_ramchain_free(coin,&coin->RTramchain,1); - if ( bp != 0 ) - bp->ramchain = coin->RTramchain; - iguana_mempurge(&coin->RTmem); - iguana_mempurge(&coin->RThashmem); - for (hdrsi=coin->bundlescount-1; hdrsi>0; hdrsi--) - if ( (bp= coin->bundles[hdrsi]) == 0 && bp != coin->current ) - { - iguana_volatilespurge(coin,&bp->ramchain); - if ( iguana_volatilesmap(coin,&bp->ramchain) != 0 ) - printf("error mapping bundle.[%d]\n",hdrsi); - } - coin->RTdatabad = 0; - printf("done RTramchain\n"); - } - //portable_mutex_unlock(&coin->RTmutex); -#endif -} - -void *iguana_ramchainfile(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block) -{ - //return(0); -#ifdef ENABLE_RAMCHAIN - char fname[1024]; long filesize; int32_t err; void *ptr=0; - if ( block == bp->blocks[bundlei] && (ptr= iguana_bundlefile(coin,fname,&filesize,bp,bundlei)) != 0 ) - { - if ( iguana_mapchaininit(fname,coin,R,bp,bundlei,block,ptr,filesize) >= 0 ) - { - if ( dest != 0 && dest->H.data != 0 ) - err = iguana_ramchain_iterate(myinfo,coin,dest,R,bp,bundlei); - else err = 0; - if ( err != 0 || dest->H.data == 0 || bits256_cmp(R->H.data->firsthash2,block->RO.hash2) != 0 ) - { - char str[65]; - printf("ERROR [%d:%d] %s vs ",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); - printf("mapped.%s\n",bits256_str(str,R->H.data->firsthash2)); - } else return(ptr); - } - iguana_blockunmark(coin,block,bp,bundlei,1); - iguana_ramchain_free(coin,R,1); - } //else printf("ramchainfile ptr.%p block.%p\n",ptr,block); -#endif - return(0); -} - -void iguana_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_bundle *bp) -{ - //return; -#ifdef ENABLE_RAMCHAIN - uint32_t i,changed = 0; struct iguana_ramchaindata *rdata; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; struct iguana_bundle *tmpbp; - //portable_mutex_lock(&coin->RTmutex); - if ( (rdata= dest->H.data) != 0 ) - { - i = 0; - if ( coin->RTheight != coin->lastRTheight ) - changed++; - else - { - B = RAMCHAIN_PTR(rdata,Boffset); - for (i=0; inumblocks; i++) - if ( bits256_cmp(B[i].hash2,bp->hashes[i]) != 0 ) - { - char str[65],str2[65]; printf("mismatched hash2 at %d %s vs %s\n",bp->bundleheight+i,bits256_str(str,B[i].hash2),bits256_str(str2,bp->hashes[i])); - changed++; - iguana_blockunmark(coin,bp->blocks[i],bp,i,1); - break; - } - } - if ( changed != 0 ) - { - printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight,rdata->numblocks); - iguana_RTramchainfree(coin,bp); - } - } - if ( coin->RTramchain.H.data == 0 ) - { - iguana_ramchainopen(fname,coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); - printf("ALLOC RTramchain.(%s) RTrdata %p rdata.%p\n",fname,coin->RTramchain.H.data,bp->ramchain.H.data); - dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; - dest->externalind = dest->H.stacksize = 0; - dest->H.scriptoffset = 1; - if ( 1 ) - { - for (i=0; ihdrsi; i++) - if ( (tmpbp= coin->bundles[i]) != 0 ) - { - iguana_volatilespurge(coin,&tmpbp->ramchain); - iguana_volatilesmap(coin,&tmpbp->ramchain); - } - sleep(1); - } - } - //portable_mutex_unlock(&coin->RTmutex); -#endif -} - -void iguana_rdataset(struct iguana_ramchain *dest,struct iguana_ramchaindata *rdest,struct iguana_ramchain *src) -{ - //return; -#ifdef ENABLE_RAMCHAIN - *dest = *src; - dest->H.data = rdest; - *rdest = *src->H.data; - rdest->numpkinds = src->pkind; - rdest->numexternaltxids = src->externalind; - rdest->numtxids = src->H.txidind; - rdest->numunspents = src->H.unspentind; - rdest->numspends = src->H.spendind; - //printf("RT set numtxids.%u numspends.%u\n",rdest->numtxids,rdest->numspends); -#endif -} - -void iguana_rdatarestore(struct iguana_ramchain *dest,struct iguana_ramchaindata *rdest,struct iguana_ramchain *src) -{ - //return; -#ifdef ENABLE_RAMCHAIN - *src = *dest; - *src->H.data = *rdest; - src->pkind = rdest->numpkinds; - src->externalind = rdest->numexternaltxids; - src->H.txidind = rdest->numtxids; - src->H.unspentind = rdest->numunspents; - src->H.spendind = rdest->numspends; - printf("RT restore numtxids.%u numspends.%u\n",rdest->numtxids,rdest->numspends); -#endif -} - -void iguana_RThdrs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t numaddrs) -{ - //return; -#ifdef ENABLE_RAMCHAIN - int32_t datalen,i; uint8_t serialized[512]; char str[65]; struct iguana_peer *addr; - if ( coin->peers == 0 ) - return; - datalen = iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,bits256_str(str,bp->hashes[0])); - for (i=0; ipeers->numranked; i++) - { - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - if ( coin->chain->hasheaders == 0 ) - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,coin->blocks.hwmchain.RO.hash2)),1); - if ( (addr= coin->peers->ranked[i]) != 0 && addr->usock >= 0 && addr->dead == 0 && datalen > 0 ) - { - iguana_send(coin,addr,serialized,datalen); - //addr->pendhdrs++; - } - } -#endif -} - -void iguana_RTspendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp) -{ - //return; -#ifdef ENABLE_RAMCHAIN - int32_t iterate,lasti,num,hdrsi,orignumemit; struct iguana_ramchain R; struct iguana_ramchaindata RDATA; - if ( bp->hdrsi <= 0 ) - return; - printf("RTspendvectors [%d]\n",bp->hdrsi); - bp->ramchain = coin->RTramchain; - iguana_rdataset(&R,&RDATA,&coin->RTramchain); - if ( (lasti= (coin->RTheight - ((coin->RTheight/bp->n)*bp->n))) >= bp->n-1 ) - lasti = bp->n - 1; - orignumemit = bp->numtmpspends; - iterate = 0; - if ( iguana_spendvectors(myinfo,coin,bp,&coin->RTramchain,coin->RTstarti%coin->chain->bundlesize,lasti,0,iterate) < 0 ) - { - printf("RTutxo error -> RTramchainfree\n"); - coin->RTdatabad = 1; - return; - } - else - { - //printf("RTspendvectors calculated to %d [%d]\n",coin->RTheight,bp->hdrsi); - bp->converted = 1; - for (hdrsi=num=0; hdrsihdrsi; hdrsi++) - { -#ifdef __APPLE__ - if ( coin->bundles[hdrsi]->lastprefetch == 0 ) - { - iguana_ramchain_prefetch(coin,&coin->bundles[hdrsi]->ramchain,2); - coin->bundles[hdrsi]->lastprefetch = (uint32_t)time(NULL); - } -#endif - num += iguana_convert(coin,IGUANA_NUMHELPERS,coin->bundles[hdrsi],1,orignumemit); - } - //printf("RTspendvectors converted.%d to %d\n",num,coin->RTheight); - //iguana_rdatarestore(&R,&RDATA,&bp->ramchain); - bp->converted = (uint32_t)time(NULL); - if ( iguana_balancegen(coin,1,bp,coin->RTstarti,coin->RTheight > 0 ? coin->RTheight-1 : bp->bundleheight+bp->n-1,orignumemit) < 0 ) - { - printf("balancegen error\n"); - coin->RTdatabad = 1; - } - else if ( coin->RTgenesis == 0 && coin->firstRTgenesis == 0 ) - coin->firstRTgenesis++, printf(">>>>>> IGUANA %s READY FOR REALTIME RPC <<<<<<\n",coin->symbol); - //printf("iguana_balancegen [%d] (%d to %d)\n",bp->hdrsi,coin->RTstarti,(coin->RTheight-1)%bp->n); - coin->RTstarti = coin->RTheight; - } -#endif -} - -int32_t iguana_realtime_update(struct supernet_info *myinfo,struct iguana_info *coin) -{ - int32_t flag = 0; - //return(0); -#ifdef ENABLE_RAMCHAIN - double startmillis0; static double totalmillis0; static int32_t num0; - struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t offset,bundlei,i,n; bits256 hash2,*ptr; struct iguana_peer *addr; - struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR; - if ( coin->peers == 0 && coin->virtualchain == 0 ) - return(0); - offset = 0;//(strcmp("BTC",coin->symbol) != 0); - if ( coin->RTheight >= (coin->current->hdrsi+1)*coin->chain->bundlesize ) - { - printf("inversion RT %d >= %d\n",coin->RTheight,(coin->current->hdrsi+1)*coin->chain->bundlesize); - coin->lastRTheight = coin->RTheight = coin->current->hdrsi*coin->chain->bundlesize; - iguana_utxoaddrs_purge(coin); - } - if ( coin->current != 0 && (coin->blocks.hwmchain.height % coin->chain->bundlesize) == coin->chain->bundlesize-1 && coin->blocks.hwmchain.height/coin->chain->bundlesize == coin->longestchain/coin->chain->bundlesize ) - { - block = coin->current->blocks[coin->current->n - 1]; - if ( _iguana_chainlink(coin,block) <= 0 ) - { - printf("RT edge case couldnt link\n"); - } - else - { - printf("RT edge case.%d\n",block->height); - if ( (bp= coin->bundles[coin->RTheight / coin->chain->bundlesize]) != 0 ) - iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,0,0); - iguana_update_balances(coin); - } - } - if ( coin->spendvectorsaved <= 1 ) - { - //printf("%s spendvectorsaved not yet\n",coin->symbol); - usleep(100000); - return(0); - } - //portable_mutex_lock(&coin->RTmutex); - for (i=0; ibundlescount-1; i++) - { - if ( (bp= coin->bundles[i]) != 0 && (i > 0 && bp->utxofinish == 0) && bp != coin->current ) - { - if ( iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,0,0) < 0 ) - { - //portable_mutex_unlock(&coin->RTmutex); - printf("error generating spendvectors.[%d], skipping\n",i); - return(0); - } // else printf("generated UTXO.[%d]\n",i); - coin->spendvectorsaved = 1; - } - } - //portable_mutex_unlock(&coin->RTmutex); - bp = coin->current; - if ( bp == 0 )//|| iguana_validated(coin) < bp->hdrsi ) - { - //printf("bp.%p validated.%d vs hdrsi.%d\n",bp,iguana_validated(coin),bp->hdrsi); - return(0); - } - if ( 0 && coin->RTheight > 0 && coin->spendvectorsaved != 1 && coin->bundlescount-1 != coin->balanceswritten ) - { - printf("RT mismatch %d != %d\n",coin->bundlescount-1,coin->balanceswritten); - iguana_RTramchainfree(coin,coin->current); - coin->spendvectorsaved = 0; - coin->lastRTheight = coin->RTheight = 0; - iguana_utxoaddrs_purge(coin); - /*while ( coin->spendvectorsaved <= 1 ) - { - fprintf(stderr,"wait for spendvectorsaved\n"); - sleep(3); - }*/ - return(0); - } - if ( coin->RTdatabad == 0 && bp->hdrsi >= (coin->longestchain/coin->chain->bundlesize)-1 && bp->hdrsi >= coin->balanceswritten-2 && ((coin->RTheight < coin->blocks.hwmchain.height-offset && time(NULL) > bp->lastRT) || time(NULL) > bp->lastRT+1) ) //coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n && - { - if ( coin->RTheight < bp->hdrsi*coin->chain->bundlesize ) - { - coin->lastRTheight = coin->RTheight = bp->hdrsi*coin->chain->bundlesize; - iguana_utxoaddrs_purge(coin); - } - if ( (block= bp->blocks[0]) == 0 || block->txvalid == 0 || block->mainchain == 0 ) - { - if ( block != 0 ) - { - if ( _iguana_chainlink(coin,block) <= 0 ) - { - iguana_blockunmark(coin,block,bp,0,0); - bp->issued[0] = 0; - hash2 = bp->hashes[0]; - //char str[65]; printf("RT[0] [%d:%d] %s %p\n",bp->hdrsi,0,bits256_str(str,hash2),block); - if ( coin->peers != 0 ) - { - addr = coin->peers->ranked[rand() % 8]; - if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 ) - iguana_sendblockreqPT(coin,addr,bp,0,hash2,0); - } - } - } - } - //char str[65]; printf("check longest.%d RTheight.%d hwm.%d %s %p\n",coin->longestchain,coin->RTheight,coin->blocks.hwmchain.height,bits256_str(str,bp->hashes[0]),block); - if ( bits256_cmp(coin->RThash1,bp->hashes[1]) != 0 ) - coin->RThash1 = bp->hashes[1]; - //bp->lastRT = (uint32_t)time(NULL); - if ( coin->peers != 0 && coin->RTheight <= coin->longestchain-offset && coin->peers->numranked > 0 && time(NULL) > coin->RThdrstime+16 ) - { - iguana_RThdrs(coin,bp,coin->peers->numranked); - coin->RThdrstime = (uint32_t)time(NULL); - } - bp->lastRT = (uint32_t)time(NULL); - iguana_RTramchainalloc("RTbundle",coin,bp); - bp->isRT = 1; - //printf("%s rdata.%p RTheight.%d hwm.%d RTdatabad.%d\n",coin->symbol,coin->RTramchain.H.data,coin->RTheight,coin->blocks.hwmchain.height,coin->RTdatabad); - while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height-offset && coin->RTdatabad == 0 ) - { - dest = &coin->RTramchain; - B = RAMCHAIN_PTR(rdata,Boffset); - bundlei = (coin->RTheight % coin->chain->bundlesize); - if ( (block= iguana_bundleblock(coin,&hash2,bp,bundlei)) != 0 ) - { - iguana_bundlehashadd(coin,bp,bundlei,block); - //printf("RT.%d vs hwm.%d starti.%d bp->n %d block.%p/%p ramchain.%p databad.%d prevnonz.%d\n",coin->RTheight,coin->blocks.hwmchain.height,coin->RTstarti,bp->n,block,bp->blocks[bundlei],dest->H.data,coin->RTdatabad,bits256_nonz(block->RO.prev_block)); - } - else - { - //printf("cant find bundleblock [%d:%d]\n",bp->hdrsi,bundlei); - iguana_blockQ("RTmissing",coin,bp,bundlei,hash2,1); - break; - } - if ( coin->RTdatabad == 0 && block != 0 && (block->height == 0 || bits256_nonz(block->RO.prev_block) != 0) ) - { - //printf("bundlei.%d blockht.%d RTheight.%d\n",bundlei,block->height,coin->RTheight); - iguana_blocksetcounters(coin,block,dest); - startmillis0 = OS_milliseconds(); - if ( iguana_ramchainfile(myinfo,coin,dest,&blockR,bp,bundlei,block) == 0 ) - { - for (i=0; in; i++) - if ( GETBIT(bp->haveblock,i) == 0 ) - bp->issued[i] = 0; - if ( (n= iguana_bundleissuemissing(coin,bp,3,1.)) > 0 ) - printf("RT issued %d priority requests [%d] to unstick stuckiters.%d\n",n,bp->hdrsi,coin->stuckiters); - for (i=bundlei; in; i++) - { - block = iguana_bundleblock(coin,&hash2,bp,i); - if ( bits256_nonz(hash2) != 0 && (block == 0 || block->txvalid == 0) ) - { - uint8_t serialized[512]; int32_t len; struct iguana_peer *addr; - //char str[65]; printf("RT error [%d:%d] %s %p\n",bp->hdrsi,i,bits256_str(str,hash2),block); - if ( coin->peers != 0 ) - { - addr = coin->peers->ranked[rand() % 8]; - if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 && (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) - iguana_send(coin,addr,serialized,len); - } - coin->RTgenesis = 0; - } - if ( bits256_nonz(hash2) != 0 ) - iguana_blockQ("RTerr",coin,bp,i,hash2,1); - //break; - } - return(-1); - } else iguana_ramchain_free(coin,&blockR,1); - B[bundlei] = block->RO; - totalmillis0 += (OS_milliseconds() - startmillis0); - num0++; - flag++; - //coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; - coin->RTheight++; - coin->lastRTheight = coin->RTheight; - //printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); - if ( coin->RTramchain.H.data != 0 ) - coin->RTramchain.H.data->numblocks = bundlei + 1; - else break; - } else break; - } - } - else - { - if ( coin->virtualchain == 0 ) - { - //printf("%s skip RT.(%d %d %d %d %d %d %d %u)\n",coin->symbol,coin->RTdatabad,bp->hdrsi,coin->longestchain/coin->chain->bundlesize,coin->balanceswritten,coin->RTheight,bp->bundleheight,coin->blocks.hwmchain.height,bp->lastRT); - //sleep(1); - } - } - n = 0; - if ( coin->RTdatabad == 0 && dest != 0 && flag != 0 && coin->RTheight >= coin->blocks.hwmchain.height-offset ) - { - printf("ramchainiterate.[%d] ave %.2f micros, total %.2f seconds starti.%d num.%d\n",num0,(totalmillis0*1000.)/num0,totalmillis0/1000.,coin->RTstarti,coin->RTheight%bp->n); - if ( (n= iguana_walkchain(coin,1)) == coin->RTheight-1+offset ) - { - //printf("RTgenesis verified\n"); - if ( (coin->RTheight % coin->chain->bundlesize) > 3 ) - { - //portable_mutex_lock(&coin->RTmutex); - iguana_RTspendvectors(myinfo,coin,bp); - //portable_mutex_unlock(&coin->RTmutex); - coin->RTgenesis = (uint32_t)time(NULL); - } - } - else - { - printf("walkchain error n.%d != %d\n",n,coin->RTheight-1+offset); - coin->RTdatabad = 1; - } - } - if ( dest != 0 && flag != 0 ) - printf("<<<< flag.%d RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld balance %.8f + %.8f - %.8f = supply %.8f\n",flag,coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,dest->H.data!=0?(long)dest->H.data->allocsize:-1,dstr(coin->histbalance),dstr(coin->RTcredits),dstr(coin->RTdebits),dstr(coin->histbalance + coin->RTcredits - coin->RTdebits)); - if ( coin->RTdatabad != 0 ) - { - bits256 lastbundle; - //portable_mutex_lock(&coin->RTmutex); - printf("START DATABAD fixing\n"); - iguana_RTramchainfree(coin,bp); - if ( coin->RTdatabad < 0 ) - { - memset(lastbundle.bytes,0,sizeof(lastbundle)); - iguana_initfinal(myinfo,coin,lastbundle); - } - coin->RTdatabad = 0; - //memset(bp->hashes,0,sizeof(bp->hashes)); - memset(bp->blocks,0,sizeof(bp->blocks)); - if ( 0 && bp->speculative != 0 ) - { - ptr = bp->speculative; - bp->speculative = 0; - memset(ptr,0,sizeof(*bp->speculative)*bp->n); - myfree(ptr,(bp->n+1)*sizeof(*bp->speculative)); - } - iguana_RTramchainalloc("RTbundle",coin,bp); - printf("DONE DATABAD fixing\n"); - //portable_mutex_unlock(&coin->RTmutex); - } -#endif - return(flag); -} -#endif //#define FAST_UTHASH #ifdef FAST_UTHASH @@ -478,13 +27,19 @@ int32_t iguana_realtime_update(struct supernet_info *myinfo,struct iguana_info * void iguana_RTtxid_free(struct iguana_RTtxid *RTptr) { - int32_t i; + int32_t i; struct iguana_RTspend *spend; for (i=0; inumvouts; i++) if ( RTptr->unspents[i] != 0 ) free(RTptr->unspents[i]); for (i=0; inumvins; i++) - if ( RTptr->spends[i] != 0 ) - free(RTptr->spends[i]); + { + if ( (spend= RTptr->spends[i]) != 0 ) + { + if ( spend->bundle_unspent != 0 ) + free(spend->bundle_unspent); + free(spend); + } + } if ( RTptr->rawtxbytes != 0 ) free(RTptr->rawtxbytes); free(RTptr); @@ -520,6 +75,7 @@ void iguana_RTreset(struct iguana_info *coin) #endif printf("%s RTreset %d\n",coin->symbol,coin->RTheight); coin->RTheight = coin->firstRTheight; + coin->RTcredits = coin->RTdebits = 0; } struct iguana_RTaddr *iguana_RTaddrfind(struct iguana_info *coin,uint8_t *rmd160,char *coinaddr) @@ -549,6 +105,32 @@ int64_t iguana_RTbalance(struct iguana_info *coin,char *coinaddr) } } +int64_t iguana_RTnetbalance(struct iguana_info *coin) +{ + struct iguana_RTaddr *RTaddr,*tmp; int64_t RTdebits,RTcredits; + RTdebits = RTcredits = 0; + HASH_ITER(hh,coin->RTaddrs,RTaddr,tmp) + { + RTcredits += RTaddr->credits; + RTdebits += RTaddr->debits; + } + if ( RTcredits != coin->RTcredits || RTdebits != coin->RTdebits ) + printf("RTnetbalance mismatch (%.8f %.8f) != (%.8f %.8f)\n",dstr(RTcredits),dstr(RTdebits),dstr(coin->RTcredits),dstr(coin->RTdebits)); + return(RTcredits - RTdebits); +} + +int32_t iguana_RTbalance_verify(char *str,struct iguana_info *coin) +{ + int64_t balance; + balance = iguana_RTnetbalance(coin); + if ( balance != (coin->RTcredits - coin->RTdebits) ) + { + printf("%s RTbalance %.8f != %.8f (%.8f - %.8f)\n",str,dstr(balance),dstr(coin->RTcredits - coin->RTdebits),dstr(coin->RTcredits),dstr(coin->RTdebits)); + return(-1); + } + return(0); +} + void iguana_RTcoinaddr(struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,char *coinaddr,uint8_t *rmd160,int32_t spendflag,int64_t value,struct iguana_RTunspent *unspent) { struct iguana_RTaddr *RTaddr; int32_t len = (int32_t)strlen(coinaddr); @@ -571,13 +153,14 @@ void iguana_RTcoinaddr(struct iguana_info *coin,struct iguana_RTtxid *RTptr,stru coin->RTcredits += polarity * value; if ( polarity > 0 ) { - //printf("unspent[%d] <- %p\n",RTaddr->numunspents,unspent); + //printf("%s lastunspent[%d] <- %p\n",coinaddr,RTaddr->numunspents,unspent); RTaddr->numunspents++; unspent->prevunspent = RTaddr->lastunspent; RTaddr->lastunspent = unspent; } else if ( polarity < 0 ) { + //printf("%s lastunspent[%d] -> last.%p %p\n",coinaddr,RTaddr->numunspents,RTaddr->lastunspent,unspent); if ( RTaddr->lastunspent == unspent ) { RTaddr->lastunspent = unspent->prevunspent; @@ -586,7 +169,8 @@ void iguana_RTcoinaddr(struct iguana_info *coin,struct iguana_RTtxid *RTptr,stru //RTaddr->unspents[i] = RTaddr->unspents[--RTaddr->numunspents]; } } - if ( 0 && strcmp("BTC",coin->symbol) != 0 && strcmp("LTC",coin->symbol) != 0 && strcmp("DOGE",coin->symbol) != 0 ) + //printf("%s %.8f [%.8f - %.8f] -> %.8f\n",coinaddr,dstr(value),dstr(coin->RTcredits),dstr(coin->RTdebits),dstr(coin->histbalance)+dstr(coin->RTcredits)-dstr(coin->RTdebits)); + if ( (0) && strcmp("BTC",coin->symbol) != 0 && strcmp("LTC",coin->symbol) != 0 && strcmp("DOGE",coin->symbol) != 0 ) printf("%lld %s %.8f h %.8f, cr %.8f deb %.8f [%.8f] numunspents.%d %p\n",(long long)polarity,coinaddr,dstr(value),dstr(RTaddr->histbalance),dstr(RTaddr->credits),dstr(RTaddr->debits),dstr(RTaddr->credits)-dstr(RTaddr->debits)+dstr(RTaddr->histbalance),RTaddr->numunspents,unspent); } @@ -630,8 +214,6 @@ void iguana_RTunspent(struct iguana_info *coin,struct iguana_RTtxid *RTptr,struc return; } } - if ( (unspent->spend == 0 && polarity < 0) || (unspent->spend != 0 && polarity > 0) ) - printf("unspent spend.%p opposite when polarity.%lld\n",unspent->spend,(long long)polarity); iguana_RTcoinaddr(coin,RTptr,block,polarity,coinaddr,unspent->rmd160,0,value,unspent); if ( polarity < 0 ) RTptr->unspents[vout] = 0; @@ -646,9 +228,25 @@ void iguana_RTunspent(struct iguana_info *coin,struct iguana_RTtxid *RTptr,struc //fprintf(stderr,","); } -void iguana_RTspend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vini,bits256 prev_hash,int32_t prev_vout) +void iguana_RTvout_create(struct iguana_info *coin,int64_t polarity,struct iguana_RTtxid *RTptr,struct iguana_block *block,bits256 txid,int32_t j,struct iguana_msgvout *vout) { - struct iguana_RTspend *spend; struct iguana_RTtxid *spentRTptr; struct iguana_RTunspent *unspent=0; char str[65],str2[65],coinaddr[64]; uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint32_t unspentind; int32_t spendlen,height; uint64_t value; struct iguana_outpoint spentpt; + int32_t scriptlen,type,k; uint8_t *script; struct vin_info V; char coinaddr[64]; + script = vout->pk_script; + scriptlen = vout->pk_scriptlen; + type = iguana_calcrmd160(coin,0,&V,script,scriptlen,txid,j,0xffffffff); + if ( (type == 12 && scriptlen == 0) || (type == 1 && bitcoin_pubkeylen(script+1) <= 0) ) + { + for (k=0; kchain->pubtype,V.rmd160,sizeof(V.rmd160)); + iguana_RTunspent(coin,RTptr,block,polarity,coinaddr,V.rmd160,type,script,scriptlen,txid,j,vout->value); +} + +void iguana_RTspend_create(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vini,bits256 prev_hash,int32_t prev_vout) +{ + struct iguana_RTspend *spend; struct iguana_RTtxid *spentRTptr; struct iguana_RTunspent *unspent=0; char str[65],str2[65],coinaddr[64]; uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint32_t unspentind; int32_t spendlen,height; uint64_t RTspent,value; struct iguana_outpoint spentpt; //printf("RTspend %s vini.%d spend.(%s/v%d) %lld\n",bits256_str(str,txid),vini,bits256_str(str2,prev_hash),prev_vout,(long long)polarity); if ( vini == 0 && bits256_nonz(prev_hash) == 0 && prev_vout < 0 ) return; @@ -689,27 +287,31 @@ void iguana_RTspend(struct supernet_info *myinfo,struct iguana_info *coin,struct } else { - if ( (unspentind= iguana_unspentindfind(myinfo,coin,coinaddr,spendscript,&spendlen,&value,&height,prev_hash,prev_vout,coin->bundlescount,0)) == 0 ) + if ( (unspentind= iguana_unspentindfind(myinfo,coin,&RTspent,coinaddr,spendscript,&spendlen,&value,&height,prev_hash,prev_vout,coin->bundlescount,0)) == 0 ) printf("iguana_RTspend cant find spentRTptr.(%s) search history\n",bits256_str(str,prev_hash)); else { int32_t spentheight,lockedflag,RTspentflag; bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); - //printf("found unspentind (%s %.8f).%d spendlen.%d\n",coinaddr,dstr(value),addrtype,spendlen); unspent = iguana_RTunspent_create(rmd160,value,spendscript,spendlen>0?spendlen:0,0,prev_vout); memset(&spentpt,0,sizeof(spentpt)); + spentpt.txid = prev_hash; + spentpt.vout = prev_vout; spentpt.unspentind = unspentind; spentpt.hdrsi = height / coin->chain->bundlesize; + spentpt.value = value; iguana_RTutxofunc(coin,&spentheight,&lockedflag,spentpt,&RTspentflag,0,RTptr->height); + spend->bundle_unspent = unspent; } } if ( unspent != 0 ) { - bitcoin_address(coinaddr,coin->chain->pubtype,unspent->rmd160,sizeof(unspent->rmd160)); - iguana_RTcoinaddr(coin,RTptr,block,polarity,coinaddr,unspent->rmd160,1,unspent->value,unspent); if ( polarity < 0 ) unspent->spend = 0; - else unspent->spend = spend; + bitcoin_address(coinaddr,coin->chain->pubtype,unspent->rmd160,sizeof(unspent->rmd160)); + iguana_RTcoinaddr(coin,RTptr,block,polarity,coinaddr,unspent->rmd160,1,unspent->value,unspent); + if ( polarity > 0 ) + unspent->spend = spend; } } } else printf("iguana_RTspend txid mismatch %llx != %llx\n",(long long)RTptr->txid.txid,(long long)txid.txid); @@ -742,15 +344,16 @@ struct iguana_RTtxid *iguana_RTtxid_create(struct iguana_info *coin,struct iguan RTptr->version = version; RTptr->timestamp = timestamp; RTptr->unspents = (void *)&RTptr->spends[numvins]; - if ( txlen > 0 ) + if ( txlen > 0 && txlen < IGUANA_MAXPACKETSIZE ) { RTptr->rawtxbytes = malloc(txlen); RTptr->txlen = txlen; memcpy(RTptr->rawtxbytes,serialized,txlen); } HASH_ADD_KEYPTR(hh,coin->RTdataset,RTptr->txid.bytes,sizeof(RTptr->txid),RTptr); - if ( 0 && strcmp("BTC",coin->symbol) != 0 ) - printf("%s txid.(%s) vouts.%d vins.%d version.%d lock.%u t.%u %lld\n",coin->symbol,bits256_str(str,txid),numvouts,numvins,version,locktime,timestamp,(long long)polarity); + bits256_str(str,txid); + if ( (0) && strcmp("BTC",coin->symbol) != 0 ) + printf("%s.%d txid.(%s) vouts.%d vins.%d version.%d lock.%u t.%u %lld\n",coin->symbol,block->height,str,numvouts,numvins,version,locktime,timestamp,(long long)polarity); } else if ( RTptr->txn_count != txn_count || RTptr->numvouts != numvouts || RTptr->numvins != numvins ) { @@ -763,17 +366,61 @@ struct iguana_RTtxid *iguana_RTtxid_create(struct iguana_info *coin,struct iguan return(RTptr); } -int64_t _RTgettxout(struct iguana_info *coin,int32_t *height,int32_t *scriptlen,uint8_t *script,uint8_t *rmd160,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool) +int32_t iguana_RTramchaindata(struct supernet_info *myinfo,struct iguana_info *coin,int64_t polarity,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t txn_count) +{ + struct iguana_msgtx *tx; struct iguana_RTtxid *RTptr; int32_t i,j; + if ( block->RO.txn_count != txn_count ) + { + printf("txn_count mismatch ht.%d %d != %d\n",block->height,block->RO.txn_count,txn_count); + return(-1); + } + if ( polarity > 0 ) + { + for (i=0; itxid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,tx->serialized,tx->allocsize); + for (j=0; jtx_out; j++) + iguana_RTvout_create(coin,polarity,RTptr,block,tx->txid,j,&tx->vouts[j]); + for (j=0; jtx_in; j++) + iguana_RTspend_create(myinfo,coin,RTptr,block,polarity,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->txid,j,tx->vins[j].prev_hash,tx->vins[j].prev_vout); + } + } + else + { + for (i=txn_count-1; i>=0; i--) + { + tx = &txarray[i]; + RTptr = iguana_RTtxid_create(coin,block,polarity,i,txn_count,tx->txid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,tx->serialized,tx->allocsize); + for (j=tx->tx_in-1; j>=0; j--) + { + iguana_RTspend_create(myinfo,coin,RTptr,block,polarity,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->txid,j,tx->vins[j].prev_hash,tx->vins[j].prev_vout); + } + for (j=tx->tx_out-1; j>=0; j--) + iguana_RTvout_create(coin,polarity,RTptr,block,tx->txid,j,&tx->vouts[j]); + } + } + return(0); +} + +int64_t _RTgettxout(struct iguana_info *coin,struct iguana_RTtxid **ptrp,int32_t *heightp,int32_t *scriptlenp,uint8_t *script,uint8_t *rmd160,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool) { - int64_t value = 0; struct iguana_RTtxid *RTptr; struct iguana_RTunspent *unspent = 0; + int32_t scriptlen; int64_t value = 0; struct iguana_RTtxid *RTptr; struct iguana_RTunspent *unspent = 0; HASH_FIND(hh,coin->RTdataset,txid.bytes,sizeof(txid),RTptr); - if ( RTptr != 0 && (RTptr->height <= coin->blocks.hwmchain.height || mempool != 0) ) + *ptrp = RTptr; + *heightp = -1; + if ( scriptlenp == 0 ) + scriptlenp = &scriptlen; + *scriptlenp = 0; + memset(rmd160,0,20); + coinaddr[0] = 0; + if ( RTptr != 0 )// && (RTptr->height <= coin->blocks.hwmchain.height || mempool != 0) ) { if ( vout >= 0 && vout < RTptr->txn_count && (unspent= RTptr->unspents[vout]) != 0 ) { - *height = RTptr->height; - if ( (*scriptlen= unspent->scriptlen) > 0 ) - memcpy(script,unspent->script,*scriptlen); + *heightp = RTptr->height; + if ( script != 0 && unspent->spend == 0 && (*scriptlenp= unspent->scriptlen) > 0 ) + memcpy(script,unspent->script,*scriptlenp); memcpy(rmd160,unspent->rmd160,sizeof(unspent->rmd160)); bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,sizeof(unspent->rmd160)); value = unspent->value; @@ -782,20 +429,6 @@ int64_t _RTgettxout(struct iguana_info *coin,int32_t *height,int32_t *scriptlen, return(value); } -int32_t iguana_RTunspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *spendlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool) -{ - char _coinaddr[64]; uint8_t rmd160[20]; int64_t value; - if ( coinaddr == 0 ) - coinaddr = _coinaddr; - if ( (value= _RTgettxout(coin,heightp,spendlenp,spendscript,rmd160,coinaddr,txid,vout,mempool)) > 0 ) - { - if ( valuep != 0 ) - *valuep = value; - return(0); - } - else return(iguana_unspentindfind(myinfo,coin,coinaddr,spendscript,spendlenp,valuep,heightp,txid,vout,lasthdrsi,mempool)); -} - int32_t _iguana_RTunspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,struct iguana_outpoint outpt,int64_t value) { int32_t spendlen = 0; struct iguana_RTunspent *unspent; struct iguana_RTtxid *parent; @@ -811,6 +444,129 @@ int32_t _iguana_RTunspentfind(struct supernet_info *myinfo,struct iguana_info *c return(spendlen); } +int32_t iguana_RTunspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint *outpt,char *coinaddr,uint8_t *spendscript,int32_t *spendlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool) +{ + char _coinaddr[64]; struct iguana_RTtxid *ptr; uint8_t rmd160[20]; uint64_t value,RTspend; uint32_t unspentind; + if ( coinaddr == 0 ) + coinaddr = _coinaddr; + memset(outpt,0,sizeof(*outpt)); + if ( (value= _RTgettxout(coin,&ptr,heightp,spendlenp,spendscript,rmd160,coinaddr,txid,vout,mempool)) > 0 ) + { + outpt->ptr = ptr; + if ( valuep != 0 ) + { + *valuep = value; + outpt->value = *valuep; + } + return(0); + } + else + { + if ( (unspentind= iguana_unspentindfind(myinfo,coin,&RTspend,coinaddr,spendscript,spendlenp,valuep,heightp,txid,vout,lasthdrsi,mempool)) != 0 ) + { + char str[65]; + if ( unspentind == 0xffffffff ) + printf("neg 1 unspentind? %s/v%d\n",bits256_str(str,txid),vout); + if ( valuep != 0 && *valuep == 0 ) + *valuep = RTspend; + outpt->hdrsi = *heightp / coin->chain->bundlesize; + outpt->unspentind = unspentind; + if ( valuep != 0 ) + outpt->value = *valuep; + return(0); + } + return(-1); + } +} + +int32_t iguana_outptset(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint *outpt,bits256 txid,int32_t vout,int64_t value,char *spendscriptstr) +{ + int32_t spendlen; + memset(outpt,0,sizeof(*outpt)); + spendlen = (int32_t)strlen(spendscriptstr) >> 1; + if ( spendlen > sizeof(outpt->spendscript) ) + return(-1); + outpt->spendlen = spendlen; + decode_hex(outpt->spendscript,spendlen,spendscriptstr); + outpt->txid = txid; + outpt->vout = vout; + outpt->value = value; + return(0); +} + +int32_t iguana_txidheight(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid) +{ + struct iguana_outpoint outpt; int32_t spendlen,height = 0; uint64_t value; char coinaddr[64]; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE]; + iguana_RTunspentindfind(myinfo,coin,&outpt,coinaddr,spendscript,&spendlen,&value,&height,txid,0,(coin->firstRTheight/coin->chain->bundlesize) - 1,0); + return(height); +} + +int64_t iguana_txidamount(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout) +{ + struct iguana_outpoint outpt; int32_t spendlen,height = 0; uint64_t value; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE]; + iguana_RTunspentindfind(myinfo,coin,&outpt,coinaddr,spendscript,&spendlen,&value,&height,txid,vout,(coin->firstRTheight/coin->chain->bundlesize) - 1,0); + return(value); +} + +char *iguana_txidcategory(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr,bits256 txid,int32_t vout) +{ + struct iguana_outpoint outpt; struct iguana_waccount *wacct; struct iguana_waddress *waddr; int32_t ismine=0,spendlen,height = 0; uint64_t value; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE]; + coinaddr[0] = 0; + iguana_RTunspentindfind(myinfo,coin,&outpt,coinaddr,spendscript,&spendlen,&value,&height,txid,vout,(coin->firstRTheight/coin->chain->bundlesize) - 1,0); + account[0] = 0; + if ( coinaddr[0] != 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) + { + if ( waddr->scriptlen != 0 ) + return("isp2sh"); + else if ( waddr->wifstr[0] != 0 ) + ismine = 1; + if ( wacct != 0 ) + strcpy(account,wacct->account); + } + } else account[0] = 0; + if ( value != 0 ) + { + if ( spendlen == 0 ) + { + if ( ismine != 0 ) + return("send"); + else return("spent"); + } + else + { + if ( ismine != 0 ) + return("receive"); + else return("unspent"); + } + } else return("unknown"); +} + +int32_t iguana_scriptsigextract(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *script,int32_t maxsize,bits256 txid,int32_t vini) +{ + return(-1); +} + +int32_t iguana_vinifind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *spentfrom,bits256 txid,int32_t vout) +{ + int32_t vini = -1; //char *txbytes; char str[65]; cJSON *txobj; + memset(spentfrom,0,sizeof(*spentfrom)); + /*if ( (txbytes= iguana_txbytes(myinfo,swap->bobcoin,txid)) != 0 ) + { + if ( (txobj= iguana_hex2json(myinfo,swap->bobcoin,txbytes)) != 0 ) + { + if ( (vins= jarray(&n,txobj,"vins")) != 0 && vini < n ) + { + + } else printf("iguana_vinifind no vins.%p or illegal vini.%d vs n.%d\n",txobj,vini,n); + free_json(txobj); + } else printf("iguana_vinifind couldnt parse %s.(%s)\n",swap->bobcoin->symbol,txbytes); + free(txbytes); + } else printf("iguana_vinifind cant get txbytes for %s.(%s)\n",swap->bobcoin->symbol,bits256_str(str,txid));*/ + return(vini); +} + void iguana_RTunmap(uint8_t *ptr,uint32_t len) { OS_releasemap(&ptr[-2*sizeof(len)],len+2*sizeof(len)); @@ -839,7 +595,7 @@ void *iguana_RTrawdata(struct iguana_info *coin,bits256 hash2,uint8_t *data,int3 return((void *)"already have rawdata"); return(0); } - //printf("len.%d filesize.%ld\n",len,filesize); + printf("malformed delete.(%s) len.%d filesize.%ld\n",fname,len,filesize); fclose(fp); OS_removefile(fname,0); } @@ -874,6 +630,11 @@ void *iguana_RTrawdata(struct iguana_info *coin,bits256 hash2,uint8_t *data,int3 return(&ptr[sizeof(*recvlenp) + sizeof(checknumtx)]); } else printf("checklen.%d vs %d, checknumtx %d vs %d\n",checklen,(int32_t)(filesize - sizeof(checklen) - sizeof(checknumtx)),checknumtx,*numtxp); } + else if ( (0) ) + { + OS_removefile(fname,0); + printf("(%s) removed to suppress errors\n",fname); + } } } return(0); @@ -897,24 +658,37 @@ void iguana_RTpurge(struct iguana_info *coin,int32_t lastheight) int32_t iguana_RTiterate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t offset,struct iguana_block *block,int64_t polarity) { - struct iguana_txblock txdata; uint8_t *serialized; struct iguana_bundle *bp; int32_t hdrsi,bundlei,height,i,n,errs=0,numtx,num,len; int32_t recvlen = 0; + struct iguana_txblock txdata; uint8_t *serialized; struct iguana_bundle *bp; int32_t hdrsi,bundlei,height,i,n,numtx,num,len; int32_t recvlen = 0; if ( (numtx= coin->RTnumtx[offset]) == 0 || (serialized= coin->RTrawdata[offset]) == 0 || (recvlen= coin->RTrecvlens[offset]) == 0 ) { - char str[65]; + //char str[65]; //printf("errs.%d cant load %s ht.%d polarity.%lld numtx.%d %p recvlen.%d\n",errs,bits256_str(str,block->RO.hash2),block->height,(long long)polarity,coin->RTnumtx[offset],coin->RTrawdata[offset],coin->RTrecvlens[offset]); coin->RTrecvlens[offset] = 0; coin->RTrawdata[offset] = iguana_RTrawdata(coin,block->RO.hash2,0,&coin->RTrecvlens[offset],&coin->RTnumtx[offset],0); if ( (numtx= coin->RTnumtx[offset]) == 0 || (serialized= coin->RTrawdata[offset]) == 0 || (recvlen= coin->RTrecvlens[offset]) == 0 ) { - printf("%s errs.%d cant load %s ht.%d polarity.%lld numtx.%d %p recvlen.%d\n",coin->symbol,errs,bits256_str(str,block->RO.hash2),block->height,(long long)polarity,coin->RTnumtx[offset],coin->RTrawdata[offset],coin->RTrecvlens[offset]); - struct iguana_peer *addr; - iguana_blockQ("RTiterate",coin,0,-1,block->RO.hash2,1); - if ( coin->peers != 0 && coin->peers->numranked > 0 ) + //char str[65]; printf("%s cant load %s ht.%d polarity.%lld numtx.%d %p recvlen.%d\n",coin->symbol,bits256_str(str,block->RO.hash2),block->height,(long long)polarity,coin->RTnumtx[offset],coin->RTrawdata[offset],coin->RTrecvlens[offset]); + struct iguana_peer *addr; // int32_t errs = 0; + iguana_blockhashset("RTblock",coin,coin->firstRTheight+offset,block->RO.hash2,1); + if ( (bp= coin->bundles[block->hdrsi]) != 0 ) { - for (i=0; ipeers->numranked&&i<8; i++) - if ( (addr= coin->peers->ranked[i]) != 0 ) - iguana_sendblockreqPT(coin,addr,0,-1,block->RO.hash2,1); + bp->issued[block->bundlei] = 0; + bp->blocks[block->bundlei] = block; + bp->hashes[block->bundlei] = block->RO.hash2; + block->height = coin->firstRTheight+offset; + if ( coin->peers != 0 ) + { + if ( coin->peers->numranked > 0 ) + { + for (i=0; ipeers->numranked&&i<8; i++) + if ( (addr= coin->peers->ranked[i]) != 0 ) + { + iguana_sendblockreqPT(coin,addr,coin->bundles[block->hdrsi],block->bundlei,block->RO.hash2,1); + } + } else iguana_updatemetrics(myinfo,coin); + } } + iguana_blockQ("RTiterate",coin,bp,block->bundlei,block->RO.hash2,1); num = 0; for (height=block->height+1; height<=coin->blocks.hwmchain.height; height++) { @@ -927,7 +701,7 @@ int32_t iguana_RTiterate(struct supernet_info *myinfo,struct iguana_info *coin,i { num++; iguana_blockQ("RTiterate",coin,0,-1,block->RO.hash2,1); - if ( coin->peers != 0 && (n= coin->peers->numranked) > 0 ) + if ( (0) && coin->peers != 0 && (n= coin->peers->numranked) > 0 ) { if ( (addr= coin->peers->ranked[rand() % n]) != 0 ) iguana_sendblockreqPT(coin,addr,0,-1,block->RO.hash2,1); @@ -935,29 +709,25 @@ int32_t iguana_RTiterate(struct supernet_info *myinfo,struct iguana_info *coin,i } } } - printf("issue missing %d to ht.%d\n",num,height); + //printf("issue missing %d to ht.%d\n",num,height); return(-1); } } - printf("%s RTiterate.%lld offset.%d numtx.%d len.%d\n",coin->symbol,(long long)polarity,offset,coin->RTnumtx[offset],coin->RTrecvlens[offset]); + char str[65]; + if ( block->height > coin->maxRTheight ) + { + coin->maxRTheight = block->height; + printf("%s.%d %.8f [%.8f %.8f] RTiterate.%lld %d tx.%d len.%d %s\n",coin->symbol,block->height,dstr(coin->histbalance)+dstr(coin->RTcredits)-dstr(coin->RTdebits),dstr(coin->RTcredits),dstr(coin->RTdebits),(long long)polarity,offset,coin->RTnumtx[offset],coin->RTrecvlens[offset],bits256_str(str,block->RO.hash2)); + } if ( coin->RTrawmem.ptr == 0 ) iguana_meminit(&coin->RTrawmem,"RTrawmem",0,IGUANA_MAXPACKETSIZE * 2,0); - if ( coin->RTmem.ptr == 0 ) - iguana_meminit(&coin->RTmem,"RTmem",0,IGUANA_MAXPACKETSIZE * 2,0); - if ( coin->RThashmem.ptr == 0 ) - iguana_meminit(&coin->RThashmem,"RThashmem",0,IGUANA_MAXPACKETSIZE * 2,0); - iguana_memreset(&coin->RTrawmem), iguana_memreset(&coin->RTmem), iguana_memreset(&coin->RThashmem); memset(&txdata,0,sizeof(txdata)); - //extern int32_t debugtest; - //debugtest = 1; - //fprintf(stderr,"T"); - if ( (n= iguana_gentxarray(coin,&coin->RTrawmem,&txdata,&len,serialized,recvlen)) > 0 ) + iguana_memreset(&coin->RTrawmem); + if ( (n= iguana_gentxarray(myinfo,coin,&coin->RTrawmem,&txdata,&len,serialized,recvlen)) > 0 ) { - //fprintf(stderr,"R"); - iguana_RTramchaindata(myinfo,coin,&coin->RTmem,&coin->RThashmem,polarity,block,coin->RTrawmem.ptr,numtx); + iguana_RTramchaindata(myinfo,coin,polarity,block,coin->RTrawmem.ptr,numtx); return(0); } else printf("gentxarray n.%d RO.txn_count.%d recvlen.%d\n",n,numtx,recvlen); - //debugtest = 0; iguana_RTreset(coin); return(-1); } @@ -1022,15 +792,37 @@ int32_t iguana_RTblocksub(struct supernet_info *myinfo,struct iguana_info *coin, void iguana_RTnewblock(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block) { - int32_t i,n,height,hdrsi,bundlei; struct iguana_block *addblock,*subblock; struct iguana_bundle *bp; + int32_t i,n,height,hdrsi,bundlei; struct iguana_block *addblock=0,*subblock=0; struct iguana_bundle *bp; + if ( coin->RTreset_needed != 0 ) + { + printf("RTreset_needed -> RTreset\n"); + iguana_RTreset(coin); + coin->RTreset_needed = 0; + } + iguana_RTbalance_verify("start iterate",coin); + /*if ( strcmp(coin->symbol,"BTC") != 0 && strcmp(coin->symbol,"LTC") != 0 ) + { + if ( block->height < coin->firstRTheight+coin->minconfirms ) + return; + if ( (block= iguana_blockfind("RTnew",coin,iguana_blockhash(coin,block->height-coin->minconfirms))) == 0 ) + return; + }*/ if ( block->height < coin->firstRTheight || block->height >= coin->firstRTheight+sizeof(coin->RTblocks)/sizeof(*coin->RTblocks) ) { - if ( coin->firstRTheight > 0 ) + if ( (0) && coin->firstRTheight > 0 ) printf("iguana_RTnewblock illegal blockheight.%d\n",block->height); return; } - if ( block != 0 && coin->RTheight > 0 && coin->RTheight <= coin->blocks.hwmchain.height ) + if ( block != 0 && coin->RTheight > 0 && coin->utxoaddrtable != 0 )//&& coin->RTheight <= coin->blocks.hwmchain.height ) { + /*if ( block->height < (coin->RTheight - coin->minconfirms) ) + { + printf("ht.%d > RT.%d - %d\n",block->height,coin->RTheight,coin->minconfirms); + return; + }*/ + if ( (block= iguana_blockfind("RTnew",coin,iguana_blockhash(coin,block->height-coin->minconfirms+1))) == 0 ) + return; + // error check to bundle boundary portable_mutex_lock(&coin->RTmutex); if ( block->height > coin->lastRTheight ) { @@ -1044,15 +836,26 @@ void iguana_RTnewblock(struct supernet_info *myinfo,struct iguana_info *coin,str { if ( iguana_RTblockadd(myinfo,coin,addblock) < 0 ) break; + //if ( iguana_RTblocksub(myinfo,coin,addblock) < 0 ) + // break; + //if ( iguana_RTblockadd(myinfo,coin,addblock) < 0 ) + // break; coin->lastRTheight = addblock->height; } else { - printf("missing RTaddblock at i.%d RTheight.%d vs %p %d\n",i,coin->RTheight,addblock,addblock!=0?addblock->height:-1); + char str[65]; + if ( addblock != 0 ) + bits256_str(str,addblock->RO.hash2); + else str[0] = 0; + printf("mismatched RTaddblock at i.%d RTheight.%d vs %p %d %s\n",i,coin->RTheight,addblock,addblock!=0?addblock->height:-1,str); + iguana_blockunmark(coin,addblock,bp,bundlei,0); break; } } coin->RTheight += i; + //if ( coin->RTheight != coin->lastRTheight+1 ) + // printf("ERROR: "); //printf("%s >= RTnewblock RTheight %d prev %d\n",coin->symbol,coin->RTheight,coin->lastRTheight); } else if ( block->height == coin->lastRTheight ) @@ -1061,6 +864,7 @@ void iguana_RTnewblock(struct supernet_info *myinfo,struct iguana_info *coin,str { if ( iguana_RTblocksub(myinfo,coin,subblock) < 0 || iguana_RTblockadd(myinfo,coin,block) < 0 ) { + printf("error unwinding to current %d\n",coin->RTheight); portable_mutex_unlock(&coin->RTmutex); return; } @@ -1069,38 +873,29 @@ void iguana_RTnewblock(struct supernet_info *myinfo,struct iguana_info *coin,str } else { - if ( block->height < coin->firstRTheight ) - { - if ( coin->lastRTheight > 0 ) - printf("%s ht.%d reorg past firstRTheight.%d\n",coin->symbol,block->height,coin->firstRTheight); - iguana_RTreset(coin); - } - else - { - while ( coin->lastRTheight >= block->height ) - { - if ( iguana_RTblocksub(myinfo,coin,iguana_RTblock(coin,coin->lastRTheight--)) < 0 ) - { - coin->RTheight = coin->lastRTheight+1; - portable_mutex_unlock(&coin->RTmutex); - return; - } - } - coin->RTheight = coin->lastRTheight+1; - if ( iguana_RTblockadd(myinfo,coin,block) < 0 ) - { - portable_mutex_unlock(&coin->RTmutex); - return; - } - coin->lastRTheight = block->height; - coin->RTheight = coin->lastRTheight+1; - } + char str[65]; printf("reorg RTheight.%d vs block.%d %s\n",coin->RTheight,block->height,bits256_str(str,block->RO.hash2)); + iguana_RTreset(coin); + /*while ( coin->RTheight > block->height ) + { + if ( iguana_RTblocksub(myinfo,coin,iguana_RTblock(coin,coin->RTheight-1)) < 0 ) + { + printf("error subtracting %d\n",coin->RTheight-1); + coin->lastRTheight = coin->RTheight-1; + portable_mutex_unlock(&coin->RTmutex); + return; + } + coin->RTheight--; + } + if ( iguana_RTblockadd(myinfo,coin,block) < 0 ) + { + printf("error adding %d\n",block->height); + portable_mutex_unlock(&coin->RTmutex); + return; + } + coin->lastRTheight = block->height; + coin->RTheight = coin->lastRTheight+1;*/ } portable_mutex_unlock(&coin->RTmutex); - //block = iguana_blockfind("next",coin,iguana_blockhash(coin,block->height+1)); } + iguana_RTbalance_verify("end iterate",coin); } - -// infinite loops at bundle boundary? -// >= RTnewblock RTheight 1254001 prev 1254000 -// B errs.0 cant load 15102564820405cd16506d2731567453c437af07cdd5954bc21b32304e39b1d4 ht.1254001 polarity.1 numtx.0 (nil) recvlen.0 diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 6bd9d4e66..d7426af08 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -25,7 +25,7 @@ struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana struct iguana_bundlereq *req; int32_t allocsize; if ( data == 0 ) datalen = 0; - allocsize = (uint32_t)sizeof(*req) + datalen; + allocsize = (uint32_t)sizeof(*req) + datalen + 64; req = mycalloc(type,1,allocsize); req->allocsize = allocsize; req->datalen = datalen; @@ -63,35 +63,29 @@ int32_t iguana_speculativesearch(struct iguana_info *coin,struct iguana_block ** int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe) { static bits256 lastreq,lastreq2; - int32_t len,j,n,recvlen,numtx; struct iguana_bundle *checkbp; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; struct iguana_block *block=0; + int32_t len,j,n; struct iguana_bundle *checkbp; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; struct iguana_block *block=0; char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); if ( addr == 0 && coin->peers != 0 && (n= coin->peers->numranked) > 0 ) addr = coin->peers->ranked[rand() % n]; if ( addr == 0 || addr->pendblocks > coin->MAXPENDINGREQUESTS ) return(0); + if ( addr->usock < 0 ) + return(0); if ( memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { //printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); - if ( iamthreadsafe == 0 && (rand() % 10 ) != 0 ) + if ( iamthreadsafe == 0 && (rand() % 10) != 0 ) return(0); } - if ( addr->usock < 0 ) - return(0); checkbp = 0, j = -2; - if ( (checkbp= iguana_bundlefind(coin,&checkbp,&j,hash2)) != 0 && j >= 0 && j < checkbp->n ) + if ( (checkbp= iguana_bundlefind(coin,&checkbp,&j,hash2)) != 0 && j >= 0 && j < checkbp->n && checkbp != coin->current ) { - if ( checkbp->emitfinish != 0 || ((block= checkbp->blocks[j]) != 0 && block->txvalid != 0 && block->mainchain != 0 && block->valid != 0) ) - { - //char str[65]; - recvlen = numtx = 0; - if ( iguana_RTrawdata(coin,hash2,0,&recvlen,&numtx,1) != 0 ) - { - //printf("found valid [%d:%d] in blockreqPT\n",checkbp->hdrsi,j); - return(0); - } //else printf("no RTrawdata for %s\n",bits256_str(str,hash2)); - } + if ( checkbp->utxofinish != 0 || ((block= checkbp->blocks[j]) != 0 && block->txvalid != 0 && block->mainchain != 0 && block->valid != 0 && block->bundlei != 0 && coin->RTheight == 0) ) + return(0); } - if ( 0 && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 ) + if ( checkbp != bp || j != bundlei ) + bp = 0, bundlei = -1; + if ( (0) && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 ) { if ( block != 0 && block->hdrsi != 0 && block->bundlei != 0 ) { @@ -109,24 +103,31 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, } if ( addr->msgcounts.verack == 0 ) { - if ( (rand() % 100) == 0 ) + if ( (rand() % 10000) == 0 ) printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); //iguana_send_version(coin,addr,coin->myservices); - return(-1); + //return(-1); } lastreq2 = lastreq; lastreq = hash2; if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) { - iguana_send(coin,addr,serialized,len); coin->numreqsent++; addr->pendblocks++; addr->pendtime = (uint32_t)time(NULL); if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) + { + if ( coin->RTheight == 0 && bp != coin->current && bp->issued[bundlei] > 1 && addr->pendtime < bp->issued[bundlei]+7 ) + { + //printf("SKIP.(%s) [%d:%d] %s n.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1,addr->ipaddr,addr->pendblocks); + return(0); + } bp->issued[bundlei] = addr->pendtime; + } + iguana_send(coin,addr,serialized,len); if ( block != 0 ) block->issued = addr->pendtime; - if ( 0 && coin->current == bp ) + if ( (0) && coin->current == bp ) printf("REQ.(%s) [%d:%d] %s n.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1,addr->ipaddr,addr->pendblocks); } else printf("MSG_BLOCK null datalen.%d\n",len); return(len); @@ -184,7 +185,7 @@ void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,st req->datalen = datalen; req->txid = tx->txid; memcpy(req->serializeddata,data,datalen); - queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); } #ifdef later @@ -266,7 +267,7 @@ int32_t iguana_speculativefind(struct iguana_info *coin,struct iguana_bundle *bp for (j=numcached=0; jn; j++) if ( bp->speculativecache[j] != 0 ) numcached++; - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("cache %s [%d:%d] h.%d s.%d c.%d -> %d\n",bits256_str(str,block->RO.hash2),bp->hdrsi,i,bp->numhashes,bp->numsaved,bp->numcached,numcached); return(i); } @@ -298,7 +299,6 @@ void iguana_bundletime(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starttime = block->issued; if ( starttime == 0 || bp->issued[bundlei] > block->issued ) starttime = bp->issued[bundlei]; - bp->issued[bundlei] = 1; if ( starttime != 0 ) { duration = (uint32_t)time(NULL) - starttime; @@ -312,13 +312,13 @@ void iguana_bundletime(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bp->totaldurations += duration; bp->durationscount++; } - if ( (block= bp->blocks[bundlei]) != 0 && block->lag == 0 ) + if ( (block != 0 || (block= bp->blocks[bundlei]) != 0) && block->lag == 0 ) block->lag = duration; } } } -void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,int32_t fromcache) +void iguana_oldgotblockM(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,int32_t fromcache) { struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t valid,speculative=0,i,j,bundlei,copyflag,numtx; struct iguana_block *block; struct iguana_bundle *bp; uint32_t now; char str[65]; if ( recvlen < 0 || recvlen > IGUANA_MAXPACKETSIZE ) @@ -326,7 +326,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("iguana_getblockM: illegal recvlen.%d\n",recvlen); return; } - if ( 0 ) + if ( (0) ) { for (i=0; ispace[0]; i++) if ( txdata->space[i] != 0 ) @@ -352,11 +352,11 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } origtxdata->zblock.RO.allocsize = sizeof(origtxdata->zblock); - if ( iguana_blockvalidate(coin,&valid,(struct iguana_block *)&origtxdata->zblock,1) < 0 ) + if ( iguana_blockvalidate(myinfo,coin,&valid,(struct iguana_block *)&origtxdata->zblock,1) < 0 ) { printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); return; - } else if ( 0 && coin->enableCACHE != 0 ) + } else if ( (0) && coin->enableCACHE != 0 ) printf("c.%d v.(%s) %s n%d\n",coin->enableCACHE,bits256_str(str,origtxdata->zblock.RO.hash2),addr->ipaddr,addr->pendblocks); origtxdata->zblock.txvalid = 1; if ( fromcache == 0 && coin->virtualchain == 0 && addr != 0 && addr != &coin->internaladdr ) @@ -392,6 +392,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i copyflag = (coin->enableCACHE != 0) && (strcmp(coin->symbol,"BTC") != 0); bp = 0, bundlei = -2; bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->zblock.RO.hash2); + printf("[%d:%d].(%s) %s n%d\n",bp!=0?bp->hdrsi:-1,bundlei,bits256_str(str,origtxdata->zblock.RO.hash2),addr->ipaddr,addr->pendblocks); if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) { block = bp->blocks[bundlei]; @@ -420,7 +421,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i else { iguana_bundletime(coin,bp,bundlei,block,1); - iguana_blockzcopyRO(coin->chain->zcash,&block->RO,0,&origtxdata->zblock.RO,0); + iguana_blockzcopyRO(0*coin->chain->zcash,&block->RO,0,&origtxdata->zblock.RO,0); block->txvalid = 1; } //if ( block->mainchain != 0 ) @@ -429,7 +430,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i else { iguana_bundletime(coin,bp,bundlei,block,0); - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("recv [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); } } @@ -461,7 +462,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i req = iguana_bundlereq(coin,addr,'B',data,copyflag * recvlen); req->copyflag = 1; req->H = *H; - if ( 0 && iguana_sethdr(&checkH,coin->chain->netmagic,H->command,req->serializeddata,recvlen) > 0 && memcmp(&checkH,H,sizeof(checkH)) != 0 ) + if ( (0) && iguana_sethdr(&checkH,coin->chain->netmagic,H->command,req->serializeddata,recvlen) > 0 && memcmp(&checkH,H,sizeof(checkH)) != 0 ) { int z; for (z=0; zrecvblocks += 1.; addr->recvtotal += recvlen; } - if ( speculative == 0 && iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->zblock.RO.txn_count,data,recvlen) >= 0 ) + if ( speculative == 0 && iguana_ramchain_data(myinfo,coin,addr,origtxdata,txarray,origtxdata->zblock.RO.txn_count,data,recvlen,bp,block) >= 0 ) { txdata->zblock.fpipbits = (uint32_t)addr->ipbits; txdata->zblock.RO.recvlen = recvlen; txdata->zblock.fpos = 0; req->datalen = txdata->datalen; req->ipbits = txdata->zblock.fpipbits; - /*if ( 0 ) - { - struct iguana_txblock *checktxdata; struct OS_memspace checkmem; int32_t checkbundlei; - memset(&checkmem,0,sizeof(checkmem)); - iguana_meminit(&checkmem,"checkmem",0,txdata->datalen + 4096,0); - if ( (checktxdata= iguana_peertxdata(coin,&checkbundlei,fname,&checkmem,(uint32_t)addr->ipbits,txdata->block.RO.hash2)) != 0 ) - { - printf("check datalen.%d bundlei.%d T.%d U.%d S.%d P.%d X.%d\n",checktxdata->datalen,checkbundlei,checktxdata->numtxids,checktxdata->numunspents,checktxdata->numspends,checktxdata->numpkinds,checktxdata->numexternaltxids); - } - iguana_mempurge(&checkmem); - }*/ - } //else printf("cant save block\n"); + } //else printf("cant save block\n"); } if ( txdata->zblock.fpos == 0 ) { @@ -536,24 +526,393 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } req->addr = addr; //if ( (bits256_cmp(origtxdata->zblock.RO.hash2,coin->blocks.hwmchain.RO.hash2) == 0 || req->zblock.mainchain == 0 || req->zblock.valid == 0 || req->zblock.txvalid == 0) && iguana_RTrawdata(coin,origtxdata->zblock.RO.hash2,0,&len,&numtx,1) == 0 ) - queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); - if ( 0 && strcmp("BTCD",coin->symbol) == 0 ) + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + if ( (0) && strcmp("BTCD",coin->symbol) == 0 ) printf("%s Q.(%s)\n",coin->symbol,bits256_str(str,origtxdata->zblock.RO.hash2)); } else printf("nonz fpos.%d %s\n",txdata->zblock.fpos,bits256_str(str,origtxdata->zblock.RO.hash2)); } +void iguana_recvstats_update(struct iguana_info *coin,struct iguana_peer *addr,int32_t recvlen) +{ + static uint64_t received[IGUANA_MAXPEERS],count[IGUANA_MAXPEERS],lastcount,lastreceived,last; + char str[65],str2[65],str3[65],str4[65]; uint32_t now; int32_t i; int64_t sum2= 0,sum = 0,diffr,diff; double bw = 0.; + coin->recvcount++; + coin->recvtime = (uint32_t)time(NULL); + netBLOCKS++; + if ( addr->pendblocks > 0 ) + addr->pendblocks--; + addr->lastblockrecv = (uint32_t)time(NULL); + addr->recvblocks += 1.; + addr->recvtotal += recvlen; + received[addr->addrind] += recvlen; + count[addr->addrind]++; + now = (uint32_t)time(NULL); + if ( ((rand() % 10000) == 0 && now > last+60) || now > last+600 ) + { + for (i=0; i coin->maxbandwidth ) + coin->maxbandwidth = bw; + } + dxblend(&coin->bandwidth,bw,.9); + printf("%s BLOCKS.%llu RECV %s ave %.1f | dup.%d %s after.%d %s %s/sec %.2f%% %s\n",coin->symbol,(long long)sum2,mbstr(str,sum),(double)sum/(sum2!=0?sum2:1),numDuplicates,mbstr(str2,sizeDuplicates),numAfteremit,mbstr(str3,sizeAfteremit),mbstr(str4,bw),coin->maxbandwidth!=0.?100.*coin->bandwidth/coin->maxbandwidth:0.,coin->maxbandwidth>4*coin->bandwidth?"SLOW":""); + last = now; + } + if ( coin->bandwidth < 0.25*coin->maxbandwidth ) + { + //printf(">>SLOW.%d<< ",addr->addrind); + //iguana_blast(coin,addr); + } +} + +int32_t iguana_bundlestats_update(struct iguana_info *coin,struct iguana_block **blockp,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txblock *origtxdata,uint8_t *data,int32_t recvlen) +{ + char str[65]; struct iguana_block *block; int32_t i,j; + *blockp = 0; + if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) + { + *blockp = block = bp->blocks[bundlei]; + if ( bp->emitfinish != 0 ) + { + numAfteremit++; + sizeAfteremit += recvlen; + if ( block != 0 ) + iguana_bundletime(coin,bp,bundlei,block,1); + //printf("got [%d:%d] with emitfinish.%u\n",bp->hdrsi,bundlei,bp->emitfinish); + return(-1); + } + bp->dirty++; + if ( bundlei >= 0 && block != 0 ) + { + if ( block->fpipbits != 0 && block->txvalid != 0 ) + { + numDuplicates++; + sizeDuplicates += recvlen; + //printf("duplicate [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); + if ( bits256_cmp(origtxdata->zblock.RO.hash2,block->RO.hash2) != 0 ) + { + //printf("mismatched tx %s received? mainchain.%d\n",bits256_str(str,block->RO.hash2),block->mainchain); + return(-1); + } + else + { + iguana_bundletime(coin,bp,bundlei,block,1); + iguana_blockzcopyRO(0*coin->chain->zcash,&block->RO,0,&origtxdata->zblock.RO,0); + return(0); + } + } + else + { + iguana_bundletime(coin,bp,bundlei,block,0); + if ( (0) && bp == coin->current ) + printf("recv [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); + return(0); + } + } + } + else + { + if ( (bp= coin->current) != 0 ) + { + for (i=0; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 && bp->speculative != 0 && bp->numhashes < bp->n ) + { + if ( (j= iguana_speculativefind(coin,bp,(struct iguana_block *)&origtxdata->zblock,data,recvlen)) >= 0 ) + { + printf("speculative found\n"); + //copyflag = 0; + //speculative = 1; + if ( (*blockp= bp->blocks[j]) != 0 ) + iguana_bundletime(coin,bp,j,*blockp,0); + return(1); + } + } + } + } + } + return(0); +} + +struct iguana_bundlereq *iguana_recv_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t copyflag,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txblock *txdata) +{ + struct iguana_bundlereq *req; struct iguana_block *block = 0; + if ( copyflag != 0 && recvlen != 0 && (bp == 0 || bundlei < 0 || ((block= bp->blocks[bundlei]) != 0 && block->fpipbits == 0 && block->req == 0)) ) + { + struct iguana_msghdr checkH; + req = iguana_bundlereq(coin,addr,'B',data,copyflag * recvlen); + req->copyflag = 1; + req->H = *H; + if ( (0) && iguana_sethdr(&checkH,coin->chain->netmagic,H->command,req->serializeddata,recvlen) > 0 && memcmp(&checkH,H,sizeof(checkH)) != 0 ) + { + int z; + for (z=0; zH datalen.%d crc.%08x error\n",recvlen,calc_crc32(0,data,recvlen)); + } + } + else + { + copyflag = 0; + req = iguana_bundlereq(coin,addr,'B',0,0); + } + req->recvlen = recvlen; + req->datalen = txdata->datalen; + req->ipbits = txdata->zblock.fpipbits; + req->zblock = txdata->zblock; + req->zblock.RO.txn_count = req->numtx = txdata->zblock.RO.txn_count; + req->addr = addr; + return(req); +} + +void iguana_RTgotblock(struct iguana_info *coin,bits256 hash2,uint8_t *data,int32_t *recvlenp,int32_t *numtxp) +{ + int32_t i; struct iguana_bundle *bp; + if ( coin->almostRT == 0 ) + { + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 && bp->utxofinish <= 1 ) + break; + if ( (i > coin->bundlescount-2 && coin->blocks.hwmchain.height > coin->longestchain-coin->chain->bundlesize*2) || coin->RTheight > 0 ) + coin->almostRT = 1; + } + if ( coin->almostRT != 0 ) + { + portable_mutex_lock(&coin->RTmutex); + iguana_RTrawdata(coin,hash2,data,recvlenp,numtxp,0); + portable_mutex_unlock(&coin->RTmutex); + } +} + +int32_t iguana_txmerkle(struct iguana_info *coin,bits256 *tree,int32_t treesize,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray) +{ + int32_t i,msize; bits256 merkle_root; + if ( bits256_nonz(origtxdata->zblock.RO.merkle_root) == 0 ) + { + memset(&origtxdata->zblock.RO.prev_block,0,sizeof(bits256)); + origtxdata->zblock.RO.recvlen = 0; + origtxdata->zblock.issued = 0; + return(-1); + } + msize = (int32_t)sizeof(bits256) * (origtxdata->zblock.RO.txn_count+1) * 2; + if ( msize <= treesize ) + { + for (i=0; izblock.RO.txn_count; i++) + tree[i] = txarray[i].txid; + merkle_root = iguana_merkle(tree,origtxdata->zblock.RO.txn_count); + if ( bits256_cmp(merkle_root,origtxdata->zblock.RO.merkle_root) != 0 ) + { + char str[65],str2[65]; + printf(">>>>>>>>>> %s merkle mismatch.[%d] calc.(%s) vs (%s)\n",coin->symbol,origtxdata->zblock.RO.txn_count,bits256_str(str,merkle_root),bits256_str(str2,origtxdata->zblock.RO.merkle_root)); + origtxdata->zblock.RO.recvlen = 0; + origtxdata->zblock.issued = 0; + return(-1); + } //else printf("matched merkle.%d\n",txn_count); + return(0); + } else printf("not enough memory for merkle verify %d vs %u\n",(int32_t)(sizeof(bits256)*(origtxdata->zblock.RO.txn_count+1)),treesize); + return(-1); +} + +void iguana_gotblockM(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,int32_t fromcache,uint8_t zcash) +{ + static uint64_t totalrecv; + struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t incr,i,numsaved,valid,speculative=0,bundlei,copyflag,numtx; struct iguana_bundle *bp; struct iguana_block *block; char str[65]; + if ( addr == 0 ) + addr = &coin->internaladdr; + if ( recvlen < 0 || recvlen > IGUANA_MAXPACKETSIZE ) + { + printf("iguana_getblockM: illegal recvlen.%d\n",recvlen); + return; + } + if ( fromcache == 0 && coin->virtualchain == 0 && addr != 0 && addr != &coin->internaladdr ) + { + iguana_recvstats_update(coin,addr,recvlen); + totalrecv += recvlen; + } + origtxdata->zblock.RO.allocsize = sizeof(origtxdata->zblock); + if ( iguana_blockvalidate(myinfo,coin,&valid,(struct iguana_block *)&origtxdata->zblock,1) < 0 ) + { + printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); + return; + } + //printf("getblockM %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); + iguana_peer_meminit(coin,addr); + if ( iguana_txmerkle(coin,addr->TXDATA.ptr,(int32_t)addr->TXDATA.totalsize,origtxdata,txarray) < 0 ) + return; + origtxdata->zblock.txvalid = 1; + bp = 0, bundlei = -2; + if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->zblock.RO.hash2) == 0 ) + { + bp = 0, bundlei = -2; + if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->zblock.RO.prev_block) == 0 ) + { + //printf("gotblockM: RTblock? %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); + numtx = origtxdata->zblock.RO.txn_count; + iguana_RTgotblock(coin,origtxdata->zblock.RO.hash2,data,&recvlen,&numtx); + req = iguana_recv_bundlereq(coin,addr,0,H,data,recvlen,0,-1,origtxdata); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + return; + } + else if ( bundlei < coin->chain->bundlesize-1 ) + { + bundlei++; + iguana_hash2set(coin,"gotblockM",bp,bundlei,origtxdata->zblock.RO.hash2); + } + else // new bundle case, but bad context to extend + { + bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + if ( (bp= iguana_bundlecreate(coin,&bundlei,bp->bundleheight + coin->chain->bundlesize,origtxdata->zblock.RO.hash2,zero,0)) == 0 ) + { + origtxdata->zblock.issued = 0; + origtxdata->zblock.RO.recvlen = 0; + printf("gotblockM2: error finding block %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); + return; + } //else printf("getblockM autoextended.[%d]\n",bp->hdrsi); + } + } + if ( bp == 0 ) + { + printf("gotblockM no bp %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); + req = iguana_recv_bundlereq(coin,addr,0,H,data,recvlen,0,-1,origtxdata); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + return; + } + for (i=numsaved=0; ichain->bundlesize; i++) + { + if ( (block= bp->blocks[i]) != 0 && block->fpipbits != 0 && block->fpos >= 0 && block->txvalid != 0 ) + numsaved++; + } + if ( (speculative= iguana_bundlestats_update(coin,&block,bp,bundlei,origtxdata,data,recvlen)) < 0 ) + { + req = iguana_recv_bundlereq(coin,addr,0,H,data,recvlen,0,-1,origtxdata); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + //printf("negative speculative return %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); + return; + } + if ( bp == coin->current ) + { + if ( block == 0 ) + block = iguana_blockhashset("noblock",coin,bp->bundleheight+bundlei,origtxdata->zblock.RO.hash2,1); + if ( block != 0 && (block->hdrsi != bp->hdrsi || block->bundlei != bundlei) ) + { + block->hdrsi = bp->hdrsi; + block->bundlei = bundlei; + } + //printf("getblockM update [%d:%d] %s %p\n",bp->hdrsi,bundlei,bits256_str(str,origtxdata->zblock.RO.hash2),block); + } + if ( (block= bp->blocks[bundlei]) == 0 || bits256_nonz(bp->hashes[bundlei]) == 0 ) + { + //printf("SET [%d:%d]\n",bp->hdrsi,bundlei); + //iguana_hash2set(coin,"noblock",bp,bundlei,origtxdata->zblock.RO.hash2); + bp->hashes[bundlei] = origtxdata->zblock.RO.hash2; + if ( bp->speculative != 0 ) + bp->speculative[bundlei] = bp->hashes[bundlei]; + //bp->blocks[bundlei] = block; + } + numtx = origtxdata->zblock.RO.txn_count; + iguana_RTgotblock(coin,origtxdata->zblock.RO.hash2,data,&recvlen,&numtx); + if ( block != 0 ) + { + block->hdrsi = bp->hdrsi; + block->bundlei = bundlei; + block->height = bp->hdrsi*coin->chain->bundlesize + bundlei; + block->txvalid = block->valid = 1; + block->RO = origtxdata->zblock.RO; + if ( block->fpipbits != 0 && block->fpos >= 0 ) + { + static int32_t numredundant; static double redundantsize; static uint32_t lastdisp; + char str[65],str2[65]; + numredundant++, redundantsize += recvlen; + if ( time(NULL) > lastdisp+30 ) + { + lastdisp = (uint32_t)time(NULL); + printf("%s have %d:%d at %d | %d blocks %s redundant xfers total %s %.2f%% wasted\n",coin->symbol,bp->hdrsi,bundlei,block->fpos,numredundant,mbstr(str,redundantsize),mbstr(str2,totalrecv),100.*redundantsize/totalrecv); + } + if ( bundlei > 1 ) + { + // printf("DUP s.%d [%d:%d].(%s) %s n%d\n",numsaved,bp!=0?bp->hdrsi:-1,bundlei,bits256_str(str,origtxdata->zblock.RO.hash2),addr->ipaddr,addr->pendblocks); + } + req = iguana_recv_bundlereq(coin,addr,0,H,data,recvlen,0,-1,origtxdata); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + return; + } + } + txdata = origtxdata; + /*static portable_mutex_t mutex; static int32_t didinit; + if ( didinit == 0 ) + { + portable_mutex_init(&mutex); + didinit = 1; + } + portable_mutex_lock(&mutex);*/ + if ( iguana_ramchain_data(myinfo,coin,addr,origtxdata,txarray,origtxdata->zblock.RO.txn_count,data,recvlen,bp,block) >= 0 ) + { + txdata->zblock.fpipbits = (uint32_t)addr->ipbits; + txdata->zblock.RO.recvlen = recvlen; + txdata->zblock.fpos = 0; + copyflag = (coin->enableCACHE != 0) && (strcmp(coin->symbol,"BTC") != 0); + req = iguana_recv_bundlereq(coin,addr,copyflag,H,data,recvlen,bp,bundlei,txdata); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + if ( (0) && bp->hdrsi == 0 && strcmp("SYS",coin->symbol) == 0 ) + printf("[%d:%d].s%d %s Q.(%s) %s\n",bp->hdrsi,bundlei,numsaved,coin->symbol,bits256_str(str,origtxdata->zblock.RO.hash2),addr->ipaddr); + if ( numsaved < coin->chain->bundlesize ) + { + for (i=numsaved=0; ichain->bundlesize; i++) + { + if ( (block= bp->blocks[i]) != 0 && block->fpipbits != 0 && block->fpos >= 0 && block->txvalid != 0 ) + numsaved++; + } + if ( numsaved < coin->chain->bundlesize && bp->startutxo == 0 ) + { + if ( (incr= coin->peers->numranked) == 0 ) + incr = 1; + i = addr->addrind % incr; + for (; ichain->bundlesize; i+=incr) + { + if ( (bp->issued[i] == 0 && bits256_nonz(bp->hashes[i]) != 0) && ((block= bp->blocks[i]) == 0 || bits256_cmp(bp->hashes[i],block->RO.hash2) != 0 || block->fpipbits == 0 || block->fpos < 0 || block->txvalid == 0) ) + { + bp->issued[i] = 1; + iguana_sendblockreqPT(coin,addr,0,-1,bp->hashes[i],0); + //printf("numsaved.%d auto issue.[%d:%d] %s\n",numsaved,bp->hdrsi,i,addr->ipaddr); + break; + } //else printf("numsaved.%d SKIP auto issue.[%d:%d] %s\n",numsaved,bp->hdrsi,i,addr->ipaddr); + } + } + else if ( bp->queued == 0 && bp->startutxo == 0 ) + { + iguana_bundleQ(myinfo,coin,bp,1000); + //printf("numsaved.%d [%d] %s\n",numsaved,bp->hdrsi,addr->ipaddr); + } + } + } + else + { + req = iguana_recv_bundlereq(coin,addr,0,H,data,recvlen,0,-1,origtxdata); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + } + //portable_mutex_unlock(&mutex); +} + void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n) { struct iguana_bundlereq *req; //printf("got %d txids from %s\n",n,addr->ipaddr); req = iguana_bundlereq(coin,addr,'T',0,0); req->hashes = txids, req->n = n; - queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); } int32_t iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_zblock *zblocks,int32_t n) { - struct iguana_bundlereq *req; int32_t i,num; + struct iguana_bundlereq *req; int32_t i,num; struct iguana_bundle *bp; + if ( n <= 1 ) + return(-1); if ( addr != 0 ) { static uint32_t hdrsreceived[IGUANA_MAXPEERS]; @@ -564,7 +923,7 @@ int32_t iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,str uint32_t i,sum = 0; for (i=0; i %s\n",sum,mbstr(str,sum*80)); + printf("%s TOTAL HDRS RECEIVED %u -> %s\n",coin->symbol,sum,mbstr(str,sum*80)); } addr->recvhdrs++; if ( addr->pendhdrs > 0 ) @@ -578,10 +937,39 @@ int32_t iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,str addr->numRThashes = num; } } - req = iguana_bundlereq(coin,addr,'H',0,0); - req->blocks = zblocks, req->n = n; - HDRnet++; - queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); + if ( strcmp("BTC",coin->symbol) != 0 && n == 2 ) + iguana_sendblockreqPT(coin,addr,0,-1,zblocks[1].RO.hash2,0); + if ( 1 ) + { + for (i=0; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bits256_cmp(zblocks[1].RO.hash2,bp->hashes[1]) == 0 && bp->numhashes >= coin->chain->bundlesize ) + return(-1); + } + } + i = 0; + if ( n >= 2*coin->chain->bundlesize+1 ) + { + while ( n-i*coin->chain->bundlesize >= 2*coin->chain->bundlesize+1 ) + { + req = iguana_bundlereq(coin,addr,'H',0,0); + req->blocks = mycalloc('r',coin->chain->bundlesize,sizeof(*zblocks)); + memcpy(req->blocks,&zblocks[i++ * coin->chain->bundlesize],coin->chain->bundlesize * sizeof(*zblocks)); + req->n = coin->chain->bundlesize; + HDRnet++; + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + } + } + else + { + req = iguana_bundlereq(coin,addr,'H',0,0); + req->blocks = zblocks, req->n = n; + HDRnet++; + queue_enqueue("recvQ",&coin->recvQ,&req->DL); + zblocks = 0; + } + if ( zblocks != 0 ) + myfree(zblocks,sizeof(*zblocks)*n); return(0); } @@ -603,14 +991,14 @@ void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bi req = iguana_bundlereq(coin,addr,'S',0,0); req->hashes = blockhashes, req->n = n; char str[65]; - if ( 0 && n > 2 && addr != 0 ) + if ( (0) && n > 2 && addr != 0 ) printf("addr.%d %s [%d]\n",addr->rank,bits256_str(str,blockhashes[1]),n); - queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); + queue_enqueue("recvQ",&coin->recvQ,&req->DL); if ( strcmp("BTC",coin->symbol) != 0 ) { if ( n > coin->chain->bundlesize ) iguana_sendblockreqPT(coin,addr,0,-1,blockhashes[1],0); - if ( 0 && coin->RTheight > 0 ) + if ( (0) && coin->RTheight > 0 ) { for (i=1; iallhash) > 0 && num >= coin->chain->bundlesize && bp->emitfinish == 0 ) { vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); + //char str[65]; printf("allhashes.(%s)\n",bits256_str(str,allhash)); if ( memcmp(allhash.bytes,bp->allhash.bytes,sizeof(allhash)) == 0 ) { if ( bp->bundleheight > 0 ) @@ -649,19 +1038,23 @@ uint32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bit prev->hh.next = block; block->hh.prev = prev; } - //if ( bp->hdrsi < coin->MAXBUNDLES ) - // iguana_blockQ(coin,bp,i,blockhashes[i],0); + if ( bp->startutxo == 0 && bp->issued[i] == 0 ) + { + iguana_blockQ("allhashes",coin,bp,i,blockhashes[i],1); + iguana_blockQ("allhashes",coin,bp,i,blockhashes[i],0); + n++; + } } else printf("no allhashes block.%p or mismatch.%p\n",block,bp->blocks[i]); prev = block; } coin->allhashes++; - n = 0; - if ( bp->hdrsi < coin->MAXBUNDLES || (coin->current != 0 && coin->lastpending != 0 && bp->hdrsi >= coin->current->hdrsi && bp->hdrsi <= coin->lastpending->hdrsi) ) - n = iguana_bundleissuemissing(coin,bp,1,3.); - if ( 0 && n > 0 ) + //n = 0; + //if ( bp->hdrsi < coin->MAXBUNDLES || (coin->current != 0 && coin->lastpending != 0 && bp->hdrsi >= coin->current->hdrsi && bp->hdrsi <= coin->lastpending->hdrsi) ) + // n = iguana_bundleissuemissing(myinfo,coin,bp,1,3.); + if ( (0) && n > 2 ) printf("ALLHASHES FOUND! %d allhashes.%d issued %d\n",bp->bundleheight,coin->allhashes,n); - if ( bp->queued == 0 ) - iguana_bundleQ(coin,bp,bp->n*5 + (rand() % 500)); + //if ( bp->queued == 0 ) + // iguana_bundleQ(myinfo,coin,bp,bp->n*5 + (rand() % 500)); return(bp->queued); } } @@ -672,22 +1065,13 @@ void iguana_bundlespeculate(struct iguana_info *coin,struct iguana_bundle *bp,in { if ( bp == 0 ) return; - if ( strcmp("BTC",coin->symbol) != 0 && bp->numhashes < bp->n && bundlei == 0 && bp->speculative == 0 && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) + if ( time(NULL) > bp->hdrtime+3 && strcmp("BTC",coin->symbol) != 0 && bp->numhashes < bp->n && bundlei == 0 && bp->speculative == 0 && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) { char str[65]; bits256_str(str,bp->hashes[0]); //fprintf(stderr,"Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); + bp->hdrtime = (uint32_t)time(NULL); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str)); } - /*else if ( bp->speculative != 0 && bundlei < bp->numspec && memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)) == 0 ) - { - bundlei += offset; - if ( bundlei < bp->n && bundlei < bp->numspec && time(NULL) > bp->issued[bundlei]+30 ) - { - char str[65]; printf("speculative req[%d] %s\n",bundlei,bits256_str(str,bp->speculative[bundlei])); - iguana_blockQ("speculate",coin,0,-1,bp->speculative[bundlei],0); - bp->issued[bundlei] = (uint32_t)time(NULL); - } - } */ //else printf("speculative.%p %d vs %d cmp.%d\n",bp->speculative,bundlei,bp->numspec,bp->speculative!=0?memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)):-1);*/ } int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block) @@ -713,14 +1097,15 @@ int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,i return(-1); } } - //if ( bp->blocks[bundlei] == 0 ) + if ( bp->blocks[bundlei] == 0 ) firstflag = 1; - bp->blocks[bundlei] = block; + //bp->blocks[bundlei] = block; + //bp->hashes[bundlei] = block->RO.hash2; iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); if ( firstflag != 0 && bp->emitfinish == 0 ) { //block->fpos = -1; - if ( 0 && iguana_ramchainfile(SuperNET_MYINFO(0),coin,0,&blockR,bp,bundlei,block) == 0 ) + if ( (0) && iguana_ramchainfile(SuperNET_MYINFO(0),coin,0,&blockR,bp,bundlei,block) == 0 ) { size = sizeof(blockR); iguana_ramchain_free(coin,&blockR,1); @@ -751,7 +1136,7 @@ int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,i void iguana_bundle_set(struct iguana_info *coin,struct iguana_block *block,int32_t height) { - int32_t hdrsi,bundlei; struct iguana_bundle *bp; + int32_t hdrsi,bundlei; struct iguana_bundle *bp; char str[65]; if ( block->height < 0 || block->height == height ) { hdrsi = (height / coin->chain->bundlesize); @@ -760,11 +1145,12 @@ void iguana_bundle_set(struct iguana_info *coin,struct iguana_block *block,int32 { bp->blocks[bundlei] = block; bp->hashes[bundlei] = block->RO.hash2; + iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); if ( bp->speculative != 0 ) bp->speculative[bundlei] = block->RO.hash2; //char str[65]; printf("SET %s ht.%d in [%d:%d]\n",bits256_str(str,block->RO.hash2),height,hdrsi,bundlei); } //else printf("iguana_bundle_set: no bundle at [%d]\n",hdrsi); - } else printf("iguana_bundle_set: mismatch ht.%d vs %d\n",block->height,height); + } else printf("iguana_bundle_set: %s mismatch ht.%d vs %d\n",bits256_str(str,block->RO.hash2),block->height,height); } void iguana_hwmchain_set(struct iguana_info *coin,struct iguana_block *block,int32_t height) @@ -773,13 +1159,13 @@ void iguana_hwmchain_set(struct iguana_info *coin,struct iguana_block *block,int { if ( block->height == height ) { - iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,(struct iguana_block *)&coin->blocks.hwmchain,block); - char str[65]; printf("SET HWM.%s ht.%d\n",bits256_str(str,block->RO.hash2),height); + iguana_blockcopy(0*coin->chain->zcash,coin->chain->auxpow,coin,(struct iguana_block *)&coin->blocks.hwmchain,block); + char str[65]; printf("SET %s HWM.%s ht.%d\n",coin->symbol,bits256_str(str,block->RO.hash2),height); } else printf("iguana_hwmchain_set: mismatched ht.%d vs %d\n",block->height,height); } } -void iguana_mainchain_clear(struct iguana_info *coin,struct iguana_block *mainchain,struct iguana_block *oldhwm,int32_t n) +void iguana_mainchain_clear(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *mainchain,struct iguana_block *oldhwm,int32_t n) { int32_t i,height; char str[65]; struct iguana_block *tmp = oldhwm; if ( mainchain != oldhwm ) @@ -787,15 +1173,18 @@ void iguana_mainchain_clear(struct iguana_info *coin,struct iguana_block *mainch height = oldhwm->height; for (i=0; iRO.hash2); if ( tmp->mainchain == 0 ) - printf("%s iguana_mainchain_clear: unexpected non-main ht.%d %s\n",coin->symbol,tmp->height,str); + { + // printf("%s iguana_mainchain_clear: ORPHANED ht.%d %s\n",coin->symbol,tmp->height,str); + } else if ( tmp->height != height ) printf("iguana_mainchain_clear: unexpected ht.%d vs %d %s\n",tmp->height,height,str); else { tmp->mainchain = 0; - printf("CLEAR mainchain.%d %s\n",height,str); + //printf("CLEAR %s mainchain.%d %s\n",coin->symbol,height,str); } if ( (tmp= iguana_blockfind("clear",coin,tmp->RO.prev_block)) == 0 ) { @@ -803,7 +1192,7 @@ void iguana_mainchain_clear(struct iguana_info *coin,struct iguana_block *mainch return; } } - if ( tmp != mainchain && coin->RTheight > 0 ) + if ( (0) && tmp != mainchain && coin->RTheight > 0 ) printf("iguana_mainchain_clear: unexpected mismatch ht.%d vs %d %s\n",tmp->height,mainchain->height,bits256_str(str,tmp->RO.hash2)); } } @@ -819,7 +1208,7 @@ int32_t iguana_height_estimate(struct iguana_info *coin,struct iguana_block **ma if ( tmp->mainchain != 0 && tmp->height >= 0 ) { char str[65]; - if ( 0 && n > 0 && coin->RTheight > 0 ) + if ( (0) && n > 0 && coin->RTheight > 0 ) printf("%s M.%d dist.%d -> %d\n",bits256_str(str,block->RO.hash2),tmp->height,n,tmp->height+n); *mainchainp = tmp; return(tmp->height + n); @@ -834,7 +1223,7 @@ int32_t iguana_height_estimate(struct iguana_info *coin,struct iguana_block **ma // main context, ie single threaded struct iguana_bundle *iguana_bundleset(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) { - struct iguana_block *block,*prevblock,*tmp,*mainchain,*hwmblock; bits256 zero,hash2,prevhash2; struct iguana_bundle *prevbp,*bp = 0; int32_t i,newheight,prevbundlei,bundlei = -2; // struct iguana_ramchain blockR; + struct iguana_block *block,*prevblock,*tmp,*mainchain,*hwmblock; bits256 zero,hash2,prevhash2; struct iguana_bundle *prevbp,*bp = 0; int32_t i,n,hdrsi,newheight,prevbundlei,bundlei = -2; // struct iguana_ramchain blockR; *bundleip = -2; *blockp = 0; if ( origblock == 0 ) return(0); @@ -845,30 +1234,39 @@ struct iguana_bundle *iguana_bundleset(struct supernet_info *myinfo,struct iguan prevhash2 = origblock->RO.prev_block; if ( block != origblock ) { - iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,block,origblock); - //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); + iguana_blockcopy(0*coin->chain->zcash,coin->chain->auxpow,coin,block,origblock); + //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%d\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); } *blockp = block; if ( coin->blocks.hwmchain.height > 0 && (hwmblock= iguana_blockfind("hwm",coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) { if ( (newheight= iguana_height_estimate(coin,&mainchain,block)) >= coin->blocks.hwmchain.height ) { - iguana_mainchain_clear(coin,mainchain,hwmblock,coin->blocks.hwmchain.height-mainchain->height); - tmp = block; - for (i=0; iheight; i++) + iguana_mainchain_clear(myinfo,coin,mainchain,hwmblock,coin->blocks.hwmchain.height-mainchain->height); + n = (newheight - mainchain->height); + for (i=1; iRO.prev_block)) == 0 ) - break; - iguana_RTnewblock(myinfo,coin,tmp); + hdrsi = ((mainchain->height+i) / coin->chain->bundlesize); + bundlei = ((mainchain->height+i) % coin->chain->bundlesize); + if ( hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 ) + { + if ( (tmp= bp->blocks[bundlei]) != 0 && tmp->height == mainchain->height+i ) + { + iguana_bundle_set(coin,tmp,mainchain->height+i); + iguana_RTnewblock(myinfo,coin,tmp); + } else break; + } } - if ( mainchain != hwmblock ) + if ( i == n && mainchain != hwmblock ) + { iguana_hwmchain_set(coin,mainchain,mainchain->height); // trigger reprocess + iguana_RTnewblock(myinfo,coin,mainchain); + } } - else if ( coin->RTheight > 0 && newheight == coin->RTheight ) + else //if ( coin->RTheight > 0 && newheight == coin->RTheight ) { //printf("newheight.%d is RTheight\n",newheight); - } + } } //if ( 0 && bits256_nonz(prevhash2) > 0 ) // iguana_patch(coin,block); @@ -877,11 +1275,10 @@ struct iguana_bundle *iguana_bundleset(struct supernet_info *myinfo,struct iguan { if ( iguana_bundlehashadd(coin,bp,bundlei,block) < 0 ) { - if ( bp->emitfinish == 0 && block->issued == 0 && strcmp("BTC",coin->symbol) != 0 )//|| coin->PREFETCHLAG < 0) ) - iguana_blockQ("bundleset",coin,bp,bundlei,block->RO.hash2,1);//coin->current == 0 || bp->hdrsi <= coin->current->hdrsi+coin->MAXBUNDLES); + if ( bp->emitfinish == 0 && bp->issued[bundlei] == 0 && block->issued == 0 && strcmp("BTC",coin->symbol) != 0 ) + iguana_blockQ("bundleset",coin,bp,bundlei,block->RO.hash2,1); } //fprintf(stderr,"bundle found %d:%d\n",bp->hdrsi,bundlei); - //printf("bundlehashadd set.%d\n",bundlei); if ( bundlei > 0 ) { //printf("bundlehashadd prev %d\n",bundlei); @@ -894,31 +1291,35 @@ struct iguana_bundle *iguana_bundleset(struct supernet_info *myinfo,struct iguan iguana_bundlespeculate(coin,bp,bundlei,hash2,1); } prevbp = 0, prevbundlei = -2; - iguana_bundlefind(coin,&prevbp,&prevbundlei,prevhash2); - //if ( 0 && block->blockhashes != 0 ) - // fprintf(stderr,"has blockhashes bp.%p[%d] prevbp.%p[%d]\n",bp,bundlei,prevbp,prevbundlei); - if ( prevbp != 0 && prevbundlei >= 0 && (prevblock= iguana_blockfind("bundleset2",coin,prevhash2)) != 0 ) - { - if ( prevbundlei < coin->chain->bundlesize ) - { - if ( prevbp->hdrsi+1 == coin->bundlescount && prevbundlei == coin->chain->bundlesize-1 ) - { - printf("%s AUTOCREATE.%d\n",coin->symbol,prevbp->bundleheight + coin->chain->bundlesize); - if ( (bp= iguana_bundlecreate(coin,bundleip,prevbp->bundleheight + coin->chain->bundlesize,hash2,zero,0)) != 0 ) - { - if ( bp->queued == 0 ) - iguana_bundleQ(coin,bp,1000); - } - } - if ( prevbundlei < coin->chain->bundlesize-1 ) - { - //printf("bundlehash2add next %d\n",prevbundlei); - iguana_bundlehash2add(coin,0,prevbp,prevbundlei+1,hash2); - } - if ( 1 && strcmp("BTC",coin->symbol) != 0 ) - iguana_bundlespeculate(coin,prevbp,prevbundlei,prevhash2,2); - } - } + if (bits256_nonz(prevhash2)) { + iguana_bundlefind(coin, &prevbp, &prevbundlei, prevhash2); + //if ( 0 && block->blockhashes != 0 ) + // fprintf(stderr,"has blockhashes bp.%p[%d] prevbp.%p[%d]\n",bp,bundlei,prevbp,prevbundlei); + if (prevbp != 0 && prevbundlei >= 0 && (prevblock = iguana_blockfind("bundleset2", coin, prevhash2)) != 0) + { + if (prevbundlei < coin->chain->bundlesize) + { + if (prevbp->hdrsi + 1 == coin->bundlescount && prevbundlei == coin->chain->bundlesize - 1) + { + if ( (prevbp->hdrsi % 10) == 9 ) + iguana_savehdrs(coin); + printf("%s AUTOCREATE.%d\n", coin->symbol, prevbp->bundleheight + coin->chain->bundlesize); + if ( (bp= iguana_bundlecreate(coin, bundleip, prevbp->bundleheight + coin->chain->bundlesize, hash2, zero, 0)) != 0) + { + if ( bp->queued == 0 ) + iguana_bundleQ(myinfo, coin, bp, 1000); + } + } + if (prevbundlei < coin->chain->bundlesize - 1) + { + //printf("bundlehash2add next %d\n",prevbundlei); + iguana_bundlehash2add(coin, 0, prevbp, prevbundlei + 1, hash2); + } + if (1 && strcmp("BTC", coin->symbol) != 0) + iguana_bundlespeculate(coin, prevbp, prevbundlei, prevhash2, 2); + } + } + } } else printf("iguana_bundleset: error adding blockhash\n"); bp = 0, *bundleip = -2; return(iguana_bundlefind(coin,&bp,bundleip,hash2)); @@ -959,7 +1360,7 @@ void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp, struct iguana_bundlereq *iguana_recvblockhdrs(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_zblock *zblocks,int32_t n,int32_t *newhwmp) { - int32_t i,bundlei,match; struct iguana_block *block; bits256 prevhash2; uint8_t serialized[sizeof(struct iguana_msgblock) + sizeof(struct iguana_msgblockhdr_zcash)]; struct iguana_peer *addr; struct iguana_bundle *bp,*firstbp = 0; + int32_t i,bundlei,match; struct iguana_block *block; bits256 prevhash2; uint8_t serialized[sizeof(struct iguana_msgblock) + sizeof(struct iguana_msgzblockhdr)]; struct iguana_peer *addr; struct iguana_bundle *bp,*firstbp = 0; if ( zblocks == 0 ) { printf("iguana_recvblockhdrs null blocks?\n"); @@ -968,7 +1369,7 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct supernet_info *myinfo,struc if ( zblocks != 0 && n > 0 ) { memset(prevhash2.bytes,0,sizeof(prevhash2)); - for (i=match=0; ichain->bundlesize; i++) { //fprintf(stderr,"i.%d of %d bundleset\n",i,n); if ( bits256_cmp(zblocks[i].RO.prev_block,coin->blocks.hwmchain.RO.hash2) == 0 ) @@ -976,66 +1377,72 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct supernet_info *myinfo,struc bp = 0, bundlei = -2; if ( (bp= iguana_bundleset(myinfo,coin,&block,&bundlei,(struct iguana_block *)&zblocks[i])) != 0 ) { + if ( firstbp == 0 ) + firstbp = bp; if ( block->height >= 0 && block->height+1 > coin->longestchain ) coin->longestchain = block->height+1; _iguana_chainlink(myinfo,coin,block); } //char str[65]; printf("HWM in hdr's prev[%d] bp.%p bundlei.%d block.%p %s\n",i,bp,bundlei,block,bp!=0?bits256_str(str,bp->hashes[bundlei]):"()"); } - if ( i > 0 && bits256_cmp(prevhash2,zblocks[i].RO.prev_block) == 0 ) + bp = 0, bundlei = -2; + if ( (bp= iguana_bundleset(myinfo,coin,&block,&bundlei,(struct iguana_block *)&zblocks[i])) == 0 ) { bp = 0, bundlei = -2; - if ( (bp= iguana_bundleset(myinfo,coin,&block,&bundlei,(struct iguana_block *)&zblocks[i])) != 0 ) + if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,zblocks[i].RO.prev_block)) != 0 ) { - bp->dirty++; - if ( 0 && bp->issued[bundlei] == 0 && bp->hdrsi < coin->MAXBUNDLES ) - iguana_blockQ("recvhdr",coin,bp,bundlei,block->RO.hash2,1); - //printf("{%d:%d} ",bp->hdrsi,bundlei); - if ( i == 0 ) - { - firstbp = bp; - iguana_checklongestchain(coin,bp,n); - } - if ( bundlei == i+1 && bp == firstbp ) - match++; + if ( bundlei < coin->chain->bundlesize-1 ) + bundlei++; else { - if ( 0 && bp != coin->current && i != n-1 ) - fprintf(stderr,"recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); + bundlei = 0; + bp = coin->bundles[bp->hdrsi+1]; } } } + if ( bp != 0 ) + { + if ( firstbp == 0 ) + firstbp = bp, match++; + else if ( bp == firstbp ) + match++; + bp->dirty++; + if ( bp->issued[bundlei] == 0 )//&& coin->RTheight > 0 ) + { + bp->issued[bundlei] = 1; + iguana_blockQ("recvhdr",coin,bp,bundlei,block->RO.hash2,0); + } + } prevhash2 = zblocks[i].RO.hash2; - //printf("%d bp.%p [%d] bundlei.%d %s prev.%s\n",i,bp,bp!=0?bp->hdrsi:-1,bundlei,bits256_str(str,zblocks[i].RO.hash2),bits256_str(str2,zblocks[i].RO.prev_block)); - //else if ( bp != firstbp ) - // printf("blockhash[%d] cant be found n.%d\n",i,n); } char str[65]; - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("i.%d n.%d match.%d blockhdrs.%s hdrsi.%d\n",i,n,match,bits256_str(str,zblocks[0].RO.hash2),firstbp!=0?firstbp->hdrsi:-1); - if ( firstbp != 0 && match == coin->chain->bundlesize-1 && n == firstbp->n ) + /*if ( firstbp != 0 && match >= coin->chain->bundlesize-1 ) { if ( firstbp->queued == 0 ) { //fprintf(stderr,"firstbp blockQ %d\n",firstbp->bundleheight); - iguana_bundleQ(coin,firstbp,1000); + iguana_bundleQ(myinfo,coin,firstbp,1000); } - } - if ( i == n && i == match && firstbp == coin->current && (addr= req->addr) != 0 ) + }*/ + if ( firstbp != 0 && (addr= req->addr) != 0 && n >= coin->chain->bundlesize ) { - addr->RThashes[i] = firstbp->hashes[0]; - for (i=1; iRThashes[0] = firstbp->hashes[0]; + for (i=1; ichain->bundlesize; i++) { - iguana_serialize_block(coin->chain,&addr->RThashes[i],serialized,(struct iguana_block *)&zblocks[i]); + iguana_serialize_block(myinfo,coin->chain,&addr->RThashes[i],serialized,(struct iguana_block *)&zblocks[i]); } - //memcpy(addr->RThashes,blockhashes,bp->numspec * sizeof(*addr->RThashes)); - addr->numRThashes = n; + addr->numRThashes = coin->chain->bundlesize; + //printf("firstbp.[%d] call allhashes %s\n",firstbp->hdrsi,bits256_str(str,addr->RThashes[0])); + if ( iguana_allhashcmp(myinfo,coin,firstbp,addr->RThashes,coin->chain->bundlesize) > 0 ) + return(req); } } return(req); } -void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp) +void iguana_autoextend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp) { char hashstr[65]; struct iguana_bundle *newbp; int32_t bundlei; static const bits256 zero; if ( bp->hdrsi == coin->bundlescount-1 && bits256_nonz(bp->nextbundlehash2) != 0 ) @@ -1054,22 +1461,25 @@ void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp) newbp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,bp->nextbundlehash2,zero,1); if ( newbp != 0 ) { - if ( newbp->speculative == 0 ) - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + if ( time(NULL) > bp->hdrtime+3 && newbp->speculative == 0 ) + { + bp->hdrtime = (uint32_t)time(NULL); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr)); + } //char str[65],str2[65]; printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,newbp->hashes[0]),bits256_str(str2,bp->nextbundlehash2),newbp->bundleheight); if ( newbp->queued == 0 ) - iguana_bundleQ(coin,newbp,1000); + iguana_bundleQ(myinfo,coin,newbp,1000); } } } -struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) +struct iguana_bundlereq *iguana_recvblockhashes(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) { int32_t bundlei,i,starti; struct iguana_block *block; struct iguana_bundle *bp; bits256 allhash,zero; struct iguana_peer *addr; char str[65],str2[65]; // uint8_t serialized[512]; memset(zero.bytes,0,sizeof(zero)); bp = 0, bundlei = -2; iguana_bundlefind(coin,&bp,&bundlei,blockhashes[1]); - if ( 0 && strcmp("BTCD",coin->symbol) == 0 )//0 && num >= coin->chain->bundlesize ) + if ( (0) && strcmp("BTCD",coin->symbol) == 0 )//0 && num >= coin->chain->bundlesize ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( num < 2 ) return(req); @@ -1100,9 +1510,9 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_blockQ("recvhash1",coin,0,-1,bp->nextbundlehash2,1); } //printf("call allhashes\n"); - if ( 0 && bp->hdrsi == coin->bundlescount-1 ) - iguana_autoextend(coin,bp); - if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) + if ( (0) && bp->hdrsi == coin->bundlescount-1 ) + iguana_autoextend(myinfo,coin,bp); + if ( iguana_allhashcmp(myinfo,coin,bp,blockhashes,num) > 0 ) return(req); //printf("done allhashes\n"); } @@ -1118,22 +1528,22 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct } } } - if ( strcmp("BTC",coin->symbol) != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) + if ( strcmp("BTCD",coin->symbol) == 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { //printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); if ( bp->speculative == 0 ) { bp->speculative = mycalloc('s',bp->n+1,sizeof(*bp->speculative)); - for (i=0; in; i++) - if ( GETBIT(bp->haveblock,i) == 0 ) - bp->issued[i] = 0; - iguana_bundleissuemissing(coin,bp,3,1.); + //for (i=0; in; i++) + // if ( GETBIT(bp->haveblock,i) == 0 ) + // bp->issued[i] = 0; + //iguana_bundleissuemissing(myinfo,coin,bp,3,1.); } for (i=1; in; i++) { bp->speculative[i] = blockhashes[i]; - //if ( bp->blocks[i] == 0 || bp->blocks[i]->issued == 0 ) - // iguana_blockQ("speculate",coin,bp,-i,blockhashes[i],0); + if ( bp->blocks[i] == 0 || bp->blocks[i]->issued == 0 ) + iguana_blockQ("speculate",coin,bp,-i,blockhashes[i],0); if ( bp->blocks[i] == 0 ) bp->blocks[i] = iguana_blockhashset("recvhashes3",coin,bp->bundleheight+i,blockhashes[i],1); //printf("speculate new issue [%d:%d]\n",bp->hdrsi,i); @@ -1157,15 +1567,15 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct { blockhashes[0] = bp->hashes[0]; vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); - if ( 0 && i == starti ) + if ( (0) && i == starti ) printf("vcalc.(%s) [%d].(%s)\n",bits256_str(str,allhash),bp->hdrsi,bits256_str(str2,bp->hashes[0])); if ( bits256_cmp(allhash,bp->allhash) == 0 ) { - if ( 0 && bp->speculative == 0 ) + if ( (0) && bp->speculative == 0 ) printf("matched allhashes.[%d]\n",bp->hdrsi); if ( bp->queued != 0 ) bp->queued = 0; - if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) + if ( iguana_allhashcmp(myinfo,coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) { bp->hdrtime = (uint32_t)time(NULL); //iguana_blockQ("recvhash2",coin,bp,1,blockhashes[1],1); @@ -1198,7 +1608,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct { if ( (block= iguana_blockfind("recvhashes2",coin,blockhashes[1])) == 0 ) { - iguana_blockhashset("recvhashes3",coin,-1,blockhashes[1],1); + //iguana_blockhashset("recvhashes3",coin,-1,blockhashes[1],1); if ( (block= iguana_blockfind("recvhashes4",coin,blockhashes[1])) != 0 ) iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],1); // should be RT block } @@ -1208,9 +1618,9 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct } if ( strcmp("BTC",coin->symbol) != 0 ) { - iguana_blockQ("recvhash7",coin,0,-7,blockhashes[1],1); + //iguana_blockQ("recvhash7",coin,0,-7,blockhashes[1],1); iguana_blockQ("recvhash7",coin,0,-7,blockhashes[num-1],1); - //if ( 1 && coin->RTheight > 0 ) + if ( 1 && coin->RTheight > 0 ) { for (i=1; isymbol) == 0 ) - printf("%s received.(%s) %s\n",coin->symbol,bits256_str(str,origblock->RO.hash2),addr->ipaddr); if ( (block= iguana_blockfind("recv",coin,origblock->RO.hash2)) != 0 ) - iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,block,(struct iguana_block *)origblock); + iguana_blockcopy(0*coin->chain->zcash,coin->chain->auxpow,coin,block,(struct iguana_block *)origblock); else if ( (block= iguana_blockhashset("recvblock",coin,-1,origblock->RO.hash2,1)) == 0 ) { printf("error adding %s\n",bits256_str(str,origblock->RO.hash2)); return(req); } + else block->txvalid = block->valid = 1; if ( bits256_nonz(origblock->RO.prev_block) != 0 ) { - if ( (prevblock= iguana_blockfind("prev",coin,origblock->RO.prev_block)) != 0 && prevblock->height+1 > coin->longestchain ) - coin->longestchain = prevblock->height+1; - else iguana_blockQ("prev",coin,0,-1,origblock->RO.prev_block,1); + if ( (prevblock= iguana_blockfind("prev",coin,origblock->RO.prev_block)) != 0 ) + { + if ( prevblock->height+1 > coin->longestchain ) + coin->longestchain = prevblock->height+1; + } else iguana_blockQ("prev",coin,0,-1,origblock->RO.prev_block,1); } + if ( (0) && block != 0 ) + printf("%s received.(%s) [%d:%d]\n",coin->symbol,bits256_str(str,origblock->RO.hash2),block->hdrsi,block->bundlei); if ( (bp= iguana_bundleset(myinfo,coin,&block,&bundlei,(struct iguana_block *)origblock)) != 0 && bp == coin->current && block != 0 && bp->speculative != 0 && bundlei >= 0 ) { + if ( (0) && strcmp("BTCD",coin->symbol) == 0 ) + printf("%s received.(%s) %s\n",coin->symbol,bits256_str(str,origblock->RO.hash2),addr->ipaddr); if ( bp->speculative != 0 && bp->numspec <= bundlei ) { bp->speculative[bundlei] = block->RO.hash2; @@ -1258,7 +1673,7 @@ struct iguana_bundlereq *iguana_recvblock(struct supernet_info *myinfo,struct ig block = iguana_bundleblock(coin,&hash2,bp,bundlei); } //printf("autoadd [%d:%d]\n",bp->hdrsi,bundlei); - } // else printf("couldnt find.(%s)\n",bits256_str(str,block->RO.hash2)); + } //else printf("couldnt find.(%s)\n",bits256_str(str,block->RO.hash2)); if ( bp != 0 ) { bp->dirty++; @@ -1278,7 +1693,7 @@ struct iguana_bundlereq *iguana_recvblock(struct supernet_info *myinfo,struct ig coin->numcached++; if ( block != 0 ) block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); + queue_enqueue("cacheQ",&coin->cacheQ,&req->DL); return(0); } else if ( block != 0 && block->req == 0 ) @@ -1315,15 +1730,16 @@ struct iguana_bundlereq *iguana_recvblock(struct supernet_info *myinfo,struct ig } } // else printf("RECV MAINCHAIN.%d\n",coin->blocks.hwmchain.height); } - if ( 0 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && strcmp("BTC",coin->symbol) != 0 && bp->speculative == 0 && bp == coin->current ) + if ( (0) && time(NULL) > bp->hdrtime+3 && bundlei == 1 && bp != 0 && bp->numhashes < bp->n && strcmp("BTC",coin->symbol) != 0 && bp->speculative == 0 && bp == coin->current ) { printf("reissue hdrs request for [%d]\n",bp->hdrsi); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + bp->hdrtime = (uint32_t)time(NULL); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0]))); } if ( (block= iguana_blockhashset("recvblock",coin,-1,origblock->RO.hash2,1)) != 0 ) { if ( block != (struct iguana_block *)origblock ) - iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,block,(struct iguana_block *)origblock); + iguana_blockcopy(0*coin->chain->zcash,coin->chain->auxpow,coin,block,(struct iguana_block *)origblock); if ( block->lag != 0 && block->issued != 0 ) block->lag = (uint32_t)time(NULL) - block->issued; //printf("datalen.%d ipbits.%x\n",datalen,req->ipbits); @@ -1374,13 +1790,12 @@ int32_t iguana_reqblocks(struct supernet_info *myinfo,struct iguana_info *coin) int32_t hdrsi,lflag,bundlei,iters=0,flag = 0; bits256 hash2; struct iguana_block *next,*block; struct iguana_bundle *bp; if ( (block= iguana_blockfind("hwmcheck",coin,coin->blocks.hwmchain.RO.hash2)) == 0 || block->mainchain == 0 || block->height != coin->blocks.hwmchain.height ) { - printf("HWM mismatch ht.%d vs %d or not mainchain.%d\n",block->height,coin->blocks.hwmchain.height,block->mainchain); + //printf("HWM %s mismatch ht.%d vs %d or not mainchain.%d\n",coin->symbol,block->height,coin->blocks.hwmchain.height,block->mainchain); if ( coin->blocks.hwmchain.height > 0 ) { if ( (block= iguana_blockfind("hwmcheckb",coin,coin->blocks.hwmchain.RO.prev_block)) != 0 ) { - printf("decrement HWM\n"); - iguana_blockzcopy(coin->chain->zcash,(struct iguana_block *)&coin->blocks.hwmchain,block); + iguana_blockzcopy(0*coin->chain->zcash,(struct iguana_block *)&coin->blocks.hwmchain,block); return(0); } } @@ -1501,7 +1916,7 @@ int32_t iguana_reqblocks(struct supernet_info *myinfo,struct iguana_info *coin) if ( 1 && (rand() % 100000) == 0 )//|| bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) printf("%s %s MAIN.%d t %.3f lag %.3f\n",coin->symbol,bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,lag); } - if ( 0 && bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) + if ( (0) && bp != 0 && bundlei < bp->n-1 && (bits256_nonz(bp->hashes[bundlei+1]) != 0 || (bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei+1]) != 0)) ) { int32_t j; //memset(bp->hashes[bundlei].bytes,0,sizeof(bp->hashes[bundlei])); @@ -1510,7 +1925,7 @@ int32_t iguana_reqblocks(struct supernet_info *myinfo,struct iguana_info *coin) { if ( time(NULL) > bp->issued[bundlei+1+j]+10 ) { - bp->issued[bundlei+1+j] = (uint32_t)time(NULL); + bp->issued[bundlei+1+j] = 1;//(uint32_t)time(NULL); printf("MAINCHAIN skip issue %d\n",bp->bundleheight+bundlei+1+j); if ( bits256_nonz(bp->hashes[bundlei+1+j]) != 0 ) iguana_blockQ("mainskip",coin,bp,bundlei+1+j,bp->hashes[bundlei+1+j],1); @@ -1529,9 +1944,10 @@ int32_t iguana_processrecvQ(struct supernet_info *myinfo,struct iguana_info *coi { int32_t flag = 0; struct iguana_bundlereq *req; *newhwmp = 0; - while ( flag < IGUANA_MAXITERATIONS && coin->active != 0 && (req= queue_dequeue(&coin->recvQ,0)) != 0 ) + while ( flag < IGUANA_MAXITERATIONS && coin->active != 0 && (req= queue_dequeue(&coin->recvQ)) != 0 ) { - flag++; + if ( req->type != 'H' ) + flag++; //fprintf(stderr,"%s flag.%d %s recvQ.%p type.%c n.%d\n",coin->symbol,flag,req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); if ( req->type == 'B' ) // one block with all txdata { @@ -1549,7 +1965,7 @@ int32_t iguana_processrecvQ(struct supernet_info *myinfo,struct iguana_info *coi } else if ( req->type == 'S' ) // blockhashes { - if ( (req= iguana_recvblockhashes(coin,req,req->hashes,req->n)) != 0 && req->hashes != 0 ) + if ( (req= iguana_recvblockhashes(myinfo,coin,req,req->hashes,req->n)) != 0 && req->hashes != 0 ) myfree(req->hashes,sizeof(*req->hashes) * req->n), req->hashes = 0; } else if ( req->type == 'U' ) // unconfirmed tx @@ -1574,14 +1990,14 @@ int32_t iguana_processrecvQ(struct supernet_info *myinfo,struct iguana_info *coi int32_t iguana_needhdrs(struct iguana_info *coin) { - if ( coin->longestchain == 0 || coin->blocks.hashblocks < coin->longestchain-coin->chain->bundlesize ) + //if ( coin->longestchain == 0 || coin->blocks.hashblocks < coin->longestchain-coin->chain->bundlesize ) return(1); - else return(0); + //else return(0); } int32_t iguana_reqhdrs(struct iguana_info *coin) { - int32_t i,lag,n = 0; struct iguana_bundle *bp; char hashstr[65]; + int32_t i,lag,n = 0; struct iguana_bundle *bp; char hashstr[65]; uint32_t now = (uint32_t)time(NULL); //if ( queue_size(&coin->hdrsQ) == 0 ) { if ( coin->active != 0 ) @@ -1592,24 +2008,30 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) { if ( bp == coin->current ) lag = 13; - else lag = 17; - if ( time(NULL) > bp->issuetime+lag ) + else if ( coin->current == 0 || bp->hdrsi > coin->current->hdrsi+coin->MAXBUNDLES ) + continue; + else lag = 30; + if ( now > bp->issuetime+lag && now > bp->hdrtime+3 ) { - if ( 0 && bp == coin->current ) - printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); + bp->hdrtime = now; + if ( (0) && bp == coin->current ) + printf("LAG.%d hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",(uint32_t)(now-bp->hdrtime),i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); if ( bp->issuetime == 0 ) coin->numpendings++; init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - if ( bp == coin->current && coin->blocks.hwmchain.height > 100 ) + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr)); + if ( bp == coin->current ) { init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr)); //printf("%s issue HWM HDRS [%d] %s\n",coin->symbol,bp->hdrsi,hashstr); - bits256 hash2 = iguana_blockhash(coin,coin->blocks.hwmchain.height-10); - init_hexbytes_noT(hashstr,hash2.bytes,sizeof(bits256)); - //printf("%s issue HWM HDRS %d-10 %s\n",coin->symbol,coin->blocks.hwmchain.height,hashstr); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + if ( coin->blocks.hwmchain.height > 10 ) + { + bits256 hash2 = iguana_blockhash(coin,coin->blocks.hwmchain.height-10); + init_hexbytes_noT(hashstr,hash2.bytes,sizeof(bits256)); + //printf("%s issue HWM HDRS %d-10 %s\n",coin->symbol,coin->blocks.hwmchain.height,hashstr); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr)); + } } //printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); if ( 1 ) @@ -1623,7 +2045,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) } } } - if ( 0 && n > 0 ) + if ( (0) && n > 0 ) printf("REQ HDRS pending.%d\n",n); coin->zcount = 0; } @@ -1640,7 +2062,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle //getchar(); return(-1); } - if ( 1 && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 && block != 0 && block->txvalid != 0 ) + if ( (0) && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 && block != 0 && block->txvalid != 0 ) { //printf("found valid [%d:%d] in blockQ\n",block!=0?block->hdrsi:-1,block!=0?block->bundlei:-1); return(0); @@ -1680,7 +2102,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle if ( block->fpipbits == 0 && block->queued == 0 && block->req != 0 ) { block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL,0); + queue_enqueue("cacheQ",&coin->cacheQ,&block->req->DL); block->req = 0; //char str2[65]; printf("already have.(%s)\n",bits256_str(str2,block->RO.hash2)); } @@ -1690,8 +2112,13 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle return(0); height = block->height; } - if ( bp != 0 && bp->emitfinish != 0 ) - return(0); + if ( bp != 0 ) + { + if ( bp->emitfinish != 0 ) + return(0); + if ( bp != coin->current && coin->RTheight == 0 && bp->issued[bundlei] > 0 ) + return(0); + } if ( priority != 0 ) str = "priorityQ", Q = &coin->priorityQ; else str = "blocksQ", Q = &coin->blocksQ; @@ -1712,7 +2139,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle { if ( 1 && n > 200000 ) printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers != 0 ? coin->peers->numranked : -1,queue_size(Q)); - while ( (ptr= queue_dequeue(Q,0)) != 0 ) + while ( (ptr= queue_dequeue(Q)) != 0 ) myfree(ptr,sizeof(*ptr)); coin->backlog = n*10 + 1000000; } else coin->backlog >>= 1; @@ -1721,7 +2148,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle //block->numrequests++; block->issued = now; } - queue_enqueue(str,Q,&req->DL,0); + queue_enqueue(str,Q,&req->DL); return(1); } else printf("null Q\n"); } //else printf("queueblock skip priority.%d bundlei.%d\n",bundlei,priority); @@ -1732,7 +2159,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) { uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; struct iguana_block *block; struct iguana_blockreq *req=0; char *hashstr=0; bits256 hash2; - int32_t bundlei,priority,i,m,z,pend,limit,height=-1,datalen,flag = 0; + int32_t bundlei,priority,i,m=0,z,pend,limit,height=-1,datalen,flag = 0; struct stritem *hashitem; uint32_t now; struct iguana_bundle *bp; struct iguana_peer *ptr; if ( addr->msgcounts.verack == 0 ) return(0); @@ -1742,8 +2169,9 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) if ( iguana_needhdrs(coin) != 0 && addr->pendhdrs < IGUANA_MAXPENDHDRS ) { //printf("%s check hdrsQ\n",addr->ipaddr); - if ( (hashstr= queue_dequeue(&coin->hdrsQ,1)) != 0 ) + if ( (hashitem= queue_dequeue(&coin->hdrsQ)) != 0 ) { + hashstr = hashitem->str; if ( (datalen= iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,hashstr)) > 0 ) { decode_hex(hash2.bytes,sizeof(hash2),hashstr); @@ -1765,7 +2193,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } if ( bp == 0 || bp->speculative == 0 || bp == coin->current || bp->hdrsi == coin->bundlescount-1 || bp->numhashes < bp->n ) { - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("%s request HDR.(%s) numhashes.%d [%d]\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0,bp!=0?bp->hdrsi:-1); iguana_send(coin,addr,serialized,datalen); addr->pendhdrs++; @@ -1775,8 +2203,9 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) //free_queueitem(hashstr); //return(flag); } else printf("datalen.%d from gethdrs\n",datalen); - free_queueitem(hashstr); + free(hashitem); hashstr = 0; + hashitem = 0; } } //if ( netBLOCKS > coin->MAXPEERS*coin->MAXPENDING ) @@ -1792,7 +2221,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } priority = 1; pend = 0; - req = queue_dequeue(&coin->priorityQ,0); + req = queue_dequeue(&coin->priorityQ); if ( flag == 0 && req == 0 && addr->pendblocks < limit ) { priority = 0; @@ -1805,7 +2234,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } } if ( pend < coin->MAXPENDINGREQUESTS*m ) - req = queue_dequeue(&coin->blocksQ,0); + req = queue_dequeue(&coin->blocksQ); } if ( req != 0 ) { @@ -1816,6 +2245,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) if ( bp->emitfinish != 0 ) { //printf("skip emitting bundle [%d:%d]\n",bp->hdrsi,req->bundlei); + //free(req); return(0); } block = bp->blocks[req->bundlei]; @@ -1832,7 +2262,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) iguana_sendblockreqPT(coin,addr,bp,req->bundlei,hash2,0); } flag++; - myfree(req,sizeof(*req)); + free(req); } return(flag); } @@ -1842,7 +2272,7 @@ int32_t iguana_processrecv(struct supernet_info *myinfo,struct iguana_info *coin int32_t newhwm = 0,hwmheight,flag = 0; char str[2000]; hwmheight = coin->blocks.hwmchain.height; coin->RTramchain_busy = 1; - if ( coin->balanceflush != 0 ) + if ( coin->balanceflush != 0 && coin->longestchain > coin->chain->bundlesize ) { fprintf(stderr,"%s call balanceflush\n",coin->symbol); //portable_mutex_lock(&coin->RTmutex); @@ -1866,9 +2296,9 @@ int32_t iguana_processrecv(struct supernet_info *myinfo,struct iguana_info *coin } } flag += iguana_processrecvQ(myinfo,coin,&newhwm); - if ( coin->RTheight == 0 || (rand() % 30) == 0 ) + if ( coin->RTheight == 0 || (rand() % 7) == 0 ) flag += iguana_reqblocks(myinfo,coin); - if ( time(NULL) > coin->laststats+30 ) + if ( time(NULL) > coin->laststats+3 ) { flag += iguana_reqhdrs(coin); iguana_bundlestats(myinfo,coin,str,IGUANA_DEFAULTLAG); diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index 32dd36668..d79aefe24 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,26 +13,39 @@ * * ******************************************************************************/ +#define WHITELIST_IPADDR "" + #include "iguana777.h" //#include "SuperNET.h" -#define RPCARGS struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr,cJSON *array -#define GLUEARGS cJSON *json,struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,char *remoteaddr,cJSON *params[] +#define RPCARGS struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr,cJSON *array,char *userpass +#define GLUEARGS cJSON *json,struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,char *remoteaddr,cJSON *params[],char *userpass -#define CALLGLUE myinfo,port,coin,remoteaddr,params +#define CALLGLUE myinfo,port,coin,remoteaddr,params,userpass char *sglue(GLUEARGS,char *agent,char *method) { - char *retstr,*rpcretstr,*walletstr,checkstr[64],dcheckstr[64]; cJSON *retjson,*tmpjson,*result,*error,*wallet; int32_t i,j,len; int64_t val; double dval; + char *retstr,*rpcretstr,*walletstr,checkstr[65],dcheckstr[65]; cJSON *retjson,*tmpjson,*result,*error,*wallet; int32_t i,j,len; int64_t val; double dval; if ( json == 0 ) json = cJSON_CreateObject(); - //printf("sglue.(%s)\n",jprint(json,0)); +//printf("userpass.(%s)\n",userpass); jaddstr(json,"agent",agent); jaddstr(json,"method",method); - jaddstr(json,"coin",coin->symbol); + if ( coin != 0 ) + jaddstr(json,"coin",coin->symbol); + if ( userpass != 0 ) + jaddstr(json,"userpass",userpass); + if ( coin != 0 && coin->FULLNODE >= 0 && coin->chain->userpass[0] != 0 ) + { + if ( userpass == 0 || strcmp(userpass,coin->chain->userpass) != 0 ) + { + printf("iguana authentication error {%s} (%s) != (%s)\n",jprint(json,0),userpass,coin->chain->userpass); + return(clonestr("{\"error\":\"authentication error\"}")); + } + } if ( myinfo->expiration != 0 && time(NULL) > myinfo->expiration ) iguana_walletlock(myinfo,0); - if ( (retstr= SuperNET_JSON(myinfo,json,remoteaddr,port)) != 0 ) + if ( (retstr= SuperNET_JSON(myinfo,coin,json,remoteaddr,port)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -40,7 +53,6 @@ char *sglue(GLUEARGS,char *agent,char *method) { if ( (wallet= iguana_walletjson(myinfo)) != 0 ) { - //printf("WALLETSTR.(%s)\n",jprint(wallet,0)); if ( (walletstr= SuperNET_login(myinfo,coin,json,remoteaddr,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) { free(walletstr); @@ -51,7 +63,7 @@ char *sglue(GLUEARGS,char *agent,char *method) jadd(tmpjson,"wallet",wallet); if ( iguana_payloadupdate(myinfo,coin,jprint(tmpjson,1),0,0) == 0 ) { - printf("wallet updated\n"); + //printf("wallet updated\n"); myinfo->dirty = 0; } else printf("iguana_payloadupdate error\n"); } else printf("error parsing decryptstr\n"); @@ -195,7 +207,7 @@ static char *sendalert(RPCARGS) static char *SuperNET(RPCARGS) { - return(SuperNET_JSON(myinfo,json,remoteaddr,port)); + return(SuperNET_JSON(myinfo,coin,json,remoteaddr,port)); } static char *getrawmempool(RPCARGS) @@ -387,6 +399,11 @@ static char *dumpprivkey(RPCARGS) return(sglue1(0,CALLGLUE,"bitcoinrpc","dumpprivkey","address",params[0])); } +static char *importaddress(RPCARGS) +{ + return(sglue3(0,CALLGLUE,"bitcoinrpc","importaddress","address",params[0],"account",params[1],"rescan",params[2])); +} + static char *importprivkey(RPCARGS) { return(sglue3(0,CALLGLUE,"bitcoinrpc","importprivkey","wif",params[0],"account",params[1],"rescan",params[2])); @@ -601,6 +618,7 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remotefla { "dumpwallet", &dumpwallet, true, false }, { "importwallet", &importwallet, false, false }, { "importprivkey", &importprivkey, false, false }, + { "importaddress", &importaddress, false, false }, { "getrawtransaction", &getrawtransaction, false, false }, { "createrawtransaction", &createrawtransaction, false, false }, { "validaterawtransaction", &validaterawtransaction, false, true }, @@ -650,7 +668,7 @@ int32_t is_bitcoinrpc(struct supernet_info *myinfo,char *method,char *remoteaddr { if ( strcmp(RPCcalls[i].name,method) == 0 ) { - if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) + if ( remoteaddr == 0 || remoteaddr[0] == 0 || strncmp(remoteaddr,"127.0.0.",strlen("127.0.0.")) == 0 ) return(1); if ( RPCcalls[i].remoteflag != 0 && myinfo->publicRPC != 0 ) return(i); @@ -665,57 +683,69 @@ char *iguana_bitcoinrpc(struct supernet_info *myinfo,uint16_t port,struct iguana for (i=0; irpcport ) { - if ( port == myinfo->rpcport ) + if ( jstr(json,"coin") == 0 ) { - if ( jstr(json,"coin") == 0 ) + strcpy(symbol,myinfo->rpcsymbol); + if ( symbol[0] == 0 ) { - strcpy(symbol,myinfo->rpcsymbol); - if ( symbol[0] == 0 ) - { - c = 'B'; - sprintf(symbol,"%c%c%c%c",c,'T',c+1,c+2); - } + c = 'B'; + sprintf(symbol,"%c%c%c%c",c,'T',c+1,c+2); } - else - { - safecopy(symbol,jstr(json,"coin"),sizeof(symbol)); - for (i=0; symbol[i]!=0; i++) - symbol[i] = toupper((int32_t)symbol[i]); - } - if ( myinfo->rpcsymbol[0] == 0 ) - strcpy(myinfo->rpcsymbol,symbol); } else { - //portable_mutex_lock(&myinfo->allcoins_mutex); - HASH_ITER(hh,myinfo->allcoins,coin,tmp) - { - if ( coin->chain->rpcport == port ) - break; - else coin = 0; - } - //portable_mutex_unlock(&myinfo->allcoins_mutex); + safecopy(symbol,jstr(json,"coin"),sizeof(symbol)); + for (i=0; symbol[i]!=0; i++) + symbol[i] = toupper((int32_t)symbol[i]); + } + } + else + { + //portable_mutex_lock(&myinfo->allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->chain->rpcport == port ) + break; + else coin = 0; } - if ( coin == 0 && symbol[0] != 0 ) - coin = iguana_coinfind(symbol); + //portable_mutex_unlock(&myinfo->allcoins_mutex); + } + if ( coin == 0 && symbol[0] != 0 ) + coin = iguana_coinfind(symbol); + return(coin); +} + +char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr,uint16_t port) +{ + cJSON *params[16],*array; struct iguana_info *coin = 0; char symbol[16],*userpass; uint32_t immed; int32_t i,n; char *retstr = 0; + symbol[0] = 0; + memset(params,0,sizeof(params)); +//printf("bitcoinRPC.(%s)\n",jprint(json,0)); + if ( json != 0 ) + { + userpass = jstr(json,"userpass"); + coin = iguana_coinchoose(myinfo,symbol,json,port); + if ( myinfo->rpcsymbol[0] == 0 ) + strcpy(myinfo->rpcsymbol,symbol); if ( coin != 0 ) safecopy(symbol,coin->symbol,sizeof(symbol)); //printf("method.(%s) (%s) remote.(%s) symbol.(%s)\n",method,jprint(json,0),remoteaddr,symbol); if ( method != 0 && symbol[0] != 0 && (coin != 0 || (coin= iguana_coinfind(symbol)) != 0) ) { + if ( (immed= juint(json,"immediate")) != 0 ) + { + if ( iguana_immediate(coin,immed) == 0 ) + return(clonestr("{\"error\":\"coin is busy processing\"}")); + } if ( (array= jarray(&n,json,"params")) == 0 ) { i = 0, n = 0; @@ -729,7 +759,7 @@ char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,ch //printf("add params[%d] of %d <- (%s) %p.(%p %p)\n",i,n,jprint(params[i],0),params[i],params[i]->next,params[i]->prev); } } - retstr = iguana_bitcoinrpc(myinfo,IGUANA_RPCPORT,coin,method,params,n,json,remoteaddr,array); + retstr = iguana_bitcoinrpc(myinfo,myinfo->rpcport,coin,method,params,n,json,remoteaddr,array); if ( n > 0 ) for (i=0; iremoteorigin == 0 ) + { + for (iter=0; iter<2; iter++) + { + fieldstr = (iter == 0) ? "Origin: " : "Referer: "; + n = (int32_t)(strlen(urlstr) - strlen(fieldstr)); + for (i=0; i 1 ) jaddstr(argjson,"method",jstri(tokens,1)); - //printf("urlstr.(%s)\n",urlstr+n); if ( (json= SuperNET_urlconv(retbuf,bufsize,urlstr+n)) != 0 ) { jadd(json,"tokens",tokens); jaddstr(json,"urlmethod",urlmethod); if ( (data= jstr(json,"POST")) == 0 || (argjson= cJSON_Parse(data)) == 0 ) { + userpass = jstr(argjson,"userpass"); + //printf("userpass.(%s)\n",userpass); if ( (n= cJSON_GetArraySize(tokens)) > 0 ) { if ( n > 1 ) @@ -1009,7 +1067,7 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz jaddstr(argjson,"data",jstri(tokens,i)); else { - if ( strcmp(jstri(tokens,i),"coin") == 0 && strlen(jstri(tokens,i+1)) < 8 ) + if ( strcmp(jstri(tokens,i),"coin") == 0 && strlen(jstri(tokens,i+1)) < sizeof(symbol)-1 ) { strcpy(symbol,jstri(tokens,i+1)); touppercase(symbol); @@ -1024,11 +1082,15 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz { cJSON *retitem,*retarray = cJSON_CreateArray(); origargjson = argjson; + symbol[0] = 0; for (i=0; iargport) == 0 ) @@ -1087,6 +1170,7 @@ void iguana_rpcloop(void *args) sleep(3); } printf(">>>>>>>>>> iguana_rpcloop 127.0.0.1:%d bind sock.%d iguana API enabled <<<<<<<<<\n",port,bindsock); + fflush(stdout); space = calloc(1,size); while ( bindsock >= 0 ) { @@ -1095,11 +1179,15 @@ void iguana_rpcloop(void *args) sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { - //printf("iguana_rpcloop ERROR on accept usock.%d\n",sock); + //printf("iguana_rpcloop ERROR on accept usock.%d errno %d %s\n",sock,errno,strerror(errno)); continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(remoteaddr,ipbits); + if ( strcmp(WHITELIST_IPADDR,remoteaddr) == 0 || strncmp(remoteaddr,"127.0.0.",strlen("127.0.0.")) == 0 ) + strcpy(remoteaddr,"127.0.0.1"); + else printf("remote RPC request from (%s) %x\n",remoteaddr,ipbits); + memset(jsonbuf,0,IGUANA_MAXPACKETSIZE); remains = (int32_t)(IGUANA_MAXPACKETSIZE - 1); buf = jsonbuf; diff --git a/iguana/iguana_scripts.c b/iguana/iguana_scripts.c index 1e6ad9a67..57e8181d1 100755 --- a/iguana/iguana_scripts.c +++ b/iguana/iguana_scripts.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -34,14 +34,26 @@ int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) return(n); } -int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]) +int32_t bitcoin_secret160verify(uint8_t *script,int32_t n,uint8_t secret160[20]) { script[n++] = SCRIPT_OP_HASH160; - script[n++] = 0x14; memcpy(&script[n],secret160,0x14); n += 0x14; + script[n++] = 0x14; + memcpy(&script[n],secret160,0x14); + n += 0x14; script[n++] = SCRIPT_OP_EQUALVERIFY; return(n); } +int32_t bitcoin_secret256spend(uint8_t *script,int32_t n,bits256 secret) +{ + script[n++] = SCRIPT_OP_SHA256; + script[n++] = 0x20; + memcpy(&script[n],secret.bytes,0x20); + n += 0x20; + script[n++] = SCRIPT_OP_EQUAL; + return(n); +} + // OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) { @@ -65,6 +77,13 @@ int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime) return(n); } +int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint32_t timestamp) +{ + n = bitcoin_checklocktimeverify(script,n,timestamp); + n = bitcoin_standardspend(script,n,rmd160); + return(n); +} + int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp) { int32_t i,plen; @@ -91,11 +110,11 @@ int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,c script[n++] = (p2shlen & 0xff); script[n++] = ((p2shlen >> 8) & 0xff); } - else + else if ( p2shlen > 76 ) { script[n++] = 0x4c; script[n++] = p2shlen; - } + } else script[n++] = p2shlen; memcpy(&script[n],p2shscript,p2shlen), n += p2shlen; return(n); } @@ -166,7 +185,7 @@ int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd n = bitcoin_checklocktimeverify(script,n,locktime); n = bitcoin_standardspend(script,n,rmd160A); script[n++] = SCRIPT_OP_ELSE; - n = bitcoin_revealsecret160(script,n,secret160); + n = bitcoin_secret160verify(script,n,secret160); n = bitcoin_standardspend(script,n,rmd160B); script[n++] = SCRIPT_OP_ENDIF; calc_rmd160_sha256(p2sh_rmd160,script,n); @@ -178,7 +197,11 @@ uint8_t iguana_addrtype(struct iguana_info *coin,uint8_t script_type) { if ( script_type == IGUANA_SCRIPT_76A988AC || script_type == IGUANA_SCRIPT_AC || script_type == IGUANA_SCRIPT_76AC ) return(coin->chain->pubtype); - else return(coin->chain->p2shtype); + else + { + //printf("P2SH type.%d\n",script_type); + return(coin->chain->p2shtype); + } } int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi) @@ -287,9 +310,11 @@ int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) { static uint8_t zero_rmd160[20]; - char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen; - vp->N = 1; - vp->M = 1; + char hexstr[8192]; uint8_t *script,type; int32_t i,n,m,plen; + if ( vp->N == 0 ) + vp->N = 1; + if ( vp->M == 0 ) + vp->M = 1; type = IGUANA_SCRIPT_STRANGE; init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); //char str[65]; printf("script.(%s).%d in %s len.%d plen.%d spendlen.%d cmp.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen,bitcoin_pubkeylen(&vp->spendscript[1]),vp->spendlen,vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG); @@ -301,7 +326,6 @@ int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) //vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 //calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb init_hexbytes_noT(hexstr,zero_rmd160,20); - char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr); } memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); return(IGUANA_SCRIPT_NULL); @@ -316,9 +340,9 @@ int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) if ( (plen= vp->spendscript[2]+5) != vp->spendlen ) { return(IGUANA_SCRIPT_STRANGE); - while ( plen < vp->spendlen ) + /*while ( plen < vp->spendlen ) if ( vp->spendscript[plen++] != 0x61 ) // nop - return(IGUANA_SCRIPT_STRANGE); + return(IGUANA_SCRIPT_STRANGE);*/ } return(IGUANA_SCRIPT_76A988AC); } @@ -447,14 +471,26 @@ int32_t iguana_calcrmd160(struct iguana_info *coin,char *asmstr,struct vin_info return(vp->type); } +char *iguana_scriptaddress(struct iguana_info *coin,char *coinaddr,uint8_t *script,int32_t scriptlen) +{ + struct vin_info V; + iguana_calcrmd160(coin,0,&V,script,scriptlen,GENESIS_PUBKEY,0,0xffffffff); + if ( V.coinaddr[0] != 0 ) + { + strcpy(coinaddr,V.coinaddr); + return(coinaddr); + } + return(0); +} + //error memalloc mem.0x7f6fc6e4a2a8 94.242.229.158 alloc 1 used 2162688 totalsize.2162688 -> 94.242.229.158 (nil) int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) { - char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; uint8_t *p2shscript; + int32_t j,n,siglen,plen; uint8_t *p2shscript; j = n = 0; *userdatap = 0; - *userdatalenp = *pubkeysizep = 0; + *userdatalenp = *pubkeysizep = *sigsizep = 0; *hashtypep = SIGHASH_ALL; while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) { @@ -495,7 +531,8 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * } vp->numpubkeys = j; *userdatap = &scriptsig[n]; - *userdatalenp = (len - n); + if ( len > n ) + *userdatalenp = (len - n); p2shscript = 0; while ( n < len ) { @@ -522,7 +559,7 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe"); vp->type = IGUANA_SCRIPT_76A988AC; }*/ - vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); + vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,0,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); //printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); return(vp->spendlen); } @@ -550,7 +587,9 @@ char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int { int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; struct vin_info V,*vp = &V; memset(vp,0,sizeof(*vp)); - scriptstr[0] = asmstr[0] = 0; + scriptstr[0] = 0; + if ( asmstr != 0 ) + asmstr[0] = 0; if ( pubkey33 != 0 && bitcoin_pubkeylen(pubkey33) > 0 ) memcpy(vp->signers[0].pubkey,pubkey33,33); scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout); @@ -681,6 +720,8 @@ int32_t iguana_vinscriptdecode(struct iguana_info *coin,struct iguana_ramchain * if ( p2shlen > 0 && p2shlen < IGUANA_MAXSCRIPTSIZE ) { if ( p2shlen <= 75 ) + _script[scriptlen++] = p2shlen; + else if ( p2shlen <= 0xff ) _script[scriptlen++] = 0x4c, _script[scriptlen++] = p2shlen; else _script[scriptlen++] = 0x4d, _script[scriptlen++] = p2shlen & 0xff, _script[scriptlen++] = (p2shlen>>8) & 0xff; //printf("p2shlen.%d\n",p2shlen); diff --git a/iguana/iguana_secp.c b/iguana/iguana_secp.c index 2e25b0ecc..c53170908 100755 --- a/iguana/iguana_secp.c +++ b/iguana/iguana_secp.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -37,7 +37,11 @@ int32_t bitcoin_pubkeylen(const uint8_t *pubkey) return(33); else if ( pubkey[0] == 4 ) return(65); - else return(-1); + else + { + //printf("illegal pubkey.[%02x] %llx\n",pubkey[0],*(long long *)pubkey); + return(-1); + } } bits256 bitcoin_randkey(secp256k1_context *ctx) @@ -68,7 +72,7 @@ bits256 bitcoin_pubkey33(secp256k1_context *ctx,uint8_t *data,bits256 privkey) { if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) { - printf("bitcoin_sign illegal privkey\n"); + //printf("bitcoin_sign illegal privkey\n"); return(pubkey); } if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) != 0 ) @@ -108,7 +112,7 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 { if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) { - printf("bitcoin_sign illegal privkey\n"); + //printf("bitcoin_sign illegal privkey\n"); return(-1); } if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 ) @@ -127,10 +131,15 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 { sig[0] = 27 + recid + (fCompressed != 0 ? 4 : 0); retval = 64 + 1; - } - else printf("secpub mismatch\n"); + //size_t i,plen = 33; uint8_t pubkey[33]; + //secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&CHECKPUB,SECP256K1_EC_COMPRESSED); + //for (i=0; i<33; i++) + // printf("%02x",pubkey[i]); + //printf(" bitcoin_sign's pubkey\n"); + + } //else printf("secpub mismatch\n"); } else printf("pubkey create error\n"); - } else printf("recover error\n"); + } //else printf("recover error\n"); } else printf("secp256k1_ecdsa_sign_recoverable error\n"); } else @@ -147,18 +156,23 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 return(retval); } -int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig65,bits256 messagehash2,uint8_t *pubkey) +int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen) { - int32_t retval = -1; size_t plen; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; + int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; pubkey[0] = 0; SECP_ENSURE_CTX { - plen = (sig65[0] <= 31) ? 65 : 33; - secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig65 + 1,0); + if ( plen == 0 ) + { + plen = (sig[0] <= 31) ? 65 : 33; + sig++; + } + secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig,0); secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG); if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) != 0 ) { plen = 33; + memset(pubkey,0,33); secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED);//plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED); if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) != 0 ) { @@ -167,8 +181,7 @@ int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig65,bits256 mess pubkey[0] = 2; else if ( pubkey[0] != 2 ) pubkey[0] = 3;*/ - } - else printf("secp256k1_ecdsa_verify error\n"); + } else printf("secp256k1_ecdsa_verify error\n"); } else printf("secp256k1_ecdsa_recover error\n"); ENDSECP_ENSURE_CTX } @@ -438,95 +451,6 @@ int32_t bitcoin_rangeproof(void *ctx,uint8_t *proof,uint8_t *commit,bits256 blin return(retval); } -/* - * The intended procedure for creating a multiparty signature is: - * - Each signer S[i] with private key x[i] and public key Q[i] runs - * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of private/public nonces. - * - All signers communicate their public nonces to each other (revealing your - * private nonce can lead to discovery of your private key, so it should be considered secret). - * - All signers combine all the public nonces they received (excluding their - * own) using secp256k1_ec_pubkey_combine to obtain an Rall[i] = sum(R[0..i-1,i+1..n]). - * - All signers produce a partial signature using - * secp256k1_schnorr_partial_sign, passing in their own private key x[i], - * their own private nonce k[i], and the sum of the others' public nonces Rall[i]. - * - All signers communicate their partial signatures to each other. - * - Someone combines all partial signatures using secp256k1_schnorr_partial_combine, to obtain a full signature. - * - The resulting signature is validatable using secp256k1_schnorr_verify, with - * public key equal to the result of secp256k1_ec_pubkey_combine of the signers' public keys (sum(Q[0..n])). - * - * Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine - * function take their arguments in any order, and it is possible to - * pre-combine several inputs already with one call, and add more inputs later - * by calling the function again (they are commutative and associative). - */ - -#ifdef test_schnorr -#include "secp256k1/src/util.h" -#include "secp256k1/src/hash_impl.h" -#include "secp256k1/src/testrand_impl.h" - -void test_schnorr_threshold(void *ctx) { - unsigned char msg[32]; - unsigned char sec[5][32]; - secp256k1_pubkey pub[5]; - unsigned char nonce[5][32]; - secp256k1_pubkey pubnonce[5]; - unsigned char sig[5][64]; - const unsigned char* sigs[5]; - unsigned char allsig[64]; - const secp256k1_pubkey* pubs[5]; - secp256k1_pubkey allpub; - int n, i; - int damage; - int ret = 0; - - damage = secp256k1_rand_bits(1) ? (1 + secp256k1_rand_int(4)) : 0; - secp256k1_rand256_test(msg); - n = 2 + secp256k1_rand_int(4); - for (i = 0; i < n; i++) { - do { - secp256k1_rand256_test(sec[i]); - } while (!secp256k1_ec_seckey_verify(ctx, sec[i])); - CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i])); - CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL)); - pubs[i] = &pub[i]; - } - if (damage == 1) { - nonce[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } else if (damage == 2) { - sec[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - for (i = 0; i < n; i++) { - secp256k1_pubkey allpubnonce; - const secp256k1_pubkey *pubnonces[4]; - int j; - for (j = 0; j < i; j++) { - pubnonces[j] = &pubnonce[j]; - } - for (j = i + 1; j < n; j++) { - pubnonces[j - 1] = &pubnonce[j]; - } - CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1)); - ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1; - sigs[i] = sig[i]; - } - if (damage == 3) { - sig[secp256k1_rand_int(n)][secp256k1_rand_bits(6)] ^= 1 + secp256k1_rand_int(255); - } - ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2; - if ((ret & 1) == 0) { - ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4; - } - if (damage == 4) { - allsig[secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); - } - if ((ret & 7) == 0) { - ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8; - } - CHECK((ret == 0) == (damage == 0)); -} -#endif - int32_t iguana_pederson_test(void *ctx) { uint8_t commits[100][33],*commitptrs[100],proofs[100][5138]; uint16_t vouts[100]; int64_t min_value,values[100],totalpos,totalneg; bits256 txids[100],nonces[100],blinds[100],*blindptrs[100],blindsum; int32_t prooflens[100],i,r,pos,neg,numpos,exponent,min_bits,n,N = 100; @@ -642,9 +566,9 @@ int32_t iguana_schnorr_test(void *ctx) { sigs[i] = sig64[i]; continue; - for (j=0; j<64; j++) - printf("%02x",sig64[i][j]); - printf(" sig[%d]\n",i); + //for (j=0; j<64; j++) + // printf("%02x",sig64[i][j]); + //printf(" sig[%d]\n",i); } for (i=0; iprev_hash),msg->prev_hash.bytes); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); + //char str[65]; printf("prev_hash.(%s) v%d\n",bits256_str(str,msg->prev_hash),msg->prev_vout); if ( rwflag == 1 ) { tmp = msg->scriptlen + msg->userdatalen + msg->p2shlen; @@ -38,14 +39,14 @@ int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *seriali len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); if ( rwflag == 0 ) { - if ( msg->p2shlen != 0 ) + /*if ( msg->p2shlen != 0 ) { if ( msg->p2shlen < 76 ) tmp++; else if ( msg->p2shlen < 0x100 ) tmp += 2; else tmp += 3; - } + }*/ msg->scriptlen = tmp; } if ( msg->scriptlen > IGUANA_MAXSCRIPTSIZE ) @@ -62,7 +63,7 @@ int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *seriali else { if ( msg->vinscript != 0 && msg->scriptlen > 0 ) - memcpy(&serialized[len],msg->vinscript,msg->scriptlen), len += msg->scriptlen; // pubkeys here + memcpy(&serialized[len],msg->vinscript,msg->scriptlen), len += msg->scriptlen; // pubkeys here if ( msg->userdatalen > 0 && msg->userdata != 0 ) { //printf("userdata.%d scriptlen.%d\n",msg->userdatalen,msg->scriptlen); @@ -71,7 +72,6 @@ int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *seriali } if ( (p2shlen= msg->p2shlen) > 0 && msg->redeemscript != 0 ) { - //printf("p2shlen.%d %x\n",p2shlen,p2shlen); if ( p2shlen < 76 ) serialized[len++] = p2shlen; else if ( p2shlen <= 0xff ) @@ -86,10 +86,18 @@ int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *seriali serialized[len++] = ((p2shlen >> 8) & 0xff); } else return(-1); memcpy(&serialized[len],msg->redeemscript,p2shlen), len += p2shlen; + if ( (0) ) + { + int32_t j; + for (j=0; jredeemscript[j]); + printf(" p2shlen.%d %x\n",p2shlen,p2shlen); + } } } + //printf("sequence starts.%d %08x\n",len,*(int32_t *)&serialized[len]); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); - if ( 0 ) + if ( (0) ) { int32_t i; char str[65]; for (i=0; ipk_script = &serialized[len]; - else memcpy(&serialized[len],msg->pk_script,msg->pk_scriptlen); - if ( 0 ) + else if ( msg->pk_scriptlen > 0 ) { - int32_t i; - for (i=0; ipk_scriptlen; i++) - printf("%02x",msg->pk_script[i]); - printf(" [%p] scriptlen.%d rwflag.%d %.8f\n",msg->pk_script,msg->pk_scriptlen,rwflag,dstr(msg->value)); - } + memcpy(&serialized[len],msg->pk_script,msg->pk_scriptlen); + if ( (0) ) + { + int32_t i; + for (i=0; ipk_scriptlen; i++) + printf("%02x",msg->pk_script[i]); + printf(" [%p] scriptlen.%d rwflag.%d %.8f\n",msg->pk_script,msg->pk_scriptlen,rwflag,dstr(msg->value)); + } + } // else serialized[len++] = 0; len += msg->pk_scriptlen; return(len); } @@ -136,13 +147,13 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin,bits256 jaddnum(json,"vout",vout); if ( bits256_nonz(sigtxid) != 0 ) jaddbits256(json,"sigtxid",sigtxid); - if ( vin->scriptlen > 0 ) // sigs + if ( vin->scriptlen > 0 && vin->vinscript != 0 ) // sigs iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"scriptSig"); if ( vin->userdatalen > 0 && vin->userdata != 0 ) iguana_addscript(coin,json,vin->userdata,vin->userdatalen,"userdata"); - if ( vin->p2shlen > 0 ) + if ( vin->p2shlen > 0 && vin->redeemscript != 0 ) iguana_addscript(coin,json,vin->redeemscript,vin->p2shlen,"redeemScript"); - if ( vin->spendlen > 0 ) + if ( vin->spendlen > 0 && vin->spendscript != 0 ) iguana_addscript(coin,json,vin->spendscript,vin->spendlen,"scriptPubKey"); } return(json); @@ -154,7 +165,10 @@ int32_t iguana_parsehexstr(uint8_t **destp,uint16_t *lenp,uint8_t *dest2,int32_t n = (int32_t)strlen(hexstr) >> 1; //printf("addhex.(%s) %d\n",hexstr,n); if ( serialized == 0 ) - serialized = *destp; + { + if ( (serialized= *destp) == 0 ) + printf("iguana_parsehexstr null serialized and destp\n"); + } if ( serialized != 0 ) { decode_hex(serialized,n,hexstr); @@ -169,9 +183,18 @@ int32_t iguana_parsehexstr(uint8_t **destp,uint16_t *lenp,uint8_t *dest2,int32_t return(n); } +int32_t iguana_scriptnum(uint8_t opcode) +{ + if ( opcode == 0x00 ) + return(0); + else if ( opcode >= 0x51 && opcode < 0x60 ) + return(opcode - 0x50); + else return(-1); +} + int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V) { - struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint8_t lastbyte; uint32_t tmp=0; int32_t i,n,starti,suppress_pubkeys,siglen,plen,m,rwflag=1,need_op0=0,len = 0; char *userdata,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; + struct iguana_outpoint outpt; struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint8_t lastbyte,spendscript[8192]; uint32_t tmp=0; int32_t i,n,starti,spendlen,suppress_pubkeys,siglen,plen,m,endi,z,rwflag=1,len = 0; char *userdata=0,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; //printf("PARSEVIN.(%s) vin.%p\n",jprint(vinobj,0),vin); if ( V == 0 ) memset(vin,0,sizeof(*vin)); @@ -183,17 +206,26 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin if ( (hexstr= jstr(vinobj,"coinbase")) == 0 ) { vin->prev_hash = jbits256(vinobj,"txid"); + //char str[65]; printf("vin->prev_hash.(%s)\n",bits256_str(str,vin->prev_hash)); vin->prev_vout = jint(vinobj,"vout"); if ( (scriptjson= jobj(vinobj,"scriptSig")) != 0 ) hexstr = jstr(scriptjson,"hex"); - if ( ((spendstr= jstr(vinobj,"scriptPub")) == 0 && (spendstr= jstr(vinobj,"scriptPubkey")) == 0) || is_hexstr(spendstr,(int32_t)strlen(spendstr)) <= 0 ) + if ( ((spendstr= jstr(vinobj,"scriptPub")) == 0 && (spendstr= jstr(vinobj,"scriptPubKey")) == 0) || is_hexstr(spendstr,(int32_t)strlen(spendstr)) <= 0 ) { - if ( (obj= jobj(vinobj,"scriptPub")) != 0 || (obj= jobj(vinobj,"scriptPubkey")) != 0 ) + if ( (obj= jobj(vinobj,"scriptPub")) != 0 || (obj= jobj(vinobj,"scriptPubKey")) != 0 ) { spendstr = jstr(obj,"hex"); - lastbyte = _decode_hex(&spendstr[strlen(spendstr)-2]); - if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) - need_op0 = 1; + if ( spendstr[0] != 0 ) + { + lastbyte = _decode_hex(&spendstr[strlen(spendstr)-2]); + //if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) + // need_op0 = 1; + if ( V != 0 ) + { + V->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(V->spendscript,V->spendlen,spendstr); + } + } } } if ( (redeemstr= jstr(vinobj,"redeemScript")) == 0 || is_hexstr(redeemstr,(int32_t)strlen(redeemstr)) <= 0 ) @@ -202,8 +234,8 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin { redeemstr = jstr(obj,"hex"); lastbyte = _decode_hex(&redeemstr[strlen(redeemstr)-2]); - if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) - need_op0 = 1; + //if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) + // need_op0 = 1; } } if ( (userdata= jstr(vinobj,"userdata")) == 0 || is_hexstr(userdata,(int32_t)strlen(userdata)) <= 0 ) @@ -212,67 +244,89 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin userdata = jstr(obj,"hex"); } } + //char str[65]; printf("rw.%d prevhash.(%s)\n",rwflag,bits256_str(str,vin->prev_hash)); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(vin->prev_hash),vin->prev_hash.bytes); len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->prev_vout),&vin->prev_vout); if ( V != 0 ) { - if ( vin->vinscript == 0 ) + V->suppress_pubkeys = suppress_pubkeys; + if ( vin->vinscript == 0 && V->spendlen == 0 ) { - if ( (V->unspentind= iguana_RTunspentindfind(myinfo,coin,V->coinaddr,V->spendscript,&V->spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1,0)) > 0 ) + if ( iguana_RTunspentindfind(myinfo,coin,&outpt,V->coinaddr,spendscript,&spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1,0) == 0 ) { + V->unspentind = outpt.unspentind; if ( V->coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,V->coinaddr)) != 0 ) { - memcpy(V->signers[0].pubkey,waddr->pubkey,bitcoin_pubkeylen(waddr->pubkey)); + plen = bitcoin_pubkeylen(waddr->pubkey); + for (z=0; zsigners[0].pubkey[z] = waddr->pubkey[z]; } //printf("V %.8f (%s) spendscript.[%d]\n",dstr(V->amount),V->coinaddr,V->spendlen); } + if ( spendlen != 0 && V->spendlen == 0 ) + { + V->spendlen = spendlen; + memcpy(V->spendscript,spendscript,spendlen); + } } } tmp = IGUANA_MAXSCRIPTSIZE; - len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); starti = len; - if ( need_op0 != 0 ) - serialized[len++] = 0; // hack for bug for bug backward compatibility + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + endi = len; + //printf("rwflag.%d len.%d tmp.%d\n",rwflag,len,tmp); + //if ( need_op0 != 0 ) + // serialized[len++] = 0; // hack for bug for bug backward compatibility if ( hexstr != 0 ) { n = (int32_t)strlen(hexstr) >> 1; - printf("add.(%s) offset.%d\n",hexstr,len); + //printf("add.(%s) offset.%d\n",hexstr,len); vin->vinscript = &serialized[len]; decode_hex(&serialized[len],n,hexstr); - vin->scriptlen = n + need_op0; + vin->scriptlen = n;// + need_op0; if ( V != 0 ) { i = m = 0; while ( m < n ) { siglen = serialized[len + m++]; - if ( i == 0 && m == 1 && siglen == 0 ) // multisig backward compatible - continue; - memcpy(V->signers[i].sig,&serialized[len + m],siglen); + //if ( i == 0 && m == 1 && siglen == 0 ) // multisig backward compatible + // continue; + if ( serialized[len + m + siglen - 1] == SIGHASH_ALL ) + memcpy(V->signers[i++].sig,&serialized[len + m],siglen); + if ( (0) ) + { + int32_t j; + for (j=0; jvinscript != 0 ) { - if ( vin->vinscript == 0 ) + /*if ( vin->vinscript == 0 ) { - printf("null vinscript case\n"); vin->vinscript = serialized; vin->vinscript[0] = 0; vin->scriptlen = 1; - } + }*/ for (i=0; i> 1) > 0 ) { if ( V != 0 ) + { memcpy(V->signers[i].pubkey,&vin->vinscript[vin->scriptlen],plen); + if ( V->spendlen == 35 && V->spendscript[0] == 33 && V->spendscript[34] == 0xac ) + suppress_pubkeys = 1; + } if ( suppress_pubkeys == 0 ) { printf("addpub.(%s)\n",pubkeystr); @@ -285,14 +339,14 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin } } } - //printf("len.%d: ",len); + //printf("userdata len.%d: ",len); if ( userdata != 0 ) { n = iguana_parsehexstr(&vin->userdata,&vin->userdatalen,V!=0?V->userdata:0,V!=0?&V->userdatalen:0,&serialized[len],userdata); - printf("parsed userdata.%d\n",n); + //printf("parsed userdata.%d\n",n); len += n; } - //printf("len.%d: ",len); + //printf("redeemlen.%d: ",len); if ( redeemstr != 0 ) { n = (int32_t)strlen(redeemstr) >> 1; @@ -311,18 +365,51 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin } n = iguana_parsehexstr(&vin->redeemscript,&vin->p2shlen,V!=0?V->p2shscript:0,V!=0?&V->p2shlen:0,&serialized[len],redeemstr); len += n; + if ( vin->redeemscript[vin->p2shlen-1] == SCRIPT_OP_CHECKMULTISIG ) + { + V->M = iguana_scriptnum(vin->redeemscript[0]); + V->N = iguana_scriptnum(vin->redeemscript[vin->p2shlen-2]); + } + } + tmp = (len - endi); + if ( tmp < 0xfd ) + { + serialized[starti] = tmp; + for (i=starti+1; i> 8) & 0xff); - //printf("output sequence.[%d] <- %x\n",len,vin->sequence); + else + { + //for (i=0; i> 8) & 0xff); + } + //printf("len.%d tmp.%d output sequence.[%d] <- %x\n",len,tmp,len,vin->sequence); len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->sequence),&vin->sequence); if ( spendstr != 0 ) { - n = iguana_parsehexstr(&vin->spendscript,&vin->spendlen,V!=0?V->spendscript:0,V!=0?&V->spendlen:0,0,spendstr); + if ( V != 0 ) + { + if ( V->spendlen == 0 ) + { + V->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(V->spendscript,V->spendlen,spendstr); + } + if ( vin->spendscript == 0 ) + vin->spendscript = V->spendscript; + } + if ( vin->spendlen == 0 && vin->spendscript != 0 ) + { + vin->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(vin->spendscript,vin->spendlen,spendstr); + } + //printf("serialized.%p len.%d\n",serialized,len); + //n = iguana_parsehexstr(&vin->spendscript,&vin->spendlen,V!=0?V->spendscript:0,V!=0?&V->spendlen:0,&serialized[len],spendstr); + //len += n; } return(len); } @@ -345,8 +432,8 @@ int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t decode_hex(&serialized[len],n,hexstr); vout->pk_script = &serialized[len]; len += n; - } - } + } // else serialized[len++] = 0; + } //else serialized[len++] = 0; return(len); } @@ -403,18 +490,25 @@ bits256 bitcoin_sigtxid(struct iguana_info *coin,int32_t height,uint8_t *seriali { int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; dest = *msgtx; + dest.vins = calloc(dest.tx_in,sizeof(*dest.vins)); + dest.vouts = calloc(dest.tx_out,sizeof(*dest.vouts)); + memcpy(dest.vins,msgtx->vins,dest.tx_in * sizeof(*dest.vins)); + memcpy(dest.vouts,msgtx->vouts,dest.tx_out * sizeof(*dest.vouts)); memset(sigtxid.bytes,0,sizeof(sigtxid)); if ( hashtype != SIGHASH_ALL ) { printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); return(sigtxid); } - for (i=0; itx_in; i++) + for (i=0; i 0 ) + //for (i=0; i 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && { #ifdef BTC2_VERSION if ( height >= BTC2_HARDFORK_HEIGHT ) @@ -435,22 +534,69 @@ bits256 bitcoin_sigtxid(struct iguana_info *coin,int32_t height,uint8_t *seriali revsigtxid = bits256_doublesha256(0,serialized,len); for (i=0; i 0 ) + { + vin->p2shlen = (int32_t)strlen(redeemstr) >> 1; + vin->spendlen = vin->p2shlen; + vin->redeemscript = calloc(1,vin->p2shlen); + decode_hex(vin->redeemscript,vin->p2shlen,redeemstr); + hexstr = redeemstr; + //printf("VINOBJSET.(%s)\n",redeemstr); + } + else if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 && (vin->spendlen == 0 || vin->spendscript == 0) ) + { + vin->spendlen = (int32_t)strlen(hexstr) >> 1; + } + if ( hexstr != 0 && vin->spendlen != 0 ) + { + if ( vin->spendlen < maxsize ) + { + if ( vin->spendscript == 0 ) + vin->spendscript = spendscript; + decode_hex(vin->spendscript,vin->spendlen,hexstr); + } + } +} + +int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout) +{ + bits256 array_txid; cJSON *item; int32_t array_vout,i,n = cJSON_GetArraySize(vinarray); + for (i=0; iversion),&msg->version); if ( json != 0 ) { jaddnum(json,"version",msg->version); - array = cJSON_CreateArray(); + vinarray = cJSON_CreateArray(); + voutarray = cJSON_CreateArray(); if ( rwflag == 0 ) sigser = calloc(1,maxsize*2); - //printf("json.%p array.%p sigser.%p\n",json,array,sigser); + //printf("json.%p array.%p sigser.%p\n",json,vinarray,sigser); } //printf("version.%d\n",msg->version); if ( coin->chain->isPoS != 0 ) @@ -478,8 +624,13 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ for (i=0; itx_in; i++) { //printf("vin.%d starts offset.%d\n",i,len); + if ( vins != 0 && jitem(vins,i) != 0 ) + iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); if ( (n= iguana_vinparse(coin,rwflag,&serialized[len],&msg->vins[i])) < 0 ) return(-1); + //printf("serialized vin.[%02x %02x %02x]\n",serialized[len],serialized[len+1],serialized[len+2]); + if ( msg->vins[i].spendscript == spendscript ) + msg->vins[i].spendscript = 0; //printf("vin.%d n.%d len.%d\n",i,n,len); len += n; if ( len > maxsize ) @@ -487,25 +638,10 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ printf("invalid tx_in.%d len.%d vs maxsize.%d\n",msg->tx_in,len,maxsize); return(-1); } - if ( array != 0 ) - { - if ( sigser != 0 && vins != 0 ) - { - //set spendscript here - printf("vini.%d spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); - sigtxid = bitcoin_sigtxid(coin,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr,suppress_pubkeys); - } else memset(sigtxid.bytes,0,sizeof(sigtxid)); - jaddi(array,iguana_vinjson(coin,&msg->vins[i],sigtxid)); - } - } - if ( array != 0 ) - { - if ( sigser != 0 ) - free(sigser); - jadd(json,"vin",array); - jaddnum(json,"numvins",msg->tx_in); - array = cJSON_CreateArray(); } + //for (i=-3; i<7; i++) + // printf("%02x",serialized[len+i]); + //printf(" prev 3 bytes before tx_out rw.%d\n",rwflag); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); if ( rwflag == 0 ) { @@ -525,25 +661,20 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ } for (i=0; itx_out; i++) { - //printf("vout.%d starts %d\n",i,len); + //printf("rwflag.%d vout.%d starts %d\n",rwflag,i,len); if ( (n= iguana_voutparse(rwflag,&serialized[len],&msg->vouts[i])) < 0 ) return(-1); len += n; if ( len > maxsize ) { - printf("invalid tx_out.%d len.%d vs maxsize.%d n.%d\n",msg->tx_out,len,maxsize,n); + printf("invalidC tx_out.%d of %d len.%d vs maxsize.%d n.%d\n",i,msg->tx_out,len,maxsize,n); return(-1); } - if ( array != 0 ) - jaddi(array,iguana_voutjson(coin,&msg->vouts[i],i,*txidp)); - } - if ( array != 0 ) - { - jadd(json,"vout",array); - jaddnum(json,"numvouts",msg->tx_out); + if ( voutarray != 0 ) + jaddi(voutarray,iguana_voutjson(coin,&msg->vouts[i],i,*txidp)); } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); - //printf("lock_time.%08x\n",msg->lock_time); +//printf("lock_time.%08x len.%d\n",msg->lock_time,len); if ( strcmp(coin->symbol,"VPN") == 0 ) { uint16_t ddosflag = 0; @@ -564,6 +695,33 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ jaddstr(json,"vpnstr",vpnstr); } } + if ( sigser != 0 && vinarray != 0 ) + { + for (i=0; itx_in; i++) + { + memset(sigtxid.bytes,0,sizeof(sigtxid)); + if ( vins != 0 && jitem(vins,i) != 0 ) + { + iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); + sigtxid = bitcoin_sigtxid(coin,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr,suppress_pubkeys); + //printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); + if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) + jaddi(vinarray,iguana_vinjson(coin,&msg->vins[i],sigtxid)); + if ( msg->vins[i].spendscript == spendscript ) + msg->vins[i].spendscript = 0; + } else if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) + jaddi(vinarray,iguana_vinjson(coin,&msg->vins[i],sigtxid)); + } + free(sigser); + jadd(json,"vin",vinarray); + msg->tx_in = cJSON_GetArraySize(vinarray); + jaddnum(json,"numvins",msg->tx_in); + } + if ( voutarray != 0 ) + { + jadd(json,"vout",voutarray); + jaddnum(json,"numvouts",msg->tx_out); + } *txidp = bits256_doublesha256(txidstr,txstart,len); if ( json != 0 ) { @@ -578,7 +736,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V) { - int32_t i,numvins,numvouts,len = 0,rwflag=1; cJSON *array=0; bits256 txid; char vpnstr[64]; + int32_t i,n,numvins,numvouts,len = 0,rwflag=1; cJSON *array=0; bits256 txid; char vpnstr[64]; memset(&txid,0,sizeof(txid)); memset(msg,0,sizeof(*msg)); *txstartp = 0; @@ -602,12 +760,16 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin, return(txid); maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; + memset(msg->vins,0,sizeof(struct iguana_msgvin) * msg->tx_in); if ( msg->tx_in > 0 && msg->tx_in*sizeof(struct iguana_msgvin) < maxsize ) { for (i=0; itx_in; i++) { - //printf("vinobj.%d starts offset.%d\n",i,len); - len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msg->vins[i],jitem(array,i),V!=0?&V[i]:0); + n = iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msg->vins[i],jitem(array,i),V!=0?&V[i]:0); + //for (j=0; j<8; j++) + // printf("%02x",serialized[len+j]); + //char str[65]; printf(" <- vinobj.%d starts offset.%d %s\n",i,len,bits256_str(str,msg->vins[i].prev_hash)); + len += n; } } } @@ -619,11 +781,12 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin, return(txid); maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; + memset(msg->vouts,0,sizeof(struct iguana_msgvout) * msg->tx_out); if ( msg->tx_out > 0 && msg->tx_out*sizeof(struct iguana_msgvout) < maxsize ) { for (i=0; itx_out; i++) { - //printf("parsevout.%d starts %d\n",i,len); + //printf("parsetxobj parsevout.%d starts %d\n",i,len); len += iguana_parsevoutobj(coin,&serialized[len],maxsize,&msg->vouts[i],jitem(array,i)); } } @@ -634,17 +797,6 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin, *txstartp = 0; msg->allocsize = len; msg->txid = txid = bits256_doublesha256(0,serialized,len); - //for (i=0; isuppress_pubkeys:0)) != msg->allocsize ) - { - //memset(txid.bytes,0,sizeof(txid)); - printf("error parsing txobj: expected %d got %d\n",msg->allocsize,len); - //msg->allocsize = 0; - } - msg->txid = txid;*/ - //char str[65]; printf("json -> %s\n",bits256_str(str,txid)); return(txid); } @@ -701,6 +853,14 @@ cJSON *bitcoin_data2json(struct iguana_info *coin,int32_t height,bits256 *txidp, jaddstr(txobj,"error","couldnt decode transaction"); jaddstr(txobj,"coin",coin->symbol); } + //printf("msgtx.(%s)\n",jprint(txobj,0)); + if ( n != len ) + { + int32_t i; + for (i=0; i<=len; i++) + printf("%02x",serialized[i]); + printf(" data2json n.%d vs len.%d\n",n,len); + } return(txobj); } @@ -711,7 +871,7 @@ cJSON *bitcoin_hex2json(struct iguana_info *coin,int32_t height,bits256 *txidp,s return(0); len = (int32_t)strlen(txbytes) >> 1; if ( (serialized= origserialized) == 0 ) - serialized = calloc(1,len); + serialized = calloc(1,len+4096); decode_hex(serialized,len,txbytes); txobj = bitcoin_data2json(coin,height,txidp,msgtx,extraspace,extralen,serialized,len,vins,suppress_pubkeys); if ( serialized != origserialized ) @@ -721,7 +881,7 @@ cJSON *bitcoin_hex2json(struct iguana_info *coin,int32_t height,bits256 *txidp,s int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,struct vin_info *V) { - int32_t vini,j,scriptlen,p2shlen,userdatalen,need_op0=0,siglen,plen,len = 0; uint8_t *script,*redeemscript=0,*userdata=0; struct vin_info *vp; + int32_t vini,j,scriptlen,p2shlen,userdatalen,siglen,plen,need_op0=0,len = 0; uint8_t *script,*redeemscript=0,*userdata=0; struct vin_info *vp; for (vini=0; vinitx_in; vini++) { vp = &V[vini]; @@ -748,7 +908,7 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m if ( redeemscript != 0 && p2shlen > 33 && redeemscript[p2shlen - 1] == SCRIPT_OP_CHECKMULTISIG ) { need_op0 = 1; - printf("found multisig redeemscript\n"); + //printf("found multisig redeemscript\n"); } msgtx->vins[vini].vinscript = script = &serialized[len]; msgtx->vins[vini].vinscript[0] = 0; @@ -783,7 +943,7 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m msgtx->vins[vini].userdatalen = userdatalen; scriptlen += userdatalen; } - printf("USERDATALEN.%d scriptlen.%d redeemlen.%d\n",userdatalen,scriptlen,p2shlen); + //printf("USERDATALEN.%d scriptlen.%d redeemlen.%d\n",userdatalen,scriptlen,p2shlen); if ( p2shlen != 0 ) { if ( p2shlen < 76 ) @@ -805,7 +965,7 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m } len += scriptlen; } - if ( 0 ) + if ( (0) ) { int32_t i; for (i=0; itx_out; vpnstr[0] = 0; *signedtx = 0; memset(signedtxidp,0,sizeof(*signedtxidp)); for (vini=0; vinitx_in; vini++) { - sigtxid = bitcoin_sigtxid(coin,height,serialized,maxlen,msgtx,vini,msgtx->vins[vini].spendscript,msgtx->vins[vini].spendlen,sighash,vpnstr,suppress_pubkeys); + if ( V->p2shscript[0] != 0 && V->p2shlen != 0 ) + { + script = V->p2shscript; + scriptlen = V->p2shlen; + //printf("V->p2shlen.%d\n",V->p2shlen); + } + else + { + script = msgtx->vins[vini].spendscript; + scriptlen = msgtx->vins[vini].spendlen; + } + sigtxid = bitcoin_sigtxid(coin,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys); if ( bits256_nonz(sigtxid) != 0 ) { vp = &V[vini]; @@ -835,17 +1006,18 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *sign if ( signtx != 0 && bits256_nonz(vp->signers[j].privkey) != 0 ) { siglen = bitcoin_sign(coin->ctx,coin->symbol,sig,sigtxid,vp->signers[j].privkey,0); - if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) + //if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) bitcoin_pubkey33(coin->ctx,vp->signers[j].pubkey,vp->signers[j].privkey); sig[siglen++] = sighash; vp->signers[j].siglen = siglen; - /*for (i=0; isigners[j].pubkey[i]);*/ + /*char str[65]; printf("SIGTXID.(%s) ",bits256_str(str,sigtxid)); + int32_t i; for (i=0; isigners[j].pubkey[i]); // s2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1; - //char str[65]; printf(" SIGNEDTX.[%02x] siglen.%d sigtxid.%s\n",sig[siglen-1],siglen,bits256_str(str,sigtxid)); + printf(" SIGNEDTX.[%02x] siglen.%d priv.%s\n",sig[siglen-1],siglen,bits256_str(str,vp->signers[j].privkey));*/ } if ( sig == 0 || siglen == 0 ) { @@ -854,8 +1026,9 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *sign } if ( bitcoin_verify(coin->ctx,sig,siglen-1,sigtxid,vp->signers[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 ) { - - printf("SIG.%d.%d ERROR\n",vini,j); + int32_t k; for (k=0; ksigners[j].pubkey); k++) + printf("%02x",vp->signers[j].pubkey[k]); + printf(" SIG.%d.%d ERROR siglen.%d\n",vini,j,siglen); } else { @@ -864,7 +1037,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *sign /*int32_t z; for (z=0; zsigners[j].pubkey[z]); printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d\n",vini,j,numsigs,vp->M);*/ @@ -873,18 +1046,18 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *sign if ( numsigs >= vp->M ) complete = 1; } - } //0398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcb + } iguana_msgtx_Vset(coin,serialized,maxlen,msgtx,V); cJSON *txobj = cJSON_CreateObject(); *signedtx = iguana_rawtxbytes(coin,height,txobj,msgtx,suppress_pubkeys); - printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); + //printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); *signedtxidp = msgtx->txid; return(complete); } int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msgtx,cJSON *vins,int32_t numinputs,struct vin_info *V) { - int32_t i,plen,finalized = 1,len = 0; struct vin_info *vp; struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,userdatalen; + struct iguana_outpoint outpt; int32_t i,plen,finalized = 1,len = 0; struct vin_info *vp; struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,userdatalen; msgtx->tx_in = numinputs; maxsize -= (sizeof(struct iguana_msgvin) * msgtx->tx_in); msgtx->vins = (struct iguana_msgvin *)&serialized[maxsize]; @@ -894,13 +1067,15 @@ int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *c for (i=0; itx_in; i++) { vp = &V[i]; + //printf("VINS.(%s)\n",jprint(jitem(vins,i),0)); len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msgtx->vins[i],jitem(vins,i),vp); if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) finalized = 0; if ( msgtx->vins[i].spendscript == 0 ) { - if ( (vp->unspentind= iguana_RTunspentindfind(myinfo,coin,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,0)) > 0 ) + if ( iguana_RTunspentindfind(myinfo,coin,&outpt,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,0) == 0 ) { + vp->unspentind = outpt.unspentind; msgtx->vins[i].spendscript = vp->spendscript; msgtx->vins[i].spendlen = vp->spendlen; vp->hashtype = iguana_vinscriptparse(coin,vp,&sigsize,&pubkeysize,&p2shsize,&userdatalen,vp->spendscript,vp->spendlen); @@ -961,9 +1136,9 @@ void iguana_ensure_privkey(struct supernet_info *myinfo,struct iguana_info *coin waddr->privkey = privkey; if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) { - if ( 0 && waddr->wiftype != coin->chain->wiftype ) + if ( (0) && waddr->wiftype != coin->chain->wiftype ) printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->chain->wiftype); - if ( 0 && waddr->addrtype != coin->chain->pubtype ) + if ( (0) && waddr->addrtype != coin->chain->pubtype ) printf("ensurepriv warning: mismatched addrtype %02x != %02x\n",waddr->addrtype,coin->chain->pubtype); } } @@ -1034,8 +1209,8 @@ void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32 return; scriptstr = scriptbuf, maxlen = sizeof(scriptbuf); init_hexbytes_noT(scriptstr,script,scriptlen); - if ( strcmp(fieldname,"userdata") == 0 ) - printf("SCRIPT_USERDATA.(%s)\n",scriptstr); + //if ( strcmp(fieldname,"userdata") == 0 ) + // printf("SCRIPT_USERDATA.(%s)\n",scriptstr); if ( strcmp(fieldname,"coinbase") == 0 ) jaddstr(dest,"coinbase",scriptstr); else @@ -1064,12 +1239,14 @@ cJSON *iguana_pubkeysjson(uint8_t *pubkeyptrs[],int32_t numpubkeys) return(pubkeysjson); } -cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys) +cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys,uint8_t *sig,int32_t siglen) { - cJSON *item,*vins; char p2shscriptstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t *script,len; + cJSON *item,*vins; char p2shscriptstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t *script,len=0; vins = jduplicate(jobj(txobj,"vin")); jdelete(txobj,"vin"); item = cJSON_CreateObject(); + if ( sig != 0 && siglen > 0 ) + iguana_addscript(coin,item,sig,siglen,"scriptSig"); if ( spendscript != 0 && spendscript > 0 ) { iguana_addscript(coin,item,spendscript,spendlen,"scriptPubKey"); @@ -1094,13 +1271,15 @@ cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_ return(txobj); } -cJSON *bitcoin_txcreate(int32_t isPoS,int64_t locktime,uint32_t txversion) +cJSON *bitcoin_txcreate(char *symbol,int32_t isPoS,int64_t locktime,uint32_t txversion,uint32_t timestamp) { cJSON *json = cJSON_CreateObject(); jaddnum(json,"version",txversion); + if ( locktime == 0 && strcmp(symbol,"KMD") == 0 ) + locktime = (uint32_t)time(NULL) - 55; jaddnum(json,"locktime",locktime); if ( isPoS != 0 ) - jaddnum(json,"timestamp",time(NULL)); + jaddnum(json,"timestamp",timestamp == 0 ? time(NULL) : timestamp); jadd(json,"vin",cJSON_CreateArray()); jadd(json,"vout",cJSON_CreateArray()); return(json); @@ -1126,9 +1305,11 @@ cJSON *bitcoin_txoutput(cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLockTime,struct vin_info *V,int32_t numvins) { - uint8_t script[IGUANA_MAXSCRIPTSIZE],*activescript; char str[IGUANA_MAXSCRIPTSIZE*2+1]; int32_t vini,scriptlen,activescriptlen,errs = 0; cJSON *spendscript,*item; + uint8_t script[IGUANA_MAXSCRIPTSIZE],*activescript,savescript[IGUANA_MAXSCRIPTSIZE]; char str[IGUANA_MAXSCRIPTSIZE*2+1]; int32_t vini,scriptlen,activescriptlen,savelen,errs = 0; cJSON *spendscript,*item=0; for (vini=0; vini 0 ) { activescript = V[vini].p2shscript; @@ -1139,10 +1320,15 @@ int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLoc activescript = V[vini].spendscript; activescriptlen = V[vini].spendlen; } + memcpy(V[vini].spendscript,activescript,activescriptlen); + V[vini].spendlen = activescriptlen; spendscript = iguana_spendasm(coin,activescript,activescriptlen); + if ( activescriptlen < 16 ) + continue; //printf("interpreter.(%s)\n",jprint(spendscript,0)); if ( (scriptlen= bitcoin_assembler(coin,logarray,script,spendscript,1,nLockTime,&V[vini])) < 0 ) { + //printf("bitcoin_assembler error scriptlen.%d\n",scriptlen); errs++; } else if ( scriptlen != activescriptlen || memcmp(script,activescript,scriptlen) != 0 ) @@ -1151,14 +1337,22 @@ int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLoc { item = cJSON_CreateObject(); jaddstr(item,"error","script reconstruction failed"); - init_hexbytes_noT(str,activescript,activescriptlen); + } + init_hexbytes_noT(str,activescript,activescriptlen); + //printf("activescript.(%s)\n",str); + if ( logarray != 0 && item != 0 ) jaddstr(item,"original",str); - init_hexbytes_noT(str,script,scriptlen); + init_hexbytes_noT(str,script,scriptlen); + //printf("reconstructed.(%s)\n",str); + if ( logarray != 0 ) + { jaddstr(item,"reconstructed",str); jaddi(logarray,item); - } else printf("scriptlen mismatch.%d vs %d or miscompare\n",scriptlen,V[vini].spendlen); + } else printf(" scriptlen mismatch.%d vs %d or miscompare\n",scriptlen,activescriptlen); errs++; } + memcpy(V[vini].spendscript,savescript,savelen); + V[vini].spendlen = savelen; } if ( errs != 0 ) return(-errs); @@ -1171,72 +1365,11 @@ int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLoc return(0); } -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - - -P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount,destaddress2,destamount2,M,N,pubA,wifA,pubB,wifB,pubC,wifC) +int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeysjson) { - struct vin_info V; uint8_t p2sh_rmd160[20],serialized[2096],spendscript[32],pubkeys[3][65],*pubkeyptrs[3]; int32_t spendlen,height = 0; - char msigaddr[64],*retstr; cJSON *retjson,*txobj; struct iguana_info *active; - bits256 signedtxid; char *signedtx; - struct iguana_msgtx msgtx; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - if ( (active= iguana_coinfind(activecoin)) == 0 ) - return(clonestr("{\"error\":\"activecoin isnt active\"}")); - if ( M > N || N > 3 ) - return(clonestr("{\"error\":\"illegal M or N\"}")); - memset(&V,0,sizeof(V)); - txobj = bitcoin_txcreate(active->chain->isPoS,0,coin->chain->normal_txversion); - if ( destaddress[0] != 0 && destamount > 0. ) - bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); - if ( destaddress2[0] != 0 && destamount2 > 0. ) - bitcoin_txaddspend(active,txobj,destaddress2,destamount2 * SATOSHIDEN); - if ( pubA[0] != 0 && (retstr= _setVsigner(active,&V,0,pubA,wifA)) != 0 ) - return(retstr); - if ( N >= 2 && pubB[0] != 0 && (retstr= _setVsigner(active,&V,1,pubB,wifB)) != 0 ) - return(retstr); - if ( N == 3 && pubC[0] != 0 && (retstr= _setVsigner(active,&V,2,pubC,wifC)) != 0 ) - return(retstr); - V.M = M, V.N = N, V.type = IGUANA_SCRIPT_P2SH; - V.p2shlen = bitcoin_MofNspendscript(p2sh_rmd160,V.p2shscript,0,&V); - spendlen = bitcoin_p2shspend(spendscript,0,p2sh_rmd160); - if ( pubA[0] != 0 ) - { - decode_hex(pubkeys[0],(int32_t)strlen(pubA)>>1,pubA); - pubkeyptrs[0] = pubkeys[0]; - } - if ( pubB[0] != 0 ) - { - decode_hex(pubkeys[1],(int32_t)strlen(pubB)>>1,pubB); - pubkeyptrs[1] = pubkeys[1]; - } - if ( pubC[0] != 0 ) - { - decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC); - pubkeyptrs[2] = pubkeys[2]; - } - bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N); - bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); - retjson = cJSON_CreateObject(); - if ( bitcoin_verifyvins(active,height,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL,1,V.suppress_pubkeys) == 0 ) - { - jaddstr(retjson,"result","msigtx"); - if ( signedtx != 0 ) - jaddstr(retjson,"signedtx",signedtx), free(signedtx); - jaddbits256(retjson,"txid",signedtxid); - } else jaddstr(retjson,"error","couldnt sign tx"); - jaddstr(retjson,"msigaddr",msigaddr); - return(jprint(retjson,1)); -} - -int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeys) -{ - uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace; int32_t finalized,i,len,n,maxsize,complete = 0,extralen = 65536; char *checkstr,*privkeystr,*signedtx = 0; bits256 privkey,txid; cJSON *item; cJSON *txobj = 0; + uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace,pubkeys[64][33]; int32_t finalized,i,len,n,z,plen,maxsize,complete = 0,extralen = 65536; char *privkeystr,*signedtx = 0; bits256 privkeys[64],privkey,txid; cJSON *item; cJSON *txobj = 0; maxsize = 1000000; + memset(privkey.bytes,0,sizeof(privkey)); if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) { serialized = malloc(maxsize); @@ -1246,57 +1379,113 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf extraspace = malloc(extralen); memset(msgtx,0,sizeof(*msgtx)); decode_hex(serialized,len,rawtx); + // printf("call hex2json.(%s) vins.(%s)\n",rawtx,jprint(vins,0)); if ( (txobj= bitcoin_hex2json(coin,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys)) != 0 ) { - //if ( vins != 0 ) - // printf("vins.(%s)\n",jprint(vins,0)); - if ( jobj(txobj,"error") != 0 ) - { - printf("txobj.(%s)\n",jprint(txobj,0)); - } - if ( 0 && (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,V)) != 0 ) - { - if ( strcmp(rawtx,checkstr) != 0 ) - { - printf("RAW.(%s) ->\nNEW.(%s)\n",rawtx,checkstr); - //free_json(txobj); - //free(checkstr); - //free(serialized), free(serialized2), free(serialized3), free(serialized4); - //free(extraspace); - //return(-2); - } - free(checkstr); - } - } + //printf("back from bitcoin_hex2json (%s)\n",jprint(vins,0)); + } else fprintf(stderr,"no txobj from bitcoin_hex2json\n"); if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) { + //printf("numinputs.%d msgtx.%d\n",numinputs,msgtx->tx_in); memset(msgtx,0,sizeof(*msgtx)); if ( iguana_rwmsgtx(coin,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,65536,vins,V->suppress_pubkeys) > 0 && numinputs == msgtx->tx_in ) { - if ( (n= cJSON_GetArraySize(privkeys)) > 0 ) + memset(pubkeys,0,sizeof(pubkeys)); + memset(privkeys,0,sizeof(privkeys)); + if ( (n= cJSON_GetArraySize(privkeysjson)) > 0 ) { for (i=0; isigners[i].privkey = privkey; + if ( privkeystr == 0 || privkeystr[0] == 0 ) + continue; + privkeys[i] = privkey = iguana_str2priv(myinfo,coin,privkeystr); + bitcoin_pubkey33(myinfo->ctx,pubkeys[i],privkey); if ( bits256_nonz(privkey) != 0 ) iguana_ensure_privkey(myinfo,coin,privkey); } } + //printf("after privkeys tx_in.%d\n",msgtx->tx_in); + for (i=0; itx_in; i++) + { + if ( msgtx->vins[i].p2shlen != 0 ) + { + char coinaddr[64]; uint32_t userdatalen,sigsize,pubkeysize; uint8_t *userdata; int32_t j,k,hashtype,type,flag; struct vin_info mvin,mainvin; bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + coinaddr[0] = 0; + sigsize = 0; + flag = (msgtx->vins[i].vinscript[0] == 0); + type = bitcoin_scriptget(coin,&hashtype,&sigsize,&pubkeysize,&userdata,&userdatalen,&mainvin,msgtx->vins[i].vinscript+flag,msgtx->vins[i].scriptlen-flag,0); + //printf("i.%d flag.%d type.%d scriptlen.%d\n",i,flag,type,msgtx->vins[i].scriptlen); + if ( msgtx->vins[i].redeemscript != 0 ) + { + //for (j=0; jvins[i].p2shlen; j++) + // printf("%02x",msgtx->vins[i].redeemscript[j]); + bitcoin_address(coinaddr,coin->chain->p2shtype,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen); + type = iguana_calcrmd160(coin,0,&mvin,msgtx->vins[i].redeemscript,msgtx->vins[i].p2shlen,zero,0,0); + for (j=0; jsuppress_pubkeys == 0 ) + { + for (z=0; z<33; z++) + V[i].signers[j].pubkey[z] = mvin.signers[j].pubkey[z]; + } + if ( flag != 0 && pubkeysize == 33 && mainvin.signers[0].siglen != 0 ) // jl777: need to generalize + { + if ( memcmp(mvin.signers[j].pubkey,mainvin.signers[0].pubkey,33) == 0 ) + { + for (z=0; zsuppress_pubkeys == 0 ) + { + for (z=0; z<33; z++) + V[i].signers[j].pubkey[z] = pubkeys[k][z]; + } + //printf("%s -> V[%d].signer.[%d] <- privkey.%d\n",mvin.signers[j].coinaddr,i,j,k); + break; + } + } + } + //printf("type.%d p2sh.[%d] -> %s M.%d N.%d\n",type,i,mvin.coinaddr,mvin.M,mvin.N); + } + } + if ( i < V->N ) + V->signers[i].privkey = privkey; + if ( i < numinputs ) + V[i].signers[0].privkey = privkey; + plen = bitcoin_pubkeylen(V->signers[i].pubkey); + if ( V->suppress_pubkeys == 0 && plen <= 0 ) + { + if ( i < numinputs ) + { + for (z=0; zsigners[i].pubkey[z]; + } + } + } finalized = iguana_vininfo_create(myinfo,coin,serialized2,maxsize,msgtx,vins,numinputs,V); + //printf("finalized.%d\n",finalized); if ( (complete= bitcoin_verifyvins(coin,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys)) > 0 && signedtx != 0 ) { - int32_t tmp; + int32_t tmp; //char str[65]; if ( (tmp= iguana_interpreter(coin,0,iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 ) { printf("iguana_interpreter %d error.(%s)\n",tmp,signedtx); complete = 0; - } - } - } - } + } //else printf("%s signed\n",bits256_str(str,*signedtxidp)); + } else printf("complete.%d\n",complete); + } else printf("rwmsgtx error\n"); + } else fprintf(stderr,"no inputs in vins.(%s)\n",vins!=0?jprint(vins,0):"null"); free(extraspace); free(serialized), free(serialized2), free(serialized3), free(serialized4); } else return(-1); @@ -1306,40 +1495,4 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf return(complete); } -STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) -{ - char *signedtx = 0; struct vin_info *V; bits256 signedtxid; int32_t complete,numinputs = 1; struct iguana_msgtx msgtx; cJSON *retjson; int uselessbitcoin_error = 0; - retjson = cJSON_CreateObject(); - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); - //printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash); - if ( sighash == 0 || sighash[0] == 0 ) - sighash = "ALL"; - if ( strcmp(sighash,"ALL") != 0 ) - jaddstr(retjson,"error","only sighash all (ALL) supported for now"); - if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) - { - V = calloc(numinputs,sizeof(*V)); - memset(&msgtx,0,sizeof(msgtx)); - if ( (complete= iguana_signrawtransaction(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) - { - if ( signedtx != 0 ) - { - jaddstr(retjson,"result",signedtx); - jadd(retjson,"complete",complete!=0?jtrue():jfalse()); - free(signedtx); - } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins"); - } - else if ( complete == -2 ) - jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error"); - else if ( complete == -1 ) - jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs"); - free(V); - } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no rawtx or rawtx too big"); - return(jprint(retjson,1)); -} - -#include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_spendvectors.c b/iguana/iguana_spendvectors.c index 3c11f0d8f..7a0cc5a27 100755 --- a/iguana/iguana_spendvectors.c +++ b/iguana/iguana_spendvectors.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -56,7 +56,7 @@ int32_t iguana_spendvectorsave(struct iguana_info *coin,struct iguana_bundle *bp int32_t i,retval = -1; FILE *fp; char fname[1024],str[65]; long fsize; bits256 zero,sha256; if ( ptr == 0 || (bp->hdrsi != 0 && ptr == bp->ramchain.Xspendinds) ) { - printf("iguana_spendvectorsave.[%d] ptr.%p Xspendinds\n",bp->hdrsi,ptr); + //printf("iguana_spendvectorsave.[%d] ptr.%p Xspendinds\n",bp->hdrsi,ptr); return(0); } memset(zero.bytes,0,sizeof(zero)); @@ -84,7 +84,7 @@ int32_t iguana_spendvectorsave(struct iguana_info *coin,struct iguana_bundle *bp printf("error mapping Xspendmap.(%s)\n",fname); else { - printf("created.(%s) %p[%d]\n",fname,bp->ramchain.Xspendinds,bp->ramchain.numXspends); + //printf("created.(%s) %p[%d]\n",fname,bp->ramchain.Xspendinds,bp->ramchain.numXspends); retval = 0; } } @@ -97,7 +97,7 @@ int32_t iguana_spendvectorsave(struct iguana_info *coin,struct iguana_bundle *bp return(retval); } -struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spent_hdrsi,struct iguana_spend *s,int32_t prefetchflag) +struct iguana_bundle *iguana_externalspent(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spent_hdrsi,struct iguana_spend *s,int32_t prefetchflag) { int32_t prev_vout,height,hdrsi; uint32_t sequenceid,unspentind; char str[65]; struct iguana_bundle *spentbp=0; struct iguana_txid *T,TX,*tp; bits256 *X; bits256 prev_hash; struct iguana_ramchaindata *rdata; if ( (rdata= ramchain->H.data) != 0 ) @@ -155,7 +155,8 @@ struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *pre else { printf("illegal hdrsi.%d prev_hash.(%s) for bp.[%d]\n",hdrsi,bits256_str(str,prev_hash),spent_hdrsi); - exit(-1); + iguana_exit(myinfo,0); + return(0); } } else @@ -163,8 +164,8 @@ struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *pre printf("cant find prev_hash.(%s) for bp.[%d]\n",bits256_str(str,prev_hash),spent_hdrsi); if ( spent_hdrsi < coin->current->hdrsi ) { - iguana_bundleremove(coin,spent_hdrsi,1); - exit(-1); + //iguana_bundleremove(coin,spent_hdrsi,1); + iguana_exit(myinfo,coin->bundles[spent_hdrsi]); } coin->RTdatabad = 1; return(0); @@ -176,7 +177,8 @@ struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *pre else if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) printf("%s illegal unspentind.%d vs max.%d spentbp.%p[%d]\n",coin->symbol,unspentind,spentbp->ramchain.H.data->numunspents,spentbp,hdrsi); else return(spentbp); - iguana_bundleremove(coin,spent_hdrsi,1); + //iguana_bundleremove(coin,spent_hdrsi,1); + iguana_exit(myinfo,coin->bundles[spent_hdrsi]); } //exit(-1); return(0); @@ -184,7 +186,7 @@ struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *pre struct iguana_bundle *iguana_fastexternalspent(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spent_hdrsi,struct iguana_spend *s) { - int32_t prev_vout,height,hdrsi,unspentind; uint32_t ind; + int32_t prev_vout,height,hdrsi,unspentind; uint32_t ind; uint64_t RTspent; struct iguana_txid *T; bits256 *X; bits256 prev_hash; struct iguana_ramchaindata *rdata; if ( (rdata= ramchain->H.data) == 0 ) return(0); @@ -202,8 +204,8 @@ struct iguana_bundle *iguana_fastexternalspent(struct supernet_info *myinfo,stru X = RAMCHAIN_PTR(rdata,Xoffset); //X = (void *)(long)((long)rdata + rdata->Xoffset); *prevhashp = prev_hash = X[ind]; - if ( (unspentind= iguana_unspentindfind(myinfo,coin,0,0,0,0,&height,prev_hash,prev_vout,spent_hdrsi-1,0)) != 0 ) - //if ( (firstvout= iguana_txidfastfind(coin,&height,prev_hash,spent_hdrsi-1)) >= 0 ) + if ( (unspentind= iguana_unspentindfind(myinfo,coin,&RTspent,0,0,0,0,&height,prev_hash,prev_vout,spent_hdrsi-1,0)) > 0 ) + //if ( (firstvout= iguana_txidfastfind(coin,&height,prev_hash,spent_hdrsi-1)) > 0 ) { /*duration = (OS_milliseconds() - startmillis); if ( ((uint64_t)coin->txidfind_num % 100) == 1 ) @@ -236,8 +238,8 @@ struct iguana_bundle *iguana_fastexternalspent(struct supernet_info *myinfo,stru int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,int32_t starti,int32_t numblocks,int32_t convertflag,int32_t iterate) { static uint64_t total,emitted; - int32_t iter,spendind,n=0,txidind,errs=0,emit=0,i,j,k; double startmillis; bits256 prevhash; - uint32_t spent_unspentind,spent_pkind,now,starttime; struct iguana_ramchaindata *rdata; + int32_t iter,spendind=0,n=0,txidind,errs=0,emit=0,i,j,k; double startmillis; bits256 prevhash; + uint32_t spent_unspentind=0,spent_pkind,now,starttime; struct iguana_ramchaindata *rdata; struct iguana_bundle *spentbp; struct iguana_blockRO *B; struct iguana_spendvector *ptr; struct iguana_unspent *u,*spentU; struct iguana_txid *T; char str[65]; struct iguana_spend *S,*s; //void *fastfind = 0; @@ -264,10 +266,11 @@ int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coi //printf("iguana_spendvectors.[%d]: already have Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); return(0); } + bp->startutxo = (uint32_t)time(NULL); ptr = mycalloc('x',sizeof(*ptr),n); total += n; startmillis = OS_milliseconds(); - if ( 0 && strcmp(coin->symbol,"BTC") == 0 ) + if ( (0) && strcmp(coin->symbol,"BTC") == 0 ) printf("start UTXOGEN.%d max.%d ptr.%p millis.%.3f\n",bp->bundleheight,n,ptr,startmillis); starttime = (uint32_t)time(NULL); iguana_ramchain_prefetch(coin,&bp->ramchain,3); @@ -279,6 +282,7 @@ int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coi //coin->fast[iter] = calloc(1,coin->fastsizes[iter]); //memcpy(coin->fast[iter],fastfind,coin->fastsizes[iter]); } + //need zB[]? txidind = B[starti].firsttxidind; spendind = B[starti].firstvin; for (i=starti; ihdrsi,s,2)) != 0 ) + if ( (spentbp= iguana_externalspent(myinfo,coin,&prevhash,&spent_unspentind,ramchain,bp->hdrsi,s,2)) != 0 ) { if ( coin->fastfind != 0 ) printf("found prevhash using slow, not fast\n"); @@ -338,7 +342,7 @@ int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coi { if ( coin->PREFETCHLAG > 0 && now >= spentbp->lastprefetch+coin->PREFETCHLAG ) { - printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); + //printf("prefetch[%d] from.[%d] lag.%d\n",spentbp->hdrsi,bp->hdrsi,now - spentbp->lastprefetch); iguana_ramchain_prefetch(coin,&spentbp->ramchain,2); spentbp->lastprefetch = now; } @@ -379,7 +383,7 @@ int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coi ptr[emit].unspentind = spent_unspentind; ptr[emit].fromheight = bp->bundleheight + i; ptr[emit].tmpflag = 1; - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("fromht.%d spends [%d] TMPVECTOR u%d s%u\n",ptr[emit].fromheight,ptr[emit].hdrsi,ptr[emit].unspentind,spendind); emit++; } @@ -432,14 +436,14 @@ int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coi //printf("ALLOC tmpspends.[%d]\n",bp->hdrsi); ptr = 0; } - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("spendvectors.[%d]: tmpspends.%p[%d] after += emit.%d X.%p\n",bp->hdrsi,bp->tmpspends,bp->numtmpspends,emit,bp->ramchain.Xspendinds); } else errs = -iguana_spendvectorsave(coin,bp,ramchain,ptr!=0?ptr:bp->tmpspends,emit,n); } if ( ptr != 0 ) myfree(ptr,sizeof(*ptr) * n); //if ( bp != coin->current ) - printf("UTXO [%4d].%-6d dur.%-2d [milli %8.3f] vectors %-6d err.%d [%5.2f%%] %7d %9s of %d\n",bp->hdrsi,bp->numtmpspends,(uint32_t)time(NULL)-starttime,OS_milliseconds()-startmillis,spendind,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); + printf("%s UTXO [%4d].%-6d dur.%-2d [%8.3f] vec %-6d err.%d [%5.2f%%] %7d %9s of %d\n",coin->symbol,bp->hdrsi,bp->numtmpspends,(uint32_t)time(NULL)-starttime,OS_milliseconds()-startmillis,spendind,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); return(-errs); } @@ -471,6 +475,9 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig if ( (Xspendinds= bp->tmpspends) == 0 ) { //printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,numXspends); + numXspends = iguana_Xspendmap(coin,ramchain,bp); + numXspends = ramchain->numXspends; + //printf("Xspendinds.%p[%d]\n",Xspendinds,numXspends); //return(-1); } } @@ -479,12 +486,12 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig spendind = B[starti].firstvin; unspentind = B[starti].firstvout; emit = startemit; - if ( 0 && (coin->RTheight == 0 || bp->bundleheight+bp->n < coin->RTheight) ) + if ( (0) && (coin->RTheight == 0 || bp->bundleheight+bp->n < coin->RTheight) ) fprintf(stderr,"BALANCEGEN.[%d] %p[%d] starti.%d s%d <-> endi.%d s%d startemit.%d\n",bp->hdrsi,Xspendinds,numXspends,starti,spendind,endi,B[endi].firstvin+B[endi].numvins,startemit); for (i=starti; i<=endi; i++) { now = (uint32_t)time(NULL); - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin || unspentind != B[i].firstvout ) { @@ -496,10 +503,10 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig now = (uint32_t)time(NULL); if ( txidind != T[txidind].txidind || spendind != T[txidind].firstvin || unspentind != T[txidind].firstvout ) { - printf("balancegen: txidind %u != %u T[txidind].firsttxidind || spendind %u != %u T[txidind].firstvin errs.%d (%d %d)\n",txidind,T[txidind].txidind,spendind,T[txidind].firstvin,errs,unspentind,B[i].firstvout); + printf("balancegen: txidind %u != %u T[txidind].firsttxidind || spendind %u != %u T[txidind].firstvin errs.%d (%d %d)\n",txidind,(uint32_t)T[txidind].txidind,spendind,(uint32_t)T[txidind].firstvin,errs,unspentind,B[i].firstvout); return(-1); } - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("starti.%d txidind.%d txi.%d numvins.%d spendind.%d\n",i,txidind,j,T[txidind].numvins,spendind); /*if ( bp == coin->current )//ramchain == &coin->RTramchain ) { @@ -534,7 +541,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig spent_hdrsi = spend->hdrsi; h = spend->fromheight; } - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("external prevout.%d (emit.%d numX.%d) %p u%d p%d errs.%d spent_hdrsi.%d s%u\n",s->prevout,emit,numXspends,Xspendinds,spent_unspentind,spent_pkind,errs,spent_hdrsi,spendind); } else if ( s->prevout >= 0 ) @@ -560,7 +567,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig spentbp = 0; if ( (spentbp= coin->bundles[spent_hdrsi]) != 0 && spent_unspentind > 0 && spent_pkind > 0 ) { - if ( 0 && bp == coin->current ) + if ( (0) && bp == coin->current ) printf("[%d] spendind.%u -> [%d] u%d\n",bp->hdrsi,spendind,spent_hdrsi,spent_unspentind); if ( iguana_volatileupdate(coin,incremental,&spentbp->ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) //(spentbp == coin->current) ? &coin->RTramchain : errs++; @@ -568,7 +575,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig else //if ( Xspendinds != 0 ) { errs++; - printf("iguana_balancegen: spendind.%u external.%d error spentbp.%p with unspentind.%d pkind.%u [%d] (%d %d %d)\n",spendind,s->external,spentbp,spent_unspentind,spent_pkind,spent_hdrsi,i,j,k); + printf("iguana_balancegen: X%p[%d] spendind.%u external.%d error spentbp.%p with unspentind.%d pkind.%u [%d] (%d %d %d)\n",Xspendinds,numXspends,spendind,s->external,spentbp,spent_unspentind,spent_pkind,spent_hdrsi,i,j,k); } } } @@ -612,25 +619,40 @@ void iguana_truncatebalances(struct iguana_info *coin) int32_t iguana_volatilesinit(struct supernet_info *myinfo,struct iguana_info *coin) { bits256 balancehash,allbundles; struct iguana_utxo *Uptr; struct iguana_account *Aptr; - struct sha256_vstate vstate,bstate; int32_t i,from_ro,numpkinds,numunspents; struct iguana_bundle *bp; struct iguana_block *block; + struct sha256_vstate vstate,bstate; int32_t i,n,from_ro,numpkinds,numunspents; struct iguana_bundle *bp; struct iguana_block *block; uint32_t crc,filecrc; FILE *fp; char crcfname[512],str[65],str2[65],buf[2048]; from_ro = 1; - for (i=0; ibundlescount; i++)//balanceswritten; i++) + for (i=n=0; ibundlescount; i++) { if ( (bp= coin->bundles[i]) == 0 ) continue; - if ( bp->emitfinish <= 1 || (i > 0 && bp->utxofinish <= 1) ) + iguana_volatilesmap(myinfo,coin,&bp->ramchain); + if ( bp->ramchain.H.data != 0 ) + { + if ( bp->startutxo == 0 ) + bp->startutxo = (uint32_t)time(NULL) - 60; + //if ( bp->utxofinish == 0 ) + // bp->utxofinish = (uint32_t)time(NULL); + n++; + } + if ( bp->utxofinish <= 1 || (i > 0 && bp->utxofinish <= 1) ) { //printf("hdrsi.[%d] emitfinish.%u utxofinish.%u\n",i,bp->emitfinish,bp->utxofinish); continue; } - iguana_volatilesmap(coin,&bp->ramchain); if ( from_ro != 0 && (bp->ramchain.from_ro == 0 || (bp->hdrsi > 0 && bp->ramchain.from_roX == 0) || bp->ramchain.from_roA == 0 || bp->ramchain.from_roU == 0) ) { printf("from_ro.[%d] %d %d %d %d\n",bp->hdrsi,bp->ramchain.from_ro,bp->ramchain.from_roX,bp->ramchain.from_roA,bp->ramchain.from_roU); from_ro = 0; } } + printf("n.%d bundlescount.%d volatilesinit %d vs %d\n",n,i,(coin->longestchain-coin->chain->minconfirms)/coin->chain->bundlesize,n); + if ( (coin->longestchain-coin->chain->minconfirms)/coin->chain->bundlesize > n ) + { + printf("SKIP checking volatile files %d >= %d\n",(coin->longestchain-coin->chain->minconfirms)/coin->chain->bundlesize,n); + iguana_bundlestats(myinfo,coin,buf,IGUANA_DEFAULTLAG); + return(coin->bundlescount); + } /*if ( i < coin->balanceswritten-1 ) { printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); @@ -659,7 +681,7 @@ int32_t iguana_volatilesinit(struct supernet_info *myinfo,struct iguana_info *co fclose(fp); } if ( filecrc != 0 ) - printf("have filecrc.%08x for %s milli.%.0f from_ro.%d\n",filecrc,bits256_str(str,balancehash),OS_milliseconds(),from_ro); + printf("%s have filecrc.%08x for %s milli.%.0f from_ro.%d\n",coin->symbol,filecrc,bits256_str(str,balancehash),OS_milliseconds(),from_ro); if ( from_ro == 0 || filecrc == 0 ) { if ( filecrc == 0 ) @@ -677,6 +699,7 @@ int32_t iguana_volatilesinit(struct supernet_info *myinfo,struct iguana_info *co fprintf(stderr,"."); if ( filecrc == 0 ) { + //fprintf(stderr,"balancehash add [%d]\n",bp->hdrsi); vupdate_sha256(balancehash.bytes,&vstate,(void *)Aptr,sizeof(*Aptr) * numpkinds); vupdate_sha256(balancehash.bytes,&vstate,(void *)Uptr,sizeof(*Uptr) * numunspents); vupdate_sha256(allbundles.bytes,&bstate,(void *)bp->hashes,sizeof(bp->hashes[0]) * bp->n); @@ -687,21 +710,39 @@ int32_t iguana_volatilesinit(struct supernet_info *myinfo,struct iguana_info *co } //else printf("missing hdrs.[%d] data.%p num.(%u %d) %p %p\n",i,bp->ramchain.H.data,numpkinds,numunspents,Aptr,Uptr); } } else crc = filecrc; - printf("millis %.0f from_ro.%d written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",OS_milliseconds(),from_ro,coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); + printf("%s millis %.0f from_ro.%d written.%d crc.%08x/%08x balancehash.(%s) vs (%s)\n",coin->symbol,OS_milliseconds(),from_ro,coin->balanceswritten,crc,filecrc,bits256_str(str,balancehash),bits256_str(str2,coin->balancehash)); if ( (filecrc != 0 && filecrc != crc) || memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) != 0 || memcmp(allbundles.bytes,coin->allbundles.bytes,sizeof(allbundles)) != 0 ) { - printf("balancehash or crc.(%x %x) mismatch or allbundles.(%llx %llx) mismatch\n",crc,filecrc,(long long)allbundles.txid,(long long)coin->allbundles.txid); + printf("%s balancehash or crc.(%x %x) mismatch or allbundles.(%llx %llx) mismatch\n",coin->symbol,crc,filecrc,(long long)allbundles.txid,(long long)coin->allbundles.txid); iguana_truncatebalances(coin); OS_removefile(crcfname,0); } else { - printf("MATCHED balancehash numhdrsi.%d crc.%08x\n",coin->balanceswritten,crc); + printf("%s MATCHED balancehash numhdrsi.%d crc.%08x LONGEST.%d\n",coin->symbol,coin->balanceswritten,crc,coin->longestchain); if ( (fp= fopen(crcfname,"wb")) != 0 ) { if ( fwrite(&crc,1,sizeof(crc),fp) != sizeof(crc) || fwrite(&balancehash,1,sizeof(balancehash),fp) != sizeof(balancehash) || fwrite(&allbundles,1,sizeof(allbundles),fp) != sizeof(allbundles) ) printf("error writing.(%s)\n",crcfname); fclose(fp); + //if ( strcmp("BTC",coin->symbol) == 0 ) + { + if ( (coin->longestchain-coin->chain->minconfirms)/coin->chain->bundlesize < coin->bundlescount ) + { + for (i=0; ibundlescount-1; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + bp->converted = bp->balancefinish = bp->validated = bp->utxofinish = (uint32_t)time(NULL); + } + } + coin->matchedfiles = 1; + coin->spendvectorsaved = (uint32_t)time(NULL); + coin->spendvalidated = 0; + printf("LONGEST.%d %s UTXOGEN spendvectorsaved <- %u\n",coin->longestchain,coin->symbol,coin->spendvectorsaved); + iguana_utxoaddr_gen(myinfo,coin,(coin->bundlescount - 1) * coin->chain->bundlesize); + } else printf("(coin->longestchain+coin->chain->minconfirms)/coin->chain->bundlesize %d >= %d coin->bundlescount\n",(coin->longestchain+coin->chain->minconfirms)/coin->chain->bundlesize,coin->bundlescount); + } } else { @@ -722,18 +763,10 @@ int32_t iguana_volatilesinit(struct supernet_info *myinfo,struct iguana_info *co iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,block); } } - //printf("end volatilesinit\n"); - if ( iguana_fastfindinit(coin) == 0 )//&& coin->PREFETCHLAG >= 0 ) + if ( iguana_fastfindinit(coin) == 0 ) iguana_fastfindcreate(coin); - /*for (j=0; jbundlescount; j++) - if ( (bp= coin->bundles[j]) != 0 ) - { - iguana_volatilesalloc(coin,&bp->ramchain,1); - iguana_volatilesmap(coin,&bp->ramchain); - } - iguana_update_balances(coin);*/ iguana_datachain_scan(myinfo,coin,CRYPTO777_RMD160); - //iguana_utxoaddr_gen(myinfo,coin,(coin->bundlescount - 1) * coin->chain->bundlesize);*/ + printf("end %s volatilesinit\n",coin->symbol); return(coin->bundlescount); } @@ -743,14 +776,13 @@ void iguana_initfinal(struct supernet_info *myinfo,struct iguana_info *coin,bits if ( bits256_nonz(lastbundle) > 0 ) { init_hexbytes_noT(hashstr,lastbundle.bytes,sizeof(bits256)); - printf("req lastbundle.(%s)\n",hashstr); - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr)); } for (i=0; ibundlescount-1; i++) { - if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish <= 1 ) + if ( (bp= coin->bundles[i]) == 0 || bp->utxofinish <= 1 ) { - printf("initfinal break.[%d]: bp.%p or emit.%u utxofinish.%u\n",i,bp,bp!=0?bp->emitfinish:-1,bp!=0?bp->utxofinish:-1); + printf("%s initfinal break.[%d]: bp.%p or emit.%u utxofinish.%u\n",coin->symbol,i,bp,bp!=0?bp->emitfinish:-1,bp!=0?bp->utxofinish:-1); break; } if ( i == 0 ) @@ -758,11 +790,11 @@ void iguana_initfinal(struct supernet_info *myinfo,struct iguana_info *coin,bits } if ( i < coin->bundlescount-1 ) { - printf("spendvectors.[%d] max.%d missing, will regen all of them\n",i,coin->bundlescount-1); + printf("%s spendvectors.[%d] max.%d missing, will regen all of them\n",coin->symbol,i,coin->bundlescount-1); for (i=0; ibundlescount-1; i++) { if ( (bp= coin->bundles[i]) != 0 ) - bp->startutxo = bp->utxofinish = 0; + bp->utxofinish = bp->startutxo = bp->emitfinish = bp->converted = bp->balancefinish = bp->validated = 0; } } else @@ -773,33 +805,35 @@ void iguana_initfinal(struct supernet_info *myinfo,struct iguana_info *coin,bits bp->converted = (uint32_t)time(NULL); } } - printf("i.%d bundlescount.%d\n",i,coin->bundlescount); - if ( coin->balanceswritten > 1 ) + printf("%s i.%d bundlescount.%d\n",coin->symbol,i,coin->bundlescount); + //if ( coin->balanceswritten > 1 ) coin->balanceswritten = iguana_volatilesinit(myinfo,coin); - if ( coin->balanceswritten > 1 ) + /*if ( coin->balanceswritten > 1 ) { //for (i=0; ibalanceswritten; i++) for (i=0; ibundlescount; i++) { + if ( (bp= coin->bundles[i]) != 0 ) + iguana_bundlevalidate(myinfo,coin,bp,0); //printf("%d ",i); - iguana_validateQ(coin,coin->bundles[i]); + //iguana_validateQ(coin,coin->bundles[i]); } - } - printf("i.%d balanceswritten.%d\n",i,coin->balanceswritten); - if ( coin->balanceswritten < coin->bundlescount ) + }*/ + printf("%s i.%d balanceswritten.%d\n",coin->symbol,i,coin->balanceswritten); + /*if ( coin->balanceswritten < coin->bundlescount ) { for (i=0*coin->balanceswritten; ibundlescount; i++) { if ( (bp= coin->bundles[i]) != 0 && bp->queued == 0 ) { //printf("%d ",i); - iguana_bundleQ(coin,bp,1000); + iguana_bundleQ(myinfo,coin,bp,1000); } } printf("iguana_bundlesQ %d to %d\n",coin->balanceswritten,coin->bundlescount); } if ( (coin->origbalanceswritten= coin->balanceswritten) > 0 ) - iguana_volatilesinit(myinfo,coin); + iguana_volatilesinit(myinfo,coin);*/ iguana_savehdrs(coin); iguana_fastlink(coin,coin->balanceswritten * coin->chain->bundlesize - 1); iguana_walkchain(coin,0); @@ -837,7 +871,9 @@ int32_t iguana_balanceflush(struct supernet_info *myinfo,struct iguana_info *coi Aptr = 0; Uptr = 0; numunspents = numpkinds = 0; - if ( (bp= coin->bundles[hdrsi]) != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A2) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) + if ( (bp= coin->bundles[hdrsi]) == 0 ) + continue; + if ( bp != 0 && bp->ramchain.H.data != 0 && (numpkinds= bp->ramchain.H.data->numpkinds) > 0 && (numunspents= bp->ramchain.H.data->numunspents) > 0 && (Aptr= bp->ramchain.A2) != 0 && (Uptr= bp->ramchain.Uextras) != 0 ) { sprintf(fname,"%s/%s/debits.%d_N%d",GLOBAL_TMPDIR,coin->symbol,bp->hdrsi,numhdrsi); sprintf(fname2,"%s/%s/lastspends.%d_N%d",GLOBAL_TMPDIR,coin->symbol,bp->hdrsi,numhdrsi); @@ -854,9 +890,9 @@ int32_t iguana_balanceflush(struct supernet_info *myinfo,struct iguana_info *coi err = -1; if ( fwrite(&numhdrsi,1,sizeof(numhdrsi),fp) == sizeof(numhdrsi) && fwrite(&numhdrsi,1,sizeof(numhdrsi),fp2) == sizeof(numhdrsi) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp) == sizeof(balancehash) && fwrite(balancehash.bytes,1,sizeof(balancehash),fp2) == sizeof(balancehash) && fwrite(allbundles.bytes,1,sizeof(allbundles),fp) == sizeof(allbundles) && fwrite(allbundles.bytes,1,sizeof(allbundles),fp2) == sizeof(allbundles) ) { - if ( fwrite(Aptr,sizeof(*Aptr),numpkinds,fp) == numpkinds ) + if ( numpkinds == 0 || fwrite(Aptr,sizeof(*Aptr),numpkinds,fp) == numpkinds ) { - if ( fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) + if ( numunspents == 0 || fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) { err = 0; if ( (hdrsi % 100) == 0 ) @@ -883,26 +919,30 @@ int32_t iguana_balanceflush(struct supernet_info *myinfo,struct iguana_info *coi else if ( iter == 2 ) { sprintf(destfname,"%s/%s/accounts/debits.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); - if ( OS_copyfile(fname,destfname,1) < 0 ) + OS_removefile(destfname,0); + OS_renamefile(fname,destfname); + /*if ( OS_copyfile(fname,destfname,1) < 0 ) { printf("balances error copying (%s) -> (%s)\n",fname,destfname); return(-1); - } + }*/ sprintf(destfname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); - if ( OS_copyfile(fname2,destfname,1) < 0 ) + OS_removefile(destfname,0); + OS_renamefile(fname2,destfname); + /*if ( OS_copyfile(fname2,destfname,1) < 0 ) { printf("balances error copying (%s) -> (%s)\n",fname2,destfname); return(-1); - } + }*/ if ( (hdrsi % 100) == 0 ) printf("%s -> %s\n",fname,destfname); - OS_removefile(fname,0); - OS_removefile(fname2,0); + //OS_removefile(fname,0); + //OS_removefile(fname2,0); } if ( bp->ramchain.allocatedA2 == 0 || bp->ramchain.allocatedU2 == 0 ) { - printf("skip saving.[%d] files as not allocated\n",bp->hdrsi); - break; + printf("account.[%d] files not allocated %u %u\n",bp->hdrsi,(uint32_t)bp->ramchain.allocatedA2,(uint32_t)bp->ramchain.allocatedU2); + //break; } } else if ( hdrsi > 0 && hdrsi != coin->bundlescount && (coin->current == 0 || hdrsi != coin->current->hdrsi ) ) @@ -921,13 +961,13 @@ int32_t iguana_balanceflush(struct supernet_info *myinfo,struct iguana_info *coi if ( (bp= coin->bundles[hdrsi]) == 0 && bp != coin->current ) { iguana_volatilespurge(coin,&bp->ramchain); - if ( iguana_volatilesmap(coin,&bp->ramchain) != 0 ) + if ( iguana_volatilesmap(myinfo,coin,&bp->ramchain) != 0 ) printf("error mapping bundle.[%d]\n",hdrsi); } } char str[65]; printf("BALANCES WRITTEN for %d orig.%d bundles %s\n",coin->balanceswritten,coin->origbalanceswritten,bits256_str(str,coin->balancehash)); //iguana_utxoaddr_gen(myinfo,coin,(coin->balanceswritten - 1) * coin->chain->bundlesize); - if ( 0 && coin->balanceswritten > coin->origbalanceswritten+10 ) // strcmp(coin->symbol,"BTC") == 0 && + if ( (0) && coin->balanceswritten > coin->origbalanceswritten+10 ) // strcmp(coin->symbol,"BTC") == 0 && { coin->active = 0; coin->started = 0; @@ -952,12 +992,7 @@ int32_t iguana_balanceflush(struct supernet_info *myinfo,struct iguana_info *coi } } #endif - for (i=0; i<30; i++) - { - printf("need to exit, please restart after shutdown in %d seconds, or just ctrl-C\n",30-i); - sleep(1); - } - exit(-1); + iguana_exit(myinfo,0); } coin->balanceswritten = iguana_volatilesinit(myinfo,coin); //printf("flush free\n"); @@ -973,7 +1008,7 @@ int32_t iguana_spendvectorsaves(struct iguana_info *coin) return(0); coin->spendvectorsaved = 1; n = coin->bundlescount - 1; - //printf("SAVE SPEND VECTORS %d of %d\n",n,coin->bundlescount); + printf("SAVE SPEND VECTORS %d of %d\n",n,coin->bundlescount); for (iter=0; iter<2; iter++) { for (i=0; inumtmpspends; j++) if ( bp->tmpspends[j].tmpflag != 0 ) { - printf("vectorsave.[%d] vec.%d still has tmpflag\n",i,j); + printf("%s vectorsave.[%d] vec.%d still has tmpflag\n",coin->symbol,i,j); return(-1); } } @@ -1084,19 +1119,28 @@ int32_t iguana_convert(struct iguana_info *coin,int32_t helperid,struct iguana_b total[helperid % max] += converted; for (i=sum=0; icurrent ) + if ( (0) && converted != 0 && bp != coin->current ) printf("[%4d] millis %7.3f converted.%-7d balance calc.%-4d of %4d | total.%llu of %llu depth.%d\n",bp->hdrsi,OS_milliseconds()-startmillis,converted,m,n,(long long)sum,(long long)total_tmpspends,(int32_t)depth); } depth--; return(converted); } -int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag) +int32_t iguana_bundlevalidate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag) { static int32_t totalerrs,totalvalidated; - FILE *fp; char fname[1024]; uint8_t *blockspace; //uint32_t now = (uint32_t)time(NULL); + FILE *fp; char fname[1024]; uint8_t *blockspace; uint32_t now = (uint32_t)time(NULL); int32_t i,max,len,errs = 0; struct sha256_vstate vstate; bits256 validatehash; int64_t total = 0; - if ( (coin->MAXPEERS > 1 && coin->VALIDATENODE == 0 && coin->FULLNODE == 0) || bp->ramchain.from_ro != 0 || bp == coin->current ) + if ( coin->chain->zcash != 0 ) + { + static uint32_t counter; + if ( (0) && counter++ < 3 ) + printf("need to process joinsplits before can validate.%s\n",coin->symbol); + bp->validated = (uint32_t)time(NULL); + forceflag = 1; + //return(bp->n); + } + if ( (coin->MAXPEERS > 1 && coin->VALIDATENODE == 0 && coin->FULLNODE == 0) || bp->ramchain.from_ro != 0 )//|| bp == coin->current ) { bp->validated = (uint32_t)time(NULL); return(bp->n); @@ -1121,26 +1165,37 @@ int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp, } if ( forceflag != 0 || bp->validated <= 1 ) { - max = coin->blockspacesize; - blockspace = calloc(1,max); - iguana_volatilesmap(coin,&bp->ramchain); - for (i=0; in; i++) + if ( coin->chain->zcash == 0 ) { - if ( (len= iguana_peerblockrequest(coin,blockspace,max,0,bp->hashes[i],1)) < 0 ) - { - errs++; - iguana_blockunmark(coin,bp->blocks[i],bp,i,1); - totalerrs++; - } - else + max = coin->blockspacesize; + blockspace = calloc(1,max); + iguana_volatilespurge(coin,&bp->ramchain); + iguana_volatilesmap(myinfo,coin,&bp->ramchain); + for (i=0; in; i++) { - vupdate_sha256(validatehash.bytes,&vstate,bp->hashes[i].bytes,sizeof(bp->hashes[i])); - total += len, totalvalidated++; + char str[65]; + if ( coin->chain->fixit != 0 ) + printf("validate %s.[%d:%d] %s\n",coin->symbol,bp->hdrsi,i,bits256_str(str,bp->hashes[i])); + if ( (len= iguana_peerblockrequest(myinfo,coin,blockspace,max,0,bp->hashes[i],1)) < 0 ) + { + errs++; + //fprintf(stderr,"-%s.[%d:%d] ",coin->symbol,bp->hdrsi,i); + //printf("bundlevalidate: %s delete [%d:%d]\n",coin->symbol,bp->hdrsi,i); + iguana_blockunmark(coin,bp->blocks[i],bp,i,1); + totalerrs++; + } + else + { + vupdate_sha256(validatehash.bytes,&vstate,bp->hashes[i].bytes,sizeof(bp->hashes[i])); + total += len, totalvalidated++; + } } + free(blockspace); + printf("%s %s VALIDATED.[%d] ht.%d duration.%d errs.%d total.%lld %u | total errs.%d validated.%d %llx\n",coin->symbol,errs!=0?"NOT":"",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL) - now,errs,(long long)total,bp->validated,totalerrs,totalvalidated,(long long)validatehash.txid); } - free(blockspace); - bp->validated = (uint32_t)time(NULL); - // printf("VALIDATED.[%d] ht.%d duration.%d errs.%d total.%lld %u | total errs.%d validated.%d %llx\n",bp->hdrsi,bp->bundleheight,bp->validated - now,errs,(long long)total,bp->validated,totalerrs,totalvalidated,(long long)validatehash.txid); + if ( errs == 0 ) + bp->validated = (uint32_t)time(NULL); + else bp->validated = bp->startutxo = bp->utxofinish = 0; //iguana_volatilesmap(coin,&bp->ramchain); //if ( bp == coin->current ) // coin->RTdatabad = -1; @@ -1158,8 +1213,9 @@ int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp, } // else printf("skip validate.[%d] validated.%u force.%d\n",bp->hdrsi,bp->validated,forceflag); if ( errs != 0 ) { - printf("remove.[%d]\n",bp->hdrsi); + printf("%s remove.[%d]\n",coin->symbol,bp->hdrsi); iguana_bundleremove(coin,bp->hdrsi,0); + return(-errs); } return(bp->n - errs); } diff --git a/iguana/iguana_tradebots.c b/iguana/iguana_tradebots.c index 275592554..c514ed4bd 100755 --- a/iguana/iguana_tradebots.c +++ b/iguana/iguana_tradebots.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -38,7 +38,7 @@ struct tradebot_info cJSON *tradebot_json(struct supernet_info *myinfo,struct exchange_info *exchange,struct tradebot_info *bot) { - char str[64]; int32_t i,numpending; double pendsum,pendvolume,vol; cJSON *json,*array,*item; + char str[65]; int32_t i,numpending; double pendsum,pendvolume,vol; cJSON *json,*array,*item; json = cJSON_CreateObject(); jaddstr(json,"exchange",exchange->name); jaddstr(json,"started",utc_str(str,bot->started)); @@ -220,6 +220,8 @@ char *tradebot_control(struct supernet_info *myinfo,char *exchangestr,char *boti } #include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin) { @@ -227,9 +229,11 @@ HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin) return(clonestr("{\"result\":\"targetcoin updated\"}")); } -ZERO_ARGS(tradebot,amlp) +STRING_ARG(tradebot,amlp,blocktrail) { myinfo->IAMLP = 1; + if ( blocktrail != 0 ) + safecopy(myinfo->blocktrail_apikey,blocktrail,sizeof(myinfo->blocktrail_apikey)); return(clonestr("{\"result\":\"liquidity provider active\"}")); } diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index 36df86655..ac6346fc8 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,30 +14,40 @@ ******************************************************************************/ #include "iguana777.h" -//#include "SuperNET.h" -//struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp; uint16_t numvouts,numvins; } __attribute__((packed)); - -//struct iguana_msgvin { bits256 prev_hash; uint8_t *script; uint32_t prev_vout,scriptlen,sequence; } __attribute__((packed)); - -//struct iguana_spend { uint32_t spendtxidind; int16_t prevout; uint16_t tbd:14,external:1,diffsequence:1; } __attribute__((packed)); - -int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,long fileptr[2],char *fname,uint64_t scriptpos,int32_t scriptlen) +#if defined(_M_X64) + /* + * because we have no choice but to pass the value as parameters + * we need 64bit to hold 64bit memory address, thus changing + * to uint64_t instead of long in win x64 + * @author - fadedreamz@gmail.com + */ +int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,uint64_t fileptr[2],char *fname,uint64_t scriptpos,int32_t scriptlen) +#else +int32_t iguana_scriptdata(struct iguana_info *coin, uint8_t *scriptspace, long fileptr[2], char *fname, uint64_t scriptpos, int32_t scriptlen) +#endif { - FILE *fp; long err; int32_t retval = scriptlen; + FILE *fp; long err; uint8_t *ptr; int32_t i,retval = scriptlen; #ifndef __PNACL__ if ( scriptpos < 0xffffffff ) { if ( fileptr[0] == 0 ) - fileptr[0] = (long)OS_mapfile(fname,&fileptr[1],0); +#if defined(_M_X64) + fileptr[0] = (uint64_t)OS_mapfile(fname,&fileptr[1],0); +#else + fileptr[0] = (long)OS_mapfile(fname, &fileptr[1], 0); +#endif if ( fileptr[0] != 0 ) { if ( (scriptpos + scriptlen) <= fileptr[1] ) { - memcpy(scriptspace,(void *)(fileptr[0] + (uint32_t)scriptpos),scriptlen); + ptr = (void *)(fileptr[0] + (uint32_t)scriptpos); + //memcpy(scriptspace,ptr,scriptlen); + for (i=0; iramchain.from_ro,fname,s->fileid); if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->vinptrs[s->fileid],fname,s->scriptpos,s->scriptlen)) != s->scriptlen ) - printf("err.%d getting %d bytes from fileid.%llu[%d] %s for s%d\n",err,s->scriptlen,(long long)s->scriptpos,s->fileid,fname,spendind); + printf("err.%d getting %d bytes from fileid.%u[%u] %s for s%d\n",err,(int32_t)s->scriptlen,(uint32_t)s->scriptpos,(uint32_t)s->fileid,fname,spendind); } vin->scriptlen = s->scriptlen; vin->vinscript = scriptspace; @@ -107,8 +117,10 @@ int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint if ( u->scriptpos > 0 && u->scriptlen > 0 ) { iguana_voutsfname(coin,bp->ramchain.from_ro,fname,u->fileid); - if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->voutptrs[u->fileid],fname,u->scriptpos,u->scriptlen)) != u->scriptlen ) - printf("%d bytes from fileid.%d[%d] %s for type.%d\n",u->scriptlen,u->fileid,u->scriptpos,fname,u->type); + if ( (int32_t)(scriptlen= iguana_scriptdata(coin,scriptspace,coin->voutptrs[u->fileid],fname,u->scriptpos,u->scriptlen)) != (int32_t)u->scriptlen ) + printf("scriptlen.%d != %d bytes from fileid.%d[%d] %s for type.%d\n",scriptlen,u->scriptlen,u->fileid,u->scriptpos,fname,u->type); + if ( scriptlen < 0 ) + scriptlen = 0; } else { @@ -134,8 +146,13 @@ int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmst //P = (void *)(long)((long)rdata + rdata->Poffset); unspentind = (tx->firstvout + i); u = &U[unspentind]; - if ( u->txidind != tx->txidind || u->vout != i || u->hdrsi != height / coin->chain->bundlesize ) - printf("iguana_voutset: txidind mismatch %d vs %d || %d vs %d || (%d vs %d)\n",u->txidind,u->txidind,u->vout,i,u->hdrsi,height / coin->chain->bundlesize); + if ( u->vout != i || u->hdrsi != height / coin->chain->bundlesize ) //u->txidind != tx->txidind || + { + static uint32_t counter; + if ( counter++ < 3 ) + printf("%s.[%d].%d iguana_voutset: vout mismatch t%d u%u || %d vs %d, type.%d scriptpos.%d scriptlen.%d\n",coin->symbol,height/coin->chain->bundlesize,u->hdrsi,u->txidind,unspentind,u->vout,i,u->type,u->scriptpos,u->scriptlen); + return(-1); + } vout->value = u->value; vout->pk_script = scriptspace; scriptlen = iguana_voutscript(coin,bp,scriptspace,asmstr,u,&P[u->pkind],i); @@ -152,19 +169,19 @@ struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid * struct iguana_bundle *bp; uint32_t txidind; if ( i >= 0 && i < block->RO.txn_count ) { - if ( block->height >= 0 ) + if ( block->height >= 0 && block->bundlei >= 0 && block->bundlei < coin->chain->bundlesize ) { if ( (bp= coin->bundles[block->hdrsi]) != 0 ) { - if ( (txidind= block->RO.firsttxidind) > 0 ) + if ( (txidind= block->RO.firsttxidind) == bp->firsttxidinds[block->bundlei] ) { if ( iguana_bundletx(coin,bp,block->bundlei,tx,txidind+i) == tx ) return(tx); printf("error getting txidind.%d + i.%d from hdrsi.%d\n",txidind,i,block->hdrsi); return(0); - } else printf("iguana_blocktx null txidind [%d:%d] i.%d\n",block->hdrsi,block->bundlei,i); + } else printf("iguana_blocktx null txidind [%d:%d] i.%d txidind.%d vs %d\n",block->hdrsi,block->bundlei,i,txidind,bp->firsttxidinds[block->bundlei]); } else printf("iguana_blocktx no bp.[%d]\n",block->hdrsi); - } else printf("blocktx illegal height.%d\n",block->height); + } else printf("%s blocktx illegal height.%d or [%d:%d]\n",coin->symbol,block->height,block->hdrsi,block->bundlei); } else printf("i.%d vs txn_count.%d\n",i,block->RO.txn_count); return(0); } @@ -178,29 +195,27 @@ int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t m version = tx->version; locktime = tx->locktime; timestamp = tx->timestamp; + numvins = tx->numvins; + numvouts = tx->numvouts; } len += iguana_rwnum(rwflag,&serialized[len],sizeof(version),&version); if ( coin->chain->isPoS != 0 ) len += iguana_rwnum(rwflag,&serialized[len],sizeof(timestamp),×tamp); - if ( rwflag == 0 ) - { - tx->version = version; - tx->timestamp = timestamp; - } - numvins = tx->numvins, numvouts = tx->numvouts; len += iguana_rwvarint32(rwflag,&serialized[len],&numvins); memset(&vin,0,sizeof(vin)); for (i=0; i maxlen ) + break; } if ( len > maxlen ) { @@ -211,9 +226,18 @@ int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t m for (i=0; i maxlen ) + break; } if ( len > maxlen ) { @@ -222,7 +246,13 @@ int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t m } len += iguana_rwnum(rwflag,&serialized[len],sizeof(locktime),&locktime); if ( rwflag == 0 ) + { + tx->version = version; + tx->timestamp = timestamp; + tx->numvins = numvins; + tx->numvouts = numvouts; tx->locktime = locktime; + } *txidp = bits256_doublesha256(txidstr,serialized,len); if ( memcmp(txidp,tx->txid.bytes,sizeof(*txidp)) != 0 ) { @@ -234,9 +264,19 @@ int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t m return(len); } -int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs) +int32_t iguana_peerblockrequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs) { - struct iguana_txid *tx,T; bits256 checktxid; int32_t i,len,total,bundlei=-2; struct iguana_block *block; struct iguana_msgblock msgB; bits256 *tree,checkhash2,merkle_root; struct iguana_bundle *bp=0; long tmp; char str[65]; struct iguana_ramchaindata *rdata; +#if defined(_M_X64) + /* + * because we have no choice but to access the memory address + * we need 64bit to correctly hold 64bit memory address, thus changing + * to uint64_t instead of long in win x64 + * @author - fadedreamz@gmail.com + */ + struct iguana_txid *tx, T; bits256 checktxid; int32_t i, len, total, bundlei = -2; struct iguana_block *block; struct iguana_msgzblock zmsgB; bits256 *tree, checkhash2, merkle_root; struct iguana_bundle *bp = 0; uint64_t tmp; char str[65]; struct iguana_ramchaindata *rdata; +#else + struct iguana_txid *tx,T; bits256 checktxid; int32_t i,len,total,bundlei=-2; struct iguana_block *block; struct iguana_msgzblock zmsgB; bits256 *tree,checkhash2,merkle_root; struct iguana_bundle *bp=0; long tmp; char str[65]; struct iguana_ramchaindata *rdata; +#endif if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) != 0 && bundlei >= 0 && bundlei < bp->n ) { if ( (rdata= bp->ramchain.H.data) == 0 )//&& bp == coin->current ) @@ -247,9 +287,9 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int } if ( (block= bp->blocks[bundlei]) != 0 && rdata != 0 ) { - iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&msgB,block,0); - msgB.txn_count = block->RO.txn_count; - total = iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&blockspace[sizeof(struct iguana_msghdr) + 0],&msgB,max); + iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&zmsgB,(void *)block,0); + zmsgB.txn_count = block->RO.txn_count; + total = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&blockspace[sizeof(struct iguana_msghdr) + 0],&zmsgB,max); if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) { //static int counter; @@ -261,30 +301,41 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int { if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) { - if ( (len= iguana_ramtxbytes(coin,&blockspace[sizeof(struct iguana_msghdr) + total],max - total,&checktxid,tx,block->height,0,0,validatesigs)) > 0 && bits256_cmp(checktxid,T.txid) == 0 ) + //printf("ht.%d [%d:%d] txi.%d i.%d o.%d %s\n",block->height,block->hdrsi,block->bundlei,i,tx->numvins,tx->numvouts,bits256_str(str,tx->txid)); + if ( (len= iguana_ramtxbytes(coin,&blockspace[sizeof(struct iguana_msghdr) + total],max - total,&checktxid,tx,block->height,0,0,validatesigs)) > 0 )//&& bits256_cmp(checktxid,T.txid) == 0 ) total += len; else { - //static int counter; + static uint32_t counter; char str[65],str2[65]; - //if ( counter++ < 100 ) + if ( counter++ < 100 ) { - for (i=0; ihdrsi,bundlei,bits256_str(str,checktxid),bits256_str(str2,T.txid)); + printf(" len.%d error getting txi.%d [%d:%d] cmp.%s %s\n",len,i,bp->hdrsi,bundlei,bits256_str(str,checktxid),bits256_str(str2,T.txid)); } break; } } else { - printf("null tx error getting txi.%d [%d:%d]\n",i,bp->hdrsi,bundlei); + printf("%s null tx error getting txi.%d [%d:%d]\n",coin->symbol,i,bp->hdrsi,bundlei); break; } } if ( i == block->RO.txn_count ) { +#if defined(_M_X64) + /* + * because we have no choice but to access the memory address + * we need 64bit to correctly hold 64bit memory address, thus changing + * to uint64_t instead of long in win x64 + * @author - fadedreamz@gmail.com + */ + tmp = (uint64_t)&blockspace[sizeof(struct iguana_msghdr) + total + sizeof(bits256)]; +#else tmp = (long)&blockspace[sizeof(struct iguana_msghdr) + total + sizeof(bits256)]; +#endif tmp &= ~(sizeof(bits256) - 1); tree = (void *)tmp; for (i=0; iRO.txn_count; i++) @@ -302,7 +353,7 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int { addr->lastsent = block->height; printf("Sendlen.%d block.%d %s to %s\n",total,block->height,bits256_str(str,block->RO.hash2),addr->ipaddr); - if ( 0 ) + if ( (0) ) { struct iguana_txblock txdata; int32_t checklen; static struct OS_memspace RAWMEM; if ( RAWMEM.ptr == 0 ) @@ -320,7 +371,7 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int for (i=0; i<16; i++) printf("%02x",blockspace[i + sizeof(struct iguana_msghdr)+81]); printf(" txhdr\n"); - if ( (checklen= iguana_gentxarray(coin,&RAWMEM,&txdata,&checklen,&blockspace[sizeof(struct iguana_msghdr)],total)) != total && checklen != total-1 ) + if ( (checklen= iguana_gentxarray(myinfo,coin,&RAWMEM,&txdata,&checklen,&blockspace[sizeof(struct iguana_msghdr)],total)) != total && checklen != total-1 ) printf("Error reconstructing txarray checklen.%d total.%d\n",checklen,total); } return(iguana_queue_send(addr,0,blockspace,"block",total)); @@ -330,9 +381,15 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int //printf("validated.[%d:%d] len.%d\n",bp->hdrsi,bundlei,total); return(total); } - } else printf("iguana_peerblockrequest: error merkle cmp tx.[%d] for ht.%d\n",i,bp->bundleheight+bundlei); + } else printf("iguana_peerblockrequest: %s error %s merkle cmp tx.[%d] for ht.%d\n",coin->symbol,bits256_str(str,block->RO.hash2),i,bp->bundleheight+bundlei); } else printf("iguana_peerblockrequest: error merkle verify tx.[%d] for ht.%d\n",i,bp->bundleheight+bundlei); - } else printf("iguana_peerblockrequest: error getting tx.[%d] for ht.%d block.%p main.%d ht.%d\n",i,bp->bundleheight+bundlei,block,block!=0?block->mainchain:-1,block!=0?block->height:-1); + } + else + { + static uint32_t counter; + if ( counter++ < 10 ) + printf("%s iguana_peerblockrequest: error getting tx.[%d] for ht.%d block.%p main.%d ht.%d\n",coin->symbol,i,bp->bundleheight+bundlei,block,block!=0?block->mainchain:-1,block!=0?block->height:-1); + } } else { @@ -346,9 +403,9 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int return(-1); } -cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag) +cJSON *iguana_blockjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag) { - char str[65],hexstr[1024]; int32_t i,len,size; struct iguana_txid *tx,T; struct iguana_msgblock msg; + char str[65],hexstr[1024]; int32_t i,len,size; struct iguana_txid *tx,T; struct iguana_msgzblock zmsg; struct iguana_msgblock *msg = (void *)&zmsg; struct iguana_zblock *zblock; bits256 hash2,nexthash2; uint8_t serialized[1024]; cJSON *array,*json = cJSON_CreateObject(); jaddstr(json,"result","success"); jaddstr(json,"hash",bits256_str(str,block->RO.hash2)); @@ -383,20 +440,34 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 serialized[3] = ((uint8_t *)&block->RO.bits)[0]; init_hexbytes_noT(hexstr,serialized,sizeof(uint32_t)); jaddstr(json,"nBitshex",hexstr); - memset(&msg,0,sizeof(msg)); - msg.H.version = block->RO.version; - msg.H.merkle_root = block->RO.merkle_root; - msg.H.timestamp = block->RO.timestamp; - msg.H.bits = block->RO.bits; if ( block->RO.allocsize == sizeof(struct iguana_zblock) ) { - msg.zH.bignonce = block->zRO[0].bignonce; - msg.zH.numelements = ZCASH_SOLUTION_ELEMENTS; + zblock = (void *)block; + memset(&zmsg,0,sizeof(zmsg)); + zmsg.zH.version = zblock->RO.version; + zmsg.zH.merkle_root = zblock->RO.merkle_root; + zmsg.zH.timestamp = zblock->RO.timestamp; + zmsg.zH.bits = zblock->RO.bits; + zmsg.zH.bignonce = zblock->zRO.bignonce; + if ( iguana_rwvarint32(1,zmsg.zH.var_numelements,&zblock->zRO.numelements) != sizeof(zmsg.zH.var_numelements) ) + printf("unexpected varint size for zmsg.zH.numelements <- %d\n",zblock->zRO.numelements); for (i=0; izRO[0].solution[i]; - } else msg.H.nonce = block->RO.nonce; - msg.txn_count = 0;//block->RO.txn_count; - len = iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&hash2,serialized,&msg,IGUANA_MAXPACKETSIZE*2); + zmsg.zH.solution[i] = zblock->zRO.solution[i]; + zmsg.txn_count = 0;//block->RO.txn_count; + len = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&hash2,serialized,&zmsg,IGUANA_MAXPACKETSIZE*2); + } + else + { + memset(msg,0,sizeof(&msg)); + msg->H.version = block->RO.version; + msg->H.prev_block = block->RO.prev_block; + msg->H.merkle_root = block->RO.merkle_root; + msg->H.timestamp = block->RO.timestamp; + msg->H.bits = block->RO.bits; + msg->H.nonce = block->RO.nonce; + msg->txn_count = 0;//block->RO.txn_count; + len = iguana_rwblock(myinfo,coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&hash2,serialized,&zmsg,IGUANA_MAXPACKETSIZE*2); + } init_hexbytes_noT(hexstr,serialized,len); jaddstr(json,"blockheader",hexstr); if ( txidsflag != 0 ) @@ -410,7 +481,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 jadd(json,"tx",array); //printf("add txids[%d]\n",block->txn_count); } - if ( (size= iguana_peerblockrequest(coin,coin->blockspace,coin->blockspacesize,0,block->RO.hash2,0)) < 0 ) + if ( (size= iguana_peerblockrequest(myinfo,coin,coin->blockspace,coin->blockspacesize,0,block->RO.hash2,0)) < 0 ) jaddstr(json,"error","couldnt generate raw bytes for block"); else jaddnum(json,"size",size); return(json); diff --git a/iguana/iguana_txidfind.c b/iguana/iguana_txidfind.c index 9805c2ba6..6f9e81f52 100755 --- a/iguana/iguana_txidfind.c +++ b/iguana/iguana_txidfind.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -18,7 +18,7 @@ int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramchain) { static int64_t total; struct iguana_ramchaindata *rdata; - if ( 0 && ramchain->txbits == 0 && (rdata= ramchain->H.data) != 0 ) + if ( (0) && ramchain->txbits == 0 && (rdata= ramchain->H.data) != 0 ) { int32_t tlen; uint8_t *TXbits; TXbits = RAMCHAIN_PTR(rdata,TXoffset); @@ -65,7 +65,7 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl printf("iguana_sparseadd tablesize zero illegal\n"); return(0); } - if ( 0 && setind == 0 ) + if ( (0) && setind == 0 ) { char str[65]; for (i=n=0; i> modval; } if ( x != 0 ) - printf("%s ",bits256_str(str,*(bits256 *)(refdata + x*refsize))), n++; + printf("%s ",bits256_str(str,*(bits256 *)((long)refdata + x*refsize))), n++; } printf("tableentries.%d\n",n); } //if ( setind == 0 ) // ramchain->sparsesearches++; //else ramchain->sparseadds++; - if ( 0 && (rdata= ramchain->H.data) != 0 && (ramchain->sparsesearches % 1000000) == 0 ) + if ( (0) && (rdata= ramchain->H.data) != 0 && (ramchain->sparsesearches % 1000000) == 0 ) printf("[%3d] %7d.[%-2d %8d] %5.3f adds.(%-10ld %10ld) search.(hits.%-10ld %10ld) %5.2f%% max.%ld\n",ramchain->height/rdata->numblocks,ramchain->height,width,tablesize,(double)(ramchain->sparseadditers + ramchain->sparsesearchiters)/(1+ramchain->sparsesearches+ramchain->sparseadds),ramchain->sparseadds,ramchain->sparseadditers,ramchain->sparsehits,ramchain->sparsesearches,100.*(double)ramchain->sparsehits/(1+ramchain->sparsesearches),ramchain->sparsemax+1); if ( width == 32 ) { @@ -123,7 +123,7 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl else { bitoffset = (ind * width); - if ( 0 && setind == 0 ) + if ( (0) && setind == 0 ) printf("tablesize.%d width.%d bitoffset.%d\n",tablesize,width,(int32_t)bitoffset); for (i=0; i> 3]; modval = (bitoffset & 7); - if ( 0 && setind == 0 ) + if ( (0) && setind == 0 ) printf("tablesize.%d width.%d bitoffset.%d modval.%d i.%d\n",tablesize,width,(int32_t)bitoffset,modval,i); for (x=j=0; j> 3]; - if ( 0 && setind == 0 ) + if ( (0) && setind == 0 ) printf("x.%d\n",x); if ( x == 0 ) { @@ -179,7 +179,7 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl } } else bits[bitoffset >> 3] = setind; - if ( 0 ) + if ( (0) ) { for (x=j=0; jsparsemax = i; return(setind); } + // fadedreamz@gmail.com +#if defined(_M_X64) + /* + * calculate the address in a portable manner + * in all platform sizeof(char) / sizeof(uchar) == 1 + * @author - fadedreamz@gmail.com + */ + else if (x < maxitems && memcmp((void *)((unsigned char *)refdata + x*refsize), key, keylen) == 0) +#else else if ( x < maxitems && memcmp((void *)(long)((long)refdata + x*refsize),key,keylen) == 0 ) +#endif { if ( setind == 0 ) ramchain->sparsehits++; @@ -307,7 +317,7 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st //printf("found txidind.%d\n",txidind); if ( bits256_cmp(txid,T[txidind].txid) == 0 ) { - if ( 0 ) + if ( (0) ) { int32_t j; struct iguana_block *block; for (j=0; jn; j++) @@ -316,7 +326,7 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st if ( j < bp->n ) { if ( j != T[txidind].bundlei ) - printf("bundlei mismatch j.%d != %d\n",j,T[txidind].bundlei); + printf("bundlei mismatch j.%d != %u\n",j,(uint32_t)T[txidind].bundlei); else { *heightp = bp->bundleheight + T[txidind].bundlei; @@ -335,7 +345,7 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st return(tx); } } - char str[65],str2[65]; printf("iguana_txidfind mismatch.[%d:%d] %d %s vs %s\n",bp->hdrsi,T[txidind].extraoffset,txidind,bits256_str(str,txid),bits256_str(str2,T[txidind].txid)); + char str[65],str2[65]; printf("iguana_txidfind mismatch.[%d:%u] %d %s vs %s\n",bp->hdrsi,(uint32_t)T[txidind].extraoffset,txidind,bits256_str(str,txid),bits256_str(str2,T[txidind].txid)); return(0); } } @@ -362,13 +372,13 @@ int32_t iguana_txidfastfind(struct iguana_info *coin,int32_t *heightp,bits256 tx if ( val >= tablesize ) val = 0; if ( (i= hashtable[val]) == 0 ) - return(-1); + return(0); else { if ( i > num ) { printf("illegal val.%d vs num.%d tablesize.%d fastfind.%02x\n",i,num,tablesize,txid.bytes[31]); - return(-1); + return(0); } else { @@ -381,11 +391,11 @@ int32_t iguana_txidfastfind(struct iguana_info *coin,int32_t *heightp,bits256 tx if ( *heightp >= (lasthdrsi+1)*coin->chain->bundlesize ) { printf("txidfastfind: unexpected height.%d with lasthdrsi.%d\n",*heightp,lasthdrsi); - return(-1); + return(0); } return(firstvout); } - else if ( 0 ) + else if ( (0) ) { int32_t k; for (k=-16; k<0; k++) @@ -403,7 +413,7 @@ int32_t iguana_txidfastfind(struct iguana_info *coin,int32_t *heightp,bits256 tx } } } - return(-1); + return(0); } int32_t iguana_fastfindadd(struct iguana_info *coin,bits256 txid,int32_t height,uint32_t firstvout) @@ -452,9 +462,26 @@ static int _bignum_cmp(const void *a,const void *b) return(0); } +int32_t iguana_fastfindreset(struct iguana_info *coin) +{ + int32_t i,n = 0; + for (i=0; i<0x100; i++) + { + if ( coin->fast[i] != 0 ) + munmap(coin->fast[i],coin->fastsizes[i]), n++; + if( coin->fasttables[i] != 0 ) + free(coin->fasttables[i]); + coin->fast[i] = 0; + coin->fastsizes[i] = 0; + coin->fasttables[i] = 0; + } + coin->fastfind = 0; + return(n); +} + uint32_t iguana_fastfindinit(struct iguana_info *coin) { - int32_t i,j,iter,num,tablesize,*hashtable; uint8_t *sorted; char fname[1024]; + int32_t i,iter,num,tablesize,*hashtable; uint8_t *sorted; char fname[1024]; //if ( strcmp("BTC",coin->symbol) != 0 ) // return(0); if ( coin->fastfind != 0 ) @@ -470,7 +497,7 @@ uint32_t iguana_fastfindinit(struct iguana_info *coin) { fprintf(stderr,"."); sorted = coin->fast[i]; - if ( 0 ) + if ( (0) ) { coin->fast[i] = calloc(1,coin->fastsizes[i]); memcpy(coin->fast[i],sorted,coin->fastsizes[i]); @@ -482,7 +509,7 @@ uint32_t iguana_fastfindinit(struct iguana_info *coin) if ( (num+1)*16 + tablesize*sizeof(*hashtable) == coin->fastsizes[i] ) { hashtable = (int32_t *)((long)sorted + (1 + num)*16); - if ( 0 ) + if ( (0) ) { coin->fasttables[i] = calloc(tablesize,sizeof(*hashtable)); memcpy(coin->fasttables[i],hashtable,tablesize * sizeof(*hashtable)); @@ -500,17 +527,7 @@ uint32_t iguana_fastfindinit(struct iguana_info *coin) coin->fastfind = (uint32_t)time(NULL); printf("initialized fastfind.%s iter.%d\n",coin->symbol,iter); return(coin->fastfind); - } - else - { - for (j=0; jfast[i],coin->fastsizes[i]); - free(coin->fasttables[i]); - coin->fast[i] = 0; - coin->fastsizes[i] = 0; - } - } + } else iguana_fastfindreset(coin); } return(0); } @@ -621,7 +638,7 @@ struct iguana_monitorinfo *iguana_monitorfind(struct iguana_info *coin,bits256 t struct iguana_monitorinfo *iguana_txidreport(struct iguana_info *coin,bits256 txid,struct iguana_peer *addr) { - struct iguana_monitorinfo *ptr; char str[65]; + struct iguana_monitorinfo *ptr; //char str[65]; if ( (ptr= iguana_monitorfind(coin,txid)) != 0 ) { if ( GETBIT(ptr->peerbits,addr->addrind) == 0 ) @@ -630,7 +647,7 @@ struct iguana_monitorinfo *iguana_txidreport(struct iguana_info *coin,bits256 tx SETBIT(ptr->peerbits,addr->addrind); ptr->numreported++; } - } else printf("txid.%s not being monitored\n",bits256_str(str,txid)); + } // else printf("%s txid.%s not being monitored\n",coin->symbol,bits256_str(str,txid)); return(0); } @@ -653,11 +670,12 @@ struct iguana_monitorinfo *iguana_txidmonitor(struct iguana_info *coin,bits256 t double iguana_txidstatus(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid) { - int32_t height,firstvout,numranked; struct iguana_monitorinfo *ptr; char str[65]; + struct iguana_outpoint outpt; int32_t height,firstvout,numranked; struct iguana_monitorinfo *ptr; char str[65]; if ( coin != 0 && coin->peers != 0 && (numranked= coin->peers->numranked) > 0 ) { - if ( (firstvout= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,txid,0,coin->bundlescount-1,0)) != 0 ) + if ( iguana_RTunspentindfind(myinfo,coin,&outpt,0,0,0,0,&height,txid,0,coin->bundlescount-1,0) == 0 ) { + firstvout = outpt.unspentind; if ( (ptr= iguana_monitorfind(coin,txid)) != 0 ) memset(ptr,0,sizeof(*ptr)); return((double)coin->longestchain - height); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 46cdeb34b..2974c300f 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -62,59 +62,18 @@ int32_t iguana_RTunspentind2txid(struct supernet_info *myinfo,struct iguana_info else break; } return(-1); - //{"txid":"e34686afc17ec37a8438f0c9a7e48f98d0c625c7917a59c2d7fa22b53d570115","vout":1,"address":"16jsjc1YvzDXqKf7PorMhTyK8ym3ra3uxm","scriptPubKey":"76a9143ef4734c1141725c095342095f6e0e7748b6c16588ac","amount":0.01000000,"timestamp":0,"height":419261,"confirmations":1729,"checkind":4497018,"account":"default","spendable":true,"spent":{"hdrsi":209,"pkind":2459804,"unspentind":4497018,"prevunspentind":0,"satoshis":"1000000","txidind":1726947,"vout":1,"type":2,"fileid":0,"scriptpos":0,"scriptlen":25},"spentheight":419713,"dest":{"spentfrom":"22651e62f248fe2e72053d650f177e4b246ee016605102a40419e603b2bbeac8","vin":0,"timestamp":0,"vouts":[{"1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu":0.00010000}, {"1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY":0.00980000}],"total":0.00990000,"ratio":1}} - /* cJSON *retarray,*item,*uitem,*sitem; char *retstr; int32_t i,n,retval = -1; - *voutp = *spentheightp = -1; - memset(txidp,0,sizeof(*txidp)); - if ( (retstr= bitcoinrpc_listunspent(myinfo,coin,0,0,0,0,0)) != 0 ) - { - if ( (retarray= cJSON_Parse(retstr)) != 0 ) - { - if ( (n= cJSON_GetArraySize(retarray)) > 0 ) - { - for (i=0; iRTmutex); if ( valuep != 0 ) *valuep = 0; + *spentamountp = 0; if ( coinaddr != 0 ) coinaddr[0] = 0; - if ( coin->fastfind != 0 && (firstvout= iguana_txidfastfind(coin,heightp,txid,lasthdrsi)) >= 0 ) + if ( coin->fastfind != 0 && (firstvout= iguana_txidfastfind(coin,heightp,txid,lasthdrsi)) > 0 ) unspentind = (firstvout + vout); else if ( (tp= iguana_txidfind(coin,heightp,&TX,txid,lasthdrsi)) != 0 ) unspentind = (tp->firstvout + vout); @@ -136,14 +95,14 @@ int32_t iguana_unspentindfind(struct supernet_info *myinfo,struct iguana_info *c memset(&spentpt,0,sizeof(spentpt)); spentpt.hdrsi = bp->hdrsi; spentpt.unspentind = unspentind; - if ( iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,&bp->ramchain,spentpt,0,1,coin->longestchain,U[unspentind].value) == 0 ) //bp == coin->current ? &coin->RTramchain : + bitcoin_address(coinaddr,iguana_addrtype(coin,U[unspentind].type),P[pkind].rmd160,sizeof(P[pkind].rmd160)); + if ( iguana_markedunspents_find(coin,&firstslot,txid,vout) < 0 && iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,&bp->ramchain,spentpt,0,1,coin->longestchain,U[unspentind].value) == 0 ) //bp == coin->current ? &coin->RTramchain : { if ( valuep != 0 ) *valuep = U[unspentind].value; - bitcoin_address(coinaddr,iguana_addrtype(coin,U[unspentind].type),P[pkind].rmd160,sizeof(P[pkind].rmd160)); if ( spendscript != 0 && spendlenp != 0 ) *spendlenp = iguana_voutscript(coin,bp,spendscript,0,&U[unspentind],&P[pkind],1); - } + } else *spentamountp = RTspend; } } if ( flag == 0 && mempool != 0 ) @@ -169,19 +128,37 @@ int32_t iguana_unspentindfind(struct supernet_info *myinfo,struct iguana_info *c char *iguana_RTinputaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,struct iguana_outpoint *spentp,cJSON *vinobj) { - bits256 txid; int32_t vout,checkind,height; + bits256 txid; int32_t vout,checkind,height,n; cJSON *txoutjson,*array; char *retstr,_coinaddr[64]; memset(spentp,0,sizeof(*spentp)); + if ( coinaddr == 0 ) + coinaddr = _coinaddr; spentp->hdrsi = -1; + //printf("%s RTinputaddress.(%s).%d %d\n",coin->symbol,jprint(vinobj,0),coin->FULLNODE,coin->notarychain); if ( jobj(vinobj,"txid") != 0 && jobj(vinobj,"vout") != 0 ) { txid = jbits256(vinobj,"txid"); vout = jint(vinobj,"vout"); + if ( coin->FULLNODE == 0 && coin->notarychain >= 0 ) + { + if ( (retstr= _dex_gettxout(myinfo,coin->symbol,txid,vout)) != 0 ) + { + //printf("dexgetO.(%s)\n",retstr); + if ( (txoutjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (array= jarray(&n,txoutjson,"addresses")) != 0 ) + safecopy(coinaddr,jstri(array,0),64); + spentp->value = jdouble(txoutjson,"value") * SATOSHIDEN; + free_json(txoutjson); + } + free(retstr); + return(coinaddr); + } else printf("dexgettxout null retstr\n"); + return(0); + } height = jint(vinobj,"height"); checkind = jint(vinobj,"checkind"); - if ( (height != 0 && checkind != 0) || (checkind= iguana_RTunspentindfind(myinfo,coin,coinaddr,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) > 0 ) + if ( (height != 0 && checkind != 0) || iguana_RTunspentindfind(myinfo,coin,spentp,coinaddr,0,0,0,&height,txid,vout,coin->bundlescount-1,0) == 0 ) { - spentp->hdrsi = (height / coin->chain->bundlesize); - spentp->unspentind = checkind; return(coinaddr); } else @@ -210,9 +187,9 @@ cJSON *ramchain_unspentjson(struct iguana_unspent *up,uint32_t unspentind) return(item); } -cJSON *ramchain_spentjson(struct iguana_info *coin,int32_t spentheight,bits256 txid,int32_t vout,int64_t uvalue) +cJSON *ramchain_spentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t spentheight,bits256 txid,int32_t vout,uint64_t uvalue) { - char coinaddr[64]; bits256 hash2,*X; struct iguana_txid T,*tx,*spentT,*spent_tx; struct iguana_bundle *bp; int32_t j,i,ind; struct iguana_block *block; int64_t total = 0; struct iguana_unspent *U,*u; struct iguana_pkhash *P; struct iguana_spend *S,*s; struct iguana_ramchaindata *rdata; cJSON *addrs,*item,*voutobj; + char coinaddr[64]; bits256 hash2,*X; struct iguana_txid T,*tx,*spentT,*spent_tx; struct iguana_bundle *bp; int32_t j,i,ind; struct iguana_block *block; uint64_t value,total = 0; struct iguana_unspent *U,*u; struct iguana_pkhash *P; struct iguana_spend *S,*s; struct iguana_ramchaindata *rdata; cJSON *addrs,*item,*voutobj; item = cJSON_CreateObject(); hash2 = iguana_blockhash(coin,spentheight); if ( (block= iguana_blockfind("spent",coin,hash2)) != 0 && (bp= coin->bundles[spentheight/coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) @@ -226,8 +203,6 @@ cJSON *ramchain_spentjson(struct iguana_info *coin,int32_t spentheight,bits256 t { if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) { - // struct iguana_txid { bits256 txid; uint32_t txidind:29,firstvout:28,firstvin:28,bundlei:11,locktime,version,timestamp,extraoffset; uint16_t numvouts,numvins; } __attribute__((packed)); - // struct iguana_spend { uint64_t scriptpos:48,scriptlen:16; uint32_t spendtxidind,sequenceid; int16_t prevout; uint16_t fileid:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 s = &S[tx->firstvin]; for (j=0; jnumvins; j++,s++) { @@ -267,11 +242,39 @@ cJSON *ramchain_spentjson(struct iguana_info *coin,int32_t spentheight,bits256 t } } } + else + { + struct iguana_RTtxid *RTptr,*tmp; struct iguana_RTspend *spend; + HASH_ITER(hh,coin->RTdataset,RTptr,tmp) + { + for (i=0; inumvins; i++) + { + if ( (spend= RTptr->spends[i]) != 0 ) + { + if ( bits256_cmp(spend->prev_hash,txid) == 0 && spend->prev_vout == vout ) + { + value = iguana_txidamount(myinfo,coin,coinaddr,txid,vout); + jaddnum(item,"total",dstr(value)); + jaddbits256(item,"spentfrom",RTptr->txid); + jaddnum(item,"vin",i); + addrs = cJSON_CreateArray(); + voutobj = cJSON_CreateObject(); + jaddnum(voutobj,coinaddr,dstr(value)); + jaddi(addrs,voutobj); + jadd(item,"vouts",addrs); + jaddnum(item,"timestamp",RTptr->timestamp); + //printf("Found MATCH! (%s %.8f)\n",coinaddr,dstr(value)); + return(item); + } + } + } + } + } jaddstr(item,"error","couldnt find spent info"); return(item); } -cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,bits256 txid,int32_t vout,int64_t value,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr) +cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,bits256 txid,int32_t vout,uint64_t value,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr) { /*{ "txid" : "d54994ece1d11b19785c7248868696250ab195605b469632b7bd68130e880c9a", @@ -283,8 +286,7 @@ cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coi "confirmations" : 6210, "spendable" : true },*/ - //struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; uint16_t hdrsi:12,type:4,vout; } __attribute__((packed)); - struct iguana_waccount *wacct; struct iguana_waddress *waddr; int32_t height; char scriptstr[8192],asmstr[sizeof(scriptstr)+1024]; cJSON *item; uint32_t checkind; struct iguana_RTunspent *unspent; + struct iguana_waccount *wacct; struct iguana_waddress *waddr; int32_t height; char scriptstr[8192],asmstr[sizeof(scriptstr)+1024]; cJSON *item; uint32_t checkind; struct iguana_RTunspent *unspent; struct iguana_block *block; item = cJSON_CreateObject(); jaddbits256(item,"txid",txid); jaddnum(item,"vout",vout); @@ -303,9 +305,14 @@ cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coi jaddstr(item,"scriptPubKey",scriptstr); } jaddnum(item,"amount",dstr(value)); + if ( strcmp(coin->symbol,"KMD") == 0 ) + jaddnum(item,"interest",dstr(iguana_interest(myinfo,coin,txid,vout,value))); //jaddnum(item,"timestamp",T[up->txidind].timestamp); - if ( (checkind= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) != 0 ) + if ( iguana_RTunspentindfind(myinfo,coin,&outpt,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0) == 0 ) { + checkind = outpt.unspentind; + if ( (block= iguana_blockfind("unspentjson",coin,iguana_blockhash(coin,height))) != 0 && block->RO.timestamp != 0 ) + jaddnum(item,"timestamp",block->RO.timestamp); jaddnum(item,"height",height); jaddnum(item,"confirmations",coin->blocks.hwmchain.height - height + 1); jaddnum(item,"checkind",checkind); @@ -325,14 +332,14 @@ cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coi if ( up != 0 ) jadd(item,"spent",ramchain_unspentjson(up,outpt.unspentind)); jaddnum(item,"spentheight",spentheight); - jadd(item,"dest",ramchain_spentjson(coin,spentheight,txid,vout,value)); + jadd(item,"dest",ramchain_spentjson(myinfo,coin,spentheight,txid,vout,value)); } else if ( up != 0 ) jadd(item,"unspent",ramchain_unspentjson(up,outpt.unspentind)); return(item); } -struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *depositsp,struct iguana_outpoint *lastptp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) +struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,uint64_t *depositsp,struct iguana_outpoint *lastptp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) { uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_account *ACCTS; struct iguana_RTaddr *RTaddr; *depositsp = 0; @@ -354,7 +361,7 @@ struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_r { if ( (bp= coin->bundles[i]) != 0 ) { - if ( 0 && coin->RTramchain_busy != 0 ) + if ( (0) && coin->RTramchain_busy != 0 ) { printf("iguana_pkhashfind: unexpected access when RTramchain_busy\n"); return(0); @@ -381,8 +388,11 @@ struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_r return(p); } else if ( pkind != 0 ) printf("[%d] not found pkind.%d vs num.%d RT.%d rdata.%p\n",i,pkind,rdata->numpkinds,bp->isRT,rdata); - } else if ( coin->spendvectorsaved > 1 && bp != coin->current && bp->bundleheight < coin->firstRTheight ) - printf("%s.[%d] skip null rdata isRT.%d [%d]\n",coin->symbol,i,bp->isRT,coin->current!=0?coin->current->hdrsi:-1); + } + else if ( coin->spendvectorsaved > 1 && bp != coin->current && bp->bundleheight < coin->firstRTheight ) + { + //printf("%s.[%d] skip null rdata isRT.%d [%d]\n",coin->symbol,i,bp->isRT,coin->current!=0?coin->current->hdrsi:-1); + } } } return(0); @@ -395,9 +405,35 @@ int32_t iguana_uheight(struct iguana_info *coin,int32_t bundleheight,struct igua else return(bundleheight); } +int32_t iguana_outpt_set(struct iguana_info *coin,struct iguana_outpoint *outpt,struct iguana_unspent *u,uint32_t unspentind,int16_t hdrsi,bits256 txid,int32_t vout,uint8_t *rmd160,uint8_t *pubkey33) +{ + char scriptstr[IGUANA_MAXSCRIPTSIZE*2+1],asmstr[16384]; + memset(outpt,0,sizeof(*outpt)); + outpt->txid = txid; + outpt->vout = vout; + outpt->hdrsi = hdrsi; + outpt->isptr = 0; + outpt->unspentind = unspentind; + outpt->value = u->value; + if ( iguana_scriptget(coin,scriptstr,asmstr,sizeof(scriptstr),outpt->hdrsi,outpt->unspentind,outpt->txid,outpt->vout,rmd160,u->type,pubkey33) != 0 ) + { + //printf("scriptstr.(%s)\n",scriptstr); + outpt->spendlen = (int32_t)strlen(scriptstr) >> 1; + if ( outpt->spendlen < sizeof(outpt->spendscript) ) + decode_hex(outpt->spendscript,outpt->spendlen,scriptstr); + else + { + outpt->spendlen = 0; + printf("error scriptstr.(%s) is too big for %d\n",scriptstr,(int32_t)sizeof(outpt->spendscript)); + return(-1); + } + } + return(0); +} + int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t rmd160[20]) { - int64_t deposits,crypto777_payment; struct iguana_outpoint lastpt; uint32_t unspentind; int32_t i,j,num,uheight; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P,p; struct iguana_unspent *U,*u; struct iguana_txid *T,*tx; + uint64_t deposits,crypto777_payment; struct iguana_outpoint lastpt; uint32_t unspentind; int32_t i,j,num,uheight; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P,p; struct iguana_unspent *U,*u; struct iguana_txid *T,*tx; for (i=num=0; ibundlescount&&i*coin->chain->bundlesizefirstRTheight; i++) { if ( (bp= coin->bundles[i]) != 0 ) @@ -432,7 +468,7 @@ int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *c return(num); } -int32_t iguana_RTscanunspents(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,cJSON *array,int64_t *spentp,int64_t *depositsp,struct iguana_outpoint *unspents,int32_t max,uint8_t *rmd160,char *coinaddr,uint8_t *pubkey33,struct iguana_outpoint lastpt,int32_t lastheight) +int32_t iguana_RTscanunspents(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,cJSON *array,uint64_t *spentp,uint64_t *depositsp,struct iguana_outpoint *unspents,int32_t max,uint8_t *rmd160,char *coinaddr,uint8_t *pubkey33,struct iguana_outpoint lastpt,int32_t lastheight) { int32_t spentheight,n = 0; struct iguana_outpoint outpt; bits256 txid; struct iguana_RTtxid *parent; struct iguana_RTunspent *unspent = lastpt.ptr; while ( unspent != 0 ) @@ -441,7 +477,7 @@ int32_t iguana_RTscanunspents(struct supernet_info *myinfo,struct iguana_info *c { if ( unspent->spend == 0 ) { - spentheight = unspent->height; + spentheight = 0; memset(&outpt,0,sizeof(outpt)); memset(&txid,0,sizeof(txid)); if ( (parent= unspent->parent) != 0 ) @@ -449,7 +485,17 @@ int32_t iguana_RTscanunspents(struct supernet_info *myinfo,struct iguana_info *c else printf("unspent has no parent?\n"); outpt.isptr = 1; outpt.ptr = unspent; + outpt.txid = txid; + outpt.vout = unspent->vout; + outpt.value = unspent->value; outpt.hdrsi = unspent->height / coin->chain->bundlesize; + if ( (outpt.spendlen= unspent->scriptlen) > 0 && outpt.spendlen < sizeof(outpt.spendscript) ) + memcpy(outpt.spendscript,unspent->script,outpt.spendlen); + else + { + printf("spendscript.%d doesnt fit into %d\n",outpt.spendlen,(int32_t)sizeof(outpt.spendscript)); + outpt.spendlen = 0; + } if ( array != 0 ) jaddi(array,iguana_RTunspentjson(myinfo,coin,outpt,txid,unspent->vout,unspent->value,0,rmd160,coinaddr,pubkey33,spentheight,remoteaddr)); *depositsp += unspent->value; @@ -463,12 +509,12 @@ int32_t iguana_RTscanunspents(struct supernet_info *myinfo,struct iguana_info *c return(n); } -int64_t iguana_RTpkhashbalance(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int64_t *spentp,struct iguana_outpoint *unspents,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,struct iguana_outpoint lastpt,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,int32_t minconf,int32_t maxconf,char *remoteaddr,int32_t includespent) +int64_t iguana_RTpkhashbalance(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,uint64_t *spentp,struct iguana_outpoint *unspents,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,struct iguana_outpoint lastpt,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,int32_t minconf,int32_t maxconf,char *remoteaddr,int32_t includespent) { - struct iguana_unspent *U; struct iguana_utxo *U2; int32_t spentflag,max,uheight,spentheight; uint32_t pkind=0,unspentind; int64_t spent = 0,checkval,deposits = 0; struct iguana_txid *T; struct iguana_account *A2; struct iguana_outpoint outpt; struct iguana_ramchaindata *rdata = 0; int64_t RTspend = 0; //struct iguana_spend *S; + struct iguana_unspent *U; struct iguana_utxo *U2; int32_t firstslot,vout,spentflag,max,uheight,spentheight=0; uint32_t pkind=0,unspentind; uint64_t spent = 0,checkval,deposits = 0; struct iguana_txid *T; struct iguana_account *A2; struct iguana_outpoint outpt; struct iguana_ramchaindata *rdata = 0; uint64_t RTspend = 0; bits256 txid; max = *nump; *spentp = *nump = 0; - if ( 0 && coin->RTramchain_busy != 0 ) + if ( (0) && coin->RTramchain_busy != 0 ) { printf("iguana_pkhashbalance: unexpected access when RTramchain_busy\n"); return(0); @@ -478,16 +524,26 @@ int64_t iguana_RTpkhashbalance(struct supernet_info *myinfo,struct iguana_info * if ( lastpt.isptr != 0 ) { *nump = iguana_RTscanunspents(myinfo,coin,remoteaddr,array,spentp,&deposits,unspents,max,rmd160,coinaddr,pubkey33,lastpt,lastheight); - } else printf("iguana_pkhashbalance: unexpected non-ptr lastpt\n"); + } + else + { + printf("iguana_pkhashbalance: unexpected RT non-ptr lastpt\n"); + coin->RTreset_needed = 1; + } return(deposits - *spentp); } if ( ramchain->Uextras == 0 || (rdata= ramchain->H.data) == 0 ) { if ( ramchain->height < (coin->bundlescount-1)*coin->chain->bundlesize ) { - //printf("iguana_pkhashbalance.[%d] %d: unexpected null spents.%p or rdata.%p\n",ramchain->height,(coin->bundlescount-1)*coin->chain->bundlesize,ramchain->Uextras,rdata); - } else iguana_volatilesalloc(coin,ramchain,0); - return(0); + printf("iguana_pkhashbalance.[%d] %d: unexpected null spents.%p or rdata.%p\n",ramchain->height,(coin->bundlescount-1)*coin->chain->bundlesize,ramchain->Uextras,rdata); + } + iguana_volatilesmap(myinfo,coin,ramchain); + if ( ramchain->Uextras == 0 || (rdata= ramchain->H.data) == 0 ) + { + printf("couldnt map ramchain %d\n",ramchain->height); + return(0); + } } unspentind = lastpt.unspentind; U = RAMCHAIN_PTR(rdata,Uoffset); @@ -500,14 +556,13 @@ int64_t iguana_RTpkhashbalance(struct supernet_info *myinfo,struct iguana_info * uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]); if ( lastheight <= 0 || uheight < lastheight ) { + //printf("u%u ",unspentind); deposits += U[unspentind].value; - memset(&outpt,0,sizeof(outpt)); - outpt.hdrsi = lastpt.hdrsi; - outpt.isptr = 0; - outpt.unspentind = unspentind; - outpt.value = U[unspentind].value; + txid = T[U[unspentind].txidind].txid; + vout = unspentind - T[U[unspentind].txidind].firstvout; + iguana_outpt_set(coin,&outpt,&U[unspentind],unspentind,lastpt.hdrsi,txid,vout,p->rmd160,pubkey33); RTspend = 0; - if ( iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,ramchain,outpt,lastheight,minconf,maxconf,U[unspentind].value) == 0 ) + if ( iguana_markedunspents_find(coin,&firstslot,txid,vout) < 0 && iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,ramchain,outpt,lastheight,minconf,maxconf,U[unspentind].value) == 0 ) { if ( *nump < max && unspents != 0 ) unspents[*nump] = outpt; @@ -544,18 +599,21 @@ int64_t iguana_RTpkhashbalance(struct supernet_info *myinfo,struct iguana_info * } unspentind = U2[unspentind].prevunspentind; } - if ( 0 && llabs(spent - checkval - RTspend) > SMALLVAL ) + if ( (0) && llabs((int64_t)spent - (int64_t)checkval - (int64_t)RTspend) > SMALLVAL ) printf("spend %s: [%d] deposits %.8f spent %.8f check %.8f (%.8f) vs A2[%u] %.8f\n",lastheight==IGUANA_MAXHEIGHT?"checkerr":"",lastpt.hdrsi,dstr(deposits),dstr(spent),dstr(checkval)+dstr(RTspend),dstr(*spentp),pkind,dstr(A2[pkind].total)); } (*spentp) = spent; - //printf("(%s) spent %.8f, RTspent %.8f deposits %.8f\n",coinaddr,dstr(spent),dstr(RTspend),dstr(deposits)); + //printf("[%d] (%s) spent %.8f, RTspent %.8f deposits %.8f\n",ramchain->height/coin->chain->bundlesize,coinaddr,dstr(spent),dstr(RTspend),dstr(deposits)); return(deposits - spent); } +// jl777: todo support notarychain iterate listunspent int32_t iguana_RTpkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,int32_t maxunspents,char *remoteaddr,int32_t includespent) { - int32_t i,n,m,numunspents; int64_t spent,deposits,netbalance,total; struct iguana_outpoint lastpt; struct iguana_pkhash *p,_p; struct iguana_ramchain *ramchain; struct iguana_bundle *bp; - if ( 0 && coin->RTramchain_busy != 0 ) + int32_t i,n,m,numunspents; uint64_t spent,deposits,netbalance,total; struct iguana_outpoint lastpt; struct iguana_pkhash *p,_p; struct iguana_ramchain *ramchain; struct iguana_bundle *bp; + if ( coin->RTheight == 0 ) + return(-1); + if ( (0) && coin->RTramchain_busy != 0 ) { printf("iguana_pkhasharray: unexpected access when RTramchain_busy\n"); return(-1); @@ -566,12 +624,12 @@ int32_t iguana_RTpkhasharray(struct supernet_info *myinfo,struct iguana_info *co if ( max > coin->bundlescount ) max = coin->bundlescount; //printf("minconf.%d maxconf.%d max.%d addr.%s last.%d maxunspents.%d\n",minconf,maxconf,max,coinaddr,lastheight,maxunspents); - for (total=n=i=0; i=coin->RTheight); i++) + for (total=n=i=0; i=coin->firstRTheight); i++) { + bp = 0; if ( i != max && (bp= coin->bundles[i]) == 0 ) continue; - else bp = 0; - if ( 0 && bp != 0 ) + if ( bp != 0 ) { if ( lastheight > 0 && bp->bundleheight > lastheight ) { @@ -595,7 +653,7 @@ int32_t iguana_RTpkhasharray(struct supernet_info *myinfo,struct iguana_info *co p = (P == 0) ? &_p : &P[n]; if ( (netbalance= iguana_RTpkhashbalance(myinfo,coin,array,&spent,unspents != 0 ? &unspents[numunspents] : 0,&m,ramchain,p,lastpt,rmd160,coinaddr,pubkey33,lastheight,minconf,maxconf,remoteaddr,includespent)) != deposits-spent && lastheight == IGUANA_MAXHEIGHT && minconf == 1 && maxconf > coin->blocks.hwmchain.height ) { - printf("pkhash balance mismatch from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",m,dstr(netbalance),dstr(deposits),dstr(spent),dstr(deposits)-dstr(spent)); + printf("%s pkhash balance mismatch from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",coin->symbol,m,dstr(netbalance),dstr(deposits),dstr(spent),dstr(deposits)-dstr(spent)); } else { @@ -620,11 +678,11 @@ int32_t iguana_RTpkhasharray(struct supernet_info *myinfo,struct iguana_info *co return(n); } -int64_t iguana_RTunspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,char *remoteaddr,int32_t includespent) +uint64_t iguana_RTunspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,char *remoteaddr,int32_t includespent) { - uint64_t total=0,sum=0; struct iguana_pkhash *P; uint8_t *addrtypes,*pubkeys; int32_t i,numunspents,maxunspents,flag = 0; char coinaddr[64]; + uint64_t total=0,sum=0; struct iguana_pkhash *P; uint8_t *addrtypes,*pubkeys; int32_t i,j,numunspents,maxunspents,flag = 0; char coinaddr[64]; //portable_mutex_lock(&coin->RTmutex); - while ( 0 && coin->RTramchain_busy != 0 ) + while ( (0) && coin->RTramchain_busy != 0 ) { fprintf(stderr,"iguana_pkhasharray: %s unexpected access when RTramchain_busy\n",coin->symbol); sleep(1); @@ -639,9 +697,14 @@ int64_t iguana_RTunspents(struct supernet_info *myinfo,struct iguana_info *coin, P = calloc(coin->bundlescount,sizeof(*P)); for (i=0; ibundlescount,&rmdarray[i * 20],coinaddr,&pubkeys[33*i],lastheight,&unspents[numunspents],numunspentsp,maxunspents,remoteaddr,includespent); + iguana_RTpkhasharray(myinfo,coin,array,minconf,maxconf,&total,P,coin->bundlescount,&rmdarray[i * 20],coinaddr,&pubkeys[33*i],lastheight,unspents != 0 ? &unspents[numunspents] : 0,numunspentsp,maxunspents,remoteaddr,includespent); //printf("iguana_unspents: i.%d of %d: %s %.8f numunspents.%d\n",i,numrmds,coinaddr,dstr(total),*numunspentsp); maxunspents -= *numunspentsp; numunspents += *numunspentsp; @@ -659,7 +722,7 @@ int64_t iguana_RTunspents(struct supernet_info *myinfo,struct iguana_info *coin, uint8_t *iguana_rmdarray(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti) { - int32_t i,n,flag=0,j=0; char *coinaddr,rmdstr[41]; uint8_t *addrtypes,*rmdarray = 0; + int32_t i,n,flag=0,k,j=0; char *coinaddr,rmdstr[41]; uint8_t addrtype,*addrtypes,*rmdarray = 0; *numrmdsp = 0; if ( array == 0 || cJSON_GetArraySize(array) == 0 ) array = iguana_getaddressesbyaccount(myinfo,coin,"*"); @@ -672,9 +735,19 @@ uint8_t *iguana_rmdarray(struct supernet_info *myinfo,struct iguana_info *coin,i { if ( (coinaddr= jstr(jitem(array,i),0)) != 0 ) { + //printf("(%s %s) ",coinaddr,rmdstr); + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) + { + printf("i.%d illegal coinaddr.(%s) longest.%d\n",i,coinaddr,coin->longestchain); + continue; + } bitcoin_addr2rmd160(&addrtypes[j],&rmdarray[20 * j],coinaddr); + for (k=0; k<20; k++) + if ( rmdarray[20 * j + k] != 0 ) + break; + if ( k == 20 ) + continue; init_hexbytes_noT(rmdstr,&rmdarray[20 * j],20); - //printf("(%s %s) ",coinaddr,rmdstr); j++; } } @@ -685,9 +758,9 @@ uint8_t *iguana_rmdarray(struct supernet_info *myinfo,struct iguana_info *coin,i return(rmdarray); } -int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_pkhash **Ptrp,int64_t *supplyp,int32_t *numacctsp,int32_t *nonzp,int32_t *errsp,int32_t lastheight) +uint64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_pkhash **Ptrp,uint64_t *supplyp,int32_t *numacctsp,int32_t *nonzp,int32_t *errsp,int32_t lastheight) { - int64_t balance,total,supply,*weights=0; uint32_t pkind; int32_t numrmds,minconf,neg,numunspents,nonz,num=0; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; struct iguana_pkhash *refP; uint8_t rmd160[20],*rmdarray; cJSON *array; char coinaddr[64]; //struct iguana_account *A2; struct iguana_utxo *U2; + uint64_t balance,total,supply,*weights=0; uint32_t pkind; int32_t j,numrmds,minconf,neg,numunspents,nonz,num=0; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; struct iguana_pkhash *refP; uint8_t rmd160[20],*rmdarray; cJSON *array; char coinaddr[64]; //struct iguana_account *A2; struct iguana_utxo *U2; *supplyp = 0; *numacctsp = *nonzp = 0; *errsp = 1; @@ -705,6 +778,11 @@ int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coi { total = 0; memcpy(rmd160,refP[pkind].rmd160,sizeof(rmd160)); + for (j=0; j<20; j++) + if ( rmd160[j] != 0 ) + break; + if ( j == 20 ) + continue; array = cJSON_CreateArray(); bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,sizeof(rmd160)); jaddistr(array,coinaddr); @@ -728,7 +806,7 @@ int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coi if ( weights[pkind] != 0 ) { nonz++; - if ( weights[pkind] < 0 ) + if ( weights[pkind] != 0 ) neg++, weights[pkind] = 0; else supply += weights[pkind]; } @@ -740,7 +818,7 @@ int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coi return(weights); } -bits256 iguana_staker_hash2(bits256 refhash2,uint8_t *refrmd160,uint8_t *rmd160,int64_t weight) +bits256 iguana_staker_hash2(bits256 refhash2,uint8_t *refrmd160,uint8_t *rmd160,uint64_t weight) { bits256 hash2; vcalc_sha256cat(hash2.bytes,refhash2.bytes,sizeof(refhash2),rmd160,20); @@ -756,7 +834,7 @@ int _cmp_hashes(const void *a,const void *b) #undef hashb } -int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *refrmd160,struct iguana_pkhash *refP,int64_t *weights,int32_t numweights,bits256 *sortbuf) +int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *refrmd160,struct iguana_pkhash *refP,uint64_t *weights,int32_t numweights,bits256 *sortbuf) { int32_t i,j,n = 0; bits256 ind,refhash2 = *hash2p; memset(sortbuf,0,sizeof(*sortbuf) * 2 * numweights); @@ -786,92 +864,158 @@ int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *ref return((int32_t)sortbuf[1].uints[5]); } -int32_t iguana_RTunspent_check(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt) +int32_t iguana_markedunspents_find(struct iguana_info *coin,int32_t *firstslotp,bits256 txid,int32_t vout) { - bits256 txid; int32_t vout,spentheight; - memset(&txid,0,sizeof(txid)); - if ( iguana_RTunspentind2txid(myinfo,coin,&spentheight,&txid,&vout,outpt) == 0 ) + int32_t i; + *firstslotp = -1; + if ( bits256_nonz(txid) != 0 && vout >= 0 ) { - //char str[65]; printf("verify %s/v%d is not already used\n",bits256_str(str,txid),vout); - if ( basilisk_addspend(myinfo,coin->symbol,txid,vout,0) != 0 ) + txid.ushorts[15] = vout; // small chance of collision ok due to small timeframe + for (i=0; imarkedunspents)/sizeof(*coin->markedunspents); i++) { - char str[65]; printf("iguana_unspent_check found unspentind (%u %d) %s\n",outpt.hdrsi,outpt.unspentind,bits256_str(str,txid)); - return(1); - } else return(0); + if ( *firstslotp < 0 && bits256_nonz(coin->markedunspents[i]) == 0 ) + *firstslotp = i; + if ( bits256_cmp(txid,coin->markedunspents[i]) == 0 ) + { + //printf("%s.v%d marked in slot.[%d]\n",bits256_str(str,txid),vout,i); + return(i); + } + } + } + if ( *firstslotp < 0 ) + { + for (i=0; imarkedunspents)/sizeof(*coin->markedunspents); i++) + if ( bits256_nonz(coin->markedunspents[i]) == 0 ) + { + *firstslotp = i; + break; + } } - printf("iguana_unspent_check: couldnt find (%d %d)\n",outpt.hdrsi,outpt.unspentind); + //printf("%s.v%d not marked\n",bits256_str(str,txid),vout); + if ( *firstslotp < 0 ) + *firstslotp = (rand() % (sizeof(coin->markedunspents)/sizeof(*coin->markedunspents))); return(-1); } -int32_t iguana_RTaddr_unspents(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *sump,struct iguana_outpoint *unspents,int32_t max,char *coinaddr,char *remoteaddr,int32_t lastheight,int32_t includespent) +void iguana_unspents_mark(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) { - int32_t n,k,numunspents,minconf = 0; uint64_t total; uint8_t rmd160[20],pubkey[65],addrtype; - total = 0; - n = numunspents = 0; - bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); - iguana_RTpkhasharray(myinfo,coin,0,minconf,coin->longestchain,&total,0,coin->bundlescount,rmd160,coinaddr,pubkey,lastheight,unspents,&n,max-1000,remoteaddr,includespent); - numunspents = n; - for (k=0; k 0 ) + { + for (i=0; i= 0 ) + { + if ( iguana_markedunspents_find(coin,&firstslot,txid,vout) < 0 ) + { + if ( firstslot >= 0 ) + { + printf("slot.[%d] <- %s/v%d\n",firstslot,bits256_str(str,txid),vout); + coin->markedunspents[firstslot] = txid; + coin->markedunspents[firstslot].ushorts[15] = vout; + if ( (0) && coin->utxofp == 0 ) + { + sprintf(fname,"%s/%s/utxo.dat",GLOBAL_DBDIR,coin->symbol), OS_compatible_path(fname); + if ( (coin->utxofp= fopen(fname,"rb+")) == 0 ) + coin->utxofp = fopen(fname,"wb"); + else fseek(coin->utxofp,0,SEEK_END); + if ( coin->utxofp != 0 ) + { + fwrite(txid.bytes,1,sizeof(txid),coin->utxofp); + fwrite(&vout,1,sizeof(vout),coin->utxofp); + fflush(coin->utxofp); + } + } + } + } else printf("error firstslot.[%d] <- %s/v%d\n",firstslot,bits256_str(str,txid),vout); + } + } + } } -int32_t iguana_RTunspentslists(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *totalp,struct iguana_outpoint *unspents,int32_t max,uint64_t required,int32_t minconf,cJSON *addresses,char *remoteaddr) +void iguana_unspents_markinit(struct supernet_info *myinfo,struct iguana_info *coin) { - uint64_t sum = 0; int32_t k,i,j,r,numunspents,numaddrs; uint8_t pubkey[65]; char *coinaddr,str[65]; struct iguana_waddress *waddr; struct iguana_waccount *wacct; struct basilisk_unspent *bu; struct iguana_outpoint outpt; - *totalp = 0; - if ( (numaddrs= cJSON_GetArraySize(addresses)) == 0 ) - { - printf("null addresses.(%s)\n",jprint(addresses,0)); - return(0); - } - memset(pubkey,0,sizeof(pubkey)); - //remains = required * 1.1 + coin->txfee; - for (i=numunspents=0; isymbol), OS_compatible_path(fname); + if ( (fp= fopen(fname,"rb")) != 0 ) { - if ( (coinaddr= jstri(addresses,i)) != 0 ) + while ( fread(&filetxid,1,sizeof(filetxid),fp) == sizeof(filetxid) && fread(&filevout,1,sizeof(filevout),fp) == sizeof(filevout) ) { - //printf("i.%d coinaddr.(%s) minconf.%d longest.%d diff.%d\n",i,coinaddr,minconf,coin->longestchain,coin->blocks.hwmchain.height - minconf); - if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + if ( iguana_markedunspents_find(coin,&firstslot,filetxid,filevout) < 0 ) { - numunspents += iguana_RTaddr_unspents(myinfo,coin,&sum,&unspents[numunspents],max-numunspents,coinaddr,remoteaddr,coin->blocks.hwmchain.height - minconf,0); + if ( firstslot >= 0 ) + { + //char str[65]; printf("%s slot.[%d] <- %s/v%d\n",fname,firstslot,bits256_str(str,filetxid),filevout); + coin->markedunspents[firstslot] = filetxid; + coin->markedunspents[firstslot].ushorts[15] = filevout; + } } - else + } + fclose(fp); + } + sprintf(fname,"%s/%s/utxo.json",GLOBAL_DBDIR,coin->symbol), OS_compatible_path(fname); + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (array= cJSON_Parse(filestr)) != 0 ) + { + printf("iguana_unspents_markinit.(%s)\n",fname); + if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { - if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 && waddr->numunspents > 0 ) + for (i=0; inumunspents); - for (j=0; jnumunspents; j++) + item = jitem(array,i); + filetxid = jbits256i(item,0); + filevout = jinti(item,1); + char str[65]; printf("[%d] %s %d\n",i,bits256_str(str,filetxid),filevout); + if ( iguana_markedunspents_find(coin,&firstslot,filetxid,filevout) < 0 ) { - i = ((j + r) % waddr->numunspents); - bu = &waddr->unspents[i]; - if ( basilisk_addspend(myinfo,coin->symbol,bu->txid,bu->vout,0) == 0 ) + if ( firstslot >= 0 ) { - for (k=0; khdrsi; - outpt.isptr = 0; - outpt.unspentind = bu->unspentind; - outpt.value = bu->value; - *unspents = outpt; - sum += bu->value; - printf("ADD unspent, mark spent\n"); - basilisk_addspend(myinfo,coin->symbol,bu->txid,bu->vout,1); - unspents++; - numunspents++; - } else printf("skip pending txid.%s/v%d\n",bits256_str(str,bu->txid),bu->vout); + //char str[65]; printf("slot.[%d] <- %s/v%d\n",firstslot,bits256_str(str,filetxid),filevout); + coin->markedunspents[firstslot] = filetxid; + coin->markedunspents[firstslot].ushorts[15] = filevout; + } } } } - if ( numunspents > max || sum > required ) - break; - //printf("n.%d max.%d total %.8f\n",n,max,dstr(total)); - } + free_json(array); + } else printf("parse error.(%s)\n",filestr); + free(filestr); + } else printf("couldnt open.(%s)\n",fname); +} + +int32_t iguana_RTunspent_check(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt) +{ + int32_t firstslot; + if ( iguana_markedunspents_find(coin,&firstslot,outpt.txid,outpt.vout) < 0 ) + return(0); + return(-1); +} + +int32_t iguana_RTaddr_unspents(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *sump,struct iguana_outpoint *unspents,int32_t max,char *coinaddr,char *remoteaddr,int32_t lastheight,int32_t includespent) +{ + int32_t n,j,k,numunspents,minconf = 0; uint64_t total; uint8_t rmd160[20],pubkey[65],addrtype; + total = 0; + n = numunspents = 0; + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) + { + printf("illegal coinaddr.(%s) minconf.%d longest.%d diff.%d\n",coinaddr,minconf,coin->longestchain,coin->blocks.hwmchain.height - minconf); + return(0); } - *totalp = sum; + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + for (j=0; j<20; j++) + if ( rmd160[j] != 0 ) + break; + if ( j == 20 ) + return(0); + iguana_RTpkhasharray(myinfo,coin,0,minconf,coin->longestchain,&total,0,coin->bundlescount,rmd160,coinaddr,pubkey,lastheight,unspents,&n,max-1000,remoteaddr,includespent); + numunspents = n; + for (k=0; kbundles[outpt.hdrsi]) == 0 ) return(-1); ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; @@ -926,20 +1070,103 @@ uint64_t iguana_unspentavail(struct supernet_info *myinfo,struct iguana_info *co } else { - printf("%s illegal unspentind.%u vs %u [%d]\n",coin->symbol,outpt.unspentind,rdata->numunspents,bp->hdrsi); + printf("%s illegal unspentind.%u [%d] vs %u [%d]\n",coin->symbol,outpt.unspentind,outpt.hdrsi,rdata->numunspents,bp->hdrsi); return(-2); } } else return(0); } -cJSON *iguana_RTlistunspent(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *argarray,int32_t minconf,int32_t maxconf,char *remoteaddr) +int32_t iguana_unspentfindjson(cJSON *destarray,cJSON *item) { - int32_t numrmds,numunspents=0; uint8_t *rmdarray; cJSON *retjson = cJSON_CreateArray(); - rmdarray = iguana_rmdarray(myinfo,coin,&numrmds,argarray,0); - iguana_RTunspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds,(1 << 30),0,&numunspents,remoteaddr,0); - if ( rmdarray != 0 ) - free(rmdarray); + cJSON *destitem; int32_t i,n; + if ( (n= cJSON_GetArraySize(destarray)) > 0 ) + { + for (i=0; iFULLNODE > 0 || coin->VALIDATENODE > 0 || coin->notarychain >= 0 ) + { + retjson = cJSON_CreateArray(); + rmdarray = iguana_rmdarray(myinfo,coin,&numrmds,argarray,0); + total = iguana_RTunspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds,(1 << 30),0,&numunspents,remoteaddr,includespends); + if ( rmdarray != 0 ) + free(rmdarray); + } + else + { + basilisk_unspents_update(myinfo,coin); + portable_mutex_lock(&myinfo->bu_mutex); + if ( (unspents= myinfo->Cunspents) != 0 && (array= jobj(unspents,coin->symbol)) != 0 ) + unspents = jduplicate(array); + portable_mutex_unlock(&myinfo->bu_mutex); + retjson = cJSON_CreateArray(); + if ( unspents != 0 ) + { + if ( (n= cJSON_GetArraySize(unspents)) > 0 && (m= cJSON_GetArraySize(argarray)) > 0 ) + { + for (i=0; i 0 ) + { + memset(hash.bytes,0,sizeof(hash)); + vals = cJSON_CreateObject(); + jaddstr(vals,"coin",coin->symbol); + jaddnum(vals,"history",1); + jaddnum(vals,"firstheight",0); + jaddnum(vals,"fanout",MAX(8,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + jaddnum(vals,"numrequired",MIN(4,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + jadd(vals,"addresses",jduplicate(argarray)); + if ( (retstr= basilisk_standardservice("BAL",myinfo,0,hash,vals,"",1)) != 0 ) + { + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retarray)) > 0 ) + { + for (i=0; itxfee; + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 || (coin->FULLNODE == 0 && coin->notarychain >= 0) ) + { + for (i=numunspents=0; iFULLNODE == 0 && coin->VALIDATENODE == 0 ) + { + if ( (array= iguana_RTlistunspent(myinfo,coin,addresses,minconf,1<<30,remoteaddr,0)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i= 0 ) + continue; + if ( (spendscriptstr= jstr(item,"scriptPubKey")) == 0 ) + { + printf("no spendscriptstr.(%s)\n",jprint(item,0)); + continue; + } + iguana_outptset(myinfo,coin,&outpt,jbits256(item,"txid"),jint(item,"vout"),jdouble(item,"amount") * SATOSHIDEN,spendscriptstr); + *unspents = outpt; + sum += outpt.value; + //printf("ITEM.(%s) %.8f\n",jprint(item,0),dstr(outpt.value)); + unspents++; + numunspents++; + if ( numunspents >= max )//|| sum > 10*required ) + break; + } + } + free_json(array); + } + } + else + { + for (i=numunspents=0; i 0 ) + { + for (i=0; i= max )//|| sum > 10*required ) + break; + } + } + if ( numunspents == 0 ) + printf("no unspents.(%s)\n",jprint(array,0)); + free_json(array); + } + } + } + } + *totalp = sum; + coinaddr = addresses != 0 ? jstri(addresses,i) : ""; + printf("numunspents.%d max.%d sum %.8f required %.8f (%s)\n",numunspents,max,dstr(sum),dstr(required),coinaddr); + return(numunspents); +} + #define UTXOADDR_ITEMSIZE 32 #define iguana_utxotable_numinds(ind) (((ind) == 0xffff) ? coin->utxoaddrlastcount : (coin->utxoaddroffsets[(ind) + 1] - coin->utxoaddroffsets[ind])) @@ -969,10 +1291,13 @@ int32_t iguana_rwutxoaddr(int32_t rwflag,uint16_t ind,uint8_t *serialized,struct } else memcpy(&serialized[2],&utxoaddr->rmd160[2],18); len += 18; if ( rwflag != 0 ) - pkind = utxoaddr->pkind; + pkind = (utxoaddr->pkind & 0x7fffffff) | (utxoaddr->p2sh << 31); len += iguana_rwnum(rwflag,&serialized[20],sizeof(pkind),&pkind); if ( rwflag == 0 ) - utxoaddr->pkind = pkind; + { + utxoaddr->pkind = pkind & 0x7fffffff; + utxoaddr->p2sh = (pkind >> 31); + } len += iguana_rwnum(rwflag,&serialized[24],sizeof(utxoaddr->histbalance),&utxoaddr->histbalance); return(len); } @@ -996,7 +1321,7 @@ uint64_t iguana_utxoaddrtablefind(struct iguana_info *coin,int16_t search_hdrsi, return(0); } -struct iguana_utxoaddr *iguana_utxoaddrfind(int32_t createflag,struct iguana_info *coin,int16_t hdrsi,uint32_t pkind,uint8_t rmd160[20],struct iguana_utxoaddr **prevp) +struct iguana_utxoaddr *iguana_utxoaddrfind(int32_t createflag,struct iguana_info *coin,int16_t hdrsi,uint32_t pkind,uint8_t rmd160[20],struct iguana_utxoaddr **prevp,int32_t p2shflag) { struct iguana_utxoaddr *utxoaddr; char coinaddr[64]; HASH_FIND(hh,coin->utxoaddrs,rmd160,sizeof(utxoaddr->rmd160),utxoaddr); @@ -1005,6 +1330,12 @@ struct iguana_utxoaddr *iguana_utxoaddrfind(int32_t createflag,struct iguana_inf utxoaddr = calloc(1,sizeof(*utxoaddr)); ++coin->utxoaddrind; utxoaddr->hdrsi = hdrsi; + if ( (utxoaddr->p2sh= p2shflag) != 0 ) + { + char coinaddr[64]; + bitcoin_address(coinaddr,coin->chain->p2shtype,rmd160,20); + //printf("P2SH type.(%s)\n",coinaddr); + } utxoaddr->pkind = pkind; if ( coin->utxoaddrtable != 0 && coin->utxoaddroffsets != 0 ) { @@ -1035,7 +1366,7 @@ struct iguana_utxoaddr *iguana_utxoaddrfind(int32_t createflag,struct iguana_inf uint64_t iguana_bundle_unspents(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_utxoaddr **prevp) { - struct iguana_utxoaddr *utxoaddr; uint32_t unspentind,pkind; struct iguana_ramchaindata *rdata=0; struct iguana_pkhash *P; struct iguana_unspent *U; struct iguana_utxo *U2=0; uint64_t value,balance = 0; + struct iguana_utxoaddr *utxoaddr; int32_t p2shflag; uint32_t unspentind,pkind; struct iguana_ramchaindata *rdata=0; struct iguana_pkhash *P; struct iguana_unspent *U; struct iguana_utxo *U2=0; uint64_t value,balance = 0; if ( bp == 0 || (rdata= bp->ramchain.H.data) == 0 || (U2= bp->ramchain.Uextras) == 0 ) { printf("missing ptr bp.%p rdata.%p U2.%p\n",bp,rdata,U2); @@ -1056,7 +1387,18 @@ uint64_t iguana_bundle_unspents(struct iguana_info *coin,struct iguana_bundle *b balance += value; if ( (pkind= U[unspentind].pkind) < rdata->numpkinds && pkind > 0 ) { - if ( (utxoaddr= iguana_utxoaddrfind(1,coin,bp->hdrsi,pkind,P[pkind].rmd160,prevp)) != 0 ) + p2shflag = 0; + //if ( (p2shflag= (iguana_addrtype(coin,U[unspentind].type) == coin->chain->p2shtype)) != 0 ) + { + char coinaddr[64]; + bitcoin_address(coinaddr,coin->chain->p2shtype,P[pkind].rmd160,20); + if ( U[unspentind].type != IGUANA_SCRIPT_76A988AC && U[unspentind].type != IGUANA_SCRIPT_AC && U[unspentind].type != IGUANA_SCRIPT_76AC ) + { + p2shflag = 1; + //printf("%s %.8f P2SH.%d\n",coinaddr,dstr(value),U[unspentind].type); + } + } + if ( (utxoaddr= iguana_utxoaddrfind(1,coin,bp->hdrsi,pkind,P[pkind].rmd160,prevp,p2shflag)) != 0 ) { //printf("%.8f ",dstr(value)); utxoaddr->histbalance += value; @@ -1126,7 +1468,11 @@ int32_t iguana_utxoaddr_map(struct iguana_info *coin,char *fname) memcpy(&last,(void *)((long)coin->utxoaddrfileptr+sizeof(uint64_t)),sizeof(last)); memcpy(&coin->utxoaddrind,(void *)((long)coin->utxoaddrfileptr+sizeof(uint64_t)+sizeof(uint32_t)),sizeof(coin->utxoaddrind)); memcpy(&coin->utxoaddrhash.bytes,(void *)((long)coin->utxoaddrfileptr+sizeof(uint64_t)+2*sizeof(uint32_t)),sizeof(coin->utxoaddrhash)); +#if defined(_M_X64) + coin->utxoaddroffsets = (void *)((unsigned char *)coin->utxoaddrfileptr + sizeof(uint64_t) + 2 * sizeof(uint32_t) + sizeof(bits256)); +#else coin->utxoaddroffsets = (void *)((long)coin->utxoaddrfileptr + sizeof(uint64_t) + 2*sizeof(uint32_t) + sizeof(bits256)); +#endif for (ind=total=count=0; ind<0x10000; ind++) { if ( (offset= coin->utxoaddroffsets[ind]) != 0 ) @@ -1188,22 +1534,28 @@ void iguana_utxoaddr_purge(struct iguana_info *coin) int32_t iguana_utxoaddr_check(struct supernet_info *myinfo,struct iguana_info *coin,int32_t lastheight,struct iguana_outpoint *unspents,int32_t max,struct iguana_utxoaddr *utxoaddr) { - static int32_t good,bad; - char coinaddr[64]; uint64_t sum,checkbalance; int32_t iter,i,numunspents = 0; + static int32_t good,bad; static uint64_t total; + char coinaddr[64]; uint64_t sum,checkbalance; int32_t i,flag=0,numunspents = 0; sum = 0; - for (iter=0; iter<2; iter++) + bitcoin_address(coinaddr,utxoaddr->p2sh == 0 ? coin->chain->pubtype : coin->chain->p2shtype,utxoaddr->rmd160,sizeof(utxoaddr->rmd160)); + numunspents += iguana_RTaddr_unspents(myinfo,coin,&sum,&unspents[numunspents],max-numunspents,coinaddr,0,lastheight,0); + if ( (0) && utxoaddr->histbalance != 0 && strcmp(coin->symbol,"BTCD") == 0 ) { - bitcoin_address(coinaddr,iter == 0 ? coin->chain->pubtype : coin->chain->p2shtype,utxoaddr->rmd160,sizeof(utxoaddr->rmd160)); - numunspents += iguana_RTaddr_unspents(myinfo,coin,&sum,&unspents[numunspents],max-numunspents,coinaddr,0,lastheight,0); - if ( sum == utxoaddr->histbalance ) - { - checkbalance = iguana_utxoaddrtablefind(coin,0,0,utxoaddr->rmd160); - if ( checkbalance != sum ) - printf("%s checkbalance %.8f vs sum %.8f\n",coinaddr,dstr(checkbalance),dstr(sum)); - break; - } + total += utxoaddr->histbalance; + //printf("fiat/revs sendtoaddress %s %.8f # total %.8f\n",coinaddr,dstr(utxoaddr->histbalance),dstr(total)); + printf("fiat/revs sendtoaddress %s %.8f\n",coinaddr,dstr(utxoaddr->histbalance)); + if ( total/SATOSHIDEN > 1308000 ) + printf("error: total %.8f\n",dstr(total)); } - if ( sum != utxoaddr->histbalance || checkbalance != sum ) + if ( sum == utxoaddr->histbalance ) + { + checkbalance = iguana_utxoaddrtablefind(coin,0,0,utxoaddr->rmd160); + if ( checkbalance != sum ) + printf("%s checkbalance %.8f vs sum %.8f\n",coinaddr,dstr(checkbalance),dstr(sum)); + flag = 1; + //break; + } + if ( (0) && flag == 0 )//sum != utxoaddr->histbalance || checkbalance != sum ) { bad++; for (i=0; irmd160[i]); bitcoin_address(coinaddr,coin->chain->pubtype,utxoaddr->rmd160,sizeof(utxoaddr->rmd160)); - printf(" %s: sum %.8f != %.8f numunspents.%d diff %.8f\n",coinaddr,dstr(sum),dstr(utxoaddr->histbalance),numunspents,dstr(utxoaddr->histbalance)-dstr(sum)); + printf(" %s: sum %.8f != %.8f %.8f numunspents.%d diff %.8f\n",coinaddr,dstr(sum),dstr(utxoaddr->histbalance),dstr(checkbalance),numunspents,dstr(utxoaddr->histbalance)-dstr(sum)); return(-1); } good++; @@ -1233,10 +1585,10 @@ int32_t iguana_utxoaddr_validate(struct supernet_info *myinfo,struct iguana_info { iguana_volatilespurge(coin,&bp->ramchain); /*sprintf(fname,"%s/%s/accounts/debits.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); - OS_removefile(fname,0); - sprintf(fname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); - OS_removefile(fname,0);*/ - iguana_volatilesmap(coin,&bp->ramchain); + OS_removefile(fname,0); + sprintf(fname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); + OS_removefile(fname,0);*/ + iguana_volatilesmap(myinfo,coin,&bp->ramchain); } total = 0; max = 1024 * 1024 * 1024; @@ -1273,7 +1625,7 @@ uint64_t iguana_RTstart(struct supernet_info *myinfo,struct iguana_info *coin,in uint64_t iguana_utxoaddr_gen(struct supernet_info *myinfo,struct iguana_info *coin,int32_t maxheight) { - char fname[1024],fname2[1024],coinaddr[64],str[65],checkaddr[64]; struct iguana_utxoaddr *utxoaddr,UA,*tmp,*last=0; uint16_t hdrsi; uint8_t *table,item[UTXOADDR_ITEMSIZE]; uint32_t *counts,*offsets,offset,n; int32_t total,errs=0,height=0,j,k,ind,tablesize=0; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata=0; uint64_t checkbalance=0,balance = 0; + char fname[1024],fname2[1024],coinaddr[64],str[65],checkaddr[64]; struct iguana_utxoaddr *utxoaddr,UA,*tmp,*last=0; uint16_t hdrsi; uint8_t *table,item[UTXOADDR_ITEMSIZE]; uint32_t *counts,*offsets,offset,n; int32_t total,errs=0,height=0,ind,tablesize=0; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata=0; uint64_t checkbalance=0,balance = 0; for (hdrsi=0; hdrsibundlescount-1; hdrsi++) { if ( (bp= coin->bundles[hdrsi]) != 0 && bp->bundleheight < maxheight ) @@ -1282,7 +1634,7 @@ uint64_t iguana_utxoaddr_gen(struct supernet_info *myinfo,struct iguana_info *co sprintf(fname2,"%s/%s/utxoaddrs.%d",GLOBAL_DBDIR,coin->symbol,height), OS_portable_path(fname2); if ( iguana_utxoaddr_map(coin,fname2) != 0 ) { - if ( 0 && strcmp("BTC",coin->symbol) != 0 ) + if ( (0) && strcmp("BTCD",coin->symbol) == 0 ) errs = iguana_utxoaddr_validate(myinfo,coin,height); printf("nogen %s HIST BALANCE %s %.8f errs %d\n",fname2,bits256_str(str,coin->utxoaddrhash),dstr(coin->histbalance),errs); if ( errs == 0 && coin->histbalance > 0 && height > 0 ) @@ -1307,9 +1659,15 @@ uint64_t iguana_utxoaddr_gen(struct supernet_info *myinfo,struct iguana_info *co { if ( (bp= coin->bundles[hdrsi]) != 0 && bp->bundleheight < maxheight ) { - balance += iguana_bundle_unspents(coin,bp,&last); - fprintf(stderr,"(%d %.8f) ",hdrsi,dstr(balance)); - height = bp->bundleheight + bp->n; + iguana_volatilespurge(coin,&bp->ramchain); + if ( iguana_volatilesmap(myinfo,coin,&bp->ramchain) != 0 ) + printf("error mapping bundle.[%d]\n",hdrsi); + else + { + balance += iguana_bundle_unspents(coin,bp,&last); + fprintf(stderr,"(%d %.8f) ",hdrsi,dstr(balance)); + height = bp->bundleheight + bp->n; + } } } sprintf(fname,"%s/%s/utxoaddrs",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); @@ -1373,15 +1731,15 @@ uint64_t iguana_utxoaddr_gen(struct supernet_info *myinfo,struct iguana_info *co if ( counts[ind] > 0 ) { qsort(&table[offsets[ind] * UTXOADDR_ITEMSIZE],counts[ind],UTXOADDR_ITEMSIZE,_utxoaddr_cmp); -continue; - for (j=0; jchain->pubtype,UA.rmd160,sizeof(UA.rmd160)); //printf(" [%4d] p%-5d %12.8f ind.%04x %d %s\n",UA.hdrsi,UA.pkind,dstr(UA.histbalance),ind,j,coinaddr); - } + }*/ } } if ( iguana_utxoaddr_save(coin,fname,balance,counts,offsets,table) == 0 ) @@ -1404,14 +1762,16 @@ continue; if ( iguana_utxoaddr_map(coin,fname) != 0 ) { printf("validating %s HIST BALANCE %s %.8f errs %d\n",fname2,bits256_str(str,coin->utxoaddrhash),dstr(coin->histbalance),errs); - errs = 0;//iguana_utxoaddr_validate(myinfo,coin,height); + errs = 0; + if ( (0) && strcmp("BTCD",coin->symbol) == 0 ) + errs = iguana_utxoaddr_validate(myinfo,coin,height); printf("gen %s HIST BALANCE %s %.8f errs %d\n",fname2,bits256_str(str,coin->utxoaddrhash),dstr(coin->histbalance),errs); if ( errs != 0 || height == 0 ) { printf("delete bad utxoaddr files\n"); OS_removefile(fname,0); OS_removefile(fname2,0); - } else return(iguana_RTstart(myinfo,coin,height)); + } else return(coin->histbalance);//iguana_RTstart(myinfo,coin,height)); } } free(counts); @@ -1436,3 +1796,151 @@ void iguana_utxoaddrs_purge(struct iguana_info *coin) } } } + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" + +STRING_AND_INT(iguana,snapshot,symbol,height) +{ + char fname[1024],coinaddr[64]; uint8_t pubtype,p2shtype; struct iguana_info *tmp; int32_t i,ind,num; cJSON *item,*array; struct iguana_utxoaddr UA; uint8_t *ptr; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + tmp = calloc(1,sizeof(*tmp)); + sprintf(fname,"%s/%s/utxoaddrs.%d",GLOBAL_DBDIR,coin->symbol,height), OS_portable_path(fname); + pubtype = coin->chain->pubtype; + p2shtype = coin->chain->p2shtype; + coin = tmp; + if ( iguana_utxoaddr_map(coin,fname) != 0 ) + { + if ( coin->utxoaddroffsets != 0 ) + { + array = cJSON_CreateArray(); + memset(&UA,0,sizeof(UA)); + for (ind=0; ind<0x10000; ind++) + { + if ( (num= iguana_utxotable_numinds(ind)) > 0 ) + { + for (i=0; iutxoaddrtable[(coin->utxoaddroffsets[ind] + i) * UTXOADDR_ITEMSIZE]; + iguana_rwutxoaddr(0,ind,ptr,&UA); + bitcoin_address(coinaddr,UA.p2sh == 0 ? pubtype : p2shtype,UA.rmd160,sizeof(UA.rmd160)); + item = cJSON_CreateObject(); + jaddnum(item,coinaddr,dstr(UA.histbalance)); + jaddi(array,item); + } + } + } + iguana_utxoaddr_purge(tmp); + free(tmp); + return(jprint(array,1)); + } + } + } + return(clonestr("{\"error\":\"couldnt find snapshot file\"}")); +} + +INT_ARRAY_STRING(iguana,dividends,height,vals,symbol) +{ + cJSON *array,*retjson,*item,*child,*exclude=0; int32_t i,j,n,execflag=0,flag,iter,numexcluded=0; char buf[1024],*retstr,*field,*prefix="",*suffix=""; uint64_t dustsum=0,excluded=0,total=0,dividend=0,value,val,emit=0,dust=0; double ratio = 1.; + if ( (retstr= iguana_snapshot(0,0,0,0,symbol,height)) != 0 ) + { + //printf("SNAPSHOT.(%s)\n",retstr); + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) != 0 ) + { + if ( vals != 0 ) + { + exclude = jarray(&numexcluded,vals,"exclude"); + dust = (uint64_t)(jdouble(vals,"dust") * SATOSHIDEN); + dividend = (uint64_t)(jdouble(vals,"dividend") * SATOSHIDEN); + if ( jstr(vals,"prefix") != 0 ) + prefix = jstr(vals,"prefix"); + if ( jstr(vals,"suffix") != 0 ) + suffix = jstr(vals,"suffix"); + execflag = jint(vals,"system"); + } + for (iter=0; iter<2; iter++) + { + for (i=0; ichild) != 0 ) + { + value = (uint64_t)(child->valuedouble * SATOSHIDEN); + if ( (field= get_cJSON_fieldname(child)) != 0 ) + { + for (j=0; j dust ) + { + sprintf(buf,"%s %s %.8f %s",prefix,field,dstr(val),suffix); + if ( execflag != 0 ) + { + if ( system(buf) != 0 ) + printf("error system.(%s)\n",buf); + } + else printf("%s\n",buf); + emit += val; + } else dustsum += val; + } + } + } + } + if ( iter == 0 ) + { + if ( total > 0 ) + { + if ( dividend == 0 ) + dividend = total; + ratio = (double)dividend / total; + } else break; + } + } + } + free_json(array); + } + free(retstr); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"coin",symbol); + jaddnum(retjson,"height",height); + jaddnum(retjson,"total",dstr(total)); + jaddnum(retjson,"excluded",dstr(excluded)); + if ( dust != 0 ) + jaddnum(retjson,"dust",dstr(dust)); + if ( dustsum != 0 ) + jaddnum(retjson,"dustsum",dstr(dustsum)); + jaddnum(retjson,"dividend",dstr(dividend)); + jaddnum(retjson,"dividends",dstr(emit)); + jaddnum(retjson,"ratio",ratio); + if ( execflag != 0 ) + jaddnum(retjson,"system",execflag); + if ( prefix[0] != 0 ) + jaddstr(retjson,"prefix",prefix); + if ( suffix[0] != 0 ) + jaddstr(retjson,"suffix",suffix); + return(jprint(retjson,1)); + } + return(clonestr("{\"error\":\"symbol not found\"}")); +} +#include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_volatiles.c b/iguana/iguana_volatiles.c index d03e592e6..b671f0012 100755 --- a/iguana/iguana_volatiles.c +++ b/iguana/iguana_volatiles.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -162,14 +162,16 @@ int32_t iguana_RTutxofunc(struct iguana_info *coin,int32_t *fromheightp,int32_t if ( (rdata= ramchain->H.data) == 0 ) return(1); val = ((uint64_t)spentpt.hdrsi << 32) | spentpt.unspentind; - if ( (utxo.fromheight= fromheight) != 0 ) - utxo.spentflag = 1; + if ( fromheight != 0 ) + utxo.fromheight = fromheight, utxo.spentflag = 1; if ( spentpt.unspentind > 0 && spentpt.unspentind < rdata->numunspents ) { if ( ramchain->Uextras != 0 ) { utxo = ramchain->Uextras[spentpt.unspentind]; - if ( lockflag != 0 ) + if ( fromheight != 0 ) + utxo.fromheight = fromheight, utxo.spentflag = 1; + if ( lockflag != 0 || fromheight != 0 ) { if ( (hhutxo= iguana_hhutxofind(coin,val)) == 0 ) { @@ -178,13 +180,20 @@ int32_t iguana_RTutxofunc(struct iguana_info *coin,int32_t *fromheightp,int32_t hhutxo->u = utxo; HASH_ADD_KEYPTR(hh,coin->utxotable,&hhutxo->uval,sizeof(hhutxo->uval),hhutxo); } - printf("iguana_utxofind: need to change to new RT lock method\n"); + //printf("iguana_utxofind: need to change to new RT lock method\n"); } } if ( ramchain->Uextras == 0 || utxo.spentflag == 0 ) { if ( (hhutxo= iguana_hhutxofind(coin,val)) != 0 ) + { utxo = hhutxo->u; + if ( fromheight != 0 ) + { + utxo.fromheight = fromheight, utxo.spentflag = 1; + hhutxo->u = utxo; + } + } //printf("iguana_utxofind: need to change to new RT method\n"); } } @@ -205,9 +214,9 @@ int32_t iguana_RTutxofunc(struct iguana_info *coin,int32_t *fromheightp,int32_t return(utxo.spentflag); } -int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,struct iguana_outpoint spentpt,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount) +int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,struct iguana_outpoint spentpt,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount) { - uint32_t numunspents; int32_t RTspentflag,spentflag,lockedflag,fromheight; uint64_t confs;//,RTspend = 0; + uint32_t numunspents; int32_t firstslot,RTspentflag,spentflag,lockedflag,fromheight=0; uint64_t confs; struct iguana_ramchaindata *rdata; struct iguana_RTunspent *unspent; *spentheightp = -1; if ( coin->disableUTXO != 0 ) @@ -219,6 +228,9 @@ int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin { if ( (unspent= spentpt.ptr) != 0 ) { + if ( unspent->parent != 0 && iguana_markedunspents_find(coin,&firstslot,unspent->parent->txid,unspent->vout) >= 0 ) + return(1); + *spentheightp = unspent->fromheight; if ( unspent->spend != 0 ) { *RTspendp += (amount == 0) ? coin->txfee : amount; @@ -278,7 +290,7 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc utxo = &spentchain->Uextras[spent_unspentind]; if ( utxo->spentflag == 0 ) { - if ( 0 && fromheight/coin->chain->bundlesize >= coin->current->hdrsi ) + if ( (0) && fromheight/coin->chain->bundlesize >= coin->current->hdrsi ) printf("iguana_volatileupdate.%d: [%d] spent.(u%u %.8f pkind.%d) fromht.%d [%d] spendind.%d\n",incremental,spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind); utxo->prevunspentind = A2[spent_pkind].lastunspentind; utxo->spendind = spendind; @@ -305,30 +317,10 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc { //double startmillis = OS_milliseconds(); static double totalmillis; static int32_t utxon; printf("hhutxo deprecated\n"); - exit(-1); - /*spentP = RAMCHAIN_PTR(rdata,Poffset); - spentU = RAMCHAIN_PTR(rdata,Uoffset); - if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight,spentP[spent_pkind].rmd160) == 0 ) - { - //totalmillis += (OS_milliseconds() - startmillis); - // if ( (++utxon % 100000) == 0 ) - // printf("ave utxo[%d] %.2f micros total %.2f seconds\n",utxon,(1000. * totalmillis)/utxon,totalmillis/1000.); - //portable_mutex_unlock(&coin->RTmutex); - return(0); - }*/ + iguana_exit(0,0); } //portable_mutex_unlock(&coin->RTmutex); printf("end iguana_volatileupdate.%d: [%d] spent.(u%u %.8f pkind.%d) double spend? at ht.%d [%d] spendind.%d (%p %p)\n",incremental,spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind,spentchain->Uextras,spentchain->A2); - /*if ( coin->current != 0 && fromheight >= coin->current->bundleheight ) - coin->RTdatabad = 1; - else - { - printf("from.%d vs current.%d\n",fromheight,coin->current->bundleheight); - iguana_bundleremove(coin,fromheight/coin->chain->bundlesize,0); - } - coin->spendvectorsaved = 0; - coin->started = 0; - coin->active = 0;*/ coin->RTdatabad = 1; if ( coin->current != 0 && spent_hdrsi != coin->current->hdrsi && spent_hdrsi != fromheight/coin->chain->bundlesize ) { @@ -346,7 +338,7 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc bp->ramchain.H.data = 0; } portable_mutex_unlock(&coin->special_mutex); - exit(-1); + iguana_exit(0,0); } } else if ( coin->spendvectorsaved > 1 ) @@ -406,9 +398,9 @@ void iguana_volatilespurge(struct iguana_info *coin,struct iguana_ramchain *ramc if ( ramchain != 0 ) { //printf("volatilespurge.[%d] (%p %p) %p %p\n",ramchain->height/coin->chain->bundlesize,ramchain->A2,ramchain->Uextras,ramchain->debitsfileptr,ramchain->lastspendsfileptr); - if ( ramchain->allocatedA2 != 0 && ramchain->A2 != 0 && ramchain->A2 != ramchain->debitsfileptr+sizeof(bits256)*2+sizeof(int32_t) ) + if ( ramchain->allocatedA2 != 0 && ramchain->A2 != 0 && (long)ramchain->A2 != (long)ramchain->debitsfileptr+sizeof(bits256)*2+sizeof(int32_t) ) free(ramchain->A2); - if ( ramchain->allocatedU2 != 0 && ramchain->Uextras != 0 && ramchain->Uextras != ramchain->lastspendsfileptr+sizeof(bits256)*2+sizeof(int32_t) ) + if ( ramchain->allocatedU2 != 0 && ramchain->Uextras != 0 && (long)ramchain->Uextras != (long)ramchain->lastspendsfileptr+sizeof(bits256)*2+sizeof(int32_t) ) free(ramchain->Uextras); ramchain->A2 = 0; ramchain->Uextras = 0; @@ -428,14 +420,17 @@ void iguana_volatilespurge(struct iguana_info *coin,struct iguana_ramchain *ramc } } -int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ramchain) +int32_t iguana_volatilesmap(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *ramchain) { int32_t iter,numhdrsi,err = -1; char fname[1024]; bits256 balancehash,allbundles; struct iguana_ramchaindata *rdata; if ( (rdata= ramchain->H.data) == 0 ) { - if ( ramchain->height > 0 ) - printf("volatilesmap.[%d] no rdata\n",ramchain->height/coin->chain->bundlesize); - return(-1); + iguana_bundleload(myinfo,coin,ramchain,coin->bundles[ramchain->height/coin->chain->bundlesize],1); + if ( (rdata= ramchain->H.data) == 0 ) + { + //printf("volatilesmap.[%d] no rdata\n",ramchain->height/coin->chain->bundlesize); + return(-1); + } } if ( ramchain->debitsfileptr != 0 && ramchain->lastspendsfileptr != 0 ) { @@ -451,7 +446,7 @@ int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ram numhdrsi = *(int32_t *)ramchain->debitsfileptr; memcpy(balancehash.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); memcpy(allbundles.bytes,(void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + sizeof(balancehash)),sizeof(allbundles)); - if ( coin->balanceswritten == 0 ) + if ( coin->balanceswritten == 0 ) { coin->balanceswritten = numhdrsi; coin->balancehash = balancehash; @@ -492,7 +487,9 @@ int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ram } else { - printf("ramchain.[%d] map error balanceswritten %d vs %d hashes %x %x\n",rdata->height,coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + static uint32_t counter; + if ( counter++ < 3 ) + printf("ramchain.[%d] map error balanceswritten %d vs %d hashes %x %x\n",rdata->height,coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); err++; OS_removefile(fname,0); } diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index a7912a569..e125aea2a 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -31,10 +31,18 @@ void scrubfree(char *sensitivestr) struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct iguana_waccount *wacct,char *coinaddr) { - struct iguana_waddress *waddr; uint8_t addrtype,rmd160[20]; + struct iguana_waddress *waddr,*tmp; uint8_t addrtype,rmd160[20]; bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); //calc_rmd160_sha256(rmd160,pubkey33,33); HASH_FIND(hh,wacct->waddr,rmd160,sizeof(rmd160),waddr); + if ( waddr == 0 ) + { + HASH_ITER(hh,wacct->waddr,waddr,tmp) + { + //printf("%s ",waddr->coinaddr); + } + //printf("not in %s\n",wacct->account); + } //if ( waddr != 0 && coin != 0 && strcmp(coin->symbol,waddr->symbol) != 0 ) // return(0); //printf("%s (%s).%d in (%s)\n",waddr==0?"couldnt find":"found",coinaddr,len,wacct->account); @@ -78,7 +86,7 @@ struct iguana_waccount *iguana_waccountcreate(struct supernet_info *myinfo,char wacct = mycalloc('w',1,sizeof(*wacct) + len); strcpy(wacct->account,account); HASH_ADD_KEYPTR(hh,myinfo->wallet,wacct->account,len,wacct); - printf("waccountcreate.(%s) -> wacct.%p\n",account,wacct); + //printf("waccountcreate.(%s) -> wacct.%p\n",account,wacct); if ( (ptr= iguana_waccountfind(myinfo,account)) != wacct ) { printf("ERROR: iguana_waccountcreate verify error %p vs %p\n",ptr,wacct); @@ -116,7 +124,7 @@ struct iguana_waddress *iguana_waddresscreate(struct supernet_info *myinfo,struc struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *addwaddr,char *redeemScript) { struct iguana_waddress *waddr,*ptr; uint8_t rmd160[20],addrtype; - printf("search for (%s)\n",addwaddr->coinaddr); + //printf("search for (%s)\n",addwaddr->coinaddr); bitcoin_addr2rmd160(&addrtype,rmd160,addwaddr->coinaddr); HASH_FIND(hh,wacct->waddr,rmd160,sizeof(rmd160),waddr); if ( waddr == 0 ) @@ -151,11 +159,13 @@ struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct i { waddr->addrtype = addrtype;//coin->chain->pubtype; waddr->wiftype = addwaddr->wiftype; - if ( bits256_nonz(waddr->privkey) == 0 ) + //if ( bits256_nonz(waddr->privkey) == 0 ) waddr->privkey = addwaddr->privkey; - if ( addwaddr->wifstr[0] != 0 ) + //if ( addwaddr->wifstr[0] != 0 ) strcpy(waddr->wifstr,addwaddr->wifstr); memcpy(waddr->rmd160,rmd160,sizeof(waddr->rmd160)); + if ( addwaddr->pubkey[0] == 0 ) + bitcoin_pubkey33(myinfo->ctx,addwaddr->pubkey,addwaddr->privkey); calc_rmd160_sha256(rmd160,addwaddr->pubkey,bitcoin_pubkeylen(addwaddr->pubkey)); if ( memcmp(rmd160,waddr->rmd160,sizeof(waddr->rmd160)) == 0 ) memcpy(waddr->pubkey,addwaddr->pubkey,sizeof(waddr->pubkey)); @@ -167,9 +177,9 @@ struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct i { HASH_ADD_KEYPTR(hh,wacct->waddr,waddr->rmd160,sizeof(waddr->rmd160),waddr); myinfo->dirty = (uint32_t)time(NULL); - int32_t i; for (i=0; i<20; i++) - printf("%02x",waddr->rmd160[i]); - printf(" add (%s) scriptlen.%d -> (%s) wif.(%s)\n",waddr->coinaddr,waddr->scriptlen,wacct->account,waddr->wifstr); + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",waddr->rmd160[i]); + //printf(" add (%s) scriptlen.%d -> (%s) wif.(%s)\n",waddr->coinaddr,waddr->scriptlen,wacct->account,waddr->wifstr); } else { @@ -245,17 +255,21 @@ struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struc addr = *waddr; flag = 1; iguana_waddressdelete(myinfo,coin,wacct,coinaddr); + waddr = 0; } } if ( (wacct= iguana_waccountcreate(myinfo,account)) != 0 ) { - waddr = iguana_waddresscreate(myinfo,coin,wacct,coinaddr,redeemScript); + if ( waddr == 0 ) + waddr = iguana_waddresscreate(myinfo,coin,wacct,coinaddr,redeemScript); if ( waddr != 0 ) { if ( redeemScript == 0 ) iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,waddr,addr.privkey); strcpy(waddr->coinaddr,coinaddr); waddr = iguana_waddressadd(myinfo,coin,wacct,waddr,redeemScript); + if ( flag != 0 ) + waddr->privkey = addr.privkey; } else waddr = 0; } myinfo->dirty = (uint32_t)time(NULL); @@ -264,7 +278,7 @@ struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struc uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp) { - int32_t iter,n,m; struct iguana_waccount *acct,*tmp; uint8_t *pubkeys,*addrtypes,*rmdarray = 0; struct iguana_waddress *waddr,*tmp2; + int32_t iter,n,m; struct iguana_waccount *acct,*tmp; uint8_t *pubkeys=0,*addrtypes=0,*rmdarray = 0; struct iguana_waddress *waddr,*tmp2; for (iter=n=m=0; iter<2; iter++) { HASH_ITER(hh,myinfo->wallet,acct,tmp) @@ -273,7 +287,7 @@ uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin { if ( iter == 0 ) n++; - else if ( m < n ) + else if ( addrtypes != 0 && pubkeys != 0 && m < n ) { addrtypes[m] = waddr->addrtype; memcpy(&rmdarray[m * 20],waddr->rmd160,20); @@ -295,6 +309,8 @@ uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin cJSON *iguana_getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account) { struct iguana_waccount *subset,*tmp; char refaddr[64],coinaddr[64]; struct iguana_waddress *waddr,*tmp2; cJSON *retjson,*array; + if ( coin == 0 ) + return(0); retjson = cJSON_CreateObject(); array = cJSON_CreateArray(); if ( account == 0 || account[0] == 0 ) @@ -367,7 +383,7 @@ cJSON *iguana_waddressjson(struct iguana_info *coin,cJSON *item,struct iguana_wa //jaddstr(item,"wif",waddr->wifstr); init_hexbytes_noT(str,waddr->rmd160,20); jaddstr(item,"rmd160",str); - jaddstr(item,"coin",waddr->symbol); + jaddstr(item,"coin",coin != 0 ? coin->symbol : waddr->symbol); if ( waddr->scriptlen > 0 ) { init_hexbytes_noT(redeemScript,waddr->redeemScript,waddr->scriptlen); @@ -453,6 +469,7 @@ char *iguana_walletvalue(char *buf,struct iguana_waddress *waddr) if ( waddr->scriptlen > 0 ) init_hexbytes_noT(buf,waddr->redeemScript,waddr->scriptlen); else init_hexbytes_noT(buf,waddr->privkey.bytes,sizeof(waddr->privkey)); + //char str[65]; printf("%s -> walletvalue.(%s)\n",bits256_str(str,waddr->privkey),buf); return(buf); } @@ -464,6 +481,7 @@ int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *co if ( account == 0 || account[0] == 0 ) account = "default"; payload = cJSON_DetachItemFromObject(retjson,"wallet"); + //printf("PAYLOAD.(%s)\n",jprint(payload,0)); if ( payload == 0 ) payload = cJSON_CreateObject(); if ( waddr != 0 && (valuestr= iguana_walletvalue(valuebuf,waddr)) != 0 ) @@ -479,13 +497,13 @@ int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *co { accountobj = cJSON_CreateObject(); jadd(payload,account,accountobj); + //printf("ADDACCOUNT.(%s)\n",jprint(accountobj,0)); } jaddstr(accountobj,rmdstr,valuestr); } jadd(retjson,"wallet",payload); newstr = jprint(retjson,1); retval = iguana_loginsave(myinfo,coin,newstr); - //printf("newstr.(%s) retval.%d\n",newstr,retval); free(newstr); } else printf("iguana_payloadupdate: error parsing.(%s)\n",retstr); return(retval); @@ -518,7 +536,8 @@ cJSON *iguana_payloadmerge(cJSON *loginjson,cJSON *importjson) cJSON *iguana_walletadd(struct supernet_info *myinfo,struct iguana_waddress **waddrp,struct iguana_info *coin,char *retstr,char *account,struct iguana_waddress *refwaddr,int32_t setcurrent,char *redeemScript) { - cJSON *retjson=0; struct iguana_waccount *wacct; struct iguana_waddress *waddr; + cJSON *retjson=0; struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; + printf("walletaddr.(%s)\n",retstr); if ( (wacct= iguana_waccountfind(myinfo,account)) == 0 ) wacct = iguana_waccountcreate(myinfo,account); if ( wacct != 0 ) @@ -599,7 +618,7 @@ char *iguana_walletfields(struct iguana_info *coin,int32_t *p2shflagp,char *wifs int32_t iguana_walletemit(struct supernet_info *myinfo,char *fname,struct iguana_info *coin,cJSON *array) { - cJSON *item,*child; char str[64],wifstr[128],*account,coinaddr[64],*privstr; int32_t i,n,p2shflag; FILE *fp; + cJSON *item,*child; char str[65],wifstr[128],*account,coinaddr[64],*privstr; int32_t i,n,p2shflag; FILE *fp; if ( (fp= fopen(fname,"wb")) == 0 ) return(-1); n = cJSON_GetArraySize(array); @@ -636,7 +655,7 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co //flag |= (5 << 0); //if ( repairflag > 0 ) { - printf("waddrvalidate: need to manually setaccount to fix mismatch (%s:%s) <- (%s:%s)\n",checkwacct != 0 ? checkwacct->account : "",checkwaddr != 0 ? checkwaddr->coinaddr : "",wacct != 0 ? wacct->account : "",waddr->coinaddr); + //printf("waddrvalidate: need to manually setaccount to fix mismatch (%s:%s) <- (%s:%s)\n",checkwacct != 0 ? checkwacct->account : "",checkwaddr != 0 ? checkwaddr->coinaddr : "",wacct != 0 ? wacct->account : "",waddr->coinaddr); } } if ( waddr->scriptlen > 0 ) @@ -652,6 +671,8 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co memset(&waddr->privkey,0,sizeof(waddr->privkey)); } } + if ( waddr->pubkey[0] == 0 ) + bitcoin_pubkey33(myinfo->ctx,waddr->pubkey,waddr->privkey); if ( bitcoin_pubkeylen(waddr->pubkey) > 0 ) { errors[1]++; @@ -691,6 +712,8 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co } } } + if ( waddr->pubkey[0] == 0 ) + bitcoin_pubkey33(myinfo->ctx,waddr->pubkey,waddr->privkey); if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) > 0 ) { calc_rmd160_sha256(rmd160,waddr->pubkey,plen); @@ -745,9 +768,6 @@ cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coi if ( flag < -1 ) { HASH_DELETE(hh,wacct->waddr,waddr); - if ( waddr->unspents != 0 ) - free(waddr->unspents); - //printf("walletiterate: %p free %s\n",waddr,waddr->coinaddr); myfree(waddr,sizeof(*waddr) + waddr->scriptlen); } } @@ -798,7 +818,7 @@ cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coi } printf("persistent address not found in wallet, autoadd.(%s)\n",coinaddr); } - else if ( persistent_flag != 0 ) + else if ( persistent_flag != 0 && (0) ) printf("found persistent address in wallet\n"); } portable_mutex_unlock(&myinfo->bu_mutex); @@ -808,9 +828,8 @@ cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coi *badp = bad; if ( iguana_waddresssearch(myinfo,&wacct,myinfo->myaddr.BTCD) != 0 ) { - printf("found persistent address.(%s)\n",myinfo->myaddr.BTCD); + //printf("found persistent address.(%s)\n",myinfo->myaddr.BTCD); } - return(array); } @@ -833,7 +852,6 @@ char *iguana_walletscan(struct supernet_info *myinfo,struct iguana_info *coin,in void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coin) { - // "wallet":{"test":{"R9S7zZzzvgb4CkiBH1i7gnFcwJuL1MYbxN":"18ab9c89ce83929db720cf26b663bf762532276146cd9d3e1f89086fcdf00053"}} cJSON *payload,*item,*array,*child; char *account,coinaddr[128],*privstr,wifstr[128]; int32_t i,p2shflag,n; struct iguana_waccount *wacct; struct iguana_waddress waddr; bits256 privkey; if ( myinfo->wallet == 0 && myinfo->decryptstr != 0 && (payload= cJSON_Parse(myinfo->decryptstr)) != 0 ) { @@ -862,14 +880,16 @@ void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coi { privkey = bits256_conv(child->valuestring); if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) + { iguana_waddressadd(myinfo,coin,wacct,&waddr,0); - else printf("walletinitcheck: error waddresscalc\n"); + printf("(%s) ",waddr.coinaddr); + } //else printf("walletinitcheck: error waddresscalc\n"); } } } child = child->next; } - //printf("account.(%s)\n",account); + printf("account.(%s)\n",account); } item = item->next; } @@ -879,7 +899,7 @@ void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coi myinfo->decryptstr = 0; myinfo->dirty = 0; } - printf("call walletiterate from initcheck.%p\n",myinfo->decryptstr); + //printf("call walletiterate from initcheck.%p\n",myinfo->decryptstr); iguana_walletiterate(myinfo,coin,1,0,0,0,0); } @@ -890,6 +910,9 @@ void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin) memset(&myinfo->persistent_priv,0,sizeof(myinfo->persistent_priv)); memset(&myinfo->persistent_pubkey33,0,sizeof(myinfo->persistent_pubkey33)); memset(myinfo->secret,0,sizeof(myinfo->secret)); + memset(myinfo->jumblr_passphrase,0,sizeof(myinfo->jumblr_passphrase)); + memset(&myinfo->jumblr_depositkey,0,sizeof(myinfo->jumblr_depositkey)); + memset(&myinfo->jumblr_pubkey,0,sizeof(myinfo->jumblr_pubkey)); memset(myinfo->permanentfile,0,sizeof(myinfo->permanentfile)); if ( myinfo->decryptstr != 0 ) scrubfree(myinfo->decryptstr), myinfo->decryptstr = 0; @@ -897,10 +920,6 @@ void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin) memset(myinfo->myaddr.NXTADDR,0,sizeof(myinfo->myaddr.NXTADDR)); myinfo->myaddr.nxt64bits = 0; myinfo->expiration = 0; - portable_mutex_lock(&myinfo->bu_mutex); - if ( myinfo->spends != 0 ) - free(myinfo->spends), myinfo->numspends = 0; - portable_mutex_unlock(&myinfo->bu_mutex); iguana_walletiterate(myinfo,coin,-2,0,0,0,0); } @@ -934,27 +953,43 @@ int64_t oldiguana_waccountbalance(struct supernet_info *myinfo,struct iguana_inf cJSON *iguana_privkeysjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins) { - int32_t i,j,n,numinputs; struct iguana_waddress *waddr; struct iguana_outpoint spentpt; struct iguana_waccount *wacct; char *addresses,*address,coinaddr[64]; cJSON *privkeys = cJSON_CreateArray(); + int32_t i,n,numinputs,scriptlen; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char *addresses,*address,*scripthexstr,coinaddr[64]; cJSON *scriptobj,*privkeys,*item; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE]; + privkeys = cJSON_CreateArray(); if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) { addresses = calloc(numinputs,64); for (i=n=0; i> 1; + decode_hex(spendscript,scriptlen,scripthexstr); + address = iguana_scriptaddress(coin,coinaddr,spendscript,scriptlen); } - if ( j == n ) - strcpy(&addresses[64 * n++],address); } + //if ( (address= iguana_RTinputaddress(myinfo,coin,coinaddr,&spentpt,jitem(vins,i))) != 0 ) + if ( address != 0 ) + { + strcpy(&addresses[64 * n++],address); + } else printf("cant get address from.(%s)\n",jprint(item,0)); } for (i=0; iwifstr); jaddistr(privkeys,waddr->wifstr); + } + else printf("cant find waddr for %s\n",&addresses[i*64]); } free(addresses); } @@ -963,13 +998,14 @@ cJSON *iguana_privkeysjson(struct supernet_info *myinfo,struct iguana_info *coin #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,cJSON *unspents,cJSON *spends,char *coinaddr,int32_t minconf,int32_t firstheight) { int64_t balance = 0; cJSON *unspentsjson,*balancejson,*item; int32_t i,n; char *balancestr; - if ( (balancestr= iguana_balance(IGUANA_CALLARGS,coin->symbol,coinaddr,-1,minconf)) != 0 ) + if ( (balancestr= iguana_balance(IGUANA_CALLARGS,coin->symbol,coinaddr,1<<30,minconf)) != 0 ) { - //printf("balancestr.(%s) (%s)\n",balancestr,coinaddr); + //printf("balancestr.(%s) (%s) firstheight.%d\n",balancestr,coinaddr,firstheight); if ( (balancejson= cJSON_Parse(balancestr)) != 0 ) { balance = jdouble(balancejson,"balance") * SATOSHIDEN; @@ -984,9 +1020,9 @@ int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info * jaddibits256(txids,jbits256(item,"txid")); if ( vouts != 0 ) jaddinum(vouts,jint(item,"vout")); - if ( unspents != 0 && jobj(item,"unspent") != 0 ) + if ( unspents != 0 && jobj(item,"spent") == 0 && jobj(item,"dest") == 0 ) jaddi(unspents,jduplicate(item)); - if ( spends != 0 && jobj(item,"spent") != 0 ) + if ( spends != 0 && (jobj(item,"spent") != 0 || jobj(item,"dest") != 0) ) jaddi(spends,jduplicate(item)); } } @@ -995,6 +1031,10 @@ int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info * } free(balancestr); } + //if ( spends != 0 ) + // printf("SPENDS.(%s)\n",jprint(spends,0)); + //if ( unspents != 0 ) + // printf("UNSPENTS.(%s)\n",jprint(unspents,0)); return(balance); } @@ -1031,7 +1071,7 @@ STRING_ARG(bitcoinrpc,validateaddress,address) strcat(str,"88ac"); jaddstr(retjson,"scriptPubKey",str); jadd(retjson,"isscript",(addrtype == coin->chain->p2shtype) ? jtrue() : jfalse()); - if ( iguana_ismine(myinfo,coin,coinaddr,addrtype,pubkey,rmd160) > 0 ) + if ( iguana_ismine(myinfo,coin,coinaddr,addrtype,pubkey,rmd160) != 0 ) { init_hexbytes_noT(str,pubkey,bitcoin_pubkeylen(pubkey)); jaddstr(retjson,"pubkey",str); @@ -1051,24 +1091,39 @@ STRING_ARG(bitcoinrpc,validateaddress,address) return(jprint(retjson,1)); } -ZERO_ARGS(bitcoinrpc,getinfo) +double _max100(double val) { - cJSON *retjson; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - retjson = cJSON_CreateObject(); + if ( val < 0. ) + return(0.); + else if ( val > 100. ) + return(100.); + else return(val); +} + +cJSON *iguana_getinfo(struct supernet_info *myinfo,struct iguana_info *coin) +{ + int32_t i; char *retstr; struct iguana_peer *addr; cJSON *array,*retjson = cJSON_CreateObject(); if ( coin != 0 ) { + if ( coin->notarychain >= 0 ) + { + if ( (retstr= _dex_getinfo(myinfo,coin->symbol)) != 0 ) + { + retjson = cJSON_Parse(retstr); + free(retstr); + return(retjson); + } else return(cJSON_Parse("{\"error\":\"null return\"}")); + } jaddstr(retjson,"result","success"); jaddnum(retjson,"protocolversion",PROTOCOL_VERSION); jaddnum(retjson,"kbfee",dstr(coin->txfee_perkb)); jaddnum(retjson,"txfee",dstr(coin->txfee)); if ( coin->bundlescount > 1 ) { - jaddnum(retjson,"bundles",100. * (double)iguana_emitfinished(coin,0)/(coin->bundlescount-1)); - jaddnum(retjson,"utxo",100. * (double)iguana_utxofinished(coin)/(coin->bundlescount-1)); - jaddnum(retjson,"balances",100. * (double)iguana_balancefinished(coin)/(coin->bundlescount-1)); - jaddnum(retjson,"validated",100. * (double)iguana_validated(coin)/(coin->bundlescount-1)); + jaddnum(retjson,"bundles",_max100(100. * (double)(iguana_emitfinished(myinfo,coin,0))/(coin->longestchain/coin->chain->bundlesize))); + jaddnum(retjson,"utxo",_max100(100. * (double)(iguana_utxofinished(coin))/(coin->longestchain/coin->chain->bundlesize))); + jaddnum(retjson,"balances",_max100(100. * (double)(iguana_balancefinished(coin))/(coin->longestchain/coin->chain->bundlesize))); + jaddnum(retjson,"validated",_max100(100. * (double)(iguana_validated(coin))/(coin->longestchain/coin->chain->bundlesize))); } jaddnum(retjson,"firstRTheight",coin->firstRTheight); jaddnum(retjson,"RTheight",coin->RTheight); @@ -1076,12 +1131,100 @@ ZERO_ARGS(bitcoinrpc,getinfo) jaddnum(retjson,"longestchain",coin->longestchain); jaddnum(retjson,"port",coin->chain->portp2p); if ( coin->peers != 0 ) + { + array = cJSON_CreateArray(); + for (i=0; ipeers->active[i]; + if ( addr->usock >= 0 && addr->supernet != 0 && addr->ipaddr[0] != 0 ) + { + jaddistr(array,addr->ipaddr); + if ( strcmp(coin->symbol,"RELAY") == 0 ) + basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(addr->ipaddr),GENESIS_PUBKEY); + } + } + jadd(retjson,"supernet",array); jaddnum(retjson,"connections",coin->peers->numranked); + } + jaddnum(retjson,"RELAY",coin->FULLNODE); jaddnum(retjson,"difficulty",coin->blocks.hwmchain.PoW); jaddstr(retjson,"status",coin->statusstr); jaddstr(retjson,"coin",coin->symbol); } - return(jprint(retjson,1)); + return(retjson); +} + +ZERO_ARGS(bitcoinrpc,getinfo) +{ + struct basilisk_item Lptr,*ptr; int32_t incr,i,j,m,n,longest; cJSON *valsobj,*getinfoobj=0,*array,*item,*fullnodes; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 || coin->notarychain >= 0 ) + return(jprint(iguana_getinfo(myinfo,coin),1)); + else + { + valsobj = cJSON_CreateObject(); + ptr = basilisk_getinfo(&Lptr,myinfo,coin,remoteaddr,0,5000,valsobj); + free_json(valsobj); + if ( ptr != 0 && ptr->retstr != 0 ) + { + if ( (array= cJSON_Parse(ptr->retstr)) != 0 ) + { + if ( is_cJSON_Array(array) != 0 ) + { + getinfoobj = jduplicate(jitem(array,0)); + longest = 0; + if ( coin->FULLNODE == 0 && coin->VALIDATENODE == 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + jdelete(getinfoobj,"longestchain"); + for (i=0; i longest ) + longest = juint(item,"longestchain"); + if ( juint(item,"RTheight") > coin->RTheight ) + { + coin->RTheight = juint(item,"RTheight"); + coin->firstRTheight = juint(item,"firstRTheight"); + printf("set RTheight.%d 1st %d\n",coin->RTheight,coin->firstRTheight); + } + if ( (fullnodes= jarray(&m,item,"supernet")) != 0 ) + { + incr = 1; + if ( strcmp(coin->symbol,"RELAY") == 0 ) + { + for (j=0; jmyaddr.pubkey.uints[0] % incr); + } else j = 0; + for (; jfinished = OS_milliseconds(); + return(jprint(array,1)); + } + free_json(array); + } + ptr->finished = OS_milliseconds(); + if ( getinfoobj != 0 ) + return(jprint(getinfoobj,1)); + } + } + return(clonestr("{\"error\":\"null basilisk_getinfo\"}")); } TWO_STRINGS(bitcoinrpc,setaccount,address,account) @@ -1123,13 +1266,32 @@ STRING_ARG(bitcoinrpc,getnewaddress,account) struct iguana_waddress *iguana_getaccountaddress(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,char *coinaddr,char *account) { - char *newstr,*retstr; struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; + char *newstr,*retstr; int32_t i,n,flag=0; struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; cJSON *unspents,*item; coinaddr[0] = 0; if ( (wacct= iguana_waccountfind(myinfo,account)) == 0 ) wacct = iguana_waccountcreate(myinfo,account); if ( wacct != 0 ) { - if ( (waddr= wacct->current) == 0 || waddr->numunspents > 0 ) + portable_mutex_lock(&myinfo->bu_mutex); + if ( myinfo->Cunspents != 0 && (unspents= jobj(myinfo->Cunspents,coin->symbol)) != 0 ) + { + flag = 0; + if ( (n= cJSON_GetArraySize(unspents)) > 0 ) + { + for (i=0; ibu_mutex); + if ( flag != 0 || (waddr= wacct->current) == 0 ) { if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) { @@ -1185,45 +1347,113 @@ TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) return(clonestr("{\"error\":\"no remote\"}")); if ( timeout <= 0 ) return(clonestr("{\"error\":\"timeout must be positive\"}")); + if ( password == 0 || password[0] == 0 ) + { + if ( (password= jstr(json,"passphrase")) == 0 || password[0] == 0 ) + return(clonestr("{\"error\":\"must have password field\"}")); + } iguana_walletlock(myinfo,coin); - printf("timeout.%d\n",timeout); myinfo->expiration = (uint32_t)time(NULL) + timeout; strcpy(myinfo->secret,password); strcpy(myinfo->password,password); if ( permanentfile != 0 ) strcpy(myinfo->permanentfile,permanentfile); + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) + free(retstr); retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password); myinfo->expiration = (uint32_t)time(NULL) + timeout; iguana_walletinitcheck(myinfo,coin); - //basilisk_unspents_update(myinfo,coin); + if ( coin != 0 ) + { + bitcoin_address(coin->changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + if ( coin->FULLNODE < 0 ) + { + char wifstr[64]; + bitcoin_priv2wif(wifstr,myinfo->persistent_priv,coin->chain->wiftype); + jumblr_importprivkey(myinfo,coin,wifstr); + } + } + if ( bits256_nonz(myinfo->persistent_priv) != 0 ) + { + char *jumblrstr,jumblr_passphrase[1024],coinaddr[64],KMDaddr[64]; bits256 privkey; + sprintf(jumblr_passphrase,"jumblr %s",password); + if ( (jumblrstr= jumblr_setpassphrase(myinfo,0,0,0,jumblr_passphrase)) != 0 ) + free(jumblrstr); + privkey = jumblr_privkey(myinfo,coinaddr,0,KMDaddr,"kmd "); + smartaddress_add(myinfo,privkey,"kmd","BTC",0.,0.); + privkey = jumblr_privkey(myinfo,coinaddr,0,KMDaddr,"btc "); + smartaddress_add(myinfo,privkey,"btc","KMD",0.,0.); + } return(retstr); } THREE_STRINGS(bitcoinrpc,encryptwallet,passphrase,password,permanentfile) { - char *retstr; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); + char *retstr,buf[128],wifstr[128]; cJSON *retjson; int32_t need_KMD = 0,need_BTC = 0; + if ( remoteaddr != 0 || coin == 0 ) + return(clonestr("{\"error\":\"no remote encrypt or no coin\"}")); iguana_walletlock(myinfo,coin); if ( password == 0 || password[0] == 0 ) password = passphrase; if ( passphrase == 0 || passphrase[0] == 0 ) passphrase = password; + if ( passphrase == 0 ) + passphrase = ""; + if ( password == 0 ) + password = ""; strcpy(myinfo->secret,passphrase); strcpy(myinfo->password,password); if ( permanentfile != 0 ) strcpy(myinfo->permanentfile,permanentfile); retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password); - myinfo->expiration = (uint32_t)time(NULL) + 3600*24; + //myinfo->expiration = (uint32_t)time(NULL) + 3600*24; struct iguana_waddress waddr; struct iguana_waccount *wacct; + memset(&waddr,0,sizeof(waddr)); if ( (wacct= iguana_waccountcreate(myinfo,"default")) != 0 ) { if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,myinfo->persistent_priv) != 0 ) iguana_waddressadd(myinfo,coin,wacct,&waddr,0); else printf("couldnt waddresscalc persistent\n"); } else printf("coildnt create default account\n"); - iguana_walletinitcheck(myinfo,coin); + if ( waddr.wifstr[0] != 0 && bits256_nonz(waddr.privkey) != 0 && (retjson= cJSON_Parse(retstr)) != 0 ) + { + free(retstr); + bitcoin_priv2wif(wifstr,waddr.privkey,coin->chain->wiftype); + jaddbits256(retjson,"privkey",waddr.privkey); + sprintf(buf,"%swif",coin->symbol); + jaddstr(retjson,buf,wifstr); + if ( strcmp(coin->symbol,"KMD") != 0 ) + need_KMD = 1; + if ( strcmp(coin->symbol,"BTC") != 0 ) + need_BTC = 1; + if ( need_KMD != 0 && (coin= iguana_coinfind("KMD")) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr.privkey,coin->chain->wiftype); + jaddstr(retjson,"KMDwif",wifstr); + } + if ( (coin= iguana_coinfind("LTC")) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr.privkey,coin->chain->wiftype); + jaddstr(retjson,"LTCwif",wifstr); + bitcoin_priv2wiflong(wifstr,waddr.privkey,coin->chain->wiftype); + jaddstr(retjson,"LTCwiflong",wifstr); + } + if ( need_BTC != 0 ) + { + bitcoin_priv2wif(wifstr,waddr.privkey,128); + jaddstr(retjson,"BTCwif",wifstr); + } + /*if ( (dexstr= _dex_importaddress(myinfo,coin->symbol,waddr.coinaddr)) != 0 ) + { + if ( (dexjson= cJSON_Parse(dexstr)) != 0 ) + jadd(retjson,"deximport",dexjson); + free(dexstr); + }*/ + retstr = jprint(retjson,1); + } + //iguana_walletinitcheck(myinfo,coin); myinfo->dirty = (uint32_t)time(NULL); + myinfo->expiration = 0; return(retstr); } @@ -1263,6 +1493,19 @@ FOUR_STRINGS(bitcoinrpc,walletpassphrasechange,oldpassword,newpassword,oldperman return(retstr); } +TWOSTRINGS_AND_INT(bitcoinrpc,importaddress,address,account,rescan) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( coin != 0 && coin->notarychain >= 0 && coin->FULLNODE == 0 && address != 0 && account != 0 ) + { + if ( strcmp(address,account) != 0 ) + return(clonestr("{\"error\":\"only special account == address supported\"}")); + else return(_dex_importaddress(myinfo,coin->symbol,address)); + } + return(0); +} + TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan) { bits256 privkey; char *retstr,*str; cJSON *retjson; struct iguana_waddress addr,*waddr; struct iguana_waccount *wacct = 0; uint8_t type,redeemScript[4096]; int32_t len; struct vin_info V; bits256 debugtxid; @@ -1270,6 +1513,8 @@ TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan) return(clonestr("{\"error\":\"no remote\"}")); if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); + if ( wif == 0 ) + return(clonestr("{\"error\":\"missing wif\"}")); myinfo->expiration++; if ( account == 0 || account[0] == 0 ) account = "default"; @@ -1288,27 +1533,29 @@ TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan) } } privkey = iguana_str2priv(myinfo,coin,wif); + //char str2[65]; printf("wif.%s -> %s\n",wif,bits256_str(str2,privkey)); if ( bits256_nonz(privkey) == 0 ) return(clonestr("{\"error\":\"illegal privkey\"}")); memset(&addr,0,sizeof(addr)); if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&addr,privkey) != 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (waddr= iguana_waddresssearch(myinfo,&wacct,addr.coinaddr)) != 0 ) { - waddr = iguana_waccountswitch(myinfo,coin,account,addr.coinaddr,0); + //waddr = iguana_waccountswitch(myinfo,coin,account,addr.coinaddr,0); + waddr->privkey = privkey; + myinfo->dirty = 0; return(clonestr("{\"result\":\"privkey already in wallet\"}")); - } - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); + } else waddr = &addr; myinfo->expiration++; if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) { free(retstr); retstr = myinfo->decryptstr, myinfo->decryptstr = 0; - if ( waddr == 0 ) - waddr = &addr; iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,waddr,privkey); iguana_waccountswitch(myinfo,coin,account,waddr->coinaddr,0); + waddr->privkey = privkey; retjson = iguana_walletadd(myinfo,0,coin,retstr,account,waddr,0,0); if ( retstr != 0 ) scrubfree(retstr); @@ -1375,7 +1622,7 @@ STRING_ARG(bitcoinrpc,dumpwallet,filename) { if ( (walletobj= jobj(strobj,"wallet")) != 0 ) jadd(retjson,"wallet",jduplicate(walletobj)); - if ( 0 && (walletobj= iguana_walletjson(myinfo)) != 0 ) + if ( (0) && (walletobj= iguana_walletjson(myinfo)) != 0 ) jadd(retjson,"memory",walletobj); free_json(strobj); } @@ -1497,6 +1744,7 @@ STRING_AND_THREEINTS(bitcoinrpc,getbalance,account,minconf,includeempty,lastheig if ( rmdarray != 0 ) free(rmdarray); retjson = cJSON_CreateObject(); + printf("%s balance %.8f\n",coin->symbol,dstr(balance)); jaddnum(retjson,"result",dstr(balance)); return(jprint(retjson,1)); } @@ -1531,14 +1779,14 @@ STRING_AND_INT(bitcoinrpc,getreceivedbyaccount,account,minconf) STRING_AND_THREEINTS(bitcoinrpc,listtransactions,account,count,skip,includewatchonly) { - cJSON *retjson,*retarray,*txids,*vouts,*item,*array; int32_t vout,i,j,total,m,n = 0; struct iguana_waccount *wacct; char *coinaddr; bits256 txid; + cJSON *retjson,*retarray,*txids,*vouts,*item,*array; int32_t vout,i,j,total,m,n = 0; struct iguana_waccount *wacct=0; char *coinaddr; bits256 txid; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); retjson = cJSON_CreateObject(); retarray = cJSON_CreateArray(); - if ( (wacct= iguana_waccountfind(myinfo,account)) != 0 ) + if ( account == 0 || account[0] == 0 || (wacct= iguana_waccountfind(myinfo,account)) != 0 ) { if ( (array= iguana_getaddressesbyaccount(myinfo,coin,account)) != 0 ) { @@ -1575,12 +1823,9 @@ STRING_AND_THREEINTS(bitcoinrpc,listtransactions,account,count,skip,includewatch "blocktime": 1448045745, }*/ item = cJSON_CreateObject(); - jaddstr(item,"account",wacct->account); - jaddstr(item,"address",coinaddr); - jaddbits256(item,"txid",txid); - jaddnum(item,"vout",vout); - //return(bitcoinrpc_getrawtransaction(IGUANA_CALLARGS,txid,1)); - + if ( wacct != 0 ) + jaddstr(item,"account",wacct->account); + iguana_txdetails(myinfo,coin,item,txid,vout,iguana_txidheight(myinfo,coin,txid)); jaddi(retarray,item); } } @@ -1623,8 +1868,8 @@ THREE_INTS(bitcoinrpc,listreceivedbyaddress,minconf,includeempty,flag) cJSON *retjson,*item,*array,*txids,*vouts; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; uint8_t addrtype; char coinaddr[64]; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); + //if ( myinfo->expiration == 0 ) + // return(clonestr("{\"error\":\"need to unlock wallet\"}")); array = cJSON_CreateArray(); HASH_ITER(hh,myinfo->wallet,wacct,tmp) { diff --git a/iguana/kmd_7776 b/iguana/kmd_7776 new file mode 100755 index 000000000..3f3fad91b --- /dev/null +++ b/iguana/kmd_7776 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"komodo.conf\",\"path\":\"${HOME#"/"}/.komodo\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":0,\"maxpeers\":32,\"newcoin\":\"KMD\",\"name\":\"Komodo\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"f9eee48d\",\"p2p\":7770,\"rpc\":7771,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0}" + diff --git a/iguana/kmd_lookup.h b/iguana/kmd_lookup.h new file mode 100755 index 000000000..05cb91ad4 --- /dev/null +++ b/iguana/kmd_lookup.h @@ -0,0 +1,785 @@ +/****************************************************************************** + * Copyright © 2014-2017 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef INCLUDE_KMDLOOKUP_H +#define INCLUDE_KMDLOOKUP_H + +#define KMD_EXPLORER_LAG 6 + +struct kmd_voutinfo +{ + bits256 spendtxid; + uint64_t amount; + uint16_t spendvini; + uint8_t type_rmd160[21], pad; +} PACKED; + +struct kmd_transaction +{ + bits256 txid; int32_t height,numvouts,numvins; uint32_t timestamp; + struct kmd_voutinfo vouts[]; +} PACKED; + +struct kmd_transactionhh +{ + UT_hash_handle hh; + struct kmd_transaction *tx; + long fpos; + int32_t numvouts,numvins; + struct kmd_transactionhh *ptrs[]; +}; + +struct kmd_addresshh +{ + UT_hash_handle hh; + struct kmd_transactionhh *prev,*lastprev; + uint8_t type_rmd160[21], pad; +}; + +struct kmd_addresshh *_kmd_address(struct iguana_info *coin,uint8_t type_rmd160[21]) +{ + struct kmd_addresshh *addr; + portable_mutex_lock(&coin->kmdmutex); + HASH_FIND(hh,coin->kmd_addresses,type_rmd160,21,addr); + portable_mutex_unlock(&coin->kmdmutex); + if ( addr != 0 && 0 ) + { + char coinaddr[64]; + bitcoin_address(coinaddr,type_rmd160[0],&type_rmd160[1],20); + printf("%s found (%s) %02x\n",coin->symbol,coinaddr,type_rmd160[0]); + } + return(addr); +} + +struct kmd_addresshh *_kmd_addressadd(struct iguana_info *coin,uint8_t type_rmd160[21]) +{ + struct kmd_addresshh *addr; + addr = calloc(1,sizeof(*addr)); + memcpy(addr->type_rmd160,type_rmd160,21); + if ( 0 ) + { + char coinaddr[64]; + bitcoin_address(coinaddr,type_rmd160[0],&type_rmd160[1],20); + printf("%s NEW ADDRESS.(%s) %02x\n",coin->symbol,coinaddr,type_rmd160[0]); + } + portable_mutex_lock(&coin->kmdmutex); + HASH_ADD_KEYPTR(hh,coin->kmd_addresses,addr->type_rmd160,21,addr); + portable_mutex_unlock(&coin->kmdmutex); + return(addr); +} + +struct kmd_addresshh *kmd_address(struct iguana_info *coin,char *coinaddr) +{ + uint8_t type_rmd160[21]; + bitcoin_addr2rmd160(&type_rmd160[0],&type_rmd160[1],coinaddr); + return(_kmd_address(coin,type_rmd160)); +} + +struct kmd_transactionhh *kmd_transaction(struct iguana_info *coin,bits256 txid) +{ + struct kmd_transactionhh *tx; + portable_mutex_lock(&coin->kmdmutex); + HASH_FIND(hh,coin->kmd_transactions,txid.bytes,sizeof(txid),tx); + portable_mutex_unlock(&coin->kmdmutex); + return(tx); +} + +int32_t kmd_transactionvin(struct iguana_info *coin,bits256 spendtxid,int32_t vini,bits256 txid,int32_t vout) +{ + struct kmd_transactionhh *ptr,*spendptr=0; + if ( bits256_nonz(txid) == 0 || vout < 0 ) + return(0); // coinbase must be + if ( (ptr= kmd_transaction(coin,txid)) != 0 && vout < ptr->numvouts && (spendptr= kmd_transaction(coin,spendtxid)) != 0 ) + { + ptr->ptrs[(vout<<1) + 1] = spendptr; + if ( bits256_cmp(ptr->tx->vouts[vout].spendtxid,spendtxid) != 0 || ptr->tx->vouts[vout].spendvini != vini ) + { + if ( bits256_nonz(ptr->tx->vouts[vout].spendtxid) != 0 ) + printf("ht.%d vout.%d overwriting nonz spend\n",ptr->tx->height,vout); + //uint8_t type_rmd160[21]; char str[65]; + //bitcoin_addr2rmd160(&type_rmd160[0],&type_rmd160[1],"RR5yAkzaxJeCVTwvpgCGsNcSPAZjeq3av4"); + //if ( memcmp(type_rmd160,ptr->tx->vouts[vout].type_rmd160,21) == 0 ) + // printf("RR5yAkzaxJeCVTwvpgCGsNcSPAZjeq3av4 %p vout.%d spend %.8f by %s/%d %p\n",ptr,vout,dstr(ptr->tx->vouts[vout].amount),bits256_str(str,spendtxid),vini,spendptr); + ptr->tx->vouts[vout].spendtxid = spendtxid; + ptr->tx->vouts[vout].spendvini = vini; + } + return(0); + } + char str[65]; printf("%s.vin error %s vout.%d of %d vs ptr %p [%d] spent.%p\n",coin->symbol,bits256_str(str,txid),vout,ptr!=0?ptr->numvouts:-1,ptr,ptr!=0?ptr->numvouts:-1,spendptr); + return(-1); +} + +void kmd_transactionvout(struct iguana_info *coin,struct kmd_transactionhh *ptr,int32_t vout,uint64_t amount,uint8_t type_rmd160[21],bits256 spendtxid,int32_t spendvini) +{ + struct kmd_addresshh *addr; struct kmd_transaction *tx = 0; + if ( 0 ) + { + char coinaddr[64],str[65]; + bitcoin_address(coinaddr,type_rmd160[0],&type_rmd160[1],20); + if ( strcmp(coinaddr,"RCsKEQ3r5Xxw4ZtK4CH9VzvfGpTFMdPpsh") == 0 ) + printf("%s ht.%d %s VOUT %d %.8f\n",coinaddr,ptr->tx->height,bits256_str(str,ptr->tx->txid),vout,dstr(amount)); + } + if ( vout < ptr->numvouts && (tx= ptr->tx) != 0 ) + { + tx->vouts[vout].spendtxid = spendtxid; + tx->vouts[vout].spendvini = spendvini; + tx->vouts[vout].amount = amount; + memcpy(tx->vouts[vout].type_rmd160,type_rmd160,21); + if ( (addr= _kmd_address(coin,type_rmd160)) == 0 ) + addr = _kmd_addressadd(coin,type_rmd160); + if ( addr != 0 ) + { + if ( addr->prev != ptr ) + { + ptr->ptrs[vout << 1] = addr->prev; + addr->lastprev = addr->prev; + addr->prev = ptr; + } + else + { + //printf("tricky case same address in different vouts, make sure backlink is right\n"); + ptr->ptrs[vout<<1] = addr->lastprev; + } + } else printf("kmd_transactionvout unexpected null addr\n"); + } else printf("vout.%d wont fit into numvouts.[%d] or null tx.%p\n",vout,ptr->numvouts,tx); +} + +struct kmd_transactionhh *kmd_transactionadd(struct iguana_info *coin,struct kmd_transaction *tx,int32_t numvouts,int32_t numvins) +{ + struct kmd_transactionhh *ptr; //char str[65]; + if ( (ptr= kmd_transaction(coin,tx->txid)) == 0 ) + { + ptr = calloc(1,sizeof(*ptr) + (sizeof(*ptr->ptrs)*numvouts*2)); + ptr->numvouts = numvouts; + ptr->numvins = numvins; + ptr->tx = tx; + portable_mutex_lock(&coin->kmdmutex); + //char str[65]; printf("%s ht.%d u.%u NEW TXID.(%s) vouts.[%d]\n",coin->symbol,tx->height,tx->timestamp,bits256_str(str,tx->txid),numvouts); + HASH_ADD_KEYPTR(hh,coin->kmd_transactions,tx->txid.bytes,sizeof(tx->txid),ptr); + portable_mutex_unlock(&coin->kmdmutex); + } // else printf("warning adding already existing txid %s\n",bits256_str(str,tx->txid)); + return(ptr); +} + +struct kmd_transaction *kmd_transactionalloc(bits256 txid,int32_t height,uint32_t timestamp,int32_t numvouts,int32_t numvins) +{ + struct kmd_transaction *tx; + tx = calloc(1,sizeof(*tx) + sizeof(struct kmd_voutinfo)*numvouts); + tx->numvouts = numvouts; + tx->numvins = numvins; + tx->txid = txid; + tx->height = height; + tx->timestamp = timestamp; + return(tx); +} + +void kmd_flushfiles(struct iguana_info *coin) +{ + if ( coin->kmd_txidfp != 0 ) + fflush(coin->kmd_txidfp); + if ( coin->kmd_spendfp != 0 ) + fflush(coin->kmd_spendfp); +} + +FILE *kmd_txidinit(struct iguana_info *coin) +{ + int32_t i; FILE *fp; char fname[1024]; struct kmd_transactionhh *ptr; struct kmd_transaction T,*tx; struct kmd_voutinfo V; long lastpos=0; + sprintf(fname,"%s/TRANSACTIONS/%s",GLOBAL_DBDIR,coin->symbol); + if ( (fp= fopen(fname,"rb+")) != 0 ) + { + while ( fread(&T,1,sizeof(T),fp) == sizeof(T) ) + { + if ( (tx= kmd_transactionalloc(T.txid,T.height,T.timestamp,T.numvouts,T.numvins)) != 0 ) + { + //char str[65]; printf("INIT %s.[%d] vins.[%d] ht.%d %u\n",bits256_str(str,T.txid),T.numvouts,T.numvins,T.height,T.timestamp); + if ( (ptr= kmd_transactionadd(coin,tx,T.numvouts,T.numvins)) != 0 ) + { + if ( ptr != kmd_transaction(coin,tx->txid) ) + printf("%s ERROR: %p != %p for ht.%d\n",coin->symbol,ptr,kmd_transaction(coin,tx->txid),tx->height); + ptr->fpos = lastpos; + ptr->numvins = T.numvins; + ptr->numvouts = T.numvouts; + for (i=0; isymbol,i,T.height); + break; + } + } + if ( i == T.numvouts ) + { + lastpos = ftell(fp); + if ( T.height > coin->kmd_height ) + coin->kmd_height = T.height; + } else break; + } + } else break; + } + printf("%s finished txidinit fpos %ld vs lastpos %ld\n",coin->symbol,ftell(fp),lastpos); + fseek(fp,lastpos,SEEK_SET); + } else fp = fopen(fname,"wb+"); + return(fp); +} + +FILE *kmd_spendinit(struct iguana_info *coin) +{ + int32_t i,numvins,spentvout; FILE *fp; char fname[1024],str[65]; bits256 txid,spenttxid; struct kmd_transactionhh *ptr,*tmp; struct kmd_voutinfo *vptr; long lastpos=0; + sprintf(fname,"%s/TRANSACTIONS/%s.spends",GLOBAL_DBDIR,coin->symbol); + if ( (fp= fopen(fname,"rb+")) != 0 ) + { + while ( fread(&txid,1,sizeof(txid),fp) == sizeof(txid) ) + { + if ( fread(&numvins,1,sizeof(numvins),fp) == sizeof(numvins) ) + { + for (i=0; isymbol,bits256_str(str,txid),i,numvins); + //break; + } + } else break; + } + if ( i == numvins ) + lastpos = ftell(fp); + else break; + } else break; + } + printf("%s finished spendinit fpos %ld vs lastpos %ld\n",coin->symbol,ftell(fp),lastpos); + fseek(fp,lastpos,SEEK_SET); + HASH_ITER(hh,coin->kmd_transactions,ptr,tmp) + { + //printf("scan for spends ht.%d\n",ptr->tx->height); + for (i=0; inumvouts; i++) + { + vptr = &ptr->tx->vouts[i]; + if ( vptr->spendvini >= 0 && bits256_nonz(vptr->spendtxid) != 0 ) + { + if ( ptr->ptrs[(i<<1) + 1] != kmd_transaction(coin,vptr->spendtxid) ) + { + printf("%s mismatch %s spend.%d %p %p\n",coin->symbol,bits256_str(str,vptr->spendtxid),i,ptr->ptrs[(i<<1) + 1],kmd_transaction(coin,vptr->spendtxid)); + } + } + } + } + } else fp = fopen(fname,"wb+"); + return(fp); +} + +cJSON *kmd_transactionjson(int32_t height,struct kmd_transactionhh *ptr,char *typestr) +{ + int32_t i; char coinaddr[64]; cJSON *item,*array,*obj = cJSON_CreateObject(); + array = cJSON_CreateArray(); + jaddstr(obj,"type",typestr); + jaddbits256(obj,"txid",ptr->tx->txid); + jaddnum(obj,"height",ptr->tx->height); + jaddnum(obj,"timestamp",ptr->tx->timestamp); + for (i=0; inumvouts; i++) + { + item = cJSON_CreateObject(); + bitcoin_address(coinaddr,ptr->tx->vouts[i].type_rmd160[0],&ptr->tx->vouts[i].type_rmd160[1],20); + jaddnum(item,coinaddr,dstr(ptr->tx->vouts[i].amount)); + jaddi(array,item); + } + jadd(obj,"vouts",array); + return(obj); +} + +cJSON *kmd_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct kmd_transaction *tx,int32_t vout,int32_t is_listunspent) +{ + char *script; cJSON *sobj,*txout,*item = cJSON_CreateObject(); + jaddstr(item,"type","received"); + jaddnum(item,"confirmations",height - tx->height); + jaddnum(item,"height",tx->height); + jaddnum(item,"timestamp",tx->timestamp); + jaddbits256(item,"txid",tx->txid); + jaddnum(item,"vout",vout); + jaddnum(item,"amount",dstr(tx->vouts[vout].amount)); + if ( strcmp(coin->symbol,"KMD") == 0 ) + jaddnum(item,"interest",dstr(_iguana_interest((uint32_t)time(NULL),coin->longestchain,tx->timestamp,tx->vouts[vout].amount))); + if ( is_listunspent != 0 ) + { + //char str[65]; printf("get spendscriptstr for %s/v%d\n",bits256_str(str,tx->txid),vout); + if ( (txout= dpow_gettxout(myinfo,coin,tx->txid,vout)) != 0 ) + { + //printf("got.(%s)\n",jprint(txout,0)); + if ( (sobj= jobj(txout,"scriptPubKey")) != 0 && (script= jstr(sobj,"hex")) != 0 ) + jaddstr(item,"scriptPubKey",script); + free_json(txout); + } + } + return(item); +} + +cJSON *kmd_spentjson(int32_t height,struct kmd_transaction *tx,int32_t vout,struct kmd_transactionhh *spent) +{ + cJSON *item = cJSON_CreateObject(); + jaddstr(item,"type","sent"); + jaddnum(item,"confirmations",height - tx->height); + jaddnum(item,"height",tx->height); + jaddnum(item,"timestamp",tx->timestamp); + jaddbits256(item,"txid",tx->txid); + jaddnum(item,"vout",vout); + jaddnum(item,"amount",dstr(tx->vouts[vout].amount)); + jaddbits256(item,"spendtxid",tx->vouts[vout].spendtxid); + jaddnum(item,"vin",tx->vouts[vout].spendvini); + if ( spent != 0 ) + { + jadd(item,"paid",kmd_transactionjson(height,spent,"paid")); + } + return(item); +} + +int32_t kmd_height(struct iguana_info *coin) +{ + char params[64],*curlstr; cJSON *curljson; int32_t height = 0; + strcpy(params,"[]"); + if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 ) + { + if ( (curljson= cJSON_Parse(curlstr)) != 0 ) + { + height = juint(curljson,"blocks"); + //printf("kmd_height.%d (%s)\n",height,jprint(curljson,0)); + free_json(curljson); + } + free(curlstr); + } + return(height); +} + +cJSON *kmd_gettxin(struct iguana_info *coin,bits256 txid,int32_t vout) +{ + struct kmd_transactionhh *ptr,*spendptr; struct kmd_transaction *tx; cJSON *retjson; + if ( (ptr= kmd_transaction(coin,txid)) != 0 && (tx= ptr->tx) != 0 ) + { + if ( vout >= ptr->numvouts ) + return(cJSON_Parse("{\"error\":\"vout too big\"}")); + if ( (spendptr= ptr->ptrs[(vout << 1) + 1]) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"status","spent"); + jaddnum(retjson,"height",tx->height); + jaddnum(retjson,"timestamp",tx->timestamp); + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + jaddnum(retjson,"value",dstr(tx->vouts[vout].amount)); + jaddbits256(retjson,"spendtxid",tx->vouts[vout].spendtxid); + jaddnum(retjson,"vin",tx->vouts[vout].spendvini); + } else return(cJSON_Parse("{\"result\":\"success\",\"status\":\"unspent\"}")); + } + return(cJSON_Parse("{\"error\":\"txid not found\"}")); +} + +cJSON *kmd_listaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,int32_t mode,cJSON *array) +{ + struct kmd_addresshh *addr; struct kmd_transactionhh *ptr=0,*spent,*prev=0; uint8_t type_rmd160[21]; int32_t i; char *retstr; cJSON *retjson; + if ( array == 0 ) + array = cJSON_CreateArray(); + //printf("%s listaddress.(%s)\n",coin->symbol,coinaddr); + if ( (retstr= bitcoinrpc_validateaddress(myinfo,coin,0,0,coinaddr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"error") != 0 && is_cJSON_False(jobj(retjson,"error")) == 0 ) + { + printf("%s\n",retstr); + free(retstr); + return(retjson); + } + free_json(retjson); + } + free(retstr); + } + /*if ( time(NULL) > coin->kmd_lasttime+30 ) + { + coin->kmd_lasttime = (uint32_t)time(NULL); + if ( (height= kmd_height(coin)) > coin->kmd_height+KMD_EXPLORER_LAG*2 ) + { + printf("height.%d > kmd_height.%d\n",height,coin->kmd_height); + return(cJSON_Parse("[]")); + } + }*/ + if ( strcmp("1111111111111111111114oLvT2",coinaddr) == 0 ) // null rmd160 from coinbase + return(cJSON_Parse("[]")); + bitcoin_addr2rmd160(&type_rmd160[0],&type_rmd160[1],coinaddr); + if ( (addr= _kmd_address(coin,type_rmd160)) != 0 && (ptr= addr->prev) != 0 && ptr->tx != 0 ) + { + while ( ptr != 0 ) + { + prev = 0; + for (i=0; inumvouts; i++) + { + if ( memcmp(ptr->tx->vouts[i].type_rmd160,type_rmd160,21) == 0 ) + { + spent = ptr->ptrs[(i<<1) + 1]; + //if ( strcmp("RFpYbieWuKm2ZsTaKeWkrrEdeSkVzhqX8x",coinaddr) == 0 ) + // printf("mode.%d [%d] %s ht.%d amount %.8f spent.%p\n",mode,coin->kmd_height,coinaddr,ptr->tx->height,dstr(ptr->tx->vouts[i].amount),spent); + if ( (mode == 0 && spent == 0) || (mode == 1 && spent != 0) || mode == 2 ) + { + //if ( fulltx == 0 ) + { + if ( mode == 0 ) + jaddi(array,kmd_unspentjson(myinfo,coin,coin->kmd_height,ptr->tx,i,1)); + else if ( mode == 1 ) + jaddi(array,kmd_spentjson(coin->kmd_height,ptr->tx,i,spent)); + else if ( mode == 2 ) + { + if ( spent != 0 ) + jaddi(array,kmd_spentjson(coin->kmd_height,ptr->tx,i,spent)); + else jaddi(array,kmd_unspentjson(myinfo,coin,coin->kmd_height,ptr->tx,i,0)); + } + } + /*else if ( flag == 0 ) + { + if ( mode == 0 ) + jaddi(array,kmd_transactionjson(coin->kmd_height,ptr,"received")); + else if ( mode == 1 ) + { + jaddi(array,kmd_transactionjson(coin->kmd_height,ptr,"received")); + jaddi(array,kmd_transactionjson(coin->kmd_height,spent,"sent")); + } + else if ( mode == 2 ) + { + if ( spent != 0 ) + jaddi(array,kmd_transactionjson(coin->kmd_height,ptr,"spent")); + else jaddi(array,kmd_transactionjson(coin->kmd_height,ptr,"received")); + } + flag = 1; + }*/ + } + if ( ptr->ptrs[i<<1] != 0 ) + { + if ( prev == 0 ) + prev = ptr->ptrs[i<<1]; + else if ( prev != ptr->ptrs[i<<1] ) + printf("%s ht.%d prev.%p != %p\n",coinaddr,ptr->tx->height,prev,ptr->ptrs[i<<1]); + } + } + } + ptr = prev; + } + } //else printf("no valid entry for (%s) %p %p\n",coinaddr,addr,ptr); + return(array); +} + +cJSON *kmd_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) +{ + cJSON *retjson; + retjson = kmd_listaddress(myinfo,coin,coinaddr,0,0); + //printf("KMD utxos.(%s)\n",jprint(retjson,0)); + return(retjson); +} + +cJSON *kmd_listspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) +{ + return(kmd_listaddress(myinfo,coin,coinaddr,1,0)); +} + +cJSON *kmd_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,int32_t count,int32_t skip) +{ + cJSON *array = cJSON_CreateArray(); + //if ( (height= kmd_height(coin)) > coin->kmd_height+KMD_EXPLORER_LAG ) + // return(cJSON_Parse("[]")); + if ( count == 0 ) + count = 100; + array = kmd_listaddress(myinfo,coin,coinaddr,0,0); + array = kmd_listaddress(myinfo,coin,coinaddr,1,array); + return(array); +} + +int64_t _kmd_getbalance(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint64_t *receivedp,uint64_t *sentp,uint64_t *interestp) +{ + int32_t iter,i,n; cJSON *array,*item; uint64_t value; + for (iter=1; iter<=2; iter++) + { + if ( (array= kmd_listaddress(myinfo,coin,coinaddr,iter,0)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ikmd_height+1; + retjson = cJSON_CreateObject(); + fbalance = 0.; + interest = 0; + if ( strcmp(coinaddr,"*") == 0 ) + { + HASH_ITER(hh,coin->kmd_addresses,addr,tmp) + { + bitcoin_address(address,addr->type_rmd160[0],&addr->type_rmd160[1],20); + s = r = i = 0; + balance += _kmd_getbalance(myinfo,coin,address,&r,&s,&i); + netbalance += dstr(r); + netbalance -= dstr(s); + if ( (r - s) > 100000*SATOSHIDEN ) + printf("{\"address\":\"%s\",\"received\":%.8f,\"sent\":%.8f,\"balance\":%.8f,\"supply\":%.8f,\"supplyf\":%.8f,\"interest\":%.8f}\n",address,dstr(r),dstr(s),dstr(r)-dstr(s),dstr(balance),netbalance,dstr(interest)); + received += r; + sent += s; + interest += i; + } + if ( strcmp("KMD",coin->symbol) == 0 ) + jaddnum(retjson,"interestpaid",dstr(balance) - 100000000 - (height*3)); + } + else + { + balance = _kmd_getbalance(myinfo,coin,coinaddr,&received,&sent,&interest); + netbalance = dstr(balance); + } + jaddstr(retjson,"result","success"); + jaddnum(retjson,"received",dstr(received)); + jaddnum(retjson,"sent",dstr(sent)); + //if ( fabs(netbalance*SATOSHIDEN - balance) > 1 ) + jaddnum(retjson,"balancef",netbalance+1./(SATOSHIDEN*2)-SMALLVAL); + //else + jaddnum(retjson,"balance",dstr(balance)); + jaddnum(retjson,"interest",dstr(interest)); + jaddnum(retjson,"height",height); + if ( strcmp("KMD",coin->symbol) == 0 ) + jaddnum(retjson,"mined",height*3); + return(retjson); +} + +char *kmd_bitcoinblockhashstr(char *coinstr,char *serverport,char *userpass,int32_t height) +{ + char numstr[128],*blockhashstr=0; bits256 hash2; struct iguana_info *coin; + sprintf(numstr,"%d",height); + if ( (blockhashstr= bitcoind_passthru(coinstr,serverport,userpass,"getblockhash",numstr)) == 0 ) + return(0); + hash2 = bits256_conv(blockhashstr); + if ( blockhashstr == 0 || blockhashstr[0] == 0 || bits256_nonz(hash2) == 0 ) + { + printf("%s couldnt get blockhash for %u, probably curl is disabled %p\n",coinstr,height,blockhashstr); + if ( blockhashstr != 0 ) + free(blockhashstr); + if ( height == 0 ) + { + if ( (coin= iguana_coinfind(coinstr)) != 0 ) + { + bits256_str(numstr,*(bits256 *)coin->chain->genesis_hashdata); + return(clonestr(numstr)); + } + } + return(0); + } + return(blockhashstr); +} + +cJSON *kmd_blockjson(int32_t *heightp,char *coinstr,char *serverport,char *userpass,char *blockhashstr,int32_t height) +{ + cJSON *json = 0; int32_t flag = 0; char buf[1024],*blocktxt = 0; + if ( blockhashstr == 0 ) + blockhashstr = kmd_bitcoinblockhashstr(coinstr,serverport,userpass,height), flag = 1; + if ( blockhashstr != 0 ) + { + sprintf(buf,"\"%s\"",blockhashstr); + blocktxt = bitcoind_passthru(coinstr,serverport,userpass,"getblock",buf); + //printf("get_blockjson.(%d %s) %s\n",height,blockhashstr,blocktxt); + if ( blocktxt != 0 && blocktxt[0] != 0 && (json= cJSON_Parse(blocktxt)) != 0 && heightp != 0 ) + if ( (*heightp= juint(json,"height")) != height ) + *heightp = -1; + if ( flag != 0 && blockhashstr != 0 ) + free(blockhashstr); + if ( blocktxt != 0 ) + free(blocktxt); + } + return(json); +} + +int32_t _kmd_bitcoinscan(struct iguana_info *coin) +{ + int32_t h,num=0,loadheight,lag,i,n,j,iter,numtxids,numvins,numvouts,flag=0,height=-1; cJSON *txjson,*vouts,*vins,*blockjson,*txids,*vout,*vin,*sobj,*addresses; bits256 zero,txid; char *curlstr,params[128],str[65]; struct kmd_transactionhh *ptr; struct kmd_transaction *tx; uint8_t type_rmd160[21]; + if ( coin->kmd_didinit == 0 ) + { + if ( (coin->kmd_txidfp= kmd_txidinit(coin)) == 0 ) + printf("error initializing %s.kmd txid\n",coin->symbol); + else if ( (coin->kmd_spendfp= kmd_spendinit(coin)) == 0 ) + printf("error initializing %s.kmd spend\n",coin->symbol); + coin->kmd_didinit = 1; + } + height = kmd_height(coin); + loadheight = coin->kmd_height+1; + //if ( strcmp(coin->symbol,"LTC") == 0 ) + // lag = 3; + //else + lag = (strcmp(coin->symbol,"KMD") == 0 ? KMD_EXPLORER_LAG : 2); + while ( loadheight < height-lag ) + { + flag = 0; + if ( (loadheight % 10000) == 0 ) + printf("loading %s ht.%d vs height.%d - lag.%d kmdheight.%d\n",coin->symbol,loadheight,height,lag,coin->kmd_height);//,jprint(kmd_getbalance(coin,"*"),1)); + if ( (blockjson= kmd_blockjson(&h,coin->symbol,coin->chain->serverport,coin->chain->userpass,0,loadheight)) != 0 ) + { + if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 ) + { + for (iter=0; iter<2; iter++) + for (i=0; isymbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 ) + { + if ( (txjson= cJSON_Parse(curlstr)) != 0 ) + { + if ( bits256_cmp(txid,jbits256(txjson,"txid")) != 0 ) + { + printf("%s txid mismatch error ht.%d i.%d\n",coin->symbol,loadheight,i); + continue; + } + vouts = jarray(&numvouts,txjson,"vout"); + vins = jarray(&numvins,txjson,"vin"); + tx = 0; + ptr = 0; + if ( iter == 0 ) + { + if ( (tx= kmd_transactionalloc(txid,loadheight,jint(txjson,"blocktime"),numvouts,numvins)) != 0 ) + ptr = kmd_transactionadd(coin,tx,numvouts,numvins); + else printf("error init tx ptr.%p tx.%p\n",ptr,tx); + } + else + { + if ( (ptr= kmd_transaction(coin,txid)) != 0 ) + tx = ptr->tx; + } + if ( ptr != 0 && tx != 0 ) + { + if ( iter == 0 ) + { + sobj = addresses = 0; + for (j=0; jsymbol); + if ( coin->kmd_txidfp != 0 ) + { + ptr->fpos = ftell(coin->kmd_txidfp); + fwrite(tx,1,sizeof(*tx) + tx->numvouts*sizeof(*tx->vouts),coin->kmd_txidfp); + fflush(coin->kmd_txidfp); + } + } + else + { + if ( coin->kmd_spendfp != 0 ) + { + fwrite(&txid,1,sizeof(txid),coin->kmd_spendfp); + fwrite(&numvins,1,sizeof(numvins),coin->kmd_spendfp); + fflush(coin->kmd_spendfp); + } + for (j=0; jkmd_spendfp != 0 ) + { + fwrite(&spenttxid,1,sizeof(spenttxid),coin->kmd_spendfp); + fwrite(&spentvout,1,sizeof(spentvout),coin->kmd_spendfp); + fflush(coin->kmd_spendfp); + } + } + } + } else printf("incomplete at ht.%d i.%d %p %p\n",loadheight,i,ptr,tx); + free_json(txjson); + } else printf("parseerror.(%s)\n",curlstr); + free(curlstr); + } + } + num++; + kmd_flushfiles(coin); + } + free_json(blockjson); + } + if ( flag != 0 || num > 100 ) + break; + coin->kmd_height = loadheight++; + } + return(num); +} + +void kmd_bitcoinscan() +{ + char *retstr; cJSON *array; int32_t i,n; struct iguana_info *coin; // scan allcoins also + if ( (retstr= dpow_notarychains(0,0,0,0)) != 0 ) + { + if ( (array= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; isymbol,"BTC") != 0 ) + { + //if ( strcmp("KMD",coin->symbol) == 0 ) + _kmd_bitcoinscan(coin); + sleep(1); + } + } + } + free_json(array); + } + free(retstr); + } +} + +#endif diff --git a/iguana/m_LP b/iguana/m_LP index efcf9f5c0..0e1135b48 100755 --- a/iguana/m_LP +++ b/iguana/m_LP @@ -1,8 +1,9 @@ +#!/bin/bash #./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery rm -f ../agents/iguana *.o git pull cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana -gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm +gcc -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +gcc -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_LP_StaticNanoMsg b/iguana/m_LP_StaticNanoMsg new file mode 100755 index 000000000..f121efc88 --- /dev/null +++ b/iguana/m_LP_StaticNanoMsg @@ -0,0 +1,12 @@ +#!/bin/bash +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery +rm -f ../agents/iguana *.o +git pull +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; make -f m_LP_StaticNanoMsg all; make -f m_LP_StaticNanoMsg clean; cd ../iguana + +clang -g -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +clang -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c + + +clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a ../OSlibs/linux/$(uname -m)/libnanomsg-static.a -lcurl -lssl -lcrypto -lpthread -lz -lm -lanl -lrt -lnsl diff --git a/iguana/m_clean b/iguana/m_clean index 368561008..2cf084c74 100755 --- a/iguana/m_clean +++ b/iguana/m_clean @@ -1 +1,2 @@ +#!/bin/bash rm *.o ../agents/iguana diff --git a/iguana/m_js b/iguana/m_js index 712f6b993..3bc0187f8 100755 --- a/iguana/m_js +++ b/iguana/m_js @@ -1,3 +1,4 @@ +#!/bin/bash rm ../agents/iguana *.o git pull emcc -s ALLOW_MEMORY_GROWTH=1 -s PTHREAD_POOL_SIZE=40 -s USE_PTHREADS=2 -o iguana.html -O3 -I. -Isecp256k1./src -Isecp256k1/include -Isecp256k1/src -Wno-unused-parameter -Wnested-externs -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H *.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c secp256k1/src/secp256k1.c -lm diff --git a/iguana/m_mm b/iguana/m_mm new file mode 100755 index 000000000..5a227a69a --- /dev/null +++ b/iguana/m_mm @@ -0,0 +1,3 @@ +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_LP; cd ../iguana +gcc -g -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c groestl.c segwit_addr.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm diff --git a/iguana/m_mm_StaticNanoMsg b/iguana/m_mm_StaticNanoMsg new file mode 100755 index 000000000..2c224b764 --- /dev/null +++ b/iguana/m_mm_StaticNanoMsg @@ -0,0 +1,27 @@ +# makefile for marketmaker uses static nanomsg +# author: fadedreamz@SuperNet.org +# date: Aug, 2017 + +LIB_ARCH=$(uname -m) + +.PHONY: clean all + +err: + @echo "no rule specified, use {clean,all}" + exit 1 + +clean: + - rm -f ../agents/iguana *.o + - rm ../agents/marketmaker + +all: + @echo "Add -j(core count + 1) to speed up build - e,g make -j5 -f m_mm_StaticNanoMsg; on a quad core cpu" + +$(MAKE) -C secp256k1 -f m_unix_Makefile all + +$(MAKE) -C ../crypto777 -f m_LP_StaticNanoMsg all + +$(MAKE) -C ../crypto777 -f m_LP_StaticNanoMsg clean + $(CC) -o ../agents/marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c mini-gmp.c groestl.c segwit_addr.c secp256k1.o ../agents/libcrypto777.a ../OSlibs/linux/$(shell uname -m)/libnanomsg-static.a -lcurl -lpthread -lm -lanl + @echo "===========================" + @echo " marketmaker -> `pwd`/../agents/marketmaker" + @echo "===========================" + + diff --git a/iguana/m_notary b/iguana/m_notary new file mode 100755 index 000000000..0d4d9a9c4 --- /dev/null +++ b/iguana/m_notary @@ -0,0 +1,5 @@ +#!/bin/bash +pkill -15 iguana +rm -f ../agents/iguana *.o +git pull +./m_notary_run diff --git a/iguana/m_notary_run b/iguana/m_notary_run new file mode 100755 index 000000000..b3b789b32 --- /dev/null +++ b/iguana/m_notary_run @@ -0,0 +1,50 @@ +#!/bin/bash + +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_LP; cd ../iguana +#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm + +../agents/iguana notary & #> iguana.log 2> error.log & + +myip=`curl -s4 checkip.amazonaws.com` +source pubkey.txt + +sleep 4 +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}" +sleep 3 +tests/addnotarys_7776 +coins/btc_7776 +coins/ltc_7776 +coins/kmd_7776 +coins/chips_7776 +./wp_7776 + +coins/revs_7776 +coins/supernet_7776 +coins/dex_7776 +coins/bet_7776 +coins/bots_7776 +coins/hodl_7776 +coins/shark_7776 +coins/mshark_7776 +coins/jumblr_7776 +coins/crypto_7776 +coins/pangea_7776 +coins/mgw_7776 +coins/coqui_7776 +coins/wlc_7776 +coins/kv_7776 +coins/ceal_7776 +coins/mesh_7776 +coins/mnz_7776 +coins/axo_7776 +coins/etomic_7776 +coins/btch_7776 +#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"passthru\",\"method\":\"paxfiats\",\"timeout\":900000}" + +#curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"$myip\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}" diff --git a/iguana/m_osx b/iguana/m_osx index 222dccae4..b7a296285 100755 --- a/iguana/m_osx +++ b/iguana/m_osx @@ -1,7 +1,9 @@ +#!/bin/bash #./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery rm ../agents/iguana *.o git pull cd secp256k1; ./m_unix; cd .. -gcc -g -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -gcc -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm +cd ../crypto777; ./m_unix; cd ../iguana +gcc -g -Wno-address-of-packed-member -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +gcc -g -Wno-address-of-packed-member -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_osx_release b/iguana/m_osx_release new file mode 100755 index 000000000..5f74885e7 --- /dev/null +++ b/iguana/m_osx_release @@ -0,0 +1,8 @@ +#!/bin/bash +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery +rm ../agents/iguana *.o +git pull +cd secp256k1; ./m_osx_release; cd .. +clang -g -mmacosx-version-min=10.6 -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +clang -g -mmacosx-version-min=10.6 -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -mmacosx-version-min=10.6 /usr/local/lib/libnanomsg.5.0.0.dylib -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_pnacl b/iguana/m_pnacl index 8f58e6df9..c5089bede 100755 --- a/iguana/m_pnacl +++ b/iguana/m_pnacl @@ -1 +1,2 @@ +#!/bin/bash make diff --git a/iguana/m_splitfund b/iguana/m_splitfund new file mode 100755 index 000000000..75f4b0cfd --- /dev/null +++ b/iguana/m_splitfund @@ -0,0 +1,62 @@ +#!/bin/bash + +set -x + +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BTC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KMD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" + +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"REVS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SUPERNET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DEX\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PANGEA\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JUMBLR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BET\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CRYPTO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HODL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MSHARK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BOTS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MGW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MVP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"COQUI\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"WLC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KV\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CEAL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MESH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MNZ\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AXO\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BTCH\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ETOMIC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" + +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"USD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"EUR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" + +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"JPY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"GBP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"AUD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CAD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CHF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NZD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CNY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RUB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MXN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BRL\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"INR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HKD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"TRY\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ZAR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PLN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NOK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SEK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"DKK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"CZK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HUF\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"ILS\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"KRW\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"MYR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"PHP\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"RON\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"SGD\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"THB\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"BGN\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"IDR\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" +#curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"HRK\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" diff --git a/iguana/m_stats b/iguana/m_stats new file mode 100755 index 000000000..9fface988 --- /dev/null +++ b/iguana/m_stats @@ -0,0 +1 @@ +gcc -g -o DEXstats -I../crypto777 exchanges/stats.c ../crypto777/cJSON.c ../agents/libcrypto777.a -lcurl -lpthread -lm diff --git a/iguana/m_test b/iguana/m_test new file mode 100755 index 000000000..8bf7b041b --- /dev/null +++ b/iguana/m_test @@ -0,0 +1,10 @@ +#!/bin/bash +TESTIPADDR=\"78.47.196.146\" +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery +rm -f ../agents/iguana *.o +git pull +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_LP; cd ../iguana +gcc -DNOTARY_TESTMODE=$TESTIPADDR -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +gcc -DNOTARY_TESTMODE=$TESTIPADDR -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_unix b/iguana/m_unix index 7859bb3c9..8517b1135 100755 --- a/iguana/m_unix +++ b/iguana/m_unix @@ -9,4 +9,4 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_unix; cd ../iguana gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm -lnanomsg diff --git a/iguana/m_win32 b/iguana/m_win32 index b587ba2b0..2f0e718a4 100755 --- a/iguana/m_win32 +++ b/iguana/m_win32 @@ -1,2 +1,3 @@ +#!/bin/bash make -f mingw32 diff --git a/iguana/m_win64 b/iguana/m_win64 index cbe067a7f..ea05be2af 100755 --- a/iguana/m_win64 +++ b/iguana/m_win64 @@ -1 +1,2 @@ +#!/bin/bash make -f mingw64 diff --git a/iguana/main.c b/iguana/main.c index 34ebe7c8f..0528393ed 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -24,6 +24,7 @@ #include "../pnacl_main.h" #include "iguana777.h" + struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char *retjsonstr; char remoteaddr[64]; uint16_t port; char jsonstr[]; }; uint16_t SuperNET_API2num(char *agent,char *method) @@ -70,17 +71,21 @@ int32_t SuperNET_str2hex(uint8_t *hex,char *str) void SuperNET_hex2str(char *str,uint8_t *hex,int32_t len) { - init_hexbytes_noT(str,hex,len); + init_hexbytes_noT(str,hex,len); } +void *bitcoin_ctx(); struct supernet_info *SuperNET_MYINFO(char *passphrase) { + //int32_t i; if ( MYINFO.ctx == 0 ) { + //for (i=0; ifinishedQ; + jsonQ = &coin->jsonQ; + } if ( COMMANDLINE_ARGFILE != 0 ) { ptr = calloc(1,sizeof(*ptr) + strlen(COMMANDLINE_ARGFILE) + 1); - ptr->myinfo = SuperNET_MYINFO(0); + ptr->myinfo = myinfo;//SuperNET_MYINFO(0); strcpy(ptr->jsonstr,COMMANDLINE_ARGFILE); free(COMMANDLINE_ARGFILE); COMMANDLINE_ARGFILE = 0; if ( (ptr->retjsonstr= SuperNET_jsonstr(ptr->myinfo,ptr->jsonstr,ptr->remoteaddr,ptr->port)) == 0 ) ptr->retjsonstr = clonestr("{\"error\":\"null return from iguana_jsonstr\"}"); printf("COMMANDLINE_ARGFILE.(%s) -> (%s) %.0f\n",ptr->jsonstr,ptr->retjsonstr!=0?ptr->retjsonstr:"null return",OS_milliseconds()); - queue_enqueue("finishedQ",&finishedQ,&ptr->DL,0); + queue_enqueue("finishedQ",finishedQ,&ptr->DL); return(1); } - if ( (ptr= queue_dequeue(&finishedQ,0)) != 0 ) + if ( (ptr= queue_dequeue(finishedQ)) != 0 ) { if ( ptr->expired != 0 ) { @@ -192,22 +209,22 @@ int32_t iguana_jsonQ() } printf("garbage collection: expired.(%s)\n",ptr->jsonstr); myfree(ptr,ptr->allocsize); - } else queue_enqueue("finishedQ",&finishedQ,&ptr->DL,0); + } else queue_enqueue("finishedQ",finishedQ,&ptr->DL); } - if ( (ptr= queue_dequeue(&jsonQ,0)) != 0 ) + if ( (ptr= queue_dequeue(jsonQ)) != 0 ) { if ( (ptr->retjsonstr= SuperNET_jsonstr(ptr->myinfo,ptr->jsonstr,ptr->remoteaddr,ptr->port)) == 0 ) ptr->retjsonstr = clonestr("{\"error\":\"null return from iguana_jsonstr\"}"); - printf("finished.(%s) -> (%s) %.0f\n",ptr->jsonstr,ptr->retjsonstr!=0?ptr->retjsonstr:"null return",OS_milliseconds()); - queue_enqueue("finishedQ",&finishedQ,&ptr->DL,0); + //printf("finished.(%s) -> (%s) %.0f\n",ptr->jsonstr,ptr->retjsonstr!=0?ptr->retjsonstr:"null return",OS_milliseconds()); + queue_enqueue("finishedQ",finishedQ,&ptr->DL); return(1); } return(0); } -char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr,uint16_t port) +char *iguana_blockingjsonstr(struct supernet_info *myinfo,struct iguana_info *coin,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr,uint16_t port) { - struct iguana_jsonitem *ptr; int32_t len,allocsize; double expiration; + queue_t *Q; struct iguana_jsonitem *ptr; int32_t len,allocsize; double expiration; expiration = OS_milliseconds() + maxmillis; //printf("blocking case.(%s) %.0f maxmillis.%d\n",jsonstr,OS_milliseconds(),maxmillis); len = (int32_t)strlen(jsonstr); @@ -219,14 +236,17 @@ char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t ptr->retjsonstr = 0; safecopy(ptr->remoteaddr,remoteaddr,sizeof(ptr->remoteaddr)); memcpy(ptr->jsonstr,jsonstr,len+1); - queue_enqueue("jsonQ",&jsonQ,&ptr->DL,0); + if ( coin == 0 || coin->FULLNODE < 0 || (coin->FULLNODE == 0 && coin->VALIDATENODE == 0) ) + Q = &JSON_Q; + else Q = &coin->jsonQ; + queue_enqueue("jsonQ",Q,&ptr->DL); while ( OS_milliseconds() < expiration ) { usleep(100); if ( ptr->retjsonstr != 0 ) { //printf("got blocking retjsonstr.(%s) delete allocsize.%d:%d\n",retjsonstr,allocsize,ptr->allocsize); - queue_delete(&finishedQ,&ptr->DL,ptr->allocsize,1); + queue_delete(coin != 0 ? &coin->finishedQ : &FINISHED_Q,&ptr->DL,ptr->allocsize,1); return(ptr->retjsonstr); } usleep(1000); @@ -236,13 +256,30 @@ char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t return(clonestr("{\"error\":\"iguana jsonstr expired\"}")); } -char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port) +int32_t iguana_immediate(struct iguana_info *coin,int32_t immedmillis) +{ + double endmillis; + if ( immedmillis > 60000 ) + immedmillis = 60000; + endmillis = OS_milliseconds() + immedmillis; + while ( 1 ) + { + if ( coin->busy_processing == 0 ) + break; + usleep(100); + if ( OS_milliseconds() > endmillis ) + break; + } + return(coin->busy_processing == 0); +} + +char *SuperNET_processJSON(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,uint16_t port) { - cJSON *retjson; uint64_t tag; uint32_t timeout; char *jsonstr,*retjsonstr,*retstr = 0; //*hexmsg,*method, + cJSON *retjson; uint64_t tag; uint32_t timeout,immedmillis; char *jsonstr,*retjsonstr,*retstr = 0; //*hexmsg,*method, //char str[65]; printf("processJSON %p %s\n",&myinfo->privkey,bits256_str(str,myinfo->privkey)); if ( json != 0 ) { - if ( (tag= j64bits(json,"tag")) == 0 ) + if ( jobj(json,"tag") == 0 || (tag= j64bits(json,"tag")) == 0 ) { OS_randombytes((uint8_t *)&tag,sizeof(tag)); jadd64bits(json,"tag",tag); @@ -257,16 +294,22 @@ char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remote }*/ jsonstr = jprint(json,0); //printf("RPC? (%s)\n",jsonstr); - if ( jstr(json,"immediate") != 0 || ((remoteaddr == 0 || remoteaddr[0] == 0) && port == IGUANA_RPCPORT) ) - retjsonstr = SuperNET_jsonstr(myinfo,jsonstr,remoteaddr,port); - else retjsonstr = iguana_blockingjsonstr(myinfo,jsonstr,tag,timeout,remoteaddr,port); + if ( (immedmillis= juint(json,"immediate")) != 0 || ((remoteaddr == 0 || remoteaddr[0] == 0) && port == myinfo->rpcport) ) + { + if ( coin != 0 ) + { + if ( immedmillis == 0 || iguana_immediate(coin,immedmillis) != 0 ) + retjsonstr = SuperNET_jsonstr(myinfo,jsonstr,remoteaddr,port); + else retjsonstr = clonestr("{\"error\":\"coin is busy processing\"}"); + } else retjsonstr = SuperNET_jsonstr(myinfo,jsonstr,remoteaddr,port); + } else retjsonstr = iguana_blockingjsonstr(myinfo,coin,jsonstr,tag,timeout,remoteaddr,port); if ( retjsonstr != 0 ) { if ( (retjsonstr[0] == '{' || retjsonstr[0] == '[') && (retjson= cJSON_Parse(retjsonstr)) != 0 ) { if ( is_cJSON_Array(retjson) == 0 ) { - if ( j64bits(retjson,"tag") != tag ) + if ( jobj(retjson,"tag") == 0 || j64bits(retjson,"tag") != tag ) { if ( jobj(retjson,"tag") != 0 ) jdelete(retjson,"tag"); @@ -286,10 +329,10 @@ char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remote return(retstr); } -char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port) +char *SuperNET_JSON(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,uint16_t port) { - int32_t autologin = 0; uint32_t timestamp; char *retstr=0,*agent=0,*method=0,*jsonstr=0; uint64_t tag; - //printf("SuperNET_JSON.(%s)\n",jprint(json,0)); + int32_t autologin = 0; uint32_t timestamp; char *retstr=0,*agent=0,*method=0,*userpass; uint64_t tag; +//printf("SuperNET_JSON.(%s)\n",jprint(json,0)); if ( remoteaddr != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 ) remoteaddr = 0; if ( (agent = jstr(json,"agent")) == 0 ) @@ -308,32 +351,44 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,ui timestamp = (uint32_t)time(NULL); jaddnum(json,"timestamp",timestamp); } - if ( (tag= j64bits(json,"tag")) == 0 ) + if ( jobj(json,"tag") == 0 || (tag= j64bits(json,"tag")) == 0 ) { OS_randombytes((uint8_t *)&tag,sizeof(tag)); jadd64bits(json,"tag",tag); } - if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr,port)) == 0 ) + if ( coin != 0 && coin->FULLNODE >= 0 && coin->chain->userpass[0] != 0 ) + { + if ( (userpass= jstr(json,"userpass")) == 0 || strcmp(userpass,coin->chain->userpass) != 0 ) + { + printf("iguana authentication error {%s} (%s) != (%s)\n",jprint(json,0),userpass,coin->chain->userpass); + return(clonestr("{\"error\":\"authentication error\"}")); + } + } + if ( (retstr= SuperNET_processJSON(myinfo,coin,json,remoteaddr,port)) == 0 ) printf("null retstr from SuperNET_JSON\n"); - if ( jsonstr != 0 ) - free(jsonstr); if ( autologin != 0 ) SuperNET_logout(myinfo,0,json,remoteaddr); return(retstr); } -void iguana_exit() +void iguana_exit(struct supernet_info *myinfo,struct iguana_bundle *bp) { - int32_t j,iter; struct iguana_info *coin,*tmp; + static int exiting; + int32_t i,j,iter; struct iguana_info *coin,*tmp; + if ( exiting != 0 ) + while ( 1 ) + sleep(1); + exiting = 1; + if ( myinfo == 0 ) + myinfo = SuperNET_MYINFO(0); printf("start EXIT\n"); for (iter=0; iter<3; iter++) { if ( iter == 0 ) - basilisk_request_goodbye(SuperNET_MYINFO(0)); + basilisk_request_goodbye(myinfo); else { - //portable_mutex_lock(&Allcoins_mutex); - HASH_ITER(hh,Allcoins,coin,tmp) + HASH_ITER(hh,myinfo->allcoins,coin,tmp) { if ( coin->peers != 0 ) { @@ -350,22 +405,28 @@ void iguana_exit() } } } - //portable_mutex_unlock(&Allcoins_mutex); } sleep(3); } - printf("sockets closed, now EXIT\n"); + printf("sockets closed\n"); + if ( bp != 0 ) + iguana_bundleremove(bp->coin,bp->hdrsi,1); + for (i=0; i<10; i++) + { + printf("need to exit, please restart after shutdown in %d seconds, or just ctrl-C\n",10-i); + sleep(1); + } exit(0); } #ifndef _WIN32 #include -void sigint_func() { printf("\nSIGINT\n"); iguana_exit(); } -void sigillegal_func() { printf("\nSIGILL\n"); iguana_exit(); } -void sighangup_func() { printf("\nSIGHUP\n"); iguana_exit(); } -void sigkill_func() { printf("\nSIGKILL\n"); iguana_exit(); } -void sigabort_func() { printf("\nSIGABRT\n"); iguana_exit(); } -void sigquit_func() { printf("\nSIGQUIT\n"); iguana_exit(); } +void sigint_func() { printf("\nSIGINT\n"); iguana_exit(0,0); } +void sigillegal_func() { printf("\nSIGILL\n"); iguana_exit(0,0); } +void sighangup_func() { printf("\nSIGHUP\n"); iguana_exit(0,0); } +void sigkill_func() { printf("\nSIGKILL\n"); iguana_exit(0,0); } +void sigabort_func() { printf("\nSIGABRT\n"); iguana_exit(0,0); } +void sigquit_func() { printf("\nSIGQUIT\n"); iguana_exit(0,0); } void sigchild_func() { printf("\nSIGCHLD\n"); signal(SIGCHLD,sigchild_func); } void sigalarm_func() { printf("\nSIGALRM\n"); signal(SIGALRM,sigalarm_func); } void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func); } @@ -405,10 +466,22 @@ rm BTC.xz; mksquashfs DB/BTC BTC.xz -comp xz -b 1048576 -comp xz -Xdict-size 102 https://github.com/vasi/squashfuse */ +void DEX_explorerloop(void *ptr) +{ + struct supernet_info *myinfo = ptr; + while ( 1 ) + { + if ( myinfo->DEXEXPLORER != 0 ) + { + kmd_bitcoinscan(); + } + usleep(100000); + } +} + void mainloop(struct supernet_info *myinfo) { - struct iguana_info *coin,*tmp; int32_t i,counter=0,depth; portable_mutex_t *stack[IGUANA_MAXCOINS]; - double lastmilli = 0; + struct iguana_info *coin; int32_t counter=0,depth; double lastmilli = 0; sleep(3); printf("mainloop\n"); while ( 1 ) @@ -422,25 +495,9 @@ void mainloop(struct supernet_info *myinfo) counter++; coin = 0; depth = 0; - if ( 0 ) - { - HASH_ITER(hh,myinfo->allcoins,coin,tmp) - { - portable_mutex_lock(&coin->allcoins_mutex); - stack[depth++] = &coin->allcoins_mutex; - } - } //printf("check jsonQ\n"); - while ( iguana_jsonQ() != 0 ) + while ( iguana_jsonQ(myinfo,0) != 0 ) ; - if ( 0 ) - { - if ( depth > 0 ) - { - for (i=depth-1; i>=0; i--) - portable_mutex_unlock(stack[i]); - } - } lastmilli = OS_milliseconds(); } usleep(30000); @@ -504,12 +561,12 @@ void iguana_appletests(struct supernet_info *myinfo) { char *str; //iguana_chaingenesis(1,1403138561,0x1e0fffff,8359109,bits256_conv("fd1751cc6963d88feca94c0d01da8883852647a37a0a67ce254d62dd8c9d5b2b")); // BTCD - if ( 0 ) + if ( (0) ) { char genesisblock[1024]; //iguana_chaingenesis("VPN",0,bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"),genesisblock,"scrypt",1,1409839200,0x1e0fffff,64881664,bits256_conv("698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828")); // VPN - iguana_chaingenesis("LTC",0,0,0,bits256_conv("12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2"),genesisblock,"sha256",1,1317972665,0x1e0ffff0,2084524493,bits256_conv("97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); // LTC + iguana_chaingenesis(myinfo,"LTC",0,0,0,bits256_conv("12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2"),genesisblock,"sha256",1,1317972665,0x1e0ffff0,2084524493,bits256_conv("97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); // LTC //char *Str = "01000000f615f7ce3b4fc6b8f61e8f89aedb1d0852507650533a9e3b10b9bbcc30639f279fcaa86746e1ef52d3edb3c4ad8259920d509bd073605c9bf1d59983752a6b06b817bb4ea78e011d012d59d4"; // https://litecoin.info/Scrypt 0000000110c8357966576df46f3b802ca897deb7ad18b12f1c24ecff6386ebd9 //uint8_t buf[1000]; bits256 shash,hash2; char str[65],str2[65]; @@ -532,16 +589,16 @@ void iguana_appletests(struct supernet_info *myinfo) bitcoin_sharedsecret(myinfo->ctx,hash2,pubkey,33); printf("secp256k1 elapsed %.3f for %d iterations\n",OS_milliseconds() - startmillis,i); getchar();**/ - if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"protover\":70002,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":512,\"endpend\":512,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) + if ( (0) && (str= SuperNET_JSON(myinfo,iguana_coinfind("BTCD"),cJSON_Parse("{\"protover\":70002,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":512,\"endpend\":512,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) { free(str); - if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"portp2p\":8333,\"RELAY\":0,\"VALIDATE\":0,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":8,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":1,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) + if ( 1 && (str= SuperNET_JSON(myinfo,iguana_coinfind("BTC"),cJSON_Parse("{\"portp2p\":8333,\"RELAY\":0,\"VALIDATE\":0,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":8,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":1,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) { free(str); - if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"alice\",\"password\":\"alice\",\"passphrase\":\"alice\"}"),0,myinfo->rpcport)) != 0 ) + if ( (0) && (str= SuperNET_JSON(myinfo,iguana_coinfind("BTCD"),cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"alice\",\"password\":\"alice\",\"passphrase\":\"alice\"}"),0,myinfo->rpcport)) != 0 ) { free(str); - if ( (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"bob\",\"password\":\"bob\",\"passphrase\":\"bob\"}"),0,myinfo->rpcport)) != 0 ) + if ( (str= SuperNET_JSON(myinfo,iguana_coinfind("BTCD"),cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"bob\",\"password\":\"bob\",\"passphrase\":\"bob\"}"),0,myinfo->rpcport)) != 0 ) free(str); } } @@ -566,6 +623,7 @@ int32_t iguana_commandline(struct supernet_info *myinfo,char *arg) else { IGUANA_NUMHELPERS = juint(argjson,"numhelpers"); + myinfo->remoteorigin = juint(argjson,"remoteorigin"); free_json(argjson); printf("Will run (%s) after initialized with %d threads\n",COMMANDLINE_ARGFILE,IGUANA_NUMHELPERS); } @@ -591,17 +649,17 @@ int32_t iguana_commandline(struct supernet_info *myinfo,char *arg) printf("GLOBAL tmpdir.(%s)\n",GLOBAL_TMPDIR); } printf("call argv JSON.(%s)\n",(char *)arg); - SuperNET_JSON(myinfo,argjson,0,myinfo->rpcport); + SuperNET_JSON(myinfo,0,argjson,0,myinfo->rpcport); if ( (coinargs= SuperNET_keysinit(myinfo,arg)) != 0 ) iguana_launch(0,"iguana_coins",iguana_coins,coinargs,IGUANA_PERMTHREAD); if ( (array= jarray(&n,argjson,"commands")) != 0 ) { for (i=0; irpcport)) != 0 ) + if ( (str= SuperNET_JSON(myinfo,0,jitem(array,i),0,myinfo->rpcport)) != 0 ) free(str); } free_json(argjson); - if ( 0 ) + if ( (0) ) { uint32_t buf[81],c; OS_randombytes((void *)buf,sizeof(buf)); @@ -630,19 +688,24 @@ void iguana_ensuredirs() sprintf(dirname,"%s",GLOBAL_GENESISDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_CONFSDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/SWAPS",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/TRANSACTIONS",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/purgeable",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_TMPDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_VALIDATEDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/ECB",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/BTC",GLOBAL_VALIDATEDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/BTCD",GLOBAL_VALIDATEDIR), OS_ensure_directory(dirname); + sprintf(dirname,"SVM"), OS_ensure_directory(dirname); + sprintf(dirname,"SVM/rawfeatures"), OS_ensure_directory(dirname); + sprintf(dirname,"SVM/models"), OS_ensure_directory(dirname); } void iguana_Qinit() { iguana_initQ(&helperQ,"helperQ"); - iguana_initQ(&jsonQ,"jsonQ"); - iguana_initQ(&finishedQ,"finishedQ"); + iguana_initQ(&JSON_Q,"jsonQ"); + iguana_initQ(&FINISHED_Q,"finishedQ"); iguana_initQ(&bundlesQ,"bundlesQ"); iguana_initQ(&emitQ,"emitQ"); //iguana_initQ(&TerminateQ,"TerminateQ"); @@ -651,7 +714,7 @@ void iguana_Qinit() void iguana_helpinit(struct supernet_info *myinfo) { char *tmpstr = 0; - if ( (tmpstr= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"help\"}"),0,myinfo->rpcport)) != 0 ) + if ( (tmpstr= SuperNET_JSON(myinfo,0,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"help\"}"),0,myinfo->rpcport)) != 0 ) { if ( (API_json= cJSON_Parse(tmpstr)) != 0 && (API_json= jobj(API_json,"result")) != 0 ) API_json = jobj(API_json,"API"); @@ -688,6 +751,33 @@ void iguana_urlinit(struct supernet_info *myinfo,int32_t ismainnet,int32_t usess else strcat(myinfo->NXTAPIURL,"6876/nxt"); } +void jumblr_loop(void *ptr) +{ + struct iguana_info *coin; uint32_t t,n=0; struct supernet_info *myinfo = ptr; int32_t mult = 10; + printf("JUMBLR loop\n"); + while ( myinfo->IAMNOTARY == 0 ) + { + if ( (coin= iguana_coinfind("KMD")) != 0 ) + { + n++; + if ( (n % 3) == 0 ) + smartaddress_update(myinfo,(n/3) & 1); + if ( myinfo->jumblr_passphrase[0] != 0 && coin->FULLNODE < 0 ) + { + // if BTC has arrived in destination address, invoke DEX -> BTC + t = (uint32_t)time(NULL); + if ( (t % (120 * mult)) < 60 ) + { + // if BTC has arrived in deposit address, invoke DEX -> KMD + jumblr_iteration(myinfo,coin,(t % (360 * mult)) / (120 * mult),t % (120 * mult)); + } + //printf("t.%u %p.%d %s\n",t,coin,coin!=0?coin->FULLNODE:0,myinfo->jumblr_passphrase); + } + } + sleep(55); + } +} + void iguana_launchdaemons(struct supernet_info *myinfo) { int32_t i; char *helperargs,helperstr[512]; @@ -703,6 +793,9 @@ void iguana_launchdaemons(struct supernet_info *myinfo) if ( COMMANDLINE_ARGFILE == 0 ) iguana_launch(0,"rpcloop",iguana_rpcloop,myinfo,IGUANA_PERMTHREAD); // limit to oneprocess printf("launch mainloop\n"); + // disable basilisk: OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo); + OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)jumblr_loop,(void *)myinfo); + OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_psockloop,(void *)myinfo); mainloop(myinfo); } @@ -798,7 +891,7 @@ uint8_t *SuperNET_ciphercalc(void **ptrp,int32_t *cipherlenp,bits256 *privkeyp,b cJSON *SuperNET_rosettajson(struct supernet_info *myinfo,bits256 privkey,int32_t showprivs) { uint8_t rmd160[20],pub[33]; uint64_t nxt64bits; bits256 pubkey; - char str2[41],wifbuf[64],addr[64],str[128],coinwif[16]; cJSON *retjson; struct iguana_info *coin,*tmp; + char str2[41],wifbuf[64],pbuf[65],addr[64],str[128],coinwif[16]; cJSON *retjson; struct iguana_info *coin,*tmp; pubkey = acct777_pubkey(privkey); nxt64bits = acct777_nxt64bits(pubkey); retjson = cJSON_CreateObject(); @@ -811,6 +904,8 @@ cJSON *SuperNET_rosettajson(struct supernet_info *myinfo,bits256 privkey,int32_t jaddstr(retjson,"btcpubkey",str); calc_OP_HASH160(str2,rmd160,str); jaddstr(retjson,"rmd160",str2); + if ( showprivs != 0 ) + jaddstr(retjson,"privkey",bits256_str(pbuf,privkey)); HASH_ITER(hh,myinfo->allcoins,coin,tmp) { if ( coin != 0 && coin->symbol[0] != 0 ) @@ -940,6 +1035,436 @@ void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int } #include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" + +STRING_ARG(iguana,initfastfind,activecoin) +{ + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + iguana_fastfindcreate(coin); + return(clonestr("{\"result\":\"fast find initialized\"}")); + } else return(clonestr("{\"error\":\"no coin to initialize\"}")); +} + +TWO_STRINGS_AND_TWO_DOUBLES(iguana,balance,activecoin,address,lastheightd,minconfd) +{ + int32_t lastheight,minconf,maxconf=1<<30; cJSON *array,*retjson = cJSON_CreateObject(); + if ( activecoin != 0 && activecoin[0] != 0 ) + coin = iguana_coinfind(activecoin); + if ( coin != 0 ) + { + if ( (minconf= minconfd) <= 0 ) + minconf = 1; + lastheight = lastheightd; + jaddstr(retjson,"address",address); + if ( bitcoin_validaddress(coin,address) < 0 ) + { + jaddstr(retjson,"error","illegal address"); + return(jprint(retjson,1)); + } + jadd64bits(retjson,"RTbalance",iguana_RTbalance(coin,address)); + array = cJSON_CreateArray(); + jaddistr(array,address); + jadd(retjson,"unspents",iguana_RTlistunspent(myinfo,coin,array,minconf,maxconf,remoteaddr,1)); + free_json(array); + if ( lastheight > 0 ) + jaddnum(retjson,"RTheight",coin->RTheight); + } + return(jprint(retjson,1)); +} + +STRING_ARG(iguana,validate,activecoin) +{ + int32_t i,total,validated; struct iguana_bundle *bp; cJSON *retjson; + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + for (i=total=validated=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 ) + { + validated += iguana_bundlevalidate(myinfo,coin,bp,1); + total += bp->n; + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","validation run"); + jaddstr(retjson,"coin",coin->symbol); + jaddnum(retjson,"validated",validated); + jaddnum(retjson,"total",total); + jaddnum(retjson,"bundles",coin->bundlescount); + jaddnum(retjson,"accuracy",(double)validated/total); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no active coin\"}")); +} + +STRING_ARG(iguana,removecoin,activecoin) +{ + struct iguana_bundle *bp; int32_t i,height; char fname[1024]; + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + coin->active = 0; + coin->started = 0; + if ( (0) ) + { + for (i=0; isymbol,i), OS_removefile(fname,0); + sprintf(fname,"%s/%s/%04d.vins",coin->VALIDATEDIR,coin->symbol,i), OS_removefile(fname,0); + } + sprintf(fname,"%s/%s/vouts/*",GLOBAL_DBDIR,coin->symbol), OS_removefile(fname,0); + sprintf(fname,"%s/%s/*",coin->VALIDATEDIR,coin->symbol), OS_removefile(fname,0); + for (i=0; ibundlescount; i++) + { + sprintf(fname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); + if ( (bp= coin->bundles[i]) != 0 ) + { + iguana_bundlepurgefiles(coin,bp); + iguana_bundleremove(coin,bp->hdrsi,1); + } + } + for (height=0; heightlongestchain; height+=IGUANA_SUBDIRDIVISOR) + { + sprintf(fname,"%s/%s/%d",GLOBAL_DBDIR,coin->symbol,height/IGUANA_SUBDIRDIVISOR); + OS_remove_directory(fname); + } + sprintf(fname,"%s/%s/*",GLOBAL_DBDIR,coin->symbol), OS_remove_directory(fname); + } + return(clonestr("{\"result\":\"success\"}")); + } + return(clonestr("{\"error\":\"no active coin\"}")); +} + +INT_ARG(bitcoinrpc,getblockhash,height) +{ + cJSON *retjson; + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_getblockhash(myinfo,coin->symbol,height)); + retjson = cJSON_CreateObject(); + jaddbits256(retjson,"result",iguana_blockhash(coin,height)); + return(jprint(retjson,1)); +} + +HASH_AND_TWOINTS(bitcoinrpc,getblock,blockhash,verbose,remoteonly) +{ + char *blockstr,*datastr; struct iguana_msgblock msg; struct iguana_block *block; cJSON *retjson; bits256 txid; int32_t len; + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_getblock(myinfo,coin->symbol,blockhash)); + retjson = cJSON_CreateObject(); + memset(&msg,0,sizeof(msg)); + if ( remoteonly == 0 && (block= iguana_blockfind("getblockRPC",coin,blockhash)) != 0 ) + { + if ( verbose != 0 ) + return(jprint(iguana_blockjson(myinfo,coin,block,1),1)); + else + { + if ( (len= iguana_peerblockrequest(myinfo,coin,coin->blockspace,coin->blockspacesize,0,blockhash,0)) > 0 ) + { + datastr = malloc(len*2 + 1); + init_hexbytes_noT(datastr,coin->blockspace,len); + jaddstr(retjson,"result",datastr); + free(datastr); + return(jprint(retjson,1)); + } + jaddstr(retjson,"error","error getting rawblock"); + } + } + else if ( coin->APIblockstr != 0 ) + jaddstr(retjson,"error","already have pending request"); + else + { + memset(txid.bytes,0,sizeof(txid)); + if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,5)) != 0 ) + { + jaddstr(retjson,"result",blockstr); + free(blockstr); + } else jaddstr(retjson,"error","cant find blockhash"); + } + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,getbestblockhash) +{ + cJSON *retjson; + if ( coin->notarychain >= 0 && coin->FULLNODE == 0 ) + return(_dex_getbestblockhash(myinfo,coin->symbol)); + retjson = cJSON_CreateObject(); + char str[65]; jaddstr(retjson,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,getblockcount) +{ + cJSON *retjson = cJSON_CreateObject(); + //printf("result %d\n",coin->blocks.hwmchain.height); + jaddnum(retjson,"result",coin->blocks.hwmchain.height); + return(jprint(retjson,1)); +} + +STRING_AND_INT(iguana,bundleaddresses,activecoin,height) +{ + struct iguana_info *ptr; + if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + return(iguana_bundleaddrs(ptr,height / coin->chain->bundlesize)); + else return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +STRING_AND_INT(iguana,PoSweights,activecoin,height) +{ + struct iguana_info *ptr; int32_t num,nonz,errs,bundleheight; struct iguana_pkhash *refP; uint64_t *weights,supply; cJSON *retjson; + if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + { + //for (bundleheight=coin->chain->bundlesize; bundleheightchain->bundlesize) + { + bundleheight = (height / ptr->chain->bundlesize) * ptr->chain->bundlesize; + if ( (weights= iguana_PoS_weights(myinfo,ptr,&refP,&supply,&num,&nonz,&errs,bundleheight)) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",errs == 0 ? "success" : "error"); + jaddnum(retjson,"bundleheight",bundleheight); + jaddnum(retjson,"numaddresses",num); + jaddnum(retjson,"nonzero",nonz); + jaddnum(retjson,"errors",errs); + jaddnum(retjson,"supply",dstr(supply)); + free(weights); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"iguana_PoS_weights returned null\"}")); + } + } + return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +STRING_ARG(iguana,stakers,activecoin) +{ + struct iguana_info *ptr; int32_t i,datalen,pkind,hdrsi; bits256 hash2; struct iguana_bundle *bp; cJSON *retjson,*array; struct iguana_pkhash *refP; struct iguana_ramchaindata *rdata; char coinaddr[64]; uint8_t refrmd160[20]; bits256 *sortbuf; + if ( (ptr= iguana_coinfind(activecoin)) != 0 && ptr->RTheight > ptr->chain->bundlesize ) + { + hdrsi = (ptr->RTheight / ptr->chain->bundlesize) - 1; + if ( (bp= ptr->bundles[hdrsi]) != 0 && bp->weights != 0 && (rdata= bp->ramchain.H.data) != 0 && bp->weights != 0 ) + { + sortbuf = calloc(bp->numweights,2 * sizeof(*sortbuf)); + for (i=datalen=0; inumweights; i++) + datalen += iguana_rwnum(1,&((uint8_t *)sortbuf)[datalen],sizeof(bp->weights[i]),(void *)&bp->weights[i]); + hash2 = bits256_doublesha256(0,(uint8_t *)sortbuf,datalen); + refP = RAMCHAIN_PTR(rdata,Poffset); + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + memset(refrmd160,0,sizeof(refrmd160)); + for (i=0; ichain->bundlesize; i++) + { + if ( (pkind= iguana_staker_sort(ptr,&hash2,refrmd160,refP,bp->weights,bp->numweights,sortbuf)) > 0 ) + { + bitcoin_address(coinaddr,ptr->chain->pubtype,refP[pkind].rmd160,sizeof(refP[pkind].rmd160)); + jaddistr(array,coinaddr); + } else jaddistr(array,"error"); + } + jaddstr(retjson,"result","success"); + jadd(retjson,"stakers",array); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"iguana_stakers needs PoSweights and weights\"}")); + } + return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +STRING_AND_INT(iguana,bundlehashes,activecoin,height) +{ + struct iguana_info *ptr; struct iguana_bundle *bp; int32_t i,hdrsi; cJSON *retjson,*array; struct iguana_ramchaindata *rdata; + if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + { + hdrsi = height / coin->chain->bundlesize; + if ( hdrsi < coin->bundlescount && hdrsi >= 0 && (bp= coin->bundles[hdrsi]) != 0 ) + { + if ( (rdata= bp->ramchain.H.data) != 0 ) + { + array = cJSON_CreateArray(); + for (i=0; ilhashes[i].txid); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddbits256(retjson,"sha256",rdata->sha256); + jadd(retjson,"bundlehashes",array); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"ramchain not there\"}")); + } else return(clonestr("{\"error\":\"height is too big\"}")); + } else return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +// low priority RPC + +HASH_AND_TWOINTS(bitcoinrpc,listsinceblock,blockhash,target,flag) +{ + /*"transactions" : [ + { + "account" : "doc test", + "address" : "mmXgiR6KAhZCyQ8ndr2BCfEq1wNG2UnyG6", + "category" : "receive", + "amount" : 0.10000000, + "vout" : 0, + "confirmations" : 76478, + "blockhash" : "000000000017c84015f254498c62a7c884a51ccd75d4dd6dbdcb6434aa3bd44d", + "blockindex" : 1, + "blocktime" : 1399294967, + "txid" : "85a98fdf1529f7d5156483ad020a51b7f3340e47448cf932f470b72ff01a6821", + "walletconflicts" : [ + ], + "time" : 1399294967, + "timereceived" : 1418924714 + },*/ + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","low priority RPC not implemented"); + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,gettxoutsetinfo) +{ + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","low priority RPC not implemented"); + return(jprint(retjson,1)); +} + +ZERO_ARGS(bitcoinrpc,listaddressgroupings) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + return(clonestr("{\"error\":\"low priority RPC not implemented\"}")); +} + +SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment) +{ + cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); + retjson = cJSON_CreateObject(); + return(jprint(retjson,1)); +} + +ZERO_ARGS(pax,start) +{ + void PAX_init(); + PAX_init(); + return(clonestr("{\"result\":\"PAX_init called\"}")); +} + +STRING_AND_TWOINTS(mouse,change,name,x,y) +{ + printf("mouse (%s) x.%d y.%d\n",name,x,y); + return(clonestr("{\"result\":\"changed\"}")); +} + +STRING_ARG(mouse,leave,name) +{ + printf("mouse (%s) leave\n",name); + return(clonestr("{\"result\":\"left\"}")); +} + +STRING_AND_TWOINTS(mouse,click,name,x,y) +{ + printf("mouse (%s) x.%d y.%d click\n",name,x,y); + return(clonestr("{\"result\":\"click\"}")); +} + +STRING_AND_INT(keyboard,key,name,c) +{ + printf(" KEY.(%s) c.%d (%c)\n",name,c,c); + return(clonestr("{\"result\":\"key\"}")); +} + +STRING_AND_TWOINTS(mouse,image,name,x,y) +{ + printf("mouse CREATE (%s) x.%d y.%d\n",name,x,y); + return(clonestr("{\"result\":\"opened\"}")); +} + +STRING_ARG(mouse,close,name) +{ + printf("mouse CLOSE (%s)\n",name); + return(clonestr("{\"result\":\"closed\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr) +{ + struct iguana_info *btcd; char *retstr=0,*symbol; uint8_t *data,*allocptr,space[4096]; int32_t datalen; bits256 txid; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) + { + if ( (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr)) != 0 ) + { + txid = bits256_doublesha256(0,data,datalen); + retstr = gecko_sendrawtransaction(myinfo,symbol,data,datalen,txid,vals,hexstr); + } else retstr = clonestr("{\"error\":\"no tx submitted\"}"); + if ( allocptr != 0 ) + free(allocptr); + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"couldnt create geckotx\"}"); + return(retstr); + } return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko tx\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr) +{ + return(clonestr("{\"error\":\"geckoblock is an internal reporting function\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr) +{ + return(clonestr("{\"error\":\"geckoheaders is an internal reporting function\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoget,hash,vals,hexstr) +{ + struct iguana_info *btcd,*virt; char *symbol; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) + { + if ( (virt= iguana_coinfind(symbol)) != 0 ) + { + basilisk_wait(myinfo,virt); + return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,hash,0)); + } else return(clonestr("{\"error\":\"geckoget needs virtualchain\"}")); + } + return(clonestr("{\"error\":\"geckoget needs BTCD\"}")); +} + +TWO_STRINGS(SuperNET,decryptjson,password,permanentfile) +{ + char pass[8192],fname2[1023],destfname[1024]; cJSON *retjson; bits256 wallethash,wallet2priv; + safecopy(pass,password,sizeof(pass)); + safecopy(fname2,permanentfile,sizeof(fname2)); + wallethash = wallet2priv = GENESIS_PRIVKEY; + if ( strlen(pass) == sizeof(wallethash)*2 && is_hexstr(pass,(int32_t)sizeof(bits256)*2) > 0 ) + wallethash = bits256_conv(pass); + if ( strlen(fname2) == sizeof(wallet2priv)*2 && is_hexstr(fname2,(int32_t)sizeof(bits256)*2) > 0 ) + wallet2priv = bits256_conv(fname2); + if ( (retjson= SuperNET_decryptedjson(destfname,pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 ) + { + //printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); + //obj = jduplicate(jobj(retjson,"payload")); + //jdelete(retjson,"payload"); + //jadd(retjson,"result",obj); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"couldnt decrypt json file\"}")); +} + +THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload) +{ + char destfname[4096],pass[8192],fname2[1023]; cJSON *argjson,*retjson = cJSON_CreateObject(); + safecopy(pass,password,sizeof(pass)); + safecopy(fname2,permanentfile,sizeof(fname2)); + argjson = jduplicate(json); + //printf("argjson.(%s)\n",jprint(argjson,0)); + jdelete(argjson,"agent"); + jdelete(argjson,"method"); + jdelete(argjson,"password"); + jdelete(argjson,"permanentfile"); + jdelete(argjson,"timestamp"); + jdelete(argjson,"tag"); + if ( _SuperNET_encryptjson(myinfo,destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"filename",destfname); + } else jaddstr(retjson,"error","couldnt encrypt json file"); + free_json(argjson); + return(jprint(retjson,1)); +} + STRING_ARG(SuperNET,addr2rmd160,address) { @@ -1150,7 +1675,7 @@ ZERO_ARGS(SuperNET,stop) { if ( remoteaddr == 0 || strncmp(remoteaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 ) { - iguana_exit(); + iguana_exit(myinfo,0); return(clonestr("{\"result\":\"exit started\"}")); } else return(clonestr("{\"error\":\"cant do a remote stop of this node\"}")); } @@ -1297,14 +1822,14 @@ STRING_ARG(SuperNET,wif2priv,wif) return(jprint(retjson,1)); } -STRING_ARG(SuperNET,priv2wif,priv) +STRING_AND_INT(SuperNET,priv2wif,priv,wiftype) { - bits256 privkey; char wifstr[65]; uint8_t wiftype; cJSON *retjson = cJSON_CreateObject(); + bits256 privkey; char wifstr[65]; cJSON *retjson = cJSON_CreateObject(); if ( is_hexstr(priv,0) == sizeof(bits256)*2 ) { - wiftype = coin != 0 ? coin->chain->wiftype : 0x80; + //wiftype = coin != 0 ? coin->chain->wiftype : 0x80; decode_hex(privkey.bytes,sizeof(privkey),priv); - if ( bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) + if ( bitcoin_priv2wif(wifstr,privkey,wiftype&0xff) > 0 ) { jaddstr(retjson,"result","success"); jaddstr(retjson,"privkey",priv); @@ -1318,21 +1843,22 @@ STRING_ARG(SuperNET,priv2wif,priv) STRING_ARG(SuperNET,myipaddr,ipaddr) { cJSON *retjson = cJSON_CreateObject(); - RELAYID = -1; + myinfo->NOTARY.RELAYID = -1; if ( myinfo->ipaddr[0] == 0 ) { if ( is_ipaddr(ipaddr) != 0 ) { strcpy(myinfo->ipaddr,ipaddr); myinfo->myaddr.myipbits = (uint32_t)calc_ipbits(ipaddr); + printf("SET MYIPADDR.(%s)\n",ipaddr); basilisk_setmyid(myinfo); } } jaddstr(retjson,"result",myinfo->ipaddr); - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0 ) { - jaddnum(retjson,"relayid",RELAYID); - jaddnum(retjson,"numrelays",NUMRELAYS); + jaddnum(retjson,"relayid",myinfo->NOTARY.RELAYID); + jaddnum(retjson,"numrelays",myinfo->NOTARY.NUMRELAYS); } return(jprint(retjson,1)); } @@ -1375,18 +1901,31 @@ ZERO_ARGS(SuperNET,logout) ZERO_ARGS(SuperNET,activehandle) { - cJSON *retjson; + cJSON *retjson; char BTCaddr[64],KMDaddr[64]; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); retjson = SuperNET_rosettajson(myinfo,myinfo->persistent_priv,0); jaddstr(retjson,"result","success"); jaddstr(retjson,"handle",myinfo->handle); + if ( myinfo->ipaddr[0] != 0 ) + jaddstr(retjson,"myip",myinfo->ipaddr); + if ( myinfo->IAMRELAY != 0 ) + jaddnum(retjson,"notary",myinfo->NOTARY.RELAYID); jaddbits256(retjson,"persistent",myinfo->myaddr.persistent); if ( myinfo->expiration != 0 ) { jaddstr(retjson,"status","unlocked"); jaddnum(retjson,"duration",myinfo->expiration - time(NULL)); } else jaddstr(retjson,"status","locked"); + if ( myinfo->jumblr_passphrase[0] != 0 ) + { + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,JUMBLR_DEPOSITPREFIX); + jaddstr(retjson,"BTCdeposit","notyet"); + jaddstr(retjson,"KMDdeposit",KMDaddr); + jumblr_privkey(myinfo,BTCaddr,0,KMDaddr,""); + jaddstr(retjson,"BTCjumblr","notyet"); + jaddstr(retjson,"KMDjumblr",KMDaddr); + } SuperNET_MYINFOadd(myinfo); return(jprint(retjson,1)); } @@ -1452,12 +1991,12 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) safecopy(myinfo->permanentfile,permanentfile,sizeof(myinfo->permanentfile)); if ( (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,myinfo->permanentfile)) != 0 ) { - printf("decryptstr.(%s)\n",decryptstr); + //printf("decryptstr.(%s)\n",decryptstr); if ( (argjson= cJSON_Parse(decryptstr)) != 0 ) { if ( jobj(argjson,"error") == 0 ) { - printf("decrypted.(%s) exp.%u pass.(%s)\n",decryptstr,myinfo->expiration,password); + //printf("decrypted.(%s) exp.%u pass.(%s)\n",decryptstr,myinfo->expiration,password); if ( myinfo->decryptstr != 0 ) free(myinfo->decryptstr); myinfo->decryptstr = decryptstr; @@ -1513,51 +2052,190 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) if ( (str= SuperNET_encryptjson(myinfo,coin,argjson,remoteaddr,password,myinfo->permanentfile,myinfo->decryptstr == 0 ? "" : myinfo->decryptstr)) != 0 ) free(str); myinfo->expiration = (uint32_t)(time(NULL) + 3600); - printf("(%s) logged into (%s) %s %s\n",password,myinfo->myaddr.NXTADDR,myinfo->myaddr.BTC,myinfo->myaddr.BTCD); return(SuperNET_activehandle(IGUANA_CALLARGS)); - } else return(clonestr("{\"error\":\"need passphrase\"}")); - printf("(%s) logged into (%s) %s %s\n",password,myinfo->myaddr.NXTADDR,myinfo->myaddr.BTC,myinfo->myaddr.BTCD); + } else return(clonestr("{\"error\":\"need passphrase or wallet doesnt exist\"}")); return(SuperNET_activehandle(IGUANA_CALLARGS)); } #include "../includes/iguana_apiundefs.h" -void iguana_relays_init(struct supernet_info *myinfo) +void komodo_ICO_batch(cJSON *array,int32_t batchid) { - static char *ipaddrs[] = { "89.248.160.237", "89.248.160.238", "89.248.160.239", "89.248.160.240", "89.248.160.241", "89.248.160.242", "89.248.160.243", "89.248.160.244" }; - char *str; int32_t i; - for (i=0; irpcport == 0 ) + myinfo->rpcport = 7778; + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + totalKMD = totalREVS = 0; + for (iter=0; iter<1; iter++) + for (i=0; i 0 ) + { + if ( (revsamount= SATOSHIDEN * jdouble(item,"revs_amount")) > 0 ) + { + printf("# %s KMD %.8f",coinaddr,dstr(kmdamount)); + printf(", REVS %.8f\n",dstr(revsamount)); + sprintf(cmd,"fiat/revs sendtoaddress %s %.8f",coinaddr,dstr(revsamount)); + if ( (iter>>1) == 1 ) + { + if ( dstr(revsamount) >= 1. && (iter & 1) == 0 ) + { + printf("curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"REVS\\\"}\" # %.8f\n",myinfo->rpcport,coinaddr,dstr(revsamount)); + printf("sleep 3\n"); + } else printf("sleep 1\n"); + if ( (iter & 1) != 0 ) + { + printf("%s\n",cmd); + totalREVS += dstr(revsamount); + } + } + } + else + { + if ( iter >= 2 ) + continue; + } + sprintf(cmd,"./komodo-cli sendtoaddress %s %.8f",coinaddr,dstr(kmdamount)); + if ( (iter>>1) == 0 ) + { + printf("# %s KMD %.8f\n",coinaddr,dstr(kmdamount)); + if ( (iter & 1) == 0 ) + { + if ( (0) ) + { + printf("curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"KMD\\\"}\" # %.8f\n",myinfo->rpcport,coinaddr,dstr(kmdamount)); + printf("sleep 3\n"); + } else printf("curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"listunspent\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"KMD\\\"}\"\n",myinfo->rpcport,coinaddr); + } + else + { + printf("%s\n",cmd); + totalKMD += dstr(kmdamount); + printf("sleep 3\n"); + } + printf("echo \"%.8f <- expected amount %s\"\n\n",dstr(kmdamount),coinaddr); + } + } + } + printf("\n# total KMD %.8f REVS %.8f\n",totalKMD,totalREVS); + } + getchar(); +} + +void komodo_REVS_merge(char *str,char *str2) +{ + char line[1024],line2[1024],*coinaddr; int32_t i,n=0,m=0,k=0; struct supernet_info *myinfo = SuperNET_MYINFO(0); + while ( 1 ) + { + if ( str[n] == 0 || str2[m] == 0 ) + break; + for (i=0; str[n]!='\n'; n++,i++) + line[i] = str[n]; + line[i] = 0; + n++; + for (i=0; str2[m]!='\n'; m++,i++) + line2[i] = str2[m]; + line2[i] = 0; + m++; + //if ( is_hexstr(line2,0) != 64 ) + { + //printf("%d: (%s) (%s)\n",k,line,line2); + coinaddr = &line[strlen("fiat/revs sendtoaddress ")]; + for (i=0; coinaddr[i]!=' '; i++) + ; + coinaddr[i] = 0; + if ( atof(&coinaddr[i+1]) > 1 ) + { + printf("curl --url \"http://127.0.0.1:%u\" --data \"{\\\"agent\\\":\\\"dex\\\",\\\"method\\\":\\\"importaddress\\\",\\\"address\\\":\\\"%s\\\",\\\"symbol\\\":\\\"REVS\\\"}\" # %.8f\n",myinfo->rpcport,coinaddr,atof(coinaddr+i+1)); + printf("sleep 3\n"); + } + k++; + } + } + getchar(); } void iguana_main(void *arg) { - int32_t usessl = 0, ismainnet = 1; struct supernet_info *myinfo; //cJSON *argjson = 0; + int32_t usessl = 0,ismainnet = 1, do_OStests = 0; struct supernet_info *myinfo; if ( (IGUANA_BIGENDIAN= iguana_isbigendian()) > 0 ) printf("BIGENDIAN\n"); else if ( IGUANA_BIGENDIAN == 0 ) printf("LITTLE ENDIAN arg.%p\n",arg); else printf("ENDIAN ERROR\n"); mycalloc(0,0,0); +#ifdef __APPLE__ + char *batchstr,*batchstr2; cJSON *batchjson; long batchsize; char fname[512],fname2[512]; int32_t batchid = 18; + sprintf(fname,"REVS.raw"), sprintf(fname2,"REVS.rawtxids"); + if ( (0) && (batchstr= OS_filestr(&batchsize,fname)) != 0 && (batchstr2= OS_filestr(&batchsize,fname2)) != 0 ) + { + komodo_REVS_merge(batchstr,batchstr2); + } + sprintf(fname,"batch%d.txt",batchid); + if ( 1 && (batchstr= OS_filestr(&batchsize,fname)) != 0 ) + { + if ( (batchjson= cJSON_Parse(batchstr)) != 0 ) + { + komodo_ICO_batch(batchjson,batchid); + free_json(batchjson); + } + free(batchstr); + } +#endif + myinfo = SuperNET_MYINFO(0); + myinfo->rpcport = IGUANA_RPCPORT; decode_hex(CRYPTO777_RMD160,20,CRYPTO777_RMD160STR); decode_hex(CRYPTO777_PUBSECP33,33,CRYPTO777_PUBSECPSTR); iguana_ensuredirs(); iguana_Qinit(); - myinfo = SuperNET_MYINFO(0); libgfshare_init(myinfo,myinfo->logs,myinfo->exps); - //void test_mimblewimble(void *ctx); - //test_mimblewimble(myinfo->ctx); - if ( 0 ) + myinfo->dpowsock = myinfo->dexsock = myinfo->pubsock = myinfo->subsock = myinfo->reqsock = myinfo->repsock = -1; + dex_init(myinfo); + myinfo->psockport = 30000; + if ( arg != 0 ) + { + if ( strcmp((char *)arg,"OStests") == 0 ) + do_OStests = 1; + else if ( strcmp((char *)arg,"stats") == 0 ) + { + void iguana_notarystats(int32_t totals[64],int32_t dispflag); + int32_t totals[64]; + memset(totals,0,sizeof(totals)); + iguana_notarystats(totals,1); + exit(0); + } + else if ( strcmp((char *)arg,"notary") == 0 ) + { + myinfo->rpcport = IGUANA_NOTARYPORT; + myinfo->IAMNOTARY = 1; + myinfo->DEXEXPLORER = 0;//1; disable as SPV is used now + } + else if ( strncmp((char *)arg,"-port=",6) == 0 ) + { + myinfo->rpcport = atoi(&((char *)arg)[6]); + printf("OVERRIDE IGUANA port <- %u\n",myinfo->rpcport); + } + } +#ifdef IGUANA_OSTESTS + do_OStests = 1; +#endif + if ( do_OStests != 0 ) { - int32_t i; for (i=0; i<10; i++) - iguana_schnorr(myinfo); - getchar(); + int32_t iguana_OStests(); + int32_t retval = iguana_OStests(); + printf("OStests retval %d\n",retval); + return; } - myinfo->rpcport = IGUANA_RPCPORT; strcpy(myinfo->rpcsymbol,"BTCD"); iguana_urlinit(myinfo,ismainnet,usessl); + portable_mutex_init(&myinfo->pending_mutex); + portable_mutex_init(&myinfo->dpowmutex); + portable_mutex_init(&myinfo->notarymutex); + portable_mutex_init(&myinfo->psockmutex); #if LIQUIDITY_PROVIDER + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("nxtae"),0); myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("bitcoin"),0); myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("poloniex"),0); myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("bittrex"),0); @@ -1566,19 +2244,36 @@ void iguana_main(void *arg) myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("coinbase"),0); myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("lakebtc"),0); myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("quadriga"),0); - myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("okcoin"),0); + // prices reversed? myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("okcoin"),0); myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("btce"),0); myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("bitstamp"),0); #endif - if ( iguana_commandline(myinfo,arg) == 0 ) + if ( myinfo->IAMNOTARY == 0 ) { - iguana_helpinit(myinfo); - iguana_relays_init(myinfo); - basilisks_init(myinfo); + if ( iguana_commandline(myinfo,arg) == 0 ) + { + iguana_helpinit(myinfo); + //iguana_relays_init(myinfo); + basilisks_init(myinfo); #ifdef __APPLE__ - iguana_appletests(myinfo); + iguana_appletests(myinfo); #endif + char *retstr; + if ( (retstr= _dex_getnotaries(myinfo,"KMD")) != 0 ) + { + printf("INITIAL NOTARIES.(%s)\n",retstr); + free(retstr); + } + } + } + else + { + basilisks_init(myinfo); } iguana_launchdaemons(myinfo); } +// features +// komodod convert passphrase to privkey +// Z -> Z +// iguana init nanomsg in own thread diff --git a/iguana/mini-gmp.c b/iguana/mini-gmp.c index 4b330f255..f39c66f69 100644 --- a/iguana/mini-gmp.c +++ b/iguana/mini-gmp.c @@ -64,7 +64,7 @@ see https://www.gnu.org/licenses/. */ #define GMP_ULONG_HIGHBIT ((uint64_t) 1 << (GMP_ULONG_BITS - 1)) #define GMP_ABS(x) ((x) >= 0 ? (x) : -(x)) -#define GMP_NEG_CAST(T,x) (-((T)((x) + 1) - 1)) +#define GMP_NEG_CAST(T,x) (-(int64_t)((T)((x) + 1) - 1)) #define GMP_MIN(a, b) ((a) < (b) ? (a) : (b)) #define GMP_MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -90,8 +90,8 @@ see https://www.gnu.org/licenses/. */ #define gmp_ctz(count, x) do { \ mp_limb_t __ctz_x = (x); \ uint32_t __ctz_c = 0; \ - gmp_clz (__ctz_c, __ctz_x & - __ctz_x); \ - (count) = GMP_LIMB_BITS - 1 - __ctz_c; \ + gmp_clz (__ctz_c, __ctz_x & - (int64_t)__ctz_x); \ + (count) = GMP_LIMB_BITS - 1 - (int64_t)__ctz_c; \ } while (0) #define gmp_add_ssaaaa(sh, sl, ah, al, bh, bl) \ @@ -141,7 +141,7 @@ see https://www.gnu.org/licenses/. */ gmp_umul_ppmm (_qh, _ql, (nh), (di)); \ gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \ _r = (nl) - _qh * (d); \ - _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \ + _mask = -(_r > _ql); /* both > and >= are OK */ \ _qh += _mask; \ _r += _mask & (d); \ if (_r >= (d)) \ @@ -168,7 +168,7 @@ see https://www.gnu.org/licenses/. */ (q)++; \ \ /* Conditionally adjust q and the remainders */ \ - _mask = - (mp_limb_t) ((r1) >= _q0); \ + _mask = -((r1) >= _q0); \ (q) += _mask; \ gmp_add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \ if ((r1) >= (d1)) \ @@ -2836,89 +2836,90 @@ static int gmp_detect_endian (void) void *mpz_export (void *r, size_t *countp, int order, size_t size, int endian,size_t nails, const mpz_t u) { - size_t count; - mp_size_t un; - - if (nails != 0) - gmp_die ("mpz_import: Nails not supported."); - - assert (order == 1 || order == -1); - assert (endian >= -1 && endian <= 1); - assert (size > 0 || u->_mp_size == 0); - - un = u->_mp_size; - count = 0; - if (un != 0) - { - size_t k; - uint8_t *p; - ptrdiff_t word_step; - /* The current (partial) limb. */ - mp_limb_t limb; - /* The number of bytes left to to in this limb. */ - size_t bytes; - /* The index where the limb was read. */ - mp_size_t i; - - un = GMP_ABS (un); - - /* Count bytes in top limb. */ - limb = u->_mp_d[un-1]; - assert (limb != 0); - - k = 0; - do { - k++; limb >>= CHAR_BIT; - } while (limb != 0); - - count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size; - - if (!r) - r = malloc (count * size); - - if (endian == 0) - endian = gmp_detect_endian (); - - p = (uint8_t *) r; - - word_step = (order != endian) ? 2 * size : 0; - - /* Process bytes from the least significant end, so point p at the - least significant word. */ - if (order == 1) - { - p += size * (count - 1); - word_step = - word_step; - } - - /* And at least significant byte of that word. */ - if (endian == 1) - p += (size - 1); - - for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step) - { - size_t j; - for (j = 0; j < size; j++, p -= (ptrdiff_t) endian) - { - if (bytes == 0) - { - if (i < un) - limb = u->_mp_d[i++]; - bytes = sizeof (mp_limb_t); - } - *p = limb; - limb >>= CHAR_BIT; - bytes--; - } - } - assert (i == un); - assert (k == count); + size_t count; + mp_size_t un; + + if (nails != 0) + gmp_die ("mpz_import: Nails not supported."); + + assert (order == 1 || order == -1); + assert (endian >= -1 && endian <= 1); + assert (size > 0 || u->_mp_size == 0); + + un = u->_mp_size; + count = 0; + if (un != 0) + { + size_t k; + uint8_t *p; + ptrdiff_t word_step; + /* The current (partial) limb. */ + mp_limb_t limb; + /* The number of bytes left to to in this limb. */ + size_t bytes; + /* The index where the limb was read. */ + mp_size_t i; + + un = GMP_ABS (un); + + /* Count bytes in top limb. */ + limb = u->_mp_d[un-1]; + assert (limb != 0); + + k = 0; + do { + k++; limb >>= CHAR_BIT; + } while (limb != 0); + + count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size; + + if (!r) + r = malloc (count * size); + + if (endian == 0) + endian = gmp_detect_endian (); + + p = (uint8_t *) r; + + word_step = (order != endian) ? 2 * size : 0; + + /* Process bytes from the least significant end, so point p at the + least significant word. */ + if (order == 1) + { + p += size * (count - 1); + word_step = - word_step; + } + + /* And at least significant byte of that word. */ + if (endian == 1) + p += (size - 1); + + for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step) + { + size_t j; + for (j = 0; j < size; j++, p -= (ptrdiff_t) endian) + { + if (bytes == 0) + { + if (i < un) + limb = u->_mp_d[i++]; + bytes = sizeof (mp_limb_t); + } + *p = limb; + //printf("{%02x} ",*p); + limb >>= CHAR_BIT; + bytes--; + } + } + assert (i == un); + assert (k == count); } - - if (countp) - *countp = count; - - return r; + + if (countp) + *countp = count; + //printf("mpz_export.%d\n",(int32_t)count); + return r; } ///////////////////////////////// @@ -3517,7 +3518,7 @@ static void mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t n uint32_t shift; mp_size_t i; mp_limb_t d1, d0, di, r1, r0; - mp_ptr tp; + mp_ptr tp=0; assert (nn >= 2); shift = inv->shift; @@ -3553,8 +3554,8 @@ static void mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t n assert ((r0 << (GMP_LIMB_BITS - shift)) == 0); r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift)); r1 >>= shift; - - free (tp); + if ( tp != 0 ) + free (tp); } rp[1] = r1; @@ -4232,9 +4233,9 @@ static mp_limb_t mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t mpn_copyi (qp, np, nn); else { - uint32_t shift; + uint64_t shift; gmp_ctz (shift, d); - mpn_rshift (qp, np, nn, shift); + mpn_rshift (qp, np, nn, (uint32_t)shift); } } return r; @@ -4360,44 +4361,6 @@ char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen) return(coinaddr); } -int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) -{ - uint32_t zeroes,be_sz=0; size_t count; const char *p,*p1; mpz_t bn58,bn; - mpz_init_set_ui(bn58,58); - mpz_init_set_ui(bn,0); - while ( isspace((uint32_t)(*coinaddr & 0xff)) ) - coinaddr++; - for (p=coinaddr; *p; p++) - { - p1 = strchr(base58_chars,*p); - if ( p1 == 0 ) - { - while (isspace((uint32_t)*p)) - p++; - if ( *p != '\0' ) - { - mpz_clear(bn), mpz_clear(bn58); - return(-1); - } - break; - } - mpz_mul(bn,bn,bn58); - mpz_add_ui(bn,bn,(int32_t)(p1 - base58_chars)); - } - zeroes = 0; - for (p=coinaddr; *p==base58_chars[0]; p++) - data[zeroes++] = 0; - mpz_export(data+zeroes,&count,1,sizeof(data[0]),-1,0,bn); - if ( count >= 2 && data[count - 1] == 0 && data[count - 2] >= 0x80 ) - count--; - be_sz = (uint32_t)count + (uint32_t)zeroes; - //memset(data,0,be_sz); - //for (i=0; i %s\n",bits256_str(str,privkey)); + }*/ + if ( count >= 2 && data[count - 1] == 0 && data[count - 2] >= 0x80 ) + count--; + be_sz = (uint32_t)count + (uint32_t)zeroes; + //memset(data,0,be_sz); + //for (i=0; i lastdayupdate + 60000*60 ) { lastdayupdate = milliseconds(); + printf("call ecb_matrix.(%s)\n",dp->edate); if ( (datenum= ecb_matrix(dp->ecbmatrix,dp->edate)) > 0 ) { dp->ecbdatenum = datenum; diff --git a/iguana/pangea777.h b/iguana/pangea777.h index 56a71e57b..1ff471e3a 100755 --- a/iguana/pangea777.h +++ b/iguana/pangea777.h @@ -123,12 +123,12 @@ int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m, struct pangea_msghdr { // sig { bits256 sigbits,pubkey; uint64_t signer64bits; uint32_t timestamp,allocsize; }; - struct acct777_sig sig __attribute__((packed)); + struct acct777_sig sig PACKED; bits256 tablehash; char cmd[8]; int8_t turni,cardi,destplayer,myind; // ALL DATA MUST BE SERIALIZED!!! uint8_t serialized[]; -} __attribute__((packed)); +};// PACKED; #define PANGEA_ARGS struct supernet_info *myinfo,struct table_info *tp,cJSON *json #define PANGEA_CALLARGS myinfo,tp,json diff --git a/iguana/pangea_api.c b/iguana/pangea_api.c index 3329fd45f..ea7d942e5 100755 --- a/iguana/pangea_api.c +++ b/iguana/pangea_api.c @@ -530,7 +530,7 @@ char *pangea_hexmsg(struct supernet_info *myinfo,struct gecko_chain *cat,void *d } } } - else if ( 0 ) + else if ( (0) ) { for (i=0; istateQ[iter],0)) != 0 ) + while ( (ptr= queue_dequeue(&tp->stateQ[iter])) != 0 ) { if ( ptr->waitevent == waitevent ) return(ptr); - queue_enqueue("stateQ",&tp->stateQ[iter ^ 1],&ptr->DL,0); + queue_enqueue("stateQ",&tp->stateQ[iter ^ 1],&ptr->DL); } } return(0); @@ -42,7 +42,7 @@ void pangea_queuestate(struct table_info *tp,int32_t currentstate,int32_t waitev ptr->last = ptr->start = tai_now(); ptr->waitevent = waitevent; char str[65]; printf("table.%s current.%d -> wait.%d\n",bits256_str(str,tp->G.tablehash),currentstate,waitevent); - queue_enqueue("stateQ",&tp->stateQ[0],&ptr->DL,0); + queue_enqueue("stateQ",&tp->stateQ[0],&ptr->DL); } int32_t pangea_slotA(struct table_info *tp) { return(0); } @@ -383,7 +383,7 @@ int32_t pangea_queueprocess(struct supernet_info *myinfo,struct table_info *tp) //char str[65]; printf("queueprocess.(%s)\n",bits256_str(str,tp->G.tablehash)); for (iter=0; iter<2; iter++) { - while ( (ptr= queue_dequeue(&tp->stateQ[iter],0)) != 0 ) + while ( (ptr= queue_dequeue(&tp->stateQ[iter])) != 0 ) { retval = 0; diff = tai_diff(ptr->last,tai_now()); @@ -409,7 +409,7 @@ int32_t pangea_queueprocess(struct supernet_info *myinfo,struct table_info *tp) else { ptr->last = tai_now(); - queue_enqueue("stateQ",&tp->stateQ[iter ^ 1],&ptr->DL,0); + queue_enqueue("stateQ",&tp->stateQ[iter ^ 1],&ptr->DL); } } } @@ -811,7 +811,7 @@ int32_t pangea_lastman(struct supernet_info *myinfo,struct table_info *tp) printf("DUPLICATE LASTMAN!\n"); return(1); } - if ( 0 && tp->priv.myind == activej && tp->priv.automuck == 0 ) + if ( (0) && tp->priv.myind == activej && tp->priv.automuck == 0 ) { pangea_sendcmd(myinfo,tp,"faceup",-1,tp->priv.holecards[0].bytes,sizeof(tp->priv.holecards[0]),tp->priv.cardis[0],tp->priv.cardis[0] != 0xff); pangea_sendcmd(myinfo,tp,"faceup",-1,tp->priv.holecards[1].bytes,sizeof(tp->priv.holecards[1]),tp->priv.cardis[1],tp->priv.cardis[1] != 0xff); diff --git a/iguana/pangea_json.c b/iguana/pangea_json.c index c325c4a69..0c3b19840 100755 --- a/iguana/pangea_json.c +++ b/iguana/pangea_json.c @@ -227,6 +227,7 @@ cJSON *pangea_tablestatus(struct supernet_info *myinfo,struct table_info *tp) jaddi64bits(array,tp->active[i]!=0?tp->active[i]->nxt64bits:0); jadd(json,"addrs",array);*/ total = 0; + str = "error"; for (iter=0; iter<6; iter++) { array = cJSON_CreateArray(); @@ -243,22 +244,23 @@ cJSON *pangea_tablestatus(struct supernet_info *myinfo,struct table_info *tp) case 3: val = p->betstatus; str = "status"; break; case 4: val = p->bets; str = "bets"; break; case 5: val = p->won; str = "won"; break; + default: str = "error"; break; } } if ( iter == 5 ) won[i] = val; else { - if ( iter == 3 ) - jaddistr(array,pangea_statusstr((int32_t)val)); - else - { - if ( iter == 4 ) - total += val, bets[i] = val; - else if ( iter == 2 ) - snapshot[i] = val; - jaddinum(array,val); - } + if ( iter == 3 ) + jaddistr(array,pangea_statusstr((int32_t)val)); + else + { + if ( iter == 4 ) + total += val, bets[i] = val; + else if ( iter == 2 ) + snapshot[i] = val; + jaddinum(array,val); + } } } jadd(json,str,array); diff --git a/iguana/pnacl/Release/iguana.nmf b/iguana/pnacl/Release/iguana.nmf new file mode 100644 index 000000000..9d37ed227 --- /dev/null +++ b/iguana/pnacl/Release/iguana.nmf @@ -0,0 +1,12 @@ +{ + "program": { + "portable": { + "pnacl-translate": { + "url": "iguana.pexe" + }, + "pnacl-debug": { + "url": "iguana_unstripped.bc" + } + } + } +} diff --git a/iguana/poker.c b/iguana/poker.c index 61980b11c..e99ee848e 100755 --- a/iguana/poker.c +++ b/iguana/poker.c @@ -6,7 +6,6 @@ #include #include #include -#include #define CLUB_SUIT (1) #define DIAMOND_SUIT (2) @@ -626,8 +625,8 @@ void poker_test() } starttime = (uint32_t)time(NULL); #ifndef _WIN32 - while ( (uint32_t)time(NULL) == starttime ) - usleep(100); + //while ( (uint32_t)time(NULL) == starttime ) + // usleep(100); total = counter = 0; while ( (uint32_t)time(NULL) < starttime+11 ) { diff --git a/iguana/pthreadVC2.lib b/iguana/pthreadVC2.lib new file mode 100644 index 000000000..d793e7144 Binary files /dev/null and b/iguana/pthreadVC2.lib differ diff --git a/iguana/ramchain_api.c b/iguana/ramchain_api.c index 5db58b16d..e28a106ff 100755 --- a/iguana/ramchain_api.c +++ b/iguana/ramchain_api.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,312 +13,425 @@ * * ******************************************************************************/ +// deprecated #include "iguana777.h" + #include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" +#include "../includes/iguana_apideclares2.h" + + +STRING_ARG(iguana,peers,activecoin) +{ + if ( coin != 0 ) + return(jprint(iguana_peersjson(coin,0),1)); + else return(clonestr("{\"error\":\"peers needs coin\"}")); +} -STRING_ARG(iguana,initfastfind,activecoin) +STRING_ARG(iguana,getconnectioncount,activecoin) { - if ( (coin= iguana_coinfind(activecoin)) != 0 ) + int32_t i,num = 0; char buf[512]; + if ( coin != 0 && coin->peers != 0 ) { - iguana_fastfindcreate(coin); - return(clonestr("{\"result\":\"fast find initialized\"}")); - } else return(clonestr("{\"error\":\"no coin to initialize\"}")); + for (i=0; ipeers->active)/sizeof(*coin->peers->active); i++) + if ( coin->peers->active[i].usock >= 0 ) + num++; + sprintf(buf,"{\"result\":\"%d\"}",num); + return(clonestr(buf)); + } else return(clonestr("{\"error\":\"getconnectioncount needs coin\"}")); } -TWO_STRINGS_AND_TWO_DOUBLES(iguana,balance,activecoin,address,lastheightd,minconfd) +ZERO_ARGS(bitcoinrpc,getdifficulty) { - int32_t lastheight,minconf,maxconf=SATOSHIDEN; uint64_t total=0; uint8_t rmd160[20],pubkey33[33],addrtype; struct iguana_pkhash *P; cJSON *array,*retjson = cJSON_CreateObject(); - if ( activecoin != 0 && activecoin[0] != 0 ) - coin = iguana_coinfind(activecoin); + char buf[512]; if ( coin != 0 ) { - if ( (minconf= minconfd) <= 0 ) - minconf = 1; - lastheight = lastheightd; - jaddstr(retjson,"address",address); - if ( bitcoin_validaddress(coin,address) < 0 ) - { - jaddstr(retjson,"error","illegal address"); - return(jprint(retjson,1)); - } - jadd64bits(retjson,"RTbalance",iguana_RTbalance(coin,address)); - if ( bitcoin_addr2rmd160(&addrtype,rmd160,address) < 0 ) + sprintf(buf,"{\"result\":\"success\",\"proof-of-work\":\"%.8f\",\"search-interval\": 0}",PoW_from_compact(coin->blocks.hwmchain.RO.bits,coin->chain->unitval)); + return(clonestr(buf)); + } else return(clonestr("{\"error\":\"getdifficulty needs coin\"}")); +} + +STRING_ARG(iguana,addcoin,newcoin) +{ + char *symbol,*seedip; int32_t retval; + if ( (symbol= newcoin) == 0 && coin != 0 ) + symbol = coin->symbol; + if ( symbol != 0 ) + { + if ( (seedip= jstr(json,"seedipaddr")) != 0 ) + safecopy(myinfo->seedipaddr,seedip,sizeof(myinfo->seedipaddr)); + printf(">> addcoin.%s seedipaddr.%s\n",symbol,myinfo->seedipaddr); +#ifdef __PNACL__ + // if ( strcmp(symbol,"BTC") == 0 ) + // return(clonestr("{\"result\":\"BTC for chrome app is not yet\"}")); +#endif + if ( (retval= iguana_launchcoin(myinfo,symbol,json,0)) > 0 ) { - jaddstr(retjson,"error","cant convert address"); - return(jprint(retjson,1)); + if ( myinfo->rpcsymbol[0] == 0 ) + safecopy(myinfo->rpcsymbol,symbol,sizeof(myinfo->rpcsymbol)); + return(clonestr("{\"result\":\"coin added\"}")); } - memset(pubkey33,0,sizeof(pubkey33)); - P = calloc(coin->bundlescount,sizeof(*P)); - array = cJSON_CreateArray(); - //printf("Start %s balance.(%s) height.%d\n",coin->symbol,address,lastheight); - if ( lastheight == 0 ) - lastheight = IGUANA_MAXHEIGHT; - iguana_RTpkhasharray(myinfo,coin,array,minconf,maxconf,&total,P,coin->bundlescount,rmd160,address,pubkey33,lastheight,0,0,0,remoteaddr,1); - free(P); - jadd(retjson,"unspents",array); - jaddnum(retjson,"balance",dstr(total)); - if ( lastheight > 0 ) - jaddnum(retjson,"RTheight",coin->RTheight); - } - return(jprint(retjson,1)); + else if ( retval == 0 ) + return(clonestr("{\"result\":\"coin already there\"}")); + else return(clonestr("{\"error\":\"error adding coin\"}")); + } else return(clonestr("{\"error\":\"addcoin needs newcoin\"}")); } -STRING_ARG(iguana,validate,activecoin) +STRING_ARG(iguana,startcoin,activecoin) { - int32_t i,total,validated; struct iguana_bundle *bp; cJSON *retjson; - if ( (coin= iguana_coinfind(activecoin)) != 0 ) + if ( coin != 0 ) { - for (i=total=validated=0; ibundlescount; i++) - if ( (bp= coin->bundles[i]) != 0 ) - { - validated += iguana_bundlevalidate(coin,bp,1); - total += bp->n; - } - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","validation run"); - jaddstr(retjson,"coin",coin->symbol); - jaddnum(retjson,"validated",validated); - jaddnum(retjson,"total",total); - jaddnum(retjson,"bundles",coin->bundlescount); - jaddnum(retjson,"accuracy",(double)validated/total); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no active coin\"}")); + coin->active = 1; + return(clonestr("{\"result\":\"coin started\"}")); + } else return(clonestr("{\"error\":\"startcoin needs coin\"}")); +} + +STRING_ARG(iguana,stopcoin,activecoin) +{ + if ( activecoin[0] != 0 ) + coin = iguana_coinfind(activecoin); + if ( coin != 0 ) + { + coin->active = 0; + //iguana_coinpurge(coin); + return(clonestr("{\"result\":\"coin stopped\"}")); + } else return(clonestr("{\"error\":\"stopcoin needs coin\"}")); } -STRING_ARG(iguana,removecoin,activecoin) +STRING_ARG(iguana,pausecoin,activecoin) { - struct iguana_bundle *bp; int32_t i,height; char fname[1024]; - if ( (coin= iguana_coinfind(activecoin)) != 0 ) + if ( coin != 0 ) { coin->active = 0; - coin->started = 0; - if ( 0 ) + return(clonestr("{\"result\":\"coin paused\"}")); + } else return(clonestr("{\"error\":\"pausecoin needs coin\"}")); +} + +TWO_STRINGS(iguana,addnode,activecoin,ipaddr) +{ + struct iguana_peer *addr; int32_t i,n; + if ( coin == 0 ) + coin = iguana_coinfind(activecoin); + if ( coin != 0 && strcmp(coin->symbol,"RELAY") == 0 ) + basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(ipaddr),GENESIS_PUBKEY); + printf("coin.%p.[%s] addnode.%s -> %s\n",coin,coin!=0?coin->symbol:"",activecoin,ipaddr); + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 ) + { + //iguana_possible_peer(coin,ipaddr); + if ( (addr= iguana_peerslot(coin,(uint32_t)calc_ipbits(ipaddr),1)) != 0 ) { - for (i=0; isupernet = 1; + if ( addr->usock >= 0 ) { - sprintf(fname,"%s/%s/vouts/%04d.vouts",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); - sprintf(fname,"%s/%s/%04d.vins",coin->VALIDATEDIR,coin->symbol,i), OS_removefile(fname,0); - } - sprintf(fname,"%s/%s/vouts/*",GLOBAL_DBDIR,coin->symbol), OS_removefile(fname,0); - sprintf(fname,"%s/%s/*",coin->VALIDATEDIR,coin->symbol), OS_removefile(fname,0); - for (i=0; ibundlescount; i++) - { - sprintf(fname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); - if ( (bp= coin->bundles[i]) != 0 ) + if ( (n= coin->peers->numranked) != 0 ) { - iguana_bundlepurgefiles(coin,bp); - iguana_bundleremove(coin,bp->hdrsi,1); + for (i=0; ipeers->ranked[i] ) + break; + } + if ( i == n ) + { + if ( i == IGUANA_MAXPEERS ) + i--; + else coin->peers->numranked = n+1; + coin->peers->ranked[i] = addr; + addr->recvblocks = coin->peers->ranked[0]->recvblocks + 100; + addr->recvtotal = coin->peers->ranked[0]->recvtotal*1.1 + 100; + printf("set (%s) -> slot.%d numranked.%d\n",ipaddr,i,coin->peers->numranked); + } else printf("(%s) is already peer.%d\n",ipaddr,i); } + return(clonestr("{\"result\":\"peer was already connected\"}")); } - for (height=0; heightlongestchain; height+=IGUANA_SUBDIRDIVISOR) + if ( addr->pending == 0 ) { - sprintf(fname,"%s/%s/%d",GLOBAL_DBDIR,coin->symbol,height/IGUANA_SUBDIRDIVISOR); - OS_remove_directory(fname); - } - sprintf(fname,"%s/%s/*",GLOBAL_DBDIR,coin->symbol), OS_remove_directory(fname); - } - return(clonestr("{\"result\":\"success\"}")); + addr->pending = (uint32_t)time(NULL); + iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); + return(clonestr("{\"result\":\"addnode submitted\"}")); + } else return(clonestr("{\"result\":\"addnode connection was already pending\"}")); + } else return(clonestr("{\"result\":\"addnode cant find peer slot\"}")); } - return(clonestr("{\"error\":\"no active coin\"}")); + else if ( coin == 0 ) + return(clonestr("{\"error\":\"addnode needs active coin, do an addcoin first\"}")); + else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); } -INT_ARG(bitcoinrpc,getblockhash,height) +TWO_STRINGS(iguana,persistent,activecoin,ipaddr) { - cJSON *retjson = cJSON_CreateObject(); - jaddbits256(retjson,"result",iguana_blockhash(coin,height)); - return(jprint(retjson,1)); + int32_t i; + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) + { + for (i=0; ipeers->active[i].ipaddr,ipaddr) == 0 ) + { + coin->peers->active[i].persistent_peer = juint(json,"interval")+3; + return(clonestr("{\"result\":\"node marked as persistent\"}")); + } + } + return(clonestr("{\"result\":\"node wasnt active\"}")); + } else return(clonestr("{\"error\":\"persistent needs coin and ipaddr\"}")); } -HASH_AND_TWOINTS(bitcoinrpc,getblock,blockhash,verbose,remoteonly) +TWO_STRINGS(iguana,removenode,activecoin,ipaddr) { - char *blockstr,*datastr; struct iguana_msgblock msg; struct iguana_block *block; cJSON *retjson; bits256 txid; int32_t len; - retjson = cJSON_CreateObject(); - memset(&msg,0,sizeof(msg)); - if ( remoteonly == 0 && (block= iguana_blockfind("getblockRPC",coin,blockhash)) != 0 ) + int32_t i; + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) { - if ( verbose != 0 ) - return(jprint(iguana_blockjson(coin,block,1),1)); - else + for (i=0; iblockspace,coin->blockspacesize,0,blockhash,0)) > 0 ) + if ( strcmp(coin->peers->active[i].ipaddr,ipaddr) == 0 ) { - datastr = malloc(len*2 + 1); - init_hexbytes_noT(datastr,coin->blockspace,len); - jaddstr(retjson,"result",datastr); - free(datastr); - return(jprint(retjson,1)); + coin->peers->active[i].rank = 0; + coin->peers->active[i].dead = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"node marked as dead\"}")); } - jaddstr(retjson,"error","error getting rawblock"); } - } - else if ( coin->APIblockstr != 0 ) - jaddstr(retjson,"error","already have pending request"); - else - { - memset(txid.bytes,0,sizeof(txid)); - if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,5)) != 0 ) - { - jaddstr(retjson,"result",blockstr); - free(blockstr); - } else jaddstr(retjson,"error","cant find blockhash"); - } - return(jprint(retjson,1)); + return(clonestr("{\"result\":\"node wasnt active\"}")); + } else return(clonestr("{\"error\":\"removenode needs coin and ipaddr\"}")); } -ZERO_ARGS(bitcoinrpc,getbestblockhash) +TWO_STRINGS(iguana,oneshot,activecoin,ipaddr) { - cJSON *retjson = cJSON_CreateObject(); - char str[65]; jaddstr(retjson,"result",bits256_str(str,coin->blocks.hwmchain.RO.hash2)); - return(jprint(retjson,1)); + if ( coin != 0 && ipaddr != 0 ) + { + iguana_possible_peer(coin,ipaddr); + return(clonestr("{\"result\":\"addnode submitted\"}")); + } else return(clonestr("{\"error\":\"addnode needs coin and ipaddr\"}")); } -ZERO_ARGS(bitcoinrpc,getblockcount) +cJSON *iguana_peerjson(struct iguana_info *coin,struct iguana_peer *addr) { - cJSON *retjson = cJSON_CreateObject(); - //printf("result %d\n",coin->blocks.hwmchain.height); - jaddnum(retjson,"result",coin->blocks.hwmchain.height); - return(jprint(retjson,1)); + cJSON *array,*json = cJSON_CreateObject(); + jaddstr(json,"ipaddr",addr->ipaddr); + if ( addr->supernet != 0 ) + jaddstr(json,"ipaddr",addr->ipaddr); + jaddstr(json,"supernet","yes"); + jaddnum(json,"protover",addr->protover); + jaddnum(json,"relay",addr->relayflag); + jaddnum(json,"height",addr->height); + jaddnum(json,"rank",addr->rank); + jaddnum(json,"usock",addr->usock); + if ( addr->dead != 0 ) + jaddnum(json,"dead",addr->dead); + jaddnum(json,"ready",addr->ready); + jaddnum(json,"recvblocks",addr->recvblocks); + jaddnum(json,"recvtotal",addr->recvtotal); + jaddnum(json,"lastcontact",addr->lastcontact); + if ( addr->numpings > 0 ) + jaddnum(json,"aveping",addr->pingsum/addr->numpings); + array = cJSON_CreateObject(); + jaddnum(array,"version",addr->msgcounts.version); + jaddnum(array,"verack",addr->msgcounts.verack); + jaddnum(array,"getaddr",addr->msgcounts.getaddr); + jaddnum(array,"addr",addr->msgcounts.addr); + jaddnum(array,"inv",addr->msgcounts.inv); + jaddnum(array,"getdata",addr->msgcounts.getdata); + jaddnum(array,"notfound",addr->msgcounts.notfound); + jaddnum(array,"getblocks",addr->msgcounts.getblocks); + jaddnum(array,"getheaders",addr->msgcounts.getheaders); + jaddnum(array,"headers",addr->msgcounts.headers); + jaddnum(array,"tx",addr->msgcounts.tx); + jaddnum(array,"block",addr->msgcounts.block); + jaddnum(array,"mempool",addr->msgcounts.mempool); + jaddnum(array,"ping",addr->msgcounts.ping); + jaddnum(array,"pong",addr->msgcounts.pong); + jaddnum(array,"reject",addr->msgcounts.reject); + jaddnum(array,"filterload",addr->msgcounts.filterload); + jaddnum(array,"filteradd",addr->msgcounts.filteradd); + jaddnum(array,"filterclear",addr->msgcounts.filterclear); + jaddnum(array,"merkleblock",addr->msgcounts.merkleblock); + jaddnum(array,"alert",addr->msgcounts.alert); + jadd(json,"msgcounts",array); + return(json); } -STRING_AND_INT(iguana,bundleaddresses,activecoin,height) +cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly) { - struct iguana_info *ptr; - if ( (ptr= iguana_coinfind(activecoin)) != 0 ) - return(iguana_bundleaddrs(ptr,height / coin->chain->bundlesize)); - else return(clonestr("{\"error\":\"activecoin is not active\"}")); + cJSON *retjson,*array; int32_t i; struct iguana_peer *addr; + if ( coin == 0 || coin->peers == 0 ) + return(0); + array = cJSON_CreateArray(); + for (i=0; iMAXPEERS; i++) + { + addr = &coin->peers->active[i]; + if ( addr->usock >= 0 && addr->ipbits != 0 && addr->ipaddr[0] != 0 ) + { + if ( addronly != 0 ) + jaddistr(array,addr->ipaddr); + else jaddi(array,iguana_peerjson(coin,addr)); + } + } + if ( addronly == 0 ) + { + retjson = cJSON_CreateObject(); + jadd(retjson,"peers",array); + jaddnum(retjson,"maxpeers",coin->MAXPEERS); + jaddstr(retjson,"coin",coin->symbol); + return(retjson); + } + else return(array); } -STRING_AND_INT(iguana,PoSweights,activecoin,height) +TWO_STRINGS(iguana,nodestatus,activecoin,ipaddr) { - struct iguana_info *ptr; int32_t num,nonz,errs,bundleheight; struct iguana_pkhash *refP; int64_t *weights,supply; cJSON *retjson; - if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + int32_t i; struct iguana_peer *addr; + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) { - //for (bundleheight=coin->chain->bundlesize; bundleheightchain->bundlesize) + for (i=0; iMAXPEERS; i++) { - bundleheight = (height / ptr->chain->bundlesize) * ptr->chain->bundlesize; - if ( (weights= iguana_PoS_weights(myinfo,ptr,&refP,&supply,&num,&nonz,&errs,bundleheight)) != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",errs == 0 ? "success" : "error"); - jaddnum(retjson,"bundleheight",bundleheight); - jaddnum(retjson,"numaddresses",num); - jaddnum(retjson,"nonzero",nonz); - jaddnum(retjson,"errors",errs); - jaddnum(retjson,"supply",dstr(supply)); - free(weights); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"iguana_PoS_weights returned null\"}")); + addr = &coin->peers->active[i]; + if ( strcmp(addr->ipaddr,ipaddr) == 0 ) + return(jprint(iguana_peerjson(coin,addr),1)); } - } - return(clonestr("{\"error\":\"activecoin is not active\"}")); + return(clonestr("{\"result\":\"nodestatus couldnt find ipaddr\"}")); + } else return(clonestr("{\"error\":\"nodestatus needs ipaddr\"}")); } -STRING_ARG(iguana,stakers,activecoin) +STRING_AND_INT(iguana,maxpeers,activecoin,max) { - struct iguana_info *ptr; int32_t i,datalen,pkind,hdrsi; bits256 hash2; struct iguana_bundle *bp; cJSON *retjson,*array; struct iguana_pkhash *refP; struct iguana_ramchaindata *rdata; char coinaddr[64]; uint8_t refrmd160[20]; bits256 *sortbuf; - if ( (ptr= iguana_coinfind(activecoin)) != 0 && ptr->RTheight > ptr->chain->bundlesize ) + cJSON *retjson; int32_t i; struct iguana_peer *addr; + if ( coin != 0 && coin->peers != 0 ) { - hdrsi = (ptr->RTheight / ptr->chain->bundlesize) - 1; - if ( (bp= ptr->bundles[hdrsi]) != 0 && bp->weights != 0 && (rdata= bp->ramchain.H.data) != 0 && bp->weights != 0 ) + retjson = cJSON_CreateObject(); + if ( max > IGUANA_MAXPEERS ) + max = IGUANA_MAXPEERS; + if ( max > coin->MAXPEERS ) { - sortbuf = calloc(bp->numweights,2 * sizeof(*sortbuf)); - for (i=datalen=0; inumweights; i++) - datalen += iguana_rwnum(1,&((uint8_t *)sortbuf)[datalen],sizeof(bp->weights[i]),(void *)&bp->weights[i]); - hash2 = bits256_doublesha256(0,(uint8_t *)sortbuf,datalen); - refP = RAMCHAIN_PTR(rdata,Poffset); - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - memset(refrmd160,0,sizeof(refrmd160)); - for (i=0; ichain->bundlesize; i++) - { - if ( (pkind= iguana_staker_sort(ptr,&hash2,refrmd160,refP,bp->weights,bp->numweights,sortbuf)) > 0 ) - { - bitcoin_address(coinaddr,ptr->chain->pubtype,refP[pkind].rmd160,sizeof(refP[pkind].rmd160)); - jaddistr(array,coinaddr); - } else jaddistr(array,"error"); - } - jaddstr(retjson,"result","success"); - jadd(retjson,"stakers",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"iguana_stakers needs PoSweights and weights\"}")); - } - return(clonestr("{\"error\":\"activecoin is not active\"}")); + for (i=max; iMAXPEERS; i++) + if ( (addr= coin->peers->ranked[i]) != 0 ) + addr->dead = 1; + } + coin->MAXPEERS = max; + jaddnum(retjson,"maxpeers",coin->MAXPEERS); + jaddstr(retjson,"coin",coin->symbol); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"maxpeers needs coin\"}")); } -STRING_AND_INT(iguana,bundlehashes,activecoin,height) +char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message),char *name,char *message,char *password) { - struct iguana_info *ptr; struct iguana_bundle *bp; int32_t i,hdrsi; cJSON *retjson,*array; struct iguana_ramchaindata *rdata; - if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + char hexstr[1025]; cJSON *json; + if ( message != 0 && password != 0 && message[0] != 0 && password[0] != 0 ) { - hdrsi = height / coin->chain->bundlesize; - if ( hdrsi < coin->bundlescount && hdrsi >= 0 && (bp= coin->bundles[hdrsi]) != 0 ) - { - if ( (rdata= bp->ramchain.H.data) != 0 ) - { - array = cJSON_CreateArray(); - for (i=0; ilhashes[i].txid); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","success"); - jaddbits256(retjson,"sha256",rdata->sha256); - jadd(retjson,"bundlehashes",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"ramchain not there\"}")); - } else return(clonestr("{\"error\":\"height is too big\"}")); - } else return(clonestr("{\"error\":\"activecoin is not active\"}")); + memset(hexstr,0,sizeof(hexstr)); + (*hmacfunc)(hexstr,password,password==0?0:(int32_t)strlen(password),message); + json = cJSON_CreateObject(); + jaddstr(json,"result","hmac calculated"); + jaddstr(json,"message",message); + jaddstr(json,name,hexstr); + return(jprint(json,1)); + } else return(clonestr("{\"error\":\"hmac needs message and passphrase\"}")); } -// low priority RPC +char *hash_dispatch(void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len),char *name,char *message) +{ + char hexstr[65537]; uint8_t databuf[32768]; cJSON *json; + if ( message != 0 && message[0] != 0 ) + { + memset(hexstr,0,sizeof(hexstr)); + (*hashfunc)(hexstr,databuf,(uint8_t *)message,(int32_t)strlen(message)); + json = cJSON_CreateObject(); + jaddstr(json,"result","hash calculated"); + jaddstr(json,"message",message); + jaddstr(json,name,hexstr); + return(jprint(json,1)); + } else return(clonestr("{\"error\":\"hash needs message\"}")); +} -HASH_AND_TWOINTS(bitcoinrpc,listsinceblock,blockhash,target,flag) +TWO_HASHES(hash,curve25519_pair,element,scalar) { - /*"transactions" : [ - { - "account" : "doc test", - "address" : "mmXgiR6KAhZCyQ8ndr2BCfEq1wNG2UnyG6", - "category" : "receive", - "amount" : 0.10000000, - "vout" : 0, - "confirmations" : 76478, - "blockhash" : "000000000017c84015f254498c62a7c884a51ccd75d4dd6dbdcb6434aa3bd44d", - "blockindex" : 1, - "blocktime" : 1399294967, - "txid" : "85a98fdf1529f7d5156483ad020a51b7f3340e47448cf932f470b72ff01a6821", - "walletconflicts" : [ - ], - "time" : 1399294967, - "timereceived" : 1418924714 - },*/ cJSON *retjson = cJSON_CreateObject(); - jaddstr(retjson,"error","low priority RPC not implemented"); + jaddbits256(retjson,"result",curve25519(element,scalar)); return(jprint(retjson,1)); } -ZERO_ARGS(bitcoinrpc,gettxoutsetinfo) +STRING_ARG(hash,NXT,passphrase) { return(hash_dispatch(calc_NXTaddr,"NXT",passphrase)); } +STRING_ARG(hash,curve25519,pubkey) { return(hash_dispatch(calc_curve25519_str,"curve25519",pubkey)); } +STRING_ARG(hash,crc32,message) { return(hash_dispatch(calc_crc32str,"crc32",message)); } +STRING_ARG(hash,base64_encode,message) { return(hash_dispatch(calc_base64_encodestr,"base64_encode",message)); } +STRING_ARG(hash,base64_decode,message) { return(hash_dispatch(calc_base64_decodestr,"base64_decode",message)); } +STRING_ARG(hash,rmd160_sha256,message) { return(hash_dispatch(rmd160ofsha256,"rmd160_sha256",message)); } +STRING_ARG(hash,sha256_sha256,message) { return(hash_dispatch(sha256_sha256,"sha256_sha256",message)); } +STRING_ARG(hash,hex,message) { return(hash_dispatch(calc_hexstr,"hex",message)); } +STRING_ARG(hash,unhex,message) { return(hash_dispatch(calc_unhexstr,"unhex",message)); } + +STRING_ARG(hash,sha224,message) { return(hash_dispatch(calc_sha224,"sha224",message)); } +STRING_ARG(hash,sha256,message) { return(hash_dispatch(vcalc_sha256,"sha256",message)); } +STRING_ARG(hash,sha384,message) { return(hash_dispatch(calc_sha384,"sha384",message)); } +STRING_ARG(hash,sha512,message) { return(hash_dispatch(calc_sha512,"sha512",message)); } +STRING_ARG(hash,rmd128,message) { return(hash_dispatch(calc_rmd128,"rmd128",message)); } +STRING_ARG(hash,rmd160,message) { return(hash_dispatch(calc_rmd160,"rmd160",message)); } +STRING_ARG(hash,rmd256,message) { return(hash_dispatch(calc_rmd256,"rmd256",message)); } +STRING_ARG(hash,rmd320,message) { return(hash_dispatch(calc_rmd320,"rmd320",message)); } +STRING_ARG(hash,sha1,message) { return(hash_dispatch(calc_sha1,"sha1",message)); } +STRING_ARG(hash,md2,message) { return(hash_dispatch(calc_md2str,"md2",message)); } +STRING_ARG(hash,md4,message) { return(hash_dispatch(calc_md4str,"md4",message)); } +STRING_ARG(hash,md5,message) { return(hash_dispatch(calc_md5str,"md5",message)); } +STRING_ARG(hash,tiger192_3,message) { return(hash_dispatch(calc_tiger,"tiger",message)); } +STRING_ARG(hash,whirlpool,message) { return(hash_dispatch(calc_whirlpool,"whirlpool",message)); } +TWO_STRINGS(hmac,sha224,message,passphrase) { return(hmac_dispatch(hmac_sha224_str,"sha224",message,passphrase)); } +TWO_STRINGS(hmac,sha256,message,passphrase) { return(hmac_dispatch(hmac_sha256_str,"sha256",message,passphrase)); } +TWO_STRINGS(hmac,sha384,message,passphrase) { return(hmac_dispatch(hmac_sha384_str,"sha384",message,passphrase)); } +TWO_STRINGS(hmac,sha512,message,passphrase) { return(hmac_dispatch(hmac_sha512_str,"sha512",message,passphrase)); } +TWO_STRINGS(hmac,rmd128,message,passphrase) { return(hmac_dispatch(hmac_rmd128_str,"rmd128",message,passphrase)); } +TWO_STRINGS(hmac,rmd160,message,passphrase) { return(hmac_dispatch(hmac_rmd160_str,"rmd160",message,passphrase)); } +TWO_STRINGS(hmac,rmd256,message,passphrase) { return(hmac_dispatch(hmac_rmd256_str,"rmd256",message,passphrase)); } +TWO_STRINGS(hmac,rmd320,message,passphrase) { return(hmac_dispatch(hmac_rmd320_str,"rmd320",message,passphrase)); } +TWO_STRINGS(hmac,sha1,message,passphrase) { return(hmac_dispatch(hmac_sha1_str,"sha1",message,passphrase)); } +TWO_STRINGS(hmac,md2,message,passphrase) { return(hmac_dispatch(hmac_md2_str,"md2",message,passphrase)); } +TWO_STRINGS(hmac,md4,message,passphrase) { return(hmac_dispatch(hmac_md4_str,"md4",message,passphrase)); } +TWO_STRINGS(hmac,md5,message,passphrase) { return(hmac_dispatch(hmac_md5_str,"md5",message,passphrase)); } +TWO_STRINGS(hmac,tiger192_3,message,passphrase) { return(hmac_dispatch(hmac_tiger_str,"tiger",message,passphrase)); } +TWO_STRINGS(hmac,whirlpool,message,passphrase) { return(hmac_dispatch(hmac_whirlpool_str,"whirlpool",message,passphrase)); } + +STRING_ARG(SuperNET,bitcoinrpc,setcoin) { - cJSON *retjson = cJSON_CreateObject(); - jaddstr(retjson,"error","low priority RPC not implemented"); - return(jprint(retjson,1)); + char buf[1024]; + if ( setcoin != 0 && setcoin[0] != 0 ) + { + strcpy(myinfo->rpcsymbol,setcoin); + touppercase(myinfo->rpcsymbol); + printf("bitcoinrpc.%s\n",myinfo->rpcsymbol); + if ( iguana_launchcoin(myinfo,myinfo->rpcsymbol,json,0) < 0 ) + return(clonestr("{\"error\":\"error creating coin\"}")); + else + { + sprintf(buf,"{\"result\":\"success\",\"setcoin\":\"%s\"}",setcoin); + return(clonestr(buf)); + } + } else return(clonestr("{\"error\":\"bitcoinrpc needs setcoin value\"}")); } -ZERO_ARGS(bitcoinrpc,listaddressgroupings) +ZERO_ARGS(SuperNET,help) { - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - return(clonestr("{\"error\":\"low priority RPC not implemented\"}")); + cJSON *helpjson,*retjson; + if ( (helpjson= SuperNET_helpjson()) != 0 ) + { + retjson = cJSON_CreateObject(); + jadd(retjson,"result",helpjson); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"cant get helpjson\"}")); } -SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment) +TWO_STRINGS(SuperNET,html,agentform,htmlfile) { - cJSON *retjson; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); + char *htmlstr; cJSON *retjson; int32_t max = 4*1024*1024; + if ( htmlfile == 0 || htmlfile[0] == 0 ) + htmlfile = "forms.html"; + //if ( (fp= fopen(htmlfile,"w")) == 0 ) + // printf("error opening htmlfile.(%s)\n",htmlfile); + htmlstr = malloc(max); + htmlstr = SuperNET_htmlstr(htmlfile,htmlstr,max,agentform); retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",htmlstr); + free(htmlstr); + //if ( fp != 0 ) + // fclose(fp); return(jprint(retjson,1)); } #undef IGUANA_ARGS +#undef _IGUANA_APIDEC_H_ #include "../includes/iguana_apiundefs.h" diff --git a/iguana/secp256k1/include/secp256k1.h b/iguana/secp256k1/include/secp256k1.h index 617493ae5..2c2042b7f 100644 --- a/iguana/secp256k1/include/secp256k1.h +++ b/iguana/secp256k1/include/secp256k1.h @@ -5,6 +5,9 @@ extern "C" { # endif +#undef HAVE_BUILTIN_EXPECT +#undef HAVE_BUILTIN_CLZLL + #include /* These rules specify the order of arguments in API calls: diff --git a/iguana/secp256k1/m_osx_release b/iguana/secp256k1/m_osx_release new file mode 100755 index 000000000..e962600e2 --- /dev/null +++ b/iguana/secp256k1/m_osx_release @@ -0,0 +1 @@ +gcc -mmacosx-version-min=10.6 -c -o ../secp256k1.o -I. -I./src -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c diff --git a/iguana/secp256k1/m_unix_Makefile b/iguana/secp256k1/m_unix_Makefile new file mode 100644 index 000000000..9457ed849 --- /dev/null +++ b/iguana/secp256k1/m_unix_Makefile @@ -0,0 +1,7 @@ +# author: fadedreamz@SuperNet.org +# date: August, 2017 + +all: + gcc -c -o ../secp256k1.o -I. -I./src -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c + +.PHONY: all diff --git a/iguana/secp256k1/src/ecmult_const_impl.h b/iguana/secp256k1/src/ecmult_const_impl.h index 90ac94770..1a1e1aea0 100644 --- a/iguana/secp256k1/src/ecmult_const_impl.h +++ b/iguana/secp256k1/src/ecmult_const_impl.h @@ -60,7 +60,7 @@ static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { int word = 0; /* 1 2 3 */ int u_last; - int u; + int u=0; #ifdef USE_ENDOMORPHISM int flip; diff --git a/iguana/secp256k1/src/modules/rangeproof/rangeproof_impl.h b/iguana/secp256k1/src/modules/rangeproof/rangeproof_impl.h index 22b245cf2..9d9fec476 100644 --- a/iguana/secp256k1/src/modules/rangeproof/rangeproof_impl.h +++ b/iguana/secp256k1/src/modules/rangeproof/rangeproof_impl.h @@ -406,7 +406,7 @@ SECP256K1_INLINE static void secp256k1_rangeproof_ch32xor(unsigned char *x, cons SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *blind,uint64_t *v, unsigned char *message,int *mlen,secp256k1_scalar *ev,secp256k1_scalar *s,int *rsizes,int rings, const unsigned char *nonce,const unsigned char *commit,const unsigned char *proof,int len) { - unsigned char prep[4096]; unsigned char tmp[32]; uint64_t value; int offset,i,j,b,skip1,skip2,npub; + unsigned char prep[4096]; unsigned char tmp[32]; uint64_t value=0; int offset,i,j,b,skip1,skip2,npub; secp256k1_scalar s_orig[128]; secp256k1_scalar sec[32]; secp256k1_scalar stmp; npub = ((rings - 1) << 2) + rsizes[rings-1]; VERIFY_CHECK(npub <= 128); diff --git a/iguana/secp256k1/src/modules/recovery/main_impl.h b/iguana/secp256k1/src/modules/recovery/main_impl.h index 12eed7eac..418c2f2f0 100644 --- a/iguana/secp256k1/src/modules/recovery/main_impl.h +++ b/iguana/secp256k1/src/modules/recovery/main_impl.h @@ -123,7 +123,7 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, cons int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { secp256k1_scalar r, s; secp256k1_scalar sec, non, msg; - int recid; + int recid = 0; int ret = 0; int overflow = 0; VERIFY_CHECK(ctx != NULL); diff --git a/iguana/secp256k1/src/util.h b/iguana/secp256k1/src/util.h index de4c2381e..24fe5c617 100644 --- a/iguana/secp256k1/src/util.h +++ b/iguana/secp256k1/src/util.h @@ -36,11 +36,15 @@ static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * } while(0) #endif +#ifndef WIN32 #ifdef HAVE_BUILTIN_EXPECT #define EXPECT(x,c) __builtin_expect((x),(c)) #else #define EXPECT(x,c) (x) #endif +#else +#define EXPECT(x,c) (x) +#endif #ifdef DETERMINISTIC #define CHECK(cond) do { \ @@ -90,12 +94,16 @@ SECP256K1_INLINE static int secp256k1_clz64_var(uint64_t x) { if (!x) { return 64; } +#ifndef WIN32 # if defined(HAVE_BUILTIN_CLZLL) ret = __builtin_clzll(x); # else /*FIXME: debruijn fallback. */ for (ret = 0; ((x & (1ULL << 63)) == 0); x <<= 1, ret++); # endif +#else + for (ret = 0; ((x & (1ULL << 63)) == 0); x <<= 1, ret++); +#endif return ret; } diff --git a/iguana/segwit_addr.c b/iguana/segwit_addr.c new file mode 100644 index 000000000..c3e030a87 --- /dev/null +++ b/iguana/segwit_addr.c @@ -0,0 +1,230 @@ +/* Copyright (c) 2017 Pieter Wuille + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include + +#include "segwit_addr.h" +#define BECH32_DELIM ':' + +/*uint32_t bech32_polymod_step(uint32_t pre) { + uint8_t b = pre >> 25; + return ((pre & 0x1FFFFFF) << 5) ^ + (-((b >> 0) & 1) & 0x3b6a57b2UL) ^ + (-((b >> 1) & 1) & 0x26508e6dUL) ^ + (-((b >> 2) & 1) & 0x1ea119faUL) ^ + (-((b >> 3) & 1) & 0x3d4233ddUL) ^ + (-((b >> 4) & 1) & 0x2a1462b3UL); +}*/ + +uint64_t PolyMod_step(uint64_t c,uint8_t d) +{ + uint8_t c0 = c >> 35; + //printf("step (%llx) + %d -> ",(long long)c,d); + c = ((c & 0x07ffffffff) << 5) ^ d; + if (c0 & 0x01) c ^= 0x98f2bc8e61; + if (c0 & 0x02) c ^= 0x79b76d99e2; + if (c0 & 0x04) c ^= 0xf33e5fb3c4; + if (c0 & 0x08) c ^= 0xae2eabe2a8; + if (c0 & 0x10) c ^= 0x1e4f43e470; + //printf("%llx\n",(long long)c); + return(c); +} + +static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; + +const int8_t charset_rev[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, 10, 17, 21, 20, 26, 30, 7, + 5, -1, -1, -1, -1, -1, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, + 31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, + -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 1, 0, + 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1}; + +int bech32_encode(char *output,const char *hrp,const uint8_t *data,int32_t data_len) +{ + uint64_t chk = 1; size_t i = 0; int32_t ch,chklen = 8; + while ( hrp[i] != 0 ) + { + ch = hrp[i]; + if ( ch < 33 || ch > 126 ) + { + printf("bech32_encode illegal ch.%d\n",ch); + return 0; + } + if ( ch >= 'A' && ch <= 'Z' ) + { + printf("bech32_encode illegal uppercase.%c\n",ch); + return 0; + } + i++; + } + //printf("bech32_encode after hrp.(%s)\n",hrp); + if ( i + chklen + 2 + data_len > 90 ) + return 0; + while ( *hrp != 0 ) + { + chk = PolyMod_step(chk,*hrp & 0x1f); + *(output++) = *(hrp++); + } + chk = PolyMod_step(chk,0); + *(output++) = BECH32_DELIM; + for (i=0; i> 5 ) + { + printf("bech32_encode out of band data.%c\n",*data); + return 0; + } + chk = PolyMod_step(chk,*data); + *(output++) = charset[*(data++)]; + } + for (i = 0; i < chklen; ++i) + chk = PolyMod_step(chk,0); + chk ^= 1; + //printf("bech32_encode emit >>>>>>> "); + for (i = 0; i < chklen; ++i) { + *output = charset[(chk >> ((chklen - 1 - i) * 5)) & 0x1f]; + //printf("%c",*output); + output++; + } + *output = 0; + //printf(" checksum %llx\n",(long long)chk); + return 1; +} + +int bech32_decode(char *hrp,uint8_t *data,int32_t *data_len,const char *input) +{ + uint64_t chk = 1; int32_t chklen = 8; size_t i,hrp_len,input_len = strlen(input); + int have_lower = 0, have_upper = 0; + if ( input_len < 8 || input_len > 90 ) + { + printf("bech32_decode: invalid input_len.%d\n",(int32_t)input_len); + return 0; + } + *data_len = 0; + while ( *data_len < input_len && input[(input_len - 1) - *data_len] != BECH32_DELIM ) + ++(*data_len); + hrp_len = input_len - (1 + *data_len); + if ( hrp_len < 1 || *data_len < chklen ) + { + printf("bech32_decode: invalid hrp_len.%d or datalen.%d\n",(int32_t)hrp_len,(int32_t)*data_len); + return 0; + } + *(data_len) -= chklen; + for (i=0; i 126 ) + { + printf("bech32_decode: invalid char.%d\n",ch); + return 0; + } + if ( ch >= 'a' && ch <= 'z' ) + have_lower = 1; + else if ( ch >= 'A' && ch <= 'Z' ) + { + have_upper = 1; + ch = (ch - 'A') + 'a'; + } + hrp[i] = ch; + chk = PolyMod_step(chk,ch & 0x1f); + } + hrp[i++] = 0; + chk = PolyMod_step(chk,0); + while ( i < input_len ) + { + int v = (input[i] & 0x80) ? -1 : charset_rev[(int)input[i]]; + if ( input[i] >= 'a' && input[i] <= 'z' ) + have_lower = 1; + else if ( input[i] >= 'A' && input[i] <= 'Z' ) + have_upper = 1; + if ( v == -1 ) + { + printf("bech32_decode: invalid v.%d from input.[%d] %d\n",(int32_t)v,(int32_t)i,(int32_t)input[i]); + return 0; + } + chk = PolyMod_step(chk,v); + if (i + chklen < input_len) + data[i - (1 + hrp_len)] = v; + ++i; + } + if ( have_lower && have_upper ) + { + printf("bech32_decode: have_lower.%d have_upper.%d\n",have_lower,have_upper); + return 0; + } + //printf("checksum chk.%llx lower.%d upper.%d inputlen.%d\n",(long long)chk,have_lower,have_upper,(int32_t)input_len); + return chk == 1; +} + +int bech32_convert_bits(uint8_t *out,int32_t *outlen,int outbits,const uint8_t *in,int32_t inlen,int inbits,int pad) +{ + uint32_t val = 0; + int bits = 0; + uint32_t maxv = (((uint32_t)1) << outbits) - 1; + while (inlen--) { + val = (val << inbits) | *(in++); + bits += inbits; + while (bits >= outbits) { + bits -= outbits; + out[(*outlen)++] = (val >> bits) & maxv; + } + } + if (pad) { + if (bits) { + out[(*outlen)++] = (val << (outbits - bits)) & maxv; + } + } else if (((val << (outbits - bits)) & maxv) || bits >= inbits) { + return 0; + } + return 1; +} + +/*int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) { + uint8_t data[65]; + size_t datalen = 0; + if (witver > 16) return 0; + if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0; + if (witprog_len < 2 || witprog_len > 40) return 0; + data[0] = witver; + convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1); + ++datalen; + return bech32_encode(output, hrp, data, datalen); +} + +int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) { + uint8_t data[84]; + char hrp_actual[84]; + size_t data_len; + if (!bech32_decode(hrp_actual, data, &data_len, addr)) return 0; + if (data_len == 0 || data_len > 65) return 0; + if (strncmp(hrp, hrp_actual, 84) != 0) return 0; + if (data[0] > 16) return 0; + *witdata_len = 0; + if (!convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0; + if (*witdata_len < 2 || *witdata_len > 40) return 0; + if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0; + *witver = data[0]; + return 1; +}*/ diff --git a/iguana/segwit_addr.h b/iguana/segwit_addr.h new file mode 100644 index 000000000..ed07b2db3 --- /dev/null +++ b/iguana/segwit_addr.h @@ -0,0 +1,89 @@ +/* Copyright (c) 2017 Pieter Wuille + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _SEGWIT_ADDR_H_ +#define _SEGWIT_ADDR_H_ 1 + +#include + +/** Encode a SegWit address + * + * Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be + * updated to contain the null-terminated address. + * In: hrp: Pointer to the null-terminated human readable part to use + * (chain/network specific). + * ver: Version of the witness program (between 0 and 16 inclusive). + * prog: Data bytes for the witness program (between 2 and 40 bytes). + * prog_len: Number of data bytes in prog. + * Returns 1 if successful. + */ +int segwit_addr_encode(char *output,const char *hrp,int ver,const uint8_t *prog,int32_t prog_len); + +/** Decode a SegWit address + * + * Out: ver: Pointer to an int that will be updated to contain the witness + * program version (between 0 and 16 inclusive). + * prog: Pointer to a buffer of size 40 that will be updated to + * contain the witness program bytes. + * prog_len: Pointer to a size_t that will be updated to contain the length + * of bytes in prog. + * hrp: Pointer to the null-terminated human readable part that is + * expected (chain/network specific). + * addr: Pointer to the null-terminated address. + * Returns 1 if successful. + */ +int segwit_addr_decode(int *ver,uint8_t *prog,int32_t *prog_len,const char *hrp,const char *addr); + +/** Encode a Bech32 string + * + * Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that + * will be updated to contain the null-terminated Bech32 string. + * In: hrp : Pointer to the null-terminated human readable part. + * data : Pointer to an array of 5-bit values. + * data_len: Length of the data array. + * Returns 1 if successful. + */ +int bech32_encode( + char *output, + const char *hrp, + const uint8_t *data, + int32_t data_len +); + +/** Decode a Bech32 string + * + * Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be + * updated to contain the null-terminated human readable part. + * data: Pointer to a buffer of size strlen(input) - 8 that will + * hold the encoded 5-bit data values. + * data_len: Pointer to a size_t that will be updated to be the number + * of entries in data. + * In: input: Pointer to a null-terminated Bech32 string. + * Returns 1 if succesful. + */ +int bech32_decode( + char *hrp, + uint8_t *data, + int32_t *data_len, + const char *input +); + +#endif diff --git a/iguana/sph_types.h b/iguana/sph_types.h new file mode 100644 index 000000000..3291dc7d8 --- /dev/null +++ b/iguana/sph_types.h @@ -0,0 +1,1966 @@ +/* $Id: sph_types.h 260 2011-07-21 01:02:38Z tp $ */ +/** + * Basic type definitions. + * + * This header file defines the generic integer types that will be used + * for the implementation of hash functions; it also contains helper + * functions which encode and decode multi-byte integer values, using + * either little-endian or big-endian conventions. + * + * This file contains a compile-time test on the size of a byte + * (the unsigned char C type). If bytes are not octets, + * i.e. if they do not have a size of exactly 8 bits, then compilation + * is aborted. Architectures where bytes are not octets are relatively + * rare, even in the embedded devices market. We forbid non-octet bytes + * because there is no clear convention on how octet streams are encoded + * on such systems. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @file sph_types.h + * @author Thomas Pornin + */ + +#ifndef SPH_TYPES_H__ +#define SPH_TYPES_H__ + +#include + +/* + * All our I/O functions are defined over octet streams. We do not know + * how to handle input data if bytes are not octets. + */ +#if CHAR_BIT != 8 +#error This code requires 8-bit bytes +#endif + +/* ============= BEGIN documentation block for Doxygen ============ */ + +#ifdef DOXYGEN_IGNORE + +/** @mainpage sphlib C code documentation + * + * @section overview Overview + * + * sphlib is a library which contains implementations of + * various cryptographic hash functions. These pages have been generated + * with doxygen and + * document the API for the C implementations. + * + * The API is described in appropriate header files, which are available + * in the "Files" section. Each hash function family has its own header, + * whose name begins with "sph_" and contains the family + * name. For instance, the API for the RIPEMD hash functions is available + * in the header file sph_ripemd.h. + * + * @section principles API structure and conventions + * + * @subsection io Input/output conventions + * + * In all generality, hash functions operate over strings of bits. + * Individual bits are rarely encountered in C programming or actual + * communication protocols; most protocols converge on the ubiquitous + * "octet" which is a group of eight bits. Data is thus expressed as a + * stream of octets. The C programming language contains the notion of a + * "byte", which is a data unit managed under the type "unsigned + * char". The C standard prescribes that a byte should hold at + * least eight bits, but possibly more. Most modern architectures, even + * in the embedded world, feature eight-bit bytes, i.e. map bytes to + * octets. + * + * Nevertheless, for some of the implemented hash functions, an extra + * API has been added, which allows the input of arbitrary sequences of + * bits: when the computation is about to be closed, 1 to 7 extra bits + * can be added. The functions for which this API is implemented include + * the SHA-2 functions and all SHA-3 candidates. + * + * sphlib defines hash function which may hash octet streams, + * i.e. streams of bits where the number of bits is a multiple of eight. + * The data input functions in the sphlib API expect data + * as anonymous pointers ("const void *") with a length + * (of type "size_t") which gives the input data chunk length + * in bytes. A byte is assumed to be an octet; the sph_types.h + * header contains a compile-time test which prevents compilation on + * architectures where this property is not met. + * + * The hash function output is also converted into bytes. All currently + * implemented hash functions have an output width which is a multiple of + * eight, and this is likely to remain true for new designs. + * + * Most hash functions internally convert input data into 32-bit of 64-bit + * words, using either little-endian or big-endian conversion. The hash + * output also often consists of such words, which are encoded into output + * bytes with a similar endianness convention. Some hash functions have + * been only loosely specified on that subject; when necessary, + * sphlib has been tested against published "reference" + * implementations in order to use the same conventions. + * + * @subsection shortname Function short name + * + * Each implemented hash function has a "short name" which is used + * internally to derive the identifiers for the functions and context + * structures which the function uses. For instance, MD5 has the short + * name "md5". Short names are listed in the next section, + * for the implemented hash functions. In subsequent sections, the + * short name will be assumed to be "XXX": replace with the + * actual hash function name to get the C identifier. + * + * Note: some functions within the same family share the same core + * elements, such as update function or context structure. Correspondingly, + * some of the defined types or functions may actually be macros which + * transparently evaluate to another type or function name. + * + * @subsection context Context structure + * + * Each implemented hash fonction has its own context structure, available + * under the type name "sph_XXX_context" for the hash function + * with short name "XXX". This structure holds all needed + * state for a running hash computation. + * + * The contents of these structures are meant to be opaque, and private + * to the implementation. However, these contents are specified in the + * header files so that application code which uses sphlib + * may access the size of those structures. + * + * The caller is responsible for allocating the context structure, + * whether by dynamic allocation (malloc() or equivalent), + * static allocation (a global permanent variable), as an automatic + * variable ("on the stack"), or by any other mean which ensures proper + * structure alignment. sphlib code performs no dynamic + * allocation by itself. + * + * The context must be initialized before use, using the + * sph_XXX_init() function. This function sets the context + * state to proper initial values for hashing. + * + * Since all state data is contained within the context structure, + * sphlib is thread-safe and reentrant: several hash + * computations may be performed in parallel, provided that they do not + * operate on the same context. Moreover, a running computation can be + * cloned by copying the context (with a simple memcpy()): + * the context and its clone are then independant and may be updated + * with new data and/or closed without interfering with each other. + * Similarly, a context structure can be moved in memory at will: + * context structures contain no pointer, in particular no pointer to + * themselves. + * + * @subsection dataio Data input + * + * Hashed data is input with the sph_XXX() fonction, which + * takes as parameters a pointer to the context, a pointer to the data + * to hash, and the number of data bytes to hash. The context is updated + * with the new data. + * + * Data can be input in one or several calls, with arbitrary input lengths. + * However, it is best, performance wise, to input data by relatively big + * chunks (say a few kilobytes), because this allows sphlib to + * optimize things and avoid internal copying. + * + * When all data has been input, the context can be closed with + * sph_XXX_close(). The hash output is computed and written + * into the provided buffer. The caller must take care to provide a + * buffer of appropriate length; e.g., when using SHA-1, the output is + * a 20-byte word, therefore the output buffer must be at least 20-byte + * long. + * + * For some hash functions, the sph_XXX_addbits_and_close() + * function can be used instead of sph_XXX_close(). This + * function can take a few extra bits to be added at + * the end of the input message. This allows hashing messages with a + * bit length which is not a multiple of 8. The extra bits are provided + * as an unsigned integer value, and a bit count. The bit count must be + * between 0 and 7, inclusive. The extra bits are provided as bits 7 to + * 0 (bits of numerical value 128, 64, 32... downto 0), in that order. + * For instance, to add three bits of value 1, 1 and 0, the unsigned + * integer will have value 192 (1*128 + 1*64 + 0*32) and the bit count + * will be 3. + * + * The SPH_SIZE_XXX macro is defined for each hash function; + * it evaluates to the function output size, expressed in bits. For instance, + * SPH_SIZE_sha1 evaluates to 160. + * + * When closed, the context is automatically reinitialized and can be + * immediately used for another computation. It is not necessary to call + * sph_XXX_init() after a close. Note that + * sph_XXX_init() can still be called to "reset" a context, + * i.e. forget previously input data, and get back to the initial state. + * + * @subsection alignment Data alignment + * + * "Alignment" is a property of data, which is said to be "properly + * aligned" when its emplacement in memory is such that the data can + * be optimally read by full words. This depends on the type of access; + * basically, some hash functions will read data by 32-bit or 64-bit + * words. sphlib does not mandate such alignment for input + * data, but using aligned data can substantially improve performance. + * + * As a rule, it is best to input data by chunks whose length (in bytes) + * is a multiple of eight, and which begins at "generally aligned" + * addresses, such as the base address returned by a call to + * malloc(). + * + * @section functions Implemented functions + * + * We give here the list of implemented functions. They are grouped by + * family; to each family corresponds a specific header file. Each + * individual function has its associated "short name". Please refer to + * the documentation for that header file to get details on the hash + * function denomination and provenance. + * + * Note: the functions marked with a '(64)' in the list below are + * available only if the C compiler provides an integer type of length + * 64 bits or more. Such a type is mandatory in the latest C standard + * (ISO 9899:1999, aka "C99") and is present in several older compilers + * as well, so chances are that such a type is available. + * + * - HAVAL family: file sph_haval.h + * - HAVAL-128/3 (128-bit, 3 passes): short name: haval128_3 + * - HAVAL-128/4 (128-bit, 4 passes): short name: haval128_4 + * - HAVAL-128/5 (128-bit, 5 passes): short name: haval128_5 + * - HAVAL-160/3 (160-bit, 3 passes): short name: haval160_3 + * - HAVAL-160/4 (160-bit, 4 passes): short name: haval160_4 + * - HAVAL-160/5 (160-bit, 5 passes): short name: haval160_5 + * - HAVAL-192/3 (192-bit, 3 passes): short name: haval192_3 + * - HAVAL-192/4 (192-bit, 4 passes): short name: haval192_4 + * - HAVAL-192/5 (192-bit, 5 passes): short name: haval192_5 + * - HAVAL-224/3 (224-bit, 3 passes): short name: haval224_3 + * - HAVAL-224/4 (224-bit, 4 passes): short name: haval224_4 + * - HAVAL-224/5 (224-bit, 5 passes): short name: haval224_5 + * - HAVAL-256/3 (256-bit, 3 passes): short name: haval256_3 + * - HAVAL-256/4 (256-bit, 4 passes): short name: haval256_4 + * - HAVAL-256/5 (256-bit, 5 passes): short name: haval256_5 + * - MD2: file sph_md2.h, short name: md2 + * - MD4: file sph_md4.h, short name: md4 + * - MD5: file sph_md5.h, short name: md5 + * - PANAMA: file sph_panama.h, short name: panama + * - RadioGatun family: file sph_radiogatun.h + * - RadioGatun[32]: short name: radiogatun32 + * - RadioGatun[64]: short name: radiogatun64 (64) + * - RIPEMD family: file sph_ripemd.h + * - RIPEMD: short name: ripemd + * - RIPEMD-128: short name: ripemd128 + * - RIPEMD-160: short name: ripemd160 + * - SHA-0: file sph_sha0.h, short name: sha0 + * - SHA-1: file sph_sha1.h, short name: sha1 + * - SHA-2 family, 32-bit hashes: file sph_sha2.h + * - SHA-224: short name: sha224 + * - SHA-256: short name: sha256 + * - SHA-384: short name: sha384 (64) + * - SHA-512: short name: sha512 (64) + * - Tiger family: file sph_tiger.h + * - Tiger: short name: tiger (64) + * - Tiger2: short name: tiger2 (64) + * - WHIRLPOOL family: file sph_whirlpool.h + * - WHIRLPOOL-0: short name: whirlpool0 (64) + * - WHIRLPOOL-1: short name: whirlpool1 (64) + * - WHIRLPOOL: short name: whirlpool (64) + * + * The fourteen second-round SHA-3 candidates are also implemented; + * when applicable, the implementations follow the "final" specifications + * as published for the third round of the SHA-3 competition (BLAKE, + * Groestl, JH, Keccak and Skein have been tweaked for third round). + * + * - BLAKE family: file sph_blake.h + * - BLAKE-224: short name: blake224 + * - BLAKE-256: short name: blake256 + * - BLAKE-384: short name: blake384 + * - BLAKE-512: short name: blake512 + * - BMW (Blue Midnight Wish) family: file sph_bmw.h + * - BMW-224: short name: bmw224 + * - BMW-256: short name: bmw256 + * - BMW-384: short name: bmw384 (64) + * - BMW-512: short name: bmw512 (64) + * - CubeHash family: file sph_cubehash.h (specified as + * CubeHash16/32 in the CubeHash specification) + * - CubeHash-224: short name: cubehash224 + * - CubeHash-256: short name: cubehash256 + * - CubeHash-384: short name: cubehash384 + * - CubeHash-512: short name: cubehash512 + * - ECHO family: file sph_echo.h + * - ECHO-224: short name: echo224 + * - ECHO-256: short name: echo256 + * - ECHO-384: short name: echo384 + * - ECHO-512: short name: echo512 + * - Fugue family: file sph_fugue.h + * - Fugue-224: short name: fugue224 + * - Fugue-256: short name: fugue256 + * - Fugue-384: short name: fugue384 + * - Fugue-512: short name: fugue512 + * - Groestl family: file sph_groestl.h + * - Groestl-224: short name: groestl224 + * - Groestl-256: short name: groestl256 + * - Groestl-384: short name: groestl384 + * - Groestl-512: short name: groestl512 + * - Hamsi family: file sph_hamsi.h + * - Hamsi-224: short name: hamsi224 + * - Hamsi-256: short name: hamsi256 + * - Hamsi-384: short name: hamsi384 + * - Hamsi-512: short name: hamsi512 + * - JH family: file sph_jh.h + * - JH-224: short name: jh224 + * - JH-256: short name: jh256 + * - JH-384: short name: jh384 + * - JH-512: short name: jh512 + * - Keccak family: file sph_keccak.h + * - Keccak-224: short name: keccak224 + * - Keccak-256: short name: keccak256 + * - Keccak-384: short name: keccak384 + * - Keccak-512: short name: keccak512 + * - Luffa family: file sph_luffa.h + * - Luffa-224: short name: luffa224 + * - Luffa-256: short name: luffa256 + * - Luffa-384: short name: luffa384 + * - Luffa-512: short name: luffa512 + * - Shabal family: file sph_shabal.h + * - Shabal-192: short name: shabal192 + * - Shabal-224: short name: shabal224 + * - Shabal-256: short name: shabal256 + * - Shabal-384: short name: shabal384 + * - Shabal-512: short name: shabal512 + * - SHAvite-3 family: file sph_shavite.h + * - SHAvite-224 (nominally "SHAvite-3 with 224-bit output"): + * short name: shabal224 + * - SHAvite-256 (nominally "SHAvite-3 with 256-bit output"): + * short name: shabal256 + * - SHAvite-384 (nominally "SHAvite-3 with 384-bit output"): + * short name: shabal384 + * - SHAvite-512 (nominally "SHAvite-3 with 512-bit output"): + * short name: shabal512 + * - SIMD family: file sph_simd.h + * - SIMD-224: short name: simd224 + * - SIMD-256: short name: simd256 + * - SIMD-384: short name: simd384 + * - SIMD-512: short name: simd512 + * - Skein family: file sph_skein.h + * - Skein-224 (nominally specified as Skein-512-224): short name: + * skein224 (64) + * - Skein-256 (nominally specified as Skein-512-256): short name: + * skein256 (64) + * - Skein-384 (nominally specified as Skein-512-384): short name: + * skein384 (64) + * - Skein-512 (nominally specified as Skein-512-512): short name: + * skein512 (64) + * + * For the second-round SHA-3 candidates, the functions are as specified + * for round 2, i.e. with the "tweaks" that some candidates added + * between round 1 and round 2. Also, some of the submitted packages for + * round 2 contained errors, in the specification, reference code, or + * both. sphlib implements the corrected versions. + */ + +/** @hideinitializer + * Unsigned integer type whose length is at least 32 bits; on most + * architectures, it will have a width of exactly 32 bits. Unsigned C + * types implement arithmetics modulo a power of 2; use the + * SPH_T32() macro to ensure that the value is truncated + * to exactly 32 bits. Unless otherwise specified, all macros and + * functions which accept sph_u32 values assume that these + * values fit on 32 bits, i.e. do not exceed 2^32-1, even on architectures + * where sph_u32 is larger than that. + */ +typedef __arch_dependant__ sph_u32; + +/** @hideinitializer + * Signed integer type corresponding to sph_u32; it has + * width 32 bits or more. + */ +typedef __arch_dependant__ sph_s32; + +/** @hideinitializer + * Unsigned integer type whose length is at least 64 bits; on most + * architectures which feature such a type, it will have a width of + * exactly 64 bits. C99-compliant platform will have this type; it + * is also defined when the GNU compiler (gcc) is used, and on + * platforms where unsigned long is large enough. If this + * type is not available, then some hash functions which depends on + * a 64-bit type will not be available (most notably SHA-384, SHA-512, + * Tiger and WHIRLPOOL). + */ +typedef __arch_dependant__ sph_u64; + +/** @hideinitializer + * Signed integer type corresponding to sph_u64; it has + * width 64 bits or more. + */ +typedef __arch_dependant__ sph_s64; + +/** + * This macro expands the token x into a suitable + * constant expression of type sph_u32. Depending on + * how this type is defined, a suffix such as UL may + * be appended to the argument. + * + * @param x the token to expand into a suitable constant expression + */ +#define SPH_C32(x) + +/** + * Truncate a 32-bit value to exactly 32 bits. On most systems, this is + * a no-op, recognized as such by the compiler. + * + * @param x the value to truncate (of type sph_u32) + */ +#define SPH_T32(x) + +/** + * Rotate a 32-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 31. This macro assumes that its + * first argument fits in 32 bits (no extra bit allowed on machines where + * sph_u32 is wider); both arguments may be evaluated + * several times. + * + * @param x the value to rotate (of type sph_u32) + * @param n the rotation count (between 1 and 31, inclusive) + */ +#define SPH_ROTL32(x, n) + +/** + * Rotate a 32-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 31. This macro assumes that its + * first argument fits in 32 bits (no extra bit allowed on machines where + * sph_u32 is wider); both arguments may be evaluated + * several times. + * + * @param x the value to rotate (of type sph_u32) + * @param n the rotation count (between 1 and 31, inclusive) + */ +#define SPH_ROTR32(x, n) + +/** + * This macro is defined on systems for which a 64-bit type has been + * detected, and is used for sph_u64. + */ +#define SPH_64 + +/** + * This macro is defined on systems for the "native" integer size is + * 64 bits (64-bit values fit in one register). + */ +#define SPH_64_TRUE + +/** + * This macro expands the token x into a suitable + * constant expression of type sph_u64. Depending on + * how this type is defined, a suffix such as ULL may + * be appended to the argument. This macro is defined only if a + * 64-bit type was detected and used for sph_u64. + * + * @param x the token to expand into a suitable constant expression + */ +#define SPH_C64(x) + +/** + * Truncate a 64-bit value to exactly 64 bits. On most systems, this is + * a no-op, recognized as such by the compiler. This macro is defined only + * if a 64-bit type was detected and used for sph_u64. + * + * @param x the value to truncate (of type sph_u64) + */ +#define SPH_T64(x) + +/** + * Rotate a 64-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 63. This macro assumes that its + * first argument fits in 64 bits (no extra bit allowed on machines where + * sph_u64 is wider); both arguments may be evaluated + * several times. This macro is defined only if a 64-bit type was detected + * and used for sph_u64. + * + * @param x the value to rotate (of type sph_u64) + * @param n the rotation count (between 1 and 63, inclusive) + */ +#define SPH_ROTL64(x, n) + +/** + * Rotate a 64-bit value by a number of bits to the left. The rotate + * count must reside between 1 and 63. This macro assumes that its + * first argument fits in 64 bits (no extra bit allowed on machines where + * sph_u64 is wider); both arguments may be evaluated + * several times. This macro is defined only if a 64-bit type was detected + * and used for sph_u64. + * + * @param x the value to rotate (of type sph_u64) + * @param n the rotation count (between 1 and 63, inclusive) + */ +#define SPH_ROTR64(x, n) + +/** + * This macro evaluates to inline or an equivalent construction, + * if available on the compilation platform, or to nothing otherwise. This + * is used to declare inline functions, for which the compiler should + * endeavour to include the code directly in the caller. Inline functions + * are typically defined in header files as replacement for macros. + */ +#define SPH_INLINE + +/** + * This macro is defined if the platform has been detected as using + * little-endian convention. This implies that the sph_u32 + * type (and the sph_u64 type also, if it is defined) has + * an exact width (i.e. exactly 32-bit, respectively 64-bit). + */ +#define SPH_LITTLE_ENDIAN + +/** + * This macro is defined if the platform has been detected as using + * big-endian convention. This implies that the sph_u32 + * type (and the sph_u64 type also, if it is defined) has + * an exact width (i.e. exactly 32-bit, respectively 64-bit). + */ +#define SPH_BIG_ENDIAN + +/** + * This macro is defined if 32-bit words (and 64-bit words, if defined) + * can be read from and written to memory efficiently in little-endian + * convention. This is the case for little-endian platforms, and also + * for the big-endian platforms which have special little-endian access + * opcodes (e.g. Ultrasparc). + */ +#define SPH_LITTLE_FAST + +/** + * This macro is defined if 32-bit words (and 64-bit words, if defined) + * can be read from and written to memory efficiently in big-endian + * convention. This is the case for little-endian platforms, and also + * for the little-endian platforms which have special big-endian access + * opcodes. + */ +#define SPH_BIG_FAST + +/** + * On some platforms, this macro is defined to an unsigned integer type + * into which pointer values may be cast. The resulting value can then + * be tested for being a multiple of 2, 4 or 8, indicating an aligned + * pointer for, respectively, 16-bit, 32-bit or 64-bit memory accesses. + */ +#define SPH_UPTR + +/** + * When defined, this macro indicates that unaligned memory accesses + * are possible with only a minor penalty, and thus should be prefered + * over strategies which first copy data to an aligned buffer. + */ +#define SPH_UNALIGNED + +/** + * Byte-swap a 32-bit word (i.e. 0x12345678 becomes + * 0x78563412). This is an inline function which resorts + * to inline assembly on some platforms, for better performance. + * + * @param x the 32-bit value to byte-swap + * @return the byte-swapped value + */ +static inline sph_u32 sph_bswap32(sph_u32 x); + +/** + * Byte-swap a 64-bit word. This is an inline function which resorts + * to inline assembly on some platforms, for better performance. This + * function is defined only if a suitable 64-bit type was found for + * sph_u64 + * + * @param x the 64-bit value to byte-swap + * @return the byte-swapped value + */ +static inline sph_u64 sph_bswap64(sph_u64 x); + +/** + * Decode a 16-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline unsigned sph_dec16le(const void *src); + +/** + * Encode a 16-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc16le(void *dst, unsigned val); + +/** + * Decode a 16-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline unsigned sph_dec16be(const void *src); + +/** + * Encode a 16-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc16be(void *dst, unsigned val); + +/** + * Decode a 32-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32le(const void *src); + +/** + * Decode a 32-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec32le() function. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32le_aligned(const void *src); + +/** + * Encode a 32-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32le(void *dst, sph_u32 val); + +/** + * Encode a 32-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc32le() function. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32le_aligned(void *dst, sph_u32 val); + +/** + * Decode a 32-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32be(const void *src); + +/** + * Decode a 32-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec32be() function. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u32 sph_dec32be_aligned(const void *src); + +/** + * Encode a 32-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32be(void *dst, sph_u32 val); + +/** + * Encode a 32-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc32be() function. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc32be_aligned(void *dst, sph_u32 val); + +/** + * Decode a 64-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64le(const void *src); + +/** + * Decode a 64-bit unsigned value from memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec64le() function. This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64le_aligned(const void *src); + +/** + * Encode a 64-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64le(void *dst, sph_u64 val); + +/** + * Encode a 64-bit unsigned value into memory, in little-endian convention + * (least significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc64le() function. This function is defined + * only if a suitable 64-bit type was detected and used for + * sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64le_aligned(void *dst, sph_u64 val); + +/** + * Decode a 64-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64be(const void *src); + +/** + * Decode a 64-bit unsigned value from memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * source address is suitably aligned for a direct access, if the platform + * supports such things; it can thus be marginally faster than the generic + * sph_dec64be() function. This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param src the source address + * @return the decoded value + */ +static inline sph_u64 sph_dec64be_aligned(const void *src); + +/** + * Encode a 64-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function is defined only + * if a suitable 64-bit type was detected and used for sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64be(void *dst, sph_u64 val); + +/** + * Encode a 64-bit unsigned value into memory, in big-endian convention + * (most significant byte comes first). This function assumes that the + * destination address is suitably aligned for a direct access, if the + * platform supports such things; it can thus be marginally faster than + * the generic sph_enc64be() function. This function is defined + * only if a suitable 64-bit type was detected and used for + * sph_u64. + * + * @param dst the destination buffer + * @param val the value to encode + */ +static inline void sph_enc64be_aligned(void *dst, sph_u64 val); + +#endif + +/* ============== END documentation block for Doxygen ============= */ + +#ifndef DOXYGEN_IGNORE + +/* + * We want to define the types "sph_u32" and "sph_u64" which hold + * unsigned values of at least, respectively, 32 and 64 bits. These + * tests should select appropriate types for most platforms. The + * macro "SPH_64" is defined if the 64-bit is supported. + */ + +#undef SPH_64 +#undef SPH_64_TRUE + +#if defined __STDC__ && __STDC_VERSION__ >= 199901L + +/* + * On C99 implementations, we can use to get an exact 64-bit + * type, if any, or otherwise use a wider type (which must exist, for + * C99 conformance). + */ + +#include + +#ifdef UINT32_MAX +typedef uint32_t sph_u32; +typedef int32_t sph_s32; +#else +typedef uint_fast32_t sph_u32; +typedef int_fast32_t sph_s32; +#endif +#if !SPH_NO_64 +#ifdef UINT64_MAX +typedef uint64_t sph_u64; +typedef int64_t sph_s64; +#else +typedef uint_fast64_t sph_u64; +typedef int_fast64_t sph_s64; +#endif +#endif + +#define SPH_C32(x) ((sph_u32)(x)) +#if !SPH_NO_64 +#define SPH_C64(x) ((sph_u64)(x)) +#define SPH_64 1 +#endif + +#else + +/* + * On non-C99 systems, we use "unsigned int" if it is wide enough, + * "unsigned long" otherwise. This supports all "reasonable" architectures. + * We have to be cautious: pre-C99 preprocessors handle constants + * differently in '#if' expressions. Hence the shifts to test UINT_MAX. + */ + +#if ((UINT_MAX >> 11) >> 11) >= 0x3FF + +typedef unsigned int sph_u32; +typedef int sph_s32; + +#define SPH_C32(x) ((sph_u32)(x ## U)) + +#else + +typedef unsigned long sph_u32; +typedef long sph_s32; + +#define SPH_C32(x) ((sph_u32)(x ## UL)) + +#endif + +#if !SPH_NO_64 + +/* + * We want a 64-bit type. We use "unsigned long" if it is wide enough (as + * is common on 64-bit architectures such as AMD64, Alpha or Sparcv9), + * "unsigned long long" otherwise, if available. We use ULLONG_MAX to + * test whether "unsigned long long" is available; we also know that + * gcc features this type, even if the libc header do not know it. + */ + +#if ((ULONG_MAX >> 31) >> 31) >= 3 + +typedef unsigned long sph_u64; +typedef long sph_s64; + +#define SPH_C64(x) ((sph_u64)(x ## UL)) + +#define SPH_64 1 + +#elif ((ULLONG_MAX >> 31) >> 31) >= 3 || defined __GNUC__ + +typedef unsigned long long sph_u64; +typedef long long sph_s64; + +#define SPH_C64(x) ((sph_u64)(x ## ULL)) + +#define SPH_64 1 + +#else + +/* + * No 64-bit type... + */ + +#endif + +#endif + +#endif + +/* + * If the "unsigned long" type has length 64 bits or more, then this is + * a "true" 64-bit architectures. This is also true with Visual C on + * amd64, even though the "long" type is limited to 32 bits. + */ +#if SPH_64 && (((ULONG_MAX >> 31) >> 31) >= 3 || defined _M_X64) +#define SPH_64_TRUE 1 +#endif + +/* + * Implementation note: some processors have specific opcodes to perform + * a rotation. Recent versions of gcc recognize the expression above and + * use the relevant opcodes, when appropriate. + */ + +#define SPH_T32(x) ((x) & SPH_C32(0xFFFFFFFF)) +#define SPH_ROTL32(x, n) SPH_T32(((x) << (n)) | ((x) >> (32 - (n)))) +#define SPH_ROTR32(x, n) SPH_ROTL32(x, (32 - (n))) + +#if SPH_64 + +#define SPH_T64(x) ((x) & SPH_C64(0xFFFFFFFFFFFFFFFF)) +#define SPH_ROTL64(x, n) SPH_T64(((x) << (n)) | ((x) >> (64 - (n)))) +#define SPH_ROTR64(x, n) SPH_ROTL64(x, (64 - (n))) + +#endif + +#ifndef DOXYGEN_IGNORE +/* + * Define SPH_INLINE to be an "inline" qualifier, if available. We define + * some small macro-like functions which benefit greatly from being inlined. + */ +#if (defined __STDC__ && __STDC_VERSION__ >= 199901L) || defined __GNUC__ +#define SPH_INLINE inline +#elif defined _MSC_VER +#define SPH_INLINE __inline +#else +#define SPH_INLINE +#endif +#endif + +/* + * We define some macros which qualify the architecture. These macros + * may be explicit set externally (e.g. as compiler parameters). The + * code below sets those macros if they are not already defined. + * + * Most macros are boolean, thus evaluate to either zero or non-zero. + * The SPH_UPTR macro is special, in that it evaluates to a C type, + * or is not defined. + * + * SPH_UPTR if defined: unsigned type to cast pointers into + * + * SPH_UNALIGNED non-zero if unaligned accesses are efficient + * SPH_LITTLE_ENDIAN non-zero if architecture is known to be little-endian + * SPH_BIG_ENDIAN non-zero if architecture is known to be big-endian + * SPH_LITTLE_FAST non-zero if little-endian decoding is fast + * SPH_BIG_FAST non-zero if big-endian decoding is fast + * + * If SPH_UPTR is defined, then encoding and decoding of 32-bit and 64-bit + * values will try to be "smart". Either SPH_LITTLE_ENDIAN or SPH_BIG_ENDIAN + * _must_ be non-zero in those situations. The 32-bit and 64-bit types + * _must_ also have an exact width. + * + * SPH_SPARCV9_GCC_32 UltraSPARC-compatible with gcc, 32-bit mode + * SPH_SPARCV9_GCC_64 UltraSPARC-compatible with gcc, 64-bit mode + * SPH_SPARCV9_GCC UltraSPARC-compatible with gcc + * SPH_I386_GCC x86-compatible (32-bit) with gcc + * SPH_I386_MSVC x86-compatible (32-bit) with Microsoft Visual C + * SPH_AMD64_GCC x86-compatible (64-bit) with gcc + * SPH_AMD64_MSVC x86-compatible (64-bit) with Microsoft Visual C + * SPH_PPC32_GCC PowerPC, 32-bit, with gcc + * SPH_PPC64_GCC PowerPC, 64-bit, with gcc + * + * TODO: enhance automatic detection, for more architectures and compilers. + * Endianness is the most important. SPH_UNALIGNED and SPH_UPTR help with + * some very fast functions (e.g. MD4) when using unaligned input data. + * The CPU-specific-with-GCC macros are useful only for inline assembly, + * normally restrained to this header file. + */ + +/* + * 32-bit x86, aka "i386 compatible". + */ +#if defined __i386__ || defined _M_IX86 + +#define SPH_DETECT_UNALIGNED 1 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u32 +#ifdef __GNUC__ +#define SPH_DETECT_I386_GCC 1 +#endif +#ifdef _MSC_VER +#define SPH_DETECT_I386_MSVC 1 +#endif + +/* + * 64-bit x86, hereafter known as "amd64". + */ +#elif defined __x86_64 || defined _M_X64 + +#define SPH_DETECT_UNALIGNED 1 +#define SPH_DETECT_LITTLE_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u64 +#ifdef __GNUC__ +#define SPH_DETECT_AMD64_GCC 1 +#endif +#ifdef _MSC_VER +#define SPH_DETECT_AMD64_MSVC 1 +#endif + +/* + * 64-bit Sparc architecture (implies v9). + */ +#elif ((defined __sparc__ || defined __sparc) && defined __arch64__) \ + || defined __sparcv9 + +#define SPH_DETECT_BIG_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u64 +#ifdef __GNUC__ +#define SPH_DETECT_SPARCV9_GCC_64 1 +#define SPH_DETECT_LITTLE_FAST 1 +#endif + +/* + * 32-bit Sparc. + */ +#elif (defined __sparc__ || defined __sparc) \ + && !(defined __sparcv9 || defined __arch64__) + +#define SPH_DETECT_BIG_ENDIAN 1 +#define SPH_DETECT_UPTR sph_u32 +#if defined __GNUC__ && defined __sparc_v9__ +#define SPH_DETECT_SPARCV9_GCC_32 1 +#define SPH_DETECT_LITTLE_FAST 1 +#endif + +/* + * ARM, little-endian. + */ +#elif defined __arm__ && __ARMEL__ + +#define SPH_DETECT_LITTLE_ENDIAN 1 + +/* + * MIPS, little-endian. + */ +#elif MIPSEL || _MIPSEL || __MIPSEL || __MIPSEL__ + +#define SPH_DETECT_LITTLE_ENDIAN 1 + +/* + * MIPS, big-endian. + */ +#elif MIPSEB || _MIPSEB || __MIPSEB || __MIPSEB__ + +#define SPH_DETECT_BIG_ENDIAN 1 + +/* + * PowerPC. + */ +#elif defined __powerpc__ || defined __POWERPC__ || defined __ppc__ \ + || defined _ARCH_PPC + +/* + * Note: we do not declare cross-endian access to be "fast": even if + * using inline assembly, implementation should still assume that + * keeping the decoded word in a temporary is faster than decoding + * it again. + */ +#if defined __GNUC__ +#if SPH_64_TRUE +#define SPH_DETECT_PPC64_GCC 1 +#else +#define SPH_DETECT_PPC32_GCC 1 +#endif +#endif + +#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN +#define SPH_DETECT_BIG_ENDIAN 1 +#elif defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN +#define SPH_DETECT_LITTLE_ENDIAN 1 +#endif + +/* + * Itanium, 64-bit. + */ +#elif defined __ia64 || defined __ia64__ \ + || defined __itanium__ || defined _M_IA64 + +#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN +#define SPH_DETECT_BIG_ENDIAN 1 +#else +#define SPH_DETECT_LITTLE_ENDIAN 1 +#endif +#if defined __LP64__ || defined _LP64 +#define SPH_DETECT_UPTR sph_u64 +#else +#define SPH_DETECT_UPTR sph_u32 +#endif + +#endif + +#if defined SPH_DETECT_SPARCV9_GCC_32 || defined SPH_DETECT_SPARCV9_GCC_64 +#define SPH_DETECT_SPARCV9_GCC 1 +#endif + +#if defined SPH_DETECT_UNALIGNED && !defined SPH_UNALIGNED +#define SPH_UNALIGNED SPH_DETECT_UNALIGNED +#endif +#if defined SPH_DETECT_UPTR && !defined SPH_UPTR +#define SPH_UPTR SPH_DETECT_UPTR +#endif +#if defined SPH_DETECT_LITTLE_ENDIAN && !defined SPH_LITTLE_ENDIAN +#define SPH_LITTLE_ENDIAN SPH_DETECT_LITTLE_ENDIAN +#endif +#if defined SPH_DETECT_BIG_ENDIAN && !defined SPH_BIG_ENDIAN +#define SPH_BIG_ENDIAN SPH_DETECT_BIG_ENDIAN +#endif +#if defined SPH_DETECT_LITTLE_FAST && !defined SPH_LITTLE_FAST +#define SPH_LITTLE_FAST SPH_DETECT_LITTLE_FAST +#endif +#if defined SPH_DETECT_BIG_FAST && !defined SPH_BIG_FAST +#define SPH_BIG_FAST SPH_DETECT_BIG_FAST +#endif +#if defined SPH_DETECT_SPARCV9_GCC_32 && !defined SPH_SPARCV9_GCC_32 +#define SPH_SPARCV9_GCC_32 SPH_DETECT_SPARCV9_GCC_32 +#endif +#if defined SPH_DETECT_SPARCV9_GCC_64 && !defined SPH_SPARCV9_GCC_64 +#define SPH_SPARCV9_GCC_64 SPH_DETECT_SPARCV9_GCC_64 +#endif +#if defined SPH_DETECT_SPARCV9_GCC && !defined SPH_SPARCV9_GCC +#define SPH_SPARCV9_GCC SPH_DETECT_SPARCV9_GCC +#endif +#if defined SPH_DETECT_I386_GCC && !defined SPH_I386_GCC +#define SPH_I386_GCC SPH_DETECT_I386_GCC +#endif +#if defined SPH_DETECT_I386_MSVC && !defined SPH_I386_MSVC +#define SPH_I386_MSVC SPH_DETECT_I386_MSVC +#endif +#if defined SPH_DETECT_AMD64_GCC && !defined SPH_AMD64_GCC +#define SPH_AMD64_GCC SPH_DETECT_AMD64_GCC +#endif +#if defined SPH_DETECT_AMD64_MSVC && !defined SPH_AMD64_MSVC +#define SPH_AMD64_MSVC SPH_DETECT_AMD64_MSVC +#endif +#if defined SPH_DETECT_PPC32_GCC && !defined SPH_PPC32_GCC +#define SPH_PPC32_GCC SPH_DETECT_PPC32_GCC +#endif +#if defined SPH_DETECT_PPC64_GCC && !defined SPH_PPC64_GCC +#define SPH_PPC64_GCC SPH_DETECT_PPC64_GCC +#endif + +#if SPH_LITTLE_ENDIAN && !defined SPH_LITTLE_FAST +#define SPH_LITTLE_FAST 1 +#endif +#if SPH_BIG_ENDIAN && !defined SPH_BIG_FAST +#define SPH_BIG_FAST 1 +#endif + +#if defined SPH_UPTR && !(SPH_LITTLE_ENDIAN || SPH_BIG_ENDIAN) +#error SPH_UPTR defined, but endianness is not known. +#endif + +#if SPH_I386_GCC && !SPH_NO_ASM + +/* + * On x86 32-bit, with gcc, we use the bswapl opcode to byte-swap 32-bit + * values. + */ + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + __asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} + +#if SPH_64 + +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + return ((sph_u64)sph_bswap32((sph_u32)x) << 32) + | (sph_u64)sph_bswap32((sph_u32)(x >> 32)); +} + +#endif + +#elif SPH_AMD64_GCC && !SPH_NO_ASM + +/* + * On x86 64-bit, with gcc, we use the bswapl opcode to byte-swap 32-bit + * and 64-bit values. + */ + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + __asm__ __volatile__ ("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} + +#if SPH_64 + +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + __asm__ __volatile__ ("bswapq %0" : "=r" (x) : "0" (x)); + return x; +} + +#endif + +/* + * Disabled code. Apparently, Microsoft Visual C 2005 is smart enough + * to generate proper opcodes for endianness swapping with the pure C + * implementation below. + * +#elif SPH_I386_MSVC && !SPH_NO_ASM +static __inline sph_u32 __declspec(naked) __fastcall +sph_bswap32(sph_u32 x) +{ + __asm { + bswap ecx + mov eax,ecx + ret + } +} +#if SPH_64 +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + return ((sph_u64)sph_bswap32((sph_u32)x) << 32) + | (sph_u64)sph_bswap32((sph_u32)(x >> 32)); +} +#endif + * + * [end of disabled code] + */ + +#else + +static SPH_INLINE sph_u32 +sph_bswap32(sph_u32 x) +{ + x = SPH_T32((x << 16) | (x >> 16)); + x = ((x & SPH_C32(0xFF00FF00)) >> 8) + | ((x & SPH_C32(0x00FF00FF)) << 8); + return x; +} + +#if SPH_64 + +/** + * Byte-swap a 64-bit value. + * + * @param x the input value + * @return the byte-swapped value + */ +static SPH_INLINE sph_u64 +sph_bswap64(sph_u64 x) +{ + x = SPH_T64((x << 32) | (x >> 32)); + x = ((x & SPH_C64(0xFFFF0000FFFF0000)) >> 16) + | ((x & SPH_C64(0x0000FFFF0000FFFF)) << 16); + x = ((x & SPH_C64(0xFF00FF00FF00FF00)) >> 8) + | ((x & SPH_C64(0x00FF00FF00FF00FF)) << 8); + return x; +} + +#endif + +#endif + +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + +/* + * On UltraSPARC systems, native ordering is big-endian, but it is + * possible to perform little-endian read accesses by specifying the + * address space 0x88 (ASI_PRIMARY_LITTLE). Basically, either we use + * the opcode "lda [%reg]0x88,%dst", where %reg is the register which + * contains the source address and %dst is the destination register, + * or we use "lda [%reg+imm]%asi,%dst", which uses the %asi register + * to get the address space name. The latter format is better since it + * combines an addition and the actual access in a single opcode; but + * it requires the setting (and subsequent resetting) of %asi, which is + * slow. Some operations (i.e. MD5 compression function) combine many + * successive little-endian read accesses, which may share the same + * %asi setting. The macros below contain the appropriate inline + * assembly. + */ + +#define SPH_SPARCV9_SET_ASI \ + sph_u32 sph_sparcv9_asi; \ + __asm__ __volatile__ ( \ + "rd %%asi,%0\n\twr %%g0,0x88,%%asi" : "=r" (sph_sparcv9_asi)); + +#define SPH_SPARCV9_RESET_ASI \ + __asm__ __volatile__ ("wr %%g0,%0,%%asi" : : "r" (sph_sparcv9_asi)); + +#define SPH_SPARCV9_DEC32LE(base, idx) ({ \ + sph_u32 sph_sparcv9_tmp; \ + __asm__ __volatile__ ("lda [%1+" #idx "*4]%%asi,%0" \ + : "=r" (sph_sparcv9_tmp) : "r" (base)); \ + sph_sparcv9_tmp; \ + }) + +#endif + +static SPH_INLINE void +sph_enc16be(void *dst, unsigned val) +{ + ((unsigned char *)dst)[0] = (val >> 8); + ((unsigned char *)dst)[1] = val; +} + +static SPH_INLINE unsigned +sph_dec16be(const void *src) +{ + return ((unsigned)(((const unsigned char *)src)[0]) << 8) + | (unsigned)(((const unsigned char *)src)[1]); +} + +static SPH_INLINE void +sph_enc16le(void *dst, unsigned val) +{ + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = val >> 8; +} + +static SPH_INLINE unsigned +sph_dec16le(const void *src) +{ + return (unsigned)(((const unsigned char *)src)[0]) + | ((unsigned)(((const unsigned char *)src)[1]) << 8); +} + +/** + * Encode a 32-bit value into the provided buffer (big endian convention). + * + * @param dst the destination buffer + * @param val the 32-bit value to encode + */ +static SPH_INLINE void +sph_enc32be(void *dst, sph_u32 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; +#else + if (((SPH_UPTR)dst & 3) == 0) { +#if SPH_LITTLE_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; + } else { + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; + } +#endif +#else + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (big endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (32-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc32be_aligned(void *dst, sph_u32 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u32 *)dst = sph_bswap32(val); +#elif SPH_BIG_ENDIAN + *(sph_u32 *)dst = val; +#else + ((unsigned char *)dst)[0] = (val >> 24); + ((unsigned char *)dst)[1] = (val >> 16); + ((unsigned char *)dst)[2] = (val >> 8); + ((unsigned char *)dst)[3] = val; +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (big endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32be(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif +#else + if (((SPH_UPTR)src & 3) == 0) { +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif + } else { + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); + } +#endif +#else + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (big endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (32-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32be_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#elif SPH_BIG_ENDIAN + return *(const sph_u32 *)src; +#else + return ((sph_u32)(((const unsigned char *)src)[0]) << 24) + | ((sph_u32)(((const unsigned char *)src)[1]) << 16) + | ((sph_u32)(((const unsigned char *)src)[2]) << 8) + | (sph_u32)(((const unsigned char *)src)[3]); +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (little endian convention). + * + * @param dst the destination buffer + * @param val the 32-bit value to encode + */ +static SPH_INLINE void +sph_enc32le(void *dst, sph_u32 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; +#else + if (((SPH_UPTR)dst & 3) == 0) { +#if SPH_BIG_ENDIAN + val = sph_bswap32(val); +#endif + *(sph_u32 *)dst = val; + } else { + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + } +#endif +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); +#endif +} + +/** + * Encode a 32-bit value into the provided buffer (little endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (32-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc32le_aligned(void *dst, sph_u32 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u32 *)dst = val; +#elif SPH_BIG_ENDIAN + *(sph_u32 *)dst = sph_bswap32(val); +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (little endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32le(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + return sph_bswap32(*(const sph_u32 *)src); +#else + return *(const sph_u32 *)src; +#endif +#else + if (((SPH_UPTR)src & 3) == 0) { +#if SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + sph_u32 tmp; + + /* + * "__volatile__" is needed here because without it, + * gcc-3.4.3 miscompiles the code and performs the + * access before the test on the address, thus triggering + * a bus error... + */ + __asm__ __volatile__ ( + "lda [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * On PowerPC, this turns out not to be worth the effort: the inline + * assembly makes GCC optimizer uncomfortable, which tends to nullify + * the decoding gains. + * + * For most hash functions, using this inline assembly trick changes + * hashing speed by less than 5% and often _reduces_ it. The biggest + * gains are for MD4 (+11%) and CubeHash (+30%). For all others, it is + * less then 10%. The speed gain on CubeHash is probably due to the + * chronic shortage of registers that CubeHash endures; for the other + * functions, the generic code appears to be efficient enough already. + * +#elif (SPH_PPC32_GCC || SPH_PPC64_GCC) && !SPH_NO_ASM + sph_u32 tmp; + __asm__ __volatile__ ( + "lwbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap32(*(const sph_u32 *)src); +#endif +#else + return *(const sph_u32 *)src; +#endif + } else { + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); + } +#endif +#else + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); +#endif +} + +/** + * Decode a 32-bit value from the provided buffer (little endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (32-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u32 +sph_dec32le_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return *(const sph_u32 *)src; +#elif SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC && !SPH_NO_ASM + sph_u32 tmp; + + __asm__ __volatile__ ("lda [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif (SPH_PPC32_GCC || SPH_PPC64_GCC) && !SPH_NO_ASM + sph_u32 tmp; + __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap32(*(const sph_u32 *)src); +#endif +#else + return (sph_u32)(((const unsigned char *)src)[0]) + | ((sph_u32)(((const unsigned char *)src)[1]) << 8) + | ((sph_u32)(((const unsigned char *)src)[2]) << 16) + | ((sph_u32)(((const unsigned char *)src)[3]) << 24); +#endif +} + +#if SPH_64 + +/** + * Encode a 64-bit value into the provided buffer (big endian convention). + * + * @param dst the destination buffer + * @param val the 64-bit value to encode + */ +static SPH_INLINE void +sph_enc64be(void *dst, sph_u64 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; +#else + if (((SPH_UPTR)dst & 7) == 0) { +#if SPH_LITTLE_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; + } else { + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; + } +#endif +#else + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (big endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (64-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc64be_aligned(void *dst, sph_u64 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u64 *)dst = sph_bswap64(val); +#elif SPH_BIG_ENDIAN + *(sph_u64 *)dst = val; +#else + ((unsigned char *)dst)[0] = (val >> 56); + ((unsigned char *)dst)[1] = (val >> 48); + ((unsigned char *)dst)[2] = (val >> 40); + ((unsigned char *)dst)[3] = (val >> 32); + ((unsigned char *)dst)[4] = (val >> 24); + ((unsigned char *)dst)[5] = (val >> 16); + ((unsigned char *)dst)[6] = (val >> 8); + ((unsigned char *)dst)[7] = val; +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (big endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64be(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif +#else + if (((SPH_UPTR)src & 7) == 0) { +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif + } else { + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); + } +#endif +#else + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (big endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (64-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64be_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#elif SPH_BIG_ENDIAN + return *(const sph_u64 *)src; +#else + return ((sph_u64)(((const unsigned char *)src)[0]) << 56) + | ((sph_u64)(((const unsigned char *)src)[1]) << 48) + | ((sph_u64)(((const unsigned char *)src)[2]) << 40) + | ((sph_u64)(((const unsigned char *)src)[3]) << 32) + | ((sph_u64)(((const unsigned char *)src)[4]) << 24) + | ((sph_u64)(((const unsigned char *)src)[5]) << 16) + | ((sph_u64)(((const unsigned char *)src)[6]) << 8) + | (sph_u64)(((const unsigned char *)src)[7]); +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (little endian convention). + * + * @param dst the destination buffer + * @param val the 64-bit value to encode + */ +static SPH_INLINE void +sph_enc64le(void *dst, sph_u64 val) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; +#else + if (((SPH_UPTR)dst & 7) == 0) { +#if SPH_BIG_ENDIAN + val = sph_bswap64(val); +#endif + *(sph_u64 *)dst = val; + } else { + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); + } +#endif +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); +#endif +} + +/** + * Encode a 64-bit value into the provided buffer (little endian convention). + * The destination buffer must be properly aligned. + * + * @param dst the destination buffer (64-bit aligned) + * @param val the value to encode + */ +static SPH_INLINE void +sph_enc64le_aligned(void *dst, sph_u64 val) +{ +#if SPH_LITTLE_ENDIAN + *(sph_u64 *)dst = val; +#elif SPH_BIG_ENDIAN + *(sph_u64 *)dst = sph_bswap64(val); +#else + ((unsigned char *)dst)[0] = val; + ((unsigned char *)dst)[1] = (val >> 8); + ((unsigned char *)dst)[2] = (val >> 16); + ((unsigned char *)dst)[3] = (val >> 24); + ((unsigned char *)dst)[4] = (val >> 32); + ((unsigned char *)dst)[5] = (val >> 40); + ((unsigned char *)dst)[6] = (val >> 48); + ((unsigned char *)dst)[7] = (val >> 56); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (little endian convention). + * + * @param src the source buffer + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64le(const void *src) +{ +#if defined SPH_UPTR +#if SPH_UNALIGNED +#if SPH_BIG_ENDIAN + return sph_bswap64(*(const sph_u64 *)src); +#else + return *(const sph_u64 *)src; +#endif +#else + if (((SPH_UPTR)src & 7) == 0) { +#if SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC_64 && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ( + "ldxa [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif SPH_PPC32_GCC && !SPH_NO_ASM + return (sph_u64)sph_dec32le_aligned(src) + | ((sph_u64)sph_dec32le_aligned( + (const char *)src + 4) << 32); +#elif SPH_PPC64_GCC && !SPH_NO_ASM + sph_u64 tmp; + __asm__ __volatile__ ( + "ldbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap64(*(const sph_u64 *)src); +#endif +#else + return *(const sph_u64 *)src; +#endif + } else { + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); + } +#endif +#else + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); +#endif +} + +/** + * Decode a 64-bit value from the provided buffer (little endian convention). + * The source buffer must be properly aligned. + * + * @param src the source buffer (64-bit aligned) + * @return the decoded value + */ +static SPH_INLINE sph_u64 +sph_dec64le_aligned(const void *src) +{ +#if SPH_LITTLE_ENDIAN + return *(const sph_u64 *)src; +#elif SPH_BIG_ENDIAN +#if SPH_SPARCV9_GCC_64 && !SPH_NO_ASM + sph_u64 tmp; + + __asm__ __volatile__ ("ldxa [%1]0x88,%0" : "=r" (tmp) : "r" (src)); + return tmp; +/* + * Not worth it generally. + * +#elif SPH_PPC32_GCC && !SPH_NO_ASM + return (sph_u64)sph_dec32le_aligned(src) + | ((sph_u64)sph_dec32le_aligned((const char *)src + 4) << 32); +#elif SPH_PPC64_GCC && !SPH_NO_ASM + sph_u64 tmp; + __asm__ __volatile__ ("ldbrx %0,0,%1" : "=r" (tmp) : "r" (src)); + return tmp; + */ +#else + return sph_bswap64(*(const sph_u64 *)src); +#endif +#else + return (sph_u64)(((const unsigned char *)src)[0]) + | ((sph_u64)(((const unsigned char *)src)[1]) << 8) + | ((sph_u64)(((const unsigned char *)src)[2]) << 16) + | ((sph_u64)(((const unsigned char *)src)[3]) << 24) + | ((sph_u64)(((const unsigned char *)src)[4]) << 32) + | ((sph_u64)(((const unsigned char *)src)[5]) << 40) + | ((sph_u64)(((const unsigned char *)src)[6]) << 48) + | ((sph_u64)(((const unsigned char *)src)[7]) << 56); +#endif +} + +#endif + +#endif /* Doxygen excluded block */ + +#endif diff --git a/iguana/swaps/iguana_BTCswap.c b/iguana/swaps/iguana_BTCswap.c index 9fe44f2bd..3cdaaf2f0 100755 --- a/iguana/swaps/iguana_BTCswap.c +++ b/iguana/swaps/iguana_BTCswap.c @@ -90,7 +90,7 @@ int32_t instantdex_bobscript(uint8_t *script,int32_t n,uint32_t *locktimep,int32 script[n++] = SCRIPT_OP_ELSE; if ( secretstartp != 0 ) *secretstartp = n + 2; - n = bitcoin_revealsecret160(script,n,secret160); + n = bitcoin_secret160verify(script,n,secret160); n = bitcoin_pubkeyspend(script,n,pubkeyB); script[n++] = SCRIPT_OP_ENDIF; return(n); @@ -164,7 +164,7 @@ void iguana_addinputs(struct iguana_info *coin,struct bitcoin_spend *spend,cJSON break; pubkeyptrs[j] = spend->inputs[i].pubkeys[j]; } - bitcoin_txinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,spend->inputs[i].sequence,spend->inputs[i].spendscript,spend->inputs[i].spendlen,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen,j>0?pubkeyptrs:0,j); + bitcoin_txinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,spend->inputs[i].sequence,spend->inputs[i].spendscript,spend->inputs[i].spendlen,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen,j>0?pubkeyptrs:0,j,0,0); } } @@ -1227,7 +1227,7 @@ char *instantdex_bailintx(struct iguana_info *coin,bits256 *txidp,struct bitcoin bitcoin_txoutput(coin,txobj,scriptv0,scriptv0len,spend->satoshis); if ( isbob != 0 ) { - scriptv1len = bitcoin_revealsecret160(scriptv1,0,x); + scriptv1len = bitcoin_secret160verify(scriptv1,0,x); scriptv1len = bitcoin_pubkeyspend(scriptv1,scriptv1len,pubkey); } else scriptv1len = bitcoin_p2shspend(scriptv1,0,x); bitcoin_txoutput(coin,txobj,scriptv1,scriptv1len,spend->txfee); @@ -1235,7 +1235,7 @@ char *instantdex_bailintx(struct iguana_info *coin,bits256 *txidp,struct bitcoin bitcoin_txoutput(coin,txobj,changescript,scriptv2len,change); for (i=0; inuminputs; i++) bitcoin_txinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,0xffffffff); - rawtxstr = bitcoin_json2hex(coin,&txid,txobj,0); + rawtxstr = bitcoin_json2hex(coin,&txid,txobj,0,0,0); char str[65]; printf("%s_bailin.%s (%s)\n",isbob!=0?"bob":"alice",bits256_str(str,txid),rawtxstr); V = calloc(spend->numinputs,sizeof(*V)); for (i=0; inuminputs; i++) @@ -1296,8 +1296,8 @@ char *instantdex_payouttx(struct iguana_info *coin,char *sigstr,int32_t *siglenp { struct vin_info V; cJSON *txobj; txobj = instantdex_bailinspend(coin,sharedprivs[1],amount); - bitcoin_txinput(coin,txobj,bailintxid,0,0xffffffff); - bitcoin_txinput(coin,txobj,bailintxid,1,0xffffffff); + bitcoin_txinput(coin,txobj,bailintxid,0,0xffffffff,0,0); + bitcoin_txinput(coin,txobj,bailintxid,1,0xffffffff,0,0); memset(&V,0,sizeof(V)); if ( othersigstr != 0 ) { @@ -1323,7 +1323,7 @@ char *instantdex_refundtx(struct iguana_info *coin,bits256 *txidp,bits256 bailin { char sigstr[256]; int32_t siglen; struct vin_info V; cJSON *txobj; txobj = instantdex_bailinspend(coin,priv2,amount - txfee); - bitcoin_txinput(coin,txobj,bailintxid,0,0xffffffff); + bitcoin_txinput(coin,txobj,bailintxid,0,0xffffffff,0,0); return(instantdex_bailinsign(coin,bailinpriv,sigstr,&siglen,txidp,&V,txobj,isbob)); } diff --git a/iguana/tests/Alistunspent b/iguana/tests/Alistunspent new file mode 100755 index 000000000..07f23d560 --- /dev/null +++ b/iguana/tests/Alistunspent @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"userpass\":\"username@password\",\"coin\":\"BTCD\",\"method\":\"listunspent\",\"params\":[1, 9999999, []]}" diff --git a/iguana/tests/DEX b/iguana/tests/DEX index 1a807d6d7..ee9dc0fb5 100755 --- a/iguana/tests/DEX +++ b/iguana/tests/DEX @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"genesis_opreturn\",\"vals\":{\"issuer\":\"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\",\"stake\":1000000,\"blocktime\":1,\"name\":\"InstantDEX\",\"symbol\":\"DEX\",\"p2sh\":5,\"wif\":128,\"nBits\":\"1effffff\"}}" diff --git a/iguana/tests/DEXinit b/iguana/tests/DEXinit new file mode 100755 index 000000000..63e43fe15 --- /dev/null +++ b/iguana/tests/DEXinit @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"init\"}" diff --git a/iguana/tests/DEXratio b/iguana/tests/DEXratio new file mode 100755 index 000000000..09365cc85 --- /dev/null +++ b/iguana/tests/DEXratio @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"ratio\":0.97,\"agent\":\"InstantDEX\",\"method\":\"DEXratio\"}" diff --git a/iguana/tests/DEXtx b/iguana/tests/DEXtx index 302997a86..644812e7c 100755 --- a/iguana/tests/DEXtx +++ b/iguana/tests/DEXtx @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"sendtoaddress\",\"params\":[\"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\", 0.0001, \"4e4557444558000000496e7374616e74444558000000000000407a10f35a0000dffc6993a2216d57ffffff1e1f4e010001000cba013c0580f1dce4182fce875748c4986b240ff7d7bc3fffb0\", \"sendcomment\"]}" diff --git a/iguana/tests/HOT b/iguana/tests/HOT index 261ef44ce..6820d3d21 100755 --- a/iguana/tests/HOT +++ b/iguana/tests/HOT @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"genesis_opreturn\",\"vals\":{\"issuer\":\"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\",\"stake\":1000000,\"blocktime\":1,\"name\":\"HOT ICO\",\"symbol\":\"HOT\",\"p2sh\":5,\"wif\":128,\"nBits\":\"1effffff\"}}" diff --git a/iguana/tests/HOTtx b/iguana/tests/HOTtx index f84d2d4b9..209088bf0 100755 --- a/iguana/tests/HOTtx +++ b/iguana/tests/HOTtx @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"sendtoaddress\",\"params\":[\"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\", 0.0001, \"4e4557484f54000000484f542049434f000000000000000000407a10f35a00007f53009145d46b57ffffff1e0000000001009577013c0580f1dce4182fce875748c4986b240ff7d7bc3fffb0\", \"sendcomment\"]}" diff --git a/iguana/tests/KMD.batch0.importaddress b/iguana/tests/KMD.batch0.importaddress new file mode 100755 index 000000000..d39c7234c --- /dev/null +++ b/iguana/tests/KMD.batch0.importaddress @@ -0,0 +1,889 @@ +# RG1QE6hTqu4dadL2XSNWS9VCHjd8xNVo58 KMD 16462.32091533, REVS 289.86606506 +# RG1QE6hTqu4dadL2XSNWS9VCHjd8xNVo58 KMD 16462.32091533 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG1QE6hTqu4dadL2XSNWS9VCHjd8xNVo58\",\"symbol\":\"KMD\"}" # 16462.32091533 +sleep 13 +# RFVvyUAnQe5yon6wq7B73Z1BzfFeZKyAZA KMD 74417.52897713, REVS 500.77700000 +# RFVvyUAnQe5yon6wq7B73Z1BzfFeZKyAZA KMD 74417.52897713 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFVvyUAnQe5yon6wq7B73Z1BzfFeZKyAZA\",\"symbol\":\"KMD\"}" # 74417.52897713 +sleep 13 +# RL9YVW2GxbYh6hM3D1J7Z2y4feK4MrwZqe KMD 9691.47954009 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL9YVW2GxbYh6hM3D1J7Z2y4feK4MrwZqe\",\"symbol\":\"KMD\"}" # 9691.47954009 +sleep 13 +# RRCwketDe8CXt4dMWpL4NpQntxJvmwousn KMD 201.21200152 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRCwketDe8CXt4dMWpL4NpQntxJvmwousn\",\"symbol\":\"KMD\"}" # 201.21200152 +sleep 13 +# RWfaj9ZNmHq5A4jV411xpt1FJoyvKfVJ6c KMD 616895.10028203, REVS 3685.61452692 +# RWfaj9ZNmHq5A4jV411xpt1FJoyvKfVJ6c KMD 616895.10028203 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWfaj9ZNmHq5A4jV411xpt1FJoyvKfVJ6c\",\"symbol\":\"KMD\"}" # 616895.10028203 +sleep 13 +# R9dTcQWVDuaRdFqDzq4xPaFDjGbaLK6t8n KMD 1053.37494565, REVS 4.29070721 +# R9dTcQWVDuaRdFqDzq4xPaFDjGbaLK6t8n KMD 1053.37494565 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9dTcQWVDuaRdFqDzq4xPaFDjGbaLK6t8n\",\"symbol\":\"KMD\"}" # 1053.37494565 +sleep 13 +# RDfCcqrNn8wgkr8CL29Z7PynpGP4w2ZySQ KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDfCcqrNn8wgkr8CL29Z7PynpGP4w2ZySQ\",\"symbol\":\"KMD\"}" # 774.65219950 +sleep 13 +# REvJWEuwqmwTnanZ8bWt85wnjfrsAjnvgE KMD 3945.67461320, REVS 30.24757576 +# REvJWEuwqmwTnanZ8bWt85wnjfrsAjnvgE KMD 3945.67461320 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REvJWEuwqmwTnanZ8bWt85wnjfrsAjnvgE\",\"symbol\":\"KMD\"}" # 3945.67461320 +sleep 13 +# RXb4SUn9mQ4Q1Fa8eehn5vitcfMMCjW2Ub KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXb4SUn9mQ4Q1Fa8eehn5vitcfMMCjW2Ub\",\"symbol\":\"KMD\"}" # 96831.52493750 +sleep 13 +# RBpEnyzuQNj1hNdAG1pKLALpAWEUS67PBj KMD 2729058.03025689, REVS 54178.00103054 +# RBpEnyzuQNj1hNdAG1pKLALpAWEUS67PBj KMD 2729058.03025689 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBpEnyzuQNj1hNdAG1pKLALpAWEUS67PBj\",\"symbol\":\"KMD\"}" # 2729058.03025689 +sleep 13 +# RGCCkHkLTkSiQFMeFvWSPzM2rNM3rrDkfw KMD 61869.43786697 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGCCkHkLTkSiQFMeFvWSPzM2rNM3rrDkfw\",\"symbol\":\"KMD\"}" # 61869.43786697 +sleep 13 +# RR6soE71ZggsYm6FeSVqebtn6oruYm3Xr8 KMD 94617.81776961 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR6soE71ZggsYm6FeSVqebtn6oruYm3Xr8\",\"symbol\":\"KMD\"}" # 94617.81776961 +sleep 13 +# RDobQ77wnMY8Me7RAL9oiFqVNvwkqqgPRF KMD 5315819.89184465 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDobQ77wnMY8Me7RAL9oiFqVNvwkqqgPRF\",\"symbol\":\"KMD\"}" # 5315819.89184465 +sleep 13 +# RHSZ1CWDNhkNbbQRDrqLHRAdCshueMrt2r KMD 8661.80183095, REVS 171.90929822 +# RHSZ1CWDNhkNbbQRDrqLHRAdCshueMrt2r KMD 8661.80183095 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHSZ1CWDNhkNbbQRDrqLHRAdCshueMrt2r\",\"symbol\":\"KMD\"}" # 8661.80183095 +sleep 13 +# RSY3GTogE7WfwukhaemrAZtPh6Gsy2q1XV KMD 4964.66964335 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSY3GTogE7WfwukhaemrAZtPh6Gsy2q1XV\",\"symbol\":\"KMD\"}" # 4964.66964335 +sleep 13 +# RM4RavnpbqkyB3cVq9tyzkoPuFZ2q87qqk KMD 17816.10973847 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM4RavnpbqkyB3cVq9tyzkoPuFZ2q87qqk\",\"symbol\":\"KMD\"}" # 17816.10973847 +sleep 13 +# RRMu7ikH1CVQmpY1vHWSZh7NTjVFbaAcUV KMD 699334.64129367 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRMu7ikH1CVQmpY1vHWSZh7NTjVFbaAcUV\",\"symbol\":\"KMD\"}" # 699334.64129367 +sleep 13 +# REyKZQ8q8xbRNCtpA5ABY1BsfscduWGgKv KMD 503444.41817988 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REyKZQ8q8xbRNCtpA5ABY1BsfscduWGgKv\",\"symbol\":\"KMD\"}" # 503444.41817988 +sleep 13 +# RTqh7gEJMJDpnBp62FZZAfXctj8X7sRRia KMD 18367.01200788, REVS 350.00000000 +# RTqh7gEJMJDpnBp62FZZAfXctj8X7sRRia KMD 18367.01200788 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTqh7gEJMJDpnBp62FZZAfXctj8X7sRRia\",\"symbol\":\"KMD\"}" # 18367.01200788 +sleep 13 +# RJZ2DjthdsfCuaGxiE1PNCUGuvARAsMpHn KMD 2848.88502056 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJZ2DjthdsfCuaGxiE1PNCUGuvARAsMpHn\",\"symbol\":\"KMD\"}" # 2848.88502056 +sleep 13 +# RTr3ghnoUgKMz7NVhcc2PEMmQ637J1P3CS KMD 1254936.56318998 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTr3ghnoUgKMz7NVhcc2PEMmQ637J1P3CS\",\"symbol\":\"KMD\"}" # 1254936.56318998 +sleep 13 +# REPaLcbXYKr7D6kx6M56bwwgC7QShb8gL7 KMD 107312.62836396 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REPaLcbXYKr7D6kx6M56bwwgC7QShb8gL7\",\"symbol\":\"KMD\"}" # 107312.62836396 +sleep 13 +# RY1n8qYX7hUVPiupbiX5zAbN4CtGpyKN5F KMD 368374.24120335 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY1n8qYX7hUVPiupbiX5zAbN4CtGpyKN5F\",\"symbol\":\"KMD\"}" # 368374.24120335 +sleep 13 +# RNhyF9U3o4hTgWqnwQjHwrD1o4GqWiP1T6 KMD 7816.63087181, REVS 78.63808960 +# RNhyF9U3o4hTgWqnwQjHwrD1o4GqWiP1T6 KMD 7816.63087181 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNhyF9U3o4hTgWqnwQjHwrD1o4GqWiP1T6\",\"symbol\":\"KMD\"}" # 7816.63087181 +sleep 13 +# RV3JsiGCq92BXiyo4JvRVJzTAm9RTdnNKn KMD 92958.26394000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV3JsiGCq92BXiyo4JvRVJzTAm9RTdnNKn\",\"symbol\":\"KMD\"}" # 92958.26394000 +sleep 13 +# RRMGMXyfD4ye9ebKwGWrAme3KU2CbaWy78 KMD 26149.64106420 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRMGMXyfD4ye9ebKwGWrAme3KU2CbaWy78\",\"symbol\":\"KMD\"}" # 26149.64106420 +sleep 13 +# RE3yR2mCeG15ARgvENMbb573VqoQJcM3po KMD 17738.87416605, REVS 18.61556549 +# RE3yR2mCeG15ARgvENMbb573VqoQJcM3po KMD 17738.87416605 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE3yR2mCeG15ARgvENMbb573VqoQJcM3po\",\"symbol\":\"KMD\"}" # 17738.87416605 +sleep 13 +# RF8Ua3mt2tMbwADn1XvYWxfJGz6fAnYBeq KMD 17817.00058850 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF8Ua3mt2tMbwADn1XvYWxfJGz6fAnYBeq\",\"symbol\":\"KMD\"}" # 17817.00058850 +sleep 13 +# RApWnKTepnDfPSDGX1wJnLXoNFCP5QzGWe KMD 928.65305676 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RApWnKTepnDfPSDGX1wJnLXoNFCP5QzGWe\",\"symbol\":\"KMD\"}" # 928.65305676 +sleep 13 +# RQjw6VEsAECmnKxXwwWCixCsz7gfFSaKsZ KMD 19137.10414825 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQjw6VEsAECmnKxXwwWCixCsz7gfFSaKsZ\",\"symbol\":\"KMD\"}" # 19137.10414825 +sleep 13 +# RWXYahA1NR6p5sBzXBknCaTDGmhSfhMV3a KMD 7891.18147631 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWXYahA1NR6p5sBzXBknCaTDGmhSfhMV3a\",\"symbol\":\"KMD\"}" # 7891.18147631 +sleep 13 +# RPkMn5ZH5E7xPbQdCYkZYx3WueAqYKVTyn KMD 259520.15743267 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPkMn5ZH5E7xPbQdCYkZYx3WueAqYKVTyn\",\"symbol\":\"KMD\"}" # 259520.15743267 +sleep 13 +# RA8GBwKDSyQas9uTAi6ThYi2jNXfrcbyZw KMD 3730.99968446 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA8GBwKDSyQas9uTAi6ThYi2jNXfrcbyZw\",\"symbol\":\"KMD\"}" # 3730.99968446 +sleep 13 +# RJ8QYKwegf7ApdYsWo3PXrGfX3nBvpN9Zn KMD 894973.14219837 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ8QYKwegf7ApdYsWo3PXrGfX3nBvpN9Zn\",\"symbol\":\"KMD\"}" # 894973.14219837 +sleep 13 +# RW3kA5hhT2Zi19ifVLWh3eHEbF7vGHp5xr KMD 722795.20152529 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW3kA5hhT2Zi19ifVLWh3eHEbF7vGHp5xr\",\"symbol\":\"KMD\"}" # 722795.20152529 +sleep 13 +# RHgNtXM72MHF8BtiD9mixaotZvb1W3LsN3 KMD 755.28589451 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHgNtXM72MHF8BtiD9mixaotZvb1W3LsN3\",\"symbol\":\"KMD\"}" # 755.28589451 +sleep 13 +# RWX3kh4b4vR2fsrgEm9SA4KQbWMaJEH5fa KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWX3kh4b4vR2fsrgEm9SA4KQbWMaJEH5fa\",\"symbol\":\"KMD\"}" # 19366.30498750 +sleep 13 +# RP38FcReMG1hqt4jjLVuGUzbQQPgNwEQ71 KMD 7523.80948764 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP38FcReMG1hqt4jjLVuGUzbQQPgNwEQ71\",\"symbol\":\"KMD\"}" # 7523.80948764 +sleep 13 +# RUUskhF2uWvRGsnTvhgjMkq48XgZ12EXuK KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUUskhF2uWvRGsnTvhgjMkq48XgZ12EXuK\",\"symbol\":\"KMD\"}" # 7746.52199500 +sleep 13 +# RT7ENMvL46nwrFfNj1TLa5FEqJzTztHefH KMD 26696.69308472, REVS 529.99000000 +# RT7ENMvL46nwrFfNj1TLa5FEqJzTztHefH KMD 26696.69308472 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT7ENMvL46nwrFfNj1TLa5FEqJzTztHefH\",\"symbol\":\"KMD\"}" # 26696.69308472 +sleep 13 +# RKyqUmtUmogi4qT5uWxvSh15TwFebrJS4B KMD 1711.08167983 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKyqUmtUmogi4qT5uWxvSh15TwFebrJS4B\",\"symbol\":\"KMD\"}" # 1711.08167983 +sleep 13 +# RCQGZn4x3AFjQJJwW6hFHfsiQQQ1pL2Kne KMD 1846.86875964 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCQGZn4x3AFjQJJwW6hFHfsiQQQ1pL2Kne\",\"symbol\":\"KMD\"}" # 1846.86875964 +sleep 13 +# RSHNubMtw3ZLmHy9QEkYmwPLy7vob6NvfP KMD 1092.25960129 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSHNubMtw3ZLmHy9QEkYmwPLy7vob6NvfP\",\"symbol\":\"KMD\"}" # 1092.25960129 +sleep 13 +# RDTcqgh4MMHLtu9FBCcULqZmP761DFmk9b KMD 82906.87674571, REVS 1438.93600000 +# RDTcqgh4MMHLtu9FBCcULqZmP761DFmk9b KMD 82906.87674571 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDTcqgh4MMHLtu9FBCcULqZmP761DFmk9b\",\"symbol\":\"KMD\"}" # 82906.87674571 +sleep 13 +# RWhJ879HiwHEb9sKbdhWQuoSQAFtC4G6t4 KMD 15493.04399000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWhJ879HiwHEb9sKbdhWQuoSQAFtC4G6t4\",\"symbol\":\"KMD\"}" # 15493.04399000 +sleep 13 +# RLS7frPLUVeNTMGQx6rBHYmcDgvNrT4cKN KMD 732.43675323 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLS7frPLUVeNTMGQx6rBHYmcDgvNrT4cKN\",\"symbol\":\"KMD\"}" # 732.43675323 +sleep 13 +# RTQknkEBMuz5i7m8ZM9BjbuFn8iXNxgeed KMD 5458.23813028 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTQknkEBMuz5i7m8ZM9BjbuFn8iXNxgeed\",\"symbol\":\"KMD\"}" # 5458.23813028 +sleep 13 +# RXfY8PwT85HVhK2cgV9uRpdaLQzTsR5g1y KMD 46479.13197000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXfY8PwT85HVhK2cgV9uRpdaLQzTsR5g1y\",\"symbol\":\"KMD\"}" # 46479.13197000 +sleep 13 +# RHSUmLRyJwpbdsRtytkGs9GmpZghQWHje3 KMD 2197.34858012, REVS 43.61040113 +# RHSUmLRyJwpbdsRtytkGs9GmpZghQWHje3 KMD 2197.34858012 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHSUmLRyJwpbdsRtytkGs9GmpZghQWHje3\",\"symbol\":\"KMD\"}" # 2197.34858012 +sleep 13 +# RJEQbNrMQUHELrYPVLPepR2Y3ruAag3hEP KMD 64966.39751162, REVS 1035.00000000 +# RJEQbNrMQUHELrYPVLPepR2Y3ruAag3hEP KMD 64966.39751162 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJEQbNrMQUHELrYPVLPepR2Y3ruAag3hEP\",\"symbol\":\"KMD\"}" # 64966.39751162 +sleep 13 +# RRBnn6p3pJfyrjFBrDrTD2RJg2AAQVSXa1 KMD 38732.60997500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRBnn6p3pJfyrjFBrDrTD2RJg2AAQVSXa1\",\"symbol\":\"KMD\"}" # 38732.60997500 +sleep 13 +# RJ1DUUySYib5LcwJKFJ78PD3so2GQ89jKJ KMD 377892.70160675, REVS 7501.00000000 +# RJ1DUUySYib5LcwJKFJ78PD3so2GQ89jKJ KMD 377892.70160675 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ1DUUySYib5LcwJKFJ78PD3so2GQ89jKJ\",\"symbol\":\"KMD\"}" # 377892.70160675 +sleep 13 +# RKtGS9q1vcReNcEtP3MzQjfjXyomLK2716 KMD 100542.16930966 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKtGS9q1vcReNcEtP3MzQjfjXyomLK2716\",\"symbol\":\"KMD\"}" # 100542.16930966 +sleep 13 +# R9YZPUTTVNcnKpuQ4JgMaxYzLXmeWA3msY KMD 96830.55662225 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9YZPUTTVNcnKpuQ4JgMaxYzLXmeWA3msY\",\"symbol\":\"KMD\"}" # 96830.55662225 +sleep 13 +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 2140.79273143 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" # 2140.79273143 +sleep 13 +# RF6eSvAE12JNFZ2eT9rwFti2CJT8m13gwA KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF6eSvAE12JNFZ2eT9rwFti2CJT8m13gwA\",\"symbol\":\"KMD\"}" # 968.31524937 +sleep 13 +# RC2nLGhFUc5Q9QFG1b38gAi9WgSgzQ9hJR KMD 41.38832712, REVS 0.82090537 +# RC2nLGhFUc5Q9QFG1b38gAi9WgSgzQ9hJR KMD 41.38832712 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC2nLGhFUc5Q9QFG1b38gAi9WgSgzQ9hJR\",\"symbol\":\"KMD\"}" # 41.38832712 +sleep 13 +# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 1350076.86672091, REVS 100.00000000 +# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 1350076.86672091 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8\",\"symbol\":\"KMD\"}" # 1350076.86672091 +sleep 13 +# RJbudEMb7wEEN8QZ18fEkptxjE4QnMECUu KMD 50567.04202258, REVS 1003.32000000 +# RJbudEMb7wEEN8QZ18fEkptxjE4QnMECUu KMD 50567.04202258 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJbudEMb7wEEN8QZ18fEkptxjE4QnMECUu\",\"symbol\":\"KMD\"}" # 50567.04202258 +sleep 13 +# RSdVypRznJsboL6MaP1shkaLhrVFcNx2KL KMD 589187.66272894, REVS 11685.49743445 +# RSdVypRznJsboL6MaP1shkaLhrVFcNx2KL KMD 589187.66272894 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSdVypRznJsboL6MaP1shkaLhrVFcNx2KL\",\"symbol\":\"KMD\"}" # 589187.66272894 +sleep 13 +# RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S KMD 100.59218694 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S\",\"symbol\":\"KMD\"}" # 100.59218694 +sleep 13 +# RWXwZyGf4q7cBakkY4tgupptBbCSvcBsBH KMD 1012.75625347, REVS 20.10000000 +# RWXwZyGf4q7cBakkY4tgupptBbCSvcBsBH KMD 1012.75625347 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWXwZyGf4q7cBakkY4tgupptBbCSvcBsBH\",\"symbol\":\"KMD\"}" # 1012.75625347 +sleep 13 +# RA7UJPwPxqgPHn4YscYWRH5EPQVaFaaaPa KMD 45132.81116316, REVS 342.26137428 +# RA7UJPwPxqgPHn4YscYWRH5EPQVaFaaaPa KMD 45132.81116316 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA7UJPwPxqgPHn4YscYWRH5EPQVaFaaaPa\",\"symbol\":\"KMD\"}" # 45132.81116316 +sleep 13 +# RUWFJ2c9CvJM8sp3YmaaN6EG58qkZ9M6ac KMD 5028.91865657 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUWFJ2c9CvJM8sp3YmaaN6EG58qkZ9M6ac\",\"symbol\":\"KMD\"}" # 5028.91865657 +sleep 13 +# RRFFxsc6kkfahR7v4paTaUZrPFisuz9Nkq KMD 155.36852443, REVS 3.08314987 +# RRFFxsc6kkfahR7v4paTaUZrPFisuz9Nkq KMD 155.36852443 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRFFxsc6kkfahR7v4paTaUZrPFisuz9Nkq\",\"symbol\":\"KMD\"}" # 155.36852443 +sleep 13 +# RKAkaVY1fgNKDbwSNiFKfWE9o5Rten6yQb KMD 15607.20311298 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKAkaVY1fgNKDbwSNiFKfWE9o5Rten6yQb\",\"symbol\":\"KMD\"}" # 15607.20311298 +sleep 13 +# RWFSbi9ECuZWVE37jpkbiKGw7DaFYdNtts KMD 23963.90703474, REVS 475.60756080 +# RWFSbi9ECuZWVE37jpkbiKGw7DaFYdNtts KMD 23963.90703474 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWFSbi9ECuZWVE37jpkbiKGw7DaFYdNtts\",\"symbol\":\"KMD\"}" # 23963.90703474 +sleep 13 +# RYQZmzckzB1gMYZQAYorYUcRuND8J6Lm4Z KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYQZmzckzB1gMYZQAYorYUcRuND8J6Lm4Z\",\"symbol\":\"KMD\"}" # 774.65219950 +sleep 13 +# RUVkn1F9g7TxoPbYtegiQoFnPTusP2gzDr KMD 43088.75849296, REVS 470.88002226 +# RUVkn1F9g7TxoPbYtegiQoFnPTusP2gzDr KMD 43088.75849296 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUVkn1F9g7TxoPbYtegiQoFnPTusP2gzDr\",\"symbol\":\"KMD\"}" # 43088.75849296 +sleep 13 +# RWDt2Xw6gHLdKdFEQFsNqAYYGUq37MvWYX KMD 19172.64193762 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWDt2Xw6gHLdKdFEQFsNqAYYGUq37MvWYX\",\"symbol\":\"KMD\"}" # 19172.64193762 +sleep 13 +# R9vBYQw9tSBhu2c1g4SQhZdhuZeeQrEBoN KMD 111664.10821907, REVS 2023.42268720 +# R9vBYQw9tSBhu2c1g4SQhZdhuZeeQrEBoN KMD 111664.10821907 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9vBYQw9tSBhu2c1g4SQhZdhuZeeQrEBoN\",\"symbol\":\"KMD\"}" # 111664.10821907 +sleep 13 +# RH2udBo3386n4hatBet85WUxiGao8VVSM6 KMD 4047.94506848 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH2udBo3386n4hatBet85WUxiGao8VVSM6\",\"symbol\":\"KMD\"}" # 4047.94506848 +sleep 13 +# RUFov2hPGqwtVTVVJGxUL5AGcyFSWmjRXe KMD 1011.40498451 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUFov2hPGqwtVTVVJGxUL5AGcyFSWmjRXe\",\"symbol\":\"KMD\"}" # 1011.40498451 +sleep 13 +# RG8g7LjK7hdyKp3aoKBRdwzpLy31XMXMLk KMD 972.80557592, REVS 19.29916914 +# RG8g7LjK7hdyKp3aoKBRdwzpLy31XMXMLk KMD 972.80557592 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG8g7LjK7hdyKp3aoKBRdwzpLy31XMXMLk\",\"symbol\":\"KMD\"}" # 972.80557592 +sleep 13 +# RTDNWLv3EJeKhhwrvBdKuxBLfWz7prmv9B KMD 2420.78812342 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTDNWLv3EJeKhhwrvBdKuxBLfWz7prmv9B\",\"symbol\":\"KMD\"}" # 2420.78812342 +sleep 13 +# RCdkLhDy7Ec2i7pwAsVmi1rnUufy2TEZmJ KMD 1589.10920508 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCdkLhDy7Ec2i7pwAsVmi1rnUufy2TEZmJ\",\"symbol\":\"KMD\"}" # 1589.10920508 +sleep 13 +# RJ7RfZfip4qL9uEJs7Wr9FYtGusQiryMqE KMD 43251.49599262, REVS 857.93461385 +# RJ7RfZfip4qL9uEJs7Wr9FYtGusQiryMqE KMD 43251.49599262 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ7RfZfip4qL9uEJs7Wr9FYtGusQiryMqE\",\"symbol\":\"KMD\"}" # 43251.49599262 +sleep 13 +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 53585.08128315, REVS 731.01000000 +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 53585.08128315 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY\",\"symbol\":\"KMD\"}" # 53585.08128315 +sleep 13 +# RRNkPd3BmppvxVxQCLzKfg2vVT2ypNcVxv KMD 4924.65994176 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRNkPd3BmppvxVxQCLzKfg2vVT2ypNcVxv\",\"symbol\":\"KMD\"}" # 4924.65994176 +sleep 13 +# RA2uJhw4TktHGHShKBTKoTaGjZSXU9Z2nX KMD 55939.57195639 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA2uJhw4TktHGHShKBTKoTaGjZSXU9Z2nX\",\"symbol\":\"KMD\"}" # 55939.57195639 +sleep 13 +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 57862.44847739, REVS 464.78017965 +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 57862.44847739 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" # 57862.44847739 +sleep 13 +# RSMNwfRUZxbE5YPud3PM46YYML8XsdELf6 KMD 11629.46614499 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSMNwfRUZxbE5YPud3PM46YYML8XsdELf6\",\"symbol\":\"KMD\"}" # 11629.46614499 +sleep 13 +# RUfJhANk7NzFapqGV1zamTgHm47LXsi8Zz KMD 2494.84014833 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUfJhANk7NzFapqGV1zamTgHm47LXsi8Zz\",\"symbol\":\"KMD\"}" # 2494.84014833 +sleep 13 +# RCyBEMjM6UgHAEosMCdxJb5VophihZ84hq KMD 755216.97171164 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCyBEMjM6UgHAEosMCdxJb5VophihZ84hq\",\"symbol\":\"KMD\"}" # 755216.97171164 +sleep 13 +# RSCe76vADETuwWAdga98c2LVdvKcNXeHmJ KMD 7436.66111520 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSCe76vADETuwWAdga98c2LVdvKcNXeHmJ\",\"symbol\":\"KMD\"}" # 7436.66111520 +sleep 13 +# RTkvmxME9rVZBY6ABNqkkbqKvn8WUqgQqr KMD 215743.93040290, REVS 4280.65926868 +# RTkvmxME9rVZBY6ABNqkkbqKvn8WUqgQqr KMD 215743.93040290 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTkvmxME9rVZBY6ABNqkkbqKvn8WUqgQqr\",\"symbol\":\"KMD\"}" # 215743.93040290 +sleep 13 +# R9Udy3hSfnsr6YuRkHXsuKWrZsd8oEm2jb KMD 1006939.18080157 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9Udy3hSfnsr6YuRkHXsuKWrZsd8oEm2jb\",\"symbol\":\"KMD\"}" # 1006939.18080157 +sleep 13 +# RAaQjULJVvG6LLF8NVKPidX1HYtrGSWbCN KMD 4005.10943567 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAaQjULJVvG6LLF8NVKPidX1HYtrGSWbCN\",\"symbol\":\"KMD\"}" # 4005.10943567 +sleep 13 +# RNBqCY6Mcp5ZLgL8R66FzvprYKhXaraeBb KMD 10117.34846003 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNBqCY6Mcp5ZLgL8R66FzvprYKhXaraeBb\",\"symbol\":\"KMD\"}" # 10117.34846003 +sleep 13 +# RCMjQirY1RqzJDEKLQjvN4Q35CHgy6LbEP KMD 1005.49855495 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCMjQirY1RqzJDEKLQjvN4Q35CHgy6LbEP\",\"symbol\":\"KMD\"}" # 1005.49855495 +sleep 13 +# RUtbAxmAqv1V47932T89tt79AN6TzazXSk KMD 1277.32401175 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUtbAxmAqv1V47932T89tt79AN6TzazXSk\",\"symbol\":\"KMD\"}" # 1277.32401175 +sleep 13 +# RS9erX84xJG17efdZ66qHxhsUMG15fnCsH KMD 977546.42205511, REVS 19403.85638743 +# RS9erX84xJG17efdZ66qHxhsUMG15fnCsH KMD 977546.42205511 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS9erX84xJG17efdZ66qHxhsUMG15fnCsH\",\"symbol\":\"KMD\"}" # 977546.42205511 +sleep 13 +# RMJp33AqgWV6oH4iLgN9XaXa2WThNdWdKL KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMJp33AqgWV6oH4iLgN9XaXa2WThNdWdKL\",\"symbol\":\"KMD\"}" # 8908.50029425 +sleep 13 +# RLG1kAeCLx4heef3FfqcqWe9ysR1BdNMoZ KMD 1394.37395910 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLG1kAeCLx4heef3FfqcqWe9ysR1BdNMoZ\",\"symbol\":\"KMD\"}" # 1394.37395910 +sleep 13 +# RE1wsrDNwW2NnNWM5eE162yp6haLtm5uh7 KMD 14588.33036215, REVS 289.61149547 +# RE1wsrDNwW2NnNWM5eE162yp6haLtm5uh7 KMD 14588.33036215 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1wsrDNwW2NnNWM5eE162yp6haLtm5uh7\",\"symbol\":\"KMD\"}" # 14588.33036215 +sleep 13 +# RRbV5dN4N7wUj3iLrv95SWJCZbtkV9uwoC KMD 18008.72700786 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRbV5dN4N7wUj3iLrv95SWJCZbtkV9uwoC\",\"symbol\":\"KMD\"}" # 18008.72700786 +sleep 13 +# RTwpYxfrofdzSYg55ci6Us48jHmtS4cjKk KMD 1626.76961895 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTwpYxfrofdzSYg55ci6Us48jHmtS4cjKk\",\"symbol\":\"KMD\"}" # 1626.76961895 +sleep 13 +# RP6fkbQibLJnKqJTogBpJ1sv6zX9b6widN KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP6fkbQibLJnKqJTogBpJ1sv6zX9b6widN\",\"symbol\":\"KMD\"}" # 722.28571081 +sleep 13 +# RB5AaE1vQKejds89eDxDzsWcDSfi8ixfbL KMD 9863.45132134 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB5AaE1vQKejds89eDxDzsWcDSfi8ixfbL\",\"symbol\":\"KMD\"}" # 9863.45132134 +sleep 13 +# RMPUMa3sjX98GG1RQunbc4mnTqUq4E6ZU3 KMD 83629.96327501 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMPUMa3sjX98GG1RQunbc4mnTqUq4E6ZU3\",\"symbol\":\"KMD\"}" # 83629.96327501 +sleep 13 +# RK5BnRzCP52qsTE4xR3Qysn6m6KeTgpZA6 KMD 3170.70655908, REVS 37.96790925 +# RK5BnRzCP52qsTE4xR3Qysn6m6KeTgpZA6 KMD 3170.70655908 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK5BnRzCP52qsTE4xR3Qysn6m6KeTgpZA6\",\"symbol\":\"KMD\"}" # 3170.70655908 +sleep 13 +# RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN KMD 11760.26545254 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN\",\"symbol\":\"KMD\"}" # 11760.26545254 +sleep 13 +# RN6TfTEYHdvFAeosYrvDaMBb2yBco47Q5a KMD 7073.16782615, REVS 44.30216197 +# RN6TfTEYHdvFAeosYrvDaMBb2yBco47Q5a KMD 7073.16782615 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN6TfTEYHdvFAeosYrvDaMBb2yBco47Q5a\",\"symbol\":\"KMD\"}" # 7073.16782615 +sleep 13 +# RV4Hf22arBv4P4s5eFsUAnXC6N11T8x9tv KMD 117108.97863641, REVS 1631.49836519 +# RV4Hf22arBv4P4s5eFsUAnXC6N11T8x9tv KMD 117108.97863641 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV4Hf22arBv4P4s5eFsUAnXC6N11T8x9tv\",\"symbol\":\"KMD\"}" # 117108.97863641 +sleep 13 +# RYBH6Ha8RJa3CcE91yxJP6z2E6mDFm3bBt KMD 163386.58575808, REVS 50.00000000 +# RYBH6Ha8RJa3CcE91yxJP6z2E6mDFm3bBt KMD 163386.58575808 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYBH6Ha8RJa3CcE91yxJP6z2E6mDFm3bBt\",\"symbol\":\"KMD\"}" # 163386.58575808 +sleep 13 +# RHBHVXLAnvB8y5itKBNxnM8w2zqDRGCg2q KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHBHVXLAnvB8y5itKBNxnM8w2zqDRGCg2q\",\"symbol\":\"KMD\"}" # 774.65219950 +sleep 13 +# RUY7YW1WmTD3hCvkXmUKLeRnNg5UsJoLbU KMD 6742.29255596, REVS 105.00000000 +# RUY7YW1WmTD3hCvkXmUKLeRnNg5UsJoLbU KMD 6742.29255596 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUY7YW1WmTD3hCvkXmUKLeRnNg5UsJoLbU\",\"symbol\":\"KMD\"}" # 6742.29255596 +sleep 13 +# RBxjj7kxFipThuHR9i3cyumFzM2c1puiua KMD 15493.04399000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBxjj7kxFipThuHR9i3cyumFzM2c1puiua\",\"symbol\":\"KMD\"}" # 15493.04399000 +sleep 13 +# REQqBMStNf7gWLxvG1a9KnbSgV78Hk19Js KMD 1936.63049875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REQqBMStNf7gWLxvG1a9KnbSgV78Hk19Js\",\"symbol\":\"KMD\"}" # 1936.63049875 +sleep 13 +# RNVwzuZynZ7d4DE5CfT8CWkxsp9TtCY3BF KMD 1598.36899361, REVS 11.75449303 +# RNVwzuZynZ7d4DE5CfT8CWkxsp9TtCY3BF KMD 1598.36899361 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNVwzuZynZ7d4DE5CfT8CWkxsp9TtCY3BF\",\"symbol\":\"KMD\"}" # 1598.36899361 +sleep 13 +# RHTDjCzn36ERtpE2DddYZq162EL9DZcsbK KMD 1341.60124279 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHTDjCzn36ERtpE2DddYZq162EL9DZcsbK\",\"symbol\":\"KMD\"}" # 1341.60124279 +sleep 13 +# RBBMrEHLVicGMQx1Do5FBUFP2tk5QiTD5a KMD 753.34926401 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBBMrEHLVicGMQx1Do5FBUFP2tk5QiTD5a\",\"symbol\":\"KMD\"}" # 753.34926401 +sleep 13 +# RWfVv2z5FrHmKPayFfSM4FZQpgBctbPHTk KMD 9212.17131564 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWfVv2z5FrHmKPayFfSM4FZQpgBctbPHTk\",\"symbol\":\"KMD\"}" # 9212.17131564 +sleep 13 +# RBy9jDvvNgvRGeyWh96rhvwLJ8zR44YTBj KMD 18464.80349033 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBy9jDvvNgvRGeyWh96rhvwLJ8zR44YTBj\",\"symbol\":\"KMD\"}" # 18464.80349033 +sleep 13 +# RMeXSe9FBfb7UA4rWKbbyUykF5SWsQFu2a KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMeXSe9FBfb7UA4rWKbbyUykF5SWsQFu2a\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 13 +# RHGSJf8UV9zJTdszmggAPdmNzzewrc5fnQ KMD 7019.31724271 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHGSJf8UV9zJTdszmggAPdmNzzewrc5fnQ\",\"symbol\":\"KMD\"}" # 7019.31724271 +sleep 13 +# RK7jYxdWFmDNEyutSbt5mLYdAdqsJv2E7A KMD 3975.36465037 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK7jYxdWFmDNEyutSbt5mLYdAdqsJv2E7A\",\"symbol\":\"KMD\"}" # 3975.36465037 +sleep 13 +# RUQYagJpBH5Enm8jRJcY4yfGUtKdXe5jLJ KMD 4066.92404737 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUQYagJpBH5Enm8jRJcY4yfGUtKdXe5jLJ\",\"symbol\":\"KMD\"}" # 4066.92404737 +sleep 13 +# RKNQdaiP4PivQqtE9wE3nPHFZkkBXSmprU KMD 2128.72487792 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKNQdaiP4PivQqtE9wE3nPHFZkkBXSmprU\",\"symbol\":\"KMD\"}" # 2128.72487792 +sleep 13 +# RKiCeCxYaJNGfgvkbH1RHsVctR3JWtDNw7 KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKiCeCxYaJNGfgvkbH1RHsVctR3JWtDNw7\",\"symbol\":\"KMD\"}" # 8908.50029425 +sleep 13 +# RU3zngUmo6Mg4kDSWdLazMS5ht1RxQ7DCM KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU3zngUmo6Mg4kDSWdLazMS5ht1RxQ7DCM\",\"symbol\":\"KMD\"}" # 774.65219950 +sleep 13 +# RMuMHC1Gp3b8yCUD5XsQH85QpfrRm1kLyS KMD 1470662.43386573 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMuMHC1Gp3b8yCUD5XsQH85QpfrRm1kLyS\",\"symbol\":\"KMD\"}" # 1470662.43386573 +sleep 13 +# RNScwyFBUV5yZz6svwsVD7fVDrAydrqFRG KMD 3692.08658052 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNScwyFBUV5yZz6svwsVD7fVDrAydrqFRG\",\"symbol\":\"KMD\"}" # 3692.08658052 +sleep 13 +# RYWjav2a7USMWe5qK2rtLkzRgE4Ciezb9Z KMD 1243.73516984 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYWjav2a7USMWe5qK2rtLkzRgE4Ciezb9Z\",\"symbol\":\"KMD\"}" # 1243.73516984 +sleep 13 +# RSbNJbs7PitRvqqVMdCpzD1yKBMM3gGAQb KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSbNJbs7PitRvqqVMdCpzD1yKBMM3gGAQb\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 13 +# RBbxPEyNRrJ5f3QtG6yz8hco3nFZPoLeUM KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBbxPEyNRrJ5f3QtG6yz8hco3nFZPoLeUM\",\"symbol\":\"KMD\"}" # 774.65219950 +sleep 13 +# RPriQZfzzgin7y2Ns6vxdrMAa4XgZqdY6y KMD 21671.70738465, REVS 170.69524117 +# RPriQZfzzgin7y2Ns6vxdrMAa4XgZqdY6y KMD 21671.70738465 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPriQZfzzgin7y2Ns6vxdrMAa4XgZqdY6y\",\"symbol\":\"KMD\"}" # 21671.70738465 +sleep 13 +# RFbaPjT7beKPWswQHcHSpicRJ35ZBMCPC4 KMD 4307.02827126 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFbaPjT7beKPWswQHcHSpicRJ35ZBMCPC4\",\"symbol\":\"KMD\"}" # 4307.02827126 +sleep 13 +# RSCdeeWvzpBhg2tKnCWZWKw9iAMyYWiREG KMD 12075.12037906, REVS 239.62000000 +# RSCdeeWvzpBhg2tKnCWZWKw9iAMyYWiREG KMD 12075.12037906 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSCdeeWvzpBhg2tKnCWZWKw9iAMyYWiREG\",\"symbol\":\"KMD\"}" # 12075.12037906 +sleep 13 +# RRjuStV5BMjwEueeEZT8DWBaUx9gQjRDLG KMD 1676.97635800 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRjuStV5BMjwEueeEZT8DWBaUx9gQjRDLG\",\"symbol\":\"KMD\"}" # 1676.97635800 +sleep 13 +# RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj KMD 25710.06172178, REVS 510.00000000 +# RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj KMD 25710.06172178 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj\",\"symbol\":\"KMD\"}" # 25710.06172178 +sleep 13 +# RDs6US7EYgfFrKiPzMFT84PcoQWUCniwky KMD 4453.35929709 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDs6US7EYgfFrKiPzMFT84PcoQWUCniwky\",\"symbol\":\"KMD\"}" # 4453.35929709 +sleep 13 +# RQuMEMn1TG7CCpbmYCVcDfPqesEvEkisjC KMD 34758.47429765, REVS 689.94006658 +# RQuMEMn1TG7CCpbmYCVcDfPqesEvEkisjC KMD 34758.47429765 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQuMEMn1TG7CCpbmYCVcDfPqesEvEkisjC\",\"symbol\":\"KMD\"}" # 34758.47429765 +sleep 13 +# RVptmyXVcTSkZQNd7UMgDz73p3AdfsamLS KMD 6487.71217081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVptmyXVcTSkZQNd7UMgDz73p3AdfsamLS\",\"symbol\":\"KMD\"}" # 6487.71217081 +sleep 13 +# REe9cFdWLNNDbCgWMNHAYBU4hBjUsu8zgY KMD 4003.40256701 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REe9cFdWLNNDbCgWMNHAYBU4hBjUsu8zgY\",\"symbol\":\"KMD\"}" # 4003.40256701 +sleep 13 +# RBNB5mKstG86jYRjrKFgJuFoUFvZKJb9Wq KMD 816561.67159376, REVS 16199.49755302 +# RBNB5mKstG86jYRjrKFgJuFoUFvZKJb9Wq KMD 816561.67159376 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBNB5mKstG86jYRjrKFgJuFoUFvZKJb9Wq\",\"symbol\":\"KMD\"}" # 816561.67159376 +sleep 13 +# RHoouCBBapEHE6uyX7CxHGFcRwUQFGMot5 KMD 88331.27512150, REVS 1398.88449696 +# RHoouCBBapEHE6uyX7CxHGFcRwUQFGMot5 KMD 88331.27512150 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHoouCBBapEHE6uyX7CxHGFcRwUQFGMot5\",\"symbol\":\"KMD\"}" # 88331.27512150 +sleep 13 +# RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 541891.46150744 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz\",\"symbol\":\"KMD\"}" # 541891.46150744 +sleep 13 +# RLHEGDwXuXQwhYkrhwSRGSJMFuvv7EAT7i KMD 22366.16022678, REVS 443.95821128 +# RLHEGDwXuXQwhYkrhwSRGSJMFuvv7EAT7i KMD 22366.16022678 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLHEGDwXuXQwhYkrhwSRGSJMFuvv7EAT7i\",\"symbol\":\"KMD\"}" # 22366.16022678 +sleep 13 +# RMWZenedfv1AQtuJw1EzYj9R2FxwzFpd54 KMD 4454.25014712 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMWZenedfv1AQtuJw1EzYj9R2FxwzFpd54\",\"symbol\":\"KMD\"}" # 4454.25014712 +sleep 13 +# RAEtFUqe3jwVxLywCga2eKQxT2DiewsUuN KMD 25.54297774, REVS 0.50680815 +# RAEtFUqe3jwVxLywCga2eKQxT2DiewsUuN KMD 25.54297774 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAEtFUqe3jwVxLywCga2eKQxT2DiewsUuN\",\"symbol\":\"KMD\"}" # 25.54297774 +sleep 13 +# RUcDMtu7fA3ATbHHsDTsZ8KThgd1ivawym KMD 21446.21749875, REVS 241.00000000 +# RUcDMtu7fA3ATbHHsDTsZ8KThgd1ivawym KMD 21446.21749875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUcDMtu7fA3ATbHHsDTsZ8KThgd1ivawym\",\"symbol\":\"KMD\"}" # 21446.21749875 +sleep 13 +# RDndtdqjEgQ2kyiCzpeWEtf9TSDJnMBvao KMD 1093.79403237 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDndtdqjEgQ2kyiCzpeWEtf9TSDJnMBvao\",\"symbol\":\"KMD\"}" # 1093.79403237 +sleep 13 +# RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 KMD 102137.83664315, REVS 2027.11216000 +# RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 KMD 102137.83664315 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4\",\"symbol\":\"KMD\"}" # 102137.83664315 +sleep 13 +# RSFJ19qzQbtYJQD98pqpkTNoBEi9gM31TA KMD 15451.81049286 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSFJ19qzQbtYJQD98pqpkTNoBEi9gM31TA\",\"symbol\":\"KMD\"}" # 15451.81049286 +sleep 13 +# R9gDQRa62Eg24qwZd3Pv374bYbWf4BSLZs KMD 4066.92404737 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9gDQRa62Eg24qwZd3Pv374bYbWf4BSLZs\",\"symbol\":\"KMD\"}" # 4066.92404737 +sleep 13 +# RTh7GDBqLRDMYLdQyE7HHooBobztNXfsdW KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTh7GDBqLRDMYLdQyE7HHooBobztNXfsdW\",\"symbol\":\"KMD\"}" # 968.31524937 +sleep 13 +# RKEkubK347PwSM9SQ9eReFng1yFrEbGN8C KMD 11415.41169287 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKEkubK347PwSM9SQ9eReFng1yFrEbGN8C\",\"symbol\":\"KMD\"}" # 11415.41169287 +sleep 13 +# RHMKLGnyum4miEW55qL8Mawv7KdGsjbmAB KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHMKLGnyum4miEW55qL8Mawv7KdGsjbmAB\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 13 +# REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf KMD 130928.69826981, REVS 2597.54928401 +# REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf KMD 130928.69826981 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf\",\"symbol\":\"KMD\"}" # 130928.69826981 +sleep 13 +# RTuiEzbcX7N1j1oXSwBbRE5n8s31wzyuXQ KMD 8948.17705032 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTuiEzbcX7N1j1oXSwBbRE5n8s31wzyuXQ\",\"symbol\":\"KMD\"}" # 8948.17705032 +sleep 13 +# RVcyGvC5uYhT1UguHu1wgHxSTH6JEx8NHP KMD 5117.51239557 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVcyGvC5uYhT1UguHu1wgHxSTH6JEx8NHP\",\"symbol\":\"KMD\"}" # 5117.51239557 +sleep 13 +# RQKrkjKAvhPvhB3f9yAjipBPutJAP7TA32 KMD 3721.26805123 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQKrkjKAvhPvhB3f9yAjipBPutJAP7TA32\",\"symbol\":\"KMD\"}" # 3721.26805123 +sleep 13 +# RFwK8bejf6ANo61ipukbXxto15z55CwRUm KMD 4360.41373744 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFwK8bejf6ANo61ipukbXxto15z55CwRUm\",\"symbol\":\"KMD\"}" # 4360.41373744 +sleep 13 +# RFHBwfH6pSfzaw3WDvV84ii4SGvGpEtgjJ KMD 26947.73503767 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFHBwfH6pSfzaw3WDvV84ii4SGvGpEtgjJ\",\"symbol\":\"KMD\"}" # 26947.73503767 +sleep 13 +# RXKZmFmmpfAV2DAdUUXhA88RqCoyPRXcnA KMD 28641.72782430, REVS 337.66808110 +# RXKZmFmmpfAV2DAdUUXhA88RqCoyPRXcnA KMD 28641.72782430 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXKZmFmmpfAV2DAdUUXhA88RqCoyPRXcnA\",\"symbol\":\"KMD\"}" # 28641.72782430 +sleep 13 +# RCxnQhmYdpK9vTS7PLRtXBtDk2HaRNo1qk KMD 2171.04073365, REVS 43.05910000 +# RCxnQhmYdpK9vTS7PLRtXBtDk2HaRNo1qk KMD 2171.04073365 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCxnQhmYdpK9vTS7PLRtXBtDk2HaRNo1qk\",\"symbol\":\"KMD\"}" # 2171.04073365 +sleep 13 +# RNFLSwnYtoA5Gjb1eHDszeGLtxaE9yPiFp KMD 56753.10185822 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNFLSwnYtoA5Gjb1eHDszeGLtxaE9yPiFp\",\"symbol\":\"KMD\"}" # 56753.10185822 +sleep 13 +# RPtwW4UejbAxs5PU6a1zMPcPqW7SVghMDS KMD 31741.86724191, REVS 514.45537037 +# RPtwW4UejbAxs5PU6a1zMPcPqW7SVghMDS KMD 31741.86724191 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPtwW4UejbAxs5PU6a1zMPcPqW7SVghMDS\",\"symbol\":\"KMD\"}" # 31741.86724191 +sleep 13 +# RYWPYz5qotHsukbFpzRksctMUBobmWLdkG KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYWPYz5qotHsukbFpzRksctMUBobmWLdkG\",\"symbol\":\"KMD\"}" # 9295.82639400 +sleep 13 +# RBnTykMEj7GPYN1v8VtE9rrPvggZGuHzct KMD 4841.57624687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBnTykMEj7GPYN1v8VtE9rrPvggZGuHzct\",\"symbol\":\"KMD\"}" # 4841.57624687 +sleep 13 +# RYMzZx5nxKrMtTm3TNeheVn4RooTGvhsNd KMD 12756.16332851, REVS 253.10000000 +# RYMzZx5nxKrMtTm3TNeheVn4RooTGvhsNd KMD 12756.16332851 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYMzZx5nxKrMtTm3TNeheVn4RooTGvhsNd\",\"symbol\":\"KMD\"}" # 12756.16332851 +sleep 13 +# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 3422.63549310, REVS 51.90683618 +# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 3422.63549310 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz\",\"symbol\":\"KMD\"}" # 3422.63549310 +sleep 13 +# RVcGdBT2N6Fbqbptj3R4zhZYNB4WJQWEns KMD 77986.19708921, REVS 1548.20316000 +# RVcGdBT2N6Fbqbptj3R4zhZYNB4WJQWEns KMD 77986.19708921 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVcGdBT2N6Fbqbptj3R4zhZYNB4WJQWEns\",\"symbol\":\"KMD\"}" # 77986.19708921 +sleep 13 +# RPZ1G1SP3qmfdmwxeLzuFYpeg2YgsyDmKm KMD 1633.25733112 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPZ1G1SP3qmfdmwxeLzuFYpeg2YgsyDmKm\",\"symbol\":\"KMD\"}" # 1633.25733112 +sleep 13 +# RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf KMD 11621.99031627, REVS 192.14192021 +# RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf KMD 11621.99031627 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf\",\"symbol\":\"KMD\"}" # 11621.99031627 +sleep 13 +# RQrV64mBwDgfSSe7Tf57xApNUYKfgeAyUx KMD 4237.18880501 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQrV64mBwDgfSSe7Tf57xApNUYKfgeAyUx\",\"symbol\":\"KMD\"}" # 4237.18880501 +sleep 13 +# RV9osrAbwSAdNpm6qNXJrC2gk3nZhp3dZB KMD 111549.91672800 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV9osrAbwSAdNpm6qNXJrC2gk3nZhp3dZB\",\"symbol\":\"KMD\"}" # 111549.91672800 +sleep 13 +# RNhXnjLYF8xWK3WJ81QGayVKspv39piE9A KMD 2186.32329008 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNhXnjLYF8xWK3WJ81QGayVKspv39piE9A\",\"symbol\":\"KMD\"}" # 2186.32329008 +sleep 13 +# RMtaFKtY9shLtoP3WBZqWgwGFGnN48aEms KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMtaFKtY9shLtoP3WBZqWgwGFGnN48aEms\",\"symbol\":\"KMD\"}" # 774.65219950 +sleep 13 +# REtq1LtbLVo6bz68f9TGFduNmUTKqG7vnH KMD 25088.84725730, REVS 305.62849999 +# REtq1LtbLVo6bz68f9TGFduNmUTKqG7vnH KMD 25088.84725730 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REtq1LtbLVo6bz68f9TGFduNmUTKqG7vnH\",\"symbol\":\"KMD\"}" # 25088.84725730 +sleep 13 +# RS3rMPEGouBWbHKStyQg8TxVmtwFQ6ebh3 KMD 3546.25060143, REVS 39.99000000 +# RS3rMPEGouBWbHKStyQg8TxVmtwFQ6ebh3 KMD 3546.25060143 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS3rMPEGouBWbHKStyQg8TxVmtwFQ6ebh3\",\"symbol\":\"KMD\"}" # 3546.25060143 +sleep 13 +# REEwT31zNEKL9B6ufdEeh3v39kaGXXmbHM KMD 3874.81030189 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REEwT31zNEKL9B6ufdEeh3v39kaGXXmbHM\",\"symbol\":\"KMD\"}" # 3874.81030189 +sleep 13 +# RGzvr4JSHDLDQAGBwdyoUiUuaYn5sUwKNd KMD 69108.92543895, REVS 314.51750000 +# RGzvr4JSHDLDQAGBwdyoUiUuaYn5sUwKNd KMD 69108.92543895 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGzvr4JSHDLDQAGBwdyoUiUuaYn5sUwKNd\",\"symbol\":\"KMD\"}" # 69108.92543895 +sleep 13 +# RUNnhqkaV7SLEGCaD72mPq8nmY4c2kFpZg KMD 971.41385817 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUNnhqkaV7SLEGCaD72mPq8nmY4c2kFpZg\",\"symbol\":\"KMD\"}" # 971.41385817 +sleep 13 +# RKKuzpkq1jxGAJSbADQzUDHUbfNvVCKFpW KMD 1118.61025995 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKKuzpkq1jxGAJSbADQzUDHUbfNvVCKFpW\",\"symbol\":\"KMD\"}" # 1118.61025995 +sleep 13 +# RMD1wVnzMmKn8uMTHaP9pYfCWkxf3QVWWE KMD 2931.50081538, REVS 40.37145505 +# RMD1wVnzMmKn8uMTHaP9pYfCWkxf3QVWWE KMD 2931.50081538 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMD1wVnzMmKn8uMTHaP9pYfCWkxf3QVWWE\",\"symbol\":\"KMD\"}" # 2931.50081538 +sleep 13 +# RKxR5Zafxm5WcmFFBdfWYTk55Qv6fbC4Vd KMD 8222.77359680 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKxR5Zafxm5WcmFFBdfWYTk55Qv6fbC4Vd\",\"symbol\":\"KMD\"}" # 8222.77359680 +sleep 13 +# RFAPtYANyAs9hhwUBNYemugxjhpwp4YvwF KMD 19588.92575705 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFAPtYANyAs9hhwUBNYemugxjhpwp4YvwF\",\"symbol\":\"KMD\"}" # 19588.92575705 +sleep 13 +# RQCEEEprmqghZHN73iG1C2XvYTTQ6FB2wE KMD 5506.18026103, REVS 90.00054364 +# RQCEEEprmqghZHN73iG1C2XvYTTQ6FB2wE KMD 5506.18026103 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQCEEEprmqghZHN73iG1C2XvYTTQ6FB2wE\",\"symbol\":\"KMD\"}" # 5506.18026103 +sleep 13 +# RDX85BbF7kJY4S33VTPgCM1tWQGwU9huTy KMD 8130.94314900 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDX85BbF7kJY4S33VTPgCM1tWQGwU9huTy\",\"symbol\":\"KMD\"}" # 8130.94314900 +sleep 13 +# RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx KMD 529.41438680, REVS 10.50000000 +# RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx KMD 529.41438680 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx\",\"symbol\":\"KMD\"}" # 529.41438680 +sleep 13 +# R9ULUWEvzmHPZ4rYL5FtwkMyTWvGDZX43J KMD 15051.18125683, REVS 298.60000000 +# R9ULUWEvzmHPZ4rYL5FtwkMyTWvGDZX43J KMD 15051.18125683 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9ULUWEvzmHPZ4rYL5FtwkMyTWvGDZX43J\",\"symbol\":\"KMD\"}" # 15051.18125683 +sleep 13 +# RE2f5UV1JDhUk6TeJLhz3VgxH5ePPa7SYH KMD 710.45289846 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE2f5UV1JDhUk6TeJLhz3VgxH5ePPa7SYH\",\"symbol\":\"KMD\"}" # 710.45289846 +sleep 13 +# RGW1zNcVLcZDHTMBqEiSEXCm2WNWBx3z9A KMD 755.28589451 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGW1zNcVLcZDHTMBqEiSEXCm2WNWBx3z9A\",\"symbol\":\"KMD\"}" # 755.28589451 +sleep 13 +# RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb KMD 166779.58408020, REVS 3310.49966000 +# RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb KMD 166779.58408020 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb\",\"symbol\":\"KMD\"}" # 166779.58408020 +sleep 13 +# RALRwXaEN3yS5damdDwAkmEMKvdAkVs361 KMD 25746.96382302, REVS 510.64558668 +# RALRwXaEN3yS5damdDwAkmEMKvdAkVs361 KMD 25746.96382302 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RALRwXaEN3yS5damdDwAkmEMKvdAkVs361\",\"symbol\":\"KMD\"}" # 25746.96382302 +sleep 13 +# RXk8hbw2g1iU5Vae5Aov8MmJBcNH9jTq6V KMD 4647.91319700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXk8hbw2g1iU5Vae5Aov8MmJBcNH9jTq6V\",\"symbol\":\"KMD\"}" # 4647.91319700 +sleep 13 +# RPVNUvVq4BgKrrB3E1uULja2hjPW6Hv6r9 KMD 16872.68860925, REVS 334.64000000 +# RPVNUvVq4BgKrrB3E1uULja2hjPW6Hv6r9 KMD 16872.68860925 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPVNUvVq4BgKrrB3E1uULja2hjPW6Hv6r9\",\"symbol\":\"KMD\"}" # 16872.68860925 +sleep 13 +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 19616.45270312, REVS 389.05771834 +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 19616.45270312 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" # 19616.45270312 +sleep 13 +# RXFr5VB9gQYC5QYv7yVvkxtjDY3zwYuvDx KMD 327.74801651, REVS 6.50475878 +# RXFr5VB9gQYC5QYv7yVvkxtjDY3zwYuvDx KMD 327.74801651 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXFr5VB9gQYC5QYv7yVvkxtjDY3zwYuvDx\",\"symbol\":\"KMD\"}" # 327.74801651 +sleep 13 +# RYZHjTxct7aq83rLkvb3ZrfXpPPQKdBX4z KMD 27224.94567564 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYZHjTxct7aq83rLkvb3ZrfXpPPQKdBX4z\",\"symbol\":\"KMD\"}" # 27224.94567564 +sleep 13 +# RCKvFCXm1SLr24i2FiVN7yNmxaXpWGy2o3 KMD 3892.43363943 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCKvFCXm1SLr24i2FiVN7yNmxaXpWGy2o3\",\"symbol\":\"KMD\"}" # 3892.43363943 +sleep 13 +# RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4 KMD 9265.21407570 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4\",\"symbol\":\"KMD\"}" # 9265.21407570 +sleep 13 +# RHUpvFhHv1umX1JsV5S8smAKAsN5CxA4HD KMD 2183.96436714, REVS 2.36599993 +# RHUpvFhHv1umX1JsV5S8smAKAsN5CxA4HD KMD 2183.96436714 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHUpvFhHv1umX1JsV5S8smAKAsN5CxA4HD\",\"symbol\":\"KMD\"}" # 2183.96436714 +sleep 13 +# RW7w9NLACVHnBW37QVTKeP6YYuYegfg1LF KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW7w9NLACVHnBW37QVTKeP6YYuYegfg1LF\",\"symbol\":\"KMD\"}" # 29049.45748125 +sleep 13 +# RAhvJHePdAb1PF9jjZhP2F7r72ebL9pA1f KMD 3457.02047726, REVS 68.56389987 +# RAhvJHePdAb1PF9jjZhP2F7r72ebL9pA1f KMD 3457.02047726 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAhvJHePdAb1PF9jjZhP2F7r72ebL9pA1f\",\"symbol\":\"KMD\"}" # 3457.02047726 +sleep 13 +# RQ5PNbYYJgytmGQQSdbUeuh7Nekc3jcMRW KMD 15358.01719845 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ5PNbYYJgytmGQQSdbUeuh7Nekc3jcMRW\",\"symbol\":\"KMD\"}" # 15358.01719845 +sleep 13 +# RLS8Y41iqJp8rBVPtsg6mDymyWmdWBQZby KMD 28274.80528175 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLS8Y41iqJp8rBVPtsg6mDymyWmdWBQZby\",\"symbol\":\"KMD\"}" # 28274.80528175 +sleep 13 +# RUYWU7rQ4vDyhhHbnyEeSMHrxt79qsnsAy KMD 1456.34613506 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUYWU7rQ4vDyhhHbnyEeSMHrxt79qsnsAy\",\"symbol\":\"KMD\"}" # 1456.34613506 +sleep 13 +# RDCjGgoZ1tvCWop6m5wPYkr83wdFrofF6M KMD 76598.36955552, REVS 1519.19347187 +# RDCjGgoZ1tvCWop6m5wPYkr83wdFrofF6M KMD 76598.36955552 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDCjGgoZ1tvCWop6m5wPYkr83wdFrofF6M\",\"symbol\":\"KMD\"}" # 76598.36955552 +sleep 13 +# RLAEm3H2LMSNzJmveLkcf2nS18AnqWR7pJ KMD 82831.36892196, REVS 1643.94000000 +# RLAEm3H2LMSNzJmveLkcf2nS18AnqWR7pJ KMD 82831.36892196 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLAEm3H2LMSNzJmveLkcf2nS18AnqWR7pJ\",\"symbol\":\"KMD\"}" # 82831.36892196 +sleep 13 +# RLko1vnC4k8WntCjCLwK6WcLYnzLZnCzfj KMD 34065.53877698 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLko1vnC4k8WntCjCLwK6WcLYnzLZnCzfj\",\"symbol\":\"KMD\"}" # 34065.53877698 +sleep 13 +# RSUfnwTLE36E3Nx8PptxVoAfSRtMeGQsFL KMD 67327.03192299, REVS 1282.48928243 +# RSUfnwTLE36E3Nx8PptxVoAfSRtMeGQsFL KMD 67327.03192299 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSUfnwTLE36E3Nx8PptxVoAfSRtMeGQsFL\",\"symbol\":\"KMD\"}" # 67327.03192299 +sleep 13 +# RPkkQmMmyLQe8Th7ZP5GoF6kSUs1DTNfAf KMD 1538.42929417, REVS 30.51202988 +# RPkkQmMmyLQe8Th7ZP5GoF6kSUs1DTNfAf KMD 1538.42929417 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPkkQmMmyLQe8Th7ZP5GoF6kSUs1DTNfAf\",\"symbol\":\"KMD\"}" # 1538.42929417 +sleep 13 +# RSkhXmiPCxqdp4bM4ux7VxAwMoCv2Uar6d KMD 73542.70261753, REVS 1459.56877203 +# RSkhXmiPCxqdp4bM4ux7VxAwMoCv2Uar6d KMD 73542.70261753 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSkhXmiPCxqdp4bM4ux7VxAwMoCv2Uar6d\",\"symbol\":\"KMD\"}" # 73542.70261753 +sleep 13 +# RP8AvHsUhZkbDdcfHFrRsZZn2QVNcBMPNQ KMD 8540.87460698 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP8AvHsUhZkbDdcfHFrRsZZn2QVNcBMPNQ\",\"symbol\":\"KMD\"}" # 8540.87460698 +sleep 13 +# RUJvR3TXCAcizk7dXdFc6GKRFS6jZfjtyY KMD 10419.10088055, REVS 206.75776925 +# RUJvR3TXCAcizk7dXdFc6GKRFS6jZfjtyY KMD 10419.10088055 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUJvR3TXCAcizk7dXdFc6GKRFS6jZfjtyY\",\"symbol\":\"KMD\"}" # 10419.10088055 +sleep 13 +# RLZmhbeB2tXTas9grzAeqaL2RFAXVmDVpU KMD 43480.56469698, REVS 50.30001915 +# RLZmhbeB2tXTas9grzAeqaL2RFAXVmDVpU KMD 43480.56469698 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLZmhbeB2tXTas9grzAeqaL2RFAXVmDVpU\",\"symbol\":\"KMD\"}" # 43480.56469698 +sleep 13 +# REU3FkPuNbZxogpStpyhZiyPkCp58G2bh3 KMD 8489.87824564 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REU3FkPuNbZxogpStpyhZiyPkCp58G2bh3\",\"symbol\":\"KMD\"}" # 8489.87824564 +sleep 13 +# RGHoKLW6r7DEBtYfV6VgjeBsQQFMvZ5thw KMD 20170.47947167 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGHoKLW6r7DEBtYfV6VgjeBsQQFMvZ5thw\",\"symbol\":\"KMD\"}" # 20170.47947167 +sleep 13 +# RLCDEXwfJ75P1iKgWGfR9geJmjZ84A4XXJ KMD 105141.23597043, REVS 1006.07261743 +# RLCDEXwfJ75P1iKgWGfR9geJmjZ84A4XXJ KMD 105141.23597043 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLCDEXwfJ75P1iKgWGfR9geJmjZ84A4XXJ\",\"symbol\":\"KMD\"}" # 105141.23597043 +sleep 13 +# RW1FmQGcpPv87WZVSCaMgjj74shMb3Y6Zi KMD 33700.59190315, REVS 380.47576230 +# RW1FmQGcpPv87WZVSCaMgjj74shMb3Y6Zi KMD 33700.59190315 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW1FmQGcpPv87WZVSCaMgjj74shMb3Y6Zi\",\"symbol\":\"KMD\"}" # 33700.59190315 +sleep 13 +# RQUMrGYr4SsHgbN56WP7tuEpWUcd62KidP KMD 61230.10078656, REVS 600.00100000 +# RQUMrGYr4SsHgbN56WP7tuEpWUcd62KidP KMD 61230.10078656 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQUMrGYr4SsHgbN56WP7tuEpWUcd62KidP\",\"symbol\":\"KMD\"}" # 61230.10078656 +sleep 13 +# RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt KMD 153725.02014837, REVS 3049.70000000 +# RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt KMD 153725.02014837 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt\",\"symbol\":\"KMD\"}" # 153725.02014837 +sleep 13 +# RRupn47XfLSMhXEuShtCCPBCv8P6LYXrLN KMD 790607.74140148, REVS 15691.16324116 +# RRupn47XfLSMhXEuShtCCPBCv8P6LYXrLN KMD 790607.74140148 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRupn47XfLSMhXEuShtCCPBCv8P6LYXrLN\",\"symbol\":\"KMD\"}" # 790607.74140148 +sleep 13 +# RTPiNQKiaVaBnhneiZXqpieHfF6F2RWt7y KMD 293399.52056062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTPiNQKiaVaBnhneiZXqpieHfF6F2RWt7y\",\"symbol\":\"KMD\"}" # 293399.52056062 +sleep 13 +# RAiZZDEXN8gqgotWvxxMc4cY7shkZ6y2Es KMD 14524.72874062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAiZZDEXN8gqgotWvxxMc4cY7shkZ6y2Es\",\"symbol\":\"KMD\"}" # 14524.72874062 +sleep 13 +# RLkUAjyNy8CQz8SxGvLwLWMP6rj3AK8Y7S KMD 6042.28715610 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLkUAjyNy8CQz8SxGvLwLWMP6rj3AK8Y7S\",\"symbol\":\"KMD\"}" # 6042.28715610 +sleep 13 +# RRX73tynW4sxCmqyYBQrS9nMcDUcXuX1yG KMD 26022.54788263, REVS 5.39446042 +# RRX73tynW4sxCmqyYBQrS9nMcDUcXuX1yG KMD 26022.54788263 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRX73tynW4sxCmqyYBQrS9nMcDUcXuX1yG\",\"symbol\":\"KMD\"}" # 26022.54788263 +sleep 13 +# RBFoJqbhcDJG3wcKu9vvenTMcc7EJTowFq KMD 14461.16736567 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBFoJqbhcDJG3wcKu9vvenTMcc7EJTowFq\",\"symbol\":\"KMD\"}" # 14461.16736567 +sleep 13 +# R9u7V63TLwJPH1shvAGHRG61aci61yy7RN KMD 20764.40163902, REVS 291.83028199 +# R9u7V63TLwJPH1shvAGHRG61aci61yy7RN KMD 20764.40163902 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9u7V63TLwJPH1shvAGHRG61aci61yy7RN\",\"symbol\":\"KMD\"}" # 20764.40163902 +sleep 13 +# RK6x2w56cGqJrnFiGcuR5VNWahzm8G5AiA KMD 1859.16527880 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK6x2w56cGqJrnFiGcuR5VNWahzm8G5AiA\",\"symbol\":\"KMD\"}" # 1859.16527880 +sleep 13 +# RV56pNJyghFp8ikNMqPsuaffcJxrk39Xkh KMD 25176.19648375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV56pNJyghFp8ikNMqPsuaffcJxrk39Xkh\",\"symbol\":\"KMD\"}" # 25176.19648375 +sleep 13 +# RKAxvqvC3apzrb8udG9trBxiNhhNXaLkz4 KMD 6483.53169406, REVS 5.41696484 +# RKAxvqvC3apzrb8udG9trBxiNhhNXaLkz4 KMD 6483.53169406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKAxvqvC3apzrb8udG9trBxiNhhNXaLkz4\",\"symbol\":\"KMD\"}" # 6483.53169406 +sleep 13 +# R9SHcVV3m86KDnjRo2Pxc5yeLGKxwbyChb KMD 120245.29223059 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9SHcVV3m86KDnjRo2Pxc5yeLGKxwbyChb\",\"symbol\":\"KMD\"}" # 120245.29223059 +sleep 13 +# RV5cgPjqt37QBHr94VL5HnXWqcwdqoqoC3 KMD 81008.20903630, REVS 1607.10337790 +# RV5cgPjqt37QBHr94VL5HnXWqcwdqoqoC3 KMD 81008.20903630 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV5cgPjqt37QBHr94VL5HnXWqcwdqoqoC3\",\"symbol\":\"KMD\"}" # 81008.20903630 +sleep 13 +# RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v KMD 14010.00244099, REVS 277.86367220 +# RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v KMD 14010.00244099 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v\",\"symbol\":\"KMD\"}" # 14010.00244099 +sleep 13 +# RF4iG6huXb9u6Pt8281WvnBjhdEtiVUnp4 KMD 674.21697725, REVS 13.37190382 +# RF4iG6huXb9u6Pt8281WvnBjhdEtiVUnp4 KMD 674.21697725 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF4iG6huXb9u6Pt8281WvnBjhdEtiVUnp4\",\"symbol\":\"KMD\"}" # 674.21697725 +sleep 13 +# RFKC68PGKwYz6rnPAbWomGZUv1BWKY8ugN KMD 1258661.38989150 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFKC68PGKwYz6rnPAbWomGZUv1BWKY8ugN\",\"symbol\":\"KMD\"}" # 1258661.38989150 +sleep 13 +# RQAzL9perFJbDKcHiJ9Lafxxce7XiKo7Sx KMD 1924794.21182562 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQAzL9perFJbDKcHiJ9Lafxxce7XiKo7Sx\",\"symbol\":\"KMD\"}" # 1924794.21182562 +sleep 13 +# RRaSQCAWk74r5cXzZV8JqqW9JFbhF2o2nH KMD 4841.57624687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRaSQCAWk74r5cXzZV8JqqW9JFbhF2o2nH\",\"symbol\":\"KMD\"}" # 4841.57624687 +sleep 13 +# RU49btc37WeEiQotQZMhEaGokFYeJYc616 KMD 128958.92559312 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU49btc37WeEiQotQZMhEaGokFYeJYc616\",\"symbol\":\"KMD\"}" # 128958.92559312 +sleep 13 +# RW3gz9fEadohRLZerK9r8zXkugk5swWHrf KMD 21219.62483892, REVS 421.20000000 +# RW3gz9fEadohRLZerK9r8zXkugk5swWHrf KMD 21219.62483892 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW3gz9fEadohRLZerK9r8zXkugk5swWHrf\",\"symbol\":\"KMD\"}" # 21219.62483892 +sleep 13 +# RAFLKtQxyGECt5fBfufuCGY6rvupfKrn3U KMD 1677670.82328714 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAFLKtQxyGECt5fBfufuCGY6rvupfKrn3U\",\"symbol\":\"KMD\"}" # 1677670.82328714 +sleep 13 +# RJ89radoRzRr5oDsf71QZ7BXUTiHcyVSUu KMD 52588.80320859, REVS 1043.00609779 +# RJ89radoRzRr5oDsf71QZ7BXUTiHcyVSUu KMD 52588.80320859 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ89radoRzRr5oDsf71QZ7BXUTiHcyVSUu\",\"symbol\":\"KMD\"}" # 52588.80320859 +sleep 13 +# RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 KMD 668547.16129881, REVS 13259.45302721 +# RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 KMD 668547.16129881 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4\",\"symbol\":\"KMD\"}" # 668547.16129881 +sleep 13 +# R9ibGGfsFHD8MxLRL4q2a6ezxAaHHPJvLc KMD 241619.45649268, REVS 4792.09548598 +# R9ibGGfsFHD8MxLRL4q2a6ezxAaHHPJvLc KMD 241619.45649268 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9ibGGfsFHD8MxLRL4q2a6ezxAaHHPJvLc\",\"symbol\":\"KMD\"}" # 241619.45649268 +sleep 13 +# RGwuMmW1ZBMrHJwJucEy5JEV3BZWv7eQnm KMD 9071868.91817425, REVS 180010.00000000 +# RGwuMmW1ZBMrHJwJucEy5JEV3BZWv7eQnm KMD 9071868.91817425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGwuMmW1ZBMrHJwJucEy5JEV3BZWv7eQnm\",\"symbol\":\"KMD\"}" # 9071868.91817425 +sleep 13 +# RT6Ckpw8yM2Q7yaCxejiVTrxELGQPtnGPm KMD 25778.27244764, REVS 225.87592741 +# RT6Ckpw8yM2Q7yaCxejiVTrxELGQPtnGPm KMD 25778.27244764 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT6Ckpw8yM2Q7yaCxejiVTrxELGQPtnGPm\",\"symbol\":\"KMD\"}" # 25778.27244764 +sleep 13 +# RJfzvRW4cWXcjFpQZmv2PSy5GDGrnbM76Q KMD 1781.70005885 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJfzvRW4cWXcjFpQZmv2PSy5GDGrnbM76Q\",\"symbol\":\"KMD\"}" # 1781.70005885 +sleep 13 +# RSixxEuXMe8DacnajhgqDdrcFjeGD54drE KMD 266743.29833631 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSixxEuXMe8DacnajhgqDdrcFjeGD54drE\",\"symbol\":\"KMD\"}" # 266743.29833631 +sleep 13 +# RGf4wwbHVYYZrVPVZg6XdS3mWvbzHSebzu KMD 6387.59296405, REVS 126.73871740 +# RGf4wwbHVYYZrVPVZg6XdS3mWvbzHSebzu KMD 6387.59296405 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGf4wwbHVYYZrVPVZg6XdS3mWvbzHSebzu\",\"symbol\":\"KMD\"}" # 6387.59296405 +sleep 13 +# RESydSaRoxRWWb1Pxn88H2kTRuV1W38dhU KMD 1243.42190050 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RESydSaRoxRWWb1Pxn88H2kTRuV1W38dhU\",\"symbol\":\"KMD\"}" # 1243.42190050 +sleep 13 +# RJAbNiCSRaMxUky9h8as6orZY3cu2rSW8z KMD 492782.94486222, REVS 9773.48000000 +# RJAbNiCSRaMxUky9h8as6orZY3cu2rSW8z KMD 492782.94486222 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJAbNiCSRaMxUky9h8as6orZY3cu2rSW8z\",\"symbol\":\"KMD\"}" # 492782.94486222 +sleep 13 +# RSW5SvtjWiGYN3iwb2mteYP7Hn223Zk1tP KMD 343847.33707184, REVS 6001.47957339 +# RSW5SvtjWiGYN3iwb2mteYP7Hn223Zk1tP KMD 343847.33707184 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSW5SvtjWiGYN3iwb2mteYP7Hn223Zk1tP\",\"symbol\":\"KMD\"}" # 343847.33707184 +sleep 13 +# RNnzD9QxDZqo6DvzfM3Pu7GiyNkVk7dgsG KMD 155758.69136969 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNnzD9QxDZqo6DvzfM3Pu7GiyNkVk7dgsG\",\"symbol\":\"KMD\"}" # 155758.69136969 +sleep 13 +# RSofHVn8U4WfqgfXCksqqgmiVSwXxnANvq KMD 4060.09161497 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSofHVn8U4WfqgfXCksqqgmiVSwXxnANvq\",\"symbol\":\"KMD\"}" # 4060.09161497 +sleep 13 +# RFPKxBL8iLQGmkoUukXdFU7VkXyGJLSsGw KMD 36335.50253541, REVS 413.60001059 +# RFPKxBL8iLQGmkoUukXdFU7VkXyGJLSsGw KMD 36335.50253541 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFPKxBL8iLQGmkoUukXdFU7VkXyGJLSsGw\",\"symbol\":\"KMD\"}" # 36335.50253541 +sleep 13 +# RA9xKdNjw1H2eqPi9f9J77v7Uq1CSWdNQJ KMD 5270.01925860 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA9xKdNjw1H2eqPi9f9J77v7Uq1CSWdNQJ\",\"symbol\":\"KMD\"}" # 5270.01925860 +sleep 13 +# RVFspAKoUpDMAiiEUiQQEpqdqXDMB48Jqp KMD 47464.51702590, REVS 634.55156126 +# RVFspAKoUpDMAiiEUiQQEpqdqXDMB48Jqp KMD 47464.51702590 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVFspAKoUpDMAiiEUiQQEpqdqXDMB48Jqp\",\"symbol\":\"KMD\"}" # 47464.51702590 +sleep 13 +# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 36359.70475507, REVS 100.00000000 +# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 36359.70475507 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1\",\"symbol\":\"KMD\"}" # 36359.70475507 +sleep 13 +# R9ce1xHEaWnRRP5jrWozEfPf9ZJgX7jnxd KMD 915808.36366861, REVS 18163.44258555 +# R9ce1xHEaWnRRP5jrWozEfPf9ZJgX7jnxd KMD 915808.36366861 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9ce1xHEaWnRRP5jrWozEfPf9ZJgX7jnxd\",\"symbol\":\"KMD\"}" # 915808.36366861 +sleep 13 +# RS1rdGqAhXvwFFTVyUCx695y84E3N3emcU KMD 18822.21903353, REVS 360.77089072 +# RS1rdGqAhXvwFFTVyUCx695y84E3N3emcU KMD 18822.21903353 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS1rdGqAhXvwFFTVyUCx695y84E3N3emcU\",\"symbol\":\"KMD\"}" # 18822.21903353 +sleep 13 +# RLgKsmgdzwNCt8CgqZ5J6cZhTat9HeZgxG KMD 62376.97840244, REVS 1045.22605497 +# RLgKsmgdzwNCt8CgqZ5J6cZhTat9HeZgxG KMD 62376.97840244 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLgKsmgdzwNCt8CgqZ5J6cZhTat9HeZgxG\",\"symbol\":\"KMD\"}" # 62376.97840244 +sleep 13 +# RFN4H8YYm71TjCVkHkoVFBFpg31i4ejbiu KMD 37183.30557600 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFN4H8YYm71TjCVkHkoVFBFpg31i4ejbiu\",\"symbol\":\"KMD\"}" # 37183.30557600 +sleep 13 +# RUBESyzjgZUts3fD6W7abpgMj4qRFSSszC KMD 541390.42407502, REVS 10592.65522652 +# RUBESyzjgZUts3fD6W7abpgMj4qRFSSszC KMD 541390.42407502 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUBESyzjgZUts3fD6W7abpgMj4qRFSSszC\",\"symbol\":\"KMD\"}" # 541390.42407502 +sleep 13 +# RSNu7Kd9p33aDrgT2AM8buy7fUSQZ2N3Gs KMD 130769.80646849, REVS 2593.58831601 +# RSNu7Kd9p33aDrgT2AM8buy7fUSQZ2N3Gs KMD 130769.80646849 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSNu7Kd9p33aDrgT2AM8buy7fUSQZ2N3Gs\",\"symbol\":\"KMD\"}" # 130769.80646849 +sleep 13 +# RCrCe4dsMzXzzp7GLahubjg73VGK2rnczC KMD 6843.04832293, REVS 25.10000000 +# RCrCe4dsMzXzzp7GLahubjg73VGK2rnczC KMD 6843.04832293 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCrCe4dsMzXzzp7GLahubjg73VGK2rnczC\",\"symbol\":\"KMD\"}" # 6843.04832293 +sleep 13 +# RVTCRzofA2cV6FwGcvn1uGjZJmP5s9G1o9 KMD 95283.12042643, REVS 497.50723875 +# RVTCRzofA2cV6FwGcvn1uGjZJmP5s9G1o9 KMD 95283.12042643 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVTCRzofA2cV6FwGcvn1uGjZJmP5s9G1o9\",\"symbol\":\"KMD\"}" # 95283.12042643 +sleep 13 + +# total KMD 45769105.32172734 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch1.importaddress b/iguana/tests/KMD.batch1.importaddress new file mode 100755 index 000000000..508364d38 --- /dev/null +++ b/iguana/tests/KMD.batch1.importaddress @@ -0,0 +1,442 @@ +# RDjc2nYjd2cgcyLyfCxCHNUacTHueLH5W8 KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDjc2nYjd2cgcyLyfCxCHNUacTHueLH5W8\",\"symbol\":\"KMD\"}" # 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RDjc2nYjd2cgcyLyfCxCHNUacTHueLH5W8" + +# RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4 KMD 205767.24475092, REVS 4084.38717211 +# RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4 KMD 205767.24475092 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4\",\"symbol\":\"KMD\"}" # 205767.24475092 +sleep 3 +echo "205767.24475092 <- expected amount RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4" + +# RAS5HArp8SMWVWm91Gwxtyno6Tkw9DBQLb KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAS5HArp8SMWVWm91Gwxtyno6Tkw9DBQLb\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RAS5HArp8SMWVWm91Gwxtyno6Tkw9DBQLb" + +# RGQ6jMjParVKLYMVLoKTuUAeUDKBbZhHRh KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGQ6jMjParVKLYMVLoKTuUAeUDKBbZhHRh\",\"symbol\":\"KMD\"}" # 7746.52199500 +sleep 3 +echo "7746.52199500 <- expected amount RGQ6jMjParVKLYMVLoKTuUAeUDKBbZhHRh" + +# RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx KMD 138163.01002402, REVS 2740.59474723 +# RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx KMD 138163.01002402 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx\",\"symbol\":\"KMD\"}" # 138163.01002402 +sleep 3 +echo "138163.01002402 <- expected amount RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx" + +# RHfHV1LTG5rz3T2HApavCto9973puD93qt KMD 243998.92767004, REVS 4839.53600000 +# RHfHV1LTG5rz3T2HApavCto9973puD93qt KMD 243998.92767004 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHfHV1LTG5rz3T2HApavCto9973puD93qt\",\"symbol\":\"KMD\"}" # 243998.92767004 +sleep 3 +echo "243998.92767004 <- expected amount RHfHV1LTG5rz3T2HApavCto9973puD93qt" + +# RMMR84AiLuuRB5gXESJ2W7q4M9bPdt57Ys KMD 5228902.34662500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMMR84AiLuuRB5gXESJ2W7q4M9bPdt57Ys\",\"symbol\":\"KMD\"}" # 5228902.34662500 +sleep 3 +echo "5228902.34662500 <- expected amount RMMR84AiLuuRB5gXESJ2W7q4M9bPdt57Ys" + +# RCkJC2Vd3A3R7na5vfHaSBUQHA3iKB4veg KMD 82566.66667868 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCkJC2Vd3A3R7na5vfHaSBUQHA3iKB4veg\",\"symbol\":\"KMD\"}" # 82566.66667868 +sleep 3 +echo "82566.66667868 <- expected amount RCkJC2Vd3A3R7na5vfHaSBUQHA3iKB4veg" + +# RRjFRzpV5EBrGigciSUn5QHkdWhB7tC6oH KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRjFRzpV5EBrGigciSUn5QHkdWhB7tC6oH\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RRjFRzpV5EBrGigciSUn5QHkdWhB7tC6oH" + +# RXs3VbEem331Rxg1Jac3hqknTti4UUo5pz KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXs3VbEem331Rxg1Jac3hqknTti4UUo5pz\",\"symbol\":\"KMD\"}" # 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RXs3VbEem331Rxg1Jac3hqknTti4UUo5pz" + +# RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy KMD 36785.74330117, REVS 730.28056435 +# RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy KMD 36785.74330117 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy\",\"symbol\":\"KMD\"}" # 36785.74330117 +sleep 3 +echo "36785.74330117 <- expected amount RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy" + +# RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB KMD 567760.05597770, REVS 11191.99000000 +# RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB KMD 567760.05597770 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB\",\"symbol\":\"KMD\"}" # 567760.05597770 +sleep 3 +echo "567760.05597770 <- expected amount RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB" + +# RC22v2GtzyHqdVQFBstrps9SBoDnSuQWot KMD 30287.84201075 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC22v2GtzyHqdVQFBstrps9SBoDnSuQWot\",\"symbol\":\"KMD\"}" # 30287.84201075 +sleep 3 +echo "30287.84201075 <- expected amount RC22v2GtzyHqdVQFBstrps9SBoDnSuQWot" + +# RJdKcUM9LazYuw9xsUEQYZRjDCZNi1M9wJ KMD 2202.52763206 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJdKcUM9LazYuw9xsUEQYZRjDCZNi1M9wJ\",\"symbol\":\"KMD\"}" # 2202.52763206 +sleep 3 +echo "2202.52763206 <- expected amount RJdKcUM9LazYuw9xsUEQYZRjDCZNi1M9wJ" + +# RLWai9FYvgf88UmGhqBKQfU1HFcviD2yXQ KMD 1403669.78549400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLWai9FYvgf88UmGhqBKQfU1HFcviD2yXQ\",\"symbol\":\"KMD\"}" # 1403669.78549400 +sleep 3 +echo "1403669.78549400 <- expected amount RLWai9FYvgf88UmGhqBKQfU1HFcviD2yXQ" + +# REvmz5CwutJh8pqSr6QtiZjMVmrvDMZsmD KMD 4002.16436294 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REvmz5CwutJh8pqSr6QtiZjMVmrvDMZsmD\",\"symbol\":\"KMD\"}" # 4002.16436294 +sleep 3 +echo "4002.16436294 <- expected amount REvmz5CwutJh8pqSr6QtiZjMVmrvDMZsmD" + +# REu24h1gWLmijHRnw5JEiQYe395ZRqoP2F KMD 198171.06769187 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REu24h1gWLmijHRnw5JEiQYe395ZRqoP2F\",\"symbol\":\"KMD\"}" # 198171.06769187 +sleep 3 +echo "198171.06769187 <- expected amount REu24h1gWLmijHRnw5JEiQYe395ZRqoP2F" + +# RShbCikwRgHp6YDNPWQyF8KBY3vEtMmtuP KMD 4824.87172431 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RShbCikwRgHp6YDNPWQyF8KBY3vEtMmtuP\",\"symbol\":\"KMD\"}" # 4824.87172431 +sleep 3 +echo "4824.87172431 <- expected amount RShbCikwRgHp6YDNPWQyF8KBY3vEtMmtuP" + +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 7771.42052436, REVS 0.62700000 +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 7771.42052436 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u\",\"symbol\":\"KMD\"}" # 7771.42052436 +sleep 3 +echo "7771.42052436 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 18186.86986853, REVS 143.39272495 +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 18186.86986853 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK\",\"symbol\":\"KMD\"}" # 18186.86986853 +sleep 3 +echo "18186.86986853 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RKJGbG1xxkzwm54gdga9Jhj49G9C8F8KZL KMD 9673.46934125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKJGbG1xxkzwm54gdga9Jhj49G9C8F8KZL\",\"symbol\":\"KMD\"}" # 9673.46934125 +sleep 3 +echo "9673.46934125 <- expected amount RKJGbG1xxkzwm54gdga9Jhj49G9C8F8KZL" + +# RJgMCdrxjg1xeJ1Rmi9CS3R93MS35Tx2sM KMD 601.90475901 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJgMCdrxjg1xeJ1Rmi9CS3R93MS35Tx2sM\",\"symbol\":\"KMD\"}" # 601.90475901 +sleep 3 +echo "601.90475901 <- expected amount RJgMCdrxjg1xeJ1Rmi9CS3R93MS35Tx2sM" + +# RSCeyDCcZ3kpJWcwBzmcEyHQ7e9VEtQXY7 KMD 1626.98055674 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSCeyDCcZ3kpJWcwBzmcEyHQ7e9VEtQXY7\",\"symbol\":\"KMD\"}" # 1626.98055674 +sleep 3 +echo "1626.98055674 <- expected amount RSCeyDCcZ3kpJWcwBzmcEyHQ7e9VEtQXY7" + +# RGERRfbvuZx2RsVyvUpjtdgBjdKzKMNww7 KMD 12588.09824187 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGERRfbvuZx2RsVyvUpjtdgBjdKzKMNww7\",\"symbol\":\"KMD\"}" # 12588.09824187 +sleep 3 +echo "12588.09824187 <- expected amount RGERRfbvuZx2RsVyvUpjtdgBjdKzKMNww7" + +# RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn KMD 4919.31879231 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn\",\"symbol\":\"KMD\"}" # 4919.31879231 +sleep 3 +echo "4919.31879231 <- expected amount RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn" + +# RBSqMV6ihCDzgMjFgm7g5bSxAwtBGseRuE KMD 17428.70617350 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBSqMV6ihCDzgMjFgm7g5bSxAwtBGseRuE\",\"symbol\":\"KMD\"}" # 17428.70617350 +sleep 3 +echo "17428.70617350 <- expected amount RBSqMV6ihCDzgMjFgm7g5bSxAwtBGseRuE" + +# RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu KMD 2375.16051963, REVS 47.12337252 +# RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu KMD 2375.16051963 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu\",\"symbol\":\"KMD\"}" # 2375.16051963 +sleep 3 +echo "2375.16051963 <- expected amount RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu" + +# RGNrH63hZEkcPzCZBnnpyYLDYfKXQqvBk1 KMD 1742.96744887 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGNrH63hZEkcPzCZBnnpyYLDYfKXQqvBk1\",\"symbol\":\"KMD\"}" # 1742.96744887 +sleep 3 +echo "1742.96744887 <- expected amount RGNrH63hZEkcPzCZBnnpyYLDYfKXQqvBk1" + +# RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta KMD 70173.29001640, REVS 1392.33555151 +# RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta KMD 70173.29001640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta\",\"symbol\":\"KMD\"}" # 70173.29001640 +sleep 3 +echo "70173.29001640 <- expected amount RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta" + +# RQNegFE2PWQtC8La69esvn2VGKttTAYpny KMD 4766.21295597 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQNegFE2PWQtC8La69esvn2VGKttTAYpny\",\"symbol\":\"KMD\"}" # 4766.21295597 +sleep 3 +echo "4766.21295597 <- expected amount RQNegFE2PWQtC8La69esvn2VGKttTAYpny" + +# RPWiTSrWZyGDmpXfVYcVpmQq56XCh4Hkky KMD 228081.21691774 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPWiTSrWZyGDmpXfVYcVpmQq56XCh4Hkky\",\"symbol\":\"KMD\"}" # 228081.21691774 +sleep 3 +echo "228081.21691774 <- expected amount RPWiTSrWZyGDmpXfVYcVpmQq56XCh4Hkky" + +# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 220390.81840860, REVS 1384.18511377 +# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 220390.81840860 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8\",\"symbol\":\"KMD\"}" # 220390.81840860 +sleep 3 +echo "220390.81840860 <- expected amount REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8" + +# RLBg1V9MCKeQjjFd2d6WKxon1hVTS4si73 KMD 3505.92510761 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLBg1V9MCKeQjjFd2d6WKxon1hVTS4si73\",\"symbol\":\"KMD\"}" # 3505.92510761 +sleep 3 +echo "3505.92510761 <- expected amount RLBg1V9MCKeQjjFd2d6WKxon1hVTS4si73" + +# RQNmvhca3LfPV8mGf7GKKCMoM1PPMojxmz KMD 15844.60160895 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQNmvhca3LfPV8mGf7GKKCMoM1PPMojxmz\",\"symbol\":\"KMD\"}" # 15844.60160895 +sleep 3 +echo "15844.60160895 <- expected amount RQNmvhca3LfPV8mGf7GKKCMoM1PPMojxmz" + +# RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ KMD 479029.87110523, REVS 9502.00000000 +# RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ KMD 479029.87110523 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ\",\"symbol\":\"KMD\"}" # 479029.87110523 +sleep 3 +echo "479029.87110523 <- expected amount RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ" + +# RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz KMD 230594.13977661, REVS 8.48502608 +# RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz KMD 230594.13977661 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz\",\"symbol\":\"KMD\"}" # 230594.13977661 +sleep 3 +echo "230594.13977661 <- expected amount RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz" + +# RC1S2CERDJR8BmvF3GZ4sbPviC5JrDYNKe KMD 36914.86263802 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC1S2CERDJR8BmvF3GZ4sbPviC5JrDYNKe\",\"symbol\":\"KMD\"}" # 36914.86263802 +sleep 3 +echo "36914.86263802 <- expected amount RC1S2CERDJR8BmvF3GZ4sbPviC5JrDYNKe" + +# RNy3NHtaKZ11xRqEU4YWWbrcdzjCgDBTuV KMD 528.33837397 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNy3NHtaKZ11xRqEU4YWWbrcdzjCgDBTuV\",\"symbol\":\"KMD\"}" # 528.33837397 +sleep 3 +echo "528.33837397 <- expected amount RNy3NHtaKZ11xRqEU4YWWbrcdzjCgDBTuV" + +# RXUEryMpxikDCdUT7LyCT3dq6bf4PPRibX KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXUEryMpxikDCdUT7LyCT3dq6bf4PPRibX\",\"symbol\":\"KMD\"}" # 19366.30498750 +sleep 3 +echo "19366.30498750 <- expected amount RXUEryMpxikDCdUT7LyCT3dq6bf4PPRibX" + +# RVoY1wTJug2VWeEG7C35iPseW2CtgZduRN KMD 13921.94668799 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVoY1wTJug2VWeEG7C35iPseW2CtgZduRN\",\"symbol\":\"KMD\"}" # 13921.94668799 +sleep 3 +echo "13921.94668799 <- expected amount RVoY1wTJug2VWeEG7C35iPseW2CtgZduRN" + +# RUJRcSoNU1y8WM7xq7X4JAwBMEqovak4Rb KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUJRcSoNU1y8WM7xq7X4JAwBMEqovak4Rb\",\"symbol\":\"KMD\"}" # 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RUJRcSoNU1y8WM7xq7X4JAwBMEqovak4Rb" + +# RAp5JCZiuapAgcbxgLnvbYKZcLq66LWRRk KMD 28437.73050782 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAp5JCZiuapAgcbxgLnvbYKZcLq66LWRRk\",\"symbol\":\"KMD\"}" # 28437.73050782 +sleep 3 +echo "28437.73050782 <- expected amount RAp5JCZiuapAgcbxgLnvbYKZcLq66LWRRk" + +# RQantoJxT8szwfAqUM3enLPe85YiQtwndH KMD 4163.75557231 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQantoJxT8szwfAqUM3enLPe85YiQtwndH\",\"symbol\":\"KMD\"}" # 4163.75557231 +sleep 3 +echo "4163.75557231 <- expected amount RQantoJxT8szwfAqUM3enLPe85YiQtwndH" + +# RQ7ZvdGNyxKJsn9WKcPbc72R91gs7WooGY KMD 4483.69874171 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ7ZvdGNyxKJsn9WKcPbc72R91gs7WooGY\",\"symbol\":\"KMD\"}" # 4483.69874171 +sleep 3 +echo "4483.69874171 <- expected amount RQ7ZvdGNyxKJsn9WKcPbc72R91gs7WooGY" + +# RWEzWEk5KSa2yBUCdHnoZ4RXS1VReq6omp KMD 56079.05303659 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWEzWEk5KSa2yBUCdHnoZ4RXS1VReq6omp\",\"symbol\":\"KMD\"}" # 56079.05303659 +sleep 3 +echo "56079.05303659 <- expected amount RWEzWEk5KSa2yBUCdHnoZ4RXS1VReq6omp" + +# RP8AvHsUhZkbDdcfHFrRsZZn2QVNcBMPNQ KMD 8540.87460698 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP8AvHsUhZkbDdcfHFrRsZZn2QVNcBMPNQ\",\"symbol\":\"KMD\"}" # 8540.87460698 +sleep 3 +echo "8540.87460698 <- expected amount RP8AvHsUhZkbDdcfHFrRsZZn2QVNcBMPNQ" + +# RLJkv3utC9vbsZDC12JtWPeY8Sp8dCAwZK KMD 1450.14891746 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLJkv3utC9vbsZDC12JtWPeY8Sp8dCAwZK\",\"symbol\":\"KMD\"}" # 1450.14891746 +sleep 3 +echo "1450.14891746 <- expected amount RLJkv3utC9vbsZDC12JtWPeY8Sp8dCAwZK" + +# RGZcCA8BT3m9vDSXmhyQQijGLw9HCsSdBy KMD 2949.36469257 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGZcCA8BT3m9vDSXmhyQQijGLw9HCsSdBy\",\"symbol\":\"KMD\"}" # 2949.36469257 +sleep 3 +echo "2949.36469257 <- expected amount RGZcCA8BT3m9vDSXmhyQQijGLw9HCsSdBy" + +# RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv KMD 25505.74161232, REVS 506.00000000 +# RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv KMD 25505.74161232 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv\",\"symbol\":\"KMD\"}" # 25505.74161232 +sleep 3 +echo "25505.74161232 <- expected amount RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv" + +# RYE329fWaVUaVg55DU4hiB4P2rfr4w3K2Y KMD 51.15844888 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYE329fWaVUaVg55DU4hiB4P2rfr4w3K2Y\",\"symbol\":\"KMD\"}" # 51.15844888 +sleep 3 +echo "51.15844888 <- expected amount RYE329fWaVUaVg55DU4hiB4P2rfr4w3K2Y" + +# RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5 KMD 4516.65527532, REVS 31.96541397 +# RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5 KMD 4516.65527532 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5\",\"symbol\":\"KMD\"}" # 4516.65527532 +sleep 3 +echo "4516.65527532 <- expected amount RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5" + +# RTJFUrfou8DU63uyGqH7ULgiCHHPZLkDT5 KMD 288282.30230152 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTJFUrfou8DU63uyGqH7ULgiCHHPZLkDT5\",\"symbol\":\"KMD\"}" # 288282.30230152 +sleep 3 +echo "288282.30230152 <- expected amount RTJFUrfou8DU63uyGqH7ULgiCHHPZLkDT5" + +# RU1usSdDYTL7yN34EayPxJurQ7UMxDvTkF KMD 2218.92003493 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU1usSdDYTL7yN34EayPxJurQ7UMxDvTkF\",\"symbol\":\"KMD\"}" # 2218.92003493 +sleep 3 +echo "2218.92003493 <- expected amount RU1usSdDYTL7yN34EayPxJurQ7UMxDvTkF" + +# RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6 KMD 30244.47828467 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6\",\"symbol\":\"KMD\"}" # 30244.47828467 +sleep 3 +echo "30244.47828467 <- expected amount RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6" + +# RF2LDXirQQ5afPGVM7W7o3ZQhgGbhSeH8W KMD 781.43040624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF2LDXirQQ5afPGVM7W7o3ZQhgGbhSeH8W\",\"symbol\":\"KMD\"}" # 781.43040624 +sleep 3 +echo "781.43040624 <- expected amount RF2LDXirQQ5afPGVM7W7o3ZQhgGbhSeH8W" + +# RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH KMD 35011.78668474, REVS 310.59835083 +# RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH KMD 35011.78668474 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH\",\"symbol\":\"KMD\"}" # 35011.78668474 +sleep 3 +echo "35011.78668474 <- expected amount RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH" + +# RH4u1f9PndVVYHkpxdMV28HwbdKphPiX6o KMD 20332.68360637 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH4u1f9PndVVYHkpxdMV28HwbdKphPiX6o\",\"symbol\":\"KMD\"}" # 20332.68360637 +sleep 3 +echo "20332.68360637 <- expected amount RH4u1f9PndVVYHkpxdMV28HwbdKphPiX6o" + +# RWszpjqDXG6ifFzTJN2qaqSfZ4nJ8FX3Cp KMD 4942.25856789 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWszpjqDXG6ifFzTJN2qaqSfZ4nJ8FX3Cp\",\"symbol\":\"KMD\"}" # 4942.25856789 +sleep 3 +echo "4942.25856789 <- expected amount RWszpjqDXG6ifFzTJN2qaqSfZ4nJ8FX3Cp" + +# R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks KMD 201.26853079, REVS 3.99180609 +# R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks KMD 201.26853079 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks\",\"symbol\":\"KMD\"}" # 201.26853079 +sleep 3 +echo "201.26853079 <- expected amount R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks" + +# RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig KMD 663.13491046, REVS 13.16292943 +# RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig KMD 663.13491046 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig\",\"symbol\":\"KMD\"}" # 663.13491046 +sleep 3 +echo "663.13491046 <- expected amount RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig" + +# RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK KMD 29548.60287586, REVS 586.04438779 +# RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK KMD 29548.60287586 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK\",\"symbol\":\"KMD\"}" # 29548.60287586 +sleep 3 +echo "29548.60287586 <- expected amount RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK" + +# RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK KMD 100186.19238242, REVS 1944.84440292 +# RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK KMD 100186.19238242 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK\",\"symbol\":\"KMD\"}" # 100186.19238242 +sleep 3 +echo "100186.19238242 <- expected amount RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK" + +# RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq KMD 1853646.03638691, REVS 415.68775429 +# RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq KMD 1853646.03638691 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq\",\"symbol\":\"KMD\"}" # 1853646.03638691 +sleep 3 +echo "1853646.03638691 <- expected amount RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq" + +# RDQH9gVbS9Yza5fd7T4GSASzdTuwiP3Sgm KMD 56782.00622335 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDQH9gVbS9Yza5fd7T4GSASzdTuwiP3Sgm\",\"symbol\":\"KMD\"}" # 56782.00622335 +sleep 3 +echo "56782.00622335 <- expected amount RDQH9gVbS9Yza5fd7T4GSASzdTuwiP3Sgm" + +# RFREgr9p32GanT4YcM25hMcPYkvRLDNkja KMD 151544.96672946, REVS 3005.62695376 +# RFREgr9p32GanT4YcM25hMcPYkvRLDNkja KMD 151544.96672946 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFREgr9p32GanT4YcM25hMcPYkvRLDNkja\",\"symbol\":\"KMD\"}" # 151544.96672946 +sleep 3 +echo "151544.96672946 <- expected amount RFREgr9p32GanT4YcM25hMcPYkvRLDNkja" + +# RHQggZrkWW9HV8d7o2dvb9mgN1z6tGDJRh KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHQggZrkWW9HV8d7o2dvb9mgN1z6tGDJRh\",\"symbol\":\"KMD\"}" # 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RHQggZrkWW9HV8d7o2dvb9mgN1z6tGDJRh" + +# RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4 KMD 295382.69930466, REVS 5860.00000000 +# RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4 KMD 295382.69930466 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4\",\"symbol\":\"KMD\"}" # 295382.69930466 +sleep 3 +echo "295382.69930466 <- expected amount RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4" + +# RKyMDKFNC79FhCfnFr58JE1ibpADa2WScE KMD 64965.94673778 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKyMDKFNC79FhCfnFr58JE1ibpADa2WScE\",\"symbol\":\"KMD\"}" # 64965.94673778 +sleep 3 +echo "64965.94673778 <- expected amount RKyMDKFNC79FhCfnFr58JE1ibpADa2WScE" + +# RHoPZSxWRgeQp7nB3eTn4dyDpmBRoZPoKv KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHoPZSxWRgeQp7nB3eTn4dyDpmBRoZPoKv\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RHoPZSxWRgeQp7nB3eTn4dyDpmBRoZPoKv" + +# RGiA2sP25BqtW9qfJ3vRUAPH8zbgepwriY KMD 2414.30320001 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGiA2sP25BqtW9qfJ3vRUAPH8zbgepwriY\",\"symbol\":\"KMD\"}" # 2414.30320001 +sleep 3 +echo "2414.30320001 <- expected amount RGiA2sP25BqtW9qfJ3vRUAPH8zbgepwriY" + +# RTHtdb735hqJi5DJjXNiP2LREkqUL5b8Sx KMD 19375.01982474 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTHtdb735hqJi5DJjXNiP2LREkqUL5b8Sx\",\"symbol\":\"KMD\"}" # 19375.01982474 +sleep 3 +echo "19375.01982474 <- expected amount RTHtdb735hqJi5DJjXNiP2LREkqUL5b8Sx" + +# RHZR3YhrgxaYASvNUrcVdoonXCfgrdGULz KMD 1589788.37880130 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHZR3YhrgxaYASvNUrcVdoonXCfgrdGULz\",\"symbol\":\"KMD\"}" # 1589788.37880130 +sleep 3 +echo "1589788.37880130 <- expected amount RHZR3YhrgxaYASvNUrcVdoonXCfgrdGULz" + +# RCaxwG9VfLVvxMVvc5q7SQxRSuwR9amxoy KMD 4458.42312105 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCaxwG9VfLVvxMVvc5q7SQxRSuwR9amxoy\",\"symbol\":\"KMD\"}" # 4458.42312105 +sleep 3 +echo "4458.42312105 <- expected amount RCaxwG9VfLVvxMVvc5q7SQxRSuwR9amxoy" + +# RAyEy5vxNeAAeRw57BrsN5Kh4zu8i3KYEf KMD 21120.82823309 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAyEy5vxNeAAeRw57BrsN5Kh4zu8i3KYEf\",\"symbol\":\"KMD\"}" # 21120.82823309 +sleep 3 +echo "21120.82823309 <- expected amount RAyEy5vxNeAAeRw57BrsN5Kh4zu8i3KYEf" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 6566.15472364 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" # 6566.15472364 +sleep 3 +echo "6566.15472364 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT KMD 59621.32507756, REVS 606.36817953 +# RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT KMD 59621.32507756 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT\",\"symbol\":\"KMD\"}" # 59621.32507756 +sleep 3 +echo "59621.32507756 <- expected amount RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT" + +# RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p KMD 23159.75532541, REVS 459.58469952 +# RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p KMD 23159.75532541 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p\",\"symbol\":\"KMD\"}" # 23159.75532541 +sleep 3 +echo "23159.75532541 <- expected amount RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p" + +# RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV" + +# RQft1wNt3sgntZDRbpz2WzHDy4F2TRamhB KMD 1504.76189752 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQft1wNt3sgntZDRbpz2WzHDy4F2TRamhB\",\"symbol\":\"KMD\"}" # 1504.76189752 +sleep 3 +echo "1504.76189752 <- expected amount RQft1wNt3sgntZDRbpz2WzHDy4F2TRamhB" + +# RRergGKQPDcYHU8PxKhpx6kmR7mXdqp8Ce KMD 1452.47287406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRergGKQPDcYHU8PxKhpx6kmR7mXdqp8Ce\",\"symbol\":\"KMD\"}" # 1452.47287406 +sleep 3 +echo "1452.47287406 <- expected amount RRergGKQPDcYHU8PxKhpx6kmR7mXdqp8Ce" + +# RDPo9tEaM9Ds5UePeQS1pAFqXzD1ZVvS1n KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDPo9tEaM9Ds5UePeQS1pAFqXzD1ZVvS1n\",\"symbol\":\"KMD\"}" # 7746.52199500 +sleep 3 +echo "7746.52199500 <- expected amount RDPo9tEaM9Ds5UePeQS1pAFqXzD1ZVvS1n" + +# RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ KMD 77304.58455563, REVS 1533.20000000 +# RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ KMD 77304.58455563 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ\",\"symbol\":\"KMD\"}" # 77304.58455563 +sleep 3 +echo "77304.58455563 <- expected amount RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ" + +# RNpa2spCJutTMYHgsr6MwM6X2pmRfYd6LT KMD 894.72329042 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNpa2spCJutTMYHgsr6MwM6X2pmRfYd6LT\",\"symbol\":\"KMD\"}" # 894.72329042 +sleep 3 +echo "894.72329042 <- expected amount RNpa2spCJutTMYHgsr6MwM6X2pmRfYd6LT" + + +# total KMD 14534159.61298856 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch1.listunspent b/iguana/tests/KMD.batch1.listunspent new file mode 100755 index 000000000..2d19bae72 --- /dev/null +++ b/iguana/tests/KMD.batch1.listunspent @@ -0,0 +1,359 @@ +# RDjc2nYjd2cgcyLyfCxCHNUacTHueLH5W8 KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDjc2nYjd2cgcyLyfCxCHNUacTHueLH5W8\",\"symbol\":\"KMD\"}" +echo "968.31524937 <- expected amount RDjc2nYjd2cgcyLyfCxCHNUacTHueLH5W8" + +# RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4 KMD 205767.24475092, REVS 4084.38717211 +# RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4 KMD 205767.24475092 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4\",\"symbol\":\"KMD\"}" +echo "205767.24475092 <- expected amount RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4" + +# RAS5HArp8SMWVWm91Gwxtyno6Tkw9DBQLb KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAS5HArp8SMWVWm91Gwxtyno6Tkw9DBQLb\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RAS5HArp8SMWVWm91Gwxtyno6Tkw9DBQLb" + +# RGQ6jMjParVKLYMVLoKTuUAeUDKBbZhHRh KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGQ6jMjParVKLYMVLoKTuUAeUDKBbZhHRh\",\"symbol\":\"KMD\"}" +echo "7746.52199500 <- expected amount RGQ6jMjParVKLYMVLoKTuUAeUDKBbZhHRh" + +# RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx KMD 138163.01002402, REVS 2740.59474723 +# RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx KMD 138163.01002402 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx\",\"symbol\":\"KMD\"}" +echo "138163.01002402 <- expected amount RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx" + +# RHfHV1LTG5rz3T2HApavCto9973puD93qt KMD 243998.92767004, REVS 4839.53600000 +# RHfHV1LTG5rz3T2HApavCto9973puD93qt KMD 243998.92767004 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHfHV1LTG5rz3T2HApavCto9973puD93qt\",\"symbol\":\"KMD\"}" +echo "243998.92767004 <- expected amount RHfHV1LTG5rz3T2HApavCto9973puD93qt" + +# RMMR84AiLuuRB5gXESJ2W7q4M9bPdt57Ys KMD 5228902.34662500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMMR84AiLuuRB5gXESJ2W7q4M9bPdt57Ys\",\"symbol\":\"KMD\"}" +echo "5228902.34662500 <- expected amount RMMR84AiLuuRB5gXESJ2W7q4M9bPdt57Ys" + +# RCkJC2Vd3A3R7na5vfHaSBUQHA3iKB4veg KMD 82566.66667868 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCkJC2Vd3A3R7na5vfHaSBUQHA3iKB4veg\",\"symbol\":\"KMD\"}" +echo "82566.66667868 <- expected amount RCkJC2Vd3A3R7na5vfHaSBUQHA3iKB4veg" + +# RRjFRzpV5EBrGigciSUn5QHkdWhB7tC6oH KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRjFRzpV5EBrGigciSUn5QHkdWhB7tC6oH\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RRjFRzpV5EBrGigciSUn5QHkdWhB7tC6oH" + +# RXs3VbEem331Rxg1Jac3hqknTti4UUo5pz KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXs3VbEem331Rxg1Jac3hqknTti4UUo5pz\",\"symbol\":\"KMD\"}" +echo "968.31524937 <- expected amount RXs3VbEem331Rxg1Jac3hqknTti4UUo5pz" + +# RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy KMD 36785.74330117, REVS 730.28056435 +# RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy KMD 36785.74330117 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy\",\"symbol\":\"KMD\"}" +echo "36785.74330117 <- expected amount RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy" + +# RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB KMD 567760.05597770, REVS 11191.99000000 +# RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB KMD 567760.05597770 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB\",\"symbol\":\"KMD\"}" +echo "567760.05597770 <- expected amount RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB" + +# RC22v2GtzyHqdVQFBstrps9SBoDnSuQWot KMD 30287.84201075 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC22v2GtzyHqdVQFBstrps9SBoDnSuQWot\",\"symbol\":\"KMD\"}" +echo "30287.84201075 <- expected amount RC22v2GtzyHqdVQFBstrps9SBoDnSuQWot" + +# RJdKcUM9LazYuw9xsUEQYZRjDCZNi1M9wJ KMD 2202.52763206 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJdKcUM9LazYuw9xsUEQYZRjDCZNi1M9wJ\",\"symbol\":\"KMD\"}" +echo "2202.52763206 <- expected amount RJdKcUM9LazYuw9xsUEQYZRjDCZNi1M9wJ" + +# RLWai9FYvgf88UmGhqBKQfU1HFcviD2yXQ KMD 1403669.78549400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLWai9FYvgf88UmGhqBKQfU1HFcviD2yXQ\",\"symbol\":\"KMD\"}" +echo "1403669.78549400 <- expected amount RLWai9FYvgf88UmGhqBKQfU1HFcviD2yXQ" + +# REvmz5CwutJh8pqSr6QtiZjMVmrvDMZsmD KMD 4002.16436294 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REvmz5CwutJh8pqSr6QtiZjMVmrvDMZsmD\",\"symbol\":\"KMD\"}" +echo "4002.16436294 <- expected amount REvmz5CwutJh8pqSr6QtiZjMVmrvDMZsmD" + +# REu24h1gWLmijHRnw5JEiQYe395ZRqoP2F KMD 198171.06769187 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REu24h1gWLmijHRnw5JEiQYe395ZRqoP2F\",\"symbol\":\"KMD\"}" +echo "198171.06769187 <- expected amount REu24h1gWLmijHRnw5JEiQYe395ZRqoP2F" + +# RShbCikwRgHp6YDNPWQyF8KBY3vEtMmtuP KMD 4824.87172431 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RShbCikwRgHp6YDNPWQyF8KBY3vEtMmtuP\",\"symbol\":\"KMD\"}" +echo "4824.87172431 <- expected amount RShbCikwRgHp6YDNPWQyF8KBY3vEtMmtuP" + +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 7771.42052436, REVS 0.62700000 +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 7771.42052436 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u\",\"symbol\":\"KMD\"}" +echo "7771.42052436 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 18186.86986853, REVS 143.39272495 +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 18186.86986853 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK\",\"symbol\":\"KMD\"}" +echo "18186.86986853 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RKJGbG1xxkzwm54gdga9Jhj49G9C8F8KZL KMD 9673.46934125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKJGbG1xxkzwm54gdga9Jhj49G9C8F8KZL\",\"symbol\":\"KMD\"}" +echo "9673.46934125 <- expected amount RKJGbG1xxkzwm54gdga9Jhj49G9C8F8KZL" + +# RJgMCdrxjg1xeJ1Rmi9CS3R93MS35Tx2sM KMD 601.90475901 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJgMCdrxjg1xeJ1Rmi9CS3R93MS35Tx2sM\",\"symbol\":\"KMD\"}" +echo "601.90475901 <- expected amount RJgMCdrxjg1xeJ1Rmi9CS3R93MS35Tx2sM" + +# RSCeyDCcZ3kpJWcwBzmcEyHQ7e9VEtQXY7 KMD 1626.98055674 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSCeyDCcZ3kpJWcwBzmcEyHQ7e9VEtQXY7\",\"symbol\":\"KMD\"}" +echo "1626.98055674 <- expected amount RSCeyDCcZ3kpJWcwBzmcEyHQ7e9VEtQXY7" + +# RGERRfbvuZx2RsVyvUpjtdgBjdKzKMNww7 KMD 12588.09824187 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGERRfbvuZx2RsVyvUpjtdgBjdKzKMNww7\",\"symbol\":\"KMD\"}" +echo "12588.09824187 <- expected amount RGERRfbvuZx2RsVyvUpjtdgBjdKzKMNww7" + +# RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn KMD 4919.31879231 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn\",\"symbol\":\"KMD\"}" +echo "4919.31879231 <- expected amount RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn" + +# RBSqMV6ihCDzgMjFgm7g5bSxAwtBGseRuE KMD 17428.70617350 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBSqMV6ihCDzgMjFgm7g5bSxAwtBGseRuE\",\"symbol\":\"KMD\"}" +echo "17428.70617350 <- expected amount RBSqMV6ihCDzgMjFgm7g5bSxAwtBGseRuE" + +# RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu KMD 2375.16051963, REVS 47.12337252 +# RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu KMD 2375.16051963 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu\",\"symbol\":\"KMD\"}" +echo "2375.16051963 <- expected amount RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu" + +# RGNrH63hZEkcPzCZBnnpyYLDYfKXQqvBk1 KMD 1742.96744887 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGNrH63hZEkcPzCZBnnpyYLDYfKXQqvBk1\",\"symbol\":\"KMD\"}" +echo "1742.96744887 <- expected amount RGNrH63hZEkcPzCZBnnpyYLDYfKXQqvBk1" + +# RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta KMD 70173.29001640, REVS 1392.33555151 +# RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta KMD 70173.29001640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta\",\"symbol\":\"KMD\"}" +echo "70173.29001640 <- expected amount RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta" + +# RQNegFE2PWQtC8La69esvn2VGKttTAYpny KMD 4766.21295597 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQNegFE2PWQtC8La69esvn2VGKttTAYpny\",\"symbol\":\"KMD\"}" +echo "4766.21295597 <- expected amount RQNegFE2PWQtC8La69esvn2VGKttTAYpny" + +# RPWiTSrWZyGDmpXfVYcVpmQq56XCh4Hkky KMD 228081.21691774 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPWiTSrWZyGDmpXfVYcVpmQq56XCh4Hkky\",\"symbol\":\"KMD\"}" +echo "228081.21691774 <- expected amount RPWiTSrWZyGDmpXfVYcVpmQq56XCh4Hkky" + +# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 220390.81840860, REVS 1384.18511377 +# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 220390.81840860 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8\",\"symbol\":\"KMD\"}" +echo "220390.81840860 <- expected amount REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8" + +# RLBg1V9MCKeQjjFd2d6WKxon1hVTS4si73 KMD 3505.92510761 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLBg1V9MCKeQjjFd2d6WKxon1hVTS4si73\",\"symbol\":\"KMD\"}" +echo "3505.92510761 <- expected amount RLBg1V9MCKeQjjFd2d6WKxon1hVTS4si73" + +# RQNmvhca3LfPV8mGf7GKKCMoM1PPMojxmz KMD 15844.60160895 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQNmvhca3LfPV8mGf7GKKCMoM1PPMojxmz\",\"symbol\":\"KMD\"}" +echo "15844.60160895 <- expected amount RQNmvhca3LfPV8mGf7GKKCMoM1PPMojxmz" + +# RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ KMD 479029.87110523, REVS 9502.00000000 +# RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ KMD 479029.87110523 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ\",\"symbol\":\"KMD\"}" +echo "479029.87110523 <- expected amount RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ" + +# RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz KMD 230594.13977661, REVS 8.48502608 +# RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz KMD 230594.13977661 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz\",\"symbol\":\"KMD\"}" +echo "230594.13977661 <- expected amount RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz" + +# RC1S2CERDJR8BmvF3GZ4sbPviC5JrDYNKe KMD 36914.86263802 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC1S2CERDJR8BmvF3GZ4sbPviC5JrDYNKe\",\"symbol\":\"KMD\"}" +echo "36914.86263802 <- expected amount RC1S2CERDJR8BmvF3GZ4sbPviC5JrDYNKe" + +# RNy3NHtaKZ11xRqEU4YWWbrcdzjCgDBTuV KMD 528.33837397 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNy3NHtaKZ11xRqEU4YWWbrcdzjCgDBTuV\",\"symbol\":\"KMD\"}" +echo "528.33837397 <- expected amount RNy3NHtaKZ11xRqEU4YWWbrcdzjCgDBTuV" + +# RXUEryMpxikDCdUT7LyCT3dq6bf4PPRibX KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXUEryMpxikDCdUT7LyCT3dq6bf4PPRibX\",\"symbol\":\"KMD\"}" +echo "19366.30498750 <- expected amount RXUEryMpxikDCdUT7LyCT3dq6bf4PPRibX" + +# RVoY1wTJug2VWeEG7C35iPseW2CtgZduRN KMD 13921.94668799 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVoY1wTJug2VWeEG7C35iPseW2CtgZduRN\",\"symbol\":\"KMD\"}" +echo "13921.94668799 <- expected amount RVoY1wTJug2VWeEG7C35iPseW2CtgZduRN" + +# RUJRcSoNU1y8WM7xq7X4JAwBMEqovak4Rb KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUJRcSoNU1y8WM7xq7X4JAwBMEqovak4Rb\",\"symbol\":\"KMD\"}" +echo "3873.26099750 <- expected amount RUJRcSoNU1y8WM7xq7X4JAwBMEqovak4Rb" + +# RAp5JCZiuapAgcbxgLnvbYKZcLq66LWRRk KMD 28437.73050782 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAp5JCZiuapAgcbxgLnvbYKZcLq66LWRRk\",\"symbol\":\"KMD\"}" +echo "28437.73050782 <- expected amount RAp5JCZiuapAgcbxgLnvbYKZcLq66LWRRk" + +# RQantoJxT8szwfAqUM3enLPe85YiQtwndH KMD 4163.75557231 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQantoJxT8szwfAqUM3enLPe85YiQtwndH\",\"symbol\":\"KMD\"}" +echo "4163.75557231 <- expected amount RQantoJxT8szwfAqUM3enLPe85YiQtwndH" + +# RQ7ZvdGNyxKJsn9WKcPbc72R91gs7WooGY KMD 4483.69874171 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQ7ZvdGNyxKJsn9WKcPbc72R91gs7WooGY\",\"symbol\":\"KMD\"}" +echo "4483.69874171 <- expected amount RQ7ZvdGNyxKJsn9WKcPbc72R91gs7WooGY" + +# RWEzWEk5KSa2yBUCdHnoZ4RXS1VReq6omp KMD 56079.05303659 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWEzWEk5KSa2yBUCdHnoZ4RXS1VReq6omp\",\"symbol\":\"KMD\"}" +echo "56079.05303659 <- expected amount RWEzWEk5KSa2yBUCdHnoZ4RXS1VReq6omp" + +# RP8AvHsUhZkbDdcfHFrRsZZn2QVNcBMPNQ KMD 8540.87460698 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP8AvHsUhZkbDdcfHFrRsZZn2QVNcBMPNQ\",\"symbol\":\"KMD\"}" +echo "8540.87460698 <- expected amount RP8AvHsUhZkbDdcfHFrRsZZn2QVNcBMPNQ" + +# RLJkv3utC9vbsZDC12JtWPeY8Sp8dCAwZK KMD 1450.14891746 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLJkv3utC9vbsZDC12JtWPeY8Sp8dCAwZK\",\"symbol\":\"KMD\"}" +echo "1450.14891746 <- expected amount RLJkv3utC9vbsZDC12JtWPeY8Sp8dCAwZK" + +# RGZcCA8BT3m9vDSXmhyQQijGLw9HCsSdBy KMD 2949.36469257 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGZcCA8BT3m9vDSXmhyQQijGLw9HCsSdBy\",\"symbol\":\"KMD\"}" +echo "2949.36469257 <- expected amount RGZcCA8BT3m9vDSXmhyQQijGLw9HCsSdBy" + +# RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv KMD 25505.74161232, REVS 506.00000000 +# RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv KMD 25505.74161232 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv\",\"symbol\":\"KMD\"}" +echo "25505.74161232 <- expected amount RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv" + +# RYE329fWaVUaVg55DU4hiB4P2rfr4w3K2Y KMD 51.15844888 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYE329fWaVUaVg55DU4hiB4P2rfr4w3K2Y\",\"symbol\":\"KMD\"}" +echo "51.15844888 <- expected amount RYE329fWaVUaVg55DU4hiB4P2rfr4w3K2Y" + +# RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5 KMD 4516.65527532, REVS 31.96541397 +# RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5 KMD 4516.65527532 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5\",\"symbol\":\"KMD\"}" +echo "4516.65527532 <- expected amount RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5" + +# RTJFUrfou8DU63uyGqH7ULgiCHHPZLkDT5 KMD 288282.30230152 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTJFUrfou8DU63uyGqH7ULgiCHHPZLkDT5\",\"symbol\":\"KMD\"}" +echo "288282.30230152 <- expected amount RTJFUrfou8DU63uyGqH7ULgiCHHPZLkDT5" + +# RU1usSdDYTL7yN34EayPxJurQ7UMxDvTkF KMD 2218.92003493 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU1usSdDYTL7yN34EayPxJurQ7UMxDvTkF\",\"symbol\":\"KMD\"}" +echo "2218.92003493 <- expected amount RU1usSdDYTL7yN34EayPxJurQ7UMxDvTkF" + +# RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6 KMD 30244.47828467 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6\",\"symbol\":\"KMD\"}" +echo "30244.47828467 <- expected amount RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6" + +# RF2LDXirQQ5afPGVM7W7o3ZQhgGbhSeH8W KMD 781.43040624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RF2LDXirQQ5afPGVM7W7o3ZQhgGbhSeH8W\",\"symbol\":\"KMD\"}" +echo "781.43040624 <- expected amount RF2LDXirQQ5afPGVM7W7o3ZQhgGbhSeH8W" + +# RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH KMD 35011.78668474, REVS 310.59835083 +# RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH KMD 35011.78668474 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH\",\"symbol\":\"KMD\"}" +echo "35011.78668474 <- expected amount RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH" + +# RH4u1f9PndVVYHkpxdMV28HwbdKphPiX6o KMD 20332.68360637 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH4u1f9PndVVYHkpxdMV28HwbdKphPiX6o\",\"symbol\":\"KMD\"}" +echo "20332.68360637 <- expected amount RH4u1f9PndVVYHkpxdMV28HwbdKphPiX6o" + +# RWszpjqDXG6ifFzTJN2qaqSfZ4nJ8FX3Cp KMD 4942.25856789 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWszpjqDXG6ifFzTJN2qaqSfZ4nJ8FX3Cp\",\"symbol\":\"KMD\"}" +echo "4942.25856789 <- expected amount RWszpjqDXG6ifFzTJN2qaqSfZ4nJ8FX3Cp" + +# R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks KMD 201.26853079, REVS 3.99180609 +# R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks KMD 201.26853079 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks\",\"symbol\":\"KMD\"}" +echo "201.26853079 <- expected amount R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks" + +# RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig KMD 663.13491046, REVS 13.16292943 +# RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig KMD 663.13491046 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig\",\"symbol\":\"KMD\"}" +echo "663.13491046 <- expected amount RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig" + +# RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK KMD 29548.60287586, REVS 586.04438779 +# RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK KMD 29548.60287586 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK\",\"symbol\":\"KMD\"}" +echo "29548.60287586 <- expected amount RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK" + +# RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK KMD 100186.19238242, REVS 1944.84440292 +# RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK KMD 100186.19238242 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK\",\"symbol\":\"KMD\"}" +echo "100186.19238242 <- expected amount RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK" + +# RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq KMD 1853646.03638691, REVS 415.68775429 +# RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq KMD 1853646.03638691 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq\",\"symbol\":\"KMD\"}" +echo "1853646.03638691 <- expected amount RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq" + +# RDQH9gVbS9Yza5fd7T4GSASzdTuwiP3Sgm KMD 56782.00622335 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDQH9gVbS9Yza5fd7T4GSASzdTuwiP3Sgm\",\"symbol\":\"KMD\"}" +echo "56782.00622335 <- expected amount RDQH9gVbS9Yza5fd7T4GSASzdTuwiP3Sgm" + +# RFREgr9p32GanT4YcM25hMcPYkvRLDNkja KMD 151544.96672946, REVS 3005.62695376 +# RFREgr9p32GanT4YcM25hMcPYkvRLDNkja KMD 151544.96672946 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFREgr9p32GanT4YcM25hMcPYkvRLDNkja\",\"symbol\":\"KMD\"}" +echo "151544.96672946 <- expected amount RFREgr9p32GanT4YcM25hMcPYkvRLDNkja" + +# RHQggZrkWW9HV8d7o2dvb9mgN1z6tGDJRh KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHQggZrkWW9HV8d7o2dvb9mgN1z6tGDJRh\",\"symbol\":\"KMD\"}" +echo "48415.76246875 <- expected amount RHQggZrkWW9HV8d7o2dvb9mgN1z6tGDJRh" + +# RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4 KMD 295382.69930466, REVS 5860.00000000 +# RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4 KMD 295382.69930466 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4\",\"symbol\":\"KMD\"}" +echo "295382.69930466 <- expected amount RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4" + +# RKyMDKFNC79FhCfnFr58JE1ibpADa2WScE KMD 64965.94673778 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKyMDKFNC79FhCfnFr58JE1ibpADa2WScE\",\"symbol\":\"KMD\"}" +echo "64965.94673778 <- expected amount RKyMDKFNC79FhCfnFr58JE1ibpADa2WScE" + +# RHoPZSxWRgeQp7nB3eTn4dyDpmBRoZPoKv KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHoPZSxWRgeQp7nB3eTn4dyDpmBRoZPoKv\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RHoPZSxWRgeQp7nB3eTn4dyDpmBRoZPoKv" + +# RGiA2sP25BqtW9qfJ3vRUAPH8zbgepwriY KMD 2414.30320001 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGiA2sP25BqtW9qfJ3vRUAPH8zbgepwriY\",\"symbol\":\"KMD\"}" +echo "2414.30320001 <- expected amount RGiA2sP25BqtW9qfJ3vRUAPH8zbgepwriY" + +# RTHtdb735hqJi5DJjXNiP2LREkqUL5b8Sx KMD 19375.01982474 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTHtdb735hqJi5DJjXNiP2LREkqUL5b8Sx\",\"symbol\":\"KMD\"}" +echo "19375.01982474 <- expected amount RTHtdb735hqJi5DJjXNiP2LREkqUL5b8Sx" + +# RHZR3YhrgxaYASvNUrcVdoonXCfgrdGULz KMD 1589788.37880130 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHZR3YhrgxaYASvNUrcVdoonXCfgrdGULz\",\"symbol\":\"KMD\"}" +echo "1589788.37880130 <- expected amount RHZR3YhrgxaYASvNUrcVdoonXCfgrdGULz" + +# RCaxwG9VfLVvxMVvc5q7SQxRSuwR9amxoy KMD 4458.42312105 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCaxwG9VfLVvxMVvc5q7SQxRSuwR9amxoy\",\"symbol\":\"KMD\"}" +echo "4458.42312105 <- expected amount RCaxwG9VfLVvxMVvc5q7SQxRSuwR9amxoy" + +# RAyEy5vxNeAAeRw57BrsN5Kh4zu8i3KYEf KMD 21120.82823309 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAyEy5vxNeAAeRw57BrsN5Kh4zu8i3KYEf\",\"symbol\":\"KMD\"}" +echo "21120.82823309 <- expected amount RAyEy5vxNeAAeRw57BrsN5Kh4zu8i3KYEf" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 6566.15472364 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" +echo "6566.15472364 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT KMD 59621.32507756, REVS 606.36817953 +# RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT KMD 59621.32507756 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT\",\"symbol\":\"KMD\"}" +echo "59621.32507756 <- expected amount RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT" + +# RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p KMD 23159.75532541, REVS 459.58469952 +# RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p KMD 23159.75532541 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p\",\"symbol\":\"KMD\"}" +echo "23159.75532541 <- expected amount RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p" + +# RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV" + +# RQft1wNt3sgntZDRbpz2WzHDy4F2TRamhB KMD 1504.76189752 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQft1wNt3sgntZDRbpz2WzHDy4F2TRamhB\",\"symbol\":\"KMD\"}" +echo "1504.76189752 <- expected amount RQft1wNt3sgntZDRbpz2WzHDy4F2TRamhB" + +# RRergGKQPDcYHU8PxKhpx6kmR7mXdqp8Ce KMD 1452.47287406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRergGKQPDcYHU8PxKhpx6kmR7mXdqp8Ce\",\"symbol\":\"KMD\"}" +echo "1452.47287406 <- expected amount RRergGKQPDcYHU8PxKhpx6kmR7mXdqp8Ce" + +# RDPo9tEaM9Ds5UePeQS1pAFqXzD1ZVvS1n KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDPo9tEaM9Ds5UePeQS1pAFqXzD1ZVvS1n\",\"symbol\":\"KMD\"}" +echo "7746.52199500 <- expected amount RDPo9tEaM9Ds5UePeQS1pAFqXzD1ZVvS1n" + +# RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ KMD 77304.58455563, REVS 1533.20000000 +# RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ KMD 77304.58455563 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ\",\"symbol\":\"KMD\"}" +echo "77304.58455563 <- expected amount RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ" + +# RNpa2spCJutTMYHgsr6MwM6X2pmRfYd6LT KMD 894.72329042 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNpa2spCJutTMYHgsr6MwM6X2pmRfYd6LT\",\"symbol\":\"KMD\"}" +echo "894.72329042 <- expected amount RNpa2spCJutTMYHgsr6MwM6X2pmRfYd6LT" + + +# total KMD 0.00000000 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch10 b/iguana/tests/KMD.batch10 new file mode 100755 index 000000000..6bbf67eca --- /dev/null +++ b/iguana/tests/KMD.batch10 @@ -0,0 +1,164 @@ +# RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d KMD 6266.43352646 +./komodo-cli sendtoaddress RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d 6266.43352646 +sleep 3 +echo "6266.43352646 <- expected amount RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d" + +# R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6 KMD 1203.04246569 +./komodo-cli sendtoaddress R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6 1203.04246569 +sleep 3 +echo "1203.04246569 <- expected amount R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6" + +# RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j KMD 9683.15249375 +./komodo-cli sendtoaddress RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 306877.42641191 +./komodo-cli sendtoaddress RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT 306877.42641191 +sleep 3 +echo "306877.42641191 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RQantoJxT8szwfAqUM3enLPe85YiQtwndH KMD 150.23706901 +./komodo-cli sendtoaddress RQantoJxT8szwfAqUM3enLPe85YiQtwndH 150.23706901 +sleep 3 +echo "150.23706901 <- expected amount RQantoJxT8szwfAqUM3enLPe85YiQtwndH" + +# RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY KMD 1985.04626121 +./komodo-cli sendtoaddress RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY 1985.04626121 +sleep 3 +echo "1985.04626121 <- expected amount RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY" + +# RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE KMD 1664.32251109 +./komodo-cli sendtoaddress RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE 1664.32251109 +sleep 3 +echo "1664.32251109 <- expected amount RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 5.99800973 +./komodo-cli sendtoaddress RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 5.99800973 +sleep 3 +echo "5.99800973 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc KMD 9671.53271075 +./komodo-cli sendtoaddress RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc 9671.53271075 +sleep 3 +echo "9671.53271075 <- expected amount RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc" + +# RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm KMD 40223.19497203, REVS 101.00000000 +# RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm KMD 40223.19497203 +./komodo-cli sendtoaddress RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm 40223.19497203 +sleep 3 +echo "40223.19497203 <- expected amount RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 72698.53877152 +./komodo-cli sendtoaddress RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB 72698.53877152 +sleep 3 +echo "72698.53877152 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe KMD 9683.15249375 +./komodo-cli sendtoaddress RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe" + +# RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB KMD 3532.13792522 +./komodo-cli sendtoaddress RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB 3532.13792522 +sleep 3 +echo "3532.13792522 <- expected amount RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 309.69366537 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 309.69366537 +sleep 3 +echo "309.69366537 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z KMD 3873.26099750 +./komodo-cli sendtoaddress RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 62053.93460050 +./komodo-cli sendtoaddress RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut 62053.93460050 +sleep 3 +echo "62053.93460050 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs KMD 6506.14889316 +./komodo-cli sendtoaddress REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs 6506.14889316 +sleep 3 +echo "6506.14889316 <- expected amount REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs" + +# RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL KMD 812.78437655 +./komodo-cli sendtoaddress RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL 812.78437655 +sleep 3 +echo "812.78437655 <- expected amount RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL" + +# R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8 KMD 1452.47287406 +./komodo-cli sendtoaddress R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8 1452.47287406 +sleep 3 +echo "1452.47287406 <- expected amount R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8" + +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 867.82549038 +./komodo-cli sendtoaddress RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A 867.82549038 +sleep 3 +echo "867.82549038 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm KMD 8521.17419450 +./komodo-cli sendtoaddress RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm 8521.17419450 +sleep 3 +echo "8521.17419450 <- expected amount RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm" + +# RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM KMD 5328.53865807 +./komodo-cli sendtoaddress RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM 5328.53865807 +sleep 3 +echo "5328.53865807 <- expected amount RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM" + +# RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1 KMD 29049.45748125 +./komodo-cli sendtoaddress RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1 29049.45748125 +sleep 3 +echo "29049.45748125 <- expected amount RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1" + +# RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot KMD 4840.60793162 +./komodo-cli sendtoaddress RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot 4840.60793162 +sleep 3 +echo "4840.60793162 <- expected amount RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot" + +# RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct KMD 2420.78812342 +./komodo-cli sendtoaddress RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct 2420.78812342 +sleep 3 +echo "2420.78812342 <- expected amount RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct" + +# RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC KMD 137.73071692, REVS 2.73426759 +# RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC KMD 137.73071692 +./komodo-cli sendtoaddress RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC 137.73071692 +sleep 3 +echo "137.73071692 <- expected amount RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC" + +# RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM KMD 9737.34607711 +./komodo-cli sendtoaddress RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM 9737.34607711 +sleep 3 +echo "9737.34607711 <- expected amount RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM" + +# RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga KMD 1903.31162313 +./komodo-cli sendtoaddress RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga 1903.31162313 +sleep 3 +echo "1903.31162313 <- expected amount RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga" + +# RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h KMD 99.84182062 +./komodo-cli sendtoaddress RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h 99.84182062 +sleep 3 +echo "99.84182062 <- expected amount RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 1167.24851677 +./komodo-cli sendtoaddress RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF 1167.24851677 +sleep 3 +echo "1167.24851677 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + +# RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD KMD 15095.38306803 +./komodo-cli sendtoaddress RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD 15095.38306803 +sleep 3 +echo "15095.38306803 <- expected amount RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD" + + +# total KMD 618514.84605397 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch10.importaddress b/iguana/tests/KMD.batch10.importaddress new file mode 100755 index 000000000..4ffc9a58c --- /dev/null +++ b/iguana/tests/KMD.batch10.importaddress @@ -0,0 +1,161 @@ +# RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d KMD 6266.43352646 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d\",\"symbol\":\"KMD\"}" # 6266.43352646 +sleep 3 +echo "6266.43352646 <- expected amount RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d" + +# R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6 KMD 1203.04246569 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6\",\"symbol\":\"KMD\"}" # 1203.04246569 +sleep 3 +echo "1203.04246569 <- expected amount R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6" + +# RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 306877.42641191 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT\",\"symbol\":\"KMD\"}" # 306877.42641191 +sleep 3 +echo "306877.42641191 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RQantoJxT8szwfAqUM3enLPe85YiQtwndH KMD 150.23706901 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQantoJxT8szwfAqUM3enLPe85YiQtwndH\",\"symbol\":\"KMD\"}" # 150.23706901 +sleep 3 +echo "150.23706901 <- expected amount RQantoJxT8szwfAqUM3enLPe85YiQtwndH" + +# RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY KMD 1985.04626121 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY\",\"symbol\":\"KMD\"}" # 1985.04626121 +sleep 3 +echo "1985.04626121 <- expected amount RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY" + +# RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE KMD 1664.32251109 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE\",\"symbol\":\"KMD\"}" # 1664.32251109 +sleep 3 +echo "1664.32251109 <- expected amount RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 5.99800973 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" # 5.99800973 +sleep 3 +echo "5.99800973 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc KMD 9671.53271075 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc\",\"symbol\":\"KMD\"}" # 9671.53271075 +sleep 3 +echo "9671.53271075 <- expected amount RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc" + +# RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm KMD 40223.19497203, REVS 101.00000000 +# RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm KMD 40223.19497203 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm\",\"symbol\":\"KMD\"}" # 40223.19497203 +sleep 3 +echo "40223.19497203 <- expected amount RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 72698.53877152 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" # 72698.53877152 +sleep 3 +echo "72698.53877152 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe" + +# RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB KMD 3532.13792522 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB\",\"symbol\":\"KMD\"}" # 3532.13792522 +sleep 3 +echo "3532.13792522 <- expected amount RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 309.69366537 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" # 309.69366537 +sleep 3 +echo "309.69366537 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z\",\"symbol\":\"KMD\"}" # 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 62053.93460050 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut\",\"symbol\":\"KMD\"}" # 62053.93460050 +sleep 3 +echo "62053.93460050 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs KMD 6506.14889316 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs\",\"symbol\":\"KMD\"}" # 6506.14889316 +sleep 3 +echo "6506.14889316 <- expected amount REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs" + +# RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL KMD 812.78437655 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL\",\"symbol\":\"KMD\"}" # 812.78437655 +sleep 3 +echo "812.78437655 <- expected amount RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL" + +# R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8 KMD 1452.47287406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8\",\"symbol\":\"KMD\"}" # 1452.47287406 +sleep 3 +echo "1452.47287406 <- expected amount R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8" + +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 867.82549038 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" # 867.82549038 +sleep 3 +echo "867.82549038 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm KMD 8521.17419450 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm\",\"symbol\":\"KMD\"}" # 8521.17419450 +sleep 3 +echo "8521.17419450 <- expected amount RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm" + +# RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM KMD 5328.53865807 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM\",\"symbol\":\"KMD\"}" # 5328.53865807 +sleep 3 +echo "5328.53865807 <- expected amount RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM" + +# RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1 KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1\",\"symbol\":\"KMD\"}" # 29049.45748125 +sleep 3 +echo "29049.45748125 <- expected amount RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1" + +# RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot KMD 4840.60793162 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot\",\"symbol\":\"KMD\"}" # 4840.60793162 +sleep 3 +echo "4840.60793162 <- expected amount RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot" + +# RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct KMD 2420.78812342 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct\",\"symbol\":\"KMD\"}" # 2420.78812342 +sleep 3 +echo "2420.78812342 <- expected amount RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct" + +# RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC KMD 137.73071692, REVS 2.73426759 +# RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC KMD 137.73071692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC\",\"symbol\":\"KMD\"}" # 137.73071692 +sleep 3 +echo "137.73071692 <- expected amount RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC" + +# RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM KMD 9737.34607711 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM\",\"symbol\":\"KMD\"}" # 9737.34607711 +sleep 3 +echo "9737.34607711 <- expected amount RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM" + +# RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga KMD 1903.31162313 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga\",\"symbol\":\"KMD\"}" # 1903.31162313 +sleep 3 +echo "1903.31162313 <- expected amount RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga" + +# RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h KMD 99.84182062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h\",\"symbol\":\"KMD\"}" # 99.84182062 +sleep 3 +echo "99.84182062 <- expected amount RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 1167.24851677 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF\",\"symbol\":\"KMD\"}" # 1167.24851677 +sleep 3 +echo "1167.24851677 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + +# RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD KMD 15095.38306803 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD\",\"symbol\":\"KMD\"}" # 15095.38306803 +sleep 3 +echo "15095.38306803 <- expected amount RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD" diff --git a/iguana/tests/KMD.batch10.listunspent b/iguana/tests/KMD.batch10.listunspent new file mode 100755 index 000000000..ef93ac5c0 --- /dev/null +++ b/iguana/tests/KMD.batch10.listunspent @@ -0,0 +1,129 @@ +# RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d KMD 6266.43352646 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d\",\"symbol\":\"KMD\"}" +echo "6266.43352646 <- expected amount RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d" + +# R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6 KMD 1203.04246569 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6\",\"symbol\":\"KMD\"}" +echo "1203.04246569 <- expected amount R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6" + +# RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 306877.42641191 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT\",\"symbol\":\"KMD\"}" +echo "306877.42641191 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RQantoJxT8szwfAqUM3enLPe85YiQtwndH KMD 150.23706901 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQantoJxT8szwfAqUM3enLPe85YiQtwndH\",\"symbol\":\"KMD\"}" +echo "150.23706901 <- expected amount RQantoJxT8szwfAqUM3enLPe85YiQtwndH" + +# RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY KMD 1985.04626121 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY\",\"symbol\":\"KMD\"}" +echo "1985.04626121 <- expected amount RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY" + +# RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE KMD 1664.32251109 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE\",\"symbol\":\"KMD\"}" +echo "1664.32251109 <- expected amount RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 5.99800973 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" +echo "5.99800973 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc KMD 9671.53271075 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc\",\"symbol\":\"KMD\"}" +echo "9671.53271075 <- expected amount RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc" + +# RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm KMD 40223.19497203, REVS 101.00000000 +# RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm KMD 40223.19497203 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm\",\"symbol\":\"KMD\"}" +echo "40223.19497203 <- expected amount RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 72698.53877152 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" +echo "72698.53877152 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe" + +# RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB KMD 3532.13792522 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB\",\"symbol\":\"KMD\"}" +echo "3532.13792522 <- expected amount RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 309.69366537 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "309.69366537 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z\",\"symbol\":\"KMD\"}" +echo "3873.26099750 <- expected amount RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 62053.93460050 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut\",\"symbol\":\"KMD\"}" +echo "62053.93460050 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs KMD 6506.14889316 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs\",\"symbol\":\"KMD\"}" +echo "6506.14889316 <- expected amount REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs" + +# RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL KMD 812.78437655 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL\",\"symbol\":\"KMD\"}" +echo "812.78437655 <- expected amount RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL" + +# R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8 KMD 1452.47287406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8\",\"symbol\":\"KMD\"}" +echo "1452.47287406 <- expected amount R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8" + +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 867.82549038 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" +echo "867.82549038 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm KMD 8521.17419450 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm\",\"symbol\":\"KMD\"}" +echo "8521.17419450 <- expected amount RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm" + +# RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM KMD 5328.53865807 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM\",\"symbol\":\"KMD\"}" +echo "5328.53865807 <- expected amount RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM" + +# RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1 KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1\",\"symbol\":\"KMD\"}" +echo "29049.45748125 <- expected amount RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1" + +# RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot KMD 4840.60793162 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot\",\"symbol\":\"KMD\"}" +echo "4840.60793162 <- expected amount RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot" + +# RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct KMD 2420.78812342 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct\",\"symbol\":\"KMD\"}" +echo "2420.78812342 <- expected amount RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct" + +# RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC KMD 137.73071692, REVS 2.73426759 +# RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC KMD 137.73071692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC\",\"symbol\":\"KMD\"}" +echo "137.73071692 <- expected amount RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC" + +# RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM KMD 9737.34607711 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM\",\"symbol\":\"KMD\"}" +echo "9737.34607711 <- expected amount RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM" + +# RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga KMD 1903.31162313 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga\",\"symbol\":\"KMD\"}" +echo "1903.31162313 <- expected amount RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga" + +# RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h KMD 99.84182062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h\",\"symbol\":\"KMD\"}" +echo "99.84182062 <- expected amount RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 1167.24851677 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF\",\"symbol\":\"KMD\"}" +echo "1167.24851677 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + +# RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD KMD 15095.38306803 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD\",\"symbol\":\"KMD\"}" +echo "15095.38306803 <- expected amount RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD" diff --git a/iguana/tests/KMD.batch10.txids b/iguana/tests/KMD.batch10.txids new file mode 100644 index 000000000..d7ae5c94b --- /dev/null +++ b/iguana/tests/KMD.batch10.txids @@ -0,0 +1,64 @@ +8b0336f166b8b6348c7af6b382ba5d5f4aa6e266922b19725e79290ee9839bf2 +6266.43352646 <- expected amount RQC6A3SKtLb2zmqDDwFvRH6Zz4mZufmp3d +f88163328ebfd735ffe40077fadb0fb8b79020943a8e5822b47fba735a4a20a2 +1203.04246569 <- expected amount R9SpRcd2KRD45B7SqzuUFhNnsnx7YqgkN6 +af967b9d98defc983047da835bd783fe66b527292052acf56197456344431826 +9683.15249375 <- expected amount RCA8H1npFPW5pnJRzycF8tFEJmn6XZhD4j +fedd862fdf4749676410a4b7babf3139c6cf624fd8f6c9620fd95256a7300600 +306877.42641191 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT +97cae9d83eadecc26cacd272880bd5120bb66aa3df3a65f37d53793c9c1d3154 +150.23706901 <- expected amount RQantoJxT8szwfAqUM3enLPe85YiQtwndH +d641a19ecb1f4d0e5938a18e794ab3b3931f12669e952b40ccadad71c29b7f09 +1985.04626121 <- expected amount RLvvwtBUupmGDy81CJNp6RxKbxxbuu3jRY +f14d32323d2f001a2bf6ca8b88c3a15252a71d80174d6390c61902d06d5f4b84 +1664.32251109 <- expected amount RFdRKqe82MmvSxZQjgtLfzdf8mNHztKpPE +fcda442735f5627876d069940adc2448f3ba60024a214f48cbbc88123167961d +5.99800973 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 +f13e4009f2c3fa3c4f97a0798f1bf1e3df0a4f8470613a125683bd052b1d94ae +9671.53271075 <- expected amount RNYMy1joru9gFitzokTSi5qFFc5nS4iFxc +edb2103b5a7577241d8d3cc7564426b6230ed9ed6a26b0a43cc8ec09d5a76bf3 +40223.19497203 <- expected amount RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm +8cdc1454b6f872eac3d95c95295816678f1bcb759bc8a7134399951c2b4d0a2f +72698.53877152 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB +70ea0803296924e353f9c21a3a24b9167868b84219610f6b0e5544622ade573d +9683.15249375 <- expected amount RVzFdNGRn8Ekr4XaeDSfE9fjqvKdcVicJe +df969fd9a0676e0a51c132432fd67fc1dba5e3fa6049bc1c81a0f3d2d32f1bf6 +3532.13792522 <- expected amount RTbTzn7FGJWwrH1E3fMwuZPs3YVH1MvVoB +1b06ade94bbc568b7fd6d9a5eb786aa05df77956c4dc3012fff2225dc3338b3c +309.69366537 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ +6356a4dd940d6e859b58fe866eacd8ff58f2d68ae46eec4376e722a26a7fa542 +3873.26099750 <- expected amount RYYgc5UD7X18E6CrDXCs1cts5WDwaWhm1Z +dea38f0d030f416d7030c8531b23fedd559410f82f23d4927e62ec3b987406fe +62053.93460050 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut +f0c32f919b860494e924953cbb8c18b7ebc48579eca47ca1f42212afa8471b89 +6506.14889316 <- expected amount REKnBAyZMnhKzRozzcuv6fKRtoBsKTFYjs +ce24b5ff26df4d10e2a34dfaa00949e6eab54c921d5be815c39b0dec50a7aac1 +812.78437655 <- expected amount RY422uSvkAoZy81uGot5PmXuMrtChhJ3uL +d301f1d220d66363aa9c8a4ce2ae3ff24b7b554577e862a8f4a0fa3650c87591 +1452.47287406 <- expected amount R9o3CQms16CLu63j9WdqsaWB3XsssRXEq8 +50b56b7eaa17403473c107706ca4f7d15dc43907e643ff70b9613476e9a88a1a +867.82549038 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A +48de26c072cc1792774528721c912b9c88245ecad1e8cc8c0e18d9b030dc483e +693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv +4faf242258a3b3a78f2e4d4217370c5bc1bd836990e4889f74c040cad2aaabfb +8521.17419450 <- expected amount RCfBinKfJ1wGSxXLPNTmC9bohFRoofUiVm +00f9410471f1953fa2379f9add97d377c0618ed03a489fbff2c2b4d2a41e59c3 +5328.53865807 <- expected amount RNEZRHeWE3KgSTUr3qvH7RNvM2JWZZkygM +8cf3efea2f6972a7e04b6d75478e54e6667fe8f88effc8a20b38f9dbbc9b03e7 +29049.45748125 <- expected amount RH7tsX9PaKECxSEALpu5EWdmEKikY7R2n1 +12f13b23bfbb519a7e2c18c7d4826ab702eee8769f4f27914e9d3b6c13b7c315 +4840.60793162 <- expected amount RYHxrTNpqrAHRbULboJVYHWqmnmVhzzrot +62315b5822e8b04541cbb0db97dcd65b93ab3b95c6ef5d6aebf3a8efa4ea55d1 +2420.78812342 <- expected amount RLCEGw7zmAhZQYtP23Z2TD45gAT9ZuZKct +3c45078d8bf67b966d4dd73a12a9963ae0638fae5af4f2a49de6f54bf507d9de +137.73071692 <- expected amount RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC +5e4daa037126cd384ec76452baa4a8388c468fd6e81d1f72b249b8de922fd403 +9737.34607711 <- expected amount RRdDD2YoR5cfwktePGGFT5cEyRcWkEjzvM +5ab178d63a2d12f5d8c906e9de598708284d0d9e13da61dd5658dc5f5040755b +1903.31162313 <- expected amount RKbb9NGB3pU2BaByoDwyZDH74E7koR2Lga +8ba4ff8dcfda0490c7927afb042768de0ea8d9f8eea89112430bc8363c736703 +99.84182062 <- expected amount RQsSsmpzFagxRaYk6cTMpNHa4eYLihKn8h +7d9c76b94c599a9cb2a0aa5301d722186fc130ac883929ef6952d9cf95e2fbd0 +1167.24851677 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF +7e291c577c4695ae3a6363ff9091d3e1f2d61d3038e324c0222677ec8cf27aee +15095.38306803 <- expected amount RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD diff --git a/iguana/tests/KMD.batch11 b/iguana/tests/KMD.batch11 new file mode 100755 index 000000000..c427e01db --- /dev/null +++ b/iguana/tests/KMD.batch11 @@ -0,0 +1,191 @@ +sleep 99999 +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 42.40642295 +./komodo-cli sendtoaddress RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A 42.40642295 +sleep 3 +echo "42.40642295 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v KMD 1248.93505747 +./komodo-cli sendtoaddress RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v 1248.93505747 +sleep 3 +echo "1248.93505747 <- expected amount RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 2684.14739323 +./komodo-cli sendtoaddress RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ 2684.14739323 +sleep 3 +echo "2684.14739323 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A KMD 19366.30498750 +./komodo-cli sendtoaddress RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A 19366.30498750 +sleep 3 +echo "19366.30498750 <- expected amount RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 209558.53271075 +./komodo-cli sendtoaddress RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB 209558.53271075 +sleep 3 +echo "209558.53271075 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 32675.00548454 +./komodo-cli sendtoaddress RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY 32675.00548454 +sleep 3 +echo "32675.00548454 <- expected amount RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY" + +# RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK KMD 15037.55193116 +./komodo-cli sendtoaddress RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK 15037.55193116 +sleep 3 +echo "15037.55193116 <- expected amount RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK" + +# RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn KMD 1022.54090334 +./komodo-cli sendtoaddress RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn 1022.54090334 +sleep 3 +echo "1022.54090334 <- expected amount RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 172688.45447080 +./komodo-cli sendtoaddress RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT 172688.45447080 +sleep 3 +echo "172688.45447080 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC KMD 35255.61377633 +./komodo-cli sendtoaddress RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC 35255.61377633 +sleep 3 +echo "35255.61377633 <- expected amount RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC" + +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 4509.36353351 +./komodo-cli sendtoaddress RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 4509.36353351 +sleep 3 +echo "4509.36353351 <- expected amount RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8" + +# RCSH7RtDM51e346niSiUk9HiYDrDiqcyev KMD 8622.26398257 +./komodo-cli sendtoaddress RCSH7RtDM51e346niSiUk9HiYDrDiqcyev 8622.26398257 +sleep 3 +echo "8622.26398257 <- expected amount RCSH7RtDM51e346niSiUk9HiYDrDiqcyev" + +# RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc KMD 1904.65394401, REVS 37.80134078 +# RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc KMD 1904.65394401 +./komodo-cli sendtoaddress RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc 1904.65394401 +sleep 3 +echo "1904.65394401 <- expected amount RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc" + +# RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog KMD 1894.96063707 +./komodo-cli sendtoaddress RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog 1894.96063707 +sleep 3 +echo "1894.96063707 <- expected amount RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog" + +# RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ KMD 55379.83556127 +./komodo-cli sendtoaddress RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ 55379.83556127 +sleep 3 +echo "55379.83556127 <- expected amount RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ" + +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 109.47952512 +./komodo-cli sendtoaddress RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX 109.47952512 +sleep 3 +echo "109.47952512 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX" + +# RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J KMD 2903.00911762 +./komodo-cli sendtoaddress RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J 2903.00911762 +sleep 3 +echo "2903.00911762 <- expected amount RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 8344.85486318 +./komodo-cli sendtoaddress RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 8344.85486318 +sleep 3 +echo "8344.85486318 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3 KMD 9295.82639400 +./komodo-cli sendtoaddress RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 5784.90308850 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 5784.90308850 +sleep 3 +echo "5784.90308850 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2 KMD 4345.79883919 +./komodo-cli sendtoaddress RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2 4345.79883919 +sleep 3 +echo "4345.79883919 <- expected amount RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 5743.12343812 +./komodo-cli sendtoaddress RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut 5743.12343812 +sleep 3 +echo "5743.12343812 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD KMD 9680.24754799 +./komodo-cli sendtoaddress RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD 9680.24754799 +sleep 3 +echo "9680.24754799 <- expected amount RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD" + +# RBboFD6fhYF11C883DxvLx5dDmbbs73XC3 KMD 1819.54181879 +./komodo-cli sendtoaddress RBboFD6fhYF11C883DxvLx5dDmbbs73XC3 1819.54181879 +sleep 3 +echo "1819.54181879 <- expected amount RBboFD6fhYF11C883DxvLx5dDmbbs73XC3" + +# RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 KMD 863.61179282, REVS 0.91962079 +# RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 KMD 863.61179282 +./komodo-cli sendtoaddress RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 863.61179282 +sleep 3 +echo "863.61179282 <- expected amount RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 0.00050130 +./komodo-cli sendtoaddress RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 0.00050130 +sleep 3 +echo "0.00050130 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr KMD 16087.76566759, REVS 319.20361833 +# RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr KMD 16087.76566759 +./komodo-cli sendtoaddress RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr 16087.76566759 +sleep 3 +echo "16087.76566759 <- expected amount RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr" + +# R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5 KMD 5577.49583640 +./komodo-cli sendtoaddress R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5 5577.49583640 +sleep 3 +echo "5577.49583640 <- expected amount R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5" + +# RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw KMD 774.65219950 +./komodo-cli sendtoaddress RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw 774.65219950 +sleep 3 +echo "774.65219950 <- expected amount RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw" + +# RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2 KMD 13362.75044137 +./komodo-cli sendtoaddress RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2 13362.75044137 +sleep 3 +echo "13362.75044137 <- expected amount RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2" + +# RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ KMD 8569.02441659 +./komodo-cli sendtoaddress RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ 8569.02441659 +sleep 3 +echo "8569.02441659 <- expected amount RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ" + +# RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt KMD 9683.15249375 +./komodo-cli sendtoaddress RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt" + +# RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS KMD 7916.77211172 +./komodo-cli sendtoaddress RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS 7916.77211172 +sleep 3 +echo "7916.77211172 <- expected amount RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS" + +# RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR KMD 722.28571081 +./komodo-cli sendtoaddress RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR 722.28571081 +sleep 3 +echo "722.28571081 <- expected amount RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR" + +# RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1 KMD 709.73247788 +./komodo-cli sendtoaddress RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1 709.73247788 +sleep 3 +echo "709.73247788 <- expected amount RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 419.36278156 +./komodo-cli sendtoaddress RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF 419.36278156 +sleep 3 +echo "419.36278156 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + + +# total KMD 675297.04318319 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch11.importaddress b/iguana/tests/KMD.batch11.importaddress new file mode 100755 index 000000000..572c78113 --- /dev/null +++ b/iguana/tests/KMD.batch11.importaddress @@ -0,0 +1,188 @@ +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 42.40642295 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" # 42.40642295 +sleep 3 +echo "42.40642295 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v KMD 1248.93505747 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v\",\"symbol\":\"KMD\"}" # 1248.93505747 +sleep 3 +echo "1248.93505747 <- expected amount RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 2684.14739323 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ\",\"symbol\":\"KMD\"}" # 2684.14739323 +sleep 3 +echo "2684.14739323 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A\",\"symbol\":\"KMD\"}" # 19366.30498750 +sleep 3 +echo "19366.30498750 <- expected amount RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 209558.53271075 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" # 209558.53271075 +sleep 3 +echo "209558.53271075 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 32675.00548454 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY\",\"symbol\":\"KMD\"}" # 32675.00548454 +sleep 3 +echo "32675.00548454 <- expected amount RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY" + +# RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK KMD 15037.55193116 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK\",\"symbol\":\"KMD\"}" # 15037.55193116 +sleep 3 +echo "15037.55193116 <- expected amount RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK" + +# RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn KMD 1022.54090334 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn\",\"symbol\":\"KMD\"}" # 1022.54090334 +sleep 3 +echo "1022.54090334 <- expected amount RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 172688.45447080 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT\",\"symbol\":\"KMD\"}" # 172688.45447080 +sleep 3 +echo "172688.45447080 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC KMD 35255.61377633 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC\",\"symbol\":\"KMD\"}" # 35255.61377633 +sleep 3 +echo "35255.61377633 <- expected amount RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC" + +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 4509.36353351 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8\",\"symbol\":\"KMD\"}" # 4509.36353351 +sleep 3 +echo "4509.36353351 <- expected amount RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8" + +# RCSH7RtDM51e346niSiUk9HiYDrDiqcyev KMD 8622.26398257 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCSH7RtDM51e346niSiUk9HiYDrDiqcyev\",\"symbol\":\"KMD\"}" # 8622.26398257 +sleep 3 +echo "8622.26398257 <- expected amount RCSH7RtDM51e346niSiUk9HiYDrDiqcyev" + +# RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc KMD 1904.65394401, REVS 37.80134078 +# RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc KMD 1904.65394401 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc\",\"symbol\":\"KMD\"}" # 1904.65394401 +sleep 3 +echo "1904.65394401 <- expected amount RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc" + +# RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog KMD 1894.96063707 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog\",\"symbol\":\"KMD\"}" # 1894.96063707 +sleep 3 +echo "1894.96063707 <- expected amount RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog" + +# RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ KMD 55379.83556127 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ\",\"symbol\":\"KMD\"}" # 55379.83556127 +sleep 3 +echo "55379.83556127 <- expected amount RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ" + +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 109.47952512 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX\",\"symbol\":\"KMD\"}" # 109.47952512 +sleep 3 +echo "109.47952512 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX" + +# RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J KMD 2903.00911762 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J\",\"symbol\":\"KMD\"}" # 2903.00911762 +sleep 3 +echo "2903.00911762 <- expected amount RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 8344.85486318 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" # 8344.85486318 +sleep 3 +echo "8344.85486318 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3 KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3\",\"symbol\":\"KMD\"}" # 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 5784.90308850 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" # 5784.90308850 +sleep 3 +echo "5784.90308850 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2 KMD 4345.79883919 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2\",\"symbol\":\"KMD\"}" # 4345.79883919 +sleep 3 +echo "4345.79883919 <- expected amount RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 5743.12343812 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" # 5743.12343812 +sleep 3 +echo "5743.12343812 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD KMD 9680.24754799 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD\",\"symbol\":\"KMD\"}" # 9680.24754799 +sleep 3 +echo "9680.24754799 <- expected amount RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD" + +# RBboFD6fhYF11C883DxvLx5dDmbbs73XC3 KMD 1819.54181879 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBboFD6fhYF11C883DxvLx5dDmbbs73XC3\",\"symbol\":\"KMD\"}" # 1819.54181879 +sleep 3 +echo "1819.54181879 <- expected amount RBboFD6fhYF11C883DxvLx5dDmbbs73XC3" + +# RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 KMD 863.61179282, REVS 0.91962079 +# RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 KMD 863.61179282 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5\",\"symbol\":\"KMD\"}" # 863.61179282 +sleep 3 +echo "863.61179282 <- expected amount RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 0.00050130 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9\",\"symbol\":\"KMD\"}" # 0.00050130 +sleep 3 +echo "0.00050130 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr KMD 16087.76566759, REVS 319.20361833 +# RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr KMD 16087.76566759 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr\",\"symbol\":\"KMD\"}" # 16087.76566759 +sleep 3 +echo "16087.76566759 <- expected amount RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr" + +# R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5 KMD 5577.49583640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5\",\"symbol\":\"KMD\"}" # 5577.49583640 +sleep 3 +echo "5577.49583640 <- expected amount R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5" + +# RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw\",\"symbol\":\"KMD\"}" # 774.65219950 +sleep 3 +echo "774.65219950 <- expected amount RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw" + +# RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2 KMD 13362.75044137 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2\",\"symbol\":\"KMD\"}" # 13362.75044137 +sleep 3 +echo "13362.75044137 <- expected amount RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2" + +# RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ KMD 8569.02441659 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ\",\"symbol\":\"KMD\"}" # 8569.02441659 +sleep 3 +echo "8569.02441659 <- expected amount RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ" + +# RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt" + +# RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS KMD 7916.77211172 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS\",\"symbol\":\"KMD\"}" # 7916.77211172 +sleep 3 +echo "7916.77211172 <- expected amount RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS" + +# RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR\",\"symbol\":\"KMD\"}" # 722.28571081 +sleep 3 +echo "722.28571081 <- expected amount RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR" + +# RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1 KMD 709.73247788 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1\",\"symbol\":\"KMD\"}" # 709.73247788 +sleep 3 +echo "709.73247788 <- expected amount RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 419.36278156 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF\",\"symbol\":\"KMD\"}" # 419.36278156 +sleep 3 +echo "419.36278156 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + diff --git a/iguana/tests/KMD.batch11.listunspent b/iguana/tests/KMD.batch11.listunspent new file mode 100755 index 000000000..6ac504d86 --- /dev/null +++ b/iguana/tests/KMD.batch11.listunspent @@ -0,0 +1,151 @@ +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 42.40642295 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" +echo "42.40642295 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v KMD 1248.93505747 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v\",\"symbol\":\"KMD\"}" +echo "1248.93505747 <- expected amount RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 2684.14739323 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ\",\"symbol\":\"KMD\"}" +echo "2684.14739323 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A\",\"symbol\":\"KMD\"}" +echo "19366.30498750 <- expected amount RTUWRmRe543k8vrwuRXQ7BkFhkK4i2dq5A" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 209558.53271075 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" +echo "209558.53271075 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 32675.00548454 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY\",\"symbol\":\"KMD\"}" +echo "32675.00548454 <- expected amount RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY" + +# RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK KMD 15037.55193116 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK\",\"symbol\":\"KMD\"}" +echo "15037.55193116 <- expected amount RNUw6ePdaQ4mXSo9koqGtMDzEC43gCvDrK" + +# RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn KMD 1022.54090334 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn\",\"symbol\":\"KMD\"}" +echo "1022.54090334 <- expected amount RLu6gRHKwXjvv64QZGiLT7uHEVRrH9mHDn" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 172688.45447080 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT\",\"symbol\":\"KMD\"}" +echo "172688.45447080 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC KMD 35255.61377633 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC\",\"symbol\":\"KMD\"}" +echo "35255.61377633 <- expected amount RDKb3QykRJNfLKWLcbbv9z7xqbtxwB54GC" + +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 4509.36353351 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8\",\"symbol\":\"KMD\"}" +echo "4509.36353351 <- expected amount RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8" + +# RCSH7RtDM51e346niSiUk9HiYDrDiqcyev KMD 8622.26398257 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCSH7RtDM51e346niSiUk9HiYDrDiqcyev\",\"symbol\":\"KMD\"}" +echo "8622.26398257 <- expected amount RCSH7RtDM51e346niSiUk9HiYDrDiqcyev" + +# RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc KMD 1904.65394401, REVS 37.80134078 +# RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc KMD 1904.65394401 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc\",\"symbol\":\"KMD\"}" +echo "1904.65394401 <- expected amount RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc" + +# RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog KMD 1894.96063707 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog\",\"symbol\":\"KMD\"}" +echo "1894.96063707 <- expected amount RUr4x8gjCU9EmbLWpYBdsJDyt1oye52iog" + +# RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ KMD 55379.83556127 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ\",\"symbol\":\"KMD\"}" +echo "55379.83556127 <- expected amount RBW6wjWoEsu22APzSfJemWi96bQZFJvEGZ" + +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 109.47952512 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX\",\"symbol\":\"KMD\"}" +echo "109.47952512 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX" + +# RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J KMD 2903.00911762 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J\",\"symbol\":\"KMD\"}" +echo "2903.00911762 <- expected amount RXs11ZkaMLV9ZVAJ93LNjF4TRri2QBHn4J" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 8344.85486318 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" +echo "8344.85486318 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3 KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RQM36oUWQFipUvhPnyoNr8f8CgmJ6W6HR3" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 5784.90308850 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "5784.90308850 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2 KMD 4345.79883919 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2\",\"symbol\":\"KMD\"}" +echo "4345.79883919 <- expected amount RFkDDs1eZCQmAKknvyrP5XbpyeaihFaFL2" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 5743.12343812 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" +echo "5743.12343812 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD KMD 9680.24754799 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD\",\"symbol\":\"KMD\"}" +echo "9680.24754799 <- expected amount RTSn55yrw2xUWM8bxVcG84ga84dofPfsuD" + +# RBboFD6fhYF11C883DxvLx5dDmbbs73XC3 KMD 1819.54181879 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBboFD6fhYF11C883DxvLx5dDmbbs73XC3\",\"symbol\":\"KMD\"}" +echo "1819.54181879 <- expected amount RBboFD6fhYF11C883DxvLx5dDmbbs73XC3" + +# RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 KMD 863.61179282, REVS 0.91962079 +# RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 KMD 863.61179282 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5\",\"symbol\":\"KMD\"}" +echo "863.61179282 <- expected amount RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 0.00050130 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9\",\"symbol\":\"KMD\"}" +echo "0.00050130 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr KMD 16087.76566759, REVS 319.20361833 +# RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr KMD 16087.76566759 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr\",\"symbol\":\"KMD\"}" +echo "16087.76566759 <- expected amount RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr" + +# R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5 KMD 5577.49583640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5\",\"symbol\":\"KMD\"}" +echo "5577.49583640 <- expected amount R9V8qEoa5zjgoJ2kDARXTyhjjvkzcTANC5" + +# RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw\",\"symbol\":\"KMD\"}" +echo "774.65219950 <- expected amount RJJdqon3kYcXtyiTujiHBxAMj9QXrgfUbw" + +# RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2 KMD 13362.75044137 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2\",\"symbol\":\"KMD\"}" +echo "13362.75044137 <- expected amount RNqJvqLSS9zpCJYFv8gDPgeUBx72Hk4as2" + +# RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ KMD 8569.02441659 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ\",\"symbol\":\"KMD\"}" +echo "8569.02441659 <- expected amount RH8i5cGy1QMK2sTehLEAqjX2Ph8FJ94LWJ" + +# RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RCEXKrX2kkQQrFu6arLBLNYYZFtdgHwATt" + +# RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS KMD 7916.77211172 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS\",\"symbol\":\"KMD\"}" +echo "7916.77211172 <- expected amount RE3f1f5XQsntqQkwpVZwyzr1YbupdPbjiS" + +# RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR\",\"symbol\":\"KMD\"}" +echo "722.28571081 <- expected amount RWoKDt8BzEQc3WtYUpXmCxRwB1Tg3AWcPR" + +# RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1 KMD 709.73247788 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1\",\"symbol\":\"KMD\"}" +echo "709.73247788 <- expected amount RNwfApozgMUmKvJCdrJWQZZCw3hEUWaNk1" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 419.36278156 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF\",\"symbol\":\"KMD\"}" +echo "419.36278156 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + diff --git a/iguana/tests/KMD.batch12 b/iguana/tests/KMD.batch12 new file mode 100755 index 000000000..f4b24ca4a --- /dev/null +++ b/iguana/tests/KMD.batch12 @@ -0,0 +1,141 @@ +# RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762, REVS 31.12033224 +# RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762 +./komodo-cli sendtoaddress RDTjem9CP97XPXvet1sQBb428xrmSZJSsd 1568.45531762 +sleep 3 +echo "1568.45531762 <- expected amount RDTjem9CP97XPXvet1sQBb428xrmSZJSsd" + +# RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 73430.96919475 +./komodo-cli sendtoaddress RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz 73430.96919475 +sleep 3 +echo "73430.96919475 <- expected amount RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz" + +# RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE KMD 5689.04575312 +./komodo-cli sendtoaddress RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE 5689.04575312 +sleep 3 +echo "5689.04575312 <- expected amount RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE" + +# RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT KMD 17817.00058850 +./komodo-cli sendtoaddress RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT 17817.00058850 +sleep 3 +echo "17817.00058850 <- expected amount RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 202518.10752377 +./komodo-cli sendtoaddress RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB 202518.10752377 +sleep 3 +echo "202518.10752377 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf KMD 6963.60677351 +./komodo-cli sendtoaddress RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf 6963.60677351 +sleep 3 +echo "6963.60677351 <- expected amount RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf" + +# RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv KMD 32042.52085087 +./komodo-cli sendtoaddress RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv 32042.52085087 +sleep 3 +echo "32042.52085087 <- expected amount RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv" + +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 2135.12309659 +./komodo-cli sendtoaddress RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A 2135.12309659 +sleep 3 +echo "2135.12309659 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic KMD 5533.00461690 +./komodo-cli sendtoaddress RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic 5533.00461690 +sleep 3 +echo "5533.00461690 <- expected amount RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic" + +# RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i KMD 50.26846585 +./komodo-cli sendtoaddress RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i 50.26846585 +sleep 3 +echo "50.26846585 <- expected amount RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i" + +# RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7 KMD 1733.05190072 +./komodo-cli sendtoaddress RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7 1733.05190072 +sleep 3 +echo "1733.05190072 <- expected amount RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7" + +# RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290, REVS 139.09398517 +# RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290 +./komodo-cli sendtoaddress RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y 11852.83167290 +sleep 3 +echo "11852.83167290 <- expected amount RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y" + +# RH9CANWQNvqSktmX39ruDfiNFimcToD2ur KMD 43125.33019700 +./komodo-cli sendtoaddress RH9CANWQNvqSktmX39ruDfiNFimcToD2ur 43125.33019700 +sleep 3 +echo "43125.33019700 <- expected amount RH9CANWQNvqSktmX39ruDfiNFimcToD2ur" + +# RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b KMD 36837.09249870 +./komodo-cli sendtoaddress RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b 36837.09249870 +sleep 3 +echo "36837.09249870 <- expected amount RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b" + +# RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526, REVS 59.85500000 +# RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526 +./komodo-cli sendtoaddress RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 3016.26045526 +sleep 3 +echo "3016.26045526 <- expected amount RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8" + +# RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb KMD 91240.39653929 +./komodo-cli sendtoaddress RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb 91240.39653929 +sleep 3 +echo "91240.39653929 <- expected amount RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb" + +# RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury KMD 2440.00507548 +./komodo-cli sendtoaddress RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury 2440.00507548 +sleep 3 +echo "2440.00507548 <- expected amount RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury" + +# RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934, REVS 75.88015839 +# RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934 +./komodo-cli sendtoaddress RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX 3823.81289934 +sleep 3 +echo "3823.81289934 <- expected amount RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 2772.48246697 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 2772.48246697 +sleep 3 +echo "2772.48246697 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 10316.17621736 +./komodo-cli sendtoaddress RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut 10316.17621736 +sleep 3 +echo "10316.17621736 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 29566.93551966 +./komodo-cli sendtoaddress RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW 29566.93551966 +sleep 3 +echo "29566.93551966 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX KMD 19365.33667225 +./komodo-cli sendtoaddress RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX 19365.33667225 +sleep 3 +echo "19365.33667225 <- expected amount RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX" + +# R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X KMD 55229.13842423 +./komodo-cli sendtoaddress R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X 55229.13842423 +sleep 3 +echo "55229.13842423 <- expected amount R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X" + +# RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB KMD 29049.45748125 +./komodo-cli sendtoaddress RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB 29049.45748125 +sleep 3 +echo "29049.45748125 <- expected amount RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 10066.89321267 +./komodo-cli sendtoaddress RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 10066.89321267 +sleep 3 +echo "10066.89321267 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 2834.17657315 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 2834.17657315 +sleep 3 +echo "2834.17657315 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + + +# total KMD 701710.56131060 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch12.importaddress b/iguana/tests/KMD.batch12.importaddress new file mode 100755 index 000000000..c140a3396 --- /dev/null +++ b/iguana/tests/KMD.batch12.importaddress @@ -0,0 +1,139 @@ +# RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762, REVS 31.12033224 +# RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDTjem9CP97XPXvet1sQBb428xrmSZJSsd\",\"symbol\":\"KMD\"}" # 1568.45531762 +sleep 3 +echo "1568.45531762 <- expected amount RDTjem9CP97XPXvet1sQBb428xrmSZJSsd" + +# RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 73430.96919475 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz\",\"symbol\":\"KMD\"}" # 73430.96919475 +sleep 3 +echo "73430.96919475 <- expected amount RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz" + +# RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE KMD 5689.04575312 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE\",\"symbol\":\"KMD\"}" # 5689.04575312 +sleep 3 +echo "5689.04575312 <- expected amount RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE" + +# RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT KMD 17817.00058850 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT\",\"symbol\":\"KMD\"}" # 17817.00058850 +sleep 3 +echo "17817.00058850 <- expected amount RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 202518.10752377 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" # 202518.10752377 +sleep 3 +echo "202518.10752377 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf KMD 6963.60677351 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf\",\"symbol\":\"KMD\"}" # 6963.60677351 +sleep 3 +echo "6963.60677351 <- expected amount RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf" + +# RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv KMD 32042.52085087 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv\",\"symbol\":\"KMD\"}" # 32042.52085087 +sleep 3 +echo "32042.52085087 <- expected amount RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv" + +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 2135.12309659 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" # 2135.12309659 +sleep 3 +echo "2135.12309659 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic KMD 5533.00461690 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic\",\"symbol\":\"KMD\"}" # 5533.00461690 +sleep 3 +echo "5533.00461690 <- expected amount RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic" + +# RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i KMD 50.26846585 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i\",\"symbol\":\"KMD\"}" # 50.26846585 +sleep 3 +echo "50.26846585 <- expected amount RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i" + +# RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7 KMD 1733.05190072 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7\",\"symbol\":\"KMD\"}" # 1733.05190072 +sleep 3 +echo "1733.05190072 <- expected amount RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7" + +# RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290, REVS 139.09398517 +# RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y\",\"symbol\":\"KMD\"}" # 11852.83167290 +sleep 3 +echo "11852.83167290 <- expected amount RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y" + +# RH9CANWQNvqSktmX39ruDfiNFimcToD2ur KMD 43125.33019700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH9CANWQNvqSktmX39ruDfiNFimcToD2ur\",\"symbol\":\"KMD\"}" # 43125.33019700 +sleep 3 +echo "43125.33019700 <- expected amount RH9CANWQNvqSktmX39ruDfiNFimcToD2ur" + +# RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b KMD 36837.09249870 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b\",\"symbol\":\"KMD\"}" # 36837.09249870 +sleep 3 +echo "36837.09249870 <- expected amount RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b" + +# RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526, REVS 59.85500000 +# RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8\",\"symbol\":\"KMD\"}" # 3016.26045526 +sleep 3 +echo "3016.26045526 <- expected amount RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8" + +# RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb KMD 91240.39653929 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb\",\"symbol\":\"KMD\"}" # 91240.39653929 +sleep 3 +echo "91240.39653929 <- expected amount RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb" + +# RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury KMD 2440.00507548 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury\",\"symbol\":\"KMD\"}" # 2440.00507548 +sleep 3 +echo "2440.00507548 <- expected amount RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury" + +# RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934, REVS 75.88015839 +# RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX\",\"symbol\":\"KMD\"}" # 3823.81289934 +sleep 3 +echo "3823.81289934 <- expected amount RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 2772.48246697 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" # 2772.48246697 +sleep 3 +echo "2772.48246697 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 10316.17621736 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" # 10316.17621736 +sleep 3 +echo "10316.17621736 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 29566.93551966 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"KMD\"}" # 29566.93551966 +sleep 3 +echo "29566.93551966 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX KMD 19365.33667225 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX\",\"symbol\":\"KMD\"}" # 19365.33667225 +sleep 3 +echo "19365.33667225 <- expected amount RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX" + +# R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X KMD 55229.13842423 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X\",\"symbol\":\"KMD\"}" # 55229.13842423 +sleep 3 +echo "55229.13842423 <- expected amount R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X" + +# RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB\",\"symbol\":\"KMD\"}" # 29049.45748125 +sleep 3 +echo "29049.45748125 <- expected amount RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 10066.89321267 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" # 10066.89321267 +sleep 3 +echo "10066.89321267 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 2834.17657315 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" # 2834.17657315 +sleep 3 +echo "2834.17657315 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + diff --git a/iguana/tests/KMD.batch12.listunspent b/iguana/tests/KMD.batch12.listunspent new file mode 100755 index 000000000..11e9bfdd0 --- /dev/null +++ b/iguana/tests/KMD.batch12.listunspent @@ -0,0 +1,112 @@ +# RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762, REVS 31.12033224 +# RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RDTjem9CP97XPXvet1sQBb428xrmSZJSsd\",\"symbol\":\"KMD\"}" +echo "1568.45531762 <- expected amount RDTjem9CP97XPXvet1sQBb428xrmSZJSsd" + +# RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 73430.96919475 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz\",\"symbol\":\"KMD\"}" +echo "73430.96919475 <- expected amount RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz" + +# RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE KMD 5689.04575312 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE\",\"symbol\":\"KMD\"}" +echo "5689.04575312 <- expected amount RWxT4Jfwp1Bv6RYdUMdrQ6oXt6dMsQZ8jE" + +# RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT KMD 17817.00058850 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT\",\"symbol\":\"KMD\"}" +echo "17817.00058850 <- expected amount RXQxetCQScefabaJaFyqCJ1FvfNwsKtvMT" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 202518.10752377 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" +echo "202518.10752377 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf KMD 6963.60677351 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf\",\"symbol\":\"KMD\"}" +echo "6963.60677351 <- expected amount RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf" + +# RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv KMD 32042.52085087 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv\",\"symbol\":\"KMD\"}" +echo "32042.52085087 <- expected amount RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv" + +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 2135.12309659 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"KMD\"}" +echo "2135.12309659 <- expected amount RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A" + +# RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic KMD 5533.00461690 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic\",\"symbol\":\"KMD\"}" +echo "5533.00461690 <- expected amount RAGhCfNvxpL55JFV7h2HQa5dSEK86Jg3ic" + +# RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i KMD 50.26846585 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i\",\"symbol\":\"KMD\"}" +echo "50.26846585 <- expected amount RDoLVY35wbzTXZ9QgFRSAzHfAiYYG7e65i" + +# RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7 KMD 1733.05190072 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7\",\"symbol\":\"KMD\"}" +echo "1733.05190072 <- expected amount RMHZ76hvxs8n2yDnkUa122rs5gubMxhiw7" + +# RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290, REVS 139.09398517 +# RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y\",\"symbol\":\"KMD\"}" +echo "11852.83167290 <- expected amount RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y" + +# RH9CANWQNvqSktmX39ruDfiNFimcToD2ur KMD 43125.33019700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RH9CANWQNvqSktmX39ruDfiNFimcToD2ur\",\"symbol\":\"KMD\"}" +echo "43125.33019700 <- expected amount RH9CANWQNvqSktmX39ruDfiNFimcToD2ur" + +# RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b KMD 36837.09249870 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b\",\"symbol\":\"KMD\"}" +echo "36837.09249870 <- expected amount RSp4ceoTDQt7fbweFBpEbvbTTH8J9SEp4b" + +# RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526, REVS 59.85500000 +# RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8\",\"symbol\":\"KMD\"}" +echo "3016.26045526 <- expected amount RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8" + +# RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb KMD 91240.39653929 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb\",\"symbol\":\"KMD\"}" +echo "91240.39653929 <- expected amount RLWvbjH97gqjGXsRyPijDmwuKNFqsaaerb" + +# RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury KMD 2440.00507548 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury\",\"symbol\":\"KMD\"}" +echo "2440.00507548 <- expected amount RGoB4uxdk2SDs5yCerizsQ3UFD7NqJjury" + +# RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934, REVS 75.88015839 +# RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX\",\"symbol\":\"KMD\"}" +echo "3823.81289934 <- expected amount RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 2772.48246697 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "2772.48246697 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 10316.17621736 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" +echo "10316.17621736 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 29566.93551966 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"KMD\"}" +echo "29566.93551966 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX KMD 19365.33667225 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX\",\"symbol\":\"KMD\"}" +echo "19365.33667225 <- expected amount RNQzdseaqPikT6Df2ECFQXxW4yUr4fahqX" + +# R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X KMD 55229.13842423 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X\",\"symbol\":\"KMD\"}" +echo "55229.13842423 <- expected amount R9PwsNzuksjJzZUAAX4yfDwdSy5Y4KP25X" + +# RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB\",\"symbol\":\"KMD\"}" +echo "29049.45748125 <- expected amount RC3DmLpKZyMD66JnKXVRHT9AVcok9xwGgB" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 10066.89321267 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" +echo "10066.89321267 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 2834.17657315 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "2834.17657315 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + diff --git a/iguana/tests/KMD.batch13 b/iguana/tests/KMD.batch13 new file mode 100755 index 000000000..0d9373fc4 --- /dev/null +++ b/iguana/tests/KMD.batch13 @@ -0,0 +1,147 @@ +sleep 999999 +# RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 341.29719958 +./komodo-cli sendtoaddress RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 341.29719958 +sleep 3 +echo "341.29719958 <- expected amount RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2" + +# RD486qQaD85849AdDPH3Xy3iyppuvxDZYf KMD 177091.93551966 +./komodo-cli sendtoaddress RD486qQaD85849AdDPH3Xy3iyppuvxDZYf 177091.93551966 +sleep 3 +echo "177091.93551966 <- expected amount RD486qQaD85849AdDPH3Xy3iyppuvxDZYf" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 10744.59269420 +./komodo-cli sendtoaddress RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 10744.59269420 +sleep 3 +echo "10744.59269420 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 885.02977777 +./komodo-cli sendtoaddress RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ 885.02977777 +sleep 3 +echo "885.02977777 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 1517.32401692 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 1517.32401692 +sleep 3 +echo "1517.32401692 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP KMD 722.28571081 +./komodo-cli sendtoaddress RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP 722.28571081 +sleep 3 +echo "722.28571081 <- expected amount RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP" + +# RS12srxPnksnwwaXrSXLjhu14hBknd26aR KMD 1859.16527880 +./komodo-cli sendtoaddress RS12srxPnksnwwaXrSXLjhu14hBknd26aR 1859.16527880 +sleep 3 +echo "1859.16527880 <- expected amount RS12srxPnksnwwaXrSXLjhu14hBknd26aR" + +# RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw KMD 748.59289950 +./komodo-cli sendtoaddress RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw 748.59289950 +sleep 3 +echo "748.59289950 <- expected amount RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw" + +# RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy KMD 1684.62281766, REVS 33.43442069 +# RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy KMD 1684.62281766 +./komodo-cli sendtoaddress RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy 1684.62281766 +sleep 3 +echo "1684.62281766 <- expected amount RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy" + +# RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc KMD 4850.29108411 +./komodo-cli sendtoaddress RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc 4850.29108411 +sleep 3 +echo "4850.29108411 <- expected amount RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc" + +# RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ KMD 935.39253089 +./komodo-cli sendtoaddress RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ 935.39253089 +sleep 3 +echo "935.39253089 <- expected amount RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ" + +# RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 KMD 86638.13975038, REVS 819.96000000 +# RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 KMD 86638.13975038 +./komodo-cli sendtoaddress RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 86638.13975038 +sleep 3 +echo "86638.13975038 <- expected amount RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4" + +# RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32 KMD 50.26846585 +./komodo-cli sendtoaddress RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32 50.26846585 +sleep 3 +echo "50.26846585 <- expected amount RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32" + +# RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS KMD 3873.26099750 +./komodo-cli sendtoaddress RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 212102.44577315 +./komodo-cli sendtoaddress RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT 212102.44577315 +sleep 3 +echo "212102.44577315 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ KMD 10486.02744190 +./komodo-cli sendtoaddress RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ 10486.02744190 +sleep 3 +echo "10486.02744190 <- expected amount RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do KMD 3389.10337281 +./komodo-cli sendtoaddress RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do 3389.10337281 +sleep 3 +echo "3389.10337281 <- expected amount RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do" + +# RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc KMD 774.65219950 +./komodo-cli sendtoaddress RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc 774.65219950 +sleep 3 +echo "774.65219950 <- expected amount RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 190185.06275980 +./komodo-cli sendtoaddress RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB 190185.06275980 +sleep 3 +echo "190185.06275980 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg KMD 9683.15249375 +./komodo-cli sendtoaddress RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg" + +# RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF KMD 8424.34266955 +./komodo-cli sendtoaddress RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF 8424.34266955 +sleep 3 +echo "8424.34266955 <- expected amount RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF" + +# R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M KMD 6007.48089910 +./komodo-cli sendtoaddress R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M 6007.48089910 +sleep 3 +echo "6007.48089910 <- expected amount R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M" + +# RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE KMD 534.11913087 +./komodo-cli sendtoaddress RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE 534.11913087 +sleep 3 +echo "534.11913087 <- expected amount RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 1.56326640 +./komodo-cli sendtoaddress RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 1.56326640 +sleep 3 +echo "1.56326640 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + +# RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM KMD 678.12202237 +./komodo-cli sendtoaddress RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM 678.12202237 +sleep 3 +echo "678.12202237 <- expected amount RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM" + +# RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE KMD 4841.57624687 +./komodo-cli sendtoaddress RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE 4841.57624687 +sleep 3 +echo "4841.57624687 <- expected amount RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE" + +# RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv KMD 25665.79190427 +./komodo-cli sendtoaddress RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv 25665.79190427 +sleep 3 +echo "25665.79190427 <- expected amount RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 6627.41635888 +./komodo-cli sendtoaddress RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut 6627.41635888 +sleep 3 +echo "6627.41635888 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" diff --git a/iguana/tests/KMD.batch13.listunspent b/iguana/tests/KMD.batch13.listunspent new file mode 100755 index 000000000..06796ec86 --- /dev/null +++ b/iguana/tests/KMD.batch13.listunspent @@ -0,0 +1,118 @@ +# RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 341.29719958 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2\",\"symbol\":\"KMD\"}" +echo "341.29719958 <- expected amount RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2" + +# RD486qQaD85849AdDPH3Xy3iyppuvxDZYf KMD 177091.93551966 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RD486qQaD85849AdDPH3Xy3iyppuvxDZYf\",\"symbol\":\"KMD\"}" +echo "177091.93551966 <- expected amount RD486qQaD85849AdDPH3Xy3iyppuvxDZYf" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 10744.59269420 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" +echo "10744.59269420 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 885.02977777 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ\",\"symbol\":\"KMD\"}" +echo "885.02977777 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 1517.32401692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "1517.32401692 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP\",\"symbol\":\"KMD\"}" +echo "722.28571081 <- expected amount RPY5bFVqHKiSfTGhQgW6USqCA1fbD1auvP" + +# RS12srxPnksnwwaXrSXLjhu14hBknd26aR KMD 1859.16527880 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RS12srxPnksnwwaXrSXLjhu14hBknd26aR\",\"symbol\":\"KMD\"}" +echo "1859.16527880 <- expected amount RS12srxPnksnwwaXrSXLjhu14hBknd26aR" + +# RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw KMD 748.59289950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw\",\"symbol\":\"KMD\"}" +echo "748.59289950 <- expected amount RQCPDTicaag9aa9VF3Vfp97o8bTX4EW9Vw" + +# RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy KMD 1684.62281766, REVS 33.43442069 +# RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy KMD 1684.62281766 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy\",\"symbol\":\"KMD\"}" +echo "1684.62281766 <- expected amount RLvFp2q8XmUpxnimcYUmpyC9vGr3woqTKy" + +# RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc KMD 4850.29108411 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc\",\"symbol\":\"KMD\"}" +echo "4850.29108411 <- expected amount RNFgp4T5uusJXRa2Xy3zPxDe93NHBpw2Nc" + +# RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ KMD 935.39253089 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ\",\"symbol\":\"KMD\"}" +echo "935.39253089 <- expected amount RCgPPsLuB9Do1RVSTpjsD27xxGvKGwr5EJ" + +# RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 KMD 86638.13975038, REVS 819.96000000 +# RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4 KMD 86638.13975038 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4\",\"symbol\":\"KMD\"}" +echo "86638.13975038 <- expected amount RWXMMFMMSv6GZzP1qEKyTkeDmodAueEMp4" + +# RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32 KMD 50.26846585 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32\",\"symbol\":\"KMD\"}" +echo "50.26846585 <- expected amount RTdoQxvwUbqmyF8EAX5uzNGGmWuPZLAy32" + +# RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS\",\"symbol\":\"KMD\"}" +echo "3873.26099750 <- expected amount RA5woupBAsRPAkaBVWiRsxWyoYdAV8v5pS" + +# RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT KMD 212102.44577315 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT\",\"symbol\":\"KMD\"}" +echo "212102.44577315 <- expected amount RTJXwRhuAH9iyztyuRuGC8G7DamTgSMGvT" + +# RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ KMD 10486.02744190 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ\",\"symbol\":\"KMD\"}" +echo "10486.02744190 <- expected amount RPEpkD8hNeLC4eJTM3VZvem43nnbVpaetZ" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do KMD 3389.10337281 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do\",\"symbol\":\"KMD\"}" +echo "3389.10337281 <- expected amount RJxAyUaeV87C1evoXNPSV8qVeKygSQk4Do" + +# RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc\",\"symbol\":\"KMD\"}" +echo "774.65219950 <- expected amount RKV15G5AC9HzEFVaZtYRwBLp33MaiHdHNc" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 190185.06275980 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" +echo "190185.06275980 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RLtagTCmTjMkWTBgM6ibGe12p7ufn9nWRg" + +# RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF KMD 8424.34266955 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF\",\"symbol\":\"KMD\"}" +echo "8424.34266955 <- expected amount RSfqroC8ApjqJgTu7p4TdBp6M6sWVSYLmF" + +# R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M KMD 6007.48089910 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M\",\"symbol\":\"KMD\"}" +echo "6007.48089910 <- expected amount R9M1LYyerZSgc6mtDVy3d4ViadhjAaSW9M" + +# RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE KMD 534.11913087 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE\",\"symbol\":\"KMD\"}" +echo "534.11913087 <- expected amount RJgEYxCjh5HkxtU4kVaYZUQ7eBS2fEeosE" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 1.56326640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9\",\"symbol\":\"KMD\"}" +echo "1.56326640 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + +# RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM KMD 678.12202237 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM\",\"symbol\":\"KMD\"}" +echo "678.12202237 <- expected amount RSVA6AL1Hi65zGg24YZU9GWu8Pd9ixSKuM" + +# RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE KMD 4841.57624687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE\",\"symbol\":\"KMD\"}" +echo "4841.57624687 <- expected amount RPmxibGkVYqTSM2NcTcuxRYtha2WUeNAQE" + +# RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv KMD 25665.79190427 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv\",\"symbol\":\"KMD\"}" +echo "25665.79190427 <- expected amount RXyXDkiMmU8jdnCuyCrZHqWthU4kp9PUhv" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 6627.41635888 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" +echo "6627.41635888 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + diff --git a/iguana/tests/KMD.batch14 b/iguana/tests/KMD.batch14 new file mode 100755 index 000000000..5b3f4d6fa --- /dev/null +++ b/iguana/tests/KMD.batch14 @@ -0,0 +1,146 @@ +sleep 999999 +# RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj KMD 283716.36806687 +./komodo-cli sendtoaddress RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj 283716.36806687 +sleep 3 +echo "283716.36806687 <- expected amount RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 232.80643392 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 232.80643392 +sleep 3 +echo "232.80643392 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 2247.65412987 +./komodo-cli sendtoaddress RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni 2247.65412987 +sleep 3 +echo "2247.65412987 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 202518.10752377 +./komodo-cli sendtoaddress RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB 202518.10752377 +sleep 3 +echo "202518.10752377 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc KMD 9837.11461840 +./komodo-cli sendtoaddress RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc 9837.11461840 +sleep 3 +echo "9837.11461840 <- expected amount RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc" + +# RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb KMD 6.87037888 +./komodo-cli sendtoaddress RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb 6.87037888 +sleep 3 +echo "6.87037888 <- expected amount RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb" + +# RY43geE3zoc88VbhnExje4J1wCNvX8fvfi KMD 601.90475901 +./komodo-cli sendtoaddress RY43geE3zoc88VbhnExje4J1wCNvX8fvfi 601.90475901 +sleep 3 +echo "601.90475901 <- expected amount RY43geE3zoc88VbhnExje4J1wCNvX8fvfi" + +# RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF KMD 40171.99122689 +./komodo-cli sendtoaddress RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF 40171.99122689 +sleep 3 +echo "40171.99122689 <- expected amount RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF" + +# RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z KMD 1465.10673247 +./komodo-cli sendtoaddress RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z 1465.10673247 +sleep 3 +echo "1465.10673247 <- expected amount RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z" + +# RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ KMD 20449.88848416 +./komodo-cli sendtoaddress RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ 20449.88848416 +sleep 3 +echo "20449.88848416 <- expected amount RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 497.55272329 +./komodo-cli sendtoaddress RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH 497.55272329 +sleep 3 +echo "497.55272329 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 26.76069242 +./komodo-cli sendtoaddress RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 26.76069242 +sleep 3 +echo "26.76069242 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc KMD 2105.68422851, REVS 41.78542648 +# RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc KMD 2105.68422851 +./komodo-cli sendtoaddress RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc 2105.68422851 +sleep 3 +echo "2105.68422851 <- expected amount RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc" + +# RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG KMD 37.03715216 +./komodo-cli sendtoaddress RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG 37.03715216 +sleep 3 +echo "37.03715216 <- expected amount RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG" + +# RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW KMD 9295.82639400 +./komodo-cli sendtoaddress RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW" + +# RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe KMD 56299.80756714 +./komodo-cli sendtoaddress RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe 56299.80756714 +sleep 3 +echo "56299.80756714 <- expected amount RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe" + +# RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r KMD 46479.13197000 +./komodo-cli sendtoaddress RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r 46479.13197000 +sleep 3 +echo "46479.13197000 <- expected amount RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r" + +# RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY KMD 21522.57690952 +./komodo-cli sendtoaddress RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY 21522.57690952 +sleep 3 +echo "21522.57690952 <- expected amount RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY" + +# RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR KMD 5510.79545709 +./komodo-cli sendtoaddress RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR 5510.79545709 +sleep 3 +echo "5510.79545709 <- expected amount RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR" + +# RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY KMD 38732.60997500 +./komodo-cli sendtoaddress RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY 38732.60997500 +sleep 3 +echo "38732.60997500 <- expected amount RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY" + +# RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk KMD 1524.15725197 +./komodo-cli sendtoaddress RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk 1524.15725197 +sleep 3 +echo "1524.15725197 <- expected amount RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk" + +# RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw KMD 21460.18988274 +./komodo-cli sendtoaddress RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw 21460.18988274 +sleep 3 +echo "21460.18988274 <- expected amount RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 4938.88955074 +./komodo-cli sendtoaddress RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW 4938.88955074 +sleep 3 +echo "4938.88955074 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3 KMD 37183.30557600 +./komodo-cli sendtoaddress RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3 37183.30557600 +sleep 3 +echo "37183.30557600 <- expected amount RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck KMD 29783.79369585 +./komodo-cli sendtoaddress R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck 29783.79369585 +sleep 3 +echo "29783.79369585 <- expected amount R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck" + +# RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3 KMD 9683.15249375 +./komodo-cli sendtoaddress RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 4040.77614254 +./komodo-cli sendtoaddress RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK 4040.77614254 +sleep 3 +echo "4040.77614254 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 47536.89479581 +./komodo-cli sendtoaddress RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 47536.89479581 +sleep 3 +echo "47536.89479581 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" diff --git a/iguana/tests/KMD.batch14.listunspent b/iguana/tests/KMD.batch14.listunspent new file mode 100755 index 000000000..f64301ab8 --- /dev/null +++ b/iguana/tests/KMD.batch14.listunspent @@ -0,0 +1,117 @@ +# RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj KMD 283716.36806687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj\",\"symbol\":\"KMD\"}" +echo "283716.36806687 <- expected amount RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 232.80643392 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "232.80643392 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 2247.65412987 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni\",\"symbol\":\"KMD\"}" +echo "2247.65412987 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB KMD 202518.10752377 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB\",\"symbol\":\"KMD\"}" +echo "202518.10752377 <- expected amount RPqAFgwnB1hjae6Ar4Kms973uS93HbDkoB" + +# RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc KMD 9837.11461840 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc\",\"symbol\":\"KMD\"}" +echo "9837.11461840 <- expected amount RBQyRBW6RFhcAmoK6UhoqrTgjH3Gz1xdCc" + +# RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb KMD 6.87037888 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb\",\"symbol\":\"KMD\"}" +echo "6.87037888 <- expected amount RDeUhHeM6kaaMg9bNJQDjXrqimqZSeVTqb" + +# RY43geE3zoc88VbhnExje4J1wCNvX8fvfi KMD 601.90475901 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RY43geE3zoc88VbhnExje4J1wCNvX8fvfi\",\"symbol\":\"KMD\"}" +echo "601.90475901 <- expected amount RY43geE3zoc88VbhnExje4J1wCNvX8fvfi" + +# RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF KMD 40171.99122689 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF\",\"symbol\":\"KMD\"}" +echo "40171.99122689 <- expected amount RJ5qNTw5sm9AiHX2129dqBQSFETkP9sYFF" + +# RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z KMD 1465.10673247 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z\",\"symbol\":\"KMD\"}" +echo "1465.10673247 <- expected amount RKbr67Hs4exDXg92LQhVYY4MSuqwbJJN7z" + +# RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ KMD 20449.88848416 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ\",\"symbol\":\"KMD\"}" +echo "20449.88848416 <- expected amount RBjZCbMHCtsqpcQfaQquiNi4s8GTr6uLRZ" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 497.55272329 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH\",\"symbol\":\"KMD\"}" +echo "497.55272329 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 26.76069242 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" +echo "26.76069242 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc KMD 2105.68422851, REVS 41.78542648 +# RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc KMD 2105.68422851 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc\",\"symbol\":\"KMD\"}" +echo "2105.68422851 <- expected amount RKoxsZuFuAHFYCRxpScXjBoTNa2zBALASc" + +# RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG KMD 37.03715216 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG\",\"symbol\":\"KMD\"}" +echo "37.03715216 <- expected amount RC3h8Y3o5Ak7gdiCJ9GPY7EkB3DKd5hqtG" + +# RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RPpsBduDnnpgEZnEYKRKv5j1Ubx32c37jW" + +# RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe KMD 56299.80756714 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe\",\"symbol\":\"KMD\"}" +echo "56299.80756714 <- expected amount RKWNm893ZmBoTDHZ287LhHfigdMbg1i5pe" + +# RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r KMD 46479.13197000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r\",\"symbol\":\"KMD\"}" +echo "46479.13197000 <- expected amount RVCsfNnKexhZfyWzYnVnyYqQ181xNaK83r" + +# RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY KMD 21522.57690952 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY\",\"symbol\":\"KMD\"}" +echo "21522.57690952 <- expected amount RGry1cqvb2DpJ8KVJ8UUx2fe3TxLmmPohY" + +# RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR KMD 5510.79545709 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR\",\"symbol\":\"KMD\"}" +echo "5510.79545709 <- expected amount RJaBNff51EwkwTq6BpmLikW3Wx3XFJ4CZR" + +# RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY KMD 38732.60997500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY\",\"symbol\":\"KMD\"}" +echo "38732.60997500 <- expected amount RSGZVs6APV5K96tEtuRoMwtc3P7h1SfzQY" + +# RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk KMD 1524.15725197 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk\",\"symbol\":\"KMD\"}" +echo "1524.15725197 <- expected amount RGQm8kgDPFCnhB6y6smATMBG8Bq7NPkeKk" + +# RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw KMD 21460.18988274 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw\",\"symbol\":\"KMD\"}" +echo "21460.18988274 <- expected amount RH6ZPNWW8XS9cm5xsEyngQuARXNtUzGFKw" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 4938.88955074 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"KMD\"}" +echo "4938.88955074 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3 KMD 37183.30557600 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3\",\"symbol\":\"KMD\"}" +echo "37183.30557600 <- expected amount RXoWchjAaJatpRYGoD7A2tEuYN1jhdrRv3" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck KMD 29783.79369585 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck\",\"symbol\":\"KMD\"}" +echo "29783.79369585 <- expected amount R9Kpd7dQ5udE7bUBWvQ5sEiTL3hSr5R2Ck" + +# RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3 KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RHh3vqCrFmZsLUKPxnx4yCcAqZ8RSZ2NW3" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 4040.77614254 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK\",\"symbol\":\"KMD\"}" +echo "4040.77614254 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9 KMD 47536.89479581 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9\",\"symbol\":\"KMD\"}" +echo "47536.89479581 <- expected amount RU3EDov1PTPAY8WhG5eGUANp2rvtki1yc9" + diff --git a/iguana/tests/KMD.batch15 b/iguana/tests/KMD.batch15 new file mode 100755 index 000000000..236157660 --- /dev/null +++ b/iguana/tests/KMD.batch15 @@ -0,0 +1,383 @@ +sleep 999999 +# RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge KMD 108355.00859530 +./komodo-cli sendtoaddress RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge 108355.00859530 +sleep 3 +echo "108355.00859530 <- expected amount RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge" + +# RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw KMD 23072.44878134 +./komodo-cli sendtoaddress RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw 23072.44878134 +sleep 3 +echo "23072.44878134 <- expected amount RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw" + +# RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE KMD 26923.62561943 +./komodo-cli sendtoaddress RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE 26923.62561943 +sleep 3 +echo "26923.62561943 <- expected amount RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE" + +# RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43 KMD 890.85002942 +./komodo-cli sendtoaddress RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43 890.85002942 +sleep 3 +echo "890.85002942 <- expected amount RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43" + +# RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV KMD 6196.32806186 +./komodo-cli sendtoaddress RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV 6196.32806186 +sleep 3 +echo "6196.32806186 <- expected amount RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 123341.77894864 +./komodo-cli sendtoaddress RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX 123341.77894864 +sleep 3 +echo "123341.77894864 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx KMD 1267.52466143 +./komodo-cli sendtoaddress RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx 1267.52466143 +sleep 3 +echo "1267.52466143 <- expected amount RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx" + +# RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 KMD 9575.27247343 +./komodo-cli sendtoaddress RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 9575.27247343 +sleep 3 +echo "9575.27247343 <- expected amount RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9" + +# RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 KMD 8123.81358037 +./komodo-cli sendtoaddress RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 8123.81358037 +sleep 3 +echo "8123.81358037 <- expected amount RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9" + +# REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8 KMD 4989.67320242 +./komodo-cli sendtoaddress REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8 4989.67320242 +sleep 3 +echo "4989.67320242 <- expected amount REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8" + +# RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD KMD 752.38094876 +./komodo-cli sendtoaddress RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD 752.38094876 +sleep 3 +echo "752.38094876 <- expected amount RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD" + +# RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz KMD 142854.50921654 +./komodo-cli sendtoaddress RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz 142854.50921654 +sleep 3 +echo "142854.50921654 <- expected amount RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz" + +# RRZw29LKHAMTfw673BQHBjf1H6krpKruEV KMD 700273.96662837 +./komodo-cli sendtoaddress RRZw29LKHAMTfw673BQHBjf1H6krpKruEV 700273.96662837 +sleep 3 +echo "700273.96662837 <- expected amount RRZw29LKHAMTfw673BQHBjf1H6krpKruEV" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 22785.43547500 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 22785.43547500 +sleep 3 +echo "22785.43547500 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC KMD 49.81951692 +./komodo-cli sendtoaddress RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC 49.81951692 +sleep 3 +echo "49.81951692 <- expected amount RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC" + +# RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG KMD 9768.98395745 +./komodo-cli sendtoaddress RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG 9768.98395745 +sleep 3 +echo "9768.98395745 <- expected amount RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG" + +# RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc KMD 17899.04337446 +./komodo-cli sendtoaddress RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc 17899.04337446 +sleep 3 +echo "17899.04337446 <- expected amount RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc" + +# RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7 KMD 14691.11993791 +./komodo-cli sendtoaddress RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7 14691.11993791 +sleep 3 +echo "14691.11993791 <- expected amount RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7" + +# RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY KMD 1161.97829925 +./komodo-cli sendtoaddress RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY 1161.97829925 +sleep 3 +echo "1161.97829925 <- expected amount RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY" + +# RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW KMD 1172.24498253 +./komodo-cli sendtoaddress RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW 1172.24498253 +sleep 3 +echo "1172.24498253 <- expected amount RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW" + +# RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx KMD 9007.57601472 +./komodo-cli sendtoaddress RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx 9007.57601472 +sleep 3 +echo "9007.57601472 <- expected amount RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx" + +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626, REVS 115.97829823 +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626 +./komodo-cli sendtoaddress RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ 5844.47004626 +sleep 3 +echo "5844.47004626 <- expected amount RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ" + +# RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg KMD 5008.45159128 +./komodo-cli sendtoaddress RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg 5008.45159128 +sleep 3 +echo "5008.45159128 <- expected amount RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 7646.82608478 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 7646.82608478 +sleep 3 +echo "7646.82608478 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf KMD 3630.85647725 +./komodo-cli sendtoaddress RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf 3630.85647725 +sleep 3 +echo "3630.85647725 <- expected amount RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf" + +# RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj KMD 26.57494393 +./komodo-cli sendtoaddress RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj 26.57494393 +sleep 3 +echo "26.57494393 <- expected amount RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj" + +# R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU KMD 0.36801433 +./komodo-cli sendtoaddress R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU 0.36801433 +sleep 3 +echo "0.36801433 <- expected amount R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU" + +# RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43 KMD 8249.37604889 +./komodo-cli sendtoaddress RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43 8249.37604889 +sleep 3 +echo "8249.37604889 <- expected amount RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43" + +# RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN KMD 2701.34236284 +./komodo-cli sendtoaddress RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN 2701.34236284 +sleep 3 +echo "2701.34236284 <- expected amount RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN" + +# RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk KMD 9799.35032367 +./komodo-cli sendtoaddress RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk 9799.35032367 +sleep 3 +echo "9799.35032367 <- expected amount RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk" + +# RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L KMD 2180.13581547 +./komodo-cli sendtoaddress RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L 2180.13581547 +sleep 3 +echo "2180.13581547 <- expected amount RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L" + +# RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV KMD 3028.34071670 +./komodo-cli sendtoaddress RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV 3028.34071670 +sleep 3 +echo "3028.34071670 <- expected amount RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 6100.04389549 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 6100.04389549 +sleep 3 +echo "6100.04389549 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ KMD 737.35656935 +./komodo-cli sendtoaddress RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ 737.35656935 +sleep 3 +echo "737.35656935 <- expected amount RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ" + +# RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919 KMD 929.58263940 +./komodo-cli sendtoaddress RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919 929.58263940 +sleep 3 +echo "929.58263940 <- expected amount RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919" + +# RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy KMD 34677.50699205 +./komodo-cli sendtoaddress RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy 34677.50699205 +sleep 3 +echo "34677.50699205 <- expected amount RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy" + +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066, REVS 20.00000000 +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066 +./komodo-cli sendtoaddress REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa 26142.50314066 +sleep 3 +echo "26142.50314066 <- expected amount REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa" + +# RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V KMD 4802.84363690 +./komodo-cli sendtoaddress RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V 4802.84363690 +sleep 3 +echo "4802.84363690 <- expected amount RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V" + +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406, REVS 19.95990000 +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406 +./komodo-cli sendtoaddress RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft 1005.97291406 +sleep 3 +echo "1005.97291406 <- expected amount RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft" + +# RD486qQaD85849AdDPH3Xy3iyppuvxDZYf KMD 112218.69529965 +./komodo-cli sendtoaddress RD486qQaD85849AdDPH3Xy3iyppuvxDZYf 112218.69529965 +sleep 3 +echo "112218.69529965 <- expected amount RD486qQaD85849AdDPH3Xy3iyppuvxDZYf" + +# RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e KMD 3479.75699272 +./komodo-cli sendtoaddress RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e 3479.75699272 +sleep 3 +echo "3479.75699272 <- expected amount RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e" + +# RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN KMD 175.51057343 +./komodo-cli sendtoaddress RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN 175.51057343 +sleep 3 +echo "175.51057343 <- expected amount RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN" + +# RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8 KMD 7477.64792521 +./komodo-cli sendtoaddress RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8 7477.64792521 +sleep 3 +echo "7477.64792521 <- expected amount RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8" + +# RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn KMD 54859.12298759 +./komodo-cli sendtoaddress RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn 54859.12298759 +sleep 3 +echo "54859.12298759 <- expected amount RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn" + +# RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo KMD 79.56270943 +./komodo-cli sendtoaddress RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo 79.56270943 +sleep 3 +echo "79.56270943 <- expected amount RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo" + +# RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb KMD 349.07505686 +./komodo-cli sendtoaddress RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb 349.07505686 +sleep 3 +echo "349.07505686 <- expected amount RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 248.34196903 +./komodo-cli sendtoaddress RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH 248.34196903 +sleep 3 +echo "248.34196903 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R KMD 904.34185995 +./komodo-cli sendtoaddress RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R 904.34185995 +sleep 3 +echo "904.34185995 <- expected amount RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R" + +# REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ KMD 49.36918661 +./komodo-cli sendtoaddress REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ 49.36918661 +sleep 3 +echo "49.36918661 <- expected amount REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ" + +# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 159023.63042654 +./komodo-cli sendtoaddress RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC 159023.63042654 +sleep 3 +echo "159023.63042654 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC" + +# RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo KMD 18870.52757981 +./komodo-cli sendtoaddress RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo 18870.52757981 +sleep 3 +echo "18870.52757981 <- expected amount RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo" + +# R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ KMD 3523.48691215 +./komodo-cli sendtoaddress R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ 3523.48691215 +sleep 3 +echo "3523.48691215 <- expected amount R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ" + +# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 2607.14186398 +./komodo-cli sendtoaddress RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 2607.14186398 +sleep 3 +echo "2607.14186398 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9" + +# RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk KMD 3098.60879800 +./komodo-cli sendtoaddress RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk 3098.60879800 +sleep 3 +echo "3098.60879800 <- expected amount RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk" + +# RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT KMD 3647.68227700 +./komodo-cli sendtoaddress RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT 3647.68227700 +sleep 3 +echo "3647.68227700 <- expected amount RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT" + +# RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH KMD 468.24354647 +./komodo-cli sendtoaddress RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH 468.24354647 +sleep 3 +echo "468.24354647 <- expected amount RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH" + +# RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi KMD 2418.85149293 +./komodo-cli sendtoaddress RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi 2418.85149293 +sleep 3 +echo "2418.85149293 <- expected amount RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi" + +# REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh KMD 9295.82639400 +./komodo-cli sendtoaddress REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh" + +# RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 55321.57248841 +./komodo-cli sendtoaddress RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz 55321.57248841 +sleep 3 +echo "55321.57248841 <- expected amount RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz" + +# RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp KMD 367572.46866275 +./komodo-cli sendtoaddress RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp 367572.46866275 +sleep 3 +echo "367572.46866275 <- expected amount RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp" + +# REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s KMD 4.48872950 +./komodo-cli sendtoaddress REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s 4.48872950 +sleep 3 +echo "4.48872950 <- expected amount REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s" + +# RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP KMD 4260.58709725 +./komodo-cli sendtoaddress RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP 4260.58709725 +sleep 3 +echo "4260.58709725 <- expected amount RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP" + +# RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf KMD 2953.97870652 +./komodo-cli sendtoaddress RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf 2953.97870652 +sleep 3 +echo "2953.97870652 <- expected amount RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf" + +# RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi KMD 75258.40704108 +./komodo-cli sendtoaddress RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi 75258.40704108 +sleep 3 +echo "75258.40704108 <- expected amount RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi" + +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493, REVS 1564.97178647 +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493 +./komodo-cli sendtoaddress RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 125611.30316493 +sleep 3 +echo "125611.30316493 <- expected amount RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149, REVS 90.00018012 +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149 +./komodo-cli sendtoaddress RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk 4535.36019149 +sleep 3 +echo "4535.36019149 <- expected amount RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk" + +# RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E KMD 11293.49948607 +./komodo-cli sendtoaddress RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E 11293.49948607 +sleep 3 +echo "11293.49948607 <- expected amount RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E" + +# RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE KMD 12200.87564194 +./komodo-cli sendtoaddress RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE 12200.87564194 +sleep 3 +echo "12200.87564194 <- expected amount RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE" + +# RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd KMD 1493.46088391 +./komodo-cli sendtoaddress RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd 1493.46088391 +sleep 3 +echo "1493.46088391 <- expected amount RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd" + +# RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 46218.10752319 +./komodo-cli sendtoaddress RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 46218.10752319 +sleep 3 +echo "46218.10752319 <- expected amount RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2" + +# RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ KMD 11952.18753277 +./komodo-cli sendtoaddress RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ 11952.18753277 +sleep 3 +echo "11952.18753277 <- expected amount RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ" + +# RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx KMD 815.56545295 +./komodo-cli sendtoaddress RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx 815.56545295 +sleep 3 +echo "815.56545295 <- expected amount RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx" + +# RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr KMD 5212.95301692 +./komodo-cli sendtoaddress RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr 5212.95301692 +sleep 3 +echo "5212.95301692 <- expected amount RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr" + +# RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY KMD 3159.92424349 +./komodo-cli sendtoaddress RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY 3159.92424349 +sleep 3 +echo "3159.92424349 <- expected amount RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY" + + +# total KMD 2467018.52955628 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch15.listunspent b/iguana/tests/KMD.batch15.listunspent new file mode 100755 index 000000000..e24f8dd38 --- /dev/null +++ b/iguana/tests/KMD.batch15.listunspent @@ -0,0 +1,305 @@ +# RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge KMD 108355.00859530 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge\",\"symbol\":\"KMD\"}" +echo "108355.00859530 <- expected amount RBzPz4Sd2Jt3jKVsXKwC4vwGkYG6hSekge" + +# RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw KMD 23072.44878134 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw\",\"symbol\":\"KMD\"}" +echo "23072.44878134 <- expected amount RSN2ceQxBUKUynBf5BGbZU6er7uqAGUXzw" + +# RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE KMD 26923.62561943 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE\",\"symbol\":\"KMD\"}" +echo "26923.62561943 <- expected amount RVMGcrxJMHST3dPZJJNNxZWJKidFYBmpTE" + +# RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43 KMD 890.85002942 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43\",\"symbol\":\"KMD\"}" +echo "890.85002942 <- expected amount RJJKtJqfC8Ytrjq9RqiYLH85qbHNkqXb43" + +# RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV KMD 6196.32806186 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV\",\"symbol\":\"KMD\"}" +echo "6196.32806186 <- expected amount RWEGPuUx2U8V28VpxAKpuKfwcs6TN4GpKV" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 123341.77894864 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX\",\"symbol\":\"KMD\"}" +echo "123341.77894864 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx KMD 1267.52466143 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx\",\"symbol\":\"KMD\"}" +echo "1267.52466143 <- expected amount RKRtuN5f76BjSxPPTVbmtBSSdz938UjiJx" + +# RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 KMD 9575.27247343 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9\",\"symbol\":\"KMD\"}" +echo "9575.27247343 <- expected amount RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9" + +# RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9 KMD 8123.81358037 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9\",\"symbol\":\"KMD\"}" +echo "8123.81358037 <- expected amount RNMsi23XMUGyRe1FB8rxrJ6FQV4UHyVQn9" + +# REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8 KMD 4989.67320242 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8\",\"symbol\":\"KMD\"}" +echo "4989.67320242 <- expected amount REZbCCvVVNdvg8eVkwz4SDk4sVvBfSXrE8" + +# RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD KMD 752.38094876 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD\",\"symbol\":\"KMD\"}" +echo "752.38094876 <- expected amount RUcSLDX7nWM1oe5ftLYj3m6RE3gSsEXcGD" + +# RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz KMD 142854.50921654 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz\",\"symbol\":\"KMD\"}" +echo "142854.50921654 <- expected amount RSs2rBgjQcZjdPLuUhEFEDNVqoUutKAqMz" + +# RRZw29LKHAMTfw673BQHBjf1H6krpKruEV KMD 700273.96662837 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRZw29LKHAMTfw673BQHBjf1H6krpKruEV\",\"symbol\":\"KMD\"}" +echo "700273.96662837 <- expected amount RRZw29LKHAMTfw673BQHBjf1H6krpKruEV" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 22785.43547500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "22785.43547500 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC KMD 49.81951692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC\",\"symbol\":\"KMD\"}" +echo "49.81951692 <- expected amount RFxv7eb5F4hYum2pfJoWDJSBLesdzEothC" + +# RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG KMD 9768.98395745 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG\",\"symbol\":\"KMD\"}" +echo "9768.98395745 <- expected amount RJD2LGt2KYdmcuLMkrwnXA18o9U5xhLXbG" + +# RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc KMD 17899.04337446 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc\",\"symbol\":\"KMD\"}" +echo "17899.04337446 <- expected amount RCuyPLaBmudGiTm7chbnWdBATqEvcLWbNc" + +# RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7 KMD 14691.11993791 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7\",\"symbol\":\"KMD\"}" +echo "14691.11993791 <- expected amount RWtBYTabQZcJku6Z7X2u9NUyhzGUyMcba7" + +# RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY KMD 1161.97829925 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY\",\"symbol\":\"KMD\"}" +echo "1161.97829925 <- expected amount RJdKjpM8pm3E5Y93p5xy4XE8zQTQP5cfaY" + +# RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW KMD 1172.24498253 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW\",\"symbol\":\"KMD\"}" +echo "1172.24498253 <- expected amount RA8iFVS6B99VfGAThL21NuBFQ1wCeqVkYW" + +# RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx KMD 9007.57601472 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx\",\"symbol\":\"KMD\"}" +echo "9007.57601472 <- expected amount RTjshGhD5Nf6ZrWLxd6Kh65LrZRQzUesbx" + +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626, REVS 115.97829823 +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ\",\"symbol\":\"KMD\"}" +echo "5844.47004626 <- expected amount RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ" + +# RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg KMD 5008.45159128 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg\",\"symbol\":\"KMD\"}" +echo "5008.45159128 <- expected amount RUWP4WNfz1axrYbhLnK1mL1mYQigS9rheg" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 7646.82608478 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "7646.82608478 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf KMD 3630.85647725 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf\",\"symbol\":\"KMD\"}" +echo "3630.85647725 <- expected amount RKGh71nXHPkXZUwoKtEnwfdLsxcTKwdfbf" + +# RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj KMD 26.57494393 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj\",\"symbol\":\"KMD\"}" +echo "26.57494393 <- expected amount RYaL2xQsvSCaWVF5p4AUFLiM8TZsm2pVuj" + +# R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU KMD 0.36801433 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU\",\"symbol\":\"KMD\"}" +echo "0.36801433 <- expected amount R9UwkeRo4HWP14LXKxvii7PQkyrkk8zybU" + +# RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43 KMD 8249.37604889 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43\",\"symbol\":\"KMD\"}" +echo "8249.37604889 <- expected amount RE9wMd3wq3SwYYq9y7iv8r2cb7ndFc7V43" + +# RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN KMD 2701.34236284 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN\",\"symbol\":\"KMD\"}" +echo "2701.34236284 <- expected amount RXZvRrVc5JhmJ3dpgFNqjPQog2RHJwSTRN" + +# RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk KMD 9799.35032367 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk\",\"symbol\":\"KMD\"}" +echo "9799.35032367 <- expected amount RD7gYAZVD9yN5uUNyGd3TZNVXJA234pWDk" + +# RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L KMD 2180.13581547 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L\",\"symbol\":\"KMD\"}" +echo "2180.13581547 <- expected amount RNsNi3L3QWXx4Sa1CyZYfCd2q6TjJcrK4L" + +# RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV KMD 3028.34071670 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV\",\"symbol\":\"KMD\"}" +echo "3028.34071670 <- expected amount RRsb2PKKvZQuGCxEJZFEHxydq4aktjQKnV" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 6100.04389549 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "6100.04389549 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ KMD 737.35656935 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ\",\"symbol\":\"KMD\"}" +echo "737.35656935 <- expected amount RBBaR5v41Bew2qeybeutzN8YcFV9z2BTXZ" + +# RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919 KMD 929.58263940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919\",\"symbol\":\"KMD\"}" +echo "929.58263940 <- expected amount RHfFfCbb32Ld5SYjqA7yL5tohX5U1nc919" + +# RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy KMD 34677.50699205 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy\",\"symbol\":\"KMD\"}" +echo "34677.50699205 <- expected amount RT4DVxxerQye2rPf89Tfdxq6XmMuYMMDWy" + +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066, REVS 20.00000000 +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa\",\"symbol\":\"KMD\"}" +echo "26142.50314066 <- expected amount REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa" + +# RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V KMD 4802.84363690 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V\",\"symbol\":\"KMD\"}" +echo "4802.84363690 <- expected amount RX2gT4WZR7VDiufaYGGCYoxRD3kNZmEN2V" + +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406, REVS 19.95990000 +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft\",\"symbol\":\"KMD\"}" +echo "1005.97291406 <- expected amount RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft" + +# RD486qQaD85849AdDPH3Xy3iyppuvxDZYf KMD 112218.69529965 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RD486qQaD85849AdDPH3Xy3iyppuvxDZYf\",\"symbol\":\"KMD\"}" +echo "112218.69529965 <- expected amount RD486qQaD85849AdDPH3Xy3iyppuvxDZYf" + +# RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e KMD 3479.75699272 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e\",\"symbol\":\"KMD\"}" +echo "3479.75699272 <- expected amount RFPpBZpjgA1wT5mHBLRfUu4X8xr4DrLP4e" + +# RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN KMD 175.51057343 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN\",\"symbol\":\"KMD\"}" +echo "175.51057343 <- expected amount RRv9LoJVCtaQYkKm92MVb2ZZWH3cthWpGN" + +# RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8 KMD 7477.64792521 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8\",\"symbol\":\"KMD\"}" +echo "7477.64792521 <- expected amount RWM6u3En5J8afndTjSyAK6bw7EThdTK3a8" + +# RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn KMD 54859.12298759 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn\",\"symbol\":\"KMD\"}" +echo "54859.12298759 <- expected amount RVbyHqZRqL7QnjZdg5JPRCic5vnehjuTgn" + +# RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo KMD 79.56270943 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo\",\"symbol\":\"KMD\"}" +echo "79.56270943 <- expected amount RHXnTT4jKiS8PGR6RrUobdVC7SxJ5gUXMo" + +# RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb KMD 349.07505686 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb\",\"symbol\":\"KMD\"}" +echo "349.07505686 <- expected amount RLgtZmLckAP74eH5DZyG2V44mX1KMCAwCb" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 248.34196903 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH\",\"symbol\":\"KMD\"}" +echo "248.34196903 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R KMD 904.34185995 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R\",\"symbol\":\"KMD\"}" +echo "904.34185995 <- expected amount RDVsguQRewZQxA4CYuFaU6P1ZfzXy15m9R" + +# REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ KMD 49.36918661 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ\",\"symbol\":\"KMD\"}" +echo "49.36918661 <- expected amount REhB64k55HNsga6tbJxqwioRHg7pD7mTpQ" + +# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 159023.63042654 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC\",\"symbol\":\"KMD\"}" +echo "159023.63042654 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC" + +# RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo KMD 18870.52757981 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo\",\"symbol\":\"KMD\"}" +echo "18870.52757981 <- expected amount RC2c6CMiCrTceYdbkYzjXmavR45pwPJczo" + +# R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ KMD 3523.48691215 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ\",\"symbol\":\"KMD\"}" +echo "3523.48691215 <- expected amount R9WDH8NDcEewJTYGPgqMkvQ7ztbtBfV8zJ" + +# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 2607.14186398 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWc6GouJggQDsBCeW1DYck629FPrDJCTP9\",\"symbol\":\"KMD\"}" +echo "2607.14186398 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9" + +# RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk KMD 3098.60879800 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk\",\"symbol\":\"KMD\"}" +echo "3098.60879800 <- expected amount RYU6iDdo1AfrBg6zUcCPEX8BnSL1YsxrMk" + +# RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT KMD 3647.68227700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT\",\"symbol\":\"KMD\"}" +echo "3647.68227700 <- expected amount RTYpGd8VFGtiDb9bJSZasTWjRRHVqYABtT" + +# RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH KMD 468.24354647 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH\",\"symbol\":\"KMD\"}" +echo "468.24354647 <- expected amount RYUgPBd2MvnSEAADUmAXMSV6bBhRTA9dBH" + +# RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi KMD 2418.85149293 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi\",\"symbol\":\"KMD\"}" +echo "2418.85149293 <- expected amount RX3EPj8UoJJbQ4LnkQGqLnRSapbneckaKi" + +# REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount REJYC31D8z48AJAC8CmhgKgSuVc4WwFPWh" + +# RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz KMD 55321.57248841 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz\",\"symbol\":\"KMD\"}" +echo "55321.57248841 <- expected amount RAvtq1kazCRZUvWvPsN7ioY2Vt1EYtgpuz" + +# RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp KMD 367572.46866275 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp\",\"symbol\":\"KMD\"}" +echo "367572.46866275 <- expected amount RWXHBrpGt1dwa1rBuQj6QgQdWBdAtLwVAp" + +# REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s KMD 4.48872950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s\",\"symbol\":\"KMD\"}" +echo "4.48872950 <- expected amount REpJJwmxrSetdhNp4uKUTwyyTrSpNxjM2s" + +# RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP KMD 4260.58709725 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP\",\"symbol\":\"KMD\"}" +echo "4260.58709725 <- expected amount RKmwwn2n1DaAqZdDXiZkobgQSKiVcUD2RP" + +# RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf KMD 2953.97870652 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf\",\"symbol\":\"KMD\"}" +echo "2953.97870652 <- expected amount RL8XNqYnfkstJPuNHPYfsPQSzccTHcqFkf" + +# RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi KMD 75258.40704108 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi\",\"symbol\":\"KMD\"}" +echo "75258.40704108 <- expected amount RECqqp55ZLUccEgEwd3VTYC2awx9aVXEHi" + +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493, REVS 1564.97178647 +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3\",\"symbol\":\"KMD\"}" +echo "125611.30316493 <- expected amount RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149, REVS 90.00018012 +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk\",\"symbol\":\"KMD\"}" +echo "4535.36019149 <- expected amount RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk" + +# RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E KMD 11293.49948607 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E\",\"symbol\":\"KMD\"}" +echo "11293.49948607 <- expected amount RMrm1S6pc1AZY7QvqFwmEGNoPMVxq61E7E" + +# RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE KMD 12200.87564194 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE\",\"symbol\":\"KMD\"}" +echo "12200.87564194 <- expected amount RQPHxw8wwm83ystB1EciD5BFKmSpQnirrE" + +# RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd KMD 1493.46088391 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd\",\"symbol\":\"KMD\"}" +echo "1493.46088391 <- expected amount RNWxopR8G5sSkEZ8gAPHBJBrais9rT8rqd" + +# RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2 KMD 46218.10752319 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2\",\"symbol\":\"KMD\"}" +echo "46218.10752319 <- expected amount RTG2uSvYLnoxtxFeZJDFq2yPEqDvhTHhk2" + +# RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ KMD 11952.18753277 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ\",\"symbol\":\"KMD\"}" +echo "11952.18753277 <- expected amount RTmG8UyrSZPRy6Et1wZNtawB8EzCnGXzgJ" + +# RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx KMD 815.56545295 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx\",\"symbol\":\"KMD\"}" +echo "815.56545295 <- expected amount RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx" + +# RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr KMD 5212.95301692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr\",\"symbol\":\"KMD\"}" +echo "5212.95301692 <- expected amount RNUpL2yQjAHawP2C1kt7bTiMg5YSLEfurr" + +# RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY KMD 3159.92424349 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY\",\"symbol\":\"KMD\"}" +echo "3159.92424349 <- expected amount RKPiAqCz2qRQFb5db11uCPDRYMBFfjWVTY" + diff --git a/iguana/tests/KMD.batch16 b/iguana/tests/KMD.batch16 new file mode 100755 index 000000000..609a56161 --- /dev/null +++ b/iguana/tests/KMD.batch16 @@ -0,0 +1,464 @@ +sleep 999999 +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 29875.03958530 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 29875.03958530 +sleep 3 +echo "29875.03958530 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL KMD 2208761.69588058 +./komodo-cli sendtoaddress RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL 2208761.69588058 +sleep 3 +echo "2208761.69588058 <- expected amount RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 500.57828265 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 500.57828265 +sleep 3 +echo "500.57828265 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2 KMD 478577.43414711 +./komodo-cli sendtoaddress RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2 478577.43414711 +sleep 3 +echo "478577.43414711 <- expected amount RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2" + +# RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR KMD 14765.68648492 +./komodo-cli sendtoaddress RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR 14765.68648492 +sleep 3 +echo "14765.68648492 <- expected amount RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR" + +# RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9 KMD 16568.79001553 +./komodo-cli sendtoaddress RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9 16568.79001553 +sleep 3 +echo "16568.79001553 <- expected amount RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 5426.58572255 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 5426.58572255 +sleep 3 +echo "5426.58572255 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o KMD 2277.23212693 +./komodo-cli sendtoaddress RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o 2277.23212693 +sleep 3 +echo "2277.23212693 <- expected amount RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o" + +# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 345.82113080 +./komodo-cli sendtoaddress R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj 345.82113080 +sleep 3 +echo "345.82113080 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj" + +# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 32573.04574031 +./komodo-cli sendtoaddress RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH 32573.04574031 +sleep 3 +echo "32573.04574031 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH" + +# RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ KMD 21696.64781873 +./komodo-cli sendtoaddress RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ 21696.64781873 +sleep 3 +echo "21696.64781873 <- expected amount RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ" + +# RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP KMD 4410.81679144 +./komodo-cli sendtoaddress RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP 4410.81679144 +sleep 3 +echo "4410.81679144 <- expected amount RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP" + +# RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q KMD 701.98982318 +./komodo-cli sendtoaddress RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q 701.98982318 +sleep 3 +echo "701.98982318 <- expected amount RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q" + +# RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK KMD 228081.21691774 +./komodo-cli sendtoaddress RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK 228081.21691774 +sleep 3 +echo "228081.21691774 <- expected amount RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK" + +# RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4 KMD 620.49641179 +./komodo-cli sendtoaddress RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4 620.49641179 +sleep 3 +echo "620.49641179 <- expected amount RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4" + +# RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH KMD 940.61717265 +./komodo-cli sendtoaddress RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH 940.61717265 +sleep 3 +echo "940.61717265 <- expected amount RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH" + +# RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP KMD 329.20973464 +./komodo-cli sendtoaddress RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP 329.20973464 +sleep 3 +echo "329.20973464 <- expected amount RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP" + +# RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n KMD 890.85002942 +./komodo-cli sendtoaddress RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n 890.85002942 +sleep 3 +echo "890.85002942 <- expected amount RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n" + +# RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3 KMD 48415.76246875 +./komodo-cli sendtoaddress RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3" + +# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 258573.82999375 +./komodo-cli sendtoaddress RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 258573.82999375 +sleep 3 +echo "258573.82999375 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3" + +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504, REVS 17.01091436 +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504 +./komodo-cli sendtoaddress RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV 857.10994504 +sleep 3 +echo "857.10994504 <- expected amount RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV" + +# RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg KMD 2324.11284584 +./komodo-cli sendtoaddress RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg 2324.11284584 +sleep 3 +echo "2324.11284584 <- expected amount RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg" + +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 10017.77725515 +./komodo-cli sendtoaddress RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY 10017.77725515 +sleep 3 +echo "10017.77725515 <- expected amount RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 6114.70953620 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 6114.70953620 +sleep 3 +echo "6114.70953620 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB KMD 1529.93809401 +./komodo-cli sendtoaddress RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB 1529.93809401 +sleep 3 +echo "1529.93809401 <- expected amount RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB" + +# RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj KMD 315.34144784 +./komodo-cli sendtoaddress RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj 315.34144784 +sleep 3 +echo "315.34144784 <- expected amount RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj" + +# RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe KMD 2913.66058536 +./komodo-cli sendtoaddress RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe 2913.66058536 +sleep 3 +echo "2913.66058536 <- expected amount RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe" + +# RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut KMD 809.20571578 +./komodo-cli sendtoaddress RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut 809.20571578 +sleep 3 +echo "809.20571578 <- expected amount RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut" + +# REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf KMD 10922.30573649 +./komodo-cli sendtoaddress REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf 10922.30573649 +sleep 3 +echo "10922.30573649 <- expected amount REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf" + +# RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt KMD 8552.16028247 +./komodo-cli sendtoaddress RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt 8552.16028247 +sleep 3 +echo "8552.16028247 <- expected amount RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt" + +# REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ KMD 11.76905135 +./komodo-cli sendtoaddress REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ 11.76905135 +sleep 3 +echo "11.76905135 <- expected amount REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ" + +# RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH KMD 781.69278094 +./komodo-cli sendtoaddress RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH 781.69278094 +sleep 3 +echo "781.69278094 <- expected amount RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH" + +# RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc KMD 5055.79050524 +./komodo-cli sendtoaddress RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc 5055.79050524 +sleep 3 +echo "5055.79050524 <- expected amount RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc" + +# RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg KMD 15570.39216000 +./komodo-cli sendtoaddress RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg 15570.39216000 +sleep 3 +echo "15570.39216000 <- expected amount RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg" + +# RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu KMD 131.27522160 +./komodo-cli sendtoaddress RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu 131.27522160 +sleep 3 +echo "131.27522160 <- expected amount RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu" + +# RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR KMD 20678.85680809 +./komodo-cli sendtoaddress RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR 20678.85680809 +sleep 3 +echo "20678.85680809 <- expected amount RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR" + +# RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1 KMD 4841.57624687 +./komodo-cli sendtoaddress RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1 4841.57624687 +sleep 3 +echo "4841.57624687 <- expected amount RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1" + +# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 8.94389143 +./komodo-cli sendtoaddress RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU 8.94389143 +sleep 3 +echo "8.94389143 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU" + +# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 1000.80729416 +./komodo-cli sendtoaddress RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW 1000.80729416 +sleep 3 +echo "1000.80729416 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW" + +# RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag KMD 1282.60555481 +./komodo-cli sendtoaddress RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag 1282.60555481 +sleep 3 +echo "1282.60555481 <- expected amount RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag" + +# RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83 KMD 247.94454562 +./komodo-cli sendtoaddress RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83 247.94454562 +sleep 3 +echo "247.94454562 <- expected amount RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83" + +# RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u KMD 9295.82639400 +./komodo-cli sendtoaddress RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u" + +# RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H KMD 3949.77164792 +./komodo-cli sendtoaddress RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H 3949.77164792 +sleep 3 +echo "3949.77164792 <- expected amount RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H" + +# RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB KMD 8845.81358175 +./komodo-cli sendtoaddress RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB 8845.81358175 +sleep 3 +echo "8845.81358175 <- expected amount RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB" + +# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 2300.71703251 +./komodo-cli sendtoaddress RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv 2300.71703251 +sleep 3 +echo "2300.71703251 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv" + +# RRW5pyLoAc2GAx618xer3ywidtN83a9nZP KMD 52.19445674 +./komodo-cli sendtoaddress RRW5pyLoAc2GAx618xer3ywidtN83a9nZP 52.19445674 +sleep 3 +echo "52.19445674 <- expected amount RRW5pyLoAc2GAx618xer3ywidtN83a9nZP" + +# RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q KMD 36.13200587 +./komodo-cli sendtoaddress RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q 36.13200587 +sleep 3 +echo "36.13200587 <- expected amount RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q" + +# RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w KMD 422.85217955 +./komodo-cli sendtoaddress RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w 422.85217955 +sleep 3 +echo "422.85217955 <- expected amount RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w" + +# RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B KMD 217.54701681 +./komodo-cli sendtoaddress RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B 217.54701681 +sleep 3 +echo "217.54701681 <- expected amount RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B" + +# RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz KMD 4005.10943567 +./komodo-cli sendtoaddress RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz 4005.10943567 +sleep 3 +echo "4005.10943567 <- expected amount RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz" + +# RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt KMD 519.46088391 +./komodo-cli sendtoaddress RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt 519.46088391 +sleep 3 +echo "519.46088391 <- expected amount RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt" + +# RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN KMD 2214.30570000 +./komodo-cli sendtoaddress RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN 2214.30570000 +sleep 3 +echo "2214.30570000 <- expected amount RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN" + +# RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr KMD 23.86363839 +./komodo-cli sendtoaddress RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr 23.86363839 +sleep 3 +echo "23.86363839 <- expected amount RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr" + +# RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA KMD 6483.53169406 +./komodo-cli sendtoaddress RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA 6483.53169406 +sleep 3 +echo "6483.53169406 <- expected amount RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA" + +# RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG KMD 49.71591332 +./komodo-cli sendtoaddress RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG 49.71591332 +sleep 3 +echo "49.71591332 <- expected amount RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG" + +# RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY KMD 32.31534366 +./komodo-cli sendtoaddress RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY 32.31534366 +sleep 3 +echo "32.31534366 <- expected amount RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY" + +# RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh KMD 181.98552204 +./komodo-cli sendtoaddress RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh 181.98552204 +sleep 3 +echo "181.98552204 <- expected amount RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh" + +# RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt KMD 108.89297630 +./komodo-cli sendtoaddress RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt 108.89297630 +sleep 3 +echo "108.89297630 <- expected amount RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt" + +# RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V KMD 619.72175960 +./komodo-cli sendtoaddress RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V 619.72175960 +sleep 3 +echo "619.72175960 <- expected amount RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V" + +# RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM KMD 81083.51536582 +./komodo-cli sendtoaddress RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM 81083.51536582 +sleep 3 +echo "81083.51536582 <- expected amount RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM" + +# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 248.64863568 +./komodo-cli sendtoaddress RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi 248.64863568 +sleep 3 +echo "248.64863568 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi" + +# REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn KMD 2033.46202368 +./komodo-cli sendtoaddress REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn 2033.46202368 +sleep 3 +echo "2033.46202368 <- expected amount REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn" + +# RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K KMD 2700.73139303 +./komodo-cli sendtoaddress RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K 2700.73139303 +sleep 3 +echo "2700.73139303 <- expected amount RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K" + +# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 34229.39253089 +./komodo-cli sendtoaddress RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB 34229.39253089 +sleep 3 +echo "34229.39253089 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB" + +# RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6 KMD 27887.47918200 +./komodo-cli sendtoaddress RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6 27887.47918200 +sleep 3 +echo "27887.47918200 <- expected amount RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6" + +# RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R KMD 24.37095068 +./komodo-cli sendtoaddress RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R 24.37095068 +sleep 3 +echo "24.37095068 <- expected amount RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R" + +# RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF KMD 181212.75889505 +./komodo-cli sendtoaddress RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF 181212.75889505 +sleep 3 +echo "181212.75889505 <- expected amount RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF" + +# RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN KMD 1273.91554206 +./komodo-cli sendtoaddress RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN 1273.91554206 +sleep 3 +echo "1273.91554206 <- expected amount RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN" + +# RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H KMD 54049.29806312 +./komodo-cli sendtoaddress RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H 54049.29806312 +sleep 3 +echo "54049.29806312 <- expected amount RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H" + +# RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW KMD 9828.35196887 +./komodo-cli sendtoaddress RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW 9828.35196887 +sleep 3 +echo "9828.35196887 <- expected amount RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW" + +# RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2 KMD 3244.24341150 +./komodo-cli sendtoaddress RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2 3244.24341150 +sleep 3 +echo "3244.24341150 <- expected amount RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2" + +# RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy KMD 134001.54651965 +./komodo-cli sendtoaddress RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy 134001.54651965 +sleep 3 +echo "134001.54651965 <- expected amount RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy" + +# RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU KMD 1450.48101086 +./komodo-cli sendtoaddress RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU 1450.48101086 +sleep 3 +echo "1450.48101086 <- expected amount RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU" + +# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 54818.61192554 +./komodo-cli sendtoaddress RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH 54818.61192554 +sleep 3 +echo "54818.61192554 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH" + +# RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8 KMD 12701.61657288 +./komodo-cli sendtoaddress RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8 12701.61657288 +sleep 3 +echo "12701.61657288 <- expected amount RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8" + +# RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF KMD 968.31524937 +./komodo-cli sendtoaddress RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF" + +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404, REVS 45.41799774 +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404 +./komodo-cli sendtoaddress REVcoi6A4GRfuchCXTwBTszbakhoh9inLs 2288.11223404 +sleep 3 +echo "2288.11223404 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs" + +# RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti KMD 2227.12507356 +./komodo-cli sendtoaddress RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti 2227.12507356 +sleep 3 +echo "2227.12507356 <- expected amount RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW KMD 0.84952973 +./komodo-cli sendtoaddress RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW 0.84952973 +sleep 3 +echo "0.84952973 <- expected amount RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW" + +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757, REVS 151.44412616 +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757 +./komodo-cli sendtoaddress RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije 13018.84319757 +sleep 3 +echo "13018.84319757 <- expected amount RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije" + +# RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ KMD 212.11828501 +./komodo-cli sendtoaddress RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ 212.11828501 +sleep 3 +echo "212.11828501 <- expected amount RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ" + +# RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR KMD 3195.44032293 +./komodo-cli sendtoaddress RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR 3195.44032293 +sleep 3 +echo "3195.44032293 <- expected amount RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR" + +# RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz KMD 18396.05310761 +./komodo-cli sendtoaddress RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz 18396.05310761 +sleep 3 +echo "18396.05310761 <- expected amount RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz" + +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944, REVS 180.67104532 +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944 +./komodo-cli sendtoaddress REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo 9102.02231944 +sleep 3 +echo "9102.02231944 <- expected amount REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo" + +# RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6 KMD 15493.04399000 +./komodo-cli sendtoaddress RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6 15493.04399000 +sleep 3 +echo "15493.04399000 <- expected amount RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6" + +# RWrywGAqokYxD11FVNYhFMrh6jjKv827jY KMD 18591.65278800 +./komodo-cli sendtoaddress RWrywGAqokYxD11FVNYhFMrh6jjKv827jY 18591.65278800 +sleep 3 +echo "18591.65278800 <- expected amount RWrywGAqokYxD11FVNYhFMrh6jjKv827jY" + +# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 2489.43684219 +./komodo-cli sendtoaddress RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 2489.43684219 +sleep 3 +echo "2489.43684219 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63" + +# RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM KMD 295334.21442887 +./komodo-cli sendtoaddress RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM 295334.21442887 +sleep 3 +echo "295334.21442887 <- expected amount RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 471.00874744 +./komodo-cli sendtoaddress RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH 471.00874744 +sleep 3 +echo "471.00874744 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 KMD 11055.19532209 +./komodo-cli sendtoaddress RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 11055.19532209 +sleep 3 +echo "11055.19532209 <- expected amount RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4" + + +# total KMD 4481986.01571721 REVS 0.00000000 + + diff --git a/iguana/tests/KMD.batch16.listunspent b/iguana/tests/KMD.batch16.listunspent new file mode 100755 index 000000000..08e6135c2 --- /dev/null +++ b/iguana/tests/KMD.batch16.listunspent @@ -0,0 +1,370 @@ +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 29875.03958530 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "29875.03958530 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL KMD 2208761.69588058 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL\",\"symbol\":\"KMD\"}" +echo "2208761.69588058 <- expected amount RE7dTo722hnJ5Hm5aLwSk3YrvTCuiaGJGL" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 500.57828265 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "500.57828265 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2 KMD 478577.43414711 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2\",\"symbol\":\"KMD\"}" +echo "478577.43414711 <- expected amount RH4ziYsxYKXi6qEe8gR2WftMFDasUmwAN2" + +# RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR KMD 14765.68648492 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR\",\"symbol\":\"KMD\"}" +echo "14765.68648492 <- expected amount RSz39LBAF8G9GLRuQ1BDvBVAcLczH87nqR" + +# RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9 KMD 16568.79001553 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9\",\"symbol\":\"KMD\"}" +echo "16568.79001553 <- expected amount RPNKYCYh9v7hzH5Cgo7KBjxAVY7sQ681S9" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 5426.58572255 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "5426.58572255 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o KMD 2277.23212693 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o\",\"symbol\":\"KMD\"}" +echo "2277.23212693 <- expected amount RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o" + +# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 345.82113080 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj\",\"symbol\":\"KMD\"}" +echo "345.82113080 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj" + +# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 32573.04574031 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH\",\"symbol\":\"KMD\"}" +echo "32573.04574031 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH" + +# RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ KMD 21696.64781873 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ\",\"symbol\":\"KMD\"}" +echo "21696.64781873 <- expected amount RTxYk2J7PQGaNFCKoxFiCJAkgWi1Yf3XWZ" + +# RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP KMD 4410.81679144 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP\",\"symbol\":\"KMD\"}" +echo "4410.81679144 <- expected amount RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP" + +# RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q KMD 701.98982318 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q\",\"symbol\":\"KMD\"}" +echo "701.98982318 <- expected amount RFLQ2DDR5BjNxnz6hqgVpQ7VpmvgyPyB7Q" + +# RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK KMD 228081.21691774 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK\",\"symbol\":\"KMD\"}" +echo "228081.21691774 <- expected amount RHaYREKsYLwafyk4GZEtWHmJhjzdZymAGK" + +# RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4 KMD 620.49641179 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4\",\"symbol\":\"KMD\"}" +echo "620.49641179 <- expected amount RHNAivbuzfhneSwLV9VpXSU4PFnEsmNsC4" + +# RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH KMD 940.61717265 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH\",\"symbol\":\"KMD\"}" +echo "940.61717265 <- expected amount RRtJ2f2YJztjFSGVQNnyFPpTt3fQ4RH1MH" + +# RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP KMD 329.20973464 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP\",\"symbol\":\"KMD\"}" +echo "329.20973464 <- expected amount RCMTHdPSNEWcteyAKZaNkqWRM189JoffZP" + +# RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n KMD 890.85002942 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n\",\"symbol\":\"KMD\"}" +echo "890.85002942 <- expected amount RB91pNtAQVu9qfhFkFYX4x4G1QfcEDNe1n" + +# RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3 KMD 48415.76246875 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3\",\"symbol\":\"KMD\"}" +echo "48415.76246875 <- expected amount RRGgzASdJ4yBv7Y9o39r9iwCit1jbXhpX3" + +# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 258573.82999375 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3\",\"symbol\":\"KMD\"}" +echo "258573.82999375 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3" + +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504, REVS 17.01091436 +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV\",\"symbol\":\"KMD\"}" +echo "857.10994504 <- expected amount RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV" + +# RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg KMD 2324.11284584 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg\",\"symbol\":\"KMD\"}" +echo "2324.11284584 <- expected amount RCX7MWLQEwgoo6qAdzbaeUBZ4x6KC5KDyg" + +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 10017.77725515 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY\",\"symbol\":\"KMD\"}" +echo "10017.77725515 <- expected amount RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 6114.70953620 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "6114.70953620 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB KMD 1529.93809401 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB\",\"symbol\":\"KMD\"}" +echo "1529.93809401 <- expected amount RSCpqqjUyjAzs2XT8ra4VzcgQoQJJL6ygB" + +# RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj KMD 315.34144784 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj\",\"symbol\":\"KMD\"}" +echo "315.34144784 <- expected amount RH8ZCNFMWAavi3n5v2buQ5QZVDJnD4BXMj" + +# RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe KMD 2913.66058536 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe\",\"symbol\":\"KMD\"}" +echo "2913.66058536 <- expected amount RHY2jW41xptqKfmxDNvojC9MmC6VSTmYTe" + +# RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut KMD 809.20571578 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut\",\"symbol\":\"KMD\"}" +echo "809.20571578 <- expected amount RF6kNo4YBUHn9hHD94fQPx7sBVcDLLLDut" + +# REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf KMD 10922.30573649 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf\",\"symbol\":\"KMD\"}" +echo "10922.30573649 <- expected amount REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf" + +# RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt KMD 8552.16028247 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt\",\"symbol\":\"KMD\"}" +echo "8552.16028247 <- expected amount RKd488zhEwgwbtonvv1jvXxq9CtWx7JdTt" + +# REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ KMD 11.76905135 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ\",\"symbol\":\"KMD\"}" +echo "11.76905135 <- expected amount REDLuGEpoo7d3Z2CvCpNu5VFYoToDWVquZ" + +# RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH KMD 781.69278094 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH\",\"symbol\":\"KMD\"}" +echo "781.69278094 <- expected amount RYNFwcLAQoqWuzZxT8eAnDX8qYyyy8X7CH" + +# RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc KMD 5055.79050524 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc\",\"symbol\":\"KMD\"}" +echo "5055.79050524 <- expected amount RPy24KLGQcj2ixf6VpRC8ceNt2TGfaotJc" + +# RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg KMD 15570.39216000 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg\",\"symbol\":\"KMD\"}" +echo "15570.39216000 <- expected amount RDS7pdCZNjXNDZRRN9ThhU9vR9wwDjzkRg" + +# RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu KMD 131.27522160 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu\",\"symbol\":\"KMD\"}" +echo "131.27522160 <- expected amount RENgBDkBfw4gJCq4C62kUFtB9z75hTeWJu" + +# RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR KMD 20678.85680809 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR\",\"symbol\":\"KMD\"}" +echo "20678.85680809 <- expected amount RJ2mT6TfXDGDpozBfFQH9khUkisvp2s3bR" + +# RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1 KMD 4841.57624687 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1\",\"symbol\":\"KMD\"}" +echo "4841.57624687 <- expected amount RK1bfZervNSyMuQPDtK7iPX1YUj5EMvmY1" + +# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 8.94389143 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU\",\"symbol\":\"KMD\"}" +echo "8.94389143 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU" + +# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 1000.80729416 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW\",\"symbol\":\"KMD\"}" +echo "1000.80729416 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW" + +# RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag KMD 1282.60555481 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag\",\"symbol\":\"KMD\"}" +echo "1282.60555481 <- expected amount RSkxA4q8XD4fH6SFXASdbijeEnMpmw9gag" + +# RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83 KMD 247.94454562 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83\",\"symbol\":\"KMD\"}" +echo "247.94454562 <- expected amount RJFk6N5CeieX3RhSSTBWEL5LwKVaKeQf83" + +# RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u KMD 9295.82639400 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RCG3XokbbH3QEu4hL4gbZwTK34rDoVKg4u" + +# RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H KMD 3949.77164792 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H\",\"symbol\":\"KMD\"}" +echo "3949.77164792 <- expected amount RCuECu2yAYZeG3HiAkXiaxCvKa5gduKL9H" + +# RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB KMD 8845.81358175 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB\",\"symbol\":\"KMD\"}" +echo "8845.81358175 <- expected amount RXDpDLmaF34iHXc8DJLrZyqj1v2HpXH7CB" + +# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 2300.71703251 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv\",\"symbol\":\"KMD\"}" +echo "2300.71703251 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv" + +# RRW5pyLoAc2GAx618xer3ywidtN83a9nZP KMD 52.19445674 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRW5pyLoAc2GAx618xer3ywidtN83a9nZP\",\"symbol\":\"KMD\"}" +echo "52.19445674 <- expected amount RRW5pyLoAc2GAx618xer3ywidtN83a9nZP" + +# RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q KMD 36.13200587 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q\",\"symbol\":\"KMD\"}" +echo "36.13200587 <- expected amount RGrJ4AGWusVdLTVsvV3xsTBZe6d1qVS16q" + +# RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w KMD 422.85217955 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w\",\"symbol\":\"KMD\"}" +echo "422.85217955 <- expected amount RAsDYD3FWvQ42eDqDnyaJgcpmUZrarA44w" + +# RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B KMD 217.54701681 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B\",\"symbol\":\"KMD\"}" +echo "217.54701681 <- expected amount RGYvkNa4vTD6QYkUyugw9Dyk285Q5qGo4B" + +# RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz KMD 4005.10943567 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz\",\"symbol\":\"KMD\"}" +echo "4005.10943567 <- expected amount RGukbCjoDr2PiJSH6NNC4t7UDQWFkx8zQz" + +# RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt KMD 519.46088391 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt\",\"symbol\":\"KMD\"}" +echo "519.46088391 <- expected amount RMusGcGfCfzNT8S8xYz6p6sPCoxtt4zZzt" + +# RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN KMD 2214.30570000 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN\",\"symbol\":\"KMD\"}" +echo "2214.30570000 <- expected amount RBbtoXBmNDjh8VYi7mogKCniKcQxBgpmeN" + +# RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr KMD 23.86363839 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr\",\"symbol\":\"KMD\"}" +echo "23.86363839 <- expected amount RH6jGuCBF3avqJxWpkwpbDHHELBfXW2atr" + +# RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA KMD 6483.53169406 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA\",\"symbol\":\"KMD\"}" +echo "6483.53169406 <- expected amount RPvApbnHfsum7vc4i7X5P2Sqi9t7mF3DUA" + +# RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG KMD 49.71591332 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG\",\"symbol\":\"KMD\"}" +echo "49.71591332 <- expected amount RACCAv92Wt4C1aKEuuL5tX9wt1ZZ5ztVCG" + +# RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY KMD 32.31534366 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY\",\"symbol\":\"KMD\"}" +echo "32.31534366 <- expected amount RXLGVWxutb7KB5cJw8gmyvs83XfvChL2oY" + +# RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh KMD 181.98552204 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh\",\"symbol\":\"KMD\"}" +echo "181.98552204 <- expected amount RLdbW5GT6WJSevJYzFqDQaPmFcXrmKyPYh" + +# RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt KMD 108.89297630 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt\",\"symbol\":\"KMD\"}" +echo "108.89297630 <- expected amount RCJtsbUUAtzHCDkyctcUUJMaibtVY5piUt" + +# RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V KMD 619.72175960 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V\",\"symbol\":\"KMD\"}" +echo "619.72175960 <- expected amount RL9G3TyhdxiWADkAvJV34brvKgKZVxq78V" + +# RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM KMD 81083.51536582 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM\",\"symbol\":\"KMD\"}" +echo "81083.51536582 <- expected amount RKy5mhomLVy1SwSros7sowZKGuRuz9ceeM" + +# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 248.64863568 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi\",\"symbol\":\"KMD\"}" +echo "248.64863568 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi" + +# REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn KMD 2033.46202368 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn\",\"symbol\":\"KMD\"}" +echo "2033.46202368 <- expected amount REf7AHXuzcRBgQmhRFi34XK2VrDf1LRJhn" + +# RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K KMD 2700.73139303 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K\",\"symbol\":\"KMD\"}" +echo "2700.73139303 <- expected amount RWPicNFcigzRVGKfMgoL5h45URs8ko3P6K" + +# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 34229.39253089 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB\",\"symbol\":\"KMD\"}" +echo "34229.39253089 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB" + +# RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6 KMD 27887.47918200 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6\",\"symbol\":\"KMD\"}" +echo "27887.47918200 <- expected amount RHXkqP1beRbwHfGrhHcLkgNBS6qvkDZuR6" + +# RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R KMD 24.37095068 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R\",\"symbol\":\"KMD\"}" +echo "24.37095068 <- expected amount RHw3gDr5hySCT1d5ZoskMKcbsZ7eC9Ey7R" + +# RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF KMD 181212.75889505 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF\",\"symbol\":\"KMD\"}" +echo "181212.75889505 <- expected amount RGV11QdETeFJ6RbnKALGTAmMZbXFDuHnnF" + +# RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN KMD 1273.91554206 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN\",\"symbol\":\"KMD\"}" +echo "1273.91554206 <- expected amount RV4gpXyGMURSC9Hop44Ysum4vBvwGDitkN" + +# RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H KMD 54049.29806312 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H\",\"symbol\":\"KMD\"}" +echo "54049.29806312 <- expected amount RBV3vBdH2fCx5Eev4HYZ94SJ6a3JXgXr9H" + +# RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW KMD 9828.35196887 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW\",\"symbol\":\"KMD\"}" +echo "9828.35196887 <- expected amount RQ6vQBtDYrT65TtFFXCHfPRjkmbBsVpXhW" + +# RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2 KMD 3244.24341150 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2\",\"symbol\":\"KMD\"}" +echo "3244.24341150 <- expected amount RK8H5iDRgFmdPnPaYNLecXbbKood1kKyz2" + +# RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy KMD 134001.54651965 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy\",\"symbol\":\"KMD\"}" +echo "134001.54651965 <- expected amount RAgL8oHgKqog2Wazp8MtctJP67UfHzDXoy" + +# RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU KMD 1450.48101086 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU\",\"symbol\":\"KMD\"}" +echo "1450.48101086 <- expected amount RRZgQUxBpHUH9PtAE3X9sBu8nGX7VYXWMU" + +# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 54818.61192554 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH\",\"symbol\":\"KMD\"}" +echo "54818.61192554 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH" + +# RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8 KMD 12701.61657288 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8\",\"symbol\":\"KMD\"}" +echo "12701.61657288 <- expected amount RYT2XAMsa7KA1ahpXex5RoTywy2kJXVbu8" + +# RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF KMD 968.31524937 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF\",\"symbol\":\"KMD\"}" +echo "968.31524937 <- expected amount RLQZSbhFzEUs8D9JfnJGKhNJmHTiqVY6ZF" + +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404, REVS 45.41799774 +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REVcoi6A4GRfuchCXTwBTszbakhoh9inLs\",\"symbol\":\"KMD\"}" +echo "2288.11223404 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs" + +# RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti KMD 2227.12507356 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti\",\"symbol\":\"KMD\"}" +echo "2227.12507356 <- expected amount RBbmWzgpLURyiCzhGv3j59sCUdCV1yLsti" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW KMD 0.84952973 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW\",\"symbol\":\"KMD\"}" +echo "0.84952973 <- expected amount RGna6hhbbVEEVZg7GiM7uCXcbz5LMb4rGW" + +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757, REVS 151.44412616 +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije\",\"symbol\":\"KMD\"}" +echo "13018.84319757 <- expected amount RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije" + +# RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ KMD 212.11828501 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ\",\"symbol\":\"KMD\"}" +echo "212.11828501 <- expected amount RFJwrDJe1oso2UgtQjvcUoWmuTmEk53gBQ" + +# RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR KMD 3195.44032293 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR\",\"symbol\":\"KMD\"}" +echo "3195.44032293 <- expected amount RMX6HitSa9q859FtybK2fNZ4Wf3jwtRFWR" + +# RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz KMD 18396.05310761 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz\",\"symbol\":\"KMD\"}" +echo "18396.05310761 <- expected amount RC1kGvPaYPdM2LqXhQK1jT48yQoeJJwVxz" + +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944, REVS 180.67104532 +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo\",\"symbol\":\"KMD\"}" +echo "9102.02231944 <- expected amount REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo" + +# RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6 KMD 15493.04399000 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6\",\"symbol\":\"KMD\"}" +echo "15493.04399000 <- expected amount RNgdaVesPmwbGfXcJQRKvvW44dZ6ABxdr6" + +# RWrywGAqokYxD11FVNYhFMrh6jjKv827jY KMD 18591.65278800 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWrywGAqokYxD11FVNYhFMrh6jjKv827jY\",\"symbol\":\"KMD\"}" +echo "18591.65278800 <- expected amount RWrywGAqokYxD11FVNYhFMrh6jjKv827jY" + +# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 2489.43684219 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63\",\"symbol\":\"KMD\"}" +echo "2489.43684219 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63" + +# RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM KMD 295334.21442887 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM\",\"symbol\":\"KMD\"}" +echo "295334.21442887 <- expected amount RNnEto9ShSFcUaEaprjCn3qFDUzXpLm7bM" + +# RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH KMD 471.00874744 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH\",\"symbol\":\"KMD\"}" +echo "471.00874744 <- expected amount RJRJ2xejRZuiMPQnafPEUU2VUfTfchpHZH" + +# RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 KMD 11055.19532209 +curl --url "http://127.0.0.1:0" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4\",\"symbol\":\"KMD\"}" +echo "11055.19532209 <- expected amount RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4" + + +# total KMD 0.00000000 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch17 b/iguana/tests/KMD.batch17 new file mode 100755 index 000000000..2b5513271 --- /dev/null +++ b/iguana/tests/KMD.batch17 @@ -0,0 +1,434 @@ +sleep 9999999 +# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 108998.28313606 +./komodo-cli sendtoaddress RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 108998.28313606 +sleep 3 +echo "108998.28313606 <- expected amount RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 196.34763557 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 196.34763557 +sleep 3 +echo "196.34763557 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU KMD 14524.72874062 +./komodo-cli sendtoaddress RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU 14524.72874062 +sleep 3 +echo "14524.72874062 <- expected amount RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU" + +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 16017.97255691 +./komodo-cli sendtoaddress REVcoi6A4GRfuchCXTwBTszbakhoh9inLs 16017.97255691 +sleep 3 +echo "16017.97255691 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs" + +# RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 KMD 145928.92215821 +./komodo-cli sendtoaddress RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 145928.92215821 +sleep 3 +echo "145928.92215821 <- expected amount RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22" + +# RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 KMD 114940.35721379 +./komodo-cli sendtoaddress RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 114940.35721379 +sleep 3 +echo "114940.35721379 <- expected amount RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6" + +# RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU KMD 28699.34324752 +./komodo-cli sendtoaddress RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU 28699.34324752 +sleep 3 +echo "28699.34324752 <- expected amount RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU" + +# RV25zizocv445ht9My45WaxpGuAC42cxLa KMD 101090.11347764 +./komodo-cli sendtoaddress RV25zizocv445ht9My45WaxpGuAC42cxLa 101090.11347764 +sleep 3 +echo "101090.11347764 <- expected amount RV25zizocv445ht9My45WaxpGuAC42cxLa" + +# RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S KMD 1704.23483890 +./komodo-cli sendtoaddress RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S 1704.23483890 +sleep 3 +echo "1704.23483890 <- expected amount RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S" + +# RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD KMD 96831.52493750 +./komodo-cli sendtoaddress RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD 96831.52493750 +sleep 3 +echo "96831.52493750 <- expected amount RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD" + +# RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve KMD 11.06362104 +./komodo-cli sendtoaddress RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve 11.06362104 +sleep 3 +echo "11.06362104 <- expected amount RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve" + +# RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv KMD 32009.28059927 +./komodo-cli sendtoaddress RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv 32009.28059927 +sleep 3 +echo "32009.28059927 <- expected amount RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv" + +# RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh KMD 305.48459176 +./komodo-cli sendtoaddress RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh 305.48459176 +sleep 3 +echo "305.48459176 <- expected amount RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh" + +# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 162977.74808228 +./komodo-cli sendtoaddress RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 162977.74808228 +sleep 3 +echo "162977.74808228 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3" + +# RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn KMD 9683.15249375 +./komodo-cli sendtoaddress RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn" + +# RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 KMD 1593.10203942 +./komodo-cli sendtoaddress RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 1593.10203942 +sleep 3 +echo "1593.10203942 <- expected amount RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3" + +# RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu KMD 4066.11066256 +./komodo-cli sendtoaddress RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu 4066.11066256 +sleep 3 +echo "4066.11066256 <- expected amount RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu" + +# RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc KMD 4014.80536992 +./komodo-cli sendtoaddress RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc 4014.80536992 +sleep 3 +echo "4014.80536992 <- expected amount RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc" + +# RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd KMD 2904.94574812 +./komodo-cli sendtoaddress RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd 2904.94574812 +sleep 3 +echo "2904.94574812 <- expected amount RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd" + +# REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc KMD 38080.08587787 +./komodo-cli sendtoaddress REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc 38080.08587787 +sleep 3 +echo "38080.08587787 <- expected amount REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc" + +# RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 KMD 875.08198390 +./komodo-cli sendtoaddress RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 875.08198390 +sleep 3 +echo "875.08198390 <- expected amount RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7" + +# RULousSwdVGhaP6vusva8u9AQWTs8ugjfp KMD 9683.15249375 +./komodo-cli sendtoaddress RULousSwdVGhaP6vusva8u9AQWTs8ugjfp 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RULousSwdVGhaP6vusva8u9AQWTs8ugjfp" + +# RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK KMD 2954.24166783 +./komodo-cli sendtoaddress RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK 2954.24166783 +sleep 3 +echo "2954.24166783 <- expected amount RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK" + +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209 +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193 +./komodo-cli sendtoaddress RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU 35716.07599193 +sleep 3 +echo "35716.07599193 <- expected amount RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU" + +# R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH KMD 1681.36207445 +./komodo-cli sendtoaddress R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH 1681.36207445 +sleep 3 +echo "1681.36207445 <- expected amount R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH" + +# RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ KMD 7119.36644540 +./komodo-cli sendtoaddress RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ 7119.36644540 +sleep 3 +echo "7119.36644540 <- expected amount RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ" + +# RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV KMD 29049.45748125 +./komodo-cli sendtoaddress RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV 29049.45748125 +sleep 3 +echo "29049.45748125 <- expected amount RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV" + +# RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG KMD 216.38341633 +./komodo-cli sendtoaddress RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG 216.38341633 +sleep 3 +echo "216.38341633 <- expected amount RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG" + +# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 3239.94057692 +./komodo-cli sendtoaddress RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 3239.94057692 +sleep 3 +echo "3239.94057692 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9" + +# R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY KMD 723.21529345 +./komodo-cli sendtoaddress R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY 723.21529345 +sleep 3 +echo "723.21529345 <- expected amount R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY" + +# RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd KMD 20415.81928042 +./komodo-cli sendtoaddress RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd 20415.81928042 +sleep 3 +echo "20415.81928042 <- expected amount RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd" + +# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 4319.48050817 +./komodo-cli sendtoaddress RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 4319.48050817 +sleep 3 +echo "4319.48050817 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63" + +# RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 KMD 155.08169171 +./komodo-cli sendtoaddress RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 155.08169171 +sleep 3 +echo "155.08169171 <- expected amount RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1" + +# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 5177.29144163 +./komodo-cli sendtoaddress RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC 5177.29144163 +sleep 3 +echo "5177.29144163 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC" + +# RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS KMD 2034.11335616 +./komodo-cli sendtoaddress RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS 2034.11335616 +sleep 3 +echo "2034.11335616 <- expected amount RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS" + +# RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk KMD 8034.62340879 +./komodo-cli sendtoaddress RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk 8034.62340879 +sleep 3 +echo "8034.62340879 <- expected amount RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk" + +# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 987.78018920 +./komodo-cli sendtoaddress RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW 987.78018920 +sleep 3 +echo "987.78018920 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW" + +# RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM KMD 98.35737149 +./komodo-cli sendtoaddress RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM 98.35737149 +sleep 3 +echo "98.35737149 <- expected amount RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 8442.69675032 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 8442.69675032 +sleep 3 +echo "8442.69675032 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU KMD 35.32468867 +./komodo-cli sendtoaddress RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU 35.32468867 +sleep 3 +echo "35.32468867 <- expected amount RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU" + +# RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww KMD 2418.19228276 +./komodo-cli sendtoaddress RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww 2418.19228276 +sleep 3 +echo "2418.19228276 <- expected amount RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww" + +# RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb KMD 34.72735411 +./komodo-cli sendtoaddress RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb 34.72735411 +sleep 3 +echo "34.72735411 <- expected amount RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb" + +# RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ KMD 49.50870613 +./komodo-cli sendtoaddress RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ 49.50870613 +sleep 3 +echo "49.50870613 <- expected amount RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ" + +# RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ KMD 9683.15249375 +./komodo-cli sendtoaddress RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ" + +# RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u KMD 56.66050704 +./komodo-cli sendtoaddress RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u 56.66050704 +sleep 3 +echo "56.66050704 <- expected amount RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u" + +# RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 KMD 722.28571081 +./komodo-cli sendtoaddress RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 722.28571081 +sleep 3 +echo "722.28571081 <- expected amount RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74" + +# RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 KMD 226.29998024 +./komodo-cli sendtoaddress RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 226.29998024 +sleep 3 +echo "226.29998024 <- expected amount RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68" + +# RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P KMD 1160.04166875 +./komodo-cli sendtoaddress RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P 1160.04166875 +sleep 3 +echo "1160.04166875 <- expected amount RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P" + +# REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 KMD 5365.78339027 +./komodo-cli sendtoaddress REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 5365.78339027 +sleep 3 +echo "5365.78339027 <- expected amount REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3" + +# RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab KMD 9683.15249375 +./komodo-cli sendtoaddress RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab" + +# RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv KMD 2475.13554655 +./komodo-cli sendtoaddress RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv 2475.13554655 +sleep 3 +echo "2475.13554655 <- expected amount RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv" + +# RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp KMD 6778.20674562 +./komodo-cli sendtoaddress RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp 6778.20674562 +sleep 3 +echo "6778.20674562 <- expected amount RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp" + +# RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh KMD 3898.73512521 +./komodo-cli sendtoaddress RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh 3898.73512521 +sleep 3 +echo "3898.73512521 <- expected amount RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh" + +# R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ KMD 18775.43011383 +./komodo-cli sendtoaddress R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ 18775.43011383 +sleep 3 +echo "18775.43011383 <- expected amount R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ" + +# RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL KMD 49.27663407 +./komodo-cli sendtoaddress RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL 49.27663407 +sleep 3 +echo "49.27663407 <- expected amount RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL" + +# RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 KMD 1177.96870224 +./komodo-cli sendtoaddress RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 1177.96870224 +sleep 3 +echo "1177.96870224 <- expected amount RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3" + +# RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW KMD 3692.18604586 +./komodo-cli sendtoaddress RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW 3692.18604586 +sleep 3 +echo "3692.18604586 <- expected amount RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW" + +# RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S KMD 422.98413624 +./komodo-cli sendtoaddress RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S 422.98413624 +sleep 3 +echo "422.98413624 <- expected amount RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S" + +# RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk KMD 428171.85680159 +./komodo-cli sendtoaddress RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk 428171.85680159 +sleep 3 +echo "428171.85680159 <- expected amount RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk" + +# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 27228.79164783 +./komodo-cli sendtoaddress RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB 27228.79164783 +sleep 3 +echo "27228.79164783 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB" + +# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 6109.56883640 +./komodo-cli sendtoaddress RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU 6109.56883640 +sleep 3 +echo "6109.56883640 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU" + +# RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN KMD 316058.09739600 +./komodo-cli sendtoaddress RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN 316058.09739600 +sleep 3 +echo "316058.09739600 <- expected amount RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN" + +# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 51229.88531218 +./komodo-cli sendtoaddress RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH 51229.88531218 +sleep 3 +echo "51229.88531218 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH" + +# RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s KMD 110083.51536582 +./komodo-cli sendtoaddress RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s 110083.51536582 +sleep 3 +echo "110083.51536582 <- expected amount RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s" + +# RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX KMD 9295.82639400 +./komodo-cli sendtoaddress RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 2611.69343481 +./komodo-cli sendtoaddress RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK 2611.69343481 +sleep 3 +echo "2611.69343481 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs KMD 4841.57624687 +./komodo-cli sendtoaddress RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs 4841.57624687 +sleep 3 +echo "4841.57624687 <- expected amount RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs" + +# RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW KMD 813.38480947 +./komodo-cli sendtoaddress RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW 813.38480947 +sleep 3 +echo "813.38480947 <- expected amount RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW" + +# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 20170.43419449 +./komodo-cli sendtoaddress RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH 20170.43419449 +sleep 3 +echo "20170.43419449 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH" + +# RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD KMD 681.69393556 +./komodo-cli sendtoaddress RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD 681.69393556 +sleep 3 +echo "681.69393556 <- expected amount RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD" + +# RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim KMD 1510.02573700 +./komodo-cli sendtoaddress RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim 1510.02573700 +sleep 3 +echo "1510.02573700 <- expected amount RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy KMD 842.93959567 +./komodo-cli sendtoaddress RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy 842.93959567 +sleep 3 +echo "842.93959567 <- expected amount RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy" + +# RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue KMD 1580.29048698 +./komodo-cli sendtoaddress RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue 1580.29048698 +sleep 3 +echo "1580.29048698 <- expected amount RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue" + +# RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN KMD 2904.94574812 +./komodo-cli sendtoaddress RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN 2904.94574812 +sleep 3 +echo "2904.94574812 <- expected amount RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN" + +# RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX KMD 594.35547049 +./komodo-cli sendtoaddress RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX 594.35547049 +sleep 3 +echo "594.35547049 <- expected amount RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX" + +# RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE KMD 929.58263940 +./komodo-cli sendtoaddress RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE 929.58263940 +sleep 3 +echo "929.58263940 <- expected amount RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE" + +# RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP KMD 95491.01211941 +./komodo-cli sendtoaddress RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP 95491.01211941 +sleep 3 +echo "95491.01211941 <- expected amount RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP" + +# RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY KMD 2631.59182505 +./komodo-cli sendtoaddress RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY 2631.59182505 +sleep 3 +echo "2631.59182505 <- expected amount RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY" + +# RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn KMD 5701.16057828 +./komodo-cli sendtoaddress RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn 5701.16057828 +sleep 3 +echo "5701.16057828 <- expected amount RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn" + +# RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a KMD 49.10934879 +./komodo-cli sendtoaddress RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a 49.10934879 +sleep 3 +echo "49.10934879 <- expected amount RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a" + +# RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR KMD 911.94644914 +./komodo-cli sendtoaddress RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR 911.94644914 +sleep 3 +echo "911.94644914 <- expected amount RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR" + +# RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH KMD 2169.54630422 +./komodo-cli sendtoaddress RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH 2169.54630422 +sleep 3 +echo "2169.54630422 <- expected amount RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH" + +# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 12470.86256471 +./komodo-cli sendtoaddress RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi 12470.86256471 +sleep 3 +echo "12470.86256471 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi" + +# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 3365.89754092 +./komodo-cli sendtoaddress R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj 3365.89754092 +sleep 3 +echo "3365.89754092 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj" + +# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 511.26690948 +./komodo-cli sendtoaddress RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv 511.26690948 +sleep 3 +echo "511.26690948 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv" + + +# total KMD 2201860.11979328 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch17.listunspent b/iguana/tests/KMD.batch17.listunspent new file mode 100755 index 000000000..bffaab46a --- /dev/null +++ b/iguana/tests/KMD.batch17.listunspent @@ -0,0 +1,346 @@ +sleep 999999 +# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 108998.28313606 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8\",\"symbol\":\"KMD\"}" +echo "108998.28313606 <- expected amount RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 196.34763557 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "196.34763557 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU KMD 14524.72874062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU\",\"symbol\":\"KMD\"}" +echo "14524.72874062 <- expected amount RTdb8aKy9UyhaQhN4XzMxG2AhR6HfZ1ATU" + +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 16017.97255691 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REVcoi6A4GRfuchCXTwBTszbakhoh9inLs\",\"symbol\":\"KMD\"}" +echo "16017.97255691 <- expected amount REVcoi6A4GRfuchCXTwBTszbakhoh9inLs" + +# RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22 KMD 145928.92215821 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22\",\"symbol\":\"KMD\"}" +echo "145928.92215821 <- expected amount RND3dLBRRvqqCGw9Pe2c2VT68ognGA9h22" + +# RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6 KMD 114940.35721379 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6\",\"symbol\":\"KMD\"}" +echo "114940.35721379 <- expected amount RUMinvguFQSi3j9viHRpdocppdZ3r1SUj6" + +# RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU KMD 28699.34324752 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU\",\"symbol\":\"KMD\"}" +echo "28699.34324752 <- expected amount RVYZtHbqWg27o8PDVc8DiwxnuEw2pdfoDU" + +# RV25zizocv445ht9My45WaxpGuAC42cxLa KMD 101090.11347764 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RV25zizocv445ht9My45WaxpGuAC42cxLa\",\"symbol\":\"KMD\"}" +echo "101090.11347764 <- expected amount RV25zizocv445ht9My45WaxpGuAC42cxLa" + +# RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S KMD 1704.23483890 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S\",\"symbol\":\"KMD\"}" +echo "1704.23483890 <- expected amount RQJgyjp5MbTA6QBnDBB4gQgUkDwx39Wv5S" + +# RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD\",\"symbol\":\"KMD\"}" +echo "96831.52493750 <- expected amount RBoQRMAn8txSuC4n49V5sYXofMeYwacvnD" + +# RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve KMD 11.06362104 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve\",\"symbol\":\"KMD\"}" +echo "11.06362104 <- expected amount RQDJUGS4uAXSMasPLCSfWCYY3CEUQ8C1Ve" + +# RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv KMD 32009.28059927 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv\",\"symbol\":\"KMD\"}" +echo "32009.28059927 <- expected amount RJS6WdJgYh7RZQa1UsR6zN4EM6c1AB9fwv" + +# RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh KMD 305.48459176 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh\",\"symbol\":\"KMD\"}" +echo "305.48459176 <- expected amount RStHfZ1ZkPmg5aA5ZinoadfGd3n7p2bYuh" + +# RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3 KMD 162977.74808228 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3\",\"symbol\":\"KMD\"}" +echo "162977.74808228 <- expected amount RGDscrxo4txwMjg3DFxD9WQmsoqv54L5A3" + +# RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RArc3Gr7t5CfmqC4sYbJp9FHe8VbLiA9Qn" + +# RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3 KMD 1593.10203942 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3\",\"symbol\":\"KMD\"}" +echo "1593.10203942 <- expected amount RGcAkUkjGzbYDZVWwM6Y4v8KVWrjqeimw3" + +# RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu KMD 4066.11066256 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu\",\"symbol\":\"KMD\"}" +echo "4066.11066256 <- expected amount RFzRMuvV81ARPU55NhnkBRD3yi3znXG7tu" + +# RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc KMD 4014.80536992 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc\",\"symbol\":\"KMD\"}" +echo "4014.80536992 <- expected amount RDqVPXmcky1tueJ6tzqUDMv1o3NBCB3xvc" + +# RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd KMD 2904.94574812 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd\",\"symbol\":\"KMD\"}" +echo "2904.94574812 <- expected amount RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd" + +# REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc KMD 38080.08587787 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc\",\"symbol\":\"KMD\"}" +echo "38080.08587787 <- expected amount REeJHDzfSqf58Br7SgNJhwYwswNgP9jjrc" + +# RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7 KMD 875.08198390 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7\",\"symbol\":\"KMD\"}" +echo "875.08198390 <- expected amount RMAqR1iFUMkojtqaWNf2gThH3NKSey4yZ7" + +# RULousSwdVGhaP6vusva8u9AQWTs8ugjfp KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RULousSwdVGhaP6vusva8u9AQWTs8ugjfp\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RULousSwdVGhaP6vusva8u9AQWTs8ugjfp" + +# RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK KMD 2954.24166783 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK\",\"symbol\":\"KMD\"}" +echo "2954.24166783 <- expected amount RXGs9paVUE6cYE7UdEyTBGeQCcyXqJbuRK" + +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209 +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU\",\"symbol\":\"KMD\"}" +echo "35716.07599193 <- expected amount RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU" + +# R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH KMD 1681.36207445 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH\",\"symbol\":\"KMD\"}" +echo "1681.36207445 <- expected amount R9R5HirAzqDcWrWGiJEL115dpV3QB3hobH" + +# RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ KMD 7119.36644540 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ\",\"symbol\":\"KMD\"}" +echo "7119.36644540 <- expected amount RBCjXdMgAVP8NopCBk5bsCUz5ZFev6s8gJ" + +# RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV\",\"symbol\":\"KMD\"}" +echo "29049.45748125 <- expected amount RUM2zxUvxwGVErZ8QopcJD3uGaR7tmxxNV" + +# RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG KMD 216.38341633 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG\",\"symbol\":\"KMD\"}" +echo "216.38341633 <- expected amount RUBFFG9jXRZMrqGsbTcCYmXccF1C8BiDLG" + +# RWc6GouJggQDsBCeW1DYck629FPrDJCTP9 KMD 3239.94057692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWc6GouJggQDsBCeW1DYck629FPrDJCTP9\",\"symbol\":\"KMD\"}" +echo "3239.94057692 <- expected amount RWc6GouJggQDsBCeW1DYck629FPrDJCTP9" + +# R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY KMD 723.21529345 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY\",\"symbol\":\"KMD\"}" +echo "723.21529345 <- expected amount R9TmkWG5UwwgLeg6vvtLA234gAiYeE2fJY" + +# RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd KMD 20415.81928042 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd\",\"symbol\":\"KMD\"}" +echo "20415.81928042 <- expected amount RP3ND8ZShCHMnnDeTcLXxdzndTNQzpUSXd" + +# RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63 KMD 4319.48050817 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63\",\"symbol\":\"KMD\"}" +echo "4319.48050817 <- expected amount RMgsHEcKzg5n5NkHs5jz4hVg7avbYsct63" + +# RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1 KMD 155.08169171 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1\",\"symbol\":\"KMD\"}" +echo "155.08169171 <- expected amount RRFpb6JQn6jrZbPiXq7C3rWfnPLjeyzFE1" + +# RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC KMD 5177.29144163 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC\",\"symbol\":\"KMD\"}" +echo "5177.29144163 <- expected amount RKjRhiPHQJEf65CwXTjBHLQ5r2fKfpeyBC" + +# RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS KMD 2034.11335616 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS\",\"symbol\":\"KMD\"}" +echo "2034.11335616 <- expected amount RFyRXwf5TyqLM5vJfa5k2dCub614tQKKGS" + +# RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk KMD 8034.62340879 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk\",\"symbol\":\"KMD\"}" +echo "8034.62340879 <- expected amount RWR94SErHZAZXNgKrhYrPAaiU6FWVagZSk" + +# RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW KMD 987.78018920 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW\",\"symbol\":\"KMD\"}" +echo "987.78018920 <- expected amount RC8LVu8PejVfzpRQ8bDXxv9jMhur3K9ErW" + +# RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM KMD 98.35737149 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM\",\"symbol\":\"KMD\"}" +echo "98.35737149 <- expected amount RSxZyyY9ok8ciXJysU9eYhoQsFbozwiZZM" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 8442.69675032 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "8442.69675032 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU KMD 35.32468867 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU\",\"symbol\":\"KMD\"}" +echo "35.32468867 <- expected amount RTtd8gWY1Yu4fWz89kjdSZCpzaWdnK5sYU" + +# RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww KMD 2418.19228276 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww\",\"symbol\":\"KMD\"}" +echo "2418.19228276 <- expected amount RCAtTmppsyCrsEYoxpLCANGzCVJwJfcfww" + +# RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb KMD 34.72735411 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb\",\"symbol\":\"KMD\"}" +echo "34.72735411 <- expected amount RHMvt73J6AV2sQP6at6pgQcdpywQFrZABb" + +# RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ KMD 49.50870613 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ\",\"symbol\":\"KMD\"}" +echo "49.50870613 <- expected amount RTVfykmTFwn6XyuDGSAKp9UK4oBkwfr4JZ" + +# RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RB8pkhY441oNYqJYtbWVmChZsByDsHBiKQ" + +# RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u KMD 56.66050704 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u\",\"symbol\":\"KMD\"}" +echo "56.66050704 <- expected amount RT8Uis8D3jusKUoZVru3DtHSnfSqHHFe2u" + +# RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74 KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74\",\"symbol\":\"KMD\"}" +echo "722.28571081 <- expected amount RDJg1f9tuySVCvjZVUbFXhhG2ikM4hft74" + +# RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68 KMD 226.29998024 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68\",\"symbol\":\"KMD\"}" +echo "226.29998024 <- expected amount RKuUZDDjHb3SfbZJJMic5s8mq4f8LKzz68" + +# RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P KMD 1160.04166875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P\",\"symbol\":\"KMD\"}" +echo "1160.04166875 <- expected amount RG9EcdLkQvWmNBNhLvqgNUNA9XCmvBtg4P" + +# REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3 KMD 5365.78339027 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3\",\"symbol\":\"KMD\"}" +echo "5365.78339027 <- expected amount REuh3kBhL3J4wFqoezgm5sH4CcZAivmwv3" + +# RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RDx1Py1724JGmq9PZUjxb8117h7Traw8Ab" + +# RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv KMD 2475.13554655 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv\",\"symbol\":\"KMD\"}" +echo "2475.13554655 <- expected amount RXGNx35hp7uZL6g19AWmQv3BuF5xWvrNNv" + +# RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp KMD 6778.20674562 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp\",\"symbol\":\"KMD\"}" +echo "6778.20674562 <- expected amount RACobrNdsFuWFiB9ZtYcj2RFUUKZ3Y1tGp" + +# RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh KMD 3898.73512521 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh\",\"symbol\":\"KMD\"}" +echo "3898.73512521 <- expected amount RLGFJUBLHCiGinRUM2qJ1YRKWNunmYKBoh" + +# R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ KMD 18775.43011383 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ\",\"symbol\":\"KMD\"}" +echo "18775.43011383 <- expected amount R9QFWSLfYM22cTYxxDKUdvdxFN2UDByijJ" + +# RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL KMD 49.27663407 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL\",\"symbol\":\"KMD\"}" +echo "49.27663407 <- expected amount RK3mfPzjv4XmPmNboLagSrV6dUKmkwvSRL" + +# RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3 KMD 1177.96870224 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3\",\"symbol\":\"KMD\"}" +echo "1177.96870224 <- expected amount RABX76mRux6dbADB2mM6F2gUbG1a5m1TH3" + +# RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW KMD 3692.18604586 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW\",\"symbol\":\"KMD\"}" +echo "3692.18604586 <- expected amount RMi53BdThuz7UA8jbJRLC6y4YSGzjP8yPW" + +# RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S KMD 422.98413624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S\",\"symbol\":\"KMD\"}" +echo "422.98413624 <- expected amount RY69roX9pRXdH3yeF8WMFUDWFEoEdWDn5S" + +# RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk KMD 428171.85680159 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk\",\"symbol\":\"KMD\"}" +echo "428171.85680159 <- expected amount RSPk4oi4dfq39LtrHucgaQLNfqcRc2vEvk" + +# RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB KMD 27228.79164783 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB\",\"symbol\":\"KMD\"}" +echo "27228.79164783 <- expected amount RMb8RPMeah3DF62p16eHALFBZ2KrhUsMuB" + +# RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU KMD 6109.56883640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU\",\"symbol\":\"KMD\"}" +echo "6109.56883640 <- expected amount RSEdLeDWTWdnFK4w8NZSNMxx7KTeTsaycU" + +# RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN KMD 316058.09739600 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN\",\"symbol\":\"KMD\"}" +echo "316058.09739600 <- expected amount RJZcnvtoZ9waY56kZou9jvHQVjXRv6aWGN" + +# RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH KMD 51229.88531218 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH\",\"symbol\":\"KMD\"}" +echo "51229.88531218 <- expected amount RP1h1V7cwz6gkqEm1cNdhzbYdTuRxrj5AH" + +# RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s KMD 110083.51536582 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s\",\"symbol\":\"KMD\"}" +echo "110083.51536582 <- expected amount RJsu52kYvdGzSZyxY53vJiUx7EkLtYof1s" + +# RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RGZUWVDbeNsBknJuqS4oaF9q4k5ndwo9KX" + +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 2611.69343481 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK\",\"symbol\":\"KMD\"}" +echo "2611.69343481 <- expected amount RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK" + +# RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs KMD 4841.57624687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs\",\"symbol\":\"KMD\"}" +echo "4841.57624687 <- expected amount RXPyGtmWdGeAYLBm4TdfrQW5AUMjCxziVs" + +# RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW KMD 813.38480947 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW\",\"symbol\":\"KMD\"}" +echo "813.38480947 <- expected amount RRfjHMdC59DDDFWAmcD48USzX6T6QKkfaW" + +# RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH KMD 20170.43419449 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH\",\"symbol\":\"KMD\"}" +echo "20170.43419449 <- expected amount RLFkkg4L1HxiVdZna1VMQHYhSSmpXqMyZH" + +# RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD KMD 681.69393556 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD\",\"symbol\":\"KMD\"}" +echo "681.69393556 <- expected amount RM73efhu5ED4T6DYi3PZXJCiwmkHABNafD" + +# RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim KMD 1510.02573700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim\",\"symbol\":\"KMD\"}" +echo "1510.02573700 <- expected amount RQQtcWoGzkTfbD3TPfUMNyLeqhge8bJdim" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy KMD 842.93959567 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy\",\"symbol\":\"KMD\"}" +echo "842.93959567 <- expected amount RUKkv5Fz4LuWVVkjLiA5m6TWkvqt8h1kgy" + +# RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue KMD 1580.29048698 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue\",\"symbol\":\"KMD\"}" +echo "1580.29048698 <- expected amount RX2SkGDAB9aANzTQe3DWqtjNv8rszmo8Ue" + +# RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN KMD 2904.94574812 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN\",\"symbol\":\"KMD\"}" +echo "2904.94574812 <- expected amount RGH1nTajxYK6pYJzJJvj4g9a6QQ8DLCdFN" + +# RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX KMD 594.35547049 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX\",\"symbol\":\"KMD\"}" +echo "594.35547049 <- expected amount RTREfp1yUnazmJi4KWzy7tCN8UPXHNoBwX" + +# RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE KMD 929.58263940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE\",\"symbol\":\"KMD\"}" +echo "929.58263940 <- expected amount RYLt5Ui2QpCAB7QMJYgHYDEx7T9v7MohKE" + +# RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP KMD 95491.01211941 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP\",\"symbol\":\"KMD\"}" +echo "95491.01211941 <- expected amount RTfaPuVrwm9pvYHWskyyxJtRbhk9GnMRXP" + +# RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY KMD 2631.59182505 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY\",\"symbol\":\"KMD\"}" +echo "2631.59182505 <- expected amount RDkKfXfzCb5kimNFymXbWwbn6hGWtaRoqY" + +# RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn KMD 5701.16057828 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn\",\"symbol\":\"KMD\"}" +echo "5701.16057828 <- expected amount RJVPgswKQzcWxHB1Woin6QKpPVYRpXVoFn" + +# RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a KMD 49.10934879 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a\",\"symbol\":\"KMD\"}" +echo "49.10934879 <- expected amount RCpUUnr6d8zei1oBSu4hSeWU9m6eVEig6a" + +# RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR KMD 911.94644914 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR\",\"symbol\":\"KMD\"}" +echo "911.94644914 <- expected amount RH1ZmVCNRmnwrVuLiXN5kp2Rw11kkMEhSR" + +# RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH KMD 2169.54630422 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH\",\"symbol\":\"KMD\"}" +echo "2169.54630422 <- expected amount RUUH1M8rdBbiiaKHDFwvQgaStgchkJunGH" + +# RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi KMD 12470.86256471 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi\",\"symbol\":\"KMD\"}" +echo "12470.86256471 <- expected amount RJW64iw5NsX74TZUi4Ngx7j8v2AHRPhKEi" + +# R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj KMD 3365.89754092 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj\",\"symbol\":\"KMD\"}" +echo "3365.89754092 <- expected amount R9rw4XnwfkQybdrVru9hPmg7n7JdDFkkLj" + +# RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv KMD 511.26690948 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv\",\"symbol\":\"KMD\"}" +echo "511.26690948 <- expected amount RLHrGiqRbVsDttjFqVVSkxCzn2QpH4VXkv" + diff --git a/iguana/tests/KMD.batch2.importaddress b/iguana/tests/KMD.batch2.importaddress new file mode 100755 index 000000000..55770931b --- /dev/null +++ b/iguana/tests/KMD.batch2.importaddress @@ -0,0 +1,264 @@ +# RDB6rqTtXja9iRKu5KeKz36poQqQkadsvG KMD 1597.72016146 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDB6rqTtXja9iRKu5KeKz36poQqQkadsvG\",\"symbol\":\"KMD\"}" # 1597.72016146 +sleep 3 +echo "1597.72016146 <- expected amount RDB6rqTtXja9iRKu5KeKz36poQqQkadsvG" + +# RFahFwS1xmwufLvidWFg3aQwi6JnZ7MV92 KMD 30956.65119641 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFahFwS1xmwufLvidWFg3aQwi6JnZ7MV92\",\"symbol\":\"KMD\"}" # 30956.65119641 +sleep 3 +echo "30956.65119641 <- expected amount RFahFwS1xmwufLvidWFg3aQwi6JnZ7MV92" + +# RS3dv3trTkvMUc1qpycmcY2mZRZj527HMG KMD 8011.05479853 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS3dv3trTkvMUc1qpycmcY2mZRZj527HMG\",\"symbol\":\"KMD\"}" # 8011.05479853 +sleep 3 +echo "8011.05479853 <- expected amount RS3dv3trTkvMUc1qpycmcY2mZRZj527HMG" + +# RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU KMD 501.64865701, REVS 9.95750000 +# RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU KMD 501.64865701 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU\",\"symbol\":\"KMD\"}" # 501.64865701 +sleep 3 +echo "501.64865701 <- expected amount RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU" + +# RFuD6bLb6seuKPmQqouwcjAy1yexEYGJ8Q KMD 6617.71011981 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFuD6bLb6seuKPmQqouwcjAy1yexEYGJ8Q\",\"symbol\":\"KMD\"}" # 6617.71011981 +sleep 3 +echo "6617.71011981 <- expected amount RFuD6bLb6seuKPmQqouwcjAy1yexEYGJ8Q" + +# RSj2RG9yEbokDDNCn94g6wRf3y1R4HztjT KMD 58970.39868693 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSj2RG9yEbokDDNCn94g6wRf3y1R4HztjT\",\"symbol\":\"KMD\"}" # 58970.39868693 +sleep 3 +echo "58970.39868693 <- expected amount RSj2RG9yEbokDDNCn94g6wRf3y1R4HztjT" + +# RLWjPQPe4zZ1ZF4VpShkiBkgkF4V9YFt7a KMD 18618.76561497 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLWjPQPe4zZ1ZF4VpShkiBkgkF4V9YFt7a\",\"symbol\":\"KMD\"}" # 18618.76561497 +sleep 3 +echo "18618.76561497 <- expected amount RLWjPQPe4zZ1ZF4VpShkiBkgkF4V9YFt7a" + +# RARemRFU1R5QcRdDZqrufjks2KCzBi6bxL KMD 52766.61227268 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RARemRFU1R5QcRdDZqrufjks2KCzBi6bxL\",\"symbol\":\"KMD\"}" # 52766.61227268 +sleep 3 +echo "52766.61227268 <- expected amount RARemRFU1R5QcRdDZqrufjks2KCzBi6bxL" + +# REg8BhZUaxjJu8Ad4ZYsrETJwcwYL7mPkC KMD 7204.26545535 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REg8BhZUaxjJu8Ad4ZYsrETJwcwYL7mPkC\",\"symbol\":\"KMD\"}" # 7204.26545535 +sleep 3 +echo "7204.26545535 <- expected amount REg8BhZUaxjJu8Ad4ZYsrETJwcwYL7mPkC" + +# RMnLqCcb13npqdUMgUYAdr4bGawNe5H8yo KMD 871.48372443 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMnLqCcb13npqdUMgUYAdr4bGawNe5H8yo\",\"symbol\":\"KMD\"}" # 871.48372443 +sleep 3 +echo "871.48372443 <- expected amount RMnLqCcb13npqdUMgUYAdr4bGawNe5H8yo" + +# RWCz1ibkFVpo6pBoBT7XeMZHVZy61EnYj3 KMD 681.69393556 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWCz1ibkFVpo6pBoBT7XeMZHVZy61EnYj3\",\"symbol\":\"KMD\"}" # 681.69393556 +sleep 3 +echo "681.69393556 <- expected amount RWCz1ibkFVpo6pBoBT7XeMZHVZy61EnYj3" + +# RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf KMD 62103.45021354, REVS 50.00000000 +# RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf KMD 62103.45021354 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf\",\"symbol\":\"KMD\"}" # 62103.45021354 +sleep 3 +echo "62103.45021354 <- expected amount RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf" + +# RRcP4HLapHvTinSVYq6bMA3d41XeYCH2Uz KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRcP4HLapHvTinSVYq6bMA3d41XeYCH2Uz\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RRcP4HLapHvTinSVYq6bMA3d41XeYCH2Uz" + +# RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71 KMD 12520.16564088, REVS 138.94305839 +# RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71 KMD 12520.16564088 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71\",\"symbol\":\"KMD\"}" # 12520.16564088 +sleep 3 +echo "12520.16564088 <- expected amount RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71" + +# RKb5ay26iSzmBoqm51vPveyErH9BYG3dry KMD 3674.15911735, REVS 72.89043156 +# RKb5ay26iSzmBoqm51vPveyErH9BYG3dry KMD 3674.15911735 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKb5ay26iSzmBoqm51vPveyErH9BYG3dry\",\"symbol\":\"KMD\"}" # 3674.15911735 +sleep 3 +echo "3674.15911735 <- expected amount RKb5ay26iSzmBoqm51vPveyErH9BYG3dry" + +# RNFKCPjFTQq5pFxBpehrVFzB55zE9enRyK KMD 1859.16527880 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNFKCPjFTQq5pFxBpehrVFzB55zE9enRyK\",\"symbol\":\"KMD\"}" # 1859.16527880 +sleep 3 +echo "1859.16527880 <- expected amount RNFKCPjFTQq5pFxBpehrVFzB55zE9enRyK" + +# REGu6tiLygx7HjsRnEYypHiV3QotErvKxP KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REGu6tiLygx7HjsRnEYypHiV3QotErvKxP\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount REGu6tiLygx7HjsRnEYypHiV3QotErvKxP" + +# RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx KMD 612851.03780014, REVS 5433.13031755 +# RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx KMD 612851.03780014 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx\",\"symbol\":\"KMD\"}" # 612851.03780014 +sleep 3 +echo "612851.03780014 <- expected amount RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx" + +# RVGv9EP36z2SHf5zuGrGKEq6or8Q2hEPts KMD 954.83978703 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVGv9EP36z2SHf5zuGrGKEq6or8Q2hEPts\",\"symbol\":\"KMD\"}" # 954.83978703 +sleep 3 +echo "954.83978703 <- expected amount RVGv9EP36z2SHf5zuGrGKEq6or8Q2hEPts" + +# RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN KMD 139007.63452726 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN\",\"symbol\":\"KMD\"}" # 139007.63452726 +sleep 3 +echo "139007.63452726 <- expected amount RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN" + +# RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp KMD 519232.27493854, REVS 10298.05578171 +# RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp KMD 519232.27493854 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp\",\"symbol\":\"KMD\"}" # 519232.27493854 +sleep 3 +echo "519232.27493854 <- expected amount RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp" + +# RV6EZQRiEszMydw3VjLabjGCBG1HiHrU6f KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV6EZQRiEszMydw3VjLabjGCBG1HiHrU6f\",\"symbol\":\"KMD\"}" # 19366.30498750 +sleep 3 +echo "19366.30498750 <- expected amount RV6EZQRiEszMydw3VjLabjGCBG1HiHrU6f" + +# RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i KMD 19106.59220646, REVS 374.39305755 +# RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i KMD 19106.59220646 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i\",\"symbol\":\"KMD\"}" # 19106.59220646 +sleep 3 +echo "19106.59220646 <- expected amount RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i" + +# RK5z4QVhNBWJn5xSkpPPgdcZzms7VtFV4x KMD 3097.05949360 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK5z4QVhNBWJn5xSkpPPgdcZzms7VtFV4x\",\"symbol\":\"KMD\"}" # 3097.05949360 +sleep 3 +echo "3097.05949360 <- expected amount RK5z4QVhNBWJn5xSkpPPgdcZzms7VtFV4x" + +# RTSFrcYBPZ3wMUtJCo5RC8n71R2c1ypC46 KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTSFrcYBPZ3wMUtJCo5RC8n71R2c1ypC46\",\"symbol\":\"KMD\"}" # 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RTSFrcYBPZ3wMUtJCo5RC8n71R2c1ypC46" + +# RSxDyaWzqT3VTK9WLkAKhY5WST8a9kQgr9 KMD 14268.23083290 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSxDyaWzqT3VTK9WLkAKhY5WST8a9kQgr9\",\"symbol\":\"KMD\"}" # 14268.23083290 +sleep 3 +echo "14268.23083290 <- expected amount RSxDyaWzqT3VTK9WLkAKhY5WST8a9kQgr9" + +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 1212.14061568, REVS 24.05385000 +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 1212.14061568 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf\",\"symbol\":\"KMD\"}" # 1212.14061568 +sleep 3 +echo "1212.14061568 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf" + +# RVUFVtJN2mVDEsADwMfZBBXXSq3G9QCvBs KMD 20418.65848567 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVUFVtJN2mVDEsADwMfZBBXXSq3G9QCvBs\",\"symbol\":\"KMD\"}" # 20418.65848567 +sleep 3 +echo "20418.65848567 <- expected amount RVUFVtJN2mVDEsADwMfZBBXXSq3G9QCvBs" + +# RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza KMD 10347.76210933, REVS 205.22959870 +# RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza KMD 10347.76210933 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza\",\"symbol\":\"KMD\"}" # 10347.76210933 +sleep 3 +echo "10347.76210933 <- expected amount RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza" + +# RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr KMD 71712.83911390, REVS 500.67180183 +# RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr KMD 71712.83911390 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr\",\"symbol\":\"KMD\"}" # 71712.83911390 +sleep 3 +echo "71712.83911390 <- expected amount RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr" + +# RNszK1KnyyDoU6di3qQgCYvSL3V3ZgGNGY KMD 26725.50088275 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNszK1KnyyDoU6di3qQgCYvSL3V3ZgGNGY\",\"symbol\":\"KMD\"}" # 26725.50088275 +sleep 3 +echo "26725.50088275 <- expected amount RNszK1KnyyDoU6di3qQgCYvSL3V3ZgGNGY" + +# RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr KMD 16435.34703311, REVS 114.80740001 +# RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr KMD 16435.34703311 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr\",\"symbol\":\"KMD\"}" # 16435.34703311 +sleep 3 +echo "16435.34703311 <- expected amount RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr" + +# RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr KMD 17137.93285029, REVS 340.00462653 +# RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr KMD 17137.93285029 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr\",\"symbol\":\"KMD\"}" # 17137.93285029 +sleep 3 +echo "17137.93285029 <- expected amount RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr" + +# RMKk4K7zC6QrESUxNGRTfqbBnXr2MFYsLV KMD 1302.29267891 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMKk4K7zC6QrESUxNGRTfqbBnXr2MFYsLV\",\"symbol\":\"KMD\"}" # 1302.29267891 +sleep 3 +echo "1302.29267891 <- expected amount RMKk4K7zC6QrESUxNGRTfqbBnXr2MFYsLV" + +# RJaaPBFPBTtqzPZ5ZV2uu15urxhiycwg7K KMD 32805.26183900 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJaaPBFPBTtqzPZ5ZV2uu15urxhiycwg7K\",\"symbol\":\"KMD\"}" # 32805.26183900 +sleep 3 +echo "32805.26183900 <- expected amount RJaaPBFPBTtqzPZ5ZV2uu15urxhiycwg7K" + +# R9isnAJ2iyyFq8BMZZJu8PiFLpnXPhXcZ7 KMD 502854.27827071 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9isnAJ2iyyFq8BMZZJu8PiFLpnXPhXcZ7\",\"symbol\":\"KMD\"}" # 502854.27827071 +sleep 3 +echo "502854.27827071 <- expected amount R9isnAJ2iyyFq8BMZZJu8PiFLpnXPhXcZ7" + +# RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF KMD 409543.68954327, REVS 8123.68911362 +# RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF KMD 409543.68954327 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF\",\"symbol\":\"KMD\"}" # 409543.68954327 +sleep 3 +echo "409543.68954327 <- expected amount RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF" + +# RQWxU8AV5SkKCmz6Q3CecmAtnauESPxDod KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQWxU8AV5SkKCmz6Q3CecmAtnauESPxDod\",\"symbol\":\"KMD\"}" # 8908.50029425 +sleep 3 +echo "8908.50029425 <- expected amount RQWxU8AV5SkKCmz6Q3CecmAtnauESPxDod" + +# RMqivy9QZ7ax1UU8ZxqaupLqDqEBAFW6MY KMD 708.48776076 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMqivy9QZ7ax1UU8ZxqaupLqDqEBAFW6MY\",\"symbol\":\"KMD\"}" # 708.48776076 +sleep 3 +echo "708.48776076 <- expected amount RMqivy9QZ7ax1UU8ZxqaupLqDqEBAFW6MY" + +# RV85Dvvf4fm13xxtjmucYXDAarMcnV8EFq KMD 29057.20400324 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV85Dvvf4fm13xxtjmucYXDAarMcnV8EFq\",\"symbol\":\"KMD\"}" # 29057.20400324 +sleep 3 +echo "29057.20400324 <- expected amount RV85Dvvf4fm13xxtjmucYXDAarMcnV8EFq" + +# RJzRaaqhT8R7pbVuVeY3C69X9K89UMU55E KMD 632.08133544 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJzRaaqhT8R7pbVuVeY3C69X9K89UMU55E\",\"symbol\":\"KMD\"}" # 632.08133544 +sleep 3 +echo "632.08133544 <- expected amount RJzRaaqhT8R7pbVuVeY3C69X9K89UMU55E" + +# RCBSjuktzRbsz1UHKjFmTUVG6nDNhd3y2g KMD 24029.98198519 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCBSjuktzRbsz1UHKjFmTUVG6nDNhd3y2g\",\"symbol\":\"KMD\"}" # 24029.98198519 +sleep 3 +echo "24029.98198519 <- expected amount RCBSjuktzRbsz1UHKjFmTUVG6nDNhd3y2g" + +# RKDnex4tqTGA9u2UqEDGS8uTxceqWGwejk KMD 10684.09534584 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKDnex4tqTGA9u2UqEDGS8uTxceqWGwejk\",\"symbol\":\"KMD\"}" # 10684.09534584 +sleep 3 +echo "10684.09534584 <- expected amount RKDnex4tqTGA9u2UqEDGS8uTxceqWGwejk" + +# RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d KMD 302.06577591, REVS 5.99094155 +# RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d KMD 302.06577591 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d\",\"symbol\":\"KMD\"}" # 302.06577591 +sleep 3 +echo "302.06577591 <- expected amount RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d" + +# REhPMC2k5XAsiqd3X1afzdT6SzE9vY7MS6 KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REhPMC2k5XAsiqd3X1afzdT6SzE9vY7MS6\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount REhPMC2k5XAsiqd3X1afzdT6SzE9vY7MS6" + +# RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL KMD 30407.13753317, REVS 411.30538288 +# RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL KMD 30407.13753317 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL\",\"symbol\":\"KMD\"}" # 30407.13753317 +sleep 3 +echo "30407.13753317 <- expected amount RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL" + +# RKa3UX7xvQuYhd9LWHFGjQm8EjbLcnLxo1 KMD 4647.91319700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKa3UX7xvQuYhd9LWHFGjQm8EjbLcnLxo1\",\"symbol\":\"KMD\"}" # 4647.91319700 +sleep 3 +echo "4647.91319700 <- expected amount RKa3UX7xvQuYhd9LWHFGjQm8EjbLcnLxo1" + +# RRBhAPHb7WY2XrLSST2oymc4LYtCskzijc KMD 1914.39627638 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRBhAPHb7WY2XrLSST2oymc4LYtCskzijc\",\"symbol\":\"KMD\"}" # 1914.39627638 +sleep 3 +echo "1914.39627638 <- expected amount RRBhAPHb7WY2XrLSST2oymc4LYtCskzijc" + +# RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6 KMD 56568.34116197 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6\",\"symbol\":\"KMD\"}" # 56568.34116197 +sleep 3 +echo "56568.34116197 <- expected amount RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6" + +# RNkRuGR4uFrcMqrPMu8X5Nwvgbc3Jxxkqk KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNkRuGR4uFrcMqrPMu8X5Nwvgbc3Jxxkqk\",\"symbol\":\"KMD\"}" # 96831.52493750 +sleep 3 +echo "96831.52493750 <- expected amount RNkRuGR4uFrcMqrPMu8X5Nwvgbc3Jxxkqk" diff --git a/iguana/tests/KMD.batch2.listunspent b/iguana/tests/KMD.batch2.listunspent new file mode 100755 index 000000000..c80fa6e04 --- /dev/null +++ b/iguana/tests/KMD.batch2.listunspent @@ -0,0 +1,215 @@ +# RDB6rqTtXja9iRKu5KeKz36poQqQkadsvG KMD 1597.72016146 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDB6rqTtXja9iRKu5KeKz36poQqQkadsvG\",\"symbol\":\"KMD\"}" +echo "1597.72016146 <- expected amount RDB6rqTtXja9iRKu5KeKz36poQqQkadsvG" + +# RFahFwS1xmwufLvidWFg3aQwi6JnZ7MV92 KMD 30956.65119641 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFahFwS1xmwufLvidWFg3aQwi6JnZ7MV92\",\"symbol\":\"KMD\"}" +echo "30956.65119641 <- expected amount RFahFwS1xmwufLvidWFg3aQwi6JnZ7MV92" + +# RS3dv3trTkvMUc1qpycmcY2mZRZj527HMG KMD 8011.05479853 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RS3dv3trTkvMUc1qpycmcY2mZRZj527HMG\",\"symbol\":\"KMD\"}" +echo "8011.05479853 <- expected amount RS3dv3trTkvMUc1qpycmcY2mZRZj527HMG" + +# RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU KMD 501.64865701, REVS 9.95750000 +# RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU KMD 501.64865701 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU\",\"symbol\":\"KMD\"}" +echo "501.64865701 <- expected amount RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU" + +# RFuD6bLb6seuKPmQqouwcjAy1yexEYGJ8Q KMD 6617.71011981 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFuD6bLb6seuKPmQqouwcjAy1yexEYGJ8Q\",\"symbol\":\"KMD\"}" +echo "6617.71011981 <- expected amount RFuD6bLb6seuKPmQqouwcjAy1yexEYGJ8Q" + +# RSj2RG9yEbokDDNCn94g6wRf3y1R4HztjT KMD 58970.39868693 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSj2RG9yEbokDDNCn94g6wRf3y1R4HztjT\",\"symbol\":\"KMD\"}" +echo "58970.39868693 <- expected amount RSj2RG9yEbokDDNCn94g6wRf3y1R4HztjT" + +# RLWjPQPe4zZ1ZF4VpShkiBkgkF4V9YFt7a KMD 18618.76561497 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLWjPQPe4zZ1ZF4VpShkiBkgkF4V9YFt7a\",\"symbol\":\"KMD\"}" +echo "18618.76561497 <- expected amount RLWjPQPe4zZ1ZF4VpShkiBkgkF4V9YFt7a" + +# RARemRFU1R5QcRdDZqrufjks2KCzBi6bxL KMD 52766.61227268 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RARemRFU1R5QcRdDZqrufjks2KCzBi6bxL\",\"symbol\":\"KMD\"}" +echo "52766.61227268 <- expected amount RARemRFU1R5QcRdDZqrufjks2KCzBi6bxL" + +# REg8BhZUaxjJu8Ad4ZYsrETJwcwYL7mPkC KMD 7204.26545535 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REg8BhZUaxjJu8Ad4ZYsrETJwcwYL7mPkC\",\"symbol\":\"KMD\"}" +echo "7204.26545535 <- expected amount REg8BhZUaxjJu8Ad4ZYsrETJwcwYL7mPkC" + +# RMnLqCcb13npqdUMgUYAdr4bGawNe5H8yo KMD 871.48372443 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMnLqCcb13npqdUMgUYAdr4bGawNe5H8yo\",\"symbol\":\"KMD\"}" +echo "871.48372443 <- expected amount RMnLqCcb13npqdUMgUYAdr4bGawNe5H8yo" + +# RWCz1ibkFVpo6pBoBT7XeMZHVZy61EnYj3 KMD 681.69393556 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWCz1ibkFVpo6pBoBT7XeMZHVZy61EnYj3\",\"symbol\":\"KMD\"}" +echo "681.69393556 <- expected amount RWCz1ibkFVpo6pBoBT7XeMZHVZy61EnYj3" + +# RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf KMD 62103.45021354, REVS 50.00000000 +# RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf KMD 62103.45021354 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf\",\"symbol\":\"KMD\"}" +echo "62103.45021354 <- expected amount RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf" + +# RRcP4HLapHvTinSVYq6bMA3d41XeYCH2Uz KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRcP4HLapHvTinSVYq6bMA3d41XeYCH2Uz\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RRcP4HLapHvTinSVYq6bMA3d41XeYCH2Uz" + +# RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71 KMD 12520.16564088, REVS 138.94305839 +# RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71 KMD 12520.16564088 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71\",\"symbol\":\"KMD\"}" +echo "12520.16564088 <- expected amount RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71" + +# RKb5ay26iSzmBoqm51vPveyErH9BYG3dry KMD 3674.15911735, REVS 72.89043156 +# RKb5ay26iSzmBoqm51vPveyErH9BYG3dry KMD 3674.15911735 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKb5ay26iSzmBoqm51vPveyErH9BYG3dry\",\"symbol\":\"KMD\"}" +echo "3674.15911735 <- expected amount RKb5ay26iSzmBoqm51vPveyErH9BYG3dry" + +# RNFKCPjFTQq5pFxBpehrVFzB55zE9enRyK KMD 1859.16527880 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNFKCPjFTQq5pFxBpehrVFzB55zE9enRyK\",\"symbol\":\"KMD\"}" +echo "1859.16527880 <- expected amount RNFKCPjFTQq5pFxBpehrVFzB55zE9enRyK" + +# REGu6tiLygx7HjsRnEYypHiV3QotErvKxP KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REGu6tiLygx7HjsRnEYypHiV3QotErvKxP\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount REGu6tiLygx7HjsRnEYypHiV3QotErvKxP" + +# RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx KMD 612851.03780014, REVS 5433.13031755 +# RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx KMD 612851.03780014 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx\",\"symbol\":\"KMD\"}" +echo "612851.03780014 <- expected amount RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx" + +# RVGv9EP36z2SHf5zuGrGKEq6or8Q2hEPts KMD 954.83978703 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVGv9EP36z2SHf5zuGrGKEq6or8Q2hEPts\",\"symbol\":\"KMD\"}" +echo "954.83978703 <- expected amount RVGv9EP36z2SHf5zuGrGKEq6or8Q2hEPts" + +# RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN KMD 139007.63452726 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN\",\"symbol\":\"KMD\"}" +echo "139007.63452726 <- expected amount RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN" + +# RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp KMD 519232.27493854, REVS 10298.05578171 +# RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp KMD 519232.27493854 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp\",\"symbol\":\"KMD\"}" +echo "519232.27493854 <- expected amount RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp" + +# RV6EZQRiEszMydw3VjLabjGCBG1HiHrU6f KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RV6EZQRiEszMydw3VjLabjGCBG1HiHrU6f\",\"symbol\":\"KMD\"}" +echo "19366.30498750 <- expected amount RV6EZQRiEszMydw3VjLabjGCBG1HiHrU6f" + +# RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i KMD 19106.59220646, REVS 374.39305755 +# RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i KMD 19106.59220646 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i\",\"symbol\":\"KMD\"}" +echo "19106.59220646 <- expected amount RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i" + +# RK5z4QVhNBWJn5xSkpPPgdcZzms7VtFV4x KMD 3097.05949360 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RK5z4QVhNBWJn5xSkpPPgdcZzms7VtFV4x\",\"symbol\":\"KMD\"}" +echo "3097.05949360 <- expected amount RK5z4QVhNBWJn5xSkpPPgdcZzms7VtFV4x" + +# RTSFrcYBPZ3wMUtJCo5RC8n71R2c1ypC46 KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTSFrcYBPZ3wMUtJCo5RC8n71R2c1ypC46\",\"symbol\":\"KMD\"}" +echo "968.31524937 <- expected amount RTSFrcYBPZ3wMUtJCo5RC8n71R2c1ypC46" + +# RSxDyaWzqT3VTK9WLkAKhY5WST8a9kQgr9 KMD 14268.23083290 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSxDyaWzqT3VTK9WLkAKhY5WST8a9kQgr9\",\"symbol\":\"KMD\"}" +echo "14268.23083290 <- expected amount RSxDyaWzqT3VTK9WLkAKhY5WST8a9kQgr9" + +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 1212.14061568, REVS 24.05385000 +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 1212.14061568 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf\",\"symbol\":\"KMD\"}" +echo "1212.14061568 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf" + +# RVUFVtJN2mVDEsADwMfZBBXXSq3G9QCvBs KMD 20418.65848567 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVUFVtJN2mVDEsADwMfZBBXXSq3G9QCvBs\",\"symbol\":\"KMD\"}" +echo "20418.65848567 <- expected amount RVUFVtJN2mVDEsADwMfZBBXXSq3G9QCvBs" + +# RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza KMD 10347.76210933, REVS 205.22959870 +# RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza KMD 10347.76210933 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza\",\"symbol\":\"KMD\"}" +echo "10347.76210933 <- expected amount RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza" + +# RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr KMD 71712.83911390, REVS 500.67180183 +# RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr KMD 71712.83911390 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr\",\"symbol\":\"KMD\"}" +echo "71712.83911390 <- expected amount RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr" + +# RNszK1KnyyDoU6di3qQgCYvSL3V3ZgGNGY KMD 26725.50088275 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNszK1KnyyDoU6di3qQgCYvSL3V3ZgGNGY\",\"symbol\":\"KMD\"}" +echo "26725.50088275 <- expected amount RNszK1KnyyDoU6di3qQgCYvSL3V3ZgGNGY" + +# RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr KMD 16435.34703311, REVS 114.80740001 +# RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr KMD 16435.34703311 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr\",\"symbol\":\"KMD\"}" +echo "16435.34703311 <- expected amount RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr" + +# RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr KMD 17137.93285029, REVS 340.00462653 +# RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr KMD 17137.93285029 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr\",\"symbol\":\"KMD\"}" +echo "17137.93285029 <- expected amount RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr" + +# RMKk4K7zC6QrESUxNGRTfqbBnXr2MFYsLV KMD 1302.29267891 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMKk4K7zC6QrESUxNGRTfqbBnXr2MFYsLV\",\"symbol\":\"KMD\"}" +echo "1302.29267891 <- expected amount RMKk4K7zC6QrESUxNGRTfqbBnXr2MFYsLV" + +# RJaaPBFPBTtqzPZ5ZV2uu15urxhiycwg7K KMD 32805.26183900 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJaaPBFPBTtqzPZ5ZV2uu15urxhiycwg7K\",\"symbol\":\"KMD\"}" +echo "32805.26183900 <- expected amount RJaaPBFPBTtqzPZ5ZV2uu15urxhiycwg7K" + +# R9isnAJ2iyyFq8BMZZJu8PiFLpnXPhXcZ7 KMD 502854.27827071 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9isnAJ2iyyFq8BMZZJu8PiFLpnXPhXcZ7\",\"symbol\":\"KMD\"}" +echo "502854.27827071 <- expected amount R9isnAJ2iyyFq8BMZZJu8PiFLpnXPhXcZ7" + +# RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF KMD 409543.68954327, REVS 8123.68911362 +# RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF KMD 409543.68954327 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF\",\"symbol\":\"KMD\"}" +echo "409543.68954327 <- expected amount RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF" + +# RQWxU8AV5SkKCmz6Q3CecmAtnauESPxDod KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQWxU8AV5SkKCmz6Q3CecmAtnauESPxDod\",\"symbol\":\"KMD\"}" +echo "8908.50029425 <- expected amount RQWxU8AV5SkKCmz6Q3CecmAtnauESPxDod" + +# RMqivy9QZ7ax1UU8ZxqaupLqDqEBAFW6MY KMD 708.48776076 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMqivy9QZ7ax1UU8ZxqaupLqDqEBAFW6MY\",\"symbol\":\"KMD\"}" +echo "708.48776076 <- expected amount RMqivy9QZ7ax1UU8ZxqaupLqDqEBAFW6MY" + +# RV85Dvvf4fm13xxtjmucYXDAarMcnV8EFq KMD 29057.20400324 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RV85Dvvf4fm13xxtjmucYXDAarMcnV8EFq\",\"symbol\":\"KMD\"}" +echo "29057.20400324 <- expected amount RV85Dvvf4fm13xxtjmucYXDAarMcnV8EFq" + +# RJzRaaqhT8R7pbVuVeY3C69X9K89UMU55E KMD 632.08133544 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJzRaaqhT8R7pbVuVeY3C69X9K89UMU55E\",\"symbol\":\"KMD\"}" +echo "632.08133544 <- expected amount RJzRaaqhT8R7pbVuVeY3C69X9K89UMU55E" + +# RCBSjuktzRbsz1UHKjFmTUVG6nDNhd3y2g KMD 24029.98198519 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCBSjuktzRbsz1UHKjFmTUVG6nDNhd3y2g\",\"symbol\":\"KMD\"}" +echo "24029.98198519 <- expected amount RCBSjuktzRbsz1UHKjFmTUVG6nDNhd3y2g" + +# RKDnex4tqTGA9u2UqEDGS8uTxceqWGwejk KMD 10684.09534584 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKDnex4tqTGA9u2UqEDGS8uTxceqWGwejk\",\"symbol\":\"KMD\"}" +echo "10684.09534584 <- expected amount RKDnex4tqTGA9u2UqEDGS8uTxceqWGwejk" + +# RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d KMD 302.06577591, REVS 5.99094155 +# RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d KMD 302.06577591 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d\",\"symbol\":\"KMD\"}" +echo "302.06577591 <- expected amount RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d" + +# REhPMC2k5XAsiqd3X1afzdT6SzE9vY7MS6 KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REhPMC2k5XAsiqd3X1afzdT6SzE9vY7MS6\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount REhPMC2k5XAsiqd3X1afzdT6SzE9vY7MS6" + +# RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL KMD 30407.13753317, REVS 411.30538288 +# RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL KMD 30407.13753317 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL\",\"symbol\":\"KMD\"}" +echo "30407.13753317 <- expected amount RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL" + +# RKa3UX7xvQuYhd9LWHFGjQm8EjbLcnLxo1 KMD 4647.91319700 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKa3UX7xvQuYhd9LWHFGjQm8EjbLcnLxo1\",\"symbol\":\"KMD\"}" +echo "4647.91319700 <- expected amount RKa3UX7xvQuYhd9LWHFGjQm8EjbLcnLxo1" + +# RRBhAPHb7WY2XrLSST2oymc4LYtCskzijc KMD 1914.39627638 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRBhAPHb7WY2XrLSST2oymc4LYtCskzijc\",\"symbol\":\"KMD\"}" +echo "1914.39627638 <- expected amount RRBhAPHb7WY2XrLSST2oymc4LYtCskzijc" + +# RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6 KMD 56568.34116197 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6\",\"symbol\":\"KMD\"}" +echo "56568.34116197 <- expected amount RQFicXTYo7QzKhFbo3ELuBfo3eyYiUv6o6" + +# RNkRuGR4uFrcMqrPMu8X5Nwvgbc3Jxxkqk KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNkRuGR4uFrcMqrPMu8X5Nwvgbc3Jxxkqk\",\"symbol\":\"KMD\"}" +echo "96831.52493750 <- expected amount RNkRuGR4uFrcMqrPMu8X5Nwvgbc3Jxxkqk" + diff --git a/iguana/tests/KMD.batch3.importaddress b/iguana/tests/KMD.batch3.importaddress new file mode 100755 index 000000000..91ebce0c1 --- /dev/null +++ b/iguana/tests/KMD.batch3.importaddress @@ -0,0 +1,245 @@ +# RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg KMD 5669.98491054, REVS 112.56208000 +# RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg KMD 5669.98491054 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg\",\"symbol\":\"KMD\"}" # 5669.98491054 +sleep 3 +echo "5669.98491054 <- expected amount RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg" + +# RXbWQbnpsQ3iSBBj5bn2HDq3WvqRPJg5Ek KMD 8353.36815152 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXbWQbnpsQ3iSBBj5bn2HDq3WvqRPJg5Ek\",\"symbol\":\"KMD\"}" # 8353.36815152 +sleep 3 +echo "8353.36815152 <- expected amount RXbWQbnpsQ3iSBBj5bn2HDq3WvqRPJg5Ek" + +# RKCDBxUx7mbCnViLt423jdLt6oNpW7SH7z KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKCDBxUx7mbCnViLt423jdLt6oNpW7SH7z\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RKCDBxUx7mbCnViLt423jdLt6oNpW7SH7z" + +# RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W KMD 43088.74729573, REVS 470.87980000 +# RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W KMD 43088.74729573 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W\",\"symbol\":\"KMD\"}" # 43088.74729573 +sleep 3 +echo "43088.74729573 <- expected amount RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 50806.03038250 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct\",\"symbol\":\"KMD\"}" # 50806.03038250 +sleep 3 +echo "50806.03038250 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RDqaDbfFHrnPAnyLY6b9A3CFZZjivhdYSJ KMD 2015.79933830 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDqaDbfFHrnPAnyLY6b9A3CFZZjivhdYSJ\",\"symbol\":\"KMD\"}" # 2015.79933830 +sleep 3 +echo "2015.79933830 <- expected amount RDqaDbfFHrnPAnyLY6b9A3CFZZjivhdYSJ" + +# RBGX2Z43Fiey6tkgRCL9rzc3gNhdcvQyzf KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBGX2Z43Fiey6tkgRCL9rzc3gNhdcvQyzf\",\"symbol\":\"KMD\"}" # 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RBGX2Z43Fiey6tkgRCL9rzc3gNhdcvQyzf" + +# RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ KMD 7885.04483652 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ\",\"symbol\":\"KMD\"}" # 7885.04483652 +sleep 3 +echo "7885.04483652 <- expected amount RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ" + +# RVUby7nAZAEKQc1mNu89KGchwgVN6H74Pb KMD 2076.57141858 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVUby7nAZAEKQc1mNu89KGchwgVN6H74Pb\",\"symbol\":\"KMD\"}" # 2076.57141858 +sleep 3 +echo "2076.57141858 <- expected amount RVUby7nAZAEKQc1mNu89KGchwgVN6H74Pb" + +# RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW KMD 55892.82951156, REVS 1070.41924580 +# RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW KMD 55892.82951156 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW\",\"symbol\":\"KMD\"}" # 55892.82951156 +sleep 3 +echo "55892.82951156 <- expected amount RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW" + +# RPAueErz2MDLv1T4VNVRkkWRPmUKDXxNyW KMD 110983.78643539 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPAueErz2MDLv1T4VNVRkkWRPmUKDXxNyW\",\"symbol\":\"KMD\"}" # 110983.78643539 +sleep 3 +echo "110983.78643539 <- expected amount RPAueErz2MDLv1T4VNVRkkWRPmUKDXxNyW" + +# RQ2pMNHbPGagXKQoVzrgF2o718GmP7A74Z KMD 135104.07865436 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ2pMNHbPGagXKQoVzrgF2o718GmP7A74Z\",\"symbol\":\"KMD\"}" # 135104.07865436 +sleep 3 +echo "135104.07865436 <- expected amount RQ2pMNHbPGagXKQoVzrgF2o718GmP7A74Z" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 8376.94442691 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" # 8376.94442691 +sleep 3 +echo "8376.94442691 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RHSA9ocZc77tHiFvVQ2h26AJQFsionWAXK KMD 47849.00411034 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHSA9ocZc77tHiFvVQ2h26AJQFsionWAXK\",\"symbol\":\"KMD\"}" # 47849.00411034 +sleep 3 +echo "47849.00411034 <- expected amount RHSA9ocZc77tHiFvVQ2h26AJQFsionWAXK" + +# RS8F3LcQ8DUSoBacUKBKzMR2Wxe3hCSToY KMD 15163.82967582 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS8F3LcQ8DUSoBacUKBKzMR2Wxe3hCSToY\",\"symbol\":\"KMD\"}" # 15163.82967582 +sleep 3 +echo "15163.82967582 <- expected amount RS8F3LcQ8DUSoBacUKBKzMR2Wxe3hCSToY" + +# RLijku3v2wyCcGykdbsUViqDCNaVkVkQpc KMD 3002.22564175 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLijku3v2wyCcGykdbsUViqDCNaVkVkQpc\",\"symbol\":\"KMD\"}" # 3002.22564175 +sleep 3 +echo "3002.22564175 <- expected amount RLijku3v2wyCcGykdbsUViqDCNaVkVkQpc" + +# RMeaeKG7vrTpryBGVEWQ8twjQDnRVAhpqH KMD 14101.70011189 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMeaeKG7vrTpryBGVEWQ8twjQDnRVAhpqH\",\"symbol\":\"KMD\"}" # 14101.70011189 +sleep 3 +echo "14101.70011189 <- expected amount RMeaeKG7vrTpryBGVEWQ8twjQDnRVAhpqH" + +# RUDEQESpyWvpwdfrieiBoNo93WHaKhGxGf KMD 5832.55634776 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUDEQESpyWvpwdfrieiBoNo93WHaKhGxGf\",\"symbol\":\"KMD\"}" # 5832.55634776 +sleep 3 +echo "5832.55634776 <- expected amount RUDEQESpyWvpwdfrieiBoNo93WHaKhGxGf" + +# RMat1mSDDigFHhVL74mjBia9uHo5w24MLQ KMD 890.85002942 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMat1mSDDigFHhVL74mjBia9uHo5w24MLQ\",\"symbol\":\"KMD\"}" # 890.85002942 +sleep 3 +echo "890.85002942 <- expected amount RMat1mSDDigFHhVL74mjBia9uHo5w24MLQ" + +# RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK KMD 335.54240549, REVS 6.65853993 +# RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK KMD 335.54240549 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK\",\"symbol\":\"KMD\"}" # 335.54240549 +sleep 3 +echo "335.54240549 <- expected amount RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK" + +# RVcMp4KgwCg6GnUJAAU2dmCvPjAa9JrEds KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVcMp4KgwCg6GnUJAAU2dmCvPjAa9JrEds\",\"symbol\":\"KMD\"}" # 19366.30498750 +sleep 3 +echo "19366.30498750 <- expected amount RVcMp4KgwCg6GnUJAAU2dmCvPjAa9JrEds" + +# RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh KMD 163589.49612623, REVS 3245.93000000 +# RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh KMD 163589.49612623 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh\",\"symbol\":\"KMD\"}" # 163589.49612623 +sleep 3 +echo "163589.49612623 <- expected amount RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh" + +# RB1j3QidCF9PTKQaZMGKe6Hzm5jdY8Mzus KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB1j3QidCF9PTKQaZMGKe6Hzm5jdY8Mzus\",\"symbol\":\"KMD\"}" # 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RB1j3QidCF9PTKQaZMGKe6Hzm5jdY8Mzus" + +# RFcH8p3Ke5y4UL3pdL9KCkJWp3aRdBwWpg KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFcH8p3Ke5y4UL3pdL9KCkJWp3aRdBwWpg\",\"symbol\":\"KMD\"}" # 7746.52199500 +sleep 3 +echo "7746.52199500 <- expected amount RFcH8p3Ke5y4UL3pdL9KCkJWp3aRdBwWpg" + +# RJDkJJd66n4Q4jVWbZJQKyXTf29ZqzeXac KMD 16670.51967129 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJDkJJd66n4Q4jVWbZJQKyXTf29ZqzeXac\",\"symbol\":\"KMD\"}" # 16670.51967129 +sleep 3 +echo "16670.51967129 <- expected amount RJDkJJd66n4Q4jVWbZJQKyXTf29ZqzeXac" + +# RKzELkcNJu4g9DWQsFFeQtFZQE5u9vevuK KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKzELkcNJu4g9DWQsFFeQtFZQE5u9vevuK\",\"symbol\":\"KMD\"}" # 7746.52199500 +sleep 3 +echo "7746.52199500 <- expected amount RKzELkcNJu4g9DWQsFFeQtFZQE5u9vevuK" + +# RKpUFnxUn9mJCZmNECEQT7xEubHECUPCem KMD 74455.81274009 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKpUFnxUn9mJCZmNECEQT7xEubHECUPCem\",\"symbol\":\"KMD\"}" # 74455.81274009 +sleep 3 +echo "74455.81274009 <- expected amount RKpUFnxUn9mJCZmNECEQT7xEubHECUPCem" + +# RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc KMD 98858.55994787, REVS 1384.95819177 +# RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc KMD 98858.55994787 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc\",\"symbol\":\"KMD\"}" # 98858.55994787 +sleep 3 +echo "98858.55994787 <- expected amount RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc" + +# RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9 KMD 5226.14889591, REVS 103.72248253 +# RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9 KMD 5226.14889591 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9\",\"symbol\":\"KMD\"}" # 5226.14889591 +sleep 3 +echo "5226.14889591 <- expected amount RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9" + +# RBtfFBdYiryB6fyWoubm4XNqZwXqzAbJEK KMD 753.34926401 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBtfFBdYiryB6fyWoubm4XNqZwXqzAbJEK\",\"symbol\":\"KMD\"}" # 753.34926401 +sleep 3 +echo "753.34926401 <- expected amount RBtfFBdYiryB6fyWoubm4XNqZwXqzAbJEK" + +# RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK KMD 159251.95713851, REVS 3160.13095281 +# RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK KMD 159251.95713851 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK\",\"symbol\":\"KMD\"}" # 159251.95713851 +sleep 3 +echo "159251.95713851 <- expected amount RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK" + +# RAaszCNodXXu9rJL6qqVMZDykXncDecTMS KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS" + +# RT1xC82iwXtZeDLLYz3tgQRCHKsRD62Jt5 KMD 2304.59029350 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT1xC82iwXtZeDLLYz3tgQRCHKsRD62Jt5\",\"symbol\":\"KMD\"}" # 2304.59029350 +sleep 3 +echo "2304.59029350 <- expected amount RT1xC82iwXtZeDLLYz3tgQRCHKsRD62Jt5" + +# RGPEHHmPFaMPSLMQxEao2uVPTfN8vBCmym KMD 6506.14889316 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGPEHHmPFaMPSLMQxEao2uVPTfN8vBCmym\",\"symbol\":\"KMD\"}" # 6506.14889316 +sleep 3 +echo "6506.14889316 <- expected amount RGPEHHmPFaMPSLMQxEao2uVPTfN8vBCmym" + +# RBUEoAzoydjckYewPsW2kfTr8TGFgnR2Ec KMD 38732.60997500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBUEoAzoydjckYewPsW2kfTr8TGFgnR2Ec\",\"symbol\":\"KMD\"}" # 38732.60997500 +sleep 3 +echo "38732.60997500 <- expected amount RBUEoAzoydjckYewPsW2kfTr8TGFgnR2Ec" + +# RVQS9NGKsbBJuKDhJnPssTRevrE428dxDK KMD 916.79536397 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVQS9NGKsbBJuKDhJnPssTRevrE428dxDK\",\"symbol\":\"KMD\"}" # 916.79536397 +sleep 3 +echo "916.79536397 <- expected amount RVQS9NGKsbBJuKDhJnPssTRevrE428dxDK" + +# RHiUqYUohv49bvB2wbDe1mAkwyEFwUEnrb KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHiUqYUohv49bvB2wbDe1mAkwyEFwUEnrb\",\"symbol\":\"KMD\"}" # 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RHiUqYUohv49bvB2wbDe1mAkwyEFwUEnrb" + +# RSWPtfGaHPL1g7SMqbLm1YZ8o3QM6krzo1 KMD 16542.25810519 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSWPtfGaHPL1g7SMqbLm1YZ8o3QM6krzo1\",\"symbol\":\"KMD\"}" # 16542.25810519 +sleep 3 +echo "16542.25810519 <- expected amount RSWPtfGaHPL1g7SMqbLm1YZ8o3QM6krzo1" + +# RFMcTK36Wzjo5QEk1wAH2CbATqsYvzgwXH KMD 2322923.09575692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFMcTK36Wzjo5QEk1wAH2CbATqsYvzgwXH\",\"symbol\":\"KMD\"}" # 2322923.09575692 +sleep 3 +echo "2322923.09575692 <- expected amount RFMcTK36Wzjo5QEk1wAH2CbATqsYvzgwXH" + +# RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq KMD 28529.48507541, REVS 566.06461415 +# RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq KMD 28529.48507541 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq\",\"symbol\":\"KMD\"}" # 28529.48507541 +sleep 3 +echo "28529.48507541 <- expected amount RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq" + +# RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72 KMD 8637.01756743, REVS 171.30000000 +# RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72 KMD 8637.01756743 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72\",\"symbol\":\"KMD\"}" # 8637.01756743 +sleep 3 +echo "8637.01756743 <- expected amount RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72" + +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 1212.26932063 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf\",\"symbol\":\"KMD\"}" # 1212.26932063 +sleep 3 +echo "1212.26932063 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf" + +# RBD72Bh4wxGi8q8xQbLfwMF2RAkTZ7sVZT KMD 32148.06627925 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBD72Bh4wxGi8q8xQbLfwMF2RAkTZ7sVZT\",\"symbol\":\"KMD\"}" # 32148.06627925 +sleep 3 +echo "32148.06627925 <- expected amount RBD72Bh4wxGi8q8xQbLfwMF2RAkTZ7sVZT" + +# RVih8N9Qh1jf4CCF5ySsAY8DR42eTxYqpB KMD 1924.55258644 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVih8N9Qh1jf4CCF5ySsAY8DR42eTxYqpB\",\"symbol\":\"KMD\"}" # 1924.55258644 +sleep 3 +echo "1924.55258644 <- expected amount RVih8N9Qh1jf4CCF5ySsAY8DR42eTxYqpB" + +# RWez2L8rPoTmqj8kYKqxLdeD9BFuDibMyJ KMD 44542.50147125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWez2L8rPoTmqj8kYKqxLdeD9BFuDibMyJ\",\"symbol\":\"KMD\"}" # 44542.50147125 +sleep 3 +echo "44542.50147125 <- expected amount RWez2L8rPoTmqj8kYKqxLdeD9BFuDibMyJ" + +# RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN KMD 49199.88128813 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN\",\"symbol\":\"KMD\"}" # 49199.88128813 +sleep 3 +echo "49199.88128813 <- expected amount RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN" + +# RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es KMD 30170.24616125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es\",\"symbol\":\"KMD\"}" # 30170.24616125 +sleep 3 +echo "30170.24616125 <- expected amount RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es" + diff --git a/iguana/tests/KMD.batch3.listunspent b/iguana/tests/KMD.batch3.listunspent new file mode 100755 index 000000000..9dd262419 --- /dev/null +++ b/iguana/tests/KMD.batch3.listunspent @@ -0,0 +1,198 @@ +# RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg KMD 5669.98491054, REVS 112.56208000 +# RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg KMD 5669.98491054 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg\",\"symbol\":\"KMD\"}" +echo "5669.98491054 <- expected amount RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg" + +# RXbWQbnpsQ3iSBBj5bn2HDq3WvqRPJg5Ek KMD 8353.36815152 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXbWQbnpsQ3iSBBj5bn2HDq3WvqRPJg5Ek\",\"symbol\":\"KMD\"}" +echo "8353.36815152 <- expected amount RXbWQbnpsQ3iSBBj5bn2HDq3WvqRPJg5Ek" + +# RKCDBxUx7mbCnViLt423jdLt6oNpW7SH7z KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKCDBxUx7mbCnViLt423jdLt6oNpW7SH7z\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RKCDBxUx7mbCnViLt423jdLt6oNpW7SH7z" + +# RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W KMD 43088.74729573, REVS 470.87980000 +# RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W KMD 43088.74729573 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W\",\"symbol\":\"KMD\"}" +echo "43088.74729573 <- expected amount RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 50806.03038250 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct\",\"symbol\":\"KMD\"}" +echo "50806.03038250 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RDqaDbfFHrnPAnyLY6b9A3CFZZjivhdYSJ KMD 2015.79933830 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDqaDbfFHrnPAnyLY6b9A3CFZZjivhdYSJ\",\"symbol\":\"KMD\"}" +echo "2015.79933830 <- expected amount RDqaDbfFHrnPAnyLY6b9A3CFZZjivhdYSJ" + +# RBGX2Z43Fiey6tkgRCL9rzc3gNhdcvQyzf KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBGX2Z43Fiey6tkgRCL9rzc3gNhdcvQyzf\",\"symbol\":\"KMD\"}" +echo "48415.76246875 <- expected amount RBGX2Z43Fiey6tkgRCL9rzc3gNhdcvQyzf" + +# RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ KMD 7885.04483652 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ\",\"symbol\":\"KMD\"}" +echo "7885.04483652 <- expected amount RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ" + +# RVUby7nAZAEKQc1mNu89KGchwgVN6H74Pb KMD 2076.57141858 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVUby7nAZAEKQc1mNu89KGchwgVN6H74Pb\",\"symbol\":\"KMD\"}" +echo "2076.57141858 <- expected amount RVUby7nAZAEKQc1mNu89KGchwgVN6H74Pb" + +# RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW KMD 55892.82951156, REVS 1070.41924580 +# RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW KMD 55892.82951156 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW\",\"symbol\":\"KMD\"}" +echo "55892.82951156 <- expected amount RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW" + +# RPAueErz2MDLv1T4VNVRkkWRPmUKDXxNyW KMD 110983.78643539 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPAueErz2MDLv1T4VNVRkkWRPmUKDXxNyW\",\"symbol\":\"KMD\"}" +echo "110983.78643539 <- expected amount RPAueErz2MDLv1T4VNVRkkWRPmUKDXxNyW" + +# RQ2pMNHbPGagXKQoVzrgF2o718GmP7A74Z KMD 135104.07865436 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQ2pMNHbPGagXKQoVzrgF2o718GmP7A74Z\",\"symbol\":\"KMD\"}" +echo "135104.07865436 <- expected amount RQ2pMNHbPGagXKQoVzrgF2o718GmP7A74Z" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 8376.94442691 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" +echo "8376.94442691 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RHSA9ocZc77tHiFvVQ2h26AJQFsionWAXK KMD 47849.00411034 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHSA9ocZc77tHiFvVQ2h26AJQFsionWAXK\",\"symbol\":\"KMD\"}" +echo "47849.00411034 <- expected amount RHSA9ocZc77tHiFvVQ2h26AJQFsionWAXK" + +# RS8F3LcQ8DUSoBacUKBKzMR2Wxe3hCSToY KMD 15163.82967582 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RS8F3LcQ8DUSoBacUKBKzMR2Wxe3hCSToY\",\"symbol\":\"KMD\"}" +echo "15163.82967582 <- expected amount RS8F3LcQ8DUSoBacUKBKzMR2Wxe3hCSToY" + +# RLijku3v2wyCcGykdbsUViqDCNaVkVkQpc KMD 3002.22564175 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLijku3v2wyCcGykdbsUViqDCNaVkVkQpc\",\"symbol\":\"KMD\"}" +echo "3002.22564175 <- expected amount RLijku3v2wyCcGykdbsUViqDCNaVkVkQpc" + +# RMeaeKG7vrTpryBGVEWQ8twjQDnRVAhpqH KMD 14101.70011189 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMeaeKG7vrTpryBGVEWQ8twjQDnRVAhpqH\",\"symbol\":\"KMD\"}" +echo "14101.70011189 <- expected amount RMeaeKG7vrTpryBGVEWQ8twjQDnRVAhpqH" + +# RUDEQESpyWvpwdfrieiBoNo93WHaKhGxGf KMD 5832.55634776 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUDEQESpyWvpwdfrieiBoNo93WHaKhGxGf\",\"symbol\":\"KMD\"}" +echo "5832.55634776 <- expected amount RUDEQESpyWvpwdfrieiBoNo93WHaKhGxGf" + +# RMat1mSDDigFHhVL74mjBia9uHo5w24MLQ KMD 890.85002942 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMat1mSDDigFHhVL74mjBia9uHo5w24MLQ\",\"symbol\":\"KMD\"}" +echo "890.85002942 <- expected amount RMat1mSDDigFHhVL74mjBia9uHo5w24MLQ" + +# RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK KMD 335.54240549, REVS 6.65853993 +# RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK KMD 335.54240549 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK\",\"symbol\":\"KMD\"}" +echo "335.54240549 <- expected amount RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK" + +# RVcMp4KgwCg6GnUJAAU2dmCvPjAa9JrEds KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVcMp4KgwCg6GnUJAAU2dmCvPjAa9JrEds\",\"symbol\":\"KMD\"}" +echo "19366.30498750 <- expected amount RVcMp4KgwCg6GnUJAAU2dmCvPjAa9JrEds" + +# RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh KMD 163589.49612623, REVS 3245.93000000 +# RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh KMD 163589.49612623 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh\",\"symbol\":\"KMD\"}" +echo "163589.49612623 <- expected amount RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh" + +# RB1j3QidCF9PTKQaZMGKe6Hzm5jdY8Mzus KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RB1j3QidCF9PTKQaZMGKe6Hzm5jdY8Mzus\",\"symbol\":\"KMD\"}" +echo "3873.26099750 <- expected amount RB1j3QidCF9PTKQaZMGKe6Hzm5jdY8Mzus" + +# RFcH8p3Ke5y4UL3pdL9KCkJWp3aRdBwWpg KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFcH8p3Ke5y4UL3pdL9KCkJWp3aRdBwWpg\",\"symbol\":\"KMD\"}" +echo "7746.52199500 <- expected amount RFcH8p3Ke5y4UL3pdL9KCkJWp3aRdBwWpg" + +# RJDkJJd66n4Q4jVWbZJQKyXTf29ZqzeXac KMD 16670.51967129 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJDkJJd66n4Q4jVWbZJQKyXTf29ZqzeXac\",\"symbol\":\"KMD\"}" +echo "16670.51967129 <- expected amount RJDkJJd66n4Q4jVWbZJQKyXTf29ZqzeXac" + +# RKzELkcNJu4g9DWQsFFeQtFZQE5u9vevuK KMD 7746.52199500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKzELkcNJu4g9DWQsFFeQtFZQE5u9vevuK\",\"symbol\":\"KMD\"}" +echo "7746.52199500 <- expected amount RKzELkcNJu4g9DWQsFFeQtFZQE5u9vevuK" + +# RKpUFnxUn9mJCZmNECEQT7xEubHECUPCem KMD 74455.81274009 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKpUFnxUn9mJCZmNECEQT7xEubHECUPCem\",\"symbol\":\"KMD\"}" +echo "74455.81274009 <- expected amount RKpUFnxUn9mJCZmNECEQT7xEubHECUPCem" + +# RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc KMD 98858.55994787, REVS 1384.95819177 +# RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc KMD 98858.55994787 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc\",\"symbol\":\"KMD\"}" +echo "98858.55994787 <- expected amount RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc" + +# RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9 KMD 5226.14889591, REVS 103.72248253 +# RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9 KMD 5226.14889591 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9\",\"symbol\":\"KMD\"}" +echo "5226.14889591 <- expected amount RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9" + +# RBtfFBdYiryB6fyWoubm4XNqZwXqzAbJEK KMD 753.34926401 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBtfFBdYiryB6fyWoubm4XNqZwXqzAbJEK\",\"symbol\":\"KMD\"}" +echo "753.34926401 <- expected amount RBtfFBdYiryB6fyWoubm4XNqZwXqzAbJEK" + +# RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK KMD 159251.95713851, REVS 3160.13095281 +# RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK KMD 159251.95713851 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK\",\"symbol\":\"KMD\"}" +echo "159251.95713851 <- expected amount RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK" + +# RAaszCNodXXu9rJL6qqVMZDykXncDecTMS KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS" + +# RT1xC82iwXtZeDLLYz3tgQRCHKsRD62Jt5 KMD 2304.59029350 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RT1xC82iwXtZeDLLYz3tgQRCHKsRD62Jt5\",\"symbol\":\"KMD\"}" +echo "2304.59029350 <- expected amount RT1xC82iwXtZeDLLYz3tgQRCHKsRD62Jt5" + +# RGPEHHmPFaMPSLMQxEao2uVPTfN8vBCmym KMD 6506.14889316 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGPEHHmPFaMPSLMQxEao2uVPTfN8vBCmym\",\"symbol\":\"KMD\"}" +echo "6506.14889316 <- expected amount RGPEHHmPFaMPSLMQxEao2uVPTfN8vBCmym" + +# RBUEoAzoydjckYewPsW2kfTr8TGFgnR2Ec KMD 38732.60997500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBUEoAzoydjckYewPsW2kfTr8TGFgnR2Ec\",\"symbol\":\"KMD\"}" +echo "38732.60997500 <- expected amount RBUEoAzoydjckYewPsW2kfTr8TGFgnR2Ec" + +# RVQS9NGKsbBJuKDhJnPssTRevrE428dxDK KMD 916.79536397 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVQS9NGKsbBJuKDhJnPssTRevrE428dxDK\",\"symbol\":\"KMD\"}" +echo "916.79536397 <- expected amount RVQS9NGKsbBJuKDhJnPssTRevrE428dxDK" + +# RHiUqYUohv49bvB2wbDe1mAkwyEFwUEnrb KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHiUqYUohv49bvB2wbDe1mAkwyEFwUEnrb\",\"symbol\":\"KMD\"}" +echo "48415.76246875 <- expected amount RHiUqYUohv49bvB2wbDe1mAkwyEFwUEnrb" + +# RSWPtfGaHPL1g7SMqbLm1YZ8o3QM6krzo1 KMD 16542.25810519 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSWPtfGaHPL1g7SMqbLm1YZ8o3QM6krzo1\",\"symbol\":\"KMD\"}" +echo "16542.25810519 <- expected amount RSWPtfGaHPL1g7SMqbLm1YZ8o3QM6krzo1" + +# RFMcTK36Wzjo5QEk1wAH2CbATqsYvzgwXH KMD 2322923.09575692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFMcTK36Wzjo5QEk1wAH2CbATqsYvzgwXH\",\"symbol\":\"KMD\"}" +echo "2322923.09575692 <- expected amount RFMcTK36Wzjo5QEk1wAH2CbATqsYvzgwXH" + +# RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq KMD 28529.48507541, REVS 566.06461415 +# RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq KMD 28529.48507541 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq\",\"symbol\":\"KMD\"}" +echo "28529.48507541 <- expected amount RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq" + +# RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72 KMD 8637.01756743, REVS 171.30000000 +# RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72 KMD 8637.01756743 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72\",\"symbol\":\"KMD\"}" +echo "8637.01756743 <- expected amount RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72" + +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 1212.26932063 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf\",\"symbol\":\"KMD\"}" +echo "1212.26932063 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf" + +# RBD72Bh4wxGi8q8xQbLfwMF2RAkTZ7sVZT KMD 32148.06627925 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBD72Bh4wxGi8q8xQbLfwMF2RAkTZ7sVZT\",\"symbol\":\"KMD\"}" +echo "32148.06627925 <- expected amount RBD72Bh4wxGi8q8xQbLfwMF2RAkTZ7sVZT" + +# RVih8N9Qh1jf4CCF5ySsAY8DR42eTxYqpB KMD 1924.55258644 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVih8N9Qh1jf4CCF5ySsAY8DR42eTxYqpB\",\"symbol\":\"KMD\"}" +echo "1924.55258644 <- expected amount RVih8N9Qh1jf4CCF5ySsAY8DR42eTxYqpB" + +# RWez2L8rPoTmqj8kYKqxLdeD9BFuDibMyJ KMD 44542.50147125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWez2L8rPoTmqj8kYKqxLdeD9BFuDibMyJ\",\"symbol\":\"KMD\"}" +echo "44542.50147125 <- expected amount RWez2L8rPoTmqj8kYKqxLdeD9BFuDibMyJ" + +# RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN KMD 49199.88128813 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN\",\"symbol\":\"KMD\"}" +echo "49199.88128813 <- expected amount RUuWvTwNAMGLpuY3GLPBAmMp8ptShkMSyN" + +# RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es KMD 30170.24616125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es\",\"symbol\":\"KMD\"}" +echo "30170.24616125 <- expected amount RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es" + diff --git a/iguana/tests/KMD.batch4.importaddress b/iguana/tests/KMD.batch4.importaddress new file mode 100755 index 000000000..4673bb396 --- /dev/null +++ b/iguana/tests/KMD.batch4.importaddress @@ -0,0 +1,248 @@ +# RKmeJpSRwBouZgkTXA1mre8EMNjQ7CawzH KMD 1999.45556678 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKmeJpSRwBouZgkTXA1mre8EMNjQ7CawzH\",\"symbol\":\"KMD\"}" # 1999.45556678 +sleep 3 +echo "1999.45556678 <- expected amount RKmeJpSRwBouZgkTXA1mre8EMNjQ7CawzH" + +# RChSVFn3Bi8kW2vRkohcaGw2QEzapdyjA7 KMD 15493.04399000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RChSVFn3Bi8kW2vRkohcaGw2QEzapdyjA7\",\"symbol\":\"KMD\"}" # 15493.04399000 +sleep 3 +echo "15493.04399000 <- expected amount RChSVFn3Bi8kW2vRkohcaGw2QEzapdyjA7" + +# RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB KMD 843.49707566, REVS 16.72927581 +# RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB KMD 843.49707566 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB\",\"symbol\":\"KMD\"}" # 843.49707566 +sleep 3 +echo "843.49707566 <- expected amount RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB" + +# RLiYLy1TMui1iVGMhfks6Go1y1mopSkc7T KMD 9678.31091750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLiYLy1TMui1iVGMhfks6Go1y1mopSkc7T\",\"symbol\":\"KMD\"}" # 9678.31091750 +sleep 3 +echo "9678.31091750 <- expected amount RLiYLy1TMui1iVGMhfks6Go1y1mopSkc7T" + +# RRLtUwtSG5oQUL6TPk5gtWPSFa4j1eBDxQ KMD 1219.26382940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRLtUwtSG5oQUL6TPk5gtWPSFa4j1eBDxQ\",\"symbol\":\"KMD\"}" # 1219.26382940 +sleep 3 +echo "1219.26382940 <- expected amount RRLtUwtSG5oQUL6TPk5gtWPSFa4j1eBDxQ" + +# RVT4P7mbHcdRmRHBotapx2BsEC1MMcTCMC KMD 1841.49885836 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVT4P7mbHcdRmRHBotapx2BsEC1MMcTCMC\",\"symbol\":\"KMD\"}" # 1841.49885836 +sleep 3 +echo "1841.49885836 <- expected amount RVT4P7mbHcdRmRHBotapx2BsEC1MMcTCMC" + +# RNrQxuKtPSrJg6fcp665Q7j8A7WTDSbwjU KMD 681.69393556 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNrQxuKtPSrJg6fcp665Q7j8A7WTDSbwjU\",\"symbol\":\"KMD\"}" # 681.69393556 +sleep 3 +echo "681.69393556 <- expected amount RNrQxuKtPSrJg6fcp665Q7j8A7WTDSbwjU" + +# RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n KMD 3090.02793673, REVS 3.67077856 +# RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n KMD 3090.02793673 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n\",\"symbol\":\"KMD\"}" # 3090.02793673 +sleep 3 +echo "3090.02793673 <- expected amount RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n" + +# RU2MYeg8uicVE28k6iiBXUxbxzeZwULwKi KMD 759.15915551 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU2MYeg8uicVE28k6iiBXUxbxzeZwULwKi\",\"symbol\":\"KMD\"}" # 759.15915551 +sleep 3 +echo "759.15915551 <- expected amount RU2MYeg8uicVE28k6iiBXUxbxzeZwULwKi" + +# RL5Mi7TdaXCWpQNtbs4zUBdHQEurPuRYh8 KMD 158029.04869800 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL5Mi7TdaXCWpQNtbs4zUBdHQEurPuRYh8\",\"symbol\":\"KMD\"}" # 158029.04869800 +sleep 3 +echo "158029.04869800 <- expected amount RL5Mi7TdaXCWpQNtbs4zUBdHQEurPuRYh8" + +# RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o KMD 2298.00667939 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o\",\"symbol\":\"KMD\"}" # 2298.00667939 +sleep 3 +echo "2298.00667939 <- expected amount RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o" + +# RAYp48ZaMJGmaKCJxeMLzWQXajW7Hd2Yjr KMD 2788.74791820 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAYp48ZaMJGmaKCJxeMLzWQXajW7Hd2Yjr\",\"symbol\":\"KMD\"}" # 2788.74791820 +sleep 3 +echo "2788.74791820 <- expected amount RAYp48ZaMJGmaKCJxeMLzWQXajW7Hd2Yjr" + +# RAryshRkyDqKp3cgavp8CD77yS9A4U5jQz KMD 710.78619077 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAryshRkyDqKp3cgavp8CD77yS9A4U5jQz\",\"symbol\":\"KMD\"}" # 710.78619077 +sleep 3 +echo "710.78619077 <- expected amount RAryshRkyDqKp3cgavp8CD77yS9A4U5jQz" + +# RRbLh1gaRgxRXMRVwGvNw2yESgRyNzscnd KMD 1118.59777607 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRbLh1gaRgxRXMRVwGvNw2yESgRyNzscnd\",\"symbol\":\"KMD\"}" # 1118.59777607 +sleep 3 +echo "1118.59777607 <- expected amount RRbLh1gaRgxRXMRVwGvNw2yESgRyNzscnd" + +# RJtnDNrMY8pzcwwKyUvGLTjDot5jR74FRw KMD 8811.66876930 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJtnDNrMY8pzcwwKyUvGLTjDot5jR74FRw\",\"symbol\":\"KMD\"}" # 8811.66876930 +sleep 3 +echo "8811.66876930 <- expected amount RJtnDNrMY8pzcwwKyUvGLTjDot5jR74FRw" + +# RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk KMD 79613.96546024, REVS 1579.43521640 +# RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk KMD 79613.96546024 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk\",\"symbol\":\"KMD\"}" # 79613.96546024 +sleep 3 +echo "79613.96546024 <- expected amount RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk" + +# RHvVq3gKrEhXkXJSfxEzweGXRBjRMX1HwR KMD 854.63736305 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHvVq3gKrEhXkXJSfxEzweGXRBjRMX1HwR\",\"symbol\":\"KMD\"}" # 854.63736305 +sleep 3 +echo "854.63736305 <- expected amount RHvVq3gKrEhXkXJSfxEzweGXRBjRMX1HwR" + +# RSqXWQNJTdiiP2L6Q8Pd6nzd3DyN7TzpNF KMD 87148.37244375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSqXWQNJTdiiP2L6Q8Pd6nzd3DyN7TzpNF\",\"symbol\":\"KMD\"}" # 87148.37244375 +sleep 3 +echo "87148.37244375 <- expected amount RSqXWQNJTdiiP2L6Q8Pd6nzd3DyN7TzpNF" + +# RRRWieSx6e2ANSukRrFaRSyF2ikYiqTqbH KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRRWieSx6e2ANSukRrFaRSyF2ikYiqTqbH\",\"symbol\":\"KMD\"}" # 96831.52493750 +sleep 3 +echo "96831.52493750 <- expected amount RRRWieSx6e2ANSukRrFaRSyF2ikYiqTqbH" + +# RBhKUj4dmHDDd8Yhm8npoh9ii5V5ZUjtpu KMD 1935.66218350 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBhKUj4dmHDDd8Yhm8npoh9ii5V5ZUjtpu\",\"symbol\":\"KMD\"}" # 1935.66218350 +sleep 3 +echo "1935.66218350 <- expected amount RBhKUj4dmHDDd8Yhm8npoh9ii5V5ZUjtpu" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 50303.39904535 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct\",\"symbol\":\"KMD\"}" # 50303.39904535 +sleep 3 +echo "50303.39904535 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RBopZSXfCKrvi6kELKu9Cn3TYDapxpVr8d KMD 106514.67743125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBopZSXfCKrvi6kELKu9Cn3TYDapxpVr8d\",\"symbol\":\"KMD\"}" # 106514.67743125 +sleep 3 +echo "106514.67743125 <- expected amount RBopZSXfCKrvi6kELKu9Cn3TYDapxpVr8d" + +# RFEHFqHrwcwnTBzvYsuEttQ4rQQZw9qQsH KMD 1526.39979262 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFEHFqHrwcwnTBzvYsuEttQ4rQQZw9qQsH\",\"symbol\":\"KMD\"}" # 1526.39979262 +sleep 3 +echo "1526.39979262 <- expected amount RFEHFqHrwcwnTBzvYsuEttQ4rQQZw9qQsH" + +# RJzu13gJQjtS6aQdNEaQMrv7TSL4wQBien KMD 2130.29354862 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJzu13gJQjtS6aQdNEaQMrv7TSL4wQBien\",\"symbol\":\"KMD\"}" # 2130.29354862 +sleep 3 +echo "2130.29354862 <- expected amount RJzu13gJQjtS6aQdNEaQMrv7TSL4wQBien" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 20106.39865075, REVS 0.09000000 +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 20106.39865075 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" # 20106.39865075 +sleep 3 +echo "20106.39865075 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RBcmNwoFVZ5kWZB8LMjgGbqvVmByD1DeTJ KMD 12526.83053462 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBcmNwoFVZ5kWZB8LMjgGbqvVmByD1DeTJ\",\"symbol\":\"KMD\"}" # 12526.83053462 +sleep 3 +echo "12526.83053462 <- expected amount RBcmNwoFVZ5kWZB8LMjgGbqvVmByD1DeTJ" + +# REwf8D6dyFevVSZc6wjTAwmTgntUM5KWGd KMD 273706.84143501 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REwf8D6dyFevVSZc6wjTAwmTgntUM5KWGd\",\"symbol\":\"KMD\"}" # 273706.84143501 +sleep 3 +echo "273706.84143501 <- expected amount REwf8D6dyFevVSZc6wjTAwmTgntUM5KWGd" + +# RJQNje5EiBV2C7f28YLcm9LEm8AvrSFtVc KMD 3880.03920424 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJQNje5EiBV2C7f28YLcm9LEm8AvrSFtVc\",\"symbol\":\"KMD\"}" # 3880.03920424 +sleep 3 +echo "3880.03920424 <- expected amount RJQNje5EiBV2C7f28YLcm9LEm8AvrSFtVc" + +# RBFuL5swKoyZnLUTVEPjsuwh7pvP5sAz7P KMD 116.48367000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBFuL5swKoyZnLUTVEPjsuwh7pvP5sAz7P\",\"symbol\":\"KMD\"}" # 116.48367000 +sleep 3 +echo "116.48367000 <- expected amount RBFuL5swKoyZnLUTVEPjsuwh7pvP5sAz7P" + +# RJA8Qe3xtpSjXEXeBa8F54fW9HU3ETHCXd KMD 4646.98361435 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJA8Qe3xtpSjXEXeBa8F54fW9HU3ETHCXd\",\"symbol\":\"KMD\"}" # 4646.98361435 +sleep 3 +echo "4646.98361435 <- expected amount RJA8Qe3xtpSjXEXeBa8F54fW9HU3ETHCXd" + +# RFVp94ZGAAbFhKZG9BwuCBwEjDG9gCpY1g KMD 4893.17953483 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFVp94ZGAAbFhKZG9BwuCBwEjDG9gCpY1g\",\"symbol\":\"KMD\"}" # 4893.17953483 +sleep 3 +echo "4893.17953483 <- expected amount RFVp94ZGAAbFhKZG9BwuCBwEjDG9gCpY1g" + +# RJcBCXAPp8VYuv87Xz9mNuNCBGJmYCKDFw KMD 13750.07654112 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJcBCXAPp8VYuv87Xz9mNuNCBGJmYCKDFw\",\"symbol\":\"KMD\"}" # 13750.07654112 +sleep 3 +echo "13750.07654112 <- expected amount RJcBCXAPp8VYuv87Xz9mNuNCBGJmYCKDFw" + +# RKhFZqq9ErJBMH36bSA3sgDfd51nAMdRck KMD 6399.50717276 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKhFZqq9ErJBMH36bSA3sgDfd51nAMdRck\",\"symbol\":\"KMD\"}" # 6399.50717276 +sleep 3 +echo "6399.50717276 <- expected amount RKhFZqq9ErJBMH36bSA3sgDfd51nAMdRck" + +# RDEbPLoUKK5sbRmJyhouhk3kx2MzTKt6d4 KMD 740.16851028 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDEbPLoUKK5sbRmJyhouhk3kx2MzTKt6d4\",\"symbol\":\"KMD\"}" # 740.16851028 +sleep 3 +echo "740.16851028 <- expected amount RDEbPLoUKK5sbRmJyhouhk3kx2MzTKt6d4" + +# RAaszCNodXXu9rJL6qqVMZDykXncDecTMS KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS" + +# RHhBfhEDW88fopZfCasn6omtFr7QKa4wSk KMD 41443.89267324 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHhBfhEDW88fopZfCasn6omtFr7QKa4wSk\",\"symbol\":\"KMD\"}" # 41443.89267324 +sleep 3 +echo "41443.89267324 <- expected amount RHhBfhEDW88fopZfCasn6omtFr7QKa4wSk" + +# RMg5XaC6Lsj3YT2FtCtSDCAa5i715NYxrf KMD 16344.19309420 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMg5XaC6Lsj3YT2FtCtSDCAa5i715NYxrf\",\"symbol\":\"KMD\"}" # 16344.19309420 +sleep 3 +echo "16344.19309420 <- expected amount RMg5XaC6Lsj3YT2FtCtSDCAa5i715NYxrf" + +# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 867960.91662544, REVS 11685.48356181 +# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 867960.91662544 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw\",\"symbol\":\"KMD\"}" # 867960.91662544 +sleep 3 +echo "867960.91662544 <- expected amount RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw" + +# RVZEqmLd5e8FBfF9Y6uaKL5hEbdKSaRyCY KMD 1086.09863742 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVZEqmLd5e8FBfF9Y6uaKL5hEbdKSaRyCY\",\"symbol\":\"KMD\"}" # 1086.09863742 +sleep 3 +echo "1086.09863742 <- expected amount RVZEqmLd5e8FBfF9Y6uaKL5hEbdKSaRyCY" + +# RMHJhEJau3JWyvsuWSm7MnzxqY4QgEXXQm KMD 4319.91306129 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMHJhEJau3JWyvsuWSm7MnzxqY4QgEXXQm\",\"symbol\":\"KMD\"}" # 4319.91306129 +sleep 3 +echo "4319.91306129 <- expected amount RMHJhEJau3JWyvsuWSm7MnzxqY4QgEXXQm" + +# RHfwxdGyRKD1P9ZAY3wPRNErGjuokg5hgi KMD 38732.60997500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHfwxdGyRKD1P9ZAY3wPRNErGjuokg5hgi\",\"symbol\":\"KMD\"}" # 38732.60997500 +sleep 3 +echo "38732.60997500 <- expected amount RHfwxdGyRKD1P9ZAY3wPRNErGjuokg5hgi" + +# RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj KMD 19695.58704144, REVS 390.89494454 +# RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj KMD 19695.58704144 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj\",\"symbol\":\"KMD\"}" # 19695.58704144 +sleep 3 +echo "19695.58704144 <- expected amount RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj" + +# RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo KMD 2981.62619009, REVS 30.35300490 +# RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo KMD 2981.62619009 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo\",\"symbol\":\"KMD\"}" # 2981.62619009 +sleep 3 +echo "2981.62619009 <- expected amount RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo" + +# RXTuSxW7zs1enAXAq3xSaimTR4NYUTQL6Q KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXTuSxW7zs1enAXAq3xSaimTR4NYUTQL6Q\",\"symbol\":\"KMD\"}" # 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RXTuSxW7zs1enAXAq3xSaimTR4NYUTQL6Q" + +# RNg2LQHqauerqtv6yCVXVLug2VFAqc7JaG KMD 3205.27840587 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNg2LQHqauerqtv6yCVXVLug2VFAqc7JaG\",\"symbol\":\"KMD\"}" # 3205.27840587 +sleep 3 +echo "3205.27840587 <- expected amount RNg2LQHqauerqtv6yCVXVLug2VFAqc7JaG" + +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 40914.30625015, REVS 476.17156540 +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 40914.30625015 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX\",\"symbol\":\"KMD\"}" # 40914.30625015 +sleep 3 +echo "40914.30625015 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX" + +# RPUoGZEYGV32m6sU1qYr375mgELoMxVEJu KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPUoGZEYGV32m6sU1qYr375mgELoMxVEJu\",\"symbol\":\"KMD\"}" # 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RPUoGZEYGV32m6sU1qYr375mgELoMxVEJu" + +# RGH3G91bdgu1WrmiN4aBNREpm8EZwddmvw KMD 1363.38787112 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGH3G91bdgu1WrmiN4aBNREpm8EZwddmvw\",\"symbol\":\"KMD\"}" # 1363.38787112 +sleep 3 +echo "1363.38787112 <- expected amount RGH3G91bdgu1WrmiN4aBNREpm8EZwddmvw" + diff --git a/iguana/tests/KMD.batch4.listunspent b/iguana/tests/KMD.batch4.listunspent new file mode 100755 index 000000000..2fd8d98a0 --- /dev/null +++ b/iguana/tests/KMD.batch4.listunspent @@ -0,0 +1,200 @@ +# RKmeJpSRwBouZgkTXA1mre8EMNjQ7CawzH KMD 1999.45556678 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKmeJpSRwBouZgkTXA1mre8EMNjQ7CawzH\",\"symbol\":\"KMD\"}" +echo "1999.45556678 <- expected amount RKmeJpSRwBouZgkTXA1mre8EMNjQ7CawzH" + +# RChSVFn3Bi8kW2vRkohcaGw2QEzapdyjA7 KMD 15493.04399000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RChSVFn3Bi8kW2vRkohcaGw2QEzapdyjA7\",\"symbol\":\"KMD\"}" +echo "15493.04399000 <- expected amount RChSVFn3Bi8kW2vRkohcaGw2QEzapdyjA7" + +# RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB KMD 843.49707566, REVS 16.72927581 +# RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB KMD 843.49707566 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB\",\"symbol\":\"KMD\"}" +echo "843.49707566 <- expected amount RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB" + +# RLiYLy1TMui1iVGMhfks6Go1y1mopSkc7T KMD 9678.31091750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLiYLy1TMui1iVGMhfks6Go1y1mopSkc7T\",\"symbol\":\"KMD\"}" +echo "9678.31091750 <- expected amount RLiYLy1TMui1iVGMhfks6Go1y1mopSkc7T" + +# RRLtUwtSG5oQUL6TPk5gtWPSFa4j1eBDxQ KMD 1219.26382940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRLtUwtSG5oQUL6TPk5gtWPSFa4j1eBDxQ\",\"symbol\":\"KMD\"}" +echo "1219.26382940 <- expected amount RRLtUwtSG5oQUL6TPk5gtWPSFa4j1eBDxQ" + +# RVT4P7mbHcdRmRHBotapx2BsEC1MMcTCMC KMD 1841.49885836 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVT4P7mbHcdRmRHBotapx2BsEC1MMcTCMC\",\"symbol\":\"KMD\"}" +echo "1841.49885836 <- expected amount RVT4P7mbHcdRmRHBotapx2BsEC1MMcTCMC" + +# RNrQxuKtPSrJg6fcp665Q7j8A7WTDSbwjU KMD 681.69393556 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNrQxuKtPSrJg6fcp665Q7j8A7WTDSbwjU\",\"symbol\":\"KMD\"}" +echo "681.69393556 <- expected amount RNrQxuKtPSrJg6fcp665Q7j8A7WTDSbwjU" + +# RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n KMD 3090.02793673, REVS 3.67077856 +# RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n KMD 3090.02793673 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n\",\"symbol\":\"KMD\"}" +echo "3090.02793673 <- expected amount RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n" + +# RU2MYeg8uicVE28k6iiBXUxbxzeZwULwKi KMD 759.15915551 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU2MYeg8uicVE28k6iiBXUxbxzeZwULwKi\",\"symbol\":\"KMD\"}" +echo "759.15915551 <- expected amount RU2MYeg8uicVE28k6iiBXUxbxzeZwULwKi" + +# RL5Mi7TdaXCWpQNtbs4zUBdHQEurPuRYh8 KMD 158029.04869800 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RL5Mi7TdaXCWpQNtbs4zUBdHQEurPuRYh8\",\"symbol\":\"KMD\"}" +echo "158029.04869800 <- expected amount RL5Mi7TdaXCWpQNtbs4zUBdHQEurPuRYh8" + +# RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o KMD 2298.00667939 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o\",\"symbol\":\"KMD\"}" +echo "2298.00667939 <- expected amount RGEkGiZQxqTZjsARMzu2exjPkFegXSGT9o" + +# RAYp48ZaMJGmaKCJxeMLzWQXajW7Hd2Yjr KMD 2788.74791820 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAYp48ZaMJGmaKCJxeMLzWQXajW7Hd2Yjr\",\"symbol\":\"KMD\"}" +echo "2788.74791820 <- expected amount RAYp48ZaMJGmaKCJxeMLzWQXajW7Hd2Yjr" + +# RAryshRkyDqKp3cgavp8CD77yS9A4U5jQz KMD 710.78619077 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAryshRkyDqKp3cgavp8CD77yS9A4U5jQz\",\"symbol\":\"KMD\"}" +echo "710.78619077 <- expected amount RAryshRkyDqKp3cgavp8CD77yS9A4U5jQz" + +# RRbLh1gaRgxRXMRVwGvNw2yESgRyNzscnd KMD 1118.59777607 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRbLh1gaRgxRXMRVwGvNw2yESgRyNzscnd\",\"symbol\":\"KMD\"}" +echo "1118.59777607 <- expected amount RRbLh1gaRgxRXMRVwGvNw2yESgRyNzscnd" + +# RJtnDNrMY8pzcwwKyUvGLTjDot5jR74FRw KMD 8811.66876930 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJtnDNrMY8pzcwwKyUvGLTjDot5jR74FRw\",\"symbol\":\"KMD\"}" +echo "8811.66876930 <- expected amount RJtnDNrMY8pzcwwKyUvGLTjDot5jR74FRw" + +# RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk KMD 79613.96546024, REVS 1579.43521640 +# RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk KMD 79613.96546024 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk\",\"symbol\":\"KMD\"}" +echo "79613.96546024 <- expected amount RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk" + +# RHvVq3gKrEhXkXJSfxEzweGXRBjRMX1HwR KMD 854.63736305 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHvVq3gKrEhXkXJSfxEzweGXRBjRMX1HwR\",\"symbol\":\"KMD\"}" +echo "854.63736305 <- expected amount RHvVq3gKrEhXkXJSfxEzweGXRBjRMX1HwR" + +# RSqXWQNJTdiiP2L6Q8Pd6nzd3DyN7TzpNF KMD 87148.37244375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSqXWQNJTdiiP2L6Q8Pd6nzd3DyN7TzpNF\",\"symbol\":\"KMD\"}" +echo "87148.37244375 <- expected amount RSqXWQNJTdiiP2L6Q8Pd6nzd3DyN7TzpNF" + +# RRRWieSx6e2ANSukRrFaRSyF2ikYiqTqbH KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRRWieSx6e2ANSukRrFaRSyF2ikYiqTqbH\",\"symbol\":\"KMD\"}" +echo "96831.52493750 <- expected amount RRRWieSx6e2ANSukRrFaRSyF2ikYiqTqbH" + +# RBhKUj4dmHDDd8Yhm8npoh9ii5V5ZUjtpu KMD 1935.66218350 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBhKUj4dmHDDd8Yhm8npoh9ii5V5ZUjtpu\",\"symbol\":\"KMD\"}" +echo "1935.66218350 <- expected amount RBhKUj4dmHDDd8Yhm8npoh9ii5V5ZUjtpu" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 50303.39904535 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct\",\"symbol\":\"KMD\"}" +echo "50303.39904535 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RBopZSXfCKrvi6kELKu9Cn3TYDapxpVr8d KMD 106514.67743125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBopZSXfCKrvi6kELKu9Cn3TYDapxpVr8d\",\"symbol\":\"KMD\"}" +echo "106514.67743125 <- expected amount RBopZSXfCKrvi6kELKu9Cn3TYDapxpVr8d" + +# RFEHFqHrwcwnTBzvYsuEttQ4rQQZw9qQsH KMD 1526.39979262 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFEHFqHrwcwnTBzvYsuEttQ4rQQZw9qQsH\",\"symbol\":\"KMD\"}" +echo "1526.39979262 <- expected amount RFEHFqHrwcwnTBzvYsuEttQ4rQQZw9qQsH" + +# RJzu13gJQjtS6aQdNEaQMrv7TSL4wQBien KMD 2130.29354862 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJzu13gJQjtS6aQdNEaQMrv7TSL4wQBien\",\"symbol\":\"KMD\"}" +echo "2130.29354862 <- expected amount RJzu13gJQjtS6aQdNEaQMrv7TSL4wQBien" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 20106.39865075, REVS 0.09000000 +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 20106.39865075 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" +echo "20106.39865075 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RBcmNwoFVZ5kWZB8LMjgGbqvVmByD1DeTJ KMD 12526.83053462 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBcmNwoFVZ5kWZB8LMjgGbqvVmByD1DeTJ\",\"symbol\":\"KMD\"}" +echo "12526.83053462 <- expected amount RBcmNwoFVZ5kWZB8LMjgGbqvVmByD1DeTJ" + +# REwf8D6dyFevVSZc6wjTAwmTgntUM5KWGd KMD 273706.84143501 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REwf8D6dyFevVSZc6wjTAwmTgntUM5KWGd\",\"symbol\":\"KMD\"}" +echo "273706.84143501 <- expected amount REwf8D6dyFevVSZc6wjTAwmTgntUM5KWGd" + +# RJQNje5EiBV2C7f28YLcm9LEm8AvrSFtVc KMD 3880.03920424 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJQNje5EiBV2C7f28YLcm9LEm8AvrSFtVc\",\"symbol\":\"KMD\"}" +echo "3880.03920424 <- expected amount RJQNje5EiBV2C7f28YLcm9LEm8AvrSFtVc" + +# RBFuL5swKoyZnLUTVEPjsuwh7pvP5sAz7P KMD 116.48367000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBFuL5swKoyZnLUTVEPjsuwh7pvP5sAz7P\",\"symbol\":\"KMD\"}" +echo "116.48367000 <- expected amount RBFuL5swKoyZnLUTVEPjsuwh7pvP5sAz7P" + +# RJA8Qe3xtpSjXEXeBa8F54fW9HU3ETHCXd KMD 4646.98361435 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJA8Qe3xtpSjXEXeBa8F54fW9HU3ETHCXd\",\"symbol\":\"KMD\"}" +echo "4646.98361435 <- expected amount RJA8Qe3xtpSjXEXeBa8F54fW9HU3ETHCXd" + +# RFVp94ZGAAbFhKZG9BwuCBwEjDG9gCpY1g KMD 4893.17953483 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFVp94ZGAAbFhKZG9BwuCBwEjDG9gCpY1g\",\"symbol\":\"KMD\"}" +echo "4893.17953483 <- expected amount RFVp94ZGAAbFhKZG9BwuCBwEjDG9gCpY1g" + +# RJcBCXAPp8VYuv87Xz9mNuNCBGJmYCKDFw KMD 13750.07654112 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJcBCXAPp8VYuv87Xz9mNuNCBGJmYCKDFw\",\"symbol\":\"KMD\"}" +echo "13750.07654112 <- expected amount RJcBCXAPp8VYuv87Xz9mNuNCBGJmYCKDFw" + +# RKhFZqq9ErJBMH36bSA3sgDfd51nAMdRck KMD 6399.50717276 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKhFZqq9ErJBMH36bSA3sgDfd51nAMdRck\",\"symbol\":\"KMD\"}" +echo "6399.50717276 <- expected amount RKhFZqq9ErJBMH36bSA3sgDfd51nAMdRck" + +# RDEbPLoUKK5sbRmJyhouhk3kx2MzTKt6d4 KMD 740.16851028 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDEbPLoUKK5sbRmJyhouhk3kx2MzTKt6d4\",\"symbol\":\"KMD\"}" +echo "740.16851028 <- expected amount RDEbPLoUKK5sbRmJyhouhk3kx2MzTKt6d4" + +# RAaszCNodXXu9rJL6qqVMZDykXncDecTMS KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS" + +# RHhBfhEDW88fopZfCasn6omtFr7QKa4wSk KMD 41443.89267324 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHhBfhEDW88fopZfCasn6omtFr7QKa4wSk\",\"symbol\":\"KMD\"}" +echo "41443.89267324 <- expected amount RHhBfhEDW88fopZfCasn6omtFr7QKa4wSk" + +# RMg5XaC6Lsj3YT2FtCtSDCAa5i715NYxrf KMD 16344.19309420 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMg5XaC6Lsj3YT2FtCtSDCAa5i715NYxrf\",\"symbol\":\"KMD\"}" +echo "16344.19309420 <- expected amount RMg5XaC6Lsj3YT2FtCtSDCAa5i715NYxrf" + +# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 867960.91662544, REVS 11685.48356181 +# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 867960.91662544 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw\",\"symbol\":\"KMD\"}" +echo "867960.91662544 <- expected amount RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw" + +# RVZEqmLd5e8FBfF9Y6uaKL5hEbdKSaRyCY KMD 1086.09863742 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVZEqmLd5e8FBfF9Y6uaKL5hEbdKSaRyCY\",\"symbol\":\"KMD\"}" +echo "1086.09863742 <- expected amount RVZEqmLd5e8FBfF9Y6uaKL5hEbdKSaRyCY" + +# RMHJhEJau3JWyvsuWSm7MnzxqY4QgEXXQm KMD 4319.91306129 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMHJhEJau3JWyvsuWSm7MnzxqY4QgEXXQm\",\"symbol\":\"KMD\"}" +echo "4319.91306129 <- expected amount RMHJhEJau3JWyvsuWSm7MnzxqY4QgEXXQm" + +# RHfwxdGyRKD1P9ZAY3wPRNErGjuokg5hgi KMD 38732.60997500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHfwxdGyRKD1P9ZAY3wPRNErGjuokg5hgi\",\"symbol\":\"KMD\"}" +echo "38732.60997500 <- expected amount RHfwxdGyRKD1P9ZAY3wPRNErGjuokg5hgi" + +# RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj KMD 19695.58704144, REVS 390.89494454 +# RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj KMD 19695.58704144 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj\",\"symbol\":\"KMD\"}" +echo "19695.58704144 <- expected amount RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj" + +# RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo KMD 2981.62619009, REVS 30.35300490 +# RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo KMD 2981.62619009 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo\",\"symbol\":\"KMD\"}" +echo "2981.62619009 <- expected amount RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo" + +# RXTuSxW7zs1enAXAq3xSaimTR4NYUTQL6Q KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXTuSxW7zs1enAXAq3xSaimTR4NYUTQL6Q\",\"symbol\":\"KMD\"}" +echo "968.31524937 <- expected amount RXTuSxW7zs1enAXAq3xSaimTR4NYUTQL6Q" + +# RNg2LQHqauerqtv6yCVXVLug2VFAqc7JaG KMD 3205.27840587 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNg2LQHqauerqtv6yCVXVLug2VFAqc7JaG\",\"symbol\":\"KMD\"}" +echo "3205.27840587 <- expected amount RNg2LQHqauerqtv6yCVXVLug2VFAqc7JaG" + +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 40914.30625015, REVS 476.17156540 +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 40914.30625015 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX\",\"symbol\":\"KMD\"}" +echo "40914.30625015 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX" + +# RPUoGZEYGV32m6sU1qYr375mgELoMxVEJu KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPUoGZEYGV32m6sU1qYr375mgELoMxVEJu\",\"symbol\":\"KMD\"}" +echo "48415.76246875 <- expected amount RPUoGZEYGV32m6sU1qYr375mgELoMxVEJu" + +# RGH3G91bdgu1WrmiN4aBNREpm8EZwddmvw KMD 1363.38787112 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGH3G91bdgu1WrmiN4aBNREpm8EZwddmvw\",\"symbol\":\"KMD\"}" +echo "1363.38787112 <- expected amount RGH3G91bdgu1WrmiN4aBNREpm8EZwddmvw" + diff --git a/iguana/tests/KMD.batch5 b/iguana/tests/KMD.batch5 new file mode 100755 index 000000000..c03ab0568 --- /dev/null +++ b/iguana/tests/KMD.batch5 @@ -0,0 +1,340 @@ +sleep 999999 +# RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4 KMD 19343.06542151 +./komodo-cli sendtoaddress RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4 19343.06542151 +sleep 3 +echo "19343.06542151 <- expected amount RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4" + +# RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy KMD 3873.26099750 +./komodo-cli sendtoaddress RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy" + +# RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq KMD 6971.86979550 +./komodo-cli sendtoaddress RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq 6971.86979550 +sleep 3 +echo "6971.86979550 <- expected amount RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq" + +# RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU KMD 4912.04612506 +./komodo-cli sendtoaddress RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU 4912.04612506 +sleep 3 +echo "4912.04612506 <- expected amount RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU" + +# RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6 KMD 27887.47918200 +./komodo-cli sendtoaddress RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6 27887.47918200 +sleep 3 +echo "27887.47918200 <- expected amount RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6" + +# RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix KMD 1452.47287406 +./komodo-cli sendtoaddress RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix 1452.47287406 +sleep 3 +echo "1452.47287406 <- expected amount RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix" + +# RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW KMD 852.11741945 +./komodo-cli sendtoaddress RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW 852.11741945 +sleep 3 +echo "852.11741945 <- expected amount RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW" + +# RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ KMD 1625.48610260 +./komodo-cli sendtoaddress RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ 1625.48610260 +sleep 3 +echo "1625.48610260 <- expected amount RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ" + +# RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19 KMD 5228.90234661 +./komodo-cli sendtoaddress RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19 5228.90234661 +sleep 3 +echo "5228.90234661 <- expected amount RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19" + +# RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y KMD 6045.00703151, REVS 119.90847305 +# RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y KMD 6045.00703151 +./komodo-cli sendtoaddress RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y 6045.00703151 +sleep 3 +echo "6045.00703151 <- expected amount RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y" + +# RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ KMD 10521.01631272 +./komodo-cli sendtoaddress RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ 10521.01631272 +sleep 3 +echo "10521.01631272 <- expected amount RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ" + +# RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc KMD 2902.52496000 +./komodo-cli sendtoaddress RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc 2902.52496000 +sleep 3 +echo "2902.52496000 <- expected amount RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc" + +# RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 KMD 35570.77185561, REVS 706.06380741 +# RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 KMD 35570.77185561 +./komodo-cli sendtoaddress RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 35570.77185561 +sleep 3 +echo "35570.77185561 <- expected amount RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1" + +# RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM KMD 291.86077302 +./komodo-cli sendtoaddress RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM 291.86077302 +sleep 3 +echo "291.86077302 <- expected amount RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM" + +# RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva KMD 19366.30498750 +./komodo-cli sendtoaddress RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva 19366.30498750 +sleep 3 +echo "19366.30498750 <- expected amount RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva" + +# RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S KMD 722.28571081 +./komodo-cli sendtoaddress RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S 722.28571081 +sleep 3 +echo "722.28571081 <- expected amount RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S" + +# RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x KMD 416761.10163094 +./komodo-cli sendtoaddress RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x 416761.10163094 +sleep 3 +echo "416761.10163094 <- expected amount RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x" + +# RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH KMD 9767.05422136 +./komodo-cli sendtoaddress RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH 9767.05422136 +sleep 3 +echo "9767.05422136 <- expected amount RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH" + +# RGur4rnZTJRSdAjU5avya5EA57K5izbv9b KMD 1891.37303787, REVS 19.42986755 +# RGur4rnZTJRSdAjU5avya5EA57K5izbv9b KMD 1891.37303787 +./komodo-cli sendtoaddress RGur4rnZTJRSdAjU5avya5EA57K5izbv9b 1891.37303787 +sleep 3 +echo "1891.37303787 <- expected amount RGur4rnZTJRSdAjU5avya5EA57K5izbv9b" + +# REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91 KMD 17009.37539559 +./komodo-cli sendtoaddress REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91 17009.37539559 +sleep 3 +echo "17009.37539559 <- expected amount REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91" + +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 1241.69290122 +./komodo-cli sendtoaddress RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u 1241.69290122 +sleep 3 +echo "1241.69290122 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u" + +# RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM KMD 852.11741945 +./komodo-cli sendtoaddress RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM 852.11741945 +sleep 3 +echo "852.11741945 <- expected amount RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 195982.90265756, REVS 3438.00000000 +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 195982.90265756 +./komodo-cli sendtoaddress RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni 195982.90265756 +sleep 3 +echo "195982.90265756 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY KMD 9117.34456938, REVS 181.00000000 +# RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY KMD 9117.34456938 +./komodo-cli sendtoaddress RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY 9117.34456938 +sleep 3 +echo "9117.34456938 <- expected amount RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY" + +# RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU KMD 11842.49549985 +./komodo-cli sendtoaddress RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU 11842.49549985 +sleep 3 +echo "11842.49549985 <- expected amount RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU" + +# RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H KMD 861.17744171 +./komodo-cli sendtoaddress RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H 861.17744171 +sleep 3 +echo "861.17744171 <- expected amount RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H" + +# RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg KMD 30792.42493012 +./komodo-cli sendtoaddress RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg 30792.42493012 +sleep 3 +echo "30792.42493012 <- expected amount RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg" + +# RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN KMD 9683.15249375 +./komodo-cli sendtoaddress RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN" + +# RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ KMD 6641.51666395, REVS 131.74080812 +# RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ KMD 6641.51666395 +./komodo-cli sendtoaddress RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ 6641.51666395 +sleep 3 +echo "6641.51666395 <- expected amount RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ" + +# RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE KMD 972.76143201 +./komodo-cli sendtoaddress RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE 972.76143201 +sleep 3 +echo "972.76143201 <- expected amount RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 7967.93037537 +./komodo-cli sendtoaddress RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ 7967.93037537 +sleep 3 +echo "7967.93037537 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM KMD 2518.25812688 +./komodo-cli sendtoaddress RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM 2518.25812688 +sleep 3 +echo "2518.25812688 <- expected amount RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM" + +# RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5 KMD 28809.31529940 +./komodo-cli sendtoaddress RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5 28809.31529940 +sleep 3 +echo "28809.31529940 <- expected amount RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5" + +# REq67wAMhhyUD6JRScLBpc2BD6farddg3e KMD 6740.09632448, REVS 16.99805655 +# REq67wAMhhyUD6JRScLBpc2BD6farddg3e KMD 6740.09632448 +./komodo-cli sendtoaddress REq67wAMhhyUD6JRScLBpc2BD6farddg3e 6740.09632448 +sleep 3 +echo "6740.09632448 <- expected amount REq67wAMhhyUD6JRScLBpc2BD6farddg3e" + +# RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s KMD 22492.75115633, REVS 236.96348849 +# RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s KMD 22492.75115633 +./komodo-cli sendtoaddress RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s 22492.75115633 +sleep 3 +echo "22492.75115633 <- expected amount RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s" + +# RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S KMD 15493.04399000 +./komodo-cli sendtoaddress RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S 15493.04399000 +sleep 3 +echo "15493.04399000 <- expected amount RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S" + +# RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m KMD 1140.36550287 +./komodo-cli sendtoaddress RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m 1140.36550287 +sleep 3 +echo "1140.36550287 <- expected amount RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m" + +# RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58 KMD 1575.45572767 +./komodo-cli sendtoaddress RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58 1575.45572767 +sleep 3 +echo "1575.45572767 <- expected amount RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58" + +# RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU KMD 14524.72874062 +./komodo-cli sendtoaddress RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU 14524.72874062 +sleep 3 +echo "14524.72874062 <- expected amount RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU" + +# RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu KMD 87148.37244375 +./komodo-cli sendtoaddress RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu 87148.37244375 +sleep 3 +echo "87148.37244375 <- expected amount RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu" + +# R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W KMD 95237.89695894 +./komodo-cli sendtoaddress R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W 95237.89695894 +sleep 3 +echo "95237.89695894 <- expected amount R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 3.13113297 +./komodo-cli sendtoaddress RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 3.13113297 +sleep 3 +echo "3.13113297 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja KMD 1659.54315667 +./komodo-cli sendtoaddress RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja 1659.54315667 +sleep 3 +echo "1659.54315667 <- expected amount RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja" + +# RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj KMD 8643.80014966 +./komodo-cli sendtoaddress RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj 8643.80014966 +sleep 3 +echo "8643.80014966 <- expected amount RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj" + +# RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D KMD 553085.02723026 +./komodo-cli sendtoaddress RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D 553085.02723026 +sleep 3 +echo "553085.02723026 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D" + +# RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP KMD 1946.54604690 +./komodo-cli sendtoaddress RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP 1946.54604690 +sleep 3 +echo "1946.54604690 <- expected amount RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP" + +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 6165.95629088, REVS 18.51019595 +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 6165.95629088 +./komodo-cli sendtoaddress REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk 6165.95629088 +sleep 3 +echo "6165.95629088 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk" + +# RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK KMD 11144.67547452 +./komodo-cli sendtoaddress RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK 11144.67547452 +sleep 3 +echo "11144.67547452 <- expected amount RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK" + +# RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es KMD 6944.64226884 +./komodo-cli sendtoaddress RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es 6944.64226884 +sleep 3 +echo "6944.64226884 <- expected amount RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es" + +# RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e KMD 29049.45748125 +./komodo-cli sendtoaddress RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e 29049.45748125 +sleep 3 +echo "29049.45748125 <- expected amount RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 14070.80002269 +./komodo-cli sendtoaddress RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct 14070.80002269 +sleep 3 +echo "14070.80002269 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd KMD 25865.73214606 +./komodo-cli sendtoaddress RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd 25865.73214606 +sleep 3 +echo "25865.73214606 <- expected amount RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd" + +# RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU KMD 20625.11481168 +./komodo-cli sendtoaddress RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU 20625.11481168 +sleep 3 +echo "20625.11481168 <- expected amount RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU" + +# RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr KMD 306877.42641191 +./komodo-cli sendtoaddress RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr 306877.42641191 +sleep 3 +echo "306877.42641191 <- expected amount RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr" + +# RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY KMD 230865.18565552, REVS 4582.57000000 +# RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY KMD 230865.18565552 +./komodo-cli sendtoaddress RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY 230865.18565552 +sleep 3 +echo "230865.18565552 <- expected amount RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY" + +# RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt KMD 1548.52974680 +./komodo-cli sendtoaddress RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt 1548.52974680 +sleep 3 +echo "1548.52974680 <- expected amount RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 2651.62370624 +./komodo-cli sendtoaddress RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 2651.62370624 +sleep 3 +echo "2651.62370624 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a KMD 13266.57413441, REVS 46.55982083 +# RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a KMD 13266.57413441 +./komodo-cli sendtoaddress RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a 13266.57413441 +sleep 3 +echo "13266.57413441 <- expected amount RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 2182.61555865 +./komodo-cli sendtoaddress RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz 2182.61555865 +sleep 3 +echo "2182.61555865 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RXoox1yRGdHhYa5scahD734qajAAQiNKDf KMD 12541.20725926 +./komodo-cli sendtoaddress RXoox1yRGdHhYa5scahD734qajAAQiNKDf 12541.20725926 +sleep 3 +echo "12541.20725926 <- expected amount RXoox1yRGdHhYa5scahD734qajAAQiNKDf" + +# RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY KMD 129183.61336863, REVS 2562.48000000 +# RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY KMD 129183.61336863 +./komodo-cli sendtoaddress RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY 129183.61336863 +sleep 3 +echo "129183.61336863 <- expected amount RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY" + +# RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr KMD 1985.04626121 +./komodo-cli sendtoaddress RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr 1985.04626121 +sleep 3 +echo "1985.04626121 <- expected amount RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr" + +# RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu KMD 15880.37008974 +./komodo-cli sendtoaddress RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu 15880.37008974 +sleep 3 +echo "15880.37008974 <- expected amount RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu" + +# RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo KMD 1578.13191862 +./komodo-cli sendtoaddress RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo 1578.13191862 +sleep 3 +echo "1578.13191862 <- expected amount RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo" + +# RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad KMD 774.65219950 +./komodo-cli sendtoaddress RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad 774.65219950 +sleep 3 +echo "774.65219950 <- expected amount RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad" + + +# total KMD 2543170.57935940 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch5.importaddress b/iguana/tests/KMD.batch5.importaddress new file mode 100755 index 000000000..369b47276 --- /dev/null +++ b/iguana/tests/KMD.batch5.importaddress @@ -0,0 +1,337 @@ +# RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4 KMD 19343.06542151 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4\",\"symbol\":\"KMD\"}" # 19343.06542151 +sleep 3 +echo "19343.06542151 <- expected amount RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4" + +# RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy\",\"symbol\":\"KMD\"}" # 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy" + +# RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq KMD 6971.86979550 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq\",\"symbol\":\"KMD\"}" # 6971.86979550 +sleep 3 +echo "6971.86979550 <- expected amount RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq" + +# RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU KMD 4912.04612506 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU\",\"symbol\":\"KMD\"}" # 4912.04612506 +sleep 3 +echo "4912.04612506 <- expected amount RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU" + +# RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6 KMD 27887.47918200 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6\",\"symbol\":\"KMD\"}" # 27887.47918200 +sleep 3 +echo "27887.47918200 <- expected amount RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6" + +# RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix KMD 1452.47287406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix\",\"symbol\":\"KMD\"}" # 1452.47287406 +sleep 3 +echo "1452.47287406 <- expected amount RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix" + +# RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW KMD 852.11741945 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW\",\"symbol\":\"KMD\"}" # 852.11741945 +sleep 3 +echo "852.11741945 <- expected amount RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW" + +# RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ KMD 1625.48610260 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ\",\"symbol\":\"KMD\"}" # 1625.48610260 +sleep 3 +echo "1625.48610260 <- expected amount RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ" + +# RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19 KMD 5228.90234661 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19\",\"symbol\":\"KMD\"}" # 5228.90234661 +sleep 3 +echo "5228.90234661 <- expected amount RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19" + +# RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y KMD 6045.00703151, REVS 119.90847305 +# RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y KMD 6045.00703151 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y\",\"symbol\":\"KMD\"}" # 6045.00703151 +sleep 3 +echo "6045.00703151 <- expected amount RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y" + +# RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ KMD 10521.01631272 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ\",\"symbol\":\"KMD\"}" # 10521.01631272 +sleep 3 +echo "10521.01631272 <- expected amount RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ" + +# RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc KMD 2902.52496000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc\",\"symbol\":\"KMD\"}" # 2902.52496000 +sleep 3 +echo "2902.52496000 <- expected amount RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc" + +# RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 KMD 35570.77185561, REVS 706.06380741 +# RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 KMD 35570.77185561 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1\",\"symbol\":\"KMD\"}" # 35570.77185561 +sleep 3 +echo "35570.77185561 <- expected amount RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1" + +# RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM KMD 291.86077302 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM\",\"symbol\":\"KMD\"}" # 291.86077302 +sleep 3 +echo "291.86077302 <- expected amount RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM" + +# RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva\",\"symbol\":\"KMD\"}" # 19366.30498750 +sleep 3 +echo "19366.30498750 <- expected amount RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva" + +# RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S\",\"symbol\":\"KMD\"}" # 722.28571081 +sleep 3 +echo "722.28571081 <- expected amount RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S" + +# RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x KMD 416761.10163094 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x\",\"symbol\":\"KMD\"}" # 416761.10163094 +sleep 3 +echo "416761.10163094 <- expected amount RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x" + +# RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH KMD 9767.05422136 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH\",\"symbol\":\"KMD\"}" # 9767.05422136 +sleep 3 +echo "9767.05422136 <- expected amount RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH" + +# RGur4rnZTJRSdAjU5avya5EA57K5izbv9b KMD 1891.37303787, REVS 19.42986755 +# RGur4rnZTJRSdAjU5avya5EA57K5izbv9b KMD 1891.37303787 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGur4rnZTJRSdAjU5avya5EA57K5izbv9b\",\"symbol\":\"KMD\"}" # 1891.37303787 +sleep 3 +echo "1891.37303787 <- expected amount RGur4rnZTJRSdAjU5avya5EA57K5izbv9b" + +# REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91 KMD 17009.37539559 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91\",\"symbol\":\"KMD\"}" # 17009.37539559 +sleep 3 +echo "17009.37539559 <- expected amount REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91" + +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 1241.69290122 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u\",\"symbol\":\"KMD\"}" # 1241.69290122 +sleep 3 +echo "1241.69290122 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u" + +# RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM KMD 852.11741945 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM\",\"symbol\":\"KMD\"}" # 852.11741945 +sleep 3 +echo "852.11741945 <- expected amount RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 195982.90265756, REVS 3438.00000000 +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 195982.90265756 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni\",\"symbol\":\"KMD\"}" # 195982.90265756 +sleep 3 +echo "195982.90265756 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY KMD 9117.34456938, REVS 181.00000000 +# RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY KMD 9117.34456938 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY\",\"symbol\":\"KMD\"}" # 9117.34456938 +sleep 3 +echo "9117.34456938 <- expected amount RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY" + +# RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU KMD 11842.49549985 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU\",\"symbol\":\"KMD\"}" # 11842.49549985 +sleep 3 +echo "11842.49549985 <- expected amount RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU" + +# RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H KMD 861.17744171 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H\",\"symbol\":\"KMD\"}" # 861.17744171 +sleep 3 +echo "861.17744171 <- expected amount RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H" + +# RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg KMD 30792.42493012 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg\",\"symbol\":\"KMD\"}" # 30792.42493012 +sleep 3 +echo "30792.42493012 <- expected amount RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg" + +# RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN" + +# RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ KMD 6641.51666395, REVS 131.74080812 +# RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ KMD 6641.51666395 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ\",\"symbol\":\"KMD\"}" # 6641.51666395 +sleep 3 +echo "6641.51666395 <- expected amount RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ" + +# RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE KMD 972.76143201 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE\",\"symbol\":\"KMD\"}" # 972.76143201 +sleep 3 +echo "972.76143201 <- expected amount RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 7967.93037537 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" # 7967.93037537 +sleep 3 +echo "7967.93037537 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM KMD 2518.25812688 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM\",\"symbol\":\"KMD\"}" # 2518.25812688 +sleep 3 +echo "2518.25812688 <- expected amount RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM" + +# RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5 KMD 28809.31529940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5\",\"symbol\":\"KMD\"}" # 28809.31529940 +sleep 3 +echo "28809.31529940 <- expected amount RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5" + +# REq67wAMhhyUD6JRScLBpc2BD6farddg3e KMD 6740.09632448, REVS 16.99805655 +# REq67wAMhhyUD6JRScLBpc2BD6farddg3e KMD 6740.09632448 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REq67wAMhhyUD6JRScLBpc2BD6farddg3e\",\"symbol\":\"KMD\"}" # 6740.09632448 +sleep 3 +echo "6740.09632448 <- expected amount REq67wAMhhyUD6JRScLBpc2BD6farddg3e" + +# RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s KMD 22492.75115633, REVS 236.96348849 +# RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s KMD 22492.75115633 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s\",\"symbol\":\"KMD\"}" # 22492.75115633 +sleep 3 +echo "22492.75115633 <- expected amount RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s" + +# RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S KMD 15493.04399000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S\",\"symbol\":\"KMD\"}" # 15493.04399000 +sleep 3 +echo "15493.04399000 <- expected amount RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S" + +# RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m KMD 1140.36550287 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m\",\"symbol\":\"KMD\"}" # 1140.36550287 +sleep 3 +echo "1140.36550287 <- expected amount RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m" + +# RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58 KMD 1575.45572767 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58\",\"symbol\":\"KMD\"}" # 1575.45572767 +sleep 3 +echo "1575.45572767 <- expected amount RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58" + +# RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU KMD 14524.72874062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU\",\"symbol\":\"KMD\"}" # 14524.72874062 +sleep 3 +echo "14524.72874062 <- expected amount RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU" + +# RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu KMD 87148.37244375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu\",\"symbol\":\"KMD\"}" # 87148.37244375 +sleep 3 +echo "87148.37244375 <- expected amount RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu" + +# R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W KMD 95237.89695894 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W\",\"symbol\":\"KMD\"}" # 95237.89695894 +sleep 3 +echo "95237.89695894 <- expected amount R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 3.13113297 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" # 3.13113297 +sleep 3 +echo "3.13113297 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja KMD 1659.54315667 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja\",\"symbol\":\"KMD\"}" # 1659.54315667 +sleep 3 +echo "1659.54315667 <- expected amount RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja" + +# RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj KMD 8643.80014966 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj\",\"symbol\":\"KMD\"}" # 8643.80014966 +sleep 3 +echo "8643.80014966 <- expected amount RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj" + +# RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D KMD 553085.02723026 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D\",\"symbol\":\"KMD\"}" # 553085.02723026 +sleep 3 +echo "553085.02723026 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D" + +# RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP KMD 1946.54604690 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP\",\"symbol\":\"KMD\"}" # 1946.54604690 +sleep 3 +echo "1946.54604690 <- expected amount RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP" + +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 6165.95629088, REVS 18.51019595 +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 6165.95629088 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk\",\"symbol\":\"KMD\"}" # 6165.95629088 +sleep 3 +echo "6165.95629088 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk" + +# RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK KMD 11144.67547452 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK\",\"symbol\":\"KMD\"}" # 11144.67547452 +sleep 3 +echo "11144.67547452 <- expected amount RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK" + +# RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es KMD 6944.64226884 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es\",\"symbol\":\"KMD\"}" # 6944.64226884 +sleep 3 +echo "6944.64226884 <- expected amount RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es" + +# RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e\",\"symbol\":\"KMD\"}" # 29049.45748125 +sleep 3 +echo "29049.45748125 <- expected amount RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 14070.80002269 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct\",\"symbol\":\"KMD\"}" # 14070.80002269 +sleep 3 +echo "14070.80002269 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd KMD 25865.73214606 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd\",\"symbol\":\"KMD\"}" # 25865.73214606 +sleep 3 +echo "25865.73214606 <- expected amount RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd" + +# RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU KMD 20625.11481168 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU\",\"symbol\":\"KMD\"}" # 20625.11481168 +sleep 3 +echo "20625.11481168 <- expected amount RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU" + +# RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr KMD 306877.42641191 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr\",\"symbol\":\"KMD\"}" # 306877.42641191 +sleep 3 +echo "306877.42641191 <- expected amount RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr" + +# RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY KMD 230865.18565552, REVS 4582.57000000 +# RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY KMD 230865.18565552 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY\",\"symbol\":\"KMD\"}" # 230865.18565552 +sleep 3 +echo "230865.18565552 <- expected amount RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY" + +# RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt KMD 1548.52974680 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt\",\"symbol\":\"KMD\"}" # 1548.52974680 +sleep 3 +echo "1548.52974680 <- expected amount RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 2651.62370624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" # 2651.62370624 +sleep 3 +echo "2651.62370624 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a KMD 13266.57413441, REVS 46.55982083 +# RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a KMD 13266.57413441 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a\",\"symbol\":\"KMD\"}" # 13266.57413441 +sleep 3 +echo "13266.57413441 <- expected amount RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 2182.61555865 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" # 2182.61555865 +sleep 3 +echo "2182.61555865 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RXoox1yRGdHhYa5scahD734qajAAQiNKDf KMD 12541.20725926 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXoox1yRGdHhYa5scahD734qajAAQiNKDf\",\"symbol\":\"KMD\"}" # 12541.20725926 +sleep 3 +echo "12541.20725926 <- expected amount RXoox1yRGdHhYa5scahD734qajAAQiNKDf" + +# RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY KMD 129183.61336863, REVS 2562.48000000 +# RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY KMD 129183.61336863 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY\",\"symbol\":\"KMD\"}" # 129183.61336863 +sleep 3 +echo "129183.61336863 <- expected amount RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY" + +# RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr KMD 1985.04626121 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr\",\"symbol\":\"KMD\"}" # 1985.04626121 +sleep 3 +echo "1985.04626121 <- expected amount RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr" + +# RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu KMD 15880.37008974 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu\",\"symbol\":\"KMD\"}" # 15880.37008974 +sleep 3 +echo "15880.37008974 <- expected amount RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu" + +# RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo KMD 1578.13191862 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo\",\"symbol\":\"KMD\"}" # 1578.13191862 +sleep 3 +echo "1578.13191862 <- expected amount RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo" + +# RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad\",\"symbol\":\"KMD\"}" # 774.65219950 +sleep 3 +echo "774.65219950 <- expected amount RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad" + diff --git a/iguana/tests/KMD.batch5.listunspent b/iguana/tests/KMD.batch5.listunspent new file mode 100755 index 000000000..7d7c89e27 --- /dev/null +++ b/iguana/tests/KMD.batch5.listunspent @@ -0,0 +1,272 @@ +# RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4 KMD 19343.06542151 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4\",\"symbol\":\"KMD\"}" +echo "19343.06542151 <- expected amount RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4" + +# RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy\",\"symbol\":\"KMD\"}" +echo "3873.26099750 <- expected amount RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy" + +# RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq KMD 6971.86979550 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq\",\"symbol\":\"KMD\"}" +echo "6971.86979550 <- expected amount RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq" + +# RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU KMD 4912.04612506 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU\",\"symbol\":\"KMD\"}" +echo "4912.04612506 <- expected amount RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU" + +# RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6 KMD 27887.47918200 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6\",\"symbol\":\"KMD\"}" +echo "27887.47918200 <- expected amount RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6" + +# RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix KMD 1452.47287406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix\",\"symbol\":\"KMD\"}" +echo "1452.47287406 <- expected amount RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix" + +# RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW KMD 852.11741945 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW\",\"symbol\":\"KMD\"}" +echo "852.11741945 <- expected amount RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW" + +# RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ KMD 1625.48610260 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ\",\"symbol\":\"KMD\"}" +echo "1625.48610260 <- expected amount RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ" + +# RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19 KMD 5228.90234661 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19\",\"symbol\":\"KMD\"}" +echo "5228.90234661 <- expected amount RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19" + +# RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y KMD 6045.00703151, REVS 119.90847305 +# RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y KMD 6045.00703151 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y\",\"symbol\":\"KMD\"}" +echo "6045.00703151 <- expected amount RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y" + +# RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ KMD 10521.01631272 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ\",\"symbol\":\"KMD\"}" +echo "10521.01631272 <- expected amount RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ" + +# RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc KMD 2902.52496000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc\",\"symbol\":\"KMD\"}" +echo "2902.52496000 <- expected amount RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc" + +# RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 KMD 35570.77185561, REVS 706.06380741 +# RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 KMD 35570.77185561 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1\",\"symbol\":\"KMD\"}" +echo "35570.77185561 <- expected amount RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1" + +# RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM KMD 291.86077302 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM\",\"symbol\":\"KMD\"}" +echo "291.86077302 <- expected amount RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM" + +# RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva KMD 19366.30498750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva\",\"symbol\":\"KMD\"}" +echo "19366.30498750 <- expected amount RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva" + +# RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S KMD 722.28571081 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S\",\"symbol\":\"KMD\"}" +echo "722.28571081 <- expected amount RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S" + +# RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x KMD 416761.10163094 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x\",\"symbol\":\"KMD\"}" +echo "416761.10163094 <- expected amount RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x" + +# RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH KMD 9767.05422136 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH\",\"symbol\":\"KMD\"}" +echo "9767.05422136 <- expected amount RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH" + +# RGur4rnZTJRSdAjU5avya5EA57K5izbv9b KMD 1891.37303787, REVS 19.42986755 +# RGur4rnZTJRSdAjU5avya5EA57K5izbv9b KMD 1891.37303787 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGur4rnZTJRSdAjU5avya5EA57K5izbv9b\",\"symbol\":\"KMD\"}" +echo "1891.37303787 <- expected amount RGur4rnZTJRSdAjU5avya5EA57K5izbv9b" + +# REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91 KMD 17009.37539559 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91\",\"symbol\":\"KMD\"}" +echo "17009.37539559 <- expected amount REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91" + +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 1241.69290122 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u\",\"symbol\":\"KMD\"}" +echo "1241.69290122 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u" + +# RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM KMD 852.11741945 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM\",\"symbol\":\"KMD\"}" +echo "852.11741945 <- expected amount RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 195982.90265756, REVS 3438.00000000 +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 195982.90265756 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni\",\"symbol\":\"KMD\"}" +echo "195982.90265756 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY KMD 9117.34456938, REVS 181.00000000 +# RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY KMD 9117.34456938 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY\",\"symbol\":\"KMD\"}" +echo "9117.34456938 <- expected amount RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY" + +# RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU KMD 11842.49549985 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU\",\"symbol\":\"KMD\"}" +echo "11842.49549985 <- expected amount RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU" + +# RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H KMD 861.17744171 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H\",\"symbol\":\"KMD\"}" +echo "861.17744171 <- expected amount RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H" + +# RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg KMD 30792.42493012 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg\",\"symbol\":\"KMD\"}" +echo "30792.42493012 <- expected amount RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg" + +# RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN" + +# RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ KMD 6641.51666395, REVS 131.74080812 +# RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ KMD 6641.51666395 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ\",\"symbol\":\"KMD\"}" +echo "6641.51666395 <- expected amount RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ" + +# RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE KMD 972.76143201 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE\",\"symbol\":\"KMD\"}" +echo "972.76143201 <- expected amount RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE" + +# RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ KMD 7967.93037537 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ\",\"symbol\":\"KMD\"}" +echo "7967.93037537 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ" + +# RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM KMD 2518.25812688 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM\",\"symbol\":\"KMD\"}" +echo "2518.25812688 <- expected amount RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM" + +# RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5 KMD 28809.31529940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5\",\"symbol\":\"KMD\"}" +echo "28809.31529940 <- expected amount RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5" + +# REq67wAMhhyUD6JRScLBpc2BD6farddg3e KMD 6740.09632448, REVS 16.99805655 +# REq67wAMhhyUD6JRScLBpc2BD6farddg3e KMD 6740.09632448 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REq67wAMhhyUD6JRScLBpc2BD6farddg3e\",\"symbol\":\"KMD\"}" +echo "6740.09632448 <- expected amount REq67wAMhhyUD6JRScLBpc2BD6farddg3e" + +# RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s KMD 22492.75115633, REVS 236.96348849 +# RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s KMD 22492.75115633 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s\",\"symbol\":\"KMD\"}" +echo "22492.75115633 <- expected amount RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s" + +# RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S KMD 15493.04399000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S\",\"symbol\":\"KMD\"}" +echo "15493.04399000 <- expected amount RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S" + +# RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m KMD 1140.36550287 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m\",\"symbol\":\"KMD\"}" +echo "1140.36550287 <- expected amount RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m" + +# RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58 KMD 1575.45572767 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58\",\"symbol\":\"KMD\"}" +echo "1575.45572767 <- expected amount RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58" + +# RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU KMD 14524.72874062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU\",\"symbol\":\"KMD\"}" +echo "14524.72874062 <- expected amount RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU" + +# RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu KMD 87148.37244375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu\",\"symbol\":\"KMD\"}" +echo "87148.37244375 <- expected amount RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu" + +# R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W KMD 95237.89695894 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W\",\"symbol\":\"KMD\"}" +echo "95237.89695894 <- expected amount R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 3.13113297 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" +echo "3.13113297 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja KMD 1659.54315667 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja\",\"symbol\":\"KMD\"}" +echo "1659.54315667 <- expected amount RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja" + +# RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj KMD 8643.80014966 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj\",\"symbol\":\"KMD\"}" +echo "8643.80014966 <- expected amount RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj" + +# RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D KMD 553085.02723026 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D\",\"symbol\":\"KMD\"}" +echo "553085.02723026 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D" + +# RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP KMD 1946.54604690 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP\",\"symbol\":\"KMD\"}" +echo "1946.54604690 <- expected amount RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP" + +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 6165.95629088, REVS 18.51019595 +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 6165.95629088 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk\",\"symbol\":\"KMD\"}" +echo "6165.95629088 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk" + +# RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK KMD 11144.67547452 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK\",\"symbol\":\"KMD\"}" +echo "11144.67547452 <- expected amount RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK" + +# RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es KMD 6944.64226884 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es\",\"symbol\":\"KMD\"}" +echo "6944.64226884 <- expected amount RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es" + +# RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e KMD 29049.45748125 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e\",\"symbol\":\"KMD\"}" +echo "29049.45748125 <- expected amount RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 14070.80002269 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct\",\"symbol\":\"KMD\"}" +echo "14070.80002269 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd KMD 25865.73214606 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd\",\"symbol\":\"KMD\"}" +echo "25865.73214606 <- expected amount RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd" + +# RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU KMD 20625.11481168 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU\",\"symbol\":\"KMD\"}" +echo "20625.11481168 <- expected amount RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU" + +# RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr KMD 306877.42641191 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr\",\"symbol\":\"KMD\"}" +echo "306877.42641191 <- expected amount RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr" + +# RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY KMD 230865.18565552, REVS 4582.57000000 +# RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY KMD 230865.18565552 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY\",\"symbol\":\"KMD\"}" +echo "230865.18565552 <- expected amount RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY" + +# RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt KMD 1548.52974680 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt\",\"symbol\":\"KMD\"}" +echo "1548.52974680 <- expected amount RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 2651.62370624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" +echo "2651.62370624 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a KMD 13266.57413441, REVS 46.55982083 +# RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a KMD 13266.57413441 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a\",\"symbol\":\"KMD\"}" +echo "13266.57413441 <- expected amount RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a" + +# RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz KMD 2182.61555865 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz\",\"symbol\":\"KMD\"}" +echo "2182.61555865 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz" + +# RXoox1yRGdHhYa5scahD734qajAAQiNKDf KMD 12541.20725926 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXoox1yRGdHhYa5scahD734qajAAQiNKDf\",\"symbol\":\"KMD\"}" +echo "12541.20725926 <- expected amount RXoox1yRGdHhYa5scahD734qajAAQiNKDf" + +# RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY KMD 129183.61336863, REVS 2562.48000000 +# RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY KMD 129183.61336863 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY\",\"symbol\":\"KMD\"}" +echo "129183.61336863 <- expected amount RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY" + +# RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr KMD 1985.04626121 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr\",\"symbol\":\"KMD\"}" +echo "1985.04626121 <- expected amount RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr" + +# RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu KMD 15880.37008974 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu\",\"symbol\":\"KMD\"}" +echo "15880.37008974 <- expected amount RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu" + +# RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo KMD 1578.13191862 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo\",\"symbol\":\"KMD\"}" +echo "1578.13191862 <- expected amount RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo" + +# RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad KMD 774.65219950 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad\",\"symbol\":\"KMD\"}" +echo "774.65219950 <- expected amount RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad" + diff --git a/iguana/tests/KMD.batch5.txids b/iguana/tests/KMD.batch5.txids new file mode 100644 index 000000000..bb3f7b656 --- /dev/null +++ b/iguana/tests/KMD.batch5.txids @@ -0,0 +1,130 @@ +671839f2ab21a621aaa25887ea401b5d4f3fdcfa2d2d1437ec7c30ad380f7f8e +19343.06542151 <- expected amount RRpHETjTPAfUExD1Bq9tnc6dhvpfsZFLi4 +c18addc60b0510f2896f27e33d7b83e4a5a9251393e94fc740008f15ed5501df +3873.26099750 <- expected amount RCkuABdHjmYJu9DqBhyUrBLma3UfGJTxXy +7e8452c65da4aaea9097d09010014030d7014283cfc78434affb67d0f0212db6 +6971.86979550 <- expected amount RCQ6Updk7CusynB1qEEs7nkRJUvChNp8Yq +53ddded19eebb4e5e2dbeba31dd9f5081f0d8fb3972892b17d8c33c8d0fd72ef +4912.04612506 <- expected amount RFquxwxMoADidBiLLFgoBvNoAotdXPGXgU +2985f9d7143580038bef79728bfe77e827ecc7366f809f92c33e6d31289b9e3e +27887.47918200 <- expected amount RFVnbATCEBhw1ZtXiJ353pYc1WCAY5Gvs6 +62ada7fc582dd59afa2c48a79796c50861a07fd28d3488640440bd79c1bbf7db +1452.47287406 <- expected amount RMNjQroPTdw6FDXvztV2QZnyCChJcuM7ix +25b1b8cac0d9f019c59727211d34f72bc054991837b93c527f36106f3cc05be2 +852.11741945 <- expected amount RAVWPDpje2fFtmm4m9LJ8whe28rLT1ahHW +775a78c73b9bf95b8f018b047aa053be81f49a17cbe5bb04b1b32e5dc061ba6a +1625.48610260 <- expected amount RC33WTbwtTrYXp6fdnX4waie6kbYBC4UTQ +ece870032a6382cae538c619bf126afede64bfc61929fd95d54e15b05c5fa250 +5228.90234661 <- expected amount RAFCAAxLFfTbLS7tHXrEMfasQVFFZAVj19 +cd1c3c0896c2a57a29b9adce2aa890a60137f0f00137e3e4f5b8eb47ba60ae56 +6045.00703151 <- expected amount RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y +c327a19c1596f224121a73d4f73ada584942691d07b4c3ba6ce20511c29fed17 +10521.01631272 <- expected amount RL5EuMVC878LpRvM7bmhvkD3v8GMtkrnsZ +7ed7bed2a5e7f4adc74004a46ca85f4b0e44342fc6ee42fe40c975bb943091e4 +2902.52496000 <- expected amount RFG72C8qkjEedduoB4kgSjZvtKFSNJpKMc +065404be877363994e606a1c56ca6cb499fa51a61d2c7e81e4bdae13fc0c53c9 +35570.77185561 <- expected amount RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 +489e0f36b6eff9d5e0ee0e4c6a42c2fc8926e7ec8f2542177aaefc408399afd1 +291.86077302 <- expected amount RPxZS6VUMVQ882fmxCES5q6xQFj8ABpMVM +e36d4886c94697d53477f2c4b3a1d2d6cd6b877c37df4037e597e50e8493d493 +19366.30498750 <- expected amount RJzkWn3SH2yk5NcQxjF2E4DbqTC5XhLpva +e398ccd36730ee0091c520705f04463d01438f64be0569977d9b41f11fe83095 +722.28571081 <- expected amount RKwvsAhZ5hRrdXoRMyjXVqu1N7rnjGhu7S +2c223ff098c632a444046356f8e0fa677f8ab69a7e7491031328ffd7daa8ca41 +416761.10163094 <- expected amount RHt5mSvqCTDkwEJhF2jQ7uAAThkt5WaM2x +b94905d04a004c9d53ec64acfda2251c00a2cfcba840682f75fcbe0162e56be6 +9767.05422136 <- expected amount RKg3D8GzPcBYsRaVuKfEahBDAdv8D1rVjH +a749ff1f14c0b724871dc55e5b1dc2460a82f6bc7bacef283094881caf6030c3 +1891.37303787 <- expected amount RGur4rnZTJRSdAjU5avya5EA57K5izbv9b +2b806ace63b634089a37159a3012ba1157f28f7fbb9cbadf0b8bbdee5524308c +17009.37539559 <- expected amount REzUa4zYVZychBN6GT1vRrQ1k7VEa8zb91 +1a15d425625378de4da79ebcadc7a8ed23d3e5b10cd1dc3f69e12655ec852fc9 +1241.69290122 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u +3bbdb56a2708ee1f7fae191625a7bbe143a1b14a77c5e3dece305ac27d64b421 +852.11741945 <- expected amount RC1MxfkT36U6ifcaE2U25yHvc7u4W2yFZM +7ab5fe203ae7b23957ca398484a9eb6279c0f9bc68c0d3dd0bc2c0aab8cc9d77 +195982.90265756 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni +f9565a6da32ceb99dc15c6f76bf9c2ba14f6f97f9507959559423fda957b8535 +9117.34456938 <- expected amount RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY +4ff416b520100c3ff835ad5609ab3e693627507ce793946acaf47a8ce5369f5e +11842.49549985 <- expected amount RGjy7Co3moKAdBWr1kXe6V9T1keDHbjhiU +26ea54eed2119c46477b15e6942d421b4650ced130b5f87b5de93c8173abcdba +861.17744171 <- expected amount RXjdDrkbmgEVBviV8PhnqASupSjPLubY5H +01079e344e33c318a09c58030d2f6a2cd504163a3b93f3140ce8deb77def3d73 +30792.42493012 <- expected amount RHrb9VZXMq4D4GGjwpmsW9U5ATwFA6CRYg +291e269fa045a3cfabe190840e2ad1334fd4d06faa1587ce24a29a9cec7ed452 +9683.15249375 <- expected amount RNXYQyJnopoYEMuq6QEvuJTAAM6oLspGtN +085e0e1c032548f1ac48a826377d8ed7d0052ecf430ada7f805485aa0597028f +6641.51666395 <- expected amount RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ +97ae90ac6609753583ec70ed0a74a775384f11a1df13250035da31340374eac2 +972.76143201 <- expected amount RFWr9v55i1zUEa1iH7J1Pz1DyUPbZ8HVfE +0c28a02c2e3f2294685b6beaf07c114ef10f9c02bea487e71a233c23873ae5a6 +7967.93037537 <- expected amount RDdUQ5t6SYYGZUdAxBk5i7QdTWvzAshxNZ +36b5dc3bca899b5cc5fee912cb921d55ad4d436e66c1d08897a9fcd00622f31e +2518.25812688 <- expected amount RX4Gzaf4W19vdRWPZxgyUz9mMvMyJsGEiM +104748914a14191cf2a662861d57f3cbc4843a22a53a8fea5f545a6dd630d264 +28809.31529940 <- expected amount RSjXG6NziGU5Qp25UTLgP6SsnTjrTfcqy5 +648e495d292e994d1ecc748af1c6405e7c7a5284d9b921c62da3b2e52142fc1f +6740.09632448 <- expected amount REq67wAMhhyUD6JRScLBpc2BD6farddg3e +f2cc6ee905fca8aad91e373df6f1fec47c49d451ba9017de04f119064936d44e +22492.75115633 <- expected amount RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s +e25f692ffca4b53e2452afecdc0fe0435fd609ad708cb60f77cc9a8857d5c1ca +15493.04399000 <- expected amount RGWCMt87wKwK4MVaAUj9EAnpsniVyuTp6S +aeb5a2f1411fb6b29a54a0f48570e1a0eb6a61e47e82f5ee4e29a2eb97138e3b +1140.36550287 <- expected amount RFWgzBtdFELPNZiA47x1NGu7f1HPmRdf3m +d501fec2932177ae06fcf1f3c15168ca50ecf1102107034ec1d88c8d10316992 +1575.45572767 <- expected amount RDcrAkGEAnUCznAfbEbRqjdJAQEu362k58 +c599f1909f31c77a72586ef345ad59a0aa2d6db7cdf4f26ccf1944ad86ad31db +14524.72874062 <- expected amount RAoJYgpXxPm2s1hvDkiqXz85yNPCkhsTvU +9df47b44440e21cbf991351f28b9ad7c851e09bf90485e2b22b7c12e737613a9 +87148.37244375 <- expected amount RCevKsK6KqdDrCTvt6WnGeFpAF9zKzRUmu +77710eacb96e013294415b40a5c1899a1501cf2a56700190a9ea8bc779ef6573 +95237.89695894 <- expected amount R9Xi2PKLWLA5d2V13qhqoqt3vjxGWfKH2W +4d36d166d161174f096725951acdf2ff7263a14ee998ecc9dfffbbb72c199d8d +3.13113297 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 +650eec54b8a77318693f1bc30101f2c33ec763ae85ef9ed5b044167de76ca06c +1659.54315667 <- expected amount RSMhR3aV7yc7LaqBmtcLgZ2SxkHquvaUja +f757e2c700a284bde5d17a971e0b8cc7202f88ab2cc9a8fa1cfc791b029190b5 +8643.80014966 <- expected amount RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj +6ba72bac45bd935d79b4f33c42d319f15b0c4e72a650cff625563126d8faac87 +553085.02723026 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D +290c608e966169e442a2c84fdb4d86e2bb85ed4e7c4a9a1370fd42d777369e63 +1946.54604690 <- expected amount RQ4kgWZng7P9ZU7wAjSf3BQxih6iTdKZtP +ec9a7c19dfb79fbd735bc8bd4a107bad5781e063717bce7d3c069b11772df3e1 +6165.95629088 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk +d86161a40821b03f118c92fbce0c0a152aa42fd5d59c1a21f2ad966c8fe41185 +11144.67547452 <- expected amount RRYeo7NkjrHqhWBpCtAPZUW6aCWZatD1qK +efd52feec4651ddd206c0bfd64a4bab6a3d935b70c0f819b50e005f8bcf125f4 +6944.64226884 <- expected amount RRTks3iwSe4oR3UDmRfGszcNcfAv6Rb5es +416bad294d078583e7fdb5add11f7c9973a0a16b963ac1050844703e16e070c1 +29049.45748125 <- expected amount RDE5pyXfNVdbyJpy3mxV3EfBLMG9PyVk5e +e1e7e0a58e522106fe4d0f88948dd5f76adfe8e3029b8da0914d9db7b5e162e7 +14070.80002269 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct +6ca3813ebbff042d97357b6e52fda029aa2976afd837736a7c8710cc167c2ead +25865.73214606 <- expected amount RG5GXpHFBJYkH3WkyJZ6QCrT9Tr9LDvddd +8ea4abdb447455b4e116d9ebbfb4b850d9579058f2b6fe9cf8e4efb3a3532a83 +20625.11481168 <- expected amount RYCfN826eBPZ1hmkUdTjG2Bn6byASCN3EU +e5fd8f8ef3b0a235c4c70d4b8c04075ec86efbec24f66637a8b1dfcfa93df790 +306877.42641191 <- expected amount RHDe5bouzmteaF1ZnWgfNG2FbKrGHHmHQr +25eef7401f610c0ea22c5dd91a918f051c8eac744dcd5cffa2281299888b0460 +230865.18565552 <- expected amount RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY +c428b116e25dd9ee1dfd56745bbf016a4b5d02a879834fd1fd5e087bd1f4158f +1548.52974680 <- expected amount RG9CAC4m1H9giJxcVW8s7zhFVmy3EAEFAt +a16520723826ae6aa4915eb4ec0e5ca050aa76ca0692a712101ea36efdb96a87 +2651.62370624 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 +399d596a0bfa0bb4e96439e7fcb431ef9a1f81ebc25cf14a80ce34b2894ea5a1 +13266.57413441 <- expected amount RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a +041d5206cb2f2cf1d9cc7af985c970393f24b4a3f3d19b20762c62962c441e48 +2182.61555865 <- expected amount RLyaf3XgjHruSeJd4oj83E8btck7kYPmVz +43e0fb29858b1319f6118c3cb056016de52f46f090aa5d59e51c4357d1d45b04 +12541.20725926 <- expected amount RXoox1yRGdHhYa5scahD734qajAAQiNKDf +e7ca53552f94e48509aaa7fa724d38fec3c774a47ac86ebae849a2b70cffe65d +129183.61336863 <- expected amount RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY +c003dd75a95918962cb1e5f3360e351c0527d561381ec5fb53391cc7385e1c99 +1985.04626121 <- expected amount RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr +fcb63dd4ff36a485c4ca7e7d169b97e71b7c2fbcb3de83b7d27232f9fbe717a6 +15880.37008974 <- expected amount RU1ZM55ux8PTTFa1uF8GizmQEBWj58YdKu +6016abb3a53bf01865ab79572b78db6ed36e5af5968b0c25945652e7ded85249 +1578.13191862 <- expected amount RQ95BQJrkhsLySpGpr2PFLHmBZBmLtjsyo +1f71f4d543a4a8254523994fa521f8772f67d5c0dc57844a54274b9a21bf1329 +774.65219950 <- expected amount RXRgFV97Y6aPAQQm2RY5fed4AB9zTKRTad diff --git a/iguana/tests/KMD.batch6 b/iguana/tests/KMD.batch6 new file mode 100755 index 000000000..e1a23e5b1 --- /dev/null +++ b/iguana/tests/KMD.batch6 @@ -0,0 +1,303 @@ +sleep 99999 +# RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk KMD 8908.50029425 +./komodo-cli sendtoaddress RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk 8908.50029425 +sleep 3 +echo "8908.50029425 <- expected amount RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk" + +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 2306.15801572 +./komodo-cli sendtoaddress RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf 2306.15801572 +sleep 3 +echo "2306.15801572 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf" + +# RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv KMD 1368.88526791 +./komodo-cli sendtoaddress RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv 1368.88526791 +sleep 3 +echo "1368.88526791 <- expected amount RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv" + +# RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ KMD 106.39636971 +./komodo-cli sendtoaddress RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ 106.39636971 +sleep 3 +echo "106.39636971 <- expected amount RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ" + +# RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie KMD 32892.15837201 +./komodo-cli sendtoaddress RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie 32892.15837201 +sleep 3 +echo "32892.15837201 <- expected amount RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie" + +# RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V KMD 153.99848359 +./komodo-cli sendtoaddress RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V 153.99848359 +sleep 3 +echo "153.99848359 <- expected amount RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V" + +# RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56 KMD 250.09618515 +./komodo-cli sendtoaddress RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56 250.09618515 +sleep 3 +echo "250.09618515 <- expected amount RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56" + +# RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei KMD 2285.12762738 +./komodo-cli sendtoaddress RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei 2285.12762738 +sleep 3 +echo "2285.12762738 <- expected amount RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei" + +# RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC KMD 1660.51377862 +./komodo-cli sendtoaddress RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC 1660.51377862 +sleep 3 +echo "1660.51377862 <- expected amount RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC" + +# RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D KMD 15065.53304887 +./komodo-cli sendtoaddress RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D 15065.53304887 +sleep 3 +echo "15065.53304887 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 2667.18064500 +./komodo-cli sendtoaddress RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut 2667.18064500 +sleep 3 +echo "2667.18064500 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda KMD 24981.55183756 +./komodo-cli sendtoaddress RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda 24981.55183756 +sleep 3 +echo "24981.55183756 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda" + +# REvMg538sSpHUdRyCV1jJDjT63XePKLwkh KMD 1334.49334406 +./komodo-cli sendtoaddress REvMg538sSpHUdRyCV1jJDjT63XePKLwkh 1334.49334406 +sleep 3 +echo "1334.49334406 <- expected amount REvMg538sSpHUdRyCV1jJDjT63XePKLwkh" + +# RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF KMD 10773.51776054 +./komodo-cli sendtoaddress RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF 10773.51776054 +sleep 3 +echo "10773.51776054 <- expected amount RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF" + +# RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs KMD 607.46792378 +./komodo-cli sendtoaddress RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs 607.46792378 +sleep 3 +echo "607.46792378 <- expected amount RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs" + +# RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS KMD 2028.62052490 +./komodo-cli sendtoaddress RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS 2028.62052490 +sleep 3 +echo "2028.62052490 <- expected amount RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS" + +# RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W KMD 40431.89788465 +./komodo-cli sendtoaddress RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W 40431.89788465 +sleep 3 +echo "40431.89788465 <- expected amount RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W" + +# RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9 KMD 24325.33313227 +./komodo-cli sendtoaddress RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9 24325.33313227 +sleep 3 +echo "24325.33313227 <- expected amount RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9" + +# RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA KMD 26784.99417167 +./komodo-cli sendtoaddress RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA 26784.99417167 +sleep 3 +echo "26784.99417167 <- expected amount RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA" + +# RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc KMD 200.88047000 +./komodo-cli sendtoaddress RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc 200.88047000 +sleep 3 +echo "200.88047000 <- expected amount RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc" + +# RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw KMD 942.22930620 +./komodo-cli sendtoaddress RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw 942.22930620 +sleep 3 +echo "942.22930620 <- expected amount RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 9295.82639400 +./komodo-cli sendtoaddress RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey KMD 1859.16527880 +./komodo-cli sendtoaddress RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey 1859.16527880 +sleep 3 +echo "1859.16527880 <- expected amount RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey" + +# RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR KMD 726.21002139 +./komodo-cli sendtoaddress RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR 726.21002139 +sleep 3 +echo "726.21002139 <- expected amount RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR" + +# RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz KMD 121577.72836165 +./komodo-cli sendtoaddress RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz 121577.72836165 +sleep 3 +echo "121577.72836165 <- expected amount RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz" + +# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 2511.34619763 +./komodo-cli sendtoaddress RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 2511.34619763 +sleep 3 +echo "2511.34619763 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1" + +# RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc KMD 23246.75713145, REVS 66.39295712 +# RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc KMD 23246.75713145 +./komodo-cli sendtoaddress RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc 23246.75713145 +sleep 3 +echo "23246.75713145 <- expected amount RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc" + +# REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L KMD 83333.21036121 +./komodo-cli sendtoaddress REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L 83333.21036121 +sleep 3 +echo "83333.21036121 <- expected amount REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L" + +# RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4 KMD 5325.73387156 +./komodo-cli sendtoaddress RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4 5325.73387156 +sleep 3 +echo "5325.73387156 <- expected amount RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4" + +# RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8 KMD 938.92347308 +./komodo-cli sendtoaddress RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8 938.92347308 +sleep 3 +echo "938.92347308 <- expected amount RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8" + +# RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW KMD 484157.62468750 +./komodo-cli sendtoaddress RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW 484157.62468750 +sleep 3 +echo "484157.62468750 <- expected amount RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW" + +# RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2 KMD 9683.15249375 +./komodo-cli sendtoaddress RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2" + +# RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH KMD 8908.50029425 +./komodo-cli sendtoaddress RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH 8908.50029425 +sleep 3 +echo "8908.50029425 <- expected amount RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH" + +# RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA KMD 502.18197380 +./komodo-cli sendtoaddress RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA 502.18197380 +sleep 3 +echo "502.18197380 <- expected amount RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 17002.74354061, REVS 278.99000000 +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 17002.74354061 +./komodo-cli sendtoaddress RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW 17002.74354061 +sleep 3 +echo "17002.74354061 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J KMD 149751.00241450 +./komodo-cli sendtoaddress RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J 149751.00241450 +sleep 3 +echo "149751.00241450 <- expected amount RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J" + +# RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe KMD 96831.52493750 +./komodo-cli sendtoaddress RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe 96831.52493750 +sleep 3 +echo "96831.52493750 <- expected amount RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe" + +# RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh KMD 18021.41836725 +./komodo-cli sendtoaddress RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh 18021.41836725 +sleep 3 +echo "18021.41836725 <- expected amount RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh" + +# RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk KMD 41017.83396352 +./komodo-cli sendtoaddress RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk 41017.83396352 +sleep 3 +echo "41017.83396352 <- expected amount RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk" + +# R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic KMD 13263.41995905 +./komodo-cli sendtoaddress R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic 13263.41995905 +sleep 3 +echo "13263.41995905 <- expected amount R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic" + +# RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN KMD 8982.68540439 +./komodo-cli sendtoaddress RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN 8982.68540439 +sleep 3 +echo "8982.68540439 <- expected amount RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN" + +# RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL KMD 12356.73789711, REVS 112.00000000 +# RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL KMD 12356.73789711 +./komodo-cli sendtoaddress RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL 12356.73789711 +sleep 3 +echo "12356.73789711 <- expected amount RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 12561.43380413 +./komodo-cli sendtoaddress RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct 12561.43380413 +sleep 3 +echo "12561.43380413 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6 KMD 4453.35929709 +./komodo-cli sendtoaddress RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6 4453.35929709 +sleep 3 +echo "4453.35929709 <- expected amount RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6" + +# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 4521.29210647 +./komodo-cli sendtoaddress RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw 4521.29210647 +sleep 3 +echo "4521.29210647 <- expected amount RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw" + +# RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv KMD 11653.72856174 +./komodo-cli sendtoaddress RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv 11653.72856174 +sleep 3 +echo "11653.72856174 <- expected amount RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv" + +# RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR KMD 1561.74292091 +./komodo-cli sendtoaddress RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR 1561.74292091 +sleep 3 +echo "1561.74292091 <- expected amount RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR" + +# RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv KMD 25107.55827068 +./komodo-cli sendtoaddress RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv 25107.55827068 +sleep 3 +echo "25107.55827068 <- expected amount RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv" + +# RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt KMD 391.52338368, REVS 7.76943254 +# RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt KMD 391.52338368 +./komodo-cli sendtoaddress RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt 391.52338368 +sleep 3 +echo "391.52338368 <- expected amount RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt" + +# RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx KMD 2212.41539458 +./komodo-cli sendtoaddress RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx 2212.41539458 +sleep 3 +echo "2212.41539458 <- expected amount RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx" + +# RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5 KMD 12079.07428158 +./komodo-cli sendtoaddress RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5 12079.07428158 +sleep 3 +echo "12079.07428158 <- expected amount RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5" + +# RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh KMD 2323.95659850 +./komodo-cli sendtoaddress RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh 2323.95659850 +sleep 3 +echo "2323.95659850 <- expected amount RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh" + +# RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r KMD 682.83148523, REVS 13.54307355 +# RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r KMD 682.83148523 +./komodo-cli sendtoaddress RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r 682.83148523 +sleep 3 +echo "682.83148523 <- expected amount RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r" + +# RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3 KMD 48415.76246875 +./komodo-cli sendtoaddress RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3" + +# RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD KMD 8133.84809475 +./komodo-cli sendtoaddress RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD 8133.84809475 +sleep 3 +echo "8133.84809475 <- expected amount RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD" + +# RAaszCNodXXu9rJL6qqVMZDykXncDecTMS KMD 693.08132289 +./komodo-cli sendtoaddress RAaszCNodXXu9rJL6qqVMZDykXncDecTMS 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS" + +# RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57 KMD 1773.66877470 +./komodo-cli sendtoaddress RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57 1773.66877470 +sleep 3 +echo "1773.66877470 <- expected amount RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57" + +# RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa KMD 2971.54458972 +./komodo-cli sendtoaddress RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa 2971.54458972 +sleep 3 +echo "2971.54458972 <- expected amount RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa" + +# RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR KMD 3351.00027124 +./komodo-cli sendtoaddress RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR 3351.00027124 +sleep 3 +echo "3351.00027124 <- expected amount RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR" + + +# total KMD 1452257.08309448 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch6.importaddress b/iguana/tests/KMD.batch6.importaddress new file mode 100755 index 000000000..a485650fc --- /dev/null +++ b/iguana/tests/KMD.batch6.importaddress @@ -0,0 +1,299 @@ +# RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk\",\"symbol\":\"KMD\"}" # 8908.50029425 +sleep 3 +echo "8908.50029425 <- expected amount RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk" + +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 2306.15801572 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf\",\"symbol\":\"KMD\"}" # 2306.15801572 +sleep 3 +echo "2306.15801572 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf" + +# RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv KMD 1368.88526791 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv\",\"symbol\":\"KMD\"}" # 1368.88526791 +sleep 3 +echo "1368.88526791 <- expected amount RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv" + +# RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ KMD 106.39636971 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ\",\"symbol\":\"KMD\"}" # 106.39636971 +sleep 3 +echo "106.39636971 <- expected amount RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ" + +# RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie KMD 32892.15837201 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie\",\"symbol\":\"KMD\"}" # 32892.15837201 +sleep 3 +echo "32892.15837201 <- expected amount RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie" + +# RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V KMD 153.99848359 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V\",\"symbol\":\"KMD\"}" # 153.99848359 +sleep 3 +echo "153.99848359 <- expected amount RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V" + +# RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56 KMD 250.09618515 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56\",\"symbol\":\"KMD\"}" # 250.09618515 +sleep 3 +echo "250.09618515 <- expected amount RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56" + +# RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei KMD 2285.12762738 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei\",\"symbol\":\"KMD\"}" # 2285.12762738 +sleep 3 +echo "2285.12762738 <- expected amount RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei" + +# RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC KMD 1660.51377862 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC\",\"symbol\":\"KMD\"}" # 1660.51377862 +sleep 3 +echo "1660.51377862 <- expected amount RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC" + +# RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D KMD 15065.53304887 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D\",\"symbol\":\"KMD\"}" # 15065.53304887 +sleep 3 +echo "15065.53304887 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 2667.18064500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" # 2667.18064500 +sleep 3 +echo "2667.18064500 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda KMD 24981.55183756 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda\",\"symbol\":\"KMD\"}" # 24981.55183756 +sleep 3 +echo "24981.55183756 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda" + +# REvMg538sSpHUdRyCV1jJDjT63XePKLwkh KMD 1334.49334406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REvMg538sSpHUdRyCV1jJDjT63XePKLwkh\",\"symbol\":\"KMD\"}" # 1334.49334406 +sleep 3 +echo "1334.49334406 <- expected amount REvMg538sSpHUdRyCV1jJDjT63XePKLwkh" + +# RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF KMD 10773.51776054 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF\",\"symbol\":\"KMD\"}" # 10773.51776054 +sleep 3 +echo "10773.51776054 <- expected amount RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF" + +# RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs KMD 607.46792378 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs\",\"symbol\":\"KMD\"}" # 607.46792378 +sleep 3 +echo "607.46792378 <- expected amount RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs" + +# RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS KMD 2028.62052490 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS\",\"symbol\":\"KMD\"}" # 2028.62052490 +sleep 3 +echo "2028.62052490 <- expected amount RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS" + +# RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W KMD 40431.89788465 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W\",\"symbol\":\"KMD\"}" # 40431.89788465 +sleep 3 +echo "40431.89788465 <- expected amount RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W" + +# RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9 KMD 24325.33313227 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9\",\"symbol\":\"KMD\"}" # 24325.33313227 +sleep 3 +echo "24325.33313227 <- expected amount RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9" + +# RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA KMD 26784.99417167 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA\",\"symbol\":\"KMD\"}" # 26784.99417167 +sleep 3 +echo "26784.99417167 <- expected amount RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA" + +# RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc KMD 200.88047000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc\",\"symbol\":\"KMD\"}" # 200.88047000 +sleep 3 +echo "200.88047000 <- expected amount RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc" + +# RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw KMD 942.22930620 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw\",\"symbol\":\"KMD\"}" # 942.22930620 +sleep 3 +echo "942.22930620 <- expected amount RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" # 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey KMD 1859.16527880 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey\",\"symbol\":\"KMD\"}" # 1859.16527880 +sleep 3 +echo "1859.16527880 <- expected amount RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey" + +# RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR KMD 726.21002139 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR\",\"symbol\":\"KMD\"}" # 726.21002139 +sleep 3 +echo "726.21002139 <- expected amount RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR" + +# RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz KMD 121577.72836165 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz\",\"symbol\":\"KMD\"}" # 121577.72836165 +sleep 3 +echo "121577.72836165 <- expected amount RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz" + +# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 2511.34619763 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1\",\"symbol\":\"KMD\"}" # 2511.34619763 +sleep 3 +echo "2511.34619763 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1" + +# RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc KMD 23246.75713145, REVS 66.39295712 +# RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc KMD 23246.75713145 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc\",\"symbol\":\"KMD\"}" # 23246.75713145 +sleep 3 +echo "23246.75713145 <- expected amount RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc" + +# REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L KMD 83333.21036121 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L\",\"symbol\":\"KMD\"}" # 83333.21036121 +sleep 3 +echo "83333.21036121 <- expected amount REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L" + +# RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4 KMD 5325.73387156 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4\",\"symbol\":\"KMD\"}" # 5325.73387156 +sleep 3 +echo "5325.73387156 <- expected amount RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4" + +# RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8 KMD 938.92347308 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8\",\"symbol\":\"KMD\"}" # 938.92347308 +sleep 3 +echo "938.92347308 <- expected amount RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8" + +# RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW KMD 484157.62468750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW\",\"symbol\":\"KMD\"}" # 484157.62468750 +sleep 3 +echo "484157.62468750 <- expected amount RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW" + +# RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2 KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2" + +# RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH\",\"symbol\":\"KMD\"}" # 8908.50029425 +sleep 3 +echo "8908.50029425 <- expected amount RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH" + +# RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA KMD 502.18197380 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA\",\"symbol\":\"KMD\"}" # 502.18197380 +sleep 3 +echo "502.18197380 <- expected amount RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 17002.74354061, REVS 278.99000000 +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 17002.74354061 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"KMD\"}" # 17002.74354061 +sleep 3 +echo "17002.74354061 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J KMD 149751.00241450 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J\",\"symbol\":\"KMD\"}" # 149751.00241450 +sleep 3 +echo "149751.00241450 <- expected amount RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J" + +# RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe\",\"symbol\":\"KMD\"}" # 96831.52493750 +sleep 3 +echo "96831.52493750 <- expected amount RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe" + +# RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh KMD 18021.41836725 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh\",\"symbol\":\"KMD\"}" # 18021.41836725 +sleep 3 +echo "18021.41836725 <- expected amount RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh" + +# RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk KMD 41017.83396352 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk\",\"symbol\":\"KMD\"}" # 41017.83396352 +sleep 3 +echo "41017.83396352 <- expected amount RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk" + +# R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic KMD 13263.41995905 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic\",\"symbol\":\"KMD\"}" # 13263.41995905 +sleep 3 +echo "13263.41995905 <- expected amount R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic" + +# RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN KMD 8982.68540439 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN\",\"symbol\":\"KMD\"}" # 8982.68540439 +sleep 3 +echo "8982.68540439 <- expected amount RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN" + +# RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL KMD 12356.73789711, REVS 112.00000000 +# RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL KMD 12356.73789711 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL\",\"symbol\":\"KMD\"}" # 12356.73789711 +sleep 3 +echo "12356.73789711 <- expected amount RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 12561.43380413 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct\",\"symbol\":\"KMD\"}" # 12561.43380413 +sleep 3 +echo "12561.43380413 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6 KMD 4453.35929709 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6\",\"symbol\":\"KMD\"}" # 4453.35929709 +sleep 3 +echo "4453.35929709 <- expected amount RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6" + +# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 4521.29210647 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw\",\"symbol\":\"KMD\"}" # 4521.29210647 +sleep 3 +echo "4521.29210647 <- expected amount RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw" + +# RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv KMD 11653.72856174 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv\",\"symbol\":\"KMD\"}" # 11653.72856174 +sleep 3 +echo "11653.72856174 <- expected amount RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv" + +# RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR KMD 1561.74292091 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR\",\"symbol\":\"KMD\"}" # 1561.74292091 +sleep 3 +echo "1561.74292091 <- expected amount RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR" + +# RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv KMD 25107.55827068 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv\",\"symbol\":\"KMD\"}" # 25107.55827068 +sleep 3 +echo "25107.55827068 <- expected amount RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv" + +# RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt KMD 391.52338368, REVS 7.76943254 +# RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt KMD 391.52338368 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt\",\"symbol\":\"KMD\"}" # 391.52338368 +sleep 3 +echo "391.52338368 <- expected amount RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt" + +# RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx KMD 2212.41539458 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx\",\"symbol\":\"KMD\"}" # 2212.41539458 +sleep 3 +echo "2212.41539458 <- expected amount RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx" + +# RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5 KMD 12079.07428158 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5\",\"symbol\":\"KMD\"}" # 12079.07428158 +sleep 3 +echo "12079.07428158 <- expected amount RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5" + +# RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh KMD 2323.95659850 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh\",\"symbol\":\"KMD\"}" # 2323.95659850 +sleep 3 +echo "2323.95659850 <- expected amount RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh" + +# RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r KMD 682.83148523, REVS 13.54307355 +# RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r KMD 682.83148523 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r\",\"symbol\":\"KMD\"}" # 682.83148523 +sleep 3 +echo "682.83148523 <- expected amount RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r" + +# RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3 KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3\",\"symbol\":\"KMD\"}" # 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3" + +# RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD KMD 8133.84809475 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD\",\"symbol\":\"KMD\"}" # 8133.84809475 +sleep 3 +echo "8133.84809475 <- expected amount RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD" + +# RAaszCNodXXu9rJL6qqVMZDykXncDecTMS KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS" + +# RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57 KMD 1773.66877470 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57\",\"symbol\":\"KMD\"}" # 1773.66877470 +sleep 3 +echo "1773.66877470 <- expected amount RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57" + +# RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa KMD 2971.54458972 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa\",\"symbol\":\"KMD\"}" # 2971.54458972 +sleep 3 +echo "2971.54458972 <- expected amount RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa" + +# RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR KMD 3351.00027124 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR\",\"symbol\":\"KMD\"}" # 3351.00027124 +sleep 3 +echo "3351.00027124 <- expected amount RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR" diff --git a/iguana/tests/KMD.batch6.listunspent b/iguana/tests/KMD.batch6.listunspent new file mode 100755 index 000000000..dba872f05 --- /dev/null +++ b/iguana/tests/KMD.batch6.listunspent @@ -0,0 +1,240 @@ +# RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk\",\"symbol\":\"KMD\"}" +echo "8908.50029425 <- expected amount RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk" + +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 2306.15801572 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf\",\"symbol\":\"KMD\"}" +echo "2306.15801572 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf" + +# RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv KMD 1368.88526791 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv\",\"symbol\":\"KMD\"}" +echo "1368.88526791 <- expected amount RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv" + +# RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ KMD 106.39636971 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ\",\"symbol\":\"KMD\"}" +echo "106.39636971 <- expected amount RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ" + +# RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie KMD 32892.15837201 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie\",\"symbol\":\"KMD\"}" +echo "32892.15837201 <- expected amount RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie" + +# RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V KMD 153.99848359 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V\",\"symbol\":\"KMD\"}" +echo "153.99848359 <- expected amount RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V" + +# RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56 KMD 250.09618515 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56\",\"symbol\":\"KMD\"}" +echo "250.09618515 <- expected amount RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56" + +# RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei KMD 2285.12762738 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei\",\"symbol\":\"KMD\"}" +echo "2285.12762738 <- expected amount RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei" + +# RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC KMD 1660.51377862 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC\",\"symbol\":\"KMD\"}" +echo "1660.51377862 <- expected amount RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC" + +# RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D KMD 15065.53304887 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D\",\"symbol\":\"KMD\"}" +echo "15065.53304887 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D" + +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 2667.18064500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"KMD\"}" +echo "2667.18064500 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut" + +# RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda KMD 24981.55183756 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda\",\"symbol\":\"KMD\"}" +echo "24981.55183756 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda" + +# REvMg538sSpHUdRyCV1jJDjT63XePKLwkh KMD 1334.49334406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REvMg538sSpHUdRyCV1jJDjT63XePKLwkh\",\"symbol\":\"KMD\"}" +echo "1334.49334406 <- expected amount REvMg538sSpHUdRyCV1jJDjT63XePKLwkh" + +# RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF KMD 10773.51776054 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF\",\"symbol\":\"KMD\"}" +echo "10773.51776054 <- expected amount RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF" + +# RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs KMD 607.46792378 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs\",\"symbol\":\"KMD\"}" +echo "607.46792378 <- expected amount RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs" + +# RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS KMD 2028.62052490 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS\",\"symbol\":\"KMD\"}" +echo "2028.62052490 <- expected amount RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS" + +# RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W KMD 40431.89788465 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W\",\"symbol\":\"KMD\"}" +echo "40431.89788465 <- expected amount RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W" + +# RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9 KMD 24325.33313227 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9\",\"symbol\":\"KMD\"}" +echo "24325.33313227 <- expected amount RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9" + +# RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA KMD 26784.99417167 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA\",\"symbol\":\"KMD\"}" +echo "26784.99417167 <- expected amount RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA" + +# RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc KMD 200.88047000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc\",\"symbol\":\"KMD\"}" +echo "200.88047000 <- expected amount RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc" + +# RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw KMD 942.22930620 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw\",\"symbol\":\"KMD\"}" +echo "942.22930620 <- expected amount RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw" + +# RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ" + +# RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey KMD 1859.16527880 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey\",\"symbol\":\"KMD\"}" +echo "1859.16527880 <- expected amount RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey" + +# RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR KMD 726.21002139 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR\",\"symbol\":\"KMD\"}" +echo "726.21002139 <- expected amount RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR" + +# RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz KMD 121577.72836165 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz\",\"symbol\":\"KMD\"}" +echo "121577.72836165 <- expected amount RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz" + +# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 2511.34619763 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1\",\"symbol\":\"KMD\"}" +echo "2511.34619763 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1" + +# RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc KMD 23246.75713145, REVS 66.39295712 +# RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc KMD 23246.75713145 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc\",\"symbol\":\"KMD\"}" +echo "23246.75713145 <- expected amount RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc" + +# REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L KMD 83333.21036121 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L\",\"symbol\":\"KMD\"}" +echo "83333.21036121 <- expected amount REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L" + +# RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4 KMD 5325.73387156 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4\",\"symbol\":\"KMD\"}" +echo "5325.73387156 <- expected amount RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4" + +# RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8 KMD 938.92347308 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8\",\"symbol\":\"KMD\"}" +echo "938.92347308 <- expected amount RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8" + +# RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW KMD 484157.62468750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW\",\"symbol\":\"KMD\"}" +echo "484157.62468750 <- expected amount RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW" + +# RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2 KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2" + +# RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH\",\"symbol\":\"KMD\"}" +echo "8908.50029425 <- expected amount RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH" + +# RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA KMD 502.18197380 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA\",\"symbol\":\"KMD\"}" +echo "502.18197380 <- expected amount RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA" + +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 17002.74354061, REVS 278.99000000 +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 17002.74354061 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"KMD\"}" +echo "17002.74354061 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW" + +# RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J KMD 149751.00241450 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J\",\"symbol\":\"KMD\"}" +echo "149751.00241450 <- expected amount RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J" + +# RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe KMD 96831.52493750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe\",\"symbol\":\"KMD\"}" +echo "96831.52493750 <- expected amount RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe" + +# RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh KMD 18021.41836725 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh\",\"symbol\":\"KMD\"}" +echo "18021.41836725 <- expected amount RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh" + +# RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk KMD 41017.83396352 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk\",\"symbol\":\"KMD\"}" +echo "41017.83396352 <- expected amount RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk" + +# R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic KMD 13263.41995905 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic\",\"symbol\":\"KMD\"}" +echo "13263.41995905 <- expected amount R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic" + +# RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN KMD 8982.68540439 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN\",\"symbol\":\"KMD\"}" +echo "8982.68540439 <- expected amount RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN" + +# RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL KMD 12356.73789711, REVS 112.00000000 +# RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL KMD 12356.73789711 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL\",\"symbol\":\"KMD\"}" +echo "12356.73789711 <- expected amount RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL" + +# RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct KMD 12561.43380413 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct\",\"symbol\":\"KMD\"}" +echo "12561.43380413 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct" + +# RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6 KMD 4453.35929709 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6\",\"symbol\":\"KMD\"}" +echo "4453.35929709 <- expected amount RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6" + +# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 4521.29210647 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw\",\"symbol\":\"KMD\"}" +echo "4521.29210647 <- expected amount RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw" + +# RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv KMD 11653.72856174 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv\",\"symbol\":\"KMD\"}" +echo "11653.72856174 <- expected amount RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv" + +# RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR KMD 1561.74292091 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR\",\"symbol\":\"KMD\"}" +echo "1561.74292091 <- expected amount RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR" + +# RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv KMD 25107.55827068 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv\",\"symbol\":\"KMD\"}" +echo "25107.55827068 <- expected amount RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv" + +# RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt KMD 391.52338368, REVS 7.76943254 +# RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt KMD 391.52338368 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt\",\"symbol\":\"KMD\"}" +echo "391.52338368 <- expected amount RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt" + +# RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx KMD 2212.41539458 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx\",\"symbol\":\"KMD\"}" +echo "2212.41539458 <- expected amount RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx" + +# RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5 KMD 12079.07428158 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5\",\"symbol\":\"KMD\"}" +echo "12079.07428158 <- expected amount RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5" + +# RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh KMD 2323.95659850 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh\",\"symbol\":\"KMD\"}" +echo "2323.95659850 <- expected amount RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh" + +# RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r KMD 682.83148523, REVS 13.54307355 +# RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r KMD 682.83148523 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r\",\"symbol\":\"KMD\"}" +echo "682.83148523 <- expected amount RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r" + +# RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3 KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3\",\"symbol\":\"KMD\"}" +echo "48415.76246875 <- expected amount RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3" + +# RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD KMD 8133.84809475 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD\",\"symbol\":\"KMD\"}" +echo "8133.84809475 <- expected amount RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD" + +# RAaszCNodXXu9rJL6qqVMZDykXncDecTMS KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS" + +# RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57 KMD 1773.66877470 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57\",\"symbol\":\"KMD\"}" +echo "1773.66877470 <- expected amount RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57" + +# RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa KMD 2971.54458972 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa\",\"symbol\":\"KMD\"}" +echo "2971.54458972 <- expected amount RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa" + +# RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR KMD 3351.00027124 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR\",\"symbol\":\"KMD\"}" +echo "3351.00027124 <- expected amount RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR" diff --git a/iguana/tests/KMD.batch6.txids b/iguana/tests/KMD.batch6.txids new file mode 100644 index 000000000..93461956a --- /dev/null +++ b/iguana/tests/KMD.batch6.txids @@ -0,0 +1,118 @@ +62292e81b302d016f6935c28dbee2b9b1a28ab22a913adaedc76880cb0e1445d +8908.50029425 <- expected amount RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk +f8dccda2957c854adb9181dbbf14f3c65948623e997e5372cb7e1d85522b8eaa +2306.15801572 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf +a787337d17f187d3607d76329a5f9ece7c0b636fe4e7101bd8d2b899f5ad6d67 +1368.88526791 <- expected amount RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv +629cb4c07a543a281dd0353b8365ed6e8ee30a2d26bfb72655fa6b0a72be543d +106.39636971 <- expected amount RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ +89401a02d597b262da1515c4130ee30e0a6576957573d1acd72e006b16aced37 +32892.15837201 <- expected amount RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie +815c8431c567ec91f0939c4ae8c34e08507db24247cd19e3a2314db8e680d8f1 +153.99848359 <- expected amount RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V +3558710185cf55790a003596f2b1facdea4785123cfb02c5323196fbe26550e9 +250.09618515 <- expected amount RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56 +0faa65db35e6a0eeff48cfec24a1db646a70a0c46b252d32ec7734f958baea11 +2285.12762738 <- expected amount RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei +950b907aa7f0e91c01967081c1eab2ce04b748cfd5c4cecb646782cfaeabcaf9 +1660.51377862 <- expected amount RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC +16d638781418ea05812b78582dd686fc70ec5309982a20cd4da3ad2812c36de0 +15065.53304887 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D +68f620f1de68116e293d89fdd248a7e2b6cde4906ab55f8da205a422b2754f15 +2667.18064500 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut +3c3b26a4b995b2b0b6c0c52c037ad96a4151078895ef350e97096ec60e60b2ca +24981.55183756 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda +dd5ca8219ce4df0fca938d8d4ce19c20ee71646e7cd7340d50b3704af326123b +1334.49334406 <- expected amount REvMg538sSpHUdRyCV1jJDjT63XePKLwkh +967a2b5b30b1b97ad0c6d3d8a5bd805e3de9e0aaf1e8b45bda1000ee9a862a2f +10773.51776054 <- expected amount RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF +de575fc356bd68dbe1570b95542ebe9999f0c39be8ca36f3a58c4cea0bb0ecbe +607.46792378 <- expected amount RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs +709270113a9a5541e14d0ba1b71d28a2caa6f843e5b8daebff12c151dd162b33 +2028.62052490 <- expected amount RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS +4c1896b71ca2e8bcf5f66466d67353c2613ab44b2ee738d1462632ee00295bf8 +40431.89788465 <- expected amount RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W +bd38717ae41d20ce382f6679f77f5b165aa8a754b113dd1c49a156a2a89d177c +24325.33313227 <- expected amount RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9 +65805dd69c8a518c8086534f3e0b9ba1056a90b308422720062a1ea24ac0469d +26784.99417167 <- expected amount RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA +b69fba6a6663e6a0b77f8613e777247e195f1bccc2f4a551d9ecf32376595518 +200.88047000 <- expected amount RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc +1fe4ffe4988900b23839d7ce56b7481f9748bd8ba2d17ab63c687500e89de527 +942.22930620 <- expected amount RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw +77168f495725434f2e60fe75ca9507041e8c5073a983804631bf28b023857d3b +9295.82639400 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ +d420e3666e15649ad7982723c03f068b9f80cbd6dbded80009410e9eaeb63e32 +1859.16527880 <- expected amount RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey +39fe472de31a335a5bece0e0b3b72e4d7162eda841e814388ee204878b7f6722 +726.21002139 <- expected amount RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR +05a803cc390a3bcac92a6d17d797985a9e14601860118dbedd9d772d6813e262 +121577.72836165 <- expected amount RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz +20c19fb029fef0be33d8b627f698d5ff74251aafb72b485a33bdb298e48a86c9 +2511.34619763 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 +4c7929dc3e4c0e47a33df0743864c59b7938395c68e630579eb1c2003b57f154 +23246.75713145 <- expected amount RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc +a5ebcbd28dca38ae64bd75958fbe7bbbde4707b3024373d4d2fbf22aa5d41783 +83333.21036121 <- expected amount REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L +53972d809f74c9de8973ff6c5fc5a0cf3bbca4d6a5ee29fc2caea12afe354cc4 +5325.73387156 <- expected amount RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4 +a6a0bf15c9fb617f62f0dbe7e52aacdeaf851aba361de024bf179c7394b7e16f +938.92347308 <- expected amount RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8 +c308d68593e3be9b77de9bc36b5916de6d201b90ca5eea897b54404334c9c817 +484157.62468750 <- expected amount RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW +7b21532d494f3af5d2f053884f2210c6583725a296c391c8d331069302fcd42f +9683.15249375 <- expected amount RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2 +919a2ebedfcf6c88fa836e371b256088331f6934453168346d15bf45d96c7ea6 +8908.50029425 <- expected amount RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH +939271c8ead6549cccb00bdd1f49ce8ca856a7b1c9885d61503a48eedd5c9858 +502.18197380 <- expected amount RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA +d69a774b813831055e034dcefeff61d98330ae0dbe37290a954cac3c4ec91d28 +17002.74354061 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW +58d710161e3badc90af5564af473cdbf6be6bace34309e54521462adfe4d5fd2 +149751.00241450 <- expected amount RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J +333e392d27cfc8200f8fd86a4842f4dda4f81a0fadad89088da3361346e4b317 +96831.52493750 <- expected amount RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe +e071d015797ed3e9b508851b5dc4ac54f03756e5083024adbbe85412bbe3ce39 +18021.41836725 <- expected amount RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh +4a29d95b927c4a6b7cc004f27e80ff76b991e74895971ca0c4c024cda65fe9be +41017.83396352 <- expected amount RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk +682512e2a527e15da96a7314968cd3fca787e4a818191a4ee4f06b65bf33354f +13263.41995905 <- expected amount R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic +6f218e175f456f96f1b4d0e8be63dfdde022aa1a0bc160f5be961a0ef37795d1 +8982.68540439 <- expected amount RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN +862f8287715462b82f455b66ce29a46a739cbf70f57f11ca5f23bb968b5c720d +12356.73789711 <- expected amount RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL +45e030fb8f98666b3f053fd70cb994be55ba0c60906b79eff28afb3f7732d12e +12561.43380413 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct +e3c49fbe2d4ea57e5c83f6a72706a61178912bfe4dc18d5bfbb8835aa6a27139 +4453.35929709 <- expected amount RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6 +826c78814f9725ff98200417d171ae0a6229bad39197a58df3dc02ab3cb6ce45 +4521.29210647 <- expected amount RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw +63a2314d5f88f7331ab55c696c1c978af200671a0ba89ba2c3a83c618f1a2890 +11653.72856174 <- expected amount RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv +1f9b50f730e18a267d4e0a1381d1a94544b8fdee8fe15b626b30f3bd6d0478a6 +1561.74292091 <- expected amount RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR +1fdf240fe884fc0ca54f07e0eac9b39792dd2ddad10e5b528858f7cdb37f4762 +25107.55827068 <- expected amount RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv +6d365c4ce11ccf2b5bd1635030616e73d38598de2bf8fb17a86ce1732dc3322c +391.52338368 <- expected amount RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt +d74721f064415a3ceffac8a8ca55cb3d0017f692c4c1e3ec6f3818f4dcc0c812 +2212.41539458 <- expected amount RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx +ed6261d0bf246e57c9acd4b08ee29ce0dccef714fb128e1dc9d6f4dc9e99336b +12079.07428158 <- expected amount RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5 +8d94f05fca74b59348108a8b949f98b18410776e57654da781a538d57ff5a6d7 +2323.95659850 <- expected amount RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh +7eaba7517f7a3027c36018d0a25f3ee540af3690729471ecd383bf1eb1313f51 +682.83148523 <- expected amount RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r +19c01565bf79e109542aeeb45cb8dbda91963eba2b21ff76a05ae8c7b5984c8d +48415.76246875 <- expected amount RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3 +0fe813014cf95822730981d8905f9a7a2ccf1ebb1344fbcdf3be7f7b5f542618 +8133.84809475 <- expected amount RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD +76dd0c3f7acfc2f12d1c140f228d82753182e86374660d8651f83683bebe20b2 +693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS +61e32c84221d569c5b449d0992f36eff52f092abcfd029015949b537bb081969 +1773.66877470 <- expected amount RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57 +93ffd2beecc84da8c6bf084509db507ed03fb12049128ef356a2d6f739716d60 +2971.54458972 <- expected amount RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa +4264b28ca78c9bacedc50befb824e82b8fd16873a75bc02874908949ce1bdd4f +3351.00027124 <- expected amount RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR diff --git a/iguana/tests/KMD.batch6.unspents b/iguana/tests/KMD.batch6.unspents new file mode 100644 index 000000000..6bb092eb8 --- /dev/null +++ b/iguana/tests/KMD.batch6.unspents @@ -0,0 +1,119 @@ +[{"txid":"62292e81b302d016f6935c28dbee2b9b1a28ab22a913adaedc76880cb0e1445d","vout":1,"address":"RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk","account":"RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk","scriptPubKey":"76a9140b0177aba4a147562e5d525beb7b326a6627f97c88ac","amount":8908.50029425,"interest":0,"confirmations":5,"spendable":false}] +8908.50029425 <- expected amount RAHPGb1w6XyVYD7WbiWBzr5yxEDdtP7zWk +[{"txid":"adf2fd2eee75f5d9fdce44b4fe4d32f62d79f5e1b0362640c76eb109b1ceb30b","vout":1,"address":"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf","account":"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf","scriptPubKey":"76a914240f48f11c4b0674afa8b58dab11bdb780a3a47d88ac","amount":1212.14061568,"interest":1.18837315,"confirmations":9351,"spendable":false}, {"txid":"684728bb5ff281762990da11e7463c6e992b5e98cb0cc7965a3470b8a664484a","vout":1,"address":"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf","account":"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf","scriptPubKey":"76a914240f48f11c4b0674afa8b58dab11bdb780a3a47d88ac","amount":1212.26932063,"interest":0.97763654,"confirmations":7634,"spendable":false}] +2306.15801572 <- expected amount RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf +[{"txid":"a787337d17f187d3607d76329a5f9ece7c0b636fe4e7101bd8d2b899f5ad6d67","vout":1,"address":"RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv","account":"RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv","scriptPubKey":"76a9145dcb3a232f8888e983b1854214b2c6c304148f3788ac","amount":1368.88526791,"interest":0,"confirmations":5,"spendable":false}] +1368.88526791 <- expected amount RHq8NpfqMJZdchhDWsXayXEM5VEimBKgSv +[{"txid":"629cb4c07a543a281dd0353b8365ed6e8ee30a2d26bfb72655fa6b0a72be543d","vout":1,"address":"RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ","account":"RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ","scriptPubKey":"76a914cec8926f2f56a8fef2b22f68a230e7ea2b90fdea88ac","amount":106.39636971,"interest":0,"confirmations":5,"spendable":false}] +106.39636971 <- expected amount RU8ZZ29f8U1LNHriwu6Tj3q6y2in9Q6LtZ +[{"txid":"89401a02d597b262da1515c4130ee30e0a6576957573d1acd72e006b16aced37","vout":1,"address":"RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie","account":"RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie","scriptPubKey":"76a914a58bdf942892f956dc5854dec7cf7113dbed332f88ac","amount":32892.15837201,"interest":0,"confirmations":5,"spendable":false}] +32892.15837201 <- expected amount RQNX8jpgQYR3WBitCrjGQ6nGt1HnX5Qcie +[{"txid":"815c8431c567ec91f0939c4ae8c34e08507db24247cd19e3a2314db8e680d8f1","vout":1,"address":"RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V","account":"RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V","scriptPubKey":"76a91428cabb231f90add806dfe1b833857d813b89964488ac","amount":153.99848359,"interest":0,"confirmations":5,"spendable":false}] +153.99848359 <- expected amount RCzsyBmQBtVWCZURt56K6XprynMNwXUr3V +[{"txid":"3558710185cf55790a003596f2b1facdea4785123cfb02c5323196fbe26550e9","vout":1,"address":"RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56","account":"RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56","scriptPubKey":"76a914f5e04666c48aca1ab1a26092e2f609c467e9a9ef88ac","amount":250.09618515,"interest":0,"confirmations":5,"spendable":false}] +250.09618515 <- expected amount RXhGJR2d175Tau3qDViZcPQwxZmzqgoW56 +[{"txid":"0faa65db35e6a0eeff48cfec24a1db646a70a0c46b252d32ec7734f958baea11","vout":1,"address":"RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei","account":"RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei","scriptPubKey":"76a914b540071a3ca6dc538a72af762bcf2b85675a1dab88ac","amount":2285.12762738,"interest":0,"confirmations":5,"spendable":false}] +2285.12762738 <- expected amount RRoZ5xorGhikkB2qEoVfmuiyMMm3Thq3ei +[{"txid":"950b907aa7f0e91c01967081c1eab2ce04b748cfd5c4cecb646782cfaeabcaf9","vout":1,"address":"RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC","account":"RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC","scriptPubKey":"76a914f7e005ef1c5f1d0d5dd94e15b2f09e27f6303eec88ac","amount":1660.51377862,"interest":0,"confirmations":5,"spendable":false}] +1660.51377862 <- expected amount RXsqMJSo3B9npdT9M57SYnRUkez1rVmQYC +[{"txid":"6ba72bac45bd935d79b4f33c42d319f15b0c4e72a650cff625563126d8faac87","vout":1,"address":"RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D","account":"RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D","scriptPubKey":"76a9142b2685d16fde2f87f6a116c03001acea69571e4188ac","amount":553085.02723026,"interest":242.58115229,"confirmations":4164,"spendable":false}, {"txid":"16d638781418ea05812b78582dd686fc70ec5309982a20cd4da3ad2812c36de0","vout":1,"address":"RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D","account":"RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D","scriptPubKey":"76a9142b2685d16fde2f87f6a116c03001acea69571e4188ac","amount":15065.53304887,"interest":0,"confirmations":5,"spendable":false}] +15065.53304887 <- expected amount RDDMHNTWge3CMGFyKXUueNjGbsWcXmL31D +[{"txid":"68f620f1de68116e293d89fdd248a7e2b6cde4906ab55f8da205a422b2754f15","vout":1,"address":"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut","account":"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut","scriptPubKey":"76a914a8fac0d74fded755c3ce82b2f6a12959176be56788ac","amount":2667.18064500,"interest":0,"confirmations":5,"spendable":false}, {"txid":"acd786f5b7bab14737a25d0ac2eb0e1a61743899f83571a694191a5317cc3c67","vout":1,"address":"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut","account":"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut","scriptPubKey":"76a914a8fac0d74fded755c3ce82b2f6a12959176be56788ac","amount":20106.39865075,"interest":13.58540449,"confirmations":6513,"spendable":false}] +2667.18064500 <- expected amount RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut +[{"txid":"3c3b26a4b995b2b0b6c0c52c037ad96a4151078895ef350e97096ec60e60b2ca","vout":1,"address":"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda","account":"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda","scriptPubKey":"76a914b64af5d62e56292a1c61b66e51adf3d73ce76d6a88ac","amount":24981.55183756,"interest":0,"confirmations":6,"spendable":false}] +24981.55183756 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda +[{"txid":"dd5ca8219ce4df0fca938d8d4ce19c20ee71646e7cd7340d50b3704af326123b","vout":1,"address":"REvMg538sSpHUdRyCV1jJDjT63XePKLwkh","account":"REvMg538sSpHUdRyCV1jJDjT63XePKLwkh","scriptPubKey":"76a9143de00796e3201826f528a457370b49c14f5239d288ac","amount":1334.49334406,"interest":0,"confirmations":6,"spendable":false}] +1334.49334406 <- expected amount REvMg538sSpHUdRyCV1jJDjT63XePKLwkh +[{"txid":"967a2b5b30b1b97ad0c6d3d8a5bd805e3de9e0aaf1e8b45bda1000ee9a862a2f","vout":1,"address":"RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF","account":"RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF","scriptPubKey":"76a91498cd04a649fa6e2c68318e06fcd9e81d066184aa88ac","amount":10773.51776054,"interest":0,"confirmations":6,"spendable":false}] +10773.51776054 <- expected amount RPD8PawM6UFBsSrYujjGa9Smfc3hT48tUF +[{"txid":"de575fc356bd68dbe1570b95542ebe9999f0c39be8ca36f3a58c4cea0bb0ecbe","vout":1,"address":"RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs","account":"RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs","scriptPubKey":"76a9142aaf497d0f3c8c3b420aa96983fa066a539c2a4988ac","amount":607.46792378,"interest":0,"confirmations":5,"spendable":false}] +607.46792378 <- expected amount RDAtSjPgVNwUvV3cNy1DohVKumdXK5zXRs +[{"txid":"709270113a9a5541e14d0ba1b71d28a2caa6f843e5b8daebff12c151dd162b33","vout":1,"address":"RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS","account":"RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS","scriptPubKey":"76a914985a82002db46326b99c6e19485af882dd1cbe2788ac","amount":2028.62052490,"interest":0,"confirmations":5,"spendable":false}] +2028.62052490 <- expected amount RPAmDGUEooCPRRxDpG3KrJ3uEK7kpo1taS +[{"txid":"4c1896b71ca2e8bcf5f66466d67353c2613ab44b2ee738d1462632ee00295bf8","vout":1,"address":"RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W","account":"RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W","scriptPubKey":"76a9140b208683ef4dd06e2626f3b9b652fd026b94733488ac","amount":40431.89788465,"interest":0,"confirmations":5,"spendable":false}] +40431.89788465 <- expected amount RAJ2UXw4RskMXFJfNbmZUhZ8PjDJ4uwz2W +[{"txid":"bd38717ae41d20ce382f6679f77f5b165aa8a754b113dd1c49a156a2a89d177c","vout":1,"address":"RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9","account":"RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9","scriptPubKey":"76a91494efc12346132d73e1c94232bfad3fa28f7dbc8088ac","amount":24325.33313227,"interest":0,"confirmations":5,"spendable":false}] +24325.33313227 <- expected amount RNrhJLYeG7yMYhTrpkFmP7g4SoEEGZLTg9 +[{"txid":"65805dd69c8a518c8086534f3e0b9ba1056a90b308422720062a1ea24ac0469d","vout":1,"address":"RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA","account":"RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA","scriptPubKey":"76a9149bee0a38bc753ebfcd0d65fa5da4391d0366b13d88ac","amount":26784.99417167,"interest":0,"confirmations":5,"spendable":false}] +26784.99417167 <- expected amount RPVfyZ5ikstBeXXZsemgWfbB85Em7BdhnA +[{"txid":"b69fba6a6663e6a0b77f8613e777247e195f1bccc2f4a551d9ecf32376595518","vout":1,"address":"RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc","account":"RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc","scriptPubKey":"76a914e521fa89860dee436a6f1bd4fa96b3304e5f5fb888ac","amount":200.88047000,"interest":0,"confirmations":5,"spendable":false}] +200.88047000 <- expected amount RWAjXKk7zwHj8jy8SeuS4R45EA9S572dUc +[{"txid":"acc00c567dc47945768302ff4acbb89150d5003e6589c3b72dc2bd591bf4a10b","vout":14,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.00399845,"interest":0,"confirmations":165,"spendable":false}, {"txid":"1fe4ffe4988900b23839d7ce56b7481f9748bd8ba2d17ab63c687500e89de527","vout":1,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":942.22930620,"interest":0,"confirmations":5,"spendable":false}, {"txid":"16431eb5aa9a3773c2c81775eaf8a00a56d3aeb7802d1370441589f379bd7b33","vout":14,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.00372134,"interest":0,"confirmations":165,"spendable":false}, {"txid":"84ee9836c5c8efcdb464e67ebf44a778dd3e8944f8b583d911fd7ac144ee7441","vout":18,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.00376084,"interest":0,"confirmations":587,"spendable":false}, {"txid":"ed9d40af32e07a771b66037a5415c1131ea0406da6b89d1fef63c891af740453","vout":7,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.00960203,"interest":0,"confirmations":516,"spendable":false}, {"txid":"2d1fa6ae1d9eb1596f07c8eda09332ea8e658dc52ba3953048e727039957ca6d","vout":23,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.00658122,"interest":0,"confirmations":586,"spendable":false}, {"txid":"bfb3daf6ee189aec019dd5911643ad546b564d308a2485ebfe464fd6cfd21096","vout":18,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.00205724,"interest":0,"confirmations":165,"spendable":false}, {"txid":"b962d6652aa5169c0ae0465d1d8c04accf16a2ba05fc9d622fab310913fcc2af","vout":28,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.05205013,"interest":0,"confirmations":458,"spendable":false}, {"txid":"ac00045379ebc7e9746a21d1514b3afbe8ca0ce8de22a24ab2d2dcaddee32dd8","vout":9,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.00407423,"interest":0,"confirmations":589,"spendable":false}, {"txid":"825aba076420b2218bde2c14b052f65ecdb5a6fc8643d72d378befa472e2f6f4","vout":17,"address":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","account":"RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw","scriptPubKey":"76a9140a763e24f43c641149509cfad2a427c0eff7dfee88ac","amount":0.00437964,"interest":0,"confirmations":587,"spendable":false}] +942.22930620 <- expected amount RAEWV5sPjaEmw9Toa44jxchKCNLQVYnkcw +[{"txid":"77168f495725434f2e60fe75ca9507041e8c5073a983804631bf28b023857d3b","vout":1,"address":"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ","account":"RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ","scriptPubKey":"76a914d41f1a25312622d5bb49e4611fa25db3bf4ab05a88ac","amount":9295.82639400,"interest":0,"confirmations":5,"spendable":false}] +9295.82639400 <- expected amount RUcnbCSHhpHMhQbKNk5VMgmi2vn7hGGyNQ +[{"txid":"d420e3666e15649ad7982723c03f068b9f80cbd6dbded80009410e9eaeb63e32","vout":1,"address":"RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey","account":"RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey","scriptPubKey":"76a914170ba0ab851469133ab4e7c3ae83a5dac5e30de688ac","amount":1859.16527880,"interest":0,"confirmations":4,"spendable":false}] +1859.16527880 <- expected amount RBP3Yq3aAkuw9HfixLWygqcSmhTWJRNvey +[{"txid":"39fe472de31a335a5bece0e0b3b72e4d7162eda841e814388ee204878b7f6722","vout":1,"address":"RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR","account":"RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR","scriptPubKey":"76a91447dd02a5ac602b77e5c75f0dbf0bcbf8a575a54288ac","amount":726.21002139,"interest":0,"confirmations":4,"spendable":false}] +726.21002139 <- expected amount RFqApCmTfnC5G4xjKojfS9HMeLGEyAEDKR +[{"txid":"05a803cc390a3bcac92a6d17d797985a9e14601860118dbedd9d772d6813e262","vout":1,"address":"RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz","account":"RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz","scriptPubKey":"76a914475bcf454d77cd5ad41005b1a05416a989a0816288ac","amount":121577.72836165,"interest":0,"confirmations":4,"spendable":false}] +121577.72836165 <- expected amount RFnW3BXvF5U67dxB1BnuWEGaQjjBosqCwz +[{"txid":"13e9b271e893f9224696d74a904696a8c25cc76f645cb27dede8a2f62cf87f6c","vout":0,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":999.99990000,"interest":0.10080644,"confirmations":991,"spendable":false}, {"txid":"13e9b271e893f9224696d74a904696a8c25cc76f645cb27dede8a2f62cf87f6c","vout":1,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":900.31368461,"interest":0.09075742,"confirmations":991,"spendable":false}, {"txid":"4f5ad6ec2d1b272e8b5bccc8f8a82924d399e6b334359a24185e85f2ed041490","vout":0,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":0.99990000,"interest":0,"confirmations":991,"spendable":false}, {"txid":"4f5ad6ec2d1b272e8b5bccc8f8a82924d399e6b334359a24185e85f2ed041490","vout":1,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":3.65643742,"interest":0,"confirmations":991,"spendable":false}, {"txid":"c8cba16908893545179be5ee114e77121c0779efafab61cf6c018bcd01a7259c","vout":1,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":28096.43798050,"interest":15.43760328,"confirmations":5200,"spendable":false}, {"txid":"2a61589e506db0004171196050d3a0c0d6bea3fca15d6e8a0897f7052bfb20ba","vout":1,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":8000,"interest":3.27868852,"confirmations":4091,"spendable":false}, {"txid":"20c19fb029fef0be33d8b627f698d5ff74251aafb72b485a33bdb298e48a86c9","vout":1,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":2511.34619763,"interest":0,"confirmations":4,"spendable":false}] +2511.34619763 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 +[{"txid":"4c7929dc3e4c0e47a33df0743864c59b7938395c68e630579eb1c2003b57f154","vout":1,"address":"RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc","account":"RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc","scriptPubKey":"76a914dedf4487a56f16b47b650bc9999d371cfc740da388ac","amount":23246.75713145,"interest":0,"confirmations":4,"spendable":false}] +23246.75713145 <- expected amount RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc +[{"txid":"a5ebcbd28dca38ae64bd75958fbe7bbbde4707b3024373d4d2fbf22aa5d41783","vout":1,"address":"REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L","account":"REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L","scriptPubKey":"76a9143634a0aacb2230ed0f289dce9c462b24c93c57cb88ac","amount":83333.21036121,"interest":0,"confirmations":4,"spendable":false}] +83333.21036121 <- expected amount REDocWFMCjY9JDTf7WYQwyPesHZd7RUT9L +[{"txid":"53972d809f74c9de8973ff6c5fc5a0cf3bbca4d6a5ee29fc2caea12afe354cc4","vout":1,"address":"RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4","account":"RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4","scriptPubKey":"76a91489aac0d1e99f053be1f37274b73e2e0b49f3093f88ac","amount":5325.73387156,"interest":0,"confirmations":4,"spendable":false}] +5325.73387156 <- expected amount RMq7CwKZHNycYivj2wFfvoJp8XWJAVeDf4 +[{"txid":"a6a0bf15c9fb617f62f0dbe7e52aacdeaf851aba361de024bf179c7394b7e16f","vout":1,"address":"RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8","account":"RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8","scriptPubKey":"76a91463c89f21563f4742678b32e205571dac9edd994188ac","amount":938.92347308,"interest":0,"confirmations":3,"spendable":false}] +938.92347308 <- expected amount RJNoJwWP9xpyNMPUi7iPrLNWCxTAKZxGD8 +[{"txid":"807e5780d91eb5202217f491f10532d101fb7fc6ab9026f3956a008f9e409400","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"91275fa732478f74a9ee65f765483dbc5a57c3a82c199f8fbaad5f1bc1d23303","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"dba850dfbd63a8ee35a1cae81c39a32cb87606313b232a24ff831002536d4704","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"19b5e41164b4f3a30e59c8ebab3fbf76bc2db79ce3dee4c9880dc43f036f0307","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"a629bab8f075e7db954d3eb6df0671f726eb9808a395153d179214324afc6f07","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"5083cb1e8a6c0077e5adca938c871fdd978abdfb7f7b774e66528bc91030c907","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"02fbe27b66b62af352a31ed1ec73dea3d47bc310cca0f904d61ef7f0ada1060d","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"062ab739991cf71bd49671fb3a0efb0d516d07cd5ccc7b60a5e4a6c71b36350f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":1000,"interest":0.14970059,"confirmations":1493,"spendable":false}, {"txid":"c09e2c772c3f5db197613051757e9c5a0780559ee6e33849f958d7e4f7ef0715","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"727ba924729edff97deb3455e6e017f7cbe031d9c0d9b8bc8301ccd93acc7716","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"b3ca11bfb2a20c78afcae319edb74492ea0845318354cb316a0524332788b216","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"c308d68593e3be9b77de9bc36b5916de6d201b90ca5eea897b54404334c9c817","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":484157.62468750,"interest":0,"confirmations":3,"spendable":false}, {"txid":"1d9aaae24823b044de3a13527251f3c84bea2856c7f5aec9eba7c7fb422afd17","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05970149,"confirmations":1489,"spendable":false}, {"txid":"b007dd511cf5a0970ea7726646db65aa82afec839592a7d10959408cdb100c1b","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"21e07d20570c1de1d892ddd735e637c42fb429c7d2ee0e65451192bc4e19b81b","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"6c4f959413b34fe6c14534277b27124be1da6fccb2d6e9c25d634e068a7bc71e","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"7df8f61b583c8df78b4d7e44efe2ec807958687621363962a4ea5da2792a421f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"0b47a14205453e701913ece85a815b3f932f7d63569b95670c16db2306417e1f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"3aafb21ffe0608c49e481653611a1823399f60123ba8ebf4851aa7af8645a11f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"bef1fe4af1f82bda2a0fcd81e75da6481b7369e978a59a807c170aa38e6fa91f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"ec91c9105d91c3f3450201e43f0734c56b940ae23b1563e9372c1b0ba4106f21","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1489,"spendable":false}, {"txid":"48553c9d7022eb653cbb7fd5fe52b0a98373c06c7606ad82abdcaf4d4d150326","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"0bb6cb1ccf6e427ffbbff668a364f10ca656f6d3c827dd9fee43ce72f85a722c","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"8826bbccfea98938674d6631b6ab4df9601d97e1f6c0b6473ccc6c597e2f5431","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"0619fef6a74d346e960a87f45ffd5273dd487823b83105120e2146265e9fc831","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"6b964565d3d997cbaaafe54636bf1e86e5a19874a27062558abed718e5dbe231","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"670088345354008ae193bda24a5a8a4674a12450f208bf27ef0aa9be23508832","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"46b4472d1da7c51e51fcccf2f0b419b0aea9672a57ee10344c3a9c82a8d40a34","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":1000,"interest":0.14970059,"confirmations":1493,"spendable":false}, {"txid":"0aff9fa1e7be37139ee6f18f5cb1a9c836eba34a1a7e1ea5bfde993cc4193139","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1489,"spendable":false}, {"txid":"cf0cb3a4370631454959d32b80d88c1695150a3fa0c7255fa1d6a4c0cce1553a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":100.78493000,"interest":0.01504252,"confirmations":1487,"spendable":false}, {"txid":"ecd661ccaabdc9f0a8a61ee45a3a3c9aac0d1d419c4a6a215815ac95edbc7741","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"22a0bf44f0a4eabc7049623db8334fbef21966dd575530cb14e826cda3968044","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"affc10f2401e1c0f98e4a07b3e6320449001b1b4cde7115ab14e2ae5fa139444","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"c2de81ddc47dc7090ae455cc2b4294f08f5b4089dfe793a2e4883b22fa18e645","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"71284255a2d516f251cfe8ce0c206461976de1df242f05abbbe46faee6a5344a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"4804cf9efa718b8ba660f2ea47b72a1ec5e286eeefc6281a174b16c1f94fc84a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"3263c4f8b757d5b00b2af9e66f160bdea3b290dd1a9301bbe049ee7825f5134d","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"f66257bfef5c195f58e2d53442ff6296a8fd0ed41baf2e26449aea07b07f2f4f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"981e4f5027914977bd3a6d80df39f3b8ac1115e1787b4e9c3cb404cc736e4b4f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"025d08accffca27ea1617ad42cf01c1fcf546f7a50a93996890dfac77bf07c4f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"f2c595ef64c90b2ec2881310ba5c70f8d15d11a3a3b01c72a2eccec89d8d6052","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"e026ecf3d19a4f50d8442fdc8befc2e16a4778d81f8308348f3d27116e258b53","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"fa899878520795e32a9aea9c0bd13b728030e8a24832358ef9c0d98195fc6154","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"536a9f329291b822314db2824c4704dc8d18418d72dd91270e47d23d6031ea54","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"8f19b5412752a5c40fdb56bce3a0a9f2dfffdae70a85b57b71db8138b3df9557","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"5860ce8988a700e0de8d5bdcf65f3f3e32f3e370ea0a4f033a4f866087419058","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"024e60a2161be4597bd00fdd657d5c0ea7cdbd98761abff205a14f7ce85dba59","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"f724f8209d243afc9f4aaa9428cd812620f1236ee454245a37e6cd4cbb64625a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"8d1fbc63cac4a463387b12fd439bb6845ff5868c5446671354661d0f68a6a65e","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"48aa3a5d74e81934df2a4b80e1bdab601e9af5978f3a01d800699d90108d2e5f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"1a78ad0433140e20101989c0fb7a69b7afeadaf18addf1b0a05b199023d08d5f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"d2965a90a28b4241aa02d1b13f7122ef7c771b2d591ecf744229c9a8500cfe5f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"e1e48c18f70b93ca5578970dd2eba1c7ec99441580cf17c526c65d8218b37563","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"62cd788b85f835a49740e9750aca27c1d5a4ae6a6e5769fbe00183c279c2d964","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"90981ea70656e0a846ad84b23f0aebbb1d51f263816048f1b2284cd2235ef564","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"03fd401667d7712442dd8cf792d00ec30dcd07ca3a9ea6492a44f4cd6d5e466a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"80241e9fad9e973cfc0a297e70edc81d142e08e9ed86fa15efc09d2495d9026f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"5479ec849719f0369253f9ce419809209ce027242cfa44f5ea8679d932889c6f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":2000,"interest":0.29850746,"confirmations":1485,"spendable":false}, {"txid":"a9f7b136bd5520eb20b77a6f179ef60888460875e0042d70d01cf9f58d401671","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"e041cbbfe0eedbf8b54df9977f2ec0c0db3f1c8ae06445ae3cbf252ad430d872","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"5f2d3e0b3a78b97be5d9af844b5298ee6cf7084a9a2485feff194cb909321e73","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"b05b14dd2ea9c3ce1b29ef326cf338b6fc1064666eea68c66765be39419bf373","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"e1f25099c25c8f3a0112f3882f25306237cf8d249829bf639bb0ab507fec0774","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"099bb04f4f3576f9f9834580934d92cacfea422b9fd36e0b1080f5ce16a28879","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"75caf7daeee4ea97eafc6cb6a4783212e5dd9feab1936f7f220f462c5810cc79","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"e578ae300c610bbf1d8436426e961e2e777d58cc478e00589679e75b9e1b987a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"590789e454f25eec829f792f26591960dc1158ff45ee8a4defb8dd8c431ebf7a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"b48836f4fdc45fb4ba9b4ae6a1884df1501a4b2fd9ad76b851bf122619b9227b","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"f2863cabacf0052fd0cd55d3dd02753d52f65de578c7bd05ed091a7de51f027c","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"744d2189d3790bc5d87a3bc2a984e2dc73c5502ee963346cf84c6b8300fd7f7d","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"276717656e35a4198459e4b7485361a6b4d8ab6aff5cf64b82724a5c714dd480","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"4ea6114f32f75ef7eed71b97484aae65ccea1a49d0980013b3d26d5d2234fc82","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"e3d1fa8c754257a3045269debf80558f3ee1a2ce468d3881da6f489080a07984","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"17d6a5a9518866da74fb69fb5ca6cc221e2d71fa4eee30588ae20b6d658d088a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"a1536d8deb76fad4d4b0b4a03f8e5f367ad0b033b2a9baf2abea6ffabe699a8a","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"b2af9754e5c64b660486aa2b35a3c68ef590d5f1e89bee6b8c30b9bb6c35558c","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"9c6ae30087c48d7e9e050cd65bb7fadd04aa9362324a7135a2dbba77ac4a7b93","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"d5a51d74a2333f13074ffa51a1cdde003733a886e81427c6e313467ecff90994","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"4457f7b40c8c65f271f217cd4e6355b1b56fe6d1ca6fbca1c678970e0a7ffe98","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"7ed2a1a86feddebba4807329017392ab53d827a4897e196042825324cb1b2a99","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05970149,"confirmations":1489,"spendable":false}, {"txid":"c35372647c9ad0491e4c9915b76f184b24930cb21f05462ec9a3804a70b0a49c","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"aa761327a9465a04fafd1656a38a939c1adc4fb1688d819ad101eb3b5f87ed9e","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":180,"interest":0.02686567,"confirmations":1486,"spendable":false}, {"txid":"40fea0e96f89d1cefb73ce97f6ee34b22ac43417ec89c631931654c53761fa9e","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"9c6aa75a21b6df434004f757be9915c2fa845d2ab44375feae2f08d6d371fd9e","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"d649ddb2407dd123896335833d008ea8d3ab15a549c40140a4d0a277404e839f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"14a6ce71ff2352effd255986e5dfdd001fe0674ed35d76695f960f2d14bab89f","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"1b9f83c5360cbe7a410f7f6b806ec176540034b8c8207df67af8c5e8dae6dca0","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"54b86c687ab22aefbe94a82799467f9b35a503575511f7090f4ebde4a25978a5","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"f6ba9adb19000f1dfc58fb2ded7d92d43b5a78b9ced54a3ba3ce1463c0b499a7","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"627ec49bcedcc6b7a49e2ff7a51c7daa1cb4cd753b32e8a47ab7440d1d2f53aa","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"52b8ef9950b8426bded18a42c133284d9ccaeffc4c4ffdf8044b49466ebbafaa","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"3c94c62b201c1bfd0c2127c91c95e9c1f5f29d92128876b3f173377353b86fab","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"321bc2832b8c203cc1bcddfaada71508493e7e2f0f2ab96b68c5314b0d521bb2","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"a77b9ad742cbb6e69d29759e7f8e46197b8fbc0eef2bad50085aabad72e6dbb4","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"e799975f3be1e7d24e2d7f01b6874bd1dce26f55baa1d1db5416af827e48c5b5","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"3dbd316a6633e15b7cc9372a19e57884cab681b3e3218373cc82ee822867f4b8","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"b3ab76f13e43761a2b949a0ed6d19a364f0aca72dfd7d68dc5ad0b5f971e01bd","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"24aa0819f11ed5ac6510345453f4ff076b370aa84475be47fee3679bb78f3fbe","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"f15a442f257718faacb193210e63b3c4fbd9cb3a50e4bfab2b2091e10c8913bf","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05970149,"confirmations":1489,"spendable":false}, {"txid":"9f870c16d5e099da52f62c53ca71314fa6b9dc56048125d4403e2dc15fbf1ebf","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"cc616b4047ecc49f392c70d8533f8bf87f9ed446bb113a645418aac7be32a9bf","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"c0bca4d782ba21f04328e0f9be21c13e910f44aafc8b3ae19b110ecdd4d26cc0","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"13ed40b51eb9cac9970729986f31723bb364febab69bad094876971fa44c18c4","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"fbeae085df68ca2b7e51c7eea1e215ae6a9f3abd583bdc7b1a9b431ce3292fc4","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"6028eebda1ce97fe95f10e59bdab57f8efa3e5330c291c6980b1b1bf7fa978c7","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"96b524029a26f1a54b1a506c55a410787840aeee8f0a211b16ca9eabfc542ccc","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"61b0e85c06a0c8e1e144baa1035ad0c344755022ed0fa79dccdb664fb3345bcd","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"05f42847ce9f9959e09ef9d588634bdf00374200e4803717b0bd8f164adbacd1","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"e0e3db77664724a4755158b0259abb87133b0d8813cc82e5ce72482777c1d0d2","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"4893a81673ffacd4a37eada50f503c39e88313d680d672e5e397761cb416a3d6","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"64bf0182a211177edbad70281040fb4eac0043d63d39f3c27db97b9cca4d3ed8","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"6d8acaacc7266d88b41fb0421289773f1de0289045f95b1071e2a9a648e395db","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"9d4b9092e61c00301ce306cebb34a9a8a70be11502a20f2664dc0fd53e4baedc","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"2005f72c4aaedf83803077bf3f16735f63d9b3182e0381ed3aa03bd791f772de","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"aa0a23b11cead6140a99fac8ca209d08dc55993339056fa0fb78bb4a9185f4de","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"6569a82c9b88398f2b6dc01cfef2cb93d50dca7c54808f533d16b604d8ef83e2","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"554fab524e105904868a4bb1d2c24d6eadee8289e74d489a4d74aaa931703ce3","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1489,"spendable":false}, {"txid":"2227fd497e6387b3ff3f4168b3d74985c3838e73f7235afdf7c7564a8c5c1ee5","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"289da36f4fc0ea5d3f934eee4985e8769378b2652fee456400cb1131ba6419e9","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"5425be5e3f870ecb98cf54d5f306bf83cba7d8beff7a10dc3a6549197fb7d4e9","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"284e3463bf15f2b3ae84be19fdddfbcdb8ee6bf17cc21aefff9c4c68f72b5eeb","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"b22edde937d33f5cf62db2839aa7888122410a7f1707758e90226f9c33c1d5f0","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"c8ebe761d0cb2b25d1db4fdbe86b5b1ea55f2581cf98bbc52fa70cd3c4cc33f2","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"0e8c4ff45f80ef7564ec3324c13875793b0a494de695fb36874062451953aaf6","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05970149,"confirmations":1489,"spendable":false}, {"txid":"29b3e84ee05f46cfe93f8f2178196eb190f29a7025724ce260b6a2fd3c48f8f6","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"d1ae8c56f3c4c3747f0b47b7ab91275c3dfb55505a6304e82810a550dbff8cf9","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"566ebced9422fa78611e22ee2fb98ba28ef939e98f0210e5c42159058f14ccf9","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"2baca693091d33364c2040c104ec0936b84e96364a75636ff176fb5696ce45fa","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"dfbdd7033500952ee496ecf474de4f8046e729e3b0e47537fab332ce30fac5fa","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":300,"interest":0.04477611,"confirmations":1488,"spendable":false}, {"txid":"960ea793c7f222f791c9db52ad2112c83be6dfe0286d6aeb9d5aae845016c8fc","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"e39528b63fb5cdcf188b0293200077d6dfde2496886876a9cbe051c658b0a7fd","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1491,"spendable":false}, {"txid":"db6a9f4466ae03a6add0b286da41f86680a900c6932f83916ca40612c56825fe","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05988023,"confirmations":1492,"spendable":false}, {"txid":"ae8ccf85dcaa7490551bd64fff0a6c9c43bd0c5cedc67371a1fec13acf638aff","vout":1,"address":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","account":"RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW","scriptPubKey":"76a9142fc1bbb9ee0051b8aef8ca0a55f5d9d0e610567188ac","amount":400,"interest":0.05970149,"confirmations":1489,"spendable":false}] +484157.62468750 <- expected amount RDdhvMj7k1ekyBp42bYEzxCVBVbprkGZPW +[{"txid":"7b21532d494f3af5d2f053884f2210c6583725a296c391c8d331069302fcd42f","vout":1,"address":"RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2","account":"RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2","scriptPubKey":"76a9145ce209b68ce8d7270d8064609218edf44c054c4f88ac","amount":9683.15249375,"interest":0,"confirmations":3,"spendable":false}] +9683.15249375 <- expected amount RHkK2ZCbWK35bDZkojVBCXTezoS9hqZDJ2 +[{"txid":"919a2ebedfcf6c88fa836e371b256088331f6934453168346d15bf45d96c7ea6","vout":1,"address":"RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH","account":"RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH","scriptPubKey":"76a9147c5e30b0189ee27fccde4d9eced2962d8fb35ba988ac","amount":8908.50029425,"interest":0,"confirmations":3,"spendable":false}] +8908.50029425 <- expected amount RLcnhkZr56a9z7oLLrj9ZSoKicpnxPZVVH +[{"txid":"939271c8ead6549cccb00bdd1f49ce8ca856a7b1c9885d61503a48eedd5c9858","vout":1,"address":"RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA","account":"RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA","scriptPubKey":"76a914639465bcf838c2958ed7684e256a3d9e4cc4a2d588ac","amount":502.18197380,"interest":0,"confirmations":3,"spendable":false}] +502.18197380 <- expected amount RJMikLhPMUv8t3Z8xycZpzdKPwv76yKbdA +[{"txid":"d69a774b813831055e034dcefeff61d98330ae0dbe37290a954cac3c4ec91d28","vout":1,"address":"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW","account":"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW","scriptPubKey":"76a9140acb4e5033ce249190419732da77cc407ba5279488ac","amount":17002.74354061,"interest":0,"confirmations":3,"spendable":false}] +17002.74354061 <- expected amount RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW +[{"txid":"58d710161e3badc90af5564af473cdbf6be6bace34309e54521462adfe4d5fd2","vout":1,"address":"RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J","account":"RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J","scriptPubKey":"76a914978cb28278917e0ee5d408d33c891dcf49e08ccb88ac","amount":149751.00241450,"interest":0,"confirmations":3,"spendable":false}] +149751.00241450 <- expected amount RP6WfJVmgrtRT9DBywBtq48HBzBpspTU4J +[{"txid":"333e392d27cfc8200f8fd86a4842f4dda4f81a0fadad89088da3361346e4b317","vout":1,"address":"RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe","account":"RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe","scriptPubKey":"76a9143fe1907a756620d9cf7c4752ef97127c8aea45ca88ac","amount":96831.52493750,"interest":0,"confirmations":3,"spendable":false}] +96831.52493750 <- expected amount RF6xs65r4k2okG9uvTx3D9Zz5yXhvjPvFe +[{"txid":"e071d015797ed3e9b508851b5dc4ac54f03756e5083024adbbe85412bbe3ce39","vout":1,"address":"RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh","account":"RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh","scriptPubKey":"76a914a638cd21581308dba197c0c1003b652a84c0c6f988ac","amount":18021.41836725,"interest":0,"confirmations":3,"spendable":false}] +18021.41836725 <- expected amount RQS6HyxAdNjeAob3cee7TVXN3ptZowRBUh +[{"txid":"4a29d95b927c4a6b7cc004f27e80ff76b991e74895971ca0c4c024cda65fe9be","vout":1,"address":"RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk","account":"RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk","scriptPubKey":"76a9141f9ea4cf71f4648097bba9218d84d07c4785b4f588ac","amount":41017.83396352,"interest":0,"confirmations":3,"spendable":false}] +41017.83396352 <- expected amount RCAP5E6YMeqbBZmbXmTq7cvhruyysyhuWk +[{"txid":"682512e2a527e15da96a7314968cd3fca787e4a818191a4ee4f06b65bf33354f","vout":1,"address":"R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic","account":"R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic","scriptPubKey":"76a9140329b744779e737b298404f7328a5870196f79ff88ac","amount":13263.41995905,"interest":0,"confirmations":3,"spendable":false}] +13263.41995905 <- expected amount R9Zv5ZZprWtw427XmGfNLTsH3Goe49Ghic +[{"txid":"6f218e175f456f96f1b4d0e8be63dfdde022aa1a0bc160f5be961a0ef37795d1","vout":1,"address":"RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN","account":"RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN","scriptPubKey":"76a914d54306e25ebc0bc6ad368b25f702ca5b6d3905c888ac","amount":8982.68540439,"interest":0,"confirmations":3,"spendable":false}] +8982.68540439 <- expected amount RUipJV9DPtvCYA81w3EwkCr5DNQ99289zN +[{"txid":"669b331517bd24a7b6b637d671df9b4f33fde73ed24d21faef8d0a2a92143a00","vout":33,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.06570807,"interest":0,"confirmations":1798,"spendable":false}, {"txid":"aaa6bf18981da0d057aad2205b43e4e686f67c32080e9e91371dd7da37164c05","vout":19,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00946668,"interest":0,"confirmations":1415,"spendable":false}, {"txid":"3d7fc9284b42d1ca64a128abe221c0b2caefb304d1c24012c8cf70571ae6bb06","vout":7,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00581894,"interest":0,"confirmations":1248,"spendable":false}, {"txid":"fb7b7652a9897128efc727d908d5068e1697b236fcd8f9822ec6f7bac90e2f07","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00540089,"interest":0,"confirmations":1072,"spendable":false}, {"txid":"d9645c1e1ef2ee63bb872baea818def83cabc4880a3c20d811e22d704c926807","vout":6,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.02698551,"interest":0,"confirmations":1451,"spendable":false}, {"txid":"8f65756d5588197b0200dbbc7b9d8f561a7299ee68640840a9b944df6fb62b08","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00663093,"interest":0,"confirmations":1362,"spendable":false}, {"txid":"cc2d87680c512cf9efe954e118de1b8c2e36bf90d726f2f336b53cc2af1bda08","vout":10,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00712655,"interest":0,"confirmations":1091,"spendable":false}, {"txid":"cbed45693e1ccc36954f8190562b995b3f0c034bf47e59422942bec05b29a70b","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00612963,"interest":0,"confirmations":1341,"spendable":false}, {"txid":"862f8287715462b82f455b66ce29a46a739cbf70f57f11ca5f23bb968b5c720d","vout":1,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":12356.73789711,"interest":0,"confirmations":3,"spendable":false}, {"txid":"d21f7b49e7b3ea178a0f836abd7eaa34438a07473c8b8cfb3de60979d6f1e910","vout":11,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00495427,"interest":0,"confirmations":1117,"spendable":false}, {"txid":"9d54eac8674c56b9f333c5b5577d29d61443c55d4ce8e02f836285e5c255df13","vout":1,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00664330,"interest":0,"confirmations":1143,"spendable":false}, {"txid":"1884b6d5ca6956805379172f21d0e07409f9ef2468641a3798676baf1777c915","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00880341,"interest":0,"confirmations":1191,"spendable":false}, {"txid":"003b4fcdec0edc36d76e0ed43d01ea1b4d968a1bf4dfd6e797dd6de1b8f7cf16","vout":21,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00444146,"interest":0,"confirmations":1301,"spendable":false}, {"txid":"e34cdd24333ba58909a7abece7e8a0d91144348225b73f1290d013cd7284a518","vout":1,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00789659,"interest":0,"confirmations":1264,"spendable":false}, {"txid":"db7bf23ef7289be05f47d9f495b350eb2651615cf7589e7563a3b98b4d519719","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01026458,"interest":0,"confirmations":1645,"spendable":false}, {"txid":"c498c532661e22c5b1261ba80f32ca15151661b9b56bdc8ac027164a7905f51a","vout":19,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00613531,"interest":0,"confirmations":1251,"spendable":false}, {"txid":"2ca2ef5408b97a4646031e2d78cfafb7892848fae835f503313c8d7d34ab471b","vout":15,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00665402,"interest":0,"confirmations":1149,"spendable":false}, {"txid":"352fc051230c1d876790d922c31eb1e1d985040cfee6726cba8fc2821c424d20","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00701349,"interest":0,"confirmations":1467,"spendable":false}, {"txid":"c3561d377aac0da1b90ef510e4e831b789fc62cca98aa627624175fe16393023","vout":6,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01100992,"interest":0,"confirmations":2701,"spendable":false}, {"txid":"993fbe0918af1f38603b57667387bdc02e3f44b8ad6acfcdec86b76365605a23","vout":10,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01106048,"interest":0,"confirmations":1087,"spendable":false}, {"txid":"b07fa68d7aa5b3003966eadd6a938273906f711c48c9debc59f20d81c7b35328","vout":19,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00526488,"interest":0,"confirmations":1467,"spendable":false}, {"txid":"e803179a482cfeb95fbfcb8085eb1b4e391be9251cddaeb42f8c66a23a0d312a","vout":4,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00314295,"interest":0,"confirmations":1397,"spendable":false}, {"txid":"7026d021aeb4b5b942e2acc9f256f0cc1c92d45671c5055359d5ec50fa97d72c","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00885260,"interest":0,"confirmations":1374,"spendable":false}, {"txid":"2baa69378c4925e19eb184dcad67f205762e5487e843494dd60efcaba1ac172d","vout":3,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00421993,"interest":0,"confirmations":1115,"spendable":false}, {"txid":"99fa9c033552a6048750447489adbc2dea26622c1001632f7b8c06b4accbce30","vout":12,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00566009,"interest":0,"confirmations":1372,"spendable":false}, {"txid":"c9d4ee0b3ff4df7eea1de6f3102c9a5591f6993fdef7f42ce33f2bb482abcd32","vout":4,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01261726,"interest":0,"confirmations":1407,"spendable":false}, {"txid":"d1f05d205d984367c14a8a8438dca9e32e76b008e1d946469ac2e5d212079533","vout":9,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01059540,"interest":0,"confirmations":1107,"spendable":false}, {"txid":"df8bb09b02ad3e8aaebe3165ab5f96e5bec5b80e63cd6c3bf967cfb69c5b5135","vout":9,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01986436,"interest":0,"confirmations":2716,"spendable":false}, {"txid":"88a55a4f2633c5159a1a06de9918b2bf26d566c4640295b0cc4e6e6f48538737","vout":15,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00268519,"interest":0,"confirmations":1361,"spendable":false}, {"txid":"5f4f5659d4a3acd0539fc176d5139ce51491a3cf9eb83d602cf992257bcf933d","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.02744666,"interest":0,"confirmations":1144,"spendable":false}, {"txid":"ffbcd4500aa048e2c1aa0c37fcbab94750eb3e02d18bc71f25db07182bf16a40","vout":9,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01112878,"interest":0,"confirmations":1160,"spendable":false}, {"txid":"57f0a89aeb568bf57b974465d3b812246b32d2398d94db331abf15370aad8041","vout":10,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01432566,"interest":0,"confirmations":1051,"spendable":false}, {"txid":"986418ea33eaba1278cb08a2dc305489c86cf22933eadfd58f9befd820458f41","vout":14,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00856760,"interest":0,"confirmations":1101,"spendable":false}, {"txid":"11395f83c4860b64e22ca77e07116b2e96a501565cb17cda329765ab00645242","vout":1,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00943416,"interest":0,"confirmations":1462,"spendable":false}, {"txid":"b536456595ba73aba63b69fb5075b9d1f5f289398376997c3c3fdb68734b9642","vout":11,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00612259,"interest":0,"confirmations":1399,"spendable":false}, {"txid":"f8a80427d6c0ef72eb64bba08c36b789a982c9d3ab0a3777f436c8eaa8f77644","vout":19,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00521255,"interest":0,"confirmations":1356,"spendable":false}, {"txid":"188a47e31739d850615e33edf4eed1d1c744e07559eb0c760780de17330e9b46","vout":8,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00910425,"interest":0,"confirmations":1343,"spendable":false}, {"txid":"3b7c97e7332838588de3f10a1e23d8c9a10872ada9be80fde0fc1ff561c23648","vout":11,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00952047,"interest":0,"confirmations":1417,"spendable":false}, {"txid":"5339d7d749dbb3c9314b35ae70f05dedbcc4e758d1e1bcb9abc7a3fc5329f349","vout":2,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.02073963,"interest":0,"confirmations":2721,"spendable":false}, {"txid":"3ba28a1307d0363570d5b706e6dd09aef743f0d05e693832ca765394f7c41e4e","vout":19,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00621014,"interest":0,"confirmations":1297,"spendable":false}, {"txid":"bfdca7f7e09dd3ef2e1c1c49e71fa3681f88a194a53ad95b208af01137959550","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00733389,"interest":0,"confirmations":1265,"spendable":false}, {"txid":"1734b70fcb0c2123d8049bc56f394d9b50d22dc751367c7fbfd67b4cf989b252","vout":7,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00983429,"interest":0,"confirmations":1186,"spendable":false}, {"txid":"aba1765eae6ae3775c7d47f59bf58a374f05ae403cb4b6f9d986ef1a50811e57","vout":6,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01065549,"interest":0,"confirmations":1301,"spendable":false}, {"txid":"9a0cc13dbe59242305096c841ae42221afb5fb851c43d321df70654971d7265a","vout":6,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.02459878,"interest":0,"confirmations":2734,"spendable":false}, {"txid":"2d9cd7054519b54db703f695f17714fd6bd5489f574841c23b0bb43a4bd7ba5d","vout":5,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01329245,"interest":0,"confirmations":1126,"spendable":false}, {"txid":"9beb21735c0930ddf6bc9ea67b8f404aa9fe80072bf76ab81faf6ec9be99905f","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00859989,"interest":0,"confirmations":1281,"spendable":false}, {"txid":"e9b48ecc042fbb6c77e6e4b21f43692d71d0144fa2c6b7ef794184a68ba0d760","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00785788,"interest":0,"confirmations":1347,"spendable":false}, {"txid":"6d88e4e4ed0d8967da43d1b6eee83b94ad78d14c8877d06c82ac35bb60bcd760","vout":8,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00791355,"interest":0,"confirmations":1242,"spendable":false}, {"txid":"0c9e5e42b42716372cef64e57445a773116947308efea29ac113a86121fe3e63","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00424481,"interest":0,"confirmations":1307,"spendable":false}, {"txid":"7af339ad8a87ec08698db03043a367670f76aa8dcd3c004ba9cf0dcd1428a864","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00685187,"interest":0,"confirmations":1264,"spendable":false}, {"txid":"7ea70f558030df794bb1fa67e4e51d1c24f6d41b1cad8ebe327682a32b8f3365","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00695979,"interest":0,"confirmations":1127,"spendable":false}, {"txid":"8e83163da7dd6da216b1f4d0d0ea940177245c7176260d080c8d36c85bef4567","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00546768,"interest":0,"confirmations":1334,"spendable":false}, {"txid":"31410d5f178aea4df25161ce8719163bd440c493c718fbefd730cba49e263769","vout":7,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00968797,"interest":0,"confirmations":1346,"spendable":false}, {"txid":"3994fe679613f3145d3dd27109bab353e16fd8f5fb169e31b0690226ad9b3b69","vout":2,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00503324,"interest":0,"confirmations":1411,"spendable":false}, {"txid":"dc4fcd0a5c1d801c9609f46dd6cd4ae0770070b07ea61c3d8e316f690348e369","vout":21,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00282306,"interest":0,"confirmations":1395,"spendable":false}, {"txid":"b486834231262a28acd961276d53c27218c54319e1c9a258686754552185666a","vout":11,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00610634,"interest":0,"confirmations":1386,"spendable":false}, {"txid":"b193bd9f00033ee9995a4fb9b921bdc5b5c134f91e03342a11bc36c8ff9e0b6b","vout":6,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00969490,"interest":0,"confirmations":1167,"spendable":false}, {"txid":"5046a3807224c8b371cf02039b2f2de8cd303fd34bcbabf29aff0bbf6c875d6b","vout":18,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00630832,"interest":0,"confirmations":1291,"spendable":false}, {"txid":"3210eb89537fff99348bcf376b31ca58c2328d1a67491874ea8a26661daf846f","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00713650,"interest":0,"confirmations":1146,"spendable":false}, {"txid":"131ee5ff930695508dcc0218c8b41f054bd659072ab9f75c82a8af0282dc2771","vout":20,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00368007,"interest":0,"confirmations":1368,"spendable":false}, {"txid":"121147ed84dad42ee323b813b6f9c6a5e1cd55f720d5d037b1f2409c5826f672","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01811952,"interest":0,"confirmations":1296,"spendable":false}, {"txid":"febe351b6b7ae6fa9bddb43a7d0a92ff7e90d8415a1ba8abbafea5852ce6f674","vout":18,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00372863,"interest":0,"confirmations":1047,"spendable":false}, {"txid":"487905accfbfee70b6098f6f430055331f84b34f00c5f9d58a0eb7ac41993575","vout":14,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00466854,"interest":0,"confirmations":1429,"spendable":false}, {"txid":"8c2c33d01e7c5f22a7476ead0d100eddb87699f89f87882e08443b4df5045675","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00157732,"interest":0,"confirmations":1406,"spendable":false}, {"txid":"4184c1d46c913cb09515e2f84dfe5f11222ca236262c8b2bbe3f34d4cc876476","vout":19,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00642229,"interest":0,"confirmations":1391,"spendable":false}, {"txid":"4b3ec8b011f5f22fd9f23f893e3bd6ed03cf96c47df4f2f82a41b51f638d4678","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00893917,"interest":0,"confirmations":1355,"spendable":false}, {"txid":"7e86b5169451ee5df16795ccdeb2626190c194741df98619433e1eb0be4ca079","vout":11,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00516451,"interest":0,"confirmations":1151,"spendable":false}, {"txid":"8f3acb4469da0e43de5d726749ebe043ec9a15247e2de0b6a3cf92347d3c3f7a","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00864817,"interest":0,"confirmations":1105,"spendable":false}, {"txid":"0a32c2ec89847d1dcae3b2a11b162299da2feddd50b0aa7e19a2d7bc20e8827b","vout":10,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00597305,"interest":0,"confirmations":1117,"spendable":false}, {"txid":"060625cd637de926bc9e7f7cdba348f2d9b747df3537347c86f81acd63bc9881","vout":1,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00783683,"interest":0,"confirmations":1323,"spendable":false}, {"txid":"2e3deaad6d080a0bf827ff288c87028fd812996a3333d1e600095abe41e3668a","vout":11,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00550427,"interest":0,"confirmations":1120,"spendable":false}, {"txid":"c9450161135bc76cb18d8779eb2e0dd619cc89710de2107ae57b2369aa596f90","vout":19,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00887483,"interest":0,"confirmations":1438,"spendable":false}, {"txid":"5fe805b8f566d242e1a432c13a69684d2827c5de2ba3d97f291fedfcf5e75191","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00790383,"interest":0,"confirmations":1350,"spendable":false}, {"txid":"96397faab2cf65f60fb8053ca6cd97b61f2716f20ada01d8297b8a9adcb89893","vout":3,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01200450,"interest":0,"confirmations":1102,"spendable":false}, {"txid":"f193974d77f8ccc786b55ca717b6ed4faaaebc8587d61b12cdd7f4b4f6861796","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00761196,"interest":0,"confirmations":1440,"spendable":false}, {"txid":"aad7678ce5c8c23c45a256218a0c1b023b134d7774427d2828e4d219748b0897","vout":6,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00626419,"interest":0,"confirmations":1332,"spendable":false}, {"txid":"1d9e90ccd04a3d0fd73060f864e4379593041dd606b602a23d61b9f09ef42498","vout":20,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00462091,"interest":0,"confirmations":1267,"spendable":false}, {"txid":"a6eada7c7495789373f858a6cb8f4ac9ebb2535982ea523a43a4a9f504d94399","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00840952,"interest":0,"confirmations":1173,"spendable":false}, {"txid":"512c2d69db68f4391d9fb4c84d80fcf53e9b3a81e31e030c8a65fdbbc7a0de9c","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01178953,"interest":0,"confirmations":1082,"spendable":false}, {"txid":"2c8ae4adc0b0d7c40d938a8f38afd71feaec4a3144ac63d1c1a34eb0bd3aa19f","vout":10,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00716348,"interest":0,"confirmations":1270,"spendable":false}, {"txid":"b5a92680c52711ed0b16206276a4b45d063ca1243368c9d2cf1ee492b82144a2","vout":7,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00831259,"interest":0,"confirmations":1155,"spendable":false}, {"txid":"73470f45e3e4cba240115700971b1e6240ca13b3c62293204a03c77461cd55a2","vout":3,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01006952,"interest":0,"confirmations":1093,"spendable":false}, {"txid":"22146d8a726420d7d1078cfb6b295c88349b0baa683de8eadc57572be786c4a5","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01730597,"interest":0,"confirmations":1134,"spendable":false}, {"txid":"6ef90f74424ace52371d633151c535678d2281b88e9fe06c14b313bac38fe5a8","vout":15,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00744924,"interest":0,"confirmations":1413,"spendable":false}, {"txid":"2f0c130a4aaa46600f7719002830a9f83842391587c6ef49860c30dfc6749dab","vout":9,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00864042,"interest":0,"confirmations":1068,"spendable":false}, {"txid":"49bd90bedeb580d5e3fcb617a3c141b408ba12379599721a2cd7ba7152a2a6ad","vout":12,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01154847,"interest":0,"confirmations":1078,"spendable":false}, {"txid":"9342c64732d50dea3bac94fc0bc7b954bddeac3cb8b684bd2c8204b02c40ceae","vout":8,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01840402,"interest":0,"confirmations":2659,"spendable":false}, {"txid":"dfb11f4f1e67111ffc9d60f6efb365e3a5f11e6cef084b4172381203831382b1","vout":1,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01870672,"interest":0,"confirmations":2637,"spendable":false}, {"txid":"e1f21b4318ab46e0d211ed97ee01a704e53d98917f23f6c818100d986bd80bb2","vout":15,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00512471,"interest":0,"confirmations":1150,"spendable":false}, {"txid":"4bb2a7c478836f7e18a4cfa806cbceaa3fd9ff9aca58f4e755855443ccb620b2","vout":1,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.02202293,"interest":0,"confirmations":2717,"spendable":false}, {"txid":"c435df68eeef82a2bde58a1812b76bb3f8c00656a522ae9b860580e3467b5cb5","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00580545,"interest":0,"confirmations":1129,"spendable":false}, {"txid":"4865355fc1baa8421a464cce4da2d315382e540971b1bcb124bbe5d8b03a86b7","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00877250,"interest":0,"confirmations":1187,"spendable":false}, {"txid":"23dffe7825f8c505ad7fa20c0b2965fde26f23cb993468e50c8a9b9770df8bb9","vout":19,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00694376,"interest":0,"confirmations":1053,"spendable":false}, {"txid":"cc72da120b0fd652295452da0849a6cd1152217d3b1c8f7b65e79ccaba80bcba","vout":0,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01418229,"interest":0,"confirmations":1636,"spendable":false}, {"txid":"a39ac2fd436c43578432a44839b9ce857d0f3fe3a533113420fc3cb76e8736bb","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00624705,"interest":0,"confirmations":1137,"spendable":false}, {"txid":"7b2f034d2b2ad151f6e6c7115f7e7aa34c69e98d96b64e3f506feded029f04bc","vout":20,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00931144,"interest":0,"confirmations":1421,"spendable":false}, {"txid":"b98558e12045289dcd83f771539a857000a95597a0f60dfd6c5e0dbc65d5c2bc","vout":7,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00676310,"interest":0,"confirmations":1125,"spendable":false}, {"txid":"d0c58ec1be2ca99a43fb15bccde428646bafe29c5be94964077e25a0f4b884be","vout":14,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00774338,"interest":0,"confirmations":1076,"spendable":false}, {"txid":"dbbd3cc00162e951394b6d42923956a81b23ae00f2e48144abf5f297568cbfbe","vout":14,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01053496,"interest":0,"confirmations":1387,"spendable":false}, {"txid":"75e7bc18236559f4bfc7dade78ed892a81a8a1f5275b88c25539cbd927040abf","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00440310,"interest":0,"confirmations":1050,"spendable":false}, {"txid":"c33cffe0c00e3fd2f528288c9fd25ab95b5d5c01aab3201dc5cef0a0f0a58bc0","vout":20,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00262218,"interest":0,"confirmations":1450,"spendable":false}, {"txid":"1dfff8505abbd8c3aef5881089a0d5f4783b9a70872732881dd4d5abd5f305c4","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01086472,"interest":0,"confirmations":1414,"spendable":false}, {"txid":"279a6adee3aedf33bdfb365e1cb63b10a358ba74c933633df74d4f192621adc4","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00439698,"interest":0,"confirmations":1232,"spendable":false}, {"txid":"1c67dac7c847799540b0c56821a3c475ee36acf436e42bbb8a6435f3f587b7c5","vout":10,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00652334,"interest":0,"confirmations":1179,"spendable":false}, {"txid":"23bf5d2f304de41e230ba77e061644266b4c22a6b91616c4aaa3d528a062ecc5","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00877710,"interest":0,"confirmations":1194,"spendable":false}, {"txid":"a1d338ba13653499adbf27947f6065e1bc84a8744fb8a49535008fb13b2737c9","vout":12,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01438530,"interest":0,"confirmations":1125,"spendable":false}, {"txid":"358fcdf9fdc20abbdb8f5fdbbd9585b8165ad3b0410c24a69aa53822abf792c9","vout":16,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00307368,"interest":0,"confirmations":1269,"spendable":false}, {"txid":"cdcdcf82ac51ae1dd38f58c3c689718bc8804abad3294c45840c4b858dda1cd1","vout":7,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00511442,"interest":0,"confirmations":1294,"spendable":false}, {"txid":"585435759b98ccc0d01175b8c8d2e719a7cb3939fb07ba959d8f3ba03d7c10d8","vout":15,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01066779,"interest":0,"confirmations":1182,"spendable":false}, {"txid":"9988778e53f3a3eb76ca68f4cb7e9560ea93610b6bcece01c05a98f387bfd9da","vout":14,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00780207,"interest":0,"confirmations":1353,"spendable":false}, {"txid":"be31e40ff1416e7f89a3e049597f3fec4344a201e8d824f7b4a3737637b015db","vout":14,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01404766,"interest":0,"confirmations":1100,"spendable":false}, {"txid":"20f05e8062fad7d21da0d9ae38000fefb1e1931519a2bf63431ac5e314a768db","vout":12,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00749217,"interest":0,"confirmations":1141,"spendable":false}, {"txid":"aeb39206af9af3a63c4817b3047b30cf866e3f5f0de5de164dff853ad4214bdf","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00816592,"interest":0,"confirmations":1464,"spendable":false}, {"txid":"a8b79ea22755b4b5f5f9d3a1feb70a248d19557d38810f020303602c5cbb29e2","vout":1,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.01384652,"interest":0,"confirmations":1465,"spendable":false}, {"txid":"7bc3a326e928a04b05d3836a1457ab346eead59481d4cd127b301d001c6b9ee7","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00720479,"interest":0,"confirmations":1314,"spendable":false}, {"txid":"8d51ab86bed67202fbfa6bc06ddd33295d100295db7ba51f0cc252e1e9cf24e8","vout":22,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00497993,"interest":0,"confirmations":1282,"spendable":false}, {"txid":"981960dcf355510ab467fad6c198525b02a788ffe88c9c74565a147300ee62e9","vout":8,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00989940,"interest":0,"confirmations":1409,"spendable":false}, {"txid":"ce213ee1a323195ee310ff4d2b5cb53df827f3734fe547a6f7fe1758ae0bf4ea","vout":6,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00768125,"interest":0,"confirmations":1134,"spendable":false}, {"txid":"691119613bc98b511ee059f650deed19037213ed232f8255088cb17bd8ac44ec","vout":13,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00664659,"interest":0,"confirmations":1384,"spendable":false}, {"txid":"fd2f68b95870dfd9f561ba774f35ff3d7b36c347188967ad862bfa2dbc72a2ec","vout":10,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.02082492,"interest":0,"confirmations":2718,"spendable":false}, {"txid":"3b4c897e393b69ce33a6c859df92b6329f4573014302038011c51ccd0ec03df1","vout":18,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00415590,"interest":0,"confirmations":1321,"spendable":false}, {"txid":"a9df763b38e7a74af38f8c712f2f17345f6f86f03ce0232247b85d36ec1b41f8","vout":11,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00452971,"interest":0,"confirmations":1289,"spendable":false}, {"txid":"31831080a4abc3bd5aab9561fe1ecf153b7a1250cbab945e94d48e77215322f9","vout":17,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00487729,"interest":0,"confirmations":1060,"spendable":false}, {"txid":"7fb8dac10ca8aaa6a43dc61b648808b4ddb08bed9dcc6b60c282754b9bf1eaf9","vout":7,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.02013728,"interest":0,"confirmations":2701,"spendable":false}, {"txid":"83c4343974bbc028fd8ea6f5747ee2eb13ceb3916d0fd5e1a686a25d02f837fa","vout":8,"address":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","account":"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL","scriptPubKey":"76a9143e4867d0286093210984cc4dc2aabdd4e1c4da4c88ac","amount":0.00651217,"interest":0,"confirmations":1112,"spendable":false}] +12356.73789711 <- expected amount RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL +[{"txid":"eb6734a2f9ff4b8297fa91867286264cf8998e33d11474773bfd3fe5e0278d0b","vout":1,"address":"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct","account":"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct","scriptPubKey":"76a914aeb33755d5b9797988f0ab88e00765521e10bf4388ac","amount":50303.39904535,"interest":33.09434147,"confirmations":6102,"spendable":false}, {"txid":"1c8b0cdcc1c1dd7a6f0f490fb57294427436ef99d362e06ebe17877313464e16","vout":1,"address":"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct","account":"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct","scriptPubKey":"76a914aeb33755d5b9797988f0ab88e00765521e10bf4388ac","amount":50006.03027000,"interest":36.23625381,"confirmations":6706,"spendable":false}, {"txid":"e1e7e0a58e522106fe4d0f88948dd5f76adfe8e3029b8da0914d9db7b5e162e7","vout":1,"address":"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct","account":"RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct","scriptPubKey":"76a914aeb33755d5b9797988f0ab88e00765521e10bf4388ac","amount":14070.80002269,"interest":5.96220339,"confirmations":3753,"spendable":false}] +12561.43380413 <- expected amount RRCvM3vVV6FPwayTevCCvkpXY2V8RxjEct +[{"txid":"e3c49fbe2d4ea57e5c83f6a72706a61178912bfe4dc18d5bfbb8835aa6a27139","vout":1,"address":"RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6","account":"RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6","scriptPubKey":"76a9147564457ef3063790d1d7470ddb03cbd2dcf062ee88ac","amount":4453.35929709,"interest":0,"confirmations":3,"spendable":false}] +4453.35929709 <- expected amount RKyuFwhojJgYNUQjuHWEcDUouiPHCpbRS6 +[{"txid":"826c78814f9725ff98200417d171ae0a6229bad39197a58df3dc02ab3cb6ce45","vout":1,"address":"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw","account":"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw","scriptPubKey":"76a91409781a2fa8f33ffbebdb0b866001c0d080a822d488ac","amount":4521.29210647,"interest":0,"confirmations":3,"spendable":false}, {"txid":"319a048094d2c8e707b0d7e96173efbb5f1e7141258a26a5ea7275ba8f20aec5","vout":1,"address":"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw","account":"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw","scriptPubKey":"76a91409781a2fa8f33ffbebdb0b866001c0d080a822d488ac","amount":868087.38826767,"interest":447.46772591,"confirmations":4819,"spendable":false}] +4521.29210647 <- expected amount RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw +[{"txid":"63a2314d5f88f7331ab55c696c1c978af200671a0ba89ba2c3a83c618f1a2890","vout":1,"address":"RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv","account":"RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv","scriptPubKey":"76a9145b3f020bc394703a9fcfcf2365363a3002f59a1e88ac","amount":11653.72856174,"interest":0,"confirmations":3,"spendable":false}] +11653.72856174 <- expected amount RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv +[{"txid":"1f9b50f730e18a267d4e0a1381d1a94544b8fdee8fe15b626b30f3bd6d0478a6","vout":1,"address":"RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR","account":"RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR","scriptPubKey":"76a91475da926fb76e671d645cdebee9de20795e1de4db88ac","amount":1561.74292091,"interest":0,"confirmations":2,"spendable":false}] +1561.74292091 <- expected amount RL2LycM1d3STMFXMN7ipcNfNejhieFeQDR +[{"txid":"1fdf240fe884fc0ca54f07e0eac9b39792dd2ddad10e5b528858f7cdb37f4762","vout":1,"address":"RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv","account":"RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv","scriptPubKey":"76a9142b55c9ca9a88801686be5f9b821956f72baecdc688ac","amount":25107.55827068,"interest":0,"confirmations":2,"spendable":false}] +25107.55827068 <- expected amount RDEKuSHP6Ues1gi4ex2vt9rpBEeKAqPWfv +[{"txid":"6d365c4ce11ccf2b5bd1635030616e73d38598de2bf8fb17a86ce1732dc3322c","vout":1,"address":"RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt","account":"RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt","scriptPubKey":"76a914a188baf22bc0aa0984d9d5442c96226ce26450ed88ac","amount":391.52338368,"interest":0,"confirmations":2,"spendable":false}] +391.52338368 <- expected amount RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt +[{"txid":"d74721f064415a3ceffac8a8ca55cb3d0017f692c4c1e3ec6f3818f4dcc0c812","vout":1,"address":"RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx","account":"RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx","scriptPubKey":"76a914118b2ae1526f5bc94d4dee641ac95a0b2d4f61c988ac","amount":2212.41539458,"interest":0,"confirmations":2,"spendable":false}] +2212.41539458 <- expected amount RAsxHJd4zrSxvhQedDeTRaANwv6eG9CYjx +[{"txid":"ed6261d0bf246e57c9acd4b08ee29ce0dccef714fb128e1dc9d6f4dc9e99336b","vout":1,"address":"RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5","account":"RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5","scriptPubKey":"76a9147757bdffcab398ea09edc8299a115117d1b80eff88ac","amount":12079.07428158,"interest":0,"confirmations":2,"spendable":false}] +12079.07428158 <- expected amount RLADbn4XTgAbsCcENNhUPX2Kb5KcX7hfs5 +[{"txid":"8d94f05fca74b59348108a8b949f98b18410776e57654da781a538d57ff5a6d7","vout":1,"address":"RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh","account":"RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh","scriptPubKey":"76a91437728989c5bee50920a145c009827d978007059288ac","amount":2323.95659850,"interest":0,"confirmations":2,"spendable":false}] +2323.95659850 <- expected amount RELNTFjyhMRntuSbrvJSnG9LSt8ycmD5eh +[{"txid":"7eaba7517f7a3027c36018d0a25f3ee540af3690729471ecd383bf1eb1313f51","vout":1,"address":"RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r","account":"RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r","scriptPubKey":"76a91447819bd839f7bcc4483fd7d4741da201e0bb598d88ac","amount":682.83148523,"interest":0,"confirmations":2,"spendable":false}] +682.83148523 <- expected amount RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r +[{"txid":"19c01565bf79e109542aeeb45cb8dbda91963eba2b21ff76a05ae8c7b5984c8d","vout":1,"address":"RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3","account":"RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3","scriptPubKey":"76a914dd614cc5feeafc8b73c46797771cf9ac8c91343488ac","amount":48415.76246875,"interest":0,"confirmations":2,"spendable":false}] +48415.76246875 <- expected amount RVTjyRex85TVcNwy5vW7JrmtfEt9y45Sx3 +[{"txid":"0fe813014cf95822730981d8905f9a7a2ccf1ebb1344fbcdf3be7f7b5f542618","vout":1,"address":"RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD","account":"RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD","scriptPubKey":"76a91482284d0e543aa213647fbffa6ac9ec16abe8c71988ac","amount":8133.84809475,"interest":0,"confirmations":2,"spendable":false}] +8133.84809475 <- expected amount RM9QCciRjSeoctNUzwfVh2gY6H8Qfc2anD +[{"txid":"fa44d50d6af4bacb6619acacf420538e012de6eeb0f436ef9c4d34f315317970","vout":1,"address":"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS","account":"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS","scriptPubKey":"76a9140e5082ca36cc024a4dca642c987ac4dd5947800988ac","amount":0.75495995,"interest":0,"confirmations":3108,"spendable":false}, {"txid":"76dd0c3f7acfc2f12d1c140f228d82753182e86374660d8651f83683bebe20b2","vout":1,"address":"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS","account":"RAaszCNodXXu9rJL6qqVMZDykXncDecTMS","scriptPubKey":"76a9140e5082ca36cc024a4dca642c987ac4dd5947800988ac","amount":693.08132289,"interest":0,"confirmations":2,"spendable":false}] +693.08132289 <- expected amount RAaszCNodXXu9rJL6qqVMZDykXncDecTMS +[{"txid":"61e32c84221d569c5b449d0992f36eff52f092abcfd029015949b537bb081969","vout":1,"address":"RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57","account":"RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57","scriptPubKey":"76a914d7ee07dc677d00cab9d78fffd2e18b1af661781988ac","amount":1773.66877470,"interest":0,"confirmations":2,"spendable":false}] +1773.66877470 <- expected amount RUxvWRVR7xEqTbxF43nE1roPXfppbsDL57 +[{"txid":"93ffd2beecc84da8c6bf084509db507ed03fb12049128ef356a2d6f739716d60","vout":1,"address":"RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa","account":"RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa","scriptPubKey":"76a9140cc7a922f193aa8b78f5a6f4a77fdff7ec8ca54588ac","amount":2971.54458972,"interest":0,"confirmations":2,"spendable":false}] +2971.54458972 <- expected amount RASmNV8wHNdhU78WnoFwu9aLpM4zS4EFNa +[{"txid":"4264b28ca78c9bacedc50befb824e82b8fd16873a75bc02874908949ce1bdd4f","vout":1,"address":"RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR","account":"RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR","scriptPubKey":"76a91450f5124256108379f7d7d47feb68d9b26ff1f4a588ac","amount":3351.00027124,"interest":0,"confirmations":2,"spendable":false}] +3351.00027124 <- expected amount RGfFiiX5euPb4GCpB76VfVdrFJhPWoJZQR + diff --git a/iguana/tests/KMD.batch7 b/iguana/tests/KMD.batch7 new file mode 100755 index 000000000..a2e06e71e --- /dev/null +++ b/iguana/tests/KMD.batch7 @@ -0,0 +1,237 @@ +sleep 9999999 +# RRcW51evLjdXhEne82mejRwTf8RAMvPxbf KMD 9682.18417850 +./komodo-cli sendtoaddress RRcW51evLjdXhEne82mejRwTf8RAMvPxbf 9682.18417850 +sleep 3 +echo "9682.18417850 <- expected amount RRcW51evLjdXhEne82mejRwTf8RAMvPxbf" + +# RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi KMD 19824.65353390, REVS 393.51044761 +# RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi KMD 19824.65353390 +./komodo-cli sendtoaddress RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi 19824.65353390 +sleep 3 +echo "19824.65353390 <- expected amount RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi" + +# RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda KMD 5932.50248029 +./komodo-cli sendtoaddress RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda 5932.50248029 +sleep 3 +echo "5932.50248029 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda" + +# RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2 KMD 3202.01278205 +./komodo-cli sendtoaddress RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2 3202.01278205 +sleep 3 +echo "3202.01278205 <- expected amount RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 2.29796059 +./komodo-cli sendtoaddress RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 2.29796059 +sleep 3 +echo "2.29796059 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ KMD 11827.69657925 +./komodo-cli sendtoaddress RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ 11827.69657925 +sleep 3 +echo "11827.69657925 <- expected amount RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ" + +# RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u KMD 9757.57240097 +./komodo-cli sendtoaddress RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u 9757.57240097 +sleep 3 +echo "9757.57240097 <- expected amount RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u" + +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 495.97007681 +./komodo-cli sendtoaddress RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX 495.97007681 +sleep 3 +echo "495.97007681 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX" + +# RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH KMD 138721.51640953, REVS 2656.00000000 +# RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH KMD 138721.51640953 +./komodo-cli sendtoaddress RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH 138721.51640953 +sleep 3 +echo "138721.51640953 <- expected amount RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc KMD 1174.11345835 +./komodo-cli sendtoaddress RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc 1174.11345835 +sleep 3 +echo "1174.11345835 <- expected amount RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc" + +# RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA KMD 9683.15249375 +./komodo-cli sendtoaddress RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA" + +# RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL KMD 47.52053869, REVS 0.94300273 +# RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL KMD 47.52053869 +./komodo-cli sendtoaddress RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL 47.52053869 +sleep 3 +echo "47.52053869 <- expected amount RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL" + +# RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx KMD 845.90749755 +./komodo-cli sendtoaddress RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx 845.90749755 +sleep 3 +echo "845.90749755 <- expected amount RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx" + +# RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x KMD 1660.54445484 +./komodo-cli sendtoaddress RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x 1660.54445484 +sleep 3 +echo "1660.54445484 <- expected amount RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x" + +# RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN KMD 55313.07943406 +./komodo-cli sendtoaddress RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN 55313.07943406 +sleep 3 +echo "55313.07943406 <- expected amount RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN" + +# RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc KMD 30986.08798000 +./komodo-cli sendtoaddress RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc 30986.08798000 +sleep 3 +echo "30986.08798000 <- expected amount RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc" + +# RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj KMD 34809.11928944 +./komodo-cli sendtoaddress RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj 34809.11928944 +sleep 3 +echo "34809.11928944 <- expected amount RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 4331.80770687 +./komodo-cli sendtoaddress RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni 4331.80770687 +sleep 3 +echo "4331.80770687 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RKXi56k97RZcs6CW2chTL286HSjgrEtAsN KMD 880.19856168 +./komodo-cli sendtoaddress RKXi56k97RZcs6CW2chTL286HSjgrEtAsN 880.19856168 +sleep 3 +echo "880.19856168 <- expected amount RKXi56k97RZcs6CW2chTL286HSjgrEtAsN" + +# RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx KMD 967.34693412 +./komodo-cli sendtoaddress RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx 967.34693412 +sleep 3 +echo "967.34693412 <- expected amount RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx" + +# RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr KMD 1192.08225695 +./komodo-cli sendtoaddress RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr 1192.08225695 +sleep 3 +echo "1192.08225695 <- expected amount RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr" + +# RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb KMD 405.34611747 +./komodo-cli sendtoaddress RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb 405.34611747 +sleep 3 +echo "405.34611747 <- expected amount RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb" + +# RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4 KMD 6712.04424766 +./komodo-cli sendtoaddress RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4 6712.04424766 +sleep 3 +echo "6712.04424766 <- expected amount RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4" + +# RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA KMD 6087.83670543 +./komodo-cli sendtoaddress RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA 6087.83670543 +sleep 3 +echo "6087.83670543 <- expected amount RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA" + +# RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC KMD 11792.89870264 +./komodo-cli sendtoaddress RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC 11792.89870264 +sleep 3 +echo "11792.89870264 <- expected amount RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC" + +# RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on KMD 22265.01478541 +./komodo-cli sendtoaddress RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on 22265.01478541 +sleep 3 +echo "22265.01478541 <- expected amount RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on" + +# RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH KMD 9295.82639400 +./komodo-cli sendtoaddress RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH" + +# RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2 KMD 92958.26394000 +./komodo-cli sendtoaddress RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2 92958.26394000 +sleep 3 +echo "92958.26394000 <- expected amount RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2" + +# RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA KMD 25176.19648375 +./komodo-cli sendtoaddress RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA 25176.19648375 +sleep 3 +echo "25176.19648375 <- expected amount RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA" + +# RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2 KMD 3457.58494193 +./komodo-cli sendtoaddress RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2 3457.58494193 +sleep 3 +echo "3457.58494193 <- expected amount RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2" + +# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 30.59737295 +./komodo-cli sendtoaddress RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz 30.59737295 +sleep 3 +echo "30.59737295 <- expected amount RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 1506.60352500 +./komodo-cli sendtoaddress RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut 1506.60352500 +sleep 3 +echo "1506.60352500 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy KMD 9683.15249375 +./komodo-cli sendtoaddress RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy" + +# RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP KMD 3725.18622956 +./komodo-cli sendtoaddress RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP 3725.18622956 +sleep 3 +echo "3725.18622956 <- expected amount RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP" + +# RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7 KMD 1486.32571743 +./komodo-cli sendtoaddress RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7 1486.32571743 +sleep 3 +echo "1486.32571743 <- expected amount RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7" + +# RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX KMD 7435.09663624, REVS 70.73874773 +# RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX KMD 7435.09663624 +./komodo-cli sendtoaddress RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX 7435.09663624 +sleep 3 +echo "7435.09663624 <- expected amount RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX" + +# RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc KMD 9034.38127666 +./komodo-cli sendtoaddress RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc 9034.38127666 +sleep 3 +echo "9034.38127666 <- expected amount RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 258541.07773074 +./komodo-cli sendtoaddress RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX 258541.07773074 +sleep 3 +echo "258541.07773074 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 7315.56699076 +./komodo-cli sendtoaddress REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk 7315.56699076 +sleep 3 +echo "7315.56699076 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk" + +# RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr KMD 6679.18894509 +./komodo-cli sendtoaddress RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr 6679.18894509 +sleep 3 +echo "6679.18894509 <- expected amount RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr" + +# RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm KMD 157.99530650 +./komodo-cli sendtoaddress RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm 157.99530650 +sleep 3 +echo "157.99530650 <- expected amount RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm" + +# RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu KMD 661.93286780 +./komodo-cli sendtoaddress RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu 661.93286780 +sleep 3 +echo "661.93286780 <- expected amount RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu" + +# RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa KMD 5022.01175000 +./komodo-cli sendtoaddress RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa 5022.01175000 +sleep 3 +echo "5022.01175000 <- expected amount RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 5206.02159816 +./komodo-cli sendtoaddress RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 5206.02159816 +sleep 3 +echo "5206.02159816 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 10312.37298338 +./komodo-cli sendtoaddress RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 10312.37298338 +sleep 3 +echo "10312.37298338 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1" + + +# total KMD 846978.97207339 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch7.importaddress b/iguana/tests/KMD.batch7.importaddress new file mode 100755 index 000000000..6dc3c2d68 --- /dev/null +++ b/iguana/tests/KMD.batch7.importaddress @@ -0,0 +1,234 @@ +# RRcW51evLjdXhEne82mejRwTf8RAMvPxbf KMD 9682.18417850 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRcW51evLjdXhEne82mejRwTf8RAMvPxbf\",\"symbol\":\"KMD\"}" # 9682.18417850 +sleep 3 +echo "9682.18417850 <- expected amount RRcW51evLjdXhEne82mejRwTf8RAMvPxbf" + +# RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi KMD 19824.65353390, REVS 393.51044761 +# RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi KMD 19824.65353390 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi\",\"symbol\":\"KMD\"}" # 19824.65353390 +sleep 3 +echo "19824.65353390 <- expected amount RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi" + +# RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda KMD 5932.50248029 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda\",\"symbol\":\"KMD\"}" # 5932.50248029 +sleep 3 +echo "5932.50248029 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda" + +# RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2 KMD 3202.01278205 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2\",\"symbol\":\"KMD\"}" # 3202.01278205 +sleep 3 +echo "3202.01278205 <- expected amount RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2" + +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 2.29796059 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"KMD\"}" # 2.29796059 +sleep 3 +echo "2.29796059 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3" + +# RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ KMD 11827.69657925 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ\",\"symbol\":\"KMD\"}" # 11827.69657925 +sleep 3 +echo "11827.69657925 <- expected amount RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ" + +# RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u KMD 9757.57240097 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u\",\"symbol\":\"KMD\"}" # 9757.57240097 +sleep 3 +echo "9757.57240097 <- expected amount RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u" + +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 495.97007681 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX\",\"symbol\":\"KMD\"}" # 495.97007681 +sleep 3 +echo "495.97007681 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX" + +# RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH KMD 138721.51640953, REVS 2656.00000000 +# RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH KMD 138721.51640953 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH\",\"symbol\":\"KMD\"}" # 138721.51640953 +sleep 3 +echo "138721.51640953 <- expected amount RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc KMD 1174.11345835 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc\",\"symbol\":\"KMD\"}" # 1174.11345835 +sleep 3 +echo "1174.11345835 <- expected amount RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc" + +# RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA" + +# RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL KMD 47.52053869, REVS 0.94300273 +# RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL KMD 47.52053869 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL\",\"symbol\":\"KMD\"}" # 47.52053869 +sleep 3 +echo "47.52053869 <- expected amount RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL" + +# RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx KMD 845.90749755 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx\",\"symbol\":\"KMD\"}" # 845.90749755 +sleep 3 +echo "845.90749755 <- expected amount RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx" + +# RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x KMD 1660.54445484 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x\",\"symbol\":\"KMD\"}" # 1660.54445484 +sleep 3 +echo "1660.54445484 <- expected amount RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x" + +# RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN KMD 55313.07943406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN\",\"symbol\":\"KMD\"}" # 55313.07943406 +sleep 3 +echo "55313.07943406 <- expected amount RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN" + +# RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc KMD 30986.08798000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc\",\"symbol\":\"KMD\"}" # 30986.08798000 +sleep 3 +echo "30986.08798000 <- expected amount RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc" + +# RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj KMD 34809.11928944 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj\",\"symbol\":\"KMD\"}" # 34809.11928944 +sleep 3 +echo "34809.11928944 <- expected amount RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj" + +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 4331.80770687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni\",\"symbol\":\"KMD\"}" # 4331.80770687 +sleep 3 +echo "4331.80770687 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni" + +# RKXi56k97RZcs6CW2chTL286HSjgrEtAsN KMD 880.19856168 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKXi56k97RZcs6CW2chTL286HSjgrEtAsN\",\"symbol\":\"KMD\"}" # 880.19856168 +sleep 3 +echo "880.19856168 <- expected amount RKXi56k97RZcs6CW2chTL286HSjgrEtAsN" + +# RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx KMD 967.34693412 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx\",\"symbol\":\"KMD\"}" # 967.34693412 +sleep 3 +echo "967.34693412 <- expected amount RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx" + +# RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr KMD 1192.08225695 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr\",\"symbol\":\"KMD\"}" # 1192.08225695 +sleep 3 +echo "1192.08225695 <- expected amount RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr" + +# RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb KMD 405.34611747 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb\",\"symbol\":\"KMD\"}" # 405.34611747 +sleep 3 +echo "405.34611747 <- expected amount RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb" + +# RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4 KMD 6712.04424766 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4\",\"symbol\":\"KMD\"}" # 6712.04424766 +sleep 3 +echo "6712.04424766 <- expected amount RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4" + +# RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA KMD 6087.83670543 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA\",\"symbol\":\"KMD\"}" # 6087.83670543 +sleep 3 +echo "6087.83670543 <- expected amount RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA" + +# RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC KMD 11792.89870264 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC\",\"symbol\":\"KMD\"}" # 11792.89870264 +sleep 3 +echo "11792.89870264 <- expected amount RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC" + +# RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on KMD 22265.01478541 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on\",\"symbol\":\"KMD\"}" # 22265.01478541 +sleep 3 +echo "22265.01478541 <- expected amount RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on" + +# RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH\",\"symbol\":\"KMD\"}" # 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH" + +# RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2 KMD 92958.26394000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2\",\"symbol\":\"KMD\"}" # 92958.26394000 +sleep 3 +echo "92958.26394000 <- expected amount RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2" + +# RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA KMD 25176.19648375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA\",\"symbol\":\"KMD\"}" # 25176.19648375 +sleep 3 +echo "25176.19648375 <- expected amount RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA" + +# RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2 KMD 3457.58494193 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2\",\"symbol\":\"KMD\"}" # 3457.58494193 +sleep 3 +echo "3457.58494193 <- expected amount RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2" + +# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 30.59737295 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz\",\"symbol\":\"KMD\"}" # 30.59737295 +sleep 3 +echo "30.59737295 <- expected amount RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 1506.60352500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut\",\"symbol\":\"KMD\"}" # 1506.60352500 +sleep 3 +echo "1506.60352500 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy" + +# RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP KMD 3725.18622956 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP\",\"symbol\":\"KMD\"}" # 3725.18622956 +sleep 3 +echo "3725.18622956 <- expected amount RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP" + +# RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7 KMD 1486.32571743 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7\",\"symbol\":\"KMD\"}" # 1486.32571743 +sleep 3 +echo "1486.32571743 <- expected amount RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7" + +# RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX KMD 7435.09663624, REVS 70.73874773 +# RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX KMD 7435.09663624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX\",\"symbol\":\"KMD\"}" # 7435.09663624 +sleep 3 +echo "7435.09663624 <- expected amount RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX" + +# RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc KMD 9034.38127666 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc\",\"symbol\":\"KMD\"}" # 9034.38127666 +sleep 3 +echo "9034.38127666 <- expected amount RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 258541.07773074 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX\",\"symbol\":\"KMD\"}" # 258541.07773074 +sleep 3 +echo "258541.07773074 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 7315.56699076 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk\",\"symbol\":\"KMD\"}" # 7315.56699076 +sleep 3 +echo "7315.56699076 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk" + +# RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr KMD 6679.18894509 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr\",\"symbol\":\"KMD\"}" # 6679.18894509 +sleep 3 +echo "6679.18894509 <- expected amount RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr" + +# RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm KMD 157.99530650 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm\",\"symbol\":\"KMD\"}" # 157.99530650 +sleep 3 +echo "157.99530650 <- expected amount RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm" + +# RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu KMD 661.93286780 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu\",\"symbol\":\"KMD\"}" # 661.93286780 +sleep 3 +echo "661.93286780 <- expected amount RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu" + +# RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa KMD 5022.01175000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa\",\"symbol\":\"KMD\"}" # 5022.01175000 +sleep 3 +echo "5022.01175000 <- expected amount RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa" + +# RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 KMD 5206.02159816 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47\",\"symbol\":\"KMD\"}" # 5206.02159816 +sleep 3 +echo "5206.02159816 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47" + +# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 10312.37298338 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1\",\"symbol\":\"KMD\"}" # 10312.37298338 +sleep 3 +echo "10312.37298338 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1" + diff --git a/iguana/tests/KMD.batch7.txids b/iguana/tests/KMD.batch7.txids new file mode 100644 index 000000000..06a5f4ca4 --- /dev/null +++ b/iguana/tests/KMD.batch7.txids @@ -0,0 +1,92 @@ +8cd3a16bcea015bfc92f2d326e6b988bb54d247aecb3d1f2900143e8d995cfa6 +9682.18417850 <- expected amount RRcW51evLjdXhEne82mejRwTf8RAMvPxbf +9b5c2726c7839c61459eaa9710569a8e2ab0714eafe9c9fd29820365220ef33c +19824.65353390 <- expected amount RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi +f9020d31431382ac11164ec811b9cb2d57d99bcfa08a39d11a942b798d4dc4d7 +5932.50248029 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda +41798069952a568fd9f365c1c1fc763c2b01e036de731ab72183549dbdc3f2a4 +3202.01278205 <- expected amount RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2 +b4a4a8e4a5c8d22cdc788a0365d61c5f0e76c120a57218a63b15d4b595b5cbab +2.29796059 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 +a27f10d1ccb049c6750f3e8721e7174160dddabe152ab8f068e6a9502be8d281 +11827.69657925 <- expected amount RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ +12d6b517710a5cd43c8fe96673a5a196e8a0bb1af363b8b8057a07cb6f775796 +9757.57240097 <- expected amount RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u +6cfeb1fefded1a795f8a749ca01a700951e3bc49f6a044cbb6ca3c322d231c1b +495.97007681 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX +cc31790b130925334b77409f5d517fed1fce5a2d17fec61318a151e7b8d9366e +138721.51640953 <- expected amount RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH +1d86cb9d2359131164da3c8ff6198c4c7958da2fb406ccd346ddaa8afb09fbe6 +693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv +1f77bfa557a3bc9b6493327fb6ce05c8e15aa088864a01e39cded9cc5159cafb +1174.11345835 <- expected amount RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc +114c24ba300ea0b3c65a6c9964ab6d3f827b819a4ee1969d26af2b7208acac7b +9683.15249375 <- expected amount RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA +70aabe32dc0619b4aa44fd6a6a3265185a68aa72160a861e992daa9d55dd645e +47.52053869 <- expected amount RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL +a3fb5c58e47085a89777ef9d798a802b78541644eed56ef503b7bdad86e15551 +845.90749755 <- expected amount RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx +05919d2d60ea93443f212e3ca50eeb93cbbdb29c0a42d5ef1ddacfe355dfbb6b +1660.54445484 <- expected amount RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x +009c59457de9585d9358c255ee467fe55157a071ff77c391865609fda8feba01 +55313.07943406 <- expected amount RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN +263170b1598bf0e3b427892696ce270abf095f04b88619c56e7c1a2a9057365a +30986.08798000 <- expected amount RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc +cb98a81a04b900342b9d1f5d656d664967c0b7cbc3048dd900e112504d0ff0f8 +34809.11928944 <- expected amount RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj +8a5734622e1bcc9ef05db4fe24f4a63fff7ac30365dd6187b5ec8dc2278ab022 +4331.80770687 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni +b20de3d53333117c80dc06500f057d236046a8a77013f9c05c71f098347aead0 +880.19856168 <- expected amount RKXi56k97RZcs6CW2chTL286HSjgrEtAsN +948c6dc337fe38a331194f3096b1e313889072946fdc166a152acf8bb3faa879 +967.34693412 <- expected amount RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx +56f5ff948e5fe94fc43ff48b5f4631a4bf633f3b6ea139a8ebe573df2a776472 +1192.08225695 <- expected amount RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr +ec23e9454fd3fcd67382c440a8f3aba51b8531ac9c55d7489d3e772f66ab8c6d +405.34611747 <- expected amount RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb +447bd75fe3d7af09d0405293cfda35a81f1e599ea2405c0ccc0c154fddb03eb7 +6712.04424766 <- expected amount RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4 +8d6ca5f467b75964b12ff6ad645c082cea67f7c5e10c24a781078158688b4da5 +6087.83670543 <- expected amount RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA +dba293859a6b57a0777e8d88dbe981172afdc25f8049104db26c7208703726b3 +11792.89870264 <- expected amount RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC +0dd51507754ba5d2fa6933531fc8e0365e6b59b6fc68d85cd100b72e2ba86ed6 +22265.01478541 <- expected amount RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on +b38302f4073bf1c23593cb589c6ceee8d4a98c95830a337871ece310f904a040 +9295.82639400 <- expected amount RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH +ae92ad1dec1b9b2c92f62ae25d2c3648d79fdf4ff26304d1a39eca73ae0bf2a0 +92958.26394000 <- expected amount RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2 +c089a123b036c77f08c650f83915b631bb226bff9658fb3069c8fb7d3ee3dae0 +25176.19648375 <- expected amount RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA +c0c58d9473c58742315917d7edd8b35ace97551b69bc68c598e9e1b0c718f3fd +3457.58494193 <- expected amount RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2 +dfa78b9def6be002a408233f913e095697d10300115852b044593defb5039a69 +30.59737295 <- expected amount RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz +8c7f041d2202fbb105e989d4f6d49527b43d553378dfd6582c93a0c7c2c155ac +1506.60352500 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut +17cff8f901a6842dcf9a9cb85aedacd67361e89505e646ab091a745971f597eb +9683.15249375 <- expected amount RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy +d9d58fb3870f19e5e87dbb612efcc89d1e59e607bbec12880d59c0289187b092 +3725.18622956 <- expected amount RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP +2a099622708035af7e7f42f3f36757fed78fcbe00dce584bc48e7545d5285b02 +1486.32571743 <- expected amount RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7 +08c844c5db3d2f92b6128dff6ff6acc177f0f054f3dfa2ec0b8e7657bff31154 +7435.09663624 <- expected amount RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX +b8cf96205934774f23a7c5f98cb9dd48885f87667a4bdd252746c5f8e762dd8d +9034.38127666 <- expected amount RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc +7f625ead60915598ddef7ef42625bb06eda260fc584e853e5a59a94f7c74d91f +258541.07773074 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX +12590bda633745461d3200ee27b5c248e572b16e09c8385442ea74db5a51b5b4 +7315.56699076 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk +5eff92ec09f56b257b3fe9529269a608948ee7380cf710805d309535a644b777 +6679.18894509 <- expected amount RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr +773443eb515a277ba7818c875799608d6e336c9a193208fb50e17b5299346ed7 +157.99530650 <- expected amount RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm +1f037b7ce3fb940fc0a3f88b669d4f43954a9e5cae189662ad6acede2d8ca06d +661.93286780 <- expected amount RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu +b2d4583fddbbf17653f21602946034fc2d3a0ee386b0a1bfca31e9aa5535b77b +5022.01175000 <- expected amount RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa +2b9f7fc1b56b2742880ba89354d4f7f6a04e4538645afdb7935b91fe29dfb0cd +5206.02159816 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 +546a20e9ce42251984bbd6bc7a6c0ad2307b1a874a6ffdd4c30d089bc49e1ff1 +10312.37298338 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 diff --git a/iguana/tests/KMD.batch7.unspents b/iguana/tests/KMD.batch7.unspents new file mode 100644 index 000000000..441cad7fe --- /dev/null +++ b/iguana/tests/KMD.batch7.unspents @@ -0,0 +1,93 @@ +[{"txid":"8cd3a16bcea015bfc92f2d326e6b988bb54d247aecb3d1f2900143e8d995cfa6","vout":1,"address":"RRcW51evLjdXhEne82mejRwTf8RAMvPxbf","account":"RRcW51evLjdXhEne82mejRwTf8RAMvPxbf","scriptPubKey":"76a914b328ef280499b55a8a445c98416c0cd6c36ac76288ac","amount":9682.18417850,"interest":0,"confirmations":3,"spendable":false}] +9682.18417850 <- expected amount RRcW51evLjdXhEne82mejRwTf8RAMvPxbf +[{"txid":"9b5c2726c7839c61459eaa9710569a8e2ab0714eafe9c9fd29820365220ef33c","vout":1,"address":"RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi","account":"RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi","scriptPubKey":"76a914b625fba2e5361e082b25f1b77a25253dbf027a9f88ac","amount":19824.65353390,"interest":0,"confirmations":3,"spendable":false}] +19824.65353390 <- expected amount RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi +[{"txid":"3c3b26a4b995b2b0b6c0c52c037ad96a4151078895ef350e97096ec60e60b2ca","vout":1,"address":"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda","account":"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda","scriptPubKey":"76a914b64af5d62e56292a1c61b66e51adf3d73ce76d6a88ac","amount":24981.55183756,"interest":3.57901888,"confirmations":1475,"spendable":false}, {"txid":"f9020d31431382ac11164ec811b9cb2d57d99bcfa08a39d11a942b798d4dc4d7","vout":1,"address":"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda","account":"RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda","scriptPubKey":"76a914b64af5d62e56292a1c61b66e51adf3d73ce76d6a88ac","amount":5932.50248029,"interest":0,"confirmations":3,"spendable":false}] +5932.50248029 <- expected amount RRu4rm9zCpK41rSMn4NPtgrmcmHXBStQda +[{"txid":"41798069952a568fd9f365c1c1fc763c2b01e036de731ab72183549dbdc3f2a4","vout":1,"address":"RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2","account":"RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2","scriptPubKey":"76a914af96c12c96fe4f35560ec7c697164142e2b7335d88ac","amount":3202.01278205,"interest":0,"confirmations":3,"spendable":false}] +3202.01278205 <- expected amount RRHcvhUfvmTFvyju9HxYUMG7ak2rAsZUG2 +[{"txid":"47fa43dfd26ca274bceef24dce7532c6dc62f5da5bef80bb3b0f529a16785668","vout":1,"address":"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3","account":"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3","scriptPubKey":"76a91433dab4ba613013fc625b8a8f13dfa24ac871a57788ac","amount":8376.76881681,"interest":7.22135242,"confirmations":8398,"spendable":false}, {"txid":"6adda35ccf807130e1e184ec3be431cbca497891cfdaf2413b8f0758cb77a882","vout":1,"address":"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3","account":"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3","scriptPubKey":"76a91433dab4ba613013fc625b8a8f13dfa24ac871a57788ac","amount":57862.44847739,"interest":78.19249794,"confirmations":13568,"spendable":false}, {"txid":"4d36d166d161174f096725951acdf2ff7263a14ee998ecc9dfffbbb72c199d8d","vout":1,"address":"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3","account":"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3","scriptPubKey":"76a91433dab4ba613013fc625b8a8f13dfa24ac871a57788ac","amount":3.13113297,"interest":0,"confirmations":5635,"spendable":false}, {"txid":"b4a4a8e4a5c8d22cdc788a0365d61c5f0e76c120a57218a63b15d4b595b5cbab","vout":1,"address":"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3","account":"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3","scriptPubKey":"76a91433dab4ba613013fc625b8a8f13dfa24ac871a57788ac","amount":2.29796059,"interest":0,"confirmations":3,"spendable":false}] +2.29796059 <- expected amount RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 +[{"txid":"a27f10d1ccb049c6750f3e8721e7174160dddabe152ab8f068e6a9502be8d281","vout":1,"address":"RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ","account":"RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ","scriptPubKey":"76a914ea4036a775293e12177fc8da78018cd96efceee588ac","amount":11827.69657925,"interest":0,"confirmations":3,"spendable":false}, {"txid":"e0b44fb9e74984823a307c82b70ddb7a173976fa43aec61440d9cd53654a8e93","vout":1,"address":"RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ","account":"RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ","scriptPubKey":"76a914ea4036a775293e12177fc8da78018cd96efceee588ac","amount":7885.04483652,"interest":7.58177388,"confirmations":9516,"spendable":false}] +11827.69657925 <- expected amount RWdo833bYVhMUHRdr8hMs7HHVcG2UNPwcZ +[{"txid":"12d6b517710a5cd43c8fe96673a5a196e8a0bb1af363b8b8057a07cb6f775796","vout":1,"address":"RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u","account":"RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u","scriptPubKey":"76a91461550febef639e641b15d7fdceee97e50e138ca988ac","amount":9757.57240097,"interest":0,"confirmations":3,"spendable":false}] +9757.57240097 <- expected amount RJ9qXMATAvg1B5B5KGtiNS8cVv37JNpw8u +[{"txid":"ba761c5bcab251499de8af6ebca8dd6f71e4697b69ad38a63ac6ed3f51e20705","vout":1,"address":"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX","account":"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX","scriptPubKey":"76a9140bdcf88401de1c3c3a1cac2e7c4d0205a2e48f6388ac","amount":40914.30625015,"interest":33.53631659,"confirmations":7981,"spendable":false}, {"txid":"3f56a88153c48bb6b1b5aa531a7dd5e90cdedd7be8bb1c0e0b036039cba21914","vout":0,"address":"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX","account":"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX","scriptPubKey":"76a9140bdcf88401de1c3c3a1cac2e7c4d0205a2e48f6388ac","amount":1,"interest":0,"confirmations":8579,"spendable":false}, {"txid":"6cfeb1fefded1a795f8a749ca01a700951e3bc49f6a044cbb6ca3c322d231c1b","vout":1,"address":"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX","account":"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX","scriptPubKey":"76a9140bdcf88401de1c3c3a1cac2e7c4d0205a2e48f6388ac","amount":495.97007681,"interest":0,"confirmations":3,"spendable":false}, {"txid":"8a621bdfa7fa034342e8f07ad4f9ccccce2c6ccf3d3b238988f53d96c7e051ae","vout":1,"address":"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX","account":"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX","scriptPubKey":"76a9140bdcf88401de1c3c3a1cac2e7c4d0205a2e48f6388ac","amount":29.00370000,"interest":0.02544184,"confirmations":8588,"spendable":false}] +495.97007681 <- expected amount RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX +[{"txid":"cc31790b130925334b77409f5d517fed1fce5a2d17fec61318a151e7b8d9366e","vout":1,"address":"RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH","account":"RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH","scriptPubKey":"76a914484d12d59bdd40cb1b3ef425c6da45533bd5913788ac","amount":138721.51640953,"interest":0,"confirmations":3,"spendable":false}] +138721.51640953 <- expected amount RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH +[{"txid":"1d86cb9d2359131164da3c8ff6198c4c7958da2fb406ccd346ddaa8afb09fbe6","vout":1,"address":"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv","account":"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv","scriptPubKey":"76a91457eb94f18b82ac15ac3256119bfe398afec0c54588ac","amount":693.08132289,"interest":0,"confirmations":3,"spendable":false}] +693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv +[{"txid":"1f77bfa557a3bc9b6493327fb6ce05c8e15aa088864a01e39cded9cc5159cafb","vout":1,"address":"RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc","account":"RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc","scriptPubKey":"76a914d96189cff80b306d2efbabe71642d2f626d2bc3a88ac","amount":1174.11345835,"interest":0,"confirmations":4,"spendable":false}] +1174.11345835 <- expected amount RV6bZE1shV9HufX9hztv7NdwwZXtPNGnmc +[{"txid":"114c24ba300ea0b3c65a6c9964ab6d3f827b819a4ee1969d26af2b7208acac7b","vout":1,"address":"RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA","account":"RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA","scriptPubKey":"76a914fa2b1c806de870f18ad1bbaba6e9bdf65ceefae388ac","amount":9683.15249375,"interest":0,"confirmations":4,"spendable":false}] +9683.15249375 <- expected amount RY5xeuFcrPgBQTtmsrNyo8Ha85z8CsQsQA +[{"txid":"70aabe32dc0619b4aa44fd6a6a3265185a68aa72160a861e992daa9d55dd645e","vout":1,"address":"RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL","account":"RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL","scriptPubKey":"76a9143ec1a5c983beb264cbd7e3bf2c0790e7695030be88ac","amount":47.52053869,"interest":0,"confirmations":4,"spendable":false}] +47.52053869 <- expected amount RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL +[{"txid":"a3fb5c58e47085a89777ef9d798a802b78541644eed56ef503b7bdad86e15551","vout":1,"address":"RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx","account":"RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx","scriptPubKey":"76a914e5e83ff1e272721ac97d729720b3ed305b61013e88ac","amount":845.90749755,"interest":0,"confirmations":4,"spendable":false}] +845.90749755 <- expected amount RWEq3Sf4H93Agwxf1ARD1MaPNCfBj54Zfx +[{"txid":"05919d2d60ea93443f212e3ca50eeb93cbbdb29c0a42d5ef1ddacfe355dfbb6b","vout":1,"address":"RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x","account":"RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x","scriptPubKey":"76a914489f66ed63cb87f2221fc3e0cb2613aeb2522d0288ac","amount":1660.54445484,"interest":0,"confirmations":4,"spendable":false}] +1660.54445484 <- expected amount RFuBgn2XPbePzKwWeiXYGdsACJutKkcH3x +[{"txid":"009c59457de9585d9358c255ee467fe55157a071ff77c391865609fda8feba01","vout":1,"address":"RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN","account":"RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN","scriptPubKey":"76a91410a22d215bed9d9140eeac9ca4f3c93636ba745588ac","amount":55313.07943406,"interest":0,"confirmations":5,"spendable":false}] +55313.07943406 <- expected amount RAo9Anrzy7Whzaxmp3tF5ZFTe77DPJUerN +[{"txid":"263170b1598bf0e3b427892696ce270abf095f04b88619c56e7c1a2a9057365a","vout":1,"address":"RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc","account":"RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc","scriptPubKey":"76a914990ee469e018495affc758dec9739c33a30499f488ac","amount":30986.08798000,"interest":0,"confirmations":5,"spendable":false}] +30986.08798000 <- expected amount RPEVJbazc37eXGGJhdZoN7Bo2B71kS1cBc +[{"txid":"cb98a81a04b900342b9d1f5d656d664967c0b7cbc3048dd900e112504d0ff0f8","vout":1,"address":"RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj","account":"RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj","scriptPubKey":"76a91421fe7eaa5272c6caa9ba8bab05feb555380b7cb988ac","amount":34809.11928944,"interest":0,"confirmations":5,"spendable":false}] +34809.11928944 <- expected amount RCNwFTJFxjxEVqsbr81Ug41E3K8fCjktwj +[{"txid":"8a5734622e1bcc9ef05db4fe24f4a63fff7ac30365dd6187b5ec8dc2278ab022","vout":1,"address":"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni","account":"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni","scriptPubKey":"76a91474a4c0fc2c8592ec97b96bba19ce07dfdb105def88ac","amount":4331.80770687,"interest":0,"confirmations":5,"spendable":false}, {"txid":"7ab5fe203ae7b23957ca398484a9eb6279c0f9bc68c0d3dd0bc2c0aab8cc9d77","vout":1,"address":"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni","account":"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni","scriptPubKey":"76a91474a4c0fc2c8592ec97b96bba19ce07dfdb105def88ac","amount":195982.90265756,"interest":113.94354805,"confirmations":5638,"spendable":false}] +4331.80770687 <- expected amount RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni +[{"txid":"b20de3d53333117c80dc06500f057d236046a8a77013f9c05c71f098347aead0","vout":1,"address":"RKXi56k97RZcs6CW2chTL286HSjgrEtAsN","account":"RKXi56k97RZcs6CW2chTL286HSjgrEtAsN","scriptPubKey":"76a91470701e389d34b5ee295dc624bcbf9a8aa7ae2f7488ac","amount":880.19856168,"interest":0,"confirmations":5,"spendable":false}] +880.19856168 <- expected amount RKXi56k97RZcs6CW2chTL286HSjgrEtAsN +[{"txid":"948c6dc337fe38a331194f3096b1e313889072946fdc166a152acf8bb3faa879","vout":1,"address":"RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx","account":"RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx","scriptPubKey":"76a9146ebe46e7db7ffb5f6276977c25dbbe4e419ac43688ac","amount":967.34693412,"interest":0,"confirmations":5,"spendable":false}] +967.34693412 <- expected amount RKNkMHyMWcK84T6JJ4MRYgSUuKZqPPfGYx +[{"txid":"56f5ff948e5fe94fc43ff48b5f4631a4bf633f3b6ea139a8ebe573df2a776472","vout":1,"address":"RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr","account":"RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr","scriptPubKey":"76a9141b685cb50d45b194ac719872f54c95651b5fa76288ac","amount":1192.08225695,"interest":0,"confirmations":5,"spendable":false}] +1192.08225695 <- expected amount RBn7LuP4xLM3Yq881BSNQ1gXCjDU8at4fr +[{"txid":"ec23e9454fd3fcd67382c440a8f3aba51b8531ac9c55d7489d3e772f66ab8c6d","vout":1,"address":"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb","account":"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb","scriptPubKey":"76a914e3a96d98131e45c6f3e950f75253d98419aeb8d888ac","amount":405.34611747,"interest":0,"confirmations":5,"spendable":false}, {"txid":"85d92801778b3110b4796758e85b461fa8d90f07020f79922d00d8ab623b8bce","vout":1,"address":"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb","account":"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb","scriptPubKey":"76a914e3a96d98131e45c6f3e950f75253d98419aeb8d888ac","amount":164046.90243912,"interest":106.52396262,"confirmations":6191,"spendable":false}, {"txid":"ee055abb21c95a20689d26fa218dcb34b0e673f12b220ebb3af5458105f82bfa","vout":1,"address":"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb","account":"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb","scriptPubKey":"76a914e3a96d98131e45c6f3e950f75253d98419aeb8d888ac","amount":2738.88754015,"interest":0.45196164,"confirmations":1728,"spendable":false}] +405.34611747 <- expected amount RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb +[{"txid":"b439fb56567136e846efbcd421806d1c6a140dd8007c66e6173cfc33a8651008","vout":1,"address":"RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4","account":"RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4","scriptPubKey":"76a914d689219c2fa34b4b808ab6c8c0e7564c787b579e88ac","amount":1.00443477,"interest":0,"confirmations":5999,"spendable":false}, {"txid":"447bd75fe3d7af09d0405293cfda35a81f1e599ea2405c0ccc0c154fddb03eb7","vout":1,"address":"RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4","account":"RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4","scriptPubKey":"76a914d689219c2fa34b4b808ab6c8c0e7564c787b579e88ac","amount":6712.04424766,"interest":0,"confirmations":5,"spendable":false}] +6712.04424766 <- expected amount RUqYxcjB5Hy6eqK1YDimjfXfhfp5TSyCF4 +[{"txid":"8d6ca5f467b75964b12ff6ad645c082cea67f7c5e10c24a781078158688b4da5","vout":1,"address":"RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA","account":"RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA","scriptPubKey":"76a914959830a2a4b30fad6b186dc78dbd3021ff994ea688ac","amount":6087.83670543,"interest":0,"confirmations":5,"spendable":false}] +6087.83670543 <- expected amount RNvB5SiEEmGQrwFfyYXuDfeSWPDj35ypqA +[{"txid":"dba293859a6b57a0777e8d88dbe981172afdc25f8049104db26c7208703726b3","vout":1,"address":"RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC","account":"RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC","scriptPubKey":"76a914c11c4d296001b9b7ec6dab87c740f22731f4b56288ac","amount":11792.89870264,"interest":0,"confirmations":5,"spendable":false}] +11792.89870264 <- expected amount RStGPxQ5amuNV4f7g8A1FhDj74qGeAXRgC +[{"txid":"0dd51507754ba5d2fa6933531fc8e0365e6b59b6fc68d85cd100b72e2ba86ed6","vout":1,"address":"RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on","account":"RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on","scriptPubKey":"76a914f631a6bf7e5adc02900220c10543c95d4b9c19f588ac","amount":22265.01478541,"interest":0,"confirmations":5,"spendable":false}] +22265.01478541 <- expected amount RXiwnYTrCgxrxa5vrCuG8sUqKstu3Yn5on +[{"txid":"b38302f4073bf1c23593cb589c6ceee8d4a98c95830a337871ece310f904a040","vout":1,"address":"RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH","account":"RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH","scriptPubKey":"76a9142d1be2ae97242fffbc5d7eb68deca17e6a731c4588ac","amount":9295.82639400,"interest":0,"confirmations":5,"spendable":false}] +9295.82639400 <- expected amount RDPhtfYMEAor4kaDfZYuDnt1LC66Qf6jMH +[{"txid":"ae92ad1dec1b9b2c92f62ae25d2c3648d79fdf4ff26304d1a39eca73ae0bf2a0","vout":1,"address":"RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2","account":"RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2","scriptPubKey":"76a914b29ca402ca2228ad8157c1df5637ed408fa4558888ac","amount":92958.26394000,"interest":0,"confirmations":5,"spendable":false}] +92958.26394000 <- expected amount RRZc1FEgEFenoLDWG7XJRiks6Xf3ZRoQc2 +[{"txid":"c089a123b036c77f08c650f83915b631bb226bff9658fb3069c8fb7d3ee3dae0","vout":1,"address":"RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA","account":"RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA","scriptPubKey":"76a914900d80c21a4f800a07b9b59c87c1693c671ff41688ac","amount":25176.19648375,"interest":0,"confirmations":5,"spendable":false}] +25176.19648375 <- expected amount RNQsZLnKUb7eNdrpkynw3rA7bFPQPXPBFA +[{"txid":"8649013884e48ce182a7514613014af5d723284902530c994ba2e084a3f0f71d","vout":1,"address":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","account":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","scriptPubKey":"76a914a77fa9f98cf8cc7152b645a54379ef8108d78a2488ac","amount":132,"interest":0.07951807,"confirmations":5881,"spendable":false}, {"txid":"77cd5371b1eceb01734458712bf80975d2e4455c970d5f4dc7fa90ba1578ab1f","vout":1,"address":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","account":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","scriptPubKey":"76a914a77fa9f98cf8cc7152b645a54379ef8108d78a2488ac","amount":500,"interest":0.30120481,"confirmations":5895,"spendable":false}, {"txid":"3d57e466010ca6b5aea5cc565da7c832f9db0fe35d437cce663ff42bd287363d","vout":1,"address":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","account":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","scriptPubKey":"76a914a77fa9f98cf8cc7152b645a54379ef8108d78a2488ac","amount":500,"interest":0.30120481,"confirmations":5898,"spendable":false}, {"txid":"7301e7c70c3451d46bb6c5754d74fd2c7ea219f360c616a64b440a4968e26873","vout":1,"address":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","account":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","scriptPubKey":"76a914a77fa9f98cf8cc7152b645a54379ef8108d78a2488ac","amount":0.00495049,"interest":0,"confirmations":1267,"spendable":false}, {"txid":"c0c58d9473c58742315917d7edd8b35ace97551b69bc68c598e9e1b0c718f3fd","vout":1,"address":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","account":"RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2","scriptPubKey":"76a914a77fa9f98cf8cc7152b645a54379ef8108d78a2488ac","amount":3457.58494193,"interest":0,"confirmations":5,"spendable":false}] +3457.58494193 <- expected amount RQYqroKgVSAdzEEnCLwaP2qffH5ApmVPM2 +[{"txid":"dfa78b9def6be002a408233f913e095697d10300115852b044593defb5039a69","vout":1,"address":"RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz","account":"RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz","scriptPubKey":"76a914a128ae07bfea203567eed1d4387e9982cdb220fa88ac","amount":30.59737295,"interest":0,"confirmations":5,"spendable":false}] +30.59737295 <- expected amount RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz +[{"txid":"8c7f041d2202fbb105e989d4f6d49527b43d553378dfd6582c93a0c7c2c155ac","vout":1,"address":"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut","account":"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut","scriptPubKey":"76a914f51a6ebba4d8af7dbddc002fb5c095ac831f00f088ac","amount":1506.60352500,"interest":0,"confirmations":5,"spendable":false}] +1506.60352500 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut +[{"txid":"17cff8f901a6842dcf9a9cb85aedacd67361e89505e646ab091a745971f597eb","vout":1,"address":"RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy","account":"RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy","scriptPubKey":"76a91489954432dfbad203078025b5d476841a7396e3de88ac","amount":9683.15249375,"interest":0,"confirmations":5,"spendable":false}] +9683.15249375 <- expected amount RMpfU1RsWJK712wkiUNS9qyteZuEGGxWFy +[{"txid":"d9d58fb3870f19e5e87dbb612efcc89d1e59e607bbec12880d59c0289187b092","vout":1,"address":"RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP","account":"RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP","scriptPubKey":"76a9142a4661c5085c948bc5d57768843e4ddecb7e622188ac","amount":3725.18622956,"interest":0,"confirmations":5,"spendable":false}] +3725.18622956 <- expected amount RD8imo1AHUvE1EuTL2EXQGoCMEWAfXgFEP +[{"txid":"2a099622708035af7e7f42f3f36757fed78fcbe00dce584bc48e7545d5285b02","vout":1,"address":"RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7","account":"RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7","scriptPubKey":"76a914e12fea0ef669739df165ea395775b0977770041488ac","amount":1486.32571743,"interest":0,"confirmations":5,"spendable":false}] +1486.32571743 <- expected amount RVosWpakrP2Cd5JcQjdhjFn9WnzvTqS9H7 +[{"txid":"08c844c5db3d2f92b6128dff6ff6acc177f0f054f3dfa2ec0b8e7657bff31154","vout":1,"address":"RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX","account":"RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX","scriptPubKey":"76a91473209045453cc0a8551790628ed625e1678ccfba88ac","amount":7435.09663624,"interest":0,"confirmations":5,"spendable":false}] +7435.09663624 <- expected amount RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX +[{"txid":"b8cf96205934774f23a7c5f98cb9dd48885f87667a4bdd252746c5f8e762dd8d","vout":1,"address":"RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc","account":"RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc","scriptPubKey":"76a9148a48a03dcddfe7c2d599cd47d7b0baccfbe9a5fc88ac","amount":9034.38127666,"interest":0,"confirmations":5,"spendable":false}] +9034.38127666 <- expected amount RMtNL8MfRZd4eQ99JF6fgRASVb8S2p7RWc +[{"txid":"7f625ead60915598ddef7ef42625bb06eda260fc584e853e5a59a94f7c74d91f","vout":1,"address":"RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX","account":"RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX","scriptPubKey":"76a91478d0c764edacbe3d496010b4b3b27494e66fc9e488ac","amount":258541.07773074,"interest":0,"confirmations":5,"spendable":false}] +258541.07773074 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX +[{"txid":"3eeb779849cdf59a51418dc40f593c01eb3327c4858de600919ce81b450b2b2c","vout":1,"address":"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk","account":"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk","scriptPubKey":"76a9143c35763cff259866a738482944074b9e12bf06bd88ac","amount":500.11560727,"interest":0.25258364,"confirmations":5033,"spendable":false}, {"txid":"12590bda633745461d3200ee27b5c248e572b16e09c8385442ea74db5a51b5b4","vout":1,"address":"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk","account":"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk","scriptPubKey":"76a9143c35763cff259866a738482944074b9e12bf06bd88ac","amount":7315.56699076,"interest":0,"confirmations":5,"spendable":false}] +7315.56699076 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk +[{"txid":"e1b6866c3b9d952c3a0ae3f18f4bae254fe9069b4ebde6fa43b8f99dedd5a659","vout":1,"address":"RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr","account":"RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr","scriptPubKey":"76a9140c2051abd568208f0492a2c8dee49a8bf3cbfd5c88ac","amount":51783.14581891,"interest":7.57063535,"confirmations":1515,"spendable":false}, {"txid":"5eff92ec09f56b257b3fe9529269a608948ee7380cf710805d309535a644b777","vout":1,"address":"RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr","account":"RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr","scriptPubKey":"76a9140c2051abd568208f0492a2c8dee49a8bf3cbfd5c88ac","amount":6679.18894509,"interest":0,"confirmations":5,"spendable":false}] +6679.18894509 <- expected amount RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr +[{"txid":"773443eb515a277ba7818c875799608d6e336c9a193208fb50e17b5299346ed7","vout":1,"address":"RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm","account":"RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm","scriptPubKey":"76a914e6c932eae192615292cdfe6ea6224117c980eb1a88ac","amount":157.99530650,"interest":0,"confirmations":5,"spendable":false}] +157.99530650 <- expected amount RWKUXBUhn1NhD1w6DvRyxVokD1urauKQXm +[{"txid":"1f037b7ce3fb940fc0a3f88b669d4f43954a9e5cae189662ad6acede2d8ca06d","vout":1,"address":"RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu","account":"RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu","scriptPubKey":"76a914e26f29c6a10973c4b41fd57c1ed058d3540740fc88ac","amount":661.93286780,"interest":0,"confirmations":5,"spendable":false}] +661.93286780 <- expected amount RVvTxd7K5A6B5GugraTMd2peLzRgKZFMbu +[{"txid":"b2d4583fddbbf17653f21602946034fc2d3a0ee386b0a1bfca31e9aa5535b77b","vout":1,"address":"RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa","account":"RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa","scriptPubKey":"76a9144c4ab74ba08f842ea2c3604e11a989866c6bd10288ac","amount":5022.01175000,"interest":0,"confirmations":5,"spendable":false}] +5022.01175000 <- expected amount RGEawTGXLwwV4QdHGrmmTDxZrXgyUxQHRa +[{"txid":"da043ca20ef95cf12325d8ac2cb3e33cef92db49cec3551f07be4e6308648f13","vout":1,"address":"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47","account":"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47","scriptPubKey":"76a9145f4bd040debae8c8bdddcad618a3de79462bcd5888ac","amount":0.02657850,"interest":0,"confirmations":3159,"spendable":false}, {"txid":"2b9f7fc1b56b2742880ba89354d4f7f6a04e4538645afdb7935b91fe29dfb0cd","vout":1,"address":"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47","account":"RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47","scriptPubKey":"76a9145f4bd040debae8c8bdddcad618a3de79462bcd5888ac","amount":5206.02159816,"interest":0,"confirmations":5,"spendable":false}] +5206.02159816 <- expected amount RHy56MTg74v8AY1Eo2RgbohbMbdHjUDN47 +[{"txid":"6fc1d56f5275ce745877e6ac038f61615983d16d13403c9ceb89b3c9989d963a","vout":0,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":10533.25049043,"interest":1.09039860,"confirmations":1034,"spendable":false}, {"txid":"6fc1d56f5275ce745877e6ac038f61615983d16d13403c9ceb89b3c9989d963a","vout":1,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":886.89557581,"interest":0.09181113,"confirmations":1034,"spendable":false}, {"txid":"13e9b271e893f9224696d74a904696a8c25cc76f645cb27dede8a2f62cf87f6c","vout":0,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":999.99990000,"interest":0.24390241,"confirmations":2462,"spendable":false}, {"txid":"c8cba16908893545179be5ee114e77121c0779efafab61cf6c018bcd01a7259c","vout":1,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":28096.43798050,"interest":19.51141526,"confirmations":6671,"spendable":false}, {"txid":"546a20e9ce42251984bbd6bc7a6c0ad2307b1a874a6ffdd4c30d089bc49e1ff1","vout":1,"address":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","account":"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1","scriptPubKey":"76a91422311801b820cf5a169e3614cfc7e61e08cffc1c88ac","amount":10312.37298338,"interest":0,"confirmations":5,"spendable":false}] +10312.37298338 <- expected amount RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 + diff --git a/iguana/tests/KMD.batch8 b/iguana/tests/KMD.batch8 new file mode 100755 index 000000000..53dca1caf --- /dev/null +++ b/iguana/tests/KMD.batch8 @@ -0,0 +1,190 @@ +sleep 999999 +# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 11472.96269487 +./komodo-cli sendtoaddress REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 11472.96269487 +sleep 3 +echo "11472.96269487 <- expected amount REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8" + +# RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV KMD 914.10663775 +./komodo-cli sendtoaddress RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV 914.10663775 +sleep 3 +echo "914.10663775 <- expected amount RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV" + +# R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG KMD 840.13904995 +./komodo-cli sendtoaddress R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG 840.13904995 +sleep 3 +echo "840.13904995 <- expected amount R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG" + +# RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG KMD 23492.49573707, REVS 189.50500057 +# RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG KMD 23492.49573707 +./komodo-cli sendtoaddress RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG 23492.49573707 +sleep 3 +echo "23492.49573707 <- expected amount RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 2584.32223431 +./komodo-cli sendtoaddress RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ 2584.32223431 +sleep 3 +echo "2584.32223431 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX KMD 1278.17612917 +./komodo-cli sendtoaddress RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX 1278.17612917 +sleep 3 +echo "1278.17612917 <- expected amount RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX" + +# RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS KMD 17042.34838900 +./komodo-cli sendtoaddress RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS 17042.34838900 +sleep 3 +echo "17042.34838900 <- expected amount RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS" + +# RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a KMD 1198.78675406, REVS 23.78885452 +# RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a KMD 1198.78675406 +./komodo-cli sendtoaddress RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a 1198.78675406 +sleep 3 +echo "1198.78675406 <- expected amount RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a" + +# RCownUMXktAgPvzwpALnGimCA1RDJoTvx1 KMD 952.88812828 +./komodo-cli sendtoaddress RCownUMXktAgPvzwpALnGimCA1RDJoTvx1 952.88812828 +sleep 3 +echo "952.88812828 <- expected amount RCownUMXktAgPvzwpALnGimCA1RDJoTvx1" + +# RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM KMD 6594.40160977 +./komodo-cli sendtoaddress RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM 6594.40160977 +sleep 3 +echo "6594.40160977 <- expected amount RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM" + +# RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j KMD 9295.82639400 +./komodo-cli sendtoaddress RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j" + +# RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns KMD 30681.77405788, REVS 608.60220842 +# RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns KMD 30681.77405788 +./komodo-cli sendtoaddress RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns 30681.77405788 +sleep 3 +echo "30681.77405788 <- expected amount RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns" + +# RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8 KMD 257.45731805 +./komodo-cli sendtoaddress RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8 257.45731805 +sleep 3 +echo "257.45731805 <- expected amount RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8" + +# RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM KMD 1163.91492974 +./komodo-cli sendtoaddress RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM 1163.91492974 +sleep 3 +echo "1163.91492974 <- expected amount RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM" + +# RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL KMD 188643.68073877, REVS 597.97000000 +# RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL KMD 188643.68073877 +./komodo-cli sendtoaddress RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL 188643.68073877 +sleep 3 +echo "188643.68073877 <- expected amount RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL" + +# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 99.43583265 +./komodo-cli sendtoaddress RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz 99.43583265 +sleep 3 +echo "99.43583265 <- expected amount RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz" + +# RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU KMD 1394.37395910 +./komodo-cli sendtoaddress RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU 1394.37395910 +sleep 3 +echo "1394.37395910 <- expected amount RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU" + +# RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h KMD 24207.88123437 +./komodo-cli sendtoaddress RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h 24207.88123437 +sleep 3 +echo "24207.88123437 <- expected amount RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h" + +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 17160.85255783, REVS 233.03444206 +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 17160.85255783 +./komodo-cli sendtoaddress RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 17160.85255783 +sleep 3 +echo "17160.85255783 <- expected amount RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8" + +# REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe KMD 203188.29997688, REVS 2109.97700000 +# REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe KMD 203188.29997688 +./komodo-cli sendtoaddress REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe 203188.29997688 +sleep 3 +echo "203188.29997688 <- expected amount REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe" + +# RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan KMD 2316.21007650 +./komodo-cli sendtoaddress RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan 2316.21007650 +sleep 3 +echo "2316.21007650 <- expected amount RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan" + +# RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH KMD 968.31524937 +./komodo-cli sendtoaddress RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH" + +# RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV KMD 1663.06468462 +./komodo-cli sendtoaddress RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV 1663.06468462 +sleep 3 +echo "1663.06468462 <- expected amount RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV" + +# RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn KMD 929.58263940 +./komodo-cli sendtoaddress RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn 929.58263940 +sleep 3 +echo "929.58263940 <- expected amount RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 91422.85735610 +./komodo-cli sendtoaddress RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX 91422.85735610 +sleep 3 +echo "91422.85735610 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB KMD 138920.34502737, REVS 835.32960760 +# RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB KMD 138920.34502737 +./komodo-cli sendtoaddress RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB 138920.34502737 +sleep 3 +echo "138920.34502737 <- expected amount RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB" + +# RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99 KMD 9683.15249375 +./komodo-cli sendtoaddress RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99" + +# RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 KMD 1422.54025612 +./komodo-cli sendtoaddress RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 1422.54025612 +sleep 3 +echo "1422.54025612 <- expected amount RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4" + +# RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN KMD 6041.35757346 +./komodo-cli sendtoaddress RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN 6041.35757346 +sleep 3 +echo "6041.35757346 <- expected amount RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN" + +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 3571.37913637 +./komodo-cli sendtoaddress REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk 3571.37913637 +sleep 3 +echo "3571.37913637 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk" + +# RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB KMD 0.29002598 +./komodo-cli sendtoaddress RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB 0.29002598 +sleep 3 +echo "0.29002598 <- expected amount RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 25106.60529680 +./komodo-cli sendtoaddress RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut 25106.60529680 +sleep 3 +echo "25106.60529680 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw KMD 48415.76246875 +./komodo-cli sendtoaddress RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw" + +# RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu KMD 2420.78820090 +./komodo-cli sendtoaddress RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu 2420.78820090 +sleep 3 +echo "2420.78820090 <- expected amount RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu" + +# REsjYn44yH4W9JcGiQND95mfJV98jzip9i KMD 6266.60868209 +./komodo-cli sendtoaddress REsjYn44yH4W9JcGiQND95mfJV98jzip9i 6266.60868209 +sleep 3 +echo "6266.60868209 <- expected amount REsjYn44yH4W9JcGiQND95mfJV98jzip9i" + + +# total KMD 882306.06485397 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch8.importaddress b/iguana/tests/KMD.batch8.importaddress new file mode 100755 index 000000000..67bd383db --- /dev/null +++ b/iguana/tests/KMD.batch8.importaddress @@ -0,0 +1,187 @@ +# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 11472.96269487 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8\",\"symbol\":\"KMD\"}" # 11472.96269487 +sleep 3 +echo "11472.96269487 <- expected amount REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8" + +# RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV KMD 914.10663775 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV\",\"symbol\":\"KMD\"}" # 914.10663775 +sleep 3 +echo "914.10663775 <- expected amount RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV" + +# R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG KMD 840.13904995 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG\",\"symbol\":\"KMD\"}" # 840.13904995 +sleep 3 +echo "840.13904995 <- expected amount R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG" + +# RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG KMD 23492.49573707, REVS 189.50500057 +# RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG KMD 23492.49573707 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG\",\"symbol\":\"KMD\"}" # 23492.49573707 +sleep 3 +echo "23492.49573707 <- expected amount RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 2584.32223431 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ\",\"symbol\":\"KMD\"}" # 2584.32223431 +sleep 3 +echo "2584.32223431 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX KMD 1278.17612917 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX\",\"symbol\":\"KMD\"}" # 1278.17612917 +sleep 3 +echo "1278.17612917 <- expected amount RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX" + +# RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS KMD 17042.34838900 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS\",\"symbol\":\"KMD\"}" # 17042.34838900 +sleep 3 +echo "17042.34838900 <- expected amount RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS" + +# RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a KMD 1198.78675406, REVS 23.78885452 +# RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a KMD 1198.78675406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a\",\"symbol\":\"KMD\"}" # 1198.78675406 +sleep 3 +echo "1198.78675406 <- expected amount RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a" + +# RCownUMXktAgPvzwpALnGimCA1RDJoTvx1 KMD 952.88812828 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCownUMXktAgPvzwpALnGimCA1RDJoTvx1\",\"symbol\":\"KMD\"}" # 952.88812828 +sleep 3 +echo "952.88812828 <- expected amount RCownUMXktAgPvzwpALnGimCA1RDJoTvx1" + +# RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM KMD 6594.40160977 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM\",\"symbol\":\"KMD\"}" # 6594.40160977 +sleep 3 +echo "6594.40160977 <- expected amount RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM" + +# RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j\",\"symbol\":\"KMD\"}" # 9295.82639400 +sleep 3 +echo "9295.82639400 <- expected amount RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j" + +# RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns KMD 30681.77405788, REVS 608.60220842 +# RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns KMD 30681.77405788 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns\",\"symbol\":\"KMD\"}" # 30681.77405788 +sleep 3 +echo "30681.77405788 <- expected amount RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns" + +# RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8 KMD 257.45731805 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8\",\"symbol\":\"KMD\"}" # 257.45731805 +sleep 3 +echo "257.45731805 <- expected amount RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8" + +# RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM KMD 1163.91492974 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM\",\"symbol\":\"KMD\"}" # 1163.91492974 +sleep 3 +echo "1163.91492974 <- expected amount RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM" + +# RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL KMD 188643.68073877, REVS 597.97000000 +# RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL KMD 188643.68073877 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL\",\"symbol\":\"KMD\"}" # 188643.68073877 +sleep 3 +echo "188643.68073877 <- expected amount RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL" + +# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 99.43583265 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz\",\"symbol\":\"KMD\"}" # 99.43583265 +sleep 3 +echo "99.43583265 <- expected amount RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz" + +# RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU KMD 1394.37395910 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU\",\"symbol\":\"KMD\"}" # 1394.37395910 +sleep 3 +echo "1394.37395910 <- expected amount RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU" + +# RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h KMD 24207.88123437 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h\",\"symbol\":\"KMD\"}" # 24207.88123437 +sleep 3 +echo "24207.88123437 <- expected amount RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h" + +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 17160.85255783, REVS 233.03444206 +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 17160.85255783 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8\",\"symbol\":\"KMD\"}" # 17160.85255783 +sleep 3 +echo "17160.85255783 <- expected amount RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8" + +# REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe KMD 203188.29997688, REVS 2109.97700000 +# REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe KMD 203188.29997688 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe\",\"symbol\":\"KMD\"}" # 203188.29997688 +sleep 3 +echo "203188.29997688 <- expected amount REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe" + +# RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan KMD 2316.21007650 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan\",\"symbol\":\"KMD\"}" # 2316.21007650 +sleep 3 +echo "2316.21007650 <- expected amount RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan" + +# RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH\",\"symbol\":\"KMD\"}" # 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH" + +# RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV KMD 1663.06468462 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV\",\"symbol\":\"KMD\"}" # 1663.06468462 +sleep 3 +echo "1663.06468462 <- expected amount RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV" + +# RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn KMD 929.58263940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn\",\"symbol\":\"KMD\"}" # 929.58263940 +sleep 3 +echo "929.58263940 <- expected amount RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 91422.85735610 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX\",\"symbol\":\"KMD\"}" # 91422.85735610 +sleep 3 +echo "91422.85735610 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB KMD 138920.34502737, REVS 835.32960760 +# RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB KMD 138920.34502737 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB\",\"symbol\":\"KMD\"}" # 138920.34502737 +sleep 3 +echo "138920.34502737 <- expected amount RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB" + +# RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99 KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99" + +# RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 KMD 1422.54025612 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4\",\"symbol\":\"KMD\"}" # 1422.54025612 +sleep 3 +echo "1422.54025612 <- expected amount RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4" + +# RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN KMD 6041.35757346 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN\",\"symbol\":\"KMD\"}" # 6041.35757346 +sleep 3 +echo "6041.35757346 <- expected amount RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN" + +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 3571.37913637 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk\",\"symbol\":\"KMD\"}" # 3571.37913637 +sleep 3 +echo "3571.37913637 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk" + +# RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB KMD 0.29002598 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB\",\"symbol\":\"KMD\"}" # 0.29002598 +sleep 3 +echo "0.29002598 <- expected amount RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 25106.60529680 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut\",\"symbol\":\"KMD\"}" # 25106.60529680 +sleep 3 +echo "25106.60529680 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw\",\"symbol\":\"KMD\"}" # 48415.76246875 +sleep 3 +echo "48415.76246875 <- expected amount RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw" + +# RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu KMD 2420.78820090 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu\",\"symbol\":\"KMD\"}" # 2420.78820090 +sleep 3 +echo "2420.78820090 <- expected amount RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu" + +# REsjYn44yH4W9JcGiQND95mfJV98jzip9i KMD 6266.60868209 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REsjYn44yH4W9JcGiQND95mfJV98jzip9i\",\"symbol\":\"KMD\"}" # 6266.60868209 +sleep 3 +echo "6266.60868209 <- expected amount REsjYn44yH4W9JcGiQND95mfJV98jzip9i" + diff --git a/iguana/tests/KMD.batch8.listunspent b/iguana/tests/KMD.batch8.listunspent new file mode 100755 index 000000000..9a1f8b6b6 --- /dev/null +++ b/iguana/tests/KMD.batch8.listunspent @@ -0,0 +1,151 @@ +# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 11472.96269487 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8\",\"symbol\":\"KMD\"}" +echo "11472.96269487 <- expected amount REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8" + +# RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV KMD 914.10663775 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV\",\"symbol\":\"KMD\"}" +echo "914.10663775 <- expected amount RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV" + +# R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG KMD 840.13904995 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG\",\"symbol\":\"KMD\"}" +echo "840.13904995 <- expected amount R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG" + +# RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG KMD 23492.49573707, REVS 189.50500057 +# RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG KMD 23492.49573707 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG\",\"symbol\":\"KMD\"}" +echo "23492.49573707 <- expected amount RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG" + +# RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ KMD 2584.32223431 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ\",\"symbol\":\"KMD\"}" +echo "2584.32223431 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ" + +# RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX KMD 1278.17612917 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX\",\"symbol\":\"KMD\"}" +echo "1278.17612917 <- expected amount RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX" + +# RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS KMD 17042.34838900 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS\",\"symbol\":\"KMD\"}" +echo "17042.34838900 <- expected amount RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS" + +# RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a KMD 1198.78675406, REVS 23.78885452 +# RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a KMD 1198.78675406 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a\",\"symbol\":\"KMD\"}" +echo "1198.78675406 <- expected amount RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a" + +# RCownUMXktAgPvzwpALnGimCA1RDJoTvx1 KMD 952.88812828 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCownUMXktAgPvzwpALnGimCA1RDJoTvx1\",\"symbol\":\"KMD\"}" +echo "952.88812828 <- expected amount RCownUMXktAgPvzwpALnGimCA1RDJoTvx1" + +# RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM KMD 6594.40160977 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM\",\"symbol\":\"KMD\"}" +echo "6594.40160977 <- expected amount RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM" + +# RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j KMD 9295.82639400 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j\",\"symbol\":\"KMD\"}" +echo "9295.82639400 <- expected amount RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j" + +# RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns KMD 30681.77405788, REVS 608.60220842 +# RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns KMD 30681.77405788 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns\",\"symbol\":\"KMD\"}" +echo "30681.77405788 <- expected amount RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns" + +# RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8 KMD 257.45731805 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8\",\"symbol\":\"KMD\"}" +echo "257.45731805 <- expected amount RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8" + +# RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM KMD 1163.91492974 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM\",\"symbol\":\"KMD\"}" +echo "1163.91492974 <- expected amount RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM" + +# RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL KMD 188643.68073877, REVS 597.97000000 +# RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL KMD 188643.68073877 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL\",\"symbol\":\"KMD\"}" +echo "188643.68073877 <- expected amount RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL" + +# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 99.43583265 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz\",\"symbol\":\"KMD\"}" +echo "99.43583265 <- expected amount RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz" + +# RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU KMD 1394.37395910 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU\",\"symbol\":\"KMD\"}" +echo "1394.37395910 <- expected amount RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU" + +# RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h KMD 24207.88123437 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h\",\"symbol\":\"KMD\"}" +echo "24207.88123437 <- expected amount RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h" + +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 17160.85255783, REVS 233.03444206 +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 17160.85255783 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8\",\"symbol\":\"KMD\"}" +echo "17160.85255783 <- expected amount RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8" + +# REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe KMD 203188.29997688, REVS 2109.97700000 +# REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe KMD 203188.29997688 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe\",\"symbol\":\"KMD\"}" +echo "203188.29997688 <- expected amount REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe" + +# RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan KMD 2316.21007650 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan\",\"symbol\":\"KMD\"}" +echo "2316.21007650 <- expected amount RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan" + +# RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH\",\"symbol\":\"KMD\"}" +echo "968.31524937 <- expected amount RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH" + +# RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV KMD 1663.06468462 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV\",\"symbol\":\"KMD\"}" +echo "1663.06468462 <- expected amount RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV" + +# RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn KMD 929.58263940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn\",\"symbol\":\"KMD\"}" +echo "929.58263940 <- expected amount RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn" + +# RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX KMD 91422.85735610 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX\",\"symbol\":\"KMD\"}" +echo "91422.85735610 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + +# RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB KMD 138920.34502737, REVS 835.32960760 +# RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB KMD 138920.34502737 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB\",\"symbol\":\"KMD\"}" +echo "138920.34502737 <- expected amount RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB" + +# RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99 KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99" + +# RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 KMD 1422.54025612 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4\",\"symbol\":\"KMD\"}" +echo "1422.54025612 <- expected amount RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4" + +# RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN KMD 6041.35757346 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN\",\"symbol\":\"KMD\"}" +echo "6041.35757346 <- expected amount RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN" + +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 3571.37913637 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk\",\"symbol\":\"KMD\"}" +echo "3571.37913637 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk" + +# RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB KMD 0.29002598 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB\",\"symbol\":\"KMD\"}" +echo "0.29002598 <- expected amount RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 25106.60529680 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut\",\"symbol\":\"KMD\"}" +echo "25106.60529680 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw KMD 48415.76246875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw\",\"symbol\":\"KMD\"}" +echo "48415.76246875 <- expected amount RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw" + +# RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu KMD 2420.78820090 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu\",\"symbol\":\"KMD\"}" +echo "2420.78820090 <- expected amount RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu" + +# REsjYn44yH4W9JcGiQND95mfJV98jzip9i KMD 6266.60868209 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REsjYn44yH4W9JcGiQND95mfJV98jzip9i\",\"symbol\":\"KMD\"}" +echo "6266.60868209 <- expected amount REsjYn44yH4W9JcGiQND95mfJV98jzip9i" + diff --git a/iguana/tests/KMD.batch8.txids b/iguana/tests/KMD.batch8.txids new file mode 100644 index 000000000..db8f60d15 --- /dev/null +++ b/iguana/tests/KMD.batch8.txids @@ -0,0 +1,72 @@ +e706793cdd5ca2502b15067c429e31dd64ac37a9f7503b80685118dd3f0f2b33 +11472.96269487 <- expected amount REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 +c742705c385577030a48fb6e6cae157373f39a5330d2536d91c7b9a5fbd8a51b +914.10663775 <- expected amount RKprtuU6cDvhMGPwJAbycWY8gYtyyWrJBV +86edf4d8240f695f1241d317c5b6a2132927680aa2b5022d540f901b40a501fc +840.13904995 <- expected amount R9ctRNEYWbE5zDmT77Xhz22Fr1LpPVj8CG +5b4c1b73e41f8f15f52d86fb53626b9672c49d44bb73dcc618632c4c35b55996 +23492.49573707 <- expected amount RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG +38ae41db2fb95299e8201453f17341021ae25ffa28911bf2e68573f07bcbecec +2584.32223431 <- expected amount RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ +75fe74a840973f2901f6f8b18f6d4191e70c4edd6a2d0ced5024482d2bd218eb +1278.17612917 <- expected amount RQGJHTEwF7TcpCGHCdRZHZVcmngwucWdXX +4fd4a96c77cfaa80cb88e3cdcde880ea1dd15c478f2dbd3bac9cbafd0470da86 +17042.34838900 <- expected amount RAuq7MzV7DgjB2bLJJ9LunEj9P3zUMiNrS +166593bf7c22faa0f7d685e5040373362a99b86c61176a59578aca1f67985866 +1198.78675406 <- expected amount RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a +8db1f874f62ea9a74892aee5de46e07904c6a328e1d2fb89944c038587086349 +952.88812828 <- expected amount RCownUMXktAgPvzwpALnGimCA1RDJoTvx1 +91805b62414de7bf4452a827d34dfb797d531e5bd069cb0229028358d75e3a84 +6594.40160977 <- expected amount RSk32hhDqxGpFLNXBaza9e9HsSwEMmJJyM +9619461676f16f6d792c02ee1cf2c3c4895088c1031c767263086b3d7ebd744b +9295.82639400 <- expected amount RJyZ9XSE4b18JQWyxPFxTzNXqfkre6aF3j +8bb6c95663c93d5d91a0b9ebbb1bc01d3c8e776c76e9e6b7ecc449a9c4bf9795 +30681.77405788 <- expected amount RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns +0926ad92015e3d3a4313bcc43ae55382b6e0212aaef4ef2629a67f29e39d00cc +257.45731805 <- expected amount RQKz3VoxhXq3aKqx2YLZnFMEjQGQ9ZU8S8 +32097e87a4ae016c886035284962c77d755c86717db9fc23bfdb31ec852a1517 +1163.91492974 <- expected amount RLHX9dCaUDnvCa7GEragjBJv9wCAXUqfYM +eef0c4739bc5a43997fed140af0d9ec884b232726cab5ce6bf37bf77466c37bc +188643.68073877 <- expected amount RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL +4edbfa109229b18d241820c38c92183f87b3a74f7214d6f2470554e483701ba4 +99.43583265 <- expected amount RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz +e3a2b2d44d9ddb41f8cfaaf3e077409cdb80c3fe6be29b29801d447f36bd73e0 +1394.37395910 <- expected amount RPJDJKyCnHUEcSJCXPCcCVgAyYzTJQY9KU +6ffe858cd590d0237468450794fe5a5d38c7074f3e7ea4afaba36f511136557a +24207.88123437 <- expected amount RLi74YPDmXDf2UAiBoTqEwUayqX76cXb3h +3d33a0b167cdad93222d4d349f65b38aea97307e9fd73f230164eea2e2e3d339 +17160.85255783 <- expected amount RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 +c0a1609c53754a8c27f1435458f17a0f6c2ca49245929cc90b29a8120efe50c1 +203188.29997688 <- expected amount REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe +8cef57eecc08b69ed854d1ea77e7a3968050edd47973a36519499794ee5e5316 +2316.21007650 <- expected amount RPD3kfdgogsPGbXefBdRt4QpiDZXFHwqan +61891b96d6e4fcc42a2509618744e19df94d3949a45118a66e00408a052d1d62 +968.31524937 <- expected amount RGXyii2bqVefbqGmXtuaG19WQY5xa7f9qH +a1cb58ed4b02702c86dbb8c3a718d8f58ebc36704129618a3926a2e6c2add782 +1663.06468462 <- expected amount RG7jKgxwFPKNPy4MFxXaBr7TRDEzR2sSkV +92f853441f10b27af1f7bfa310c8407cf57b787bde24f9c5718f88dd2b412005 +929.58263940 <- expected amount RC63RYx695o7ve2fdjRtcXKqw4QwzTjqDn +4b86fcfbce4df5dc114c7ae8a8b12b6897ca3d3a5ccff395d7c668b1caa40b6e +91422.85735610 <- expected amount RLJ1GkGiu9jmDngdzYGNtwWffWkFYKgbuX +55282c7553eb17fa7d74c67aeb112e19effb4930cd8df184e18223dc3d1a4803 +693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv +c776090ef42630fa404ab43f36ed53b656c9dd69d19f3c5a380ff2939194f160 +138920.34502737 <- expected amount RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB +4d75910e5b0db53220ca8ebc1ea5e7ee8bfd5b9934ce2fbe65dbf429fc5320f6 +9683.15249375 <- expected amount RTUeFxM12wv69Mf5JcXFZGx9qVbGYtPf99 +3a3b068904ee87f157d0b3b7f2c7ab7252d0b9be1fcb0178f2bf2bfff04bc344 +1422.54025612 <- expected amount RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 +137664f7fecf790ed3c944b91870c11206a5e12774716403cee9b66903d3055c +6041.35757346 <- expected amount RLzSA37kWBnxCz3yTspTLg1Y85ai18LZoN +4f489677f35c8c3844e039330310c1e1c85aa41e368ae6caeff517040ed0f773 +3571.37913637 <- expected amount REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk +4efa01883041a797c20a1d320d36e3a2cff2b9958b28254ed88306a1448b7752 +0.29002598 <- expected amount RMuS51q7GuPd2jF8aYmRuD8vAwY3GpjhEB +fc195c8a97098890334c2291229d518cf03156100184dd9bb26fb548630bc387 +25106.60529680 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut +0569eae7e77315a56d78fc110d6130441d4fdac9e5fe27d32739055a959bb1ee +48415.76246875 <- expected amount RPm9bzUBbWbhqPdnydRxFnEk5XXxxcdMPw +744f5222411621ef1a9764beda4bd64795269a18759b83ee0d9a442889403a62 +2420.78820090 <- expected amount RUoGAwzyNUF1F22TkPq2Jx7cQVQk8Yn6Gu +8463044c21af1d44490760ac94ad05c279716ac8149e4cbf30b42b2ca987c386 +6266.60868209 <- expected amount REsjYn44yH4W9JcGiQND95mfJV98jzip9i diff --git a/iguana/tests/KMD.batch9 b/iguana/tests/KMD.batch9 new file mode 100755 index 000000000..e13df79af --- /dev/null +++ b/iguana/tests/KMD.batch9 @@ -0,0 +1,253 @@ +# RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL KMD 2225.74637484, REVS 44.17250867 +# RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL KMD 2225.74637484 +./komodo-cli sendtoaddress RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL 2225.74637484 +sleep 3 +echo "2225.74637484 <- expected amount RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL" + +# RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 KMD 71.93221162, REVS 1.27173666 +# RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 KMD 71.93221162 +./komodo-cli sendtoaddress RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 71.93221162 +sleep 3 +echo "71.93221162 <- expected amount RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5" + +# RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc KMD 929.58263940 +./komodo-cli sendtoaddress RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc 929.58263940 +sleep 3 +echo "929.58263940 <- expected amount RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc" + +# RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb KMD 38642.70360624 +./komodo-cli sendtoaddress RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb 38642.70360624 +sleep 3 +echo "38642.70360624 <- expected amount RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 338.77820389 +./komodo-cli sendtoaddress RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF 338.77820389 +sleep 3 +echo "338.77820389 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + +# RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC KMD 3010.53084291 +./komodo-cli sendtoaddress RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC 3010.53084291 +sleep 3 +echo "3010.53084291 <- expected amount RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC" + +# RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy KMD 9683.15249375 +./komodo-cli sendtoaddress RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy" + +# RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1 KMD 1318.49290289 +./komodo-cli sendtoaddress RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1 1318.49290289 +sleep 3 +echo "1318.49290289 <- expected amount RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1" + +# RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC KMD 1696.59450723 +./komodo-cli sendtoaddress RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC 1696.59450723 +sleep 3 +echo "1696.59450723 <- expected amount RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC" + +# RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4 KMD 9294.89681136 +./komodo-cli sendtoaddress RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4 9294.89681136 +sleep 3 +echo "9294.89681136 <- expected amount RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4" + +# RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN KMD 3873.26099750 +./komodo-cli sendtoaddress RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN" + +# RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX KMD 48410.92089250 +./komodo-cli sendtoaddress RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX 48410.92089250 +sleep 3 +echo "48410.92089250 <- expected amount RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX" + +# REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg KMD 24342.54200516 +./komodo-cli sendtoaddress REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg 24342.54200516 +sleep 3 +echo "24342.54200516 <- expected amount REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg" + +# RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy KMD 224445.72348323 +./komodo-cli sendtoaddress RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy 224445.72348323 +sleep 3 +echo "224445.72348323 <- expected amount RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy" + +# RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u KMD 4163.75557231 +./komodo-cli sendtoaddress RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u 4163.75557231 +sleep 3 +echo "4163.75557231 <- expected amount RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u" + +# RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW KMD 1060.11153500 +./komodo-cli sendtoaddress RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW 1060.11153500 +sleep 3 +echo "1060.11153500 <- expected amount RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW" + +# RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM KMD 5526.71509918 +./komodo-cli sendtoaddress RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM 5526.71509918 +sleep 3 +echo "5526.71509918 <- expected amount RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM" + +# RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb KMD 163809.81597006, REVS 3251.55110000 +# RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb KMD 163809.81597006 +./komodo-cli sendtoaddress RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb 163809.81597006 +sleep 3 +echo "163809.81597006 <- expected amount RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb" + +# RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN KMD 968.31524937 +./komodo-cli sendtoaddress RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN" + +# RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq KMD 4785.58282591, REVS 2.73080820 +# RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq KMD 4785.58282591 +./komodo-cli sendtoaddress RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq 4785.58282591 +sleep 3 +echo "4785.58282591 <- expected amount RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq" + +# REALH3GPjNeVt3q9URisFKKCvjZd6NQcid KMD 631.99999696 +./komodo-cli sendtoaddress REALH3GPjNeVt3q9URisFKKCvjZd6NQcid 631.99999696 +sleep 3 +echo "631.99999696 <- expected amount REALH3GPjNeVt3q9URisFKKCvjZd6NQcid" + +# RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo KMD 2826.51221292 +./komodo-cli sendtoaddress RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo 2826.51221292 +sleep 3 +echo "2826.51221292 <- expected amount RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo" + +# RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q KMD 14524.72874062 +./komodo-cli sendtoaddress RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q 14524.72874062 +sleep 3 +echo "14524.72874062 <- expected amount RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q" + +# RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj KMD 112939.81142424, REVS 2241.80390030 +# RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj KMD 112939.81142424 +./komodo-cli sendtoaddress RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj 112939.81142424 +sleep 3 +echo "112939.81142424 <- expected amount RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj" + +# RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v KMD 813.38480947 +./komodo-cli sendtoaddress RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v 813.38480947 +sleep 3 +echo "813.38480947 <- expected amount RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v" + +# RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM KMD 6777.23843037 +./komodo-cli sendtoaddress RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM 6777.23843037 +sleep 3 +echo "6777.23843037 <- expected amount RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM" + +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 253.57894226 +./komodo-cli sendtoaddress RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u 253.57894226 +sleep 3 +echo "253.57894226 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u" + +# RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7 KMD 4841.57624687 +./komodo-cli sendtoaddress RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7 4841.57624687 +sleep 3 +echo "4841.57624687 <- expected amount RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7" + +# RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU KMD 1788.59446342 +./komodo-cli sendtoaddress RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU 1788.59446342 +sleep 3 +echo "1788.59446342 <- expected amount RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU" + +# RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u KMD 4840.60793162 +./komodo-cli sendtoaddress RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u 4840.60793162 +sleep 3 +echo "4840.60793162 <- expected amount RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u" + +# RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj KMD 21334.16787115 +./komodo-cli sendtoaddress RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj 21334.16787115 +sleep 3 +echo "21334.16787115 <- expected amount RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj" + +# REBRXGotFX5fojy22CFEzq88EbbZux9CjM KMD 2075.39004188 +./komodo-cli sendtoaddress REBRXGotFX5fojy22CFEzq88EbbZux9CjM 2075.39004188 +sleep 3 +echo "2075.39004188 <- expected amount REBRXGotFX5fojy22CFEzq88EbbZux9CjM" + +# RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD KMD 7111.30719141 +./komodo-cli sendtoaddress RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD 7111.30719141 +sleep 3 +echo "7111.30719141 <- expected amount RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD" + +# REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m KMD 142057.63342296 +./komodo-cli sendtoaddress REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m 142057.63342296 +sleep 3 +echo "142057.63342296 <- expected amount REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m" + +# RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK KMD 27999.94713904 +./komodo-cli sendtoaddress RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK 27999.94713904 +sleep 3 +echo "27999.94713904 <- expected amount RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK" + +# RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb KMD 2026.68381694 +./komodo-cli sendtoaddress RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb 2026.68381694 +sleep 3 +echo "2026.68381694 <- expected amount RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb" + +# RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz KMD 264.96107994 +./komodo-cli sendtoaddress RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz 264.96107994 +sleep 3 +echo "264.96107994 <- expected amount RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz" + +# RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY KMD 6951.11546870 +./komodo-cli sendtoaddress RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY 6951.11546870 +sleep 3 +echo "6951.11546870 <- expected amount RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY" + +# RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq KMD 3325.70020871, REVS 65.95939412 +# RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq KMD 3325.70020871 +./komodo-cli sendtoaddress RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq 3325.70020871 +sleep 3 +echo "3325.70020871 <- expected amount RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq" + +# RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP KMD 773.87754730 +./komodo-cli sendtoaddress RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP 773.87754730 +sleep 3 +echo "773.87754730 <- expected amount RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP" + +# RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M KMD 8908.50029425 +./komodo-cli sendtoaddress RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M 8908.50029425 +sleep 3 +echo "8908.50029425 <- expected amount RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M" + +# RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD KMD 2802.45988185 +./komodo-cli sendtoaddress RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD 2802.45988185 +sleep 3 +echo "2802.45988185 <- expected amount RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD" + +# R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz KMD 27199.08040085 +./komodo-cli sendtoaddress R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz 27199.08040085 +sleep 3 +echo "27199.08040085 <- expected amount R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz" + +# RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz KMD 818.43860613 +./komodo-cli sendtoaddress RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz 818.43860613 +sleep 3 +echo "818.43860613 <- expected amount RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz" + +# RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN KMD 1544.33012483 +./komodo-cli sendtoaddress RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN 1544.33012483 +sleep 3 +echo "1544.33012483 <- expected amount RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN" + +# R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg KMD 30016.80441537 +./komodo-cli sendtoaddress R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg 30016.80441537 +sleep 3 +echo "30016.80441537 <- expected amount R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg" + +# RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN KMD 4146.19464926 +./komodo-cli sendtoaddress RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN 4146.19464926 +sleep 3 +echo "4146.19464926 <- expected amount RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 24089.07982436 +./komodo-cli sendtoaddress RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut 24089.07982436 +sleep 3 +echo "24089.07982436 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +./komodo-cli sendtoaddress RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + + +# total KMD 1012975.94073092 REVS 0.00000000 diff --git a/iguana/tests/KMD.batch9.importaddress b/iguana/tests/KMD.batch9.importaddress new file mode 100755 index 000000000..77d831f7f --- /dev/null +++ b/iguana/tests/KMD.batch9.importaddress @@ -0,0 +1,251 @@ +# RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL KMD 2225.74637484, REVS 44.17250867 +# RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL KMD 2225.74637484 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL\",\"symbol\":\"KMD\"}" # 2225.74637484 +sleep 3 +echo "2225.74637484 <- expected amount RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL" + +# RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 KMD 71.93221162, REVS 1.27173666 +# RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 KMD 71.93221162 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5\",\"symbol\":\"KMD\"}" # 71.93221162 +sleep 3 +echo "71.93221162 <- expected amount RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5" + +# RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc KMD 929.58263940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc\",\"symbol\":\"KMD\"}" # 929.58263940 +sleep 3 +echo "929.58263940 <- expected amount RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc" + +# RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb KMD 38642.70360624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb\",\"symbol\":\"KMD\"}" # 38642.70360624 +sleep 3 +echo "38642.70360624 <- expected amount RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 338.77820389 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF\",\"symbol\":\"KMD\"}" # 338.77820389 +sleep 3 +echo "338.77820389 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + +# RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC KMD 3010.53084291 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC\",\"symbol\":\"KMD\"}" # 3010.53084291 +sleep 3 +echo "3010.53084291 <- expected amount RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC" + +# RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy\",\"symbol\":\"KMD\"}" # 9683.15249375 +sleep 3 +echo "9683.15249375 <- expected amount RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy" + +# RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1 KMD 1318.49290289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1\",\"symbol\":\"KMD\"}" # 1318.49290289 +sleep 3 +echo "1318.49290289 <- expected amount RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1" + +# RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC KMD 1696.59450723 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC\",\"symbol\":\"KMD\"}" # 1696.59450723 +sleep 3 +echo "1696.59450723 <- expected amount RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC" + +# RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4 KMD 9294.89681136 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4\",\"symbol\":\"KMD\"}" # 9294.89681136 +sleep 3 +echo "9294.89681136 <- expected amount RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4" + +# RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN\",\"symbol\":\"KMD\"}" # 3873.26099750 +sleep 3 +echo "3873.26099750 <- expected amount RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN" + +# RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX KMD 48410.92089250 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX\",\"symbol\":\"KMD\"}" # 48410.92089250 +sleep 3 +echo "48410.92089250 <- expected amount RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX" + +# REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg KMD 24342.54200516 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg\",\"symbol\":\"KMD\"}" # 24342.54200516 +sleep 3 +echo "24342.54200516 <- expected amount REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg" + +# RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy KMD 224445.72348323 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy\",\"symbol\":\"KMD\"}" # 224445.72348323 +sleep 3 +echo "224445.72348323 <- expected amount RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy" + +# RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u KMD 4163.75557231 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u\",\"symbol\":\"KMD\"}" # 4163.75557231 +sleep 3 +echo "4163.75557231 <- expected amount RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u" + +# RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW KMD 1060.11153500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW\",\"symbol\":\"KMD\"}" # 1060.11153500 +sleep 3 +echo "1060.11153500 <- expected amount RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW" + +# RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM KMD 5526.71509918 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM\",\"symbol\":\"KMD\"}" # 5526.71509918 +sleep 3 +echo "5526.71509918 <- expected amount RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM" + +# RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb KMD 163809.81597006, REVS 3251.55110000 +# RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb KMD 163809.81597006 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb\",\"symbol\":\"KMD\"}" # 163809.81597006 +sleep 3 +echo "163809.81597006 <- expected amount RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb" + +# RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN\",\"symbol\":\"KMD\"}" # 968.31524937 +sleep 3 +echo "968.31524937 <- expected amount RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN" + +# RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq KMD 4785.58282591, REVS 2.73080820 +# RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq KMD 4785.58282591 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq\",\"symbol\":\"KMD\"}" # 4785.58282591 +sleep 3 +echo "4785.58282591 <- expected amount RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq" + +# REALH3GPjNeVt3q9URisFKKCvjZd6NQcid KMD 631.99999696 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REALH3GPjNeVt3q9URisFKKCvjZd6NQcid\",\"symbol\":\"KMD\"}" # 631.99999696 +sleep 3 +echo "631.99999696 <- expected amount REALH3GPjNeVt3q9URisFKKCvjZd6NQcid" + +# RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo KMD 2826.51221292 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo\",\"symbol\":\"KMD\"}" # 2826.51221292 +sleep 3 +echo "2826.51221292 <- expected amount RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo" + +# RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q KMD 14524.72874062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q\",\"symbol\":\"KMD\"}" # 14524.72874062 +sleep 3 +echo "14524.72874062 <- expected amount RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q" + +# RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj KMD 112939.81142424, REVS 2241.80390030 +# RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj KMD 112939.81142424 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj\",\"symbol\":\"KMD\"}" # 112939.81142424 +sleep 3 +echo "112939.81142424 <- expected amount RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj" + +# RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v KMD 813.38480947 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v\",\"symbol\":\"KMD\"}" # 813.38480947 +sleep 3 +echo "813.38480947 <- expected amount RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v" + +# RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM KMD 6777.23843037 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM\",\"symbol\":\"KMD\"}" # 6777.23843037 +sleep 3 +echo "6777.23843037 <- expected amount RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM" + +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 253.57894226 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u\",\"symbol\":\"KMD\"}" # 253.57894226 +sleep 3 +echo "253.57894226 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u" + +# RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7 KMD 4841.57624687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7\",\"symbol\":\"KMD\"}" # 4841.57624687 +sleep 3 +echo "4841.57624687 <- expected amount RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7" + +# RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU KMD 1788.59446342 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU\",\"symbol\":\"KMD\"}" # 1788.59446342 +sleep 3 +echo "1788.59446342 <- expected amount RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU" + +# RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u KMD 4840.60793162 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u\",\"symbol\":\"KMD\"}" # 4840.60793162 +sleep 3 +echo "4840.60793162 <- expected amount RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u" + +# RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj KMD 21334.16787115 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj\",\"symbol\":\"KMD\"}" # 21334.16787115 +sleep 3 +echo "21334.16787115 <- expected amount RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj" + +# REBRXGotFX5fojy22CFEzq88EbbZux9CjM KMD 2075.39004188 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REBRXGotFX5fojy22CFEzq88EbbZux9CjM\",\"symbol\":\"KMD\"}" # 2075.39004188 +sleep 3 +echo "2075.39004188 <- expected amount REBRXGotFX5fojy22CFEzq88EbbZux9CjM" + +# RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD KMD 7111.30719141 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD\",\"symbol\":\"KMD\"}" # 7111.30719141 +sleep 3 +echo "7111.30719141 <- expected amount RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD" + +# REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m KMD 142057.63342296 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m\",\"symbol\":\"KMD\"}" # 142057.63342296 +sleep 3 +echo "142057.63342296 <- expected amount REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m" + +# RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK KMD 27999.94713904 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK\",\"symbol\":\"KMD\"}" # 27999.94713904 +sleep 3 +echo "27999.94713904 <- expected amount RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK" + +# RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb KMD 2026.68381694 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb\",\"symbol\":\"KMD\"}" # 2026.68381694 +sleep 3 +echo "2026.68381694 <- expected amount RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb" + +# RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz KMD 264.96107994 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz\",\"symbol\":\"KMD\"}" # 264.96107994 +sleep 3 +echo "264.96107994 <- expected amount RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz" + +# RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY KMD 6951.11546870 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY\",\"symbol\":\"KMD\"}" # 6951.11546870 +sleep 3 +echo "6951.11546870 <- expected amount RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY" + +# RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq KMD 3325.70020871, REVS 65.95939412 +# RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq KMD 3325.70020871 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq\",\"symbol\":\"KMD\"}" # 3325.70020871 +sleep 3 +echo "3325.70020871 <- expected amount RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq" + +# RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP KMD 773.87754730 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP\",\"symbol\":\"KMD\"}" # 773.87754730 +sleep 3 +echo "773.87754730 <- expected amount RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP" + +# RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M\",\"symbol\":\"KMD\"}" # 8908.50029425 +sleep 3 +echo "8908.50029425 <- expected amount RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M" + +# RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD KMD 2802.45988185 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD\",\"symbol\":\"KMD\"}" # 2802.45988185 +sleep 3 +echo "2802.45988185 <- expected amount RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD" + +# R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz KMD 27199.08040085 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz\",\"symbol\":\"KMD\"}" # 27199.08040085 +sleep 3 +echo "27199.08040085 <- expected amount R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz" + +# RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz KMD 818.43860613 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz\",\"symbol\":\"KMD\"}" # 818.43860613 +sleep 3 +echo "818.43860613 <- expected amount RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz" + +# RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN KMD 1544.33012483 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN\",\"symbol\":\"KMD\"}" # 1544.33012483 +sleep 3 +echo "1544.33012483 <- expected amount RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN" + +# R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg KMD 30016.80441537 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg\",\"symbol\":\"KMD\"}" # 30016.80441537 +sleep 3 +echo "30016.80441537 <- expected amount R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg" + +# RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN KMD 4146.19464926 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN\",\"symbol\":\"KMD\"}" # 4146.19464926 +sleep 3 +echo "4146.19464926 <- expected amount RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 24089.07982436 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut\",\"symbol\":\"KMD\"}" # 24089.07982436 +sleep 3 +echo "24089.07982436 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" # 693.08132289 +sleep 3 +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" + diff --git a/iguana/tests/KMD.batch9.listunspent b/iguana/tests/KMD.batch9.listunspent new file mode 100755 index 000000000..a428359de --- /dev/null +++ b/iguana/tests/KMD.batch9.listunspent @@ -0,0 +1,200 @@ +# RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL KMD 2225.74637484 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL\",\"symbol\":\"KMD\"}" +echo "2225.74637484 <- expected amount RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL" + +# RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 KMD 71.93221162, REVS 1.27173666 +# RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 KMD 71.93221162 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5\",\"symbol\":\"KMD\"}" +echo "71.93221162 <- expected amount RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5" + +# RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc KMD 929.58263940 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc\",\"symbol\":\"KMD\"}" +echo "929.58263940 <- expected amount RJ8xVxojynDtLj4MVY1Tsxvkv4Sbwajutc" + +# RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb KMD 38642.70360624 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb\",\"symbol\":\"KMD\"}" +echo "38642.70360624 <- expected amount RSEGac8BnijkbygChtYXnMnLUpAvWvhHWb" + +# RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF KMD 338.77820389 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF\",\"symbol\":\"KMD\"}" +echo "338.77820389 <- expected amount RKQPNcePppEkV4CMXZrwqEMAvRHbruKVdF" + +# RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC KMD 3010.53084291 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC\",\"symbol\":\"KMD\"}" +echo "3010.53084291 <- expected amount RNHXPTTCq6tMb7xV52ermT9s6k29HN2TJC" + +# RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy KMD 9683.15249375 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy\",\"symbol\":\"KMD\"}" +echo "9683.15249375 <- expected amount RHptgvQVXDWFckRfgocRbEWxbQoPBKsWcy" + +# RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1 KMD 1318.49290289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1\",\"symbol\":\"KMD\"}" +echo "1318.49290289 <- expected amount RFutyg6w7miN1FPvJiNwTzV1NfJ4Y4HGt1" + +# RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC KMD 1696.59450723 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC\",\"symbol\":\"KMD\"}" +echo "1696.59450723 <- expected amount RGMX8qe4DgbPTXTYZXmLowXf6hriQuzhyC" + +# RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4 KMD 9294.89681136 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4\",\"symbol\":\"KMD\"}" +echo "9294.89681136 <- expected amount RVN1oyNtmgWGteHfdiQcnzUUHz48STqxg4" + +# RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN KMD 3873.26099750 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN\",\"symbol\":\"KMD\"}" +echo "3873.26099750 <- expected amount RQQgVtao1Li8RmvhUaZR3DYLMEv1boWiSN" + +# RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX KMD 48410.92089250 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX\",\"symbol\":\"KMD\"}" +echo "48410.92089250 <- expected amount RJNbZ57kzkNkA4fBmKynhXFddH4njTbUcX" + +# REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg KMD 24342.54200516 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg\",\"symbol\":\"KMD\"}" +echo "24342.54200516 <- expected amount REM9dVPx7ZkMKEVyFnNJ9CDJGCmE8UL1vg" + +# RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy KMD 224445.72348323 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy\",\"symbol\":\"KMD\"}" +echo "224445.72348323 <- expected amount RKdNj83UsxCDPHKh6AyN28nGtUVxJZywuy" + +# RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u KMD 4163.75557231 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u\",\"symbol\":\"KMD\"}" +echo "4163.75557231 <- expected amount RKBoXULPPTR2QyAH6axGTsXncbT8mfGS2u" + +# RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW KMD 1060.11153500 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW\",\"symbol\":\"KMD\"}" +echo "1060.11153500 <- expected amount RLu1gA75ySXwnYsimbUdtJr6xFJTqXrKJW" + +# RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM KMD 5526.71509918 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM\",\"symbol\":\"KMD\"}" +echo "5526.71509918 <- expected amount RMJXpqJjgPrbNCpLnug3LKzqjYCJ2AmDVM" + +# RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb KMD 163809.81597006, REVS 3251.55110000 +# RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb KMD 163809.81597006 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb\",\"symbol\":\"KMD\"}" +echo "163809.81597006 <- expected amount RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb" + +# RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN KMD 968.31524937 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN\",\"symbol\":\"KMD\"}" +echo "968.31524937 <- expected amount RDSVuxLxeFYLqisj9Tdk5ThB5PzY7HBptN" + +# RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq KMD 4785.58282591, REVS 2.73080820 +# RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq KMD 4785.58282591 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq\",\"symbol\":\"KMD\"}" +echo "4785.58282591 <- expected amount RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq" + +# REALH3GPjNeVt3q9URisFKKCvjZd6NQcid KMD 631.99999696 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REALH3GPjNeVt3q9URisFKKCvjZd6NQcid\",\"symbol\":\"KMD\"}" +echo "631.99999696 <- expected amount REALH3GPjNeVt3q9URisFKKCvjZd6NQcid" + +# RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo KMD 2826.51221292 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo\",\"symbol\":\"KMD\"}" +echo "2826.51221292 <- expected amount RTKmpREsZKc28s3oQAuWqGYh1xVtwJjHBo" + +# RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q KMD 14524.72874062 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q\",\"symbol\":\"KMD\"}" +echo "14524.72874062 <- expected amount RA27UHcoKZuDU5dE8eBjcFNdGHgaw2ux6q" + +# RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj KMD 112939.81142424, REVS 2241.80390030 +# RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj KMD 112939.81142424 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj\",\"symbol\":\"KMD\"}" +echo "112939.81142424 <- expected amount RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj" + +# RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v KMD 813.38480947 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v\",\"symbol\":\"KMD\"}" +echo "813.38480947 <- expected amount RPJ9T5XcXJgqf1PstxE5xzFFWq7vonAr5v" + +# RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM KMD 6777.23843037 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM\",\"symbol\":\"KMD\"}" +echo "6777.23843037 <- expected amount RHzaoiAXNB6AkUXbpwVBapd2dpsDBxWtLM" + +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 253.57894226 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u\",\"symbol\":\"KMD\"}" +echo "253.57894226 <- expected amount RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u" + +# RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7 KMD 4841.57624687 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7\",\"symbol\":\"KMD\"}" +echo "4841.57624687 <- expected amount RYZ62rj6VEgojsWhkxT5ucV6kZnwMGBKr7" + +# RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU KMD 1788.59446342 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU\",\"symbol\":\"KMD\"}" +echo "1788.59446342 <- expected amount RU21Y5CyH5xgGC5aHdqXoss8z7wkNQoacU" + +# RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u KMD 4840.60793162 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u\",\"symbol\":\"KMD\"}" +echo "4840.60793162 <- expected amount RJ8tyXNVoi4iLLMJxirCYzRj1tXpUFmN2u" + +# RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj KMD 21334.16787115 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj\",\"symbol\":\"KMD\"}" +echo "21334.16787115 <- expected amount RFkZfkHiRrtAmSMsfj7CVS6hkvLagEqYKj" + +# REBRXGotFX5fojy22CFEzq88EbbZux9CjM KMD 2075.39004188 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REBRXGotFX5fojy22CFEzq88EbbZux9CjM\",\"symbol\":\"KMD\"}" +echo "2075.39004188 <- expected amount REBRXGotFX5fojy22CFEzq88EbbZux9CjM" + +# RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD KMD 7111.30719141 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD\",\"symbol\":\"KMD\"}" +echo "7111.30719141 <- expected amount RFZyBhemdJqpRSppnVYPJZ5wUW6JtbnsHD" + +# REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m KMD 142057.63342296 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m\",\"symbol\":\"KMD\"}" +echo "142057.63342296 <- expected amount REbV2nRwPWFAdrW2BzmjpDpxTNErm2468m" + +# RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK KMD 27999.94713904 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK\",\"symbol\":\"KMD\"}" +echo "27999.94713904 <- expected amount RYRiQU4nVLcjaEtqtrNpDQBRS3ovbjDFaK" + +# RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb KMD 2026.68381694 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb\",\"symbol\":\"KMD\"}" +echo "2026.68381694 <- expected amount RU292SeuDimqFSdZXmdmjd1BZcxLWzqqfb" + +# RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz KMD 264.96107994 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz\",\"symbol\":\"KMD\"}" +echo "264.96107994 <- expected amount RXTemgKRoF4d28V5fLJxAWWcJyaoTRmZyz" + +# RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY KMD 6951.11546870 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY\",\"symbol\":\"KMD\"}" +echo "6951.11546870 <- expected amount RPx4vRAMxvAjH33g6q4a27UL3CHcJtJ8VY" + +# RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq KMD 3325.70020871, REVS 65.95939412 +# RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq KMD 3325.70020871 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq\",\"symbol\":\"KMD\"}" +echo "3325.70020871 <- expected amount RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq" + +# RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP KMD 773.87754730 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP\",\"symbol\":\"KMD\"}" +echo "773.87754730 <- expected amount RFPHfk7EtgVSoiFJLXgu8tbfXFJSbsN4cP" + +# RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M KMD 8908.50029425 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M\",\"symbol\":\"KMD\"}" +echo "8908.50029425 <- expected amount RPHUJ7RmVAPCFqPhxpxo6E4kc54w7t5A8M" + +# RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD KMD 2802.45988185 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD\",\"symbol\":\"KMD\"}" +echo "2802.45988185 <- expected amount RCkPBpsQtbB2JDbHLU4RpC2DecxRvpZ9BD" + +# R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz KMD 27199.08040085 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz\",\"symbol\":\"KMD\"}" +echo "27199.08040085 <- expected amount R9kB2xFTKB5wMXTW6i7bNiEWx4hsJKCzbz" + +# RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz KMD 818.43860613 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz\",\"symbol\":\"KMD\"}" +echo "818.43860613 <- expected amount RWwjkQec3yhivp7UuWRqYWvKJDA3EAADZz" + +# RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN KMD 1544.33012483 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN\",\"symbol\":\"KMD\"}" +echo "1544.33012483 <- expected amount RBBwTTeLq3tkeBg5GxKX6JugEv5pTijiyN" + +# R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg KMD 30016.80441537 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg\",\"symbol\":\"KMD\"}" +echo "30016.80441537 <- expected amount R9Jz7RWJ6LVBhrt2RgY6SSMWEkmKHqz5qg" + +# RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN KMD 4146.19464926 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN\",\"symbol\":\"KMD\"}" +echo "4146.19464926 <- expected amount RXBFW2KavmhfhbkEbofYueD66Laq4kYZQN" + +# RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut KMD 24089.07982436 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut\",\"symbol\":\"KMD\"}" +echo "24089.07982436 <- expected amount RXdBJ5cWDcS38ykuggEQZh3vSztxwmG3ut" + +# RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv KMD 693.08132289 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv\",\"symbol\":\"KMD\"}" +echo "693.08132289 <- expected amount RHJ55iWUQNbKcSn8shbv1RbGuip3RSRHFv" diff --git a/iguana/tests/KMD.bounty0 b/iguana/tests/KMD.bounty0 new file mode 100644 index 000000000..4ae393026 --- /dev/null +++ b/iguana/tests/KMD.bounty0 @@ -0,0 +1,115 @@ +sleep 99999 +./komodo-cli sendtoaddress RSYpupqZVwubaRADkasjHnWAQwHmZ91gwo 775 +./komodo-cli sendtoaddress RPVNUvVq4BgKrrB3E1uULja2hjPW6Hv6r9 1162 +./komodo-cli sendtoaddress RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt 1162 +./komodo-cli sendtoaddress RXs3VbEem331Rxg1Jac3hqknTti4UUo5pz 775 +./komodo-cli sendtoaddress RE1wsrDNwW2NnNWM5eE162yp6haLtm5uh7 775 +./komodo-cli sendtoaddress R9jjHXGTWmT19dVuqyTXv9sETectd1PjsP 388 +./komodo-cli sendtoaddress RFU7peqch5dMXr2Hm7Quz1VeHirkxsomSC 1937 +./komodo-cli sendtoaddress RM6mJs8LG1des4HhXaj4DS5mnF3hgsE56g 2000 +./komodo-cli sendtoaddress RHKuiEoakr9yeWQT9UZzCrqPgR8MPBaGvD 1000 +./komodo-cli sendtoaddress RC8jWr1QQsRyo1pDkue8AxGs58Wyz4F3wZ 777 +./komodo-cli sendtoaddress RDzixD5TUH8MHPQQ4WeL3qjP6GqQvtzssH 100 +./komodo-cli sendtoaddress RLHADkss8t2xJWxoBqH1Vj8bqEhAt8YgK7 100 +./komodo-cli sendtoaddress RSsTgVnqh9qvcrKmZTg596VQ7moyNrh1WD 100 +./komodo-cli sendtoaddress RBEJuQMGaB1uSJuH4U1yCgbksZRaGyZaJE 100 +./komodo-cli sendtoaddress RKZNz4pVsguad4HM5H71YwRFjRNnWGvMTi 100 +./komodo-cli sendtoaddress RN1t6SGGsWGrgcfE8fJPJWwHmKH4zE93Vj 100 +./komodo-cli sendtoaddress RWZetGBkP4UiFQFht1Tem4pLAyvGjBGRY5 100 +./komodo-cli sendtoaddress RRCNocaPAB74cUzZDr8iepomNJiZGYiKno 100 +./komodo-cli sendtoaddress RLKpQZGWbkciVEmvtNVT93VLbm8kFE9BBB 100 +./komodo-cli sendtoaddress RJG3GAzYkX2BypfFXsZ6M8zozpX1ALSdpm 100 +./komodo-cli sendtoaddress RFTF6ya1XDqtFrAunPdJ3g4bUZrMCD8cEM 100 +./komodo-cli sendtoaddress RQJYttaCzFwb8iNNTJuyHjRt7hyjYZG4yX 100 +./komodo-cli sendtoaddress RNoaDacQgoYifqagidpsMqTQ74t5QxDWXd 100 +./komodo-cli sendtoaddress RMg5XaC6Lsj3YT2FtCtSDCAa5i715NYxrf 100 +./komodo-cli sendtoaddress RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt 908 +./komodo-cli sendtoaddress RKcZmLNMsfdooKLzD6pRRDnbECBoygTQbz 1005 +./komodo-cli sendtoaddress RTHtdb735hqJi5DJjXNiP2LREkqUL5b8Sx 484 +./komodo-cli sendtoaddress RRergGKQPDcYHU8PxKhpx6kmR7mXdqp8Ce 1150 +./komodo-cli sendtoaddress RLxJJAZzFZUj9t23KbHARNywC7twcMHq3o 908 +./komodo-cli sendtoaddress RKMWyyocd1CSMRqByAfsn31QHoqZd9Bfk4 1126 +./komodo-cli sendtoaddress RG4jMz3SPqXQL8Eqj6q5CFLefB2PDw2qkx 605 +./komodo-cli sendtoaddress RFPKxBL8iLQGmkoUukXdFU7VkXyGJLSsGw 726 +./komodo-cli sendtoaddress RVryLHd1zcrC4J2q2fzSWdTTXuDWz43wKa 605 +./komodo-cli sendtoaddress RBzif61dTsAJsZQd3L4Q559nsuUNXp6N4R 545 +./komodo-cli sendtoaddress RHzPpnxWeyiydRdNoTYv3b2akDr9mPAf4Q 1210 +./komodo-cli sendtoaddress RLVqd66r5LXb4ZvYjzpVVoKEQboiMrZnYY 575 +./komodo-cli sendtoaddress RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72 1452 +./komodo-cli sendtoaddress RSJsEK1pstctVa5A5Tn57SqtRUfbAovRef 508 +./komodo-cli sendtoaddress RRaSQCAWk74r5cXzZV8JqqW9JFbhF2o2nH 1816 +./komodo-cli sendtoaddress RAFRxQLG1PYUTbo51BTK8XnU7txmZ6n4gS 520 +./komodo-cli sendtoaddress RKMWyyocd1CSMRqByAfsn31QHoqZd9Bfk4 545 +./komodo-cli sendtoaddress RG3BbpMegpZNqDetqw4fuUZFiSXurg3drG 908 +./komodo-cli sendtoaddress RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx 1089 +./komodo-cli sendtoaddress R9ce1xHEaWnRRP5jrWozEfPf9ZJgX7jnxd 605 +./komodo-cli sendtoaddress RXuNeDyRd2EAKaYZryYrB4CcwtomRjuNeX 520 +./komodo-cli sendtoaddress RSTKuMryZW56yf3kdEXhMJG8Hy9TwvHwYs 908 +./komodo-cli sendtoaddress RVQ9CuyZzaScspJV5sGSiZ3TTkwbP3hzwq 726 +./komodo-cli sendtoaddress R9biWRWRVedJh8FKqWY8Y3FWnV6XupYWYH 1186 +./komodo-cli sendtoaddress RHoouCBBapEHE6uyX7CxHGFcRwUQFGMot5 756 +./komodo-cli sendtoaddress RWszpjqDXG6ifFzTJN2qaqSfZ4nJ8FX3Cp 908 +./komodo-cli sendtoaddress RXazQXNerkDmCdvPTmSU3VeLKBZ1CTtyAj 490 +./komodo-cli sendtoaddress RSeppnxMwvVDkiA5d3wDZjyeYwvcyn8dve 697 +./komodo-cli sendtoaddress RHbf3qwhmmUBw3WNR5NYoMx3YH13JjXWrv 363 +./komodo-cli sendtoaddress RFN4H8YYm71TjCVkHkoVFBFpg31i4ejbiu 310 +./komodo-cli sendtoaddress RBGX2Z43Fiey6tkgRCL9rzc3gNhdcvQyzf 436 +./komodo-cli sendtoaddress RNyoYchuVZXH8vKE4uSRpJwKi87K6ChrWr 871 + +ea1c78c745ce438e63162245391a81fe927bedfc271b1ec2dc5cba2e7404ceb8 +7abf28ba81489341f1ca84624ad7dd906c59a9aa918797ef5ac0ce1f6c65e755 +9a267a73e883828c418a4787402d95f0593bf0c7c94c320447d1f6a52bd2cd45 +9f3d10b949f59be536a5ae1407ec5dd3c116d5a2566cef6ef4220eb42adc1e93 +73d27618816805a9d8ced056ef1374d8705935320c92f6f7134e6c2b7e2233ac +f5002db57264351d06184285a72d588dc46d8923f52e7b79b8b24dde0ac52a60 +64418ecd76d064689aef22ccdf57e5375a8994219a80ffec605a6456c47cce02 +964ab4c6d0a755b6c694076fce6c32ea0f45864988f6fae198cd83dc885f203c +ebb5800be0ffe1817998d3addf301000c915c4591da3c6056bcc5cdf6f854a3a +33201a7465d55203c376c96921ed664dc2c40454c00de2442affca491b5982b8 +33248c0f33b0af88d7ea1e76dd9d9dcc5da262bce5550b6a50f6bc76aed9f0c8 +e313f326440b6873d76e0f6f886747dd9eef75d6247308b8c9c1d277cc7d0dae +0d5139cb9361e5c23e297dc9b9a6482cf515625011f2b96683559a50a07df0f9 +5ea2e77e4a3453321c0ab116afb16fbce872fda21e4f366a475362648a5a2541 +352c0563da158e5cab2e01040ceab5f680b9fad7487d0d72ca18b23117fcb0d0 +f2a46fc6f9bc318a75be0b4bc02192cd980492423b7ef972ae5ce71f012409f5 +76bb6dfd31e599fcb7f388691b19fb09cd18add9aa61c2f94b6e7b81d9e6e00a +ff40a66d7009d69d8927fafe89532b598179ecbac55973d7b72d0bd3c85689b8 +3013607e8fea9e226b12a9330a85d05f6110a92ff0a835afce485e902bfa56a0 +3af34176360af2fef394b8ffba51698af944ef3a44d44e92f54ddecf528d482e +a53590c831ef88164cb7d8fc2e5e8e4920fa1a506c7ce81b12af0372d3535146 +002478453347223e4b80dfde5b5b3e70adc559adb7d724479c6238566ba69664 +6d07ba1c2651a900a8b4f457ba9123ca2b5ea25b2c07b20ebc49325a159d92c4 +974c1c3bb967a7f9407eb15600a7db5bf81172152ca4ec23d04c52547f952f31 +b396c2eea6df1031f031dbcfbaf8b27cda00faecf247c7c9ba025fe1362b5b7f +b53cbb895bb097733102c1861a8777d79ca9239f88591734b22e46c8475ff442 +b35056858ef7d66e109ea532efd956ff0f93c8e9e5584426dcece4bd1464ac90 +834f0b3c04cf173173bfcd68f25dfea9bfe0e87cc7f96cbf75344740409d591d +57b8130aa9539a59473264f417ceea634866e3f91c4b1e2b67dff348745e104a +f8f1594f3c6867a20082a9fdbfa76cf40eb7a2e9e76b0e02c82551055a1b117e +44f59799bf745182eb8c0e524801412e1248f3709c474514a917a05c39374205 +ae5c06de2aee59b09812374313a280247972851876243ea43f39f58a82a7703a +ba22caff723dcd837bc1f6201dca2677ad4f77f213d272802ecf4bc569b0e2f1 +a259babba660e0f577f44d26a4ec966a11a62e61a7bd69d4c37e908abde10385 +85f25a41fdc14fff4a96828a5e823f9ac7328336fb680bec516e23297db22602 +bf6255452c4edd0afa2f5274733714c4cafee5f88f8e919b093d121a9ab3c920 +b4400c0dea93483e84f8d3157ca2a1b6fa7d21ff60176a7f102d427614861e9a +6ea70bc7abb5171fc2dac7a8f0a0b63a1ba10c801b9465c1de6143c4e4a83f7b +4edc0ce43b85695088a34a07a25685a3adc56faa515884d4650b97745286bd1b +737016875be9619de6cf6521bdce1d1a7e9bfca9829221b8adf3355f2206dcbc +40f6c466e0366c24985e6f449af4825e80179cc49ec7f77e234a36c0bf24e022 +29c897d952003d97880b0cf5d1dc27e4e336d1ea0c2b40ea881f4e340d72ed26 +9cd5650657491b955d66c3048850659be70844f87ccf248b1be30007d9603c87 +1b0820a5898fddfc8da255a9711c7f20ed8e840694043916b5fffbbc86a44d50 +bd0799a588cd6329e7e78d28c7cb827a6dcfefdc1dbd7f04abd2a6359d0367d5 +2be889e7b69765e13aecd529542a3816619b4579f320c5e3f00a5c406f73841b +5502aa0e5a162e5941db6653a298c96482d6295c715d095f46213c037322f75b +f81804c91fcd000a1138e328c252c4ff37bf02b5d97b4b93f23c4baf3a017b7e +6e52ca4b4385bb1b51fe3e28e66b2501bf1ac5ce4688b8a6977ee5bd5e35285d +f275612c3df8023287b06846824170d9a5bd85e149d6767b6d6fa3f6422491e6 +d8202d11390f89eca637059572b67933a6418802eb0c4e5b4ae77e36e309ab10 +79f005a323ac5d9173d535f62eb66c8439d92e85410d7ef700ebecaf094747fb +f9c59a9598fbfa9b43a4456f88ba8ae9791f082d420845b00e9dc28fc986bf78 +e16422d5ef3afa67ac5d125243dcd3e157253b8eef203e17b3da15ee670c0554 +6c7f82189df7906dc0a12a771d2cb7ab8f55b7419c263c424a430fe98ffb72b0 +460af1d4342f511d91d634ff4ba62dad705f39b6e89396d3e7e153b04fc669f1 + diff --git a/iguana/tests/LPinit b/iguana/tests/LPinit new file mode 100755 index 000000000..1905ec149 --- /dev/null +++ b/iguana/tests/LPinit @@ -0,0 +1,5 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"3809853923098test\",\"timeout\":86444}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"amlp\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"KMD\",\"vals\":{\"ask\":0.000077,\"bid\":0.000067,\"maxvol\":400,\"minvol\":100}}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MVP\",\"vals\":{\"rel\":\"USD\",\"bid\":0.09,\"ask\":0.11,\"maxvol\":100}}" diff --git a/iguana/tests/LPinit0 b/iguana/tests/LPinit0 new file mode 100755 index 000000000..513f39a9a --- /dev/null +++ b/iguana/tests/LPinit0 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTCD\",\"vals\":{\"profit\":0.01}}" diff --git a/iguana/tests/PAX b/iguana/tests/PAX index f4d6950e8..01f66b80b 100755 --- a/iguana/tests/PAX +++ b/iguana/tests/PAX @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"pax\",\"method\":\"start\"}" diff --git a/iguana/tests/PoS b/iguana/tests/PoS index f3ee99728..8e1ab12dc 100755 --- a/iguana/tests/PoS +++ b/iguana/tests/PoS @@ -1,3 +1,4 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1192000}" curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1192500}" curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1193000}" diff --git a/iguana/tests/REVS.batch0.importaddress b/iguana/tests/REVS.batch0.importaddress new file mode 100755 index 000000000..cbe74c6ee --- /dev/null +++ b/iguana/tests/REVS.batch0.importaddress @@ -0,0 +1,323 @@ +# RG1QE6hTqu4dadL2XSNWS9VCHjd8xNVo58 KMD 16462.32091533, REVS 289.86606506 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG1QE6hTqu4dadL2XSNWS9VCHjd8xNVo58\",\"symbol\":\"REVS\"}" # 289.86606506 +sleep 3 +# RFVvyUAnQe5yon6wq7B73Z1BzfFeZKyAZA KMD 74417.52897713, REVS 500.77700000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFVvyUAnQe5yon6wq7B73Z1BzfFeZKyAZA\",\"symbol\":\"REVS\"}" # 500.77700000 +sleep 3 +# RWfaj9ZNmHq5A4jV411xpt1FJoyvKfVJ6c KMD 616895.10028203, REVS 3685.61452692 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWfaj9ZNmHq5A4jV411xpt1FJoyvKfVJ6c\",\"symbol\":\"REVS\"}" # 3685.61452692 +sleep 3 +# R9dTcQWVDuaRdFqDzq4xPaFDjGbaLK6t8n KMD 1053.37494565, REVS 4.29070721 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9dTcQWVDuaRdFqDzq4xPaFDjGbaLK6t8n\",\"symbol\":\"REVS\"}" # 4.29070721 +sleep 3 +# REvJWEuwqmwTnanZ8bWt85wnjfrsAjnvgE KMD 3945.67461320, REVS 30.24757576 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REvJWEuwqmwTnanZ8bWt85wnjfrsAjnvgE\",\"symbol\":\"REVS\"}" # 30.24757576 +sleep 3 +# RBpEnyzuQNj1hNdAG1pKLALpAWEUS67PBj KMD 2729058.03025689, REVS 54178.00103054 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBpEnyzuQNj1hNdAG1pKLALpAWEUS67PBj\",\"symbol\":\"REVS\"}" # 54178.00103054 +sleep 3 +# RHSZ1CWDNhkNbbQRDrqLHRAdCshueMrt2r KMD 8661.80183095, REVS 171.90929822 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHSZ1CWDNhkNbbQRDrqLHRAdCshueMrt2r\",\"symbol\":\"REVS\"}" # 171.90929822 +sleep 3 +# RTqh7gEJMJDpnBp62FZZAfXctj8X7sRRia KMD 18367.01200788, REVS 350.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTqh7gEJMJDpnBp62FZZAfXctj8X7sRRia\",\"symbol\":\"REVS\"}" # 350.00000000 +sleep 3 +# RNhyF9U3o4hTgWqnwQjHwrD1o4GqWiP1T6 KMD 7816.63087181, REVS 78.63808960 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNhyF9U3o4hTgWqnwQjHwrD1o4GqWiP1T6\",\"symbol\":\"REVS\"}" # 78.63808960 +sleep 3 +# RE3yR2mCeG15ARgvENMbb573VqoQJcM3po KMD 17738.87416605, REVS 18.61556549 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE3yR2mCeG15ARgvENMbb573VqoQJcM3po\",\"symbol\":\"REVS\"}" # 18.61556549 +sleep 3 +# RT7ENMvL46nwrFfNj1TLa5FEqJzTztHefH KMD 26696.69308472, REVS 529.99000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT7ENMvL46nwrFfNj1TLa5FEqJzTztHefH\",\"symbol\":\"REVS\"}" # 529.99000000 +sleep 3 +# RDTcqgh4MMHLtu9FBCcULqZmP761DFmk9b KMD 82906.87674571, REVS 1438.93600000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDTcqgh4MMHLtu9FBCcULqZmP761DFmk9b\",\"symbol\":\"REVS\"}" # 1438.93600000 +sleep 3 +# RHSUmLRyJwpbdsRtytkGs9GmpZghQWHje3 KMD 2197.34858012, REVS 43.61040113 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHSUmLRyJwpbdsRtytkGs9GmpZghQWHje3\",\"symbol\":\"REVS\"}" # 43.61040113 +sleep 3 +# RJEQbNrMQUHELrYPVLPepR2Y3ruAag3hEP KMD 64966.39751162, REVS 1035.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJEQbNrMQUHELrYPVLPepR2Y3ruAag3hEP\",\"symbol\":\"REVS\"}" # 1035.00000000 +sleep 3 +# RJ1DUUySYib5LcwJKFJ78PD3so2GQ89jKJ KMD 377892.70160675, REVS 7501.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ1DUUySYib5LcwJKFJ78PD3so2GQ89jKJ\",\"symbol\":\"REVS\"}" # 7501.00000000 +sleep 3 +# RC2nLGhFUc5Q9QFG1b38gAi9WgSgzQ9hJR KMD 41.38832712, REVS 0.82090537 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC2nLGhFUc5Q9QFG1b38gAi9WgSgzQ9hJR\",\"symbol\":\"REVS\"}" # 0.82090537 +sleep 3 +# RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8 KMD 1350076.86672091, REVS 100.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCJHEogA7SW6PxuctPLtaVnXwiu49PyZY8\",\"symbol\":\"REVS\"}" # 100.00000000 +sleep 3 +# RJbudEMb7wEEN8QZ18fEkptxjE4QnMECUu KMD 50567.04202258, REVS 1003.32000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJbudEMb7wEEN8QZ18fEkptxjE4QnMECUu\",\"symbol\":\"REVS\"}" # 1003.32000000 +sleep 3 +# RSdVypRznJsboL6MaP1shkaLhrVFcNx2KL KMD 589187.66272894, REVS 11685.49743445 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSdVypRznJsboL6MaP1shkaLhrVFcNx2KL\",\"symbol\":\"REVS\"}" # 11685.49743445 +sleep 3 +# RWXwZyGf4q7cBakkY4tgupptBbCSvcBsBH KMD 1012.75625347, REVS 20.10000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWXwZyGf4q7cBakkY4tgupptBbCSvcBsBH\",\"symbol\":\"REVS\"}" # 20.10000000 +sleep 3 +# RA7UJPwPxqgPHn4YscYWRH5EPQVaFaaaPa KMD 45132.81116316, REVS 342.26137428 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA7UJPwPxqgPHn4YscYWRH5EPQVaFaaaPa\",\"symbol\":\"REVS\"}" # 342.26137428 +sleep 3 +# RRFFxsc6kkfahR7v4paTaUZrPFisuz9Nkq KMD 155.36852443, REVS 3.08314987 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRFFxsc6kkfahR7v4paTaUZrPFisuz9Nkq\",\"symbol\":\"REVS\"}" # 3.08314987 +sleep 3 +# RWFSbi9ECuZWVE37jpkbiKGw7DaFYdNtts KMD 23963.90703474, REVS 475.60756080 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWFSbi9ECuZWVE37jpkbiKGw7DaFYdNtts\",\"symbol\":\"REVS\"}" # 475.60756080 +sleep 3 +# RUVkn1F9g7TxoPbYtegiQoFnPTusP2gzDr KMD 43088.75849296, REVS 470.88002226 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUVkn1F9g7TxoPbYtegiQoFnPTusP2gzDr\",\"symbol\":\"REVS\"}" # 470.88002226 +sleep 3 +# R9vBYQw9tSBhu2c1g4SQhZdhuZeeQrEBoN KMD 111664.10821907, REVS 2023.42268720 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9vBYQw9tSBhu2c1g4SQhZdhuZeeQrEBoN\",\"symbol\":\"REVS\"}" # 2023.42268720 +sleep 3 +# RG8g7LjK7hdyKp3aoKBRdwzpLy31XMXMLk KMD 972.80557592, REVS 19.29916914 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG8g7LjK7hdyKp3aoKBRdwzpLy31XMXMLk\",\"symbol\":\"REVS\"}" # 19.29916914 +sleep 3 +# RJ7RfZfip4qL9uEJs7Wr9FYtGusQiryMqE KMD 43251.49599262, REVS 857.93461385 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ7RfZfip4qL9uEJs7Wr9FYtGusQiryMqE\",\"symbol\":\"REVS\"}" # 857.93461385 +sleep 3 +# RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY KMD 53585.08128315, REVS 731.01000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY\",\"symbol\":\"REVS\"}" # 731.01000000 +sleep 3 +# RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3 KMD 57862.44847739, REVS 464.78017965 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1NYFqFG2vmhhHVY7QFC7sTp7zBxvSSP3\",\"symbol\":\"REVS\"}" # 464.78017965 +sleep 3 +# RTkvmxME9rVZBY6ABNqkkbqKvn8WUqgQqr KMD 215743.93040290, REVS 4280.65926868 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTkvmxME9rVZBY6ABNqkkbqKvn8WUqgQqr\",\"symbol\":\"REVS\"}" # 4280.65926868 +sleep 3 +# RS9erX84xJG17efdZ66qHxhsUMG15fnCsH KMD 977546.42205511, REVS 19403.85638743 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS9erX84xJG17efdZ66qHxhsUMG15fnCsH\",\"symbol\":\"REVS\"}" # 19403.85638743 +sleep 3 +# RE1wsrDNwW2NnNWM5eE162yp6haLtm5uh7 KMD 14588.33036215, REVS 289.61149547 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1wsrDNwW2NnNWM5eE162yp6haLtm5uh7\",\"symbol\":\"REVS\"}" # 289.61149547 +sleep 3 +# RK5BnRzCP52qsTE4xR3Qysn6m6KeTgpZA6 KMD 3170.70655908, REVS 37.96790925 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK5BnRzCP52qsTE4xR3Qysn6m6KeTgpZA6\",\"symbol\":\"REVS\"}" # 37.96790925 +sleep 3 +# RN6TfTEYHdvFAeosYrvDaMBb2yBco47Q5a KMD 7073.16782615, REVS 44.30216197 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN6TfTEYHdvFAeosYrvDaMBb2yBco47Q5a\",\"symbol\":\"REVS\"}" # 44.30216197 +sleep 3 +# RV4Hf22arBv4P4s5eFsUAnXC6N11T8x9tv KMD 117108.97863641, REVS 1631.49836519 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV4Hf22arBv4P4s5eFsUAnXC6N11T8x9tv\",\"symbol\":\"REVS\"}" # 1631.49836519 +sleep 3 +# RYBH6Ha8RJa3CcE91yxJP6z2E6mDFm3bBt KMD 163386.58575808, REVS 50.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYBH6Ha8RJa3CcE91yxJP6z2E6mDFm3bBt\",\"symbol\":\"REVS\"}" # 50.00000000 +sleep 3 +# RUY7YW1WmTD3hCvkXmUKLeRnNg5UsJoLbU KMD 6742.29255596, REVS 105.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUY7YW1WmTD3hCvkXmUKLeRnNg5UsJoLbU\",\"symbol\":\"REVS\"}" # 105.00000000 +sleep 3 +# RNVwzuZynZ7d4DE5CfT8CWkxsp9TtCY3BF KMD 1598.36899361, REVS 11.75449303 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNVwzuZynZ7d4DE5CfT8CWkxsp9TtCY3BF\",\"symbol\":\"REVS\"}" # 11.75449303 +sleep 3 +# RPriQZfzzgin7y2Ns6vxdrMAa4XgZqdY6y KMD 21671.70738465, REVS 170.69524117 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPriQZfzzgin7y2Ns6vxdrMAa4XgZqdY6y\",\"symbol\":\"REVS\"}" # 170.69524117 +sleep 3 +# RSCdeeWvzpBhg2tKnCWZWKw9iAMyYWiREG KMD 12075.12037906, REVS 239.62000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSCdeeWvzpBhg2tKnCWZWKw9iAMyYWiREG\",\"symbol\":\"REVS\"}" # 239.62000000 +sleep 3 +# RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj KMD 25710.06172178, REVS 510.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUAvb7FFPvxjNTVhABeS2EbbdUi2LfGNMj\",\"symbol\":\"REVS\"}" # 510.00000000 +sleep 3 +# RQuMEMn1TG7CCpbmYCVcDfPqesEvEkisjC KMD 34758.47429765, REVS 689.94006658 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQuMEMn1TG7CCpbmYCVcDfPqesEvEkisjC\",\"symbol\":\"REVS\"}" # 689.94006658 +sleep 3 +# RBNB5mKstG86jYRjrKFgJuFoUFvZKJb9Wq KMD 816561.67159376, REVS 16199.49755302 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBNB5mKstG86jYRjrKFgJuFoUFvZKJb9Wq\",\"symbol\":\"REVS\"}" # 16199.49755302 +sleep 3 +# RHoouCBBapEHE6uyX7CxHGFcRwUQFGMot5 KMD 88331.27512150, REVS 1398.88449696 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHoouCBBapEHE6uyX7CxHGFcRwUQFGMot5\",\"symbol\":\"REVS\"}" # 1398.88449696 +sleep 3 +# RLHEGDwXuXQwhYkrhwSRGSJMFuvv7EAT7i KMD 22366.16022678, REVS 443.95821128 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLHEGDwXuXQwhYkrhwSRGSJMFuvv7EAT7i\",\"symbol\":\"REVS\"}" # 443.95821128 +sleep 3 +# RAEtFUqe3jwVxLywCga2eKQxT2DiewsUuN KMD 25.54297774, REVS 0.50680815 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAEtFUqe3jwVxLywCga2eKQxT2DiewsUuN\",\"symbol\":\"REVS\"}" # 0.50680815 +sleep 3 +# RUcDMtu7fA3ATbHHsDTsZ8KThgd1ivawym KMD 21446.21749875, REVS 241.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUcDMtu7fA3ATbHHsDTsZ8KThgd1ivawym\",\"symbol\":\"REVS\"}" # 241.00000000 +sleep 3 +# RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4 KMD 102137.83664315, REVS 2027.11216000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG2cAef3JbCXiQkzPgrqS52HAQrBzJiAy4\",\"symbol\":\"REVS\"}" # 2027.11216000 +sleep 3 +# REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf KMD 130928.69826981, REVS 2597.54928401 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REzcqBkARMCCxkA5rVdp61f7rovmFtq5kf\",\"symbol\":\"REVS\"}" # 2597.54928401 +sleep 3 +# RXKZmFmmpfAV2DAdUUXhA88RqCoyPRXcnA KMD 28641.72782430, REVS 337.66808110 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXKZmFmmpfAV2DAdUUXhA88RqCoyPRXcnA\",\"symbol\":\"REVS\"}" # 337.66808110 +sleep 3 +# RCxnQhmYdpK9vTS7PLRtXBtDk2HaRNo1qk KMD 2171.04073365, REVS 43.05910000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCxnQhmYdpK9vTS7PLRtXBtDk2HaRNo1qk\",\"symbol\":\"REVS\"}" # 43.05910000 +sleep 3 +# RPtwW4UejbAxs5PU6a1zMPcPqW7SVghMDS KMD 31741.86724191, REVS 514.45537037 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPtwW4UejbAxs5PU6a1zMPcPqW7SVghMDS\",\"symbol\":\"REVS\"}" # 514.45537037 +sleep 3 +# RYMzZx5nxKrMtTm3TNeheVn4RooTGvhsNd KMD 12756.16332851, REVS 253.10000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYMzZx5nxKrMtTm3TNeheVn4RooTGvhsNd\",\"symbol\":\"REVS\"}" # 253.10000000 +sleep 3 +# RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz KMD 3422.63549310, REVS 51.90683618 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPyKbtBPVb3FYv5iFULNUB6bq9DdvekZuz\",\"symbol\":\"REVS\"}" # 51.90683618 +sleep 3 +# RVcGdBT2N6Fbqbptj3R4zhZYNB4WJQWEns KMD 77986.19708921, REVS 1548.20316000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVcGdBT2N6Fbqbptj3R4zhZYNB4WJQWEns\",\"symbol\":\"REVS\"}" # 1548.20316000 +sleep 3 +# RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf KMD 11621.99031627, REVS 192.14192021 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH4SXj2zZqfG4TfejyHcVpaoPoDv1Uonnf\",\"symbol\":\"REVS\"}" # 192.14192021 +sleep 3 +# REtq1LtbLVo6bz68f9TGFduNmUTKqG7vnH KMD 25088.84725730, REVS 305.62849999 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REtq1LtbLVo6bz68f9TGFduNmUTKqG7vnH\",\"symbol\":\"REVS\"}" # 305.62849999 +sleep 3 +# RS3rMPEGouBWbHKStyQg8TxVmtwFQ6ebh3 KMD 3546.25060143, REVS 39.99000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS3rMPEGouBWbHKStyQg8TxVmtwFQ6ebh3\",\"symbol\":\"REVS\"}" # 39.99000000 +sleep 3 +# RGzvr4JSHDLDQAGBwdyoUiUuaYn5sUwKNd KMD 69108.92543895, REVS 314.51750000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGzvr4JSHDLDQAGBwdyoUiUuaYn5sUwKNd\",\"symbol\":\"REVS\"}" # 314.51750000 +sleep 3 +# RMD1wVnzMmKn8uMTHaP9pYfCWkxf3QVWWE KMD 2931.50081538, REVS 40.37145505 +sleep 3 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMD1wVnzMmKn8uMTHaP9pYfCWkxf3QVWWE\",\"symbol\":\"REVS\"}" # 40.37145505 +# RQCEEEprmqghZHN73iG1C2XvYTTQ6FB2wE KMD 5506.18026103, REVS 90.00054364 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQCEEEprmqghZHN73iG1C2XvYTTQ6FB2wE\",\"symbol\":\"REVS\"}" # 90.00054364 +sleep 3 +# RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx KMD 529.41438680, REVS 10.50000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCmLc2JBpPw9T9g1skg7J5Xr5kz1fyd7mx\",\"symbol\":\"REVS\"}" # 10.50000000 +sleep 3 +# R9ULUWEvzmHPZ4rYL5FtwkMyTWvGDZX43J KMD 15051.18125683, REVS 298.60000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9ULUWEvzmHPZ4rYL5FtwkMyTWvGDZX43J\",\"symbol\":\"REVS\"}" # 298.60000000 +sleep 3 +# RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb KMD 166779.58408020, REVS 3310.49966000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW2xS8dpxjudqBX1hqxShP7FWn8EHYH4Rb\",\"symbol\":\"REVS\"}" # 3310.49966000 +sleep 3 +# RALRwXaEN3yS5damdDwAkmEMKvdAkVs361 KMD 25746.96382302, REVS 510.64558668 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RALRwXaEN3yS5damdDwAkmEMKvdAkVs361\",\"symbol\":\"REVS\"}" # 510.64558668 +sleep 3 +# RPVNUvVq4BgKrrB3E1uULja2hjPW6Hv6r9 KMD 16872.68860925, REVS 334.64000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPVNUvVq4BgKrrB3E1uULja2hjPW6Hv6r9\",\"symbol\":\"REVS\"}" # 334.64000000 +sleep 3 +# RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A KMD 19616.45270312, REVS 389.05771834 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWTfFTP7c9WxLhgxd2EXSsKszpDVPXHN8A\",\"symbol\":\"REVS\"}" # 389.05771834 +sleep 3 +# RXFr5VB9gQYC5QYv7yVvkxtjDY3zwYuvDx KMD 327.74801651, REVS 6.50475878 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXFr5VB9gQYC5QYv7yVvkxtjDY3zwYuvDx\",\"symbol\":\"REVS\"}" # 6.50475878 +sleep 3 +# RHUpvFhHv1umX1JsV5S8smAKAsN5CxA4HD KMD 2183.96436714, REVS 2.36599993 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHUpvFhHv1umX1JsV5S8smAKAsN5CxA4HD\",\"symbol\":\"REVS\"}" # 2.36599993 +sleep 3 +# RAhvJHePdAb1PF9jjZhP2F7r72ebL9pA1f KMD 3457.02047726, REVS 68.56389987 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAhvJHePdAb1PF9jjZhP2F7r72ebL9pA1f\",\"symbol\":\"REVS\"}" # 68.56389987 +sleep 3 +# RDCjGgoZ1tvCWop6m5wPYkr83wdFrofF6M KMD 76598.36955552, REVS 1519.19347187 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDCjGgoZ1tvCWop6m5wPYkr83wdFrofF6M\",\"symbol\":\"REVS\"}" # 1519.19347187 +sleep 3 +# RLAEm3H2LMSNzJmveLkcf2nS18AnqWR7pJ KMD 82831.36892196, REVS 1643.94000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLAEm3H2LMSNzJmveLkcf2nS18AnqWR7pJ\",\"symbol\":\"REVS\"}" # 1643.94000000 +sleep 3 +# RSUfnwTLE36E3Nx8PptxVoAfSRtMeGQsFL KMD 67327.03192299, REVS 1282.48928243 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSUfnwTLE36E3Nx8PptxVoAfSRtMeGQsFL\",\"symbol\":\"REVS\"}" # 1282.48928243 +sleep 3 +# RPkkQmMmyLQe8Th7ZP5GoF6kSUs1DTNfAf KMD 1538.42929417, REVS 30.51202988 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPkkQmMmyLQe8Th7ZP5GoF6kSUs1DTNfAf\",\"symbol\":\"REVS\"}" # 30.51202988 +sleep 3 +# RSkhXmiPCxqdp4bM4ux7VxAwMoCv2Uar6d KMD 73542.70261753, REVS 1459.56877203 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSkhXmiPCxqdp4bM4ux7VxAwMoCv2Uar6d\",\"symbol\":\"REVS\"}" # 1459.56877203 +sleep 3 +# RUJvR3TXCAcizk7dXdFc6GKRFS6jZfjtyY KMD 10419.10088055, REVS 206.75776925 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUJvR3TXCAcizk7dXdFc6GKRFS6jZfjtyY\",\"symbol\":\"REVS\"}" # 206.75776925 +sleep 3 +# RLZmhbeB2tXTas9grzAeqaL2RFAXVmDVpU KMD 43480.56469698, REVS 50.30001915 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLZmhbeB2tXTas9grzAeqaL2RFAXVmDVpU\",\"symbol\":\"REVS\"}" # 50.30001915 +sleep 3 +# RLCDEXwfJ75P1iKgWGfR9geJmjZ84A4XXJ KMD 105141.23597043, REVS 1006.07261743 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLCDEXwfJ75P1iKgWGfR9geJmjZ84A4XXJ\",\"symbol\":\"REVS\"}" # 1006.07261743 +sleep 3 +# RW1FmQGcpPv87WZVSCaMgjj74shMb3Y6Zi KMD 33700.59190315, REVS 380.47576230 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW1FmQGcpPv87WZVSCaMgjj74shMb3Y6Zi\",\"symbol\":\"REVS\"}" # 380.47576230 +sleep 3 +# RQUMrGYr4SsHgbN56WP7tuEpWUcd62KidP KMD 61230.10078656, REVS 600.00100000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQUMrGYr4SsHgbN56WP7tuEpWUcd62KidP\",\"symbol\":\"REVS\"}" # 600.00100000 +sleep 3 +# RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt KMD 153725.02014837, REVS 3049.70000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP8CkGhyfhdoVpGqGbVmEmRL7gGdqKBdkt\",\"symbol\":\"REVS\"}" # 3049.70000000 +sleep 3 +# RRupn47XfLSMhXEuShtCCPBCv8P6LYXrLN KMD 790607.74140148, REVS 15691.16324116 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRupn47XfLSMhXEuShtCCPBCv8P6LYXrLN\",\"symbol\":\"REVS\"}" # 15691.16324116 +sleep 3 +# RRX73tynW4sxCmqyYBQrS9nMcDUcXuX1yG KMD 26022.54788263, REVS 5.39446042 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRX73tynW4sxCmqyYBQrS9nMcDUcXuX1yG\",\"symbol\":\"REVS\"}" # 5.39446042 +sleep 3 +# R9u7V63TLwJPH1shvAGHRG61aci61yy7RN KMD 20764.40163902, REVS 291.83028199 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9u7V63TLwJPH1shvAGHRG61aci61yy7RN\",\"symbol\":\"REVS\"}" # 291.83028199 +sleep 3 +# RKAxvqvC3apzrb8udG9trBxiNhhNXaLkz4 KMD 6483.53169406, REVS 5.41696484 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKAxvqvC3apzrb8udG9trBxiNhhNXaLkz4\",\"symbol\":\"REVS\"}" # 5.41696484 +sleep 3 +# RV5cgPjqt37QBHr94VL5HnXWqcwdqoqoC3 KMD 81008.20903630, REVS 1607.10337790 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV5cgPjqt37QBHr94VL5HnXWqcwdqoqoC3\",\"symbol\":\"REVS\"}" # 1607.10337790 +sleep 3 +# RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v KMD 14010.00244099, REVS 277.86367220 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMnuGgpEzWcxYi861E7BjGMURCFX2Szj2v\",\"symbol\":\"REVS\"}" # 277.86367220 +sleep 3 +# RF4iG6huXb9u6Pt8281WvnBjhdEtiVUnp4 KMD 674.21697725, REVS 13.37190382 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF4iG6huXb9u6Pt8281WvnBjhdEtiVUnp4\",\"symbol\":\"REVS\"}" # 13.37190382 +sleep 3 +# RW3gz9fEadohRLZerK9r8zXkugk5swWHrf KMD 21219.62483892, REVS 421.20000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW3gz9fEadohRLZerK9r8zXkugk5swWHrf\",\"symbol\":\"REVS\"}" # 421.20000000 +sleep 3 +# RJ89radoRzRr5oDsf71QZ7BXUTiHcyVSUu KMD 52588.80320859, REVS 1043.00609779 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ89radoRzRr5oDsf71QZ7BXUTiHcyVSUu\",\"symbol\":\"REVS\"}" # 1043.00609779 +sleep 3 +# RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4 KMD 668547.16129881, REVS 13259.45302721 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKenAzKZyD58qPu2zVdjwPjDn71T34sWE4\",\"symbol\":\"REVS\"}" # 13259.45302721 +sleep 3 +# R9ibGGfsFHD8MxLRL4q2a6ezxAaHHPJvLc KMD 241619.45649268, REVS 4792.09548598 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9ibGGfsFHD8MxLRL4q2a6ezxAaHHPJvLc\",\"symbol\":\"REVS\"}" # 4792.09548598 +sleep 3 +# RGwuMmW1ZBMrHJwJucEy5JEV3BZWv7eQnm KMD 9071868.91817425, REVS 180010.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGwuMmW1ZBMrHJwJucEy5JEV3BZWv7eQnm\",\"symbol\":\"REVS\"}" # 180010.00000000 +sleep 3 +# RT6Ckpw8yM2Q7yaCxejiVTrxELGQPtnGPm KMD 25778.27244764, REVS 225.87592741 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT6Ckpw8yM2Q7yaCxejiVTrxELGQPtnGPm\",\"symbol\":\"REVS\"}" # 225.87592741 +sleep 3 +# RGf4wwbHVYYZrVPVZg6XdS3mWvbzHSebzu KMD 6387.59296405, REVS 126.73871740 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGf4wwbHVYYZrVPVZg6XdS3mWvbzHSebzu\",\"symbol\":\"REVS\"}" # 126.73871740 +sleep 3 +# RJAbNiCSRaMxUky9h8as6orZY3cu2rSW8z KMD 492782.94486222, REVS 9773.48000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJAbNiCSRaMxUky9h8as6orZY3cu2rSW8z\",\"symbol\":\"REVS\"}" # 9773.48000000 +sleep 3 +# RSW5SvtjWiGYN3iwb2mteYP7Hn223Zk1tP KMD 343847.33707184, REVS 6001.47957339 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSW5SvtjWiGYN3iwb2mteYP7Hn223Zk1tP\",\"symbol\":\"REVS\"}" # 6001.47957339 +sleep 3 +# RFPKxBL8iLQGmkoUukXdFU7VkXyGJLSsGw KMD 36335.50253541, REVS 413.60001059 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFPKxBL8iLQGmkoUukXdFU7VkXyGJLSsGw\",\"symbol\":\"REVS\"}" # 413.60001059 +sleep 3 +# RVFspAKoUpDMAiiEUiQQEpqdqXDMB48Jqp KMD 47464.51702590, REVS 634.55156126 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVFspAKoUpDMAiiEUiQQEpqdqXDMB48Jqp\",\"symbol\":\"REVS\"}" # 634.55156126 +sleep 3 +# RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1 KMD 36359.70475507, REVS 100.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCPys8hvEfFSDkMZL7GtYA8a5GSwih67Q1\",\"symbol\":\"REVS\"}" # 100.00000000 +sleep 3 +# R9ce1xHEaWnRRP5jrWozEfPf9ZJgX7jnxd KMD 915808.36366861, REVS 18163.44258555 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9ce1xHEaWnRRP5jrWozEfPf9ZJgX7jnxd\",\"symbol\":\"REVS\"}" # 18163.44258555 +sleep 3 +# RS1rdGqAhXvwFFTVyUCx695y84E3N3emcU KMD 18822.21903353, REVS 360.77089072 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS1rdGqAhXvwFFTVyUCx695y84E3N3emcU\",\"symbol\":\"REVS\"}" # 360.77089072 +sleep 3 +# RLgKsmgdzwNCt8CgqZ5J6cZhTat9HeZgxG KMD 62376.97840244, REVS 1045.22605497 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLgKsmgdzwNCt8CgqZ5J6cZhTat9HeZgxG\",\"symbol\":\"REVS\"}" # 1045.22605497 +sleep 3 +# RUBESyzjgZUts3fD6W7abpgMj4qRFSSszC KMD 541390.42407502, REVS 10592.65522652 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUBESyzjgZUts3fD6W7abpgMj4qRFSSszC\",\"symbol\":\"REVS\"}" # 10592.65522652 +sleep 3 +# RSNu7Kd9p33aDrgT2AM8buy7fUSQZ2N3Gs KMD 130769.80646849, REVS 2593.58831601 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSNu7Kd9p33aDrgT2AM8buy7fUSQZ2N3Gs\",\"symbol\":\"REVS\"}" # 2593.58831601 +sleep 3 +# RCrCe4dsMzXzzp7GLahubjg73VGK2rnczC KMD 6843.04832293, REVS 25.10000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCrCe4dsMzXzzp7GLahubjg73VGK2rnczC\",\"symbol\":\"REVS\"}" # 25.10000000 +sleep 3 +# RVTCRzofA2cV6FwGcvn1uGjZJmP5s9G1o9 KMD 95283.12042643, REVS 497.50723875 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVTCRzofA2cV6FwGcvn1uGjZJmP5s9G1o9\",\"symbol\":\"REVS\"}" # 497.50723875 +sleep 3 +sleep 3 diff --git a/iguana/tests/REVS.batch1.importaddress b/iguana/tests/REVS.batch1.importaddress new file mode 100755 index 000000000..20993167a --- /dev/null +++ b/iguana/tests/REVS.batch1.importaddress @@ -0,0 +1,76 @@ +# RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4 KMD 205767.24475092, REVS 4084.38717211 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA4nyddYYzEzoUqnpLCvTm8d4nKvqQavs4\",\"symbol\":\"REVS\"}" # 4084.38717211 +sleep 3 +# RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx KMD 138163.01002402, REVS 2740.59474723 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFppcFo1bKQzD4zxrxCbicpAvnrqo99hPx\",\"symbol\":\"REVS\"}" # 2740.59474723 +sleep 3 +# RHfHV1LTG5rz3T2HApavCto9973puD93qt KMD 243998.92767004, REVS 4839.53600000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHfHV1LTG5rz3T2HApavCto9973puD93qt\",\"symbol\":\"REVS\"}" # 4839.53600000 +sleep 3 +# RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy KMD 36785.74330117, REVS 730.28056435 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPNRr6efhaPYKHzRyemxYowUbNQ6crBtcy\",\"symbol\":\"REVS\"}" # 730.28056435 +sleep 3 +# RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB KMD 567760.05597770, REVS 11191.99000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTnhkYHVoApyX8Fc2ZEHB2rtW7cLHqZEMB\",\"symbol\":\"REVS\"}" # 11191.99000000 +sleep 3 +# RER2vwRLHFT4HNQLzyqT1PhbeMCitDaY1u KMD 7771.42052436, REVS 0.62700000 +sleep 1 +# RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK KMD 18186.86986853, REVS 143.39272495 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM3onNDjZbjypoN8wqo7Rzz3QEv6EiCfwK\",\"symbol\":\"REVS\"}" # 143.39272495 +sleep 3 +# RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu KMD 2375.16051963, REVS 47.12337252 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVXTirtRaZkYk1wjAE3mwhdUjTXWKrTnFu\",\"symbol\":\"REVS\"}" # 47.12337252 +sleep 3 +# RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta KMD 70173.29001640, REVS 1392.33555151 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJJBtg8XfxMmb6rg6UMWME6zhxM1n8Umta\",\"symbol\":\"REVS\"}" # 1392.33555151 +sleep 3 +# REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8 KMD 220390.81840860, REVS 1384.18511377 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REbMisMicS8W7LUqBPJwkVfYHxNfSeW7d8\",\"symbol\":\"REVS\"}" # 1384.18511377 +sleep 3 +# RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ KMD 479029.87110523, REVS 9502.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRDmaG64XZjdERzojAQ3DwHewBZbXfqpcJ\",\"symbol\":\"REVS\"}" # 9502.00000000 +sleep 3 +# RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz KMD 230594.13977661, REVS 8.48502608 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTBeZc5Biq3BY1hB1dXi6XTaH8j6FsyGuz\",\"symbol\":\"REVS\"}" # 8.48502608 +sleep 3 +# RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv KMD 25505.74161232, REVS 506.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGbLr8CsszoGATo6uy7fZJ5GJPuXYbA6sv\",\"symbol\":\"REVS\"}" # 506.00000000 +sleep 3 +# RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5 KMD 4516.65527532, REVS 31.96541397 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP7HdvokCK1yJmpVCY49q4LXsVe3qhnEU5\",\"symbol\":\"REVS\"}" # 31.96541397 +sleep 3 +# RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH KMD 35011.78668474, REVS 310.59835083 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMvpp3QwvYch8hFCjZNXvXkzoFWEw9R5QH\",\"symbol\":\"REVS\"}" # 310.59835083 +sleep 3 +# R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks KMD 201.26853079, REVS 3.99180609 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9whNiPsV9NHvyPqg6ranxDFvsM8HsDtks\",\"symbol\":\"REVS\"}" # 3.99180609 +sleep 3 +# RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig KMD 663.13491046, REVS 13.16292943 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFfJkcC1fnFZB2G2MUPYdNEeRrZk6njPig\",\"symbol\":\"REVS\"}" # 13.16292943 +sleep 3 +# RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK KMD 29548.60287586, REVS 586.04438779 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV49vYgGa9kdzTQ5hq5ra88DkX4wwVdzmK\",\"symbol\":\"REVS\"}" # 586.04438779 +sleep 3 +# RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK KMD 100186.19238242, REVS 1944.84440292 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMYqPrPpgosrjcoS34WmBtG9KDRmE7WcXK\",\"symbol\":\"REVS\"}" # 1944.84440292 +sleep 3 +# RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq KMD 1853646.03638691, REVS 415.68775429 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH1Ug5jz6S5DbJyLENhMthMEAoSBbkXRMq\",\"symbol\":\"REVS\"}" # 415.68775429 +sleep 3 +# RFREgr9p32GanT4YcM25hMcPYkvRLDNkja KMD 151544.96672946, REVS 3005.62695376 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFREgr9p32GanT4YcM25hMcPYkvRLDNkja\",\"symbol\":\"REVS\"}" # 3005.62695376 +sleep 3 +# RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4 KMD 295382.69930466, REVS 5860.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFjddDTCuobaHatQtd7kTiSjYv94Mp9Cu4\",\"symbol\":\"REVS\"}" # 5860.00000000 +sleep 3 +# RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT KMD 59621.32507756, REVS 606.36817953 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVNWkGzsFG1ZhzKBzzUj7UPzHMu8s1JWfT\",\"symbol\":\"REVS\"}" # 606.36817953 +sleep 3 +# RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p KMD 23159.75532541, REVS 459.58469952 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGwu8hcD19TKuqzPbjdnzKmkMsUUrdsw5p\",\"symbol\":\"REVS\"}" # 459.58469952 +sleep 3 +# RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ KMD 77304.58455563, REVS 1533.20000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMwP7F2QRMprthjNwT7gHWjHvvqtefwRsJ\",\"symbol\":\"REVS\"}" # 1533.20000000 +sleep 3 + +# total KMD 0.00000000 REVS 51342.01215065 diff --git a/iguana/tests/REVS.batch10 b/iguana/tests/REVS.batch10 new file mode 100755 index 000000000..3f5a20e03 --- /dev/null +++ b/iguana/tests/REVS.batch10 @@ -0,0 +1,12 @@ +sleep 999999 +# RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm KMD 40223.19497203, REVS 101.00000000 +sleep 1 +fiat/revs sendtoaddress RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm 101.00000000 +# RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC KMD 137.73071692, REVS 2.73426759 +sleep 1 +fiat/revs sendtoaddress RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC 2.73426759 + +# total KMD 0.00000000 REVS 103.73426759 +64c45de19774850698051651ba5476b0de1f213520366d46459de0eccebdaad7 +17a5af91044e1461ca8fca70ddd900ae9e50acd7af59bf5af1a9c4cccb20b552 + diff --git a/iguana/tests/REVS.batch10.importaddress b/iguana/tests/REVS.batch10.importaddress new file mode 100755 index 000000000..f0e9b3536 --- /dev/null +++ b/iguana/tests/REVS.batch10.importaddress @@ -0,0 +1,6 @@ +# RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm KMD 40223.19497203, REVS 101.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF4jZsF5BUckQqX5hsS68kjQMYSba8Fypm\",\"symbol\":\"REVS\"}" # 101.00000000 +sleep 3 +# RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC KMD 137.73071692, REVS 2.73426759 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGQmMzmUfa6R5dZvvL5wvy2vxPLEcgkkyC\",\"symbol\":\"REVS\"}" # 2.73426759 +sleep 3 diff --git a/iguana/tests/REVS.batch11 b/iguana/tests/REVS.batch11 new file mode 100755 index 000000000..ae2682ab8 --- /dev/null +++ b/iguana/tests/REVS.batch11 @@ -0,0 +1,15 @@ +sleep 99999 +# RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc KMD 1904.65394401, REVS 37.80134078 +sleep 1 +fiat/revs sendtoaddress RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc 37.80134078 +# RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 KMD 863.61179282, REVS 0.91962079 +sleep 1 +fiat/revs sendtoaddress RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 0.91962079 +# RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr KMD 16087.76566759, REVS 319.20361833 +sleep 1 +fiat/revs sendtoaddress RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr 319.20361833 + +94940c0e2adc685722b2bf2525515cdab544afc0ad25af1c4cd2cfa5a06a28cd +e17395d17efa9254e06b566a2719c066ddba6c196f34892ec99bd987abc9dc89 +3142dd53cc5a76e6f41b43754e9506d02818571e8d5caed6384fad4f760dc49a + diff --git a/iguana/tests/REVS.batch11.importaddress b/iguana/tests/REVS.batch11.importaddress new file mode 100755 index 000000000..569017cbd --- /dev/null +++ b/iguana/tests/REVS.batch11.importaddress @@ -0,0 +1,8 @@ +# RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc KMD 1904.65394401, REVS 37.80134078 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBYMsuS89HQKxNCZB3xb1UxRyfLMLvrbmc\",\"symbol\":\"REVS\"}" # 37.80134078 +sleep 3 +# RCKVUKnC3pjVkjnDfnBj1Eu68yc8ELdMC5 KMD 863.61179282, REVS 0.91962079 +sleep 1 +# RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr KMD 16087.76566759, REVS 319.20361833 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUrV1qvjBapCDGQnwpdhyneGhX1wiHZwVr\",\"symbol\":\"REVS\"}" # 319.20361833 +sleep 3 diff --git a/iguana/tests/REVS.batch12 b/iguana/tests/REVS.batch12 new file mode 100755 index 000000000..78ad38586 --- /dev/null +++ b/iguana/tests/REVS.batch12 @@ -0,0 +1,14 @@ +# RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762, REVS 31.12033224 +sleep 1 +fiat/revs sendtoaddress RDTjem9CP97XPXvet1sQBb428xrmSZJSsd 31.12033224 +# RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290, REVS 139.09398517 +sleep 1 +fiat/revs sendtoaddress RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y 139.09398517 +# RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526, REVS 59.85500000 +sleep 1 +fiat/revs sendtoaddress RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 59.85500000 +# RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934, REVS 75.88015839 +sleep 1 +fiat/revs sendtoaddress RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX 75.88015839 + +# total KMD 0.00000000 REVS 305.94947580 diff --git a/iguana/tests/REVS.batch12.importaddress b/iguana/tests/REVS.batch12.importaddress new file mode 100755 index 000000000..53ae5be86 --- /dev/null +++ b/iguana/tests/REVS.batch12.importaddress @@ -0,0 +1,12 @@ +# RDTjem9CP97XPXvet1sQBb428xrmSZJSsd KMD 1568.45531762, REVS 31.12033224 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDTjem9CP97XPXvet1sQBb428xrmSZJSsd\",\"symbol\":\"REVS\"}" # 31.12033224 +sleep 3 +# RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y KMD 11852.83167290, REVS 139.09398517 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHmVdfQM3PbJayYGbYnGtsqiWD9gDt2n4y\",\"symbol\":\"REVS\"}" # 139.09398517 +sleep 3 +# RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8 KMD 3016.26045526, REVS 59.85500000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUbMmLRMeSf2xnBHspdzS2JC3e8epKmoM8\",\"symbol\":\"REVS\"}" # 59.85500000 +sleep 3 +# RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX KMD 3823.81289934, REVS 75.88015839 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXQBgNYtszvmdwniLu1nteS9MX1xD75bNX\",\"symbol\":\"REVS\"}" # 75.88015839 +sleep 3 diff --git a/iguana/tests/REVS.batch15 b/iguana/tests/REVS.batch15 new file mode 100755 index 000000000..3e64201d3 --- /dev/null +++ b/iguana/tests/REVS.batch15 @@ -0,0 +1,18 @@ +sleep 999999 +# RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ KMD 5844.47004626, REVS 115.97829823 +sleep 1 +fiat/revs sendtoaddress RQedHsGydzYsynBRiizK3LNBnRUkAMRafZ 115.97829823 +# REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa KMD 26142.50314066, REVS 20.00000000 +sleep 1 +fiat/revs sendtoaddress REmJva8Uc5Rhmyf4CSvVTWCkSQ5MAiXpXa 20.00000000 +# RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft KMD 1005.97291406, REVS 19.95990000 +sleep 1 +fiat/revs sendtoaddress RD592mTwrB5w4XF5RL5qVfVYCkGCuctGft 19.95990000 +# RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 KMD 125611.30316493, REVS 1564.97178647 +sleep 1 +fiat/revs sendtoaddress RB6Ua6YzhT1nra7vhZFa15NZ2uv8ahGET3 1564.97178647 +# RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk KMD 4535.36019149, REVS 90.00018012 +sleep 1 +fiat/revs sendtoaddress RTVFC7r5K3bedTrPbXLwh63g27PKzqHBDk 90.00018012 + +# total KMD 0.00000000 REVS 1810.91016482 diff --git a/iguana/tests/REVS.batch16 b/iguana/tests/REVS.batch16 new file mode 100755 index 000000000..cd1687ffb --- /dev/null +++ b/iguana/tests/REVS.batch16 @@ -0,0 +1,19 @@ +sleep 99999 +# RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV KMD 857.10994504, REVS 17.01091436 +sleep 1 +fiat/revs sendtoaddress RTqkW9K9Mumij6KmtVmyfjcDwiU8ncKdKV 17.01091436 +# REVcoi6A4GRfuchCXTwBTszbakhoh9inLs KMD 2288.11223404, REVS 45.41799774 +sleep 1 +fiat/revs sendtoaddress REVcoi6A4GRfuchCXTwBTszbakhoh9inLs 45.41799774 +# RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije KMD 13018.84319757, REVS 151.44412616 +sleep 1 +fiat/revs sendtoaddress RHSVnGZSp7fjqP2dRRNe3zmjf2CaWZTije 151.44412616 +# REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo KMD 9102.02231944, REVS 180.67104532 +sleep 1 +fiat/revs sendtoaddress REKBky3HVTcujcbGyfSD6r8V7FvVaBkbLo 180.67104532 + +1f5038508e4b13c7e9cfc89e2cd3ac187716b7c05506c1432c177757ac2b7b6a +ba117446a8ca5aed03668f6e896e4e993e90007caa5315795db040123a946089 +32f4cec5856b1a0cd0e6de4d1f340cb7f73b52c461cb540e1f6c3bb7b7024dc7 +556402cc20da2e4f162e9212534d8b66239851729b990366a26e5dfe7111ad58 + diff --git a/iguana/tests/REVS.batch17 b/iguana/tests/REVS.batch17 new file mode 100755 index 000000000..fee159901 --- /dev/null +++ b/iguana/tests/REVS.batch17 @@ -0,0 +1,5 @@ +# RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU KMD 35716.07599193, REVS 708.36533209 +sleep 100000 +fiat/revs sendtoaddress RXcy9GwSCmd5RRsZfuMxaa6GpHqetmrPGU 708.36533209 +2781e7d1a888c22083832e46241aca1cb512605cb4c5492c9a36cc7f2d7829f3 +# total KMD 0.00000000 REVS 708.36533209 diff --git a/iguana/tests/REVS.batch2.importaddress b/iguana/tests/REVS.batch2.importaddress new file mode 100755 index 000000000..5aa01def8 --- /dev/null +++ b/iguana/tests/REVS.batch2.importaddress @@ -0,0 +1,45 @@ +# RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU KMD 501.64865701, REVS 9.95750000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU18xoQZeK4Kno2ER7mv8ZEKLHiTECRhkU\",\"symbol\":\"REVS\"}" # 9.95750000 +sleep 3 +# RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf KMD 62103.45021354, REVS 50.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJxiu5FTx2Nqr9xHvwdq1xynExUjFKVPdf\",\"symbol\":\"REVS\"}" # 50.00000000 +sleep 3 +# RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71 KMD 12520.16564088, REVS 138.94305839 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB95bkGifi94Z4VSHGULKhCU8ML7tUbQ71\",\"symbol\":\"REVS\"}" # 138.94305839 +sleep 3 +# RKb5ay26iSzmBoqm51vPveyErH9BYG3dry KMD 3674.15911735, REVS 72.89043156 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKb5ay26iSzmBoqm51vPveyErH9BYG3dry\",\"symbol\":\"REVS\"}" # 72.89043156 +sleep 3 +# RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx KMD 612851.03780014, REVS 5433.13031755 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVeVZrr24524LhN3VRhLqNG6qgH9tBPixx\",\"symbol\":\"REVS\"}" # 5433.13031755 +sleep 3 +# RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp KMD 519232.27493854, REVS 10298.05578171 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFBxwyTKGy5DtxR5CLLZSjKL5jU6fm13kp\",\"symbol\":\"REVS\"}" # 10298.05578171 +sleep 3 +# RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i KMD 19106.59220646, REVS 374.39305755 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB1cuwtKBpwZPZnwyJeznaij53ovj8Dm8i\",\"symbol\":\"REVS\"}" # 374.39305755 +sleep 3 +# RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf KMD 1212.14061568, REVS 24.05385000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf\",\"symbol\":\"REVS\"}" # 24.05385000 +sleep 3 +# RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza KMD 10347.76210933, REVS 205.22959870 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDx4sokytAASudNuMDDdk4R6RHJ4P8aPza\",\"symbol\":\"REVS\"}" # 205.22959870 +sleep 3 +# RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr KMD 71712.83911390, REVS 500.67180183 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAPJuPCGMoPwfeHuckiea21LMek8BkH8Zr\",\"symbol\":\"REVS\"}" # 500.67180183 +sleep 3 +# RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr KMD 16435.34703311, REVS 114.80740001 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSWsxgczqH1uYyY6MMPePJY5jNjj7uD7Xr\",\"symbol\":\"REVS\"}" # 114.80740001 +sleep 3 +# RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr KMD 17137.93285029, REVS 340.00462653 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVxvCQ393MRnsQ8Fn8qiKm5yP6pk9GVgEr\",\"symbol\":\"REVS\"}" # 340.00462653 +sleep 3 +# RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF KMD 409543.68954327, REVS 8123.68911362 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG5eabU8sYvrfWrCu1wb2Go5vxhyVXsbAF\",\"symbol\":\"REVS\"}" # 8123.68911362 +sleep 3 +# RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d KMD 302.06577591, REVS 5.99094155 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYTMDSu1BjaQAdvh6a9CQFCr7h1rsGi48d\",\"symbol\":\"REVS\"}" # 5.99094155 +sleep 3 +# RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL KMD 30407.13753317, REVS 411.30538288 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVLd4HkkB8SsyXfXHQeHHNouNer7nv3mkL\",\"symbol\":\"REVS\"}" # 411.30538288 +sleep 3 diff --git a/iguana/tests/REVS.batch3.importaddress b/iguana/tests/REVS.batch3.importaddress new file mode 100755 index 000000000..8f0029ee7 --- /dev/null +++ b/iguana/tests/REVS.batch3.importaddress @@ -0,0 +1,30 @@ +# RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg KMD 5669.98491054, REVS 112.56208000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSVzs8BLvCrmvNF1MbqEpAwx9VHinmAxDg\",\"symbol\":\"REVS\"}" # 112.56208000 +sleep 3 +# RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W KMD 43088.74729573, REVS 470.87980000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLqqYX4oMVz6c6s52bLnYdfi9qZ56bEK3W\",\"symbol\":\"REVS\"}" # 470.87980000 +sleep 3 +# RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW KMD 55892.82951156, REVS 1070.41924580 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY5qhTwDGWQy4LsG2M3R8zyJz51KaMgCLW\",\"symbol\":\"REVS\"}" # 1070.41924580 +sleep 3 +# RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK KMD 335.54240549, REVS 6.65853993 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMx1MCvzuaiuRpS3rXV4LURWgZVRnLJCYK\",\"symbol\":\"REVS\"}" # 6.65853993 +sleep 3 +# RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh KMD 163589.49612623, REVS 3245.93000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNdQAbnuehuF5RnYiaLkWoWktpaxzfvNXh\",\"symbol\":\"REVS\"}" # 3245.93000000 +sleep 3 +# RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc KMD 98858.55994787, REVS 1384.95819177 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXX1kbdye39h9g7oFnP6cMZ6EEePCPRYnc\",\"symbol\":\"REVS\"}" # 1384.95819177 +sleep 3 +# RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9 KMD 5226.14889591, REVS 103.72248253 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUV5xgcHVavuxKkvMduhjXPVKA7oa1QCK9\",\"symbol\":\"REVS\"}" # 103.72248253 +sleep 3 +# RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK KMD 159251.95713851, REVS 3160.13095281 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGFv6LBE1xgiu34SqSh6wjn3fpr973sREK\",\"symbol\":\"REVS\"}" # 3160.13095281 +sleep 3 +# RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq KMD 28529.48507541, REVS 566.06461415 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQFihaDjPvCwhENGhB163D7e8Wc8LURtKq\",\"symbol\":\"REVS\"}" # 566.06461415 +sleep 3 +# RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72 KMD 8637.01756743, REVS 171.30000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDjm2Xec5UTWiz3Yku8sUce8ZWxe8mTh72\",\"symbol\":\"REVS\"}" # 171.30000000 +sleep 3 diff --git a/iguana/tests/REVS.batch4.importaddress b/iguana/tests/REVS.batch4.importaddress new file mode 100755 index 000000000..4a2513244 --- /dev/null +++ b/iguana/tests/REVS.batch4.importaddress @@ -0,0 +1,33 @@ +# RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB KMD 843.49707566, REVS 16.72927581 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPYGEUfYMHizer5siX2CNpQ6xHAbjtgQuB\",\"symbol\":\"REVS\"}" # 16.72927581 +sleep 3 +# RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n KMD 3090.02793673, REVS 3.67077856 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTrZWBu7SUZWf4ZdyUVddRPxsnDhZnre7n\",\"symbol\":\"REVS\"}" # 3.67077856 +sleep 3 +# RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk KMD 79613.96546024, REVS 1579.43521640 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRixT2CqGcr5cdPoP3G2rhrWDfSbVZR6sk\",\"symbol\":\"REVS\"}" # 1579.43521640 +sleep 3 +# RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut KMD 20106.39865075, REVS 0.09000000 +sleep 1 +# RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw KMD 867960.91662544, REVS 11685.48356181 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA9G36WwA9K95bn8Cbycq5ZnoxhSzzhhBw\",\"symbol\":\"REVS\"}" # 11685.48356181 +sleep 3 +# RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj KMD 19695.58704144, REVS 390.89494454 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVcSdFR5fC3Qjk3CARvQSkra5PQwC8U3uj\",\"symbol\":\"REVS\"}" # 390.89494454 +sleep 3 +# RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo KMD 2981.62619009, REVS 30.35300490 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQokxkBAizLmegMeWK5TyTpSHn2vP5adjo\",\"symbol\":\"REVS\"}" # 30.35300490 +sleep 3 +# RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX KMD 40914.30625015, REVS 476.17156540 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAMvDwi58oyArqfGseWZsYbR2BN3L7ghVX\",\"symbol\":\"REVS\"}" # 476.17156540 +sleep 3 + +d7b569ab57ecd41bac23f3dc39f3844878d337e9318fc91018a7eca8bb6ba77a +bd4cfe44080e63be6fff752053231779b419fa10c579425d6f9b362359f28ae9 +825ff540a2846c8ce4d25a2a51687b0506eda0a0f2bd006254c8a0c6a8ebc721 +75b0586d9feda7503a7251629345a1bc9e47847abb71d976d8eb8eead54f4a2e +4df987f42b0ba6f75f89a591b1a5a5aefd0ad7094b8ff2e2ce7d6b273f8985e9 +73672daeee959723e4373fb2b5252dd8d2515863cfdb397d8b9dfdc743000afe +817c83d32f325d44d95f906492b9a567909b2d9488e9f25e8eddd800dd5f3a86 +64cc8779344aa739c4f4b55194c847ff0f11fd10fe226cb467eb22fc8ca4b9b5 + diff --git a/iguana/tests/REVS.batch5 b/iguana/tests/REVS.batch5 new file mode 100755 index 000000000..ab67a7075 --- /dev/null +++ b/iguana/tests/REVS.batch5 @@ -0,0 +1,39 @@ +sleep 99999 +# RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y KMD 6045.00703151, REVS 119.90847305 +sleep 1 +fiat/revs sendtoaddress RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y 119.90847305 +# RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 KMD 35570.77185561, REVS 706.06380741 +sleep 1 +fiat/revs sendtoaddress RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 706.06380741 +# RGur4rnZTJRSdAjU5avya5EA57K5izbv9b KMD 1891.37303787, REVS 19.42986755 +sleep 1 +fiat/revs sendtoaddress RGur4rnZTJRSdAjU5avya5EA57K5izbv9b 19.42986755 +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 195982.90265756, REVS 3438.00000000 +sleep 1 +fiat/revs sendtoaddress RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni 3438.00000000 +# RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY KMD 9117.34456938, REVS 181.00000000 +sleep 1 +fiat/revs sendtoaddress RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY 181.00000000 +# RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ KMD 6641.51666395, REVS 131.74080812 +sleep 1 +fiat/revs sendtoaddress RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ 131.74080812 +# REq67wAMhhyUD6JRScLBpc2BD6farddg3e KMD 6740.09632448, REVS 16.99805655 +sleep 1 +fiat/revs sendtoaddress REq67wAMhhyUD6JRScLBpc2BD6farddg3e 16.99805655 +# RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s KMD 22492.75115633, REVS 236.96348849 +sleep 1 +fiat/revs sendtoaddress RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s 236.96348849 +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 6165.95629088, REVS 18.51019595 +sleep 1 +fiat/revs sendtoaddress REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk 18.51019595 +# RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY KMD 230865.18565552, REVS 4582.57000000 +sleep 1 +fiat/revs sendtoaddress RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY 4582.57000000 +# RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a KMD 13266.57413441, REVS 46.55982083 +sleep 1 +fiat/revs sendtoaddress RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a 46.55982083 +# RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY KMD 129183.61336863, REVS 2562.48000000 +sleep 1 +fiat/revs sendtoaddress RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY 2562.48000000 + +# total KMD 0.00000000 REVS 12060.22451795 diff --git a/iguana/tests/REVS.batch5.importaddress b/iguana/tests/REVS.batch5.importaddress new file mode 100755 index 000000000..90ab7be04 --- /dev/null +++ b/iguana/tests/REVS.batch5.importaddress @@ -0,0 +1,36 @@ +# RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y KMD 6045.00703151, REVS 119.90847305 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGahFz48G2H6mUJfGnrH6wvDXTJuTE6i6Y\",\"symbol\":\"REVS\"}" # 119.90847305 +sleep 3 +# RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1 KMD 35570.77185561, REVS 706.06380741 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPwgBuP6dqg275ogGT6oXLGLRhb3KJBiL1\",\"symbol\":\"REVS\"}" # 706.06380741 +sleep 3 +# RGur4rnZTJRSdAjU5avya5EA57K5izbv9b KMD 1891.37303787, REVS 19.42986755 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGur4rnZTJRSdAjU5avya5EA57K5izbv9b\",\"symbol\":\"REVS\"}" # 19.42986755 +sleep 3 +# RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni KMD 195982.90265756, REVS 3438.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKuwq4oi4mqQ2V4r54mPEthn3TBrEwu2Ni\",\"symbol\":\"REVS\"}" # 3438.00000000 +sleep 3 +# RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY KMD 9117.34456938, REVS 181.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLF4RDbghSp9F1bXpnYoT64BhiS5BK2pXY\",\"symbol\":\"REVS\"}" # 181.00000000 +sleep 3 +# RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ KMD 6641.51666395, REVS 131.74080812 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAHQfS9AwqS5i75zSVL2DgJFwYfQGY6BWJ\",\"symbol\":\"REVS\"}" # 131.74080812 +sleep 3 +# REq67wAMhhyUD6JRScLBpc2BD6farddg3e KMD 6740.09632448, REVS 16.99805655 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REq67wAMhhyUD6JRScLBpc2BD6farddg3e\",\"symbol\":\"REVS\"}" # 16.99805655 +sleep 3 +# RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s KMD 22492.75115633, REVS 236.96348849 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKCBKPrxDxTEtedqSqCm76obnGt8Enii6s\",\"symbol\":\"REVS\"}" # 236.96348849 +sleep 3 +# REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk KMD 6165.95629088, REVS 18.51019595 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REmYfd1MwrYzxW7swvXMMcuKb7u1LFeNHk\",\"symbol\":\"REVS\"}" # 18.51019595 +sleep 3 +# RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY KMD 230865.18565552, REVS 4582.57000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAfW9pukafJsa2CweFztAsFxaSW8HT7KfY\",\"symbol\":\"REVS\"}" # 4582.57000000 +sleep 3 +# RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a KMD 13266.57413441, REVS 46.55982083 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKziMKBsSDGQT6zmwgyyXvTWbc7PPjiy4a\",\"symbol\":\"REVS\"}" # 46.55982083 +sleep 3 +# RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY KMD 129183.61336863, REVS 2562.48000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJfGGtCX44Q3eEkg8LL2tkGg2cS6WGZxDY\",\"symbol\":\"REVS\"}" # 2562.48000000 +sleep 3 diff --git a/iguana/tests/REVS.batch5.txids b/iguana/tests/REVS.batch5.txids new file mode 100644 index 000000000..4c6611554 --- /dev/null +++ b/iguana/tests/REVS.batch5.txids @@ -0,0 +1,12 @@ +1f2ef4a160ef08a462fea5743a43471c51c485f013e30dd82a9be8b97743e674 +4df46669fea7697c04f58cf60a9290287f74ae026686a29b3f610bb397651134 +86aa2de8fe4f96374cb0d97631a4d95b076db775e11955cd72bcdb0166b86ff6 +6d45001119034eaa73ff607e3f779c07e3ea64fdafbb02c141e9b0bf04593191 +38e0ea46fc476f97238dae649213c764ee648a5dd661d58809fbda9dce82ff65 +14cbe2b75e6d1d0664a387dcec1099d81438f7b4a16e93e45b5f60fa11d2735c +0f1389abb35b7cfb0d607872078a3131bab4c21f38e7442e7b21196b790fbba0 +fe642dcc31305547eed48056aa714a8d09b2a0e1debecf58e18a47f2ada0a39a +ac2ef885f7b10ba44de3c7ea3e631faf8b575b2138805bf7c2456ba1b9d3f66d +3cac67df2e80b2f04cf6f28225be476cf0b8be2664b219f12a9196897db709c6 +2d03201c6a1eb0beb40e47fe5ffccdde8d6e8199c3230d5df43a772a24f9e1bd +5aa8e6fd3e05374094eb2ad922f6d5e7ac54ab6a3bde2488513d104085048554 diff --git a/iguana/tests/REVS.batch6 b/iguana/tests/REVS.batch6 new file mode 100755 index 000000000..88ba59bc4 --- /dev/null +++ b/iguana/tests/REVS.batch6 @@ -0,0 +1,24 @@ +sleep 99999 +# RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc KMD 23246.75713145, REVS 66.39295712 +sleep 1 +fiat/revs sendtoaddress RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc 66.39295712 +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 17002.74354061, REVS 278.99000000 +sleep 1 +fiat/revs sendtoaddress RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW 278.99000000 +# RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL KMD 12356.73789711, REVS 112.00000000 +sleep 1 +fiat/revs sendtoaddress RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL 112.00000000 +# RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt KMD 391.52338368, REVS 7.76943254 +sleep 1 +fiat/revs sendtoaddress RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt 7.76943254 +# RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r KMD 682.83148523, REVS 13.54307355 +sleep 1 +fiat/revs sendtoaddress RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r 13.54307355 + +# total KMD 0.00000000 REVS 478.69546321 +af290c5d5e12a44d46de9942f8cda407ca85bf44c9cf390523c5e21c3a851322 +f4c8e606db994bf65b788bcbd0a8976ff1287ff5d6744a0652d6aa9da284a725 +c230ad49f773fd59b84c1267d4373a7679cd231aaf1fd27329ad8e9d29708e2a +03b0b119d20d181ccc687f01c17a6017e7718f8f74f68059d4a8de3e52db0c0b +5a24fba048923f922d4e417ceac0157c56c7d03d26b0a9b2867d0013549de27c + diff --git a/iguana/tests/REVS.batch6.importaddress b/iguana/tests/REVS.batch6.importaddress new file mode 100755 index 000000000..99cc268e0 --- /dev/null +++ b/iguana/tests/REVS.batch6.importaddress @@ -0,0 +1,15 @@ +# RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc KMD 23246.75713145, REVS 66.39295712 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVbdZ1ki4piJF9NNBVbgc49r7KccxJL6oc\",\"symbol\":\"REVS\"}" # 66.39295712 +sleep 3 +# RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW KMD 17002.74354061, REVS 278.99000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAGGPNoZgxAj6ABBTwehQfVYEa1PEN4qZW\",\"symbol\":\"REVS\"}" # 278.99000000 +sleep 3 +# RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL KMD 12356.73789711, REVS 112.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RExWiEUz3GAatrkEvXNj3N6rBpzm29wRrL\",\"symbol\":\"REVS\"}" # 112.00000000 +sleep 3 +# RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt KMD 391.52338368, REVS 7.76943254 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ1JfavGVxps1wXnhCfwnAbNoXn7ei1zMt\",\"symbol\":\"REVS\"}" # 7.76943254 +sleep 3 +# RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r KMD 682.83148523, REVS 13.54307355 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFoHKWbcKrktCAdYJVGhrJ4g8dXQ1Cvy5r\",\"symbol\":\"REVS\"}" # 13.54307355 +sleep 3 diff --git a/iguana/tests/REVS.batch7 b/iguana/tests/REVS.batch7 new file mode 100755 index 000000000..bf8cfbe2e --- /dev/null +++ b/iguana/tests/REVS.batch7 @@ -0,0 +1,20 @@ +sleep 9999999 +# RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi KMD 19824.65353390, REVS 393.51044761 +sleep 1 +fiat/revs sendtoaddress RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi 393.51044761 +# RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH KMD 138721.51640953, REVS 2656.00000000 +sleep 1 +fiat/revs sendtoaddress RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH 2656.00000000 +# RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL KMD 47.52053869, REVS 0.94300273 +sleep 1 +fiat/revs sendtoaddress RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL 0.94300273 +# RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX KMD 7435.09663624, REVS 70.73874773 +sleep 1 +fiat/revs sendtoaddress RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX 70.73874773 + +# total KMD 0.00000000 REVS 3121.19219807 +563fab7a3c96c33899314d77ad37d724d5dae8febd52c6c435133c2e1450339f +2a147a839e8d6bbe9546d37dd05851657ddd3eec5dfd53a055cc2dde24f81b6f +8efec553d6e525cd2b141316ac06a09e282a13215c97ba6d18b1eccf1375a217 +0b0f8cfd256c573a584cd68c971448b2d9b90f6a6eb7fc7ae932bbcbf609518a + diff --git a/iguana/tests/REVS.batch7.importaddress b/iguana/tests/REVS.batch7.importaddress new file mode 100755 index 000000000..8955bffbe --- /dev/null +++ b/iguana/tests/REVS.batch7.importaddress @@ -0,0 +1,11 @@ +# RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi KMD 19824.65353390, REVS 393.51044761 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRtJZXkyye8CdgkiqqU2vDBzVL8br8v7qi\",\"symbol\":\"REVS\"}" # 393.51044761 +sleep 3 +# RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH KMD 138721.51640953, REVS 2656.00000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFsV4VaRdzLLFHotqsxZbim2ARwP8VHxJH\",\"symbol\":\"REVS\"}" # 2656.00000000 +sleep 3 +# RF11xHFssjxqa4UhUtZmReeb2w8ikmzkzL KMD 47.52053869, REVS 0.94300273 +sleep 1 +# RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX KMD 7435.09663624, REVS 70.73874773 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKmvo8crdpftFSPtJ8332KN82r1vZJaBKX\",\"symbol\":\"REVS\"}" # 70.73874773 +sleep 3 diff --git a/iguana/tests/REVS.batch8 b/iguana/tests/REVS.batch8 new file mode 100755 index 000000000..d3f78263e --- /dev/null +++ b/iguana/tests/REVS.batch8 @@ -0,0 +1,33 @@ +sleep 999999 +# RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG KMD 23492.49573707, REVS 189.50500057 +sleep 1 +fiat/revs sendtoaddress RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG 189.50500057 +# RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a KMD 1198.78675406, REVS 23.78885452 +sleep 1 +fiat/revs sendtoaddress RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a 23.78885452 +# RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns KMD 30681.77405788, REVS 608.60220842 +sleep 1 +fiat/revs sendtoaddress RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns 608.60220842 +# RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL KMD 188643.68073877, REVS 597.97000000 +sleep 1 +fiat/revs sendtoaddress RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL 597.97000000 +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 17160.85255783, REVS 233.03444206 +sleep 1 +fiat/revs sendtoaddress RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 233.03444206 +# REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe KMD 203188.29997688, REVS 2109.97700000 +sleep 1 +fiat/revs sendtoaddress REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe 2109.97700000 +# RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB KMD 138920.34502737, REVS 835.32960760 +sleep 1 +fiat/revs sendtoaddress RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB 835.32960760 + +# total KMD 0.00000000 REVS 4598.20711317 + +fae0e4e8f3ad348dff687f9baa3e9975d4d893a38cd45190b60f61868a577ca4 +edc160137ddb19dc7d00ddce6c35589ad5ab3ab6fee7cfb53090ee512a6595a9 +d745bfb6e8fb32fff521b249be86ee8dba904c03738755420b7980a8350160a8 +931c7d187b641c681c8f75a03da9849053504a95f55534af3385e3426fc4c5ea +e2598e462f81aff6d57c48adf224983a5b8c72f2c396096651c6e354b6c43928 +ac9e2a40a4d565587cb73616d179ae90592a60b3cfc628f84e42a4533d3e3c51 +d86e7b79d0aac2347804e0c11baac74e985005fcba8edffb5b9c359c05a08bb0 + diff --git a/iguana/tests/REVS.batch8.importaddress b/iguana/tests/REVS.batch8.importaddress new file mode 100755 index 000000000..1422950aa --- /dev/null +++ b/iguana/tests/REVS.batch8.importaddress @@ -0,0 +1,21 @@ +# RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG KMD 23492.49573707, REVS 189.50500057 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWq87C4y7KBfy95otyvkgyCf18LfXV2vcG\",\"symbol\":\"REVS\"}" # 189.50500057 +sleep 3 +# RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a KMD 1198.78675406, REVS 23.78885452 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWC11HxcX18hxm38NTZ6U5EMA9uSPzTJ3a\",\"symbol\":\"REVS\"}" # 23.78885452 +sleep 3 +# RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns KMD 30681.77405788, REVS 608.60220842 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFkQHrVHb7xiFgjmhz1tvbrYJ8DcEH33ns\",\"symbol\":\"REVS\"}" # 608.60220842 +sleep 3 +# RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL KMD 188643.68073877, REVS 597.97000000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJCBezf4HwreDsMK6tCm5YtcZtfBfeY3wL\",\"symbol\":\"REVS\"}" # 597.97000000 +sleep 3 +# RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8 KMD 17160.85255783, REVS 233.03444206 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH7cfyUkBwrLbxfWBggcbV3UgzaAHyy3J8\",\"symbol\":\"REVS\"}" # 233.03444206 +sleep 3 +# REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe KMD 203188.29997688, REVS 2109.97700000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REopaxhMho1ffQ9fpqC6YLKaAS8D2Q2Twe\",\"symbol\":\"REVS\"}" # 2109.97700000 +sleep 3 +# RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB KMD 138920.34502737, REVS 835.32960760 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKmZ2U9SYweYcUCuVugKmyfiawpPzXX8JB\",\"symbol\":\"REVS\"}" # 835.32960760 +sleep 3 diff --git a/iguana/tests/REVS.batch9 b/iguana/tests/REVS.batch9 new file mode 100755 index 000000000..9b581cba8 --- /dev/null +++ b/iguana/tests/REVS.batch9 @@ -0,0 +1,27 @@ +# RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL KMD 2225.74637484, REVS 44.17250867 +sleep 1 +fiat/revs sendtoaddress RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL 44.17250867 +# RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 KMD 71.93221162, REVS 1.27173666 +sleep 1 +fiat/revs sendtoaddress RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 1.27173666 +# RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb KMD 163809.81597006, REVS 3251.55110000 +sleep 1 +fiat/revs sendtoaddress RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb 3251.55110000 +# RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq KMD 4785.58282591, REVS 2.73080820 +sleep 1 +fiat/revs sendtoaddress RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq 2.73080820 +# RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj KMD 112939.81142424, REVS 2241.80390030 +sleep 1 +fiat/revs sendtoaddress RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj 2241.80390030 +# RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq KMD 3325.70020871, REVS 65.95939412 +sleep 1 +fiat/revs sendtoaddress RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq 65.95939412 + +# total KMD 0.00000000 REVS 5607.48944795 +d5d9950efea532582846b744eaf4e922556fa1446a2364fd55aaa90f4510106b +48acaf51ecc7aba3209bb2532c777ee9594c66d46056cb8003a11cc16c6bbb27 +5c06f259610af698bed238b1a849201c5ef1bd05619773f4df5e930d1a926b40 +f871cf48871b1bf6ccd9a388876ab911666b045da981ccd49f3d54315fdeac11 +e0db5b8c49fe3d7f0a51df0844bb7b04838661a436575f5b8c8c895ed8c33349 +ab617a095862b0db6d3aeec36e628b2d67aa7130548fac7d9be950b7687fec8b + diff --git a/iguana/tests/REVS.batch9.importaddress b/iguana/tests/REVS.batch9.importaddress new file mode 100755 index 000000000..1b52c45de --- /dev/null +++ b/iguana/tests/REVS.batch9.importaddress @@ -0,0 +1,18 @@ +# RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL KMD 2225.74637484, REVS 44.17250867 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPFYcaJ1hLGSNeMAyPyNmFeJaXPKMSPtbL\",\"symbol\":\"REVS\"}" # 44.17250867 +sleep 3 +# RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5 KMD 71.93221162, REVS 1.27173666 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQMnsa46FhvHnwg7M1DsUKnh8GPTbUqCJ5\",\"symbol\":\"REVS\"}" # 1.27173666 +sleep 3 +# RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb KMD 163809.81597006, REVS 3251.55110000 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW8FwjCAcV8SWJaT1r8aKiFHXit5pfPkVb\",\"symbol\":\"REVS\"}" # 3251.55110000 +sleep 3 +# RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq KMD 4785.58282591, REVS 2.73080820 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSXBDSmt7rsPJNg4Cy6tVZCQRyWv2oRmdq\",\"symbol\":\"REVS\"}" # 2.73080820 +sleep 3 +# RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj KMD 112939.81142424, REVS 2241.80390030 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVVsTRZDt1ywJ115KB22kpwUGEba21aJfj\",\"symbol\":\"REVS\"}" # 2241.80390030 +sleep 3 +# RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq KMD 3325.70020871, REVS 65.95939412 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH8q81jTRuH35g2g59iT3kxJWoF9Unzgqq\",\"symbol\":\"REVS\"}" # 65.95939412 +sleep 3 diff --git a/iguana/tests/REVS.importaddress b/iguana/tests/REVS.importaddress new file mode 100755 index 000000000..949b50d5e --- /dev/null +++ b/iguana/tests/REVS.importaddress @@ -0,0 +1,2350 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYXNNwhn8yWRNkbAdUCEBSvqUcTivqxUsF\",\"symbol\":\"REVS\"}" # 1.00219032 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9TgGaoE9Kvb1ueqBH8Px5XHAkYiKoTqQH\",\"symbol\":\"REVS\"}" # 1.00235226 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPsvT7SkSvCSeGG7HQaXhABLGn5ZTMmrsi\",\"symbol\":\"REVS\"}" # 1.00323306 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB522aFX4HZa8FG3uQkp8iN9Wu6aCN4Tfz\",\"symbol\":\"REVS\"}" # 1.00438063 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTrnP43t1WyXSuyVU5hocNThZ3SHDVehqZ\",\"symbol\":\"REVS\"}" # 1.00492821 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUK99xTisiQXLxeGd1dthvnMDU2vRdv2sa\",\"symbol\":\"REVS\"}" # 1.00506510 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVZx5sSoM69dTriw3h5aPHYZCdbyMbrSWk\",\"symbol\":\"REVS\"}" # 1.00520200 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB83thrZiTF7E5CtuEufz7y5ox7FiZPv9a\",\"symbol\":\"REVS\"}" # 1.00533889 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTpRFdQuweU5nGqror7Hh98agPt74GM2FY\",\"symbol\":\"REVS\"}" # 1.00533891 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDXhENQUVE3xZTWRMynBfay2ih8PAXYQPv\",\"symbol\":\"REVS\"}" # 1.00561268 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK7DnD9meJHVFRMYHQhHSbcRujbiLq1Hr2\",\"symbol\":\"REVS\"}" # 1.00561269 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU7qaDDeCW73DvFgEobUUr7S5ZLNjyk9ws\",\"symbol\":\"REVS\"}" # 1.00571268 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDt7LuGsu46DqyVLrzBmP6Bem2G3DMfC3V\",\"symbol\":\"REVS\"}" # 1.00574957 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHNocz18MS4RvUGqm2rGZRK5NBSMmfsob1\",\"symbol\":\"REVS\"}" # 1.00574959 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSMY1xDJm6NJWjvUKWgTTPWJgxADq29Avk\",\"symbol\":\"REVS\"}" # 1.00588646 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR7if8S9HJc3NzcKQwskj1r3AkF4Qq3H4t\",\"symbol\":\"REVS\"}" # 1.00588647 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAsqCgMrAxA2E9AkNB4wP3HakCbMsCam2N\",\"symbol\":\"REVS\"}" # 1.00588648 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBfUQwZEU4nGBJcb4CgjohhE56r2FBj6js\",\"symbol\":\"REVS\"}" # 1.00602335 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCJ4iPHQYGxbQBr2yrSHQDHAHmoJcNq2vg\",\"symbol\":\"REVS\"}" # 1.00602337 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM6pXaUi2VVvE45pPSLkg7fTDgZiG3ZMeZ\",\"symbol\":\"REVS\"}" # 1.00602338 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGJd7kAJZukbGSejFzfwa54V5BL66wK8Bg\",\"symbol\":\"REVS\"}" # 1.00616025 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGaaRsUJXx935dC9TFHHSLBjDe4SLiZWZf\",\"symbol\":\"REVS\"}" # 1.00616027 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMdJBwoRuuFRk8fvtzZG6YjCcrw1zpygpa\",\"symbol\":\"REVS\"}" # 1.00626025 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPEWGCJ1khGbfggd1GVFVBpBVcvoKziHsj\",\"symbol\":\"REVS\"}" # 1.00629715 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWibUtwLfz3y5k6b18KZCxMNe8Rh3K3ZZ5\",\"symbol\":\"REVS\"}" # 1.00629717 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPsFft6ce7VExfwrAk1pDbz1dRvmZhjXox\",\"symbol\":\"REVS\"}" # 1.00643405 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBaTVtWAJBRWLrwoLJqJcaW2RfKnykGYsN\",\"symbol\":\"REVS\"}" # 1.00643406 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRx7phckZykXqzrMyuLZML1dkYGdAqt48S\",\"symbol\":\"REVS\"}" # 1.00653406 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK38qjB5RsTzQVsfanjCZXQcGCCMgdwCMd\",\"symbol\":\"REVS\"}" # 1.00657093 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNnpckXPNgDcN93j3d1WQ8X4hJs1YYf51T\",\"symbol\":\"REVS\"}" # 1.00657094 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVFAUQkNEFXJrvFceBA9nSbgzBPiJNUNu2\",\"symbol\":\"REVS\"}" # 1.00657095 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAmCMxnuvhTWJT1VawDRMcS8dTs451W46F\",\"symbol\":\"REVS\"}" # 1.00667095 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTMQMAjUenKUGqfNAKcJEGK2unUQ52o8wV\",\"symbol\":\"REVS\"}" # 1.00669715 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RX7xiKrHRUnwngJfSRcagE5mDiS1qnicuW\",\"symbol\":\"REVS\"}" # 1.00670781 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKyBgaG5tJyVVA2kJUAFzFMorgWzs5kzA8\",\"symbol\":\"REVS\"}" # 1.00670783 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS5FbA78PK6SAe8GHSmmUWLF1qvWvuiJ4X\",\"symbol\":\"REVS\"}" # 1.00670784 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNEQc7KmhxUTSg2qGjK6v9GHKE5KgufySa\",\"symbol\":\"REVS\"}" # 1.00670785 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRW9d9JZHhRkLdJoX27UcDecqD9wz5Dx72\",\"symbol\":\"REVS\"}" # 1.00680783 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLLQNJDEKkMZur6cpgjPdMgpHS3UUgUrha\",\"symbol\":\"REVS\"}" # 1.00680784 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9uvvN7k5jiQYws3h67EEcqQdhDSL3pUw8\",\"symbol\":\"REVS\"}" # 1.00684471 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW34SVHK5c3XJRBN2wUq8YmwwpBkHtx2ti\",\"symbol\":\"REVS\"}" # 1.00684473 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR9es3yRQ4PAes49w2x8UErHYFddnbvhkk\",\"symbol\":\"REVS\"}" # 1.00684474 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXUThKYh6uMvv5mf4geStrLLYYDSF34XSM\",\"symbol\":\"REVS\"}" # 1.00684475 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWwEXx3b5syksp3cJae8kqeTRTRDnsEzj9\",\"symbol\":\"REVS\"}" # 1.00694473 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUSwJUcREkKkK2uxoBpHMWXj5foaGMF5er\",\"symbol\":\"REVS\"}" # 1.00698161 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLQLCMktbxJWWaz3BWairGxgPpMQr2mpV4\",\"symbol\":\"REVS\"}" # 1.00698163 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXtYrtBJw6B4wfiX2oVbvKBYVNT4Khjmsf\",\"symbol\":\"REVS\"}" # 1.00698164 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCpLjxHC4Ki9kL6H6NVZ36MaGxgAyEhVqw\",\"symbol\":\"REVS\"}" # 1.00711852 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDP6ViSrCckekSa7PGcphnX6vxgZKv7FDh\",\"symbol\":\"REVS\"}" # 1.00711853 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REovwe65if2RSkhETRpWK4yUMAZvyQesHy\",\"symbol\":\"REVS\"}" # 1.00711854 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRFQjZ26eMg65BQQszYM8KH7MTx9xT5MPT\",\"symbol\":\"REVS\"}" # 1.00715541 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMuLfxyR77ghChbBLrqeq1MmC9dSJ1eDAL\",\"symbol\":\"REVS\"}" # 1.00725543 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJhywbyJk8FkTCMKXVRzypQcAJAMeDHnU5\",\"symbol\":\"REVS\"}" # 1.00733406 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTR8bnNwg5PWkMQvr6EbdzT631taduNa8j\",\"symbol\":\"REVS\"}" # 1.00745543 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHJ9gDfHVWCNDbR2o9xfVGaPEFs3AUGNDP\",\"symbol\":\"REVS\"}" # 1.00756611 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTUdnAHu38ukszdvcdeZqH4nSpHyfNePw9\",\"symbol\":\"REVS\"}" # 1.00783302 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA4tNV7a2X6zTwzYFqbHfBeFFveckrXxNZ\",\"symbol\":\"REVS\"}" # 1.00821753 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT7P27xJTwmijtQvQbXvkskNCmGB2oasCn\",\"symbol\":\"REVS\"}" # 1.00839715 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVdGLVL4PfRyhLZR14N8ZYGQiXsj9uHDHb\",\"symbol\":\"REVS\"}" # 1.00897627 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNwhd2Q8Ht3AxVjiPdpkSsWCmMTV3jVPLS\",\"symbol\":\"REVS\"}" # 1.00898185 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHyzfjE73nikKXn2cgASXiQapjsLEbXy5D\",\"symbol\":\"REVS\"}" # 1.01000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQE1A6R1JNp47dV4w7t6eRo5x2BMQhri2D\",\"symbol\":\"REVS\"}" # 1.01318580 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSgu6rSX3193VXd1EBt1RuZn7Wm9M3ucSv\",\"symbol\":\"REVS\"}" # 1.01607052 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVrcKQ5mb1gyBp6YorUPHdzdgj31SpFGh5\",\"symbol\":\"REVS\"}" # 1.01814050 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKFqJRoYizcmSphVeKzvhiqdNXRNfarVGU\",\"symbol\":\"REVS\"}" # 1.01938979 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNjZQxQEEQssAKUay8n1TtChxUBQ8PBqwK\",\"symbol\":\"REVS\"}" # 1.01987315 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV25PKU1uER2HxA5PpgbxEx3YUe8VGaW1U\",\"symbol\":\"REVS\"}" # 1.02385871 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REVQCfJjPCqTVfi4iszhPKZDeQiaAPRHvF\",\"symbol\":\"REVS\"}" # 1.02411103 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSKmx2FgUFuZmRyimuZ5UoZ6PFWpGShTTM\",\"symbol\":\"REVS\"}" # 1.02699342 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKY7pHG9EadEcaoWSygpXcPFscAYS6HSQa\",\"symbol\":\"REVS\"}" # 1.02751965 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMtnxXvFiVj8dgnP5gYeXpovt7nzTM8Jks\",\"symbol\":\"REVS\"}" # 1.03047428 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWUcw7dePV8cMi29nFwnLFQ3eXE4S5H2RL\",\"symbol\":\"REVS\"}" # 1.03153735 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQs3J2QfDe2ETL7A3NZZWHedNXvhU6etiz\",\"symbol\":\"REVS\"}" # 1.03328580 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bSjWe9tp4sjtehJxBSEBJi1Aed1NXejE5m\",\"symbol\":\"REVS\"}" # 1.03610000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVp8ZGAACfpXFguGiT3saVJvhKsns99JFW\",\"symbol\":\"REVS\"}" # 1.03893782 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNhzw3UNS2EDv1PG4iY6cCFpWLkc4TvMvu\",\"symbol\":\"REVS\"}" # 1.04070429 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNtXaHPobwLBH5mLsF48sramDRECZiRhZw\",\"symbol\":\"REVS\"}" # 1.04736687 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS3XxRpr7ew9B4t1B69C9Y9NHYXYstDz1Z\",\"symbol\":\"REVS\"}" # 1.04908716 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKNRL3tC9m72ycUG9u9S8Yr2CeuwQXHa2j\",\"symbol\":\"REVS\"}" # 1.04916801 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYPHft1dLmsqJS6yxjG788HZ8Ze8n2mEF3\",\"symbol\":\"REVS\"}" # 1.05636881 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bHEoRLM5zSHjdP81LW7sD6Mr1ZQRZ4Fu5J\",\"symbol\":\"REVS\"}" # 1.05700000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRXXa6769aALZvfeiC5WYjtYM2vnNhs7BT\",\"symbol\":\"REVS\"}" # 1.05772610 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLGrcD5YgDYhciRATJTiA2aji3kndP7n4N\",\"symbol\":\"REVS\"}" # 1.06364344 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RShuJwaNmvyU8bc7GtE6XZBuZu5iV3mVs2\",\"symbol\":\"REVS\"}" # 1.07114814 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSxGVspEt8xUJEs39sXdovkoQ1GRXMjRC6\",\"symbol\":\"REVS\"}" # 1.07521774 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH6HTbU3i6SJTGZbJfcoZoPNHQBtvch6bA\",\"symbol\":\"REVS\"}" # 1.07759935 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRrgy1qYP56iRPhCRN9zTWhupgLPezAxdY\",\"symbol\":\"REVS\"}" # 1.08673844 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REeenBUJUdkpwVkBT9fphjXCTkWShKBQMy\",\"symbol\":\"REVS\"}" # 1.08755766 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLVuSHKtXPg1ttx44h6zDJJBiRskMkUbdm\",\"symbol\":\"REVS\"}" # 1.08915528 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bRmhenKFGwcHmv5pcegMGqqaKPMqshU58E\",\"symbol\":\"REVS\"}" # 1.09000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTWeue98rTN2MEyobj7fSmff7CZFqGkxAm\",\"symbol\":\"REVS\"}" # 1.09677588 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPMTn6kP6qkbqWU2LSgJHRAK1qZ9qioi8u\",\"symbol\":\"REVS\"}" # 1.10090396 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCJvbEYyU1rJFf3mRG2mj9CRAiNkfRo3yS\",\"symbol\":\"REVS\"}" # 1.10167493 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPZw6kcMotYjcykX1S6FBaNaLTUyUMzdz2\",\"symbol\":\"REVS\"}" # 1.10264199 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSiVctTs1sM1eeG8ruNtLp2Yp8GYRotjqD\",\"symbol\":\"REVS\"}" # 1.10273790 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTYfFMyhibug31XcpzwfridFJdqY8vHaKH\",\"symbol\":\"REVS\"}" # 1.11583822 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPF9SqxScrg9mhUyiaJBCnAUDGGNzjnwV6\",\"symbol\":\"REVS\"}" # 1.11999426 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYFiBBm5PmMHarY5aYzbzrHKC39YGU7jtU\",\"symbol\":\"REVS\"}" # 1.12446319 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFm3is8KmTmmCPbhwm16txnHH4fNiw9GTo\",\"symbol\":\"REVS\"}" # 1.12618210 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWqJ2GtJ7gJ5AHVWgLWQr8C9C6Ve3ky4ub\",\"symbol\":\"REVS\"}" # 1.12814944 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVqShVM4zJN5ek2stHyJeQB3UkH4NLg2hZ\",\"symbol\":\"REVS\"}" # 1.13102130 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTZL8HjD9g8nZJA4edWdvERsH1aTq85QWP\",\"symbol\":\"REVS\"}" # 1.13302477 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTfB4qE75df5XW1rPgYaR89WTpUQZFQHSp\",\"symbol\":\"REVS\"}" # 1.13740666 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ7S1HrupzMwbXyAi3azcj9eFFMKciEfVZ\",\"symbol\":\"REVS\"}" # 1.14590863 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RERL41V7aTxUJmpewF2jZ6fcEvKtFzf5ZH\",\"symbol\":\"REVS\"}" # 1.14647693 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQq26XJaZewYWSpt8p8gjfU93qdm1s5366\",\"symbol\":\"REVS\"}" # 1.14830381 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAzLrZcbyuZXawkYK5HdihKZ9kzhD8wWVz\",\"symbol\":\"REVS\"}" # 1.15438148 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQMGqPvzcjUoCYTb25LHV5WGenA4bukdhA\",\"symbol\":\"REVS\"}" # 1.15566613 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH9Z8Jw4Xxahem74s7EGWUeyJTXinaeTLi\",\"symbol\":\"REVS\"}" # 1.17046666 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWY9zQf3763qAVR4x39BfXYrSKc2ZNjP7W\",\"symbol\":\"REVS\"}" # 1.18568692 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBphVPd4MiKi1LkiPfu1et8Kpa9JSk7rh2\",\"symbol\":\"REVS\"}" # 1.18700000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV4Mw8nMXijvPBZ1zBBM32BFvzp7dYZ1C4\",\"symbol\":\"REVS\"}" # 1.19154018 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RX36LorLqGgbMpCbrUyjydu45aweN9jh19\",\"symbol\":\"REVS\"}" # 1.19454928 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLdB8ZZ8AfAviYxCaYP7wVkntqgYD64Jpn\",\"symbol\":\"REVS\"}" # 1.19713102 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT58V9mS1JmhKjSRZaHdZLrt4PzwN2nSR1\",\"symbol\":\"REVS\"}" # 1.19875350 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN9oHPqf9QmFi7m56AMsEk9FPJu1vVP3zY\",\"symbol\":\"REVS\"}" # 1.19892206 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUC1iYeSLb2YRMZiazT8TqHaz3gYmf9Gut\",\"symbol\":\"REVS\"}" # 1.20000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBNE1yHgYp5bNaocKn9Q7BZYtYB3XzufNQ\",\"symbol\":\"REVS\"}" # 1.20068347 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM8vw2rnTNhQ1xVFUzuVgModQhUG9d3zwk\",\"symbol\":\"REVS\"}" # 1.20567914 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG8cEVW7WLAAh6JKKngopbd4RLQ9kSfisG\",\"symbol\":\"REVS\"}" # 1.21156235 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXpnUwb8DKVsi2T3SWhbDADkXFMBCKsVye\",\"symbol\":\"REVS\"}" # 1.21223647 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAvV3Lk6La77gyKcJfH9jqDRdP4nki24HP\",\"symbol\":\"REVS\"}" # 1.21423234 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RX8TSFaxZGUPPB9uRzPH2AiKBRq13hLuPC\",\"symbol\":\"REVS\"}" # 1.21975557 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL4kqyihwav93jo8VwJwKuSJZiyf9sK7Tn\",\"symbol\":\"REVS\"}" # 1.22237299 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSSa7SScyTtDjXc3jP6npo3mMhvC5Th6oj\",\"symbol\":\"REVS\"}" # 1.22249997 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQnfXbXQQcE43muwMm3ojq16wFCad3PvrK\",\"symbol\":\"REVS\"}" # 1.22426673 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTjeebKboJjNXW3waS81VkSMC6ffJoPz4P\",\"symbol\":\"REVS\"}" # 1.22501630 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK4MmD9oCKMcafRh5BE9TRuFfhs5Ar5DeN\",\"symbol\":\"REVS\"}" # 1.23454729 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGdwjLpxScLGQPdY7HL9HzxL1rVXmLens1\",\"symbol\":\"REVS\"}" # 1.23741881 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAZmr6RjC7c7RQ8mjhGCriwgTJK8oXWKNC\",\"symbol\":\"REVS\"}" # 1.24308814 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPBo2F3mYmXUua6Sf3XwPT9JWpgmnogABQ\",\"symbol\":\"REVS\"}" # 1.25335363 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRdEZ2kLUU4HEhpQJQKDPE3SVmG4uod5VQ\",\"symbol\":\"REVS\"}" # 1.25492241 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNRF3knrQws2LnpBqMcYR826eAsZY5DYzQ\",\"symbol\":\"REVS\"}" # 1.26518133 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMjh84gmUjQvmMmEksvFtyPJ92NtnJXmzE\",\"symbol\":\"REVS\"}" # 1.26914043 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY1FYvxUs7qHtVtpGGu1VYQZcp6GEsZnv2\",\"symbol\":\"REVS\"}" # 1.26977694 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCkc86LUZmcunwZ51EzsdauRSC2sYDqXqo\",\"symbol\":\"REVS\"}" # 1.27990000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQjGLmSN7MceVQaFJMEFXxgqLZcn8Cdxce\",\"symbol\":\"REVS\"}" # 1.28329754 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLK7k8fYy5w76ScQ7UbjbMYjYsq9B12LcA\",\"symbol\":\"REVS\"}" # 1.28629131 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTmhoi1TfuVqS1TVpjQKyPCNfWUNJu4BsH\",\"symbol\":\"REVS\"}" # 1.29101449 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQChMmyxVzCKgdJudUQarmEYUMDeyyNpgi\",\"symbol\":\"REVS\"}" # 1.29146132 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMGLFX89yRLAoBRghk9zsW1tbwHh1ox8ef\",\"symbol\":\"REVS\"}" # 1.29446427 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQPbJwfyVvbBtLG2gEX6xhbafZSvXxo1iU\",\"symbol\":\"REVS\"}" # 1.29905594 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ8jDfnuHbm2G2ULMgNXwWpftwjcfiL5GT\",\"symbol\":\"REVS\"}" # 1.30218820 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL7LAXxhWoNyD5eGE92gB72m1ThjXwoYWM\",\"symbol\":\"REVS\"}" # 1.31742887 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9PnTkUFSegkFNzJRXMD6wX6mkLGg1hyjw\",\"symbol\":\"REVS\"}" # 1.31863412 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNBGifRYKUkRKosNm2cWjWa7mC8FyPxZM3\",\"symbol\":\"REVS\"}" # 1.31970855 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGtrs1cYyPAQMd85sCekvRwC6AKXcZ3sDr\",\"symbol\":\"REVS\"}" # 1.32005014 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFaEnmNkqJCoM7LwVkmm1dQvZPw7WQyvZZ\",\"symbol\":\"REVS\"}" # 1.32515352 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYc1aVTJF3jEQEsnofiypBH7BZaK7MFpKv\",\"symbol\":\"REVS\"}" # 1.33271517 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQutfzuVzjXQZY9bGDf8LkoXC7zYR3dCdY\",\"symbol\":\"REVS\"}" # 1.33280514 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBDqmM8gd2GpmqBxp1745YnnwWwCdjN41e\",\"symbol\":\"REVS\"}" # 1.33515153 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK5PjWa9bLssWRa9MT6YwpitkxxYC8GmEG\",\"symbol\":\"REVS\"}" # 1.33650226 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RD3b4gfPAYKZa8GouWBsT4FVxAf44hdVMA\",\"symbol\":\"REVS\"}" # 1.34813377 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCuvkhb6VbdquBhwTLQ5LcsX6yJgSgsiSJ\",\"symbol\":\"REVS\"}" # 1.34856314 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCu4FfEWht2CEWi7g98JDRe9f5Fn75cwak\",\"symbol\":\"REVS\"}" # 1.36199095 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL7mTzWvtFC3F8D1WFbAEwBmnefKYiupVK\",\"symbol\":\"REVS\"}" # 1.39208756 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REy7L2BAJsJqryyg7Ab4iDMBLpFvWssE6s\",\"symbol\":\"REVS\"}" # 1.39461673 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bZxsv5Uavht6nKtWfFPppGodRKB18kmKYa\",\"symbol\":\"REVS\"}" # 1.40153681 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REPyMFnLfqVsyRA2KfrQ776ayvTsK32o3J\",\"symbol\":\"REVS\"}" # 1.41501441 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFVpMGVbjeCaSeQFHKiYAbpRwGyfiMVyxX\",\"symbol\":\"REVS\"}" # 1.42000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLV5cKTyaYVABXjCkzd8vHvWqjDi8aLEH8\",\"symbol\":\"REVS\"}" # 1.42624969 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQZXGQNefs8Zx2SFgzhtEAkt2RdVAMaDr5\",\"symbol\":\"REVS\"}" # 1.42755666 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDjcC2MNpawEZgq2JTK4Cc9DTNFMZ7PsSh\",\"symbol\":\"REVS\"}" # 1.43201326 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDCsAhpcZqpdZCWigdM1ujfeQmCAHbfPfc\",\"symbol\":\"REVS\"}" # 1.45874046 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPhBpv2cQ3WSMNzqmUb86ET5y7jQ7DPD2T\",\"symbol\":\"REVS\"}" # 1.45929382 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPcHvF4jEty9qqKfYeNjTacBhLKGb2ixpt\",\"symbol\":\"REVS\"}" # 1.47310188 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLpaETsoZj52HBbAW7rHANBg1t2ttySPQb\",\"symbol\":\"REVS\"}" # 1.47750626 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSF8gGSix9untMctXB3G2vrfzWyJzALu6V\",\"symbol\":\"REVS\"}" # 1.48250000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHxNWVSRdyVbomaVBWVuzYnS3RKZzWuxFg\",\"symbol\":\"REVS\"}" # 1.48653046 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRVrfwgx9x7gkZER1yrhR4a4Pk2gs8udNV\",\"symbol\":\"REVS\"}" # 1.49702366 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bNaoVTFpRaXnCgb5vBtAXbZ4pXvHsySb3J\",\"symbol\":\"REVS\"}" # 1.50000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGsQUfcFvZLZdwmKX4aZvunTxbwKx8yccM\",\"symbol\":\"REVS\"}" # 1.50780573 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS7UtKWKAnp51Mqzkfb9zFus6g56V6VzxS\",\"symbol\":\"REVS\"}" # 1.51352332 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMqbEGZBu1iXQErb2r8mBdRHJYLWnoP5nU\",\"symbol\":\"REVS\"}" # 1.52457228 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJBUEVzgvSw4HF2vVvhjecADHxWCGhSjr2\",\"symbol\":\"REVS\"}" # 1.52864745 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ4u4DgxYqMArpfp96hTy5Srx87hyc1J7C\",\"symbol\":\"REVS\"}" # 1.54124286 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWZJ8JjYJDjt6kNRLBEQq1aeR3juoKrvPU\",\"symbol\":\"REVS\"}" # 1.54585135 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFkLL2xf4vsTiajnRevya9TVcQyHFTsKiQ\",\"symbol\":\"REVS\"}" # 1.56358736 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ1VYwz6fV6J5KVKmgutCwyeSfb7Xv1No9\",\"symbol\":\"REVS\"}" # 1.57797376 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVBqRSC7BH5QYoqF1cBLDxceG74n5fMJ34\",\"symbol\":\"REVS\"}" # 1.57905079 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBBHBNytzvyMyDhR24noVBAq9uxZKxLAeh\",\"symbol\":\"REVS\"}" # 1.57927229 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bGudHujZahqnRJvXC2VCSDnczVHgEPh1Wa\",\"symbol\":\"REVS\"}" # 1.58700000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFtwVS6TN2Aq1CsMuBmM6o5QMaVMTfMsCg\",\"symbol\":\"REVS\"}" # 1.58954872 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCJnFAfMno28iC6Xnia49LSdUn2WRkLRpU\",\"symbol\":\"REVS\"}" # 1.59419732 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBGWmHq9rvFzabmacwXxnTCr7YEX4Jrqod\",\"symbol\":\"REVS\"}" # 1.60046674 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9j9cH2zvMmPFdB9pcwC9zXwicSPP7pwE6\",\"symbol\":\"REVS\"}" # 1.60400995 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNkzqWHi5Dgg96F37YpeRDFGqJrxRfbBnH\",\"symbol\":\"REVS\"}" # 1.62257668 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRTinbg9zaegzof3twiJxSNuBnsHHgZaEQ\",\"symbol\":\"REVS\"}" # 1.64318216 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGniivvshN6EVGUKZRF5EzBsqKxpS93RJm\",\"symbol\":\"REVS\"}" # 1.65639919 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXpDee4SEiY9rhfxoEgdC8PVWsbqdEZw1k\",\"symbol\":\"REVS\"}" # 1.69773342 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bPXgssSE8kC7Saoj7L8u5Pe1gJut7tvPb3\",\"symbol\":\"REVS\"}" # 1.69910000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRjVysht9ZeeSkSMbf5JDQJPcJyErSAjcg\",\"symbol\":\"REVS\"}" # 1.70322869 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFRM37qFvntM7TPqrAwYNAy2y5xqn3dGpr\",\"symbol\":\"REVS\"}" # 1.70656263 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bNXWWWqNtTXD5GmxK19eZcSMgrxN3VDboZ\",\"symbol\":\"REVS\"}" # 1.72734851 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bPY6tFSkLUzQAkadwvimYc1spsxXaEYbae\",\"symbol\":\"REVS\"}" # 1.74189851 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPBdNsv1HHwgeeeEJo7qT7nM6EVA2rroso\",\"symbol\":\"REVS\"}" # 1.74888552 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bZG7wd5BaUwzY1bNGuqqFnjVMvMV4SmEut\",\"symbol\":\"REVS\"}" # 1.74920000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJrkgeBFbfs6oLMyoJXsskADQPjKYQ6Ftb\",\"symbol\":\"REVS\"}" # 1.76577984 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUtxrXiAFq1oqg8fqvJ1Ax2CX4BiM1dy2Z\",\"symbol\":\"REVS\"}" # 1.78316624 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXW8GvCBxqkzZb3kHcm55ormZTa3YL7q8C\",\"symbol\":\"REVS\"}" # 1.78616541 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc\",\"symbol\":\"REVS\"}" # 1.79820000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPBXkDU4Vu4N8B3FXGDgghtT4rqgw12vTW\",\"symbol\":\"REVS\"}" # 1.80744276 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXb9E377iq3CZNMJ7aSUauoMZWMButpA3j\",\"symbol\":\"REVS\"}" # 1.82576189 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH2kRVyri99Nt6UWTpuXmWda9ZvtiEz6xX\",\"symbol\":\"REVS\"}" # 1.83128234 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCs9Sqe99sRDD3yKCfY39VvShamcGXXSRD\",\"symbol\":\"REVS\"}" # 1.83578804 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVufZEJRVw3UTKRjVApXfZgzxW8JV24nuw\",\"symbol\":\"REVS\"}" # 1.83846574 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWE5VQQ6oDKGyXJxWh3FPQ7RFJFiZWDjYN\",\"symbol\":\"REVS\"}" # 1.85417492 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQygqtXQJpngKZ3NM5MbeoByWbHyNGyJRe\",\"symbol\":\"REVS\"}" # 1.85486597 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWTYpN5VBTSXjgbdVACNiyFULRPoLvaV61\",\"symbol\":\"REVS\"}" # 1.85972528 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bKeuwSTZWjWm87vJpYpy3eCuFJmWCrF38v\",\"symbol\":\"REVS\"}" # 1.86222005 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHMC9tBFYL8Fb7zJUm81BD8oM6Uzu2feAb\",\"symbol\":\"REVS\"}" # 1.86531877 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRb1eZNQo8mxgKtFEQbWsEycUr4Pbik7ha\",\"symbol\":\"REVS\"}" # 1.86735991 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bDtewFRcLkir2cf9SRPyPTYQug8DyF6xfi\",\"symbol\":\"REVS\"}" # 1.87282410 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bEL3j9hiN7DtaCHTGB4q825MNvnm4wUDoh\",\"symbol\":\"REVS\"}" # 1.90359999 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNDYvqLDMztos8BPkvKxVHccsmE8QvmNub\",\"symbol\":\"REVS\"}" # 1.90641705 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXHWasBG7RhWDysy9YgCFDcWcdqDYS7tbb\",\"symbol\":\"REVS\"}" # 1.91990000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bZDxcTBZ78TmfANqEe9p96FFEohgCYt8iN\",\"symbol\":\"REVS\"}" # 1.92178425 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHaXgjxZU8v5TZMtAs4hEw3WWchjnTdYGr\",\"symbol\":\"REVS\"}" # 1.93088161 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBeSgf3owwzrjSiKQfZQPeYUkiFF1HNHME\",\"symbol\":\"REVS\"}" # 1.93308711 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bYjsXxENs4u7raX3EPyrgqPy46MUrq4k8h\",\"symbol\":\"REVS\"}" # 1.93456780 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REtzrDguaT4m1hz9JJNBrhWxamfCG1kjQn\",\"symbol\":\"REVS\"}" # 1.93727166 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bDCZH7qzJ8nqnsiLq1123VAd4Wgd3byR8q\",\"symbol\":\"REVS\"}" # 1.94455537 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLbo3UjWv9bT45RiYZwgrJ9bP29QDAN81B\",\"symbol\":\"REVS\"}" # 1.94599612 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQfScf1meLqV9BRDo2QuT5hbQpienYF5i9\",\"symbol\":\"REVS\"}" # 1.95091094 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REf51DyPU7kyk4S88Ea7vD5wTADKaRAZXr\",\"symbol\":\"REVS\"}" # 1.95304633 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW21d98WXt7XXNGDAZxG4VByLTtzEHekWj\",\"symbol\":\"REVS\"}" # 1.95600000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCrzyCkHN235TGnPeNcUvhm6Pk8EpeJQgx\",\"symbol\":\"REVS\"}" # 1.96000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQiqMgNyVqaqetsgosDeP2LUFKVAm5Nrwp\",\"symbol\":\"REVS\"}" # 1.97995553 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bKB5RdkKnHKKjzQHnonvf43PWMkTtB7K5u\",\"symbol\":\"REVS\"}" # 1.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ2Fs5ymVobuQ6A8ttQTCfxNfBETNoZ78t\",\"symbol\":\"REVS\"}" # 1.98088848 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWRAwwHiSGdjkGNbDfw9exEHifuwLjdJUW\",\"symbol\":\"REVS\"}" # 1.98200800 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bE6fVmnjfLRjfr9Gq86VTuNCoc86JhAHgL\",\"symbol\":\"REVS\"}" # 1.98620009 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bRq5CJZwSgb3k2aCXBLzDCRTP2HsLGmSph\",\"symbol\":\"REVS\"}" # 1.99000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWCADpdrQZCTiyo8nfGqQ9siUBipet9zrx\",\"symbol\":\"REVS\"}" # 1.99959601 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTvcjHngNQKXaK5NjPcH7Wssin7hvTkZ5m\",\"symbol\":\"REVS\"}" # 2.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPJjzoKPb8idoUCT9XLBkNojNgysjJ5qrE\",\"symbol\":\"REVS\"}" # 2.00090000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE6qPxVbXsF8kFUSzgXQM6VQqm9SWrJKLo\",\"symbol\":\"REVS\"}" # 2.00365927 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJrVCN7kMqVx9jVC9He1MWR3MeGViHsg4e\",\"symbol\":\"REVS\"}" # 2.00980787 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVkeqmBucdaG9DTLbYanHZ8KzLkp7pFDkp\",\"symbol\":\"REVS\"}" # 2.01242056 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHmXxYpYVRSM4uoaKb4iEQHMQLcs3Vjrik\",\"symbol\":\"REVS\"}" # 2.01293993 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bE6nkWV2BF5YWKwmHrirDPVQLAjj55S84m\",\"symbol\":\"REVS\"}" # 2.02380000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bKzDfRnGGTDwqNZWGCXa42DRdumAGskqo4\",\"symbol\":\"REVS\"}" # 2.04990000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKxm7MdSse1JtHY7XBn3uHh1AJTT939DKu\",\"symbol\":\"REVS\"}" # 2.05575531 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLGKaQYUEbafkm9kZKemQ83JkhUFF4uZ4u\",\"symbol\":\"REVS\"}" # 2.06173997 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAkyFUu4fEXtpUuGDbzcjM3DSny9tiVzAz\",\"symbol\":\"REVS\"}" # 2.07064827 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG3F4QihQgrKpHk5RsBwnCwDAds5rLLWqW\",\"symbol\":\"REVS\"}" # 2.07695299 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bV2A8j7JJJxpRuW1M1hUSfe9n6UEXQHEvR\",\"symbol\":\"REVS\"}" # 2.08000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJT3MMQdahmsQzKMRUCfci19gJrUE9TgFb\",\"symbol\":\"REVS\"}" # 2.08312949 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXzjUGvZ7oUrUTGaN2mP4aJSbLbqzpRnz6\",\"symbol\":\"REVS\"}" # 2.08564650 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFJuCQAevqPqVDBGbBruMRRub72WDCiMeK\",\"symbol\":\"REVS\"}" # 2.10001000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REvjSkX26zyPX7HgM6RCJgvkYjSLPdCZTn\",\"symbol\":\"REVS\"}" # 2.13044119 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKJzUA4MvdFQ5F9PGWHaxkcEvXCKCGg4VR\",\"symbol\":\"REVS\"}" # 2.16410519 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGzoukVA7fHUD6Nds6USQFsp4QkWjsBh8B\",\"symbol\":\"REVS\"}" # 2.17894706 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRZARxvCqWuH5H4crSc6KjN6HFYfvGJ8Gg\",\"symbol\":\"REVS\"}" # 2.21090900 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFC81cLV3sGMmqbCUiVrkBTGAXnHPg2V3K\",\"symbol\":\"REVS\"}" # 2.21844875 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYYbrxAnF9szAsTitPipp9p4X2f5F37ZF3\",\"symbol\":\"REVS\"}" # 2.22917835 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bNEy6y2USZkmXfiWb7dx8Sg88rVJqfnunF\",\"symbol\":\"REVS\"}" # 2.23217506 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWZNekyWtFa3qP9poAyKN23tZdvZFNG9hS\",\"symbol\":\"REVS\"}" # 2.23284202 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bWywMc6kV1G5x1ZJZoZxE7UJB4b2R9bbMD\",\"symbol\":\"REVS\"}" # 2.23548655 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPf6z9yuQNg8gP58GYzgjSaLsq43UQ7oEx\",\"symbol\":\"REVS\"}" # 2.24946914 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXPVEFk8NjAaCjyaSXkjo2dk8ZMiMCJWWn\",\"symbol\":\"REVS\"}" # 2.26061327 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bTUSLAm7UEij24FwUZd4TKFwvKVGDTPfyT\",\"symbol\":\"REVS\"}" # 2.26307039 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSb5zwsBoTK1UkHTqFwTiPeeGVfacNztFo\",\"symbol\":\"REVS\"}" # 2.27998400 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBTgQUaUkU1oRMusrGUKHCQVwkJxqoJBCS\",\"symbol\":\"REVS\"}" # 2.29718810 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFGfsGR4u9F7UC2VtxDHH5dWR53gjfucrt\",\"symbol\":\"REVS\"}" # 2.32198080 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bUS5pwZBM744sY6gsaWMb9kNQHCb8U7MMs\",\"symbol\":\"REVS\"}" # 2.32918072 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQykFxhNuBbGdGdcCp3kRrfK77NJ4fe2m9\",\"symbol\":\"REVS\"}" # 2.36204605 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPp4fcMCnznHNAAfT3mVCK8sZLit8ULWqy\",\"symbol\":\"REVS\"}" # 2.37664696 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRL3L1M9XZD2iRtScPAyT9tN3HkAtAukmZ\",\"symbol\":\"REVS\"}" # 2.38743361 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJtuUb8C9LVj8pwMNHhjHYVfz6jLvLTQTQ\",\"symbol\":\"REVS\"}" # 2.40912026 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REVK99cVFsMupSPgnn98b35jGTARiyJMUA\",\"symbol\":\"REVS\"}" # 2.41992887 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REoZHPTDS5EVS5LZbt14JJK3KsLinWGWcs\",\"symbol\":\"REVS\"}" # 2.42156948 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTRByU7B58URFDFJ3dyBeXP6xhyXQ68N5F\",\"symbol\":\"REVS\"}" # 2.42619962 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUS9xjmpzaEr8w765Lqs4uvf5f4VV9Kwqu\",\"symbol\":\"REVS\"}" # 2.47000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSRzzNnhMX26Jb3GKA1QjZM4LXkJT2mysH\",\"symbol\":\"REVS\"}" # 2.48509167 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT3N8cQ3u51hu9yDfEVrKQDQwW3cXEqnq5\",\"symbol\":\"REVS\"}" # 2.48874638 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9TYuUNUywNVrE8WFM6FNnr16pJy7bbTnv\",\"symbol\":\"REVS\"}" # 2.49146775 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNKrApCguSxc7R2RWRZ3QaNTLCoT2qfovw\",\"symbol\":\"REVS\"}" # 2.50000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWRoTk9tdhdiusKK8ZYx2H7zvoeMCG7nEg\",\"symbol\":\"REVS\"}" # 2.50725545 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA5N2WrysZJqLNrocm9Ub7eFtgRuEpChb7\",\"symbol\":\"REVS\"}" # 2.50897343 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bUa9ZggkafUny4QdtBbHRWZ6ooPJyo7ms5\",\"symbol\":\"REVS\"}" # 2.52752023 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQYku4fpqpwt2wdMGNpabeDtTzQA2kxjef\",\"symbol\":\"REVS\"}" # 2.53994527 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRHTYjv9UDm7fn3bTmc37DwqpvUsoj5kQY\",\"symbol\":\"REVS\"}" # 2.57131849 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL4zAeZBg5GHhbQ8TmqEcJQf8YZesmWZdt\",\"symbol\":\"REVS\"}" # 2.57411256 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bPFABV7tn7YjKiiT6JRt86kwFc1XFmJeGV\",\"symbol\":\"REVS\"}" # 2.57541784 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCFsvyxWvorh54XBr3wWYs4j6huDUXRPp2\",\"symbol\":\"REVS\"}" # 2.58877500 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVTMKYZDgpu2K6EJePhwXbfXyF2HJSALjn\",\"symbol\":\"REVS\"}" # 2.62725726 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REGmmJTUg8s5xD85RLinEBSAHhsMvmXHRa\",\"symbol\":\"REVS\"}" # 2.63202023 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDqXcW6f7fXWELD8Krd3hQhyRv85BbknjY\",\"symbol\":\"REVS\"}" # 2.63206417 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDuK7tiVG9i611zudsKAs5xiycRDLARzz1\",\"symbol\":\"REVS\"}" # 2.65449250 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ7tPLopmnk2w6MqvBNPxs4upARiDuLs1w\",\"symbol\":\"REVS\"}" # 2.66827444 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHvoTnReTrY7FjXZcRgjyZGraAPAFFPCqR\",\"symbol\":\"REVS\"}" # 2.67580000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLsZsXxoHF1GTmWavAT1nWE4F5X9XgaRp7\",\"symbol\":\"REVS\"}" # 2.69784800 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUdtBYhwwmJN2ioAYamNDE9eixUFiQUasK\",\"symbol\":\"REVS\"}" # 2.74269645 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL4c5XhjvnQzijV5yAAd5G4oxCDsnTwjtS\",\"symbol\":\"REVS\"}" # 2.74873446 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCsPHNjrhL7r1cWhgey35WZU61ksWnHjC8\",\"symbol\":\"REVS\"}" # 2.75509594 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMihEZdA5SJCshcEmJ1cfYy4gKjpHMbGjC\",\"symbol\":\"REVS\"}" # 2.76003097 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWmaVVDurBiZxTwkJ1LRWcS2CKj82BVab2\",\"symbol\":\"REVS\"}" # 2.78395528 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT1XUGeJGzEEkwT3i3GjGXtcqq47eRCM75\",\"symbol\":\"REVS\"}" # 2.78844263 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHybv6nbE8QTEXT15CyNc7wUXUb3RrUEY9\",\"symbol\":\"REVS\"}" # 2.79749605 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJbQhJLpn2fWmEdxkrNfjU3EAcaFwLKYja\",\"symbol\":\"REVS\"}" # 2.83312566 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RACaaDhrZWEgD95PKbr3A1Lg1uKB75qQVG\",\"symbol\":\"REVS\"}" # 2.84063548 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY3Ym6WDHTXHwSuWTJ7Zv3pCsJU2jDVKAZ\",\"symbol\":\"REVS\"}" # 2.85660204 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REwEabCzgasGBpJ1voD9G3bEi6o7yxppgF\",\"symbol\":\"REVS\"}" # 2.86976420 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJXovSo5a7RwQGsTgkcSmvbMvW7zy8DJbZ\",\"symbol\":\"REVS\"}" # 2.87000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWtKSzjTPw3ArK6ooCcAdSVaU4dzrULQs4\",\"symbol\":\"REVS\"}" # 2.87997775 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGaswcCVFmxpZM4pcEdkP68LFiKwEAsLW5\",\"symbol\":\"REVS\"}" # 2.90824900 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTVYgG6JfeAgqXT7xmFZa4MPu4QwWK4woJ\",\"symbol\":\"REVS\"}" # 2.99000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDdRQ5j6LVspHfwcHeL21er236MvCPSj89\",\"symbol\":\"REVS\"}" # 2.99158800 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ9wS5HjveiXqBXaxwBCao32L9ogSS5s1m\",\"symbol\":\"REVS\"}" # 2.99206721 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVfEv3qesfVXdJYRjPLMwQRGwfCxSNVnPk\",\"symbol\":\"REVS\"}" # 2.99604321 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJZuURSaU6vCto4MJgeDrEiYDPNvibvuwz\",\"symbol\":\"REVS\"}" # 3.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDvk2puiR9d7xGLg4yddUsLHxBEQ6Q5GG3\",\"symbol\":\"REVS\"}" # 3.09347716 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REjUEkSoC1SsLwnU1pGhYH1zs8DRqVUNRk\",\"symbol\":\"REVS\"}" # 3.12909427 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBWWZxY7eUn5w1gCxHhyGkzNKpXBzVP4xF\",\"symbol\":\"REVS\"}" # 3.13259544 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bNFpwB3Wpy6TYicuhJ3TVMuhWdjERvazcD\",\"symbol\":\"REVS\"}" # 3.13612794 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPm2iZjtCR4iUFGJmh5goC4WisemznUrF3\",\"symbol\":\"REVS\"}" # 3.17226153 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJLdH7y8EMuxGoJJuQDRwhQqg64AcyY1FH\",\"symbol\":\"REVS\"}" # 3.20101972 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bbxreB4NRa3N5ApXFCvEm5MD6FnpjtS78a\",\"symbol\":\"REVS\"}" # 3.22895411 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBgnekdZTPXo8HZwFw4pTAXZhH6a7MJhR5\",\"symbol\":\"REVS\"}" # 3.23482598 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPLa6HQrRdXbHwfVbWzbSPg8sw26s7zW2g\",\"symbol\":\"REVS\"}" # 3.27749623 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAEXYhfEXRDuRB4ief16ZoDiGNYoBP4DC5\",\"symbol\":\"REVS\"}" # 3.29504240 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bQLtNMSxwgWf7FRvkdvGWLWPxbHDYUnzgf\",\"symbol\":\"REVS\"}" # 3.30380000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFcGPCy4ABXnmDuhhzTwUyTGFthnrsbxqZ\",\"symbol\":\"REVS\"}" # 3.32146226 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bZy1RXoHG7rTgDcKerym64djkRSbHhqFrg\",\"symbol\":\"REVS\"}" # 3.42157328 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPRqxGLZFiQwEpKoFeq3pA9YTDNQZgjw3y\",\"symbol\":\"REVS\"}" # 3.44064699 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW9RK2gP4uwsdLd9vtLPuyqKzwR1hDG63t\",\"symbol\":\"REVS\"}" # 3.44524832 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQqTgaoSLVFwZMAa38uJ5hXJFPpiuiNsgP\",\"symbol\":\"REVS\"}" # 3.46075137 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCe8skL8hbBG3vMDqLAh3UNVQ1xhGaFhqD\",\"symbol\":\"REVS\"}" # 3.50025765 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ6a9R3MMY3gLyB3juFejLe6d4VJ4nseRd\",\"symbol\":\"REVS\"}" # 3.52343620 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS5iwgvZF2K8pMrZWQX88St5RXowK6rL2D\",\"symbol\":\"REVS\"}" # 3.53209615 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT1JF5w81bD9VPo2tZtGRYAavTY2A3aN3w\",\"symbol\":\"REVS\"}" # 3.58176650 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REtMhx1eqgAJCWi8ThEQQsSqP6xRi62Dka\",\"symbol\":\"REVS\"}" # 3.58484457 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bDG89EsDs9o7h4Q9mjSVGRsW588dAUdrqd\",\"symbol\":\"REVS\"}" # 3.59331365 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS7hg4amfzoFuaQt2eTBZDqm34zrQKLLW2\",\"symbol\":\"REVS\"}" # 3.59958961 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPQMSMtdUdRSqx8JN7vaAQfajbwC4zHM3d\",\"symbol\":\"REVS\"}" # 3.60890805 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPHMzajSnHaDRXts3L4RS5BcJikAvS7T59\",\"symbol\":\"REVS\"}" # 3.67122767 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHwMwj79Aq8Tpa3dXNdUNr8eTWWqquCUkr\",\"symbol\":\"REVS\"}" # 3.68495362 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REHJPWZr4RKX4sRXt3xyPaASuP9Uzfcv4m\",\"symbol\":\"REVS\"}" # 3.69478143 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9NERQaSneNLBGd3NowTvmhaJizjdjVu6n\",\"symbol\":\"REVS\"}" # 3.71517590 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR8Wsp5DTn3rmR4531kbbPYZTQVXZoCwm3\",\"symbol\":\"REVS\"}" # 3.71915767 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKi5WEbiEQkPRJdwv6RsM5hRqByLTmoEjC\",\"symbol\":\"REVS\"}" # 3.72300876 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGo6pr1kJwnmy7iqkhvWtSDBLXrhACcQVa\",\"symbol\":\"REVS\"}" # 3.76892503 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDVHSwjjbmvRQ3pkNJxQPSQZwGzoTeNy2S\",\"symbol\":\"REVS\"}" # 3.85839309 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bHTnZNnT4BN7CcZu86XByARSzHgx9VBbSk\",\"symbol\":\"REVS\"}" # 3.89492068 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYZdCN4hvqaffVUk6dvXKvXdVnoc6DsSW3\",\"symbol\":\"REVS\"}" # 3.90798966 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bWVvhfUNUZqukaLKF6v9vVxMBk5EKzvo2k\",\"symbol\":\"REVS\"}" # 3.93362425 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bTGYQFtwHc6jaxzhDgNVAxLXqgNvGBCTRB\",\"symbol\":\"REVS\"}" # 3.96787567 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGcgWanVKKdNn3N5SJ8riiDzoCqhqdFaQD\",\"symbol\":\"REVS\"}" # 3.99083039 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRiMVwZGskYaNKQ5U77ygt7GRhzFquSWJe\",\"symbol\":\"REVS\"}" # 4.01959642 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCx6Ts9V8gRV2WExzQeGP5cnWt2mNmwerj\",\"symbol\":\"REVS\"}" # 4.02463493 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHMq3Q723zevaDTk6EyPdFUvnSb4D7aFVq\",\"symbol\":\"REVS\"}" # 4.02943320 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNjtvMBfE5gyVvpiHdZqnWz88xnQ87mTdQ\",\"symbol\":\"REVS\"}" # 4.03000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bLRp614oYpZCvJ3PjJpJG9Kw4GQBh9ui84\",\"symbol\":\"REVS\"}" # 4.04690001 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVhGrmQKc3kE2oWfGKEdcAq6FLE3MBMmah\",\"symbol\":\"REVS\"}" # 4.05228522 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RExi2qBNpP2FxV4fGyJ7krVwdX8kSV2fwV\",\"symbol\":\"REVS\"}" # 4.07342248 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRNZsaPb8rMEtkj9LQ4dUDxh8K2E3ntL1i\",\"symbol\":\"REVS\"}" # 4.08531176 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC8tn2whAqacHxxGjEvYLG55tAFvJDz1j2\",\"symbol\":\"REVS\"}" # 4.08862550 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWhwxSbibcQYKa2PkyVsQArHa1tjp8dpt4\",\"symbol\":\"REVS\"}" # 4.10310990 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJUX3LKJwnCaTREMr1RUhbpTbQWsKhXmZX\",\"symbol\":\"REVS\"}" # 4.11609401 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV1xc2KHBTmj6LTRKLah7QBNGyXz71DhVn\",\"symbol\":\"REVS\"}" # 4.12372278 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bSUjA8hYfQsqHPL5RyVruY9shnwy6aNzmR\",\"symbol\":\"REVS\"}" # 4.13948139 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBspRqZnwNUKExmwX8wvbL3pK9FW8zFLzv\",\"symbol\":\"REVS\"}" # 4.16600446 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN9JkMyiug2yyk6uvHU4x7bYc1gRjmT99Q\",\"symbol\":\"REVS\"}" # 4.18806510 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQZ6yUnLwG4KxZWgHSjsysP55ELTQwgbFu\",\"symbol\":\"REVS\"}" # 4.18891770 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK9eGduosS7qaqdK4WBdV7ekuErkcu1fmk\",\"symbol\":\"REVS\"}" # 4.23609095 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bQw3mN168fQuBpxzrt3ZvNoaTmBEpj8UCs\",\"symbol\":\"REVS\"}" # 4.24456392 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYAkmpmghTXkzutKuHNWveQpxBUfpajbKn\",\"symbol\":\"REVS\"}" # 4.25843165 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUuDFrhMXYowVRvAPxJ23iqW7JUtTFTxmS\",\"symbol\":\"REVS\"}" # 4.26075162 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGsWp8uDpeaJyfe2BqBr6vPmZCkoPwcPAQ\",\"symbol\":\"REVS\"}" # 4.27803826 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGJ9g8tP6T8LyWBp2giQUYwxD39xHi9bHT\",\"symbol\":\"REVS\"}" # 4.29251906 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"symbol\":\"REVS\"}" # 4.31860001 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRXvDgiJ6wtCVWCjfqe7KHFkDFZDg9SmLr\",\"symbol\":\"REVS\"}" # 4.32375278 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSY8jJJ7NRGvFr1gmvL7XTAXZuCTro7wgM\",\"symbol\":\"REVS\"}" # 4.32644404 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPte7o9GeSdfJsHVPcYw6BiHkcZ7fV9NQH\",\"symbol\":\"REVS\"}" # 4.32771484 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWfmdid5JYnf7TeaRV4gGLV7NLAcLhZT4R\",\"symbol\":\"REVS\"}" # 4.33826339 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFXuXXffSu6PpVxw71WYyAYH2gW9ziB3is\",\"symbol\":\"REVS\"}" # 4.36956575 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVRNfEidMxZRfCwLjaJGsVpEtrzr4tzH7C\",\"symbol\":\"REVS\"}" # 4.42288273 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS1qbKDxj7rFbwuJR17k9tqEUfeQQztYEY\",\"symbol\":\"REVS\"}" # 4.42527774 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRLuPbK9qzz2rLVYRbVqe6z2zYpx7dYVHM\",\"symbol\":\"REVS\"}" # 4.42965965 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJtisakm5oUkdJQZHJMDz3FZDsjWZHR7Ps\",\"symbol\":\"REVS\"}" # 4.45700001 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGQKqoiFKZVrAqoo6F88DnHCoX8JvvjUHQ\",\"symbol\":\"REVS\"}" # 4.48512493 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9yXurqBmnjmpKuDkuRtkLTf3951ttGdsc\",\"symbol\":\"REVS\"}" # 4.48859816 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLFLrKx8tpsoUi3YGaWR5UfebvikBENeZU\",\"symbol\":\"REVS\"}" # 4.50632723 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHW1uX8E8VMCDwBRy3jSkQsQGS4n1U84uq\",\"symbol\":\"REVS\"}" # 4.55672414 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAfvHP5Ew8iUd14xWa6CQWPYdR11V6F2pm\",\"symbol\":\"REVS\"}" # 4.59747581 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTdg93uKWzpD5JNJaAAV5zKtufasdjYNK5\",\"symbol\":\"REVS\"}" # 4.64825892 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXbdbm45JL6kSvy5kGdHZ4CFVi9CnEHWgm\",\"symbol\":\"REVS\"}" # 4.69035736 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDPZaeCumMyHb1mdGvxNriZWHq3r6jjKQE\",\"symbol\":\"REVS\"}" # 4.75309658 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBVL3L5V3MxwuAAuyBjDeL4ywZ63ipGJfm\",\"symbol\":\"REVS\"}" # 4.76661661 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVepoYFYbX9R8pSNs83jaReqtBVcESPKQe\",\"symbol\":\"REVS\"}" # 4.80115071 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bP7vFSRNbFdnFRUZFe42H89L8AHJSaarL7\",\"symbol\":\"REVS\"}" # 4.86350000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJB2BvB57Pf3DiGWaKjcYGqRBP1YwoCzBT\",\"symbol\":\"REVS\"}" # 4.90780000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCrZNMtJm7PG44s9rZ6WwfntGzV6RngoAK\",\"symbol\":\"REVS\"}" # 4.91402989 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWHonVjmsX5LF9MpWHh35XWfMGfQcceCLx\",\"symbol\":\"REVS\"}" # 4.95706575 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHcRQFGpsSwvUN7C8Z4SvQYLZMbs5Ugz6j\",\"symbol\":\"REVS\"}" # 4.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLytuweJthPvjHY6erv3owjYZg8rmMkS2F\",\"symbol\":\"REVS\"}" # 4.98780303 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA8vVLi9D7kzCw8wcvwPmne3XJjdjPqZf1\",\"symbol\":\"REVS\"}" # 4.99686523 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJJ4BtUdgz4QwSK221VyDNku9qBUsxcN7k\",\"symbol\":\"REVS\"}" # 5.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNq9ZvNxAgKnPkGfho8DoLUTsSGSEjxdhd\",\"symbol\":\"REVS\"}" # 5.03909090 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQGJuEfE9JJsrcxiqXDugafTfUuGGcK4gP\",\"symbol\":\"REVS\"}" # 5.09814157 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA6XsEerNDRaC1M7gVtRYANafh14rWdHNw\",\"symbol\":\"REVS\"}" # 5.10658589 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVwAm5E17BVxiEjNc6XUSmZg3pBWWvQxUL\",\"symbol\":\"REVS\"}" # 5.16105657 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXcUfGadc61jpm8fsDz6p2fj4zSn9BmWGu\",\"symbol\":\"REVS\"}" # 5.17217723 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG6gYZMxdNWkDwz31E1xSA9DUipcBCCrZq\",\"symbol\":\"REVS\"}" # 5.17336848 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bY7sNbdVUaV9jnq3WJsJknypqRuymd2NkR\",\"symbol\":\"REVS\"}" # 5.21561285 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQtTteK9hRnDo9HR4tJgW2jJQdg6cGaLYG\",\"symbol\":\"REVS\"}" # 5.26062962 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFcGSUKjSX3AtCyaF9hZn3TUuUWUuzJjV1\",\"symbol\":\"REVS\"}" # 5.30055325 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLLS1GnQ928Y93iPzEp7P3kAbkLi1Si1P9\",\"symbol\":\"REVS\"}" # 5.30359561 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REQnuF9xcLFN4giC4JFK6xcNAtj5DmoyGs\",\"symbol\":\"REVS\"}" # 5.31130764 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUJYuNkziiJQyfjbK2p6XZ7BLjwTs8Qvmj\",\"symbol\":\"REVS\"}" # 5.33867197 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bTL1aHX93V9YKzoEJ5mMkhq8w1isPsdjgD\",\"symbol\":\"REVS\"}" # 5.34256292 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMWmAAyeYRTXw2FrZqJ2Tnt1Y6va8za7MG\",\"symbol\":\"REVS\"}" # 5.36719392 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"ba6xGsVQBhoSfsuePXNeRLqVRNsSwrVhYM\",\"symbol\":\"REVS\"}" # 5.37647634 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSoRZxg2hfBqeSQNYGtpHREj8Hs4hr31AQ\",\"symbol\":\"REVS\"}" # 5.37745371 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bMB4ECM8DHhJd4YP5zzktoyDsr5ZXsBxro\",\"symbol\":\"REVS\"}" # 5.38691659 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVU6vTgkE64z7TXdhEWS4qJ3TTiELeDJjz\",\"symbol\":\"REVS\"}" # 5.40441340 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDiLF8GjeWpqUGn49oQbJxV26v3nEt9sAR\",\"symbol\":\"REVS\"}" # 5.40540711 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJbFz9QxGgJZ9ZzYUA2gsrZV7KrK9P9RNa\",\"symbol\":\"REVS\"}" # 5.45916020 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQHpFq2hP1DKsdzMMqm3mgs1fBWNrr8VMd\",\"symbol\":\"REVS\"}" # 5.48588608 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVh4vRybmr6vdtcJYSxbhtbkHXEzmJfRJk\",\"symbol\":\"REVS\"}" # 5.54283710 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRdvTNkiqDL5RyifpFSMynCoPUQEo9b82w\",\"symbol\":\"REVS\"}" # 5.57804444 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bY96rJtT6E5Hsu8kUWpPLwZkQnNTa3vugQ\",\"symbol\":\"REVS\"}" # 5.59161129 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9aKC9fDGx7FCsEGRgxqhUeKbGx1NWUzYb\",\"symbol\":\"REVS\"}" # 5.63387351 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVCEeszwRkLz97FwuvxcWBMzHnWzVXBiZj\",\"symbol\":\"REVS\"}" # 5.65838637 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ9hR9mDHaFR3aCDjXvM9p8A7LjvhsL4bB\",\"symbol\":\"REVS\"}" # 5.67842818 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bWf9LMCfvscafJbkFdmmGxYVTkyWtayaBg\",\"symbol\":\"REVS\"}" # 5.68573823 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLu679Jerpk4TRdB4JEBeomKHxHKpHtAWD\",\"symbol\":\"REVS\"}" # 5.77791739 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCfxaAv2aqftKGq3yx2bXNtYsp5DVPGKAa\",\"symbol\":\"REVS\"}" # 5.78934941 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXevAUM5QbSUWyyUcNkQGbLsxRPnQagaAf\",\"symbol\":\"REVS\"}" # 5.95388731 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bLvqs86RAZA4z7pPZgWk3JUDSFhzYH1gkz\",\"symbol\":\"REVS\"}" # 5.96138993 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTERUvGEuKjv5q5HkrZumQ8jT4iieAvjxB\",\"symbol\":\"REVS\"}" # 5.97079602 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REWN11YhFm9FXuA3UjtiE4MWNytdF27ZPB\",\"symbol\":\"REVS\"}" # 6.00558341 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUajR1po4RwaW8AEBSYvGuTQ7wTFfXUDSB\",\"symbol\":\"REVS\"}" # 6.02345907 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJY7DSYsS4T5xHFJsd2AgaZtPZVitXYRJe\",\"symbol\":\"REVS\"}" # 6.02384480 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bNAG2b3hsNqMZjtp2Nsx82AK2ZYzxECdwb\",\"symbol\":\"REVS\"}" # 6.06434319 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTfUWsozDr1UyzGkqLCjf8Gcy8RX1nMZii\",\"symbol\":\"REVS\"}" # 6.09834713 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUrP8wAG9Q3AWnXoQ5GtQQeHYzED4z6Fdg\",\"symbol\":\"REVS\"}" # 6.11569832 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHh28ETXZbxRr115cuwviah5rYREQhTX7G\",\"symbol\":\"REVS\"}" # 6.15465639 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJMjSghHKjSxUju79ZEFfotF3U3VzWjMuo\",\"symbol\":\"REVS\"}" # 6.15607830 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REjW5f2tDj359qPfohXJTuQmQH4fygXo3d\",\"symbol\":\"REVS\"}" # 6.15875877 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF2ECSJgGiwUNsyJkgmQDYfvKJatFPfU5h\",\"symbol\":\"REVS\"}" # 6.17851917 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNSzg9StyTZCtpHkQAC6ZkQWxMYiR9k7hT\",\"symbol\":\"REVS\"}" # 6.18106775 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTZEL1RZ4SW1UvvYNWTDWFbjdx7cPzuo9V\",\"symbol\":\"REVS\"}" # 6.18142560 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REmhyAviaF38EVcF4AGekv2THdpk5Ygiuz\",\"symbol\":\"REVS\"}" # 6.19264761 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAgLdxBGDkzE7uBXAgbsPBDM5mAC5n536L\",\"symbol\":\"REVS\"}" # 6.25307746 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPjMSyA3g8BjoUUsriQvdD1NLrrK1TB3Mz\",\"symbol\":\"REVS\"}" # 6.29263862 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bEoKuv3ZQATw3ZJLpJyP9xBZ22KZeGGHbM\",\"symbol\":\"REVS\"}" # 6.29978870 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXn9kR9D2XNGsjCTGtU4AwiEz9wx5hivth\",\"symbol\":\"REVS\"}" # 6.37285131 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXe9gVvBUiobEZpD2kin6ci3rqjcdTxQdq\",\"symbol\":\"REVS\"}" # 6.40626439 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP519KC4eJ5VubBM3m9h8UWj2G1DrqCGyk\",\"symbol\":\"REVS\"}" # 6.44654665 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKNUssHQ1MVm9RfYkMFbtqmH8hTPjLj1x5\",\"symbol\":\"REVS\"}" # 6.45071233 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPN4UxMojhN21FAAjanY2Ym3DbVRx8baHM\",\"symbol\":\"REVS\"}" # 6.47991749 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RX5nuag97TfD91vBtsYfMmkNU5mFwxRpjs\",\"symbol\":\"REVS\"}" # 6.55679133 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bLF3zxeasZuDbWLJjvmEfGsWZj4Ef5Maq4\",\"symbol\":\"REVS\"}" # 6.57726223 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDR4wckLqkbSQrVm1QVmEFNRpvdNSEnuZt\",\"symbol\":\"REVS\"}" # 6.57751649 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bZ6QvZdesEFM4rVoZeTbVVyUyuX1tVmPMJ\",\"symbol\":\"REVS\"}" # 6.61263963 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRsgbucf31dzNkdrke1dCYTQKDna5jzMGY\",\"symbol\":\"REVS\"}" # 6.66225723 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bU56V7Qk4egxMpF3Ty4E9MFY66fhHEjZ6C\",\"symbol\":\"REVS\"}" # 6.76298899 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RASgmQ7vpS6ixq2oRamQ7pdfmraLwgETki\",\"symbol\":\"REVS\"}" # 6.82799533 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCCahX9yNRkpq9HaL58kC2fR1ZjAFsy7Ay\",\"symbol\":\"REVS\"}" # 6.84109943 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RD1Ki5Qkzx19C4tu46TV9s7U8zDH1Uzp95\",\"symbol\":\"REVS\"}" # 6.85401372 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bMr4ZKP1415NwtyqoLRNkuBJwUYnk3SMWp\",\"symbol\":\"REVS\"}" # 7.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTuALQT8coBXcLnYmRHajhZHw61o1E2KGd\",\"symbol\":\"REVS\"}" # 7.01513900 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCGoxVfZpGs4dxUs8DcLDTfojL1wkWMxcL\",\"symbol\":\"REVS\"}" # 7.02508499 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCCAQhsikDfUuemcpT52M82VP7DPpN4ug4\",\"symbol\":\"REVS\"}" # 7.05979335 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVw3oQ6ap78HGn61K7CSCNBz2jg7kE2ZHK\",\"symbol\":\"REVS\"}" # 7.06099231 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWM7cZbjQ1t2GyyGWkfDwxTmkxatLCbM6J\",\"symbol\":\"REVS\"}" # 7.09011587 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVP6S4o6bCtWqRktETnwcpX7symQPnw55h\",\"symbol\":\"REVS\"}" # 7.18860202 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKpek9H2vrekZ213cyofxUjhSDY6Gbq91D\",\"symbol\":\"REVS\"}" # 7.22046828 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYJjYsaK5AEegbYvvT42vNGysdK7UYpcDS\",\"symbol\":\"REVS\"}" # 7.26124120 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHS9zj8CR9yAnjcfUbNV37Bh8L7CQh6jLK\",\"symbol\":\"REVS\"}" # 7.26198113 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM76KfYhKNTmvshcWehrLP5ctFRdX1G7DC\",\"symbol\":\"REVS\"}" # 7.27877611 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXtqtekeWMhzW261sBvaQ2bEm97zsM9xT1\",\"symbol\":\"REVS\"}" # 7.30896024 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDTH8uPQXZfhLreqpAKBYyhUNLZr4EHQPn\",\"symbol\":\"REVS\"}" # 7.42232722 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTVhP1vHoFG6EHdKi4HNCi3Vrd4zj2sPRp\",\"symbol\":\"REVS\"}" # 7.47550000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCwxX8YjgWnDJzUcb46dAjrPHyBjzyudjE\",\"symbol\":\"REVS\"}" # 7.47872317 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REJjfqXKShS43BHqUxLpx3uzwt8wz9c1zx\",\"symbol\":\"REVS\"}" # 7.54805723 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REN5wkHRo3UWYY81sGgV2R1vr5m4YkLyyX\",\"symbol\":\"REVS\"}" # 7.55087913 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REGEjAsxB9MCUV6W3VD3ioz1kHpHX6zjiZ\",\"symbol\":\"REVS\"}" # 7.63189129 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCLgACGpktPD9vKAnEYxQDQQppKt9LnfmG\",\"symbol\":\"REVS\"}" # 7.69901513 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA2SrMLyfCdzNHZopFKX3wBzE4Vfpo8t2z\",\"symbol\":\"REVS\"}" # 7.70733708 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKZSYmdLj6WhfwSkHu7Y67w4K7hSPyquyF\",\"symbol\":\"REVS\"}" # 7.73050202 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDixr3uj3gKAkYjSotrEQoTPVBoM1p6Fi5\",\"symbol\":\"REVS\"}" # 7.75437207 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUtSnBuS5H2EvXjsv21fbQds5q76BUG6q8\",\"symbol\":\"REVS\"}" # 7.78695249 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RChLfZZo4ptQmWndAw2FaGuv72gUcCeG42\",\"symbol\":\"REVS\"}" # 7.82175932 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bLRMfoBCRgYCKahVfjs8vDhAANYCrwyusX\",\"symbol\":\"REVS\"}" # 7.98287448 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB5vwEfQ3N7GJ39qQjGTbteQ5K8U3udUDu\",\"symbol\":\"REVS\"}" # 8.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVE5bbkWVYDsyY4yW4L7E8m9gFQBH2uod7\",\"symbol\":\"REVS\"}" # 8.00916943 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGnfzigKXUuRWf3XczBoQxXbG8766bVVFV\",\"symbol\":\"REVS\"}" # 8.08700041 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE8cvJBtbEsS8B93m5tmFEzrAEQZUFEVKU\",\"symbol\":\"REVS\"}" # 8.17119008 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMFuMuMuDaY3ryXAkF9WCd5uQevGMKW7EC\",\"symbol\":\"REVS\"}" # 8.25112000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK4YuiJo8PXaz1MPDpkahSNxk4PiQxWry8\",\"symbol\":\"REVS\"}" # 8.27336417 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSVYZFNfpxWBSvmWo1wx9TrjrMmJTc6NXS\",\"symbol\":\"REVS\"}" # 8.55864135 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRhPti7wzrDr41soAJr4c5dpKXyqZokJhR\",\"symbol\":\"REVS\"}" # 8.60934449 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bLj21adcDpdu2WMpVuyWNtzQkHMUhzzBxd\",\"symbol\":\"REVS\"}" # 8.64768637 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDDhdWuYrZMciPtJP23S2uVFny6vb9X7iE\",\"symbol\":\"REVS\"}" # 8.66077898 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNTZjRB162SPSdHfNUEzvYTcVw1y2PPXUU\",\"symbol\":\"REVS\"}" # 8.66444303 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTzB8ezpXH6C1GB89PjX4XoLSVwYCS5fLQ\",\"symbol\":\"REVS\"}" # 8.66577801 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVQV5spiARDTqfwBCxstWnMbrT6Q8mhRYz\",\"symbol\":\"REVS\"}" # 8.70430000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ85BeANJJa2wJjcXRGUZQWTRTnnqVyJvR\",\"symbol\":\"REVS\"}" # 8.73016364 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWQrMiW84qn7G69hxFA6Xws66cMPpiTLGU\",\"symbol\":\"REVS\"}" # 8.75387271 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNnjQ3VrdCAq8M9wQxuF9amyetjCLnxogc\",\"symbol\":\"REVS\"}" # 8.90245080 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHrQ2NJSHeHTouBJyk1b8jsQ8M5RZYtNBK\",\"symbol\":\"REVS\"}" # 8.96604688 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPFKYt5xoowtPkcn4yszFSRpUEnktymetG\",\"symbol\":\"REVS\"}" # 9.07044639 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMvT5Yiqf9XUVxeSz3gRe4s1RQiRVYKtf8\",\"symbol\":\"REVS\"}" # 9.31783113 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bKXGYrJYDMa8tLznG4KWBHJ9s7iYQHfwgy\",\"symbol\":\"REVS\"}" # 9.34414085 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKWsNksSp9wheZJmAEBXqsguwyRt7BUWC2\",\"symbol\":\"REVS\"}" # 9.40598001 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPM8y8JFL5svCr8osxJnfQFR8YAzhWuWxB\",\"symbol\":\"REVS\"}" # 9.42863849 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRXDmRBVgQaEWZD6zEBrXobeShAibTxAMd\",\"symbol\":\"REVS\"}" # 9.48885324 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBMni8BcodshhstqsDY6Z2G2VoV98exkaM\",\"symbol\":\"REVS\"}" # 9.53705814 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLxixyXF5sqpaAudjMeL6xHsCz3gagonFA\",\"symbol\":\"REVS\"}" # 9.62088045 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHhHcEga7TcgmYVS7Uny4FxpA7gyMgDXgn\",\"symbol\":\"REVS\"}" # 9.73476933 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKtHAoxJLN8LhUPZh1mR1tFgLKG8nPWTCx\",\"symbol\":\"REVS\"}" # 9.76245781 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLH17YLRpFZAj2pvKerVHSatYfxchrZB4F\",\"symbol\":\"REVS\"}" # 9.77918294 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAEhAyrVT3SBy5RgsGNzAb1ET9teadNvQF\",\"symbol\":\"REVS\"}" # 9.80265036 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM1FH9jneo3DzArwhFjVVkCx2oSZhHNXbk\",\"symbol\":\"REVS\"}" # 9.83053279 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW4QXNm4iqWAdJBXiHinPjJ85H7Z3zhhJh\",\"symbol\":\"REVS\"}" # 9.94000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bPtJnUANkDa7qH5Wtztex3tL3N6SrrGUzr\",\"symbol\":\"REVS\"}" # 9.97000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bGCkEU15D4L44GXFL9WTqAZd6JJmgcyGAg\",\"symbol\":\"REVS\"}" # 9.97730000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bTWACpopGbMuUmmXCTr1TKCc2oZdqrRYtB\",\"symbol\":\"REVS\"}" # 9.97800000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGxx6Dt9BD5bDrBKTFshkzgzJEf5j9drkT\",\"symbol\":\"REVS\"}" # 9.97990000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bQbVVtjwoqr8uSfwyE3Ndo5QzSTrWo76VG\",\"symbol\":\"REVS\"}" # 9.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQRD7qPoe2kr7qA4cBJ4RXPSVAmqfJc6wa\",\"symbol\":\"REVS\"}" # 10.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLvSkAwDUdMJzS32hnz6txeasC1H45u3oA\",\"symbol\":\"REVS\"}" # 10.01628389 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPBZL2cNrMaKRM9d8jVkJyK1XgLErNjqBb\",\"symbol\":\"REVS\"}" # 10.04589271 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJepZPEKTnjRCqs74a2WtiFc3jfDGWAKU1\",\"symbol\":\"REVS\"}" # 10.09575378 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKxdtxraDBfkFcHVwnBsJyz5xqPJAa1PWg\",\"symbol\":\"REVS\"}" # 10.09875834 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXug7zpcUDXVLvi7zyGuV8nPpH9E5z8A9W\",\"symbol\":\"REVS\"}" # 10.09934689 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bUpDGMBSkEkaXmS3Va4x8XEKRSwHo1zANz\",\"symbol\":\"REVS\"}" # 10.10000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNjLw9C8qfeA4465ZgSm5e3vWo2g9fqnhp\",\"symbol\":\"REVS\"}" # 10.12231392 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RATZjtx6Jb2qJPxkUfGC552bUnPvxr2k6J\",\"symbol\":\"REVS\"}" # 10.12324646 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTppyFJBBTux2WWme3VN9W44b9t3nQcaqh\",\"symbol\":\"REVS\"}" # 10.17085261 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAzZ3SApjjECcxKRAbfJpsKv9XLwXfZSXq\",\"symbol\":\"REVS\"}" # 10.22925792 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RATLjzZDPj9pMRk39i3yku47SxCKeQ29wT\",\"symbol\":\"REVS\"}" # 10.27439517 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAAhGiiHbDVTmcFtHX9uSmpeMwwZpRbng8\",\"symbol\":\"REVS\"}" # 10.36000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKXDhcAH7CCgf6SqSnQW43b5znB7bcjivf\",\"symbol\":\"REVS\"}" # 10.36425561 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVTGaBfe1aCWR5uXJMMgikRfP9DnAHABPw\",\"symbol\":\"REVS\"}" # 10.40724092 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAgHbPuF3pK7UjQ6194G4qtAHPxHnSQLgH\",\"symbol\":\"REVS\"}" # 10.70551662 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWovFPYJdsN8EEyvna5cuTrF8cyHoN7Xvi\",\"symbol\":\"REVS\"}" # 10.94374601 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG627XfAkt2EEm6wjspECKFZLTd7CBt8ye\",\"symbol\":\"REVS\"}" # 10.94403493 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY51cChTJAM3Vu93S1CxYCXBqoaK3pcSP4\",\"symbol\":\"REVS\"}" # 10.97863973 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bFsCjoceWYkpGnRZQ64SZztN9KWhtaFrGu\",\"symbol\":\"REVS\"}" # 11.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCNL1GJuTVt88dgnuiwS7i51ztjYHpPKF2\",\"symbol\":\"REVS\"}" # 11.08420000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC1h4zAjJcoXq5q637dK7QofvzXifi2wri\",\"symbol\":\"REVS\"}" # 11.29086294 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLE4TTGnMPma6cY2M3C3YQnEUDjHienMwo\",\"symbol\":\"REVS\"}" # 11.31241989 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFFNMEGjko4PFsbzf6MnNQeChwkkSSaGxr\",\"symbol\":\"REVS\"}" # 11.37982774 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFAUxLikD4e1xfumD7qUBvu9LwP2NLXJ9m\",\"symbol\":\"REVS\"}" # 11.46412992 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXQu5iNhbKmMciB8yb45FKa7MEykdNnBdu\",\"symbol\":\"REVS\"}" # 11.46809665 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY7JPTHmLVyZPaC8dqnifyTTjdLGFTKcbP\",\"symbol\":\"REVS\"}" # 11.49885173 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSi2k8no5EjRPVvACiEjuMEqR1nuMvVpQr\",\"symbol\":\"REVS\"}" # 11.50552477 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUndNcE3waCCYmSir6YAEPqQ13vrtW1U2n\",\"symbol\":\"REVS\"}" # 11.50998241 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLZyNC1mJv9xv8XW9zmNtTbWjmuYXPwYun\",\"symbol\":\"REVS\"}" # 11.59027663 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMZXWs6iCKcy9xqzFqSQRNjxDYgdPNtHa8\",\"symbol\":\"REVS\"}" # 11.61497275 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCfwEwNiVHbE9ZtviNEwip5kX7Xw6bBuQy\",\"symbol\":\"REVS\"}" # 11.64061118 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMwewBVYypysdK6kgyViygPeegCRBQKeAx\",\"symbol\":\"REVS\"}" # 11.72419877 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM6zMhsezMzcdhiQxiAJYmvs4gHUYomnxt\",\"symbol\":\"REVS\"}" # 11.72940887 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGQ6tqNipuKa2g6jNva2bRJVS5t6Wwdq61\",\"symbol\":\"REVS\"}" # 11.91053184 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bMBrJQzzyjadRf1hbefP5NYth8KCAJv4ue\",\"symbol\":\"REVS\"}" # 11.97804853 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bGzChjyd2QSy6ngHvaoZoWsvSHoS75s9S5\",\"symbol\":\"REVS\"}" # 11.98000493 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGnJK86j6n2gxJ5yM8Y8JU13A6gn78LFek\",\"symbol\":\"REVS\"}" # 11.98632762 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKXvhRQoVM57PMnXHjreBLuSdC1hNv66nX\",\"symbol\":\"REVS\"}" # 12.22549689 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNbE3759WCwGxZK4H8mkpAu1N3DZeeQQ8C\",\"symbol\":\"REVS\"}" # 12.22838967 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDg29vmrLNZRxWrRwW9qMhr5f1Dc6obMJp\",\"symbol\":\"REVS\"}" # 12.23635859 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLBrfF7wA4XawMeWuEjkGQ6Vy4xRJ8L9Rm\",\"symbol\":\"REVS\"}" # 12.26271901 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGcjC2ZT5jABMYegPDaZXQKMH9yQ3FP7yn\",\"symbol\":\"REVS\"}" # 12.45720563 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJZ37ZbAE5gSCwzi17gjvzRERC8zLEwzmX\",\"symbol\":\"REVS\"}" # 12.48602133 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNzYbCtkEw7dCt2qyC5XLPANB1Fyt5QpUd\",\"symbol\":\"REVS\"}" # 12.63140000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYCRYF42iNjFmFpEcYBj1BaSj893vsP4jR\",\"symbol\":\"REVS\"}" # 12.73240581 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHDz1SBqnogKuDc4yGjwrpnoDvYoz5TEEE\",\"symbol\":\"REVS\"}" # 12.81132571 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJLiW6quCrwEgExwAsJcBLhNgxZCTxbVjF\",\"symbol\":\"REVS\"}" # 12.93284052 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRezFyHPgUNu7Mo4rdyPgxXwA6TzyZvUfF\",\"symbol\":\"REVS\"}" # 12.93365966 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bEfb9xoDhKSK8mvFBfuJwWiB7pHqEsDoy1\",\"symbol\":\"REVS\"}" # 12.99702667 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMY62TF2rZ61Y2LE9rnyaejMGhyR5r4ga6\",\"symbol\":\"REVS\"}" # 13.00138970 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCziZFrJmQQDcMziVuL2sr5GQPUgQRZgqS\",\"symbol\":\"REVS\"}" # 13.08556125 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRq5Wna4FnVEsEqvQiSjiH1mrBJjuDqMpa\",\"symbol\":\"REVS\"}" # 13.11364546 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPN7WeABqDw9gmoE7jzQKLFU81521uJT59\",\"symbol\":\"REVS\"}" # 13.19427008 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLVsyrnFVyh5g2AXRwxEywSGVTzLHVvDR3\",\"symbol\":\"REVS\"}" # 13.21087443 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKHt6mmoKrLG3DSjv5KnDU7szqUiSG3Dy7\",\"symbol\":\"REVS\"}" # 13.32421245 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bRHewpfqA5YpGvff6YiSMbFSTjS792HZP3\",\"symbol\":\"REVS\"}" # 13.40000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUyYEBCp8yeEmxA8rZdSX7JAHYffqf3w2H\",\"symbol\":\"REVS\"}" # 13.64425051 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKDF3bRUTQTQNeXahroqU5fcK7XLpcUHzZ\",\"symbol\":\"REVS\"}" # 13.71270708 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTKABgPTaekUvupeLVtord8C7RWoRTi7Fz\",\"symbol\":\"REVS\"}" # 13.71530638 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE98nBuhWCu7UpxsBTSqbK4tGAWwaDFUzD\",\"symbol\":\"REVS\"}" # 13.77683460 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHhQXJM12G8xKaH1e6JM27vgGKNavZitRf\",\"symbol\":\"REVS\"}" # 13.85923910 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bRMrnxqd4DnmC7jzhLBqHNoazbGZxtjXy1\",\"symbol\":\"REVS\"}" # 13.91898000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bNJAhxa7uRQn7X4BWQVotaGmV5ihmkRzb4\",\"symbol\":\"REVS\"}" # 13.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REigyrSa6rg4kh5JnzHD5Xmi7LUXK7P1Ro\",\"symbol\":\"REVS\"}" # 14.07056206 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR96Qg7pMbPMJ2W7g2y9LqUuN29jT6Vftn\",\"symbol\":\"REVS\"}" # 14.08583460 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bDNSNBjBMGu5WXYqZV36qDdGhu8JLeW8oq\",\"symbol\":\"REVS\"}" # 14.38667315 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ6axNdbzY7KwRBDRXGYAstdjY2ReYdKHD\",\"symbol\":\"REVS\"}" # 14.39206871 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKDuPMsNqAchvvgHit3FjCa6xXj3MBYFE7\",\"symbol\":\"REVS\"}" # 14.44006093 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTFkVz41dAidUbZNi2KjhJYDJwVFtuvRNa\",\"symbol\":\"REVS\"}" # 14.45799256 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP8ZdDgwnC5hkv2pRhLHWJA3QUor6vV8bw\",\"symbol\":\"REVS\"}" # 14.60896206 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMz7CnEbCarY4eWcauV8zPA5VbiwpV1tBq\",\"symbol\":\"REVS\"}" # 14.69168104 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVhuV561hXCCWiqpSTXeTJVRBR8aghZCVm\",\"symbol\":\"REVS\"}" # 14.79301683 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWzkYvoCVean8EdWv5BYcPms6Pd4WPfVtg\",\"symbol\":\"REVS\"}" # 14.84881740 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJkVFVJjBLkjtqWAcoejf6N2YwtyFpx74e\",\"symbol\":\"REVS\"}" # 14.86126740 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPKHftKfT42qC6KLkAJNd6qt7jYoJ9uYB2\",\"symbol\":\"REVS\"}" # 14.93004526 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLdRxr1d4JgfHVqhHMgK5HkaVeRkNbUaBk\",\"symbol\":\"REVS\"}" # 14.99000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJrntvb2jYahU1KFrwvPErLq6fH3vBH99V\",\"symbol\":\"REVS\"}" # 15.07434953 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9dMSZYhjVar5WPEiMfJtx628xCchEkkns\",\"symbol\":\"REVS\"}" # 15.14149722 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRyNrbePcPoxjdUZx39saC5bezu1EwbnXU\",\"symbol\":\"REVS\"}" # 15.23806169 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJxBSmJSn7Gf1MVc5xTohPe2NBZjgJSYDx\",\"symbol\":\"REVS\"}" # 15.41660974 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN8hiGJkqi7a5TuhtnWh5Xrv55qdsw1LaT\",\"symbol\":\"REVS\"}" # 15.47900157 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRXW4oiL5HQxeffXQPX16sY2RqVxxsNR4i\",\"symbol\":\"REVS\"}" # 15.57990000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL3EUFd4U3tNKCFC3GPTxUknrjMLbaDwWq\",\"symbol\":\"REVS\"}" # 15.59110501 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL89Nq2YVnU1cx2DimvBSUuDKJDo4v79f5\",\"symbol\":\"REVS\"}" # 15.71654101 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM2nMWMeQ9Gw4GTLq3m5eXPyzbwB9mppxc\",\"symbol\":\"REVS\"}" # 15.84493003 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHtUj519CWFXZLYmxqTKnzXujNQ5BcDQdH\",\"symbol\":\"REVS\"}" # 15.86105167 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGM5Azshb3uj6fYf54y4t2Uk936ZCZTEu3\",\"symbol\":\"REVS\"}" # 16.30462792 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPuUeAMvAPSepweaSFaDKgbaugdvKyyhTx\",\"symbol\":\"REVS\"}" # 16.34892435 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE67nbSrh2hDEADHACNWsxtxVkQHkb2gBo\",\"symbol\":\"REVS\"}" # 16.41382706 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDBBd3eQdieMBQ6GfKZwcpMKzNbeKEp4Cb\",\"symbol\":\"REVS\"}" # 16.59177141 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RERSUpqfSCbdoTSpQWhwwe9KqDaDYJG6CU\",\"symbol\":\"REVS\"}" # 16.70612498 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQpserUdG9MEi5HWnq8XwnxD4fNFk5EQfc\",\"symbol\":\"REVS\"}" # 16.71481224 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYRLVH8J2YUM4PSmRn4US4CEeXfev5oyVT\",\"symbol\":\"REVS\"}" # 16.82656086 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTJHsf5YGCnpzmjXSLxmdApcJ9FLe1scZr\",\"symbol\":\"REVS\"}" # 16.91416826 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGVYJst5uBroFFL9iZduhrMQnJwp5CmgP2\",\"symbol\":\"REVS\"}" # 17.10952827 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGGT2ew3AQsDGiTM3odnCUyiv28e1vMjQ3\",\"symbol\":\"REVS\"}" # 17.13634047 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE5N6moX3S95h9P1o182miapBuVCaYUpHC\",\"symbol\":\"REVS\"}" # 17.54142304 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLfoQiJ8Zz3DTpvTcJRF4EmmgdKTZSDCBn\",\"symbol\":\"REVS\"}" # 17.76085471 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGPxHboHchYagV4YUjyzS5x12YaMdTNuTU\",\"symbol\":\"REVS\"}" # 17.76559916 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bTisc6Jj89hkfUfKXaixKAE2eDn84JBchG\",\"symbol\":\"REVS\"}" # 17.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVGEtfcsr2tuFpEJ9fe8YKMLnWScH3eLaq\",\"symbol\":\"REVS\"}" # 18.11802172 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAYm872orBvw7DBX7r7SjwdKusHCoP16QC\",\"symbol\":\"REVS\"}" # 18.22020782 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLk5xhUE4yUeAmakHbCWaAxeFxXiMhbdx3\",\"symbol\":\"REVS\"}" # 18.27183189 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQv94vYLnrUm3oTAJijoma5pHxFPLQkAkU\",\"symbol\":\"REVS\"}" # 18.28349476 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWMW2MmVpxHeeZ7CWbxjbdvFwR2beU9XHX\",\"symbol\":\"REVS\"}" # 18.71186656 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLxEbFJZk2eMBApNLtp5CPMkecAsud271x\",\"symbol\":\"REVS\"}" # 18.79673763 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9JprN4X3oYP45QUx1wiRbgUEUZeffYDP9\",\"symbol\":\"REVS\"}" # 18.99990000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQXCg535VfPKKav8eRHFbKJYjhnSEDYyF4\",\"symbol\":\"REVS\"}" # 19.19168638 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE1fGebb8dQ9nbC6W4BBY1wsSRwERgYUK2\",\"symbol\":\"REVS\"}" # 19.49566224 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJDbYk2yPqefWTGzd1euqMeanrta2wgXwh\",\"symbol\":\"REVS\"}" # 19.53159729 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUzuV9tWd2QCwnw9QAdF6Rvu1f1rxU6vV4\",\"symbol\":\"REVS\"}" # 19.70650000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQqCqY27MFw7Bz7tuZrjN4Yv52yX3trhLV\",\"symbol\":\"REVS\"}" # 19.96986886 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY6oEhMB9XhLhZCYRJ2vDf3r47Nega1qvi\",\"symbol\":\"REVS\"}" # 20.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bbhNkGRmsdCdef4oDaJ9TnB9KBzD4U3Hqi\",\"symbol\":\"REVS\"}" # 20.00050000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKK26dWi9GeUA7DKcTztuFWcfzAHZQB7yg\",\"symbol\":\"REVS\"}" # 20.01297681 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bb7wzpimc94Vmy1LJqWA2u3AinCj8MYHzd\",\"symbol\":\"REVS\"}" # 20.05410472 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA8r962ZQc8vzENfrDPUqURFZy7TnTFLMN\",\"symbol\":\"REVS\"}" # 20.08202268 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RStZxiAUeTisYU7bSkRDHN7dZf4ye8spkK\",\"symbol\":\"REVS\"}" # 20.08980500 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REw3BxmpcDT8i1DtnnpwyEbkdtfh5DTC3G\",\"symbol\":\"REVS\"}" # 20.32291312 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHnqXn3W984FzeNp5ZyvLEpz8f7eiLR8yn\",\"symbol\":\"REVS\"}" # 20.36885561 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bG1RRbdWE6M6mbDBdTtZ8i7VQLFPavd7xq\",\"symbol\":\"REVS\"}" # 20.52186953 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSJcMZuzcvr47DoYPMquM7ciWkN4m79Ats\",\"symbol\":\"REVS\"}" # 20.70261657 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bRv9NA2yL6NLj158NrkdVkTL555Pmffweo\",\"symbol\":\"REVS\"}" # 21.06991058 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUnbfGwqwgaKniaUzmNRgaD6suCMkpWsSy\",\"symbol\":\"REVS\"}" # 21.17667297 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN6LmMTEY9yCmpszz9QW92Nr6TjruqRRUg\",\"symbol\":\"REVS\"}" # 21.21727192 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTkEpCiLFdks4H7MNsbV67hxXPScHKJYTc\",\"symbol\":\"REVS\"}" # 21.23403553 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYLfBUkCVR8ZXrRijBS3i53akQw4u5cwX7\",\"symbol\":\"REVS\"}" # 21.50295318 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RD5t75MABmK9CvGYQN7a2cYcTE8obAoeSj\",\"symbol\":\"REVS\"}" # 21.52317207 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bD4nDFKiCLJGJT22gbVrFro3dXiET5nhPh\",\"symbol\":\"REVS\"}" # 21.68163463 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAE6RubBDc4ojW8U2CT1NS95Hf495ahn9A\",\"symbol\":\"REVS\"}" # 21.76541771 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDRgUYhC7752xwDQrAqUi1DsxWjyiZSJtx\",\"symbol\":\"REVS\"}" # 21.85310020 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTgYq4LFL3LiT2qBHS2jLQJVcR9wAVbdVq\",\"symbol\":\"REVS\"}" # 21.87197169 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUcY7jNkfcr7FdCGicxm6rFFMsftVG2q5g\",\"symbol\":\"REVS\"}" # 22.22900000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTMapTtbfKjqcHyJRH7bnA8967UFFXeoKw\",\"symbol\":\"REVS\"}" # 22.72955192 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bSwduqERWfjSLtyEaDhkPuYaWsB4GiRpeh\",\"symbol\":\"REVS\"}" # 22.88086692 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bP5YYJuouR2zkbRVTmbRWDM5EUzZXFf5wW\",\"symbol\":\"REVS\"}" # 22.92160462 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bUhCLBFd2rmfPvmbXWXg7ZrxdQFpNkVs9W\",\"symbol\":\"REVS\"}" # 22.95887915 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLnfLx1jHoAWWHfLwMB6uoGDU6H6DUc7s6\",\"symbol\":\"REVS\"}" # 22.96060896 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGk2XbwmXxbgbyZ2ED7f8pDqzCnJ4JugAZ\",\"symbol\":\"REVS\"}" # 23.63488442 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTA659rVfjuZ9nVCeF17A2tSEX57HYUpT9\",\"symbol\":\"REVS\"}" # 23.96332418 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCZriSKpiSSmgwjumuiMP2XEC2FgYgTrBf\",\"symbol\":\"REVS\"}" # 24.05385000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSf14eDKMwqirfEhfGwFdxwxEn32k88aQb\",\"symbol\":\"REVS\"}" # 24.54185339 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bPWMmT3oDWqQJy22UiFqEerbwDgvHBmJdv\",\"symbol\":\"REVS\"}" # 24.94000002 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVdE9TtbBER6AX8VKEzZ7c67wLzAmKGxVF\",\"symbol\":\"REVS\"}" # 25.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPPDVgfhnvR2VY87rSN52ECwkmucqDwoHq\",\"symbol\":\"REVS\"}" # 25.09012689 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REFZgK5DiG21VNYYspvyJcoEcu3w9cN1m7\",\"symbol\":\"REVS\"}" # 25.18682282 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGJDE8ZhKcKwBhQ8pA8PHAkxMabjR46DLX\",\"symbol\":\"REVS\"}" # 25.23164985 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPZmrnCKnZJpEXDjqwF9tR1NnrPsGyNedq\",\"symbol\":\"REVS\"}" # 25.30329901 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPsudhrty5f3RERUQKb8JqT14kWJ8Pgo2t\",\"symbol\":\"REVS\"}" # 25.31263322 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTVhcwSx4g8zQvyfmzBB7eVMZHUenG5Hbp\",\"symbol\":\"REVS\"}" # 25.52825141 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVU87RsgsPs5XCd1cKxek5Cm8UMdYb89Zb\",\"symbol\":\"REVS\"}" # 25.56542965 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJA39wH5wayxBQ42FEYq952Nh6G4cTQCVw\",\"symbol\":\"REVS\"}" # 25.99079855 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY2wme6iYopBVGDqfDw2Ky9Sr6KohYCBSz\",\"symbol\":\"REVS\"}" # 26.59001804 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAsUxrXkZJ5ZSH7LhbKaXGWu3KNoiURs1A\",\"symbol\":\"REVS\"}" # 26.65141146 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQnAJYgm76XKGny3BUntkFT6PrdACJScFr\",\"symbol\":\"REVS\"}" # 26.96884349 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA3xr2Us7u5z7d6nxZrRCfRCtxTX2u3stS\",\"symbol\":\"REVS\"}" # 27.99163429 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF6ZXivZJkNJwdbwdnNxTSFebS1FA1dAov\",\"symbol\":\"REVS\"}" # 28.25611482 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVpjSJitvEHaEpBXaS8UgPKUqZQxhA5Ven\",\"symbol\":\"REVS\"}" # 28.34230329 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQJ4TPSTYxVtxmfkHDHhqhiJwudDS8fLgu\",\"symbol\":\"REVS\"}" # 28.42905520 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJygH3aomv3bV8jSrKMuBKEmWWYrD5izCn\",\"symbol\":\"REVS\"}" # 28.55163073 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUs9Jc1oe1eGcJ3DBh76hzRP7Qug1kG1N2\",\"symbol\":\"REVS\"}" # 28.76362070 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUzBwyqJeZZBZtQEoASetrYLqCtg1Y6hsu\",\"symbol\":\"REVS\"}" # 28.78899081 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9n8dRBCbTmcGSX7d4WNq8iiFG8BUvRuUz\",\"symbol\":\"REVS\"}" # 28.91110731 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQKQmahdtDuZZ89sJCiHqJaexhNi8XsZ9C\",\"symbol\":\"REVS\"}" # 28.93042991 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bTBscx9pemaGuUH4TS4YeJhACjxJNYhWqU\",\"symbol\":\"REVS\"}" # 29.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA7C6BnphnV83PSg4D2ddXBNtbUfRw5W76\",\"symbol\":\"REVS\"}" # 29.17499765 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLr1kaGMePM2tpej85TMPVjX9hiW9qbeQ5\",\"symbol\":\"REVS\"}" # 30.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"baMdN84uxhaax7s3JNqyHmDsrwPcdjfBVu\",\"symbol\":\"REVS\"}" # 30.01000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBWi5QkS75yXSeDDdvKyTfJo9sytNFqdca\",\"symbol\":\"REVS\"}" # 30.03538484 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF21HJfT1q6rLwiZZEqZW4yxJjQUdZS8M6\",\"symbol\":\"REVS\"}" # 30.07940327 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDd64Cz8nkF2a8HVJNfdRhr7wMffqUhpyu\",\"symbol\":\"REVS\"}" # 30.81611795 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYbVkE1rcRWktcpxyqwh9nFqMZduPi72Ks\",\"symbol\":\"REVS\"}" # 31.03202705 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJimwiT35jAA7VZT7ZHv4unrj1pWcMTjBM\",\"symbol\":\"REVS\"}" # 31.08585106 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVfMRsetW5Dy5WLKsefuDQxikDLVEE2gR4\",\"symbol\":\"REVS\"}" # 31.12958871 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV94vi3zsVKmWaEJhZm3NwwZcftUagaZmw\",\"symbol\":\"REVS\"}" # 31.38033168 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTywPrMpFgm4EWrkX2p9s6WBhqn7qvrUQB\",\"symbol\":\"REVS\"}" # 31.49707608 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMYPPZKq5kmspA6PRBKGURNy7fTaRfWXFj\",\"symbol\":\"REVS\"}" # 32.18730084 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REy8KiPJkq18MrhUEHBZK6ZTJZVhsJM9Mi\",\"symbol\":\"REVS\"}" # 32.26197903 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REeFYdQ81qoSi2LHAT4mfDSp6meaUkq54R\",\"symbol\":\"REVS\"}" # 32.48842943 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYZuCvn5ZMGeAFvNDJy3Ws44rnRvCmWfZZ\",\"symbol\":\"REVS\"}" # 32.81268577 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH4M2Fm2RFds8ytetqDoQCqjrMK3YXDV2N\",\"symbol\":\"REVS\"}" # 32.97000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFiVhKH5A32yxh5PbAAPYan6EqdKk5RCUU\",\"symbol\":\"REVS\"}" # 33.69673470 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMEDMMCwTwPokiY1FiUKqqry8Ru5VD3uEY\",\"symbol\":\"REVS\"}" # 35.19000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQVPHPjaGN5jJboBeKHJdJ19XaJSG3YKZY\",\"symbol\":\"REVS\"}" # 35.32086964 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYJ4dgrrfLsGebPTj5qdnf6reRTWoy3o1k\",\"symbol\":\"REVS\"}" # 35.57154136 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDMjM2gAZjhWtP2Ztaedkt7qKVycMmY67a\",\"symbol\":\"REVS\"}" # 36.97762226 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKAGNCcrxCgci43d7XCt8H5bkSTGHe14SV\",\"symbol\":\"REVS\"}" # 37.19249558 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBeftVvNGBpHjmEQCUg8CCDHVULgGVNJsP\",\"symbol\":\"REVS\"}" # 37.54892664 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSfkUZpp5nW1dw7GzEwUEfcPusCaGD6XkV\",\"symbol\":\"REVS\"}" # 38.08192060 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVYUgpjwCF4ohFkv8W5118Nc2kTo22MkXx\",\"symbol\":\"REVS\"}" # 38.32196946 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMsPcEQnPPMiZogu7vccYTTDZM46TXptun\",\"symbol\":\"REVS\"}" # 38.67375486 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bV91tz6BKcygZ1Xewdv68H3F6UQPo6DV8F\",\"symbol\":\"REVS\"}" # 39.22798428 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAUbunsjA1xdPD3xsDpP5bfbUf7t4f5QDe\",\"symbol\":\"REVS\"}" # 40.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RW9S3bnW8UqaoHMpLAK3E74LymQ5dvk6UQ\",\"symbol\":\"REVS\"}" # 40.06389247 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP9QtzmRNRfLFi5Mbm8gvD6TZfoHwj2MmV\",\"symbol\":\"REVS\"}" # 40.66855529 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDwzirpMNsH48w5rEL4JZXnTvRruCmybrx\",\"symbol\":\"REVS\"}" # 40.83472214 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS9jA75yxYvZJkua7GE6kGrQJqSbPaVzjZ\",\"symbol\":\"REVS\"}" # 40.90800000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAP2RT4eoLBKuWXGRDiA4fSsJ17vqpnnKm\",\"symbol\":\"REVS\"}" # 41.11815355 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLFN7yZoyQMc82Bo2VGgE3d3gqc8Q6JcjL\",\"symbol\":\"REVS\"}" # 41.63038353 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCtgFQuvJPYUQTXywNh7vJ2YW5tFYXPPHP\",\"symbol\":\"REVS\"}" # 41.92581014 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9Kj3m1ZvXfRVr8NfwoYQqgXPWnfAEXNer\",\"symbol\":\"REVS\"}" # 42.46570277 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN9Uc8y1tfkAohARBr8x6Tvb9P6y9dqx15\",\"symbol\":\"REVS\"}" # 43.20551649 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQdhMza6wWp84dHZPyrRHfibAsYX9yfzru\",\"symbol\":\"REVS\"}" # 43.60137527 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCBtWy4JKPwQDSNPj81U6QL5PVNNgrRhcb\",\"symbol\":\"REVS\"}" # 43.87960000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTKm5hJAkLccm9BMkw63W6ceEpx7kNrVAE\",\"symbol\":\"REVS\"}" # 44.27236648 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMVn8uBovxtjxtbhYp1WiGahfaRp8urgVL\",\"symbol\":\"REVS\"}" # 44.36039614 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCSwNeGfNQCv2A8E921aqZgE4KoVM1G4xk\",\"symbol\":\"REVS\"}" # 45.26159097 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFSLmAGrHmUuQN43rVBE1f5aaQkxi92Lc9\",\"symbol\":\"REVS\"}" # 45.35485306 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGAiFaWTsD7X8N3Y1cRnSuQSbSasxCuu2e\",\"symbol\":\"REVS\"}" # 45.36502840 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCS2gVPEfFVjTWovdGXm4UoE93V9RGYneF\",\"symbol\":\"REVS\"}" # 45.78716177 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAhRFdzDF7mrchNZxp7pFsxFPLsgRBB2Si\",\"symbol\":\"REVS\"}" # 45.88643625 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTcJXCL1TruoZ2hFMfaPuC3r7HRFpRdaWs\",\"symbol\":\"REVS\"}" # 45.94912573 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUSBeCaGi3LK1arqUJUU6NMLhEGGmdvF7k\",\"symbol\":\"REVS\"}" # 46.17388739 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLT1PH7WHARhoV3Lm5j8n2Jf77Rj9pGAPb\",\"symbol\":\"REVS\"}" # 46.51149000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAfuUdcYQ3GQkmiojQHbfozuvbGGNHVi5w\",\"symbol\":\"REVS\"}" # 50.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXRk8T9yDyt2Pc9rPYK7qZ2EqEhr9qaeya\",\"symbol\":\"REVS\"}" # 50.21033178 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMpsdtAfSxWpHVXbTpJF5TNkf71MRahQf1\",\"symbol\":\"REVS\"}" # 50.73219475 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPESR5AymiPaYP6QTZPFfP6T9ws2CRu329\",\"symbol\":\"REVS\"}" # 50.92160000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUoBWjRaoR5dwSfQ9UwsTmEJaEvjHexLJh\",\"symbol\":\"REVS\"}" # 52.16835519 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGzVULuqZSSWmnxeqdggZt816SxTfDzAuP\",\"symbol\":\"REVS\"}" # 53.16556252 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RReFVgQHePN89U9YiraS5L4Wq2izaCyVZy\",\"symbol\":\"REVS\"}" # 53.64128669 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLXsMTWBikxAgqqjuBd1Uveq8wtLq1VjbT\",\"symbol\":\"REVS\"}" # 53.81988797 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bWPsh24sRtkgHg8o18x6MraGgKG5ZbwMf6\",\"symbol\":\"REVS\"}" # 54.77669998 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUkFd6ai5SXXj5cAbX5C51SSJ2ZjsKPVFe\",\"symbol\":\"REVS\"}" # 55.56852967 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJtmLD2E14LkH8hDpGYUYzkeUix5piRtUG\",\"symbol\":\"REVS\"}" # 55.63858042 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTzcdBFvrjL2xhj72k1GzBqjcydQ6PeWxo\",\"symbol\":\"REVS\"}" # 55.84620814 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVweURd15ub1h85wfNkYqvXMyUqFB55564\",\"symbol\":\"REVS\"}" # 55.86220000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDzKUu1uEoRXcKPvQqacmvBAEAXSKkzvSa\",\"symbol\":\"REVS\"}" # 56.18294195 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ7DNRagYN1RRX7CekDYDf9pzyQYLFKRpX\",\"symbol\":\"REVS\"}" # 56.37277591 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBUDJzemwyBvPF8hY1snRuj79we1WGM5qc\",\"symbol\":\"REVS\"}" # 56.71074057 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXMcD9J2JFygmaPxLBHp4y22kz1KZ1CLYw\",\"symbol\":\"REVS\"}" # 56.82525711 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKjqSAZer1R5JGScaXWoESvGUJ3LctfK7J\",\"symbol\":\"REVS\"}" # 57.29543876 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFUQsPXj3Ls547Me1mpLCf1uSoumwUP63P\",\"symbol\":\"REVS\"}" # 59.17036860 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bDvNazT4qdiTvcBnRNRvZfA8mW2GpfrMYw\",\"symbol\":\"REVS\"}" # 59.49000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKfJfdFP4Y7zvjS1D1aSKz84vJVZ2k3u6z\",\"symbol\":\"REVS\"}" # 59.86359941 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHv6F3txYYk6UKjyboSbQjWMLyqgdAAieE\",\"symbol\":\"REVS\"}" # 60.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHrERJZ6yJ62Hu42s6ENYauP7PbtfTKouK\",\"symbol\":\"REVS\"}" # 60.89100237 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAnXn6JX7mvcXB4oQ4HDvG1LqGTTyDBpDK\",\"symbol\":\"REVS\"}" # 61.33416695 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCBrFa25Dnc462ovQDkTBYuypzscWS4rc3\",\"symbol\":\"REVS\"}" # 62.54983642 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REYtA8PVRe8AfNC3qYungbVnmB1zwkBzXx\",\"symbol\":\"REVS\"}" # 63.69739387 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9xDXLjankytgcWQY7atn7Bbdb3gdchVSR\",\"symbol\":\"REVS\"}" # 64.10973396 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDkjbRzi8YEA53cWqrzRPygxXQDpHtChTe\",\"symbol\":\"REVS\"}" # 64.14507919 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRPrHoMQ86N87f8YHfMiGjSax2D53PmH4A\",\"symbol\":\"REVS\"}" # 64.80890026 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU6xJqp2ujs4DekPy4zhoH2w6nLENPpuNX\",\"symbol\":\"REVS\"}" # 65.79183438 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCwTYcnjq4D5FZHqof4FAVjnJnrL43vLFM\",\"symbol\":\"REVS\"}" # 65.84642049 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTkaPWn5ikgiKeDX9225guk6tTaBA7RqGg\",\"symbol\":\"REVS\"}" # 65.86789399 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQt5oRDo7xHg1xEkoNLgFJ2bdhyKPr8HKr\",\"symbol\":\"REVS\"}" # 66.69911819 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKL7QVeP7RVxJXV2c2D34WKLo3zZdx7NNp\",\"symbol\":\"REVS\"}" # 67.05614804 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJsAQynCwmVmKhLQ2TWVqke5hr9Md98NTU\",\"symbol\":\"REVS\"}" # 67.56912018 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAWnPCfHYyaF8w7DGUFjWfTKHy1Ksy6uiU\",\"symbol\":\"REVS\"}" # 67.57766718 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCv1zUhwdZ4eub4J7MQqK4y9TXoxUw27dy\",\"symbol\":\"REVS\"}" # 68.91424493 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUEWpaa6t4t8ZkXMQFea5o2hyLecvmiSgf\",\"symbol\":\"REVS\"}" # 68.91918018 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPpiV8XJrhkv9ZiyM64Akr3UXhnuAyTQC2\",\"symbol\":\"REVS\"}" # 69.04779793 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWci7EMXg3rHsWixDYoS1awmtaXcCcNUKD\",\"symbol\":\"REVS\"}" # 69.05662957 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVziSFdCLqwCoCc4S6h8gMid3b7wSv5paH\",\"symbol\":\"REVS\"}" # 70.12692312 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCMoyxzyRA7d1D72bVAWnhUocB9BxRJWW8\",\"symbol\":\"REVS\"}" # 71.59658394 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR2eusoUZRav6vcTdgFVeNWA44B62zGaYK\",\"symbol\":\"REVS\"}" # 72.30662573 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9KAW42xg429dz8iNf1ndZ1JpUVP9rh2cm\",\"symbol\":\"REVS\"}" # 72.39322336 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJLWdeLn1M5sY1T6DqnBCthmo4kx56EfuE\",\"symbol\":\"REVS\"}" # 72.41353461 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAWmLT4xCMMoigdLZ4StuiQRCUm9XpCeZu\",\"symbol\":\"REVS\"}" # 72.73825100 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQJ6iQ8BQwUma8XfW6cwTPLdsAGrqC9kDT\",\"symbol\":\"REVS\"}" # 73.07378007 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bG8bXdDdDGXC2MRoctyduJu57xj4zkECxT\",\"symbol\":\"REVS\"}" # 73.36528155 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9MAG1Lv8HW9DRq78DDZbz8SQXyP2gHGV4\",\"symbol\":\"REVS\"}" # 73.59822799 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAMLFBRuCsU8RFx9cqmXMSuxeMoMJsDatj\",\"symbol\":\"REVS\"}" # 73.95460045 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA8uFpmvySKWgDnopuRQCYmngDtoYL1Bm4\",\"symbol\":\"REVS\"}" # 74.62258456 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bFvKi5z6fr118nMMM3fRLrzmXtgqNg8TFZ\",\"symbol\":\"REVS\"}" # 74.93094772 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF8CDS3b6Q3vqeAzmoL6ngbyNt2oNF23sj\",\"symbol\":\"REVS\"}" # 75.71613168 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNW6Kkcdktbeemd2n8NVPCfgnRirzWoiZY\",\"symbol\":\"REVS\"}" # 75.98999999 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUPEK1UJ9dxDUnZVFQXfKdNERFkkAUzBnv\",\"symbol\":\"REVS\"}" # 76.09309632 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE5oyQSbMXC7ccRHgkoAApL8h3PB3Gp4bE\",\"symbol\":\"REVS\"}" # 76.51471756 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL8m3betBrE5hTHPMFT6qdhqyanTFshyKB\",\"symbol\":\"REVS\"}" # 76.89974819 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFUCrHkgp1pT6TWn7JM8c8dkbi2zaiCxhg\",\"symbol\":\"REVS\"}" # 77.24810157 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFfz7SaUQqVW7gXovhbgNpCA6HCE7KG783\",\"symbol\":\"REVS\"}" # 77.70000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHjemTRTpTN2m1g7gqZEQRdHTjBCpBDxfY\",\"symbol\":\"REVS\"}" # 77.93130589 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bKGnX6Kv8vFC6jALbf39SiDCVTf4RJdgz2\",\"symbol\":\"REVS\"}" # 77.98778009 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFxXM8MaUaUPt8TzUg3yub1hugRvnXz2oS\",\"symbol\":\"REVS\"}" # 78.74400181 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSL5mA7bwZSYEfWb4xa6Y44FdC3dK1ooXg\",\"symbol\":\"REVS\"}" # 78.82514781 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVdj9qFei2CYbezv7F6URG9Ztn52UEM6vQ\",\"symbol\":\"REVS\"}" # 79.02526364 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLY3AYB1A8ZMKx3jjYRDersmuMY2pWuYyF\",\"symbol\":\"REVS\"}" # 79.33015345 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSByda5tHs8P24SEpLTjVYvmM224VFUMZo\",\"symbol\":\"REVS\"}" # 79.65688080 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNmCUjsZgbyb1WpJ2geA7PudX7FEWt6A1f\",\"symbol\":\"REVS\"}" # 80.83392215 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXACz9vncXsH12yfw1cy5jcAB7Ac8ntEa9\",\"symbol\":\"REVS\"}" # 81.00660000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9QiMbjeajKnjjjj9SCDasv8QSqeF7PMcj\",\"symbol\":\"REVS\"}" # 81.69159762 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQoG4MwfgFXKd4YgtqKAhbrUBxBsBFPHcx\",\"symbol\":\"REVS\"}" # 83.03037663 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR2mB6Pwc6Gb2cvNyeHjNBXx68HXtVaXxZ\",\"symbol\":\"REVS\"}" # 83.30080000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQCiBLdKTwHFwzzmhcJMCqEXCiawN4iU9e\",\"symbol\":\"REVS\"}" # 83.35113918 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTBQygMTKnEUrb6mDuRX6oZMzD6bpz7MHV\",\"symbol\":\"REVS\"}" # 84.76381876 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYZs641EAgUVndtfummJSN6R6qRYFbUM2s\",\"symbol\":\"REVS\"}" # 85.17955243 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYFif5LZddRF4VNggedHDV8Sb6KdfHLfsY\",\"symbol\":\"REVS\"}" # 86.40991880 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTotPYKMLJ8kBGidruLBNsuD23sP7t26V9\",\"symbol\":\"REVS\"}" # 88.23282148 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bUC1sLWLJAg4rhJqX7iuM9hveEqaBrNejD\",\"symbol\":\"REVS\"}" # 89.18619772 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RD2cWM7HimECphiu8V8sctwGfubg2WKrJ3\",\"symbol\":\"REVS\"}" # 89.81298936 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWMvsej9DLbf7Ah4pERzig9f7jRr3GQEjp\",\"symbol\":\"REVS\"}" # 92.20066887 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bXnJfaRrXzXG6hB7rzyf5RhMs38dmbyucN\",\"symbol\":\"REVS\"}" # 93.75110762 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKZU1TEmq2AgR55V5zPou9wbwL8aoY4BLY\",\"symbol\":\"REVS\"}" # 97.14527606 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWcFZhSSAy687UnNQuLn4FH2z5jvADHckJ\",\"symbol\":\"REVS\"}" # 98.25817616 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN2L1tSiXFGzqwiD4JnpW4bNm1WwuW3bCB\",\"symbol\":\"REVS\"}" # 99.99000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bRrtZrDKaeB3BRuU4sGPFxQbKNCPYghrF1\",\"symbol\":\"REVS\"}" # 100.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWP5jYB4JBngnikbh2DWoL6AmkQtU16keG\",\"symbol\":\"REVS\"}" # 101.03001729 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWxknfDNTUssXFYXs9WjyGY55gTouXRAiT\",\"symbol\":\"REVS\"}" # 101.03220000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMaTWd43Y59AQaMV7A2yUo17UxgjCrWsLk\",\"symbol\":\"REVS\"}" # 102.06379403 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXL21swDPMdGZduJdpj5Jd4xmtZW7ADn7n\",\"symbol\":\"REVS\"}" # 102.07140374 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPuc3TzLc4mvUFeSSCHMdka2mD6skMdt2d\",\"symbol\":\"REVS\"}" # 102.07309463 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUy8CriCsoirom6SDQE7PbKG6peRYLkg8e\",\"symbol\":\"REVS\"}" # 102.87000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDDqYEMc6U7DCk5yo93Cy8phZi7cpRMcHo\",\"symbol\":\"REVS\"}" # 103.29269921 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRCDVWSxqac2aRcR5TQeGj9RY9vVJ5dDv3\",\"symbol\":\"REVS\"}" # 103.74612194 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV81npybQ798Gq7xpEy1N4iszz3Y2vezsA\",\"symbol\":\"REVS\"}" # 104.18722767 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY8Lsz2tM6kzyi38fuH1zVpBiii96t73c6\",\"symbol\":\"REVS\"}" # 104.49000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bKysATBpmdYMzN1u2JR9qoGRMztNkAndV3\",\"symbol\":\"REVS\"}" # 104.77000375 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSPpiHRcmFQvSpeepeXuuuLHDo2ZSXArBo\",\"symbol\":\"REVS\"}" # 105.21121101 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9HVQC9seWf4vub1Nw6yYZhsaDWAMmhcLT\",\"symbol\":\"REVS\"}" # 105.59787727 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSrQrnZB1ZCxS8WTPVUqzkiwRcXbKekf48\",\"symbol\":\"REVS\"}" # 106.26016048 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REWLpX7P3YZwJG6pWcDRV3oqaSMRBrrnxb\",\"symbol\":\"REVS\"}" # 108.09472652 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRL9HpNhootz5qHax7UA3ijUaqTqqrpJjs\",\"symbol\":\"REVS\"}" # 108.17453259 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU5DB5mWRWsHhu8sZTWmckGcQwhdJUDqpP\",\"symbol\":\"REVS\"}" # 108.65124152 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RETXHi8xLcgjW5YzRo6LPWtD7Srea8kojF\",\"symbol\":\"REVS\"}" # 108.85720716 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bYy5Lrv3TjWxaewGM9W3ZgAiE3CMwdTdtU\",\"symbol\":\"REVS\"}" # 109.06796023 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTo9KuSFye1nMUMwqNrZY5Qdk6JPuSFhdd\",\"symbol\":\"REVS\"}" # 109.35742161 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKGauAspW6jwnFYGcjWjyLb6C6RekiWfAW\",\"symbol\":\"REVS\"}" # 109.72267940 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXKhdVSuLNMFNPQGAADye6QxtAv4wrXLKp\",\"symbol\":\"REVS\"}" # 109.83484606 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bDtQQ3LrzfucJZo3nEf9hQsERQYMyGAnVd\",\"symbol\":\"REVS\"}" # 110.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bN5hZtKunzwMBqBykcs3upMa9biJc5QiTe\",\"symbol\":\"REVS\"}" # 110.79984203 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bD2o1o77YE6CS59CwVKozsSTXsakEeXxA9\",\"symbol\":\"REVS\"}" # 111.23900000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bYMX6vnisuBuaNfJwAm36YhxvvzsVhAUE7\",\"symbol\":\"REVS\"}" # 111.44650003 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9mVKdn5XBSgk9SqAZ3b7vYT5DYYdbMmuZ\",\"symbol\":\"REVS\"}" # 112.23680320 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDnngUbvKmFY1xVEFrcUrd3mF1z1CZL4ca\",\"symbol\":\"REVS\"}" # 113.18376426 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGFFr1ZW5CfM63ezygMei7GnNZDGmmGkTf\",\"symbol\":\"REVS\"}" # 113.19540830 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bLuMST8VKhkgkjkyFDivUddserzvrSrUjP\",\"symbol\":\"REVS\"}" # 115.14320000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RD7AEjxCAZrTtGkCC31QF5GnA41GBraWLT\",\"symbol\":\"REVS\"}" # 115.59707426 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bYhubBJb6dQquG6qy1VPycYSwAGcX7uUt5\",\"symbol\":\"REVS\"}" # 116.02835750 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bFQw6FJKEDDXYNmFTyGaQL7TUcgfzUjFVn\",\"symbol\":\"REVS\"}" # 119.02425427 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWcvDsT4NZ13JhAj2qLJ9Wd1fZQX7VnfPa\",\"symbol\":\"REVS\"}" # 119.92800000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bGStxaL2Y6Z7kEYDYGMACEqRnCoFXku7f4\",\"symbol\":\"REVS\"}" # 124.42418850 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFnMLGg2P8MquXAUrKwpgRKyhypdSw85Ns\",\"symbol\":\"REVS\"}" # 124.58995140 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUVHvbf5DkZJQstTYt8XnNiLJuTsndiP66\",\"symbol\":\"REVS\"}" # 124.70965075 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH8T5D1sxscFfh3tAm1GsBLjBN4A4D3dei\",\"symbol\":\"REVS\"}" # 126.44377040 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCDmBWeYYBX5wXsKxmZjsbiVAMzwuWizZd\",\"symbol\":\"REVS\"}" # 126.63803423 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUMpTRo2d5gdo23gXW4tjbWGEvAPHDjWni\",\"symbol\":\"REVS\"}" # 128.42575936 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY5FWH4N3eSZACd2VuBoj9dqfPuZLPKUo8\",\"symbol\":\"REVS\"}" # 128.45984982 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFPNe5BcNz1sgcW7s1Rmcq4t5jJThJRZRw\",\"symbol\":\"REVS\"}" # 129.09473986 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT7U3WZW67mAQUaqrdVgwXw5su7ZiA6Bsu\",\"symbol\":\"REVS\"}" # 129.16030619 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUmnosqbFAwLoiETLcHvuo8E9dsJtq2iyG\",\"symbol\":\"REVS\"}" # 129.49860507 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJbuiMNx66QNizQgwGuHRT3H59ViETfNxc\",\"symbol\":\"REVS\"}" # 129.74892513 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKmoYcFcT22fwPZsTYq1F3G2oSoGevwCF1\",\"symbol\":\"REVS\"}" # 133.14058657 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUjai4VGtvjfW2NWdgZQDpbuCiQ8M9PswK\",\"symbol\":\"REVS\"}" # 133.20739488 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTDMPwXdg5kYn416yHwRQZt5ZU1qyMqMmK\",\"symbol\":\"REVS\"}" # 134.38426806 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA5E3yCgWjVo6hgLq4RjGA3shkX2PbtrpU\",\"symbol\":\"REVS\"}" # 135.12217336 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bFHdzaZD7RfnRgbGKqimzx52hYDxjyg3zu\",\"symbol\":\"REVS\"}" # 136.79000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQF16BQCW7KwWQ5kQJUPNoVmqLK3jw6mGt\",\"symbol\":\"REVS\"}" # 136.98025871 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUxzdHCj27j8GUQsfVpjUWfCeeEL8NoGUu\",\"symbol\":\"REVS\"}" # 137.41618878 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ66W5cbSSRMiPqLqGD2zFPpFJa8Lz2Ps9\",\"symbol\":\"REVS\"}" # 137.72500465 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNCqLXDDnfYxkrfXZNQ2UdtVYBqGs7eNHr\",\"symbol\":\"REVS\"}" # 137.88286666 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKWuqX2Lu7U62qkTjsvMzPj5v5wD3y3TMY\",\"symbol\":\"REVS\"}" # 138.36843821 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYGz6a6htzW6Z3ZuwXeCU9evWrud54kM2e\",\"symbol\":\"REVS\"}" # 139.28924668 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bSWtbVqFM6TDPULibkMSKeVubbPRtAef19\",\"symbol\":\"REVS\"}" # 140.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPYVGGwVqJpPG4P8oRv6PaaXZWZL2WyAbX\",\"symbol\":\"REVS\"}" # 140.02010000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQDGhbt6ez5f4udUb5W7NpB3p9fwgEi5Rk\",\"symbol\":\"REVS\"}" # 144.61662947 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHiV43fLaNduShusi6oveEMkManXYTDbHA\",\"symbol\":\"REVS\"}" # 145.83490394 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJ3Ers2f4x2LNikgQhcnCfE3jdUgM5F8As\",\"symbol\":\"REVS\"}" # 146.61293122 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJoRrRJ2fMNS1u2RbEuxv4qEMAyzf59NJg\",\"symbol\":\"REVS\"}" # 149.97999999 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bacLS8FB73nSK1fZryuNdpP5FBWdyHWTJV\",\"symbol\":\"REVS\"}" # 151.63363650 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXGaGPgd8trrUjSefqPnvo8f4dkLSFUHGy\",\"symbol\":\"REVS\"}" # 152.66602809 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPpU9K7UfairC4DpQyUCYYSjm3R9HhikHi\",\"symbol\":\"REVS\"}" # 152.87919619 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKqQ1gfS2V8feocwzRKaBTVa7dJN5cmVzv\",\"symbol\":\"REVS\"}" # 153.78237940 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF7Q4dR7wfL6m2ezMAg28zcn1kxcpWBgM2\",\"symbol\":\"REVS\"}" # 154.21079380 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJco5BoAAkkxzoRw8c9GwNtC4FWa5xDswW\",\"symbol\":\"REVS\"}" # 155.46509045 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCRiUbVm9c9AhDuDj6zVwGpVmp2YyvDQGr\",\"symbol\":\"REVS\"}" # 155.60103980 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYFzcG71eshar3WQuH89n68EYz1EpUtE2t\",\"symbol\":\"REVS\"}" # 159.55861379 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY3vfgBpJcwYFZpFo8woTJj35kJQiLyXmU\",\"symbol\":\"REVS\"}" # 159.61549762 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQyZ6ffCveNat1Prm1QpFSBA8ixUyygkEz\",\"symbol\":\"REVS\"}" # 159.77050000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bFP7W2vA9SwUmsPej8TpCkTVWHRNCi3ivg\",\"symbol\":\"REVS\"}" # 159.97000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAzndmF383hyxSLnZRtazbmGRRs1CtPpL3\",\"symbol\":\"REVS\"}" # 162.01532205 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAHgHm1cjahRTaXZu1uyJLYc5nuYofUATD\",\"symbol\":\"REVS\"}" # 164.13512046 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNFrgZYqwhUnZwxWBFpm4cpxREGDtRbbte\",\"symbol\":\"REVS\"}" # 165.11938752 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSbAxPN91TiGcGUmsv6czUog8bBEEBxAgx\",\"symbol\":\"REVS\"}" # 165.70403879 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB5Q63vAW9yx1tsHp8SNRBqxckbWp81Edr\",\"symbol\":\"REVS\"}" # 167.39044670 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGzQ3cih6otR1BjkqpDTDpm8pFF8u4ztXF\",\"symbol\":\"REVS\"}" # 168.28892221 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPCcfYA6o1kfEZH4G64BQBYCc4gxCJLiHJ\",\"symbol\":\"REVS\"}" # 170.16705435 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bDTQPYsdisnCmeMRgMjdbPWLtm3XAPdbwD\",\"symbol\":\"REVS\"}" # 172.73941026 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV62WyrNLmRQeamkJ3QxrrnwfYDVfjcgeK\",\"symbol\":\"REVS\"}" # 172.74920372 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDNfqkziCYdpyJQBWJU8tSTxZu6WTdS8gF\",\"symbol\":\"REVS\"}" # 177.93629331 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bYrb2PMz24NCdvRhHpuDuqU6L3rKiVmaDB\",\"symbol\":\"REVS\"}" # 179.00609901 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV3uDVzT6t67NJeudiCXJBs7VtYupw9Ar9\",\"symbol\":\"REVS\"}" # 179.49681871 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLDc6KmUUsQjfWVWmAXCcKdrYEiKA1MHir\",\"symbol\":\"REVS\"}" # 179.83179727 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPr5vw7WyytSFqJaihn5K9YtSks9LC1npb\",\"symbol\":\"REVS\"}" # 180.72169916 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSRniHtiToruxfLKx2vehX52w997ja9FXM\",\"symbol\":\"REVS\"}" # 180.89312968 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUiTAU5RKEdkFxm8cL4XHny1Q7q9kWygZn\",\"symbol\":\"REVS\"}" # 181.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB3Cq7NFoiBrWtBDuBcTEChZmFsKYBWyU9\",\"symbol\":\"REVS\"}" # 182.99000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKGYQUCL9vD6i1PxJ18UPmxufPww8PY2B6\",\"symbol\":\"REVS\"}" # 184.99000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXzvjALGUh7AgQBCvyyqWCVYXJMnEpesbP\",\"symbol\":\"REVS\"}" # 185.75821658 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNZdeNaniirmNFEsDnoPopyUyFt6FkusD9\",\"symbol\":\"REVS\"}" # 188.40297419 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTAjocvBccVgu7TyhRY6Hf2xfmNx92pzLx\",\"symbol\":\"REVS\"}" # 189.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFGxfyFbZnmxtnU9iFS5cC4L3pWVvMUGYW\",\"symbol\":\"REVS\"}" # 190.94497623 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bbLeGoxJEzjyvaBxFwZM7h6ySyydhM5m8E\",\"symbol\":\"REVS\"}" # 197.68254058 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRNa93gNRJoygnbu5HGT1kdQdQuCHpqHkn\",\"symbol\":\"REVS\"}" # 200.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGu5zqbftY92VJFchBXdfTrk1dJ1YSWZoJ\",\"symbol\":\"REVS\"}" # 200.32704136 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RF6g4Fo6zoD8MKV1g1wp54xzZGK34RXkb8\",\"symbol\":\"REVS\"}" # 202.22778625 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU2KCNXDWnenp5v2nt33ipL4p4QYNrUhjY\",\"symbol\":\"REVS\"}" # 204.30408005 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLyfAXoyaE4fBoF1sSdi1gcYN3wDzKD8GR\",\"symbol\":\"REVS\"}" # 204.32479990 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYQ48DY4828Rvabks852BZMfoLG1NdJoSo\",\"symbol\":\"REVS\"}" # 204.38917526 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bU5VBCLQwu9d5DuUJfoHjUM1Hs19YAv72C\",\"symbol\":\"REVS\"}" # 205.00610085 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bKfAmn3pediqbHZvEuTxVTyMhMimi2kYVR\",\"symbol\":\"REVS\"}" # 209.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bbStrHZF7WUwDnPr4ijrYjuEJiuoVGsrqT\",\"symbol\":\"REVS\"}" # 210.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKmZhK5uhtza4WAywnWsN398bqyQois5oU\",\"symbol\":\"REVS\"}" # 210.10438688 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSCkSSty1jYM8fCwDZuWwXBa27LKQJD4Sc\",\"symbol\":\"REVS\"}" # 210.23364623 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGvEKh9WyJ9hiNVWbyTC2KDWKQ4BEs7Th7\",\"symbol\":\"REVS\"}" # 210.43508396 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFiXf9xBVopnj6zzpwA9GJvL949S14ymR7\",\"symbol\":\"REVS\"}" # 210.58913554 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bHsPKv9XEtN8RAYhqRHv3BqdquZ31bD7co\",\"symbol\":\"REVS\"}" # 211.29966352 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMq5sfV7rVQzf6H7SaeuXzAK9fR5R3JFja\",\"symbol\":\"REVS\"}" # 218.42967306 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWcJVaWagHwedcvHFvwBGbc114pmrfnrkM\",\"symbol\":\"REVS\"}" # 218.89063780 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDHNJYXuBQo5oJVfZk9puQ2N5Z7JnHuwYW\",\"symbol\":\"REVS\"}" # 220.59598299 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRsRhuCnKiUtaW5bMJYGURr59PEtXWHT3i\",\"symbol\":\"REVS\"}" # 224.55408869 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHeww6CSzHFsYkDWyanBzvSHJpWmbm2st3\",\"symbol\":\"REVS\"}" # 225.65799662 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RH1w7tz4Gbvwx6UEgFL73w3sUCCKDYo4JF\",\"symbol\":\"REVS\"}" # 225.96608282 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTzC7EwL6YZsTi3rcRu65zRu5XRkNEK4GC\",\"symbol\":\"REVS\"}" # 226.84505627 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM98UarGogmuPGuaVWcu32m5xEB7K2RwE1\",\"symbol\":\"REVS\"}" # 228.97743683 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMQYpQtcQDzwtKKUso8c95yV82b4Az15D2\",\"symbol\":\"REVS\"}" # 228.99599800 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVWAwaF4TSxvABnv1sm8usYm9xNNwUBCXW\",\"symbol\":\"REVS\"}" # 229.33065176 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKCNEkJkj9TVo9hKwuwXkabJ9cB37PWXHY\",\"symbol\":\"REVS\"}" # 231.44778423 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REbX7oMD6SZMKUN7ZwPa3c1no2wuVW46kc\",\"symbol\":\"REVS\"}" # 231.87096527 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPk7TFQrccjSZVZL4AqJrhvXnmNa7bPKC1\",\"symbol\":\"REVS\"}" # 233.59000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bD1p6oibYatoRHo3EVPXkyVE86pNgJjt7p\",\"symbol\":\"REVS\"}" # 234.64089600 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRE5A2QoE934tcsu2wBqk6U2oHnCh7wjSK\",\"symbol\":\"REVS\"}" # 239.57769669 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bKhxoozko7qKJQD4yDQgrbfZnMtkDhmy29\",\"symbol\":\"REVS\"}" # 240.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNerSsSBiGngBguyYxQ9ZSqpcZyUcPLYRU\",\"symbol\":\"REVS\"}" # 240.33867862 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKQfN1Y8aJ64Zxms83JECQ9oBJzF9AjnfA\",\"symbol\":\"REVS\"}" # 241.97686429 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCLQYSKcSAnooB4Vjps6m65iZpLtFjEdJQ\",\"symbol\":\"REVS\"}" # 247.80300179 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXaFNT43dJMd1ZrQzfh1fH23xhZCj9GfC4\",\"symbol\":\"REVS\"}" # 249.29379492 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bJpWurgzJidkaHQMgDveGHUyd3Wd79iqMe\",\"symbol\":\"REVS\"}" # 249.99000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWr9pDaNDqC5tQxAUaB35sc1cLFT8wimXZ\",\"symbol\":\"REVS\"}" # 253.28888467 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGacvvKckDJR7qSTnFoAWuYDrm3QVK4FSv\",\"symbol\":\"REVS\"}" # 254.31918912 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAYYUqsDb41SoETDAbBzGSct6HWpHBRe2s\",\"symbol\":\"REVS\"}" # 255.79012692 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTxV7qMBsuFzZ1rjuMe2LW6PLT5X1wYqw1\",\"symbol\":\"REVS\"}" # 258.77462194 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWNfZrTPdb6PUdRfHEhbJ52jNK5pyPNVUg\",\"symbol\":\"REVS\"}" # 260.24907020 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBUdGJxwaUF9dKNC7DRWXqNEwCau1WoCaY\",\"symbol\":\"REVS\"}" # 278.69301585 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSfgSNh6HqXEgcHaQbXM8K83yCJUek7xkB\",\"symbol\":\"REVS\"}" # 281.76486338 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bUi1VsVeoyHxq9mxys6gGntBy9vdxXeeVz\",\"symbol\":\"REVS\"}" # 283.69305405 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHMNYPvHLKG5McGfsUxuRhmoYWHkUet8Jx\",\"symbol\":\"REVS\"}" # 285.45438215 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG7mf1AHWGXUpqd3FTrUTYfFPbwjKLLvPp\",\"symbol\":\"REVS\"}" # 291.60482497 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAJ11XuG22Nucs7yzoLUgNzbUqCSEtScZy\",\"symbol\":\"REVS\"}" # 298.42252899 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXZ7BcoNfcc2yZQARRG587fsEJqhheDJA3\",\"symbol\":\"REVS\"}" # 299.57911711 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTiNp3b5SoXvFvKEFDoPUom8WVFbZYLKMb\",\"symbol\":\"REVS\"}" # 300.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RURYZ8FhS5oJ1h1xuv78EXe8rA32SiM4Dy\",\"symbol\":\"REVS\"}" # 304.32862968 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGba6AJogyFQGuMAzD1czE67KR6eW5PV2k\",\"symbol\":\"REVS\"}" # 304.98070893 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXMtwrMXyimRU5CWSdtWzHwWmcCeAc62ua\",\"symbol\":\"REVS\"}" # 306.73973391 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYEmXCS9D2qR71XKzzWbsiAMZGg5E2UWt3\",\"symbol\":\"REVS\"}" # 307.15599818 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWM3UrsRP4WtH6DTetm5KmUyBASvFCV6wH\",\"symbol\":\"REVS\"}" # 3005.50690770 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL4hFVzdntZQ2DM59QXZc619boZV45YFdk\",\"symbol\":\"REVS\"}" # 316.05434626 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG3vbi2TJp9jeqn8qDSnL1W5eFUeTGQJmu\",\"symbol\":\"REVS\"}" # 317.33569076 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQYgriDwRUuUbfw3E1AecAHZXryGSx1BdN\",\"symbol\":\"REVS\"}" # 337.23469627 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWyjhMRtXkSMFgaqJem2smR17Gcn2DswNx\",\"symbol\":\"REVS\"}" # 338.51975147 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDWMR1dGt7EyjuvJrHXcL8aoo5D23JX37M\",\"symbol\":\"REVS\"}" # 338.52917347 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWAoeRWoBpAT7xWeZWoXmgM114hLVxiVFg\",\"symbol\":\"REVS\"}" # 338.53842558 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RL9pVyV7EhGKujNcTwcw8m7n9LbeWLcbgK\",\"symbol\":\"REVS\"}" # 338.54432258 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV7FTQ5ivqHU4bZwdFdsGuSHpHkKqjPZpD\",\"symbol\":\"REVS\"}" # 338.55302702 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXa4aDTZenjvLeN7h4LRxd4jvHVpN2FmvL\",\"symbol\":\"REVS\"}" # 338.58187076 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNcscpbG6dH4AGffwpj3NDCN7gW8fL4Pnx\",\"symbol\":\"REVS\"}" # 338.63694015 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDgxkT2SnhVrcGx6jRuBrQ5FMVkxm38C6T\",\"symbol\":\"REVS\"}" # 338.80993693 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPxbRx4HyB83Y5uTLwue3bjEMDHizt1Yrd\",\"symbol\":\"REVS\"}" # 338.92318296 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHsPNWmD7YZwFsBzqB7CeWb3essSPUXynv\",\"symbol\":\"REVS\"}" # 339.01798043 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQeZBRQRsFMKT3ittCZzyTSrHkSaCXGRZb\",\"symbol\":\"REVS\"}" # 339.16387361 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFmPR4dYC2J4SGJQWyYF75DsdaSzs6amaf\",\"symbol\":\"REVS\"}" # 339.27093705 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB6yVhHGirfcXjqyZsSJLmJ3piSyBq9QnD\",\"symbol\":\"REVS\"}" # 348.36515758 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPsG2FM5DSoCEsoMLRwmKVgqvSRvM8raYW\",\"symbol\":\"REVS\"}" # 350.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bDfaeJk4Q1PBLB5ghUsJ4qGpoPEtNuSViR\",\"symbol\":\"REVS\"}" # 352.05485019 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXw7hzKyWNGqKjc51XaE2GtsW6iF15S7VW\",\"symbol\":\"REVS\"}" # 354.98460556 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REQAbdfBsdfLPqkUbrqq4FzjCQc1mUDJwY\",\"symbol\":\"REVS\"}" # 357.17138770 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPAgmZyfvcjBDbiPrr6k7aptgRJajNpdf2\",\"symbol\":\"REVS\"}" # 359.88265432 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUkWpDYuSF7q9Ee5qSd3prMcuc2qdXGKL8\",\"symbol\":\"REVS\"}" # 362.16988971 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REtWa3fas1CDnGVDgbgLPQfRjHTpELQ5oL\",\"symbol\":\"REVS\"}" # 362.89945753 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVp13qMhi7MkRjeV7cZp4mPwap8g3GB7pj\",\"symbol\":\"REVS\"}" # 364.88330000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMJaHNoxMR8efShueiySEXqEce62gviWp9\",\"symbol\":\"REVS\"}" # 385.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bWzc9xpS8PoaUXwL3H15F8BVVrAFM4HbEo\",\"symbol\":\"REVS\"}" # 387.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRkn1n1Gj3qCazWkSWScEwcGtZ5bctzDFC\",\"symbol\":\"REVS\"}" # 387.88469890 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUzj43VUzPWzLyv5ZUzFjzLvQNnYePZdss\",\"symbol\":\"REVS\"}" # 393.14137381 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRorKDSJg5nQJ42W9VfoLXxNg56Wyic2ye\",\"symbol\":\"REVS\"}" # 397.49164512 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ4EicmosAM41MTcg6Pn8KkK4xFto4H6Fi\",\"symbol\":\"REVS\"}" # 403.00294489 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTEgENkpiXgpQfauEG9AdnoZD8UUCPsvws\",\"symbol\":\"REVS\"}" # 405.02784721 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWxXDSWjxTgm2DQkMkP43CFYs21T3UyNh2\",\"symbol\":\"REVS\"}" # 407.90306325 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFBKhFCoTZ8yv3svNxm2KrZDFRFNoZ36TZ\",\"symbol\":\"REVS\"}" # 411.92646474 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA3SdteuK73TnyFY6ERdoX9hTxYCqeqt6v\",\"symbol\":\"REVS\"}" # 412.56794909 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMZuEijs8pH78aoxFgfWrsMLvNA6zVSeok\",\"symbol\":\"REVS\"}" # 415.01988324 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK7uSTUkBFzAzJRry7U1YHwrHuxHXyrbfj\",\"symbol\":\"REVS\"}" # 429.26665095 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCkjAp39oU9YHj1LMBwpyEzvU32qaBVAhg\",\"symbol\":\"REVS\"}" # 429.65636091 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQGUx8rqF6MAdbbZyoP3h1e7ukpTLCeY3y\",\"symbol\":\"REVS\"}" # 433.50000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REDuRH2VAbKHriXjemDARr8yZjfnuAzp7z\",\"symbol\":\"REVS\"}" # 436.77575645 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RD1cpMEy9tGCXoYKnuvCguAED4GfGHoGvT\",\"symbol\":\"REVS\"}" # 439.98136544 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RK3qrWAPpjbe6ENVumhesNfAnc9YsBYyiT\",\"symbol\":\"REVS\"}" # 451.87677477 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RP8awkjU6TTTNgahXsgAkdVhDnfzA5Z7hv\",\"symbol\":\"REVS\"}" # 458.70559633 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMnFJGoToc5qQKbaZyocen8k6mfVCGaqYY\",\"symbol\":\"REVS\"}" # 461.70514904 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bWtsHmWGb7Lb5dWrSDUQ87vGB4H5qS7LqA\",\"symbol\":\"REVS\"}" # 465.10657278 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSat9yC4JxuB5ijDhH2FbDAJ5ArRnAHfWT\",\"symbol\":\"REVS\"}" # 469.13540009 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMFrL52Gi4HdJJ4Hvfbu8dosKJNo4RVA7p\",\"symbol\":\"REVS\"}" # 473.35491660 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPnyG7pDUePrC8us819Y9w4MZhguYFeGzh\",\"symbol\":\"REVS\"}" # 475.26809848 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPLhkZw7tUcoJTnBaTkfvGg6ijqzNV3TA9\",\"symbol\":\"REVS\"}" # 480.24541236 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFs2Mvsuaku7NZji16txxd92nJh8tUK28h\",\"symbol\":\"REVS\"}" # 480.25997692 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSeSsp5oQ5P4wsbabW6xyaSoHX6stNLkqT\",\"symbol\":\"REVS\"}" # 485.91365273 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bNtCZW5GRLggbnfSQd3gYexSmJ8TgwqERF\",\"symbol\":\"REVS\"}" # 499.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKjcz5oj8SAgWxPvnEkmXrpAjo57NRh87J\",\"symbol\":\"REVS\"}" # 516.33357993 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGdGceBEcBs5F733sMY1DhJb5UikgEP9Hm\",\"symbol\":\"REVS\"}" # 518.39299913 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSjXz5b8y8cu3voJkaGzhf2mjXbcdArHQr\",\"symbol\":\"REVS\"}" # 519.14858738 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFhtwdLbpzHPPqE2E12g41ij92B8w2nbQw\",\"symbol\":\"REVS\"}" # 520.13194764 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGgCoh8S3KSb4C2YWQ4PbffuS6Y2XYtSZW\",\"symbol\":\"REVS\"}" # 521.28427061 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTVc5fn53gzZdV8Npov7THaqZLjkQtPPcM\",\"symbol\":\"REVS\"}" # 521.93818312 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCXtKno8uEU6RhPBeqQPaFfgptuVVzFVTD\",\"symbol\":\"REVS\"}" # 522.14752884 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQFi68oSBJWcmvj1gCiG2gxH458ER3AHgP\",\"symbol\":\"REVS\"}" # 522.46660091 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bY78FJ6EBgvrNkvvX1DS4KEcE7uiN2heqx\",\"symbol\":\"REVS\"}" # 526.65276086 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bXGxhTKhuaibYHNsH1HpxTEa898vA97xiF\",\"symbol\":\"REVS\"}" # 528.82237107 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSYsWBudyTjQf57JoD8B9KD1U6aSwsH9Do\",\"symbol\":\"REVS\"}" # 530.61712025 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMYDkqhQLZRjvv39Mfsy2EAp4vpFRCjdkN\",\"symbol\":\"REVS\"}" # 531.49628827 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bTVM8FrxdBixBLimtFa7rTRTCdTvG4H5Fp\",\"symbol\":\"REVS\"}" # 545.95950000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXg4YhwCZCHH5Trsej9e4XRHKVgfVNuyj1\",\"symbol\":\"REVS\"}" # 562.21708186 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYMQkDytoWGKeygfouRJjPLmmais9t8ovQ\",\"symbol\":\"REVS\"}" # 564.89274744 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXH3U1958u7a82KmLW4RwU9So6RmCfraaY\",\"symbol\":\"REVS\"}" # 575.80164953 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAjZsvmu7omTUZc24AEEB4rvt1j9keHH61\",\"symbol\":\"REVS\"}" # 590.17732021 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFd2ygcFgrCd2MzPfF6ZiamnNAunypabRw\",\"symbol\":\"REVS\"}" # 600.66098439 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS4AVzd7SW8rANVnuBydxEJLfBRCt6KKyp\",\"symbol\":\"REVS\"}" # 601.77765154 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWRWxi9LiPSMhQVTSXKppmtBeSFKB7zTkw\",\"symbol\":\"REVS\"}" # 623.13492532 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQgfzPR4zeCyLWaddHysGEVzoKLZa5E4Ut\",\"symbol\":\"REVS\"}" # 630.20000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCBZWHkpyvBjV2sA5kzCuUimoeJfJVsec7\",\"symbol\":\"REVS\"}" # 631.93532165 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKKRz2VW7WiYefjWcP48Nj2enT7i62ncu8\",\"symbol\":\"REVS\"}" # 662.37110434 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJgboHU12hUcWCBAQJmtsCUsohksjGrnmF\",\"symbol\":\"REVS\"}" # 666.41577353 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYatRGtqiDZHS63CaBkAWaDbo7SZffNv4u\",\"symbol\":\"REVS\"}" # 683.84493839 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTZrNx8tjx7F4b5qwCixT6rkgynzDkg11s\",\"symbol\":\"REVS\"}" # 728.66953211 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RX9H4o7wyG6nTNFiQF5tCSENFGeLGMWUyL\",\"symbol\":\"REVS\"}" # 739.71019424 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC83L4gshS5WE2BkmomjbzQgiFtq7xBfJi\",\"symbol\":\"REVS\"}" # 769.33230149 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RApYWob9QocU5Us7LLEwaV4U8h1z68dDiW\",\"symbol\":\"REVS\"}" # 782.08757984 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RAbWNNciRspsMniVJbzHrrv5MSUwD8HuYM\",\"symbol\":\"REVS\"}" # 785.64503552 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPpXeiGfv1yYdrLGFqjPpAF8ZSo71ghq4o\",\"symbol\":\"REVS\"}" # 810.85168289 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKYWTbwFoUijKCieriwofCuPgiJ2bbes1X\",\"symbol\":\"REVS\"}" # 841.27927382 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRNj31z6oqiNEv7GFmhNifFLGd1MMvvAqF\",\"symbol\":\"REVS\"}" # 842.49822301 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXVwRd2rB4nE7MkWjDQWcLgFJRQgPjWaUa\",\"symbol\":\"REVS\"}" # 850.32853855 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNko5DHae1cVhbeazqXvLJEVYJccHx67KW\",\"symbol\":\"REVS\"}" # 867.82542543 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA49LjsMvLfmAFy5qYr1oCQ8rdch6Lj1NE\",\"symbol\":\"REVS\"}" # 880.14735554 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQikhyiVU6meX3on5A5JDwzwraRnUiHQkH\",\"symbol\":\"REVS\"}" # 882.51675831 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bZVpBR2daTncJZZtPuNqv88TzrQkbQYYdg\",\"symbol\":\"REVS\"}" # 900.10000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDoDgWSFzNFcBkiiM8jHyG9CTgAHA36rLd\",\"symbol\":\"REVS\"}" # 928.97360414 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RByFvbaE5nrB4mqUJ2u4vwzowaWvaB52ar\",\"symbol\":\"REVS\"}" # 944.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLunPXFJMWQ9DJLVGUP2Xj9fgH8A32vWPt\",\"symbol\":\"REVS\"}" # 970.67993828 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMPXvtVDndUeCHBPXS7nWneC4b7kN9PtZs\",\"symbol\":\"REVS\"}" # 987.30467389 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTGQ1Wjijq1PXzPGJV9oHRPQJq1B64ALpV\",\"symbol\":\"REVS\"}" # 1000.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKNo9k7vM9Xe8TvZpr16Qeb5HbGpdAydrL\",\"symbol\":\"REVS\"}" # 1001.64702040 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTsh1yvLPM86i5ygVeD8vfotqeVB1zV4Ps\",\"symbol\":\"REVS\"}" # 1011.15326271 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJZvpWzwxALD9FwPvcXZLGFGdamGLC7Zf8\",\"symbol\":\"REVS\"}" # 1021.54501080 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RT9obeyoapYL1kzZdrBKTtJvasTJoDTiwA\",\"symbol\":\"REVS\"}" # 1023.08312357 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC9mY5pgfqfyQfsGVSuo14E6mMp78sD77c\",\"symbol\":\"REVS\"}" # 1030.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWrBZR2W72YKHujQ6YdXwkrVRArLRqAqZZ\",\"symbol\":\"REVS\"}" # 1030.32106028 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ49CbZ4HpAVHPb5e9k6C8VzGRizV7wVUC\",\"symbol\":\"REVS\"}" # 1037.11942646 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLwamWWsbVQbqpbVYiGDUBDrACuNprSpDa\",\"symbol\":\"REVS\"}" # 1070.33908131 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bWMnm4JFHc3P4wxAQNWhkxYWZV9pkPXavq\",\"symbol\":\"REVS\"}" # 1079.83959447 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFyurZh8G5mHgHose6CNSxY17jrCzwFA3C\",\"symbol\":\"REVS\"}" # 1115.69217311 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REKNAiyTbkAupJYHyDCjwoAU6zqYGc6LUe\",\"symbol\":\"REVS\"}" # 1178.35224911 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWZKyeoA6USwkdpMnCLvM4gdQNJ2Jkyb9E\",\"symbol\":\"REVS\"}" # 1182.57361147 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RS4fhJG53XUyvD9gmWEjep9ecEUYLpzMYw\",\"symbol\":\"REVS\"}" # 1197.42230538 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REKW1Fds6ZR1kr9ZQpMQfX9JtVr4JoMDQP\",\"symbol\":\"REVS\"}" # 1245.36418320 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCzdxZnzEReriAHYShjqVE7fWUKBmUAGKr\",\"symbol\":\"REVS\"}" # 1248.11187974 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMu8dLXBwygMM6QX26RUZumoNz6gsSPUbW\",\"symbol\":\"REVS\"}" # 1252.75530323 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"bbQ3vYxDVW121iRGR7Gif7HLJyV1J5kGpx\",\"symbol\":\"REVS\"}" # 1255.04360000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSzQ8VgtT5fcoWSxG7msWenU4MZspsRuZE\",\"symbol\":\"REVS\"}" # 1258.45808870 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9qzjnYUNA5AQvaBFzHHkQcSgm3c7qaGiq\",\"symbol\":\"REVS\"}" # 1270.43960528 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXnGy9gspTSbXyBHHpDuDDJ8isZKdbdZDM\",\"symbol\":\"REVS\"}" # 1283.33070550 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ7HrZo1sbVi6JjU4U8mTqZeesh3cgikqx\",\"symbol\":\"REVS\"}" # 1500.76743524 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTdKZwhyw6JLhtFHPSq895ss3PGVRoFiTv\",\"symbol\":\"REVS\"}" # 1533.78985801 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJxmRHNggLPjZTM2eB4ApEs9NqrDeo3pX3\",\"symbol\":\"REVS\"}" # 1552.58020215 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RB8dMmoUxCGTA5BnGiUuUpLuWMmYBGKka6\",\"symbol\":\"REVS\"}" # 1580.79802115 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJaaJGWo6kKCV3cH4gtZ8zU1nhLRfbpHEr\",\"symbol\":\"REVS\"}" # 1597.30381665 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYCRimXfejiMnenUJaDuwWPuAiPWCCW9WE\",\"symbol\":\"REVS\"}" # 1624.86184672 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC6aYisvBT1GB5GmzeZsrXwE2ghbmzGyHD\",\"symbol\":\"REVS\"}" # 1680.63385794 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSAFhoDsaHgpvWQAQHfQgrTw2y251sMdSX\",\"symbol\":\"REVS\"}" # 1711.15826952 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKoUvKXy6eApLpUQwvvBF1phNp1fApeu1t\",\"symbol\":\"REVS\"}" # 1712.15414286 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RD4gYn4oSN3bCoZ5xG8ZQcSCUJDnEot3dD\",\"symbol\":\"REVS\"}" # 1748.97302195 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RC9UvLgfgFx4BsS77bkC8swFA5WjNfn58w\",\"symbol\":\"REVS\"}" # 1922.42175949 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWyzffxhC6E8qAmndUEWaA9HsFAokB12kr\",\"symbol\":\"REVS\"}" # 1953.81900169 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RY1WSzWWgaJRof1tK3Vxmo6q8f6ZYsAvvp\",\"symbol\":\"REVS\"}" # 1989.58109245 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGWa4NEsEEtNGcHtH7tba3sKoifHgy6xgU\",\"symbol\":\"REVS\"}" # 2012.14166801 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFFJFhgSy2z36BNJ4AqzhRwMdiECqkLu5o\",\"symbol\":\"REVS\"}" # 2022.18035204 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGaGoL5vZcd6teKEHPzgkurA3grskipQnb\",\"symbol\":\"REVS\"}" # 2050.81194884 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RFY1AA25ME61rw5eqTYiKUUoFnSuz4g37S\",\"symbol\":\"REVS\"}" # 2065.02328418 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM5NNYdGee6X65aFGkyaRkYocSxQVNsB8d\",\"symbol\":\"REVS\"}" # 2070.75469155 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RU4vhnUxetvmDappwN1Bip3UQLWXQZtgVC\",\"symbol\":\"REVS\"}" # 2080.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRWZoKdmHGDbS5vfj7KwBScK3uSTpt9pHL\",\"symbol\":\"REVS\"}" # 2198.60600609 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQXssiJhWsc11wimZDGQtWfP2z6xAEjACh\",\"symbol\":\"REVS\"}" # 2203.39011975 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RE232ssJFR5qE1xEfVc8mnbfVykxtHpK3V\",\"symbol\":\"REVS\"}" # 2242.14368261 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRZZ7VYu5HowvkadGgpXoYDhTtuhFt3Rga\",\"symbol\":\"REVS\"}" # 2306.22009491 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDoY2wATo6jddqNP34jGqJ8LtUYB92vDn9\",\"symbol\":\"REVS\"}" # 2392.92000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMQY3Rnm74oB8k9kwmbAhiv4KASBAXgc5Q\",\"symbol\":\"REVS\"}" # 2410.55569525 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWU752dM2s3sjpPZCaWpihUEYmbL6m7Pne\",\"symbol\":\"REVS\"}" # 2537.07064054 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTCq8NorFo4bNwUTNnyKg9YwYgxH49SbbY\",\"symbol\":\"REVS\"}" # 2556.94031291 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNiUNTzDtBgQyA64txPH3W7gMXAjJriM1T\",\"symbol\":\"REVS\"}" # 2597.18712886 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RHuJvZphT6ZhKP3hxCRDDsCnNmCMtDy43r\",\"symbol\":\"REVS\"}" # 2603.59182293 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKxJ7a2J8faQ7VD5dAyFFjMU9DxMDFqv3D\",\"symbol\":\"REVS\"}" # 1.10000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGyC2cGKrTbv1zQq4f6fbMc2byCNdUAwBX\",\"symbol\":\"REVS\"}" # 2700.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWJPh9C4WQGuT8UDMXb4u278Teqzcq3zQt\",\"symbol\":\"REVS\"}" # 2784.22122603 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNjNREuiLJ3D5eWGqLcsMvjno5RBsBxqKN\",\"symbol\":\"REVS\"}" # 2894.22787069 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM7V81SXk2iGG3Ks5XoiqFcfmoUiWHtvwu\",\"symbol\":\"REVS\"}" # 2954.22050198 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RSZAauYp87qK1bYHTLECVNwkz8o5sT378i\",\"symbol\":\"REVS\"}" # 3060.14169415 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RG6CQRTT5YELbwZsbXQTkpM6AwuYJdmTbK\",\"symbol\":\"REVS\"}" # 3158.94508818 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXJTdXZFtHSHn1uoUKjPf1o8EnJWfPQctm\",\"symbol\":\"REVS\"}" # 3219.09324326 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQQeDVVZazjiVo4hvX426Mveu7w3oG1ctb\",\"symbol\":\"REVS\"}" # 3462.94432823 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR67pFVScD4dVhaksdAmBwiNU2bi9GLAnK\",\"symbol\":\"REVS\"}" # 3947.67767456 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGakaSDQtRH91A9LJRMqqCRmLtsBKBxscf\",\"symbol\":\"REVS\"}" # 3979.52576425 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBdqPkQkwDCPWqTZChUjybb9fR4MaqMbFP\",\"symbol\":\"REVS\"}" # 4153.14427322 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPYyAiFE7ZPs5MS9AEPRBK4RozvR4N3ZgH\",\"symbol\":\"REVS\"}" # 4181.63220753 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGnSemXxYSWJNgdZYpQUf5wNwsFU8aYhNi\",\"symbol\":\"REVS\"}" # 4299.51617127 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGfVQAre3NPLZsk6ggwk9wsnUqtTLkFsBp\",\"symbol\":\"REVS\"}" # 4314.00888047 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ4MryQ1eqCybU9WUe1eH9MmEgzGcfMmgV\",\"symbol\":\"REVS\"}" # 4541.72536969 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJdo7GR1LgtSG8nuuAU2F5vQYtw7whMKVw\",\"symbol\":\"REVS\"}" # 4869.97663739 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLAv4hKnrweHfmWfe6trpTWmkp8By89zEH\",\"symbol\":\"REVS\"}" # 4912.84976935 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTaYBryxVTYy6oorEspmnDLYh5WkqeuzBi\",\"symbol\":\"REVS\"}" # 5133.33174713 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNBdRLCTf1DpgSsnhKmTMbfLRxCgsTGjh6\",\"symbol\":\"REVS\"}" # 5142.01416110 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"REzqSJ7qonDbMVWfPEJKfRPduvfPyumkPR\",\"symbol\":\"REVS\"}" # 5338.41830397 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVHyYHfgSgFux5iNoZgBEFGC747r5Lk5Wi\",\"symbol\":\"REVS\"}" # 5344.11999439 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBCtWKuc9XvKQJqrxeNAGB3fh2JXbsFS87\",\"symbol\":\"REVS\"}" # 5432.11872965 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RLdUWLMxWLz6szQYUbyfvcZMra8dTjwDFX\",\"symbol\":\"REVS\"}" # 5682.18856311 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RKqfxo98Dmf6xamGfSFVeczQaU8UdBvzgB\",\"symbol\":\"REVS\"}" # 5810.91344741 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQfmbLQkvJEEUE1s4qC7NJn9nm9LVtLDYz\",\"symbol\":\"REVS\"}" # 5945.95358406 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQ7pyVDnUW2dW4VsyreWV843ABkDETxuih\",\"symbol\":\"REVS\"}" # 5978.00568581 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTXuCinnhGU5Vz1MsLcVQBPhA3Kj6zffc2\",\"symbol\":\"REVS\"}" # 6744.61067515 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGaV5Qxi2PdtMpe8GR9MpQ9JogDz5oaZbK\",\"symbol\":\"REVS\"}" # 7192.90498591 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RRA6inSrHDZKXFWMD4V2dyiyHtghLHDq1m\",\"symbol\":\"REVS\"}" # 7474.72830247 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDnHMnK8tgm9WmY9u3EoRLww9FyFBannCa\",\"symbol\":\"REVS\"}" # 7674.44264872 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RXcEPd6zV1hHAVZzfe2d8Ccv3MzHMZEZ49\",\"symbol\":\"REVS\"}" # 7979.29356057 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUw1psGnNrrcgmXDc7cRwEBLKRudikSdmy\",\"symbol\":\"REVS\"}" # 8009.98000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWAxa88tQXVDY64Bwz6DP2ZppsFotibaYh\",\"symbol\":\"REVS\"}" # 8600.42312744 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGqQ24q9Ar48oyuG3krmEZoYwVumhJmZ6C\",\"symbol\":\"REVS\"}" # 9021.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJANoTkNwx76yB3Hkx2Bk1KdisTVM66DmW\",\"symbol\":\"REVS\"}" # 9099.20666047 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RNfuDmVjCkCuXHk8MBn6K5mUyBHY5xXRew\",\"symbol\":\"REVS\"}" # 9212.51505260 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RTJiW6nmfYpwE9seVBCBGFg9o4SodM41rJ\",\"symbol\":\"REVS\"}" # 9228.95935659 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RPMh2JYF4QrveeBYC9oBgaoLvVNm2PadWW\",\"symbol\":\"REVS\"}" # 9238.95876293 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RWUTuApNQuuSustN4DBt6PxxVRwZhh52An\",\"symbol\":\"REVS\"}" # 9285.66131773 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RN2oUdxRbBG77NwCuyzw8KRtAnhNczpSic\",\"symbol\":\"REVS\"}" # 9324.74856304 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9UXLLQwJDdWDCRNSFRnfBPwaycxxEJ1Jq\",\"symbol\":\"REVS\"}" # 10000.00000000 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RM9iwyjkh2KRxWwa71DFfNXZsMtMzDZtwq\",\"symbol\":\"REVS\"}" # 10054.89954688 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9g77ds8kFS58V24s9Wodt8quMB8NSp3FC\",\"symbol\":\"REVS\"}" # 10145.26130120 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJ94yrqKCP3XjFsAsNj9WXS5SLpyHUpx5n\",\"symbol\":\"REVS\"}" # 10530.83468511 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUZ9AKxy6J2okcBd1PZm4YH6atmPwqV4bo\",\"symbol\":\"REVS\"}" # 11376.67477057 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RCcyievEDRE2RFUag5jcoz9fMQ5uwXXPaf\",\"symbol\":\"REVS\"}" # 11413.06578145 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RBCLnsjCVHWRyUpfgauyzUu8iP6X5CabJT\",\"symbol\":\"REVS\"}" # 11587.12695823 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RV5eKvybKDNctYxXiNYV766PzCakiUNRRm\",\"symbol\":\"REVS\"}" # 12320.60757772 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RYNE2isKrRu5b7xxm1DtXcLxdmBEKatuJY\",\"symbol\":\"REVS\"}" # 12352.53172757 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RR1svWTDxD6bjtkXDzq4vhB6PWPETPNU42\",\"symbol\":\"REVS\"}" # 12442.52868329 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDvdbqJLu8GgLL1TvdADNeCbbjXRmHBjog\",\"symbol\":\"REVS\"}" # 13489.95082851 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RUtWXg4RK7rs3pF7zCUGspED4aUoRzoopg\",\"symbol\":\"REVS\"}" # 15100.47446281 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJPGpRQ4nudwzw6mjWCUb6cq7aWP4to6pM\",\"symbol\":\"REVS\"}" # 16712.75904663 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RGgbJiV2Hs8eWJbZmZ3hZLS8sSzFA7tYNu\",\"symbol\":\"REVS\"}" # 18146.04892666 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RQif3cnnrWjP2zzrhum24FjgwS4wBzBfts\",\"symbol\":\"REVS\"}" # 19648.89190390 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RVVXPGLFbRUeQo1oGSWjkposncuzFirxep\",\"symbol\":\"REVS\"}" # 19960.31588900 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RMo9emPiNDd1kvn9jpDBEvLavPxb9rdyNk\",\"symbol\":\"REVS\"}" # 20322.05955760 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RJjAyD4hgq3XgtLikv1U1TrTvp46fBdxbB\",\"symbol\":\"REVS\"}" # 26613.67939303 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RDn6vnPHXixF9zJNj6jyowy32qUJhrVDvx\",\"symbol\":\"REVS\"}" # 31325.56985113 +sleep 3 +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"RA7FDvaNFXZNLqosSbCWFbypuvijJNQw5J\",\"symbol\":\"REVS\"}" # 37986.61891061 +sleep 3 diff --git a/iguana/tests/accept b/iguana/tests/accept index bdf736e9a..4c165c5bc 100755 --- a/iguana/tests/accept +++ b/iguana/tests/accept @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"accept\",\"requestid\":1728286611,\"quoteid\":123456}" diff --git a/iguana/tests/active_7776 b/iguana/tests/active_7776 new file mode 100755 index 000000000..f6929bcbe --- /dev/null +++ b/iguana/tests/active_7776 @@ -0,0 +1,3 @@ +#!/bin/bash +source pubkey.txt +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"dpow\",\"method\":\"active\",\"maskhex\":\"ffff\"}" diff --git a/iguana/tests/activehandle b/iguana/tests/activehandle index 2d53b5b76..266c45dc7 100755 --- a/iguana/tests/activehandle +++ b/iguana/tests/activehandle @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"activehandle\"}" diff --git a/iguana/tests/addmultisig b/iguana/tests/addmultisig index 10891244b..ede3fc981 100755 --- a/iguana/tests/addmultisig +++ b/iguana/tests/addmultisig @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"addmultisig\",\"params\":[2, [\"1CHzgAakwGCvGX2BG1duWygDuVE6s7tzZ6\", \"d0296ed1364639c696c374730320480301f3194c86231f62f0409cd76467f87c\", \"d045925b3e6f648bca6ed0c65149ee445137f0ab14e88cf60013d88419bcdd60\"], \"msigs\"]}" diff --git a/iguana/tests/addnode b/iguana/tests/addnode index b9fd550f7..2840f3b51 100755 --- a/iguana/tests/addnode +++ b/iguana/tests/addnode @@ -1,2 +1,3 @@ -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"5.9.102.210\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"78.47.196.146\"}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTC\",\"ipaddr\":\"5.9.102.210\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTC\",\"ipaddr\":\"78.47.196.146\"}" diff --git a/iguana/tests/addnode2 b/iguana/tests/addnode2 new file mode 100755 index 000000000..2840f3b51 --- /dev/null +++ b/iguana/tests/addnode2 @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTC\",\"ipaddr\":\"5.9.102.210\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTC\",\"ipaddr\":\"78.47.196.146\"}" diff --git a/iguana/tests/addnodeSYS b/iguana/tests/addnodeSYS index b4a548e1c..c55b1811f 100755 --- a/iguana/tests/addnodeSYS +++ b/iguana/tests/addnodeSYS @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"SYS\",\"ipaddr\":\"198.147.29.138\"}" curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"SYS\",\"ipaddr\":\"118.244.207.7\"}" diff --git a/iguana/tests/addnotarys b/iguana/tests/addnotarys new file mode 100755 index 000000000..a4945ed09 --- /dev/null +++ b/iguana/tests/addnotarys @@ -0,0 +1,46 @@ +#!/bin/bash +../coins/notary +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"5.9.102.210\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"78.47.196.146\"}" + +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.40.125.53\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.224.130\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.227.203\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.228.245\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.229.250\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"31.14.140.189\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"188.213.170.78\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.36.208.190\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.36.211.238\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"188.213.166.206\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.46.79.88\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.46.78.206\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.46.79.99\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.46.78.56\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"5.249.155.123\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"85.255.2.118\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"85.255.0.237\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"85.255.2.167\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"85.255.9.234\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"85.255.9.239\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.242.116\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.242.43\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.242.55\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.242.142\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.242.240\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"185.58.224.204\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"185.58.225.164\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"185.58.226.204\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.253.143\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"94.177.253.144\"}" + +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.248.160.237\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.248.160.238\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.248.160.239\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.248.160.240\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.248.160.241\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.248.160.242\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.248.160.243\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"89.248.160.244\"}" +sleep 3 +./getinfoN diff --git a/iguana/tests/addnotarys_7776 b/iguana/tests/addnotarys_7776 new file mode 100755 index 000000000..8547daa09 --- /dev/null +++ b/iguana/tests/addnotarys_7776 @@ -0,0 +1,8 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"78.47.196.146\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"149.56.29.163\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"191.235.80.138\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"52.72.135.200\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"94.102.63.226\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"129.232.225.202\"}" +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"104.255.64.3\"}" diff --git a/iguana/tests/addrelays b/iguana/tests/addrelays deleted file mode 100755 index 26dd60206..000000000 --- a/iguana/tests/addrelays +++ /dev/null @@ -1,8 +0,0 @@ -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.237\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.238\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.239\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.240\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.241\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.242\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.243\"}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.244\"}" diff --git a/iguana/tests/ahloop b/iguana/tests/ahloop index e9f287381..f91d78529 100755 --- a/iguana/tests/ahloop +++ b/iguana/tests/ahloop @@ -1,3 +1,4 @@ +#!/bin/bash ind=0 one=1 while true diff --git a/iguana/tests/allcoins b/iguana/tests/allcoins index 1454b39b7..bd1306015 100755 --- a/iguana/tests/allcoins +++ b/iguana/tests/allcoins @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"allcoins\"}" diff --git a/iguana/tests/amlp b/iguana/tests/amlp new file mode 100755 index 000000000..76856c320 --- /dev/null +++ b/iguana/tests/amlp @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"amlp\",\"blocktrail\":\"e5ddfdceb58fa6c1bf9411aaeff4b6ee28cbc370\"}" diff --git a/iguana/tests/arbinit b/iguana/tests/arbinit new file mode 100755 index 000000000..5ff0f15ef --- /dev/null +++ b/iguana/tests/arbinit @@ -0,0 +1,75 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"amlp\"}" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTC\",\"vals\":{\"rel\":\"USD\",\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTC\",\"vals\":{\"rel\":\"USD\",\"profit\":0.004,\"exchange\":\"coinbase\"}}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTC\",\"vals\":{\"rel\":\"USD\",\"profit\":0.004,\"exchange\":\"lakebtc\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTC\",\"vals\":{\"rel\":\"USD\",\"profit\":0.004,\"exchange\":\"quadriga\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTC\",\"vals\":{\"rel\":\"USD\",\"profit\":0.004,\"exchange\":\"btcd\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTC\",\"vals\":{\"rel\":\"USD\",\"profit\":0.004,\"exchange\":\"bitstamp\"}}" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTC\",\"vals\":{\"rel\":\"CNY\",\"profit\":0.004,\"exchange\":\"huobi\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTC\",\"vals\":{\"rel\":\"CNY\",\"profit\":0.004,\"exchange\":\"btc38\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"amlp\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTCD\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTCD\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"CLOAK\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"CLOAK\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"SYS\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"SYS\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"GAME\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"GAME\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"XMR\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"XMR\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"ETH\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"ETH\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"ETC\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"ETC\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"DASH\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"DASH\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"ZEC\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"ZEC\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"FCT\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"FCT\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"STRAT\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"STRAT\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"DGD\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"DGD\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"NAV\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"NAV\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"LTC\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"LTC\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"SDC\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"SDC\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"STEEM\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"STEEM\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"SBD\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"SBD\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"XRP\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"XRP\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"LSK\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"LSK\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"NXT\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"NXT\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MAID\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MAID\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BLK\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BLK\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"POT\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"POT\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"XEM\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"XEM\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"VRC\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"VRC\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"VTC\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"VTC\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTS\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BTS\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"NAUT\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"NAUT\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"AUR\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"AUR\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"REP\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"REP\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"AMP\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"AMP\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" diff --git a/iguana/tests/arbnxt b/iguana/tests/arbnxt new file mode 100755 index 000000000..0e7b25cf3 --- /dev/null +++ b/iguana/tests/arbnxt @@ -0,0 +1,16 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"amlp\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"NXT\",\"vals\":{\"profit\":0.004,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"NXT\",\"vals\":{\"profit\":0.004,\"exchange\":\"bittrex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"UNITY\",\"vals\":{\"profit\":0.01,\"exchange\":\"poloniex\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"UNITY\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"DEX\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"PANGEA\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"JUMBLR\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BET\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"CRYPTO\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"HODL\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"SHARK\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"BOTS\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"liquidity\",\"targetcoin\":\"MGW\",\"vals\":{\"rel\":\"NXT\",\"profit\":0.01,\"exchange\":\"nxtae\"}}" + diff --git a/iguana/tests/arraytest b/iguana/tests/arraytest index 4191fd1cf..3d811998b 100755 --- a/iguana/tests/arraytest +++ b/iguana/tests/arraytest @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "[{\"agent\":\"SuperNET\",\"method\":\"activehandle\"}, {\"agent\":\"bitcoinrpc\",\"activecoin\":\"BTCD\",\"method\":\"getdifficulty\"}]" diff --git a/iguana/tests/automatched b/iguana/tests/automatched index 4475dce0b..75f49e123 100755 --- a/iguana/tests/automatched +++ b/iguana/tests/automatched @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"automatched\",\"requestid\":1728286611}" diff --git a/iguana/tests/available b/iguana/tests/available index fbe1a0e22..500a09946 100755 --- a/iguana/tests/available +++ b/iguana/tests/available @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"available\",\"source\":\"BTCD\"}" diff --git a/iguana/tests/aveprice b/iguana/tests/aveprice index cc176176e..279371992 100755 --- a/iguana/tests/aveprice +++ b/iguana/tests/aveprice @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"aveprice\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"basevolume\":1.0}" diff --git a/iguana/tests/backupwallet b/iguana/tests/backupwallet index 8b0222eb7..04de4dfb1 100755 --- a/iguana/tests/backupwallet +++ b/iguana/tests/backupwallet @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"backupwallet\",\"params\":[\"testwallet\"]}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"backupwallet\",\"params\":[\"testwallet\"]}" diff --git a/iguana/tests/backupwallet2 b/iguana/tests/backupwallet2 new file mode 100755 index 000000000..04de4dfb1 --- /dev/null +++ b/iguana/tests/backupwallet2 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"backupwallet\",\"params\":[\"testwallet\"]}" diff --git a/iguana/tests/balance b/iguana/tests/balance new file mode 100755 index 000000000..5f29223dd --- /dev/null +++ b/iguana/tests/balance @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"activecoin\":\"BTCD\",\"timeout\":20000,\"agent\":\"iguana\",\"method\":\"balance\",\"address\":\"RDbGxL8QYdEp8sMULaVZS2E6XThcTKT9Jd\"}" diff --git a/iguana/tests/balance2 b/iguana/tests/balance2 new file mode 100755 index 000000000..2299cae52 --- /dev/null +++ b/iguana/tests/balance2 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"activecoin\":\"BTCD\",\"timeout\":20000,\"agent\":\"iguana\",\"method\":\"balance\",\"address\":\"RFMEYcxuBL8S7UPdUbzXunPtS4p82HRcKs\"}" diff --git a/iguana/tests/balances b/iguana/tests/balances index 4a899475f..8c109cc1e 100755 --- a/iguana/tests/balances +++ b/iguana/tests/balances @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1}}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1,\"history\":3,\"addresses\":[\"RYNE2isKrRu5b7xxm1DtXcLxdmBEKatuJY\"]}}" diff --git a/iguana/tests/basilisks b/iguana/tests/basilisks new file mode 100755 index 000000000..078d2463e --- /dev/null +++ b/iguana/tests/basilisks @@ -0,0 +1,17 @@ +#!/bin/bash +../coins/basilisk/bet +../coins/basilisk/btc +../coins/basilisk/dex +../coins/basilisk/jumblr +../coins/basilisk/mgw +../coins/basilisk/pangea +../coins/basilisk/shark +../coins/basilisk/bots +../coins/basilisk/crypto +../coins/basilisk/hodl +../coins/basilisk/kmd +../coins/basilisk/mvp +../coins/basilisk/revs +../coins/basilisk/supernet + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"paxfiats\"}" diff --git a/iguana/tests/bitcoinrpc b/iguana/tests/bitcoinrpc index dba1bd3de..18fbef257 100755 --- a/iguana/tests/bitcoinrpc +++ b/iguana/tests/bitcoinrpc @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"bitcoinrpc\",\"setcoin\":\"$1\"}" diff --git a/iguana/tests/buy b/iguana/tests/buy index 67c07d1a0..749fc8603 100755 --- a/iguana/tests/buy +++ b/iguana/tests/buy @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"buy\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.0029,\"volume\":1.0}" diff --git a/iguana/tests/buy2 b/iguana/tests/buy2 index 252ab3c60..b9044ba9e 100755 --- a/iguana/tests/buy2 +++ b/iguana/tests/buy2 @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"buy\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.0027,\"volume\":1.0}" diff --git a/iguana/tests/cancelrefresh b/iguana/tests/cancelrefresh new file mode 100755 index 000000000..35c27504d --- /dev/null +++ b/iguana/tests/cancelrefresh @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"cancelrefresh\"}" diff --git a/iguana/tests/checkwallet b/iguana/tests/checkwallet index 7df59c569..7adafdc0d 100755 --- a/iguana/tests/checkwallet +++ b/iguana/tests/checkwallet @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"checkwallet\",\"params\":[]}" diff --git a/iguana/tests/clearassets b/iguana/tests/clearassets new file mode 100755 index 000000000..e58ac362e --- /dev/null +++ b/iguana/tests/clearassets @@ -0,0 +1,33 @@ +#!/bin/bash +rm -rf ~/.USD +rm -rf ~/.EUR +rm -rf ~/.JPY +rm -rf ~/.GBP +rm -rf ~/.AUD +rm -rf ~/.CAD +rm -rf ~/.CHF +rm -rf ~/.NZD +rm -rf ~/.CNY +rm -rf ~/.RUB +rm -rf ~/.MXN +rm -rf ~/.RBL +rm -rf ~/.INR +rm -rf ~/.HKD +rm -rf ~/.TRY +rm -rf ~/.ZAR +rm -rf ~/.PLN +rm -rf ~/.NOK +rm -rf ~/.SEK +rm -rf ~/.DKK +rm -rf ~/.CZK +rm -rf ~/.HUF +rm -rf ~/.ILS +rm -rf ~/.KRW +rm -rf ~/.MYR +rm -rf ~/.PHP +rm -rf ~/.RON +rm -rf ~/.SGD +rm -rf ~/.THB +rm -rf ~/.BGN +rm -rf ~/.IDR +rm -rf ~/.HRK diff --git a/iguana/tests/crash b/iguana/tests/crash new file mode 100755 index 000000000..90be8a6d1 --- /dev/null +++ b/iguana/tests/crash @@ -0,0 +1,7 @@ +../coins/basilisk/kmd + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"amount common obey erupt ensure salon shrug digital phone vacant provide word nurse legend shaft ritual strike black fiscal circle dove tone inmate plunge\",\"timeout\":864445678904}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"amount common obey erupt ensure salon shrug digital phone vacant provide word nurse legend shaft ritual strike black fiscal circle dove tone inmate plunge\",\"timeout\":864445678904}" + +curl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"KMD\",\"agent\":\"basilisk\",\"method\":\"utxorawtx\",\"vals\":{\"timelock\":0,\"changeaddr\":\"RD5Sj6igy53nscMiFS4ECXByfqVeyV9NdG\",\"destaddr\":\"RD5Sj6igy53nscMiFS4ECXByfqVeyV9NdG\",\"txfee\":0,\"amount\":0.0001,\"sendflag\":0},\"utxos\":[{\"bestblock\":\"0000119186ecfaa8d72a7d3c62e78135043db220a6d29a9605f1fbe383bcedfb\",\"confirmations\":65549,\"value\":0.04900000,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 29a7bd36e6913b674bb2b5c65e61a6544426ddd7 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a91429a7bd36e6913b674bb2b5c65e61a6544426ddd788ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"RD5Sj6igy53nscMiFS4ECXByfqVeyV9NdG\"]},\"version\":1,\"coinbase\":false,\"randipbits\":579036043,\"coin\":\"KMD\",\"txid\":\"b32af9977bc8ed0e54631d27f490c79841a03bccce4d6b8181456657b06194ef\",\"vout\":0,\"amount\":0.04900000}, {\"bestblock\":\"0000119186ecfaa8d72a7d3c62e78135043db220a6d29a9605f1fbe383bcedfb\",\"confirmations\":65553,\"value\":1,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 29a7bd36e6913b674bb2b5c65e61a6544426ddd7 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a91429a7bd36e6913b674bb2b5c65e61a6544426ddd788ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"RD5Sj6igy53nscMiFS4ECXByfqVeyV9NdG\"]},\"version\":1,\"coinbase\":false,\"randipbits\":3795805790,\"coin\":\"KMD\",\"txid\":\"84ca2ba7f621c820ab642e358813fcc33171c9999a47bb99dcf3a309dc847419\",\"vout\":1,\"amount\":1}]}" + diff --git a/iguana/tests/creategtx b/iguana/tests/creategtx index fedeb0764..5ddd50a8f 100755 --- a/iguana/tests/creategtx +++ b/iguana/tests/creategtx @@ -1,2 +1,4 @@ +#!/bin/bash +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"DEX\",\"method\":\"createrawtransaction\",\"params\":[[], {\"data\":\"deadbeef\"}] }" diff --git a/iguana/tests/createmultisig b/iguana/tests/createmultisig index 84f093b80..22476b715 100755 --- a/iguana/tests/createmultisig +++ b/iguana/tests/createmultisig @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"createmultisig\",\"params\":[2, [\"002629c77b81a4d338a339488aaff796a93aeec8c734b22dee865d0ff58ff64c\", \"d0296ed1364639c696c374730320480301f3194c86231f62f0409cd76467f87c\", \"d045925b3e6f648bca6ed0c65149ee445137f0ab14e88cf60013d88419bcdd60\"]]}" diff --git a/iguana/tests/createrawtransaction b/iguana/tests/createrawtransaction index 47fc3c1cd..3120e1520 100755 --- a/iguana/tests/createrawtransaction +++ b/iguana/tests/createrawtransaction @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"createrawtransaction\",\"params\":[[{\"txid\":\"e8a0cc971e769de1fcf9d4abb734acb9ab4ab7f44d9eb7d9cd96707b847dd1f6\",\"vout\":0}], {\"RAoMou7euzvDwa9dQwjrNB5A41hrAWgvBt\":0.01,\"RV37MfeBD1QTeoLHteab3j4mFVrsSaGMJx\":0.0093}] }" diff --git a/iguana/tests/createrawtransactionA b/iguana/tests/createrawtransactionA index 9673ce27e..6fd6d865a 100755 --- a/iguana/tests/createrawtransactionA +++ b/iguana/tests/createrawtransactionA @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"createrawtransaction\",\"params\":[[{\"txid\":\"e8a0cc971e769de1fcf9d4abb734acb9ab4ab7f44d9eb7d9cd96707b847dd1f6\",\"vout\":0}], [{\"RAoMou7euzvDwa9dQwjrNB5A41hrAWgvBt\":0.01,\"RV37MfeBD1QTeoLHteab3j4mFVrsSaGMJx\":0.0093}]] }" diff --git a/iguana/tests/createrawtransactionT b/iguana/tests/createrawtransactionT index 1e48c0e7f..7105c977c 100755 --- a/iguana/tests/createrawtransactionT +++ b/iguana/tests/createrawtransactionT @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"createrawtransaction\",\"params\":[[{\"txid\":\"2196c07f71f206728301b03ffbffb7fd383744d03c1a3e0a1e03b6fb9ffd4ece\",\"vout\":1}], {\"1E4EadLDvqRWgSPRLqTM5YXefdaxsPPZVs\":0.009}] }" diff --git a/iguana/tests/createrelay b/iguana/tests/createrelay index 1ed85c205..b613c3db8 100755 --- a/iguana/tests/createrelay +++ b/iguana/tests/createrelay @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:14632" --data "{\"method\":\"createrelay\",\"params\":[\"ipaddr\", \"secp\", \"curve25519\"] }" diff --git a/iguana/tests/d b/iguana/tests/d index feb7a8e97..972887308 100755 --- a/iguana/tests/d +++ b/iguana/tests/d @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"decoderawtransaction\",\"params\":[\"010000009049a757019cb804dc1c70059d45c8d135bd630b2be9fcd27dd6c9d5510aec0d25e43f734b01000000834730440220777a24cf3b508571eeb597c3c8055dbf84e5a2bd17ff574a6fab7b258c10a37902200241979f977098b6691572642251bdc8f5737ec2fe7c20e95871774fb0e675200121020ce8ffc263769bfa15579b2757873ea5690107acfafb6dc1b77cd7057ac3834900000000000000000000000000000000000000000000000000ffffffff028096980000000000475221021193f3676d50b15b51a386af7a93bac569a8a71536cb3f41775cc1906771e97121032991f9c5088fca3d839c1971889c2f671d98551af2386c89628ea49f7c0b0df552ae00947604000000001976a91421e112f4211cbc612bc5f3de86acf0017b88b67d88ac00000000\", 0]}" diff --git a/iguana/tests/decodegtx b/iguana/tests/decodegtx index 54f389941..cf0447e71 100755 --- a/iguana/tests/decodegtx +++ b/iguana/tests/decodegtx @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"DEX\",\"method\":\"decoderawtransaction\",\"params\":[\"01000000018efaaa9bdf615b126eb7c84aad2b2dfa3517cd885d35be4584cceec61f619d0a0000000001014c68630405c5a357b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a914f0a979f6abfb2f9e2e76b96b9252307d3b873f5088210398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcbf4baac68510000000001db390000000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac05c5a357\"]}" diff --git a/iguana/tests/decoderawtransaction b/iguana/tests/decoderawtransaction index 8a4671500..50f98b8be 100755 --- a/iguana/tests/decoderawtransaction +++ b/iguana/tests/decoderawtransaction @@ -1 +1,3 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"decoderawtransaction\",\"params\":[\"010000000f0ea95701466304197095eeceb34a9b8cc57b34a9d069f37cb3c0aedcb71c5f3c0858afd50000000090004730440220626010de8205712edb16560410fb2e99c1c602aa25d77575471321c62c1b33e30220684ab1e4037e1b38c25fb1f175e07a54621ffca4e37659019dcfa1d7ac463b0e0147304402205f907d97d9b229ce660f4bf13382e04132e042d49d1ea043a3043ea76e4c6f710220177f69d1be52744c0f55b2be106575159efffd5c8d84ca85b2cb0741d022fbaa01ffffffff01706f9800000000001976a91454a752f0d71b89d7c014ed0be29ca231c9546f9f88ac00000000\", 1]}" +#!/bin/bash +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"decoderawtransaction\",\"params\":[\"0100000008d70d193b7e3a9b8605f78757ae0c65807a9f56e5853cfc51b4b39847fd75943e0100000000fffffffffaeb9b0c2637cd94f9831f0d71309e9d62ee3fda70f17abf8c51221a293275750200000000ffffffffc48bd20f4e186faf4ae665ad9549d1663e13725908097cb48e1e582feb0d374f1d00000000ffffffffb9480d1b24c1374f013e4ef514ecdb2e49da8c4174d8f546b29973493109e1ae2400000000fffffffffe3d8e123baaaaffabbbbc4de921089bd81e27b8e19b0d62cec0ec9d1f0640620800000000ffffffff5e920a3ef55f0f0ea9d003f8588cfeca79705cffe0c5658af48384a3f662e1762400000000ffffffff093140fbda2ee097df32a12060eafef38de302402b377c4fc3ee1fd2ee90747e1f00000000ffffffffd00b6f16fff640bbe2af368cb2c1592dd57c972b8e84a0ea8bb71f7aa634b11e2c00000000ffffffff4270170000000000002321020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9ac7017000000000000232103b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828ac7017000000000000232102ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344ac70170000000000002321029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90ac7017000000000000232103f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ceac701700000000000023210224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842ac7017000000000000232102bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937ac701700000000000023210209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9eac7017000000000000232102afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7ac70170000000000002321026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530bac701700000000000023210340c66cf2c41c41efb420af57867baa765e8468c12aa996bfd816e1e07e410728ac70170000000000002321029e1c01131974f4cd3f564cc0c00eb87a0f9721043fbc1ca60f9bd0a1f73f64a1ac7017000000000000232102313d72f9a16055737e14cfc528dcd5d0ef094cfce23d0348fe974b6b1a32e5f0ac7017000000000000232102bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57ac701700000000000023210281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7ac7017000000000000232102757999e651200ac24ff808e5dc7762ba64da1b940c7b150980f636a3866d6de9ac701700000000000023210252b6185bf8ea7efe8bbc345ddc8da87329149f30233088387abd716d4aa9e974ac70170000000000002321025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682ddeac701700000000000023210300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3fac701700000000000023210396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030ac701700000000000023210204a908350b8142698fdb6fabefc97fe0e04f537adc7522ba7a1e8f3bec003d4aac7017000000000000232103e928cdb694cd3805a03e6f792ac0ba177c3261d98401e9a5450f512fdb89bd09ac701700000000000023210396699a1792207b39cd20629a51e0825e075d3a80f0237a95d4385ad2a12d88fbac70170000000000002321034e804867936874d2dcef56ab5696f5fba059db069eb4f5c2887c61e6c60638b1ac7017000000000000232103adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132ac7017000000000000232103212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68ac701700000000000023210221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303cac70170000000000002321023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6ac7017000000000000232102a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982ac7017000000000000232102b74e712998ca1e9580c8c0851f20f79563afd65a22d47d47e184d951bcc1e135ac7017000000000000232103016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6ac7017000000000000232103f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692bac7017000000000000232102e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58cac7017000000000000232102aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185ac7017000000000000232102ea030819f09586aa33fa57c1daf80782880e509c9bae87ef8fde1a08acf78599ac7017000000000000232102b714aa5833d7a76700c429d5542cea409826d3668ba9d75ec3407a607450563cac70170000000000002321022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3ac70170000000000002321021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42ac7017000000000000232102efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80ac70170000000000002321031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859ac70170000000000002321022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005eac701700000000000023210252b6185bf8ea7efe8bbc345ddc8da87329149f30233088387abd716d4aa9e974ac70170000000000002321032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899ac7017000000000000232102708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622ac70170000000000002321032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735ac701700000000000023210225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29dac70170000000000002321031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411ac7017000000000000232102209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36ac7017000000000000232103681ffdf17c8f4f0008cefb7fa0779c5e888339cdf932f0974483787a4d6747c1ac7017000000000000232102ffda5a0147e781308fe66a1774793eacd9b35829073746b217845cfe7577b7dcac701700000000000023210287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edecac7017000000000000232103f381ba12b70fb3c5c790ca0131a200534d608c301ff8ccca93abe4cc3444ae5bac70170000000000002321037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377ac7017000000000000232103f2a02e212604afeff85bedd15703a3e47a13650013e04609140a7b3109d08f77ac70170000000000002321029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355ac7017000000000000232102061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546ac70170000000000002321033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1ac7017000000000000232103cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185ac7017000000000000232103517fcac101fed480ae4f2caf775560065957930d8c1facc83e30077e45bdd199ac701700000000000023210387046d9745414fb58a0fa3599078af5073e10347e4657ef7259a99cb4f10ad47ac70170000000000002321035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960ac70170000000000002321024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3ac7017000000000000232103f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1ac70170000000000002321033fb7231bb66484081952890d9a03f91164fb27d392d9152ec41336b71b15fbd0ac701700000000000023210334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65eac00000000000000002a6a280000000000000000000000000000000000000000000000000000000000000000000000004b4d440000000000\", 1]}" diff --git a/iguana/tests/decoderawtransactionB b/iguana/tests/decoderawtransactionB index 695f44691..bf7176403 100755 --- a/iguana/tests/decoderawtransactionB +++ b/iguana/tests/decoderawtransactionB @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"decoderawtransaction\",\"params\":[\"01000000e37486570105cbd4d0058c3d7842966917456cbb4202ba90489abaa142dc093755b10a077d010000000100ffffffff0200e1f505000000004752210211a23a9bbbb43784b0b0198bab1cc6dbf2bab6cf3dd96a428ec6916267c80e70210372e08a8a353ba0190f513b3980d8229f4afecddbf014052199799875a924e56752ae50677235000000001976a914c210f6711e98fe9971757ede2b2dcb0507f3f25e88ac00000000\"]}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"decoderawtransaction\",\"params\":[\"01000000e54ce857013758a47167e70d79da65c98ea85153f5585201caef2941d035e9d46b4a4b2aba00000000db00483045022100e4f539cd49b9e7c69ce7a486a37671a7a8f3260a4801576fb086450342efd67102204157d8fa172c48abed5c33ed9228a77d42825d59901c06c0d2d4a778b92f1b82014830450221008f1a9aa8b0fdcad174f981c53ddd74f09d054a2ec9fe7328b4b7354cb83f3d7f02201fac19a9e0f2c32707f0e9fbc2a97540d225cdb8a1cb8ed06025f6b170035c400147522102b33efbc5046df029620fdc84f6b294a725ba66a585851f63400f3c10781f86bc2103ee87c99f4665df9a9958de06493498392bc1c977936c2b84a4461f9e593c145352aeffffffff01706f9800000000001976a9148ee61a3161993f4f7b7081259bf5f3322d65d3f888ac00000000\"]}" diff --git a/iguana/tests/dexalladdresses b/iguana/tests/dexalladdresses new file mode 100755 index 000000000..d638ad15c --- /dev/null +++ b/iguana/tests/dexalladdresses @@ -0,0 +1,9 @@ +#!/bin/bash +echo BTC +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"alladdresses\",\"symbol\":\"BTC\"}" +echo KMD +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"alladdresses\",\"symbol\":\"KMD\"}" +echo MVP +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"alladdresses\",\"symbol\":\"MVP\"}" +echo USD +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"alladdresses\",\"symbol\":\"USD\"}" diff --git a/iguana/tests/dexcheckaddress b/iguana/tests/dexcheckaddress new file mode 100755 index 000000000..2ffb57a10 --- /dev/null +++ b/iguana/tests/dexcheckaddress @@ -0,0 +1,5 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"checkaddress\",\"address\":\"RYHpUJFaB4QHUW8jCJCCNL2kzWq3D3QoyG\",\"symbol\":\"KMD\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"checkaddress\",\"address\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"symbol\":\"BTC\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"checkaddress\",\"address\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"symbol\":\"USD\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"checkaddress\",\"address\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"symbol\":\"MVP\"}" diff --git a/iguana/tests/dexexplorer b/iguana/tests/dexexplorer new file mode 100755 index 000000000..460ce8631 --- /dev/null +++ b/iguana/tests/dexexplorer @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"explorer\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexgetB b/iguana/tests/dexgetB new file mode 100755 index 000000000..5511ca49d --- /dev/null +++ b/iguana/tests/dexgetB @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getblock\",\"hash\":\"02faa3cb03cf4bad4522303877cfa23abe6ccd3c070176efd684f77ca2e56d95\",\"symbol\":\"SHARK\"}" diff --git a/iguana/tests/dexgetH b/iguana/tests/dexgetH new file mode 100755 index 000000000..e92625b22 --- /dev/null +++ b/iguana/tests/dexgetH @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getblockhash\",\"height\":100,\"symbol\":\"SHARK\"}" diff --git a/iguana/tests/dexgetO b/iguana/tests/dexgetO new file mode 100755 index 000000000..8f3ab668e --- /dev/null +++ b/iguana/tests/dexgetO @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"gettxout\",\"vout\":0,\"txid\":\"8661a47003ce3d1712dee5798432475b6b7abb65ba88c4f26eb37446b9038973\",\"symbol\":\"BTC\"}" diff --git a/iguana/tests/dexgetT b/iguana/tests/dexgetT new file mode 100755 index 000000000..18241a84d --- /dev/null +++ b/iguana/tests/dexgetT @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"gettransaction\",\"txid\":\"88794bbb699f130951c40dc99a27d2c7c7016e12824fd1040cbedf86980de04d\",\"symbol\":\"REVS\"}" diff --git a/iguana/tests/dexgetbalance b/iguana/tests/dexgetbalance new file mode 100755 index 000000000..f096618ee --- /dev/null +++ b/iguana/tests/dexgetbalance @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"RYZx1e7kVNTuQ6RTrvTkYeZAz5uJobC3pg\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexgetbestblockhash b/iguana/tests/dexgetbestblockhash new file mode 100755 index 000000000..45b501dcc --- /dev/null +++ b/iguana/tests/dexgetbestblockhash @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbestblockhash\",\"symbol\":\"BTC\"}" diff --git a/iguana/tests/dexgetinfo b/iguana/tests/dexgetinfo new file mode 100755 index 000000000..0d89dba21 --- /dev/null +++ b/iguana/tests/dexgetinfo @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getinfo\",\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getinfo\",\"symbol\":\"LTC\"}" diff --git a/iguana/tests/dexgetsupply b/iguana/tests/dexgetsupply new file mode 100755 index 000000000..9d843eb19 --- /dev/null +++ b/iguana/tests/dexgetsupply @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getbalance\",\"address\":\"*\",\"symbol\":\"KMD\",\"timeout\":600000}" diff --git a/iguana/tests/dexgettxin b/iguana/tests/dexgettxin new file mode 100755 index 000000000..70abbb1db --- /dev/null +++ b/iguana/tests/dexgettxin @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"gettxin\",\"vout\":0,\"txid\":\"cad09f4c3e23ef4cde4980cc0e2b296943f22cbaac183a30f86f49f7eccfedfd\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/deximportaddress b/iguana/tests/deximportaddress new file mode 100755 index 000000000..a4a923291 --- /dev/null +++ b/iguana/tests/deximportaddress @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"importaddress\",\"address\":\"R9pgJYo7ZeTJPQWJYHxgmdM8uXY6Pv7NUe\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexkvsearch b/iguana/tests/dexkvsearch new file mode 100755 index 000000000..8391dea10 --- /dev/null +++ b/iguana/tests/dexkvsearch @@ -0,0 +1,4 @@ +#!/bin/bash +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvsearch\",\"key\":\"foo\",\"symbol\":\"KMD\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvsearch\",\"key\":\"test\",\"symbol\":\"KV\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvsearch\",\"key\":\"ec474661-de713a84\",\"symbol\":\"KV\"}" diff --git a/iguana/tests/dexkvupdate b/iguana/tests/dexkvupdate new file mode 100755 index 000000000..a6792a142 --- /dev/null +++ b/iguana/tests/dexkvupdate @@ -0,0 +1,3 @@ +#!/bin/bash +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvupdate\",\"key\":\"test\",\"value\":\"$1\",\"flags\":0,\"symbol\":\"KMD\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"kvupdate\",\"key\":\"testtest\",\"value\":\"$1\",\"flags\":0,\"symbol\":\"KV\"}" diff --git a/iguana/tests/dexlistspent b/iguana/tests/dexlistspent new file mode 100755 index 000000000..9b2a2c3d9 --- /dev/null +++ b/iguana/tests/dexlistspent @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listspent\",\"address\":\"RU58D7nNLXwD29hgC2MPgtAF458gGxnPYS\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexlisttransactions b/iguana/tests/dexlisttransactions new file mode 100755 index 000000000..09a94f406 --- /dev/null +++ b/iguana/tests/dexlisttransactions @@ -0,0 +1,5 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"RWE3NWHT6Fb1zW4mY9LU859MPoWGYvtLfj\",\"count\":100,\"skip\":0,\"symbol\":\"KMD\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"count\":100,\"skip\":0,\"symbol\":\"MVP\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"RMGpGoX82M1ZUUbHxZ3JKHacxY9NYVakqr\",\"count\":100,\"skip\":0,\"symbol\":\"USD\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions\",\"address\":\"RMGpGoX82M1ZUUbHxZ3JKHacxY9NYVakqr\",\"count\":100,\"skip\":0,\"symbol\":\"MVP\"}" diff --git a/iguana/tests/dexlisttransactions2 b/iguana/tests/dexlisttransactions2 new file mode 100755 index 000000000..ba225b1dd --- /dev/null +++ b/iguana/tests/dexlisttransactions2 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listtransactions2\",\"address\":\"RDobQ77wnMY8Me7RAL9oiFqVNvwkqqgPRF\",\"count\":100,\"skip\":0,\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexlistunspent b/iguana/tests/dexlistunspent new file mode 100755 index 000000000..4e13419d8 --- /dev/null +++ b/iguana/tests/dexlistunspent @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent\",\"address\":\"RNmvQtThVZAbc1tFEFmKAnJZrc9XqciNog\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexlistunspent2 b/iguana/tests/dexlistunspent2 new file mode 100755 index 000000000..f66da368b --- /dev/null +++ b/iguana/tests/dexlistunspent2 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"listunspent2\",\"address\":\"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexnotaries b/iguana/tests/dexnotaries new file mode 100755 index 000000000..1da169442 --- /dev/null +++ b/iguana/tests/dexnotaries @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getnotaries\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexpsock b/iguana/tests/dexpsock new file mode 100755 index 000000000..0a0e6fb16 --- /dev/null +++ b/iguana/tests/dexpsock @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"psock\"}" diff --git a/iguana/tests/dexsend b/iguana/tests/dexsend new file mode 100755 index 000000000..5e8d619ef --- /dev/null +++ b/iguana/tests/dexsend @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"send\",\"hex\":\"deadbeef\"}" diff --git a/iguana/tests/dexsend_7776 b/iguana/tests/dexsend_7776 new file mode 100755 index 000000000..b43998bef --- /dev/null +++ b/iguana/tests/dexsend_7776 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"dex\",\"method\":\"send\",\"hex\":\"deadbeef\"}" diff --git a/iguana/tests/dexsendrawtransaction b/iguana/tests/dexsendrawtransaction new file mode 100755 index 000000000..f3796ea37 --- /dev/null +++ b/iguana/tests/dexsendrawtransaction @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"sendrawtransaction\",\"signedtx\":\"01000000010c42a05c0c04f7dc575ab93a7c0b5faa9ff285ddcbcc1cd10bc18a7126201a4a010000006b483045022100814b44c4af1beeb7ab3abdd7dfd95216b48da2f47ded4137f3dca366db4a94bc0220686108f29cc1eea5c845b7571e01412a373e5077d448e021bac7e8a19ec451a20121025879c9eaa100984ee1faaeb55bcbafed5b1f565c35ed7ebaadcce0a8416e6263ffffffff0240420f00000000001976a914c5a58530ee7bec4f5ab9a8c0c63069484273276c88ac34955836020000001976a914971f98b33fb838faee190e2fab799440d8c5170288acf70ab858\",\"symbol\":\"KMD\"}" diff --git a/iguana/tests/dexvalidate b/iguana/tests/dexvalidate new file mode 100755 index 000000000..0136b6fbb --- /dev/null +++ b/iguana/tests/dexvalidate @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"validateaddress\",\"address\":\"1En4tL4drN5qAZDtu1BCC7DThj58yrx7cX\",\"symbol\":\"BTC\"}" diff --git a/iguana/tests/dividends b/iguana/tests/dividends new file mode 100755 index 000000000..aa39a4c3d --- /dev/null +++ b/iguana/tests/dividends @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"dividends\",\"height\":1486500,\"symbol\":\"BTCD\",\"vals\":{\"exclude\":[\"RWc6VDt5SdjnWXoVQ2AJsuxU2QSaDcG5R7\", \"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\"],\"dust\":0,\"dividend\":0,\"system\":0,\"prefix\":\"fiat/revs sendtoaddress\",\"suffix\":\"\"}}" + diff --git a/iguana/tests/dpow b/iguana/tests/dpow new file mode 100755 index 000000000..b11b68ec3 --- /dev/null +++ b/iguana/tests/dpow @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"020e0f6fe6e0fcdcac541eb728d6fe538a12adff20412b3c8a7fa892b223a47c2f\"}" diff --git a/iguana/tests/dpow_7776 b/iguana/tests/dpow_7776 new file mode 100755 index 000000000..cdb0bf06e --- /dev/null +++ b/iguana/tests/dpow_7776 @@ -0,0 +1,3 @@ +#!/bin/bash +source pubkey.txt +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}" diff --git a/iguana/tests/dumpprivkey b/iguana/tests/dumpprivkey index 3c6151dc5..3bc231d35 100755 --- a/iguana/tests/dumpprivkey +++ b/iguana/tests/dumpprivkey @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RLaBkgU3Y61VLXPNjBd2cW1RfkghXU8yHt\"]}" diff --git a/iguana/tests/dumpprivkeyB b/iguana/tests/dumpprivkeyB index 3c6151dc5..3bc231d35 100755 --- a/iguana/tests/dumpprivkeyB +++ b/iguana/tests/dumpprivkeyB @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RLaBkgU3Y61VLXPNjBd2cW1RfkghXU8yHt\"]}" diff --git a/iguana/tests/dumpprivkeyC b/iguana/tests/dumpprivkeyC index f5e88c91a..a73e593cf 100755 --- a/iguana/tests/dumpprivkeyC +++ b/iguana/tests/dumpprivkeyC @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RBNzdRUrY2iDsjucQVEtEF1jyohYLg1d7U\"]}" diff --git a/iguana/tests/dumpprivkeyP b/iguana/tests/dumpprivkeyP index a37d9682f..e41683795 100755 --- a/iguana/tests/dumpprivkeyP +++ b/iguana/tests/dumpprivkeyP @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"bGgDwtn375uarXH3AqNfNLBKFHF7YGcFhN\"]}" diff --git a/iguana/tests/dumpprivkeyR b/iguana/tests/dumpprivkeyR index 15572b565..02c9bc3e5 100755 --- a/iguana/tests/dumpprivkeyR +++ b/iguana/tests/dumpprivkeyR @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"522102c866c51b603e2d943774314b88aff1eb04aef3971fcf34503c8f07d27915bc1d2102e053cc9d98d9e157917ed74bcabeaf72006b1ecf019d148dd3eac06271b6bcf02102869ca05bf6b476bb8cb433e08846a67037b921062f49cd0f9f66087454e88abb53ae\"]}" diff --git a/iguana/tests/dumpwallet b/iguana/tests/dumpwallet index 5ec708ec9..f573697a2 100755 --- a/iguana/tests/dumpwallet +++ b/iguana/tests/dumpwallet @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpwallet\",\"params\":[]}" diff --git a/iguana/tests/encryptwallet b/iguana/tests/encryptwallet index 1af7926be..2d99cd534 100755 --- a/iguana/tests/encryptwallet +++ b/iguana/tests/encryptwallet @@ -1 +1,3 @@ -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"test\"}" +#!/bin/bash +../coins/basilisk/kmd +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"KMD\",\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"test\"}" diff --git a/iguana/tests/encryptwallet2 b/iguana/tests/encryptwallet2 index 36fd9d69e..ee4aac780 100755 --- a/iguana/tests/encryptwallet2 +++ b/iguana/tests/encryptwallet2 @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"test2\"}" diff --git a/iguana/tests/events b/iguana/tests/events index a51fc4cf7..73718832b 100755 --- a/iguana/tests/events +++ b/iguana/tests/events @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"events\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/eventsV b/iguana/tests/eventsV index 975f88de8..16de7b1dc 100755 --- a/iguana/tests/eventsV +++ b/iguana/tests/eventsV @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"events\",\"base\":\"VPN\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/firstheight b/iguana/tests/firstheight index d5b181d7c..60502c019 100755 --- a/iguana/tests/firstheight +++ b/iguana/tests/firstheight @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1,\"history\":3,\"firstheight\":1181452}}" diff --git a/iguana/tests/fundBTC b/iguana/tests/fundBTC new file mode 100755 index 000000000..6d423164c --- /dev/null +++ b/iguana/tests/fundBTC @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dpow\",\"method\":\"fundnotaries\",\"symbol\":\"BTC\",\"numblocks\":0}" diff --git a/iguana/tests/fundfiats b/iguana/tests/fundfiats new file mode 100755 index 000000000..ff7637885 --- /dev/null +++ b/iguana/tests/fundfiats @@ -0,0 +1,34 @@ +#!/bin/bash +set -x +~/komodo/src/komodo-cli paxdeposit $1 1 aud +~/komodo/src/komodo-cli paxdeposit $1 1 bgn +~/komodo/src/komodo-cli paxdeposit $1 1 cad +~/komodo/src/komodo-cli paxdeposit $1 1 chf +~/komodo/src/komodo-cli paxdeposit $1 1 cny +~/komodo/src/komodo-cli paxdeposit $1 1 czk +~/komodo/src/komodo-cli paxdeposit $1 1 dkk +~/komodo/src/komodo-cli paxdeposit $1 1 eur +~/komodo/src/komodo-cli paxdeposit $1 1 gbp +~/komodo/src/komodo-cli paxdeposit $1 1 hkd +~/komodo/src/komodo-cli paxdeposit $1 1 hrk +~/komodo/src/komodo-cli paxdeposit $1 1 huf +~/komodo/src/komodo-cli paxdeposit $1 1 idr +~/komodo/src/komodo-cli paxdeposit $1 1 ils +~/komodo/src/komodo-cli paxdeposit $1 1 inr +~/komodo/src/komodo-cli paxdeposit $1 1 jpy +~/komodo/src/komodo-cli paxdeposit $1 1 krw +~/komodo/src/komodo-cli paxdeposit $1 1 mxn +~/komodo/src/komodo-cli paxdeposit $1 1 myr +~/komodo/src/komodo-cli paxdeposit $1 1 nok +~/komodo/src/komodo-cli paxdeposit $1 1 nzd +~/komodo/src/komodo-cli paxdeposit $1 1 php +~/komodo/src/komodo-cli paxdeposit $1 1 pln +~/komodo/src/komodo-cli paxdeposit $1 1 brl +~/komodo/src/komodo-cli paxdeposit $1 1 ron +~/komodo/src/komodo-cli paxdeposit $1 1 rub +~/komodo/src/komodo-cli paxdeposit $1 1 sek +~/komodo/src/komodo-cli paxdeposit $1 1 sgd +~/komodo/src/komodo-cli paxdeposit $1 1 thb +~/komodo/src/komodo-cli paxdeposit $1 1 try +~/komodo/src/komodo-cli paxdeposit $1 1 usd +~/komodo/src/komodo-cli paxdeposit $1 1 zar diff --git a/iguana/tests/fundnotaries b/iguana/tests/fundnotaries new file mode 100755 index 000000000..f36590638 --- /dev/null +++ b/iguana/tests/fundnotaries @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dpow\",\"method\":\"fundnotaries\",\"symbol\":\"$1\"}" diff --git a/iguana/tests/genesis b/iguana/tests/genesis index 01bcfd446..3b5136a58 100755 --- a/iguana/tests/genesis +++ b/iguana/tests/genesis @@ -1 +1,3 @@ +#!/bin/bash +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"geckogenesis\"}" diff --git a/iguana/tests/gensvm b/iguana/tests/gensvm new file mode 100755 index 000000000..d4e749a50 --- /dev/null +++ b/iguana/tests/gensvm @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"gensvm\",\"base\":\"BTC\",\"rel\":\"USD\"}" +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"gensvm\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/get b/iguana/tests/get index fa1f49360..72b3e9239 100755 --- a/iguana/tests/get +++ b/iguana/tests/get @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"getmessage\",\"vals\":{\"channel\":12345,\"msgid\":1}}" diff --git a/iguana/tests/getaccountaddress b/iguana/tests/getaccountaddress index c9acb6bbc..5cc0f75cc 100755 --- a/iguana/tests/getaccountaddress +++ b/iguana/tests/getaccountaddress @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccountaddress\",\"account\":\"test\"}" diff --git a/iguana/tests/getaddressesbyaccount b/iguana/tests/getaddressesbyaccount index 1ec011ea1..f85d8980b 100755 --- a/iguana/tests/getaddressesbyaccount +++ b/iguana/tests/getaddressesbyaccount @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"agent\":\"bitcoinrpc\",\"method\":\"getaddressesbyaccount\",\"account\":\"*\"}" diff --git a/iguana/tests/getbalance b/iguana/tests/getbalance index 5256439f2..d6ddcdf35 100755 --- a/iguana/tests/getbalance +++ b/iguana/tests/getbalance @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getbalance\",\"params\":[\"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm\"]}" diff --git a/iguana/tests/getbalanceall b/iguana/tests/getbalanceall index 86b6fe557..ddb992fe9 100755 --- a/iguana/tests/getbalanceall +++ b/iguana/tests/getbalanceall @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getbalance\",\"params\":[\"*\"]}" diff --git a/iguana/tests/getblock b/iguana/tests/getblock index b051ba6a5..9030b51f4 100755 --- a/iguana/tests/getblock +++ b/iguana/tests/getblock @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblock\",\"params\":[\"0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46\"]}" diff --git a/iguana/tests/getblockcount b/iguana/tests/getblockcount index ca9ec4b9f..06002d20e 100755 --- a/iguana/tests/getblockcount +++ b/iguana/tests/getblockcount @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblockcount\",\"params\":[]}" diff --git a/iguana/tests/getblockhash b/iguana/tests/getblockhash index 9537a87d3..ab63fdeb6 100755 --- a/iguana/tests/getblockhash +++ b/iguana/tests/getblockhash @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblockhash\",\"params\":[0]}" diff --git a/iguana/tests/getconnectioncount b/iguana/tests/getconnectioncount index efcec901f..255d38bbb 100755 --- a/iguana/tests/getconnectioncount +++ b/iguana/tests/getconnectioncount @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getconnectioncount\",\"params\":[]}" diff --git a/iguana/tests/getdifficulty b/iguana/tests/getdifficulty index 06f406304..476aef6ef 100755 --- a/iguana/tests/getdifficulty +++ b/iguana/tests/getdifficulty @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getdifficulty\",\"params\":[]}" diff --git a/iguana/tests/getinfo b/iguana/tests/getinfo index 755bee524..3f0a59664 100755 --- a/iguana/tests/getinfo +++ b/iguana/tests/getinfo @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getinfo\",\"params\":[]}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"WLC\",\"method\":\"getinfo\",\"params\":[]}" diff --git a/iguana/tests/getinfo2 b/iguana/tests/getinfo2 new file mode 100755 index 000000000..5da475d91 --- /dev/null +++ b/iguana/tests/getinfo2 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:14632" --data "{\"coin\":\"BTCD\",\"method\":\"getinfo\",\"params\":[]}" diff --git a/iguana/tests/getinfoN b/iguana/tests/getinfoN new file mode 100755 index 000000000..85851456d --- /dev/null +++ b/iguana/tests/getinfoN @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"NOTARY\",\"method\":\"getinfo\",\"params\":[]}" diff --git a/iguana/tests/getinfoN_7776 b/iguana/tests/getinfoN_7776 new file mode 100755 index 000000000..3ca934d51 --- /dev/null +++ b/iguana/tests/getinfoN_7776 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"coin\":\"NOTARY\",\"method\":\"getinfo\",\"params\":[]}" diff --git a/iguana/tests/getinfoS b/iguana/tests/getinfoS new file mode 100755 index 000000000..35e732fc9 --- /dev/null +++ b/iguana/tests/getinfoS @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"SHARK\",\"method\":\"getinfo\",\"params\":[]}" diff --git a/iguana/tests/getmessage b/iguana/tests/getmessage index 571382e44..00696f32f 100755 --- a/iguana/tests/getmessage +++ b/iguana/tests/getmessage @@ -1 +1,3 @@ +#!/bin/bash +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"getmessage\",\"vals\":{\"channel\":5784900,\"width\":60}}" diff --git a/iguana/tests/getnewaddress b/iguana/tests/getnewaddress index 26c316dbf..2a8120821 100755 --- a/iguana/tests/getnewaddress +++ b/iguana/tests/getnewaddress @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getnewaddress\",\"account\":\"\"}" diff --git a/iguana/tests/getpeers b/iguana/tests/getpeers index d7cb39eb3..7b6aafe26 100755 --- a/iguana/tests/getpeers +++ b/iguana/tests/getpeers @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"getpeers\",\"activecoin\":\"BTCD\"}" diff --git a/iguana/tests/getrawtransaction b/iguana/tests/getrawtransaction index e541e19e8..54f3c7b09 100755 --- a/iguana/tests/getrawtransaction +++ b/iguana/tests/getrawtransaction @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getrawtransaction\",\"params\":[\"fe9ba49c411ee7b3ae16f8de6f2e32b4ea469a8ff64766be113817646100bb56\"]}" diff --git a/iguana/tests/getreceivedbyaddress b/iguana/tests/getreceivedbyaddress index 6f652200a..97c832b0c 100755 --- a/iguana/tests/getreceivedbyaddress +++ b/iguana/tests/getreceivedbyaddress @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getreceivedbyaddress\",\"params\":[\"RL1tyXPK5NzT1d4upgcHnujgG5v3xjLaYC\"]}" diff --git a/iguana/tests/gettransaction b/iguana/tests/gettransaction index a03d7fd7a..a7fcae75b 100755 --- a/iguana/tests/gettransaction +++ b/iguana/tests/gettransaction @@ -1,2 +1,4 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"gettransaction\",\"coin\":\"BTCD\",\"params\":[\"f19aa5e469be3864030f44f184638d55ddc6bf66c7eecf1697c22092421901e7\"]}" +#!/bin/bash +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"gettransaction\",\"coin\":\"BTCD\",\"params\":[\"8091ecac0b6796bac05fed2838c1951a25b86c4ced31f9f711b0711c839dbbea\"]}" diff --git a/iguana/tests/gettxout b/iguana/tests/gettxout index 107624225..25e276573 100755 --- a/iguana/tests/gettxout +++ b/iguana/tests/gettxout @@ -1,2 +1,3 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"gettxout\",\"params\":[\"091c99b7b7f9b83ad2385c45b342ed5dd57035d15ff812262a3ceb3f1b291a5a\", 1]}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"KMD\",\"method\":\"gettxout\",\"params\":[\"78d8efb10877c2293d5f2ed6fd3b7ff2da4f599ab63de25043e9211ddb669c13\", 1]}" diff --git a/iguana/tests/gtx b/iguana/tests/gtx index cc81e80df..7b0a8d050 100755 --- a/iguana/tests/gtx +++ b/iguana/tests/gtx @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"geckotx\",\"vals\":{\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"},\"hexstr\":\"01000000c3e763570001000000000000000006056adeadbeef00000000\"}" diff --git a/iguana/tests/history b/iguana/tests/history index 0546e0f11..a34942339 100755 --- a/iguana/tests/history +++ b/iguana/tests/history @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"history\",\"vals\":{\"coin\":\"BTCD\"}}" diff --git a/iguana/tests/history2 b/iguana/tests/history2 new file mode 100755 index 000000000..a34942339 --- /dev/null +++ b/iguana/tests/history2 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"history\",\"vals\":{\"coin\":\"BTCD\"}}" diff --git a/iguana/tests/historyB b/iguana/tests/historyB index 7b63b6ee7..54e0175db 100755 --- a/iguana/tests/historyB +++ b/iguana/tests/historyB @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"history\",\"vals\":{\"coin\":\"BTC\"}}" diff --git a/iguana/tests/historyS b/iguana/tests/historyS index b4f745b8d..b210c6b5c 100755 --- a/iguana/tests/historyS +++ b/iguana/tests/historyS @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1,\"history\":2}}" diff --git a/iguana/tests/historyU b/iguana/tests/historyU index 9f2dbf278..43a112365 100755 --- a/iguana/tests/historyU +++ b/iguana/tests/historyU @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1,\"history\":1}}" diff --git a/iguana/tests/igget b/iguana/tests/igget index f92792b80..436b65cc1 100755 --- a/iguana/tests/igget +++ b/iguana/tests/igget @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"params\":[\"RMd1Ek7bG7UknByTjfdDvJSXNUTahQKKWG\"]}" diff --git a/iguana/tests/igphrase b/iguana/tests/igphrase index 6f008031f..815fa4a50 100755 --- a/iguana/tests/igphrase +++ b/iguana/tests/igphrase @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"walletpassphrase\",\"params\":[\"igtest\", 66600]}" diff --git a/iguana/tests/igset b/iguana/tests/igset index 529097447..e155047ae 100755 --- a/iguana/tests/igset +++ b/iguana/tests/igset @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"RMd1Ek7bG7UknByTjfdDvJSXNUTahQKKWG\", \"igacct\"]}" diff --git a/iguana/tests/importprivkey b/iguana/tests/importprivkey index 26a53c9df..04e7ded6c 100755 --- a/iguana/tests/importprivkey +++ b/iguana/tests/importprivkey @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"UvBSu7PtUcGFeCd4fJdWSN6NKH4DPzmMoZtPn4Sb94Tj3CyXj9Fn\", \"testing\"]}" diff --git a/iguana/tests/importprivkeyB b/iguana/tests/importprivkeyB index daf596641..7d7a14da1 100755 --- a/iguana/tests/importprivkeyB +++ b/iguana/tests/importprivkeyB @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"Kzw1ordPLaxDqgn2Uz8UyjszcjyPsSM8a16CpHQ4DJF2DiVtFSX1\"]}" diff --git a/iguana/tests/importprivkeyR b/iguana/tests/importprivkeyR index e8a2551a1..2f2e3edf8 100755 --- a/iguana/tests/importprivkeyR +++ b/iguana/tests/importprivkeyR @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"522102c866c51b603e2d943774314b88aff1eb04aef3971fcf34503c8f07d27915bc1d2102e053cc9d98d9e157917ed74bcabeaf72006b1ecf019d148dd3eac06271b6bcf02102869ca05bf6b476bb8cb433e08846a67037b921062f49cd0f9f66087454e88abb53ae\"]}" diff --git a/iguana/tests/incoming b/iguana/tests/incoming index baceca9a8..0811301af 100755 --- a/iguana/tests/incoming +++ b/iguana/tests/incoming @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"incoming\",\"requestid\":1728286611}" diff --git a/iguana/tests/json_extract.c b/iguana/tests/json_extract.c old mode 100644 new mode 100755 diff --git a/iguana/tests/json_extracta.c b/iguana/tests/json_extracta.c old mode 100644 new mode 100755 diff --git a/iguana/tests/json_extractd.c b/iguana/tests/json_extractd.c old mode 100644 new mode 100755 diff --git a/iguana/tests/json_extracti.c b/iguana/tests/json_extracti.c old mode 100644 new mode 100755 diff --git a/iguana/tests/jsoncmp.c b/iguana/tests/jsoncmp.c old mode 100644 new mode 100755 diff --git a/iguana/tests/jumblrstatus b/iguana/tests/jumblrstatus new file mode 100755 index 000000000..6c1824244 --- /dev/null +++ b/iguana/tests/jumblrstatus @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"jumblr\",\"method\":\"status\"}" diff --git a/iguana/tests/listreceivedbyaccount b/iguana/tests/listreceivedbyaccount index 3d9771fdf..275cd7d4e 100755 --- a/iguana/tests/listreceivedbyaccount +++ b/iguana/tests/listreceivedbyaccount @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"listreceivedbyaccount\",\"params\":[1, 9999999, [\"RUXwXF37SMA63vL4bUPnytP3KUwp69PCVv\"]]}" diff --git a/iguana/tests/listtransactions b/iguana/tests/listtransactions index 0b719dc7f..36926d8ed 100755 --- a/iguana/tests/listtransactions +++ b/iguana/tests/listtransactions @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"listtransactions\",\"params\":[1, 9999999, [\"RUXwXF37SMA63vL4bUPnytP3KUwp69PCVv\"]]}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"listtransactions\",\"params\":[1, 9999999, []]}" diff --git a/iguana/tests/listunspent b/iguana/tests/listunspent index e5ce5c0d9..804e1f076 100755 --- a/iguana/tests/listunspent +++ b/iguana/tests/listunspent @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"listunspent\",\"params\":[1, 9999999, [\"RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf\"]]}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"KMD\",\"method\":\"listunspent\",\"params\":[1, 9999999, [\"REApv3sqJjzXTz72dRGrfzKJt3neHfTVym\"]]}" diff --git a/iguana/tests/listunspent2 b/iguana/tests/listunspent2 new file mode 100755 index 000000000..b9c04d79b --- /dev/null +++ b/iguana/tests/listunspent2 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"listunspent\",\"params\":[1, 9999999, [\"RNJmgYaFF5DbnrNUX6pMYz9rcnDKC2tuAc\"]]}" diff --git a/iguana/tests/listunspentB b/iguana/tests/listunspentB index e7fbcc744..3debb1992 100755 --- a/iguana/tests/listunspentB +++ b/iguana/tests/listunspentB @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"listunspent\",\"params\":[1, 9999999, [\"RVQV5spiARDTqfwBCxstWnMbrT6Q8mhRYz\"]]}" diff --git a/iguana/tests/listunspentK b/iguana/tests/listunspentK new file mode 100755 index 000000000..bec4770b5 --- /dev/null +++ b/iguana/tests/listunspentK @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"KMD\",\"method\":\"listunspent\",\"params\":[1, 9999999, []]}" diff --git a/iguana/tests/login b/iguana/tests/login index bd706185e..5d5c33f6a 100755 --- a/iguana/tests/login +++ b/iguana/tests/login @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"login\",\"passphrase\":\"test\"}" diff --git a/iguana/tests/loop b/iguana/tests/loop index cae5818c0..460d2c4db 100755 --- a/iguana/tests/loop +++ b/iguana/tests/loop @@ -1,7 +1,6 @@ -pkill iguana +#!/bin/bash while true do -../../agents/iguana -sleep 3 +./dexgetinfo done diff --git a/iguana/tests/loop2 b/iguana/tests/loop2 index b23fc5b8d..da4ce4ef3 100755 --- a/iguana/tests/loop2 +++ b/iguana/tests/loop2 @@ -1,3 +1,4 @@ +#!/bin/bash cd .. pkill iguana ./m_LP diff --git a/iguana/tests/ltest b/iguana/tests/ltest index 76fd2fe8f..47b655806 100755 --- a/iguana/tests/ltest +++ b/iguana/tests/ltest @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"listunspent\",\"params\":[1, 9999999, [\"RDxggCVF42Ds19DLNSjC6e3BaFk4ScCb2T\"]]}" diff --git a/iguana/tests/make_jsoncmp b/iguana/tests/make_jsoncmp index 26548619e..a05cb2f18 100755 --- a/iguana/tests/make_jsoncmp +++ b/iguana/tests/make_jsoncmp @@ -1,3 +1,4 @@ +#!/bin/bash gcc -o jsoncmp jsoncmp.c ../../agents/libcrypto777.a -pthread -lm gcc -o json_extract json_extract.c ../../agents/libcrypto777.a -pthread -lm gcc -o json_extracti json_extracti.c ../../agents/libcrypto777.a -pthread -lm diff --git a/iguana/tests/mm b/iguana/tests/mm new file mode 100755 index 000000000..816419047 --- /dev/null +++ b/iguana/tests/mm @@ -0,0 +1,3 @@ +../../coins/basilisk/btc +../../coins/basilisk/kmd +../marketmaker '{"blocktrail":"","passphrase":"","base":"KMD","rel":"BTC","name":"komodo","exchange":"bittrex","apikey":"","apisecret":"","profitmargin":0.001,"maxexposure":0.1,"lotratio":0.02,"start_rel":0.1,"start_base":1000}' diff --git a/iguana/tests/mvpgetinfo b/iguana/tests/mvpgetinfo new file mode 100755 index 000000000..8af5685a8 --- /dev/null +++ b/iguana/tests/mvpgetinfo @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dex\",\"method\":\"getinfo\",\"symbol\":\"MVP\"}" diff --git a/iguana/tests/myip2 b/iguana/tests/myip2 index b8a2f0f00..5dcd33fc6 100755 --- a/iguana/tests/myip2 +++ b/iguana/tests/myip2 @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"5.9.102.210\"}" diff --git a/iguana/tests/myip4 b/iguana/tests/myip4 index 145bd98e7..9afdd680c 100755 --- a/iguana/tests/myip4 +++ b/iguana/tests/myip4 @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"78.47.196.146\"}" diff --git a/iguana/tests/new b/iguana/tests/new index 59ff44b82..2a90d146b 100755 --- a/iguana/tests/new +++ b/iguana/tests/new @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"newgeckochain\",\"vals\":{\"RELAY\":1,\"blocktime\":10,\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"}}" diff --git a/iguana/tests/newtest b/iguana/tests/newtest index ba46a7827..0707a1afe 100755 --- a/iguana/tests/newtest +++ b/iguana/tests/newtest @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"newgeckochain\",\"vals\":{\"RELAY\":1,\"blocktime\":10,\"chain\":\"testchain\",\"symbol\":\"test\"}}" diff --git a/iguana/tests/notarychains b/iguana/tests/notarychains new file mode 100755 index 000000000..484b4bbe9 --- /dev/null +++ b/iguana/tests/notarychains @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dpow\",\"method\":\"notarychains\"}" diff --git a/iguana/tests/notaryinit b/iguana/tests/notaryinit new file mode 100755 index 000000000..cca040ab6 --- /dev/null +++ b/iguana/tests/notaryinit @@ -0,0 +1,15 @@ +#!/bin/bash +myip=`cat myip.txt` +pkill iguana +../agents/iguana notary & +sleep 4 +coins/gennotary +tests/addnotarys_7776 +tests/getinfoN_7776 +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}" +./wp_7776 +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"activehandle\"}" +./btc_7776 +./kmd_7776 +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"NOTARY\",\"ipaddr\":\"$myip\"}" +./dpow_7776 diff --git a/iguana/tests/notlp b/iguana/tests/notlp new file mode 100755 index 000000000..b29c9dde7 --- /dev/null +++ b/iguana/tests/notlp @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"notlp\"}" diff --git a/iguana/tests/openliquidity b/iguana/tests/openliquidity new file mode 100755 index 000000000..c8e5c6232 --- /dev/null +++ b/iguana/tests/openliquidity @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"openliquidity\"}" diff --git a/iguana/tests/openorders b/iguana/tests/openorders index 8f3e4db9d..579b941a7 100755 --- a/iguana/tests/openorders +++ b/iguana/tests/openorders @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"openorders\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/orderbook b/iguana/tests/orderbook index b5799ba80..ab2a02698 100755 --- a/iguana/tests/orderbook +++ b/iguana/tests/orderbook @@ -1 +1,3 @@ +#!/bin/bash +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"allfields\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"orderbook\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/passthru b/iguana/tests/passthru new file mode 100755 index 000000000..eca311fd2 --- /dev/null +++ b/iguana/tests/passthru @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"komodo\",\"method\":\"passthru\",\"function\":\"getinfo\",\"hex\":\"\"}" diff --git a/iguana/tests/paxfiats b/iguana/tests/paxfiats new file mode 100755 index 000000000..63bbd2af0 --- /dev/null +++ b/iguana/tests/paxfiats @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"paxfiats\",\"mask\":$1}" diff --git a/iguana/tests/paxrates b/iguana/tests/paxrates index e37b7f985..4faf7b3f4 100755 --- a/iguana/tests/paxrates +++ b/iguana/tests/paxrates @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"rates\",\"quotes\":[\"USD\", \"EUR\", \"JPY\", \"GBP\", \"AUD\", \"CAD\", \"CHF\", \"NZD\", \"CNY\", \"RUB\", \"MXN\", \"BRL\", \"INR\", \"HKD\", \"TRY\", \"ZAR\", \"PLN\", \"NOK\", \"SEK\", \"DKK\", \"CZK\", \"HUF\", \"ILS\", \"KRW\", \"MYR\", \"PHP\", \"RON\", \"SGD\", \"THB\", \"BGN\", \"IDR\", \"HRK\"]}" diff --git a/iguana/tests/peers.txt b/iguana/tests/peers.txt old mode 100644 new mode 100755 index 76848e4b4..69de8e2c2 --- a/iguana/tests/peers.txt +++ b/iguana/tests/peers.txt @@ -1,3 +1,4 @@ +#!/bin/bash [ { "addr" : "85.25.217.233:14631", diff --git a/iguana/tests/pending b/iguana/tests/pending new file mode 100755 index 000000000..510ddfc86 --- /dev/null +++ b/iguana/tests/pending @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"dpow\",\"method\":\"pending\",\"fiat\":\"eur\"}" diff --git a/iguana/tests/priv2wif b/iguana/tests/priv2wif index 99ce4f73a..18e4ca20a 100755 --- a/iguana/tests/priv2wif +++ b/iguana/tests/priv2wif @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"agent\":\"SuperNET\",\"method\":\"priv2wif\",\"priv\":\"59c56c68e3e4910385523d67fe174509da7ddb6f7f35189e0d691d3b5e98ea0a\"}" diff --git a/iguana/tests/pub b/iguana/tests/pub index fcea54b8e..1b9dc5160 100755 --- a/iguana/tests/pub +++ b/iguana/tests/pub @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"publish\",\"vals\":{\"testfield\":\"test\"},\"hexstr\":\"deadbeef\"}" diff --git a/iguana/tests/rate b/iguana/tests/rate index 4adef8cf3..99ea9f314 100755 --- a/iguana/tests/rate +++ b/iguana/tests/rate @@ -1 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"rate\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"rate\",\"base\":\"BTC\",\"rel\":\"USD\"}" diff --git a/iguana/tests/rates b/iguana/tests/rates index c076f231e..c225efec1 100755 --- a/iguana/tests/rates +++ b/iguana/tests/rates @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"rates\",\"quotes\":[\"BTCD/BTC\", \"BTC/USD\", \"EUR/USD\", \"THB/BRL\"]}" diff --git a/iguana/tests/ratesloop b/iguana/tests/ratesloop index 764f0f684..8cb24d519 100755 --- a/iguana/tests/ratesloop +++ b/iguana/tests/ratesloop @@ -1,3 +1,4 @@ +#!/bin/bash while true do ./rates diff --git a/iguana/tests/ratify b/iguana/tests/ratify new file mode 100755 index 000000000..cd376f0f2 --- /dev/null +++ b/iguana/tests/ratify @@ -0,0 +1,2 @@ +#!/bin/bash +curl -s "https://komodonotary.com/notary.json" | curl "http://127.0.0.1:7776" -d @- diff --git a/iguana/tests/ratifyC_7776 b/iguana/tests/ratifyC_7776 new file mode 100755 index 000000000..09f4f7b7d --- /dev/null +++ b/iguana/tests/ratifyC_7776 @@ -0,0 +1,3 @@ +#!/bin/bash +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"dpow\",\"method\":\"ratify\",\"source\":\"REVS\",\"minsigs\":8,\"start\":1478381719,\"ratified\":[{\"destprevtxid0\":\"3e9475fd4798b3b451fc3c85e5569f7a80650cae5787f705869b3a7e3b190dd7\",\"destprevvout0\":1,\"srcprevtxid0\":\"034b2505b15b7dbc320aab1697c2e2c9426c9aa9184219387a287eef2905f85b\",\"srcprevvout0\":0,\"handle\":\"testA\",\"pubkey\":\"03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828\"},{\"handle\":\"testB\",\"pubkey\":\"02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344\"},{\"handle\":\"artik_AE\",\"pubkey\":\"029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90\"},{\"handle\":\"artik_EU\",\"pubkey\":\"03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce\"},{\"handle\":\"artik_NA\",\"pubkey\":\"0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842\"},{\"handle\":\"artik_SH\",\"pubkey\":\"02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937\"},{\"handle\":\"badass_EU\",\"pubkey\":\"0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e\"},{\"handle\":\"badass_NA\",\"pubkey\":\"02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7\"},{\"handle\":\"badass_SH\",\"pubkey\":\"026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b\"},{\"handle\":\"crackers_EU\",\"pubkey\":\"0340c66cf2c41c41efb420af57867baa765e8468c12aa996bfd816e1e07e410728\"},{\"handle\":\"crackers_NA\",\"pubkey\":\"029e1c01131974f4cd3f564cc0c00eb87a0f9721043fbc1ca60f9bd0a1f73f64a1\"},{\"handle\":\"crackers_SH\",\"pubkey\":\"02313d72f9a16055737e14cfc528dcd5d0ef094cfce23d0348fe974b6b1a32e5f0\"},{\"handle\":\"durerus_EU\",\"pubkey\":\"02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57\"},{\"handle\":\"eclips_EU\",\"pubkey\":\"02f236c98c025fccf8b24e96d489ca03a4345d0ec18660c03c67a522bc827b614e\"},{\"handle\":\"etszombi_EU\",\"pubkey\":\"0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7\"},{\"handle\":\"farl4web_EU\",\"pubkey\":\"0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f\"},{\"handle\":\"fullmoon_AE\",\"pubkey\":\"0204a908350b8142698fdb6fabefc97fe0e04f537adc7522ba7a1e8f3bec003d4a\"},{\"handle\":\"grewal_AE\",\"pubkey\":\"034e804867936874d2dcef56ab5696f5fba059db069eb4f5c2887c61e6c60638b1\"},{\"handle\":\"grewal_NA\",\"pubkey\":\"03834b13ebaa060ecda0f94ed570a8d2a31ade1d3e29c79db6eb66887cfd0b800a\"},{\"handle\":\"grewal_SH\",\"pubkey\":\"03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68\"},{\"handle\":\"jeezy_EU\",\"pubkey\":\"023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6\"},{\"handle\":\"karasugoi_NA\",\"pubkey\":\"02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982\"},{\"handle\":\"kolo_AE\",\"pubkey\":\"02ffda5a0147e781308fe66a1774793eacd9b35829073746b217845cfe7577b7dc\"},{\"handle\":\"kolo_EU\",\"pubkey\":\"03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b\"},{\"handle\":\"locomb_EU\",\"pubkey\":\"025c6d26649b9d397e63323d96db42a9d3caad82e1d6076970efe5056c00c0779b\"},{\"handle\":\"movecrypto_EU\",\"pubkey\":\"021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42\"},{\"handle\":\"nxtswe_EU\",\"pubkey\":\"032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899\"},{\"handle\":\"polycryptoblock_NA\",\"pubkey\":\"02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622\"},{\"handle\":\"pondsea_AE\",\"pubkey\":\"032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735\"},{\"handle\":\"pondsea_EU\",\"pubkey\":\"0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d\"},{\"handle\":\"pondsea_NA\",\"pubkey\":\"031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411\"},{\"handle\":\"pondsea_SH\",\"pubkey\":\"02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36\"},{\"handle\":\"proto_EU\",\"pubkey\":\"03681ffdf17c8f4f0008cefb7fa0779c5e888339cdf932f0974483787a4d6747c1\"},{\"handle\":\"rnr_EU\",\"pubkey\":\"0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec\"},{\"handle\":\"supernet_AE\",\"pubkey\":\"029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355\"},{\"handle\":\"supernet_EU\",\"pubkey\":\"02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546\"},{\"handle\":\"supernet_NA\",\"pubkey\":\"033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1\"},{\"handle\":\"titomane_AE\",\"pubkey\":\"03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185\"},{\"handle\":\"titomane_EU\",\"pubkey\":\"03517fcac101fed480ae4f2caf775560065957930d8c1facc83e30077e45bdd199\"},{\"handle\":\"titomane_NA\",\"pubkey\":\"0387046d9745414fb58a0fa3599078af5073e10347e4657ef7259a99cb4f10ad47\"},{\"handle\":\"titomane_SH\",\"pubkey\":\"035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960\"},{\"handle\":\"vanbreuk_EU\",\"pubkey\":\"024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3\"},{\"handle\":\"yassin_EU\",\"pubkey\":\"033fb7231bb66484081952890d9a03f91164fb27d392d9152ec41336b71b15fbd0\"}]}" diff --git a/iguana/tests/ratifyE b/iguana/tests/ratifyE new file mode 100644 index 000000000..0a8105f44 --- /dev/null +++ b/iguana/tests/ratifyE @@ -0,0 +1,265 @@ +{ + "agent": "dpow", + "method": "ratify", + "round": "E", + "minsigs": 10, + "start": 1478713787, + "ratified": [ + { + "handle": "testA", + "pubkey": "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828", + "destprevtxid0": "3e9475fd4798b3b451fc3c85e5569f7a80650cae5787f705869b3a7e3b190dd7", + "destprevvout0": 0, + "srcprevtxid0": "034b2505b15b7dbc320aab1697c2e2c9426c9aa9184219387a287eef2905f85b", + "srcprevvout0": 1 + }, + { + "handle": "testB", + "pubkey": "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" + }, + { + "handle": "artik_AE", + "pubkey": "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" + }, + { + "handle": "artik_EU", + "pubkey": "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" + }, + { + "handle": "artik_NA", + "pubkey": "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" + }, + { + "handle": "artik_SH", + "pubkey": "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" + }, + { + "handle": "badass_EU", + "pubkey": "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" + }, + { + "handle": "badass_NA", + "pubkey": "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" + }, + { + "handle": "badass_SH", + "pubkey": "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" + }, + { + "handle": "crackers_EU", + "pubkey": "0340c66cf2c41c41efb420af57867baa765e8468c12aa996bfd816e1e07e410728" + }, + { + "handle": "crackers_NA", + "pubkey": "029e1c01131974f4cd3f564cc0c00eb87a0f9721043fbc1ca60f9bd0a1f73f64a1" + }, + { + "handle": "crackers_SH", + "pubkey": "02313d72f9a16055737e14cfc528dcd5d0ef094cfce23d0348fe974b6b1a32e5f0" + }, + { + "handle": "durerus_EU", + "pubkey": "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" + }, + { + "handle": "etszombi_EU", + "pubkey": "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" + }, + { + "handle": "etszombi_NA", + "pubkey": "02757999e651200ac24ff808e5dc7762ba64da1b940c7b150980f636a3866d6de9" + }, + { + "handle": "etszombii_AE", + "pubkey": "0252b6185bf8ea7efe8bbc345ddc8da87329149f30233088387abd716d4aa9e974" + }, + { + "handle": "etszombii_SH", + "pubkey": "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" + }, + { + "handle": "farl4web_EU", + "pubkey": "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" + }, + { + "handle": "farl4web_SH", + "pubkey": "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" + }, + { + "handle": "fullmoon_AE", + "pubkey": "0204a908350b8142698fdb6fabefc97fe0e04f537adc7522ba7a1e8f3bec003d4a" + }, + { + "handle": "fullmoon_NA", + "pubkey": "03e928cdb694cd3805a03e6f792ac0ba177c3261d98401e9a5450f512fdb89bd09" + }, + { + "handle": "fullmoon_SH", + "pubkey": "0396699a1792207b39cd20629a51e0825e075d3a80f0237a95d4385ad2a12d88fb" + }, + { + "handle": "grewal_AE", + "pubkey": "034e804867936874d2dcef56ab5696f5fba059db069eb4f5c2887c61e6c60638b1" + }, + { + "handle": "grewal_NA", + "pubkey": "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" + }, + { + "handle": "grewal_SH", + "pubkey": "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" + }, + { + "handle": "indenode_EU", + "pubkey": "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" + }, + { + "handle": "jeezy_EU", + "pubkey": "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" + }, + { + "handle": "karasugoi_NA", + "pubkey": "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" + }, + { + "handle": "kashifali_EU", + "pubkey": "02b74e712998ca1e9580c8c0851f20f79563afd65a22d47d47e184d951bcc1e135" + }, + { + "handle": "kolo_AE", + "pubkey": "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" + }, + { + "handle": "kolo_EU", + "pubkey": "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" + }, + { + "handle": "kolo_NA", + "pubkey": "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" + }, + { + "handle": "kolo_SH", + "pubkey": "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" + }, + { + "handle": "locomb_EU", + "pubkey": "02ea030819f09586aa33fa57c1daf80782880e509c9bae87ef8fde1a08acf78599" + }, + { + "handle": "metaphilibert_NA", + "pubkey": "02b714aa5833d7a76700c429d5542cea409826d3668ba9d75ec3407a607450563c" + }, + { + "handle": "movecrypto_AE", + "pubkey": "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" + }, + { + "handle": "movecrypto_EU", + "pubkey": "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" + }, + { + "handle": "movecrypto_NA", + "pubkey": "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" + }, + { + "handle": "movecrypto_SH", + "pubkey": "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" + }, + { + "handle": "muros_NA", + "pubkey": "0252b6185bf8ea7efe8bbc345ddc8da87329149f30233088387abd716d4aa9e974" + }, + { + "handle": "nxtswe_EU", + "pubkey": "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" + }, + { + "handle": "polycryptoblock_NA", + "pubkey": "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" + }, + { + "handle": "pondsea_AE", + "pubkey": "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" + }, + { + "handle": "pondsea_EU", + "pubkey": "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" + }, + { + "handle": "pondsea_NA", + "pubkey": "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" + }, + { + "handle": "pondsea_SH", + "pubkey": "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" + }, + { + "handle": "proto_EU", + "pubkey": "03681ffdf17c8f4f0008cefb7fa0779c5e888339cdf932f0974483787a4d6747c1" + }, + { + "handle": "rnr_AE", + "pubkey": "02ffda5a0147e781308fe66a1774793eacd9b35829073746b217845cfe7577b7dc" + }, + { + "handle": "rnr_EU", + "pubkey": "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" + }, + { + "handle": "rnr_NA", + "pubkey": "03f381ba12b70fb3c5c790ca0131a200534d608c301ff8ccca93abe4cc3444ae5b" + }, + { + "handle": "rnr_SH", + "pubkey": "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" + }, + { + "handle": "siggurd_NA", + "pubkey": "03f2a02e212604afeff85bedd15703a3e47a13650013e04609140a7b3109d08f77" + }, + { + "handle": "supernet_AE", + "pubkey": "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" + }, + { + "handle": "supernet_EU", + "pubkey": "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" + }, + { + "handle": "supernet_NA", + "pubkey": "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" + }, + { + "handle": "titomane_AE", + "pubkey": "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" + }, + { + "handle": "titomane_EU", + "pubkey": "03517fcac101fed480ae4f2caf775560065957930d8c1facc83e30077e45bdd199" + }, + { + "handle": "titomane_NA", + "pubkey": "0387046d9745414fb58a0fa3599078af5073e10347e4657ef7259a99cb4f10ad47" + }, + { + "handle": "titomane_SH", + "pubkey": "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" + }, + { + "handle": "vanbreuk_EU", + "pubkey": "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" + }, + { + "handle": "xrobesx_NA", + "pubkey": "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" + }, + { + "handle": "yassin_EU", + "pubkey": "033fb7231bb66484081952890d9a03f91164fb27d392d9152ec41336b71b15fbd0" + }, + { + "handle": "yassin_SH", + "pubkey": "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" + } + ] +} diff --git a/iguana/tests/ratifyX.json b/iguana/tests/ratifyX.json new file mode 100644 index 000000000..5f1832ea0 --- /dev/null +++ b/iguana/tests/ratifyX.json @@ -0,0 +1,278 @@ +{ + "agent": "dpow", + "method": "ratify", + "round": "finaltest", + "minsigs": 7, + "start": 1479400896, + "ratified": [ + { + "handle": "testA", + "pubkey": "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828", + "destprevtxid0": "4f49bd22b44ae02f543359e98cea0e9d1f99060877ae220f26cb2f9bcd0a497f", + "destprevvout0": 1, + "srcprevtxid0": "d14260097cb69cebe52841c6ec8aecd68302d8cc100aa37213bf552cc26bed03", + "srcprevvout0": 1 + }, + { + "handle": "testB", + "pubkey": "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" + }, + { + "handle": "artik_AE", + "pubkey": "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" + }, + { + "handle": "artik_EU", + "pubkey": "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" + }, + { + "handle": "artik_NA", + "pubkey": "0224e31f93eff0cc30eaf0b2389fbc591085c0e122c4d11862c1729d090106c842" + }, + { + "handle": "artik_SH", + "pubkey": "02bdd8840a34486f38305f311c0e2ae73e84046f6e9c3dd3571e32e58339d20937" + }, + { + "handle": "badass_EU", + "pubkey": "0209d48554768dd8dada988b98aca23405057ac4b5b46838a9378b95c3e79b9b9e" + }, + { + "handle": "badass_NA", + "pubkey": "02afa1a9f948e1634a29dc718d218e9d150c531cfa852843a1643a02184a63c1a7" + }, + { + "handle": "badass_SH", + "pubkey": "026b49dd3923b78a592c1b475f208e23698d3f085c4c3b4906a59faf659fd9530b" + }, + { + "handle": "crackers_EU", + "pubkey": "0340c66cf2c41c41efb420af57867baa765e8468c12aa996bfd816e1e07e410728" + }, + { + "handle": "crackers_NA", + "pubkey": "029e1c01131974f4cd3f564cc0c00eb87a0f9721043fbc1ca60f9bd0a1f73f64a1" + }, + { + "handle": "crackers_SH", + "pubkey": "02313d72f9a16055737e14cfc528dcd5d0ef094cfce23d0348fe974b6b1a32e5f0" + }, + { + "handle": "durerus_EU", + "pubkey": "02bcbd287670bdca2c31e5d50130adb5dea1b53198f18abeec7211825f47485d57" + }, + { + "handle": "etszombi_EU", + "pubkey": "0281b1ad28d238a2b217e0af123ce020b79e91b9b10ad65a7917216eda6fe64bf7" + }, + { + "handle": "etszombi_NA", + "pubkey": "02757999e651200ac24ff808e5dc7762ba64da1b940c7b150980f636a3866d6de9" + }, + { + "handle": "etszombii_AE", + "pubkey": "0252b6185bf8ea7efe8bbc345ddc8da87329149f30233088387abd716d4aa9e974" + }, + { + "handle": "etszombii_SH", + "pubkey": "025d7a193c0757f7437fad3431f027e7b5ed6c925b77daba52a8755d24bf682dde" + }, + { + "handle": "farl4web_EU", + "pubkey": "0300ecf9121cccf14cf9423e2adb5d98ce0c4e251721fa345dec2e03abeffbab3f" + }, + { + "handle": "farl4web_SH", + "pubkey": "0396bb5ed3c57aa1221d7775ae0ff751e4c7dc9be220d0917fa8bbdf670586c030" + }, + { + "handle": "fullmoon_AE", + "pubkey": "0204a908350b8142698fdb6fabefc97fe0e04f537adc7522ba7a1e8f3bec003d4a" + }, + { + "handle": "fullmoon_NA", + "pubkey": "03e928cdb694cd3805a03e6f792ac0ba177c3261d98401e9a5450f512fdb89bd09" + }, + { + "handle": "fullmoon_SH", + "pubkey": "0396699a1792207b39cd20629a51e0825e075d3a80f0237a95d4385ad2a12d88fb" + }, + { + "handle": "grewal_AE", + "pubkey": "034e804867936874d2dcef56ab5696f5fba059db069eb4f5c2887c61e6c60638b1" + }, + { + "handle": "grewal_NA", + "pubkey": "03adc0834c203d172bce814df7c7a5e13dc603105e6b0adabc942d0421aefd2132" + }, + { + "handle": "grewal_SH", + "pubkey": "03212a73f5d38a675ee3cdc6e82542a96c38c3d1c79d25a1ed2e42fcf6a8be4e68" + }, + { + "handle": "indenode_EU", + "pubkey": "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" + }, + { + "handle": "jeezy_EU", + "pubkey": "023cb3e593fb85c5659688528e9a4f1c4c7f19206edc7e517d20f794ba686fd6d6" + }, + { + "handle": "karasugoi_NA", + "pubkey": "02a348b03b9c1a8eac1b56f85c402b041c9bce918833f2ea16d13452309052a982" + }, + { + "handle": "kashifali_EU", + "pubkey": "02b74e712998ca1e9580c8c0851f20f79563afd65a22d47d47e184d951bcc1e135" + }, + { + "handle": "kolo_AE", + "pubkey": "03016d19344c45341e023b72f9fb6e6152fdcfe105f3b4f50b82a4790ff54e9dc6" + }, + { + "handle": "kolo_EU", + "pubkey": "03f5c08dadffa0ffcafb8dd7ffc38c22887bd02702a6c9ac3440deddcf2837692b" + }, + { + "handle": "kolo_NA", + "pubkey": "02e17c5f8c3c80f584ed343b8dcfa6d710dfef0889ec1e7728ce45ce559347c58c" + }, + { + "handle": "kolo_SH", + "pubkey": "02aa24064500756d9b0959b44d5325f2391d8e95c6127e109184937152c384e185" + }, + { + "handle": "locomb_EU", + "pubkey": "02ea030819f09586aa33fa57c1daf80782880e509c9bae87ef8fde1a08acf78599" + }, + { + "handle": "metaphilibert_NA", + "pubkey": "02b714aa5833d7a76700c429d5542cea409826d3668ba9d75ec3407a607450563c" + }, + { + "handle": "movecrypto_AE", + "pubkey": "022783d94518e4dc77cbdf1a97915b29f427d7bc15ea867900a76665d3112be6f3" + }, + { + "handle": "movecrypto_EU", + "pubkey": "021ab53bc6cf2c46b8a5456759f9d608966eff87384c2b52c0ac4cc8dd51e9cc42" + }, + { + "handle": "movecrypto_NA", + "pubkey": "02efb12f4d78f44b0542d1c60146738e4d5506d27ec98a469142c5c84b29de0a80" + }, + { + "handle": "movecrypto_SH", + "pubkey": "031f9739a3ebd6037a967ce1582cde66e79ea9a0551c54731c59c6b80f635bc859" + }, + { + "handle": "muros_AE", + "pubkey": "022d77402fd7179335da39479c829be73428b0ef33fb360a4de6890f37c2aa005e" + }, + { + "handle": "muros_NA", + "pubkey": "0252b6185bf8ea7efe8bbc345ddc8da87329149f30233088387abd716d4aa9e974" + }, + { + "handle": "nxtswe_EU", + "pubkey": "032fb104e5eaa704a38a52c126af8f67e870d70f82977e5b2f093d5c1c21ae5899" + }, + { + "handle": "polycryptoblock_NA", + "pubkey": "02708dcda7c45fb54b78469673c2587bfdd126e381654819c4c23df0e00b679622" + }, + { + "handle": "pondsea_AE", + "pubkey": "032e1c213787312099158f2d74a89e8240a991d162d4ce8017d8504d1d7004f735" + }, + { + "handle": "pondsea_EU", + "pubkey": "0225aa6f6f19e543180b31153d9e6d55d41bc7ec2ba191fd29f19a2f973544e29d" + }, + { + "handle": "pondsea_NA", + "pubkey": "031bcfdbb62268e2ff8dfffeb9ddff7fe95fca46778c77eebff9c3829dfa1bb411" + }, + { + "handle": "pondsea_SH", + "pubkey": "02209073bc0943451498de57f802650311b1f12aa6deffcd893da198a544c04f36" + }, + { + "handle": "popcornbag_EU", + "pubkey": "024d21c1fa55c454a71da7ca188ada8d530e2f2af5223af3c352f039f555b5178f" + }, + { + "handle": "proto_EU", + "pubkey": "03681ffdf17c8f4f0008cefb7fa0779c5e888339cdf932f0974483787a4d6747c1" + }, + { + "handle": "rnr_AE", + "pubkey": "02ffda5a0147e781308fe66a1774793eacd9b35829073746b217845cfe7577b7dc" + }, + { + "handle": "rnr_EU", + "pubkey": "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" + }, + { + "handle": "rnr_NA", + "pubkey": "03f381ba12b70fb3c5c790ca0131a200534d608c301ff8ccca93abe4cc3444ae5b" + }, + { + "handle": "rnr_SH", + "pubkey": "037536fb9bdfed10251f71543fb42679e7c52308bcd12146b2568b9a818d8b8377" + }, + { + "handle": "siggurd_NA", + "pubkey": "03f2a02e212604afeff85bedd15703a3e47a13650013e04609140a7b3109d08f77" + }, + { + "handle": "supernet_AE", + "pubkey": "029d93ef78197dc93892d2a30e5a54865f41e0ca3ab7eb8e3dcbc59c8756b6e355" + }, + { + "handle": "supernet_EU", + "pubkey": "02061c6278b91fd4ac5cab4401100ffa3b2d5a277e8f71db23401cc071b3665546" + }, + { + "handle": "supernet_NA", + "pubkey": "033c073366152b6b01535e15dd966a3a8039169584d06e27d92a69889b720d44e1" + }, + { + "handle": "titomane_AE", + "pubkey": "03cda6ca5c2d02db201488a54a548dbfc10533bdc275d5ea11928e8d6ab33c2185" + }, + { + "handle": "titomane_EU", + "pubkey": "03517fcac101fed480ae4f2caf775560065957930d8c1facc83e30077e45bdd199" + }, + { + "handle": "titomane_NA", + "pubkey": "0387046d9745414fb58a0fa3599078af5073e10347e4657ef7259a99cb4f10ad47" + }, + { + "handle": "titomane_SH", + "pubkey": "035f49d7a308dd9a209e894321f010d21b7793461b0c89d6d9231a3fe5f68d9960" + }, + { + "handle": "vanbreuk_EU", + "pubkey": "024f3cad7601d2399c131fd070e797d9cd8533868685ddbe515daa53c2e26004c3" + }, + { + "handle": "xrobesx_NA", + "pubkey": "03f0cc6d142d14a40937f12dbd99dbd9021328f45759e26f1877f2a838876709e1" + }, + { + "handle": "yassin_EU", + "pubkey": "033fb7231bb66484081952890d9a03f91164fb27d392d9152ec41336b71b15fbd0" + }, + { + "handle": "yassin_EU2", + "pubkey": "02468340f56b8efa09c0df2ae4c2e5d9360a77bb6bec136152ed235baecf7ebae6" + }, + { + "handle": "yassin_SH", + "pubkey": "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" + } + ] +} + diff --git a/iguana/tests/ratify_7776 b/iguana/tests/ratify_7776 new file mode 100755 index 000000000..d00e7bdcd --- /dev/null +++ b/iguana/tests/ratify_7776 @@ -0,0 +1,2 @@ +#!/bin/bash +curl -s "http://komodonotary.com/notary.json" | curl "http://127.0.0.1:7776" -d @- diff --git a/iguana/tests/ratifytest b/iguana/tests/ratifytest new file mode 100755 index 000000000..591632673 --- /dev/null +++ b/iguana/tests/ratifytest @@ -0,0 +1,3 @@ +#!/bin/bash +#!/bin/bash +curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"dpow\",\"method\":\"ratify\",\"source\":\"REVS\",\"minsigs\":8,\"start\":1479481719,\"ratified\":[{\"destprevtxid0\":\"b193f44182d6bcfb52374560ac792ac6fc299fe75401437a446256c26762d189\",\"destprevvout0\":1,\"srcprevtxid0\":\"cca08b14a3cd4c6359a5b0dbf899d8a855044ce8761c4d5581226ca645525cf3\",\"srcprevvout0\":8,\"pubkey\":\"03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828\"}, {\"pubkey\":\"02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344\"}, {\"pubkey\":\"03750cf30d739cd7632f77c1c02812dd7a7181628b0558058d4755838117e05339\"}, {\"pubkey\":\"0394f3529d2e8cc69ffa7a2b55f3761e7be978fa1896ef4c55dc9c275e77e5bf5e\"}, {\"pubkey\":\"0243c1eeb3777af47187d542e5f8c84f0ac4b05cf5a7ad77faa8cb6d2d56db7823\"}, {\"pubkey\":\"02bb298844175640a34e908ffdfa2839f77aba3d5edadefee16beb107826e00063\"}, {\"pubkey\":\"02fa88e549b4b871498f892e527a5d57287916809f8cc3163f641d71c535e8df5a\"}, {\"pubkey\":\"032f799e370f06476793a122fcd623db7804898fe5aef5572095cfee6353df34bf\"}, {\"pubkey\":\"02c06fe5401faff4442ef87b7d1b56c2e5a214166615f9a2f2030c71b0cb067ae8\"}, {\"pubkey\":\"038ac67ca49a8169bcc5de83fe020071095a2c3b2bc4d1c17386977329758956d5\"}]}" diff --git a/iguana/tests/rawtx b/iguana/tests/rawtx index 84b5b8ab6..282d2ec20 100755 --- a/iguana/tests/rawtx +++ b/iguana/tests/rawtx @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"1FNhoaBYzf7safMBjoCsJYgxtah3K95sep\",\"addresses\":[\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\"],\"timeout\":15000,\"satoshis\":\"20000\",\"spendscript\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}}" diff --git a/iguana/tests/rawtx2 b/iguana/tests/rawtx2 index e206fd012..cef4cd52a 100755 --- a/iguana/tests/rawtx2 +++ b/iguana/tests/rawtx2 @@ -1,3 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\", \"RPett64qbUvSefiPCyBzQ52Aer9dx32ngd\", \"RGxn8p5QWZXbs58mpRtVRD8aeATVkRq2Rh\", \"RD9HQdpu9Z7Xsvvbh9URdnwYi6RZVMTVAa\", \"RSZzYEEAVnYDnRvfj5oA3yL6vYtm1WmXHJ\", \"RC3k4XRZxrDDMyYFmvBunZCAsNEFepbpRQ\", \"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm\"],\"timeout\":15000,\"satoshis\":\"128700\",\"spendscript\":\"76a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ac\",\"txfee\":\"1000000\",\"burn\":0.00010000}}" - -#{"coin":"BTCD","spendscript":"76a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ac","changeaddr":"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm","satoshis":"128700","txfee":"1000000","minconf":1,"locktime":0,"timeout":30000,"burn":0.00010000,"addresses":["RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z", "RPett64qbUvSefiPCyBzQ52Aer9dx32ngd", "RGxn8p5QWZXbs58mpRtVRD8aeATVkRq2Rh", "RD9HQdpu9Z7Xsvvbh9URdnwYi6RZVMTVAa", "RSZzYEEAVnYDnRvfj5oA3yL6vYtm1WmXHJ", "RC3k4XRZxrDDMyYFmvBunZCAsNEFepbpRQ", "RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm"],"symbol":"BTCD"} +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"KMD\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"addresses\":[\"RFMEYcxuBL8S7UPdUbzXunPtS4p82HRcKs\", \"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\", \"RDBjpRUqV1AXzVJCBbbXNskgxGRj711qSc\", \"RL4aMgTBzkM1kX7d8QtE2oYXuAj2ZKabmW\", \"RDE9LBKqMaKgQgnsZM3hFCNeWfoXkHWMLs\", \"RDBjpRUqV1AXzVJCBbbXNskgxGRj711qSc\"],\"timeout\":15000,\"satoshis\":\"128700\",\"spendscript\":\"76a9142b4cf64627268ac24effd9aad5895e8ca862114288ac\",\"txfee\":\"10000\",\"burn\":0.00000000}}" diff --git a/iguana/tests/rawtx3 b/iguana/tests/rawtx3 index ffa90d8d2..7c0479903 100755 --- a/iguana/tests/rawtx3 +++ b/iguana/tests/rawtx3 @@ -1,3 +1,3 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY\",\"addresses\":[\"16jsjc1YvzDXqKf7PorMhTyK8ym3ra3uxm\", \"1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY\"],\"timeout\":15000,\"satoshis\":\"20000\",\"spendscript\":\"76a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ac\"}}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RD1rFucYCMhCGeEqdztivP3DFdJwVAzXn7\",\"addresses\":[\"RD1rFucYCMhCGeEqdztivP3DFdJwVAzXn7\"],\"timeout\":15000,\"satoshis\":\"130000\",\"spendscript\":\"76a9145da2ae69885741a6946e01ad8aa8b5312eed856088ac\"}}" -#{"coin":"BTC","spendscript":"76a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ac","changeaddr":"1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY","satoshis":"331","txfee":"10000","minconf":1,"locktime":0,"timeout":30000,"burn":0.00010000,"addresses":["16jsjc1YvzDXqKf7PorMhTyK8ym3ra3uxm", "1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY"]} diff --git a/iguana/tests/rawtx4 b/iguana/tests/rawtx4 new file mode 100755 index 000000000..92cabd7f4 --- /dev/null +++ b/iguana/tests/rawtx4 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RD1rFucYCMhCGeEqdztivP3DFdJwVAzXn7\",\"addresses\":[\"RD1rFucYCMhCGeEqdztivP3DFdJwVAzXn7\"],\"timeout\":15000,\"satoshis\":\"130000\",\"spendscript\":\"76a9145da2ae69885741a6946e01ad8aa8b5312eed856088ac\"}}" diff --git a/iguana/tests/rawtx5 b/iguana/tests/rawtx5 new file mode 100755 index 000000000..92cabd7f4 --- /dev/null +++ b/iguana/tests/rawtx5 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RD1rFucYCMhCGeEqdztivP3DFdJwVAzXn7\",\"addresses\":[\"RD1rFucYCMhCGeEqdztivP3DFdJwVAzXn7\"],\"timeout\":15000,\"satoshis\":\"130000\",\"spendscript\":\"76a9145da2ae69885741a6946e01ad8aa8b5312eed856088ac\"}}" diff --git a/iguana/tests/rawtx6 b/iguana/tests/rawtx6 new file mode 100755 index 000000000..b1e724046 --- /dev/null +++ b/iguana/tests/rawtx6 @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"rawtx\",\"agent\":\"basilisk\",\"vals\":{\"addresses\":[\"19pE1sb6hPbV5644Fud6u7voNeKPfmfP3Y\", \"17SuJzHEuLzBtyHe83sYDjQFq2HeczRA1b\", \"1DyCyE5f4wCT9vBNUrCshg3ZkF7C9hT5wK\", \"15K5spF7woSF4rzGsQWSLVttmCF1nGGDXe\", \"1APJX58afkt2A25SmPQb9TrzGHbYYHLiVu\", \"12KFXEJ9C6VmvFabj4uqKeLYLm4XMsATU1\", \"12qDPNmMXez9r8CiHaww9dJooUk8AZSueF\", \"1DM9PDaBkYU27fB9ZQipZtGJtfBakpuYDv\", \"1HiTUabo7ruYY3NbxiDZi9dpnb5t4K6AqD\", \"1Q1thfWmTTwkR1yWEUHytrKcU6uGU8gUTu\", \"187ozeW6E1pbsQYvw5yqU6kzros5uXKcZk\", \"1FtJpcQ7q9msxYwR8QpF92bZDmGzVNHpxo\", \"1KDeCZiFXuNtpARcwEwohKJJb3Yeyjy8Ui\"],\"coin\":\"SYS\",\"changeaddr\":\"15K5spF7woSF4rzGsQWSLVttmCF1nGGDXe\",\"spendscript\":\"76a914df3f034f9805301d881b0d8c24a106f8d4c7fc8c88ac\",\"satoshis\":\"10000\",\"txfee\":\"10000\",\"minconf\":2},\"basilisktag\":995811301,\"locktime\":0,\"timeout\":30000}" diff --git a/iguana/tests/rawtxB b/iguana/tests/rawtxB index a7ede91c9..9948d3c01 100755 --- a/iguana/tests/rawtxB +++ b/iguana/tests/rawtxB @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"timeout\":25000,\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"coin\":\"BTCD\",\"satoshis\":\"20000\",\"spendscript\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}}" diff --git a/iguana/tests/refresh b/iguana/tests/refresh new file mode 100755 index 000000000..d6b1839aa --- /dev/null +++ b/iguana/tests/refresh @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"refresh\",\"symbol\":\"KMD\",\"address\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"timeout\":600000}" diff --git a/iguana/tests/repairwallet b/iguana/tests/repairwallet index c5f412816..9bd6553ff 100755 --- a/iguana/tests/repairwallet +++ b/iguana/tests/repairwallet @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"repairwallet\",\"params\":[]}" diff --git a/iguana/tests/request b/iguana/tests/request index 93fa2b351..ac3337301 100755 --- a/iguana/tests/request +++ b/iguana/tests/request @@ -1,2 +1,3 @@ -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"BTCD\",\"amount\":0.1,\"dest\":\"BTC\",\"minprice\":0.002}}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"KMD\",\"amount\":20,\"dest\":\"USD\",\"minprice\":0.08}}" diff --git a/iguana/tests/request2 b/iguana/tests/request2 new file mode 100755 index 000000000..772db43d0 --- /dev/null +++ b/iguana/tests/request2 @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"BTC\",\"amount\":0.0001,\"dest\":\"BTCD\",\"minprice\":240}}" + diff --git a/iguana/tests/requestK b/iguana/tests/requestK new file mode 100755 index 000000000..03ee29c1c --- /dev/null +++ b/iguana/tests/requestK @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"BTC\",\"amount\":0.0001,\"dest\":\"KMD\",\"minprice\":10000}}" + diff --git a/iguana/tests/requestM b/iguana/tests/requestM new file mode 100755 index 000000000..c480eef39 --- /dev/null +++ b/iguana/tests/requestM @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"MVP\",\"amount\":0.1,\"dest\":\"USD\",\"minprice\":0.09}}" + diff --git a/iguana/tests/sell b/iguana/tests/sell index c0eb0ae05..be338e54c 100755 --- a/iguana/tests/sell +++ b/iguana/tests/sell @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"sell\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.0029,\"volume\":1.0}" diff --git a/iguana/tests/sell2 b/iguana/tests/sell2 index 4db541c05..cbe94d0a2 100755 --- a/iguana/tests/sell2 +++ b/iguana/tests/sell2 @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"password\":\"test\",\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"sell\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.0029,\"volume\":1.0}" diff --git a/iguana/tests/sellV b/iguana/tests/sellV index 86f12afc6..6be066f9f 100755 --- a/iguana/tests/sellV +++ b/iguana/tests/sellV @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"sell\",\"base\":\"VPN\",\"rel\":\"BTC\",\"price\":0.000025,\"volume\":1.0}" diff --git a/iguana/tests/send b/iguana/tests/send index 309e1f3e1..26aaa893d 100755 --- a/iguana/tests/send +++ b/iguana/tests/send @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"sendmessage\",\"vals\":{\"channel\":12345,\"msgid\":1},\"hexstr\":\"deadbeef\"}" diff --git a/iguana/tests/sendmany b/iguana/tests/sendmany index 957b6866a..d94192464 100755 --- a/iguana/tests/sendmany +++ b/iguana/tests/sendmany @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendmany\", \"params\":[\"\", {\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\":0.01, \"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\":0.02}, 2]}" diff --git a/iguana/tests/sendrawtransaction b/iguana/tests/sendrawtransaction index 09d9dbfda..f256ee206 100755 --- a/iguana/tests/sendrawtransaction +++ b/iguana/tests/sendrawtransaction @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendrawtransaction\",\"params\":[\"010000002ec9a45701048f2f330b71f5cbef5d7b1cd161b1cf2dee06ddb15b670d46a41fca3a25beed00000000904730440220039cc97a4b266bef6802db4ae6219637842e97db025529240c01ea207cbd317502204d3796090624c86c43ee150cdc99e313483fe41c6d630d22d167e828688caaeb014730440220388f36c50854292d4a62d631d012b33d1f02fdd8623180151548947eacc06a4002207fe79c455ba5860b15e7b74fa31cf25c4a0f93c1e488f446d3322712067fb73d01ffffffff01706f9800000000001976a91454a752f0d71b89d7c014ed0be29ca231c9546f9f88ac00000000\"]}" diff --git a/iguana/tests/sendtoaddress b/iguana/tests/sendtoaddress index e9e059e50..3a1ef1bbc 100755 --- a/iguana/tests/sendtoaddress +++ b/iguana/tests/sendtoaddress @@ -1,2 +1,3 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendtoaddress\",\"params\":[\"RKk3hmkHr3khf2aQRZW51oxnzFVHsQe4hf\", 0.001, \"testcomment\", \"sendcomment\"]}" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"sendtoaddress\",\"params\":[\"1HEQifAU8mcMsTtM4ougjfZemVYfdT1TcJ\", 0.005]}" diff --git a/iguana/tests/set b/iguana/tests/set index 1be121420..319676317 100755 --- a/iguana/tests/set +++ b/iguana/tests/set @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"set\",\"vals\":{\"key\":\"testkey\",\"chain\":\"test\"},\"hexstr\":\"beefdead\"}" diff --git a/iguana/tests/setaccount b/iguana/tests/setaccount index 29d9bc622..c6e95dd9b 100755 --- a/iguana/tests/setaccount +++ b/iguana/tests/setaccount @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"RSM6HUAiQabjEzoXrtptdyMUrUsbYicTDE\", \"newaccount\"]}" diff --git a/iguana/tests/setaccountB b/iguana/tests/setaccountB index 7106166d7..387fc2020 100755 --- a/iguana/tests/setaccountB +++ b/iguana/tests/setaccountB @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"RSM6HUAiQabjEzoXrtptdyMUrUsbYicTDE\", \"newaccount2\"]}" diff --git a/iguana/tests/sign b/iguana/tests/sign new file mode 100755 index 000000000..d4774b944 --- /dev/null +++ b/iguana/tests/sign @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"SHARK\",\"method\":\"signrawtransaction\",\"params\":[\"0100000001f0c3007d723b5e88148a0e8be405148aa0b4f1ced247cec6d61f25e3bfa49f7401000000d700483045022100d2e2af39027b46516622f5c040770f4f20032bb99a1e69dc0072c8f9409d0d860220147d24c21d54d6411eac6c2aa970a9a8caec489ee12af77c7cbb424e3f17b36c0121035c7ceb91140df541a12c7cbe245ec9bc53a09771e37e480c485e8fbd69fb76fd4c695221035c7ceb91140df541a12c7cbe245ec9bc53a09771e37e480c485e8fbd69fb76fd21020a4b45aeeaea23cbe3cd288a399c8a42ba567bdd4841819569a54e8ef3a597432102e505c7e3480a643e23dd7b77687751b901404d8eea9c8d0d5a4c6af12b42172553aeffffffff0470170000000000001976a9148ca6e1a181cac5c0ea1e37fd50140c8ed81b8c6988ac60361e00000000001976a914d092ccfc3da5dc4279cb328e39e7a9903395946e88ac10270000000000001976a9147f9878c75123115a00000000000000000000000088ac00127a00000000001976a914ccf0d9a519f21e939893ed3a39f2c5e9d31ec24988ac00000000\", [{\"txid\":\"749fa4bfe3251fd6c6ce47d2cef1b4a08a1405e48b0e8a14885e3b727d00c3f0\",\"vout\":1,\"scriptPubKey\":\"a914ccf0d9a519f21e939893ed3a39f2c5e9d31ec24987\",\"redeemScript\":\"5221035c7ceb91140df541a12c7cbe245ec9bc53a09771e37e480c485e8fbd69fb76fd21020a4b45aeeaea23cbe3cd288a399c8a42ba567bdd4841819569a54e8ef3a597432102e505c7e3480a643e23dd7b77687751b901404d8eea9c8d0d5a4c6af12b42172553ae\"}], [\"UurweRHDBr4BSdMJuiXkgcnueawCNBXNw2e4zQ7TT75TieeG4auT\"], \"ALL\"] }" diff --git a/iguana/tests/signmessage b/iguana/tests/signmessage index 9b97e5bca..f008a24a9 100755 --- a/iguana/tests/signmessage +++ b/iguana/tests/signmessage @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"signmessage\",\"params\":[\"1KHJ4zELwwwND4dytYp7tFyBvELMH1r7a7\", \"testmessage\"]}" diff --git a/iguana/tests/signmessageC b/iguana/tests/signmessageC index 62da5d054..49d1e7ad2 100755 --- a/iguana/tests/signmessageC +++ b/iguana/tests/signmessageC @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"signmessage\",\"params\":[\"RAoMou7euzvDwa9dQwjrNB5A41hrAWgvBt\", \"testmessage\"]}" diff --git a/iguana/tests/signrawtransaction b/iguana/tests/signrawtransaction index 1cc56768c..f37a5adfe 100755 --- a/iguana/tests/signrawtransaction +++ b/iguana/tests/signrawtransaction @@ -1,2 +1,3 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"signrawtransaction\",\"params\":[\"0100000093b7325701f6d17d847b7096cdd9b79e4df4b74aabb9ac34b7abd4f9fce19d761e97cca0e80000000000ffffffff0240420f00000000001976a91410acba3a841fae68aba4b5ff162714c493bcc04e88acd0300e00000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\", [{\"txid\":\"e8a0cc971e769de1fcf9d4abb734acb9ab4ab7f44d9eb7d9cd96707b847dd1f6\",\"vout\":0,\"scriptPubKey\":\"2102d14a195654f536df6dfe5a38278d1b470d00f17de78eeb5ce9e9eea9edb2c212ac\"}], [\"UqvuZXEAVXDXJkL4j4Xq6qoMdeJfPF1aNsCzmzfZaQ1ZgBTwfmWn\"], \"ALL\"] }" +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"signrawtransaction\",\"params\":[\"0100000083bbd75701007b32687744a8ec1cadeda58b7db9bc8b089484820fe010aaaaae42784be24e0000000000ffffffff02bcf60100000000001976a9142b4cf64627268ac24effd9aad5895e8ca862114288ac43123b00000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000\", [{\"txid\":\"4ee24b7842aeaaaa10e00f828494088bbcb97d8ba5edad1ceca8447768327bc4\",\"vout\":0,\"scriptPubKey\":\"76a91442947a6941767b71f61fd9fec6514d96fef700e988ac\"}], [], \"ALL\"] }" diff --git a/iguana/tests/signrawtransaction2 b/iguana/tests/signrawtransaction2 index a25bf319e..88f8844c2 100755 --- a/iguana/tests/signrawtransaction2 +++ b/iguana/tests/signrawtransaction2 @@ -1,2 +1,4 @@ +#!/bin/bash +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"signrawtransaction\",\"params\":[\"01000000dc4f24570156bb006164173811be6647f68f9a46eab4322e6fdef816aeb3e71e419ca49bfe1800000000ffffffff01588c0200000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\", [{\"txid\":\"fe9ba49c411ee7b3ae16f8de6f2e32b4ea469a8ff64766be113817646100bb56\",\"vout\":24}], [\"UqvuZXEAVXDXJkL4j4Xq6qoMdeJfPF1aNsCzmzfZaQ1ZgBTwfmWn\"], \"ALL\"] }" diff --git a/iguana/tests/smartadd b/iguana/tests/smartadd new file mode 100755 index 000000000..41b844ecc --- /dev/null +++ b/iguana/tests/smartadd @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"smartaddress\",\"type\":\"usd\",\"symbol\":\"USD\"}" # first time +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"smartaddress\",\"type\":\"usd\",\"symbol\":\"REVS\",\"maxbid\":0.20,\"minask\":0.10}" diff --git a/iguana/tests/smartaddresses b/iguana/tests/smartaddresses new file mode 100755 index 000000000..fbcccbf57 --- /dev/null +++ b/iguana/tests/smartaddresses @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"smartaddresses\"}" diff --git a/iguana/tests/snapshot b/iguana/tests/snapshot new file mode 100755 index 000000000..56108d4cf --- /dev/null +++ b/iguana/tests/snapshot @@ -0,0 +1,3 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"snapshot\",\"height\":1486000,\"symbol\":\"BTCD\"}" + diff --git a/iguana/tests/splitfunds b/iguana/tests/splitfunds new file mode 100755 index 000000000..75f93431e --- /dev/null +++ b/iguana/tests/splitfunds @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"agent\":\"iguana\",\"method\":\"splitfunds\",\"satoshis\":\"50000\",\"sendflag\":1,\"duplicates\":10}" diff --git a/iguana/tests/stakers b/iguana/tests/stakers index bf6c5f5f9..71aae0a92 100755 --- a/iguana/tests/stakers +++ b/iguana/tests/stakers @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"stakers\",\"activecoin\":\"BTCD\"}" diff --git a/iguana/tests/statstest b/iguana/tests/statstest new file mode 100755 index 000000000..a91ae778e --- /dev/null +++ b/iguana/tests/statstest @@ -0,0 +1,3 @@ +#!/bin/bash +#curl --url "http://127.0.0.1:7779" --data "{\"method\":\"bitmap\",\"endtimestamp\":0,\"source\":\"KMD\",\"dest\":\"BTC\",\"numdates\":30}" +curl --url "http://78.46.193.199:7779" --data "{\"method\":\"bitmap\",\"endtimestamp\":0,\"source\":\"KMD\",\"dest\":\"BTC\",\"numdates\":30}" diff --git a/iguana/tests/swaplist b/iguana/tests/swaplist new file mode 100755 index 000000000..2db29548e --- /dev/null +++ b/iguana/tests/swaplist @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"getswaplist\"}" diff --git a/iguana/tests/swapstatus b/iguana/tests/swapstatus index 325a1f1ac..82d2e2cc4 100755 --- a/iguana/tests/swapstatus +++ b/iguana/tests/swapstatus @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"swapstatus\",\"requestid\":1728286611,\"quoteid\":123456}" diff --git a/iguana/tests/test b/iguana/tests/test deleted file mode 100755 index 0804f2cdf..000000000 --- a/iguana/tests/test +++ /dev/null @@ -1,2 +0,0 @@ -echo "{\"field\":\"requiredvalue\"}" > /tmp/foo -./jsoncmp /tmp/foo {\"fields\":[{\"field\":\"requiredvalue\"}]} diff --git a/iguana/tests/txdata b/iguana/tests/txdata old mode 100644 new mode 100755 index 182bc5e38..df6e330f4 --- a/iguana/tests/txdata +++ b/iguana/tests/txdata @@ -1 +1,2 @@ +#!/bin/bash 010000007cf5a0560129b801b4a171146128ff452388de7f79ef84dd6440c8338721f262a8723ce2b24e0000006b483045022100a0916f2f567430465491f013f5c5aaa8fc85f30ecd769b63e5138bb68d0397930220444fde47c6a164ebb60c2a886be68f7037225803c3f9fbf38521227ee9fcd8a3012102bed1c9ebabc5b7e1599f994535e23c30f8d16f06a16eca70e1b3023393b5d736ffffffff6561b80200000000001976a9142a9728ebe5238ee9c792a85c31f383258988638888aca70a1300000000001976a914f6a928f1d41edc531b58e1e74d9b5f42a2b172ce88ac84e10a00000000001976a914900b8c6fff5a412419f83159fb46ba9dd44c57ce88ac94673600000000001976a9143da598437a5fefc0258bc493189161a5de913b7688ac84e10a00000000001976a9141f4d437fedd4e8edde06ebe1f4f9722344669d3188ac61b80200000000001976a914fac8ed758c3674997910f3af15f724226da8c41d88aca70a1300000000001976a9140d8a2b6acbe8377f8b7a32579b720b38928d26fe88ac23290800000000001976a9146b40f6bcf074203f3290892e6c3e2ea636801b0c88ac23290800000000001976a914bebe555fc61384241c235264e321512e276ecd8488aca3596401000000001976a9149c8da3a872ff73018d0a5431a667ceab19e6701f88ac10862b00000000001976a914c39b6e8752c40291b06feeaf4dba2220c2142cf788ac61b80200000000001976a914409818ca21d824feb495364c72641bd64400df2f88aced5c2300000000001976a914059779da335857a73b6657f2633875abef964e4888ac61b80200000000001976a9148619a26459aae54f2183ca6885bfc66e31b0297788ac46521000000000001976a914a2bbb9b2789310dbc81386101f4ae62b35009ba888ac81c45900000000001976a914dbc9bfd3805e69f5060277a4de69ec9a91cee6fd88ac46521000000000001976a9149ae8c51664de7e4a37704104ff15eba6d537bad788ac61b80200000000001976a914ab3bd2c4aca00f81dfa2f7ad66e837ef0fcd91dd88aca4ed6100000000001976a914f244452d87a1fec4db49b84ee604698d7380f7d288ac61b80200000000001976a914f827410c13fdb549c3672c081a8eaf0769dd507588acc2700500000000001976a914cfdca8d112dc3de4b9fbe466e399da759a065a7088ac5e9b5100000000001976a9142b969f3592b9958691bf446b08f09c28e284669088ac84e10a00000000001976a914430795c0cd6b4f622c61a1edae56e50835edd94f88ac61b80200000000001976a914de61ec6a29c441f62be030537c72ce452118b8e688ac61b80200000000001976a91410acba3a841fae68aba4b5ff162714c493bcc04e88ac61b80200000000001976a91471e22c8137cb5f0d93d2ea3d4c984c283f8ea95a88ac4bf87400000000001976a9141875d3f6a95714245993caf23cefec1508a302f388ac866abe00000000001976a9143c1f4f93ec300bf85f06e6e23956a0325e81aff988ac23290800000000001976a914d82ac199053ab70059239dc4c0670a766318569e88acd2f63000000000001976a914d132d60a8cf311fe597e11fe71eb12f64c46bce088acc2700500000000001976a91441189216ec876e7be716fca7fe29149a95ef946488ac61b80200000000001976a9143addea52337ad7c672fe04b102f027fcf0a801af88ac23290800000000001976a914731a82df7e0db5bd60432a937ecab8cfc171259888acc2700500000000001976a914c2fd5ba321e6aee6d39c9347ce0089ad00b51f9588ac61b80200000000001976a91498f917fe1904ec2116dc78c2713605b5cc393b4788ac61b80200000000001976a914455e29e97f8ff02973a800c16d96e44b36e502c688ac200c5700000000001976a91439cfaf75df642ce2dd2a692a4be5d19371505ef788ac23290800000000001976a914fc03963b63886a4fcf0c1fb12fd1f5210103f89488ac23290800000000001976a91432d20902680d8c2a105685297d9e87092ee2184188ac61b80200000000001976a91486e576a5a8b711dabfc765591d4d5c764ad1eb1088aced5c2300000000001976a91406c56c1bc7af3ff3804822a3fff53c2a2f6d025c88ac61b80200000000001976a914837921b1254ced8af2640777da56fcfe9e48cac388ac61b80200000000001976a914c116620ae8747f40daa653c8eddf58cd6602ec0588ac23290800000000001976a914ca8fc7699dbe46694fe194d7e65be1b42e6866b988ac5e9b5100000000001976a914c26761dc6cd0c8d1782bddc1715ed04fa6711e6688ac61b80200000000001976a914f4e3b78842d745caf17eb64984bd8f9e4b75392888ac23290800000000001976a91431f6ff68e6ee2b574ce48d7cc6df79bb3d4f763a88ac713e2e00000000001976a9141401968d43c09efedbc381385127f84bc6c779ee88ac61b80200000000001976a914507288d95ddc1c30297ffbe75c6049ab52b2abc588ac18494100000000001976a914ca3eb7d89e5712838d37b7e6bae27ff8bd46adde88ac08c31500000000001976a914debe0477f71a4387a88e668893f64c1a8e85ff1288ac23290800000000001976a91421e2fb66e1ebf5e479a723002ea457d5d33c9b6f88acc2700500000000001976a91476167f22f8f4a11ad42e54d44c5158d041d3f35088ac23290800000000001976a914e5709beffa45123a17419832dda7116af048373588ac0d697a00000000001976a91469d5f122c4972a9be5eaa545519317dfa70626e388ace27c5c00000000001976a9148467a751755e86e969b27be8c0bacd571daed2bb88ac61b80200000000001976a914ec97ef5a68fc6be0e02ff496834454963e18223388ac84e10a00000000001976a9142904efeca777bbd02a48dbed0cfefdd445c5e92088ac697b1800000000001976a914670f40dc03c009098c1603eaf7810c9a1c05395a88ac61b80200000000001976a9142da73a5e01ef854d875013af642f040e05005c7588ac61b80200000000001976a91482000570d55e62d374d0c34c4dbac56240ef852d88acc2700500000000001976a914cf4aa579ba5b12c2f3072e15f9f13549d37e838588ac61b80200000000001976a91435404d3a1a72bfb8302bcc1e3ad04f59be57daba88acd2f63000000000001976a914464a4370b3076076894da53e65f4074786f5c2f388acc2700500000000001976a91400663898623384e2e13679dc0a42134b6f2f9fc488ac61b80200000000001976a9147ed7767129e8cedc6e683988a3c546cf3034ce0988ac61b80200000000001976a9148c85c32b5137173265b3a8908a8a079d35f2cad088aca3c33c1b000000001976a9149a5de522483fd5f33f565dda83340af225f17d5488aca70a1300000000001976a9148c0964bc35065d6d78355a5f4cbe5034b5f356a088ac10862b00000000001976a914e763aae64684afa07001435a54c55d61b5409f7188ac61b80200000000001976a914a9eda113dcb89ba0fc9984e356231928e4e1503788ac273b6f01000000001976a91400427207d45a817b74f20e935dd794a23d4256d088ac697b1800000000001976a91420db5c7cb9fc153069b3c33748f918892d5897b188ac5e9b5100000000001976a914a6293e41aa0d9df57b6c2279330cd54fb99a98f588ac120fdf00000000001976a9143e064e89f2292b215cfa35a1ca9924e55b3a154e88ac46521000000000001976a914e95fc45794f57d0241c6b0a0e90a17c29cace1f288acf51f3900000000001976a91422c69a323907ef4b9c17216350dc24769d87588488ac23290800000000001976a914d69d25fddb12c495f967cc930a6b1837a2f683c288acc2700500000000001976a914bbeff7dfa4383ae320cef44eaa44950f665f628e88ac3b724900000000001976a914a2a3367d75e4e5e399017e4138197407e6cfb93a88ac4e152600000000001976a914ce9781f7d5a39c3e1b1fead5e5da2f40747d6cab88ac46521000000000001976a91491732d8876aa026764dd332b9202aeac8927d36388ac61b80200000000001976a9148d1be008ddd3358e25e7110e88d4e09eb6400fa188ace5990d00000000001976a91488d231a12e880ec2f88bd2df9250102942f3258288ac61b80200000000001976a9148a53d0dab4a2a643cd5ef747c0e4786727c6bb2a88ac93d33801000000001976a9140aae0856c56aa515137d9cd45fe69f284b0cc84c88ac84e10a00000000001976a91449919b6f02d6669c3c2d26194fccf03b72a74f7e88ac84e10a00000000001976a91473753974a6cc712d8a6b47c1ae7068bda98cf0c488ace68ec301000000001976a914e8bf0dc66ac203127aadc49c06c2f1207ab54d5c88ace5990d00000000001976a914a3fbd9847729046af324b909eb700f5d5446680e88acc2700500000000001976a9146913ec42559f6ba0b0dd743a216fa8abb090198788ac61b80200000000001976a9144ad49bc80d99732b0286678c2cb232aa5d4b1fc288ac2bec1d00000000001976a9145014b273313506de7ab7bd9e22f4d7ae8c5b320d88ac30928200000000001976a91494b58e79a98398f5984043b676b2fc5b1d9d246c88acc2700500000000001976a914e6dce6b6ecff523f07b03013d81a8de494b4111d88ac84e10a00000000001976a914bb5d4ba61f34e27c21c3014897b236aeb78182dd88ac61b80200000000001976a91412aa0018548d83dde85257e2d9eeb83feb85403488acc2700500000000001976a91416ede9013dbdfc6658a122461f0ee87972a9255388aca70a1300000000001976a914a1ca84147d965f39fd45a7c3c2ca73aa59ce804888acb4738d00000000001976a91443aa9f60dfac7072f421c6a5aa1bfc9e68dbc44888acc2700500000000001976a914f9dd37f4373bab3e04d4c3f30c88707b2cffd20288ac00000000 diff --git a/iguana/tests/utxocombine b/iguana/tests/utxocombine new file mode 100755 index 000000000..8f7ab3ff9 --- /dev/null +++ b/iguana/tests/utxocombine @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"utxocombine\",\"vals\":{\"coinaddr\":\"1E2ac2gxeFR2ir1H3vqETTperWkiXkwy99\",\"maxamount\":0.0001,\"sendflag\":0}}" diff --git a/iguana/tests/utxorawtx b/iguana/tests/utxorawtx new file mode 100755 index 000000000..7fc804c2f --- /dev/null +++ b/iguana/tests/utxorawtx @@ -0,0 +1 @@ +#!/bin/bashcurl --url "http://127.0.0.1:7778" --data "{\"symbol\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"utxorawtx\",\"vals\":{\"timelock\":0,\"changeaddr\":\"1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg\",\"destaddr\":\"1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg\",\"txfee\":0,\"amount\":0.0001,\"sendflag\":0},\"utxos\":[{\"value\":0.00100000,\"address\":\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\",\"scriptPubKey\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\",\"confirmations\":23351,\"spendable\":true}]}" diff --git a/iguana/tests/validateaddress b/iguana/tests/validateaddress index 1ea44c657..f3524101f 100755 --- a/iguana/tests/validateaddress +++ b/iguana/tests/validateaddress @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"validateaddress\",\"params\":[\"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm\"]}" diff --git a/iguana/tests/validaterawtransaction b/iguana/tests/validaterawtransaction index d28b172a2..0e8d109af 100755 --- a/iguana/tests/validaterawtransaction +++ b/iguana/tests/validaterawtransaction @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"validaterawtransaction\",\"params\":[\"0100000001d330b1a60b68272d1249a178605ef699e26772a642a68d2e0558a7a558dc420100000000b4483045022100c4de2343865be62552137fc594a5acbe8db036aa7fc811ed7819966f6b30a0400220522776e79aff3ec77947837c03c2a6a11a1c1953f551fc0b6e87350a10c86b6601514c676304b762a657b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a91418a616c8617d1bbae6369e5d41c2cd1e5d4c0f9c88210398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcbf4baac685100000000000001d441\", 1]}" diff --git a/iguana/tests/value b/iguana/tests/value new file mode 100755 index 000000000..e6e38ee74 --- /dev/null +++ b/iguana/tests/value @@ -0,0 +1,2 @@ +#!/bin/bash +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"value\",\"vals\":{\"vout\":0,\"txid\":\"aa82ebd1c5bd2a9e19214cbc959df1745378676fddfd6f4903930ac16485c7ae\",\"symbol\":\"BTC\"}}" diff --git a/iguana/tests/verifymessage b/iguana/tests/verifymessage index 1b7761603..54b7036d1 100755 --- a/iguana/tests/verifymessage +++ b/iguana/tests/verifymessage @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"verifymessage\",\"params\":[\"1H5iJUaopB8Zpu1sBTKAPXC2MqVM1DQgRz\", \"IDbLEkZFwjfPfXyEXVKr0x0e3GjiyY3W67/wATCUanqXcD96JlzzDEHfcPjr7YpEEWItqEkR6HC+kvBSFHVp6Jc=\", \"testmessage\"]}" diff --git a/iguana/tests/verifymessageB b/iguana/tests/verifymessageB index 0b81050d0..505dbc061 100755 --- a/iguana/tests/verifymessageB +++ b/iguana/tests/verifymessageB @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"verifymessage\",\"params\":[\"1KHJ4zELwwwND4dytYp7tFyBvELMH1r7a7\", \"H2dVkWTaunFi4g1W50hsXWQy/m/G0KjrjBujo/SMSxQ3GBFPHRU3F//lTkciFP9c53hBrAnqQGaecsov6Gter3I=\", \"testmessage\"]}" diff --git a/iguana/tests/verifymessageC b/iguana/tests/verifymessageC index 1d47c0413..53aa01a2c 100755 --- a/iguana/tests/verifymessageC +++ b/iguana/tests/verifymessageC @@ -1,2 +1,3 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"verifymessage\",\"params\":[\"RAoMou7euzvDwa9dQwjrNB5A41hrAWgvBt\", \"IGIYj77TqR1PnFs4oxY503NpBDJEMA8MB9H+/dF5Xm9xadgIDEDbWor6rbBaUYIxTvGzWDKOQ2z9tHvnPzcn47E=\", \"testmessage\"]}" diff --git a/iguana/tests/walletlock b/iguana/tests/walletlock index fb2012ea4..7f8487514 100755 --- a/iguana/tests/walletlock +++ b/iguana/tests/walletlock @@ -1 +1,2 @@ +#!/bin/bash curl --url "http://127.0.0.1:7778" --data "{\"method\":\"walletlock\",\"params\":[]}" diff --git a/iguana/tests/walletpassphrase b/iguana/tests/walletpassphrase index d5c8f0fcb..94d46e776 100755 --- a/iguana/tests/walletpassphrase +++ b/iguana/tests/walletpassphrase @@ -1,2 +1,4 @@ +#!/bin/bash #curl --url "http://127.0.0.1:7778" --data "{\"method\":\"walletpassphrase\",\"params\":[\"test\", 600]}" curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"test\",\"timeout\":86444}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"jumblr\",\"method\":\"setpassphrase\",\"passphrase\":\"jumblr test\"}" diff --git a/includes/cJSON.h b/includes/cJSON.h index 2de29d8d7..3ecdadc69 100755 --- a/includes/cJSON.h +++ b/includes/cJSON.h @@ -26,12 +26,10 @@ #include #include #include -#include #include #include #include #include -#include #include "../crypto777/OS_portable.h" @@ -75,6 +73,7 @@ extern "C" double valuedouble; /* The item's number, if type==cJSON_Number */ char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + uint32_t cjsonid; } cJSON; typedef struct cJSON_Hooks { @@ -213,13 +212,15 @@ extern "C" char *get_cJSON_fieldname(cJSON *obj); void ensure_jsonitem(cJSON *json,char *field,char *value); int32_t in_jsonarray(cJSON *array,char *value); - char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params); + char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params,int32_t timeout); uint64_t calc_nxt64bits(const char *str); int32_t expand_nxt64bits(char *str,uint64_t nxt64bits); char *nxt64str(uint64_t nxt64bits); char *nxt64str2(uint64_t nxt64bits); cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num); int32_t myatoi(char *str,int32_t range); + void cJSON_register(cJSON *item); + void cJSON_unregister(cJSON *item); char *stringifyM(char *str); #define replace_backslashquotes unstringify diff --git a/includes/curl/.gitignore b/includes/curl/.gitignore new file mode 100644 index 000000000..228a961fb --- /dev/null +++ b/includes/curl/.gitignore @@ -0,0 +1,4 @@ +curlbuild.h +curlver.h.dist +stamp-h2 +stamp-h3 diff --git a/includes/curl/Makefile.am b/includes/curl/Makefile.am new file mode 100644 index 000000000..7c924fcb5 --- /dev/null +++ b/includes/curl/Makefile.am @@ -0,0 +1,53 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +pkginclude_HEADERS = \ + curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \ + typecheck-gcc.h curlbuild.h curlrules.h + +pkgincludedir= $(includedir)/curl + +# curlbuild.h does not exist in the git tree. When the original libcurl +# source code distribution archive file is created, curlbuild.h.dist is +# renamed to curlbuild.h and included in the tarball so that it can be +# used directly on non-configure systems. +# +# The distributed curlbuild.h will be overwritten on configure systems +# when the configure script runs, with one that is suitable and specific +# to the library being configured and built. +# +# curlbuild.h.in is the distributed template file from which the configure +# script creates curlbuild.h at library configuration time, overwiting the +# one included in the distribution archive. +# +# curlbuild.h.dist is not included in the source code distribution archive. + +EXTRA_DIST = curlbuild.h.in + +DISTCLEANFILES = curlbuild.h + +checksrc: + @@PERL@ $(top_srcdir)/lib/checksrc.pl -Wcurlbuild.h -D$(top_srcdir)/include/curl $(pkginclude_HEADERS) $(EXTRA_DIST) + +if CURLDEBUG +# for debug builds, we scan the sources on all regular make invokes +all-local: checksrc +endif diff --git a/includes/curl/curl.h b/includes/curl/curl.h new file mode 100644 index 000000000..7c7d28d6a --- /dev/null +++ b/includes/curl/curl.h @@ -0,0 +1,2551 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * https://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#ifdef CURL_NO_OLDIES +#define CURL_STRICTER +#endif + +#include "curlver.h" /* libcurl version defines */ +#include "curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#endif + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on systems that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_easy CURL; +typedef struct Curl_share CURLSH; +#else +typedef void CURL; +typedef void CURLSH; +#endif + +/* + * libcurl external API function linkage decorations. + */ + +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +# define CURL_EXTERN +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist *contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ +}; + +/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered + deprecated but was the only choice up until 7.31.0 */ +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in + 7.32.0, it avoids floating point and provides more detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_READ_SIZE + /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ +#define CURL_MAX_READ_SIZE 524288 +#endif + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + + + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char *b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + +/* compatibility with older names */ +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING +#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY + +/* The following were added in 7.21.5, April 2011 */ +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +#define CURL_ERROR_SIZE 256 + +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS +}; + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum curl_khtype keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_STRINGPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, STRINGPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, STRINGPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, STRINGPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, STRINGPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, STRINGPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, STRINGPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, STRINGPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, STRINGPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, STRINGPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, STRINGPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, STRINGPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, STRINGPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, STRINGPOINT, 36), + + /* FILE handle to use instead of stderr */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, STRINGPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, STRINGPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, STRINGPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, STRINGPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, STRINGPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, STRINGPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, STRINGPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, STRINGPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, STRINGPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, STRINGPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, STRINGPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and + CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, STRINGPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, STRINGPOINT, 134), + + /* feed cookie into cookie engine */ + CINIT(COOKIELIST, STRINGPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, STRINGPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, STRINGPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, STRINGPOINT, 173), + CINIT(PASSWORD, STRINGPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, STRINGPOINT, 175), + CINIT(PROXYPASSWORD, STRINGPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, STRINGPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, STRINGPOINT, 186), + + /* set the list of SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of miliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, OBJECTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CINIT(SSL_VERIFYSTATUS, LONG, 232), + + /* Set if we should enable TLS false start. */ + CINIT(SSL_FALSESTART, LONG, 233), + + /* Do not squash dot-dot sequences */ + CINIT(PATH_AS_IS, LONG, 234), + + /* Proxy Service Name */ + CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), + + /* Service Name */ + CINIT(SERVICE_NAME, STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CINIT(PIPEWAIT, LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CINIT(STREAM_WEIGHT, LONG, 239), + + /* Set stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CINIT(TFTP_NO_OPTIONS, LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CINIT(CONNECT_TO, OBJECTPOINT, 243), + + /* Set TCP Fast Open */ + CINIT(TCP_FASTOPEN, LONG, 244), + + /* Continue to send data if the server responds early with an + * HTTP status code >= 300 */ + CINIT(KEEP_SENDING_ON_ERROR, LONG, 245), + + /* The CApath or CAfile used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAINFO, STRINGPOINT, 246), + + /* The CApath directory used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAPATH, STRINGPOINT, 247), + + /* Set if we should verify the proxy in ssl handshake, + set 1 to verify. */ + CINIT(PROXY_SSL_VERIFYPEER, LONG, 248), + + /* Set if we should verify the Common name from the proxy certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches + * the provided hostname. */ + CINIT(PROXY_SSL_VERIFYHOST, LONG, 249), + + /* What version to specifically try to use for proxy. + See CURL_SSLVERSION defines below. */ + CINIT(PROXY_SSLVERSION, LONG, 250), + + /* Set a username for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251), + + /* Set a password for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252), + + /* Set authentication type for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253), + + /* name of the file keeping your private SSL-certificate for proxy */ + CINIT(PROXY_SSLCERT, STRINGPOINT, 254), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255), + + /* name of the file keeping your private SSL-key for proxy */ + CINIT(PROXY_SSLKEY, STRINGPOINT, 256), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257), + + /* password for the SSL private key for proxy */ + CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258), + + /* Specify which SSL ciphers to use for proxy */ + CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259), + + /* CRL file for proxy */ + CINIT(PROXY_CRLFILE, STRINGPOINT, 260), + + /* Enable/disable specific SSL features with a bitmask for proxy, see + CURLSSLOPT_* */ + CINIT(PROXY_SSL_OPTIONS, LONG, 261), + + /* Name of pre proxy to use. */ + CINIT(PRE_PROXY, STRINGPOINT, 262), + + /* The public key in DER form used to validate the proxy public key + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263), + + /* Path to an abstract Unix domain socket */ + CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264), + + /* Suppress proxy CONNECT response headers from user callbacks */ + CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + CURL_SSLVERSION_TLSv1_3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +enum { + CURL_SSLVERSION_MAX_NONE = 0, + CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), + CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), + CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), + CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), + CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), + + /* never use, keep last */ + CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) +}; + +enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, + CURL_TLSAUTH_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details + + !checksrc! disable SPACEBEFOREPAREN 2 +*/ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_CYASSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_DARWINSSL = 9, + CURLSSLBACKEND_AXTLS = 10, + CURLSSLBACKEND_MBEDTLS = 11 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL 1 +#define CURLSSLBACKEND_BORINGSSL 1 +#define CURLSSLBACKEND_WOLFSSL 6 + +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_SLIST + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = CURLINFO_LONG + 48, + CURLINFO_SCHEME = CURLINFO_STRING + 49, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 49 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is suported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ +#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ + + /* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/includes/curl/curlbuild.h b/includes/curl/curlbuild.h new file mode 100644 index 000000000..ae95095fa --- /dev/null +++ b/includes/curl/curlbuild.h @@ -0,0 +1,586 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * See file include/curl/curlbuild.h.in, run configure, and forget + * that this file exists it is only used for non-configure systems. + * But you can keep reading if you want ;-) + * + */ + +/* ================================================================ */ +/* NOTES FOR NON-CONFIGURE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * Try to keep one section per platform, compiler and architecture, + * otherwise, if an existing section is reused for a different one and + * later on the original is adjusted, probably the piggybacking one can + * be adversely changed. + * + * In order to differentiate between platforms/compilers/architectures + * use only compiler built in predefined preprocessor symbols. + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * For any given platform/compiler curl_off_t must be typedef'ed to a + * 64-bit wide signed integral data type. The width of this data type + * must remain constant and independent of any possible large file + * support settings. + * + * As an exception to the above, curl_off_t shall be typedef'ed to a + * 32-bit wide signed integral data type if there is no 64-bit type. + * + * As a general rule, curl_off_t shall not be mapped to off_t. This + * rule shall only be violated if off_t is the only 64-bit data type + * available and the size of off_t is independent of large file support + * settings. Keep your build on the safe side avoiding an off_t gating. + * If you have a 64-bit off_t then take for sure that another 64-bit + * data type exists, dig deeper and you will find it. + * + * NOTE 3: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.dist or + * at file include/curl/curlbuild.h, this is due to the following reason: + * file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h + * when the libcurl source code distribution archive file is created. + * + * File include/curl/curlbuild.h.dist is not included in the distribution + * archive. File include/curl/curlbuild.h is not present in the git tree. + * + * The distributed include/curl/curlbuild.h file is only intended to be used + * on systems which can not run the also distributed configure script. + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + * If you check out from git on a non-configure platform, you must run the + * appropriate buildconf* script to set up curlbuild.h and other local files. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY */ +/* ================================================================ */ + +#if defined(__DJGPP__) || defined(__GO32__) +# if defined(__DJGPP__) && (__DJGPP__ > 1) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SALFORDC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x520) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__TURBOC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__WATCOMC__) +# if defined(__386__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__POCC__) +# if (__POCC__ < 280) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# elif defined(_MSC_VER) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__LCC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SYMBIAN32__) +# if defined(__EABI__) /* Treat all ARM compilers equally */ +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__CW32__) +# pragma longlong on +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__VC32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MWERKS__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(_WIN32_WCE) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MINGW32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__VMS) +# if defined(__VAX) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__OS400__) +# if defined(__ILEC400__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__MVS__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__370__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(TPF) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP MSVC THE PENULTIMATE ENTRY */ +/* ===================================== */ + +#elif defined(_MSC_VER) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP GENERIC GCC THE LAST ENTRY */ +/* ===================================== */ + +#elif defined(__GNUC__) +# if !defined(__LP64__) && (defined(__ILP32__) || \ + defined(__i386__) || defined(__ppc__) || defined(__arm__) || \ + defined(__sparc__) || defined(__mips__) || defined(__sh__)) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64__) || \ + defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#else +# error "Unknown non-configure build target!" + Error Compilation_aborted_Unknown_non_configure_build_target +#endif + +/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ +/* sys/types.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ +/* sys/socket.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Data type definition of curl_socklen_t. */ + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T + typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; +#endif + +/* Data type definition of curl_off_t. */ + +#ifdef CURL_TYPEOF_CURL_OFF_T + typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; +#endif + +#endif /* __CURL_CURLBUILD_H */ diff --git a/includes/curl/curlbuild.h.cmake b/includes/curl/curlbuild.h.cmake new file mode 100644 index 000000000..bbb31a940 --- /dev/null +++ b/includes/curl/curlbuild.h.cmake @@ -0,0 +1,197 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +#cmakedefine CURL_PULL_WS2TCPIP_H +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#cmakedefine CURL_PULL_SYS_TYPES_H +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#cmakedefine CURL_PULL_STDINT_H +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#cmakedefine CURL_PULL_INTTYPES_H +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#cmakedefine CURL_PULL_SYS_SOCKET_H +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/poll.h must be included by the external interface. */ +#cmakedefine CURL_PULL_SYS_POLL_H +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#define CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG} + +/* Integral data type used for curl_socklen_t. */ +#define CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T} + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T} + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#define CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T} + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}" + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}" + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#define CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}" + +/* The size of `curl_off_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T} + +/* curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T} + +/* unsigned curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU} + +#endif /* __CURL_CURLBUILD_H */ diff --git a/includes/curl/curlbuild.h.dist b/includes/curl/curlbuild.h.dist new file mode 100644 index 000000000..ae95095fa --- /dev/null +++ b/includes/curl/curlbuild.h.dist @@ -0,0 +1,586 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * See file include/curl/curlbuild.h.in, run configure, and forget + * that this file exists it is only used for non-configure systems. + * But you can keep reading if you want ;-) + * + */ + +/* ================================================================ */ +/* NOTES FOR NON-CONFIGURE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * Try to keep one section per platform, compiler and architecture, + * otherwise, if an existing section is reused for a different one and + * later on the original is adjusted, probably the piggybacking one can + * be adversely changed. + * + * In order to differentiate between platforms/compilers/architectures + * use only compiler built in predefined preprocessor symbols. + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * For any given platform/compiler curl_off_t must be typedef'ed to a + * 64-bit wide signed integral data type. The width of this data type + * must remain constant and independent of any possible large file + * support settings. + * + * As an exception to the above, curl_off_t shall be typedef'ed to a + * 32-bit wide signed integral data type if there is no 64-bit type. + * + * As a general rule, curl_off_t shall not be mapped to off_t. This + * rule shall only be violated if off_t is the only 64-bit data type + * available and the size of off_t is independent of large file support + * settings. Keep your build on the safe side avoiding an off_t gating. + * If you have a 64-bit off_t then take for sure that another 64-bit + * data type exists, dig deeper and you will find it. + * + * NOTE 3: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.dist or + * at file include/curl/curlbuild.h, this is due to the following reason: + * file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h + * when the libcurl source code distribution archive file is created. + * + * File include/curl/curlbuild.h.dist is not included in the distribution + * archive. File include/curl/curlbuild.h is not present in the git tree. + * + * The distributed include/curl/curlbuild.h file is only intended to be used + * on systems which can not run the also distributed configure script. + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + * If you check out from git on a non-configure platform, you must run the + * appropriate buildconf* script to set up curlbuild.h and other local files. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY */ +/* ================================================================ */ + +#if defined(__DJGPP__) || defined(__GO32__) +# if defined(__DJGPP__) && (__DJGPP__ > 1) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SALFORDC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x520) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__TURBOC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__WATCOMC__) +# if defined(__386__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__POCC__) +# if (__POCC__ < 280) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# elif defined(_MSC_VER) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__LCC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SYMBIAN32__) +# if defined(__EABI__) /* Treat all ARM compilers equally */ +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__CW32__) +# pragma longlong on +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__VC32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MWERKS__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(_WIN32_WCE) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MINGW32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__VMS) +# if defined(__VAX) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__OS400__) +# if defined(__ILEC400__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__MVS__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__370__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(TPF) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP MSVC THE PENULTIMATE ENTRY */ +/* ===================================== */ + +#elif defined(_MSC_VER) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP GENERIC GCC THE LAST ENTRY */ +/* ===================================== */ + +#elif defined(__GNUC__) +# if !defined(__LP64__) && (defined(__ILP32__) || \ + defined(__i386__) || defined(__ppc__) || defined(__arm__) || \ + defined(__sparc__) || defined(__mips__) || defined(__sh__)) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64__) || \ + defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#else +# error "Unknown non-configure build target!" + Error Compilation_aborted_Unknown_non_configure_build_target +#endif + +/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ +/* sys/types.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ +/* sys/socket.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Data type definition of curl_socklen_t. */ + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T + typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; +#endif + +/* Data type definition of curl_off_t. */ + +#ifdef CURL_TYPEOF_CURL_OFF_T + typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; +#endif + +#endif /* __CURL_CURLBUILD_H */ diff --git a/includes/curl/curlbuild.h.in b/includes/curl/curlbuild.h.in new file mode 100644 index 000000000..ffab35670 --- /dev/null +++ b/includes/curl/curlbuild.h.in @@ -0,0 +1,197 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +#undef CURL_PULL_WS2TCPIP_H +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#undef CURL_PULL_SYS_TYPES_H +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#undef CURL_PULL_STDINT_H +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#undef CURL_PULL_INTTYPES_H +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#undef CURL_PULL_SYS_SOCKET_H +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/poll.h must be included by the external interface. */ +#undef CURL_PULL_SYS_POLL_H +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#undef CURL_SIZEOF_LONG + +/* Integral data type used for curl_socklen_t. */ +#undef CURL_TYPEOF_CURL_SOCKLEN_T + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#undef CURL_SIZEOF_CURL_SOCKLEN_T + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#undef CURL_TYPEOF_CURL_OFF_T + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#undef CURL_FORMAT_CURL_OFF_T + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#undef CURL_FORMAT_CURL_OFF_TU + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#undef CURL_FORMAT_OFF_T + +/* The size of `curl_off_t', as computed by sizeof. */ +#undef CURL_SIZEOF_CURL_OFF_T + +/* curl_off_t constant suffix. */ +#undef CURL_SUFFIX_CURL_OFF_T + +/* unsigned curl_off_t constant suffix. */ +#undef CURL_SUFFIX_CURL_OFF_TU + +#endif /* __CURL_CURLBUILD_H */ diff --git a/includes/curl/curlrules.h b/includes/curl/curlrules.h new file mode 100644 index 000000000..55d21f68f --- /dev/null +++ b/includes/curl/curlrules.h @@ -0,0 +1,262 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * curl_setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) +# define __CURL_OFF_T_C_HLPR2(x) x +# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) +#else +# ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix +# else +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix +# endif +# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) +#endif + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CURL_PULL_WS2TCPIP_H +#undef CURL_PULL_SYS_TYPES_H +#undef CURL_PULL_SYS_SOCKET_H +#undef CURL_PULL_SYS_POLL_H +#undef CURL_PULL_STDINT_H +#undef CURL_PULL_INTTYPES_H + +#undef CURL_TYPEOF_CURL_SOCKLEN_T +#undef CURL_TYPEOF_CURL_OFF_T + +#ifdef CURL_NO_OLDIES +#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ +#endif + +#endif /* __CURL_CURLRULES_H */ diff --git a/includes/curl/curlver.h b/includes/curl/curlver.h new file mode 100644 index 000000000..7beda3fa7 --- /dev/null +++ b/includes/curl/curlver.h @@ -0,0 +1,77 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.54.0-DEV" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 54 +#define LIBCURL_VERSION_PATCH 0 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. +*/ +#define LIBCURL_VERSION_NUM 0x073600 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "DEV" + +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* __CURL_CURLVER_H */ diff --git a/includes/curl/easy.h b/includes/curl/easy.h new file mode 100644 index 000000000..752c5049f --- /dev/null +++ b/includes/curl/easy.h @@ -0,0 +1,102 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistent connections cannot + * be transferred. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/includes/curl/mprintf.h b/includes/curl/mprintf.h new file mode 100644 index 000000000..e20f546e1 --- /dev/null +++ b/includes/curl/mprintf.h @@ -0,0 +1,50 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include /* needed for FILE */ +#include "curl.h" /* for CURL_EXTERN */ + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/includes/curl/multi.h b/includes/curl/multi.h new file mode 100644 index 000000000..d1e00cc5d --- /dev/null +++ b/includes/curl/multi.h @@ -0,0 +1,439 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_multi CURLM; +#else +typedef void CURLM; +#endif + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was + attempted to get added - again */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +/* bitmask bits for CURLMOPT_PIPELINING */ +#define CURLPIPE_NOTHING 0L +#define CURLPIPE_HTTP1 1L +#define CURLPIPE_MULTIPLEX 2L + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + /* maximum number of (pipelining) connections to one host */ + CINIT(MAX_HOST_CONNECTIONS, LONG, 7), + + /* maximum number of requests in a pipeline */ + CINIT(MAX_PIPELINE_LENGTH, LONG, 8), + + /* a connection with a content-length longer than this + will not be considered for pipelining */ + CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), + + /* a connection with a chunk length longer than this + will not be considered for pipelining */ + CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), + + /* a list of site names(+port) that are blacklisted from + pipelining */ + CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), + + /* a list of server types that are blacklisted from + pipelining */ + CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), + + /* maximum number of open connections in total */ + CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), + + /* This is the server push callback function pointer */ + CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), + + /* This is the argument passed to the server push callback */ + CINIT(PUSHDATA, OBJECTPOINT, 15), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + + +/* + * Name: curl_push_callback + * + * Desc: This callback gets called when a new stream is being pushed by the + * server. It approves or denies the new stream. + * + * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. + */ +#define CURL_PUSH_OK 0 +#define CURL_PUSH_DENY 1 + +struct curl_pushheaders; /* forward declaration only */ + +CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, + size_t num); +CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, + const char *name); + +typedef int (*curl_push_callback)(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/includes/curl/stdcheaders.h b/includes/curl/stdcheaders.h new file mode 100644 index 000000000..027b6f421 --- /dev/null +++ b/includes/curl/stdcheaders.h @@ -0,0 +1,33 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif /* __STDC_HEADERS_H */ diff --git a/includes/curl/typecheck-gcc.h b/includes/curl/typecheck-gcc.h new file mode 100644 index 000000000..3d683152b --- /dev/null +++ b/includes/curl/typecheck-gcc.h @@ -0,0 +1,624 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt)) + * if(!_curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * NOTE: We use two nested 'if' statements here instead of the && operator, in + * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x + * when compiling with -Wlogical-op. + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__(option) _curl_opt = option; \ + if(__builtin_constant_p(_curl_opt)) { \ + if(_curl_is_long_option(_curl_opt)) \ + if(!_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if(_curl_is_off_t_option(_curl_opt)) \ + if(!_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if(_curl_is_string_option(_curl_opt)) \ + if(!_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if(_curl_is_write_cb_option(_curl_opt)) \ + if(!_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_READFUNCTION) \ + if(!_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if(!_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if(!_curl_is_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if(!_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if(!_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if(!_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if(!_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if(_curl_is_conv_cb_option(_curl_opt)) \ + if(!_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if(!_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if(_curl_is_cb_data_option(_curl_opt)) \ + if(!_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if(!_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if((_curl_opt) == CURLOPT_STDERR) \ + if(!_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if(_curl_is_postfields_option(_curl_opt)) \ + if(!_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if((_curl_opt) == CURLOPT_HTTPPOST) \ + if(!_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if(_curl_is_slist_option(_curl_opt)) \ + if(!_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if((_curl_opt) == CURLOPT_SHARE) \ + if(!_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +/* FIXME: don't allow const pointers */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__(info) _curl_info = info; \ + if(__builtin_constant_p(_curl_info)) { \ + if(_curl_is_string_info(_curl_info)) \ + if(!_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if(_curl_is_long_info(_curl_info)) \ + if(!_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if(_curl_is_double_info(_curl_info)) \ + if(!_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if(_curl_is_slist_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), + * for now just make sure that the functions are called with three + * arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((__warning__(message))) \ + __attribute__((__unused__)) __attribute__((__noinline__)) \ + id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a " + "string ('char *' or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a " + "curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a " + "private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a " + "char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a 'FILE *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a 'void *' or 'char *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a 'struct curl_httppost *' " + "argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a 'struct curl_slist *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to 'char *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ + (option) == CURLOPT_ACCEPT_ENCODING || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_DEFAULT_PROTOCOL || \ + (option) == CURLOPT_DNS_INTERFACE || \ + (option) == CURLOPT_DNS_LOCAL_IP4 || \ + (option) == CURLOPT_DNS_LOCAL_IP6 || \ + (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_ISSUERCERT || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_LOGIN_OPTIONS || \ + (option) == CURLOPT_MAIL_AUTH || \ + (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_RTSP_SESSION_ID || \ + (option) == CURLOPT_RTSP_STREAM_URI || \ + (option) == CURLOPT_RTSP_TRANSPORT || \ + (option) == CURLOPT_SERVICE_NAME || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_TLSAUTH_TYPE || \ + (option) == CURLOPT_TLSAUTH_USERNAME || \ + (option) == CURLOPT_UNIX_SOCKET_PATH || \ + (option) == CURLOPT_URL || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_XOAUTH2_BEARER || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_CLOSESOCKETDATA || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_FNMATCH_DATA || \ + (option) == CURLOPT_HEADERDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_WRITEDATA || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_MAIL_RCPT || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_PROXYHEADER || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_RESOLVE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (CURLINFO_SLIST < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true iff expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void *)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *)) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char)) + +/* FIXME: the whole callback checking is messy... + * The idea is to tolerate char vs. void and const vs. not const + * pointers in arguments at least + */ +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func), type*)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void *); +typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void *); +typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE *); +typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void *); +typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void *); +typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void *); +typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, + const void *); +typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE *); +typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void *); +typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, + const void *); +typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void *); +typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void *); +typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void *); +typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void *); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or + "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4) || \ + _curl_callback_compatible((expr), _curl_debug_callback5) || \ + _curl_callback_compatible((expr), _curl_debug_callback6) || \ + _curl_callback_compatible((expr), _curl_debug_callback7) || \ + _curl_callback_compatible((expr), _curl_debug_callback8)) +typedef int (_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); +typedef int (_curl_debug_callback5) (CURL *, + curl_infotype, unsigned char *, size_t, void *); +typedef int (_curl_debug_callback6) (CURL *, + curl_infotype, unsigned char *, size_t, const void *); +typedef int (_curl_debug_callback7) (CURL *, + curl_infotype, const unsigned char *, size_t, void *); +typedef int (_curl_debug_callback8) (CURL *, + curl_infotype, const unsigned char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, + const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/includes/curve25519.h b/includes/curve25519.h index cff0e0e02..9f8c9ba16 100755 --- a/includes/curve25519.h +++ b/includes/curve25519.h @@ -36,8 +36,8 @@ struct rmd160_vstate { uint64_t length; uint8_t buf[64]; uint32_t curlen, state[ struct acct777_sig { bits256 sigbits,pubkey; uint64_t signer64bits; uint32_t timestamp,allocsize; }; -#undef force_inline -#define force_inline __attribute__((always_inline)) +//#undef force_inline +//#define force_inline __attribute__((always_inline)) bits320 fmul(const bits320 in2,const bits320 in); diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index c600ac69e..48d39e417 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,33 +13,61 @@ * * ******************************************************************************/ -#ifdef INCLUDE_PAX -ZERO_ARGS(pax,start); +#ifdef _IGUANA_APIDEC_H_ +emit compiler error if recursively being included #endif -HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin); -ZERO_ARGS(tradebot,amlp); -ZERO_ARGS(tradebot,notlp); - -INT_AND_ARRAY(iguana,rates,unused,quotes); -TWO_STRINGS(iguana,rate,base,rel); -THREE_STRINGS_AND_THREE_INTS(iguana,prices,exchange,base,rel,period,start,end); - -ZERO_ARGS(InstantDEX,allcoins); -STRING_ARG(InstantDEX,available,source); -HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr); +#ifndef _IGUANA_APIDEC_H_ +#define _IGUANA_APIDEC_H_ -INT_ARG(InstantDEX,incoming,requestid); -INT_ARG(InstantDEX,automatched,requestid); +STRING_ARG(dpow,pending,fiat); +ZERO_ARGS(dpow,notarychains); +STRING_ARG(dpow,active,maskhex); +TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified); +ZERO_ARGS(dpow,cancelratify); +STRING_ARG(dpow,bindaddr,ipaddr); +STRING_AND_INT(dpow,fundnotaries,symbol,numblocks); -TWO_INTS(InstantDEX,accept,requestid,quoteid); -//TWO_INTS(InstantDEX,swapstatus,requestid,quoteid); +ZERO_ARGS(pax,start); +INT_ARG(passthru,paxfiats,mask); +TWO_STRINGS(zcash,passthru,function,hex); +TWO_STRINGS(komodo,passthru,function,hex); +TWO_STRINGS(dex,kvsearch,symbol,key); +THREE_STRINGS_AND_THREE_INTS(dex,kvupdate,symbol,key,value,flags,unused,unusedb); + +TWO_STRINGS(dex,send,hex,handler); +HASH_AND_STRING(dex,gettransaction,txid,symbol); +STRING_ARG(dex,getinfo,symbol); +STRING_ARG(dex,getnotaries,symbol); +STRING_ARG(dex,alladdresses,symbol); +STRING_ARG(dex,getbestblockhash,symbol); +STRING_AND_INT(dex,getblockhash,symbol,height); +HASH_AND_STRING(dex,getblock,hash,symbol); +TWO_STRINGS(dex,sendrawtransaction,symbol,signedtx); +HASH_AND_STRING_AND_INT(dex,gettxout,txid,symbol,vout); +TWO_STRINGS(dex,importaddress,symbol,address); +TWO_STRINGS(dex,validateaddress,symbol,address); +TWO_STRINGS(dex,checkaddress,symbol,address); +TWO_STRINGS(dex,listunspent,symbol,address); +TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions,symbol,address,count,skip); +TWO_STRINGS(dex,listunspent2,symbol,address); +TWO_STRINGS_AND_TWO_DOUBLES(dex,listtransactions2,symbol,address,count,skip); +HASH_AND_STRING_AND_INT(dex,gettxin,txid,symbol,vout); +TWO_STRINGS(dex,listspent,symbol,address); +TWO_STRINGS(dex,getbalance,symbol,address); +STRING_ARG(dex,explorer,symbol); +STRING_ARG(dex,getmessage,argstr); +STRING_ARG(dex,psock,argstr); HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr); - +INT_ARG(basilisk,paxfiats,mask); HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr); -//HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr); +TWO_STRINGS(basilisk,refresh,symbol,address); +ZERO_ARGS(basilisk,cancelrefresh); +STRING_ARRAY_OBJ_STRING(basilisk,utxorawtx,symbol,utxos,vals,ignore); +HASH_ARRAY_STRING(basilisk,utxocombine,ignore,vals,symbol); HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr); @@ -56,13 +84,15 @@ HASH_ARRAY_STRING(basilisk,subscribe,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,forward,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,mailbox,hash,vals,hexstr); -HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr); +/*HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,VPNjoin,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,VPNmessage,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,vote,hash,vals,hexstr);*/ + ZERO_ARGS(bitcoinrpc,getinfo); ZERO_ARGS(bitcoinrpc,getblockcount); ZERO_ARGS(bitcoinrpc,getdifficulty); @@ -81,7 +111,6 @@ STRING_AND_INT(bitcoinrpc,decoderawtransaction,rawtx,suppress); STRING_AND_INT(bitcoinrpc,validaterawtransaction,rawtx,suppress); ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime); -ZERO_ARGS(iguana,makekeypair); STRING_ARG(bitcoinrpc,validatepubkey,pubkey); STRING_ARG(bitcoinrpc,validateaddress,address); @@ -94,6 +123,7 @@ STRING_ARG(bitcoinrpc,backupwallet,filename); STRING_ARG(bitcoinrpc,importwallet,filename); STRING_ARG(bitcoinrpc,getnewaddress,account); TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan); +TWOSTRINGS_AND_INT(bitcoinrpc,importaddress,address,account,rescan); STRING_ARG(bitcoinrpc,dumpprivkey,address); STRING_AND_THREEINTS(bitcoinrpc,listtransactions,account,count,skip,includewatchonly); @@ -134,7 +164,16 @@ ZERO_ARGS(bitcoinrpc,gettxoutsetinfo); ZERO_ARGS(bitcoinrpc,getrawchangeaddress); SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment); +THREE_INTS(iguana,splitfunds,satoshis,duplicates,sendflag); +ZERO_ARGS(iguana,makekeypair); +INT_AND_ARRAY(iguana,rates,unused,quotes); +TWO_STRINGS(iguana,rate,base,rel); +THREE_STRINGS_AND_THREE_INTS(iguana,prices,exchange,base,rel,period,start,end); +STRING_AND_INT(iguana,snapshot,symbol,height); +INT_ARRAY_STRING(iguana,dividends,height,vals,symbol); +THREE_STRINGS(iguana,passthru,asset,function,hex); STRING_ARG(iguana,initfastfind,activecoin); +TWO_STRINGS(iguana,dpow,symbol,pubkey); STRING_ARG(iguana,peers,activecoin); STRING_AND_INT(iguana,maxpeers,activecoin,max); STRING_ARG(iguana,getconnectioncount,activecoin); @@ -145,6 +184,7 @@ STRING_ARG(iguana,startcoin,activecoin); STRING_ARG(iguana,pausecoin,activecoin); STRING_ARG(iguana,stopcoin,activecoin); TWO_STRINGS(iguana,addnode,activecoin,ipaddr); +STRING_ARG(iguana,addnotary,ipaddr); TWO_STRINGS(iguana,persistent,activecoin,ipaddr); TWO_STRINGS(iguana,removenode,activecoin,ipaddr); TWO_STRINGS(iguana,oneshot,activecoin,ipaddr); @@ -156,6 +196,18 @@ STRING_AND_INT(iguana,bundlehashes,activecoin,height); STRING_AND_INT(iguana,PoSweights,activecoin,height); STRING_ARG(iguana,stakers,activecoin); +STRING_ARG(jumblr,setpassphrase,passphrase); +ZERO_ARGS(jumblr,status); +ZERO_ARGS(jumblr,runsilent); +ZERO_ARGS(jumblr,totransparent); + +ZERO_ARGS(InstantDEX,allcoins); +STRING_ARG(InstantDEX,available,source); +HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr); +INT_ARG(InstantDEX,incoming,requestid); +INT_ARG(InstantDEX,automatched,requestid); +TWO_INTS(InstantDEX,accept,requestid,quoteid); +//TWO_INTS(InstantDEX,swapstatus,requestid,quoteid); //TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume); //TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume); THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,dotrade); @@ -168,13 +220,17 @@ TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid); TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid); STRING_ARG(InstantDEX,openorders,exchange); STRING_ARG(InstantDEX,tradehistory,exchange); - THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfields,ignore); STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap); //TWO_STRINGS(InstantDEX,events,base,rel); ZERO_ARGS(InstantDEX,allexchanges); STRING_ARG(InstantDEX,allpairs,exchange); THREE_STRINGS(InstantDEX,supports,exchange,base,rel); +ZERO_ARGS(InstantDEX,init); +ZERO_ARGS(InstantDEX,getswaplist); +ZERO_ARGS(InstantDEX,smartaddresses); +TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,smartaddress,type,symbol,maxbid,minask); +DOUBLE_ARG(InstantDEX,DEXratio,ratio); //THREE_STRINGS(atomic,approve,myorderid,otherid,txname); //THREE_STRINGS(atomic,claim,myorderid,otherid,txname); @@ -183,6 +239,11 @@ THREE_STRINGS(InstantDEX,supports,exchange,base,rel); //TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags); //TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,confirm,reference,message,basetxid,reltxid,baseheight,relheight); +HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin); +STRING_ARG(tradebot,amlp,blocktrail); +ZERO_ARGS(tradebot,notlp); +TWO_STRINGS(tradebot,gensvm,base,rel); +ZERO_ARGS(tradebot,openliquidity); THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume); THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission); STRING_AND_DOUBLE(tradebot,monitorall,exchange,commission); @@ -194,8 +255,13 @@ TWO_STRINGS(tradebot,status,exchange,botid); TWO_STRINGS(tradebot,pause,exchange,botid); TWO_STRINGS(tradebot,stop,exchange,botid); TWO_STRINGS(tradebot,resume,exchange,botid); +ZERO_ARGS(tradebot,allbalances); +ZERO_ARGS(tradebot,anchor); +ZERO_ARGS(tradebot,portfolio); +ARRAY_OBJ_INT(tradebot,goals,currencies,vals,targettime); -HASH_ARG(pangea,call,tablehash); +#ifndef WIN32 +/*HASH_ARG(pangea,call,tablehash); HASH_AND_INT(pangea,raise,tablehash,numchips); HASH_AND_INT(pangea,bet,tablehash,numchips); HASH_ARG(pangea,check,tablehash); @@ -209,7 +275,8 @@ INT_AND_ARRAY(pangea,host,minplayers,params); ZERO_ARGS(pangea,lobby); HASH_AND_STRING(pangea,join,tablehash,handle); HASH_AND_INT(pangea,buyin,tablehash,numchips); -HASH_ARG(pangea,start,tablehash); +HASH_ARG(pangea,start,tablehash);*/ +#endif ZERO_ARGS(SuperNET,help); STRING_ARG(SuperNET,utime2utc,utime); @@ -237,7 +304,7 @@ THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey); ZERO_ARGS(SuperNET,keypair); HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype); STRING_ARG(SuperNET,wif2priv,wif); -STRING_ARG(SuperNET,priv2wif,priv); +STRING_AND_INT(SuperNET,priv2wif,priv,wiftype); STRING_ARG(SuperNET,addr2rmd160,address); STRING_ARG(SuperNET,rmd160conv,rmd160); @@ -275,6 +342,8 @@ STRING_ARG(hash,base64_decode,message); STRING_ARG(hash,rmd160_sha256,message); STRING_ARG(hash,sha256_sha256,message); +#ifndef WIN32 + STRING_ARG(hash,sha224,message); STRING_ARG(hash,sha256,message); STRING_ARG(hash,sha384,message); @@ -304,3 +373,7 @@ TWO_STRINGS(hmac,md4,message,passphrase); TWO_STRINGS(hmac,md5,message,passphrase); TWO_STRINGS(hmac,tiger192_3,message,passphrase); TWO_STRINGS(hmac,whirlpool,message,passphrase); + +#endif + +#endif diff --git a/includes/iguana_apideclares2.h b/includes/iguana_apideclares2.h new file mode 100644 index 000000000..952301d89 --- /dev/null +++ b/includes/iguana_apideclares2.h @@ -0,0 +1,31 @@ +#ifdef WIN32 +STRING_ARG(hash, sha224, message); +STRING_ARG(hash, sha256, message); +STRING_ARG(hash, sha384, message); +STRING_ARG(hash, sha512, message); +STRING_ARG(hash, rmd128, message); +STRING_ARG(hash, rmd160, message); +STRING_ARG(hash, rmd256, message); +STRING_ARG(hash, rmd320, message); +STRING_ARG(hash, sha1, message); +STRING_ARG(hash, md2, message); +STRING_ARG(hash, md4, message); +STRING_ARG(hash, md5, message); +STRING_ARG(hash, tiger192_3, message); +STRING_ARG(hash, whirlpool, message); + +TWO_STRINGS(hmac, sha224, message, passphrase); +TWO_STRINGS(hmac, sha256, message, passphrase); +TWO_STRINGS(hmac, sha384, message, passphrase); +TWO_STRINGS(hmac, sha512, message, passphrase); +TWO_STRINGS(hmac, rmd128, message, passphrase); +TWO_STRINGS(hmac, rmd160, message, passphrase); +TWO_STRINGS(hmac, rmd256, message, passphrase); +TWO_STRINGS(hmac, rmd320, message, passphrase); +TWO_STRINGS(hmac, sha1, message, passphrase); +TWO_STRINGS(hmac, md2, message, passphrase); +TWO_STRINGS(hmac, md4, message, passphrase); +TWO_STRINGS(hmac, md5, message, passphrase); +TWO_STRINGS(hmac, tiger192_3, message, passphrase); +TWO_STRINGS(hmac, whirlpool, message, passphrase); +#endif \ No newline at end of file diff --git a/includes/iguana_apidefs.h b/includes/iguana_apidefs.h index 7668e1475..08013ef18 100755 --- a/includes/iguana_apidefs.h +++ b/includes/iguana_apidefs.h @@ -39,6 +39,7 @@ #define IGUANA_CFUNC_HI(agent,name,hash,val) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,int32_t val) #define IGUANA_CFUNC_H(agent,name,hash) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash) #define IGUANA_CFUNC_HS(agent,name,hash,str) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,char *str) +#define IGUANA_CFUNC_HSI(agent,name,hash,str,val) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,char *str,int32_t val) #define IGUANA_CFUNC_HA(agent,name,hash,array) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,cJSON *array) #define IGUANA_CFUNC_HH(agent,name,hash,hash2) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,bits256 hash2) #define IGUANA_CFUNC_HHS(agent,name,hash,hash2,str) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,bits256 hash2,char *str) @@ -65,6 +66,7 @@ #define STRING_AND_TWOINTS IGUANA_CFUNC_SII #define HASH_AND_INT IGUANA_CFUNC_HI #define HASH_AND_STRING IGUANA_CFUNC_HS +#define HASH_AND_STRING_AND_INT IGUANA_CFUNC_HSI #define TWOHASHES_AND_STRING IGUANA_CFUNC_HHS #define HASH_AND_TWOINTS IGUANA_CFUNC_HII #define DOUBLE_ARG IGUANA_CFUNC_D diff --git a/includes/iguana_apiundefs.h b/includes/iguana_apiundefs.h index 7f70ed381..88156175d 100755 --- a/includes/iguana_apiundefs.h +++ b/includes/iguana_apiundefs.h @@ -12,6 +12,7 @@ #undef STRING_AND_INT #undef STRING_AND_TWOINTS #undef HASH_AND_STRING +#undef HASH_AND_STRING_AND_INT #undef HASH_AND_INT #undef HASH_AND_TWOINTS #undef DOUBLE_ARG @@ -48,3 +49,5 @@ #undef IGUANA_ARGS #undef IGUANA_CALLARGS +#undef _IGUANA_APIDEC_H_ + diff --git a/includes/iguana_defines.h b/includes/iguana_defines.h index 7c7e7ed4d..ba7e106cb 100755 --- a/includes/iguana_defines.h +++ b/includes/iguana_defines.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -25,9 +25,9 @@ #ifdef __PNACL__ #define IGUANA_MAXITERATIONS 77 #else -#define IGUANA_MAXITERATIONS 7777 +#define IGUANA_MAXITERATIONS 777 #endif -#define IGUANA_DEFAULTLAG 30 +#define IGUANA_DEFAULTLAG 7 #define IGUANA_MAXHEIGHT (1 << 30) #define IGUANA_MAXCOINS 64 @@ -44,11 +44,12 @@ #define IGUANA_HEADPERCENTAGE 0. #define IGUANA_TAILPERCENTAGE 1.0 #define IGUANA_MAXPENDHDRS 1 -#define IGUANA_MAXPENDINGREQUESTS 8 -#define IGUANA_PENDINGREQUESTS 500 +#define IGUANA_BTCPENDINGREQUESTS 3 +#define IGUANA_PENDINGREQUESTS 64 #define IGUANA_MINPENDBUNDLES 4 #define IGUANA_MAXPENDBUNDLES 64 #define IGUANA_RPCPORT 7778 +#define IGUANA_NOTARYPORT 7776 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) #define IGUANA_MAPHASHTABLES 1 @@ -57,16 +58,14 @@ #define IGUANA_MAXBUNDLES (50000000 / 500) #define IGUANA_MINPEERS 64 -#define IGUANA_LOG2MAXPEERS 11 -#define IGUANA_LOG2PEERFILESIZE 23 + +#define IGUANA_LOG2MAXPEERS 11 // cant exceed 13 bits as ramchain unspents has bitfield #define IGUANA_MAXPEERS (1 << IGUANA_LOG2MAXPEERS) -#define IGUANA_LOG2PACKETSIZE 21 +#ifndef IGUANA_MAXPACKETSIZE #define IGUANA_MAXPACKETSIZE (1 << IGUANA_LOG2PACKETSIZE) -#define IGUANA_PEERFILESIZE (1 << IGUANA_LOG2PEERFILESIZE) -struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpos:IGUANA_LOG2PEERFILESIZE,datalen:IGUANA_LOG2PACKETSIZE,isdir:1; }; - -#define IGUANA_MAXFILEITEMS 8192 +#endif +//#define IGUANA_MAXFILEITEMS 8192 #define IGUANA_RECENTPEER (3600 * 24 * 7) #define IGUANA_PERMTHREAD 0 @@ -112,11 +111,11 @@ extern int32_t IGUANA_NUMHELPERS; #define PNACL_message printf #endif +#ifndef WIN32 #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0x4000 // Do not generate SIGPIPE #endif - -#if defined(_WIN32) || defined(_WIN64) +#else #define MSG_NOSIGNAL 0 #endif @@ -124,7 +123,7 @@ extern int32_t IGUANA_NUMHELPERS; #define CADDR_TIME_VERSION 31402 #define MIN_PROTO_VERSION 209 #define MAX_BLOCK_SIZE 1000000 -#define COINBASE_MATURITY 100 +//#define COINBASE_MATURITY 100 #define _IGUANA_HDRSCOUNT 2000 #define _IGUANA_BLOCKHASHES 500 diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index 61a31b0d1..ceb086e22 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -15,6 +15,10 @@ #ifndef H_IGUANAFUNCS_H #define H_IGUANAFUNCS_H +#define SIGHASH_ALL 1 + +cJSON *SuperNET_helpjson(); + // peers int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); int32_t iguana_peermetrics(struct supernet_info *myinfo,struct iguana_info *coin); @@ -41,22 +45,21 @@ int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endian int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p); int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp); -int32_t iguana_rwblock(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct iguana_msgblock *msg,int32_t maxlen); -int32_t iguana_serialize_block(struct iguana_chain *chain,bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgblock)],struct iguana_block *block); -void iguana_blockconv(uint8_t zcash,uint8_t auxpow,struct iguana_block *dest,struct iguana_msgblock *msg,bits256 hash2,int32_t height); -//void iguana_freetx(struct iguana_msgtx *tx,int32_t n); -int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t datalen,int32_t fromcache); +int32_t iguana_rwblock(struct supernet_info *myinfo,char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct iguana_msgzblock *zmsg,int32_t maxlen); +int32_t iguana_serialize_block(struct supernet_info *myinfo,struct iguana_chain *chain,bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgblock)],struct iguana_block *block); +int32_t iguana_blockconv(uint8_t zcash,uint8_t auxpow,struct iguana_zblock *zdest,struct iguana_msgzblock *zmsg,bits256 hash2,int32_t height); +int32_t iguana_msgparser(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t datalen,int32_t fromcache); // send message int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H); int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *command,uint8_t *data,int32_t datalen); int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); -int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txblock,int32_t *lenp,uint8_t *data,int32_t datalen); +int32_t iguana_gentxarray(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txblock,int32_t *lenp,uint8_t *data,int32_t datalen); int32_t iguana_gethdrs(struct iguana_info *coin,uint8_t *serialized,char *cmd,char *hashstr); int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,bits256 *hashes,int32_t n); -void iguana_blockunconv(uint8_t zcash,uint8_t auxpow,struct iguana_msgblock *msg,struct iguana_block *src,int32_t cleartxn_count); -int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs); -int32_t iguana_validatesigs(struct iguana_info *coin,struct iguana_msgvin *vin); +void iguana_blockunconv(uint8_t zcash,uint8_t auxpow,struct iguana_msgzblock *zmsg,struct iguana_zblock *zsrc,int32_t cleartxn_count); +int32_t iguana_peerblockrequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs); +int32_t iguana_validatesigs(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t datalen); // ramchain int64_t iguana_verifyaccount(struct iguana_info *coin,struct iguana_account *acct,uint32_t pkind); @@ -65,7 +68,7 @@ void iguana_syncramchain(struct iguana_info *coin); //int32_t iguana_validateramchain(struct iguana_info *coin,int64_t *netp,uint64_t *creditsp,uint64_t *debitsp,int32_t height,struct iguana_block *block,int32_t hwmheight,struct iguana_prevdep *lp); int32_t iguana_calcrmd160(struct iguana_info *coin,char *asmstr,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence); uint32_t iguana_updatescript(struct iguana_info *coin,uint32_t blocknum,uint32_t txidind,uint32_t spendind,uint32_t unspentind,uint64_t value,uint8_t *script,int32_t scriptlen,uint32_t sequence); -void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t datalen,int32_t fromcache); +void iguana_gotblockM(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,int32_t fromcache,uint8_t zcash); int32_t iguana_parseblock(struct iguana_info *coin,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx); uint32_t iguana_txidind(struct iguana_info *coin,uint32_t *firstvoutp,uint32_t *firstvinp,bits256 txid); bits256 iguana_txidstr(struct iguana_info *coin,uint32_t *firstvoutp,uint32_t *firstvinp,char *txidstr,uint32_t txidind); @@ -74,12 +77,12 @@ int32_t iguana_updateramchain(struct iguana_info *coin); // blockchain int32_t iguana_needhdrs(struct iguana_info *coin); -struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createflag); +struct iguana_chain *iguana_chainfind(struct supernet_info *myinfo,char *name,cJSON *argjson,int32_t createflag); int32_t iguana_chainextend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *newblock); uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum); // tx -int32_t iguana_rwtx(uint8_t zcash,int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin); +int32_t iguana_rwtx(struct supernet_info *myinfo,uint8_t zcash,int32_t rwflag,struct iguana_info *coin,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin); void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n); void iguana_gotquotesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *quotes,int32_t n); void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgtx *tx,uint8_t *data,int32_t datalen); @@ -120,12 +123,12 @@ int32_t iguana_avail(struct iguana_info *coin,int32_t height,int32_t n); int32_t iguana_updatebundles(struct iguana_info *coin); uint64_t iguana_utxoaddrtablefind(struct iguana_info *coin,int16_t search_hdrsi,uint32_t search_pkind,uint8_t rmd160[20]); void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,char *str,int32_t lag); -void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjson); +void iguana_chaininit(struct supernet_info *myinfo,struct iguana_chain *chain,int32_t hasheaders,cJSON *argjson); void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,int32_t *maxpeersp,int32_t *initialheightp,uint64_t *servicesp,int32_t *maxrequestsp,int32_t *maxbundlesp,cJSON *json); struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json,int32_t virtcoin); // init -struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags); +struct iguana_info *iguana_coinstart(struct supernet_info *myinfo,struct iguana_info *coin,int32_t initialheight,int32_t mapflags); void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin); void iguana_initcoin(struct iguana_info *coin,cJSON *argjson); void iguana_coinloop(void *arg); @@ -135,10 +138,11 @@ double PoW_from_compact(uint32_t nBits,uint8_t unitval); void calc_rmd160(char *hexstr,uint8_t buf[20],uint8_t *msg,int32_t len); void calc_OP_HASH160(char *hexstr,uint8_t hash160[20],char *msg); double dxblend(double *destp,double val,double decay); +double _xblend(float *destp,double val,double decay); // json int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime -char *iguana_JSON(char *,uint16_t port); +char *iguana_JSON(void *_myinfo,void *_coin,char *jsonstr,uint16_t port); char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed); char *mbstr(char *str,double); @@ -187,17 +191,18 @@ int32_t iguana_rpctest(struct iguana_info *coin); extern queue_t helperQ; extern const char *Hardcoded_coins[][3]; void iguana_main(void *arg); +void iguana_exit(struct supernet_info *myinfo,struct iguana_bundle *bp); int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks,int32_t dispflag); struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundleip,char *fname,struct OS_memspace *mem,uint32_t ipbits,bits256 hash2); int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr,char *dirname,char *fname,bits256 hash2,bits256 prevhash2,int32_t numblocks); struct iguana_ramchain *iguana_ramchainset(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_txblock *txdata); -void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA); -long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen); +void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA,struct iguana_peer *addr); +long iguana_ramchain_data(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen,struct iguana_bundle *bp,struct iguana_block *block); int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blockp,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2); struct iguana_block *iguana_bundleblockadd(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock); int32_t iguana_chainextend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *newblock); -int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct iguana_block *block,int32_t dispflag); +int32_t iguana_blockvalidate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *validp,struct iguana_block *block,int32_t dispflag); char *iguana_bundledisp(struct iguana_info *coin,struct iguana_bundle *prevbp,struct iguana_bundle *bp,struct iguana_bundle *nextbp,int32_t m); struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,bits256 hash2); //int32_t iguana_chainheight(struct iguana_info *coin,struct iguana_block *origblock); @@ -237,17 +242,20 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin, struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int32_t forceflag); void iguana_dedicatedglue(void *arg); void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag); +void iguana_peer_meminit(struct iguana_info *coin,struct iguana_peer *addr); void SuperNET_yourip(struct supernet_info *myinfo,char *yourip); void iguana_peerkill(struct iguana_info *coin); int32_t blockhash_sha256(uint8_t *blockhashp,uint8_t *serialized,int32_t len); void iguana_nameset(char name[64],char *symbol,cJSON *json); - +cJSON *iguana_getinfo(struct supernet_info *myinfo,struct iguana_info *coin); +void *basilisk_getinfo(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj); +void basilisk_unspents_process(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr); char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *destNXTaddr); void peggy(); int32_t opreturns_init(uint32_t blocknum,uint32_t blocktimestamp,char *path); struct iguana_info *iguana_coinfind(char *symbol); struct iguana_info *iguana_coinadd(char *symbol,char *nane,cJSON *json,int32_t virtcoin); -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag); +struct iguana_ramchain *iguana_bundleload(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag); int32_t iguana_sendblockreq(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_send_supernet(struct iguana_peer *addr,char *jsonstr,int32_t delay); @@ -256,42 +264,44 @@ struct iguana_waddress *iguana_waccountadd(struct supernet_info *myinfo,struct i struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr,char *redeemScript); struct iguana_waddress *iguana_waddresscalc(struct supernet_info *myinfo,uint8_t pubval,uint8_t wiftype,struct iguana_waddress *addr,bits256 privkey); struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct iguana_waccount *wacct,char *coinaddr); +void dex_init(struct supernet_info *myinfo); char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json); cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly); //int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype); //int32_t btc_pub2rmd(uint8_t rmd160[20],uint8_t pubkey[33]); int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json,int32_t virtcoin); -int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,int32_t height,bits256 hash2,bits256 hash1); -int32_t iguana_jsonQ(); +int32_t iguana_bundleinitmap(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t height,bits256 hash2,bits256 hash1); +int32_t iguana_jsonQ(struct supernet_info *myinfo,struct iguana_info *coin); int32_t is_bitcoinrpc(struct supernet_info *myinfo,char *method,char *remoteaddr); char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr,uint16_t port); cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr); -void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); +void iguana_bundleQ(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); int32_t iguana_bundleiters(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag); void ramcoder_test(void *data,int64_t len); -void iguana_exit(); +void iguana_exit(struct supernet_info *myinfo,struct iguana_bundle *bp); int32_t iguana_pendingaccept(struct iguana_info *coin); -char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr,uint16_t port); +char *iguana_blockingjsonstr(struct supernet_info *myinfo,struct iguana_info *coin,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr,uint16_t port); void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t markflag); cJSON *SuperNET_bits2json(uint8_t *serialized,int32_t datalen); int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis); int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash); int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr); int32_t bitcoin_priv2wif(char *wifstr,bits256 privkey,uint8_t addrtype); -bits256 iguana_chaingenesis(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); +int32_t bitcoin_priv2wiflong(char *wifstr,bits256 privkey,uint8_t addrtype); +bits256 iguana_chaingenesis(struct supernet_info *myinfo,char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr); cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V); -char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid); +char *iguana_txscan(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid); char *iguana_rawtxbytes(struct iguana_info *coin,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys); int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sleepflag); int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvout *msg); -int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg); +int32_t iguana_rwvin(int32_t rwflag,struct iguana_info *coin,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg,int32_t vini); int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys); int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts,int32_t validatesigs); cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid); -cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag); -int32_t iguana_rwblockhdr(int32_t rwflag,uint8_t zcash,uint8_t *serialized,struct iguana_msgblock *msg); +cJSON *iguana_blockjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag); +int32_t iguana_rwblockhdr(int32_t rwflag,uint8_t zcash,uint8_t *serialized,struct iguana_msgzblock *zmsg); //int32_t iguana_sig(uint8_t *sig,int32_t maxsize,uint8_t *data,int32_t datalen,bits256 privkey); //int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,bits256 pubkey); //int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey); @@ -303,34 +313,38 @@ cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits2 void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname); bits256 iguana_genesis(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_chain *chain); -cJSON *bitcoin_txcreate(int32_t isPoS,int64_t locktime,uint32_t txversion); +cJSON *bitcoin_txcreate(char *symbol,int32_t isPoS,int64_t locktime,uint32_t txversion,uint32_t timestamp); cJSON *bitcoin_txoutput(cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis); -cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); +cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys,uint8_t *sigscript,int32_t siglen); int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee); //cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs); int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen); +cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize,bits256 wallethash,char *fname2fa,int32_t fnamesize,bits256 wallet2priv); +int32_t bitcoin_txaddspend(struct iguana_info *coin,cJSON *txobj,char *destaddress,uint64_t satoshis); +char *_setVsigner(struct iguana_info *coin,struct vin_info *V,int32_t ind,char *pubstr,char *wifstr); + char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V); int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); char *issue_startForging(struct supernet_info *myinfo,char *secret); struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *address); -void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson); +void iguana_chainparms(struct supernet_info *myinfo,struct iguana_chain *chain,cJSON *argjson); int32_t iguana_RTpkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,int32_t maxunspents,char *remoteaddr,int32_t includespent); long iguana_spentsfile(struct iguana_info *coin,int32_t n); uint8_t *iguana_rmdarray(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti); -int64_t iguana_RTunspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,char *remoteaddr,int32_t includespent); +uint64_t iguana_RTunspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,char *remoteaddr,int32_t includespent); uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp); void iguana_hhutxo_purge(struct iguana_info *coin); char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi); uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind,struct iguana_ramchain *ramchain); int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen); -void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len,int32_t fromcache); +void iguana_parsebuf(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len,int32_t fromcache); int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,int32_t starti,int32_t numblocks,int32_t convertflag,int32_t iterate); int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct iguana_bundle *bp,int32_t startheight,int32_t endheight,int32_t startemit); -struct iguana_utxoaddr *iguana_utxoaddrfind(int32_t createflag,struct iguana_info *coin,int16_t hdrsi,uint32_t pkind,uint8_t rmd160[20],struct iguana_utxoaddr **prevp); -int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag); +struct iguana_utxoaddr *iguana_utxoaddrfind(int32_t createflag,struct iguana_info *coin,int16_t hdrsi,uint32_t pkind,uint8_t rmd160[20],struct iguana_utxoaddr **prevp,int32_t p2shflag); +int32_t iguana_bundlevalidate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag); void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); struct iguana_bloominds iguana_calcbloom(bits256 hash2); int32_t iguana_bloomfind(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); @@ -342,21 +356,21 @@ int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); -int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag); +int64_t iguana_bundlecalcs(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag); int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t txonly); int32_t iguana_realtime_update(struct supernet_info *myinfo,struct iguana_info *coin); -int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_volatilesmap(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *ramchain); void iguana_volatilespurge(struct iguana_info *coin,struct iguana_ramchain *ramchain); int32_t iguana_volatilesinit(struct supernet_info *myinfo,struct iguana_info *coin); void iguana_initfinal(struct supernet_info *myinfo,struct iguana_info *coin,bits256 lastbundle); -int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2); +int64_t iguana_ramchainopen(struct supernet_info *myinfo,char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2); int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag); void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain); int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int16_t bundlei); -void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei); +void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei,int32_t renameflag); int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_ramchain *mapchain,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,void *ptr,long filesize); void iguana_RTdataset_free(struct iguana_info *coin); -void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_autoextend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp); //void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp); void iguana_coinpurge(struct iguana_info *coin); void tradebot_liquidity_command(struct supernet_info *myinfo,char *targetcoin,bits256 hash,cJSON *vals); @@ -376,15 +390,16 @@ struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p void *iguana_ramchainfile(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block); int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block); int32_t iguana_convert(struct iguana_info *coin,int32_t helperid,struct iguana_bundle *bp,int32_t RTflag,int32_t starti); -int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult); +int32_t iguana_bundleissuemissing(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult); FILE *myfopen(char *fname,char *mode); int32_t myfclose(FILE *fp); +char *iguana_scriptaddress(struct iguana_info *coin,char *coinaddr,uint8_t *script,int32_t scriptlen); int32_t iguana_walkchain(struct iguana_info *coin,int32_t skipflag); struct iguana_block *iguana_fastlink(struct iguana_info *coin,int32_t hwmheight); int32_t iguana_balancenormal(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); int32_t iguana_spendvectorsaves(struct iguana_info *coin); int32_t iguana_convertfinished(struct iguana_info *coin); -int32_t iguana_emitfinished(struct iguana_info *coin,int32_t queueincomplete); +int32_t iguana_emitfinished(struct supernet_info *myinfo,struct iguana_info *coin,int32_t queueincomplete); int32_t iguana_utxofinished(struct iguana_info *coin); int32_t iguana_balancefinished(struct iguana_info *coin); int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramchain); @@ -402,42 +417,50 @@ int32_t iguana_bundleremove(struct iguana_info *coin,int32_t hdrsi,int32_t tmpfi int32_t iguana_voutsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); int32_t iguana_vinsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); bits256 iguana_merkle(bits256 *tree,int32_t txn_count); -int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag); +int32_t iguana_bundleready(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag); int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr); int32_t iguana_validated(struct iguana_info *coin); void iguana_volatilesalloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t copyflag); int32_t iguana_send_ping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr); int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin); uint32_t iguana_fastfindinit(struct iguana_info *coin); -int32_t iguana_unspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool); -int32_t iguana_RTunspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool); +int32_t iguana_outptset(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint *outpt,bits256 txid,int32_t vout,int64_t value,char *spendscriptstr); +int32_t iguana_unspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *spentamountp,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool); +int32_t iguana_RTunspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint *outpt,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool); int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,char *address); int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag); +void revcalc_rmd160_sha256(uint8_t rmd160[20],bits256 revhash); struct iguana_utxo iguana_utxofind(struct iguana_info *coin,struct iguana_outpoint spentpt,int32_t *RTspendflagp,int32_t lockflag); +int32_t iguana_vinifind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *spentfrom,bits256 txid,int32_t vout); +int32_t iguana_scriptsigextract(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *script,int32_t maxsize,bits256 txid,int32_t vini); +void iguana_unspents_markinit(struct supernet_info *myinfo,struct iguana_info *coin); + bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,char *str); -int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,struct iguana_outpoint spentpt,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount); -int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,struct iguana_outpoint spentpt,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount); +int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,struct iguana_outpoint spentpt,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount); int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint8_t *scriptspace,char *asmstr,struct iguana_unspent *u,struct iguana_pkhash *p,int32_t txi); struct iguana_RTaddr *iguana_RTaddrfind(struct iguana_info *coin,uint8_t *rmd160,char *coinaddr); -cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,bits256 txid,int32_t vout,int64_t value,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr); +cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,bits256 txid,int32_t vout,uint64_t value,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr); int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_waccount **wacctp,char *coinaddr); -cJSON *iguana_RTlistunspent(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *argarray,int32_t minconf,int32_t maxconf,char *remoteaddr); +cJSON *iguana_RTlistunspent(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *argarray,int32_t minconf,int32_t maxconf,char *remoteaddr,int32_t includespends); +uint64_t iguana_interest(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout,uint64_t value); void calc_shares(struct supernet_info *myinfo,uint8_t *shares,uint8_t *secret,int32_t size,int32_t width,int32_t M,int32_t N,uint8_t *sharenrs,uint8_t *space,int32_t spacesize); -struct basilisk_spend *basilisk_addspend(struct supernet_info *myinfo,char *symbol,bits256 txid,uint16_t vout,int32_t addflag); -int64_t _RTgettxout(struct iguana_info *coin,int32_t *height,int32_t *scriptlen,uint8_t *script,uint8_t *rmd160,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool); +//struct basilisk_spend *basilisk_addspend(struct supernet_info *myinfo,char *symbol,bits256 txid,uint16_t vout,int32_t addflag); +//void iguana_wallet_Cclear(struct supernet_info *myinfo,char *symbol); +int64_t _RTgettxout(struct iguana_info *coin,struct iguana_RTtxid **ptrp,int32_t *heightp,int32_t *scriptlenp,uint8_t *script,uint8_t *rmd160,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool); int32_t _iguana_RTunspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,struct iguana_outpoint outpt,int64_t value); int32_t basilisk_unspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,struct iguana_outpoint outpt,int64_t value); int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,cJSON *unspents,cJSON *spends,char *coinaddr,int32_t minconf,int32_t firstheight); cJSON *iguana_walletjson(struct supernet_info *myinfo); int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr,struct iguana_waddress *waddr,char *account); int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp); +cJSON *basilisk_balance_valsobj(struct supernet_info *myinfo,struct iguana_info *coin); void basilisk_unspents_update(struct supernet_info *myinfo,struct iguana_info *coin); struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid *tx,struct iguana_block *block,int32_t i); cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr); char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript); char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds); -int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,int32_t sighash,int32_t signtx,int32_t suppress_pubkeys); +int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,uint32_t sighash,int32_t signtx,int32_t suppress_pubkeys); char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys); int64_t iguana_fastfindcreate(struct iguana_info *coin); int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); @@ -445,6 +468,10 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc void iguana_utxoaddrs_purge(struct iguana_info *coin); int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight,uint8_t *rmd160); int32_t iguana_RTunspentslists(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *totalp,struct iguana_outpoint *unspents,int32_t max,uint64_t required,int32_t minconf,cJSON *addresses,char *remoteaddr); +double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk_request *issueR,struct basilisk_request *list,int32_t n); +void iguana_unspents_mark(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins); +int32_t iguana_immediate(struct iguana_info *coin,int32_t immedmillis); +int32_t iguana_fastfindreset(struct iguana_info *coin); int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin); int32_t iguana_txidfastfind(struct iguana_info *coin,int32_t *heightp,bits256 txid,int32_t lasthdrsi); uint8_t iguana_addrtype(struct iguana_info *coin,uint8_t script_type); @@ -452,7 +479,7 @@ struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct i cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *txobj,cJSON *vins); bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey); bits256 bitcoin_randkey(void *ctx); -int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig64,bits256 messagehash2,uint8_t *pubkey); +int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig64,bits256 messagehash2,uint8_t *pubkey,size_t plen); int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t script[IGUANA_MAXSCRIPTSIZE],cJSON *scriptobj,int32_t interpret,int64_t nLockTime,struct vin_info *V); cJSON *iguana_spendasm(struct iguana_info *coin,uint8_t *spendscript,int32_t spendlen); uint64_t iguana_unspentavail(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,int32_t minconf,int32_t maxconf); @@ -475,22 +502,34 @@ char *iguana_signunspents(struct supernet_info *myinfo,struct iguana_info *coin, bits256 iguana_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx); int32_t iguana_inv2packet(uint8_t *serialized,int32_t maxsize,int32_t type,bits256 *hashes,int32_t n); int32_t instantdex_inv2data(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct exchange_info *exchange); +uint32_t basilisk_crcrecv(struct supernet_info *myinfo,int32_t width,uint8_t *verifybuf,int32_t maxlen,int32_t *datalenp,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgbits); struct iguana_bundlereq *instantdex_recvquotes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *encodedhash,int32_t n); +uint32_t basilisk_crcsend(struct supernet_info *myinfo,int32_t width,uint8_t *verifybuf,int32_t maxlen,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t crcs[2]); struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson); int32_t iguana_inv2poll(struct supernet_info *myinfo,struct iguana_info *coin); struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,uint8_t *data,int32_t datalen); void instantdex_FSMinit(); +//void dpow_handler(struct supernet_info *myinfo,struct basilisk_message *msg); +int32_t datachain_opreturnscript(struct iguana_info *coin,uint8_t *script,char *datastr,int32_t datalen); +int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp); +cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,int32_t width); +int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t duration); +cJSON *dpow_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); +void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp); +char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *pubkey33,uint64_t satoshis,int32_t duplicates,int32_t *completedp,bits256 *signedtxidp,int32_t sendflag,cJSON *addresses); int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); void iguana_RTunspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins); -char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint8_t *opreturn,int32_t oplen,int64_t burnamount,char *remoteaddr); +char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint8_t *opreturn,int32_t oplen,int64_t burnamount,char *remoteaddr,struct vin_info *V,int32_t maxmode); int64_t datachain_update(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,uint8_t rmd160[20],int64_t crypto777_payment,uint8_t type,int32_t height,uint64_t hdrsi_unspentind,int64_t burned,uint32_t fileid,uint64_t scriptpos,int32_t scriptlen,bits256 txid,int32_t vout); void datachain_update_spend(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int32_t height,bits256 txid,int32_t vout,uint8_t rmd160[20],int64_t value); cJSON *bitcoin_data2json(struct iguana_info *coin,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys); int32_t iguana_unspentind2txid(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *spentheightp,bits256 *txidp,int32_t *voutp,struct iguana_outpoint outpt); int32_t iguana_RTunspent_check(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt); -char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj); +char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj,struct vin_info *V); +int32_t iguana_markedunspents_find(struct iguana_info *coin,int32_t *firstslotp,bits256 txid,int32_t vout); +void jumblr_opidsupdate(struct supernet_info *myinfo,struct iguana_info *coin); -char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkey,struct vin_info *V); +char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkeys,struct vin_info *V); bits256 scrypt_blockhash(const void *input); bits256 iguana_calcblockhash(char *symbol,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),uint8_t *serialized,int32_t len); struct bitcoin_eventitem *instantdex_event(char *cmdstr,cJSON *argjson,cJSON *newjson,uint8_t *serdata,int32_t serdatalen); @@ -512,6 +551,8 @@ void *iguana_blockzcopyRO(uint8_t zcash,struct iguana_blockRO *dest,int32_t dest void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_block *src); int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block *block); void basilisk_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr); +int32_t bitcoin_secret160verify(uint8_t *script,int32_t n,uint8_t secret160[20]); +int32_t bitcoin_secret256spend(uint8_t *script,int32_t n,bits256 secret); int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]); int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,struct iguana_peer *addr,char *blockstr,bits256 hash2,int32_t height); struct supernet_info *SuperNET_MYINFO(char *passphrase); @@ -519,7 +560,11 @@ bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); struct gecko_chain *category_find(bits256 categoryhash,bits256 subhash); void *category_subscribe(struct supernet_info *myinfo,bits256 category,bits256 keyhash); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); -char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port); +char *SuperNET_JSON(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,uint16_t port); +int64_t iguana_txdetails(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *item,bits256 txid,int32_t vout,int32_t height); +int32_t iguana_txidheight(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid); +int64_t iguana_txidamount(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout); +char *iguana_txidcategory(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr,bits256 txid,int32_t vout); struct supernet_info *SuperNET_accountfind(cJSON *json); cJSON *SuperNET_rosettajson(struct supernet_info *myinfo,bits256 privkey,int32_t showprivs); double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double basevolume,cJSON *argjson); @@ -527,7 +572,7 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr); char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,cJSON *json,char *remoteaddr); char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr); void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256); -int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block); +int32_t iguana_headerget(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block); int32_t iguana_bundlefinalize(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,struct OS_memspace *mem,struct OS_memspace *memB); bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V); int32_t iguana_ROallocsize(struct iguana_info *virt); @@ -547,30 +592,49 @@ struct iguana_peer *iguana_peerfindipbits(struct iguana_info *coin,uint32_t ipbi //int32_t basilisk_relays_send(struct supernet_info *myinfo,struct iguana_peer *addr); int32_t basilisk_hashes_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,char *CMD,bits256 *txids,int32_t num); int32_t iguana_opreturn(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int64_t crypto777_payment,int32_t height,uint64_t hdrsi_unspentind,int64_t payment,uint32_t fileid,uint64_t scriptpos,uint32_t scriptlen); +/* +* because the address passed in a non-portable way we defined uint64_t as parameter to +* allow the pass of 64bit memory address in windows 64 +* @author - fadedreamz@gmail.com +*/ +#if defined(_M_X64) +int32_t iguana_scriptdata(struct iguana_info *coin, uint8_t *scriptspace, uint64_t fileptr[2], char *fname, uint64_t scriptpos, int32_t scriptlen); +#else int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,long fileptr[2],char *fname,uint64_t scriptpos,int32_t scriptlen); -struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *btcd,uint32_t ipbits); +#endif +void basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *notaries,uint32_t ipbits); +void dpow_nanomsginit(struct supernet_info *myinfo,char *ipaddr); int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t rmd160[20]); -int32_t iguana_RTramchaindata(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *TXDATA,struct OS_memspace *HASHMEM,int64_t polarity,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t txn_count); -struct iguana_RTtxid *iguana_RTtxid_create(struct iguana_info *coin,struct iguana_block *block,int64_t polarity,int32_t txi,int32_t txn_count,bits256 txid,int32_t numvouts,int32_t numvins,uint32_t locktime,uint32_t version,uint32_t timestamp,uint8_t *serialized,int32_t txlen); -void iguana_RTspend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vini,bits256 prev_hash,int32_t prev_vout); -void iguana_RTunspent(struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,char *coinaddr,uint8_t *rmd160,int32_t type,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,int64_t value); +int32_t basilisk_requests_poll(struct supernet_info *myinfo); +void dpow_psockloop(void *_ptr); +int32_t smartaddress_add(struct supernet_info *myinfo,bits256 privkey,char *typestr,char *symbol,double maxbid,double minask); +int32_t smartaddress(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,char *coinaddr); +int32_t smartaddress_pubkey(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,bits256 pubkey); +int32_t smartaddress_pubkey33(struct supernet_info *myinfo,char *typestr,double *bidaskp,bits256 *privkeyp,char *symbol,uint8_t *pubkey33); void iguana_RTreset(struct iguana_info *coin); void iguana_RTpurge(struct iguana_info *coin,int32_t lastheight); void iguana_RTnewblock(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block); +cJSON *iguana_listunspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,char *remoteaddr); void *iguana_RTrawdata(struct iguana_info *coin,bits256 hash2,uint8_t *data,int32_t *recvlenp,int32_t *numtxp,int32_t checkonly); int32_t iguana_bundlehash2_check(struct iguana_info *coin,bits256 hash2); void iguana_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_bundle *bp); -void iguana_update_balances(struct iguana_info *coin); +void iguana_update_balances(struct supernet_info *myinfo,struct iguana_info *coin); void iguana_RTspendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp); int64_t iguana_RTbalance(struct iguana_info *coin,char *coinaddr); double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *base,char *rel,double basevolume); -int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]); +int32_t bitcoin_secret160verify(uint8_t *script,int32_t n,uint8_t secret160[20]); int64_t iguana_lockval(int32_t finalized,int64_t locktime); -int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_pkhash **Ptrp,int64_t *supplyp,int32_t *numacctsp,int32_t *nonzp,int32_t *errsp,int32_t lastheight); -int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *refrmd160,struct iguana_pkhash *refP,int64_t *weights,int32_t numweights,bits256 *sortbuf); +uint64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_pkhash **Ptrp,uint64_t *supplyp,int32_t *numacctsp,int32_t *nonzp,int32_t *errsp,int32_t lastheight); +int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *refrmd160,struct iguana_pkhash *refP,uint64_t *weights,int32_t numweights,bits256 *sortbuf); bits256 mpz_div64(bits256 hash,uint64_t divval); void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coin); +void jumblr_iteration(struct supernet_info *myinfo,struct iguana_info *coin,int32_t selector,int32_t modval); +void smartaddress_update(struct supernet_info *myinfo,int32_t selector); +bits256 jumblr_privkey(struct supernet_info *myinfo,char *BTCaddr,uint8_t pubtype,char *KMDaddr,char *prefix); +char *jumblr_importprivkey(struct supernet_info *myinfo,struct iguana_info *coin,char *wifstr); +int64_t iguana_esttxfee(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,char *signedtx,int32_t numvins); +int64_t jumblr_balance(struct supernet_info *myinfo,struct iguana_info *coin,char *addr); // ------------------------------------------------------[ Preparation ]---- // Initialise a gfshare context for producing shares @@ -594,6 +658,11 @@ void gfshare_ctx_decextract(uint8_t *logs,uint8_t *exps,gfshare_ctx * /* ctx */, void libgfshare_init(struct supernet_info *myinfo,uint8_t _logs[256],uint8_t _exps[510]); int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n); void iguana_schnorr(struct supernet_info *myinfo); +void iguana_fixsecp(struct supernet_info *myinfo); +int32_t bitcoin_timelockspend(uint8_t *script,int32_t n,uint8_t rmd160[20],uint32_t timestamp); + +char *iguana_calcutxorawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t *satoshis,int32_t numoutputs,char *changeaddr,int64_t txfee,cJSON *utxos,char *remoteaddr,struct vin_info *V,int32_t maxmode); +uint64_t _iguana_interest(uint32_t now,int32_t height,uint32_t txlocktime,uint64_t value); #include "../includes/iguana_api.h" diff --git a/includes/iguana_globals.h b/includes/iguana_globals.h index 8ff140ae9..31a91a073 100755 --- a/includes/iguana_globals.h +++ b/includes/iguana_globals.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -54,19 +54,19 @@ int32_t IGUANA_NUMHELPERS = 1; // ALL globals must be here! -CONDEXTERN struct basilisk_relay RELAYS[BASILISK_MAXRELAYS]; -CONDEXTERN int32_t NUMRELAYS,RELAYID; +//CONDEXTERN struct basilisk_relay RELAYS[BASILISK_MAXRELAYS]; +//CONDEXTERN int32_t NUMRELAYS,RELAYID; CONDEXTERN char *COMMANDLINE_ARGFILE; CONDEXTERN char *Iguana_validcommands[]; CONDEXTERN int32_t Showmode,Autofold,PANGEA_MAXTHREADS,QUEUEITEMS; CONDEXTERN struct gecko_chain *Categories; -CONDEXTERN struct iguana_info *Allcoins; +//CONDEXTERN struct iguana_info *Allcoins; CONDEXTERN char Userhome[512]; -CONDEXTERN int32_t USE_JAY,FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel,IGUANA_BIGENDIAN; +CONDEXTERN int32_t FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel,IGUANA_BIGENDIAN; CONDEXTERN uint32_t prices777_NXTBLOCK; -CONDEXTERN queue_t helperQ,jsonQ,finishedQ,bundlesQ,emitQ; +CONDEXTERN queue_t helperQ,JSON_Q,FINISHED_Q,bundlesQ,emitQ; CONDEXTERN struct supernet_info MYINFO,**MYINFOS; CONDEXTERN int32_t MAIN_initflag,MAX_DEPTH; CONDEXTERN int32_t HDRnet,netBLOCKS; @@ -83,7 +83,7 @@ CONDEXTERN int32_t IGUANA_NUMHELPERS; #define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9" #define CRYPTO777_RMD160STR "f1dce4182fce875748c4986b240ff7d7bc3fffb0" #define CRYPTO777_BTCADDR "1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg" -#define CRYPTO777_BTCDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA" +#define CRYPTO777_KMDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA" CONDEXTERN uint8_t CRYPTO777_RMD160[20],CRYPTO777_PUBSECP33[33]; diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index 1223095e8..e9fd52383 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,6 +16,12 @@ #ifndef H_IGUANASTRUCTS_H #define H_IGUANASTRUCTS_H +#ifdef WIN32 +#define PACKEDSTRUCT +#else +#define PACKEDSTRUCT __attribute__((packed)) +#endif + struct iguana_thread { struct queueitem DL; @@ -34,7 +40,7 @@ struct iguana_peermsgrequest { struct queueitem DL; struct iguana_peer *addr; bi struct iguana_chain { //const int32_t chain_id; - char name[32],symbol[8],messagemagic[64]; + char name[32],symbol[16],messagemagic[64]; uint8_t pubtype,p2shtype,wiftype,netmagic[4]; char *genesis_hash,*genesis_hex; // hex string uint16_t portp2p,rpcport; @@ -49,11 +55,11 @@ struct iguana_chain char use_addmultisig,do_opreturn; int32_t estblocktime,protover; bits256 genesishash2,PoWtarget,PoStargets[16]; int32_t numPoStargets,PoSheights[16]; - uint8_t zcash,auxpow,havecltv,alertpubkey[65]; + uint8_t zcash,fixit,auxpow,debug,havecltv,alertpubkey[65]; uint16_t targetspacing,targettimespan; uint32_t nBits,normal_txversion,locktime_txversion; }; -struct iguana_msgaddress { uint32_t nTime; uint64_t nServices; uint8_t ip[16]; uint16_t port; } __attribute__((packed)); +struct iguana_msgaddress { uint32_t nTime; uint64_t nServices; uint8_t ip[16]; uint16_t port; }PACKEDSTRUCT; struct iguana_msgversion { @@ -65,7 +71,7 @@ struct iguana_msgversion char strSubVer[80]; uint32_t nStartingHeight; uint8_t relayflag; -} __attribute__((packed)); +}PACKEDSTRUCT; struct iguana_msgalert // warning, many varints/variable length fields, struct is 1:1 { @@ -91,43 +97,67 @@ struct iguana_VPNversion char strSubVer[80]; uint32_t nStartingHeight; uint32_t iVer,v_Network_id; uint16_t wPort; uint8_t bIsGui; uint16_t wCtPort,wPrPort; -} __attribute__((packed)); +} PACKEDSTRUCT; struct iguana_msgblockhdr { uint32_t version; bits256 prev_block,merkle_root; uint32_t timestamp,bits,nonce; -} __attribute__((packed)); +} PACKEDSTRUCT; -#define ZKSNARK_PROOF_SIZE 584 -#define ZCASH_SOLUTION_ELEMENTS 32 +#define ZKSNARK_PROOF_SIZE 296 +#define ZCASH_SOLUTION_ELEMENTS 1344 -struct iguana_msgblockhdr_zcash +struct iguana_msgzblockhdr +{ + uint32_t version; + bits256 prev_block,merkle_root,reserved; + uint32_t timestamp,bits; + bits256 bignonce; + uint8_t var_numelements[3]; + uint8_t solution[ZCASH_SOLUTION_ELEMENTS]; +} PACKEDSTRUCT; + +/*int32_t nVersion; +uint256 hashPrevBlock; +uint256 hashMerkleRoot; +uint256 hashReserved; +uint32_t nTime; +uint32_t nBits; +uint256 nNonce; +std::vector nSolution;*/ + +/*struct iguana_msgblockhdr_zcash { bits256 bignonce; uint8_t numelements; uint32_t solution[ZCASH_SOLUTION_ELEMENTS]; //bits256 reserved; // only here if auxpow is set -} __attribute__((packed)); +}PACKEDSTRUCT;*/ struct iguana_msgmerkle { uint32_t branch_length; bits256 branch_hash[4096]; uint32_t branch_side_mask; -} __attribute__((packed)); +}; //PACKEDSTRUCT; struct iguana_msgblock { struct iguana_msgblockhdr H; // double hashed for blockhash - struct iguana_msgblockhdr_zcash zH; uint32_t txn_count; -} __attribute__((packed)); +} PACKEDSTRUCT; + +struct iguana_msgzblock +{ + struct iguana_msgzblockhdr zH; // double hashed for blockhash + uint32_t txn_count; +} PACKEDSTRUCT; -struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; } __attribute__((packed)); +struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; }; //PACKEDSTRUCT; -struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; } __attribute__((packed)); +struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; //PACKEDSTRUCT; struct iguana_msgtx { @@ -138,24 +168,24 @@ struct iguana_msgtx int32_t allocsize,timestamp,numinputs,numoutputs; int64_t inputsum,outputsum,txfee; uint8_t *serialized; -} __attribute__((packed)); +};// PACKEDSTRUCT; struct iguana_msgjoinsplit { uint64_t vpub_old,vpub_new; bits256 anchor,nullifiers[2],commitments[2],ephemeralkey; - uint8_t ciphertexts[2][217]; bits256 randomseed,vmacs[2]; - uint8_t zkproof[ZKSNARK_PROOF_SIZE-1]; -} __attribute__((packed)); + uint8_t zkproof[ZKSNARK_PROOF_SIZE]; + uint8_t ciphertexts[2][601]; +}PACKEDSTRUCT; struct iguana_packet { struct queueitem DL; struct iguana_peer *addr; struct tai embargo; int32_t datalen,getdatablock; uint8_t serialized[]; }; struct msgcounts { uint32_t version,verack,getaddr,addr,inv,getdata,notfound,getblocks,getheaders,headers,tx,block,mempool,ping,pong,reject,filterload,filteradd,filterclear,merkleblock,alert; }; -struct iguana_fileitem { bits256 hash2; struct iguana_txdatabits txdatabits; }; +//struct iguana_fileitem { bits256 hash2; struct iguana_txdatabits txdatabits; }; -struct iguana_kvitem { UT_hash_handle hh; uint8_t keyvalue[]; };// __attribute__((packed)); +struct iguana_kvitem { UT_hash_handle hh; uint8_t keyvalue[]; }; struct iguana_iAddr { @@ -173,19 +203,19 @@ struct iguana_blockRO uint32_t timestamp,nonce,bits,version; uint32_t firsttxidind,firstvin,firstvout,firstpkind,firstexternalind,recvlen:24,tbd:8; uint16_t txn_count,numvouts,numvins,allocsize; -} __attribute__((packed)); +}PACKEDSTRUCT; -struct iguana_zcashRO { bits256 bignonce; uint32_t solution[ZCASH_SOLUTION_ELEMENTS]; } __attribute__((packed)); +struct iguana_zcashRO { bits256 bignonce; uint32_t numelements; uint8_t solution[ZCASH_SOLUTION_ELEMENTS]; } PACKEDSTRUCT; struct iguana_zblockRO { struct iguana_blockRO RO; struct iguana_zcashRO zRO; -} __attribute__((packed)); +} PACKEDSTRUCT; #define iguana_blockfields double PoW; \ -int32_t height,fpos; uint32_t fpipbits,issued,lag:19,protected:1,peerid:12; \ -uint16_t hdrsi:15,mainchain:1,bundlei:11,valid:1,queued:1,txvalid:1,newtx:1,processed:1; \ +int32_t height,fpos; uint32_t fpipbits,issued,lag:17,sigsvalid:1,protected:1,peerid:12,processed:1; \ +uint16_t hdrsi:15,mainchain:1; int16_t bundlei:12,valid:1,queued:1,txvalid:1,newtx:1; \ UT_hash_handle hh; struct iguana_bundlereq *req; \ struct iguana_blockRO RO @@ -193,13 +223,13 @@ struct iguana_block { iguana_blockfields; struct iguana_zcashRO zRO[]; -} __attribute__((packed)); +} ; struct iguana_zblock // mu { - iguana_blockfields; - struct iguana_zcashRO zRO; -} __attribute__((packed)); + iguana_blockfields; // this is to minimize code needed to support both types + struct iguana_zcashRO zRO; // if zRO is changed, the RO part must also be updated +} ; #define IGUANA_LHASH_BLOCKS 0 #define IGUANA_LHASH_TXIDS 1 // @@ -218,13 +248,13 @@ struct iguana_counts uint32_t firsttxidind,firstunspentind,firstspendind,firstpkind; uint64_t credits,debits; struct iguana_block block; -} __attribute__((packed)); +} PACKEDSTRUCT; struct iguana_blocks { - char coin[8]; + char coin[16]; struct iguanakv *db; - struct iguana_block *hash; //struct iguana_blockRO *RO; int32_t maxbits; + struct iguana_block *hash; int32_t maxblocks,initblocks,hashblocks,pending,issuedblocks,recvblocks,emitblocks,parsedblocks,dirty; struct iguana_zblock hwmchain,prev,prev2; }; @@ -233,34 +263,34 @@ struct iguana_ledger { struct iguana_counts snapshot; //struct iguana_account accounts[]; -} __attribute__((packed)); +} PACKEDSTRUCT; // ramchain temp file structures -struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,fileid; uint8_t rmd160[20]; } __attribute__((packed)); -struct iguana_spend256 { bits256 prevhash2; uint64_t scriptpos:48,vinscriptlen:16; uint32_t sequenceid; int16_t prevout; uint16_t spendind,fileid; } __attribute__((packed)); +struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,fileid; uint8_t rmd160[20]; }PACKEDSTRUCT; +struct iguana_spend256 { bits256 prevhash2; uint64_t scriptpos:48,vinscriptlen:16; uint32_t sequenceid; int16_t prevout; uint16_t spendind,fileid; }PACKEDSTRUCT; // permanent readonly structs -struct iguana_txid { bits256 txid; uint64_t txidind:29,firstvout:28,firstvin:28,bundlei:11,locktime:32,version:32,timestamp:32,extraoffset:32; uint16_t numvouts,numvins; } __attribute__((packed)); +struct iguana_txid { bits256 txid; uint64_t txidind:29,firstvout:28,firstvin:28,bundlei:11,locktime:32,version:32,timestamp:32,extraoffset:32; uint16_t numvouts,numvins; }PACKEDSTRUCT; -struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos; uint16_t scriptlen,hdrsi; uint16_t fileid:11,type:5; int16_t vout; } __attribute__((packed)); +struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos,scriptlen:13,fileid:14,type:5; uint16_t hdrsi; int16_t vout; } PACKEDSTRUCT; -struct iguana_spend { uint64_t scriptpos:48,scriptlen:16; uint32_t spendtxidind,sequenceid; int16_t prevout; uint16_t fileid:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 +struct iguana_spend { uint64_t scriptpos:48,scriptlen:16; uint32_t spendtxidind,sequenceid; int16_t prevout; uint16_t fileid:14,external:1,tbd:1; }PACKEDSTRUCT; // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 -struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((packed)); //firstunspentind,pubkeyoffset +struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; }PACKEDSTRUCT; //firstunspentind,pubkeyoffset // dynamic -struct iguana_account { int64_t total; uint32_t lastunspentind; } __attribute__((packed)); -struct iguana_utxo { uint32_t fromheight:31,lockedflag:1,prevunspentind:31,spentflag:1,spendind; } __attribute__((packed)); +struct iguana_account { int64_t total; uint32_t lastunspentind; }PACKEDSTRUCT; +struct iguana_utxo { uint32_t fromheight:31,lockedflag:1,prevunspentind:31,spentflag:1,spendind; }PACKEDSTRUCT; #ifdef DEPRECATED_HHUTXO -struct iguana_hhaccount { UT_hash_handle hh; uint64_t pval; struct iguana_account a; } __attribute__((packed)); +struct iguana_hhaccount { UT_hash_handle hh; uint64_t pval; struct iguana_account a; }PACKEDSTRUCT; #endif -struct iguana_hhutxo { UT_hash_handle hh; uint64_t uval; struct iguana_utxo u; } __attribute__((packed)); -struct iguana_utxoaddr { UT_hash_handle hh; int64_t histbalance; uint32_t pkind:31,searchedhist:1; uint16_t hdrsi; uint8_t rmd160[20]; } __attribute__((packed)); +struct iguana_hhutxo { UT_hash_handle hh; uint64_t uval; struct iguana_utxo u; }; +struct iguana_utxoaddr { UT_hash_handle hh; uint64_t histbalance; uint32_t pkind:30,p2sh:1,searchedhist:1; uint16_t hdrsi; uint8_t rmd160[20]; }; // GLOBAL one zero to non-zero write (unless reorg) -struct iguana_spendvector { uint64_t value; uint32_t pkind,unspentind; int32_t fromheight; uint16_t hdrsi:15,tmpflag:1; } __attribute__((packed)); // unspentind -//struct iguana_pkextra { uint32_t firstspendind; } __attribute__((packed)); // pkind +struct iguana_spendvector { uint64_t value; uint32_t pkind,unspentind; int32_t fromheight; uint16_t hdrsi:15,tmpflag:1; }PACKEDSTRUCT; // unspentind +//struct iguana_pkextra { uint32_t firstspendind; } PACKEDSTRUCT; // pkind struct iguana_txblock { @@ -271,7 +301,17 @@ struct iguana_txblock struct iguana_zblock zblock; }; +#if defined(_M_X64) +/* +* calculate the address in a portable manner +* in all platform sizeof(char) / sizeof(uchar) == 1 +* @author - fadedreamz@gmail.com +*/ +#define RAMCHAIN_PTR(rdata,offset) ((void *)((unsigned char *)rdata + rdata->offset)) +#else #define RAMCHAIN_PTR(rdata,offset) ((void *)(long)((long)(rdata) + (long)(rdata)->offset)) +#endif + struct iguana_ramchaindata { bits256 sha256; @@ -311,7 +351,7 @@ struct iguana_peer struct iguana_msgaddress A; char ipaddr[64],lastcommand[16],coinname[64],symbol[64]; uint64_t pingnonce,totalsent,totalrecv,ipbits; double pingtime,sendmillis,pingsum,getdatamillis; - uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer,protover; + uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer,protover,numrecverrs; int32_t supernet,basilisk,dead,addrind,usock,lastheight,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid,dirty[2],laggard,headerserror,lastsent,isrelay; double recvblocks,recvtotal; int64_t allocated,freed; @@ -319,7 +359,7 @@ struct iguana_peer struct msgcounts msgcounts; struct OS_memspace RAWMEM,TXDATA,HASHMEM; struct iguana_ramchain ramchain; - struct iguana_fileitem *filehash2; int32_t numfilehash2,maxfilehash2; + //struct iguana_fileitem *filehash2; int32_t numfilehash2,maxfilehash2; FILE *voutsfp,*vinsfp; uint8_t *blockspace;//[IGUANA_MAXPACKETSIZE + 8192]; #ifdef IGUANA_PEERALLOC @@ -344,24 +384,24 @@ struct iguana_bundle { struct queueitem DL; struct iguana_info *coin; struct iguana_bundle *nextbp; struct iguana_bloom16 bloom; int64_t totaldurations,duplicatedurations; int32_t durationscount,duplicatescount; - uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime,lastprefetch,lastRT,missingstime,unsticktime,converted; + uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime,lastprefetch,lastRT,missingstime,unsticktime,converted,utxofinish; int32_t numhashes,numrecv,numsaved,numcached,generrs,currentflag,origmissings,numissued,Xvalid; int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec,isRT; double avetime,threshold,metric; uint64_t datasize,estsize; struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; uint8_t *speculativecache[IGUANA_MAXBUNDLESIZE],haveblock[IGUANA_MAXBUNDLESIZE/3+1]; - uint32_t issued[IGUANA_MAXBUNDLESIZE]; + uint32_t issued[IGUANA_MAXBUNDLESIZE],firsttxidinds[IGUANA_MAXBUNDLESIZE]; bits256 prevbundlehash2,hashes[IGUANA_MAXBUNDLESIZE+1],nextbundlehash2,allhash,*speculative,validatehash; struct iguana_ramchain ramchain; uint8_t red,green,blue; struct iguana_spendvector *tmpspends; int32_t numtmpspends; - int64_t *weights,supply; int32_t numweights; + uint64_t *weights,supply; int32_t numweights; }; struct iguana_bundlereq { struct queueitem DL; struct iguana_info *coin; int32_t type; struct iguana_peer *addr; struct iguana_zblock *blocks; bits256 *hashes,txid; - struct iguana_txdatabits txdatabits; + //struct iguana_txdatabits txdatabits; struct iguana_msghdr H; int32_t allocsize,datalen,n,recvlen,numtx; uint32_t ipbits; struct iguana_zblock zblock; @@ -374,7 +414,7 @@ struct basilisk_spend { bits256 txid,spentfrom; uint64_t relaymask,value; uint32 struct basilisk_unspent { bits256 txid; uint64_t value,relaymask; uint32_t unspentind,timestamp; int32_t RTheight,height,spentheight; int16_t status,hdrsi,vout,spendlen; char symbol[16]; uint8_t script[256]; }; -struct iguana_waddress { UT_hash_handle hh; struct basilisk_unspent *unspents; uint64_t balance; uint32_t maxunspents,numunspents; uint16_t scriptlen; uint8_t rmd160[20],pubkey[33],wiftype,addrtype; bits256 privkey; char symbol[8],coinaddr[36],wifstr[54]; uint8_t redeemScript[]; }; +struct iguana_waddress { UT_hash_handle hh; uint64_t balance; uint16_t scriptlen; uint8_t rmd160[20],pubkey[33],wiftype,addrtype; bits256 privkey; char symbol[16],coinaddr[36],wifstr[54]; uint8_t redeemScript[]; }; struct iguana_waccount { UT_hash_handle hh; struct iguana_waddress *waddr,*current; char account[]; }; struct iguana_wallet { UT_hash_handle hh; struct iguana_waccount *wacct; }; @@ -383,12 +423,6 @@ struct hhbits256 { UT_hash_handle hh; bits256 txid; int32_t height; uint16_t fir struct iguana_monitorinfo { bits256 txid; int32_t numreported; uint8_t peerbits[IGUANA_MAXPEERS >> 3]; }; -struct iguana_RTspend -{ - bits256 prev_hash; int16_t prev_vout,scriptlen; - uint8_t vinscript[]; -}; - struct iguana_RTunspent { uint8_t rmd160[20]; @@ -402,6 +436,14 @@ struct iguana_RTunspent uint8_t script[]; }; +struct iguana_RTspend +{ + bits256 prev_hash; + struct iguana_RTunspent *bundle_unspent; + int16_t prev_vout,scriptlen; + uint8_t vinscript[]; +}; + struct iguana_RTaddr { UT_hash_handle hh; @@ -422,38 +464,62 @@ struct iguana_RTtxid struct iguana_RTspend *spends[]; }; +struct hashstr_item { UT_hash_handle hh; char address[40]; }; + +struct jumblr_pending { bits256 splittxid,txid; int32_t vout,ind; }; + +struct DEXcoin_info +{ + bits256 deposit_privkey,jumblr_privkey; + struct iguana_info *coin; + double btcprice,BTC2KMD,kmdprice,USD_average,DEXpending,maxbid,minask,avail,jumblravail; + uint32_t lasttime,counter; int32_t numpending; + char CMCname[32],symbol[16],depositaddr[64],KMDdepositaddr[64],KMDjumblraddr[64],jumblraddr[64]; + struct jumblr_pending *pending; +}; + struct iguana_info { UT_hash_handle hh; - char name[64],symbol[64],protocol,statusstr[512],scriptsfname[2][512]; + char CMCname[64],name[64],symbol[64],protocol,statusstr[512],scriptsfname[2][512]; struct iguana_peers *peers; struct iguana_peer internaladdr; //basilisk_func basilisk_rawtx,basilisk_balances,basilisk_value; //basilisk_metricfunc basilisk_rawtxmetric,basilisk_balancesmetric,basilisk_valuemetric; +#if defined(_M_X64) + /* + * because we have no choice but to pass the value as parameters + * we need 64bit to hold 64bit memory address, thus changing + * to uint64_t instead of long in win x64 + * @author - fadedreamz@gmail.com + */ + uint64_t vinptrs[IGUANA_MAXPEERS + 1][2], voutptrs[IGUANA_MAXPEERS + 1][2]; +#else long vinptrs[IGUANA_MAXPEERS+1][2],voutptrs[IGUANA_MAXPEERS+1][2]; +#endif uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100]; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles; int32_t MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,numemit,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,FULLNODE,VALIDATENODE,origbalanceswritten,balanceswritten,lastRTheight,RTdatabad; bits256 balancehash,allbundles; uint32_t lastsync,parsetime,numiAddrs,lastpossible,bundlescount,savedblocks,backlog,spendvectorsaved,laststats,lastinv2,symbolcrc,spendvalidated; char VALIDATEDIR[512]; - int32_t longestchain,badlongestchain,longestchain_strange,RTramchain_busy,emitbusy,stuckiters,virtualchain,RTheight; + int32_t longestchain,badlongestchain,longestchain_strange,RTramchain_busy,emitbusy,stuckiters,virtualchain,RTheight,RTreset_needed; struct tai starttime; double startmillis; struct iguana_chain *chain; struct iguana_iAddr *iAddrs; void *ctx; struct iguana_bitmap *screen; struct OS_memspace TXMEM,MEM,MEMB[IGUANA_MAXBUNDLESIZE]; - queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,cacheQ,recvQ,msgrequestQ; + queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,cacheQ,recvQ,msgrequestQ,jsonQ,finishedQ; double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; portable_mutex_t peers_mutex,blocks_mutex,special_mutex,RTmutex,allcoins_mutex; char changeaddr[64]; struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending; struct OS_memspace RTrawmem,RTmem,RThashmem; // struct iguana_ramchain RTramchain; bits256 RThash1; - int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified,blockdepth; - uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis,firstRTgenesis,RTstarti,idletime,stucktime,stuckmonitor,maxstuck,lastreqtime,RThdrstime,nextchecked,lastcheckpoint; + int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified,blockdepth,matchedfiles; + uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis,firstRTgenesis,RTstarti,idletime,stucktime,stuckmonitor,maxstuck,lastreqtime,RThdrstime,nextchecked,lastcheckpoint,sigserrs,sigsvalidated,coinid; double bandwidth,maxbandwidth,backstopmillis; bits256 backstophash2; int64_t spaceused; - int32_t disableUTXO,initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,firstRTheight,polltimeout,numreqtxids,allhashes,balanceflush,basilisk_busy; bits256 reqtxids[64]; + int32_t disableUTXO,initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,firstRTheight,maxRTheight,polltimeout,numreqtxids,allhashes,balanceflush,basilisk_busy,almostRT,busy_processing; bits256 reqtxids[64]; void *launched,*started,*rpcloop; uint64_t bloomsearches,bloomhits,bloomfalse,collisions,txfee_perkb,txfee; uint8_t *blockspace; int32_t blockspacesize; struct OS_memspace blockMEM,RTHASHMEM; @@ -465,6 +531,7 @@ struct iguana_info char lastdispstr[2048]; double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num; struct iguana_monitorinfo monitoring[256]; + int32_t notarychain,didaddresses; struct datachain_info dPoW; struct iguana_zblock newblock; char *newblockstr; int32_t relay_RTheights[BASILISK_MAXRELAYS]; @@ -474,8 +541,16 @@ struct iguana_info uint64_t histbalance,RTcredits,RTdebits; void *utxoaddrfileptr; long utxoaddrfilesize; uint32_t utxoaddrlastcount,*utxoaddroffsets,lastunspentsupdate; uint8_t *utxoaddrtable; bits256 utxoaddrhash; + FILE *utxofp; + bits256 markedunspents[1024]; + uint64_t estimatedfee; + char seedipaddr[64]; + uint32_t lastbesthashtime; bits256 lastbesthash; int32_t lastbestheight; + struct DEXcoin_info DEXinfo; struct iguana_block *RTblocks[65536]; uint8_t *RTrawdata[65536]; int32_t RTrecvlens[65536],RTnumtx[65536]; struct iguana_RTtxid *RTdataset; struct iguana_RTaddr *RTaddrs; + struct hashstr_item *alladdresses; + struct kmd_transactionhh *kmd_transactions; struct kmd_addresshh *kmd_addresses; portable_mutex_t kmdmutex; FILE *kmd_txidfp,*kmd_spendfp; int32_t kmd_didinit,kmd_height,DEXEXPLORER; uint32_t kmd_lasttime; }; struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; @@ -483,7 +558,7 @@ struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],r struct vin_info { struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; - int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys; + int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys,ignore_cltverr; uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE],userdata[IGUANA_MAXSCRIPTSIZE]; }; @@ -502,7 +577,7 @@ struct bitcoin_spend struct bitcoin_unspent inputs[]; }; -struct iguana_outpoint { void *ptr; int64_t value; uint32_t unspentind:31,isptr:1; int16_t hdrsi; }; +struct iguana_outpoint { void *ptr; bits256 txid; int64_t value; uint32_t unspentind; int16_t hdrsi,vout,spendlen:15,isptr:1; uint8_t spendscript[512]; }; struct exchange_quote { uint64_t satoshis,orderid,offerNXT,exchangebits; double price,volume; uint32_t timestamp,val; }; @@ -512,17 +587,26 @@ struct _gfshare_ctx uint8_t sharenrs[255],buffer[]; }; +struct basilisk_p2pitem +{ + struct queueitem DL; + struct iguana_info *coin; struct iguana_peer *addr; + uint32_t ipbits,datalen; char type[4]; + uint8_t data[]; +}; + struct basilisk_request { uint32_t requestid,timestamp,quoteid,quotetime; // 0 to 15 uint64_t srcamount,minamount; // 16 to 31 - bits256 hash; // 32 to 63 + bits256 srchash; // 32 to 63 bits256 desthash; char src[8],dest[8]; //char volatile_start,message[43]; uint64_t destamount; - uint32_t relaybits; -} __attribute__((packed)); + int32_t optionhours,profitmargin;//,DEXselector,extraspace; +} PACKEDSTRUCT; + struct basilisk_relaystatus { uint8_t pingdelay; diff --git a/includes/iguana_types.h b/includes/iguana_types.h index 7b953cea1..4a1b4647e 100755 --- a/includes/iguana_types.h +++ b/includes/iguana_types.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * + * Copyright © 2014-2017 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/m_onetime b/m_onetime index b41d17856..1bff9d8d4 100755 --- a/m_onetime +++ b/m_onetime @@ -20,5 +20,5 @@ cd crypto777 ./$1 cd .. cd iguana -./m_unix +./$1 ../agents/iguana diff --git a/m_osx_release b/m_osx_release new file mode 100755 index 000000000..e3bce6893 --- /dev/null +++ b/m_osx_release @@ -0,0 +1,2 @@ +git pull +cd iguana; ./m_osx_release; cd .. diff --git a/makeRelease.sh b/makeRelease.sh new file mode 100644 index 000000000..89f5c8a88 --- /dev/null +++ b/makeRelease.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +binaries=("iguana") + +for binary in "${binaries[@]}"; +do + # find the dylibs to copy for komodod + DYLIBS=`otool -L agents/$binary | grep "/usr/local" | awk -F' ' '{ print $1 }'` + echo "copying $DYLIBS to agents" + # copy the dylibs to the agents-dir + for dylib in $DYLIBS; do cp -rf $dylib agents/; done + + # modify komodod to point to dylibs + echo "modifying $binary to use local libraries" + for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` agents/$binary; done; + chmod +x agents/$binary +done diff --git a/marketmaker.sln b/marketmaker.sln new file mode 100644 index 000000000..98097205c --- /dev/null +++ b/marketmaker.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marketmaker", "marketmaker.vcxproj", "{BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}.Debug|x64.ActiveCfg = Debug|x64 + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}.Debug|x64.Build.0 = Debug|x64 + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}.Debug|x86.ActiveCfg = Debug|Win32 + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}.Debug|x86.Build.0 = Debug|Win32 + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}.Release|x64.ActiveCfg = Release|x64 + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}.Release|x64.Build.0 = Release|x64 + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}.Release|x86.ActiveCfg = Release|Win32 + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/marketmaker.vcxproj b/marketmaker.vcxproj new file mode 100644 index 000000000..fbe023dc8 --- /dev/null +++ b/marketmaker.vcxproj @@ -0,0 +1,260 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {BE4A118A-115D-44B5-B9D9-AD17C1C1AAE8} + Win32Proj + + + + Application + true + v140 + + + Application + false + v140 + + + Application + true + v140 + + + Application + false + v140 + + + + + + + + + + + + + + + + + + + + + true + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) + $(ProjectDir)\OSlibs\win;$(LibraryPath) + + + true + $(SolutionDir)/includes;$(SolutionDir)/includes/curl;$(IncludePath) + + + false + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) + $(ProjectDir)\OSlibs\win;$(LibraryPath) + + + false + false + $(ProjectDir)\includes;$(ProjectDir)\includes\curl;$(IncludePath) + + + + + + Level2 + Disabled + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_DEBUG;_CONSOLE;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + 8Bytes + .\iguana;%(AdditionalIncludeDirectories) + + + Console + true + Ws2_32.lib;pthreadVC2.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) + .\iguana;.\OSlibs\win;%(AdditionalLibraryDirectories) + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + 8Bytes + + + Console + true + .\OSlibs\win\x64;%(AdditionalLibraryDirectories) + pthread_lib.lib;Ws2_32.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + 8Bytes + + + MachineX86 + true + Console + true + true + Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\release\pthreadVC2.lib;libcurl.lib;nanomsg.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;WIN32_LEAN_AND_MEAN;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + 8Bytes + MultiThreaded + + + Console + true + true + true + Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\x64\pthread_lib.lib;libcurl.lib;nanomsg.lib;%(AdditionalDependencies) + .\OSlibs\win\x64\release;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/marketmaker.vcxproj.filters b/marketmaker.vcxproj.filters new file mode 100644 index 000000000..36d2bdfe0 --- /dev/null +++ b/marketmaker.vcxproj.filters @@ -0,0 +1,303 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + + \ No newline at end of file diff --git a/marketmaker_build_32_64.cmd b/marketmaker_build_32_64.cmd new file mode 100644 index 000000000..730081702 --- /dev/null +++ b/marketmaker_build_32_64.cmd @@ -0,0 +1,82 @@ +@echo off + +@REM Check for Visual Studio +call set "VSPATH=" +if defined VS140COMNTOOLS ( if not defined VSPATH ( + call set "VSPATH=%%VS140COMNTOOLS%%" +) ) + +@REM check if we already have the tools in the environment +if exist "%VCINSTALLDIR%" ( + goto compile +) + +if not defined VSPATH ( + echo You need Microsoft Visual Studio 15 installed + pause + exit +) + +@REM set up the environment +if exist "%VSPATH%..\..\vc\vcvarsall.bat" ( + call "%%VSPATH%%..\..\vc\vcvarsall.bat" amd64 + goto compile +) + +echo Unable to set up the environment +pause +exit + +:compile +rem MSBuild /help +MSBuild marketmaker.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64 +MSBuild marketmaker.sln /t:Rebuild /p:Configuration=Release /p:Platform=x86 + +rem Obtain version number and latest git commit number + +FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_MAJOR_VERSION" "iguana\exchanges\LP_include.h"`) DO ( +SET LP_MAJOR_VERSION_STR=%%F +) +FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_MINOR_VERSION" "iguana\exchanges\LP_include.h"`) DO ( +SET LP_MINOR_VERSION_STR=%%F +) +FOR /F "tokens=* USEBACKQ" %%F IN (`find /i "LP_BUILD_NUMBER" "iguana\exchanges\LP_include.h"`) DO ( +SET LP_BUILD_NUMBER_STR=%%F +) + +for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_MAJOR_VERSION_STR%') do ( +set LP_MAJOR_VERSION=%%a +) +for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_MINOR_VERSION_STR%') do ( +set LP_MINOR_VERSION=%%a +) +for /f delims^=^"^ tokens^=2 %%a in ('echo %LP_BUILD_NUMBER_STR%') do ( +set LP_BUILD_NUMBER=%%a +) + +rem Check if git command exist and if does - receive latest GIT_COMMIT +git --version >nul 2>&1 && ( + for /f "tokens=1" %%a in ('git rev-parse --short HEAD') do ( + set GIT_COMMIT=_%%a + ) +) || ( + set GIT_COMMIT= +) + +rem echo Marketmaker_%LP_MAJOR_VERSION%.%LP_MINOR_VERSION%_%LP_BUILD_NUMBER%%GIT_COMMIT% + +rem Using to add in marketmaker_release.7z +set host=%COMPUTERNAME% +IF "%host%"=="VM-81" ( + mkdir package_content\win32 + mkdir package_content\win64 + copy /y Release\marketmaker.exe package_content\win32 + copy /y x64\Release\marketmaker.exe package_content\win64 + echo Marketmaker_%LP_MAJOR_VERSION%.%LP_MINOR_VERSION%_%LP_BUILD_NUMBER%%GIT_COMMIT% > package_content\version.txt + cd package_content + "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win32\marketmaker.exe + "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z win64\marketmaker.exe + "C:\Program Files\7-Zip\7z.exe" a C:\komodo\marketmaker_release\marketmaker_release.7z version.txt + cd .. + rd package_content /s /q + ) diff --git a/osx_deploy.sh b/osx_deploy.sh new file mode 100755 index 000000000..9fa0f5733 --- /dev/null +++ b/osx_deploy.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +TMP_DIR=~/tmp/iguana + +# make a tmp directory +mkdir -p $TMP_DIR +echo "making $TMP_DIR" + +binaries=("iguana" "marketmaker") + +for binary in "${binaries[@]}"; +do + echo "copying $binary to $TMP_DIR" + + if [ "$binary" = "iguana" ] + then + cp agents/$binary $TMP_DIR + fi + + if [ "$binary" = "marketmaker" ] + then + cp iguana/$binary $TMP_DIR + fi + + # find the dylibs to copy for iguana + DYLIBS=`otool -L $TMP_DIR/$binary | grep "/usr/local" | awk -F' ' '{ print $1 }'` + echo "copying $DYLIBS to $TMP_DIR" + + # copy the dylibs to the tmpdir + for dylib in $DYLIBS; do cp -rf $dylib $TMP_DIR/; done + + # modify iguana to point to dylibs + echo "modifying $binary to use local libraries" + for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` $TMP_DIR/$binary; done; +done diff --git a/pnacl_main.h b/pnacl_main.h index 9d3c0f4d7..d80349202 100755 --- a/pnacl_main.h +++ b/pnacl_main.h @@ -6,13 +6,13 @@ #include #include #include -#include #ifdef _WIN32 #include "OSlibs/win/pthread.h" #include //static inline void sleep(unsigned ms) { Sleep(ms*1000); } #else +#include #include #endif @@ -622,14 +622,14 @@ static int GetParamString(struct PP_Var params, int CHROMEAPP_HANDLER(struct PP_Var params,struct PP_Var *output,const char **out_error) { - char *CHROMEAPP_JSON(char *,uint16_t port); + char *CHROMEAPP_JSON(void *_myinfo,void *_coin,char *,uint16_t port); char *retstr; PNACL_message("inside Handle_%s\n",CHROMEAPP_STR); CHECK_PARAM_COUNT(CHROMEAPP_STR, 1); PARAM_STRING(0,jsonstr); if ( jsonstr == 0 ) retstr = clonestr("{\"error\":\"illegal null jsonstr received\"}"); - else if ( (retstr= CHROMEAPP_JSON(jsonstr,7778)) == 0 ) + else if ( (retstr= CHROMEAPP_JSON(0,0,jsonstr,7778)) == 0 ) retstr = clonestr("{\"error\":\"null return\"}"); CREATE_RESPONSE(CHROMEAPP_STR); RESPONSE_STRING(retstr); diff --git a/webui/css/flag-icon.min.css b/webui/css/flag-icon.min.css new file mode 100644 index 000000000..339a9ac8d --- /dev/null +++ b/webui/css/flag-icon.min.css @@ -0,0 +1,8 @@ +.flag-icon,.flag-icon-background{ background-size:contain;background-position:50%;background-repeat:no-repeat } +.flag-icon{ position:relative;display:inline-block;width:1.8em;line-height:1.9em } +.flag-icon:before{ content:"\00a0" } +.flag-icon.flag-icon-squared{ width:1em } +.flag-icon-eu{ background-image:url(../flags/4x3/eu.svg) } +.flag-icon-eu.flag-icon-squared{ background-image:url(../flags/1x1/eu.svg) } +.flag-icon-us{ background-image:url(../flags/4x3/us.svg) } +.flag-icon-us.flag-icon-squared{ background-image:url(../flags/1x1/us.svg) } \ No newline at end of file diff --git a/webui/css/reference-currency.css b/webui/css/reference-currency.css new file mode 100644 index 000000000..22d9ba750 --- /dev/null +++ b/webui/css/reference-currency.css @@ -0,0 +1,140 @@ +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,d09GRgABAAAAAEywABIAAAAAg3QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEWU5BAAAGbAAAALgAAAGJNI0oHkZGVE0AAAGUAAAAHAAAABxdnq2WR0RFRgAAByQAAAA4AAAAQgSqBTxHUE9TAAAHXAAABCIAABH0zI0AF09TLzIAAAXUAAAAVwAAAGCAz3p9Y21hcAAASvgAAAG2AAAC5lCJVL9jdnQgAAABsAAAAB4AAAAeCkcLCmZwZ20AAAHQAAABsgAAAmUjtC+nZ2FzcAAAA4QAAAAIAAAACAAAABBnbHlmAAALgAAAO4sAAF8I3FzIU2hlYWQAAAOMAAAANQAAADb9TDtqaGhlYQAABiwAAAAgAAAAJA9PBsBobXR4AABHDAAAAh8AAANsqw8hfGxvY2EAAEksAAABuAAAAbhtqYQ8bWF4cAAABkwAAAAgAAAAIAIDAhpuYW1lAAADxAAAAawAAANRLIw+gnBvc3QAAErkAAAAEwAAACD/DQAocHJlcAAABXAAAABjAAAAdNUcAaMAAAABAAAAAMmJbzEAAAAAyRrF1wAAAADK+niN/pAAAAPGBTYBYADCANABNgE+AWgBmQDkAZIBkAFYAAB42l1Ru05bQRDdDQ+TBBJjg+RoU8xmQhrvhYYCJBBXF8XIdmM5QtqNXORiXMAHUCBRg/ZrBmgoKdKmQcgFUj6BT0BiZk2iKM3Ozuycc+bMknKk6l1a73nqnARSuNOg2abfDql2FuCedH21kZF28EDzzYxeuW7ff8VgM5pyRw2gvOct5SGjaSdQi/bU/za/guE+/2Qeg0FLM01PrZOQHkJgvhm3MPie0ay7/KQvWB0uBgNDimkq7vJzKuV/S3Outgibaxm9dnAmIj+ZBmhqpY1A0186pHo+jmIJctkw1gYTU9afZCL4ZjJd1VQtM751cJfszDtYo0pz4AH2sFUeg4fDgwmF9C2IMktDhL3YKjFCxCSHQk45d7I/KVA+koQx75LS9rhhrYFx5DUwqM3T7L/MZlPbe4cwfhFH8N1vxpIOPrKhNkaE2I5YCmACkZBRVb6hxnMvigG51P4zECVgefzjXycCrTs2Ec9lbZ1DjBWCnt8yt/yy5K5VrvOi0N2bqhqqdErzvpez7/GAp8fCcNBY8Obzvr9SoHaHxZUGzYFgSB9GH/9oLTviKu+Fj+wZZC+xKgAAAAEAAf//AA942mNgZGBgYGI4KhOnYxHPb/OVQZ79AlCE4dSvij4Y/W/F3wWcVewyDIwMHEC1QAAAdrsNxAAAAHjajZHfatswFMY/p0nLBivbLnclxi6a0dpOSmjxXVvK2EVDoaP3ii0a4z8ylhKSV9gL7BX2JIU9wh5i77DPigJZy6AWln465/vOkWUAb/GIAJvnjO+GA7znbsM9DPDV8x4+Y+q5T83K8wBv8N3zPt7hh+dDjPCTrqD/irsavz0H+BR88dzD66DwvIdvwcJzn5pfngf4EPzxvI+PvQPPh5j1hle6Wbf5w9yKo3QobmRbiLu80rXR9bEYx/EkFBdlKZzEiFYZ1S5VFt62epVXUkz1UorLUqaFmzr/1p6If0TXK9vKmS6zxJV9XuBetSbXtRiHcXzq0132xGXn1jZJFNl1o4rchqmuIrUopYni589ocp5muIJGgzVa5HjAHBYCR0gx5HoDyXhBumO2orKGcfMxY2PEHBOE5AuUHGKninE7xVVxXXLOqLwla/7SrpqkYsrd0tEl/ZJ9ix3a9n/aPaH+/5WuGbXMSswYK9k32TntS05w785sqOm6dd7QuU+fuLfekx1v9+2WN5og4rC82YbVCjosq6R0VIwrLJzDkOMXjRHPfk5/9hf9N50SeNrbwfi/dQNjL4P3Bo6AiI2MjH2RG93YtCMUNwhEem8QCQIyGiJlN7Bpx0QwbGBRcN3ArO2ygUPBdROLKpM2mMMO5HAoQDlsQA47J5TDCuSwBUE4jBs4IZojN4hoAwBDVyF/AHjaY2BiXsXcwsDKwMBawSrCwMAoAaGZdzGkMM1iYGBiYGVjBlEsCxiY3gcwPPjNAAW5OcXFQErhARvrnX88DAzsWkwJCgyM80FyzMdYzUByDCwAwEUPOwB42mNgZGBg1/q7gIGBc86/Ff9WcFYxAEVQwG0Am1sHIAABAAAA2wBXAAcAYAAGAAIAAQACABYAAAEAAV4AAwABeNqFjj0KwkAQhV9+lDRCypQeIf6g2HkPq7hJJLDZDZmk0NpjeAiPI55EUYg7EjSFkgf78S28GQY2AAucK4735ptHx513wTMvZHGB4QB9Oa82ZvHag9+O/Y3fcb5n/2x+x/rUgrZr2b13XE4jw7HLfnN6yoGYkoCIKEGsdI60jARktosgVZ1DaiFhpITmry5jhYKNIlmBMpWCclGAKJwwpowZY85YMJageksGBaHi2UNSarwA8Chcw3jaHYvbCcAgAAMvReiPE3U0Rbfsy2l6lOMgCYQAVQ/d2AlNO8M2Oc2XhJvH5ZWwJJT/wQcPXwnneNq9V01oXFUU/mYmpukkbSY1TWdMk6bNJFXbQpcBo4hoRRwk0G2hKdiVbZUyaHThSmQWgrgQN0+6d/U2IrgQfx74hwoi+gRXrmftquT2O+feN/P+ZvLe2PZ+3Jn7e+453zn3vPdQAVDHKs6jcuNa9xZmMMURGAOZqbx2/baMwfY4V+V/lTua7NV11M5VG3/KziM35tdwAZuU0DUdE2Db7Brf9Fh9jgTmX/Ol6ZvQhChVTH/Y0v0BJixDSU7af2lZyRVjZQWy1toiNhF+dkUZbc3umDnP1QO5i6/I58vaWNTSjFU+JfbUr72khnqWP1LO1v4fotv+11y1xcjo7N918gLu9cp70+7P95vpCp+U7FvfFI0v5Swcvc6yWSSCXWT0Y34Ic/Qcr1loOqmIjfEk/JstZZ6+oLV93jIvuWacJ9NzJSI1lHMTkd51dyB0sjpOry5rYCNFfJIrazfVDyxTyrfv7Aw1i0is+PbEfCtMIxkFzEMaqSqj6/Tq7d9lBDbImMRhiuPymeAArryhj3max9q+L3J71NzL53SyO1QmH2V06cdsFMbbB2VPPIRic/RAx+D/8zXMxmX4yYmJQQ4uxteY8ir29H8PO8QHinTZocY7qYjelnG3N8cr1FFudaeULnuj84vcutFcluBO8kOQzhnJ9vi7G9lEKVuaNzua00Vqr4A2O9zRuD/ZofJsOuck81dW79TzICjElzDm5ckrtD+evySTesncP2m+tG8L455JxTPIRLE6XrNe9jktGWQCaVlZfRttE7yv5uvlFdUr8yYYxX1Km0nexh7cEzR+Z0t5MZMnHupT6J8HIrWCGv7CKdc7xtY5/j/KuoJlVuDxxPondOQEkZRSpRzwq+0R7c9hGoe0VeMXXw2H+X03y9EjOIqzmEdDT4nKAhaxxP8mWniMPfD3pI7LzCJ7aziNM1hHGxt4kl+E67H9S4XsXGddTo2tpvrVzK6a1gjSnnOY1/5CDE1q0nRI2hYBrOsOm2xv6oomZUX8LxOnHFZwXPkHv6eTlgjbIVdUBwxIa025X6Rn5KS2WmxLm9xJOamsRl/Z4uuaO8v+Tw3Orrm6Qi9O03sz1KWuUSHnwOkN+kswyyrltGN1lX1bl+lx4eoofdhwfNv9rRF+SvpgjvVEZs2xBGoDreNIem3aoe40j6M1QFSs9sPR1sDr8jRtqMQWZUW6ym2oOiyqx6VsDOyZVYaq9IjV5xAZrejoFPmZp98kfmZUm8Ma+3V6bINzZ3nXFhjrF8j9Rb5hLeE5PE85l/ASo+dldHgbXsEVRsg14il0iW28STyNd/EensH7xAv4kLiEj/AxXsQn+JT77uAzXIaPz3EVX+ArXMc3xE18S9zCd8Tr+B4/4A38iJ9wGz/jF8r+Fb/hLfxOvI2/iXfuAUeiM/oAAHjapXwLeFTVueha+zGTmUzm/cqTzEwyeUEmmUkmD0IIGGOMgLyMESgGjBgRKSIiRYzIoR7KoYiUi4hoOWiVy6G49zAiWkojpRSpVUs9OZTj8XD8+HqBWku9lComO/f/19ozJGh7z/2uMrP3XpmZ9a9//e/HIgJZMjxFLJfPEZEYST1RaCRplIlNqlAMkaTA7qiSEVHoQNJoIiYYN9pViVYkCXtSTbSCVFXLAUdAdAQcYvnQZOFoy1B/0rDty72GvC/PE0IEMnn4Er0sx2GOTEJoQAwIwXBNPOp10yPakTjd//iBJ5448AS9LLZdSz6B98PDpFV4RVwkd9hLSAZNEGI3kAz2W35CpCvwW7lkDLmNJGRKKhQSS1hFuDr5NWnMkK1ZFao/LxZTjYaLqpATjSYtmWzQmw+DFhi0u6NRqhRG1ABbQiDkConwqouxV0xkL2MIXyXwJ+FzbfGLvdri/W1K54HW5GJt8a7F2hJl8qGuQ61Hkl27OmmTdpw2naUZZ2iL1o+vM9oXZ+FZ+wIWTYqG66UPDIREaR5RCGBZIhmAzWAkmcPuqBKLKO6BZJGJFMB4kV3NprCyaDLPRKwwUB1V8uyqGTBfyT6h1sCf4zlv/emxYxXEU2G2Kna7YulXw+YvlfJ+eDiYZbe4Kg5a2bsN35Ww/WBJuBweS9l7Gb4nYKRwY+HGkMHqcDYopQ1KWUMCPo4P1gYlq4G0mC1ZVps9XFJaVl6Z/o9+87DSkkPVIrfDqUgNal62w6kagw0NaqUZ7grGNDQQ1UjgVqxuaFCCjoOSe0xlka9ByXGq2QUNDUBJtUUlrgIai8ZrayqNtTXNQl1twOP1iZU0FPS4C4wet8HoESza794+PeM/1k68I9a57LHHlnXGGpbsf4CSv7x2ZvbphYtind9+7LFvd8b++G8nD+cpdOzUu4uK3HkuZ254cteG2VM3r5xlPdof3Kx90tLa5M53u/PDk+5YO73/j7mHgcZkUjp8Qf5C7gBq9ZAAGUuqYAOD4dqaeCzqhflJId4Xwi1FMMOhoMHj9pLr9y4aonTT7uPHd+85cUKUtP7jx2nLia+2xSa11ESbm0Wpt6WlJjZRG9x3TJwt7PvZ01uOHdvy9M+GmvU74d8mTGhpbm6ZMGGouakZ7yZKE6+dYhzkB9iqALYwqSbjyXqSoMABCQnekiVG4pYqEi5kgQaAEomqKaKYBtSI6eJBe8SUUaFGTReViF2NAx35TCQb6GgCrVAjdtgw2O2oI1EyTmqAvYk7E678MrzzOQ4KtDAIu0TUEgqfExqUBsfrJruveFwNjFZVl9ESQyhYKbDd4mgqoB63VTR6x9B4nWwweoujdeGScAniyeX26YiSq7TW5p2Je/Y+0T525rcmdPzpJ70HHy6umzOtviLQPrmQeu+8b+HQ5qrK5nAkVnrHgvD6cYHSmpau2ILn77nl0TmT8ret+aeftX1/blNPW0upf3zJvPseXK8+vnS6+5bY+FurJ978LeFa/ZSW2WMqYsh/IE9oku1pK0kYAEXsjSqWiCIOqBmAIJIhZlQkKZdyIAd1CZcF+KEirFtuUDOAdhVDA4gLGoLlxhk5GGnbtqUPbn+wLhemOFo5ZcmSKe6rD+GcHdpyYYs8B6WebAwLdmedzwDvwpbzL/ziFy+cv3/u3I8S36ef00v08+8fOKAd1BZrB5msgO8t5t+jJXGnXSip88I7zcCv3I9f1pYn9tGpdDudeuDA9zWr5tWs8L2gcEDANTqAOhImXKOJrdGJ8lvJiOpLUsxR1cWEHg3VGUvqSup8JTFjnc/oM5bQI3sylOmHD09XMvaYlZlvvTVTEQ6cXrapu3vTstP6lSCMjeSweEzqAxjvIIocARmsGgwX4acTssFccbBFFk2AYhlvDRmmFKIVYzQpcIFmiiYEEf8sEPikKOCtKJsYwhG0gCPkCNQGHDFQLcc05YKm0OkX6HShUeuj607T5dpmBkerdpYO0m2w5nKimCJJm0TGSHzNlgFcsAv2EFer2kwgeIgRpUwx7FpJM60DstXZmg7+w6NbY8tc7sKOnjWzuzdsXffJ7JXeh+syemd2rtkE8zTRaUKesBo4MB+1pCoYL1JFYooRJsmCSeQU3AEhTyuk5+g0OpZwGIcv0MsAo5EEOb8mZQlxwDSryDSrK61LpZRufIhpRT9TiPx3yPAZ4UN5PsBAfCEau3aNnr1WKj/F9GLR8AXpOOy9CzTjdD6L6pEuJjKBAtRsCYDNiyiGgWQu1y+5dtUHMsDOdUk+0Lgv1+E8SM2ZhHF6tgeeDDa7zDhcClaKNc1itEB0WwUQdPZw0GAXLlw4vrG7srJ74/HUjdbbP2dO/xx/x5OvnfrondfWdnSsfe2dj0699iTNeZnO3rNH28/XQYg4B6SZgYzT5Zcs6m9UMaZwioBlAGCEMuYjKGgcQKEBcY625JPzVKPzxJpzn9Er7DfRLtgG688l00iC4OpzYPVuXL1VX33mAMo8XD2JJjJ9SHCZ1MRWT9QcwkWb1ZHItPtQ8LmdioNJN0ezkQksoxgvihUSZPmAtO2ro4//8LnOacFcQ9fkIy9/tIRGnqOUjv/pRZqgjV0PPTSpNTx2jDvSsJFaHv62NvyrTV/sZHDCPu0COMvJAh1OI8CZj3D6pItJl5Xkg5XiQpArIopnIFnIMTEWMFEIm6KaQyktqogIriqVArAupxJCWa3mFMJTvlPJRWUaHKFMQX8aHd5YtLYGRK+xJB4olHAlBaLHLQldR7WBrhPt73bO78n9VufO0py9h0/c+S+tR0/SXppFx7z6RMPSeQ3az/wP3U3dEyfFSrLznRJdJEzubKof/Ojkvgf2egxVUx+efPA/OC3CXnwI+2smWaT7xh1OCllUzgI7MqYK0kUQA1Sx4t4oNIqMoG+PMRO3x2gC0ZBpZDsF8kS14U5lCcy6UGSHYmH7A0KCopwIUYcoNWpLhvro74WqnTu1JYMDNA42KdF20276sjYP8N0C+O8H2ApIp45/A+DfjvgHpCd9FmLPYltBlTGoO9H+QvwXAv7zUIKAYQT4N+jkYnEcFK22PLRhfE7FjUgvTOMcaaYYzOKApxkGCgSPmwhLtX9+/8xNr8+ZP7+ra/tC7ZI4OLSjeuusO3Y92qYd9x+hefVNLZVVzfNaxHJt95FIXfO3X1nwsXYtzeOngHYCwDerdeiDAL0ZobcD9NllxJyls3slY3cvx6jXrhYDuxfwtURgLV4DLKCiQSl2vG62k+xgGS6hwKlas3B5ZUH4a0GDku1QDV4gKDszD8wOsAeRrCrF2hpnEYhNnwhrtAr5NLVAKxXT1FZAhd1Pnt52bxUwxAfL//P2ffc+U9NzZ2301W/N3fvd6c8MvtHR3Tx97KM3G+/xtz72418/+u+08YXmuHayPS8+r1GadMv4B//lvs0fraQ9LWNL6zzx2+5muhFoaxGTHcGU7YOrF3HJxggKDKJKIlPTSBsojh3CPq2NvjK0WZosDtBu7QKIH4bLk0xelJBYSg6ppRkXEzb8vWAG/F5NRK3F3wuWOpyvy2aXP68yJQ5R+6Ot0yywZRuZwUMBDWl70MUooMQKf/AKF3//3v57N6640LP3+Jnje3surdh0737tZy3dnR1TOhdMmrloedstD/X4x9757MLFanX3h/OfnlFaOuPp+b9dUK0uXvjsnWK9qbagrLq6rKB26N/ry4sazebGooo65g8NX5KOylPAG6pI0wRStBdXUQw0kVVIvEATWYigsRHFOZAs5TRRakeNk6LvcUATpU6gb0mE/TY5XjeQLG9hMVJFnlMJpkgeRE6WA7mvECRRXgPSj+JkNBEucYF0iU+gVqobg0gSIF0ESYzWIUEAVoAkBE4JT/woTQcvcCLRTixCWui59e7m6d7mOK1vX7/QkKYCTiHaiRfEAqCESRVAEaAPh7luFT+0h4kNvEQjvgstgJdW7SM6KH4IOjcbeEfXqa6v632uZS2jtb9QyrTu0B9HWwHc7kmC3bMB6I8UUwf1ZFHx2OAqccNQj7ArCdJSor3XPv+MMNga6RrxmHgEfNgBeG4H6OBKDt34OyZaO47Wst8Rdg31iBvAfthx7bPPr2k7CON7MnxBXAG0mofUT5HqRC7FRcSxF01tj9uXdqqj8crJkyunlS4oPjf7j4/96o/jZ80a772d+9j9HSsmLGwaF7aXV4apcNe3Dmyb9lhH0+Tiqpyhc7qlIZC24RXygDRIWsDD3ksSJQJwWQjekm0GEgAPAwfQh23ikQJQrZ5YchL7mzIuCo5s0qxHDqZEFHkgWc/Nznq7OgYI7lYTKYanW+1qFTzZuJU9Fcjv1jFAYHkNSpWjxUTM2SFPrGliK7NG8pqAMJsnArlNcijZDUqb83WbXFFVPwbJM+RQwlwqAdE5QUVzQSTCHkcYMYY5LXp9dQERaJCJZhIKSgb4mFeKRcEqF6MTqc63Qv9Tn766YP3vaNFzm/+0+67G+Y8+Wn9Xj0OKbmz7wavfeWfZzCdCTto0z1A/8W7tP7/8njZ8ZPlmMvzCW/urfv6bWZPCJVO7lty8acHeC//wPA3965Pd//xvK+977ZFZ4Y5Ga3vHL55d8x//0FTTpU0r8E959sn/RW0PHRkm33vuqy1LWvuEyplH6x+d0diGez78EfgMCsg5I2jR6utxjrTnkhTNsiFLF3yZEdWCgsoAbrZi4i5ZwBiggUxBVrR4lVZYpcXpp3Rw9fr1u3bJ8cET9IA2E80wsgTmaYJ5nCAJi+CJy8EikCCCyI2oZG6ICjBTLs5UzKwzPUiRE8U4hRd2MYMPjCkccCStXKCEYUczcEczYQNDRdzBzHXAI3j7Sga3rAJsrwxcfAoiV5oBD03diInBt8Tye16YV/XEvQ8+Uz1/578HIpGAdpK2VsRiFdoROd7c88iE77zkdRx64pa19zWJHeNCgYpdmqEyXFy9j8ddLsjdIB+DJK5Lx+yUxnTjgkKMQrldqBYhEt3ZDmfSLjvy8pmwByMqnCYs0SczSWZHUVcnWyVReF778/Fly45T2/P3qmsXt+ZoL+c8c+fTr7/+9J3P5NB52a0PrFX99x6k4rM7qJi4t7Kj9/7xe2Y81K+d739oxu7G++6fUsV4HPcBdgbsXifwHYfUCZCKCKkDIXUx1Ds5pp129JN0g0l1I9wOlN4G5t8wzErgMkocpRXUIRwb2ifM/pC29/drb/7rVuXlXcfk+HPa+1q39t5O2n14/fd/PLQRZgU4pG6AI5N06LRgTtGCDLRgMDFaMCBAFgaQmQMkRxNmioaaGdw5RYzCTUbamUN4wApiL6l70CJeGdotzBw6IMBM2u712u6tTCam5jaRm3Td/o3zmkd4CDgvYfMSyYTvOGnmDZMKRFuSmlKfkKRoowdoI0Bm6Rj3p2gDbcH8AmZN5eOcQUYm3JpSQ4huP6rDwga1IB/Q7pXRBneodg9czU7FdiPhCKMIpzaEVokoPKtd+eWKFb+klmeX/2LzPUFtf+G62Ug69asKvxA2XvEveI0adr1ADQcWjF+08uYDrQuRbELZVbR76GPt8xTO5OWp/RopJRQzvyYzRCYoMvQtg2VIHHXGqCLZVUrRF085XCP3i/8vL9eWaEFtCd1GP4aXpgmAwlJ6hs8tEBaVKh6xX+xthG9ckPaN8WdxL+g2+BLzZy+Iq+A2i9Tp+IetHhm4AMcgYyCZyX+DGf+ybnebHGCKII651VELkLoluuLCppe7Zt80g27T/uhfQmuapreJswdf+fIrksbVQoareg6vIsXYTIohps9oYVazLs7EKMMHmEmwxUIG5yxqZHihASov1Nzahx0MNfPpZ1oGHejRNgN2LPTK0DY+n3gN5pNJjc5Lks5LOo4MDEd8OxISI2MJ2Ec1jtgF8drgcpgAfmewnP+mAeWEhcwgCSP+JhFjsUQGriKTX6mSFVGMA8AzbBUGtsepnbBiOAtsf9WUiYZ+htHhTAiyuUEXGzTEJs2lAcMu2PeBpDagLREqL10SKsXg4Mf4kuNDa4W1KXwuY/wKsEg67aGPp2TEdG8eeFUaSIo6Pu24sqSJQwJcqhq5pY7bSQEaWUJE6yKMAQJv8jJtDSB6Cd1NP6DbhJeH5gEEG4RVJOUTyWeAhzOJKx33AFs3YUzLTTcDwcVBcNmRjnShpXoABJsL4x4GI497OLLgSTKZRW7oFxYJdmdRIYrSosK4PVxosIu/0hZpybffplPoTjrl7beHumiBqmqfqP79dALdSifs36/9XFuq/fxwP80DYXuepOW7m+2bh7Tr3CLqWihp8VARWNSC4HpHSjd3VCF21Q4Q883EoA1oKE/avwE5T1B1hgJpnYkcJpz8LzI88dHDy7V3KYm3tsaHgU+1a8fnv9zXTrvj0Zr4aYa7XQx3dpJP7tY50JHCXQ4CU8Bwx10EzD/4ruNuDMaM8jBKZLQh7tA7tCIGgUMTliwbhlByHOCdcdoCaaij0mM3+uQSgxgrKWaRYMCpV9B+PQKnr7RrF+b3bbDMo/4eN6J2FG7f0f7y5pxzK0ppz4pza+OtmxHH/WkcewHHNuInM69zuFEPrlAle6T48zHx57q+ohyKch9QS9libLAYH0X2MNt19hBRbusYN1JdtXpkr1ZzeKuO9LEd08Zqp+unTK27ihEHhvWZm7pbvHRsvCZWexr5xgC+ZwLs+bEA4XWPzY9gFiCY4yKKKxX4UQq5m1bOYay8MetjsyuZ/WrQ/KUS7oeHgxZbpqviYBZ7t+K7ErQfBBsYHovYezG+J2BkRNanCPy4hgR8HB+yGhQLZn0yMb8TDBUVh0dlfb5pmGV9Cl3cPzQ5DhqIvwBJotyp5uSODJcUOA6Krtxy/JvfqeSMDpfwfE+scGSyRxKWa0/8YXSqp/2pf/sunXl+VKZHe8//4Y15ns4XHu9464Ycz7//RY8hrGO29YQbYgiKIZpKd3IOTBkXBlNFghK8pRiIMo1Sk2IBiMqd0nxtF4sv7GayEeTSVpjDjfkGJpUyYY+ZYrbF9NyDh5Gjrmwy7Cibkw6+z2BUq9YMDFjTBgx9SoXg3aCSS2s7KxV/pB0a/uEMunPdqpXr6M7pP/Tf8fx7faJzcPDeJ9f1iNLg5b4PngdY0r6EAfMCaT2tyDFdDaXiJgJlkTUeNzHRgHhckzQ3PUUL4f9ToID6xHX4excIMW5isixyXe6zQLOcEeN3qINwPQSWjSxkTGmYTFCcqF5Qw1i1LmDoLm0dPb7/FK06tY+eEK4MWWCiD8QqfOmwr2E6u+L6XDfqbF1NSyPUdCZbQS6q6TVa0ZUrWhE9qnXTs2c+pB/DdYfWK+wXNmrr6ZqhVSkczYZ5MlK2AZPOOInIJjGNNGfMI8LSqshvuPpkM4o9QA8WeuKLK/SEZhecYpHWTI8NfoR00Q6018t0ZqXO+2CYMWWJxgEqTGa+8lST0MBUomJM/TozPKTer87RQU2SnJogWGiLsB2I7thQL7dxtPVCJ8h0I6kiXMHIhovgrGN2JkXaBpaB0fMWaOWY0qkLT8gREzo1L710+bK23nDyPDOdRuceZBqj9KwWvkbPlspPXVvNbWmY18rmjfP8GpsXEyX6vCLDHmZ+iB2zbFksywZEmJ69NuYI1QYEq+a9fJle0tafl8l59tthYac4n9Gvl4xOFTC6xTxWJhguAXH+4O4XNYpBpp3o4Aq7GOzD17R3paXDCsDuImmQpEg6Y1MbkJZ+tUlaob3L5yNSlxCWV+Fa8WeF8GXtFI1LXbSQ6/Ig2K3XxI/B6q0m30nFtzGtEzaQCpAZYzBW4mfZ2KRjnDwmCy7sL1SJYqhbrTJdVKrs6LaptCwaVYtNF9UYPFSBAD4oO3JZPNntUP0sY+6Qka7doE/9DiW3QRmDURIW+GahNhHjQRje4KFHDHCxwBtFR4M5HW6veE3bUfbPc8bO7WotK588p6vy7hdL5nfetKVh9by/PDrlH/q6ajXz2BkOx4yxNR0d82KTfLFbl0y8eelN4xwN1T21N0XHftzR7m2465lvaRvz/HF/XsnMYsBDD+ixp5gcyCcLScKKeMhFkhb1MCp/cwE6VFMGNydsA6oDVkuyolHFYVcNGIqGZ7QmDA5Yp4vpCxHUkpLP7EIvS25gJoZeD6sbuBEej0WdzPoJltB3/XeWTL3vvqnhLr+2g/b27j38+U2PPHfX7mV0UUFwUded9xYVDO0BdVzep12+9J3jj0/uY3uNe3kW9jIbdQHjRxcAb0SQrQhyDlpADORcZEsXsqWPpYmkTC/aOEanYubhJ1pbQ3AfjDrS0dPzWanQ8tzVp2ntxWd/W3XBPzs+48EHZ9TOzr5Q/Vv/movPfkL9D956tnjcPYl7q4o+al+aoi+pFfBqJ3mI13SGX3WMwqsFgfQjkPksy58LVJVr5xa+G6jKDkAXoB7JxbCuhZGSnsAHQjKBmseYDCMkPX/vjEV9jsBIwpFatR3Ldt/13CM3fX54by/t1QTAL8N076K+yY8f/84lau+jA19dLir4oiB474H7UvCHAac+MobcybGadPDiBBOyRj5njTFWYgKrdwxyYyEzNLNMxAjiNUDRhgegdfpHnHsQ54qbUb+UxjeYC1GSTwOMMhDZrkoxFDQKTTs+3zL1e794+CzNG1pmf3BWZHNgW+v5QtkRai7rK/Svuvh871sbpmu/+7IjdktJ/seNzcIyV6jEt4LLOiv4bVPAPvOSb+nYR0WTtBkxqJmQMPrpiqmi8aLiAXPBx7LrclQlgH9nOhzhGW0x+FkKGoV5FiNrnrpygLjlgWifEck6n4IMFLzajt273//nOS9VryusL6o/flzYTOvHPvt2bexkeGxwrHYScaytkiYDjoOgRx4iiVyM0fqRIMqBRnJ5gFY1AIjWiBpCGomgUamOAxjH2VlwLjMHaCQfaKQKHsa5sCpHAHoOo/lm9TNvyGpgJp1ajjU7FlcDC+Ch1UZ1q61ZmEDTtR9APLVomIjiCAKi17Sh13fUPjez+OZbxz30w7uefeSmSSuem/OjB2jv1Ede+oFUfCeQU/H0nh5t1RZKamsdpXc01awb//CRVSvfemRC36LBPaveuH+yVzgXzHs3Lzh973TYn0UgocGyBmk+hSTMI+wP/mYXmCXCXT/zgGqCNVuiion5wbhLzO9j+tsOi7TLbFPYdoyQLTy0Ls3TdrS31t1cgDIl+sqK3XuEnPbm8uDQfhAlwYaprzwFezENiOYTeTfovszruQYRvdcle1eu3LvSi1+WLCvx4as+8QTGd8dqq/Tv+DATiTKSvYGqVG1G1JxYJJCNOsOPWRvVY7p4sMApWtNBv2xYhMeJzqskc+fVlsHCrYqLk1cKEoq5GS470XA06FBpXb33TewsqCqP1tPed3TwvryaW0LNPlt7q7hrsOf4Z4wfegDfPMbUdN2rSkeiGU+zNz2+hNU03xw7EY0YjnO4AlRarrW90oZ4+ZgmtCStn38WvPp62qW1k9Sc9F0WWwr+jdgS28nrgSX6Lv4afIN91/Ai8MYY8gBJOFiMBO1SJ8LpQxznxdSsjIsYO3QysEH6OAZQXiquqGJnDhdbRMZ1kgmwIViLL7uhgRNPHqDcmQVD7uyG6+SD1JO68sSvj5OS4UVtR7x+1iRtR03jjEkIbFhZfKa58tDSf/qhUFPVNGVov34RTyytvmNfW88zz6RxIc2B9TiR3k06vZtxNTYkdQk43szW4WJ6ACHPjI4E3p2id/RpzSiEdPFTkyJ3j07uc7Qdm0ZRu3cjEjtA1DB131O6bO8GWGwkNx0htgMAuP+qN4NXWgANZAMQ2cy9VrMAAqwwcWUjsYK7w4jVa0dbx5IlpVOqPJkKjk3xiLI64afX3t/Q0bHh/Wu/wYuWmDlv3szp8+b5Z216491Dm2bO3HTo3Tc2/WHx7JmLF8+c9QDTnz3aFmk9wGgFGLt1rW4DGOUUoaoe/QkoiQEMKl4EKA1+sEpEu+oEaC061E4RvTATKiKb7sV6kL8UmdvlcrCEIZDbIkK6JNDoATv0oz1LEZUP/Ognf/yj9s6U3vtvA3nn6/L3aeVyfFGfdvXyn7W/0GZunlzNL9btS4AfZbuFw5/FKfhiwpsSEqpRf1KyOfz2AdUMCDezqlFV9IBk9+vwZ2PpZZYL4SdArCC+FaMDBJ/iRaUKojwtrAHbYlC3AmqRTw1CW3GXD8Tzbff3VsEKfoJSW9uxlIaL868WFN17Z9ci7RjN/PNlau5bdO0UHehL06twRfyEZKEvwHkXIWdGlRkgFwQ9uMuZGGUFC+4K5rT/ySnSwRDJOTvyP6cX1LSszhNPLK67XdtrDgbZXE6w3w4BrkpS9lvSyC0NN1oaOQZeDVYaUctwhlTZTI7joOTwsey22wkmJq+VqUMhWVtTKTOVrNtxHneB7AGh+el67cvbt4w/fXt304JHHlnQ9L/e+f2R9dW7bg/X8Oe/+mdN+rxySrnTneUoa1k1Y2P/mktl47MddqfVOe6m1TN/8Ca3LYYvCJ9J74FtsTQVcQOMGAQWsFdlI6qqUXVzPr1uTrWasFomYWVFc1YPZjusFiyds6ZL5/xo7WFIlYwwm2QHr0sJhmvR3HCwUhkeSKhzGei1Pft276a9x4+PC/kqDC3t/p3b6Upaj3XL2knt83CNxaBdbuH7CrzfBeqLyaG014OilHGV4ojpasCFcXs1E+UQi14qNJqWQ5kZut+cxW3RtCMTZtoJoXIEpC5tB8ofAGxT7c0FtHdJ/ZRXvyskhi5sKA8Ks8Gn+wRk4hSAZURMQ9BjGsLfjGmAcy4MaOu0jXTN4bfoGvHE0BmhlPuIF0BnLITfGx3TENIxDeG/F9OQO7RVL+7SVmkX6PK1++jkvWvpCiFv6DxM9angxhefSyqHuVhMg+lTMcZJwMSv12MaBvq1mIavDtRnubZy+04wIZq0M3TjunV0I1zJMKGX6cAnn2jlfE2fgI04he1XFWHchzkhdnVE0EfDjeK5Q9HBiAYkg0pNOFkuBfqYyFFGraIxOCcaqFjizMCACaJOmzdm7ncem92pbaAtzrBbHEBMfnVsxoP1YIQirUwGG3ojzD0izmHkMleVjP+NOIcH3PmNg4fpbG2/2KK9THtoBn2K1g9qS7mMkfQ4RwBz1g4WSOfxhkK4gA1lknnWThoAhkrm88iDL5rIl5Bb8jFJCba6lM9yLiYTS+qp+RITkABVIbpMeawSBiWmG0SoH/HC6RQEfC1aUzXNdDz1oJBwuI1eePOOp0Lnqud+VxuL1d7/6sJVq2I3z5t3c2yVtv6dV6m3se1IWyN1L9vfeX5Ki3bs6ZKSp7XjE2/ncZvhM3S6Hl8BLqXTz5/npZ3oo8JaV6TWykrVbDymQ+GSE1Gz5VSGUjFHscgL1+qJJgqYGCnIBiEhF7CiXFy2LcrWWoBmbwasNQdJzFDQgNVeMKDYnKrZg2t11TKTsaaOrbiC1rK6bpQcHrZiMPxT61u18NX7cc2/e05bf/72ibQJ10abW6ac79y/TPuULVy79Oo7fD1RMSiCuUfKyCskUSgyXlMdsBZTRC1Fb7A8omQPqDm50WjSz1ajerygmf12sGJYiTYOVfBQePPwlSSGwiUlp9Kq5PVLqjfzS6vi7pcOerxuV4WSYz+Ym5PnqhBed3u8Obl5eiRbdefpgWvix3RYIWrIUrDwFH+D4nCo1uIGrHJSKO66z4pejhwKWiVjSbMMiICX8PkFyeIrqJ5wZ03drKqg2+F32PwOi0kSP5Xt+VWTFjSlhifL8bz6bz0wa0ZNYVHDzTc3FOU3NHTGy3ImL1k9b2pZUUNbW0MR6P0WbQv9TDzH+2SA8Vypkp7JUdoaf5JV8GhbxLbBt8SXebEOxi/qxbPSYlJAFhClIJL0Siyy5ogkTXqN8Rhm3rhBGLsZ/rAGuyBVg83qGgvQvXN4EQHeArilOQ2IgoRkzcYIh8mpGrN4cwZLaNfVxsC2uTHMYfTQUz/9wx9+OnjP5tDIOEfR5oUn3wrSzF+ApRDavtPzrXg63FE733MU6aEG9Mpy8Ldj5J9IohTlYWVMDUkXlZBdKSwccKhjM/S0POjKJKGl5qwKxR9TCZJ/FOv0MHjgZlXUCTdjcHcOEL3kTmdUaylm2hzO14WCsZHqGLNAC8eCFC8IR3CNxKEWV4NhjwESVbLq5B/moTVJT95j/Zov4AnBYtFlj0VBfwJZUFYaXFtTUjNl7KTF39vS9ktKbtH6vTNi42+1Zzqo5azYWFYUrV9f2lu1c8F/3rrloaKetev3uYW8s3dMnbXl3vbgmg2Hm5purs6dkBc+G1mYbYlO1o71lpd30Iz5C8fVMpuwlDRJF6RBkgP6biV2EKm54MEEIjxKVYIJX7UI9rjIzmI+sN1qKVyLjLhmMA4yLazA05HIshJe3fy6ze70+rMZKnIJfkySvT58VgIO1W2ED1mdr5vMFpvDyWz04mCJsQSLHrFjIF7oq/OBzHNj14BBHGmxb9i4bNvpDW3tG09vf5iaH97xwYb2jo0f7Fz2VNfCe+7sXLjwxei2DzY8+vQPHtn4wY6qqh0fbFy9eeuq9R9sraLN3IyfvZjrr1RM3kvW6DoeiUDJirFrUpQoEgKGYgwYikkaM9iAjXV9KY4RsZlUPnVUeEaxR0dEaNDE8qf8JAv6SRlpP6k2wP/n6jDgYf+zKP9C+iK8coBxebR/K83jYwOnF58WZmLcf+gA3PL8ZFrGG7mUr9UlPch6YdV2YRWr55wvHmK8MJ48ThIhXGgZL63LiCRt7I619WQPKIVRtR62vCKKpXUO4OyaqCrDAImyrp568LcSHkt+A+PmpC0jVMaarWRnQiwONzSMiBiUOV6XLYXheCMrqHMqxSj03AbcXwk03kjLuJnWYeQtHivkEgCYwiDXYGuPLy4emt62XdNObvnTHRsnvDVrObeMG28Kzbj9r29Qy/Z1tT9o641MvWfRPVMj2otLOvtahd3TNpbe+uOdiTlt5+Kd8dyQx1fR8sj08Q80OsMbOtcfWHe6PB5359ncnsrm3i2zfLYZnd58jJ8kpaBwChSkiTjAisKKBzGGyWslI8qaP2xp+xNDzBTYgbe8EFRbYbTvJbeBiVfh1P23dfT2dtymvXHf9vvu2y6PwXf9H6uR6xq+JB+RpxEXeBnN5Hu8ziYZYjWOLBSbzOb39ehzVLP75NgJcnUWXPRKyIkYikK5i5WQBXaswU6O50/jWSYg1W/Ugtw73uF8wyZnh8rGVtcwBq2f4HC2mM3uAlJWGampLWUMSVnou5KmqoykAmqsqRSwIht2RcDwnOxjprU9fj0wjSVI8pEH3xz+/qbhN5cufZMMb/o+GX7zwdndL517bPW5lxYs2PNfqx8791K3tn1K/QtzX/vzn1+b+3y8o/SRm59UE2s3CbtGfw1/CD/Nvv1fexYseOnc7PZJt/2JLv7DrRM74s1vaJd+gvJLWCP0y3bQU6VkHXYMJcfIxA+rD0eSFnaXCFuQF8MUeNGlGzVlrAS/lGurUh7QsAWjUT2VpJZj1bKJBRI8XqRd6lBd2UjZY2Tuq4f1SLdqA5tGzcYctZfZcTx5QvXoKy/WL9HL2OWUT+wW+jXvwvba7pvXd9660NNYP39aV/OrUyc90B3XDmRXm83V2VOETY15leULblq4qCy7KlzV/nIkkj1++fTzHkeB3d2LfN9E+qStYjuRUa8Xow3P/1HhiNaPvaLYLSp6r9/30V66UHsR3V68snphXksMvxEjLHdluJiQmH0nCSZeSiQM6N1rCYHJOEFKlxJR1kwlHjszNF08MtRPl57G+mS9p8luwIg3kUgbvSZuB9ljAYlbRMaRJOGC1s7rfMVI0sPvciJKUSxZzok+pxwny8kzsZKKskgyXyf5SlaF5ORE7rSreUDkufypLIqZCmxJCPCBAK9n1HkAGxRy80AT292sxPyg2S8WMcXkVD22BlaDjlxRngNbb8xysvqTMocS4GLr+r4asbwEdFJh3BgqCWFyk7XshepY4QZYLuL2v6oP/3z5F4r617b3tbPvv0/D72+f0zet48Ske+YEq+LBNWuCcXGP8sXynz+s/vWv6rb33tu29YMPFvb309/PmtTWsSVctbeS5wynCQNA3+kco3xjjlEYGCoXBqRpx3iMR/hCwJpurFifR3iNSqZ8EZCs2vCrdlYbkMWxk8VrQPjuoqRXszAnKBqApKlJr5kCaY6hKirBoDET7mSCZgxJibmaMFprUWHFa1d//OOrclv35Mnd0vN4/5r2SncbPLOadRB4x6QPec360LtAGxbSCesbK3YIXxhWEh+ZyqwPL2hYSwQtdjta7H5WN+fSE7zRhMHFIhjYXpWNbp5Xd/NMFnQ2MJNg580kgJlmYWTmkrVUBoQvhub17yuPVTc9GljfenTeK/2rX6GlYsfR7z4ZzQmVNRXtvWXS5lXT/sfDiPtKsUnQALYScgtJeFgzDMekmftHLMOUCgGZ9ZIzu4M1Ayoe1HZKjkPNCzaw7FJ+ioh0tac38tSyyosalBJ6HzA2uGgn96x8s25N5dpovL51WqfFOW1K4/JVs1c8/l//8to9t3eslMY+8N2bGg6MG5fvK3IL7wregui0netX90xclGXsuSHXbKIhlxDWTl2+LK/SzrFkM2WxzDPgR+eSLpLIQdvYE8PwHxovosCL/thV4JFAcUA3ARSZtYuno69mmQf/shyqx8dayHJYKhPMepbv0CMvLDDE7NoSFJA89sZjMCX5bqf3prs+bwt8Z3plhrZDjuvhmKEXCwoN2gfuA9PnM5jj4JN0srzwbYSlZJIil/BiZipUBQCyMkVejoU0LtmxMBB74k0RvS41JQ6s/JCBkAP/Z8osIHbu3rB786lTm+nJk/L8a3vEaado3insB6Fuelno550grAETcKwto2dBpvnJNNZ7b+CaJzOSdOmiKpvpGS+fLoflpFH6uBpG9L1kgkOUxVK+LqdqdTAXAWnkOl3UxYw6aXx229pQ8523h6rLx3hWNu2OFoTrZmzQlpXkr23y+4P+1t0rnLMmzrobYQO+KjUsxj4QGsD2xphQqn2xaRtt+0TsoKc37qJN3P4X1ogCyBe0d6YzDjTLLLknI3E7WX2FnbOf3Y7dAFhXZOW9r6rFrosDIH+iB5RU2YoihBVbUt1CsBtKWH+gx023/eiXv/zRq7/85auLFy8S1hyj9mNva5+9fXJdX9868jWdxtWZyN6lrVyP4Wv79Vv6+5Q241eUNfCf4YIcB1nzW/HDwUNwPS3sZV08q2DP3iX6Z4wZ7DP8byX8b/CZhyT74CH2GRDAxqXyZPwdaQ7/HbGS/c5y/jsAr11bI2JOgPfQ6D0zLASaahERwYOL6w63MPObemiGmAcuGEb00GjayB6aFXoLzfAwr7kynABYJtEwnWbHfrXR4w8LjalxIqbGgQ5whwkNlRhDrkCmQAO8k0Pyn167+rRC6/3r14tLR/Z0yK9s3UoLv4pjxYsmYXvH9XnegnlO0OVfmx/l+310w43jxjwY/wW9kIZLGH4PcNvHaiqdqWo5RYphT60iomvu1KvaVJN0MWnOolhqbpZGhBZNGNR36G4UriTVCFDsEI19gxZt4UytRvRKO1MtAYOWT3ARvC9gF29UwfqiVayPo46sJQkfThiQLo5m5qjOzPWsy+36QRqoOms5azcAM5iKwJQ2EdFq8wXCkSo0HWodSvRGTq9FTo8Cp1c1oEOctOU7CyLc7L6B64uI42+0h4g2qgsE4epIiVCu/UF76W/2jBTM+e7by3O4yFiVFhnLC+kj1PNNTSRtq1d0GFq4QGH8wPooOO2RfraX4RvGH6Yfp8Z53SyOA+0505THas30nRIP6bRHR/duMML7svF6D0d6Dk5fldfnHt6FE3GYhnex8fLU54UPOUzkwPXx4fMwvo6NHx8+nxoHPtkP48cM2NfnIB4Y0a0bKe3Wsby7nXlvQrbu2d2FNfqGB0f4dV+OxRYEAAksX/kE60HIIY+O6BxnBpkHaFqUiDGrQvHGMGKu+EFt5aKpjUGFHE5inmgihx1fkOM3ge2dw2xvjCjkMK881b+QxwLtOdzhlhzAE2h7mNN1IDe27DDcC58O7duw4YbGHTA7NDpIm+ng6AaeXdqxXTpO5WU6729nuIswXLNaeV0mLWTjVTeMPywsS43zHlkcJ+gf5KQpg+iF8GREcbw0W6cQ7Td6NbyQNbpMnhPLtaf0ovihj26olr8OB4d739fg4zR1Ig0fJfPJoPii1MS8KhMtMdE6E/WZqGjWrmhXt1OLdmU7NVPLNu0qNQ/i4zZqwccr7E27kl4jyBUPySfF5Ame++Fk4AUysKaqSjAeyZ4oeKzo1/BeanTlwcDV27LUEoymspYKSW5gEfWDmSQvgDLGiUUmYAizIlVsFwo5DjqNuYX4N6tTzbLzKvkSY6Au7GDd1b66gNHrcOsUUUK9otvHuhQF7aP9zdqnBw4Adn/91r4ode84+baW/PXTalRbeNP/LqCbqhqfVv0LO979CXW9Azie3pg8pp19R/v5ftrTv/m+GVpOIZ02ezI97exn9IK1yqPoIk5Gjz8srPzG8eO0/2vjfJ9OXh/ncTz9d6xsvHFUT4SN18CMrvJI2nys5csGPCh52S0rkPWPLMQVMS1ARlXxc3fD50izFggwvTU9FHBF44y1eBcSrVl++NGJS/7jWe3dq3VTp9ZdleP9tz7xo7uf+NUa2h3vqT+NtUawpnbw0xpJD0mEWF0wBn9MPMlcxmr2MQI7PqKEBtQgmN5BO5YKYqWV2oR+bBB7JGQPa7Af53jdJNossTgL6phCLBWKUVliGMeSiczxSPsdlQZul7DIKtaVYJEVP1sH09Jy+5UjV/ZtLNlzW1mkdPLsrtmTS8vGjy+bWH3bXG3HLevfe/yxge9FJk+O1Mzs6ZlZQ2u2H9pyNdrud9q8mW5fVcsDrXV3T6gqthQW3jJxcLX41NyXHr916o4FLfe3RMe5rTaLY+xN32H7yupd5VX2MGb1wKqaRNaPGkd9sp2d0TWZyQ19nOmT+rTcGFkVJgf+fu2quEaXJ8fSValC+f+thFXqYobQnFSF6um/V8h6Hf4lKG/I6RT86fGnkI6xAvmG8feYjdQxer2GzWBbjiMxMhErNllNmo2VCLL75AR2HFOiCB210pheAKlUR5OV1FwE2qU+plaCr+oF7dISUSchCeORWQcNFhcLyOc7lMIGpcipBsKMSgKprIvupo2OY+l49MVZMKs4gEO09nq6xrB5aF3dc/EHQrta//O+3/7Tze+vWv3Wyv6t81+tWDin7X+MR4S+f/9337/ntfVThvro2Lw1N92sbXJ1RmpntJXfch9dsTxc8PvG5nWN7c1bFu/cXV+1sGZydOy5jvaVK2/b+P6anSvatAOG7Pyi1mA0lb9cwWpsq8gm8M8xBZyXcYPtVqHbbtWs1m0MsNEYbrhVcsMtCpw0xplqMGnB3JbNkxcoZVxV6UxkF1U0fM1Zq0QRXAEmXBlc8xwHbc5sDJyi2vV/gx2Hya1vKuC9bsR1jDLiTmlfr+ot//FjBdxyW5G23Fb4qf290YW+zYusbbrBxulKCjP+atP5a8uoceSvPYze2lL0huNML4fT/MVLX13fXBcrrtUZyqDXwO77xgpZzkKD51gx7NCWr9fJjoCL88eVFFwg5/tYzR6u42d8HTgCn8d6oOSI8YfJZvb5UzDey8aPn8Jf+RnrNRCH4a/Cy/JTLA8KNh5rG/2anccjE2dHG3riCXrXyOi9Xq8mHyLZJIScaWP2HVDfmAgWgVGliBGcLrfz9bqvYrgGgdrADmCnoeU7Dho82TakHYvzoNGU4WPye0wOlsU6MYjkUImPRQRK6kpcXpYac3rcJBAs4rVE4WKmehhZ7W05Nr9/09oTk1e/uEs7N0yuaAOfH/jXb1dof12KxW0z5s4Vl+2aXU8LZnd3bo9v044f/kL76Ktf/XKo/3tvDkVvW30b/EvhVZrD5Re1sH24Pb0/3Qyv03V6ennUONJTkn1+epqeunV5HRwpr9M5PefI8jxxq05Lu/RavF+PKtHTxfCBVEmedmxUqV4aDi53P03BkR5ndEWFEfA1kSPicWkDi5W6rtv8Tv1ajMHV7Xf13ZX6R/8RT+SQqvvmzu27cyiTjU47Ta6vVa9NL8EMG7M6PJSX0rOael4iWKw/YeQQE+iFQCKFXLVjYX0ZnseEZUBUYKdF5ToOekwFISQRuzORmWVl4sjPynd8PIhtl/KDnITUTJZhjoX4ETJo6sUw18Y6GVj1Y4nRW+L21SH6P3t37VpA7uM/eqL89Lp1HRt+8/j/fJyGZ84zf1KwKeNjf3D6vM2bTi0C/LZVbt58YtEbm2a1X108OxC4aj5akns1YzH3CVntFqOJTp0mjo0aR5rgOrDzhvHj1P21cb5HRdfHea2R/jsb2fic67WYYON9rRYz1caTLsj8/6nFNI2qxXT8v9ZiGl7BtpCvF2Om18Vl3Zn0uvT6ZPHEyPpkQX/7e/XJ8A3Ws5xhZ2cPlZL79Rpa9DlZNV0Ybpy688kcDiCzi0lvNj+9VOJJMfNAMsTN3XJ2eJne1pHtwPNTvM6ECU8JY8jJZ56HY0S/EAWvjZ+HUjsiFpOqAAV9kWEftIx/s2vL4Bv33//G4JauN8df9/kHLeHNc3YeOrTzrqfbI9U9CSrRKiqqPZFx7TwIsJqum3TrT5/ecnRqmt8Mn7M+hXLwBjaTRCZllYJJiVvQ+KjWAEFg05SSE0uW8XF8VCszLiZDNHMMrDyEYc66iOIdUKuBE6vtWP+TDPKGkXqgjYpqoI0cBz9X1JYfKmIimtawsjJ0tjzeimoYU8dgbsSWz+2otIJExPBjLBlDetF4ImA7oVKVU2IQbafPh5b5H7iz7qGiXa3nV8z6/uzojlOPc/H3+LJXp249gQp1CW1mavYJ7aEFU6d0d0+ZuoCuiHaECz5qbI40RnakBGL7TlCtO12hUv+luQsWzJ3Xc88If4n7UfNS/hI7E3cLHZQ7gHuzALWH0r1qLzLZnZLbwou6eOaCGM8Pkqz0iPweiyx2EZ6xlvWIPHKgUeTn+WSysVQ02cHj8g6emcvgdhir53ako8mZJF2e6OJq2es2hFHTgaI7N2/9+nlzn3zy0frS0vpyybr+8Hr4t7Ossay8Xod9trBPXgJQVbGcpkkGqxCDilkyi2nzcxslop9ropqw2N5m5xHrSgpbErKjPwRsHrPTo/HO8eW5iU/5RZpdUREuohZ8R0+f8DMcpUXsDEfXyDMcR5zcKC36akAq5yc3ss8b2v7u5w1tX141mNOfF7bSK/IUWE8j773kPaQ2VouVOpWSDCQtI06lNNn0UykV0cHqVF01vJxKtznB2mkafTiVuG3UqVTfRBcwViNsFc/KU4CG3qG/Z3LrnS90GhIvsXOV2WfxO/Qz/Tut2lnxEt2Gf6Ofse9k6bLuE2GJcAHop5BgFjhDP7HYzPI3hGVt9ENXKOpkdjKqsGTHmR3wj55/4NlnH1iyYwfRz+u6ZOii22EOm9RLBLwKNXA1gG4XEIekTzjC8go8Uz4qR953PR8+4nM8+5D63MhkA6HaXlBC/ayPJJckhFRfr97Um95LEw1RoZ+dxyvH2Um7qLvCYofoNixm5xjeTXjjF4mpWQZWiC1lsew7nnOaxWrOsoymitRhhmIUs1mYjaHRhImlvUx4zmmmiR1mKKcPM5T0oxxoyIMlRniQYaDWKLrna9e0lbSALp+v7dogntm8+QA9rzV++ql+hqS8FeisEjPHTKMWg67ISp0hKckkC3zKwpgqAUMFAZIMNpAbYxyWHcVmMOz6At4qhunLWI14KfAXVgO58RhJxaWXxIdqY7XwGhndNoK+wGofuKRPQaq5pv3jLQubm3va6aNfjohpPzOX9mhtgkDf0rbP3zbiRKQvPjzaefQ3f0lFshcetRfkWY72jjgSCW13sU9sY3lEN1lF2MHGakZmLJZ08jKErGjCyfLMTjugloiGKB7p7cF2CP1csYTNjn+3ZcHf7Ta8tTuxBJYfRGLgEs4wKtnoHXVACm6MQwyJGKDNpTGeg6wNiG312+3b6zvXru3ULGvq19AqsY8u0bax12EkwRptDV1fw+VOo1AjHhMNf6f/mJ8hJ9ScZjxi1VYZD8i7gTfOCJx3b2G6FMalk/Ju8ImKyTjmF6XaB0d0D97Y7eVMpbRYV+EHu//xrsmBSFH0+HFqHtn/dT/rCWONhtuPVV3JGRcYq5386tLobjB5G2sSS/eogl7/5h5VYUR7Knu6oUeVdT5bo7wrgNUr/q0eVds39ajW/s0e1Vd66eJv7FFdNNQNRl1B8B5sUdV9DYAfcPs7Qv4PmyiAmwB42m2SP0hbURTGv3f/vCcliIiUN4k8HqGUEEIQhxKCSBAR6Rw6SIeHOLypdJBSHEKHUqSjk4iUIkEcOkiHIuLkEMRBpJQSOoRQQslcQgm5/e59rQRx+HHuu+eec8/7vit3kXojQJSwJI9Q0zmE6jdifw6PdIjQG6AmTrAqPiMWXxHJIZ6IMvfqqIgFxhtA9RDLC8YWa6/JALHqYlF1GLdJn3QQihmeZ63tccsbwJ/Fst4xbf0CKYn1OVLVJAf8Pub3D6QiRSq7gK5yv4Q0mGCuTYbMF/7FNeZa8NUh1yPusWfw0vR0nb1Lpq0+YUW8Yi/OzBjz7rzaNH9EnrOvI+Kdiey7GKkqIvETk+wVqXNsUJ+nomQK6hkSrpNAIFFnpMH8ISPPyRzrbzAthqw75V7RdPxV01PThGt5iSWxBeWdcoYt1uVQZq9Fd+c7zOspas45bV72qNdrc+LPoC65r65QUbPUnrrLNpbpBcRu5ocsokCK7j++cYYGFqw33neeOQDk46yeMyOokrcoyghTTvN7CL6YK+uD82AMkZo96wNjlxzrX5i89eAOnGvdra0P4/D/nF/PseE0vwffatnPPBiH+m9b7Rlb5L3T/r8Hd5Aj6mXX1odx6IPzi9H2mlhDHDxAZOdy73ofoP4QR9TyAyp+g++87KipOcwTG2viEom/xzhgjniboyY9yOuPCOVO5kvAd6Af8i00szf1F9hK2YIAAAAAMgAyAEwAWAC0AYoB2AJ0Aq4CygLmAxwDYAOUA7ID1gPkBDoEZAS4BSoFeAXWBlgGfAbgB2AHbAeYB64HvAfSCAoIzAkACXAJxAoICkYKfgrgCx4LPgt2C64L2AweDGAMtAz+DWYNug56DqwO8g8aD1APhA+4D+gQFBAkEFIQchCKEJoRHhGAEcoSKhKKEtwTWhOiE7wUEhRMFGoU0hUYFWoVyhYqFmAWuBcWF1wXhBe6F+4YLBhcGMQY0hk6GcYZ4BpCGtQbThu2G8gcXBySHTQdsh3UHf4eBh6kHrwfCB8UH2IfwB/QICogaCByIMAg1CEcIT4hUCFiIXQhrCG4IcQh7CH4IgQiECJUIuoi9iMCIygjNCNAI0wjWCOAI+oj9iQCJA4kRiRSJF4kgCUCJQ4lGiUmJTIlPiWQJhImHiYqJn4miiaWJqInMifCJ84n2igaKCYoMig+KEoocCjeKOoo9ikCKTopRilSKXgp9CoAKgwqGCokKjAqkCqcKrorMCvKK9Yr4CvyLD4sdiyOLKYs4izsLPgtBi0SLTgtSC1cLXAtji3aLk4usi7KLtYvHC98L4R42mNgZgCD/1wMGgxYAAAckwE1AHjardLVjlVBEEbh7xyGwd29GdzdbXB3d3d3d3d3dxvcnXfgloTNLe8Ahz3ADQkXkPAnnepKViXdK4Ucfp7yErLzMe4SP/o07+NaV4hv+a1zQSoxOLEi+Tr5MRQPZULFkBGqh9Yhq3JGJEpEyShHlDNKT6XiqRDTFxODftHFQulQ/gfd6jc6LZtOfU5NTL1LzUv1+pbr65focfQguhdlRTej41HNT49ClVAtdAyZ4UMY8uuFf5v0ZN7s8m9Df0xCMraSJqd0ueSWR175YicFFFRIYUUUVUxxJZRUSmlllFUuNlhBRZViF5VlqKKqaqqroaZaaqsTm62nvgYaaqSxJppqprkWWmqltTbaaqe9DjJ11ElnXXTVTXc99NRLb3301U9/Aww0yGBDDDXMcCOMNMpoY4w1znj/4/8TTDTJZFNMNc10M8w0y2xzzDXPfAsstMhiSyy1zHIrrLTKamusjTdnvQ022mSzLbbaZrsddtpltz322me/Aw465LAjjjrmuBNOOuW0M84653z2Nrnksiuuuua6G2665bYsd9x1z30PPPTIY0889cxzL7z0ymtvvP0OVRZ+fwAA); + font-style:normal; + font-weight:900; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:italic; + font-weight:900; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:normal; + font-weight:700; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,d09GRgABAAAAAFZwABIAAAAAlSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEWU5BAAAG4AAAALkAAAGKAuh0x0ZGVE0AAAGUAAAAHAAAABxdnq3DR0RFRgAAB5wAAAA4AAAAQgSqBTxHUE9TAAAH1AAABSQAABJK0WkEYU9TLzIAAAZEAAAAWgAAAGCAB3qEY21hcAAAVLgAAAG2AAAC5lCJVL9jdnQgAAABsAAAAF4AAABeE24VbGZwZ20AAAIQAAABsgAAAmUjtC+nZ2FzcAAAA8QAAAAIAAAACAAAABBnbHlmAAAM+AAAQ6sAAG/ITa86qWhlYWQAAAPMAAAANQAAADb8cjuWaGhlYQAABqAAAAAgAAAAJA5zBZ5obXR4AABQpAAAAkcAAANsimglbmxvY2EAAFLsAAABuAAAAbhv/4p4bWF4cAAABsAAAAAgAAAAIAIDAsNuYW1lAAAEBAAAAboAAAN+fZC4DXBvc3QAAFSkAAAAEwAAACD/DQAocHJlcAAABcAAAACBAAAApHPubIkAAAABAAAAAMmJbzEAAAAAyRrF+QAAAADK+niY/pAAAAPGBTYA+gCSAJoAygDiASgAfgESASgAtwCnARUA3QEwARcA9QEZALMAsQCuAPgA/QEFALUAoABCAHsBHQEDAQcAhQB1ALkA6gBZADcAOQA7AJAARgEbAR8BAQAAeNpdUbtOW0EQ3Q0PkwQSY4PkaFPMZkIa74WGAiQQVxfFyHZjOULajVzkYlzAB1AgUYP2awZoKCnSpkHIBVI+gU9AYmZNoijNzs7snHPmzJJypOpdWu956pwEUrjToNmm3w6pdhbgnnR9tZGRdvBA882MXrlu33/FYDOackcNoLznLeUho2knUIv21P82v4LhPv9kHoNBSzNNT62TkB5CYL4ZtzD4ntGsu/ykL1gdLgYDQ4ppKu7ycyrlf0tzrrYIm2sZvXZwJiI/mQZoaqWNQNNfOqR6Po5iCXLZMNYGE1PWn2Qi+GYyXdVULTO+dXCX7Mw7WKNKc+AB9rBVHoOHw4MJhfQtiDJLQ4S92CoxQsQkh0JOOXeyPylQPpKEMe+S0va4Ya2BceQ1MKjN0+y/zGZT23uHMH4RR/Ddb8aSDj6yoTZGhNiOWApgApGQUVW+ocZzL4oBudT+MxAlYHn8418nAq07NhHPZW2dQ4wVgp7fMrf8suSuVa7zotDdm6oaqnRK876Xs+/xgKfHwnDQWPDm876/UqB2h8WVBs2BYEgfRh//aC074irvhY/sGWQvsSoAAAABAAH//wAPeNpjYGRgYGBiOProTahXPL/NVwZ59gtAEYZTvypmwuh/Nn/PcHKxszEwM3AA1QIBALQpDqUAAAB42pWQQU7bQBSGf5tA1UUjxAp1NYsuoAJ7EhQVeQeIRRZQJCrvJ86IWLE9lj1Eya6rnoAFF+gZeoOepcfo78mkAipU1U+e+ebN//55MwB28RMB1t8n/msOsM/VmkO8wWfPW/iI1HOPmq+et/EOj553sIfvnvsY4Aergt5brir88hxABqnnEP3gm+ctfAkePPeo2ei38T7c97yDD+HQcx+TML0w9arJ72ZWHGSH4ko1c3Gbl6ZqTXUkhlKOInFWFMJJWtHoVjcLPY1uGrPMSyWuzUKJc1NMxdiqIs88dj4bm0Q8E18ubaMmlCXO/jWjVDdtbioxjKQ88aJOc9xpxnZmbZ3EsV3Vep7bKDNlrO8L1cby728wOp1KXMCgxgoNctxhBguBA2Q45HwFxfycdMvdksoKrRuPmBtCMkaIyGcoGOKJS+tWmrPmvOA4pfKGbLB0boqKa64Wjs5JBTUCY1Yrcs4unmc3/bzsJuH+686XzFruKky8W/Kk+//tKHX3acndyZ1P5JxOXjhtfI7/+HQu3ctYvneCmGH57jX95qyx9MmoLJnXuGeF4imx8/53DHiTU54hfwMhKKdBAAB42tvB+L91A2Mvg/cGjoCIjYyMfZEb3di0IxQ3CER6bxAJAjIaImU3sGnHRDBsYFFw3cCs7bKBQ8F1E4sOkzaYww7kcMhAOWxADjsPlMMK5LB1QjiMGzihmrmBopzGTNobmd3KgFwuIJebG87lUXDdxcBZ/58BJhK5QUQbANv8LzcAAAB42mNgYp7AtIeBlYGBtYJVhIGBUQJCM+9iSGGaxcDAxMDKxgyiWBYwML0PYHjwmwEKcnOKixkUGRQesLHe+cfDwMCuxZSgwMA4HyTHfIzVDEgpMLAAAM6gD3kAAHjaY2BkYGDX+ruAgYHT5J/N33ecXAxAERRwGwCE1wYhAAEAAADbAGgABwBoAAYAAgABAAIAFgAAAQAB7gADAAF42oWOPQrCQBCFX36UNELKlB4hRlTsvIdV3CQS2OyGTFJo7y08hMcRT6IoxB0RTaHkwXy8gTePgQ3AAuuCw6396t7xzivgmQnZuMBwgD6dlmtTvPLgv8/+yu8uYzO7R/tb1icWMMzzlt37yPk44l6X/dXpCQciIgERU4pE6QJZFQvIfBtDqqaA1ELCmAqaV10lCiU7imUNylUGKkQJonDCiBhTxowxZyxAzYYMSkLNt/u00ngCKktc4wAAAHjaHYvbCcAgAAMvReiPE3U0Rbfsy2l6lOMgCYQAVQ/d2AlNO8M2Oc2XhJvH5ZWwJJT/wQcPXwnneNq1V29InVUY/917t/n3Tp2pU6duzrnlHCxizUwkTGItCfFDRazIagvq5ochIX0YEhHSBzOwgrj1IVaIX1qxHMTlUk6Wu7MSIbMIGXHxwxgRsg/7tKffed7X6/veP++96jwPzznnOX+e8/w7z3te+AAUoh6t8IX6BweQjx0cgQjMjO/Ns+fNGCyKc362ARQjhB9Jn9LVZn8TWgjH8Qg60KXgQ5fEtV7Veknr17R+R+tLWjeyLuT5x/AQHsYJnEQb2hHGNMefUf4+nleKgKwgn7hfJnFCunFSBtAmX6JdmvAWx8Nsp4lX2b9OjBFvEOeIvxN95jT4Sy8YnsE9u6/xxEPUNCTdMoEjclriMknqMxmVc7JEaoG4RLlzLnLb0Y/LbVmWGWyi0GLAbu3uNhQ5xSWaZk12TgtGpjUdZEoixHeT1iyT+3xuksqg5+wkMUxc8VzlmqWF/5EYYyGNdrnoyAhw07ckSp5huSQjMuKaCfOcaAYuLff+kxhw7zv256VNBqRH/Gp7Y7NxGXesvWtOySJVaaJ3hzySYkhCxD5KGaVEy1niwBFbjIP5DCvvEGeyWX49JujxH+woXZUVs8to5YwJj/23pI9NvmNkUYZYzxpgS1tJJ9F4oEMuy0u0/FAGXnPeklpa5aDTXXMiahwjMRljZK8YNJFP7DHn8XaPsDZROpbe5vIBmwccIzdlRm7qzKrNaVh9MUUN5+RaJhl5ciXrfx0jI4yqqIlLE5kyass0IYWSz5zTJoOGTsMpjvtSnFFLr0zIsHQ4b+IGuRV6zp7OiccnrpzZoTFTmc6/iV4E21wYOc57d570JL9YW+cbzp5BM2dWOyPGLdvSTqP81nnYacvSZucUwrC2w/zq9xLeJ1xIWdXLDN2blMnNWpfFXdQQ79tY+puQtrzhocUU7VSadubihqzxNW/6HF8czrF5Z99k4Iy7X0j0ZqSTt+555oGYRtoUqXFPy/fyW9Qui1v3qO/xlEzX6qlzpy15/prsOdgpwowbsyI9aaZP/sr2JXdmIL7EvpCLmtU9v4s5yDTNDB41eXszuWBLkZmZ7yytv+x+n1gZmPEQ2Rgn89VP4RTX2M+isztmVaaVtDKN5yJTanzoi2RGX1CRzd+9DKct3rdM173B9Zc1F5zzugXb9Gn6ext4+vg/9wcabKqMvaNs9xDrUEsEjrjWP6gjlahM4uInH/DfaqfSxdiFPO0FmD8CKOA/XhFHg/yjOYwS/s8ddew+iHJUsK1Ctf2Gq8E+e66cUIP9OIBGrmviP1sLmtlb31+Rk54HibVJY/VJtD9lV0BxDax/XwtKlHaWKkpSZcNa2WtrYAEUrdLMfrO9ryRh/1pCgw11fIXW6Whris/8+JPS+xMnm16D2r6CZ1aovo0O3Q9ouy9hVZ/KUk8d6hWsdodNWbTBXfReHn1XQH8X2a/iNVmrFQ0Uax/0EjRu6khbWEt/B+ntEvqwzNamwdNPbh8EbRu6S7kLAgmpneD2Wp4NRWlOrLbRWepUr/UVQRvK9I4YjtXk5U94eS/7FlTw7lgR2ZTQp1gtVM1+ky1RHi3qI4ci2jxI6+wk1zLa2nAq0OgvpP8Oce4wb1sZo/0YNT2ODvqhC9306JM4xfh5Gj28kb04wxX9hDYMEh7F24R2vsbew2P6LuvCh4Qn8BE+5u5P8TmewleY5M5vCM/iW3yP53CFcAYRRPEifiK8jGlCP64SXsHPmMWruI4YzuIGfsHr+BW/8fW1QAj9D6qBdvN42r29C3xTVbY/vvd55NU0TdI0TZ80TZv0RVuakj4opRQoD0spr4pYniICAmJBLLUgIhZEdBhFBhlEZBhkOlw9J42IjDId5DLocL0Ow3QYf4zXy+XnANfxasc7I9ie/tba56RNC/q79/f//C+a89hJc/Zee+21vuu1QzhyrK+WXyF+SniiJ6VEogUhvUgcQq6kKwhx7IpKhgKJdoX0JpIM7XqrLNDcEGF3spHmksIRotvm5m1uG7+it5o7VdXbGdLtvnlUl3zzKiGEI9a+a9wMMQDPiCGEemLdNN07sjjgL3LGOXR08acHaJEyY/TdKyaNnr2MBvmtt4JzKictwxdhf3+F+4JvFqeQKBKPf28vqaTsb/V4rX2Pnju1xspxc6uLJll6r8FlI15xX9DnsybMmzwyLVmZr13ac/A74Z+YDn1KIsPIZBIUKcmVqD9o5+Eco56DZo7kylaH3y9H6a7LzpSiopDeIJqjc2VXMjTqoZFLLCqiUlqB7GaEcHtiPTy8Svzs5efZS+/Blw/e4spPnTr1zjunTs85feL0rHPv4L9TnWdmnTvxQcOHi0+8c5zOUF6nMw7R2oO0QWnH10EldAjulRB2mQdalgqf6AjJIYWkhHpIMBZ77PDLI4XrwXi4plJpgWTpkkcYr0sjrHIuzZU9xutyGc2VAoknK5u++pbE5ZosErFKcZ1yTvRNydkJNx2UxMXmdujZ0YBHscOBJynH2hGf44zNPVm5oTsZ/jaqIxlvO1LYMZsdh7NjPh7xu4rVvx+JpyB8cdqOtB0encVmL5P0ZZKhTCouC8If4n1+mTS8TEopk5LLSFU0oXpDnDM5JTtneH5xfuQ/WmXFNx1xznjt7ZH5Q/5JVYlU9uTa7FJiGZFjR8JFQhkwZ0k+9ZU442PzhZHFldwoWuLXO+P1Xh+fKsQ5LFwu1dNiH19JqcMZX2KhtCVv68VKaemJmoq7l1bmTnri/WZD1qn8i5ukGdurRs9ZWpU7eev7zRYvtbeUz2lUDldUBKYsOXcmqXn6R0+PoOXxWWMnLh0188ctU46fL9p1bn6+cjU+G5oqGo9snCxxVVUBpVs3l9uZXpz4DZ2ObEj29F0T2zX+9pARZCRweVFgZLHXk66Lg05Frpah7dpSsFAj9VB6464HZ1TVrphR+tTbf3zpqbcv0WNTH5w+ZuryaaPa3nngZ4vxQDO+3bpXaOHrmuePmvroglFT9/9oY/vH+Oq9sAFum+dX1O1/aePDHQvZQay79QEsE8Z7pr5rwgfQz2zoYRVpIUEKqyYowEHO0V9nnChX6q9TaWyBZOyS/VHXJb9VtgIHBuAyYJVHgeCIjyI2EBzV2Gq12TsES05hRnyZNMr2JuViPXnD8CbeLmdmlcEs5lCYRa5MqrS9abTGZxWWwruFI7KpT+dJz+dwPktU4qRSIIIIE+uMD5TE6/TOzKISr8/rs0C7M9YRX0lVugkrlQulr/103r5Hq0evfWxm+uft8398X6K3pmLxuJKkglHuhyYc37yppvfCzEXT3FOc9XPWdDlbNo0eMWbRlMU5M5+eO++FB8YPe+i+A5dGbbp7xOwxFb68hNjS+pWB5tamNzesKit/ZMwzI/IemXn3At5bMSmncUpJ2f1IO4oyjDOzOc4kQR1KFx1brOYCie+SjVHX5WigiJGH4ZIykCSRoo3OuE2egRCjJF9p4rrEucQMD9B7uZFWAiPnbA7adqJuBs1Q2s5cUi6vWEfHvkFLuQf+9/bPey8olz5i/elrgb9NV/82tsRpj7MSvS9gtxV/cGLqTOV/9W09c0n4csUjyrvHlHO9L8GfcvnUewGeuZe7zLtgHDbggKARx2Fk47CjjpCJ6Tqsf9QKssl0XY6FM4EZDHKioaysTDYZ4TrKYoNrNsQSva/EVxIPC7IkXh+v99GLWyovZnS1NxzwboaLi+1z93OXry5sqm1esv3SlYXr6tYv2Q59mEFO8d1CM9DyB0QSC2QqgDTWgTTWm4qKgqLOlNtRJXLGXIkvCupEvNMZ4M5YhORGOjNJ2NrtRUko8fmSMV/irTJnuSkZrbIBThzIQ84Iwoy3dgi8AQUjHrHdhO38W5TjBb3BaIoQPjgkN0h/d4kbpL6b/1DZO/fYXGVvOl3W8HoDXcbNUlbQPQdom9KizsFl5RZtpPnESkimQ6f3VdIST3it08ajm+ZWNDmd/okPThh7746Hr4yen9Q4YsLoCQ/cjfyUTpu5Iq4eVmUsam2ZM8C6EwpkkekhCn3gOCWtkH5Kmy/h50EH01nwrCjQd0G4zw3pBBIrDHCgkXEg/G2kuDmsaWVXhEKmfdv7LvFzxfnwbBLvof6aU7y9M0tsY7q6AWTEeeAPC0kl49UnyTGgmgwoHOIF6OQw9rxkUE/JVtkBHBIFj06DsyPZZpcNBJd9fAxcRvFlKL7TychiO4o5EufgBF9RJcdWsoWDhc2V/kn5dvHPv931J0p/ovzT4fptswtXrmFHF01WXqWFN55V/tz3R+WJ7p61od8u2fjDtR2/vW/jC+qabAKhthKEm440qrJMIv6giPpUp56ppC+QDRq/PNU9jfELzZd0+RK1yiTmpkXSAd/E3CQSrI8OQjldWBERmAlYyzyTVrGij/q5GuXqRaV7E8d9w5+70k6PMFp2EyK8DvRKRRTCqJUC1HIgtSzC9Q4rcRhyGc2iumSXRihXFFCHpCKhrCm4uqJcuLocoGAlm/rASj0jEvKUJhs5vZv/pMdRvuHlt5seqxmd0Lbi1HPN9/Q8ufPa84t++Z8/5dKoYcK9q2vvmVA7wTNxdvP5qfc0hFoW/aLj8D2sn5/BvB5ksn+51k899DNFm9WQzUxSABfZoMsJJAW7nFMgmbpkHwh+R1qXTU6DviMWcZigkxnQc7Mees4LPux5AoEBOTLKQPDbpDSAA6jCceozfCWpMADQeTCWWKdf037qsFB7Uz0OTuDy31VOTT5V8b8eamr9en1eufNw885nHvvF00tn/2XrV3TYqkP3rNmudLl2bzk2f9kD03eCyuKm1I+btvL01Hve/knDCw1Rybua37iO/AvIUGgDnjCRaPLSnbkixEVTEQarjwKxwwnXJRMIFkuBHKMxyo7uZXdmFHPMTRHuOzhqVnGSnuhAtJjwiO1R2M4TyZxP30Je0puizJHyRY7mgHiCOsPuEhA2DFZSfqFytaJ3SykXonuD7YFjn7UqydTxDZ/Tc+nWLS6v9yLMVwbM38cwrmGkTps/HcyfDefPgQxnQzHpiDHmhsyw+GB0ZhQoaUyRJ8HcIb6VzTpQ2BxvTWI62ibF4SSl8eE5Qv2q98W6gdPCGpnj6pUtr39Q8lZz046n105dXXbiAL870Ns2fuWBVfLK6T/4rYuS0JyFG++dvSAzdwp3/pZytqHhjUeWnther2L/OtbvKdDvPPKQ1vM06DBqHRQsoQQvMUJ3EwzXO8zEiJw3nAmYHOC8HKvsAZ4DWSPnIw7OsdlDxhiS4MT+J9skM/ChNw14LxlEjWwGLpScZbIRhI8UFRY9lbw/LV6fT1Hi6HX6frzlC/MiQjFu7t+Vf6/YcPR6G008IhW8NGfixsZqh85cemrJW/+xu+/FVS+88NBTq7gdLmr9esuty0cWHj9XOb50QdMYc9ao6e+/tvOLnT1PLZq2aKklsHKzKptagQ8vMtmUHsZZOGIeJagqlIgsIFrQMXZAga+np5WT3LneNQH+Rp5QcessYrZkjX6pYDEEyCqNgrlAQSt+XyZ+X0mBJHbJxcbrHVHFoiFXzgLSFVsZyWDqpXRcv3FAw1KK78EzAcHn294k1sxhuSOQlEl2yQWkzATs/aYYFZc0bASDaSKDaAHA3wjUgCNAZOvYgrVQPgzIgHo8I6UK1bjylb98ae6Z1xua5r305qLFx/fMPbX/vsde/lv2+l1ti+998tHYJbs3zt740x2u3Fk7733yn/N8z86Z90JDXs70bbOefDd15P55j3TM4QOGuyeMmTl7wsiG3n+YN7lyvkO3pK52BuOn4r4bwimxlvHTg4BgwvqJ8CpjAT8ZicpPjJOSu9B8kjxWgKJA/iiNk0BVAfdIObZ+fiJyjJHxjZSAjCV5kZekNBvjLdDIqL4svCdNlWiAWwNga6jqPiOekcFfVIJ04IJ/p3GjNvzsxjbl2uHX8/c21rQ2jouzcOXvLHnrqz2U7AZmWvX0g9wOsVb58usnbwI3hT4YM65kwZqq3KiKGb957Zn/2NmzbcG0RUuAm7aQvj6m+6/xXVYf2N+7uaNWHdrhhGP4A9oBEyQDy0Woff42NFKqAYGMQaiE2xXGBb23BgEUSmpJSJgibAf+JZm0hOqNlF/TczmHv5jX8w23JUSfO053nVE+Ui5C/7z0ecHFH4H+dfV19VVa9aSLZJEQ0ztfkxBgPfY9RloC/1P+g56cPN7U25rFZ3DVStMZmkcLQ8oaVV4c6bvGXwF+TwFNhagYF7CmM9TBWcQ4Bx8xVq78Wnp9U1P9zGnPLG8OXu3464hpCxZMG3Eq7I+4VFVZN6NlYsXEvBFlC8/sObh90tq7Ro8oGped3nurHxVxZHXfOlEResgYchf5TxL0caAvsvxBD5xDNXr0o6htpCA0SnWwJBdIcf5QFXtPyi+SigtCJs3hUosLMlRqInnwVqlVHgZ202RmN0mTrfIIuIth78lTNZXT3t3HVI4v3yJVd4pylhU0TnanVG3t8Fb7QMeMw2MQjhGmuLeMdHizq8cx8/pNry9Lu9Ys6RGTbfa3SJwp2VM8qpIxePIoEJWjK0FNV9nAtJZqYLXH5I4oHRax2u2BDHWhA6+newuoxuNMbALQ51VGBz4nnnQBPkaA6+N1fNEYiiKWydJrbZ+/tmjrH2nGSzu/ePXeEfXLVgVm32fiRu6b/oPXnvhobcOTbueVpbps94RHlQu33lZOvEeru3/5Rs57//L4giLHjIp1B+fuXHT02pP7acbFzYtf+5fWRUcenp7ZUGme0vDO7i1Xt06pWKG4MszDhx/Z/x/Ud0Y5eeJzpXN1xSZ6Y8uN7NHyw9MW4drYAfL3a5C/ekACzap/CEwZv5+ZbZJePYd4k6iLzpUMfhTMEgc4IKpANquT0nn8b4+FcYBexQE2mBU9mEe2m2IHZ6ToacEjqHwjzACofLAoIs0JsHNBmVJ3FKXC18r59N4zbcrrfA5d8ny9ErxyRQz0HOEqe0+jnHcRIhZCf20kkXjIi6rOkD0g2TiUbAkg2RLTKQeSLRFFfkaBlNolm0HQx6F014F0z9R46fHukeFuJ7Bue+w3pQSAuXDyWDsSPQnQ73Q88mCxJySme/q7LMelggg0Aquke1QBmWiDWylhQE2xNafqAF6V+x43Hxu+4L7szaJebvtr77352D0PpE1c/oo4v6GuXHm96ut5q6aNU/aPFwMn2576jTl+37zy1cumFvBpi8ePnKh80tt1/+TRdykfMN05p++aKIGMTyN+Td/B8IMmpEMsDt5dIAldshPGnI5qNDYBYEGMYE1O0fg4g2NqH9g4XkSuJCrPlsQDnLl2QvnDG9OfP/3n1vXndi1JVb7wSY/8UvnLh+0NPy/7eNKv33L9kMYGd3zzix0TKx7cOq1xWZNy6dIr/zSrZve85uEon3CetsI8RZMEMk/tnUT9rINsolzYwcQCydElG6CDSf2TEghPiotNSkLMTcnFbA8eTFVXQj9GdCUwBa1Rm61EsJr8qtmUS3kuo/drILHw0EeHFpU/9Z7yh2dM689smfTuC9dOiIGZL3y8adVvz/3o3lvTtgWXvPBezymkJ/RZ+AL6HIXYn/GVKdxdEfhKZ2R8pcOeR9jXW7qrw10WWZdN0GWRdVkyWTt0JhH4yIhH5CNRF7alw6xPEUeyF3+up556eam0d3Ult7W0t7Wae14M3FI+u6VciOyfkSwbQOx37J6pQI7Sure5u3xw98hA9wCa6wjrHmHdI6x/d+4eLVauDuqc2rMwHx4EPvSQKRofJkbwYSh1GDFBx1K19QgQLF5dhkRORCjqLpOHwXqSxXiQuLE2OcZaNlTMqvzJgJMfRCiAQF4ncNe2fyk/0PI7mvPzB97atniYcsv91prHup74p58/35yhHCjlNq1brFxzzXrpyrYj1PPho4EFa6vXzHzwqb88t/+jpQdv9X7zyOMqBkVeVef9uIZBiSD6QQaamP8K7R/1OmTgKQxF4vyyAeTgEEfLxu4cRmmRyUEgsQAkBjGoi7k5aBqi1GkAMRMFzAInZiqZwDYSrB28oEdxiUdsN2I7X2Um6IcRdeiJiRriCyaqmcSD/OTdsW7hnHKltXdHK84WTW7i1q2jqVxh70dioPdrzhweLzeXxSnqBvORxKvnsIdlKAPx/QzEa0sS+zWYW1Q+ocnMmUr7zgIu5+A6hiyMsKej8GFmPztTyVog2/oX03j2sChQ8CZQ8GY0KaM7iWyKBuXdAYZi9IDnQU+Y50GKsjFjUUz3amZ0CZDDQumU9R9V7ktbO27B+vgzNPnMyG5X7ZSLI0Y/fD/f2rP5L//aP/e72Nw/p615nHrV7NLptatB09z0Ve//bZqjhswk2P/6CEBiAMXBGxCMqHM6AEaIbFQdwYyWejanQFLhOSWofLyjUaXsJq6Gru5dwqVvV5bCrJ7hKnqfC4+FPwBjEcm08Fg0+TUwsboCWa8N5MnumsETK0RMLPLb4IkF+bSsR8IOfMEViYFvz4SfqbsKzzSTn6vP7CCCTp8Rr85t0GA04+JR5zm6QLYMYSo9zLNoFTX6ITUNQMbO6/85hr0t5Ms60SCJnRbZFHtTlIydg/jRHF5JFsnMFDcJcqKJRVGigDO1BWMeEjtRFwz1RAFl3bHULZ5SrlzsDbUevsjou3UHVeg+/nRPJb4Ae5ziqwfkxDUmf58gajiA8H7VVwJKzB/2pUUI35buVG0cFomDYQpWmbej21UW7cAt67tN7G1DvkTyJQMgJsdNjFjJesdNInP6fHSQ4MLvx0sRI6DIHbDwhdPKF0rtOdb3DHr0NE3mt/aAdO7Zzy9RbQWUz1+AfLaCtRD2VdrCvgXmq0xlYhmN4CTVVxkNEnoYurGSQDAbVV+lDS6jxQjZDKJZsKvOSqL6Kplle23HV9L9v6H3XzpBs17/QNl/rpNaLh5+/OJjF12zX7rS9gf6wEe7lC+Cf1D2/raH5nT99Nfb//3ZI2c1zOBgmMFJHh2i4ZygSKItTMNFY4/jCyR7F8NzrtvllLNfTjn7FR18KSxHCx6Zoou2OCM8Tk6LbTB2A1gPWkbDa6pM46Z0/NE9c8N7zUowQHOWP3nvXcqnYuD3L4/Z/NTSqlvNc6tnMVq/zmjtIF5yt0bruDCt07DnPkbrDKB1hlVO0WidBeeUDJsdNLHdiq6GaJtkA6LHgYgLWm2xZWXMxr4j+TGioPMVYYRBczbcYR4O7qy5WtW8Lr+o6cqKCdPuMB3vKm+vXLl6cVaP6cTqoxPfWx2eloh5scDVtkgpqQu7RXkXBftA9dokFEixXczZndgvaCaHJWZ8v8SMV1c8E5TxMDMuPPJMIsa7BpB2VKwaKZJd6ASyMHdcFJsn3oMLgLnfwIr3h6G1UK+cPXB5GZuw8lUnH/nDTw8Iqx5fMl65Uk8/Vrxi4J431gT7hn3W1Fg9R9nLdJSi+fKHk/kROgqDzCpoyWe85oYZc4PChpnKhsEVYOzHbbO/SfSW+NRMnLNsm5RUNqCWUm0dgj0pW43z3ebozRdVZ5GgOt3AIkwVmSNx7q+UXzRINX99evHSiWt37Fg7ESOzr9KEOdLEj1fd9cCktc88s3bS5K3vu7av+Wh+07xRmZUFI6qmb6rDUOzDD5ybeff0kvTy/BHVMx6vw1AsjCekzZ8+rBdwVYXdbCBmMLRvKMBo1lC9oO+HKnomX5nC1w8GHiUADrkVypUvlJZSISugtAgVt24xebkV5E43PNdJntXoGq354wBU2VAvWJnAjEdHpiQWySYgsaGof0Vv7Z6KHRGAcURJ1ynIBgfoAD3ogGe717EuWkGuxgBMsKHctHeSDtEQY1ftfJ0+xmqzR6pWa7QWqBDTMkYWI0bQxcFkpCWBbrPw3Dnlz8rvYdRprxu4H22jjvESTQ8mz3vhsqunK6uIT+/5zJWz4jlazif2fLr59I+nqzpBAv2XyPyXXg07Mhc6NziwokVJVJc2j0qH61b2f0IDu7gZdAYoU0Xg1O97hxC9qk8rVR2DcxXFML4hQpGiCEHhB/oUNCT7aiJHCRgk0ZvKytTnMEBI/ajiqpULaUqdcmEOLXXQC59k0VO0ht/dsxLURAV/Bl+wDgBFiB8zLJQ78GyjFhGIxEEAU+BRMmfof5CRaVIqXFBOdSuzlP3cFuU0rf6YttGlvYdw3XGnuGalhp7sXdpPN/E8PMtA7hngSZ0GVdSQsbEAF5sGC8dpLAl6FOabRRoMAAs5hFHIlIaBedYhqUU1eqB2izuqXG1WjtHiLhj3rN5ZXDrv6L3GuXo+Z+v/GthV3zC9nq9JN0D3qloXBqwpAhPJsBlYW3DWsweUqA5pN/9pjwF4pHd/gL9R2PMxt/4zvuHW1Z6j7Pv3K1u5D0En6Ekt0ew13XWJFKBBrNNdH7T4WrrTBptrujjVXItjoEzURQZhwTbzUD+tVerpFip5v1E++EbZqjvXfmsno/GZvktcshq/FHlggyUHTxzMEttutUCfFkOfnmd9mk3Cvh7WLaFIogUwGTIHN3zRHTvHM8kAUJE4mWQQnCgZAORGdq7ETz0lbmpVZni/oYFvMqikbG0X17Wr81/L7eOb2LrBrKTviEX+alX3C+yBOph30ilz8WAsdaIs4fLzhwYiMdDOU6AH3xRcobxzlp4/ye2jXyh2bj+Mt6FPx3/ZJw3EkXWRcWQRLcpz3z6XJTTdamf9+0CYw20Wm5F2+J3c5qDSc0OYQ9OYb/2asJn/hNhIKnmXBPVU7b0JOcdluB4U0AEq+oME86rsWgMLbkZ3yXFRLLjJ6Hnir+M0FMysCZhsgU22INzEuH0WMyX0oCH1ApoS7JjEjsl4DEJLhFmRhMlFIOBIB29ISmZS8C3VwFDvBlaI3QUMHM289c54GLm7RKd6L7mwhx5MqHzKFS08XAif7+ojyY+9dvTc+I1nX2k5tGHe2HXZU9yP8p/UT9rcU96863fvPnQpuOrKr59e2lpZTOuLKhEz2IFGjTC/dpVGLO9M8KtaIBZIEuleDJqQUCwSATRydsnRETRq6545xNxyqeaW6zvNrY4kdky+g+mVzMhk+C/QKCFWoxGalbjMeM2vzvdHxPhUyi2879XCZIV6lZWP/eyn7+c0rH/t6cde3TDv8QVAIRcQSAworl0X35nz+isbJjESrVOkogp1DZT2XeO7gY8SyGhNPzqAMnokhsWgusf4LtkWxdxjRHYgrgAwYbEF+SgnIkK9XTKpsEKFg85+LIFBlniAy/Y/KL0vUH7/c2eLT6U+OLat/enlzTN2VJ50ffXrl6l+3wN3P+8fdWbniuaF7WPv1uJG14QLzL/6HbzNq7yN534GvxNvP929+Lt5+7Fuz/8Ib8eCiPwe3l5JiXLpO5mbfnnrgztyN9IJ5k5wwdzFk2FkZdim0muzl6K/HnJFE310bsilIzUY6khjc2mJui5ZrHICzQ2Z1PwwNyjwBBhih544XAgVTTbZHIf2lg2nO45ZAo4yyWWXeVPZoMmOc+jd/R5bMFvUOCOX97+Vr35AuZff/U9Hb9Gzj43dlldf86byPr3atHLRC67r7++nxldunG2sck18wpv+emEx1+CYtvYJJpOZ/2AKiSPPDOhkZrhY9JpUs/tl3gCYMQ4xo7NAjr/NCWoBpAYK2gUK2tappQHo1DQAO7HB9MbhkQc1bYNJPI4i3GaPi4z+WwTVp25Ukb6b5ZmyXNh4PY4whvphPU5RDh8sOmBOP7HvJ/duyqkuq44xny06w924HNhzYv7unPE1RZcxvtGlNAubYJ7SSQH5FQkm4SCS/cF4nKYc4OckNVgl6/TXEdx4kJkLCyRblzwcmHmENrx13TwbXlI+wg5RThZgeCmdYLJ3GA1JMKhEdvSyow+PQWgfFIOSfGWYr/mmwZiY4vVpyZ5vwV1Scv+9FpEabmNAVc1DgAs5h2gZL1QLq45h8aZ8zX/PZLhFiFU5W13/9Khybt/u4T9f/HGpo2zv3XdtfqA8t2H9q41zjhUnU3IufvYDj28oGL0ue3z6xqmPvLRBaT7aXjn+1pwJU4ffu2/pnGN7mqpn1GzuaV1xeEmVi2saPYLmlY05vvW+R5BP7ICXykFGxJFfkGAU85dSE8J5MwqHaPUctCKJ9UhPJ4tDxAI94/tz0rI0N58Unc/coCAcoq2yGYXDM90rBoM95KW4TnSmG03RaMTjMQjXEQS2gGjgjJY4NYfWBGxlRGehJW6I70fWY2A/VuWrsBwfkO56/oCyyTS3dk3TLibU9x195icmbnyWo6qiqXc9CHP7nrY1qUWqDAA6cKViI+DlmCFxZU+sn+4sr3twzKhpK99RuhQhvzYwdcFdJVMXfHuBR5ta2a40a3/rGvy3NN1XgtI71o8uzPCX9J4LzVmRN+NRzyfKJ1554OtuTZlxvPQAoM806RQJz81OhuH3DLXU+9WtkdMOg/yaYYH931C0/29+TT6GoTSAr/xp5XxwTwAp/TrtpOOVNNqyBZB4Tzc9oEwJj4cL/H/wVbtUl6brNl+1G5GzFR8N386eo2sEOZFF/kPl6RDwtCMOHZlOFBFwTsSzxy/bDNclfRFrplI2420v8HaO1odN3X7Whzjm7Yizyg4X83Y4kY5Pdy/q92+bgbdNKEjQq6kJUHGA6/GdrE7JYe2IdTAHCR6DcB1BcRcIFM5ojnVlhbPHLRrnx2IGebh58Aqw4QoAgeS0SW7VSgqvAzdcoQDRIwPrMbeJT6HawhA7+8gWQ3350iXPwYWJu2vs4iW7gLWTd+4LzCvPte86tfZVEzep0DpyzJreddykIkdhJVzwZzftScktyjILwa1NWVn9PFoOtL5dfnCq/AiLDtZwJ/kRpvGA/HCp8gNpHHa6/g/KD5VaTH7sVzabZo/ZvI7RRhUfVcNjx4zWaKFKD44EAD+MBxpgfDTsk7WE0Z9jAP3FA2IA5rGht0kFgrItHmxvPfPJYipkPy7waj5B1SM7kD/POf6191nKH/hX0ves0vNi66FHl2/8SbPrr+/9iOoP/ed7e5Rbh668v235hg/alm9g+TKdyi4B1wJi91+QCMzOqUIkDNfVBhFmx38n5P5Yd+Z3C5QwAvz/G7mjbNd/J3JfrdAsJfmOyF2xioHmOyF3wMhAn7D9B/T5frsPzFkA0P9t6+9/CiGXYAzke60/RMirv8P8u/UBvXYnhMzWOJ8GNDJHYkmO0/w7SCAjxqa4IXGhx7WFfQcBPmARA5QUCA90MOMxCMcIOqAjTDDnq3kmvGAeFDVxqyuVwUg9SP8uJXXn+dLCvHFP5OHi7DGP9RPa9wXYZXuh77lkadgfDPiXQcZULPvIU/3BUQP+YJjV4XB222E5WoQyRPEdRB+fyrzCdjkps+z/4hf23uYXdg7yC+vo8W1f1T9X8KvFlXWBhuXLGwIjF780v+Xjmi2ZP5k19i616Ypr7qz2sgWjs5OHu9OHl80bVbWuMTB78qERU0t8rqxhaQWjFlT84D3V9pzSd437VPgQ0MdbEbangU2MGYu+AOXrYoqKgMswY9ZgMuZKUUXMuw9SyR51PWjn8Q17vDG339Hf1j2bzZ4Jo3ogeaNQ8lrBChCtHTrRhIkGeJSs1g6zNQpuY/AItoBoRXbF3Igoc4w1gl1lO8/SPFTrV+YxRUBvk5xhgVfC6s9YgjCmXLEkK7qnbZ9h5cGig+WUlJ8pPtMozM93mUa7li9PT6NfXKYG5ZvLSqPLOstxPidMC6EJYFkc+UcSjKZqaNpKNR2EqzlITSwJgIT1UWyXLEToo7D5Q/JR04gyReXNdfYDXZGpqXxNRWkKa4Cho0EzRSN5LHgMwjGCoY3/Vc1E9JpmYp5thwYiPZr9W/IZBf09d9Ka9UwzHTgMmok/23sywzlmdBO3o6d8055tD7uHIz3mg35uBnpE+LQ5zafNfa9PO1X54nVqWEp3Uxd89ULuoMprKwBbrYTvM5ONml+Z+oNRSFaYcRYeHiIGOpN7xmuqAxPJkH9kXYLqaky4ebJz/K3CCA0vm/QsNMwTdH4zwafGfodWragucb/qEhfWKN0VymHly3rFS5dcqaY11Mo937saOr6e24Ev5rvdDbQYD30f7BPnNJ84930+cZUolN+qfL5b+Vj5hJ6+RO1t1EQzlBm0RjlJv6RdShfNUXLgOQfBTkWa2zBPAumhRpTxCvMjeEQE9gKsNGIEOvm3+7XIMRAIGM6YeBMTJkDImNAxGq7YURmDt7IYGuZJUOgcj/ZFYIzWPTQkF87yjPGVJlQc0yavt6ru9ZZ5yq7L1mGZc/nzOJPf7n/8Qc1Xzn8A/WS+ciY3DLBGkC9kwRDpKyff6Svneno+z+G8SkMhb87qvUBPnOJyPjnR+xGj9+fKVu4TsZb4SJda8yk7ddfRYetFh20WIsGQx0ScAkBxq5Sa1mULGdVbY0EolV3J2dqqXPHVH9UaUJ0VpJDsjr8pJXTCTYdeZ0Xhg0cQ4R2Jbkz1S8NjEN6KWHsxZUFoxisw3d/CkFJCYpq7v1bzthZmvjM+MEeXlcmpmB2YDMLL6YUmIZolSKurUcWOJbBEK+koqkd9xOv0DEHi2h1FaePcpsOGOiE3M215Sm3mmRdavM2jZ9gaPIvKDbXCmILVytYfPuRJonNc5tySXW204dVX2msnKS27U93TMtKUQy4LKGJKjvVdog1aDMBj89OG9na1hAlovRBoPQNo7SVniZoYDkSWHAVynE6NU6d3hQSVuCkDhMZYtQbCi1TyuqxSWqdsdd6UdJ0dequOCXb0+bisHQmuNLgdhscgXEfQdlhZED6l1sqqtHUlDEsbTNvIFkbb9BSgaFKZLBg1GhPZG9dP21gNgzPppweYB/KElqAcDJT0Ez2XXkHK1go5GQOUfdw9J22xRlix9ocPeV3KUZc5L7CrTWkHwu6mbS+4U+sz0uh8l2XEGKDrFr5U2MTqTBpJMI5nckE26a4HU3Ap8EBHCyuYlmK6QhYTcQENLYBmaG6Isjvm+CMMvjNvXwrquRjm/jMkgpKLs7O1SuM5d3q+gCF9va9SAItMhLXLdx1doXw5/u60ON2wFG99pb3dmlM97aGqUdN9TqM5ObFsjRhwKM7iusa64qUHGh11bVvmlvoqa2srfV2A748qu+g1wDesTh1L+CL9D3s/3a+cp7u0tHDO3rNJMETkf5f2lfLdwgrADankCgnGM78nSABUEwzkgqWWEAFyI+uwjZ2yK+km5nWphdhGtdg6gRVbG/AWOSbKhZrQikexw8Zu4vHY/1H84yT8dEcyHoNwPdhOMJQF4c/xJqqMVBkJJs1ZXQMwGNSomVDWaouPbB8wkcHEkhxaUTVmIY6h4WJq5myNoTxY4xZKa/J2H3nmby+mncw4WHfKN7p57vgdo95YnXV25bqlLefOZP/pwF7KvazfeTD38ecrE3uvWerax8wWJG7dtlGcIRkQKnH2fSbsE6eQkWQTCWajfinwyxkCJodIbkxZHm7QUimByiFCszH/MMEvE+CwpKIOS7YJS4ECYGN0yQ7jdbkEk3ZgVb3JDXMP949k+ezu4TZ7cJivEEMGxCZ7/SCaLKC7ZZ0DWmw2ZgzElviZPxELztR0S4SeXLxb7wHeQ+Zg4MqTzhwEPsw08ZVm7I93xD/31bOvUy5LUaJXT130pDkmQUeTvVcsD43Oya94Y2RjTeXCPVOO7C6evznw2Mscl3ioMO/u7PXn1j23aUV17ZP3J5VklMUcmvFDt6V6ypUleXm1pwNv3mc1oJ0lkHoxS7hGkkBCkUyvT+8r8ZYEMM8lEA+WS7zeqdex5BfOGSgJeH1enV7H5T0578zWExN9wxataV+/o33r4lNwl5m+GO52fv75z5KcDzzy6M+cCaGYUQeO7N7Z/vyK3dv3Vdtjxuw7sHd7+4sP7tj+fBXpS9y2ZvVhs6Vt9Rq1NoOIH7I8hkkaHorGBW/ys3OIF2g0TEqsny37ONw8gTXEsK0TJFsRZjhgUgORow3Mtc20oVv9T41Qu/XsP65duVqkFKfT8xlKIJ0uUb4Mx6wv0yUZSmkGPZehlH+2/+ABbj0GsHt3HDi4n/kiB+S8XpX0IzVpD/Kea97DNaNd3zefvwW85ieVaJV5sPPZOjIcZJOhIBSjI2UYqRhTICV2yWVg3ZRZpTxW0wjXaQVyHmuSi1FwwaUd3xJhqVdBQ16azd5hcMZgarlkt8mBCuAs0d7Be7IL1aIhg1o0lG17UzSneQMV+EGPXcpEIedgmg9x6iAzSK2oCoTr0pgpJBar9VPxlZQ/vHF587+9ufvm9OdK3lpY0zBy9gMPzB755MYJUz95nca9uDX/xzMnzwzMXrZsdkC5tWPBgntm19Vy++57NWPckz/4ZUP93qq6miJ3UUZ6fvn80Ut2pw9bNWl78PmdReWV+cMK3e7hZfMfvacgekZZ0dikuAZG45VCJZ8h1mn7czh0/WVDYsQ13TS/wj8BX/RI+Eq4WDF3fHFF40S/dlb3Gdjcd0O8Ct8XSzxkDNmhRklDaaw4JhiDs+Ni1yHfaDEmGk7qXf5IdpevFdFUYQFqKFktoklm9VuhchOpgLtylsyHe5hgEc1YFA3lNvtbMaIrLdOXP4JNzMjRNnuV0eRIJpk5IzKKWGkAdViogCs9nIEtpFJ9MZehlrLYQQ1l2MV4XUTFi1Y4qHoPxKur3+4jz+7sO7Fq1QnSt/NZSt5ePek15cprR5SrR47Q5COv0dTXlLmFW3Yfu/DU75uXv1ZYm/HEzHFPLR97cOuYDdz+nX1vr179Nv4l6Xt71aq3+559jaYcOaL822v4guv68St/+8pTf2qZPi0wdsKopXtmNrePVH3y+7hWvk20whwlkhcIQmadiLkWsksETJNUIMV1hXgTiQN6JPfnbeepKspqlcydsiXuphTdiTaqwWpGk5UdE/EYhJZBlhnCwuMGI1hj1sSwbhlyr9lmOhbMA9JqLhasAyoZsM6Ac+K5xOkP3TW6tirgqN1+cudJa/3KFbv+8dmd44VNbY0TJo//OjF1S+/Ouvk7Nh35bD4baznZJJTyk4gIoyWZHp76MSkOj9uvfEl3dSvLdmvnTXQZXazsVg6pZ9A7LawW7Sj87SwiCWDUq9kfpCgosJ0EBAoGPxb6RCQMhwMzHEtX5awyTcbUSplPvs27Ttn+AIJr3eFZvd50/mjvDbr+INboafX8Vh2xwBgEcpTe4r9h+0U4SQYZTn6r7rYQilGLx/iCUJx6lVggZfhDOepNdkEoRWP/fFR9Ibu6aY/dinUFIbe6GNxWrFEKb+FTMCShIAVMp2QwnbJTwHRKAkySBJZAUjbMdQ4eeSIjMqBvYoAuO2fAI5FpB+1qjAEAkIEyzI3lwUROjFOD8zm2Dp3ZTlTHD/OvRwoKfdgnmxbQe3wevUdFrDpPCeJSPUK7b27Kb/z9G0n+e9XvX9zz0W9pzu+76mfNyRm/4sSY6feNnjM8uylry4jR/CHpG/zQ3+UXf3dhz4u/u7iws5N+Nql0/MID6VnHylS7e6ewhN8sfD2Q8yIO3TuBX9ibl8ZdFJbsYjqEz+fOwVwAzCcTiRb5hdXDF8gOUc25BVLbTCQXiGuzoqEnUxPLwJWjMDvYyCOUtTgAblCiY2loZGD0seHBwzC5c688/NDLLz+0xllXGpgyKVBaL7R/un//modfUb4srYO22lq2nvvOg6DsEYJajC1y2wns/sfK3rmvz1X2ZtBlc47NocuCPVsy+FZup7KM7t1Pdyjrey4dUGnRzk/h9+rWqyOLQ4wOCEp1SBoK5BidOjyRcRIKBxyTXcT9B5w4JgNMb1CMsiOEirExFQ70y+gvBtfKpXV6N5/auzOdBj6qLR+7wVs/6ujMZ9+++Amdy0/Z3XFocn5RoXfzyFGtK1ecaVX7dZyvYP3Kxpplk2Y7BCk6R3Sa7R8HU5BUILuxjznoRUaOhj5KLjTKMtT+4p4DLkxw9OFuCSbsuB7NCIB7vjKsXA66UjKw98Cvqf1c6YsoadeXDNl3QKtg4+cc27Whc3izr2Vc9fgFMwPmtLyGmimN45sbqst+XLf3xPql4+cIOfN31Y1fX1JSkZ+Vz+0VivKyh09qLixvWjJtnd4yF8bZJszhOtV8KtzBh+tUWo/TWrFZ+ZSmIcY6qewS1vBnSQo5QYJJiIOdfnQtAHxiUaAgL0T3h4g4TJ3DrHXMUWeLetVXV8KiSVBFk3CTZdujL/2J7tHsTTOs+ChY8dHonbN0Ym4CoehPF/EYhOsI4S6WkQ4iRlkG3G68IKLfbaitYEiyYVl44YhMMKT8vM6pFaDgRYkeqOxjtaHUMbeP0EJlq6Ouftzmgl2U7DG6vVZX2qgxvzOO+cms4RNSlSYx0HvinnljC7jnehtz8oVLlmNTF6QyPjkAdtenLAd7HVHhp8Uf4kWSL6hiOqYANyCK1GcSD8MVOmVd6k1JZK5In+qK5KCdAhksqVhs0EnAqhDUvEJ1PwaMGliGlBuIHpg0T6ym8N3czk20/IBybtM7D79635sr6alz4pZbm/i6YNv8Y6sJyvn5dBI9xD1n1cO6raMLmb+hTmmmqbACE0gBwQJhnUjcKMIT2e4L8SY1vBWPpr3NgatOR7SM3Vhk1Qj2LAnHdHQVtY97aiYvKBg5LMWdUL9wU12K2z9us9Jc4FlYk+l2JiYXH251jCubtRRo+BE/hTutW4E11jAWPe5VYj/dfKiB1h6Bd9K3rqdmplf3AoaYwzBEPKnBnspmWIIIJXAJutADHopTl2CcFbfDQM8ILsIE6H4MuiN0LDpnN2syEdX+gIUdGZujl1+Q/+2l3dKV3Q2Lp1Q1LLmLa/3JEz/+Pb52b7u7agq+mBy8QTbx18K6Hh2YHiM7Us555UtlTTfd27tfu+AnKXuVA3Qlna+e2XzsJESXIwasPvI77lTPcThf4OAdmJ/mvneU8/2f2c4+o77nU9+DzzzMfdlznH2mCT7zsViN38OvVr+HT2Tf06R+D/S1XWnhPuMvk2SSBX0tcTosvJaRpkFGwPYlkSkPM26ksdL06TuXRpSmHwiXpn9RWX74jpXpnRHb9fT1qbXMurPQp7F0E62z4p4SWrsYYO1rufXhdsKHPw/8YCQ25AkfKuQoaqRutR5ZaN+7MnTwm6tH65Ugb44sTBaPBIM07VsnliUrGViirD1f0Z2E55ylxwY/H56zD9ofoB8ObdfroP0fuTRarvWL69tCiP5vrGbOjlngVM2dZPvk8BZqAMUkqAmUGEMLmaJZ7YUJM5VjCxDwE9lo6t8ip4SNJFximhlLdR/11BcpRceVkDBDSGflnG2lva3jued7trYoVTgWteT0CpYNsvpOpZnVGZeTzSRYiB6fLMzjR0M4AXuRLlyPXM6jWHgk03hdylS3yCqFlV0B58xYNQBmtL0pkBhrkR9RUqk9mFU4sixiuUuFtpAQ4x+Je6DJ6Vk2eyg1dlhunmqZDBUEXvKdNcwgecNSgps/SEzU/Yvyl++pbZ6fbCm6TYy05dKSq99R8MzVqyIG1ger0dV4sJDNtZcMbl/LecPtam0NtgMP2vs5kI+YMGGuyoLOO5QGMx68WT5QItz/HJXXNg1+PrdU7VffZ6w9J9zO71f7RS4Pabey9jMkP9yu1t/zc3T7mGxM+h4rGGvTgo1g+84bVTyeHglf9V5Waxh16aPuneAfde/4Yu18sx0LRjkC2k48zvJPh5EfaBGGYWF2T8RSI4Egu4tJfi0VMVXdmRKzD8zqBj6ad7owjAgSGSIYFnNTSlSLjjhrh8ihg3qYtSNpWCIggFQ88sc5UZeYlDosMhsRN5+RzU41qqNGG/urzcO15jhTXEPv1y1Hig+3RJScb/zxX5rffeFaNfUWKZequazPuKyBynO6/U9tL7ynXPhMuaDSW7ymyY6PGb0L2Dyw2j2Nny6y9sIh7Wu5c+F2mB+tHfgpFuypMEfRyAK9+CHVe4Kispiyvr9Qb/eQEj6V1W6lDpTr9Qwt5evvExsDR27rK+NJkHPhvlIyg1r4L4QcptF46qN8SSyNp7HctUvK4cV04aVNF+nCxcrBLuqiDuVKM02jjmXKDZrarHyifA5jTe27pjOBXIoD1OgNxxZVlnECy1gw142Vzni0OxbU0HfJqSCbUlkarmzXiu9ScZsujhcRIifYOqJIspu5suxBsOWZdHKy8B58QPLYOuz6pDR832KXo7VydSB0iZaCgzv9OfsLI33UCcYiZeTnrn19bP75U1uRtp+2zzov7dYKJMt7tyz8Io9rbmwB+ruaF57edwWpu7Ih9Or1cKXkurm968fTlctmcJvLt/8703lqjZXGHxKjbWBI+1ruyB3bz9BvbmtX5YYS0c7qdLTvqWft5f1y6yrTUa5wpuHQzLxQjIvVa+LuVUI8uxQGCgQNEQWC31NiPpDsEcOO8ezowiOvgtWYcLmgtmDjXREbQ+j7izkzwwWC4QL1fDr+ld9nzmp9d50i0YWrN8+fpHxSJwYu/fFHE9qeWFxxa8Pd42Yq+1guS9814QzYxWXkZySYjiN1+4M8splRfz2YhRyWgrHPcjYwbTvQRPSKwmWeVSLoKcU9SMwF6DnF7UEHiah0AOQeAORuTJdI6yRymgeDuGludcsRFvjyg+6UU7LKcKuREB/jMrINqcx2KQCsaUxn1atSii1I9HnM7g7bd6quZFvCCpqxCjY005i4N4kQ50gVhDOfBZ/5cObOplB1/diFTQvHjpjcMHnEvHGzH3JcUC7E1j7y8+UrfrGheOrcqcVjFzUtGktLd5yd1Xhwx5jc1PzkXP+CMWOXVZZkjEjKL7//7p4p/PHZP3h4zLgtMyvvr4AFkZKYkzy85H7kJVY3IzZbvaSaIcax5AMS2Q48RjvhHR2+D+tba2eyLHNAlkUmKfmGFrDwf9OE2acDqUpNt5WxCHNQnvVuHchZujKomIVE9GslyjNyK9yv/vZatlZct7WfQzxHm/p6Iseh+4LlQgXIGHKMBGNQThVTNZ8+H3iomG1UZ7geTEVTN5xoSqABr+XRevWdUEl2cWI0nLSigip0Z+JmXbhYysEO8apFBejpLeeZX9ee6MnOLSwuQW7x2uSsESjKsmPQhRVtjStkXFRiQ9RF7EGTtxy3KUwcjbyWVhbhrmTEpvoBOqtZ5+Ft4vTugZoT+ECsW7NwuLkDs0BzMgYm4FF1ShJL9za0n3D2BrgfPv7Du+trjtRs/ZmffsI99OCiF7iegdnpPXo4PDUwT+sr63///rIawTHxsUmh/MBS+qVgrW96Qq2pUZpZTY2fPE2CuUjWDIOGVdUELsMgrFrMlqyWyoVYdQRg1ZGYyoXrTQDbDdGqDtAqA6DSCHtHfGpGPvOch+Fqri0oxIxAxZGB7hcp1RaMTfLivZbedRtoZTHFO9Xr5NIwYqVHBiHW2oMn7lTGs95SeBtQ3er+tyO31fbUMYAKPMrqVtgarNHW4FnGu9i+SVuDpxhP1zDe1T5P0F/rHViDWrFJ7HcUo/Bfqquw97JadvLBnWpS1EXYcxbLT3pn316Y0t+vcm2tOcP9gnbMCzewcfyStY7dTsLtfEVE+9rW/nYuyNrPfITtvyRqDAbbewBDYCwc8CwmCPLfhWkxX3DX7ZiWP0stQ9CsGosogr7XiXuZHfxnomaUpWgZZaF4jxX334tn/MjyyGlXRxSNteSybHLgxY4ooxnu0ows+obYVk0xl7ygDwjNf5/IlOS/T0GV4rXRUPA+qhV7zulDLEzOSm/Ynr54REVqioiaw1uDtisPQjNemTDdTG9SM0j7r5gOSvMCRhKs8cjaZhvbfdyTgug4Vt3RlPE6mGS4CzlGZ22AgDzIIWqMyOvjIz0fRanfZEwKPTn949SDH7YpPe2Xla83/8u2pp8N955tWL+/pWntS838B+umpJaevP/uqnWFinLjH5RP3/jzu7u+euahBw+f7Tl0pHXW+p8+uuih8PwKtYNk9TTWzvKs2bzXD9I52N6q8fs77PP1jB+0zzN7LC0CPw/Zjrw/0Zr/WtM3R7S86oWRydYqi387I5xefSUy6bq/H4P7XR/R70gdo/ZvBunkFWGzxq+1GLtB018raUV3sRMxVjLi3FB0FKaadMRG6w25oQR2w3aciNWjcDPhjrTRcGV1qvtUYzQ6wi0TG1nRcrlnfTq/o/fD/Kq6QH719OXsXFXHzTrQ+2F1fqBu3PCSqdx5vKrOL5nK1lbfpzCG51mefwro741a7DyW4XNYBiwDkGWcerQ7KnlZAklqVD8+j4G14EN8jrXthIvT8HmsQcXnMfZglClaxeeY0YAfQHwuxKj4PMoum1hqkP92cO5J9zFQCPjcp+JzXduRw3U4e6dbphw9OAMm8JWzrbS29ZBVWRhos9ADJbM3/mTvyn04h/Nr9qx6Gadx4Zb3t40YrrTmXAlk0C1ZH6jyhuWUMr5r0Pjuw/72LRrfnWbz2jDo84jLnbe1q3yQOtCu5gtq39PC2ucO5O5rdbeDcvfvVG/7/5i7ryZ+/c/k7vPfl7vf/B1Vt4pVd+ROZbf9dGP0JBf76cby1eln/NkhdUZavrqaph5RZxSuX/sv1RnF+pnmYHVfaAsbLoMtkUB8ZIlWoeUC85RtJ5QZ3q42Fi6itf1HQo54ITqabV/MEiANXXI66IJs9PO5tJ8NYMJXcthlQzrbQw3JbcV8MuYB1LnTvVokPw1BW78vMGJTtYD+eE99+n6lZ3/fi4/9M439ES3ZmMdLgQh/U0/LHPc7T22/3PKbV9Z+sFf6EbX/Qzv1vd/02QXV//QOfb51xzPXd/z012tIWJbqrbD+88hI4P+Xtdxqp5+l0+O1PAY4MwuJnOqX/Xr1Wi4zXA8Np9FZAHSHa0C3ukBK6JIrQCxUWOVCALq5KtAdB5KhsAKBLjVFO1OzhgsBXPW5NrCzUCaMwZRoa5lEbUzcScPtHQm5au5JmU0qLJOzMGTmYdE8RxjpMi+1z6KpLrafbzwrs4xzZIaBrRgRy9QpveXcc81VT+XWPfuPz1/0erJmTn6w/PfKt/XP/q5l0hONY+y+Mfc/VvPW33ur6GWAtvftVv7QuvDRnz76wIZX6fPUprtro8/9+pInZ/qyJmSm3Di/6p8PLc6unpQ5vGKy9+r5mgadpb5pe9PDD7/37PINZwdsctVWbw/b5NB+lndyNeIUkDbR5IaQzPh6hzCHu8L0WViXcVdUjaXqJuTJdsHL1YnnWQyexTtCZgaPJfsAUGZ7tMhxputayEM2aoHf/0a8A5T+slkrnp43e/n2GVkVwzOzKvMF74OzG3esaJi/fX1FlrdwdF0Bi1vP4meIK6E3U1n0xSZe79DZiCEX4zCsK8Yu2QBdMVjZTy84tK7EGjDsaQ67kgEX4W7XGJiOdaidyudBgHjYXvEwryV+C+Xm+0b70nMTKxO3JzXdXzDZG0gdnbI99WFhVnJWVnLrU9tyinJa2tqI9lsEQuv3/haBUPttV6GQo/0WAXxe1/i9n9fl3fxboc6kff447+IC7DcnckiQR0HNh39zgnSFzEaSCSyPAzazWgg909qxxQxxh+0GYN3j6t7FOkvxpFUTqubyJ5v+lW1ZzNVU1CxtuBOfQNsJ3sV/BG1e8j6H+up9uo9hWPgsj/LKStzM2zt4v2RxaAN/edDGycqKQbfCkcjdk6cO2koZZPNl5RbXTfPh6ef7nN9eZTRfT77hGrgLwJtpBLNBjAIxar/moOsKESPeaT/oEOmL5hpeebCxBV+0Z8W+lkZ4qXrZ2ndNnAXP8JEYgbAYVwzuvKPtFU0xp4Z7h8XZtIwazjw4h4ZQjMVxK9XPxLIY3L4hkTdClQoQgPWsbjWJANbW5lKb0H4ewFA4X89+qEYMaD9Aw5F9/BR+pW4F25v/FZadQ/1ytAhGQVRRUVCIZvk52u9+RAt4F62HO8Pg7fm19GxUUAb1dz8ycNMcq2zOuCmqv/xhCP/yh1n9zQ9juCWKH9ihH31sBuPQHfoFbb806tF7StQ9+t2xlK9d4T3lVdanglwyLVumXBqvfM3/7dixLbRbSafFLD4I6wLm4BrYXHlkjoZQMjUHLdtMTBCJJTpXGuaXBUC07qKQycAaklmCtZRYhBuW4/bkRBYyYSFkZeNPrhhYxi5qwlh1S3ufp8QfKMFDxBaiOsyy1MXBQd0oMt7C8Wl/U17ObUmv5aMq0yfdQ7d9MRAVWvebsRzJ6L1i5ezpSlbWic3h3W8p/eP+iSP3/7FXCwY9cv/+qor9DzyqbYDLkQv8JoGwfZwc5H21kkHbDDFkZ5lLssWGgYs4AOz9oIIF6CVbPiuaki2+m7i7Vf/uR6JW7SGLPsy0P/kr319vqO1GtlsmbpUoi9k3Mep/snJb973qm2Zt7xwf2zuHZTIg9DIN1FlhgkNMxH6Jlhir7Q6/OcV22InlPVFw9CdRv6j+BJibP1ha/5m1pr50YUP52QaFa20obWg10UJ+E12p7GavE0onrSpWWunWYpjvem4W/yXX/R178bC8pA/VRJ5ZB3DN1irN+gaxEdbqJW4XW6sTGb6YAljurNgIFE4jwwlRwzMDG0Wo+0R8Z2n9lD5y5GDhQbPn7ec2z5rjKVs1jG0gkXfHinvu2ifFB4KBY4nbiz+hNXesvucwHsF8T8NILuax9e+0xrI6GZIJuhDgxOqvh6K8ggsATpQGcPIYrssGgJOt/pJUilpSOGinaqwuGwYzKdyULJ0d0ZwFN6hmRw8eg3AdAbo9ZQCkyZtctGVYeOtqepxE3qpWfTZqzTgwASWrLUSFqFgX827F4o+vxKVAs0utt0MgiTmharJiSWBgt3kMh+lpxNbm/NI+4lx3bPazjf/8o3963KVrXfJ8a+XRS/f8qKXG3Htj49TE5PWTZt4/b3FLxZa5Bzu3rHYlVtc3htZ7JrbUFxUr9fXrcwrvmVhZjXOv0RTm/I+E/B+4Od5FAHjabZJPZFxRFMa/d++5byq6iFFjVLzFGF1URMUYI0ZEF11ERL1FvFVUV1WVRRZRkUWNihHPiIiIiBijKkbVqIoaEVE1qmYRVdFFVGQRFVWjoipqTs99o+006eLn3HvPPffP9x3dwDMFQOjV/TiiDwA10WtOsGIuo8d5jSPlY0D5PKt2sKpb8BX4QAVI2Rq1xEX6iAmdxTTV+But8DFVoWgXaWGcbmKOttEn40y0X2rljDHhmm7xqV7EU9fDlAl4wQwgaSYRmHUkqSTMyLws8y0kVRpJ3eQG/ZD1BJLuc8m9EM4Q0GEnGldyNW5TiJemjscmQC3Wj22T45LpQY3K/Fnd4HW1hDcS7+ppjNE9nnC+4x0tIyPE9TFy0dhHTpUkv8T7VETcObO0izTQGbubiNO8MIcslXhX3ptRe1Jf56/qCUYlN0oKk67CffnnMiku6x25f4S/ODXRfITv6J8oiB6b0Z1jSNAnkOnhU5vXb3lXjeOBewWPdB5r5GGIXMxa3fUBNtU+QjUl+1rc1FdRFbbkH/O0wXVdwIZoPenUeVzlsaevY5U8PnELCN0GwtggpnUfVyPN/0NskQvWh8iDLqwH3ZgmvN8enMf2iUQv8qEb64P1yxXtOppfIJZGJtLE/5eOB38R7Qf/eHAO3YZPc3wY+dCN+BD5JdGecekhgtgtZO27nDYaou+CU0FVvA+pgpRolpL1LZvTK3glSJT+b2LGtf1cwZCq8Ikz3M6LB2tmQfwJ8V7+fzuWkP4pyp3D8Cy/ADsV95IAAAAAMgAyAFIAfADYAcICFgK0At4C/AMYA1oDvgPcA/QEGgQoBH4EwAUUBYgF9AZQBswG8Ad4B/IH/ggsCEIIUAhoCKQJjAnkCmoKuAsSC2ILrgwODIYMvA0MDXINrA4iDn4O0g80D54QDhB+ELoRLBFUEZIRyBIOEj4SehKIEsgTABMYEyYTuBRKFJQVKBWSFfwWphcqF0gXdBfcGBAYxhlIGZYaJhq4GxYbiBwOHJYcvh0cHVAdpB3UHnweih8oH4YfpCBMINohHiFwIYIiIiJKIvQjaiOII8QjzCR6JJIk3CUAJUwlwCXQJmAmuCbCJwInFidgJ4AnkiekJ7Yn8if+KAooMig+KEooViieKTQpQClMKXQpgCmMKZgppCnUKlAqXCpoKnQqsiq+Ksoq6itsK3grhCuQK5wrqCweLMIszizaLRotJi0yLT4t9C6ELpAunC7cLugu9C8ALwwvOi/wL/wwCDAUMEwwWDBkMLoxODFEMVAxXDFoMXQyBDIQMkQyujNmM3IzfDOOM9Y0IjQ6NFI0hjSQNJw00jTcNQQ1FDUmNTg1VjXGNjg2xjbeNuo3MjfcN+R42mNgZgCD/1wMGgxYAAAckwE1AHjardLVjlVBEEbh7xyGwd29GdzdbXB3d3d3d3d3dxvcnXfgloTNLe8Ahz3ADQkXkPAnnepKViXdK4Ucfp7yErLzMe4SP/o07+NaV4hv+a1zQSoxOLEi+Tr5MRQPZULFkBGqh9Yhq3JGJEpEyShHlDNKT6XiqRDTFxODftHFQulQ/gfd6jc6LZtOfU5NTL1LzUv1+pbr65focfQguhdlRTej41HNT49ClVAtdAyZ4UMY8uuFf5v0ZN7s8m9Df0xCMraSJqd0ueSWR175YicFFFRIYUUUVUxxJZRUSmlllFUuNlhBRZViF5VlqKKqaqqroaZaaqsTm62nvgYaaqSxJppqprkWWmqltTbaaqe9DjJ11ElnXXTVTXc99NRLb3301U9/Aww0yGBDDDXMcCOMNMpoY4w1znj/4/8TTDTJZFNMNc10M8w0y2xzzDXPfAsstMhiSyy1zHIrrLTKamusjTdnvQ022mSzLbbaZrsddtpltz322me/Aw465LAjjjrmuBNOOuW0M84653z2Nrnksiuuuua6G2665bYsd9x1z30PPPTIY0889cxzL7z0ymtvvP0OVRZ+fwAA); + font-style:italic; + font-weight:700; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:normal; + font-weight:800; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:italic; + font-weight:800; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:normal; + font-weight:100; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:italic; + font-weight:100; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:italic; + font-weight:600; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:normal; + font-weight:400; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:italic; + font-weight:400; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,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); + font-style:normal; + font-weight:300; +} + +@font-face { + font-family:"Proxima Nova"; + src: url(data:font/opentype;base64,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); + font-style:italic; + font-weight:300; +} + +@font-face { + font-family:"Proxima Nova"; + src:url(data:font/opentype;base64,d09GRgABAAAAAD1sABIAAAAAayAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCQVNFAAABlAAAAEYAAABGZSFdvURZTkEAAAWoAAAA+wAAAX3SkDhLR0RFRgAABqQAAABKAAAAXgfrCGZHUE9TAAAG8AAABwsAABQs1mgQU09TLzIAAAUQAAAAVQAAAGCNwp6JY21hcAAAO0wAAAIfAAAEOMANqFRjdnQgAAAB3AAAABoAAAAaBOMEeWZwZ20AAAH4AAAAsgAAAQlDPvCIZ2FzcAAAAqwAAAAQAAAAEAAaACNnbHlmAAAN/AAAJ9wAAEIIhcRkIWhlYWQAAAK8AAAANgAAADYFn/XRaGhlYQAABWgAAAAgAAAAJAcUAzFobXR4AAA12AAAAgAAAAN0vewc0mxvY2EAADfYAAABvAAAAbwtez6ubWF4cAAABYgAAAAgAAAAIAFTAQtuYW1lAAAC9AAAAaQAAANRzCRIiHBvc3QAADmUAAABtgAAAkkBlLVycHJlcAAABJgAAAB1AAAAeUYGBrMAAQAAAAgAAAAEAA4AAmlkZW9yb21uAARERkxUABpjeXJsABpncmVrABpsYXRuABoABgAAAAAAAQACAAgADAAB/1kAAQAAAAADFgKbAiYB4wAA/0j/LgAAACMAVQBVAF4AAAAAeNpNj0sOwiAQhu2CodQ+kOLeA+gFXJFOZN106apNdOERequhvaBDUWPCkO9/AIF2Z1cLkBUoW7d7kx80Unb0pNBPjw5v3+WpjA4ZnF5R6U3ZTZHr5wCuC0Imlq5btRAGqcWRSyMBj+Q5TVw/4MCC/HCfVyFkPBRt3oIWKYZfDPAXq09sUhyMSX6++Yz9vIDjx7q1asoCubhkmUJt2yvGSwvUDBaf/IFIkqlhurwBdppNvwAAAAEAAwAHAAoAEwAH//8ADwABAAAAAgMScJ4Z2F8PPPUAAwPoAAAAANFfEmIAAAAA0XudNf9O/rgEXwOMAAAABwACAAAAAAAAeNqNk7FOwzAQhn+XAmKgYoCFBY8tgiSNQEhUQkIMLIAQkdjT1GqjJnGITdVOjLwAD8FLsPIOPAGvwd/USCAY6lPs7y7/3dmOAmAL7xBYjBM+CxbYobfgBtZx5XgFe4gcN6mpHK9iE8+O17CNF8ctdPHKLNHcoFfgw7HAvrh03EBLPDhewZl4ctyk5s3xKnbFp+M1tBvCcQv9RudCl7MqHY6sbCcdeR1XYxmluS6MLg5kGATHnjzPMllLjKyUUdVEDbzbSk/TPJY3ehLLSOVpX2eDOzV8zOIq9IJu2MszY3pONlcdfqv+Tb1XlUl1Ievc/7JG1panvm9npRqn1kt07is2M37wd3RPjuIEF9AoMeM1pxhiBAuJNhJ0uF4jZnxMivg2p7KAqecDxkIEtGN45HNkNPmjiqk9xVVxnXAeUHlL1pjW1WIqbuhNaoqoyBnvM5JRe0d/iEfyfA8hcwN+6BA9qjJWNaTf1b5rHf6ptXzX+3q3hpH5KeWPvsv2mp/d8kZP4dMsb7akYkyFZa2Eqpxx5U5myMFS1uXPcsSM5Avo2Z9YeNpj2MTAzujt5LTRlsF5A09A5WZ2JiYGZ1cn5w0OAZWbJJkcnGQ2cjI5b4gF8jiZmJwznWQ2MXExOSdkOu34v3czAyMDUB+Ts4tzAlCCgcFBymmjDFCEPaByx/9720HSLMzMYAMzgWayQBTu0GWQBQAXeiHuAAAAeNpjYGbSYIpgYGVgYOoC0gwM3hCaMY5BhFERKMrAysYMolgUGJjagfKMDFCQm1NczODAoPCAjendfzYGBuY+xhYFBsb5IDnGx0yzgZQCAzMA8o4MbQAAAHjaY2BkYGDu+1fDwMDS/N/vfwiLKQNQBAXcBQCLwQZLAAEAAADdAGAABwBgAAYAAgAAABYAAQAAAGQAMgADAAF42mNgYmBgYGQAgTsMXZ7/Qcwfv//X/3//n5uBoeEcg0CjGAPDBSaGK5oMHAwXGBlECtKBDAaHBawMLQxvgKpfiTCwKIAkGCQYMEHBcTAlgCGRdcbn3zGG+2d1lgYJMkT82O7dwKJgAZJwkJNhYGABMpL+/McOGOGGgG0E+oCFg4EwaDgryQxyCtgtB+TBYpLJRsXJDMmJxakMKXn5uQxpRYnJDDmZ6YkMOXmluQw5+ck5DEBGEUM+iJtflJLHUABiFSfmlDAUZ+alMRTnJhcwFBcbGIIIIxBhDCJMQIQZiLAAEZYMxaVJxUCioJihBGRAVWpRPgMAfO9gngB42iXHzQ1FABQF4TnWdOqnCVsvLCnEhkhEARTwijGJ+yWTcwlQ8l1B5a4JDa1fR+8eFH4KI5OdWezKZncOeypc3PZR+CsvMMUQUgAAeNq1WFtsVFUUXXem7Tw6j3boY1pKO4CPBsWAykNFpKiAAhJLRSU+IEpAgZoQNBKjicIHP/BREUjkkQpWpD8NMJg0xBrTEJqY/rQmE2N/xo8a02BGk344mus6q5fODJ2+eHTl7nvuuWfO2Wfttfe9t7AA+PGrqwIFz6xa14Tqt/bt2YX67Xu27cSqXVv3NqMJBRwD24aLpwBHWxsbV8ZQ5vRZCDotF0JZY90I4yF4GjY/G8PSpxubYli5tmFzDOvWb1gXw6bGDetj2NLUwP53mxrXxrDX+V0BSpxWIUqdVhEiTsuDGU7LO+qBD+VOy48Kp1WMSkR3btvTjBbZ47KnZM/KnpftkL0se0X2R9lrsr2y/bu37tmJX2STsn/I/iX7j7GWS9YvG5Gtlp0jO0/2YVJj+L4T1vDuumtnN9mNoNrpqfZeV1yt4p+ccz9cxb+bdmAo9AHmYDZZT9jtPAbtXp677G77GFutdtqOsy/OOz3s78UU/+xk7tm5GprkV8NcOcX1knYfV++hF4N2G/t77SEew/aA3Zo1OpVnhjQ9TXOONH/Zx/FmR13GD86QNB5k7yHvDAPm4Pi4rvpy92Qn8u8zp6/bPsSjh+yd4H4O2vvJXxtXbqM3bbxj7ndNNENmpjE9KdzBP7vTbqGPCcN87l7zjh6w03n2etAoxZkhcQs+JMgRNWZix2Nw0vFjfejhLlq1CxP5SX3IienIbHNRy2pUxVY95vMKqqr109hFLyMbv+H9hDEdHLsDp7/T7slcZXNh8ob6SeVGiPnwt9RqNBGWD13i8jrZaKX6k9OORYq6T43MPXLky9F8MRi9+598TY8Xq+wsu7HP3PrAfZqcHXJWGhrNvNTNurnBfG79mMZu0xPUIVNBhrPHjT+a99rzRLM3o8SRmaaXu4xfq91hIi4u+ibzIV8NNvXvdirHRKpm5qd4JO1OZ2Ry5P5Ihb153Ulri/NkGBs/rZLIjdmoenoYKebMSK3O7JG9yUy94h72s8q18PoTexOzbPBWdTF5/uRqM0dR3WOeHYmJc2OMouIZrY+/h1Eme/L7kJubmbUyz2auoypgnrxZWjo0TvVNjVl5OF8NdNYbtv907qfzVpbh8TImM55zDOfVs8v9g3mn8ezw/Ms32Wo931pv+xk5OIUx7czVtpsVrIpu3l/qqdM0K3MHWUxkMWrer+Ls7+PdbtylP67SeaM+Tff5zKw5oXPHhFVmKvnSfAuuL5vqDvmsnpyFrtvkcRpK4jvRlEerfh1y6vvAlH5iWVGrhu/5Aap85NprlYxem3d/Awtp6ze+/dfwO6yQ/R71+Qk3R4aZKaX8RvDy26uSfdV82wliHr/4arAAC/lF8AhW8E2oAat4tYZYgka8jKV4FVuwHG8Tq7CdWI0dxBrsIp7DbuJ5RrsZa/EhsQ77iPX4iHgBn+IzbMB+HMCLOERsxGWiCd8RL9G7Wn0NFuMwWnAER3EcX+IETuIUTuMMzuJrtOEbnMO3OI92dOACLuIS4riKa+jXl5WlLx4XniKg9cz3UIM4CIuD2eIgTA4MX0EizHOIX61holSICDPITTl/X0FEyVIlWTIoxUyijkzVsD2LiNHzWs4cIyyeZ3PNOYSbDM4l0/cQhbiXKMJ9hAf3E15yXs/9ziP8eAAPcufziQCjwC9vxmEB2wuJIKPxKHsWYTF/tYQIMBJL+c76GFGOx4kKPEFUMmuW8U32SaKGcVpO7wwXtYzmCt418QwpniWKZynj+Rp9fh1v0MM3GdtSxdaj2PoVW59i61dsA4ptQLH1KrZexdYvrmsZ2/3k5gDhVYQrFeHZirCPrKxVJAKc36P/RfgVB3MdEgzvIfEeEdchsRwSvwFyXsd9GpZrxHKZWJ4plmvFcrlYjollF9mdx1UNswVi1icew+RxEduLibDY9InNsNgsEptRsRkUm26xWSI2/WLTEpthsrmanhs2Q2TzFVrDZo3YLMdWwiUeXQ6P7xA+sthMf94jwthLhPE+4ROPPnxMBB3lGgaDzIbDjMrnRB2+IOpwjKhjdhwnQyZDipkjJ6nXU0Qxc+U0218RlcyZc1SDyZcqZkw773YQXmbOBdqLhJcZdIk2TsxStAJOtK4QVfieqGKGXWXcrhGF3E1UOWZxjMlWA0teFjJvWzjXEcLL/D1Ka7wMyEuXvPTLS5e89DOrz5BB42WRvCySly55GZSXQXkZlJdBeVkgb9zyxs2875eyFrBt/mdlfApKU0VSVFSaikpThdJUVJqKSk0uqalcarKkJk9WzrqlJq90FJGOQtJRRLlZIh1FpKCItFMp7QSkmhlSTYX0UiqlFEkpUSklKqWUSyluqSMidUSkjpAUEZEiItJCqRj0iTuf+CoTX2Xiy6eIRRSxMkWsTLxU4WeiGAnC/z8h3JDzAHjarXsJeFvVmeg9V7Z2L5KtXbIlXe27tXrRYkuy5XiLHWdzYjuxnQUDCQmJQ4CUQgkkYWnDwKQtgRBaAtOWzTIEKAwQCnRhfa+0TF87bV/75r2GlAIDtGy+nv+cK8myEzrzvm8S60o6Ovc//76dcymayi3cj+6n36d4lICqpvKVQp7/bL5CSPnPBupMMlOdzCTLoU3svY3ISL//xWme54t/51VTNOVc+IhO0aeoGkpH1VJzaomkInV2Ti7hodTZgDwaDQWVSkU9n8+YbbaIxcaY+Yp6ZSgYjThb94+M7G/lruieXH9/rruvrxvdf/fk5N0jI3dPTd09Mn3o0PT04cPTFAL4FIrQxyk+JaZm+RWpWVggUCewx0Iy5vkd2ee3zdC83bkX5rfCXCdF0QrASU2pqDlKosYYKSUq/CaQVGPEYkk6EsbICOwlFAUmhSn4jdu7csHmjaas+/ru9M700TuQgzWMXvqVKX9TxGXrD8cC4+1rv79rOwXoUGqgvQbWccFKczyJHRY4kBdKqvxn1XN1Eg1ZSEmIDTNmQYT7BKsWFsVrNtAF5tjXGbdEOnruyIilHcnevrbJnrjz6pU7Dq5rZboDyd19a663PGT1xPzjaBp5PN6mnhWBlonh5JCYZ+8ONK8PxgOAEshDDxcH8ElMVVFKalZckcpLJMh/FvMrz5cIQJ5WUwSFZCEFo2DsIRnawL6A5PeOjMy88so3x9H97NT2b7IojOlrBvp8AMsAkOZoiQ7oA/Lq/GfnaiRSjrpFkmTAPkW5vO1Xd+1M9q5IrEkMo8fZ57UrfS0Tbe17e+5d94OVmWC0o1WNZraf0RrDE+ns9tj2gi4FgZ8NlBuvaJdo8YomiRxWFJVplEpgw7IDTVItU7AKIlPCc9Cw7MHxvX0xfcoXHXQhzWRzYls8sWvF+NWt6PaBNteAlt+dcyUa0cN3b+gZaTDEt7ZV8a3NTZPZ5Lb46PGJdMJtaR81R/VE1jq4fEH0r4ro3xyS0BghZIqYFIhBM+z96H+z89fS4e1D86exLHiUC+hxAj06yk5FMEVBooR5t8QCFDVIRBhANBoDxMOLalhGDlWwFyAzIrfZ7NV0wXhcazqS/V27UslduYFkx5rOmc6umU50TS7WnBvy+QYlgXaNtj2wsq1l8E8blPUD8daVNtvK1vhAvXJDomXY7RpuRZOBgNPpFQq9TvavXg2Pp/EaXeGwC+uQbeFj2k/fD3J3Yax5nOTtEglgbZTULep1NBIpYBpeInmqIB48J3atvt3butKunYwltiU4/oNgZnrQRStyzkTjQKt7QPNNgyG5paXe2hLkuH/XxORdG3rQveNMRN+acFk43UZwuQdkIADtrqVmeaDbQqLbFeALrCYBg0KIsYZ46Cz7etMNiP8PiH8D++z7+6+9lj4+v/X/oSTIJAcwNgCMWkpDmbHdmiW1xG5NEg22W7WEwvTVmQrSIAbKmBCn54yirvghh7rb1nozTUwbs30j+wgKeIJBz9PPgzwDz9PHvf2B+LC40t/tGNyCDgVs9sBD7O+bPPbIU9g/gV7cDvzVY4+plOixY6qWCPC6FSVeLio5YXVMxWeQ9eTo6MnJ8YOuLZqN4Y7peHy6I7JBs2Xzg9J1J7ZsObFuOBNyR5M7Ozt3JqPu0DHMM0zvXcQfKPBqCokYr1ZfoLIkMyaGpRmGJRlZ7pPtJ9avP7H9k0+6LopFLuq+nj6+5lsTE99csz0x3d4xnWBDQAOGWwtwJZiHQuL1D+QFkgrMQ16Rh4rS/xz6Kfsg6mfn0Go2Rh/f/tD2pzgfWoQjAvxmRRWpLwMiY0ogZsj97O/J/c6FD+k7gZcmrKlyiQFrqkqiBk0Vl8eg5dyMMGC2Bd11jp2c2HiDd7N+Y5TjqX+N9scoHr559cTJMTR399q+VNQeJGxNWdQXbf+spX3d3dsKuN9CeKAl2nggjyR8wH0WuIF1clYIeokAdVkIwicEKlrFnpqZQRvhxbD/Sh9n30MyiFgFPlDPACwejm8Aa5bC8Q3uyc3MYO3Fc4QLH6E7YU4V/Ad/jHk+y4dpnBuGBeqx8SVDqWhq5sDWy9K3x9Ix9DLbvHN3V4nX2wi+cm6NIp4CEksVGE8wIcT8tRUwrLyN/QAxR5Em+wvA9AWUZF9iTxbhoD8AnEoOj0qMRwFdLOoZZGO3As6vbi+sif2mFK8JM2el8AKkZ0WYNzyGh7lThwmlD70WfHXm1OOnT82g91gZfsG6K9ATJKZjOEeIngAcGmCIuByAMKAOA0GYw8/M7EdrZnaj37AWuLkJvUHYW4gtPwc9qaEasR3ouDyl7svylHJlgUiy7vjU1PF13JUOxrak01ti3BU9cmJk5MTkJLmC3YGaZHemUjuzBdvrIrQrqDoKU56XScSgmrVLnQyYn4KhsFPBcswha3YyHJ7KPDqDDrUHT54MttPHmze3tGxu/hR91vpWa4Cj59eEnjrKhumxSQSYngZJDQZM8QUqgX2pZ66I2WMqzsSLpNE/97ljQ6094yXa2N+5h4eGvSUCEf8qfzLb4ShR+EH9eGasfaREKFX0Mb1AZzXkW3rOL9dhvwz2CNp1drYaix3VnglYgU5Z0bPWMfIiySiwdwZZO6aio+nvHhJzNH/6KX08simxequE/axINuiBHuToXZpzXZUXSxo53y0vz7kgYPpojv6C+WOqVYsp15jt0o5Mxh6P9I5nE5fl7tycsW2NhhO2lnDvRGfz3rUjh/xPOkNRq96iqJbbVnbERkJj62w2r01trK+qcwxlWsdizUGKwwt4YCWxqZ6aFZTyg7kKTsPqsL9hZMz//Rkt+tkMJAnb51/lbAnoOQz3yeD/XKWkumBLxDzAKurLTdsWye0bWbVq/b7bb/367aDeu4bGx4fQUXbHtXfc8VWAVYyPfJAEyZExIJInYwuDJOWGn/3sBvazfwDb/D+0nvMpfEhUriU6quTsSrpoVyUbxbfDH49BP7ruK89d/7Wbxm667vpnv4L+zNYDLJamyYvA4wEOtxV9DL3MxwCsOl5IFQvx6hjU8/Qtn5275cEf3PrOp7egSvZztBZ1fvwx+wz7PapAy9UAR4hpEQIMhAicAEKEGBmDKtj5G588fSPLziAFupH9A2pgr2LPwZ0euNdIfEUDzv9FXOIvxG80EQcwuoJoCpe9gdPyoDXsD9C78BplpZvQL7ZvYt3bsW7bwee+hd4D+TrhNWcT8XCkm5OLVLwUeHo9zq9FRpxVL8mEVMVEH+f5MiZiW6x8YugS3VDAOdDU1O9qGtImQ0NJ96orR3ZNyxMWb2ur15KQhxtN1u5QpMtsbOh2BRIrBlZvZJ9/Qq0N2O1+rZrYXBb0pgFolIM/A0tQiKsweTpxJaA1Ky/FjyUZuc2uYKKllJ0vUGSn9UO+5EQsNpH0Demnr8pZkr29SUuXnD7+uc2Z3NM/cHnCaU3vs47kchts+ueAtzbgx6+AHyrsdarFdXhVoZjHK8vNi5TilAVzxNZ+efeV7Z2OXHpwMN3p6my/svvydtS6t2NtewsG3NK+tmPvCpJ3fkSjEk2YijklRHEgCLzanF6MWX8en8Hpy5Zw91uYpslYbDLpHTJMT8u7rMmenqS1S562OhOXD/TvSTptn89vRUN664ZcbsSip6jC2iJCVyPOJKQiTFleKxKBG2sULdIHvFSYihkZh0kUSkcfzdhSu7pyl7axN/NXpa29moBlW2v3nvQTXRWoFjXEvah5TzZ7RZ+mpU+v6TRbUnt7H+gPNbbZgKdVoPA94NMUoK+zCuw7xDSmGkxmTi6Wwce8VCyoJV4kBISXuKwIYZ8yNji4ujNkUsk0jZbJyWl0aFS3cn1dv9jp0I2yV/73wa/VlsMfkBTgY97FITl/j9RtOvDKYl0laIVDTFJNs1iO11LyUgEV55gj50mQODc7KhfjZfreYHzYMFhUz0HD9Dem2ze50Yi8y4IFCloaMBlS2Varu3XXQN/uNqctw0av2Gayo9d0tjVdXWtsOqA9C7R/BDpVh/NLcAGAXTXGp66i4N44U8AJBGcrYK3o5pDfmlZMT+s2RvpXTqNAxGvTsY/Qxz8z+gZ62e9jfYmB1jxFnwQ/V4M9VA32nLzUgUcl/oDcRniIjY4RgHqO2+1anc2mC09P0w02Hf6os7WxBqx3C28vxAtwNBhDWWVqVs1LzdWLa4CH54GrIxleMd8rAo6sGjBoJFJ5o7VsgfmXV45UruPZnGiB4vhAC5fnfgIe51NjXO4XC0FQfj8zPf2Lr/30tYM/7vwaxJhNZ3/NfsLdTz10ofw0C1QV8lO8xjzogZkyAiUwByQ/JxVjTwlsN2C2Y09urihn+3L+q4pSoO+wO0xJ2bTdaUzIwY5HguGsVLUhlM1Nozanz6ZlHybvIBn0x7QuFHBaIitWsN/l4jGW+4eAywXlzvsSud8U9NvS9SD3DUTuvmgRutE32Ms+WPQTKoBb6HfpxDVYyRViAfYQymWVcLTgabFOv7U7kdjd04uvvR29vR3tvb3t0uzers692eyerq692bGxbGZsLJMdK/j3broB1in4QqoSO8Bqbi0+JgRhg5Kd5+ApzrNzlpad1g35UxPR6EQKDAhVEKsh9vMkfZxzhwN7Eg775+iDEZvuOZ1tA07lKMtCN2KXr11BumhiKV67FtauPN+MeUv88D+C8XJr+4d02A8XzfbJz+2OxJ4BLrbMb6VFOhuJL7qi3HrQX8BnyajZKqxnoENCCQ5rhXCmKAgOgtdqb3Wdqbd2Gv0xZ/FdxLNr2CcwDC3EqDzgbyc5oshCckSR2IBzRJUI+7vFHPECKSKXIWJu9uhGvb6mSEvLirB3bdtl/R5Vn8fZ1NTc0he9eFPyUuvNeofFoFNXSXVtQUfGke3RGk1albJKakhG0qvtFsBFBLg009shpqiouVqxEnOxgkTpOYlYzClNRIb9bgh72wLzIHJ+KzU4OD05qVZW6/gaU1raHkeq0YMHR+e1jWLBykbCK4D9Ifojp+N1nD2DveEwSUTEhUqSPRKouEBCNxlGIv0D0wVNbze5B3rRWvbNiNeiQ8PYKaEFFi6fAtzFPBL8BITAAI/LAuldt966+6Xd6I/sMXQx8WMIakGKfhfuWZpH8oixzfJ5y/PIK3ftPLZj257RPdt2HNuJJtkTAOxe3F+Gl6EAD50DeEvzSB6hEfwVE7PjPFKgYj65Zmb2gX17Lt/3QH5fPv/JufvuO/cJpmEhTmiQYz2C9SHmVYNHJbZPmBHjiOHzBSDo2JBSaxKrX8aEnVWvilcxktrtdaoYOotJnH+5rQlV8MYxXj64PARwudxSzOWWYi63JGnQXKW4gmgYSfl5IYXJ99576OoPPmavW4maR/vZlzZSCwtcrs6bohjqBlRPPQBWJ6WWjh+mfnTeeAeM30i9cMH5h6gT541fA+M3U+eoby8bH4PxI9SjxfkQh0DmvKPg32uAY2bIfyTYr+VrcRl3IC+RCLHtCLhyDvQLKjkBg8r6O7iR/OO/9d+A7kSfLDZ6nnsOt95Iswd337h+TZr0vsKUgZqrF2KZ5IVCDWRZYdJImPNIrDg1t2AjEAiKgQ/LqNRJt8eKRru0r4Oe2aDZsvG7NbX1BlvSZ2qpVVq8KpNJUeVUjtw6tLxzNhp1h47yrRJ7g9Unr/IZ6mQNNapW4cZj40s7aRThG+lTcfKi/kL4Vrts/DB193njnLzuvuD8Q9T+svEuYE60AL+LjNfj8YWPYFzGwYfPi+O/g3EbB3/J+OuA7rMcfPhcGuf6JwW5v0zGNWSc9EUKepgm49pl44epfz9vnKPr/QvOP0S9WhyHbKHYd1FRJsgO1WRHYlYBiadbwsfiNnA1O1VsHYNlF2MKtm9KqUKcgCtIMLUjZYj+Vtu641OTQ5p1sWAMPo31K9eF2JROi+S+OG7JNG6JNRrYPwc7aNvhockTIz5zn//gAHxwNnSxPxk2oqu0INoPUjuzofUm9muNi/hz/PltCX/SN6rAe0laqP9s1JxVgr3rnIpsTRzIK/FuiHpOTtouQIsEXaBCKTMTemkTku4zX9G++djq1cc2t19hLm+Rai/uym6LxbZlOy/Rbg43k+2w9c2hCWJL6JPO5A6sml0dbxHZ4h5CQYZugruRWjp+mPr1eeOcDH99wfmHqMfLxkktXoCPyLilbJyDM1sch6sILqdJP4jsHOlJ6Z2XCHHrSyWp4uRdaHzh0CcLyYvNZxIDQ+h5rgG9fn2xBX3iRKkLjQxrkWP+Va4XfWbtaarUg+oq9KBUFG455eskUtKDoulSf1IRumDHbebR8ztuu5s3t7Zsih1Bh9t+3uon9JJeAP0M+Ecb0e0bqNcvME5Th79ClY3fWRq/ccn44vxD68vH/60E/2bq/rLx06X5Ry7h9pdgnNcDeY4XvGmaclFzCVE1F4hwWMp7RSH/2bxCFAMu6EUmHJsCYjuOTZbF+tVeUtZlXQtVqdqNkoQrVLGY3EENhz7oTZi7VAFm0n+w1bCjI7whuq03PGLIxkYy7tUH0hvkDcPt6akoe+/fUvGWDt5n7JFOWzCVDJnbmGM9ek3OZJ30RC3dod7hRkPOiZscAa+nCVfIBwYGgr06p83maPCpBKTn0E56Dn4cM+qEVThmCIS4x+/n0lKn2ELI+q+EjMUGBbrY1dkyXXuBaNG+JVbesxhqae8XOpYGijg/uzPbXephEDmRHgKRq6ugH7+74Phh6utl43eWxm9cMl6cD/oxzelHFeQ074IvMuMOF8wP4G1abpxnJuNuGGcoDx7Hv9PTxVqIwjnLYu3GK9VukHcZMIw4TPSQNW+I4zUvo8iaC+/AuICMH36nfPwXMK4nuN+4ZPwleHuczD/0Utk4V48RHQ5zOnyAKtGqIvMjBZ794YLjh6mjZeN3lsZvXDJenA88u5SzkWK9hvs69lL8gXzQLibxR0/aE18afypUMaIuSlAjuwB05iMG6rfVbZpspNEM9dxQm7IzyD6vft7obe99tVd3xuxDB8ciUM65GtrNo2Go7uy6xDvOP6nGMveOZVtc72jL6T5dwvfINSV8ebcAvkbANgT+dM7LdfZoEbFpG+41zoXECmzNjEh7njUvRp5FAybHLgQmS/HoBRg53TCUtvZqcZPqulzngR5SnF6d043lcpe2srcgaWdHsouHauef7OtLtff1tR/j2lb793Ml65VN3UVTvXJjZ9foaFfnRqpQk9DjoIvNkHfM8cXNGHeNmMF5YwPkjRXYKJeUXrFSkYybAYvb4PzFUozPoPVrHH7lSo+3KRiJZJo8dq06YvbFp8ObO0LrIy6HQe8LRnMh30hc6rCtMNhsOq2uqkrXGnCGdXJ1ja4x6mV16N8i60PmpNMZ1NU31KsUUqk+FXF3Ojj9xLUU0Z+2gh7+9oLjh6lby8bvLI3fSN1ygfmghxdxdkHqETKeKsB/tmz8zsI4xIgdVKkfqaJfovSUA3LyOYcYJ8f5KrHZD8pa2qjiBG2zg3/DjFXFVAK6rOdAq+K7+1bsTjZPJafizpnblLt0jpauwLRyQFDoQKDHfth3RQZnEzuSG1evbg83ydVrXFZfiGF5a5LJNfi12I9Y7M0i0hMo633M0hBgVcx5DQlLeT/ioekvb0jwhj9bbEj8dbEdQbIMD/U+8I5HUbhHdcuWU7Tn6FHCp4VztBUFgX8SsHB8bgkfUsjLJCpgU3njLFj2ucps1qjNZvVTDKNWw4u2ct815uL7sjVDKmbLLb30M0e5cWSAcT5F1YGvgJ9u7U2Pbd6coW/ZzOGE57hQB9i2BkuuRqiE/CNPC0UEJSwZhgu2HE9CXKj6Wp1Urm6JBLVGWbVcKle1wkeTjL6o1mJJdquVshruvQA/ii6h9wJuQipP4ZNaAbzxii5h/5Hem+T0h6LV1CuQSxT4Ui+ECi5fLaRhbu1ihIxEy05kxV2utjaXK/5tg1LR2KhQNND/lEjA97hL2dBAhvDaC0nql2TXH2ijhQoci2uE+FiRqizYhsqjcCmuNsa0pWA7w4XR4fZCWOV8RzfdDHFKj3cRcdepUozPbuFWF67bC9sNuOslqy/0M0r7DPZC/ys7PWlN10+r6kViQV3jhFLT6zY6xU/Sx9k3p6y4w3FSpaNH+GttgfraN4GDBrCzPSR2eqkW7LNauLrEReoS3HkIWFSMjThW7K2KaT3WbwHIUEXqVEpV8mJysESYztlfJHmk1j180fiV/Vm/fziUG/dmojqb0uNSr3UF2b+ZmlttBrNvdSxgdhkt9mwgkahxd01t7BqxrE56Vjh7Uv6MR2fz6IKpPvtEFm1MaKO2BrPPwmb8EXvIq26xRwryrivswerAPlXcHixfVIkPTolwl2lWiriiPQY6S14hAXkJGPJi6uAr8m5rHWzdotzWtk0xDZ+2tg62ba2/KD6tuKR10NG2Jf7www93PpZ9FP5lH+t8GD3w2GNkbWbhh/Q5+hoqQfVAlZcPC1tA17pFcrh2iKC0z3uwjs4aeKlHNWeWbbbbOcEViyVAqZRjlm9VlzaTrLbFs0Ux5rInto99Y2XzWq+rqQLpBt1dq9MXt3o7aqXjUVolV/qMnV8dHjs12XPd0MS6+smdI7cNo5+LfYy7y9nkWhFFY49fuvrra/p3xjwmvtU32pO+PGM3Ni9IJSqNpa918EDX1H2jK69dEdOnho+u26e2+vudnmgf0FxJ9qFfJ+ce64DjfvD2EKubRW7spfUifFJKKcJbjbgvlw+KGKC/FkSw/KSBNYQYeZkNLv+93D71zr5AU5/L1dfU1OukazLsmvS3g3Z7U9BmD07DbwH4rRf/xuLRJrs9SHv7PJ4+v6/X7e713T2/lXbHYl54udmflv3gLQwS3+JaaEE0/RDeM1IShVdxgVhw1eBgriMcDIY7dp+7cv+5dU2Tp3fvPj0RhHtkCy3UO9w9chLfcfy2gwT3ByMduaGhXEckiLacnmxa986VV55bG5w4vZus5VlIU3+j76cEuJNeIRLgXSOeqHAyCe9IKBjPK9dc8wp9f/e8p5vzrTK45zfFe6jiPWQ3VxUixSQjg1te2Ue/1f3FXdw9FQtpxIN7zLgabRSZSf0gAoc4VyeqRYW+PTbfCN6dwpoIK+Ptr3oBpE/AfPh6b4dDp9HoHB3WREJn9fmsukTiWUvW87TBnrQbfujJWrvd5hc76+s7XzSV4Ypqi+uaRSa8rloEoWmuSkSOoarIejFuccCdpGuwnoIsjqvUyEBxMesiAvs8Jm4ls7vbmvX8kKDwtCdrKaxrQPtRAnRTBlGqcLbHjk9/2EMCSBBUAruKOTaum5rSjVc288f1U1P6cX4z+lMiEAoF4rt2xfF7YlfhPOnCIygPsIJUEnQ9LxVjn2IVN5Ie3WKdtTSls124pS6wFQ8z4kbOQd9lG7JTNp9ujd8ba4m3ZIMJz7R/bcv+jFvTZ3eFwm3NK8Je13chADHmsOfRVn9uyGXJGFxWU2NDdY2uJRBor7aut7fbOlO6BqZBp6mW6ttCrnR93tnINFbXOAxmi4Sc3Vy4Cx0mvU0RNYdE5OgqYkBRiikU7osPDcf8K32+lf4zMXrLfDN6AD7CwDzieBpe+Jh6nroOIh/EXFpYkXotEC2Lo2GX3uB0GvSu9eTq0uMcL7zwV/p75B4VVGX1ODuB+/IyFb4aGAxD+SU5SvnnMacTgLv0v1r2LnZyazqXv2O5EXzRO8X4X12P1xTSPFhTXoZ37YVoKL6jM4Wv7GMlqjheXE29DHTJMC9w1/a1AAg1VvDjhZPNLRpXpUioNTv0Rl/IPV4T1fAYvR78bnBjA8EPYBD8DBg/lQzjh7d5XluSt/HOgztO0HPpO5bAR+NFpNns0qVgrcjCX6nnyd5lDT6xxpdIF0+s8Rh+GQtar5VvVHPc1TvxAbK9BcZSHJxu4Om7ZM+3ipqtxhmKREKOBpR4GA2p6pi6Yy7uNl/dtXL0rlOvJ9/fZoPodYBTtfAxsalGqNdr8QlUBzlFwR1Nl5cqorKz6cVySGCLKMvQ/bbPazE3+Va1ZOy7MsnRpgaX2W6Witdb6JIIO5uNGqu20dnV6w87c157i12lt+qkGqGBCZ4pSZWm1FCH/DOhjeBUL9FWkuMyQlIdl4lAXsCFhORSFcLhDI5AgfzAOyIj2u9llmFntWDs0M0FVWU/ihk1Ns0S7HR2LcbOHOL8TwAdQr3AKylk02JqthKlZuU4jpZpBBMt/9JvgCyeMfADJ/EHs4HvR//0hATn+ZInTKbSJ6zHAJu6n8DmE8hLoZYAld3P4eRDJ9F+4l8Z8OxczTErQ6m8SmKATwxWLBBZuWmROLps5GmNu6KiSoM12BtynV3yjf4qaDFt0ekdoMUbGmxLvhH7RvegrxZwqMUnx3DreQ4QINHzPKuJ/Sf2edNSa3p5iQ3Zl1kUyRPQSeoZsr60jAMXoPsJgMyXFCFzdAGsIiXEn6B7qJcJLJAw0DFbKbkQDS1/D8f/PjjEN6GvEv+GvTbOpeck3OaUgRzgv4C3+//j7/jfYy9NNVAp9Aq6D7JMCF8xssvJXRtOTp08OSUm1w9nZx97DF7nz7eHVJDM42vDSTw1R66px4o3EJ7je0zkHqoc9ofchGW/L8JKcRDw7y+hatRYqEFFuAbFOVvD+++jxg3/td/p0LLfoYaFPGH+HJ5RWIPHXGAOr/KLz4tzwtQj4JNbubhM9DBQ5g6YYrR4ZDE2IipNXYdsaAvmVvncGzIZvx9e16XJmz+NYzizcBcd5lFQ1zggy1dTc36iCVflpRJynsAqqSepEF+gYCIkE1JFuFZzLBJSYI9th0JaQcEwuE058ZIKOrzjksGjIx3GNaH2kbbwRGpw/1AmOtixMc4eCHjcTf8aaArs3i3eMCIZ32AKCM/UOvsSodXRytFx6cC6aO2DctdAClWZq+6qdJvZA8FGo636QdIzugv9io4AluSMs5prjqu4DidpjgOOy5CT2ZQqGWCG9pg6wxMDiU3h8KbEwES40xiYjfh8kXFPe7d0w0ZR5yXpjkuzohXd0u52j5h9aeuqGhSqXtWC+alY+JCuArtrwztkzRIa10BysQwSRZNEi2sg/BRSUIw7EE6xi5yVxFmjrRDjImE75L7LH3zA4U4FGkOMabFfEqOr/JsaPXpNo8KzwhFrr7p+WN+Q3hHv39UwVpW0hbrUqprb9/LsjWpdvVEp18sbAlJLU5VUIrKv0nQ79Poua9zeOhaOt8RM7niTqalR0VVVa0vWC0VioUhVU372VAn05KW4mMvXimrAw+Ez5xB98pUiPowhEQ1jCnyIjOxa4QeqIvgkB7zI4QJ06oW//OUvM+++++6Zt/FJVbQ+M5rZtw8uKIOPq+K1NFBHfg9qBB/o15yP6FZeIhJjVomAVXm5CPiYN+MCcq5BoiptjePAS9gG9QO8JelFzuEH2fCzUSZyUBH9T/KEyOBNE4qwg6YdEcXEkcHCRnhulxZVs7+jaWRiP9Bd1o23xI/Fd6zIqKXV6kz3jjayDb4ilVFXS9WZ9h6yaxyle+ht5JkmyNvsYswJk7gepGopHDon3UhAC583x110FVRR/PKupMvdm+pNDA0le1I9Lndfqr9t1aq2vlSv+3RfXzoNr88TPckeu6M32dO+clWiL9lvt/fDHauOrUsl165NptZhH1YB3nkevUJq8EbgXwxwyquEIKd8QGiCq1+IH7NqFJIHa6LLjmbRZcf7caNBgIVX6OswKsauKDTK/3mipWWitZVcg8NNTcPBJnxtqnSbpow+VYOow3lxWqbTyeZL0+CKjgRg4uom+AsOB97Y/KHTpDHWTPxyvUZex+2Le0Duvy08jxDHJ4sBcyz7ZoJ6QOhcRL3iP0FdXr7bvPypIeS4Z2zsxPj4CXxd/Y3Vpb9NG1s2NTdvavH26gz1Kcbb5/X2eyypeoN07J4xbjpc6aPl98x/3DwRj2+OmY16baNnZSg46GvUcbmxDD2Hvls4/66g5nhC7uQ/BOF65D/zaNUZfLgUOKxgKgXAXfikisGXS/TJbyWRvlfYq3e3t7v16LkXtFrp6dOnf3Py5G9Ir3Phz6iNfgT3YXGy/u7AuwP0I/MJavlvdQwPfnoX/0b/CH6rQ/3oO+QsPOR25Aw8j6kL1TH/64rBewdODtKr2M/RAJvHcBbmF47SsYV/KY8z2IZ4dOv8y45CTa2FnO/3AE9LqhVs+XmRqNZfyI05Z1Z6mlTFdazQ28kVZo+yqqq+rsEk7BGnus0elVSqqGuuWUFbD5o8FotparVox0Gj12IxPyningf4M/WNIr0yJtfdXSAX73GXfhNwvyq4GXgO+2Iv+yKu/anNEAPaILYBnhWYFsBTjH0u55vIKTNk7HnqKfjb/Eb2Jz/JEvraqK+jp+lqkkGQZgHXKbgkcPRo8e/r/tuOBm67LXD0Nv9RosMGagL9gU6SekiH61uFWAfrSbGvzFeKJct68Jin5fXuWaNRqTIaVX9AL7Ftrxa+oP9hVKkajUqlaTz7OjekNBK6NgBdWdJ3tyoqKxVWA3qGvR3tYLNo75tDp+4bfIPrfSzOi1mtkUpFpQFdyt4Bc7Pfv+/U0Ju9b3C8NFCvoV+hN4rPO1eIBIDzYo6B/+MFsuT1RvbqDLmHAthDhN4afEacWCxh8lL24mZ8gcXsPIYw82bmpz/NsGymgCO3diXWNx7WpYA1YoqYZOh29ib0zGvPZlkW46hA30HqwrPVNcBdzNc5nYg4Bfkyp2Ar29zb08Yw8BfHf3qHg2Q+6DvmeGGIiZt/7DQYHDgl4vq3KIly9GHQbbxDmrfgXYJZMS+Vb+B2DUQKzJVSeqta8ui0QrH06YbPrBlPJuPJWpxGbVN9oz5nT/T3SxxKvdWqVzokaLsz1tQUcfh0RqUiqNU2p17ZVyNrUGsa5DUYFzPgsgdwwTSDXNQk+soJi//e0+RmZ38w1O909oeC/U6EAk6n3+90Buha3Of0erlrLOb1NTf7yD6dGJ2iXuVFQP54J/sUd4YJnUKbeW0w9svSmAWdQJNk7G1uDPzFarikST+Bwo+cPoi+n2XXkEPQCCoPinoVHeX8Dr+i9Iz61Rnfga4h5OhsOsDu4p5RR5vRMUqFNUkhwudC8wJRtf/8Z9Nx/hNSmALrRl1uozle69YNe9PrRjY9zb7Zluxp0TYaGxQho6m9NbQ100H0y7LwKZoE2DbsifkiG5dT1JLDIFo/bnfalz2XXv60SvERZObWVSqnImm0uzdZ+ULziJdJeu2tm7tWRSxMYl23gDGE1bpGbQvqQBGN3hdItTVZm/i8oDvcAXLEBfalwAf8HLoQZ1FYy03YSGLERuyhCIoMvnjfrljsxb2jzV981N7+CJELOJZG4C1DvYWc5DTDL9FzxNtgOUmo4hzhkjn/gu5aNscCX6fpe8mcI4U582TO29wckI+LctG76d2Q17dSndQKajW1CWwgP1jYK+vx43CM0y+VMIjzG1skwiz2eSDPK9V7itCiW8NnisiH4tPbMNOCn6XgjBMSjZCgpLfgMEpmi95KH0n7fB0dvs6sL40/Fb924iv7G86Ss0jg6MRmvevIkc/gHYqa38HFYTe40nhq+Z25HL760kfwBX0Mkw2uXKfDkHOB/T9+xIW/uwydnfhqcFD/ATA8ATB42m3TS0hUURgH8P/3HQ0bGEVUGB8zYDONOIyDxA0FNbnjnYYWLXos1ChahARRbdr1WEUltLVNq7aC0aa1uNBFoQbRY9FzmVE4orYIvf3P8SJjzOLHd849wznn/9078gtlEUCvolfuoEnPoVdPIKEBunQcgzrBeSs6+TzHcVafQfQRyjrL50usPh2jZc7fci9D39Gg1/msHmUzxvqGdrh+Oaq3WM9yf59WOeae5iEO6QyM3uX+p5HXBHq0hEAqPLNEfciKh7jFu2V1EAEqGEAl/KCNbhwYH4EO0AjXi6xFZOQC9/iIDhnFYbsmf8Jd3UC9rBPH8gkFl6kGM8/f2px+lDPCjCfFhJv0lVb289VQV2K1GavZjNY33sn2xGatwdxAj8vf95+jiJtJxG1mGmYP1ugdLe7nr8G8YL0Z9aiK64PtS9Q3rAOSDH/uVfLpGoDX9J7fCt+L3kdSL6HFNCGta+iSVuSoWRqQp2aO69x8Ekn5zPUFdGILnn6BZ2uV45a84rt9jITcRj/P6Jc5FMjDJnJkqyfP6QdSzmgkv0fPIMX3n7J7yhSKehFp17sE2lyv59GuV9Auv5E2Md5xiXcbYi7rJVrUC3fkLzp4dtmSbd57G0MSunrQLhXQJvd4xgyOMG9Mpvn/mUYGT8Lz1XPqNqcQM1l6gIw+Re4fyv+t7QAAABwAHABQAGYAmgDkAQoBQgGQAaoCBgJSAnQCtgLsAxgDPANcA5oDwAPSA/IEFgQsBFAEcASqBNgFHgVUBaAFvAXiBfwGJAZIBmYGjAbYBxQHQgeAB74H7ggeCGwImAi8CPAJEAkiCWgJlAnICgYKRApmCqwK2gsGCyALSAtoC5QLuAvEC9AL3AvoC/QMAAw0DJAMnAyoDLQMwAzMDNgM5AzwDPwNCA0UDSANLA2ADYwN3g3qDfYOAg4ODhoOJg5gDpIOng6qDrYOwg7ODtoPTg+iD64Pug/GD9IP3g/uEAAQDBAYECQQMBA8EEgQVBBgEGwQuBDEESQRgBGMEZgRpBGwEbwRyBIQEk4SXBKIEpQSphLWEugTFBNCE3wT4BQeFJgVBBUeFToVVBVuFaoV5hYMFm4WkBaqFugXFhc4F24Xkhe2GAAYTBh6GJYY2BkYGT4ZYhmGGcYZ3hn4GggaGBooGjgaShpcGnYajBriGx4bhhu8HBQcWhy4HSAdTB1aHWgdfh2QHcQd0h3kHgAeGh5QHmQeeB6SHrYeyh7+H0QfeB+CH4wflh+kH7gf5iAoIEQgViBoIHohBHjabdBXbM4BFMbh56+7VXvvvVXVrK2ovfesop9a/ahW7RF7hki4ItYNYs+YFyL2ii3h2o4L3FLl0puc83vPec/VUUyRfq1Vzv/0trAilC1My6ugokoqq6Kqauqpr4GGGmmsiaaaaS5JC8laStFKa2201U57qTroqJPOeuolXW999A2K6ae/AQYaZLAhhhpmuBFGGmW0McYaZ7wJJrrjlimOmeq47abJcttd99z3wEOPhDz2xHRP7XDCSc88l+2FTy774IsZZpltphxz7BM2V6755gURQaSX8ixQIN9Ciyyx1GL7LXPKRsuttMoKn13y0VdbbdPDK6+9KfzLO7vFiVZXrATFddHNJJMlWmeD0o6qrqQaIh1UxwFR4p11znkXgig3HXbENdeVCqKddsYN68VYY61dQYyrNtlsizK66i5NpgzvlfDNRTXVVstOh6y2x94gNogL4l0JEoLiQWJQwnc//AxKRoeSMmfntYwIZcyMCmUU9pj8nBnJKWk9ipjcvWdkr/zc8N8hLfUfU/6xVWw4JytpWk54TmxeQbjIxOdl52b93cWFwvm5Re7PeXr79PTfXp9/SgAAeNrVktdPlFEQxX/32wUroIIKinhZYW0RARXdFRU7dgUrWNeGNVhA7GKNxt672DViYi8RY2Uta8UnS+L3F/iqL+Zzsrsxui/G+ORJ7kwm987kzjkHsBE48SiJGFlSKX9tN5IkZ6KxS5WKiyz6ksckpjGbxazAUrmqxKgwPukYHacTtEM7tVuXJzpMTGUaps0MM8MtS6Zo0nDTnWzy8TCdOSyhTOUEu6N1rI73d7t+67YHuq0qOT7LJ7HS8lpegvj+hZ8wi80iM/LzYR2ho3Sylp9rl+yRKVd5/gee4MMCClWKSgWJklW6yiAEyhlIlHGKbdxgB1s5zU52sR8vR7nEIe5hcIRjPMPHc06wnd3cZw8PeMgGnMLVXh6zj0cy5zg3ucUdblPJAdZzl9eU85LLVLCJV7yginesYwsHucZm3vKGi3zgPR85SS/hrQd96Elv4T+bgfSjPwMYyiAGM4QJDGMEOeQyiuE8YSRjGSNb5zOOiSxjiijmEc0mM1WYLxDtZjCTWSygkHnMZw0LKaGIYtFkEU9F2VUsF3VXUspaVjOapYxnI1e4yjnOc4azXOA6c0XFcPVNmKrBV/4Of+bWJq4LI5xqVJf5NakVwnZtIogkijrUpR7RxFCfBjQkljga0Vgc24QEmorzEnHQjCSSQxRqTgta0orWtCGFtuLwNNJpR3s6kEFHOonj3XQWD3WhK91+UfTf8Z974gf5kNMEAA==); + font-style:normal; + font-weight:600; +} +body{ background-color:#f4f8fb; } +body, +h1, +h2, +h3, +h4, +h5, +h6{ margin:0px;padding:0px;line-height:20px;} +ul{ + list-style-type:none; + -webkit-margin-before:0px; + -webkit-margin-after:0px; + -webkit-margin-start:0px; + -webkit-margin-end:0px; + -webkit-padding-start:0px; +} +.country-li .flag-head{ padding:7px;} +.container{ font-family:"Proxima Nova";margin:0px auto; } +.currenc y-content{ width:80%;margin:0px auto;} +.container-left{ margin-top:calc(18% - 12.4%);padding-left:13.1%;padding-top:7px; } +.container-left .choose-currency{ font-weight:700;font-size:20px; } +.container-left .transaction-amount{ color: #898a94;font-weight:500;font-size:16px;} +.currency-parent{ margin-top:30px;padding-left:0px} +.selected{ border:2px solid #F00;color:#F00; } +.currency-loop .selected .full-name{ color:#F00;font-weight: bold; } +.currency-loop{ padding-left:0px; } +.currency-loop .country-li{ + background-color:#fff; + border-radius:6px; + list-style-type:none; + text-align:center; + width:177px; + padding-top:8px; + margin:10px; + height:128px; + display:table-cell; + vertical-align:middle; + float:left; + box-shadow:0px 2px 4px 1px #ccc; +} +.currency-loop .country-li span{ color:#d3d4d6;font-weight: bold; } +.label { background-color:transparent; } +.country-li .short-name{ width:100%; display:block; } \ No newline at end of file diff --git a/webui/flags/1x1/eu.svg b/webui/flags/1x1/eu.svg new file mode 100644 index 000000000..da5152180 --- /dev/null +++ b/webui/flags/1x1/eu.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webui/flags/1x1/um.svg b/webui/flags/1x1/um.svg new file mode 100644 index 000000000..e3e7a60f7 --- /dev/null +++ b/webui/flags/1x1/um.svg @@ -0,0 +1,48 @@ + + + The United States of America flag, produced by Daniel McRae + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webui/flags/1x1/us.svg b/webui/flags/1x1/us.svg new file mode 100644 index 000000000..e3e7a60f7 --- /dev/null +++ b/webui/flags/1x1/us.svg @@ -0,0 +1,48 @@ + + + The United States of America flag, produced by Daniel McRae + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webui/flags/4x3/eu.svg b/webui/flags/4x3/eu.svg new file mode 100644 index 000000000..616735c4a --- /dev/null +++ b/webui/flags/4x3/eu.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webui/flags/4x3/um.svg b/webui/flags/4x3/um.svg new file mode 100644 index 000000000..6d7e675bd --- /dev/null +++ b/webui/flags/4x3/um.svg @@ -0,0 +1,48 @@ + + + The United States of America flag, produced by Daniel McRae + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webui/flags/4x3/us.svg b/webui/flags/4x3/us.svg new file mode 100644 index 000000000..6d7e675bd --- /dev/null +++ b/webui/flags/4x3/us.svg @@ -0,0 +1,48 @@ + + + The United States of America flag, produced by Daniel McRae + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webui/js/currency-array.js b/webui/js/currency-array.js new file mode 100644 index 000000000..288bbe858 --- /dev/null +++ b/webui/js/currency-array.js @@ -0,0 +1,5 @@ +var currency_arr = [ { "id": 1, "shortName": "USD", "fullName": "United States Dollar","flagid":"us","selected":1}, + { "id": 2, "shortName": "EUR", "fullName": " Euro" ,"flagid":"eu","selected":0}, + // Here you can add as much as currency list and pass selected 1 which you want to defaul selected + ]; + \ No newline at end of file diff --git a/webui/js/custom.js b/webui/js/custom.js new file mode 100644 index 000000000..f999be17e --- /dev/null +++ b/webui/js/custom.js @@ -0,0 +1,26 @@ +$(document).ready(function(e) { + var json_Obj =currency_arr; + var outPut=""; + var defaultActive=""; + + for (var i in json_Obj) + { + defaultActive=""; + if(json_Obj[i].selected==1) + defaultActive=" selected"; + + outPut+="
  • " + + json_Obj[i].shortName + " " + +json_Obj[i].fullName+"
  • "; + } + $('.currency-loop').html(outPut); + $('.country-li').on("click",function(){ + console.clear() + $('.country-li').removeClass("selected"); + $(this).addClass("selected"); + var id=$(this).attr("data-id"); + console.log(currency_arr[id-1]); }); +}); \ No newline at end of file diff --git a/webui/js/jquery.min.js b/webui/js/jquery.min.js new file mode 100644 index 000000000..5c82cc00e --- /dev/null +++ b/webui/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.2.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c; +}catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,la=/\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("