Merge pull request #19 from jl777/dev

dev
This commit is contained in:
ca333
2018-04-20 15:40:51 +02:00
committed by GitHub
111 changed files with 1938 additions and 1152 deletions

View File

@@ -15,7 +15,7 @@ endif
BITCOIND_BIN=$(top_builddir)/src/zcashd$(EXEEXT) BITCOIND_BIN=$(top_builddir)/src/zcashd$(EXEEXT)
BITCOIN_CLI_BIN=$(top_builddir)/src/zcash-cli$(EXEEXT) BITCOIN_CLI_BIN=$(top_builddir)/src/zcash-cli$(EXEEXT)
WALLET_UTILITY_BIN=$(top_builddir)/src/wallet-utility$(EXEEXT) #WALLET_UTILITY_BIN=$(top_builddir)/src/wallet-utility$(EXEEXT)
BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT)
if TARGET_DARWIN if TARGET_DARWIN
@@ -156,8 +156,8 @@ $(BITCOIND_BIN): FORCE
$(BITCOIN_CLI_BIN): FORCE $(BITCOIN_CLI_BIN): FORCE
$(MAKE) -C src $(@F) $(MAKE) -C src $(@F)
$(WALLET_UTILITY_BIN): FORCE #$(WALLET_UTILITY_BIN): FORCE
$(MAKE) -C src $(@F) # $(MAKE) -C src $(@F)
if USE_LCOV if USE_LCOV

View File

@@ -799,7 +799,11 @@ AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"])
AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"]) AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"])
AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]])
LIBZCASH_LIBS="-lgmp -lgmpxx -lboost_system -lcrypto -lsodium $RUST_LIBS" if test x$TARGET_OS != xwindows; then
LIBZCASH_LIBS="-lgmp -lgmpxx -lboost_system -lcrypto -lsodium $RUST_LIBS"
else
LIBZCASH_LIBS="-lgmp -lgmpxx -lboost_system-mt-s -lcrypto -lsodium $RUST_LIBS"
fi
AC_MSG_CHECKING([whether to build bitcoind]) AC_MSG_CHECKING([whether to build bitcoind])
AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes])

View File

@@ -14,7 +14,8 @@ endif
ifeq ($(build_os),darwin) ifeq ($(build_os),darwin)
$(package)_install=ginstall $(package)_install=ginstall
define $(package)_build_cmds define $(package)_build_cmds
$(MAKE) -C make gtest.a $(MAKE) -C googlemock/make gmock.a && \
$(MAKE) -C googletest/make gtest.a
endef endef
else else
$(package)_install=install $(package)_install=install

View File

@@ -1,17 +1,20 @@
ifeq ($(build_os),darwin)
package=libsodium
$(package)_version=1.0.11
$(package)_download_path=https://supernetorg.bintray.com/misc
$(package)_file_name=libsodium-1.0.11.tar.gz
$(package)_sha256_hash=a14549db3c49f6ae2170cbbf4664bd48ace50681045e8dbea7c8d9fb96f9c765
$(package)_dependencies=
$(package)_config_opts=
else
package=libsodium package=libsodium
#<<<<<<< HEAD
#$(package)_version=1.0.11
#$(package)_download_path=https://supernetorg.bintray.com/misc
#$(package)_file_name=libsodium-1.0.11.tar.gz
#$(package)_sha256_hash=a14549db3c49f6ae2170cbbf4664bd48ace50681045e8dbea7c8d9fb96f9c765
#=======
$(package)_version=1.0.15 $(package)_version=1.0.15
$(package)_download_path=https://download.libsodium.org/libsodium/releases/ $(package)_download_path=https://download.libsodium.org/libsodium/releases/
$(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4 $(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4
#>>>>>>> zcash/master
$(package)_dependencies= $(package)_dependencies=
$(package)_config_opts= $(package)_config_opts=
endif
define $(package)_preprocess_cmds define $(package)_preprocess_cmds
cd $($(package)_build_subdir); ./autogen.sh cd $($(package)_build_subdir); ./autogen.sh

View File

@@ -1,6 +1,6 @@
package=proton package=proton
$(package)_version=0.17.0 $(package)_version=0.17.0
$(package)_download_path=http://apache.cs.utah.edu/qpid/proton/$($(package)_version) $(package)_download_path=https://archive.apache.org/dist/qpid/proton/$($(package)_version)
$(package)_file_name=qpid-proton-$($(package)_version).tar.gz $(package)_file_name=qpid-proton-$($(package)_version).tar.gz
$(package)_sha256_hash=6ffd26d3d0e495bfdb5d9fefc5349954e6105ea18cc4bb191161d27742c5a01a $(package)_sha256_hash=6ffd26d3d0e495bfdb5d9fefc5349954e6105ea18cc4bb191161d27742c5a01a
$(package)_patches=minimal-build.patch $(package)_patches=minimal-build.patch
@@ -21,4 +21,3 @@ endef
define $(package)_stage_cmds define $(package)_stage_cmds
cd build; $(MAKE) VERBOSE=1 DESTDIR=$($(package)_staging_prefix_dir) install cd build; $(MAKE) VERBOSE=1 DESTDIR=$($(package)_staging_prefix_dir) install
endef endef

View File

@@ -1,23 +1,16 @@
package=rust package=rust
$(package)_version=1.16.0 $(package)_version=1.16.0
$(package)_download_path=https://static.rust-lang.org/dist $(package)_download_path=https://static.rust-lang.org/dist
#<<<<<<< HEAD ifeq ($(build_os),darwin)
#ifeq ($(build_os),darwin) $(package)_file_name=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz
#$(package)_file_name=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz $(package)_sha256_hash=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926
#$(package)_sha256_hash=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926 else ifeq ($(host_os),mingw32)
#else ifeq ($(host_os),mingw32) $(package)_file_name=rust-$($(package)_version)-i686-unknown-linux-gnu.tar.gz
#$(package)_file_name=rust-$($(package)_version)-i686-unknown-linux-gnu.tar.gz $(package)_sha256_hash=b5859161ebb182d3b75fa14a5741e5de87b088146fb0ef4a30f3b2439c6179c5
#$(package)_sha256_hash=b5859161ebb182d3b75fa14a5741e5de87b088146fb0ef4a30f3b2439c6179c5 else
#else $(package)_file_name=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz
#$(package)_file_name=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz $(package)_sha256_hash=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd
#$(package)_sha256_hash=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd endif
#endif
#=======
$(package)_file_name_linux=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz
$(package)_sha256_hash_linux=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd
$(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz
$(package)_sha256_hash_darwin=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926
#>>>>>>> zcash/master
define $(package)_stage_cmds define $(package)_stage_cmds
./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig

View File

@@ -100,9 +100,9 @@ bin_PROGRAMS =
noinst_PROGRAMS = noinst_PROGRAMS =
TESTS = TESTS =
if BUILD_BITCOIND #if BUILD_BITCOIND
bin_PROGRAMS += komodod bin_PROGRAMS += komodod
endif #endif
if BUILD_BITCOIN_UTILS if BUILD_BITCOIN_UTILS
bin_PROGRAMS += komodo-cli komodo-tx bin_PROGRAMS += komodo-cli komodo-tx
@@ -111,6 +111,7 @@ if ENABLE_WALLET
bin_PROGRAMS += wallet-utility bin_PROGRAMS += wallet-utility
endif endif
LIBZCASH_H = \ LIBZCASH_H = \
zcash/IncrementalMerkleTree.hpp \ zcash/IncrementalMerkleTree.hpp \
zcash/NoteEncryption.hpp \ zcash/NoteEncryption.hpp \
@@ -528,7 +529,7 @@ wallet_utility_LDADD = \
$(LIBZCASH) \ $(LIBZCASH) \
$(LIBSNARK) \ $(LIBSNARK) \
$(LIBZCASH_LIBS)\ $(LIBZCASH_LIBS)\
$(LIBCRYPTOCONDITIONS) $(LIBCRYPTOCONDITIONS)
endif endif
# zcash-tx binary # # zcash-tx binary #

40
src/assetchains_stop Normal file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
args=("$@")
komodo_cli='./komodo-cli'
delay=20
function komodo_stop ()
{
$komodo_cli --ac_name=$1 stop
}
#set -x
komodo_stop REVS
komodo_stop SUPERNET
komodo_stop DEX
komodo_stop PANGEA
komodo_stop JUMBLR
komodo_stop BET
komodo_stop CRYPTO
komodo_stop HODL
komodo_stop MSHARK
komodo_stop BOTS
komodo_stop MGW
komodo_stop COQUI
komodo_stop WLC
komodo_stop KV
komodo_stop CEAL
komodo_stop MESH
komodo_stop MNZ
komodo_stop AXO
komodo_stop ETOMIC
komodo_stop BTCH
komodo_stop VOTE2018
komodo_stop PIZZA
komodo_stop BEER
komodo_stop NINJA
komodo_stop OOT
komodo_stop BNTN
komodo_stop CHAIN
komodo_stop PRLPAY

View File

@@ -125,7 +125,7 @@ bool AppInit(int argc, char* argv[])
sleep(1); sleep(1);
#endif #endif
} }
printf("initialized %s\n",ASSETCHAINS_SYMBOL); printf("initialized %s at %u\n",ASSETCHAINS_SYMBOL,(uint32_t)time(NULL));
if (!boost::filesystem::is_directory(GetDataDir(false))) if (!boost::filesystem::is_directory(GetDataDir(false)))
{ {
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());

View File

@@ -1,6 +1,11 @@
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#if __linux
#include <sys/syscall.h> #include <sys/syscall.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>

View File

@@ -11,12 +11,13 @@
#include "chainparams.h" #include "chainparams.h"
static const std::string CLIENT_VERSION_STR = FormatVersion(CLIENT_VERSION); static const std::string CLIENT_VERSION_STR = FormatVersion(CLIENT_VERSION);
extern char ASSETCHAINS_SYMBOL[];
void EnforceNodeDeprecation(int nHeight, bool forceLogging) { void EnforceNodeDeprecation(int nHeight, bool forceLogging) {
// Do not enforce deprecation in regtest or on testnet // Do not enforce deprecation in regtest or on testnet
std::string networkID = Params().NetworkIDString(); std::string networkID = Params().NetworkIDString();
if (networkID != "main") return; if (networkID != "main" || ASSETCHAINS_SYMBOL[0] != 0 ) return;
int blocksToDeprecation = DEPRECATION_HEIGHT - nHeight; int blocksToDeprecation = DEPRECATION_HEIGHT - nHeight;
bool disableDeprecation = (GetArg("-disabledeprecation", "") == CLIENT_VERSION_STR); bool disableDeprecation = (GetArg("-disabledeprecation", "") == CLIENT_VERSION_STR);

View File

@@ -1442,7 +1442,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
break; break;
} }
KOMODO_LOADINGBLOCKS = 0; KOMODO_LOADINGBLOCKS = 0;
// Check for changed -txindex state // Check for changed -txindex state
if (fTxIndex != GetBoolArg("-txindex", true)) { if (fTxIndex != GetBoolArg("-txindex", true)) {
strLoadError = _("You need to rebuild the database using -reindex to change -txindex"); strLoadError = _("You need to rebuild the database using -reindex to change -txindex");

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *
@@ -54,6 +54,7 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char
#include "komodo_jumblr.h" #include "komodo_jumblr.h"
#include "komodo_gateway.h" #include "komodo_gateway.h"
#include "komodo_events.h" #include "komodo_events.h"
#include "komodo_ccdata.h"
void komodo_currentheight_set(int32_t height) void komodo_currentheight_set(int32_t height)
{ {
@@ -356,6 +357,7 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar
if ( didinit == 0 ) if ( didinit == 0 )
{ {
portable_mutex_init(&KOMODO_KV_mutex); portable_mutex_init(&KOMODO_KV_mutex);
portable_mutex_init(&KOMODO_CC_mutex);
didinit = 1; didinit = 1;
} }
if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) if ( (sp= komodo_stateptr(symbol,dest)) == 0 )
@@ -505,10 +507,35 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar
} }
} }
int32_t komodo_validate_chain(uint256 srchash,int32_t notarized_height)
{
static int32_t last_rewind; int32_t rewindtarget; CBlockIndex *pindex; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN];
if ( (sp= komodo_stateptr(symbol,dest)) == 0 )
return(0);
if ( IsInitialBlockDownload() == 0 && ((pindex= mapBlockIndex[srchash]) == 0 || pindex->nHeight != notarized_height) )
{
if ( sp->NOTARIZED_HEIGHT > 0 && sp->NOTARIZED_HEIGHT < notarized_height )
rewindtarget = sp->NOTARIZED_HEIGHT - 1;
else if ( notarized_height > 101 )
rewindtarget = notarized_height - 101;
else rewindtarget = 0;
if ( rewindtarget != 0 && rewindtarget > KOMODO_REWIND && rewindtarget > last_rewind )
{
if ( last_rewind != 0 )
{
//KOMODO_REWIND = rewindtarget;
fprintf(stderr,"%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n",ASSETCHAINS_SYMBOL,notarized_height,srchash.ToString().c_str(),sp->NOTARIZED_HEIGHT,rewindtarget);
}
last_rewind = rewindtarget;
}
return(0);
} else return(1);
}
int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp) int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scriptbuf,int32_t scriptlen,int32_t height,uint256 txhash,int32_t i,int32_t j,uint64_t *voutmaskp,int32_t *specialtxp,int32_t *notarizedheightp,uint64_t value,int32_t notarized,uint64_t signedmask,uint32_t timestamp)
{ {
static uint256 zero; static FILE *signedfp; static uint256 zero; static FILE *signedfp;
int32_t opretlen,nid,k,len = 0; uint256 srchash,desttxid; uint8_t crypto777[33]; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; int32_t opretlen,nid,offset,k,MoMdepth,matched,len = 0; uint256 MoM,srchash,desttxid; uint8_t crypto777[33]; struct komodo_state *sp; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN];
if ( (sp= komodo_stateptr(symbol,dest)) == 0 ) if ( (sp= komodo_stateptr(symbol,dest)) == 0 )
return(-1); return(-1);
if ( scriptlen == 35 && scriptbuf[0] == 33 && scriptbuf[34] == 0xac ) if ( scriptlen == 35 && scriptbuf[0] == 33 && scriptbuf[34] == 0xac )
@@ -555,6 +582,8 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
} }
if ( scriptbuf[len++] == 0x6a ) if ( scriptbuf[len++] == 0x6a )
{ {
struct komodo_ccdata ccdata; struct komodo_ccdataMoMoM MoMoMdata;
int32_t validated = 0,nameoffset,opoffset = 0;
if ( (opretlen= scriptbuf[len++]) == 0x4c ) if ( (opretlen= scriptbuf[len++]) == 0x4c )
opretlen = scriptbuf[len++]; opretlen = scriptbuf[len++];
else if ( opretlen == 0x4d ) else if ( opretlen == 0x4d )
@@ -562,96 +591,148 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
opretlen = scriptbuf[len++]; opretlen = scriptbuf[len++];
opretlen += (scriptbuf[len++] << 8); opretlen += (scriptbuf[len++] << 8);
} }
if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) opoffset = len;
printf("[%s] notarized.%d notarizedht.%d sp.Nht %d sp.ht %d opretlen.%d (%c %c %c)\n",ASSETCHAINS_SYMBOL,notarized,*notarizedheightp,sp->NOTARIZED_HEIGHT,sp->CURRENT_HEIGHT,opretlen,scriptbuf[len+32*2+4],scriptbuf[len+32*2+4+1],scriptbuf[len+32*2+4+2]); matched = 0;
if ( j == 1 && opretlen >= 32*2+4 && strcmp(ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 ) if ( ASSETCHAINS_SYMBOL[0] == 0 )
{ {
if ( strcmp("KMD",(char *)&scriptbuf[len+32 * 2 + 4]) == 0 )
matched = 1;
}
else
{
if ( strcmp(ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 )
matched = 1;
}
offset = 32 * (1 + matched) + 4;
nameoffset = (int32_t)strlen((char *)&scriptbuf[len+offset]);
if ( nameoffset == 2 )
nameoffset += 2;
else nameoffset++;
memset(&ccdata,0,sizeof(ccdata));
strncpy(ccdata.symbol,(char *)&scriptbuf[len+offset],sizeof(ccdata.symbol));
if ( j == 1 && opretlen >= len+offset-opoffset )
{
memset(&MoMoMdata,0,sizeof(MoMoMdata));
if ( matched == 0 && bitweight(signedmask) >= KOMODO_MINRATIFY )
notarized = 1;
if ( strcmp("PIZZA",ccdata.symbol) == 0 )
notarized = 1;
if ( 0 && opretlen != 149 )
printf("[%s].%d (%s) matched.%d i.%d j.%d notarized.%d %llx opretlen.%d len.%d offset.%d opoffset.%d\n",ASSETCHAINS_SYMBOL,height,ccdata.symbol,matched,i,j,notarized,(long long)signedmask,opretlen,len,offset,opoffset);
len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&srchash); len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&srchash);
len += iguana_rwnum(0,&scriptbuf[len],sizeof(*notarizedheightp),(uint8_t *)notarizedheightp); len += iguana_rwnum(0,&scriptbuf[len],sizeof(*notarizedheightp),(uint8_t *)notarizedheightp);
len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid); if ( matched != 0 )
if ( strcmp("PIZZA",ASSETCHAINS_SYMBOL) == 0 && opretlen == 110 ) len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid);
if ( matched != 0 )
validated = komodo_validate_chain(srchash,*notarizedheightp);
else validated = 1;
if ( notarized != 0 && validated != 0 )
{ {
notarized = 1; //sp->NOTARIZED_HEIGHT = *notarizedheightp;
} //sp->NOTARIZED_HASH = srchash;
static int32_t last_rewind; //sp->NOTARIZED_DESTTXID = desttxid;
int32_t rewindtarget,validated = 0; memset(&MoM,0,sizeof(MoM));
CBlockIndex *pindex;// MoMdepth = 0;
if ( IsInitialBlockDownload() == 0 && ((pindex= mapBlockIndex[srchash]) == 0 || pindex->nHeight != *notarizedheightp) ) len += nameoffset;
{ ccdata.MoMdata.notarized_height = *notarizedheightp;
if ( sp->NOTARIZED_HEIGHT > 0 && sp->NOTARIZED_HEIGHT < *notarizedheightp ) ccdata.MoMdata.height = height;
rewindtarget = sp->NOTARIZED_HEIGHT - 1; ccdata.MoMdata.txi = i;
else if ( *notarizedheightp > 101 ) //printf("nameoffset.%d len.%d + 36 %d vs opretlen.%d\n",nameoffset,len,len+36,opretlen);
rewindtarget = *notarizedheightp - 101; if ( len+36-opoffset <= opretlen )
else rewindtarget = 0;
if ( rewindtarget != 0 && rewindtarget > KOMODO_REWIND && rewindtarget > last_rewind )
{ {
if ( last_rewind != 0 ) len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&MoM);
len += iguana_rwnum(0,&scriptbuf[len],sizeof(MoMdepth),(uint8_t *)&MoMdepth);
ccdata.MoMdata.MoM = MoM;
ccdata.MoMdata.MoMdepth = MoMdepth;
if ( len+sizeof(ccdata.CCid)-opoffset <= opretlen )
{ {
//KOMODO_REWIND = rewindtarget; len += iguana_rwnum(0,&scriptbuf[len],sizeof(ccdata.CCid),(uint8_t *)&ccdata.CCid);
fprintf(stderr,"%s FORK detected. notarized.%d %s not in this chain! last notarization %d -> rewindtarget.%d\n",ASSETCHAINS_SYMBOL,*notarizedheightp,srchash.ToString().c_str(),sp->NOTARIZED_HEIGHT,rewindtarget); ccdata.len = sizeof(ccdata.CCid);
if ( ASSETCHAINS_SYMBOL[0] != 0 )
{
// MoMoM, depth, numpairs, (notarization ht, MoMoM offset)
if ( len+48-opoffset <= opretlen && strcmp(ccdata.symbol,ASSETCHAINS_SYMBOL) == 0 )
{
len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdstarti);
len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.kmdendi);
len += iguana_rwbignum(0,&scriptbuf[len],sizeof(MoMoMdata.MoMoM),(uint8_t *)&MoMoMdata.MoMoM);
len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.MoMoMdepth);
len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.numpairs);
MoMoMdata.len += sizeof(MoMoMdata.MoMoM) + sizeof(uint32_t)*4;
if ( len+MoMoMdata.numpairs*8-opoffset == opretlen )
{
MoMoMdata.pairs = (struct komodo_ccdatapair *)calloc(MoMoMdata.numpairs,sizeof(*MoMoMdata.pairs));
for (k=0; k<MoMoMdata.numpairs; k++)
{
len += iguana_rwnum(0,&scriptbuf[len],sizeof(int32_t),(uint8_t *)&MoMoMdata.pairs[k].notarized_height);
len += iguana_rwnum(0,&scriptbuf[len],sizeof(uint32_t),(uint8_t *)&MoMoMdata.pairs[k].MoMoMoffset);
MoMoMdata.len += sizeof(uint32_t) * 2;
}
} else ccdata.len = MoMoMdata.len = 0;
} else ccdata.len = MoMoMdata.len = 0;
}
} }
last_rewind = rewindtarget; if ( MoM == zero || MoMdepth > 1440 || MoMdepth < 0 )
}
} else validated = 1;
if ( notarized != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height && validated != 0 )
{
int32_t nameoffset = (int32_t)strlen(ASSETCHAINS_SYMBOL) + 1;
sp->NOTARIZED_HEIGHT = *notarizedheightp;
sp->NOTARIZED_HASH = srchash;
sp->NOTARIZED_DESTTXID = desttxid;
memset(&sp->MoM,0,sizeof(sp->MoM));
sp->MoMdepth = 0;
if ( len+36 <= opretlen )
{
len += iguana_rwbignum(0,&scriptbuf[len+nameoffset],32,(uint8_t *)&sp->MoM);
len += iguana_rwnum(0,&scriptbuf[len+nameoffset],sizeof(sp->MoMdepth),(uint8_t *)&sp->MoMdepth);
if ( sp->MoM == zero || sp->MoMdepth > 1440 || sp->MoMdepth < 0 )
{ {
memset(&sp->MoM,0,sizeof(sp->MoM)); memset(&MoM,0,sizeof(MoM));
sp->MoMdepth = 0; MoMdepth = 0;
} }
else else
{ {
//printf("VALID %s MoM.%s [%d]\n",ASSETCHAINS_SYMBOL,sp->MoM.ToString().c_str(),sp->MoMdepth); komodo_rwccdata(ASSETCHAINS_SYMBOL,1,&ccdata,&MoMoMdata);
//printf("[%s] matched.%d VALID (%s) MoM.%s [%d]\n",ASSETCHAINS_SYMBOL,matched,ccdata.symbol,MoM.ToString().c_str(),MoMdepth);
} }
if ( MoMoMdata.pairs != 0 )
free(MoMoMdata.pairs);
memset(&ccdata,0,sizeof(ccdata));
memset(&MoMoMdata,0,sizeof(MoMoMdata));
} }
komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 )
len += nameoffset; komodo_rwccdata((char *)"KMD",1,&ccdata,0);
if ( ASSETCHAINS_SYMBOL[0] != 0 ) if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height )
printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth);
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{ {
if ( signedfp == 0 ) sp->NOTARIZED_HEIGHT = *notarizedheightp;
sp->NOTARIZED_HASH = srchash;
sp->NOTARIZED_DESTTXID = desttxid;
sp->MoM = MoM;
sp->MoMdepth = MoMdepth;
komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth);
if ( ASSETCHAINS_SYMBOL[0] != 0 )
printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth);
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{ {
char fname[512]; if ( signedfp == 0 )
komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"signedmasks"); {
if ( (signedfp= fopen(fname,"rb+")) == 0 ) char fname[512];
signedfp = fopen(fname,"wb"); komodo_statefname(fname,ASSETCHAINS_SYMBOL,(char *)"signedmasks");
else fseek(signedfp,0,SEEK_END); if ( (signedfp= fopen(fname,"rb+")) == 0 )
} signedfp = fopen(fname,"wb");
if ( signedfp != 0 ) else fseek(signedfp,0,SEEK_END);
{ }
fwrite(&height,1,sizeof(height),signedfp); if ( signedfp != 0 )
fwrite(&signedmask,1,sizeof(signedmask),signedfp); {
fflush(signedfp); fwrite(&height,1,sizeof(height),signedfp);
} fwrite(&signedmask,1,sizeof(signedmask),signedfp);
if ( opretlen > len && scriptbuf[len] == 'A' ) fflush(signedfp);
{ }
//for (i=0; i<opretlen-len; i++) if ( opretlen > len && scriptbuf[len] == 'A' )
// printf("%02x",scriptbuf[len+i]); {
//printf(" Found extradata.[%d] %d - %d\n",opretlen-len,opretlen,len); //for (i=0; i<opretlen-len; i++)
komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen-len+4+3+(scriptbuf[1] == 0x4d),j,zero,0); // printf("%02x",scriptbuf[len+i]);
//printf(" Found extradata.[%d] %d - %d\n",opretlen-len,opretlen,len);
komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen-len+4+3+(scriptbuf[1] == 0x4d),j,zero,0);
}
} }
} }
} else if ( *notarizedheightp != sp->NOTARIZED_HEIGHT ) } else if ( opretlen != 149 && height > 600000 && matched != 0 )
printf("validated.%d notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s (%s) len.%d opretlen.%d\n",validated,notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),desttxid.ToString().c_str(),(char *)&scriptbuf[len],len,opretlen); printf("%s validated.%d notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s len.%d opretlen.%d\n",ccdata.symbol,validated,notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),desttxid.ToString().c_str(),len,opretlen);
} }
else if ( i == 0 && j == 1 && opretlen == 149 ) else if ( matched != 0 && i == 0 && j == 1 && opretlen == 149 )
{ {
if ( notaryid >= 0 && notaryid < 64 ) if ( notaryid >= 0 && notaryid < 64 )
komodo_paxpricefeed(height,&scriptbuf[len],opretlen); komodo_paxpricefeed(height,&scriptbuf[len],opretlen);
} }
else else if ( matched != 0 )
{ {
//int32_t k; for (k=0; k<scriptlen; k++) //int32_t k; for (k=0; k<scriptlen; k++)
// printf("%02x",scriptbuf[k]); // printf("%02x",scriptbuf[k]);
@@ -726,7 +807,11 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
else else
{ {
if ( pindex->nHeight != hwmheight ) if ( pindex->nHeight != hwmheight )
{
printf("%s hwmheight.%d vs pindex->nHeight.%d t.%u reorg.%d\n",ASSETCHAINS_SYMBOL,hwmheight,pindex->nHeight,(uint32_t)pindex->nTime,hwmheight-pindex->nHeight); printf("%s hwmheight.%d vs pindex->nHeight.%d t.%u reorg.%d\n",ASSETCHAINS_SYMBOL,hwmheight,pindex->nHeight,(uint32_t)pindex->nTime,hwmheight-pindex->nHeight);
komodo_purge_ccdata((int32_t)pindex->nHeight);
hwmheight = pindex->nHeight;
}
komodo_event_rewind(sp,symbol,pindex->nHeight); komodo_event_rewind(sp,symbol,pindex->nHeight);
komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0,zero,0); komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0,zero,0);
} }

View File

@@ -592,7 +592,6 @@ void komodo_disconnect(CBlockIndex *pindex,CBlock& block)
} else printf("komodo_disconnect: ht.%d cant get komodo_state.(%s)\n",pindex->nHeight,ASSETCHAINS_SYMBOL); } else printf("komodo_disconnect: ht.%d cant get komodo_state.(%s)\n",pindex->nHeight,ASSETCHAINS_SYMBOL);
} }
int32_t komodo_is_notarytx(const CTransaction& tx) int32_t komodo_is_notarytx(const CTransaction& tx)
{ {
uint8_t *ptr; static uint8_t crypto777[33]; uint8_t *ptr; static uint8_t crypto777[33];
@@ -725,45 +724,45 @@ uint32_t komodo_heightstamp(int32_t height)
} }
/*void komodo_pindex_init(CBlockIndex *pindex,int32_t height) gets data corrupted /*void komodo_pindex_init(CBlockIndex *pindex,int32_t height) gets data corrupted
{ {
int32_t i,num; uint8_t pubkeys[64][33]; CBlock block; int32_t i,num; uint8_t pubkeys[64][33]; CBlock block;
if ( pindex->didinit != 0 ) if ( pindex->didinit != 0 )
return; return;
//printf("pindex.%d komodo_pindex_init notary.%d from height.%d\n",pindex->nHeight,pindex->notaryid,height); //printf("pindex.%d komodo_pindex_init notary.%d from height.%d\n",pindex->nHeight,pindex->notaryid,height);
if ( pindex->didinit == 0 ) if ( pindex->didinit == 0 )
{ {
pindex->notaryid = -1; pindex->notaryid = -1;
if ( KOMODO_LOADINGBLOCKS == 0 ) if ( KOMODO_LOADINGBLOCKS == 0 )
memset(pindex->pubkey33,0xff,33); memset(pindex->pubkey33,0xff,33);
else memset(pindex->pubkey33,0,33); else memset(pindex->pubkey33,0,33);
if ( komodo_blockload(block,pindex) == 0 ) if ( komodo_blockload(block,pindex) == 0 )
{ {
komodo_block2pubkey33(pindex->pubkey33,&block); komodo_block2pubkey33(pindex->pubkey33,&block);
//for (i=0; i<33; i++) //for (i=0; i<33; i++)
// fprintf(stderr,"%02x",pindex->pubkey33[i]); // fprintf(stderr,"%02x",pindex->pubkey33[i]);
//fprintf(stderr," set pubkey at height %d/%d\n",pindex->nHeight,height); //fprintf(stderr," set pubkey at height %d/%d\n",pindex->nHeight,height);
//if ( pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3 ) //if ( pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3 )
// pindex->didinit = (KOMODO_LOADINGBLOCKS == 0); // pindex->didinit = (KOMODO_LOADINGBLOCKS == 0);
} // else fprintf(stderr,"error loading block at %d/%d",pindex->nHeight,height); } // else fprintf(stderr,"error loading block at %d/%d",pindex->nHeight,height);
} }
if ( pindex->didinit != 0 && pindex->nHeight >= 0 && (num= komodo_notaries(pubkeys,(int32_t)pindex->nHeight,(uint32_t)pindex->nTime)) > 0 ) if ( pindex->didinit != 0 && pindex->nHeight >= 0 && (num= komodo_notaries(pubkeys,(int32_t)pindex->nHeight,(uint32_t)pindex->nTime)) > 0 )
{ {
for (i=0; i<num; i++) for (i=0; i<num; i++)
{ {
if ( memcmp(pubkeys[i],pindex->pubkey33,33) == 0 ) if ( memcmp(pubkeys[i],pindex->pubkey33,33) == 0 )
{ {
pindex->notaryid = i; pindex->notaryid = i;
break; break;
} }
} }
if ( 0 && i == num ) if ( 0 && i == num )
{ {
for (i=0; i<33; i++) for (i=0; i<33; i++)
fprintf(stderr,"%02x",pindex->pubkey33[i]); fprintf(stderr,"%02x",pindex->pubkey33[i]);
fprintf(stderr," unmatched pubkey at height %d/%d\n",pindex->nHeight,height); fprintf(stderr," unmatched pubkey at height %d/%d\n",pindex->nHeight,height);
} }
} }
}*/ }*/
void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
{ {
@@ -777,32 +776,32 @@ void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height)
} }
/*int8_t komodo_minerid(int32_t height,uint8_t *destpubkey33) /*int8_t komodo_minerid(int32_t height,uint8_t *destpubkey33)
{ {
int32_t num,i,numnotaries; CBlockIndex *pindex; uint32_t timestamp=0; uint8_t pubkey33[33],pubkeys[64][33]; int32_t num,i,numnotaries; CBlockIndex *pindex; uint32_t timestamp=0; uint8_t pubkey33[33],pubkeys[64][33];
if ( (pindex= chainActive[height]) != 0 ) if ( (pindex= chainActive[height]) != 0 )
{ {
if ( pindex->didinit != 0 ) if ( pindex->didinit != 0 )
{ {
if ( destpubkey33 != 0 ) if ( destpubkey33 != 0 )
memcpy(destpubkey33,pindex->pubkey33,33); memcpy(destpubkey33,pindex->pubkey33,33);
return(pindex->notaryid); return(pindex->notaryid);
} }
komodo_index2pubkey33(pubkey33,pindex,height); komodo_index2pubkey33(pubkey33,pindex,height);
if ( destpubkey33 != 0 ) if ( destpubkey33 != 0 )
memcpy(destpubkey33,pindex->pubkey33,33); memcpy(destpubkey33,pindex->pubkey33,33);
if ( pindex->didinit != 0 ) if ( pindex->didinit != 0 )
return(pindex->notaryid); return(pindex->notaryid);
timestamp = pindex->GetBlockTime(); timestamp = pindex->GetBlockTime();
if ( (num= komodo_notaries(pubkeys,height,timestamp)) > 0 ) if ( (num= komodo_notaries(pubkeys,height,timestamp)) > 0 )
{ {
for (i=0; i<num; i++) for (i=0; i<num; i++)
if ( memcmp(pubkeys[i],pubkey33,33) == 0 ) if ( memcmp(pubkeys[i],pubkey33,33) == 0 )
return(i); return(i);
} }
} }
fprintf(stderr,"komodo_minerid height.%d null pindex\n",height); fprintf(stderr,"komodo_minerid height.%d null pindex\n",height);
return(komodo_electednotary(&numnotaries,pubkey33,height,timestamp)); return(komodo_electednotary(&numnotaries,pubkey33,height,timestamp));
}*/ }*/
int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height) int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blocktimes[66],int32_t *nonzpkeysp,int32_t height)
{ {
@@ -836,18 +835,33 @@ int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blo
else return(0); else return(0);
} }
int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width) // deprecate int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width)
{ {
/*int32_t i,n=0; int32_t i,j,n,nonz,numnotaries; CBlock block; CBlockIndex *pindex; uint8_t notarypubs33[64][33],pubkey33[33];
for (i=0; i<width; i++,n++) numnotaries = komodo_notaries(notarypubs33,height,0);
{ for (i=nonz=0; i<width; i++,n++)
if ( height-i <= 0 ) {
break; if ( height-i <= 0 )
minerids[i] = komodo_minerid(height - i,0); continue;
} if ( (pindex= komodo_chainactive(height-width+i+1)) != 0 )
return(n);*/ {
fprintf(stderr,"komodo_minerids is deprecated\n"); if ( komodo_blockload(block,pindex) == 0 )
return(-1); {
komodo_block2pubkey33(pubkey33,&block);
for (j=0; j<numnotaries; j++)
{
if ( memcmp(notarypubs33[j],pubkey33,33) == 0 )
{
minerids[nonz++] = j;
break;
}
}
if ( j == numnotaries )
minerids[nonz++] = j;
} else fprintf(stderr,"couldnt load block.%d\n",height);
}
}
return(nonz);
} }
int32_t komodo_is_special(uint8_t pubkeys[66][33],int32_t mids[66],uint32_t blocktimes[66],int32_t height,uint8_t pubkey33[33],uint32_t blocktime) int32_t komodo_is_special(uint8_t pubkeys[66][33],int32_t mids[66],uint32_t blocktimes[66],int32_t height,uint8_t pubkey33[33],uint32_t blocktime)
@@ -873,7 +887,6 @@ int32_t komodo_is_special(uint8_t pubkeys[66][33],int32_t mids[66],uint32_t bloc
} }
if ( blocktime != 0 && blocktimes[1] != 0 && blocktime < blocktimes[1]+57 ) if ( blocktime != 0 && blocktimes[1] != 0 && blocktime < blocktimes[1]+57 )
{ {
//fprintf(stderr,"lag.%d ht.%d n.%d blocktimes[%u vs %u %u]\n",blocktime-blocktimes[1],height,notaryid,blocktime,blocktimes[0],blocktimes[1]);
if ( height > 807000 ) if ( height > 807000 )
return(-2); return(-2);
} }
@@ -946,7 +959,7 @@ int32_t komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 has
fprintf(stderr,"[%s] nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n",ASSETCHAINS_SYMBOL,nHeight,notarized_height); fprintf(stderr,"[%s] nHeight.%d == NOTARIZED_HEIGHT.%d, diff hash\n",ASSETCHAINS_SYMBOL,nHeight,notarized_height);
return(-1); return(-1);
} }
} else fprintf(stderr,"[%s] unexpected error notary_hash %s ht.%d at ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,notary->nHeight); } //else fprintf(stderr,"[%s] unexpected error notary_hash %s ht.%d at ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,notary->nHeight);
} }
//else if ( notarized_height > 0 && notarized_height != 73880 && notarized_height >= 170000 ) //else if ( notarized_height > 0 && notarized_height != 73880 && notarized_height >= 170000 )
// fprintf(stderr,"[%s] couldnt find notarized.(%s %d) ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,pindex->nHeight); // fprintf(stderr,"[%s] couldnt find notarized.(%s %d) ht.%d\n",ASSETCHAINS_SYMBOL,notarized_hash.ToString().c_str(),notarized_height,pindex->nHeight);
@@ -1031,3 +1044,302 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_
return(0); return(0);
} }
/*
komodo_checkPOW (fast) is called early in the process and should only refer to data immediately available. it is a filter to prevent bad blocks from going into the local DB
komodo_checkPOW (slow) is called right before connecting blocks so all prior blocks can be assumed to be there and all checks must pass
commission must be in coinbase.vout[1] and must be >= 10000 sats
PoS stake must be without txfee and in the last tx in the block at vout[0]
PoW mining on PoS chain must solve a harder diff that adjusts, but never less than KOMODO_POWMINMULT
*/
#define KOMODO_POWMINMULT 16
uint64_t komodo_commission(const CBlock *pblock)
{
int32_t i,j,n=0,txn_count; uint64_t commission,total = 0;
txn_count = pblock->vtx.size();
for (i=0; i<txn_count; i++)
{
n = pblock->vtx[i].vout.size();
for (j=0; j<n; j++)
{
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
if ( i != 0 || j != 1 )
total += pblock->vtx[i].vout[j].nValue;
}
}
//fprintf(stderr,"txn.%d n.%d commission total %.8f -> %.8f\n",txn_count,n,dstr(total),dstr((total * ASSETCHAINS_COMMISSION) / COIN));
commission = ((total * ASSETCHAINS_COMMISSION) / COIN);
if ( commission < 10000 )
commission = 0;
return(commission);
}
uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeight,uint256 txid,int32_t vout,uint32_t blocktime,uint32_t prevtime,char *destaddr)
{
CBlockIndex *pindex; uint8_t hashbuf[128]; char address[64]; bits256 addrhash; arith_uint256 hashval; uint256 hash,pasthash; int64_t diff=0; int32_t segid,minage,i,iter=0; uint32_t txtime,winner = 0; uint64_t value,coinage,supply = ASSETCHAINS_SUPPLY + nHeight*ASSETCHAINS_REWARD/SATOSHIDEN;
txtime = komodo_txtime(&value,txid,vout,address);
if ( value == 0 || txtime == 0 || blocktime == 0 || prevtime == 0 )
return(0);
if ( (minage= nHeight*3) > 6000 )
minage = 6000;
if ( blocktime < prevtime+57 )
blocktime = prevtime+57;
if ( blocktime > txtime+minage && (pindex= komodo_chainactive(nHeight>200?nHeight-200:1)) != 0 )
{
vcalc_sha256(0,(uint8_t *)&addrhash,(uint8_t *)address,(int32_t)strlen(address));
segid = ((nHeight + addrhash.uints[0]) & 0x3f);
pasthash = pindex->GetBlockHash();
memcpy(hashbuf,&pasthash,sizeof(pasthash));
memcpy(&hashbuf[sizeof(pasthash)],&addrhash,sizeof(addrhash));
vcalc_sha256(0,(uint8_t *)&hash,hashbuf,(int32_t)sizeof(uint256)*2);
//fprintf(stderr,"(%s) vs. (%s) %s %.8f txtime.%u\n",address,destaddr,hash.ToString().c_str(),dstr(value),txtime);
for (iter=0; iter<3600; iter++)
{
diff = (iter + blocktime - txtime - minage);
if ( diff > 3600*24 )
break;
coinage = (value * diff) * ((diff >> 16) + 1);
hashval = arith_uint256(supply * 64) * (UintToArith256(hash) / arith_uint256(coinage+1));
if ( hashval <= bnTarget )
{
winner = 1;
if ( validateflag == 0 )
{
blocktime += iter;
blocktime += segid * 2;
}
break;
}
if ( validateflag != 0 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
fprintf(stderr," vs target ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," segid.%d iter.%d winner.%d coinage.%llu %d ht.%d gap.%d %.8f diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,(int32_t)(blocktime - prevtime),dstr(value),(int32_t)diff);
break;
}
}
//fprintf(stderr,"iterated until i.%d winner.%d\n",i,winner);
if ( 0 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
fprintf(stderr," vs ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," segid.%d iter.%d winner.%d coinage.%llu %d ht.%d t.%u %.8f diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,blocktime,dstr(value),(int32_t)diff);
}
}
if ( nHeight < 2 )
return(blocktime);
return(blocktime * winner);
}
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc)
{
CBlockIndex *pindex; arith_uint256 bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,ht,percPoS,diff,val;
*percPoSp = percPoS = 0;
if ( height < 3 )
return(target);
sum = arith_uint256(0);
ave = sum;
for (i=n=0; i<100; i++)
{
ht = height - 100 + i;
if ( (pindex= komodo_chainactive(ht)) != 0 )
{
bnTarget.SetCompact(pindex->nBits,&fNegative,&fOverflow);
bnTarget = (bnTarget / arith_uint256(KOMODO_POWMINMULT));
hashval = UintToArith256(pindex->GetBlockHash());
if ( hashval <= bnTarget ) // PoW is never as easy as PoS/64, some PoS will be counted as PoW
{
fprintf(stderr,"1");
sum += hashval;
n++;
}
else
{
percPoS++;
fprintf(stderr,"0");
}
}
}
fprintf(stderr," -> %d%% percPoS ht.%d\n",percPoS,height);
*percPoSp = percPoS;
target = (target / arith_uint256(KOMODO_POWMINMULT));
if ( n > 0 )
{
ave = (sum / arith_uint256(n));
if ( ave > target )
ave = target;
} else return(target);
if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget
{
bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256((goalperc) * (goalperc));
/*if ( height > 1165 )
{
if ( height > 1180 )
{
if ( height > 1230 )
bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256((goalperc) * (goalperc));
else bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc);
}
else bnTarget = (ave * arith_uint256(goalperc * goalperc)) / arith_uint256(2 * (percPoS + goalperc) * (percPoS + goalperc));
} else bnTarget = (ave * arith_uint256(goalperc)) / arith_uint256(percPoS + goalperc);*/
if ( 1 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
fprintf(stderr," increase diff -> ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," floor diff ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&target)[i]);
fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS);
}
}
else if ( percPoS > goalperc ) // decrease PoW diff -> raise bnTarget
{
bnTarget = ((ave * arith_uint256(goalperc)) + (target * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc);
if ( 1 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
fprintf(stderr," decrease diff -> ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," floor diff ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&target)[i]);
fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS);
}
}
else bnTarget = ave; // recent ave is perfect
return(bnTarget);
}
int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_uint256 bnTarget)
{
CBlockIndex *previndex; char voutaddr[64],destaddr[64]; uint256 txid; uint32_t txtime,prevtime=0; int32_t vout,txn_count,eligible,isPoS = 0; uint64_t value; CTxDestination voutaddress;
txn_count = pblock->vtx.size();
if ( txn_count > 1 )
{
if ( prevtime == 0 )
{
if ( (previndex= mapBlockIndex[pblock->hashPrevBlock]) != 0 )
prevtime = (uint32_t)previndex->nTime;
}
txid = pblock->vtx[txn_count-1].vin[0].prevout.hash;
vout = pblock->vtx[txn_count-1].vin[0].prevout.n;
if ( prevtime != 0 )
{
eligible = komodo_stake(1,bnTarget,height,txid,vout,pblock->nTime,prevtime,(char *)"");
if ( eligible == 0 || eligible > pblock->nTime )
{
fprintf(stderr,"komodo_is_PoSblock PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)pblock->nTime,(int32_t)(eligible - pblock->nTime));
} else isPoS = 1;
}
else if ( slowflag == 0 ) // maybe previous block is not seen yet, do the best approx
{
txtime = komodo_txtime(&value,txid,vout,destaddr);
if ( ExtractDestination(pblock->vtx[txn_count-1].vout[0].scriptPubKey,voutaddress) )
{
strcpy(voutaddr,CBitcoinAddress(voutaddress).ToString().c_str());
if ( strcmp(destaddr,voutaddr) == 0 && pblock->vtx[txn_count-1].vout[0].nValue == value )
isPoS = 1; // close enough for a pre-filter
else fprintf(stderr,"komodo_is_PoSblock ht.%d (%s) != (%s) or %.8f != %.8f\n",height,destaddr,voutaddr,dstr(value),dstr(pblock->vtx[txn_count-1].vout[0].nValue));
} else fprintf(stderr,"komodo_is_PoSblock ht.%d couldnt extract voutaddress\n",height);
} else return(-1);
}
return(isPoS);
}
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height)
{
uint256 hash; arith_uint256 bnTarget,bhash; bool fNegative,fOverflow; uint8_t *script,pubkey33[33],pubkeys[64][33]; int32_t i,PoSperc,is_PoSblock=0,n,failed = 0,notaryid = -1; int64_t checktoshis,value; CBlockIndex *pprev;
if ( !CheckEquihashSolution(pblock, Params()) )
{
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d CheckEquihashSolution failed\n",slowflag,height);
return(-1);
}
hash = pblock->GetHash();
if ( height == 0 )
{
if ( (pprev= mapBlockIndex[pblock->hashPrevBlock]) != 0 )
height = pprev->nHeight + 1;
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d zeroheight\n",slowflag,height);
//if ( height == 0 )
return(0);
}
bnTarget.SetCompact(pblock->nBits,&fNegative,&fOverflow);
bhash = UintToArith256(hash);
komodo_block2pubkey33(pubkey33,pblock);
if ( bhash > bnTarget )
{
failed = 1;
if ( ASSETCHAINS_SYMBOL[0] == 0 ) // for the fast case
{
if ( (n= komodo_notaries(pubkeys,height,pblock->nTime)) > 0 )
{
for (i=0; i<n; i++)
if ( memcmp(pubkey33,pubkeys[i],33) == 0 )
{
notaryid = i;
break;
}
}
}
}
else if ( ASSETCHAINS_STAKED != 0 && height >= 2 ) // must PoS or have at least 16x better PoW
{
if ( (is_PoSblock= komodo_is_PoSblock(slowflag,height,pblock,bnTarget)) == 0 )
{
if ( ASSETCHAINS_STAKED == 100 && height > 100 ) // only PoS allowed!
return(-1);
else
{
if ( slowflag != 0 )
bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
else bnTarget = (bnTarget / arith_uint256(KOMODO_POWMINMULT)); // lower bound
if ( bhash > bnTarget )
{
for (i=31; i>=16; i--)
fprintf(stderr,"%02x",((uint8_t *)&bhash)[i]);
fprintf(stderr," > ");
for (i=31; i>=16; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," ht.%d PoW diff violation PoSperc.%d vs goalperc.%d\n",height,PoSperc,(int32_t)ASSETCHAINS_STAKED);
return(-1);
}
}
} else if ( is_PoSblock < 0 )
return(-1);
}
if ( failed == 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
{
checktoshis = komodo_commission(pblock);
if ( checktoshis > 10000 && pblock->vtx[0].vout.size() != 2 )
return(-1);
else if ( checktoshis != 0 )
{
script = (uint8_t *)pblock->vtx[0].vout[1].scriptPubKey.data();
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
return(-1);
if ( pblock->vtx[0].vout[1].nValue != checktoshis )
{
fprintf(stderr,"checktoshis %.8f vs actual vout[1] %.8f\n",dstr(checktoshis),dstr(pblock->vtx[0].vout[1].nValue));
return(-1);
}
}
}
fprintf(stderr,"komodo_checkPOW slowflag.%d ht.%d notaryid.%d failed.%d\n",slowflag,height,notaryid,failed);
if ( failed != 0 && notaryid < 0 )
return(-1);
else return(0);
}

View File

@@ -56,7 +56,7 @@ static int32_t cJSON_strcasecmp(const char *s1,const char *s2)
// the following written by jl777 // the following written by jl777
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *

273
src/komodo_ccdata.h Normal file
View File

@@ -0,0 +1,273 @@
/******************************************************************************
* Copyright © 2014-2018 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef H_KOMODOCCDATA_H
#define H_KOMODOCCDATA_H
struct komodo_ccdata *CC_data;
int32_t CC_firstheight;
bits256 iguana_merkle(bits256 *tree,int32_t txn_count)
{
int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2];
if ( txn_count == 1 )
return(tree[0]);
prev = 0;
while ( txn_count > 1 )
{
if ( (txn_count & 1) != 0 )
tree[prev + txn_count] = tree[prev + txn_count-1], txn_count++;
n += txn_count;
for (i=0; i<txn_count; i+=2)
{
iguana_rwbignum(1,serialized,sizeof(*tree),tree[prev + i].bytes);
iguana_rwbignum(1,&serialized[sizeof(*tree)],sizeof(*tree),tree[prev + i + 1].bytes);
tree[n + (i >> 1)] = bits256_doublesha256(0,serialized,sizeof(serialized));
}
prev = n;
txn_count >>= 1;
}
return(tree[n]);
}
struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi)
{
struct komodo_ccdata_entry *allMoMs=0; bits256 *tree,tmp; struct komodo_ccdata *ccdata,*tmpptr; int32_t i,num,max;
num = max = 0;
portable_mutex_lock(&KOMODO_CC_mutex);
DL_FOREACH_SAFE(CC_data,ccdata,tmpptr)
{
if ( ccdata->MoMdata.height <= kmdendi && ccdata->MoMdata.height >= kmdstarti )
{
if ( num >= max )
{
max += 100;
allMoMs = (struct komodo_ccdata_entry *)realloc(allMoMs,max * sizeof(*allMoMs));
}
allMoMs[num].MoM = ccdata->MoMdata.MoM;
allMoMs[num].notarized_height = ccdata->MoMdata.notarized_height;
allMoMs[num].kmdheight = ccdata->MoMdata.height;
allMoMs[num].txi = ccdata->MoMdata.txi;
strcpy(allMoMs[num].symbol,ccdata->symbol);
num++;
}
if ( ccdata->MoMdata.height < kmdstarti )
break;
}
portable_mutex_unlock(&KOMODO_CC_mutex);
if ( (*nump= num) > 0 )
{
tree = (bits256 *)calloc(sizeof(bits256),num*3);
for (i=0; i<num; i++)
memcpy(&tree[i],&allMoMs[i].MoM,sizeof(tree[i]));
tmp = iguana_merkle(tree,num);
memcpy(MoMoMp,&tree,sizeof(*MoMoMp));
}
else
{
free(allMoMs);
allMoMs = 0;
}
return(allMoMs);
}
int32_t komodo_addpair(struct komodo_ccdataMoMoM *mdata,int32_t notarized_height,int32_t offset,int32_t maxpairs)
{
if ( maxpairs >= 0) {
if ( mdata->numpairs >= maxpairs )
{
maxpairs += 100;
mdata->pairs = (struct komodo_ccdatapair *)realloc(mdata->pairs,sizeof(*mdata->pairs)*maxpairs);
//fprintf(stderr,"pairs reallocated to %p num.%d\n",mdata->pairs,mdata->numpairs);
}
} else {
fprintf(stderr,"komodo_addpair.maxpairs %d must be >= 0\n",(int32_t)maxpairs);
return(-1);
}
mdata->pairs[mdata->numpairs].notarized_height = notarized_height;
mdata->pairs[mdata->numpairs].MoMoMoffset = offset;
mdata->numpairs++;
return(maxpairs);
}
int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height)
{
uint8_t hexdata[8192]; struct komodo_ccdata *ccdata,*tmpptr; int32_t len,maxpairs,i,retval=-1,depth,starti,endi,CCid=0; struct komodo_ccdata_entry *allMoMs;
starti = endi = depth = len = maxpairs = 0;
hexstr[0] = 0;
if ( sizeof(hexdata)*2+1 > hexsize )
{
fprintf(stderr,"hexsize.%d too small for %d\n",hexsize,(int32_t)sizeof(hexdata));
return(-1);
}
memset(mdata,0,sizeof(*mdata));
portable_mutex_lock(&KOMODO_CC_mutex);
DL_FOREACH_SAFE(CC_data,ccdata,tmpptr)
{
if ( ccdata->MoMdata.height < kmdheight )
{
//fprintf(stderr,"%s notarized.%d kmd.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height,ccdata->MoMdata.height);
if ( strcmp(ccdata->symbol,symbol) == 0 )
{
if ( endi == 0 )
{
endi = ccdata->MoMdata.height;
CCid = ccdata->CCid;
}
if ( (mdata->numpairs == 1 && notarized_height == 0) || ccdata->MoMdata.notarized_height <= notarized_height )
{
starti = ccdata->MoMdata.height + 1;
if ( notarized_height == 0 )
notarized_height = ccdata->MoMdata.notarized_height;
break;
}
}
starti = ccdata->MoMdata.height;
}
}
portable_mutex_unlock(&KOMODO_CC_mutex);
mdata->kmdstarti = starti;
mdata->kmdendi = endi;
if ( starti != 0 && endi != 0 && endi >= starti )
{
if ( (allMoMs= komodo_allMoMs(&depth,&mdata->MoMoM,starti,endi)) != 0 )
{
mdata->MoMoMdepth = depth;
for (i=0; i<depth; i++)
{
if ( strcmp(symbol,allMoMs[i].symbol) == 0 )
maxpairs = komodo_addpair(mdata,allMoMs[i].notarized_height,i,maxpairs);
}
if ( mdata->numpairs > 0 )
{
len += iguana_rwnum(1,&hexdata[len],sizeof(CCid),(uint8_t *)&CCid);
len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->kmdstarti);
len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->kmdendi);
len += iguana_rwbignum(1,&hexdata[len],sizeof(mdata->MoMoM),(uint8_t *)&mdata->MoMoM);
len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->MoMoMdepth);
len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->numpairs);
for (i=0; i<mdata->numpairs; i++)
{
if ( len + sizeof(uint32_t)*2 > sizeof(hexdata) )
{
fprintf(stderr,"%s %d %d i.%d of %d exceeds hexdata.%d\n",symbol,kmdheight,notarized_height,i,mdata->numpairs,(int32_t)sizeof(hexdata));
break;
}
len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->pairs[i].notarized_height);
len += iguana_rwnum(1,&hexdata[len],sizeof(uint32_t),(uint8_t *)&mdata->pairs[i].MoMoMoffset);
}
if ( i == mdata->numpairs && len*2+1 < hexsize )
{
init_hexbytes_noT(hexstr,hexdata,len);
//fprintf(stderr,"hexstr.(%s)\n",hexstr);
retval = 0;
} else fprintf(stderr,"%s %d %d too much hexdata[%d] for hexstr[%d]\n",symbol,kmdheight,notarized_height,len,hexsize);
}
free(allMoMs);
}
}
return(retval);
}
void komodo_purge_ccdata(int32_t height)
{
struct komodo_ccdata *ccdata,*tmpptr;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
portable_mutex_lock(&KOMODO_CC_mutex);
DL_FOREACH_SAFE(CC_data,ccdata,tmpptr)
{
if ( ccdata->MoMdata.height >= height )
{
printf("PURGE %s notarized.%d\n",ccdata->symbol,ccdata->MoMdata.notarized_height);
DL_DELETE(CC_data,ccdata);
free(ccdata);
} else break;
}
portable_mutex_unlock(&KOMODO_CC_mutex);
}
else
{
// purge notarized data
}
}
// this is just a demo of ccdata processing to create example data for the MoMoM and allMoMs calls
int32_t komodo_rwccdata(char *thischain,int32_t rwflag,struct komodo_ccdata *ccdata,struct komodo_ccdataMoMoM *MoMoMdata)
{
uint256 hash,zero; bits256 tmp; int32_t i,nonz; struct komodo_ccdata *ptr; struct notarized_checkpoint *np;
if ( rwflag == 0 )
{
// load from disk
}
else
{
// write to disk
}
if ( ccdata->MoMdata.height > 0 && (CC_firstheight == 0 || ccdata->MoMdata.height < CC_firstheight) )
CC_firstheight = ccdata->MoMdata.height;
for (nonz=i=0; i<32; i++)
{
if ( (tmp.bytes[i]= ((uint8_t *)&ccdata->MoMdata.MoM)[31-i]) != 0 )
nonz++;
}
if ( nonz == 0 )
return(0);
memcpy(&hash,&tmp,sizeof(hash));
//fprintf(stderr,"[%s] ccdata.%s id.%d notarized_ht.%d MoM.%s height.%d/t%d\n",ASSETCHAINS_SYMBOL,ccdata->symbol,ccdata->CCid,ccdata->MoMdata.notarized_height,hash.ToString().c_str(),ccdata->MoMdata.height,ccdata->MoMdata.txi);
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
if ( CC_data != 0 && (CC_data->MoMdata.height > ccdata->MoMdata.height || (CC_data->MoMdata.height == ccdata->MoMdata.height && CC_data->MoMdata.txi >= ccdata->MoMdata.txi)) )
{
printf("out of order detected? SKIP CC_data ht.%d/txi.%d vs ht.%d/txi.%d\n",CC_data->MoMdata.height,CC_data->MoMdata.txi,ccdata->MoMdata.height,ccdata->MoMdata.txi);
}
else
{
ptr = (struct komodo_ccdata *)calloc(1,sizeof(*ptr));
*ptr = *ccdata;
portable_mutex_lock(&KOMODO_CC_mutex);
DL_PREPEND(CC_data,ptr);
portable_mutex_unlock(&KOMODO_CC_mutex);
}
}
else
{
if ( MoMoMdata != 0 && MoMoMdata->pairs != 0 )
{
for (i=0; i<MoMoMdata->numpairs; i++)
{
if ( (np= komodo_npptr(MoMoMdata->pairs[i].notarized_height)) != 0 )
{
memset(&zero,0,sizeof(zero));
if ( memcmp(&np->MoMoM,&zero,sizeof(np->MoMoM)) == 0 )
{
np->MoMoM = MoMoMdata->MoMoM;
np->MoMoMdepth = MoMoMdata->MoMoMdepth;
np->MoMoMoffset = MoMoMdata->MoMoMoffset;
np->kmdstarti = MoMoMdata->kmdstarti;
np->kmdendi = MoMoMdata->kmdendi;
}
else if ( memcmp(&np->MoMoM,&MoMoMdata->MoMoM,sizeof(np->MoMoM)) != 0 || np->MoMoMdepth != MoMoMdata->MoMoMdepth || np->MoMoMoffset != MoMoMdata->MoMoMoffset || np->kmdstarti != MoMoMdata->kmdstarti || np->kmdendi != MoMoMdata->kmdendi )
{
fprintf(stderr,"preexisting MoMoM mismatch: %s (%d %d %d %d) vs %s (%d %d %d %d)\n",np->MoMoM.ToString().c_str(),np->MoMoMdepth,np->MoMoMoffset,np->kmdstarti,np->kmdendi,MoMoMdata->MoMoM.ToString().c_str(),MoMoMdata->MoMoMdepth,MoMoMdata->MoMoMoffset,MoMoMdata->kmdstarti,MoMoMdata->kmdendi);
}
}
}
}
}
return(1);
}
#endif

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *
@@ -650,153 +650,6 @@ int32_t komodo_bannedset(int32_t *indallvoutsp,uint256 *array,int32_t max)
void komodo_passport_iteration(); void komodo_passport_iteration();
uint64_t komodo_commission(const CBlock &block)
{
int32_t i,j,n=0,txn_count; uint64_t total = 0;
txn_count = block.vtx.size();
for (i=0; i<txn_count; i++)
{
n = block.vtx[i].vout.size();
for (j=0; j<n; j++)
{
//fprintf(stderr,"(%d %.8f).%d ",i,dstr(block.vtx[i].vout[j].nValue),j);
if ( i != 0 || j != 1 )
{
total += block.vtx[i].vout[j].nValue;
}
}
}
//fprintf(stderr,"txn.%d n.%d commission total %.8f -> %.8f\n",txn_count,n,dstr(total),dstr((total * ASSETCHAINS_COMMISSION) / COIN));
return((total * ASSETCHAINS_COMMISSION) / COIN);
}
uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeight,uint256 txid,int32_t vout,uint32_t blocktime,uint32_t prevtime,char *destaddr)
{
CBlockIndex *pindex; uint8_t hashbuf[128]; char address[64]; bits256 addrhash; arith_uint256 hashval; uint256 hash,pasthash; int64_t diff=0; int32_t segid,minage,i,iter=0; uint32_t txtime,winner = 0; uint64_t value,coinage,supply = ASSETCHAINS_SUPPLY + nHeight*ASSETCHAINS_REWARD/SATOSHIDEN;
txtime = komodo_txtime(&value,txid,vout,address);
if ( value == 0 || txtime == 0 )
return(0);
if ( (minage= nHeight*3) > 6000 )
minage = 6000;
if ( blocktime > txtime+minage && (pindex= komodo_chainactive(nHeight>200?nHeight-200:1)) != 0 )
{
vcalc_sha256(0,(uint8_t *)&addrhash,(uint8_t *)address,(int32_t)strlen(address));
segid = ((nHeight + addrhash.uints[0]) & 0x3f);
pasthash = pindex->GetBlockHash();
memcpy(hashbuf,&pasthash,sizeof(pasthash));
memcpy(&hashbuf[sizeof(pasthash)],&addrhash,sizeof(addrhash));
vcalc_sha256(0,(uint8_t *)&hash,hashbuf,(int32_t)sizeof(uint256)*2);
//fprintf(stderr,"(%s) vs. (%s) %s %.8f txtime.%u\n",address,destaddr,hash.ToString().c_str(),dstr(value),txtime);
for (iter=0; iter<3600; iter++)
{
diff = (iter + blocktime - txtime - minage);
if ( diff > 3600*24 )
break;
coinage = (value * diff) * ((diff >> 16) + 1);
hashval = arith_uint256(supply * 64) * (UintToArith256(hash) / arith_uint256(coinage+1));
if ( hashval <= bnTarget )
{
winner = 1;
if ( validateflag == 0 )
{
blocktime += iter;
blocktime += segid * 2;
}
break;
}
if ( validateflag != 0 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
fprintf(stderr," vs target ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," segid.%d iter.%d winner.%d coinage.%llu %d ht.%d gap.%d %.8f diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,(int32_t)(blocktime - prevtime),dstr(value),(int32_t)diff);
break;
}
}
//fprintf(stderr,"iterated until i.%d winner.%d\n",i,winner);
if ( 0 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
fprintf(stderr," vs ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," segid.%d iter.%d winner.%d coinage.%llu %d ht.%d t.%u %.8f diff.%d\n",segid,iter,winner,(long long)coinage,(int32_t)(blocktime - txtime),nHeight,blocktime,dstr(value),(int32_t)diff);
}
}
if ( nHeight < 2 )
return(blocktime);
return(blocktime * winner);
}
#define KOMODO_POWMINMULT 16
arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc)
{
CBlockIndex *pindex; arith_uint256 bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,ht,percPoS,diff;
*percPoSp = percPoS = 0;
sum = arith_uint256(0);
ave = sum;
for (i=n=0; i<100; i++)
{
ht = height - 100 + i;
if ( (pindex= komodo_chainactive(ht)) != 0 )
{
bnTarget.SetCompact(pindex->nBits,&fNegative,&fOverflow);
bnTarget = (bnTarget / arith_uint256(KOMODO_POWMINMULT));
hashval = UintToArith256(pindex->GetBlockHash());
if ( hashval <= bnTarget ) // PoW is never as easy as PoS/64, some PoS will be counted as PoW
{
sum += hashval;
n++;
} else percPoS++;
}
}
*percPoSp = percPoS;
target = (target / arith_uint256(KOMODO_POWMINMULT));
if ( n > 0 )
{
ave = (sum / arith_uint256(n));
if ( ave > target )
ave = target;
} else return(target);
if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget
{
bnTarget = (ave * arith_uint256(goalperc)) / arith_uint256(percPoS + goalperc);
if ( 1 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
fprintf(stderr," increase diff -> ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," floor diff ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&target)[i]);
fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS);
}
}
else if ( percPoS > goalperc ) // decrease PoW diff -> raise bnTarget
{
bnTarget = ((ave * arith_uint256(goalperc)) + (target * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc);
if ( 1 )
{
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&ave)[i]);
fprintf(stderr," decrease diff -> ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," floor diff ");
for (i=31; i>=24; i--)
fprintf(stderr,"%02x",((uint8_t *)&target)[i]);
fprintf(stderr," ht.%d percPoS.%d vs goal.%d -> diff %d\n",height,percPoS,goalperc,goalperc - percPoS);
}
}
else bnTarget = ave; // recent ave is perfect
return(bnTarget);
}
int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime) // verify above block is valid pax pricing int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime) // verify above block is valid pax pricing
{ {
static uint256 array[64]; static int32_t numbanned,indallvouts; static uint256 array[64]; static int32_t numbanned,indallvouts;
@@ -867,59 +720,6 @@ int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtim
} }
else else
{ {
if ( ASSETCHAINS_STAKED != 0 && height >= 2 )
{
arith_uint256 bnTarget,hashval; int32_t PoSperc; bool fNegative,fOverflow; CBlockIndex *previndex; uint32_t eligible,isPoS = 0;
bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
if ( txn_count > 1 )
{
if ( prevtime == 0 )
{
if ( (previndex= mapBlockIndex[block.hashPrevBlock]) != 0 )
prevtime = (uint32_t)previndex->nTime;
}
eligible = komodo_stake(1,bnTarget,height,block.vtx[txn_count-1].vin[0].prevout.hash,block.vtx[txn_count-1].vin[0].prevout.n,block.nTime,prevtime,(char *)"");
if ( eligible == 0 || eligible > block.nTime )
{
fprintf(stderr,"PoS failure ht.%d eligible.%u vs blocktime.%u, lag.%d -> check to see if it is PoW block\n",height,eligible,(uint32_t)block.nTime,(int32_t)(eligible - block.nTime));
} else isPoS = 1;
}
if ( isPoS == 0 && height > 100 )
{
if ( ASSETCHAINS_STAKED == 100 )
{
fprintf(stderr,"ht.%d 100%% PoS after height 100 rule violated for -ac_staking=100\n",height);
return(-1);
}
// check PoW
bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED);
hashval = UintToArith256(block.GetHash());
if ( hashval > bnTarget )
{
/*for (i=31; i>=0; i--)
fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]);
fprintf(stderr," > ");
for (i=31; i>=0; i--)
fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," ht.%d PoW diff violation PoSperc.%d vs goalperc.%d\n",height,PoSperc,(int32_t)ASSETCHAINS_STAKED);*/
return(-1);
}
}
}
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && block.vtx[0].vout.size() > 1 )
{
script = (uint8_t *)block.vtx[0].vout[1].scriptPubKey.data();
if ( script[0] != 33 || script[34] != OP_CHECKSIG || memcmp(script+1,ASSETCHAINS_OVERRIDE_PUBKEY33,33) != 0 )
return(-1);
if ( (checktoshis = komodo_commission(block)) != 0 )
{
if ( block.vtx[0].vout[1].nValue != checktoshis )
{
fprintf(stderr,"checktoshis %.8f vs actual vout[1] %.8f\n",dstr(checktoshis),dstr(block.vtx[0].vout[1].nValue));
return(-1);
} else return(0);
}
}
if ( overflow != 0 || total > 0 ) if ( overflow != 0 || total > 0 )
return(-1); return(-1);
} }
@@ -1972,7 +1772,7 @@ void komodo_passport_iteration()
if ( expired == 0 && KOMODO_PASSPORT_INITDONE == 0 ) if ( expired == 0 && KOMODO_PASSPORT_INITDONE == 0 )
{ {
KOMODO_PASSPORT_INITDONE = 1; KOMODO_PASSPORT_INITDONE = 1;
printf("done PASSPORT %s refid.%d\n",ASSETCHAINS_SYMBOL,refid); printf("READY for %s RPC calls at %u! done PASSPORT %s refid.%d\n",ASSETCHAINS_SYMBOL,(uint32_t)time(NULL),ASSETCHAINS_SYMBOL,refid);
} }
} }

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *
@@ -15,6 +15,7 @@
#include "komodo_defs.h" #include "komodo_defs.h"
void komodo_prefetch(FILE *fp);
uint32_t komodo_heightstamp(int32_t height); uint32_t komodo_heightstamp(int32_t height);
void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth);
void komodo_init(int32_t height); void komodo_init(int32_t height);
@@ -22,7 +23,6 @@ int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,in
int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp);
char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port); char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port);
void komodo_init(int32_t height); void komodo_init(int32_t height);
void komodo_assetchain_pubkeys(char *jsonstr);
int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp);
int32_t komodo_isrealtime(int32_t *kmdheightp); int32_t komodo_isrealtime(int32_t *kmdheightp);
uint64_t komodo_paxtotal(); uint64_t komodo_paxtotal();
@@ -46,7 +46,7 @@ struct komodo_state KOMODO_STATES[34];
int COINBASE_MATURITY = _COINBASE_MATURITY;//100; int COINBASE_MATURITY = _COINBASE_MATURITY;//100;
int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND; int32_t IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND;
int32_t KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE; int32_t KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE = 1;
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY; std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY;
uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33]; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33];
@@ -59,6 +59,7 @@ uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAI
uint32_t KOMODO_INITDONE; uint32_t KOMODO_INITDONE;
char KMDUSERPASS[4096],BTCUSERPASS[4096]; uint16_t KMD_PORT = 7771,BITCOIND_PORT = 7771; char KMDUSERPASS[4096],BTCUSERPASS[4096]; uint16_t KMD_PORT = 7771,BITCOIND_PORT = 7771;
uint64_t PENDING_KOMODO_TX; uint64_t PENDING_KOMODO_TX;
extern int32_t KOMODO_LOADINGBLOCKS;
struct komodo_kv *KOMODO_KV; struct komodo_kv *KOMODO_KV;
pthread_mutex_t KOMODO_KV_mutex; pthread_mutex_t KOMODO_KV_mutex,KOMODO_CC_mutex;

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *
@@ -13,6 +13,7 @@
* * * *
******************************************************************************/ ******************************************************************************/
#include "komodo_defs.h" #include "komodo_defs.h"
#include "komodo_cJSON.h" #include "komodo_cJSON.h"
@@ -399,7 +400,6 @@ int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp)
} }
} }
struct notarized_checkpoint *komodo_npptr(int32_t height) struct notarized_checkpoint *komodo_npptr(int32_t height)
{ {
char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; int32_t i; struct komodo_state *sp; struct notarized_checkpoint *np = 0; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; int32_t i; struct komodo_state *sp; struct notarized_checkpoint *np = 0;
@@ -437,7 +437,6 @@ int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,in
return(0); return(0);
} }
int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp) int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp)
{ {
struct notarized_checkpoint *np = 0; int32_t i=0,flag = 0; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; struct notarized_checkpoint *np = 0; int32_t i=0,flag = 0; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp;
@@ -543,50 +542,4 @@ void komodo_init(int32_t height)
didinit = 1; didinit = 1;
komodo_stateupdate(0,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,zero,0); komodo_stateupdate(0,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,zero,0);
} }
/*else if ( 0 && height == KOMODO_MAINNET_START )
{
n = (int32_t)(sizeof(Notaries_elected)/sizeof(*Notaries_elected));
for (k=0; k<n; k++)
{
if ( Notaries_elected[k][0] == 0 || Notaries_elected[k][1] == 0 || Notaries_elected[k][0][0] == 0 || Notaries_elected[k][1][0] == 0 )
break;
decode_hex(pubkeys[k],33,(char *)Notaries_elected[k][1]);
}
printf("set MAINNET notaries.%d\n",k);
komodo_notarysinit(KOMODO_MAINNET_START,pubkeys,k);
}*/
} }
/*void komodo_assetchain_pubkeys(char *jsonstr)
{
cJSON *array; int32_t i,n; uint8_t pubkeys[64][33]; char *hexstr;
memset(pubkeys,0,sizeof(pubkeys));
if ( (array= cJSON_Parse(jsonstr)) != 0 )
{
if ( (n= cJSON_GetArraySize(array)) > 0 )
{
for (i=0; i<n; i++)
{
if ( (hexstr= jstri(array,i)) != 0 && is_hexstr(hexstr,0) == 66 )
{
decode_hex(pubkeys[i],33,hexstr);
fprintf(stderr,"i.%d of n.%d pubkey.(%s)\n",i,n,hexstr);
}
else
{
fprintf(stderr,"illegal hexstr.(%s) i.%d of n.%d\n",hexstr,i,n);
break;
}
}
if ( i == n )
{
komodo_init(-1);
komodo_notarysinit(0,pubkeys,n);
KOMODO_EXTERNAL_NOTARIES = 1;
//printf("initialize pubkeys[%d]\n",n);
} else fprintf(stderr,"komodo_assetchain_pubkeys i.%d vs n.%d\n",i,n);
} else fprintf(stderr,"assetchain pubkeys n.%d\n",n);
}
//else if ( jsonstr != 0 )
// fprintf(stderr,"assetchain pubkeys couldnt parse.(%s)\n",jsonstr);
}*/

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *
@@ -89,6 +89,30 @@ struct notarized_checkpoint
int32_t nHeight,notarized_height,MoMdepth,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; int32_t nHeight,notarized_height,MoMdepth,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi;
}; };
struct komodo_ccdataMoM
{
uint256 MoM;
int32_t MoMdepth,notarized_height,height,txi;
};
struct komodo_ccdata_entry { uint256 MoM; int32_t notarized_height,kmdheight,txi; char symbol[65]; };
struct komodo_ccdatapair { int32_t notarized_height,MoMoMoffset; };
struct komodo_ccdataMoMoM
{
uint256 MoMoM;
int32_t kmdstarti,kmdendi,MoMoMoffset,MoMoMdepth,numpairs,len;
struct komodo_ccdatapair *pairs;
};
struct komodo_ccdata
{
struct komodo_ccdata *next,*prev;
struct komodo_ccdataMoM MoMdata;
uint32_t CCid,len;
char symbol[65];
};
struct komodo_state struct komodo_state
{ {
uint256 NOTARIZED_HASH,NOTARIZED_DESTTXID,MoM; uint256 NOTARIZED_HASH,NOTARIZED_DESTTXID,MoM;

View File

@@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. * * Copyright © 2014-2018 The SuperNET Developers. *
* * * *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright * * the top-level directory of this distribution for the individual copyright *
@@ -1365,7 +1365,7 @@ void komodo_configfile(char *symbol,uint16_t port)
#ifndef FROM_CLI #ifndef FROM_CLI
if ( (fp= fopen(fname,"wb")) != 0 ) if ( (fp= fopen(fname,"wb")) != 0 )
{ {
fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=64\nrpcallowip=127.0.0.1\n",crc,password,port); fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=256\nrpcallowip=127.0.0.1\n",crc,password,port);
fclose(fp); fclose(fp);
printf("Created (%s)\n",fname); printf("Created (%s)\n",fname);
} else printf("Couldnt create (%s)\n",fname); } else printf("Couldnt create (%s)\n",fname);
@@ -1528,7 +1528,7 @@ void komodo_args(char *argv0)
} }
} }
} }
ASSETCHAINS_CC = GetArg("-ac_cc",0); // keep it outside the assetchains hashing so KMD can do it and we dont have two identical chains other than -ac_cc ASSETCHAINS_CC = GetArg("-ac_cc",0);
if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 ) if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 )
{ {
printf("KOMODO_REWIND %d\n",KOMODO_REWIND); printf("KOMODO_REWIND %d\n",KOMODO_REWIND);
@@ -1575,7 +1575,7 @@ void komodo_args(char *argv0)
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_REWARD),(void *)&ASSETCHAINS_REWARD); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_REWARD),(void *)&ASSETCHAINS_REWARD);
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_HALVING),(void *)&ASSETCHAINS_HALVING); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_HALVING),(void *)&ASSETCHAINS_HALVING);
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY),(void *)&ASSETCHAINS_DECAY); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY),(void *)&ASSETCHAINS_DECAY);
val = ASSETCHAINS_COMMISSION | ((ASSETCHAINS_STAKED & 0xff) << 32); val = ASSETCHAINS_COMMISSION | (((uint64_t)ASSETCHAINS_STAKED & 0xff) << 32) | (((uint64_t)ASSETCHAINS_CC & 0xffffff) << 40);
extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val); extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val);
} }
addn = GetArg("-seednode",""); addn = GetArg("-seednode","");
@@ -1696,3 +1696,24 @@ struct komodo_state *komodo_stateptr(char *symbol,char *dest)
komodo_nameset(symbol,dest,ASSETCHAINS_SYMBOL); komodo_nameset(symbol,dest,ASSETCHAINS_SYMBOL);
return(komodo_stateptrget(symbol)); return(komodo_stateptrget(symbol));
} }
void komodo_prefetch(FILE *fp)
{
long fsize,fpos; int32_t incr = 16*1024*1024;
fpos = ftell(fp);
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
if ( fsize > incr )
{
char *ignore = (char *)malloc(incr);
if ( ignore != 0 )
{
rewind(fp);
while ( fread(ignore,1,incr,fp) == incr ) // prefetch
fprintf(stderr,".");
free(ignore);
}
}
fseek(fp,fpos,SEEK_SET);
}

View File

@@ -1600,7 +1600,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
if (pindexSlow) { if (pindexSlow) {
CBlock block; CBlock block;
if (ReadBlockFromDisk(block, pindexSlow)) { if (ReadBlockFromDisk(block, pindexSlow,1)) {
BOOST_FOREACH(const CTransaction &tx, block.vtx) { BOOST_FOREACH(const CTransaction &tx, block.vtx) {
if (tx.GetHash() == hash) { if (tx.GetHash() == hash) {
txOut = tx; txOut = tx;
@@ -1655,7 +1655,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::M
return true; return true;
} }
bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos) bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
{ {
uint8_t pubkey33[33]; uint8_t pubkey33[33];
block.SetNull(); block.SetNull();
@@ -1677,23 +1677,26 @@ bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos)
return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString()); return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
} }
// Check the header // Check the header
komodo_block2pubkey33(pubkey33,(CBlock *)&block); if ( 0 && checkPOW != 0 )
if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime)))
{ {
int32_t i; for (i=0; i<33; i++) komodo_block2pubkey33(pubkey33,(CBlock *)&block);
fprintf(stderr,"%02x",pubkey33[i]); if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime)))
fprintf(stderr," warning unexpected diff at ht.%d\n",height); {
int32_t i; for (i=0; i<33; i++)
fprintf(stderr,"%02x",pubkey33[i]);
fprintf(stderr," warning unexpected diff at ht.%d\n",height);
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
}
} }
return true; return true;
} }
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
{ {
if ( pindex == 0 ) if ( pindex == 0 )
return false; return false;
if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos())) if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos(),checkPOW))
return false; return false;
if (block.GetHash() != pindex->GetBlockHash()) if (block.GetHash() != pindex->GetBlockHash())
return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s", return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
@@ -2249,7 +2252,6 @@ namespace {
catch (const std::exception& e) { catch (const std::exception& e) {
return error("%s: Deserialize or I/O error - %s", __func__, e.what()); return error("%s: Deserialize or I/O error - %s", __func__, e.what());
} }
// Verify checksum // Verify checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock; hasher << hashBlock;
@@ -2331,7 +2333,6 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
return error("DisconnectBlock(): block and undo data inconsistent"); return error("DisconnectBlock(): block and undo data inconsistent");
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex; std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex; std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
@@ -2340,7 +2341,6 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
for (int i = block.vtx.size() - 1; i >= 0; i--) { for (int i = block.vtx.size() - 1; i >= 0; i--) {
const CTransaction &tx = block.vtx[i]; const CTransaction &tx = block.vtx[i];
uint256 hash = tx.GetHash(); uint256 hash = tx.GetHash();
if (fAddressIndex) { if (fAddressIndex) {
for (unsigned int k = tx.vout.size(); k-- > 0;) { for (unsigned int k = tx.vout.size(); k-- > 0;) {
@@ -2585,8 +2585,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
auto disabledVerifier = libzcash::ProofVerifier::Disabled(); auto disabledVerifier = libzcash::ProofVerifier::Disabled();
// Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
if (!CheckBlock(pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck)) //!fJustCheck, !fJustCheck)) if (!CheckBlock(pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck))
{
fprintf(stderr,"checkblock failure in connectblock\n");
return false; return false;
}
// verify that the view's current state corresponds to the previous block // verify that the view's current state corresponds to the previous block
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash(); uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
@@ -2681,7 +2684,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (!view.HaveJoinSplitRequirements(tx)) if (!view.HaveJoinSplitRequirements(tx))
return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"), return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met"); REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
if (fAddressIndex || fSpentIndex) if (fAddressIndex || fSpentIndex)
{ {
for (size_t j = 0; j < tx.vin.size(); j++) { for (size_t j = 0; j < tx.vin.size(); j++) {
@@ -2718,7 +2720,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
} }
} }
// Add in sigops done by pay-to-script-hash inputs; // Add in sigops done by pay-to-script-hash inputs;
// this is to prevent a "rogue miner" from creating // this is to prevent a "rogue miner" from creating
// an incredibly-expensive-to-validate block. // an incredibly-expensive-to-validate block.
@@ -2800,14 +2801,14 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001); LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum; CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && block.vtx[0].vout.size() > 1 ) if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
{ {
uint64_t checktoshis; uint64_t checktoshis;
if ( (checktoshis = komodo_commission(block)) != 0 ) if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
{ {
if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis ) if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
blockReward += checktoshis; blockReward += checktoshis;
else fprintf(stderr,"checktoshis %.8f vs actual vout[1] %.8f\n",dstr(checktoshis),dstr(block.vtx[0].vout[1].nValue)); else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
} }
} }
if ( block.vtx[0].GetValueOut() > blockReward+1 ) if ( block.vtx[0].GetValueOut() > blockReward+1 )
@@ -2862,7 +2863,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (fTxIndex) if (fTxIndex)
if (!pblocktree->WriteTxIndex(vPos)) if (!pblocktree->WriteTxIndex(vPos))
return AbortNode(state, "Failed to write transaction index"); return AbortNode(state, "Failed to write transaction index");
if (fAddressIndex) { if (fAddressIndex) {
if (!pblocktree->WriteAddressIndex(addressIndex)) { if (!pblocktree->WriteAddressIndex(addressIndex)) {
return AbortNode(state, "Failed to write address index"); return AbortNode(state, "Failed to write address index");
@@ -3086,7 +3086,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
assert(pindexDelete); assert(pindexDelete);
// Read block from disk. // Read block from disk.
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindexDelete)) if (!ReadBlockFromDisk(block, pindexDelete,1))
return AbortNode(state, "Failed to read block"); return AbortNode(state, "Failed to read block");
// Apply the block atomically to the chain state. // Apply the block atomically to the chain state.
uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor(); uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
@@ -3153,7 +3153,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
int64_t nTime1 = GetTimeMicros(); int64_t nTime1 = GetTimeMicros();
CBlock block; CBlock block;
if (!pblock) { if (!pblock) {
if (!ReadBlockFromDisk(block, pindexNew)) if (!ReadBlockFromDisk(block, pindexNew,1))
return AbortNode(state, "Failed to read block"); return AbortNode(state, "Failed to read block");
pblock = &block; pblock = &block;
} }
@@ -3752,9 +3752,11 @@ bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& bl
return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low"); return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
// Check Equihash solution is valid // Check Equihash solution is valid
/*if ( fCheckPOW && !CheckEquihashSolution(&blockhdr, Params()) ) if ( fCheckPOW )
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");*/ {
if ( !CheckEquihashSolution(&blockhdr, Params()) )
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
}
// Check proof of work matches claimed amount // Check proof of work matches claimed amount
/*komodo_index2pubkey33(pubkey33,pindex,height); /*komodo_index2pubkey33(pubkey33,pindex,height);
if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) ) if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
@@ -3763,75 +3765,51 @@ bool CheckBlockHeader(int32_t height,CBlockIndex *pindex, const CBlockHeader& bl
} }
int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime); int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
int32_t komodo_reverify_blockcheck(CValidationState& state,int32_t height,CBlockIndex *pindex)
{
static int32_t oneshot;
CBlockIndex *tipindex; int32_t rewindtarget;
if ( KOMODO_REWIND != 0 )
oneshot = KOMODO_REWIND;
if ( oneshot == 0 && IsInitialBlockDownload() == 0 && (tipindex= chainActive.Tip()) != 0 )
{
// if 200 blocks behind longestchain and no blocks for 2 hours
if ( KOMODO_LONGESTCHAIN > height+200 && KOMODO_NEWBLOCKS == 0 )
{
if ( GetAdjustedTime() > tipindex->nTime+3600*2 )
{
fprintf(stderr,"possible fork: tip.%d longest.%d newblock.%d lag.%d blocktime.%u\n",tipindex->nHeight,KOMODO_LONGESTCHAIN,height,(int32_t)(GetAdjustedTime() - tipindex->nTime),tipindex->nTime);
/*KOMODO_REWIND = tipindex->nHeight - 11;
rewindtarget = tipindex->nHeight - 11;
fprintf(stderr,"rewindtarget <- %d\n",rewindtarget);
oneshot = 1;
while ( rewindtarget > 0 && (tipindex= chainActive.Tip()) != 0 && tipindex->nHeight > rewindtarget )
{
fprintf(stderr,"%d ",(int32_t)tipindex->nHeight);
InvalidateBlock(state,tipindex);
if ( !DisconnectTip(state) )
break;
}
tipindex = chainActive.Tip();
fprintf(stderr,"rewind done to %d\n",tipindex!=0?tipindex->nHeight:-1);*/
}
}
}
return(0);
}
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state, bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
libzcash::ProofVerifier& verifier, libzcash::ProofVerifier& verifier,
bool fCheckPOW, bool fCheckMerkleRoot) bool fCheckPOW, bool fCheckMerkleRoot)
{ {
uint8_t pubkey33[33]; uint8_t pubkey33[33]; uint256 hash;
// These are checks that are independent of context. // These are checks that are independent of context.
hash = block.GetHash();
// Check that the header is valid (particularly PoW). This is mostly // Check that the header is valid (particularly PoW). This is mostly
// redundant with the call in AcceptBlockHeader. // redundant with the call in AcceptBlockHeader.
if (!CheckBlockHeader(height,pindex,block,state,fCheckPOW)) if (!CheckBlockHeader(height,pindex,block,state,fCheckPOW))
{ {
//fprintf(stderr,"checkblockheader error PoW.%d\n",fCheckPOW); fprintf(stderr,"checkblockheader error PoW.%d\n",fCheckPOW);
return false; return false;
} }
if ( fCheckPOW && !CheckEquihashSolution(&block, Params()) ) if ( fCheckPOW )
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
komodo_block2pubkey33(pubkey33,(CBlock *)&block);
if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime) )
{ {
//komodo_reverify_blockcheck(state,height,pindex); //if ( !CheckEquihashSolution(&block, Params()) )
return state.DoS(1, error("CheckBlock(): proof of work failed"),REJECT_INVALID, "high-hash"); // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
komodo_block2pubkey33(pubkey33,(CBlock *)&block);
if ( !CheckProofOfWork(height,pubkey33,hash,block.nBits,Params().GetConsensus(),block.nTime) )
{
int32_t z; for (z=31; z>=0; z--)
fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
fprintf(stderr," failed hash ht.%d\n",height);
return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
}
if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
} }
// Check the merkle root. // Check the merkle root.
if (fCheckMerkleRoot) { if (fCheckMerkleRoot) {
bool mutated; bool mutated;
uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
if (block.hashMerkleRoot != hashMerkleRoot2) if (block.hashMerkleRoot != hashMerkleRoot2)
return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"), return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
REJECT_INVALID, "bad-txnmrklroot", true); REJECT_INVALID, "bad-txnmrklroot", true);
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
// of transactions in a block without affecting the merkle root of a block, // of transactions in a block without affecting the merkle root of a block,
// while still invalidating it. // while still invalidating it.
if (mutated) if (mutated)
return state.DoS(100, error("CheckBlock(): duplicate transaction"), return state.DoS(100, error("CheckBlock: duplicate transaction"),
REJECT_INVALID, "bad-txns-duplicate", true); REJECT_INVALID, "bad-txns-duplicate", true);
} }
@@ -3841,16 +3819,16 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat
// Size limits // Size limits
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
return state.DoS(100, error("CheckBlock(): size limits failed"), return state.DoS(100, error("CheckBlock: size limits failed"),
REJECT_INVALID, "bad-blk-length"); REJECT_INVALID, "bad-blk-length");
// First transaction must be coinbase, the rest must not be // First transaction must be coinbase, the rest must not be
if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
return state.DoS(100, error("CheckBlock(): first tx is not coinbase"), return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
REJECT_INVALID, "bad-cb-missing"); REJECT_INVALID, "bad-cb-missing");
for (unsigned int i = 1; i < block.vtx.size(); i++) for (unsigned int i = 1; i < block.vtx.size(); i++)
if (block.vtx[i].IsCoinBase()) if (block.vtx[i].IsCoinBase())
return state.DoS(100, error("CheckBlock(): more than one coinbase"), return state.DoS(100, error("CheckBlock: more than one coinbase"),
REJECT_INVALID, "bad-cb-multiple"); REJECT_INVALID, "bad-cb-multiple");
// Check transactions // Check transactions
@@ -3859,7 +3837,7 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat
if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,1) < 0 ) if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,1) < 0 )
return error("CheckBlock: komodo_validate_interest failed"); return error("CheckBlock: komodo_validate_interest failed");
if (!CheckTransaction(tx, state, verifier)) if (!CheckTransaction(tx, state, verifier))
return error("CheckBlock(): CheckTransaction failed"); return error("CheckBlock: CheckTransaction failed");
} }
unsigned int nSigOps = 0; unsigned int nSigOps = 0;
BOOST_FOREACH(const CTransaction& tx, block.vtx) BOOST_FOREACH(const CTransaction& tx, block.vtx)
@@ -3867,12 +3845,11 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat
nSigOps += GetLegacySigOpCount(tx); nSigOps += GetLegacySigOpCount(tx);
} }
if (nSigOps > MAX_BLOCK_SIGOPS) if (nSigOps > MAX_BLOCK_SIGOPS)
return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
REJECT_INVALID, "bad-blk-sigops", true); REJECT_INVALID, "bad-blk-sigops", true);
if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 ) if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
//if ( komodo_check_deposit(ASSETCHAINS_SYMBOL[0] == 0 ? height : pindex != 0 ? (int32_t)pindex->nHeight : chainActive.Tip()->nHeight+1,block,pindex==0||pindex->pprev==0?0:pindex->pprev->nTime) < 0 )
{ {
static uint32_t counter; //static uint32_t counter;
//if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 ) //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
fprintf(stderr,"check deposit rejection\n"); fprintf(stderr,"check deposit rejection\n");
return(false); return(false);
@@ -3911,11 +3888,11 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash)) if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
{ {
/*CBlockIndex *heightblock = chainActive[nHeight]; /*CBlockIndex *heightblock = chainActive[nHeight];
if ( heightblock != 0 && heightblock->GetBlockHash() == hash ) if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
{ {
//fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight); //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
return true; return true;
}*/ }*/
return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch"); return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
} }
// Don't accept any forks from the main chain prior to last checkpoint // Don't accept any forks from the main chain prior to last checkpoint
@@ -3986,8 +3963,9 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
// Check for duplicate // Check for duplicate
uint256 hash = block.GetHash(); uint256 hash = block.GetHash();
BlockMap::iterator miSelf = mapBlockIndex.find(hash); BlockMap::iterator miSelf = mapBlockIndex.find(hash);
CBlockIndex *pindex = NULL; CBlockIndex *tipindex,*pindex = NULL;
if (miSelf != mapBlockIndex.end()) { if (miSelf != mapBlockIndex.end())
{
// Block header is already known. // Block header is already known.
pindex = miSelf->second; pindex = miSelf->second;
if (ppindex) if (ppindex)
@@ -4038,7 +4016,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
CBlockIndex *&pindex = *ppindex; CBlockIndex *&pindex = *ppindex;
if (!AcceptBlockHeader(block, state, &pindex)) if (!AcceptBlockHeader(block, state, &pindex))
{ {
//fprintf(stderr,"AcceptBlockHeader rejected\n"); fprintf(stderr,"AcceptBlockHeader rejected\n");
return false; return false;
} }
if ( pindex == 0 ) if ( pindex == 0 )
@@ -4119,20 +4097,23 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
void komodo_currentheight_set(int32_t height); void komodo_currentheight_set(int32_t height);
bool ProcessNewBlock(int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
{ {
// Preliminary checks // Preliminary checks
bool checked; bool checked;
auto verifier = libzcash::ProofVerifier::Disabled(); auto verifier = libzcash::ProofVerifier::Disabled();
if ( chainActive.Tip() != 0 ) if ( chainActive.Tip() != 0 )
komodo_currentheight_set(chainActive.Tip()->nHeight); komodo_currentheight_set(chainActive.Tip()->nHeight);
if ( ASSETCHAINS_SYMBOL[0] == 0 ) checked = CheckBlock(height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
checked = CheckBlock(height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
else checked = CheckBlock(height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
{ {
LOCK(cs_main); LOCK(cs_main);
bool fRequested = MarkBlockAsReceived(pblock->GetHash()); bool fRequested = MarkBlockAsReceived(pblock->GetHash());
fRequested |= fForceProcessing; fRequested |= fForceProcessing;
if ( checked != 0 && komodo_checkPOW(from_miner && ASSETCHAINS_STAKED == 0,pblock,height) < 0 )
{
checked = 0;
fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
}
if (!checked) if (!checked)
{ {
if ( pfrom != 0 ) if ( pfrom != 0 )
@@ -4170,26 +4151,25 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
indexDummy.nHeight = pindexPrev->nHeight + 1; indexDummy.nHeight = pindexPrev->nHeight + 1;
// JoinSplit proofs are verified in ConnectBlock // JoinSplit proofs are verified in ConnectBlock
auto verifier = libzcash::ProofVerifier::Disabled(); auto verifier = libzcash::ProofVerifier::Disabled();
// NOTE: CheckBlockHeader is called by CheckBlock // NOTE: CheckBlockHeader is called by CheckBlock
if (!ContextualCheckBlockHeader(block, state, pindexPrev)) if (!ContextualCheckBlockHeader(block, state, pindexPrev))
{ {
fprintf(stderr,"TestBlockValidity failure A\n"); fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
return false; return false;
} }
if (!CheckBlock(indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot)) if (!CheckBlock(indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
{ {
//fprintf(stderr,"TestBlockValidity failure B\n"); fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
return false; return false;
} }
if (!ContextualCheckBlock(block, state, pindexPrev)) if (!ContextualCheckBlock(block, state, pindexPrev))
{ {
//fprintf(stderr,"TestBlockValidity failure C\n"); fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
return false; return false;
} }
if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW)) if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
{ {
fprintf(stderr,"TestBlockValidity failure D\n"); fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
return false; return false;
} }
assert(state.IsValid()); assert(state.IsValid());
@@ -4264,7 +4244,6 @@ void FindFilesToPrune(std::set<int>& setFilesToPrune)
if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) { if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
return; return;
} }
unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP; unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
uint64_t nCurrentUsage = CalculateCurrentUsage(); uint64_t nCurrentUsage = CalculateCurrentUsage();
// We don't check to prune until after we've allocated new space for files // We don't check to prune until after we've allocated new space for files
@@ -4313,10 +4292,9 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes)
return true; return true;
} }
FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
{ {
static int32_t didinit[1000]; long fsize,fpos; int32_t incr = 16*1024*1024; static int32_t didinit[64];
if (pos.IsNull()) if (pos.IsNull())
return NULL; return NULL;
boost::filesystem::path path = GetBlockPosFilename(pos, prefix); boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
@@ -4330,22 +4308,7 @@ FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
} }
if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 ) if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
{ {
fpos = ftell(file); komodo_prefetch(file);
fseek(file,0,SEEK_END);
fsize = ftell(file);
if ( fsize > incr )
{
char *ignore = (char *)malloc(incr);
if ( ignore != 0 )
{
rewind(file);
while ( fread(ignore,1,incr,file) == incr )
fprintf(stderr,".");
free(ignore);
fprintf(stderr,"blk.%d loaded %ld bytes set fpos.%ld loading.%d\n",(int)pos.nFile,(long)ftell(file),(long)fpos,KOMODO_LOADINGBLOCKS);
}
}
fseek(file,fpos,SEEK_SET);
didinit[pos.nFile] = 1; didinit[pos.nFile] = 1;
} }
if (pos.nPos) { if (pos.nPos) {
@@ -4396,9 +4359,10 @@ CBlockIndex * InsertBlockIndex(uint256 hash)
bool static LoadBlockIndexDB() bool static LoadBlockIndexDB()
{ {
const CChainParams& chainparams = Params(); const CChainParams& chainparams = Params();
LogPrintf("%s: start loading guts\n", __func__);
if (!pblocktree->LoadBlockIndexGuts()) if (!pblocktree->LoadBlockIndexGuts())
return false; return false;
LogPrintf("%s: loaded guts\n", __func__);
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
// Calculate nChainWork // Calculate nChainWork
@@ -4410,7 +4374,9 @@ bool static LoadBlockIndexDB()
vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
//komodo_pindex_init(pindex,(int32_t)pindex->nHeight); //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
} }
//fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
sort(vSortedByHeight.begin(), vSortedByHeight.end()); sort(vSortedByHeight.begin(), vSortedByHeight.end());
//fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
{ {
CBlockIndex* pindex = item.second; CBlockIndex* pindex = item.second;
@@ -4459,6 +4425,7 @@ bool static LoadBlockIndexDB()
pindexBestHeader = pindex; pindexBestHeader = pindex;
//komodo_pindex_init(pindex,(int32_t)pindex->nHeight); //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
} }
//fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
// Load block file info // Load block file info
pblocktree->ReadLastBlockFile(nLastBlockFile); pblocktree->ReadLastBlockFile(nLastBlockFile);
@@ -4488,6 +4455,7 @@ bool static LoadBlockIndexDB()
} }
//komodo_pindex_init(pindex,(int32_t)pindex->nHeight); //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
} }
//fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
{ {
CDiskBlockPos pos(*it, 0); CDiskBlockPos pos(*it, 0);
@@ -4509,7 +4477,6 @@ bool static LoadBlockIndexDB()
// Check whether we have a transaction index // Check whether we have a transaction index
pblocktree->ReadFlag("txindex", fTxIndex); pblocktree->ReadFlag("txindex", fTxIndex);
LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled"); LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
// Check whether we have an address index // Check whether we have an address index
pblocktree->ReadFlag("addressindex", fAddressIndex); pblocktree->ReadFlag("addressindex", fAddressIndex);
LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled"); LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
@@ -4587,6 +4554,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
CValidationState state; CValidationState state;
// No need to verify JoinSplits twice // No need to verify JoinSplits twice
auto verifier = libzcash::ProofVerifier::Disabled(); auto verifier = libzcash::ProofVerifier::Disabled();
//fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
{ {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
@@ -4595,7 +4563,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
break; break;
CBlock block; CBlock block;
// check level 0: read from disk // check level 0: read from disk
if (!ReadBlockFromDisk(block, pindex)) if (!ReadBlockFromDisk(block, pindex,0))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
// check level 1: verify block validity // check level 1: verify block validity
if (nCheckLevel >= 1 && !CheckBlock(pindex->nHeight,pindex,block, state, verifier,0)) if (nCheckLevel >= 1 && !CheckBlock(pindex->nHeight,pindex,block, state, verifier,0))
@@ -4624,6 +4592,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
if (ShutdownRequested()) if (ShutdownRequested())
return true; return true;
} }
//fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
if (pindexFailure) if (pindexFailure)
return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions); return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
@@ -4635,7 +4604,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)))); uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
pindex = chainActive.Next(pindex); pindex = chainActive.Next(pindex);
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex)) if (!ReadBlockFromDisk(block, pindex,0))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
if (!ConnectBlock(block, state, pindex, coins,false, true)) if (!ConnectBlock(block, state, pindex, coins,false, true))
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
@@ -4841,7 +4810,6 @@ bool InitBlockIndex() {
// Use the provided setting for -txindex in the new database // Use the provided setting for -txindex in the new database
fTxIndex = GetBoolArg("-txindex", true); fTxIndex = GetBoolArg("-txindex", true);
pblocktree->WriteFlag("txindex", fTxIndex); pblocktree->WriteFlag("txindex", fTxIndex);
// Use the provided setting for -addressindex in the new database // Use the provided setting for -addressindex in the new database
fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
pblocktree->WriteFlag("addressindex", fAddressIndex); pblocktree->WriteFlag("addressindex", fAddressIndex);
@@ -4852,7 +4820,6 @@ bool InitBlockIndex() {
fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
pblocktree->WriteFlag("spentindex", fSpentIndex); pblocktree->WriteFlag("spentindex", fSpentIndex);
LogPrintf("Initializing databases...\n"); LogPrintf("Initializing databases...\n");
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk) // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
@@ -4896,7 +4863,8 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
int nLoaded = 0; int nLoaded = 0;
try { try {
// This takes over fileIn and calls fclose() on it in the CBufferedFile destructor // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
uint64_t nRewind = blkdat.GetPos(); uint64_t nRewind = blkdat.GetPos();
while (!blkdat.eof()) { while (!blkdat.eof()) {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
@@ -4945,7 +4913,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
// process in case the block isn't known yet // process in case the block isn't known yet
if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
CValidationState state; CValidationState state;
if (ProcessNewBlock(0,state, NULL, &block, true, dbp)) if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
nLoaded++; nLoaded++;
if (state.IsError()) if (state.IsError())
break; break;
@@ -4962,12 +4930,12 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head); std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
while (range.first != range.second) { while (range.first != range.second) {
std::multimap<uint256, CDiskBlockPos>::iterator it = range.first; std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second)) if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second,1))
{ {
LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
head.ToString()); head.ToString());
CValidationState dummy; CValidationState dummy;
if (ProcessNewBlock(0,dummy, NULL, &block, true, &it->second)) if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
{ {
nLoaded++; nLoaded++;
queue.push_back(block.GetHash()); queue.push_back(block.GetHash());
@@ -5321,7 +5289,7 @@ void static ProcessGetData(CNode* pfrom)
{ {
// Send block from disk // Send block from disk
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, (*mi).second)) if (!ReadBlockFromDisk(block, (*mi).second,1))
{ {
assert(!"cannot load block from disk"); assert(!"cannot load block from disk");
} }
@@ -6052,7 +6020,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Such an unrequested block may still be processed, subject to the // Such an unrequested block may still be processed, subject to the
// conditions in AcceptBlock(). // conditions in AcceptBlock().
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload(); bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
ProcessNewBlock(0,state, pfrom, &block, forceProcessing, NULL); ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
int nDoS; int nDoS;
if (state.IsInvalid(nDoS)) { if (state.IsInvalid(nDoS)) {
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),

View File

@@ -190,7 +190,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals);
* @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location. * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
* @return True if state.IsValid() * @return True if state.IsValid()
*/ */
bool ProcessNewBlock(int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp); bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp);
/** Check whether enough disk space is available for an incoming block */ /** Check whether enough disk space is available for an incoming block */
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
/** Open a block file (blk?????.dat) */ /** Open a block file (blk?????.dat) */
@@ -780,8 +780,8 @@ bool GetAddressUnspent(uint160 addressHash, int type,
/** Functions for disk access for blocks */ /** Functions for disk access for blocks */
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos); bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW);
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW);
/** Functions for validating blocks and updating the block tree */ /** Functions for validating blocks and updating the block tree */

View File

@@ -119,7 +119,7 @@ int32_t komodo_is_issuer();
int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo); int32_t komodo_gateway_deposits(CMutableTransaction *txNew,char *symbol,int32_t tokomodo);
int32_t komodo_isrealtime(int32_t *kmdheightp); int32_t komodo_isrealtime(int32_t *kmdheightp);
int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag); int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
uint64_t komodo_commission(const CBlock &block); uint64_t komodo_commission(const CBlock *block);
int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig); int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
@@ -384,7 +384,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
nLastBlockTx = nBlockTx; nLastBlockTx = nBlockTx;
nLastBlockSize = nBlockSize; nLastBlockSize = nBlockSize;
blocktime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
//pblock->nTime = blocktime + 1; //pblock->nTime = blocktime + 1;
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
//LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits); //LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits);
@@ -429,32 +429,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
txNew.vout[0].nValue += nFees; txNew.vout[0].nValue += nFees;
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
/*if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
int32_t i,opretlen; uint8_t opret[256],*ptr;
if ( (nHeight % 60) == 0 || komodo_gateway_deposits(&txNew,(char *)"KMD",1) == 0 )
{
if ( (opretlen= komodo_pax_opreturn((int32_t)nHeight,opret,sizeof(opret))) > 0 ) // have pricefeed
{
txNew.vout.resize(2);
txNew.vout[1].scriptPubKey.resize(opretlen);
ptr = (uint8_t *)txNew.vout[1].scriptPubKey.data();
for (i=0; i<opretlen; i++)
ptr[i] = opret[i];
txNew.vout[1].nValue = 0;
//fprintf(stderr,"opretlen.%d\n",opretlen);
} //else printf("null opretlen for prices\n");
}
}
else if ( komodo_is_issuer() != 0 )
{
komodo_gateway_deposits(&txNew,ASSETCHAINS_SYMBOL,0);
if ( txNew.vout.size() > 1 )
fprintf(stderr,"%s txNew numvouts.%d\n",ASSETCHAINS_SYMBOL,(int32_t)txNew.vout.size());
}*/
pblock->vtx[0] = txNew; pblock->vtx[0] = txNew;
if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission(pblocktemplate->block)) != 0 ) if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 )
{ {
int32_t i; uint8_t *ptr; int32_t i; uint8_t *ptr;
txNew.vout.resize(2); txNew.vout.resize(2);
@@ -487,9 +463,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
if ( ASSETCHAINS_SYMBOL[0] == 0 && NOTARY_PUBKEY33[0] != 0 && pblock->nTime < pindexPrev->nTime+60 ) if ( ASSETCHAINS_SYMBOL[0] == 0 && NOTARY_PUBKEY33[0] != 0 && pblock->nTime < pindexPrev->nTime+60 )
{ {
pblock->nTime = pindexPrev->nTime + 60; pblock->nTime = pindexPrev->nTime + 60;
fprintf(stderr,"block.nTime %u vs prev.%u, gettime.%u vs adjusted.%u\n",(uint32_t)pblock->nTime,(uint32_t)(pindexPrev->nTime + 60),(uint32_t)pblock->GetBlockTime(),(uint32_t)(GetAdjustedTime() + 60));
while ( pblock->GetBlockTime() > GetAdjustedTime() + 60 ) while ( pblock->GetBlockTime() > GetAdjustedTime() + 60 )
sleep(1); sleep(1);
//fprintf(stderr,"block.nTime %u vs prev.%u, gettime.%u vs adjusted.%u\n",(uint32_t)pblock->nTime,(uint32_t)(pindexPrev->nTime + 60),(uint32_t)pblock->GetBlockTime(),(uint32_t)(GetAdjustedTime() + 60));
} }
pblock->nSolution.clear(); pblock->nSolution.clear();
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
@@ -499,7 +475,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
{ {
//static uint32_t counter; //static uint32_t counter;
//if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 ) //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
//fprintf(stderr,"warning: miner testblockvalidity failed\n"); // fprintf(stderr,"warning: miner testblockvalidity failed\n");
return(0); return(0);
} }
} }
@@ -655,11 +631,24 @@ static bool ProcessBlockFound(CBlock* pblock)
// Process this block the same as if we had received it from another node // Process this block the same as if we had received it from another node
CValidationState state; CValidationState state;
if (!ProcessNewBlock(chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL)) if (!ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL))
return error("KomodoMiner: ProcessNewBlock, block not accepted"); return error("KomodoMiner: ProcessNewBlock, block not accepted");
TrackMinedBlock(pblock->GetHash()); TrackMinedBlock(pblock->GetHash());
if ( ASSETCHAINS_STAKED != 0 )
{
fprintf(stderr,"broadcast new block t.%u\n",(uint32_t)time(NULL));
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
if ( pnode->hSocket == INVALID_SOCKET )
continue;
pnode->PushMessage("block", *pblock);
}
}
fprintf(stderr,"finished broadcast new block t.%u\n",(uint32_t)time(NULL));
}
return true; return true;
} }
@@ -669,7 +658,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
int32_t FOUND_BLOCK,KOMODO_MAYBEMINED; int32_t FOUND_BLOCK,KOMODO_MAYBEMINED;
extern int32_t KOMODO_LASTMINED; extern int32_t KOMODO_LASTMINED;
int32_t roundrobin_delay; int32_t roundrobin_delay;
arith_uint256 HASHTarget; arith_uint256 HASHTarget,HASHTarget_POW;
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
void static BitcoinMiner(CWallet *pwallet) void static BitcoinMiner(CWallet *pwallet)
@@ -870,15 +859,15 @@ void static BitcoinMiner()
if ( ASSETCHAINS_STAKED != 0 && NOTARY_PUBKEY33[0] == 0 ) if ( ASSETCHAINS_STAKED != 0 && NOTARY_PUBKEY33[0] == 0 )
{ {
int32_t percPoS,z; int32_t percPoS,z;
if ( Mining_height <= 100 ) /*if ( Mining_height <= 100 )
{ {
sleep(60); sleep(60);
continue; continue;
} }*/
HASHTarget = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED); HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
for (z=31; z>=0; z--) for (z=31; z>=0; z--)
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]); fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
fprintf(stderr," PoW for staked coin\n"); fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%%\n",percPoS,(int32_t)ASSETCHAINS_STAKED);
} }
while (true) while (true)
{ {
@@ -904,8 +893,10 @@ void static BitcoinMiner()
crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size()); crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
// (x_1, x_2, ...) = A(I, V, n, k) // (x_1, x_2, ...) = A(I, V, n, k)
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString()); LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
arith_uint256 hashTarget = HASHTarget; arith_uint256 hashTarget;
//fprintf(stderr,"running solver\n"); if ( NOTARY_PUBKEY33[0] == 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 )
hashTarget = HASHTarget_POW;
else hashTarget = HASHTarget;
std::function<bool(std::vector<unsigned char>)> validBlock = std::function<bool(std::vector<unsigned char>)> validBlock =
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams] [&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
@@ -913,20 +904,31 @@ void static BitcoinMiner()
[&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams] [&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams]
#endif #endif
(std::vector<unsigned char> soln) { (std::vector<unsigned char> soln) {
int32_t z; arith_uint256 h; CBlock B;
// Write the solution to the hash and compute the result. // Write the solution to the hash and compute the result.
LogPrint("pow", "- Checking solution against target\n"); LogPrint("pow", "- Checking solution against target\n");
pblock->nSolution = soln; pblock->nSolution = soln;
solutionTargetChecks.increment(); solutionTargetChecks.increment();
if ( UintToArith256(pblock->GetHash()) > HASHTarget ) B = *pblock;
{ h = UintToArith256(B.GetHash());
//if ( ASSETCHAINS_SYMBOL[0] != 0 ) if ( h > hashTarget )
// fprintf(stderr," missed target\n");
return false; return false;
} /*for (z=31; z>=16; z--)
fprintf(stderr,"%02x",((uint8_t *)&h)[z]);
fprintf(stderr," mined ");
for (z=31; z>=16; z--)
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]);
fprintf(stderr," hashTarget ");
for (z=31; z>=16; z--)
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
fprintf(stderr," POW\n");*/
CValidationState state; CValidationState state;
if ( !TestBlockValidity(state, *pblock, chainActive.Tip(), true, false)) if ( !TestBlockValidity(state,B, chainActive.Tip(), true, false))
{ {
fprintf(stderr,"Invalid block mined, try again\n"); h = UintToArith256(B.GetHash());
for (z=31; z>=0; z--)
fprintf(stderr,"%02x",((uint8_t *)&h)[z]);
fprintf(stderr," Invalid block mined, try again\n");
return(false); return(false);
} }
if ( ASSETCHAINS_STAKED == 0 ) if ( ASSETCHAINS_STAKED == 0 )
@@ -948,13 +950,13 @@ void static BitcoinMiner()
{ {
if ( NOTARY_PUBKEY33[0] != 0 ) if ( NOTARY_PUBKEY33[0] != 0 )
{ {
printf("need to wait %d seconds to submit\n",(int32_t)(pblock->nTime - GetAdjustedTime())); printf("need to wait %d seconds to submit staked block\n",(int32_t)(B.nTime - GetAdjustedTime()));
while ( GetAdjustedTime() < pblock->nTime ) while ( GetAdjustedTime() < B.nTime )
sleep(1); sleep(1);
} }
else else
{ {
uint256 tmp = pblock->GetHash(); uint256 tmp = B.GetHash();
int32_t z; for (z=31; z>=0; z--) int32_t z; for (z=31; z>=0; z--)
fprintf(stderr,"%02x",((uint8_t *)&tmp)[z]); fprintf(stderr,"%02x",((uint8_t *)&tmp)[z]);
fprintf(stderr," mined block!\n"); fprintf(stderr," mined block!\n");
@@ -964,11 +966,11 @@ void static BitcoinMiner()
// Found a solution // Found a solution
SetThreadPriority(THREAD_PRIORITY_NORMAL); SetThreadPriority(THREAD_PRIORITY_NORMAL);
LogPrintf("KomodoMiner:\n"); LogPrintf("KomodoMiner:\n");
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), HASHTarget.GetHex()); LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", B.GetHash().GetHex(), HASHTarget.GetHex());
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
if (ProcessBlockFound(pblock, *pwallet, reservekey)) { if (ProcessBlockFound(&B, *pwallet, reservekey)) {
#else #else
if (ProcessBlockFound(pblock)) { if (ProcessBlockFound(&B)) {
#endif #endif
// Ignore chain updates caused by us // Ignore chain updates caused by us
std::lock_guard<std::mutex> lock{m_cs}; std::lock_guard<std::mutex> lock{m_cs};
@@ -1083,13 +1085,17 @@ void static BitcoinMiner()
// Update nNonce and nTime // Update nNonce and nTime
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
pblock->nBits = savebits; pblock->nBits = savebits;
if ( ASSETCHAINS_STAKED == 0 || NOTARY_PUBKEY33[0] == 0 ) /*if ( NOTARY_PUBKEY33[0] == 0 )
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
{ {
// Changing pblock->nTime can change work required on testnet: int32_t percPoS;
HASHTarget.SetCompact(pblock->nBits); UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
} if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
{
// Changing pblock->nTime can change work required on testnet:
HASHTarget.SetCompact(pblock->nBits);
HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
}
}*/
} }
} }
} }

View File

@@ -57,9 +57,9 @@ unsigned int TxConfirmStats::FindBucketIndex(double val)
auto it = bucketMap.lower_bound(val); auto it = bucketMap.lower_bound(val);
if ( it != bucketMap.end() ) if ( it != bucketMap.end() )
{ {
static uint32_t counter; //static uint32_t counter;
if ( counter++ < 1 ) //if ( counter++ < 1 )
fprintf(stderr,"%s FindBucketIndex violation: from val %f\n",ASSETCHAINS_SYMBOL,val); // fprintf(stderr,"%s FindBucketIndex violation: from val %f\n",ASSETCHAINS_SYMBOL,val);
} }
return it->second; return it->second;
} }

View File

@@ -136,6 +136,9 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash,unsigned int
extern int32_t KOMODO_REWIND; extern int32_t KOMODO_REWIND;
bool fNegative,fOverflow; uint8_t origpubkey33[33]; int32_t i,nonzpkeys=0,nonz=0,special=0,special2=0,notaryid=-1,flag = 0, mids[66]; uint32_t tiptime,blocktimes[66]; bool fNegative,fOverflow; uint8_t origpubkey33[33]; int32_t i,nonzpkeys=0,nonz=0,special=0,special2=0,notaryid=-1,flag = 0, mids[66]; uint32_t tiptime,blocktimes[66];
arith_uint256 bnTarget; uint8_t pubkeys[66][33]; arith_uint256 bnTarget; uint8_t pubkeys[66][33];
//for (i=31; i>=0; i--)
// fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
//fprintf(stderr," checkpow\n");
memcpy(origpubkey33,pubkey33,33); memcpy(origpubkey33,pubkey33,33);
memset(blocktimes,0,sizeof(blocktimes)); memset(blocktimes,0,sizeof(blocktimes));
tiptime = komodo_chainactive_timestamp(); tiptime = komodo_chainactive_timestamp();
@@ -192,23 +195,20 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash,unsigned int
return true; return true;
if ( ASSETCHAINS_SYMBOL[0] != 0 || height > 792000 ) if ( ASSETCHAINS_SYMBOL[0] != 0 || height > 792000 )
{ {
if ( 0 && height > 792000 ) //if ( 0 && height > 792000 )
{ {
for (i=31; i>=0; i--) for (i=31; i>=0; i--)
printf("%02x",((uint8_t *)&hash)[i]); fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
printf(" hash vs "); fprintf(stderr," hash vs ");
for (i=31; i>=0; i--) for (i=31; i>=0; i--)
printf("%02x",((uint8_t *)&bnTarget)[i]); fprintf(stderr,"%02x",((uint8_t *)&bnTarget)[i]);
printf(" ht.%d special.%d notaryid.%d ht.%d mod.%d error\n",height,special,notaryid,height,(height % 35)); fprintf(stderr," ht.%d special.%d notaryid.%d mod.%d error\n",height,special,notaryid,(height % 35));
for (i=0; i<33; i++) for (i=0; i<33; i++)
printf("%02x",pubkey33[i]); fprintf(stderr,"%02x",pubkey33[i]);
printf(" <- pubkey\n"); fprintf(stderr," <- pubkey\n");
for (i=0; i<33; i++) for (i=0; i<33; i++)
printf("%02x",origpubkey33[i]); fprintf(stderr,"%02x",origpubkey33[i]);
printf(" <- origpubkey\n"); fprintf(stderr," <- origpubkey\n");
for (i=0; i<66; i++)
printf("%d ",mids[i]);
printf(" minerids from ht.%d\n",height);
} }
return false; return false;
} }

View File

@@ -214,7 +214,7 @@ static bool rest_block(HTTPRequest* req,
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
if (!ReadBlockFromDisk(block, pblockindex)) if (!ReadBlockFromDisk(block, pblockindex,1))
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
} }

View File

@@ -438,7 +438,7 @@ UniValue getblockdeltas(const UniValue& params, bool fHelp)
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
if(!ReadBlockFromDisk(block, pblockindex)) if(!ReadBlockFromDisk(block, pblockindex,1))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
return blockToDeltasJSON(block, pblockindex); return blockToDeltasJSON(block, pblockindex);
@@ -693,7 +693,7 @@ UniValue getblock(const UniValue& params, bool fHelp)
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
if(!ReadBlockFromDisk(block, pblockindex)) if(!ReadBlockFromDisk(block, pblockindex,1))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
if (!fVerbose) if (!fVerbose)
@@ -746,6 +746,7 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
} }
#include "komodo_defs.h" #include "komodo_defs.h"
#include "komodo_structs.h"
#define IGUANA_MAXSCRIPTSIZE 10001 #define IGUANA_MAXSCRIPTSIZE 10001
#define KOMODO_KVDURATION 1440 #define KOMODO_KVDURATION 1440
@@ -760,6 +761,8 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,
int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width); int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width);
int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen);
int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip); int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip);
int32_t komodo_MoMoMdata(char *hexstr,int32_t hexsize,struct komodo_ccdataMoMoM *mdata,char *symbol,int32_t kmdheight,int32_t notarized_height);
struct komodo_ccdata_entry *komodo_allMoMs(int32_t *nump,uint256 *MoMoMp,int32_t kmdstarti,int32_t kmdendi);
UniValue kvsearch(const UniValue& params, bool fHelp) UniValue kvsearch(const UniValue& params, bool fHelp)
{ {
@@ -796,6 +799,74 @@ UniValue kvsearch(const UniValue& params, bool fHelp)
return ret; return ret;
} }
UniValue allMoMs(const UniValue& params, bool fHelp)
{
struct komodo_ccdata_entry *allMoMs; uint256 MoMoM; int32_t num,i,kmdstarti,kmdendi; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR);
if ( fHelp || params.size() != 2 )
throw runtime_error("allMoMs kmdstarti kmdendi\n");
LOCK(cs_main);
kmdstarti = atoi(params[0].get_str().c_str());
kmdendi = atoi(params[1].get_str().c_str());
ret.push_back(Pair("kmdstarti",kmdstarti));
ret.push_back(Pair("kmdendi",kmdendi));
if ( (allMoMs= komodo_allMoMs(&num,&MoMoM,kmdstarti,kmdendi)) != 0 )
{
for (i=0; i<num; i++)
{
UniValue item(UniValue::VOBJ);
item.push_back(Pair("MoM",allMoMs[i].MoM.ToString()));
item.push_back(Pair("coin",allMoMs[i].symbol));
item.push_back(Pair("notarized_height",allMoMs[i].notarized_height));
item.push_back(Pair("kmdheight",allMoMs[i].kmdheight));
item.push_back(Pair("txi",allMoMs[i].txi));
a.push_back(item);
}
ret.push_back(Pair("MoMs",a));
ret.push_back(Pair("MoMoM",MoMoM.ToString()));
ret.push_back(Pair("MoMoMdepth",(int)num));
free(allMoMs);
}
return(ret);
}
UniValue MoMoMdata(const UniValue& params, bool fHelp)
{
char *symbol,hexstr[16384+1]; struct komodo_ccdataMoMoM mdata; int32_t i,kmdheight,notarized_height; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR);
if ( fHelp || params.size() != 3 )
throw runtime_error("MoMoMdata symbol kmdheight notarized_height\n");
LOCK(cs_main);
symbol = (char *)params[0].get_str().c_str();
kmdheight = atoi(params[1].get_str().c_str());
notarized_height = atoi(params[2].get_str().c_str());
ret.push_back(Pair("coin",symbol));
ret.push_back(Pair("kmdheight",kmdheight));
ret.push_back(Pair("notarized_height",notarized_height));
memset(&mdata,0,sizeof(mdata));
if ( komodo_MoMoMdata(hexstr,sizeof(hexstr),&mdata,symbol,kmdheight,notarized_height) == 0 )
{
ret.push_back(Pair("kmdstarti",mdata.kmdstarti));
ret.push_back(Pair("kmdendi",mdata.kmdendi));
ret.push_back(Pair("MoMoM",mdata.MoMoM.ToString()));
ret.push_back(Pair("MoMoMdepth",mdata.MoMoMdepth));
ret.push_back(Pair("numnotarizations",mdata.numpairs));
if ( mdata.pairs != 0 )
{
//fprintf(stderr,"mdata.pairs free %p, numpairs.%d\n",mdata.pairs,mdata.numpairs);
for (i=0; i<mdata.numpairs; i++)
{
UniValue item(UniValue::VOBJ);
item.push_back(Pair("height",(int)mdata.pairs[i].notarized_height));
item.push_back(Pair("MoMoMoffset",(int)mdata.pairs[i].MoMoMoffset));
a.push_back(item);
}
free(mdata.pairs);
}
ret.push_back(Pair("notarizations",a));
ret.push_back(Pair("data",hexstr));
} else ret.push_back(Pair("error","cant calculate MoMoM"));
return(ret);
}
UniValue height_MoM(const UniValue& params, bool fHelp) UniValue height_MoM(const UniValue& params, bool fHelp)
{ {
int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; uint256 MoM,MoMoM,kmdtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); int32_t height,depth,notarized_height,MoMoMdepth,MoMoMoffset,kmdstarti,kmdendi; uint256 MoM,MoMoM,kmdtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR);
@@ -891,7 +962,7 @@ UniValue txMoMproof(const UniValue& params, bool fHelp)
if (fHavePruned && !(blockIndex->nStatus & BLOCK_HAVE_DATA) && blockIndex->nTx > 0) if (fHavePruned && !(blockIndex->nStatus & BLOCK_HAVE_DATA) && blockIndex->nTx > 0)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
if(!ReadBlockFromDisk(block, blockIndex)) if(!ReadBlockFromDisk(block, blockIndex,1))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
// Locate the transaction in the block // Locate the transaction in the block
@@ -939,7 +1010,7 @@ UniValue minerids(const UniValue& params, bool fHelp)
if ( pblockindex != 0 ) if ( pblockindex != 0 )
timestamp = pblockindex->GetBlockTime(); timestamp = pblockindex->GetBlockTime();
} }
if ( 0 && (n= komodo_minerids(minerids,height,(int32_t)(sizeof(minerids)/sizeof(*minerids)))) > 0 ) if ( (n= komodo_minerids(minerids,height,(int32_t)(sizeof(minerids)/sizeof(*minerids)))) > 0 )
{ {
memset(tally,0,sizeof(tally)); memset(tally,0,sizeof(tally));
numnotaries = komodo_notaries(pubkeys,height,timestamp); numnotaries = komodo_notaries(pubkeys,height,timestamp);
@@ -977,6 +1048,7 @@ UniValue minerids(const UniValue& params, bool fHelp)
a.push_back(item); a.push_back(item);
} }
ret.push_back(Pair("mined", a)); ret.push_back(Pair("mined", a));
ret.push_back(Pair("numnotaries", numnotaries));
} else ret.push_back(Pair("error", (char *)"couldnt extract minerids")); } else ret.push_back(Pair("error", (char *)"couldnt extract minerids"));
return ret; return ret;
} }

View File

@@ -135,6 +135,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "paxpending", 0 }, { "paxpending", 0 },
{ "notaries", 2 }, { "notaries", 2 },
{ "height_MoM", 1 }, { "height_MoM", 1 },
{ "MoMoMdata", 3 },
{ "allMoMs", 2 },
{ "txMoMproof", 1 }, { "txMoMproof", 1 },
{ "minerids", 1 }, { "minerids", 1 },
{ "kvsearch", 1 }, { "kvsearch", 1 },

View File

@@ -267,7 +267,7 @@ UniValue generate(const UniValue& params, bool fHelp)
} }
endloop: endloop:
CValidationState state; CValidationState state;
if (!ProcessNewBlock(chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL)) if (!ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL))
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
++nHeight; ++nHeight;
blockHashes.push_back(pblock->GetHash().GetHex()); blockHashes.push_back(pblock->GetHash().GetHex());
@@ -807,7 +807,7 @@ UniValue submitblock(const UniValue& params, bool fHelp)
CValidationState state; CValidationState state;
submitblock_StateCatcher sc(block.GetHash()); submitblock_StateCatcher sc(block.GetHash());
RegisterValidationInterface(&sc); RegisterValidationInterface(&sc);
bool fAccepted = ProcessNewBlock(chainActive.Tip()->nHeight+1,state, NULL, &block, true, NULL); bool fAccepted = ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, &block, true, NULL);
UnregisterValidationInterface(&sc); UnregisterValidationInterface(&sc);
if (fBlockPresent) if (fBlockPresent)
{ {

View File

@@ -53,6 +53,10 @@ extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE;
extern char ASSETCHAINS_SYMBOL[]; extern char ASSETCHAINS_SYMBOL[];
int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp); int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp);
#define KOMODO_VERSION "0.1.1" #define KOMODO_VERSION "0.1.1"
extern uint16_t ASSETCHAINS_PORT;
extern uint32_t ASSETCHAINS_CC;
extern uint32_t ASSETCHAINS_MAGIC;
extern uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY;
UniValue getinfo(const UniValue& params, bool fHelp) UniValue getinfo(const UniValue& params, bool fHelp)
{ {
@@ -149,6 +153,28 @@ UniValue getinfo(const UniValue& params, bool fHelp)
obj.push_back(Pair("lastmined", KOMODO_LASTMINED)); obj.push_back(Pair("lastmined", KOMODO_LASTMINED));
} }
} }
if ( ASSETCHAINS_CC != 0 )
obj.push_back(Pair("CCid", (int)ASSETCHAINS_CC));
if ( ASSETCHAINS_SYMBOL[0] != 0 )
{
obj.push_back(Pair("name", ASSETCHAINS_SYMBOL));
obj.push_back(Pair("port", ASSETCHAINS_PORT));
obj.push_back(Pair("magic", (int)ASSETCHAINS_MAGIC));
if ( ASSETCHAINS_SUPPLY != 0 )
obj.push_back(Pair("premine", ASSETCHAINS_SUPPLY));
if ( ASSETCHAINS_REWARD != 0 )
obj.push_back(Pair("reward", ASSETCHAINS_REWARD));
if ( ASSETCHAINS_HALVING != 0 )
obj.push_back(Pair("halving", ASSETCHAINS_HALVING));
if ( ASSETCHAINS_DECAY != 0 )
obj.push_back(Pair("decay", ASSETCHAINS_DECAY));
if ( ASSETCHAINS_ENDSUBSIDY != 0 )
obj.push_back(Pair("endsubsidy", ASSETCHAINS_ENDSUBSIDY));
if ( ASSETCHAINS_COMMISSION != 0 )
obj.push_back(Pair("commission", ASSETCHAINS_COMMISSION));
if ( ASSETCHAINS_STAKED != 0 )
obj.push_back(Pair("staked", ASSETCHAINS_STAKED));
}
return obj; return obj;
} }
@@ -203,7 +229,10 @@ UniValue jumblr_deposit(const UniValue& params, bool fHelp)
{ {
string addr = params[0].get_str(); string addr = params[0].get_str();
if ( (retval= Jumblr_depositaddradd((char *)addr.c_str())) >= 0 ) if ( (retval= Jumblr_depositaddradd((char *)addr.c_str())) >= 0 )
{
result.push_back(Pair("result", retval)); result.push_back(Pair("result", retval));
JUMBLR_PAUSE = 0;
}
else result.push_back(Pair("error", retval)); else result.push_back(Pair("error", retval));
} else result.push_back(Pair("error", "invalid address")); } else result.push_back(Pair("error", "invalid address"));
return(result); return(result);
@@ -222,6 +251,7 @@ UniValue jumblr_secret(const UniValue& params, bool fHelp)
retval = Jumblr_secretaddradd((char *)addr.c_str()); retval = Jumblr_secretaddradd((char *)addr.c_str());
result.push_back(Pair("result", "success")); result.push_back(Pair("result", "success"));
result.push_back(Pair("num", retval)); result.push_back(Pair("num", retval));
JUMBLR_PAUSE = 0;
} else result.push_back(Pair("error", "invalid address")); } else result.push_back(Pair("error", "invalid address"));
return(result); return(result);
} }

View File

@@ -174,6 +174,7 @@ int32_t komodo_longestchain()
CopyNodeStats(vstats); CopyNodeStats(vstats);
BOOST_FOREACH(const CNodeStats& stats, vstats) BOOST_FOREACH(const CNodeStats& stats, vstats)
{ {
//fprintf(stderr,"komodo_longestchain iter.%d\n",n);
CNodeStateStats statestats; CNodeStateStats statestats;
bool fStateStats = GetNodeStateStats(stats.nodeid,statestats); bool fStateStats = GetNodeStateStats(stats.nodeid,statestats);
ht = 0; ht = 0;

View File

@@ -522,7 +522,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp)
} }
CBlock block; CBlock block;
if(!ReadBlockFromDisk(block, pblockindex)) if(!ReadBlockFromDisk(block, pblockindex,1))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
unsigned int ntxFound = 0; unsigned int ntxFound = 0;

View File

@@ -238,9 +238,11 @@ UniValue help(const UniValue& params, bool fHelp)
return tableRPC.help(strCommand); return tableRPC.help(strCommand);
} }
extern char ASSETCHAINS_SYMBOL[];
UniValue stop(const UniValue& params, bool fHelp) UniValue stop(const UniValue& params, bool fHelp)
{ {
char buf[64];
// Accept the deprecated and ignored 'detach' boolean argument // Accept the deprecated and ignored 'detach' boolean argument
if (fHelp || params.size() > 1) if (fHelp || params.size() > 1)
throw runtime_error( throw runtime_error(
@@ -248,7 +250,8 @@ UniValue stop(const UniValue& params, bool fHelp)
"\nStop Komodo server."); "\nStop Komodo server.");
// Shutdown will take long enough that the response should get back // Shutdown will take long enough that the response should get back
StartShutdown(); StartShutdown();
return "Komodo server stopping"; sprintf(buf,"%s Komodo server stopping",ASSETCHAINS_SYMBOL);
return buf;
} }
/** /**
@@ -299,6 +302,8 @@ static const CRPCCommand vRPCCommands[] =
{ "blockchain", "paxpending", &paxpending, true }, { "blockchain", "paxpending", &paxpending, true },
{ "blockchain", "paxprices", &paxprices, true }, { "blockchain", "paxprices", &paxprices, true },
{ "blockchain", "notaries", &notaries, true }, { "blockchain", "notaries", &notaries, true },
{ "blockchain", "allMoMs", &allMoMs, true },
{ "blockchain", "MoMoMdata", &MoMoMdata, true },
{ "blockchain", "height_MoM", &height_MoM, true }, { "blockchain", "height_MoM", &height_MoM, true },
{ "blockchain", "txMoMproof", &txMoMproof, true }, { "blockchain", "txMoMproof", &txMoMproof, true },
{ "blockchain", "minerids", &minerids, true }, { "blockchain", "minerids", &minerids, true },

View File

@@ -312,6 +312,8 @@ extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpc
extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp); // in rpcdisclosure.cpp extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp); // in rpcdisclosure.cpp
extern UniValue z_validatepaymentdisclosure(const UniValue &params, bool fHelp); // in rpcdisclosure.cpp extern UniValue z_validatepaymentdisclosure(const UniValue &params, bool fHelp); // in rpcdisclosure.cpp
extern UniValue allMoMs(const UniValue& params, bool fHelp);
extern UniValue MoMoMdata(const UniValue& params, bool fHelp);
extern UniValue height_MoM(const UniValue& params, bool fHelp); extern UniValue height_MoM(const UniValue& params, bool fHelp);
extern UniValue txMoMproof(const UniValue& params, bool fHelp); extern UniValue txMoMproof(const UniValue& params, bool fHelp);
extern UniValue notaries(const UniValue& params, bool fHelp); extern UniValue notaries(const UniValue& params, bool fHelp);

View File

@@ -17,3 +17,6 @@ External contributors:
Tadanori TERUYA Tadanori TERUYA
Sean Bowe Sean Bowe
Daira Hopwood Daira Hopwood
@mugatu on forum.z.cash
David Mercer
Joshua Yabut

View File

@@ -6,6 +6,13 @@
#* @copyright MIT license (see LICENSE file) #* @copyright MIT license (see LICENSE file)
#*******************************************************************************/ #*******************************************************************************/
# Determine building operating system
ifeq ($(OS),Windows_NT)
uname_S := Windows
else
uname_S := $(shell uname -s)
endif
# To override these, use "make OPTFLAGS=..." etc. # To override these, use "make OPTFLAGS=..." etc.
CURVE = BN128 CURVE = BN128
OPTFLAGS = -O2 -march=native -mtune=native OPTFLAGS = -O2 -march=native -mtune=native
@@ -106,18 +113,9 @@ EXECUTABLES_WITH_GTEST =
EXECUTABLES_WITH_SUPERCOP = \ EXECUTABLES_WITH_SUPERCOP = \
libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark
GTEST_TESTS = libsnark/gtests GTEST_TESTS =
GTEST_SRCS = \ GTEST_SRCS =
libsnark/algebra/curves/tests/test_bilinearity.cpp \
libsnark/algebra/curves/tests/test_groups.cpp \
libsnark/algebra/fields/tests/test_bigint.cpp \
libsnark/algebra/fields/tests/test_fields.cpp \
libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp \
libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp \
libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp \
libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp \
libsnark/gtests.cpp
DOCS = README.html DOCS = README.html
@@ -175,6 +173,7 @@ all: \
$(if $(NO_GTEST),,$(EXECUTABLES_WITH_GTEST) $(GTEST_TESTS)) \ $(if $(NO_GTEST),,$(EXECUTABLES_WITH_GTEST) $(GTEST_TESTS)) \
$(if $(NO_SUPERCOP),,$(EXECUTABLES_WITH_SUPERCOP)) \ $(if $(NO_SUPERCOP),,$(EXECUTABLES_WITH_SUPERCOP)) \
$(EXECUTABLES) \ $(EXECUTABLES) \
$(LIBSNARK_A) \
$(if $(NO_DOCS),,doc) $(if $(NO_DOCS),,doc)
doc: $(DOCS) doc: $(DOCS)

View File

@@ -14,7 +14,7 @@ Copyright (c) 2012-2014 SCIPR Lab and contributors (see [AUTHORS] file).
[TOC] [TOC]
<!--- <!---
NOTE: the file you are reading is in Markdown format, which is fairly readable NOTE: the file you are reading is in Markdown format, which is is fairly readable
directly, but can be converted into an HTML file with much nicer formatting. directly, but can be converted into an HTML file with much nicer formatting.
To do so, run "make doc" (this requires the python-markdown package) and view To do so, run "make doc" (this requires the python-markdown package) and view
the resulting file README.html. Alternatively, view the latest HTML version at the resulting file README.html. Alternatively, view the latest HTML version at
@@ -84,7 +84,7 @@ The libsnark library currently provides a C++ implementation of:
This is easily adapted to any other Random Access Machine that satisfies a This is easily adapted to any other Random Access Machine that satisfies a
simple load-store interface. simple load-store interface.
3. A scalable for TinyRAM using Proof-Carrying Data, as explained in \[BCTV14b] 3. A scalable for TinyRAM using Proof-Carrying Data, as explained in \[BCTV14b]
4. Zero-knowledge cluster MapReduce, as explained in \[CTV15]. 4. Zero-knowldge cluster MapReduce, as explained in \[CTV15].
The zkSNARK construction implemented by libsnark follows, extends, and The zkSNARK construction implemented by libsnark follows, extends, and
optimizes the approach described in \[BCTV14], itself an extension of optimizes the approach described in \[BCTV14], itself an extension of
@@ -272,7 +272,7 @@ To build just the static library `libsnark.a`, run:
$ make lib STATIC=1 $ make lib STATIC=1
Note that static compilation requires static versions of all libraries it depends on. Note that static compilation requires static versions of all libraries it depends on.
It may help to minimize these dependencies by appending It may help to minize these dependencies by appending
`CURVE=ALT_BN128 NO_PROCPS=1 NO_GTEST=1 NO_SUPERCOP=1`. On Fedora 21, the requisite `CURVE=ALT_BN128 NO_PROCPS=1 NO_GTEST=1 NO_SUPERCOP=1`. On Fedora 21, the requisite
library RPM dependencies are then: library RPM dependencies are then:
`boost-static glibc-static gmp-static libstdc++-static openssl-static zlib-static `boost-static glibc-static gmp-static libstdc++-static openssl-static zlib-static
@@ -399,7 +399,7 @@ The following flags change the behavior of the compiled code.
* `make MULTICORE=1` * `make MULTICORE=1`
Enable parallelized execution of the ppzkSNARK generator and prover, using OpenMP. Enable parallelized execution of the ppzkSNARK generator and prover, using OpenMP.
This will utilize all cores on the CPU for heavyweight parallelizable operations such as This will utilize all cores on the CPU for heavyweight parallelizabe operations such as
FFT and multiexponentiation. The default is single-core. FFT and multiexponentiation. The default is single-core.
To override the maximum number of cores used, set the environment variable `OMP_NUM_THREADS` To override the maximum number of cores used, set the environment variable `OMP_NUM_THREADS`

View File

@@ -6,16 +6,17 @@
*****************************************************************************/ *****************************************************************************/
#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" #include "algebra/curves/alt_bn128/alt_bn128_g1.hpp"
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
#ifdef PROFILE_OP_COUNTS #ifdef PROFILE_OP_COUNTS
long long alt_bn128_G1::add_cnt = 0; int64_t alt_bn128_G1::add_cnt = 0;
long long alt_bn128_G1::dbl_cnt = 0; int64_t alt_bn128_G1::dbl_cnt = 0;
#endif #endif
std::vector<size_t> alt_bn128_G1::wnaf_window_table; std::vector<uint64_t> alt_bn128_G1::wnaf_window_table;
std::vector<size_t> alt_bn128_G1::fixed_base_exp_window_table; std::vector<uint64_t> alt_bn128_G1::fixed_base_exp_window_table;
alt_bn128_G1 alt_bn128_G1::G1_zero; alt_bn128_G1 alt_bn128_G1::G1_zero;
alt_bn128_G1 alt_bn128_G1::G1_one; alt_bn128_G1 alt_bn128_G1::G1_one;
@@ -256,7 +257,7 @@ alt_bn128_G1 alt_bn128_G1::add(const alt_bn128_G1 &other) const
alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const
{ {
#ifdef DEBUG #ifdef DEBUG
assert(other.is_special()); assert_except(other.is_special());
#endif #endif
// handle special cases having to do with O // handle special cases having to do with O

View File

@@ -20,11 +20,11 @@ std::istream& operator>>(std::istream &, alt_bn128_G1&);
class alt_bn128_G1 { class alt_bn128_G1 {
public: public:
#ifdef PROFILE_OP_COUNTS #ifdef PROFILE_OP_COUNTS
static long long add_cnt; static int64_t add_cnt;
static long long dbl_cnt; static int64_t dbl_cnt;
#endif #endif
static std::vector<size_t> wnaf_window_table; static std::vector<uint64_t> wnaf_window_table;
static std::vector<size_t> fixed_base_exp_window_table; static std::vector<uint64_t> fixed_base_exp_window_table;
static alt_bn128_G1 G1_zero; static alt_bn128_G1 G1_zero;
static alt_bn128_G1 G1_one; static alt_bn128_G1 G1_one;

View File

@@ -6,16 +6,17 @@
*****************************************************************************/ *****************************************************************************/
#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" #include "algebra/curves/alt_bn128/alt_bn128_g2.hpp"
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
#ifdef PROFILE_OP_COUNTS #ifdef PROFILE_OP_COUNTS
long long alt_bn128_G2::add_cnt = 0; int64_t alt_bn128_G2::add_cnt = 0;
long long alt_bn128_G2::dbl_cnt = 0; int64_t alt_bn128_G2::dbl_cnt = 0;
#endif #endif
std::vector<size_t> alt_bn128_G2::wnaf_window_table; std::vector<uint64_t> alt_bn128_G2::wnaf_window_table;
std::vector<size_t> alt_bn128_G2::fixed_base_exp_window_table; std::vector<uint64_t> alt_bn128_G2::fixed_base_exp_window_table;
alt_bn128_G2 alt_bn128_G2::G2_zero; alt_bn128_G2 alt_bn128_G2::G2_zero;
alt_bn128_G2 alt_bn128_G2::G2_one; alt_bn128_G2 alt_bn128_G2::G2_one;
@@ -266,7 +267,7 @@ alt_bn128_G2 alt_bn128_G2::add(const alt_bn128_G2 &other) const
alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const
{ {
#ifdef DEBUG #ifdef DEBUG
assert(other.is_special()); assert_except(other.is_special());
#endif #endif
// handle special cases having to do with O // handle special cases having to do with O

View File

@@ -20,11 +20,11 @@ std::istream& operator>>(std::istream &, alt_bn128_G2&);
class alt_bn128_G2 { class alt_bn128_G2 {
public: public:
#ifdef PROFILE_OP_COUNTS #ifdef PROFILE_OP_COUNTS
static long long add_cnt; static int64_t add_cnt;
static long long dbl_cnt; static int64_t dbl_cnt;
#endif #endif
static std::vector<size_t> wnaf_window_table; static std::vector<uint64_t> wnaf_window_table;
static std::vector<size_t> fixed_base_exp_window_table; static std::vector<uint64_t> fixed_base_exp_window_table;
static alt_bn128_G2 G2_zero; static alt_bn128_G2 G2_zero;
static alt_bn128_G2 G2_one; static alt_bn128_G2 G2_one;

View File

@@ -324,7 +324,7 @@ alt_bn128_ate_G2_precomp alt_bn128_ate_precompute_G2(const alt_bn128_G2& Q)
bool found_one = false; bool found_one = false;
alt_bn128_ate_ell_coeffs c; alt_bn128_ate_ell_coeffs c;
for (long i = loop_count.max_bits(); i >= 0; --i) for (int64_t i = loop_count.max_bits(); i >= 0; --i)
{ {
const bool bit = loop_count.test_bit(i); const bool bit = loop_count.test_bit(i);
if (!found_one) if (!found_one)
@@ -378,7 +378,7 @@ alt_bn128_Fq12 alt_bn128_ate_miller_loop(const alt_bn128_ate_G1_precomp &prec_P,
const bigint<alt_bn128_Fr::num_limbs> &loop_count = alt_bn128_ate_loop_count; const bigint<alt_bn128_Fr::num_limbs> &loop_count = alt_bn128_ate_loop_count;
alt_bn128_ate_ell_coeffs c; alt_bn128_ate_ell_coeffs c;
for (long i = loop_count.max_bits(); i >= 0; --i) for (int64_t i = loop_count.max_bits(); i >= 0; --i)
{ {
const bool bit = loop_count.test_bit(i); const bool bit = loop_count.test_bit(i);
if (!found_one) if (!found_one)
@@ -432,7 +432,7 @@ alt_bn128_Fq12 alt_bn128_ate_double_miller_loop(const alt_bn128_ate_G1_precomp &
size_t idx = 0; size_t idx = 0;
const bigint<alt_bn128_Fr::num_limbs> &loop_count = alt_bn128_ate_loop_count; const bigint<alt_bn128_Fr::num_limbs> &loop_count = alt_bn128_ate_loop_count;
for (long i = loop_count.max_bits(); i >= 0; --i) for (int64_t i = loop_count.max_bits(); i >= 0; --i)
{ {
const bool bit = loop_count.test_bit(i); const bool bit = loop_count.test_bit(i);
if (!found_one) if (!found_one)

View File

@@ -16,7 +16,7 @@ GroupT scalar_mul(const GroupT &base, const bigint<m> &scalar)
GroupT result = GroupT::zero(); GroupT result = GroupT::zero();
bool found_one = false; bool found_one = false;
for (long i = scalar.max_bits() - 1; i >= 0; --i) for (int64_t i = scalar.max_bits() - 1; i >= 0; --i)
{ {
if (found_one) if (found_one)
{ {

View File

@@ -4,13 +4,17 @@
* and contributors (see AUTHORS). * and contributors (see AUTHORS).
* @copyright MIT license (see LICENSE file) * @copyright MIT license (see LICENSE file)
*****************************************************************************/ *****************************************************************************/
#include <iostream>
#include "common/profiling.hpp" #include "common/profiling.hpp"
//#include "algebra/curves/edwards/edwards_pp.hpp"
#ifdef CURVE_BN128 #ifdef CURVE_BN128
#include "algebra/curves/bn128/bn128_pp.hpp" #include "algebra/curves/bn128/bn128_pp.hpp"
#endif #endif
#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" #include "algebra/curves/alt_bn128/alt_bn128_pp.hpp"
//#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp"
#include <gtest/gtest.h> //#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp"
#include "algebra/curves/alt_bn128/alt_bn128_pairing.hpp"
#include "algebra/curves/alt_bn128/alt_bn128_pairing.cpp"
using namespace libsnark; using namespace libsnark;
@@ -45,11 +49,11 @@ void pairing_test()
ans1.print(); ans1.print();
ans2.print(); ans2.print();
ans3.print(); ans3.print();
EXPECT_EQ(ans1, ans2); assert(ans1 == ans2);
EXPECT_EQ(ans2, ans3); assert(ans2 == ans3);
EXPECT_NE(ans1, GT_one); assert(ans1 != GT_one);
EXPECT_EQ((ans1^Fr<ppT>::field_char()), GT_one); assert((ans1^Fr<ppT>::field_char()) == GT_one);
printf("\n\n"); printf("\n\n");
} }
@@ -69,7 +73,7 @@ void double_miller_loop_test()
const Fqk<ppT> ans_1 = ppT::miller_loop(prec_P1, prec_Q1); const Fqk<ppT> ans_1 = ppT::miller_loop(prec_P1, prec_Q1);
const Fqk<ppT> ans_2 = ppT::miller_loop(prec_P2, prec_Q2); const Fqk<ppT> ans_2 = ppT::miller_loop(prec_P2, prec_Q2);
const Fqk<ppT> ans_12 = ppT::double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); const Fqk<ppT> ans_12 = ppT::double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2);
EXPECT_EQ(ans_1 * ans_2, ans_12); assert(ans_1 * ans_2 == ans_12);
} }
template<typename ppT> template<typename ppT>
@@ -98,17 +102,31 @@ void affine_pairing_test()
ans1.print(); ans1.print();
ans2.print(); ans2.print();
ans3.print(); ans3.print();
EXPECT_EQ(ans1, ans2); assert(ans1 == ans2);
EXPECT_EQ(ans2, ans3); assert(ans2 == ans3);
EXPECT_NE(ans1, GT_one); assert(ans1 != GT_one);
EXPECT_EQ((ans1^Fr<ppT>::field_char()), GT_one); assert((ans1^Fr<ppT>::field_char()) == GT_one);
printf("\n\n"); printf("\n\n");
} }
TEST(algebra, bilinearity) int main(void)
{ {
start_profiling(); start_profiling();
edwards_pp::init_public_params();
pairing_test<edwards_pp>();
double_miller_loop_test<edwards_pp>();
mnt6_pp::init_public_params();
pairing_test<mnt6_pp>();
double_miller_loop_test<mnt6_pp>();
affine_pairing_test<mnt6_pp>();
mnt4_pp::init_public_params();
pairing_test<mnt4_pp>();
double_miller_loop_test<mnt4_pp>();
affine_pairing_test<mnt4_pp>();
alt_bn128_pp::init_public_params(); alt_bn128_pp::init_public_params();
pairing_test<alt_bn128_pp>(); pairing_test<alt_bn128_pp>();
double_miller_loop_test<alt_bn128_pp>(); double_miller_loop_test<alt_bn128_pp>();

View File

@@ -5,14 +5,15 @@
* @copyright MIT license (see LICENSE file) * @copyright MIT license (see LICENSE file)
*****************************************************************************/ *****************************************************************************/
#include "common/profiling.hpp" #include "common/profiling.hpp"
//#include "algebra/curves/edwards/edwards_pp.hpp"
//#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp"
//#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp"
#ifdef CURVE_BN128 #ifdef CURVE_BN128
#include "algebra/curves/bn128/bn128_pp.hpp" #include "algebra/curves/bn128/bn128_pp.hpp"
#endif #endif
#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" #include "algebra/curves/alt_bn128/alt_bn128_pp.hpp"
#include <sstream> #include <sstream>
#include <gtest/gtest.h>
using namespace libsnark; using namespace libsnark;
template<typename GroupT> template<typename GroupT>
@@ -24,31 +25,31 @@ void test_mixed_add()
el = GroupT::zero(); el = GroupT::zero();
el.to_special(); el.to_special();
result = base.mixed_add(el); result = base.mixed_add(el);
EXPECT_EQ(result, base + el); assert(result == base + el);
base = GroupT::zero(); base = GroupT::zero();
el = GroupT::random_element(); el = GroupT::random_element();
el.to_special(); el.to_special();
result = base.mixed_add(el); result = base.mixed_add(el);
EXPECT_EQ(result, base + el); assert(result == base + el);
base = GroupT::random_element(); base = GroupT::random_element();
el = GroupT::zero(); el = GroupT::zero();
el.to_special(); el.to_special();
result = base.mixed_add(el); result = base.mixed_add(el);
EXPECT_EQ(result, base + el); assert(result == base + el);
base = GroupT::random_element(); base = GroupT::random_element();
el = GroupT::random_element(); el = GroupT::random_element();
el.to_special(); el.to_special();
result = base.mixed_add(el); result = base.mixed_add(el);
EXPECT_EQ(result, base + el); assert(result == base + el);
base = GroupT::random_element(); base = GroupT::random_element();
el = base; el = base;
el.to_special(); el.to_special();
result = base.mixed_add(el); result = base.mixed_add(el);
EXPECT_EQ(result, base.dbl()); assert(result == base.dbl());
} }
template<typename GroupT> template<typename GroupT>
@@ -59,53 +60,53 @@ void test_group()
bigint<1> randsum = bigint<1>("121160274"); bigint<1> randsum = bigint<1>("121160274");
GroupT zero = GroupT::zero(); GroupT zero = GroupT::zero();
EXPECT_EQ(zero, zero); assert(zero == zero);
GroupT one = GroupT::one(); GroupT one = GroupT::one();
EXPECT_EQ(one, one); assert(one == one);
GroupT two = bigint<1>(2l) * GroupT::one(); GroupT two = bigint<1>(2l) * GroupT::one();
EXPECT_EQ(two, two); assert(two == two);
GroupT five = bigint<1>(5l) * GroupT::one(); GroupT five = bigint<1>(5l) * GroupT::one();
GroupT three = bigint<1>(3l) * GroupT::one(); GroupT three = bigint<1>(3l) * GroupT::one();
GroupT four = bigint<1>(4l) * GroupT::one(); GroupT four = bigint<1>(4l) * GroupT::one();
EXPECT_EQ(two+five, three+four); assert(two+five == three+four);
GroupT a = GroupT::random_element(); GroupT a = GroupT::random_element();
GroupT b = GroupT::random_element(); GroupT b = GroupT::random_element();
EXPECT_NE(one, zero); assert(one != zero);
EXPECT_NE(a, zero); assert(a != zero);
EXPECT_NE(a, one); assert(a != one);
EXPECT_NE(b, zero); assert(b != zero);
EXPECT_NE(b, one); assert(b != one);
EXPECT_EQ(a.dbl(), a + a); assert(a.dbl() == a + a);
EXPECT_EQ(b.dbl(), b + b); assert(b.dbl() == b + b);
EXPECT_EQ(one.add(two), three); assert(one.add(two) == three);
EXPECT_EQ(two.add(one), three); assert(two.add(one) == three);
EXPECT_EQ(a + b, b + a); assert(a + b == b + a);
EXPECT_EQ(a - a, zero); assert(a - a == zero);
EXPECT_EQ(a - b, a + (-b)); assert(a - b == a + (-b));
EXPECT_EQ(a - b, (-b) + a); assert(a - b == (-b) + a);
// handle special cases // handle special cases
EXPECT_EQ(zero + (-a), -a); assert(zero + (-a) == -a);
EXPECT_EQ(zero - a, -a); assert(zero - a == -a);
EXPECT_EQ(a - zero, a); assert(a - zero == a);
EXPECT_EQ(a + zero, a); assert(a + zero == a);
EXPECT_EQ(zero + a, a); assert(zero + a == a);
EXPECT_EQ((a + b).dbl(), (a + b) + (b + a)); assert((a + b).dbl() == (a + b) + (b + a));
EXPECT_EQ(bigint<1>("2") * (a + b), (a + b) + (b + a)); assert(bigint<1>("2") * (a + b) == (a + b) + (b + a));
EXPECT_EQ((rand1 * a) + (rand2 * a), (randsum * a)); assert((rand1 * a) + (rand2 * a) == (randsum * a));
EXPECT_EQ(GroupT::order() * a, zero); assert(GroupT::order() * a == zero);
EXPECT_EQ(GroupT::order() * one, zero); assert(GroupT::order() * one == zero);
EXPECT_NE((GroupT::order() * a) - a, zero); assert((GroupT::order() * a) - a != zero);
EXPECT_NE((GroupT::order() * one) - one, zero); assert((GroupT::order() * one) - one != zero);
test_mixed_add<GroupT>(); test_mixed_add<GroupT>();
} }
@@ -114,7 +115,7 @@ template<typename GroupT>
void test_mul_by_q() void test_mul_by_q()
{ {
GroupT a = GroupT::random_element(); GroupT a = GroupT::random_element();
EXPECT_EQ((GroupT::base_field_char()*a), a.mul_by_q()); assert((GroupT::base_field_char()*a) == a.mul_by_q());
} }
template<typename GroupT> template<typename GroupT>
@@ -128,14 +129,36 @@ void test_output()
ss << g; ss << g;
GroupT gg; GroupT gg;
ss >> gg; ss >> gg;
EXPECT_EQ(g, gg); assert(g == gg);
/* use a random point in next iteration */ /* use a random point in next iteration */
g = GroupT::random_element(); g = GroupT::random_element();
} }
} }
TEST(algebra, groups) int main(void)
{ {
/*
edwards_pp::init_public_params();
test_group<G1<edwards_pp> >();
test_output<G1<edwards_pp> >();
test_group<G2<edwards_pp> >();
test_output<G2<edwards_pp> >();
test_mul_by_q<G2<edwards_pp> >();
mnt4_pp::init_public_params();
test_group<G1<mnt4_pp> >();
test_output<G1<mnt4_pp> >();
test_group<G2<mnt4_pp> >();
test_output<G2<mnt4_pp> >();
test_mul_by_q<G2<mnt4_pp> >();
mnt6_pp::init_public_params();
test_group<G1<mnt6_pp> >();
test_output<G1<mnt6_pp> >();
test_group<G2<mnt6_pp> >();
test_output<G2<mnt6_pp> >();
test_mul_by_q<G2<mnt6_pp> >();
*/
alt_bn128_pp::init_public_params(); alt_bn128_pp::init_public_params();
test_group<G1<alt_bn128_pp> >(); test_group<G1<alt_bn128_pp> >();
test_output<G1<alt_bn128_pp> >(); test_output<G1<alt_bn128_pp> >();

View File

@@ -15,15 +15,16 @@
#define BASIC_RADIX2_DOMAIN_TCC_ #define BASIC_RADIX2_DOMAIN_TCC_
#include "algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp" #include "algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp"
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
template<typename FieldT> template<typename FieldT>
basic_radix2_domain<FieldT>::basic_radix2_domain(const size_t m) : evaluation_domain<FieldT>(m) basic_radix2_domain<FieldT>::basic_radix2_domain(const size_t m) : evaluation_domain<FieldT>(m)
{ {
assert(m > 1); assert_except(m > 1);
const size_t logm = log2(m); const size_t logm = log2(m);
assert(logm <= (FieldT::s)); assert_except(logm <= (FieldT::s));
omega = get_root_of_unity<FieldT>(m); omega = get_root_of_unity<FieldT>(m);
} }
@@ -32,7 +33,7 @@ template<typename FieldT>
void basic_radix2_domain<FieldT>::FFT(std::vector<FieldT> &a) void basic_radix2_domain<FieldT>::FFT(std::vector<FieldT> &a)
{ {
enter_block("Execute FFT"); enter_block("Execute FFT");
assert(a.size() == this->m); assert_except(a.size() == this->m);
_basic_radix2_FFT(a, omega); _basic_radix2_FFT(a, omega);
leave_block("Execute FFT"); leave_block("Execute FFT");
} }
@@ -41,7 +42,7 @@ template<typename FieldT>
void basic_radix2_domain<FieldT>::iFFT(std::vector<FieldT> &a) void basic_radix2_domain<FieldT>::iFFT(std::vector<FieldT> &a)
{ {
enter_block("Execute inverse FFT"); enter_block("Execute inverse FFT");
assert(a.size() == this->m); assert_except(a.size() == this->m);
_basic_radix2_FFT(a, omega.inverse()); _basic_radix2_FFT(a, omega.inverse());
const FieldT sconst = FieldT(a.size()).inverse(); const FieldT sconst = FieldT(a.size()).inverse();
@@ -91,7 +92,7 @@ FieldT basic_radix2_domain<FieldT>::compute_Z(const FieldT &t)
template<typename FieldT> template<typename FieldT>
void basic_radix2_domain<FieldT>::add_poly_Z(const FieldT &coeff, std::vector<FieldT> &H) void basic_radix2_domain<FieldT>::add_poly_Z(const FieldT &coeff, std::vector<FieldT> &H)
{ {
assert(H.size() == this->m+1); assert_except(H.size() == this->m+1);
H[this->m] += coeff; H[this->m] += coeff;
H[0] -= coeff; H[0] -= coeff;
} }

View File

@@ -21,6 +21,7 @@
#include "algebra/fields/field_utils.hpp" #include "algebra/fields/field_utils.hpp"
#include "common/profiling.hpp" #include "common/profiling.hpp"
#include "common/utils.hpp" #include "common/utils.hpp"
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
@@ -38,7 +39,7 @@ template<typename FieldT>
void _basic_serial_radix2_FFT(std::vector<FieldT> &a, const FieldT &omega) void _basic_serial_radix2_FFT(std::vector<FieldT> &a, const FieldT &omega)
{ {
const size_t n = a.size(), logn = log2(n); const size_t n = a.size(), logn = log2(n);
assert(n == (1u << logn)); assert_except(n == (1u << logn));
/* swapping in place (from Storer's book) */ /* swapping in place (from Storer's book) */
for (size_t k = 0; k < n; ++k) for (size_t k = 0; k < n; ++k)
@@ -74,11 +75,11 @@ void _basic_serial_radix2_FFT(std::vector<FieldT> &a, const FieldT &omega)
template<typename FieldT> template<typename FieldT>
void _basic_parallel_radix2_FFT_inner(std::vector<FieldT> &a, const FieldT &omega, const size_t log_cpus) void _basic_parallel_radix2_FFT_inner(std::vector<FieldT> &a, const FieldT &omega, const size_t log_cpus)
{ {
const size_t num_cpus = 1ul<<log_cpus; const size_t num_cpus = UINT64_C(1)<<log_cpus;
const size_t m = a.size(); const size_t m = a.size();
const size_t log_m = log2(m); const size_t log_m = log2(m);
assert(m == 1ul<<log_m); assert_except(m == UINT64_C(1)<<log_m);
if (log_m < log_cpus) if (log_m < log_cpus)
{ {
@@ -90,7 +91,7 @@ void _basic_parallel_radix2_FFT_inner(std::vector<FieldT> &a, const FieldT &omeg
std::vector<std::vector<FieldT> > tmp(num_cpus); std::vector<std::vector<FieldT> > tmp(num_cpus);
for (size_t j = 0; j < num_cpus; ++j) for (size_t j = 0; j < num_cpus; ++j)
{ {
tmp[j].resize(1ul<<(log_m-log_cpus), FieldT::zero()); tmp[j].resize(UINT64_C(1)<<(log_m-log_cpus), FieldT::zero());
} }
#ifdef MULTICORE #ifdef MULTICORE
@@ -102,7 +103,7 @@ void _basic_parallel_radix2_FFT_inner(std::vector<FieldT> &a, const FieldT &omeg
const FieldT omega_step = omega^(j<<(log_m - log_cpus)); const FieldT omega_step = omega^(j<<(log_m - log_cpus));
FieldT elt = FieldT::one(); FieldT elt = FieldT::one();
for (size_t i = 0; i < 1ul<<(log_m - log_cpus); ++i) for (size_t i = 0; i < UINT64_C(1)<<(log_m - log_cpus); ++i)
{ {
for (size_t s = 0; s < num_cpus; ++s) for (size_t s = 0; s < num_cpus; ++s)
{ {
@@ -135,7 +136,7 @@ void _basic_parallel_radix2_FFT_inner(std::vector<FieldT> &a, const FieldT &omeg
#endif #endif
for (size_t i = 0; i < num_cpus; ++i) for (size_t i = 0; i < num_cpus; ++i)
{ {
for (size_t j = 0; j < 1ul<<(log_m - log_cpus); ++j) for (size_t j = 0; j < UINT64_C(1)<<(log_m - log_cpus); ++j)
{ {
// now: i = idx >> (log_m - log_cpus) and j = idx % (1u << (log_m - log_cpus)), for idx = ((i<<(log_m-log_cpus))+j) % (1u << log_m) // now: i = idx >> (log_m - log_cpus) and j = idx % (1u << (log_m - log_cpus)), for idx = ((i<<(log_m-log_cpus))+j) % (1u << log_m)
a[(j<<log_cpus) + i] = tmp[i][j]; a[(j<<log_cpus) + i] = tmp[i][j];
@@ -189,7 +190,7 @@ std::vector<FieldT> _basic_radix2_lagrange_coeffs(const size_t m, const FieldT &
return std::vector<FieldT>(1, FieldT::one()); return std::vector<FieldT>(1, FieldT::one());
} }
assert(m == (1u << log2(m))); assert_except(m == (1u << log2(m)));
const FieldT omega = get_root_of_unity<FieldT>(m); const FieldT omega = get_root_of_unity<FieldT>(m);

View File

@@ -7,7 +7,7 @@
a choice of domain S with size ~m that has been selected so to optimize a choice of domain S with size ~m that has been selected so to optimize
- computations of Lagrange polynomials, and - computations of Lagrange polynomials, and
- FFT/iFFT computations. - FFT/iFFT computations.
An evaluation domain also provides other functions, e.g., accessing An evaluation domain also provides other other functions, e.g., accessing
individual elements in S or evaluating its vanishing polynomial. individual elements in S or evaluating its vanishing polynomial.
The descriptions below make use of the definition of a *Lagrange polynomial*, The descriptions below make use of the definition of a *Lagrange polynomial*,
@@ -111,7 +111,7 @@ std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t m
* The inputs are: * The inputs are:
* - an integer m * - an integer m
* - a domain S = (a_{0},...,a_{m-1}) of size m * - a domain S = (a_{0},...,a_{m-1}) of size m
* - a field element t * - a field element element t
* - an index idx in {0,...,m-1} * - an index idx in {0,...,m-1}
* The output is the polynomial L_{idx,S}(z) evaluated at z = t. * The output is the polynomial L_{idx,S}(z) evaluated at z = t.
*/ */

View File

@@ -22,15 +22,16 @@
#include <cassert> #include <cassert>
#include "algebra/fields/field_utils.hpp" #include "algebra/fields/field_utils.hpp"
#include "algebra/evaluation_domain/domains/basic_radix2_domain.hpp" #include "algebra/evaluation_domain/domains/basic_radix2_domain.hpp"
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
template<typename FieldT> template<typename FieldT>
std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t min_size) std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t min_size)
{ {
assert(min_size > 1); assert_except(min_size > 1);
const size_t log_min_size = log2(min_size); const size_t log_min_size = log2(min_size);
assert(log_min_size <= (FieldT::s+1)); assert_except(log_min_size <= (FieldT::s+1));
std::shared_ptr<evaluation_domain<FieldT> > result; std::shared_ptr<evaluation_domain<FieldT> > result;
if (min_size == (1u << log_min_size)) if (min_size == (1u << log_min_size))
@@ -41,7 +42,7 @@ std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t m
{ {
print_indent(); printf("* Selected domain: extended_radix2\n"); print_indent(); printf("* Selected domain: extended_radix2\n");
} }
assert(0); assert_except(0);
} }
else else
{ {
@@ -54,9 +55,9 @@ std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t m
} }
else else
{ {
const size_t big = 1ul<<(log2(min_size)-1); const size_t big = UINT64_C(1)<<(log2(min_size)-1);
const size_t small = min_size - big; const size_t small = min_size - big;
const size_t rounded_small = (1ul<<log2(small)); const size_t rounded_small = (UINT64_C(1)<<log2(small));
if (big == rounded_small) if (big == rounded_small)
{ {
if (log2(big + rounded_small) < FieldT::s+1) if (log2(big + rounded_small) < FieldT::s+1)
@@ -73,7 +74,7 @@ std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t m
{ {
print_indent(); printf("* Selected domain: extended_radix2\n"); print_indent(); printf("* Selected domain: extended_radix2\n");
} }
assert(0); assert_except(0);
} }
} }
else else
@@ -82,7 +83,7 @@ std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t m
{ {
print_indent(); printf("* Selected domain: step_radix2\n"); print_indent(); printf("* Selected domain: step_radix2\n");
} }
assert(0); assert_except(0);
} }
} }
@@ -92,8 +93,8 @@ std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t m
template<typename FieldT> template<typename FieldT>
FieldT lagrange_eval(const size_t m, const std::vector<FieldT> &domain, const FieldT &t, const size_t idx) FieldT lagrange_eval(const size_t m, const std::vector<FieldT> &domain, const FieldT &t, const size_t idx)
{ {
assert(m == domain.size()); assert_except(m == domain.size());
assert(idx < m); assert_except(idx < m);
FieldT num = FieldT::one(); FieldT num = FieldT::one();
FieldT denom = FieldT::one(); FieldT denom = FieldT::one();

View File

@@ -22,7 +22,7 @@ template<typename FieldT, mp_size_t m>
FieldT power(const FieldT &base, const bigint<m> &exponent); FieldT power(const FieldT &base, const bigint<m> &exponent);
template<typename FieldT> template<typename FieldT>
FieldT power(const FieldT &base, const unsigned long exponent); FieldT power(const FieldT &base, const uint64_t exponent);
} // libsnark } // libsnark

View File

@@ -25,7 +25,7 @@ FieldT power(const FieldT &base, const bigint<m> &exponent)
bool found_one = false; bool found_one = false;
for (long i = exponent.max_bits() - 1; i >= 0; --i) for (int64_t i = exponent.max_bits() - 1; i >= 0; --i)
{ {
if (found_one) if (found_one)
{ {
@@ -43,7 +43,7 @@ FieldT power(const FieldT &base, const bigint<m> &exponent)
} }
template<typename FieldT> template<typename FieldT>
FieldT power(const FieldT &base, const unsigned long exponent) FieldT power(const FieldT &base, const uint64_t exponent)
{ {
return power<FieldT>(base, bigint<1>(exponent)); return power<FieldT>(base, bigint<1>(exponent));
} }

View File

@@ -33,7 +33,7 @@ public:
mp_limb_t data[n] = {0}; mp_limb_t data[n] = {0};
bigint() = default; bigint() = default;
bigint(const unsigned long x); /// Initialize from a small integer bigint(const uint64_t x); /// Initalize from a small integer
bigint(const char* s); /// Initialize from a string containing an integer in decimal notation bigint(const char* s); /// Initialize from a string containing an integer in decimal notation
bigint(const mpz_t r); /// Initialize from MPZ element bigint(const mpz_t r); /// Initialize from MPZ element
@@ -46,7 +46,7 @@ public:
size_t max_bits() const { return n * GMP_NUMB_BITS; } size_t max_bits() const { return n * GMP_NUMB_BITS; }
size_t num_bits() const; size_t num_bits() const;
unsigned long as_ulong() const; /* return the last limb of the integer */ uint64_t as_ulong() const; /* return the last limb of the integer */
void to_mpz(mpz_t r) const; void to_mpz(mpz_t r) const;
bool test_bit(const std::size_t bitno) const; bool test_bit(const std::size_t bitno) const;

View File

@@ -13,13 +13,14 @@
#include <climits> #include <climits>
#include <cstring> #include <cstring>
#include "sodium.h" #include "sodium.h"
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
template<mp_size_t n> template<mp_size_t n>
bigint<n>::bigint(const unsigned long x) /// Initialize from a small integer bigint<n>::bigint(const uint64_t x) /// Initalize from a small integer
{ {
static_assert(ULONG_MAX <= GMP_NUMB_MAX, "unsigned long does not fit in a GMP limb"); static_assert(UINT64_MAX <= GMP_NUMB_MAX, "uint64_t does not fit in a GMP limb");
this->data[0] = x; this->data[0] = x;
} }
@@ -31,12 +32,12 @@ bigint<n>::bigint(const char* s) /// Initialize from a string containing an inte
for (size_t i = 0; i < l; ++i) for (size_t i = 0; i < l; ++i)
{ {
assert(s[i] >= '0' && s[i] <= '9'); assert_except(s[i] >= '0' && s[i] <= '9');
s_copy[i] = s[i] - '0'; s_copy[i] = s[i] - '0';
} }
mp_size_t limbs_written = mpn_set_str(this->data, s_copy, l, 10); mp_size_t limbs_written = mpn_set_str(this->data, s_copy, l, 10);
assert(limbs_written <= n); assert_except(limbs_written <= n);
delete[] s_copy; delete[] s_copy;
} }
@@ -53,7 +54,7 @@ bigint<n>::bigint(const mpz_t r) /// Initialize from MPZ element
mpz_fdiv_q_2exp(k, k, GMP_NUMB_BITS); mpz_fdiv_q_2exp(k, k, GMP_NUMB_BITS);
} }
assert(mpz_sgn(k) == 0); assert_except(mpz_sgn(k) == 0);
mpz_clear(k); mpz_clear(k);
} }
@@ -105,7 +106,7 @@ template<mp_size_t n>
size_t bigint<n>::num_bits() const size_t bigint<n>::num_bits() const
{ {
/* /*
for (long i = max_bits(); i >= 0; --i) for (int64_t i = max_bits(); i >= 0; --i)
{ {
if (this->test_bit(i)) if (this->test_bit(i))
{ {
@@ -115,7 +116,7 @@ size_t bigint<n>::num_bits() const
return 0; return 0;
*/ */
for (long i = n-1; i >= 0; --i) for (int64_t i = n-1; i >= 0; --i)
{ {
mp_limb_t x = this->data[i]; mp_limb_t x = this->data[i];
if (x == 0) if (x == 0)
@@ -124,14 +125,14 @@ size_t bigint<n>::num_bits() const
} }
else else
{ {
return ((i+1) * GMP_NUMB_BITS) - __builtin_clzl(x); return ((i+1) * GMP_NUMB_BITS) - __builtin_clzll(x);
} }
} }
return 0; return 0;
} }
template<mp_size_t n> template<mp_size_t n>
unsigned long bigint<n>::as_ulong() const uint64_t bigint<n>::as_ulong() const
{ {
return this->data[0]; return this->data[0];
} }
@@ -186,7 +187,7 @@ inline void bigint<n>::div_qr(bigint<n-d+1>& quotient, bigint<d>& remainder,
const bigint<n>& dividend, const bigint<d>& divisor) const bigint<n>& dividend, const bigint<d>& divisor)
{ {
static_assert(n >= d, "dividend must not be smaller than divisor for bigint::div_qr"); static_assert(n >= d, "dividend must not be smaller than divisor for bigint::div_qr");
assert(divisor.data[d-1] != 0); assert_except(divisor.data[d-1] != 0);
mpn_tdiv_qr(quotient.data, remainder.data, 0, dividend.data, n, divisor.data, d); mpn_tdiv_qr(quotient.data, remainder.data, 0, dividend.data, n, divisor.data, d);
} }
@@ -223,7 +224,7 @@ inline bool bigint<n>::operator>(const bigint<n>& other) const
template<mp_size_t n> template<mp_size_t n>
bigint<n>& bigint<n>::randomize() bigint<n>& bigint<n>::randomize()
{ {
assert(GMP_NUMB_BITS == sizeof(mp_limb_t) * 8); assert_except(GMP_NUMB_BITS == sizeof(mp_limb_t) * 8);
randombytes_buf(this->data, sizeof(mp_limb_t) * n); randombytes_buf(this->data, sizeof(mp_limb_t) * n);
@@ -262,12 +263,12 @@ std::istream& operator>>(std::istream &in, bigint<n> &b)
for (size_t i = 0; i < l; ++i) for (size_t i = 0; i < l; ++i)
{ {
assert(s[i] >= '0' && s[i] <= '9'); assert_except(s[i] >= '0' && s[i] <= '9');
s_copy[i] = s[i] - '0'; s_copy[i] = s[i] - '0';
} }
mp_size_t limbs_written = mpn_set_str(b.data, s_copy, l, 10); mp_size_t limbs_written = mpn_set_str(b.data, s_copy, l, 10);
assert(limbs_written <= n); assert_except(limbs_written <= n);
delete[] s_copy; delete[] s_copy;
#endif #endif

View File

@@ -16,13 +16,13 @@ namespace libsnark {
// returns root of unity of order n (for n a power of 2), if one exists // returns root of unity of order n (for n a power of 2), if one exists
template<typename FieldT> template<typename FieldT>
FieldT get_root_of_unity(const size_t n); FieldT get_root_of_unity(const uint64_t n);
template<typename FieldT> template<typename FieldT>
std::vector<FieldT> pack_int_vector_into_field_element_vector(const std::vector<size_t> &v, const size_t w); std::vector<FieldT> pack_int_vector_into_field_element_vector(const std::vector<uint64_t> &v, const uint64_t w);
template<typename FieldT> template<typename FieldT>
std::vector<FieldT> pack_bit_vector_into_field_element_vector(const bit_vector &v, const size_t chunk_bits); std::vector<FieldT> pack_bit_vector_into_field_element_vector(const bit_vector &v, const uint64_t chunk_bits);
template<typename FieldT> template<typename FieldT>
std::vector<FieldT> pack_bit_vector_into_field_element_vector(const bit_vector &v); std::vector<FieldT> pack_bit_vector_into_field_element_vector(const bit_vector &v);
@@ -37,7 +37,7 @@ template<typename FieldT>
bit_vector convert_field_element_to_bit_vector(const FieldT &el); bit_vector convert_field_element_to_bit_vector(const FieldT &el);
template<typename FieldT> template<typename FieldT>
bit_vector convert_field_element_to_bit_vector(const FieldT &el, const size_t bitcount); bit_vector convert_field_element_to_bit_vector(const FieldT &el, const uint64_t bitcount);
template<typename FieldT> template<typename FieldT>
FieldT convert_bit_vector_to_field_element(const bit_vector &v); FieldT convert_bit_vector_to_field_element(const bit_vector &v);

View File

@@ -11,6 +11,7 @@
#define FIELD_UTILS_TCC_ #define FIELD_UTILS_TCC_
#include "common/utils.hpp" #include "common/utils.hpp"
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
@@ -21,14 +22,14 @@ FieldT coset_shift()
} }
template<typename FieldT> template<typename FieldT>
FieldT get_root_of_unity(const size_t n) FieldT get_root_of_unity(const uint64_t n)
{ {
const size_t logn = log2(n); const uint64_t logn = log2(n);
assert(n == (1u << logn)); assert_except(n == (1u << logn));
assert(logn <= FieldT::s); assert_except(logn <= FieldT::s);
FieldT omega = FieldT::root_of_unity; FieldT omega = FieldT::root_of_unity;
for (size_t i = FieldT::s; i > logn; --i) for (uint64_t i = FieldT::s; i > logn; --i)
{ {
omega *= omega; omega *= omega;
} }
@@ -37,21 +38,21 @@ FieldT get_root_of_unity(const size_t n)
} }
template<typename FieldT> template<typename FieldT>
std::vector<FieldT> pack_int_vector_into_field_element_vector(const std::vector<size_t> &v, const size_t w) std::vector<FieldT> pack_int_vector_into_field_element_vector(const std::vector<uint64_t> &v, const uint64_t w)
{ {
const size_t chunk_bits = FieldT::capacity(); const uint64_t chunk_bits = FieldT::capacity();
const size_t repacked_size = div_ceil(v.size() * w, chunk_bits); const uint64_t repacked_size = div_ceil(v.size() * w, chunk_bits);
std::vector<FieldT> result(repacked_size); std::vector<FieldT> result(repacked_size);
for (size_t i = 0; i < repacked_size; ++i) for (uint64_t i = 0; i < repacked_size; ++i)
{ {
bigint<FieldT::num_limbs> b; bigint<FieldT::num_limbs> b;
for (size_t j = 0; j < chunk_bits; ++j) for (uint64_t j = 0; j < chunk_bits; ++j)
{ {
const size_t word_index = (i * chunk_bits + j) / w; const uint64_t word_index = (i * chunk_bits + j) / w;
const size_t pos_in_word = (i * chunk_bits + j) % w; const uint64_t pos_in_word = (i * chunk_bits + j) % w;
const size_t word_or_0 = (word_index < v.size() ? v[word_index] : 0); const uint64_t word_or_0 = (word_index < v.size() ? v[word_index] : 0);
const size_t bit = (word_or_0 >> pos_in_word) & 1; const uint64_t bit = (word_or_0 >> pos_in_word) & 1;
b.data[j / GMP_NUMB_BITS] |= bit << (j % GMP_NUMB_BITS); b.data[j / GMP_NUMB_BITS] |= bit << (j % GMP_NUMB_BITS);
} }
@@ -62,11 +63,11 @@ std::vector<FieldT> pack_int_vector_into_field_element_vector(const std::vector<
} }
template<typename FieldT> template<typename FieldT>
std::vector<FieldT> pack_bit_vector_into_field_element_vector(const bit_vector &v, const size_t chunk_bits) std::vector<FieldT> pack_bit_vector_into_field_element_vector(const bit_vector &v, const uint64_t chunk_bits)
{ {
assert(chunk_bits <= FieldT::capacity()); assert_except(chunk_bits <= FieldT::capacity());
const size_t repacked_size = div_ceil(v.size(), chunk_bits); const uint64_t repacked_size = div_ceil(v.size(), chunk_bits);
std::vector<FieldT> result(repacked_size); std::vector<FieldT> result(repacked_size);
for (size_t i = 0; i < repacked_size; ++i) for (size_t i = 0; i < repacked_size; ++i)
@@ -131,7 +132,7 @@ bit_vector convert_field_element_to_bit_vector(const FieldT &el)
} }
template<typename FieldT> template<typename FieldT>
bit_vector convert_field_element_to_bit_vector(const FieldT &el, const size_t bitcount) bit_vector convert_field_element_to_bit_vector(const FieldT &el, const uint64_t bitcount)
{ {
bit_vector result = convert_field_element_to_bit_vector(el); bit_vector result = convert_field_element_to_bit_vector(el);
result.resize(bitcount); result.resize(bitcount);
@@ -142,7 +143,7 @@ bit_vector convert_field_element_to_bit_vector(const FieldT &el, const size_t bi
template<typename FieldT> template<typename FieldT>
FieldT convert_bit_vector_to_field_element(const bit_vector &v) FieldT convert_bit_vector_to_field_element(const bit_vector &v)
{ {
assert(v.size() <= FieldT::size_in_bits()); assert_except(v.size() <= FieldT::size_in_bits());
FieldT res = FieldT::zero(); FieldT res = FieldT::zero();
FieldT c = FieldT::one(); FieldT c = FieldT::one();
@@ -164,14 +165,14 @@ void batch_invert(std::vector<FieldT> &vec)
for (auto el : vec) for (auto el : vec)
{ {
assert(!el.is_zero()); assert_except(!el.is_zero());
prod.emplace_back(acc); prod.emplace_back(acc);
acc = acc * el; acc = acc * el;
} }
FieldT acc_inverse = acc.inverse(); FieldT acc_inverse = acc.inverse();
for (long i = vec.size()-1; i >= 0; --i) for (int64_t i = vec.size()-1; i >= 0; --i)
{ {
const FieldT old_el = vec[i]; const FieldT old_el = vec[i];
vec[i] = acc_inverse * prod[i]; vec[i] = acc_inverse * prod[i];

View File

@@ -34,7 +34,7 @@ std::istream& operator>>(std::istream &, Fp_model<n, modulus> &);
* The implementation is mostly a wrapper around GMP's MPN (constant-size integers). * The implementation is mostly a wrapper around GMP's MPN (constant-size integers).
* But for the integer sizes of interest for libsnark (3 to 5 limbs of 64 bits each), * But for the integer sizes of interest for libsnark (3 to 5 limbs of 64 bits each),
* we implement performance-critical routines, like addition and multiplication, * we implement performance-critical routines, like addition and multiplication,
* using hand-optimized assembly code. * using hand-optimzied assembly code.
*/ */
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
class Fp_model { class Fp_model {
@@ -44,15 +44,15 @@ public:
static const mp_size_t num_limbs = n; static const mp_size_t num_limbs = n;
static const constexpr bigint<n>& mod = modulus; static const constexpr bigint<n>& mod = modulus;
#ifdef PROFILE_OP_COUNTS #ifdef PROFILE_OP_COUNTS
static long long add_cnt; static int64_t add_cnt;
static long long sub_cnt; static int64_t sub_cnt;
static long long mul_cnt; static int64_t mul_cnt;
static long long sqr_cnt; static int64_t sqr_cnt;
static long long inv_cnt; static int64_t inv_cnt;
#endif #endif
static size_t num_bits; static uint64_t num_bits;
static bigint<n> euler; // (modulus-1)/2 static bigint<n> euler; // (modulus-1)/2
static size_t s; // modulus = 2^s * t + 1 static uint64_t s; // modulus = 2^s * t + 1
static bigint<n> t; // with t odd static bigint<n> t; // with t odd
static bigint<n> t_minus_1_over_2; // (t-1)/2 static bigint<n> t_minus_1_over_2; // (t-1)/2
static Fp_model<n, modulus> nqr; // a quadratic nonresidue static Fp_model<n, modulus> nqr; // a quadratic nonresidue
@@ -67,9 +67,9 @@ public:
Fp_model() {}; Fp_model() {};
Fp_model(const bigint<n> &b); Fp_model(const bigint<n> &b);
Fp_model(const long x, const bool is_unsigned=false); Fp_model(const int64_t x, const bool is_unsigned=false);
void set_ulong(const unsigned long x); void set_ulong(const uint64_t x);
void mul_reduce(const bigint<n> &other); void mul_reduce(const bigint<n> &other);
@@ -82,7 +82,7 @@ public:
/* Return the last limb of the standard representation of the /* Return the last limb of the standard representation of the
field element. E.g. on 64-bit architectures Fp(123).as_ulong() field element. E.g. on 64-bit architectures Fp(123).as_ulong()
and Fp(2^64+123).as_ulong() would both return 123. */ and Fp(2^64+123).as_ulong() would both return 123. */
unsigned long as_ulong() const; uint64_t as_ulong() const;
bool operator==(const Fp_model& other) const; bool operator==(const Fp_model& other) const;
bool operator!=(const Fp_model& other) const; bool operator!=(const Fp_model& other) const;
@@ -93,7 +93,7 @@ public:
Fp_model& operator+=(const Fp_model& other); Fp_model& operator+=(const Fp_model& other);
Fp_model& operator-=(const Fp_model& other); Fp_model& operator-=(const Fp_model& other);
Fp_model& operator*=(const Fp_model& other); Fp_model& operator*=(const Fp_model& other);
Fp_model& operator^=(const unsigned long pow); Fp_model& operator^=(const uint64_t pow);
template<mp_size_t m> template<mp_size_t m>
Fp_model& operator^=(const bigint<m> &pow); Fp_model& operator^=(const bigint<m> &pow);
@@ -107,12 +107,12 @@ public:
Fp_model inverse() const; Fp_model inverse() const;
Fp_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate) Fp_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate)
Fp_model operator^(const unsigned long pow) const; Fp_model operator^(const uint64_t pow) const;
template<mp_size_t m> template<mp_size_t m>
Fp_model operator^(const bigint<m> &pow) const; Fp_model operator^(const bigint<m> &pow) const;
static size_t size_in_bits() { return num_bits; } static uint64_t size_in_bits() { return num_bits; }
static size_t capacity() { return num_bits - 1; } static uint64_t capacity() { return num_bits - 1; }
static bigint<n> field_char() { return modulus; } static bigint<n> field_char() { return modulus; }
static Fp_model<n, modulus> zero(); static Fp_model<n, modulus> zero();
@@ -125,29 +125,29 @@ public:
#ifdef PROFILE_OP_COUNTS #ifdef PROFILE_OP_COUNTS
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
long long Fp_model<n, modulus>::add_cnt = 0; int64_t Fp_model<n, modulus>::add_cnt = 0;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
long long Fp_model<n, modulus>::sub_cnt = 0; int64_t Fp_model<n, modulus>::sub_cnt = 0;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
long long Fp_model<n, modulus>::mul_cnt = 0; int64_t Fp_model<n, modulus>::mul_cnt = 0;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
long long Fp_model<n, modulus>::sqr_cnt = 0; int64_t Fp_model<n, modulus>::sqr_cnt = 0;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
long long Fp_model<n, modulus>::inv_cnt = 0; int64_t Fp_model<n, modulus>::inv_cnt = 0;
#endif #endif
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
size_t Fp_model<n, modulus>::num_bits; uint64_t Fp_model<n, modulus>::num_bits;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
bigint<n> Fp_model<n, modulus>::euler; bigint<n> Fp_model<n, modulus>::euler;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
size_t Fp_model<n, modulus>::s; uint64_t Fp_model<n, modulus>::s;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
bigint<n> Fp_model<n, modulus>::t; bigint<n> Fp_model<n, modulus>::t;

View File

@@ -173,13 +173,13 @@ void Fp_model<n,modulus>::mul_reduce(const bigint<n> &other)
/* calculate res = res + k * mod * b^i */ /* calculate res = res + k * mod * b^i */
mp_limb_t carryout = mpn_addmul_1(res+i, modulus.data, n, k); mp_limb_t carryout = mpn_addmul_1(res+i, modulus.data, n, k);
carryout = mpn_add_1(res+n+i, res+n+i, n-i, carryout); carryout = mpn_add_1(res+n+i, res+n+i, n-i, carryout);
assert(carryout == 0); assert_except(carryout == 0);
} }
if (mpn_cmp(res+n, modulus.data, n) >= 0) if (mpn_cmp(res+n, modulus.data, n) >= 0)
{ {
const mp_limb_t borrow = mpn_sub(res+n, res+n, n, modulus.data, n); const mp_limb_t borrow = mpn_sub(res+n, res+n, n, modulus.data, n);
assert(borrow == 0); assert_except(borrow == 0);
} }
mpn_copyi(this->mont_repr.data, res+n, n); mpn_copyi(this->mont_repr.data, res+n, n);
@@ -194,7 +194,7 @@ Fp_model<n,modulus>::Fp_model(const bigint<n> &b)
} }
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
Fp_model<n,modulus>::Fp_model(const long x, const bool is_unsigned) Fp_model<n,modulus>::Fp_model(const int64_t x, const bool is_unsigned)
{ {
if (is_unsigned || x >= 0) if (is_unsigned || x >= 0)
{ {
@@ -203,14 +203,14 @@ Fp_model<n,modulus>::Fp_model(const long x, const bool is_unsigned)
else else
{ {
const mp_limb_t borrow = mpn_sub_1(this->mont_repr.data, modulus.data, n, -x); const mp_limb_t borrow = mpn_sub_1(this->mont_repr.data, modulus.data, n, -x);
assert(borrow == 0); assert_except(borrow == 0);
} }
mul_reduce(Rsquared); mul_reduce(Rsquared);
} }
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
void Fp_model<n,modulus>::set_ulong(const unsigned long x) void Fp_model<n,modulus>::set_ulong(const uint64_t x)
{ {
this->mont_repr.clear(); this->mont_repr.clear();
this->mont_repr.data[0] = x; this->mont_repr.data[0] = x;
@@ -237,7 +237,7 @@ bigint<n> Fp_model<n,modulus>::as_bigint() const
} }
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
unsigned long Fp_model<n,modulus>::as_ulong() const uint64_t Fp_model<n,modulus>::as_ulong() const
{ {
return this->as_bigint().as_ulong(); return this->as_bigint().as_ulong();
} }
@@ -391,7 +391,7 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::operator+=(const Fp_model<n,modulus>&
if (carry || mpn_cmp(scratch, modulus.data, n) >= 0) if (carry || mpn_cmp(scratch, modulus.data, n) >= 0)
{ {
const mp_limb_t borrow = mpn_sub(scratch, scratch, n+1, modulus.data, n); const mp_limb_t borrow = mpn_sub(scratch, scratch, n+1, modulus.data, n);
assert(borrow == 0); assert_except(borrow == 0);
} }
mpn_copyi(this->mont_repr.data, scratch, n); mpn_copyi(this->mont_repr.data, scratch, n);
@@ -483,7 +483,7 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::operator-=(const Fp_model<n,modulus>&
} }
const mp_limb_t borrow = mpn_sub(scratch, scratch, n+1, other.mont_repr.data, n); const mp_limb_t borrow = mpn_sub(scratch, scratch, n+1, other.mont_repr.data, n);
assert(borrow == 0); assert_except(borrow == 0);
mpn_copyi(this->mont_repr.data, scratch, n); mpn_copyi(this->mont_repr.data, scratch, n);
} }
@@ -502,7 +502,7 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::operator*=(const Fp_model<n,modulus>&
} }
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
Fp_model<n,modulus>& Fp_model<n,modulus>::operator^=(const unsigned long pow) Fp_model<n,modulus>& Fp_model<n,modulus>::operator^=(const uint64_t pow)
{ {
(*this) = power<Fp_model<n, modulus> >(*this, pow); (*this) = power<Fp_model<n, modulus> >(*this, pow);
return (*this); return (*this);
@@ -538,7 +538,7 @@ Fp_model<n,modulus> Fp_model<n,modulus>::operator*(const Fp_model<n,modulus>& ot
} }
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
Fp_model<n,modulus> Fp_model<n,modulus>::operator^(const unsigned long pow) const Fp_model<n,modulus> Fp_model<n,modulus>::operator^(const uint64_t pow) const
{ {
Fp_model<n, modulus> r(*this); Fp_model<n, modulus> r(*this);
return (r ^= pow); return (r ^= pow);
@@ -626,7 +626,7 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::invert()
this->inv_cnt++; this->inv_cnt++;
#endif #endif
assert(!this->is_zero()); assert_except(!this->is_zero());
bigint<n> g; /* gp should have room for vn = n limbs */ bigint<n> g; /* gp should have room for vn = n limbs */
@@ -637,7 +637,7 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::invert()
/* computes gcd(u, v) = g = u*s + v*t, so s*u will be 1 (mod v) */ /* computes gcd(u, v) = g = u*s + v*t, so s*u will be 1 (mod v) */
const mp_size_t gn = mpn_gcdext(g.data, s, &sn, this->mont_repr.data, n, v.data, n); const mp_size_t gn = mpn_gcdext(g.data, s, &sn, this->mont_repr.data, n, v.data, n);
assert(gn == 1 && g.data[0] == 1); /* inverse exists */ assert_except(gn == 1 && g.data[0] == 1); /* inverse exists */
mp_limb_t q; /* division result fits into q, as sn <= n+1 */ mp_limb_t q; /* division result fits into q, as sn <= n+1 */
/* sn < 0 indicates negative sn; will fix up later */ /* sn < 0 indicates negative sn; will fix up later */
@@ -658,7 +658,7 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::invert()
if (sn < 0) if (sn < 0)
{ {
const mp_limb_t borrow = mpn_sub_n(this->mont_repr.data, modulus.data, this->mont_repr.data, n); const mp_limb_t borrow = mpn_sub_n(this->mont_repr.data, modulus.data, this->mont_repr.data, n);
assert(borrow == 0); assert_except(borrow == 0);
} }
mul_reduce(Rcubed); mul_reduce(Rcubed);
@@ -684,13 +684,13 @@ Fp_model<n, modulus> Fp_model<n,modulus>::random_element() /// returns random el
r.mont_repr.randomize(); r.mont_repr.randomize();
/* clear all bits higher than MSB of modulus */ /* clear all bits higher than MSB of modulus */
size_t bitno = GMP_NUMB_BITS * n - 1; uint64_t bitno = GMP_NUMB_BITS * n - 1;
while (modulus.test_bit(bitno) == false) while (modulus.test_bit(bitno) == false)
{ {
const std::size_t part = bitno/GMP_NUMB_BITS; const uint64_t part = bitno/GMP_NUMB_BITS;
const std::size_t bit = bitno - (GMP_NUMB_BITS*part); const uint64_t bit = bitno - (GMP_NUMB_BITS*part);
r.mont_repr.data[part] &= ~(1ul<<bit); r.mont_repr.data[part] &= ~(1ull<<bit);
bitno--; bitno--;
} }
@@ -710,7 +710,7 @@ Fp_model<n,modulus> Fp_model<n,modulus>::sqrt() const
Fp_model<n,modulus> one = Fp_model<n,modulus>::one(); Fp_model<n,modulus> one = Fp_model<n,modulus>::one();
size_t v = Fp_model<n,modulus>::s; uint64_t v = Fp_model<n,modulus>::s;
Fp_model<n,modulus> z = Fp_model<n,modulus>::nqr_to_t; Fp_model<n,modulus> z = Fp_model<n,modulus>::nqr_to_t;
Fp_model<n,modulus> w = (*this)^Fp_model<n,modulus>::t_minus_1_over_2; Fp_model<n,modulus> w = (*this)^Fp_model<n,modulus>::t_minus_1_over_2;
Fp_model<n,modulus> x = (*this) * w; Fp_model<n,modulus> x = (*this) * w;
@@ -734,7 +734,7 @@ Fp_model<n,modulus> Fp_model<n,modulus>::sqrt() const
while (b != one) while (b != one)
{ {
size_t m = 0; uint64_t m = 0;
Fp_model<n,modulus> b2m = b; Fp_model<n,modulus> b2m = b;
while (b2m != one) while (b2m != one)
{ {

View File

@@ -66,7 +66,7 @@ public:
Fp12_2over3over2_model squared_karatsuba() const; Fp12_2over3over2_model squared_karatsuba() const;
Fp12_2over3over2_model squared_complex() const; Fp12_2over3over2_model squared_complex() const;
Fp12_2over3over2_model inverse() const; Fp12_2over3over2_model inverse() const;
Fp12_2over3over2_model Frobenius_map(unsigned long power) const; Fp12_2over3over2_model Frobenius_map(uint64_t power) const;
Fp12_2over3over2_model unitary_inverse() const; Fp12_2over3over2_model unitary_inverse() const;
Fp12_2over3over2_model cyclotomic_squared() const; Fp12_2over3over2_model cyclotomic_squared() const;
@@ -78,7 +78,7 @@ public:
Fp12_2over3over2_model cyclotomic_exp(const bigint<m> &exponent) const; Fp12_2over3over2_model cyclotomic_exp(const bigint<m> &exponent) const;
static bigint<n> base_field_char() { return modulus; } static bigint<n> base_field_char() { return modulus; }
static size_t extension_degree() { return 12; } static uint64_t extension_degree() { return 12; }
friend std::ostream& operator<< <n, modulus>(std::ostream &out, const Fp12_2over3over2_model<n, modulus> &el); friend std::ostream& operator<< <n, modulus>(std::ostream &out, const Fp12_2over3over2_model<n, modulus> &el);
friend std::istream& operator>> <n, modulus>(std::istream &in, Fp12_2over3over2_model<n, modulus> &el); friend std::istream& operator>> <n, modulus>(std::istream &in, Fp12_2over3over2_model<n, modulus> &el);

View File

@@ -156,7 +156,7 @@ Fp12_2over3over2_model<n,modulus> Fp12_2over3over2_model<n,modulus>::inverse() c
} }
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
Fp12_2over3over2_model<n,modulus> Fp12_2over3over2_model<n,modulus>::Frobenius_map(unsigned long power) const Fp12_2over3over2_model<n,modulus> Fp12_2over3over2_model<n,modulus>::Frobenius_map(uint64_t power) const
{ {
return Fp12_2over3over2_model<n,modulus>(c0.Frobenius_map(power), return Fp12_2over3over2_model<n,modulus>(c0.Frobenius_map(power),
Frobenius_coeffs_c1[power % 12] * c1.Frobenius_map(power)); Frobenius_coeffs_c1[power % 12] * c1.Frobenius_map(power));
@@ -339,16 +339,16 @@ Fp12_2over3over2_model<n, modulus> Fp12_2over3over2_model<n,modulus>::cyclotomic
Fp12_2over3over2_model<n,modulus> res = Fp12_2over3over2_model<n,modulus>::one(); Fp12_2over3over2_model<n,modulus> res = Fp12_2over3over2_model<n,modulus>::one();
bool found_one = false; bool found_one = false;
for (long i = m-1; i >= 0; --i) for (int64_t i = m-1; i >= 0; --i)
{ {
for (long j = GMP_NUMB_BITS - 1; j >= 0; --j) for (int64_t j = GMP_NUMB_BITS - 1; j >= 0; --j)
{ {
if (found_one) if (found_one)
{ {
res = res.cyclotomic_squared(); res = res.cyclotomic_squared();
} }
if (exponent.data[i] & (1ul<<j)) if (exponent.data[i] & (UINT64_C(1)<<j))
{ {
found_one = true; found_one = true;
res = res * (*this); res = res * (*this);
@@ -390,7 +390,7 @@ std::istream& operator>>(std::istream& in, std::vector<Fp12_2over3over2_model<n,
{ {
v.clear(); v.clear();
size_t s; uint64_t s;
in >> s; in >> s;
char b; char b;

View File

@@ -37,7 +37,7 @@ public:
typedef Fp_model<n, modulus> my_Fp; typedef Fp_model<n, modulus> my_Fp;
static bigint<2*n> euler; // (modulus^2-1)/2 static bigint<2*n> euler; // (modulus^2-1)/2
static size_t s; // modulus^2 = 2^s * t + 1 static uint64_t s; // modulus^2 = 2^s * t + 1
static bigint<2*n> t; // with t odd static bigint<2*n> t; // with t odd
static bigint<2*n> t_minus_1_over_2; // (t-1)/2 static bigint<2*n> t_minus_1_over_2; // (t-1)/2
static my_Fp non_residue; // X^4-non_residue irreducible over Fp; used for constructing Fp2 = Fp[X] / (X^2 - non_residue) static my_Fp non_residue; // X^4-non_residue irreducible over Fp; used for constructing Fp2 = Fp[X] / (X^2 - non_residue)
@@ -66,7 +66,7 @@ public:
Fp2_model operator-() const; Fp2_model operator-() const;
Fp2_model squared() const; // default is squared_complex Fp2_model squared() const; // default is squared_complex
Fp2_model inverse() const; Fp2_model inverse() const;
Fp2_model Frobenius_map(unsigned long power) const; Fp2_model Frobenius_map(uint64_t power) const;
Fp2_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate) Fp2_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate)
Fp2_model squared_karatsuba() const; Fp2_model squared_karatsuba() const;
Fp2_model squared_complex() const; Fp2_model squared_complex() const;
@@ -74,7 +74,7 @@ public:
template<mp_size_t m> template<mp_size_t m>
Fp2_model operator^(const bigint<m> &other) const; Fp2_model operator^(const bigint<m> &other) const;
static size_t size_in_bits() { return 2*my_Fp::size_in_bits(); } static uint64_t size_in_bits() { return 2*my_Fp::size_in_bits(); }
static bigint<n> base_field_char() { return modulus; } static bigint<n> base_field_char() { return modulus; }
friend std::ostream& operator<< <n, modulus>(std::ostream &out, const Fp2_model<n, modulus> &el); friend std::ostream& operator<< <n, modulus>(std::ostream &out, const Fp2_model<n, modulus> &el);
@@ -94,7 +94,7 @@ template<mp_size_t n, const bigint<n>& modulus>
bigint<2*n> Fp2_model<n, modulus>::euler; bigint<2*n> Fp2_model<n, modulus>::euler;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
size_t Fp2_model<n, modulus>::s; uint64_t Fp2_model<n, modulus>::s;
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
bigint<2*n> Fp2_model<n, modulus>::t; bigint<2*n> Fp2_model<n, modulus>::t;

View File

@@ -136,7 +136,7 @@ Fp2_model<n,modulus> Fp2_model<n,modulus>::inverse() const
} }
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
Fp2_model<n,modulus> Fp2_model<n,modulus>::Frobenius_map(unsigned long power) const Fp2_model<n,modulus> Fp2_model<n,modulus>::Frobenius_map(uint64_t power) const
{ {
return Fp2_model<n,modulus>(c0, return Fp2_model<n,modulus>(c0,
Frobenius_coeffs_c1[power % 2] * c1); Frobenius_coeffs_c1[power % 2] * c1);
@@ -151,7 +151,7 @@ Fp2_model<n,modulus> Fp2_model<n,modulus>::sqrt() const
Fp2_model<n,modulus> one = Fp2_model<n,modulus>::one(); Fp2_model<n,modulus> one = Fp2_model<n,modulus>::one();
size_t v = Fp2_model<n,modulus>::s; unsigned long long v = Fp2_model<n,modulus>::s;
Fp2_model<n,modulus> z = Fp2_model<n,modulus>::nqr_to_t; Fp2_model<n,modulus> z = Fp2_model<n,modulus>::nqr_to_t;
Fp2_model<n,modulus> w = (*this)^Fp2_model<n,modulus>::t_minus_1_over_2; Fp2_model<n,modulus> w = (*this)^Fp2_model<n,modulus>::t_minus_1_over_2;
Fp2_model<n,modulus> x = (*this) * w; Fp2_model<n,modulus> x = (*this) * w;
@@ -175,7 +175,7 @@ Fp2_model<n,modulus> Fp2_model<n,modulus>::sqrt() const
while (b != one) while (b != one)
{ {
size_t m = 0; unsigned long long m = 0;
Fp2_model<n,modulus> b2m = b; Fp2_model<n,modulus> b2m = b;
while (b2m != one) while (b2m != one)
{ {
@@ -239,7 +239,7 @@ std::istream& operator>>(std::istream& in, std::vector<Fp2_model<n, modulus> > &
{ {
v.clear(); v.clear();
size_t s; unsigned long long s;
in >> s; in >> s;
char b; char b;

View File

@@ -63,7 +63,7 @@ public:
Fp6_3over2_model operator-() const; Fp6_3over2_model operator-() const;
Fp6_3over2_model squared() const; Fp6_3over2_model squared() const;
Fp6_3over2_model inverse() const; Fp6_3over2_model inverse() const;
Fp6_3over2_model Frobenius_map(unsigned long power) const; Fp6_3over2_model Frobenius_map(uint64_t power) const;
static my_Fp2 mul_by_non_residue(const my_Fp2 &elt); static my_Fp2 mul_by_non_residue(const my_Fp2 &elt);
@@ -71,7 +71,7 @@ public:
Fp6_3over2_model operator^(const bigint<m> &other) const; Fp6_3over2_model operator^(const bigint<m> &other) const;
static bigint<n> base_field_char() { return modulus; } static bigint<n> base_field_char() { return modulus; }
static size_t extension_degree() { return 6; } static uint64_t extension_degree() { return 6; }
friend std::ostream& operator<< <n, modulus>(std::ostream &out, const Fp6_3over2_model<n, modulus> &el); friend std::ostream& operator<< <n, modulus>(std::ostream &out, const Fp6_3over2_model<n, modulus> &el);
friend std::istream& operator>> <n, modulus>(std::istream &in, Fp6_3over2_model<n, modulus> &el); friend std::istream& operator>> <n, modulus>(std::istream &in, Fp6_3over2_model<n, modulus> &el);

View File

@@ -149,7 +149,7 @@ Fp6_3over2_model<n,modulus> Fp6_3over2_model<n,modulus>::inverse() const
} }
template<mp_size_t n, const bigint<n>& modulus> template<mp_size_t n, const bigint<n>& modulus>
Fp6_3over2_model<n,modulus> Fp6_3over2_model<n,modulus>::Frobenius_map(unsigned long power) const Fp6_3over2_model<n,modulus> Fp6_3over2_model<n,modulus>::Frobenius_map(uint64_t power) const
{ {
return Fp6_3over2_model<n,modulus>(c0.Frobenius_map(power), return Fp6_3over2_model<n,modulus>(c0.Frobenius_map(power),
Frobenius_coeffs_c1[power % 6] * c1.Frobenius_map(power), Frobenius_coeffs_c1[power % 6] * c1.Frobenius_map(power),
@@ -194,7 +194,7 @@ std::istream& operator>>(std::istream& in, std::vector<Fp6_3over2_model<n, modul
{ {
v.clear(); v.clear();
size_t s; uint64_t s;
in >> s; in >> s;
char b; char b;

View File

@@ -7,13 +7,11 @@
#include "algebra/fields/bigint.hpp" #include "algebra/fields/bigint.hpp"
#include <gtest/gtest.h>
using namespace libsnark; using namespace libsnark;
TEST(algebra, bigint) void test_bigint()
{ {
static_assert(ULONG_MAX == 0xFFFFFFFFFFFFFFFFul, "unsigned long not 64-bit"); static_assert(UINT64_MAX == 0xFFFFFFFFFFFFFFFFul, "uint64_t not 64-bit");
static_assert(GMP_NUMB_BITS == 64, "GMP limb not 64-bit"); static_assert(GMP_NUMB_BITS == 64, "GMP limb not 64-bit");
const char *b1_decimal = "76749407"; const char *b1_decimal = "76749407";
@@ -22,76 +20,88 @@ TEST(algebra, bigint)
const char *b2_binary = "0000000000000000000000000000010101111101101000000110100001011010" const char *b2_binary = "0000000000000000000000000000010101111101101000000110100001011010"
"1101101010001001000001101000101000100110011001110001111110100010"; "1101101010001001000001101000101000100110011001110001111110100010";
bigint<1> b0 = bigint<1>(0ul); bigint<1> b0 = bigint<1>(UINT64_C(0));
bigint<1> b1 = bigint<1>(b1_decimal); bigint<1> b1 = bigint<1>(b1_decimal);
bigint<2> b2 = bigint<2>(b2_decimal); bigint<2> b2 = bigint<2>(b2_decimal);
EXPECT_EQ(b0.as_ulong(), 0ul); assert(b0.as_ulong() == UINT64_C(0));
EXPECT_TRUE(b0.is_zero()); assert(b0.is_zero());
EXPECT_EQ(b1.as_ulong(), 76749407ul); assert(b1.as_ulong() == UINT64_C(76749407));
EXPECT_FALSE(b1.is_zero()); assert(!(b1.is_zero()));
EXPECT_EQ(b2.as_ulong(), 15747124762497195938ul); assert(b2.as_ulong() == UINT64_C(15747124762497195938));
EXPECT_FALSE(b2.is_zero()); assert(!(b2.is_zero()));
EXPECT_NE(b0, b1); assert(b0 != b1);
EXPECT_FALSE(b0 == b1); assert(!(b0 == b1));
EXPECT_EQ(b2.max_bits(), 128); assert(b2.max_bits() == 128);
EXPECT_EQ(b2.num_bits(), 99); assert(b2.num_bits() == 99);
for (size_t i = 0; i < 128; i++) { for (size_t i = 0; i < 128; i++) {
EXPECT_EQ(b2.test_bit(i), (b2_binary[127-i] == '1')); assert(b2.test_bit(i) == (b2_binary[127-i] == '1'));
} }
bigint<3> b3 = b2 * b1; bigint<3> b3 = b2 * b1;
EXPECT_EQ(b3, bigint<3>(b3_decimal)); assert(b3 == bigint<3>(b3_decimal));
EXPECT_FALSE(b3.is_zero()); assert(!(b3.is_zero()));
bigint<3> b3a { b3 }; bigint<3> b3a { b3 };
EXPECT_EQ(b3a, bigint<3>(b3_decimal)); assert(b3a == bigint<3>(b3_decimal));
EXPECT_EQ(b3a, b3); assert(b3a == b3);
EXPECT_FALSE(b3a.is_zero()); assert(!(b3a.is_zero()));
mpz_t m3; mpz_t m3;
mpz_init(m3); mpz_init(m3);
b3.to_mpz(m3); b3.to_mpz(m3);
bigint<3> b3b { m3 }; bigint<3> b3b { m3 };
EXPECT_EQ(b3b, b3); assert(b3b == b3);
bigint<2> quotient; bigint<2> quotient;
bigint<2> remainder; bigint<2> remainder;
bigint<3>::div_qr(quotient, remainder, b3, b2); bigint<3>::div_qr(quotient, remainder, b3, b2);
EXPECT_LT(quotient.num_bits(), GMP_NUMB_BITS); assert(quotient.num_bits() < GMP_NUMB_BITS);
EXPECT_EQ(quotient.as_ulong(), b1.as_ulong()); assert(quotient.as_ulong() == b1.as_ulong());
bigint<1> b1inc = bigint<1>("76749408"); bigint<1> b1inc = bigint<1>("76749408");
bigint<1> b1a = quotient.shorten(b1inc, "test"); bigint<1> b1a = quotient.shorten(b1inc, "test");
EXPECT_EQ(b1a, b1); assert(b1a == b1);
EXPECT_TRUE(remainder.is_zero()); assert(remainder.is_zero());
remainder.limit(b2, "test"); remainder.limit(b2, "test");
EXPECT_THROW((void)(quotient.shorten(b1, "test")), std::domain_error); try {
EXPECT_THROW(remainder.limit(remainder, "test"), std::domain_error); (void)(quotient.shorten(b1, "test"));
assert(false);
} catch (std::domain_error) {}
try {
remainder.limit(remainder, "test");
assert(false);
} catch (std::domain_error) {}
bigint<1> br = bigint<1>("42"); bigint<1> br = bigint<1>("42");
b3 += br; b3 += br;
EXPECT_NE(b3, b3a); assert(b3 != b3a);
EXPECT_GT(b3, b3a); assert(b3 > b3a);
EXPECT_FALSE(b3a > b3); assert(!(b3a > b3));
bigint<3>::div_qr(quotient, remainder, b3, b2); bigint<3>::div_qr(quotient, remainder, b3, b2);
EXPECT_LT(quotient.num_bits(), GMP_NUMB_BITS); assert(quotient.num_bits() < GMP_NUMB_BITS);
EXPECT_EQ(quotient.as_ulong(), b1.as_ulong()); assert(quotient.as_ulong() == b1.as_ulong());
EXPECT_LT(remainder.num_bits(), GMP_NUMB_BITS); assert(remainder.num_bits() < GMP_NUMB_BITS);
EXPECT_EQ(remainder.as_ulong(), 42); assert(remainder.as_ulong() == 42);
b3a.clear(); b3a.clear();
EXPECT_TRUE(b3a.is_zero()); assert(b3a.is_zero());
EXPECT_EQ(b3a.num_bits(), 0); assert(b3a.num_bits() == 0);
EXPECT_FALSE(b3.is_zero()); assert(!(b3.is_zero()));
bigint<4> bx = bigint<4>().randomize(); bigint<4> bx = bigint<4>().randomize();
bigint<4> by = bigint<4>().randomize(); bigint<4> by = bigint<4>().randomize();
EXPECT_FALSE(bx == by); assert(!(bx == by));
// TODO: test serialization // TODO: test serialization
} }
int main(void)
{
test_bigint();
return 0;
}

View File

@@ -5,6 +5,9 @@
* @copyright MIT license (see LICENSE file) * @copyright MIT license (see LICENSE file)
*****************************************************************************/ *****************************************************************************/
#include "common/profiling.hpp" #include "common/profiling.hpp"
#include "algebra/curves/edwards/edwards_pp.hpp"
#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp"
#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp"
#ifdef CURVE_BN128 #ifdef CURVE_BN128
#include "algebra/curves/bn128/bn128_pp.hpp" #include "algebra/curves/bn128/bn128_pp.hpp"
#endif #endif
@@ -12,8 +15,6 @@
#include "algebra/fields/fp6_3over2.hpp" #include "algebra/fields/fp6_3over2.hpp"
#include "algebra/fields/fp12_2over3over2.hpp" #include "algebra/fields/fp12_2over3over2.hpp"
#include <gtest/gtest.h>
using namespace libsnark; using namespace libsnark;
template<typename FieldT> template<typename FieldT>
@@ -28,25 +29,25 @@ void test_field()
FieldT a = FieldT::random_element(); FieldT a = FieldT::random_element();
FieldT a_ser; FieldT a_ser;
a_ser = reserialize<FieldT>(a); a_ser = reserialize<FieldT>(a);
EXPECT_EQ(a_ser, a); assert(a_ser == a);
FieldT b = FieldT::random_element(); FieldT b = FieldT::random_element();
FieldT c = FieldT::random_element(); FieldT c = FieldT::random_element();
FieldT d = FieldT::random_element(); FieldT d = FieldT::random_element();
EXPECT_NE(a, zero); assert(a != zero);
EXPECT_NE(a, one); assert(a != one);
EXPECT_EQ(a * a, a.squared()); assert(a * a == a.squared());
EXPECT_EQ((a + b).squared(), a.squared() + a*b + b*a + b.squared()); assert((a + b).squared() == a.squared() + a*b + b*a + b.squared());
EXPECT_EQ((a + b)*(c + d), a*c + a*d + b*c + b*d); assert((a + b)*(c + d) == a*c + a*d + b*c + b*d);
EXPECT_EQ(a - b, a + (-b)); assert(a - b == a + (-b));
EXPECT_EQ(a - b, (-b) + a); assert(a - b == (-b) + a);
EXPECT_EQ((a ^ rand1) * (a ^ rand2), (a^randsum)); assert((a ^ rand1) * (a ^ rand2) == (a^randsum));
EXPECT_EQ(a * a.inverse(), one); assert(a * a.inverse() == one);
EXPECT_EQ((a + b) * c.inverse(), a * c.inverse() + (b.inverse() * c).inverse()); assert((a + b) * c.inverse() == a * c.inverse() + (b.inverse() * c).inverse());
} }
@@ -57,7 +58,7 @@ void test_sqrt()
{ {
FieldT a = FieldT::random_element(); FieldT a = FieldT::random_element();
FieldT asq = a.squared(); FieldT asq = a.squared();
EXPECT_TRUE(asq.sqrt() == a || asq.sqrt() == -a); assert(asq.sqrt() == a || asq.sqrt() == -a);
} }
} }
@@ -65,21 +66,21 @@ template<typename FieldT>
void test_two_squarings() void test_two_squarings()
{ {
FieldT a = FieldT::random_element(); FieldT a = FieldT::random_element();
EXPECT_EQ(a.squared(), a * a); assert(a.squared() == a * a);
EXPECT_EQ(a.squared(), a.squared_complex()); assert(a.squared() == a.squared_complex());
EXPECT_EQ(a.squared(), a.squared_karatsuba()); assert(a.squared() == a.squared_karatsuba());
} }
template<typename FieldT> template<typename FieldT>
void test_Frobenius() void test_Frobenius()
{ {
FieldT a = FieldT::random_element(); FieldT a = FieldT::random_element();
EXPECT_EQ(a.Frobenius_map(0), a); assert(a.Frobenius_map(0) == a);
FieldT a_q = a ^ FieldT::base_field_char(); FieldT a_q = a ^ FieldT::base_field_char();
for (size_t power = 1; power < 10; ++power) for (size_t power = 1; power < 10; ++power)
{ {
const FieldT a_qi = a.Frobenius_map(power); const FieldT a_qi = a.Frobenius_map(power);
EXPECT_EQ(a_qi, a_q); assert(a_qi == a_q);
a_q = a_q ^ FieldT::base_field_char(); a_q = a_q ^ FieldT::base_field_char();
} }
@@ -88,10 +89,49 @@ void test_Frobenius()
template<typename FieldT> template<typename FieldT>
void test_unitary_inverse() void test_unitary_inverse()
{ {
EXPECT_EQ(FieldT::extension_degree() % 2, 0); assert(FieldT::extension_degree() % 2 == 0);
FieldT a = FieldT::random_element(); FieldT a = FieldT::random_element();
FieldT aqcubed_minus1 = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse(); FieldT aqcubed_minus1 = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse();
EXPECT_EQ(aqcubed_minus1.inverse(), aqcubed_minus1.unitary_inverse()); assert(aqcubed_minus1.inverse() == aqcubed_minus1.unitary_inverse());
}
template<typename FieldT>
void test_cyclotomic_squaring();
template<>
void test_cyclotomic_squaring<Fqk<edwards_pp> >()
{
typedef Fqk<edwards_pp> FieldT;
assert(FieldT::extension_degree() % 2 == 0);
FieldT a = FieldT::random_element();
FieldT a_unitary = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse();
// beta = a^((q^(k/2)-1)*(q+1))
FieldT beta = a_unitary.Frobenius_map(1) * a_unitary;
assert(beta.cyclotomic_squared() == beta.squared());
}
template<>
void test_cyclotomic_squaring<Fqk<mnt4_pp> >()
{
typedef Fqk<mnt4_pp> FieldT;
assert(FieldT::extension_degree() % 2 == 0);
FieldT a = FieldT::random_element();
FieldT a_unitary = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse();
// beta = a^(q^(k/2)-1)
FieldT beta = a_unitary;
assert(beta.cyclotomic_squared() == beta.squared());
}
template<>
void test_cyclotomic_squaring<Fqk<mnt6_pp> >()
{
typedef Fqk<mnt6_pp> FieldT;
assert(FieldT::extension_degree() % 2 == 0);
FieldT a = FieldT::random_element();
FieldT a_unitary = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse();
// beta = a^((q^(k/2)-1)*(q+1))
FieldT beta = a_unitary.Frobenius_map(1) * a_unitary;
assert(beta.cyclotomic_squared() == beta.squared());
} }
template<typename ppT> template<typename ppT>
@@ -157,16 +197,16 @@ void test_Fp4_tom_cook()
c2 = - (FieldT(5)*(FieldT(4).inverse()))* v0 + (FieldT(2)*(FieldT(3).inverse()))*(v1 + v2) - FieldT(24).inverse()*(v3 + v4) + FieldT(4)*v6 + beta*v6; c2 = - (FieldT(5)*(FieldT(4).inverse()))* v0 + (FieldT(2)*(FieldT(3).inverse()))*(v1 + v2) - FieldT(24).inverse()*(v3 + v4) + FieldT(4)*v6 + beta*v6;
c3 = FieldT(12).inverse() * (FieldT(5)*v0 - FieldT(7)*v1) - FieldT(24).inverse()*(v2 - FieldT(7)*v3 + v4 + v5) + FieldT(15)*v6; c3 = FieldT(12).inverse() * (FieldT(5)*v0 - FieldT(7)*v1) - FieldT(24).inverse()*(v2 - FieldT(7)*v3 + v4 + v5) + FieldT(15)*v6;
EXPECT_EQ(res, correct_res); assert(res == correct_res);
// {v0, v3, v4, v5} // {v0, v3, v4, v5}
const FieldT u = (FieldT::one() - beta).inverse(); const FieldT u = (FieldT::one() - beta).inverse();
EXPECT_EQ(v0, u * c0 + beta * u * c2 - beta * u * FieldT(2).inverse() * v1 - beta * u * FieldT(2).inverse() * v2 + beta * v6); assert(v0 == u * c0 + beta * u * c2 - beta * u * FieldT(2).inverse() * v1 - beta * u * FieldT(2).inverse() * v2 + beta * v6);
EXPECT_EQ(v3, - FieldT(15) * u * c0 - FieldT(30) * u * c1 - FieldT(3) * (FieldT(4) + beta) * u * c2 - FieldT(6) * (FieldT(4) + beta) * u * c3 + (FieldT(24) - FieldT(3) * beta * FieldT(2).inverse()) * u * v1 + (-FieldT(8) + beta * FieldT(2).inverse()) * u * v2 assert(v3 == - FieldT(15) * u * c0 - FieldT(30) * u * c1 - FieldT(3) * (FieldT(4) + beta) * u * c2 - FieldT(6) * (FieldT(4) + beta) * u * c3 + (FieldT(24) - FieldT(3) * beta * FieldT(2).inverse()) * u * v1 + (-FieldT(8) + beta * FieldT(2).inverse()) * u * v2
- FieldT(3) * (-FieldT(16) + beta) * v6); - FieldT(3) * (-FieldT(16) + beta) * v6);
EXPECT_EQ(v4, - FieldT(15) * u * c0 + FieldT(30) * u * c1 - FieldT(3) * (FieldT(4) + beta) * u * c2 + FieldT(6) * (FieldT(4) + beta) * u * c3 + (FieldT(24) - FieldT(3) * beta * FieldT(2).inverse()) * u * v2 + (-FieldT(8) + beta * FieldT(2).inverse()) * u * v1 assert(v4 == - FieldT(15) * u * c0 + FieldT(30) * u * c1 - FieldT(3) * (FieldT(4) + beta) * u * c2 + FieldT(6) * (FieldT(4) + beta) * u * c3 + (FieldT(24) - FieldT(3) * beta * FieldT(2).inverse()) * u * v2 + (-FieldT(8) + beta * FieldT(2).inverse()) * u * v1
- FieldT(3) * (-FieldT(16) + beta) * v6); - FieldT(3) * (-FieldT(16) + beta) * v6);
EXPECT_EQ(v5, - FieldT(80) * u * c0 - FieldT(240) * u * c1 - FieldT(8) * (FieldT(9) + beta) * u * c2 - FieldT(24) * (FieldT(9) + beta) * u * c3 - FieldT(2) * (-FieldT(81) + beta) * u * v1 + (-FieldT(81) + beta) * u * v2 assert(v5 == - FieldT(80) * u * c0 - FieldT(240) * u * c1 - FieldT(8) * (FieldT(9) + beta) * u * c2 - FieldT(24) * (FieldT(9) + beta) * u * c3 - FieldT(2) * (-FieldT(81) + beta) * u * v1 + (-FieldT(81) + beta) * u * v2
- FieldT(8) * (-FieldT(81) + beta) * v6); - FieldT(8) * (-FieldT(81) + beta) * v6);
// c0 + beta c2 - (beta v1)/2 - (beta v2)/ 2 - (-1 + beta) beta v6, // c0 + beta c2 - (beta v1)/2 - (beta v2)/ 2 - (-1 + beta) beta v6,
@@ -176,8 +216,22 @@ void test_Fp4_tom_cook()
} }
} }
TEST(algebra, fields) int main(void)
{ {
edwards_pp::init_public_params();
test_all_fields<edwards_pp>();
test_cyclotomic_squaring<Fqk<edwards_pp> >();
mnt4_pp::init_public_params();
test_all_fields<mnt4_pp>();
test_Fp4_tom_cook<mnt4_Fq4>();
test_two_squarings<Fqe<mnt4_pp> >();
test_cyclotomic_squaring<Fqk<mnt4_pp> >();
mnt6_pp::init_public_params();
test_all_fields<mnt6_pp>();
test_cyclotomic_squaring<Fqk<mnt6_pp> >();
alt_bn128_pp::init_public_params(); alt_bn128_pp::init_public_params();
test_field<alt_bn128_Fq6>(); test_field<alt_bn128_Fq6>();
test_Frobenius<alt_bn128_Fq6>(); test_Frobenius<alt_bn128_Fq6>();

View File

@@ -10,9 +10,9 @@
/* /*
Split out from multiexp to prevent cyclical Split out from multiexp to prevent cyclical
dependencies. I.e. previously multiexp depended on dependencies. I.e. previously multiexp dependend on
knowledge_commitment, which depended on sparse_vector, which knowledge_commitment, which dependend on sparse_vector, which
depended on multiexp (to do accumulate). dependend on multiexp (to do accumulate).
Will probably go away in more general exp refactoring. Will probably go away in more general exp refactoring.
*/ */

View File

@@ -8,6 +8,8 @@
#ifndef KC_MULTIEXP_TCC_ #ifndef KC_MULTIEXP_TCC_
#define KC_MULTIEXP_TCC_ #define KC_MULTIEXP_TCC_
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
template<typename T1, typename T2, mp_size_t n> template<typename T1, typename T2, mp_size_t n>
@@ -50,7 +52,7 @@ knowledge_commitment<T1, T2> kc_multi_exp_with_mixed_addition(const knowledge_co
while (index_it != vec.indices.end() && *index_it < max_idx) while (index_it != vec.indices.end() && *index_it < max_idx)
{ {
const size_t scalar_position = (*index_it) - min_idx; const size_t scalar_position = (*index_it) - min_idx;
assert(scalar_position < scalar_length); assert_except(scalar_position < scalar_length);
const FieldT scalar = *(scalar_start + scalar_position); const FieldT scalar = *(scalar_start + scalar_position);

View File

@@ -22,6 +22,7 @@
#include "common/profiling.hpp" #include "common/profiling.hpp"
#include "common/utils.hpp" #include "common/utils.hpp"
#include "common/assert_except.hpp"
#include "algebra/scalar_multiplication/wnaf.hpp" #include "algebra/scalar_multiplication/wnaf.hpp"
namespace libsnark { namespace libsnark {
@@ -40,7 +41,7 @@ public:
#if defined(__x86_64__) && defined(USE_ASM) #if defined(__x86_64__) && defined(USE_ASM)
if (n == 3) if (n == 3)
{ {
long res; int64_t res;
__asm__ __asm__
("// check for overflow \n\t" ("// check for overflow \n\t"
"mov $0, %[res] \n\t" "mov $0, %[res] \n\t"
@@ -58,7 +59,7 @@ public:
} }
else if (n == 4) else if (n == 4)
{ {
long res; int64_t res;
__asm__ __asm__
("// check for overflow \n\t" ("// check for overflow \n\t"
"mov $0, %[res] \n\t" "mov $0, %[res] \n\t"
@@ -77,7 +78,7 @@ public:
} }
else if (n == 5) else if (n == 5)
{ {
long res; int64_t res;
__asm__ __asm__
("// check for overflow \n\t" ("// check for overflow \n\t"
"mov $0, %[res] \n\t" "mov $0, %[res] \n\t"
@@ -119,7 +120,7 @@ T naive_exp(typename std::vector<T>::const_iterator vec_start,
bigint<FieldT::num_limbs> scalar_bigint = scalar_it->as_bigint(); bigint<FieldT::num_limbs> scalar_bigint = scalar_it->as_bigint();
result = result + opt_window_wnaf_exp(*vec_it, scalar_bigint, scalar_bigint.num_bits()); result = result + opt_window_wnaf_exp(*vec_it, scalar_bigint, scalar_bigint.num_bits());
} }
assert(scalar_it == scalar_end); assert_except(scalar_it == scalar_end);
return result; return result;
} }
@@ -139,7 +140,7 @@ T naive_plain_exp(typename std::vector<T>::const_iterator vec_start,
{ {
result = result + (*scalar_it) * (*vec_it); result = result + (*scalar_it) * (*vec_it);
} }
assert(scalar_it == scalar_end); assert_except(scalar_it == scalar_end);
return result; return result;
} }
@@ -185,15 +186,15 @@ T multi_exp_inner(typename std::vector<T>::const_iterator vec_start,
opt_q.emplace_back(ordered_exponent<n>(i, scalar_it->as_bigint())); opt_q.emplace_back(ordered_exponent<n>(i, scalar_it->as_bigint()));
} }
std::make_heap(opt_q.begin(),opt_q.end()); std::make_heap(opt_q.begin(),opt_q.end());
assert(scalar_it == scalar_end); assert_except(scalar_it == scalar_end);
if (vec_len != odd_vec_len) if (vec_len != odd_vec_len)
{ {
g.emplace_back(T::zero()); g.emplace_back(T::zero());
opt_q.emplace_back(ordered_exponent<n>(odd_vec_len - 1, bigint<n>(0ul))); opt_q.emplace_back(ordered_exponent<n>(odd_vec_len - 1, bigint<n>(UINT64_C(0))));
} }
assert(g.size() % 2 == 1); assert_except(g.size() % 2 == 1);
assert(opt_q.size() == g.size()); assert_except(opt_q.size() == g.size());
T opt_result = T::zero(); T opt_result = T::zero();
@@ -214,7 +215,7 @@ T multi_exp_inner(typename std::vector<T>::const_iterator vec_start,
const size_t bbits = b.r.num_bits(); const size_t bbits = b.r.num_bits();
const size_t limit = (abits-bbits >= 20 ? 20 : abits-bbits); const size_t limit = (abits-bbits >= 20 ? 20 : abits-bbits);
if (bbits < 1ul<<limit) if (bbits < UINT64_C(1)<<limit)
{ {
/* /*
In this case, exponentiating to the power of a is cheaper than In this case, exponentiating to the power of a is cheaper than
@@ -329,7 +330,7 @@ T multi_exp_with_mixed_addition(typename std::vector<T>::const_iterator vec_star
const size_t chunks, const size_t chunks,
const bool use_multiexp) const bool use_multiexp)
{ {
assert(std::distance(vec_start, vec_end) == std::distance(scalar_start, scalar_end)); assert_except(std::distance(vec_start, vec_end) == std::distance(scalar_start, scalar_end));
enter_block("Process scalar vector"); enter_block("Process scalar vector");
auto value_it = vec_start; auto value_it = vec_start;
auto scalar_it = scalar_start; auto scalar_it = scalar_start;
@@ -389,7 +390,7 @@ size_t get_exp_window_size(const size_t num_scalars)
#endif #endif
} }
size_t window = 1; size_t window = 1;
for (long i = T::fixed_base_exp_window_table.size()-1; i >= 0; --i) for (int64_t i = T::fixed_base_exp_window_table.size()-1; i >= 0; --i)
{ {
#ifdef DEBUG #ifdef DEBUG
if (!inhibit_profiling_info) if (!inhibit_profiling_info)
@@ -420,9 +421,9 @@ window_table<T> get_window_table(const size_t scalar_size,
const size_t window, const size_t window,
const T &g) const T &g)
{ {
const size_t in_window = 1ul<<window; const size_t in_window = UINT64_C(1)<<window;
const size_t outerc = (scalar_size+window-1)/window; const size_t outerc = (scalar_size+window-1)/window;
const size_t last_in_window = 1ul<<(scalar_size - (outerc-1)*window); const size_t last_in_window = UINT64_C(1)<<(scalar_size - (outerc-1)*window);
#ifdef DEBUG #ifdef DEBUG
if (!inhibit_profiling_info) if (!inhibit_profiling_info)
{ {

View File

@@ -18,7 +18,7 @@ namespace libsnark {
* Find the wNAF representation of the given scalar relative to the given window size. * Find the wNAF representation of the given scalar relative to the given window size.
*/ */
template<mp_size_t n> template<mp_size_t n>
std::vector<long> find_wnaf(const size_t window_size, const bigint<n> &scalar); std::vector<int64_t> find_wnaf(const size_t window_size, const bigint<n> &scalar);
/** /**
* In additive notation, use wNAF exponentiation (with the given window size) to compute scalar * base. * In additive notation, use wNAF exponentiation (with the given window size) to compute scalar * base.

View File

@@ -17,15 +17,15 @@
namespace libsnark { namespace libsnark {
template<mp_size_t n> template<mp_size_t n>
std::vector<long> find_wnaf(const size_t window_size, const bigint<n> &scalar) std::vector<int64_t> find_wnaf(const size_t window_size, const bigint<n> &scalar)
{ {
const size_t length = scalar.max_bits(); // upper bound const size_t length = scalar.max_bits(); // upper bound
std::vector<long> res(length+1); std::vector<int64_t> res(length+1);
bigint<n> c = scalar; bigint<n> c = scalar;
long j = 0; int64_t j = 0;
while (!c.is_zero()) while (!c.is_zero())
{ {
long u; int64_t u;
if ((c.data[0] & 1) == 1) if ((c.data[0] & 1) == 1)
{ {
u = c.data[0] % (1u << (window_size+1)); u = c.data[0] % (1u << (window_size+1));
@@ -59,11 +59,11 @@ std::vector<long> find_wnaf(const size_t window_size, const bigint<n> &scalar)
template<typename T, mp_size_t n> template<typename T, mp_size_t n>
T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint<n> &scalar) T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint<n> &scalar)
{ {
std::vector<long> naf = find_wnaf(window_size, scalar); std::vector<int64_t> naf = find_wnaf(window_size, scalar);
std::vector<T> table(1ul<<(window_size-1)); std::vector<T> table(UINT64_C(1)<<(window_size-1));
T tmp = base; T tmp = base;
T dbl = base.dbl(); T dbl = base.dbl();
for (size_t i = 0; i < 1ul<<(window_size-1); ++i) for (size_t i = 0; i < UINT64_C(1)<<(window_size-1); ++i)
{ {
table[i] = tmp; table[i] = tmp;
tmp = tmp + dbl; tmp = tmp + dbl;
@@ -71,7 +71,7 @@ T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint<n>
T res = T::zero(); T res = T::zero();
bool found_nonzero = false; bool found_nonzero = false;
for (long i = naf.size()-1; i >= 0; --i) for (int64_t i = naf.size()-1; i >= 0; --i)
{ {
if (found_nonzero) if (found_nonzero)
{ {
@@ -99,7 +99,7 @@ template<typename T, mp_size_t n>
T opt_window_wnaf_exp(const T &base, const bigint<n> &scalar, const size_t scalar_bits) T opt_window_wnaf_exp(const T &base, const bigint<n> &scalar, const size_t scalar_bits)
{ {
size_t best = 0; size_t best = 0;
for (long i = T::wnaf_window_table.size() - 1; i >= 0; --i) for (int64_t i = T::wnaf_window_table.size() - 1; i >= 0; --i)
{ {
if (scalar_bits >= T::wnaf_window_table[i]) if (scalar_bits >= T::wnaf_window_table[i])
{ {

View File

@@ -66,14 +66,14 @@ merkle_tree<HashT>::merkle_tree(const size_t depth,
assert(log2(contents_as_vector.size()) <= depth); assert(log2(contents_as_vector.size()) <= depth);
for (size_t address = 0; address < contents_as_vector.size(); ++address) for (size_t address = 0; address < contents_as_vector.size(); ++address)
{ {
const size_t idx = address + (1ul<<depth) - 1; const size_t idx = address + (UINT64_C(1)<<depth) - 1;
values[idx] = contents_as_vector[address]; values[idx] = contents_as_vector[address];
hashes[idx] = contents_as_vector[address]; hashes[idx] = contents_as_vector[address];
hashes[idx].resize(digest_size); hashes[idx].resize(digest_size);
} }
size_t idx_begin = (1ul<<depth) - 1; size_t idx_begin = (UINT64_C(1)<<depth) - 1;
size_t idx_end = contents_as_vector.size() + ((1ul<<depth) - 1); size_t idx_end = contents_as_vector.size() + ((UINT64_C(1)<<depth) - 1);
for (int layer = depth; layer > 0; --layer) for (int layer = depth; layer > 0; --layer)
{ {
@@ -100,13 +100,13 @@ merkle_tree<HashT>::merkle_tree(const size_t depth,
if (!contents.empty()) if (!contents.empty())
{ {
assert(contents.rbegin()->first < 1ul<<depth); assert(contents.rbegin()->first < UINT64_C(1)<<depth);
for (auto it = contents.begin(); it != contents.end(); ++it) for (auto it = contents.begin(); it != contents.end(); ++it)
{ {
const size_t address = it->first; const size_t address = it->first;
const bit_vector value = it->second; const bit_vector value = it->second;
const size_t idx = address + (1ul<<depth) - 1; const size_t idx = address + (UINT64_C(1)<<depth) - 1;
values[address] = value; values[address] = value;
hashes[idx] = value; hashes[idx] = value;
@@ -167,7 +167,7 @@ void merkle_tree<HashT>::set_value(const size_t address,
const bit_vector &value) const bit_vector &value)
{ {
assert(log2(address) <= depth); assert(log2(address) <= depth);
size_t idx = address + (1ul<<depth) - 1; size_t idx = address + (UINT64_C(1)<<depth) - 1;
assert(value.size() == value_size); assert(value.size() == value_size);
values[address] = value; values[address] = value;
@@ -201,7 +201,7 @@ typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(con
{ {
typename HashT::merkle_authentication_path_type result(depth); typename HashT::merkle_authentication_path_type result(depth);
assert(log2(address) <= depth); assert(log2(address) <= depth);
size_t idx = address + (1ul<<depth) - 1; size_t idx = address + (UINT64_C(1)<<depth) - 1;
for (size_t layer = depth; layer > 0; --layer) for (size_t layer = depth; layer > 0; --layer)
{ {
@@ -209,7 +209,7 @@ typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(con
auto it = hashes.find(sibling_idx); auto it = hashes.find(sibling_idx);
if (layer == depth) if (layer == depth)
{ {
auto it2 = values.find(sibling_idx - ((1ul<<depth) - 1)); auto it2 = values.find(sibling_idx - ((UINT64_C(1)<<depth) - 1));
result[layer-1] = (it2 == values.end() ? bit_vector(value_size, false) : it2->second); result[layer-1] = (it2 == values.end() ? bit_vector(value_size, false) : it2->second);
result[layer-1].resize(digest_size); result[layer-1].resize(digest_size);
} }
@@ -227,7 +227,7 @@ typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(con
template<typename HashT> template<typename HashT>
void merkle_tree<HashT>::dump() const void merkle_tree<HashT>::dump() const
{ {
for (size_t i = 0; i < 1ul<<depth; ++i) for (size_t i = 0; i < UINT64_C(1)<<depth; ++i)
{ {
auto it = values.find(i); auto it = values.find(i);
printf("[%zu] -> ", i); printf("[%zu] -> ", i);

View File

@@ -32,9 +32,9 @@ std::istream& operator>>(std::istream &in, sparse_vector<T> &v);
template<typename T> template<typename T>
struct sparse_vector { struct sparse_vector {
std::vector<size_t> indices; std::vector<uint64_t> indices;
std::vector<T> values; std::vector<T> values;
size_t domain_size_ = 0; uint64_t domain_size_ = 0;
sparse_vector() = default; sparse_vector() = default;
sparse_vector(const sparse_vector<T> &other) = default; sparse_vector(const sparse_vector<T> &other) = default;
@@ -44,7 +44,7 @@ struct sparse_vector {
sparse_vector<T>& operator=(const sparse_vector<T> &other) = default; sparse_vector<T>& operator=(const sparse_vector<T> &other) = default;
sparse_vector<T>& operator=(sparse_vector<T> &&other) = default; sparse_vector<T>& operator=(sparse_vector<T> &&other) = default;
T operator[](const size_t idx) const; T operator[](const uint64_t idx) const;
bool operator==(const sparse_vector<T> &other) const; bool operator==(const sparse_vector<T> &other) const;
bool operator==(const std::vector<T> &other) const; bool operator==(const std::vector<T> &other) const;
@@ -52,15 +52,15 @@ struct sparse_vector {
bool is_valid() const; bool is_valid() const;
bool empty() const; bool empty() const;
size_t domain_size() const; // return domain_size_ uint64_t domain_size() const; // return domain_size_
size_t size() const; // return the number of indices (representing the number of non-zero entries) uint64_t size() const; // return the number of indices (representing the number of non-zero entries)
size_t size_in_bits() const; // return the number bits needed to store the sparse vector uint64_t size_in_bits() const; // return the number bits needed to store the sparse vector
/* return a pair consisting of the accumulated value and the sparse vector of non-accumulated values */ /* return a pair consisting of the accumulated value and the sparse vector of non-accumuated values */
template<typename FieldT> template<typename FieldT>
std::pair<T, sparse_vector<T> > accumulate(const typename std::vector<FieldT>::const_iterator &it_begin, std::pair<T, sparse_vector<T> > accumulate(const typename std::vector<FieldT>::const_iterator &it_begin,
const typename std::vector<FieldT>::const_iterator &it_end, const typename std::vector<FieldT>::const_iterator &it_end,
const size_t offset) const; const uint64_t offset) const;
friend std::ostream& operator<< <T>(std::ostream &out, const sparse_vector<T> &v); friend std::ostream& operator<< <T>(std::ostream &out, const sparse_vector<T> &v);
friend std::istream& operator>> <T>(std::istream &in, sparse_vector<T> &v); friend std::istream& operator>> <T>(std::istream &in, sparse_vector<T> &v);

View File

@@ -29,7 +29,7 @@ sparse_vector<T>::sparse_vector(std::vector<T> &&v) :
} }
template<typename T> template<typename T>
T sparse_vector<T>::operator[](const size_t idx) const T sparse_vector<T>::operator[](const uint64_t idx) const
{ {
auto it = std::lower_bound(indices.begin(), indices.end(), idx); auto it = std::lower_bound(indices.begin(), indices.end(), idx);
return (it != indices.end() && *it == idx) ? values[it - indices.begin()] : T(); return (it != indices.end() && *it == idx) ? values[it - indices.begin()] : T();
@@ -43,7 +43,7 @@ bool sparse_vector<T>::operator==(const sparse_vector<T> &other) const
return false; return false;
} }
size_t this_pos = 0, other_pos = 0; uint64_t this_pos = 0, other_pos = 0;
while (this_pos < this->indices.size() && other_pos < other.indices.size()) while (this_pos < this->indices.size() && other_pos < other.indices.size())
{ {
if (this->indices[this_pos] == other.indices[other_pos]) if (this->indices[this_pos] == other.indices[other_pos])
@@ -103,8 +103,8 @@ bool sparse_vector<T>::operator==(const std::vector<T> &other) const
return false; return false;
} }
size_t j = 0; uint64_t j = 0;
for (size_t i = 0; i < other.size(); ++i) for (uint64_t i = 0; i < other.size(); ++i)
{ {
if (this->indices[j] == i) if (this->indices[j] == i)
{ {
@@ -134,7 +134,7 @@ bool sparse_vector<T>::is_valid() const
return false; return false;
} }
for (size_t i = 0; i + 1 < indices.size(); ++i) for (uint64_t i = 0; i + 1 < indices.size(); ++i)
{ {
if (indices[i] >= indices[i+1]) if (indices[i] >= indices[i+1])
{ {
@@ -157,42 +157,42 @@ bool sparse_vector<T>::empty() const
} }
template<typename T> template<typename T>
size_t sparse_vector<T>::domain_size() const uint64_t sparse_vector<T>::domain_size() const
{ {
return domain_size_; return domain_size_;
} }
template<typename T> template<typename T>
size_t sparse_vector<T>::size() const uint64_t sparse_vector<T>::size() const
{ {
return indices.size(); return indices.size();
} }
template<typename T> template<typename T>
size_t sparse_vector<T>::size_in_bits() const uint64_t sparse_vector<T>::size_in_bits() const
{ {
return indices.size() * (sizeof(size_t) * 8 + T::size_in_bits()); return indices.size() * (sizeof(uint64_t) * 8 + T::size_in_bits());
} }
template<typename T> template<typename T>
template<typename FieldT> template<typename FieldT>
std::pair<T, sparse_vector<T> > sparse_vector<T>::accumulate(const typename std::vector<FieldT>::const_iterator &it_begin, std::pair<T, sparse_vector<T> > sparse_vector<T>::accumulate(const typename std::vector<FieldT>::const_iterator &it_begin,
const typename std::vector<FieldT>::const_iterator &it_end, const typename std::vector<FieldT>::const_iterator &it_end,
const size_t offset) const const uint64_t offset) const
{ {
// TODO: does not really belong here. // TODO: does not really belong here.
const size_t chunks = 1; const uint64_t chunks = 1;
const bool use_multiexp = true; const bool use_multiexp = true;
T accumulated_value = T::zero(); T accumulated_value = T::zero();
sparse_vector<T> resulting_vector; sparse_vector<T> resulting_vector;
resulting_vector.domain_size_ = domain_size_; resulting_vector.domain_size_ = domain_size_;
const size_t range_len = it_end - it_begin; const uint64_t range_len = it_end - it_begin;
bool in_block = false; bool in_block = false;
size_t first_pos = -1, last_pos = -1; // g++ -flto emits unitialized warning, even though in_block guards for such cases. uint64_t first_pos = -1, last_pos = -1; // g++ -flto emits unitialized warning, even though in_block guards for such cases.
for (size_t i = 0; i < indices.size(); ++i) for (uint64_t i = 0; i < indices.size(); ++i)
{ {
const bool matching_pos = (offset <= indices[i] && indices[i] < offset + range_len); const bool matching_pos = (offset <= indices[i] && indices[i] < offset + range_len);
// printf("i = %zu, pos[i] = %zu, offset = %zu, w_size = %zu\n", i, indices[i], offset, w_size); // printf("i = %zu, pos[i] = %zu, offset = %zu, w_size = %zu\n", i, indices[i], offset, w_size);
@@ -265,7 +265,7 @@ std::ostream& operator<<(std::ostream& out, const sparse_vector<T> &v)
{ {
out << v.domain_size_ << "\n"; out << v.domain_size_ << "\n";
out << v.indices.size() << "\n"; out << v.indices.size() << "\n";
for (const size_t& i : v.indices) for (const uint64_t& i : v.indices)
{ {
out << i << "\n"; out << i << "\n";
} }
@@ -285,11 +285,11 @@ std::istream& operator>>(std::istream& in, sparse_vector<T> &v)
in >> v.domain_size_; in >> v.domain_size_;
consume_newline(in); consume_newline(in);
size_t s; uint64_t s;
in >> s; in >> s;
consume_newline(in); consume_newline(in);
v.indices.resize(s); v.indices.resize(s);
for (size_t i = 0; i < s; ++i) for (uint64_t i = 0; i < s; ++i)
{ {
in >> v.indices[i]; in >> v.indices[i];
consume_newline(in); consume_newline(in);
@@ -300,7 +300,7 @@ std::istream& operator>>(std::istream& in, sparse_vector<T> &v)
consume_newline(in); consume_newline(in);
v.values.reserve(s); v.values.reserve(s);
for (size_t i = 0; i < s; ++i) for (uint64_t i = 0; i < s; ++i)
{ {
T t; T t;
in >> t; in >> t;

View File

@@ -26,27 +26,44 @@
#include <proc/readproc.h> #include <proc/readproc.h>
#endif #endif
#ifdef __MACH__ // required to build on MacOS
#include <time.h>
#include <sys/time.h>
#include <mach/clock.h>
#include <mach/mach.h>
#endif
namespace libsnark { namespace libsnark {
long long get_nsec_time() int64_t get_nsec_time()
{ {
auto timepoint = std::chrono::high_resolution_clock::now(); auto timepoint = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::nanoseconds>(timepoint.time_since_epoch()).count(); return std::chrono::duration_cast<std::chrono::nanoseconds>(timepoint.time_since_epoch()).count();
} }
/* Return total CPU time consumed by all threads of the process, in nanoseconds. */ /* Return total CPU time consumsed by all threads of the process, in nanoseconds. */
long long get_nsec_cpu_time() int64_t get_nsec_cpu_time()
{ {
::timespec ts; ::timespec ts;
#ifdef __MACH__
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
ts.tv_sec = mts.tv_sec;
ts.tv_nsec = mts.tv_nsec;
#else
if ( ::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) ) if ( ::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) )
throw ::std::runtime_error("clock_gettime(CLOCK_PROCESS_CPUTIME_ID) failed"); throw ::std::runtime_error("clock_gettime(CLOCK_PROCESS_CPUTIME_ID) failed");
// If we expected this to work, don't silently ignore failures, because that would hide the problem and incur an unnecessarily system-call overhead. So if we ever observe this exception, we should probably add a suitable #ifdef . // If we expected this to work, don't silently ignore failures, because that would hide the problem and incur an unnecessarily system-call overhead. So if we ever observe this exception, we should probably add a suitable #ifdef .
//TODO: clock_gettime(CLOCK_PROCESS_CPUTIME_ID) is not supported by native Windows. What about Cygwin? Should we #ifdef on CLOCK_PROCESS_CPUTIME_ID or on __linux__? //TODO: clock_gettime(CLOCK_PROCESS_CPUTIME_ID) is not supported by native Windows. What about Cygwin? Should we #ifdef on CLOCK_PROCESS_CPUTIME_ID or on __linux__?
#endif
return ts.tv_sec * 1000000000ll + ts.tv_nsec; return ts.tv_sec * 1000000000ll + ts.tv_nsec;
} }
long long start_time, last_time; int64_t start_time, last_time;
long long start_cpu_time, last_cpu_time; int64_t start_cpu_time, last_cpu_time;
void start_profiling() void start_profiling()
{ {
@@ -57,20 +74,20 @@ void start_profiling()
} }
std::map<std::string, size_t> invocation_counts; std::map<std::string, size_t> invocation_counts;
std::map<std::string, long long> enter_times; std::map<std::string, int64_t> enter_times;
std::map<std::string, long long> last_times; std::map<std::string, int64_t> last_times;
std::map<std::string, long long> cumulative_times; std::map<std::string, int64_t> cumulative_times;
//TODO: Instead of analogous maps for time and cpu_time, use a single struct-valued map //TODO: Instead of analogous maps for time and cpu_time, use a single struct-valued map
std::map<std::string, long long> enter_cpu_times; std::map<std::string, int64_t> enter_cpu_times;
std::map<std::string, long long> last_cpu_times; std::map<std::string, int64_t> last_cpu_times;
std::map<std::pair<std::string, std::string>, long long> op_counts; std::map<std::pair<std::string, std::string>, int64_t> op_counts;
std::map<std::pair<std::string, std::string>, long long> cumulative_op_counts; // ((msg, data_point), value) std::map<std::pair<std::string, std::string>, int64_t> cumulative_op_counts; // ((msg, data_point), value)
// TODO: Convert op_counts and cumulative_op_counts from pair to structs // TODO: Convert op_counts and cumulative_op_counts from pair to structs
size_t indentation = 0; size_t indentation = 0;
std::vector<std::string> block_names; std::vector<std::string> block_names;
std::list<std::pair<std::string, long long*> > op_data_points = { std::list<std::pair<std::string, int64_t*> > op_data_points = {
#ifdef PROFILE_OP_COUNTS #ifdef PROFILE_OP_COUNTS
std::make_pair("Fradd", &Fr<default_ec_pp>::add_cnt), std::make_pair("Fradd", &Fr<default_ec_pp>::add_cnt),
std::make_pair("Frsub", &Fr<default_ec_pp>::sub_cnt), std::make_pair("Frsub", &Fr<default_ec_pp>::sub_cnt),
@@ -98,7 +115,7 @@ void clear_profiling_counters()
cumulative_times.clear(); cumulative_times.clear();
} }
void print_cumulative_time_entry(const std::string &key, const long long factor) void print_cumulative_time_entry(const std::string &key, const int64_t factor)
{ {
const double total_ms = (cumulative_times.at(key) * 1e-6); const double total_ms = (cumulative_times.at(key) * 1e-6);
const size_t cnt = invocation_counts.at(key); const size_t cnt = invocation_counts.at(key);
@@ -106,7 +123,7 @@ void print_cumulative_time_entry(const std::string &key, const long long factor)
printf(" %-45s: %12.5fms = %lld * %0.5fms (%zu invocations, %0.5fms = %lld * %0.5fms per invocation)\n", key.c_str(), total_ms, factor, total_ms/factor, cnt, avg_ms, factor, avg_ms/factor); printf(" %-45s: %12.5fms = %lld * %0.5fms (%zu invocations, %0.5fms = %lld * %0.5fms per invocation)\n", key.c_str(), total_ms, factor, total_ms/factor, cnt, avg_ms, factor, avg_ms/factor);
} }
void print_cumulative_times(const long long factor) void print_cumulative_times(const int64_t factor)
{ {
printf("Dumping times:\n"); printf("Dumping times:\n");
for (auto& kv : cumulative_times) for (auto& kv : cumulative_times)
@@ -155,7 +172,7 @@ void print_op_profiling(const std::string &msg)
printf("(opcounts) = ("); printf("(opcounts) = (");
bool first = true; bool first = true;
for (std::pair<std::string, long long*> p : op_data_points) for (std::pair<std::string, int64_t*> p : op_data_points)
{ {
if (!first) if (!first)
{ {
@@ -171,14 +188,14 @@ void print_op_profiling(const std::string &msg)
#endif #endif
} }
static void print_times_from_last_and_start(long long now, long long last, static void print_times_from_last_and_start(int64_t now, int64_t last,
long long cpu_now, long long cpu_last) int64_t cpu_now, int64_t cpu_last)
{ {
long long time_from_start = now - start_time; int64_t time_from_start = now - start_time;
long long time_from_last = now - last; int64_t time_from_last = now - last;
long long cpu_time_from_start = cpu_now - start_cpu_time; int64_t cpu_time_from_start = cpu_now - start_cpu_time;
long long cpu_time_from_last = cpu_now - cpu_last; int64_t cpu_time_from_last = cpu_now - cpu_last;
if (time_from_last != 0) { if (time_from_last != 0) {
double parallelism_from_last = 1.0 * cpu_time_from_last / time_from_last; double parallelism_from_last = 1.0 * cpu_time_from_last / time_from_last;
@@ -199,8 +216,8 @@ void print_time(const char* msg)
return; return;
} }
long long now = get_nsec_time(); int64_t now = get_nsec_time();
long long cpu_now = get_nsec_cpu_time(); int64_t cpu_now = get_nsec_cpu_time();
printf("%-35s\t", msg); printf("%-35s\t", msg);
print_times_from_last_and_start(now, last_time, cpu_now, last_cpu_time); print_times_from_last_and_start(now, last_time, cpu_now, last_cpu_time);
@@ -231,7 +248,7 @@ void print_indent()
void op_profiling_enter(const std::string &msg) void op_profiling_enter(const std::string &msg)
{ {
for (std::pair<std::string, long long*> p : op_data_points) for (std::pair<std::string, int64_t*> p : op_data_points)
{ {
op_counts[std::make_pair(msg, p.first)] = *(p.second); op_counts[std::make_pair(msg, p.first)] = *(p.second);
} }
@@ -245,9 +262,9 @@ void enter_block(const std::string &msg, const bool indent)
} }
block_names.emplace_back(msg); block_names.emplace_back(msg);
long long t = get_nsec_time(); int64_t t = get_nsec_time();
enter_times[msg] = t; enter_times[msg] = t;
long long cpu_t = get_nsec_cpu_time(); int64_t cpu_t = get_nsec_cpu_time();
enter_cpu_times[msg] = cpu_t; enter_cpu_times[msg] = cpu_t;
if (inhibit_profiling_info) if (inhibit_profiling_info)
@@ -288,15 +305,15 @@ void leave_block(const std::string &msg, const bool indent)
++invocation_counts[msg]; ++invocation_counts[msg];
long long t = get_nsec_time(); int64_t t = get_nsec_time();
last_times[msg] = (t - enter_times[msg]); last_times[msg] = (t - enter_times[msg]);
cumulative_times[msg] += (t - enter_times[msg]); cumulative_times[msg] += (t - enter_times[msg]);
long long cpu_t = get_nsec_cpu_time(); int64_t cpu_t = get_nsec_cpu_time();
last_cpu_times[msg] = (cpu_t - enter_cpu_times[msg]); last_cpu_times[msg] = (cpu_t - enter_cpu_times[msg]);
#ifdef PROFILE_OP_COUNTS #ifdef PROFILE_OP_COUNTS
for (std::pair<std::string, long long*> p : op_data_points) for (std::pair<std::string, int64_t*> p : op_data_points)
{ {
cumulative_op_counts[std::make_pair(msg, p.first)] += *(p.second)-op_counts[std::make_pair(msg, p.first)]; cumulative_op_counts[std::make_pair(msg, p.first)] += *(p.second)-op_counts[std::make_pair(msg, p.first)];
} }

View File

@@ -22,7 +22,7 @@
namespace libsnark { namespace libsnark {
void start_profiling(); void start_profiling();
long long get_nsec_time(); int64_t get_nsec_time();
void print_time(const char* msg); void print_time(const char* msg);
void print_header(const char* msg); void print_header(const char* msg);
@@ -31,13 +31,13 @@ void print_indent();
extern bool inhibit_profiling_info; extern bool inhibit_profiling_info;
extern bool inhibit_profiling_counters; extern bool inhibit_profiling_counters;
extern std::map<std::string, size_t> invocation_counts; extern std::map<std::string, size_t> invocation_counts;
extern std::map<std::string, long long> last_times; extern std::map<std::string, int64_t> last_times;
extern std::map<std::string, long long> cumulative_times; extern std::map<std::string, int64_t> cumulative_times;
void clear_profiling_counters(); void clear_profiling_counters();
void print_cumulative_time_entry(const std::string &key, const long long factor=1); void print_cumulative_time_entry(const std::string &key, const int64_t factor=1);
void print_cumulative_times(const long long factor=1); void print_cumulative_times(const int64_t factor=1);
void print_cumulative_op_counts(const bool only_fq=false); void print_cumulative_op_counts(const bool only_fq=false);
void enter_block(const std::string &msg, const bool indent=true); void enter_block(const std::string &msg, const bool indent=true);

View File

@@ -22,7 +22,7 @@ namespace libsnark {
/* /*
* @todo * @todo
* The serialization is fragile. Should be rewritten using a standard, portable-format * The serialization is fragile. Shoud be rewritten using a standard, portable-format
* library like boost::serialize. * library like boost::serialize.
* *
* However, for now the following conventions are used within the code. * However, for now the following conventions are used within the code.

View File

@@ -17,6 +17,7 @@
#include <cassert> #include <cassert>
#include <sstream> #include <sstream>
#include "common/utils.hpp" #include "common/utils.hpp"
#include "common/assert_except.hpp"
namespace libsnark { namespace libsnark {
@@ -69,7 +70,7 @@ T reserialize(const T &obj)
ss << obj; ss << obj;
T tmp; T tmp;
ss >> tmp; ss >> tmp;
assert(obj == tmp); assert_except(obj == tmp);
return tmp; return tmp;
} }

View File

@@ -15,11 +15,11 @@
namespace libsnark { namespace libsnark {
size_t log2(size_t n) uint64_t log2(uint64_t n)
/* returns ceil(log2(n)), so 1ul<<log2(n) is the smallest power of 2, /* returns ceil(log2(n)), so 1ul<<log2(n) is the smallest power of 2,
that is not less than n. */ that is not less than n. */
{ {
size_t r = ((n & (n-1)) == 0 ? 0 : 1); // add 1 if n is not power of 2 uint64_t r = ((n & (n-1)) == 0 ? 0 : 1); // add 1 if n is not power of 2
while (n > 1) while (n > 1)
{ {
@@ -30,10 +30,10 @@ size_t log2(size_t n)
return r; return r;
} }
size_t bitreverse(size_t n, const size_t l) uint64_t bitreverse(uint64_t n, const uint64_t l)
{ {
size_t r = 0; uint64_t r = 0;
for (size_t k = 0; k < l; ++k) for (uint64_t k = 0; k < l; ++k)
{ {
r = (r << 1) | (n & 1); r = (r << 1) | (n & 1);
n >>= 1; n >>= 1;
@@ -41,20 +41,20 @@ size_t bitreverse(size_t n, const size_t l)
return r; return r;
} }
bit_vector int_list_to_bits(const std::initializer_list<unsigned long> &l, const size_t wordsize) bit_vector int_list_to_bits(const std::initializer_list<uint64_t> &l, const size_t wordsize)
{ {
bit_vector res(wordsize*l.size()); bit_vector res(wordsize*l.size());
for (size_t i = 0; i < l.size(); ++i) for (uint64_t i = 0; i < l.size(); ++i)
{ {
for (size_t j = 0; j < wordsize; ++j) for (uint64_t j = 0; j < wordsize; ++j)
{ {
res[i*wordsize + j] = (*(l.begin()+i) & (1ul<<(wordsize-1-j))); res[i*wordsize + j] = (*(l.begin()+i) & (UINT64_C(1)<<(wordsize-1-j)));
} }
} }
return res; return res;
} }
long long div_ceil(long long x, long long y) int64_t div_ceil(int64_t x, int64_t y)
{ {
return (x + (y-1)) / y; return (x + (y-1)) / y;
} }
@@ -68,7 +68,7 @@ bool is_little_endian()
std::string FORMAT(const std::string &prefix, const char* format, ...) std::string FORMAT(const std::string &prefix, const char* format, ...)
{ {
const static size_t MAX_FMT = 256; const static uint64_t MAX_FMT = 256;
char buf[MAX_FMT]; char buf[MAX_FMT];
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@@ -81,7 +81,7 @@ std::string FORMAT(const std::string &prefix, const char* format, ...)
void serialize_bit_vector(std::ostream &out, const bit_vector &v) void serialize_bit_vector(std::ostream &out, const bit_vector &v)
{ {
out << v.size() << "\n"; out << v.size() << "\n";
for (size_t i = 0; i < v.size(); ++i) for (uint64_t i = 0; i < v.size(); ++i)
{ {
out << v[i] << "\n"; out << v[i] << "\n";
} }
@@ -89,10 +89,10 @@ void serialize_bit_vector(std::ostream &out, const bit_vector &v)
void deserialize_bit_vector(std::istream &in, bit_vector &v) void deserialize_bit_vector(std::istream &in, bit_vector &v)
{ {
size_t size; uint64_t size;
in >> size; in >> size;
v.resize(size); v.resize(size);
for (size_t i = 0; i < size; ++i) for (uint64_t i = 0; i < size; ++i)
{ {
bool b; bool b;
in >> b; in >> b;

View File

@@ -21,13 +21,13 @@ namespace libsnark {
typedef std::vector<bool> bit_vector; typedef std::vector<bool> bit_vector;
/// returns ceil(log2(n)), so 1ul<<log2(n) is the smallest power of 2, that is not less than n /// returns ceil(log2(n)), so 1ul<<log2(n) is the smallest power of 2, that is not less than n
size_t log2(size_t n); uint64_t log2(uint64_t n);
inline size_t exp2(size_t k) { return 1ul << k; } inline uint64_t exp2(uint64_t k) { return 1ull << k; }
size_t bitreverse(size_t n, const size_t l); uint64_t bitreverse(uint64_t n, const uint64_t l);
bit_vector int_list_to_bits(const std::initializer_list<unsigned long> &l, const size_t wordsize); bit_vector int_list_to_bits(const std::initializer_list<uint64_t> &l, const uint64_t wordsize);
long long div_ceil(long long x, long long y); int64_t div_ceil(int64_t x, int64_t y);
bool is_little_endian(); bool is_little_endian();
@@ -46,8 +46,13 @@ void UNUSED(Types&&...) {}
void serialize_bit_vector(std::ostream &out, const bit_vector &v); void serialize_bit_vector(std::ostream &out, const bit_vector &v);
void deserialize_bit_vector(std::istream &in, bit_vector &v); void deserialize_bit_vector(std::istream &in, bit_vector &v);
#ifdef __APPLE__
template<typename T> template<typename T>
size_t size_in_bits(const std::vector<T> &v); unsigned long size_in_bits(const std::vector<T> &v);
#else
template<typename T>
uint64_t size_in_bits(const std::vector<T> &v);
#endif
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))

View File

@@ -12,11 +12,19 @@
namespace libsnark { namespace libsnark {
#ifdef __APPLE__
template<typename T>
unsigned long size_in_bits(const std::vector<T> &v)
{
return v.size() * T::size_in_bits();
}
#else
template<typename T> template<typename T>
size_t size_in_bits(const std::vector<T> &v) size_t size_in_bits(const std::vector<T> &v)
{ {
return v.size() * T::size_in_bits(); return v.size() * T::size_in_bits();
} }
#endif
} // libsnark } // libsnark

View File

@@ -275,11 +275,11 @@ void test_disjunction_gadget(const size_t n)
disjunction_gadget<FieldT> d(pb, inputs, output, "d"); disjunction_gadget<FieldT> d(pb, inputs, output, "d");
d.generate_r1cs_constraints(); d.generate_r1cs_constraints();
for (size_t w = 0; w < 1ul<<n; ++w) for (size_t w = 0; w < UINT64_C(1)<<n; ++w)
{ {
for (size_t j = 0; j < n; ++j) for (size_t j = 0; j < n; ++j)
{ {
pb.val(inputs[j]) = FieldT((w & (1ul<<j)) ? 1 : 0); pb.val(inputs[j]) = FieldT((w & (UINT64_C(1)<<j)) ? 1 : 0);
} }
d.generate_r1cs_witness(); d.generate_r1cs_witness();
@@ -366,11 +366,11 @@ void test_conjunction_gadget(const size_t n)
conjunction_gadget<FieldT> c(pb, inputs, output, "c"); conjunction_gadget<FieldT> c(pb, inputs, output, "c");
c.generate_r1cs_constraints(); c.generate_r1cs_constraints();
for (size_t w = 0; w < 1ul<<n; ++w) for (size_t w = 0; w < UINT64_C(1)<<n; ++w)
{ {
for (size_t j = 0; j < n; ++j) for (size_t j = 0; j < n; ++j)
{ {
pb.val(inputs[j]) = (w & (1ul<<j)) ? FieldT::one() : FieldT::zero(); pb.val(inputs[j]) = (w & (UINT64_C(1)<<j)) ? FieldT::one() : FieldT::zero();
} }
c.generate_r1cs_witness(); c.generate_r1cs_witness();
@@ -378,13 +378,13 @@ void test_conjunction_gadget(const size_t n)
#ifdef DEBUG #ifdef DEBUG
printf("positive test for %zu\n", w); printf("positive test for %zu\n", w);
#endif #endif
assert(pb.val(output) == (w == (1ul<<n) - 1 ? FieldT::one() : FieldT::zero())); assert(pb.val(output) == (w == (UINT64_C(1)<<n) - 1 ? FieldT::one() : FieldT::zero()));
assert(pb.is_satisfied()); assert(pb.is_satisfied());
#ifdef DEBUG #ifdef DEBUG
printf("negative test for %zu\n", w); printf("negative test for %zu\n", w);
#endif #endif
pb.val(output) = (w == (1ul<<n) - 1 ? FieldT::zero() : FieldT::one()); pb.val(output) = (w == (UINT64_C(1)<<n) - 1 ? FieldT::zero() : FieldT::one());
assert(!pb.is_satisfied()); assert(!pb.is_satisfied());
} }
@@ -454,9 +454,9 @@ void test_comparison_gadget(const size_t n)
comparison_gadget<FieldT> cmp(pb, n, A, B, less, less_or_eq, "cmp"); comparison_gadget<FieldT> cmp(pb, n, A, B, less, less_or_eq, "cmp");
cmp.generate_r1cs_constraints(); cmp.generate_r1cs_constraints();
for (size_t a = 0; a < 1ul<<n; ++a) for (size_t a = 0; a < UINT64_C(1)<<n; ++a)
{ {
for (size_t b = 0; b < 1ul<<n; ++b) for (size_t b = 0; b < UINT64_C(1)<<n; ++b)
{ {
pb.val(A) = FieldT(a); pb.val(A) = FieldT(a);
pb.val(B) = FieldT(b); pb.val(B) = FieldT(b);
@@ -523,16 +523,16 @@ void test_inner_product_gadget(const size_t n)
inner_product_gadget<FieldT> g(pb, A, B, result, "g"); inner_product_gadget<FieldT> g(pb, A, B, result, "g");
g.generate_r1cs_constraints(); g.generate_r1cs_constraints();
for (size_t i = 0; i < 1ul<<n; ++i) for (size_t i = 0; i < UINT64_C(1)<<n; ++i)
{ {
for (size_t j = 0; j < 1ul<<n; ++j) for (size_t j = 0; j < UINT64_C(1)<<n; ++j)
{ {
size_t correct = 0; size_t correct = 0;
for (size_t k = 0; k < n; ++k) for (size_t k = 0; k < n; ++k)
{ {
pb.val(A[k]) = (i & (1ul<<k) ? FieldT::one() : FieldT::zero()); pb.val(A[k]) = (i & (UINT64_C(1)<<k) ? FieldT::one() : FieldT::zero());
pb.val(B[k]) = (j & (1ul<<k) ? FieldT::one() : FieldT::zero()); pb.val(B[k]) = (j & (UINT64_C(1)<<k) ? FieldT::one() : FieldT::zero());
correct += ((i & (1ul<<k)) && (j & (1ul<<k)) ? 1 : 0); correct += ((i & (UINT64_C(1)<<k)) && (j & (UINT64_C(1)<<k)) ? 1 : 0);
} }
g.generate_r1cs_witness(); g.generate_r1cs_witness();
@@ -587,7 +587,7 @@ void loose_multiplexing_gadget<FieldT>::generate_r1cs_witness()
{ {
/* assumes that idx can be fit in ulong; true for our purposes for now */ /* assumes that idx can be fit in ulong; true for our purposes for now */
const bigint<FieldT::num_limbs> valint = this->pb.val(index).as_bigint(); const bigint<FieldT::num_limbs> valint = this->pb.val(index).as_bigint();
unsigned long idx = valint.as_ulong(); uint64_t idx = valint.as_ulong();
const bigint<FieldT::num_limbs> arrsize(arr.size()); const bigint<FieldT::num_limbs> arrsize(arr.size());
if (idx >= arr.size() || mpn_cmp(valint.data, arrsize.data, FieldT::num_limbs) >= 0) if (idx >= arr.size() || mpn_cmp(valint.data, arrsize.data, FieldT::num_limbs) >= 0)
@@ -619,7 +619,7 @@ void test_loose_multiplexing_gadget(const size_t n)
protoboard<FieldT> pb; protoboard<FieldT> pb;
pb_variable_array<FieldT> arr; pb_variable_array<FieldT> arr;
arr.allocate(pb, 1ul<<n, "arr"); arr.allocate(pb, UINT64_C(1)<<n, "arr");
pb_variable<FieldT> index, result, success_flag; pb_variable<FieldT> index, result, success_flag;
index.allocate(pb, "index"); index.allocate(pb, "index");
result.allocate(pb, "result"); result.allocate(pb, "result");
@@ -628,20 +628,20 @@ void test_loose_multiplexing_gadget(const size_t n)
loose_multiplexing_gadget<FieldT> g(pb, arr, index, result, success_flag, "g"); loose_multiplexing_gadget<FieldT> g(pb, arr, index, result, success_flag, "g");
g.generate_r1cs_constraints(); g.generate_r1cs_constraints();
for (size_t i = 0; i < 1ul<<n; ++i) for (size_t i = 0; i < UINT64_C(1)<<n; ++i)
{ {
pb.val(arr[i]) = FieldT((19*i) % (1ul<<n)); pb.val(arr[i]) = FieldT((19*i) % (UINT64_C(1)<<n));
} }
for (int idx = -1; idx <= (int)(1ul<<n); ++idx) for (int idx = -1; idx <= (int)(UINT64_C(1)<<n); ++idx)
{ {
pb.val(index) = FieldT(idx); pb.val(index) = FieldT(idx);
g.generate_r1cs_witness(); g.generate_r1cs_witness();
if (0 <= idx && idx <= (int)(1ul<<n) - 1) if (0 <= idx && idx <= (int)(UINT64_C(1)<<n) - 1)
{ {
printf("demuxing element %d (in bounds)\n", idx); printf("demuxing element %d (in bounds)\n", idx);
assert(pb.val(result) == FieldT((19*idx) % (1ul<<n))); assert(pb.val(result) == FieldT((19*idx) % (UINT64_C(1)<<n)));
assert(pb.val(success_flag) == FieldT::one()); assert(pb.val(success_flag) == FieldT::one());
assert(pb.is_satisfied()); assert(pb.is_satisfied());
pb.val(result) -= FieldT::one(); pb.val(result) -= FieldT::one();

View File

@@ -285,7 +285,7 @@ void majority_gadget<FieldT>::generate_r1cs_witness()
{ {
for (size_t i = 0; i < 32; ++i) for (size_t i = 0; i < 32; ++i)
{ {
const long v = (this->pb.lc_val(X[i]) + this->pb.lc_val(Y[i]) + this->pb.lc_val(Z[i])).as_ulong(); const int64_t v = (this->pb.lc_val(X[i]) + this->pb.lc_val(Y[i]) + this->pb.lc_val(Z[i])).as_ulong();
this->pb.val(result_bits[i]) = FieldT(v / 2); this->pb.val(result_bits[i]) = FieldT(v / 2);
} }

View File

@@ -78,7 +78,7 @@ public:
pb_linear_combination_array<FieldT> g; pb_linear_combination_array<FieldT> g;
pb_linear_combination_array<FieldT> h; pb_linear_combination_array<FieldT> h;
pb_variable<FieldT> W; pb_variable<FieldT> W;
long K; int64_t K;
pb_linear_combination_array<FieldT> new_a; pb_linear_combination_array<FieldT> new_a;
pb_linear_combination_array<FieldT> new_e; pb_linear_combination_array<FieldT> new_e;
@@ -92,7 +92,7 @@ public:
const pb_linear_combination_array<FieldT> &g, const pb_linear_combination_array<FieldT> &g,
const pb_linear_combination_array<FieldT> &h, const pb_linear_combination_array<FieldT> &h,
const pb_variable<FieldT> &W, const pb_variable<FieldT> &W,
const long &K, const int64_t &K,
const pb_linear_combination_array<FieldT> &new_a, const pb_linear_combination_array<FieldT> &new_a,
const pb_linear_combination_array<FieldT> &new_e, const pb_linear_combination_array<FieldT> &new_e,
const std::string &annotation_prefix); const std::string &annotation_prefix);

View File

@@ -16,7 +16,7 @@
namespace libsnark { namespace libsnark {
const unsigned long SHA256_K[64] = { const uint64_t SHA256_K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
@@ -27,7 +27,7 @@ const unsigned long SHA256_K[64] = {
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
}; };
const unsigned long SHA256_H[8] = { const uint64_t SHA256_H[8] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
}; };
@@ -149,7 +149,7 @@ sha256_round_function_gadget<FieldT>::sha256_round_function_gadget(protoboard<Fi
const pb_linear_combination_array<FieldT> &g, const pb_linear_combination_array<FieldT> &g,
const pb_linear_combination_array<FieldT> &h, const pb_linear_combination_array<FieldT> &h,
const pb_variable<FieldT> &W, const pb_variable<FieldT> &W,
const long &K, const int64_t &K,
const pb_linear_combination_array<FieldT> &new_a, const pb_linear_combination_array<FieldT> &new_a,
const pb_linear_combination_array<FieldT> &new_e, const pb_linear_combination_array<FieldT> &new_e,
const std::string &annotation_prefix) : const std::string &annotation_prefix) :

View File

@@ -10,8 +10,6 @@
#include "common/profiling.hpp" #include "common/profiling.hpp"
#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" #include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp"
#include <gtest/gtest.h>
using namespace libsnark; using namespace libsnark;
template<typename FieldT> template<typename FieldT>
@@ -37,10 +35,10 @@ void test_two_to_one()
f.generate_r1cs_witness(); f.generate_r1cs_witness();
output.generate_r1cs_witness(hash_bv); output.generate_r1cs_witness(hash_bv);
EXPECT_TRUE(pb.is_satisfied()); assert(pb.is_satisfied());
} }
TEST(gadgetlib1, sha256) int main(void)
{ {
start_profiling(); start_profiling();
default_ec_pp::init_public_params(); default_ec_pp::init_public_params();

View File

@@ -41,7 +41,7 @@ void merkle_authentication_path_variable<FieldT, HashT>::generate_r1cs_witness(c
for (size_t i = 0; i < tree_depth; ++i) for (size_t i = 0; i < tree_depth; ++i)
{ {
if (address & (1ul << (tree_depth-1-i))) if (address & (UINT64_C(1) << (tree_depth-1-i)))
{ {
left_digests[i].generate_r1cs_witness(path[i]); left_digests[i].generate_r1cs_witness(path[i]);
} }
@@ -58,7 +58,7 @@ merkle_authentication_path merkle_authentication_path_variable<FieldT, HashT>::g
merkle_authentication_path result; merkle_authentication_path result;
for (size_t i = 0; i < tree_depth; ++i) for (size_t i = 0; i < tree_depth; ++i)
{ {
if (address & (1ul << (tree_depth-1-i))) if (address & (UINT64_C(1) << (tree_depth-1-i)))
{ {
result.emplace_back(left_digests[i].get_digest()); result.emplace_back(left_digests[i].get_digest());
} }

View File

@@ -144,10 +144,10 @@ void test_merkle_tree_check_read_gadget()
bit_vector address_bits; bit_vector address_bits;
size_t address = 0; size_t address = 0;
for (long level = tree_depth-1; level >= 0; --level) for (int64_t level = tree_depth-1; level >= 0; --level)
{ {
const bool computed_is_right = (std::rand() % 2); const bool computed_is_right = (std::rand() % 2);
address |= (computed_is_right ? 1ul << (tree_depth-1-level) : 0); address |= (computed_is_right ? UINT64_C(1) << (tree_depth-1-level) : 0);
address_bits.push_back(computed_is_right); address_bits.push_back(computed_is_right);
bit_vector other(digest_len); bit_vector other(digest_len);
std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; });

View File

@@ -19,6 +19,7 @@
#include "common/data_structures/merkle_tree.hpp" #include "common/data_structures/merkle_tree.hpp"
#include "gadgetlib1/gadget.hpp" #include "gadgetlib1/gadget.hpp"
#include "gadgetlib1/gadgets/hashes/crh_gadget.hpp"
#include "gadgetlib1/gadgets/hashes/hash_io.hpp" #include "gadgetlib1/gadgets/hashes/hash_io.hpp"
#include "gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp" #include "gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp"
#include "gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp" #include "gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp"

View File

@@ -197,10 +197,10 @@ void test_merkle_tree_check_update_gadget()
bit_vector address_bits; bit_vector address_bits;
size_t address = 0; size_t address = 0;
for (long level = tree_depth-1; level >= 0; --level) for (int64_t level = tree_depth-1; level >= 0; --level)
{ {
const bool computed_is_right = (std::rand() % 2); const bool computed_is_right = (std::rand() % 2);
address |= (computed_is_right ? 1ul << (tree_depth-1-level) : 0); address |= (computed_is_right ? UINT64_C(1) << (tree_depth-1-level) : 0);
address_bits.push_back(computed_is_right); address_bits.push_back(computed_is_right);
bit_vector other(digest_len); bit_vector other(digest_len);
std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; });

View File

@@ -5,36 +5,44 @@
* @copyright MIT license (see LICENSE file) * @copyright MIT license (see LICENSE file)
*****************************************************************************/ *****************************************************************************/
#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp"
#ifdef CURVE_BN128 #ifdef CURVE_BN128
#include "algebra/curves/bn128/bn128_pp.hpp" #include "algebra/curves/bn128/bn128_pp.hpp"
#endif #endif
#include "algebra/curves/edwards/edwards_pp.hpp"
#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp"
#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp"
#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp" #include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp"
#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp" #include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp"
#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" #include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp"
#include <gtest/gtest.h>
using namespace libsnark; using namespace libsnark;
template<typename ppT> template<typename ppT>
void test_all_merkle_tree_gadgets() void test_all_merkle_tree_gadgets()
{ {
typedef Fr<ppT> FieldT; typedef Fr<ppT> FieldT;
test_merkle_tree_check_read_gadget<FieldT, CRH_with_bit_out_gadget<FieldT> >();
test_merkle_tree_check_read_gadget<FieldT, sha256_two_to_one_hash_gadget<FieldT> >(); test_merkle_tree_check_read_gadget<FieldT, sha256_two_to_one_hash_gadget<FieldT> >();
test_merkle_tree_check_update_gadget<FieldT, CRH_with_bit_out_gadget<FieldT> >();
test_merkle_tree_check_update_gadget<FieldT, sha256_two_to_one_hash_gadget<FieldT> >(); test_merkle_tree_check_update_gadget<FieldT, sha256_two_to_one_hash_gadget<FieldT> >();
} }
TEST(gadgetlib1, merkle_tree) int main(void)
{ {
start_profiling(); start_profiling();
alt_bn128_pp::init_public_params();
test_all_merkle_tree_gadgets<alt_bn128_pp>();
#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled #ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled
bn128_pp::init_public_params(); bn128_pp::init_public_params();
test_all_merkle_tree_gadgets<bn128_pp>(); test_all_merkle_tree_gadgets<bn128_pp>();
#endif #endif
edwards_pp::init_public_params();
test_all_merkle_tree_gadgets<edwards_pp>();
mnt4_pp::init_public_params();
test_all_merkle_tree_gadgets<mnt4_pp>();
mnt6_pp::init_public_params();
test_all_merkle_tree_gadgets<mnt6_pp>();
} }

View File

@@ -59,7 +59,7 @@ public:
void fill_with_field_elements(protoboard<FieldT> &pb, const std::vector<FieldT>& vals) const; void fill_with_field_elements(protoboard<FieldT> &pb, const std::vector<FieldT>& vals) const;
void fill_with_bits(protoboard<FieldT> &pb, const bit_vector& bits) const; void fill_with_bits(protoboard<FieldT> &pb, const bit_vector& bits) const;
void fill_with_bits_of_ulong(protoboard<FieldT> &pb, const unsigned long i) const; void fill_with_bits_of_ulong(protoboard<FieldT> &pb, const uint64_t i) const;
void fill_with_bits_of_field_element(protoboard<FieldT> &pb, const FieldT &r) const; void fill_with_bits_of_field_element(protoboard<FieldT> &pb, const FieldT &r) const;
std::vector<FieldT> get_vals(const protoboard<FieldT> &pb) const; std::vector<FieldT> get_vals(const protoboard<FieldT> &pb) const;
@@ -120,7 +120,7 @@ public:
void fill_with_field_elements(protoboard<FieldT> &pb, const std::vector<FieldT>& vals) const; void fill_with_field_elements(protoboard<FieldT> &pb, const std::vector<FieldT>& vals) const;
void fill_with_bits(protoboard<FieldT> &pb, const bit_vector& bits) const; void fill_with_bits(protoboard<FieldT> &pb, const bit_vector& bits) const;
void fill_with_bits_of_ulong(protoboard<FieldT> &pb, const unsigned long i) const; void fill_with_bits_of_ulong(protoboard<FieldT> &pb, const uint64_t i) const;
void fill_with_bits_of_field_element(protoboard<FieldT> &pb, const FieldT &r) const; void fill_with_bits_of_field_element(protoboard<FieldT> &pb, const FieldT &r) const;
std::vector<FieldT> get_vals(const protoboard<FieldT> &pb) const; std::vector<FieldT> get_vals(const protoboard<FieldT> &pb) const;

View File

@@ -65,7 +65,7 @@ void pb_variable_array<FieldT>::fill_with_bits_of_field_element(protoboard<Field
} }
template<typename FieldT> template<typename FieldT>
void pb_variable_array<FieldT>::fill_with_bits_of_ulong(protoboard<FieldT> &pb, const unsigned long i) const void pb_variable_array<FieldT>::fill_with_bits_of_ulong(protoboard<FieldT> &pb, const uint64_t i) const
{ {
this->fill_with_bits_of_field_element(pb, FieldT(i, true)); this->fill_with_bits_of_field_element(pb, FieldT(i, true));
} }
@@ -232,7 +232,7 @@ void pb_linear_combination_array<FieldT>::fill_with_bits_of_field_element(protob
} }
template<typename FieldT> template<typename FieldT>
void pb_linear_combination_array<FieldT>::fill_with_bits_of_ulong(protoboard<FieldT> &pb, const unsigned long i) const void pb_linear_combination_array<FieldT>::fill_with_bits_of_ulong(protoboard<FieldT> &pb, const uint64_t i) const
{ {
this->fill_with_bits_of_field_element(pb, FieldT(i)); this->fill_with_bits_of_field_element(pb, FieldT(i));
} }

View File

@@ -4,7 +4,7 @@
Declaration of interfaces for a R1CS-to-QAP reduction, that is, constructing Declaration of interfaces for a R1CS-to-QAP reduction, that is, constructing
a QAP ("Quadratic Arithmetic Program") from a R1CS ("Rank-1 Constraint System"). a QAP ("Quadratic Arithmetic Program") from a R1CS ("Rank-1 Constraint System").
QAPs are defined in \[GGPR13], and constructed for R1CS also in \[GGPR13]. QAPs are defined in \[GGPR13], and construced for R1CS also in \[GGPR13].
The implementation of the reduction follows, extends, and optimizes The implementation of the reduction follows, extends, and optimizes
the efficient approach described in Appendix E of \[BCGTV13]. the efficient approach described in Appendix E of \[BCGTV13].

View File

@@ -10,15 +10,13 @@
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" #include "algebra/curves/mnt/mnt6/mnt6_pp.hpp"
#include "algebra/fields/field_utils.hpp" #include "algebra/fields/field_utils.hpp"
#include "common/profiling.hpp" #include "common/profiling.hpp"
#include "common/utils.hpp" #include "common/utils.hpp"
#include "reductions/r1cs_to_qap/r1cs_to_qap.hpp" #include "reductions/r1cs_to_qap/r1cs_to_qap.hpp"
#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" #include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp"
#include <gtest/gtest.h>
using namespace libsnark; using namespace libsnark;
template<typename FieldT> template<typename FieldT>
@@ -30,7 +28,7 @@ void test_qap(const size_t qap_degree, const size_t num_inputs, const bool binar
See the transformation from R1CS to QAP for why this is the case. See the transformation from R1CS to QAP for why this is the case.
So we need that qap_degree >= num_inputs + 1. So we need that qap_degree >= num_inputs + 1.
*/ */
ASSERT_LE(num_inputs + 1, qap_degree); assert(num_inputs + 1 <= qap_degree);
enter_block("Call to test_qap"); enter_block("Call to test_qap");
const size_t num_constraints = qap_degree - num_inputs - 1; const size_t num_constraints = qap_degree - num_inputs - 1;
@@ -53,7 +51,7 @@ void test_qap(const size_t qap_degree, const size_t num_inputs, const bool binar
leave_block("Generate constraint system and assignment"); leave_block("Generate constraint system and assignment");
enter_block("Check satisfiability of constraint system"); enter_block("Check satisfiability of constraint system");
EXPECT_TRUE(example.constraint_system.is_satisfied(example.primary_input, example.auxiliary_input)); assert(example.constraint_system.is_satisfied(example.primary_input, example.auxiliary_input));
leave_block("Check satisfiability of constraint system"); leave_block("Check satisfiability of constraint system");
const FieldT t = FieldT::random_element(), const FieldT t = FieldT::random_element(),
@@ -74,31 +72,44 @@ void test_qap(const size_t qap_degree, const size_t num_inputs, const bool binar
leave_block("Compute QAP witness"); leave_block("Compute QAP witness");
enter_block("Check satisfiability of QAP instance 1"); enter_block("Check satisfiability of QAP instance 1");
EXPECT_TRUE(qap_inst_1.is_satisfied(qap_wit)); assert(qap_inst_1.is_satisfied(qap_wit));
leave_block("Check satisfiability of QAP instance 1"); leave_block("Check satisfiability of QAP instance 1");
enter_block("Check satisfiability of QAP instance 2"); enter_block("Check satisfiability of QAP instance 2");
EXPECT_TRUE(qap_inst_2.is_satisfied(qap_wit)); assert(qap_inst_2.is_satisfied(qap_wit));
leave_block("Check satisfiability of QAP instance 2"); leave_block("Check satisfiability of QAP instance 2");
leave_block("Call to test_qap"); leave_block("Call to test_qap");
} }
TEST(relations, qap) int main()
{ {
start_profiling(); start_profiling();
mnt6_pp::init_public_params();
const size_t num_inputs = 10; const size_t num_inputs = 10;
const size_t basic_domain_size = UINT64_C(1)<<mnt6_Fr::s;
const size_t step_domain_size = (UINT64_C(1)<<10) + (UINT64_C(1)<<8);
const size_t extended_domain_size = UINT64_C(1)<<(mnt6_Fr::s+1);
const size_t extended_domain_size_special = extended_domain_size-1;
enter_block("Test QAP with binary input"); enter_block("Test QAP with binary input");
test_qap<Fr<alt_bn128_pp> >(1ul << 21, num_inputs, true); test_qap<Fr<mnt6_pp> >(basic_domain_size, num_inputs, true);
test_qap<Fr<mnt6_pp> >(step_domain_size, num_inputs, true);
test_qap<Fr<mnt6_pp> >(extended_domain_size, num_inputs, true);
test_qap<Fr<mnt6_pp> >(extended_domain_size_special, num_inputs, true);
leave_block("Test QAP with binary input"); leave_block("Test QAP with binary input");
enter_block("Test QAP with field input"); enter_block("Test QAP with field input");
test_qap<Fr<alt_bn128_pp> >(1ul << 21, num_inputs, false); test_qap<Fr<mnt6_pp> >(basic_domain_size, num_inputs, false);
test_qap<Fr<mnt6_pp> >(step_domain_size, num_inputs, false);
test_qap<Fr<mnt6_pp> >(extended_domain_size, num_inputs, false);
test_qap<Fr<mnt6_pp> >(extended_domain_size_special, num_inputs, false);
leave_block("Test QAP with field input"); leave_block("Test QAP with field input");
} }

Some files were not shown because too many files have changed in this diff Show More