diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index 302275323..3ddb69d24 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -591,18 +591,24 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi bitcoin_address(changeaddr, coin->chain->pubtype, myinfo->persistent_pubkey33, 33); txfee = (coin->txfee + duplicates*coin->txfee/10); - if ( strcmp(coin->symbol,"GAME") == 0 ) - printf("GAME txfee %.8f\n",dstr(txfee)); - if ( strcmp(coin->symbol,"EMC2") == 0 ) - printf("EMC2 txfee %.8f\n",dstr(txfee)); - if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,1,0)) != 0 ) + if (strcmp(coin->symbol, "GAME") == 0 || strcmp(coin->symbol, "EMC2") == 0) + printf("%s txfee %.8f\n", coin->symbol, dstr(txfee)); + + uint32_t txversion = 1; // txversion = 1 for non-overwintered and non-sapling coins + if (coin->sapling != 0) + txversion = 4; + + if ( (txobj= bitcoin_txcreate(coin->symbol,coin->chain->isPoS,0,txversion,0)) != 0 ) { - if ( duplicates <= 0 ) + if ( duplicates <= 0 ) duplicates = 1; spendlen = bitcoin_pubkeyspend(script,0,pubkey33); for (i=0; ichain->symbol,"BTC") == 0 && cJSON_GetArraySize(vins) > duplicates/2 ) { free(rawtx); diff --git a/iguana.vcxproj b/iguana.vcxproj index fbdc95c13..34ee05b7d 100644 --- a/iguana.vcxproj +++ b/iguana.vcxproj @@ -113,14 +113,14 @@ Level3 Disabled - _DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;NATIVE_WINDOWS;WIN32;ISNOTARYNODE=1;LIQUIDITY_PROVIDER=1;%(PreprocessorDefinitions) 1Byte Console true .\OSlibs\win\x64;%(AdditionalLibraryDirectories) - pthread_lib.lib;Ws2_32.lib;nanomsg.lib;libcurl.lib;%(AdditionalDependencies) + pthread_lib.lib;Ws2_32.lib;nanomsg.lib;libcurl.lib;libsodium.lib;%(AdditionalDependencies) @@ -151,7 +151,7 @@ MaxSpeed true true - WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;IGUANA_LOG2PACKETSIZE=20;IGUANA_MAXPACKETSIZE=1572864;%(PreprocessorDefinitions) + WIN64;_WIN64;_CRT_SECURE_NO_WARNINGS;NATIVE_WINDOWS;WIN32;_CONSOLE;NDEBUG;ISNOTARYNODE=1;LIQUIDITY_PROVIDER=1;%(PreprocessorDefinitions) 1Byte MultiThreaded @@ -160,7 +160,7 @@ true true true - Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\x64\pthread_lib.lib;libcurl.lib;nanomsg.lib;%(AdditionalDependencies) + Ws2_32.lib;Advapi32.lib;$(SolutionDir)OSlibs\win\x64\pthread_lib.lib;libcurl.lib;nanomsg.lib;libsodium.lib;%(AdditionalDependencies) .\OSlibs\win\x64\release;%(AdditionalLibraryDirectories) diff --git a/iguana/dpow/dpow_rpc.c b/iguana/dpow/dpow_rpc.c index f5700c1a5..487eb96e3 100755 --- a/iguana/dpow/dpow_rpc.c +++ b/iguana/dpow/dpow_rpc.c @@ -647,6 +647,9 @@ char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *c free_json(retjson); } //printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr); + + /*if (coin->sapling != 0) + printf("[Decker] %s dpow_signrawtransaction.(%s) params.(%s)\n", coin->symbol, retstr, paramstr);*/ free(paramstr); usleep(10000); return(retstr); diff --git a/iguana/dpow/dpow_tx.c b/iguana/dpow/dpow_tx.c index 148827d68..0bf6dfcd9 100755 --- a/iguana/dpow/dpow_tx.c +++ b/iguana/dpow/dpow_tx.c @@ -267,43 +267,64 @@ int32_t dpow_voutstandard(struct supernet_info *myinfo,struct dpow_block *bp,uin bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsigsp,int32_t isPoS,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t usesigs,int32_t src_or_dest,uint8_t pubkeys[][33],int32_t numratified) { uint32_t k,m,numsigs,version,vout,crcval,sequenceid = 0xffffffff; bits256 zero; int32_t n,siglen,len; uint8_t serialized[32768],*sig; bits256 txid; struct dpow_entry *ep; struct dpow_coinentry *cp; - signedtx[0] = 0; + // int32_t preimage_len; uint8_t preimage[32768]; // here we will create preimage, when usesigs=0 (?) + + struct iguana_info *coin = (src_or_dest != 0) ? bp->destcoin : bp->srccoin; + //printf("[Decker] dpow_notarytx: src.(%s) dst.(%s) src_or_dest.(%d) usesigs.(%d)\n", bp->srccoin->symbol, bp->destcoin->symbol, src_or_dest, usesigs); + + signedtx[0] = 0; *numsigsp = 0; memset(zero.bytes,0,sizeof(zero)); len = numsigs = 0; version = 1; - len += iguana_rwnum(1,&serialized[len],sizeof(version),&version); - if ( isPoS != 0 ) + + if (coin->sapling != 0) { + version = 4; + version = 1 << 31 | version; // overwintered + } + + len += iguana_rwnum(1,&serialized[len],sizeof(version),&version); + + if (coin->sapling != 0) { + uint32_t versiongroupid = 0x892f2085; // sapling + len += iguana_rwnum(1, &serialized[len], sizeof(versiongroupid), &versiongroupid); + } + + if ( isPoS != 0 ) len += iguana_rwnum(1,&serialized[len],sizeof(bp->timestamp),&bp->timestamp); m = bp->minsigs; len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&m); - for (k=m=0; knumnotaries; k++) + // -- vins -- + for (k=m=0; knumnotaries; k++) { siglen = 0; sig = 0; if ( ((1LL << k) & bestmask) != 0 ) { - if ( pubkeys != 0 && numratified > 0 ) + if ( pubkeys != 0 && numratified > 0 ) // state [1] { + //printf("[Decker] dpow_notarytx: state [1]\n"); if ( src_or_dest != 0 ) { txid = bp->notaries[k].ratifydestutxo; vout = bp->notaries[k].ratifydestvout; - } + } else { txid = bp->notaries[k].ratifysrcutxo; vout = bp->notaries[k].ratifysrcvout; } - if ( bestk >= 0 ) + + if ( bestk >= 0 ) // { siglen = bp->notaries[k].ratifysiglens[src_or_dest]; sig = bp->notaries[k].ratifysigs[src_or_dest]; } //char str[65]; printf("j.%d k.%d m.%d vin.(%s) v%d siglen.%d\n",j,k,m,bits256_str(str,txid),vout,siglen); } - else + else // state [2] { + //printf("[Decker] dpow_notarytx: state [2]\n"); ep = &bp->notaries[k]; cp = (src_or_dest != 0) ? &bp->notaries[k].dest : &bp->notaries[k].src; if ( bits256_nonz(cp->prev_hash) == 0 ) @@ -321,7 +342,8 @@ bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsi } len += iguana_rwbignum(1,&serialized[len],sizeof(txid),txid.bytes); len += iguana_rwnum(1,&serialized[len],sizeof(vout),&vout); - if ( usesigs != 0 && bestk >= 0 ) + + if ( usesigs != 0 && bestk >= 0 ) // usesigs=1 -> insert signature { len += iguana_rwvarint32(1,&serialized[len],(uint32_t *)&siglen); if ( siglen > 0 && siglen <= sizeof(cp->sigs[bestk]) ) @@ -330,7 +352,8 @@ bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsi len += siglen; numsigs++; } //else printf("%s -> %s src_or_dest.%d Missing sig from k.%d\n",bp->srccoin->symbol,bp->destcoin->symbol,src_or_dest,k); - } else serialized[len++] = 0; + } else serialized[len++] = 0; // usesigs=0 -> insert scriptlen = 0 + len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid); //printf("height.%d mod.%d VINI.%d <- i.%d j.%d\n",height,height % numnotaries,m,i,j); m++; @@ -338,13 +361,32 @@ bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsi break; } } + // -- vins -- if ( (n= dpow_voutstandard(myinfo,bp,&serialized[len],m,src_or_dest,pubkeys,numratified)) < 0 ) { printf("error dpow_voutstandard m.%d src_or_dest.%d\n",m,src_or_dest); return(zero); } len += n; + + if (coin->sapling != 0) { + uint32_t nExpiryHeight = 0; + uint64_t valueBalance = 0; + uint8_t nShieldedSpend = 0; + uint8_t nShieldedOutput = 0; + uint8_t nJoinSplit = 0; + len += iguana_rwnum(1, &serialized[len], sizeof(nExpiryHeight), &nExpiryHeight); + len += iguana_rwnum(1, &serialized[len], sizeof(valueBalance), &valueBalance); + len += iguana_rwnum(1, &serialized[len], sizeof(nShieldedSpend), &nShieldedSpend); // The number of Spend descriptions in vShieldedSpend + len += iguana_rwnum(1, &serialized[len], sizeof(nShieldedOutput), &nShieldedOutput); // The number of Output descriptions in vShieldedOutput + len += iguana_rwnum(1, &serialized[len], sizeof(nJoinSplit), &nJoinSplit); // The number of JoinSplit descriptions in vJoinSplit + } + + // here if usesigs=0 we have unsigned tx (not preimage), if usesigs=1 - we have signed tx with sigs from nn_bus network (?) + init_hexbytes_noT(signedtx,serialized,len); + //printf("[Decker] dpow_notarytx: signedtx.(%s)\n", signedtx); + //printf("notarytx.(%s) opretlen.%d\n",signedtx,opretlen); if ( usesigs == 0 && bestk >= 0 ) { @@ -393,6 +435,7 @@ cJSON *dpow_vins(struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uin item = cJSON_CreateObject(); jaddbits256(item,"txid",txid); jaddnum(item,"vout",vout); + jaddnum(item, "amount", dstr(dpow_utxosize(coin->symbol))); if ( k == 0 && bp->require0 != 0 ) { script[0] = 0x76; diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 8c88ec624..167d8543b 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -1066,6 +1066,7 @@ void iguana_nameset(char name[64],char *symbol,cJSON *json) struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json,int32_t virtcoin) { + // printf("[Decker] iguana_setcoin: [%s] %s", symbol, cJSON_Print(json)); struct iguana_chain *iguana_createchain(cJSON *json); struct supernet_info *myinfo = SuperNET_MYINFO(0); struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char name[64]; cJSON *peers; @@ -1134,7 +1135,15 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->enableCACHE = 1;//0;//(strcmp("BTCD",coin->symbol) == 0); if ( jobj(json,"cache") != 0 ) coin->enableCACHE = juint(json,"cache"); - if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) + + coin->sapling = 0; + if (jobj(json, "sapling") != 0) + { + coin->sapling = juint(json, "sapling"); + printf("[Decker] %s sapling = %d\n", symbol, coin->sapling); + } + + if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) coin->polltimeout = IGUANA_DEFAULT_POLLTIMEOUT; coin->active = juint(json,"active"); if ( (coin->minconfirms= minconfirms) == 0 ) diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 0ddd1c16f..39d1dd71d 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -600,7 +600,7 @@ int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized return(len); } -int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgjoinsplit *msg) +int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgjoinsplit *msg, uint32_t proof_size) { int32_t len = 0; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->vpub_old),&msg->vpub_old); @@ -620,9 +620,9 @@ int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgj len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[0]),msg->vmacs[0].bytes); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[1]),msg->vmacs[1].bytes); if ( rwflag == 1 ) - memcpy(&serialized[len],msg->zkproof,sizeof(msg->zkproof)); - else memcpy(msg->zkproof,&serialized[len],sizeof(msg->zkproof)); - len += sizeof(msg->zkproof); + memcpy(&serialized[len],msg->zkproof,proof_size); + else memcpy(msg->zkproof,&serialized[len],proof_size); + len += proof_size; return(len); } @@ -697,8 +697,14 @@ int32_t iguana_rwtx(struct supernet_info *myinfo,uint8_t zcash,int32_t rwflag,st len += iguana_rwvarint32(rwflag,&serialized[len],&numjoinsplits); if ( numjoinsplits > 0 ) { + // for version 4 the ZK proof size is 192, otherwise 296 + uint32_t zksnark_proof_size = ZKSNARK_PROOF_SIZE; + if (msg->version >= 4) { + zksnark_proof_size = GROTH_PROOF_SIZE; + } + for (i=0; irpcport ) @@ -703,9 +703,10 @@ struct iguana_info *iguana_coinchoose(struct supernet_info *myinfo,char *symbol, } else { - safecopy(symbol,jstr(json,"coin"),sizeof(symbol)); - for (i=0; symbol[i]!=0; i++) - symbol[i] = toupper((int32_t)symbol[i]); + safecopy(symbol, jstr(json, "coin"), symbol_len); // here was sizeof(symbol), but sizeof of pointer (char *) always = 8 + for (i = 0; symbol[i] != 0; i++) + symbol[i] = toupper((int32_t)symbol[i]); + } } else @@ -726,14 +727,14 @@ struct iguana_info *iguana_coinchoose(struct supernet_info *myinfo,char *symbol, char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr,uint16_t port) { - cJSON *params[16],*array; struct iguana_info *coin = 0; char symbol[16],*userpass; uint32_t immed; int32_t i,n; char *retstr = 0; + cJSON *params[16],*array; struct iguana_info *coin = 0; char symbol[64],*userpass; uint32_t immed; int32_t i,n; char *retstr = 0; symbol[0] = 0; memset(params,0,sizeof(params)); //printf("bitcoinRPC.(%s)\n",jprint(json,0)); if ( json != 0 ) { userpass = jstr(json,"userpass"); - coin = iguana_coinchoose(myinfo,symbol,json,port); + coin = iguana_coinchoose(myinfo,symbol, sizeof(symbol), json,port); if ( myinfo->rpcsymbol[0] == 0 ) strcpy(myinfo->rpcsymbol,symbol); if ( coin != 0 ) @@ -1089,7 +1090,7 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz if ( userpass != 0 && jstr(argjson,"userpass") == 0 ) jaddstr(argjson,"userpass",userpass); //printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0)); - coin = iguana_coinchoose(myinfo,symbol,argjson,port); + coin = iguana_coinchoose(myinfo,symbol, sizeof(symbol), argjson,port); if ( (retstr= SuperNET_JSON(myinfo,coin,argjson,remoteaddr,port)) != 0 ) { if ( (retitem= cJSON_Parse(retstr)) != 0 ) @@ -1111,7 +1112,7 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz arg = jitem(arg,0); } else arg = argjson; //printf("ARGJSON.(%s)\n",jprint(arg,0)); - coin = iguana_coinchoose(myinfo,symbol,arg,port); + coin = iguana_coinchoose(myinfo,symbol, sizeof(symbol), arg,port); if ( userpass != 0 && jstr(arg,"userpass") == 0 ) jaddstr(arg,"userpass",userpass); retstr = SuperNET_JSON(myinfo,coin,arg,remoteaddr,port); diff --git a/iguana/iguana_sign.c b/iguana/iguana_sign.c index 9255581b9..3d4f66cd4 100755 --- a/iguana/iguana_sign.c +++ b/iguana/iguana_sign.c @@ -15,9 +15,28 @@ #include "iguana777.h" #include "exchanges/bitcoin.h" +#include +const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[16] = +{ 'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h' }; +const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[16] = +{ 'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h' }; +const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[16] = +{ 'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h' }; +const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[16] = +{ 'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h' }; +const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[16] = +{ 'Z','c','a','s','h','S','S','p','e','n','d','s','H','a','s','h' }; +const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[16] = +{ 'Z','c','a','s','h','S','O','u','t','p','u','t','H','a','s','h' }; +const unsigned char ZCASH_SIG_HASH_SAPLING_PERSONALIZATION[16] = +{ 'Z','c','a','s','h','S','i','g','H','a','s','h', '\xBB', '\x09', '\xB8', '\x76' }; +const unsigned char ZCASH_SIG_HASH_OVERWINTER_PERSONALIZATION[16] = +{ 'Z','c','a','s','h','S','i','g','H','a','s','h', '\x19', '\x1B', '\xA8', '\x5B' }; -// make sure coinbase outputs are matured +int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgjoinsplit *msg, uint32_t proof_size); // defined in iguana_msg.c + +// make sure coinbase outputs are matured int32_t iguana_vinparse(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,struct iguana_msgvin *msg) { int32_t p2shlen,len = 0; uint32_t tmp; @@ -486,7 +505,7 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int3 return(json); } -bits256 bitcoin_sigtxid(struct iguana_info *coin,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr,int32_t suppress_pubkeys) +bits256 bitcoin_sigtxid(struct iguana_info *coin, int32_t height, uint8_t *serialized, int32_t maxlen, struct iguana_msgtx *msgtx, int32_t vini, uint8_t *spendscript, int32_t spendlen, uint64_t spendamount, int32_t hashtype, char *vpnstr, int32_t suppress_pubkeys) { int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; dest = *msgtx; @@ -500,42 +519,160 @@ bits256 bitcoin_sigtxid(struct iguana_info *coin,int32_t height,uint8_t *seriali printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); return(sigtxid); } - for (i=0; i 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && - { -#ifdef BTC2_VERSION - if ( height >= BTC2_HARDFORK_HEIGHT ) - hashtype |= (0x777 << 20); -#endif - len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); - revsigtxid = bits256_doublesha256(0,serialized,len); - for (i=0; i> 31; + uint32_t version = dest.version & 0x7FFFFFFF; + + if (overwintered && version >= 3) { + // sapling tx sighash preimage + len = 0; + uint8_t for_sig_hash[1000], sig_hash[32]; + len = iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.version), &dest.version); + len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.version_group_id), &dest.version_group_id); + uint8_t prev_outs[1000], hash_prev_outs[32]; + int32_t prev_outs_len = 0; + for (i = 0; i < dest.tx_in; i++) { + prev_outs_len += iguana_rwbignum(1, &prev_outs[prev_outs_len], sizeof(dest.vins[i].prev_hash), dest.vins[i].prev_hash.bytes); + prev_outs_len += iguana_rwnum(1, &prev_outs[prev_outs_len], sizeof(dest.vins[i].prev_vout), &dest.vins[i].prev_vout); + } + crypto_generichash_blake2b_salt_personal( + hash_prev_outs, + 32, + prev_outs, + (uint64_t)prev_outs_len, + NULL, + 0, + NULL, + ZCASH_PREVOUTS_HASH_PERSONALIZATION + ); + memcpy(&for_sig_hash[len], hash_prev_outs, 32); + len += 32; + + uint8_t sequence[1000], sequence_hash[32]; + int32_t sequence_len = 0; + + for (i = 0; i < dest.tx_in; i++) { + sequence_len += iguana_rwnum(1, &sequence[sequence_len], sizeof(dest.vins[i].sequence), + &dest.vins[i].sequence); + } + crypto_generichash_blake2b_salt_personal( + sequence_hash, + 32, + sequence, + (uint64_t)sequence_len, + NULL, + 0, + NULL, + ZCASH_SEQUENCE_HASH_PERSONALIZATION + ); + memcpy(&for_sig_hash[len], sequence_hash, 32); + len += 32; + + uint8_t outputs[1000], hash_outputs[32]; + int32_t outputs_len = 0; + for (i = 0; i < dest.tx_out; i++) { + outputs_len += iguana_rwnum(1, &outputs[outputs_len], sizeof(dest.vouts[i].value), &dest.vouts[i].value); + outputs[outputs_len++] = (uint8_t)dest.vouts[i].pk_scriptlen; + memcpy(&outputs[outputs_len], dest.vouts[i].pk_script, dest.vouts[i].pk_scriptlen); + outputs_len += dest.vouts[i].pk_scriptlen; + } + + crypto_generichash_blake2b_salt_personal( + hash_outputs, + 32, + outputs, + (uint64_t)outputs_len, + NULL, + 0, + NULL, + ZCASH_OUTPUTS_HASH_PERSONALIZATION + ); + memcpy(&for_sig_hash[len], hash_outputs, 32); + len += 32; + + // no join splits, fill the hashJoinSplits with 32 zeros + memset(&for_sig_hash[len], 0, 32); + len += 32; + if (version > 3) { + // no shielded spends, fill the hashShieldedSpends with 32 zeros + memset(&for_sig_hash[len], 0, 32); + len += 32; + // no shielded outputs, fill the hashShieldedOutputs with 32 zeros + memset(&for_sig_hash[len], 0, 32); + len += 32; + } + + len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.lock_time), &dest.lock_time); + len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.expiry_height), &dest.expiry_height); + if (version > 3) { + len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.value_balance), &dest.value_balance); + } + len += iguana_rwnum(1, &for_sig_hash[len], sizeof(hashtype), &hashtype); + + len += iguana_rwbignum(1, &for_sig_hash[len], sizeof(dest.vins[vini].prev_hash), dest.vins[vini].prev_hash.bytes); + len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.vins[vini].prev_vout), &dest.vins[vini].prev_vout); + + for_sig_hash[len++] = (uint8_t)spendlen; + memcpy(&for_sig_hash[len], spendscript, spendlen), len += spendlen; + len += iguana_rwnum(1, &for_sig_hash[len], sizeof(spendamount), &spendamount); + len += iguana_rwnum(1, &for_sig_hash[len], sizeof(dest.vins[vini].sequence), &dest.vins[vini].sequence); + unsigned const char *sig_hash_personal = ZCASH_SIG_HASH_OVERWINTER_PERSONALIZATION; + if (version == 4) { + sig_hash_personal = ZCASH_SIG_HASH_SAPLING_PERSONALIZATION; + } + + crypto_generichash_blake2b_salt_personal( + sig_hash, + 32, + for_sig_hash, + (uint64_t)len, + NULL, + 0, + NULL, + sig_hash_personal + ); + + for (i = 0; i<32; i++) + sigtxid.bytes[i] = sig_hash[i]; + + } + else { + for (i = 0; i 0) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 && + { + #ifdef BTC2_VERSION + if (height >= BTC2_HARDFORK_HEIGHT) + hashtype |= (0x777 << 20); + #endif + len += iguana_rwnum(1, &serialized[len], sizeof(hashtype), &hashtype); + revsigtxid = bits256_doublesha256(0, serialized, len); + for (i = 0; iversion),&msg->version); + int32_t i,n,len = 0,extraused=0; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE],*txstart = serialized,*sigser=0; char txidstr[65]; uint64_t spendamount; cJSON *vinarray=0,*voutarray=0; bits256 sigtxid; + + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); + uint32_t overwintered = msg->version >> 31; + uint32_t version = msg->version; + // for version 4 the ZK proof size is 192, otherwise 296 + uint32_t zksnark_proof_size = ZKSNARK_PROOF_SIZE; + if (coin->sapling != 0) { + if (overwintered) { + version = msg->version & 0x7FFFFFFF; + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->version_group_id), &msg->version_group_id); + if (version >= 4) { + zksnark_proof_size = GROTH_PROOF_SIZE; + } + } + } + if ( json != 0 ) { - jaddnum(json,"version",msg->version); + if (overwintered) { + jaddnum(json, "version", msg->version & 0x7FFFFFFF); + } + else { + jaddnum(json, "version", msg->version); + } + cJSON_AddBoolToObject(json, "overwintered", overwintered); + if (overwintered) { + char group_id_str[10]; + sprintf(group_id_str, "%x", msg->version_group_id); + jaddstr(json, "versiongroupid", group_id_str); + } + vinarray = cJSON_CreateArray(); voutarray = cJSON_CreateArray(); if ( rwflag == 0 ) @@ -674,7 +838,160 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ jaddi(voutarray,iguana_voutjson(coin,&msg->vouts[i],i,*txidp)); } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); -//printf("lock_time.%08x len.%d\n",msg->lock_time,len); + + if ((coin->sapling !=0) && overwintered) { + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->expiry_height), &msg->expiry_height); + if (json != 0) { + jaddnum(json, "expiryheight", msg->expiry_height); + } + if (version >= 4) { + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->value_balance), &msg->value_balance); + if (json != 0) { + jaddnum(json, "valueBalance", dstr(msg->value_balance)); + } + cJSON *v_shielded_spend = cJSON_CreateArray(); + cJSON *v_shielded_output = cJSON_CreateArray(); + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->shielded_spend_num), &msg->shielded_spend_num); + if (msg->shielded_spend_num > 0) { + if (extraused + sizeof(struct sapling_spend_description) * msg->shielded_spend_num > extralen) { + printf("extraused.%d + shielded_spend.%d > extralen.%d\n", extraused, msg->shielded_spend_num, + extralen); + return (-1); + } + msg->shielded_spends = (struct sapling_spend_description *) &extraspace[extraused]; + extraused += (sizeof(struct sapling_spend_description) * msg->shielded_spend_num); + for (i = 0; i < msg->shielded_spend_num; i++) { + len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_spends[i].cv), msg->shielded_spends[i].cv.bytes); + len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_spends[i].anchor), msg->shielded_spends[i].anchor.bytes); + len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_spends[i].nullifier), msg->shielded_spends[i].nullifier.bytes); + len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_spends[i].rk), msg->shielded_spends[i].rk.bytes); + if (rwflag == 1) { + memcpy(&serialized[len], msg->shielded_spends[i].zkproof, GROTH_PROOF_SIZE); + } + else { + memcpy(msg->shielded_spends[i].zkproof, &serialized[len], GROTH_PROOF_SIZE); + } + len += GROTH_PROOF_SIZE; + if (rwflag == 1) { + memcpy(&serialized[len], msg->shielded_spends[i].spend_auth_sig, SAPLING_AUTH_SIG_SIZE); + } + else { + memcpy(msg->shielded_spends[i].spend_auth_sig, &serialized[len], SAPLING_AUTH_SIG_SIZE); + } + len += SAPLING_AUTH_SIG_SIZE; + if (json != 0) { + cJSON *spend_item = cJSON_CreateObject(); + jaddbits256(spend_item, "cv", msg->shielded_spends[i].cv); + jaddbits256(spend_item, "anchor", msg->shielded_spends[i].anchor); + jaddbits256(spend_item, "nullifier", msg->shielded_spends[i].nullifier); + jaddbits256(spend_item, "rk", msg->shielded_spends[i].rk); + char proof_str[GROTH_PROOF_SIZE * 2 + 1]; + init_hexbytes_noT(proof_str, msg->shielded_spends[i].zkproof, GROTH_PROOF_SIZE); + jaddstr(spend_item, "proof", proof_str); + char auth_sig_str[SAPLING_AUTH_SIG_SIZE * 2 + 1]; + init_hexbytes_noT(auth_sig_str, msg->shielded_spends[i].spend_auth_sig, SAPLING_AUTH_SIG_SIZE); + jaddstr(spend_item, "spendAuthSig", auth_sig_str); + jaddi(v_shielded_spend, spend_item); + } + } + } + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->shielded_output_num), &msg->shielded_output_num); + if (msg->shielded_output_num > 0) { + if (extraused + sizeof(struct sapling_output_description) * msg->shielded_output_num > extralen) { + printf("extraused.%d + shielded_output.%d > extralen.%d\n", extraused, msg->shielded_output_num, + extralen); + return (-1); + } + msg->shielded_outputs = (struct sapling_output_description *) &extraspace[extraused]; + extraused += (sizeof(struct sapling_output_description) * msg->shielded_output_num); + for (i = 0; i < msg->shielded_output_num; i++) { + len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_outputs[i].cv), msg->shielded_outputs[i].cv.bytes); + len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_outputs[i].cm), msg->shielded_outputs[i].cm.bytes); + len += iguana_rwbignum(rwflag, &serialized[len], sizeof(msg->shielded_outputs[i].ephemeral_key), msg->shielded_outputs[i].ephemeral_key.bytes); + if (rwflag == 1) { + memcpy(&serialized[len], msg->shielded_outputs[i].enc_ciphertext, ENC_CIPHER_SIZE); + } + else { + memcpy(msg->shielded_outputs[i].enc_ciphertext, &serialized[len], ENC_CIPHER_SIZE); + } + len += ENC_CIPHER_SIZE; + if (rwflag == 1) { + memcpy(&serialized[len], msg->shielded_outputs[i].out_ciphertext, OUT_CIPHER_SIZE); + } + else { + memcpy(msg->shielded_outputs[i].out_ciphertext, &serialized[len], OUT_CIPHER_SIZE); + } + len += OUT_CIPHER_SIZE; + if (rwflag == 1) { + memcpy(&serialized[len], msg->shielded_outputs[i].zkproof, GROTH_PROOF_SIZE); + } + else { + memcpy(msg->shielded_outputs[i].zkproof, &serialized[len], GROTH_PROOF_SIZE); + } + len += GROTH_PROOF_SIZE; + if (json != 0) { + cJSON *output_item = cJSON_CreateObject(); + jaddbits256(output_item, "cv", msg->shielded_outputs[i].cv); + jaddbits256(output_item, "cmu", msg->shielded_outputs[i].cm); + jaddbits256(output_item, "ephemeralKey", msg->shielded_outputs[i].ephemeral_key); + char enc_cip_str[ENC_CIPHER_SIZE * 2 + 1]; + init_hexbytes_noT(enc_cip_str, msg->shielded_outputs[i].enc_ciphertext, ENC_CIPHER_SIZE); + jaddstr(output_item, "encCiphertext", enc_cip_str); + char out_cip_str[OUT_CIPHER_SIZE * 2 + 1]; + init_hexbytes_noT(out_cip_str, msg->shielded_outputs[i].out_ciphertext, OUT_CIPHER_SIZE); + jaddstr(output_item, "outCiphertext", out_cip_str); + jaddi(v_shielded_output, output_item); + char proof_str[GROTH_PROOF_SIZE * 2 + 1]; + init_hexbytes_noT(proof_str, msg->shielded_outputs[i].zkproof, GROTH_PROOF_SIZE); + jaddstr(output_item, "proof", proof_str); + } + } + } + if (json != 0) { + cJSON_AddItemToObject(json, "vShieldedSpend", v_shielded_spend); + cJSON_AddItemToObject(json, "vShieldedOutput", v_shielded_output); + } + } + } + //printf("lock_time.%08x len.%d\n",msg->lock_time,len); + + if ((coin->sapling != 0) && msg->version > 1) + { + struct iguana_msgjoinsplit joinsplit; uint8_t joinsplitpubkey[33], joinsplitsig[64]; + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->numjoinsplits), &msg->numjoinsplits); + if (msg->numjoinsplits > 0) + { + for (i = 0; inumjoinsplits; i++) + len += iguana_rwjoinsplit(rwflag, &serialized[len], &joinsplit, zksnark_proof_size); + if (rwflag != 0) + { + memset(joinsplitpubkey, 0, sizeof(joinsplitpubkey)); // for now + memset(joinsplitsig, 0, sizeof(joinsplitsig)); // set to actuals + memcpy(&serialized[len], joinsplitpubkey + 1, 32), len += 32; + memcpy(&serialized[len], joinsplitsig, 64), len += 64; + } + else + { + joinsplitpubkey[0] = 0x02; // need to verify its not 0x03 + memcpy(joinsplitpubkey + 1, &serialized[len], 32), len += 32; + memcpy(joinsplitsig, &serialized[len], 64), len += 64; + } + } + } + if ((coin->sapling != 0) && msg->version >= 4 && !(msg->shielded_spend_num == 0 && msg->shielded_output_num == 0)) { + if (rwflag == 1) { + memcpy(&serialized[len], msg->binding_sig, 64), len += 64; + } + else { + memcpy(msg->binding_sig, &serialized[len], 64), len += 64; + } + if (json != 0) { + char binding_sig_str[64 * 2 + 1]; + init_hexbytes_noT(binding_sig_str, msg->binding_sig, 64); + jaddstr(json, "bindingSig", binding_sig_str); + } + } + if ( strcmp(coin->symbol,"VPN") == 0 ) { uint16_t ddosflag = 0; @@ -702,9 +1019,19 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ memset(sigtxid.bytes,0,sizeof(sigtxid)); if ( vins != 0 && jitem(vins,i) != 0 ) { + uint32_t sighash = SIGHASH_ALL; // in marketmaker we use LP_sighash(symbol,zcash) to determine sighash (depends on zcash type), but here SIGHASH_ALL is enough for now + iguana_vinobjset(&msg->vins[i],jitem(vins,i),spendscript,sizeof(spendscript)); - sigtxid = bitcoin_sigtxid(coin,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr,suppress_pubkeys); - //printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); + + struct supernet_info *myinfo = SuperNET_MYINFO(0); cJSON *jtxout = 0; + jtxout = dpow_gettxout(0, coin, msg->vins[i].prev_hash, msg->vins[i].prev_vout); + spendamount = jdouble(jtxout, "value") * SATOSHIDEN; + //printf("JSON (txout): %s\n", cJSON_Print(jtxout)); + //printf("spendamount = %.8f\n", dstr(spendamount)); + free(jtxout); + + sigtxid = bitcoin_sigtxid(coin,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,spendamount, SIGHASH_ALL,vpnstr,suppress_pubkeys); + // printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); if ( iguana_vinarray_check(vinarray,msg->vins[i].prev_hash,msg->vins[i].prev_vout) < 0 ) jaddi(vinarray,iguana_vinjson(coin,&msg->vins[i],sigtxid)); if ( msg->vins[i].spendscript == spendscript ) @@ -745,7 +1072,19 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin, vpnstr[0] = 0; if ( (msg->version= juint(txobj,"version")) == 0 ) msg->version = 1; + if (is_cJSON_True(cJSON_GetObjectItem(txobj, "overwintered"))) { + msg->version = 1 << 31 | msg->version; + //msg->version_group_id = (uint32_t)strtol(jstr(txobj, "versiongroupid"), NULL, 16); + msg->version_group_id = strtoul(jstr(txobj, "versiongroupid"), NULL, 16); + msg->expiry_height = juint(txobj, "expiryheight"); + if (msg->version >= 4) { + msg->value_balance = (uint64_t)(jdouble(txobj, "valueBalance") * SATOSHIDEN); + } + } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); + if (is_cJSON_True(cJSON_GetObjectItem(txobj, "overwintered"))) { + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->version_group_id), &msg->version_group_id); + } if ( coin->chain->isPoS != 0 ) { if ( (msg->timestamp= juint(txobj,"timestamp")) == 0 ) @@ -793,11 +1132,22 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin, } msg->lock_time = jint(txobj,"locktime"); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + if (is_cJSON_True(cJSON_GetObjectItem(txobj, "overwintered"))) { + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->expiry_height), &msg->expiry_height); + if (msg->version >= 4) { + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->value_balance), &msg->value_balance); + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->shielded_spend_num), &msg->shielded_spend_num); + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->shielded_output_num), &msg->shielded_output_num); + } + len += iguana_rwnum(rwflag, &serialized[len], sizeof(msg->numjoinsplits), &msg->numjoinsplits); + } //msg->txid = jbits256(txobj,"txid"); *txstartp = 0; msg->allocsize = len; - msg->txid = txid = bits256_doublesha256(0,serialized,len); - return(txid); + + msg->txid = txid = bits256_doublesha256(0,serialized,len); // bits256_calctxid(coin->symbol, serialized, len); + + return(txid); } char *iguana_rawtxbytes(struct iguana_info *coin,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys) @@ -976,7 +1326,7 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,uint32_t sighash,int32_t signtx,int32_t suppress_pubkeys) { - bits256 sigtxid; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs; + bits256 sigtxid; uint8_t *sig,*script; struct vin_info *vp; char vpnstr[64]; int32_t scriptlen,complete=0,j,vini=0,flag=0,siglen,numvouts,numsigs; uint64_t spendamount; numvouts = msgtx->tx_out; vpnstr[0] = 0; *signedtx = 0; @@ -994,7 +1344,15 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *sign script = msgtx->vins[vini].spendscript; scriptlen = msgtx->vins[vini].spendlen; } - sigtxid = bitcoin_sigtxid(coin,height,serialized,maxlen,msgtx,vini,script,scriptlen,sighash,vpnstr,suppress_pubkeys); + + struct supernet_info *myinfo = SuperNET_MYINFO(0); cJSON *jtxout = 0; + jtxout = dpow_gettxout(0, coin, msgtx->vins[vini].prev_hash, msgtx->vins[vini].prev_vout); + spendamount = jdouble(jtxout, "value") * SATOSHIDEN; + //printf("JSON (txout): %s\n", cJSON_Print(jtxout)); + //printf("spendamount = %.8f\n", dstr(spendamount)); + free(jtxout); + + sigtxid = bitcoin_sigtxid(coin,height,serialized,maxlen,msgtx,vini,script,scriptlen,spendamount,sighash,vpnstr,suppress_pubkeys); if ( bits256_nonz(sigtxid) != 0 ) { vp = &V[vini]; @@ -1271,18 +1629,31 @@ cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_ return(txobj); } -cJSON *bitcoin_txcreate(char *symbol,int32_t isPoS,int64_t locktime,uint32_t txversion,uint32_t timestamp) +cJSON *bitcoin_txcreate(char *symbol, int32_t isPoS, int64_t locktime, uint32_t txversion, uint32_t timestamp) { - cJSON *json = cJSON_CreateObject(); - jaddnum(json,"version",txversion); - if ( locktime == 0 && strcmp(symbol,"KMD") == 0 ) - locktime = (uint32_t)time(NULL) - 55; - jaddnum(json,"locktime",locktime); - if ( isPoS != 0 ) - jaddnum(json,"timestamp",timestamp == 0 ? time(NULL) : timestamp); - jadd(json,"vin",cJSON_CreateArray()); - jadd(json,"vout",cJSON_CreateArray()); - return(json); + cJSON *json = cJSON_CreateObject(); + jaddnum(json, "version", txversion); + if (txversion >= 3) { + cJSON_AddBoolToObject(json, "overwintered", 1); + jaddnum(json, "expiryheight", 0); + if (txversion == 3) { + jaddstr(json, "versiongroupid", "03c48270"); + } + else if (txversion == 4) { + jaddstr(json, "versiongroupid", "892f2085"); + jaddnum(json, "valueBalance", 0.); + jadd(json, "vShieldedSpend", cJSON_CreateArray()); + jadd(json, "vShieldedOutput", cJSON_CreateArray()); + } + } + if (locktime == 0 && strcmp(symbol, "KMD") == 0) + locktime = (uint32_t)time(NULL) - 55; + jaddnum(json, "locktime", locktime); + if (isPoS != 0) + jaddnum(json, "timestamp", timestamp == 0 ? time(NULL) : timestamp); + jadd(json, "vin", cJSON_CreateArray()); + jadd(json, "vout", cJSON_CreateArray()); + return(json); } cJSON *bitcoin_txoutput(cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis) diff --git a/iguana/m_LP b/iguana/m_LP index 0e1135b48..1f73edd7d 100755 --- a/iguana/m_LP +++ b/iguana/m_LP @@ -6,4 +6,4 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana gcc -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c gcc -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm -lsodium diff --git a/iguana/m_LP_StaticNanoMsg b/iguana/m_LP_StaticNanoMsg index d2d295351..21afde2ed 100755 --- a/iguana/m_LP_StaticNanoMsg +++ b/iguana/m_LP_StaticNanoMsg @@ -10,4 +10,4 @@ clang -g -DNOTETOMIC -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_ clang -g -DNOTETOMIC -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 -DUSE_STATIC_NANOMSG main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c -clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a ../OSlibs/linux/$(uname -m)/libnanomsg-static.a -lcurl -lssl -lcrypto -lpthread -lz -lm -lanl -lrt -lnsl +clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a ../OSlibs/linux/$(uname -m)/libnanomsg-static.a -lcurl -lssl -lcrypto -lpthread -lz -lm -lanl -lrt -lnsl -lsodium diff --git a/iguana/m_notary_build b/iguana/m_notary_build new file mode 100755 index 000000000..c752f97ce --- /dev/null +++ b/iguana/m_notary_build @@ -0,0 +1,8 @@ +#!/bin/bash +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_LP; cd ../iguana +#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +#gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm -lsodium diff --git a/iguana/m_notary_run b/iguana/m_notary_run index 3991f1399..0f1632dae 100755 --- a/iguana/m_notary_run +++ b/iguana/m_notary_run @@ -8,7 +8,7 @@ cd ../crypto777; ./m_LP; cd ../iguana clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c #gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm +clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm -lsodium iguana_arg=${2:-notary} stdbuf -oL $1 ../agents/iguana $iguana_arg & #> iguana.log 2> error.log & diff --git a/iguana/m_notary_testnet b/iguana/m_notary_testnet index 0e377a239..9064bbb7e 100755 --- a/iguana/m_notary_testnet +++ b/iguana/m_notary_testnet @@ -6,7 +6,7 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c -clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm +clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm -lsodium wget -qO testnet https://raw.githubusercontent.com/KomodoPlatform/vote2018/master/testnet/testnet.json ../agents/iguana testnet & #> iguana.log 2> error.log & myip=`curl -s4 checkip.amazonaws.com` diff --git a/iguana/m_test b/iguana/m_test index 8bf7b041b..a0069904a 100755 --- a/iguana/m_test +++ b/iguana/m_test @@ -7,4 +7,4 @@ cd secp256k1; ./m_unix; cd .. cd ../crypto777; ./m_LP; cd ../iguana gcc -DNOTARY_TESTMODE=$TESTIPADDR -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c gcc -DNOTARY_TESTMODE=$TESTIPADDR -g -Wno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c iguana_ramchain.c -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a /usr/local/lib/libnanomsg.so -lcurl -lssl -lcrypto -lpthread -lz -lm -lsodium diff --git a/iguana_build_depends.cmd b/iguana_build_depends.cmd new file mode 100644 index 000000000..7f8976510 --- /dev/null +++ b/iguana_build_depends.cmd @@ -0,0 +1,71 @@ +@echo off +rem [ Decker] Automatically download and build depends script for marketmaker. +rem +rem 1. Requires installed CMake for Windows (!) +rem 2. Currently build only 64-bit release versions of .lib and .dll +rem 3. Libraries available: pthreads, nanomsg, curl + +@REM Check for Visual Studio +call set "VSPATH=" +if defined VS140COMNTOOLS ( if not defined VSPATH ( + call set "VSPATH=%%VS140COMNTOOLS%%" +) ) + +@REM check if we already have the tools in the environment +if exist "%VCINSTALLDIR%" ( + goto compile +) + +if not defined VSPATH ( + echo You need Microsoft Visual Studio 15 installed + pause + exit +) + +@REM set up the environment +if exist "%VSPATH%..\..\vc\vcvarsall.bat" ( + call "%%VSPATH%%..\..\vc\vcvarsall.bat" amd64 + goto compile +) + +echo Unable to set up the environment +pause +exit + +:compile +rem MSBuild /help +echo. +echo Decker will automatically download and build all needed *.dll and *.lib for you ;) + +mkdir iguana_depends +mkdir x64\Release + +rem --- libsodium --- +rem https://libsodium.gitbook.io/doc/installation + +:compile_libsodium + +if not exist iguana_depends\libsodium\bin\x64\Release\v140\dynamic\libsodium.lib ( +cd iguana_depends +git clone https://github.com/jedisct1/libsodium +cd libsodium +cd "builds\msvc\vs2015" +MSBuild libsodium.sln /t:Rebuild /p:Configuration=DynRelease /p:Platform=x64 +MSBuild libsodium.sln /t:Rebuild /p:Configuration=DynDebug /p:Platform=x64 +cd ../../.. +cd .. +) + +copy iguana_depends\libsodium\bin\x64\Release\v140\dynamic\libsodium.lib OSlibs\win\x64\release\libsodium.lib +copy iguana_depends\libsodium\bin\x64\Release\v140\dynamic\libsodium.exp OSlibs\win\x64\release\libsodium.exp +copy iguana_depends\libsodium\bin\x64\Release\v140\dynamic\libsodium.dll x64\Release\libsodium.dll + +rem mkdir OSlibs\win\x64\debug +rem libs for configuration: Debug stored in OSlibs\win\x64 (check .sln) +copy iguana_depends\libsodium\bin\x64\Debug\v140\dynamic\libsodium.lib OSlibs\win\x64\libsodium.lib +copy iguana_depends\libsodium\bin\x64\Debug\v140\dynamic\libsodium.exp OSlibs\win\x64\libsodium.exp +copy iguana_depends\libsodium\bin\x64\Debug\v140\dynamic\libsodium.dll x64\Debug\libsodium.dll + +mkdir includes\sodium +xcopy /E /Y iguana_depends\libsodium\src\libsodium\include\sodium includes\sodium +copy iguana_depends\libsodium\src\libsodium\include\sodium.h includes\ \ No newline at end of file diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h index 02939a582..287a53f3c 100755 --- a/includes/iguana_structs.h +++ b/includes/iguana_structs.h @@ -106,7 +106,14 @@ struct iguana_msgblockhdr uint32_t timestamp,bits,nonce; } PACKEDSTRUCT; +#define LP_IS_ZCASHPROTOCOL 1 + +#define SIGHASH_FORKID 0x40 #define ZKSNARK_PROOF_SIZE 296 +#define GROTH_PROOF_SIZE 192 +#define SAPLING_AUTH_SIG_SIZE 64 +#define ENC_CIPHER_SIZE 580 +#define OUT_CIPHER_SIZE 80 #define ZCASH_SOLUTION_ELEMENTS 1344 struct iguana_msgzblockhdr @@ -161,15 +168,20 @@ struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_scrip struct iguana_msgtx { - uint32_t version,tx_in,tx_out,lock_time; - struct iguana_msgvin *vins; - struct iguana_msgvout *vouts; - bits256 txid; - int32_t allocsize,timestamp,numinputs,numoutputs; - int64_t inputsum,outputsum,txfee; - uint8_t *serialized; + uint32_t version, version_group_id, tx_in, tx_out, lock_time, expiry_height; + struct iguana_msgvin *vins; + struct iguana_msgvout *vouts; + struct sapling_spend_description *shielded_spends; + struct sapling_output_description *shielded_outputs; + bits256 txid; + int32_t allocsize, timestamp, numinputs, numoutputs; + int64_t inputsum, outputsum, txfee; + uint8_t *serialized, shielded_spend_num, shielded_output_num, numjoinsplits; + uint64_t value_balance; + uint8_t binding_sig[64]; };// PACKEDSTRUCT; + struct iguana_msgjoinsplit { uint64_t vpub_old,vpub_new; @@ -179,6 +191,17 @@ struct iguana_msgjoinsplit uint8_t ciphertexts[2][601]; }PACKEDSTRUCT; +struct sapling_spend_description { + bits256 cv, anchor, nullifier, rk; + uint8_t zkproof[GROTH_PROOF_SIZE], spend_auth_sig[SAPLING_AUTH_SIG_SIZE]; +}; + +struct sapling_output_description { + bits256 cv, cm, ephemeral_key; + uint8_t zkproof[GROTH_PROOF_SIZE], enc_ciphertext[ENC_CIPHER_SIZE], out_ciphertext[OUT_CIPHER_SIZE]; +}; + + struct iguana_packet { struct queueitem DL; struct iguana_peer *addr; struct tai embargo; int32_t datalen,getdatablock; uint8_t serialized[]; }; struct msgcounts { uint32_t version,verack,getaddr,addr,inv,getdata,notfound,getblocks,getheaders,headers,tx,block,mempool,ping,pong,reject,filterload,filteradd,filterclear,merkleblock,alert; }; @@ -499,7 +522,7 @@ struct iguana_info uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100]; uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles; - int32_t MoMoMheight,MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,numemit,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,FULLNODE,VALIDATENODE,origbalanceswritten,balanceswritten,lastRTheight,RTdatabad; + int32_t MoMoMheight,MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,numemit,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,FULLNODE,VALIDATENODE,origbalanceswritten,balanceswritten,lastRTheight,RTdatabad,sapling; bits256 balancehash,allbundles; uint32_t lastsync,parsetime,numiAddrs,lastpossible,bundlescount,savedblocks,backlog,spendvectorsaved,laststats,lastinv2,symbolcrc,spendvalidated; char VALIDATEDIR[512]; int32_t longestchain,badlongestchain,longestchain_strange,RTramchain_busy,emitbusy,stuckiters,virtualchain,RTheight,RTreset_needed;