diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h index a9cd5c43e..eb37d7f2f 100644 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -94,13 +94,23 @@ struct supernet_info int32_t nnsock,num; struct endpoint eps[]; };*/ +struct category_chain +{ + bits256 *weights,*blocks,category_hwm,cchainhash; + int32_t hashlen,addrlen,maxblocknum; + struct supernet_info *myinfo; + void *categoryinfo,*subinfo; + int32_t (*blockhash_func)(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen); + bits256 (*stake_func)(struct category_chain *cchain,void *addr,int32_t addrlen); + bits256 (*hit_func)(struct category_chain *cchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp); + bits256 (*default_func)(struct category_chain *cchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest); +}; + struct category_info { UT_hash_handle hh; queue_t Q; int32_t (*process_func)(struct supernet_info *myinfo,void *data,int32_t datalen,char *remoteaddr); - int32_t (*blockhash_func)(void *blockhashp,void *data,int32_t datalen); // returns len of blockhash - uint64_t (*hit_func)(struct supernet_info *myinfo,void *categoryinfo,void *subinfo,void *addr,int32_t addrlen); - int32_t (*ishwm_func)(struct supernet_info *myinfo,void *categoryinfo,void *subinfo,void *blockhashp,int32_t hashlen,int32_t heighthint,uint64_t hwmwt,uint64_t prevwt,uint64_t hit); + struct category_chain *cchain; bits256 hash; void *info; struct category_info *sub; }; extern struct category_info *Categories; @@ -144,6 +154,8 @@ char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr) char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subcategory,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext); bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); +struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func); +#define category_default_latest() (*cchain->default_func)(cchain,'L',0,0,0,0,zero) #endif diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c index c77b4b195..8fca7663f 100644 --- a/iguana/SuperNET_category.c +++ b/iguana/SuperNET_category.c @@ -85,15 +85,6 @@ struct category_info *category_processfunc(bits256 categoryhash,int32_t (*proces return(0); } -struct category_chain -{ - int32_t hashlen,addrlen; - struct supernet_info *myinfo; - void *categoryinfo,*subinfo; - int32_t (*blockhash_func)(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen); - bits256 (*stake_func)(struct category_chain *cchain,void *addr,int32_t addrlen); -}; - int32_t category_default_blockhash(struct category_chain *cchain,void *blockhashp,void *data,int32_t datalen) { bits256 hash; @@ -110,82 +101,88 @@ bits256 category_default_stake(struct category_chain *cchain,void *addr,int32_t return(stake); } -bits256 catgory_default_hit(struct supernet_info *myinfo,void *categoryinfo,void *subinfo,int32_t height,void *prevgenerator,void *addr,int32_t addrlen,void *blockhashp,int32_t hashlen) +bits256 catgory_default_hit(struct category_chain *cchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp) { bits256 hash; bits256 rawhit,hit; memset(rawhit.bytes,0,sizeof(rawhit)); memset(hit.bytes,0,sizeof(hit)); - vcalc_sha256cat(hash.bytes,prevgenerator,addrlen,addr,addrlen); - hit = category_default_stake(*(void **)categoryinfo,addr,addrlen); + vcalc_sha256cat(hash.bytes,prevgenerator,cchain->addrlen,addr,cchain->addrlen); + hit = (*cchain->stake_func)(cchain,addr,cchain->addrlen); rawhit.txid = hash.txid % ((uint64_t)1 << 42); if ( rawhit.txid != 0 ) hit.txid /= rawhit.txid; return(hit); } -// WARNING: toy implementation assumes only one category chain -bits256 category_default_func(struct supernet_info *myinfo,int32_t func,void *categoryinfo,void *subinfo,int32_t height,void *prevgenerator,void *addr,int32_t addrlen,void *blockhashp,int32_t hashlen,bits256 heaviest) +#define category_default_heaviest() (*cchain->default_func)(cchain,'H',0,0,0,0,zero) +#define category_default_latest() (*cchain->default_func)(cchain,'L',0,0,0,0,zero) +#define category_default_setheaviest(height,blockhashp,heaviest) (*cchain->default_func)(cchain,'S',height,0,0,blockhashp,zero) +#define category_default_weight(height) (*cchain->default_func)(cchain,'W',height,0,0,0,zero) +#define category_default_blockfind(height) (*cchain->default_func)(cchain,'B',height,0,0,0,zero) + +bits256 category_default_func(struct category_chain *cchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest) { - static int maxblocknum; static bits256 *weights,*blocks,category_hwm,zero; - if ( hashlen != sizeof(bits256) || addrlen != sizeof(bits256) ) + static bits256 zero; + if ( cchain->hashlen != sizeof(bits256) || cchain->addrlen != sizeof(bits256) ) { - printf("unsupported hashlen.%d or addrlen.%d\n",hashlen,addrlen); + printf("unsupported hashlen.%d or addrlen.%d\n",cchain->hashlen,cchain->addrlen); return(zero); } - if ( height > maxblocknum + (func == 'S') ) + if ( height > cchain->maxblocknum + (func == 'S') ) { - printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,maxblocknum,height); - return(category_hwm); + printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,cchain->maxblocknum,height); + return(cchain->category_hwm); } if ( func == 'H' ) - return(category_hwm); + return(cchain->category_hwm); + else if ( func == 'L' ) + { + if ( cchain->maxblocknum < 0 ) + return(cchain->cchainhash); + else return(cchain->blocks[cchain->maxblocknum]); + } else if ( func == 'S' ) { - category_hwm = heaviest; - if ( height > maxblocknum ) + cchain->category_hwm = heaviest; + if ( height > cchain->maxblocknum ) { - weights = realloc(weights,(maxblocknum+1) * sizeof(*weights)); - blocks = realloc(blocks,(maxblocknum+1) * sizeof(*blocks)); + cchain->weights = realloc(cchain->weights,(cchain->maxblocknum+1) * sizeof(*cchain->weights)); + cchain->blocks = realloc(cchain->blocks,(cchain->maxblocknum+1) * sizeof(*cchain->blocks)); } - maxblocknum = height; - weights[height] = heaviest; + cchain->maxblocknum = height; + cchain->weights[height] = heaviest; if ( blockhashp != 0 ) - memcpy(&blocks[height],blockhashp,sizeof(blocks[height])); + memcpy(&cchain->blocks[height],blockhashp,sizeof(cchain->blocks[height])); } else if ( func == 'B' ) { - if ( height <= maxblocknum ) - return(blocks[height]); + if ( height <= cchain->maxblocknum ) + return(cchain->blocks[height]); else { - printf("error: illegal height.%d vs max.%d\n",height,maxblocknum); + printf("error: illegal height.%d vs max.%d\n",height,cchain->maxblocknum); return(zero); } } else if ( func == 'W' ) { - if ( height >= 0 && height < maxblocknum ) - return(weights[height]); - else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,maxblocknum); + if ( height >= 0 && height < cchain->maxblocknum ) + return(cchain->weights[height]); + else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,cchain->maxblocknum); } - return(category_hwm); + return(cchain->category_hwm); } -#define category_default_heaviest() category_default_func(myinfo,'H',categoryinfo,subinfo,0,0,0,0,0,0,zero) -#define category_default_setheaviest(height,blockhashp,heaviest) category_default_func(myinfo,'S',categoryinfo,subinfo,height,0,0,0,blockhashp,hashlen,zero) -#define category_default_weight(height) category_default_func(myinfo,'W',categoryinfo,subinfo,height,0,0,0,0,0,zero) -#define category_default_blockfind(height) category_default_func(myinfo,'B',categoryinfo,subinfo,height,0,0,0,0,0,zero) - -int32_t category_default_ishwm(struct supernet_info *myinfo,void *categoryinfo,void *subinfo,int32_t prevheight,void *prevblockhashp,void *blockhashp,int32_t hashlen,void *prevgenerator,void *addr,int32_t addrlen) +int32_t category_default_ishwm(struct category_chain *cchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) { bits256 checkhash,prevwt,oldhit,hit,heaviest; static bits256 zero; checkhash = category_default_blockfind(prevheight); - if ( memcmp(checkhash.bytes,prevblockhashp,hashlen) == 0 ) + if ( memcmp(checkhash.bytes,prevblockhashp,cchain->hashlen) == 0 ) { heaviest = category_default_heaviest(); prevwt = category_default_weight(prevheight); oldhit = category_default_weight(prevheight+1); - hit = catgory_default_hit(myinfo,categoryinfo,subinfo,prevheight+1,prevgenerator,addr,addrlen,blockhashp,hashlen); + hit = (*cchain->hit_func)(cchain,prevheight+1,prevgenerator,addr,blockhashp); if ( hit.txid > oldhit.txid && prevwt.txid+hit.txid > heaviest.txid ) { heaviest.txid = (prevwt.txid + hit.txid); @@ -197,13 +194,43 @@ int32_t category_default_ishwm(struct supernet_info *myinfo,void *categoryinfo,v return(-1); } -struct category_info *category_chain_functions(bits256 categoryhash,bits256 subhash,int32_t (*blockhash_func)(void *blockhashp,void *data,int32_t datalen)) +struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func) { - struct category_info *cat; + struct category_info *cat; struct category_chain *cchain = calloc(1,sizeof(*cchain)); if ( (cat= category_find(categoryhash,subhash)) != 0 ) { - cat->blockhash_func = blockhash_func; - return(cat); + cchain->maxblocknum = -1; + cchain->myinfo = myinfo, cchain->subinfo = cat->info; + if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 ) + cchain->categoryinfo = cat->info, cchain->cchainhash = categoryhash; + else cchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), cchain->cchainhash = subhash; + if ( cchain->myinfo == 0 || cchain->categoryinfo || cchain->subinfo ) + { + printf("error with cchain pointers\n"); + return(0); + } + if ( (cchain->addrlen= addrlen) <= 0 || (cchain->hashlen= hashlen) <= 0 ) + { + printf("error with cchain lens.%d %d\n",addrlen,hashlen); + return(0); + } + if ( (cchain->blockhash_func= hash_func) == 0 || (cchain->stake_func= stake_func) == 0 || (cchain->hit_func= hit_func) == 0 || (cchain->default_func= default_func) == 0 ) + { + if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) ) + { + cchain->blockhash_func = category_default_blockhash; + cchain->stake_func = category_default_stake; + cchain->hit_func = catgory_default_hit; + cchain->default_func = category_default_func; + } + else + { + printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen); + return(0); + } + } + cat->cchain = cchain; + return(cchain); } return(0); } diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index a84044d63..6e414e662 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -523,7 +523,10 @@ TWO_STRINGS(iguana,addnode,activecoin,ipaddr) { iguana_possible_peer(coin,ipaddr); return(clonestr("{\"result\":\"addnode submitted\"}")); - } else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); + } + else if ( coin == 0 ) + return(clonestr("{\"error\":\"addnode needs active coin, do an addcoin first\"}")); + else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); } TWO_STRINGS(iguana,persistent,activecoin,ipaddr) diff --git a/iguana/main.c b/iguana/main.c index f8a53f9bd..949d31a0c 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -283,15 +283,6 @@ void iguana_main(void *arg) struct supernet_info *myinfo; int32_t i,len,flag,c; bits256 acct,seed,checkhash,wallethash,walletpub,wallet2shared,wallet2priv,wallet2pub; myinfo = SuperNET_MYINFO(0); - char str[65]; uint32_t t,s; - t = 1409839200;//(uint32_t)time(NULL); - for (i=0; i<1; i++) - { - utc_str(str,t-i); - s = OS_conv_utime(str); - //if ( s != t-i ) - printf("t.%u -> %s -> %u diff.[%d]\n",t-i,str,s,(t-i) - s); - } iguana_chaingenesis(1,1403138561,0x1e0fffff,8359109,bits256_conv("fd1751cc6963d88feca94c0d01da8883852647a37a0a67ce254d62dd8c9d5b2b")); iguana_chaingenesis(1,1409839200,0x1e0fffff,64881664,bits256_conv("698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828")); @@ -429,7 +420,7 @@ void iguana_main(void *arg) vcalc_sha256(0,acct.bytes,(void *)myinfo->myaddr.persistent.bytes,sizeof(bits256)); myinfo->myaddr.nxt64bits = acct.txid; RS_encode(myinfo->myaddr.NXTADDR,myinfo->myaddr.nxt64bits); - char str2[65]; printf("%s %llu %p PRIV.%s PUB.%s persistent.%llx %llx\n",myinfo->myaddr.NXTADDR,(long long)myinfo->myaddr.nxt64bits,&myinfo->privkey,bits256_str(str,myinfo->privkey),bits256_str(str2,myinfo->myaddr.pubkey),(long long)myinfo->persistent_priv.txid,(long long)myinfo->myaddr.persistent.txid); + char str[65],str2[65]; printf("%s %llu %p PRIV.%s PUB.%s persistent.%llx %llx\n",myinfo->myaddr.NXTADDR,(long long)myinfo->myaddr.nxt64bits,&myinfo->privkey,bits256_str(str,myinfo->privkey),bits256_str(str2,myinfo->myaddr.pubkey),(long long)myinfo->persistent_priv.txid,(long long)myinfo->myaddr.persistent.txid); if ( confstr == 0 ) { uint8_t *compressed,*serialized; int32_t r,complen,maxsize = IGUANA_MAXPACKETSIZE; @@ -488,6 +479,7 @@ void iguana_main(void *arg) pangeahash = calc_categoryhashes(0,"pangea",0); category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); category_processfunc(pangeahash,pangea_hexmsg); + category_chain_functions(&MYINFO,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0); for (i=0; i