diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index b4382289d..467a94514 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,18 @@ *.o -agents/iguana -agents/libcrypto777.a + + agents/iguana.exe iguana/pnacl/Release/iguana_unstripped.pexe +iguana/pnacl/Release/iguana.pexe + +agents/libcrypto777.a + iguana/pnacl/Release/iguana_unstripped.bc *.deps diff --git a/InstantDEX/Makefile b/InstantDEX/Makefile old mode 100644 new mode 100755 diff --git a/InstantDEX/index.html b/InstantDEX/index.html old mode 100644 new mode 100755 diff --git a/InstantDEX/main.c b/InstantDEX/main.c old mode 100644 new mode 100755 diff --git a/LEGAL/AUTHORS b/LEGAL/AUTHORS old mode 100644 new mode 100755 diff --git a/LEGAL/DEVELOPER-AGREEMENT b/LEGAL/DEVELOPER-AGREEMENT old mode 100644 new mode 100755 diff --git a/LEGAL/LICENSE b/LEGAL/LICENSE old mode 100644 new mode 100755 diff --git a/LEGAL/THIRDPARTY-LICENSES b/LEGAL/THIRDPARTY-LICENSES old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 985d18afa..36a90a51d --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ > #TL;DR# > -> ```sudo apt-get update; sudo apt-get install libcurl4-gnutls-dev libssl-dev; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix; ./m_unix; agents/iguana``` +> ```sudo apt-get update; sudo apt-get install libcurl4-gnutls-dev libssl-dev libgmp3-dev; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix; ./m_unix; agents/iguana``` > > The above one line gets SuperNET installed, built and launched for unix. > diff --git a/SuperNET/Makefile b/SuperNET/Makefile old mode 100644 new mode 100755 diff --git a/SuperNET/SuperNET.c b/SuperNET/SuperNET.c old mode 100644 new mode 100755 diff --git a/SuperNET/SuperNET.h b/SuperNET/SuperNET.h old mode 100644 new mode 100755 diff --git a/SuperNET/index.html b/SuperNET/index.html old mode 100644 new mode 100755 diff --git a/SuperNET/main.c b/SuperNET/main.c old mode 100644 new mode 100755 diff --git a/SuperNET/tools/common.mk b/SuperNET/tools/common.mk old mode 100644 new mode 100755 diff --git a/_API.md b/_API.md new file mode 100755 index 000000000..e69de29bb diff --git a/agents/.tmp b/agents/.tmp old mode 100644 new mode 100755 diff --git a/agents/field.html b/agents/field.html old mode 100644 new mode 100755 diff --git a/agents/footer.html b/agents/footer.html old mode 100644 new mode 100755 diff --git a/agents/formfooter.html b/agents/formfooter.html old mode 100644 new mode 100755 diff --git a/agents/formheader.html b/agents/formheader.html old mode 100644 new mode 100755 diff --git a/agents/header.html b/agents/header.html old mode 100644 new mode 100755 diff --git a/agents/iguana b/agents/iguana new file mode 100755 index 000000000..90f8d12ac Binary files /dev/null and b/agents/iguana differ diff --git a/agents/libcrypto777.a b/agents/libcrypto777.a new file mode 100755 index 000000000..7a71827de Binary files /dev/null and b/agents/libcrypto777.a differ diff --git a/android/Android_Readme.md b/android/Android_Readme.md old mode 100644 new mode 100755 diff --git a/android/include/curl/Makefile b/android/include/curl/Makefile old mode 100644 new mode 100755 diff --git a/android/include/curl/Makefile.am b/android/include/curl/Makefile.am old mode 100644 new mode 100755 diff --git a/android/include/curl/Makefile.in b/android/include/curl/Makefile.in old mode 100644 new mode 100755 diff --git a/android/include/curl/curl.h b/android/include/curl/curl.h old mode 100644 new mode 100755 diff --git a/android/include/curl/curlbuild.h b/android/include/curl/curlbuild.h old mode 100644 new mode 100755 diff --git a/android/include/curl/curlbuild.h.cmake b/android/include/curl/curlbuild.h.cmake old mode 100644 new mode 100755 diff --git a/android/include/curl/curlbuild.h.in b/android/include/curl/curlbuild.h.in old mode 100644 new mode 100755 diff --git a/android/include/curl/curlrules.h b/android/include/curl/curlrules.h old mode 100644 new mode 100755 diff --git a/android/include/curl/curlver.h b/android/include/curl/curlver.h old mode 100644 new mode 100755 diff --git a/android/include/curl/easy.h b/android/include/curl/easy.h old mode 100644 new mode 100755 diff --git a/android/include/curl/mprintf.h b/android/include/curl/mprintf.h old mode 100644 new mode 100755 diff --git a/android/include/curl/multi.h b/android/include/curl/multi.h old mode 100644 new mode 100755 diff --git a/android/include/curl/stamp-h2 b/android/include/curl/stamp-h2 old mode 100644 new mode 100755 diff --git a/android/include/curl/stdcheaders.h b/android/include/curl/stdcheaders.h old mode 100644 new mode 100755 diff --git a/android/include/curl/typecheck-gcc.h b/android/include/curl/typecheck-gcc.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/aes.h b/android/include/openssl/aes.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/asn1.h b/android/include/openssl/asn1.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/asn1_mac.h b/android/include/openssl/asn1_mac.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/asn1t.h b/android/include/openssl/asn1t.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/bio.h b/android/include/openssl/bio.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/blowfish.h b/android/include/openssl/blowfish.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/bn.h b/android/include/openssl/bn.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/buffer.h b/android/include/openssl/buffer.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/camellia.h b/android/include/openssl/camellia.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/cast.h b/android/include/openssl/cast.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/cmac.h b/android/include/openssl/cmac.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/cms.h b/android/include/openssl/cms.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/comp.h b/android/include/openssl/comp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/conf.h b/android/include/openssl/conf.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/conf_api.h b/android/include/openssl/conf_api.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/cryptlib.h b/android/include/openssl/cryptlib.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/crypto.h b/android/include/openssl/crypto.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/curl.h b/android/include/openssl/curl.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/curlbuild.h b/android/include/openssl/curlbuild.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/curlrules.h b/android/include/openssl/curlrules.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/curlver.h b/android/include/openssl/curlver.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/des.h b/android/include/openssl/des.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/des_old.h b/android/include/openssl/des_old.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/dh.h b/android/include/openssl/dh.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/dsa.h b/android/include/openssl/dsa.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/dso.h b/android/include/openssl/dso.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/dtls1.h b/android/include/openssl/dtls1.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/e_os.h b/android/include/openssl/e_os.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/e_os2.h b/android/include/openssl/e_os2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/easy.h b/android/include/openssl/easy.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ebcdic.h b/android/include/openssl/ebcdic.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ec.h b/android/include/openssl/ec.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ecdh.h b/android/include/openssl/ecdh.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ecdsa.h b/android/include/openssl/ecdsa.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/engine.h b/android/include/openssl/engine.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/err.h b/android/include/openssl/err.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/evp.h b/android/include/openssl/evp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/fips_err.h b/android/include/openssl/fips_err.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/hmac.h b/android/include/openssl/hmac.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/idea.h b/android/include/openssl/idea.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/krb5_asn.h b/android/include/openssl/krb5_asn.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/kssl.h b/android/include/openssl/kssl.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/lhash.h b/android/include/openssl/lhash.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/md32_common.h b/android/include/openssl/md32_common.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/md4.h b/android/include/openssl/md4.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/md5.h b/android/include/openssl/md5.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/mdc2.h b/android/include/openssl/mdc2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/modes.h b/android/include/openssl/modes.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/mprintf.h b/android/include/openssl/mprintf.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/multi.h b/android/include/openssl/multi.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/o_dir.h b/android/include/openssl/o_dir.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/o_str.h b/android/include/openssl/o_str.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/o_time.h b/android/include/openssl/o_time.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/obj_mac.h b/android/include/openssl/obj_mac.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/objects.h b/android/include/openssl/objects.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ocsp.h b/android/include/openssl/ocsp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/opensslconf.h b/android/include/openssl/opensslconf.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/opensslv.h b/android/include/openssl/opensslv.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ossl_typ.h b/android/include/openssl/ossl_typ.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pem.h b/android/include/openssl/pem.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pem2.h b/android/include/openssl/pem2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pkcs12.h b/android/include/openssl/pkcs12.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pkcs7.h b/android/include/openssl/pkcs7.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/pqueue.h b/android/include/openssl/pqueue.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/rand.h b/android/include/openssl/rand.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/rc2.h b/android/include/openssl/rc2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/rc4.h b/android/include/openssl/rc4.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ripemd.h b/android/include/openssl/ripemd.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/rsa.h b/android/include/openssl/rsa.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/safestack.h b/android/include/openssl/safestack.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/seed.h b/android/include/openssl/seed.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/sha.h b/android/include/openssl/sha.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/srp.h b/android/include/openssl/srp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/srtp.h b/android/include/openssl/srtp.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ssl.h b/android/include/openssl/ssl.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ssl2.h b/android/include/openssl/ssl2.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ssl23.h b/android/include/openssl/ssl23.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ssl3.h b/android/include/openssl/ssl3.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/stack.h b/android/include/openssl/stack.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/stdcheaders.h b/android/include/openssl/stdcheaders.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/symhacks.h b/android/include/openssl/symhacks.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/tls1.h b/android/include/openssl/tls1.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ts.h b/android/include/openssl/ts.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/txt_db.h b/android/include/openssl/txt_db.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/typecheck-gcc.h b/android/include/openssl/typecheck-gcc.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ui.h b/android/include/openssl/ui.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/ui_compat.h b/android/include/openssl/ui_compat.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/whrlpool.h b/android/include/openssl/whrlpool.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/x509.h b/android/include/openssl/x509.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/x509_vfy.h b/android/include/openssl/x509_vfy.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/x509v3.h b/android/include/openssl/x509v3.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/zconf.h b/android/include/openssl/zconf.h old mode 100644 new mode 100755 diff --git a/android/include/openssl/zlib.h b/android/include/openssl/zlib.h old mode 100644 new mode 100755 diff --git a/android/lib/libcrypto.so b/android/lib/libcrypto.so old mode 100644 new mode 100755 diff --git a/android/lib/libcurl.a b/android/lib/libcurl.a old mode 100644 new mode 100755 diff --git a/android/lib/libssl.so b/android/lib/libssl.so old mode 100644 new mode 100755 diff --git a/chrome_extension.sh b/chrome_extension.sh index 347ec530a..812ae85eb 100755 --- a/chrome_extension.sh +++ b/chrome_extension.sh @@ -3,16 +3,22 @@ echo About to create a chrome extension rm -rf pnacl_${BUILD_NUMBER}.zip -mkdir -p pnacl_${BUILD_NUMBER} - -cp -rf iguana/manifest.json pnacl_${BUILD_NUMBER}/ -cp -f iguana/pnacl/Release/iguana.pexe pnacl_${BUILD_NUMBER}/ -cp -rf confs/* pnacl_${BUILD_NUMBER}/ -cp -rf iguana/icon128.png pnacl_${BUILD_NUMBER}/ -cp -rf *.html pnacl_${BUILD_NUMBER}/ -cp -rf LEGAL/** pnacl_${BUILD_NUMBER}/ -cp -rf css/** pnacl_${BUILD_NUMBER}/ -cp -rf js/** pnacl_${BUILD_NUMBER}/ +mkdir -p pnacl_${BUILD_NUMBER}/pnacl/Release/ + +#copying required folders +cp -rf iguana/css pnacl_${BUILD_NUMBER}/ +cp -rf iguana/js pnacl_${BUILD_NUMBER}/ +cp -rf iguana/app pnacl_${BUILD_NUMBER}/ +cp -rf iguana/confs pnacl_${BUILD_NUMBER}/ +cp -rf iguana/fonts pnacl_${BUILD_NUMBER}/ +cp -rf iguana/images pnacl_${BUILD_NUMBER}/ +cp -rf iguana/help pnacl_${BUILD_NUMBER}/ + +cp -rf iguana/pnacl/Release/{iguana.nmf,iguana.pexe} pnacl_${BUILD_NUMBER}/pnacl/Release/ + +cd iguana +find . -maxdepth 1 \( -iname \*.js -o -iname \*.html -o -iname \*.ico -o -iname \*.json -o -iname \*.png \) -exec cp -r {} ../pnacl_${BUILD_NUMBER} \; +cd - echo Listing the contents of pnacl_${BUILD_NUMBER} ls -al pnacl_${BUILD_NUMBER}/ diff --git a/confs/BTCD_hdrs.txt b/confs/BTCD_hdrs.txt old mode 100644 new mode 100755 diff --git a/confs/BTCD_peers.txt b/confs/BTCD_peers.txt old mode 100644 new mode 100755 diff --git a/confs/BTC_hdrs.txt b/confs/BTC_hdrs.txt index 71f7075f4..120788ff5 100644 --- a/confs/BTC_hdrs.txt +++ b/confs/BTC_hdrs.txt @@ -1,4 +1,4 @@ -398011 +400011 0 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f dece1ed3311faba0f3bc7792930799ecc20985ea95997c5e8edf1a876f17aed1 2000 00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a 41e27d57bc7a3a7694e3cb13a92984b37dc4e98bf3f935b58c68227d0ee06702 4000 00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842 83c43672b8617e4c4a4bbfcfa99f8877fd9db36ed19e57ff7c686f182b60bfce @@ -199,3 +199,4 @@ 394000 000000000000000009ae6157a480e351cdeb8be494362a3bf3cd1c4feedf8ad6 e871c05b4794191df935d8a585fbabba5cb981ff5936d49a1078aa8ad925802f 396000 0000000000000000079226c668cd1db713fb78ffc127b422e12b47baf205b478 f9542a8a8185328b82984691a41509cf245d008d875d158e6d770b703c08b5fa 398000 000000000000000001c6bd9d2dbccc3f16ddb534119de0aeb7d0a8c87f78e001 e73b9cb5fb81415bbe18e2601f261aeb8fe843d53ecf708219da5bfe096df418 +400000 000000000000000004ec466ce4732fe6f1ed1cddc2ed4b328fff5224276e3f6f 78cde34786c36dccfdde5f90f26e4f49df8202d38e7f813a49e4a288b52d2f3f diff --git a/confs/BTC_oldhdrs.txt b/confs/BTC_oldhdrs.txt new file mode 100755 index 000000000..71f7075f4 --- /dev/null +++ b/confs/BTC_oldhdrs.txt @@ -0,0 +1,201 @@ +398011 +0 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f dece1ed3311faba0f3bc7792930799ecc20985ea95997c5e8edf1a876f17aed1 +2000 00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a 41e27d57bc7a3a7694e3cb13a92984b37dc4e98bf3f935b58c68227d0ee06702 +4000 00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842 83c43672b8617e4c4a4bbfcfa99f8877fd9db36ed19e57ff7c686f182b60bfce +6000 00000000dbbb79792303bdd1c6c4d7ab9c21bba0667213c2eca955e11230c5a5 66f3cdb93a6b871f468a44456e12a11ba102cf76be74ccbc61d615ce9c076acb +8000 0000000094fbacdffec05aea9847000522a258c269ae37a74a818afb96fc27d9 4f93ddc7cc1dd0427dbfd9ef7080b70e676553c566b358a807b9abd4006b2196 +10000 0000000099c744455f58e6c6e98b671e1bf7f37346bfd4cf5d0274ad8ee660cb 9d4c6e97e3959c23f38ed37798743df5a4d47e34683cab54603f3000f934b511 +12000 0000000011d1d9f1af3e1d038cebba251f933102dbe181d46a7966191b3299ee 8b8feb0ba990705d4378e1b778e62db2d417c8985ae569b7fb3e6844e8a58852 +14000 000000002d9050318ec8112057423e30b9570b39998aacd00ca648216525fce3 9ccb85438e9350235b1d30c01ce0b2f3e408ddc5193e73badb3977a3d52cc134 +16000 00000000679a1ab3af6da03f13a0bc96d7215e65458b2d2edfa030b5b431e8b3 38f5879424c92f6160f4adf7bb8ca8d0002dd1a7ea82a47cff891ad2eba92468 +18000 00000000f914f0d0692e56bd06565ac4de668251b6a29fe0535d1e0031cfd0de 476ef2170dbdb8ab3a921d8ffafcb87b521002dc33e50863a469b14f721bae1a +20000 00000000770ebe897270ca5f6d539d8afb4ea4f4e757761a34ca82e17207d886 23551ac19182c7d69112344013508171046ccdede1f5c4a5912e151bed6803fe +22000 000000004625a14242beccb38c63a1f770a76ee5788764e6c0abd4129bbc1b9d 67ac3ab11d5d6bccec6805f1aa725b464c45b75cbbd2d29c7f35ecb599c220ba +24000 00000000f04fccc81f37002707e9501a3f7bdcf25f65531f386a2da8af20122e b0ea761af31989e9f6766d8f3ed5e64af98661011b31b6e52cd223a715ba7351 +26000 000000006d6c151db6d4d67356d590a897a11cd7d8111ee989de6f2f548410bf 56aaf4660baebf6c881604875dfe216fb720330f27a8ec011aa97aa03c0d0783 +28000 00000000172c5ed49d7dfc29bf9a18a53fa2d050fa37aa210d6d4080fd0c7e67 999d77cd45d68a64d152b00d003953142d2685d3a19286844c05ae72b41df7c8 +30000 00000000de1250dc2df5cf4d877e055f338d6ed1ab504d5b71c097cdccd00e13 409f89a04968a0af18c834c55fc15685c24b26e4f07f1dcc129de4db3e77451e +32000 00000000049172ba3ec1b673cf13e3d0049c1c07bb103ed3fa300e3833480055 9c91128d2961310ee1eb83ab25e7c3468cfceb08a8689fd9ef27bacfbb73eeb3 +34000 00000000495968d19210d3be15bd24fdc19805a0ef15026b0bb4482b04a9da3c eaf2fe87514eaada77c27a8796dee58e55918ab4d3d97511eea08fc323064caf +36000 0000000080c3deea35dc3df90a5fbe5f27db52f5e01018ae7d62f8b454c71335 d3092ecd06aeb81f6ef6e323b7ef660122dd72d9c33c6d7208c2acc30f417636 +38000 000000002dfebce284d1e08b6cf04452530891579b7377669865889498de8f3f 18a63c2239c8d7903b8ea3c153ad8ab8b723e705018a2e13ee5ca443ef11cd1e +40000 00000000504d5fa0ad2cb90af16052a4eb2aea70fa1cba653b90a4583c5193e4 546d597a9a0648ef89a77811c4036ee380cdca1febb0e95da45003693e6b3d5e +42000 000000000f80c09687893406279f62da437a6a0b95b8dc096b30c10ce088fc64 3890d815c8a112f061307bc03683391523587a5edcf6b60c9656358e3c4aba97 +44000 000000000122898b31073a770a97cf599c00672fc8d6ae15652235862f8b76d8 0a1e6031ac37b5b67989d210cfb64eee7268c4cc3d94c253e9618e8b3862b6bf +46000 000000001dd39771dbe4f9fc6da07327f13f894dd2c1a46cdfcedf930fbbc52b 73fde83c7450255681d866ba1d8ea043c7e5a6daf605093c2dde3430a926242f +48000 000000000f3d40ea2bfa8d779010e52cff4720c072ec4b12ed576cf5cf93c947 9f34e4674f86609d74961eb54c1cc2f98f5590a6450863ea3e21e346719afd86 +50000 000000001aeae195809d120b5d66a39c83eb48792e068f8ea1fea19d84a4278a 6916dff98241e918e453f0eb52856de9aa9a960414b2993c8e97d75ff44cfc3e +52000 00000000082bc4398c4aa5bd8d9fc452d60d533ef68baabf594c9e7d6649049f ab884b30d7ed5872d1d90a2e25a8b095bb39434ae0f80a32adfc97eed69aaaf7 +54000 00000000144197f54afa21ae7db2bc93eee604432101fc0ebe7966a52bb27e61 17646473198bbeea3d60633c6d1c3380e5d119e1e9a2eb504abb615957a6836b +56000 000000000dfa452ea45e0426dd8914c35e24dfd4399037c5e6deb9f18f58d6d3 37e7e05cecd7df0602970dd7f985ed73ae216bd160994b4d07577881f299a4b6 +58000 0000000013e3791d288d9db814c52fbdf240b2206eb8e19d7dc80013c60c0c00 088e663cf7476201f3faf37e38fd435ac69e7939c4b3dadc3a065ac7d0466147 +60000 000000000b554c46f8eb7264d7d5e334382c6fc3098dabf734de37962ccd7495 7bf914410170e1fd75df6efc08af8617306a4cdea1d5c950101c700406783815 +62000 0000000006dd4bc72daabef992f860e703820de119af3e24a1ea6f6c81521011 bb58902ef76cab599d025523bf078110cbbcd99212f3b35953b637dbfb3b5630 +64000 0000000003d7055b51d7b9ab693de84c03201fe0396af61dbb30bf31445d3f55 e84093b7fa29447382f1354e788af857b14cd0d4b60f01c7211c8f537ef310c6 +66000 00000000071d7e8a0f4895e60c1073df9311d65a85244be1ee6369c9506281af 01318a72a31c85ca5b8b59fb235307588e85f3cbf892fa36d50f43887948ed48 +68000 0000000000d991791fdfdbccbbc2a73d2f86ccf78e2d0a7ce7675f40b5986b3e 08b4c9998a1a39c87016dd387d313a73a1d3d4917ec3941952780154436fe6bd +70000 00000000002b8cd0faa58444df3ba2a22af2b5838c7e4a5b687444f913a575c2 42621404a60ced6d1bd83116a726657ca1c23450322e3dc8be8f82fef75b326b +72000 0000000000eb357d4c6fef6ad9a6fade126985ad36042a99cf215a4454545977 c4df76d0f20fd07e30b763b28e60ef25f00dafe41ebbe08dab7fefe730915034 +74000 0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20 bd262f98ae8ff0c5a9fda8b744e000f67ab181f10e9daa192d05521505db3d25 +76000 0000000000571138ff757a28ddf9b56f28c4a461e170660bb5ae79a556069bb6 18762c4f10e41503af7c19f320ab05ecc0c6935d6976cf8c38123c294561edfd +78000 00000000001f3fe62641b473673c9ababbe207046a109f0861af95c905a918fa 61b897997332e2256ea43b37a6d838957181099b700818b7fbd6d0b990e79683 +80000 000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6 cdb9b85b40849062327de45286562a3014230fbdd615b332de6430072d63763e +82000 00000000000c9d1c4acc114afb58d55db5ec44a963263cf6247220b7a3f85c5c 5a91827586e71fa53b9cac1b98967fddfab0e732a1366cdd4131dcb29718fd1b +84000 00000000001385326e30864192ba84ed2f9cbfadf0698655b1c25f93c92f22ad 1e82db93950b485af0c98a91f84f5e2db290852015d5b8deff93772f4b5dbac1 +86000 000000000000ff4e1adb14f07774dad6b34968a5e19d1a2fe1fc9157e7c2b85d 50800ab18837ee3f87c6edf73c625b26ea2133354d9bb9423670fe755174da5a +88000 00000000000ae9e98b82b39a912cdc0ebed97c26376780ac996c84d9ec3264a4 9dec8129d35ae538ac5fe73c0c4496f3e42c6673ac010f9edbf2296d3c09e168 +90000 0000000000071694daf735a6b5da101d77a04c7e6008c680e461f0025ba7b7af 76a46a23998e76a022eaa9b7ce6a966153288c621432c25c047d479f8c4958a3 +92000 0000000000001df90b0c523a4d7e4731336b00cf4ba9d8e02d111523df80998c 158705b4874dd942efa31c146f7483fead8f2b8692469789247708a6cf19efe2 +94000 000000000002a4c42580d51f0ddfd867eaaa790781c484c633a69167d17b48ec 3474b1e5c321938d9091b0798efe7e18ab418658eb4b958841181c97da91ab88 +96000 000000000002c86b568cdd2d0f4b0430cccf42bcde3361f63a32e23b5d839e99 86e2f364192a51944f2cf0e35af7557e6b0e1fc578ab34204e57552259be5dd5 +98000 000000000002272a6dfb695d9db936d813bf0055ae92e920c2791d4c5f7290f1 c0d37a94957444d44255048391dea29cf12ab99b294a14cc89429123ff4021d1 +100000 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506 1012e9e419f5b93f096cec8df29b860bf0207e2ce09931d7d5c1a2eb6e030d67 +102000 00000000000335c47dd6ae953912d172a4d9839355f2083165043bb6f43c2f58 3f00c2b2a78004e5f9e9d20b245f5aab5b5bca68345979b00b16116002769ee9 +104000 000000000000a9887c91956b638bb3c0651321fdb24715354c3fc6633f5a16a3 16cf31820595a465b545bcc1190508ce091086d53b97b5e71bbff9d420bcb319 +106000 00000000000058d919f52d255f394ed0aa3a344432676fd30f1aab4e10c22fad 2d3a18e763ddd1f6eabc79b722b5bd98097f0d2c89abb9f449c481e78749d983 +108000 00000000000167cea0b43ff7ce22f330d3e302832187eb31c61b15bb1511e118 5d8584db379287def00b37a2d6fc9bc381eb1b723c6ccb5f7f1ac2b8ba4d6dc1 +110000 000000000001bbda3f22ef8e476b470a2d3ae16821c23a6d22db77318d0799a9 d6eb660c646bea29b93ee23bc569178dbee16b36b182df7e99ba18dc08489374 +112000 0000000000001d69b3899a49f37799c375a7471829953d5470f468f48ff70432 6ef68447cb6145c71a404ce44e3e7f1e2c45c8ec8f78080dd6f7735ba6b75b2e +114000 0000000000003195a1e6dc48a540264d37e9ef79b552bd78ea4b93a3b6e7e449 084813c7a679421b7e1eeae9897fd25bad3dc19a1e702818ee0a94a1e5d01c42 +116000 00000000000007ff257fb2edd3fdbd7b00c127a66dae1288fc5e26c402d13bf7 d2334cecec9805da62d511a4d2eb3743fb8f69c9d9141650947ff326a241ced0 +118000 000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553 b969a1da29e137da960fcc3cd0fa4960fefda1bfeda87edb4a430e62b08eeacf +120000 0000000000000e07595fca57b37fea8522e95e0f6891779cfd34d7e537524471 7c49116af07a77ca3fc5f5003b68585b9b689eed77154c1af88be8b467506fee +122000 0000000000002fe5f29af38282ac1c8f4ea2bf8a0855946150130419491b6c05 0efb5e74991e099c041ee1e22da6bdb06ad21df739595e2a8cf7e21a7163304e +124000 00000000000023e9a0523cfac29afe07a07acf81e273cd892c51ff8318846620 962c0106ebfe5e7d2b356fcd2f78a2180a6e136660cdcc85b195aadd311f291b +126000 000000000000166b7d480aada35af1e6f9a2835d68f9c2fbd272073dc6c9d5fb 15471893042686f902f90d6f2c0f3dd617fcc662abffb433bc608a9c261ea746 +128000 00000000000003b8ddd8692769e1965554a8bb030863e0566a28bc0dc952864e 3026d964b955a13f24bf1f795469f839da4a89bdef0de03372c5305494c9388e +130000 00000000000011906b491883ab0f16f0e690b133ca860b199b775c3cf6581c21 e8b17a15e52032cc813e52b283ea9afa020a166a105f8eb86e8202c8747d7476 +132000 00000000000000a7a0483857f0d951983ff2834a47c38fdcc22563ac0f8f707b 14a632498c78a609adc8cc4f2eacc23ca48cd4e18f7ed2652c5f143810a593c3 +134000 00000000000007e3e442ce1423496a064a7c34342ba98be164ac0c9f9b872213 e1dc2c77415d565b094abe960ab93118a6b8c4340f15ef57de7f61d45ee03e52 +136000 00000000000004da0d6d69fd474fa08fe2ff3111ff1e9e01f72899dcd9d897f0 00030c8c4775f8a50c3da2622f653024d45e2cfffaa6a202a50cae7da8ccc596 +138000 0000000000000044c7b6a5511c0b2ae64ec545abccac8053f31cf7bba23bb886 37372808d4a8d98e1a82d630db5ff9a6b2d5e190d28d7ca70f2acbb55af312a9 +140000 000000000000086e28cf4717a80066def0ec26c53d660582bd997221fef297db 372dcb64d18db0dfb6ea202f6718a40b5886bd69f4bbbaf760c14b2cb9bd125d +142000 00000000000006379826f5f10cd23739b9c29f87ca10f199f9f4b72006311f85 c0cba7384d1aecba968211e8d91859f80c901574bbfa5a6abae9bbcfdaa5894a +144000 0000000000000681a73f1bb50454cee419048d24e1091bcddadded89df53fd07 3922c45217b67d3245660060e7b6ff7a13ecc1eb66b7d62e4826834afdf0d0b2 +146000 0000000000000188cbeebda87456f040370995dc11eb3a1e76b1577b6e0b588d d49ec8d5f2b91e3bec87165770d8355d78e1934a8916637df186420bc1ff95f9 +148000 00000000000008be94b219a94752bde6a6a1c5b9d72abf2aaab53df7d93c5fa6 efa0fd50c1e7d8dc91040031052abe3cc851ab4c6675e3a4ce724d95c478d34c +150000 0000000000000a3290f20e75860d505ce0e948a1d1d846bec7e39015d242884b 5d8aea62e24c35e0266a24ec1200f47daf86fd8f3977ce7ab7132745a403e4fb +152000 0000000000000aca2b3a267dab498adc48afd15b60cbf21fa58dc26c86a6dc13 fe846c807abd35fb49fbb1d78136c0edf0debdb45ed086155f00504e72b9a7aa +154000 0000000000000a7446d1a63b8229670aa02d1d9fdfd729b89107fe5d88dacd8e 44fcd84719ce3be98a7d64e0ee3bc21d4e2cf0de2365370eb71d434ed9baaa85 +156000 00000000000002adfcffbd5f09744ae3b930597dd0ea684cd37b816783ba3762 7233ce2c246f20142d71b3972b9f6d8b51dc15ad134ace83ecc24e2fd9f8da28 +158000 00000000000000e50d56f13c7ce64183386abcac63462ca745b711be27568f52 b60615c9c91eb51eb52c8bc80782d6bb528a19ed309b957d28c1fc20372b31e0 +160000 000000000000066c6e629b2fb49c7fcc52b82fe9833f328e0c3943856facf231 7dd93cd9bc029e52f8f2ba78ea2029a920e8fe7cab865d055e4737ef257f56e8 +162000 00000000000001a83f5b20cd132f38f792fc02a17eb14d494c780ea9d1c82acc f87730a51ef49bf3dd51f6435344f9a01f939b00c3a280fedbe643d031432ef4 +164000 00000000000005a38f162cf308edea0a0a5d000bdb2073cba2386ebb1df7a2cf 06cd95a118d1293cd9aed19fa23bafb1fff0045d1dee3754f6442719706e0cfd +166000 00000000000003b3402f35327d144a465f3768d6e6cb06cd8a2d8fc1328b2477 e3282f15a892df27073c8c0fc76fa4648b624d47db47dfdcc1ac21d5ebdbaf0f +168000 000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763 524d8a0ef4e2aff9bb36851dfa1b359efe49f8848834fbe0791931c8942282f3 +170000 000000000000051f68f43e9d455e72d9c4e4ce52e8a00c5e24c07340632405cb b9f6e63a249962e7e4a422104077e0396dc2ab8d4a120806a7eec97d676b8d7c +172000 0000000000000837e82c3a4ebe35a1d1d943e056234dba7c629922c6d4052d4c c1c8170cb5acba5dcef1ce4b12f3e08db2acece327461af6d92bd557ed82fa8a +174000 0000000000000504d3e701deb624eee4370f50c3d688fd1c27be5bbef07d76dd 6fb97ccb59c9c83166a6599be85879f97e46997daea452a895bfe23b6e645429 +176000 00000000000004659b5b8602b2132b62973994079a1c828df6ef8d6427e4686b 24ebfb8a7f8996c1ce2d3441420e898aa6fb6b7f6a1a11a30ee708585af56d8c +178000 00000000000009eae2697a7aaf57e730b707b9f4530449c16d924d534d41f297 8fc623c7e53b100d697a24e3193411d0cafc14af70f20aa79c27ef5348e9996e +180000 00000000000004ff83b6c10460b239ef4a6aa320e5fffd6c7bcedefa8c78593c 9e0f0850e7deb21dc15a0676c2d55b2fcb73b66bc9f02e1b878966cee4a74aa8 +182000 000000000000068dce12903c1447e4c5b60311b61e443a25d5fc82c77f4f9a8f de9a4ba8ef86cab92ab5f6b5d6d8c180671036e603999b2a0b983b3eb5415d2b +184000 000000000000060405a235c6b968ccb18fd6b3800ae9742c2524e28863367359 25b40a18d6e6dc6966618e0636a16cd3b13d321632ced8f3935c9597a98d75df +186000 000000000000072ede9629fd1fd1af3cc2baa0e637f1959f34884be0e160dd1c 4cab848ccdaa00419273ef25ee9e64c164f6919ba04fb1fdd54106f1afbe5f72 +188000 000000000000004cf0c72d6dedfde88ca4c3dae129563210072ee68acded0ab1 68f7e02181e36a230abf6983f967813b89a0e0f98674158a50db6996e29db510 +190000 0000000000000708bf3b261ffc963b6a768d915f9cfc9ec0a6c2a09969efad1a 4c2cea5a930fe3af893a641eaf1f92899f4453af2b11455515c57406ecfa27dc +192000 00000000000000af130d565291ba49208c546685c69b48a293aaf06387fc22ef 9d58ad9678fae8bf7866d6edcccdc6678e8da63aab98df7f5bcf641aa9bf24be +194000 000000000000046242d4984ecf2217e9afa113f2835bffbff118f2df4d80b216 22376dfb11c837c1d70067afd38bd70554e6576fdadbab4d65c113d869899aca +196000 00000000000006ae59396d4a289e83fe1b9967630752a5799f064620af7836a9 a0101abab5da4a3947d441bd4838c1dc04fa824c67feb850384899e5f116af56 +198000 000000000000000f2ad431ff18ab1673d911395c8fa1f6801e054c5dcb54f8fb 1c7d1751d862cc8c87213435c51d9b1f6992945a097ed059c626b87cfbdc6efa +200000 000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf 380b65fa49998421330f6187ec57d31a132c9d1ac3e119f9a55c095b7f65f746 +202000 00000000000003282fe1d5533e4275fd9f51e6ba0352ec01f32914e9fbaeaf55 b65f823ad7e038d1dc64c4144e87f5f77f1910351122549ee79ab7600ee2227a +204000 0000000000000423eb625dc140272ab97fea3ba6baf1dc56de77deabcc492872 eb34c90dec6b2173136c797b36b0115a9448a68c047bcaba89df75f0c4891b93 +206000 0000000000000130b815d40fd6d8851438cd21ac9e428615ba03a1285ef1374c 568b3aa80c5504f24059cd0fc9f177b33480c33eaab9041f7c976fcdfa7d4bdf +208000 000000000000001db5a1515a5f8534c941b1628f60466e6b709b3b320254afff 11800801a4cc43da007a66aa7d7d96dd947086bee56917a6f786bb4fee5746cf +210000 000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e 91ffd7a5cf624d50981c4db059fef7cb148e5bdbf81fac67fd9599e5be55d3fa +212000 00000000000003d906e4131c39f7655b72df40146d2967f5d75113a09610de61 6ce91205ac2f4832d1c7cc99b9a935b80a52af6db0089d2276e4dab5427c9bf6 +214000 00000000000003e6427f9fafa8b0e1af0859f15cea90d911f64445d296a2781a f2c92f620050c691b8bb71976dbfd6c660a90f5ca5dd5723ae9add7e057f2d12 +216000 00000000000001f79a2db15d0ec6d951729e044749372caf504679bba5b1e65e 265dd035294ae9ec29783deb5d1488d506fa341a202980b3388e18ca037843b5 +218000 0000000000000569070e338293af66258adba29dcdd5f33212314dff752ff458 826c3a82b4fbc764b486ca1df08bfd3209fba9ab9b37f3fe77f529c49eacbe85 +220000 000000000000002fdd2c741ed50bc3975a640ca419081711f30f553939641303 fbb6729ca1783f40e5f7bd0937f4969158d671dc0a03850ddfcf2746dfa04057 +222000 00000000000002c752a481ce0c45450ab046e640d38d6532178721e7700d8148 e4cbaf6e4174fbd3f1d361396f5d136851b4f6542ea7fddbf8d8025a5c203986 +224000 0000000000000107ee276d037218bf1780dbf6d4256bd7e05c66ca133bbc9ac5 4f33a3a088c3ece8d87905a2c14baff172b4cafcf22b1dbdc61ad570adfffbe8 +226000 000000000000012c614cf477c3b155d339f29d565c0258f9846c2f4dd402ff9b fdde99179a5cc0891675e550a3803c903b65acd5c4a223cc188b4598e158c506 +228000 00000000000000efc4311c93fafbccedb6fdc682b566cba9519f1736b9788a67 960fbe213f3d6384eea60ce0c0cdbfda4af95e6d276596f05ed412edd7dd0ee5 +230000 000000000000012cfb19f5662707816e122ad60dd9b1cd646c6c9899be2c9667 74f1a551b24a3b99c6df3328285be3256b410df8e534a1fe06c88485e0a705b8 +232000 000000000000018f47636e1c3a946db77624880ae484ffb0233f5aac6316b3bb 532e37e6cdf476e407938b13ebd723793e57677639368d32bc378767d343384c +234000 00000000000000597f9263ea97bed4d3b10fbd55733a73bd1027f1a9b6c1451a 7e5e7cce998ee02fc54ac72faa03d127a8959d346e028b04d0eb24f7b09194ad +236000 00000000000000f2f5e55e89dde082cecc9b4a46a10bbb4197f5e35b16612db5 4cc95beafc27959fef3e9d31c47112e6ab83a12843cc35bfe341f94b92f5995f +238000 000000000000010014007d4b51ab60063684665401e448c6b0b1971a7398a442 0d8403176d4a29713df8b2bb56f1457e927391e9cc4e83122770cba48611de3a +240000 000000000000000e7ad69c72afc00dc4e05fc15ae3061c47d3591d07c09f2928 6ba437006735b0f9856fff92c4cb943a03f89022aa06321eb39484e8ad0b521d +242000 00000000000000c95233d37a8c78dff10afecb14060347151b7eb7a04a2a5a3c 4f837013584761696fa661ebeb6dd7824a71db18ab0cb8785aa43e2fdbe7d9ca +244000 000000000000006ded1526017d5b87ca22e1bd0da3921872cc99e9ec77ee5166 3ad2d2fde08f4b714d4bf7bce1e8aba066c27f8b7fe604e4903c940c52674b0c +246000 000000000000004c318a3ad2ebac28d140fada215b11f5b7d8e9151ff0b000af eccdaaffdadc837852f64c344ecbf0cca417df84a73435ca7ea7ce21245e87f0 +248000 000000000000004d945017c14b75a3a58a2aa6772cacbfcaf907b3bee6d7f344 8903f33f0671e4d616c52a9b7ff9fcfa52f2d8693de4d861171f9a9a4ebf60b4 +250000 000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214 fca9f44b3b916d15b3f443c421ca9ba2ab375fb4e04c67fa0376356bda89507c +252000 00000000000000200e99940b296ded4ce16462bba1950453b29abf313ba7cc47 e73cc4a756a24389065d1449aced46be359a3dde08d21771d6acc4cca13f7bfc +254000 000000000000004753be91559a2c74c6cb8a5d2be6db1df2ca0b2385697e53ff 53b9c0602531b91799388b526a92a080f416a050b11672d1d0445fa679675774 +256000 00000000000000252b217c0ce5c4d96b825b90dacbe8e4dcf5f6a8ba6749f3c2 3f5c51e6a34ee0efb91e840422f1a0cb9d369159ee3a60878af73275f8513fa2 +258000 00000000000000159f682a983465761f471dd24300746efe8db5642411f1b631 768d77dcefe6edb2ea15685557687aa1d56090364caa056a50500e9dbc003057 +260000 000000000000001fb91fbcebaaba0e2d926f04908d798a8b598c3bd962951080 a3dce35682fb3ab81208ee85e060fca7df01ac1f1571963cc282aadba5dc7ae5 +262000 000000000000001002ac67e026c523c3779b1ff2e3b9e2b7bfa6022ee1afae2a c84f3300243a15c28cb92da4a463a222994b4161ad7924d3ed4a229d2bea6ba2 +264000 000000000000000d05c31485c532503939ca0b88d7e322dff79900ee6cdd5ed4 0fbc45e463dd17169de0fa15142c8cc76b2e17ae63337522eedf481e67dede59 +266000 0000000000000009d755c65d58c7c1fde9167ba632a85574de3bb11c8a862e35 2ec325ba811b0f3ab51d3634509e01163fcda807fb4283b22ff9df612640d05f +268000 000000000000000048974ba0669938f7f8463650cd5c48c027aafd88c00a46af 8db51a37cf62199eaddb7b4c6eb8f3123ed0b86a5794e893e40973c96661b2b0 +270000 0000000000000002a775aec59dc6a9e4bb1c025cf1b8c2195dd9dc3998c827c5 c2346a70b37186219035dc71a1646401c8ba43c4e7acd77331e0fbdefce3b76e +272000 00000000000000050a89e2ffb28757d35e14615f23b981eca68906c8c71f65f2 c65c9f220b58b16cca0692250d1e0cad5ab362f4ebed32341c48607e6fda97ab +274000 0000000000000003fe2d3425e9f9b906f02f40b3db90d908ba0fbd1e44cf43f8 30ce70e30cdc5a67101f02b4f3a5c03a6884115dbcdc7575c9d67074410a0c53 +276000 0000000000000004b8ed801f8a09ba8c1248a5b1dd1533a35124a80438573f59 e1c5aab0f6644074f689bbf82342ed9506b1a0870e16693f8ac4262998defa15 +278000 0000000000000001bcadd1e4b4d01063a17347dfca126c63893d2aa37d82eb7f 64b4ff707207f3cc5ee178ae31fd21657cd40058e4b229c73eeffdf0ee2a3554 +280000 0000000000000001c091ada69f444dc0282ecaabe4808ddbb2532e5555db0c03 e2b966c103fc51cde523784e0ced0ee2cd3278b2e7b3df1f63a33f6b25a01ca1 +282000 0000000000000002337ad25e6a9767420766309cfea79f13dd9c910bcf5ca063 f240c2cd23349a0e763f38e584f1dc0bbf1d90472771442fe7884d4985067ee9 +284000 0000000000000000eac86582f121e5431734e2ea36bf73347022c99c1adae37f 2d1a44421e7e34d10bb7b5c32a59c9c5a3b14573e3d0a46c90e322bb05161dc3 +286000 00000000000000004388ae444347bde423f2f3aa6ef335b50909f5bc27d31ea3 e4ed93975428acd1ef1ef7bb927ac1daf20fb8c2d6adab05336992b6b0d0f4c7 +288000 00000000000000003c395f08779c3ac1301488b8a18c0999c008129a55610785 3b6fafbfdfc0b5178fa61259550f1b2103a5540487a626fdde1b6d9a0ba167a7 +290000 0000000000000000fa0b2badd05db0178623ebf8dd081fe7eb874c26e27d0b3b c58364e3c15d72620ef6e6a109ffa90f96e245c2ca97ce9a7dba1853fa82d3ac +292000 0000000000000000620671231acb6a68134a0396235dcb0e53f4fc82bbaa1184 facb26fe1435fbbfc5a310535d2908aef9062c0a6fd9b68916079a8023caf2fb +294000 0000000000000000cb2540b3f00ce422887904c75b24bf75b8a73817302a4138 b809bb53b2bfe7a4f5cc8799f0ed01ae9c7ad62e84337dedbaa254b645bd8d22 +296000 00000000000000009570102278e59ecf045c16ec8c8a5ea85bf823d0ec72e3d0 65ee22d627de991a1bbb6a0991a651f104402ced579619eb0f7a377d55773e7a +298000 000000000000000047d2f2eb7278e3f4aded9acaf502f5ec27bab5018b5871f2 017018dc979c71efe3f45156cf325f526282b12e166ddf89d268eeb58ecb2dd1 +300000 000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254 f7d092ed2a8dde8b8d9cddd1506113821128e2e159b853639deab2900c4fa120 +302000 0000000000000000072268c9bb18603566ed5012378c29bb4d37e34cead7448d 120995054ebb9c08b074422fba9ef42e8bb2bc30cd60258c844b966505f19a8c +304000 00000000000000003558a1ceec3f5338c0e887b4171410195a7fa0a81bcaa628 19e4344dc468e4e7c8dc4007d8ceff0addaed303635905de439366142697ea06 +306000 00000000000000002bb3265a8bf67ec2aa436c297ac7e56fcedd4dbaecccacc0 ac5028bfbcb9b75d7d6899a4011df8b145eeb608f5a49416bbef4bfc5c4a9abb +308000 00000000000000001d55aa114bddd81938d09e2dccd432dec59a4078ca0bc0f4 7e4d47a510a28d57b7f11345446c8e54c6a6229d8b5769cd379ca605233d134e +310000 0000000000000000125a28cc9e9209ddb75718f599a8039f6c9e7d9f1fb021e0 4648a8ed4221390d9a2c0fed720057624e3d33315588c4cc2bc9b8033d8c446d +312000 00000000000000002bd1fa27964e31fe9861b40940e7ece2cfa359765b219a49 e9d2bd7f66ce893da7326ee58375c74646d42a908e8c4836316e557d2427669a +314000 000000000000000008ae6cb20997f3c4aacc50ee2f0d08a0c3691907fe7357a3 58ca25e3391f26df92c47b9e5f6e19852248734b369cbba90b73c5e99e746470 +316000 00000000000000000d77a89ab1069e47d1213ae509de95ee0d9ab095a725f7d7 7afd93faff66fc592596cb8bc2eee09e0a0f3e7f594b9655953b24922d3bb75d +318000 00000000000000002583a647dc5f084a312e12bb90a70c3fe1eb1e4d419f35b6 498e6e0c39a2b4e3e112d0f79db25bfa7b482df8826a817e893738f9393b19c2 +320000 000000000000000015aab005b28a326ade60f07515c33517ea5cb598f28fb7ea c4e88ac94f5537333d613291ce13a4161d96533fba812ba61748b95d02095695 +322000 0000000000000000177da809382f93ca1c4336811e4a910050689d317d62264e 5acfc8fe0a05892c2c92f047ba55547f125245877c2d12c6aff9f1d74a60e088 +324000 00000000000000000b9880c40075d763b2a5f04fc01444a6278c5d2d442cda0b ab36c74346782a0047a2276e588492a5609d3fd7fc4f2a26645c70166db0f124 +326000 00000000000000001e95e7216072cd53353b964054b592f7ce84d3743aab125a 61a2e1cba22bc04a885f62544518c46f0eb4e7a39668028d67ff48b2aadb9b7b +328000 000000000000000009cb9a303d105e7b96b36546a3196f6f79ece4b43712cbb2 3a7260ef08d756e217dbac41123a2d9c29e9449ceeed9690c4f67bc9f891011f +330000 00000000000000000faabab19f17c0178c754dbed023e6c871dcaf74159c5f02 3f57d68b53b69e52e5d284e7566c2d0575c4bafb08e7de1cc0f9defbab5d78e6 +332000 00000000000000001799255bc0c35f91f7d4fddfbf7e84dedf94fc59cde9b7f2 d833c527d933a4443bd9776ecf69d12f386cbe74d025812cb0eee5582098c962 +334000 000000000000000008d1ff7b7673837e9d7e1324dc7ab8498405ea583f43f53d d28c040b4daea020a13a9720212ee698905b106bb985b46fa7fe3aaa3a45586c +336000 0000000000000000125e3e6f327edcd7163b486efc16e79b8a996270127b54df 204e1ee93f97f61493e1de727c872cbfc11b7c51c42aca4f78e49ead1fffa7ad +338000 00000000000000001983dc4a87df627b63cdce28e5321cb867fbbb74c0e87e8e a10621d27b01bd6be869a6972b56505b2833076c33b04e8b5722e09b35091de1 +340000 00000000000000000d9b2508615d569e18f00c034d71474fc44a43af8d4a5003 3925a6d41b5ba3ee2bb450f109e6e0741fd3e21776ca9d1fd78ac3ae721e24a5 +342000 0000000000000000007220892af98a563a1c891c756e94be3f14edddcf637c3e d4406c4644692a1e617b7e140714bfac57b4d5c1da5efcbabcf8867675cb7d07 +344000 000000000000000005f0a16f5a9f95eeb95c5eed0eb221e8f5dc5a9943a03aee 0b62e591128428eb437643cc5047e000149f30003ee8c7e1ce4cf57faf6d713f +346000 0000000000000000068d33fd865621cb7eedbf05c6b235191fa1cb8ee2c797d7 9b868fb539094f9e9185fe1d7683f0d6712247a64ffea660ac384ab6abead41c +348000 00000000000000001598a651988bb3a45237c4f801cf8049be20f74aed8e827a f88007d47bcb3ce6f2940440ec98237963376db32cb7cb7ab5d68b40717f3b27 +350000 0000000000000000053cf64f0400bb38e0c4b3872c38795ddde27acb40a112bb e59c9c36cc8fe49a7fc817551bec3eaebda6a5a21f337dc1f77fddeaf1c4c7a4 +352000 00000000000000001635a4b5f27d2ec458f7bca550d71f490b93e98e7a07cbca c191dbe07764711eff7795883414db7d14381de453776edfb75abd6f3e7bb013 +354000 00000000000000000cf8af9be2709e9d7adf2c33b3789aeeff517987f4be22e8 4b1e12b9f948003447d072f31f0531794e578d918f024580fbbb52f29d412463 +356000 0000000000000000138ce5493b612b0e90b66e2a76714088d6b3e6a4770215af dd4d81753ecf9b2ea599ede6307c8b4e0f7eea8dd9c677887d16c980270d13b9 +358000 0000000000000000073aceefab8c381c3c4edb4f87a6d5d2ae32184278218429 9167ed0d73ec659f60b8b526b66078ec5c2eb263b7957a2bc1d16c36566d749c +360000 00000000000000000ca6e07cf681390ff888b7f96790286a440da0f2b87c8ea6 64d55132d7d41efd3c82522714f8ffc48d16b97ef1319de1b773d8e683ac70d1 +362000 00000000000000000bfcad6c331dd152cfc713e9e0790978a10e0bfda3e030d5 18a58a96470360af27c405f7aa63392676e77b723f524186926bf72b649c7070 +364000 00000000000000000e20bcf213a0bbd6be88d5fede6b060c737f7f8b7f1df504 09ec4fe62e9741db9583a5c93ea9b19663c84d0c97f34407e2e5905eac6fadd5 +366000 0000000000000000138e108e780fdb71eb4cad533b46445ab6befbf9687f561f 02440f43691a61e3b6748396acab0cd04d6e2f7c52da764bb5ab8ff2f5b52551 +368000 00000000000000000d39970aac12754eb89c2dcfda539b65562e5c3fec102c24 6ef2048848f4ba32f43a8c9ae7c96ad44dac0cfb96344434acc96afcd57dbb3b +370000 000000000000000002cad3026f68357229dd6eaa6bcef6fe5166e1e53b039b8c 64bf9a93317f4241810ad1fd317b3353941c4c1d45e393485681b817204bcf23 +372000 0000000000000000028093cc8035a6bc4e0d1b40932c2f8b50312a3fc86bf3da 1667a87afc743f41a0731091f2762b73d82cd28244fac555cf26623ee0922543 +374000 00000000000000001016aa3783721673bebbcd1efa49946b52cceb09a81465a6 083a4b6e7c05729940cbc80f545dc03eb45ad8c1b9990cbccbb80788835ded3a +376000 0000000000000000106e9e99cf4fce4e8a4abc97f3e883956e26d76b3a1133ce 1d5cccf38607557a1f0529cc6e1e447a6c179e1dbb9312f4fb8e6e75c11fb434 +378000 00000000000000000516cd5b5f4b7e528d6e61c643595cc818f1d02f53da4281 a6816997bbb1524ad10392a1749a2ff4dbcfde9a54ce6e7a5eb020d33c0421be +380000 00000000000000000b06cee3cee10d2617e2024a996f5c613f7d786b15a571ff 6e6daa40b94422f281dbe453dbb9a66607593d5255dcd89ac17da7126a0719e4 +382000 000000000000000003cf98590769bde40ffcd6800733ab47dd406d8203e65a89 dd7ef79f7cc85f27f2fc778e458e42669b1a0edc6fda9de066b75ab72859dc13 +384000 000000000000000005dc7ea53e2f6eeb09798cc9d2214f09d249661c36c288b3 e58fa7e82c9b78bc96e506097a62546f80a8714575eed182322b5dadc08fdb48 +386000 00000000000000000d94c8c0b0ddec874d2a597e988154733d9ea614292c08bb 1744bde331acb42ff7fa8dc19cbfd8fa82272905fa9f7be058701cf2dc494bec +388000 000000000000000003c5e9f4f84dc78b5ca96b7f2d89e9063b5f74543b42b9d5 5265b61950210ab7c9680de11d7be5bb02d3b5d3be97af2627c0cc0308104927 +390000 00000000000000000520000e60b56818523479ada2614806ba17ce0bbe6eaded 46bab737096a1e1bf800d9a0429688c8e676f3a480c850b3a5622bf580366703 +392000 00000000000000000850dc9d4a9a8d45d618d8f0dcbbdcc8a6fa88a6a90dfe1c 21d7a6c6c4b6e3c389c9d0046512b348d1f2246b8d9d5004bc1244cafd7d066a +394000 000000000000000009ae6157a480e351cdeb8be494362a3bf3cd1c4feedf8ad6 e871c05b4794191df935d8a585fbabba5cb981ff5936d49a1078aa8ad925802f +396000 0000000000000000079226c668cd1db713fb78ffc127b422e12b47baf205b478 f9542a8a8185328b82984691a41509cf245d008d875d158e6d770b703c08b5fa +398000 000000000000000001c6bd9d2dbccc3f16ddb534119de0aeb7d0a8c87f78e001 e73b9cb5fb81415bbe18e2601f261aeb8fe843d53ecf708219da5bfe096df418 diff --git a/confs/BTC_peers.txt b/confs/BTC_peers.txt old mode 100644 new mode 100755 index abb52b839..953707877 --- a/confs/BTC_peers.txt +++ b/confs/BTC_peers.txt @@ -1,137 +1,84 @@ -108.58.252.82 -74.207.233.193 -130.211.146.81 -71.193.19.234 -173.66.1.180 -104.158.113.201 -108.207.245.69 -107.4.134.66 -96.231.100.124 -209.6.208.31 -69.141.89.74 -82.20.129.167 -5.9.222.226 -149.210.234.41 -168.235.85.242 -52.91.247.30 -191.237.64.28 -173.236.101.34 -73.189.2.240 -106.186.113.184 -173.64.13.6 -73.166.27.56 -70.106.255.189 -168.62.188.213 -71.234.225.255 -24.41.10.204 -72.175.146.90 -184.107.155.82 -162.220.47.150 -12.23.127.150 -169.228.66.43 -192.227.137.5 -71.205.232.181 -207.182.151.130 -46.4.22.45 -198.50.238.171 -174.59.182.120 -66.172.10.4 -75.73.82.209 -91.121.108.61 -24.6.74.4 -37.187.78.27 -96.32.46.235 -107.170.13.184 +148.251.238.178 +176.9.137.66 148.251.151.48 -178.62.70.16 144.76.185.151 -144.76.92.199 -91.121.210.159 -76.105.242.7 -54.84.231.113 -89.187.134.220 -64.15.77.36 -212.51.147.153 -216.15.33.203 -74.100.90.30 -185.18.6.3 -104.131.65.197 -89.248.174.54 -128.8.124.7 -54.232.245.146 -67.205.101.120 -72.207.119.149 -192.95.27.144 -69.61.93.240 -209.91.190.202 -50.35.82.152 -66.175.220.212 -23.239.22.219 -73.229.104.201 -207.244.73.8 -78.129.251.170 +144.76.108.6 +144.76.108.6 +52.29.215.16 +178.254.31.223:8333 139.162.211.181 -172.245.5.156 -98.144.123.251 -177.238.90.180 -198.71.92.236 -73.254.38.48 -75.189.201.141 -52.24.104.64 -71.231.209.66 -87.224.35.189 -73.162.143.196 -82.204.103.94 -91.148.210.17 -94.242.229.158 +37.1.207.72 +193.111.141.197 +139.162.211.181 +178.254.29.171 +46.101.85.163 +109.206.177.21 +86.86.139.48 +46.244.0.138 +94.23.252.166 188.121.252.243 -70.39.8.97 -95.97.112.190 -109.228.152.9 -91.209.77.101 -217.76.121.251 +85.144.162.100 +94.242.229.158 +104.155.8.102 +5.135.182.69 +178.62.86.100 +162.220.246.101 +46.59.61.234 +62.210.204.29 +87.72.198.28 +188.24.61.132:8333 +52.18.56.236 +91.121.108.61 +50.116.59.118 +194.135.92.96 +2.30.150.229 +66.175.220.212 +45.79.97.30 +185.25.113.68:8333 79.136.29.43 -178.212.136.92 -178.255.41.123 -84.212.200.24 +185.86.151.145 +109.120.250.3 91.145.49.56 -162.220.246.101 -95.167.109.125 -153.163.32.61 -78.67.29.111 -92.247.229.163 -210.195.201.103 -95.84.162.95 -106.38.234.67 -186.88.0.18 -121.208.106.80 -120.55.193.136 -124.171.128.201 -54.94.163.92 -98.217.125.225 -104.156.97.121 -162.255.117.230 -129.13.252.36 -79.120.12.63 -108.5.176.30 -69.144.244.229 -76.22.18.34 -115.29.186.22 -78.46.193.75 +77.110.11.176:8333 +74.207.233.193 +169.53.178.155 +23.94.65.207 +52.11.33.24 +107.170.13.184 +198.27.67.36 213.91.211.17 -164.177.179.162 -134.249.141.40 -69.140.88.12 -178.212.136.108 -109.120.250.3 -154.127.61.55 -123.120.167.101 -73.210.74.120 -82.136.95.220 -124.122.212.150 -81.191.80.160 -96.58.196.51 -77.23.111.25 -14.175.245.51 -76.164.234.12 -92.156.214.192 +98.200.151.87 +75.177.137.134 +192.99.223.253 +82.221.106.17 +54.94.211.146 +70.75.20.127 +23.108.83.12 +52.74.14.245 +52.192.180.114 +68.173.30.2 +108.24.76.250 +95.85.24.244:6002 +107.167.180.31 +37.187.132.223 +94.174.169.213 +208.88.126.226 +83.142.160.14:8333 +74.72.60.83 +207.226.141.129 +71.62.31.72 +52.32.80.148 +104.171.115.168 +104.171.115.168 +114.158.145.163 +58.96.171.129 +75.118.144.161 +198.15.127.242:8333 +24.87.52.186 +192.124.224.7 +58.178.198.147:8333 +52.62.33.159 +2.221.62.207:8333 +108.227.234.117:8333 +222.152.161.43:8333 +54.223.101.145 diff --git a/crypto777/Makefile b/crypto777/Makefile old mode 100644 new mode 100755 diff --git a/crypto777/OS_portable.c b/crypto777/OS_portable.c index 41496bc0e..38bfed58b 100755 --- a/crypto777/OS_portable.c +++ b/crypto777/OS_portable.c @@ -109,6 +109,43 @@ int32_t OS_portable_removefile(char *fname) #else return(remove(fname)); #endif + return(-1); +} + +int32_t OS_portable_rmdir(char *dirname,int32_t diralso) +{ + char cmdstr[1024],tmp[512]; int32_t i; + strcpy(tmp,dirname); + OS_portable_path(tmp); +#ifdef _WIN32 + sprintf(cmdstr,"del %s\*.*",tmp); + if ( system(cmdstr) != 0 ) + printf("error deleting dir.(%s)\n",cmdstr); + else return(1); +#else + if ( diralso != 0 ) + { + sprintf(cmdstr,"rm -rf %s",tmp); + if ( system(cmdstr) != 0 ) + printf("error deleting dir.(%s)\n",cmdstr); + sprintf(cmdstr,"mkdir %s",tmp); + if ( system(cmdstr) != 0 ) + printf("error deleting dir.(%s)\n",cmdstr); + } + else + { + for (i=0; i<=16; i++) + { + if ( i < 16 ) + sprintf(cmdstr,"rm %s/%c*",tmp,i<10?'0'+i:'a'-10+i); + else sprintf(cmdstr,"rm %s/*",tmp); + if ( system(cmdstr) != 0 ) + printf("error deleting dir.(%s)\n",cmdstr); + } + } + return(0); +#endif + return(-1); } void *OS_portable_mapfile(char *fname,long *filesizep,int32_t enablewrite) diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index c4442eefd..2a23a19cb 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -360,6 +360,7 @@ bits256 bits256_from_compact(uint32_t c); bits256 bits256_conv(char *hexstr); int32_t btc_priv2pub(uint8_t pubkey[33],uint8_t privkey[32]); void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs); +int32_t OS_portable_rmdir(char *dirname,int32_t diralso); extern char *Iguana_validcommands[]; extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY; diff --git a/crypto777/crypto777.sources b/crypto777/crypto777.sources old mode 100644 new mode 100755 diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index 438ba3386..e2ec357d2 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -248,8 +248,8 @@ void *queue_dequeue(queue_t *queue,int32_t offsetflag) if ( queue->list != 0 ) { item = queue->list; - DL_DELETE(queue->list,item); //printf("queue_dequeue name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list); + DL_DELETE(queue->list,item); } portable_mutex_unlock(&queue->mutex); if ( item != 0 && offsetflag != 0 ) @@ -434,7 +434,12 @@ void *iguana_memalloc(struct OS_memspace *mem,long size,int32_t clearflag) } #endif //printf(">>>>>>>>> USED.%s alloc %ld used %ld alloc.%ld -> %s %p\n",mem->name,size,(long)mem->used,(long)mem->totalsize,mem->name,ptr); - } else printf("error memalloc mem.%p %s alloc %ld used %ld totalsize.%ld -> %s %p\n",mem,mem->name,size,(long)mem->used,(long)mem->totalsize,mem->name,ptr), getchar();//exit(-1); + } + else + { + printf("error memalloc mem.%p (%s) alloc %ld used %ld totalsize.%ld -> %s %p\n",mem,mem->name,size,(long)mem->used,(long)mem->totalsize,mem->name,ptr); + ptr = calloc(1,size); + } //if ( mem->threadsafe != 0 ) // portable_mutex_unlock(&mem->mutex); return(ptr); @@ -515,7 +520,7 @@ int32_t OS_removefile(char *fname,int32_t scrubflag) void OS_ensure_directory(char *dirname) { FILE *fp; int32_t retval; char fname[512]; - if ( OS_removefile(dirname,0) < 0 ) + if ( 0 && OS_removefile(dirname,0) < 0 ) { sprintf(fname,"tmp/%d",rand()); OS_renamefile(dirname,fname); @@ -530,12 +535,12 @@ void OS_ensure_directory(char *dirname) ,511 #endif ); - printf("mkdir.(%s) retval.%d errno.%d %s\n",dirname,retval,errno,strerror(errno)); - } else fclose(fp), printf("dirname.(%s) exists\n",dirname); + //printf("mkdir.(%s) retval.%d errno.%d %s\n",dirname,retval,errno,strerror(errno)); + } else fclose(fp);//, printf("dirname.(%s) exists\n",dirname); if ( (fp= fopen(fname,"wb")) != 0 ) - fclose(fp), printf("created.(%s)\n",fname); + fclose(fp);//, printf("created.(%s)\n",fname); else printf("cant create.(%s) errno.%d %s\n",fname,errno,strerror(errno)); - } else fclose(fp), printf("%s exists\n",fname); + } else fclose(fp);//, printf("%s exists\n",fname); } uint64_t OS_filesize(char *fname) diff --git a/crypto777/iguana_serdes.c b/crypto777/iguana_serdes.c index 03a9c8e09..9d0bbec5f 100755 --- a/crypto777/iguana_serdes.c +++ b/crypto777/iguana_serdes.c @@ -170,19 +170,19 @@ int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p) n = *varint64p; if ( n < 0xfd ) *serialized++ = (uint8_t)n; - else if ( n == 0xfd ) + else if ( n <= 0xffff ) { *serialized++ = 0xfd; iguana_varint16(rwflag,serialized,(uint16_t *)varint64p); vlen += 2; } - else if ( n == 0xfe ) + else if ( n <= 0xffffffff ) { *serialized++ = 0xfe; iguana_varint32(rwflag,serialized,(uint16_t *)varint64p); vlen += 4; } - else if ( n == 0xff ) + else { *serialized++ = 0xff; iguana_varint64(rwflag,serialized,(uint32_t *)varint64p); diff --git a/crypto777/inet.c b/crypto777/inet.c index 7c06827a7..2057f90d3 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -225,13 +225,13 @@ static int inet_pton4(char *src, unsigned char *dst) { saw_digit = 0; } else { - printf("inet_pton4 4 error.(%s)\n",savestr); getchar(); + printf("inet_pton4 4 error.(%s)\n",savestr); //getchar(); return EINVAL; } } if (octets < 4) { - printf("inet_pton4 5 error.(%s)\n",savestr); getchar(); + printf("inet_pton4 5 error.(%s)\n",savestr); //getchar(); return EINVAL; } memcpy(dst, tmp, sizeof(struct in_addr)); diff --git a/crypto777/jpeg/Makefile b/crypto777/jpeg/Makefile old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/cderror.h b/crypto777/jpeg/cderror.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/cdjpeg.h b/crypto777/jpeg/cdjpeg.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jaricom.c b/crypto777/jpeg/jaricom.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcapimin.c b/crypto777/jpeg/jcapimin.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcapistd.c b/crypto777/jpeg/jcapistd.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcarith.c b/crypto777/jpeg/jcarith.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jccoefct.c b/crypto777/jpeg/jccoefct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jccolor.c b/crypto777/jpeg/jccolor.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcdctmgr.c b/crypto777/jpeg/jcdctmgr.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jchuff.c b/crypto777/jpeg/jchuff.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcinit.c b/crypto777/jpeg/jcinit.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcmainct.c b/crypto777/jpeg/jcmainct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcmarker.c b/crypto777/jpeg/jcmarker.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcmaster.c b/crypto777/jpeg/jcmaster.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcomapi.c b/crypto777/jpeg/jcomapi.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jconfig.h b/crypto777/jpeg/jconfig.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcparam.c b/crypto777/jpeg/jcparam.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcprepct.c b/crypto777/jpeg/jcprepct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jcsample.c b/crypto777/jpeg/jcsample.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jctrans.c b/crypto777/jpeg/jctrans.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdapimin.c b/crypto777/jpeg/jdapimin.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdapistd.c b/crypto777/jpeg/jdapistd.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdarith.c b/crypto777/jpeg/jdarith.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdatadst.c b/crypto777/jpeg/jdatadst.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdatasrc.c b/crypto777/jpeg/jdatasrc.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdcoefct.c b/crypto777/jpeg/jdcoefct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdcolor.c b/crypto777/jpeg/jdcolor.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdct.h b/crypto777/jpeg/jdct.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jddctmgr.c b/crypto777/jpeg/jddctmgr.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdhuff.c b/crypto777/jpeg/jdhuff.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdinput.c b/crypto777/jpeg/jdinput.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdmainct.c b/crypto777/jpeg/jdmainct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdmarker.c b/crypto777/jpeg/jdmarker.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdmaster.c b/crypto777/jpeg/jdmaster.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdmerge.c b/crypto777/jpeg/jdmerge.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdpostct.c b/crypto777/jpeg/jdpostct.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdsample.c b/crypto777/jpeg/jdsample.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jdtrans.c b/crypto777/jpeg/jdtrans.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jerror.c b/crypto777/jpeg/jerror.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jerror.h b/crypto777/jpeg/jerror.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jfdctflt.c b/crypto777/jpeg/jfdctflt.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jfdctfst.c b/crypto777/jpeg/jfdctfst.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jfdctint.c b/crypto777/jpeg/jfdctint.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jidctflt.c b/crypto777/jpeg/jidctflt.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jidctfst.c b/crypto777/jpeg/jidctfst.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jidctint.c b/crypto777/jpeg/jidctint.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jinclude.h b/crypto777/jpeg/jinclude.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmemansi.c b/crypto777/jpeg/jmemansi.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmemmgr.c b/crypto777/jpeg/jmemmgr.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmemnobs.c b/crypto777/jpeg/jmemnobs.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmemsys.h b/crypto777/jpeg/jmemsys.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jmorecfg.h b/crypto777/jpeg/jmorecfg.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jpegint.h b/crypto777/jpeg/jpegint.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jpeglib.h b/crypto777/jpeg/jpeglib.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jpegtran.c b/crypto777/jpeg/jpegtran.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jquant1.c b/crypto777/jpeg/jquant1.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jquant2.c b/crypto777/jpeg/jquant2.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jutils.c b/crypto777/jpeg/jutils.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/jversion.h b/crypto777/jpeg/jversion.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/ansi2knr.c b/crypto777/jpeg/misc/ansi2knr.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/cdjpeg.c b/crypto777/jpeg/misc/cdjpeg.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/cjpeg.c b/crypto777/jpeg/misc/cjpeg.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/ckconfig.c b/crypto777/jpeg/misc/ckconfig.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/djpeg.c b/crypto777/jpeg/misc/djpeg.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/example.c b/crypto777/jpeg/misc/example.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdbmp.c b/crypto777/jpeg/misc/rdbmp.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdcolmap.c b/crypto777/jpeg/misc/rdcolmap.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdgif.c b/crypto777/jpeg/misc/rdgif.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdjpgcom.c b/crypto777/jpeg/misc/rdjpgcom.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdppm.c b/crypto777/jpeg/misc/rdppm.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdrle.c b/crypto777/jpeg/misc/rdrle.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdswitch.c b/crypto777/jpeg/misc/rdswitch.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/rdtarga.c b/crypto777/jpeg/misc/rdtarga.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/test.c b/crypto777/jpeg/misc/test.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/transupp.c b/crypto777/jpeg/misc/transupp.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrbmp.c b/crypto777/jpeg/misc/wrbmp.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrgif.c b/crypto777/jpeg/misc/wrgif.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrjpgcom.c b/crypto777/jpeg/misc/wrjpgcom.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrppm.c b/crypto777/jpeg/misc/wrppm.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrrle.c b/crypto777/jpeg/misc/wrrle.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/misc/wrtarga.c b/crypto777/jpeg/misc/wrtarga.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/osx/jmemmac.c b/crypto777/jpeg/osx/jmemmac.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/transupp.h b/crypto777/jpeg/transupp.h old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/unix/jmemname.c b/crypto777/jpeg/unix/jmemname.c old mode 100644 new mode 100755 diff --git a/crypto777/jpeg/win/jmemdos.c b/crypto777/jpeg/win/jmemdos.c old mode 100644 new mode 100755 diff --git a/crypto777/m_ios b/crypto777/m_ios index c579b9661..6afeef994 100755 --- a/crypto777/m_ios +++ b/crypto777/m_ios @@ -1,5 +1,8 @@ + CC="$(xcrun --sdk iphoneos --find clang) -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -arch armv7 -arch arm64 -arch armv7s -ONLY_ACTIVE_ARCH=YES" -AR="$(xcrun --sdk iphones --find ar)" +AR="$(xcrun --sdk iphoneos --find ar)" + +echo Compiling .. -$CC -c -O2 *.c jpeg/*.c jpeg/unix/*.c +$CC -I /usr/local/opt/curl/include/ -c -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/local/opt/ rm -f ../agents/libcrypto777.a; $AR -rcs ../agents/libcrypto777.a *.o diff --git a/crypto777/nanosrc/aio/usock_posix.c b/crypto777/nanosrc/aio/usock_posix.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/README b/crypto777/nanosrc/tests/README old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/block.c b/crypto777/nanosrc/tests/block.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/bus.c b/crypto777/nanosrc/tests/bus.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/cmsg.c b/crypto777/nanosrc/tests/cmsg.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/device.c b/crypto777/nanosrc/tests/device.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/domain.c b/crypto777/nanosrc/tests/domain.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/emfile.c b/crypto777/nanosrc/tests/emfile.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/hash.c b/crypto777/nanosrc/tests/hash.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/inproc.c b/crypto777/nanosrc/tests/inproc.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/inproc_shutdown.c b/crypto777/nanosrc/tests/inproc_shutdown.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/iovec.c b/crypto777/nanosrc/tests/iovec.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/ipc.c b/crypto777/nanosrc/tests/ipc.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/ipc_shutdown.c b/crypto777/nanosrc/tests/ipc_shutdown.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/ipc_stress.c b/crypto777/nanosrc/tests/ipc_stress.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/list.c b/crypto777/nanosrc/tests/list.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/msg.c b/crypto777/nanosrc/tests/msg.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/pair.c b/crypto777/nanosrc/tests/pair.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/pipeline.c b/crypto777/nanosrc/tests/pipeline.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/poll.c b/crypto777/nanosrc/tests/poll.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/prio.c b/crypto777/nanosrc/tests/prio.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/pubsub.c b/crypto777/nanosrc/tests/pubsub.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/reqrep.c b/crypto777/nanosrc/tests/reqrep.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/separation.c b/crypto777/nanosrc/tests/separation.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/shutdown.c b/crypto777/nanosrc/tests/shutdown.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/survey.c b/crypto777/nanosrc/tests/survey.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/symbol.c b/crypto777/nanosrc/tests/symbol.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/tcp.c b/crypto777/nanosrc/tests/tcp.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/tcp_shutdown.c b/crypto777/nanosrc/tests/tcp_shutdown.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/tcpmux.c b/crypto777/nanosrc/tests/tcpmux.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/term.c b/crypto777/nanosrc/tests/term.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/testutil.h b/crypto777/nanosrc/tests/testutil.h old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/timeo.c b/crypto777/nanosrc/tests/timeo.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/trie.c b/crypto777/nanosrc/tests/trie.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/ws.c b/crypto777/nanosrc/tests/ws.c old mode 100644 new mode 100755 diff --git a/crypto777/nanosrc/tests/zerocopy.c b/crypto777/nanosrc/tests/zerocopy.c old mode 100644 new mode 100755 diff --git a/crypto777/pnacl_libs/libcrypto.a b/crypto777/pnacl_libs/libcrypto.a old mode 100644 new mode 100755 diff --git a/crypto777/pnacl_libs/libcurl.a b/crypto777/pnacl_libs/libcurl.a old mode 100644 new mode 100755 diff --git a/crypto777/pnacl_libs/libnanomsg.a b/crypto777/pnacl_libs/libnanomsg.a old mode 100644 new mode 100755 diff --git a/crypto777/pnacl_libs/libssl.a b/crypto777/pnacl_libs/libssl.a old mode 100644 new mode 100755 diff --git a/crypto777/pnacl_libs/libz.a b/crypto777/pnacl_libs/libz.a old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/NativeSecp256k1.java b/crypto777/secp256k1/NativeSecp256k1.java old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/basic-config.h b/crypto777/secp256k1/basic-config.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/bench.h b/crypto777/secp256k1/bench.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/bench_ecdh.c b/crypto777/secp256k1/bench_ecdh.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/bench_internal.c b/crypto777/secp256k1/bench_internal.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/bench_rangeproof.c b/crypto777/secp256k1/bench_rangeproof.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/bench_recover.c b/crypto777/secp256k1/bench_recover.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/bench_schnorr_verify.c b/crypto777/secp256k1/bench_schnorr_verify.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/bench_sign.c b/crypto777/secp256k1/bench_sign.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/bench_verify.c b/crypto777/secp256k1/bench_verify.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/ecdsa.h b/crypto777/secp256k1/ecdsa.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/ecdsa_impl.h b/crypto777/secp256k1/ecdsa_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/eckey.h b/crypto777/secp256k1/eckey.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/eckey_impl.h b/crypto777/secp256k1/eckey_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/ecmult.h b/crypto777/secp256k1/ecmult.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/ecmult_const.h b/crypto777/secp256k1/ecmult_const.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/ecmult_const_impl.h b/crypto777/secp256k1/ecmult_const_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/ecmult_gen.h b/crypto777/secp256k1/ecmult_gen.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/ecmult_gen_impl.h b/crypto777/secp256k1/ecmult_gen_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/ecmult_impl.h b/crypto777/secp256k1/ecmult_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/field.h b/crypto777/secp256k1/field.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/field_10x26.h b/crypto777/secp256k1/field_10x26.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/field_10x26_impl.h b/crypto777/secp256k1/field_10x26_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/field_5x52.h b/crypto777/secp256k1/field_5x52.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/field_5x52_asm_impl.h b/crypto777/secp256k1/field_5x52_asm_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/field_5x52_impl.h b/crypto777/secp256k1/field_5x52_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/field_5x52_int128_impl.h b/crypto777/secp256k1/field_5x52_int128_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/field_impl.h b/crypto777/secp256k1/field_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/gen_context.c b/crypto777/secp256k1/gen_context.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/group.h b/crypto777/secp256k1/group.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/group_impl.h b/crypto777/secp256k1/group_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/hash.h b/crypto777/secp256k1/hash.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/hash_impl.h b/crypto777/secp256k1/hash_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/libsecp256k1-config.h b/crypto777/secp256k1/libsecp256k1-config.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/ecdh/Makefile.am.include b/crypto777/secp256k1/modules/ecdh/Makefile.am.include old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/ecdh/main_impl.h b/crypto777/secp256k1/modules/ecdh/main_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/ecdh/tests_impl.h b/crypto777/secp256k1/modules/ecdh/tests_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/Makefile.am.include b/crypto777/secp256k1/modules/rangeproof/Makefile.am.include old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/borromean.h b/crypto777/secp256k1/modules/rangeproof/borromean.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/borromean_impl.h b/crypto777/secp256k1/modules/rangeproof/borromean_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/main_impl.h b/crypto777/secp256k1/modules/rangeproof/main_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/pedersen.h b/crypto777/secp256k1/modules/rangeproof/pedersen.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/pedersen_impl.h b/crypto777/secp256k1/modules/rangeproof/pedersen_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/rangeproof.h b/crypto777/secp256k1/modules/rangeproof/rangeproof.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/rangeproof_impl.h b/crypto777/secp256k1/modules/rangeproof/rangeproof_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/rangeproof/tests_impl.h b/crypto777/secp256k1/modules/rangeproof/tests_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/schnorr/Makefile.am.include b/crypto777/secp256k1/modules/schnorr/Makefile.am.include old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/schnorr/main_impl.h b/crypto777/secp256k1/modules/schnorr/main_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/schnorr/schnorr.h b/crypto777/secp256k1/modules/schnorr/schnorr.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/schnorr/schnorr_impl.h b/crypto777/secp256k1/modules/schnorr/schnorr_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/modules/schnorr/tests_impl.h b/crypto777/secp256k1/modules/schnorr/tests_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/num.h b/crypto777/secp256k1/num.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/num_gmp.h b/crypto777/secp256k1/num_gmp.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/num_gmp_impl.h b/crypto777/secp256k1/num_gmp_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/num_impl.h b/crypto777/secp256k1/num_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/org_bitcoin_NativeSecp256k1.c b/crypto777/secp256k1/org_bitcoin_NativeSecp256k1.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/org_bitcoin_NativeSecp256k1.h b/crypto777/secp256k1/org_bitcoin_NativeSecp256k1.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/scalar.h b/crypto777/secp256k1/scalar.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/scalar_4x64.h b/crypto777/secp256k1/scalar_4x64.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/scalar_4x64_impl.h b/crypto777/secp256k1/scalar_4x64_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/scalar_8x32.h b/crypto777/secp256k1/scalar_8x32.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/scalar_8x32_impl.h b/crypto777/secp256k1/scalar_8x32_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/scalar_impl.h b/crypto777/secp256k1/scalar_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/secp256k1.c b/crypto777/secp256k1/secp256k1.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/secp256k1.h b/crypto777/secp256k1/secp256k1.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/secp256k1_ecdh.h b/crypto777/secp256k1/secp256k1_ecdh.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/secp256k1_rangeproof.h b/crypto777/secp256k1/secp256k1_rangeproof.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/secp256k1_schnorr.h b/crypto777/secp256k1/secp256k1_schnorr.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/testrand.h b/crypto777/secp256k1/testrand.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/testrand_impl.h b/crypto777/secp256k1/testrand_impl.h old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/tests.c b/crypto777/secp256k1/tests.c old mode 100644 new mode 100755 diff --git a/crypto777/secp256k1/util.h b/crypto777/secp256k1/util.h old mode 100644 new mode 100755 diff --git a/crypto777/tools/chrome.localhost.bat b/crypto777/tools/chrome.localhost.bat old mode 100644 new mode 100755 diff --git a/crypto777/tools/common.mk b/crypto777/tools/common.mk old mode 100644 new mode 100755 diff --git a/crypto777/tools/run.bat b/crypto777/tools/run.bat old mode 100644 new mode 100755 diff --git a/deprecated/Makefile b/deprecated/Makefile old mode 100644 new mode 100755 diff --git a/deprecated/SuperNET.c b/deprecated/SuperNET.c old mode 100644 new mode 100755 diff --git a/deprecated/SuperNET2.c b/deprecated/SuperNET2.c old mode 100644 new mode 100755 diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h old mode 100644 new mode 100755 index 42938968c..043561e08 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -8440,48 +8440,7 @@ void iguana_dedicatedrecv(void *arg) } return(0); } - - struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundleip,char *fname,struct iguana_memspace *mem,uint32_t ipbits,bits256 hash2) - { - int32_t bundlei,datalen,checki,hdrsi,fpos; char str[65],str2[65]; FILE *fp; - bits256 checkhash2; struct iguana_txblock *txdata = 0; - if ( (bundlei= iguana_peerfname(coin,&hdrsi,fname,ipbits,hash2)) >= 0 ) - { - if ( (fp= fopen(fname,"rb")) != 0 ) - { - fseek(fp,bundlei * sizeof(bundlei),SEEK_SET); - fread(&fpos,1,sizeof(fpos),fp); - fseek(fp,fpos,SEEK_SET); - fread(&checki,1,sizeof(checki),fp); - if ( ftell(fp)-sizeof(checki) == fpos && bundlei == checki ) - { - fread(&checkhash2,1,sizeof(checkhash2),fp); - if ( memcmp(hash2.bytes,checkhash2.bytes,sizeof(hash2)) == 0 ) - { - fread(&datalen,1,sizeof(datalen),fp); - if ( datalen < (mem->totalsize - mem->used - 4) ) - { - if ( (txdata= iguana_memalloc(mem,datalen,0)) != 0 ) - { - fread(txdata,1,datalen,fp); - if ( txdata->datalen != datalen || txdata->block.bundlei != bundlei ) - { - printf("%s peertxdata txdata->datalen.%d != %d bundlei.%d vs %d\n",bits256_str(str,txdata->block.hash2),txdata->datalen,datalen,txdata->block.bundlei,bundlei); - getchar(); - txdata = 0; - iguana_memreset(mem); - } //else printf("SUCCESS txdata.%s bundlei.%d fpos.%d T.%d U.%d S.%d P.%d\n",bits256_str(str,txdata->block.hash2),bundlei,fpos,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds); - } else printf("peertxdata error allocating txdata\n"); - } else printf("mismatch peertxdata datalen %d vs %ld totalsize %ld\n",datalen,mem->totalsize - mem->used - 4,(long)mem->totalsize); - } else printf("peertxdata hash mismatch %s != %s\n",bits256_str(str,hash2),bits256_str(str2,checkhash2)); - } else printf("peertxdata bundlei.%d != checki.%d, fpos.%d ftell.%ld\n",bundlei,checki,fpos,ftell(fp)); - fclose(fp); - } else printf("cant find file.(%s)\n",fname); - } //else printf("bundlei.%d\n",bundlei); - *bundleip = bundlei; - return(txdata); - } - + /*if ( (n= ramchain->data->numtxids) > 0 ) { for (ramchain->txidind=ramchain->data->firsti; ramchain->txidindtxidind++) @@ -13721,5 +13680,720 @@ len = 0; else printf("BTCSWAP.(%s)\n",retstr); return(retstr); #endif + else if ( strcmp(cmdstr,"BTCdeckC") == 0 ) + { + if ( ap->info == 0 ) + { + printf("A (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap); + return(clonestr("{\"error\":\"no swap for orderid\"}")); + } + else + { + if ( ap->otherorderid == 0 ) + { + ap->otherorderid = ap->orderid; + ap->otheroffer = ap->offer; + ap->offer = A.offer; + ap->orderid = A.orderid; + ((struct bitcoin_swapinfo *)ap->info)->feetag64 = ap->orderid; + } + printf("add to statemachine\n"); + queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0); + newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0); + if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,ap->info,"BOB_sentoffer","ALICE_sentoffer")) == 0 ) + { + return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen)); + } else return(clonestr("{\"error\":\"couldnt add fee\"}")); + } + /* + for (iter=0; iter<2; iter++) + { + while ( (m= category_gethexmsg(myinfo,instantdexhash,iter == 0 ? GENESIS_PUBKEY : myinfo->myaddr.persistent)) != 0 ) + { + //printf("gothexmsg len.%d\n",m->len); + pm = (struct instantdex_msghdr *)m->msg; + if ( m->remoteipbits != 0 ) + expand_ipbits(remote,m->remoteipbits); + else remote[0] = 0; + if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 ) + free(str); + free(m); + } + }*/ + + /* uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; + bits256 orderhash,traderpub; struct iguana_info *coinbtc; + if ( (swap= ap->info) == 0 ) + return(clonestr("{\"error\":\"no swapinfo set\"}")); + relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); + if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC ) + minperc = INSTANTDEX_MINPERC; + offerdir = instantdex_bidaskdir(&ap->offer); + if ( 0 ) + { + int32_t i; + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&ap->offer)[i]); + printf("swapset.%llu\n",(long long)ap->orderid); + } + if ( offerdir > 0 ) + { + swap->bidid = ap->orderid; + swap->askid = ap->otherorderid; + } + else + { + swap->askid = ap->orderid; + swap->bidid = ap->otherorderid; + } + if ( bits256_nonz(swap->othertrader) == 0 ) + swap->othertrader = traderpub; + else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) + { + printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); + return(clonestr("{\"error\":\"no competing offers for now\"}")); + } + if ( bits256_nonz(swap->orderhash) == 0 ) + swap->orderhash = orderhash; + else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) + { + printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); + return(clonestr("{\"error\":\"orderhash mismatch???\"}")); + } + swap->satoshis[0] = ap->offer.basevolume64; + swap->satoshis[1] = relsatoshis; + swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee + /* if ( ap->info == 0 ) + //printf("gotoffer SETSWAP for orderid.%llu (%s)\n",(long long)ap->orderid,jprint(argjson,0)); + swap->choosei = swap->otherschoosei = -1; + if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) + return(retstr); + swap->feetag64 = ap->orderid;*/ + + /*char *instantdex_swapset(struct supernet_info *myinfo,struct instantdex_accept *ap,cJSON *argjson) + { + uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; + struct bitcoin_swapinfo *swap; bits256 orderhash,traderpub; struct iguana_info *coinbtc; + if ( (swap= ap->info) == 0 ) + return(clonestr("{\"error\":\"no swapinfo set\"}")); + relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); + traderpub = jbits256(argjson,"traderpub"); + if ( (minperc= jdouble(argjson,"m")) < INSTANTDEX_MINPERC ) + minperc = INSTANTDEX_MINPERC; + if ( (coinbtc= iguana_coinfind("BTC")) == 0 ) + return(clonestr("{\"error\":\"no BTC found\"}")); + insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); + offerdir = instantdex_bidaskdir(&ap->offer); + vcalc_sha256(0,orderhash.bytes,(void *)&ap->offer,sizeof(ap->offer)); + if ( 0 ) + { + int32_t i; + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&ap->offer)[i]); + printf("swapset.%llu\n",(long long)ap->orderid); + } + if ( offerdir > 0 ) + { + swap->bidid = ap->orderid; + swap->askid = ap->otherorderid; + } + else + { + swap->askid = ap->orderid; + swap->bidid = ap->otherorderid; + } + if ( bits256_nonz(swap->othertrader) == 0 ) + swap->othertrader = traderpub; + else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) + { + printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); + return(clonestr("{\"error\":\"no competing offers for now\"}")); + } + if ( bits256_nonz(swap->orderhash) == 0 ) + swap->orderhash = orderhash; + else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) + { + printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); + return(clonestr("{\"error\":\"orderhash mismatch???\"}")); + } + swap->satoshis[0] = ap->offer.basevolume64; + swap->satoshis[1] = relsatoshis; + swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee + return(0); + } + + char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson) // Bob sending to network (Alice) + { + struct iguana_info *other; struct bitcoin_swapinfo *swap; int32_t isbob; cJSON *newjson; char *retstr; + if ( strcmp(ap->offer.rel,"BTC") != 0 ) + return(clonestr("{\"error\":\"invalid othercoin\"}")); + else if ( (other= iguana_coinfind(ap->offer.base)) == 0 ) + return(clonestr("{\"error\":\"invalid othercoin\"}")); + else if ( ap->offer.price64 <= 0 || ap->offer.basevolume64 <= 0 ) + return(clonestr("{\"error\":\"illegal price or volume\"}")); + isbob = (ap->offer.myside == 1); + swap = calloc(1,sizeof(struct bitcoin_swapinfo)); + swap->isbob = isbob; + swap->expiration = ap->offer.expiration;//(uint32_t)(time(NULL) + INSTANTDEX_LOCKTIME*isbob); + swap->choosei = swap->otherschoosei = -1; + swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1; + ap->info = swap; + printf("sendoffer SETSWAP for orderid.%llu ap.%p (%p)\n",(long long)ap->orderid,ap,swap); + if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) + return(retstr); + ap->orderid = swap->orderhash.txid; + if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); + else + { + //instantdex_bobtx(myinfo,iguana_coinfind("BTCD"),&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],ap->offer.expiration-INSTANTDEX_LOCKTIME*2,swap->satoshis[1],1); + //instantdex_alicetx(myinfo,iguana_coinfind("BTCD"),swap->altmsigaddr,&swap->altpaymenttxid,swap->pubAm,swap->pubBn,swap->satoshis[0]); + if ( 0 ) + { + int32_t i; + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&ap->offer)[i]); + printf("BTCoffer.%llu\n",(long long)ap->orderid); + } + return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); + } + }*/ + /*ptr = (void *)bp->scriptsmap; + ind = unspentind << 1; + for (i=0; inumscriptsmaps; i++,ptr+=2) + { + if ( ind == ptr[0] ) + { + printf("bp.[%d] ind.%d offset.%d vs %ld\n",bp->hdrsi,ind,ptr[1],coin->scriptsfilesize); + if ( ptr[1] + sizeof(struct scriptdata) <= coin->scriptsfilesize ) + { + if ( memcmp((void *)((long)coin->scriptsptr + ptr[1] + sizeof(struct scriptdata)),spendscript,spendlen) == 0 ) + { + printf("matched against existing scriptsptr[%d] %d\n",ptr[1],spendlen); + return(ptr[1]); + } + printf("mismatch against existing scriptsptr[%d] %d\n",ptr[1],spendlen); + } + else + { + if ( (fp= fopen(coin->scriptsfname,"rb")) != 0 ) + { + fseek(fp,ptr[1] + sizeof(struct scriptdata),SEEK_SET); + for (i=0; ihdrsi,unspentind,i,ftell(fp),ptr[1],ptr[1]+sizeof(struct scriptdata)+spendlen,c,spendscript[i]); + for (; inumscriptsmaps >= bp->maxscriptsmaps ) + { + bp->scriptsmap = realloc(bp->scriptsmap,(1000+bp->maxscriptsmaps) * (sizeof(offset) + sizeof(ind))); + bp->maxscriptsmaps += 1000; + } + ptr = (void *)((long)bp->scriptsmap + bp->numscriptsmaps*size); + ptr[0] = ind; + ptr[1] = offset; + bp->numscriptsmaps++; + }*/ + + uint32_t iguana_scriptstableadd(struct iguana_info *coin,int32_t spendflag,uint32_t fpos,uint8_t *script,uint16_t scriptlen) + { + struct scriptinfo *ptr; + HASH_FIND(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); + if ( ptr == 0 ) + { + ptr = mycalloc('w',1,sizeof(*ptr) + scriptlen); + ptr->fpos = fpos; + ptr->scriptlen = scriptlen; + memcpy(ptr->script,script,scriptlen); + HASH_ADD(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); + } + return(fpos); + } + + uint32_t iguana_scriptstablefind(struct iguana_info *coin,int32_t spendflag,uint8_t *script,int32_t scriptlen) + { + struct scriptinfo *ptr; + HASH_FIND(hh,coin->scriptstable[spendflag],script,scriptlen,ptr); + if ( ptr != 0 ) + return(ptr->fpos); + else return(0); + } + + long iguana_rwscript(struct iguana_info *coin,int32_t rwflag,void *fileptr,long offset,long filesize,FILE *fp,struct iguana_bundle *bp,uint8_t **scriptptrp,int32_t *lenp,int32_t hdrsi,uint32_t ind,int32_t spendflag) + { + long scriptpos; struct scriptdata data; uint8_t *script = *scriptptrp; + if ( spendflag == 0 && (scriptpos= iguana_scriptstablefind(coin,spendflag,script,*lenp)) != 0 ) + return(scriptpos); + memset(&data,0,sizeof(data)); + if ( rwflag != 0 && fp != 0 && fileptr == 0 ) + { + scriptpos = ftell(fp); + data.ind = ind, data.spendflag = spendflag; + data.hdrsi = hdrsi; + data.scriptlen = *lenp; + if ( fwrite(&data,1,sizeof(data),fp) != sizeof(data) ) + return(-1); + if ( fwrite(script,1,data.scriptlen,fp) != data.scriptlen ) + return(-1); + offset = (uint32_t)ftell(fp); + //printf("spend.%d filesize.%ld wrote.h%d u%d len.%d [%ld,%ld) crc.%08x\n",spendflag,coin->scriptsfilesize[spendflag],hdrsi,ind,data.scriptlen,scriptpos,ftell(fp),calc_crc32(0,script,data.scriptlen)); + } + else if ( rwflag == 0 && fp == 0 && fileptr != 0 ) + { + scriptpos = offset; + if ( offset+sizeof(data) <= filesize ) + { + memcpy(&data,(void *)((long)fileptr + offset),sizeof(data)); + if ( data.scriptlen > 0 && data.scriptlen < *lenp && offset+sizeof(data)+data.scriptlen <= filesize ) + { + if ( data.scriptlen > 0 ) + { + *scriptptrp = script = (void *)((long)fileptr + offset); + offset += data.scriptlen + sizeof(data); + if ( data.hdrsi < coin->bundlescount ) + bp = coin->bundles[data.hdrsi]; + else printf("illegal hdrsi.%d/%d\n",data.hdrsi,coin->bundlescount); + } else printf("illegal scriptlen %d\n",data.scriptlen); + //printf("hdrsi.%d loaded script.%d %u s%d\n",data.hdrsi,data.scriptlen,data.ind,data.spendflag); + } + else if ( data.scriptlen > 0 ) + { + printf("spendlen overflow.%d vs %d\n",data.scriptlen,*lenp); + return(-1); + } + } + else + { + printf("error reading from %ld\n",scriptpos); + return(-1); + } + //printf("hdrsi.%d scriptlen.%d\n",data.hdrsi,data.scriptlen); + *lenp = data.scriptlen; + } + if ( bp != 0 ) + { + //if ( spendflag == 0 ) + iguana_scriptstableadd(coin,spendflag,(uint32_t)scriptpos,script,*lenp); + } + else if ( rwflag == 0 ) + { + printf("null bp for iguana_rwscript hdrsi.%d/%d\n",data.hdrsi,coin->bundlescount); + return(-1); + } + return(offset); + } + + long iguana_initscripts(struct iguana_info *coin) + { + long fpos=0,offset = 0; uint8_t scriptdata[IGUANA_MAXSCRIPTSIZE],*scriptptr; int32_t spendflag,size,n=0; struct scriptdata script; + for (spendflag=0; spendflag<2; spendflag++) + { + portable_mutex_lock(&coin->scripts_mutex[spendflag]); + sprintf(coin->scriptsfname[spendflag],"tmp/%s/%sscripts",coin->symbol,spendflag==0?"":"sig"), OS_portable_path(coin->scriptsfname[spendflag]); + printf("scripts fname.(%s)\n",coin->scriptsfname[spendflag]); + if ( (coin->scriptsptr[spendflag]= OS_mapfile(coin->scriptsfname[spendflag],&coin->scriptsfilesize[spendflag],0)) == 0 ) + { + coin->scriptsfp[spendflag] = fopen(coin->scriptsfname[spendflag],"wb"); + memset(&script,0,sizeof(script)); + fwrite(&script,1,sizeof(script),coin->scriptsfp[spendflag]); + } + else + { + while ( 1 ) + { + size = sizeof(scriptdata); + scriptptr = scriptdata; + if ( (offset= iguana_rwscript(coin,0,coin->scriptsptr[spendflag],offset,coin->scriptsfilesize[spendflag],0,0,&scriptptr,&size,0,0,spendflag)) < 0 ) + break; + else fpos = offset; + n++; + } + coin->scriptsfp[spendflag] = fopen(coin->scriptsfname[spendflag],"ab"); + portable_mutex_unlock(&coin->scripts_mutex[spendflag]); + printf("initialized %d scripts, fpos %ld\n",n,fpos); + return(offset); + } + portable_mutex_unlock(&coin->scripts_mutex[spendflag]); + } + return(-1); + } + + uint32_t iguana_scriptsave(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t ind,int32_t spendflag,uint8_t *script,int32_t scriptlen) + { + FILE *fp; long fpos = 0; + if ( scriptlen > 0 && (fp= coin->scriptsfp[spendflag]) != 0 ) + { + portable_mutex_lock(&coin->scripts_mutex[spendflag]); + fpos = ftell(fp); + if ( iguana_rwscript(coin,1,0,0,0,fp,bp,&script,&scriptlen,bp->hdrsi,ind,spendflag) < 0 ) + { + fseek(fp,fpos,SEEK_SET); + fpos = -1; + printf("error saving script at %ld\n",fpos); + } else fflush(fp); + portable_mutex_unlock(&coin->scripts_mutex[spendflag]); + } else printf("cant scriptsave.%d to (%s).%p scriptlen.%d\n",spendflag,coin->scriptsfname[spendflag],coin->scriptsfp[spendflag],scriptlen); + return((uint32_t)fpos); + } + + long iguana_scriptadd(struct iguana_info *coin,struct iguana_bundle *bp,uint32_t unspentind,int32_t type,uint8_t *spendscript,int32_t spendlen,uint8_t rmd160[20],int32_t vout) + { + static long total,saved; + int32_t scriptlen; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t script[IGUANA_MAXSCRIPTSIZE]; long fpos=0; struct vin_info V,*vp = &V; + if ( spendlen == 0 ) + { + printf("null script?\n"); + getchar(); + return(0); + } + memset(vp,0,sizeof(*vp)); + asmstr[0] = 0; + total++; + scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout); + if ( scriptlen == spendlen && memcmp(script,spendscript,scriptlen) == 0 ) + return(0); + else + { + saved++; + //if ( (saved % 1000) == 0 ) + printf("add type.%d scriptlen.%d fpos.%ld saved.%ld/%ld\n",type,spendlen,coin->scriptsfp!=0?ftell(coin->scriptsfp[0]):-1,saved,total); + fpos = iguana_scriptsave(coin,bp,unspentind,0,spendscript,spendlen); + } + return(fpos); + } + if ( s->sighash != iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vinscript,vinscriptlen) ) + { + static uint64_t counter; + if ( counter++ < 100 ) + { + for (i=0; isighash); + } + return(spendind); + } + //ramchain->H.stacksize += sigsize;// + 1 + (sigsize >= 0xfd)*2; + if ( s->numpubkeys > 0 ) + { + for (i=0; inumpubkeys; i++) + { + if ( (ptr= iguana_hashfind(ramchain,'P',V.signers[i].rmd160)) == 0 ) + { + //printf("from addspend\n"); + //pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,V.signers[i].rmd160,0,0,0); + //printf("create pkind.%d from vin\n",pkind); + } else pkind = ptr->hh.itemind; + } + } + if ( 0 && s->numsigs > 0 ) + printf("autoverify numsigs.%d\n",s->numsigs); + + + uint8_t *iguana_scriptptr(struct iguana_info *coin,int32_t *scriptlenp,uint8_t _script[IGUANA_MAXSCRIPTSIZE],uint32_t scriptfpos,uint8_t *scriptdata,int32_t scriptlen,int32_t maxsize,int32_t spendflag) + { + *scriptlenp = scriptlen; + if ( 0 && scriptlen > 0 ) + { + if ( scriptfpos != 0 ) + scriptdata = iguana_scriptfpget(coin,scriptlenp,_script,scriptfpos,spendflag); + } + return(scriptdata); + } + + uint8_t *iguana_scriptfpget(struct iguana_info *coin,int32_t *scriptlenp,uint8_t _script[IGUANA_MAXSCRIPTSIZE],uint32_t scriptoffset,int32_t spendflag) + { + FILE *fp; uint8_t *scriptdata=0; int32_t scriptlen=0; struct scriptdata sdata; + *scriptlenp = 0; + if ( (fp= fopen(coin->scriptsfname[spendflag],"rb")) != 0 ) + { + fseek(fp,scriptoffset,SEEK_SET); + if ( fread(&sdata,1,sizeof(sdata),fp) != sizeof(sdata) ) + printf("iguana_scriptfpget: error reading sdata\n"); + else if ( sdata.scriptlen > 0 && sdata.scriptlen <= IGUANA_MAXSCRIPTSIZE ) + { + if ( fread(_script,1,sdata.scriptlen,fp) == sdata.scriptlen ) + { + scriptdata = _script; + *scriptlenp = scriptlen = sdata.scriptlen; + //printf("raw [%d] offset.%d scriptlen.%d\n",bp->hdrsi,scriptoffset,scriptlen); + //for (i=0; i<16; i++) + // printf("%02x",_script[i]); + //printf(" set script.%d\n",scriptlen); + } + } + fclose(fp); + } + return(scriptdata); + } + //struct scriptdata { uint32_t ind:31,spendflag:1; uint16_t hdrsi,scriptlen; }__attribute__((packed)); + + if ( ramchain->expanded != 0 ) + { + if ( (long)destoffset < (long)srcoffset ) + { + /*sprintf(fname,"sigs/%s/%s",coin->symbol,bits256_str(str,bp->hashes[0])); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( ramchain->H.stacksize > 0 ) + { + if ( fwrite(srcoffset,1,ramchain->H.stacksize,fp) != ramchain->H.stacksize ) + printf("error writing %d sigs to %s\n",ramchain->H.stacksize,fname); + } + else + { + if ( fwrite(&izero,1,sizeof(izero),fp) != sizeof(izero) ) + printf("error writing izero to %s\n",fname); + } + fclose(fp); + } + if ( (ramchain->sigsfileptr= OS_mapfile(fname,&ramchain->sigsfilesize,0)) == 0 ) + return(-1); + printf("%s bp.[%d] ht.%d stacksize.%u filesize.%u\n",fname,bp->hdrsi,bp->bundleheight,ramchain->H.stacksize,(uint32_t)ramchain->sigsfilesize);*/ + //for (i=0; iH.stacksize; i++) + // c = *srcoffset, *destoffset++ = c, *srcoffset++ = 0; + } else printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); + } + // if file exists and is valid, load and then process only the incremental + long iguana_spentsfile(struct iguana_info *coin,int32_t n) + { + int32_t i,iter,allocated = 0; long filesize,total,count; struct iguana_bundleind *spents = 0; struct iguana_ramchain *ramchain; char fname[1024]; struct iguana_bundle *bp; FILE *fp; + fname[0] = 0; + for (total=iter=0; iter<2; iter++) + { + for (count=i=0; ibundles[i]) != 0 ) + { + ramchain = &bp->ramchain; + if ( ramchain->H.data != 0 ) + { + if ( iter == 1 ) + { + ramchain->spents = &spents[count]; + //printf("bp.[%d] count.%ld %p\n",i,count,ramchain->spents); + if ( allocated != 0 && iguana_spentsinit(coin,spents,bp,ramchain) < 0 ) + { + printf("error initializing spents bp.%d\n",i); + exit(-1); + } + } + count += ramchain->H.data->numunspents; + } else break; + } else return(-1); + } + if ( i < n ) + n = (i + 1); + sprintf(fname,"DB/%s/spents_%d.%ld",coin->symbol,n,count); + printf("%s total unspents.%ld\n",fname,count); + if ( iter == 0 ) + { + total = count; + if ( (spents= OS_filestr(&filesize,fname)) == 0 ) + spents = calloc(total,sizeof(*spents)), allocated = 1; + } + else if ( total != count ) + printf("%s total.%ld != count.%ld\n",fname,total,count); + } + if ( allocated != 0 && fname[0] != 0 && (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(spents,total,sizeof(*spents),fp); + fclose(fp); + } + return(total); + } + + int32_t iguana_spentsinit(struct iguana_info *coin,struct iguana_bundleind *spents,struct iguana_bundle *bp,struct iguana_ramchain *ramchain) + { + int32_t spendind,n,max,hdrsi,errs,flag; uint32_t unspentind; struct iguana_bundle *spentbp; + struct iguana_spend *S; bits256 prevhash; + S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + max = ramchain->H.data->numunspents; + n = ramchain->H.data->numspends; + for (spendind=1,errs=0; spendindhdrsi; + if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,&S[spendind])) != 0 ) + { + spentbp->ramchain.spents[unspentind].ind = spendind; + spentbp->ramchain.spents[unspentind].hdrsi = bp->hdrsi; + flag = 1; + if ( S[spendind].external == 0 && spentbp != bp ) + printf("spentsinit unexpected spendbp: %p bp.[%d] U%d <- S%d.[%d] [%p %p %p]\n",&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spendind,bp->hdrsi,coin->bundles[0],coin->bundles[1],coin->bundles[2]); + } + else if ( S[spendind].prevout < 0 ) + flag = 1; + else printf("unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + if ( flag == 0 ) + errs++; + } + printf("processed %d spendinds for bp.[%d] -> errs.%d\n",spendind,bp->hdrsi,errs); + return(-errs); + } + if ( bp != currentbp ) + { + //printf("initial requests for hdrs.%d\n",bp->hdrsi); + pend = queue_size(&coin->priorityQ) + queue_size(&coin->blocksQ); + for (i=0; ipeers.active[i].pendblocks; + if ( 0 && pend >= IGUANA_BUNDLELOOP ) + { + //for (i=better=0; ibundlescount; i++) + // if ( coin->bundles[i] != 0 && coin->bundles[i]->numsaved > bp->numsaved ) + // better++; + //if ( better > coin->peers.numranked ) + { + //usleep(10000); + //printf("SKIP pend.%d vs %d: better.%d ITERATE bundle.%d n.%d r.%d s.%d finished.%d timelimit.%d\n",pend,coin->MAXPENDING*coin->peers.numranked,better,bp->bundleheight,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit); + iguana_bundleQ(coin,bp,1000); + return(0); + } + } + counter = iguana_bundlekick(coin,bp,starti,max); + } + if ( req == 0 && 0 ) + { + if ( 1 )//(rand() % 10) == 0 ) + flag = iguana_neargap(coin,addr); + else if ( 0 && (bp= addr->bp) != 0 && bp->rank != 0 && addr->pendblocks < limit ) + { + r = rand(); + for (j=0; jn; j++) + { + i = (r + j) % bp->n; + if ( (block= bp->blocks[i]) != 0 && block->numrequests == bp->minrequests && block->fpipbits == 0 && block->queued == 0 ) + { + printf("peer.%s BPranked.%d [%d:%d] pending.%d numreqs.%d\n",addr->ipaddr,bp->rank,bp->hdrsi,i,addr->pendblocks,block->numrequests); + block->numrequests++; + flag++; + iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); + break; + } + } + } + } + + int32_t iguana_neargap(struct iguana_info *coin,struct iguana_peer *addr) + { + struct iguana_block *block,*bestblock = 0; struct iguana_bundle *bp,*bestbp = 0; + int32_t height,hdrsi,i,j,n,bundlei,gap,besti = -1; uint32_t r; + if ( addr->rank > 0 ) + { + n = coin->peers.numranked * 2; + gap = addr->rank * (1 + n + coin->peers.numranked) + coin->peers.numranked; + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish == 0 ) + break; + height = (i * coin->chain->bundlesize); + r = rand(); + for (i=0; ichain->bundlesize; + if ( (bp= coin->bundles[hdrsi]) != 0 ) + { + bundlei = (height + j) % coin->chain->bundlesize; + if ( (block= bp->blocks[bundlei]) != 0 && block->fpipbits == 0 && block->queued == 0 ) + { + if ( block->numrequests == bp->minrequests ) + { + bestblock = block; + bestbp = bp; + besti = bundlei; + break; + } + else if ( bestblock == 0 || block->numrequests < bestblock->numrequests ) + { + bestblock = block; + bestbp = bp; + besti = bundlei; + } + } + } + } + if ( bestblock != 0 ) + { + printf("near hwm.%d gap.%d peer.%s bpranked.%d [%d:%d] pending.%d numreqs.%d\n",height,j,addr->ipaddr,bestbp->rank,bestbp->hdrsi,besti,addr->pendblocks,bestblock->numrequests); + bestblock->numrequests++; + iguana_sendblockreqPT(coin,addr,bestbp,besti,bestblock->RO.hash2,0); + return(1); + } + } + return(0); + } + /*if ( doneval != maxval ) + { + r = rand() % numpeers; + oldest = 0; + for (i=0; i 0 ) + { + for (i=j; in; i+=numpeers) + if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 ) + { + if ( oldest == 0 || block->issued < oldest->issued ) + oldest = block; + if ( now > block->issued+10+60*(bp!=coin->current) ) + { + for (k=0; k 0 && (addr= coin->peers.ranked[z]) != 0 ) + { + if ( bp == coin->current ) + printf("send [%d:%d] to addr[%d]\n",bp->hdrsi,block->bundlei,z); + block->issued = (uint32_t)time(NULL); + counter++; + iguana_sendblockreqPT(coin,addr,bp,block->bundlei,block->RO.hash2,0); + break; + } + } + } + } + } + } + }*/ + //return(counter); + /*if ( 0 && time(NULL) > bp->lastspeculative+60 ) + { + for (i=1,counter=0; in; i++) + { + if ( (block= bp->blocks[i]) == 0 || block->fpos < 0 || block->fpipbits == 0 ) + { + if ( bp->speculative != 0 && bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) > 0 && i < bp->numspec ) + iguana_blockQ("speculate0",coin,0,-2,bp->speculative[i],0), counter++; + else if ( bits256_nonz(bp->hashes[i]) != 0 ) + iguana_blockQ("speculate1",coin,0,-3,bp->hashes[i],0), counter++; + } + } + if ( counter != 0 ) + printf("SPECULATIVE issue.%d bp.[%d]\n",counter,bp->hdrsi); + bp->lastspeculative = (uint32_t)time(NULL); + }*/ #endif diff --git a/field.html b/field.html old mode 100644 new mode 100755 diff --git a/footer.html b/footer.html old mode 100644 new mode 100755 diff --git a/formfooter.html b/formfooter.html old mode 100644 new mode 100755 diff --git a/formheader.html b/formheader.html old mode 100644 new mode 100755 diff --git a/header.html b/header.html old mode 100644 new mode 100755 diff --git a/help.json b/help.json new file mode 100755 index 000000000..fe51488c7 --- /dev/null +++ b/help.json @@ -0,0 +1 @@ +[] diff --git a/help/.tmpmarker b/help/.tmpmarker old mode 100644 new mode 100755 diff --git a/iguana/Makefile b/iguana/Makefile old mode 100644 new mode 100755 diff --git a/iguana/Readme.md b/iguana/Readme.md new file mode 100755 index 000000000..596952081 --- /dev/null +++ b/iguana/Readme.md @@ -0,0 +1,193 @@ +#SuperNET Client "iguana" + +[![Join the chat at https://gitter.im/jl777/SuperNET](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jl777/SuperNET?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +> #TL;DR# +> +> ```sudo apt-get update; sudo apt-get install libcurl4-gnutls-dev libssl-dev; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix; ./m_unix; agents/iguana``` +> +> The above one line gets SuperNET installed, built and launched for unix. +> +> After that ```./m_unix``` updates to latest. +> *Continue below at "Running".* + +**iguana is easy to build. Start by cloning (or downloading) this repository.** + +#DEPENDENCIES# +##for native (unix, osx)## +Just make sure you have the dev versions of openssl and curl installed: + +```sudo apt-get install libcurl4-gnutls-dev libssl-dev``` + +##For native (win32, win64)## +TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin +MINGW := i586-mingw32 +The above two definitions need to be changed to match the mingw install on your system. m_win32 and m_win64 just invokes the makefile in mingw32 and mingw64 + +##For chrome app## +You need to make sure the nacl sdk is properly installed and you are able to build the examples. +Now you will need to get the external libs, which can be built from scratch using naclports or there use the reference builds of libssl.a, libcrypto.a, libcurl.a and libz.a in the SuperNET/crypto777/pnacl_libs. You can just copy those over into $(NACL_SDK_ROOT)//lib/pnacl. + + +#ONETIME# +Now you are ready to build. +I try to make the build process as simple as possible, so there are no `autoconf`, `autoreconf`, `configure`, `cmake`, `make`, to get properly installed and running and run, etc. You do need a C compiler, like gcc. + +The **first time** you need to build libcrypto777.a and to do that you need to run: + +For unix: ```./m_onetime m_unix``` + +For osx: ```./m_onetime m_osx``` + +For win32: ```./m_onetime m_win32``` + +For win64: ```./m_onetime m_win64``` + +#(RE)BUILD + +Once libcrypto777.a is built, you can build the agents. + +For pnacl: ```cd crypto777; make clean; make; cd ../iguana; make clean; make``` + +For unix: ```./m_unix``` + +For osx: ```./m_osx``` + +For win32: ```./m_win32``` + +For win64: ```./m_win64``` + + +The m_(OS) is a standard I follow and should be self explanatory. within each is usually just a few lines, ie compile all the .c files and link with the standard libs. + +To build just iguana, you can ```cd``` into SuperNET/iguana and do ```./m_unix``` (or ```./m_osx```, ...). + +```./m_clean``` will remove the files created from the building + +#RUNNING# + +The native versions are command line applications: agents/iguana {JSON} +The chrome app pexe requires that the chrome is launched with a command line parameter (tools/chrome.localhost) and then browse to *http://127.0.0.1:7777* to see the pexe + +#SUPERUGLYGUI# + +Once iguana is running, you can see the superuglyGUI at *http://127.0.0.1:7778/?method* +by submitting API calls using the forms, you will see it go to some specific URL. You can also do a programmatic GET request to ```http://127.0.0.1:7778/api/``` + +*http://127.0.0.1:7778/ramchain/block/height/0* -> full webpage + +*http://127.0.0.1:7778/json/ramchain/block/height/0* -> JSON only + +```curl --url "http://127.0.0.1:7778/ramchain/BTCD/block/height/0"``` --> full webpage returned (probably not what you want) +```curl --url "http://127.0.0.1:7778/api/ramchain/BTCD/block/height/0"``` --> returns just the json object from the api call + +Internally, all paths convert the request into a standard SuperNET JSON request. you can use a POST command to directly submit such JSON requests: +```curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"ramchain\",\"method\":\"block\",\"coin\":\"BTCD\",\"height\":0}"``` + +Another approach is to use the bitcoin RPC syntax via: + curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"getinfo\",\"params\":[]}" +the params:[] array is where the standard bitcoin parameters go, the only change that is needed is to specify the coin +alternatively {"agent":"SuperNET","method":"bitcoinrpc","coin":"BTCD"} will set the coin +to use for bitcoin RPC calls. this will suffice in single coin environments + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana",\"method\":\"test\"}" +curl --url "http://127.0.0.1:7778/iguana/test" -> html page with results +curl --url "http://127.0.0.1:7778/api/iguana/test" -> just json text +http://127.0.0.1:7778 -> superugly GUI +http://127.0.0.1:7778/iguana/test +http://127.0.0.1:7778/api/iguana/test +postCall('{"agent":"iguana","method":"test"}'} +iguana_JSON("{\"agent\":\"iguana",\"method\":\"test\"}"); -> direct C function call + + +iguana can be invoked with a command line argument. if it is a name of a file, it will load it and check to see if it is valid JSON and if it is, it will use it. Otherwise the command line argument needs to be valid JSON to be used and it will process the JSON to initialize account passphrases, exchange apikeys, etc. A few special keys: + +"wallet" -> passphrase used for the persistent privkey +"2fafile" -> secondary part (optional) for the persistent privkey +"numhelpers" -> number of helper threads (need at least 1) +"exchanges" -> { "name":"", ... } + "apikey", "apisecret", "userid", "tradepassword" these are as expected + "pollgap" -> gap between each access to exchange for getting prices + +###### +The goal for iguana is to create a scalable bitcoin core implementation that is backward compatible and a drop in replacement, so all the RPC needs to be implemented in addition to peer messaging, blockchain, scripts, wallet, etc. + +The first thing you notice when looking at the raw blockchain is that there is a LOT of redundancy, so by mapping the high entropy hashes to a 32bit integer, you get a 28 byte savings for each use. For a txid with N outputs, that is up to N*28 bytes that would be saved as each vin refers to the txid. + +Since the blockchain has an implicit ordering, it is possible to create a canonical numbering for the txid, vouts, vins, and this will allow syncing the iguana files to save gobs of bandwidth. However both endian formats need to be put into the bittorrent network as the iguana files are designed to be directly memory mapped. This allows skipping of serialization/deserialization of each and every multibyte field. Since the files are less than half the size, even with the doubling due to both endian forms, it is still less overall data than the raw blockchain. + +bitfields are used, so that means a standard way of allocating the bits needs to be used by each compiler. gcc and clang use the same method, so as long as it is compiled with those or one with compatible bitfield allocation, the memory mapped files should work. + +The most space is used by the vout, vin, pkhash structures, as there are a lot more vouts than txids. The txid structure has not been fully optimized, but since it is less than 1% of overall space, I felt it was not worth making it more complicated to save few bytes. The pkhash is the pubkey hash rmd160(sha256(pubkey)) and this is the most efficient way to index the blockchain as all vout scripts generate a rmd160[20] either implicitly for the scripts with pubkey, pay to pubkey hash standard script and all the new p2sh scripts. Another reason to use rmd160 is that it makes it easy to convert to the equivalent addresses for other coins, ie. all coins have the same rmd160 even if the coin addresses are different due to the address type byte added to the base58 conversion. + +The following are the second pass data structures that are created from a batch of raw structures in groups of 2000 (the size of the getheaders). The design needs to meet many constraints, primarily to be as small as possible without sacrificing speed and to be able to work in a parallel sync. That means that each block or bundle needs to be as self-contained as possible, but have external references that can be resolved. This is similar to object files and linkers. The main thing that has these external references are the vins. + +I tried quite a few variations before settling on this. Earlier versions combined everything into a single dataset, which is good for making searches via hashtable really fast, but with the ever growing size of the blockchain not very scalable. The maximum size of 2000 blocks is 2GB right now and at that size there is no danger of overflowing any 32bit offset, but for the most part, the 32bit indexes are of the item, so it can represent much larger than 4GB. + +iguana doesnt use any DB as that is what causes most of the bottlenecks and since the data doesnt change (after 20 blocks), a DB is just overkill. Using the memory mapped file approach, it takes no time to initialize the data structures, but certain operations take linear time relative to the number of bundles. Achieving this performance requires constant time performance for all operations within a bundle. Since most bundles will not have the hash that is being searched for, I used a bloom filter to quickly determine which bundles need to be searched deeper. For the deeper searches, there is a open hashtable that always has good performance as it is sized so it is one third empty. Since the total number of items is known and never changes, both the bloom filters and hashtable never change after initial creation. + +What this means is that on initialization, you memory map the 200 bundles and in the time it takes to do that (less than 1sec), you are ready to query the dataset. Operations like adding a privkey takes a few milliseconds, since all the addresses are already indexed, but caching all the transactions for an address is probably not even necessary for a single user wallet use case. However for dealing with thousands of addresses, it would make sense to cache the lists of transactions to save the few milliseconds per address. + +You might be wondering how is it even possible to have an append only dataset that allows traversing the entire blockchain and searching for all transactions from a specific address. Note that by indexing at the rmd160 level, there is no difference between a multisig address and a normal address and so all the operations work equally for any address, be it pubkey, pubkeyhash, multisig or p2sh. + +With 200 bundles and millions of unspents per bundle recently, it would be easy to have things take a long time to iterate through and find all references to a specific address. What I realized was that during a single pass I can update an arbitrary number of linked lists, one for each rmd160. However it needs to work backwards so you never need to change any previous entry. As soon as an unspent is created, it is final and never changes. It does require a single dynamic data structure for the account which keeps track of the balance (just the sum of outputs) and the last unspentind. As new unspents are made to the same address, it links back to the prior one and updates the total balance. + +To get the list of all transactions, all bundles need to be queried. For each bundle, constant time hash lookups find the last access and then iterating backwards to the first occurance finds all unspents in the bundle. So it is linear time relative to the total number of unspents that an address has with a small 200 constant time operations overhead. As the number of bundles grows, this will continue to increase, but it is always possible to make a single lookup table that spans the entire set of bundles, so I am not worried about scaling things up. Note that the parallel nature of all the bundles makes using multiple cores for all the searches relatively easy, so speedups of N using N cores is not much work. + +I could probably get rid of the firstunspentind in the pkhash struct, but it is there to provide an error check when iterating backwards on the linked list. the pubkeyoffset is also optional, but I find it handy to be able to know what pubkey maps to the rmd160 for a variety of use cases and I am on the fence as to whether to make it purgeable or not. + +I had to make the signatures from the vinscripts purgeable as I dont seem much use for them after a node has validated an input other than relaying the raw block to other nodes. Without the sigs, a node can still be totally self-sufficient when creating new transactions and the sigs are high entropy and unique and is approx equal to the uncompressed size of everything else! The pubkeys are much smaller, especially due to address reuse within a bundle, which only takes up 4 bytes. It is probably worth adding a way to purge the pubkeys at some point, but the method I used to enable signature pruning was to create a stack that grows down to put the signatures into during processing the each block. There is also a forward growing data store where all the things that cant be encoded in the baseline structures are put into. + +It is necessary to used an upfront memory allocation as doing hundreds of millions of malloc/free is a good way to slow things down, especially when there are many threads. Using the onetime allocation, cleanup is guaranteed to not leave any stragglers as a single free releases all memory. After all the blocks in the bundle are processed, there will be a gap between the end of the forward growing data called Kspace and the reverse growing stack for the sigs, so before saving to disk, the sigs are moved to remove the gap. At this point it becomes clear why it had to be a reverse growing stack. I dont want to have to make another pass through the data after moving the signatures and by using negative offsets relative to the top of the stack, there is no need to change any of the offsets used for the signatures. + +Most of the unspents use standard scripts so usually the script offset is zero. However this doesnt take up much room at all as all this data is destined to be put into a compressed filesystem, like squashfs, which cuts the size in about half. Not sure what the compressed size will be with the final iteration, but last time with most of the data it was around 12GB, so I think it will end up around 15GB compressed and 25GB uncompressed. + +Each bundle file will have the following order: +[ ][nonstandard scripts and other data] ... gap ... [signatures] +after saving it the gap goes away. Since the signatures are at the end, it is possible to truncate each bundle file to dramatically reduce its size. It would save a lot of time compressing the files without the signatures as they are high entropy and dont compress, but having them in a different file would really complicate the code. Not that it isnt already quite complicated. + +I realize totally replace all the DB is rather radical, but it was the only way possible to achieve a parallel sync that streams data in at bandwidth saturation speeds. In order to validate the dataset, which is clearly required before any production use of a DB replacement, I decided to put in the extra effort to make iguana able to act as a lossless codec. This would allow verification at the rawtx bytes level with a simple loop that iterates across all blocks and all tx within a block to verify that all txbytes match against what bitcoind returns. + +Of course, since bitcoind wont be able to even calculate balances for all addresses without enabling watching all addresses, I dont know a practical way to verify that all the balance calculations are correct. + +Here are the fundamental data structures and the total size for each is not a typo, it really is 64 bytes for txid, 28 bytes per unspent, 12 bytes per spend and 32 bytes per pkhash and 12 bytes for account balance and end of linked list. But things are even smaller! Each unspent has a unique unspentind within each bundle, so you can have a list of all the unspents that takes up 4 bytes per unspent + 4bytes per bundle it appears in. + +I havent optimized the utxo handling yet, but the plan is to calculate an overlay vector of all unspents that are spent for each bundle. This too is a static dataset, but it cant be calculated until all prior bundles are present due to all external references needing to be resolved. This final step would happen as the mainchain is validated linearly as the parallel sync is proceeding. For simplicity I will also verify all the signatures during this last pass. + +At that point, to create the current utxo at any bundle boundary, it is a matter to OR all the spend vectors. That brings all the data current to the most recent bundle, which might be 1 or 1999 blocks in the past. So the final block will need to be special cased to allow it to be searched before it is in final form. + +I think that covers most of the basics. + +struct iguana_txid // 64 bytes +{ + bits256 txid; + uint32_t txidind,firstvout,firstvin,locktime,version,timestamp,extraoffset; + uint16_t numvouts,numvins; +} __attribute__((packed)); + +struct iguana_unspent // 28 bytes +{ + uint64_t value; + uint32_t txidind,pkind,prevunspentind,scriptoffset; + uint16_t hdrsi:12,type:4,vout; + } __attribute__((packed)); + +struct iguana_spend // 12 bytes +{ + uint32_t spendtxidind,scriptoffset; + int16_t prevout; + uint16_t numsigs:4,numpubkeys:4,p2sh:1,sighash:4,external:1,sequenceid:2; + } __attribute__((packed)); + +struct iguana_pkhash // 32 bytes +{ + uint8_t rmd160[20]; + uint32_t pkind,firstunspentind,pubkeyoffset; +} __attribute__((packed)); + +// dynamic during bundle creation +struct iguana_account // 12 bytes +{ + uint64_t balance; uint32_t lastunspentind; +} __attribute__((packed)); // pkind + diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c old mode 100644 new mode 100755 index f9b340fe8..64ebd198c --- a/iguana/SuperNET.c +++ b/iguana/SuperNET.c @@ -654,7 +654,8 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) //printf("SuperNET_JSON.(%s)\n",jprint(json,0)); if ( remoteaddr != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 ) remoteaddr = 0; - agent = jstr(json,"agent"); + if ( (agent = jstr(json,"agent")) == 0 ) + agent = "bitcoinrpc"; method = jstr(json,"method"); if ( agent != 0 && strcmp(agent,"pangea") == 0 && jobj(json,"categoryhash") == 0 ) { @@ -701,7 +702,7 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) } if ( (destflag & SUPERNET_ISMINE) != 0 && agent != 0 && method != 0 ) { - if ( hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) + if ( newflag == 0 && hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr); if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr)) != 0 ) { @@ -1210,11 +1211,11 @@ TWO_STRINGS(SuperNET,subscribe,category,subcategory) TWO_STRINGS(SuperNET,gethexmsg,category,subcategory) { - bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; + bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; struct category_info *cat; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); categoryhash = calc_categoryhashes(&subhash,category,subcategory); - if ( (m= category_gethexmsg(myinfo,categoryhash,subhash)) != 0 ) + if ( (m= category_gethexmsg(myinfo,&cat,categoryhash,subhash)) != 0 ) { hexstr = calloc(1,m->len*2+1); init_hexbytes_noT(hexstr,m->msg,m->len); diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h old mode 100644 new mode 100755 index d9dc58563..1d517d891 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -78,7 +78,7 @@ struct supernet_info char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64]; //int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers; - bits256 privkey,persistent_priv; char secret[2048],NXTAPIURL[512]; + bits256 privkey,persistent_priv,BTCmarkerhash; char secret[2048],NXTAPIURL[512]; uint8_t *recvbuf[6]; struct supernet_address myaddr; int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; @@ -100,21 +100,31 @@ struct supernet_info struct category_chain { - bits256 *weights,*blocks,category_hwm,cchainhash; + bits256 *weights,*blocks,category_hwm,genesishash,hwmhash; int32_t hashlen,addrlen,maxblocknum; struct supernet_info *myinfo; void *categoryinfo,*subinfo; - int32_t (*blockhash_func)(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen); - bits256 (*stake_func)(struct category_chain *cchain,void *addr,int32_t addrlen); - bits256 (*hit_func)(struct category_chain *cchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp); - bits256 (*default_func)(struct category_chain *cchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest); + int32_t (*blockhash_func)(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen); + int32_t (*payment_func)(struct category_chain *catchain,void *src,void *dest,uint64_t amount); + bits256 (*stake_func)(struct category_chain *catchain,void *addr,int32_t addrlen); + bits256 (*hit_func)(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp); + bits256 (*default_func)(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest); + int32_t (*ishwm_func)(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr); }; +struct crypto777_msghdr +{ + struct acct777_sig sig __attribute__((packed)); + bits256 prevhash,btchash; + uint8_t cmd[8]; + uint8_t serialized[]; +} __attribute__((packed)); + struct category_info { UT_hash_handle hh; queue_t Q; - char *(*processfunc)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr); - struct category_chain *cchain; + char *(*processfunc)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr); + struct category_chain *catchain; bits256 hash; void *info; struct category_info *sub; }; extern struct category_info *Categories; @@ -158,8 +168,8 @@ void *category_info(bits256 categoryhash,bits256 subhash); void *category_infoset(bits256 categoryhash,bits256 subhash,void *info); struct category_info *category_find(bits256 categoryhash,bits256 subhash); void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *json,char *hexmsg,char *remoteaddr); -struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)); -char *pangea_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr); +struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr)); +char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr); void pangea_queues(struct supernet_info *myinfo); int32_t SuperNET_str2hex(uint8_t *hex,char *str); @@ -168,19 +178,19 @@ void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits25 int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits256 subhash,char *hexmsg,int32_t addflag); void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr); void *category_subscribe(struct supernet_info *myinfo,bits256 category,bits256 subhash); -struct category_msg *category_gethexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash); +struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct category_info **catptrp,bits256 categoryhash,bits256 subhash); char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr); -queue_t *category_Q(bits256 categoryhash,bits256 subhash); +queue_t *category_Q(struct category_info **catptrp,bits256 categoryhash,bits256 subhash); char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext,cJSON *argjson,char *remoteaddr); bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); -struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func); -#define category_default_latest() (*cchain->default_func)(cchain,'L',0,0,0,0,zero) +struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func,void *ishwm_func,void *payment_func); +#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) void category_init(struct supernet_info *myinfo); char *SuperNET_keysinit(struct supernet_info *myinfo,char *jsonstr); double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double volume,cJSON *argjson); void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256); -char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *data,int32_t len,char *remoteaddr); +char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr); bits256 bitcoin_pubkey33(uint8_t data[33],bits256 privkey); char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len); diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c old mode 100644 new mode 100755 index c5ef66f9c..c56bce779 --- a/iguana/SuperNET_category.c +++ b/iguana/SuperNET_category.c @@ -57,11 +57,15 @@ struct category_info *category_find(bits256 categoryhash,bits256 subhash) return(0); } -queue_t *category_Q(bits256 categoryhash,bits256 subhash) +queue_t *category_Q(struct category_info **catptrp,bits256 categoryhash,bits256 subhash) { struct category_info *cat; + *catptrp = 0; if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + *catptrp = cat; return(&cat->Q); + } else return(0); } @@ -84,7 +88,7 @@ void *category_infoset(bits256 categoryhash,bits256 subhash,void *info) return(0); } -struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr)) +struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr)) { struct category_info *cat; if ( (cat= category_find(categoryhash,subhash)) != 0 ) @@ -95,169 +99,19 @@ struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash, return(0); } -int32_t category_default_blockhash(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen) -{ - bits256 hash; - vcalc_sha256(0,hash.bytes,data,datalen); - vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash)); - return(sizeof(*blockhashp)); -} - -bits256 category_default_stake(struct category_chain *cchain,void *addr,int32_t addrlen) -{ - bits256 stake; - memset(stake.bytes,0,sizeof(stake)); - stake.txid = ((uint64_t)1 << 63); - return(stake); -} - -bits256 catgory_default_hit(struct category_chain *cchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp) -{ - bits256 hash; bits256 rawhit,hit; - memset(rawhit.bytes,0,sizeof(rawhit)); - memset(hit.bytes,0,sizeof(hit)); - vcalc_sha256cat(hash.bytes,prevgenerator,cchain->addrlen,addr,cchain->addrlen); - hit = (*cchain->stake_func)(cchain,addr,cchain->addrlen); - rawhit.txid = hash.txid % ((uint64_t)1 << 42); - if ( rawhit.txid != 0 ) - hit.txid /= rawhit.txid; - return(hit); -} - -#define category_default_heaviest() (*cchain->default_func)(cchain,'H',0,0,0,0,zero) -#define category_default_latest() (*cchain->default_func)(cchain,'L',0,0,0,0,zero) -#define category_default_setheaviest(height,blockhashp,heaviest) (*cchain->default_func)(cchain,'S',height,0,0,blockhashp,zero) -#define category_default_weight(height) (*cchain->default_func)(cchain,'W',height,0,0,0,zero) -#define category_default_blockfind(height) (*cchain->default_func)(cchain,'B',height,0,0,0,zero) - -bits256 category_default_func(struct category_chain *cchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest) -{ - static bits256 zero; - if ( cchain->hashlen != sizeof(bits256) || cchain->addrlen != sizeof(bits256) ) - { - printf("unsupported hashlen.%d or addrlen.%d\n",cchain->hashlen,cchain->addrlen); - return(zero); - } - if ( height > cchain->maxblocknum + (func == 'S') ) - { - printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,cchain->maxblocknum,height); - return(cchain->category_hwm); - } - if ( func == 'H' ) - return(cchain->category_hwm); - else if ( func == 'L' ) - { - if ( cchain->maxblocknum < 0 ) - return(cchain->cchainhash); - else return(cchain->blocks[cchain->maxblocknum]); - } - else if ( func == 'S' ) - { - cchain->category_hwm = heaviest; - if ( height > cchain->maxblocknum ) - { - cchain->weights = realloc(cchain->weights,(cchain->maxblocknum+1) * sizeof(*cchain->weights)); - cchain->blocks = realloc(cchain->blocks,(cchain->maxblocknum+1) * sizeof(*cchain->blocks)); - } - cchain->maxblocknum = height; - cchain->weights[height] = heaviest; - if ( blockhashp != 0 ) - memcpy(&cchain->blocks[height],blockhashp,sizeof(cchain->blocks[height])); - } - else if ( func == 'B' ) - { - if ( height <= cchain->maxblocknum ) - return(cchain->blocks[height]); - else - { - printf("error: illegal height.%d vs max.%d\n",height,cchain->maxblocknum); - return(zero); - } - } - else if ( func == 'W' ) - { - if ( height >= 0 && height < cchain->maxblocknum ) - return(cchain->weights[height]); - else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,cchain->maxblocknum); - } - return(cchain->category_hwm); -} - -int32_t category_default_ishwm(struct category_chain *cchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) -{ - bits256 checkhash,prevwt,oldhit,hit,heaviest; static bits256 zero; - checkhash = category_default_blockfind(prevheight); - if ( memcmp(checkhash.bytes,prevblockhashp,cchain->hashlen) == 0 ) - { - heaviest = category_default_heaviest(); - prevwt = category_default_weight(prevheight); - oldhit = category_default_weight(prevheight+1); - hit = (*cchain->hit_func)(cchain,prevheight+1,prevgenerator,addr,blockhashp); - if ( hit.txid > oldhit.txid && prevwt.txid+hit.txid > heaviest.txid ) - { - heaviest.txid = (prevwt.txid + hit.txid); - category_default_setheaviest(prevheight+1,blockhashp,heaviest); - return(prevheight+1); - } - - } else return(-2); - return(-1); -} - -struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func) -{ - struct category_info *cat; struct category_chain *cchain = calloc(1,sizeof(*cchain)); - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - { - cchain->maxblocknum = -1; - cchain->myinfo = myinfo, cchain->subinfo = cat->info; - if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 ) - cchain->categoryinfo = cat->info, cchain->cchainhash = categoryhash; - else cchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), cchain->cchainhash = subhash; - if ( cchain->myinfo == 0 || cchain->categoryinfo || cchain->subinfo ) - { - printf("error with cchain pointers\n"); - return(0); - } - if ( (cchain->addrlen= addrlen) <= 0 || (cchain->hashlen= hashlen) <= 0 ) - { - printf("error with cchain lens.%d %d\n",addrlen,hashlen); - return(0); - } - if ( (cchain->blockhash_func= hash_func) == 0 || (cchain->stake_func= stake_func) == 0 || (cchain->hit_func= hit_func) == 0 || (cchain->default_func= default_func) == 0 ) - { - if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) ) - { - cchain->blockhash_func = category_default_blockhash; - cchain->stake_func = category_default_stake; - cchain->hit_func = catgory_default_hit; - cchain->default_func = category_default_func; - } - else - { - printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen); - return(0); - } - } - cat->cchain = cchain; - return(cchain); - } - return(0); -} - -struct category_msg *category_gethexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash) +struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct category_info **catptrp,bits256 categoryhash,bits256 subhash) { queue_t *Q; //char str[65]; printf("getmsg.(%s) %llx\n",bits256_str(str,categoryhash),(long long)subhash.txid); - if ( (Q= category_Q(categoryhash,subhash)) != 0 ) + if ( (Q= category_Q(catptrp,categoryhash,subhash)) != 0 ) return(queue_dequeue(Q,0)); else return(0); } void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr) { - int32_t len; struct category_msg *m; queue_t *Q = 0; - if ( (Q= category_Q(categoryhash,subhash)) != 0 ) + int32_t len; struct category_msg *m; queue_t *Q = 0; struct category_info *cat; + if ( (Q= category_Q(&cat,categoryhash,subhash)) != 0 ) { len = (int32_t)strlen(hexmsg) >> 1; m = calloc(1,sizeof(*m) + len); @@ -355,6 +209,6 @@ void category_init(struct supernet_info *myinfo) pangeahash = calc_categoryhashes(0,"pangea",0); category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); category_processfunc(pangeahash,GENESIS_PUBKEY,pangea_hexmsg); - category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0); + category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0,0,0); exchanges777_init(myinfo,0,0); } diff --git a/iguana/SuperNET_hexmsg.c b/iguana/SuperNET_hexmsg.c old mode 100644 new mode 100755 index cfe2108c9..876637d15 --- a/iguana/SuperNET_hexmsg.c +++ b/iguana/SuperNET_hexmsg.c @@ -40,7 +40,7 @@ int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits25 } else if ( Packetcache[i] == packethash.txid ) { - printf("SuperNET_DHTsend reject duplicate packet.%llx\n",(long long)packethash.txid); + //printf("SuperNET_DHTsend reject duplicate packet.%llx\n",(long long)packethash.txid); return(i); } } @@ -93,7 +93,7 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *j { if ( cat->processfunc != 0 ) { - if ( (str= (*cat->processfunc)(myinfo,buf,len,remoteaddr)) != 0 ) + if ( (str= (*cat->processfunc)(myinfo,cat,buf,len,remoteaddr)) != 0 ) { if ( retjson != 0 ) jaddstr(retjson,"processfunc",str); @@ -114,3 +114,277 @@ void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *j } } } + +int32_t category_default_blockhash(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,data,datalen); + vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash)); + return(sizeof(*blockhashp)); +} + +bits256 category_default_stake(struct category_chain *catchain,void *addr,int32_t addrlen) +{ + bits256 stake; + memset(stake.bytes,0,sizeof(stake)); + stake.txid = ((uint64_t)1 << 63); + return(stake); +} + +bits256 catgory_default_hit(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp) +{ + bits256 hash; bits256 rawhit,hit; + memset(rawhit.bytes,0,sizeof(rawhit)); + memset(hit.bytes,0,sizeof(hit)); + vcalc_sha256cat(hash.bytes,prevgenerator,catchain->addrlen,addr,catchain->addrlen); + hit = (*catchain->stake_func)(catchain,addr,catchain->addrlen); + rawhit.txid = hash.txid % ((uint64_t)1 << 42); + if ( rawhit.txid != 0 ) + hit.txid /= rawhit.txid; + return(hit); +} + +#define category_default_heaviest() (*catchain->default_func)(catchain,'H',0,0,0,0,zero) +#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) +#define category_default_setheaviest(height,blockhashp,heaviest) (*catchain->default_func)(catchain,'S',height,0,0,blockhashp,zero) +#define category_default_weight(height) (*catchain->default_func)(catchain,'W',height,0,0,0,zero) +#define category_default_blockfind(height) (*catchain->default_func)(catchain,'B',height,0,0,0,zero) + +bits256 category_default_func(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest) +{ + static bits256 zero; + if ( catchain->hashlen != sizeof(bits256) || catchain->addrlen != sizeof(bits256) ) + { + printf("unsupported hashlen.%d or addrlen.%d\n",catchain->hashlen,catchain->addrlen); + return(zero); + } + if ( height > catchain->maxblocknum + (func == 'S') ) + { + printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,catchain->maxblocknum,height); + return(catchain->category_hwm); + } + if ( func == 'H' ) + return(catchain->category_hwm); + else if ( func == 'L' ) + { + if ( catchain->maxblocknum < 0 ) + return(catchain->genesishash); + else return(catchain->blocks[catchain->maxblocknum]); + } + else if ( func == 'S' ) + { + catchain->category_hwm = heaviest; + if ( height > catchain->maxblocknum ) + { + catchain->weights = realloc(catchain->weights,(catchain->maxblocknum+1) * sizeof(*catchain->weights)); + catchain->blocks = realloc(catchain->blocks,(catchain->maxblocknum+1) * sizeof(*catchain->blocks)); + } + catchain->maxblocknum = height; + catchain->weights[height] = heaviest; + if ( blockhashp != 0 ) + memcpy(&catchain->blocks[height],blockhashp,sizeof(catchain->blocks[height])); + } + else if ( func == 'B' ) + { + if ( height <= catchain->maxblocknum ) + return(catchain->blocks[height]); + else + { + printf("error: illegal height.%d vs max.%d\n",height,catchain->maxblocknum); + return(zero); + } + } + else if ( func == 'W' ) + { + if ( height >= 0 && height < catchain->maxblocknum ) + return(catchain->weights[height]); + else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,catchain->maxblocknum); + } + return(catchain->category_hwm); +} + +int32_t category_default_ishwm(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) +{ + bits256 checkhash,prevwt,oldhit,hit,heaviest; static bits256 zero; + checkhash = category_default_blockfind(prevheight); + if ( memcmp(checkhash.bytes,prevblockhashp,catchain->hashlen) == 0 ) + { + heaviest = category_default_heaviest(); + prevwt = category_default_weight(prevheight); + oldhit = category_default_weight(prevheight+1); + hit = (*catchain->hit_func)(catchain,prevheight+1,prevgenerator,addr,blockhashp); + if ( hit.txid > oldhit.txid && prevwt.txid+hit.txid > heaviest.txid ) + { + heaviest.txid = (prevwt.txid + hit.txid); + category_default_setheaviest(prevheight+1,blockhashp,heaviest); + return(prevheight+1); + } + + } else return(-2); + return(-1); +} + +int32_t category_default_payment(struct category_chain *catchain,void *src,void *dest,uint64_t amount) +{ + //uint32_t srcind=0,destind=0; + // catchain->balances[destind] += amount; + // catchain->balances[srcind] -= amount; + return(0); +} + +struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func,void *ishwm_func,void *payment_func) +{ + struct category_info *cat; struct category_chain *catchain = calloc(1,sizeof(*catchain)); + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + catchain->maxblocknum = -1; + catchain->myinfo = myinfo, catchain->subinfo = cat->info; + if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 ) + catchain->categoryinfo = cat->info, catchain->genesishash = categoryhash; + else catchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), catchain->genesishash = subhash; + if ( catchain->myinfo == 0 || catchain->categoryinfo || catchain->subinfo ) + { + printf("error with catchain pointers\n"); + return(0); + } + if ( (catchain->addrlen= addrlen) <= 0 || (catchain->hashlen= hashlen) <= 0 ) + { + printf("error with catchain lens.%d %d\n",addrlen,hashlen); + return(0); + } + if ( (catchain->blockhash_func= hash_func) == 0 || (catchain->stake_func= stake_func) == 0 || (catchain->hit_func= hit_func) == 0 || (catchain->default_func= default_func) == 0 || (catchain->ishwm_func= ishwm_func) == 0 || (catchain->payment_func= payment_func) == 0 ) + { + if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) ) + { + catchain->blockhash_func = category_default_blockhash; + catchain->stake_func = category_default_stake; + catchain->hit_func = catgory_default_hit; + catchain->default_func = category_default_func; + catchain->ishwm_func = category_default_ishwm; + catchain->payment_func = category_default_payment; + } + else + { + printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen); + return(0); + } + } + cat->catchain = catchain; + return(catchain); + } + return(0); +} + +struct crypto777_msghdr *crypto777_msgcreate(struct supernet_info *myinfo,struct crypto777_msghdr *msg,int32_t datalen) +{ + bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; + memset(&msg->sig,0,sizeof(msg->sig)); + datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig)); + data = (void *)((long)msg + sizeof(msg->sig)); + otherpubkey = acct777_msgpubkey(data,datalen); + timestamp = (uint32_t)time(NULL); + acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); + if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) + { + //int32_t i; + //char str[65],str2[65]; + //for (i=0; i>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey)); + memset(buf,0,sizeof(buf)); + acct777_rwsig(1,buf,&msg->sig); + memcpy(&msg->sig,buf,sizeof(buf)); + return(msg); + } else printf("error validating crypto777_msgcreate msg\n"); + return(0); +} + +void crypto777_catchain(struct supernet_info *myinfo,struct category_info *cat,bits256 *prevhashp,bits256 *btchashp) +{ + *btchashp = myinfo->BTCmarkerhash; + *prevhashp = cat->catchain->hwmhash; +} + +char *crypto777_sendmsg(struct supernet_info *myinfo,bits256 category,bits256 subhash,uint8_t *data,int32_t datalen,int32_t hops,char cmdstr[8]) +{ + char *hexstr,*retstr; int32_t i; struct crypto777_msghdr *msg; bits256 prevhash,btchash; struct category_info *cat; + msg = calloc(1,datalen + sizeof(*msg)); + for (i=0; icmd); i++) + if ( (msg->cmd[i]= cmdstr[i]) == 0 ) + break; + cat = category_info(category,subhash); + crypto777_catchain(myinfo,cat,&prevhash,&btchash); + iguana_rwbignum(1,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); + iguana_rwbignum(1,msg->btchash.bytes,sizeof(bits256),btchash.bytes); + memcpy(msg->serialized,data,datalen); + if ( crypto777_msgcreate(myinfo,msg,datalen) != 0 ) + { + printf(">>>>>>>>>>>> crypto777_send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); + hexstr = malloc(msg->sig.allocsize*2 + 1); + init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); + retstr = SuperNET_categorymulticast(myinfo,0,category,subhash,hexstr,0,hops,1,0,0); + free(hexstr), free(msg); + return(retstr); + } + else + { + free(msg); + printf("cant crypto777 msgcreate datalen.%d\n",datalen); + return(clonestr("{\"error\":\"couldnt create crypto777 message\"}")); + } +} + +char *crypto777_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr) +{ + struct crypto777_msghdr *msg = ptr; int32_t slen,datalen,newlen,flag = 0; bits256 prevhash,btchash; + uint8_t *serdata; uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; cJSON *argjson = 0; + datalen = len - (int32_t)sizeof(msg->sig); + serdata = (void *)((long)msg + sizeof(msg->sig)); + acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); + memcpy(&msg->sig,tmp,sizeof(msg->sig)); + /*if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) + { + printf("string crypto777_hexmsg RESULT.(%s)\n",jprint(argjson,0)); + free_json(argjson); + return(clonestr("{\"error\":\"string base packets deprecated\"}")); + } + else*/ if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 ) + { + flag++; + iguana_rwbignum(0,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); + iguana_rwbignum(0,msg->btchash.bytes,sizeof(bits256),btchash.bytes); + printf("crypto777_hexmsg <<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); + newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); + serdata = msg->serialized; + if ( (argjson= cJSON_Parse((char *)serdata)) != 0 ) + { + slen = (int32_t)strlen((char *)serdata) + 1; + serdata = &serdata[slen]; + newlen -= slen; + free_json(argjson); + } + } + return(clonestr("{\"result\":\"test packet\"}")); +} + +/* + Consensus rules: + 0. Valid burn protocol or new issuance with small fee to crypto777 account -> OP_RETURN on BTCD with txid of payment/burn + Ti boundary - Balances reconciled and signed by issuer or super majority vote. Only amounts marked as frozen eligible for atomic swaps. + tx via p2p, signed payment to dest acct, based on balance. no outputs to double spend + payment valid during Ti and Ti+1 + atomic cross chain: both sides freeze trade amount, wait for this to be confirmed in BTC OP_RETURN, then a joint swap tx is signed by both and submitted to both chains + + valid tx must be accepted and sig added with Ti slippage. It is valid if signed, and balance is available. + + When Ti boundary changes, all online nodes reconcile the submitted tx to make sure all are confirmed and balances updated. Special tx like freezing, atomics, etc. + +Top PoS account publishes balance changes and majority stake approves. Next trade period starts at Ti+2 + + Split into odd/even offset periods to allow nonstop tx + + 1. all nodes must ntp and all tx must be timestamped within 50 seconds in the past and cant be more than 10 seconds from the future. + 2. tx spends cannot exceed available balance/2 as of prior Ti. + 2. all tx must refer to the latest BTC.Ti and BTCD.Ti and BTC.RTblock. any tx received that has older BTC.Ti is rejected. + 3. +*/ diff --git a/iguana/SuperNET_keys.c b/iguana/SuperNET_keys.c old mode 100644 new mode 100755 diff --git a/iguana/app/coin_mgmt.js b/iguana/app/coin_mgmt.js old mode 100644 new mode 100755 diff --git a/iguana/app/common.js b/iguana/app/common.js old mode 100644 new mode 100755 diff --git a/iguana/app/startup.js b/iguana/app/startup.js old mode 100644 new mode 100755 diff --git a/iguana/confs/.tmpmarker b/iguana/confs/.tmpmarker old mode 100644 new mode 100755 diff --git a/iguana/confs/BTCD_hdrs.txt b/iguana/confs/BTCD_hdrs.txt old mode 100644 new mode 100755 diff --git a/iguana/confs/BTCD_peers.txt b/iguana/confs/BTCD_peers.txt old mode 100644 new mode 100755 diff --git a/iguana/confs/BTC_hdrs.txt b/iguana/confs/BTC_hdrs.txt old mode 100644 new mode 100755 diff --git a/iguana/confs/BTC_peers.txt b/iguana/confs/BTC_peers.txt old mode 100644 new mode 100755 diff --git a/iguana/css/googleFonts.css b/iguana/css/googleFonts.css old mode 100644 new mode 100755 diff --git a/iguana/css/googleIcons.css b/iguana/css/googleIcons.css old mode 100644 new mode 100755 diff --git a/iguana/css/googleTheme.css b/iguana/css/googleTheme.css old mode 100644 new mode 100755 diff --git a/iguana/css/jquery.dropdown.css b/iguana/css/jquery.dropdown.css old mode 100644 new mode 100755 diff --git a/iguana/css/ripples.css b/iguana/css/ripples.css old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/docs/about.md b/iguana/docs/supernet/docs/about.md old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/docs/index.md b/iguana/docs/supernet/docs/index.md old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/mkdocs.yml b/iguana/docs/supernet/mkdocs.yml old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/about/index.html b/iguana/docs/supernet/site/about/index.html old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/css/highlight.css b/iguana/docs/supernet/site/css/highlight.css old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/css/theme.css b/iguana/docs/supernet/site/css/theme.css old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/css/theme_extra.css b/iguana/docs/supernet/site/css/theme_extra.css old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/fonts/fontawesome-webfont.eot b/iguana/docs/supernet/site/fonts/fontawesome-webfont.eot old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/fonts/fontawesome-webfont.svg b/iguana/docs/supernet/site/fonts/fontawesome-webfont.svg old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/fonts/fontawesome-webfont.ttf b/iguana/docs/supernet/site/fonts/fontawesome-webfont.ttf old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/fonts/fontawesome-webfont.woff b/iguana/docs/supernet/site/fonts/fontawesome-webfont.woff old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/img/favicon.ico b/iguana/docs/supernet/site/img/favicon.ico old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/index.html b/iguana/docs/supernet/site/index.html old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/js/highlight.pack.js b/iguana/docs/supernet/site/js/highlight.pack.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/js/jquery-2.1.1.min.js b/iguana/docs/supernet/site/js/jquery-2.1.1.min.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/js/modernizr-2.8.3.min.js b/iguana/docs/supernet/site/js/modernizr-2.8.3.min.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/js/theme.js b/iguana/docs/supernet/site/js/theme.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/license/highlight.js/LICENSE b/iguana/docs/supernet/site/license/highlight.js/LICENSE old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/mkdocs/js/lunr-0.5.7.min.js b/iguana/docs/supernet/site/mkdocs/js/lunr-0.5.7.min.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/mkdocs/js/mustache.min.js b/iguana/docs/supernet/site/mkdocs/js/mustache.min.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/mkdocs/js/require.js b/iguana/docs/supernet/site/mkdocs/js/require.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/mkdocs/js/search-results-template.mustache b/iguana/docs/supernet/site/mkdocs/js/search-results-template.mustache old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/mkdocs/js/search.js b/iguana/docs/supernet/site/mkdocs/js/search.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/mkdocs/js/text.js b/iguana/docs/supernet/site/mkdocs/js/text.js old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/mkdocs/search_index.json b/iguana/docs/supernet/site/mkdocs/search_index.json old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/search.html b/iguana/docs/supernet/site/search.html old mode 100644 new mode 100755 diff --git a/iguana/docs/supernet/site/sitemap.xml b/iguana/docs/supernet/site/sitemap.xml old mode 100644 new mode 100755 diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index 49d7dbedf..b2c854f41 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -14,307 +14,10 @@ ******************************************************************************/ #include "bitcoin.h" +cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap); static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; -#define IGUANA_SCRIPT_NULL 0 -#define IGUANA_SCRIPT_76AC 1 -#define IGUANA_SCRIPT_76A988AC 2 -#define IGUANA_SCRIPT_P2SH 3 -#define IGUANA_SCRIPT_OPRETURN 4 -#define IGUANA_SCRIPT_3of3 5 -#define IGUANA_SCRIPT_2of3 6 -#define IGUANA_SCRIPT_1of3 7 -#define IGUANA_SCRIPT_2of2 8 -#define IGUANA_SCRIPT_1of2 9 -#define IGUANA_SCRIPT_MSIG 10 -#define IGUANA_SCRIPT_DATA 11 -#define IGUANA_SCRIPT_STRANGE 15 - -enum opcodetype -{ - // push value - OP_0 = 0x00, - OP_FALSE = OP_0, - OP_PUSHDATA1 = 0x4c, - OP_PUSHDATA2 = 0x4d, - OP_PUSHDATA4 = 0x4e, - OP_1NEGATE = 0x4f, - OP_RESERVED = 0x50, - OP_1 = 0x51, - OP_TRUE=OP_1, - OP_2 = 0x52, - OP_3 = 0x53, - OP_4 = 0x54, - OP_5 = 0x55, - OP_6 = 0x56, - OP_7 = 0x57, - OP_8 = 0x58, - OP_9 = 0x59, - OP_10 = 0x5a, - OP_11 = 0x5b, - OP_12 = 0x5c, - OP_13 = 0x5d, - OP_14 = 0x5e, - OP_15 = 0x5f, - OP_16 = 0x60, - - // control - OP_NOP = 0x61, - OP_VER = 0x62, - OP_IF = 0x63, - OP_NOTIF = 0x64, - OP_VERIF = 0x65, - OP_VERNOTIF = 0x66, - OP_ELSE = 0x67, - OP_ENDIF = 0x68, - OP_VERIFY = 0x69, - OP_RETURN = 0x6a, - - // stack ops - OP_TOALTSTACK = 0x6b, - OP_FROMALTSTACK = 0x6c, - OP_2DROP = 0x6d, - OP_2DUP = 0x6e, - OP_3DUP = 0x6f, - OP_2OVER = 0x70, - OP_2ROT = 0x71, - OP_2SWAP = 0x72, - OP_IFDUP = 0x73, - OP_DEPTH = 0x74, - OP_DROP = 0x75, - OP_DUP = 0x76, - OP_NIP = 0x77, - OP_OVER = 0x78, - OP_PICK = 0x79, - OP_ROLL = 0x7a, - OP_ROT = 0x7b, - OP_SWAP = 0x7c, - OP_TUCK = 0x7d, - - // splice ops - OP_CAT = 0x7e, - OP_SUBSTR = 0x7f, - OP_LEFT = 0x80, - OP_RIGHT = 0x81, - OP_SIZE = 0x82, - - // bit logic - OP_INVERT = 0x83, - OP_AND = 0x84, - OP_OR = 0x85, - OP_XOR = 0x86, - OP_EQUAL = 0x87, - OP_EQUALVERIFY = 0x88, - OP_RESERVED1 = 0x89, - OP_RESERVED2 = 0x8a, - - // numeric - OP_1ADD = 0x8b, - OP_1SUB = 0x8c, - OP_2MUL = 0x8d, - OP_2DIV = 0x8e, - OP_NEGATE = 0x8f, - OP_ABS = 0x90, - OP_NOT = 0x91, - OP_0NOTEQUAL = 0x92, - - OP_ADD = 0x93, - OP_SUB = 0x94, - OP_MUL = 0x95, - OP_DIV = 0x96, - OP_MOD = 0x97, - OP_LSHIFT = 0x98, - OP_RSHIFT = 0x99, - - OP_BOOLAND = 0x9a, - OP_BOOLOR = 0x9b, - OP_NUMEQUAL = 0x9c, - OP_NUMEQUALVERIFY = 0x9d, - OP_NUMNOTEQUAL = 0x9e, - OP_LESSTHAN = 0x9f, - OP_GREATERTHAN = 0xa0, - OP_LESSTHANOREQUAL = 0xa1, - OP_GREATERTHANOREQUAL = 0xa2, - OP_MIN = 0xa3, - OP_MAX = 0xa4, - - OP_WITHIN = 0xa5, - - // crypto - OP_RIPEMD160 = 0xa6, - OP_SHA1 = 0xa7, - OP_SHA256 = 0xa8, - OP_HASH160 = 0xa9, - OP_HASH256 = 0xaa, - OP_CODESEPARATOR = 0xab, - OP_CHECKSIG = 0xac, - OP_CHECKSIGVERIFY = 0xad, - OP_CHECKMULTISIG = 0xae, - OP_CHECKMULTISIGVERIFY = 0xaf, - - // expansion - OP_NOP1 = 0xb0, - OP_NOP2 = 0xb1, - OP_NOP3 = 0xb2, - OP_NOP4 = 0xb3, - OP_NOP5 = 0xb4, - OP_NOP6 = 0xb5, - OP_NOP7 = 0xb6, - OP_NOP8 = 0xb7, - OP_NOP9 = 0xb8, - OP_NOP10 = 0xb9, - - // template matching params - OP_SMALLINTEGER = 0xfa, - OP_PUBKEYS = 0xfb, - OP_PUBKEYHASH = 0xfd, - OP_PUBKEY = 0xfe, - - OP_INVALIDOPCODE = 0xff, -}; - -const char *get_opname(int32_t *extralenp,enum opcodetype opcode) -{ - *extralenp = 0; - switch (opcode) - { - // push value - case OP_0 : return "0"; - case OP_PUSHDATA1 : *extralenp = 1; return "OP_PUSHDATA1"; - case OP_PUSHDATA2 : *extralenp = 2; return "OP_PUSHDATA2"; - case OP_PUSHDATA4 : *extralenp = 4; return "OP_PUSHDATA4"; - case OP_1NEGATE : return "-1"; - case OP_RESERVED : return "OP_RESERVED"; - case OP_1 : return "1"; - case OP_2 : return "2"; - case OP_3 : return "3"; - case OP_4 : return "4"; - case OP_5 : return "5"; - case OP_6 : return "6"; - case OP_7 : return "7"; - case OP_8 : return "8"; - case OP_9 : return "9"; - case OP_10 : return "10"; - case OP_11 : return "11"; - case OP_12 : return "12"; - case OP_13 : return "13"; - case OP_14 : return "14"; - case OP_15 : return "15"; - case OP_16 : return "16"; - - // control - case OP_NOP : return "OP_NOP"; - case OP_VER : return "OP_VER"; - case OP_IF : return "OP_IF"; - case OP_NOTIF : return "OP_NOTIF"; - case OP_VERIF : return "OP_VERIF"; - case OP_VERNOTIF : return "OP_VERNOTIF"; - case OP_ELSE : return "OP_ELSE"; - case OP_ENDIF : return "OP_ENDIF"; - case OP_VERIFY : return "OP_VERIFY"; - case OP_RETURN : return "OP_RETURN"; - - // stack ops - case OP_TOALTSTACK : return "OP_TOALTSTACK"; - case OP_FROMALTSTACK : return "OP_FROMALTSTACK"; - case OP_2DROP : return "OP_2DROP"; - case OP_2DUP : return "OP_2DUP"; - case OP_3DUP : return "OP_3DUP"; - case OP_2OVER : return "OP_2OVER"; - case OP_2ROT : return "OP_2ROT"; - case OP_2SWAP : return "OP_2SWAP"; - case OP_IFDUP : return "OP_IFDUP"; - case OP_DEPTH : return "OP_DEPTH"; - case OP_DROP : return "OP_DROP"; - case OP_DUP : return "OP_DUP"; - case OP_NIP : return "OP_NIP"; - case OP_OVER : return "OP_OVER"; - case OP_PICK : return "OP_PICK"; - case OP_ROLL : return "OP_ROLL"; - case OP_ROT : return "OP_ROT"; - case OP_SWAP : return "OP_SWAP"; - case OP_TUCK : return "OP_TUCK"; - - // splice ops - case OP_CAT : return "OP_CAT"; - case OP_SUBSTR : return "OP_SUBSTR"; - case OP_LEFT : return "OP_LEFT"; - case OP_RIGHT : return "OP_RIGHT"; - case OP_SIZE : return "OP_SIZE"; - - // bit logic - case OP_INVERT : return "OP_INVERT"; - case OP_AND : return "OP_AND"; - case OP_OR : return "OP_OR"; - case OP_XOR : return "OP_XOR"; - case OP_EQUAL : return "OP_EQUAL"; - case OP_EQUALVERIFY : return "OP_EQUALVERIFY"; - case OP_RESERVED1 : return "OP_RESERVED1"; - case OP_RESERVED2 : return "OP_RESERVED2"; - - // numeric - case OP_1ADD : return "OP_1ADD"; - case OP_1SUB : return "OP_1SUB"; - case OP_2MUL : return "OP_2MUL"; - case OP_2DIV : return "OP_2DIV"; - case OP_NEGATE : return "OP_NEGATE"; - case OP_ABS : return "OP_ABS"; - case OP_NOT : return "OP_NOT"; - case OP_0NOTEQUAL : return "OP_0NOTEQUAL"; - case OP_ADD : return "OP_ADD"; - case OP_SUB : return "OP_SUB"; - case OP_MUL : return "OP_MUL"; - case OP_DIV : return "OP_DIV"; - case OP_MOD : return "OP_MOD"; - case OP_LSHIFT : return "OP_LSHIFT"; - case OP_RSHIFT : return "OP_RSHIFT"; - case OP_BOOLAND : return "OP_BOOLAND"; - case OP_BOOLOR : return "OP_BOOLOR"; - case OP_NUMEQUAL : return "OP_NUMEQUAL"; - case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY"; - case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL"; - case OP_LESSTHAN : return "OP_LESSTHAN"; - case OP_GREATERTHAN : return "OP_GREATERTHAN"; - case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL"; - case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL"; - case OP_MIN : return "OP_MIN"; - case OP_MAX : return "OP_MAX"; - case OP_WITHIN : return "OP_WITHIN"; - - // crypto - case OP_RIPEMD160 : return "OP_RIPEMD160"; - case OP_SHA1 : return "OP_SHA1"; - case OP_SHA256 : return "OP_SHA256"; - case OP_HASH160 : return "OP_HASH160"; - case OP_HASH256 : return "OP_HASH256"; - case OP_CODESEPARATOR : return "OP_CODESEPARATOR"; - case OP_CHECKSIG : return "OP_CHECKSIG"; - case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY"; - case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; - case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; - - // expanson - case OP_NOP1 : return "OP_NOP1"; - case OP_NOP2 : return "OP_NOP2"; - case OP_NOP3 : return "OP_NOP3"; - case OP_NOP4 : return "OP_NOP4"; - case OP_NOP5 : return "OP_NOP5"; - case OP_NOP6 : return "OP_NOP6"; - case OP_NOP7 : return "OP_NOP7"; - case OP_NOP8 : return "OP_NOP8"; - case OP_NOP9 : return "OP_NOP9"; - case OP_NOP10 : return "OP_NOP10"; - - case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; - // Note: - // The template matching params OP_SMALLDATA/etc are defined in opcodetype enum - // as kind of implementation hack, they are *NOT* real opcodes. If found in real - // Script, just let the default: case deal with them. - default: return "OP_UNKNOWN"; - } -} - char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params) { return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params)); @@ -481,11 +184,11 @@ void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen) char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len) { - int32_t i; uint8_t data[25]; bits256 hash; char checkaddr[65]; + int32_t i; uint8_t data[25]; bits256 hash;// char checkaddr[65]; if ( len != 20 ) calc_rmd160_sha256(data+1,pubkey,len); else memcpy(data+1,pubkey,20); - btc_convrmd160(checkaddr,addrtype,data+1); + //btc_convrmd160(checkaddr,addrtype,data+1); //for (i=0; i<20; i++) // printf("%02x",data[i+1]); //printf(" RMD160 len.%d\n",len); @@ -495,10 +198,10 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t le data[21+i] = hash.bytes[31-i]; if ( (coinaddr= bitcoin_base58encode(coinaddr,data,25)) != 0 ) { - uint8_t checktype,rmd160[20]; - bitcoin_addr2rmd160(&checktype,rmd160,coinaddr); - if ( strcmp(checkaddr,coinaddr) != 0 ) - printf("checkaddr.(%s) vs coinaddr.(%s) %02x vs [%02x] memcmp.%d\n",checkaddr,coinaddr,addrtype,checktype,memcmp(rmd160,data+1,20)); + //uint8_t checktype,rmd160[20]; + //bitcoin_addr2rmd160(&checktype,rmd160,coinaddr); + //if ( strcmp(checkaddr,coinaddr) != 0 ) + // printf("checkaddr.(%s) vs coinaddr.(%s) %02x vs [%02x] memcmp.%d\n",checkaddr,coinaddr,addrtype,checktype,memcmp(rmd160,data+1,20)); } return(coinaddr); } @@ -649,385 +352,6 @@ int32_t bitcoin_verify(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen return(retval); } -int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]) -{ - int32_t scriptlen = bitcoin_pubkeylen(pubkey); - script[n++] = scriptlen; - memcpy(&script[n],pubkey,scriptlen); - n += scriptlen; - script[n++] = SCRIPT_OP_CHECKSIG; - return(n); -} - -int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) -{ - script[n++] = SCRIPT_OP_HASH160; - script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14; - script[n++] = SCRIPT_OP_EQUAL; - return(n); -} - -int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]) -{ - script[n++] = SCRIPT_OP_HASH160; - script[n++] = 0x14; memcpy(&script[n],secret160,0x14); n += 0x14; - script[n++] = SCRIPT_OP_EQUALVERIFY; - return(n); -} - -int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) -{ - script[n++] = SCRIPT_OP_DUP; - script[n++] = SCRIPT_OP_HASH160; - script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14; - script[n++] = SCRIPT_OP_EQUALVERIFY; - script[n++] = SCRIPT_OP_CHECKSIG; - return(n); -} - -int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime) -{ - script[n++] = (locktime >> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime; - script[n++] = SCRIPT_OP_CHECKLOCKTIMEVERIFY; - script[n++] = SCRIPT_OP_DROP; - return(n); -} - -int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp) -{ - int32_t i,plen; - script[n++] = 0x50 + vp->M; - for (i=0; iN; i++) - { - if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 ) - return(-1); - script[n++] = plen; - memcpy(&script[n],vp->signers[i].pubkey,plen); - n += plen; - } - script[n++] = 0x50 + vp->N; - script[n++] = SCRIPT_OP_CHECKMULTISIG; - calc_rmd160_sha256(p2sh_rmd160,script,n); - return(n); -} - -int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,const int32_t p2shlen) -{ - if ( p2shlen >= 0xfd ) - { - script[n++] = 0x4d; - script[n++] = (p2shlen & 0xff); - script[n++] = ((p2shlen >> 8) & 0xff); - } - else - { - script[n++] = 0x4c; - script[n++] = p2shlen; - } - memcpy(&script[n],p2shscript,p2shlen), n += p2shlen; - return(n); -} - -int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee) -{ - uint8_t addrtype,rmd160[20]; int32_t len; - *changep = 0; - if ( inputsatoshis >= (satoshis + txfee) ) - { - *changep = inputsatoshis - (satoshis + txfee); - if ( changeaddr != 0 && changeaddr[0] != 0 ) - { - bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); - if ( addrtype == coin->chain->pubtype ) - len = bitcoin_standardspend(changescript,0,rmd160); - else if ( addrtype == coin->chain->p2shtype ) - len = bitcoin_standardspend(changescript,0,rmd160); - else - { - printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype); - return(-1); - } - return(len); - } - else printf("error no change address when there is change\n"); - } - return(-1); -} - -int32_t bitcoin_scriptsig(struct iguana_info *coin,uint8_t *script,int32_t n,const struct vin_info *vp,struct iguana_msgtx *msgtx) -{ - int32_t i,siglen; - if ( vp->N > 1 ) - script[n++] = SCRIPT_OP_NOP; - for (i=0; iN; i++) - { - if ( (siglen= vp->signers[i].siglen) != 0 ) - { - script[n++] = siglen; - memcpy(&script[n],vp->signers[i].sig,siglen), n += siglen; - } - } - if ( vp->type == IGUANA_SCRIPT_P2SH ) - { - printf("add p2sh script to sig\n"); - n = bitcoin_p2shscript(script,n,vp->p2shscript,vp->p2shlen); - } - return(n); -} - -int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime) -{ - // OP_IF - // OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG - // OP_ELSE - // OP_HASH160 secret160 OP_EQUALVERIFY OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG // standard spend - // OP_ENDIF - uint8_t rmd160A[20],rmd160B[20],addrtypeA,addrtypeB; - bitcoin_addr2rmd160(&addrtypeA,rmd160A,senderaddr); - bitcoin_addr2rmd160(&addrtypeB,rmd160B,otheraddr); - script[n++] = SCRIPT_OP_IF; - n = bitcoin_checklocktimeverify(script,n,locktime); - n = bitcoin_standardspend(script,n,rmd160A); - script[n++] = SCRIPT_OP_ELSE; - n = bitcoin_revealsecret160(script,n,secret160); - n = bitcoin_standardspend(script,n,rmd160B); - script[n++] = SCRIPT_OP_ENDIF; - calc_rmd160_sha256(p2sh_rmd160,script,n); - bitcoin_address(ps2h_coinaddr,p2shtype,p2sh_rmd160,20); - return(n); -} - -int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi) -{ - uint8_t addrtype; char rmd160str[41],pubkeystr[256]; int32_t plen,i,m,n,flag = 0,scriptlen = 0; - m = n = 1; - asmstr[0] = 0; - if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH ) - { - if ( type == IGUANA_SCRIPT_P2SH ) - addrtype = coin->chain->p2shtype; - else addrtype = coin->chain->pubtype; - init_hexbytes_noT(rmd160str,rmd160,20); - btc_convrmd160(coinaddr,addrtype,rmd160); - } - switch ( type ) - { - case IGUANA_SCRIPT_NULL: - strcpy(asmstr,txi == 0 ? "coinbase " : "PoSbase "); - flag++; - coinaddr[0] = 0; - break; - case IGUANA_SCRIPT_76AC: - if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) < 0 ) - return(0); - init_hexbytes_noT(pubkeystr,(uint8_t *)vp->signers[0].pubkey,plen); - sprintf(asmstr,"OP_DUP %s OP_CHECKSIG // %s",pubkeystr,coinaddr); - scriptlen = bitcoin_pubkeyspend(script,0,(uint8_t *)vp->signers[0].pubkey); - printf("[%02x] scriptlen.%d (%s)\n",vp->signers[0].pubkey[0],scriptlen,asmstr); - break; - case IGUANA_SCRIPT_76A988AC: - sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr); - scriptlen = bitcoin_standardspend(script,0,rmd160); - break; - case IGUANA_SCRIPT_P2SH: - sprintf(asmstr,"OP_HASH160 %s OP_EQUAL // %s",rmd160str,coinaddr); - scriptlen = bitcoin_p2shspend(script,0,rmd160); - break; - case IGUANA_SCRIPT_OPRETURN: - strcpy(asmstr,"OP_RETURN "); - flag++; - break; - case IGUANA_SCRIPT_3of3: m = 3, n = 3; break; - case IGUANA_SCRIPT_2of3: m = 2, n = 3; break; - case IGUANA_SCRIPT_1of3: m = 1, n = 3; break; - case IGUANA_SCRIPT_2of2: m = 2, n = 2; break; - case IGUANA_SCRIPT_1of2: m = 1, n = 2; break; - case IGUANA_SCRIPT_MSIG: m = vp->M, n = vp->N; break; - case IGUANA_SCRIPT_DATA: - strcpy(asmstr,"DATA ONLY"); - flag++; - break; - case IGUANA_SCRIPT_STRANGE: - strcpy(asmstr,"STRANGE SCRIPT "); - flag++; - break; - default: printf("unexpected script type\n"); break; - } - if ( n > 1 ) - { - scriptlen = bitcoin_MofNspendscript(rmd160,script,0,vp); - sprintf(asmstr,"%d ",m); - for (i=0; isigners[i].pubkey)) > 0 ) - { - init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->signers[i].pubkey,plen); - strcat(asmstr," "); - } else strcat(asmstr,"NOPUBKEY "); - } - sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n); - for (i=0; isigners[i].coinaddr,ispendlen > 0 ) - init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->spendscript,vp->spendlen); - *Mp = m, *nump = n; - return(scriptlen); -} - -int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen) -{ - asmstr[0] = 0; - return(0); -} - -int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) -{ - static uint8_t zero_rmd160[20]; - char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen; - vp->N = 1; - vp->M = 1; - type = IGUANA_SCRIPT_STRANGE; - if ( vp->spendlen == 0 ) - { - if ( zero_rmd160[0] == 0 ) - { - calc_rmd160_sha256(zero_rmd160,vp->spendscript,vp->spendlen); - //vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - //calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb - init_hexbytes_noT(hexstr,zero_rmd160,20); - char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr); - } - memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); - return(IGUANA_SCRIPT_NULL); - } - else if ( vp->spendscript[0] == SCRIPT_OP_RETURN ) - type = IGUANA_SCRIPT_OPRETURN; - else if ( vp->spendscript[0] == SCRIPT_OP_DUP && vp->spendscript[1] == SCRIPT_OP_HASH160 && vp->spendscript[2] == 20 && vp->spendscript[vp->spendscript[2]+3] == SCRIPT_OP_EQUALVERIFY && vp->spendscript[vp->spendscript[2]+4] == SCRIPT_OP_CHECKSIG ) - { - //printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d vp->spendlen\n",vp->spendscript[2]+4,vp->spendlen); - // 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac - //vcalc_sha256(0,sha256,&vp->spendscript[3],vp->spendscript[2]); - //calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256)); - memcpy(vp->rmd160,&vp->spendscript[3],20); - if ( (plen= vp->spendscript[2]+5) < vp->spendlen ) - { - while ( plen < vp->spendlen ) - if ( vp->spendscript[plen++] != 0x61 ) // nop - return(IGUANA_SCRIPT_STRANGE); - } - return(IGUANA_SCRIPT_76A988AC); - } - // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac - else if ( vp->spendscript[0] > 0 && vp->spendscript[0] < 76 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == vp->spendlen-2 ) - { - memcpy(vp->signers[0].pubkey,&vp->spendscript[1],vp->spendscript[0]); - calc_rmd160_sha256(vp->rmd160,vp->signers[0].pubkey,vp->spendscript[0]); - return(IGUANA_SCRIPT_76AC); - } - else if ( vp->spendscript[0] == SCRIPT_OP_HASH160 && vp->spendscript[1] == 0x14 && vp->spendlen == 23 && vp->spendscript[22] == SCRIPT_OP_EQUAL ) - { - memcpy(vp->rmd160,vp->spendscript+2,20); - return(IGUANA_SCRIPT_P2SH); - } - else if ( vp->spendlen > 34 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKMULTISIG && (n= vp->spendscript[vp->spendlen-2]) >= 0x51 && n <= 0x60 && (m= vp->spendscript[0]) >= 0x51 && m <= n ) // m of n multisig - { - m -= 0x50, n -= 0x50; - script = vp->spendscript+1; - for (i=0; isigners[i].pubkey,script,plen); - calc_rmd160_sha256(vp->signers[i].rmd160,vp->signers[i].pubkey,plen); - bitcoin_address(vp->signers[i].coinaddr,coin->chain->pubtype,vp->signers[i].pubkey,plen); - } - if ( (int32_t)((long)script - (long)vp->spendscript) == vp->spendlen-2 ) - { - vp->N = n; - vp->M = m; - //printf("M.%d N.%d\n",m,n); - } - calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); - if ( n == 3 ) - { - if ( m == 3 ) - return(IGUANA_SCRIPT_3of3); - else if ( m == 2 ) - return(IGUANA_SCRIPT_2of3); - else if ( m == 1 ) - return(IGUANA_SCRIPT_1of3); - } - else if ( n == 2 ) - { - if ( m == 2 ) - return(IGUANA_SCRIPT_2of2); - else if ( m == 1 ) - return(IGUANA_SCRIPT_1of2); - } - printf("strange msig M.%d of N.%d\n",m,n); - return(IGUANA_SCRIPT_MSIG); - } - else if ( vp->spendlen == vp->spendscript[0]+1 ) - { - //printf("just data.%d\n",vp->spendlen); - memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); - return(IGUANA_SCRIPT_DATA); - } - if ( type != IGUANA_SCRIPT_OPRETURN && type != IGUANA_SCRIPT_DATA ) - { - if ( vp->spendlen > 0 && vp->spendlen < sizeof(hexstr)/2-1 ) - { - static FILE *fp; - init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); - //char str[65]; printf("unparsed script.(%s).%d in %s len.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen); - if ( 1 && fp == 0 ) - fp = fopen("unparsed.txt","w"); - if ( fp != 0 ) - fprintf(fp,"%s\n",hexstr), fflush(fp); - } else sprintf(hexstr,"pkscript overflowed %ld\n",(long)sizeof(hexstr)); - } - calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); - return(type); -} - -int32_t iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence) -{ - int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; char asmstr[IGUANA_MAXSCRIPTSIZE*3]; - memset(vp,0,sizeof(*vp)); - vp->vin.prev_hash = debugtxid, vp->vin.prev_vout = vout; - vp->spendlen = pk_scriptlen; - vp->vin.sequence = sequence; - memcpy(vp->spendscript,pk_script,pk_scriptlen); - if ( (vp->type= _iguana_calcrmd160(coin,vp)) >= 0 && 0 ) - { - scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vout); - if ( scriptlen != pk_scriptlen || (scriptlen != 0 && memcmp(script,pk_script,scriptlen) != 0) ) - { - if ( vp->type != IGUANA_SCRIPT_OPRETURN && vp->type != IGUANA_SCRIPT_DATA && vp->type != IGUANA_SCRIPT_STRANGE ) - { - int32_t i; - printf("\n--------------------\n"); - for (i=0; itype,scriptlen,pk_scriptlen); - } - } - } - return(vp->type); -} - int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj) { int32_t len = 0; cJSON *skey; char *hexstr; @@ -1065,7 +389,7 @@ int32_t iguana_parsevinobj(struct iguana_info *coin,uint8_t *serialized,int32_t { len = (int32_t)strlen(hexstr) >> 1; decode_hex(serialized,len,hexstr); - vin->sigscript = serialized; + vin->vinscript = serialized; vin->scriptlen = len; serialized = &serialized[len]; } //else printf("iguana_parsevinobj: hex script missing (%s)\n",jprint(vinobj,0)); @@ -1156,13 +480,13 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) vout = vin->prev_vout; jaddnum(json,"sequence",vin->sequence); if ( vout < 0 && bits256_nonz(vin->prev_hash) == 0 ) - iguana_addscript(coin,json,vin->sigscript,vin->scriptlen,"coinbase"); + iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"coinbase"); else { jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); jaddnum(json,"vout",vout); if ( vin->scriptlen > 0 ) - iguana_addscript(coin,json,vin->sigscript,vin->scriptlen,"scriptSig"); + iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"scriptSig"); if ( vin->spendlen > 0 ) iguana_addscript(coin,json,vin->spendscript,vin->spendlen,"scriptPub"); } @@ -1177,14 +501,14 @@ int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *seriali len += iguana_rwvarint32(rwflag,&serialized[len],&msg->scriptlen); if ( rwflag == 0 ) { - msg->sigscript = &serialized[len]; + msg->vinscript = &serialized[len]; len += msg->scriptlen; } else { if ( msg->scriptlen > 0 ) { - memcpy(&serialized[len],msg->sigscript,msg->scriptlen); + memcpy(&serialized[len],msg->vinscript,msg->scriptlen); len += msg->scriptlen; } } @@ -1193,8 +517,8 @@ int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *seriali { int32_t i; char str[65]; for (i=0; iscriptlen; i++) - printf("%02x",msg->sigscript[i]); - printf(" prev_hash.(%s) vout.%d [%p] scriptlen.%d rwflag.%d\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->sigscript,msg->scriptlen,rwflag); + printf("%02x",msg->vinscript[i]); + printf(" prev_hash.(%s) vout.%d [%p] scriptlen.%d rwflag.%d\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->vinscript,msg->scriptlen,rwflag); } return(len); } @@ -1233,7 +557,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 if ( coin->chain->hastimestamp != 0 ) { len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); - char str[65]; printf("timestamp.%08x %u %s\n",msg->timestamp,msg->timestamp,utc_str(str,msg->timestamp)); + //char str[65]; printf("timestamp.%08x %u %s\n",msg->timestamp,msg->timestamp,utc_str(str,msg->timestamp)); if ( json != 0 ) jaddnum(json,"timestamp",msg->timestamp); } @@ -1396,56 +720,10 @@ char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,struct iguana_msgtx return(txbytes); } -int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t type) -{ - char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; - j = n = 0; - *hashtypep = SIGHASH_ALL; - while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen+1 < len && j < 16 ) - { - vp->signers[j].siglen = siglen; - memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen); - if ( j == 0 ) - *hashtypep = vp->signers[j].sig[siglen-1]; - n += (siglen + 1); - j++; - if ( type == 0 && j > 1 ) - type = IGUANA_SCRIPT_MSIG; - } - vp->type = type; - j = 0; - while ( ((plen= scriptsig[n]) == 33 || plen == 65 ) && j < 16 ) - { - memcpy(vp->signers[j].pubkey,&scriptsig[n+1],plen); - calc_rmd160_sha256(vp->signers[j].rmd160,vp->signers[j].pubkey,plen); - if ( j == 0 ) - memcpy(vp->rmd160,vp->signers[j].rmd160,20); - n += (plen + 1); - j++; - } - if ( n < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) - { - if ( scriptsig[n] == 0x4c ) - vp->p2shlen = scriptsig[n+1], n += 2; - else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; - memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); - vp->type = IGUANA_SCRIPT_P2SH; - } - /*if ( len == 0 ) - { - // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1 - decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe"); - vp->type = IGUANA_SCRIPT_76A988AC; - }*/ - vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); - //printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); - return(vp->spendlen); -} - int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,int32_t sighashsingle) { bits256 txid,sigtxid,revsigtxid; uint8_t *sig,*pubkey; struct vin_info *vp; - char txidstr[128],bigstr[2560],coinaddr[64],vpnstr[64],str[65]; + char txidstr[128],bigstr[2560],coinaddr[64],vpnstr[64],str[65]; uint32_t suffixlen,sigsize,pubkeysize; int32_t n2,i,j,k,plen,vini=0,flag,numvins,hashtype,retval,siglen,asmtype,numvouts; numvouts = msgtx->tx_out; vpnstr[0] = 0; @@ -1455,16 +733,16 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char ** retval = -numvins; for (vini=0; vinivins[vini].sigscript; + //saveinput = msgtx->vins[vini].vinscript; vp = &V[vini]; - sig = &msgtx->vins[vini].sigscript[1]; - siglen = msgtx->vins[vini].sigscript[0]; + sig = &msgtx->vins[vini].vinscript[1]; + siglen = msgtx->vins[vini].vinscript[0]; vp->vin = msgtx->vins[vini]; flag = 0; for (k=0; k<2; k++) { asmtype = (k == 0) ? IGUANA_SCRIPT_76A988AC : IGUANA_SCRIPT_76AC; - if ( bitcoin_scriptget(coin,&hashtype,vp,msgtx->vins[vini].sigscript,msgtx->vins[vini].scriptlen,asmtype) < 0 ) + if ( bitcoin_scriptget(coin,&hashtype,&sigsize,&pubkeysize,&suffixlen,vp,msgtx->vins[vini].vinscript,msgtx->vins[vini].scriptlen,asmtype) < 0 ) { printf("cant get script for (%s).v%d\n",bits256_str(str,vp->vin.prev_hash),vp->vin.prev_vout); continue; @@ -1499,7 +777,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char ** if ( n2 > 0 ) { n2 += iguana_rwnum(1,&serialized[n2],sizeof(hashtype),&hashtype); - printf("hashtype.%d [%02x]\n",hashtype,sig[siglen-1]); + //printf("hashtype.%d [%02x]\n",hashtype,sig[siglen-1]); revsigtxid = bits256_doublesha256(txidstr,serialized,n2); for (i=0; isigners[j].sig; sig[siglen++] = hashtype; vp->signers[j].siglen = siglen; - msgtx->vins[vini].sigscript = calloc(1,siglen*2+256); // fix this memleak! - msgtx->vins[vini].scriptlen = bitcoin_scriptsig(coin,msgtx->vins[vini].sigscript,0,(const struct vin_info *)vp,msgtx); - for (i=0; ivins[vini].vinscript = calloc(1,siglen*2+256); // fix this memleak! + msgtx->vins[vini].scriptlen = bitcoin_scriptsig(coin,msgtx->vins[vini].vinscript,0,(const struct vin_info *)vp,msgtx); + //for (i=0; isigners[j].pubkey,bitcoin_pubkeylen(vp->signers[j].pubkey)) < 0 ) { @@ -1528,7 +806,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char ** cJSON *txobj = cJSON_CreateObject(); *signedtx = iguana_rawtxbytes(coin,txobj,msgtx); *signedtxidp = msgtx->txid; - printf("SIG.%d VERIFIED %s (%s)\n",vini,*signedtx,jprint(txobj,1)); + //printf("SIG.%d VERIFIED %s (%s)\n",vini,*signedtx,jprint(txobj,1)); flag = 1; break; } @@ -1591,12 +869,12 @@ cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_ms msgtx = &M; memset(msgtx,0,sizeof(M)); } - len = (int32_t)strlen(txbytes) + 32768; - serialized = malloc(len); + len = (int32_t)strlen(txbytes); + serialized = malloc(len + 32768); decode_hex(serialized,len,txbytes); vpnstr[0] = 0; memset(txidp,0,sizeof(*txidp)); - if ( (n= iguana_rwmsgtx(coin,0,txobj,serialized,len,msgtx,txidp,vpnstr)) <= 0 ) + if ( (n= iguana_rwmsgtx(coin,0,txobj,serialized,len + 32768,msgtx,txidp,vpnstr)) <= 0 ) { printf("error from rwmsgtx\n"); free_json(txobj); @@ -1636,11 +914,11 @@ cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *payments hexstr = malloc(len*2 + 1); init_hexbytes_noT(hexstr,paymentscript,len); jaddstr(skey,"hex",hexstr); + //printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0)); free(hexstr); jadd(item,"scriptPubkey",skey); jaddi(vouts,item); jadd(txobj,"vout",vouts); - printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0)); return(txobj); } @@ -1656,7 +934,7 @@ cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32 jaddnum(item,"sequence",sequence); jaddi(vins,item); jadd(txobj,"vin",vins); - printf("addvin -> (%s)\n",jprint(txobj,0)); + //printf("addvin -> (%s)\n",jprint(txobj,0)); return(txobj); } @@ -1887,7 +1165,7 @@ rawtxstr = refstr; if ( bitcoin_verifytx(coin,&signedtxid,&signedtx,rawtxstr,V) != 0 ) printf("bitcoin_verifytx error\n"); jadd(retjson,"result",txjson); - if ( (tp= iguana_txidfind(coin,&height,&T,txid)) != 0 ) + if ( (tp= iguana_txidfind(coin,&height,&T,txid,coin->bundlescount-1)) != 0 ) { if ( height >= 0 ) { @@ -1992,7 +1270,7 @@ struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct i } } } - printf("numunspents.%d -> %d total %.8f\n",*numunspentsp,n,dstr(total)); + //printf("numunspents.%d -> %d total %.8f\n",*numunspentsp,n,dstr(total)); *numunspentsp = n; free_json(utxo); } else printf("error parsing.(%s)\n",retstr); @@ -2030,6 +1308,7 @@ double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchang bids = cJSON_CreateArray(); asks = cJSON_CreateArray(); instantdex_offerfind(SuperNET_MYINFO(0),exchange,bids,asks,0,base,rel,1); + //printf("bids.(%s) asks.(%s)\n",jprint(bids,0),jprint(asks,0)); retjson = cJSON_CreateObject(); cJSON_AddItemToObject(retjson,"bids",bids); cJSON_AddItemToObject(retjson,"asks",asks); @@ -2098,7 +1377,8 @@ int32_t is_valid_BTCother(char *other) uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson) { - char *str,coinaddr[64]; uint64_t txid = 0; cJSON *tmp,*json=0; struct instantdex_accept *ap; + char *str,*retstr,coinaddr[64]; uint64_t txid = 0; cJSON *json=0; + struct instantdex_accept *ap; struct supernet_info *myinfo; uint8_t pubkey[33]; struct iguana_info *other; myinfo = SuperNET_accountfind(argjson); //printf("TRADE with myinfo.%p\n",myinfo); @@ -2139,26 +1419,13 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha jaddnum(json,dir > 0 ? "maxprice" : "minprice",price); jaddnum(json,"volume",volume); jaddstr(json,"BTC",myinfo->myaddr.BTC); + jaddnum(json,"minperc",jdouble(argjson,"minperc")); //printf("trade dir.%d (%s/%s) %.6f vol %.8f\n",dir,base,"BTC",price,volume); - if ( (str= instantdex_queueaccept(myinfo,&ap,exchange,base,"BTC",price,volume,-dir,dir > 0 ? "BTC" : base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,0)) != 0 && ap != 0 ) - { - if ( (tmp= cJSON_Parse(str)) != 0 ) - { - txid = j64bits(json,"orderid"); - if ( (str= instantdex_sendoffer(myinfo,exchange,ap,json)) != 0 ) - { - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - //queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0); - json = cJSON_CreateObject(); - printf("from TRADE\n"); - jaddstr(json,"BTCoffer",str); - } else printf("null return from btcoffer\n"); - free_json(tmp); - } else printf("queueaccept return parse error.(%s)\n",str); - } else printf("null return queueaccept\n"); + if ( (str= instantdex_createaccept(myinfo,&ap,exchange,base,"BTC",price,volume,-dir,dir > 0 ? "BTC" : base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,0,jdouble(argjson,"minperc"))) != 0 && ap != 0 ) + retstr = instantdex_checkoffer(myinfo,&txid,exchange,ap,json), free(str); + else printf("null return queueaccept\n"); if ( retstrp != 0 ) - *retstrp = jprint(json,1); - else free_json(json); + *retstrp = retstr; } } return(txid); @@ -2166,32 +1433,35 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha char *ORDERSTATUS(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson) { - struct instantdex_accept *ap; cJSON *retjson = cJSON_CreateObject(); + struct instantdex_accept *ap; struct bitcoin_swapinfo *swap; cJSON *retjson; + retjson = cJSON_CreateObject(); struct supernet_info *myinfo = SuperNET_accountfind(argjson); - if ( (ap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) - jadd(retjson,"result",instantdex_statemachinejson(ap)); + if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + jadd(retjson,"result",instantdex_statemachinejson(swap)); else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) jadd(retjson,"result",instantdex_acceptjson(ap)); - else if ( (ap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 ) - jadd(retjson,"result",instantdex_historyjson(ap)); + else if ( (swap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 ) + jadd(retjson,"result",instantdex_historyjson(swap)); else jaddstr(retjson,"error","couldnt find orderid"); return(jprint(retjson,1)); } char *CANCELORDER(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson) { - struct instantdex_accept *ap = 0; cJSON *retjson; + struct instantdex_accept *ap = 0; cJSON *retjson; struct bitcoin_swapinfo *swap=0; struct supernet_info *myinfo = SuperNET_accountfind(argjson); retjson = cJSON_CreateObject(); if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) - jadd(retjson,"orderid",instantdex_acceptjson(ap)); - else if ( (ap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) - jadd(retjson,"orderid",instantdex_statemachinejson(ap)); - if ( ap != 0 ) { ap->dead = (uint32_t)time(NULL); + jadd(retjson,"orderid",instantdex_acceptjson(ap)); jaddstr(retjson,"result","killed orderid, but might have pending"); - } else jaddstr(retjson,"error","couldnt find orderid"); + } + else if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + { + jadd(retjson,"orderid",instantdex_statemachinejson(swap)); + jaddstr(retjson,"result","killed statemachine orderid, but might have pending"); + } return(jprint(retjson,1)); } @@ -2210,13 +1480,13 @@ char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson) char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson) { - struct instantdex_accept PAD,*ap; cJSON *retjson = cJSON_CreateArray(); + struct bitcoin_swapinfo PAD,*swap; cJSON *retjson = cJSON_CreateArray(); memset(&PAD,0,sizeof(PAD)); queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); - while ( (ap= queue_dequeue(&exchange->historyQ,0)) != 0 && ap != &PAD ) + while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD ) { - jaddi(retjson,instantdex_historyjson(ap)); - queue_enqueue("historyQ",&exchange->historyQ,&ap->DL,0); + jaddi(retjson,instantdex_historyjson(swap)); + queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); } return(jprint(retjson,1)); } diff --git a/iguana/exchanges/bitcoin.h b/iguana/exchanges/bitcoin.h index 2032b5d36..d098ebcbc 100755 --- a/iguana/exchanges/bitcoin.h +++ b/iguana/exchanges/bitcoin.h @@ -43,6 +43,21 @@ #define SCRIPT_OP_CHECKSEQUENCEVERIFY 0xb2 #define SCRIPT_OP_CHECKLOCKTIMEVERIFY 0xb1 +#define IGUANA_SCRIPT_NULL 0 +#define IGUANA_SCRIPT_76AC 1 +#define IGUANA_SCRIPT_76A988AC 2 +#define IGUANA_SCRIPT_P2SH 3 +#define IGUANA_SCRIPT_OPRETURN 4 +#define IGUANA_SCRIPT_3of3 5 +#define IGUANA_SCRIPT_2of3 6 +#define IGUANA_SCRIPT_1of3 7 +#define IGUANA_SCRIPT_2of2 8 +#define IGUANA_SCRIPT_1of2 9 +#define IGUANA_SCRIPT_MSIG 10 +#define IGUANA_SCRIPT_DATA 11 +#define IGUANA_SCRIPT_STRANGE 15 + +#define IGUANA_MAXSCRIPTSIZE 10001 struct bp_key { EC_KEY *k; }; @@ -57,5 +72,13 @@ int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]); int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); +int32_t bitcoin_pubkeylen(const uint8_t *pubkey); +int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *suffixp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype); +int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen); +int32_t bitcoin_scriptsig(struct iguana_info *coin,uint8_t *script,int32_t n,const struct vin_info *vp,struct iguana_msgtx *msgtx); +char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33); + + + #endif diff --git a/iguana/exchanges/nxtae.c b/iguana/exchanges/nxtae.c index fe620bc1c..592532f30 100755 --- a/iguana/exchanges/nxtae.c +++ b/iguana/exchanges/nxtae.c @@ -725,6 +725,7 @@ uint64_t submit_triggered_nxtae(struct supernet_info *myinfo,int32_t dotrade,cha } if ( (jsonstr= issue_NXTPOST(cmd)) != 0 ) { + printf("NXT.(%s) -> (%s)\n",cmd,jsonstr); _stripwhite(jsonstr,' '); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index b02369a96..bca353d8d 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -19,6 +19,18 @@ #include #include +#define INSTANTDEX_DECKSIZE 2000 +#define INSTANTDEX_HOPS 2 +#define INSTANTDEX_DURATION 60 + +#define INSTANTDEX_INSURANCERATE (1. / 777.) +#define INSTANTDEX_PUBEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" +#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" +#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" +#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" +#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" +#define INSTANTDEX_MINPERC 50. + #define INSTANTDEX_OFFERDURATION 300 #define INSTANTDEX_LOCKTIME 3600 @@ -90,19 +102,63 @@ struct exchange_request struct exchange_quote bidasks[]; }; -struct instantdex_offer { char base[24],rel[24]; uint64_t price64,basevolume64,offer64; uint32_t expiration,nonce; char myside,acceptdir; }; +struct instantdex_offer +{ + char base[24],rel[24]; + uint64_t price64,basevolume64,offer64; + uint32_t expiration,nonce; + char myside,acceptdir,minperc,pad; +}; + struct instantdex_accept { - struct queueitem DL; void *info; - uint64_t pendingvolume64,otherorderid,orderid,matchid; uint32_t dead; int32_t didstate; - struct instantdex_offer otheroffer,offer; + struct queueitem DL; + uint64_t pendingvolume64,orderid; + uint32_t dead; int32_t didstate; + struct instantdex_offer offer; +}; + +struct bitcoin_statetx +{ + bits256 txid; + uint64_t amount,change,inputsum; + double numconfirms; + char destaddr[64]; + char txbytes[]; }; +struct bitcoin_swapinfo +{ + struct queueitem DL; + struct instantdex_accept mine,other; + bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn; + bits256 myorderhash,otherorderhash,mypubkey,othertrader; + uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; + uint64_t altsatoshis,BTCsatoshis,insurance,altpremium,matched64; + int32_t isinitiator,choosei,otherchoosei,cutverified,otherverifiedcut; + struct bitcoin_statetx *deposit,*payment,*altpayment,*myfee,*otherfee; + char expectedcmdstr[16],status[16],waitfortx[16]; + struct instantdex_stateinfo *state; uint32_t expiration,dead,reftime; +}; + +struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; }; + +struct instantdex_stateinfo +{ + char name[24]; int16_t ind,initialstate; + cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); + cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); + int16_t timeoutind,errorind; + struct instantdex_event *events; int32_t numevents; +}; + +#define instantdex_isbob(swap) (swap)->mine.offer.myside + struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue); cJSON *instantdex_acceptjson(struct instantdex_accept *ap); -cJSON *instantdex_statemachinejson(struct instantdex_accept *ap); -cJSON *instantdex_historyjson(struct instantdex_accept *ap); -struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits,double minperc); +cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap); +struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid); +struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc); void *curl_post(void **cHandlep,char *url,char *userpass,char *postfields,char *hdr0,char *hdr1,char *hdr2,char *hdr3); char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t allfields,int32_t depth,cJSON *argjson,int32_t monitor,double commission); @@ -119,12 +175,11 @@ double truefx_price(struct exchange_info *exchange,char *base,char *rel,struct e double fxcm_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert); double instaforex_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert); -char *instantdex_queueaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t txid,int32_t queueflag); +char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag,uint8_t minperc); void instantdex_update(struct supernet_info *myinfo); char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extra,int32_t extralen); char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson); // Bob sending to network (Alice) -char *instantdex_selectqueue(struct exchange_info *exchange,struct instantdex_accept *ap,char *retstr); -struct instantdex_accept *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid); -struct instantdex_accept *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag); +struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag); +char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *json); #endif diff --git a/iguana/fonts/MaterialIcons-Regular.woff2 b/iguana/fonts/MaterialIcons-Regular.woff2 old mode 100644 new mode 100755 diff --git a/iguana/fonts/Roboto-Bold.woff2 b/iguana/fonts/Roboto-Bold.woff2 old mode 100644 new mode 100755 diff --git a/iguana/fonts/Roboto-Light.woff2 b/iguana/fonts/Roboto-Light.woff2 old mode 100644 new mode 100755 diff --git a/iguana/fonts/Roboto-Medium.woff2 b/iguana/fonts/Roboto-Medium.woff2 old mode 100644 new mode 100755 diff --git a/iguana/fonts/Roboto-Regular.woff2 b/iguana/fonts/Roboto-Regular.woff2 old mode 100644 new mode 100755 diff --git a/iguana/form-widget.html b/iguana/form-widget.html old mode 100644 new mode 100755 diff --git a/iguana/help/agent.md b/iguana/help/agent.md old mode 100644 new mode 100755 diff --git a/iguana/help/bootstrap-theme.min.css b/iguana/help/bootstrap-theme.min.css old mode 100644 new mode 100755 diff --git a/iguana/help/bootstrap.min.css b/iguana/help/bootstrap.min.css old mode 100644 new mode 100755 diff --git a/iguana/help/bootstrap.min.js b/iguana/help/bootstrap.min.js old mode 100644 new mode 100755 diff --git a/iguana/help/field.html b/iguana/help/field.html old mode 100644 new mode 100755 diff --git a/iguana/help/field.md b/iguana/help/field.md old mode 100644 new mode 100755 diff --git a/iguana/help/footer.html b/iguana/help/footer.html old mode 100644 new mode 100755 diff --git a/iguana/help/footer.md b/iguana/help/footer.md old mode 100644 new mode 100755 diff --git a/iguana/help/formfooter.html b/iguana/help/formfooter.html old mode 100644 new mode 100755 diff --git a/iguana/help/formfooter.md b/iguana/help/formfooter.md old mode 100644 new mode 100755 diff --git a/iguana/help/formheader.html b/iguana/help/formheader.html old mode 100644 new mode 100755 diff --git a/iguana/help/formheader.md b/iguana/help/formheader.md old mode 100644 new mode 100755 diff --git a/iguana/help/header.html b/iguana/help/header.html old mode 100644 new mode 100755 diff --git a/iguana/help/header.md b/iguana/help/header.md old mode 100644 new mode 100755 diff --git a/iguana/help/html5shiv.min.js b/iguana/help/html5shiv.min.js old mode 100644 new mode 100755 diff --git a/iguana/help/jquery-ui.css b/iguana/help/jquery-ui.css old mode 100644 new mode 100755 diff --git a/iguana/help/jquery-ui.min.js b/iguana/help/jquery-ui.min.js old mode 100644 new mode 100755 diff --git a/iguana/help/jquery.min.js b/iguana/help/jquery.min.js old mode 100644 new mode 100755 diff --git a/iguana/help/mime.json b/iguana/help/mime.json old mode 100644 new mode 100755 diff --git a/iguana/help/respond.min.js b/iguana/help/respond.min.js old mode 100644 new mode 100755 diff --git a/iguana/icon128.jpg b/iguana/icon128.jpg old mode 100644 new mode 100755 diff --git a/iguana/icon128.png b/iguana/icon128.png old mode 100644 new mode 100755 diff --git a/iguana/iguana.sources b/iguana/iguana.sources index b2fd43338..422a1cbab 100755 --- a/iguana/iguana.sources +++ b/iguana/iguana.sources @@ -1,3 +1,3 @@ #iguana_html.c -SOURCES := SuperNET.c SuperNET_keys.c SuperNET_category.c SuperNET_hexmsg.c peggy.c peggy_consensus.c peggy_price.c peggy_update.c peggy_accts.c peggy_tx.c peggy_txind.c peggy_ramkv.c peggy_serdes.c iguana_exchanges.c iguana_tradebots.c iguana_instantdex.c pangea_api.c pangea_bets.c cards777.c pangea_summary.c pangea_json.c pangea_hand.c poker.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c +SOURCES := iguana_rpc.c SuperNET.c SuperNET_keys.c SuperNET_category.c SuperNET_hexmsg.c iguana_exchanges.c iguana_tradebots.c iguana_instantdex.c pangea_api.c pangea_bets.c cards777.c pangea_summary.c pangea_json.c pangea_hand.c poker.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_scripts.c iguana_pubkeys.c iguana_unspents.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c peggy.c peggy_consensus.c peggy_price.c peggy_update.c peggy_accts.c peggy_tx.c peggy_txind.c peggy_ramkv.c peggy_serdes.c diff --git a/iguana/iguana777.c b/iguana/iguana777.c index dc65d875f..2e23b1e28 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -15,7 +15,7 @@ #include "iguana777.h" -const char *Hardcoded_coins[][3] = { { "BTC", "bitcoin", "0" }, { "BTCD", "BitcoinDark", "129" }, { "VPN", "VPNcoin", "129" }, { "LTC", "litecoin", "129" } }; +const char *Hardcoded_coins[][3] = { { "BTC", "bitcoin", "0" }, { "BTCD", "BitcoinDark", "129" }, { "VPN", "VPNcoin", "129" }, { "LTC", "litecoin", "129" } , { "endmarker", "", "" } }; struct iguana_info *iguana_coinfind(const char *symbol) { @@ -28,7 +28,7 @@ struct iguana_info *iguana_coinfind(const char *symbol) return(0); } -struct iguana_info *iguana_coinadd(const char *symbol) +struct iguana_info *iguana_coinadd(const char *symbol,cJSON *argjson) { struct iguana_info *coin; int32_t i = 0; if ( symbol == 0 ) @@ -41,7 +41,6 @@ struct iguana_info *iguana_coinadd(const char *symbol) if ( Coins[i] == 0 ) { Coins[i] = mycalloc('c',1,sizeof(*Coins[i])); - //memset(Coins[i],0,sizeof(*Coins[i])); printf("iguana_coin.(new) -> %p\n",Coins[i]); return(Coins[i]); } return(0); @@ -52,20 +51,29 @@ struct iguana_info *iguana_coinadd(const char *symbol) { for (i=0; i= sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) || Hardcoded_coins[i][0] == 0 ) + if ( i >= sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) break; - if ( strcmp(symbol,Hardcoded_coins[i][0]) == 0 ) + //printf("Hardcoded_coins[i][0] %s vs.(%s)\n",Hardcoded_coins[i][0],symbol); + //if ( symbol[0] == 0 ) + // getchar(); + if ( strcmp("endmarker",Hardcoded_coins[i][0]) == 0 || strcmp(symbol,Hardcoded_coins[i][0]) == 0 ) { if ( Coins[i] == 0 ) Coins[i] = mycalloc('c',1,sizeof(*Coins[i])); coin = Coins[i]; if ( coin->chain == 0 ) { - strcpy(coin->name,Hardcoded_coins[i][1]); - //coin->myservices = atoi(Hardcoded_coins[i][2]); + if ( i < sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) + strcpy(coin->name,Hardcoded_coins[i][1]); + else if (argjson != 0 ) + { + if ( jstr(argjson,"name") != 0 ) + safecopy(coin->name,jstr(argjson,"name"),sizeof(coin->name)); + else strcpy(coin->name,symbol); + } + coin->chain = iguana_chainfind((char *)symbol,argjson,1); strcpy(coin->symbol,symbol); - coin->chain = iguana_chainfind(coin->symbol); - iguana_initcoin(coin); + iguana_initcoin(coin,argjson); } return(coin); } @@ -89,7 +97,7 @@ void iguana_recvalloc(struct iguana_info *coin,int32_t numitems) { //coin->blocks.ptrs = myrealloc('W',coin->blocks.ptrs,coin->blocks.ptrs==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.ptrs),numitems * sizeof(*coin->blocks.ptrs)); coin->blocks.RO = myrealloc('W',coin->blocks.RO,coin->blocks.RO==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.RO),numitems * sizeof(*coin->blocks.RO)); - printf("realloc waitingbits.%d -> %d\n",coin->blocks.maxbits,numitems); + //printf("realloc waitingbits.%d -> %d\n",coin->blocks.maxbits,numitems); coin->blocks.maxbits = numitems; } @@ -138,6 +146,7 @@ int32_t iguana_peermetrics(struct iguana_info *coin) addr = &coin->peers.active[i]; if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 ) continue; + addr->pendblocks = 0; if ( addr->recvblocks > coin->peers.mostreceived ) coin->peers.mostreceived = addr->recvblocks; //printf("[%.0f %.0f] ",addr->recvblocks,addr->recvtotal); @@ -199,16 +208,29 @@ void *iguana_kviAddriterator(struct iguana_info *coin,struct iguanakv *kv,struct uint32_t iguana_updatemetrics(struct iguana_info *coin) { - char fname[512],tmpfname[512],oldfname[512]; int32_t i; struct iguana_peer *addr; FILE *fp; + char fname[512],tmpfname[512],oldfname[512],ipaddr[64]; int32_t i,j; struct iguana_peer *addr,*tmpaddr; FILE *fp; iguana_peermetrics(coin); sprintf(fname,"confs/%s_peers.txt",coin->symbol), OS_compatible_path(fname); sprintf(oldfname,"confs/%s_oldpeers.txt",coin->symbol), OS_compatible_path(oldfname); - sprintf(tmpfname,"tmp/%s/peers.txt",coin->symbol), OS_compatible_path(tmpfname); + sprintf(tmpfname,"%s/%s/peers.txt",GLOBALTMPDIR,coin->symbol), OS_compatible_path(tmpfname); if ( (fp= fopen(tmpfname,"w")) != 0 ) { for (i=0; ipeers.numranked; i++) - if ( (addr= coin->peers.ranked[i]) != 0 && strcmp(addr->ipaddr,"127.0.0.1") != 0 ) - fprintf(fp,"%s\n",addr->ipaddr); + { + if ( (addr= coin->peers.ranked[i]) != 0 && addr->relayflag != 0 && strcmp(addr->ipaddr,"127.0.0.1") != 0 ) + { + for (j=0; jpeers.numranked; j++) + { + if ( i != 0 && (tmpaddr= coin->peers.ranked[j]) != 0 && (uint32_t)addr->ipbits == (uint32_t)tmpaddr->ipbits ) + break; + } + if ( j == coin->peers.numranked ) + { + expand_ipbits(ipaddr,(uint32_t)addr->ipbits); + fprintf(fp,"%s\n",ipaddr); + } + } + } if ( ftell(fp) > OS_filesize(fname) ) { printf("new peers.txt %ld vs (%s) %ld\n",ftell(fp),fname,(long)OS_filesize(fname)); @@ -229,8 +251,8 @@ void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp) ptr->bp = bp, ptr->hdrsi = bp->hdrsi; ptr->type = 'E'; ptr->starttime = (uint32_t)time(NULL); - //printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); - queue_enqueue("helperQ",&helperQ,&ptr->DL,0); + printf("%s EMIT.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); + queue_enqueue("emitQ",&emitQ,&ptr->DL,0); } void iguana_mergeQ(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_bundle *nextbp) @@ -259,10 +281,40 @@ void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t ti ptr->starttime = (uint32_t)time(NULL); ptr->timelimit = timelimit; coin->numbundlesQ++; - //printf("%s bundle.%d[%d] emitfinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->emitfinish); + //printf("%s %p bundle.%d[%d] ht.%d emitfinish.%u\n",coin->symbol,bp,ptr->hdrsi,bp->n,bp->bundleheight,bp->emitfinish); queue_enqueue("bundlesQ",&bundlesQ,&ptr->DL,0); } +void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp) +{ + struct iguana_helper *ptr; + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 'V'; + ptr->starttime = (uint32_t)time(NULL); + ptr->timelimit = 0; + //printf("VALIDATE Q %s bundle.%d[%d] utxofinish.%u balancefinish.%u\n",coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); + queue_enqueue("validateQ",&validateQ,&ptr->DL,0); +} + +void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp) +{ + struct iguana_helper *ptr; + ptr = mycalloc('i',1,sizeof(*ptr)); + ptr->allocsize = sizeof(*ptr); + ptr->coin = coin; + ptr->bp = bp, ptr->hdrsi = bp->hdrsi; + ptr->type = 'B'; + ptr->starttime = (uint32_t)time(NULL); + ptr->timelimit = 0; + bp->balancefinish = 1; + coin->pendbalances++; + //printf("BALANCES Q[%d] %s bundle.%d[%d] balances.%u balancefinish.%u\n",coin->pendbalances,coin->symbol,ptr->hdrsi,bp->n,bp->utxofinish,bp->balancefinish); + queue_enqueue("balancesQ",&balancesQ,&ptr->DL,0); +} + int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_helper *ptr) { struct iguana_info *coin; struct iguana_peer *addr; struct iguana_bundle *bp,*nextbp; @@ -271,6 +323,8 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m { if ( (bp= ptr->bp) != 0 ) { + if ( time(NULL) > bp->nexttime ) + return(0); if ( 0 && ptr->type == 'M' ) { if ( (nextbp= ptr->nextbp) != 0 ) @@ -282,35 +336,49 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m } else if ( ptr->type == 'B' ) { - iguana_bundleiters(coin,bp,ptr->timelimit); + iguana_bundleiters(coin,mem,memB,bp,ptr->timelimit); } else if ( ptr->type == 'E' ) { - //printf("emitQ coin.%p bp.%p\n",ptr->coin,ptr->bp); if ( iguana_bundlesaveHT(coin,mem,memB,bp,ptr->starttime) == 0 ) { - bp->emitfinish = (uint32_t)time(NULL); + //fprintf(stderr,"emitQ coin.%p bp.[%d]\n",ptr->coin,bp->bundleheight); + bp->emitfinish = (uint32_t)time(NULL) + 1; coin->numemitted++; - } - else bp->emitfinish = 0; + } else bp->emitfinish = 0; } } else printf("no bundle in helperrequest\n"); } else printf("no coin in helperrequest\n"); return(0); } +void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp) +{ + uint32_t starttime; + starttime = (uint32_t)time(NULL); + if ( iguana_balancegen(coin,bp) < 0 ) + { + printf("GENERATE BALANCES ERROR ht.%d\n",bp->bundleheight); + exit(-1); + } + bp->balancefinish = (uint32_t)time(NULL); + printf("GENERATED BALANCES for ht.%d duration %d seconds\n",bp->bundleheight,bp->balancefinish - (uint32_t)starttime); + iguana_validateQ(coin,bp); +} + void iguana_helper(void *arg) { - FILE *fp = 0; char fname[512],name[64],*helpername = 0; cJSON *argjson=0; int32_t flag; + FILE *fp = 0; char fname[512],name[64],*helpername = 0; cJSON *argjson=0; int32_t type,flag,idle=0; struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) helpername = jstr(argjson,"name"); if ( helpername == 0 ) { - sprintf(name,"helper.%d",rand()); + sprintf(name,"%d",rand()); helpername = name; } - sprintf(fname,"tmp/%s",helpername); + type = (name[0] % 2); + sprintf(fname,"%s/%s",GLOBALTMPDIR,helpername); OS_compatible_path(fname); fp = fopen(fname,"wb"); if ( argjson != 0 ) @@ -321,30 +389,87 @@ void iguana_helper(void *arg) { //iguana_jsonQ(); flag = 0; - if ( (ptr= queue_dequeue(&helperQ,0)) != 0 ) + if ( ((ptr= queue_dequeue(&emitQ,0)) != 0 || (ptr= queue_dequeue(&helperQ,0)) != 0) ) { - if ( (coin= ptr->coin) != 0 && myallocated(0,-1) > coin->MAXMEM ) - queue_enqueue("reQ",&helperQ,&ptr->DL,0); - else + if ( ptr->bp != 0 && (coin= ptr->coin) != 0 ) { + idle = 0; coin->helperdepth++; iguana_helpertask(fp,&MEM,MEMB,ptr); coin->helperdepth--; - myfree(ptr,ptr->allocsize); + flag++; } + myfree(ptr,ptr->allocsize); + } + else if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) + { + idle = 0; + if ( ptr->bp != 0 && ptr->coin != 0 ) + flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,ptr->bp,ptr->timelimit); + else printf("helper missing param? %p %p %u\n",ptr->coin,ptr->bp,ptr->timelimit); + myfree(ptr,ptr->allocsize); flag++; } else { - if ( (ptr= queue_dequeue(&bundlesQ,0)) != 0 ) + if ( (ptr= queue_dequeue(&validateQ,0)) != 0 ) { if ( ptr->bp != 0 && ptr->coin != 0 ) - flag += iguana_bundleiters(ptr->coin,ptr->bp,ptr->timelimit); + flag += iguana_bundlevalidate(ptr->coin,ptr->bp); + else printf("helper validate missing param? %p %p\n",ptr->coin,ptr->bp); myfree(ptr,ptr->allocsize); + flag++; } } if ( flag == 0 ) - sleep(10); + usleep(1000000); + else usleep(100000); + } +} + +void iguana_coinflush(struct iguana_info *coin,int32_t forceflag) +{ + int32_t hdrsi,blen; struct iguana_bundle *bp; char fname[1024],fname2[1024]; FILE *fp,*fp2=0; + memset(coin->bundlebits,0,sizeof(coin->bundlebits)); + for (hdrsi=0; hdrsibundlescount; hdrsi++) + if ( (bp= coin->bundles[hdrsi]) != 0 && bp->validated != 0 ) + SETBIT(coin->bundlebits,hdrsi); + blen = (int32_t)hconv_bitlen(coin->bundlescount); + for (hdrsi=0; hdrsibundlescount; hdrsi++) + { + if ( (bp= coin->bundles[hdrsi]) != 0 && (forceflag != 0 || (bp->dirty != 0 && time(NULL) > bp->dirty+60)) && bp->ramchain.H.data != 0 && bp->ramchain.A != 0 && bp->ramchain.Uextras != 0 ) + { + if ( forceflag == 0 ) + { + sprintf(fname,"accounts/%s/debits.%d",coin->symbol,bp->bundleheight); + sprintf(fname2,"accounts/%s/lastspends.%d",coin->symbol,bp->bundleheight); + } + else + { + sprintf(fname,"DB/%s/accounts/debits_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); + sprintf(fname2,"DB/%s/accounts/lastspends_%d.%d",coin->symbol,coin->bundlescount,bp->bundleheight); + } + //printf("save (%s) and (%s) %p %p\n",fname,fname2,bp,bp->ramchain.H.data);//,bp->ramchain.H.data->numpkinds,bp->ramchain.H.data->numunspents); + if ( (fp= fopen(fname,"wb")) != 0 && (fp2= fopen(fname2,"wb")) != 0 ) + { + if ( fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp) == sizeof(coin->bundlescount) && fwrite(&coin->bundlescount,1,sizeof(coin->bundlescount),fp2) == sizeof(coin->bundlescount) && fwrite(coin->bundlebits,1,blen,fp) == blen && fwrite(coin->bundlebits,1,blen,fp2) == blen ) + { + if ( fwrite(bp->ramchain.A,sizeof(*bp->ramchain.A),bp->ramchain.H.data->numpkinds,fp) == bp->ramchain.H.data->numpkinds ) + { + if ( fwrite(bp->ramchain.Uextras,sizeof(*bp->ramchain.Uextras),bp->ramchain.H.data->numunspents,fp2) == bp->ramchain.H.data->numunspents ) + { + bp->dirty = 0; + printf("saved (%s) and (%s)\n",fname,fname2); + } + } + } + fclose(fp), fclose(fp2); + if ( bp->dirty != 0 ) + printf("error writing %s\n",fname); + } + else if ( fp != 0 ) + fclose(fp); + } } } @@ -369,14 +494,12 @@ void iguana_coinloop(void *arg) coin = coins[0]; iguana_rwiAddrind(coin,0,0,0); iguana_possible_peer(coin,"127.0.0.1"); - //while ( 1 ) sleep(1); - memset(zero.bytes,0,sizeof(zero)); if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) bp->bundleheight = 0; while ( 1 ) { - //printf("iter\n"); + //fprintf(stderr,"iter\n"); flag = 0; for (i=0; iactive != 0 ) { - if ( coin->isRT == 0 && now > coin->startutc+600 && coin->blocksrecv >= coin->longestchain-1 && coin->blocks.hwmchain.height >= coin->longestchain-1 ) + if ( coin->isRT == 0 && now > coin->startutc+600 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) { - printf(">>>>>>> %s isRT blockrecv.%d vs longest.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); + fprintf(stderr,">>>>>>> %s isRT blockrecv.%d vs longest.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); coin->isRT = 1; if ( coin->polltimeout > 100 ) coin->polltimeout = 100; coin->MAXPEERS = 8; } + if ( coin->isRT != 0 && coin->current != 0 && coin->numverified >= coin->current->hdrsi ) + { + static int32_t saved; + if ( saved++ == 0 ) + iguana_coinflush(coin,1); + } if ( coin->bindsock >= 0 ) { if ( coin->peers.numranked < 8 && now > coin->lastpossible+60 ) { - //printf("possible\n"); + //fprintf(stderr,"possible\n"); coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers } } else { - if ( coin->peers.numranked != 0 && coin->peers.numranked < (coin->MAXPEERS>>1) && now > coin->lastpossible+6 ) + if ( coin->peers.numranked != 0 && coin->peers.numranked < (coin->MAXPEERS>>1) && now > coin->lastpossible ) { - //printf("possible\n"); + //fprintf(stderr,"possible\n"); coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers } } if ( now > coin->peers.lastmetrics+6 ) { - //printf("metrics\n"); + //fprintf(stderr,"metrics\n"); coin->peers.lastmetrics = iguana_updatemetrics(coin); // ranks peers } - //printf("process\n"); + //fprintf(stderr,"call stats\n"); iguana_bundlestats(coin,str); + //fprintf(stderr,"call process\n"); flag += iguana_processrecv(coin); + if ( coin->longestchain+10000 > coin->blocks.maxbits ) + iguana_recvalloc(coin,coin->longestchain + 100000); } } } if ( flag == 0 ) - usleep(coin->polltimeout * 100); + usleep(10000); } } @@ -443,21 +575,25 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, struct iguana_chain *iguana_createchain(cJSON *json); struct iguana_info *coin; int32_t j,m,mapflags; char dirname[512]; cJSON *peers; mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS; - coin = iguana_coinadd(symbol); + coin = iguana_coinadd(symbol,json); coin->launched = launched; if ( (coin->MAXPEERS= maxpeers) <= 0 ) - coin->MAXPEERS = (strcmp(symbol,"BTC") == 0) ? 64 : 32; + coin->MAXPEERS = (strcmp(symbol,"BTC") == 0) ? 128 : 64; if ( (coin->MAXRECVCACHE= maxrecvcache) == 0 ) coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; if ( (coin->MAXPENDING= maxpending) <= 0 ) - coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : _IGUANA_MAXPENDING*32; + coin->MAXPENDING = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXPENDING : 64*_IGUANA_MAXPENDING; if ( (coin->MAXBUNDLES= maxbundles) <= 0 ) - coin->MAXBUNDLES = (strcmp(symbol,"BTC") == 0) ? _IGUANA_MAXBUNDLES : _IGUANA_MAXBUNDLES*64; + coin->MAXBUNDLES = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDBUNDLES : IGUANA_MAXPENDBUNDLES * 64; coin->myservices = services; - sprintf(dirname,"DB/%s",symbol); - OS_ensure_directory(dirname); - sprintf(dirname,"tmp/%s",symbol); - OS_ensure_directory(dirname); + printf("ensure directories\n"); + sprintf(dirname,"accounts/%s",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"DB/%s",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"DB/%s/accounts",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"DB/%s/spends",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"DB/%s/vouts",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"purgeable/%s",symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s",GLOBALTMPDIR,symbol), OS_ensure_directory(dirname); coin->initialheight = initialheight; coin->mapflags = mapflags; coin->MAXMEM = juint(json,"RAM"); @@ -493,7 +629,7 @@ int32_t iguana_launchcoin(char *symbol,cJSON *json) int64_t maxrecvcache; uint64_t services; struct iguana_info **coins,*coin; if ( symbol == 0 ) return(-1); - if ( (coin= iguana_coinadd(symbol)) == 0 ) + if ( (coin= iguana_coinadd(symbol,json)) == 0 ) return(-1); if ( coin->launched == 0 ) { @@ -502,7 +638,7 @@ int32_t iguana_launchcoin(char *symbol,cJSON *json) else maphash = 0; iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxpending,&maxbundles,json); coins = mycalloc('A',1+1,sizeof(*coins)); - if ( (coin= iguana_setcoin(coin->symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxpending,maxbundles,json)) != 0 ) + if ( (coin= iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxpending,maxbundles,json)) != 0 ) { coins[0] = (void *)((long)1); coins[1] = coin; @@ -524,7 +660,8 @@ void iguana_coins(void *arg) { struct iguana_info **coins,*coin; char *jsonstr,*symbol; cJSON *array,*item,*json; int32_t i,n,maxpeers,maphash,initialheight,minconfirms,maxpending,maxbundles; - int64_t maxrecvcache; uint64_t services; + int64_t maxrecvcache; uint64_t services; struct vin_info V; + memset(&V,0,sizeof(V)); if ( (jsonstr= arg) != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) { if ( (array= jarray(&n,json,"coins")) == 0 ) @@ -533,6 +670,7 @@ void iguana_coins(void *arg) { coins = mycalloc('A',1+1,sizeof(*coins)); coins[1] = iguana_setcoin(symbol,coins,0,0,0,0,0,0,0,0,json); + _iguana_calcrmd160(coins[1],&V); coins[0] = (void *)((long)1); iguana_coinloop(coins); } else printf("no coins[] array in JSON.(%s) only BTCD and BTC can be quicklaunched\n",jsonstr); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 7268f41e2..692ccc81c 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -18,9 +18,11 @@ #include "../crypto777/OS_portable.h" #include "SuperNET.h" +#define SPARSECOUNT(x) ((x) << 2) + typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); -#define IGUANA_MAXSCRIPTSIZE 8192 +#define IGUANA_MAXSCRIPTSIZE 10001 //#define IGUANA_DISABLEPEERS #define IGUANA_MAXCOINS 64 @@ -32,17 +34,20 @@ typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t #define IGUANA_WIDTH 1024 #define IGUANA_HEIGHT 200 +#define IGUANA_HEADPERCENTAGE 0. +#define IGUANA_TAILPERCENTAGE 1.0 #define IGUANA_MAXPENDHDRS 1 -#define _IGUANA_MAXPENDING 64 //64 -#define _IGUANA_MAXBUNDLES 8 -#define IGUANA_BUNDLELOOP 1000 +#define _IGUANA_MAXPENDING 3 +#define IGUANA_MINPENDBUNDLES 4 +#define IGUANA_MAXPENDBUNDLES 16 +#define IGUANA_BUNDLELOOP 77 #define IGUANA_RPCPORT 7778 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) #define IGUANA_MAPHASHTABLES 1 #define IGUANA_DEFAULTRAM 4 #define IGUANA_MAXRECVCACHE ((int64_t)1024L * 1024 * 1024L) -#define IGUANA_MAXBUNDLES (5000000 / 500) +#define IGUANA_MAXBUNDLES (50000000 / 500) #define IGUANA_LOG2MAXPEERS 9 #define IGUANA_LOG2PACKETSIZE 21 #define IGUANA_LOG2PEERFILESIZE 23 @@ -65,7 +70,7 @@ struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpo #define IGUANA_DEDICATED_THREADS #ifdef IGUANA_DEDICATED_THREADS -#define IGUANA_MAXCONNTHREADS 32 +#define IGUANA_MAXCONNTHREADS 128 #define IGUANA_MAXSENDTHREADS IGUANA_MAXPEERS #define IGUANA_MAXRECVTHREADS IGUANA_MAXPEERS #else @@ -107,7 +112,7 @@ extern int32_t IGUANA_NUMHELPERS; #define NODE_GETUTXO (1 << 1) #define NODE_BLOOM (1 << 2) -#define PROTOCOL_VERSION 70011 +#define PROTOCOL_VERSION 70001 #define INIT_PROTO_VERSION 209 // initial proto version, to be increased after version/verack negotiation #define GETHEADERS_VERSION 31800 // In this version, 'getheaders' was introduced. #define MIN_PEER_PROTO_VERSION GETHEADERS_VERSION // disconnect from peers older than this proto version @@ -230,7 +235,7 @@ struct iguana_msgblock uint32_t txn_count; } __attribute__((packed)); -struct iguana_msgvin { bits256 prev_hash; uint8_t *sigscript,*spendscript; uint32_t prev_vout,scriptlen,spendlen,sequence; } __attribute__((packed)); +struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*spendscript; uint32_t prev_vout,scriptlen,spendlen,sequence; } __attribute__((packed)); struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; } __attribute__((packed)); @@ -249,7 +254,7 @@ struct msgcounts { uint32_t version,verack,getaddr,addr,inv,getdata,notfound,get struct iguana_fileitem { bits256 hash2; struct iguana_txdatabits txdatabits; }; -struct iguana_kvitem { UT_hash_handle hh; uint8_t keyvalue[]; } __attribute__((packed)); +struct iguana_kvitem { UT_hash_handle hh; uint8_t keyvalue[]; };// __attribute__((packed)); struct iguana_iAddr { @@ -273,10 +278,10 @@ struct iguana_block { struct iguana_blockRO RO; double PoW; // NOT consensus safe, for estimation purposes only - int32_t height,fpos; uint32_t fpipbits,numrequests,issued; - uint16_t hdrsi,bundlei:12,mainchain:1,valid:1,queued:1,tbd:1,extra:8; + int32_t height; uint32_t fpipbits,numrequests,issued; long fpos; + uint16_t hdrsi,bundlei:12,mainchain:1,valid:1,queued:1,txvalid:1,peerid:8; UT_hash_handle hh; bits256 *blockhashes; -} __attribute__((packed)); +};// __attribute__((packed)); #define IGUANA_LHASH_BLOCKS 0 @@ -288,8 +293,9 @@ struct iguana_block //#define IGUANA_LHASH_FIRSTSPENDS 5 // #define IGUANA_LHASH_ACCOUNTS 5 // #define IGUANA_LHASH_EXTERNALS 6 // -#define IGUANA_LHASH_TXBITS 7 // -#define IGUANA_LHASH_PKBITS 8 // +#define IGUANA_LHASH_KSPACE 7 // +#define IGUANA_LHASH_TXBITS 8 // +#define IGUANA_LHASH_PKBITS 9 // #define IGUANA_NUMLHASHES (IGUANA_LHASH_PKBITS + 1) struct iguana_counts @@ -319,21 +325,23 @@ struct iguana_ledger } __attribute__((packed)); // ramchain append only structs -> canonical 32bit inds and ledgerhashes -struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp; uint16_t numvouts,numvins; } __attribute__((packed)); +struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,ipbits; uint8_t rmd160[20]; } __attribute__((packed)); +struct iguana_spend256 { bits256 prevhash2; uint32_t sequenceid,scriptpos; int16_t prevout; uint16_t vinscriptlen,spendind,ipbits; } __attribute__((packed)); + +struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp,extraoffset; uint16_t numvouts,numvins; } __attribute__((packed)); -struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; uint16_t hdrsi:12,type:4,vout; } __attribute__((packed)); -struct iguana_unspent20 { uint64_t value; uint32_t txidind:28,type:4; uint8_t rmd160[20]; } __attribute__((packed)); +struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos,ipbits; uint16_t hdrsi,type:4,scriptlen:14; int16_t vout; } __attribute__((packed)); -struct iguana_spend256 { bits256 prevhash2; int16_t prevout; uint16_t spendind:15,diffsequence:1; } __attribute__((packed)); -struct iguana_spend { uint32_t spendtxidind; int16_t prevout; uint16_t tbd:14,external:1,diffsequence:1; } __attribute__((packed)); +struct iguana_spend { uint32_t spendtxidind,sequenceid,scriptpos,ipbits; int16_t prevout; uint16_t scriptlen:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 -struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind,firstunspentind,flags:23,type:8,ps2h:1; } __attribute__((packed)); +struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((packed)); //firstunspentind,pubkeyoffset // dynamic -struct iguana_account { uint64_t balance; uint32_t lastunspentind; } __attribute__((packed)); // pkind +struct iguana_account { int64_t total; uint32_t lastind; } __attribute__((packed)); +struct iguana_utxo { uint32_t prevspendind,height:31,spentflag:1; } __attribute__((packed)); // GLOBAL one zero to non-zero write (unless reorg) -struct iguana_Uextra { uint32_t spendind; uint16_t hdrsi; } __attribute__((packed)); // unspentind +struct iguana_spendvector { uint32_t ind,height; uint16_t hdrsi; } __attribute__((packed)); // unspentind //struct iguana_pkextra { uint32_t firstspendind; } __attribute__((packed)); // pkind struct iguana_txblock @@ -349,25 +357,26 @@ struct iguana_ramchaindata { bits256 sha256; bits256 lhashes[IGUANA_NUMLHASHES],firsthash2,lasthash2; - int64_t allocsize,Boffset,Toffset,Uoffset,Soffset,Poffset,Aoffset,Xoffset,TXoffset,PKoffset; + int64_t allocsize,Boffset,Toffset,Uoffset,Soffset,Poffset,Aoffset,Xoffset,TXoffset,PKoffset,Koffset; int32_t numblocks,height,firsti,hdrsi,txsparsebits,pksparsebits; - uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,numtxsparse,numpksparse; + uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,numtxsparse,numpksparse,scriptspace,stackspace; uint8_t rdata[]; }; struct iguana_ramchain_hdr { - uint32_t txidind,unspentind,spendind; uint16_t hdrsi,bundlei:15,ROflag:1; + uint32_t txidind,unspentind,spendind,scriptoffset,stacksize; uint16_t hdrsi,bundlei:15,ROflag:1; struct iguana_ramchaindata *data; }; struct iguana_ramchain { struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize; - uint32_t numblocks:31,expanded:1,pkind,externalind,height; + uint32_t numblocks:31,expanded:1,pkind,externalind,height,numXspends; struct iguana_kvitem *txids,*pkhashes; - struct OS_memspace *hashmem; long filesize; void *fileptr; - struct iguana_account *A,*roA; //struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; + struct OS_memspace *hashmem; long filesize,sigsfilesize; void *fileptr,*sigsfileptr,*Xspendptr; + struct iguana_account *A,*creditsA; struct iguana_spendvector *Xspendinds; struct iguana_utxo *Uextras; +//struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; }; struct iguana_peer @@ -379,15 +388,14 @@ struct iguana_peer char ipaddr[64],lastcommand[16],coinstr[16],symbol[16]; uint64_t pingnonce,totalsent,totalrecv,ipbits; double pingtime,sendmillis,pingsum,getdatamillis; uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer; - int32_t supernet,dead,addrind,usock,lastheight,protover,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid; + int32_t supernet,dead,addrind,usock,lastheight,protover,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid,dirty[2],laggard; double recvblocks,recvtotal; int64_t allocated,freed; struct msgcounts msgcounts; - //FILE *fp; int32_t filecount,addrind; struct OS_memspace RAWMEM,TXDATA,HASHMEM; struct iguana_ramchain ramchain; - //struct iguana_kvitem *txids,*pkhashes; struct iguana_fileitem *filehash2; int32_t numfilehash2,maxfilehash2; + struct iguana_bundle *bp; FILE *voutsfp,*vinsfp; #ifdef IGUANA_PEERALLOC struct OS_memspace *SEROUT[128]; #endif @@ -404,13 +412,14 @@ struct iguana_peers }; struct iguana_bloom16 { uint8_t hash2bits[65536 / 8]; }; +struct iguana_bloominds { uint16_t inds[8]; }; struct iguana_bundle { struct queueitem DL; struct iguana_info *coin; struct iguana_bundle *nextbp; - struct iguana_bloom16 bloom; - uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued; - int32_t numhashes,numrecv,numsaved,numcached; + struct iguana_bloom16 bloom; uint32_t rawscriptspace; + uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime; + int32_t numhashes,numrecv,numsaved,numcached,rank,generrs,checkedtmp,currentflag; int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec; double avetime,threshold,metric; uint64_t datasize,estsize; struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; uint32_t issued[IGUANA_MAXBUNDLESIZE]; @@ -434,9 +443,11 @@ struct iguana_waddress { UT_hash_handle hh; uint8_t rmd160[20],type,pubkey[33],w struct iguana_waccount { UT_hash_handle hh; char account[128]; struct iguana_waddress *waddrs; }; struct iguana_wallet { UT_hash_handle hh; struct iguana_waccount *waccts; }; +struct scriptinfo { UT_hash_handle hh; uint32_t fpos; uint16_t scriptlen; uint8_t script[]; }; + struct iguana_info { - char name[64],symbol[8],statusstr[512]; + char name[64],symbol[8],statusstr[512],scriptsfname[2][512]; struct iguana_peers peers; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,estsize,activebundles; @@ -445,27 +456,29 @@ struct iguana_info struct tai starttime; double startmillis; struct iguana_chain *chain; struct iguana_iAddr *iAddrs; - struct iguanakv *txids,*spends,*unspents,*pkhashes; - struct iguana_txid *T; - struct iguana_unspent *U; struct iguana_Uextra *Uextras; - struct iguana_spend *S; struct iguana_Sextra *Sextras; - struct iguana_pkhash *P; struct iguana_account *accounts; struct iguana_pkextra *pkextras; + //struct iguanakv *txids,*spends,*unspents,*pkhashes; + //struct iguana_txid *T; + //struct iguana_unspent *U; struct iguana_Uextra *Uextras; + //struct iguana_spend *S; struct iguana_Sextra *Sextras; + //struct iguana_pkhash *P; struct iguana_account *accounts; struct iguana_pkextra *pkextras; //struct iguana_counts latest; //struct iguana_ledger LEDGER,loadedLEDGER; struct iguana_bitmap screen; //struct pollfd fds[IGUANA_MAXPEERS]; struct iguana_peer bindaddr; int32_t numsocks; struct OS_memspace TXMEM; - queue_t acceptQ,bundlesQ,hdrsQ,blocksQ,priorityQ,possibleQ,TerminateQ,cacheQ; + queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,TerminateQ,cacheQ,recvQ; double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; portable_mutex_t peers_mutex,blocks_mutex; - struct iguana_bundle *bundles[IGUANA_MAXBUNDLES]; - int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle; + portable_mutex_t scripts_mutex[2]; FILE *scriptsfp[2]; void *scriptsptr[2]; long scriptsfilesize[2]; + //struct scriptinfo *scriptstable[2]; + struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending; + int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified; uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime; - double backstopmillis; bits256 backstophash2; - int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids; bits256 reqtxids[64]; + double backstopmillis; bits256 backstophash2; int64_t spaceused; + int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids,allhashes; bits256 reqtxids[64]; void *launched,*started; - uint64_t bloomsearches,bloomhits,bloomfalse,collisions; uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; + uint64_t bloomsearches,bloomhits,bloomfalse,collisions; uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192],bundlebits[IGUANA_MAXBUNDLES/8+1]; struct OS_memspace blockMEM; struct iguana_blocks blocks; bits256 APIblockhash,APItxid; char *APIblockstr; struct iguana_waccount *wallet; }; @@ -475,7 +488,7 @@ struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],r struct vin_info { struct iguana_msgvin vin; - int32_t M,N,validmask,spendlen,type,p2shlen; uint32_t sequence; + int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs; uint32_t sequence; struct vin_signer signers[16]; char coinaddr[65]; uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; @@ -519,7 +532,7 @@ int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *co int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txblock,int32_t *lenp,uint8_t *data,int32_t datalen); int32_t iguana_gethdrs(struct iguana_info *coin,uint8_t *serialized,char *cmd,char *hashstr); -int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,char *hashstr); +int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,bits256 *hashes,int32_t n); // ramchain int64_t iguana_verifyaccount(struct iguana_info *coin,struct iguana_account *acct,uint32_t pkind); @@ -537,7 +550,7 @@ int32_t iguana_updateramchain(struct iguana_info *coin); // blockchain int32_t iguana_needhdrs(struct iguana_info *coin); -struct iguana_chain *iguana_chainfind(char *name); +struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createflag); int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock); uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum); @@ -582,7 +595,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str); // init struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags); -void iguana_initcoin(struct iguana_info *coin); +void iguana_initcoin(struct iguana_info *coin,cJSON *argjson); void iguana_coinloop(void *arg); // utils @@ -636,7 +649,7 @@ int32_t iguana_ramchainfree(struct iguana_info *coin,struct OS_memspace *mem,str struct iguana_ramchain *iguana_ramchainmergeHT(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *ramchains[],int32_t n,struct iguana_bundle *bp); void iguana_ramchainmerge(struct iguana_info *coin); -int32_t iguana_blockQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority); +int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority); void iguana_blockcopy(struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock); int32_t iguana_rpctest(struct iguana_info *coin); extern queue_t helperQ; @@ -680,15 +693,14 @@ struct iguana_agent int32_t iguana_txbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts); void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i); int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i); -int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]); +//int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]); struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txid *tx,int32_t txidind); int32_t iguana_txidreq(struct iguana_info *coin,char **retstrp,bits256 txid); void iguana_bundleiclear(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei); int32_t hcalc_bitsize(uint64_t x); -struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_pkhash *p,uint8_t rmd160[20]); -struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid); +struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi); int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi); -int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); +int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); struct iguana_info *iguana_coinselect(); void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int32_t forceflag); @@ -701,8 +713,8 @@ char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *dest void peggy(); int32_t opreturns_init(uint32_t blocknum,uint32_t blocktimestamp,char *path); struct iguana_info *iguana_coinfind(const char *symbol); -struct iguana_info *iguana_coinadd(const char *symbol); -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_bundle *bp); +struct iguana_info *iguana_coinadd(const char *symbol,cJSON *json); +struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag); int32_t iguana_sendblockreq(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delay); @@ -721,7 +733,7 @@ int32_t is_bitcoinrpc(char *method,char *remoteaddr); char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr); cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr); void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); -int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); +int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit); void ramcoder_test(void *data,int64_t len); void iguana_exit(); int32_t iguana_pendingaccept(struct iguana_info *coin); @@ -731,7 +743,7 @@ cJSON *SuperNET_bits2json(uint8_t *serialized,int32_t datalen); int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis); int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash); int32_t btc_wif2priv(uint8_t *addrtypep,uint8_t privkey[32],char *wifstr); -bits256 iguana_chaingenesis(char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); +bits256 iguana_chaingenesis(bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr); cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V); char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid); @@ -763,8 +775,36 @@ char *issue_startForging(struct supernet_info *myinfo,char *secret); struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account); void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson); void iguana_addinputs(struct iguana_info *coin,struct bitcoin_spend *spend,cJSON *txobj,uint32_t sequence); - -extern queue_t bundlesQ; +int32_t iguana_pkhasharray(struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33); +long iguana_spentsfile(struct iguana_info *coin,int32_t n); +uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti); +void iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds); +uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp); +char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi); +uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind); +int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen); +void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len); +int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); +int32_t iguana_utxogen(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); +struct iguana_bloominds iguana_calcbloom(bits256 hash2); +int32_t iguana_bloomfind(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); +struct iguana_bloominds iguana_bloomset(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); +int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); +void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_coinflush(struct iguana_info *coin,int32_t forceflag); +int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max); +void iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); +int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); +int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp); + +extern int32_t HDRnet,netBLOCKS; + +extern queue_t bundlesQ,validateQ,emitQ,balancesQ; +extern char GLOBALTMPDIR[]; #include "../includes/iguana_api.h" diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 61bb1744c..a4a836d69 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -92,10 +92,15 @@ void iguana_acceptloop(void *args) if ( coin->peers.active[i].ipbits == (uint32_t)ipbits && coin->peers.active[i].usock >= 0 ) { printf("found existing peer.(%s) in slot[%d]\n",ipaddr,i); - iguana_iAkill(coin,&coin->peers.active[i],0); - sleep(1); + close(sock); + sock = -1; + //iguana_iAkill(coin,&coin->peers.active[i],0); + //sleep(1); + break; } } + if ( sock < 0 ) + continue; /*if ( (uint32_t)ipbits == myinfo->myaddr.myipbits ) { diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 30feeb0cd..4c00ce9e3 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -51,7 +51,7 @@ struct iguana_block *iguana_blockhashset(struct iguana_info *coin,int32_t height struct iguana_block *block,*prev; if ( height > 0 && (height > coin->blocks.maxbits || depth != 0) ) { - printf("illegal height.%d when max.%d, depth.%d\n",height,coin->blocks.maxbits,depth); + printf("illegal height.%d when max.%d, or nonz depth.%d\n",height,coin->blocks.maxbits,depth); //getchar(); return(0); } @@ -141,7 +141,10 @@ int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct igu if ( *validp == 0 ) { if ( dispflag != 0 ) + { printf("iguana_blockvalidate: miscompare (%s) vs (%s)\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); + //getchar(); + } return(-1); } return(0); @@ -191,9 +194,13 @@ void iguana_blockconv(struct iguana_block *dest,struct iguana_msgblock *msg,bits void iguana_blockcopy(struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock) { block->RO.hash2 = origblock->RO.hash2; - block->RO.prev_block = origblock->RO.prev_block; block->RO.merkle_root = origblock->RO.merkle_root; - block->mainchain = origblock->mainchain; + if ( bits256_nonz(block->RO.prev_block) == 0 ) + block->RO.prev_block = origblock->RO.prev_block; + if ( block->mainchain == 0 ) + block->mainchain = origblock->mainchain; + if ( block->fpos < 0 ) + block->fpos = origblock->fpos; if ( block->fpipbits == 0 ) block->fpipbits = origblock->fpipbits; if ( block->RO.timestamp == 0 ) @@ -289,7 +296,7 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl } else { - char str[65]; printf("(%s) notready v.%d m.%d h.%d\n",bits256_str(str,prev->RO.hash2),prev->valid,prev->mainchain,prev->height); + //char str[65]; printf("(%s) notready v.%d m.%d h.%d\n",bits256_str(str,prev->RO.hash2),prev->valid,prev->mainchain,prev->height); return(0); } } @@ -300,7 +307,7 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl return(0); } //char str[65]; printf("extend? %s.h%d: %.15f vs %.15f ht.%d vs %d\n",bits256_str(str,block->RO.hash2),height,block->PoW,coin->blocks.hwmchain.PoW,height,coin->blocks.hwmchain.height); - if ( iguana_blockvalidate(coin,&valid,newblock,1) < 0 || valid == 0 ) + if ( iguana_blockvalidate(coin,&valid,newblock,0) < 0 || valid == 0 ) return(0); block->height = height; block->valid = 1; @@ -330,7 +337,14 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl printf("EXTENDMAIN %s %d <- (%s) n.%u max.%u PoW %f numtx.%d valid.%d\n",str,block->height,str2,hwmchain->height+1,coin->blocks.maxblocks,block->PoW,block->RO.txn_count,block->valid); struct iguana_bundle *bp; if ( (block->height % coin->chain->bundlesize) == 0 ) + { bp = iguana_bundlecreate(coin,&bundlei,block->height,block->RO.hash2,zero,0); + if ( bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + { + //printf("created last bundle ht.%d\n",bp->bundleheight); + iguana_blockreq(coin,block->height,1); + } + } else { if ( (bp= coin->bundles[block->height / coin->chain->bundlesize]) != 0 ) @@ -356,6 +370,7 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl //if ( block->fpipbits == 0 ) // iguana_blockQ(coin,bp,block->height % coin->chain->bundlesize,block->RO.hash2,1); block->mainchain = 1; + //iguana_blockreq(coin,block->height+1,0); return(block); } } @@ -379,7 +394,7 @@ void iguana_blocksetheights(struct iguana_info *coin,struct iguana_block *block) int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock) { struct iguana_block *block,*prev; int32_t valid,oldhwm; char str[65]; - if ( iguana_blockvalidate(coin,&valid,newblock,1) < 0 || valid == 0 ) + if ( iguana_blockvalidate(coin,&valid,newblock,0) < 0 || valid == 0 ) { printf("chainextend: newblock.%s didnt validate\n",bits256_str(str,newblock->RO.hash2)); return(-1); diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index 2e1b1cc87..512df107e 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -17,7 +17,6 @@ static uint16_t iguana_primes[] = { 65353, 65357, 65371, 65381, 65393, 65407, 65413, 65419, 65423, 65437, 65447, 65449, 65479, 65497, 65519, 65521 }; -struct iguana_bloominds { uint16_t inds[8]; }; struct iguana_bloominds iguana_calcbloom(bits256 hash2) { @@ -76,6 +75,7 @@ struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,struct iguana_b if ( bp == 0 ) { for (i=coin->bundlescount-1; i>=0; i--) + //for (i=0; ibundlescount; i++) { if ( (bp= coin->bundles[i]) != 0 ) { @@ -86,8 +86,7 @@ struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,struct iguana_b { //printf("bloom miss\n"); coin->bloomfalse++; - } - else return(bp); + } else return(bp); } //else printf("no bloom\n"); } } @@ -136,7 +135,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu if ( bits256_nonz(newhash2) == 0 || (orighash2p= iguana_bundleihash2p(coin,&isinside,bp,bundlei)) == 0 ) { printf("iguana_hash2set warning: bundlei.%d newhash2.%s orighash2p.%p\n",bundlei,bits256_str(str,newhash2),orighash2p); - *orighash2p = newhash2; + //*orighash2p = newhash2; //getchar(); return(-1); } @@ -144,9 +143,9 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu { char str2[65],str3[65]; bits256_str(str2,*orighash2p), bits256_str(str3,newhash2); - printf("ERRRO iguana_hash2set overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); - *orighash2p = newhash2; - getchar(); + printf("WARNING iguana_hash2set REFUSE overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); + //*orighash2p = newhash2; + // getchar(); return(-1); } if ( isinside != 0 ) @@ -154,7 +153,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu bit = iguana_calcbloom(newhash2); if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) { - //printf("bloomset (%s)\n",bits256_str(str,newhash2)); + //printf("bloomset (%s) -> [%d:%d]\n",bits256_str(str,newhash2),bp->hdrsi,bundlei); iguana_bloomset(coin,&bp->bloom,0,bit); if ( 0 ) { @@ -191,7 +190,7 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo int32_t otherbundlei,setval,bundlesize,err = 0; if ( blockp != 0 ) *blockp = 0; - if ( bp == 0 ) + if ( bp == 0 || bits256_nonz(hash2) == 0 ) return(-1111); if ( bits256_nonz(hash2) > 0 && (block= iguana_blockhashset(coin,-1,hash2,1)) != 0 ) { @@ -220,6 +219,7 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo //char str[65]; printf(">>>>>>>>>>>>>> bundlehash2.(%s) ht.(%d %d)\n",bits256_str(str,hash2),bp->bundleheight,bundlei); block->hdrsi = bp->hdrsi; block->bundlei = bundlei; + bp->hashes[bundlei] = block->RO.hash2; bp->blocks[bundlei] = block; otherbp = 0; if ( (otherbp= iguana_bundlefind(coin,&otherbp,&otherbundlei,hash2)) != 0 || (bundlei % (bundlesize-1)) == 0) @@ -260,16 +260,17 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo if ( err != 0 ) { printf("bundlehash2add err.%d\n",err); - while ( 1 ) - sleep(1); - exit(-1); + return(0); + //while ( 1 ) + // sleep(1); + //exit(-1); } return(-err); } struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bundleip,int32_t bundleheight,bits256 bundlehash2,bits256 allhash,int32_t issueflag) { - char str[65]; struct iguana_bundle *bp = 0; + char str[65],dirname[1024]; struct iguana_bundle *bp = 0; if ( bits256_nonz(bundlehash2) > 0 ) { bits256_str(str,bundlehash2); @@ -283,7 +284,7 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund } bp = mycalloc('b',1,sizeof(*bp)); bp->n = coin->chain->bundlesize; - bp->hdrsi = coin->bundlescount; + bp->hdrsi = bundleheight / coin->chain->bundlesize; bp->bundleheight = bundleheight; bp->allhash = allhash; iguana_hash2set(coin,"create",bp,0,bundlehash2); @@ -291,20 +292,21 @@ struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bund { bp->coin = coin; bp->avetime = coin->avetime * 2.; - coin->bundles[coin->bundlescount] = bp; - if ( coin->bundlescount > 0 ) - coin->bundles[coin->bundlescount-1]->nextbp = bp; + coin->bundles[bp->hdrsi] = bp; + if ( bp->hdrsi > 0 && coin->bundles[bp->hdrsi-1] != 0 ) + coin->bundles[bp->hdrsi-1]->nextbp = bp; *bundleip = 0; bits256_str(str,bundlehash2); - fprintf(stderr,"{%d} ",bp->bundleheight); + sprintf(dirname,"%s/%s/%d",GLOBALTMPDIR,coin->symbol,bp->bundleheight), OS_ensure_directory(dirname); //printf("ht.%d alloc.[%d] new hdrs.%s %s\n",bp->bundleheight,coin->bundlescount,str,bits256_str(str2,allhash)); iguana_bundlehash2add(coin,0,bp,0,bundlehash2); if ( issueflag != 0 ) { - iguana_blockQ(coin,bp,0,bundlehash2,1); + iguana_blockQ("bundlecreate",coin,bp,0,bundlehash2,1); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } - coin->bundlescount++; + if ( bp->hdrsi >= coin->bundlescount ) + coin->bundlescount = (bp->hdrsi + 1); } else { @@ -350,7 +352,7 @@ void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp) { if ( (ipbits= (uint32_t)coin->peers.active[j].ipbits) != 0 ) { - if ( iguana_peerfname(coin,&hdrsi,"tmp",fname,ipbits,bp->hashes[0],zero,1) >= 0 ) + if ( iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,ipbits,bp->hashes[0],zero,1) >= 0 ) { if ( OS_removefile(fname,0) > 0 ) coin->peers.numfiles--, m++; @@ -363,67 +365,504 @@ void iguana_bundlepurge(struct iguana_info *coin,struct iguana_bundle *bp) } } +int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t max,int32_t timelimit) +{ + int32_t i,j,k,len,starti,lag,doneval,nonz,total=0,maxval,numpeers,laggard,flag=0,finished,peercounts[IGUANA_MAXPEERS],donecounts[IGUANA_MAXPEERS],priority,counter = 0; + struct iguana_peer *addr; uint32_t now; struct iguana_block *block; + bits256 hashes[50]; uint8_t serialized[sizeof(hashes) + 256]; + if ( bp == 0 ) + return(0); + now = (uint32_t)time(NULL); + memset(peercounts,0,sizeof(peercounts)); + memset(donecounts,0,sizeof(donecounts)); + if ( coin->current != 0 ) + starti = coin->current->hdrsi; + else starti = 0; + priority = (bp->hdrsi < starti+8); + lag = (bp->hdrsi - starti); + lag *= lag; + if ( (i= sqrt(bp->hdrsi)) < 2 ) + i = 2; + if ( lag < i ) + lag = i; + else if ( lag > 10*i ) + lag = 10*i; + if ( (numpeers= coin->peers.numranked) > 8 )//&& bp->currentflag < bp->n ) + { + if ( bp->currentflag == 0 ) + bp->currenttime = now; + if ( bp->numhashes >= bp->n ) + { + for (j=0; jpeers.ranked[j]) != 0 && addr->dead == 0 && addr->usock >= 0 ) + { + now = (uint32_t)time(NULL); + for (i=j,k=doneval=maxval=0; in&&khashes[i]) != 0 ) + { + if ( (block= bp->blocks[i]) != 0 ) + { + if ( block->peerid == 0 ) + { + //printf("<%d>.%d ",i,j); + if ( block->fpipbits == 0 ) + { + hashes[k++] = bp->hashes[i]; + bp->issued[i] = now; + block->issued = now; + block->peerid = j + 1; + block->numrequests++; + } + else + { + block->peerid = 1; + block->numrequests++; + } + } + else if ( block->peerid > 0 ) + { + total++; + if ( block->fpipbits != 0 )//&& block->fpos >= 0 ) + { + donecounts[block->peerid - 1]++; + if ( donecounts[block->peerid - 1] > doneval ) + doneval = donecounts[block->peerid - 1]; + } + else + { + peercounts[block->peerid - 1]++; + if ( peercounts[block->peerid - 1] > maxval ) + maxval = peercounts[block->peerid - 1]; + } + } + } + } + } + if ( k > 0 ) + { + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hashes,k)) > 0 ) + { + iguana_send(coin,addr,serialized,len); + counter += k; + coin->numreqsent += k; + addr->pendblocks += k; + addr->pendtime = (uint32_t)time(NULL); + bp->currentflag += k; + } + //printf("a%d/%d ",j,k); + } + } + } + //printf("doneval.%d maxval.%d\n",doneval,maxval); + if ( priority != 0 ) + { + double threshold; + for (i=nonz=0; i threshold ) + laggard++; + if ( peercounts[i] == 0 && donecounts[i] > threshold ) + finished++; + } + if ( finished > laggard*10 && numpeers > 2*laggard && laggard > 0 ) + { + for (i=0; i threshold && (addr= coin->peers.ranked[i]) != 0 && now > bp->currenttime+lag ) + { + if ( numpeers > 64 || addr->laggard++ > 3 ) + addr->dead = (uint32_t)time(NULL); + for (j=0; jn; j++) + { + if ( (block= bp->blocks[j]) != 0 && block->peerid == i && block->fpipbits == 0 ) + { + printf("%d ",j); + flag++; + counter++; + block->peerid = 0; + iguana_blockQ("kick",coin,bp,j,block->RO.hash2,bp == coin->current); + bp->issued[i] = block->issued = now; + } + } + printf("kill peer.%d %s reissued\n",i,addr->ipaddr); + } + } + } + if ( 0 && laggard != 0 ) + { + for (i=0; ihdrsi,finished,laggard,threshold); + } + } + } + for (i=0; in; i++) + { + if ( (block= bp->blocks[i]) != 0 && block->fpipbits == 0 ) + { + if ( now > block->issued+lag ) + { + counter++; + if ( priority != 0 ) + { + //if ( (addr= coin->peers.ranked[rand() % numpeers]) != 0 ) + // iguana_sendblockreqPT(coin,addr,bp,i,block->RO.hash2,0); + iguana_blockQ("kick",coin,bp,i,block->RO.hash2,bp == coin->current); + printf("[%d:%d] ",bp->hdrsi,i); + } else iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); + flag++; + } //else printf("%d ",now - block->issued); + } + } + if ( flag != 0 && priority != 0 && laggard != 0 ) + printf("currentflag.%d ht.%d s.%d finished.%d most.%d laggards.%d maxunfinished.%d\n",bp->currentflag,bp->bundleheight,bp->numsaved,finished,doneval,laggard,maxval); + } + } + if ( bp == coin->current ) + return(counter); + for (i=0; in; i++) + { + if ( (block= bp->blocks[i]) != 0 ) + { + if ( block->fpipbits == 0 || block->RO.recvlen == 0 ) + { + if ( block->issued == 0 || now > block->issued+lag ) + { + block->numrequests++; + if ( bp == coin->current ) + printf("[%d:%d] ",bp->hdrsi,i); + iguana_blockQ("kick",coin,bp,i,block->RO.hash2,0); + bp->issued[i] = block->issued = now; + counter++; + if ( --max <= 0 ) + break; + } + //else if ( block->fpipbits != 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(block->RO.prev_block) != 0) ) + // n++; + } + } //else printf("iguana_bundleiters[%d] unexpected null block[%d]\n",bp->bundleheight,i); + } + return(counter); +} + +int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp) +{ + int32_t i,ready,valid; struct iguana_block *block; + for (i=ready=0; in; i++) + { + if ( (block= bp->blocks[i]) != 0 ) + { + //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); + if ( block->fpipbits == 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) + { + char str[65]; printf(">>>>>>> ipbits.%x null prevblock error at ht.%d patch.(%s) and reissue\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block)); + iguana_blockQ("null retry",coin,bp,i,block->RO.hash2,1); + } else ready++; + } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i])); + } + return(ready); +} + +int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti) +{ + int32_t counter=0; + //if ( bp->speculative != 0 ) + // printf("hdr ITERATE bundle.%d vs %d: h.%d n.%d r.%d s.%d finished.%d speculative.%p\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,bp->speculative); + if ( strcmp(coin->symbol,"BTC") != 0 && bp->speculative == 0 && bp->numhashes < bp->n ) + { + char str[64]; + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + } + return(counter); +} + +int32_t iguana_bundletweak(struct iguana_info *coin,struct iguana_bundle *bp) +{ + struct iguana_bundle *lastbp; + if ( coin->current == bp ) + coin->current = coin->bundles[bp->hdrsi+1]; + if ( (lastbp= coin->lastpending) != 0 && lastbp->hdrsi < coin->bundlescount-1 ) + coin->lastpending = coin->bundles[lastbp->hdrsi + 1]; + if ( (rand() % 2) == 0 ) + { + if ( coin->MAXBUNDLES > IGUANA_MINPENDBUNDLES ) + coin->MAXBUNDLES--; + else if ( coin->MAXBUNDLES < IGUANA_MINPENDBUNDLES ) + coin->MAXBUNDLES++; + } + return(coin->MAXBUNDLES); +} + int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp) { - int32_t bundlei; struct iguana_block *block; + FILE *fp; int32_t bundlei,checki,hdrsi,numhashes,numsaved,numcached,numrecv,minrequests; + int64_t datasize; struct iguana_block *block; char fname[1024]; static bits256 zero; if ( bp->emitfinish > coin->startutc ) { bp->numhashes = bp->numsaved = bp->numcached = bp->numrecv = bp->n; return(bp->datasize); } - bp->datasize = bp->numhashes = bp->numsaved = bp->numcached = bp->numrecv = bp->minrequests = 0; + datasize = numhashes = numsaved = numcached = numrecv = minrequests = 0; for (bundlei=0; bundlein; bundlei++) { - if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) + if ( bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 ) { - if ( (block= bp->blocks[bundlei]) != 0 || (block= iguana_blockfind(coin,bp->hashes[bundlei])) != 0 ) + if ( block == iguana_blockfind(coin,bp->hashes[bundlei]) ) { + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("iguana_bundlecalcs.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); + continue; + } + if ( 1 && bp->checkedtmp < bp->n && (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + if ( block->RO.recvlen == 0 ) + { + block->RO.recvlen = (uint32_t)ftell(fp); + block->fpipbits = 1; + block->fpos = 0; + //printf("[%d:%d] len.%d\n",hdrsi,bundlei,block->RO.recvlen); + } + fclose(fp); + } bp->blocks[bundlei] = block; + block->hdrsi = bp->hdrsi, block->bundlei = bundlei; if ( bp->minrequests == 0 || (block->numrequests > 0 && block->numrequests < bp->minrequests) ) bp->minrequests = block->numrequests; - if ( block->fpipbits != 0 ) - bp->numsaved++; - if ( block->RO.recvlen != 0 ) + if ( (bp->hdrsi == 0 && bundlei == 0) || bits256_nonz(block->RO.prev_block) > 0 ) { - bp->numrecv++; - bp->datasize += block->RO.recvlen; - if ( block->queued != 0 ) - bp->numcached++; + if ( block->fpipbits != 0 ) //block->fpos >= 0 && + numsaved++; + if ( block->RO.recvlen != 0 || block->fpipbits != 0 || block->fpos >= 0 )//|| block->queued != 0 ) + { + numrecv++; + datasize += block->RO.recvlen; + if ( block->queued != 0 ) + numcached++; + } } + /*else //if ( 0 ) + { + printf("cleared block?\n"); + //block->RO.recvlen = 0; + //block->fpipbits = 0; + //block->fpos = -1; + //block->issued = bp->issued[bundlei] = 0; + }*/ + } + else if ( 0 ) + { + bp->blocks[bundlei] = iguana_blockfind(coin,bp->hashes[bundlei]); + bp->hashes[bundlei] = bp->blocks[bundlei]->RO.hash2; + if ( (block= bp->blocks[bundlei]) != 0 ) + block->fpipbits = block->queued = 0; } - bp->numhashes++; + numhashes++; + bp->checkedtmp++; } } - bp->metric = bp->numhashes; + bp->datasize = datasize; + bp->numhashes = numhashes; + bp-> numsaved = numsaved; + bp->numcached = numcached; + bp->numrecv = numrecv; + bp->minrequests = minrequests; + bp->estsize = ((int64_t)bp->datasize * bp->n) / (bp->numrecv+1); return(bp->estsize); } +int32_t iguana_bundlefinish(struct iguana_info *coin,struct iguana_bundle *bp) +{ + struct iguana_bundle *prevbp; int32_t prevdone = 0; + if ( (prevbp= coin->bundles[bp->hdrsi-1]) != 0 && prevbp->balancefinish > 1 ) + prevdone = 1; + else if ( coin->current != 0 && prevbp != 0 && coin->current->hdrsi >= prevbp->hdrsi && prevbp->emitfinish > 1 && time(NULL) > prevbp->emitfinish+3 ) + prevdone = 1; + if ( bp->hdrsi == 0 || prevdone != 0 ) + { + if ( bp->startutxo == 0 ) + { + bp->startutxo = (uint32_t)time(NULL); + if ( iguana_utxogen(coin,bp) >= 0 ) + { + printf("GENERATED UTXO.%d for ht.%d duration %d seconds\n",bp->hdrsi,bp->bundleheight,(uint32_t)time(NULL)-bp->startutxo); + bp->utxofinish = (uint32_t)time(NULL); + iguana_balancesQ(coin,bp); + return(1); + } else printf("UTXO gen.[%d] utxo error\n",bp->hdrsi); + } + } // else printf("%u notready postfinish.%d startutxo.%u prevbp.%d %u current.%d\n",(uint32_t)time(NULL),bp->hdrsi,bp->startutxo,prevbp!=0?prevbp->hdrsi:-1,prevbp!=0?prevbp->emitfinish:0,coin->current!=0?coin->current->hdrsi:-1); + return(0); +} + +int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit) +{ + int32_t range,starti,lasti,retval=0,max,counter = 0; struct iguana_bundle *currentbp,*lastbp; + bp->nexttime = (uint32_t)time(NULL) + 1; + if ( coin->started == 0 ) + { + iguana_bundleQ(coin,bp,1000); + return(retval); + } + if ( coin->current == 0 ) + coin->current = coin->bundles[0]; + if ( (range= coin->peers.numranked) > coin->MAXBUNDLES ) + range = coin->MAXBUNDLES; + currentbp = coin->current; + lastbp = coin->lastpending; + starti = currentbp == 0 ? 0 : currentbp->hdrsi; + lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; + coin->numbundlesQ--; + iguana_bundlecalcs(coin,bp); + //printf("ITERATE.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d counter.%d\n",bp->rank,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) + iguana_bundlehdr(coin,bp,starti); + else if ( bp->emitfinish != 0 ) + { + if ( bp->emitfinish > 1 ) + { + if ( (retval= iguana_bundlefinish(coin,bp)) > 0 ) + { + //printf("moved to balancesQ.%d bundleiters.%d\n",bp->hdrsi,bp->bundleheight); + bp->queued = 0; + return(0); + } //else printf("finish incomplete.%d\n",bp->hdrsi); + } + } + else if ( bp->numsaved >= bp->n ) + { + if ( iguana_bundleready(coin,bp) == bp->n ) + { + printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT bundle.%d | 1st.%d h.%d s.[%d] maxbundles.%d NET.(h%d b%d)\n",bp->bundleheight,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,netBLOCKS); + bp->emitfinish = 1; + iguana_bundletweak(coin,bp); + sleep(1); // just in case data isnt totally sync'ed to HDD + if ( 0 ) + iguana_emitQ(coin,bp); + else + { + if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + { + fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d\n",coin,bp->hdrsi,bp->bundleheight); + bp->emitfinish = (uint32_t)time(NULL) + 1; + coin->numemitted++; + } + else + { + fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d error\n",coin,bp->hdrsi,bp->bundleheight); + bp->emitfinish = 0; + } + } + } + retval = 1; + } + else if ( bp->hdrsi >= starti && bp->hdrsi <= starti+range ) + { + max = bp->n; + counter = iguana_bundleissue(coin,bp,max,timelimit); + if ( 0 && counter > 0 ) + printf("ITERATE.%d max.%d bundle.%d h.%d n.%d r.%d s.%d F.%d T.%d counter.%d\n",bp->rank,max,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter); + } + iguana_bundleQ(coin,bp,1000); + return(retval); +} + +static int _decreasing_double(const void *a,const void *b) +{ +#define double_a (*(double *)a) +#define double_b (*(double *)b) + if ( double_b > double_a ) + return(1); + else if ( double_b < double_a ) + return(-1); + return(0); +#undef double_a +#undef double_b +} + +static int32_t revsortds(double *buf,uint32_t num,int32_t size) +{ + qsort(buf,num,size,_decreasing_double); + return(0); +} + void iguana_bundlestats(struct iguana_info *coin,char *str) { static uint32_t lastdisp; - int32_t i,n,dispflag,numrecv,done,numhashes,numcached,numsaved,numemit; int64_t estsize = 0; - struct iguana_bundle *bp,*firstgap = 0; + int32_t i,n,m,numv,count,pending,dispflag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; + int64_t spaceused=0,estsize = 0; struct iguana_bundle *bp,*lastpending = 0,*firstgap = 0; double *sortbuf; struct iguana_peer *addr; dispflag = (rand() % 1000) == 0; - numrecv = numhashes = numcached = numsaved = numemit = done = 0; - for (i=n=0; ibundlescount; i++) + numrecv = numhashes = numcached = numsaved = numemit = done = numutxo = numbalances = 0; + count = coin->bundlescount; + sortbuf = calloc(count,sizeof(*sortbuf)*2); + for (i=n=m=numv=pending=0; ibundles[i]) != 0 ) { - estsize += iguana_bundlecalcs(coin,bp); + bp->rank = 0; + estsize += bp->estsize;//iguana_bundlecalcs(coin,bp,done); + //bp->metric = bp->numhashes; + bp->metric = coin->bundlescount - bp->hdrsi; + if ( done > coin->bundlescount*IGUANA_HEADPERCENTAGE && bp->hdrsi > coin->bundlescount*IGUANA_TAILPERCENTAGE ) + bp->metric *= 1000; numhashes += bp->numhashes; numcached += bp->numcached; numrecv += bp->numrecv; numsaved += bp->numsaved; - if ( bp->emitfinish != 0 ) + if ( bp->utxofinish > 1 ) + numutxo++; + if ( bp->balancefinish > 1 ) + numbalances++; + if ( bp->validated != 0 ) + numv++; + if ( bp->emitfinish > 1 ) { done++; - if ( bp->emitfinish > 1 ) - numemit++; + numemit++; iguana_bundlepurge(coin,bp); - } else if ( firstgap == 0 ) - firstgap = bp; + } + else + { + if ( ++pending == coin->MAXBUNDLES ) + { + lastpending = bp; + //printf("SET MAXBUNDLES.%d pend.%d\n",bp->hdrsi,pending); + } + if ( firstgap == 0 ) + firstgap = bp; + if ( bp->emitfinish == 0 ) + { + spaceused += bp->estsize; + sortbuf[m*2] = bp->metric; + sortbuf[m*2 + 1] = i; + m++; + } + } + } + } + if ( m > 0 ) + { + revsortds(sortbuf,m,sizeof(*sortbuf)*2); + for (i=0; ibundles[(int32_t)sortbuf[i*2 + 1]]) != 0 ) + { + bp->rank = i + 1; + if ( coin->peers.numranked > 0 && i < coin->peers.numranked && (addr= coin->peers.ranked[i]) != 0 ) + addr->bp = bp; + } } } + free(sortbuf); coin->numremain = n; coin->blocksrecv = numrecv; char str2[65]; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); @@ -435,17 +874,27 @@ void iguana_bundlestats(struct iguana_info *coin,char *str) tmp = (difft.millis * 1000000); tmp %= 1000000000; difft.millis = ((double)tmp / 1000000.); - sprintf(str,"N[%d] Q.%d h.%d r.%d c.%d:%d:%d s.%d d.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d)",coin->bundlescount,coin->numbundlesQ,numhashes,coin->blocksrecv,coin->numcached,numcached,coin->cachefreed,numsaved,done,numemit,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); + if ( (coin->current= firstgap) == 0 ) + coin->current = coin->bundlescount > 0 ? coin->bundles[coin->bundlescount-1] : coin->bundles[0]; + if ( lastpending != 0 ) + coin->lastpending = lastpending; + else coin->lastpending = coin->bundles[coin->bundlescount - 1]; + coin->numsaved = numsaved; + coin->spaceused = spaceused; + coin->numverified = numv; + char str4[65]; + sprintf(str,"u.%d b.%d v.%d/%d (%d 1st.%d) to %d N[%d] Q.%d h.%d r.%d c.%s s.%d d.%d E.%d:%d M.%d L.%d est.%d %s %d:%02d:%02d %03.3f peers.%d/%d Q.(%d %d)",numutxo,numbalances,numv,coin->pendbalances,firstgap!=0?firstgap->numsaved:0,firstgap!=0?firstgap->hdrsi:0,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,coin->numbundlesQ,numhashes,coin->blocksrecv,mbstr(str4,spaceused),numsaved,done,numemit,coin->numreqsent,coin->blocks.hwmchain.height,coin->longestchain,coin->MAXBUNDLES,mbstr(str2,estsize),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,difft.millis,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); //sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - if ( time(NULL) > lastdisp+1000 ) + if ( time(NULL) > lastdisp+10 ) { printf("%s\n",str); - //myallocated(0,0); + if ( (rand() % 100) == 0 ) + myallocated(0,0); lastdisp = (uint32_t)time(NULL); + //if ( firstgap != 0 && firstgap->queued == 0 ) + // iguana_bundleQ(coin,firstgap,1000); } strcpy(coin->statusstr,str); coin->estsize = estsize; - if ( firstgap != 0 && firstgap->queued == 0 ) - iguana_bundleQ(coin,firstgap,1000); } diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index 1f9a91f75..31f80dd62 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -78,7 +78,7 @@ static struct iguana_chain Chains[] = //"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2", "12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2", "010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4804ffff001d0104404e592054696d65732030352f4f63742f32303131205374657665204a6f62732c204170706c65e280997320566973696f6e6172792c2044696573206174203536ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", - 9333,9334,0,0x1e // port and rpcport vpncoin.conf + 9333,9334,0,0x1e // port and rpcport litecoin.conf }, }; @@ -122,16 +122,16 @@ blockhashfunc iguana_hashalgo(char *hashalgostr) return(0); } -bits256 iguana_chaingenesis(char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root) +bits256 iguana_chaingenesis(bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root) { struct iguana_msgblock msg; int32_t len,blockhashlen; bits256 hash2; - char blockhashstr[256]; uint8_t serialized[1024],blockhash[256]; + char blockhashstr[256],str3[65]; uint8_t serialized[1024],blockhash[256]; int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); memset(&msg,0,sizeof(msg)); msg.H.version = version; msg.H.merkle_root = merkle_root; msg.H.timestamp = timestamp; - msg.H.bits = bits; + msg.H.bits = nBits; msg.H.nonce = nonce; len = iguana_rwblock(1,&hash2,serialized,&msg); blockhashstr[0] = 0; @@ -139,9 +139,12 @@ bits256 iguana_chaingenesis(char *genesisblock,char *hashalgostr,int32_t version { if ( (blockhashlen= (*hashalgo)(blockhash,serialized,len)) > 0 ) init_hexbytes_noT(blockhashstr,blockhash,blockhashlen); - } + } else init_hexbytes_noT(blockhashstr,hash2.bytes,sizeof(hash2)); + char str[65],str2[65]; + if ( bits256_cmp(genesishash,hash2) != 0 ) + printf("WARNING: genesishash.(%s) mismatch vs calc.(%s)\n",bits256_str(str,genesishash),bits256_str(str2,genesishash)); init_hexbytes_noT(genesisblock,serialized,len); - char str[65],str2[65]; printf("v.%d t.%u bits.%x nonce.%u merkle.(%s) genesis.(%s) hash2.(%s) blockhash.(%s) size.%ld\n",version,timestamp,bits,nonce,bits256_str(str2,merkle_root),genesisblock,bits256_str(str,hash2),blockhashstr,strlen(genesisblock)/2); + printf("v.%d t.%u %s nBits.%08x nonce.%u merkle.(%s) genesis.(%s) hash2.(%s) blockhash.(%s) size.%ld\n",version,timestamp,utc_str(str3,timestamp),nBits,nonce,bits256_str(str2,merkle_root),genesisblock,bits256_str(str,hash2),blockhashstr,strlen(genesisblock)/2); return(hash2); } @@ -242,86 +245,10 @@ uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *us return(port); } -void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders) -{ - chain->hasheaders = hasheaders; - chain->minoutput = 10000; - chain->hashalgo = blockhash_sha256; - if ( strcmp(chain->symbol,"BTC") == 0 ) - { - chain->unitval = 0x1d; - chain->txfee = 10000; - } - else chain->txfee = 1000000; - if ( chain->unitval == 0 ) - chain->unitval = 0x1e; - if ( hasheaders != 0 ) - { - strcpy(chain->gethdrsmsg,"getheaders"); - chain->bundlesize = _IGUANA_HDRSCOUNT; - } - else - { - strcpy(chain->gethdrsmsg,"getblocks"); - chain->bundlesize = _IGUANA_BLOCKHASHES; - } - decode_hex((uint8_t *)chain->genesis_hashdata,32,(char *)chain->genesis_hash); - if ( chain->ramchainport == 0 ) - chain->ramchainport = chain->portp2p - 1; - if ( chain->portrpc == 0 ) - chain->portrpc = chain->portp2p + 1; -} - -struct iguana_chain *iguana_chainfind(char *name) -{ - struct iguana_chain *chain; uint32_t i; - for (i=0; igenesis_hash,chain->name,name,strcmp(name,chain->name)); - if ( chain->name[0] == 0 || chain->genesis_hash == 0 ) - continue; - if ( strcmp(name,chain->symbol) == 0 ) - { - printf("found.(%s)\n",name); - iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0); - return(chain); - } - } - return NULL; -} - -struct iguana_chain *iguana_findmagic(uint8_t netmagic[4]) -{ - struct iguana_chain *chain; uint8_t i; - for (i=0; iname[0] == 0 || chain->genesis_hash == 0 ) - continue; - if ( memcmp(netmagic,chain->netmagic,4) == 0 ) - return(iguana_chainfind((char *)chain->symbol)); - } - return NULL; -} - -uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum) -{ - int32_t i; uint64_t reward = 50LL * SATOSHIDEN; - for (i=0; ichain->rewards)/sizeof(*coin->chain->rewards); i++) - { - //printf("%d: %u %.8f\n",i,(int32_t)coin->chain->rewards[i][0],dstr(coin->chain->rewards[i][1])); - if ( blocknum >= coin->chain->rewards[i][0] ) - reward = coin->chain->rewards[i][1]; - else break; - } - return(reward); -} - void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) { extern char Userhome[]; - char *path,*conf,*hexstr,genesisblock[1024],str[65]; bits256 hash; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; + char *path,*conf,*hexstr,genesisblock[1024]; bits256 hash; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; uint32_t nBits; uint8_t tmp[4]; if ( strcmp(chain->symbol,"NXT") != 0 ) { if ( strcmp(chain->symbol,"BTC") != 0 ) @@ -371,20 +298,30 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) decode_hex((uint8_t *)chain->netmagic,1,hexstr); if ( (hexstr= jstr(argjson,"unitval")) != 0 && strlen(hexstr) == 2 ) decode_hex((uint8_t *)&chain->unitval,1,hexstr); + if ( (hexstr= jstr(argjson,"genesishash")) != 0 ) + { + chain->genesis_hash = mycalloc('G',1,strlen(hexstr)+1); + strcpy(chain->genesis_hash,hexstr); + } if ( (genesis= jobj(argjson,"genesis")) != 0 ) { chain->hashalgo = iguana_hashalgo(jstr(genesis,"hashalgo")); - hash = iguana_chaingenesis(genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),juint(genesis,"nbits"),juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); - chain->genesis_hash = clonestr(bits256_str(str,hash)); + decode_hex(hash.bytes,sizeof(hash),chain->genesis_hash); + if ( jstr(genesis,"nBits") != 0 ) + { + decode_hex((void *)&tmp,sizeof(tmp),jstr(genesis,"nBits")); + ((uint8_t *)&nBits)[0] = tmp[3]; + ((uint8_t *)&nBits)[1] = tmp[2]; + ((uint8_t *)&nBits)[2] = tmp[1]; + ((uint8_t *)&nBits)[3] = tmp[0]; + } + else nBits = 0x1e00ffff; + hash = iguana_chaingenesis(hash,genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),nBits,juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); + //chain->genesis_hash = clonestr(bits256_str(str,hash)); chain->genesis_hex = clonestr(genesisblock); } else { - if ( (hexstr= jstr(argjson,"genesishash")) != 0 ) - { - chain->genesis_hash = mycalloc('G',1,strlen(hexstr)+1); - strcpy(chain->genesis_hash,hexstr); - } if ( (hexstr= jstr(argjson,"genesisblock")) != 0 ) { chain->genesis_hex = mycalloc('G',1,strlen(hexstr)+1); @@ -412,16 +349,101 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) } } +void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjson) +{ + chain->hasheaders = hasheaders; + chain->minoutput = 10000; + chain->hashalgo = blockhash_sha256; + if ( strcmp(chain->symbol,"BTC") == 0 ) + { + chain->unitval = 0x1d; + chain->txfee = 10000; + } + else chain->txfee = 1000000; + if ( chain->unitval == 0 ) + chain->unitval = 0x1e; + if ( argjson != 0 ) + iguana_chainparms(chain,argjson); + if ( hasheaders != 0 ) + { + strcpy(chain->gethdrsmsg,"getheaders"); + chain->bundlesize = _IGUANA_HDRSCOUNT; + } + else + { + strcpy(chain->gethdrsmsg,"getblocks"); + chain->bundlesize = _IGUANA_BLOCKHASHES; + } + decode_hex((uint8_t *)chain->genesis_hashdata,32,(char *)chain->genesis_hash); + if ( chain->ramchainport == 0 ) + chain->ramchainport = chain->portp2p - 1; + if ( chain->portrpc == 0 ) + chain->portrpc = chain->portp2p + 1; +} + +struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createflag) +{ + struct iguana_chain *chain; uint32_t i; + for (i=0; igenesis_hash,chain->name,name,strcmp(name,chain->name)); + if ( chain->name[0] == 0 || chain->genesis_hash == 0 ) + { + if ( createflag != 0 && argjson != 0 ) + { + iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0,argjson); + return(chain); + } + continue; + } + if ( strcmp(name,chain->symbol) == 0 ) + { + printf("found.(%s)\n",name); + iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0,argjson); + return(chain); + } + } + return NULL; +} + +struct iguana_chain *iguana_findmagic(uint8_t netmagic[4]) +{ + struct iguana_chain *chain; uint8_t i; + for (i=0; iname[0] == 0 || chain->genesis_hash == 0 ) + continue; + if ( memcmp(netmagic,chain->netmagic,4) == 0 ) + return(iguana_chainfind((char *)chain->symbol,0,0)); + } + return NULL; +} + +uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum) +{ + int32_t i; uint64_t reward = 50LL * SATOSHIDEN; + for (i=0; ichain->rewards)/sizeof(*coin->chain->rewards); i++) + { + //printf("%d: %u %.8f\n",i,(int32_t)coin->chain->rewards[i][0],dstr(coin->chain->rewards[i][1])); + if ( blocknum >= coin->chain->rewards[i][0] ) + reward = coin->chain->rewards[i][1]; + else break; + } + return(reward); +} + struct iguana_chain *iguana_createchain(cJSON *json) { char *symbol,*name; struct iguana_chain *chain = 0; - if ( (symbol= jstr(json,"name")) != 0 && strlen(symbol) < 8 ) + if ( ((symbol= jstr(json,"newcoin")) != 0 || (symbol= jstr(json,"name")) != 0) && strlen(symbol) < 8 ) { chain = mycalloc('C',1,sizeof(*chain)); strcpy(chain->symbol,symbol); if ( (name= jstr(json,"description")) != 0 && strlen(name) < 32 ) strcpy(chain->name,name); - iguana_chaininit(chain,juint(json,"hasheaders")); + iguana_chaininit(chain,juint(json,"hasheaders"),json); } return(chain); } diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index 02663db6b..db34842a9 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -909,7 +909,7 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) exchange->commission *= .01; printf("ADDEXCHANGE.(%s) [%s, %s, %s] commission %.3f%%\n",exchangestr,exchange->apikey,exchange->userid,exchange->apisecret,exchange->commission * 100.); Exchanges[exchangeid] = exchange; - iguana_launch(iguana_coinadd("BTCD"),"exchangeloop",(void *)exchanges777_loop,exchange,IGUANA_EXCHANGETHREAD); + iguana_launch(iguana_coinadd("BTCD",0),"exchangeloop",(void *)exchanges777_loop,exchange,IGUANA_EXCHANGETHREAD); return(exchange); } @@ -946,12 +946,17 @@ void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sle myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; } } - if ( 0 ) + if ( 1 ) { argjson = cJSON_CreateObject(); for (i=0; iname)) == 0 && (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) - myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; + if ( (exchange= exchanges777_find(Exchange_funcs[i]->name)) == 0 ) + { + if ( strcmp(Exchange_funcs[i]->name,"PAX") == 0 || strcmp(Exchange_funcs[i]->name,"truefx") == 0 || strcmp(Exchange_funcs[i]->name,"fxcm") == 0 || strcmp(Exchange_funcs[i]->name,"instaforx") == 0 ) + continue; + if ( (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; + } free_json(argjson); } instantdexhash = calc_categoryhashes(0,"InstantDEX",0); diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index d5ffce0db..9cb31693f 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -27,13 +27,13 @@ void iguana_initQs(struct iguana_info *coin) { int32_t i; iguana_initQ(&coin->acceptQ,"acceptQ"); - iguana_initQ(&coin->bundlesQ,"bundlesQ"); iguana_initQ(&coin->hdrsQ,"hdrsQ"); iguana_initQ(&coin->blocksQ,"blocksQ"); iguana_initQ(&coin->priorityQ,"priorityQ"); iguana_initQ(&coin->possibleQ,"possibleQ"); iguana_initQ(&coin->cacheQ,"cacheQ"); iguana_initQ(&coin->TerminateQ,"TerminateQ"); + iguana_initQ(&coin->recvQ,"recvQ"); for (i=0; ipeers.active[i].sendQ,"addrsendQ"); } @@ -50,11 +50,15 @@ void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t iguana_initQ(&addr->sendQ,"addrsendQ"); } -void iguana_initcoin(struct iguana_info *coin) +void iguana_initcoin(struct iguana_info *coin,cJSON *argjson) { - int32_t i; + int32_t i; + //sprintf(dirname,"%s/%s",GLOBALTMPDIR,coin->symbol), OS_portable_path(dirname); + //OS_portable_rmdir(dirname,0); portable_mutex_init(&coin->peers_mutex); portable_mutex_init(&coin->blocks_mutex); + portable_mutex_init(&coin->scripts_mutex[0]); + portable_mutex_init(&coin->scripts_mutex[1]); iguana_meminit(&coin->blockMEM,"blockMEM",coin->blockspace,sizeof(coin->blockspace),0); iguana_initQs(coin); coin->bindsock = -1; @@ -74,15 +78,21 @@ void iguana_initcoin(struct iguana_info *coin) bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) { - struct iguana_block block,*ptr; struct iguana_msgblock msg; bits256 hash2; char str[65]; uint8_t buf[1024]; int32_t height; + struct iguana_block block,*ptr; struct iguana_msgblock msg; bits256 hash2; char str[65],str2[65]; uint8_t buf[1024]; int32_t height; + if ( chain->genesis_hex == 0 ) + { + printf("no genesis_hex for %s\n",coin->symbol); + memset(hash2.bytes,0,sizeof(hash2)); + return(hash2); + } decode_hex(buf,(int32_t)strlen(chain->genesis_hex)/2,(char *)chain->genesis_hex); hash2 = bits256_doublesha256(0,buf,sizeof(struct iguana_msgblockhdr)); iguana_rwblock(0,&hash2,buf,&msg); if ( memcmp(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)) != 0 ) { bits256_str(str,hash2); - printf("genesis mismatch? calculated %s vs %s\n",str,(char *)chain->genesis_hex); - hash2 = bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"); + printf("genesis mismatch? calculated %s vs %s\n",str,bits256_str(str2,*(bits256 *)chain->genesis_hashdata)); + //hash2 = bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"); //memset(hash2.bytes,0,sizeof(hash2)); //return(hash2); @@ -125,7 +135,7 @@ int32_t iguana_savehdrs(struct iguana_info *coin) n = coin->blocks.hwmchain.height + 1; hashes = mycalloc('h',coin->chain->bundlesize,sizeof(*hashes)); sprintf(oldfname,"confs/%s_oldhdrs.txt",coin->symbol), OS_compatible_path(oldfname); - sprintf(tmpfname,"tmp/%s/hdrs.txt",coin->symbol), OS_compatible_path(tmpfname); + sprintf(tmpfname,"%s/%s/hdrs.txt",GLOBALTMPDIR,coin->symbol), OS_compatible_path(tmpfname); sprintf(fname,"confs/%s_hdrs.txt",coin->symbol), OS_compatible_path(fname); if ( (fp= fopen(tmpfname,"w")) != 0 ) { @@ -177,7 +187,7 @@ int32_t iguana_savehdrs(struct iguana_info *coin) void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) { - int32_t j,k,m,c,height,flag,bundlei; char checkstr[1024],line[1024]; + int32_t i,j,k,m,c,height,flag,bundlei; char checkstr[1024],line[1024]; struct iguana_peer *addr; struct iguana_bundle *bp; bits256 allhash,hash2,zero,lastbundle; struct iguana_block *block; memset(&zero,0,sizeof(zero)); @@ -212,19 +222,19 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) //printf("parse line.(%s) maxpeers.%d\n",line,coin->MAXPEERS); if ( iter == 0 ) { - if ( m < (2*coin->MAXPEERS)/3 )//&& m < 77.7 ) + if ( m < coin->MAXPEERS-3 )//&& m < 77.7 ) { if ( 0 && m == 0 ) { addr = &coin->peers.active[m++]; iguana_initpeer(coin,addr,(uint32_t)calc_ipbits("127.0.0.1")); - printf("call initpeer.(%s)\n",addr->ipaddr); + //printf("call initpeer.(%s)\n",addr->ipaddr); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); } #ifndef IGUANA_DISABLEPEERS addr = &coin->peers.active[m++]; iguana_initpeer(coin,addr,(uint32_t)calc_ipbits(line)); - printf("call initpeer.(%s)\n",addr->ipaddr); + //printf("call initpeer.(%s)\n",addr->ipaddr); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); #endif } @@ -256,20 +266,31 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,allhash,0)) != 0 ) { bp->bundleheight = height; + if ( height == 0 && coin->current == 0 ) + coin->current = coin->bundles[0] = bp; lastbundle = hash2; if ( (block= iguana_blockfind(coin,hash2)) != 0 ) block->mainchain = 1, block->height = height; - if ( iguana_bundleload(coin,bp) != 0 ) + if ( iguana_bundleload(coin,&bp->ramchain,bp,2) != 0 ) { bp->emitfinish = (uint32_t)time(NULL) + 1; - //printf("LOADED bundle.%d\n",bp->bundleheight); + if ( coin->current != 0 && coin->current->hdrsi+1 == bp->hdrsi ) + coin->current = bp; + //printf("LOADED bundle.%d %p current %p\n",bp->bundleheight,bp,coin->current); + //if ( bp->hdrsi == 0 || coin->bundles[bp->hdrsi-1]->emitfinish != 0 ) + { + //bp->startutxo = (uint32_t)time(NULL); + //printf("GENERATE UTXO, verify sigs, etc for ht.%d\n",bp->bundleheight); + iguana_bundleQ(coin,bp,1000); + } } else { char str[65]; init_hexbytes_noT(str,hash2.bytes,sizeof(hash2)); bp->emitfinish = 0; - iguana_blockQ(coin,bp,0,hash2,1); + iguana_blockQ("init",coin,bp,0,hash2,1); + //printf("init reqhdrs.%d\n",bp->bundleheight); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } } @@ -285,6 +306,19 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) printf("req lastbundle.(%s)\n",hashstr); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); } + if ( iter == 1 ) + { + for (i=0; ibundlescount; i++) + if ( coin->bundles[i] == 0 ) + break; + printf("INIT bundles i.%d\n",i); + if ( i > 0 ) + { + //iguana_spentsfile(coin,i); + } + char buf[1024]; + iguana_bundlestats(coin,buf); + } } struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags) @@ -325,8 +359,7 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei #ifndef IGUANA_DEDICATED_THREADS coin->peers.peersloop = iguana_launch("peersloop",iguana_peersloop,coin,IGUANA_PERMTHREAD); #endif - if ( 0 && (coin->MAXBUNDLES= coin->bundlescount / 4) < _IGUANA_MAXBUNDLES ) - coin->MAXBUNDLES = _IGUANA_MAXBUNDLES; + coin->MAXBUNDLES = IGUANA_MAXPENDBUNDLES; printf("started.%s\n",coin->symbol); return(coin); } diff --git a/iguana/iguana_instantdex.c b/iguana/iguana_instantdex.c index b7dc24ed4..96eed5170 100755 --- a/iguana/iguana_instantdex.c +++ b/iguana/iguana_instantdex.c @@ -17,40 +17,19 @@ #include "exchanges777.h" -#define INSTANTDEX_HOPS 2 -#define INSTANTDEX_DURATION 60 - -#define INSTANTDEX_INSURANCERATE (1. / 777.) -#define INSTANTDEX_PUBEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" -#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" -#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" -#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" -#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" -#define INSTANTDEX_MINPERC 50. -#define INSTANTDEX_DECKSIZE 1000 - -struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; }; +struct instantdex_stateinfo *BTC_states; int32_t BTC_numstates; -struct instantdex_stateinfo +int64_t instantdex_BTCsatoshis(int64_t price,int64_t volume) { - char name[24]; int16_t ind,initialstate; - cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); - cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); - int16_t timeoutind,errorind; - struct instantdex_event *events; int32_t numevents; -}; + if ( volume > price ) + return(price * dstr(volume)); + else return(dstr(price) * volume); +} -struct bitcoin_swapinfo +int64_t instantdex_insurance(struct iguana_info *coin,int64_t amount) { - bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn; - bits256 orderhash,deposittxid,paymenttxid,altpaymenttxid,myfeetxid,otherfeetxid,othertrader; - uint64_t otherscut[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2],satoshis[2],insurance,bidid,askid,initiator64; - int32_t isbob,choosei,otherschoosei,cutverified,otherverifiedcut; - char altmsigaddr[64],expectedcmdstr[16],*deposit,*payment,*altpayment,*myfeetx,*otherfeetx; - double minperc,depositconfirms,paymentconfirms,altpaymentconfirms,myfeeconfirms,otherfeeconfirms; - struct instantdex_stateinfo *state; uint32_t expiration; -}; -struct instantdex_stateinfo *BTC_states; int32_t BTC_numstates; + return(amount * INSTANTDEX_INSURANCERATE + coin->chain->txfee); // insurance prevents attack +} void instantdex_swapfree(struct instantdex_accept *A,struct bitcoin_swapinfo *swap) { @@ -64,14 +43,14 @@ void instantdex_swapfree(struct instantdex_accept *A,struct bitcoin_swapinfo *sw free(swap->payment); if ( swap->altpayment != 0 ) free(swap->altpayment); - if ( swap->myfeetx != 0 ) - free(swap->myfeetx); - if ( swap->otherfeetx != 0 ) - free(swap->otherfeetx); + if ( swap->myfee != 0 ) + free(swap->myfee); + if ( swap->otherfee != 0 ) + free(swap->otherfee); } } -cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; *serdatap = 0, *serdatalenp = 0; @@ -81,8 +60,8 @@ cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_in } return(newjson); } - -cJSON *instantdex_defaulttimeout(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +//({"agent":"iguana","method":"addcoin","newcoin":"PPC","active":1,"maxpeers":128,"services":0,"poll":1,"RAM":4,"minoutput":100000,"minconfirms":3,"estblocktime":600,"path":"/data/ppcoin","conf":"/data/.ppcoin","txfee_satoshis":100000,"useaddmultisig":1,"hastimestamp":0,"userhome":"/data/SuperNET/iguana","pubval":"37","scriptval":"75","wiftype":"b7","netmagic":"e6e8e9e5","genesishash":"00000ffd590b1485b3caadc19b22e6379c733355108f107a430458cdf3407ab6","genesis":{"hashalgo":"sha256","version":1,"timestamp":1345084287,"nbits":"1d00ffff","nonce":2179302059,"merkleroot":"3c2d8f85fab4d17aac558cc648a1a58acff0de6deb890c29985690052c5993c2"},"p2p":9901,"rpc":9902}) +cJSON *instantdex_defaulttimeout(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; *serdatap = 0, *serdatalenp = 0; @@ -128,7 +107,7 @@ void instantdex_stateinit(struct instantdex_stateinfo *states,int32_t numstates, state->timeout = instantdex_defaulttimeout; } -struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr,int32_t initialstate) +struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr,int32_t initialstate) { struct instantdex_stateinfo S,*state = 0; if ( (state= instantdex_statefind(states,*numstatesp,name)) == 0 ) @@ -179,6 +158,9 @@ struct instantdex_event *instantdex_addevent(struct instantdex_stateinfo *states } else { + int32_t i; + for (i=0; i %s) without existing state and nextstate\n",statename,nextstatename); exit(-1); return(0); @@ -501,9 +483,10 @@ int32_t instantdex_bidaskdir(struct instantdex_offer *offer) else return(0); } -cJSON *instantdex_offerjson(struct instantdex_offer *offer) +cJSON *instantdex_offerjson(struct instantdex_offer *offer,uint64_t orderid) { int32_t dir; cJSON *item = cJSON_CreateObject(); + jadd64bits(item,"orderid",orderid); jadd64bits(item,"offerer",offer->offer64); if ( (dir= instantdex_bidaskdir(offer)) > 0 ) jaddstr(item,"type","bid"); @@ -520,6 +503,7 @@ cJSON *instantdex_offerjson(struct instantdex_offer *offer) jaddnum(item,"timestamp",offer->expiration); jaddnum(item,"price",dstr(offer->price64)); jaddnum(item,"volume",dstr(offer->basevolume64)); + jaddnum(item,"minperc",offer->minperc); jaddnum(item,"nonce",offer->nonce); jaddnum(item,"expiresin",offer->expiration - time(NULL)); return(item); @@ -532,29 +516,60 @@ cJSON *instantdex_acceptjson(struct instantdex_accept *ap) jaddnum(item,"pendingvolume",dstr(ap->pendingvolume64)); if ( ap->dead != 0 ) jadd64bits(item,"dead",ap->dead); - jadd(item,"offer",instantdex_offerjson(&ap->offer)); - if ( ap->otherorderid != 0 ) + jadd(item,"offer",instantdex_offerjson(&ap->offer,ap->orderid)); + return(item); +} + +void instantdex_statetxjson(cJSON *array,char *name,struct bitcoin_statetx *tx) +{ + cJSON *item; + if ( tx != 0 ) { - jadd64bits(item,"otherid",ap->orderid); - jadd(item,"otheroffer",instantdex_offerjson(&ap->otheroffer)); + item = cJSON_CreateObject(); + jaddbits256(item,"txid",tx->txid); + jaddnum(item,"inputsum",dstr(tx->inputsum)); + jaddnum(item,"amount",dstr(tx->amount)); + jaddnum(item,"change",dstr(tx->change)); + jaddnum(item,"txfee",dstr(tx->inputsum) - dstr(tx->amount) - dstr(tx->change)); + jaddnum(item,"confirms",dstr(tx->numconfirms)); + jaddstr(item,"destaddr",tx->destaddr); + jaddstr(item,"txbytes",tx->txbytes); + jadd(array,name,item); } - return(item); } -cJSON *instantdex_statemachinejson(struct instantdex_accept *ap) +cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap) { - struct bitcoin_swapinfo *swap = ap->info; cJSON *confirms,*retjson,*txs; + cJSON *retjson,*txs; int32_t isbob,mydir,otherdir; retjson = cJSON_CreateObject(); if ( swap != 0 ) { - jaddnum(retjson,"isbob",swap->isbob); + mydir = instantdex_bidaskdir(&swap->mine.offer); + otherdir = instantdex_bidaskdir(&swap->other.offer); + isbob = instantdex_isbob(swap); + jaddnum(retjson,"isbob",isbob); + jaddnum(retjson,"mydir",mydir); + jaddnum(retjson,"otherdir",otherdir); + jaddnum(retjson,"expiration",swap->expiration); + jaddnum(retjson,"insurance",dstr(swap->insurance)); + jaddnum(retjson,"baseamount",dstr(swap->altsatoshis)); + jaddnum(retjson,"BTCamount",dstr(swap->BTCsatoshis)); + jaddnum(retjson,"expiration",swap->expiration); + if ( swap->dead != 0 ) + jadd64bits(retjson,"dead",swap->dead); jaddbits256(retjson,"privAm",swap->privAm); jaddbits256(retjson,"pubAm",swap->pubAm); jaddbits256(retjson,"privBn",swap->privBn); jaddbits256(retjson,"pubBn",swap->pubBn); + + jaddbits256(retjson,"myorderhash",swap->myorderhash); + jaddnum(retjson,"choosei",swap->choosei); + jaddnum(retjson,"cutverified",swap->cutverified); jaddbits256(retjson,"othertrader",swap->othertrader); - jaddbits256(retjson,"orderhash",swap->orderhash); - if ( swap->isbob == 0 ) + jaddbits256(retjson,"otherorderhash",swap->otherorderhash); + jaddnum(retjson,"otherchoosei",swap->otherchoosei); + jaddnum(retjson,"otherverifiedcut",swap->otherverifiedcut); + if ( isbob == 0 ) { jaddbits256(retjson,"pubA0",swap->mypubs[0]); jaddbits256(retjson,"pubA1",swap->mypubs[1]); @@ -568,104 +583,97 @@ cJSON *instantdex_statemachinejson(struct instantdex_accept *ap) jaddbits256(retjson,"pubA0",swap->otherpubs[0]); jaddbits256(retjson,"pubA1",swap->otherpubs[1]); } - jaddnum(retjson,"choosei",swap->choosei); - jaddnum(retjson,"otherschoosei",swap->otherschoosei); - jaddnum(retjson,"otherschoosei",swap->otherschoosei); - jaddnum(retjson,"cutverified",swap->cutverified); - jaddnum(retjson,"otherverifiedcut",swap->otherverifiedcut); - - jaddnum(retjson,"expiration",swap->expiration); - jaddnum(retjson,"minperc",swap->minperc * 100.); - jaddnum(retjson,"insurance",dstr(swap->insurance)); - jaddnum(retjson,"baseamount",dstr(swap->satoshis[0])); - jaddnum(retjson,"BTCamount",dstr(swap->satoshis[1])); - jadd64bits(retjson,"bidid",swap->bidid); - jadd64bits(retjson,"askid",swap->askid); - jaddstr(retjson,"altmsigaddr",swap->altmsigaddr); + if ( mydir > 0 && otherdir < 0 ) + { + jadd64bits(retjson,"bidid",swap->mine.orderid); + jadd64bits(retjson,"askid",swap->other.orderid); + } + else if ( mydir < 0 && otherdir > 0 ) + { + jadd64bits(retjson,"askid",swap->mine.orderid); + jadd64bits(retjson,"bidid",swap->other.orderid); + } + if ( swap->matched64 == swap->mine.orderid ) + { + jadd(retjson,"initiator",instantdex_acceptjson(&swap->other)); + jadd(retjson,"matched",instantdex_acceptjson(&swap->mine)); + } + else if ( swap->matched64 == swap->other.orderid ) + { + jadd(retjson,"initiator",instantdex_acceptjson(&swap->mine)); + jadd(retjson,"matched",instantdex_acceptjson(&swap->other)); + } + else jaddstr(retjson,"initiator","illegal initiator missing"); if ( swap->state != 0 ) jaddstr(retjson,"state",swap->state->name); - jaddstr(retjson,"expected",swap->expectedcmdstr); - confirms = cJSON_CreateObject(); - jaddnum(confirms,"deposit",swap->depositconfirms); - jaddnum(confirms,"payment",swap->paymentconfirms); - jaddnum(confirms,"altpayment",swap->altpaymentconfirms); - jaddnum(confirms,"myfee",swap->myfeeconfirms); - jaddnum(confirms,"otherfee",swap->otherfeeconfirms); - jadd(retjson,"confirms",confirms); txs = cJSON_CreateObject(); - if ( swap->deposit != 0 ) - jaddstr(txs,"deposit",swap->deposit), jaddbits256(txs,"deposittxid",swap->deposittxid); - if ( swap->payment != 0 ) - jaddstr(txs,"payment",swap->payment), jaddbits256(txs,"paymenttxid",swap->paymenttxid); - if ( swap->altpayment != 0 ) - jaddstr(txs,"altpayment",swap->altpayment), jaddbits256(txs,"altpaymenttxid",swap->altpaymenttxid); - if ( swap->myfeetx != 0 ) - jaddstr(txs,"myfee",swap->myfeetx), jaddbits256(txs,"myfeetxid",swap->myfeetxid);; - if ( swap->otherfeetx != 0 ) - jaddstr(txs,"otherfee",swap->otherfeetx), jaddbits256(txs,"otherfeetxid",swap->otherfeetxid); - jadd(retjson,"txs",confirms); - jaddbits256(retjson,"othertrader",swap->othertrader); + instantdex_statetxjson(txs,"deposit",swap->deposit); + instantdex_statetxjson(txs,"payment",swap->payment); + instantdex_statetxjson(txs,"altpayment",swap->altpayment); + instantdex_statetxjson(txs,"myfee",swap->myfee); + instantdex_statetxjson(txs,"otherfee",swap->otherfee); + jadd(retjson,"txs",txs); + jaddstr(retjson,"status",swap->status); } - jadd(retjson,"swap",instantdex_acceptjson(ap)); return(retjson); } -cJSON *instantdex_historyjson(struct instantdex_accept *ap) +cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap) { // need to make sure accepts are put onto history queue when they are completed or deaded // also to make permanent copy (somewhere) - return(instantdex_acceptjson(ap)); + return(instantdex_statemachinejson(swap)); } -struct instantdex_accept *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid) +struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid) { - struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; + struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now; now = (uint32_t)time(NULL); memset(&PAD,0,sizeof(PAD)); queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); - while ( (ap= queue_dequeue(&exchange->historyQ,0)) != 0 && ap != &PAD ) + while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD ) { - if ( orderid == ap->orderid ) - retap = ap; - queue_enqueue("historyQ",&exchange->historyQ,&ap->DL,0); + if ( orderid == swap->mine.orderid ) + retswap = swap; + queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); } - return(retap); + return(retswap); } -struct instantdex_accept *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag) +struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag) { - struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; + struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now; now = (uint32_t)time(NULL); memset(&PAD,0,sizeof(PAD)); queue_enqueue("statemachineQ",&exchange->statemachineQ,&PAD.DL,0); - while ( (ap= queue_dequeue(&exchange->statemachineQ,0)) != 0 && ap != &PAD ) + while ( (swap= queue_dequeue(&exchange->statemachineQ,0)) != 0 && swap != &PAD ) { - if ( now < ap->offer.expiration && ap->dead == 0 ) + if ( now < swap->expiration && swap->mine.dead == 0 && swap->other.dead == 0 ) { - if ( orderid == ap->orderid ) + if ( orderid == swap->mine.orderid || orderid == swap->other.orderid ) { - if ( retap != 0 && requeueflag == 0 ) - queue_enqueue("statemachineQ",&exchange->statemachineQ,&retap->DL,0); - retap = ap; + if ( retswap != 0 && requeueflag == 0 ) + queue_enqueue("statemachineQ",&exchange->statemachineQ,&retswap->DL,0); + retswap = swap; } } else { + strcpy(swap->status,"expired"); printf("expired pending, need to take action, send timeout event\n"); - free(ap); + queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); continue; } - if ( ap != retap || requeueflag != 0 ) - queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0); + if ( swap != retswap || requeueflag != 0 ) + queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); } - return(retap); + //printf("found statemachine.%p\n",retswap); + return(retswap); } struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue) { - struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; cJSON *item; char *type; - //if ( (retap= instantdex_statemachinefind(myinfo,exchange,orderid,requeue)) != 0 ) - // return(retap); + struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; cJSON *item,*offerobj; char *type; now = (uint32_t)time(NULL); memset(&PAD,0,sizeof(PAD)); queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); @@ -673,10 +681,9 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,stru { if ( now < ap->offer.expiration && ap->dead == 0 ) { - //printf("find cmps %d %d %d %d %d %d\n",strcmp(base,"*") == 0,strcmp(base,ap->offer.base) == 0,strcmp(rel,"*") == 0,strcmp(rel,ap->offer.rel) == 0,orderid == 0,orderid == ap->orderid); + //printf("%d %d find cmps %d %d %d %d %d %d me.%llu vs %llu o.%llu | vs %llu\n",instantdex_bidaskdir(&ap->offer),ap->offer.expiration-now,strcmp(base,"*") == 0,strcmp(base,ap->offer.base) == 0,strcmp(rel,"*") == 0,strcmp(rel,ap->offer.rel) == 0,orderid == 0,orderid == ap->orderid,(long long)myinfo->myaddr.nxt64bits,(long long)ap->offer.offer64,(long long)ap->orderid,(long long)orderid); if ( (strcmp(base,"*") == 0 || strcmp(base,ap->offer.base) == 0) && (strcmp(rel,"*") == 0 || strcmp(rel,ap->offer.rel) == 0) && (orderid == 0 || orderid == ap->orderid) ) { - //printf("found match.%p\n",ap); if ( requeue == 0 && retap != 0 ) queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0); retap = ap; @@ -684,14 +691,15 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,stru if ( (item= instantdex_acceptjson(ap)) != 0 ) { //printf("item.(%s)\n",jprint(item,0)); - if ( (type= jstr(item,"type")) != 0 ) + if ( (offerobj= jobj(item,"offer")) != 0 && (type= jstr(offerobj,"type")) != 0 ) { if ( strcmp(type,"bid") == 0 && bids != 0 ) - jaddi(bids,item); + jaddi(bids,jduplicate(offerobj)); else if ( strcmp(type,"ask") == 0 && asks != 0 ) - jaddi(asks,item); + jaddi(asks,jduplicate(offerobj)); } - } + free_json(item); + } else printf("error generating acceptjson.%llu\n",(long long)ap->orderid); if ( ap != retap || requeue != 0 ) { //printf("requeue.%p\n",ap); @@ -702,40 +710,53 @@ struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,stru return(retap); } -struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,uint64_t offerbits,double minperc) +struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc) { - struct instantdex_accept PAD,*ap,*retap = 0; double aveprice,retvals[4]; + struct instantdex_accept PAD,*ap,*retap = 0; double aveprice;//,retvals[4]; uint64_t minvol,bestprice64 = 0; uint32_t now; int32_t offerdir; - aveprice = instantdex_avehbla(myinfo,retvals,A->offer.base,A->offer.rel,dstr(A->offer.basevolume64)); + aveprice = 0;//instantdex_avehbla(myinfo,retvals,A->offer.base,A->offer.rel,dstr(A->offer.basevolume64)); now = (uint32_t)time(NULL); memset(&PAD,0,sizeof(PAD)); queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); offerdir = instantdex_bidaskdir(&A->offer); - minvol = A->offer.basevolume64 * minperc * .01; + minvol = (A->offer.basevolume64 * minperc * .01); + printf("offerdir.%d (%s/%s) minperc %.3f minvol %.8f vs %.8f\n",offerdir,A->offer.base,A->offer.rel,minperc,dstr(minvol),dstr(A->offer.basevolume64)); while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD ) { - //printf("check offerbits.%llu vs %llu: %d %d %d %d %d %d %d %d\n",(long long)offerbits,(long long)ap->offer.offer64,A->offer.basevolume64 > 0.,strcmp(A->offer.base,"*") == 0 ,strcmp(A->offer.base,ap->offer.base) == 0, strcmp(A->offer.rel,"*") == 0 ,strcmp(A->offer.rel,ap->offer.rel) == 0,A->offer.basevolume64 <= (ap->offer.basevolume64 - ap->pendingvolume64),offerdir,instantdex_bidaskdir(ap)); - if ( now < ap->offer.expiration && ap->dead == 0 && (offerbits == 0 || offerbits != ap->offer.offer64) ) + if ( now > ap->offer.expiration || ap->dead != 0 || A->offer.offer64 == ap->offer.offer64 ) + { + //printf("now.%u skip expired %u/dead.%u or my order orderid.%llu from %llu\n",now,ap->offer.expiration,ap->dead,(long long)ap->orderid,(long long)ap->offer.offer64); + } + else if ( strcmp(ap->offer.base,A->offer.base) != 0 || strcmp(ap->offer.rel,A->offer.rel) != 0 ) + { + //printf("skip mismatched.(%s/%s) orderid.%llu from %llu\n",ap->offer.base,ap->offer.rel,(long long)ap->orderid,(long long)ap->offer.offer64); + } + else if ( offerdir*instantdex_bidaskdir(&ap->offer) > 0 ) + { + //printf("skip same direction %d orderid.%llu from %llu\n",instantdex_bidaskdir(&ap->offer),(long long)ap->orderid,(long long)ap->offer.offer64); + } + else if ( minvol > ap->offer.basevolume64 - ap->pendingvolume64 ) { - if ( A->offer.basevolume64 > 0. && (strcmp(A->offer.base,"*") == 0 || strcmp(A->offer.base,ap->offer.base) == 0) && (strcmp(A->offer.rel,"*") == 0 || strcmp(A->offer.rel,ap->offer.rel) == 0) && minvol <= (ap->offer.basevolume64 - ap->pendingvolume64) && offerdir*instantdex_bidaskdir(&ap->offer) < 0 ) + //printf("skip too small order %.8f vs %.8f orderid.%llu from %llu\n",dstr(minvol),dstr(ap->offer.basevolume64)-dstr(ap->pendingvolume64),(long long)ap->orderid,(long long)ap->offer.offer64); + } + else if ( (offerdir > 0 && ap->offer.price64 > A->offer.price64) || (offerdir < 0 && ap->offer.price64 < A->offer.price64) ) + { + //printf("skip out of band dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.offer64); + } + else + { + if ( bestprice64 == 0 || (offerdir > 0 && ap->offer.price64 < bestprice64) || (offerdir < 0 && ap->offer.price64 > bestprice64) ) { - //printf("aveprice %.8f %.8f offerdir.%d first cmp: %d %d %d\n",aveprice,dstr(ap->offer.price64),offerdir,A->offer.price64 == 0,(offerdir > 0 && ap->offer.price64 >= A->offer.price64),(offerdir < 0 && ap->offer.price64 <= A->offer.price64)); - if ( offerdir == 0 || A->offer.price64 == 0 || ((offerdir < 0 && ap->offer.price64 >= A->offer.price64) || (offerdir > 0 && ap->offer.price64 <= A->offer.price64)) ) - { - //printf("passed second cmp: offerdir.%d best %.8f ap %.8f\n",offerdir,dstr(bestprice64),dstr(ap->offer.price64)); - if ( bestprice64 == 0 || (offerdir < 0 && ap->offer.price64 < bestprice64) || (offerdir > 0 && ap->offer.price64 > bestprice64) ) - { - printf("found better price %f vs %f\n",dstr(ap->offer.price64),dstr(bestprice64)); - bestprice64 = ap->offer.price64; - if ( retap != 0 ) - queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0); - retap = ap; - } - } + printf(">>>> MATCHED better price dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.offer64); + bestprice64 = ap->offer.price64; + if ( retap != 0 ) + queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0); + retap = ap; } - if ( ap != retap ) - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - } else free(ap); + } + if ( ap != retap ) + queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); + else free(ap); } return(retap); } @@ -752,7 +773,7 @@ struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,str // NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey // BTC* node approves phased tx with onetimepubkey -bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t offerbits,uint32_t nonce) +bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t offerbits,uint32_t nonce,uint8_t minperc) { bits256 hash; memset(ap,0,sizeof(*ap)); @@ -767,6 +788,7 @@ bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,i ap->offer.offer64 = offerbits; ap->offer.myside = myside; ap->offer.acceptdir = acceptdir; + ap->offer.minperc = minperc; ap->offer.price64 = price * SATOSHIDEN; ap->offer.basevolume64 = volume * SATOSHIDEN; vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer)); @@ -780,11 +802,15 @@ bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,i int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson) { - char *base,*rel; bits256 hash,traderpub; double price,volume; int32_t baserel,acceptdir; + char *base,*rel; bits256 hash,traderpub; double price,volume; int32_t baserel,acceptdir,minperc; memset(ap,0,sizeof(*ap)); if ( (base= jstr(argjson,"base")) != 0 ) { volume = jdouble(argjson,"volume"); + if ( (minperc= juint(argjson,"minperc")) < INSTANTDEX_MINPERC ) + minperc = INSTANTDEX_MINPERC; + else if ( minperc > 100 ) + minperc = 100; if ( (rel= jstr(argjson,"rel")) != 0 ) safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); if ( (price= jdouble(argjson,"maxprice")) > SMALLVAL ) @@ -799,7 +825,7 @@ int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson) } else return(-1); //printf("price %f vol %f baserel.%d acceptdir.%d\n",price,volume,baserel,acceptdir); traderpub = jbits256(argjson,"traderpub"); - hash = instantdex_acceptset(ap,base,rel,INSTANTDEX_LOCKTIME*2,baserel,acceptdir,price,volume,traderpub.txid,0); + hash = instantdex_acceptset(ap,base,rel,INSTANTDEX_LOCKTIME*2,baserel,acceptdir,price,volume,traderpub.txid,0,minperc); } else { @@ -814,6 +840,8 @@ int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson) ap->offer.offer64 = j64bits(argjson,"o"); ap->offer.price64 = j64bits(argjson,"p"); ap->offer.basevolume64 = j64bits(argjson,"v"); + if ( (ap->offer.minperc= juint(argjson,"m")) < INSTANTDEX_MINPERC ) + ap->offer.minperc = INSTANTDEX_MINPERC; vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer)); ap->orderid = j64bits(argjson,"id"); } @@ -833,188 +861,121 @@ int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson) #include "swaps/iguana_NXTswap.c" #include "swaps/iguana_PAXswap.c" -char *instantdex_swapset(struct supernet_info *myinfo,struct instantdex_accept *ap,cJSON *argjson) +struct bitcoin_swapinfo *bitcoin_swapinit(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,int32_t aminitiator,cJSON *argjson,char *statename) { - uint64_t satoshis[2]; int32_t offerdir = 0; double minperc; uint64_t insurance,relsatoshis; - struct bitcoin_swapinfo *swap; bits256 orderhash,traderpub; struct iguana_info *coinbtc; - if ( (swap= ap->info) == 0 ) - return(clonestr("{\"error\":\"no swapinfo set\"}")); - relsatoshis = instantdex_BTCsatoshis(ap->offer.price64,ap->offer.basevolume64); - traderpub = jbits256(argjson,"traderpub"); - if ( (minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - if ( (coinbtc= iguana_coinfind("BTC")) == 0 ) - return(clonestr("{\"error\":\"no BTC found\"}")); - insurance = (satoshis[1] * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee prevents papercut attack - offerdir = instantdex_bidaskdir(&ap->offer); - vcalc_sha256(0,orderhash.bytes,(void *)&ap->offer,sizeof(ap->offer)); - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("swapset.%llu\n",(long long)ap->orderid); - } - if ( offerdir > 0 ) + struct bitcoin_swapinfo *swap = 0; struct iguana_info *coinbtc,*altcoin; + swap = calloc(1,sizeof(struct bitcoin_swapinfo)); + swap->state = instantdex_statefind(BTC_states,BTC_numstates,statename); + swap->mine = *myap, swap->other = *otherap; + if ( (swap->isinitiator= aminitiator) != 0 ) { - swap->bidid = ap->orderid; - swap->askid = ap->otherorderid; + swap->matched64 = otherap->orderid; + swap->expiration = otherap->offer.expiration; } else { - swap->askid = ap->orderid; - swap->bidid = ap->otherorderid; + swap->matched64 = myap->orderid; + swap->expiration = myap->offer.expiration; } - if ( bits256_nonz(swap->othertrader) == 0 ) - swap->othertrader = traderpub; - else if ( bits256_cmp(traderpub,swap->othertrader) != 0 ) + swap->choosei = swap->otherchoosei = -1; + strcpy(swap->status,"pending"); + vcalc_sha256(0,swap->myorderhash.bytes,(void *)&swap->mine.offer,sizeof(swap->mine.offer)); + vcalc_sha256(0,swap->otherorderhash.bytes,(void *)&swap->other.offer,sizeof(swap->other.offer)); + swap->mypubkey = myinfo->myaddr.persistent; + swap->othertrader = jbits256(argjson,"traderpub"); + swap->altsatoshis = myap->offer.basevolume64; + swap->BTCsatoshis = instantdex_BTCsatoshis(myap->offer.price64,myap->offer.basevolume64); + if ( (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(swap->mine.offer.base)) == 0 ) { - printf("competing offer received for (%s/%s) %.8f %.8f\n",ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64)); - return(clonestr("{\"error\":\"no competing offers for now\"}")); + printf("cant find BTC or %s\n",swap->mine.offer.base); + return(0); } - if ( bits256_nonz(swap->orderhash) == 0 ) - swap->orderhash = orderhash; - else if ( bits256_cmp(orderhash,swap->orderhash) != 0 ) + swap->insurance = (swap->BTCsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); + swap->altpremium = (swap->altsatoshis * INSTANTDEX_INSURANCERATE + altcoin->chain->txfee); + if ( myap->offer.myside != instantdex_isbob(swap) || otherap->offer.myside == instantdex_isbob(swap) ) { - printf("orderhash %llx mismatch %llx\n",(long long)swap->orderhash.txid,(long long)orderhash.txid); - return(clonestr("{\"error\":\"orderhash mismatch???\"}")); + printf("isbob error.(%d %d) %d\n",myap->offer.myside,otherap->offer.myside,instantdex_isbob(swap)); + return(0); } - swap->satoshis[0] = ap->offer.basevolume64; - swap->satoshis[1] = relsatoshis; - swap->insurance = (relsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); // txfee - if ( swap->minperc < minperc ) - swap->minperc = minperc; - return(0); + return(swap); } -char *instantdex_addfeetx(struct supernet_info *myinfo,cJSON *newjson,struct instantdex_accept *ap,struct bitcoin_swapinfo *swap,char *bobstate,char *alicestate) +char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *myap,cJSON *argjson) { - if ( (swap->myfeetx= instantdex_feetx(myinfo,&swap->myfeetxid,ap)) != 0 ) + char *retstr = 0; struct instantdex_accept *otherap; struct bitcoin_swapinfo *swap; cJSON *newjson; int32_t isbob = 0; + *txidp = myap->orderid; + if ( (otherap= instantdex_acceptable(myinfo,exchange,myap,myap->offer.minperc)) == 0 ) { - jaddstr(newjson,"feetx",swap->myfeetx); - jaddbits256(newjson,"feetxid",swap->myfeetxid); - swap->state = instantdex_statefind(BTC_states,BTC_numstates,swap->isbob != 0 ? bobstate : alicestate); - return(0); + printf("add.%llu to acceptableQ\n",(long long)myap->orderid); + if ( (retstr= instantdex_sendcmd(myinfo,&myap->offer,argjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,0,0)) != 0 ) + free(retstr); + queue_enqueue("acceptableQ",&exchange->acceptableQ,&myap->DL,0); + return(jprint(instantdex_offerjson(&myap->offer,myap->orderid),1)); } - return(clonestr("{\"error\":\"couldnt create feetx\"}")); -} - -char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson) // Bob sending to network (Alice) -{ - struct iguana_info *other; struct bitcoin_swapinfo *swap; int32_t isbob; cJSON *newjson; char *retstr; - if ( strcmp(ap->offer.rel,"BTC") != 0 ) - return(clonestr("{\"error\":\"invalid othercoin\"}")); - else if ( (other= iguana_coinfind(ap->offer.base)) == 0 ) - return(clonestr("{\"error\":\"invalid othercoin\"}")); - else if ( ap->offer.price64 <= 0 || ap->offer.basevolume64 <= 0 ) - return(clonestr("{\"error\":\"illegal price or volume\"}")); - isbob = (ap->offer.myside == 1); - swap = calloc(1,sizeof(struct bitcoin_swapinfo)); - swap->isbob = isbob; - swap->expiration = ap->offer.expiration;//(uint32_t)(time(NULL) + INSTANTDEX_LOCKTIME*isbob); - swap->choosei = swap->otherschoosei = -1; - swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1; - ap->info = swap; - printf("sendoffer SETSWAP for orderid.%llu ap.%p (%p)\n",(long long)ap->orderid,ap,swap); - if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) - return(retstr); - ap->orderid = swap->orderhash.txid; - if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); - else if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,swap,"BOB_sentoffer","ALICE_sentoffer")) == 0 ) + else { - //instantdex_bobtx(myinfo,iguana_coinfind("BTCD"),&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],ap->offer.expiration-INSTANTDEX_LOCKTIME*2,swap->satoshis[1],1); - //instantdex_alicetx(myinfo,iguana_coinfind("BTCD"),swap->altmsigaddr,&swap->altpaymenttxid,swap->pubAm,swap->pubBn,swap->satoshis[0]); - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("BTCoffer.%llu\n",(long long)ap->orderid); - } - return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); + isbob = myap->offer.myside; + swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,1,argjson,isbob != 0 ? "BOB_sentoffer" : "ALICE_sentoffer"); + printf("STATEMACHINEQ.(%llu / %llu)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid); + //queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0); + queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); + if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) + return(clonestr("{\"error\":\"instantdex_checkoffer null newjson\"}")); + return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); } - else return(retstr); + return(retstr); } -char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side +char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side { - struct bitcoin_swapinfo *swap = 0; bits256 traderpub; struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0; - swap = ap->info; + struct bitcoin_swapinfo *swap = 0; bits256 traderpub; struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0; int32_t isbob; coinbtc = iguana_coinfind("BTC"); traderpub = jbits256(argjson,"traderpub"); if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) { - printf("got my own gotoffer packet orderid.%llu\n",(long long)ap->orderid); + printf("got my own gotoffer packet orderid.%llu/%llu\n",(long long)myap->orderid,(long long)otherap->orderid); return(clonestr("{\"result\":\"got my own packet\"}")); } if ( 0 ) { int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&ap->offer)[i]); - printf("BTCoffer.%llu\n",(long long)ap->orderid); + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&otherap->offer)[i]); + printf("gotoffer.%llu\n",(long long)otherap->orderid); } - printf("T.%d got (%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d swap.%p decksize.%ld/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),ap->offer.base,ap->offer.rel,dstr(ap->offer.price64),dstr(ap->offer.basevolume64),(long long)ap->orderid,ap->offer.myside,ap->offer.acceptdir,ap->info,sizeof(swap->deck),serdatalen); + printf(">>>>>>>>> GOTOFFER T.%d got (%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d decksize.%ld/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),myap->offer.base,myap->offer.rel,dstr(myap->offer.price64),dstr(myap->offer.basevolume64),(long long)myap->orderid,myap->offer.myside,myap->offer.acceptdir,sizeof(swap->deck),serdatalen); if ( exchange == 0 ) return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}")); - if ( (altcoin= iguana_coinfind(ap->offer.base)) == 0 || coinbtc == 0 ) + if ( (altcoin= iguana_coinfind(myap->offer.base)) == 0 || coinbtc == 0 ) return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}")); - if ( strcmp(ap->offer.rel,"BTC") != 0 ) + if ( strcmp(myap->offer.rel,"BTC") != 0 ) return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}")); - if ( ap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) + if ( myap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) || otherap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}")); - if ( ap->info == 0 ) - ap->info = swap = calloc(1,sizeof(struct bitcoin_swapinfo)); - //printf("gotoffer SETSWAP for orderid.%llu (%s)\n",(long long)ap->orderid,jprint(argjson,0)); - swap->choosei = swap->otherschoosei = -1; - swap->depositconfirms = swap->paymentconfirms = swap->altpaymentconfirms = swap->myfeeconfirms = swap->otherfeeconfirms = -1; - swap->isbob = (ap->offer.myside ^ 1); - if ( (retstr= instantdex_swapset(myinfo,ap,argjson)) != 0 ) - return(retstr); - if ( instantdex_pubkeyargs(swap,newjson,2+INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->orderhash,0x02 + swap->isbob) != 2+INSTANTDEX_DECKSIZE ) - return(clonestr("{\"error\":\"instantdex_BTCswap error creating pubkeyargs\"}")); - char str[65]; printf("GOT OFFER! orderid.%llu %p (%s/%s) other.%s myside.%d\n",(long long)ap->orderid,ap->info,ap->offer.base,ap->offer.rel,bits256_str(str,traderpub),swap->isbob); - if ( (newjson= instantdex_parseargjson(myinfo,exchange,ap,argjson,1)) == 0 ) + isbob = myap->offer.myside; + swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,0,argjson,isbob != 0 ? "BOB_gotoffer" : "ALICE_gotoffer"); + if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) + { + printf("error parsing argjson\n"); return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); - else if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,swap,"BOB_gotoffer","ALICE_gotoffer")) == 0 ) + } + else //if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,swap,"BOB_gotoffer","ALICE_gotoffer")) == 0 ) { - //instantdex_pendingnotice(myinfo,exchange,A,ap->offer.basevolume64); + queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0); + queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) return(retstr); else { - return(instantdex_sendcmd(myinfo,&ap->offer,newjson,"BTCdeckC",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); + return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCdeckC",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); } - } else return(retstr); -} - -char *instantdex_selectqueue(struct exchange_info *exchange,struct instantdex_accept *ap,char *retstr) -{ - cJSON *retjson; int32_t flag = 0; - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( jobj(retjson,"error") != 0 ) - { - printf("requeue acceptableQ gotoffer error.(%s)\n",jprint(retjson,0)); - instantdex_swapfree(0,ap->info); - ap->info = 0; - flag++; - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - } - free_json(retjson); - } - if ( flag == 0 ) - { - printf("add orderid.%llu to statemachine\n",(long long)ap->orderid); - queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0); } return(retstr); } char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,struct instantdex_offer *offer,bits256 orderhash,uint8_t *serdata,int32_t serdatalen) { - char cmdstr[16],*retstr; struct exchange_info *exchange; double minperc; struct instantdex_accept A,*ap = 0; bits256 traderpub; cJSON *newjson; + char cmdstr[16],*retstr; struct exchange_info *exchange; struct instantdex_accept A,*ap = 0; bits256 traderpub; cJSON *newjson; struct bitcoin_swapinfo *swap; if ( BTC_states == 0 ) BTC_states = BTC_initFSM(&BTC_numstates); exchange = exchanges777_find("bitcoin"); @@ -1030,50 +991,25 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms } A.offer = *offer; A.orderid = orderhash.txid; - if ( strcmp(cmdstr,"BTCoffer") == 0 || strcmp(cmdstr,"BTCdeckC") == 0 ) + printf("got.(%s) for %llu offer64.%llu\n",cmdstr,(long long)A.orderid,(long long)A.offer.offer64); + if ( (A.offer.minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) + A.offer.minperc = INSTANTDEX_MINPERC; + else if ( A.offer.minperc > 100 ) + A.offer.minperc = 100; + if ( strcmp(cmdstr,"BTCoffer") == 0 ) // incoming { - if ( (minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - if ( (ap= instantdex_acceptable(myinfo,exchange,&A,acct777_nxt64bits(traderpub),minperc)) != 0 ) + printf("BTCoffer state\n"); + if ( (ap= instantdex_acceptable(myinfo,exchange,&A,A.offer.minperc)) != 0 ) { - if ( strcmp(cmdstr,"BTCoffer") == 0 ) + if ( (retstr= instantdex_gotoffer(myinfo,exchange,ap,&A,msg,argjson,remoteaddr,signerbits,serdata,serdatalen)) != 0 ) // adds to statemachine if no error { - if ( ap->otherorderid == 0 ) - { - ap->otherorderid = A.orderid; - ap->otheroffer = A.offer; - } - if ( (retstr= instantdex_gotoffer(myinfo,exchange,ap,msg,argjson,remoteaddr,signerbits,serdata,serdatalen)) != 0 ) // adds to statemachine if no error - { - //printf("from GOTOFFER\n"); - return(instantdex_selectqueue(exchange,ap,retstr)); - } - } - else - { - if ( ap->info == 0 ) - { - printf("A (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap); - return(clonestr("{\"error\":\"no swap for orderid\"}")); - } - else - { - if ( ap->otherorderid == 0 ) - { - ap->otherorderid = ap->orderid; - ap->otheroffer = ap->offer; - ap->offer = A.offer; - ap->orderid = A.orderid; - } - queue_enqueue("statemachineQ",&exchange->statemachineQ,&ap->DL,0); - newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0); - return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen)); - } - } + printf("from GOTOFFER.(%s)\n",retstr); + return(retstr); + } else return(clonestr("{\"error\":\"gotoffer error\"}")); } else { - printf("no matching trade for %llu -> InstantDEX_minaccept isbob.%d\n",(long long)A.orderid,A.offer.myside); + printf("no matching trade for %s %llu -> InstantDEX_minaccept isbob.%d\n",cmdstr,(long long)A.orderid,A.offer.myside); if ( instantdex_offerfind(myinfo,exchange,0,0,A.orderid,"*","*",1) == 0 ) { ap = calloc(1,sizeof(*ap)); @@ -1084,22 +1020,16 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms } else return(clonestr("{\"result\":\"order was already in orderbook\"}")); } } - else if ( (ap= instantdex_statemachinefind(myinfo,exchange,A.orderid,1)) != 0 || (ap= instantdex_offerfind(myinfo,exchange,0,0,A.orderid,"*","*",0)) != 0 ) + else if ( (swap= instantdex_statemachinefind(myinfo,exchange,A.orderid,1)) != 0 ) { - if ( ap->info == 0 ) + //printf("found existing state machine %llu\n",(long long)A.orderid); + newjson = instantdex_parseargjson(myinfo,exchange,swap,argjson,0); + if ( serdatalen == sizeof(swap->otherdeck) && swap->choosei < 0 && (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) { - if ( strcmp(cmdstr,"BTCdeckC") != 0 ) - { - printf("B (%s) null swap for orderid.%llu p.%p\n",cmdstr,(long long)ap->orderid,ap); - return(clonestr("{\"error\":\"no swap for orderid\"}")); - } - else - { - printf("BTCdeckC ap.%p null info\n",ap->info); - } + printf("error choosei\n"); + return(retstr); } - newjson = instantdex_parseargjson(myinfo,exchange,ap,argjson,0); - return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,ap,cmdstr,argjson,newjson,serdata,serdatalen)); + return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,swap,cmdstr,argjson,newjson,serdata,serdatalen)); } else { @@ -1110,7 +1040,7 @@ char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *ms return(clonestr("{\"error\":\"request needs argjson\"}")); } -char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr) +char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr) { struct instantdex_msghdr *msg = ptr; int32_t i,olen,slen,num,datalen,newlen,flag = 0; uint8_t *serdata; struct supernet_info *myinfos[64]; struct instantdex_offer rawoffer; @@ -1130,12 +1060,10 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char free_json(argjson); return(clonestr("{\"error\":\"string base packets deprecated\"}")); } - //printf("msg.%p len.%d data.%p datalen.%d crc.%u %s\n",msg,len,data,datalen,calc_crc32(0,(void *)msg,len),bits256_str(str,msg->sig.pubkey)); - //return(0); - else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 || 1 ) + else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 )//|| 1 ) { flag++; - //printf("InstantDEX_hexmsg <<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); + printf("InstantDEX_hexmsg <<<<<<<<<<<<< sigsize.%ld VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); serdata = msg->serialized; //printf("newlen.%d diff.%ld alloc.%d datalen.%d\n",newlen,((long)msg->serialized - (long)msg),msg->sig.allocsize,datalen); @@ -1189,7 +1117,7 @@ char *InstantDEX_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char return(retstr); } -char *instantdex_queueaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag) +char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag,uint8_t minperc) { struct instantdex_accept *ap; int32_t myside; char *retstr; *aptrp = 0; @@ -1205,7 +1133,7 @@ char *instantdex_queueaccept(struct supernet_info *myinfo,struct instantdex_acce myside = -1; printf("myside.(%s) != base.%s or rel.%s\n",mysidestr,base,rel); } - instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,offerer,0); + instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,offerer,0,minperc); if ( queueflag != 0 ) { printf("acceptableQ <- %llu\n",(long long)ap->orderid); @@ -1219,13 +1147,13 @@ char *instantdex_queueaccept(struct supernet_info *myinfo,struct instantdex_acce void instantdex_update(struct supernet_info *myinfo) { - struct instantdex_msghdr *pm; struct category_msg *m; bits256 instantdexhash; char *str,remote[64]; queue_t *Q; struct queueitem *item; + struct instantdex_msghdr *pm; struct category_msg *m; bits256 instantdexhash; char *str,remote[64]; queue_t *Q; struct queueitem *item; struct category_info *cat; instantdexhash = calc_categoryhashes(0,"InstantDEX",0); //char str2[65]; printf("instantdexhash.(%s)\n",bits256_str(str2,instantdexhash)); - if ( (Q= category_Q(instantdexhash,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) + if ( (Q= category_Q(&cat,instantdexhash,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) { m = (void *)item; - m= queue_dequeue(Q,0); + m = queue_dequeue(Q,0); pm = (struct instantdex_msghdr *)m->msg; //printf("loop cmd.(%s)\n",pm->cmd); //if ( m->remoteipbits == 0 && (m= queue_dequeue(Q,0)) ) @@ -1236,47 +1164,103 @@ void instantdex_update(struct supernet_info *myinfo) if ( m->remoteipbits != 0 ) expand_ipbits(remote,m->remoteipbits); else remote[0] = 0; - if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 ) + if ( (str= InstantDEX_hexmsg(myinfo,cat,pm,m->len,remote)) != 0 ) free(str); } //else printf("instantdex_update: unexpected m.%p changed item.%p\n",m,item); free(m); } } -/* - for (iter=0; iter<2; iter++) - { - while ( (m= category_gethexmsg(myinfo,instantdexhash,iter == 0 ? GENESIS_PUBKEY : myinfo->myaddr.persistent)) != 0 ) - { - //printf("gothexmsg len.%d\n",m->len); - pm = (struct instantdex_msghdr *)m->msg; - if ( m->remoteipbits != 0 ) - expand_ipbits(remote,m->remoteipbits); - else remote[0] = 0; - if ( (str= InstantDEX_hexmsg(myinfo,pm,m->len,remote)) != 0 ) - free(str); - free(m); - } - }*/ } #include "../includes/iguana_apidefs.h" TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume) { - struct instantdex_accept *ap; + struct instantdex_accept *ap; char *retstr; struct exchange_info *exchange; uint64_t txid; myinfo = SuperNET_accountfind(json); - if ( remoteaddr == 0 ) - return(instantdex_queueaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,maxprice,basevolume,-1,rel,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1)); - else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + retstr = instantdex_createaccept(myinfo,&ap,exchange,base,rel,maxprice,basevolume,-1,rel,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1,juint(json,"minperc")); + return(instantdex_checkoffer(myinfo,&txid,exchange,ap,json)); + + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); } TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume) { - struct instantdex_accept *ap; + struct instantdex_accept *ap; char *retstr; struct exchange_info *exchange; uint64_t txid; myinfo = SuperNET_accountfind(json); - if ( remoteaddr == 0 ) - return(instantdex_queueaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,minprice,basevolume,1,base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1)); - else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + retstr = instantdex_createaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,minprice,basevolume,1,base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1,juint(json,"minperc")); + return(instantdex_checkoffer(myinfo,&txid,exchange,ap,json)); + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); +} + +char *instantdex_statemachineget(struct supernet_info *myinfo,struct bitcoin_swapinfo **swapp,cJSON *argjson,char *remoteaddr) +{ + struct bitcoin_swapinfo *swap; uint64_t orderid,otherorderid; struct exchange_info *exchange; + *swapp = 0; + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + orderid = j64bits(argjson,"myorderid"); + otherorderid = j64bits(argjson,"otherid"); + if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + { + if ( swap->other.orderid != otherorderid ) + return(clonestr("{\"error\":\"statemachine otherid mismatch\"}")); + else + { + *swapp = swap; + return(0); + } + } else return(clonestr("{\"error\":\"statemachine not found\"}")); + } else return(clonestr("{\"error\":\"atomic API request only local usage!\"}")); +} + +THREE_STRINGS(atomic,approve,myorderid,otherid,txname) +{ + char *retstr,virtualevent[16]; cJSON *newjson; struct bitcoin_statetx *tx; struct bitcoin_swapinfo *swap = 0; + if ( (retstr= instantdex_statemachineget(myinfo,&swap,json,remoteaddr)) != 0 ) + return(retstr); + else if ( (tx= instantdex_getstatetx(swap,txname)) == 0 ) + return(clonestr("{\"error\":\"cant find txname\"}")); + else + { + strcpy(virtualevent,txname); + strcat(virtualevent,"found"); + newjson = cJSON_CreateObject(); + if ( (retstr= instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,virtualevent,myinfo->myaddr.persistent,0,0,0)) != 0 ) + return(retstr); + else return(clonestr("{\"result\":\"statemachine sent found event\"}")); + } } + +THREE_STRINGS(atomic,claim,myorderid,otherid,txname) +{ + char *retstr; struct bitcoin_statetx *tx; struct bitcoin_swapinfo *swap = 0; + if ( (retstr= instantdex_statemachineget(myinfo,&swap,json,remoteaddr)) != 0 ) + return(retstr); + else if ( (tx= instantdex_getstatetx(swap,txname)) == 0 ) + return(clonestr("{\"error\":\"cant find txname\"}")); + else + { + return(clonestr("{\"result\":\"statemachine should claim tx\"}")); + } +} + +THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) +{ + double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); + aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"aveprice",aveprice); + jaddnum(retjson,"avebid",retvals[0]); + jaddnum(retjson,"bidvol",retvals[1]); + jaddnum(retjson,"aveask",retvals[2]); + jaddnum(retjson,"askvol",retvals[3]); + return(jprint(retjson,1)); +} + #include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index 2d7a2bfe6..e6e973bff 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -861,8 +861,8 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c coinstr = myinfo->rpcsymbol; if ( coinstr != 0 && coinstr[0] != 0 ) coin = iguana_coinfind(coinstr); - if ( strcmp(agentstr,"ramchain") == 0 && coin == 0 ) - return(clonestr("{\"error\":\"ramchain needs coin\"}")); + if ( strcmp(agentstr,"bitcoinrpc") == 0 && coin == 0 ) + return(clonestr("{\"error\":\"bitcoinrpc needs coin\"}")); #define IGUANA_ARGS myinfo,coin,json,remoteaddr #define IGUANA_DISPATCH0(agent,name) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS)) #define IGUANA_DISPATCH_S(agent,name,str) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str))) @@ -964,7 +964,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #include "../includes/iguana_apiundefs.h" - return(clonestr("{\"error\":\"illegal ramchain method or missing coin\"}")); + return(clonestr("{\"error\":\"illegal bitcoinrpc method or missing coin\"}")); } diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index ea8b4898d..dad820714 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -71,7 +71,7 @@ int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgver else if ( msg->nVersion > 70000 ) len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->relayflag),&msg->relayflag); //if ( rwflag == 0 ) - printf("readsize.%d %-15s v.%llu srv.%llx %u ht.%llu [%s].R%d nonce.%llx\n",readsize,ipaddr,(long long)msg->nVersion,(long long)msg->nServices,(uint32_t)msg->nTime,(long long)msg->nStartingHeight,msg->strSubVer,msg->relayflag,(long long)msg->nonce); + //printf("readsize.%d %-15s v.%llu srv.%llx %u ht.%llu [%s].R%d nonce.%llx\n",readsize,ipaddr,(long long)msg->nVersion,(long long)msg->nServices,(uint32_t)msg->nTime,(long long)msg->nStartingHeight,msg->strSubVer,msg->relayflag,(long long)msg->nonce); // 6e ea 00 00 01 00 00 00 00 00 00 00 86 5f a8 56 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff b5 2f b7 bc c6 83 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff 67 e5 7e c2 07 80 00 00 00 00 00 00 00 00 10 2f 42 69 74 4e 65 74 3a 31 2e 31 2e 33 2e 32 2f 92 d0 09 00 6c 04 00 00 01 00 00 00 80 07 01 9a 03 9b 03 01 return(len); } @@ -155,7 +155,7 @@ int32_t iguana_rwblockhash(int32_t rwflag,uint8_t *serialized,uint32_t *nVersion void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgversion *vers) { uint8_t serialized[sizeof(struct iguana_msghdr)]; - printf("gotversion from %s: starting height.%d services.%llx proto.%d\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion); + //printf("gotversion from %s: starting height.%d services.%llx proto.%d\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion); if ( (vers->nServices & NODE_NETWORK) != 0 )//&& vers->nonce != coin->instance_nonce ) { addr->protover = (vers->nVersion < PROTOCOL_VERSION) ? vers->nVersion : PROTOCOL_VERSION; @@ -166,9 +166,11 @@ void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_queue_send(coin,addr,0,serialized,"verack",0,0,0); //iguana_send_ping(coin,addr); } + else if ( (vers->nServices & (1<<7)) == 0 ) + addr->dead = (uint32_t)time(NULL); if ( (vers->nServices & (1<<7)) == (1<<7) ) addr->supernet = 1; - else printf("nServices.%lld nonce.%llu non-relay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->ipaddr,addr->supernet); + else printf("nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); if ( vers->nStartingHeight > coin->longestchain ) coin->longestchain = vers->nStartingHeight; iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); @@ -182,7 +184,7 @@ int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,ui msg.nServices = myservices; msg.nTime = (int64_t)time(NULL); msg.nonce = coin->instance_nonce; - sprintf(msg.strSubVer,"/Satoshi:0.11.99/"); + sprintf(msg.strSubVer,"/Satoshi:0.12.0/"); msg.nStartingHeight = coin->blocks.hwmchain.height; iguana_gotdata(coin,addr,msg.nStartingHeight); len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],&msg,addr->ipaddr,0); @@ -208,7 +210,7 @@ void iguana_gotverack(struct iguana_info *coin,struct iguana_peer *addr) uint8_t serialized[sizeof(struct iguana_msghdr)]; if ( addr != 0 ) { - printf("gotverack from %s\n",addr->ipaddr); + //printf("gotverack from %s\n",addr->ipaddr); addr->A.nTime = (uint32_t)time(NULL); iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); if ( addr->supernet != 0 ) @@ -300,15 +302,14 @@ int32_t iguana_gethdrs(struct iguana_info *coin,uint8_t *serialized,char *cmd,ch return(iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len)); } -int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,char *hashstr) +int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,bits256 *hashes,int32_t n) { - uint32_t len,i,n=1; bits256 hash2; - decode_hex(hash2.bytes,sizeof(hash2),hashstr); + uint32_t len,i; //bits256 hash2; len = iguana_rwvarint32(1,&serialized[sizeof(struct iguana_msghdr)],(uint32_t *)&n); for (i=0; ichain->netmagic,"getdata",&serialized[sizeof(struct iguana_msghdr)],len)); } @@ -320,8 +321,8 @@ int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized, len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->scriptlen); if ( rwflag == 0 ) - msg->sigscript = iguana_memalloc(mem,msg->scriptlen,1); - len += iguana_rwmem(rwflag,&serialized[len],msg->scriptlen,msg->sigscript); + msg->vinscript = iguana_memalloc(mem,msg->scriptlen,1); + len += iguana_rwmem(rwflag,&serialized[len],msg->scriptlen,msg->vinscript); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); //char str[65]; printf("MSGvin.(%s/v%d) script[%d]\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->scriptlen); //int i; for (i=0; iscriptlen; i++) diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 89ebd5f2d..4de289c0b 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -108,7 +108,7 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind) { FILE *fp; char fname[512],hexstr[65]; int32_t i,n,m,retval = 0; struct iguana_iAddr tmp,*ptr; - sprintf(fname,"DB/%s/peers.dat",coin->symbol); + sprintf(fname,"DB/%s_peers.dat",coin->symbol); OS_compatible_path(fname); if ( rwflag < 0 || iA == 0 ) { @@ -371,7 +371,7 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s } else if ( addr->msgcounts.verack == 0 && (strcmp((char *)&serialized[4],"version") != 0 && strcmp((char *)&serialized[4],"ConnectTo") != 0 && strcmp((char *)&serialized[4],"verack") != 0) != 0 ) { - printf("skip.(%s) since no verack yet\n",(char *)&serialized[4]); + //printf("skip.(%s) since no verack yet\n",(char *)&serialized[4]); return(-1); } if ( strcmp((char *)&serialized[4],"ping") == 0 ) @@ -474,9 +474,9 @@ void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct ig if ( strcmp(H->command,"block") == 0 || strcmp(H->command,"tx") == 0 ) { if ( addr->RAWMEM.ptr == 0 ) - iguana_meminit(&addr->RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE,0); + iguana_meminit(&addr->RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE + 65536*3,0); if ( addr->TXDATA.ptr == 0 ) - iguana_meminit(&addr->TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE,0); + iguana_meminit(&addr->TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE*1.5,0); if ( addr->HASHMEM.ptr == 0 ) iguana_meminit(&addr->HASHMEM,"HASHPTRS",0,256,0);//IGUANA_MAXPACKETSIZE*16,0); //printf("Init %s memory %p %p %p\n",addr->ipaddr,addr->RAWMEM.ptr,addr->TXDATA.ptr,addr->HASHMEM.ptr); @@ -604,7 +604,7 @@ void iguana_startconnection(void *arg) if ( addr->usock < 0 || coin->peers.shuttingdown != 0 ) { strcpy(ipaddr,addr->ipaddr); - printf("refused PEER KILLED. for %s:%d usock.%d\n",ipaddr,coin->chain->portp2p,addr->usock); + //printf("refused PEER KILLED. slot.%d for %s:%d usock.%d\n",addr->addrind,ipaddr,coin->chain->portp2p,addr->usock); iguana_iAkill(coin,addr,1); } else @@ -693,13 +693,18 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); if ( addr->pending == 0 && iA->status != IGUANA_PEER_CONNECTING ) { - iA->status = IGUANA_PEER_CONNECTING; - addr->pending = (uint32_t)time(NULL); if ( iguana_rwiAddrind(coin,1,iA,iA->hh.itemind) > 0 ) { //printf("iA.%p iguana_startconnection.(%s) status.%d pending.%d\n",iA,addr->ipaddr,iA->status,addr->pending); + iA->status = IGUANA_PEER_CONNECTING; + addr->pending = (uint32_t)time(NULL); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); - } else printf("error rwiAddrind.%d\n",iA->hh.itemind); + } + else + { + addr->ipbits = 0; + printf("error rwiAddrind.%d\n",iA->hh.itemind); + } } } else printf("no open peer slots left\n"); } @@ -936,7 +941,7 @@ int64_t iguana_peerallocated(struct iguana_info *coin,struct iguana_peer *addr) void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { static uint32_t lastping; - struct pollfd fds; struct iguana_bundlereq *req; uint8_t *buf;//,serialized[64]; + struct pollfd fds; struct iguana_bundlereq *req; char fname[1024]; uint8_t *buf;//,serialized[64]; uint32_t ipbits; int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; #ifdef IGUANA_PEERALLOC int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)]; @@ -954,9 +959,17 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) #endif addr->addrind = (int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)); ipbits = (uint32_t)addr->ipbits; + sprintf(fname,"DB/%s/vouts/%08x.vouts",coin->symbol,ipbits); + if ( (addr->voutsfp= fopen(fname,"rb+")) != 0 ) + fseek(addr->voutsfp,0,SEEK_END); + else addr->voutsfp = fopen(fname,"wb+"); + sprintf(fname,"purgeable/%s/%08x.vins",coin->symbol,ipbits); + if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) + fseek(addr->vinsfp,0,SEEK_END); + else addr->vinsfp = fopen(fname,"wb+"); //addr->pubkey = GENESIS_PUBKEY; vcalc_sha256(0,addr->iphash.bytes,(uint8_t *)&ipbits,sizeof(ipbits)); - char str[65]; printf("start dedicatedloop.%s addrind.%d %s\n",addr->ipaddr,addr->addrind,bits256_str(str,addr->iphash)); + //char str[65]; printf("start dedicatedloop.%s addrind.%d %s\n",addr->ipaddr,addr->addrind,bits256_str(str,addr->iphash)); addr->maxfilehash2 = IGUANA_MAXFILEITEMS; bufsize = IGUANA_MAXPACKETSIZE; buf = mycalloc('r',1,bufsize); @@ -979,7 +992,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { if ( req->datalen != 0 ) { - //char str[65]; printf("CACHE parse[%d] %s %s\n",req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2)); + char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2)); iguana_parsebuf(coin,addr,&req->H,req->serialized,req->recvlen); } else printf("CACHE error no datalen\n"); coin->cachefreed++; @@ -1034,8 +1047,8 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) usleep(100000); } else if ( addr->rank != 1 ) - usleep(coin->polltimeout*100 + 1*(rand() % (coin->polltimeout*100))); - else usleep(100); + usleep(coin->polltimeout*3000 + 1*(rand() % (coin->polltimeout*3000))); + else usleep(1000); } else run >>= 2; } if ( flag != 0 ) @@ -1070,8 +1083,10 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } } printf(">>>>>>>>>>>>>> finish dedicatedloop.%s\n",addr->ipaddr); - //if ( addr->fp != 0 ) - // fclose(addr->fp); + if ( addr->vinsfp != 0 ) + fclose(addr->vinsfp); + if ( addr->voutsfp != 0 ) + fclose(addr->voutsfp); iguana_iAkill(coin,addr,addr->dead != 0); myfree(buf,bufsize); if ( addr->filehash2 != 0 ) diff --git a/iguana/iguana_pubkeys.c b/iguana/iguana_pubkeys.c index 1e82f8c52..cb9742e7e 100755 --- a/iguana/iguana_pubkeys.c +++ b/iguana/iguana_pubkeys.c @@ -537,6 +537,14 @@ bool bp_key_secret_get(void *p, size_t len, const struct bp_key *key) return true; } +/*void get_shared_secret( unsigned char bytes[ 32 ], const EC_KEY* p_key ) +{ + const EC_POINT* p_pub = EC_KEY_get0_public_key( p_key ); + const BIGNUM* p_priv = EC_KEY_get0_private_key( p_pub_impl->p_key ); + + ECDH_compute_key( &bytes[ 0 ], 32, p_pub, p_pub_impl->p_key, 0 ); +}*/ + bool bp_sign(EC_KEY *key, const void *data, size_t data_len,void **sig_, size_t *sig_len_) { size_t sig_sz = ECDSA_size(key); @@ -596,7 +604,7 @@ int32_t btc_getpubkey(char pubkeystr[67],uint8_t pubkeybuf[33],struct bp_key *ke return((int32_t)len); } -int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]) +/*int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]) { cstring *btc_addr; if ( (btc_addr= base58_encode_check(addrtype,true,rmd160,20)) != 0 ) @@ -606,13 +614,14 @@ int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]) return(0); } return(-1); -} +}*/ int32_t btc_coinaddr(char *coinaddr,uint8_t addrtype,char *pubkeystr) { uint8_t rmd160[20]; char hashstr[41]; calc_OP_HASH160(hashstr,rmd160,pubkeystr); - return(btc_convrmd160(coinaddr,addrtype,rmd160)); + return(bitcoin_address(coinaddr,addrtype,rmd160,20) != 0); + //return(btc_convrmd160(coinaddr,addrtype,rmd160)); } int32_t btc_convaddr(char *hexaddr,char *addr58) @@ -801,7 +810,7 @@ struct iguana_waddress *iguana_waddresscalc(uint8_t pubtype,uint8_t wiftype,stru { memset(addr,0,sizeof(*addr)); addr->privkey = privkey; - if ( btc_priv2pub(addr->pubkey,addr->privkey.bytes) == 0 && btc_priv2wif(addr->wifstr,addr->privkey.bytes,wiftype) == 0 && btc_pub2rmd(addr->rmd160,addr->pubkey) == 0 && btc_convrmd160(addr->coinaddr,pubtype,addr->rmd160) == 0 ) + if ( btc_priv2pub(addr->pubkey,addr->privkey.bytes) == 0 && btc_priv2wif(addr->wifstr,addr->privkey.bytes,wiftype) == 0 && btc_pub2rmd(addr->rmd160,addr->pubkey) == 0 && bitcoin_address(addr->coinaddr,pubtype,addr->rmd160,10) != 0 ) { addr->wiftype = wiftype; addr->type = pubtype; diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index f572780d2..7deaf1675 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -21,6 +21,7 @@ //#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 #include "iguana777.h" +#include "exchanges/bitcoin.h" //void iguana_stub(void *ptr,int size) { }//printf("uthash_free ptr.%p %d\n",ptr,size); } #define iguana_hashfind(ramchain,selector,key) iguana_hashsetPT(ramchain,selector,key,0) @@ -45,27 +46,34 @@ struct iguana_kvitem *iguana_hashsetPT(struct iguana_ramchain *ramchain,int32_t { if ( ramchain->hashmem != 0 ) ptr = iguana_memalloc(ramchain->hashmem,allocsize,1); - else ptr = mycalloc('e',1,allocsize); + else + { + ptr = mycalloc('e',1,allocsize); + printf("alloc.%d\n",allocsize); + } if ( ptr == 0 ) printf("fatal alloc error in hashset\n"), exit(-1); if ( 0 && ramchain->expanded && selector == 'T' ) printf("hashmem.%p selector.%c added.(%s) itemind.%x ptr.%p\n",ramchain->hashmem,selector,str,itemind,ptr); - ptr->hh.itemind = itemind; if ( selector == 'T' ) HASH_ADD_KEYPTR(hh,ramchain->txids,key,keylen,ptr); else HASH_ADD_KEYPTR(hh,ramchain->pkhashes,key,keylen,ptr); - if ( selector == 'T' ) - HASH_FIND(hh,ramchain->txids,key,keylen,tmp); - else HASH_FIND(hh,ramchain->pkhashes,key,keylen,tmp); + ptr->hh.itemind = itemind; //if ( strcmp(str,"0000000000000000000000000000000000000000000000000000000000000000") == 0 ) // printf("added null txid?\n"), getchar(); if ( 0 && ramchain->expanded && selector == 'T' ) printf("selector.%c added.(%s) itemind.%x ptr.%p tmp.%p\n",selector,str,itemind,ptr,tmp); if ( itemind == 0 ) printf("negative itemind\n"), exit(-1); - if ( tmp != ptr ) + if ( 0 ) { - printf("(%s) hashmem.%p selector.%c %s search error %p != %p itemind.%x\n",str,ramchain->hashmem,selector,str,ptr,tmp,itemind), exit(-1); + if ( selector == 'T' ) + HASH_FIND(hh,ramchain->txids,key,keylen,tmp); + else HASH_FIND(hh,ramchain->pkhashes,key,keylen,tmp); + if ( tmp != ptr ) + { + printf("(%s) hashmem.%p selector.%c %s search error %p != %p itemind.%x\n",str,ramchain->hashmem,selector,str,ptr,tmp,itemind), exit(-1); + } } } return(ptr); @@ -193,12 +201,14 @@ void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block block->RO.firstexternalind = ramchain->externalind; } -struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid) +struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi) { - uint8_t *TXbits; struct iguana_txid *T; uint32_t txidind,i,j; + uint8_t *TXbits; struct iguana_txid *T; uint32_t txidind; int32_t i,j; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_block *block; *heightp = -1; - for (i=0; ibundlescount; i++) + if ( lasthdrsi < 0 ) + return(0); + for (i=lasthdrsi; i>=0; i--) { if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish > coin->startutc ) { @@ -211,13 +221,23 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st if ( (txidind= iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,0)) > 0 ) { //printf("found txidind.%d\n",txidind); - for (j=0; jn; j++) - if ( (block= bp->blocks[j]) != 0 && txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count ) - break; - *heightp = bp->bundleheight + j; - //printf("found height.%d\n",*heightp); - *tx = T[txidind]; - return(tx); + if ( bits256_cmp(txid,T[txidind].txid) == 0 ) + { + for (j=0; jn; j++) + if ( (block= bp->blocks[j]) != 0 && txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count ) + break; + if ( j < bp->n ) + { + *heightp = bp->bundleheight + j; + //printf("found height.%d\n",*heightp); + *tx = T[txidind]; + return(tx); + } + for (j=0; jn; j++) + if ( (block= bp->blocks[j]) != 0 ) + printf("(%d %d).%d ",block->RO.firsttxidind,block->RO.txn_count,txidind >= block->RO.firsttxidind && txidind < block->RO.firsttxidind+block->RO.txn_count); + printf(" <- firsttxidind txidind.%d not in block range\n",txidind); + } else printf("mismatched sparse entry\n"); } } } @@ -225,30 +245,10 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st return(0); } -struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_pkhash *p,uint8_t rmd160[20]) -{ - uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; - for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - ramchain = &bp->ramchain; - PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); - P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); - if ( (pkind= iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,0)) > 0 ) - { - *p = P[pkind]; - return(p); - } - } - } - return(0); -} - int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks) { struct iguana_bundle *bp = 0; int32_t bundlei = -2; char str[65]; - *hdrsip = -1; + *hdrsip = -1; ipbits = 0; //if ( ipbits == 0 ) // printf("illegal ipbits.%d\n",ipbits), getchar(); if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) == 0 ) @@ -259,8 +259,18 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, } hash2 = bp->hashes[0], *hdrsip = bp->hdrsi; if ( numblocks == 1 ) - sprintf(fname,"%s/%s/%s.%u",dirname,coin->symbol,bits256_str(str,hash2),ipbits!=0?ipbits:*hdrsip); - else sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits!=0?ipbits:*hdrsip); + { + if ( bits256_nonz(bp->hashes[bundlei]) != 0 ) + sprintf(fname,"%s/%s/%d/%s_%u.%d",dirname,coin->symbol,bp->bundleheight,bits256_str(str,bp->hashes[bundlei]),ipbits!=0?ipbits:*hdrsip,bundlei); + else + { + printf("no hash for [%d:%d]\n",bp->hdrsi,bundlei); + return(-3); + } + } + else if ( strcmp("DB",dirname) == 0 ) + sprintf(fname,"%s/%s/%s_%d.%u",dirname,coin->symbol,bits256_str(str,hash2),numblocks,ipbits!=0?ipbits:*hdrsip); + else sprintf(fname,"%s/%s.%u",dirname,bits256_str(str,hash2),bp->bundleheight); OS_compatible_path(fname); return(bundlei); } @@ -278,18 +288,20 @@ int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr return(bundlei); } -#define RAMCHAIN_FUNC struct iguana_ramchain *ramchain,struct iguana_blockRO *B,struct iguana_txid *T,struct iguana_unspent20 *U,struct iguana_spend256 *S,struct iguana_pkhash *P,struct iguana_account *A,bits256 *X,struct iguana_unspent *Ux,struct iguana_spend *Sx,uint8_t *TXbits,uint8_t *PKbits -#define RAMCHAIN_PTRPS struct iguana_ramchain *ramchain,struct iguana_blockRO **B,struct iguana_txid **T,struct iguana_unspent20 **U,struct iguana_spend256 **S,struct iguana_pkhash **P,struct iguana_account **A,bits256 **X,struct iguana_unspent **Ux,struct iguana_spend **Sx,uint8_t **TXbits,uint8_t **PKbits +#define RAMCHAIN_FUNC struct iguana_ramchain *ramchain,struct iguana_blockRO *B,struct iguana_txid *T,struct iguana_unspent20 *U,struct iguana_spend256 *S,struct iguana_pkhash *P,struct iguana_account *A,bits256 *X,struct iguana_unspent *Ux,struct iguana_spend *Sx,uint8_t *TXbits,uint8_t *PKbits,uint8_t *Kspace +#define RAMCHAIN_PTRPS struct iguana_ramchain *ramchain,struct iguana_blockRO **B,struct iguana_txid **T,struct iguana_unspent20 **U,struct iguana_spend256 **S,struct iguana_pkhash **P,struct iguana_account **A,bits256 **X,struct iguana_unspent **Ux,struct iguana_spend **Sx,uint8_t **TXbits,uint8_t **PKbits,uint8_t **Kspace -#define _RAMCHAIN_ARG B,T,U,S,P,A,X,Ux,Sx,TXbits,PKbits +#define _RAMCHAIN_ARG B,T,U,S,P,A,X,Ux,Sx,TXbits,PKbits,Kspace #define RAMCHAIN_ARG ramchain,_RAMCHAIN_ARG #define MAPCHAIN_ARG mapchain,_RAMCHAIN_ARG -#define RAMCHAIN_PTRS ramchain,&B,&T,&U,&S,&P,&A,&X,&Ux,&Sx,&TXbits,&PKbits -#define RAMCHAIN_DECLARE struct iguana_blockRO *B; struct iguana_txid *T; struct iguana_unspent20 *U; struct iguana_spend256 *S; struct iguana_pkhash *P; struct iguana_account *A; bits256 *X; struct iguana_unspent *Ux; struct iguana_spend *Sx; uint8_t *TXbits,*PKbits; +#define MAPCHAIN_PTRS mapchain,&B,&T,&U,&S,&P,&A,&X,&Ux,&Sx,&TXbits,&PKbits,&Kspace -#define RAMCHAIN_DESTARG dest,destB,destT,destU,destS,destP,destA,destX,destUx,destSx,destTXbits,destPKbits -#define RAMCHAIN_DESTPTRS dest,&destB,&destT,&destU,&destS,&destP,&destA,&destX,&destUx,&destSx,&destTXbits,&destPKbits -#define RAMCHAIN_DESTDECLARE struct iguana_blockRO *destB; struct iguana_txid *destT; struct iguana_unspent20 *destU; struct iguana_spend256 *destS; struct iguana_pkhash *destP; struct iguana_account *destA; bits256 *destX; struct iguana_unspent *destUx; struct iguana_spend *destSx; uint8_t *destTXbits,*destPKbits; +#define RAMCHAIN_PTRS ramchain,&B,&T,&U,&S,&P,&A,&X,&Ux,&Sx,&TXbits,&PKbits,&Kspace +#define RAMCHAIN_DECLARE struct iguana_blockRO *B; struct iguana_txid *T; struct iguana_unspent20 *U; struct iguana_spend256 *S; struct iguana_pkhash *P; struct iguana_account *A; bits256 *X; struct iguana_unspent *Ux; struct iguana_spend *Sx; uint8_t *TXbits,*PKbits,*Kspace; + +#define RAMCHAIN_DESTARG dest,destB,destT,destU,destS,destP,destA,destX,destUx,destSx,destTXbits,destPKbits,destKspace +#define RAMCHAIN_DESTPTRS dest,&destB,&destT,&destU,&destS,&destP,&destA,&destX,&destUx,&destSx,&destTXbits,&destPKbits,&destKspace +#define RAMCHAIN_DESTDECLARE struct iguana_blockRO *destB; struct iguana_txid *destT; struct iguana_unspent20 *destU; struct iguana_spend256 *destS; struct iguana_pkhash *destP; struct iguana_account *destA; bits256 *destX; struct iguana_unspent *destUx; struct iguana_spend *destSx; uint8_t *destTXbits,*destPKbits,*destKspace; uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 txid,int32_t numvouts,int32_t numvins,uint32_t locktime,uint32_t version,uint32_t timestamp) { @@ -300,15 +312,15 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 { if ( t->txidind != txidind || memcmp(t->txid.bytes,txid.bytes,sizeof(bits256)) != 0 || t->numvouts != numvouts || t->numvins != numvins || t->firstvout != ramchain->H.unspentind || t->firstvin != ramchain->H.spendind || t->locktime != locktime || t->version != version || t->timestamp != timestamp ) { - printf("iguana_ramchain_addtxid: addtxid mismatch (%d %d %d %d %d) vs. (%d %d %d %d %d)\n",t->txidind,t->numvouts,t->numvins,t->firstvout,t->firstvin,txidind,numvouts,numvins,ramchain->H.unspentind,ramchain->H.spendind); - exit(-1); + printf("iguana_ramchain_addtxid.RO: addtxid mismatch (%d %d %d %d %d) vs. (%d %d %d %d %d)\n",t->txidind,t->numvouts,t->numvins,t->firstvout,t->firstvin,txidind,numvouts,numvins,ramchain->H.unspentind,ramchain->H.spendind); + //getchar(); return(0); } } else { - //if ( ramchain->expanded != 0 ) - // printf("T.%p txidind.%d numvouts.%d numvins.%d\n",T,txidind,numvouts,numvins); + if ( 0 && ramchain->expanded != 0 ) + printf("T.%p txidind.%d numvouts.%d numvins.%d\n",T,txidind,numvouts,numvins); t->txidind = txidind, t->txid = txid, t->numvouts = numvouts, t->numvins = numvins; t->firstvout = ramchain->H.unspentind, t->firstvin = ramchain->H.spendind; t->locktime = locktime, t->version = version, t->timestamp = timestamp; @@ -328,62 +340,98 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 return(txidind); } -uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_t rmd160[20],int32_t flags,uint32_t unspentind) +uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_t *rmd160,int32_t pubkeyind,uint32_t unspentind,uint32_t pkind) { - struct iguana_kvitem *ptr; uint32_t pkind = 0; + struct iguana_kvitem *ptr; uint32_t i; if ( ramchain->expanded != 0 && (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) { - pkind = ramchain->pkind++; if ( ramchain->H.ROflag != 0 ) { - if ( P[pkind].flags != flags || P[pkind].firstunspentind != unspentind || P[pkind].pkind != pkind ) + if ( P[pkind].pkind != pkind ) //unspentind != 0 && (P[pkind].firstunspentind != unspentind || { - printf("iguana_ramchain_addpkhash pkind.%d vs %d error mismatched flags.(%x %x) firstunspentind.%x vs %x\n",pkind,P[pkind].pkind,P[pkind].flags,flags,P[pkind].firstunspentind,unspentind); + printf("iguana_ramchain_addpkhash error mismatched pkind.(%x %x) unspentind.%d\n",pkind,P[pkind].pkind,unspentind); exit(-1); return(0); } if ( memcmp(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)) != 0 ) { - printf("iguana_ramchain_addpkhash error mismatched rmd160\n"); - return(0); + for (i=0; i<20; i++) + printf("%02x",P[pkind].rmd160[i]); + printf(" -> rmd160 pkind.%d\n",pkind); + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" vs rmd160\n"); + printf("iguana_ramchain_addpkhash pkind.%d error mismatched rmd160\n",pkind); + //getchar(); + return(pkind); } + //ramchain->pkind = (pkind + 1); } else { - P[pkind].flags = flags; + pkind = ramchain->pkind++; P[pkind].pkind = pkind; - P[pkind].firstunspentind = unspentind; - //printf("%p P[%d] <- firstunspent.%d\n",&P[pkind],pkind,unspentind); + /*if ( P[pkind].firstunspentind == 0 && unspentind != 0 ) + { + P[pkind].firstunspentind = unspentind; + printf("%p P[%d] <- firstunspent.%d\n",&P[pkind],pkind,unspentind); + }*/ memcpy(P[pkind].rmd160,rmd160,sizeof(P[pkind].rmd160)); + //for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //printf(" -> rmd160 pkind.%d \n",pkind); if ( ramchain->expanded != 0 ) iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,pkind); } if ( (ptr= iguana_hashsetPT(ramchain,'P',&P[pkind],pkind)) == 0 ) { - printf("iguana_ramchain_addpkhash error adding pkhash\n"); + printf("iguana_ramchain_addpkhash error adding pkhash pkind.%d\n",pkind); return(0); } } return(pkind); } -uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,uint8_t type) +uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_peer *addr,RAMCHAIN_FUNC,uint64_t value,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,int8_t type,struct iguana_bundle *bp,uint8_t rmd160[20]) { - //struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; } __attribute__((packed)); - uint32_t unspentind; struct iguana_unspent20 *u; struct vin_info V; + uint32_t unspentind; struct iguana_unspent20 *u; struct vin_info V; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; unspentind = ramchain->H.unspentind++; u = &U[unspentind]; - if ( scriptlen == -20 ) - memcpy(V.rmd160,script,20); - else + if ( scriptlen > 0 ) { memset(&V,0,sizeof(V)); - type = iguana_calcrmd160(coin,&V,script,scriptlen,txid,vout,0xffffffff); + if ( type < 0 ) + { + type = iguana_calcrmd160(coin,&V,script,scriptlen,txid,vout,0xffffffff); + if ( type == 1 && bitcoin_pubkeylen(script+1) <= 0 ) + { + int32_t i; for (i=0; iH.ROflag != 0 ) { - //printf("%p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->txidind,pkind); - if ( u->txidind != ramchain->H.txidind || u->value != value || memcmp(u->rmd160,V.rmd160,sizeof(V.rmd160)) != 0 ) + //fprintf(stderr,"RO %p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->H.txidind,ramchain->pkind); + /*if ( 0 && u->scriptpos != 0 && u->scriptlen > 0 )//&& u->scriptlen <= sizeof(u->script) ) + { + scriptptr = &Kspace[u->scriptpos]; + if ( memcmp(script,scriptptr,u->scriptlen) != 0 ) + { + int32_t i; + for (i=0; iscriptlen; i++) + printf("%02x",scriptptr[i]); + printf(" u->script\n"); + for (i=0; iscriptlen; i++) + printf("%02x",script[i]); + printf(" script\n"); + printf("[%d] u%d script compare error.%d vs %d\n",bp->hdrsi,unspentind,scriptlen,u->scriptlen); + return(0); + } //else printf("SCRIPT.%d MATCHED!\n",u->scriptlen); + } // else would need to get from HDD to verify*/ + if ( u->txidind != ramchain->H.txidind || u->value != value || memcmp(u->rmd160,rmd160,sizeof(u->rmd160)) != 0 ) { printf("iguana_ramchain_addunspent20: mismatched values.(%.8f %d) vs (%.8f %d)\n",dstr(u->value),u->txidind,dstr(value),ramchain->H.txidind); return(0); @@ -393,28 +441,66 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,RAMCHAIN_FUNC,uin { u->value = value; u->type = type; + memcpy(u->rmd160,rmd160,sizeof(u->rmd160)); + if ( type == IGUANA_SCRIPT_76AC ) + { + static uint64_t totalsize; + totalsize += scriptlen; + char str[65]; + if ( (rand() % 100000) == 0 ) + fprintf(stderr,"IGUANA_SCRIPT_76AC type.%d scriptlen.%d bp.%p %s\n",type,scriptlen,bp,mbstr(str,totalsize)); + } + u->scriptlen = scriptlen; + if ( scriptlen > 0 && script != 0 ) + { + memset(&V,0,sizeof(V)); + V.spendlen = iguana_scriptgen(coin,&V.M,&V.N,V.coinaddr,V.spendscript,asmstr,u->rmd160,type,(const struct vin_info *)&V,vout); + if ( (V.spendlen != scriptlen || memcmp(V.spendscript,script,scriptlen) != 0) && addr != 0 && addr->voutsfp != 0 ) + { + u->ipbits = (uint32_t)addr->ipbits; + u->scriptpos = (uint32_t)ftell(addr->voutsfp); + if ( fwrite(script,1,scriptlen,addr->voutsfp) != scriptlen ) + printf("error writing scriptlen.%d\n",scriptlen); + else addr->dirty[0]++; + } + else + { + u->scriptpos = 0; + u->ipbits = 0; + } + } else u->scriptpos = 0; u->txidind = ramchain->H.txidind; - memcpy(u->rmd160,V.rmd160,sizeof(V.rmd160)); } return(unspentind); } -uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint16_t hdrsi,uint8_t *rmd160,uint16_t vout,uint8_t type) +uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint16_t hdrsi,uint8_t *rmd160,uint16_t vout,uint8_t type,uint32_t ipbits,uint32_t fpos,int32_t scriptlen) { - uint32_t unspentind; struct iguana_unspent *u; struct iguana_kvitem *ptr; int32_t pkind; + uint32_t unspentind; struct iguana_unspent *u; struct iguana_kvitem *ptr; int32_t pkind;//,checklen,metalen; uint8_t _script[IGUANA_MAXSCRIPTSIZE],*checkscript; unspentind = ramchain->H.unspentind++; u = &Ux[unspentind]; if ( (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) - pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,rmd160,0,unspentind); + pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,rmd160,0,unspentind,u->pkind); else pkind = ptr->hh.itemind; if ( pkind == 0 ) + { + printf("addunspent error getting pkind\n"); return(0); + } + //printf("ROflag.%d pkind.%d unspentind.%d script.%p[%d] uoffset.%d %d:%d type.%d\n",ramchain->H.ROflag,pkind,unspentind,script,scriptlen,u->scriptoffset,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,type); if ( ramchain->H.ROflag != 0 ) { - //printf("%p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->txidind,pkind); - if ( u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastunspentind) || u->vout != vout || u->hdrsi != hdrsi ) + /*if ( Kspace != 0 && ((u->scriptoffset != 0 && scriptlen > 0) || type == IGUANA_SCRIPT_76AC) ) + { + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspace,u->type,_script,u->scriptoffset,P[pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[pkind].pubkeyoffset : 0); + if ( checklen != scriptlen || (script != 0 && checkscript != 0 && memcmp(checkscript,script,scriptlen) != 0) ) + { + printf("script mismatch len.%d vs %d or cmp error.%d\n",scriptlen,checklen,(checkscript != 0 && script != 0) ? memcmp(checkscript,script,scriptlen):0); + } //else printf("RO spendscript match.%d\n",scriptlen); + }*/ + if ( u->ipbits != ipbits || u->scriptpos != fpos || u->scriptlen != scriptlen || u->value != value || u->pkind != pkind || u->value != value || u->txidind != ramchain->H.txidind || (pkind != 0 && u->prevunspentind != A[pkind].lastind) || u->vout != vout || u->hdrsi != hdrsi ) { - printf("iguana_ramchain_addunspent: mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastunspentind,vout,hdrsi); + printf("iguana_ramchain_addunspent: (%d %d %d) vs (%d %d %d) mismatched values.(%d %.8f %d %d %d %d) vs (%d %.8f %d %d %d %d)\n",u->ipbits,u->scriptpos,u->scriptlen,ipbits,fpos,scriptlen,u->pkind,dstr(u->value),u->txidind,u->prevunspentind,u->vout,u->hdrsi,pkind,dstr(value),ramchain->H.txidind,A[pkind].lastind,vout,hdrsi); exit(-1); return(0); } @@ -422,55 +508,34 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 else { u->value = value; - u->type = type; + //if ( type == IGUANA_SCRIPT_76AC ) + // pubkeyoffset = P[pkind].pubkeyoffset; + //else pubkeyoffset = 0; u->vout = vout, u->hdrsi = hdrsi; u->txidind = ramchain->H.txidind, u->pkind = pkind; - u->prevunspentind = A[pkind].lastunspentind; + u->prevunspentind = A[pkind].lastind; + u->ipbits = ipbits; + u->scriptlen = scriptlen; + u->scriptpos = fpos; + u->type = type; } //printf("%p A[%d] last <- U%d\n",&A[pkind],pkind,unspentind); - A[pkind].balance += value; - A[pkind].lastunspentind = unspentind; + A[pkind].total += value; + A[pkind].lastind = unspentind; return(unspentind); } -uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint8_t *script,int32_t scriptlen,uint32_t sequence)//,int32_t hdrsi,int32_t bundlei) -{ - struct iguana_spend256 *s; uint32_t spendind; - spendind = ramchain->H.spendind++; - s = &S[spendind]; - if ( ramchain->H.ROflag != 0 ) - { - if ( (s->diffsequence == 0 && sequence != 0xffffffff) || (s->diffsequence != 0 && sequence == 0xffffffff) || memcmp(s->prevhash2.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout ) //|| s->hdrsi != hdrsi - { - char str[65],str2[65]; printf("check addspend.%d v %d RO value mismatch diffseq.%d seq.%x prev_vout(%d vs %d) %s vs %s\n",spendind,s->spendind,s->diffsequence,sequence,s->prevout,prev_vout,bits256_str(str,s->prevhash2),bits256_str(str2,prev_hash)); - //printf("check addspend.%d vs %d RO value mismatch (%d %d:%d) vs (%d %d:%d)\n",spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei,prev_vout,hdrsi,bundlei); - exit(-1); - return(0); - } - //printf(" READ.%p spendind.%d vs %d prevout.%d hdrsi.%d:%d\n",s,spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei); - } - else - { - if ( sequence != 0xffffffff ) - s->diffsequence = 1; - s->prevhash2 = prev_hash, s->prevout = prev_vout; - //s->hdrsi = hdrsi, s->bundlei = bundlei; - s->spendind = spendind; - //char str[65]; printf("W.%p s.%d vout.%d/%d %d:%d %s\n",s,spendind,s->prevout,prev_vout,s->hdrsi,s->bundlei,bits256_str(str,prev_hash)); - } - return(spendind); -} - -int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s) +int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s) { uint32_t ind,external; + *unspentindp = 0; memset(txidp,0,sizeof(*txidp)); - //printf("s.%p ramchaintxid vout.%x spendtxidind.%d numexternals.%d isext.%d numspendinds.%d\n",s,s->vout,s->spendtxidind,ramchain->numexternaltxids,s->external,ramchain->numspends); - if ( s->prevout < 0 ) - return(-1); ind = s->spendtxidind; external = (ind >> 31) & 1; ind &= ~(1 << 31); + //printf("s.%p ramchaintxid vout.%x spendtxidind.%d isext.%d ext.%d ind.%d\n",s,s->prevout,s->spendtxidind,s->external,external,ind); + if ( s->prevout < 0 ) + return(-1); if ( s->external != 0 && s->external == external && ind < numexternaltxids ) { //printf("ind.%d externalind.%d X[%d]\n",ind,ramchain->externalind,ramchain->H.data->numexternaltxids); @@ -480,6 +545,7 @@ int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct else if ( s->external == 0 && s->external == external && ind < numtxids ) { *txidp = T[ind].txid; + *unspentindp = T[ind].firstvout + s->prevout; return(s->prevout); } return(-2); @@ -509,14 +575,15 @@ int32_t iguana_ramchain_txid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 *txi return(-2); } -uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence)//,int32_t hdrsi,int32_t bundlei) +uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence,int32_t hdrsi,uint32_t ipbits,uint32_t scriptpos,int32_t vinscriptlen) { - struct iguana_spend *s; struct iguana_kvitem *ptr; bits256 txid; - uint32_t spendind,unspentind,txidind,pkind,external; uint64_t value = 0; + struct iguana_spend *s; struct iguana_kvitem *ptr = 0; bits256 txid; + uint32_t spendind,unspentind,txidind=0,pkind,external=0; uint64_t value = 0; + // uint8_t _script[IGUANA_MAXSCRIPTSIZE]; int32_t metalen,i,checklen; spendind = ramchain->H.spendind++; s = &Sx[spendind]; pkind = unspentind = 0; - if ( (ptr= iguana_hashfind(ramchain,'T',prev_hash.bytes)) == 0 ) + if ( prev_vout >= 0 && (ptr= iguana_hashfind(ramchain,'T',prev_hash.bytes)) == 0 ) { external = 1; txidind = ramchain->externalind++; @@ -536,8 +603,10 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 return(0); } txidind |= (1 << 31); - } else txidind = ptr->hh.itemind; - if ( (external= ((txidind >> 31) & 1)) == 0 ) + } + else if ( ptr != 0 ) + txidind = ptr->hh.itemind; + if ( prev_vout >= 0 && (external= ((txidind >> 31) & 1)) == 0 ) { if ( txidind > 0 && txidind < ramchain->H.data->numtxids ) { @@ -555,18 +624,63 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 if ( ramchain->H.ROflag != 0 ) { iguana_ramchain_txid(coin,RAMCHAIN_ARG,&txid,s); - if ( (s->diffsequence == 0 && sequence != 0xffffffff) || (s->diffsequence != 0 && sequence == 0xffffffff) || memcmp(txid.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout )// || s->hdrsi != hdrsi + if ( s->sequenceid != sequence || memcmp(txid.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout ) { - char str[65],str2[65]; printf("ramchain_addspend RO value mismatch diffseq.%d v %x (%d) vs (%d) %s vs %s\n",s->diffsequence,sequence,s->prevout,prev_vout,bits256_str(str,txid),bits256_str(str2,prev_hash)); + char str[65],str2[65]; printf("ramchain_addspend RO value mismatch diffseq.%x v %x (%d) vs (%d) %s vs %s\n",s->sequenceid,sequence,s->prevout,prev_vout,bits256_str(str,txid),bits256_str(str2,prev_hash)); return(0); } + /*if ( (checklen= iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) ) + { + static uint64_t counter; + if ( counter++ < 100 ) + { + for (i=0; iH.scriptoffset += metalen; } else { - if ( sequence != 0xffffffff ) - s->diffsequence = 1; + //for (i=0; isequenceid = sequence; s->external = external, s->spendtxidind = txidind, s->prevout = prev_vout; + s->ipbits = ipbits; + s->scriptpos = scriptpos; + s->scriptlen = vinscriptlen; + /*static uint64_t good,bad; + if ( 0 && iguana_metascript(coin,RAMCHAIN_ARG,s,vinscript,vinscriptlen,0) < 0 ) + { + static long errlen,err2len; char errbuf[1024]; + errlen += vinscriptlen; + if ( iguana_metascript(coin,RAMCHAIN_ARG,s,vinscript,vinscriptlen,1) < 0 ) + { + err2len += vinscriptlen; + errbuf[0] = 0; + for (i=0; i 138 ) + { + errbuf[0] = 0; + for (i=0; ihdrsi = hdrsi; //s->bundlei = bundlei; //char str[65]; printf("%s set prevout.%d -> %d\n",bits256_str(str,prev_hash),prev_vout,s->prevout); @@ -575,23 +689,58 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 } if ( pkind != 0 ) { - A[pkind].balance -= value; + //A[pkind].balance -= value; //A[pkind].lastspendind = spendind; //if ( P2[pkind].firstspendind == 0 ) // P2[pkind].firstspendind = spendind; } - /*if ( unspentind != 0 ) + return(spendind); +} + +uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer *addr,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint8_t *vinscript,int32_t vinscriptlen,uint32_t sequence,struct iguana_bundle *bp) +{ + struct iguana_spend256 *s; uint32_t spendind; + spendind = ramchain->H.spendind++; + s = &S[spendind]; + if ( ramchain->H.ROflag != 0 ) + { + if ( vinscriptlen != s->vinscriptlen || s->sequenceid != sequence || memcmp(s->prevhash2.bytes,prev_hash.bytes,sizeof(bits256)) != 0 || s->prevout != prev_vout ) //|| s->hdrsi != hdrsi + { + char str[65],str2[65]; printf("check offset %d (%d %d) addspend.%d v %d RO value mismatch sequenceid.%x seq.%x prev_vout(%d vs %d) %s vs %s\n",s->scriptpos,vinscriptlen,s->vinscriptlen,spendind,s->spendind,s->sequenceid,sequence,s->prevout,prev_vout,bits256_str(str,s->prevhash2),bits256_str(str2,prev_hash)); + //printf("check addspend.%d vs %d RO value mismatch (%d %d:%d) vs (%d %d:%d)\n",spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei,prev_vout,hdrsi,bundlei); + //exit(-1); + return(0); + } + //printf(" READ.%p spendind.%d vs %d prevout.%d hdrsi.%d:%d\n",s,spendind,s->spendind,s->prevout,s->hdrsi,s->bundlei); + } + else { - if ( U2[unspentind].spendind == 0 ) - U2[unspentind].spendind = spendind; - }*/ + s->sequenceid = sequence; + s->prevhash2 = prev_hash, s->prevout = prev_vout; + s->spendind = spendind; + if ( (s->vinscriptlen= vinscriptlen) > 0 && vinscript != 0 && addr != 0 && addr->vinsfp != 0 && vinscriptlen < IGUANA_MAXSCRIPTSIZE) + { + s->ipbits = (uint32_t)addr->ipbits; + s->scriptpos = (uint32_t)ftell(addr->vinsfp); + if ( fwrite(vinscript,1,vinscriptlen,addr->vinsfp) != vinscriptlen ) + printf("error writing vinscriptlen.%d\n",vinscriptlen); + else addr->dirty[1]++; + } else s->scriptpos = 0; + //else printf("spend256 scriptfpos.%d\n",s->scriptfpos); + //char str[65]; printf("W.%p s.%d vout.%d/%d [%d] %s fpos.%u slen.%d\n",s,spendind,s->prevout,prev_vout,bp->hdrsi,bits256_str(str,prev_hash),s->scriptfpos,s->vinscriptlen); + } return(spendind); } -int64_t iguana_hashmemsize(uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids) +int64_t iguana_hashmemsize(int64_t numtxids,int64_t numunspents,int64_t numspends,int64_t numpkinds,int64_t numexternaltxids,int64_t scriptspace) { int64_t allocsize = 0; - allocsize += (65536*4 + ((numtxids + numpkinds) * (sizeof(UT_hash_handle)*2)) + (((sizeof(struct iguana_account)) * 2 * numpkinds)) + (2 * numunspents * sizeof(struct iguana_Uextra))); + allocsize += (scriptspace + IGUANA_MAXSCRIPTSIZE + ((numtxids + numpkinds) * (sizeof(UT_hash_handle)*2)) + (((sizeof(struct iguana_account)) * 2 * numpkinds)) + (2 * numunspents * sizeof(struct iguana_spendvector))); + if ( allocsize >= (1LL << 32) ) + { + printf("REALLY big hashmemsize %llu, truncate and hope for best\n",(long long)allocsize); + allocsize = (1LL << 32) - 1; + } //printf("iguana_hashmemsize T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)allocsize); return(allocsize); } @@ -600,6 +749,7 @@ void _iguana_ramchain_setptrs(RAMCHAIN_PTRPS,struct iguana_ramchaindata *rdata) { *B = (void *)(long)((long)rdata + (long)rdata->Boffset); *T = (void *)(long)((long)rdata + (long)rdata->Toffset); + *Kspace = (void *)(long)((long)rdata + (long)rdata->Koffset); if ( ramchain->expanded != 0 ) { *Ux = (void *)(long)((long)rdata + (long)rdata->Uoffset); @@ -608,13 +758,13 @@ void _iguana_ramchain_setptrs(RAMCHAIN_PTRPS,struct iguana_ramchaindata *rdata) *X = (void *)(long)((long)rdata + (long)rdata->Xoffset); //ramchain->roU2 = (void *)(long)((long)rdata + (long)rdata->U2offset); //ramchain->roP2 = (void *)(long)((long)rdata + (long)rdata->P2offset); - ramchain->roA = (void *)(long)(long)((long)rdata + (long)rdata->Aoffset); + ramchain->creditsA = (void *)(long)(long)((long)rdata + (long)rdata->Aoffset); //if ( (*U2= ramchain->U2) == 0 ) // *U2 = ramchain->U2 = ramchain->roU2; //if ( (*P2= ramchain->P2) == 0 ) // *P2 = ramchain->P2 = ramchain->roP2; if ( (*A= ramchain->A) == 0 ) - *A = ramchain->A = ramchain->roA; + *A = ramchain->A = ramchain->creditsA; //printf("T.%p Ux.%p Sx.%p P.%p\n",*T,*Ux,*Sx,*P); *TXbits = (void *)(long)((long)rdata + (long)rdata->TXoffset); *PKbits = (void *)(long)((long)rdata + (long)rdata->PKoffset); @@ -651,7 +801,7 @@ void *iguana_ramchain_offset(void *dest,uint8_t *lhash,FILE *fp,uint64_t fpos,vo return((void *)(long)((long)destptr + fpos)); } -int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *destptr,uint64_t fpos,uint32_t expanded,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t txsparsebits,uint64_t numtxsparse,uint32_t pksparsebits,uint64_t numpksparse,uint64_t srcsize,RAMCHAIN_FUNC,int32_t numblocks) +int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *destptr,uint64_t fpos,uint32_t expanded,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,uint32_t txsparsebits,uint64_t numtxsparse,uint32_t pksparsebits,uint64_t numpksparse,uint64_t srcsize,RAMCHAIN_FUNC,int32_t numblocks) { #define RAMCHAIN_LARG(ind) ((lhashes == 0) ? 0 : lhashes[ind].bytes) #define SPARSECOUNT(x) ((x) << 2) @@ -685,8 +835,8 @@ int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *d if ( 0 && fparg != 0 && numblocks > 1 ) { printf("%s %p\n",bits256_str(str,B[0].hash2),B); - if ( bits256_nonz(B[0].hash2) == 0 ) - getchar(); + //if ( bits256_nonz(B[0].hash2) == 0 ) + // getchar(); } T = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_TXIDS),fparg,fpos,T,&offset,(sizeof(struct iguana_txid) * numtxids),srcsize); if ( expanded != 0 ) @@ -707,12 +857,13 @@ int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *d } else { - Ux = destptr, Sx = destptr, P = destptr, A = destptr, X = destptr, TXbits = destptr, PKbits = destptr; //U2 = destptr, P2 = destptr, + Ux = destptr, Sx = destptr, P = destptr, A = destptr, X = destptr, TXbits = destptr, PKbits = destptr, Kspace = destptr; //U2 = destptr, P2 = destptr, U = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_UNSPENTS),fparg,fpos,U,&offset,(sizeof(struct iguana_unspent20) * numunspents),srcsize); if ( 0 && lhashes != 0 ) printf("iter.%d lhashes.%p offset.%ld destptr.%p len.%ld fparg.%p fpos.%ld srcsize.%ld\n",iter,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),(long)offset,destptr,(long)sizeof(struct iguana_spend256) * numspends,fparg,(long)fpos,(long)srcsize); S = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_SPENDS),fparg,fpos,S,&offset,(sizeof(struct iguana_spend256) * numspends),srcsize); } + Kspace = iguana_ramchain_offset(rdata,RAMCHAIN_LARG(IGUANA_LHASH_KSPACE),fparg,fpos,Kspace,&offset,scriptspace,srcsize); // at the end so it can be truncated if ( (fparg= fp) == 0 ) break; lhashes = 0; @@ -732,6 +883,8 @@ int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *d rdata->Uoffset = (uint64_t)((long)U - (long)destptr); rdata->Soffset = (uint64_t)((long)S - (long)destptr); } + rdata->Koffset = (uint64_t)((long)Kspace - (long)destptr); + rdata->scriptspace = (uint32_t)(offset - rdata->Koffset); rdata->Poffset = (uint64_t)((long)P - (long)destptr); //rdata->U2offset = (uint64_t)((long)U2 - (long)destptr); //rdata->P2offset = (uint64_t)((long)P2 - (long)destptr); @@ -752,28 +905,36 @@ int64_t _iguana_rdata_action(FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *d #undef SPARSECOUNT } -int64_t iguana_ramchain_action(RAMCHAIN_FUNC,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],struct iguana_ramchaindata *destdata,uint64_t fpos,struct iguana_ramchaindata *srcdata,int32_t numblocks) +int64_t iguana_ramchain_action(RAMCHAIN_FUNC,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],struct iguana_ramchaindata *destdata,uint64_t fpos,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace) { - if ( 0 && ramchain->expanded != 0 ) + if ( 0 && ramchain->expanded == 0 ) printf("action.%p (%p %p %p) %ld allocated.%ld [%d:%d %d:%d]\n",srcdata,fp,lhashes,destdata,(long)fpos,(long)srcdata->allocsize,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse); - return(_iguana_rdata_action(fp,lhashes,destdata,fpos,ramchain->expanded,srcdata->numtxids,srcdata->numunspents,srcdata->numspends,srcdata->numpkinds,srcdata->numexternaltxids,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse,srcdata->allocsize,RAMCHAIN_ARG,numblocks)); + return(_iguana_rdata_action(fp,lhashes,destdata,fpos,ramchain->expanded,srcdata->numtxids,srcdata->numunspents,srcdata->numspends,srcdata->numpkinds,srcdata->numexternaltxids,scriptspace,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse,srcdata->allocsize,RAMCHAIN_ARG,numblocks)); } -int64_t iguana_ramchain_size(RAMCHAIN_FUNC,int32_t numblocks) +int64_t iguana_ramchain_size(RAMCHAIN_FUNC,int32_t numblocks,int32_t scriptspace) { - return(iguana_ramchain_action(RAMCHAIN_ARG,0,0,0,0,ramchain->H.data,numblocks)); + int64_t allocsize; + allocsize = iguana_ramchain_action(RAMCHAIN_ARG,0,0,0,0,ramchain->H.data,numblocks,scriptspace); + if ( 0 && ramchain->expanded != 0 ) + printf("%p iguana_ramchain_size.expanded.%d %u: Koffset.%u scriptoffset.%u stacksize.%u stackspace.%u [%u]\n",ramchain,ramchain->expanded,(int32_t)allocsize,(int32_t)ramchain->H.data->Koffset,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)ramchain->H.data->stackspace,scriptspace); + return(allocsize); } long iguana_ramchain_setsize(struct iguana_ramchain *ramchain,struct iguana_ramchaindata *srcdata,int32_t numblocks) { RAMCHAIN_DECLARE; struct iguana_ramchaindata *rdata = ramchain->H.data; - B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, TXbits = 0, PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, + B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, rdata->numtxids = ramchain->H.txidind; rdata->numunspents = ramchain->H.unspentind; rdata->numspends = ramchain->H.spendind; rdata->numpkinds = ramchain->pkind; rdata->numexternaltxids = ramchain->externalind; - rdata->allocsize = iguana_ramchain_size(RAMCHAIN_ARG,numblocks); + rdata->scriptspace = ramchain->H.scriptoffset; + rdata->stackspace = ramchain->H.stacksize; + rdata->allocsize = iguana_ramchain_size(RAMCHAIN_ARG,numblocks,rdata->scriptspace); + if ( 0 && rdata->scriptspace != 0 ) + printf("iguana_ramchain_setsize: Koffset.%d scriptspace.%d stackspace.%d (scriptoffset.%d stacksize.%d) allocsize.%d\n",(int32_t)rdata->Koffset,(int32_t)rdata->scriptspace,(int32_t)rdata->stackspace,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)rdata->allocsize); ramchain->datasize = rdata->allocsize; return((long)rdata->allocsize); } @@ -781,43 +942,44 @@ long iguana_ramchain_setsize(struct iguana_ramchain *ramchain,struct iguana_ramc int64_t iguana_ramchain_compact(RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks) { //iguana_ramchain_setsize(ramchain,srcdata); - return(iguana_ramchain_action(RAMCHAIN_ARG,0,0,destdata,0,srcdata,numblocks)); + return(iguana_ramchain_action(RAMCHAIN_ARG,0,0,destdata,0,srcdata,numblocks,ramchain->H.scriptoffset)); } -bits256 iguana_ramchain_lhashes(RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks) +bits256 iguana_ramchain_lhashes(RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace) { - iguana_ramchain_action(RAMCHAIN_ARG,0,destdata->lhashes,0,0,srcdata,numblocks); + iguana_ramchain_action(RAMCHAIN_ARG,0,destdata->lhashes,0,0,srcdata,numblocks,scriptspace); memset(&destdata->sha256,0,sizeof(destdata->sha256)); vcalc_sha256(0,destdata->sha256.bytes,(void *)destdata,sizeof(*destdata)); return(destdata->sha256); } -int64_t iguana_ramchain_saveaction(RAMCHAIN_FUNC,FILE *fp,struct iguana_ramchaindata *rdata,int32_t numblocks) +int64_t iguana_ramchain_saveaction(RAMCHAIN_FUNC,FILE *fp,struct iguana_ramchaindata *rdata,int32_t numblocks,int32_t scriptspace) { long before,after; before = ftell(fp); - iguana_ramchain_action(RAMCHAIN_ARG,fp,0,rdata,0,rdata,numblocks); + iguana_ramchain_action(RAMCHAIN_ARG,fp,0,rdata,0,rdata,numblocks,scriptspace); after = ftell(fp); - if ( 0 && ramchain->expanded != 0 ) + if ( 0 && ramchain->expanded == 0 ) { - char str[65]; - printf("SAVEACTION: rdata.%ld DEST T.%d U.%d S.%d P.%d X.%d -> size.%ld %ld vs %ld %p %s\n",sizeof(*rdata),rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks),after-before+sizeof(*rdata),&X[1],bits256_str(str,X[1])); + int32_t i; for (i=0; i size.%ld %ld vs %ld %u\n",(int32_t)rdata->Koffset,(long)Kspace-(long)rdata,sizeof(*rdata),rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks,scriptspace),after-before+sizeof(*rdata),scriptspace); } //printf("before.%ld after.%ld allocsize.%ld [%ld] %ld expanded.%d\n",before,after,(long)srcdata->allocsize,(long)ramchain->H.data->allocsize,(long)iguana_ramchain_size(ramchain),ramchain->expanded); return(after - before); } -int64_t iguana_ramchain_init(struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t firsti,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,int32_t numexternaltxids,int32_t expanded,int32_t numblocks) +int64_t iguana_ramchain_init(struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t firsti,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,int32_t numexternaltxids,int32_t scriptspace,int32_t expanded,int32_t numblocks) { RAMCHAIN_DECLARE; int64_t offset = 0; struct iguana_ramchaindata *rdata; - B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, TXbits = 0, PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, + B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; if ( mem == 0 ) return(0); memset(ramchain,0,sizeof(*ramchain)); ramchain->expanded = (expanded != 0); if ( (ramchain->hashmem= hashmem) != 0 ) iguana_memreset(hashmem); - rdata = ramchain->H.data = mem->ptr, offset += sizeof(struct iguana_ramchaindata); + rdata = ramchain->H.data = mem->ptr;//, offset += sizeof(struct iguana_ramchaindata); if ( (rdata->firsti= firsti) != 0 ) { numtxids++, numunspents++, numspends++; @@ -828,63 +990,69 @@ int64_t iguana_ramchain_init(struct iguana_ramchain *ramchain,struct OS_memspace numexternaltxids = numspends; if ( numpkinds == 0 ) numpkinds = numunspents; + _iguana_rdata_action(0,0,rdata,0,expanded,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks); + offset += rdata->allocsize; if ( 0 && expanded != 0 ) printf("init T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)offset); - _iguana_rdata_action(0,0,rdata,0,expanded,numtxids,numunspents,numspends,numpkinds,numexternaltxids,0,0,0,0,0,RAMCHAIN_ARG,numblocks); - if ( rdata->allocsize != iguana_ramchain_size(RAMCHAIN_ARG,numblocks) ) + if ( rdata->allocsize != iguana_ramchain_size(RAMCHAIN_ARG,numblocks,scriptspace) ) { - printf("offset.%ld vs memsize.%ld\n",(long)offset,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks)); + printf("offset.%ld scriptspace.%d allocsize.%ld vs memsize.%ld\n",(long)offset,scriptspace,(long)rdata->allocsize,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks,scriptspace)); exit(-1); } - if ( offset < mem->totalsize ) + if ( offset <= mem->totalsize ) iguana_memreset(mem); else { - printf("offset.%ld vs memsize.%ld\n",(long)offset,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks)); + printf("offset.%ld vs memsize.%ld\n",(long)offset,(long)iguana_ramchain_size(RAMCHAIN_ARG,numblocks,scriptspace)); printf("NEED %ld realloc for %ld\n",(long)offset,(long)mem->totalsize); + getchar(); exit(-1); iguana_mempurge(mem); iguana_meminit(mem,"ramchain",0,offset,0); } - //printf("init.(%d %d %d %d %d)\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids); + if ( rdata->allocsize > mem->totalsize ) + { + printf("init.(%d %d %d %d %d) rdata->allocsize.%ld mem->totalsize.%ld hashmemsize.%ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)rdata->allocsize,mem->totalsize,hashmem!=0?hashmem->totalsize:0); + exit(-1); + } return(offset); } -int32_t iguana_ramchain_alloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,int32_t height,int32_t numblocks) +int32_t iguana_ramchain_alloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,int32_t height,int32_t numblocks) { RAMCHAIN_DECLARE; int64_t hashsize,allocsize,x; - B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, TXbits = 0, PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, + B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; memset(ramchain,0,sizeof(*ramchain)); ramchain->height = height; - allocsize = _iguana_rdata_action(0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,0,0,0,0,0,RAMCHAIN_ARG,numblocks); - //printf("T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)allocsize); + allocsize = _iguana_rdata_action(0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks); + if ( 0 && ramchain->expanded != 0 ) + printf("T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)allocsize); memset(mem,0,sizeof(*mem)); memset(hashmem,0,sizeof(*hashmem)); - hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids); - while ( (x= (myallocated(0,-1)+hashsize+allocsize)) > coin->MAXMEM ) + hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace); + while ( 0 && (x= (myallocated(0,-1)+hashsize+allocsize + 65536)) > coin->MAXMEM ) { - char str[65],str2[65]; fprintf(stderr,"ht.%d wait for allocated %s < MAXMEM %s | elapsed %.2f minutes\n",height,mbstr(str,hashsize+allocsize),mbstr(str2,coin->MAXMEM),(double)(time(NULL)-coin->startutc)/60.); - sleep(3); + char str[65],str2[65]; fprintf(stderr,"ht.%d wait for allocated %s < MAXMEM %s | elapsed %.2f minutes hashsize.%ld allocsize.%ld\n",height,mbstr(str,myallocated(0,-1)+hashsize+allocsize),mbstr(str2,coin->MAXMEM),(double)(time(NULL)-coin->startutc)/60.,(long)hashsize,(long)allocsize); + sleep(13); } - iguana_meminit(hashmem,"ramhashmem",0,hashsize + 4096,0); - iguana_meminit(mem,"ramchain",0,allocsize + 4096,0); + iguana_meminit(hashmem,"ramhashmem",0,hashsize,0); + iguana_meminit(mem,"ramchain",0,allocsize + 65536,0); mem->alignflag = sizeof(uint32_t); hashmem->alignflag = sizeof(uint32_t); - if ( iguana_ramchain_init(ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,1,numblocks) == 0 ) + if ( iguana_ramchain_init(ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) == 0 ) return(-1); return(0); } long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,struct iguana_bundle *bp) { - struct iguana_ramchaindata *rdata,tmp; - char fname[1024]; long fpos = -1; int32_t hdrsi,checki; FILE *fp; + struct iguana_ramchaindata *rdata,tmp; char fname[1024]; long fpos = -1; int32_t hdrsi,checki; FILE *fp; if ( (rdata= ramchain->H.data) == 0 ) { printf("ramchainsave no data ptr\n"); return(-1); } - if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?"DB":"tmp",fname,ipbits,hash2,prevhash2,ramchain->numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?"DB":GLOBALTMPDIR,fname,ipbits,hash2,prevhash2,ramchain->numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { printf(" wont save.(%s) bundlei.%d != checki.%d\n",fname,bundlei,checki); return(-1); @@ -896,7 +1064,9 @@ long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits coin->peers.numfiles++; } else if ( ipbits != 0 ) - fseek(fp,0,SEEK_END); + { + //fseek(fp,0,SEEK_END); + } else { fclose(fp); @@ -905,11 +1075,14 @@ long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits if ( fp != 0 ) { fpos = ftell(fp); - iguana_ramchain_lhashes(RAMCHAIN_ARG,rdata,rdata,bp!=0?bp->n:1); + if ( ramchain->expanded != 0 ) + iguana_ramchain_lhashes(RAMCHAIN_ARG,rdata,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset); tmp = *rdata; iguana_ramchain_compact(RAMCHAIN_ARG,&tmp,rdata,bp!=0?bp->n:1); + if ( 0 && ramchain->expanded != 0 ) + printf("compact: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize); fwrite(&tmp,1,sizeof(tmp),fp); - iguana_ramchain_saveaction(RAMCHAIN_ARG,fp,rdata,bp!=0?bp->n:1); + iguana_ramchain_saveaction(RAMCHAIN_ARG,fp,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset); *rdata = tmp; fclose(fp); } @@ -920,12 +1093,12 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * { RAMCHAIN_DECLARE; struct iguana_txid *t; struct iguana_unspent *u; struct iguana_pkhash *p; struct iguana_ramchaindata *rdata; int32_t k,pkind,vout; struct iguana_kvitem *ptr; bits256 txid; - // iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin; uint16_t numvouts,numvins;} if ( (rdata= ramchain->H.data) == 0 ) return(-100); _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); ramchain->pkind = ramchain->H.unspentind = ramchain->H.spendind = rdata->firsti; - ramchain->externalind = 0; + ramchain->externalind = ramchain->H.stacksize = 0; + ramchain->H.scriptoffset = 1; for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { t = &T[ramchain->H.txidind]; @@ -988,9 +1161,9 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * p = &P[pkind]; if ( (ptr= iguana_hashfind(ramchain,'P',p->rmd160)) == 0 ) return(-8); - if ( ptr->hh.itemind == pkind && p->firstunspentind > ramchain->H.unspentind ) + if ( ptr->hh.itemind != pkind )//&& p->firstunspentind > ramchain->H.unspentind ) { - printf("%p itemind.%d pkind.%d firstunspent.%d != %d unspentind?\n",p,ptr->hh.itemind,pkind,p->firstunspentind,ramchain->H.unspentind); + printf("%p itemind.%d pkind.%d %d unspentind?\n",p,ptr->hh.itemind,pkind,ramchain->H.unspentind); return(-9); } } @@ -1037,14 +1210,14 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * } } } - if ( ramchain->expanded != 0 && ramchain->A != ramchain->roA ) + if ( ramchain->expanded != 0 && ramchain->A != ramchain->creditsA ) { for (k=rdata->firsti; knumpkinds; k++) { - if ( memcmp(&ramchain->A[k],&ramchain->roA[k],sizeof(ramchain->A[k])) != 0 ) + if ( memcmp(&ramchain->A[k],&ramchain->creditsA[k],sizeof(ramchain->A[k])) != 0 ) { - printf("k.%d balance.(%.8f vs %.8f) lastU.(%d %d)\n",k,dstr(ramchain->A[k].balance),dstr(ramchain->roA[k].balance),ramchain->A[k].lastunspentind,ramchain->roA[k].lastunspentind); - return(-14); + printf("k.%d balance.(%.8f vs %.8f) lastU.(%d %d)\n",k,dstr(ramchain->A[k].total),dstr(ramchain->creditsA[k].total),ramchain->A[k].lastind,ramchain->creditsA[k].lastind); + //return(-14); } //if ( memcmp(&ramchain->P2[k],&ramchain->roP2[k],sizeof(ramchain->P2[k])) != 0 ) // return(-15); @@ -1061,9 +1234,11 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag struct iguana_kvitem *item,*tmp; if ( ramchain->H.ROflag != 0 && ramchain->hashmem == 0 ) { - //printf("Free A %p %p, U2, P2\n",ramchain->A,ramchain->roA); - if ( ramchain->A != ramchain->roA ) + if ( ramchain->A != ramchain->creditsA ) + { + //printf("hashmem.%p Free A %p %p, numpkinds.%d %ld\n",ramchain->hashmem,ramchain->A,ramchain->creditsA,ramchain->H.data->numpkinds,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); myfree(ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds), ramchain->A = 0; + } //if ( ramchain->U2 != ramchain->roU2 ) // myfree(ramchain->U2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents), ramchain->U2 = 0; //if ( ramchain->P2 != ramchain->roP2 ) @@ -1079,6 +1254,7 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag if ( ramchain->hashmem == 0 ) myfree(item,sizeof(*item)); } + ramchain->txids = 0; } if ( ramchain->pkhashes != 0 ) { @@ -1088,25 +1264,70 @@ int32_t iguana_ramchain_free(struct iguana_ramchain *ramchain,int32_t deleteflag if ( ramchain->hashmem == 0 ) myfree(item,sizeof(*item)); } + ramchain->pkhashes = 0; } } if ( ramchain->hashmem != 0 ) - iguana_memreset(ramchain->hashmem); + iguana_mempurge(ramchain->hashmem), ramchain->hashmem = 0; if ( ramchain->filesize != 0 ) + { munmap(ramchain->fileptr,ramchain->filesize); - memset(ramchain,0,sizeof(*ramchain)); + ramchain->fileptr = 0; + ramchain->filesize = 0; + } + if ( ramchain->Xspendptr != 0 ) + { + munmap(ramchain->Xspendptr,ramchain->filesize); + ramchain->Xspendptr = 0; + ramchain->numXspends = 0; + ramchain->Xspendinds = 0; + } + if ( deleteflag != 0 ) + memset(ramchain,0,sizeof(*ramchain)); return(0); } -void iguana_ramchain_extras(struct iguana_ramchain *ramchain,struct OS_memspace *hashmem) +void iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { - RAMCHAIN_DECLARE; + RAMCHAIN_DECLARE; char fname[1024]; //long filesize; if ( ramchain->expanded != 0 ) { _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( (ramchain->hashmem= hashmem) != 0 ) - iguana_memreset(hashmem); - ramchain->A = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * ramchain->H.data->numpkinds,1) : mycalloc('p',ramchain->H.data->numpkinds,sizeof(struct iguana_account)); + if ( extraflag == 0 ) + { + if ( (ramchain->hashmem= hashmem) != 0 ) + iguana_memreset(hashmem); + else printf("alloc ramchain->A %ld\n",sizeof(struct iguana_account) * ramchain->H.data->numpkinds); + ramchain->A = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * ramchain->H.data->numpkinds,1) : mycalloc('p',ramchain->H.data->numpkinds,sizeof(struct iguana_account)); + ramchain->Uextras = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents,1) : mycalloc('p',ramchain->H.data->numunspents,sizeof(*ramchain->Uextras)); + } + else + { + if ( 1 && extraflag == 2 ) + { + sprintf(fname,"accounts/%s/debits.%d",coin->symbol,ramchain->H.data->height); + //ramchain->A = OS_filestr(&filesize,fname); + //if ( filesize != sizeof(*ramchain->A)*ramchain->H.data->numpkinds ) + // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->A)*ramchain->H.data->numpkinds); + sprintf(fname,"accounts/%s/lastspends.%d",coin->symbol,ramchain->H.data->height); + //ramchain->Uextras = OS_filestr(&filesize,fname); + //if ( filesize != sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds ) + // printf("%s unexpected filesize %ld vs %ld\n",fname,filesize,sizeof(*ramchain->Uextras)*ramchain->H.data->numpkinds); + //if ( ramchain->A == 0 ) + ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + //if ( ramchain->Uextras == 0 ) + ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); + } + else + { + //if ( ramchain->A == 0 ) + ramchain->A = myaligned_alloc(sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + //if ( ramchain->Uextras == 0 ) + ramchain->Uextras = myaligned_alloc(sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents); + } + //printf("ALLOC RAMCHAIN A.%p Uextras.%p | extraflag.%d hashmem.%p\n",ramchain->A,ramchain->Uextras,extraflag,ramchain->hashmem); + } + //printf("hashmem.%p A allocated.%p numpkinds.%d %ld\n",hashmem,ramchain->A,ramchain->H.data->numpkinds,sizeof(struct iguana_account)*ramchain->H.data->numpkinds); //ramchain->P2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_pkextra) * ramchain->H.data->numpkinds,1) : mycalloc('2',ramchain->H.data->numpkinds,sizeof(struct iguana_pkextra)); ///ramchain->U2 = (hashmem != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_Uextra) * ramchain->H.data->numunspents,1) : mycalloc('3',ramchain->H.data->numunspents,sizeof(struct iguana_Uextra)); //printf("iguana_ramchain_extras A.%p:%p U2.%p:%p P2.%p:%p\n",ramchain->A,ramchain->roA,ramchain->U2,ramchain->roU2,ramchain->P2,ramchain->roP2); @@ -1115,13 +1336,52 @@ void iguana_ramchain_extras(struct iguana_ramchain *ramchain,struct OS_memspace } } +int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) +{ + int32_t hdrsi; bits256 sha256; char fname[1024],dirname[128]; void *ptr; long filesize; static bits256 zero; + sprintf(dirname,"DB/%s/spends",coin->symbol); + if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + { + if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) + { + ramchain->Xspendinds = (void *)((long)ptr + sizeof(sha256)); + vcalc_sha256(0,sha256.bytes,(void *)ramchain->Xspendinds,(int32_t)(filesize - sizeof(sha256))); + if ( memcmp(sha256.bytes,ptr,sizeof(sha256)) == 0 ) + { + ramchain->Xspendptr = ptr; + ramchain->numXspends = (int32_t)((filesize - sizeof(sha256)) / sizeof(*ramchain->Xspendinds)); + //int32_t i; for (i=0; inumXspends; i++) + // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); + //printf("filesize %ld Xspendptr.%p %p num.%d\n",ftell(fp),ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + //printf("mapped utxo vector[%d] from (%s)\n",ramchain->numXspends,fname); + } + else + { + char str[65]; printf("hash cmp error.%d vs (%s)\n",memcmp(sha256.bytes,ptr,sizeof(sha256)),bits256_str(str,sha256)); + munmap(ptr,filesize); + ramchain->Xspendinds = 0; + } + } //else printf("no Xspendfile\n"); + } else printf("couldnt open.(%s)\n",fname); + return(ramchain->numXspends); +} + struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) { RAMCHAIN_DECLARE; int32_t valid,i,checki,hdrsi; char str[65],str2[65]; long filesize; void *ptr; struct iguana_block *block; + /*if ( ramchain->expanded != 0 && (ramchain->sigsfileptr == 0 || ramchain->sigsfilesize == 0) ) + { + sprintf(sigsfname,"sigs/%s/%s",coin->symbol,bits256_str(str,hash2)); + if ( (ramchain->sigsfileptr= OS_mapfile(sigsfname,&ramchain->sigsfilesize,0)) == 0 ) + { + printf("couldnt map.(%s)\n",sigsfname); + return(0); + } + }*/ if ( ramchain->fileptr == 0 || ramchain->filesize <= 0 ) { - if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?"DB":"tmp",fname,ipbits,hash2,prevhash2,numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + if ( (checki= iguana_peerfname(coin,&hdrsi,ipbits==0?"DB":GLOBALTMPDIR,fname,ipbits,hash2,prevhash2,numblocks)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { printf("iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d %s\n",fname,hdrsi,bundlei,bits256_str(str,hash2)); return(0); @@ -1141,7 +1401,7 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname ramchain->H.ROflag = 1; ramchain->expanded = expanded; ramchain->numblocks = (bp == 0) ? 1 : bp->n; - //printf("ptr.%p %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld\n",ptr,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize); + //printf("ptr.%p %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); if ( 0 && bp != 0 ) { /*blocksRO = (struct iguana_blockRO *)ramchain->H.data; @@ -1157,8 +1417,8 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname bp->blocks[i]->RO = blocksRO[i]; } ramchain->H.data = (void *)&blocksRO[bp->n];*/ - for (valid=0,i=bp->n=1; i>=0; i--) - { + for (valid=0,i=bp->n-1; i>=0; i--) + { if ( (block= bp->blocks[i]) != 0 ) { if ( memcmp(block->RO.hash2.bytes,bp->hashes[i].bytes,sizeof(block->RO.hash2)) == 0 ) @@ -1175,9 +1435,9 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname } } _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks) != ramchain->H.data->allocsize || fpos+ramchain->H.data->allocsize > filesize ) + if ( iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace) != ramchain->H.data->allocsize || fpos+ramchain->H.data->allocsize > filesize ) { - printf("iguana_ramchain_map.(%s) size mismatch %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks),(long)ramchain->H.data->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+ramchain->H.data->allocsize)); + printf("iguana_ramchain_map.(%s) size mismatch %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace),(long)ramchain->H.data->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+ramchain->H.data->allocsize)); exit(-1); //munmap(ramchain->fileptr,ramchain->filesize); return(0); @@ -1191,9 +1451,9 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname else if ( ramchain->expanded != 0 ) { if ( allocextras > 0 ) - iguana_ramchain_extras(ramchain,ramchain->hashmem); + iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras); } - if ( B != 0 ) + if ( B != 0 && bp != 0 ) { for (i=0; in; i++) { @@ -1204,9 +1464,11 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname } bp->blocks[i]->RO = B[i];//coin->blocks.RO[bp->bundleheight + i]; coin->blocks.RO[bp->bundleheight+i] = B[i]; + bp->hashes[i] = B[i].hash2; } - } + //printf("mapped %s scriptspace %d:%d\n",fname,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); + iguana_Xspendmap(coin,ramchain,bp); return(ramchain); } else printf("iguana_ramchain_map.(%s) cant map file\n",fname); return(0); @@ -1228,7 +1490,7 @@ void iguana_ramchain_link(struct iguana_ramchain *ramchain,bits256 firsthash2,bi ramchain->numblocks = numblocks; ramchain->lasthash2 = lasthash2; ramchain->H.txidind = ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = firsti; - ramchain->externalind = 0; + ramchain->externalind = 0;//ramchain->H.scriptoffset = ramchain->H.stacksize = 0; } int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B,int32_t deepflag) @@ -1237,29 +1499,36 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, struct iguana_txid *Ta,*Tb; struct iguana_unspent20 *Ua,*Ub; struct iguana_spend256 *Sa,*Sb; struct iguana_pkhash *Pa,*Pb; bits256 *Xa,*Xb; struct iguana_blockRO *Ba,*Bb; struct iguana_account *ACCTa,*ACCTb; struct iguana_unspent *Uxa,*Uxb; - struct iguana_spend *Sxa,*Sxb; uint8_t *TXbitsa,*TXbitsb,*PKbitsa,*PKbitsb; + struct iguana_spend *Sxa,*Sxb; uint8_t *TXbitsa,*TXbitsb,*PKbitsa,*PKbitsb,*Kspacea,*Kspaceb; if ( A->H.data != 0 && B->H.data != 0 && A->H.data->numblocks == B->H.data->numblocks && memcmp(A->H.data->firsthash2.bytes,B->H.data->firsthash2.bytes,sizeof(A->H.data->firsthash2)) == 0 ) { if ( A->H.data->firsti == B->H.data->firsti && A->H.data->numtxids == B->H.data->numtxids && A->H.data->numunspents == B->H.data->numunspents && A->H.data->numspends == B->H.data->numspends && A->H.data->numpkinds == B->H.data->numpkinds && A->H.data->numexternaltxids == B->H.data->numexternaltxids ) { - _iguana_ramchain_setptrs(A,&Ba,&Ta,&Ua,&Sa,&Pa,&ACCTa,&Xa,&Uxa,&Sxa,&TXbitsa,&PKbitsa,A->H.data); - _iguana_ramchain_setptrs(B,&Bb,&Tb,&Ub,&Sb,&Pb,&ACCTb,&Xb,&Uxb,&Sxb,&TXbitsb,&PKbitsb,B->H.data); + _iguana_ramchain_setptrs(A,&Ba,&Ta,&Ua,&Sa,&Pa,&ACCTa,&Xa,&Uxa,&Sxa,&TXbitsa,&PKbitsa,&Kspacea,A->H.data); + _iguana_ramchain_setptrs(B,&Bb,&Tb,&Ub,&Sb,&Pb,&ACCTb,&Xb,&Uxb,&Sxb,&TXbitsb,&PKbitsb,&Kspaceb,B->H.data); for (i=A->H.data->firsti; iH.data->numtxids; i++) if ( memcmp(&Ta[i],&Tb[i],sizeof(Ta[i])) != 0 ) return(-2); - if ( A->numblocks > 1 ) + if ( A->numblocks > 0 ) { + if ( A->expanded != 0 ) + { for (i=A->H.data->firsti; iH.data->numspends; i++) if ( memcmp(&Sxa[i],&Sxb[i],sizeof(Sxa[i])) != 0 ) return(-3); - for (i=A->H.data->firsti; iH.data->numunspents; i++) - { + /*for (i=A->H.data->firsti; iH.data->numunspents; i++) + {break; + int32_t j,metalen,checklen; uint8_t _script[8129],*checkscript; if ( memcmp(&Uxa[i],&Uxb[i],sizeof(Uxa[i])) != 0 ) return(-4); + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspacea,Uxa[i].type,_script,Uxa[i].scriptoffset,0); + for (j=0; jH.data->firsti; iH.data->numpkinds; i++) { //if ( memcmp(&P2a[i],&P2b[i],sizeof(P2a[i])) != 0 ) @@ -1275,15 +1544,29 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, printf("X[%d] A.%s B.%s\n",i,str,str2); return(-8); } + } + else + { + for (i=A->H.data->firsti; iH.data->numspends; i++) + if ( memcmp(&Sa[i],&Sb[i],sizeof(Sa[i])) != 0 ) + return(-9); + for (i=A->H.data->firsti; iH.data->numunspents; i++) + if ( memcmp(&Ua[i],&Ub[i],sizeof(Ua[i])) != 0 ) + return(-10); + /*for (i=A->H.data->firsti; iH.data->numunspents; i++) + {break; + int32_t j,metalen,checklen; uint8_t _script[8129],*checkscript; + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspacea,Ua[i].type,_script,Ua[i].scriptoffset,0); + for (j=0; jH.data->firsti; iH.data->numspends; i++) - if ( memcmp(&Sa[i],&Sb[i],sizeof(Sa[i])) != 0 ) - return(-9); - for (i=A->H.data->firsti; iH.data->numunspents; i++) - if ( memcmp(&Ua[i],&Ub[i],sizeof(Ua[i])) != 0 ) - return(-10); } } return(0); @@ -1292,23 +1575,27 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, return(-1); } -int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain) +int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp) { RAMCHAIN_DECLARE; RAMCHAIN_DESTDECLARE; - int32_t j,hdrsi,prevout; uint32_t sequence,destspendind=0,desttxidind=0; - bits256 prevhash; uint64_t value; uint8_t type; - struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t *rmd160; struct iguana_unspent *u; - if ( dest != 0 ) - _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + int32_t j,hdrsi,prevout,scriptlen; uint32_t scriptpos,ipbits,sequenceid,destspendind=0,desttxidind=0; + bits256 prevhash; uint64_t value; uint8_t type; struct iguana_unspent *u; + struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t *rmd160; + //if ( dest != 0 ) + // printf("iterate ramchain.%p rdata.%p dest.%p ht.%d/%d txids.%p destoffset.%d\n",ramchain,ramchain->H.data,dest,bp->bundleheight,bp->n,ramchain->txids,dest->H.scriptoffset); if ( (rdata= ramchain->H.data) == 0 ) { printf("iguana_ramchain_iterate cant iterate without data\n"); return(-1); } + if ( dest != 0 ) + _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); + //else fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); ramchain->H.ROflag = 1; ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = rdata->firsti; - ramchain->externalind = 0; + ramchain->externalind = ramchain->H.stacksize = 0; + ramchain->H.scriptoffset = 1; if ( dest != 0 ) { desttxidind = dest->H.txidind; @@ -1316,23 +1603,24 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { - if ( 0 && ramchain->expanded != 0 ) - printf("ITER TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p\n",ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0); + if ( 0 && ramchain->expanded == 0 && dest != 0 ) + printf("ITER TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); tx = &T[ramchain->H.txidind]; if ( iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) return(-1); if ( dest != 0 ) { char str[65]; - if ( 0 && ramchain->expanded != 0 ) + if ( 0 && ramchain->expanded == 0 ) printf("add hdrsi.%d dest.%p txidind.%d %s\n",dest->H.hdrsi,ramchain,dest->H.txidind,bits256_str(str,tx->txid)); if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp) == 0 ) return(-2); } for (j=0; jnumvouts; j++) { - if ( 0 && ramchain->expanded != 0 ) - printf("unspentind.%d pkind.%d Ux.%p\n",ramchain->H.unspentind,Ux[ramchain->H.unspentind].pkind,Ux); + ipbits = 0; + scriptpos = 0; + scriptlen = 0; if ( ramchain->H.unspentind < rdata->numunspents ) { if ( ramchain->expanded != 0 ) @@ -1341,10 +1629,19 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain value = u->value; hdrsi = u->hdrsi; type = u->type; + ipbits = u->ipbits; + scriptpos = u->scriptpos; + scriptlen = u->scriptlen; if ( u->pkind < rdata->numpkinds ) { rmd160 = P[u->pkind].rmd160; - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type) == 0 ) + /*scriptlen = 0; + if ( u->scriptoffset != 0 || type == IGUANA_SCRIPT_76AC ) + { + scriptdata = iguana_ramchain_scriptdecode(&metalen,&scriptlen,Kspace,type,_script,u->scriptoffset,P[u->pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[u->pkind].pubkeyoffset : 0); + }*/ + //fprintf(stderr,"iter add %p[%d] type.%d\n",scriptdata,scriptlen,type); + if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,ipbits,scriptpos,scriptlen) == 0 ) return(-3); } } @@ -1353,15 +1650,33 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain hdrsi = rdata->hdrsi; value = U[ramchain->H.unspentind].value; rmd160 = U[ramchain->H.unspentind].rmd160; - type = U[ramchain->H.unspentind].type; - if ( iguana_ramchain_addunspent20(coin,RAMCHAIN_ARG,value,rmd160,-20,tx->txid,j,type) == 0 ) + type = U[ramchain->H.unspentind].type & 0xf; + ipbits = U[ramchain->H.unspentind].ipbits; + scriptpos = U[ramchain->H.unspentind].scriptpos; + scriptlen = U[ramchain->H.unspentind].scriptlen; + /*if ( U[ramchain->H.unspentind].scriptoffset != 0 ) + { + scriptdata = &Kspace[U[ramchain->H.unspentind].scriptoffset]; + scriptlen = U[ramchain->H.unspentind].scriptlen; + } + if ( 0 && scriptdata != 0 && scriptlen > 0 ) + { + int32_t i; for (i=0; iH.unspentind,U[ramchain->H.unspentind].scriptoffset); + } //else printf("no script\n");*/ + //for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //printf(" raw rmd160\n"); + if ( iguana_ramchain_addunspent20(coin,0,RAMCHAIN_ARG,value,0,scriptlen,tx->txid,j,type,bp,rmd160) == 0 ) return(-4); } if ( dest != 0 ) { - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type) == 0 ) + //fprintf(stderr,"dest add %p[%d] type.%d offset.%d vs %d\n",scriptdata,scriptlen,type,dest->H.scriptoffset,dest->H.data->scriptspace); + if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type,ipbits,scriptpos,scriptlen) == 0 ) return(-5); - } + } //else printf("addunspent20 done\n"); } else return(-6); } ramchain->H.spendind += tx->numvins; @@ -1369,32 +1684,38 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain { dest->H.txidind++; dest->H.spendind += tx->numvins; - } + } //else printf("iter scriptoffset.%u/%u stacksize.%u/%u\n",ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); } if ( dest != 0 ) { dest->H.txidind = desttxidind; dest->H.spendind = destspendind; - } + } //else printf("Start VINs\n"); ramchain->H.txidind = ramchain->H.spendind = rdata->firsti; for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { tx = &T[ramchain->H.txidind]; for (j=0; jnumvins; j++) { + ipbits = 0; + scriptpos = 0; + scriptlen = 0; if ( ramchain->expanded != 0 ) { - sequence = (Sx[ramchain->H.spendind].diffsequence == 0) ? 0xffffffff : 0; + ipbits = Sx[ramchain->H.spendind].ipbits; + scriptpos = Sx[ramchain->H.spendind].scriptpos; + scriptlen = Sx[ramchain->H.spendind].scriptlen; + //scriptlen = iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,&Sx[ramchain->H.spendind]); + //scriptdata = _script; prevout = iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); - //bundlei = Sx[ramchain->H.spendind].bundlei; - //hdrsi = Sx[ramchain->H.spendind].hdrsi; - if ( iguana_ramchain_addspend(coin,RAMCHAIN_ARG,prevhash,prevout,sequence) == 0 ) + //fprintf(stderr,"from expanded iter\n"); + if ( iguana_ramchain_addspend(coin,RAMCHAIN_ARG,prevhash,prevout,Sx[ramchain->H.spendind].sequenceid,bp->hdrsi,ipbits,scriptpos,scriptlen) == 0 ) { - char str[65]; int32_t i; - printf("txidind.%d spendind.%d spendtxid.%x %d vin.%d %s vout.%d\n",ramchain->H.txidind,ramchain->H.spendind,Sx[ramchain->H.spendind].spendtxidind,Sx[ramchain->H.spendind].spendtxidind&0xfffffff,j,bits256_str(str,prevhash),prevout); - for (i=0; iH.data->numexternaltxids; i++) - printf("%p X[%d] %s\n",X,i,bits256_str(str,X[i])); - exit(-1); + char str[65]; + printf("hdrsi.%d txidind.%d spendind.%d spendtxid.%x %d vin.%d %s vout.%d\n",bp->bundleheight,ramchain->H.txidind,ramchain->H.spendind,Sx[ramchain->H.spendind].spendtxidind,Sx[ramchain->H.spendind].spendtxidind&0xfffffff,j,bits256_str(str,prevhash),prevout); + //for (i=0; iH.data->numexternaltxids; i++) + // printf("%p X[%d] %s\n",X,i,bits256_str(str,X[i])); + //exit(-1); iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); return(-7); } @@ -1402,18 +1723,31 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain else { //spendind = (tx->firstvin + j); - sequence = (S[ramchain->H.spendind].diffsequence == 0) ? 0xffffffff : 0; + sequenceid = S[ramchain->H.spendind].sequenceid; prevhash = S[ramchain->H.spendind].prevhash2; prevout = S[ramchain->H.spendind].prevout; - //bundlei = S[ramchain->H.spendind].bundlei; - //hdrsi = S[ramchain->H.spendind].hdrsi; - if ( iguana_ramchain_addspend256(coin,RAMCHAIN_ARG,prevhash,prevout,0,0,sequence) == 0 ) + ipbits = S[ramchain->H.spendind].ipbits; + scriptpos = S[ramchain->H.spendind].scriptpos; + scriptlen = S[ramchain->H.spendind].vinscriptlen; + /*if ( S[ramchain->H.spendind].scriptoffset != 0 ) + { + scriptdata = &Kspace[S[ramchain->H.spendind].scriptoffset]; + scriptlen = S[ramchain->H.spendind].vinscriptlen; + }*/ + /*if ( scriptdata != 0 && scriptlen > 0 ) + { + int32_t i; for (i=0; iH.spendind); + }*/ + if ( iguana_ramchain_addspend256(coin,0,RAMCHAIN_ARG,prevhash,prevout,0,scriptlen,sequenceid,bp) == 0 ) return(-8); } if ( dest != 0 ) { - if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequence) == 0 ) + if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequenceid,bp->hdrsi,ipbits,scriptpos,scriptlen) == 0 ) return(-9); + //printf("from dest iter scriptspace.%d\n",dest->H.stacksize); } } if ( dest != 0 ) @@ -1422,118 +1756,208 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain return(0); } +bits256 iguana_merkle(struct iguana_info *coin,bits256 *tree,struct iguana_msgtx *txarray,int32_t txn_count) +{ + int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; + if ( txn_count == 1 ) + return(txarray[0].txid); + for (i=0; i 1 ) + { + if ( (txn_count & 1) != 0 ) + tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++; + n += txn_count; + for (i=0; i> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized)); + } + prev = n; + txn_count >>= 1; + } + return(tree[n]); +} + long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen) { - int32_t verifyflag = 0; - RAMCHAIN_DECLARE; long fsize; void *ptr; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain; - struct iguana_msgtx *tx; int32_t i,j,fpos,firsti=1,err,flag,bundlei = -2; char fname[1024]; - struct iguana_bundle *bp = 0; struct iguana_block *block; + int32_t verifyflag = 0; static uint64_t totalrecv; + RAMCHAIN_DECLARE; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain; + struct iguana_msgtx *tx; char fname[1024]; uint8_t rmd160[20]; long fsize; void *ptr; + int32_t i,j,fpos,pubkeysize,msize,sigsize,firsti=1,err,flag,bundlei = -2; bits256 merkle_root; + struct iguana_bundle *bp = 0; struct iguana_block *block; uint32_t scriptspace,stackspace; + totalrecv += recvlen; + if ( bits256_nonz(origtxdata->block.RO.merkle_root) == 0 ) + { + memset(&origtxdata->block.RO.prev_block,0,sizeof(bits256)); + origtxdata->block.RO.recvlen = 0; + origtxdata->block.issued = 0; + return(-1); + } + for (i=0; idirty)/sizeof(*addr->dirty); i++) + addr->dirty[i] = 0; + msize = (int32_t)sizeof(bits256) * (txn_count+1) * 2; + if ( msize <= addr->TXDATA.totalsize ) + { + iguana_memreset(&addr->TXDATA); + merkle_root = iguana_merkle(coin,addr->TXDATA.ptr,txarray,txn_count); + if ( bits256_cmp(merkle_root,origtxdata->block.RO.merkle_root) != 0 ) + { + char str[65],str2[65]; + printf(">>>>>>>>>> merkle mismatch.[%d] calc.(%s) vs (%s)\n",txn_count,bits256_str(str,merkle_root),bits256_str(str2,origtxdata->block.RO.merkle_root)); + origtxdata->block.RO.recvlen = 0; + origtxdata->block.issued = 0; + return(-1); + } //else printf("matched merkle.%d\n",txn_count); + } else printf("not enough memory for merkle verify %ld vs %lu\n",sizeof(bits256)*(txn_count+1),(long)addr->TXDATA.totalsize); if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2) == 0 ) { if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.prev_block) == 0 ) + { + origtxdata->block.RO.recvlen = 0; + origtxdata->block.issued = 0; return(-1); + } else if ( bundlei < coin->chain->bundlesize-1 ) bundlei++; else { - printf("error finding block\n"); + origtxdata->block.issued = 0; + origtxdata->block.RO.recvlen = 0; + printf("ramchain data: error finding block\n"); return(-1); } } - if ( bits256_nonz(bp->hashes[bundlei]) == 0 ) - bp->hashes[bundlei] = origtxdata->block.RO.hash2; - if ( (block= bp->blocks[bundlei]) == 0 ) + if ( (block= bp->blocks[bundlei]) == 0 || bits256_cmp(block->RO.hash2,origtxdata->block.RO.hash2) != 0 || bits256_cmp(bp->hashes[bundlei],origtxdata->block.RO.hash2) != 0 ) { - //char str[65]; printf("%d:%d has no block ptr %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei])); + char str[65]; + if ( block != 0 ) + printf("%d:%d has no block ptr.%p %s or wrong hash\n",bp->hdrsi,bundlei,block,bits256_str(str,origtxdata->block.RO.hash2)); return(-1); } - if ( block->fpipbits != 0 ) + block->txvalid = 1; + if ( block->fpipbits != 0 && block->fpos >= 0 ) { - //printf("ramchaindata have %d:%d at %d\n",bp->hdrsi,bundlei,bp->fpos[bundlei]); + static int32_t numredundant; static double redundantsize; static uint32_t lastdisp; + char str[65],str2[65]; + numredundant++, redundantsize += recvlen; + if ( time(NULL) > lastdisp+30 ) + { + lastdisp = (uint32_t)time(NULL); + printf("ramchaindata have %d:%d at %ld | %d blocks %s redundant xfers total %s %.2f%% wasted\n",bp->hdrsi,bundlei,block->fpos,numredundant,mbstr(str,redundantsize),mbstr(str2,totalrecv),100.*redundantsize/totalrecv); + } return(block->fpos); } - //SETBIT(bp->recv,bundlei); - fpos = -1; - //bp->recvlens[bundlei] = recvlen; - //bp->firsttxidinds[bundlei] = firsti; - if ( iguana_ramchain_init(ramchain,&addr->TXDATA,&addr->HASHMEM,1,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0,0,1) == 0 ) + sigsize = pubkeysize = 0; + scriptspace = 1;//iguana_scriptspaceraw(coin,&scriptsize,&sigsize,&pubkeysize,txarray,txn_count); + if ( iguana_ramchain_init(ramchain,&addr->TXDATA,&addr->HASHMEM,1,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0,(scriptspace+sigsize+pubkeysize)*1.1,0,1) == 0 ) + { + if ( block->fpipbits == 0 ) + block->issued = block->RO.recvlen = 0, block->fpos = -1; return(-1); - iguana_ramchain_link(ramchain,origtxdata->block.RO.hash2,origtxdata->block.RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,0); + } + block->fpos = fpos = -1; + iguana_ramchain_link(ramchain,block->RO.hash2,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,0); _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( T == 0 || U == 0 || S == 0 || B == 0 )// P == 0//|| X == 0 || A == 0 || U2 == 0 || P2 == 0 ) + //printf("Kspace.%p bp.[%d:%d] <- scriptspace.%d expanded.%d\n",Kspace,bp->hdrsi,bundlei,scriptspace,ramchain->expanded); + if ( T == 0 || U == 0 || S == 0 || B == 0 ) { - printf("fatal error getting txdataptrs\n"); + block->issued = 0; + block->RO.recvlen = 0; + printf("fatal error getting txdataptrs %p %p %p %p\n",T,U,S,B); return(-1); } + block->fpipbits = 1; for (i=0; iH.txidind++) { tx = &txarray[i]; iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp); for (j=0; jtx_out; j++) { - iguana_ramchain_addunspent20(coin,RAMCHAIN_ARG,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,0); + memset(rmd160,0,sizeof(rmd160)); + iguana_ramchain_addunspent20(coin,addr,RAMCHAIN_ARG,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,-1,bp,rmd160); } ramchain->H.spendind += tx->tx_in; } + //printf("scriptoffset.%d after %d txids\n",ramchain->H.scriptoffset,txn_count); ramchain->H.txidind = ramchain->H.spendind = ramchain->H.data->firsti; for (i=0; iH.txidind++) { tx = &txarray[i]; for (j=0; jtx_in; j++) { - //char str[65]; printf("PT vin.%d %s vout.%d\n",j,bits256_str(str,tx->vins[j].prev_hash),tx->vins[j].prev_vout); - iguana_ramchain_addspend256(coin,RAMCHAIN_ARG,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].sigscript,tx->vins[j].scriptlen,tx->vins[j].sequence);//,bp->hdrsi,bundlei); + iguana_ramchain_addspend256(coin,addr,RAMCHAIN_ARG,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->vins[j].sequence,bp);//,bp->hdrsi,bundlei); } } - //char str[65]; printf("before height.%d num.%d:%d T.%d U.%d S.%d P.%d X.%d %s\n",ramchain->height,ramchain->numblocks,ramchain->H.data->numblocks,ramchain->H.txidind,ramchain->H.unspentind,ramchain->H.spendind,ramchain->pkind,ramchain->externalind,bits256_str(str,ramchain->H.data->firsthash2)); + ramchain->H.data->scriptspace = scriptspace = ramchain->H.scriptoffset; + ramchain->H.data->stackspace = stackspace = ramchain->H.stacksize; iguana_ramchain_setsize(ramchain,ramchain->H.data,1); flag = 0; if ( ramchain->H.txidind != ramchain->H.data->numtxids || ramchain->H.unspentind != ramchain->H.data->numunspents || ramchain->H.spendind != ramchain->H.data->numspends ) { - printf("error creating PT ramchain: ramchain->txidind %d != %d ramchain->data->numtxids || ramchain->unspentind %d != %d ramchain->data->numunspents || ramchain->spendind %d != %d ramchain->data->numspends\n",ramchain->H.txidind,ramchain->H.data->numtxids,ramchain->H.unspentind,ramchain->H.data->numunspents,ramchain->H.spendind,ramchain->H.data->numspends); + printf("error creating PT ramchain.[%d:%d] ramchain->txidind %d != %d ramchain->data->numtxids || ramchain->unspentind %d != %d ramchain->data->numunspents || ramchain->spendind %d != %d ramchain->data->numspends space.(%d v %d)\n",bp->hdrsi,bp->bundleheight,ramchain->H.txidind,ramchain->H.data->numtxids,ramchain->H.unspentind,ramchain->H.data->numunspents,ramchain->H.spendind,ramchain->H.data->numspends,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); + block->fpipbits = 0; + block->issued = 0; + block->RO.recvlen = 0; } else { if ( (err= iguana_ramchain_verify(coin,ramchain)) == 0 ) { - B[0] = origtxdata->block.RO; - if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,(uint32_t)addr->ipbits,origtxdata->block.RO.hash2,origtxdata->block.RO.prev_block,bundlei,0)) >= 0 ) + B[0] = block->RO; + ramchain->H.data->scriptspace = ramchain->H.scriptoffset = scriptspace; + ramchain->H.data->stackspace = ramchain->H.stacksize = stackspace; + if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,(uint32_t)addr->ipbits,block->RO.hash2,block->RO.prev_block,bundlei,0)) >= 0 ) { - //printf("set fpos.%d\n",fpos); - //bp->ipbits[bundlei] = addr->ipbits; + //char str[65]; printf("saved.%s [%d:%d]\n",bits256_str(str,block->RO.hash2),bp->hdrsi,bundlei); origtxdata->datalen = (int32_t)ramchain->H.data->allocsize; ramchain->H.ROflag = 0; flag = 1; + if ( 1 ) + { + if ( addr->dirty[0] != 0 && addr->voutsfp != 0 ) + fflush(addr->voutsfp); + if ( addr->dirty[1] != 0 && addr->vinsfp != 0 ) + fflush(addr->vinsfp); + } memset(&R,0,sizeof(R)); - if ( verifyflag != 0 && (mapchain= iguana_ramchain_map(coin,fname,0,1,&R,0,(uint32_t)addr->ipbits,origtxdata->block.RO.hash2,origtxdata->block.RO.prev_block,bundlei,fpos,1,0)) != 0 ) + if ( verifyflag != 0 && (mapchain= iguana_ramchain_map(coin,fname,0,1,&R,0,(uint32_t)addr->ipbits,block->RO.hash2,block->RO.prev_block,bundlei,fpos,1,0)) != 0 ) { //printf("mapped Soffset.%ld\n",(long)mapchain->data->Soffset); - iguana_ramchain_link(&R,origtxdata->block.RO.hash2,origtxdata->block.RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - if ( 0 ) // crashes unix + iguana_ramchain_link(&R,block->RO.hash2,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + if ( 1 ) // unix issues? { if ( (err= iguana_ramchain_cmp(ramchain,mapchain,0)) != 0 ) - printf("error.%d comparing ramchains\n",err); - ptr = mapchain->fileptr; fsize = mapchain->filesize; - mapchain->fileptr = 0, mapchain->filesize = 0; - iguana_ramchain_free(mapchain,1); - memset(&R,0,sizeof(R)); - R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; - iguana_ramchain_link(&R,origtxdata->block.RO.hash2,origtxdata->block.RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + fpos = -1, printf("error.%d comparing ramchains\n",err); + else + { + ptr = mapchain->fileptr; fsize = mapchain->filesize; + mapchain->fileptr = 0, mapchain->filesize = 0; + iguana_ramchain_free(mapchain,1); + memset(&R,0,sizeof(R)); + R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; + iguana_ramchain_link(&R,block->RO.hash2,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + } } if ( (err= iguana_ramchain_cmp(ramchain,&R,0)) != 0 ) { fpos = -1; + block->issued = 0; + block->RO.recvlen = 0; printf("error.%d comparing REMAP ramchains\n",err); } else { - iguana_ramchain_extras(&R,0); - if ( (err= iguana_ramchain_iterate(coin,0,&R)) != 0 ) + iguana_ramchain_extras(coin,&R,0,0); + if ( (err= iguana_ramchain_iterate(coin,0,&R,bp)) != 0 ) printf("err.%d iterate ",err); //printf("SUCCESS REMAP\n"); bp->numtxids += ramchain->H.data->numtxids; bp->numunspents += ramchain->H.data->numunspents; bp->numspends += ramchain->H.data->numspends; + bp->rawscriptspace += ramchain->H.data->scriptspace; } iguana_ramchain_free(&R,1); } @@ -1542,12 +1966,16 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru bp->numtxids += ramchain->H.data->numtxids; bp->numunspents += ramchain->H.data->numunspents; bp->numspends += ramchain->H.data->numspends; + bp->rawscriptspace += ramchain->H.data->scriptspace; } if ( fpos >= 0 ) block->fpos = fpos, block->fpipbits = (uint32_t)addr->ipbits; } } else printf("ramchain verification error.%d hdrsi.%d bundlei.%d\n",err,bp->hdrsi,bundlei); } + if ( fpos < 0 ) + block->fpos = -1, block->fpipbits = block->RO.recvlen = 0; + //fprintf(stderr,"finished with hdrsi.%d ht.%d scripts.%u:%u\n",bp->hdrsi,bp->bundleheight,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); ramchain->H.ROflag = 0; iguana_ramchain_free(ramchain,0); return(fpos); @@ -1577,7 +2005,7 @@ void iguana_ramchain_disp(struct iguana_ramchain *ramchain) } } -int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp) +int32_t iguana_oldbundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp) { static bits256 zero; int32_t j,bundlei,num,hdrsi,checki; struct iguana_block *block; uint32_t fpipbits; char fname[1024]; @@ -1589,6 +2017,7 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs { block->queued = 0; block->fpipbits = 0; + block->issued = 0; bp->issued[bundlei] = 0; return(0); } @@ -1601,14 +2030,14 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs if ( j == num ) { ipbits[num] = fpipbits; - if ( (checki= iguana_peerfname(coin,&hdrsi,"tmp",fname,fpipbits,bp->hashes[bundlei],bundlei>0?bp->hashes[bundlei-1]:zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,fpipbits,bp->hashes[bundlei],zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) { printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); return(0); } if ( (ptrs[num]= OS_mapfile(fname,&filesizes[num],0)) == 0 ) { - printf("error mapping bundlei.%d\n",bundlei); + printf("error mapping bundlei.%d (%s)\n",bundlei,fname); block->queued = 0; block->fpipbits = 0; bp->issued[bundlei] = 0; @@ -1621,9 +2050,30 @@ int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs return(num); } -void iguana_bundlemapfree(struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t *ipbits,void **ptrs,long *filesizes,int32_t num,struct iguana_ramchain *R,int32_t n) +int32_t iguana_bundlefiles(struct iguana_info *coin,uint32_t *ipbits,void **ptrs,long *filesizes,struct iguana_bundle *bp,int32_t starti,int32_t endi) { - int32_t j; + int32_t bundlei,checki,hdrsi,num = 0; char fname[1024]; static bits256 zero; + for (bundlei=starti; bundlei<=endi; bundlei++) + { + if ( (checki= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,0,bp->hashes[bundlei],zero,1)) != bundlei || bundlei < 0 || bundlei >= coin->chain->bundlesize ) + { + printf("B iguana_ramchain_map.(%s) illegal hdrsi.%d bundlei.%d checki.%d\n",fname,hdrsi,bundlei,checki); + return(0); + } + if ( (ptrs[num]= OS_mapfile(fname,&filesizes[num],0)) == 0 ) + { + printf("error mapping.(%s) bundlei.%d\n",fname,bundlei); + return(0); + } + //printf("%s mapped ptrs[%d] filesize.%ld bundlei.%d ipbits.%x fpos.%d\n",fname,num,(long)filesizes[num],bundlei,fpipbits,bp->fpos[bundlei]); + num++; + } + return(num); +} + +void iguana_bundlemapfree(struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t *ipbits,void **ptrs,long *filesizes,int32_t num,struct iguana_ramchain *R,int32_t starti,int32_t endi) +{ + int32_t j,n = (endi - starti + 1); for (j=0; jH.data->firsthash2, lasthash2 = ramchain->H.data->lasthash2; height = ramchain->height, firsti = ramchain->H.data->firsti, hdrsi = ramchain->H.hdrsi, numblocks = ramchain->numblocks; - //printf("B[] %p\n",B); - //printf("Apresave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti); + destoffset = &Kspace[ramchain->H.scriptoffset]; + srcoffset = &Kspace[ramchain->H.data->scriptspace - ramchain->H.stacksize]; + if ( ramchain->expanded != 0 ) + { + if ( (long)destoffset > (long)srcoffset ) + printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); + } + printf("%d SAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d gap.%ld RO.%d\n",bp->bundleheight,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize,(long)destoffset - (long)srcoffset,ramchain->H.ROflag); + scriptspace = ramchain->H.data->scriptspace; + scriptoffset = ramchain->H.scriptoffset; + stacksize = ramchain->H.stacksize; + //ramchain->H.scriptoffset = scriptoffset; + ramchain->H.data->scriptspace = scriptoffset; + ramchain->H.stacksize = ramchain->H.data->stackspace = stacksize; iguana_ramchain_setsize(ramchain,ramchain->H.data,bp->n); + //printf("Apresave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scriptoffset.%d stacksize.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,ramchain->H.scriptoffset,ramchain->H.stacksize); *newchain = *ramchain; //memcpy(ramchain->roU2,ramchain->U2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); //memcpy(ramchain->roP2,ramchain->P2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); - memcpy(ramchain->roA,ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + memcpy(ramchain->creditsA,ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); memset(ramchain->A,0,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); //printf("presave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti); - if ( (err= iguana_ramchain_iterate(coin,0,ramchain)) != 0 ) + //printf("0 preSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize); + if ( (err= iguana_ramchain_iterate(coin,0,ramchain,bp)) != 0 ) printf("ERROR.%d iterating presave ramchain hdrsi.%d\n",err,hdrsi); - else if ( (err= iguana_ramchain_verify(coin,ramchain)) != 0 ) - printf("ERROR.%d verifying presave ramchain hdrsi.%d\n",err,hdrsi); - else retval = 0; - printf("postiterateA T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti); + else + { + //printf("postiterate0.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scripts.%d:%d stack.%d:%d\n",bp->bundleheight,ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,(int32_t)ramchain->H.scriptoffset,scriptoffset,(int32_t)ramchain->H.stacksize,stacksize); + if ( ramchain->H.scriptoffset > scriptoffset || ramchain->H.stacksize > stacksize ) + printf("MEMORY OVERFLOW\n"); + if ( (err= iguana_ramchain_verify(coin,ramchain)) != 0 ) + printf("ERROR.%d verifying presave ramchain hdrsi.%d\n",err,hdrsi); + else retval = 0; + } + //printf("postiterateA.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scripts.%d:%d stack.%d:%d\n",bp->bundleheight,ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,(int32_t)ramchain->H.scriptoffset,scriptoffset,(int32_t)ramchain->H.stacksize,stacksize); + ramchain->H.scriptoffset = scriptoffset; + ramchain->H.data->scriptspace = scriptoffset; + ramchain->H.stacksize = ramchain->H.data->stackspace = stacksize; if ( iguana_ramchain_save(coin,RAMCHAIN_ARG,0,firsthash2,zero,0,bp) < 0 ) printf("ERROR saving ramchain hdrsi.%d\n",hdrsi); else @@ -1679,15 +2153,17 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru //printf("DEST T.%d U.%d S.%d P.%d X.%d -> size.%ld Xoffset.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,(int32_t)ramchain->H.data->Xoffset); //printf("free dest hdrs.%d retval.%d\n",bp->hdrsi,retval); memset(&checkR,0,sizeof(checkR)); + checkR.sigsfileptr = ramchain->sigsfileptr; + checkR.sigsfilesize = ramchain->sigsfilesize; bundlei = 0; if ( cmpflag == 0 ) iguana_memreset(hashmem); - if ( (mapchain= iguana_ramchain_map(coin,fname,bp,numblocks,&checkR,cmpflag==0?hashmem:0,0,firsthash2,zero,bundlei,0,1,1)) != 0 ) + if ( (mapchain= iguana_ramchain_map(coin,fname,bp,numblocks,&checkR,cmpflag==0?hashmem:0,0,firsthash2,zero,bundlei,0,0,1)) != 0 ) { iguana_ramchain_link(mapchain,firsthash2,lasthash2,hdrsi,height,0,numblocks,firsti,1); - iguana_ramchain_extras(mapchain,hashmem); - //printf("MAP T.%d U.%d S.%d P.%d X.%d -> size.%ld Xoffset.%d\n",mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,(long)mapchain->H.data->allocsize,(int32_t)mapchain->H.data->Xoffset); - if ( (err= iguana_ramchain_iterate(coin,0,mapchain)) != 0 ) + iguana_ramchain_extras(coin,mapchain,hashmem,0); + //printf("expSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)mapchain->H.data->Koffset,mapchain->H.scriptoffset,mapchain->H.stacksize,(int32_t)mapchain->H.data->allocsize); + if ( (err= iguana_ramchain_iterate(coin,0,mapchain,bp)) != 0 ) printf("err.%d iterate mapped dest\n",err); else if ( cmpflag != 0 ) { @@ -1701,7 +2177,7 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru } int32_t i; for (i=0; iH.data->lhashes[i].uints[0]); - printf("%llx ht.%d\n",(long long)mapchain->H.data->sha256.txid,mapchain->height); + printf("%llx ht.%d bundlehashes\n",(long long)mapchain->H.data->sha256.txid,mapchain->height); iguana_ramchain_free(mapchain,cmpflag); } iguana_mempurge(hashmem); @@ -1709,17 +2185,17 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru return(retval); } -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_bundle *bp) +struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag) { static bits256 zero; struct iguana_blockRO *B; struct iguana_txid *T; int32_t i,firsti = 1; char fname[512]; struct iguana_block *block; struct iguana_ramchain *mapchain; - memset(&bp->ramchain,0,sizeof(bp->ramchain)); - if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,&bp->ramchain,0,0,bp->hashes[0],zero,0,0,0,1)) != 0 ) + memset(ramchain,0,sizeof(*ramchain)); + if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,extraflag,1)) != 0 ) { - iguana_ramchain_link(mapchain,bp->hashes[0],bp->ramchain.lasthash2,bp->hdrsi,bp->bundleheight,0,bp->ramchain.numblocks,firsti,1); - //char str[65]; printf("bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",bp->hdrsi,bp->ramchain.H.data->numtxids,bp->ramchain.H.data->numunspents,bp->ramchain.H.data->numspends,bp->ramchain.H.data->numpkinds,bp->ramchain.H.data->numexternaltxids,mbstr(str,bp->ramchain.H.data->allocsize),bp->ramchain.H.data); - //ramcoder_test(bp->ramchain.H.data,bp->ramchain.H.data->allocsize); + iguana_ramchain_link(mapchain,bp->hashes[0],bp->hashes[bp->n-1],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,1); + //char str[65]; printf("bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",bp->hdrsi,mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,mbstr(str,mapchain->H.data->allocsize),mapchain->H.data); + //ramcoder_test(mapchain->H.data,mapchain->H.data->allocsize); B = (void *)(long)((long)mapchain->H.data + mapchain->H.data->Boffset); T = (void *)(long)((long)mapchain->H.data + mapchain->H.data->Toffset); for (i=0; in; i++) @@ -1744,8 +2220,10 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana } } } - //printf("bundle.%d\n",bp->bundleheight); + //printf("mapped bundle.%d\n",bp->bundleheight); bp->emitfinish = (uint32_t)time(NULL) + 1; + iguana_bundlecalcs(coin,bp); + /*for (i=1; iH.data->numtxids; i++) {break; if ( iguana_txidfind(coin,&height,&tx,T[i].txid) == 0 ) @@ -1754,6 +2232,11 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana printf("compare error T[%d] %s\n",i,bits256_str(str,T[i].txid)); }*/ } + else + { + //printf("couldnt load bundle.%d\n",bp->bundleheight); + memset(&bp->ramchain,0,sizeof(bp->ramchain)); + } if ( mapchain != 0 ) coin->newramchain++; return(mapchain); @@ -1765,26 +2248,32 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str static int depth; static bits256 zero; RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; void **ptrs,*ptr; long *filesizes,filesize; uint32_t *ipbits; char fname[1024]; - struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits,now = (uint32_t)time(NULL); - int32_t i,numtxids,valid,numunspents,numspends,numpkinds,numexternaltxids,fpos; struct iguana_block *block; + struct iguana_ramchain *R,*mapchain,*dest,newchain; uint32_t fpipbits; + int32_t i,starti,endi,bp_n,numtxids,valid,sigspace,pubkeyspace,numunspents,numspends,numpkinds,numexternaltxids,scriptspace; struct iguana_block *block; long fpos; struct OS_memspace HASHMEM; int32_t err,j,num,hdrsi,bundlei,firsti= 1,retval = -1; - B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, TXbits = 0, PKbits = 0, U = 0, S = 0, T = 0;//U2 = 0, P2 = 0, + memset(&HASHMEM,0,sizeof(HASHMEM)); + starti = 0, endi = bp->n - 1; + bp_n = (endi - starti + 1); + B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; R = mycalloc('s',bp->n,sizeof(*R)); ptrs = mycalloc('w',bp->n,sizeof(*ptrs)); ipbits = mycalloc('w',bp->n,sizeof(*ipbits)); filesizes = mycalloc('f',bp->n,sizeof(*filesizes)); - if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp)) == 0 ) + if ( (num= iguana_bundlefiles(coin,ipbits,ptrs,filesizes,bp,starti,endi)) == 0 ) { - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,bp->n,R,bp->n); + iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + printf("iguana_bundlesaveHT: no bundlefiles error\n"); return(-1); } - for (bundlei=numtxids=numunspents=numspends=0; bundlein; bundlei++) + scriptspace = 1; + sigspace = pubkeyspace = 0; + for (bundlei=starti,numtxids=numunspents=numspends=scriptspace=0; bundlei<=endi; bundlei++) { if ( (block= bp->blocks[bundlei]) != 0 ) fpipbits = block->fpipbits, fpos = block->fpos; else fpipbits = fpos = 0; mapchain = &R[bundlei]; - for (j=0; jfileptr = ptr; mapchain->filesize = filesize; mapchain->H.data = (void *)(long)((long)ptr + fpos); mapchain->H.ROflag = 1; - if ( fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(MAPCHAIN_ARG,1) != mapchain->H.data->allocsize ) + if ( fpos > filesize ) + { + iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); + printf("fpos error %ld > %ld mapping hdrsi.%d bundlei.%d\n",fpos,filesize,bp->hdrsi,bundlei); + break; + } + if ( fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace) != mapchain->H.data->allocsize ) { - printf("iguana_bundlesaveHT ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d\n",fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1),(long)mapchain->H.data->allocsize,(long)filesize,(long)fpos,bundlei,mapchain->expanded); + printf("iguana_bundlesaveHT.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,fpipbits,(long)iguana_ramchain_size(MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); //getchar(); break; } else if ( memcmp(bp->hashes[bundlei].bytes,mapchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) { - char str[65],str2[65]; printf("iguana_bundlesaveHT hash2 mismatch %s vs %s\n",bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,mapchain->H.data->firsthash2)); + char str[65],str2[65]; printf("iguana_bundlesaveHT.[%d:%d] hash2 mismatch %s vs %s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,mapchain->H.data->firsthash2)); break; } iguana_ramchain_link(mapchain,bp->hashes[bundlei],bp->hashes[bundlei],bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); numtxids += (mapchain->H.data->numtxids - 1); numunspents += (mapchain->H.data->numunspents - 1); numspends += (mapchain->H.data->numspends - 1); + scriptspace += 1;//iguana_ramchain_scriptspace(coin,&sigsize,&pubkeysize,mapchain); + //sigspace += sigsize; + //pubkeyspace += pubkeysize; if ( (block= bp->blocks[bundlei]) == 0 || bits256_nonz(block->RO.hash2) == 0 || block != iguana_blockfind(coin,block->RO.hash2) || memcmp(block->RO.hash2.bytes,bp->hashes[bundlei].bytes,sizeof(bits256)) != 0 ) { printf("block.%p error vs %p\n",block,iguana_blockfind(coin,block->RO.hash2)); break; } //printf("%x ",(uint32_t)block->RO.hash2.ulongs[3]); - //printf("(%d %d %d) ",numtxids,numunspents,numspends); + if ( bp->blocks[bundlei]->RO.txn_count == 0 ) + bp->blocks[bundlei]->RO.txn_count = mapchain->H.data->numtxids - 1; + //printf("(%d %d).%d ",mapchain->H.data->numtxids,bp->blocks[bundlei]->RO.txn_count,numtxids); //printf("%d ",numtxids); } - //printf("RObits\n"); - if ( bundlei != bp->n ) + scriptspace += pubkeyspace*1.1 + sigspace*1.1; + //printf("mem.%p mapchain txid tables, scriptspace.%u sigspace.%u pubkeyspace.%u bundlei.%d/%d\n",mem,scriptspace,sigspace,pubkeyspace,bundlei,bp->n); + if ( bundlei != endi+1 ) { - iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,bp->n); + if ( (block= bp->blocks[bundlei]) != 0 ) + { + block->fpipbits = 0; + block->queued = 0; + block->issued = 0; + block->RO.recvlen = 0; + bp->issued[bundlei] = 0; + } + iguana_bundlemapfree(0,0,ipbits,ptrs,filesizes,num,R,starti,endi); printf("error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); return(-1); } - //printf("-> total (%d %d %d)\n",numtxids,numunspents,numspends); + dest = &bp->ramchain; + printf("iguana_bundlesaveHT.%d -> total (%d %d %d) scriptspace.%d (pubkeys.%d sigs.%d) dest->txids %p\n",bp->bundleheight,numtxids,numunspents,numspends,scriptspace,pubkeyspace,sigspace,dest->txids); + dest->txids = dest->pkhashes = 0; numpkinds = numunspents; numexternaltxids = numspends; - dest = &bp->ramchain; //printf("E.%d depth.%d start bundle ramchain %d at %u started.%u lag.%d\n",coin->numemitted,depth,bp->bundleheight,now,starttime,now-starttime); depth++; - if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,bp->bundleheight,bp->n) < 0 ) + if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace+sigspace,bp->bundleheight+starti,bp_n) < 0 ) { - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,bp->n); + printf("error iguana_ramchain_alloc for bundleheight.%d\n",bp->bundleheight); + iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); return(-1); } - iguana_ramchain_link(dest,bp->hashes[0],bp->hashes[bp->n-1],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,0); + iguana_ramchain_link(dest,bp->hashes[starti],bp->hashes[endi],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,0); + dest->expanded = 1; + dest->H.scriptoffset = 1; _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(dest,&HASHMEM); - for (i=0; in; i++) + iguana_ramchain_extras(coin,dest,&HASHMEM,0); + for (i=starti; i<=endi; i++) { if ( (block= bp->blocks[i]) != 0 && block == iguana_blockfind(coin,bp->hashes[i]) ) { - //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); - if ( iguana_blockvalidate(coin,&valid,block,1) != 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) ) + if ( bits256_nonz(block->RO.prev_block) == 0 && i > 0 ) + block->RO.prev_block = bp->hashes[i-1]; + if ( (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) { char str[65]; printf("null prevblock error at ht.%d patch.(%s)\n",bp->bundleheight+i,bits256_str(str,bp->hashes[i-1])); block->queued = 0; block->fpipbits = 0; bp->issued[i] = 0; + block->issued = 0; + iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); return(-1); } - destB[i] = block->RO; + //destB[i] = block->RO; } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i])); } dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; - dest->externalind = 0; - //printf("\n"); - for (bundlei=0; bundlein; bundlei++) + dest->externalind = dest->H.stacksize = 0; + dest->H.scriptoffset = 1; + for (bundlei=starti; bundlei<=endi; bundlei++) { if ( (block= bp->blocks[bundlei]) != 0 ) { iguana_blocksetcounters(coin,block,dest); coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; destB[bundlei] = block->RO; - //printf("(%d %d) ",R[bundlei].H.data->numtxids,dest->H.txidind); - if ( (err= iguana_ramchain_iterate(coin,dest,&R[bundlei])) != 0 ) + //fprintf(stderr,"(%d %d).%d ",R[bundlei].H.data->numtxids,dest->H.txidind,bundlei); + if ( (err= iguana_ramchain_iterate(coin,dest,&R[bundlei],bp)) != 0 ) { + if ( (block= bp->blocks[bundlei]) != 0 ) + { + block->queued = 0; + block->fpipbits = 0; + bp->issued[bundlei] = 0; + block->issued = 0; + } printf("error ramchain_iterate hdrs.%d bundlei.%d\n",bp->hdrsi,bundlei); break; } @@ -1884,34 +2410,40 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str break; } } + if ( dest->H.scriptoffset > dest->H.data->scriptspace ) + { + printf("bundlesave: stack smashed %d+%d > %d\n",dest->H.scriptoffset,dest->H.stacksize,dest->H.data->scriptspace); + bundlei = -1; + } + //printf(" about to save dest scriptoffset.%d stacksize.%d data scriptspace.%d\n",dest->H.scriptoffset,dest->H.stacksize,dest->H.data->scriptspace); depth--; - if ( bundlei == bp->n && iguana_ramchain_expandedsave(coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,bp) == 0 ) + memset(&newchain,0,sizeof(newchain)); + if ( bundlei == endi+1 && iguana_ramchain_expandedsave(coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,bp) == 0 ) { - char str[65],str2[65]; printf("%s d.%d ht.%d %s saved lag.%d elapsed.%ld\n",bits256_str(str2,newchain.H.data->sha256),depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); + //char str[65]; printf("d.%d ht.%d %s saved lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); retval = 0; - } - iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,bp->n); - if ( retval == 0 ) + } else bp->generrs++; + iguana_bundlemapfree(mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); + if ( retval == 0 )//|| bp->generrs > 3 ) { + char dirname[1024]; //printf("delete %d files hdrs.%d retval.%d\n",num,bp->hdrsi,retval); - for (j=0; jn && bp->n == coin->chain->bundlesize ) { - if ( iguana_peerfname(coin,&hdrsi,"tmp",fname,ipbits[j],bp->hashes[0],zero,1) >= 0 ) - coin->peers.numfiles -= OS_removefile(fname,0); - else printf("error removing.(%s)\n",fname); + for (j=starti; j<=endi; j++) + { + if ( iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,1,bp->hashes[j],zero,1) >= 0 ) // ipbits[j] + coin->peers.numfiles -= OS_removefile(fname,0); + else printf("error removing.(%s)\n",fname); + } + sprintf(dirname,"%s/%s/%d",GLOBALTMPDIR,coin->symbol,bp->bundleheight), OS_portable_rmdir(dirname,1); } + iguana_bundleload(coin,&newchain,bp,0); + newchain.A = 0; } iguana_ramchain_free(dest,0); bp->ramchain = newchain; - if ( 0 ) - { - bp->ramchain.hashmem = 0; - bp->ramchain.txids = 0; - bp->ramchain.pkhashes = 0; - bp->ramchain.fileptr = 0; - bp->ramchain.filesize = 0; - } - else iguana_bundleload(coin,bp); + //printf("finished bundlesave.%d\n",bp->bundleheight); return(retval); } @@ -1937,9 +2469,9 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st struct iguana_ramchain _Achain,_Bchain,*A,*B,R,newchain,*dest = &R; int32_t err,retval = -1,firsti = 1; memset(mem,0,sizeof(*mem)); memset(&HASHMEMA,0,sizeof(HASHMEMA)); - iguana_meminit(&HASHMEMA,"hashmemA",0,iguana_hashmemsize(bp->ramchain.H.txidind,bp->ramchain.H.unspentind,bp->ramchain.H.spendind,bp->ramchain.pkind,bp->ramchain.externalind) + 4096,0); + iguana_meminit(&HASHMEMA,"hashmemA",0,iguana_hashmemsize(bp->ramchain.H.txidind,bp->ramchain.H.unspentind,bp->ramchain.H.spendind,bp->ramchain.pkind,bp->ramchain.externalind,bp->ramchain.H.data->scriptspace) + IGUANA_MAXSCRIPTSIZE,0); memset(&HASHMEMB,0,sizeof(HASHMEMB)); - iguana_meminit(&HASHMEMB,"hashmemB",0,iguana_hashmemsize(nextbp->ramchain.H.txidind,nextbp->ramchain.H.unspentind,nextbp->ramchain.H.spendind,nextbp->ramchain.pkind,nextbp->ramchain.externalind) + 4096,0); + iguana_meminit(&HASHMEMB,"hashmemB",0,iguana_hashmemsize(nextbp->ramchain.H.txidind,nextbp->ramchain.H.unspentind,nextbp->ramchain.H.spendind,nextbp->ramchain.pkind,nextbp->ramchain.externalind,nextbp->ramchain.H.data->scriptspace) + IGUANA_MAXSCRIPTSIZE,0); memset(&_Achain,0,sizeof(_Achain)); A = &_Achain; memset(&_Bchain,0,sizeof(_Bchain)); B = &_Bchain; if ( (A= iguana_ramchain_map(coin,fnameA,bp,bp->ramchain.numblocks,A,&HASHMEMA,0,bp->hashes[0],zero,0,0,1,1)) != 0 ) @@ -1958,7 +2490,7 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st } if ( A->H.data != 0 && B->H.data != 0 && B->height == A->height+A->numblocks ) { - if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->height,A->numblocks + B->numblocks) < 0 ) + if ( iguana_ramchain_alloc(coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->H.data->scriptspace,A->height,A->numblocks + B->numblocks) < 0 ) { printf("depth.%d ht.%d fsize.%s ERROR alloc lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); iguana_mergefree(mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); @@ -1967,12 +2499,12 @@ int32_t iguana_bundlemergeHT(struct iguana_info *coin,struct OS_memspace *mem,st depth++; iguana_ramchain_link(dest,A->H.data->firsthash2,B->H.data->lasthash2,A->H.hdrsi,A->height,0,A->numblocks+B->numblocks,firsti,0); _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); - iguana_ramchain_extras(dest,&HASHMEM); + iguana_ramchain_extras(coin,dest,&HASHMEM,0); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = 0; - if ( (err= iguana_ramchain_iterate(coin,dest,A)) != 0 ) + if ( (err= iguana_ramchain_iterate(coin,dest,A,bp)) != 0 ) printf("error.%d ramchain_iterate A.%d\n",err,A->height); - else if ( (err= iguana_ramchain_iterate(coin,dest,B)) != 0 ) + else if ( (err= iguana_ramchain_iterate(coin,dest,B,nextbp)) != 0 ) printf("error.%d ramchain_iterate B.%d\n",err,B->height); else if ( iguana_ramchain_expandedsave(coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,0) == 0 ) { diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index 19ecbe0c4..b84613fb7 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -35,25 +35,26 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, static bits256 lastreq,lastreq2; int32_t len; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); - if ( memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) + if ( addr == 0 || memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { - //printf("duplicate req\n"); + //printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); return(0); } - lastreq2 = lastreq; - lastreq = hash2; if ( addr->msgcounts.verack == 0 ) { - printf("iguana_sendblockreq %s hasn't verack'ed yet\n",addr->ipaddr); + //printf("iguana_sendblockreq (%s) hasn't verack'ed yet\n",addr->ipaddr); return(-1); } - if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hexstr)) > 0 ) + lastreq2 = lastreq; + lastreq = hash2; + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) { iguana_send(coin,addr,serialized,len); coin->numreqsent++; addr->pendblocks++; addr->pendtime = (uint32_t)time(NULL); - //printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); + if ( 0 && coin->current == bp ) + printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); } else printf("MSG_BLOCK null datalen.%d\n",len); return(len); } @@ -61,8 +62,8 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, int32_t iguana_sendtxidreq(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2) { uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; - int32_t len,i,r,j; char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); - if ( (len= iguana_getdata(coin,serialized,MSG_TX,hexstr)) > 0 ) + int32_t len,i,r,j; //char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); + if ( (len= iguana_getdata(coin,serialized,MSG_TX,&hash2,1)) > 0 ) { if ( addr == 0 ) { @@ -107,12 +108,56 @@ void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,st req->datalen = datalen; req->txid = tx->txid; memcpy(req->serialized,data,datalen); - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } +#ifdef later +struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundleip,char *fname,struct OS_memspace *mem,uint32_t ipbits,bits256 hash2) +{ + int32_t bundlei,datalen,checki,hdrsi,fpos; char str[65],str2[65]; FILE *fp; + bits256 checkhash2; struct iguana_txblock *txdata = 0; static bits256 zero; + if ( (bundlei= iguana_peerfname(coin,&hdrsi,GLOBALTMPDIR,fname,ipbits,hash2,zero,1)) >= 0 ) + //if ( (bundlei= iguana_peerfname(coin,&hdrsi,fname,ipbits,hash2)) >= 0 ) + { + if ( (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,bundlei * sizeof(bundlei),SEEK_SET); + fread(&fpos,1,sizeof(fpos),fp); + fseek(fp,fpos,SEEK_SET); + fread(&checki,1,sizeof(checki),fp); + if ( ftell(fp)-sizeof(checki) == fpos && bundlei == checki ) + { + fread(&checkhash2,1,sizeof(checkhash2),fp); + if ( memcmp(hash2.bytes,checkhash2.bytes,sizeof(hash2)) == 0 ) + { + fread(&datalen,1,sizeof(datalen),fp); + if ( datalen < (mem->totalsize - mem->used - 4) ) + { + if ( (txdata= iguana_memalloc(mem,datalen,0)) != 0 ) + { + fread(txdata,1,datalen,fp); + if ( txdata->datalen != datalen || txdata->block.bundlei != bundlei ) + { + printf("%s peertxdata txdata->datalen.%d != %d bundlei.%d vs %d\n",bits256_str(str,txdata->block.RO.hash2),txdata->datalen,datalen,txdata->block.bundlei,bundlei); + getchar(); + txdata = 0; + iguana_memreset(mem); + } //else printf("SUCCESS txdata.%s bundlei.%d fpos.%d T.%d U.%d S.%d P.%d\n",bits256_str(str,txdata->block.hash2),bundlei,fpos,txdata->numtxids,txdata->numunspents,txdata->numspends,txdata->numpkinds); + } else printf("peertxdata error allocating txdata\n"); + } else printf("mismatch peertxdata datalen %d vs %ld totalsize %ld\n",datalen,mem->totalsize - mem->used - 4,(long)mem->totalsize); + } else printf("peertxdata hash mismatch %s != %s\n",bits256_str(str,hash2),bits256_str(str2,checkhash2)); + } else printf("peertxdata bundlei.%d != checki.%d, fpos.%d ftell.%ld\n",bundlei,checki,fpos,ftell(fp)); + fclose(fp); + } else printf("cant find file.(%s)\n",fname); + } //else printf("bundlei.%d\n",bundlei); + *bundleip = bundlei; + return(txdata); +} +#endif + void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) { - struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t i,j,bundlei,copyflag; char fname[1024]; + struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t valid,i,j,bundlei,copyflag; struct iguana_bundle *bp; if ( 0 ) { @@ -139,16 +184,40 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } } + char str[65]; + if ( iguana_blockvalidate(coin,&valid,&origtxdata->block,1) < 0 ) + { + printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); + return; + } //else printf("validated prev.%s\n",bits256_str(str,origtxdata->block.RO.prev_block)); copyflag = 1 * (strcmp(coin->symbol,"BTC") != 0); - req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); - req->recvlen = recvlen; - req->H = *H; bp = 0, bundlei = -2; if ( copyflag != 0 && recvlen != 0 && ((bp= iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2)) == 0 || (bp->blocks[bundlei] != 0 && bp->blocks[bundlei]->fpipbits == 0)) ) { - //printf("copy %p serialized[%d]\n",req->serialized,req->recvlen); - memcpy(req->serialized,data,recvlen), req->copyflag = 1; + req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); + //printf("copy %p serialized[%d]\n",req,req->recvlen); + memcpy(req->serialized,data,recvlen); + } + else + { + copyflag = 0; + req = iguana_bundlereq(coin,addr,'B',0); + } + if ( bp != 0 && bundlei >= 0 && bp->blocks[bundlei] != 0 )//&& bits256_cmp(bp->blocks[bundlei]->RO.prev_block,origtxdata->block.RO.prev_block) != 0 ) + { + if ( bp->blocks[bundlei]->fpos >= 0 && bp->blocks[bundlei]->fpipbits != 0 && bp->blocks[bundlei]->txvalid != 0 ) + { + if ( bits256_cmp(origtxdata->block.RO.hash2,bp->blocks[bundlei]->RO.hash2) == 0 ) + return; + else printf("mismatched tx received? mainchain.%d\n",bp->blocks[bundlei]->mainchain); + if ( bp->blocks[bundlei]->mainchain != 0 ) + return; + } + bp->blocks[bundlei]->RO = origtxdata->block.RO; + //printf("update prev for [%d:%d]\n",bp->hdrsi,bundlei); } + req->recvlen = recvlen; + req->H = *H; if ( bits256_cmp(origtxdata->block.RO.hash2,coin->APIblockhash) == 0 ) { printf("MATCHED APIblockhash\n"); @@ -166,9 +235,11 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i if ( iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->block.RO.txn_count,data,recvlen) >= 0 ) { txdata->block.fpipbits = (uint32_t)addr->ipbits; + txdata->block.fpipbits = recvlen; + txdata->block.fpos = 0; req->datalen = txdata->datalen; req->ipbits = txdata->block.fpipbits; - if ( 0 ) + /*if ( 0 ) { struct iguana_txblock *checktxdata; struct OS_memspace checkmem; int32_t checkbundlei; memset(&checkmem,0,sizeof(checkmem)); @@ -178,16 +249,17 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i printf("check datalen.%d bundlei.%d T.%d U.%d S.%d P.%d X.%d\n",checktxdata->datalen,checkbundlei,checktxdata->numtxids,checktxdata->numunspents,checktxdata->numspends,checktxdata->numpkinds,checktxdata->numexternaltxids); } iguana_mempurge(&checkmem); - } + }*/ } } - //printf("recvlen.%d\n",req->recvlen); req->block = txdata->block; + //printf("recvlen.%d prev.(%s)\n",req->recvlen,bits256_str(str,txdata->block.RO.prev_block)); req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; coin->recvcount++; coin->recvtime = (uint32_t)time(NULL); req->addr = addr; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + netBLOCKS++; + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n) @@ -196,7 +268,7 @@ void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 //printf("got %d txids from %s\n",n,addr->ipaddr); req = iguana_bundlereq(coin,addr,'T',0); req->hashes = txids, req->n = n; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) @@ -211,7 +283,9 @@ void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct } req = iguana_bundlereq(coin,addr,'H',0); req->blocks = blocks, req->n = n; - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + HDRnet++; + //char str[65]; printf("PTblockhdrs.%s net.%d blocks.%d\n",bits256_str(str,blocks[0].RO.hash2),HDRnet,netBLOCKS); + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n) @@ -226,10 +300,10 @@ void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bi req = iguana_bundlereq(coin,addr,'S',0); req->hashes = blockhashes, req->n = n; //printf("bundlesQ blockhashes.%p[%d]\n",blockhashes,n); - queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } -void iguana_patch(struct iguana_info *coin,struct iguana_block *block) +/*void iguana_patch(struct iguana_info *coin,struct iguana_block *block) { int32_t i,j,origheight,height; struct iguana_block *prev,*next; struct iguana_bundle *bp; prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); @@ -283,15 +357,15 @@ void iguana_patch(struct iguana_info *coin,struct iguana_block *block) } } } -} +}*/ uint32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bits256 *blockhashes,int32_t num) { bits256 allhash; int32_t err,i,n; struct iguana_block *block,*prev; - if ( bits256_nonz(bp->allhash) > 0 && num >= coin->chain->bundlesize ) + if ( bits256_nonz(bp->allhash) > 0 && num >= coin->chain->bundlesize && bp->queued == 0 ) { vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); - if ( memcmp(allhash.bytes,bp->allhash.bytes,sizeof(allhash)) == 0 && bp->queued == 0 ) + if ( memcmp(allhash.bytes,bp->allhash.bytes,sizeof(allhash)) == 0 ) { if ( bp->bundleheight > 0 ) prev = iguana_blockfind(coin,iguana_blockhash(coin,bp->bundleheight-1)); @@ -299,22 +373,32 @@ uint32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bit for (i=n=0; ichain->bundlesize&&in; i++) { if ( (err= iguana_bundlehash2add(coin,&block,bp,i,blockhashes[i])) < 0 ) + { + printf("error adding blockhash allhashes hdrsi.%d i.%d\n",bp->hdrsi,i); return(err); + } if ( block != 0 && block == bp->blocks[i] ) { + if ( i > 0 ) + block->RO.prev_block = blockhashes[i-1]; block->height = bp->bundleheight + i; block->mainchain = 1; if ( prev != 0 ) { - //block->RO.prev_block = prev->RO.hash2; + block->RO.prev_block = prev->RO.hash2; prev->hh.next = block; block->hh.prev = prev; } - } + //if ( bp->hdrsi < coin->MAXBUNDLES ) + // iguana_blockQ(coin,bp,i,blockhashes[i],0); + } else printf("no allhashes block.%p or mismatch.%p\n",block,bp->blocks[i]); prev = block; } - //printf("ALLHASHES FOUND! %d requested.%d\n",bp->bundleheight,n); - iguana_bundleQ(coin,bp,bp->n/2 + (rand() % 500)); + coin->allhashes++; + // if ( bp->hdrsi == 0 ) + printf("ALLHASHES FOUND! %d allhashes.%d\n",bp->bundleheight,coin->allhashes); + if ( bp->queued == 0 ) + iguana_bundleQ(coin,bp,bp->n*5 + (rand() % 500)); return(bp->queued); } } @@ -323,13 +407,15 @@ uint32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bit void iguana_bundlespeculate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t offset) { + if ( bp == 0 ) + return; if ( bp->numhashes < bp->n && bundlei == 0 && bp->speculative == 0 && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) { char str[65]; bits256_str(str,bp->hashes[0]); - //printf("Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); + //fprintf(stderr,"Afound block -> %d %d hdr.%s\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,str); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); } - else if ( bp->speculative != 0 && bundlei < bp->numspec && memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)) == 0 ) + /*else if ( bp->speculative != 0 && bundlei < bp->numspec && memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)) == 0 ) { bundlei += offset; if ( bundlei < bp->n && bundlei < bp->numspec ) @@ -337,107 +423,9 @@ void iguana_bundlespeculate(struct iguana_info *coin,struct iguana_bundle *bp,in //char str[65]; printf("speculative req[%d] %s\n",bundlei,bits256_str(str,bp->speculative[bundlei])); //iguana_blockQ(coin,0,-1,bp->speculative[bundlei],0); } - } //else printf("speculative.%p %d vs %d cmp.%d\n",bp->speculative,bundlei,bp->numspec,bp->speculative!=0?memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)):-1); + } //else printf("speculative.%p %d vs %d cmp.%d\n",bp->speculative,bundlei,bp->numspec,bp->speculative!=0?memcmp(hash2.bytes,bp->speculative[bundlei].bytes,sizeof(hash2)):-1);*/ } -int32_t iguana_bundleiters(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit) -{ - int32_t i,n,valid,pend,max,counter = 0; uint32_t now; struct iguana_block *block; double endmillis; - coin->numbundlesQ--; - if ( bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize ) - { - //printf("ITERATE bundle.%d vs %d: h.%d n.%d r.%d s.%d finished.%d speculative.%p\n",bp->bundleheight,coin->longestchain-coin->chain->bundlesize,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,bp->speculative); - if ( bp->speculative == 0 ) - { - char str[64]; - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - } - else - { - for (i=1; in; i++) - if ( bits256_nonz(bp->hashes[i]) == 0 && bits256_nonz(bp->speculative[i]) > 0 ) - { - iguana_blockQ(coin,0,-1,bp->speculative[i],0); - break; - } - } - usleep(10000); - iguana_bundleQ(coin,bp,bp->n); - return(0); - } - pend = queue_size(&coin->priorityQ) + queue_size(&coin->blocksQ); - for (i=0; ipeers.active[i].pendblocks; - if ( pend >= coin->MAXPENDING*coin->MAXPEERS ) - { - usleep(1000); - //printf("SKIP pend.%d vs %d: ITERATE bundle.%d n.%d r.%d s.%d finished.%d timelimit.%d\n",pend,coin->MAXPENDING*coin->MAXPEERS,bp->bundleheight,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit); - iguana_bundleQ(coin,bp,counter == 0 ? bp->n*5 : bp->n*2); - return(0); - } - max = 1 + ((coin->MAXPENDING*coin->MAXPEERS - pend) >> 1); - endmillis = OS_milliseconds() + timelimit; - while ( bp->emitfinish == 0 && OS_milliseconds() < endmillis ) - { - now = (uint32_t)time(NULL); - for (i=n=counter=0; in; i++) - { - if ( (block= bp->blocks[i]) != 0 ) - { - if ( block->fpipbits == 0 && (block->queued == 0 || bp->issued[i] == 0 || now > bp->issued[i]+30) ) - { - //if ( bp->bundleheight == 20000 ) - // printf("(%d:%d) ",bp->hdrsi,i); - block->numrequests++; - iguana_blockQ(coin,bp,i,block->RO.hash2,bp->numsaved > bp->n-10); - bp->issued[i] = now; - counter++; - if ( --max <= 0 ) - break; - } - else if ( block->fpipbits != 0 ) - n++; - } //else printf("iguana_bundleiters[%d] unexpected null block[%d]\n",bp->bundleheight,i); - bp->numsaved = n; - } - if ( max <= 0 ) - break; - usleep(100); - } - if ( 0 && counter > 0 ) - printf("ITERATE bundle.%d h.%d n.%d r.%d s.%d finished.%d issued.%d\n",bp->bundleheight,bp->numhashes,bp->n,bp->numrecv,bp->numsaved,bp->emitfinish,counter); - if ( bp->emitfinish == 0 ) - { - if ( bp->numsaved >= bp->n ) - { - for (i=0; in; i++) - { - if ( (block= bp->blocks[i]) != 0 ) - { - //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); - if ( iguana_blockvalidate(coin,&valid,block,0) != 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) ) - { - //char str[65]; printf(">>>>>>> null prevblock error at ht.%d patch.(%s) and reissue\n",bp->bundleheight+i,bits256_str(str,bp->hashes[i-1])); - block->queued = 0; - block->fpipbits = 0; - bp->issued[i] = 0; - iguana_blockQ(coin,bp,i,block->RO.hash2,0); - iguana_bundleQ(coin,bp,counter == 0 ? bp->n*5 : bp->n*2); - return(0); - } - } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,iguana_blockfind(coin,bp->hashes[i])); - } - // merkle - printf(">>>>>>>>>>>>>>>>>>>>>>> EMIT bundle.%d\n",bp->bundleheight); - bp->emitfinish = 1; - sleep(1); - iguana_emitQ(coin,bp); - return(1); - } - iguana_bundleQ(coin,bp,counter == 0 ? bp->n*5 : bp->n*2); - } - return(0); -} // main context, ie single threaded struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) @@ -450,37 +438,55 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl hash2 = origblock->RO.hash2; if ( (block= iguana_blockhashset(coin,-1,hash2,1)) != 0 ) { + prevhash2 = origblock->RO.prev_block; if ( block != origblock ) + { iguana_blockcopy(coin,block,origblock); + //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); + } *blockp = block; - prevhash2 = origblock->RO.prev_block; - if ( 1 && bits256_nonz(prevhash2) > 0 ) - iguana_patch(coin,block); + //if ( 0 && bits256_nonz(prevhash2) > 0 ) + // iguana_patch(coin,block); if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) != 0 && bundlei < coin->chain->bundlesize ) { + //fprintf(stderr,"bundle found %d:%d\n",bp->hdrsi,bundlei); block->bundlei = bundlei; block->hdrsi = bp->hdrsi; bp->blocks[bundlei] = block; + //printf("bundlehashadd set.%d\n",bundlei); iguana_bundlehash2add(coin,0,bp,bundlei,hash2); if ( bundlei > 0 ) + { + //printf("bundlehashadd prev %d\n",bundlei); iguana_bundlehash2add(coin,0,bp,bundlei-1,prevhash2); + } else if ( bp->hdrsi > 0 && (bp= coin->bundles[bp->hdrsi-1]) != 0 ) iguana_bundlehash2add(coin,0,bp,coin->chain->bundlesize-1,prevhash2); - iguana_bundlespeculate(coin,bp,bundlei,hash2,1); + if ( strcmp(coin->symbol,"BTC") != 0 ) + iguana_bundlespeculate(coin,bp,bundlei,hash2,1); } prevbp = 0, prevbundlei = -2; iguana_bundlefind(coin,&prevbp,&prevbundlei,prevhash2); - if ( block->blockhashes != 0 ) - printf("has blockhashes bp.%p[%d] prevbp.%p[%d]\n",bp,bundlei,prevbp,prevbundlei); + if ( 0 && block->blockhashes != 0 ) + fprintf(stderr,"has blockhashes bp.%p[%d] prevbp.%p[%d]\n",bp,bundlei,prevbp,prevbundlei); if ( prevbp != 0 && prevbundlei >= 0 && (prevblock= iguana_blockfind(coin,prevhash2)) != 0 ) { if ( prevbundlei < coin->chain->bundlesize ) { if ( prevbp->hdrsi+1 == coin->bundlescount && prevbundlei == coin->chain->bundlesize-1 ) - iguana_bundlecreate(coin,&prevbundlei,prevbp->bundleheight + coin->chain->bundlesize,hash2,zero,0); + { + printf("AUTOCREATE.%d\n",prevbp->bundleheight + coin->chain->bundlesize); + bp = iguana_bundlecreate(coin,bundleip,prevbp->bundleheight + coin->chain->bundlesize,hash2,zero,0); + if ( bp->queued == 0 ) + iguana_bundleQ(coin,bp,1000); + } if ( prevbundlei < coin->chain->bundlesize-1 ) + { + //printf("bundlehash2add next %d\n",prevbundlei); iguana_bundlehash2add(coin,0,prevbp,prevbundlei+1,hash2); - iguana_bundlespeculate(coin,prevbp,prevbundlei,prevhash2,2); + } + if ( strcmp(coin->symbol,"BTC") != 0 ) + iguana_bundlespeculate(coin,prevbp,prevbundlei,prevhash2,2); } } } else printf("iguana_bundleset: error adding blockhash\n"); @@ -490,7 +496,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) { - int32_t i,bundlei,match; struct iguana_block *block; struct iguana_bundle *bp,*firstbp = 0; + int32_t i,bundlei,match; bits256 *blockhashes,allhash; struct iguana_block *block; struct iguana_bundle *bp,*firstbp = 0; if ( blocks == 0 ) { printf("iguana_recvblockhdrs null blocks?\n"); @@ -498,115 +504,212 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig } if ( blocks != 0 && n > 0 ) { + if ( 0 && n >= coin->chain->bundlesize ) + { + blockhashes = malloc(sizeof(*blockhashes) * coin->chain->bundlesize); + for (i=0; ichain->bundlesize; i++) + blockhashes[i] = blocks[i].RO.hash2; + for (i=0; ibundlescount; i++) + { + if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 ) + { + blockhashes[0] = bp->hashes[0]; + vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); + if ( bits256_cmp(allhash,bp->allhash) == 0 ) + { + if ( bp->queued != 0 ) + bp->queued = 0; + if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) + { + free(blockhashes); + return(req); + } + } + } + } + free(blockhashes); + } for (i=match=0; ihdrsi,bundlei); if ( i == 0 ) firstbp = bp; if ( bundlei == i+1 && bp == firstbp ) match++; - //else printf("recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); - } + else + { + if ( i != n-1 ) + fprintf(stderr,"recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); + } + } else printf("blockhash[%d] cant be found\n",i); } + //char str[65]; printf("blockhdrs.%s hdrsi.%d\n",bits256_str(str,blocks[0].RO.hash2),firstbp!=0?firstbp->hdrsi:-1); if ( firstbp != 0 && match == coin->chain->bundlesize-1 && n == firstbp->n ) { if ( firstbp->queued == 0 ) { - //printf("firstbp blockQ %d\n",firstbp->bundleheight); - iguana_bundleQ(coin,firstbp,1000 + 10*(rand() % (int32_t)(1+sqrt(firstbp->bundleheight)))); + //fprintf(stderr,"firstbp blockQ %d\n",firstbp->bundleheight); + iguana_bundleQ(coin,firstbp,1000); } - } else printf("match.%d vs n.%d bp->n.%d ht.%d\n",match,n,firstbp->n,firstbp->bundleheight); + } } return(req); } struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) { - int32_t bundlei,i; struct iguana_bundle *bp;// struct iguana_block *block; + int32_t bundlei,i,len; struct iguana_bundle *bp; bits256 allhash,zero; char hashstr[65]; uint8_t serialized[512]; struct iguana_peer *addr; + memset(zero.bytes,0,sizeof(zero)); bp = 0, bundlei = -2; + if ( num < 2 ) + return(req); iguana_bundlefind(coin,&bp,&bundlei,blockhashes[1]); - // char str[65]; printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); + //iguana_blockQ(coin,0,-1,blockhashes[1],0); + //iguana_blockQ(coin,0,-4,blockhashes[1],1); + char str[65]; + if ( num > 2 )//&& bp->hdrsi == coin->bundlescount-1 ) + printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( bp != 0 ) { bp->hdrtime = (uint32_t)time(NULL); blockhashes[0] = bp->hashes[0]; + iguana_blockQ("recvhash0",coin,bp,0,blockhashes[0],0); if ( num >= coin->chain->bundlesize ) { - iguana_blockQ(coin,0,-1,blockhashes[coin->chain->bundlesize],1); - if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) + iguana_blockQ("recvhash1",coin,0,-1,blockhashes[coin->chain->bundlesize],0); + //printf("call allhashes\n"); + if ( bp->hdrsi == coin->bundlescount-1 ) + { + init_hexbytes_noT(hashstr,blockhashes[coin->chain->bundlesize].bytes,sizeof(bits256)); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + bp = iguana_bundlecreate(coin,&bundlei,bp->bundleheight+coin->chain->bundlesize,blockhashes[coin->chain->bundlesize],zero,1); + if ( bp != 0 ) + { + char str2[65]; + printf("EXTEND last bundle %s/%s ht.%d\n",bits256_str(str,bp->hashes[0]),bits256_str(str2,blockhashes[coin->chain->bundlesize]),bp->bundleheight); + if ( bp->queued == 0 ) + iguana_bundleQ(coin,bp,1000); + } + } + else if ( iguana_allhashcmp(coin,bp,blockhashes,num) > 0 ) return(req); + //printf("done allhashes\n"); } - if ( (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) + if ( bp != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { - printf("FOUND speculative BLOCKHASHES[%d] ht.%d\n",num,bp->bundleheight); + printf("FOUND speculative.%p BLOCKHASHES[%d] ht.%d\n",bp->speculative,num,bp->bundleheight); if ( bp->speculative != 0 ) myfree(bp->speculative,sizeof(*bp->speculative) * bp->numspec); bp->speculative = blockhashes; bp->numspec = num; req->hashes = 0; - iguana_blockQ(coin,0,-1,blockhashes[2],1); + //iguana_blockQ(coin,0,-1,blockhashes[2],1); } } else if ( num >= coin->chain->bundlesize ) { for (i=coin->bundlescount-1; i>=0; i--) { - if ( (bp= coin->bundles[i]) != 0 && bits256_nonz(bp->hashes[0]) > 0 ) + if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 ) { blockhashes[0] = bp->hashes[0]; - if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) + vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); + if ( bits256_cmp(allhash,bp->allhash) == 0 ) { - bp->hdrtime = (uint32_t)time(NULL); - iguana_blockQ(coin,bp,1,blockhashes[1],0); - iguana_blockQ(coin,bp,0,blockhashes[0],0); - iguana_blockQ(coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); - //printf("matched bundle.%d\n",bp->bundleheight); - return(req); + if ( bp->queued != 0 ) + bp->queued = 0; + if ( iguana_allhashcmp(coin,bp,blockhashes,coin->chain->bundlesize) > 0 ) + { + bp->hdrtime = (uint32_t)time(NULL); + iguana_blockQ("recvhash2",coin,bp,1,blockhashes[1],0); + iguana_blockQ("recvhash3",coin,bp,0,blockhashes[0],0); + iguana_blockQ("recvhash4",coin,bp,coin->chain->bundlesize-1,blockhashes[coin->chain->bundlesize-1],0); + printf("matched bundle.%d\n",bp->bundleheight); + return(req); + } else printf("unexpected mismatch??\n"); } } } - //printf("issue block1\n"); + //printf("no match to allhashes issue block1\n"); struct iguana_block *block; if ( num == coin->chain->bundlesize+1 && (block= iguana_blockhashset(coin,-1,blockhashes[1],1)) != 0 ) + { block->blockhashes = blockhashes, req->hashes = 0; - iguana_blockQ(coin,0,-1,blockhashes[1],1); - } - else iguana_blockQ(coin,0,-1,blockhashes[1],0); // should be RT block + //printf("set block->blockhashes[%d]\n",num); + } + if ( (addr= coin->peers.ranked[0]) != 0 ) + { + if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&blockhashes[1],1)) > 0 ) + { + iguana_send(coin,addr,serialized,len); + char str[65]; printf("REQ.%s\n",bits256_str(str,blockhashes[1])); + } + } + } else iguana_blockQ("recvhash6",coin,0,-6,blockhashes[1],0); // should be RT block return(req); } struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t recvlen,int32_t *newhwmp) { - struct iguana_bundle *bp=0; int32_t bundlei = -2; struct iguana_block *block; - bp = iguana_bundleset(coin,&block,&bundlei,origblock); - //static int total; char str[65]; printf("RECV %s [%d:%d] block.%08x | %d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,total++); + struct iguana_bundle *bp=0; int32_t i,numsaved=0,bundlei = -2; struct iguana_block *block,*tmpblock; char str[65]; + if ( (bp= iguana_bundleset(coin,&block,&bundlei,origblock)) == 0 ) + { + for (i=coin->bundlescount-1; i>=0; i--) + { + //if ( coin->bundles[i] != 0 ) + // printf("compare vs %s\n",bits256_str(str,coin->bundles[i]->hashes[0])); + if ( coin->bundles[i] != 0 && bits256_cmp(origblock->RO.prev_block,coin->bundles[i]->hashes[0]) == 0 ) + { + bp = coin->bundles[i]; + bundlei = 1; + iguana_bundlehash2add(coin,&block,bp,bundlei,origblock->RO.hash2); + printf("[%d] bundlehashadd set.%d block.%p\n",i,bundlei,block); + if ( block != 0 ) + { + bp->blocks[bundlei] = block; + block->bundlei = bundlei; + block->hdrsi = bp->hdrsi; + } + break; + } + } + printf("i.%d ref prev.(%s)\n",i,bits256_str(str,origblock->RO.prev_block)); + } + if ( 0 && bp != 0 && bp->hdrsi == coin->bundlescount-1 ) + { + int32_t i; static int32_t numrecv; + numrecv++; + if ( bp != 0 ) + { + for (i=numsaved=0; in; i++) + if ( (tmpblock= bp->blocks[i]) != 0 && tmpblock->fpipbits != 0 && tmpblock->fpos >= 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(tmpblock->RO.prev_block) != 0) ) + numsaved++; + } + fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block->fpipbits,numsaved,numrecv); + } + if ( bundlei == 1 && bp != 0 && bp->numhashes < bp->n && strcmp(coin->symbol,"BTC") != 0 ) + { + printf("reissue hdrs request for [%d]\n",bp->hdrsi); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + } if ( block != 0 ) { - block->RO.recvlen = recvlen; - if ( req->copyflag != 0 && block->queued == 0 && bp != 0 )//block->rawdata == 0 ) + block->RO.txn_count = req->numtx; + //block->RO.recvlen = recvlen; + if ( req->copyflag != 0 && block->queued == 0 && bp != 0 ) { - //char str[65]; printf("%s copyflag.%d %d data %d %d\n",bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen); - //block->rawdata = mycalloc('n',1,block->RO.recvlen); - //memcpy(block->rawdata,req->serialized,block->RO.recvlen); - //block->copyflag = 1; + char str[65]; fprintf(stderr,"req.%p %s copyflag.%d %d data %d %d\n",req,bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen); coin->numcached++; block->queued = 1; queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); return(0); } - while ( block != 0 && memcmp(block->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) - { - if ( _iguana_chainlink(coin,block) != 0 ) - { - printf("chainlink.%d -> next.%p\n",block->height,block->hh.next); - block = block->hh.next; - } else break; - } //printf("datalen.%d ipbits.%x\n",datalen,req->ipbits); - } else printf("cant create block.%llx block.%p bp.%p bundlei.%d\n",(long long)origblock->RO.hash2.txid,block,bp,bundlei); + } else printf("cant create origblock.%p block.%p bp.%p bundlei.%d\n",origblock,block,bp,bundlei); return(req); } @@ -629,17 +732,203 @@ struct iguana_bundlereq *iguana_recvunconfirmed(struct iguana_info *coin,struct return(req); } -int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp) // single threaded +int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority) +{ + int32_t hdrsi,bundlei; struct iguana_bundle *bp; + hdrsi = height / coin->chain->bundlesize; + bundlei = height % coin->chain->bundlesize; + if ( (bp= coin->bundles[hdrsi]) != 0 && bits256_nonz(bp->hashes[bundlei]) != 0 ) + { + iguana_blockQ("blockreq",coin,bp,bundlei,bp->hashes[bundlei],priority); + return(height); + } + return(-1); +} + +int32_t iguana_reqblocks(struct iguana_info *coin) +{ + int32_t hdrsi,lflag,bundlei,flag = 0; bits256 hash2; struct iguana_block *next,*block; struct iguana_bundle *bp; + /*if ( 0 && (bp= coin->current) != 0 && bp->numsaved < bp->n ) + { + for (hdrsi=numissued=0; hdrsiMAXBUNDLES && coin->current->hdrsi+hdrsibundlescount && numissued<100; hdrsi++) + { + if ( (bp= coin->bundles[hdrsi + coin->current->hdrsi]) == 0 ) + continue; + if ( (addr= coin->peers.ranked[hdrsi]) == 0 || addr->msgcounts.verack == 0 ) + continue; + for (bundlei=n=flag=0; bundlein; bundlei++) + if ( (block= bp->blocks[bundlei]) != 0 ) + { + if ( bits256_nonz(block->RO.hash2) > 0 && block->fpos >= 0 ) + n++; + else if ( block->fpipbits == 0 || time(NULL) > block->issued+60 ) + { + block->issued = (uint32_t)time(NULL); + //iguana_sendblockreqPT(coin,addr,bp,bundlei,block->RO.hash2,0); + iguana_blockQ("reqblocks",coin,bp,bundlei,block->RO.hash2,0); + flag++; + if ( ++numissued > 100 ) + break; + } + } + if ( 0 && flag != 0 ) + printf("issued %d priority blocks for %d current.[%d] have %d blocks emit.%u\n",flag,hdrsi,bp->hdrsi,n,bp->emitfinish); + } + }*/ + hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; + if ( (bp= coin->bundles[hdrsi]) != 0 ) + { + bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; + if ( (next= bp->blocks[bundlei]) != 0 || (next= iguana_blockfind(coin,bp->hashes[bundlei])) != 0 ) + { + if ( bits256_nonz(next->RO.prev_block) > 0 ) + _iguana_chainlink(coin,next); + else if ( next->queued == 0 && next->fpipbits == 0 && (rand() % 100) == 0 ) + { + printf("HWM next %d\n",coin->blocks.hwmchain.height+1); + iguana_blockQ("reqblocks",coin,bp,bundlei,next->RO.hash2,0); + } + } + /*else if ( iguana_blockfind(coin,bp->hashes[bundlei]) == 0 ) + { + //if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) + // { + // printf("next %d\n",coin->blocks.hwmchain.height+1); + // iguana_blockQ(coin,bp,bundlei,bp->hashes[bundlei],0); + // } + // else if ( bp->speculative != 0 && (bits256_cmp(bp->hashes[bundlei],bp->speculative[bundlei]) != 0 || (rand() % 100) == 0) ) + { + if ( time(NULL) > bp->issued[bundlei]+30 && iguana_blockfind(coin,bp->speculative[bundlei]) == 0 ) + { + bp->hashes[bundlei] = bp->speculative[bundlei]; + struct iguana_bloominds bit = iguana_calcbloom(bp->speculative[bundlei]); + if ( iguana_bloomfind(coin,&bp->bloom,0,bit) < 0 ) + iguana_bloomset(coin,&bp->bloom,0,bit); + printf("speculative next %d\n",coin->blocks.hwmchain.height+1); + iguana_blockQ("speculativenext",coin,0,-1,bp->speculative[bundlei],0); + bp->issued[bundlei] = (uint32_t)time(NULL); + } + } + }*/ + } + /*else if ( 0 && (bp= coin->bundles[--hdrsi]) != 0 ) + { + char str[65]; + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + }*/ + lflag = 1; + while ( lflag != 0 ) + { + lflag = 0; + hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; + bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; + if ( (next= iguana_blockfind(coin,iguana_blockhash(coin,coin->blocks.hwmchain.height+1))) == 0 ) + { + if ( (block= iguana_blockfind(coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) + next = block->hh.next, block->mainchain = 1; + } + if ( next == 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (next= bp->blocks[bundlei]) != 0 ) + { + if ( bits256_nonz(next->RO.prev_block) == 0 ) + { + printf(" next has null prev [%d:%d]\n",bp->hdrsi,bundlei); + iguana_blockQ("reqblocks0",coin,bp,bundlei,next->RO.hash2,0); + next = 0; + } + } + else if ( bp != 0 && bits256_nonz(bp->hashes[bundlei]) == 0 && time(NULL) > bp->issued[bundlei]+60 ) + { + if ( bundlei > 0 && bits256_nonz(bp->hashes[bundlei+1]) != 0 ) + { + if ( (block= iguana_blockfind(coin,bp->hashes[bundlei+1])) != 0 && bits256_nonz(block->RO.prev_block) != 0 ) + { + bp->hashes[bundlei] = block->RO.prev_block; + printf("reqblock [%d:%d]\n",bp->hdrsi,bundlei); + iguana_blockQ("reqblocks1",coin,bp,bundlei,bp->hashes[bundlei],0); + } + } + } + if ( next != 0 ) + { + //printf("have next %d\n",coin->blocks.hwmchain.height); + if ( memcmp(next->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) + { + if ( _iguana_chainlink(coin,next) != 0 ) + lflag++, flag++; + //else printf("chainlink error for %d\n",coin->blocks.hwmchain.height+1); + } + if ( strcmp(coin->symbol,"BTC") != 0 && queue_size(&coin->blocksQ) < _IGUANA_MAXPENDING ) + { + double threshold,lag = OS_milliseconds() - coin->backstopmillis; + threshold = (10 + coin->longestchain - coin->blocksrecv); + if ( threshold < 1 ) + threshold = 1.; + if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) + threshold = (bp->avetime + coin->avetime) * .5; + else threshold = coin->avetime; + threshold *= 100. * sqrt(threshold) * .000777; + if ( strcmp(coin->symbol,"BTC") != 0 ) + threshold = 1000; + else threshold = 10000; + if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) + { + coin->backstop = coin->blocks.hwmchain.height+1; + hash2 = iguana_blockhash(coin,coin->backstop); + bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; + bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; + if ( bp != 0 && bits256_nonz(hash2) == 0 ) + { + hash2 = bp->hashes[bundlei]; + if ( bits256_nonz(hash2) == 0 && bp->speculative != 0 ) + hash2 = bp->speculative[bundlei]; + } + if ( bits256_nonz(hash2) > 0 ) + { + if ( bp != 0 && bits256_nonz(hash2) > 0 ) + { + coin->backstopmillis = OS_milliseconds(); + iguana_blockQ("mainchain",coin,bp,bundlei,hash2,0); + flag++; + char str[65]; + if ( 1 && (rand() % 1000) == 0 || bp->bundleheight > coin->longestchain-coin->chain->bundlesize ) + printf("%s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); + } + } + /*else if ( bp != 0 && bundlei < bp->n-1 && bits256_nonz(bp->hashes[bundlei+1]) > 0 ) + { + printf("MAINCHAIN skip issue %d\n",bundlei+1); + iguana_blockQ("mainskip",coin,bp,bundlei,bp->hashes[bundlei+1],0); + } + else if ( bp != 0 && time(NULL) > bp->hdrtime+10 ) + { + char str[65]; + printf("MAINCHAIN gethdr %d\n",bp->bundleheight); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + bp->hdrtime = (uint32_t)time(NULL); + }*/ + } + } + } + } + return(flag); +} + +int32_t iguana_processrecvQ(struct iguana_info *coin,int32_t *newhwmp) // single threaded { int32_t flag = 0; struct iguana_bundlereq *req; *newhwmp = 0; - while ( flag < IGUANA_BUNDLELOOP && (req= queue_dequeue(&coin->bundlesQ,0)) != 0 ) + while ( (req= queue_dequeue(&coin->recvQ,0)) != 0 ) { - //printf("%s bundlesQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); + //fprintf(stderr,"%s recvQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); if ( req->type == 'B' ) // one block with all txdata + { + netBLOCKS--; req = iguana_recvblock(coin,req->addr,req,&req->block,req->numtx,req->datalen,req->recvlen,newhwmp); + flag++; + } else if ( req->type == 'H' ) // blockhdrs (doesnt have txn_count!) { + HDRnet--; if ( (req= iguana_recvblockhdrs(coin,req,req->blocks,req->n,newhwmp)) != 0 ) { if ( req->blocks != 0 ) @@ -658,12 +947,16 @@ int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp) // sin if ( (req= iguana_recvtxids(coin,req,req->hashes,req->n)) != 0 ) myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0; } - else printf("iguana_updatebundles unknown type.%c\n",req->type); - flag++; - //printf("done %s bundlesQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); + else printf("iguana_updatebundles unknown type.%c\n",req->type), getchar(); + //fprintf(stderr,"finished coin->recvQ\n"); if ( req != 0 ) myfree(req,req->allocsize), req = 0; + if ( flag >= IGUANA_BUNDLELOOP ) + break; + if ( (flag % 100) == 0 ) + iguana_reqblocks(coin); } + iguana_reqblocks(coin); return(flag); } @@ -677,37 +970,35 @@ int32_t iguana_needhdrs(struct iguana_info *coin) int32_t iguana_reqhdrs(struct iguana_info *coin) { int32_t i,lag,n = 0; struct iguana_bundle *bp; char hashstr[65]; - if ( iguana_needhdrs(coin) > 0 && queue_size(&coin->hdrsQ) == 0 ) + if ( queue_size(&coin->hdrsQ) == 0 ) { - ///if ( coin->zcount++ > 1 ) + if ( iguana_needhdrs(coin) > 0 ) { for (i=0; ibundlescount; i++) { - if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish < coin->startutc ) + if ( (bp= coin->bundles[i]) != 0 && (bp->numhashes < bp->n || i == coin->bundlescount-1) ) { - if ( i == coin->bundlescount-1 ) - lag = 60; - else lag = 60 + (rand() % 30); - //if ( i < coin->bundlescount-1 && (bp->numhashes >= (rand() % bp->n) || time(NULL) < bp->hdrtime+lag) ) - // continue; - if ( bp->numhashes < bp->n && bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) + lag = 60; + if ( bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) { - printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); + //printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount); if ( bp->issuetime == 0 ) coin->numpendings++; - char str[65]; - bits256_str(str,bp->hashes[0]); - //printf("(%s %d).%d ",str,bp->bundleheight,i); - //printf("%d ",bp->bundleheight); init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); - iguana_blockQ(coin,bp,0,bp->hashes[0],0); + printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); + if ( 1 ) + { + iguana_blockQ("reqhdrs0",coin,bp,0,bp->hashes[0],0); + if ( bits256_nonz(bp->hashes[1]) > 0 ) + iguana_blockQ("reqhdrs1",coin,bp,1,bp->hashes[1],0); + } n++; bp->hdrtime = bp->issuetime = (uint32_t)time(NULL); } } } - if ( n > 0 ) + if ( 0 && n > 0 ) printf("REQ HDRS pending.%d\n",n); coin->zcount = 0; } @@ -717,7 +1008,7 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct iguana_bundle *bp; int32_t n,height,bundlei; }; -int32_t iguana_blockQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority) +int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority) { queue_t *Q; char *str; int32_t height = -1; struct iguana_blockreq *req; struct iguana_block *block = 0; if ( bits256_nonz(hash2) == 0 ) @@ -728,37 +1019,37 @@ int32_t iguana_blockQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t block = iguana_blockfind(coin,hash2); if ( priority != 0 || block == 0 || (block->queued == 0 && block->fpipbits == 0) ) { - if ( block != 0 && bits256_cmp(coin->APIblockhash,hash2) != 0 ) + if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) + { + if ( block == 0 ) + block = bp->blocks[bundlei]; + height = bp->bundleheight + bundlei; + } + if ( block != 0 ) { - if ( block->fpipbits != 0 || block->queued != 0 || block->issued > time(NULL)-10 ) + if ( bits256_cmp(coin->APIblockhash,hash2) != 0 && block->fpipbits != 0 && block->fpos >= 0 ) return(0); + height = block->height; } + if ( bp != 0 && bp->emitfinish != 0 ) + return(0); if ( priority != 0 ) str = "priorityQ", Q = &coin->priorityQ; else str = "blocksQ", Q = &coin->blocksQ; if ( Q != 0 ) { - if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) - { - if ( bp->issued[bundlei] == 0 || time(NULL) > bp->issued[bundlei]+3 ) - { - bp->issued[bundlei] = (uint32_t)time(NULL); - if ( bp->bundleheight >= 0 ) - height = (bp->bundleheight + bundlei); - } - else - { - return(1); - } - } req = mycalloc('y',1,sizeof(*req)); req->hash2 = hash2; - req->bp = bp; + if ( (req->bp= bp) != 0 && bundlei >= 0 ) + { + height = bp->bundleheight + bundlei; + bp->issued[bundlei] = (uint32_t)time(NULL); + } req->height = height; req->bundlei = bundlei; char str2[65]; if ( 0 && (bundlei % 250) == 0 ) - printf("%s %d %s %d numranked.%d qsize.%d\n",str,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + printf("%s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); if ( block != 0 ) { block->numrequests++; @@ -774,8 +1065,9 @@ int32_t iguana_blockQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) { uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; - char *hashstr=0; bits256 hash2; uint32_t now; struct iguana_block *block; struct iguana_blockreq *req=0; - struct iguana_bundle *bp; struct iguana_peer *ptr; int32_t priority,i,m,z,pend,limit,height=-1,bundlei,datalen,flag = 0; + struct iguana_block *block; struct iguana_blockreq *req=0; char *hashstr=0; bits256 hash2; + int32_t bundlei,priority,i,m,z,pend,limit,height=-1,datalen,flag = 0; + uint32_t now; struct iguana_bundle *bp; struct iguana_peer *ptr; if ( addr->msgcounts.verack == 0 ) return(0); now = (uint32_t)time(NULL); @@ -792,7 +1084,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) bp = 0, bundlei = -2; bp = iguana_bundlefind(coin,&bp,&bundlei,hash2); z = m = 0; - if ( bp != 0 && bp->queued == 0 ) + if ( bp != 0 ) { if ( bp->bundleheight+coin->chain->bundlesize < coin->longestchain ) { @@ -800,32 +1092,38 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) if ( bp->numhashes < m ) z = 1; } - else if ( bp->numhashes < 3 ) + else if ( bp->numhashes < bp->n ) z = 1; } - //if ( bp == 0 || z != 0 ) + if ( bp == 0 || z != 0 ) { - //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp->numhashes); + //printf("%s request HDR.(%s) numhashes.%d\n",addr!=0?addr->ipaddr:"local",hashstr,bp!=0?bp->numhashes:0); iguana_send(coin,addr,serialized,datalen); addr->pendhdrs++; flag++; - } //else printf("skip hdrreq.%s m.%d z.%d\n",hashstr,m,z); + } else printf("skip hdrreq.%s m.%d z.%d bp.%p longest.%d queued.%d\n",hashstr,m,z,bp,bp->coin->longestchain,bp->queued); } - free_queueitem(hashstr); - return(flag); + //free_queueitem(hashstr); + //return(flag); } else printf("datalen.%d from gethdrs\n",datalen); free_queueitem(hashstr); hashstr = 0; } } + //if ( netBLOCKS > coin->MAXPEERS*coin->MAXPENDING ) + // usleep(netBLOCKS); if ( (limit= addr->recvblocks) > coin->MAXPENDING ) limit = coin->MAXPENDING; if ( limit < 1 ) limit = 1; - //if ( addr->pendblocks >= limit ) - // printf("%s %d overlimit.%d\n",addr->ipaddr,addr->pendblocks,limit); + if ( addr->pendblocks >= limit ) + { + //printf("%s %d overlimit.%d\n",addr->ipaddr,addr->pendblocks,limit); + return(0); + } + priority = 1; req = queue_dequeue(&coin->priorityQ,0); - if ( addr->rank != 1 && req == 0 && addr->pendblocks < limit ) + if ( flag == 0 && req == 0 && addr->pendblocks < limit ) { priority = 0; for (i=m=pend=0; ipeers.numranked; i++) @@ -835,7 +1133,7 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } if ( pend < coin->MAXPENDING*m ) req = queue_dequeue(&coin->blocksQ,0); - } else priority = 1; + } if ( req != 0 ) { hash2 = req->hash2; @@ -848,11 +1146,11 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) } else { - //char str[65]; - //if ( 0 && priority != 0 ) - // printf(" issue.%s\n",bits256_str(str,hash2)); + char str[65]; if ( block != 0 ) block->numrequests++; + if ( 0 && priority != 0 ) + printf("sendreq %s [%d:%d]\n",bits256_str(str,hash2),bp!=0?bp->bundleheight:-1,req->bundlei); iguana_sendblockreqPT(coin,addr,req->bp,req->bundlei,hash2,0); } flag++; @@ -861,112 +1159,14 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) return(flag); } -int32_t iguana_reqblocks(struct iguana_info *coin) -{ - int32_t hdrsi,lflag,bundlei,flag = 0; bits256 hash2; struct iguana_block *next,*block; struct iguana_bundle *bp; - hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; - if ( (bp= coin->bundles[hdrsi]) != 0 ) - { - bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; - if ( (next= bp->blocks[bundlei]) != 0 || (next= iguana_blockfind(coin,bp->hashes[bundlei])) != 0 ) - { - if ( bits256_nonz(next->RO.prev_block) > 0 ) - _iguana_chainlink(coin,next); - else if ( next->queued == 0 && next->fpipbits == 0 ) - { - //printf("HWM next %d\n",coin->blocks.hwmchain.height+1); - iguana_blockQ(coin,bp,bundlei,next->RO.hash2,0); - } - } - else - { - if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) - { - //printf("next %d\n",coin->blocks.hwmchain.height+1); - iguana_blockQ(coin,bp,bundlei,bp->hashes[bundlei],0); - } - else if ( bp->speculative != 0 && bits256_nonz(bp->speculative[bundlei]) > 0 ) - { - //printf("speculative next %d\n",coin->blocks.hwmchain.height+1); - iguana_blockQ(coin,0,-1,bp->speculative[bundlei],0); - } - } - } - else if ( (bp= coin->bundles[--hdrsi]) != 0 ) - { - char str[65]; - queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - } - lflag = 1; - while ( lflag != 0 ) - { - lflag = 0; - hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; - bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; - if ( (next= iguana_blockfind(coin,iguana_blockhash(coin,coin->blocks.hwmchain.height+1))) == 0 ) - { - if ( (block= iguana_blockfind(coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) - next = block->hh.next, block->mainchain = 1; - } - if ( next == 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (next= bp->blocks[bundlei]) != 0 ) - { - if ( bits256_nonz(next->RO.prev_block) == 0 ) - next = 0; - } - if ( next != 0 ) - { - //printf("have next\n"); - if ( memcmp(next->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) - { - if ( _iguana_chainlink(coin,next) != 0 ) - lflag++, flag++; - //else printf("chainlink error for %d\n",coin->blocks.hwmchain.height+1); - } - if ( 1 && queue_size(&coin->blocksQ) == 0 ) - { - double threshold,lag = OS_milliseconds() - coin->backstopmillis; - threshold = (10 + coin->longestchain - coin->blocksrecv); - if ( threshold < 1 ) - threshold = 1.; - if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) - threshold = (bp->avetime + coin->avetime) * .5; - else threshold = coin->avetime; - threshold *= 100. * sqrt(threshold) * .000777; - if ( strcmp(coin->symbol,"BTC") != 0 ) - threshold = 1000; - else threshold = 10000; - if ( coin->blocks.hwmchain.height < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) - { - coin->backstop = coin->blocks.hwmchain.height+1; - hash2 = iguana_blockhash(coin,coin->backstop); - if ( bits256_nonz(hash2) > 0 ) - { - bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; - bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; - if ( bp != 0 ) - { - coin->backstopmillis = OS_milliseconds(); - iguana_blockQ(coin,bp,bundlei,hash2,0); - flag++; - //if ( (rand() % 100) == 0 ) - char str[65]; printf("%s MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",bits256_str(str,hash2),coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); - } - } - } - else if ( 0 && bits256_nonz(next->RO.prev_block) > 0 ) - printf("next prev cmp error nonz.%d\n",bits256_nonz(next->RO.prev_block)); - } - } - } - return(flag); -} - int32_t iguana_processrecv(struct iguana_info *coin) // single threaded { int32_t newhwm = 0,flag = 0; - //printf("process bundlesQ\n"); - flag += iguana_processbundlesQ(coin,&newhwm); + //fprintf(stderr,"process coin->recvQ\n"); + flag += iguana_processrecvQ(coin,&newhwm); + //fprintf(stderr,"iguana_reqhdrs\n"); flag += iguana_reqhdrs(coin); - flag += iguana_reqblocks(coin); + //fprintf(stderr,"iguana_reqblocks\n"); + //flag += iguana_reqblocks(coin); return(flag); } diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index 0521b62b4..b0f459ba2 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -16,7 +16,7 @@ #include "iguana777.h" #include "SuperNET.h" -#define RPCARGS struct supernet_info *myinfo,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr +#define RPCARGS struct supernet_info *myinfo,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr,cJSON *array char *sglue(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,char *agent,char *method) { @@ -31,7 +31,7 @@ char *sglue(cJSON *json,struct supernet_info *myinfo,struct iguana_info *coin,ch if ( (retjson= cJSON_Parse(retstr)) != 0 ) { jdelete(retjson,"tag"); - //printf("RPCret.(%s) n.%d\n",jprint(retjson,0),cJSON_GetArraySize(retjson)); + ///printf("RPCret.(%s) n.%d\n",jprint(retjson,0),cJSON_GetArraySize(retjson)); result = cJSON_GetObjectItem(retjson,"result"); error = cJSON_GetObjectItem(retjson,"error"); if ( result != 0 && cJSON_GetArraySize(retjson) == 1 ) @@ -182,289 +182,306 @@ static char *addnode(RPCARGS) // address and pubkeys static char *validateaddress(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","validateaddress","address",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","validateaddress","address",params[0])); } static char *validatepubkey(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","validatepubkey","pubkey",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","validatepubkey","pubkey",params[0])); } static char *createmultisig(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","createmultisig","M",params[0],"pubkeys",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","createmultisig","M",params[0],"pubkeys",params[1])); } static char *addmultisigaddress(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","createmultisig","M",params[0],"pubkeys",params[1],"account",params[2])); + return(sglue3(0,myinfo,coin,remoteaddr,"bitcoinrpc","createmultisig","M",params[0],"pubkeys",params[1],"account",params[2])); } // blockchain static char *getinfo(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","status")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","status")); } static char *getbestblockhash(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","getbestblockhash")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","getbestblockhash")); } static char *getblockcount(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","getblockcount")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","getblockcount")); } static char *getblock(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getblock","blockhash",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","getblock","blockhash",params[0])); } static char *getblockhash(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getblockhash","height",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","getblockhash","height",params[0])); } static char *gettransaction(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","tx","txid",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","gettransaction","txid",params[0])); } static char *listtransactions(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","listtransactions","account",params[0],"count",params[1],"from",params[2])); + return(sglue3(0,myinfo,coin,remoteaddr,"bitcoinrpc","listtransactions","account",params[0],"count",params[1],"from",params[2])); } static char *getreceivedbyaddress(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getreceivedbyaddress","address",params[0],"minconfs",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","getreceivedbyaddress","address",params[0],"minconfs",params[1])); } static char *listreceivedbyaddress(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listreceivedbyaddress","minconf",params[0],"includeempty",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","listreceivedbyaddress","minconf",params[0],"includeempty",params[1])); } static char *listsinceblock(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listsinceblock","blockhash",params[0],"target",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","listsinceblock","blockhash",params[0],"target",params[1])); } // waccount and waddress funcs static char *getreceivedbyaccount(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getreceivedbyaccount","account",params[0],"minconfs",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","getreceivedbyaccount","account",params[0],"minconfs",params[1])); } static char *listreceivedbyaccount(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listreceivedbyaccount","account",params[0],"includeempty",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","listreceivedbyaccount","account",params[0],"includeempty",params[1])); } static char *getnewaddress(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getnewaddress","account",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","getnewaddress","account",params[0])); } static char *vanitygen(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","vanitygen","vanity",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","vanitygen","vanity",params[0])); } static char *makekeypair(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","makekeypair")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","makekeypair")); } static char *getaccountaddress(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaccountaddress","account",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","getaccountaddress","account",params[0])); } static char *setaccount(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","setaccount","address",params[0],"account",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","setaccount","address",params[0],"account",params[1])); } static char *getaccount(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaccount","address",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","getaccount","address",params[0])); } static char *getaddressesbyaccount(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getaddressesbyaccount","account",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","getaddressesbyaccount","account",params[0])); } static char *listaddressgroupings(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","listaddressgroupings")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","listaddressgroupings")); } static char *getbalance(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getbalance","account",params[0],"minconf",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","getbalance","account",params[0],"minconf",params[1])); } // wallet static char *listaccounts(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","listaccounts","minconf",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","listaccounts","minconf",params[0])); } static char *dumpprivkey(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","dumpprivkey","address",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","dumpprivkey","address",params[0])); } static char *importprivkey(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","importprivkey","wif",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","importprivkey","wif",params[0])); } static char *dumpwallet(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","dumpwallet")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","dumpwallet")); } static char *importwallet(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","importwallet","wallet",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","importwallet","wallet",params[0])); } static char *walletpassphrase(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","walletpassphrase","passphrase",params[0],"timeout",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","walletpassphrase","passphrase",params[0],"timeout",params[1])); } static char *walletpassphrasechange(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","walletpassphrasechange","oldpassphrase",params[0],"newpassphrase",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","walletpassphrasechange","oldpassphrase",params[0],"newpassphrase",params[1])); } static char *walletlock(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","walletlock")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","walletlock")); } static char *encryptwallet(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","encryptwallet","passphrase",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","encryptwallet","passphrase",params[0])); } static char *checkwallet(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","checkwallet")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","checkwallet")); } static char *repairwallet(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","repairwallet")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","repairwallet")); } static char *backupwallet(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","backupwallet","filename",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","backupwallet","filename",params[0])); } // messages static char *signmessage(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","signmessage","address",params[0],"message",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","signmessage","address",params[0],"message",params[1])); } static char *verifymessage(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","verifymessage","address",params[0],"sig",params[1],"message",params[2])); + return(sglue3(0,myinfo,coin,remoteaddr,"bitcoinrpc","verifymessage","address",params[0],"sig",params[1],"message",params[2])); } // unspents static char *listunspent(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","listunspent","minconf",params[0],"maxconf",params[1])); + int32_t numrmds,minconf=0,maxconf=0,m = 0; uint8_t *rmdarray; cJSON *retjson; + retjson = cJSON_CreateArray(); + if ( (minconf= juint(params[0],0)) > 0 ) + { + m++; + if ( (maxconf= juint(params[1],0)) > 0 ) + m++; + } + if ( minconf == 0 ) + minconf = 1; + if ( maxconf == 0 ) + maxconf = 9999999; + rmdarray = iguana_rmdarray(coin,&numrmds,array,m); + iguana_unspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds); + if ( rmdarray != 0 ) + free(rmdarray); + return(jprint(retjson,1)); +// return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","listunspent","minconf",params[0],"maxconf",params[1])); } static char *lockunspent(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","lockunspent","flag",params[0],"array",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","lockunspent","flag",params[0],"array",params[1])); } static char *listlockunspent(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","listlockunspent")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","listlockunspent")); } static char *gettxout(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","gettxout","txid",params[0],"vout",params[1],"mempool",params[2])); + return(sglue3(0,myinfo,coin,remoteaddr,"bitcoinrpc","gettxout","txid",params[0],"vout",params[1],"mempool",params[2])); } static char *gettxoutsetinfo(RPCARGS) { - return(sglue(0,myinfo,coin,remoteaddr,"ramchain","gettxoutsetinfo")); + return(sglue(0,myinfo,coin,remoteaddr,"bitcoinrpc","gettxoutsetinfo")); } // payments static char *sendtoaddress(RPCARGS) { - return(sglue4(0,myinfo,coin,remoteaddr,"ramchain","sendtoaddress","address",params[0],"amount",params[1],"comment",params[2],"comment2",params[3])); + return(sglue4(0,myinfo,coin,remoteaddr,"bitcoinrpc","sendtoaddress","address",params[0],"amount",params[1],"comment",params[2],"comment2",params[3])); } static char *movecmd(RPCARGS) { - return(sglue5(0,myinfo,coin,remoteaddr,"ramchain","move","fromaccount",params[0],"toaccount",params[1],"amount",params[2],"minconf",params[3],"comment",params[4])); + return(sglue5(0,myinfo,coin,remoteaddr,"bitcoinrpc","move","fromaccount",params[0],"toaccount",params[1],"amount",params[2],"minconf",params[3],"comment",params[4])); } static char *sendfrom(RPCARGS) { - return(sglue6(0,myinfo,coin,remoteaddr,"ramchain","sendfrom","fromaccount",params[0],"toaddress",params[1],"amount",params[2],"minconf",params[3],"comment",params[4],"comment2",params[5])); + return(sglue6(0,myinfo,coin,remoteaddr,"bitcoinrpc","sendfrom","fromaccount",params[0],"toaddress",params[1],"amount",params[2],"minconf",params[3],"comment",params[4],"comment2",params[5])); } static char *sendmany(RPCARGS) { - return(sglue4(0,myinfo,coin,remoteaddr,"ramchain","sendmany","fromaccount",params[0],"payments",params[1],"minconf",params[2],"comment",params[3])); + return(sglue4(0,myinfo,coin,remoteaddr,"bitcoinrpc","sendmany","fromaccount",params[0],"payments",params[1],"minconf",params[2],"comment",params[3])); } static char *settxfee(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","settxfee","amount",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","settxfee","amount",params[0])); } // rawtransaction static char *getrawtransaction(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","getrawtransaction","txid",params[0],"verbose",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","getrawtransaction","txid",params[0],"verbose",params[1])); } static char *createrawtransaction(RPCARGS) { - return(sglue2(0,myinfo,coin,remoteaddr,"ramchain","createrawtransaction","vins",params[0],"vouts",params[1])); + return(sglue2(0,myinfo,coin,remoteaddr,"bitcoinrpc","createrawtransaction","vins",params[0],"vouts",params[1])); } static char *decoderawtransaction(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","decoderawtransaction","rawtx",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","decoderawtransaction","rawtx",params[0])); } static char *decodescript(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","decodescript","script",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","decodescript","script",params[0])); } static char *signrawtransaction(RPCARGS) { - return(sglue3(0,myinfo,coin,remoteaddr,"ramchain","signrawtransaction","rawtx",params[0],"vins",params[1],"privkeys",params[2])); + return(sglue3(0,myinfo,coin,remoteaddr,"bitcoinrpc","signrawtransaction","rawtx",params[0],"vins",params[1],"privkeys",params[2])); } static char *sendrawtransaction(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","sendrawtransaction","rawtx",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","sendrawtransaction","rawtx",params[0])); } static char *getrawchangeaddress(RPCARGS) { - return(sglue1(0,myinfo,coin,remoteaddr,"ramchain","getrawchangeaddress","account",params[0])); + return(sglue1(0,myinfo,coin,remoteaddr,"bitcoinrpc","getrawchangeaddress","account",params[0])); } #define true 1 @@ -574,13 +591,13 @@ int32_t is_bitcoinrpc(char *method,char *remoteaddr) return(-1); } -char *iguana_bitcoinrpc(struct supernet_info *myinfo,struct iguana_info *coin,char *method,cJSON *params[16],int32_t n,cJSON *json,char *remoteaddr) +char *iguana_bitcoinrpc(struct supernet_info *myinfo,struct iguana_info *coin,char *method,cJSON *params[16],int32_t n,cJSON *json,char *remoteaddr,cJSON *array) { int32_t i; for (i=0; i> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime; + script[n++] = SCRIPT_OP_CHECKLOCKTIMEVERIFY; + script[n++] = SCRIPT_OP_DROP; + return(n); +} + +int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp) +{ + int32_t i,plen; + script[n++] = 0x50 + vp->M; + for (i=0; iN; i++) + { + if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 ) + return(-1); + script[n++] = plen; + memcpy(&script[n],vp->signers[i].pubkey,plen); + n += plen; + } + script[n++] = 0x50 + vp->N; + script[n++] = SCRIPT_OP_CHECKMULTISIG; + calc_rmd160_sha256(p2sh_rmd160,script,n); + return(n); +} + +int32_t bitcoin_p2shscript(uint8_t *script,int32_t n,const uint8_t *p2shscript,const int32_t p2shlen) +{ + if ( p2shlen >= 0xfd ) + { + script[n++] = 0x4d; + script[n++] = (p2shlen & 0xff); + script[n++] = ((p2shlen >> 8) & 0xff); + } + else + { + script[n++] = 0x4c; + script[n++] = p2shlen; + } + memcpy(&script[n],p2shscript,p2shlen), n += p2shlen; + return(n); +} + +int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee) +{ + uint8_t addrtype,rmd160[20]; int32_t len; + *changep = 0; + if ( inputsatoshis >= (satoshis + txfee) ) + { + *changep = inputsatoshis - (satoshis + txfee); + if ( changeaddr != 0 && changeaddr[0] != 0 ) + { + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); + if ( addrtype == coin->chain->pubtype ) + len = bitcoin_standardspend(changescript,0,rmd160); + else if ( addrtype == coin->chain->p2shtype ) + len = bitcoin_standardspend(changescript,0,rmd160); + else + { + printf("error with mismatched addrtype.%02x vs (%02x %02x)\n",addrtype,coin->chain->pubtype,coin->chain->p2shtype); + return(-1); + } + return(len); + } + else printf("error no change address when there is change\n"); + } + return(-1); +} + +int32_t bitcoin_scriptsig(struct iguana_info *coin,uint8_t *script,int32_t n,const struct vin_info *vp,struct iguana_msgtx *msgtx) +{ + int32_t i,siglen; + if ( vp->N > 1 ) + script[n++] = SCRIPT_OP_NOP; + for (i=0; iN; i++) + { + if ( (siglen= vp->signers[i].siglen) != 0 ) + { + script[n++] = siglen; + memcpy(&script[n],vp->signers[i].sig,siglen), n += siglen; + } + } + if ( vp->type == IGUANA_SCRIPT_P2SH ) + { + printf("add p2sh script to sig\n"); + n = bitcoin_p2shscript(script,n,vp->p2shscript,vp->p2shlen); + } + return(n); +} + +int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime) +{ + // OP_IF + // OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + // OP_ELSE + // OP_HASH160 secret160 OP_EQUALVERIFY OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG // standard spend + // OP_ENDIF + uint8_t rmd160A[20],rmd160B[20],addrtypeA,addrtypeB; + bitcoin_addr2rmd160(&addrtypeA,rmd160A,senderaddr); + bitcoin_addr2rmd160(&addrtypeB,rmd160B,otheraddr); + script[n++] = SCRIPT_OP_IF; + n = bitcoin_checklocktimeverify(script,n,locktime); + n = bitcoin_standardspend(script,n,rmd160A); + script[n++] = SCRIPT_OP_ELSE; + n = bitcoin_revealsecret160(script,n,secret160); + n = bitcoin_standardspend(script,n,rmd160B); + script[n++] = SCRIPT_OP_ENDIF; + calc_rmd160_sha256(p2sh_rmd160,script,n); + bitcoin_address(ps2h_coinaddr,p2shtype,p2sh_rmd160,20); + return(n); +} + +int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi) +{ + uint8_t addrtype; char rmd160str[41],pubkeystr[256]; int32_t plen,i,m,n,flag = 0,scriptlen = 0; + m = n = 1; + if ( asmstr != 0 ) + asmstr[0] = 0; + if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH ) + { + if ( type == IGUANA_SCRIPT_P2SH ) + addrtype = coin->chain->p2shtype; + else addrtype = coin->chain->pubtype; + init_hexbytes_noT(rmd160str,rmd160,20); + bitcoin_address(coinaddr,addrtype,rmd160,20); + } + switch ( type ) + { + case IGUANA_SCRIPT_NULL: + if ( asmstr != 0 ) + strcpy(asmstr,txi == 0 ? "coinbase " : "PoSbase "); + flag++; + coinaddr[0] = 0; + break; + case IGUANA_SCRIPT_76AC: + if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) < 0 ) + return(0); + init_hexbytes_noT(pubkeystr,(uint8_t *)vp->signers[0].pubkey,plen); + if ( asmstr != 0 ) + sprintf(asmstr,"OP_DUP %s OP_CHECKSIG // %s",pubkeystr,coinaddr); + scriptlen = bitcoin_pubkeyspend(script,0,(uint8_t *)vp->signers[0].pubkey); + //printf("[%02x] scriptlen.%d (%s)\n",vp->signers[0].pubkey[0],scriptlen,asmstr); + break; + case IGUANA_SCRIPT_76A988AC: + if ( asmstr != 0 ) + sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr); + scriptlen = bitcoin_standardspend(script,0,rmd160); + break; + case IGUANA_SCRIPT_P2SH: + if ( asmstr != 0 ) + sprintf(asmstr,"OP_HASH160 %s OP_EQUAL // %s",rmd160str,coinaddr); + scriptlen = bitcoin_p2shspend(script,0,rmd160); + break; + case IGUANA_SCRIPT_OPRETURN: + if ( asmstr != 0 ) + strcpy(asmstr,"OP_RETURN "); + flag++; + break; + case IGUANA_SCRIPT_3of3: m = 3, n = 3; break; + case IGUANA_SCRIPT_2of3: m = 2, n = 3; break; + case IGUANA_SCRIPT_1of3: m = 1, n = 3; break; + case IGUANA_SCRIPT_2of2: m = 2, n = 2; break; + case IGUANA_SCRIPT_1of2: m = 1, n = 2; break; + case IGUANA_SCRIPT_MSIG: m = vp->M, n = vp->N; break; + case IGUANA_SCRIPT_DATA: + if ( asmstr != 0 ) + strcpy(asmstr,"DATA ONLY"); + flag++; + break; + case IGUANA_SCRIPT_STRANGE: + if ( asmstr != 0 ) + strcpy(asmstr,"STRANGE SCRIPT "); + flag++; + break; + default: break;//printf("unexpected script type.%d\n",type); break; + } + if ( n > 1 ) + { + scriptlen = bitcoin_MofNspendscript(rmd160,script,0,vp); + if ( asmstr != 0 ) + { + sprintf(asmstr,"%d ",m); + for (i=0; isigners[i].pubkey)) > 0 ) + { + init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->signers[i].pubkey,plen); + if ( asmstr != 0 ) + strcat(asmstr," "); + } + else if ( asmstr != 0 ) + strcat(asmstr,"NOPUBKEY "); + sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n); + for (i=0; isigners[i].coinaddr,ispendlen > 0 ) + init_hexbytes_noT(asmstr + strlen(asmstr),(uint8_t *)vp->spendscript,vp->spendlen); + *Mp = m, *nump = n; + return(scriptlen); +} + +int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen) +{ + asmstr[0] = 0; + return(0); +} + +int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) +{ + static uint8_t zero_rmd160[20]; + char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen; + vp->N = 1; + vp->M = 1; + type = IGUANA_SCRIPT_STRANGE; + if ( vp->spendlen == 0 ) + { + if ( zero_rmd160[0] == 0 ) + { + calc_rmd160_sha256(zero_rmd160,vp->spendscript,vp->spendlen); + //vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + //calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb + init_hexbytes_noT(hexstr,zero_rmd160,20); + char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr); + } + memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_NULL); + } + else if ( vp->spendscript[0] == SCRIPT_OP_RETURN ) + type = IGUANA_SCRIPT_OPRETURN; + else if ( vp->spendscript[0] == SCRIPT_OP_DUP && vp->spendscript[1] == SCRIPT_OP_HASH160 && vp->spendscript[2] == 20 && vp->spendscript[vp->spendscript[2]+3] == SCRIPT_OP_EQUALVERIFY && vp->spendscript[vp->spendscript[2]+4] == SCRIPT_OP_CHECKSIG ) + { + //printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d vp->spendlen\n",vp->spendscript[2]+4,vp->spendlen); + // 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac + memcpy(vp->rmd160,&vp->spendscript[3],20); + if ( (plen= vp->spendscript[2]+5) != vp->spendlen ) + { + return(IGUANA_SCRIPT_STRANGE); + while ( plen < vp->spendlen ) + if ( vp->spendscript[plen++] != 0x61 ) // nop + return(IGUANA_SCRIPT_STRANGE); + } + return(IGUANA_SCRIPT_76A988AC); + } + // 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac + else if ( vp->spendscript[0] > 0 && vp->spendscript[0] < 76 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == vp->spendlen-2 && bitcoin_pubkeylen(&vp->spendscript[1]) > 0 ) + { + memcpy(vp->signers[0].pubkey,&vp->spendscript[1],vp->spendscript[0]); + calc_rmd160_sha256(vp->rmd160,vp->signers[0].pubkey,vp->spendscript[0]); + return(IGUANA_SCRIPT_76AC); + } + else if ( vp->spendscript[0] == SCRIPT_OP_HASH160 && vp->spendscript[1] == 0x14 && vp->spendlen == 23 && vp->spendscript[22] == SCRIPT_OP_EQUAL ) + { + memcpy(vp->rmd160,vp->spendscript+2,20); + return(IGUANA_SCRIPT_P2SH); + } + else if ( vp->spendlen > 34 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKMULTISIG && (n= vp->spendscript[vp->spendlen-2]) >= 0x51 && n <= 0x60 && (m= vp->spendscript[0]) >= 0x51 && m <= n ) // m of n multisig + { + m -= 0x50, n -= 0x50; + script = vp->spendscript+1; + for (i=0; isigners[i].pubkey,script,plen); + calc_rmd160_sha256(vp->signers[i].rmd160,vp->signers[i].pubkey,plen); + bitcoin_address(vp->signers[i].coinaddr,coin->chain->pubtype,vp->signers[i].pubkey,plen); + } + if ( (int32_t)((long)script - (long)vp->spendscript) == vp->spendlen-2 ) + { + vp->N = n; + vp->M = m; + //printf("M.%d N.%d\n",m,n); + } + calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); + if ( n == 3 ) + { + if ( m == 3 ) + return(IGUANA_SCRIPT_3of3); + else if ( m == 2 ) + return(IGUANA_SCRIPT_2of3); + else if ( m == 1 ) + return(IGUANA_SCRIPT_1of3); + } + else if ( n == 2 ) + { + if ( m == 2 ) + return(IGUANA_SCRIPT_2of2); + else if ( m == 1 ) + return(IGUANA_SCRIPT_1of2); + } + //printf("strange msig M.%d of N.%d\n",m,n); + return(IGUANA_SCRIPT_MSIG); + } + else if ( vp->spendlen == vp->spendscript[0]+1 ) + { + //printf("just data.%d\n",vp->spendlen); + memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160)); + return(IGUANA_SCRIPT_DATA); + } + if ( type != IGUANA_SCRIPT_OPRETURN && type != IGUANA_SCRIPT_DATA ) + { + if ( vp->spendlen > 0 && vp->spendlen < sizeof(hexstr)/2-1 ) + { + static FILE *fp; + init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen); + //char str[65]; printf("unparsed script.(%s).%d in %s len.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen); + if ( 1 && fp == 0 ) + fp = fopen("unparsed.txt","w"); + if ( fp != 0 ) + fprintf(fp,"%s\n",hexstr), fflush(fp); + } else sprintf(hexstr,"pkscript overflowed %ld\n",(long)sizeof(hexstr)); + } + calc_rmd160_sha256(vp->rmd160,vp->spendscript,vp->spendlen); + return(type); +} + +int32_t iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence) +{ + int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; char asmstr[IGUANA_MAXSCRIPTSIZE*3]; + memset(vp,0,sizeof(*vp)); + vp->vin.prev_hash = debugtxid, vp->vin.prev_vout = vout; + vp->spendlen = pk_scriptlen; + vp->vin.sequence = sequence; + memcpy(vp->spendscript,pk_script,pk_scriptlen); + if ( (vp->type= _iguana_calcrmd160(coin,vp)) >= 0 && 0 ) + { + scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vout); + if ( scriptlen != pk_scriptlen || (scriptlen != 0 && memcmp(script,pk_script,scriptlen) != 0) ) + { + if ( vp->type != IGUANA_SCRIPT_OPRETURN && vp->type != IGUANA_SCRIPT_DATA && vp->type != IGUANA_SCRIPT_STRANGE ) + { + int32_t i; + printf("\n--------------------\n"); + for (i=0; itype,scriptlen,pk_scriptlen); + } + } + } + return(vp->type); +} + +//error memalloc mem.0x7f6fc6e4a2a8 94.242.229.158 alloc 1 used 2162688 totalsize.2162688 -> 94.242.229.158 (nil) + +int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *suffixp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) +{ + char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; + j = n = 0; + *suffixp = *pubkeysizep = 0; + *hashtypep = SIGHASH_ALL; + while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) + { + vp->signers[j].siglen = siglen; + memcpy(vp->signers[j].sig,&scriptsig[n+1],siglen); + if ( j == 0 ) + *hashtypep = vp->signers[j].sig[siglen-1]; + else if ( vp->signers[j].sig[siglen-1] != *hashtypep ) + { + //printf("SIGHASH.%d mismatch %d vs %d\n",j,vp->signers[j].sig[siglen-1],*hashtypep); + break; + } + (*sigsizep) += siglen; + //printf("sigsize %d [%02x]\n",*sigsizep,vp->signers[j].sig[siglen-1]); + n += (siglen + 1); + j++; + if ( spendtype == 0 && j > 1 ) + spendtype = IGUANA_SCRIPT_MSIG; + } + vp->numsigs = j; + vp->type = spendtype; + if ( j == 0 ) + { + *suffixp = len; + vp->spendlen = len; + return(vp->spendlen); + } + j = 0; + while ( ((plen= scriptsig[n]) == 33 || plen == 65) && j < 16 && plen+n <= len ) + { + memcpy(vp->signers[j].pubkey,&scriptsig[n+1],plen); + calc_rmd160_sha256(vp->signers[j].rmd160,vp->signers[j].pubkey,plen); + if ( j == 0 ) + memcpy(vp->rmd160,vp->signers[j].rmd160,20); + n += (plen + 1); + (*pubkeysizep) += plen; + j++; + } + vp->numpubkeys = j; + if ( n+2 < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) + { + if ( scriptsig[n] == 0x4c ) + vp->p2shlen = scriptsig[n+1], n += 2; + else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; + //printf("p2sh opcode.%02x %02x %02x scriptlen.%d\n",scriptsig[n],scriptsig[n+1],scriptsig[n+2],vp->p2shlen); + if ( vp->p2shlen < IGUANA_MAXSCRIPTSIZE && n+vp->p2shlen <= len ) + { + memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); + n += vp->p2shlen; + vp->type = IGUANA_SCRIPT_P2SH; + } else vp->p2shlen = 0; + } + if ( n < len ) + *suffixp = (len - n); + /*if ( len == 0 ) + { + // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1 + decode_hex(vp->rmd160,20,"010966776006953d5567439e5e39f86a0d273bee");//3564a74f9ddb4372301c49154605573d7d1a88fe"); + vp->type = IGUANA_SCRIPT_76A988AC; + }*/ + vp->spendlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,vp->spendscript,asmstr,vp->rmd160,vp->type,(const struct vin_info *)vp,vp->vin.prev_vout); + //printf("type.%d asmstr.(%s) spendlen.%d\n",vp->type,asmstr,vp->spendlen); + return(vp->spendlen); +} + +int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen) +{ + int32_t hashtype; + *sigsizep = *pubkeysizep = *p2shsizep = *suffixp = 0; + memset(vp,0,sizeof(*vp)); + if ( bitcoin_scriptget(coin,&hashtype,sigsizep,pubkeysizep,suffixp,vp,vinscript,scriptlen,0) < 0 ) + { + printf("iguana_vinscriptparse: error parsing vinscript?\n"); + return(-1); + } + if ( vp->type == IGUANA_SCRIPT_P2SH ) + { + *p2shsizep = vp->p2shlen + 1 + (vp->p2shlen >= 0xfd)*2; + //printf("P2SHSIZE.%d\n",*p2shsizep); + } + return(hashtype); +} + +char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33) +{ + int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; struct vin_info V,*vp = &V; + memset(vp,0,sizeof(*vp)); + scriptstr[0] = asmstr[0] = 0; + if ( pubkey33 != 0 && bitcoin_pubkeylen(pubkey33) > 0 ) + memcpy(vp->signers[0].pubkey,pubkey33,33); + scriptlen = iguana_scriptgen(coin,&vp->M,&vp->N,vp->coinaddr,script,asmstr,rmd160,type,(const struct vin_info *)vp,vout); + init_hexbytes_noT(scriptstr,script,scriptlen); + return(scriptstr); +} + + +#ifdef later + +uint32_t iguana_ramchain_pubkeyoffset(struct iguana_info *coin,RAMCHAIN_FUNC,int32_t createflag,uint32_t *pkindp,uint32_t *scriptoffsetp,uint8_t *pubkey,uint8_t rmd160[20]) +{ + uint32_t pkind; int32_t plen; struct iguana_kvitem *ptr; + if ( (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) + { + if ( createflag != 0 ) + { + //printf("from pubkeyoffset\n"); + pkind = iguana_ramchain_addpkhash(coin,RAMCHAIN_ARG,rmd160,0,0,0); + //int32_t i; for (i=0; i<33; i++) + // printf("%02x",pubkey[i]); + //printf(" pkind.%d created from pubkeyoffset\n",pkind); + *pkindp = pkind + 1; + } else return(0); + } else pkind = ptr->hh.itemind; + if ( P[pkind].pubkeyoffset == 0 ) + { + plen = bitcoin_pubkeylen(pubkey); + if ( plen > 0 ) + { + if ( *scriptoffsetp == 0 ) + *scriptoffsetp++ = 0; + P[pkind].pubkeyoffset = *scriptoffsetp, *scriptoffsetp += plen; + // printf(" plen.%d -> new offset.%d\n",plen,*scriptoffsetp); + memcpy(&Kspace[P[pkind].pubkeyoffset],pubkey,plen); + } + else + { + //int32_t i; for (i=0; iscriptoffset]; uint32_t poffset; int32_t totalsize,sigslen,plen,stacksize=0,p2shlen=0,scriptlen = 0; + if ( s->scriptoffset == 0 ) + { + //printf("iguana_vinscriptdecode: null scriptoffset\n"); + return(0); + } + len += iguana_rwvarint32(0,&metascript[len],(void *)&totalsize); + *metalenp = 0; + if ( s->rawmode != 0 ) + { + *metalenp = 0; + if ( totalsize < IGUANA_MAXSCRIPTSIZE ) + { + //printf("rawmode.%d\n",totalsize); + memcpy(_script,&metascript[len],totalsize); + return(totalsize); + } + printf("illegal rawmode vinscript totalsize.%d\n",totalsize); + return(-1); + } + if ( totalsize > IGUANA_MAXSCRIPTSIZE ) + { + fprintf(stderr,"totalsize too big %d\n",totalsize); + return(0); + } + // expand metascript!! + totalsize += len; + len += iguana_rwvarint32(0,&metascript[len],(void *)&sigslen); + //printf("totalsize %d, len %d sigslen %d numpubs.%d p2sh.%d\n",totalsize,len,sigslen,s->numpubkeys,s->p2sh); + if ( sigslen > 0 && sigslen < 74*16 ) + { + len += iguana_rwvarint32(0,&metascript[len],(void *)&stacksize); + if ( ramchain->sigsfileptr != 0 && stacksize < ramchain->sigsfilesize ) + memcpy(&_script[scriptlen],(void *)((long)ramchain->sigsfileptr + ramchain->sigsfilesize - stacksize),sigslen); + else + { + diff = (long)Kstackend - (long)Kspace; + if ( stacksize < diff ) + memcpy(&_script[scriptlen],&Kspace[diff - stacksize],sigslen); + } + scriptlen += sigslen; + } + if ( s->numpubkeys > 0 ) + { + for (i=0; inumpubkeys; i++) + { + len += iguana_rwvarint32(0,&metascript[len],(void *)&poffset); + if ( poffset > ramchain->H.data->scriptspace-33 ) + { + printf("illegal poffset.%d/%d\n",poffset,ramchain->H.data->scriptspace); + return(-1); + } + //printf("poffset[%d] of %d poffset %x\n",i,s->numpubkeys,poffset); + pubkey = &Kspace[poffset]; + if ( (plen= bitcoin_pubkeylen(pubkey)) <= 0 ) + { + /*int32_t j; + for (j=0; jnumpubkeys,s->numsigs);*/ + *metalenp = len; + return(scriptlen); + } + else + { + _script[scriptlen++] = plen; + //printf("plen.%d\n",i); + memcpy(&_script[scriptlen],pubkey,plen), scriptlen += plen; + } + } + } + if ( s->p2sh != 0 ) + { + len += iguana_rwvarint32(0,&metascript[len],(void *)&p2shlen); + if ( p2shlen > 0 && p2shlen < IGUANA_MAXSCRIPTSIZE ) + { + if ( p2shlen <= 75 ) + _script[scriptlen++] = 0x4c, _script[scriptlen++] = p2shlen; + else _script[scriptlen++] = 0x4d, _script[scriptlen++] = p2shlen & 0xff, _script[scriptlen++] = (p2shlen>>8) & 0xff; + //printf("p2shlen.%d\n",p2shlen); + memcpy(&_script[scriptlen],&metascript[len],p2shlen), scriptlen += p2shlen, len += p2shlen; + } + } + if ( (suffixlen= (totalsize - len)) != 0 ) + { + if ( suffixlen < 0 || suffixlen >= IGUANA_MAXSCRIPTSIZE ) + printf("suffixlen.%d totalsize.%d vs len.%d\n",suffixlen,totalsize,len); + else memcpy(&_script[scriptlen],&metascript[len],suffixlen), scriptlen += suffixlen, len += suffixlen; + } + *metalenp = len - 1 - (len>=0xfd ? 2 : 0); + return(scriptlen); +} + +int32_t iguana_vinscriptencode(struct iguana_info *coin,int32_t *metalenp,uint8_t *Kstackend,uint32_t stacksize,uint8_t *Kspace,uint32_t scriptoffset,struct iguana_spend *s,uint8_t *sigsbuf,int32_t sigslen,uint32_t *poffsets,uint8_t *p2shscript,int32_t p2shlen,uint8_t *suffix,int32_t suffixlen) +{ + int32_t i,len = 0; long diff; uint8_t metascript[IGUANA_MAXSCRIPTSIZE]; uint32_t origoffset = scriptoffset; + *metalenp = 0; + //printf("vinencode[%d] <- stacksize.%d sigslen.%d numsigs.%d numpubs.%d p2shlen.%d suffixlen.%d\n",scriptoffset,stacksize,sigslen,s->numsigs,s->numpubkeys,p2shlen,suffixlen); + if ( sigslen == 0 && s->numpubkeys == 0 && p2shlen == 0 && suffixlen == 0 ) + { + printf("spendencode: null script??\n"); + return(0); + } + len += iguana_rwvarint32(1,&metascript[len],(void *)&sigslen); + if ( sigslen > 0 ) + { + diff = (long)Kstackend - (long)Kspace; + if ( diff < stacksize ) + { + printf("vinscriptencode error diff.%ld < stacksize.%u\n",diff,stacksize); + return(0); + } + memcpy(&Kspace[diff - stacksize],sigsbuf,sigslen); + //printf("Kspace.%p Kstackend.%p diff.%ld stacksize.%d sigsbuf.%p sigslen.%d [%02x]\n",Kspace,Kstackend,diff,stacksize,sigsbuf,sigslen,Kspace[diff - stacksize + sigslen - 1]); + for (i=0; i %p stacksize.%d\n",len,&Kspace[diff - stacksize],stacksize); + } + if ( s->numpubkeys > 0 ) + { + //printf("metalen.%d\n",len); + for (i=0; inumpubkeys; i++) + { + len += iguana_rwvarint32(1,&metascript[len],&poffsets[i]); + //printf("EMIT pubkey poffsets.[%x] len.%d\n",poffsets[0],len); + } + } + if ( p2shlen != 0 ) + { + len += iguana_rwvarint32(1,&metascript[len],(void *)&p2shlen); + memcpy(&metascript[len],p2shscript,p2shlen), len += p2shlen; + } + if ( suffixlen > 0 && suffixlen < IGUANA_MAXSCRIPTSIZE ) + { + //printf("[%d] <- SUFFIX.(%02x) len.%d\n",len,suffix[0],suffixlen); + memcpy(&metascript[len],suffix,suffixlen), len += suffixlen; + } + scriptoffset += iguana_rwvarint32(1,&Kspace[scriptoffset],(void *)&len); + memcpy(&Kspace[scriptoffset],metascript,len); + //for (i=0; i 0 && vinscriptlen < IGUANA_MAXSCRIPTSIZE ) + { + memset(&V,0,sizeof(V)); + if ( rawflag == 0 ) + { + s->sighash = iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vinscript,vinscriptlen); + //for (i=0; i<33; i++) + // printf("%02x",V.signers[0].pubkey[i]); + //printf(" parsed pubkey0\n"); + //for (i=0; i<20; i++) + // printf("%02x",V.signers[0].rmd160[i]); + //printf(" parsed rmd160_0\n"); + memset(sigsbuf,0,sizeof(sigsbuf)); + memset(poffsets,0,sizeof(poffsets)); + for (i=sigslen=0; i 0 ) + { + sigsbuf[sigslen++] = V.signers[i].siglen; + memcpy(&sigsbuf[sigslen],V.signers[i].sig,V.signers[i].siglen); + sigslen += V.signers[i].siglen; + } + } + for (i=0; ipkind,&ramchain->H.scriptoffset,V.signers[i].pubkey,V.signers[i].rmd160)) == 0 ) + { + //printf("addspend: error couldnt get pubkeyoffset\n"); + return(-1); + } //else printf("poffset[%d] <- 0x%x (%02x %02x)\n",i,poffsets[i],Kspace[poffsets[i]],Kspace[poffsets[i]+32]); + } + } + s->numsigs = V.numsigs; + s->numpubkeys = V.numpubkeys; + if ( p2shsize != 0 ) + s->p2sh = 1; + suffix = &vinscript[vinscriptlen-suffixlen]; + if ( sigslen+V.numsigs+V.numpubkeys+suffixlen != 0 ) + { + ramchain->H.stacksize += sigslen; + s->scriptoffset = ramchain->H.scriptoffset; + len = iguana_vinscriptencode(coin,&metalen,&Kspace[ramchain->H.data->scriptspace],ramchain->H.stacksize,Kspace,ramchain->H.scriptoffset,s,sigsbuf,sigslen,poffsets,V.p2shscript,V.p2shlen,suffix,suffixlen); + } else printf("sigslen.%d numsigs.%d numpubs.%d suffixlen.%d\n",sigslen,V.numsigs,V.numpubkeys,suffixlen); + } + else + { + metalen = sigslen = 0; + s->sighash = s->numsigs = s->numpubkeys = s->p2sh = 0; + suffix = vinscript; + suffixlen = vinscriptlen; + //for (i=0; iscriptoffset = ramchain->H.scriptoffset; + s->rawmode = 1; + ramchain->H.scriptoffset += iguana_rwvarint32(1,&Kspace[s->scriptoffset],(void *)&vinscriptlen); + memcpy(&Kspace[ramchain->H.scriptoffset],vinscript,vinscriptlen); + ramchain->H.scriptoffset += vinscriptlen; + } + } + //printf("checklen.%d scriptoffset.%d\n",checklen,ramchain->H.scriptoffset); + if ( (decodelen= iguana_vinscriptdecode(coin,ramchain,&checkmetalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) || checkmetalen != metalen ) + { + //static uint64_t counter; + //if ( counter++ < 100 ) + { + for (i=0; iH.stacksize -= sigslen; + return(-1); + } //else s->coinbase = 1;//, printf("vin reconstructed metalen.%d vinlen.%d\n",metalen,checklen); + ramchain->H.scriptoffset += len; + return(metalen); +} + +int32_t iguana_scriptspaceraw(struct iguana_info *coin,int32_t *scriptspacep,int32_t *sigspacep,int32_t *pubkeyspacep,struct iguana_msgtx *txarray,int32_t txn_count) +{ + uint32_t i,j,sigspace,suffixlen,scriptspace,pubkeyspace,p2shspace,p2shsize,sigsize,pubkeysize,type,scriptlen; //struct iguana_spend256 *s; struct iguana_unspent20 *u; + struct iguana_msgtx *tx; struct vin_info V; uint8_t rmd160[20],scriptdata[IGUANA_MAXSCRIPTSIZE]; char asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; + return(1); + for (i=sigspace=scriptspace=pubkeyspace=p2shspace=0; itx_out; j++) + { + memset(&V,0,sizeof(V)); + type = iguana_calcrmd160(coin,&V,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,0xffffffff); + if ( type != 0 ) // IGUANA_SCRIPT_NULL + { + memcpy(rmd160,V.rmd160,sizeof(rmd160)); + memset(&V,0,sizeof(V)); + scriptlen = iguana_scriptgen(coin,&V.M,&V.N,V.coinaddr,scriptdata,asmstr,rmd160,type,(const struct vin_info *)&V,j); + if ( (scriptlen != tx->vouts[j].pk_scriptlen || (scriptdata != 0 && memcmp(scriptdata,tx->vouts[j].pk_script,scriptlen) != 0)) ) //tx->vouts[j].pk_scriptlen > sizeof(u->script) && + { + scriptspace += tx->vouts[j].pk_scriptlen; + //printf("type.%d scriptspace.%d <= %d + 2\n",type,scriptspace,tx->vouts[j].pk_scriptlen); + } + } + } + for (j=0; jtx_in; j++) + { + iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,tx->vins[j].vinscript,tx->vins[j].scriptlen); + pubkeyspace += pubkeysize; + p2shspace += p2shsize; + //if ( tx->vins[j].scriptlen > sizeof(s->vinscript) ) + sigspace += tx->vins[j].scriptlen; + } + } + *scriptspacep = scriptspace + p2shspace, *sigspacep = sigspace, *pubkeyspacep = pubkeyspace; + return(scriptspace + sigspace); +} + +int32_t iguana_ramchain_scriptspace(struct iguana_info *coin,int32_t *sigspacep,int32_t *pubkeyspacep,struct iguana_ramchain *ramchain) +{ + RAMCHAIN_DECLARE; + int32_t j,scriptlen; struct vin_info V; + uint32_t sequence,p2shspace,altspace,sigspace,pubkeyspace,spendind,unspentind,p2shsize,pubkeysize,sigsize,scriptspace,suffixlen; + struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t *scriptdata; + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + *sigspacep = *pubkeyspacep = altspace = 0; + return(1); + if ( (rdata= ramchain->H.data) == 0 || ramchain->expanded != 0 ) + { + printf("iguana_ramchain_scriptspace cant iterate without data and requires simple ramchain\n"); + return(-1); + } + sigspace = pubkeyspace = p2shspace = 0; + scriptspace = 1; + for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) + { + tx = &T[ramchain->H.txidind]; + for (j=0; jnumvouts; j++) + { + if ( (unspentind= ramchain->H.unspentind++) < rdata->numunspents ) + if ( U[unspentind].scriptlen != 0 ) + scriptspace += U[unspentind].scriptlen + 3; + } + for (j=0; jnumvins; j++) + {break; + if ( (spendind= ramchain->H.spendind++) < rdata->numspends ) + { + sequence = S[spendind].sequenceid; + scriptlen = S[spendind].vinscriptlen; + if ( S[spendind].scriptoffset != 0 && S[spendind].scriptoffset+scriptlen < ramchain->H.data->scriptspace ) + { + scriptdata = &Kspace[S[spendind].scriptoffset]; + altspace += scriptlen; + if ( scriptdata != 0 ) + { + iguana_vinscriptparse(coin,&V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,scriptdata,scriptlen); + p2shspace += p2shsize; + sigspace += sigsize; + pubkeyspace += pubkeysize; + sigspace += suffixlen; + // fprintf(stderr,"(%d %d %d %d).%d ",sigsize,pubkeysize,p2shsize,suffixlen,scriptlen); + } //else fprintf(stderr,"(none)" ); + } + } + } + //altspace += tx->numvins * 16 + 128; // for metascripts + //scriptspace += tx->numvins * 16 + 128; // for metascripts + //fprintf(stderr,"scriptspace.%u altspace.%u, ",scriptspace,altspace); + } + *sigspacep = sigspace, *pubkeyspacep = pubkeyspace; + //printf("altspace.%d numvouts.%d numvins.%d scriptspace.%d p2shspace.%d sigspace.%d pubkeyspace.%d\n",altspace,tx->numvouts,tx->numvins,scriptspace,p2shspace,sigspace,pubkeyspace); + return(scriptspace + p2shspace); +} + +uint32_t iguana_ramchain_scriptencode(struct iguana_info *coin,uint8_t *Kspace,uint32_t *offsetp,int32_t type,uint8_t *script,int32_t scriptlen,uint32_t *pubkeyoffsetp) +{ + uint32_t uoffset,offset = *offsetp,pubkeyoffset = *pubkeyoffsetp; int32_t plen; + if ( type == IGUANA_SCRIPT_76AC ) + { + plen = bitcoin_pubkeylen(script+1); + /*if ( plen <= 0 ) + { + char buf[1025]; + buf[0] = 0; + for (i=0; i<33; i++) + sprintf(buf+strlen(buf),"%02x",script[1+i]); + printf("%s pubkey -> pubkeyoffset.%d offset.%d plen.%d\n",buf,pubkeyoffset,offset,plen); + }*/ + if ( plen > 0 ) + { + if ( pubkeyoffset == 0 ) + { + if ( offset == 0 ) + offset = 1; + *pubkeyoffsetp = pubkeyoffset = offset; + memcpy(&Kspace[pubkeyoffset],script+1,plen); + offset += plen; + *offsetp = offset; + return(0); + } + if ( memcmp(script+1,&Kspace[pubkeyoffset],plen) != 0 ) + { + /*for (i=-1; i<=plen; i++) + printf("%02x",script[1+i]); + printf(" script arg\n"); + for (i=0; iH.scriptoffset; + if ( type != IGUANA_SCRIPT_STRANGE && type != IGUANA_SCRIPT_DATA && type != IGUANA_SCRIPT_OPRETURN && scriptlen > 0 && script != 0 ) + { + if ( Kspace != 0 && ramchain->H.scriptoffset+scriptlen+3 <= ramchain->H.data->scriptspace-ramchain->H.stacksize ) + { + if ( (u->scriptoffset= iguana_ramchain_scriptencode(coin,Kspace,&ramchain->H.scriptoffset,type,script,scriptlen,&pubkeyoffset)) > 0 || type == IGUANA_SCRIPT_76AC ) + { + fprintf(stderr,"new offset.%d from scriptlen.%d pubkeyoffset.%d\n",ramchain->H.scriptoffset,scriptlen,pubkeyoffset); + } + //printf("[%d] u%d offset.%u len.%d\n",hdrsi,unspentind,u->scriptoffset,scriptlen); + } else printf("[%d] u%d Kspace.%p scriptspace overflow! %d + %d vs space.%d - stack.%d\n",hdrsi,unspentind,Kspace,ramchain->H.scriptoffset,scriptlen,ramchain->H.data->scriptspace,ramchain->H.stacksize); + checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspace,u->type,_script,u->scriptoffset,P[pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[pkind].pubkeyoffset : 0); + if ( checklen != scriptlen || (script != 0 && checkscript != 0 && memcmp(checkscript,script,scriptlen) != 0) ) + { + //printf("create script mismatch len.%d vs %d or cmp error.%d\n",scriptlen,checklen,(script!=0&&checkscript!=0)?memcmp(checkscript,script,scriptlen):0); + type = IGUANA_SCRIPT_STRANGE; + } //else printf("RO spendscript match.%d\n",scriptlen); + } + if ( type == IGUANA_SCRIPT_DATA || type == IGUANA_SCRIPT_OPRETURN || type == IGUANA_SCRIPT_STRANGE ) + { + if ( script != 0 && scriptlen > 0 ) + { + u->scriptoffset = origoffset; + origoffset += iguana_rwvarint32(1,&Kspace[origoffset],(void *)&scriptlen); + memcpy(&Kspace[origoffset],script,scriptlen); + ramchain->H.scriptoffset = origoffset + scriptlen; + } + } + else if ( type == IGUANA_SCRIPT_76AC && pubkeyoffset != 0 && P[pkind].pubkeyoffset == 0 ) + P[pkind].pubkeyoffset = pubkeyoffset;*/ + +#endif diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index c50d9cf6a..9f2deb2d5 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -24,7 +24,7 @@ void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i) { - struct iguana_spend *s,*S; uint32_t spendind; struct iguana_bundle *bp; + struct iguana_spend *s,*S; uint32_t spendind,unspentind; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; struct iguana_txid *T; bits256 *X; memset(vin,0,sizeof(*vin)); if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) @@ -34,10 +34,13 @@ void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin T = (void *)(long)((long)rdata + rdata->Toffset); spendind = (tx->firstvin + i); s = &S[spendind]; - if ( s->diffsequence == 0 ) + if ( s->sequenceid == 1 ) vin->sequence = 0xffffffff; + else if ( s->sequenceid == 2 ) + vin->sequence = 0xfffffffe; + else vin->sequence = 0; vin->prev_vout = s->prevout; - iguana_ramchain_spendtxid(coin,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); + iguana_ramchain_spendtxid(coin,&unspentind,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); } } diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c new file mode 100755 index 000000000..5fa71c192 --- /dev/null +++ b/iguana/iguana_unspents.c @@ -0,0 +1,489 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "iguana777.h" +#include "exchanges/bitcoin.h" + +struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *balancep,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) +{ + uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_account *ACCTS; + *balancep = 0; + *ramchainp = 0; + *lastunspentindp = 0; + for (i=firsti; ibundlescount&&i<=endi; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + ramchain = &bp->ramchain; + if ( ramchain->H.data != 0 ) + { + PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); + P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); + ACCTS = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Aoffset); + if ( (pkind= iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,0)) > 0 && pkind < ramchain->H.data->numpkinds ) + { + *ramchainp = ramchain; + *balancep = ACCTS[pkind].total; + *lastunspentindp = ACCTS[pkind].lastind; + *p = P[pkind]; + return(p); + } //else printf("not found pkind.%d vs num.%d\n",pkind,ramchain->H.data->numpkinds); + } else printf("%s.[%d] error null ramchain->H.data\n",coin->symbol,i); + } + } + return(0); +} + +char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi) +{ + uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; cJSON *retjson; char rmdstr[41]; + if ( (bp= coin->bundles[hdrsi]) != 0 ) + { + ramchain = &bp->ramchain; + if ( ramchain->H.data != 0 ) + { + retjson = cJSON_CreateArray(); + PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); + P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); + for (pkind=0; pkindH.data->numpkinds; pkind++,P++) + { + init_hexbytes_noT(rmdstr,P->rmd160,20); + jaddistr(retjson,rmdstr); + } + return(jprint(retjson,1)); + } + //iguana_bundleQ(coin,bp,bp->n); + return(clonestr("{\"error\":\"no bundle data\"}")); + } return(clonestr("{\"error\":\"no bundle\"}")); +} + +struct iguana_bundle *iguana_spent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spend_hdrsi,struct iguana_spend *s) +{ + int32_t prev_vout,height,hdrsi; uint32_t sequenceid,unspentind; char str[65]; + struct iguana_bundle *spentbp=0; struct iguana_txid *T,TX,*tp; bits256 *X; bits256 prev_hash; + X = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Xoffset); + T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + sequenceid = s->sequenceid; + hdrsi = spend_hdrsi; + *unspentindp = 0; + memset(prevhashp,0,sizeof(*prevhashp)); + if ( s->prevout < 0 ) + { + //printf("n.%d coinbase at spendind.%d firstvin.%d -> firstvout.%d -> unspentind\n",m,spendind,nextT->firstvin,nextT->firstvout); + //nextT++; + //m++; + return(0); + } + else + { + prev_vout = s->prevout; + iguana_ramchain_spendtxid(coin,&unspentind,&prev_hash,T,ramchain->H.data->numtxids,X,ramchain->H.data->numexternaltxids,s); + *prevhashp = prev_hash; + *unspentindp = unspentind; + if ( unspentind == 0 ) + { + if ( (tp= iguana_txidfind(coin,&height,&TX,prev_hash,spend_hdrsi-1)) != 0 ) + { + *unspentindp = unspentind = TX.firstvout + ((prev_vout > 0) ? prev_vout : 0); + hdrsi = height / coin->chain->bundlesize; + //printf("%s height.%d firstvout.%d prev.%d ->U%d\n",bits256_str(str,prev_hash),height,TX.firstvout,prev_vout,unspentind); + } + else + { + printf("cant find prev_hash.(%s) for bp.[%d]\n",bits256_str(str,prev_hash),spend_hdrsi); + } + } + } + if ( hdrsi > spend_hdrsi || (spentbp= coin->bundles[hdrsi]) == 0 ) + printf("illegal hdrsi.%d when [%d] spentbp.%p\n",hdrsi,spend_hdrsi,spentbp);//, getchar(); + //else if ( spentbp->ramchain.spents[unspentind].ind != 0 || hdrsi < 0 ) + // printf("DOUBLE SPEND? U%d %p bp.[%d] unspentind.%u already has %u, no room\n",unspentind,&spentbp->ramchain.spents[unspentind],hdrsi,unspentind,spentbp->ramchain.spents[unspentind].ind);//, getchar(); + else if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) + printf("illegal unspentind.%d vs max.%d spentbp.%p[%d]\n",unspentind,spentbp->ramchain.H.data->numunspents,spentbp,hdrsi);//, getchar(); + else return(spentbp); + return(0); +} + +cJSON *iguana_unspentjson(struct iguana_info *coin,int32_t hdrsi,uint32_t unspentind,struct iguana_txid *T,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33) +{ + /*{ + "txid" : "d54994ece1d11b19785c7248868696250ab195605b469632b7bd68130e880c9a", + "vout" : 1, + "address" : "mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe", + "account" : "test label", + "scriptPubKey" : "76a9140dfc8bafc8419853b34d5e072ad37d1a5159f58488ac", + "amount" : 0.00010000, + "confirmations" : 6210, + "spendable" : true + },*/ + //struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; uint16_t hdrsi:12,type:4,vout; } __attribute__((packed)); + struct iguana_waccount *wacct; struct iguana_txid TX; int32_t height,ind; char scriptstr[8192],asmstr[sizeof(scriptstr)+1024]; cJSON *item; + item = cJSON_CreateObject(); + jaddbits256(item,"txid",T[up->txidind].txid); + jaddnum(item,"vout",up->vout); + jaddstr(item,"address",coinaddr); + if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) != 0 ) + jaddstr(item,"account",wacct->account); + if ( iguana_scriptget(coin,scriptstr,asmstr,sizeof(scriptstr),hdrsi,unspentind,T[up->txidind].txid,up->vout,rmd160,up->type,pubkey33) != 0 ) + jaddstr(item,"scriptPubKey",scriptstr); + jaddnum(item,"amount",dstr(up->value)); + if ( iguana_txidfind(coin,&height,&TX,T[up->txidind].txid,coin->bundlescount-1) != 0 ) + jaddnum(item,"confirmations",coin->longestchain - height); + return(item); +} + +int64_t iguana_pkhashbalance(struct iguana_info *coin,cJSON *array,int64_t *spentp,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t hdrsi) +{ + struct iguana_unspent *U; uint32_t unspentind; int64_t balance = 0; struct iguana_txid *T; + *spentp = *nump = 0; + if ( ramchain->Uextras == 0 ) + { + printf("iguana_pkhashbalance: unexpected null spents\n"); + return(0); + } + unspentind = lastunspentind; + U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); + T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + while ( unspentind > 0 ) + { + (*nump)++; + printf("%s u.%d %.8f\n",jprint(iguana_unspentjson(coin,hdrsi,unspentind,T,&U[unspentind],rmd160,coinaddr,pubkey33),1),unspentind,dstr(U[unspentind].value)); + if ( ramchain->Uextras[unspentind].spentflag == 0 ) + { + balance += U[unspentind].value; + if ( array != 0 ) + jaddi(array,iguana_unspentjson(coin,hdrsi,unspentind,T,&U[unspentind],rmd160,coinaddr,pubkey33)); + } else (*spentp) += U[unspentind].value; + unspentind = U[unspentind].prevunspentind; + } + return(balance); +} + +int32_t iguana_pkhasharray(struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33) +{ + int32_t i,n,m; int64_t spent,balance,netbalance,total; uint32_t lastunspentind; struct iguana_ramchain *ramchain; + for (total=i=n=0; ibundlescount; i++) + { + if ( iguana_pkhashfind(coin,&ramchain,&balance,&lastunspentind,&P[n],rmd160,i,i) != 0 ) + { + if ( (netbalance= iguana_pkhashbalance(coin,array,&spent,&m,ramchain,&P[n],lastunspentind,rmd160,coinaddr,pubkey33,i)) != balance-spent ) + { + printf("pkhash balance mismatch from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",m,dstr(netbalance),dstr(balance),dstr(spent),dstr(balance)-dstr(spent)); + } + else + { + //P[n].firstunspentind = lastunspentind; + total += netbalance; + n++; + } + } + //printf("%d: balance %.8f, lastunspent.%u\n",i,dstr(balance),lastunspentind); + } + //printf("n.%d max.%d\n",n,max); + *totalp = total; + return(n); +} + +void iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds) +{ + int64_t total,sum=0; struct iguana_pkhash *P; uint8_t *addrtypes,*pubkeys; int32_t i,flag = 0; char coinaddr[64]; + if ( rmdarray == 0 ) + rmdarray = iguana_walletrmds(myinfo,coin,&numrmds), flag++; + addrtypes = &rmdarray[numrmds * 20], pubkeys = &rmdarray[numrmds * 21]; + P = calloc(coin->bundlescount,sizeof(*P)); + for (i=0; ibundlescount,&rmdarray[i * 20],coinaddr,&pubkeys[33*i]); + printf("%s %.8f\n",coinaddr,dstr(total)); + sum += total; + } + printf("sum %.8f\n",dstr(sum)); + free(P); + if ( flag != 0 ) + free(rmdarray); +} + +uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti) +{ + int32_t i,n,j=0; char *coinaddr; uint8_t *addrtypes,*rmdarray = 0; + *numrmdsp = 0; + if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + *numrmdsp = n - firsti; + rmdarray = calloc(1,(n-firsti) * 21); + addrtypes = &rmdarray[(n-firsti) * 20]; + for (i=firsti; iramchain; + //printf("UTXO gen.%d ramchain data.%p\n",bp->bundleheight,ramchain->H.data); + if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) + return(0); + S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + numtxid = 1; + if ( ramchain->Xspendinds != 0 ) + { + //printf("iguana_utxogen: already have Xspendinds[%d]\n",ramchain->numXspends); + return(0); + } + ptr = mycalloc('x',sizeof(*ptr),n); + total += n; + height = bp->bundleheight; + //printf("start UTXOGEN.%d max.%d ptr.%p\n",bp->bundleheight,n,ptr); + for (spendind=ramchain->H.data->firsti; spendindbundleheight + numtxid; + //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + numtxid++; + } + u = 0; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( (spentbp= iguana_spent(coin,&prevhash,&unspentind,ramchain,bp->hdrsi,s)) != 0 ) + { + if ( (ptr[emit].ind= unspentind) != 0 && spentbp->hdrsi < bp->hdrsi ) + { + ptr[emit].hdrsi = spentbp->hdrsi; + ptr[emit].height = height; + //printf("(%d u%d).%d ",spentbp->hdrsi,unspentind,emit); + emit++; + } + else + { + printf("utxogen: null unspentind for spendind.%d hdrsi.%d [%d]\n",spendind,spentbp->hdrsi,bp->hdrsi); + errs++; + } + if ( spentbp == bp ) + { + char str[65]; + printf("unexpected spendbp: height.%d bp.[%d] U%d <- S%d.[%d] [ext.%d %s prev.%d]\n",height,spentbp->hdrsi,unspentind,spendind,bp->hdrsi,s->external,bits256_str(str,prevhash),s->prevout); + errs++; + } + } + else + { + errs++; + printf("utxogen: unresolved spendind.%d hdrsi.%d\n",spendind,bp->hdrsi); + } + } + } + if ( numtxid != bp->ramchain.H.data->numtxids ) + { + printf("numtxid.%d != bp %d\n",numtxid,bp->ramchain.H.data->numtxids); + errs++; + } + if ( errs == 0 && emit >= 0 ) + { + emitted += emit; + memset(zero.bytes,0,sizeof(zero)); + sprintf(dirname,"DB/%s/spends",coin->symbol); + vcalc_sha256(0,sha256.bytes,(void *)ptr,(int32_t)(sizeof(*ptr) * emit)); + if ( iguana_peerfname(coin,&hdrsi,dirname,fname,0,bp->hashes[0],zero,bp->n) >= 0 ) + { + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(sha256.bytes,1,sizeof(sha256),fp) != sizeof(sha256) ) + printf("error writing hash for %ld -> (%s)\n",sizeof(*ptr) * emit,fname); + else if ( fwrite(ptr,sizeof(*ptr),emit,fp) != emit ) + printf("error writing %d of %d -> (%s)\n",emit,n,fname); + else retval = 0; + fsize = ftell(fp); + fclose(fp); + if ( iguana_Xspendmap(coin,ramchain,bp) < 0 ) + { + printf("error mapping Xspendmap.(%s)\n",fname); + retval = -1; + } + //int32_t i; for (i=0; inumXspends; i++) + // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); + //printf("filesize %ld Xspendptr.%p %p num.%d\n",fsize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + } else printf("Error creating.(%s)\n",fname); + } else printf("error getting utxo fname\n"); + } + if ( ptr != 0 ) + myfree(ptr,sizeof(*ptr) * n); + printf("utxo %d spendinds.[%d] errs.%d [%.2f%%] emitted.%d %s of %d | ",spendind,bp->hdrsi,errs,100.*(double)emitted/(total+1),emit,mbstr(str,sizeof(*ptr) * emit),n); + return(-errs); +} + +int32_t iguana_balancegen(struct iguana_info *coin,struct iguana_bundle *bp) +{ + int32_t spendind,n,errs=0,emit=0; uint32_t unspentind,pkind,txidind; struct iguana_account *A2; + struct iguana_unspent *u,*spentU; struct iguana_spend *S,*s; struct iguana_ramchain *ramchain; + struct iguana_bundle *spentbp; struct iguana_txid *T,*nextT; int32_t hdrsi; + uint32_t numtxid,now,h,refheight; struct iguana_utxo *utxo; + ramchain = &bp->ramchain; + //printf("BALANCEGEN.%d\n",bp->bundleheight); + if ( ramchain->H.data == 0 || (n= ramchain->H.data->numspends) < 1 ) + return(0); + S = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Soffset); + nextT = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + numtxid = 1; + refheight = bp->bundleheight; + if ( ramchain->Xspendinds == 0 ) + { + printf("iguana_balancegen.%d: no Xspendinds[%d]\n",bp->hdrsi,ramchain->numXspends); + return(0); + } + for (spendind=ramchain->H.data->firsti; spendindbundleheight + numtxid; + //printf("height.%d firstvin.%d\n",height,nextT[numtxid].firstvin); + numtxid++; + } + s = &S[spendind]; + u = 0; + unspentind = 0; + hdrsi = -1; + if ( s->external != 0 && s->prevout >= 0 ) + { + if ( emit >= ramchain->numXspends ) + errs++; + else + { + h = ramchain->Xspendinds[emit].height; + unspentind = ramchain->Xspendinds[emit].ind; + if ( (hdrsi= ramchain->Xspendinds[emit].hdrsi) >= 0 && hdrsi <= bp->hdrsi ) + spentbp = coin->bundles[hdrsi]; + else + { + printf("iguana_balancegen[%d] s.%d illegal hdrsi.%d emit.%d\n",bp->hdrsi,spendind,hdrsi,emit); + errs++; + } + //printf("%d of %d: [%d] X spendind.%d -> (%d u%d)\n",emit,ramchain->numXspends,bp->hdrsi,spendind,hdrsi,unspentind); + emit++; + } + } + else if ( s->prevout >= 0 ) + { + spentbp = bp; + hdrsi = bp->hdrsi; + h = refheight; + if ( (txidind= s->spendtxidind) != 0 && txidind < spentbp->ramchain.H.data->numtxids ) + { + T = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Toffset); + unspentind = T[txidind].firstvout + s->prevout; + if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) + { + printf("iguana_balancegen unspentind overflow %u vs %u\n",unspentind,spentbp->ramchain.H.data->numunspents); + errs++; + } + //printf("txidind.%d 1st.%d prevout.%d\n",txidind,T[txidind].firstvout,s->prevout); + } + else + { + printf("iguana_balancegen txidind overflow %u vs %u\n",txidind,spentbp->ramchain.H.data->numtxids); + errs++; + } + //printf("[%d] spendind.%d -> (hdrsi.%d u%d)\n",bp->hdrsi,spendind,hdrsi,unspentind); + } + else continue; + now = (uint32_t)time(NULL); + if ( unspentind > 0 && unspentind < spentbp->ramchain.H.data->numunspents ) + { + if ( spentbp->ramchain.Uextras == 0 ) + { + spentbp->ramchain.Uextras = calloc(sizeof(*spentbp->ramchain.Uextras),spentbp->ramchain.H.data->numunspents + 16); + } + if ( spentbp->ramchain.A == 0 ) + { + spentbp->ramchain.A = calloc(sizeof(*spentbp->ramchain.A),spentbp->ramchain.H.data->numpkinds + 16); + } + if ( spentbp->ramchain.Uextras == 0 || (A2= spentbp->ramchain.A) == 0 ) + { + printf("null ptrs %p %p\n",spentbp->ramchain.Uextras,spentbp->ramchain.A); + errs++; + } + else + { + spentU = (void *)(long)((long)spentbp->ramchain.H.data + spentbp->ramchain.H.data->Uoffset); + u = &spentU[unspentind]; + if ( (pkind= u->pkind) != 0 && pkind < spentbp->ramchain.H.data->numpkinds ) + { + utxo = &spentbp->ramchain.Uextras[unspentind]; + if ( utxo->spentflag == 0 ) + { + utxo->prevspendind = A2[pkind].lastind; + utxo->spentflag = 1; + utxo->height = h; + A2[pkind].total += u->value; + A2[pkind].lastind = spendind; + spentbp->dirty = now; + } + else + { + errs++; + printf("iguana_balancegen: pkind.%d double spend of hdrsi.%d unspentind.%d prev.%u spentflag.%d height.%d\n",pkind,spentbp->hdrsi,unspentind,utxo->prevspendind,utxo->spentflag,utxo->height); + getchar(); + } + } + else + { + errs++; + printf("iguana_balancegen: pkind overflow %d vs %d\n",pkind,spentbp->ramchain.H.data->numpkinds); + } + } + } + else + { + errs++; + printf("iguana_balancegen: error with unspentind.%d vs max.%d\n",unspentind,spentbp->ramchain.H.data->numunspents); + } + } + if ( numtxid != bp->ramchain.H.data->numtxids ) + { + printf("iguana_balancegen: numtxid.%d != bp %d\n",numtxid,bp->ramchain.H.data->numtxids); + errs++; + } + if ( emit != ramchain->numXspends ) + { + printf("iguana_balancegen: emit %d != %d ramchain->numXspends\n",emit,ramchain->numXspends); + errs++; + } + printf(">>>>>>>> balances.%d done errs.%d spendind.%d\n",bp->hdrsi,errs,n); + if ( errs == 0 ) + bp->validated = (uint32_t)time(NULL); + return(-errs); +} + +int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp) +{ + bp->validated = (uint32_t)time(NULL); + printf("VALIDATE.%d %u\n",bp->bundleheight,bp->validated); + return(0); +} \ No newline at end of file diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index 9c38e1fd9..6577d5a4f 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -42,6 +42,36 @@ struct iguana_waccount *iguana_waccountadd(struct iguana_info *coin,char *wallet return(acct); } +uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp) +{ + int32_t iter,n,m; struct iguana_waccount *acct,*tmp; uint8_t *pubkeys,*addrtypes,*rmdarray = 0; struct iguana_waddress *waddr,*tmp2; + for (iter=n=m=0; iter<2; iter++) + { + HASH_ITER(hh,coin->wallet,acct,tmp) + { + HASH_ITER(hh,acct->waddrs,waddr,tmp2) + { + if ( iter == 0 ) + n++; + else if ( m < n ) + { + addrtypes[m] = waddr->type; + memcpy(&rmdarray[m * 20],waddr->rmd160,20); + memcpy(&pubkeys[m * 33],waddr->pubkey,33); + m++; + } + } + } + if ( iter == 0 ) + { + rmdarray = calloc(n,20 + 1 + 33); + addrtypes = &rmdarray[n * 20]; + pubkeys = &rmdarray[n * 21]; + } + } + return(rmdarray); +} + int32_t iguana_waccountswitch(struct iguana_info *coin,char *account,struct iguana_waccount *oldwaddr,int32_t oldind,char *coinaddr) { // what if coinaddr is already in an account? @@ -51,6 +81,20 @@ int32_t iguana_waccountswitch(struct iguana_info *coin,char *account,struct igua struct iguana_waccount *iguana_waddressfind(struct iguana_info *coin,int32_t *indp,char *coinaddr) { + int32_t n=0; struct iguana_waccount *acct,*tmp; struct iguana_waddress *waddr,*tmp2; + *indp = -1; + HASH_ITER(hh,coin->wallet,acct,tmp) + { + HASH_ITER(hh,acct->waddrs,waddr,tmp2) + { + if ( strcmp(coinaddr,waddr->coinaddr) == 0 ) + { + *indp = n; + return(acct); + } + n++; + } + } return(0); } diff --git a/iguana/images/img1.png b/iguana/images/img1.png old mode 100644 new mode 100755 diff --git a/iguana/images/img2.jpg b/iguana/images/img2.jpg old mode 100644 new mode 100755 diff --git a/iguana/images/img3.png b/iguana/images/img3.png old mode 100644 new mode 100755 diff --git a/iguana/images/img4.png b/iguana/images/img4.png old mode 100644 new mode 100755 diff --git a/iguana/index.html b/iguana/index.html old mode 100644 new mode 100755 index 2ee41b90b..50efa9c89 --- a/iguana/index.html +++ b/iguana/index.html @@ -20,7 +20,6 @@ -