Browse Source

Merge branch 'staked' of https://github.com/KMDLabs/SuperNET into KMDLabs-staked

blackjok3r
blackjok3r 6 years ago
parent
commit
fd0b3bfd62
  1. 8
      crypto777/bitcoind_RPC.c
  2. 133
      iguana/dpow/dpow_fsm.c
  3. 18
      iguana/dpow/dpow_network.c
  4. 279
      iguana/dpow/dpow_rpc.c
  5. 16
      iguana/dpow/dpow_tx.c
  6. 24
      iguana/iguana_notary.c
  7. 46
      iguana/main.c

8
crypto777/bitcoind_RPC.c

@ -183,7 +183,7 @@ try_again:
if ( curl_handle == 0 )
curl_handle = curl_easy_init();
headers = curl_slist_append(0,"Expect:");
curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl_handle,CURLOPT_URL, url);
@ -280,7 +280,7 @@ try_again:
free(retstr);
sleep((1<<numretries));
goto try_again;
}
else
{
@ -345,7 +345,7 @@ try_again:
memset(&chunk,0,sizeof(chunk));
curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback);
curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void *)&chunk);
}
curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL, 1L); // supposed to fix "Alarm clock" and long jump crash
curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS, 1L); // no progress callback
@ -427,7 +427,7 @@ try_again:
free(retstr);
sleep((1<<numretries));
goto try_again;
}
else
{

133
iguana/dpow/dpow_fsm.c

@ -324,6 +324,7 @@ void dpow_statemachinestart(void *ptr)
bp->finished = 0xffffffff;
free(ptr);
free_json(ratified);
bp->finished = 0xffffffff;
return;
}
for (i=0; i<numratified; i++)
@ -436,6 +437,7 @@ void dpow_statemachinestart(void *ptr)
bp->finished = 0xffffffff;
free(ptr);
dp->ratifying -= bp->isratify;
bp->finished = 0xffffffff;
exit(-1);
return;
}
@ -447,6 +449,7 @@ void dpow_statemachinestart(void *ptr)
bp->finished = 0xffffffff;
free(ptr);
dp->ratifying -= bp->isratify;
bp->finished = 0xffffffff;
return;
}
bp->myind = myind;
@ -479,28 +482,28 @@ void dpow_statemachinestart(void *ptr)
}
else
{
if ( dpow_haveutxo(myinfo,bp->destcoin,&ep->dest.prev_hash,&ep->dest.prev_vout,destaddr,src->symbol) > 0 )
{
if ( (strcmp("KMD",dest->symbol) == 0 ) && (ep->dest.prev_vout != -1) )
{
// lock the dest utxo if destination coin is KMD.
if (dpow_lockunspent(myinfo,bp->destcoin,destaddr,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout) != 0)
printf(">>>> LOCKED %s UTXO.(%s) vout.(%d)\n",dest->symbol,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout);
else
printf("<<<< FAILED TO LOCK %s UTXO.(%s) vout.(%d)\n",dest->symbol,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout);
}
}
if ( dpow_haveutxo(myinfo,bp->srccoin,&ep->src.prev_hash,&ep->src.prev_vout,srcaddr,"") > 0 )
{
if ( ( strcmp("KMD",src->symbol) == 0 ) && (ep->src.prev_vout != -1) )
if ( dpow_haveutxo(myinfo,bp->destcoin,&ep->dest.prev_hash,&ep->dest.prev_vout,destaddr,src->symbol) > 0 )
{
if ( (strcmp("KMD",dest->symbol) == 0 ) && (ep->dest.prev_vout != -1) )
{
// lock the dest utxo if destination coin is KMD.
if (dpow_lockunspent(myinfo,bp->destcoin,destaddr,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout) != 0)
printf(">>>> LOCKED %s UTXO.(%s) vout.(%d)\n",dest->symbol,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout);
else
printf("<<<< FAILED TO LOCK %s UTXO.(%s) vout.(%d)\n",dest->symbol,bits256_str(str2,ep->dest.prev_hash),ep->dest.prev_vout);
}
}
if ( dpow_haveutxo(myinfo,bp->srccoin,&ep->src.prev_hash,&ep->src.prev_vout,srcaddr,"") > 0 )
{
// lock the src coin selected utxo if the source coin is KMD.
if (dpow_lockunspent(myinfo,bp->srccoin,srcaddr,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout) != 0)
printf(">>>> LOCKED %s UTXO.(%s) vout.(%d\n",src->symbol,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout);
else
printf("<<<< FAILED TO LOCK %s UTXO.(%s) vout.(%d)\n",src->symbol,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout);
if ( ( strcmp("KMD",src->symbol) == 0 ) && (ep->src.prev_vout != -1) )
{
// lock the src coin selected utxo if the source coin is KMD.
if (dpow_lockunspent(myinfo,bp->srccoin,srcaddr,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout) != 0)
printf(">>>> LOCKED %s UTXO.(%s) vout.(%d\n",src->symbol,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout);
else
printf("<<<< FAILED TO LOCK %s UTXO.(%s) vout.(%d)\n",src->symbol,bits256_str(str2,ep->src.prev_hash),ep->src.prev_vout);
}
}
}
if ( bp->isratify != 0 )
{
bp->notaries[myind].ratifysrcutxo = ep->src.prev_hash;
@ -570,6 +573,9 @@ void dpow_statemachinestart(void *ptr)
src_or_dest = 0;
else src_or_dest = 1;
extralen = dpow_paxpending(myinfo,extras,sizeof(extras),&bp->paxwdcrc,bp->MoM,bp->MoMdepth,bp->CCid,src_or_dest,bp);
// This is no longer be needed... It can stop notarizations dead if they have not happened for 1440 blocks.
//if ( extralen == -1 )
// break;
bp->notaries[bp->myind].paxwdcrc = bp->paxwdcrc;
}
if ( dp->checkpoint.blockhash.height > checkpoint.blockhash.height ) //(checkpoint.blockhash.height % 100) != 0 &&
@ -616,9 +622,92 @@ void dpow_statemachinestart(void *ptr)
printf("[%d] END isratify.%d:%d bestk.%d %llx sigs.%llx state.%x machine ht.%d completed state.%x %s.%s %s.%s recvmask.%llx paxwdcrc.%x %p %p\n",Numallocated,bp->isratify,dp->ratifying,bp->bestk,(long long)bp->bestmask,(long long)(bp->bestk>=0?bp->destsigsmasks[bp->bestk]:0),bp->state,bp->height,bp->state,dp->dest,bits256_str(str,bp->desttxid),dp->symbol,bits256_str(str2,bp->srctxid),(long long)bp->recvmask,bp->paxwdcrc,src,dest);
dp->lastrecvmask = bp->recvmask;
dp->ratifying -= bp->isratify;
// We need to wait for notarized confirm here. If the notarization is reorged for any reason we need to rebroadcast it,
// because the mempool is stupid after the sapling update, or Alright might be playing silly games.
int8_t dest_confs = 0, src_confs = 0, destnotarized = 0, srcnotarized = 0, firstloop = 0;
char desttx[32768] = {0}, srctx[32768] = {0};
while ( destnotarized == 0 || srcnotarized == 0 )
{
// If the round was sucessful and both notarization transactions were created successfully we will make sure they are in the chain.
if ( bits256_cmp(bp->desttxid,zero) == 0 )
break;
if ( bits256_cmp(bp->srctxid,zero) == 0 )
break;
int8_t send_dest = 0, send_src = 0; char rettx[32768] = {0};
if ( firstloop == 0 )
{
sleep((rand() % (120 - 60)) + 60);
firstloop = 1;
}
// random sleep here so all nodes are checking/rebroadcasting at diffrent times.
sleep((rand() % (77 - 33)) + 33);
// get the confirms for desttxid
if ( destnotarized == 0 )
{
if ( (dest_confs= dpow_txconfirms(myinfo, bp->destcoin, bp->desttxid, rettx)) != -1 )
{
if ( desttx[0] == 0 && rettx[0] != 0 )
{
// save the transaction once we fetch it once, as its possible we wil not be able to always see it.
memcpy(desttx, rettx, strlen(rettx)+1);
}
if ( dest_confs > 2 )
{
// tx is notarized. or it has 100+ raw confirms. Its now final and cannot be lost, no longer need to check.
fprintf(stderr, "[dest.%s] txid.%s is notarized. confirms.%d srcnotarized.%i\n",dp->dest, bits256_str(str,bp->desttxid), dest_confs, srcnotarized);
destnotarized = 1;
}
else if ( dest_confs == 0 )
{
// not confirmed, rebroadcast it.
fprintf(stderr, "[%s] txid.%s is not confirmed rebroadcasting....\n",dp->dest, bits256_str(str,bp->desttxid));
if ( desttx[0] != 0 )
send_dest = 1;
}
}
else if ( desttx[0] != 0 ) // we have the tranxation hex saved, and the tx is not in the local mempool or a block, so resend it.
{
fprintf(stderr, "[%s] Cant find tx.%s rebroadcasting...\n", dp->dest, bits256_str(str,bp->desttxid));
send_dest = 1;
} else fprintf(stderr, "[%s] get raw transaction error\n", dp->dest);
if ( send_dest == 1 )
dpow_sendrawtransaction(myinfo, bp->destcoin, desttx);
}
// get the confirms for srctxid
memset(rettx,0,sizeof(rettx)); // zero out rettx!
if ( srcnotarized == 0 )
{
if ( (src_confs= dpow_txconfirms(myinfo, bp->srccoin, bp->srctxid, rettx)) != -1 )
{
if ( srctx[0] == 0 && rettx[0] != 0 )
{
memcpy(srctx, rettx, strlen(rettx)+1);
}
if ( src_confs > 2 )
{
fprintf(stderr, "[src.%s] txid.%s is notarized. confirms.%i destnotarized.%i\n", dp->symbol, bits256_str(str,bp->srctxid), src_confs, destnotarized);
srcnotarized = 1;
}
else if ( src_confs == 0 )
{
fprintf(stderr, "[%s] txid.%s is not confirmed rebroadcasting....\n", dp->symbol, bits256_str(str,bp->srctxid));
if ( srctx[0] != 0 )
send_src = 1;
}
}
else if ( srctx[0] != 0 )
{
fprintf(stderr, "[%s] Cant find tx.%s rebroadcasting...\n", dp->symbol, bits256_str(str,bp->srctxid));
send_src = 1;
} else fprintf(stderr, "[%s] get raw transaction error\n", dp->symbol);
if ( send_src == 1 )
dpow_sendrawtransaction(myinfo, bp->srccoin, srctx);
}
}
bp->state = 0xffffffff;
end:
end:
// unlock the dest utxo on KMD.
if ( (strcmp("KMD",dest->symbol) == 0 ) && (ep->dest.prev_vout != -1) )
{

18
iguana/dpow/dpow_network.c

@ -1378,7 +1378,7 @@ int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *i
//if ( strcmp(ipaddr,"88.99.251.101") == 0 || strcmp(ipaddr,"82.202.193.100") == 0 )
// return(-1);
#ifdef CHECKNODEIP
#ifdef CHECKNODEIP
// -B- [+] Decker ---
// every new ip in BUS topology network goes to dead or white list forever, until iguana restart
ip_pattern = (uint32_t)calc_ipbits(ipaddr);
@ -1405,7 +1405,7 @@ int32_t dpow_addnotary(struct supernet_info *myinfo,struct dpow_info *dp,char *i
} else
if (dead_or_alive[in_list_flag] == -1) return -1;
// -E- [+] Decker ---
#endif
#endif
portable_mutex_lock(&myinfo->notarymutex);
if ( myinfo->dpowsock >= 0 )//&& myinfo->dexsock >= 0 )
@ -1663,13 +1663,13 @@ void dpow_bestconsensus(struct dpow_info *dp,struct dpow_block *bp)
bp->bestmatches = bestmatches;
bp->notaries[bp->myind].bestmask = bp->bestmask = masks[besti];
bp->notaries[bp->myind].bestk = bp->bestk = bestks[besti];
if ( bp->myind == 0 )
if ( 0 && bp->myind == 0 )
printf("matches.%d bestmatches.%d recv.%llx (%d %llx)\n",matches,bestmatches,(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask);
if ( 1 && bp->myind == 0 && strcmp("KMD",dp->symbol) == 0 )
if ( 0 && bp->myind == 0 && strcmp("LABS",dp->symbol) == 0 )
{
for (i=0; i<bp->numnotaries; i++)
printf("%d:%d%s ",wts[i],owts[i],wts[i]*owts[i]>median?"*":"");
printf("median.%d %s.%d set matches.%d best.%d to (%d %llx) recv.%llx topmask.%llx\n",sortbuf[bp->numnotaries/2],dp->symbol,bp->height,bp->matches,bp->bestmatches,bp->bestk,(long long)bp->bestmask,(long long)recvmask,(long long)topmask);
printf("median.%d %s.%d set matches.%d best.%d to (%d %llx) recv.%llx topmask.%llx minsigs.%d\n",sortbuf[bp->numnotaries/2],dp->symbol,bp->height,bp->matches,bp->bestmatches,bp->bestk,(long long)bp->bestmask,(long long)recvmask,(long long)topmask,bp->minsigs);
for (i=0; i<bp->numnotaries; i++)
if ( wts[i] == 0 || owts[i] == 0 )
printf("%s.%d:%d ",Notaries_elected[i][0],wts[i],owts[i]);
@ -2063,7 +2063,7 @@ void dpow_notarize_update(struct supernet_info *myinfo,struct dpow_info *dp,stru
dpow_send(myinfo,dp,bp,srchash,bp->hashmsg,0,bp->height,(void *)"ping",0);
bp->lastnanosend = now;
}
if ( 1 && strcmp("KMD",dp->symbol) == 0 && bp->myind == 0 )
if ( 0 && strcmp("LABSTH",dp->symbol) == 0 && bp->myind == 0 )
printf("%s recv.%llx best.(%d %llx) m.%d p.%d:%d b.%d state.%d minsigs.%d pend.%d\n",dp->symbol,(long long)bp->recvmask,bp->bestk,(long long)bp->bestmask,matches,paxmatches,paxbestmatches,bestmatches,bp->state,bp->minsigs,bp->pendingbestk);
if ( bestmatches == bp->minsigs && paxbestmatches == bp->minsigs && bp->bestk >= 0 && bp->bestmask != 0 )
{
@ -2138,7 +2138,7 @@ void dpow_nanoutxoget(struct supernet_info *myinfo,struct dpow_info *dp,struct d
}
}
}
if ( 1 && bp->myind == 0 && dispflag != 0 )
if ( 0 && bp->myind == 0 && dispflag != 0 )
{
printf("%s.%d RECV.%-2d %llx (%2d %llx) %llx/%llx matches.%-2d best.%-2d %s\n",dp->symbol,bp->height,senderind,(long long)np->recvmask,(int8_t)np->bestk,(long long)np->bestmask,(long long)np->srcutxo.txid,(long long)np->destutxo.txid,matches,bestmatches,Notaries_elected[senderind][0]);
}
@ -2222,7 +2222,7 @@ void dpow_send(struct supernet_info *myinfo,struct dpow_info *dp,struct dpow_blo
printf("maxiters expired for signed_nn_send dpowsock.%d\n",myinfo->dpowsock);
//portable_mutex_unlock(&myinfo->dpowmutex);
free(np);
if ( 1 && bp->myind == 0 )
if ( 0 && bp->myind == 0 )
printf("%d NANOSEND.%d %s.%d channel.%08x (%d) pax.%08x datalen.%d (%d %llx) (%d %llx) recv.%llx\n",i,sentbytes,dp->symbol,np->height,np->channel,size,np->notarize.paxwdcrc,datalen,(int8_t)np->notarize.bestk,(long long)np->notarize.bestmask,bp->notaries[bp->myind].bestk,(long long)bp->notaries[bp->myind].bestmask,(long long)bp->recvmask);
}
@ -2311,7 +2311,7 @@ int32_t dpow_nanomsg_update(struct supernet_info *myinfo)
if ( i == myinfo->numdpows )
printf("received nnpacket for (%s)\n",np->symbol);
else
{
{
dpow_ipbitsadd(myinfo,dp,np->ipbits,np->numipbits,sizeof(np->ipbits)/sizeof(*np->ipbits),np->senderind,np->myipbits);
if ( (bp= dpow_heightfind(myinfo,dp,np->height)) != 0 && bp->state != 0xffffffff && bp->myind >= 0 )
{

279
iguana/dpow/dpow_rpc.c

@ -111,57 +111,75 @@ int32_t Notaries_minsigs = DPOW_MIN_ASSETCHAIN_SIGS;
uint16_t Notaries_port = DPOW_SOCKPORT;
char *Notaries_seeds[65];
int32_t komodo_initjson(char *fname)
int32_t komodo_initjson2(char *fstr)
{
char *fstr,*field,*hexstr; cJSON *argjson,*array,*item; long fsize; uint16_t port; int32_t i,n,num,retval = -1;
//for (i=0; i<Notaries_numseeds; i++)
// Notaries_seeds[i] = seeds[i];
if ( (fstr= OS_filestr(&fsize,fname)) != 0 )
{
if ( (argjson= cJSON_Parse(fstr)) != 0 )
char *field,*hexstr; cJSON *array,*item,*argjson; uint16_t port; int32_t i,n,num,retval = -1;
static portable_mutex_t notaries_mutex; static int32_t initflag;
if ( initflag == 0 )
{
portable_mutex_init(&notaries_mutex);
initflag = 1;
}
portable_mutex_lock(&notaries_mutex);
if ( (argjson= cJSON_Parse(fstr)) != 0 )
{
// memset arrays to 0!
memset(Notaries_seeds,0,sizeof(Notaries_seeds));
memset(Notaries_elected,0,sizeof(Notaries_elected));
if ( (port= juint(argjson,"port")) != 0 )
Notaries_port = port;
if ( (num= juint(argjson,"BTCminsigs")) > Notaries_BTCminsigs )
Notaries_BTCminsigs = num;
Notaries_minsigs = juint(argjson,"minsigs");
if ( (array= jarray(&n,argjson,"seeds")) != 0 && n <= 64 )
{
if ( (port= juint(argjson,"port")) != 0 )
Notaries_port = port;
if ( (num= juint(argjson,"BTCminsigs")) > Notaries_BTCminsigs )
Notaries_BTCminsigs = num;
Notaries_minsigs = juint(argjson,"minsigs");
if ( (array= jarray(&n,argjson,"seeds")) != 0 && n <= 64 )
for (i=0; i<n&&i<64; i++)
{
for (i=0; i<n&&i<64; i++)
{
Notaries_seeds[i] = clonestr(jstri(array,i));
printf("%s ",Notaries_seeds[i]);
}
Notaries_numseeds = i;
printf("Notaries_numseeds.%d\n",Notaries_numseeds);
Notaries_seeds[i] = clonestr(jstri(array,i));
//printf("%s ",Notaries_seeds[i]);
}
if ( (array= jarray(&n,argjson,"notaries")) != 0 && n <= 64 )
Notaries_numseeds = i;
//printf("Notaries_numseeds.%d\n",Notaries_numseeds);
}
if ( (array= jarray(&n,argjson,"notaries")) != 0 && n <= 64 )
{
for (i=0; i<n&&i<64; i++)
{
for (i=0; i<n&&i<64; i++)
item = jitem(array,i);
field = jfieldname(item);
if ( (hexstr= jstr(item,field)) != 0 && is_hexstr(hexstr,0) == 66 )
{
item = jitem(array,i);
field = jfieldname(item);
if ( (hexstr= jstr(item,field)) != 0 && is_hexstr(hexstr,0) == 66 )
{
Notaries_elected[i][0] = clonestr(field);
Notaries_elected[i][1] = clonestr(hexstr);
//printf("%d of %d: %s %s\n",i,n,field,hexstr);
}
else
{
printf("couldnt find (%s) in %s or non-hex (%s)\n",field,jprint(item,0),hexstr!=0?hexstr:"");
break;
}
Notaries_elected[i][0] = clonestr(field);
Notaries_elected[i][1] = clonestr(hexstr);
//printf("%d of %d: %s %s\n",i,n,field,hexstr);
}
if ( i == n )
else
{
Notaries_num = n;
retval = 0;
printf("numnotaries %d, port.%d minsigs.%d BTCminsigs.%d\n",Notaries_num,Notaries_port,Notaries_BTCminsigs,Notaries_minsigs);
printf("couldnt find (%s) in %s or non-hex (%s)\n",field,jprint(item,0),hexstr!=0?hexstr:"");
break;
}
}
free_json(argjson);
if ( i == n )
{
Notaries_num = n;
retval = 0;
//printf("numnotaries %d, port.%d minsigs.%d BTCminsigs.%d\n",Notaries_num,Notaries_port,Notaries_BTCminsigs,Notaries_minsigs);
}
}
free_json(argjson);
}
portable_mutex_unlock(&notaries_mutex);
return(retval);
}
int32_t komodo_initjson(char *fname)
{
char *fstr; long fsize; int32_t retval = -1;
if ( (fstr= OS_filestr(&fsize,fname)) != 0 )
{
retval = komodo_initjson2(fstr);
free(fstr);
}
return(retval);
@ -169,62 +187,30 @@ int32_t komodo_initjson(char *fname)
int32_t komodo_notaries(char *symbol,uint8_t pubkeys[64][33],int32_t height)
{
int32_t i; //,num=-1; struct iguana_info *coin; char params[256],*retstr,*pubkeystr; cJSON *retjson,*item,*array;
if ( Notaries_num > 0 )
{
for (i=0; i<Notaries_num; i++)
decode_hex(pubkeys[i],33,Notaries_elected[i][1]);
return(Notaries_num);
} else return(-1);
/*if ( (coin= iguana_coinfind(symbol)) != 0 )
int32_t i,num=-1, didinit=0; struct iguana_info *coin; char params[64],*retstr; cJSON *retjson;
#if STAKED
if ( (coin= iguana_coinfind("KMD")) != 0 )
{
if ( height < 0 )
{
if ( (retjson= dpow_getinfo(SuperNET_MYINFO(0),coin)) != 0 )
{
height = jint(retjson,"blocks") - 1;
free_json(retjson);
//printf("komodo_notaries height.%d\n",height);
}
}
if ( height >= 180000 )
{
for (i=0; i<sizeof(Notaries_elected)/sizeof(*Notaries_elected); i++)
decode_hex(pubkeys[i],33,(char *)Notaries_elected[i][1]);
return(i);
}
if ( coin->FULLNODE < 0 )
{
sprintf(params,"[\"%d\"]",height);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"notaries",params)) != 0 )
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getiguanajson","")) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
//printf("%s\n",retstr);
if ( (array= jarray(&num,retjson,"notaries")) != 0 )
{
if ( num > 64 )
{
printf("warning: numnotaries.%d? > 64?\n",num);
num = 64;
}
for (i=0; i<num; i++)
{
item = jitem(array,i);
if ( (pubkeystr= jstr(item,"pubkey")) != 0 && strlen(pubkeystr) == 66 )
decode_hex(pubkeys[i],33,pubkeystr);
else printf("error i.%d of %d (%s)\n",i,num,pubkeystr!=0?pubkeystr:"");
}
//printf("notaries.[%d] <- ht.%d\n",num,height);
}
free_json(retjson);
}
//printf("NOTARIES retstr.%s\n", retstr);
if ( komodo_initjson2(retstr) < 0 )
printf("init notaries failed!\n");
free(retstr);
}
}
}
//printf("komodo_notaries returns.%d\n",num);
return(num);*/
#endif
if ( Notaries_num > 0 )
{
for (i=0; i<Notaries_num; i++)
decode_hex(pubkeys[i],33,Notaries_elected[i][1]);
return(Notaries_num);
} else return(-1);
//printf("staked_notaries returns.%d\n",num);
return(num);
}
bits256 dpow_getbestblockhash(struct supernet_info *myinfo,struct iguana_info *coin)
@ -285,7 +271,7 @@ cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight,ui
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"MoMoMdata",buf)) != 0 )
{
retjson = cJSON_Parse(retstr);
printf("%s kmdheight.%d CCid.%u MoMoM.%s -> %s\n",symbol,kmdheight,CCid,buf,retstr);
//printf("%s kmdheight.%d CCid.%u MoMoM.%s -> %s\n",symbol,kmdheight,CCid,buf,retstr);
free(retstr);
}
usleep(1000);
@ -293,17 +279,24 @@ cJSON *dpow_MoMoMdata(struct iguana_info *coin,char *symbol,int32_t kmdheight,ui
return(retjson);
}
int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsize,uint32_t *paxwdcrcp,bits256 MoM,uint32_t MoMdepth,uint16_t CCid,int32_t src_or_dest,struct dpow_block *bp)
{
struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson,*infojson; int32_t kmdheight=0,hexlen=0,n=0; uint32_t paxwdcrc;
paxwdcrc = 0;
struct iguana_info *coin,*kmdcoin=0; char *retstr,*hexstr; cJSON *retjson,*infojson, *srcinfojson; int32_t kmdheight=0,hexlen=0,n=0,ppMoMheight=0; uint32_t paxwdcrc=0;
if ( dpow_smallopreturn(bp->srccoin->symbol) == 0 || src_or_dest != 0 )
{
n += iguana_rwbignum(1,&hex[n],sizeof(MoM),MoM.bytes);
MoMdepth = (MoMdepth & 0xffff) | ((uint32_t)CCid<<16);
n += iguana_rwnum(1,&hex[n],sizeof(MoMdepth),(uint32_t *)&MoMdepth);
if ( dpow_CCid(myinfo,bp->srccoin) != 0 && src_or_dest == 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) //strncmp(bp->srccoin->symbol,"TXSCL",5) == 0 &&
/*if ( (srcinfojson= dpow_getinfo(myinfo,bp->srccoin)) != 0 )
{
// not needed CCid is passed to this function already, and we dont need the ppmomheight anymore!
CCid = juint(srcinfojson,"CCid");
if ( CCid > 1 )
ppMoMheight = jint(srcinfojson,"ppMoMheight");
free_json(srcinfojson);
//printf("ppMoMheight.%i CCid.%i\n", ppMoMheight, CCid);
} */
if ( CCid > 1 && src_or_dest == 0 && strcmp(bp->destcoin->symbol,"KMD") == 0 ) //strncmp(bp->srccoin->symbol,"TXSCL",5) == 0 &&
{
kmdcoin = bp->destcoin;
if ( (infojson= dpow_getinfo(myinfo,kmdcoin)) != 0 )
@ -311,8 +304,16 @@ int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsiz
kmdheight = jint(infojson,"blocks");
free_json(infojson);
}
if ( (retjson= dpow_MoMoMdata(kmdcoin,bp->srccoin->symbol,kmdheight,bp->CCid)) != 0 )
// 5 block delay is easily enough most of the time. In rare case KMD is reorged more than this,
// the backup notary validation can be used to complete the import.
if ( (retjson= dpow_MoMoMdata(kmdcoin,bp->srccoin->symbol,kmdheight-5,bp->CCid)) != 0 )
{
/*if ( ppMoMheight != 0 && jstr(retjson,"error") != 0 )
{
// MoMoM returned NULL when after 2 MoM exist on the chain.
free_json(retjson);
return(-1);
} */
if ( (hexstr= jstr(retjson,"data")) != 0 && (hexlen= (int32_t)strlen(hexstr)) > 0 && n+hexlen/2 <= hexsize )
{
hexlen >>= 1;
@ -324,8 +325,8 @@ int32_t dpow_paxpending(struct supernet_info *myinfo,uint8_t *hex,int32_t hexsiz
}
paxwdcrc = calc_crc32(0,hex,n) & 0xffffff00;
paxwdcrc |= (n & 0xff);
if ( hexlen > 0 )
printf("%s.ht.%d opretlen.%d src_or_dest.%d dest.(%s) lastbest.%d paxwdcrc.%x\n",bp->srccoin->symbol,bp->height,n,src_or_dest,bp->destcoin->symbol,kmdcoin!=0?((kmdcoin->lastbestheight/10)*10 - 5):-1,paxwdcrc);
//if ( hexlen > 0 )
//printf("%s.ht.%d opretlen.%d src_or_dest.%d dest.(%s) lastbest.%d paxwdcrc.%x\n",bp->srccoin->symbol,bp->height,n,src_or_dest,bp->destcoin->symbol,kmdcoin!=0?((kmdcoin->lastbestheight/10)*10 - 5):-1,paxwdcrc);
}
*paxwdcrcp = paxwdcrc;
return(n);
@ -385,39 +386,6 @@ bits256 dpow_getblockhash(struct supernet_info *myinfo,struct iguana_info *coin,
return(blockhash);
}
int dpow_lockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,char *txid,int32_t vout)
{
char buf[128],*retstr;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"false, [{\"txid\":\"%s\",\"vout\":%d}]", txid, vout);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"lockunspent",buf)) != 0 )
{
//printf("RESULT.(%s)\n",retstr);
free(retstr);
return(1);
} // else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
return(0);
}
int dpow_unlockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,char *txid,int32_t vout)
{
char buf[128],*retstr;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"true, [{\"txid\":\"%s\",\"vout\":%d}]", txid, vout);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"lockunspent",buf)) != 0 )
{
//printf("RESULT.(%s)\n",retstr);
free(retstr);
return(1);
} //else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
return(0);
}
cJSON *dpow_getblock(struct supernet_info *myinfo,struct iguana_info *coin,bits256 blockhash)
{
char buf[128],str[65],*retstr=0; cJSON *json = 0;
@ -506,6 +474,38 @@ cJSON *dpow_gettxout(struct supernet_info *myinfo,struct iguana_info *coin,bits2
return(json);
}
int dpow_lockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,char *txid,int32_t vout)
{
char buf[128],*retstr;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"false, [{\"txid\":\"%s\",\"vout\":%d}]", txid, vout);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"lockunspent",buf)) != 0 )
{
//printf("RESULT.(%s)\n",retstr);
free(retstr);
return(1);
} // else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
return(0);
}
int dpow_unlockunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,char *txid,int32_t vout)
{
char buf[128],*retstr;
if ( coin->FULLNODE < 0 )
{
sprintf(buf,"true, [{\"txid\":\"%s\",\"vout\":%d}]", txid, vout);
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"lockunspent",buf)) != 0 )
{
//printf("RESULT.(%s)\n",retstr);
free(retstr);
return(1);
} //else printf("%s null retstr from (%s)n",coin->symbol,buf);
}
return(0);
}
char *dpow_decoderawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx)
{
char *retstr,*paramstr; cJSON *array;
@ -530,6 +530,23 @@ char *dpow_decoderawtransaction(struct supernet_info *myinfo,struct iguana_info
return(retstr);
}
int32_t dpow_txconfirms(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid, char *rawtx)
{
cJSON *txobj; int32_t confirms = 0, ret = 0;
if ( (txobj= dpow_gettransaction(myinfo, coin, txid)) != 0 )
{
memcpy(rawtx, jstr(txobj, "hex"), strlen(jstr(txobj, "hex"))+1);
if ( (confirms= juint(txobj, "confirmations")) != 0 )
ret = confirms;
else if ( confirms == 1 && juint(txobj, "rawconfirmations") > 100 )
ret = 100;
else
ret = 0;
} else ret = -1;
free_json(txobj);
return(ret);
}
cJSON *dpow_gettransaction(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid)
{
char buf[128],str[65],*retstr=0; cJSON *json = 0;
@ -655,7 +672,7 @@ 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);
@ -750,7 +767,7 @@ char *dpow_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *c
jaddistr(array,signedtx);
paramstr = jprint(array,1);
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"sendrawtransaction",paramstr);
printf(">>>>>>>>>>> %s dpow_sendrawtransaction (%s)\n",coin->symbol,retstr);
fprintf(stderr,">>>>>>>>>>> %s dpow_sendrawtransaction (%s)\n",coin->symbol,retstr);
free(paramstr);
return(retstr);
}

16
iguana/dpow/dpow_tx.c

@ -351,7 +351,7 @@ bits256 dpow_notarytx(struct supernet_info *myinfo,char *signedtx,int32_t *numsi
memcpy(&serialized[len],sig,siglen);
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 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; // usesigs=0 -> insert scriptlen = 0
len += iguana_rwnum(1,&serialized[len],sizeof(sequenceid),&sequenceid);
@ -624,8 +624,6 @@ void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpo
{
dpow_notarytx(myinfo,bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,0,src_or_dest,pubkeys,numratified); // setcrcval
signedtxid = dpow_notarytx(myinfo,bp->signedtx,&numsigs,coin->chain->isPoS,bp,bestk,bestmask,1,src_or_dest,pubkeys,numratified);
//if ( strcmp("GAME",coin->symbol) == 0 || strcmp("EMC2",coin->symbol) == 0 )
// printf("src_or_dest.%d bestk.%d %llx %s numsigs.%d signedtx.(%s)\n",src_or_dest,bestk,(long long)bestmask,bits256_str(str,signedtxid),numsigs,bp->signedtx);
bp->state = 1;
if ( bits256_nonz(signedtxid) != 0 && numsigs == bp->minsigs )
{
@ -641,7 +639,17 @@ void dpow_sigscheck(struct supernet_info *myinfo,struct dpow_info *dp,struct dpo
{
bp->desttxid = txid;
dpow_signedtxgen(myinfo,dp,bp->srccoin,bp,bestk,bestmask,myind,DPOW_SIGCHANNEL,0,numratified != 0);
} else bp->srctxid = txid;
} else
{
bp->srctxid = txid;
#ifdef LOGTX
FILE * fptr;
fptr = fopen("/home/node/complete_notarizations", "a+");
// SRC SRC_TXID DEST DEST_TXID HEIGHT
fprintf(fptr, "%s %s %s\n", bp->srccoin->symbol,bp->srctxid,bp->destcoin->symbol,bp->desttxid,bp->height);
fclose(fptr);
#endif
}
len = (int32_t)strlen(bp->signedtx) >> 1;
decode_hex(txdata+32,len,bp->signedtx);
for (j=0; j<sizeof(srchash); j++)

24
iguana/iguana_notary.c

@ -58,6 +58,20 @@ void dpow_checkpointset(struct supernet_info *myinfo,struct dpow_checkpoint *che
checkpoint->blockhash.height = height;
}
int8_t is_STAKED(const char *chain_name)
{
int8_t ret;
if ( chain_name[0] == 0 )
return(0);
if ( (strcmp(chain_name, "LABS") == 0) || (strncmp(chain_name, "LABS", 4) == 0) )
ret = 1; // These chains are allowed coin emissions.
else if ( (strcmp(chain_name, "CFEK") == 0) || (strncmp(chain_name, "CFEK", 4) == 0) )
ret = 2; // These chains have no speical rules at all.
else if ( (strcmp(chain_name, "TEST") == 0) || (strncmp(chain_name, "TEST", 4) == 0) )
ret = 3; // These chains are for testing consensus to create a chain etc. Not meant to be actually used for anything important.
return(ret);
};
void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t height,bits256 hash,uint32_t timestamp,uint32_t blocktime)
{
//struct komodo_ccdataMoMoM mdata; cJSON *blockjson; uint64_t signedmask; struct iguana_info *coin;
@ -67,10 +81,16 @@ void dpow_srcupdate(struct supernet_info *myinfo,struct dpow_info *dp,int32_t he
dpow_fifoupdate(myinfo,dp->srcfifo,dp->last);
if ( strcmp(dp->dest,"KMD") == 0 )
{
if ( dp->DESTHEIGHT < dp->prevDESTHEIGHT+DPOW_CHECKPOINTFREQ )
int supressfreq = DPOW_CHECKPOINTFREQ;
if ( is_STAKED(dp->symbol) != 0 )
{
dp->minsigs = Notaries_minsigs;
supressfreq = 3;
}
if ( dp->DESTHEIGHT < dp->prevDESTHEIGHT+supressfreq )
{
suppress = 1;
//fprintf(stderr,"suppress %s -> KMD\n",dp->symbol);
//fprintf(stderr,"suppress %s -> KMD freq KMD blocks.%d\n",dp->symbol,checkpointfreq);
}
}
/*if ( strcmp(dp->dest,"KMD") == 0 )//|| strcmp(dp->dest,"CHAIN") == 0 )

46
iguana/main.c

@ -778,10 +778,40 @@ void jumblr_loop(void *ptr)
}
}
void dpow_loop(void *arg)
{
struct supernet_info *myinfo = arg; double startmilli,endmilli;
int32_t counter = 0;
printf("start dpow loop\n");
while ( 1 )
{
counter++;
startmilli = OS_milliseconds();
endmilli = startmilli + 1000;
if ( myinfo->IAMNOTARY != 0 )
{
if ( myinfo->numdpows == 1 )
{
iguana_dPoWupdate(myinfo,myinfo->DPOWS[0]);
endmilli = startmilli + 100;
}
else if ( myinfo->numdpows > 1 )
{
iguana_dPoWupdate(myinfo,myinfo->DPOWS[counter % myinfo->numdpows]);
endmilli = startmilli + 30;
}
}
if ( counter > 1000000 )
counter = 0;
while ( OS_milliseconds() < endmilli )
usleep(10000);
}
}
void iguana_launchdaemons(struct supernet_info *myinfo)
{
int32_t i; char *helperargs,helperstr[512];
if ( IGUANA_NUMHELPERS == 0 )//|| COMMANDLINE_ARGFILE != 0 )
/*if ( IGUANA_NUMHELPERS == 0 )//|| COMMANDLINE_ARGFILE != 0 )
IGUANA_NUMHELPERS = 1;
for (i=0; i<IGUANA_NUMHELPERS; i++)
{
@ -789,12 +819,12 @@ void iguana_launchdaemons(struct supernet_info *myinfo)
helperargs = clonestr(helperstr);
printf("helper launch[%d] of %d (%s)\n",i,IGUANA_NUMHELPERS,helperstr);
iguana_launch(0,"iguana_helper",iguana_helper,helperargs,IGUANA_PERMTHREAD);
}
} */
if ( COMMANDLINE_ARGFILE == 0 )
iguana_launch(0,"rpcloop",iguana_rpcloop,myinfo,IGUANA_PERMTHREAD); // limit to oneprocess
printf("launch mainloop\n");
// disable basilisk: OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)DEX_explorerloop,(void *)myinfo);
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)jumblr_loop,(void *)myinfo);
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_loop,(void *)myinfo);
OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)dpow_psockloop,(void *)myinfo);
mainloop(myinfo);
}
@ -2231,6 +2261,7 @@ void iguana_main(void *arg)
myinfo->IAMNOTARY = 1;
myinfo->DEXEXPLORER = 0;//1; disable as SPV is used now
elected = (char *)arg;
myinfo->nosplit = 1;
}
}
if ( komodo_initjson(elected) < 0 )
@ -2250,7 +2281,7 @@ void iguana_main(void *arg)
return;
}
strcpy(myinfo->rpcsymbol,"BTCD");
iguana_urlinit(myinfo,ismainnet,usessl);
//iguana_urlinit(myinfo,ismainnet,usessl);
portable_mutex_init(&myinfo->pending_mutex);
portable_mutex_init(&myinfo->MoM_mutex);
portable_mutex_init(&myinfo->dpowmutex);
@ -2274,9 +2305,9 @@ void iguana_main(void *arg)
{
if ( iguana_commandline(myinfo,arg) == 0 )
{
iguana_helpinit(myinfo);
//iguana_helpinit(myinfo);
//iguana_relays_init(myinfo);
basilisks_init(myinfo);
//basilisks_init(myinfo);
#ifdef __APPLE__
iguana_appletests(myinfo);
#endif
@ -2290,7 +2321,8 @@ void iguana_main(void *arg)
}
else
{
basilisks_init(myinfo);
//basilisks_init(myinfo);
}
iguana_launchdaemons(myinfo);
}

Loading…
Cancel
Save