Browse Source

new code

release/v0.1
jl777 9 years ago
parent
commit
d0363b8fec
  1. 159
      basilisk/basilisk.c
  2. 32
      basilisk/basilisk_CMD.c
  3. 16
      datachain/datachain.c
  4. 90
      datachain/datachain.h
  5. 152
      gecko/gecko.c
  6. 13
      gecko/gecko.h
  7. 146
      gecko/gecko_blocks.c
  8. 172
      gecko/gecko_miner.c
  9. 2
      iguana/iguana.sources
  10. 10
      iguana/iguana777.c
  11. 1
      iguana/iguana777.h
  12. 4
      iguana/iguana_accept.c
  13. 4
      iguana/iguana_blocks.c
  14. 25
      iguana/iguana_bundles.c
  15. 6
      iguana/iguana_chains.c
  16. 29
      iguana/iguana_init.c
  17. 20
      iguana/iguana_instantdex.c
  18. 14
      iguana/iguana_json.c
  19. 23
      iguana/iguana_payments.c
  20. 35
      iguana/iguana_peers.c
  21. 10
      iguana/iguana_ramchain.c
  22. 4
      iguana/iguana_realtime.c
  23. 14
      iguana/iguana_recv.c
  24. 18
      iguana/iguana_spendvectors.c
  25. 11
      iguana/iguana_tx.c
  26. 2
      iguana/iguana_txidfind.c
  27. 1
      iguana/iguana_wallet.c
  28. 7
      iguana/main.c
  29. 2
      iguana/tests/new
  30. 42
      includes/iguana_apideclares.h
  31. 6
      includes/iguana_funcs.h
  32. 15
      includes/iguana_structs.h

159
basilisk/basilisk.c

@ -16,8 +16,8 @@
#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 pubkey,int32_t from_basilisk);
typedef struct basilisk_item *basilisk_requestfunc(struct basilisk_item *Lptr,struct supernet_info *myinfo,bits256 pubkey,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)
{
@ -80,35 +80,35 @@ uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t
uint8_t *basilisk_jsondata(uint8_t **ptrp,uint8_t *space,int32_t spacesize,int32_t *datalenp,char *symbol,cJSON *sendjson,uint32_t basilisktag)
{
char *sendstr,*hexstr; uint8_t *data; bits256 pubkey; int32_t i,datalen,hexlen=0,havepubkey=1;
char *sendstr,*hexstr; uint8_t *data; bits256 hash; int32_t i,datalen,hexlen=0,havehash=1;
if ( jobj(sendjson,"coin") == 0 )
jaddstr(sendjson,"coin",symbol);
if ( jobj(sendjson,"pubkey") != 0 )
if ( jobj(sendjson,"hash") != 0 )
{
havepubkey = 1;
pubkey = jbits256(sendjson,"pubkey");
havehash = 1;
hash = jbits256(sendjson,"hash");
}
if ( (hexstr= jstr(sendjson,"data")) != 0 && (hexlen= is_hexstr(hexstr,0)) > 0 )
hexlen >>= 1;
*ptrp = 0;
sendstr = jprint(sendjson,0);
datalen = (int32_t)strlen(sendstr) + 1;
if ( (datalen + BASILISK_HDROFFSET + hexlen + havepubkey*(sizeof(pubkey)+1)) <= spacesize )
if ( (datalen + BASILISK_HDROFFSET + hexlen + havehash*(sizeof(hash)+1)) <= spacesize )
data = space;
else
{
data = calloc(1,datalen + BASILISK_HDROFFSET + hexlen + havepubkey*(sizeof(pubkey)+1));
data = calloc(1,datalen + BASILISK_HDROFFSET + hexlen + havehash*(sizeof(hash)+1));
*ptrp = data;
}
data += BASILISK_HDROFFSET;
memcpy(data,sendstr,datalen);
free(sendstr);
if ( havepubkey != 0 || hexlen != 0 )
if ( havehash != 0 || hexlen != 0 )
{
if ( (data[datalen++]= havepubkey) != 0 )
if ( (data[datalen++]= havehash) != 0 )
{
for (i=0; i<32; i++)
data[datalen++] = pubkey.bytes[i];
data[datalen++] = hash.bytes[i];
}
}
if ( hexlen > 0 )
@ -159,7 +159,7 @@ struct basilisk_item *basilisk_itemcreate(struct supernet_info *myinfo,char *CMD
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,offset,havepubkey=0,retval = -1; char cmd[12]; struct iguana_info *coin,*tmp; struct iguana_peer *addr; bits256 pubkey; uint32_t *alreadysent;
int32_t i,r,l,s,val,n=0,offset,havehash=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 )
@ -178,17 +178,17 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ
else if ( strcmp(destipaddr,"127.0.0.1") == 0 )
{
printf("return after locally basilisk_msgprocess\n");
pubkey = GENESIS_PUBKEY;
hash = GENESIS_PUBKEY;
if ( datalen > 0 )
{
if ( (havepubkey= *data) != 0 )
if ( (havehash= *data) != 0 )
{
for (i=0; i<32; i++)
pubkey.bytes[i] = data[i + 1];
hash.bytes[i] = data[i + 1];
}
}
offset = (int32_t)(havepubkey * (1 + sizeof(bits256)));
basilisk_msgprocess(myinfo,0,0,type,*basilisktagp,data+offset,datalen-offset,pubkey);
offset = (int32_t)(havehash * (1 + sizeof(bits256)));
basilisk_msgprocess(myinfo,0,0,type,*basilisktagp,data+offset,datalen-offset,hash);
return(0);
}
}
@ -274,8 +274,8 @@ int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *vi
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 i,havepubkey,msglen,len=0; void *ptr = 0; uint8_t space[8192]; bits256 senderpub,pubkey,hash,hash2; struct supernet_info *myinfo = _myinfo;
pubkey = GENESIS_PUBKEY;
uint32_t ipbits,basilisktag; int32_t i,havehash,msglen,len=0; void *ptr = 0; uint8_t space[8192]; bits256 senderpub,hash,tmp,hash2; struct supernet_info *myinfo = _myinfo;
hash = GENESIS_PUBKEY;
if ( encrypted != 0 )
{
printf("encrypted basilisk_p2p.(%s) from %s\n",type,senderip!=0?senderip:"?");
@ -290,18 +290,17 @@ void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t
ipbits = (uint32_t)calc_ipbits(senderip);
else ipbits = 0;
len += iguana_rwnum(0,&data[len],sizeof(basilisktag),&basilisktag);
if ( datalen > len && (havepubkey= data[len]) != 0 )
if ( datalen > len && (havehash= data[len]) != 0 )
{
vcalc_sha256(0,hash.bytes,&data[len],datalen - len);
hash.uints[0] = basilisktag;
vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash));
char str[65]; printf("tag.%u %s\n",basilisktag,bits256_str(str,hash2));
vcalc_sha256(0,tmp.bytes,&data[len],datalen - len);
tmp.uints[0] = basilisktag;
vcalc_sha256(0,hash2.bytes,tmp.bytes,sizeof(tmp));
for (i=0; i<32; i++)
pubkey.bytes[i] = data[len + i + 1];
hash.bytes[i] = data[len + i + 1];
}
if ( bits256_nonz(pubkey) == 0 )
pubkey = GENESIS_PUBKEY;
basilisk_msgprocess(myinfo,_addr,ipbits,type,basilisktag,&data[len],datalen - len,pubkey);
if ( bits256_nonz(hash) == 0 )
hash = GENESIS_PUBKEY;
basilisk_msgprocess(myinfo,_addr,ipbits,type,basilisktag,&data[len],datalen - len,hash);
if ( ptr != 0 )
free(ptr);
}
@ -373,14 +372,14 @@ struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,int32_t
return(ptr);
}
struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char *CMD,cJSON *valsobj,bits256 pubkey,uint8_t *data,int32_t datalen,uint32_t nBits)
struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char *CMD,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits)
{
int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag; struct basilisk_item *ptr; char buf[4096],*str = 0;
basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen);
if ( jobj(valsobj,"pubkey") != 0 )
jdelete(valsobj,"pubkey");
if ( bits256_cmp(pubkey,GENESIS_PUBKEY) != 0 && bits256_nonz(pubkey) != 0 )
jaddbits256(valsobj,"pubkey",pubkey);
if ( jobj(valsobj,"hash") != 0 )
jdelete(valsobj,"hash");
if ( bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0 )
jaddbits256(valsobj,"hash",hash);
if ( (minresults= jint(valsobj,"minresults")) <= 0 )
minresults = 1;
if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 )
@ -662,64 +661,64 @@ INT_AND_ARRAY(basilisk,result,basilisktag,vals)
return(clonestr("{\"error\":\"no hexmsg to return\"}"));
}
HASH_ARRAY_STRING(basilisk,addrelay,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr)
{
return(basilisk_standardservice("ADD",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("ADD",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,dispatch,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr)
{
return(basilisk_standardservice("RUN",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("RUN",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,publish,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,publish,hash,vals,hexstr)
{
return(basilisk_standardservice("PUB",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("PUB",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,subscribe,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,subscribe,hash,vals,hexstr)
{
return(basilisk_standardservice("SUB",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("SUB",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,forward,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,forward,hash,vals,hexstr)
{
return(basilisk_standardservice("HOP",myinfo,pubkey,vals,hexstr,0));
return(basilisk_standardservice("HOP",myinfo,hash,vals,hexstr,0));
}
HASH_ARRAY_STRING(basilisk,mailbox,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,mailbox,hash,vals,hexstr)
{
return(basilisk_standardservice("BOX",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("BOX",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,VPNcreate,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr)
{
return(basilisk_standardservice("VPN",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("VPN",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,VPNjoin,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,VPNjoin,hash,vals,hexstr)
{
return(basilisk_standardservice("ARC",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("ARC",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,VPNmessage,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,VPNmessage,hash,vals,hexstr)
{
return(basilisk_standardservice("GAB",myinfo,pubkey,vals,hexstr,0));
return(basilisk_standardservice("GAB",myinfo,hash,vals,hexstr,0));
}
HASH_ARRAY_STRING(basilisk,VPNbroadcast,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr)
{
return(basilisk_standardservice("SAY",myinfo,pubkey,vals,hexstr,0));
return(basilisk_standardservice("SAY",myinfo,hash,vals,hexstr,0));
}
HASH_ARRAY_STRING(basilisk,VPNreceive,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr)
{
return(basilisk_standardservice("EAR",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("EAR",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,VPNlogout,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr)
{
return(basilisk_standardservice("END",myinfo,pubkey,vals,hexstr,0));
return(basilisk_standardservice("END",myinfo,hash,vals,hexstr,0));
}
#include "../includes/iguana_apiundefs.h"
@ -736,7 +735,7 @@ void basilisk_geckoresult(struct supernet_info *myinfo,struct basilisk_item *ptr
str = 0;
if ( (type= jstr(retjson,"type")) != 0 )
{
hash2 = jbits256(retjson,"pubkey");
hash2 = jbits256(retjson,"hash");
if ( strcmp(type,"HDR") == 0 )
str = gecko_headersarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2);
else if ( strcmp(type,"BLK") == 0 )
@ -894,12 +893,15 @@ void basilisks_loop(void *arg)
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 )
{
bitcoin_address(mineraddr,virt->chain->pubtype,myinfo->persistent_pubkey33,33);
//printf("mine.%s %s\n",virt->symbol,mineraddr);
gecko_miner(myinfo,btcd,virt,maxmillis,mineraddr);
gecko_miner(myinfo,btcd,virt,maxmillis,myinfo->persistent_pubkey33);
flag++;
}
}
//portable_mutex_unlock(&Allcoins_mutex);
}
}
@ -916,6 +918,9 @@ void basilisks_init(struct supernet_info *myinfo)
//bits256 basiliskhash;
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);
//basiliskhash = calc_categoryhashes(0,"basilisk",0);
//myinfo->basilisk_category = basiliskhash;
//category_subscribe(myinfo,basiliskhash,GENESIS_PUBKEY);
@ -924,7 +929,21 @@ void basilisks_init(struct supernet_info *myinfo)
myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD);
}
void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen,bits256 pubkey)
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,bits256 hash)
{
cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0;
static basilisk_servicefunc *basilisk_services[][2] =
@ -943,8 +962,8 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
// 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 *)"PUB", &basilisk_respond_publish }, // adds to global list of published items
{ (void *)"SUB", &basilisk_respond_subscribe }, // subscribes to one or all published items
{ (void *)"BID", &basilisk_respond_bid },
{ (void *)"ASK", &basilisk_respond_ask },
// encrypted data for jumblr
{ (void *)"HOP", &basilisk_respond_forward }, // message forwarding
@ -984,6 +1003,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
cmd[i] = tolower((int32_t)CMD[i]);
}
//printf("MSGPROCESS.(%s)\n",(char *)data);
myinfo->basilisk_busy = 1;
if ( (valsobj= cJSON_Parse((char *)data)) != 0 )
{
jsonlen = (int32_t)strlen((char *)data) + 1;
@ -991,7 +1011,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
{
data += jsonlen, datalen -= jsonlen;
if ( *data++ != 0 )
data += sizeof(pubkey), datalen -= sizeof(pubkey);
data += sizeof(hash), datalen -= sizeof(hash);
} else data = 0, datalen = 0;
if ( (symbol= jstr(valsobj,"coin")) == 0 )
symbol = "BTCD";
@ -999,7 +1019,10 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
if ( (numrequired= jint(valsobj,"numrequired")) == 0 )
numrequired = 1;
if ( jobj(valsobj,"coin") != 0 )
coin = iguana_coinfind(jstr(valsobj,"coin"));
{
if ( (coin= iguana_coinfind(jstr(valsobj,"coin"))) != 0 )
coin->basilisk_busy = 1;
}
if ( senderipbits != 0 )
expand_ipbits(remoteaddr,senderipbits);
else remoteaddr[0] = 0;
@ -1011,7 +1034,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
{
if ( from_basilisk != 0 )
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,pubkey,from_basilisk)) != 0 )
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 )
@ -1021,6 +1044,9 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
}
} else printf("non-relay got unexpected.(%s)\n",type);
free_json(valsobj);
if ( coin != 0 )
coin->basilisk_busy = 0;
myinfo->basilisk_busy = 0;
return;
}
}
@ -1055,6 +1081,9 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
free_json(valsobj);
if ( retstr != 0 )
free(retstr);
if ( coin != 0 )
coin->basilisk_busy = 0;
myinfo->basilisk_busy = 0;
}

32
basilisk/basilisk_CMD.c

@ -15,7 +15,7 @@
// included from basilisk.c
char *basilisk_respond_goodbye(struct supernet_info *myinfo,char *CMD,void *_addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_goodbye(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)
{
struct iguana_peer *addr = _addr;
printf("(%s) sends goodbye\n",remoteaddr);
@ -32,75 +32,77 @@ void basilisk_request_goodbye(struct supernet_info *myinfo)
free_json(valsobj);
}
char *basilisk_respond_publish(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_bid(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)
{
char *retstr=0;
printf("from.(%s) PUB.(%s) datalen.%d\n",remoteaddr,jprint(valsobj,0),datalen);
printf("from.(%s) BID.(%s) datalen.%d\n",remoteaddr,jprint(valsobj,0),datalen);
instantdex_quotep2p(myinfo,0,addr,data,datalen);
return(retstr);
}
char *basilisk_respond_subscribe(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_ask(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)
{
char *retstr=0;
printf("from.(%s) SUB.(%s) datalen.%d\n",remoteaddr,jprint(valsobj,0),datalen);
printf("from.(%s) ASK.(%s) datalen.%d\n",remoteaddr,jprint(valsobj,0),datalen);
instantdex_quotep2p(myinfo,0,addr,data,datalen);
return(retstr);
}
char *basilisk_respond_dispatch(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_dispatch(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_addrelay(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_addrelay(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_forward(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_forward(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_mailbox(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_mailbox(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_VPNcreate(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_VPNcreate(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_VPNjoin(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_VPNjoin(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_VPNlogout(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_VPNlogout(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_VPNbroadcast(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_VPNbroadcast(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_VPNreceive(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_VPNreceive(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)
{
char *retstr=0;
return(retstr);
}
char *basilisk_respond_VPNmessage(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 pubkey,int32_t from_basilisk)
char *basilisk_respond_VPNmessage(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)
{
char *retstr=0;
return(retstr);

16
datachain/datachain.c

@ -0,0 +1,16 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/

90
datachain/datachain.h

@ -0,0 +1,90 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
#ifndef H_DATACHAIN_H
#define H_DATACHAIN_H
// Mutually Exclusive - first one to get this value is the only one that can get it, subsequent requests get rejected, unless it is from the original creator of the specific data item
// Majority (threshold) vote - anybody can submit, but until the required thresholds are met there is no valid value
// Auction and reverse auction - anybody can submit, everybody sees the highest (lowest) value
// Random - value is a random value, but all nodes get the same value, useful for lottery type of use cases
// MofN - shamir's shared secret
// Pegged - values can be derived from external data feeds and pegged to a moving average
// Averaged - value is a determistically chosen value that is close to the majority of other values in the time period. it is not a true mathematical average, but over time will be very close to the average. The advantage is that submission of bogus values wont affect things much.
// Orderbook - price and volume are combined for bids and asks, Orderbook is constructed from auction (bid) and reverse auction (ask)
// Oneshot (limited triggers) - defined value can only happen the specified number of times, then the data field is expired
// Derived - value is derived from a combination of other values using a standard set of operations. For binary evaluation, values above 0 are treated as true, below zero as false and 0 means undefined. If any value a derived field depends on is undefined, then it also is undefined.
// Scripts - turing complete scripts can be specified in C, that will have access to all the data fields and be able to do standard transactions and invoke any of the other derived data types.
#define DATACHAIN_TYPE_BALANCE 1
#define DATACHAIN_TYPE_DEPOSIT 2
#define DATACHAIN_TYPE_PAYMENT 3
#define DATACHAIN_TYPE_GROUP 4
#define DATACHAIN_TYPE_QUOTE 5
#define DATACHAIN_TYPE_EXCLUSIVE 10
#define DATACHAIN_TYPE_MAJORITY 11
#define DATACHAIN_TYPE_AUCTION 12
#define DATACHAIN_TYPE_REVAUCTION 13
#define DATACHAIN_TYPE_RANDOM 20
#define DATACHAIN_TYPE_MOFN 21
#define DATACHAIN_TYPE_PEGGED 22
#define DATACHAIN_TYPE_AVERAGED 100
#define DATACHAIN_TYPE_ORDERBOOK 101
#define DATACHAIN_TYPE_DERIVED 102
#define DATACHAIN_TYPE_TRIGGER 200
#define DATACHAIN_TYPE_TURING 1000
#define DATACHAIN_TYPE_GATEWAY 1001
#define DATACHAIN_ACTION_SWAP 10000
#define DATACHAIN_ACTION_PAY 10001
#define DATACHAIN_ACTION_BID 10002
#define DATACHAIN_ACTION_ASK 10003
#define DATACHAIN_ACTION_QUOTE 10004
#define DATACHAIN_ACTION_SENDGROUP 10005
struct datachain_itemexclusive { uint8_t ownerpub[33]; };
struct datachain_item
{
struct iguana_info *coin;
uint64_t value;
int32_t firstheight;
uint32_t expiration; // expires first time BTCD block timestamp exceeds expiration
uint16_t type,scaling,minconfirms;
char label[32];
uint8_t rmd160[20];
uint8_t itemdata[];
};
struct datachain_info
{
};
#endif

152
gecko/gecko.c

@ -13,11 +13,35 @@
* *
******************************************************************************/
// code mempool and tx (payment and opreturn protocol)
// debug genesis balances
// debug remote <-> server and p2p network
// debug network port mode
// debug virtual + network port mode
// debug reorgs, detect when network is forked
// port DEX to use geckochain
// debug DEXchain
// code subchains synchronized with parent chain
// port pangea to use gecko with subchains
// debug pangea
// debug delayed PoW, code BTCD -> BTC, delegate selection using virtual coin stakes
// code datachain
//
#include "../iguana/iguana777.h"
#include "gecko_delayedPoW.c"
#include "gecko_miner.c"
#include "gecko_blocks.c"
int32_t iguana_ROallocsize(struct iguana_info *virt)
{
return(virt->chain->zcash != 0 ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block));
}
bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory)
{
bits256 categoryhash;
@ -66,6 +90,7 @@ queue_t *category_Q(struct gecko_chain **catptrp,bits256 categoryhash,bits256 su
void *category_subscribe(struct supernet_info *myinfo,bits256 chainhash,bits256 keyhash)
{
struct gecko_chain *chain,*subchain; bits256 hash;
portable_mutex_lock(&myinfo->gecko_mutex);
HASH_FIND(hh,Categories,chainhash.bytes,sizeof(chainhash),chain);
if ( chain == 0 )
{
@ -85,6 +110,7 @@ void *category_subscribe(struct supernet_info *myinfo,bits256 chainhash,bits256
HASH_ADD(hh,chain->subchains,hash,sizeof(hash),subchain);
}
}
portable_mutex_unlock(&myinfo->gecko_mutex);
return(chain);
}
@ -212,7 +238,7 @@ cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,i
memset(&genesis,0,sizeof(genesis));
genesis.RO.version = GECKO_DEFAULTVERSION;
genesis.RO.bits = nBits;
if ( (blockstr= gecko_createblock(myinfo,btcd,isPoS,&genesis,symbol,0,0,0,10000)) != 0 )
if ( (blockstr= gecko_createblock(myinfo,btcd,isPoS,&genesis,symbol,0,0,10000,0,0)) != 0 )
{
bits256_str(hashstr,genesis.RO.hash2);
sprintf(argbuf,"{\"isPoS\":%d,\"name\":\"%s\",\"symbol\":\"%s\",\"netmagic\":\"%s\",\"port\":%u,\"blocktime\":%u,\"pubval\":\"%s\",\"p2shval\":\"%s\",\"wifval\":\"%s\",\"isPoS\":%u,\"unitval\":\"%02x\",\"genesishash\":\"%s\",\"genesis\":{\"version\":1,\"timestamp\":%u,\"nBits\":\"%s\",\"nonce\":%d,\"merkle_root\":\"%s\"},\"genesisblock\":\"%s\"}",isPoS,chainname,symbol,magicstr,juint(valsobj,"port"),blocktime,pubstr,p2shstr,wifvalstr,juint(valsobj,"isPoS"),(nBits >> 24) & 0xff,hashstr,genesis.RO.timestamp,nbitstr,genesis.RO.nonce,bits256_str(str2,genesis.RO.merkle_root),blockstr);
@ -230,7 +256,8 @@ cJSON *gecko_genesisissue(char *symbol,char *chainname,char *chainstr,cJSON *val
struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbol,char *chainname,cJSON *valsobj)
{
int32_t datalen,hdrsize; struct iguana_info *virt=0; char *hexstr; uint8_t hexbuf[1024],*ptr,*serialized; struct iguana_peer *addr;
int32_t datalen,hdrsize,len=0; struct iguana_info *virt=0; char *hexstr; uint8_t hexbuf[1024],*ptr,*serialized; struct iguana_peer *addr; struct iguana_txblock txdata;
portable_mutex_lock(&myinfo->gecko_mutex);
if ( iguana_coinfind(symbol) == 0 && (hexstr= jstr(valsobj,"genesisblock")) != 0 && (virt= iguana_coinadd(symbol,chainname,valsobj)) != 0 )
{
safecopy(virt->name,chainname,sizeof(virt->name));
@ -245,11 +272,18 @@ struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbo
memcpy(virt->chain->genesis_hashdata,virt->chain->genesishash2.bytes,sizeof(virt->chain->genesishash2));
if ( ptr != 0 )
free(ptr);
if ( virt->TXMEM.ptr == 0 )
iguana_meminit(&virt->TXMEM,virt->name,0,IGUANA_MAXPACKETSIZE * 2,0);
virt->chain->genesis_hex = clonestr(hexstr);
virt->MAXPEERS = 0;
virt->RELAYNODE = 1;
virt->virtualchain = 1;
addr = &virt->internaladdr;
strcpy(virt->VALIDATEDIR,GLOBAL_VALIDATEDIR);
printf("GLOBAL_VALIDATEDIR.(%s) (%s)\n",GLOBAL_VALIDATEDIR,virt->VALIDATEDIR);
iguana_callcoinstart(myinfo,virt);
iguana_initpeer(virt,addr,calc_ipbits("127.0.0.1"));
iguana_peerslotinit(virt,addr,IGUANA_MAXPEERS,addr->ipbits);
if ( addr->blockspace == 0 )
addr->blockspace = calloc(1,IGUANA_MAXPACKETSIZE + 8192);
if ( addr->RAWMEM.ptr == 0 )
@ -258,9 +292,20 @@ struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbo
iguana_meminit(&addr->TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE * 2,0);
if ( addr->HASHMEM.ptr == 0 )
iguana_meminit(&addr->HASHMEM,"HASHPTRS",0,256,0);//IGUANA_MAXPACKETSIZE*16,0);
iguana_callcoinstart(virt);
iguana_bundlesload(myinfo,virt);
if ( virt->blocks.hwmchain.height == 0 )
{
memset(&txdata,0,sizeof(txdata));
iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,serialized,datalen);
txdata.zblock.height = 0;
txdata.zblock.RO.allocsize = iguana_ROallocsize(virt);
gecko_hwmset(virt,&txdata,virt->TXMEM.ptr,serialized,datalen,txdata.numtxids);
}
virt->started = virt;
virt->active = (uint32_t)time(NULL);
} else printf("error validating nonce\n");
}
portable_mutex_unlock(&myinfo->gecko_mutex);
return(virt);
}
@ -367,7 +412,7 @@ char *basilisk_standardreturn(char *CMD,char *type,struct iguana_info *virt,uint
jaddstr(retjson,"coin",virt->symbol);
jaddnum(retjson,"longest",virt->longestchain);
jaddnum(retjson,"hwm",virt->blocks.hwmchain.height);
jaddbits256(retjson,"pubkey",virt->blocks.hwmchain.RO.hash2);
jaddbits256(retjson,"hash",virt->blocks.hwmchain.RO.hash2);
}
else jaddstr(retjson,"error","no data to send");
if ( allocstr != 0 )
@ -403,14 +448,14 @@ int32_t basilisk_respond_geckogetheaders(struct supernet_info *myinfo,struct igu
int32_t basilisk_respond_geckogetblock(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2)
{
int32_t datalen = 0;
// set serialized
// find block and set serialized
return(datalen);
}
int32_t basilisk_respond_geckogettx(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2)
{
int32_t datalen = 0;
// set serialized
// find txid and set serialized
return(datalen);
}
@ -448,39 +493,15 @@ char *basilisk_respond_geckoheaders(struct supernet_info *myinfo,char *CMD,void
char *basilisk_respond_geckotx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 txid,int32_t from_basilisk)
{
bits256 checktxid; int32_t blocklen; uint32_t nBits; char *symbol,*blockstr,*txptrs[2],space[4096]; struct iguana_info *virt; cJSON *sendjson; struct iguana_block newblock; uint8_t *blockdata,*allocptr,blockspace[8192];
bits256 checktxid; char *symbol; struct iguana_info *virt;
if ( data != 0 && datalen != 0 && (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 )
{
checktxid = bits256_doublesha256(0,data,datalen);
memset(&newblock,0,sizeof(newblock));
newblock.height = virt->blocks.hwmchain.height + 1;
newblock.RO.prev_block = virt->blocks.hwmchain.RO.prev_block;
newblock.RO.version = GECKO_DEFAULTVERSION;
if ( bits256_cmp(txid,checktxid) == 0 && (nBits= gecko_nBits(virt,&newblock,GECKO_DIFFITERS)) != 0 )
{
newblock.RO.bits = nBits;
txptrs[0] = basilisk_addhexstr(&txptrs[1],0,space,sizeof(space),data,datalen); // add mempool
if ( (blockstr= gecko_createblock(myinfo,iguana_coinfind("BTCD"),juint(valsobj,"isPoS"),&newblock,virt->symbol,txptrs,1,gecko_paymentsobj(myinfo,0,jobj(valsobj,"payments"),0),1000)) != 0 )
{
if ( _iguana_chainlink(virt,&newblock) != 0 )
{
sendjson = cJSON_CreateObject();
jaddstr(sendjson,"coin",symbol);
jaddnum(sendjson,"ht",newblock.height);
jaddbits256(sendjson,"pubkey",newblock.RO.hash2);
blockdata = basilisk_jsondata(&allocptr,blockspace,sizeof(blockspace),&blocklen,symbol,sendjson,basilisktag);
printf("broadcast %s %s\n",blockstr,jprint(sendjson,0));
basilisk_sendcmd(myinfo,0,"BLK",&basilisktag,juint(valsobj,"encrypt"),juint(valsobj,"delay"),&blockdata[sizeof(struct iguana_msghdr)+sizeof(basilisktag)],blocklen,-1,nBits);
if ( allocptr != 0 )
free(allocptr);
}
free(blockstr);
if ( bits256_cmp(txid,checktxid) == 0 )
return(gecko_txarrived(myinfo,virt,addr,data,datalen,txid));
else return(clonestr("{\"error\":\"geckotx mismatched txid\"}"));
}
if ( txptrs[1] != 0 )
free(txptrs[1]);
} else return(clonestr("{\"error\":\"geckotx doesnt match txid\"}"));
}
return(clonestr("{\"error\":\"no geckotx data\"}"));
return(clonestr("{\"error\":\"no geckotx chain or missing tx data\"}"));
}
char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk)
@ -505,14 +526,14 @@ char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *a
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
HASH_ARRAY_STRING(basilisk,sequence,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,sequence,hash,vals,hexstr)
{
return(basilisk_standardservice("SEQ",myinfo,pubkey,vals,hexstr,1));
return(basilisk_standardservice("SEQ",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,newgeckochain,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,newgeckochain,hash,vals,hexstr)
{
char chainname[GECKO_MAXNAMELEN],magicstr[9],*retstr,*symbol,*chainstr; struct iguana_info *btcd; cJSON *argjson,*argvals,*retjson=0; int32_t i,isPoS; uint32_t magic; struct gecko_chain *chain;
char chainname[GECKO_MAXNAMELEN],magicstr[9],*retstr=0,*symbol,*chainstr; struct iguana_info *btcd; cJSON *argjson,*argvals,*retjson=0; int32_t i,isPoS; uint32_t magic; struct gecko_chain *chain;
if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 && (chainstr= jstr(vals,"chain")) != 0 )
{
if ( iguana_coinfind(symbol) == 0 && (chain= gecko_chain(myinfo,chainname,vals)) != 0 && chain->info != 0 )
@ -534,8 +555,12 @@ HASH_ARRAY_STRING(basilisk,newgeckochain,pubkey,vals,hexstr)
{
argvals = gecko_genesisissue(symbol,chainname,chainstr,argjson);
if ( btcd->RELAYNODE != 0 || btcd->VALIDATENODE != 0 )
{
basilisk_wait(myinfo,0);
retstr = basilisk_respond_newgeckochain(myinfo,"NEW",0,0,0,argvals,0,0,GENESIS_PUBKEY,0);
else retstr = basilisk_standardservice("NEW",myinfo,GENESIS_PUBKEY,argvals,0,1);
}
if ( retstr == 0 )
retstr = basilisk_standardservice("NEW",myinfo,GENESIS_PUBKEY,argvals,0,1);
free_json(argvals);
if ( (argvals= cJSON_Parse(retstr)) != 0 )
{
@ -557,7 +582,20 @@ HASH_ARRAY_STRING(basilisk,newgeckochain,pubkey,vals,hexstr)
return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko chain\"}"));
}
HASH_ARRAY_STRING(basilisk,geckotx,pubkey,vals,hexstr)
char *gecko_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *data,int32_t datalen,bits256 txid,cJSON *vals,char *signedtx)
{
char *retstr = 0; struct iguana_info *btcd = iguana_coinfind("BTCD");
if ( btcd != 0 && (btcd->RELAYNODE != 0 || btcd->VALIDATENODE != 0) )
{
basilisk_wait(myinfo,virt);
retstr = basilisk_respond_geckotx(myinfo,"GTX",0,0,0,vals,data,datalen,txid,0);
}
if ( retstr == 0 )
retstr = basilisk_standardservice("GTX",myinfo,txid,vals,signedtx,1);
return(retstr);
}
HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr)
{
struct iguana_info *btcd,*virt; char *retstr=0,*symbol; uint8_t *data,*allocptr,space[4096]; int32_t datalen; bits256 txid;
if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 )
@ -566,11 +604,8 @@ HASH_ARRAY_STRING(basilisk,geckotx,pubkey,vals,hexstr)
{
txid = bits256_doublesha256(0,data,datalen);
if ( (virt= iguana_coinfind(symbol)) != 0 )
{
if ( btcd->RELAYNODE != 0 || btcd->VALIDATENODE != 0 )
retstr = basilisk_respond_geckotx(myinfo,"GTX",0,0,0,vals,data,datalen,txid,0);
else retstr = basilisk_standardservice("GTX",myinfo,txid,vals,hexstr,1);
}
retstr = gecko_sendrawtransaction(myinfo,virt,data,datalen,txid,vals,hexstr);
else retstr = clonestr("{\"error\":\"virtualchain not found\"}");
} else retstr = clonestr("{\"error\":\"no tx submitted\"}");
if ( allocptr != 0 )
free(allocptr);
@ -580,29 +615,40 @@ HASH_ARRAY_STRING(basilisk,geckotx,pubkey,vals,hexstr)
} return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko tx\"}"));
}
HASH_ARRAY_STRING(basilisk,geckoblock,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr)
{
return(clonestr("{\"error\":\"geckoblock is an internal reporting function\"}"));
}
HASH_ARRAY_STRING(basilisk,geckoheaders,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr)
{
return(clonestr("{\"error\":\"geckoheaders is an internal reporting function\"}"));
}
HASH_ARRAY_STRING(basilisk,geckoget,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,geckoget,hash,vals,hexstr)
{
return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,pubkey,0));
struct iguana_info *btcd,*virt; char *symbol;
if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 )
{
if ( (virt= iguana_coinfind(symbol)) != 0 )
{
basilisk_wait(myinfo,virt);
return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,hash,0));
} else return(clonestr("{\"error\":\"geckoget needs virtualchain\"}"));
}
return(clonestr("{\"error\":\"geckoget needs BTCD\"}"));
}
HASH_ARRAY_STRING(basilisk,geckogenesis,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,geckogenesis,hash,vals,hexstr)
{
long filesize; int32_t i,j,n,m; struct iguana_info *btcd; char *ref,*symbol,*retstr=0; cJSON *item,*array = 0,*arrayB = 0; FILE *fp;
if ( (btcd= iguana_coinfind("BTCD")) != 0 )
{
if ( (retstr= basilisk_standardservice("GEN",myinfo,pubkey,vals,hexstr,1)) != 0 )
if ( (retstr= basilisk_standardservice("GEN",myinfo,hash,vals,hexstr,1)) != 0 )
{
arrayB = cJSON_Parse(retstr);
item = cJSON_Parse(retstr);
arrayB = cJSON_CreateArray();
jaddi(arrayB,item);
free(retstr);
}
if ( btcd->RELAYNODE != 0 || btcd->VALIDATENODE != 0 )

13
gecko/gecko.h

@ -20,7 +20,7 @@
#define GECKO_MAXBTCDGAP 18
#define GECKO_DEFAULTVERSION 1
#define GECKO_EASIESTDIFF 0x1fffffff
#define GECKO_EASIESTDIFF 0x1f7fffff
#define GECKO_DEFAULTDIFF 0x1f00ffff
#define GECKO_DEFAULTDIFFSTR "1f00ffff"
@ -36,6 +36,14 @@ struct hashstamp { bits256 hash2; uint32_t timestamp; int32_t height; };
struct gecko_sequence { struct hashstamp *stamps; int32_t lastupdate,maxstamps,numstamps,lasti,longestchain; };
struct gecko_sequences { struct gecko_sequence BTC,BTCD; };
struct gecko_mempooltx { bits256 txid; char *rawtx; int64_t txfee; int32_t pending; uint32_t ipbits; };
struct gecko_mempool
{
int32_t numtx;
struct gecko_mempooltx txs[100];
};
struct gecko_chain
{
UT_hash_handle hh; queue_t Q;
@ -53,11 +61,12 @@ char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *a
char *basilisk_respond_geckoheaders(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk);
char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk);
void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr);
void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,uint8_t *minerpubkey33);
void gecko_seqresult(struct supernet_info *myinfo,char *retstr);
int32_t gecko_sequpdate(char *symbol,uint32_t reftimestamp);
char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2);
char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2);
char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2);
char *gecko_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *data,int32_t datalen,bits256 txid,cJSON *vals,char *signedtx);
#endif

146
gecko/gecko_blocks.c

@ -20,16 +20,64 @@ char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt
return(clonestr("{\"result\":\"gecko headers queued\"}"));
}
char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 txid)
char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *serialized,int32_t datalen,bits256 txid)
{
return(clonestr("{\"result\":\"gecko headers queued\"}"));
struct gecko_mempool *pool; int64_t txfee,vinstotal,voutstotal; uint64_t hdrsi_unspentind,value; int32_t i,numvins,numvouts,txlen,spentheight,minconf,maxconf,unspentind,hdrsi; struct gecko_mempooltx *mtx; struct iguana_msgtx msg;
memset(&msg,0,sizeof(msg));
iguana_memreset(&virt->TXMEM);
txlen = iguana_rwtx(virt->chain->zcash,0,&virt->TXMEM,serialized,&msg,datalen,&txid,virt->chain->isPoS,strcmp("VPN",virt->symbol) == 0);
vinstotal = voutstotal = 0;
maxconf = virt->longestchain;
minconf = virt->chain->minconfirms;
if ( (numvins= msg.tx_in) > 0 )
{
for (i=0; i<numvins; i++)
{
if ( (unspentind= iguana_unspentindfind(virt,0,0,0,&value,&spentheight,msg.vins[i].prev_hash,msg.vins[i].prev_vout,virt->bundlescount-1)) != 0 )
{
hdrsi = spentheight / virt->chain->bundlesize;
hdrsi_unspentind = ((uint64_t)hdrsi << 32) | unspentind;
if ( iguana_unspentavail(virt,hdrsi_unspentind,minconf,maxconf) != value )
{
printf("vin.%d already spent\n",i);
return(clonestr("{\"error\":\"gecko tx has double spend\"}"));
}
vinstotal += value;
}
}
}
if ( (numvouts= msg.tx_out) > 0 )
for (i=0; i<numvouts; i++)
voutstotal += msg.vouts[i].value;
if ( (txfee= (vinstotal - voutstotal)) < 0 )
return(clonestr("{\"error\":\"gecko tx has more spends than inputs\"}"));
if ( txlen <= 0 )
return(clonestr("{\"error\":\"couldnt decode gecko tx\"}"));
if ( (pool= virt->mempool) == 0 )
pool = virt->mempool = calloc(1,sizeof(*pool));
mtx = &pool->txs[pool->numtx];
memset(mtx,0,sizeof(*mtx));
mtx->txid = txid;
mtx->txfee = txfee;
mtx->ipbits = (uint32_t)calc_ipbits(remoteaddr);
mtx->rawtx = calloc(1,datalen*2 + 1);
init_hexbytes_noT(mtx->rawtx,serialized,datalen);
return(clonestr("{\"result\":\"gecko tx queued\"}"));
}
struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_block *block,int32_t origheight,int32_t depth)
{
int32_t hdrsi,bundlei,i,iter,checkbundlei,height = origheight; bits256 zero; struct iguana_block *prev; struct iguana_bundle *bp = 0;
int32_t hdrsi,bundlei,checkbundlei,height = origheight; bits256 zero; struct iguana_bundle *bp = 0;
memset(zero.bytes,0,sizeof(zero));
for (iter=0; iter<2; iter++)
bundlei = (height % virt->chain->bundlesize);
hdrsi = (height / virt->chain->bundlesize);
if ( bundlei == 0 )
{
if ( hdrsi+1 > virt->bundlescount )
virt->bundlescount = hdrsi + 1;
return(iguana_bundlecreate(virt,&checkbundlei,origheight,block->RO.hash2,zero,0));
}
/*for (iter=0; iter<2; iter++)
{
prev = block;
height = block->height;
@ -43,6 +91,7 @@ struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_
{
if ( (bp= virt->bundles[hdrsi]) != 0 )
{
iguana_hash2set(virt,"ensure",bp,bundlei,prev->RO.hash2);
bp->blocks[bundlei] = prev;
bp->hashes[bundlei] = prev->RO.hash2;
}
@ -56,19 +105,70 @@ struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_
iguana_bundlecreate(virt,&checkbundlei,height,prev->RO.hash2,zero,0);
prev = iguana_blockfind("geckoensure",virt,prev->RO.prev_block);
}
if ( iter == 0 )
{
char str[65];
bundlei = (origheight % virt->chain->bundlesize);
hdrsi = (origheight / virt->chain->bundlesize);
if ( (bp= virt->bundles[hdrsi]) != 0 )
iguana_hash2set(virt,"ensure",bp,bundlei,block->RO.hash2);
if ( iguana_bundlefind(virt,&bp,&bundlei,block->RO.hash2) == 0 )
printf("cant find ht.%d %s\n",block->height,bits256_str(str,block->RO.hash2));
}
}*/
hdrsi = (block->height / virt->chain->bundlesize);
return(virt->bundles[hdrsi]);
if ( (bp= virt->bundles[hdrsi]) == 0 )
printf("error ensuring bundle ht.%d\n",origheight);
else
{
bp->blocks[bundlei] = block;
bp->hashes[bundlei] = block->RO.hash2;
//char str[65]; printf("[%d:%d] <- %s %p\n",hdrsi,bundlei,bits256_str(str,block->RO.hash2),block);
iguana_hash2set(virt,"ensure",bp,bundlei,block->RO.hash2);
}
return(bp);
}
int32_t gecko_hwmset(struct iguana_info *virt,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,uint8_t *data,int32_t datalen,int32_t depth)
{
struct iguana_peer *addr; int32_t hdrsi; struct iguana_bundle *bp,*prevbp; struct iguana_block *block;
if ( (block= iguana_blockhashset("gecko_hwmset",virt,txdata->zblock.height,txdata->zblock.RO.hash2,1)) != 0 )
{
iguana_blockcopy(virt->chain->zcash,virt->chain->auxpow,virt,block,(struct iguana_block *)&txdata->zblock);
} else return(-1);
addr = &virt->internaladdr;
if ( gecko_ensurebundle(virt,block,block->height,depth) == 0 )
return(-1);
if ( iguana_ramchain_data(virt,addr,txdata,txarray,block->RO.txn_count,data,datalen) >= 0 )
{
block->fpipbits = (uint32_t)addr->ipbits;
block->RO.recvlen = datalen;
block->txvalid = 1;
iguana_blockzcopy(virt->chain->zcash,(void *)&virt->blocks.hwmchain,block);
hdrsi = block->height / virt->chain->bundlesize;
if ( (bp= virt->bundles[hdrsi]) != 0 )
{
bp->numsaved++;
if ( (block->height % virt->chain->bundlesize) == 13 && hdrsi > 0 && (prevbp= virt->bundles[hdrsi - 1]) != 0 && prevbp->emitfinish == 0 && prevbp->numsaved >= prevbp->n )
{
iguana_bundlefinalize(virt,prevbp,&virt->MEM,virt->MEMB);
prevbp->emitfinish = (uint32_t)(time(NULL) - 3600);
iguana_bundlepurgefiles(virt,prevbp);
iguana_savehdrs(virt);
iguana_bundlevalidate(virt,prevbp,1);
}
}
//printf("created block.%d [%d:%d] %d\n",block->height,bp!=0?bp->hdrsi:-1,block->height%virt->chain->bundlesize,bp->numsaved);
return(block->height);
}
return(-1);
}
char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2)
{
struct iguana_txblock txdata; int32_t valid,adjacent,n,i,hdrsi,j,len = -1; struct iguana_peer *addr; struct iguana_block *block,*prev; struct iguana_bundle *bp;
struct iguana_txblock txdata; int32_t valid,adjacent,n,i,j,len = -1; struct iguana_block *block,*prev;
memset(&txdata,0,sizeof(txdata));
if ( virt->TXMEM.ptr == 0 )
iguana_meminit(&virt->TXMEM,virt->name,0,IGUANA_MAXPACKETSIZE * 2,0);
iguana_memreset(&virt->TXMEM);
addr = &virt->internaladdr;
if ( (n= iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,data,datalen)) == datalen )
{
if ( bits256_cmp(hash2,txdata.zblock.RO.hash2) != 0 )
@ -76,7 +176,7 @@ char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,c
printf("gecko_blockarrived: mismatched hash2\n");
return(clonestr("{\"error\":\"gecko block hash2 mismatch\"}"));
}
txdata.zblock.RO.allocsize = sizeof(struct iguana_block);
txdata.zblock.RO.allocsize = iguana_ROallocsize(virt);
if ( iguana_blockvalidate(virt,&valid,(struct iguana_block *)&txdata.zblock,1) < 0 )
{
char str[65]; printf("got block that doesnt validate? %s\n",bits256_str(str,txdata.zblock.RO.hash2));
@ -99,11 +199,11 @@ char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,c
//printf("i.%d prevht.%d adjacent.%d hwm.%d\n",i,prev->height,adjacent,virt->blocks.hwmchain.height);
if ( prev->height >= 0 )
{
block->height = adjacent + 1;
txdata.zblock.height = block->height = adjacent + 1;
if ( block->height > virt->blocks.hwmchain.height ) // longest chain wins
{
//printf("new HWM %d adjacent.%d prev.%d i.%d\n",block->height,adjacent,prev->height,i);
block->mainchain = 1;
txdata.zblock.mainchain = block->mainchain = 1;
prev = block;
// probably should clear mainchain bits in old path
for (j=0; j<=i; j++)
@ -112,27 +212,13 @@ char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,c
return(clonestr("{\"error\":\"gecko block mainchain link error\"}"));
prev->mainchain = 1;
}
iguana_blockzcopy(virt->chain->zcash,(void *)&virt->blocks.hwmchain,block);
if ( gecko_ensurebundle(virt,block,block->height,i+1) == 0 )
return(clonestr("{\"error\":\"gecko bundle couldnt be created\"}"));
if ( iguana_ramchain_data(virt,addr,&txdata,virt->TXMEM.ptr,txdata.zblock.RO.txn_count,data,datalen) >= 0 )
{
block->fpipbits = (uint32_t)addr->ipbits;
block->RO.recvlen = datalen;
block->txvalid = 1;
hdrsi = block->height / virt->chain->bundlesize;
if ( (bp= virt->bundles[hdrsi]) != 0 )
{
bp->numsaved++;
if ( (block->height % virt->chain->bundlesize) == 13 && hdrsi > 0 && (bp= virt->bundles[hdrsi - 1]) != 0 && bp->emitfinish == 0 && bp->numsaved >= bp->n )
iguana_bundlefinalize(virt,bp,&virt->MEM,virt->MEMB);
}
//printf("created block.%d [%d:%d] %d\n",block->height,bp!=0?bp->hdrsi:-1,block->height%virt->chain->bundlesize,bp->numsaved);
if ( gecko_hwmset(virt,&txdata,virt->TXMEM.ptr,data,datalen,i+1) >= 0 )
return(clonestr("{\"result\":\"gecko block created\"}"));
} else return(clonestr("{\"error\":\"gecko error creating ramchain0\"}"));
}
else return(clonestr("{\"error\":\"gecko error creating hwmblock\"}"));
} else return(clonestr("{\"results\":\"gecko block wasnt hwmblock\"}"));
}
}
return(clonestr("{\"error\":\"gecko orphan block\"}"));
}
return(clonestr("{\"error\":\"gecko block didnt decode\"}"));
}

172
gecko/gecko_miner.c

@ -25,32 +25,6 @@ int32_t gecko_blocknonce_verify(struct iguana_info *virt,uint8_t *serialized,int
else return(0);
}
/*uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchain,struct iguana_block *prev,struct iguana_block *prev2,int32_t PoSflag,int32_t targetspacing,int32_t targettimespan)
{
// targetspacing NTARGETSPACING, mspacing NINTERVAL_MSPACING, pspacing NINTERVAL_PSPACING
bits256 mpz_muldivcmp(bits256 oldval,int32_t mulval,int32_t divval,bits256 cmpval);
bits256 targetval; int32_t gap,mspacing,pspacing;
if ( hwmchain->height <= 2 || hwmchain->height <= 0 )
return(hwmchain->RO.bits);
mspacing = (((targettimespan / targetspacing) - 1) * targetspacing);
pspacing = (((targettimespan / targetspacing) + 1) * targetspacing);
targetval = iguana_targetval(coin,hwmchain->height,PoSflag);
if ( prev != 0 )
{
if ( prev2 != 0 && prev->RO.timestamp != 0 && prev2->RO.timestamp != 0 )
{
//if ( prev->RO.timestamp != 0 && prev2->RO.timestamp != 0 ) skip check for compatiblity
{
if ( (gap= prev->RO.timestamp - prev2->RO.timestamp) < 0 )
gap = targetspacing;
//printf("nBits.%08x gap.%d (%u - %u)\n",prev->RO.bits,gap,prev->RO.timestamp,prev2->RO.timestamp);
targetval = mpz_muldivcmp(bits256_from_compact(prev->RO.bits),mspacing + (gap << 1),pspacing,targetval);
}
}
}
return(bits256_to_compact(targetval));
}*/
uint32_t gecko_nBits(struct iguana_info *virt,struct iguana_block *block,int32_t n)
{
uint32_t nBits = GECKO_DEFAULTDIFF,starttime,endtime,est; struct iguana_block *prev=0; int32_t i,diff; bits256 targetval;
@ -92,18 +66,6 @@ uint32_t gecko_nBits(struct iguana_info *virt,struct iguana_block *block,int32_t
printf("nBits.%08x vs easiest %08x\n",nBits,GECKO_EASIESTDIFF);
nBits = GECKO_EASIESTDIFF;
}
/*if ( newblock->height >= 0 && (prev= iguana_blockfind("geckotx",virt,newblock->RO.prev_block)) != 0 && prev->height > 1 )
{
if ( (prev2= iguana_blockfind("prvatetx2",virt,prev->RO.prev_block)) != 0 && prev2->height >= 0 )
{
nBits = iguana_targetbits(virt,newblock,prev,prev2,1,virt->chain->targetspacing,virt->chain->targettimespan);
if ( nBits > GECKO_EASIESTDIFF )
{
printf("nBits.%08x vs easiest %08x\n",nBits,GECKO_EASIESTDIFF);
nBits = GECKO_EASIESTDIFF;
}
}
} else printf("ht.%d prev.%p prevht.%d prev2.%p\n",newblock->height,prev,prev!=0?prev->height:-1,prev2);*/
return(nBits);
}
@ -124,20 +86,58 @@ int32_t gecko_delayedPoW(struct supernet_info *myinfo,struct iguana_info *btcd,i
return(len);
}
char *gecko_coinbasestr(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,uint8_t *data,int32_t datalen,bits256 coinbasespend,cJSON *coinbasetx)
int32_t iguana_coinbase(struct iguana_info *virt,uint8_t *serialized,uint32_t timestamp,bits256 prev_hash,uint8_t *coinbasescript,uint32_t coinbaselen,uint8_t *minerpayment,uint32_t minerpaymentlen,int64_t blockreward,bits256 *txidp)
{
int32_t len = 0,rwflag=1; uint32_t prev_vout,sequence,lock_time; char txidstr[65]; struct iguana_msgtx msg;
memset(&msg,0,sizeof(msg));
msg.tx_out = (blockreward > 0) ? 1 : 0;
msg.tx_in = 1;
sequence = prev_vout = -1;
lock_time = 0;
msg.version = virt->chain->normal_txversion;
msg.timestamp = timestamp;
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg.version),&msg.version);
if ( virt->chain->isPoS != 0 )
len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg.timestamp),&msg.timestamp);
{
len += iguana_rwvarint32(rwflag,&serialized[len],&msg.tx_in);
// tx_in times
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(prev_hash),prev_hash.bytes);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(prev_vout),&prev_vout);
len += iguana_rwvarint32(rwflag,&serialized[len],&coinbaselen);
len += iguana_rwmem(rwflag,&serialized[len],coinbaselen,coinbasescript);
len += iguana_rwnum(rwflag,&serialized[len],sizeof(sequence),&sequence);
}
{
len += iguana_rwvarint32(rwflag,&serialized[len],&msg.tx_out);
// tx_out times
if ( msg.tx_out > 0 )
{
len += iguana_rwnum(rwflag,&serialized[len],sizeof(blockreward),&blockreward);
len += iguana_rwvarint32(rwflag,&serialized[len],&minerpaymentlen);
len += iguana_rwmem(rwflag,&serialized[len],minerpaymentlen,minerpayment);
}
}
len += iguana_rwnum(rwflag,&serialized[len],sizeof(lock_time),&lock_time);
*txidp = bits256_doublesha256(txidstr,serialized,len);
return(len);
}
char *gecko_coinbasestr(struct supernet_info *myinfo,struct iguana_info *virt,bits256 *txidp,uint32_t timestamp,uint8_t *minerpubkey,uint64_t blockreward,uint8_t *data,int32_t datalen,bits256 coinbasespend)
{
char *rawtx; cJSON *txjson;
if ( (txjson= coinbasetx) == 0 )
txjson = bitcoin_txcreate(1,0,coin->chain->normal_txversion);
bitcoin_txinput(coin,txjson,coinbasespend,-1,0xffffffff,0,0,data,datalen,0,0);
//printf("TX.(%s)\n",jprint(txjson,0));
rawtx = bitcoin_json2hex(myinfo,coin,txidp,txjson,0);
if ( txjson != coinbasetx )
free_json(txjson);
char *rawtx=0; uint8_t minerpayment[512],serialized[8192]; int32_t minerpaymentlen=0,len=0;
if ( blockreward > 0 )
minerpaymentlen = bitcoin_pubkeyspend(minerpayment,0,minerpubkey);
len = iguana_coinbase(virt,serialized,timestamp,coinbasespend,data,datalen,minerpayment,minerpaymentlen,blockreward,txidp);
if ( len > 0 )
{
rawtx = malloc(len*2 + 1);
init_hexbytes_noT(rawtx,serialized,len);
}
return(rawtx);
}
char *gecko_block(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_block *newblock,uint32_t *noncep,char **txptrs,int32_t txn_count,uint8_t *coinbase,int32_t coinbaselen,bits256 coinbasespend,cJSON *coinbasetx,double expiration)
char *gecko_block(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_block *newblock,uint32_t *noncep,char **txptrs,int32_t txn_count,uint8_t *coinbase,int32_t coinbaselen,bits256 coinbasespend,double expiration,uint8_t *minerpubkey,int64_t blockreward)
{
struct iguana_info *btcd; uint8_t serialized[sizeof(*newblock)],space[16384],*txdata,*allocptr = 0; int32_t i,n,totaltxlen=0,txlen; char *coinbasestr,*blockstr=0; bits256 *txids=0,txspace[256],threshold;
//char str[65]; printf("prevblock.%s\n",bits256_str(str,newblock->RO.prev_block));
@ -168,7 +168,7 @@ char *gecko_block(struct supernet_info *myinfo,struct iguana_info *virt,struct i
free(allocptr);
}
}
if ( (coinbasestr= gecko_coinbasestr(myinfo,virt,&txids[0],coinbase,coinbaselen,coinbasespend,coinbasetx)) != 0 )
if ( (coinbasestr= gecko_coinbasestr(myinfo,virt,&txids[0],newblock->RO.timestamp,minerpubkey,blockreward,coinbase,coinbaselen,coinbasespend)) != 0 )
{
newblock->RO.merkle_root = iguana_merkle(txids,txn_count + 1);
newblock->RO.txn_count = (txn_count + 1);
@ -204,7 +204,7 @@ char *gecko_block(struct supernet_info *myinfo,struct iguana_info *virt,struct i
return(blockstr);
}
char *gecko_createblock(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,struct iguana_block *newblock,char *symbol,char **txptrs,int32_t txn_count,cJSON *coinbasetx,int32_t maxmillis)
char *gecko_createblock(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,struct iguana_block *newblock,char *symbol,char **txptrs,int32_t txn_count,int32_t maxmillis,uint8_t *minerpubkey,int64_t blockreward)
{
bits256 btcdhash; uint8_t coinbase[512]; int32_t coinbaselen; uint32_t nonce; double expiration = OS_milliseconds() + maxmillis;
//char str[65]; printf("create prev.(%s) %p\n",bits256_str(str,newblock->RO.prev_block),&newblock->RO.prev_block);
@ -217,7 +217,7 @@ char *gecko_createblock(struct supernet_info *myinfo,struct iguana_info *btcd,in
return(0);
}
nonce = 0;
return(gecko_block(myinfo,btcd,newblock,&nonce,txptrs,txn_count,coinbase,coinbaselen,btcdhash,coinbasetx,expiration));
return(gecko_block(myinfo,btcd,newblock,&nonce,txptrs,txn_count,coinbase,coinbaselen,btcdhash,expiration,minerpubkey,blockreward));
} else return(0);
}
@ -275,11 +275,38 @@ cJSON *gecko_paymentsobj(struct supernet_info *myinfo,cJSON *txjson,cJSON *valso
return(txjson);
}
char **gecko_mempool(struct supernet_info *myinfo,struct iguana_info *virt,int64_t *rewardp,int32_t *txn_countp,char **ptrp,void *space,int32_t max)
void **gecko_mempool(struct supernet_info *myinfo,struct iguana_info *virt,int64_t *rewardp,int32_t *txn_countp,void **ptrp,void *space,int32_t max,int32_t height)
{
int32_t i,n; void **txptrs; struct gecko_mempool *pool; int64_t txfees = 0,reward = virt->chain->initialreward;
if ( virt->chain->halvingduration != 0 && (n= (height / virt->chain->halvingduration)) != 0 )
{
for (i=0; i<n; i++)
reward >>= 1;
}
*ptrp = 0;
*txn_countp = 0;
return(0);
if ( (pool= virt->mempool) == 0 )
pool = virt->mempool = calloc(1,sizeof(*pool));
if ( pool->numtx*sizeof(char *) <= max )
txptrs = space;
else
{
txptrs = calloc(pool->numtx,sizeof(char *));
*ptrp = (void *)txptrs;
}
for (i=n=0; i<pool->numtx; i++)
{
if ( pool->txs[i].pending == 0 )
{
txfees += pool->txs[i].txfee;
txptrs[n++] = pool->txs[i].rawtx;
pool->txs[i].pending = height;
}
}
*rewardp = (reward + txfees);
if ( (*txn_countp= n) != 0 )
return(txptrs);
else return(0);
}
void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2)
@ -302,50 +329,29 @@ void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,cha
}
}
void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr)
void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,uint8_t *minerpubkey33)
{
struct iguana_zblock newblock; uint32_t nBits,locktime=0; int64_t reward = 0; int32_t bundlei,txn_count; cJSON *item,*array,*coinbasetx=0; char *blockstr,**txptrs,*ptr,*space[256]; struct iguana_bundle *bp;
if ( virt->virtualchain == 0 )//|| virt->bundles[virt->blocks.hwmchain.height / virt->chain->bundlesize] == 0 )
struct iguana_zblock newblock; uint32_t nBits; int64_t reward = 0; int32_t txn_count; char *blockstr,*space[256]; void **txptrs,*ptr; //struct iguana_bundle *bp;
if ( virt->virtualchain == 0 )
return;
memset(&newblock,0,sizeof(newblock));
newblock.height = virt->blocks.hwmchain.height + 1;
newblock.RO.prev_block = virt->blocks.hwmchain.RO.hash2;
newblock.RO.version = GECKO_DEFAULTVERSION;
newblock.RO.allocsize = sizeof(struct iguana_block);
newblock.RO.allocsize = iguana_ROallocsize(virt);
if ( (nBits= gecko_nBits(virt,(void *)&newblock,GECKO_DIFFITERS)) != 0 )
{
newblock.RO.bits = nBits;
//printf("mine.%s %s nBits.%x\n",virt->symbol,mineraddr,nBits);
txptrs = gecko_mempool(myinfo,virt,&reward,&txn_count,&ptr,space,(int32_t)(sizeof(space)/sizeof(*space)));
if ( reward > 0 )
{
array = cJSON_CreateArray();
item = cJSON_CreateObject();
jaddnum(item,mineraddr,dstr(reward));
jaddi(array,item);
coinbasetx = bitcoin_txcreate(1,locktime,virt->chain->normal_txversion);
jadd(coinbasetx,"payments",array);
}
//printf("mine.%s nBits.%x ht.%d\n",virt->symbol,nBits,newblock.height);
txptrs = gecko_mempool(myinfo,virt,&reward,&txn_count,&ptr,space,(int32_t)(sizeof(space)/sizeof(*space)),newblock.height);
//char str[65]; printf("HWM.%s %p\n",bits256_str(str,newblock.RO.prev_block),&newblock.RO.prev_block);
if ( (blockstr= gecko_createblock(myinfo,btcd,virt->chain->isPoS,(void *)&newblock,virt->symbol,txptrs,txn_count,coinbasetx,maxmillis)) != 0 )
if ( (blockstr= gecko_createblock(myinfo,btcd,virt->chain->isPoS,(void *)&newblock,virt->symbol,(char **)txptrs,txn_count,maxmillis,minerpubkey33,reward)) != 0 )
{
if ( (bundlei= (newblock.height % virt->chain->bundlesize)) == 0 )
iguana_bundlecreate(virt,&bundlei,newblock.height,newblock.RO.hash2,newblock.RO.prev_block,1);
newblock.RO.allocsize = virt->chain->zcash != 0 ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block);
if ( (bp= virt->bundles[newblock.height / virt->chain->bundlesize]) != 0 )
{
char str[65];
iguana_hash2set(virt,"miner",bp,bundlei,newblock.RO.hash2);
if ( iguana_bundlefind(virt,&bp,&bundlei,newblock.RO.hash2) == 0 )
printf("cant find ht.%d %s\n",newblock.height,bits256_str(str,newblock.RO.hash2));
//else printf("found bp.%p bundlei.%d\n",bp,bundlei);
}
//virt->blocks.hwmchain = newblock;
//char str[65]; printf("%s mined.%x %s %u ht.%d\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),newblock.RO.timestamp,newblock.height);
char str[65]; printf("%s.%x %s %u %d %.8f\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),newblock.RO.timestamp,newblock.height,dstr(reward));
gecko_blocksubmit(myinfo,virt,blockstr,newblock.RO.hash2);
free(blockstr);
}
if ( txptrs != space )
if ( txptrs != (void *)space )
free(txptrs);
}
}

2
iguana/iguana.sources

@ -1,2 +1,2 @@
SOURCES := iguana_bundles.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c ../gecko/gecko.c ../basilisk/basilisk.c secp256k1/src/secp256k1.c
SOURCES := iguana_bundles.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c ../gecko/gecko.c ../basilisk/basilisk.c ../datachain/datachain.c secp256k1/src/secp256k1.c

10
iguana/iguana777.c

@ -291,7 +291,7 @@ void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp)
void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit)
{
struct iguana_helper *ptr;
if ( bp->queued == 0 && bp->emitfinish <= 1 && iguana_bundleready(coin,bp,0) == bp->n )
if ( 0 && bp->queued == 0 && bp->emitfinish <= 1 && iguana_bundleready(coin,bp,0) == bp->n )
printf("bundle.[%d] is ready\n",bp->hdrsi);
bp->queued = (uint32_t)time(NULL);
ptr = mycalloc('i',1,sizeof(*ptr));
@ -656,7 +656,7 @@ void iguana_helper(void *arg)
}
}
void iguana_callcoinstart(struct iguana_info *coin)
void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin)
{
struct iguana_bundle *bp; int32_t bundlei; bits256 zero; char dirname[512],*symbol;
iguana_rwiAddrind(coin,0,0,0);
@ -685,6 +685,8 @@ void iguana_callcoinstart(struct iguana_info *coin)
memset(zero.bytes,0,sizeof(zero));
if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 )
bp->bundleheight = 0;
if ( strcmp("BTCD",coin->symbol) == 0 )
basilisk_geckogenesis(myinfo,coin,0,0,GENESIS_PUBKEY,0,0);
}
void iguana_coinloop(void *arg)
@ -722,7 +724,7 @@ void iguana_coinloop(void *arg)
#endif
}
if ( coin->started == 0 && coin->active != 0 )
iguana_callcoinstart(coin);
iguana_callcoinstart(myinfo,coin);
now = (uint32_t)time(NULL);
coin->idletime = 0;
if ( coin->started != 0 && coin->active != 0 )
@ -735,8 +737,6 @@ void iguana_coinloop(void *arg)
coin->polltimeout = 100;
if ( coin->MAXPEERS > IGUANA_MINPEERS )
coin->MAXPEERS = IGUANA_MINPEERS;
if ( strcmp("BTCD",coin->symbol) == 0 )
basilisk_geckogenesis(myinfo,coin,0,0,GENESIS_PUBKEY,0,0);
}
if ( coin->isRT != 0 && coin->current != 0 && coin->numverified >= coin->current->hdrsi )
{

1
iguana/iguana777.h

@ -22,6 +22,7 @@ struct exchange_info;
#include "../crypto777/OS_portable.h"
#include "../basilisk/basilisk.h"
#include "../gecko/gecko.h"
#include "../datachain/datachain.h"
#include "../includes/iguana_defines.h"
#include "../includes/iguana_types.h"

4
iguana/iguana_accept.c

@ -66,6 +66,8 @@ void iguana_acceptloop(void *args)
struct iguana_peer *addr; struct iguana_info *coin = args;
struct pollfd pfd; int32_t sock; struct iguana_accept *ptr; uint16_t port = coin->chain->portp2p;
socklen_t clilen; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t i,ipbits,flag;
if ( coin->peers == 0 )
return;
while ( (coin->bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 )
{
if ( coin->peers->localaddr != 0 )
@ -362,6 +364,8 @@ int32_t iguana_peergetrequest(struct iguana_info *coin,struct iguana_peer *addr,
int32_t iguana_peeraddrrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t spacesize)
{
int32_t i,iter,n,max,sendlen; uint64_t x; struct iguana_peer *tmpaddr,tmp; char ipaddr[65];
if ( coin->peers == 0 )
return(0);
sendlen = 0;
max = (IGUANA_MINPEERS + IGUANA_MAXPEERS) / 2;
if ( max > coin->peers->numranked )

4
iguana/iguana_blocks.c

@ -535,10 +535,6 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl
bits256 *hash2p=0; double prevPoW = 0.; struct iguana_bundle *bp;
if ( newblock == 0 )
return(0);
if ( coin->virtualchain != 0 )
{
;
}
iguana_blocksizecheck("chainlink new",coin->chain->zcash,newblock);
hwmchain = (struct iguana_block *)&coin->blocks.hwmchain;
if ( 0 && hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize > bp->hdrsi+0*bp->isRT) )

25
iguana/iguana_bundles.c

@ -458,7 +458,7 @@ void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp)
if ( coin->current != 0 )
lasti = coin->current->hdrsi;
else lasti = 0;
if ( bp->purgetime == 0 && time(NULL) > bp->emitfinish+600 && bp->hdrsi < lasti-2 )
if ( coin->virtualchain != 0 || (bp->purgetime == 0 && time(NULL) > bp->emitfinish+600 && bp->hdrsi < lasti-2) )
{
for (j=m=0; j<bp->n; j++)
{
@ -469,7 +469,11 @@ void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp)
//printf("purge.(%s)\n",fname);
fclose(fp);
if ( OS_removefile(fname,0) > 0 )
coin->peers->numfiles--, m++;
{
if ( coin->peers != 0 )
coin->peers->numfiles--;
m++;
}
}
}
else printf("error removing.(%s)\n",fname);
@ -496,7 +500,10 @@ void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp)
uint8_t iguana_recentpeers(struct iguana_info *coin,int32_t *capacityp,struct iguana_peer *peers[])
{
struct iguana_peer *addr; uint8_t m; int32_t capacity,i,n = coin->peers->numranked;
struct iguana_peer *addr; uint8_t m; int32_t capacity,i,n;
if ( coin->peers == 0 )
return(0);
n = coin->peers->numranked;
for (i=m=capacity=0; i<n&&m<0xff; i++)
{
if ( (addr= coin->peers->ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 && addr->pendblocks < coin->MAXPENDINGREQUESTS )
@ -580,6 +587,8 @@ struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p
int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult)
{
int32_t i,max,nonz,starti,lasti,firsti,lag,num,n=0; uint32_t now; bits256 hash2; double aveduration; struct iguana_peer *addr;
if ( coin->peers == 0 )
return(0);
starti = coin->current == 0 ? 0 : coin->current->hdrsi;
lasti = coin->lastpending == 0 ? starti+coin->MAXBUNDLES : coin->lastpending->hdrsi;
if ( bp->hdrsi < starti || bp->hdrsi > lasti || bp->emitfinish != 0 || ((priority > 0 || bp == coin->current) && time(NULL) < bp->missingstime+3) || time(NULL) < bp->missingstime+30 )
@ -820,7 +829,6 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int
}
}
}
printf("ready.%d\n",ready);
return(ready);
}
@ -1010,7 +1018,7 @@ int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp,
}
else
{
//fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d error\n",coin,bp->hdrsi,bp->bundleheight);
fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d error\n",coin,bp->hdrsi,bp->bundleheight);
bp->emitfinish = 0;
}
coin->emitbusy--;
@ -1057,7 +1065,7 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru
iguana_bundlehdr(coin,bp,starti);
else if ( bp->emitfinish == 0 && bp->numsaved >= bp->n )
{
if ( iguana_bundlefinalize(coin,bp,mem,memB) > 0 )
if ( coin->virtualchain != 0 || iguana_bundlefinalize(coin,bp,mem,memB) > 0 )
return(0);
//else printf("bundlefinalize not done.[%d]\n",bp->hdrsi);
retval = 1;
@ -1125,6 +1133,8 @@ int32_t iguana_cacheprocess(struct iguana_info *coin,struct iguana_bundle *bp,in
void iguana_unstickhdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag)
{
int32_t datalen,m,i; uint8_t serialized[512]; char str[65]; struct iguana_peer *addr;
if ( coin->peers == 0 )
return;
if ( (m= coin->peers->numranked) > 0 && bp->numhashes < bp->n && bp->hdrsi < coin->longestchain/coin->chain->bundlesize && time(NULL) > bp->unsticktime+lag )
{
for (i=0; i<10; i++)
@ -1316,9 +1326,12 @@ void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag)
coin->numremain = n;
coin->blocksrecv = numrecv;
uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now();
if ( coin->peers != 0 )
{
for (i=0; i<IGUANA_MAXPEERS; i++)
if ( coin->peers->active[i].usock > 0 )
p++;
}
diff = (int32_t)time(NULL) - coin->startutc;
difft.x = (t.x - coin->starttime.x), difft.millis = (t.millis - coin->starttime.millis);
tmp = (difft.millis * 1000000);

6
iguana/iguana_chains.c

@ -338,6 +338,12 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson)
chain->targettimespan = NTARGETSPACING * 60;
if ( (port= extract_userpass(chain->serverport,chain->userpass,chain->symbol,chain->userhome,path,conf)) != 0 )
chain->rpcport = port;
if ( jobj(argjson,"halving") != 0 )
chain->halvingduration = juint(argjson,"halving");
else chain->halvingduration = 210000;
if ( jobj(argjson,"reward") != 0 )
chain->initialreward = jdouble(argjson,"reward") * SATOSHIDEN;
else chain->initialreward = 50 * SATOSHIDEN;
if ( chain->serverport[0] == 0 )
sprintf(chain->serverport,"127.0.0.1:%u",chain->rpcport);
if ( (hexstr= jstr(argjson,"pubval")) != 0 && strlen(hexstr) == 2 )

29
iguana/iguana_init.c

@ -36,7 +36,7 @@ void iguana_initQs(struct iguana_info *coin)
iguana_initQ(&coin->msgrequestQ,"msgrequestQ");
iguana_initQ(&coin->cacheQ,"cacheQ");
iguana_initQ(&coin->recvQ,"recvQ");
if ( coin->MAXPEERS > 0 )
if ( coin->MAXPEERS > 0 && coin->peers != 0 )
{
for (i=0; i<IGUANA_MAXPEERS; i++)
iguana_initQ(&coin->peers->active[i].sendQ,"addrsendQ");
@ -76,7 +76,7 @@ void iguana_initcoin(struct iguana_info *coin,cJSON *argjson)
coin->startmillis = OS_milliseconds(), coin->starttime = tai_now();
coin->avetime = 1 * 100;
//coin->R.maxrecvbundles = IGUANA_INITIALBUNDLES;
if ( coin->MAXPEERS > 0 )
if ( coin->MAXPEERS > 0 && coin->peers != 0 )
{
for (i=0; i<IGUANA_MAXPEERS; i++)
coin->peers->active[i].usock = -1;
@ -315,12 +315,15 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp)
if ( line[k] == ' ' )
{
decode_hex(hash2.bytes,sizeof(hash2),line+k+1);
//printf("line.(%s) k.%d (%c)(%c)(%d)\n",line,k,line[k+63],line[k+64],line[k+65]);
if ( coin->virtualchain != 0 )
printf("line.(%s) k.%d (%c)(%c)(%d)\n",line,k,line[k+63],line[k+64],line[k+65]);
if ( height >= 0 && bits256_nonz(hash2) != 0 )
{
if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,zero,0)) != 0 )
{
//printf("created bundle.%d\n",bp->hdrsi);
memset(hash1.bytes,0,sizeof(hash1));
iguana_bundleinitmap(coin,bp,height,hash2,hash1);
lastbundle = hash2;
}
}
@ -337,7 +340,9 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp)
if ( strlen(line+k+1 + 2*64 + 2) == sizeof(hash1)*2 )
decode_hex(hash1.bytes,sizeof(hash1),line+k+1 + 2*64 + 2);
else memset(hash1.bytes,0,sizeof(hash1));
//char str[65],str2[65]; printf(">>>> bundle.%d got (%s)/(%s) allhash.(%s)\n",height,bits256_str(str,hash1),checkstr,bits256_str(str2,allhash));
if ( coin->virtualchain != 0 )
memset(hash1.bytes,0,sizeof(hash1));
//char str[65],str2[65]; printf(">>>> %s bundle.%d last.%d got (%s)/(%s) allhash.(%s)\n",coin->symbol,height,lastheight,bits256_str(str,hash1),checkstr,bits256_str(str2,allhash));
if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,allhash,0)) != 0 )
{
if ( bits256_cmp(allhash,bp->allhash) != 0 )
@ -364,6 +369,20 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp)
}
}
long iguana_bundlesload(struct supernet_info *myinfo,struct iguana_info *coin)
{
char fname[1024]; int32_t iter = 1; FILE *fp; long fpos = -1;
sprintf(fname,"%s/%s_%s.txt",GLOBAL_CONFSDIR,coin->symbol,(iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname);
if ( (fp= fopen(fname,"r")) != 0 )
{
iguana_parseline(coin,iter,fp);
printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos);
fpos = ftell(fp);
fclose(fp);
}
return(fpos);
}
void iguana_ramchainpurge(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain)
{
iguana_ramchain_free(coin,ramchain,1);
@ -489,7 +508,7 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei
coin->blocks.hwmchain.height = 0;
coin->blocks.hwmchain.RO.allocsize = coin->chain->zcash != 0 ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block);
printf("%s MYSERVICES.%llx\n",coin->symbol,(long long)coin->myservices);
if ( coin->virtualchain == 0 )
if ( coin->virtualchain == 0 && coin->peers != 0 )
{
if ( (coin->myservices & NODE_NETWORK) != 0 )
{

20
iguana/iguana_instantdex.c

@ -389,11 +389,7 @@ bits256 instantdex_rwoffer(int32_t rwflag,int32_t *lenp,uint8_t *serialized,stru
char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extraser,int32_t extralen,struct iguana_peer *addr,struct bitcoin_swapinfo *swap)
{
cJSON *sendjson; char *reqstr; struct instantdex_msghdr *msg; bits256 orderhash,tmphash; int32_t i,j,len,dir=0,serflag,olen,slen,datalen; uint8_t *buf,*allocptr,space[4096],serialized[sizeof(*offer) + sizeof(struct iguana_msghdr) + 4096 + INSTANTDEX_DECKSIZE*33]; uint64_t x,nxt64bits; //,*hexstr,*retstr
//if ( strcmp(cmdstr,"poll") == 0 )
// return(clonestr("{\"result\":\"skip sending poll\"}"));
//category_subscribe(myinfo,myinfo->instantdex_category,GENESIS_PUBKEY);
cJSON *sendjson; char *reqstr; struct instantdex_msghdr *msg; bits256 orderhash,tmphash; int32_t i,j,len,dir=0,serflag,olen,slen,datalen; uint8_t *buf,*allocptr,space[4096],serialized[sizeof(*offer) + sizeof(struct iguana_msghdr) + 4096 + INSTANTDEX_DECKSIZE*33]; uint64_t x,nxt64bits;
orderhash = instantdex_rwoffer(1,&olen,serialized,offer);
if ( 1 )
{
@ -422,7 +418,6 @@ char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *o
extralen = (int32_t)sizeof(swap->privkeys);
serflag = 2;
} else serflag = 0;
printf("serflag.%d\n",serflag);
datalen = (int32_t)slen + extralen + olen;
msg = calloc(1,datalen + sizeof(*msg));
for (i=0; i<sizeof(msg->cmd); i++)
@ -452,9 +447,6 @@ char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *o
memcpy(&tmphash,&((uint8_t *)extraser)[len],sizeof(tmphash));
for (j=0; j<32; j++)
((uint8_t *)extraser)[len++] = tmphash.bytes[j];
//iguana_rwbignum(1,&((uint8_t *)extraser)[len],sizeof(bits256),tmphash.bytes);
//if ( len == 0 )
// printf("ser privkeys0 %s\n",bits256_str(str,*(bits256 *)extraser));
len += sizeof(bits256);
}
}
@ -466,12 +458,12 @@ char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *o
sendjson = cJSON_CreateObject();
jaddstr(sendjson,"hexmsg",(char *)buf);
free(buf);
//jaddstr(sendjson,"agent","SuperNET");
//jaddstr(sendjson,"method","DHT");
//jaddnum(sendjson,"plaintext",1);
//jaddbits256(sendjson,"categoryhash",myinfo->instantdex_category);
jaddstr(sendjson,"cmd",cmdstr);
jaddstr(sendjson,"agent","SuperNET");
jaddstr(sendjson,"method","DHT");
jaddstr(sendjson,"handle",myinfo->handle);
jaddnum(sendjson,"plaintext",1);
jaddbits256(sendjson,"categoryhash",myinfo->instantdex_category);
jaddbits256(sendjson,"traderpub",myinfo->myaddr.persistent);
data = basilisk_jsondata(&allocptr,space,sizeof(space),&datalen,swap->mine.offer.base,sendjson,basilisktag);
basilisk_sendcmd(myinfo,addr->ipaddr,dir > 0 ? "BID" : "ASK",&basilisktag,encryptflag,delaymillis,data,datalen,1,BASILISK_DEFAULTDIFF);
@ -1078,7 +1070,7 @@ void instantdex_propagate(struct supernet_info *myinfo,struct exchange_info *exc
{
bits256 orderhash; uint8_t serialized[8192]; int32_t i,len; struct iguana_peer *addr; struct iguana_info *coin;
orderhash = instantdex_rwoffer(1,&len,&serialized[sizeof(struct iguana_msghdr)],&ap->offer);
if ( (coin= iguana_coinfind("BTCD")) != 0 && coin->peers->numranked > 0 )
if ( (coin= iguana_coinfind("BTCD")) != 0 && coin->peers != 0 && coin->peers->numranked > 0 )
{
for (i=0; i<coin->peers->numranked; i++)
if ( (addr= coin->peers->ranked[i]) != 0 && addr->supernet != 0 && addr->usock >= 0 && GETBIT(ap->peerhas,addr->addrind) == 0 && strcmp("0.0.0.0",addr->ipaddr) != 0 && strcmp("127.0.0.1",addr->ipaddr) != 0 )

14
iguana/iguana_json.c

@ -555,7 +555,7 @@ cJSON *iguana_peerjson(struct iguana_info *coin,struct iguana_peer *addr)
cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly)
{
cJSON *retjson,*array; int32_t i; struct iguana_peer *addr;
if ( coin == 0 )
if ( coin == 0 || coin->peers == 0 )
return(0);
array = cJSON_CreateArray();
for (i=0; i<coin->MAXPEERS; i++)
@ -591,7 +591,7 @@ STRING_ARG(iguana,peers,activecoin)
STRING_ARG(iguana,getconnectioncount,activecoin)
{
int32_t i,num = 0; char buf[512];
if ( coin != 0 )
if ( coin != 0 && coin->peers == 0 )
{
for (i=0; i<sizeof(coin->peers->active)/sizeof(*coin->peers->active); i++)
if ( coin->peers->active[i].usock >= 0 )
@ -661,7 +661,7 @@ TWO_STRINGS(iguana,addnode,activecoin,ipaddr)
if ( coin == 0 )
coin = iguana_coinfind(activecoin);
printf("coin.%p.[%s] addnode.%s -> %s\n",coin,coin!=0?coin->symbol:"",activecoin,ipaddr);
if ( coin != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 )
if ( coin != 0 && coin->peers != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 )
{
//iguana_possible_peer(coin,ipaddr);
if ( (addr= iguana_peerslot(coin,(uint32_t)calc_ipbits(ipaddr),1)) != 0 )
@ -705,7 +705,7 @@ TWO_STRINGS(iguana,addnode,activecoin,ipaddr)
TWO_STRINGS(iguana,persistent,activecoin,ipaddr)
{
int32_t i;
if ( coin != 0 && ipaddr != 0 )
if ( coin != 0 && coin->peers != 0 && ipaddr != 0 )
{
for (i=0; i<IGUANA_MAXPEERS; i++)
{
@ -722,7 +722,7 @@ TWO_STRINGS(iguana,persistent,activecoin,ipaddr)
TWO_STRINGS(iguana,removenode,activecoin,ipaddr)
{
int32_t i;
if ( coin != 0 && ipaddr != 0 )
if ( coin != 0 && coin->peers != 0 && ipaddr != 0 )
{
for (i=0; i<IGUANA_MAXPEERS; i++)
{
@ -749,7 +749,7 @@ TWO_STRINGS(iguana,oneshot,activecoin,ipaddr)
TWO_STRINGS(iguana,nodestatus,activecoin,ipaddr)
{
int32_t i; struct iguana_peer *addr;
if ( coin != 0 && ipaddr != 0 )
if ( coin != 0 && coin->peers != 0 && ipaddr != 0 )
{
for (i=0; i<coin->MAXPEERS; i++)
{
@ -764,7 +764,7 @@ TWO_STRINGS(iguana,nodestatus,activecoin,ipaddr)
STRING_AND_INT(iguana,maxpeers,activecoin,max)
{
cJSON *retjson; int32_t i; struct iguana_peer *addr;
if ( coin != 0 )
if ( coin != 0 && coin->peers != 0 )
{
retjson = cJSON_CreateObject();
if ( max > IGUANA_MAXPEERS )

23
iguana/iguana_payments.c

@ -300,20 +300,28 @@ char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,bit
bits256 iguana_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx)
{
bits256 txid; uint8_t *serialized; int32_t i,len; struct iguana_peer *addr;
if ( coin->peers->numranked >= 8 )
{
bits256 txid; uint8_t *serialized; int32_t i,len,n; struct iguana_peer *addr; cJSON *vals; char *str;
len = (int32_t)strlen(signedtx) >> 1;
serialized = calloc(1,sizeof(struct iguana_msghdr) + len);
decode_hex(&serialized[sizeof(struct iguana_msghdr)],len,signedtx);
for (i=0; i<8; i++)
txid = bits256_doublesha256(0,&serialized[sizeof(struct iguana_msghdr)],len);
if ( coin->peers != 0 && (n= coin->peers->numranked) > 0 )
{
for (i=0; i<8 && i<n; i++)
{
if ( (addr= coin->peers->ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 )
iguana_queue_send(addr,0,serialized,"tx",len);
}
}
else
{
vals = cJSON_CreateObject();
jaddstr(vals,"symbol",coin->symbol);
if ( (str= gecko_sendrawtransaction(myinfo,coin,serialized,len,txid,vals,signedtx)) != 0 )
free(str);
free_json(vals);
}
free(serialized);
txid = bits256_doublesha256(0,&serialized[sizeof(struct iguana_msghdr)],len);
} else memset(txid.bytes,0,sizeof(txid));
return(txid);
}
@ -633,9 +641,6 @@ HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool)
U = RAMCHAIN_PTR(rdata,Uoffset);
P = RAMCHAIN_PTR(rdata,Poffset);
T = RAMCHAIN_PTR(rdata,Toffset);
//U = (void *)(long)((long)rdata + rdata->Uoffset);
//P = (void *)(long)((long)rdata + rdata->Poffset);
//T = (void *)(long)((long)rdata + rdata->Toffset);
RTspend = 0;
if ( iguana_spentflag(coin,&RTspend,&spentheight,ramchain,bp->hdrsi,unspentind,height,minconf,coin->longestchain,U[unspentind].value) == 0 )
{

35
iguana/iguana_peers.c

@ -297,7 +297,7 @@ void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t mar
strcpy(ipaddr,addr->ipaddr);
if ( addr->usock >= 0 )
closesocket(addr->usock), addr->usock = -1;
if ( addr == coin->peers->localaddr )
if ( coin->peers != 0 && addr == coin->peers->localaddr )
coin->peers->localaddr = 0;
//printf("iAkill.(%s)\n",addr->ipaddr);
if ( (iA= iguana_iAddrhashfind(coin,addr->ipbits,1)) != 0 )
@ -417,7 +417,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port)
int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t len)
{
int32_t numsent,remains,usock,r,i; char *cmdstr = (char *)&serialized[4];
if ( addr == 0 )
if ( addr == 0 && coin->peers != 0 )
{
r = rand();
for (i=0; i<IGUANA_MAXPEERS; i++)
@ -450,7 +450,7 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s
printf("sending too big! %d\n",len);
while ( remains > 0 )
{
if ( coin->peers->shuttingdown != 0 )
if ( coin->peers != 0 && coin->peers->shuttingdown != 0 )
return(-1);
if ( (numsent= (int32_t)send(usock,serialized,remains,MSG_NOSIGNAL)) < 0 )
{
@ -575,12 +575,12 @@ void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct ig
void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_peer *addr,uint8_t *_buf,int32_t maxlen)
{
int32_t len,recvlen; void *buf = _buf; struct iguana_msghdr H;
if ( coin->peers->shuttingdown != 0 || addr->dead != 0 )
if ( (coin->peers != 0 && coin->peers->shuttingdown != 0) || addr->dead != 0 )
return;
memset(&H,0,sizeof(H));
if ( (recvlen= (int32_t)iguana_recv(addr->ipaddr,usock,(uint8_t *)&H,sizeof(H))) == sizeof(H) )
{
if ( coin->peers->shuttingdown != 0 || addr->dead != 0 )
if ( (coin->peers != 0 && coin->peers->shuttingdown != 0) || addr->dead != 0 )
return;
{
iguana_rwnum(0,H.serdatalen,sizeof(H.serdatalen),(uint32_t *)&len);
@ -654,7 +654,7 @@ void iguana_startconnection(void *arg)
printf("iguana_startconnection nullptrs addr.%p (%s) coin.%p\n",addr,addr!=0?addr->symbol:"",coin);
return;
}
if ( coin->virtualchain != 0 )
if ( coin->virtualchain != 0 || coin->peers == 0 )
return;
addr->addrind = (int32_t)(((long)addr - (long)&coin->peers->active[0]) / sizeof(*addr));
if ( addr->usock >= 0 )
@ -680,7 +680,7 @@ void iguana_startconnection(void *arg)
port = coin->chain->portp2p;
if ( addr->usock < 0 )
addr->usock = iguana_socket(0,addr->ipaddr,port);
if ( addr->usock < 0 || coin->peers->shuttingdown != 0 )
if ( addr->usock < 0 || (coin->peers != 0 && coin->peers->shuttingdown != 0) )
{
strcpy(ipaddr,addr->ipaddr);
//printf("%s refused PEER KILLED. slot.%d for %s:%d usock.%d\n",coin->symbol,addr->addrind,ipaddr,coin->chain->portp2p,addr->usock);
@ -695,17 +695,20 @@ void iguana_startconnection(void *arg)
addr->height = iguana_iAddrheight(coin,addr->ipbits);
strcpy(addr->symbol,coin->symbol);
strcpy(addr->coinname,coin->name);
if ( coin->peers != 0 )
{
coin->peers->lastpeer = (uint32_t)time(NULL);
for (i=n=0; i<coin->MAXPEERS; i++)
if ( coin->peers->active[i].usock > 0 )
n++;
iguana_iAconnected(coin,addr);
coin->peers->numconnected++;
//printf("%s.PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->symbol,coin->peers->numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock);
if ( strcmp("127.0.0.1",addr->ipaddr) == 0 )
coin->peers->localaddr = addr;
else if ( coin->peers->numranked == 0 )
coin->peers->ranked[0] = addr;
} else n = 0;
iguana_iAconnected(coin,addr);
//printf("%s.PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->symbol,coin->peers->numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock);
#ifdef IGUANA_DEDICATED_THREADS
//iguana_launch("recv",iguana_dedicatedrecv,addr,IGUANA_RECVTHREAD);
iguana_dedicatedloop(SuperNET_MYINFO(0),coin,addr);
@ -716,7 +719,7 @@ void iguana_startconnection(void *arg)
void iguana_peerkill(struct iguana_info *coin)
{
struct iguana_peer *addr;
if ( coin->virtualchain != 0 )
if ( coin->virtualchain != 0 || coin->peers == 0 )
return;
if ( coin->peers->numranked > 0 && (addr= coin->peers->ranked[coin->peers->numranked-1]) != 0 )
{
@ -728,7 +731,7 @@ void iguana_peerkill(struct iguana_info *coin)
struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int32_t forceflag)
{
int32_t i; struct iguana_peer *addr; char ipaddr[64];
if ( coin->virtualchain != 0 )
if ( coin->virtualchain != 0 || coin->peers == 0 )
return(0);
for (i=0; i<IGUANA_MAXPEERS; i++)
if ( (uint32_t)ipbits == (uint32_t)coin->peers->active[i].ipbits )
@ -817,9 +820,9 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA)
uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr)
{
char checkaddr[64]; uint64_t ipbits; uint32_t now = (uint32_t)time(NULL); int32_t i,n; struct iguana_iAddr *iA;
if ( coin->virtualchain != 0 )
if ( coin->virtualchain != 0 || coin->peers == 0 )
return(0);
if ( ipaddr != 0 && ipaddr[0] != 0 )
if ( ipaddr != 0 && ipaddr[0] != 0 && coin->peers != 0 )
{
if ( strcmp(ipaddr,"0.0.0.0") == 0 || strcmp(ipaddr,"127.0.0.1") == 0 )
return(0);
@ -938,7 +941,7 @@ int32_t iguana_pollrecv(struct iguana_info *coin,struct iguana_peer *addr,uint8_
{
#ifndef IGUANA_DEDICATED_THREADS
strcpy(addr->symbol,coin->symbol);
if ( addr != coin->peers->localaddr )
if ( coin->peers != 0 && addr != coin->peers->localaddr )
{
addr->startrecv = (uint32_t)time(NULL);
iguana_launch("processmsg",iguana_processmsg,addr,IGUANA_RECVTHREAD);
@ -1105,7 +1108,7 @@ void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin,
//static uint32_t lastping;
struct pollfd fds; struct iguana_bundlereq *req; uint8_t *buf; uint32_t ipbits;
int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout;
if ( coin->virtualchain != 0 )
if ( coin->virtualchain != 0 || coin->peers == 0 )
return;
if ( iguana_peerslotinit(coin,addr,(int32_t)(((long)addr - (long)&coin->peers->active[0]) / sizeof(*addr)),calc_ipbits(addr->ipaddr)) < 0 )
{
@ -1295,7 +1298,7 @@ void iguana_peersloop(void *ptr)
memset(fds,0,sizeof(fds));
memset(bufs,0,sizeof(bufs));
memset(bufsizes,0,sizeof(bufsizes));
while ( 1 )
while ( coin->peers != 0 )
{
while ( coin->peers->shuttingdown != 0 )
{

10
iguana/iguana_ramchain.c

@ -101,8 +101,8 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,
bp = 0, bundlei = -2;
if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 )
{
//if ( 0 && dispflag != 0 )
printf("iguana_peerfname error finding.(%s) spec.%p bp.%p\n",bits256_str(str,hash2),bp!=0?bp->speculative:0,bp);
if ( 0 && dispflag != 0 )
printf("iguana_peerfname %s error finding.(%s) spec.%p bp.%p\n",coin->symbol,bits256_str(str,hash2),bp!=0?bp->speculative:0,bp);
return(-2);
}
else bundlei++;
@ -332,7 +332,9 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee
#ifdef __PNACL__
//portable_mutex_unlock(&mutex);
#endif
} else printf("addr.%p unspent error fp.%p\n",addr,addr!=0?addr->voutsfp:0);
}
else
printf("addr.%p unspent error fp.%p\n",addr,addr!=0?addr->voutsfp:0);
}
}
u->txidind = ramchain->H.txidind;
@ -2276,7 +2278,7 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana
if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,extraflag,1)) != 0 )
{
iguana_ramchain_link(mapchain,bp->hashes[0],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,1);
//char str[65]; printf("bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",bp->hdrsi,mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,mbstr(str,mapchain->H.data->allocsize),mapchain->H.data);
//char str[65]; printf("%s bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",coin->symbol,bp->hdrsi,mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,mbstr(str,mapchain->H.data->allocsize),mapchain->H.data);
//ramcoder_test(mapchain->H.data,mapchain->H.data->allocsize);
if ( (rdata= ramchain->H.data) != 0 )
{

4
iguana/iguana_realtime.c

@ -139,6 +139,8 @@ void iguana_rdatarestore(struct iguana_ramchain *dest,struct iguana_ramchaindata
void iguana_RThdrs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t numaddrs)
{
int32_t datalen,i; uint8_t serialized[512]; char str[65]; struct iguana_peer *addr;
if ( coin->peers == 0 )
return;
for (i=0; i<numaddrs && i<coin->peers->numranked; i++)
{
queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1);
@ -205,6 +207,8 @@ int32_t iguana_realtime_update(struct iguana_info *coin)
double startmillis0; static double totalmillis0; static int32_t num0;
struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t offset,bundlei,i,n,flag=0; bits256 hash2,*ptr; struct iguana_peer *addr;
struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR;
if ( coin->peers == 0 )
return(0);
offset = (strcmp("BTC",coin->symbol) != 0);
if ( coin->current != 0 && (coin->blocks.hwmchain.height % coin->chain->bundlesize) == coin->chain->bundlesize-1 && coin->blocks.hwmchain.height/coin->chain->bundlesize == coin->longestchain/coin->chain->bundlesize )
{

14
iguana/iguana_recv.c

@ -121,7 +121,7 @@ int32_t iguana_sendtxidreq(struct iguana_info *coin,struct iguana_peer *addr,bit
int32_t len,i,r,j; //char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2));
if ( (len= iguana_getdata(coin,serialized,MSG_TX,&hash2,1)) > 0 )
{
if ( addr == 0 )
if ( addr == 0 && coin->peers != 0 )
{
r = rand();
for (i=0; i<coin->MAXPEERS; i++)
@ -150,9 +150,12 @@ int32_t iguana_txidreq(struct iguana_info *coin,char **retstrp,bits256 txid)
}
char str[65]; printf("txidreq.%s\n",bits256_str(str,txid));
coin->reqtxids[coin->numreqtxids++] = txid;
if ( coin->peers != 0 )
{
for (i=0; i<coin->MAXPEERS; i++)
if ( coin->peers->active[i].usock >= 0 )
iguana_sendtxidreq(coin,coin->peers->ranked[i],txid);
}
return(0);
}
@ -779,6 +782,8 @@ void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,
coin->badlongestchain = coin->longestchain;
coin->longestchain = bp->bundleheight+num;
coin->longestchain_strange = 0;
if ( coin->peers != 0 )
{
for (i=0; i<coin->peers->numranked; i++)
if ( (addr= coin->peers->ranked[i]) != 0 && addr->height >= coin->badlongestchain )
{
@ -788,6 +793,7 @@ void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,
}
}
}
}
else if ( coin->longestchain_strange > 0 )
{
printf("not strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n);
@ -1504,7 +1510,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle
if ( (n= queue_size(Q)) > 100000 )
{
if ( 1 && n > 200000 )
printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers->numranked,queue_size(Q));
printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers != 0 ? coin->peers->numranked : -1,queue_size(Q));
while ( (ptr= queue_dequeue(Q,0)) != 0 )
myfree(ptr,sizeof(*ptr));
coin->backlog = n*10 + 1000000;
@ -1584,15 +1590,19 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr)
return(0);
}
priority = 1;
pend = 0;
req = queue_dequeue(&coin->priorityQ,0);
if ( flag == 0 && req == 0 && addr->pendblocks < limit )
{
priority = 0;
if ( coin->peers != 0 )
{
for (i=m=pend=0; i<coin->peers->numranked; i++)
{
if ( (ptr= coin->peers->ranked[i]) != 0 && ptr->msgcounts.verack > 0 )
pend += ptr->pendblocks, m++;
}
}
if ( pend < coin->MAXPENDINGREQUESTS*m )
req = queue_dequeue(&coin->blocksQ,0);
}

18
iguana/iguana_spendvectors.c

@ -705,7 +705,7 @@ int32_t iguana_volatilesinit(struct iguana_info *coin)
void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle)
{
int32_t i; struct iguana_bundle *bp; bits256 hash2; struct iguana_block *block; char hashstr[65];
int32_t i,hdrsi,bundlei,height; struct iguana_bundle *bp; bits256 hash2; struct iguana_block *block; char hashstr[65];
if ( bits256_nonz(lastbundle) > 0 )
{
init_hexbytes_noT(hashstr,lastbundle.bytes,sizeof(bits256));
@ -770,7 +770,20 @@ void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle)
iguana_walkchain(coin,0);
hash2 = iguana_blockhash(coin,coin->balanceswritten * coin->chain->bundlesize);
if ( bits256_nonz(hash2) != 0 && (block= iguana_blockfind("initfinal",coin,hash2)) != 0 )
_iguana_chainlink(coin,block);
{
for (height=0; height<coin->bundlescount*coin->chain->bundlesize; height++)
{
if ( _iguana_chainlink(coin,block) == 0 )
break;
if ( coin->virtualchain == 0 )
break;
bundlei = (height % coin->chain->bundlesize);
hdrsi = (height / coin->chain->bundlesize);
if ( (bp= coin->bundles[hdrsi]) == 0 || (block= bp->blocks[bundlei]) == 0 )
break;
}
printf("%s height.%d hwm.%d\n",coin->symbol,height,coin->blocks.hwmchain.height);
}
}
int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi)
@ -880,6 +893,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi)
{
coin->active = 0;
coin->started = 0;
if ( coin->peers != 0 )
for (i=0; i<IGUANA_MAXPEERS; i++)
coin->peers->active[i].dead = (uint32_t)time(NULL);
#ifdef __linux__

11
iguana/iguana_tx.c

@ -78,17 +78,16 @@ int32_t iguana_vinset(struct iguana_info *coin,uint8_t *scriptspace,int32_t heig
S = RAMCHAIN_PTR(rdata,Soffset);
X = RAMCHAIN_PTR(rdata,Xoffset);
T = RAMCHAIN_PTR(rdata,Toffset);
//S = (void *)(long)((long)rdata + rdata->Soffset);
//X = (void *)(long)((long)rdata + rdata->Xoffset);
//T = (void *)(long)((long)rdata + rdata->Toffset);
spendind = (tx->firstvin + i);
s = &S[spendind];
vin->sequence = s->sequenceid;
vin->prev_vout = s->prevout;
if ( s->prevout < 0 )
;
if ( s->scriptpos != 0 && s->scriptlen > 0 )
{
iguana_vinsfname(coin,bp->ramchain.from_ro,fname,s->fileid);
if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->peers->vinptrs[s->fileid],fname,s->scriptpos,s->scriptlen)) != s->scriptlen )
if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->vinptrs[s->fileid],fname,s->scriptpos,s->scriptlen)) != s->scriptlen )
printf("err.%d getting %d bytes from fileid.%llu[%d] %s for s%d\n",err,s->scriptlen,(long long)s->scriptpos,s->fileid,fname,spendind);
}
vin->scriptlen = s->scriptlen;
@ -107,7 +106,7 @@ int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint
if ( u->scriptpos > 0 && u->scriptlen > 0 )
{
iguana_voutsfname(coin,bp->ramchain.from_ro,fname,u->fileid);
if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->peers->voutptrs[u->fileid],fname,u->scriptpos,u->scriptlen)) != u->scriptlen )
if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->voutptrs[u->fileid],fname,u->scriptpos,u->scriptlen)) != u->scriptlen )
printf("%d bytes from fileid.%d[%d] %s for type.%d\n",u->scriptlen,u->fileid,u->scriptpos,fname,u->type);
}
else
@ -316,6 +315,8 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int
}
else
{
if ( coin->virtualchain != 0 )
;
if ( block != 0 )
printf("iguana_peerblockrequest: block.%p ht.%d mainchain.%d [%d:%d] from %s\n",block,block->height,block->mainchain,bp->hdrsi,bundlei,addr!=0?addr->ipaddr:"local");
else printf("iguana_peerblockrequest: block.%p [%d:%d]\n",block,bp->hdrsi,bundlei);

2
iguana/iguana_txidfind.c

@ -651,7 +651,7 @@ struct iguana_monitorinfo *iguana_txidmonitor(struct iguana_info *coin,bits256 t
double iguana_txidstatus(struct iguana_info *coin,bits256 txid)
{
int32_t height,firstvout,numranked; struct iguana_monitorinfo *ptr; char str[65];
if ( coin != 0 && (numranked= coin->peers->numranked) > 0 )
if ( coin != 0 && coin->peers != 0 && (numranked= coin->peers->numranked) > 0 )
{
if ( (firstvout= iguana_unspentindfind(coin,0,0,0,0,&height,txid,0,coin->bundlescount-1)) != 0 )
{

1
iguana/iguana_wallet.c

@ -958,6 +958,7 @@ ZERO_ARGS(bitcoinrpc,getinfo)
jaddnum(retjson,"blocks",coin->blocks.hwmchain.height);
jaddnum(retjson,"longestchain",coin->longestchain);
jaddnum(retjson,"port",coin->chain->portp2p);
if ( coin->peers != 0 )
jaddnum(retjson,"connections",coin->peers->numranked);
jaddnum(retjson,"difficulty",coin->blocks.hwmchain.PoW);
jaddstr(retjson,"status",coin->statusstr);

7
iguana/main.c

@ -321,6 +321,8 @@ void iguana_exit()
{
//portable_mutex_lock(&Allcoins_mutex);
HASH_ITER(hh,Allcoins,coin,tmp)
{
if ( coin->peers != 0 )
{
for (j=0; j<IGUANA_MAXPEERS; j++)
{
@ -334,6 +336,7 @@ void iguana_exit()
}
}
}
}
//portable_mutex_unlock(&Allcoins_mutex);
}
sleep(3);
@ -412,6 +415,7 @@ void mainloop(struct supernet_info *myinfo)
if ( coin->current != 0 && coin->active != 0 && coin->started != 0 )
{
isRT *= coin->isRT;
if ( coin->peers != 0 )
numpeers += coin->peers->numranked;
if ( time(NULL) > coin->startutc+10 && coin->spendvectorsaved == 0 && coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-coin->minconfirms)/coin->chain->bundlesize )
{
@ -1320,7 +1324,6 @@ void iguana_main(void *arg)
iguana_Qinit();
myinfo = SuperNET_MYINFO(0);
myinfo->rpcport = IGUANA_RPCPORT;
portable_mutex_init(&myinfo->allcoins_mutex);
strcpy(myinfo->rpcsymbol,"BTCD");
iguana_urlinit(myinfo,ismainnet,usessl);
//category_init(myinfo);
@ -1452,6 +1455,8 @@ cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs)
cJSON *SuperNET_peerarray(struct iguana_info *coin,int32_t max,int32_t supernetflag)
{
int32_t i,r,j,n = 0; struct iguana_peer *addr; cJSON *array = cJSON_CreateArray();
if ( coin->peers == 0 )
return(array);
r = rand();
for (j=0; j<IGUANA_MAXPEERS; j++)
{

2
iguana/tests/new

@ -1 +1 @@
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"newgeckochain\",\"vals\":{\"blocktime\":0,\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"}}"
curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"newgeckochain\",\"vals\":{\"RELAY\":1,\"blocktime\":0,\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"}}"

42
includes/iguana_apideclares.h

@ -18,27 +18,27 @@ INT_ARRAY_STRING(basilisk,balances,basilisktag,vals,activecoin);
INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin);
INT_ARRAY_STRING(basilisk,value,basilisktag,vals,activecoin);
INT_AND_ARRAY(basilisk,result,basilisktag,vals);
HASH_ARRAY_STRING(basilisk,geckogenesis,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,newgeckochain,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoheaders,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoblock,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckotx,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoget,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,addrelay,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,dispatch,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,publish,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,subscribe,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,forward,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,mailbox,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNcreate,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNjoin,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNmessage,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNbroadcast,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNreceive,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNlogout,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckogenesis,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,newgeckochain,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoget,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,publish,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,subscribe,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,forward,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,mailbox,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNjoin,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNmessage,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr);
HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr);
ZERO_ARGS(bitcoinrpc,getinfo);
ZERO_ARGS(bitcoinrpc,getblockcount);

6
includes/iguana_funcs.h

@ -125,7 +125,7 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,
// init
struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags);
void iguana_callcoinstart(struct iguana_info *coin);
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);
@ -502,6 +502,10 @@ char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr)
void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256);
int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block);
int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp,struct OS_memspace *mem,struct OS_memspace *memB);
bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V);
int32_t iguana_ROallocsize(struct iguana_info *virt);
long iguana_bundlesload(struct supernet_info *myinfo,struct iguana_info *coin);
void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin);
#include "../includes/iguana_api.h"

15
includes/iguana_structs.h

@ -44,7 +44,7 @@ struct iguana_chain
uint8_t genesis_hashdata[32],minconfirms;
uint16_t bundlesize,hasheaders;
char gethdrsmsg[16];
uint64_t txfee,minoutput,dust;
uint64_t txfee,minoutput,dust,halvingduration,initialreward;
blockhashfunc hashalgo;
char userhome[512],serverport[128],userpass[1024];
char use_addmultisig,do_opreturn;
@ -329,7 +329,6 @@ struct iguana_peers
struct iguana_peer active[IGUANA_MAXPEERS+1],*ranked[IGUANA_MAXPEERS+1],*localaddr;
struct iguana_thread *peersloop,*recvloop; pthread_t *acceptloop;
double topmetrics[IGUANA_MAXPEERS+1],avemetric;
long vinptrs[IGUANA_MAXPEERS+1][2],voutptrs[IGUANA_MAXPEERS+1][2];
uint32_t numranked,mostreceived,shuttingdown,lastpeer,lastmetrics,numconnected;
int32_t numfiles;
};
@ -383,7 +382,7 @@ struct iguana_info
struct iguana_peers *peers; struct iguana_peer internaladdr;
basilisk_func basilisk_rawtx,basilisk_balances,basilisk_value;
basilisk_metricfunc basilisk_rawtxmetric,basilisk_balancesmetric,basilisk_valuemetric;
long vinptrs[IGUANA_MAXPEERS+1][2],voutptrs[IGUANA_MAXPEERS+1][2];
uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100];
uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime;
int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles;
@ -406,7 +405,7 @@ struct iguana_info
int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified,blockdepth;
uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis,firstRTgenesis,RTstarti,idletime,stucktime,stuckmonitor,maxstuck,lastreqtime,RThdrstime,nextchecked;
double bandwidth,maxbandwidth,backstopmillis; bits256 backstophash2; int64_t spaceused;
int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids,allhashes,balanceflush; bits256 reqtxids[64];
int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids,allhashes,balanceflush,basilisk_busy; bits256 reqtxids[64];
void *launched,*started,*rpcloop;
uint64_t bloomsearches,bloomhits,bloomfalse,collisions,txfee_perkb,txfee;
uint8_t *blockspace; int32_t blockspacesize; struct OS_memspace blockMEM;
@ -415,7 +414,7 @@ struct iguana_info
double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num;
struct iguana_monitorinfo monitoring[256];
struct gecko_sequences SEQ;
struct iguana_blocks blocks;
struct iguana_blocks blocks; void *mempool;
};
struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
@ -458,15 +457,15 @@ struct supernet_info
uint8_t persistent_pubkey33[33];
char ipaddr[64],NXTAPIURL[512],secret[4096],rpcsymbol[64],handle[1024],permanentfile[1024];
char *decryptstr;
int32_t maxdelay,IAMRELAY,publicRPC;
int32_t maxdelay,IAMRELAY,publicRPC,basilisk_busy;
uint32_t expiration,dirty;
uint16_t argport,rpcport;
struct basilisk_info basilisks;
struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges;
struct iguana_waccount *wallet;
struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; portable_mutex_t allcoins_mutex;
struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts;
portable_mutex_t allcoins_mutex,gecko_mutex,basilisk_mutex;
void *ctx;
// compatibility
bits256 pangea_category,instantdex_category;
};

Loading…
Cancel
Save