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)
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)
if TARGET_DARWIN
@@ -156,8 +156,8 @@ $(BITCOIND_BIN): FORCE
$(BITCOIN_CLI_BIN): FORCE
$(MAKE) -C src $(@F)
$(WALLET_UTILITY_BIN): FORCE
$(MAKE) -C src $(@F)
#$(WALLET_UTILITY_BIN): FORCE
# $(MAKE) -C src $(@F)
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([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]])
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])
AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes])

View File

@@ -14,7 +14,8 @@ endif
ifeq ($(build_os),darwin)
$(package)_install=ginstall
define $(package)_build_cmds
$(MAKE) -C make gtest.a
$(MAKE) -C googlemock/make gmock.a && \
$(MAKE) -C googletest/make gtest.a
endef
else
$(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
#<<<<<<< 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)_download_path=https://download.libsodium.org/libsodium/releases/
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4
#>>>>>>> zcash/master
$(package)_dependencies=
$(package)_config_opts=
endif
define $(package)_preprocess_cmds
cd $($(package)_build_subdir); ./autogen.sh

View File

@@ -1,6 +1,6 @@
package=proton
$(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)_sha256_hash=6ffd26d3d0e495bfdb5d9fefc5349954e6105ea18cc4bb191161d27742c5a01a
$(package)_patches=minimal-build.patch
@@ -21,4 +21,3 @@ endef
define $(package)_stage_cmds
cd build; $(MAKE) VERBOSE=1 DESTDIR=$($(package)_staging_prefix_dir) install
endef

View File

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

View File

@@ -100,9 +100,9 @@ bin_PROGRAMS =
noinst_PROGRAMS =
TESTS =
if BUILD_BITCOIND
#if BUILD_BITCOIND
bin_PROGRAMS += komodod
endif
#endif
if BUILD_BITCOIN_UTILS
bin_PROGRAMS += komodo-cli komodo-tx
@@ -111,6 +111,7 @@ if ENABLE_WALLET
bin_PROGRAMS += wallet-utility
endif
LIBZCASH_H = \
zcash/IncrementalMerkleTree.hpp \
zcash/NoteEncryption.hpp \

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);
#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)))
{
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
#if __linux
#include <sys/syscall.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif
#include <unistd.h>
#include <pthread.h>

View File

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

View File

@@ -1442,7 +1442,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
break;
}
KOMODO_LOADINGBLOCKS = 0;
// Check for changed -txindex state
if (fTxIndex != GetBoolArg("-txindex", true)) {
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 *
* 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_gateway.h"
#include "komodo_events.h"
#include "komodo_ccdata.h"
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 )
{
portable_mutex_init(&KOMODO_KV_mutex);
portable_mutex_init(&KOMODO_CC_mutex);
didinit = 1;
}
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)
{
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 )
return(-1);
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 )
{
struct komodo_ccdata ccdata; struct komodo_ccdataMoMoM MoMoMdata;
int32_t validated = 0,nameoffset,opoffset = 0;
if ( (opretlen= scriptbuf[len++]) == 0x4c )
opretlen = scriptbuf[len++];
else if ( opretlen == 0x4d )
@@ -562,61 +591,112 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
opretlen = scriptbuf[len++];
opretlen += (scriptbuf[len++] << 8);
}
if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
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]);
if ( j == 1 && opretlen >= 32*2+4 && strcmp(ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 )
opoffset = len;
matched = 0;
if ( ASSETCHAINS_SYMBOL[0] == 0 )
{
len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&srchash);
len += iguana_rwnum(0,&scriptbuf[len],sizeof(*notarizedheightp),(uint8_t *)notarizedheightp);
len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid);
if ( strcmp("PIZZA",ASSETCHAINS_SYMBOL) == 0 && opretlen == 110 )
{
notarized = 1;
}
static int32_t last_rewind;
int32_t rewindtarget,validated = 0;
CBlockIndex *pindex;//
if ( IsInitialBlockDownload() == 0 && ((pindex= mapBlockIndex[srchash]) == 0 || pindex->nHeight != *notarizedheightp) )
{
if ( sp->NOTARIZED_HEIGHT > 0 && sp->NOTARIZED_HEIGHT < *notarizedheightp )
rewindtarget = sp->NOTARIZED_HEIGHT - 1;
else if ( *notarizedheightp > 101 )
rewindtarget = *notarizedheightp - 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,*notarizedheightp,srchash.ToString().c_str(),sp->NOTARIZED_HEIGHT,rewindtarget);
}
last_rewind = rewindtarget;
}
} 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));
sp->MoMdepth = 0;
if ( strcmp("KMD",(char *)&scriptbuf[len+32 * 2 + 4]) == 0 )
matched = 1;
}
else
{
//printf("VALID %s MoM.%s [%d]\n",ASSETCHAINS_SYMBOL,sp->MoM.ToString().c_str(),sp->MoMdepth);
if ( strcmp(ASSETCHAINS_SYMBOL,(char *)&scriptbuf[len+32*2+4]) == 0 )
matched = 1;
}
}
komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth);
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_rwnum(0,&scriptbuf[len],sizeof(*notarizedheightp),(uint8_t *)notarizedheightp);
if ( matched != 0 )
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 )
{
//sp->NOTARIZED_HEIGHT = *notarizedheightp;
//sp->NOTARIZED_HASH = srchash;
//sp->NOTARIZED_DESTTXID = desttxid;
memset(&MoM,0,sizeof(MoM));
MoMdepth = 0;
len += nameoffset;
ccdata.MoMdata.notarized_height = *notarizedheightp;
ccdata.MoMdata.height = height;
ccdata.MoMdata.txi = i;
//printf("nameoffset.%d len.%d + 36 %d vs opretlen.%d\n",nameoffset,len,len+36,opretlen);
if ( len+36-opoffset <= opretlen )
{
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 )
{
len += iguana_rwnum(0,&scriptbuf[len],sizeof(ccdata.CCid),(uint8_t *)&ccdata.CCid);
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;
}
}
if ( MoM == zero || MoMdepth > 1440 || MoMdepth < 0 )
{
memset(&MoM,0,sizeof(MoM));
MoMdepth = 0;
}
else
{
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));
}
else if ( ASSETCHAINS_SYMBOL[0] == 0 && matched != 0 && notarized != 0 && validated != 0 )
komodo_rwccdata((char *)"KMD",1,&ccdata,0);
if ( matched != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height )
{
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 )
@@ -643,15 +723,16 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr
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 )
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);
}
else if ( i == 0 && j == 1 && opretlen == 149 )
} else if ( opretlen != 149 && height > 600000 && matched != 0 )
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 ( matched != 0 && i == 0 && j == 1 && opretlen == 149 )
{
if ( notaryid >= 0 && notaryid < 64 )
komodo_paxpricefeed(height,&scriptbuf[len],opretlen);
}
else
else if ( matched != 0 )
{
//int32_t k; for (k=0; k<scriptlen; k++)
// printf("%02x",scriptbuf[k]);
@@ -726,7 +807,11 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block)
else
{
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);
komodo_purge_ccdata((int32_t)pindex->nHeight);
hwmheight = 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);
}

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);
}
int32_t komodo_is_notarytx(const CTransaction& tx)
{
uint8_t *ptr; static uint8_t crypto777[33];
@@ -836,18 +835,33 @@ int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t blo
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;
for (i=0; i<width; i++,n++)
int32_t i,j,n,nonz,numnotaries; CBlock block; CBlockIndex *pindex; uint8_t notarypubs33[64][33],pubkey33[33];
numnotaries = komodo_notaries(notarypubs33,height,0);
for (i=nonz=0; i<width; i++,n++)
{
if ( height-i <= 0 )
continue;
if ( (pindex= komodo_chainactive(height-width+i+1)) != 0 )
{
if ( komodo_blockload(block,pindex) == 0 )
{
komodo_block2pubkey33(pubkey33,&block);
for (j=0; j<numnotaries; j++)
{
if ( memcmp(notarypubs33[j],pubkey33,33) == 0 )
{
minerids[nonz++] = j;
break;
minerids[i] = komodo_minerid(height - i,0);
}
return(n);*/
fprintf(stderr,"komodo_minerids is deprecated\n");
return(-1);
}
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)
@@ -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 )
{
//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 )
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);
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 )
// 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);
}
/*
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
/******************************************************************************
* Copyright © 2014-2017 The SuperNET Developers. *
* 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 *

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 *
* 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 *
* 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();
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
{
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
{
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 )
return(-1);
}
@@ -1972,7 +1772,7 @@ void komodo_passport_iteration()
if ( expired == 0 && KOMODO_PASSPORT_INITDONE == 0 )
{
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 *
* the top-level directory of this distribution for the individual copyright *
@@ -15,6 +15,7 @@
#include "komodo_defs.h"
void komodo_prefetch(FILE *fp);
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_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);
char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port);
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_isrealtime(int32_t *kmdheightp);
uint64_t komodo_paxtotal();
@@ -46,7 +46,7 @@ struct komodo_state KOMODO_STATES[34];
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 KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE;
int32_t KOMODO_LASTMINED,prevKOMODO_LASTMINED,JUMBLR_PAUSE = 1;
std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY;
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;
char KMDUSERPASS[4096],BTCUSERPASS[4096]; uint16_t KMD_PORT = 7771,BITCOIND_PORT = 7771;
uint64_t PENDING_KOMODO_TX;
extern int32_t KOMODO_LOADINGBLOCKS;
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 *
* 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 *
* 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 *
* 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 *
* the top-level directory of this distribution for the individual copyright *
@@ -13,6 +13,7 @@
* *
******************************************************************************/
#include "komodo_defs.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)
{
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);
}
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;
@@ -543,50 +542,4 @@ void komodo_init(int32_t height)
didinit = 1;
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 *
* 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 *
* 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;
};
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
{
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 *
* 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
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);
printf("Created (%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 )
{
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_HALVING),(void *)&ASSETCHAINS_HALVING);
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);
}
addn = GetArg("-seednode","");
@@ -1696,3 +1696,24 @@ struct komodo_state *komodo_stateptr(char *symbol,char *dest)
komodo_nameset(symbol,dest,ASSETCHAINS_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) {
CBlock block;
if (ReadBlockFromDisk(block, pindexSlow)) {
if (ReadBlockFromDisk(block, pindexSlow,1)) {
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
if (tx.GetHash() == hash) {
txOut = tx;
@@ -1655,7 +1655,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::M
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];
block.SetNull();
@@ -1677,6 +1677,8 @@ 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());
}
// Check the header
if ( 0 && checkPOW != 0 )
{
komodo_block2pubkey33(pubkey33,(CBlock *)&block);
if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime)))
{
@@ -1686,14 +1688,15 @@ bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos)
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
}
}
return true;
}
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
{
if ( pindex == 0 )
return false;
if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos()))
if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos(),checkPOW))
return false;
if (block.GetHash() != pindex->GetBlockHash())
return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
@@ -2249,7 +2252,6 @@ namespace {
catch (const std::exception& e) {
return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
// Verify checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock;
@@ -2331,7 +2333,6 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
return error("DisconnectBlock(): block and undo data inconsistent");
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
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--) {
const CTransaction &tx = block.vtx[i];
uint256 hash = tx.GetHash();
if (fAddressIndex) {
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();
// 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;
}
// verify that the view's current state corresponds to the previous block
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))
return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
if (fAddressIndex || fSpentIndex)
{
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;
// this is to prevent a "rogue miner" from creating
// 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);
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;
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 )
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 )
@@ -2862,7 +2863,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
if (fTxIndex)
if (!pblocktree->WriteTxIndex(vPos))
return AbortNode(state, "Failed to write transaction index");
if (fAddressIndex) {
if (!pblocktree->WriteAddressIndex(addressIndex)) {
return AbortNode(state, "Failed to write address index");
@@ -3086,7 +3086,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
assert(pindexDelete);
// Read block from disk.
CBlock block;
if (!ReadBlockFromDisk(block, pindexDelete))
if (!ReadBlockFromDisk(block, pindexDelete,1))
return AbortNode(state, "Failed to read block");
// Apply the block atomically to the chain state.
uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
@@ -3153,7 +3153,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
int64_t nTime1 = GetTimeMicros();
CBlock block;
if (!pblock) {
if (!ReadBlockFromDisk(block, pindexNew))
if (!ReadBlockFromDisk(block, pindexNew,1))
return AbortNode(state, "Failed to read 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");
// Check Equihash solution is valid
/*if ( fCheckPOW && !CheckEquihashSolution(&blockhdr, Params()) )
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");*/
if ( fCheckPOW )
{
if ( !CheckEquihashSolution(&blockhdr, Params()) )
return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
}
// Check proof of work matches claimed amount
/*komodo_index2pubkey33(pubkey33,pindex,height);
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_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);
}
int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
libzcash::ProofVerifier& verifier,
bool fCheckPOW, bool fCheckMerkleRoot)
{
uint8_t pubkey33[33];
uint8_t pubkey33[33]; uint256 hash;
// These are checks that are independent of context.
hash = block.GetHash();
// Check that the header is valid (particularly PoW). This is mostly
// redundant with the call in AcceptBlockHeader.
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;
}
if ( fCheckPOW && !CheckEquihashSolution(&block, Params()) )
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) )
if ( fCheckPOW )
{
//komodo_reverify_blockcheck(state,height,pindex);
return state.DoS(1, error("CheckBlock(): proof of work failed"),REJECT_INVALID, "high-hash");
//if ( !CheckEquihashSolution(&block, Params()) )
// 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.
if (fCheckMerkleRoot) {
bool mutated;
uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
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);
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences
// of transactions in a block without affecting the merkle root of a block,
// while still invalidating it.
if (mutated)
return state.DoS(100, error("CheckBlock(): duplicate transaction"),
return state.DoS(100, error("CheckBlock: duplicate transaction"),
REJECT_INVALID, "bad-txns-duplicate", true);
}
@@ -3841,16 +3819,16 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat
// Size limits
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");
// First transaction must be coinbase, the rest must not be
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");
for (unsigned int i = 1; i < block.vtx.size(); i++)
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");
// 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 )
return error("CheckBlock: komodo_validate_interest failed");
if (!CheckTransaction(tx, state, verifier))
return error("CheckBlock(): CheckTransaction failed");
return error("CheckBlock: CheckTransaction failed");
}
unsigned int nSigOps = 0;
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);
}
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);
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 )
fprintf(stderr,"check deposit rejection\n");
return(false);
@@ -3986,8 +3963,9 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
// Check for duplicate
uint256 hash = block.GetHash();
BlockMap::iterator miSelf = mapBlockIndex.find(hash);
CBlockIndex *pindex = NULL;
if (miSelf != mapBlockIndex.end()) {
CBlockIndex *tipindex,*pindex = NULL;
if (miSelf != mapBlockIndex.end())
{
// Block header is already known.
pindex = miSelf->second;
if (ppindex)
@@ -4038,7 +4016,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
CBlockIndex *&pindex = *ppindex;
if (!AcceptBlockHeader(block, state, &pindex))
{
//fprintf(stderr,"AcceptBlockHeader rejected\n");
fprintf(stderr,"AcceptBlockHeader rejected\n");
return false;
}
if ( pindex == 0 )
@@ -4119,20 +4097,23 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
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
bool checked;
auto verifier = libzcash::ProofVerifier::Disabled();
if ( chainActive.Tip() != 0 )
komodo_currentheight_set(chainActive.Tip()->nHeight);
if ( ASSETCHAINS_SYMBOL[0] == 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);
bool fRequested = MarkBlockAsReceived(pblock->GetHash());
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 ( pfrom != 0 )
@@ -4170,26 +4151,25 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex
indexDummy.nHeight = pindexPrev->nHeight + 1;
// JoinSplit proofs are verified in ConnectBlock
auto verifier = libzcash::ProofVerifier::Disabled();
// NOTE: CheckBlockHeader is called by CheckBlock
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
{
fprintf(stderr,"TestBlockValidity failure A\n");
fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
return false;
}
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;
}
if (!ContextualCheckBlock(block, state, pindexPrev))
{
//fprintf(stderr,"TestBlockValidity failure C\n");
fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
return false;
}
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;
}
assert(state.IsValid());
@@ -4264,7 +4244,6 @@ void FindFilesToPrune(std::set<int>& setFilesToPrune)
if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
return;
}
unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
uint64_t nCurrentUsage = CalculateCurrentUsage();
// 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;
}
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())
return NULL;
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 )
{
fpos = ftell(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);
komodo_prefetch(file);
didinit[pos.nFile] = 1;
}
if (pos.nPos) {
@@ -4396,9 +4359,10 @@ CBlockIndex * InsertBlockIndex(uint256 hash)
bool static LoadBlockIndexDB()
{
const CChainParams& chainparams = Params();
LogPrintf("%s: start loading guts\n", __func__);
if (!pblocktree->LoadBlockIndexGuts())
return false;
LogPrintf("%s: loaded guts\n", __func__);
boost::this_thread::interruption_point();
// Calculate nChainWork
@@ -4410,7 +4374,9 @@ bool static LoadBlockIndexDB()
vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
//komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
}
//fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
sort(vSortedByHeight.begin(), vSortedByHeight.end());
//fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
{
CBlockIndex* pindex = item.second;
@@ -4459,6 +4425,7 @@ bool static LoadBlockIndexDB()
pindexBestHeader = pindex;
//komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
}
//fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
// Load block file info
pblocktree->ReadLastBlockFile(nLastBlockFile);
@@ -4488,6 +4455,7 @@ bool static LoadBlockIndexDB()
}
//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++)
{
CDiskBlockPos pos(*it, 0);
@@ -4509,7 +4477,6 @@ bool static LoadBlockIndexDB()
// Check whether we have a transaction index
pblocktree->ReadFlag("txindex", fTxIndex);
LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
// Check whether we have an address index
pblocktree->ReadFlag("addressindex", fAddressIndex);
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;
// No need to verify JoinSplits twice
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)
{
boost::this_thread::interruption_point();
@@ -4595,7 +4563,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
break;
CBlock block;
// 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());
// check level 1: verify block validity
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())
return true;
}
//fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
if (pindexFailure)
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))));
pindex = chainActive.Next(pindex);
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());
if (!ConnectBlock(block, state, pindex, coins,false, true))
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
fTxIndex = GetBoolArg("-txindex", true);
pblocktree->WriteFlag("txindex", fTxIndex);
// Use the provided setting for -addressindex in the new database
fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
pblocktree->WriteFlag("addressindex", fAddressIndex);
@@ -4852,7 +4820,6 @@ bool InitBlockIndex() {
fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
pblocktree->WriteFlag("spentindex", fSpentIndex);
LogPrintf("Initializing databases...\n");
// 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;
try {
// 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();
while (!blkdat.eof()) {
boost::this_thread::interruption_point();
@@ -4945,7 +4913,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
// process in case the block isn't known yet
if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
CValidationState state;
if (ProcessNewBlock(0,state, NULL, &block, true, dbp))
if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
nLoaded++;
if (state.IsError())
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);
while (range.first != range.second) {
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(),
head.ToString());
CValidationState dummy;
if (ProcessNewBlock(0,dummy, NULL, &block, true, &it->second))
if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
{
nLoaded++;
queue.push_back(block.GetHash());
@@ -5321,7 +5289,7 @@ void static ProcessGetData(CNode* pfrom)
{
// Send block from disk
CBlock block;
if (!ReadBlockFromDisk(block, (*mi).second))
if (!ReadBlockFromDisk(block, (*mi).second,1))
{
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
// conditions in AcceptBlock().
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
ProcessNewBlock(0,state, pfrom, &block, forceProcessing, NULL);
ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
int nDoS;
if (state.IsInvalid(nDoS)) {
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.
* @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 */
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
/** Open a block file (blk?????.dat) */
@@ -780,8 +780,8 @@ bool GetAddressUnspent(uint160 addressHash, int type,
/** Functions for disk access for blocks */
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos);
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex);
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW);
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW);
/** 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_isrealtime(int32_t *kmdheightp);
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);
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
@@ -384,7 +384,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
nLastBlockTx = nBlockTx;
nLastBlockSize = nBlockSize;
blocktime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
//pblock->nTime = blocktime + 1;
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
//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.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;
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;
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 )
{
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 )
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();
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
@@ -655,11 +631,24 @@ static bool ProcessBlockFound(CBlock* pblock)
// Process this block the same as if we had received it from another node
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");
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;
}
@@ -669,7 +658,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he
int32_t FOUND_BLOCK,KOMODO_MAYBEMINED;
extern int32_t KOMODO_LASTMINED;
int32_t roundrobin_delay;
arith_uint256 HASHTarget;
arith_uint256 HASHTarget,HASHTarget_POW;
#ifdef ENABLE_WALLET
void static BitcoinMiner(CWallet *pwallet)
@@ -870,15 +859,15 @@ void static BitcoinMiner()
if ( ASSETCHAINS_STAKED != 0 && NOTARY_PUBKEY33[0] == 0 )
{
int32_t percPoS,z;
if ( Mining_height <= 100 )
/*if ( Mining_height <= 100 )
{
sleep(60);
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--)
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]);
fprintf(stderr," PoW for staked coin\n");
fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%%\n",percPoS,(int32_t)ASSETCHAINS_STAKED);
}
while (true)
{
@@ -904,8 +893,10 @@ void static BitcoinMiner()
crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
// (x_1, x_2, ...) = A(I, V, n, k)
LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
arith_uint256 hashTarget = HASHTarget;
//fprintf(stderr,"running solver\n");
arith_uint256 hashTarget;
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 =
#ifdef ENABLE_WALLET
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
@@ -913,19 +904,30 @@ void static BitcoinMiner()
[&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams]
#endif
(std::vector<unsigned char> soln) {
int32_t z; arith_uint256 h; CBlock B;
// Write the solution to the hash and compute the result.
LogPrint("pow", "- Checking solution against target\n");
pblock->nSolution = soln;
solutionTargetChecks.increment();
if ( UintToArith256(pblock->GetHash()) > HASHTarget )
{
//if ( ASSETCHAINS_SYMBOL[0] != 0 )
// fprintf(stderr," missed target\n");
B = *pblock;
h = UintToArith256(B.GetHash());
if ( h > hashTarget )
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;
if ( !TestBlockValidity(state, *pblock, chainActive.Tip(), true, false))
if ( !TestBlockValidity(state,B, chainActive.Tip(), true, false))
{
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);
}
@@ -948,13 +950,13 @@ void static BitcoinMiner()
{
if ( NOTARY_PUBKEY33[0] != 0 )
{
printf("need to wait %d seconds to submit\n",(int32_t)(pblock->nTime - GetAdjustedTime()));
while ( GetAdjustedTime() < pblock->nTime )
printf("need to wait %d seconds to submit staked block\n",(int32_t)(B.nTime - GetAdjustedTime()));
while ( GetAdjustedTime() < B.nTime )
sleep(1);
}
else
{
uint256 tmp = pblock->GetHash();
uint256 tmp = B.GetHash();
int32_t z; for (z=31; z>=0; z--)
fprintf(stderr,"%02x",((uint8_t *)&tmp)[z]);
fprintf(stderr," mined block!\n");
@@ -964,11 +966,11 @@ void static BitcoinMiner()
// Found a solution
SetThreadPriority(THREAD_PRIORITY_NORMAL);
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
if (ProcessBlockFound(pblock, *pwallet, reservekey)) {
if (ProcessBlockFound(&B, *pwallet, reservekey)) {
#else
if (ProcessBlockFound(pblock)) {
if (ProcessBlockFound(&B)) {
#endif
// Ignore chain updates caused by us
std::lock_guard<std::mutex> lock{m_cs};
@@ -1083,13 +1085,17 @@ void static BitcoinMiner()
// Update nNonce and nTime
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
pblock->nBits = savebits;
if ( ASSETCHAINS_STAKED == 0 || NOTARY_PUBKEY33[0] == 0 )
/*if ( NOTARY_PUBKEY33[0] == 0 )
{
int32_t percPoS;
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);
if ( it != bucketMap.end() )
{
static uint32_t counter;
if ( counter++ < 1 )
fprintf(stderr,"%s FindBucketIndex violation: from val %f\n",ASSETCHAINS_SYMBOL,val);
//static uint32_t counter;
//if ( counter++ < 1 )
// fprintf(stderr,"%s FindBucketIndex violation: from val %f\n",ASSETCHAINS_SYMBOL,val);
}
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;
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];
//for (i=31; i>=0; i--)
// fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
//fprintf(stderr," checkpow\n");
memcpy(origpubkey33,pubkey33,33);
memset(blocktimes,0,sizeof(blocktimes));
tiptime = komodo_chainactive_timestamp();
@@ -192,23 +195,20 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash,unsigned int
return true;
if ( ASSETCHAINS_SYMBOL[0] != 0 || height > 792000 )
{
if ( 0 && height > 792000 )
//if ( 0 && height > 792000 )
{
for (i=31; i>=0; i--)
printf("%02x",((uint8_t *)&hash)[i]);
printf(" hash vs ");
fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
fprintf(stderr," hash vs ");
for (i=31; i>=0; i--)
printf("%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,"%02x",((uint8_t *)&bnTarget)[i]);
fprintf(stderr," ht.%d special.%d notaryid.%d mod.%d error\n",height,special,notaryid,(height % 35));
for (i=0; i<33; i++)
printf("%02x",pubkey33[i]);
printf(" <- pubkey\n");
fprintf(stderr,"%02x",pubkey33[i]);
fprintf(stderr," <- pubkey\n");
for (i=0; i<33; i++)
printf("%02x",origpubkey33[i]);
printf(" <- origpubkey\n");
for (i=0; i<66; i++)
printf("%d ",mids[i]);
printf(" minerids from ht.%d\n",height);
fprintf(stderr,"%02x",origpubkey33[i]);
fprintf(stderr," <- origpubkey\n");
}
return false;
}

View File

@@ -214,7 +214,7 @@ static bool rest_block(HTTPRequest* req,
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
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");
}

View File

@@ -438,7 +438,7 @@ UniValue getblockdeltas(const UniValue& params, bool fHelp)
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
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");
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)
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");
if (!fVerbose)
@@ -746,6 +746,7 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
}
#include "komodo_defs.h"
#include "komodo_structs.h"
#define IGUANA_MAXSCRIPTSIZE 10001
#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_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_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)
{
@@ -796,6 +799,74 @@ UniValue kvsearch(const UniValue& params, bool fHelp)
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)
{
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)
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");
// Locate the transaction in the block
@@ -939,7 +1010,7 @@ UniValue minerids(const UniValue& params, bool fHelp)
if ( pblockindex != 0 )
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));
numnotaries = komodo_notaries(pubkeys,height,timestamp);
@@ -977,6 +1048,7 @@ UniValue minerids(const UniValue& params, bool fHelp)
a.push_back(item);
}
ret.push_back(Pair("mined", a));
ret.push_back(Pair("numnotaries", numnotaries));
} else ret.push_back(Pair("error", (char *)"couldnt extract minerids"));
return ret;
}

View File

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

View File

@@ -267,7 +267,7 @@ UniValue generate(const UniValue& params, bool fHelp)
}
endloop:
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");
++nHeight;
blockHashes.push_back(pblock->GetHash().GetHex());
@@ -807,7 +807,7 @@ UniValue submitblock(const UniValue& params, bool fHelp)
CValidationState state;
submitblock_StateCatcher sc(block.GetHash());
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);
if (fBlockPresent)
{

View File

@@ -53,6 +53,10 @@ extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE;
extern char ASSETCHAINS_SYMBOL[];
int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp);
#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)
{
@@ -149,6 +153,28 @@ UniValue getinfo(const UniValue& params, bool fHelp)
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;
}
@@ -203,7 +229,10 @@ UniValue jumblr_deposit(const UniValue& params, bool fHelp)
{
string addr = params[0].get_str();
if ( (retval= Jumblr_depositaddradd((char *)addr.c_str())) >= 0 )
{
result.push_back(Pair("result", retval));
JUMBLR_PAUSE = 0;
}
else result.push_back(Pair("error", retval));
} else result.push_back(Pair("error", "invalid address"));
return(result);
@@ -222,6 +251,7 @@ UniValue jumblr_secret(const UniValue& params, bool fHelp)
retval = Jumblr_secretaddradd((char *)addr.c_str());
result.push_back(Pair("result", "success"));
result.push_back(Pair("num", retval));
JUMBLR_PAUSE = 0;
} else result.push_back(Pair("error", "invalid address"));
return(result);
}

View File

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

View File

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

View File

@@ -238,9 +238,11 @@ UniValue help(const UniValue& params, bool fHelp)
return tableRPC.help(strCommand);
}
extern char ASSETCHAINS_SYMBOL[];
UniValue stop(const UniValue& params, bool fHelp)
{
char buf[64];
// Accept the deprecated and ignored 'detach' boolean argument
if (fHelp || params.size() > 1)
throw runtime_error(
@@ -248,7 +250,8 @@ UniValue stop(const UniValue& params, bool fHelp)
"\nStop Komodo server.");
// Shutdown will take long enough that the response should get back
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", "paxprices", &paxprices, true },
{ "blockchain", "notaries", &notaries, true },
{ "blockchain", "allMoMs", &allMoMs, true },
{ "blockchain", "MoMoMdata", &MoMoMdata, true },
{ "blockchain", "height_MoM", &height_MoM, true },
{ "blockchain", "txMoMproof", &txMoMproof, 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_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 txMoMproof(const UniValue& params, bool fHelp);
extern UniValue notaries(const UniValue& params, bool fHelp);

View File

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

View File

@@ -6,6 +6,13 @@
#* @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.
CURVE = BN128
OPTFLAGS = -O2 -march=native -mtune=native
@@ -106,18 +113,9 @@ EXECUTABLES_WITH_GTEST =
EXECUTABLES_WITH_SUPERCOP = \
libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark
GTEST_TESTS = libsnark/gtests
GTEST_TESTS =
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
GTEST_SRCS =
DOCS = README.html
@@ -175,6 +173,7 @@ all: \
$(if $(NO_GTEST),,$(EXECUTABLES_WITH_GTEST) $(GTEST_TESTS)) \
$(if $(NO_SUPERCOP),,$(EXECUTABLES_WITH_SUPERCOP)) \
$(EXECUTABLES) \
$(LIBSNARK_A) \
$(if $(NO_DOCS),,doc)
doc: $(DOCS)

View File

@@ -14,7 +14,7 @@ Copyright (c) 2012-2014 SCIPR Lab and contributors (see [AUTHORS] file).
[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.
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
@@ -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
simple load-store interface.
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
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
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
library RPM dependencies are then:
`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`
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.
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 "common/assert_except.hpp"
namespace libsnark {
#ifdef PROFILE_OP_COUNTS
long long alt_bn128_G1::add_cnt = 0;
long long alt_bn128_G1::dbl_cnt = 0;
int64_t alt_bn128_G1::add_cnt = 0;
int64_t alt_bn128_G1::dbl_cnt = 0;
#endif
std::vector<size_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::wnaf_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_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
{
#ifdef DEBUG
assert(other.is_special());
assert_except(other.is_special());
#endif
// 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 {
public:
#ifdef PROFILE_OP_COUNTS
static long long add_cnt;
static long long dbl_cnt;
static int64_t add_cnt;
static int64_t dbl_cnt;
#endif
static std::vector<size_t> wnaf_window_table;
static std::vector<size_t> fixed_base_exp_window_table;
static std::vector<uint64_t> wnaf_window_table;
static std::vector<uint64_t> fixed_base_exp_window_table;
static alt_bn128_G1 G1_zero;
static alt_bn128_G1 G1_one;

View File

@@ -6,16 +6,17 @@
*****************************************************************************/
#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp"
#include "common/assert_except.hpp"
namespace libsnark {
#ifdef PROFILE_OP_COUNTS
long long alt_bn128_G2::add_cnt = 0;
long long alt_bn128_G2::dbl_cnt = 0;
int64_t alt_bn128_G2::add_cnt = 0;
int64_t alt_bn128_G2::dbl_cnt = 0;
#endif
std::vector<size_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::wnaf_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_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
{
#ifdef DEBUG
assert(other.is_special());
assert_except(other.is_special());
#endif
// 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 {
public:
#ifdef PROFILE_OP_COUNTS
static long long add_cnt;
static long long dbl_cnt;
static int64_t add_cnt;
static int64_t dbl_cnt;
#endif
static std::vector<size_t> wnaf_window_table;
static std::vector<size_t> fixed_base_exp_window_table;
static std::vector<uint64_t> wnaf_window_table;
static std::vector<uint64_t> fixed_base_exp_window_table;
static alt_bn128_G2 G2_zero;
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;
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);
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;
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);
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;
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);
if (!found_one)

View File

@@ -16,7 +16,7 @@ GroupT scalar_mul(const GroupT &base, const bigint<m> &scalar)
GroupT result = GroupT::zero();
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)
{

View File

@@ -4,13 +4,17 @@
* and contributors (see AUTHORS).
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#include <iostream>
#include "common/profiling.hpp"
//#include "algebra/curves/edwards/edwards_pp.hpp"
#ifdef CURVE_BN128
#include "algebra/curves/bn128/bn128_pp.hpp"
#endif
#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp"
#include <gtest/gtest.h>
//#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp"
//#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;
@@ -45,11 +49,11 @@ void pairing_test()
ans1.print();
ans2.print();
ans3.print();
EXPECT_EQ(ans1, ans2);
EXPECT_EQ(ans2, ans3);
assert(ans1 == ans2);
assert(ans2 == ans3);
EXPECT_NE(ans1, GT_one);
EXPECT_EQ((ans1^Fr<ppT>::field_char()), GT_one);
assert(ans1 != GT_one);
assert((ans1^Fr<ppT>::field_char()) == GT_one);
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_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);
EXPECT_EQ(ans_1 * ans_2, ans_12);
assert(ans_1 * ans_2 == ans_12);
}
template<typename ppT>
@@ -98,17 +102,31 @@ void affine_pairing_test()
ans1.print();
ans2.print();
ans3.print();
EXPECT_EQ(ans1, ans2);
EXPECT_EQ(ans2, ans3);
assert(ans1 == ans2);
assert(ans2 == ans3);
EXPECT_NE(ans1, GT_one);
EXPECT_EQ((ans1^Fr<ppT>::field_char()), GT_one);
assert(ans1 != GT_one);
assert((ans1^Fr<ppT>::field_char()) == GT_one);
printf("\n\n");
}
TEST(algebra, bilinearity)
int main(void)
{
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();
pairing_test<alt_bn128_pp>();
double_miller_loop_test<alt_bn128_pp>();

View File

@@ -5,14 +5,15 @@
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#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
#include "algebra/curves/bn128/bn128_pp.hpp"
#endif
#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp"
#include <sstream>
#include <gtest/gtest.h>
using namespace libsnark;
template<typename GroupT>
@@ -24,31 +25,31 @@ void test_mixed_add()
el = GroupT::zero();
el.to_special();
result = base.mixed_add(el);
EXPECT_EQ(result, base + el);
assert(result == base + el);
base = GroupT::zero();
el = GroupT::random_element();
el.to_special();
result = base.mixed_add(el);
EXPECT_EQ(result, base + el);
assert(result == base + el);
base = GroupT::random_element();
el = GroupT::zero();
el.to_special();
result = base.mixed_add(el);
EXPECT_EQ(result, base + el);
assert(result == base + el);
base = GroupT::random_element();
el = GroupT::random_element();
el.to_special();
result = base.mixed_add(el);
EXPECT_EQ(result, base + el);
assert(result == base + el);
base = GroupT::random_element();
el = base;
el.to_special();
result = base.mixed_add(el);
EXPECT_EQ(result, base.dbl());
assert(result == base.dbl());
}
template<typename GroupT>
@@ -59,53 +60,53 @@ void test_group()
bigint<1> randsum = bigint<1>("121160274");
GroupT zero = GroupT::zero();
EXPECT_EQ(zero, zero);
assert(zero == zero);
GroupT one = GroupT::one();
EXPECT_EQ(one, one);
assert(one == one);
GroupT two = bigint<1>(2l) * GroupT::one();
EXPECT_EQ(two, two);
assert(two == two);
GroupT five = bigint<1>(5l) * GroupT::one();
GroupT three = bigint<1>(3l) * 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 b = GroupT::random_element();
EXPECT_NE(one, zero);
EXPECT_NE(a, zero);
EXPECT_NE(a, one);
assert(one != zero);
assert(a != zero);
assert(a != one);
EXPECT_NE(b, zero);
EXPECT_NE(b, one);
assert(b != zero);
assert(b != one);
EXPECT_EQ(a.dbl(), a + a);
EXPECT_EQ(b.dbl(), b + b);
EXPECT_EQ(one.add(two), three);
EXPECT_EQ(two.add(one), three);
EXPECT_EQ(a + b, b + a);
EXPECT_EQ(a - a, zero);
EXPECT_EQ(a - b, a + (-b));
EXPECT_EQ(a - b, (-b) + a);
assert(a.dbl() == a + a);
assert(b.dbl() == b + b);
assert(one.add(two) == three);
assert(two.add(one) == three);
assert(a + b == b + a);
assert(a - a == zero);
assert(a - b == a + (-b));
assert(a - b == (-b) + a);
// handle special cases
EXPECT_EQ(zero + (-a), -a);
EXPECT_EQ(zero - a, -a);
EXPECT_EQ(a - zero, a);
EXPECT_EQ(a + zero, a);
EXPECT_EQ(zero + a, a);
assert(zero + (-a) == -a);
assert(zero - a == -a);
assert(a - zero == a);
assert(a + zero == a);
assert(zero + a == a);
EXPECT_EQ((a + b).dbl(), (a + b) + (b + a));
EXPECT_EQ(bigint<1>("2") * (a + b), (a + b) + (b + a));
assert((a + b).dbl() == (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);
EXPECT_EQ(GroupT::order() * one, zero);
EXPECT_NE((GroupT::order() * a) - a, zero);
EXPECT_NE((GroupT::order() * one) - one, zero);
assert(GroupT::order() * a == zero);
assert(GroupT::order() * one == zero);
assert((GroupT::order() * a) - a != zero);
assert((GroupT::order() * one) - one != zero);
test_mixed_add<GroupT>();
}
@@ -114,7 +115,7 @@ template<typename GroupT>
void test_mul_by_q()
{
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>
@@ -128,14 +129,36 @@ void test_output()
ss << g;
GroupT gg;
ss >> gg;
EXPECT_EQ(g, gg);
assert(g == gg);
/* use a random point in next iteration */
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();
test_group<G1<alt_bn128_pp> >();
test_output<G1<alt_bn128_pp> >();

View File

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

View File

@@ -21,6 +21,7 @@
#include "algebra/fields/field_utils.hpp"
#include "common/profiling.hpp"
#include "common/utils.hpp"
#include "common/assert_except.hpp"
namespace libsnark {
@@ -38,7 +39,7 @@ template<typename FieldT>
void _basic_serial_radix2_FFT(std::vector<FieldT> &a, const FieldT &omega)
{
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) */
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>
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 log_m = log2(m);
assert(m == 1ul<<log_m);
assert_except(m == UINT64_C(1)<<log_m);
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);
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
@@ -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));
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)
{
@@ -135,7 +136,7 @@ void _basic_parallel_radix2_FFT_inner(std::vector<FieldT> &a, const FieldT &omeg
#endif
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)
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());
}
assert(m == (1u << log2(m)));
assert_except(m == (1u << log2(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
- computations of Lagrange polynomials, and
- 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.
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:
* - an integer 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}
* The output is the polynomial L_{idx,S}(z) evaluated at z = t.
*/

View File

@@ -22,15 +22,16 @@
#include <cassert>
#include "algebra/fields/field_utils.hpp"
#include "algebra/evaluation_domain/domains/basic_radix2_domain.hpp"
#include "common/assert_except.hpp"
namespace libsnark {
template<typename FieldT>
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);
assert(log_min_size <= (FieldT::s+1));
assert_except(log_min_size <= (FieldT::s+1));
std::shared_ptr<evaluation_domain<FieldT> > result;
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");
}
assert(0);
assert_except(0);
}
else
{
@@ -54,9 +55,9 @@ std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t m
}
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 rounded_small = (1ul<<log2(small));
const size_t rounded_small = (UINT64_C(1)<<log2(small));
if (big == rounded_small)
{
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");
}
assert(0);
assert_except(0);
}
}
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");
}
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>
FieldT lagrange_eval(const size_t m, const std::vector<FieldT> &domain, const FieldT &t, const size_t idx)
{
assert(m == domain.size());
assert(idx < m);
assert_except(m == domain.size());
assert_except(idx < m);
FieldT num = 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);
template<typename FieldT>
FieldT power(const FieldT &base, const unsigned long exponent);
FieldT power(const FieldT &base, const uint64_t exponent);
} // libsnark

View File

@@ -25,7 +25,7 @@ FieldT power(const FieldT &base, const bigint<m> &exponent)
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)
{
@@ -43,7 +43,7 @@ FieldT power(const FieldT &base, const bigint<m> &exponent)
}
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));
}

View File

@@ -33,7 +33,7 @@ public:
mp_limb_t data[n] = {0};
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 mpz_t r); /// Initialize from MPZ element
@@ -46,7 +46,7 @@ public:
size_t max_bits() const { return n * GMP_NUMB_BITS; }
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;
bool test_bit(const std::size_t bitno) const;

View File

@@ -13,13 +13,14 @@
#include <climits>
#include <cstring>
#include "sodium.h"
#include "common/assert_except.hpp"
namespace libsnark {
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;
}
@@ -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)
{
assert(s[i] >= '0' && s[i] <= '9');
assert_except(s[i] >= '0' && s[i] <= '9');
s_copy[i] = s[i] - '0';
}
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;
}
@@ -53,7 +54,7 @@ bigint<n>::bigint(const mpz_t r) /// Initialize from MPZ element
mpz_fdiv_q_2exp(k, k, GMP_NUMB_BITS);
}
assert(mpz_sgn(k) == 0);
assert_except(mpz_sgn(k) == 0);
mpz_clear(k);
}
@@ -105,7 +106,7 @@ template<mp_size_t n>
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))
{
@@ -115,7 +116,7 @@ size_t bigint<n>::num_bits() const
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];
if (x == 0)
@@ -124,14 +125,14 @@ size_t bigint<n>::num_bits() const
}
else
{
return ((i+1) * GMP_NUMB_BITS) - __builtin_clzl(x);
return ((i+1) * GMP_NUMB_BITS) - __builtin_clzll(x);
}
}
return 0;
}
template<mp_size_t n>
unsigned long bigint<n>::as_ulong() const
uint64_t bigint<n>::as_ulong() const
{
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)
{
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);
}
@@ -223,7 +224,7 @@ inline bool bigint<n>::operator>(const bigint<n>& other) const
template<mp_size_t n>
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);
@@ -262,12 +263,12 @@ std::istream& operator>>(std::istream &in, bigint<n> &b)
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';
}
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;
#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
template<typename FieldT>
FieldT get_root_of_unity(const size_t n);
FieldT get_root_of_unity(const uint64_t n);
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>
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>
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);
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>
FieldT convert_bit_vector_to_field_element(const bit_vector &v);

View File

@@ -11,6 +11,7 @@
#define FIELD_UTILS_TCC_
#include "common/utils.hpp"
#include "common/assert_except.hpp"
namespace libsnark {
@@ -21,14 +22,14 @@ FieldT coset_shift()
}
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);
assert(n == (1u << logn));
assert(logn <= FieldT::s);
const uint64_t logn = log2(n);
assert_except(n == (1u << logn));
assert_except(logn <= FieldT::s);
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;
}
@@ -37,21 +38,21 @@ FieldT get_root_of_unity(const size_t n)
}
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 size_t repacked_size = div_ceil(v.size() * w, chunk_bits);
const uint64_t chunk_bits = FieldT::capacity();
const uint64_t repacked_size = div_ceil(v.size() * w, chunk_bits);
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;
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 size_t pos_in_word = (i * chunk_bits + j) % w;
const size_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 word_index = (i * chunk_bits + j) / w;
const uint64_t pos_in_word = (i * chunk_bits + j) % w;
const uint64_t word_or_0 = (word_index < v.size() ? v[word_index] : 0);
const uint64_t bit = (word_or_0 >> pos_in_word) & 1;
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>
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);
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>
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);
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>
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 c = FieldT::one();
@@ -164,14 +165,14 @@ void batch_invert(std::vector<FieldT> &vec)
for (auto el : vec)
{
assert(!el.is_zero());
assert_except(!el.is_zero());
prod.emplace_back(acc);
acc = acc * el;
}
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];
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).
* 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,
* using hand-optimized assembly code.
* using hand-optimzied assembly code.
*/
template<mp_size_t n, const bigint<n>& modulus>
class Fp_model {
@@ -44,15 +44,15 @@ public:
static const mp_size_t num_limbs = n;
static const constexpr bigint<n>& mod = modulus;
#ifdef PROFILE_OP_COUNTS
static long long add_cnt;
static long long sub_cnt;
static long long mul_cnt;
static long long sqr_cnt;
static long long inv_cnt;
static int64_t add_cnt;
static int64_t sub_cnt;
static int64_t mul_cnt;
static int64_t sqr_cnt;
static int64_t inv_cnt;
#endif
static size_t num_bits;
static uint64_t num_bits;
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_minus_1_over_2; // (t-1)/2
static Fp_model<n, modulus> nqr; // a quadratic nonresidue
@@ -67,9 +67,9 @@ public:
Fp_model() {};
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);
@@ -82,7 +82,7 @@ public:
/* Return the last limb of the standard representation of the
field element. E.g. on 64-bit architectures Fp(123).as_ulong()
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;
@@ -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 unsigned long pow);
Fp_model& operator^=(const uint64_t pow);
template<mp_size_t m>
Fp_model& operator^=(const bigint<m> &pow);
@@ -107,12 +107,12 @@ public:
Fp_model inverse() const;
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>
Fp_model operator^(const bigint<m> &pow) const;
static size_t size_in_bits() { return num_bits; }
static size_t capacity() { return num_bits - 1; }
static uint64_t size_in_bits() { return num_bits; }
static uint64_t capacity() { return num_bits - 1; }
static bigint<n> field_char() { return modulus; }
static Fp_model<n, modulus> zero();
@@ -125,29 +125,29 @@ public:
#ifdef PROFILE_OP_COUNTS
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>
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>
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>
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>
long long Fp_model<n, modulus>::inv_cnt = 0;
int64_t Fp_model<n, modulus>::inv_cnt = 0;
#endif
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>
bigint<n> Fp_model<n, modulus>::euler;
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>
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 */
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);
assert(carryout == 0);
assert_except(carryout == 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);
assert(borrow == 0);
assert_except(borrow == 0);
}
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>
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)
{
@@ -203,14 +203,14 @@ Fp_model<n,modulus>::Fp_model(const long x, const bool is_unsigned)
else
{
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);
}
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.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>
unsigned long Fp_model<n,modulus>::as_ulong() const
uint64_t Fp_model<n,modulus>::as_ulong() const
{
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)
{
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);
@@ -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);
assert(borrow == 0);
assert_except(borrow == 0);
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>
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);
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>
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);
return (r ^= pow);
@@ -626,7 +626,7 @@ Fp_model<n,modulus>& Fp_model<n,modulus>::invert()
this->inv_cnt++;
#endif
assert(!this->is_zero());
assert_except(!this->is_zero());
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) */
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 */
/* 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)
{
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);
@@ -684,13 +684,13 @@ Fp_model<n, modulus> Fp_model<n,modulus>::random_element() /// returns random el
r.mont_repr.randomize();
/* 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)
{
const std::size_t part = bitno/GMP_NUMB_BITS;
const std::size_t bit = bitno - (GMP_NUMB_BITS*part);
const uint64_t part = bitno/GMP_NUMB_BITS;
const uint64_t bit = bitno - (GMP_NUMB_BITS*part);
r.mont_repr.data[part] &= ~(1ul<<bit);
r.mont_repr.data[part] &= ~(1ull<<bit);
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();
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> w = (*this)^Fp_model<n,modulus>::t_minus_1_over_2;
Fp_model<n,modulus> x = (*this) * w;
@@ -734,7 +734,7 @@ Fp_model<n,modulus> Fp_model<n,modulus>::sqrt() const
while (b != one)
{
size_t m = 0;
uint64_t m = 0;
Fp_model<n,modulus> b2m = b;
while (b2m != one)
{

View File

@@ -66,7 +66,7 @@ public:
Fp12_2over3over2_model squared_karatsuba() const;
Fp12_2over3over2_model squared_complex() 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 cyclotomic_squared() const;
@@ -78,7 +78,7 @@ public:
Fp12_2over3over2_model cyclotomic_exp(const bigint<m> &exponent) const;
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::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>
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),
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();
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)
{
res = res.cyclotomic_squared();
}
if (exponent.data[i] & (1ul<<j))
if (exponent.data[i] & (UINT64_C(1)<<j))
{
found_one = true;
res = res * (*this);
@@ -390,7 +390,7 @@ std::istream& operator>>(std::istream& in, std::vector<Fp12_2over3over2_model<n,
{
v.clear();
size_t s;
uint64_t s;
in >> s;
char b;

View File

@@ -37,7 +37,7 @@ public:
typedef Fp_model<n, modulus> my_Fp;
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_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)
@@ -66,7 +66,7 @@ public:
Fp2_model operator-() const;
Fp2_model squared() const; // default is squared_complex
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 squared_karatsuba() const;
Fp2_model squared_complex() const;
@@ -74,7 +74,7 @@ public:
template<mp_size_t m>
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; }
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;
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>
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>
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,
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();
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> w = (*this)^Fp2_model<n,modulus>::t_minus_1_over_2;
Fp2_model<n,modulus> x = (*this) * w;
@@ -175,7 +175,7 @@ Fp2_model<n,modulus> Fp2_model<n,modulus>::sqrt() const
while (b != one)
{
size_t m = 0;
unsigned long long m = 0;
Fp2_model<n,modulus> b2m = b;
while (b2m != one)
{
@@ -239,7 +239,7 @@ std::istream& operator>>(std::istream& in, std::vector<Fp2_model<n, modulus> > &
{
v.clear();
size_t s;
unsigned long long s;
in >> s;
char b;

View File

@@ -63,7 +63,7 @@ public:
Fp6_3over2_model operator-() const;
Fp6_3over2_model squared() 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);
@@ -71,7 +71,7 @@ public:
Fp6_3over2_model operator^(const bigint<m> &other) const;
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::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>
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),
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();
size_t s;
uint64_t s;
in >> s;
char b;

View File

@@ -7,13 +7,11 @@
#include "algebra/fields/bigint.hpp"
#include <gtest/gtest.h>
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");
const char *b1_decimal = "76749407";
@@ -22,76 +20,88 @@ TEST(algebra, bigint)
const char *b2_binary = "0000000000000000000000000000010101111101101000000110100001011010"
"1101101010001001000001101000101000100110011001110001111110100010";
bigint<1> b0 = bigint<1>(0ul);
bigint<1> b0 = bigint<1>(UINT64_C(0));
bigint<1> b1 = bigint<1>(b1_decimal);
bigint<2> b2 = bigint<2>(b2_decimal);
EXPECT_EQ(b0.as_ulong(), 0ul);
EXPECT_TRUE(b0.is_zero());
EXPECT_EQ(b1.as_ulong(), 76749407ul);
EXPECT_FALSE(b1.is_zero());
EXPECT_EQ(b2.as_ulong(), 15747124762497195938ul);
EXPECT_FALSE(b2.is_zero());
EXPECT_NE(b0, b1);
EXPECT_FALSE(b0 == b1);
assert(b0.as_ulong() == UINT64_C(0));
assert(b0.is_zero());
assert(b1.as_ulong() == UINT64_C(76749407));
assert(!(b1.is_zero()));
assert(b2.as_ulong() == UINT64_C(15747124762497195938));
assert(!(b2.is_zero()));
assert(b0 != b1);
assert(!(b0 == b1));
EXPECT_EQ(b2.max_bits(), 128);
EXPECT_EQ(b2.num_bits(), 99);
assert(b2.max_bits() == 128);
assert(b2.num_bits() == 99);
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;
EXPECT_EQ(b3, bigint<3>(b3_decimal));
EXPECT_FALSE(b3.is_zero());
assert(b3 == bigint<3>(b3_decimal));
assert(!(b3.is_zero()));
bigint<3> b3a { b3 };
EXPECT_EQ(b3a, bigint<3>(b3_decimal));
EXPECT_EQ(b3a, b3);
EXPECT_FALSE(b3a.is_zero());
assert(b3a == bigint<3>(b3_decimal));
assert(b3a == b3);
assert(!(b3a.is_zero()));
mpz_t m3;
mpz_init(m3);
b3.to_mpz(m3);
bigint<3> b3b { m3 };
EXPECT_EQ(b3b, b3);
assert(b3b == b3);
bigint<2> quotient;
bigint<2> remainder;
bigint<3>::div_qr(quotient, remainder, b3, b2);
EXPECT_LT(quotient.num_bits(), GMP_NUMB_BITS);
EXPECT_EQ(quotient.as_ulong(), b1.as_ulong());
assert(quotient.num_bits() < GMP_NUMB_BITS);
assert(quotient.as_ulong() == b1.as_ulong());
bigint<1> b1inc = bigint<1>("76749408");
bigint<1> b1a = quotient.shorten(b1inc, "test");
EXPECT_EQ(b1a, b1);
EXPECT_TRUE(remainder.is_zero());
assert(b1a == b1);
assert(remainder.is_zero());
remainder.limit(b2, "test");
EXPECT_THROW((void)(quotient.shorten(b1, "test")), std::domain_error);
EXPECT_THROW(remainder.limit(remainder, "test"), std::domain_error);
try {
(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");
b3 += br;
EXPECT_NE(b3, b3a);
EXPECT_GT(b3, b3a);
EXPECT_FALSE(b3a > b3);
assert(b3 != b3a);
assert(b3 > b3a);
assert(!(b3a > b3));
bigint<3>::div_qr(quotient, remainder, b3, b2);
EXPECT_LT(quotient.num_bits(), GMP_NUMB_BITS);
EXPECT_EQ(quotient.as_ulong(), b1.as_ulong());
EXPECT_LT(remainder.num_bits(), GMP_NUMB_BITS);
EXPECT_EQ(remainder.as_ulong(), 42);
assert(quotient.num_bits() < GMP_NUMB_BITS);
assert(quotient.as_ulong() == b1.as_ulong());
assert(remainder.num_bits() < GMP_NUMB_BITS);
assert(remainder.as_ulong() == 42);
b3a.clear();
EXPECT_TRUE(b3a.is_zero());
EXPECT_EQ(b3a.num_bits(), 0);
EXPECT_FALSE(b3.is_zero());
assert(b3a.is_zero());
assert(b3a.num_bits() == 0);
assert(!(b3.is_zero()));
bigint<4> bx = bigint<4>().randomize();
bigint<4> by = bigint<4>().randomize();
EXPECT_FALSE(bx == by);
assert(!(bx == by));
// TODO: test serialization
}
int main(void)
{
test_bigint();
return 0;
}

View File

@@ -5,6 +5,9 @@
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#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
#include "algebra/curves/bn128/bn128_pp.hpp"
#endif
@@ -12,8 +15,6 @@
#include "algebra/fields/fp6_3over2.hpp"
#include "algebra/fields/fp12_2over3over2.hpp"
#include <gtest/gtest.h>
using namespace libsnark;
template<typename FieldT>
@@ -28,25 +29,25 @@ void test_field()
FieldT a = FieldT::random_element();
FieldT a_ser;
a_ser = reserialize<FieldT>(a);
EXPECT_EQ(a_ser, a);
assert(a_ser == a);
FieldT b = FieldT::random_element();
FieldT c = FieldT::random_element();
FieldT d = FieldT::random_element();
EXPECT_NE(a, zero);
EXPECT_NE(a, one);
assert(a != zero);
assert(a != one);
EXPECT_EQ(a * a, a.squared());
EXPECT_EQ((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);
EXPECT_EQ(a - b, a + (-b));
EXPECT_EQ(a - b, (-b) + a);
assert(a * a == a.squared());
assert((a + b).squared() == a.squared() + a*b + b*a + b.squared());
assert((a + b)*(c + d) == a*c + a*d + b*c + b*d);
assert(a - b == a + (-b));
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);
EXPECT_EQ((a + b) * c.inverse(), a * c.inverse() + (b.inverse() * c).inverse());
assert(a * a.inverse() == one);
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 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()
{
FieldT a = FieldT::random_element();
EXPECT_EQ(a.squared(), a * a);
EXPECT_EQ(a.squared(), a.squared_complex());
EXPECT_EQ(a.squared(), a.squared_karatsuba());
assert(a.squared() == a * a);
assert(a.squared() == a.squared_complex());
assert(a.squared() == a.squared_karatsuba());
}
template<typename FieldT>
void test_Frobenius()
{
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();
for (size_t power = 1; power < 10; ++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();
}
@@ -88,10 +89,49 @@ void test_Frobenius()
template<typename FieldT>
void test_unitary_inverse()
{
EXPECT_EQ(FieldT::extension_degree() % 2, 0);
assert(FieldT::extension_degree() % 2 == 0);
FieldT a = FieldT::random_element();
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>
@@ -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;
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}
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);
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(v0 == u * c0 + beta * u * c2 - beta * u * FieldT(2).inverse() * v1 - beta * u * FieldT(2).inverse() * v2 + beta * v6);
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);
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);
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);
// 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();
test_field<alt_bn128_Fq6>();
test_Frobenius<alt_bn128_Fq6>();

View File

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

View File

@@ -8,6 +8,8 @@
#ifndef KC_MULTIEXP_TCC_
#define KC_MULTIEXP_TCC_
#include "common/assert_except.hpp"
namespace libsnark {
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)
{
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);

View File

@@ -22,6 +22,7 @@
#include "common/profiling.hpp"
#include "common/utils.hpp"
#include "common/assert_except.hpp"
#include "algebra/scalar_multiplication/wnaf.hpp"
namespace libsnark {
@@ -40,7 +41,7 @@ public:
#if defined(__x86_64__) && defined(USE_ASM)
if (n == 3)
{
long res;
int64_t res;
__asm__
("// check for overflow \n\t"
"mov $0, %[res] \n\t"
@@ -58,7 +59,7 @@ public:
}
else if (n == 4)
{
long res;
int64_t res;
__asm__
("// check for overflow \n\t"
"mov $0, %[res] \n\t"
@@ -77,7 +78,7 @@ public:
}
else if (n == 5)
{
long res;
int64_t res;
__asm__
("// check for overflow \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();
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;
}
@@ -139,7 +140,7 @@ T naive_plain_exp(typename std::vector<T>::const_iterator vec_start,
{
result = result + (*scalar_it) * (*vec_it);
}
assert(scalar_it == scalar_end);
assert_except(scalar_it == scalar_end);
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()));
}
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)
{
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(opt_q.size() == g.size());
assert_except(g.size() % 2 == 1);
assert_except(opt_q.size() == g.size());
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 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
@@ -329,7 +330,7 @@ T multi_exp_with_mixed_addition(typename std::vector<T>::const_iterator vec_star
const size_t chunks,
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");
auto value_it = vec_start;
auto scalar_it = scalar_start;
@@ -389,7 +390,7 @@ size_t get_exp_window_size(const size_t num_scalars)
#endif
}
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
if (!inhibit_profiling_info)
@@ -420,9 +421,9 @@ window_table<T> get_window_table(const size_t scalar_size,
const size_t window,
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 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
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.
*/
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.

View File

@@ -17,15 +17,15 @@
namespace libsnark {
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
std::vector<long> res(length+1);
std::vector<int64_t> res(length+1);
bigint<n> c = scalar;
long j = 0;
int64_t j = 0;
while (!c.is_zero())
{
long u;
int64_t u;
if ((c.data[0] & 1) == 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>
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<T> table(1ul<<(window_size-1));
std::vector<int64_t> naf = find_wnaf(window_size, scalar);
std::vector<T> table(UINT64_C(1)<<(window_size-1));
T tmp = base;
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;
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();
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)
{
@@ -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)
{
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])
{

View File

@@ -66,14 +66,14 @@ merkle_tree<HashT>::merkle_tree(const size_t depth,
assert(log2(contents_as_vector.size()) <= depth);
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];
hashes[idx] = contents_as_vector[address];
hashes[idx].resize(digest_size);
}
size_t idx_begin = (1ul<<depth) - 1;
size_t idx_end = contents_as_vector.size() + ((1ul<<depth) - 1);
size_t idx_begin = (UINT64_C(1)<<depth) - 1;
size_t idx_end = contents_as_vector.size() + ((UINT64_C(1)<<depth) - 1);
for (int layer = depth; layer > 0; --layer)
{
@@ -100,13 +100,13 @@ merkle_tree<HashT>::merkle_tree(const size_t depth,
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)
{
const size_t address = it->first;
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;
hashes[idx] = value;
@@ -167,7 +167,7 @@ void merkle_tree<HashT>::set_value(const size_t address,
const bit_vector &value)
{
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);
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);
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)
{
@@ -209,7 +209,7 @@ typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(con
auto it = hashes.find(sibling_idx);
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].resize(digest_size);
}
@@ -227,7 +227,7 @@ typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(con
template<typename HashT>
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);
printf("[%zu] -> ", i);

View File

@@ -32,9 +32,9 @@ std::istream& operator>>(std::istream &in, sparse_vector<T> &v);
template<typename T>
struct sparse_vector {
std::vector<size_t> indices;
std::vector<uint64_t> indices;
std::vector<T> values;
size_t domain_size_ = 0;
uint64_t domain_size_ = 0;
sparse_vector() = 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=(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 std::vector<T> &other) const;
@@ -52,15 +52,15 @@ struct sparse_vector {
bool is_valid() const;
bool empty() const;
size_t domain_size() const; // return domain_size_
size_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 domain_size() const; // return domain_size_
uint64_t size() const; // return the number of indices (representing the number of non-zero entries)
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>
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 size_t offset) const;
const uint64_t offset) const;
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);

View File

@@ -29,7 +29,7 @@ sparse_vector<T>::sparse_vector(std::vector<T> &&v) :
}
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);
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;
}
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())
{
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;
}
size_t j = 0;
for (size_t i = 0; i < other.size(); ++i)
uint64_t j = 0;
for (uint64_t i = 0; i < other.size(); ++i)
{
if (this->indices[j] == i)
{
@@ -134,7 +134,7 @@ bool sparse_vector<T>::is_valid() const
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])
{
@@ -157,42 +157,42 @@ bool sparse_vector<T>::empty() const
}
template<typename T>
size_t sparse_vector<T>::domain_size() const
uint64_t sparse_vector<T>::domain_size() const
{
return domain_size_;
}
template<typename T>
size_t sparse_vector<T>::size() const
uint64_t sparse_vector<T>::size() const
{
return indices.size();
}
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 FieldT>
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 size_t offset) const
const uint64_t offset) const
{
// TODO: does not really belong here.
const size_t chunks = 1;
const uint64_t chunks = 1;
const bool use_multiexp = true;
T accumulated_value = T::zero();
sparse_vector<T> resulting_vector;
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;
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);
// 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.indices.size() << "\n";
for (const size_t& i : v.indices)
for (const uint64_t& i : v.indices)
{
out << i << "\n";
}
@@ -285,11 +285,11 @@ std::istream& operator>>(std::istream& in, sparse_vector<T> &v)
in >> v.domain_size_;
consume_newline(in);
size_t s;
uint64_t s;
in >> s;
consume_newline(in);
v.indices.resize(s);
for (size_t i = 0; i < s; ++i)
for (uint64_t i = 0; i < s; ++i)
{
in >> v.indices[i];
consume_newline(in);
@@ -300,7 +300,7 @@ std::istream& operator>>(std::istream& in, sparse_vector<T> &v)
consume_newline(in);
v.values.reserve(s);
for (size_t i = 0; i < s; ++i)
for (uint64_t i = 0; i < s; ++i)
{
T t;
in >> t;

View File

@@ -26,27 +26,44 @@
#include <proc/readproc.h>
#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 {
long long get_nsec_time()
int64_t get_nsec_time()
{
auto timepoint = std::chrono::high_resolution_clock::now();
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. */
long long get_nsec_cpu_time()
/* Return total CPU time consumsed by all threads of the process, in nanoseconds. */
int64_t get_nsec_cpu_time()
{
::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) )
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 .
//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;
}
long long start_time, last_time;
long long start_cpu_time, last_cpu_time;
int64_t start_time, last_time;
int64_t start_cpu_time, last_cpu_time;
void start_profiling()
{
@@ -57,20 +74,20 @@ void start_profiling()
}
std::map<std::string, size_t> invocation_counts;
std::map<std::string, long long> enter_times;
std::map<std::string, long long> last_times;
std::map<std::string, long long> cumulative_times;
std::map<std::string, int64_t> enter_times;
std::map<std::string, int64_t> last_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
std::map<std::string, long long> enter_cpu_times;
std::map<std::string, long long> last_cpu_times;
std::map<std::pair<std::string, std::string>, long long> op_counts;
std::map<std::pair<std::string, std::string>, long long> cumulative_op_counts; // ((msg, data_point), value)
std::map<std::string, int64_t> enter_cpu_times;
std::map<std::string, int64_t> last_cpu_times;
std::map<std::pair<std::string, std::string>, int64_t> op_counts;
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
size_t indentation = 0;
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
std::make_pair("Fradd", &Fr<default_ec_pp>::add_cnt),
std::make_pair("Frsub", &Fr<default_ec_pp>::sub_cnt),
@@ -98,7 +115,7 @@ void clear_profiling_counters()
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 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);
}
void print_cumulative_times(const long long factor)
void print_cumulative_times(const int64_t factor)
{
printf("Dumping times:\n");
for (auto& kv : cumulative_times)
@@ -155,7 +172,7 @@ void print_op_profiling(const std::string &msg)
printf("(opcounts) = (");
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)
{
@@ -171,14 +188,14 @@ void print_op_profiling(const std::string &msg)
#endif
}
static void print_times_from_last_and_start(long long now, long long last,
long long cpu_now, long long cpu_last)
static void print_times_from_last_and_start(int64_t now, int64_t last,
int64_t cpu_now, int64_t cpu_last)
{
long long time_from_start = now - start_time;
long long time_from_last = now - last;
int64_t time_from_start = now - start_time;
int64_t time_from_last = now - last;
long long cpu_time_from_start = cpu_now - start_cpu_time;
long long cpu_time_from_last = cpu_now - cpu_last;
int64_t cpu_time_from_start = cpu_now - start_cpu_time;
int64_t cpu_time_from_last = cpu_now - cpu_last;
if (time_from_last != 0) {
double parallelism_from_last = 1.0 * cpu_time_from_last / time_from_last;
@@ -199,8 +216,8 @@ void print_time(const char* msg)
return;
}
long long now = get_nsec_time();
long long cpu_now = get_nsec_cpu_time();
int64_t now = get_nsec_time();
int64_t cpu_now = get_nsec_cpu_time();
printf("%-35s\t", msg);
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)
{
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);
}
@@ -245,9 +262,9 @@ void enter_block(const std::string &msg, const bool indent)
}
block_names.emplace_back(msg);
long long t = get_nsec_time();
int64_t t = get_nsec_time();
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;
if (inhibit_profiling_info)
@@ -288,15 +305,15 @@ void leave_block(const std::string &msg, const bool indent)
++invocation_counts[msg];
long long t = get_nsec_time();
int64_t t = get_nsec_time();
last_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]);
#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)];
}

View File

@@ -22,7 +22,7 @@
namespace libsnark {
void start_profiling();
long long get_nsec_time();
int64_t get_nsec_time();
void print_time(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_counters;
extern std::map<std::string, size_t> invocation_counts;
extern std::map<std::string, long long> last_times;
extern std::map<std::string, long long> cumulative_times;
extern std::map<std::string, int64_t> last_times;
extern std::map<std::string, int64_t> cumulative_times;
void clear_profiling_counters();
void print_cumulative_time_entry(const std::string &key, const long long factor=1);
void print_cumulative_times(const long long factor=1);
void print_cumulative_time_entry(const std::string &key, const int64_t factor=1);
void print_cumulative_times(const int64_t factor=1);
void print_cumulative_op_counts(const bool only_fq=false);
void enter_block(const std::string &msg, const bool indent=true);

View File

@@ -22,7 +22,7 @@ namespace libsnark {
/*
* @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.
*
* However, for now the following conventions are used within the code.

View File

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

View File

@@ -15,11 +15,11 @@
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,
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)
{
@@ -30,10 +30,10 @@ size_t log2(size_t n)
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;
for (size_t k = 0; k < l; ++k)
uint64_t r = 0;
for (uint64_t k = 0; k < l; ++k)
{
r = (r << 1) | (n & 1);
n >>= 1;
@@ -41,20 +41,20 @@ size_t bitreverse(size_t n, const size_t l)
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());
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;
}
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;
}
@@ -68,7 +68,7 @@ bool is_little_endian()
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];
va_list args;
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)
{
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";
}
@@ -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)
{
size_t size;
uint64_t size;
in >> size;
v.resize(size);
for (size_t i = 0; i < size; ++i)
for (uint64_t i = 0; i < size; ++i)
{
bool b;
in >> b;

View File

@@ -21,13 +21,13 @@ namespace libsnark {
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
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);
bit_vector int_list_to_bits(const std::initializer_list<unsigned long> &l, const size_t wordsize);
long long div_ceil(long long x, long long y);
uint64_t bitreverse(uint64_t n, const uint64_t l);
bit_vector int_list_to_bits(const std::initializer_list<uint64_t> &l, const uint64_t wordsize);
int64_t div_ceil(int64_t x, int64_t y);
bool is_little_endian();
@@ -46,8 +46,13 @@ void UNUSED(Types&&...) {}
void serialize_bit_vector(std::ostream &out, const bit_vector &v);
void deserialize_bit_vector(std::istream &in, bit_vector &v);
#ifdef __APPLE__
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]))

View File

@@ -12,11 +12,19 @@
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>
size_t size_in_bits(const std::vector<T> &v)
{
return v.size() * T::size_in_bits();
}
#endif
} // libsnark

View File

@@ -275,11 +275,11 @@ void test_disjunction_gadget(const size_t n)
disjunction_gadget<FieldT> d(pb, inputs, output, "d");
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)
{
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();
@@ -366,11 +366,11 @@ void test_conjunction_gadget(const size_t n)
conjunction_gadget<FieldT> c(pb, inputs, output, "c");
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)
{
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();
@@ -378,13 +378,13 @@ void test_conjunction_gadget(const size_t n)
#ifdef DEBUG
printf("positive test for %zu\n", w);
#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());
#ifdef DEBUG
printf("negative test for %zu\n", w);
#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());
}
@@ -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");
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(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");
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;
for (size_t k = 0; k < n; ++k)
{
pb.val(A[k]) = (i & (1ul<<k) ? FieldT::one() : FieldT::zero());
pb.val(B[k]) = (j & (1ul<<k) ? FieldT::one() : FieldT::zero());
correct += ((i & (1ul<<k)) && (j & (1ul<<k)) ? 1 : 0);
pb.val(A[k]) = (i & (UINT64_C(1)<<k) ? FieldT::one() : FieldT::zero());
pb.val(B[k]) = (j & (UINT64_C(1)<<k) ? FieldT::one() : FieldT::zero());
correct += ((i & (UINT64_C(1)<<k)) && (j & (UINT64_C(1)<<k)) ? 1 : 0);
}
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 */
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());
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;
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;
index.allocate(pb, "index");
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");
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);
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);
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.is_satisfied());
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)
{
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);
}

View File

@@ -78,7 +78,7 @@ public:
pb_linear_combination_array<FieldT> g;
pb_linear_combination_array<FieldT> h;
pb_variable<FieldT> W;
long K;
int64_t K;
pb_linear_combination_array<FieldT> new_a;
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> &h,
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_e,
const std::string &annotation_prefix);

View File

@@ -16,7 +16,7 @@
namespace libsnark {
const unsigned long SHA256_K[64] = {
const uint64_t SHA256_K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
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
};
const unsigned long SHA256_H[8] = {
const uint64_t SHA256_H[8] = {
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> &h,
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_e,
const std::string &annotation_prefix) :

View File

@@ -10,8 +10,6 @@
#include "common/profiling.hpp"
#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp"
#include <gtest/gtest.h>
using namespace libsnark;
template<typename FieldT>
@@ -37,10 +35,10 @@ void test_two_to_one()
f.generate_r1cs_witness();
output.generate_r1cs_witness(hash_bv);
EXPECT_TRUE(pb.is_satisfied());
assert(pb.is_satisfied());
}
TEST(gadgetlib1, sha256)
int main(void)
{
start_profiling();
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)
{
if (address & (1ul << (tree_depth-1-i)))
if (address & (UINT64_C(1) << (tree_depth-1-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;
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());
}

View File

@@ -144,10 +144,10 @@ void test_merkle_tree_check_read_gadget()
bit_vector address_bits;
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);
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);
bit_vector other(digest_len);
std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; });

View File

@@ -19,6 +19,7 @@
#include "common/data_structures/merkle_tree.hpp"
#include "gadgetlib1/gadget.hpp"
#include "gadgetlib1/gadgets/hashes/crh_gadget.hpp"
#include "gadgetlib1/gadgets/hashes/hash_io.hpp"
#include "gadgetlib1/gadgets/hashes/digest_selector_gadget.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;
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);
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);
bit_vector other(digest_len);
std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; });

View File

@@ -5,36 +5,44 @@
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp"
#ifdef CURVE_BN128
#include "algebra/curves/bn128/bn128_pp.hpp"
#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_update_gadget.hpp"
#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp"
#include <gtest/gtest.h>
using namespace libsnark;
template<typename ppT>
void test_all_merkle_tree_gadgets()
{
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_update_gadget<FieldT, CRH_with_bit_out_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();
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
bn128_pp::init_public_params();
test_all_merkle_tree_gadgets<bn128_pp>();
#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_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;
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_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;
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>
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));
}
@@ -232,7 +232,7 @@ void pb_linear_combination_array<FieldT>::fill_with_bits_of_field_element(protob
}
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));
}

View File

@@ -4,7 +4,7 @@
Declaration of interfaces for a R1CS-to-QAP reduction, that is, constructing
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 efficient approach described in Appendix E of \[BCGTV13].

View File

@@ -10,15 +10,13 @@
#include <cstring>
#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 "common/profiling.hpp"
#include "common/utils.hpp"
#include "reductions/r1cs_to_qap/r1cs_to_qap.hpp"
#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp"
#include <gtest/gtest.h>
using namespace libsnark;
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.
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");
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");
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");
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");
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");
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("Call to test_qap");
}
TEST(relations, qap)
int main()
{
start_profiling();
mnt6_pp::init_public_params();
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");
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");
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");
}

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