diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index b0b4b2e86..39c49c775 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -865,7 +865,7 @@ int32_t basilisk_issued_purge(struct supernet_info *myinfo,int32_t timepad) void basilisks_loop(void *arg) { static uint32_t counter; - struct iguana_info *relay; struct supernet_info *myinfo = arg; int32_t iter; double startmilli,endmilli; + struct iguana_info *relay; struct supernet_info *myinfo = arg; int32_t iter; double startmilli,endmilli; struct dpow_info *dp; iter = 0; relay = iguana_coinfind("RELAY"); printf("start basilisk loop\n"); @@ -880,8 +880,14 @@ void basilisks_loop(void *arg) { if ( relay != 0 ) basilisk_ping_send(myinfo,relay); - if ( (counter++ % 10) == 0 && myinfo->DPOW.symbol[0] != 0 && myinfo->DPOW.dest[0] != 0 ) - iguana_dPoWupdate(myinfo); + counter++; + if ( (counter % 10) == 0 && myinfo->numdpows == 1 ) + iguana_dPoWupdate(myinfo,&myinfo->DPOWS[0]); + else if ( myinfo->numdpows > 1 ) + { + dp = &myinfo->DPOWS[counter % myinfo->numdpows]; + iguana_dPoWupdate(myinfo,dp); + } endmilli = startmilli + 500; } else if ( myinfo->IAMLP != 0 ) diff --git a/iguana/dPoW.h b/iguana/dPoW.h index fdeac51c4..08cb0e158 100755 --- a/iguana/dPoW.h +++ b/iguana/dPoW.h @@ -16,7 +16,6 @@ #ifndef INCLUDE_DPOW_H #define INCLUDE_DPOW_H -#define DPOW_MAXBLOCKS 10000000 #define DPOW_CHECKPOINTFREQ 10 #define DPOW_MINSIGS 7 #define DPOW_M(bp) ((bp)->minsigs) // (((bp)->numnotaries >> 1) + 1) @@ -110,7 +109,7 @@ struct dpow_info struct dpow_hashheight approved[DPOW_FIFOSIZE],notarized[DPOW_FIFOSIZE]; bits256 srctx[DPOW_MAXTX],desttx[DPOW_MAXTX]; uint32_t destupdated,srcconfirms,numdesttx,numsrctx,lastsplit,cancelratify,crcs[1024]; - int32_t sock; + int32_t sock,maxblocks; struct dpow_block **blocks; }; diff --git a/iguana/dpow/dpow_fsm.c b/iguana/dpow/dpow_fsm.c index e410e09bc..b184552f4 100755 --- a/iguana/dpow/dpow_fsm.c +++ b/iguana/dpow/dpow_fsm.c @@ -96,32 +96,32 @@ void dpow_utxosync(struct supernet_info *myinfo,struct dpow_block *bp,uint64_t r } } -void dpow_sync(struct supernet_info *myinfo,struct dpow_block *bp,uint64_t refmask,int32_t myind,bits256 srchash,uint32_t channel,int32_t src_or_dest) +void dpow_sync(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint64_t refmask,int32_t myind,bits256 srchash,uint32_t channel,int32_t src_or_dest) { int8_t lastk; uint64_t mask; mask = dpow_maskmin(refmask,bp,&lastk); //dpow_utxosync(myinfo,bp,mask,myind,srchash); if ( bp->notaries[myind].masks[lastk] == 0 ) - dpow_signedtxgen(myinfo,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,lastk,mask,myind,src_or_dest != 0 ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL,src_or_dest); + dpow_signedtxgen(myinfo,dp,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,lastk,mask,myind,src_or_dest != 0 ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL,src_or_dest); } -int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t height,uint8_t *data,int32_t datalen) +int32_t dpow_datahandler(struct supernet_info *myinfo,struct dpow_info *dp,uint32_t channel,uint32_t height,uint8_t *data,int32_t datalen) { bits256 txid,commit,srchash; struct dpow_block *bp = 0; uint32_t flag = 0; int32_t src_or_dest,senderind,i,myind = -1; char str[65],str2[65]; struct dpow_sigentry dsig; struct dpow_entry *ep; struct dpow_coinentry *cp; struct dpow_utxoentry U; struct iguana_info *coin; - if ( (bp= dpow_heightfind(myinfo,height)) == 0 ) + if ( (bp= dpow_heightfind(myinfo,dp,height)) == 0 ) { if ( (rand() % 100) == 0 ) printf("couldnt find height.%d | if you just started notary dapp this is normal\n",height); return(-1); } - dpow_notaryfind(myinfo,bp,&myind,myinfo->DPOW.minerkey33); + dpow_notaryfind(myinfo,bp,&myind,dp->minerkey33); if ( myind < 0 ) { printf("couldnt find myind height.%d | this means your pubkey for this node is not registered and needs to be ratified by majority vote of all notaries\n",height); return(-1); } for (i=0; i<32; i++) - srchash.bytes[i] = myinfo->DPOW.minerkey33[i+1]; + srchash.bytes[i] = dp->minerkey33[i+1]; if ( channel == DPOW_UTXOCHANNEL ) { src_or_dest = 1; @@ -145,7 +145,7 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t dpow_utxosync(myinfo,bp,0,myind,srchash); bp->recvmask |= (1LL << senderind); } - dpow_sync(myinfo,bp,ep->recvmask,myind,srchash,channel,src_or_dest); + dpow_sync(myinfo,dp,bp,ep->recvmask,myind,srchash,channel,src_or_dest); flag = 1; } //if ( 0 && flag == 0 && bp != 0 ) @@ -189,7 +189,7 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t bp->destsigsmasks[dsig.lastk] |= (1LL << dsig.senderind); if ( bp->bestk >= 0 && bp->bestk == dsig.lastk && (bp->bestmask & bp->destsigsmasks[dsig.lastk]) == bp->bestmask ) { - dpow_sigscheck(myinfo,bp,DPOW_SIGBTCCHANNEL,myind,1); + dpow_sigscheck(myinfo,dp,bp,DPOW_SIGBTCCHANNEL,myind,1); } } else @@ -197,11 +197,11 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t bp->srcsigsmasks[dsig.lastk] |= (1LL << dsig.senderind); if ( bp->bestk >= 0 && bp->bestk == dsig.lastk && (bp->bestmask & bp->srcsigsmasks[dsig.lastk]) == bp->bestmask ) { - dpow_sigscheck(myinfo,bp,DPOW_SIGCHANNEL,myind,0); + dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0); } } printf(" (%d %llx) <<<<<<<< %s from.%d got lastk.%d %llx/%llx siglen.%d >>>>>>>>>\n",bp->bestk,(long long)bp->bestmask,coin->symbol,dsig.senderind,dsig.lastk,(long long)dsig.mask,(long long)bp->destsigsmasks[dsig.lastk],dsig.siglen); - dpow_sync(myinfo,bp,dsig.mask,myind,srchash,channel,src_or_dest); + dpow_sync(myinfo,dp,bp,dsig.mask,myind,srchash,channel,src_or_dest); flag = 1; } } else printf("%s pubkey mismatch for senderind.%d %llx vs %llx\n",coin->symbol,dsig.senderind,*(long long *)dsig.senderpub,*(long long *)bp->notaries[dsig.senderind].pubkey); @@ -236,9 +236,9 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t { bp->desttxid = txid; bp->state = 1000; - myinfo->DPOW.destupdated = 0; - dpow_signedtxgen(myinfo,bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,0); - //dpow_sigscheck(myinfo,bp,DPOW_SIGCHANNEL,myind,0); + dp->destupdated = 0; + dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,0); + //dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0); } else { @@ -258,7 +258,7 @@ int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t return(0); } -int32_t dpow_update(struct supernet_info *myinfo,struct dpow_block *bp,uint32_t txidchannel,bits256 srchash,int32_t myind) +int32_t dpow_update(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint32_t txidchannel,bits256 srchash,int32_t myind) { struct dpow_entry *ep; int32_t i,k,len,src_or_dest,sendutxo = 0; uint8_t data[sizeof(struct dpow_entry)+2]; struct dpow_utxoentry U; ep = &bp->notaries[myind]; @@ -281,7 +281,7 @@ int32_t dpow_update(struct supernet_info *myinfo,struct dpow_block *bp,uint32_t } } if ( ep->masks[src_or_dest][bp->bestk] == 0 ) - dpow_signedtxgen(myinfo,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGBTCCHANNEL,src_or_dest); + dpow_signedtxgen(myinfo,dp,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGBTCCHANNEL,src_or_dest); //else dpow_sigsend(myinfo,bp,myind,bp->bestk,bp->bestmask,srchash,sigchannel); } else sendutxo = 1; if ( sendutxo != 0 ) @@ -292,25 +292,25 @@ int32_t dpow_update(struct supernet_info *myinfo,struct dpow_block *bp,uint32_t dpow_send(myinfo,bp,srchash,bp->hashmsg,DPOW_UTXOCHANNEL,bp->height,data,len,bp->utxocrcs); } if ( ep->masks[src_or_dest][bp->bestk] == 0 ) - dpow_signedtxgen(myinfo,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGBTCCHANNEL,src_or_dest); + dpow_signedtxgen(myinfo,dp,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGBTCCHANNEL,src_or_dest); //else dpow_sigsend(myinfo,bp,myind,bp->bestk,bp->bestmask,srchash,sigchannel); } else if ( bp->state != 0xffffffff ) { src_or_dest = 0; if ( ep->masks[src_or_dest][bp->bestk] == 0 ) - dpow_signedtxgen(myinfo,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,src_or_dest); + dpow_signedtxgen(myinfo,dp,(src_or_dest != 0) ? bp->destcoin : bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,src_or_dest); //else dpow_sigsend(myinfo,bp,myind,bp->bestk,bp->bestmask,srchash,sigchannel); } if ( (rand() % 10) == 0 ) printf("[%d] %s ht.%d FSM.%08x masks.%llx best.(%d %llx) sigsmask.%llx %llx src.%llx\n",myind,src_or_dest != 0 ? bp->destcoin->symbol : bp->srccoin->symbol,bp->height,bp->state,(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask,(long long)bp->destsigsmasks[bp->bestk],(long long)(bp->destsigsmasks[bp->bestk] & bp->bestmask),(long long)bp->srcsigsmasks[bp->bestk]); if ( bp->state < 1000 && bp->bestk >= 0 && (bp->destsigsmasks[bp->bestk] & bp->bestmask) == bp->bestmask ) { - dpow_sigscheck(myinfo,bp,DPOW_SIGBTCCHANNEL,myind,1); + dpow_sigscheck(myinfo,dp,bp,DPOW_SIGBTCCHANNEL,myind,1); } else if ( bp->state != 0xffffffff && bp->bestk >= 0 && (bp->srcsigsmasks[bp->bestk] & bp->bestmask) == bp->bestmask ) { - dpow_sigscheck(myinfo,bp,DPOW_SIGCHANNEL,myind,0); + dpow_sigscheck(myinfo,dp,bp,DPOW_SIGCHANNEL,myind,0); } return(bp->state); } @@ -335,11 +335,11 @@ uint32_t dpow_statemachineiterate(struct supernet_info *myinfo,struct dpow_info txidchannel = DPOW_TXIDCHANNEL; opret_symbol = dp->symbol; } - bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->DPOW.minerkey33,33); + bitcoin_address(coinaddr,coin->chain->pubtype,dp->minerkey33,33); if ( bits256_nonz(bp->hashmsg) == 0 && bp->height != 0 ) return(0); for (j=0; jDPOW.minerkey33[j+1]; + srchash.bytes[j] = dp->minerkey33[j+1]; bp->bestk = dpow_bestk(bp,&bp->bestmask); if ( bp->state < 7 ) { @@ -348,21 +348,21 @@ uint32_t dpow_statemachineiterate(struct supernet_info *myinfo,struct dpow_info } else { - dpow_update(myinfo,bp,txidchannel,srchash,myind); + dpow_update(myinfo,dp,bp,txidchannel,srchash,myind); if ( bits256_nonz(bp->srctxid) != 0 ) bp->state = 0xffffffff; } return(bp->state); } -int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_block *bp,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr) +int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,char *coinaddr) { int32_t haveutxo,completed; bits256 signedtxid; cJSON *addresses; char *rawtx,*sendtx; - if ( (haveutxo= dpow_haveutxo(myinfo,coin,txidp,voutp,coinaddr)) <= 10 && time(NULL) > myinfo->DPOW.lastsplit+bp->duration ) + if ( (haveutxo= dpow_haveutxo(myinfo,coin,txidp,voutp,coinaddr)) <= 10 && time(NULL) > dp->lastsplit+bp->duration ) { addresses = cJSON_CreateArray(); jaddistr(addresses,coinaddr); - if ( (rawtx= iguana_utxoduplicates(myinfo,coin,myinfo->DPOW.minerkey33,DPOW_UTXOSIZE,strcmp(coin->symbol,"BTC") == 0 ? 50 : 10,&completed,&signedtxid,0,addresses)) != 0 ) + if ( (rawtx= iguana_utxoduplicates(myinfo,coin,dp->minerkey33,DPOW_UTXOSIZE,strcmp(coin->symbol,"BTC") == 0 ? 50 : 10,&completed,&signedtxid,0,addresses)) != 0 ) { if ( (sendtx= dpow_sendrawtransaction(myinfo,coin,rawtx)) != 0 ) { @@ -372,7 +372,7 @@ int32_t dpow_checkutxo(struct supernet_info *myinfo,struct dpow_block *bp,struct free(rawtx); } free_json(addresses); - myinfo->DPOW.lastsplit = (uint32_t)time(NULL); + dp->lastsplit = (uint32_t)time(NULL); } if ( bits256_nonz(*txidp) == 0 ) return(-1); @@ -450,7 +450,7 @@ void dpow_statemachinestart(void *ptr) for (i=0; inotaries[i].pubkey,33,Notaries[i][1]); - if ( memcmp(bp->notaries[i].pubkey,myinfo->DPOW.minerkey33,33) == 0 ) + if ( memcmp(bp->notaries[i].pubkey,dp->minerkey33,33) == 0 ) { myind = i; ep = &bp->notaries[myind]; @@ -462,16 +462,16 @@ void dpow_statemachinestart(void *ptr) free(ptr); return; } - bitcoin_address(srcaddr,src->chain->pubtype,myinfo->DPOW.minerkey33,33); - bitcoin_address(destaddr,dest->chain->pubtype,myinfo->DPOW.minerkey33,33); + bitcoin_address(srcaddr,src->chain->pubtype,dp->minerkey33,33); + bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33); printf(" myaddr.(%s %s)\n",srcaddr,destaddr); - if ( dpow_checkutxo(myinfo,bp,bp->destcoin,&ep->dest.prev_hash,&ep->dest.prev_vout,destaddr) < 0 ) + if ( dpow_checkutxo(myinfo,dp,bp,bp->destcoin,&ep->dest.prev_hash,&ep->dest.prev_vout,destaddr) < 0 ) { printf("dont have %s %s utxo, please send funds\n",dp->dest,destaddr); free(ptr); return; } - if ( dpow_checkutxo(myinfo,bp,bp->srccoin,&ep->src.prev_hash,&ep->src.prev_vout,srcaddr) < 0 ) + if ( dpow_checkutxo(myinfo,dp,bp,bp->srccoin,&ep->src.prev_hash,&ep->src.prev_vout,srcaddr) < 0 ) { printf("dont have %s %s utxo, please send funds\n",dp->symbol,srcaddr); free(ptr); @@ -495,7 +495,7 @@ void dpow_statemachinestart(void *ptr) starttime = (uint32_t)time(NULL); printf("DPOW statemachine checkpoint.%d %s\n",checkpoint.blockhash.height,bits256_str(str,checkpoint.blockhash.hash)); for (i=0; iDPOW.minerkey33[i+1]; + srchash.bytes[i] = dp->minerkey33[i+1]; dpow_utxosync(myinfo,bp,0,myind,srchash); while ( time(NULL) < starttime+bp->duration && src != 0 && dest != 0 && bp->state != 0xffffffff ) { @@ -510,13 +510,13 @@ void dpow_statemachinestart(void *ptr) //printf("dp->ht.%d ht.%d DEST.%08x %s\n",dp->checkpoint.blockhash.height,checkpoint.blockhash.height,deststate,bits256_str(str,srchash.hash)); bp->state = dpow_statemachineiterate(myinfo,dp,dest,bp,myind,1); } - if ( myinfo->DPOW.cancelratify != 0 && checkpoint.blockhash.height == 0 ) + if ( dp->cancelratify != 0 && checkpoint.blockhash.height == 0 ) { printf("abort pending ratify\n"); break; } } printf("state machine ht.%d completed state.%x %s.%s %s.%s recvmask.%llx\n",bp->height,bp->state,dp->dest,bits256_str(str,bp->desttxid),dp->symbol,bits256_str(str2,bp->srctxid),(long long)bp->recvmask); - myinfo->DPOW.lastrecvmask = bp->recvmask; + dp->lastrecvmask = bp->recvmask; free(ptr); } diff --git a/iguana/dpow/dpow_network.c b/iguana/dpow/dpow_network.c index 98e4f1649..06cfd5147 100755 --- a/iguana/dpow/dpow_network.c +++ b/iguana/dpow/dpow_network.c @@ -285,14 +285,14 @@ int32_t dpow_rwsigentry(int32_t rwflag,uint8_t *data,struct dpow_sigentry *dsig) return(len); } -void dpow_sigsend(struct supernet_info *myinfo,struct dpow_block *bp,int32_t myind,int8_t bestk,uint64_t bestmask,bits256 srchash,uint32_t sigchannel) +void dpow_sigsend(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,int32_t myind,int8_t bestk,uint64_t bestmask,bits256 srchash,uint32_t sigchannel) { struct dpow_sigentry dsig; int32_t i,len; uint8_t data[4096]; struct dpow_entry *ep; ep = &bp->notaries[myind]; printf("sigsend.%s: myind.%d bestk.%d %llx >>>>>> broadcast channel.%x\n",sigchannel == DPOW_SIGCHANNEL ? bp->srccoin->symbol : bp->destcoin->symbol,myind,bestk,(long long)bestmask,sigchannel); memset(&dsig,0,sizeof(dsig)); for (i=0; i<33; i++) - dsig.senderpub[i] = myinfo->DPOW.minerkey33[i]; + dsig.senderpub[i] = dp->minerkey33[i]; dsig.lastk = bestk; dsig.mask = bestmask; dsig.senderind = myind; @@ -307,7 +307,7 @@ void dpow_sigsend(struct supernet_info *myinfo,struct dpow_block *bp,int32_t myi dsig.siglen = ep->src.siglens[bestk]; memcpy(dsig.sig,ep->src.sigs[bestk],ep->src.siglens[bestk]); } - memcpy(dsig.senderpub,myinfo->DPOW.minerkey33,33); + memcpy(dsig.senderpub,dp->minerkey33,33); len = dpow_rwsigentry(1,data,&dsig); dpow_send(myinfo,bp,srchash,bp->hashmsg,sigchannel,bp->height,data,len,bp->sigcrcs); } diff --git a/iguana/dpow/dpow_rpc.c b/iguana/dpow/dpow_rpc.c index d3dfc1aaa..388b819b7 100755 --- a/iguana/dpow/dpow_rpc.c +++ b/iguana/dpow/dpow_rpc.c @@ -245,7 +245,7 @@ int32_t dpow_getchaintip(struct supernet_info *myinfo,bits256 *blockhashp,uint32 return(height); } -int32_t dpow_vini_ismine(struct supernet_info *myinfo,cJSON *item) +int32_t dpow_vini_ismine(struct supernet_info *myinfo,struct dpow_info *dp,cJSON *item) { cJSON *sobj; char *hexstr; int32_t len; uint8_t data[35]; if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 ) @@ -254,7 +254,7 @@ int32_t dpow_vini_ismine(struct supernet_info *myinfo,cJSON *item) if ( len <= sizeof(data) ) { decode_hex(data,len,hexstr); - if ( len == 35 && data[34] == CHECKSIG && data[0] == 33 && memcmp(data+1,myinfo->DPOW.minerkey33,33) == 0 ) + if ( len == 35 && data[34] == CHECKSIG && data[0] == 33 && memcmp(data+1,dp->minerkey33,33) == 0 ) return(0); } } diff --git a/iguana/dpow/dpow_tx.c b/iguana/dpow/dpow_tx.c index 9ad48f117..234d607c6 100755 --- a/iguana/dpow/dpow_tx.c +++ b/iguana/dpow/dpow_tx.c @@ -64,10 +64,17 @@ uint64_t dpow_maskmin(uint64_t refmask,struct dpow_block *bp,int8_t *lastkp) return(mask); } -struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,int32_t height) +struct dpow_block *dpow_heightfind(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height) { - if ( height < DPOW_MAXBLOCKS ) - return(myinfo->DPOW.blocks!=0?myinfo->DPOW.blocks[height]:0); + int32_t incr = 100000; + if ( height > dp->maxblocks ) + { + dp->blocks = realloc(dp->blocks,sizeof(*dp->blocks) * (dp->maxblocks + incr)); + memset(&dp->blocks[dp->maxblocks],0,sizeof(*dp->blocks) * incr); + dp->maxblocks += incr; + } + if ( height < dp->maxblocks ) + return(dp->blocks!=0?dp->blocks[height]:0); else return(0); } @@ -226,7 +233,7 @@ cJSON *dpow_vins(struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uin return(vins); } -void dpow_rawtxsign(struct supernet_info *myinfo,struct iguana_info *coin,struct dpow_block *bp,char *rawtx,cJSON *vins,int8_t bestk,uint64_t bestmask,int32_t myind,int32_t src_or_dest) +void dpow_rawtxsign(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,struct dpow_block *bp,char *rawtx,cJSON *vins,int8_t bestk,uint64_t bestmask,int32_t myind,int32_t src_or_dest) { int32_t j,m=0,retval=-1; char *jsonstr,*signedtx,*rawtx2,*sigstr; cJSON *signobj,*sobj,*txobj2,*item,*vin; bits256 srchash; struct dpow_entry *ep; struct dpow_coinentry *cp; m = 0; @@ -255,7 +262,7 @@ void dpow_rawtxsign(struct supernet_info *myinfo,struct iguana_info *coin,struct decode_hex(cp->sigs[bestk],cp->siglens[bestk],sigstr); ep->masks[src_or_dest][bestk] = bestmask; ep->beacon = bp->beacon; - dpow_sigsend(myinfo,bp,myind,bestk,bestmask,srchash,src_or_dest != 0 ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL); + dpow_sigsend(myinfo,dp,bp,myind,bestk,bestmask,srchash,src_or_dest != 0 ? DPOW_SIGBTCCHANNEL : DPOW_SIGCHANNEL); retval = 0; break; } // else printf("notmine.(%s)\n",jprint(item,0)); @@ -271,7 +278,7 @@ void dpow_rawtxsign(struct supernet_info *myinfo,struct iguana_info *coin,struct } } -int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t myind,uint32_t sigchannel,int32_t src_or_dest) +int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct dpow_info *dp,struct iguana_info *coin,struct dpow_block *bp,int8_t bestk,uint64_t bestmask,int32_t myind,uint32_t sigchannel,int32_t src_or_dest) { int32_t j,incr,numsigs,retval=-1; char rawtx[32768]; cJSON *vins; bits256 txid,srchash,zero; struct dpow_entry *ep; if ( bp->numnotaries < 8 ) @@ -283,7 +290,7 @@ int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct iguana_info *coin,s if ( bestk < 0 ) return(-1); for (j=0; jDPOW.minerkey33[j+1]; + srchash.bytes[j] = dp->minerkey33[j+1]; if ( (vins= dpow_vins(coin,bp,bestk,bestmask,1,src_or_dest)) != 0 ) { txid = dpow_notarytx(rawtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,bp->numratified!=0?bp->ratified_pubkeys:0,bp->numratified); @@ -297,14 +304,14 @@ int32_t dpow_signedtxgen(struct supernet_info *myinfo,struct iguana_info *coin,s for (j=0; jhashmsg,(bits256_nonz(bp->btctxid) == 0) ? DPOW_BTCTXIDCHANNEL : DPOW_TXIDCHANNEL,bp->height,txdata,len+32,bp->txidcrcs);*/ - dpow_rawtxsign(myinfo,coin,bp,rawtx,vins,bestk,bestmask,myind,src_or_dest); + dpow_rawtxsign(myinfo,dp,coin,bp,rawtx,vins,bestk,bestmask,myind,src_or_dest); } else printf("signedtxgen zero txid or null rawtx\n"); free_json(vins); } else printf("signedtxgen error generating vins\n"); return(retval); } -void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_block *bp,uint32_t channel,int32_t myind,int32_t src_or_dest) +void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_block *bp,uint32_t channel,int32_t myind,int32_t src_or_dest) { bits256 txid,srchash,zero,signedtxid; struct iguana_info *coin; int32_t j,len,numsigs; char *retstr=0,str[65],str2[65]; uint8_t txdata[32768]; coin = (src_or_dest != 0) ? bp->destcoin : bp->srccoin; @@ -328,7 +335,7 @@ void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_block *bp,uint32_t if ( src_or_dest != 0 ) { bp->desttxid = txid; - dpow_signedtxgen(myinfo,bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,0); + dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bp->bestk,bp->bestmask,myind,DPOW_SIGCHANNEL,0); } else bp->srctxid = txid; len = (int32_t)strlen(bp->signedtx) >> 1; diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 7872f6bbc..eda195500 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -96,7 +96,7 @@ struct supernet_info void *ctx; uint8_t *pingbuf; FILE *dexfp; - struct dpow_info DPOW; + struct dpow_info DPOWS[64]; int32_t numdpows; struct delayedPoW_info dPoW; struct basilisk_spend *spends; int32_t numspends; //struct peggy_info *PEGS; diff --git a/iguana/iguana_notary.c b/iguana/iguana_notary.c index 206d55b42..d81afafe4 100755 --- a/iguana/iguana_notary.c +++ b/iguana/iguana_notary.c @@ -22,7 +22,7 @@ #include "iguana777.h" #include "notaries.h" -int32_t dpow_datahandler(struct supernet_info *myinfo,uint32_t channel,uint32_t height,uint8_t *data,int32_t datalen); +int32_t dpow_datahandler(struct supernet_info *myinfo,struct dpow_info *dp,uint32_t channel,uint32_t height,uint8_t *data,int32_t datalen); #include "dpow/dpow_network.c" #include "dpow/dpow_rpc.c" @@ -127,9 +127,9 @@ void dpow_destupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t h } } -void iguana_dPoWupdate(struct supernet_info *myinfo) +void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp) { - int32_t height; char str[65]; uint32_t blocktime; bits256 blockhash; struct iguana_info *src,*dest; struct dpow_info *dp = &myinfo->DPOW; + int32_t height; char str[65]; uint32_t blocktime; bits256 blockhash; struct iguana_info *src,*dest; dpow_nanomsg_update(myinfo); src = iguana_coinfind(dp->symbol); dest = iguana_coinfind(dp->dest); @@ -180,7 +180,7 @@ void dpow_addresses() TWO_STRINGS(iguana,dpow,symbol,pubkey) { - char *retstr; + char *retstr; int32_t i; struct dpow_info *dp = &myinfo->DPOWS[myinfo->numdpows]; if ( myinfo->NOTARY.RELAYID < 0 ) { if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(myinfo->ipaddr),myinfo->myaddr.persistent)) != 0 ) @@ -191,7 +191,7 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) if ( myinfo->NOTARY.RELAYID < 0 ) return(clonestr("{\"error\":\"must be running as notary node\"}")); } - if ( myinfo->DPOW.symbol[0] != 0 ) + if ( dp->symbol[0] != 0 ) return(clonestr("{\"error\":\"cant dPoW more than one coin at a time\"}")); if ( pubkey == 0 || pubkey[0] == 0 || is_hexstr(pubkey,0) != 66 ) return(clonestr("{\"error\":\"need 33 byte pubkey\"}")); @@ -201,26 +201,38 @@ TWO_STRINGS(iguana,dpow,symbol,pubkey) return(clonestr("{\"error\":\"cant dPoW an inactive coin\"}")); if ( strcmp(symbol,"KMD") == 0 && iguana_coinfind("BTC") == 0 ) return(clonestr("{\"error\":\"cant dPoW KMD without BTC\"}")); - else if ( strcmp(symbol,"KMD") != 0 && iguana_coinfind("KMD") == 0 ) + else if ( myinfo->numdpows == 0 && strcmp(symbol,"KMD") != 0 && iguana_coinfind("KMD") == 0 ) return(clonestr("{\"error\":\"cant dPoW without KMD\"}")); - decode_hex(myinfo->DPOW.minerkey33,33,pubkey); - if ( bitcoin_pubkeylen(myinfo->DPOW.minerkey33) <= 0 ) + if ( myinfo->numdpows > 1 ) + { + if ( strcmp(symbol,"KMD") == 0 || iguana_coinfind("BTC") == 0 ) + return(clonestr("{\"error\":\"cant dPoW KMD or BTC again\"}")); + for (i=1; inumdpows; i++) + if ( strcmp(symbol,myinfo->DPOWS[i].symbol) == 0 ) + return(clonestr("{\"error\":\"cant dPoW same coin again\"}")); + } + decode_hex(dp->minerkey33,33,pubkey); + if ( bitcoin_pubkeylen(dp->minerkey33) <= 0 ) return(clonestr("{\"error\":\"illegal pubkey\"}")); - strcpy(myinfo->DPOW.symbol,symbol); - if ( strcmp(myinfo->DPOW.symbol,"KMD") == 0 ) + strcpy(dp->symbol,symbol); + if ( strcmp(dp->symbol,"KMD") == 0 ) { - strcpy(myinfo->DPOW.dest,"BTC"); - myinfo->DPOW.srcconfirms = DPOW_KOMODOCONFIRMS; + strcpy(dp->dest,"BTC"); + dp->srcconfirms = DPOW_KOMODOCONFIRMS; } else { - strcpy(myinfo->DPOW.dest,"KMD"); - myinfo->DPOW.srcconfirms = DPOW_THIRDPARTY_CONFIRMS; + strcpy(dp->dest,"KMD"); + dp->srcconfirms = DPOW_THIRDPARTY_CONFIRMS; + } + if ( dp->srcconfirms > DPOW_FIFOSIZE ) + dp->srcconfirms = DPOW_FIFOSIZE; + if ( dp->blocks == 0 ) + { + dp->maxblocks = 100000; + dp->blocks = calloc(dp->maxblocks,sizeof(*dp->blocks)); } - if ( myinfo->DPOW.srcconfirms > DPOW_FIFOSIZE ) - myinfo->DPOW.srcconfirms = DPOW_FIFOSIZE; - if ( myinfo->DPOW.blocks == 0 ) - myinfo->DPOW.blocks = calloc(DPOW_MAXBLOCKS,sizeof(*myinfo->DPOW.blocks)); + myinfo->numdpows++; PAX_init(); return(clonestr("{\"result\":\"success\"}")); } @@ -271,7 +283,7 @@ STRING_ARG(dpow,active,maskhex) uint8_t data[8],revdata[8]; int32_t i,len; uint64_t mask; cJSON *retjson,*array = cJSON_CreateArray(); if ( maskhex == 0 || maskhex[0] == 0 ) { - mask = myinfo->DPOW.lastrecvmask; + mask = myinfo->DPOWS[0].lastrecvmask; for (i=0; i<64; i++) { if ( ((1LL << i) & mask) != 0 ) @@ -310,7 +322,7 @@ STRING_ARG(dpow,active,maskhex) ZERO_ARGS(dpow,cancelratify) { - myinfo->DPOW.cancelratify = 1; + myinfo->DPOWS[0].cancelratify = 1; return(clonestr("{\"result\":\"queued dpow cancel ratify\"}")); } @@ -323,12 +335,12 @@ TWOINTS_AND_ARRAY(dpow,ratify,minsigs,timestamp,ratified) dpow_checkpointset(myinfo,&checkpoint,0,zero,timestamp,timestamp); ptrs = calloc(1,sizeof(void *)*5 + sizeof(struct dpow_checkpoint)); ptrs[0] = (void *)myinfo; - ptrs[1] = (void *)&myinfo->DPOW; + ptrs[1] = (void *)&myinfo->DPOWS[0]; ptrs[2] = (void *)(long)minsigs; ptrs[3] = (void *)DPOW_RATIFYDURATION; ptrs[4] = (void *)jprint(ratified,0); memcpy(&ptrs[5],&checkpoint,sizeof(checkpoint)); - myinfo->DPOW.cancelratify = 0; + myinfo->DPOWS[0].cancelratify = 0; if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_statemachinestart,(void *)ptrs) != 0 ) { } diff --git a/iguana/main.c b/iguana/main.c index 1a420c07d..2cea9645e 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -1572,7 +1572,7 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) void iguana_main(void *arg) { - int32_t usessl = 0, ismainnet = 1, do_OStests = 0; struct supernet_info *myinfo; + int32_t i,usessl = 0,ismainnet = 1, do_OStests = 0; struct supernet_info *myinfo; if ( (IGUANA_BIGENDIAN= iguana_isbigendian()) > 0 ) printf("BIGENDIAN\n"); else if ( IGUANA_BIGENDIAN == 0 ) @@ -1586,7 +1586,8 @@ void iguana_main(void *arg) myinfo = SuperNET_MYINFO(0); libgfshare_init(myinfo,myinfo->logs,myinfo->exps); myinfo->rpcport = IGUANA_RPCPORT; - myinfo->DPOW.sock = -1; + for (i=0; iDPOWS)/sizeof(*myinfo->DPOWS); i++) + myinfo->DPOWS[i].sock = -1; //myinfo->rpcport = IGUANA_NOTARYPORT; //myinfo->IAMNOTARY = 1; if ( arg != 0 ) diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index fcd28ef0b..d7de8a102 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -503,7 +503,7 @@ int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,int32_t width); int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t duration); cJSON *dpow_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr); -void iguana_dPoWupdate(struct supernet_info *myinfo); +void iguana_dPoWupdate(struct supernet_info *myinfo,struct dpow_info *dp); char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *pubkey33,uint64_t satoshis,int32_t duplicates,int32_t *completedp,bits256 *signedtxidp,int32_t sendflag,cJSON *addresses); int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); void iguana_RTunspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins);