Browse Source

geckochain initial alpha

release/v0.1
jl777 9 years ago
parent
commit
2fd423c96d
  1. 61
      basilisk/basilisk.c
  2. 3
      basilisk/basilisk.h
  3. 2
      basilisk/basilisk_bitcoin.c
  4. 133
      gecko/gecko.c
  5. 13
      gecko/gecko.h
  6. 119
      gecko/gecko_blocks.c
  7. 97
      gecko/gecko_miner.c
  8. 49
      iguana/iguana777.c
  9. 28
      iguana/iguana_accept.c
  10. 6
      iguana/iguana_bundles.c
  11. 24
      iguana/iguana_chains.c
  12. 8
      iguana/iguana_init.c
  13. 2
      iguana/iguana_json.c
  14. 7
      iguana/iguana_ramchain.c
  15. 3
      iguana/iguana_stake.c
  16. 2
      iguana/iguana_tx.c
  17. 2
      iguana/tests/new
  18. 7
      includes/iguana_apideclares.h
  19. 4
      includes/iguana_funcs.h

61
basilisk/basilisk.c

@ -262,11 +262,11 @@ int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *typ
return(n);
}
int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr)
int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2)
{
int32_t recvlen; uint8_t *data,space[16384],*allocptr;
if ( (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&recvlen,space,sizeof(space),blockstr)) != 0 )
gecko_blockarrived(myinfo,virt,&virt->internaladdr,data,recvlen);
gecko_blockarrived(myinfo,virt,"127.0.0.1",data,recvlen,hash2);
if ( allocptr != 0 )
free(allocptr);
return(recvlen);
@ -654,6 +654,7 @@ INT_AND_ARRAY(basilisk,result,basilisktag,vals)
ptr = calloc(1,sizeof(*ptr));
ptr->retstr = jprint(vals,0);
ptr->basilisktag = basilisktag;
strcpy(ptr->remoteaddr,remoteaddr);
printf("(%s) -> Q.%u results vals.(%s)\n",ptr->CMD,basilisktag,ptr->retstr);
queue_enqueue("resultsQ",&myinfo->basilisks.resultsQ,&ptr->DL,0);
return(clonestr("{\"result\":\"queued basilisk return\"}"));
@ -723,6 +724,36 @@ HASH_ARRAY_STRING(basilisk,VPNlogout,pubkey,vals,hexstr)
#include "../includes/iguana_apiundefs.h"
void basilisk_geckoresult(struct supernet_info *myinfo,struct basilisk_item *ptr)
{
uint8_t *data,space[16384],*allocptr = 0; struct iguana_info *virt; char *symbol,*str,*type; int32_t datalen; cJSON *retjson; bits256 hash2;
if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 )
{
if ( (symbol= jstr(retjson,"coin")) != 0 && (virt= iguana_coinfind(symbol)) != 0 )
{
if ( (data= get_dataptr(0,&allocptr,&datalen,space,sizeof(space),jstr(retjson,"data"))) != 0 )
{
str = 0;
if ( (type= jstr(retjson,"type")) != 0 )
{
hash2 = jbits256(retjson,"pubkey");
if ( strcmp(type,"HDR") == 0 )
str = gecko_headersarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2);
else if ( strcmp(type,"BLK") == 0 )
str = gecko_blockarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2);
else if ( strcmp(type,"GTX") == 0 )
str = gecko_txarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2);
}
if ( str != 0 )
free(str);
if ( allocptr != 0 )
free(allocptr);
}
}
free_json(retjson);
}
}
void basilisks_loop(void *arg)
{
basilisk_metricfunc metricfunc; struct iguana_info *btcd,*virt,*hhtmp; struct basilisk_item *ptr,*tmp,*pending,*parent; int32_t i,iter,maxmillis,done,flag,n; cJSON *valsobj,*retjson; uint32_t now; struct supernet_info *myinfo = arg;
@ -759,6 +790,9 @@ void basilisks_loop(void *arg)
free_json(retjson);
}
}
else if ( strcmp(ptr->CMD,"RET") == 0 )
{
}
}
}
free(ptr);
@ -860,13 +894,10 @@ void basilisks_loop(void *arg)
maxmillis = (1000 / myinfo->allcoins_numvirts) + 1;
//portable_mutex_lock(&Allcoins_mutex);
HASH_ITER(hh,myinfo->allcoins,virt,hhtmp)
{
if ( iguana_processrecv(myinfo,virt) == 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);
}
flag++;
}
//portable_mutex_unlock(&Allcoins_mutex);
@ -903,10 +934,12 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
// gecko chains
{ (void *)"NEW", &basilisk_respond_newgeckochain }, // creates new virtual gecko chain
{ (void *)"GEN", &basilisk_respond_geckogenesis }, // returns genesis list
{ (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx
{ (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers
{ (void *)"BLK", &basilisk_respond_geckoblock }, // reports block
{ (void *)"GTX", &basilisk_respond_geckotx }, // reports tx
{ (void *)"SEQ", &basilisk_respond_hashstamps }, // BTCD and BTC recent hashes from timestamp
{ (void *)"GTX", &basilisk_respond_geckotx },
{ (void *)"BLK", &basilisk_respond_geckoblock },
{ (void *)"GEN", &basilisk_respond_geckogenesis },
// unencrypted low level functions, used by higher level protocols and virtual network funcs
{ (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus
@ -993,7 +1026,11 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
}
if ( coin != 0 )
{
if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node
if ( strcmp(type,"RET") == 0 )
{
retstr = _basilisk_result(myinfo,coin,addr,remoteaddr,basilisktag,valsobj,data,datalen);
}
else if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node
{
for (i=0; i<sizeof(basilisk_coinservices)/sizeof(*basilisk_coinservices); i++)
if ( strcmp((char *)basilisk_coinservices[i][0],type) == 0 )
@ -1007,11 +1044,7 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
}
else // basilisk node
{
if ( strcmp(type,"RET") == 0 )
{
retstr = _basilisk_result(myinfo,coin,addr,remoteaddr,basilisktag,valsobj,data,datalen);
}
else if ( strcmp(type,"ADD") == 0 )
if ( strcmp(type,"ADD") == 0 )
{
printf("new relay ADD.(%s) datalen.%d\n",jprint(valsobj,0),datalen);
}

3
basilisk/basilisk.h

@ -33,7 +33,8 @@ struct basilisk_item
{
struct queueitem DL; UT_hash_handle hh; struct basilisk_item *parent; void *dependents;
uint32_t submit,finished,basilisktag,numresults,numsent,numexact,uniqueflag,numrequired,childrendone,numchildren,nBits;
char symbol[32],CMD[4]; double expiration; cJSON *vals; int32_t metricdir; void *metricfunc;
char symbol[32],CMD[4],remoteaddr[64];
double expiration; cJSON *vals; int32_t metricdir; void *metricfunc;
char *retstr,*results[BASILISK_MAXFANOUT]; double metrics[BASILISK_MAXFANOUT];
};

2
basilisk/basilisk_bitcoin.c

@ -209,7 +209,7 @@ int32_t basilisk_bitcoinscan(struct iguana_info *coin,uint8_t origblockspace[IGU
B.RO.prev_block = jbits256(blockjson,"previousblockhash");
B.RO.merkle_root = jbits256(blockjson,"merkleroot");
B.RO.timestamp = juint(blockjson,"time");
if ( (bitstr= jstr(blockjson,"bits")) != 0 )
if ( (bitstr= jstr(blockjson,"nBits")) != 0 )
{
decode_hex(revbits,sizeof(uint32_t),bitstr);
for (i=0; i<4; i++)

133
gecko/gecko.c

@ -157,7 +157,7 @@ cJSON *gecko_genesisargs(char *symbol,char *chainname,char *chain,char *keystr,c
jaddstr(argvals,"wifval",wifval);
if ( nbitstr == 0 || nbitstr[0] == 0 )
nbitstr = GECKO_DEFAULTDIFFSTR;
jaddstr(argvals,"nbits",nbitstr);
jaddstr(argvals,"nBits",nbitstr);
jaddstr(argvals,"chain",chain);
if ( keystr != 0 )
jaddstr(argvals,"key",keystr);
@ -172,7 +172,10 @@ cJSON *gecko_genesisargs(char *symbol,char *chainname,char *chain,char *keystr,c
{
jaddnum(argvals,"services",129);
jaddnum(argvals,"portp2p",port);
}
jaddnum(argvals,"blocktime",blocktime);
if ( blocktime != 0 )
{
if ( blocktime == 0xffff )
targetspacing = 24 * 60 * 60; // one day
else targetspacing = 60; // one minute
@ -184,10 +187,10 @@ cJSON *gecko_genesisargs(char *symbol,char *chainname,char *chain,char *keystr,c
return(argvals);
}
cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,char *symbol,char *chainname,cJSON *valsobj,char *magicstr)
cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,char *symbol,char *chainname,cJSON *valsobj,char *magicstr,uint16_t blocktime)
{
char str2[64],hashstr[65],argbuf[1024],*pubstr,*p2shstr,*wifvalstr,*nbitstr,*blockstr; uint8_t buf[4]; int32_t i; uint32_t nBits; struct iguana_block genesis; uint16_t blocktime;
if ( (nbitstr= jstr(valsobj,"nbits")) == 0 )
char str2[64],hashstr[65],argbuf[1024],*pubstr,*p2shstr,*wifvalstr,*nbitstr,*blockstr; uint8_t buf[4]; int32_t i; uint32_t nBits; struct iguana_block genesis;
if ( (nbitstr= jstr(valsobj,"nBits")) == 0 )
{
nBits = GECKO_DEFAULTDIFF;
nbitstr = GECKO_DEFAULTDIFFSTR;
@ -198,8 +201,7 @@ cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,i
decode_hex(&buf[3-i],1,&nbitstr[i*2]);
memcpy(&nBits,buf,sizeof(nBits));
}
if ( (blocktime= juint(valsobj,"blocktime")) == 0 )
blocktime = 60;
blocktime = juint(valsobj,"blocktime");
if ( (pubstr= jstr(valsobj,"pubval")) == 0 )
pubstr = "00";
if ( (p2shstr= jstr(valsobj,"p2shval")) == 0 )
@ -213,7 +215,7 @@ cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,i
if ( (blockstr= gecko_createblock(myinfo,btcd,isPoS,&genesis,symbol,0,0,0,10000)) != 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);
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);
free(blockstr);
//printf("argbuf.(%s) hash.%s\n",argbuf,hashstr);
return(cJSON_Parse(argbuf));
@ -222,8 +224,8 @@ cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,i
cJSON *gecko_genesisissue(char *symbol,char *chainname,char *chainstr,cJSON *valsobj)
{
//printf("issue isPoS.%d\n",juint(valsobj,"isPoS"));
return(gecko_genesisargs(symbol,chainname,chainstr,jstr(valsobj,"key"),jstr(valsobj,"genesishash"),jstr(valsobj,"genesisblock"),jstr(valsobj,"netmagic"),juint(valsobj,"port"),juint(valsobj,"blocktime"),jstr(valsobj,"nbits"),jstr(valsobj,"pubval"),jstr(valsobj,"p2shval"),jstr(valsobj,"wifval"),juint(valsobj,"isPoS")));
printf("issue blocktime.%d\n",juint(valsobj,"blocktime"));
return(gecko_genesisargs(symbol,chainname,chainstr,jstr(valsobj,"key"),jstr(valsobj,"genesishash"),jstr(valsobj,"genesisblock"),jstr(valsobj,"netmagic"),juint(valsobj,"port"),juint(valsobj,"blocktime"),jstr(valsobj,"nBits"),jstr(valsobj,"pubval"),jstr(valsobj,"p2shval"),jstr(valsobj,"wifval"),juint(valsobj,"isPoS")));
}
struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbol,char *chainname,cJSON *valsobj)
@ -245,8 +247,11 @@ struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbo
free(ptr);
virt->chain->genesis_hex = clonestr(hexstr);
virt->MAXPEERS = 0;
virt->virtualchain = 1;
addr = &virt->internaladdr;
iguana_initpeer(virt,addr,calc_ipbits("127.0.0.1"));
if ( addr->blockspace == 0 )
addr->blockspace = calloc(1,IGUANA_MAXPACKETSIZE + 8192);
if ( addr->RAWMEM.ptr == 0 )
iguana_meminit(&addr->RAWMEM,virt->symbol,0,IGUANA_MAXPACKETSIZE * 2,0);
if ( addr->TXDATA.ptr == 0 )
@ -352,6 +357,95 @@ char *basilisk_respond_geckogenesis(struct supernet_info *myinfo,char *CMD,void
return(OS_filestr(&filesize,"genesis/list"));
}
char *basilisk_standardreturn(char *CMD,char *type,struct iguana_info *virt,uint8_t *serialized,int32_t datalen)
{
char space[16384],*allocstr = 0; cJSON *retjson = cJSON_CreateObject();
if ( datalen > 0 && basilisk_addhexstr(&allocstr,retjson,space,sizeof(space),serialized,datalen) != 0 )
{
jaddstr(retjson,"CMD",CMD);
jaddstr(retjson,"type",type);
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);
}
else jaddstr(retjson,"error","no data to send");
if ( allocstr != 0 )
free(allocstr);
return(jprint(retjson,1));
}
int32_t basilisk_respond_geckogetheaders(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2)
{
int32_t i,n,num,height,len=0; struct iguana_block *block;
if ( (block= iguana_blockfind("geckohdr",virt,hash2)) != 0 )
{
if ( (height= block->height) >= 0 )
{
if ( (num= juint(valsobj,"num")) == 0 || num > virt->chain->bundlesize )
num = virt->chain->bundlesize;
for (i=0; i<num; i++)
{
if ( block != 0 )
{
if ( (n= iguana_headerget(virt,&serialized[len],maxsize-len,block)) > 0 )
len += n;
}
hash2 = iguana_blockhash(virt,height+i+1);
block = iguana_blockfind("geckohdri",virt,hash2);
}
return(len);
}
}
return(-1);
}
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
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
return(datalen);
}
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)
{
int32_t (*getfunc)(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2);
uint8_t *serialized; int32_t maxsize,len = 0; char *symbol,*type; struct iguana_info *virt;
if ( (type= jstr(valsobj,"type")) != 0 )
{
if ( strcmp(type,"HDR") == 0 )
getfunc = basilisk_respond_geckogetheaders;
else if ( strcmp(type,"BLK") == 0 )
getfunc = basilisk_respond_geckogetblock;
else if ( strcmp(type,"GTX") == 0 )
getfunc = basilisk_respond_geckogettx;
else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}"));
if ( (serialized= ((struct iguana_peer *)addr)->blockspace) == 0 )
return(clonestr("{\"error\":\"peer has no blockspace\"}"));
maxsize = IGUANA_MAXPACKETSIZE;
if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 )
{
datalen = (*getfunc)(myinfo,virt,serialized,maxsize,valsobj,hash2);
return(basilisk_standardreturn(CMD,type,virt,serialized,len));
} else return(clonestr("{\"error\":\"couldt find gecko chain\"}"));
} else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}"));
}
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 *symbol; struct iguana_info *virt;
if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 )
return(gecko_headersarrived(myinfo,virt,addr,data,datalen,hash2));
else return(clonestr("{\"error\":\"couldt find gecko chain\"}"));
}
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];
@ -362,7 +456,7 @@ char *basilisk_respond_geckotx(struct supernet_info *myinfo,char *CMD,void *addr
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)) != 0 )
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
@ -396,12 +490,12 @@ char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *a
if ( (symbol= jstr(valsobj,"coin")) != 0 && (virt= iguana_coinfind(symbol)) != 0 )
{
hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr);
nBits = gecko_nBits(virt,(struct iguana_block *)&virt->blocks.hwmchain);
nBits = gecko_nBits(virt,(struct iguana_block *)&virt->blocks.hwmchain,GECKO_DIFFITERS);
if ( gecko_blocknonce_verify(virt,data,hdrsize,nBits) == 0 )
{
iguana_rwblock(symbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&checkhash2,data,&msg,datalen);
if ( bits256_cmp(hash2,checkhash2) == 0 )
return(gecko_blockarrived(myinfo,virt,addr,data,datalen));
return(gecko_blockarrived(myinfo,virt,addr,data,datalen,hash2));
else return(clonestr("{\"error\":\"block error with checkhash2\"}"));
} else return(clonestr("{\"error\":\"block nonce didnt verify\"}"));
}
@ -436,7 +530,7 @@ HASH_ARRAY_STRING(basilisk,newgeckochain,pubkey,vals,hexstr)
if ( (isPoS= juint(vals,"isPoS")) == 0 )
isPoS = 1;
//printf("netmagic.%s\n",magicstr);
if ( (argjson= gecko_genesisjson(myinfo,btcd,isPoS,symbol,chainname,vals,magicstr)) != 0 )
if ( (argjson= gecko_genesisjson(myinfo,btcd,isPoS,symbol,chainname,vals,magicstr,juint(vals,"blocktime"))) != 0 )
{
argvals = gecko_genesisissue(symbol,chainname,chainstr,argjson);
if ( btcd->RELAYNODE != 0 || btcd->VALIDATENODE != 0 )
@ -488,8 +582,17 @@ HASH_ARRAY_STRING(basilisk,geckotx,pubkey,vals,hexstr)
HASH_ARRAY_STRING(basilisk,geckoblock,pubkey,vals,hexstr)
{
return(clonestr("{\"error\":\"geckoblock is an internal function\"}"));
//return(basilisk_standardservice("BLK",myinfo,pubkey,vals,hexstr,1));
return(clonestr("{\"error\":\"geckoblock is an internal reporting function\"}"));
}
HASH_ARRAY_STRING(basilisk,geckoheaders,pubkey,vals,hexstr)
{
return(clonestr("{\"error\":\"geckoheaders is an internal reporting function\"}"));
}
HASH_ARRAY_STRING(basilisk,geckoget,pubkey,vals,hexstr)
{
return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,pubkey,0));
}
HASH_ARRAY_STRING(basilisk,geckogenesis,pubkey,vals,hexstr)

13
gecko/gecko.h

@ -20,13 +20,15 @@
#define GECKO_MAXBTCDGAP 18
#define GECKO_DEFAULTVERSION 1
#define GECKO_DEFAULTDIFF 0x1fffffff
#define GECKO_DEFAULTDIFFSTR "1fffffff"
#define GECKO_EASIESTDIFF 0x1fffffff
#define GECKO_DEFAULTDIFF 0x1f00ffff
#define GECKO_DEFAULTDIFFSTR "1f00ffff"
#define GECKO_FIRSTPOSSIBLEBTC 414000
#define GECKO_FIRSTPOSSIBLEBTCD 1100000
#define GECKO_MAXNAMELEN 64
#define GECKO_MAXMINERITERS 10000000
#define GECKO_DIFFITERS 3
struct iguana_peer;
@ -48,11 +50,14 @@ char *basilisk_respond_hashstamps(struct supernet_info *myinfo,char *CMD,void *a
char *basilisk_respond_newgeckochain(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk);
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 prevhash,int32_t from_basilisk);
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 prevhash,int32_t from_basilisk);
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_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,struct iguana_peer *addr,uint8_t *data,int32_t datalen);
char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,uint8_t *data,int32_t datalen);
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);
#endif

119
gecko/gecko_blocks.c

@ -15,22 +15,125 @@
// included from gecko.c
char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,uint8_t *data,int32_t datalen)
char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2)
{
return(clonestr("{\"result\":\"gecko headers queued\"}"));
}
char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,uint8_t *data,int32_t datalen)
char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 txid)
{
struct iguana_txblock txdata; int32_t n,len = -1; struct iguana_msghdr H;
return(clonestr("{\"result\":\"gecko headers 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;
memset(zero.bytes,0,sizeof(zero));
for (iter=0; iter<2; iter++)
{
prev = block;
height = block->height;
for (i=0; i<depth; i++,height--)
{
if ( prev == 0 || height < 0 )
return(0);
bundlei = (height % virt->chain->bundlesize);
hdrsi = (height / virt->chain->bundlesize);
if ( iter == 1 )
{
if ( (bp= virt->bundles[hdrsi]) != 0 )
{
bp->blocks[bundlei] = prev;
bp->hashes[bundlei] = prev->RO.hash2;
}
else
{
printf("cant find bundle for ht.%d\n",height);
return(0);
}
}
else if ( bundlei == 0 && virt->bundles[hdrsi] == 0 )
iguana_bundlecreate(virt,&checkbundlei,height,prev->RO.hash2,zero,0);
prev = iguana_blockfind("geckoensure",virt,prev->RO.prev_block);
}
}
hdrsi = (block->height / virt->chain->bundlesize);
return(virt->bundles[hdrsi]);
}
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;
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);
memset(&txdata,0,sizeof(txdata));
addr = &virt->internaladdr;
if ( (n= iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,data,datalen)) == datalen )
{
memset(&H,0,sizeof(H));
iguana_gotblockM(virt,addr,&txdata,virt->TXMEM.ptr,&H,data,datalen);
return(clonestr("{\"result\":\"gecko block queued\"}"));
} else return(clonestr("{\"error\":\"gecko block didnt decode\"}"));
if ( bits256_cmp(hash2,txdata.zblock.RO.hash2) != 0 )
{
printf("gecko_blockarrived: mismatched hash2\n");
return(clonestr("{\"error\":\"gecko block hash2 mismatch\"}"));
}
txdata.zblock.RO.allocsize = sizeof(struct iguana_block);
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));
return(clonestr("{\"error\":\"gecko block didnt validate\"}"));
}
if ( (block= iguana_blockfind("geckoblock",virt,hash2)) == 0 )
{
if ( (block= iguana_blockhashset("geckoblock",virt,-1,hash2,1)) == 0 )
return(clonestr("{\"error\":\"gecko block couldnt be created\"}"));
}
iguana_blockcopy(virt->chain->zcash,virt->chain->auxpow,virt,block,(struct iguana_block *)&txdata.zblock);
prev = block;
adjacent = -1;
for (i=0; i<virt->chain->bundlesize; i++)
{
if ( (prev= iguana_blockfind("geckoprev",virt,prev->RO.prev_block)) == 0 )
return(clonestr("{\"error\":\"gecko block is orphan\"}"));
if ( i == 0 )
adjacent = prev->height;
//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;
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;
prev = block;
// probably should clear mainchain bits in old path
for (j=0; j<=i; j++)
{
if ( (prev= iguana_blockfind("geckoprev",virt,prev->RO.prev_block)) == 0 )
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);
return(clonestr("{\"result\":\"gecko block created\"}"));
} else return(clonestr("{\"error\":\"gecko error creating ramchain0\"}"));
}
}
}
}
return(clonestr("{\"error\":\"gecko block didnt decode\"}"));
}

97
gecko/gecko_miner.c

@ -25,19 +25,85 @@ int32_t gecko_blocknonce_verify(struct iguana_info *virt,uint8_t *serialized,int
else return(0);
}
uint32_t gecko_nBits(struct iguana_info *virt,struct iguana_block *newblock)
/*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)
{
uint32_t nBits = GECKO_DEFAULTDIFF; struct iguana_block *prev=0,*prev2=0;
if ( newblock->height >= 0 && (prev= iguana_blockfind("geckotx",virt,newblock->RO.prev_block)) != 0 && prev->height > 1 )
// 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;
if ( virt->chain->estblocktime == 0 )
return(GECKO_EASIESTDIFF);
for (i=0; i<n; i++)
{
if ( (prev= iguana_blockfind("geckotx",virt,block->RO.prev_block)) == 0 || prev->height == 0 )
{
i++;
break;
}
if ( i == 0 )
{
endtime = prev->RO.timestamp;
nBits = prev->RO.bits;
}
starttime = prev->RO.timestamp;
block = prev;
}
if ( starttime != 0 && endtime > starttime && i > 1 )
{
diff = (endtime - starttime);
est = virt->chain->estblocktime * i;
targetval = bits256_from_compact(nBits);
if ( diff > est )
{
targetval = bits256_rshift(bits256_add(targetval,bits256_lshift(targetval)));
}
else if ( diff < est )
{
targetval = bits256_rshift(bits256_add(targetval,bits256_rshift(targetval)));
}
//printf("diff.%d est.%d nBits.%08x <- %08x\n",endtime - starttime,virt->chain->estblocktime * i,bits256_to_compact(targetval),nBits);
nBits = bits256_to_compact(targetval);
}
if ( nBits > GECKO_EASIESTDIFF )
{
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 > virt->chain->nBits )
nBits = virt->chain->nBits;
if ( nBits > GECKO_EASIESTDIFF )
{
printf("nBits.%08x vs easiest %08x\n",nBits,GECKO_EASIESTDIFF);
nBits = GECKO_EASIESTDIFF;
}
}
else nBits = virt->chain->nBits;
} else printf("ht.%d prev.%p prevht.%d prev2.%p\n",newblock->height,prev,prev!=0?prev->height:-1,prev2);
} else printf("ht.%d prev.%p prevht.%d prev2.%p\n",newblock->height,prev,prev!=0?prev->height:-1,prev2);*/
return(nBits);
}
@ -216,11 +282,11 @@ char **gecko_mempool(struct supernet_info *myinfo,struct iguana_info *virt,int64
return(0);
}
void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr)
void gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2)
{
uint8_t *data,space[16384],*allocptr=0; int32_t i,len,numranked=0; struct iguana_peers *peers; struct iguana_peer *addr;
if ( (peers= virt->peers) == 0 || (numranked= peers->numranked) == 0 )
basilisk_blocksubmit(myinfo,virt,blockstr);
basilisk_blocksubmit(myinfo,virt,blockstr,hash2);
else
{
if ( (data= get_dataptr(sizeof(struct iguana_msghdr),&allocptr,&len,space,sizeof(space),blockstr)) != 0 )
@ -239,13 +305,14 @@ 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)
{
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 )
if ( virt->virtualchain == 0 )//|| virt->bundles[virt->blocks.hwmchain.height / virt->chain->bundlesize] == 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;
if ( (nBits= gecko_nBits(virt,(void *)&newblock)) != 0 )
newblock.RO.allocsize = sizeof(struct iguana_block);
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);
@ -271,11 +338,11 @@ void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct ig
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);
//else printf("found bp.%p bundlei.%d\n",bp,bundlei);
}
virt->blocks.hwmchain = newblock;
char str[65]; printf("%s mined.%x %s isPoS.%d numtx.%d ht.%d\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),virt->chain->isPoS,newblock.RO.txn_count,newblock.height);
gecko_blocksubmit(myinfo,virt,blockstr);
//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);
gecko_blocksubmit(myinfo,virt,blockstr,newblock.RO.hash2);
free(blockstr);
}
if ( txptrs != space )

49
iguana/iguana777.c

@ -47,6 +47,14 @@ struct iguana_info *iguana_coinadd(char *symbol,char *name,cJSON *argjson)
coin = mycalloc('C',1,sizeof(*coin));
coin->blockspacesize = IGUANA_MAXPACKETSIZE + 8192;
coin->blockspace = calloc(1,coin->blockspacesize);
if ( (privatechain= jstr(argjson,"geckochain")) != 0 && privatechain[0] != 0 )
{
myinfo->allcoins_numvirts++;
coin->virtualchain = 1;
}
else
{
coin->chain = iguana_chainfind((char *)symbol,argjson,1);
coin->peers = calloc(1,sizeof(*coin->peers));
for (j=0; j<IGUANA_MAXPEERS; j++)
{
@ -54,6 +62,7 @@ struct iguana_info *iguana_coinadd(char *symbol,char *name,cJSON *argjson)
strcpy(coin->peers->active[j].coinname,name);
strcpy(coin->peers->active[j].symbol,symbol);
}
}
if ( (coin->protocol= juint(argjson,"protocol")) == 0 )
coin->protocol = IGUANA_PROTOCOL_BITCOIN;
coin->ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
@ -61,11 +70,6 @@ struct iguana_info *iguana_coinadd(char *symbol,char *name,cJSON *argjson)
secp256k1_rangeproof_context_initialize(coin->ctx);
strcpy(coin->name,name);
strcpy(coin->symbol,symbol);
if ( (privatechain= jstr(argjson,"privatechain")) != 0 && privatechain[0] != 0 )
{
myinfo->allcoins_numvirts++;
coin->virtualchain = 1;
} else coin->chain = iguana_chainfind((char *)symbol,argjson,1);
iguana_initcoin(coin,argjson);
basilisk_functions(coin,coin->protocol);
printf("ADD ALLCOINS.(%s) name.(%s) size %ld numvirts.%d\n",symbol,name,sizeof(*coin),myinfo->allcoins_numvirts);
@ -654,11 +658,26 @@ void iguana_helper(void *arg)
void iguana_callcoinstart(struct iguana_info *coin)
{
struct iguana_bundle *bp; int32_t bundlei; bits256 zero;
struct iguana_bundle *bp; int32_t bundlei; bits256 zero; char dirname[512],*symbol;
iguana_rwiAddrind(coin,0,0,0);
//for (i=0; i<sizeof(*coin->chain); i++)
// printf("%02x",((uint8_t *)coin->chain)[i]);
char str[65]; printf(" netmagic.%08x init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d cache.%d pend.(%d -> %d)\n",*(uint32_t *)coin->chain->netmagic,coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout,coin->enableCACHE,coin->startPEND,coin->endPEND);
symbol = coin->symbol;
sprintf(dirname,"%s/ro",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/ro/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/purgeable/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s/validated",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s/accounts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s/spends",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s/vouts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
if ( coin->VALIDATEDIR[0] != 0 )
{
sprintf(dirname,"%s",coin->VALIDATEDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s",coin->VALIDATEDIR,symbol), OS_ensure_directory(dirname);
}
sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname);
iguana_coinstart(coin,coin->initialheight,coin->mapflags);
coin->chain->minconfirms = coin->minconfirms;
coin->started = coin;
@ -798,11 +817,12 @@ void iguana_nameset(char name[64],char *symbol,cJSON *json)
struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json)
{
struct iguana_chain *iguana_createchain(cJSON *json);
struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char dirname[512],name[64]; cJSON *peers;
struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char name[64]; cJSON *peers;
mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS;
iguana_nameset(name,symbol,json);
if ( (coin= iguana_coinfind(symbol)) == 0 )
coin = iguana_coinadd(symbol,name,json);
//printf("ensure directories maxval.%d mult.%d start.%d end.%d\n",maxval,mult,coin->startPEND,coin->endPEND);
mult = (strcmp("BTC",coin->symbol) != 0) ? 8 : 32;
maxval = IGUANA_MAXPENDBUNDLES;
if ( coin->virtualchain == 0 )
@ -865,21 +885,6 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,
coin->active = juint(json,"active");
if ( (coin->minconfirms = minconfirms) == 0 )
coin->minconfirms = (strcmp(symbol,"BTC") == 0) ? 3 : 10;
//printf("ensure directories maxval.%d mult.%d start.%d end.%d\n",maxval,mult,coin->startPEND,coin->endPEND);
sprintf(dirname,"%s/ro",GLOBAL_DBDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/ro/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/purgeable/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s/validated",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s/accounts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s/spends",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s/vouts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname);
if ( coin->VALIDATEDIR[0] != 0 )
{
sprintf(dirname,"%s",coin->VALIDATEDIR), OS_ensure_directory(dirname);
sprintf(dirname,"%s/%s",coin->VALIDATEDIR,symbol), OS_ensure_directory(dirname);
}
sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname);
if ( coin->chain == 0 && (coin->chain= iguana_createchain(json)) == 0 )
{
printf("cant initialize chain.(%s)\n",jstr(json,0));

28
iguana/iguana_accept.c

@ -286,9 +286,24 @@ int32_t iguana_inv2packet(uint8_t *serialized,int32_t maxsize,int32_t type,bits2
return(len - sizeof(struct iguana_msghdr));
}
int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block)
{
bits256 checkhash2; struct iguana_msgblock msgB; int32_t len = 0;
iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&msgB,block,1);
if ( (len= iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&serialized[sizeof(struct iguana_msghdr)],&msgB,(int32_t)(maxsize-sizeof(struct iguana_msghdr)))) < 0 )
return(-1);
if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 )
{
char str[65],str2[65];
printf("iguana_peerhdrrequest blockhash.%d error (%s) vs (%s)\n",block->height,bits256_str(str,checkhash2),bits256_str(str2,block->RO.hash2));
return(-1);
}
return(len);
}
int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2)
{
int32_t len=0,i,flag=0,height,hdrsi,bundlei,bundlesize,firstvout,retval=-1; struct iguana_block *block; struct iguana_msgblock msgB; bits256 checkhash2; struct iguana_bundle *bp;
int32_t len=0,i,flag=0,height,n,hdrsi,bundlei,bundlesize,firstvout,retval=-1; struct iguana_block *block; struct iguana_bundle *bp;
if ( (firstvout= iguana_unspentindfind(coin,0,0,0,0,&height,hash2,0,coin->bundlescount-1)) != 0 )
{
bundlesize = coin->chain->bundlesize;
@ -300,15 +315,12 @@ int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32
{
if ( (block= bp->blocks[i]) != 0 )
{
iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&msgB,block,1);
len += iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&serialized[sizeof(struct iguana_msghdr) + len],&msgB,(int32_t)(maxsize-len-sizeof(struct iguana_msghdr)));
flag++;
if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 )
if ( (n= iguana_headerget(coin,&serialized[len],maxsize-len,block)) < 0 )
{
char str[65],str2[65];
printf("iguana_peerhdrrequest blockhash.%d error (%s) vs (%s)\n",height+i,bits256_str(str,checkhash2),bits256_str(str2,block->RO.hash2));
return(-1);
printf("%s error getting header ht.%d\n",coin->symbol,block->height);
continue;
}
len += n;
} else printf("cant find block at ht.%d\n",height+i);
}
}

6
iguana/iguana_bundles.c

@ -217,8 +217,8 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo
}
if ( bits256_nonz(bp->hashes[bundlei]) != 0 && bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 )
{
char str[65],str2[65];
printf("bp.[%d]->hashes[%d] mismatch %s != %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":"");
//char str[65],str2[65];
//printf("B bp.[%d]->hashes[%d] mismatch %s != %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":"");
iguana_blockunmark(coin,block,bp,bundlei,1);
bp->blocks[bundlei] = 0;
//if ( block->mainchain != 0 )
@ -805,6 +805,7 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int
if ( 0 && requiredflag != 0 )
printf("not ready altpath.(%d %d %d %d %d) [%d:%d]\n",block->txvalid == 0,block->fpipbits == 0 ,block->fpos < 0,(bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0),iguana_blockvalidate(coin,&valid,block,1) < 0,bp->hdrsi,i);
}
else printf("cant find (%s)\n",fname);
}
}
else
@ -819,6 +820,7 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int
}
}
}
printf("ready.%d\n",ready);
return(ready);
}

24
iguana/iguana_chains.c

@ -287,6 +287,7 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson)
{
extern char Userhome[];
char *path,conf[512],*hexstr,genesisblock[1024]; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; uint32_t nBits; uint8_t tmp[4];
printf("chainparams.(%s)\n",jprint(argjson,0));
if ( strcmp(chain->symbol,"NXT") != 0 )
{
if ( strcmp(chain->symbol,"BTCD") == 0 )
@ -294,7 +295,8 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson)
if ( (chain->minoutput= j64bits(argjson,"minoutput")) == 0 )
chain->minoutput = 10000;
chain->minconfirms = juint(argjson,"minconfirms");
chain->estblocktime = juint(argjson,"estblocktime");
if ( (chain->estblocktime= juint(argjson,"estblocktime")) == 0 )
chain->estblocktime = juint(argjson,"blocktime");
path = jstr(argjson,"path");
if ( jobj(argjson,"conf") == 0 )
conf[0] = 0;
@ -347,10 +349,7 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson)
if ( (hexstr= jstr(argjson,"wifval")) != 0 && strlen(hexstr) == 2 )
decode_hex((uint8_t *)&chain->wiftype,1,hexstr);
if ( (hexstr= jstr(argjson,"netmagic")) != 0 && strlen(hexstr) == 8 )
{
decode_hex((uint8_t *)chain->netmagic,4,hexstr);
printf("NETMAGIC.(%s) -> %08x\n",hexstr,*(uint32_t *)chain->netmagic);
}
if ( (hexstr= jstr(argjson,"unitval")) != 0 && strlen(hexstr) == 2 )
decode_hex((uint8_t *)&chain->unitval,1,hexstr);
if ( (hexstr= jstr(argjson,"alertpubkey")) != 0 && (strlen(hexstr)>>1) <= sizeof(chain->alertpubkey) )
@ -371,8 +370,10 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson)
((uint8_t *)&nBits)[1] = tmp[2];
((uint8_t *)&nBits)[2] = tmp[1];
((uint8_t *)&nBits)[3] = tmp[0];
}
else nBits = 0x1e00ffff;
} else nBits = 0x1e00ffff;
chain->nBits = nBits;
chain->unitval = (nBits >> 24);
printf("NETMAGIC %08x unitval.%02x nBits.%08x\n",*(uint32_t *)chain->netmagic,chain->unitval,chain->nBits);
chain->genesishash2 = iguana_chaingenesis(chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,chain->genesishash2,genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),nBits,juint(genesis,"nonce"),jbits256(genesis,"merkle_root"));
memcpy(chain->genesis_hashdata,chain->genesishash2.bytes,32);
char str[65]; init_hexbytes_noT(str,chain->genesis_hashdata,32);
@ -381,6 +382,17 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson)
}
else
{
if ( jstr(argjson,"nBits") != 0 )
{
decode_hex((void *)&tmp,sizeof(tmp),jstr(argjson,"nBits"));
((uint8_t *)&nBits)[0] = tmp[3];
((uint8_t *)&nBits)[1] = tmp[2];
((uint8_t *)&nBits)[2] = tmp[1];
((uint8_t *)&nBits)[3] = tmp[0];
} else nBits = 0x1e00ffff;
chain->nBits = nBits;
chain->unitval = (nBits >> 24);
printf("NETMAGIC -> %08x unitval.%02x (%s) -> tmp.%08x nBits.%08x\n",*(uint32_t *)chain->netmagic,chain->unitval,jstr(argjson,"nBits"),*(uint32_t *)tmp,chain->nBits);
if ( (hexstr= jstr(argjson,"genesisblock")) != 0 )
{
uint8_t hexbuf[1024],*ptr,*data; int32_t datalen,hdrsize;

8
iguana/iguana_init.c

@ -104,7 +104,7 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain)
auxback = coin->chain->auxpow, coin->chain->auxpow = 0;
iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,buf,&msg,sizeof(buf));
coin->chain->auxpow = auxback;
if ( coin->virtualchain != 0 || coin->MAXPEERS > 1 )
if ( coin->virtualchain == 0 && coin->MAXPEERS > 1 )
{
if ( memcmp(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)) != 0 )
{
@ -127,9 +127,10 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain)
ptr->mainchain = 1;
ptr->height = 0;
//coin->blocks.RO[0] = block.RO;
if ( (height= iguana_chainextend(coin,ptr)) == 0 )
if ( coin->virtualchain != 0 || (height= iguana_chainextend(coin,ptr)) == 0 )
{
iguana_blockzcopy(coin->chain->zcash,block,ptr);
iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,ptr);
printf("size.%d genesis block PoW %f ptr %f\n",block->RO.allocsize,block->PoW,ptr->PoW);
coin->blocks.recvblocks = coin->blocks.issuedblocks = 1;
} else printf("genesis block doesnt validate for %s ht.%d\n",coin->symbol,height);
@ -520,12 +521,15 @@ struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialhei
int32_t bundlei = -2;
static const bits256 zero;
iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1);
if ( coin->virtualchain == 0 )
{
_iguana_chainlink(coin,iguana_blockfind("genesis",coin,*(bits256 *)coin->chain->genesis_hashdata));
if ( coin->blocks.hwmchain.height != 0 || memcmp(coin->blocks.hwmchain.RO.hash2.bytes,coin->chain->genesis_hashdata,sizeof(coin->chain->genesis_hashdata)) != 0 )
{
char str[65]; printf("%s genesis values mismatch hwmheight.%d %.15f %.15f %s\n",coin->name,coin->blocks.hwmchain.height,coin->blocks.hwmchain.PoW,coin->blocks.hwmchain.PoW,bits256_str(str,coin->blocks.hwmchain.RO.hash2));
getchar();
}
}
memset(&lastbundle,0,sizeof(lastbundle));
if ( coin->peers == 0 )
iter = 2;

2
iguana/iguana_json.c

@ -799,7 +799,7 @@ char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char
char *hash_dispatch(void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len),char *name,char *message)
{
char hexstr[16384]; uint8_t databuf[8192]; cJSON *json;
char hexstr[65537]; uint8_t databuf[32768]; cJSON *json;
if ( message != 0 && message[0] != 0 )
{
memset(hexstr,0,sizeof(hexstr));

7
iguana/iguana_ramchain.c

@ -101,7 +101,7 @@ 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 )
//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);
return(-2);
}
@ -1050,7 +1050,8 @@ long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits
#endif
if ( (fp= fopen(fname,"wb")) == 0 )
printf("iguana_ramchain_save: couldnt create.(%s) errno.%d\n",fname,errno);
else coin->peers->numfiles++;
else if ( coin->peers != 0 )
coin->peers->numfiles++;
if ( fp != 0 )
{
fpos = ftell(fp);
@ -2603,7 +2604,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str
{
for (j=starti; j<=endi; j++)
{
if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 )
if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 && coin->peers != 0 )
coin->peers->numfiles -= OS_removefile(fname,0);
else printf("error removing.(%s)\n",fname);
}

3
iguana/iguana_stake.c

@ -87,8 +87,7 @@ uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchai
{
if ( (gap= prev->RO.timestamp - prev2->RO.timestamp) < 0 )
gap = targetspacing;
// ppcoin: target change every block, retarget with exponential moving toward target spacing
//printf("MSPACING.%d gap.%d\n",NINTERVAL_MSPACING,gap);
//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);
}
}

2
iguana/iguana_tx.c

@ -354,7 +354,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3
jaddnum(json,"valid",block->valid);
jaddnum(json,"txn_count",block->RO.txn_count);
jaddnum(json,"bits",block->RO.bits);
jaddnum(json,"nBits",block->RO.bits);
serialized[0] = ((uint8_t *)&block->RO.bits)[3];
serialized[1] = ((uint8_t *)&block->RO.bits)[2];
serialized[2] = ((uint8_t *)&block->RO.bits)[1];

2
iguana/tests/new

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

7
includes/iguana_apideclares.h

@ -21,12 +21,15 @@ 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,geckotx,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,geckoblock,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,forward,pubkey,vals,hexstr);
HASH_ARRAY_STRING(basilisk,mailbox,pubkey,vals,hexstr);

4
includes/iguana_funcs.h

@ -486,7 +486,7 @@ void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_blo
int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block *block);
void basilisk_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr);
int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]);
int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr);
int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *virt,char *blockstr,bits256 hash2);
struct supernet_info *SuperNET_MYINFO(char *passphrase);
bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory);
struct gecko_chain *category_find(bits256 categoryhash,bits256 subhash);
@ -500,6 +500,8 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr);
char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,cJSON *json,char *remoteaddr);
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);
#include "../includes/iguana_api.h"

Loading…
Cancel
Save