From aca83f21ece381629f7e6db176ccd5270fe5a993 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 17 Sep 2016 04:15:07 -0300 Subject: [PATCH] voting server --- basilisk/basilisk copy.c | 1160 --------------------------------- basilisk/basilisk.c | 57 +- basilisk/basilisk_CMD.c | 75 ++- basilisk/basilisk_DEX.c | 12 +- basilisk/basilisk_MSG.c | 10 +- basilisk/basilisk_bitcoin.c | 14 +- basilisk/basilisk_ping.c | 24 +- basilisk/basilisk_vote.c | 405 ++++++++++++ datachain/datachain.c | 2 +- gecko/gecko_blocks.c | 2 +- gecko/gecko_mempool.c | 16 +- iguana/coins/gennotary | 1 + iguana/iguana777.c | 4 +- iguana/iguana777.h | 9 +- iguana/iguana_chains.c | 6 +- iguana/iguana_init.c | 8 +- iguana/iguana_unspents.c | 4 +- iguana/main.c | 26 +- includes/iguana_apideclares.h | 2 + includes/iguana_defines.h | 1 + includes/iguana_funcs.h | 4 +- includes/iguana_globals.h | 4 +- 22 files changed, 560 insertions(+), 1286 deletions(-) delete mode 100755 basilisk/basilisk copy.c create mode 100755 basilisk/basilisk_vote.c create mode 100755 iguana/coins/gennotary diff --git a/basilisk/basilisk copy.c b/basilisk/basilisk copy.c deleted file mode 100755 index 5b9a88c04..000000000 --- a/basilisk/basilisk copy.c +++ /dev/null @@ -1,1160 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "../iguana/iguana777.h" - -typedef char *basilisk_coinfunc(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen); -typedef char *basilisk_servicefunc(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk); -typedef struct basilisk_item *basilisk_requestfunc(struct basilisk_item *Lptr,struct supernet_info *myinfo,bits256 hash,cJSON *valsobj,uint8_t *data,int32_t datalen); - -uint32_t basilisk_calcnonce(struct supernet_info *myinfo,uint8_t *data,int32_t datalen,uint32_t nBits) -{ - int32_t i,numiters = 0; bits256 hash,hash2,threshold; uint32_t basilisktag; - vcalc_sha256(0,hash.bytes,data,datalen); - threshold = bits256_from_compact(nBits); - for (i=0; i 0 ) - break; - } - iguana_rwnum(0,(void *)hash.uints,sizeof(basilisktag),&basilisktag); - iguana_rwnum(1,&data[-sizeof(basilisktag)],sizeof(basilisktag),&basilisktag); - char str[65],str2[65]; printf("found hash after numiters.%d %s vs %s basilisktag.%u\n",numiters,bits256_str(str,threshold),bits256_str(str2,hash2),basilisktag); - return(basilisktag); -} - -char *basilisk_addhexstr(char **ptrp,cJSON *valsobj,char *strbuf,int32_t strsize,uint8_t *data,int32_t datalen) -{ - *ptrp = 0; - if ( data != 0 && datalen > 0 ) - { - if ( valsobj != 0 && jobj(valsobj,"data") != 0 ) - { - printf("basilisk_addhexstr warning: already have data object\n"); - jdelete(valsobj,"data"); - } - if ( (datalen<<1)+1 > strsize ) - { - strbuf = calloc(1,(datalen << 1) + 1); - *ptrp = (void *)strbuf; - } - init_hexbytes_noT(strbuf,data,datalen); - if ( valsobj != 0 ) - jaddstr(valsobj,"data",strbuf); - } else return(0); - return(strbuf); -} - -uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t *space,int32_t spacesize,char *hexstr) -{ - *ptrp = 0; uint8_t *data = 0; - if ( hexstr != 0 && (*datalenp= is_hexstr(hexstr,0)) > 0 ) - { - *datalenp >>= 1; - if ( (*datalenp+hdroffset) <= spacesize ) - { - memset(space,0,hdroffset); - data = &space[hdroffset]; - } else *ptrp = data = calloc(1,*datalenp + hdroffset); - decode_hex(&data[hdroffset],*datalenp,hexstr); - } - if ( data != 0 ) - return(&data[hdroffset]); - else return(data); -} - -uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int32_t spacesize,int32_t *datalenp,char *symbol,cJSON *sendjson,uint32_t basilisktag) -{ - char *sendstr,*hexstr=0; uint8_t *data,hexspace[8192],*allocptr=0,*hexdata; int32_t datalen,hexlen=0; - if ( jobj(sendjson,"symbol") == 0 ) - jaddstr(sendjson,"symbol",symbol); - if ( (hexstr= jstr(sendjson,"data")) != 0 ) - { - hexdata = get_dataptr(0,&allocptr,&hexlen,hexspace,sizeof(hexspace),hexstr); - //printf("delete data.%s from sendjson\n",hexstr); - jdelete(sendjson,"data"); - } - *ptrp = 0; - sendstr = jprint(sendjson,0); - datalen = (int32_t)strlen(sendstr) + 1; - if ( (datalen + extraoffset + BASILISK_HDROFFSET + hexlen) <= spacesize ) - data = space; - else - { - data = calloc(1,datalen + extraoffset + BASILISK_HDROFFSET + hexlen); - *ptrp = data; - } - data += extraoffset + BASILISK_HDROFFSET; - memcpy(data,sendstr,datalen); - //printf("jsondata.(%s) + hexlen.%d\n",sendstr,hexlen); - free(sendstr); - if ( hexlen > 0 ) - { - memcpy(&data[datalen],hexdata,hexlen); - datalen += hexlen; - } - *datalenp = datalen; - if ( allocptr != 0 ) - free(allocptr); - return(data); -} - -char *basilisk_finish(struct basilisk_item *ptr,int32_t besti,char *errstr) -{ - char *retstr = 0; struct basilisk_item *parent; - if ( ptr->retstr != 0 ) - return(ptr->retstr); - if ( besti >= 0 && besti < ptr->numresults ) - { - retstr = ptr->results[besti]; - ptr->results[besti] = 0; - } else printf("besti.%d vs numresults.%d retstr.%p\n",besti,ptr->numresults,retstr); - if ( retstr == 0 ) - retstr = clonestr(errstr); - ptr->retstr = retstr; - ptr->finished = (uint32_t)time(NULL); - if ( (parent= ptr->parent) != 0 ) - { - ptr->parent = 0; - parent->childrendone++; - } - return(retstr); -} - -struct basilisk_item *basilisk_itemcreate(struct supernet_info *myinfo,char *CMD,char *symbol,uint32_t basilisktag,int32_t minresults,cJSON *vals,int32_t timeoutmillis,void *metricfunc) -{ - struct basilisk_item *ptr; - ptr = calloc(1,sizeof(*ptr)); - ptr->basilisktag = basilisktag; - if ( (ptr->numrequired= minresults) == 0 ) - ptr->numrequired = 1; - if ( (ptr->metricfunc= metricfunc) != 0 ) - ptr->vals = jduplicate(vals); - strcpy(ptr->CMD,CMD); - safecopy(ptr->symbol,symbol,sizeof(ptr->symbol)); - ptr->expiration = OS_milliseconds() + timeoutmillis; - return(ptr); -} - -int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *type,uint32_t *basilisktagp,int32_t encryptflag,int32_t delaymillis,uint8_t *data,int32_t datalen,int32_t fanout,uint32_t nBits) // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) -{ - int32_t i,r,l,s,val,n=0,retval = -1; char cmd[12]; struct iguana_info *coin,*tmp; struct iguana_peer *addr; bits256 hash; uint32_t *alreadysent; - if ( fanout <= 0 ) - fanout = BASILISK_MINFANOUT; - else if ( fanout > BASILISK_MAXFANOUT ) - fanout = BASILISK_MAXFANOUT; - if ( type == 0 ) - type = "BTCD"; - if ( strlen(type) > 3 ) - { - printf("basilisk_sendcmd illegal type(%s)\n",type); - return(-1); - } - if ( destipaddr != 0 ) - { - if ( destipaddr[0] == 0 ) - destipaddr = 0; // broadcast - else if ( strcmp(destipaddr,"127.0.0.1") == 0 ) - { - printf("return after locally basilisk_msgprocess\n"); - hash = GENESIS_PUBKEY; - basilisk_msgprocess(myinfo,0,0,type,*basilisktagp,data,datalen); - return(0); - } - } - alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); - iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); - if ( *basilisktagp == 0 ) - { - if ( nBits != 0 ) - *basilisktagp = basilisk_calcnonce(myinfo,data,datalen,nBits); - else *basilisktagp = rand(); - iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); - } - data -= sizeof(*basilisktagp), datalen += sizeof(*basilisktagp); - memset(cmd,0,sizeof(cmd)); - sprintf(cmd,"SuperNET%s",type); - r = rand(); - //portable_mutex_lock(&Allcoins_mutex); - HASH_ITER(hh,myinfo->allcoins,coin,tmp) - { - if ( coin->peers == 0 ) - continue; - if ( coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 ) - cmd[0] = 's'; - else cmd[0] = 'S'; - for (l=0; lpeers->active[i]; - if ( addr->usock >= 0 ) - { - for (s=0; sipbits ) - break; - //printf("%s s.%d vs n.%d\n",addr->ipaddr,s,n); - if ( s == n && (addr->supernet != 0 || addr->basilisk != 0) && (destipaddr == 0 || strcmp(addr->ipaddr,destipaddr) == 0) ) - { - //printf("[%s].tag%d send %s.(%s) [%x] datalen.%d addr->supernet.%u basilisk.%u to (%s).%d destip.%s\n",cmd,*(uint32_t *)data,type,(char *)&data[4],*(int32_t *)&data[datalen-4],datalen,addr->supernet,addr->basilisk,addr->ipaddr,addr->A.port,destipaddr!=0?destipaddr:"broadcast"); - if ( encryptflag != 0 && bits256_nonz(addr->pubkey) != 0 ) - { - void *ptr; uint8_t *cipher,space[8192]; int32_t cipherlen; bits256 privkey; - cmd[6] = 'e', cmd[7] = 't'; - memset(privkey.bytes,0,sizeof(privkey)); - if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&addr->pubkey,data,datalen,space,sizeof(space))) != 0 ) - { - if ( (val= iguana_queue_send(addr,delaymillis,&cipher[-sizeof(struct iguana_msghdr)],cmd,cipherlen)) >= cipherlen ) - n++; - if ( ptr != 0 ) - free(ptr); - } - } - else - { - cmd[6] = 'E', cmd[7] = 'T'; - if ( (val= iguana_queue_send(addr,delaymillis,&data[-sizeof(struct iguana_msghdr)],cmd,datalen)) >= datalen ) - { - alreadysent[n++] = (uint32_t)addr->ipbits; - if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) - break; - } - } - if ( destipaddr != 0 || (fanout > 0 && n >= fanout) ) - { - free(alreadysent); - return(val); - } - else if ( val > retval ) - retval = val; - } - } - } - if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) - break; - } - //portable_mutex_unlock(&Allcoins_mutex); - free(alreadysent); - return(n); -} - -void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t datalen,char *type,int32_t encrypted) -{ - uint32_t ipbits,basilisktag; int32_t msglen,len=0; void *ptr = 0; uint8_t space[8192]; bits256 senderpub; struct supernet_info *myinfo = _myinfo; - if ( encrypted != 0 ) - { - printf("encrypted p2p\n"); - memset(senderpub.bytes,0,sizeof(senderpub)); - if ( (data= SuperNET_deciphercalc(&ptr,&msglen,myinfo->privkey,senderpub,data,datalen,space,sizeof(space))) == 0 ) - { - printf("basilisk_p2p decrytion error\n"); - return; - } else datalen = msglen; - } - if ( senderip != 0 && senderip[0] != 0 && strcmp(senderip,"127.0.0.1") != 0 ) - ipbits = (uint32_t)calc_ipbits(senderip); - else ipbits = 0; - len += iguana_rwnum(0,data,sizeof(basilisktag),&basilisktag); - //int32_t i; for (i=0; ireceived.%d basilisk_p2p.(%s) from %s tag.%d\n",datalen,type,senderip!=0?senderip:"?",basilisktag); - basilisk_msgprocess(myinfo,_addr,ipbits,type,basilisktag,&data[len],datalen - len); - if ( ptr != 0 ) - free(ptr); -} - -void basilisk_sendback(struct supernet_info *myinfo,char *origCMD,char *symbol,char *remoteaddr,uint32_t basilisktag,char *retstr) -{ - uint8_t *data,space[4096],*allocptr; struct iguana_info *virt; cJSON *valsobj; int32_t datalen,encryptflag=0,delaymillis=0; - //printf("%s retstr.(%s) -> remote.(%s) basilisktag.%u\n",origCMD,retstr,remoteaddr,basilisktag); - if ( retstr != 0 && remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 ) - { - if ( (valsobj= cJSON_Parse(retstr)) != 0 ) - { - jaddstr(valsobj,"origcmd",origCMD); - jaddstr(valsobj,"symbol",symbol); - if ( (virt= iguana_coinfind(symbol)) != 0 ) - { - jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); - jaddbits256(valsobj,"chaintip",virt->blocks.hwmchain.RO.hash2); - } - data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); - basilisk_sendcmd(myinfo,remoteaddr,"RET",&basilisktag,encryptflag,delaymillis,data,datalen,0,0); - if ( allocptr != 0 ) - free(allocptr); - free_json(valsobj); - } - } -} - -char *basilisk_waitresponse(struct supernet_info *myinfo,char *CMD,char *symbol,char *remoteaddr,struct basilisk_item *Lptr,struct basilisk_item *ptr) -{ - char *retstr = 0; - if ( ptr == Lptr ) - { - if ( (retstr= Lptr->retstr) == 0 ) - retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}"); - ptr = basilisk_itemcreate(myinfo,CMD,symbol,Lptr->basilisktag,Lptr->numrequired,Lptr->vals,OS_milliseconds() - Lptr->expiration,Lptr->metricfunc); - queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - } - else - { - queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - while ( OS_milliseconds() < ptr->expiration ) - { - //if ( (retstr= basilisk_iscomplete(ptr)) != 0 ) - if ( (retstr= ptr->retstr) != 0 ) - break; - usleep(50000); - } - if ( retstr == 0 ) - retstr = basilisk_finish(ptr,-1,"{\"error\":\"basilisk timeout\"}"); - } - basilisk_sendback(myinfo,CMD,symbol,remoteaddr,ptr->basilisktag,retstr); - return(retstr); -} - -struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,int32_t *numsentp,char *CMD,char *symbol,int32_t blockflag,cJSON *valsobj,int32_t fanout,int32_t minresults,uint32_t basilisktag,int32_t timeoutmillis,void *_metricfunc,char *retstr,int32_t encryptflag,int32_t delaymillis,uint32_t nBits) -{ - struct basilisk_item *ptr; uint8_t *allocptr,*data,space[4096]; int32_t datalen; basilisk_metricfunc metricfunc = _metricfunc; - ptr = basilisk_itemcreate(myinfo,CMD,symbol,basilisktag,minresults,valsobj,timeoutmillis,metricfunc); - ptr->nBits = nBits; - *numsentp = 0; - if ( retstr != 0 ) - { - ptr->results[0] = ptr->retstr = retstr; - ptr->numresults = ptr->numrequired; - ptr->metrics[0] = (*metricfunc)(myinfo,ptr,retstr); - ptr->finished = (uint32_t)time(NULL); - } - else - { - data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); - *numsentp = ptr->numsent = basilisk_sendcmd(myinfo,0,CMD,&ptr->basilisktag,encryptflag,delaymillis,data,datalen,1,ptr->nBits); - if ( blockflag != 0 ) - queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - else ptr->finished = (uint32_t)time(NULL); - if ( allocptr != 0 ) - free(allocptr); - } - return(ptr); -} - -struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char *CMD,int32_t blockflag,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits) -{ - int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag,fanout; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt,*btcd; - if ( (btcd= iguana_coinfind("BTCD")) != 0 && btcd->RELAYNODE != 0 ) - jaddnum(valsobj,"iamrelay",1); - basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen); - if ( bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0 ) - { - if ( jobj(valsobj,"hash") != 0 ) - jdelete(valsobj,"hash"); - jaddbits256(valsobj,"hash",hash); - } - if ( (minresults= jint(valsobj,"minresults")) <= 0 ) - minresults = 1; - if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) - timeoutmillis = BASILISK_TIMEOUT; - if ( jobj(valsobj,"fanout") == 0 ) - fanout = 1; - else fanout = jint(valsobj,"fanout"); - if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) - { - if ( (virt= iguana_coinfind(symbol)) != 0 ) - { - jaddstr(valsobj,"symbol",symbol); - jaddnum(valsobj,"longest",virt->longestchain); - jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); - } - } - encryptflag = jint(valsobj,"encrypt"); - delaymillis = jint(valsobj,"delay"); - ptr = basilisk_issueremote(myinfo,&numsent,CMD,"BTCD",blockflag,valsobj,fanout,minresults,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); - return(ptr); -} - -char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag) // client side -{ - uint32_t nBits = 0; uint8_t space[8192],*allocptr=0,*data = 0; struct basilisk_item *ptr,Lptr; int32_t datalen = 0; cJSON *retjson; - retjson = cJSON_CreateObject(); - data = get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr); - ptr = basilisk_requestservice(myinfo,CMD,blockflag,valsobj,hash,data,datalen,nBits); - if ( allocptr != 0 ) - free(allocptr); - if ( ptr != 0 ) - { - if ( blockflag != 0 ) - { - if ( ptr->expiration <= OS_milliseconds() ) - ptr->expiration = OS_milliseconds() + BASILISK_TIMEOUT; - ptr->vals = jduplicate(valsobj); - strcpy(ptr->symbol,"BTCD"); - strcpy(ptr->CMD,CMD); - return(basilisk_waitresponse(myinfo,CMD,"BTCD",0,&Lptr,ptr)); - } - else if ( ptr->numsent > 0 ) - { - queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"numsent",ptr->numsent); - } else jaddstr(retjson,"error","didnt find any nodes to send to"); - } else jaddstr(retjson,"error","couldnt create basilisk item"); - return(jprint(retjson,1)); -} - -#include "basilisk_bitcoin.c" -#include "basilisk_nxt.c" -#include "basilisk_ether.c" -#include "basilisk_waves.c" -#include "basilisk_lisk.c" -#include "basilisk_CMD.c" - -void basilisk_functions(struct iguana_info *coin,int32_t protocol) -{ - coin->protocol = protocol; - switch ( protocol ) - { - case IGUANA_PROTOCOL_BITCOIN: - coin->basilisk_balances = basilisk_bitcoinbalances; - coin->basilisk_rawtx = basilisk_bitcoinrawtx; - coin->basilisk_rawtxmetric = basilisk_bitcoin_rawtxmetric; - coin->basilisk_value = basilisk_bitcoinvalue; - coin->basilisk_valuemetric = basilisk_bitcoin_valuemetric; - break; - /*case IGUANA_PROTOCOL_IOTA: - coin->basilisk_balances = basilisk_iotabalances; - coin->basilisk_rawtx = basilisk_iotarawtx; - break; - case IGUANA_PROTOCOL_NXT: - coin->basilisk_balances = basilisk_nxtbalances; - coin->basilisk_rawtx = basilisk_nxtrawtx; - break; - case IGUANA_PROTOCOL_ETHER: - coin->basilisk_balances = basilisk_etherbalances; - coin->basilisk_rawtx = basilisk_etherrawtx; - break; - case IGUANA_PROTOCOL_WAVES: - coin->basilisk_balances = basilisk_wavesbalances; - coin->basilisk_rawtx = basilisk_wavesrawtx; - break; - case IGUANA_PROTOCOL_LISK: - coin->basilisk_balances = basilisk_liskbalances; - coin->basilisk_rawtx = basilisk_liskrawtx; - break;*/ - } -} - -int32_t basilisk_besti(struct basilisk_item *ptr) -{ - int32_t i,besti = -1; double metric,bestmetric=-1.; - for (i=0; inumresults; i++) - { - if ( (metric= ptr->metrics[i]) > 0. ) - { - if ( (ptr->metricdir < 0 && (bestmetric < 0. || metric < bestmetric)) || (ptr->metricdir > 0 && (bestmetric < 0. || metric > bestmetric)) || (ptr->metricdir == 0 && bestmetric < 0.) ) - { - bestmetric = metric; - besti = i; - } - } - } - if ( besti >= 0 ) - { - for (ptr->numexact=i=0; inumresults; i++) - if ( fabs(ptr->metrics[i] - bestmetric) < SMALLVAL ) - ptr->numexact++; - } - return(besti); -} - -char *basilisk_iscomplete(struct basilisk_item *ptr) -{ - int32_t i,numvalid,besti=-1; char *errstr = 0,*retstr = 0; - if ( ptr->childrendone < ptr->numchildren ) - return(0); - if ( ptr->retstr != 0 || ptr->finished != 0 ) - return(ptr->retstr); - if ( (numvalid= ptr->numresults) >= ptr->numrequired ) - { - for (i=numvalid=0; inumresults; i++) - { - if ( ptr->metrics[i] != 0. ) - numvalid++; - } - } - if ( numvalid < ptr->numrequired ) - { - //printf("%u: numvalid.%d < required.%d m %f\n",ptr->basilisktag,numvalid,ptr->numrequired,ptr->metrics[0]); - return(0); - } - if ( ptr->uniqueflag == 0 && ptr->numexact != ptr->numresults && ptr->numexact < (ptr->numresults >> 1) ) - besti = -1, errstr = "{\"error\":\"basilisk non-consensus results\"}"; - else besti = basilisk_besti(ptr), errstr = "{\"error\":\"basilisk no valid results\"}"; - //printf("%u complete besti.%d\n",ptr->basilisktag,besti); - retstr = basilisk_finish(ptr,besti,errstr); - //printf("%u besti.%d numexact.%d numresults.%d -> (%s)\n",ptr->basilisktag,besti,ptr->numexact,ptr->numresults,retstr); - return(retstr); -} - -struct basilisk_item *basilisk_issuecmd(struct basilisk_item *Lptr,basilisk_func func,basilisk_metricfunc metricfunc,struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,int32_t timeoutmillis,cJSON *vals) -{ - struct iguana_info *coin; struct basilisk_item *ptr; - memset(Lptr,0,sizeof(*Lptr)); - if ( (coin= iguana_coinfind(symbol)) != 0 ) - { - if ( func != 0 ) - { - if ( (ptr= (*func)(Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) - { - if ( (ptr->metricfunc= metricfunc) != 0 ) - ptr->vals = jduplicate(vals); - strcpy(ptr->symbol,symbol); - ptr->basilisktag = basilisktag; - ptr->expiration = OS_milliseconds() + timeoutmillis; - return(ptr); - } else Lptr->retstr = clonestr("{\"error\":\"error issuing basilisk command\"}"); - } else Lptr->retstr = clonestr("{\"error\":\"null basilisk function\"}"); - } else Lptr->retstr = clonestr("{\"error\":\"error missing coin\"}"); - return(Lptr); -} - -char *basilisk_check(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) -{ - if ( symbol != 0 && symbol[0] != 0 && vals != 0 ) - { - if ( *basilisktagp == 0 ) - *basilisktagp = rand(); - if ( (*timeoutmillisp= jint(vals,"timeout")) < 0 ) - *timeoutmillisp = BASILISK_TIMEOUT; - return(0); - } else return(clonestr("{\"error\":\"missing activecoin or vals\"}")); -} - -char *basilisk_standardcmd(struct supernet_info *myinfo,char *CMD,char *activecoin,char *remoteaddr,uint32_t basilisktag,cJSON *vals,basilisk_func func,basilisk_metricfunc metric) -{ - char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; struct iguana_info *coin; - if ( (retstr= basilisk_check(&timeoutmillis,&basilisktag,activecoin,vals)) == 0 ) - { - if ( (coin= iguana_coinfind(activecoin)) != 0 ) - { - if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) - { - return(basilisk_waitresponse(myinfo,CMD,coin->symbol,remoteaddr,&Lptr,ptr)); - } - else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}")); - } else return(clonestr("{\"error\":\"couldnt get coin\"}")); - } else return(retstr); -} - -char *_basilisk_value(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) -{ - return(basilisk_standardcmd(myinfo,"VAL",coin->symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_value,coin->basilisk_valuemetric)); -} - -char *_basilisk_balances(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) -{ - return(basilisk_standardcmd(myinfo,"BAL",coin->symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_balances,coin->basilisk_balancesmetric)); -} - -char *_basilisk_rawtx(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) -{ - char *retstr,strbuf[4096],*str = 0; - printf("remote rawtx.(%s)\n",jprint(valsobj,0)); - basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); - retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); - if ( str != 0 ) - free(str); - return(retstr); -} - -char *_basilisk_result(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) -{ - char strbuf[4096],*str = 0; - basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); - return(basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj)); -} - -char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) -{ - cJSON *addresses=0; char *changeaddr,*spendscriptstr; int32_t i,n; - *timeoutmillisp = -1; - changeaddr = jstr(vals,"changeaddr"); - spendscriptstr = jstr(vals,"spendscript"); - addresses = jarray(&n,vals,"addresses"); - if ( addresses == 0 || changeaddr == 0 || changeaddr[0] == 0 ) - return(clonestr("{\"error\":\"invalid addresses[] or changeaddr\"}")); - else - { - for (i=0; isymbol); - if ( (retstr= basilisk_standardservice(CMD,myinfo,hash,vals,hexstr,0)) != 0 ) - free(retstr); - free_json(vals); - if ( allocptr != 0 ) - free(allocptr); - } - return(0); - } else return(-1); -} - -#include "../includes/iguana_apidefs.h" -#include "../includes/iguana_apideclares.h" - -INT_ARRAY_STRING(basilisk,balances,basilisktag,vals,activecoin) -{ - return(basilisk_standardcmd(myinfo,"BAL",activecoin,remoteaddr,basilisktag,vals,coin->basilisk_balances,coin->basilisk_balancesmetric)); -} - -INT_ARRAY_STRING(basilisk,value,basilisktag,vals,activecoin) -{ - return(basilisk_standardcmd(myinfo,"VAL",activecoin,remoteaddr,basilisktag,vals,coin->basilisk_value,coin->basilisk_valuemetric)); -} - -INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin) -{ - char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; - if ( (retstr= basilisk_checkrawtx(&timeoutmillis,(uint32_t *)&basilisktag,activecoin,vals)) == 0 ) - { - coin = iguana_coinfind(activecoin); - if ( coin != 0 && (ptr= basilisk_issuecmd(&Lptr,coin->basilisk_rawtx,coin->basilisk_rawtxmetric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) - { - if ( (ptr->numrequired= juint(vals,"numrequired")) == 0 ) - ptr->numrequired = 1; - ptr->uniqueflag = 1; - ptr->metricdir = -1; - return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,ptr)); - } else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}")); - } else return(retstr); -} - -INT_AND_ARRAY(basilisk,result,basilisktag,vals) -{ - struct basilisk_item *ptr; - if ( vals != 0 ) - { - ptr = calloc(1,sizeof(*ptr)); - ptr->retstr = jprint(vals,0); - ptr->basilisktag = basilisktag; - strcpy(ptr->remoteaddr,remoteaddr); - safecopy(ptr->CMD,jstr(vals,"origcmd"),sizeof(ptr->CMD)); - printf("(%s) -> Q.%u results vals.(%s)\n",ptr->CMD,basilisktag,ptr->retstr); - queue_enqueue("resultsQ",&myinfo->basilisks.resultsQ,&ptr->DL,0); - return(clonestr("{\"result\":\"queued basilisk return\"}")); - } else printf("null vals.(%s) or no hexmsg.%p\n",jprint(vals,0),vals); - return(clonestr("{\"error\":\"no hexmsg to return\"}")); -} - -HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr) -{ - return(basilisk_standardservice("ADD",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,relays,hash,vals,hexstr) -{ - return(basilisk_standardservice("RLY",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr) -{ - return(basilisk_standardservice("RUN",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,publish,hash,vals,hexstr) -{ - return(basilisk_standardservice("PUB",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,subscribe,hash,vals,hexstr) -{ - return(basilisk_standardservice("SUB",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,forward,hash,vals,hexstr) -{ - return(basilisk_standardservice("HOP",myinfo,hash,vals,hexstr,0)); -} - -HASH_ARRAY_STRING(basilisk,mailbox,hash,vals,hexstr) -{ - return(basilisk_standardservice("BOX",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr) -{ - return(basilisk_standardservice("VPN",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,VPNjoin,hash,vals,hexstr) -{ - return(basilisk_standardservice("ARC",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,VPNmessage,hash,vals,hexstr) -{ - return(basilisk_standardservice("GAB",myinfo,hash,vals,hexstr,0)); -} - -HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr) -{ - return(basilisk_standardservice("SAY",myinfo,hash,vals,hexstr,0)); -} - -HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr) -{ - return(basilisk_standardservice("EAR",myinfo,hash,vals,hexstr,1)); -} - -HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr) -{ - return(basilisk_standardservice("END",myinfo,hash,vals,hexstr,0)); -} - -#include "../includes/iguana_apiundefs.h" - -// set hwm, get headers, then blocks - -void basilisk_geckoresult(struct supernet_info *myinfo,struct basilisk_item *ptr) -{ - uint8_t *data,space[16384],*allocptr = 0; struct iguana_info *virt; char *symbol,*str,*type; int32_t datalen; cJSON *retjson; bits256 hash2; - if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) - { - if ( (symbol= jstr(retjson,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) - { - if ( (data= get_dataptr(0,&allocptr,&datalen,space,sizeof(space),jstr(retjson,"data"))) != 0 ) - { - str = 0; - if ( (type= jstr(retjson,"type")) != 0 ) - { - hash2 = jbits256(retjson,"hash"); - if ( strcmp(type,"HDR") == 0 ) - str = gecko_headersarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); - else if ( strcmp(type,"MEM") == 0 ) - str = gecko_mempoolarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); - else if ( strcmp(type,"BLK") == 0 ) - str = gecko_blockarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); - else if ( strcmp(type,"GTX") == 0 ) - str = gecko_txarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); - } - if ( str != 0 ) - free(str); - if ( allocptr != 0 ) - free(allocptr); - } - } - free_json(retjson); - } -} - -void basilisk_pending_result(struct supernet_info *myinfo,struct basilisk_item *ptr,struct basilisk_item *pending) -{ - int32_t n; struct basilisk_item *parent; basilisk_metricfunc metricfunc; - if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) ) - { - pending->numresults++; - if ( (metricfunc= pending->metricfunc) == 0 ) - pending->metrics[n] = n + 1; - else if ( (pending->metrics[n]= (*metricfunc)(myinfo,pending,ptr->retstr)) != 0. ) - pending->childrendone++; - printf("%s.%u Add results[%d] <- metric %f\n",pending->CMD,pending->basilisktag,n,pending->metrics[n]); - pending->results[n] = ptr->retstr, ptr->retstr = 0; - /*if ( strcmp(ptr->CMD,"SEQ") == 0 ) - { - if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) - { - gecko_seqresult(myinfo,ptr->retstr); - free_json(retjson); - } - } - else*/ - if ( strcmp(ptr->CMD,"RET") == 0 || strcmp(ptr->CMD,"GET") == 0 ) - { - printf("got return for tag.%d parent.%p\n",pending->basilisktag,pending->parent); - if ( (parent= pending->parent) != 0 ) - { - pending->parent = 0; - parent->childrendone++; - } - if ( strcmp(ptr->CMD,"GET") == 0 ) - basilisk_geckoresult(myinfo,ptr); - } - } -} - -int32_t basilisk_issued_iteration(struct supernet_info *myinfo,struct basilisk_item *pending) -{ - basilisk_metricfunc metricfunc; struct basilisk_item *parent; int32_t i,flag = 0; - //printf("pending.%u numresults.%d m %f func.%p\n",pending->basilisktag,pending->numresults,pending->metrics[0],pending->metricfunc); - if ( (metricfunc= pending->metricfunc) != 0 ) - { - for (i=0; inumresults; i++) - if ( pending->metrics[i] == 0. && pending->results[i] != 0 ) - { - if ( (pending->metrics[i]= (*metricfunc)(myinfo,pending,pending->results[i])) != 0 ) - pending->childrendone++; - // printf("iter.%d %p.[%d] poll metrics.%u metric %f\n",iter,pending,i,pending->basilisktag,pending->metrics[i]); - flag++; - } - } - basilisk_iscomplete(pending); - if ( OS_milliseconds() > pending->expiration ) - { - if ( pending->finished == 0 ) - { - if ( (parent= pending->parent) != 0 ) - { - pending->parent = 0; - parent->childrendone++; - } - pending->finished = (uint32_t)time(NULL); - if ( pending->retstr == 0 ) - pending->retstr = clonestr("{\"error\":\"basilisk timeout\"}"); - fprintf(stderr,"timeout.%s call metrics.%u lag %f - %f\n",pending->CMD,pending->basilisktag,OS_milliseconds(),pending->expiration); - for (i=0; inumresults; i++) - if ( (metricfunc= pending->metricfunc) != 0 && pending->metrics[i] == 0. ) - pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); - flag++; - } - } - //fprintf(stderr,"c"); - if ( pending->finished != 0 && time(NULL) > pending->finished+60 ) - { - if ( pending->dependents == 0 || pending->childrendone >= pending->numchildren ) - { - HASH_DELETE(hh,myinfo->basilisks.issued,pending); - if ( pending->dependents != 0 ) - free(pending->dependents); - fprintf(stderr,"HASH_DELETE free ptr.%u refcount.%d\n",pending->basilisktag,pending->refcount); - for (i=0; inumresults; i++) - if ( pending->results[i] != 0 ) - free(pending->results[i]), pending->results[i] = 0; - if ( pending->vals != 0 ) - free_json(pending->vals), pending->vals = 0; - free(pending); - flag++; - } - } - return(flag); -} - -void basilisks_loop(void *arg) -{ - struct iguana_info *btcd,*virt,*hhtmp; struct basilisk_item *ptr,*tmp,*pending; int32_t iter,maxmillis,flag; struct supernet_info *myinfo = arg; - iter = 0; - while ( 1 ) - { - iter++; - if ( (ptr= queue_dequeue(&myinfo->basilisks.submitQ,0)) != 0 ) - HASH_ADD(hh,myinfo->basilisks.issued,basilisktag,sizeof(ptr->basilisktag),ptr); - //fprintf(stderr,"A"); - else if ( (ptr= queue_dequeue(&myinfo->basilisks.resultsQ,0)) != 0 ) - { - HASH_FIND(hh,myinfo->basilisks.issued,&ptr->basilisktag,sizeof(ptr->basilisktag),pending); - if ( pending != 0 ) - basilisk_pending_result(myinfo,ptr,pending); - else printf("couldnt find issued.%u\n",ptr->basilisktag); - free(ptr); - } - else - { - flag = 0; - HASH_ITER(hh,myinfo->basilisks.issued,pending,tmp) - { - flag += basilisk_issued_iteration(myinfo,pending); - } - if ( flag == 0 && myinfo->allcoins_numvirts > 0 && (btcd= iguana_coinfind("BTCD")) != 0 ) - { - maxmillis = (1000 / myinfo->allcoins_numvirts) + 1; - //portable_mutex_lock(&Allcoins_mutex); - HASH_ITER(hh,myinfo->allcoins,virt,hhtmp) - { - if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) - { - //fprintf(stderr,"h"); - gecko_iteration(myinfo,btcd,virt,maxmillis); - flag++; - } - } - //portable_mutex_unlock(&Allcoins_mutex); - } - } - //fprintf(stderr,"i "); - //for (i=0; iRELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 && coin->MAXPEERS == 1 ) - // basilisk_bitcoinscan(coin,blockspace,&RAWMEM); - if ( flag == 0 ) - usleep(10000); - } -} - -void basilisks_init(struct supernet_info *myinfo) -{ - iguana_initQ(&myinfo->basilisks.submitQ,"submitQ"); - iguana_initQ(&myinfo->basilisks.resultsQ,"resultsQ"); - portable_mutex_init(&myinfo->allcoins_mutex); - portable_mutex_init(&myinfo->basilisk_mutex); - portable_mutex_init(&myinfo->gecko_mutex); - myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD); -} - -void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin) -{ - if ( coin != 0 ) - { - while ( coin->basilisk_busy != 0 ) - usleep(1000); - } - else - { - while ( myinfo->basilisk_busy != 0 ) - usleep(1000); - } -} - -void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen) -{ - cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t height,origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0; bits256 hash; struct iguana_peer *addr = _addr; - static basilisk_servicefunc *basilisk_services[][2] = - { - { (void *)"RUN", &basilisk_respond_dispatch }, // higher level protocol handler, pass through - { (void *)"BYE", &basilisk_respond_goodbye }, // disconnect - - // gecko chains - { (void *)"NEW", &basilisk_respond_newgeckochain }, // creates new virtual gecko chain - { (void *)"GEN", &basilisk_respond_geckogenesis }, // returns genesis list - { (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx - { (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers - { (void *)"BLK", &basilisk_respond_geckoblock }, // reports block - { (void *)"MEM", &basilisk_respond_mempool }, // reports mempool - { (void *)"GTX", &basilisk_respond_geckotx }, // reports tx - //{ (void *)"SEQ", &basilisk_respond_hashstamps }, // BTCD and BTC recent hashes from timestamp - - // unencrypted low level functions, used by higher level protocols and virtual network funcs - { (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus - { (void *)"RLY", &basilisk_respond_relays }, - { (void *)"DEX", &basilisk_respond_instantdex }, - - // encrypted data for jumblr - { (void *)"HOP", &basilisk_respond_forward }, // message forwarding - { (void *)"BOX", &basilisk_respond_mailbox }, // create/send/check mailbox pubkey - - // small virtual private network - { (void *)"VPN", &basilisk_respond_VPNcreate }, // create virtual network's hub via privkey - { (void *)"ARC", &basilisk_respond_VPNjoin }, // join - { (void *)"GAB", &basilisk_respond_VPNmessage }, // private message - { (void *)"SAY", &basilisk_respond_VPNbroadcast }, // broadcast - { (void *)"EAR", &basilisk_respond_VPNreceive }, // network receive (via poll) - { (void *)"END", &basilisk_respond_VPNlogout }, // logout - - // coin services - { (void *)"RAW", &_basilisk_rawtx }, - { (void *)"VAL", &_basilisk_value }, - }; - /*static basilisk_coinfunc *basilisk_coinservices[][2] = - { - { (void *)"RAW", &_basilisk_rawtx }, - { (void *)"VAL", &_basilisk_value }, - { (void *)"BAL", &_basilisk_balances }, - };*/ - symbol = "BTCD"; - if ( (valsobj= cJSON_Parse((char *)data)) != 0 ) - { - //printf("MSGVALS.(%s)\n",(char *)data); - if ( jobj(valsobj,"coin") != 0 ) - coin = iguana_coinfind(jstr(valsobj,"coin")); - else if ( jobj(valsobj,"symbol") != 0 ) - coin = iguana_coinfind(jstr(valsobj,"symbol")); - if ( coin != 0 ) - { - if ( (height= juint(valsobj,"hwm")) > 0 ) - { - if ( height > addr->height ) - addr->height = height; - if ( height > coin->longestchain ) - coin->longestchain = height; - } - } - if ( strcmp(type,"RET") == 0 ) - { - if ( (retstr= _basilisk_result(myinfo,coin,addr,remoteaddr,basilisktag,valsobj,data,datalen)) != 0 ) - free(retstr); - return; - } - } else return; - for (i=flag=0; ibasilisk_busy = 1; - if ( valsobj != 0 ) - { - jsonlen = (int32_t)strlen((char *)data) + 1; - if ( datalen > jsonlen ) - data += jsonlen, datalen -= jsonlen; - else data = 0, datalen = 0; - if ( coin == 0 ) - coin = iguana_coinfind("BTCD"); - if ( coin != 0 ) - { - symbol = coin->symbol; - coin->basilisk_busy = 1; - } - hash = jbits256(valsobj,"hash"); - timeoutmillis = jint(valsobj,"timeout"); - if ( (numrequired= jint(valsobj,"numrequired")) == 0 ) - numrequired = 1; - if ( senderipbits != 0 ) - expand_ipbits(remoteaddr,senderipbits); - else remoteaddr[0] = 0; - /*if ( valsobj != 0 && remoteaddr != 0 ) - { - if ( from_basilisk == 0 ) - { - if ( strcmp(CMD,"RLY") == 0 ) - { - printf("add relay path\n"); - if ( juint(valsobj,"iamrelay") != 0 ) - { - retstr = basilisk_respond_relays(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk); - } - free_json(valsobj); - if ( coin != 0 ) - coin->basilisk_busy = 0; - myinfo->basilisk_busy = 0; - return; - } - else if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(remoteaddr),GENESIS_PUBKEY)) != 0 ) - free(retstr); - } - }*/ - for (i=0; iIAMRELAY != 0 ) // iguana node - { - if ( 0 && from_basilisk != 0 ) - { - printf("echo to other relays\n"); - basilisk_sendcmd(myinfo,0,cmd,&basilisktag,0,0,origdata,origlen,-1,0); // to other iguanas - } - if ( (retstr= (*basilisk_services[i][1])(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk)) != 0 ) - { - //printf("from_basilisk.%d ret.(%s)\n",from_basilisk,retstr); - if ( from_basilisk != 0 || strcmp(CMD,"GET") == 0 ) - basilisk_sendback(myinfo,CMD,symbol,remoteaddr,basilisktag,retstr); - if ( retstr != 0 ) - free(retstr); - } //else printf("services null return\n"); - } else printf("non-relay got unexpected.(%s)\n",type); - /*free_json(valsobj); - if ( coin != 0 ) - coin->basilisk_busy = 0; - myinfo->basilisk_busy = 0; - return;*/ - } - } - /*if ( coin != 0 ) - { - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node - { - if ( 0 && from_basilisk != 0 ) - { - printf("echo to other relays\n"); - basilisk_sendcmd(myinfo,0,cmd,&basilisktag,0,0,origdata,origlen,-1,0); // to other iguanas - } - for (i=0; ibasilisk_busy = 0; - myinfo->basilisk_busy = 0; -} - - diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c index 8f5c8f64d..54334de3a 100755 --- a/basilisk/basilisk.c +++ b/basilisk/basilisk.c @@ -17,7 +17,7 @@ typedef char *basilisk_servicefunc(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk); -int32_t basilisk_specialcmd(char *cmd) +int32_t basilisk_notarycmd(char *cmd) { //&& strcmp(cmd,"DEX") != 0 && strcmp(cmd,"ACC") != 0 && strcmp(cmd,"RID") != 0 && if ( strcmp(cmd,"PIN") != 0 && strcmp(cmd,"OUT") != 0 && strcmp(cmd,"MSG") != 0 ) @@ -149,7 +149,7 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ { int32_t i,l,s,valid,val,n=0,retval = -1; char cmd[12]; struct iguana_info *coin,*tmp; struct iguana_peer *addr; bits256 hash; uint32_t *alreadysent,r,r2; if ( fanout <= 0 ) - fanout = sqrt(NUMRELAYS) + 1; + fanout = sqrt(myinfo->NOTARY.NUMRELAYS) + 1; else if ( fanout > BASILISK_MAXFANOUT ) fanout = BASILISK_MAXFANOUT; if ( type == 0 ) @@ -205,7 +205,7 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ } return(-1); } - if ( basilisk_specialcmd(type) != 0 && NUMRELAYS == 0 ) + if ( basilisk_notarycmd(type) != 0 && myinfo->NOTARY.NUMRELAYS == 0 ) return(-1); //portable_mutex_lock(&myinfo->allcoins_mutex); alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); @@ -228,19 +228,19 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ { s = 0; valid = (addr->supernet != 0); - if ( basilisk_specialcmd(type) != 0 ) + if ( basilisk_notarycmd(type) != 0 ) { valid = 0; OS_randombytes((void *)&r2,sizeof(r2)); - if ( (r2 % NUMRELAYS) >= sqrt(NUMRELAYS) ) + if ( (r2 % myinfo->NOTARY.NUMRELAYS) >= sqrt(myinfo->NOTARY.NUMRELAYS) ) { //printf("fanout.%d s.%d n.%d skip %s\n",fanout,s,n,addr->ipaddr); continue; } - for (s=0; sipbits != myinfo->myaddr.myipbits && RELAYS[s].ipbits == addr->ipbits ) + for (s=0; sNOTARY.NUMRELAYS; s++) + if ( addr->ipbits != myinfo->myaddr.myipbits && myinfo->NOTARY.RELAYS[s].ipbits == addr->ipbits ) break; - if ( s == NUMRELAYS ) + if ( s == myinfo->NOTARY.NUMRELAYS ) { //printf("skip non-relay.(%s)\n",addr->ipaddr); continue; @@ -394,7 +394,7 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struc } if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) timeoutmillis = BASILISK_TIMEOUT; - minfanout = sqrt(NUMRELAYS)+1; + minfanout = sqrt(myinfo->NOTARY.NUMRELAYS)+1; if ( minfanout < 5 ) minfanout = 5; if ( jobj(valsobj,"fanout") == 0 ) @@ -403,7 +403,7 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struc if ( fanout < minfanout ) fanout = minfanout; if ( (numrequired= jint(valsobj,"numrequired")) <= 0 ) - numrequired = MAX(fanout,sqrt(NUMRELAYS)+1); + numrequired = MAX(fanout,sqrt(myinfo->NOTARY.NUMRELAYS)+1); if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) { if ( (virt= iguana_coinfind(symbol)) != 0 ) @@ -424,7 +424,7 @@ struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struc char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,void *_addr,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag) // client side { uint32_t nBits = 0; uint8_t space[4096],*allocptr=0,*data = 0; struct basilisk_item *ptr; int32_t datalen = 0; cJSON *retjson; char *retstr=0; - if ( RELAYID >= 0 && basilisk_specialcmd(CMD) == 0 ) + if ( myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0 && basilisk_notarycmd(CMD) == 0 ) return(clonestr("{\"error\":\"unsupported special relay command\"}")); data = get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr); //printf("request.(%s)\n",jprint(valsobj,0)); @@ -456,8 +456,8 @@ char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,void *_add int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits) { int32_t j; - for (j=0; jNOTARY.NUMRELAYS; j++) + if ( myinfo->NOTARY.RELAYS[j].ipbits == ipbits ) return(j); return(-1); } @@ -473,6 +473,7 @@ int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits) #include "basilisk_swap.c" #include "basilisk_DEX.c" #include "basilisk_ping.c" +#include "basilisk_vote.c" #include "basilisk_CMD.c" void basilisk_functions(struct iguana_info *coin,int32_t protocol) @@ -625,7 +626,10 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende { (void *)"OUT", &basilisk_respond_OUT }, // send MSG to hash/id/num { (void *)"MSG", &basilisk_respond_MSG }, // get MSG (hash, id, num) { (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus + { (void *)"VOT", &basilisk_respond_VOT }, // VOTE handler for something //{ (void *)"PIN", &basilisk_respond_PIN }, + + // encrypted data for jumblr { (void *)"HOP", &basilisk_respond_forward }, // message forwarding { (void *)"BOX", &basilisk_respond_mailbox }, // create/send/check mailbox pubkey @@ -666,12 +670,11 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende CMD[i] = toupper((int32_t)CMD[i]); cmd[i] = tolower((int32_t)CMD[i]); } - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 )//RELAYID >= 0 ) { - if ( basilisk_specialcmd(CMD) == 0 ) + if ( basilisk_notarycmd(CMD) == 0 ) return; - } - else if ( basilisk_specialcmd(CMD) != 0 ) + } else if ( basilisk_notarycmd(CMD) != 0 ) return; symbol = "BTCD"; if ( senderipbits == 0 ) @@ -729,7 +732,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende hash = jbits256(valsobj,"hash"); timeoutmillis = jint(valsobj,"timeout"); if ( (numrequired= jint(valsobj,"numrequired")) == 0 ) - numrequired = sqrt(NUMRELAYS)+1; + numrequired = sqrt(myinfo->NOTARY.NUMRELAYS)+1; if ( senderipbits != 0 ) expand_ipbits(remoteaddr,senderipbits); else remoteaddr[0] = 0; @@ -737,7 +740,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t sende { if ( strcmp((char *)basilisk_services[i][0],type) == 0 ) { - if ( coin->FULLNODE != 0 || RELAYID >= 0 ) // iguana node + if ( coin->FULLNODE != 0 || myinfo->NOTARY.RELAYID >= 0 ) // iguana node { //printf("FULL.%d RELAYID.%d NUMRELAYS.%d services %s\n",coin->FULLNODE,RELAYID,NUMRELAYS,type); if ( (retstr= (*basilisk_services[i][1])(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk)) != 0 ) @@ -777,7 +780,7 @@ void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t else ipbits = myinfo->myaddr.myipbits; if ( type[0] == 'P' && type[1] == 'I' && type[2] == 'N' ) { - if ( strcmp(type,"PIN") == 0 && RELAYID >= 0 ) + if ( strcmp(type,"PIN") == 0 && myinfo->NOTARY.RELAYID >= 0 ) { basilisk_ping_process(myinfo,_addr,ipbits,data,datalen); } @@ -787,8 +790,8 @@ void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t len += iguana_rwnum(0,data,sizeof(basilisktag),&basilisktag); //int32_t i; for (i=0; i= 0 ) - printf("RELAYID.%d ->received.%d basilisk_p2p.(%s) from %s tag.%u\n",RELAYID,datalen,type,senderip!=0?senderip:"?",basilisktag); + if ( myinfo->NOTARY.RELAYID >= 0 ) + printf("RELAYID.%d ->received.%d basilisk_p2p.(%s) from %s tag.%u\n",myinfo->NOTARY.RELAYID,datalen,type,senderip!=0?senderip:"?",basilisktag); basilisk_msgprocess(myinfo,_addr,ipbits,type,basilisktag,&data[len],datalen - len); } if ( ptr != 0 ) @@ -865,7 +868,7 @@ void basilisks_loop(void *arg) } } //portable_mutex_unlock(&myinfo->allcoins_mutex); - if ( RELAYID >= 0 ) + if ( myinfo->NOTARY.RELAYID >= 0 ) { basilisk_ping_send(myinfo,btcd); } @@ -883,7 +886,7 @@ void basilisks_loop(void *arg) } } } - if ( RELAYID < 0 && myinfo->expiration != 0 ) + if ( myinfo->NOTARY.RELAYID < 0 && myinfo->expiration != 0 ) basilisk_requests_poll(myinfo); now = (uint32_t)time(NULL); portable_mutex_lock(&myinfo->messagemutex); @@ -898,7 +901,7 @@ void basilisks_loop(void *arg) } } portable_mutex_unlock(&myinfo->messagemutex); - if ( RELAYID >= 0 ) + if ( myinfo->NOTARY.RELAYID >= 0 ) usleep(100000); else usleep(3000000); } @@ -925,7 +928,7 @@ void basilisks_init(struct supernet_info *myinfo) HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr) { char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; - if ( RELAYID >= 0 ) + if ( myinfo->NOTARY.RELAYID >= 0 ) return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); if ( vals == 0 ) return(clonestr("{\"error\":\"need vals object\"}")); @@ -934,7 +937,7 @@ HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr) if ( jobj(vals,"history") == 0 ) jaddnum(vals,"history",3); if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(NUMRELAYS)+1)); + jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); if ( jobj(vals,"numrequired") == 0 ) jaddnum(vals,"numrequired",juint(vals,"fanout")); if ( jobj(vals,"addresses") == 0 ) diff --git a/basilisk/basilisk_CMD.c b/basilisk/basilisk_CMD.c index 2ba7443cc..dc0873610 100755 --- a/basilisk/basilisk_CMD.c +++ b/basilisk/basilisk_CMD.c @@ -24,25 +24,25 @@ return(-1); }*/ -struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *btcd,uint32_t ipbits) +struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *notaries,uint32_t ipbits) { struct iguana_peer *addr; int32_t i; - if ( btcd == 0 ) + if ( notaries == 0 ) return(0); - if ( (addr= iguana_peerfindipbits(btcd,ipbits,0)) == 0 ) + if ( (addr= iguana_peerfindipbits(notaries,ipbits,0)) == 0 ) { - if ( (addr= iguana_peerslot(btcd,ipbits,0)) != 0 ) + if ( (addr= iguana_peerslot(notaries,ipbits,0)) != 0 ) { printf("launch peer for relay\n"); addr->isrelay = 1; - RELAYID = -1; - for (i=0; imyaddr.myipbits ) + myinfo->NOTARY.RELAYID = -1; + for (i=0; iNOTARY.NUMRELAYS; i++) + if ( myinfo->NOTARY.RELAYS[i].ipbits == myinfo->myaddr.myipbits ) { - RELAYID = i; + myinfo->NOTARY.RELAYID = i; break; } - iguana_launch(btcd,"addrelay",iguana_startconnection,addr,IGUANA_CONNTHREAD); + iguana_launch(notaries,"addrelay",iguana_startconnection,addr,IGUANA_CONNTHREAD); } else printf("error getting peerslot\n"); } else addr->isrelay = 1; return(addr); @@ -65,30 +65,30 @@ void basilisk_relay_remap(struct supernet_info *myinfo,struct basilisk_relay *rp { int32_t i; struct basilisk_relaystatus tmp[BASILISK_MAXRELAYS]; // need to verify this works - for (i=0; iNOTARY.NUMRELAYS; i++) tmp[i] = rp->reported[i]; - for (i=0; ireported[RELAYS[i].relayid] = tmp[RELAYS[i].oldrelayid]; + for (i=0; iNOTARY.NUMRELAYS; i++) + rp->reported[myinfo->NOTARY.RELAYS[i].relayid] = tmp[myinfo->NOTARY.RELAYS[i].oldrelayid]; } void basilisk_setmyid(struct supernet_info *myinfo) { - int32_t i; char ipaddr[64]; struct iguana_info *btcd = iguana_coinfind("BTCD"); - for (i=0; iNOTARY.NUMRELAYS; i++) { - expand_ipbits(ipaddr,RELAYS[i].ipbits); - if ( myinfo->myaddr.myipbits == RELAYS[i].ipbits ) - RELAYID = i; - basilisk_ensurerelay(myinfo,btcd,RELAYS[i].ipbits); + expand_ipbits(ipaddr,myinfo->NOTARY.RELAYS[i].ipbits); + if ( myinfo->myaddr.myipbits == myinfo->NOTARY.RELAYS[i].ipbits ) + myinfo->NOTARY.RELAYID = i; + basilisk_ensurerelay(myinfo,notaries,myinfo->NOTARY.RELAYS[i].ipbits); } } char *basilisk_addrelay_info(struct supernet_info *myinfo,uint8_t *pubkey33,uint32_t ipbits,bits256 pubkey) { int32_t i; struct basilisk_relay *rp; - for (i=0; iNOTARY.NUMRELAYS; i++) { - rp = &RELAYS[i]; + rp = &myinfo->NOTARY.RELAYS[i]; if ( ipbits == rp->ipbits ) { if ( bits256_cmp(GENESIS_PUBKEY,pubkey) != 0 && bits256_nonz(pubkey) != 0 ) @@ -99,24 +99,24 @@ char *basilisk_addrelay_info(struct supernet_info *myinfo,uint8_t *pubkey33,uint return(clonestr("{\"error\":\"relay already there\"}")); } } - if ( i >= sizeof(RELAYS)/sizeof(*RELAYS) ) - i = (rand() % (sizeof(RELAYS)/sizeof(*RELAYS))); + if ( i >= sizeof(myinfo->NOTARY.RELAYS)/sizeof(*myinfo->NOTARY.RELAYS) ) + i = (rand() % (sizeof(myinfo->NOTARY.RELAYS)/sizeof(*myinfo->NOTARY.RELAYS))); printf("add relay[%d] <- %x\n",i,ipbits); - for (i=0; iNOTARY.NUMRELAYS; i++) + myinfo->NOTARY.RELAYS[i].oldrelayid = i; + rp = &myinfo->NOTARY.RELAYS[i]; rp->ipbits = ipbits; - rp->relayid = NUMRELAYS; - basilisk_ensurerelay(myinfo,iguana_coinfind("BTCD"),rp->ipbits); - if ( NUMRELAYS < sizeof(RELAYS)/sizeof(*RELAYS) ) - NUMRELAYS++; - qsort(RELAYS,NUMRELAYS,sizeof(RELAYS[0]),_increasing_ipbits); - for (i=0; irelayid = myinfo->NOTARY.NUMRELAYS; + basilisk_ensurerelay(myinfo,iguana_coinfind("NOTARY"),rp->ipbits); + if ( myinfo->NOTARY.NUMRELAYS < sizeof(myinfo->NOTARY.RELAYS)/sizeof(*myinfo->NOTARY.RELAYS) ) + myinfo->NOTARY.NUMRELAYS++; + qsort(myinfo->NOTARY.RELAYS,myinfo->NOTARY.NUMRELAYS,sizeof(myinfo->NOTARY.RELAYS[0]),_increasing_ipbits); + for (i=0; iNOTARY.NUMRELAYS; i++) + myinfo->NOTARY.RELAYS[i].relayid = i; basilisk_setmyid(myinfo); - printf("sorted MYRELAYID.%d\n",RELAYID); - for (i=0; iNOTARY.RELAYID); + for (i=0; iNOTARY.NUMRELAYS; i++) + basilisk_relay_remap(myinfo,&myinfo->NOTARY.RELAYS[i]); return(clonestr("{\"result\":\"relay added\"}")); } @@ -254,6 +254,11 @@ char *basilisk_respond_getinfo(struct supernet_info *myinfo,char *CMD,void *addr #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" +HASH_ARRAY_STRING(basilisk,vote,hash,vals,hexstr) +{ + return(basilisk_standardservice("VOT",myinfo,0,hash,vals,hexstr,0)); +} + HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr) { return(basilisk_standardservice("ADD",myinfo,0,hash,vals,hexstr,1)); diff --git a/basilisk/basilisk_DEX.c b/basilisk/basilisk_DEX.c index 5245c546d..e4c99be16 100755 --- a/basilisk/basilisk_DEX.c +++ b/basilisk/basilisk_DEX.c @@ -247,7 +247,7 @@ struct basilisk_relay *basilisk_request_ensure(struct supernet_info *myinfo,uint int32_t j; struct basilisk_relay *relay = 0; if ( (j= basilisk_relayid(myinfo,senderipbits)) >= 0 ) { - relay = &RELAYS[j]; + relay = &myinfo->NOTARY.RELAYS[j]; if ( numrequests > relay->maxrequests ) { relay->maxrequests = numrequests; @@ -284,14 +284,14 @@ static int _cmp_requests(const void *a,const void *b) struct basilisk_request *_basilisk_requests_uniq(struct supernet_info *myinfo,int32_t *nump,uint8_t *space,int32_t spacesize) { int32_t i,j,n,k,m; struct basilisk_relay *relay; struct basilisk_request *requests,*rp; - for (j=m=0; jNOTARY.NUMRELAYS; j++) + m += myinfo->NOTARY.RELAYS[j].numrequests; if ( m*sizeof(*requests) <= spacesize ) requests = (void *)space; else requests = calloc(m,sizeof(*requests)); - for (j=m=0; jNOTARY.NUMRELAYS; j++) { - relay = &RELAYS[j]; + relay = &myinfo->NOTARY.RELAYS[j]; if ( (n= relay->numrequests) > 0 ) { for (i=0; i= 0 ) + if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) R.relaybits = myinfo->myaddr.myipbits; if ( (reqjson= basilisk_requestjson(&R)) != 0 ) free_json(reqjson); diff --git a/basilisk/basilisk_MSG.c b/basilisk/basilisk_MSG.c index 4463761ec..7c578cd52 100755 --- a/basilisk/basilisk_MSG.c +++ b/basilisk/basilisk_MSG.c @@ -167,7 +167,7 @@ HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr) jdelete(vals,"msgid"); jaddnum(vals,"msgid",msgid); } - if ( RELAYID >= 0 ) + if ( myinfo->NOTARY.RELAYID >= 0 ) { channel = juint(vals,"channel"); width = juint(vals,"width"); @@ -178,7 +178,7 @@ HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr) HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) { int32_t keylen,datalen; uint8_t key[BASILISK_KEYSIZE],space[16384],*data,*ptr = 0; char *retstr=0; - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0 ) { keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"sender"),hash); if ( (data= get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,space,sizeof(space),hexstr)) != 0 ) @@ -189,7 +189,7 @@ HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) free(retstr); } if ( vals != 0 && juint(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(NUMRELAYS)+2)); + jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+2)); return(basilisk_standardservice("OUT",myinfo,0,hash,vals,hexstr,0)); } #include "../includes/iguana_apiundefs.h" @@ -203,7 +203,7 @@ int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 hash,uint32_t jaddnum(valsobj,"channel",channel); if ( msgid == 0 ) msgid = (uint32_t)time(NULL); - jaddnum(valsobj,"fanout",MAX(5,(int32_t)sqrt(NUMRELAYS)+2)); + jaddnum(valsobj,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+2)); jaddnum(valsobj,"msgid",msgid); jaddnum(valsobj,"duration",duration); jaddbits256(valsobj,"sender",myinfo->myaddr.persistent); @@ -252,7 +252,7 @@ cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 hash,uint32_t ch jaddnum(valsobj,"msgid",msgid); jaddnum(valsobj,"width",width); jaddnum(valsobj,"timeout",2500); - jaddnum(valsobj,"fanout",MAX(5,(int32_t)sqrt(NUMRELAYS)+1)); + jaddnum(valsobj,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); jaddnum(valsobj,"numrequired",1); if ( (retstr= basilisk_getmessage(myinfo,0,0,0,hash,valsobj,0)) != 0 ) { diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c index 1af51548b..903c9b9e3 100755 --- a/basilisk/basilisk_bitcoin.c +++ b/basilisk/basilisk_bitcoin.c @@ -383,7 +383,7 @@ double basilisk_bitcoin_valuemetric(struct supernet_info *myinfo,struct basilisk void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) { int32_t i,height,vout,numsent; struct basilisk_item *ptr; char coinaddr[64],str[65]; struct basilisk_value *v; uint64_t value = 0; bits256 txid; struct iguana_outpoint outpt; - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0 ) return(0); txid = jbits256(valsobj,"txid"); vout = jint(valsobj,"vout"); @@ -424,7 +424,7 @@ void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myi void *basilisk_getinfo(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) { struct basilisk_item *ptr; cJSON *infojson; int32_t numsent,fanout,numrequired; - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) return(0); if ( coin->VALIDATENODE != 0 || coin->FULLNODE != 0 ) { @@ -516,7 +516,7 @@ int32_t basilisk_vins_validate(struct supernet_info *myinfo,struct iguana_info * char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) { uint8_t buf[4096]; int32_t oplen,offset,minconf,spendlen; cJSON *vins,*addresses,*txobj = 0; uint32_t locktime; char *opreturn,*spendscriptstr,*changeaddr,*rawtx = 0; int64_t amount,txfee,burnamount; - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); vins = 0; changeaddr = jstr(valsobj,"changeaddr"); @@ -815,7 +815,7 @@ cJSON *BTC_makeclaimfunc(struct supernet_info *myinfo,struct exchange_info *exch HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) { char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 || myinfo->NOTARY.RELAYID >= 0 ) return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); //if ( coin == 0 ) { @@ -823,7 +823,7 @@ HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) coin = iguana_coinfind(symbol); } if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(NUMRELAYS)+1)); + jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); if ( coin != 0 ) { if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) @@ -849,9 +849,9 @@ HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) coin = iguana_coinfind(symbol); } if ( jobj(vals,"numrequired") == 0 ) - jaddnum(vals,"numrequired",NUMRELAYS); + jaddnum(vals,"numrequired",myinfo->NOTARY.NUMRELAYS); if ( jobj(vals,"fanout") == 0 ) - jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(NUMRELAYS)+1)); + jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); if ( coin != 0 ) { //if ( juint(vals,"burn") == 0 ) diff --git a/basilisk/basilisk_ping.c b/basilisk/basilisk_ping.c index 9ec8f0e2d..4df9b4fc3 100755 --- a/basilisk/basilisk_ping.c +++ b/basilisk/basilisk_ping.c @@ -212,9 +212,9 @@ void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr int32_t diff,i,n,len = 0; struct iguana_info *btcd; char ipbuf[64]; struct basilisk_relay *rp; uint8_t numrelays; uint16_t sn; uint32_t now = (uint32_t)time(NULL); expand_ipbits(ipbuf,senderipbits); btcd = iguana_coinfind("BTCD"); - for (i=0; iNOTARY.NUMRELAYS; i++) { - rp = &RELAYS[i]; + rp = &myinfo->NOTARY.RELAYS[i]; rp->direct.pingdelay = 0; if ( rp->ipbits == senderipbits ) rp->lastping = now; @@ -231,7 +231,7 @@ void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr //len += basilisk_ping_processvirts(myinfo,btcd,addr,&data[len],datalen - len); for (i=0; iNOTARY.RELAYS[i]; if ( len > datalen ) break; if ( (n= basilisk_ping_processrelay(myinfo,&data[len],datalen-len,rp,i)) < 0 ) @@ -253,10 +253,10 @@ void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr int32_t basilisk_ping_gen(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) { int32_t i,datalen = 0; - data[datalen++] = NUMRELAYS; + data[datalen++] = myinfo->NOTARY.NUMRELAYS; //datalen += basilisk_ping_genvirts(myinfo,&data[datalen],maxlen - datalen); - for (i=0; iNOTARY.NUMRELAYS; i++) + datalen += basilisk_ping_genrelay(myinfo,&data[datalen],maxlen - datalen,&myinfo->NOTARY.RELAYS[i]); //datalen += basilisk_ping_genDEX(myinfo,&data[datalen],maxlen - datalen); datalen += basilisk_ping_genMSG(myinfo,&data[datalen],maxlen - datalen); //for (i=0; iNOTARY.NUMRELAYS <= 0 ) return; if ( myinfo->pingbuf == 0 ) myinfo->pingbuf = malloc(IGUANA_MAXPACKETSIZE); datalen = basilisk_ping_gen(myinfo,&myinfo->pingbuf[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE-sizeof(struct iguana_msghdr)); - incr = sqrt(NUMRELAYS) + 1; + incr = sqrt(myinfo->NOTARY.NUMRELAYS) + 1; for (alreadysent=j=0; j<=incr; j++) { OS_randombytes((void *)&r,sizeof(r)); - i = (j == 0) ? RELAYID : (r % NUMRELAYS); - if ( j != 0 && i == RELAYID ) - i = (RELAYID + 1) % NUMRELAYS; + i = (j == 0) ? myinfo->NOTARY.RELAYID : (r % myinfo->NOTARY.NUMRELAYS); + if ( j != 0 && i == myinfo->NOTARY.RELAYID ) + i = (myinfo->NOTARY.RELAYID + 1) % myinfo->NOTARY.NUMRELAYS; if ( (((uint64_t)1 << i) & alreadysent) != 0 ) { j--; continue; } alreadysent |= ((uint64_t)1 << i); - rp = &RELAYS[i]; + rp = &myinfo->NOTARY.RELAYS[i]; addr = 0; expand_ipbits(ipaddr,rp->ipbits); if ( rp->ipbits == myinfo->myaddr.myipbits ) diff --git a/basilisk/basilisk_vote.c b/basilisk/basilisk_vote.c new file mode 100755 index 000000000..9646ed906 --- /dev/null +++ b/basilisk/basilisk_vote.c @@ -0,0 +1,405 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#define MAX_ELECTIONS 64 + +struct vote_info +{ + bits256 commit,vote; + uint64_t stake,repstake; + int32_t repid; + uint8_t sig[74],siglen; + uint8_t pubkey[33],rmd160[20]; +}; + +struct election_info +{ + bits256 hash; + char name[64]; + uint32_t expiration,duration,numcandidates,numvotes; + cJSON *ballot; + struct vote_info *votes; +} Elections[MAX_ELECTIONS]; + +int64_t basilisk_voter_stake(struct supernet_info *myinfo,uint8_t *rmd160,struct iguana_info *coin,uint8_t *pubkey) +{ + char coinaddr[64]; int64_t stake = 1; + calc_rmd160_sha256(rmd160,pubkey,33); + bitcoin_address(coinaddr,coin->chain->pubtype,pubkey,33); + // get stake of address + return(stake); +} + +int32_t basilisk_voter_process(struct supernet_info *myinfo,uint8_t *rmd160,struct iguana_info *coin,struct election_info *ep,struct vote_info *vp) +{ + int32_t i; + if ( vp->stake == 0 ) + vp->stake = 1; + if ( bits256_nonz(vp->vote) != 0 ) + { + for (i=1; i<8; i++) + if ( vp->vote.uints[i] != 0 ) + break; + if ( i == 8 ) + return(vp->vote.uints[0]); + else + { + for (i=0; i<20; i++) + rmd160[i] = vp->vote.bytes[i + 4]; + return(ep->numcandidates); + } + } + return(-1); +} + +int32_t basilisk_election_process(struct supernet_info *myinfo,int64_t *tally,struct iguana_info *coin,struct election_info *ep) +{ + int32_t i,j,pending = 0; struct vote_info *vp; uint8_t rmd160[20]; + for (i=0; inumvotes; i++) + ep->votes[i].repstake = 0; + for (i=0; inumvotes; i++) + { + vp = &ep->votes[i]; + if ( basilisk_voter_process(myinfo,rmd160,coin,ep,vp) == ep->numcandidates && vp->repid < 0 ) + { + for (j=0; jnumvotes; j++) + { + if ( i != j && memcmp(rmd160,ep->votes[j].rmd160,20) == 0 ) + { + vp->repid = j; + ep->votes[j].repstake += vp->stake; + break; + } + } + } + } + if ( tally != 0 ) + { + memset(tally,0,ep->numcandidates*sizeof(*tally)); + for (i=0; inumvotes; i++) + { + vp = &ep->votes[i]; + if ( vp->repid < 0 && vp->vote.uints[0] > 0 && vp->vote.uints[0] <= ep->numcandidates ) + tally[vp->vote.uints[0]] += (vp->stake + vp->repstake); + else if ( vp->repid < 0 ) + pending++; + } + } + return(pending); +} + +cJSON *basilisk_voterjson(struct supernet_info *myinfo,struct iguana_info *coin,struct election_info *ep,struct vote_info *vp) +{ + char coinaddr[64],sigstr[74*2+1]; int32_t i; uint8_t rmd160[20]; cJSON *item; + item = cJSON_CreateObject(); + basilisk_voter_process(myinfo,rmd160,coin,ep,vp); + bitcoin_address(coinaddr,5,vp->pubkey,sizeof(vp->pubkey)); + jaddstr(item,"coinaddr",coinaddr); + jaddnum(item,"stake",dstr(vp->stake)); + if ( vp->repstake != 0 ) + jaddnum(item,"repstake",dstr(vp->repstake)); + if ( bits256_nonz(vp->vote) != 0 ) + { + for (i=1; i<8; i++) + if ( vp->vote.uints[i] != 0 ) + break; + if ( i == 8 ) + { + if ( vp->vote.uints[0] <= ep->numcandidates ) + jaddnum(item,"vote",vp->vote.uints[0]); + else jaddstr(item,"error","illegal vote"); + } + else + { + for (i=0; i<20; i++) + rmd160[i] = vp->vote.bytes[i + 4]; + bitcoin_address(coinaddr,5,rmd160,20); + jaddstr(item,"delegated",coinaddr); + } + } + else if ( bits256_nonz(vp->commit) != 0 ) + jaddbits256(item,"commit",vp->commit); + init_hexbytes_noT(sigstr,vp->sig,vp->siglen); + jaddstr(item,"sig",sigstr); + return(item); +} + +cJSON *basilisk_electionjson(struct supernet_info *myinfo,struct iguana_info *coin,struct election_info *ep) +{ + int32_t i; cJSON *array,*obj = cJSON_CreateObject(); + jaddstr(obj,"name",ep->name); + jaddbits256(obj,"hash",ep->hash); + jaddnum(obj,"expiration",ep->expiration); + jaddnum(obj,"numcandidates",ep->numcandidates); + jaddnum(obj,"numvotes",ep->numvotes); + jadd(obj,"ballot",jduplicate(ep->ballot)); + array = cJSON_CreateArray(); + for (i=0; inumvotes; i++) + jaddi(array,basilisk_voterjson(myinfo,coin,ep,&ep->votes[i])); + jadd(obj,"votes",array); + return(obj); +} + +int32_t basilisk_electionsave(struct election_info *ep) +{ + char fname[512],str[65],*ballotstr; int32_t n; FILE *fp; + OS_ensure_directory("elections"); + sprintf(fname,"elections/%s",bits256_str(str,ep->hash)); + OS_compatible_path(fname); + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(ep,1,sizeof(*ep),fp) != sizeof(*ep) ) + printf("error saving election.(%s) to %s\n",ep->name,fname); + else + { + if ( fwrite(&ep->numvotes,1,sizeof(ep->numvotes),fp) != sizeof(ep->numvotes) ) + printf("error saving numvotes.%d to %s\n",ep->numvotes,fname); + else if ( ep->numvotes > 0 ) + { + if ( fwrite(ep->votes,sizeof(*ep->votes),ep->numvotes,fp) != ep->numvotes ) + printf("error saving votes.%d for %s to %s\n",ep->numvotes,ep->name,fname); + else + { + if ( (ballotstr= jprint(ep->ballot,0)) != 0 ) + { + n = (int32_t)strlen(ballotstr) + 1; + if ( fwrite(&n,1,sizeof(n),fp) != sizeof(n) ) + printf("error saving n.%d for (%s) to %s\n",n,ballotstr,fname); + else if ( fwrite(ballotstr,1,n,fp) != n ) + printf("error saving election.(%s) to %s\n",ballotstr,fname); + free(ballotstr); + } + } + } + } + fclose(fp); + return(0); + } + return(-1); +} + +struct vote_info *basilisk_vote_find(struct election_info *ep,struct vote_info *vote) +{ + int32_t i; + for (i=0; inumvotes; i++) + { + if ( memcmp(ep->votes[i].pubkey,vote->pubkey,33) == 0 ) + return(&ep->votes[i]); + } + return(0); +} + +struct election_info *basilisk_election_find(int32_t createflag,bits256 hash) +{ + int32_t i; uint32_t now = (uint32_t)time(NULL); + for (i=0; i Elections[i].expiration ) + { + basilisk_electionsave(&Elections[i]); + memset(&Elections[i],0,sizeof(Elections[i])); + } + if ( bits256_nonz(hash) != 0 ) + { + if ( bits256_nonz(Elections[i].hash) == 0 ) + return(&Elections[i]); + else if ( bits256_cmp(Elections[i].hash,hash) == 0 ) + return(0); + } + } + return(0); +} + +int32_t basilisk_vote_extract(struct supernet_info *myinfo,char *coinaddr,struct vote_info *vote,cJSON *item) +{ + char str[65],str2[65],str3[65]; uint8_t *sig,*pubkey; int32_t action,siglen,plen; bits256 data,hash; + memset(vote,0,sizeof(*vote)); + if ( get_dataptr(0,&sig,&siglen,vote->sig,sizeof(vote->sig),jstr(item,"sig")) != 0 ) + { + vote->siglen = siglen; + action = juint(item,"action"); + if ( get_dataptr(0,&pubkey,&plen,vote->pubkey,sizeof(vote->pubkey),jstr(item,"pubkey")) != 0 ) + { + bitcoin_address(coinaddr,5,pubkey,33); + data = jbits256(item,"data"); + if ( bitcoin_verify(myinfo->ctx,vote->sig,vote->siglen,data,vote->pubkey,33) == 0 ) + { + if ( (action & 0xff) == 'c' ) + { + vote->commit = data; + printf("%s commits to %s\n",coinaddr,bits256_str(str,data)); + return(action); + } + else if ( (action & 0xff) == 'r' ) + { + if ( bits256_nonz(vote->commit) != 0 ) + { + vcalc_sha256(0,hash.bytes,data.bytes,sizeof(data)); + if ( bits256_cmp(hash,vote->commit) == 0 ) + { + printf("%s vote %s -> %s matches commit %s\n",coinaddr,bits256_str(str,data),bits256_str(str2,hash),bits256_str(str3,vote->commit)); + vote->vote = data; + // error check vote + return(action); + } + else + { + printf("%s vote %s -> %s doesnt match commit %s\n",coinaddr,bits256_str(str,data),bits256_str(str2,hash),bits256_str(str3,vote->commit)); + return(-2); + } + } + } + } else return(-1); + } + } + return(-1); +} + +char *basilisk_respond_VOT(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + int32_t i,duration,winner,pending,action,numcandidates; char coinaddr[64],*symbol,*votemethod,*ballotstr; cJSON *item,*array,*electionobj,*ballot,*retjson; struct election_info *ep; struct vote_info vote,*vp; struct iguana_info *coin; int64_t *tally,max; + retjson = cJSON_CreateObject(); + if ( (symbol= jstr(valsobj,"coin")) == 0 ) + symbol = "BTCD"; + coin = iguana_coinfind(symbol); + if ( (votemethod= jstr(valsobj,"votemethod")) != 0 ) + { + if ( strcmp(votemethod,"create") == 0 ) + { + if ( (ballot= jarray(&numcandidates,valsobj,"ballot")) != 0 && numcandidates > 0 ) + { + if ( (duration= juint(valsobj,"duration")) == 0 ) + duration = 3600; + ballotstr = jprint(ballot,0); + vcalc_sha256(0,hash.bytes,(uint8_t *)ballotstr,(int32_t)strlen(ballotstr)); + free(ballotstr); + if ( (ep= basilisk_election_find(1,hash)) != 0 ) + { + ep->hash = hash; + ep->duration = duration; + ep->expiration = (uint32_t)time(NULL) + duration; + ep->ballot = jduplicate(ballot); + ep->numcandidates = numcandidates; + safecopy(ep->name,jstr(valsobj,"name"),sizeof(ep->name)); + if ( (electionobj= basilisk_electionjson(myinfo,coin,ep)) != 0 ) + { + jaddstr(retjson,"result","success"); + jadd(retjson,"election",electionobj); + } else jaddstr(retjson,"error","couldnt create election object"); + } else jaddstr(retjson,"error","couldnt allocate election slot"); + } + } + else if ( strcmp(votemethod,"list") == 0 ) + { + array = cJSON_CreateArray(); + for (i=0; inumcandidates+1,sizeof(*tally)); + pending = basilisk_election_process(myinfo,tally,coin,ep); + if ( pending != 0 ) + jaddnum(retjson,"pending",pending); + jadd(retjson,"election",basilisk_electionjson(myinfo,coin,ep)); + array = cJSON_CreateArray(); + max = 0; + winner = -1; + for (i=1; i<=ep->numcandidates; i++) + { + if ( tally[i] > max ) + { + max = tally[i]; + winner = i; + } + jaddinum(array,dstr(tally[i])); + } + jadd(retjson,"tally",array); + if ( winner > 0 ) + { + item = jitem(ep->ballot,winner-1); + jadd(retjson,"winner",item); + } + free(tally); + } + else if ( strcmp(votemethod,"ratify") == 0 ) + { + // record ratification of tally + } + else if ( (action= basilisk_vote_extract(myinfo,coinaddr,&vote,valsobj)) > 0 ) + { + vp = basilisk_vote_find(ep,&vote); + if ( strcmp(votemethod,"vote") == 0 ) + { + if ( vp == 0 ) + { + ep->votes = realloc(ep->votes,sizeof(*ep->votes) + (ep->numvotes + 1)); + vote.repid = -1; + vote.stake = basilisk_voter_stake(myinfo,vote.rmd160,coin,vote.pubkey); + ep->votes[ep->numvotes++] = vote; + jaddstr(retjson,"result","success"); + } + else if ( action == 'c' ) + { + *vp = vote; + jaddstr(retjson,"result","success"); + } + else if ( action == 'r' ) + { + *vp = vote; + jaddstr(retjson,"result","success"); + } else jaddstr(retjson,"error","illegal vote action"); + } + else if ( strcmp(votemethod,"verify") == 0 ) + { + if ( vp == 0 ) + jaddstr(retjson,"error","cant find voter"); + else if ( action == 'c' ) + { + if ( bits256_cmp(vote.commit,vp->commit) == 0 ) + jaddstr(retjson,"result","success"); + else jaddstr(retjson,"error","mismatched commit"); + jaddbits256(retjson,"oldcommit",vp->commit); + jaddbits256(retjson,"newcommit",vote.commit); + } + else if ( action == 'r' ) + { + if ( bits256_cmp(vote.vote,vp->vote) == 0 ) + jaddstr(retjson,"result","success"); + else jaddstr(retjson,"error","mismatched vote"); + jaddbits256(retjson,"oldvote",vp->vote); + jaddbits256(retjson,"newvote",vote.vote); + } else jaddstr(retjson,"error","illegal vote action"); + } else jaddstr(retjson,"error","illegal vote method"); + } else jaddstr(retjson,"error","couldnt extract vote info"); + } + } + return(jprint(retjson,1)); +} + + diff --git a/datachain/datachain.c b/datachain/datachain.c index 95792c520..8500d6f47 100755 --- a/datachain/datachain.c +++ b/datachain/datachain.c @@ -20,7 +20,7 @@ uint32_t datachain_checkpoint(struct supernet_info *myinfo,struct iguana_info *c { char str[65],str2[65]; struct iguana_info *btc = iguana_coinfind("BTC"); printf("datachain_checkpoint.%s for %s.%u to %u lastheight.%d %s\n",bits256_str(str,merkle),coin->symbol,lastcheckpoint,timestamp,lastheight,bits256_str(str2,lasthash2)); - if ( (lastheight % NUMRELAYS) == RELAYID ) + if ( (lastheight % myinfo->NOTARY.NUMRELAYS) == myinfo->NOTARY.RELAYID ) { // if designated relay, submit checkpoint -> add ip/relayid to opreturn // diff --git a/gecko/gecko_blocks.c b/gecko/gecko_blocks.c index 7f089ae34..db66cfb03 100755 --- a/gecko/gecko_blocks.c +++ b/gecko/gecko_blocks.c @@ -341,7 +341,7 @@ int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *bt if ( jobj(retjson,"error") == 0 ) { valsobj = cJSON_CreateObject(); - jaddnum(valsobj,"numrequired",NUMRELAYS - 1); + jaddnum(valsobj,"numrequired",myinfo->NOTARY.NUMRELAYS - 1); jaddnum(valsobj,"timeout",3000); jaddnum(valsobj,"fanout",-1); jaddnum(valsobj,"height",height); diff --git a/gecko/gecko_mempool.c b/gecko/gecko_mempool.c index 7bd5fbcf8..7a546c19e 100755 --- a/gecko/gecko_mempool.c +++ b/gecko/gecko_mempool.c @@ -21,7 +21,7 @@ struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct igua int32_t j,firstz,numother; bits256 *othertxids; struct gecko_mempool *otherpool = 0; othertxids = 0; numother = firstz = 0; - for (j=0; jNOTARY.NUMRELAYS; j++) { if ( (otherpool= virt->mempools[j]) != 0 ) { @@ -44,22 +44,22 @@ struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct igua void gecko_mempool_sync(struct supernet_info *myinfo,struct iguana_info *virt,bits256 *reftxids,int32_t numtx) { int32_t i,j,k,n,num,numother; struct iguana_peer *addr; bits256 txid,*txids; struct gecko_mempool *pool,*otherpool; struct iguana_info *coin; - if ( (pool= virt->mempool) == 0 || NUMRELAYS <= 0 ) + if ( (pool= virt->mempool) == 0 || myinfo->NOTARY.NUMRELAYS <= 0 ) return; - n = sqrt(NUMRELAYS) + 2; - if ( n > NUMRELAYS ) - NUMRELAYS = n; + n = sqrt(myinfo->NOTARY.NUMRELAYS) + 2; + if ( n > myinfo->NOTARY.NUMRELAYS ) + myinfo->NOTARY.NUMRELAYS = n; i = (myinfo->myaddr.myipbits % n); txids = calloc(pool->numtx,sizeof(bits256)); if ( virt->peers == 0 ) coin = iguana_coinfind("BTCD"); else coin = virt; - for (; iNOTARY.NUMRELAYS; i+=n) { printf("mempool_sync.%d\n",i); - if ( (addr= iguana_peerfindipbits(coin,RELAYS[i].ipbits,1)) != 0 ) + if ( (addr= iguana_peerfindipbits(coin,myinfo->NOTARY.RELAYS[i].ipbits,1)) != 0 ) { - if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,RELAYS[i].ipbits)) != 0 ) + if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,myinfo->NOTARY.RELAYS[i].ipbits)) != 0 ) { for (j=num=0; jnumtx; j++) { diff --git a/iguana/coins/gennotary b/iguana/coins/gennotary new file mode 100755 index 000000000..ba3b8a569 --- /dev/null +++ b/iguana/coins/gennotary @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"NOTARY\",\"services\":128,\"maxpeers\":2048,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":7776,\"rpc\":0}" diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 36ab9a16e..5117338f7 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -782,7 +782,7 @@ void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin) } sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname); sprintf(dirname,"%s/%s/RT",GLOBAL_TMPDIR,coin->symbol), OS_ensure_directory(dirname); - iguana_coinstart(coin,coin->initialheight,coin->mapflags); + iguana_coinstart(myinfo,coin,coin->initialheight,coin->mapflags); coin->chain->minconfirms = coin->minconfirms; coin->started = coin; coin->startutc = (uint32_t)time(NULL); @@ -843,7 +843,7 @@ void iguana_coinloop(void *arg) if ( coin->MAXPEERS > IGUANA_MINPEERS ) coin->MAXPEERS = IGUANA_MINPEERS; } - if ( RELAYID < 0 ) + if ( myinfo->NOTARY.RELAYID < 0 ) { if ( coin->bindsock >= 0 ) { diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 5c2a324c4..24056b18b 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -63,6 +63,12 @@ struct supernet_address struct liquidity_info { char base[64],rel[64]; double profit,refprice; }; struct message_info { int32_t msgcount; bits256 refhash,msghashes[64]; uint32_t timestamps[64]; }; +struct komodo_notaries +{ + struct basilisk_relay RELAYS[BASILISK_MAXRELAYS]; + int32_t NUMRELAYS,RELAYID; +}; + struct supernet_info { struct supernet_address myaddr; @@ -70,7 +76,7 @@ struct supernet_info uint8_t persistent_pubkey33[33]; char ipaddr[64],NXTAPIURL[512],secret[4096],password[4096],rpcsymbol[64],handle[1024],permanentfile[1024]; char *decryptstr; - int32_t maxdelay,IAMRELAY,IAMLP,publicRPC,basilisk_busy,genesisresults; + int32_t maxdelay,IAMRELAY,IAMNOTARY,IAMLP,publicRPC,basilisk_busy,genesisresults; uint32_t expiration,dirty,DEXactive,DEXpoll; uint16_t argport,rpcport; struct basilisk_info basilisks; @@ -87,6 +93,7 @@ struct supernet_info struct basilisk_spend *spends; int32_t numspends; struct peggy_info *PEGS; struct liquidity_info linfos[64]; + struct komodo_notaries NOTARY; // compatibility bits256 pangea_category,instantdex_category; uint8_t logs[256],exps[510]; diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index eb073d680..880e7600e 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -321,7 +321,7 @@ void iguana_chainparms(struct supernet_info *myinfo,struct iguana_chain *chain,c if ( juint(argjson,"p2p") != 0 ) chain->portp2p = juint(argjson,"p2p"); else chain->portp2p = juint(argjson,"portp2p"); - if ( (chain->rpcport= juint(argjson,"rpc")) == 0 ) + if ( (chain->rpcport= juint(argjson,"rpc")) == 0 && strcmp(chain->symbol,"NOTARY") != 0 ) { if ( chain->portp2p != 0 ) chain->rpcport = chain->portp2p-1; @@ -504,7 +504,7 @@ void iguana_chaininit(struct supernet_info *myinfo,struct iguana_chain *chain,in if ( strcmp(chain->symbol,"BTC") == 0 ) chain->bundlesize = 100; decode_hex((uint8_t *)chain->genesis_hashdata,32,(char *)chain->genesis_hash); - if ( chain->rpcport == 0 ) + if ( chain->rpcport == 0 && strcmp(chain->symbol,"NOTARY") != 0 ) chain->rpcport = chain->portp2p + 1; } @@ -531,6 +531,8 @@ struct iguana_chain *iguana_chainfind(struct supernet_info *myinfo,char *name,cJ } } chain = calloc(1,sizeof(*chain)); + strcpy(chain->name,name); + strcpy(chain->symbol,name); iguana_chaininit(myinfo,chain,1,argjson); return(chain); } diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index b0b341207..e01c6a38c 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -506,9 +506,9 @@ void iguana_coinpurge(struct iguana_info *coin) coin->active = saved; } -struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags) +struct iguana_info *iguana_coinstart(struct supernet_info *myinfo,struct iguana_info *coin,int32_t initialheight,int32_t mapflags) { - FILE *fp; char fname[512],*symbol; int32_t iter; long fpos; bits256 lastbundle; struct supernet_info *myinfo = SuperNET_MYINFO(0); + FILE *fp; char fname[512],*symbol; int32_t iter; long fpos; bits256 lastbundle; /*if ( coin->peers == 0 ) { printf("cant start privatechain directly\n"); @@ -531,7 +531,7 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei printf("%s MYSERVICES.%llx\n",coin->symbol,(long long)coin->myservices); if ( coin->virtualchain == 0 && coin->peers != 0 ) { - if ( (coin->myservices & NODE_NETWORK) != 0 || (coin->FULLNODE != 0 || coin->VALIDATENODE != 0) ) + if ( myinfo->IAMNOTARY != 0 || (coin->myservices & NODE_NETWORK) != 0 || (coin->FULLNODE != 0 || coin->VALIDATENODE != 0) ) { if ( coin->peers->acceptloop == 0 && coin->peers->localaddr == 0 ) { @@ -544,7 +544,7 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei } } } - if ( coin->rpcloop == 0 ) + if ( coin->rpcloop == 0 && strcmp(coin->chain->symbol,"NOTARY") != 0 ) { myinfo->argport = coin->chain->rpcport; coin->rpcloop = malloc(sizeof(pthread_t)); diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 4bd2a1fd9..d74f1aded 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -965,8 +965,8 @@ cJSON *iguana_RTlistunspent(struct supernet_info *myinfo,struct iguana_info *coi jaddstr(vals,"coin",coin->symbol); jaddnum(vals,"history",1); jaddnum(vals,"firstheight",0); - jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(NUMRELAYS)+1)); - jaddnum(vals,"numrequired",MAX(5,(int32_t)sqrt(NUMRELAYS)+1)); + jaddnum(vals,"fanout",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); + jaddnum(vals,"numrequired",MAX(5,(int32_t)sqrt(myinfo->NOTARY.NUMRELAYS)+1)); jadd(vals,"addresses",jduplicate(argarray)); if ( (retstr= basilisk_standardservice("BAL",myinfo,0,hash,vals,"",1)) != 0 ) { diff --git a/iguana/main.c b/iguana/main.c index c92acbce8..5384d5402 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -80,7 +80,7 @@ struct supernet_info *SuperNET_MYINFO(char *passphrase) OS_randombytes(MYINFO.privkey.bytes,sizeof(MYINFO.privkey)); MYINFO.myaddr.pubkey = curve25519(MYINFO.privkey,curve25519_basepoint9()); printf("SuperNET_MYINFO: generate session keypair\n"); - RELAYID = -1; + MYINFO.NOTARY.RELAYID = -1; } if ( passphrase == 0 || passphrase[0] == 0 ) return(&MYINFO); @@ -1340,7 +1340,7 @@ STRING_ARG(SuperNET,priv2wif,priv) STRING_ARG(SuperNET,myipaddr,ipaddr) { cJSON *retjson = cJSON_CreateObject(); - RELAYID = -1; + myinfo->NOTARY.RELAYID = -1; if ( myinfo->ipaddr[0] == 0 ) { if ( is_ipaddr(ipaddr) != 0 ) @@ -1351,10 +1351,10 @@ STRING_ARG(SuperNET,myipaddr,ipaddr) } } jaddstr(retjson,"result",myinfo->ipaddr); - if ( RELAYID >= 0 ) + if ( myinfo->IAMNOTARY != 0 && myinfo->NOTARY.RELAYID >= 0 ) { - jaddnum(retjson,"relayid",RELAYID); - jaddnum(retjson,"numrelays",NUMRELAYS); + jaddnum(retjson,"relayid",myinfo->NOTARY.RELAYID); + jaddnum(retjson,"numrelays",myinfo->NOTARY.NUMRELAYS); } return(jprint(retjson,1)); } @@ -1546,7 +1546,7 @@ FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) void iguana_relays_init(struct supernet_info *myinfo) { - static char *ipaddrs[] = { "89.248.160.237", "89.248.160.238", "89.248.160.239", "89.248.160.240", "89.248.160.241", "89.248.160.242", "89.248.160.243", "89.248.160.244" }; + static char *ipaddrs[] = { "78.47.196.146", "5.9.102.210" };//"89.248.160.237", "89.248.160.238", "89.248.160.239", "89.248.160.240", "89.248.160.241", "89.248.160.242", "89.248.160.243", "89.248.160.244" }; char *str; int32_t i; for (i=0; ilogs,myinfo->exps); - if ( arg != 0 && strcmp((char *)arg,"OStests") == 0 ) - do_OStests = 1; + myinfo->rpcport = IGUANA_RPCPORT; + if ( arg != 0 ) + { + if ( strcmp((char *)arg,"OStests") == 0 ) + do_OStests = 1; + else if ( strcmp((char *)arg,"notary") == 0 ) + { + myinfo->rpcport = IGUANA_NOTARYPORT; + myinfo->IAMNOTARY = 1; + } + } #ifdef IGUANA_OSTESTS do_OStests = 1; #endif @@ -1580,7 +1589,6 @@ void iguana_main(void *arg) printf("OStests retval %d\n",retval); return; } - myinfo->rpcport = IGUANA_RPCPORT; strcpy(myinfo->rpcsymbol,"BTCD"); iguana_urlinit(myinfo,ismainnet,usessl); #if LIQUIDITY_PROVIDER diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 43a31ce02..7325ddb1b 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -63,6 +63,8 @@ HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr); HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,vote,hash,vals,hexstr); + ZERO_ARGS(bitcoinrpc,getinfo); ZERO_ARGS(bitcoinrpc,getblockcount); ZERO_ARGS(bitcoinrpc,getdifficulty); diff --git a/includes/iguana_defines.h b/includes/iguana_defines.h index bd7b3a7b9..bb7473585 100755 --- a/includes/iguana_defines.h +++ b/includes/iguana_defines.h @@ -49,6 +49,7 @@ #define IGUANA_MINPENDBUNDLES 4 #define IGUANA_MAXPENDBUNDLES 64 #define IGUANA_RPCPORT 7778 +#define IGUANA_NOTARYPORT 7776 #define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) #define IGUANA_MAPHASHTABLES 1 diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h index c737bac8d..051732b9c 100755 --- a/includes/iguana_funcs.h +++ b/includes/iguana_funcs.h @@ -124,7 +124,7 @@ void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,i 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); // init -struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags); +struct iguana_info *iguana_coinstart(struct supernet_info *myinfo,struct iguana_info *coin,int32_t initialheight,int32_t mapflags); void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin); void iguana_initcoin(struct iguana_info *coin,cJSON *argjson); void iguana_coinloop(void *arg); @@ -558,7 +558,7 @@ struct iguana_peer *iguana_peerfindipbits(struct iguana_info *coin,uint32_t ipbi int32_t basilisk_hashes_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,char *CMD,bits256 *txids,int32_t num); int32_t iguana_opreturn(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int64_t crypto777_payment,int32_t height,uint64_t hdrsi_unspentind,int64_t payment,uint32_t fileid,uint64_t scriptpos,uint32_t scriptlen); int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,long fileptr[2],char *fname,uint64_t scriptpos,int32_t scriptlen); -struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *btcd,uint32_t ipbits); +struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *notaries,uint32_t ipbits); int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t rmd160[20]); void iguana_RTreset(struct iguana_info *coin); diff --git a/includes/iguana_globals.h b/includes/iguana_globals.h index f00e640e5..fe8ad9c93 100755 --- a/includes/iguana_globals.h +++ b/includes/iguana_globals.h @@ -54,8 +54,8 @@ int32_t IGUANA_NUMHELPERS = 1; // ALL globals must be here! -CONDEXTERN struct basilisk_relay RELAYS[BASILISK_MAXRELAYS]; -CONDEXTERN int32_t NUMRELAYS,RELAYID; +//CONDEXTERN struct basilisk_relay RELAYS[BASILISK_MAXRELAYS]; +//CONDEXTERN int32_t NUMRELAYS,RELAYID; CONDEXTERN char *COMMANDLINE_ARGFILE; CONDEXTERN char *Iguana_validcommands[];