@@ -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
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
40
src/assetchains_stop
Normal 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
|
||||
@@ -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());
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
195
src/komodo.h
195
src/komodo.h
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
273
src/komodo_ccdata.h
Normal 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
|
||||
@@ -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 *
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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);
|
||||
}*/
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
190
src/main.cpp
190
src/main.cpp
@@ -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 = █
|
||||
}
|
||||
@@ -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(),
|
||||
|
||||
@@ -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 */
|
||||
|
||||
108
src/miner.cpp
108
src/miner.cpp
@@ -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);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
24
src/pow.cpp
24
src/pow.cpp
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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", ¬aries, true },
|
||||
{ "blockchain", "allMoMs", &allMoMs, true },
|
||||
{ "blockchain", "MoMoMdata", &MoMoMdata, true },
|
||||
{ "blockchain", "height_MoM", &height_MoM, true },
|
||||
{ "blockchain", "txMoMproof", &txMoMproof, true },
|
||||
{ "blockchain", "minerids", &minerids, true },
|
||||
|
||||
@@ -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 ¶ms, 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);
|
||||
|
||||
@@ -17,3 +17,6 @@ External contributors:
|
||||
Tadanori TERUYA
|
||||
Sean Bowe
|
||||
Daira Hopwood
|
||||
@mugatu on forum.z.cash
|
||||
David Mercer
|
||||
Joshua Yabut
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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> >();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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])
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)];
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) :
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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; });
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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; });
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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].
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user