diff --git a/.gitignore b/.gitignore index 29a8aeb20..ee8ea0277 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ web/serverconfig.php web/assets/ *.rej *.orig +.idea/* +web/yaamp/.idea/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..f9546188c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: cpp +script: + - (cd blocknotify && make) + - (cd stratum/iniparser && make) + - (cd stratum && make) diff --git a/README.md b/README.md index 3472e5567..99c19e84d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/tpruvot/yiimp.svg?branch=next)](https://travis-ci.org/tpruvot/yiimp) + #yiimp - yaamp fork Required: diff --git a/rc.local b/rc.local index 9da2b84e3..9dea15bd2 100644 --- a/rc.local +++ b/rc.local @@ -15,6 +15,7 @@ STRATUM_DIR=/var/stratum screen -dmS main $WEB_DIR/main.sh screen -dmS loop2 $WEB_DIR/loop2.sh screen -dmS blocks $WEB_DIR/blocks.sh +#screen -dmS ln $WEB_DIR/ln.sh screen -dmS debug tail -f $LOG_DIR/debug.log # Stratum instances (skipped/exit if no .conf) @@ -49,7 +50,8 @@ screen -dmS jha $STRATUM_DIR/run.sh jha #screen -dmS dmd-gr $STRATUM_DIR/run.sh dmd-gr screen -dmS myr-gr $STRATUM_DIR/run.sh myr-gr screen -dmS lbry $STRATUM_DIR/run.sh lbry -screen -dmS lyra2 $STRATUM_DIR/run.sh lyra2 +screen -dmS allium $STRATUM_DIR/run.sh allium +#screen -dmS lyra2 $STRATUM_DIR/run.sh lyra2 screen -dmS lyra2v2 $STRATUM_DIR/run.sh lyra2v2 screen -dmS zero $STRATUM_DIR/run.sh lyra2z diff --git a/sql/2018-08-lightning-testnet.sql b/sql/2018-08-lightning-testnet.sql new file mode 100644 index 000000000..6b274e432 --- /dev/null +++ b/sql/2018-08-lightning-testnet.sql @@ -0,0 +1,14 @@ +CREATE TABLE `invoices` ( + `id` int(11) NOT NULL, + `userid` int(11) NOT NULL, + `workerid` int(11) NOT NULL, + `bolt11` varchar(1000) NOT NULL, + `amount` int(11) NOT NULL, + `paid` int(11) NOT NULL, + `shop` text, + `description` text NOT NULL, + `status` varchar(80) DEFAULT NULL, + `exectime` int(10) UNSIGNED NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `workers` ADD `work` DOUBLE NOT NULL DEFAULT '0.0' AFTER `algo`; diff --git a/stratum/algos/Lyra2z.c b/stratum/algos/Lyra2-z.c similarity index 100% rename from stratum/algos/Lyra2z.c rename to stratum/algos/Lyra2-z.c diff --git a/stratum/algos/Lyra2z.h b/stratum/algos/Lyra2-z.h similarity index 100% rename from stratum/algos/Lyra2z.h rename to stratum/algos/Lyra2-z.h diff --git a/stratum/algos/aergo.c b/stratum/algos/aergo.c new file mode 100644 index 000000000..7a791846c --- /dev/null +++ b/stratum/algos/aergo.c @@ -0,0 +1,162 @@ +#include "aergo.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gost.h" + +#include "common.h" + +void aergo_hash(const char* input, char* output, uint32_t len) +{ + uint32_t hash[16]; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_skein512_context ctx_skein; + sph_luffa512_context ctx_luffa; + sph_cubehash512_context ctx_cubehash; + sph_shavite512_context ctx_shavite; + sph_simd512_context ctx_simd; + sph_echo512_context ctx_echo; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_gost512_context ctx_gost; + sph_whirlpool_context ctx_whirlpool; + sph_haval256_5_context ctx_haval; + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, input, len); + sph_echo512_close(&ctx_echo, hash); + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, hash, 64); + sph_blake512_close(&ctx_blake, hash); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hash, 64); + sph_whirlpool_close(&ctx_whirlpool, hash); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_gost512_init(&ctx_gost); + sph_gost512(&ctx_gost, hash, 64); + sph_gost512_close(&ctx_gost, hash); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_gost512_init(&ctx_gost); + sph_gost512(&ctx_gost, hash, 64); + sph_gost512_close(&ctx_gost, hash); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, hash, 64); + sph_fugue512_close(&ctx_fugue, hash); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hash, 64); + sph_shabal512_close(&ctx_shabal, hash); + + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval,(const void*) hash, 64); + sph_haval256_5_close(&ctx_haval, hash); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_gost512_init(&ctx_gost); + sph_gost512(&ctx_gost, hash, 64); + sph_gost512_close(&ctx_gost, hash); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, hash, 64); + sph_blake512_close(&ctx_blake, hash); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + memcpy(output, hash, 32); +} diff --git a/stratum/algos/aergo.h b/stratum/algos/aergo.h new file mode 100644 index 000000000..ad129b32a --- /dev/null +++ b/stratum/algos/aergo.h @@ -0,0 +1,17 @@ + +#ifndef AERGO_H +#define AERGO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void aergo_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/stratum/algos/allium.c b/stratum/algos/allium.c new file mode 100644 index 000000000..4c3569d36 --- /dev/null +++ b/stratum/algos/allium.c @@ -0,0 +1,46 @@ +#include + +#include "sha3/sph_blake.h" +#include "sha3/sph_groestl.h" +#include "sha3/sph_skein.h" +#include "sha3/sph_keccak.h" +#include "sha3/sph_cubehash.h" + +#include "Lyra2.h" + +void allium_hash(const char* input, char* output, uint32_t len) +{ + uint32_t hashA[8], hashB[8]; + + sph_blake256_context ctx_blake; + sph_keccak256_context ctx_keccak; + sph_cubehash512_context ctx_cubehash; + sph_skein256_context ctx_skein; + sph_groestl256_context ctx_groestl; + + sph_blake256_init(&ctx_blake); + sph_blake256(&ctx_blake, input, 80); + sph_blake256_close(&ctx_blake, hashA); + + sph_keccak256_init(&ctx_keccak); + sph_keccak256(&ctx_keccak, hashA, 32); + sph_keccak256_close(&ctx_keccak, hashB); + + LYRA2(hashA, 32, hashB, 32, hashB, 32, 1, 8, 8); + + sph_cubehash256_init(&ctx_cubehash); + sph_cubehash256(&ctx_cubehash, hashA, 32); + sph_cubehash256_close(&ctx_cubehash, hashB); + + LYRA2(hashA, 32, hashB, 32, hashB, 32, 1, 8, 8); + + sph_skein256_init(&ctx_skein); + sph_skein256(&ctx_skein, hashA, 32); + sph_skein256_close(&ctx_skein, hashB); + + sph_groestl256_init(&ctx_groestl); + sph_groestl256(&ctx_groestl, hashB, 32); + sph_groestl256_close(&ctx_groestl, hashA); + + memcpy(output, hashA, 32); +} diff --git a/stratum/algos/allium.h b/stratum/algos/allium.h new file mode 100644 index 000000000..3705161f7 --- /dev/null +++ b/stratum/algos/allium.h @@ -0,0 +1,16 @@ +#ifndef ALLIUM_H +#define ALLIUM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void allium_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/blake2.c b/stratum/algos/blake2s.c similarity index 100% rename from stratum/algos/blake2.c rename to stratum/algos/blake2s.c diff --git a/stratum/algos/blake2.h b/stratum/algos/blake2s.h similarity index 100% rename from stratum/algos/blake2.h rename to stratum/algos/blake2s.h diff --git a/stratum/algos/hex.c b/stratum/algos/hex.c new file mode 100644 index 000000000..9a294d119 --- /dev/null +++ b/stratum/algos/hex.c @@ -0,0 +1,180 @@ +// Copyright (c) 2018 The XDNA Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include + +#include "hex.h" + +#include "../sha3/sph_blake.h" +#include "../sha3/sph_bmw.h" +#include "../sha3/sph_groestl.h" +#include "../sha3/sph_skein.h" +#include "../sha3/sph_jh.h" +#include "../sha3/sph_keccak.h" + +#include "../sha3/sph_luffa.h" +#include "../sha3/sph_cubehash.h" +#include "../sha3/sph_shavite.h" +#include "../sha3/sph_simd.h" +#include "../sha3/sph_echo.h" + +#include "../sha3/sph_hamsi.h" +#include "../sha3/sph_fugue.h" +#include "../sha3/sph_shabal.h" +#include "../sha3/sph_whirlpool.h" +#include "../sha3/sph_sha2.h" + +enum Algo { + BLAKE = 0, + BMW, + GROESTL, + JH, + KECCAK, + SKEIN, + LUFFA, + CUBEHASH, + SHAVITE, + SIMD, + ECHO, + HAMSI, + FUGUE, + SHABAL, + WHIRLPOOL, + SHA512, + HASH_FUNC_COUNT +}; + +static const int TOTAL_CYCLES = 16; + +static uint8_t get_first_algo(const uint32_t* prevblock) { + uint8_t* data = (uint8_t*)prevblock; + return data[7] >> 4; +} + +void hex_hash(const char* input, char* output, uint32_t len) +{ + unsigned char hash[128]; + uint8_t curr_algo; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_skein512_context ctx_skein; + sph_luffa512_context ctx_luffa; + sph_cubehash512_context ctx_cubehash; + sph_shavite512_context ctx_shavite; + sph_simd512_context ctx_simd; + sph_echo512_context ctx_echo; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + + const void *in = input; + int size = len; + + uint32_t *in32 = (uint32_t*) input; + + // initial algo = first digit of prev block hashorder (cheers, x16r) + curr_algo = get_first_algo(&in32[1]); + + for (int i = 0; i < TOTAL_CYCLES; i++) + { + // Only 4 test algos yet + switch (curr_algo) { + case BLAKE: + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, in, size); + sph_blake512_close(&ctx_blake, hash); + break; + case BMW: + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, in, size); + sph_bmw512_close(&ctx_bmw, hash); + break; + case GROESTL: + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, in, size); + sph_groestl512_close(&ctx_groestl, hash); + break; + case JH: + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, in, size); + sph_jh512_close(&ctx_jh, hash); + break; + case KECCAK: + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, in, size); + sph_keccak512_close(&ctx_keccak, hash); + break; + case SKEIN: + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, in, size); + sph_skein512_close(&ctx_skein, hash); + break; + case LUFFA: + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, in, size); + sph_luffa512_close(&ctx_luffa, hash); + break; + case CUBEHASH: + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, in, size); + sph_cubehash512_close(&ctx_cubehash, hash); + break; + case SHAVITE: + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, in, size); + sph_shavite512_close(&ctx_shavite, hash); + break; + case SIMD: + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, in, size); + sph_simd512_close(&ctx_simd, hash); + break; + + case ECHO: + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, in, size); + sph_echo512_close(&ctx_echo, hash); + break; + case HAMSI: + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, in, size); + sph_hamsi512_close(&ctx_hamsi, hash); + break; + case FUGUE: + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, in, size); + sph_fugue512_close(&ctx_fugue, hash); + break; + case SHABAL: + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, in, size); + sph_shabal512_close(&ctx_shabal, hash); + break; + case WHIRLPOOL: + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, in, size); + sph_whirlpool_close(&ctx_whirlpool, hash); + break; + case SHA512: + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) in, size); + sph_sha512_close(&ctx_sha512,(void*) hash); + break; + } + // next algos = first digit on prev hash + curr_algo = (uint8_t)hash[0] % HASH_FUNC_COUNT; + in = (void*)hash; + size = 64; + } + + memcpy(output, hash, 32); +} diff --git a/stratum/algos/hex.h b/stratum/algos/hex.h new file mode 100644 index 000000000..101f1a17d --- /dev/null +++ b/stratum/algos/hex.h @@ -0,0 +1,20 @@ +// Copyright (c) 2018 The XDNA Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef HEXHASH_H +#define HEXHASH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void hex_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif // HEXHASH_H diff --git a/stratum/algos/lyra2z.c b/stratum/algos/lyra2z.c index b83b83881..0d946def4 100644 --- a/stratum/algos/lyra2z.c +++ b/stratum/algos/lyra2z.c @@ -3,7 +3,7 @@ #include #include -#include "Lyra2z.h" +#include "Lyra2-z.h" #include diff --git a/stratum/algos/makefile b/stratum/algos/makefile index b684b8716..5640cfa08 100644 --- a/stratum/algos/makefile +++ b/stratum/algos/makefile @@ -8,19 +8,18 @@ CXXFLAGS = -O2 -I.. -march=native CFLAGS= $(CXXFLAGS) -std=gnu99 LDFLAGS=-O2 -lgmp -SOURCES=lyra2re.c lyra2v2.c Lyra2.c lyra2z.c Lyra2z.c Sponge.c \ - blake.c scrypt.c c11.c x11.c x13.c sha256.c sha256t.c jha.c keccak.c deep.c tribus.c \ - hsr14.c sm3.c \ - x14.c x15.c x17.c nist5.c fresh.c quark.c neoscrypt.c scryptn.c qubit.c skein.c groestl.c \ - bitcore.c timetravel.c x16r.c xevan.c bastion.c hmq17.c \ - skein2.c zr5.c bmw.c luffa.c pentablake.c whirlpool.c whirlpoolx.c blakecoin.c \ - blake2.c \ - yescrypt.c yescrypt-opt.c sha256_Y.c lbry.c \ - m7m.c magimath.cpp velvet.c \ +SOURCES=lyra2re.c lyra2v2.c Lyra2.c lyra2z.c Lyra2-z.c Sponge.c allium.c \ + c11.c x11.c x12.c x13.c hsr14.c sm3.c x14.c x15.c x17.c \ + blake.c blakecoin.c blake2s.c jha.c keccak.c lbry.c tribus.c \ + deep.c fresh.c groestl.c neoscrypt.c nist5.c quark.c qubit.c skein.c skein2.c \ + bitcore.c timetravel.c x11evo.c x16r.c x16s.c xevan.c bastion.c hmq17.c sonoa.c \ + bmw.c luffa.c pentablake.c vitalium.c whirlpool.c whirlpoolx.c zr5.c \ + scrypt.c scryptn.c sha256.c sha256t.c \ + yescrypt.c yescrypt-opt.c sha256_Y.c \ + a5a.c a5amath.c m7m.c magimath.cpp velvet.c \ argon2a.c ar2/blake2b.c ar2/argon2.c ar2/ref.c ar2/cores.c ar2/ar2-scrypt-jane.c \ - a5a.c a5amath.c \ - hive.c pomelo.c \ - phi.c polytimos.c skunk.c sib.c veltor.c gost.c x11evo.c + hive.c pomelo.c hex.c \ + phi.c phi2.c polytimos.c skunk.c sib.c veltor.c gost.c aergo.c OBJECTS=$(SOURCES:%.c=%.o) $(SOURCES:%.cpp=%.o) OUTPUT=libalgos.a diff --git a/stratum/algos/phi2.c b/stratum/algos/phi2.c new file mode 100644 index 000000000..1aad37200 --- /dev/null +++ b/stratum/algos/phi2.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "gost.h" + +#include "Lyra2.h" + +#include "common.h" + +void phi2_hash(const char* input, char* output, uint32_t len) +{ + unsigned char _ALIGN(128) hash[64]; + unsigned char _ALIGN(128) hashA[64]; + unsigned char _ALIGN(128) hashB[64]; + + sph_cubehash512_context ctx_cubehash; + sph_jh512_context ctx_jh; + sph_gost512_context ctx_gost; + sph_echo512_context ctx_echo; + sph_skein512_context ctx_skein; + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, input, len); + sph_cubehash512_close(&ctx_cubehash, (void*)hashB); + + LYRA2(&hashA[ 0], 32, &hashB[ 0], 32, &hashB[ 0], 32, 1, 8, 8); + LYRA2(&hashA[32], 32, &hashB[32], 32, &hashB[32], 32, 1, 8, 8); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, (const void*)hashA, 64); + sph_jh512_close(&ctx_jh, (void*)hash); + + if (hash[0] & 1) { + sph_gost512_init(&ctx_gost); + sph_gost512(&ctx_gost, (const void*)hash, 64); + sph_gost512_close(&ctx_gost, (void*)hash); + } else { + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, (const void*)hash, 64); + sph_echo512_close(&ctx_echo, (void*)hash); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, (const void*)hash, 64); + sph_echo512_close(&ctx_echo, (void*)hash); + } + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, (const void*)hash, 64); + sph_skein512_close(&ctx_skein, (void*)hash); + + for (int i=0; i<32; i++) + hash[i] ^= hash[i+32]; + + memcpy(output, hash, 32); +} diff --git a/stratum/algos/phi2.h b/stratum/algos/phi2.h new file mode 100644 index 000000000..d551d2849 --- /dev/null +++ b/stratum/algos/phi2.h @@ -0,0 +1,16 @@ +#ifndef PHI2_H +#define PHI2_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void phi2_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/sonoa.c b/stratum/algos/sonoa.c new file mode 100644 index 000000000..ade6ef973 --- /dev/null +++ b/stratum/algos/sonoa.c @@ -0,0 +1,369 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +void sonoa_hash(const char* input, char* output, uint32_t len) +{ + uint8_t _ALIGN(128) hash[64]; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_skein512_context ctx_skein; + sph_luffa512_context ctx_luffa; + sph_cubehash512_context ctx_cubehash; + sph_shavite512_context ctx_shavite; + sph_simd512_context ctx_simd; + sph_echo512_context ctx_echo; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + sph_haval256_5_context ctx_haval; + + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, input, 80); + sph_blake512_close(&ctx_blake, hash); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, hash, 64); + sph_fugue512_close(&ctx_fugue, hash); + + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + sph_fugue512(&ctx_fugue, hash, 64); + sph_fugue512_close(&ctx_fugue, hash); + + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, hash, 64); + sph_shabal512_close(&ctx_shabal, hash); + + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_shabal512(&ctx_shabal, hash, 64); + sph_shabal512_close(&ctx_shabal, hash); + + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + sph_fugue512(&ctx_fugue, hash, 64); + sph_fugue512_close(&ctx_fugue, hash); + + sph_shabal512(&ctx_shabal, hash, 64); + sph_shabal512_close(&ctx_shabal, hash); + + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, hash, 64); + sph_whirlpool_close(&ctx_whirlpool, hash); + + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + sph_fugue512(&ctx_fugue, hash, 64); + sph_fugue512_close(&ctx_fugue, hash); + + sph_shabal512(&ctx_shabal, hash, 64); + sph_shabal512_close(&ctx_shabal, hash); + + sph_whirlpool(&ctx_whirlpool, hash, 64); + sph_whirlpool_close(&ctx_whirlpool, hash); + + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) hash, 64); + sph_sha512_close(&ctx_sha512,(void*) hash); + + sph_whirlpool(&ctx_whirlpool, hash, 64); + sph_whirlpool_close(&ctx_whirlpool, hash); + + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + sph_fugue512(&ctx_fugue, hash, 64); + sph_fugue512_close(&ctx_fugue, hash); + + sph_shabal512(&ctx_shabal, hash, 64); + sph_shabal512_close(&ctx_shabal, hash); + + sph_whirlpool(&ctx_whirlpool, hash, 64); + sph_whirlpool_close(&ctx_whirlpool, hash); + + sph_sha512(&ctx_sha512,(const void*) hash, 64); + sph_sha512_close(&ctx_sha512,(void*) hash); + + sph_haval256_5_init(&ctx_haval); + sph_haval256_5(&ctx_haval,(const void*) hash, 64); + sph_haval256_5_close(&ctx_haval, hash); + + memcpy(output, hash, 32); +} + diff --git a/stratum/algos/sonoa.h b/stratum/algos/sonoa.h new file mode 100644 index 000000000..c4b6b88f9 --- /dev/null +++ b/stratum/algos/sonoa.h @@ -0,0 +1,16 @@ +#ifndef SONOA_H +#define SONOA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void sonoa_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/vitalium.c b/stratum/algos/vitalium.c new file mode 100644 index 000000000..2a3b27cbb --- /dev/null +++ b/stratum/algos/vitalium.c @@ -0,0 +1,87 @@ +#include "vitalium.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "gost.h" + +#include "common.h" + +void vitalium_hash(const char* input, char* output, uint32_t len) +{ + sph_skein512_context ctx_skein; + sph_cubehash512_context ctx_cubehash; + sph_fugue512_context ctx_fugue; + sph_gost512_context ctx_gost; + sph_echo512_context ctx_echo; + sph_shavite512_context ctx_shavite; + sph_luffa512_context ctx_luffa; + + //these uint512 in the c++ source of the client are backed by an array of uint32 + uint32_t hashA[16], hashB[16]; + + sph_skein512_init(&ctx_skein); + sph_skein512 (&ctx_skein, input, len); + sph_skein512_close (&ctx_skein, hashA); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512 (&ctx_cubehash, hashA, 64); + sph_cubehash512_close(&ctx_cubehash, hashB); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512 (&ctx_fugue, hashB, 64); + sph_fugue512_close(&ctx_fugue, hashA); + + sph_gost512_init(&ctx_gost); + sph_gost512 (&ctx_gost, hashA, 64); + sph_gost512_close (&ctx_gost, hashB); + + sph_echo512_init(&ctx_echo); + sph_echo512 (&ctx_echo, hashB, 64); + sph_echo512_close(&ctx_echo, hashA); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512 (&ctx_shavite, hashA, 64); + sph_shavite512_close(&ctx_shavite, hashB); + + sph_luffa512_init (&ctx_luffa); + sph_luffa512 (&ctx_luffa, hashB, 64); + sph_luffa512_close (&ctx_luffa, hashA); + + sph_gost512_init(&ctx_gost); + sph_gost512 (&ctx_gost, hashA, 64); + sph_gost512_close (&ctx_gost, hashB); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512 (&ctx_cubehash, hashB, 64); + sph_cubehash512_close(&ctx_cubehash, hashA); + + sph_fugue512_init(&ctx_fugue); + sph_fugue512 (&ctx_fugue, hashA, 64); + sph_fugue512_close(&ctx_fugue, hashB); + + sph_gost512_init(&ctx_gost); + sph_gost512 (&ctx_gost, hashB, 64); + sph_gost512_close (&ctx_gost, hashA); + + sph_echo512_init(&ctx_echo); + sph_echo512 (&ctx_echo, hashA, 64); + sph_echo512_close(&ctx_echo, hashB); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512 (&ctx_shavite, hashB, 64); + sph_shavite512_close(&ctx_shavite, hashA); + + sph_luffa512_init (&ctx_luffa); + sph_luffa512 (&ctx_luffa, hashA, 64); + sph_luffa512_close (&ctx_luffa, hashB); + + memcpy(output, hashB, 32); +} diff --git a/stratum/algos/vitalium.h b/stratum/algos/vitalium.h new file mode 100644 index 000000000..e29b3bcb4 --- /dev/null +++ b/stratum/algos/vitalium.h @@ -0,0 +1,16 @@ +#ifndef VITALITY_H +#define VITALITY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void vitalium_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/x12.c b/stratum/algos/x12.c new file mode 100644 index 000000000..07346a1a7 --- /dev/null +++ b/stratum/algos/x12.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void x12_hash(const char* input, char* output, uint32_t len) +{ + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_luffa512_context ctx_luffa; + sph_cubehash512_context ctx_cubehash; + sph_shavite512_context ctx_shavite; + sph_simd512_context ctx_simd; + sph_echo512_context ctx_echo; + sph_groestl512_context ctx_groestl; + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_hamsi512_context ctx_hamsi; + + uint32_t hash[16]; + + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, input, len); + sph_blake512_close(&ctx_blake, hash); + + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, hash, 64); + sph_bmw512_close(&ctx_bmw, hash); + + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, hash, 64); + sph_luffa512_close(&ctx_luffa, hash); + + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, hash, 64); + sph_cubehash512_close(&ctx_cubehash, hash); + + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, hash, 64); + sph_shavite512_close(&ctx_shavite, hash); + + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, hash, 64); + sph_simd512_close(&ctx_simd, hash); + + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, hash, 64); + sph_echo512_close(&ctx_echo, hash); + + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, hash, 64); + sph_groestl512_close(&ctx_groestl, hash); + + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, hash, 64); + sph_skein512_close(&ctx_skein, hash); + + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, hash, 64); + sph_jh512_close(&ctx_jh, hash); + + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, hash, 64); + sph_keccak512_close(&ctx_keccak, hash); + + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, hash, 64); + sph_hamsi512_close(&ctx_hamsi, hash); + + memcpy(output, hash, 32); +} diff --git a/stratum/algos/x12.h b/stratum/algos/x12.h new file mode 100644 index 000000000..1b7ee985f --- /dev/null +++ b/stratum/algos/x12.h @@ -0,0 +1,16 @@ +#ifndef X12_H +#define X12_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void x12_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/x16s.c b/stratum/algos/x16s.c new file mode 100644 index 000000000..d3f329136 --- /dev/null +++ b/stratum/algos/x16s.c @@ -0,0 +1,180 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +enum Algo { + BLAKE = 0, + BMW, + GROESTL, + JH, + KECCAK, + SKEIN, + LUFFA, + CUBEHASH, + SHAVITE, + SIMD, + ECHO, + HAMSI, + FUGUE, + SHABAL, + WHIRLPOOL, + SHA512, + HASH_FUNC_COUNT +}; + +static void getAlgoString(const uint8_t* prevblock, char *output) +{ + strcpy(output, "0123456789ABCDEF"); + + for(int i = 0; i < 16; i++){ + uint8_t b = (15 - i) >> 1; // 16 ascii hex chars, reversed + uint8_t algoDigit = (i & 1) ? prevblock[b] & 0xF : prevblock[b] >> 4; + + int offset = algoDigit; + // insert the nth character at the front + char oldVal = output[offset]; + for(int j=offset; j-->0;) { + output[j+1] = output[j]; + } + output[0] = oldVal; + } +} + +void x16s_hash(const char* input, char* output, uint32_t len) +{ + uint32_t hash[64/4]; + char hashOrder[HASH_FUNC_COUNT + 1] = { 0 }; + + sph_blake512_context ctx_blake; + sph_bmw512_context ctx_bmw; + sph_groestl512_context ctx_groestl; + sph_skein512_context ctx_skein; + sph_jh512_context ctx_jh; + sph_keccak512_context ctx_keccak; + sph_luffa512_context ctx_luffa; + sph_cubehash512_context ctx_cubehash; + sph_shavite512_context ctx_shavite; + sph_simd512_context ctx_simd; + sph_echo512_context ctx_echo; + sph_hamsi512_context ctx_hamsi; + sph_fugue512_context ctx_fugue; + sph_shabal512_context ctx_shabal; + sph_whirlpool_context ctx_whirlpool; + sph_sha512_context ctx_sha512; + + void *in = (void*) input; + int size = len; + + getAlgoString(&input[4], hashOrder); + + for (int i = 0; i < 16; i++) + { + const char elem = hashOrder[i]; + const uint8_t algo = elem >= 'A' ? elem - 'A' + 10 : elem - '0'; + + switch (algo) { + case BLAKE: + sph_blake512_init(&ctx_blake); + sph_blake512(&ctx_blake, in, size); + sph_blake512_close(&ctx_blake, hash); + break; + case BMW: + sph_bmw512_init(&ctx_bmw); + sph_bmw512(&ctx_bmw, in, size); + sph_bmw512_close(&ctx_bmw, hash); + break; + case GROESTL: + sph_groestl512_init(&ctx_groestl); + sph_groestl512(&ctx_groestl, in, size); + sph_groestl512_close(&ctx_groestl, hash); + break; + case SKEIN: + sph_skein512_init(&ctx_skein); + sph_skein512(&ctx_skein, in, size); + sph_skein512_close(&ctx_skein, hash); + break; + case JH: + sph_jh512_init(&ctx_jh); + sph_jh512(&ctx_jh, in, size); + sph_jh512_close(&ctx_jh, hash); + break; + case KECCAK: + sph_keccak512_init(&ctx_keccak); + sph_keccak512(&ctx_keccak, in, size); + sph_keccak512_close(&ctx_keccak, hash); + break; + case LUFFA: + sph_luffa512_init(&ctx_luffa); + sph_luffa512(&ctx_luffa, in, size); + sph_luffa512_close(&ctx_luffa, hash); + break; + case CUBEHASH: + sph_cubehash512_init(&ctx_cubehash); + sph_cubehash512(&ctx_cubehash, in, size); + sph_cubehash512_close(&ctx_cubehash, hash); + break; + case SHAVITE: + sph_shavite512_init(&ctx_shavite); + sph_shavite512(&ctx_shavite, in, size); + sph_shavite512_close(&ctx_shavite, hash); + break; + case SIMD: + sph_simd512_init(&ctx_simd); + sph_simd512(&ctx_simd, in, size); + sph_simd512_close(&ctx_simd, hash); + break; + case ECHO: + sph_echo512_init(&ctx_echo); + sph_echo512(&ctx_echo, in, size); + sph_echo512_close(&ctx_echo, hash); + break; + case HAMSI: + sph_hamsi512_init(&ctx_hamsi); + sph_hamsi512(&ctx_hamsi, in, size); + sph_hamsi512_close(&ctx_hamsi, hash); + break; + case FUGUE: + sph_fugue512_init(&ctx_fugue); + sph_fugue512(&ctx_fugue, in, size); + sph_fugue512_close(&ctx_fugue, hash); + break; + case SHABAL: + sph_shabal512_init(&ctx_shabal); + sph_shabal512(&ctx_shabal, in, size); + sph_shabal512_close(&ctx_shabal, hash); + break; + case WHIRLPOOL: + sph_whirlpool_init(&ctx_whirlpool); + sph_whirlpool(&ctx_whirlpool, in, size); + sph_whirlpool_close(&ctx_whirlpool, hash); + break; + case SHA512: + sph_sha512_init(&ctx_sha512); + sph_sha512(&ctx_sha512,(const void*) in, size); + sph_sha512_close(&ctx_sha512,(void*) hash); + break; + } + in = (void*) hash; + size = 64; + } + memcpy(output, hash, 32); +} diff --git a/stratum/algos/x16s.h b/stratum/algos/x16s.h new file mode 100644 index 000000000..ec9201c57 --- /dev/null +++ b/stratum/algos/x16s.h @@ -0,0 +1,16 @@ +#ifndef X16S_H +#define X16S_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void x16s_hash(const char* input, char* output, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/stratum/algos/yescrypt-opt.c b/stratum/algos/yescrypt-opt.c index b65cdd2d0..c96190bab 100644 --- a/stratum/algos/yescrypt-opt.c +++ b/stratum/algos/yescrypt-opt.c @@ -942,6 +942,9 @@ yescrypt_kdf(const yescrypt_shared_t * shared, yescrypt_local_t * local, { HMAC_SHA256_CTX_Y ctx; HMAC_SHA256_Init_Y(&ctx, buf, buflen); + if (r == 32) { // yescryptR32 + HMAC_SHA256_Update_Y(&ctx, "WaviBanana", 10); + } else if (r == 16) { // yescryptR16 HMAC_SHA256_Update_Y(&ctx, "Client Key", 10); } diff --git a/stratum/algos/yescrypt.c b/stratum/algos/yescrypt.c index 9fac019ca..2959dfa4b 100644 --- a/stratum/algos/yescrypt.c +++ b/stratum/algos/yescrypt.c @@ -327,35 +327,25 @@ static int yescrypt_bsty(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, uint8_t * buf, size_t buflen) { - static __thread int initialized = 0; - static __thread yescrypt_shared_t shared; - static __thread yescrypt_local_t local; + yescrypt_shared_t shared; + yescrypt_local_t local; int retval; - if (!initialized) { -/* "shared" could in fact be shared, but it's simpler to keep it private - * along with "local". It's dummy and tiny anyway. */ - if (yescrypt_init_shared(&shared, NULL, 0, + if (yescrypt_init_shared(&shared, NULL, 0, 0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0)) return -1; - if (yescrypt_init_local(&local)) { + if (yescrypt_init_local(&local)) { yescrypt_free_shared(&shared); return -1; - } - initialized = 1; } + retval = yescrypt_kdf(&shared, &local, passwd, passwdlen, salt, saltlen, N, r, p, 0, YESCRYPT_FLAGS, buf, buflen); -#if 0 - if (yescrypt_free_local(&local)) { - yescrypt_free_shared(&shared); - return -1; - } - if (yescrypt_free_shared(&shared)) - return -1; - initialized = 0; -#endif + + yescrypt_free_local(&local); + yescrypt_free_shared(&shared); + return retval; } @@ -364,7 +354,13 @@ void yescrypt_hash(const char *input, char *output, uint32_t len) { yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 2048, 8, 1, (uint8_t*)output, 32); } + void yescryptR16_hash(const char *input, char *output, uint32_t len) { yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 4096, 16, 1, (uint8_t*)output, 32); } + +void yescryptR32_hash(const char *input, char *output, uint32_t len) +{ + yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 4096, 32, 1, (uint8_t*)output, 32); +} diff --git a/stratum/algos/yescrypt.h b/stratum/algos/yescrypt.h index f7dac4865..8e87c7bee 100644 --- a/stratum/algos/yescrypt.h +++ b/stratum/algos/yescrypt.h @@ -40,6 +40,7 @@ extern "C" { void yescrypt_hash(const char* input, char* output, uint32_t len); void yescryptR16_hash(const char* input, char* output, uint32_t len); +void yescryptR32_hash(const char* input, char* output, uint32_t len); /** * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): diff --git a/stratum/base58.cpp b/stratum/base58.cpp index 856683ebe..631fde043 100644 --- a/stratum/base58.cpp +++ b/stratum/base58.cpp @@ -96,3 +96,19 @@ bool base58_decode(const char *input, char *output) return true; } + +bool is_base58(char *input) +{ + // All alphanumeric characters except "0", "O", "I" and "l" + size_t i=0, len = strlen(input); + char *c = input; + while (i < len) { + bool isdigit = (c[i] >= '1' && c[i] <= '9'); + bool isalpha = (c[i] >= 'a' && c[i] <= 'z') || (c[i] >= 'A' && c[i] <= 'Z'); + if (!isdigit && !isalpha) return false; + if (c[i] == 'I' || c[i] == 'O' || c[i] == 'l') return false; + i++; + } + return true; +} + diff --git a/stratum/client.cpp b/stratum/client.cpp index bdc6bb2b6..3c2bd94ca 100644 --- a/stratum/client.cpp +++ b/stratum/client.cpp @@ -45,8 +45,8 @@ bool client_subscribe(YAAMP_CLIENT *client, json_value *json_params) if(json_params->u.array.length>0) { - strncpy(client->version, json_params->u.array.values[0]->u.string.ptr, 1023); - // if(!strcmp(client->version, "stratum-proxy/0.0.1")) return false; + if (json_params->u.array.values[0]->u.string.ptr) + strncpy(client->version, json_params->u.array.values[0]->u.string.ptr, 1023); if(strstr(client->version, "NiceHash") || strstr(client->version, "proxy") || strstr(client->version, "/3.")) client->reconnectable = false; @@ -202,7 +202,7 @@ bool client_authorize(YAAMP_CLIENT *client, json_value *json_params) return false; } - if(json_params->u.array.length>1) + if(json_params->u.array.length>1 && json_params->u.array.values[1]->u.string.ptr) strncpy(client->password, json_params->u.array.values[1]->u.string.ptr, 1023); if (g_list_client.count >= g_stratum_max_cons) { @@ -210,7 +210,7 @@ bool client_authorize(YAAMP_CLIENT *client, json_value *json_params) return false; } - if(json_params->u.array.length>0) + if(json_params->u.array.length>0 && json_params->u.array.values[0]->u.string.ptr) { strncpy(client->username, json_params->u.array.values[0]->u.string.ptr, 1023); @@ -229,6 +229,11 @@ bool client_authorize(YAAMP_CLIENT *client, json_value *json_params) } } + if (!is_base58(client->username)) { + clientlog(client, "bad mining address %s", client->username); + return false; + } + bool reset = client_initialize_multialgo(client); if(reset) return false; @@ -286,7 +291,7 @@ bool client_authorize(YAAMP_CLIENT *client, json_value *json_params) bool client_update_block(YAAMP_CLIENT *client, json_value *json_params) { // password, id, block hash - if(json_params->u.array.length < 3) + if(json_params->u.array.length < 3 || !json_params->u.array.values[0]->u.string.ptr) { clientlog(client, "update block, bad params"); return false; diff --git a/stratum/client_submit.cpp b/stratum/client_submit.cpp index 47dfd0fe0..055c349e7 100644 --- a/stratum/client_submit.cpp +++ b/stratum/client_submit.cpp @@ -31,10 +31,14 @@ void build_submit_values(YAAMP_JOB_VALUES *submitvalues, YAAMP_JOB_TEMPLATE *tem #ifdef MERKLE_DEBUGLOG printf("merkle root %s\n", merkleroot.c_str()); #endif - if (!strcmp(g_current_algo->name, "lbry")) { + if (!strcmp(g_stratum_algo, "lbry")) { sprintf(submitvalues->header, "%s%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, templ->claim_be, ntime, templ->nbits, nonce); - ser_string_be(submitvalues->header, submitvalues->header_be, 32 + 20); + ser_string_be(submitvalues->header, submitvalues->header_be, 112/4); + } else if (strlen(templ->extradata_be) == 128) { // LUX SC + sprintf(submitvalues->header, "%s%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, + ntime, templ->nbits, nonce, templ->extradata_be); + ser_string_be(submitvalues->header, submitvalues->header_be, 36); // 80+64 / sizeof(u32) } else { sprintf(submitvalues->header, "%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, ntime, templ->nbits, nonce); @@ -215,7 +219,7 @@ static void client_do_submit(YAAMP_CLIENT *client, YAAMP_JOB *job, YAAMP_JOB_VAL if(hash_int <= coin_target) { char count_hex[8] = { 0 }; - if (templ->txcount <= 255) + if (templ->txcount <= 252) sprintf(count_hex, "%02x", templ->txcount & 0xFF); else sprintf(count_hex, "fd%02x%02x", templ->txcount & 0xFF, templ->txcount >> 8); @@ -339,33 +343,37 @@ static bool ntime_valid_range(const char ntimehex[]) uint32_t ntime = 0; if (strlen(ntimehex) != 8) return false; sscanf(ntimehex, "%8x", &ntime); - if (ntime < 0x57000000 || ntime > 0x60000000) // 14 Jan 2021 - ntime = bswap32(ntime); // just in case... + if (ntime < 0x5b000000 || ntime > 0x60000000) // 14 Jan 2021 + return false; time(&rawtime); - return ((rawtime - ntime) < (23 * 60 * 60)); + return (abs(rawtime - ntime) < (30 * 60)); +} + +static bool valid_string_params(json_value *json_params) +{ + for(int p=0; p < json_params->u.array.length; p++) { + if (!json_is_string(json_params->u.array.values[p])) + return false; + } + return true; } bool client_submit(YAAMP_CLIENT *client, json_value *json_params) { // submit(worker_name, jobid, extranonce2, ntime, nonce): - if(json_params->u.array.length<5) - { + if(json_params->u.array.length<5 || !valid_string_params(json_params)) { debuglog("%s - %s bad message\n", client->username, client->sock->ip); client->submit_bad++; return false; } - char extranonce2[32]; - char ntime[32]; - char nonce[32]; - char vote[8]; - - memset(extranonce2, 0, 32); - memset(ntime, 0, 32); - memset(nonce, 0, 32); - memset(vote, 0, 8); + char extranonce2[32] = { 0 }; + char extra[160] = { 0 }; + char nonce[80] = { 0 }; + char ntime[32] = { 0 }; + char vote[8] = { 0 }; - if (!json_params->u.array.values[1]->u.string.ptr || strlen(json_params->u.array.values[1]->u.string.ptr) > 32) { + if (strlen(json_params->u.array.values[1]->u.string.ptr) > 32) { clientlog(client, "bad json, wrong jobid len"); client->submit_bad++; return false; @@ -375,17 +383,27 @@ bool client_submit(YAAMP_CLIENT *client, json_value *json_params) strncpy(extranonce2, json_params->u.array.values[2]->u.string.ptr, 31); strncpy(ntime, json_params->u.array.values[3]->u.string.ptr, 31); strncpy(nonce, json_params->u.array.values[4]->u.string.ptr, 31); - if (json_params->u.array.length == 6) - strncpy(vote, json_params->u.array.values[5]->u.string.ptr, 7); - - if (g_debuglog_hash) { - debuglog("submit %s (uid %d) %d, %s, %s, %s\n", client->sock->ip, client->userid, jobid, extranonce2, ntime, nonce); - } string_lower(extranonce2); string_lower(ntime); string_lower(nonce); - string_lower(vote); + + if (json_params->u.array.length == 6) { + if (strstr(g_stratum_algo, "phi")) { + // lux optional field, smart contral root hashes (not mandatory on shares submit) + strncpy(extra, json_params->u.array.values[5]->u.string.ptr, 128); + string_lower(extra); + } else { + // heavycoin vote + strncpy(vote, json_params->u.array.values[5]->u.string.ptr, 7); + string_lower(vote); + } + } + + if (g_debuglog_hash) { + debuglog("submit %s (uid %d) %d, %s, t=%s, n=%s, extra=%s\n", client->sock->ip, client->userid, + jobid, extranonce2, ntime, nonce, extra); + } YAAMP_JOB *job = (YAAMP_JOB *)object_find(&g_list_job, jobid, true); if(!job) @@ -413,7 +431,7 @@ bool client_submit(YAAMP_CLIENT *client, json_value *json_params) if(strcmp(ntime, templ->ntime)) { - if (!ntime_valid_range(ntime)) { + if (!ishexa(ntime, 8) || !ntime_valid_range(ntime)) { client_submit_error(client, job, 23, "Invalid time rolling", extranonce2, ntime, nonce); return true; } diff --git a/stratum/coinbase.cpp b/stratum/coinbase.cpp index 4b99ef289..f42879fa4 100644 --- a/stratum/coinbase.cpp +++ b/stratum/coinbase.cpp @@ -14,12 +14,30 @@ static void encode_tx_value(char *encoded, json_int_t value) TX_VALUE(value, 32), TX_VALUE(value, 40), TX_VALUE(value, 48), TX_VALUE(value, 56)); } +static void p2sh_pack_tx(YAAMP_COIND *coind, char *data, json_int_t amount, char *payee) +{ + char evalue[32]; + char coinb2_part[256]; + char coinb2_len[4]; + sprintf(coinb2_part, "a9%02x%s87", (unsigned int)(strlen(payee) >> 1) & 0xFF, payee); + sprintf(coinb2_len, "%02x", (unsigned int)(strlen(coinb2_part) >> 1) & 0xFF); + encode_tx_value(evalue, amount); + strcat(data, evalue); + strcat(data, coinb2_len); + strcat(data, coinb2_part); +} + static void job_pack_tx(YAAMP_COIND *coind, char *data, json_int_t amount, char *key) { int ol = strlen(data); char evalue[32]; - encode_tx_value(evalue, amount); + if(coind->p2sh_address && !key) { + p2sh_pack_tx(coind, data, amount, coind->script_pubkey); + return; + } + + encode_tx_value(evalue, amount); sprintf(data+strlen(data), "%s", evalue); if(coind->pos && !key) @@ -206,7 +224,7 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * } // 2 txs are required on these coins, one for foundation (dev fees) - if(coind->charity_percent) + if(coind->charity_percent && !coind->hasmasternodes) { char script_payee[1024]; char charity_payee[256] = { 0 }; @@ -278,7 +296,7 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * char script_dests[2048] = { 0 }; char script_payee[128] = { 0 }; char payees[4]; // addresses count - int npayees = 1; + int npayees = (templ->has_segwit_txs) ? 2 : 1; bool masternode_enabled = json_get_bool(json_result, "masternode_payments_enforced"); bool superblocks_enabled = json_get_bool(json_result, "superblocks_enabled"); json_value* superblock = json_get_array(json_result, "superblock"); @@ -288,6 +306,26 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * debuglog("%s is using old masternodes rpc keys\n", coind->symbol); return; } + if(coind->charity_percent) { + char charity_payee[256] = { 0 }; + const char *payee = json_get_string(json_result, "payee"); + if (payee) snprintf(charity_payee, 255, "%s", payee); + else sprintf(charity_payee, "%s", coind->charity_address); + if (strlen(charity_payee) == 0) + stratumlog("ERROR %s has no charity_address set!\n", coind->name); + json_int_t charity_amount = (available * coind->charity_percent) / 100; + npayees++; + available -= charity_amount; + coind->charity_amount = charity_amount; + base58_decode(charity_payee, script_payee); + job_pack_tx(coind, script_dests, charity_amount, script_payee); + } + // smart contracts balance refund, same format as DASH superblocks + json_value* screfund = json_get_array(json_result, "screfund"); + if(screfund && screfund->u.array.length) { + superblocks_enabled = true; + superblock = screfund; + } if(superblocks_enabled && superblock) { for(int i = 0; i < superblock->u.array.length; i++) { const char *payee = json_get_string(superblock->u.array.values[i], "payee"); @@ -296,27 +334,38 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * npayees++; available -= amount; base58_decode(payee, script_payee); - job_pack_tx(coind, script_dests, amount, script_payee); + bool superblock_use_p2sh = (strcmp(coind->symbol, "MAC") == 0); + if(superblock_use_p2sh) + p2sh_pack_tx(coind, script_dests, amount, script_payee); + else + job_pack_tx(coind, script_dests, amount, script_payee); //debuglog("%s superblock %s %u\n", coind->symbol, payee, amount); } } } if (masternode_enabled && masternode) { + bool started = json_get_bool(json_result, "masternode_payments_started"); const char *payee = json_get_string(masternode, "payee"); json_int_t amount = json_get_int(masternode, "amount"); - if (payee && amount) { + if (payee && amount && started) { npayees++; available -= amount; base58_decode(payee, script_payee); - job_pack_tx(coind, script_dests, amount, script_payee); + bool masternode_use_p2sh = (strcmp(coind->symbol, "MAC") == 0); + if(masternode_use_p2sh) + p2sh_pack_tx(coind, script_dests, amount, script_payee); + else + job_pack_tx(coind, script_dests, amount, script_payee); } } sprintf(payees, "%02x", npayees); strcat(templ->coinb2, payees); + if (templ->has_segwit_txs) strcat(templ->coinb2, commitment); strcat(templ->coinb2, script_dests); job_pack_tx(coind, templ->coinb2, available, NULL); strcat(templ->coinb2, "00000000"); // locktime coind->reward = (double)available/100000000*coind->reward_mul; + //debuglog("%s total %u available %u\n", coind->symbol, templ->value, available); //debuglog("%s %d dests %s\n", coind->symbol, npayees, script_dests); return; } diff --git a/stratum/coind.cpp b/stratum/coind.cpp index 4ba9ab84f..cfda91cfe 100644 --- a/stratum/coind.cpp +++ b/stratum/coind.cpp @@ -114,7 +114,12 @@ bool coind_validate_address(YAAMP_COIND *coind) char params[YAAMP_SMALLBUFSIZE]; sprintf(params, "[\"%s\"]", coind->wallet); - json_value *json = rpc_call(&coind->rpc, "validateaddress", params); + json_value *json; + bool getaddressinfo = (strcmp(coind->symbol,"DGB") == 0); + if(getaddressinfo) + json = rpc_call(&coind->rpc, "getaddressinfo", params); + else + json = rpc_call(&coind->rpc, "validateaddress", params); if(!json) return false; json_value *json_result = json_get_object(json, "result"); @@ -124,11 +129,12 @@ bool coind_validate_address(YAAMP_COIND *coind) return false; } - bool isvalid = json_get_bool(json_result, "isvalid"); + bool isvalid = getaddressinfo || json_get_bool(json_result, "isvalid"); if(!isvalid) stratumlog("%s wallet %s is not valid.\n", coind->name, coind->wallet); bool ismine = json_get_bool(json_result, "ismine"); if(!ismine) stratumlog("%s wallet %s is not mine.\n", coind->name, coind->wallet); + else isvalid = ismine; const char *p = json_get_string(json_result, "pubkey"); strcpy(coind->pubkey, p ? p : ""); @@ -139,6 +145,8 @@ bool coind_validate_address(YAAMP_COIND *coind) if (!base58_decode(coind->wallet, coind->script_pubkey)) stratumlog("Warning: unable to decode %s %s script pubkey\n", coind->symbol, coind->wallet); + coind->p2sh_address = json_get_bool(json_result, "isscript"); + // if base58 decode fails if (!strlen(coind->script_pubkey)) { const char *pk = json_get_string(json_result, "scriptPubKey"); diff --git a/stratum/coind.h b/stratum/coind.h index d008a24e7..f58f091b7 100644 --- a/stratum/coind.h +++ b/stratum/coind.h @@ -35,6 +35,7 @@ class YAAMP_COIND: public YAAMP_OBJECT char pubkey[1024]; char script_pubkey[1024]; + bool p2sh_address; bool pos; bool hassubmitblock; diff --git a/stratum/coind_template.cpp b/stratum/coind_template.cpp index cca3ebfff..33ecc6259 100644 --- a/stratum/coind_template.cpp +++ b/stratum/coind_template.cpp @@ -333,6 +333,18 @@ YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) } } + const char *sc_root = json_get_string(json_result, "stateroot"); + const char *sc_utxo = json_get_string(json_result, "utxoroot"); + if (sc_root && sc_utxo) { + // LUX Smart Contracts, 144-bytes block headers + strcpy(&templ->extradata_hex[ 0], sc_root); // 32-bytes hash (64 in hexa) + strcpy(&templ->extradata_hex[64], sc_utxo); // 32-bytes hash too + + // same weird byte order as previousblockhash field + ser_string_be2(sc_root, &templ->extradata_be[ 0], 8); + ser_string_be2(sc_utxo, &templ->extradata_be[64], 8); + } + if (strcmp(coind->rpcencoding, "DCR") == 0) { decred_fix_template(coind, templ, json_result); } diff --git a/stratum/config.sample/aergo.conf b/stratum/config.sample/aergo.conf new file mode 100644 index 000000000..c7488e3a7 --- /dev/null +++ b/stratum/config.sample/aergo.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 3691 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = aergo +difficulty = 0.001 +max_ttf = 400000000 \ No newline at end of file diff --git a/stratum/config.sample/allium.conf b/stratum/config.sample/allium.conf new file mode 100644 index 000000000..1f8f1921a --- /dev/null +++ b/stratum/config.sample/allium.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 4443 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = allium +difficulty = 1 +max_ttf = 4000000 diff --git a/stratum/config.sample/phi2.conf b/stratum/config.sample/phi2.conf new file mode 100644 index 000000000..f96111283 --- /dev/null +++ b/stratum/config.sample/phi2.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 8332 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = phi2 +difficulty = 1 +max_ttf = 40000 + diff --git a/stratum/config.sample/vitalium.conf b/stratum/config.sample/vitalium.conf new file mode 100644 index 000000000..ff522cbb1 --- /dev/null +++ b/stratum/config.sample/vitalium.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 3233 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = vitalium +difficulty = 0.001 +max_ttf = 400000000 + diff --git a/stratum/config.sample/x12.conf b/stratum/config.sample/x12.conf new file mode 100644 index 000000000..6bce44ac8 --- /dev/null +++ b/stratum/config.sample/x12.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 3233 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x12 +difficulty = 0.008 +max_ttf = 50000 + diff --git a/stratum/config.sample/x16s.conf b/stratum/config.sample/x16s.conf new file mode 100644 index 000000000..d71d25ec7 --- /dev/null +++ b/stratum/config.sample/x16s.conf @@ -0,0 +1,16 @@ +[TCP] +server = yaamp.com +port = 3663 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = x16s +difficulty = 0.25 +max_ttf = 50000 + diff --git a/stratum/config.sample/yescryptR32.conf b/stratum/config.sample/yescryptR32.conf new file mode 100644 index 000000000..7494625ea --- /dev/null +++ b/stratum/config.sample/yescryptR32.conf @@ -0,0 +1,15 @@ +[TCP] +server = yaamp.com +port = 6343 +password = tu8tu5 + +[SQL] +host = yaampdb +database = yaamp +username = root +password = patofpaq + +[STRATUM] +algo = yescryptR32 +difficulty = 1 +max_ttf = 400000000 diff --git a/stratum/db.cpp b/stratum/db.cpp index 3b3441542..f8c513cd8 100644 --- a/stratum/db.cpp +++ b/stratum/db.cpp @@ -55,6 +55,19 @@ char *db_clean_string(YAAMP_DB *db, char *string) return string; } +// allow more chars without the most hurting ones (bench device names) +static void clean_html(char* string) +{ + char *c = string; + size_t i, len = strlen(string) & 0x1FF; + for (i = 0; i < len; i++) { + if (c[i] == '<' || c[i] == '>' || c[i] == '%' || c[i] == '\\' || c[i] == '"' || c[i] == '\'') { + c[i] = '\0'; break; + } + } + if (strstr(string, "script")) strcpy(string, ""); +} + void db_query(YAAMP_DB *db, const char *format, ...) { va_list arglist; @@ -536,7 +549,7 @@ static void _json_str_safe(YAAMP_DB *db, json_value *json, const char *key, size char escaped[256] = { 0 }; snprintf(str, sizeof(str)-1, "%s", json_string_value(val)); str[maxlen-1] = '\0'; // truncate to dest len - //db_clean_string(db, str); + clean_html(str); mysql_real_escape_string(&db->mysql, escaped, str, strlen(str)); snprintf(out, maxlen, "%s", escaped); out[maxlen-1] = '\0'; diff --git a/stratum/job.h b/stratum/job.h index 59657fc12..aef4bdbe1 100644 --- a/stratum/job.h +++ b/stratum/job.h @@ -24,9 +24,13 @@ struct YAAMP_JOB_TEMPLATE int created; char flags[64]; - char prevhash_hex[1024]; - char prevhash_be[1024]; + char prevhash_hex[512]; + char prevhash_be[512]; + char extradata_hex[512]; + char extradata_be[512]; + + // todo: can use extra field char claim_hex[128]; char claim_be[128]; diff --git a/stratum/job_send.cpp b/stratum/job_send.cpp index 8ed6a237f..5af3c7272 100644 --- a/stratum/job_send.cpp +++ b/stratum/job_send.cpp @@ -16,14 +16,22 @@ static void job_mining_notify_buffer(YAAMP_JOB *job, char *buffer) { YAAMP_JOB_TEMPLATE *templ = job->templ; - if (!strcmp(g_current_algo->name, "lbry")) { + if (!strcmp(g_stratum_algo, "lbry")) { sprintf(buffer, "{\"id\":null,\"method\":\"mining.notify\",\"params\":[" "\"%x\",\"%s\",\"%s\",\"%s\",\"%s\",[%s],\"%s\",\"%s\",\"%s\",true]}\n", job->id, templ->prevhash_be, templ->claim_be, templ->coinb1, templ->coinb2, templ->txmerkles, templ->version, templ->nbits, templ->ntime); return; + } else if (strlen(templ->extradata_hex) == 128) { + // LUX smart contract state hashes (like lbry extra field, here the 2 root hashes in one) + sprintf(buffer, "{\"id\":null,\"method\":\"mining.notify\",\"params\":[" + "\"%x\",\"%s\",\"%s\",\"%s\",\"%s\",[%s],\"%s\",\"%s\",\"%s\",true]}\n", + job->id, templ->prevhash_be, templ->extradata_be, templ->coinb1, templ->coinb2, + templ->txmerkles, templ->version, templ->nbits, templ->ntime); + return; } + // standard stratum sprintf(buffer, "{\"id\":null,\"method\":\"mining.notify\",\"params\":[\"%x\",\"%s\",\"%s\",\"%s\",[%s],\"%s\",\"%s\",\"%s\",true]}\n", job->id, templ->prevhash_be, templ->coinb1, templ->coinb2, templ->txmerkles, templ->version, templ->nbits, templ->ntime); } diff --git a/stratum/remote_template.cpp b/stratum/remote_template.cpp index 84fadc5e7..6235b705a 100644 --- a/stratum/remote_template.cpp +++ b/stratum/remote_template.cpp @@ -62,7 +62,7 @@ void remote_create_job(YAAMP_REMOTE *remote, json_value *json_params) YAAMP_JOB_TEMPLATE *templ = new YAAMP_JOB_TEMPLATE; memset(templ, 0, sizeof(YAAMP_JOB_TEMPLATE)); - strncpy(templ->prevhash_be, json_params->u.array.values[1]->u.string.ptr, 1023); + strncpy(templ->prevhash_be, json_params->u.array.values[1]->u.string.ptr, sizeof(templ->prevhash_be)-1); strncpy(templ->coinb1, json_params->u.array.values[2]->u.string.ptr, 1023); strncpy(templ->coinb2, json_params->u.array.values[3]->u.string.ptr, 1023); diff --git a/stratum/share.cpp b/stratum/share.cpp index a8a4f8226..14c4332a7 100644 --- a/stratum/share.cpp +++ b/stratum/share.cpp @@ -261,8 +261,10 @@ bool block_confirm(int coinid, const char *blockhash) } const char *h1 = json_get_string(json_res, "pow_hash"); // DGB, MYR, J const char *h2 = json_get_string(json_res, "mined_hash"); // XVG + const char *h3 = json_get_string(json_res, "phash"); // XSH if (h1) snprintf(hash, 161, "%s", h1); else if (h2) snprintf(hash, 161, "%s", h2); + else if (h3) snprintf(hash, 161, "%s", h3); //debuglog("%s: getblock %s -> pow %s\n", __func__, blockhash, hash); json_value_free(json); break; diff --git a/stratum/stratum.cpp b/stratum/stratum.cpp index 382a16515..a6827d4cd 100644 --- a/stratum/stratum.cpp +++ b/stratum/stratum.cpp @@ -115,6 +115,7 @@ YAAMP_ALGO g_algos[] = {"c11", c11_hash, 1, 0, 0}, {"x11", x11_hash, 1, 0, 0}, + {"x12", x12_hash, 1, 0, 0}, {"x13", x13_hash, 1, 0, 0}, {"x14", x14_hash, 1, 0, 0}, {"x15", x15_hash, 1, 0, 0}, @@ -124,6 +125,7 @@ YAAMP_ALGO g_algos[] = {"xevan", xevan_hash, 0x100, 0, 0}, {"x16r", x16r_hash, 0x100, 0, 0}, + {"x16s", x16s_hash, 0x100, 0, 0}, {"timetravel", timetravel_hash, 0x100, 0, 0}, {"bitcore", timetravel10_hash, 0x100, 0, 0}, {"hsr", hsr_hash, 1, 0, 0}, @@ -131,6 +133,7 @@ YAAMP_ALGO g_algos[] = {"jha", jha_hash, 0x10000, 0}, + {"allium", allium_hash, 0x100, 0, 0}, {"lyra2", lyra2re_hash, 0x80, 0, 0}, {"lyra2v2", lyra2v2_hash, 0x100, 0, 0}, {"lyra2z", lyra2z_hash, 0x100, 0, 0}, @@ -151,10 +154,15 @@ YAAMP_ALGO g_algos[] = {"dmd-gr", groestl_hash, 0x100, 0, 0}, /* diamond (double groestl) */ {"myr-gr", groestlmyriad_hash, 1, 0, 0}, /* groestl + sha 64 */ {"skein", skein_hash, 1, 0, 0}, + {"sonoa", sonoa_hash, 1, 0, 0}, {"tribus", tribus_hash, 1, 0, 0}, {"keccak", keccak256_hash, 0x80, 0, sha256_hash_hex }, {"keccakc", keccak256_hash, 0x100, 0, 0}, + {"hex", hex_hash, 0x100, 0, sha256_hash_hex }, + {"phi", phi_hash, 1, 0, 0}, + {"phi2", phi2_hash, 0x100, 0, 0}, + {"polytimos", polytimos_hash, 1, 0, 0}, {"skunk", skunk_hash, 1, 0, 0}, @@ -165,6 +173,7 @@ YAAMP_ALGO g_algos[] = {"skein2", skein2_hash, 1, 0, 0}, {"yescrypt", yescrypt_hash, 0x10000, 0, 0}, {"yescryptR16", yescryptR16_hash, 0x10000, 0, 0 }, + {"yescryptR32", yescryptR32_hash, 0x10000, 0, 0 }, {"zr5", zr5_hash, 1, 0, 0}, {"a5a", a5a_hash, 0x10000, 0, 0}, @@ -173,6 +182,8 @@ YAAMP_ALGO g_algos[] = {"veltor", veltor_hash, 1, 0, 0}, {"velvet", velvet_hash, 0x10000, 0, 0}, {"argon2", argon2_hash, 0x10000, 0, sha256_hash_hex }, + {"vitalium", vitalium_hash, 1, 0, 0}, + {"aergo", aergo_hash, 1, 0, 0}, {"sha256t", sha256t_hash, 1, 0, 0}, // sha256 3x diff --git a/stratum/stratum.h b/stratum/stratum.h index cb9f9dd34..e3e716556 100644 --- a/stratum/stratum.h +++ b/stratum/stratum.h @@ -150,10 +150,12 @@ void sha256_double_hash_hex(const char *input, char *output, unsigned int len); #include "algos/c11.h" #include "algos/x11.h" #include "algos/x11evo.h" +#include "algos/x12.h" #include "algos/x13.h" #include "algos/x14.h" #include "algos/x15.h" #include "algos/x16r.h" +#include "algos/x16s.h" #include "algos/x17.h" #include "algos/xevan.h" #include "algos/hmq17.h" @@ -162,12 +164,13 @@ void sha256_double_hash_hex(const char *input, char *output, unsigned int len); #include "algos/hsr14.h" #include "algos/quark.h" #include "algos/neoscrypt.h" +#include "algos/allium.h" #include "algos/lyra2re.h" #include "algos/lyra2v2.h" #include "algos/lyra2z.h" #include "algos/blake.h" #include "algos/blakecoin.h" -#include "algos/blake2.h" +#include "algos/blake2s.h" #include "algos/qubit.h" #include "algos/groestl.h" #include "algos/jha.h" @@ -193,9 +196,14 @@ void sha256_double_hash_hex(const char *input, char *output, unsigned int len); #include "algos/sib.h" #include "algos/m7m.h" #include "algos/phi.h" +#include "algos/phi2.h" #include "algos/polytimos.h" +#include "algos/sonoa.h" #include "algos/tribus.h" #include "algos/veltor.h" #include "algos/velvet.h" #include "algos/argon2a.h" +#include "algos/vitalium.h" +#include "algos/aergo.h" +#include "algos/hex.h" diff --git a/stratum/user.cpp b/stratum/user.cpp index 29bf045f5..1e2ec6ce0 100644 --- a/stratum/user.cpp +++ b/stratum/user.cpp @@ -108,8 +108,8 @@ void db_add_user(YAAMP_DB *db, YAAMP_CLIENT *client) else if(client->userid == 0 && strlen(client->username) >= MIN_ADDRESS_LEN) { - db_query(db, "INSERT INTO accounts (username, coinsymbol, balance, donation) values ('%s', '%s', 0, %d)", - client->username, symbol, gift); + db_query(db, "INSERT INTO accounts (username, coinsymbol, balance, donation, hostaddr) values ('%s', '%s', 0, %d, '%s')", + client->username, symbol, gift, client->sock->ip); client->userid = (int)mysql_insert_id(&db->mysql); } diff --git a/stratum/util.h b/stratum/util.h index 7afdd1bed..bf57bfd27 100644 --- a/stratum/util.h +++ b/stratum/util.h @@ -74,6 +74,7 @@ string merkle_with_first(vector steps, string f); ////////////////////////////////////////////////////////////////////////// bool base58_decode(const char *input, char *output); +bool is_base58(char *input); void base64_encode(char *base64, const char *normal); void base64_decode(char *normal, const char *base64); diff --git a/web/ln.sh b/web/ln.sh new file mode 100644 index 000000000..124c5c83f --- /dev/null +++ b/web/ln.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +PHP_CLI='php -d max_execution_time=60' + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd ${DIR} + +date +echo started in ${DIR} + +while true; do + ${PHP_CLI} runconsole.php cronjob/runLightning + sleep 20 +done +exec bash diff --git a/web/serverconfig.sample.php b/web/serverconfig.sample.php index 59b4a7f99..0a8d2e068 100644 --- a/web/serverconfig.sample.php +++ b/web/serverconfig.sample.php @@ -36,7 +36,8 @@ define('YAAMP_ADMIN_EMAIL', 'yiimp@spam.la'); define('YAAMP_ADMIN_IP', ''); // samples: "80.236.118.26,90.234.221.11" or "10.0.0.1/8" define('YAAMP_ADMIN_WEBCONSOLE', true); -define('YAAMP_NOTIFY_NEW_COINS', true); +define('YAAMP_CREATE_NEW_COINS', true); +define('YAAMP_NOTIFY_NEW_COINS', false); define('YAAMP_DEFAULT_ALGO', 'x11'); define('YAAMP_USE_NGINX', false); diff --git a/web/yaamp/commands/CheckupCommand.php b/web/yaamp/commands/CheckupCommand.php index b4da2ba01..87f72b4a8 100644 --- a/web/yaamp/commands/CheckupCommand.php +++ b/web/yaamp/commands/CheckupCommand.php @@ -186,8 +186,15 @@ public function autolinkCoinsImages() $nbUpdated = 0; $nbDropped = 0; foreach ($coins->findAll() as $coin) { if (!empty($coin->image)) { - if (file_exists($this->basePath.$coin->image)) + if (file_exists($this->basePath.$coin->image)) { + $data = file_get_contents($this->basePath.$coin->image); + if (strstr($data, "basePath.$coin->image); + $coin->image = NULL; + $nbDropped += $coin->save(); + } continue; + } if (file_exists($this->basePath."/images/coin-$coin->symbol.png")) { $coin->image = "/images/coin-$coin->symbol.png"; $nbUpdated += $coin->save(); diff --git a/web/yaamp/commands/CoindbCommand.php b/web/yaamp/commands/CoindbCommand.php index 7d6913b01..920fbf3fa 100644 --- a/web/yaamp/commands/CoindbCommand.php +++ b/web/yaamp/commands/CoindbCommand.php @@ -441,7 +441,7 @@ public function grabCryptopiaIcons() } catch (Exception $e) { continue; } - if (strlen($data) < 2048) continue; + if (strlen($data) < 3000 || strstr($data, ' 0) { diff --git a/web/yaamp/commands/PayoutCommand.php b/web/yaamp/commands/PayoutCommand.php index 128e2ef6d..759b248ba 100644 --- a/web/yaamp/commands/PayoutCommand.php +++ b/web/yaamp/commands/PayoutCommand.php @@ -35,6 +35,10 @@ public function run($args) echo "Yiimp payout command\n"; echo "Usage: yiimp payout check [fixit]\n"; echo "Usage: payout coinswaps\n"; + echo "Usage: payout confirmations \n"; + if (YIIMP_CLI_ALLOW_TXS) + echo "Usage: payout redotx \n"; + return 1; } elseif ($command == 'check') { @@ -52,6 +56,14 @@ public function run($args) } elseif ($command == 'coinswaps') { $this->checkCoinSwaps($args); return 0; + + } elseif ($command == 'confirmations') { + $this->checkPayoutsConfirmations($args); + return 0; + + } elseif ($command == 'redotx' && YIIMP_CLI_ALLOW_TXS) { + $this->redoTransaction($args); + return 0; } } @@ -263,4 +275,93 @@ function checkCoinSwaps($args) echo "earnings: all fine\n"; } } + + /** + * Can be used to redo a payment made on a bad fork... + */ + protected function redoTransaction($args) + { + $txid = arraySafeVal($args, 1); + if (empty($txid)) + die("Usage..\n"); + + $payouts = getdbolist('db_payouts', "tx=:txid", array(':txid'=>$txid)); + if (empty($payouts)) + die("Invalid payout txid\n"); + echo "users to pay: ".count($payouts)."\n"; + + $payout = $payouts[0]; + $coin = getdbo('db_coins', $payout->idcoin); + if (!$coin || !$coin->installed) + die("Invalid payout coin id\n"); + + $relayfee = 0.0001; + + $dests = array(); $total = 0.; + foreach ($payouts as $payout) { + $user = getdbo('db_accounts', $payout->account_id); + if (!$user || $user->coinid != $coin->id) continue; + if (doubleval($payout->amount) < $relayfee) continue; // dust if < relayfee + $dests[$user->username] = doubleval($payout->amount); + $total += doubleval($payout->amount); + } + + echo "$total {$coin->symbol} to pay...\n"; + + $nbnew = 0; + $remote = new WalletRPC($coin); + $res = $remote->sendmany((string) $coin->account, $dests); + if (!$res) var_dump($remote->error); + else { + $new_txid = $res; + echo "txid: $new_txid\n"; + foreach ($payouts as $payout) { + if (doubleval($payout->amount) < $relayfee) continue; + $p = new db_payouts; + $p->time = time(); + $p->idcoin = $coin->id; + $p->amount = doubleval($payout->amount); + $p->account_id = $payout->account_id; + $p->completed = 1; + $p->fee = 0; + $p->tx = $new_txid; + $nbnew += $p->insert(); + } + echo "payouts rows added: $nbnew\n"; + if ($nbnew == count($payouts)) { + $res = dborun("UPDATE payouts SET completed=0, tx='orphaned', memoid='redo' WHERE tx=:txid", array(':txid'=>$txid)); + echo "payouts marked as 'orphaned': $res\n"; + } + } + return $nbnew; + } + + /** + * List the last payouts made for a wallet and check if the tx have confirmations + */ + protected function checkPayoutsConfirmations($args) + { + $symbol = arraySafeVal($args, 1); + if (empty($symbol)) + die("payout confirmations \n"); + + $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); + if (!$coin) { + echo "wallet $symbol not found!\n"; + return 0; + } + $since = time() - (72 * 3600); + $data = dbolist("SELECT P.tx, MAX(P.time) as time, SUM(P.amount) as amount FROM payouts P ". + "WHERE P.time>$since AND P.idcoin=".$coin->id." ". + "GROUP BY P.tx ORDER BY time DESC" + ); + + $remote = new WalletRPC($coin); + foreach ($data as $row) { + $txid = $row['tx']; + $tx = $remote->gettransaction($txid); + echo strftime('%Y-%m-%d %H:%M', $row['time'])." $txid ".$tx['confirmations']. + " confs (".altcoinvaluetoa($row['amount'],4)." $symbol, fees: ".bitcoinvaluetoa($tx['fee']).")\n"; + } + } } diff --git a/web/yaamp/core/backend/backend.php b/web/yaamp/core/backend/backend.php index 4f0c1773a..b2940d348 100644 --- a/web/yaamp/core/backend/backend.php +++ b/web/yaamp/core/backend/backend.php @@ -1,5 +1,6 @@ attributes); + if (strpos($rawdata,"script")) { + debuglog("bench record deleted : $rawdata"); + $bench->delete(); + continue; + } + $dups = getdbocount('db_benchmarks', "vendorid=:vid AND client=:client AND os=:os AND driver=:drv AND throughput=:thr AND userid=:uid", array(':vid'=>$bench->vendorid, ':client'=>$bench->client, ':os'=>$bench->os, ':drv'=>$bench->driver,':thr'=>$bench->throughput,':uid'=>$bench->userid) ); diff --git a/web/yaamp/core/backend/blocks.php b/web/yaamp/core/backend/blocks.php index 7625e1add..ca5c0bcf5 100644 --- a/web/yaamp/core/backend/blocks.php +++ b/web/yaamp/core/backend/blocks.php @@ -61,6 +61,12 @@ function BackendBlockNew($coin, $db_block) $user->save(); } + $target = yaamp_hashrate_constant($coin->algo); + $interval = yaamp_hashrate_step(); + $delay = time()-$interval; + + dborun("UPDATE workers w SET work = w.work + (SELECT (sum(difficulty) * $target / $interval / 1000) FROM shares WHERE valid AND time>".time()-$interval." AND workerid=w.id)"); + $delay = time() - 5*60; $sqlCond = "time < $delay"; if(!YAAMP_ALLOW_EXCHANGE) // only one coin mined @@ -98,6 +104,16 @@ function BackendBlockFind1($coinid = NULL) } if(!$coin->enable) continue; if($coin->rpcencoding == 'DCR' && !$coin->auto_ready) continue; + + $dblock = getdbosql('db_blocks', "coin_id=:coinid AND blockhash=:hash AND height=:height AND id!=:blockid", + array(':coinid'=>$coin->id, ':hash'=>$db_block->blockhash, ':height'=>$db_block->height, ':blockid'=>$db_block->id) + ); + + if($dblock) { + debuglog("warning: Doubled {$coin->symbol} block found for block height {$db_block->height}!"); + $db_block->delete(); + continue; + } $db_block->category = 'orphan'; $remote = new WalletRPC($coin); @@ -271,6 +287,7 @@ function BackendBlocksUpdate($coinid = NULL) // auto update mature_blocks if ($block->confirmations > 0 && $block->confirmations < $coin->mature_blocks || empty($coin->mature_blocks)) { + $coin = getdbo('db_coins', $block->coin_id); // refresh coin data debuglog("{$coin->symbol} mature_blocks updated to {$block->confirmations}"); $coin->mature_blocks = $block->confirmations; $coin->save(); @@ -285,7 +302,7 @@ function BackendBlocksUpdate($coinid = NULL) } //////////////////////////////////////////////////////////////////////////////////////////// -// Search new block transactions +// Search new block transactions (main thread) function BackendBlockFind2($coinid = NULL) { @@ -299,23 +316,20 @@ function BackendBlockFind2($coinid = NULL) if($coin->symbol == 'BTC') continue; $remote = new WalletRPC($coin); + $timerpc = microtime(true); $mostrecent = 0; if(empty($coin->lastblock)) $coin->lastblock = ''; $list = $remote->listsinceblock($coin->lastblock); + $rpcdelay = microtime(true) - $timerpc; + if ($rpcdelay > 0.5) + screenlog(__FUNCTION__.": {$coin->symbol} listsinceblock took ".round($rpcdelay,3)." sec, ". + (is_array($list) ? count($list) : 0). "txs"); if(!$list) continue; -// debuglog("find2 $coin->symbol"); foreach($list['transactions'] as $transaction) { if(!isset($transaction['blockhash'])) continue; if($transaction['time'] > time() - 5*60) continue; - - if($transaction['time'] > $mostrecent) - { - $coin->lastblock = $transaction['blockhash']; - $mostrecent = $transaction['time']; - } - if($transaction['time'] < time() - 60*60) continue; if($transaction['category'] != 'generate' && $transaction['category'] != 'immature') continue; @@ -330,6 +344,13 @@ function BackendBlockFind2($coinid = NULL) if ($coin->rpcencoding == 'DCR') debuglog("{$coin->name} generated block {$blockext['height']} detected!"); + if($transaction['time'] > $mostrecent) { + $coin = getdbo('db_coins', $coin->id); // refresh coin data + $coin->lastblock = $transaction['blockhash']; + $coin->save(); + $mostrecent = $transaction['time']; + } + $db_block = new db_blocks; $db_block->blockhash = $transaction['blockhash']; $db_block->coin_id = $coin->id; @@ -357,6 +378,7 @@ function BackendBlockFind2($coinid = NULL) } if (!$coin->hasmasternodes) { + $coin = getdbo('db_coins', $coin->id); // refresh coin data $coin->hasmasternodes = true; $coin->save(); } @@ -370,14 +392,12 @@ function BackendBlockFind2($coinid = NULL) debuglog(__FUNCTION__.": unable to insert block!"); BackendBlockNew($coin, $db_block); - } - - $coin->save(); + } // tx } $d1 = microtime(true) - $t1; controller()->memcache->add_monitoring_function(__FUNCTION__, $d1); - //debuglog(__FUNCTION__." took ".round($d1,3)." sec"); + if ($d1 > 3.0) screenlog(__FUNCTION__.": took ".round($d1,3)." sec"); } //////////////////////////////////////////////////////////////////////////////////////////// diff --git a/web/yaamp/core/backend/coins.php b/web/yaamp/core/backend/coins.php index 51c0e80e8..11126716c 100644 --- a/web/yaamp/core/backend/coins.php +++ b/web/yaamp/core/backend/coins.php @@ -140,12 +140,13 @@ function BackendCoinsUpdate() $coin->charity_amount = $template['_V2']/100000000; if(isset($template['payee_amount']) && $coin->symbol != 'LIMX') { - $coin->charity_amount = $template['payee_amount']/100000000; + $coin->charity_amount = doubleval($template['payee_amount'])/100000000; $coin->reward -= $coin->charity_amount; } else if(isset($template['masternode']) && arraySafeVal($template,'masternode_payments_enforced')) { - $coin->reward -= arraySafeVal($template['masternode'],'amount',0)/100000000; + if (arraySafeVal($template,'masternode_payments_started')) + $coin->reward -= arraySafeVal($template['masternode'],'amount',0)/100000000; $coin->hasmasternodes = true; } diff --git a/web/yaamp/core/backend/functions.php b/web/yaamp/core/backend/functions.php new file mode 100644 index 000000000..0c680c7fd --- /dev/null +++ b/web/yaamp/core/backend/functions.php @@ -0,0 +1,12 @@ + $ticker) + { + $pairs = explode('_', $c); + $symbol = strtoupper(reset($pairs)); $base = end($pairs); + if($symbol == 'BTC' || $base != 'btc') continue; + + if (market_get($exchange, $symbol, "disabled")) { + $market->disabled = 1; + $market->message = 'disabled from settings'; + } + $coin = getdbosql('db_coins', "symbol='{$symbol}'"); + if(!$coin) continue; + if(!$coin->installed && !$coin->watch) continue; + $market = getdbosql('db_markets', "coinid={$coin->id} and name='{$exchange}'"); + + if(!$market) continue; + $price2 = ($ticker->bidPrice + $ticker->askPrice)/2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, $ticker->bidPrice); + $market->pricetime = time(); + $market->priority = -1; + $market->txfee = 0.2; // trade pct + $market->save(); + // debuglog("$exchange: update $symbol: {$market->price} {$market->price2}"); + } +} + ///////////////////////////////////////////////////////////////////////////////////////////// function updateCryptoBridgeMarkets($force = false) { $exchange = 'cryptobridge'; + if (exchange_get($exchange, 'disabled')) return; + + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; $result = cryptobridge_api_query('ticker'); if(!is_array($result)) return; @@ -324,11 +371,107 @@ function updateCryptoBridgeMarkets($force = false) ///////////////////////////////////////////////////////////////////////////////////////////// +function updateGateioMarkets($force = false) +{ + $exchange = 'gateio'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $markets = gateio_api_query('tickers'); + if(!is_array($markets)) return; + + foreach($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if(!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $dbpair = strtolower($symbol).'_btc'; + foreach ($markets as $pair => $ticker) { + if ($pair != $dbpair) continue; + $price2 = (doubleval($ticker['highestBid']) + doubleval($ticker['lowestAsk'])) / 2; + $market->price = AverageIncrement($market->price, doubleval($ticker['highestBid'])); + $market->price2 = AverageIncrement($market->price2, $price2); + $market->pricetime = time(); + $market->priority = -1; + $market->txfee = 0.2; // trade pct + $market->save(); + + if (empty($coin->price2)) { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->market = $exchange; + $coin->save(); + } + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////////// + +function updateGraviexMarkets($force = false) +{ + $exchange = 'graviex'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $markets = graviex_api_query('tickers'); + if(!is_array($markets)) return; + + foreach($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if(!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $symbol = strtolower($symbol); + $dbpair = $symbol.'btc'; + foreach ($markets as $pair => $ticker) { + if ($pair != $dbpair) continue; + $price2 = ($ticker['ticker']['buy']+$ticker['ticker']['sell'])/2; + $market->price = AverageIncrement($market->price, $ticker['ticker']['buy']); + $market->price2 = AverageIncrement($market->price2, $price2); + $market->pricetime = time(); + $market->save(); + + if (empty($coin->price2)) { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->market = $exchange; + $coin->save(); + } + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////////// + function updateKrakenMarkets($force = false) { $exchange = 'kraken'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $result = kraken_api_query('AssetPairs'); if(!is_array($result)) return; @@ -393,6 +536,9 @@ function updateBittrexMarkets($force = false) $exchange = 'bittrex'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $list = bittrex_api_query('public/getcurrencies'); if(!is_object($list)) return; foreach($list->result as $currency) @@ -473,6 +619,9 @@ function updateCCexMarkets() $exchange = 'c-cex'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $ccex = new CcexAPI; $list = $ccex->getMarketSummaries(); if (!is_array($list)) return; @@ -560,6 +709,9 @@ function updatePoloniexMarkets() $exchange = 'poloniex'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $poloniex = new poloniex; $tickers = $poloniex->get_ticker(); @@ -645,6 +797,9 @@ function updateYobitMarkets() $exchange = 'yobit'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $res = yobit_api_query('info'); if(!is_object($res)) return; @@ -730,10 +885,12 @@ function updateJubiMarkets() $exchange = 'jubi'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $btc = jubi_api_query('ticker', "?coin=btc"); if(!is_object($btc)) return; - $list = getdbolist('db_markets', "name='jubi'"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); @@ -775,10 +932,12 @@ function updateAlcurexMarkets() $exchange = 'alcurex'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $data = alcurex_api_query('market', "?info=on"); if(!is_object($data)) return; - $list = getdbolist('db_markets', "name='$exchange'"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); @@ -827,10 +986,12 @@ function updateCryptopiaMarkets() $exchange = 'cryptopia'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $data = cryptopia_api_query('GetMarkets', 24); if(!is_object($data)) return; - $list = getdbolist('db_markets', "name LIKE('$exchange%')"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); @@ -1087,10 +1248,12 @@ function updateBinanceMarkets() $exchange = 'binance'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $tickers = binance_api_query('ticker/allBookTickers'); if(!is_array($tickers)) return; - $list = getdbolist('db_markets', "name='$exchange'"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); @@ -1129,10 +1292,12 @@ function updateBterMarkets() $exchange = 'bter'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $markets = bter_api_query('tickers'); if(!is_array($markets)) return; - $list = getdbolist('db_markets', "name='$exchange'"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); @@ -1165,15 +1330,61 @@ function updateBterMarkets() } } +function updateCryptohubMarkets() +{ + $exchange = 'cryptohub'; + if (exchange_get($exchange, 'disabled')) return; + + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + + $markets = cryptohub_api_query('market/ticker'); + if(!is_array($markets)) return; + + foreach($list as $market) + { + $coin = getdbo('db_coins', $market->coinid); + if(!$coin) continue; + + $symbol = $coin->getOfficialSymbol(); + if (market_get($exchange, $symbol, "disabled")) { + $market->disabled = 1; + $market->message = 'disabled from settings'; + $market->save(); + continue; + } + + $dbpair = 'BTC'.'_'.$symbol; + foreach ($markets as $pair => $ticker) { + if ($pair != $dbpair) continue; + $price2 = ($ticker['highestBid']+$ticker['lowestAsk'])/2; + $market->price = AverageIncrement($market->price, $ticker['highestBid']); + $market->price2 = AverageIncrement($market->price2, $price2); + $market->pricetime = time(); + //if ($market->disabled < 9) $market->disabled = (floatval($ticker['baseVolume']) < 0.01); + $market->save(); + + if (empty($coin->price2)) { + $coin->price = $market->price; + $coin->price2 = $market->price2; + $coin->market = $exchange; + $coin->save(); + } + } + } +} + function updateEmpoexMarkets() { $exchange = 'empoex'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $markets = empoex_api_query('marketinfo'); if(!is_array($markets)) return; - $list = getdbolist('db_markets', "name='$exchange'"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); @@ -1214,6 +1425,9 @@ function updateKuCoinMarkets() $exchange = 'kucoin'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $markets = kucoin_api_query('open/symbols','market=BTC'); if(!kucoin_result_valid($markets) || empty($markets->data)) return; @@ -1222,7 +1436,6 @@ function updateKuCoinMarkets() $coininfo = NULL; } - $list = getdbolist('db_markets', "name='$exchange'"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); @@ -1271,10 +1484,12 @@ function updateLiveCoinMarkets() $exchange = 'livecoin'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $markets = livecoin_api_query('exchange/ticker'); if(!is_array($markets)) return; - $list = getdbolist('db_markets', "name='$exchange'"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); @@ -1340,6 +1555,9 @@ function updateCoinExchangeMarkets() $exchange = 'coinexchange'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $list = coinexchange_api_query('getmarkets'); if(!is_object($list)) return; $markets = coinexchange_api_query('getmarketsummaries'); @@ -1411,6 +1629,9 @@ function updateCoinsMarketsMarkets() $exchange = 'coinsmarkets'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $list = coinsmarkets_api_query('apicoin'); if(empty($list) || !is_array($list)) return; foreach($list as $pair=>$data) @@ -1468,6 +1689,9 @@ function updateStocksExchangeMarkets() $exchange = 'stocksexchange'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $list = stocksexchange_api_query('ticker'); if(empty($list) || !is_array($list)) return; foreach($list as $m) @@ -1515,6 +1739,9 @@ function updateTradeSatoshiMarkets() $exchange = 'tradesatoshi'; if (exchange_get($exchange, 'disabled')) return; + $count = (int) dboscalar("SELECT count(id) FROM markets WHERE name LIKE '$exchange%'"); + if ($count == 0) return; + $data = tradesatoshi_api_query('getmarketsummaries'); if(!is_object($data) || !$data->success || !is_array($data->result)) return; foreach($data->result as $m) @@ -1562,10 +1789,12 @@ function updateShapeShiftMarkets() $exchange = 'shapeshift'; if (exchange_get($exchange, 'disabled')) return; + $list = getdbolist('db_markets', "name LIKE '$exchange%'"); + if (empty($list)) return; + $markets = shapeshift_api_query('marketinfo'); if(!is_array($markets) || empty($markets)) return; - $list = getdbolist('db_markets', "name='$exchange'"); foreach($list as $market) { $coin = getdbo('db_coins', $market->coinid); diff --git a/web/yaamp/core/backend/payment.php b/web/yaamp/core/backend/payment.php index 7a5eaa5cb..3f2915857 100644 --- a/web/yaamp/core/backend/payment.php +++ b/web/yaamp/core/backend/payment.php @@ -32,6 +32,14 @@ function BackendUserCancelFailedPayment($userid) return 0.0; } +function is_ln_invoice($bill) +{ +if (!empty($bill) && preg_match('/[^A-Za-z0-9]/', $bill)) + return false; +else + return true; // TODO: Enhance the check of the bolt11 invoice (length, first characters, ...) +} + function BackendCoinPayments($coin) { // debuglog("BackendCoinPayments $coin->symbol"); @@ -106,6 +114,34 @@ function BackendCoinPayments($coin) { $total_to_pay += round($user->balance, 8); $addresses[$user->username] = round($user->balance, 8); + if ($coin->symbol==LN_COIN && LN_ENABLED == true && YAAMP_LN_WORKERS == true) { + $ln_works = getdbolist('db_workers', "work > 0 AND worker <> '' AND userid=".$user->id); + foreach($ln_works as $ln_work) { + if (is_ln_invoice($ln_work->worker)) { + $output = shell_exec('sudo lightning-cli -J decodepay '.$ln_work->worker); + $bill = json_decode($output); + // TODO: Enhance and add pool fee + if ($ln_work->work * YAAMP_LN_FACTOR > $bill->msatoshi / 1000 && $user->balance > $bill->msatoshi / 1000) { + $db_bill = getdbosql('db_invoices', "bolt11=:bolt11", array(':bolt11'=>$ln_work->worker)); + if (!$db_bill) { + dborun("INSERT IGNORE INTO invoices(bolt11, status) VALUES (:key,:val)", array( + ':key'=>$bill,':val'=>"New" + )); + } + if ($db_bill && $db_bill->status == "complete") { + // Invoice is already paid, no need to change total_to_pay and addresses + } + else { + // Invoice is not paid yet: some value should be kept to pay it + // TODO: Add pool fee + $total_to_pay -= round($bill->msatoshi / 1000, 8); + $addresses[$user->username] -= round($bill->msatoshi / 1000, 8); + } + } + } + } + } + // transaction xxx has too many sigops: 1035 > 1000 if ($coin->symbol == 'DCR' && count($addresses) > 990) { debuglog("payment: more than 990 {$coin->symbol} users to pay, limit to top balances..."); @@ -171,17 +207,19 @@ function BackendCoinPayments($coin) if(!$user) continue; if(!isset($addresses[$user->username])) continue; + $payment_amount = bitcoinvaluetoa($addresses[$user->username]); + $payout = new db_payouts; $payout->account_id = $user->id; $payout->time = time(); - $payout->amount = bitcoinvaluetoa($user->balance*$coef); + $payout->amount = $payment_amount; $payout->fee = 0; $payout->idcoin = $coin->id; if ($payout->save()) { $payouts[$payout->id] = $user->id; - $user->balance = bitcoinvaluetoa(floatval($user->balance) - (floatval($user->balance)*$coef)); + $user->balance = bitcoinvaluetoa(floatval($user->balance) - $payment_amount); $user->save(); } } diff --git a/web/yaamp/core/backend/rawcoins.php b/web/yaamp/core/backend/rawcoins.php index 067d0defc..70de461f0 100644 --- a/web/yaamp/core/backend/rawcoins.php +++ b/web/yaamp/core/backend/rawcoins.php @@ -13,6 +13,7 @@ function updateRawcoins() exchange_set_default('empoex', 'disabled', true); exchange_set_default('coinexchange', 'disabled', true); exchange_set_default('coinsmarkets', 'disabled', true); + exchange_set_default('gateio', 'disabled', true); exchange_set_default('jubi', 'disabled', true); exchange_set_default('nova', 'disabled', true); exchange_set_default('stocksexchange', 'disabled', true); @@ -22,21 +23,44 @@ function updateRawcoins() if (!exchange_get('bittrex', 'disabled')) { $list = bittrex_api_query('public/getcurrencies'); - if(isset($list->result)) + if(isset($list->result) && !empty($list->result)) { dborun("UPDATE markets SET deleted=true WHERE name='bittrex'"); - foreach($list->result as $currency) + foreach($list->result as $currency) { + if ($currency->Currency == 'BTC') { + exchange_set('bittrex', 'withdraw_fee_btc', $currency->TxFee); + continue; + } updateRawCoin('bittrex', $currency->Currency, $currency->CurrencyLong); + } } } + if (!exchange_get('bitz', 'disabled')) { + $list = bitz_api_query('tickerall'); + + dborun("UPDATE markets SET deleted=true WHERE name='bitz'"); + foreach($list as $c => $ticker) { + $e = explode('_', $c); + if (strtoupper($e[1]) !== 'BTC') + continue; + $symbol = strtoupper($e[0]); + updateRawCoin('bitz', $symbol); + } + } + if (!exchange_get('bleutrade', 'disabled')) { $list = bleutrade_api_query('public/getcurrencies'); - if(isset($list->result)) + if(isset($list->result) && !empty($list->result)) { dborun("UPDATE markets SET deleted=true WHERE name='bleutrade'"); - foreach($list->result as $currency) + foreach($list->result as $currency) { + if ($currency->Currency == 'BTC') { + exchange_set('bleutrade', 'withdraw_fee_btc', $currency->TxFee); + continue; + } updateRawCoin('bleutrade', $currency->Currency, $currency->CurrencyLong); + } } } @@ -226,6 +250,22 @@ function updateRawcoins() } } + if (!exchange_get('gateio', 'disabled')) { + $json = gateio_api_query('marketlist'); + $list = arraySafeVal($json,'data'); + if(!empty($list)) + { + dborun("UPDATE markets SET deleted=true WHERE name='gateio'"); + foreach($list as $item) { + if ($item['curr_b'] != 'BTC') + continue; + $symbol = trim(strtoupper($item['symbol'])); + $name = trim($item['name']); + updateRawCoin('gateio', $symbol, $name); + } + } + } + if (!exchange_get('nova', 'disabled')) { $list = nova_api_query('markets'); if(is_object($list) && !empty($list->markets)) @@ -372,7 +412,7 @@ function updateRawCoin($marketname, $symbol, $name='unknown') if($symbol == 'BTC') return; $coin = getdbosql('db_coins', "symbol=:symbol", array(':symbol'=>$symbol)); - if(!$coin && $marketname != 'yobit') + if(!$coin && YAAMP_CREATE_NEW_COINS) { $algo = ''; if ($marketname == 'cryptopia') { @@ -390,11 +430,15 @@ function updateRawCoin($marketname, $symbol, $name='unknown') } } - if (in_array($marketname, array('nova','askcoin','binance','coinexchange','coinsmarkets','cryptobridge','hitbtc'))) { + if (in_array($marketname, array('nova','askcoin','binance','bitz','coinexchange','coinsmarkets','cryptobridge','hitbtc'))) { // don't polute too much the db with new coins, its better from exchanges with labels return; } + // some other to ignore... + if (in_array($marketname, array('yobit','kucoin','tradesatoshi'))) + return; + if (market_get($marketname, $symbol, "disabled")) { return; } diff --git a/web/yaamp/core/backend/sell.php b/web/yaamp/core/backend/sell.php index 5b25a2ce6..7fba09b3c 100644 --- a/web/yaamp/core/backend/sell.php +++ b/web/yaamp/core/backend/sell.php @@ -38,7 +38,7 @@ function sellCoinToExchange($coin) $market = getBestMarket($coin); if(!$market) return; - if(!$coin->sellonbid && $market->lastsent != null && $market->lastsent > $market->lasttraded) + if($market->lastsent != null && $market->lastsent > $market->lasttraded) { // debuglog("*** not sending $coin->name to $market->name. last tx is late ***"); return; @@ -77,9 +77,6 @@ function sellCoinToExchange($coin) $amount = round($amount, 8); // debuglog("sending $amount $coin->symbol to $marketname, $deposit_address"); - $market->lastsent = time(); - $market->save(); - // sleep(1); $tx = $remote->sendtoaddress($deposit_address, $amount); @@ -107,6 +104,12 @@ function sellCoinToExchange($coin) return; } } + + if($tx) + { + $market->lastsent = time(); + $market->save(); + } $exchange = new db_exchange; $exchange->market = $marketname; diff --git a/web/yaamp/core/backend/system.php b/web/yaamp/core/backend/system.php index 9d5478a92..b70da2ce9 100644 --- a/web/yaamp/core/backend/system.php +++ b/web/yaamp/core/backend/system.php @@ -35,8 +35,7 @@ function BackendQuickClean() foreach($coins as $coin) { - $delay = time() - 24*60*60; - if ($coin->symbol=='DCR') $delay = time() - 7*24*60*60; + $delay = time() - 7*24*60*60; $id = dboscalar("select id from blocks where coin_id=$coin->id and time<$delay and id not in (select blockid from earnings where coinid=$coin->id) diff --git a/web/yaamp/core/backend/users.php b/web/yaamp/core/backend/users.php index 35bc8bb36..443443d10 100644 --- a/web/yaamp/core/backend/users.php +++ b/web/yaamp/core/backend/users.php @@ -70,7 +70,7 @@ function BackendUsersUpdate() } if (empty($user->coinid)) { - debuglog("{$user->username} is an unknown address!"); + debuglog("{$user->hostaddr} - {$user->username} is an unknown address!"); } $user->save(); diff --git a/web/yaamp/core/common/util.php b/web/yaamp/core/common/util.php index d49403531..999d89748 100644 --- a/web/yaamp/core/common/util.php +++ b/web/yaamp/core/common/util.php @@ -40,6 +40,13 @@ function getparam($p,$default='') return isset($_REQUEST[$p]) ? $_REQUEST[$p] : $default; } +function gethexparam($p,$default='') +{ + $str = getparam($p, NULL); + $hex = (is_string($str) && ctype_xdigit($str)) ? $str : $default; + return $hex; +} + function getiparam($p,$default=0) { // workaround for yii default /route/ .... @@ -54,6 +61,12 @@ function getiparam($p,$default=0) return isset($_REQUEST[$p]) ? intval($_REQUEST[$p]) : $default; } +function getalgoparam() +{ + $algo = strip_tags(substr(getparam('algo'), 0, 32)); + return $algo; +} + ////////////////////////////////////////////////////// function downloadFile($url, &$size) diff --git a/web/yaamp/core/exchange/bitz.php b/web/yaamp/core/exchange/bitz.php new file mode 100644 index 000000000..37405710e --- /dev/null +++ b/web/yaamp/core/exchange/bitz.php @@ -0,0 +1,24 @@ +data; +} diff --git a/web/yaamp/core/exchange/cryptohub.php b/web/yaamp/core/exchange/cryptohub.php new file mode 100644 index 000000000..611172474 --- /dev/null +++ b/web/yaamp/core/exchange/cryptohub.php @@ -0,0 +1,68 @@ +$symbol)); + if(!$coin) return false; + $pair = $symbol; + $market = getdbosql('db_markets', "coinid={$coin->id} AND name='$exchange'"); + if(!$market) return false; + + } else if (is_object($market)) { + + $coin = getdbo('db_coins', $market->coinid); + if(!$coin) return false; + $symbol = $coin->getOfficialSymbol(); + $pair = $symbol; + if (!empty($market->base_coin)) $pair = $market->base_coin.'_'.$symbol; + } + + $t1 = microtime(true); + $ticker = cryptohub_api_query("market/ticker",$pair); + if(!$ticker || empty($ticker)) return false; + $ticker = array_pop($ticker); + if(arraySafeVal($ticker,'highestBid') === NULL) { + debuglog("$exchange: invalid data received for $pair ticker"); + return false; + } + + $price2 = ((double) $ticker['highestBid'] + $ticker['lowestAsk']) / 2; + $market->price2 = AverageIncrement($market->price2, $price2); + $market->price = AverageIncrement($market->price, (double) $ticker['highestBid']); + if ($ticker['lowestAsk'] < $market->price) $market->price = $ticker['lowestAsk']; + $market->pricetime = time(); + $market->save(); + + $apims = round((microtime(true) - $t1)*1000,3); + user()->setFlash('message', "$exchange $symbol price updated in $apims ms"); + + return true; +} diff --git a/web/yaamp/core/exchange/exchange.php b/web/yaamp/core/exchange/exchange.php index fc2a983dc..2cad682ea 100644 --- a/web/yaamp/core/exchange/exchange.php +++ b/web/yaamp/core/exchange/exchange.php @@ -15,10 +15,14 @@ function strip_data($data) require_once("bitstamp.php"); require_once("bittrex.php"); +require_once("bitz.php"); require_once("bleutrade.php"); require_once("ccexapi.php"); require_once("cexio.php"); require_once("cryptobridge.php"); +require_once("gateio.php"); +require_once("graviex.php"); +require_once("cryptohub.php"); require_once("kraken.php"); require_once("poloniex.php"); require_once("yobit.php"); @@ -79,6 +83,8 @@ function getMarketUrl($coin, $marketName) $url = "https://www.binance.com/trade.html?symbol={$symbol}_{$base}"; else if($market == 'bittrex') $url = "https://bittrex.com/Market/Index?MarketName={$base}-{$symbol}"; + else if($market == 'bitz') + $url = "https://www.bit-z.com/exchange/{$symbol}_{$base}"; else if($market == 'poloniex') $url = "https://poloniex.com/exchange#{$lowbase}_{$lowsymbol}"; else if($market == 'bleutrade') @@ -93,6 +99,8 @@ function getMarketUrl($coin, $marketName) $url = "https://coinsmarkets.com/trade-{$base}-{$symbol}.htm"; else if($market == 'cryptobridge') $url = "https://wallet.crypto-bridge.org/market/BRIDGE.{$symbol}_BRIDGE.{$base}"; + else if($market == 'cryptohub') + $url = "https://cryptohub.online/market/{$symbol}/{$base}"; else if($market == 'cryptopia') $url = "https://www.cryptopia.co.nz/Exchange?market={$symbol}_{$base}"; else if($market == 'cryptowatch') @@ -101,6 +109,10 @@ function getMarketUrl($coin, $marketName) $url = "https://c-cex.com/?p={$lowsymbol}-{$lowbase}"; else if($market == 'empoex') $url = "http://www.empoex.com/trade/{$symbol}-{$base}"; + else if($market == 'gateio') + $url = "https://gate.io/trade/{$symbol}_{$base}"; + else if($market == 'graviex') + $url = "https://graviex.net/markets/{$lowsymbol}{$lowbase}"; else if($market == 'jubi') $url = "http://jubi.com/coin/{$lowsymbol}"; else if($market == 'hitbtc') diff --git a/web/yaamp/core/exchange/gateio.php b/web/yaamp/core/exchange/gateio.php new file mode 100644 index 000000000..21b6cbb70 --- /dev/null +++ b/web/yaamp/core/exchange/gateio.php @@ -0,0 +1,24 @@ + 1.0, 'yescrypt' => 1.0, 'yescryptR16' => 1.0, + 'yescryptR32' => 1.0, 'zr5' => 1.0, ); @@ -135,13 +144,17 @@ function getAlgoColors($algo) 'deep' => '#e0ffff', 'x11' => '#f0f0a0', 'x11evo' => '#c0f0c0', + 'x12' => '#ffe090', 'x13' => '#ffd880', 'x14' => '#f0c080', 'x15' => '#f0b080', 'x16r' => '#f0b080', + 'x16s' => '#f0b080', 'x17' => '#f0b0a0', 'xevan' => '#f0b0a0', + 'allium' => '#80a0d0', 'argon2' => '#e0d0e0', + 'aergo' => '#e0d0e0', 'bastion' => '#e0b0b0', 'blake' => '#f0f0f0', 'blakecoin' => '#f0f0f0', @@ -153,6 +166,7 @@ function getAlgoColors($algo) 'hsr' => '#aa70ff', 'keccak' => '#c0f0c0', 'keccakc' => '#c0f0c0', + 'hex' => '#c0f0c0', 'lbry' => '#b0d0e0', 'luffa' => '#a0c0c0', 'm7m' => '#d0a0a0', @@ -164,6 +178,7 @@ function getAlgoColors($algo) 'lyra2v2' => '#80c0f0', 'lyra2z' => '#80b0f0', 'phi' => '#a0a0e0', + 'phi2' => '#a0a0e0', 'polytimos' => '#dedefe', 'sib' => '#a0a0c0', 'skein' => '#80a0a0', @@ -172,12 +187,14 @@ function getAlgoColors($algo) 'bitcore' => '#f790c0', 'skunk' => '#dedefe', 'tribus' => '#c0d0d0', - 'a5a' => '#f0f0f0', + 'a5a' => '#f0f0f0', 'vanilla' => '#f0f0f0', 'velvet' => '#aac0cc', + 'vitalium' => '#f0b0a0', 'whirlpool' => '#d0e0e0', 'yescrypt' => '#e0d0e0', 'yescryptR16' => '#e2d0e2', + 'yescryptR32' => '#e2d0d2', 'zr5' => '#d0b0d0', 'MN' => '#ffffff', // MasterNode Earnings @@ -203,10 +220,13 @@ function getAlgoPort($algo) 'deep' => 3535, 'x11' => 3533, 'x11evo' => 3553, + 'x12' => 3233, 'x13' => 3633, 'x15' => 3733, 'x16r' => 3636, + 'x16s' => 3663, 'x17' => 3737, + 'aergo' => 3691, 'xevan' => 3739, 'hmq1725' => 3747, 'nist5' => 3833, @@ -216,6 +236,7 @@ function getAlgoPort($algo) 'neoscrypt' => 4233, 'argon2' => 4234, 'scryptn' => 4333, + 'allium' => 4443, 'lyra2' => 4433, 'lyra2v2' => 4533, 'lyra2z' => 4553, @@ -226,6 +247,7 @@ function getAlgoPort($algo) 'sib' => 5033, 'keccak' => 5133, 'keccakc' => 5134, + 'hex' => 5135, 'skein2' => 5233, //'groestl' => 5333, 'dmd-gr' => 5333, @@ -242,11 +264,14 @@ function getAlgoPort($algo) 'm7m' => 6033, 'veltor' => 5034, 'velvet' => 6133, + 'vitalium' => 3233, 'yescrypt' => 6233, 'yescryptR16' => 6333, + 'yescryptR32' => 6343, 'bastion' => 6433, 'hsr' => 7433, 'phi' => 8333, + 'phi2' => 8332, 'polytimos' => 8463, 'skunk' => 8433, 'tribus' => 8533, @@ -268,7 +293,7 @@ function getAlgoPort($algo) function yaamp_fee($algo) { $fee = controller()->memcache->get("yaamp_fee-$algo"); - if($fee) return $fee; + if($fee && is_numeric($fee)) return (float) $fee; /* $norm = yaamp_get_algo_norm($algo); if($norm == 0) $norm = 1; diff --git a/web/yaamp/core/rpc/easybitcoin.php b/web/yaamp/core/rpc/easybitcoin.php index 59d834202..5021887f0 100644 --- a/web/yaamp/core/rpc/easybitcoin.php +++ b/web/yaamp/core/rpc/easybitcoin.php @@ -135,6 +135,11 @@ function __call($method, $params) // The ID should be unique for each call $this->id++; + if (stripos($method, 'dump') !== false) { + $this->error = "$method method is not authorized!"; + return FALSE; + } + // If no parameters are passed, this will be an empty array if($method == 'getblocktemplate') { diff --git a/web/yaamp/core/rpc/wallet-rpc.php b/web/yaamp/core/rpc/wallet-rpc.php index f5b77c4b8..533bb13aa 100644 --- a/web/yaamp/core/rpc/wallet-rpc.php +++ b/web/yaamp/core/rpc/wallet-rpc.php @@ -7,6 +7,7 @@ class WalletRPC { public $type = 'Bitcoin'; protected $rpc; protected $rpc_wallet; + protected $hasGetInfo = false; // cache protected $account; @@ -42,6 +43,7 @@ function __construct($userOrCoin, $pw='', $host='localhost', $port=8332, $url=nu default: $this->type = 'Bitcoin'; $this->rpc = new Bitcoin($coin->rpcuser, $coin->rpcpasswd, $coin->rpchost, $coin->rpcport, $url); + $this->hasGetInfo = $coin->hasgetinfo; } } else { @@ -53,6 +55,12 @@ function __construct($userOrCoin, $pw='', $host='localhost', $port=8332, $url=nu function __call($method, $params) { + if (stripos($method, "dump") !== false) { + $this->error = "$method not authorized!"; + debuglog("$method rpc method is not authorized!"); + return false; + } + if ($this->type == 'Ethereum') { if (!isset($this->accounts)) { $this->accounts = $this->rpc->eth_accounts(); @@ -62,11 +70,6 @@ function __call($method, $params) // if wallet is stopped return false; } - if (stripos($method, "key") !== false) { - $this->error = "$method not authorized!"; - debuglog("$method not authorized (key)!"); - return false; - } // convert common methods used by yiimp switch ($method) { case 'getaccountaddress': @@ -377,7 +380,34 @@ function __call($method, $params) } // Bitcoin RPC - $res = $this->rpc->__call($method,$params); + switch ($method) { + case 'getinfo': + if ($this->hasGetInfo) { + $res = $this->rpc->__call($method,$params); + } else { + $miningInfo = $this->rpc->getmininginfo(); + $res["blocks"] = arraySafeVal($miningInfo,"blocks"); + $res["difficulty"] = arraySafeVal($miningInfo,"difficulty"); + $res["testnet"] = "main" != arraySafeVal($miningInfo,"chain"); + $walletInfo = $this->rpc->getwalletinfo(); + $res["walletversion"] = arraySafeVal($walletInfo,"walletversion"); + $res["balance"] = arraySafeVal($walletInfo,"balance"); + $res["keypoololdest"] = arraySafeVal($walletInfo,"keypoololdest"); + $res["keypoolsize"] = arraySafeVal($walletInfo,"keypoolsize"); + $res["paytxfee"] = arraySafeVal($walletInfo,"paytxfee"); + $networkInfo = $this->rpc->getnetworkinfo(); + $res["version"] = arraySafeVal($networkInfo,"version"); + $res["protocolversion"] = arraySafeVal($networkInfo,"protocolversion"); + $res["timeoffset"] = arraySafeVal($networkInfo,"timeoffset"); + $res["connections"] = arraySafeVal($networkInfo,"connections"); +// $res["proxy"] = arraySafeVal($networkInfo,"networks")[0]["proxy"]; + $res["relayfee"] = arraySafeVal($networkInfo,"relayfee"); + } + break; + default: + $res = $this->rpc->__call($method,$params); + } + $this->error = $this->rpc->error; return $res; } diff --git a/web/yaamp/core/trading/bittrex_trading.php b/web/yaamp/core/trading/bittrex_trading.php index 8f67ceca3..2ce73f223 100644 --- a/web/yaamp/core/trading/bittrex_trading.php +++ b/web/yaamp/core/trading/bittrex_trading.php @@ -236,7 +236,7 @@ function doBittrexTrading($quick=false) } $withdraw_min = exchange_get($exchange, 'withdraw_min_btc', EXCH_AUTO_WITHDRAW); - $withdraw_fee = exchange_get($exchange, 'withdraw_fee_btc', 0.001); + $withdraw_fee = exchange_get($exchange, 'withdraw_fee_btc', 0.0005); if($withdraw_min > 0 && $savebalance->balance >= ($withdraw_min + $withdraw_fee)) { // $btcaddr = exchange_get($exchange, 'withdraw_btc_address', YAAMP_BTCADDRESS); diff --git a/web/yaamp/core/trading/trading.php b/web/yaamp/core/trading/trading.php index f82205ebc..c8575fb1b 100644 --- a/web/yaamp/core/trading/trading.php +++ b/web/yaamp/core/trading/trading.php @@ -90,6 +90,9 @@ function runExchange($exchangeName=false) doBittrexTrading(true); updateBittrexMarkets(); break; + case 'bitz': + updateBitzMarkets(); + break; case 'cexio': getCexIoBalances(); diff --git a/web/yaamp/defaultconfig.php b/web/yaamp/defaultconfig.php index 195eb2118..7d95e97f6 100644 --- a/web/yaamp/defaultconfig.php +++ b/web/yaamp/defaultconfig.php @@ -48,6 +48,8 @@ if (!defined('YAAMP_BTCADDRESS')) define('YAAMP_BTCADDRESS', ''); if (!defined('YAAMP_SITE_URL')) define('YAAMP_SITE_URL', 'localhost'); if (!defined('YAAMP_API_URL')) define('YAAMP_API_URL', YAAMP_SITE_URL); +if (!defined('YAAMP_API_PAYOUTS')) define('YAAMP_API_PAYOUTS', false); +if (!defined('YAAMP_API_PAYOUTS_PERIOD')) define('YAAMP_API_PAYOUTS_PERIOD', 24 * 60 * 60); if (!defined('YAAMP_STRATUM_URL')) define('YAAMP_STRATUM_URL', YAAMP_SITE_URL); if (!defined('YAAMP_SITE_NAME')) define('YAAMP_SITE_NAME', 'YiiMP'); if (!defined('YAAMP_DEFAULT_ALGO')) define('YAAMP_DEFAULT_ALGO', 'x11'); @@ -55,7 +57,8 @@ if (!defined('YAAMP_ADMIN_IP')) define('YAAMP_ADMIN_IP', '127.0.0.1'); if (!defined('YAAMP_ADMIN_WEBCONSOLE')) define('YAAMP_ADMIN_WEBCONSOLE', true); -if (!defined('YAAMP_NOTIFY_NEW_COINS')) define('YAAMP_NOTIFY_NEW_COINS', true); +if (!defined('YAAMP_CREATE_NEW_COINS')) define('YAAMP_CREATE_NEW_COINS', true); +if (!defined('YAAMP_NOTIFY_NEW_COINS')) define('YAAMP_NOTIFY_NEW_COINS', false); if (!defined('YAAMP_LIMIT_ESTIMATE')) define('YAAMP_LIMIT_ESTIMATE', false); if (!defined('YAAMP_RENTAL')) define('YAAMP_RENTAL', false); @@ -69,3 +72,25 @@ // cli stuff if (!defined('YIIMP_CLI_ALLOW_TXS')) define('YIIMP_CLI_ALLOW_TXS', false); +// Lightning Network +if (!defined('LN_ENABLED')) define('LN_ENABLED', false); +if (!defined('LN_MY_BTC_ADDRESS')) define('LN_MY_BTC_ADDRESS', ''); +if (!defined('LN_MY_LN_ADDRESS')) define('LN_MY_LN_ADDRESS', ''); +if (!defined('LN_COIN')) define('LN_COIN', 'BTC'); +if (!defined('LN_MY_IP')) define('LN_MY_IP', ''); +if (!defined('LN_MY_PORT')) define('LN_MY_PORT', '9735'); +if (!defined('LN_FRACTION')) define('LN_FRACTION', 7); // Fraction of main BTC wallet to fund channels +if (!defined('LN_MIN_PAY')) define('LN_MIN_PAY', 1000); // min payout in satoshis +if (!defined('LN_MAIN_NODE')) define('LN_MAIN_NODE', ''); +if (!define('YAAMP_LN_NET')) define('YAAMP_LN_NET', 'TESTNET'); // TESTNET or MAINET +if (!define('YAAMP_LN_WORKERS')) define('YAAMP_LN_WORKERS', false); +if (!define('YAAMP_LN_FACTOR')) define('YAAMP_LN_FACTOR', 0.8); + +if (!isset($configLNGamePlayers)) $configLNGamePlayers = array ( + /* + // testnet: + 'testnet.millionbitcoinhomepage.net' => array('023bcc1daeb7c85208991e993a2eacf86f7d9584a6dc33291bbe5e19c986a31568', '51.15.250.152', '9735'), + 'yalls.org' => array('02212d3ec887188b284dbb7b2e6eb40629a6e14fb049673f22d2a0aa05f902090e', '54.236.55.50', '9735'), + 'testnet.satoshis.place' => array('02dd4cef0192611bc34cd1c3a0a7eb0f381e7229aa3309ae961a7fc0076b4d2bb6', '35.198.136.5', '9735') + */ + ); diff --git a/web/yaamp/modules/api/ApiController.php b/web/yaamp/modules/api/ApiController.php index 9a5a1568c..b6a7f0553 100644 --- a/web/yaamp/modules/api/ApiController.php +++ b/web/yaamp/modules/api/ApiController.php @@ -6,8 +6,6 @@ class ApiController extends CommonController ///////////////////////////////////////////////// -// debuglog("saving renter {$_SERVER['REMOTE_ADDR']} $renter->address"); - public function actionStatus() { $client_ip = arraySafeVal($_SERVER,'REMOTE_ADDR'); @@ -82,6 +80,7 @@ public function actionStatus() "estimate_current" => $price, "estimate_last24h" => $avgprice, "actual_last24h" => $btcmhday1, + "mbtc_mh_factor" => $algo_unit_factor, "hashrate_last24h" => (double) $hashrate1, ); if(YAAMP_RENTAL) { @@ -285,12 +284,38 @@ public function actionWalletEx() } echo "]"; + + if(YAAMP_API_PAYOUTS) + { + $json_payouts = controller()->memcache->get("api_payouts-$user->id"); + if (empty($json_payouts)) { + $json_payouts = ",\"payouts\": "; + $json_payouts .= "["; + $list = getdbolist('db_payouts', "account_id={$user->id} AND completed>0 AND tx IS NOT NULL AND time >= ".(time() - YAAMP_API_PAYOUTS_PERIOD)." ORDER BY time DESC"); + foreach($list as $j => payout) + { + if($j) $json_payouts .= ", "; + $json_payouts .= "{"; + $json_payouts .= "\"time\": \"$payout->time\","; + $json_payouts .= "\"amount\": \"$payout->amount\","; + $json_payouts .= "\"tx\": \"$payout->tx\""; + $json_payouts .= "}"; + } + $json_payouts .= "]"; + controller()->memcache->set("api_payouts-$user->id", $json_payouts, 60, MEMCACHE_COMPRESSED); + } + echo str_replace("},","},\n", $json_payouts); + } + echo "}"; } + ///////////////////////////////////////////////// + public function actionRental() { if(!LimitRequest('api-rental', 10)) return; + if(!YAAMP_RENTAL) return; $key = getparam('key'); $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); @@ -335,6 +360,8 @@ public function actionRental() public function actionRental_price() { + if(!YAAMP_RENTAL) return; + $key = getparam('key'); $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); if(!$renter) return; @@ -352,6 +379,8 @@ public function actionRental_price() public function actionRental_hashrate() { + if(!YAAMP_RENTAL) return; + $key = getparam('key'); $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); if(!$renter) return; @@ -369,6 +398,8 @@ public function actionRental_hashrate() public function actionRental_start() { + if(!YAAMP_RENTAL) return; + $key = getparam('key'); $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); if(!$renter || $renter->balance<=0) return; @@ -385,6 +416,8 @@ public function actionRental_start() public function actionRental_stop() { + if(!YAAMP_RENTAL) return; + $key = getparam('key'); $renter = getdbosql('db_renters', "apikey=:apikey", array(':apikey'=>$key)); if(!$renter) return; @@ -399,33 +432,5 @@ public function actionRental_stop() $job->save(); } -// public function actionNodeReport() -// { -// $name = getparam('name'); -// $uptime = getparam('uptime'); - -// $server = getdbosql('db_servers', "name='$name'"); -// if(!$server) -// { -// $server = new db_servers; -// $server->name = $name; -// } - -// $server->uptime = $uptime; -// $server->save(); -// } - } -// function dummy() -// { -// $uptime = system('uptime'); -// $name = system('hostname'); - -// fetch_url("http://".YAAMP_SITE_URL."/api/nodereport?name=$name&uptime=$uptime"); -// } - - - - - diff --git a/web/yaamp/modules/bench/devices.php b/web/yaamp/modules/bench/devices.php index 5bc76d3f8..68174eee1 100644 --- a/web/yaamp/modules/bench/devices.php +++ b/web/yaamp/modules/bench/devices.php @@ -105,11 +105,7 @@ $chip = CHtml::link($chip, '/bench?chip='.$row['idchip'].'&algo=all'); } echo ''.$chip.''; - - if ($row['type'] == 'gpu') - echo ''.$row['device'].getProductIdSuffix($row).''; - else - echo ''.formatCPU($row).''; + echo ''.formatDevice($row).''; if (substr($vendorid,0,4) == '10de') echo ''.$vendorid.''; diff --git a/web/yaamp/modules/bench/functions.php b/web/yaamp/modules/bench/functions.php index 9e67a9583..84b3e45ea 100644 --- a/web/yaamp/modules/bench/functions.php +++ b/web/yaamp/modules/bench/functions.php @@ -140,6 +140,20 @@ function formatCPU($row) return trim($device); } +function formatGPU($row) +{ + $label = $row['device'].getProductIdSuffix($row); + return strip_tags($label); +} + +function formatDevice($row) +{ + if ($row['type'] == 'gpu') + return formatGPU($row); + else + return formatCPU($row); +} + function getChipName($row) { if ($row['type'] == 'cpu') { @@ -179,6 +193,8 @@ function getChipName($row) $chip = str_replace('650 Ti BOOST','650 Ti', $chip); $chip = str_replace('760 Ti OEM','760 Ti', $chip); $chip = str_replace(' (Pascal)',' Pascal', $chip); + $chip = str_replace('Quadro M6000 24GB','Quadro M6000', $chip); + $chip = str_replace('Tesla P100 (PCIe)','Tesla P100', $chip); $chip = str_replace('Tesla P100-SXM2-16GB','Tesla P100', $chip); $chip = str_replace('Tesla P100-PCIE-16GB','Tesla P100', $chip); $chip = str_replace('Tesla V100-SXM2-16GB','Tesla V100', $chip); diff --git a/web/yaamp/modules/bench/index.php b/web/yaamp/modules/bench/index.php index f45cd6e92..1546dfce7 100644 --- a/web/yaamp/modules/bench/index.php +++ b/web/yaamp/modules/bench/index.php @@ -144,14 +144,12 @@ echo ''.CHtml::link($row['algo'],'/bench?algo='.$row['algo']).''; echo ''.$age.''; echo ''.($row['idchip'] ? CHtml::link($row['chip'],'/bench?chip='.$row['idchip']) : $row['chip']).''; - if ($row['type'] == 'cpu') { - echo ''.formatCPU($row).''; - echo ''.CHtml::link($row['vendorid'],'/bench?vid='.$row['vendorid']).''; - echo ''.$row['arch'].''; - } else { - echo ''.$row['device'].getProductIdSuffix($row).''; - echo ''.CHtml::link($row['vendorid'],'/bench?vid='.$row['vendorid']).''; + echo ''.formatDevice($row).''; + echo ''.CHtml::link($row['vendorid'],'/bench?vid='.$row['vendorid']).''; + if ($row['type'] == 'gpu') { echo ''.formatCudaArch($row['arch']).''; + } else { + echo ''.$row['arch'].''; } echo ''.$hashrate.''; diff --git a/web/yaamp/modules/explorer/ExplorerController.php b/web/yaamp/modules/explorer/ExplorerController.php index c1650075b..cfa192539 100644 --- a/web/yaamp/modules/explorer/ExplorerController.php +++ b/web/yaamp/modules/explorer/ExplorerController.php @@ -59,8 +59,8 @@ public function actionIndex() $coin = getdbo('db_coins', $id); if($coin && $coin->no_explorer) { $link = $coin->link_explorer; - //$txid = getparam('txid'); - //$hash = getparam('hash'); + //$txid = gethexparam('txid'); + //$hash = gethexparam('hash'); //if (!empty($txid)) $link .= 'tx/'.$txid; //elseif (!empty($hash)) $link .= 'block/'.$hash; die("Block explorer disabled, please use $link"); @@ -71,11 +71,11 @@ public function actionIndex() $remote = new WalletRPC($coin); $hash = $remote->getblockhash(intval($height)); } else { - $hash = getparam('hash'); + $hash = gethexparam('hash'); } - $txid = getparam('txid'); - $q = getparam('q'); + $txid = gethexparam('txid'); + $q = gethexparam('q'); if (strlen($q) >= 32 && ctype_xdigit($q)) { $remote = new WalletRPC($coin); $block = $remote->getblock($q); @@ -87,7 +87,7 @@ public function actionIndex() } } - if($coin && !empty($txid) && ctype_xdigit($txid)) + if($coin && !empty($txid)) { $remote = new WalletRPC($coin); $tx = $remote->getrawtransaction($txid, 1); @@ -96,7 +96,7 @@ public function actionIndex() $hash = arraySafeVal($tx,'blockhash'); } - if($coin && !empty($hash) && ctype_xdigit($hash)) + if($coin && !empty($hash)) $this->render('block', array('coin'=>$coin, 'hash'=>$hash)); else if($coin) @@ -116,9 +116,9 @@ public function actionId() public function actionSearch() { $height = getiparam('height'); - $txid = arraySafeVal($_REQUEST,'txid'); - $hash = arraySafeVal($_REQUEST,'hash'); - $q = arraySafeVal($_REQUEST,'q'); + $txid = gethexparam('txid'); + $hash = gethexparam('hash'); + $q = gethexparam('q'); if (isset($_GET['SYM'])) { // only for visible coins $url = "/explorer/".$_GET['SYM']."?"; diff --git a/web/yaamp/modules/explorer/coin.php b/web/yaamp/modules/explorer/coin.php index e4db45e06..ce724c797 100644 --- a/web/yaamp/modules/explorer/coin.php +++ b/web/yaamp/modules/explorer/coin.php @@ -68,7 +68,7 @@ $type = ''; if (arraySafeval($block,'nonce',0) > 0) $type = 'PoW'; else if (isset($block['auxpow'])) $type = 'Aux'; - else if (isset($block['mint']) || arraySafeVal($block,'flags') == 'proof-of-stake') $type = 'PoS'; + else if (isset($block['mint']) || strstr(arraySafeVal($block,'flags',''), 'proof-of-stake')) $type = 'PoS'; // nonce 256bits if ($type == '' && $coin->symbol=='ZEC') $type = 'PoW'; diff --git a/web/yaamp/modules/explorer/util.php b/web/yaamp/modules/explorer/util.php index fb66eaf27..1d5d5df3f 100644 --- a/web/yaamp/modules/explorer/util.php +++ b/web/yaamp/modules/explorer/util.php @@ -160,11 +160,17 @@ function versionToAlgo($coin, $version) $algos['DGC'] = array( 0=>'scrypt', 1=>'sha256', 2=>'x11' ); + $algos['DUO'] = array( + 0=>'sha256', 1=>'scrypt' + ); $algos['J'] = array( 2 =>'sha256', 3=>'x11', 4=>'x13', 5=>'x15', 6=>'scrypt', 7 =>'nist5', 8 =>'myr-gr', 9=>'penta', 10=>'whirlpool', 11=>'luffa', 12=>'keccak', 13=>'quark', 15=>'bastion' ); + $algos['GCH'] = array( + 0=>'x12', 1=>'x11', 2=>'x13', 3=>'sha256', 4=>'blake2s' + ); $algos['RICHX'] = array( 0=>'sha256', 1=>'scrypt', 2=>'myr-gr', 3=>'skein', 4=>'qubit' ); @@ -177,13 +183,23 @@ function versionToAlgo($coin, $version) $algos['XVG'] = array( 0=>'scrypt', 1=>'scrypt', 2=>'myr-gr', 3=>'x17', 4=>'blake2s', 10=>'lyra2v2', ); + $algos['XSH'] = array( + 0=>'scrypt', 1=>'scrypt', 2=>'myr-gr', 3=>'x17', 4=>'blake2s', 10=>'lyra2v2', 11=>'x16s', + ); + $algos['ARG'] = array( + 0=>'sha256', 1=>'scrypt', 2=>'lyra2v2', 3=>'myr-gr', 4=>'argon2d', 5=>'yescrypt', + ); $symbol = $coin->symbol; if (!empty($coin->symbol2)) $symbol = $coin->symbol2; if ($symbol == 'J') return arraySafeVal($algos[$symbol], $version, ''); + else if($symbol == 'GCH') + return arraySafeVal($algos[$symbol], ($version - 9), ''); else if($symbol == 'XVG') return arraySafeVal($algos[$symbol], ($version >> 11), 'scrypt'); + else if($symbol == 'XSH') + return arraySafeVal($algos[$symbol], (($version-536870000) >> 11), 'scrypt'); else if (isset($algos[$symbol])) return arraySafeVal($algos[$symbol], ($version >> 9) & 7, ''); return false; diff --git a/web/yaamp/modules/renting/login.php b/web/yaamp/modules/renting/login.php index 5f4cc6d86..e7ad453a4 100644 --- a/web/yaamp/modules/renting/login.php +++ b/web/yaamp/modules/renting/login.php @@ -13,6 +13,9 @@ $address = getparam('address'); if($address == 0) $address = ''; +if (!empty($address) && preg_match('/[^A-Za-z0-9]/', $address)) { + die; +} echo <<goback(); } - public function actionCancelorder() + public function actionCancelorder() { if(!$this->admin) return; $order = getdbo('db_orders', getiparam('id')); @@ -1091,7 +1091,7 @@ public function actionCancelorder() public function actionAlgo() { - $algo = substr(getparam('algo'), 0, 32); + $algo = getalgoparam(); $a = getdbosql('db_algos', "name=:name", array(':name'=>$algo)); if($a) @@ -1108,7 +1108,7 @@ public function actionAlgo() public function actionGomining() { - $algo = substr(getparam('algo'), 0, 32); + $algo = getalgoparam(); if ($algo == 'all') { return; } @@ -1192,4 +1192,9 @@ public function actionMainbtc() setcookie('mainbtc', '1', time()+60*60*24, '/'); } + public function actionLn() + { + if(LN_ENABLED == false || (YAAMP_LN_NET == 'MAINET' && !$this->admin)) return; + $this->render('/site/ln'); + } } diff --git a/web/yaamp/modules/site/api.php b/web/yaamp/modules/site/api.php index 2a7520b02..0c84881ed 100644 --- a/web/yaamp/modules/site/api.php +++ b/web/yaamp/modules/site/api.php @@ -45,9 +45,19 @@ "accepted": 82463372.083, "rejected": 0 }] + + "payouts":[{ + "time": "1529860641", + "amount": "0.001", + "tx": "transaction_id_of_the_payout" + }] + } - +

Pool Status

request: diff --git a/web/yaamp/modules/site/common_results.php b/web/yaamp/modules/site/common_results.php index fb88841e2..88abe8b11 100644 --- a/web/yaamp/modules/site/common_results.php +++ b/web/yaamp/modules/site/common_results.php @@ -507,20 +507,13 @@ function cronstate2text($state) } } -//$state_block = $this->memcache->get('cronjob_block_state'); -$state_main = $this->memcache->get('cronjob_main_state'); +$state_main = (int) $this->memcache->get('cronjob_main_state'); $btc = getdbosql('db_coins', "symbol='BTC'"); if (!$btc) $btc = json_decode('{"id": 6, "balance": 0}'); echo ''; for($i=0; $i<10; $i++) { -// if($i != $state_block-1 && $state_block>0) -// { -// $state = $this->memcache->get("cronjob_block_state_$i"); -// if($state) echo "block $i "; -// } - if($i != $state_main-1 && $state_main>0) { $state = $this->memcache->get("cronjob_main_state_$i"); diff --git a/web/yaamp/modules/site/index.php b/web/yaamp/modules/site/index.php index a1888b8ce..824eaffd2 100644 --- a/web/yaamp/modules/site/index.php +++ b/web/yaamp/modules/site/index.php @@ -67,6 +67,18 @@
  • As optional password, you can use -p c=<SYMBOL> if yiimp does not set the currency correctly on the Wallet page.
  • See the "Pool Status" area on the right for PORT numbers. Algorithms without associated coins are disabled.
  • + +Lightning Network payments are enabled on this pool on . You can send Lightning Network invoices using LN page'; +if (YAAMP_LN_NET == 'TESTNET' && YAAMP_LN_WORKERS == true) echo ' or '; +if (YAAMP_LN_WORKERS == true) { + ?>the workername to send the invoice. Example: +

    + -o stratum+tcp://:<PORT> -u <WALLET_ADDRESS>.<invoice> [-p <OPTIONS>]

    + Lightning Network invoices can be generated from a LN wallet or directly on a merchant's website (List of merchants (mainet), List of merchants (testnet)). +
    diff --git a/web/yaamp/modules/site/ln.php b/web/yaamp/modules/site/ln.php new file mode 100644 index 000000000..da5c40eed --- /dev/null +++ b/web/yaamp/modules/site/ln.php @@ -0,0 +1,240 @@ + + Auto refresh is paused - Click to resume +--> + +
    +END; + +echo << +
    Lightning Network (testnet)
    +
    +END; + +//echo "

    Lightning Network (testnet)

    "; + +echo "

    Lightning Network (LN) is a second-layer network based on bitcoin on-chain transactions. "; +echo "It allows to perform bitcoin transactions with less fees and high speed.

    "; +//echo "More informations: lightning.network

    "; +echo "

    This page allows you to pay LN bills/invoices on testnet for any service on testnet.

    "; + +//echo "

    ?

    "; +?> + + +
      + +Please type a bolt11 testnet bill. Try again"; +// die; +} +else if (!empty($bill)) { +// Save bill (or pay it directly if enough funds) +$db_bill = getdbosql('db_invoices', "bolt11=:bolt11", array(':bolt11'=>$bill)); +// etdbo('db_invoices', $bill); + +if (!$db_bill) { + echo << +
      +
      Invoice payment status
      +
      +

      + Your invoice was saved in the list of invoices to pay, it will be paid soon. Please refresh this page in few seconds.
      +A scheduled task is running once per 20 seconds to pay automatically all bills in the list. +

      +
      +END; + dborun("INSERT IGNORE INTO invoices(bolt11, status) VALUES (:key,:val)", array( + ':key'=>$bill,':val'=>"New" + )); +} +else { + echo << +
      +
      Invoice payment status
      +
      +END; + echo "

      This bill is already into the list of bills.
      "; + echo "Its status is: ".$db_bill->status."
      "; + switch ($db_bill->status) { + case 'New': + echo "The scheduled task did not run yet, your invoice will be processed in a short while."; + break; + case 'maxfee': + echo "The fee associated with your invoice is too high compared to the invoice amount. As the maximum fee is 4% for normal invoices, your invoice won't be paid. Please try again with a higher amount."; + break; + case 'synok': + echo "Synthax and destinator of the bill are correct."; + break; + case 'underpay': + echo "Payment of bill is ongoing."; + break; + case 'complete': + echo "Bill of ".$db_bill->amount." millisatoshi is paid ("; + echo number_format($db_bill->amount / 1000, 0)." satoshi = "; + echo number_format($db_bill->amount / 100000000000, 8)." bitcoin).
      "; + echo "Fee was ".($db_bill->paid - $db_bill->amount)." millisatoshi ("; + echo number_format(100*($db_bill->paid - $db_bill->amount)/$db_bill->amount, 2)." %)"; + break; + default: + echo "Err"; + } +echo "

      "; +global $configLNGamePlayers; +$found = false; +if ($db_bill->shop != "") { +//echo $db_bill->shop; +//var_dump($db_bill); + foreach ($configLNGamePlayers as $name => $player) { + if ($player[0] == $db_bill->shop) { + echo "Shop: ".$name." (".$db_bill->shop.") "; + $found = true; + break; + } + } + if ($found == false) { + echo "Shop: Unknown shop (".$db_bill->shop.")."; + } + +echo "
      Amount: ".$db_bill->amount. " millisatoshi ("; + echo number_format($db_bill->amount / 1000, 3)." satoshi = "; + echo number_format($db_bill->amount / 100000000000, 11)." bitcoin).
      "; +echo "Description: ".$db_bill->description; + } +echo "

      "; + +} +echo "
      "; +echo "

      Please refresh this screen to check the status of payment of the testnet bill.

      "; + +} +else +echo << +
      +
      Pay testnet bill:
      +
      +
      + + + +
      +
      +Your testnet bill should be created on a testnet shop such as The Million Bitcoin Homepage or another testnet shop that works with the LN node of the pool. +
      +
      +
      +END; + +echo << +
      How to use ?
      +
      +
        +
      • Bitcoin, altcoins and mining pools are still in development.
      • +
      • This pool allows miners to pay any testnet bill from The Million Bitcoin Homepage +(but you can also try with other LN testnet merchants such as yaals, +Starblocks or testnet.satoshis.place) with Lightning Network on Bitcoin testnet.
      • +How to use ? +
      • 1. Go to The Million Bitcoin Homepage,
      • +
      • 2. Make a drawing, click on "Publish your pixels",
      • +
      • 3. Copy/paste the payment request (invoice bolt11 reference) into the field here below and click on "Pay my testnet bill".
      • +
      • 4. Refresh the page to make sure that the payment was executed.
      • + +
    + +
    + +
    +
    How does it work ?
    +
    +

    +

    +

    +END; + +echo "
    +
    "; +?> +
    + + + + +
    "; +echo << +









    + +END; + +echo <<
    + + + +END; +?> diff --git a/web/yaamp/modules/site/results/found_results.php b/web/yaamp/modules/site/results/found_results.php index c18109354..e37a6365b 100644 --- a/web/yaamp/modules/site/results/found_results.php +++ b/web/yaamp/modules/site/results/found_results.php @@ -90,7 +90,7 @@ function WriteBoxHeader($title) echo ''; echo ''; - echo ''.$link.' ('.$coin->algo.')'.$flags.''; + echo ''.$link.' ('.$db_block->algo.')'.$flags.''; echo ''.$reward.' '.$coin->symbol_show.''; echo ''.$difficulty.''; echo ''.$height.''; diff --git a/web/yaamp/modules/site/wallet.php b/web/yaamp/modules/site/wallet.php index abeaaddbc..dc9e28ddf 100644 --- a/web/yaamp/modules/site/wallet.php +++ b/web/yaamp/modules/site/wallet.php @@ -14,6 +14,10 @@ } $address = getparam('address'); +if (!empty($address) && preg_match('/[^A-Za-z0-9]/', $address)) { + // Just to make happy XSS seekers who can hack their own browser html... + die; +} $drop_address = getparam('drop'); if (!empty($drop_address)) { @@ -137,9 +141,10 @@ $balance = $balance>0? "$balance BTC": ''; echo ''.$balance.''; - echo ''. - ''. - ''; + + $delicon = $address == $addr ? '' : ''; + echo ''.$delicon.''; + echo ''; } diff --git a/web/yaamp/modules/thread/CronjobController.php b/web/yaamp/modules/thread/CronjobController.php index 4af398266..0f7b026ca 100644 --- a/web/yaamp/modules/thread/CronjobController.php +++ b/web/yaamp/modules/thread/CronjobController.php @@ -3,12 +3,6 @@ require_once('serverconfig.php'); require_once('yaamp/defaultconfig.php'); -function ld($string) -{ - $d = date('h:i:s'); - echo("$d - $string\n"); -} - class CronjobController extends CommonController { private function monitorApache() @@ -45,9 +39,322 @@ private function monitorApache() } } + + public function actionRunLightning() + { + debuglog(__METHOD__); + set_time_limit(0); + +// $this->monitorApache(); + + $last_complete = memcache_get($this->memcache->memcache, "cronjob_ln_time_start"); + + // debuglog("Lightning turned on ?"); + $output = shell_exec('sudo lightning-cli -J getinfo'); + $output = json_decode($output); + + $lightning = false; + foreach ($output as $key => $out) + { + if ($key == 'id') { + debuglog("[LN] 1. Lightning is turned ON: OK"); + debuglog("[LN] My LN id = $out"); + $lightning = true; + } + } + if (!$lightning) + debuglog("[LN] Error: Please run lightningd in a screen"); + else { + debuglog("[LN] 2. Check LN BTC address"); + $outpute = shell_exec("sudo lightning-cli -J dev-listaddrs"); + $output = json_decode($outpute); + //debuglog("ok"); +// debuglog($outpute); + + $found = false; + //if (isset($output->addresses)) + foreach ($output->addresses as $out) { +// debuglog("in"); // value = ".$out["value"]." status = ".$out["status"]); + if (LN_MY_BTC_ADDRESS == $out->p2sh) { + $found = true; + debuglog("[LN] LN_MY_BTC_ADDRESS found and own : OK"); + break; + } + } + if ($found == false) { + debuglog("[LN] Error: Please create a p2sh-segwit address using lightning-cli newaddr then fill LN_MY_BTC_ADDRESS"); + } + else { + debuglog("[LN] 3. Check funds"); // TODO: Enhance the logic + + $output = shell_exec("sudo lightning-cli -J listfunds"); + $listfunds = json_decode($output); +// debuglog($output); + + $ln_balance = 0; + + $found = false; + if (count($listfunds->outputs) > 0) + foreach ($listfunds->outputs as $out) { +// debuglog("in"); // value = ".$out["value"]." status = ".$out["status"]); + if ($out->status == "unconfirmed" && $out->output == 1 && count($listfunds->channels) > 0) { + debuglog("[LN] Channel creation ongoing"); + $found = true; + } + + if ($out->status == "confirmed" && $out->output == 1 && count($listfunds->channels) > 0 && $out->value > 100) { + $ln_balance = $out->value; + debuglog("[LN] seems ok (logic to enhance)"); + $found = true; + } + if ("confirmed" == $out->status && 0 == $out->output && count($listfunds->channels) > 0) { + $ln_balance = $out->value; + $found = true; + debuglog("[LN] Initial funding onchain : OK"); + break; + } + } + if ($found == false) { + debuglog("[LN] Error: Please perform a Bitcoin onchain transaction to ".LN_MY_BTC_ADDRESS); + // testnet faucet : https://testnet.manu.backend.hamburg/faucet + } + else { + + debuglog("LN Balance (not in channels) = ".$ln_balance." sat = ".($ln_balance/100000000)." BTC"); + + debuglog("[LN] 4. Check connections"); + + $output = shell_exec('sudo lightning-cli -J listpeers'); + $output = json_decode($output); + + global $configLNGamePlayers; + + foreach ($configLNGamePlayers as $player) { + //debuglog($player[0]); + $connected = false; + foreach ($output->peers as $out) { + if ($out->id == $player[1]) { + debuglog("Connected to player OK"); + $connected = true; + break; + } + } + if ($connected == false) { + debuglog("Connect to player..."); + $ttt = 'sudo lightning-cli -J connect ' . $player[1] . ' ' . $player[2] . ' ' . $player[3]; // . "'"; + //debuglog("OK"); + debuglog($ttt); + + $output = shell_exec($ttt); + debuglog($output); + // todo: handle errors to avoid this peer (into memcache ?) + // -1, "message" : "Connection establishment: Connection timed out + } + } + + debuglog("[LN] 5. Check channels funds : cancelled !"); + +// $output = shell_exec('sudo lightning-cli -J list'); +// $output = json_decode($output); + $found = true; +/* if (count($listfunds->channels) > 0) + foreach ($listfunds->channels as $out) { +// debuglog("in"); // value = ".$out["value"]." status = ".$out["status"]); + if ($out->channel_sat > 100 && isset($out->id_peer) && $out->id_peer == LN_MAIN_NODE) { + $found = true; + debuglog("[LN] Channel credit > 100 : OK"); + //break; + } + else { + debuglog("[LN] Channel $out->peer_id with less than 100 !!! To refund ..."); + // I dont think that the function to refund a channel is already developped in LN ... + $output = shell_exec('sudo lightning-cli close '.$out->id_peer); //. ' ' . max( 16777215, round($ln_balance / LN_FRACTION))); + $output = json_decode($output); + debuglog($output); + break; + } + } +*/ + if ($found == false) { + debuglog("[LN] No channels credited: Channel credit with a fraction of the remaining funds"); + //foreach ($configLNGamePlayers as $player) { + // code : -32602 [message] => 'Funding satoshi must be <= 16777215' +// $output = shell_exec('sudo lightning-cli -J fundchannel '.$out->id_peer. ' ' . min( 16777215, round($ln_balance / LN_FRACTION))); +// $output = json_decode($output); +// debuglog($output); + //} + + } + else { + debuglog("[LN] 6. Channel open on LN : cancelled !"); +/* + $outpute = shell_exec('sudo lightning-cli -J listpeers'); + $output = json_decode($outpute); +//debuglog($outpute); + $found = true; // false; + if (isset($output->peers)) + if(count($output->peers) > 0) + foreach ($output->peers as $out) { + debuglog("Peer ".$out->alias); + if (count($out->channels) > 0) + foreach ($out->channels as $o) { + if ($o->state == "CHANNELD_AWAITING_LOCKIN") { + debuglog("[LN] Waiting for 3 to 6 confirmations on bitcoin network. CHANNELD_AWAITING_LOCKIN:Funding needs more confirmations."); + } + if ($o->state == "CHANNELD_NORMAL") { + debuglog("[LN] Channel open : OK"); + } + if ($o->state == "GOSSIPING") { + $output = shell_exec('sudo lightning-cli -J fundchannel '.$out->id_peer. ' ' . min( 16777215, round($ln_balance / LN_FRACTION))); + $output = json_decode($output); + debuglog($output); + } + if ($o->state == "ONCHAIN") + && in_array("ONCHAIN:All outputs resolved: waiting 99 more blocks before forgetting channel", $o->states)) { + $output = shell_exec('sudo lightning-cli -J fundchannel '.$out->id_peer. ' ' . min( 16777215, round($ln_balance / LN_FRACTION))); + $output = json_decode($output); + debuglog($output); + } + } + } + debuglog("channels chekcs ended"); +*/ + if (true) { + debuglog("Payment will be done"); + if (true) { // $ln_balance > LN_MIN_PAY) { + + $db_bills = dbolist("SELECT bolt11 from invoices WHERE status='New' ORDER by id ASC"); + if (!$db_bills) { + debuglog("Nothing to pay"); + } + else { + debuglog("There are LN invoices to pay"); + foreach ($db_bills as $bill) { +// debuglog("Bill"); +// break; +// } +// } + +//if (!empty($bill) && preg_match('/[^A-Za-z0-9]/', $bill)) { +//echo "Please type a bolt11 testnet bill. Try again"; +// die; +//} + +// debuglog("before"); +// debuglog($bill['bolt11']); + $oo = "sudo lightning-cli -J decodepay ".$bill['bolt11']; + debuglog($oo); + $outpute = shell_exec($oo); + $output = json_decode($outpute); + debuglog($outpute); + if (isset($output->message) && $output->message == "Invalid bolt11: Bad bech32 string") { + // debuglog("clean invalid"); + dborun("UPDATE invoices SET status = 'Invalid' WHERE bolt11='".$bill['bolt11']."'"); + debuglog("Invoice with invalid bolt11"); + break; + } + if (isset($output->description)) { + dborun("UPDATE invoices SET description = '".addslashes(htmlentities($output->description))."' WHERE bolt11='".$bill['bolt11']."'"); + debuglog("Update description"); // TODO: add filter to prevent injections here + } + if (isset($output->payee)) { + dborun("UPDATE invoices SET shop = '".$output->payee."' WHERE bolt11='".$bill['bolt11']."'"); + debuglog("Update shop"); // TODO: add filter to prevent injections here + } + if (isset($output->msatoshi)) { + dborun("UPDATE invoices SET amount = '".$output->msatoshi."' WHERE bolt11='".$bill['bolt11']."'"); + debuglog("Update amount"); + } + + $oo = "sudo lightning-cli -J pay maxfeepercent=4 maxdelay=1200 bolt11=".$bill['bolt11']; + debuglog($oo); + $outpute = shell_exec($oo); +// debuglog("ok"); + $output = json_decode($outpute); + debuglog($outpute); + if (isset($output->message) && $output->message == "Invoice expired") { + dborun("UPDATE invoices SET status = 'Expired' WHERE bolt11='".$bill['bolt11']."'"); + debuglog("Invoice expired"); + break; + } + + if (isset($output->message) && $output->message == "Invalid bolt11: Bad bech32 string") { + // debuglog("clean invalid"); + dborun("UPDATE invoices SET status = 'Invalid' WHERE bolt11='".$bill['bolt11']."'"); + debuglog("Invoice with invalid bolt11"); + break; + } + if (isset($output->message) && (strpos($output->message == "max fee requested is") !== false)) { + // Fee 2001 is 1.352941% of payment 147900; max fee requested is + // debuglog("clean invalid"); + dborun("UPDATE invoices SET status = 'maxfee' WHERE bolt11='".$bill['bolt11']."'"); + debuglog("Invoice with too much fee."); + break; + } + + if (isset($output->status) && $output->status == "complete") { + // debuglog("clean invalid"); + dborun("UPDATE invoices SET status = 'complete', exectime = '".time()."' WHERE bolt11='".$bill['bolt11']."'"); + debuglog("Bill paid ! :-)"); + if (isset($output->msatoshi_sent)) { + dborun("UPDATE invoices SET paid = '".$output->msatoshi_sent."' WHERE bolt11='".$bill['bolt11']."'"); + } + break; + } + +/* + + //debuglog($output); +// if ($output->msatoshi == LN_MIN_PAY * 1000) { // * 1000 because millisat + $outpute = shell_exec('sudo lightning-cli -J pay '.$bill); + $output = json_decode($outpute); + debuglog($outpute); + if ($output->code == 206) // "code" : 206, "message" : "Delay (locktime) is 576 blocks; max delay requested is 500." + // https://github.com/ElementsProject/lightning/issues/1586 issue still opened + { + $outpute = shell_exec('sudo lightning-cli -J pay maxdelay=577 bolt11='.$bill); + $output = json_decode($outpute); + debuglog($outpute); + } + if ($output->code == 200) // "code" : 200, "message" : "Stopped retrying during payment attempt; continue monitoring with pay or listpayments" + { + debuglog("[LN] Err 200: Stopped retrying during payment attempt; continue monitoring with pay or l"); + } + if ($output->code == 205) // "code" : 205, "message" : "Could not find a route" + { + debuglog("[LN] Err 205"); + } + } + else + debuglog("[LN] Bill: bad amount ".$output->msatoshi." ".(LN_MIN_PAY * 1000)); + +*/ + break; + } + } + + +// $bill = file_get_contents(""); + } + } + //debuglog($outpute); + } + + //debuglog($output["id"]); + //debuglog("Refund channel if new payment occured"); + + } + } + } + + memcache_set($this->memcache->memcache, "cronjob_ln_time_start", time()); +// debuglog(__METHOD__); + } + + public function actionRunBlocks() { -// debuglog(__METHOD__); +// screenlog(__FUNCTION__); set_time_limit(0); $this->monitorApache(); @@ -55,20 +362,21 @@ public function actionRunBlocks() $last_complete = memcache_get($this->memcache->memcache, "cronjob_block_time_start"); if($last_complete+(5*60) < time()) dborun("update jobs set active=false"); - BackendBlockFind1(); - BackendClearEarnings(); + if(!memcache_get($this->memcache->memcache, 'balances_locked')) { + BackendClearEarnings(); + } BackendRentingUpdate(); BackendProcessList(); BackendBlocksUpdate(); memcache_set($this->memcache->memcache, "cronjob_block_time_start", time()); -// debuglog(__METHOD__); +// screenlog(__FUNCTION__.' done'); } public function actionRunLoop2() { -// debuglog(__METHOD__); +// screenlog(__FUNCTION__); set_time_limit(0); $this->monitorApache(); @@ -83,7 +391,7 @@ public function actionRunLoop2() MonitorBTC(); $last = memcache_get($this->memcache->memcache, 'last_renting_payout2'); - if($last + 5*60 < time()) + if($last + 5*60 < time() && !memcache_get($this->memcache->memcache, 'balances_locked')) { memcache_set($this->memcache->memcache, 'last_renting_payout2', time()); BackendRentingPayout(); @@ -97,7 +405,7 @@ public function actionRunLoop2() } memcache_set($this->memcache->memcache, "cronjob_loop2_time_start", time()); -// debuglog(__METHOD__); +// screenlog(__FUNCTION__.' done'); } public function actionRun() @@ -209,10 +517,13 @@ public function actionRun() sleep(10); BackendDoBackup(); - memcache_set($this->memcache->memcache, 'apache_locked', false); + // prevent user balances changes during payments (blocks thread) + memcache_set($this->memcache->memcache, 'balances_locked', true, 0, 300); BackendPayments(); + memcache_set($this->memcache->memcache, 'balances_locked', false); + BackendCleanDatabase(); // BackendOptimizeTables(); diff --git a/web/yaamp/modules/trading/index.php b/web/yaamp/modules/trading/index.php index db69d233e..d510b071a 100644 --- a/web/yaamp/modules/trading/index.php +++ b/web/yaamp/modules/trading/index.php @@ -10,6 +10,9 @@ $height = '240px'; $wallet = user()->getState('yaamp-wallet'); +if (!empty($wallet) && preg_match('/[^A-Za-z0-9]/', $wallet)) { + die; +} $user = getuserparam($wallet); $algo_unit = 'Mh'; diff --git a/web/yaamp/ui/main.php b/web/yaamp/ui/main.php index 0d0394870..68be000cd 100644 --- a/web/yaamp/ui/main.php +++ b/web/yaamp/ui/main.php @@ -120,14 +120,22 @@ function showPageHeader() if (YAAMP_USE_NICEHASH_API) showItemHeader(controller()->id=='nicehash', '/nicehash', 'Nicehash'); + + if (LN_ENABLED) + showItemHeader(controller()->id=='ln', '/site/ln', 'LN'); } - + + if (LN_ENABLED && YAAMP_LN_NET == 'TESTNET' && !controller()->admin) + showItemHeader(controller()->id=='ln', '/site/ln', 'LN (testnet)'); + echo ''; $mining = getdbosql('db_mining'); $nextpayment = date('H:i T', $mining->last_payout+YAAMP_PAYMENTS_FREQ); + $eta = ($mining->last_payout+YAAMP_PAYMENTS_FREQ) - time(); + $eta_mn = 'in '.round($eta / 60).' minutes'; - echo 'Next Payout: '.$nextpayment.''; + echo 'Next Payout: '.$nextpayment.''; echo ""; echo "";