Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
e1d1682456
  1. 79
      basilisk/basilisk.c
  2. 8
      basilisk/basilisk.h
  3. 67
      basilisk/basilisk_CMD.c
  4. 14
      basilisk/basilisk_bitcoin.c
  5. 5
      crypto777/OS_portable.h
  6. 19
      crypto777/curve25519.c
  7. 19
      crypto777/iguana_utils.c
  8. 10
      gecko/gecko.c
  9. 17
      gecko/gecko.h
  10. 100
      gecko/gecko_blocks.c
  11. 293
      gecko/gecko_mempool.c
  12. 70
      gecko/gecko_miner.c
  13. 2
      iguana/coins/btcd
  14. 2
      iguana/coins/genltc
  15. 2
      iguana/coins/ltc
  16. 9
      iguana/exchanges/bitcoin.c
  17. 4
      iguana/iguana777.c
  18. 2
      iguana/iguana_accept.c
  19. 1229
      iguana/iguana_interpreter.c
  20. 4
      iguana/iguana_msg.c
  21. 63
      iguana/iguana_payments.c
  22. 31
      iguana/iguana_peers.c
  23. 2
      iguana/iguana_ramchain.c
  24. 2
      iguana/iguana_recv.c
  25. 15
      iguana/iguana_rpc.c
  26. 126
      iguana/iguana_secp.c
  27. 16
      iguana/iguana_sign.c
  28. 2
      iguana/iguana_spendvectors.c
  29. 2
      iguana/iguana_txidfind.c
  30. 27
      iguana/iguana_unspents.c
  31. 153
      iguana/main.c
  32. 1
      iguana/ramchain_api.c
  33. 1
      iguana/tests/getblock
  34. 1
      iguana/tests/getblockcount
  35. 1
      iguana/tests/getblockhash
  36. 2
      iguana/tests/new
  37. 19
      includes/iguana_funcs.h
  38. 9
      includes/iguana_structs.h

79
basilisk/basilisk.c

@ -102,7 +102,7 @@ uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int
} }
data += extraoffset + BASILISK_HDROFFSET; data += extraoffset + BASILISK_HDROFFSET;
memcpy(data,sendstr,datalen); memcpy(data,sendstr,datalen);
printf("jsondata.(%s) + hexlen.%d\n",sendstr,hexlen); //printf("jsondata.(%s) + hexlen.%d\n",sendstr,hexlen);
free(sendstr); free(sendstr);
if ( hexlen > 0 ) if ( hexlen > 0 )
{ {
@ -286,7 +286,7 @@ void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t
void basilisk_sendback(struct supernet_info *myinfo,char *origCMD,char *symbol,char *remoteaddr,uint32_t basilisktag,char *retstr) void basilisk_sendback(struct supernet_info *myinfo,char *origCMD,char *symbol,char *remoteaddr,uint32_t basilisktag,char *retstr)
{ {
uint8_t *data,space[4096],*allocptr; cJSON *valsobj; int32_t datalen,encryptflag=0,delaymillis=0; uint8_t *data,space[4096],*allocptr; cJSON *valsobj; int32_t datalen,encryptflag=0,delaymillis=0;
printf("retstr.(%s) -> remote.(%s) basilisktag.%u\n",retstr,remoteaddr,basilisktag); printf("%s retstr.(%s) -> remote.(%s) basilisktag.%u\n",origCMD,retstr,remoteaddr,basilisktag);
if ( retstr != 0 && remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 ) if ( retstr != 0 && remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 )
{ {
if ( (valsobj= cJSON_Parse(retstr)) != 0 ) if ( (valsobj= cJSON_Parse(retstr)) != 0 )
@ -309,11 +309,11 @@ char *basilisk_waitresponse(struct supernet_info *myinfo,char *CMD,char *symbol,
if ( (retstr= Lptr->retstr) == 0 ) if ( (retstr= Lptr->retstr) == 0 )
retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}"); retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}");
ptr = basilisk_itemcreate(myinfo,CMD,symbol,Lptr->basilisktag,Lptr->numrequired,Lptr->vals,OS_milliseconds() - Lptr->expiration,Lptr->metricfunc); ptr = basilisk_itemcreate(myinfo,CMD,symbol,Lptr->basilisktag,Lptr->numrequired,Lptr->vals,OS_milliseconds() - Lptr->expiration,Lptr->metricfunc);
//queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0);
} }
else else
{ {
//queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0);
while ( OS_milliseconds() < ptr->expiration ) while ( OS_milliseconds() < ptr->expiration )
{ {
//if ( (retstr= basilisk_iscomplete(ptr)) != 0 ) //if ( (retstr= basilisk_iscomplete(ptr)) != 0 )
@ -387,7 +387,6 @@ char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,bits256 ha
ptr->vals = jduplicate(valsobj); ptr->vals = jduplicate(valsobj);
strcpy(ptr->symbol,"BTCD"); strcpy(ptr->symbol,"BTCD");
strcpy(ptr->CMD,CMD); strcpy(ptr->CMD,CMD);
queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0);
return(basilisk_waitresponse(myinfo,CMD,"BTCD",0,&Lptr,ptr)); return(basilisk_waitresponse(myinfo,CMD,"BTCD",0,&Lptr,ptr));
} }
else if ( ptr->numsent > 0 ) else if ( ptr->numsent > 0 )
@ -536,7 +535,6 @@ char *basilisk_standardcmd(struct supernet_info *myinfo,char *CMD,char *activeco
{ {
if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 )
{ {
queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0);
return(basilisk_waitresponse(myinfo,CMD,coin->symbol,remoteaddr,&Lptr,ptr)); return(basilisk_waitresponse(myinfo,CMD,coin->symbol,remoteaddr,&Lptr,ptr));
} }
else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}")); else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}"));
@ -599,6 +597,48 @@ char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *s
} }
} }
int32_t basilisk_relays_send(struct supernet_info *myinfo,struct iguana_peer *addr)
{
int32_t i,len = 0; uint8_t serialized[sizeof(myinfo->relaybits)]; cJSON *vals; bits256 hash; char *retstr,hexstr[sizeof(myinfo->relaybits)*2 + 1];
if ( myinfo != 0 )
{
memset(hash.bytes,0,sizeof(hash));
for (i=0; i<myinfo->numrelays; i++)
len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&myinfo->relaybits[i]);
init_hexbytes_noT(hexstr,serialized,len);
vals = cJSON_CreateObject();
if ( (retstr= basilisk_standardservice("REL",myinfo,hash,vals,hexstr,1)) != 0 )
free(retstr);
free_json(vals);
return(0);
} else return(-1);
}
int32_t basilisk_headers_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,bits256 *txids,int32_t num)
{
bits256 hash; uint8_t *serialized; int32_t i,len = 0; char *str=0,*retstr,*hexstr,*allocptr=0,space[8192]; bits256 txid; cJSON *vals;
if ( virt != 0 && addr != 0 )
{
memset(hash.bytes,0,sizeof(hash));
serialized = (void *)txids;
for (i=0; i<num; i++)
{
txid = txids[i];
len += iguana_rwbignum(1,&serialized[len],sizeof(txid),txid.bytes);
}
if ( (hexstr= basilisk_addhexstr(&str,0,space,sizeof(space),serialized,len)) != 0 )
{
vals = cJSON_CreateObject();
if ( (retstr= basilisk_standardservice("MEM",myinfo,hash,vals,hexstr,1)) != 0 )
free(retstr);
free_json(vals);
if ( allocptr != 0 )
free(allocptr);
}
return(0);
} else return(-1);
}
#include "../includes/iguana_apidefs.h" #include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h" #include "../includes/iguana_apideclares.h"
@ -624,7 +664,6 @@ INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin)
ptr->numrequired = 1; ptr->numrequired = 1;
ptr->uniqueflag = 1; ptr->uniqueflag = 1;
ptr->metricdir = -1; ptr->metricdir = -1;
queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0);
return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,ptr)); return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,ptr));
} else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}")); } else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}"));
} else return(retstr); } else return(retstr);
@ -652,6 +691,11 @@ HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr)
return(basilisk_standardservice("ADD",myinfo,hash,vals,hexstr,1)); return(basilisk_standardservice("ADD",myinfo,hash,vals,hexstr,1));
} }
HASH_ARRAY_STRING(basilisk,relays,hash,vals,hexstr)
{
return(basilisk_standardservice("REL",myinfo,hash,vals,hexstr,1));
}
HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr) HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr)
{ {
return(basilisk_standardservice("RUN",myinfo,hash,vals,hexstr,1)); return(basilisk_standardservice("RUN",myinfo,hash,vals,hexstr,1));
@ -724,6 +768,8 @@ void basilisk_geckoresult(struct supernet_info *myinfo,struct basilisk_item *ptr
hash2 = jbits256(retjson,"hash"); hash2 = jbits256(retjson,"hash");
if ( strcmp(type,"HDR") == 0 ) if ( strcmp(type,"HDR") == 0 )
str = gecko_headersarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); str = gecko_headersarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2);
else if ( strcmp(type,"MEM") == 0 )
str = gecko_mempoolarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2);
else if ( strcmp(type,"BLK") == 0 ) else if ( strcmp(type,"BLK") == 0 )
str = gecko_blockarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); str = gecko_blockarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2);
else if ( strcmp(type,"GTX") == 0 ) else if ( strcmp(type,"GTX") == 0 )
@ -834,10 +880,10 @@ void basilisks_loop(void *arg)
printf("HASH_DELETE free ptr.%u\n",pending->basilisktag); printf("HASH_DELETE free ptr.%u\n",pending->basilisktag);
for (i=0; i<pending->numresults; i++) for (i=0; i<pending->numresults; i++)
if ( pending->results[i] != 0 ) if ( pending->results[i] != 0 )
free(pending->results[i]); free(pending->results[i]), pending->results[i] = 0;
if ( pending->vals != 0 ) if ( pending->vals != 0 )
free_json(pending->vals); free_json(pending->vals), pending->vals = 0;
free(pending); //free(pending);
flag++; flag++;
} }
} }
@ -949,11 +995,13 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
{ (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx { (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx
{ (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers { (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers
{ (void *)"BLK", &basilisk_respond_geckoblock }, // reports block { (void *)"BLK", &basilisk_respond_geckoblock }, // reports block
{ (void *)"MEM", &basilisk_respond_mempool }, // reports mempool
{ (void *)"GTX", &basilisk_respond_geckotx }, // reports tx { (void *)"GTX", &basilisk_respond_geckotx }, // reports tx
{ (void *)"SEQ", &basilisk_respond_hashstamps }, // BTCD and BTC recent hashes from timestamp { (void *)"SEQ", &basilisk_respond_hashstamps }, // BTCD and BTC recent hashes from timestamp
// unencrypted low level functions, used by higher level protocols and virtual network funcs // 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 *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus
{ (void *)"REL", &basilisk_respond_relays },
{ (void *)"DEX", &basilisk_respond_instantdex }, { (void *)"DEX", &basilisk_respond_instantdex },
// encrypted data for jumblr // encrypted data for jumblr
@ -1088,11 +1136,16 @@ void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t sender
} }
else // basilisk node else // basilisk node
{ {
if ( strcmp(type,"ADD") == 0 ) if ( strcmp(type,"REL") == 0 )
{ {
printf("new relay ADD.(%s) datalen.%d\n",jprint(valsobj,0),datalen); printf("relays REL.(%s) datalen.%d\n",jprint(valsobj,0),datalen);
basilisk_respond_relays(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk);
} }
else printf("basilisk node doenst handle.(%s)\n",type); else if ( strcmp(type,"ADD") == 0 )
{
printf("new relay ADD.(%s) datalen.%d\n",jprint(valsobj,0),datalen);
basilisk_respond_addrelay(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk);
} else printf("basilisk node doenst handle.(%s)\n",type);
} }
} else printf("basilisk_msgprocess no coin\n"); } else printf("basilisk_msgprocess no coin\n");
} }

8
basilisk/basilisk.h

@ -45,6 +45,12 @@ struct basilisk_info
struct basilisk_value values[8192]; int32_t numvalues; struct basilisk_value values[8192]; int32_t numvalues;
}; };
struct basilisk_relay
{
bits256 pubkey; uint32_t ipbits; struct iguana_peer *addr;
char btcdaddr[64],sigstr[168];
};
void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen); void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen);
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 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)
@ -57,7 +63,7 @@ void *SuperNET_deciphercalc(void **ptrp,int32_t *msglenp,bits256 privkey,bits256
uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t *space,int32_t spacesize,char *hexstr); uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t *space,int32_t spacesize,char *hexstr);
char *basilisk_addhexstr(char **ptrp,cJSON *valsobj,char *strbuf,int32_t strsize,uint8_t *data,int32_t datalen); char *basilisk_addhexstr(char **ptrp,cJSON *valsobj,char *strbuf,int32_t strsize,uint8_t *data,int32_t datalen);
char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag); // client side char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag); // client side
char *basilisk_respond_mempool(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);
void basilisk_request_goodbye(struct supernet_info *myinfo); void basilisk_request_goodbye(struct supernet_info *myinfo);
int32_t basilisk_update(char *symbol,uint32_t reftimestamp); int32_t basilisk_update(char *symbol,uint32_t reftimestamp);

67
basilisk/basilisk_CMD.c

@ -15,6 +15,67 @@
// included from basilisk.c // included from basilisk.c
struct iguana_peer *basilisk_ensurerelay(struct iguana_info *btcd,uint32_t ipbits)
{
struct iguana_peer *addr;
if ( (addr= iguana_peerfindipbits(btcd,ipbits,0)) == 0 )
{
if ( (addr= iguana_peerslot(btcd,ipbits,0)) != 0 )
{
printf("launch peer for relay\n");
addr->isrelay = 1;
iguana_launch(btcd,"addrelay",iguana_startconnection,addr,IGUANA_CONNTHREAD);
} else printf("error getting peerslot\n");
} else addr->isrelay = 1;
return(addr);
}
char *basilisk_addrelay_info(struct supernet_info *myinfo,char *btcdaddr,uint32_t ipbits,bits256 pubkey,char *sigstr)
{
int32_t i; struct basilisk_relay *rp; struct iguana_info *btcd;
if ( (btcd= iguana_coinfind("BTCD")) == 0 )
return(clonestr("{\"error\":\"add relay needs BTCD\"}"));
for (i=0; i<myinfo->numrelays; i++)
{
rp = &myinfo->relays[i];
if ( ipbits == rp->ipbits )
return(clonestr("{\"error\":\"relay already there\"}"));
}
if ( i >= sizeof(myinfo->relays)/sizeof(*myinfo->relays) )
i = (rand() % (sizeof(myinfo->relays)/sizeof(*myinfo->relays)));
rp = &myinfo->relays[i];
printf("verify relay sig\n");
rp->ipbits = ipbits;
rp->pubkey = pubkey;
safecopy(rp->btcdaddr,btcdaddr,sizeof(rp->btcdaddr));
safecopy(rp->sigstr,sigstr,sizeof(rp->sigstr));
rp->addr = basilisk_ensurerelay(btcd,rp->ipbits);
for (i=0; i<myinfo->numrelays; i++)
myinfo->relaybits[i] = myinfo->relays[i].ipbits;
revsort32(&myinfo->relaybits[0],myinfo->numrelays,sizeof(myinfo->relaybits[0]));
return(clonestr("{\"result\":\"relay added\"}"));
}
char *basilisk_respond_relays(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)
{
uint32_t *ipbits = (uint32_t *)data; int32_t num,i,j,n = datalen >> 2;
for (i=num=0; i<n; i++)
{
for (j=0; j<myinfo->numrelays; j++)
if ( ipbits[i] == myinfo->relays[j].ipbits )
break;
if ( j == myinfo->numrelays )
{
num++;
printf("ensure unknown relay\n");
basilisk_ensurerelay(iguana_coinfind("BTCD"),ipbits[i]);
}
}
if ( num == 0 )
return(clonestr("{\"result\":\"no new relays found\"}"));
else return(clonestr("{\"result\":\"relay added\"}"));
}
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) 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; struct iguana_peer *addr = _addr;
@ -42,7 +103,11 @@ char *basilisk_respond_instantdex(struct supernet_info *myinfo,char *CMD,void *a
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 *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; char *ipaddr,*btcdaddr,*sigstr,*retstr=0;
printf("from.(%s) ADD.(%s) datalen.%d\n",remoteaddr,jprint(valsobj,0),datalen);
if ( (ipaddr= jstr(valsobj,"ipaddr")) != 0 && (btcdaddr= jstr(valsobj,"btcdaddr")) != 0 && (sigstr= jstr(valsobj,"sigstr")) != 0 )
retstr = basilisk_addrelay_info(myinfo,btcdaddr,(uint32_t)calc_ipbits(ipaddr),hash,sigstr);
else retstr = clonestr("{\"error\":\"need rmd160, address and ipaddr\"}");
return(retstr); return(retstr);
} }

14
basilisk/basilisk_bitcoin.c

@ -334,7 +334,7 @@ double basilisk_bitcoin_valuemetric(struct supernet_info *myinfo,struct basilisk
void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj)
{ {
int32_t i,height,vout,numsent; char *coinaddr; struct basilisk_value *v; uint64_t value = 0; bits256 txid; int32_t i,height,vout,numsent; struct basilisk_item *ptr; char *coinaddr; struct basilisk_value *v; uint64_t value = 0; bits256 txid;
txid = jbits256(valsobj,"txid"); txid = jbits256(valsobj,"txid");
vout = jint(valsobj,"vout"); vout = jint(valsobj,"vout");
coinaddr = jstr(valsobj,"address"); coinaddr = jstr(valsobj,"address");
@ -342,7 +342,7 @@ void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myi
{ {
if ( (coin->VALIDATENODE != 0 || coin->RELAYNODE != 0) && coinaddr != 0 && coinaddr[0] != 0 ) if ( (coin->VALIDATENODE != 0 || coin->RELAYNODE != 0) && coinaddr != 0 && coinaddr[0] != 0 )
{ {
if ( iguana_unspentindfind(coin,coinaddr,0,0,&value,&height,txid,vout,coin->bundlescount) > 0 ) if ( iguana_unspentindfind(coin,coinaddr,0,0,&value,&height,txid,vout,coin->bundlescount,0) > 0 )
{ {
printf("bitcoinvalue found iguana\n"); printf("bitcoinvalue found iguana\n");
Lptr->retstr = basilisk_valuestr(coin,coinaddr,value,height,txid,vout); Lptr->retstr = basilisk_valuestr(coin,coinaddr,value,height,txid,vout);
@ -360,12 +360,16 @@ void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myi
if ( v->vout == vout && bits256_cmp(txid,v->txid) == 0 && strcmp(v->coinaddr,coinaddr) == 0 ) if ( v->vout == vout && bits256_cmp(txid,v->txid) == 0 && strcmp(v->coinaddr,coinaddr) == 0 )
{ {
printf("bitcoinvalue local ht.%d %s %.8f\n",v->height,v->coinaddr,dstr(v->value)); printf("bitcoinvalue local ht.%d %s %.8f\n",v->height,v->coinaddr,dstr(v->value));
return(basilisk_issueremote(myinfo,&numsent,"VAL",coin->symbol,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,coin->basilisk_valuemetric,basilisk_valuestr(coin,v->coinaddr,v->value,v->height,txid,vout),0,0,BASILISK_DEFAULTDIFF)); ptr = basilisk_issueremote(myinfo,&numsent,"VAL",coin->symbol,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,coin->basilisk_valuemetric,basilisk_valuestr(coin,v->coinaddr,v->value,v->height,txid,vout),0,0,BASILISK_DEFAULTDIFF);
queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0);
return(ptr);
} }
} }
} }
printf("bitcoinvalue issue remote tag.%u\n",basilisktag); printf("bitcoinvalue issue remote tag.%u\n",basilisktag);
return(basilisk_issueremote(myinfo,&numsent,"VAL",coin->symbol,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,coin->basilisk_valuemetric,0,0,0,BASILISK_DEFAULTDIFF)); ptr = basilisk_issueremote(myinfo,&numsent,"VAL",coin->symbol,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,coin->basilisk_valuemetric,0,0,0,BASILISK_DEFAULTDIFF);
queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0);
return(ptr);
} }
double basilisk_bitcoin_rawtxmetric_dependents(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_item *ptr,struct bitcoin_rawtxdependents *dependents) double basilisk_bitcoin_rawtxmetric_dependents(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_item *ptr,struct bitcoin_rawtxdependents *dependents)
@ -421,7 +425,7 @@ double basilisk_bitcoin_rawtxmetric_dependents(struct supernet_info *myinfo,stru
printf("spend of invalid input address.(%s)\n",coinaddr); printf("spend of invalid input address.(%s)\n",coinaddr);
metric = -(3. + i); metric = -(3. + i);
} }
printf("Valid spend %.8f to %s\n",dstr(value),coinaddr); printf("Valid spend %.8f sum.(%.8f) to %s\n",dstr(value),dstr(inputsum),coinaddr);
} }
free_json(childjson); free_json(childjson);
} }

5
crypto777/OS_portable.h

@ -373,6 +373,11 @@ int32_t btc_priv2pub(uint8_t pubkey[33],uint8_t privkey[32]);
void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs); void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs);
int32_t OS_portable_rmdir(char *dirname,int32_t diralso); int32_t OS_portable_rmdir(char *dirname,int32_t diralso);
void calc_hmac_sha256(uint8_t *mac,int32_t maclen,uint8_t *key,int32_t key_size,uint8_t *message,int32_t len); void calc_hmac_sha256(uint8_t *mac,int32_t maclen,uint8_t *key,int32_t key_size,uint8_t *message,int32_t len);
int32_t revsort32(uint32_t *buf,uint32_t num,int32_t size);
bits256 bits256_sha256(bits256 data);
void bits256_rmd160(uint8_t rmd160[20],bits256 data);
void bits256_rmd160_sha256(uint8_t rmd160[20],bits256 data);
extern char *Iguana_validcommands[]; extern char *Iguana_validcommands[];
extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY; extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY;

19
crypto777/curve25519.c

@ -1540,6 +1540,25 @@ void calc_rmd160(char hexstr[41],uint8_t buf[20],uint8_t *msg,int32_t len)
init_hexbytes_noT(hexstr,buf,20); init_hexbytes_noT(hexstr,buf,20);
} }
bits256 bits256_sha256(bits256 data)
{
bits256 hash;
vcalc_sha256(0,hash.bytes,data.bytes,sizeof(data));
return(hash);
}
void bits256_rmd160(uint8_t rmd160[20],bits256 data)
{
calc_rmd160(0,rmd160,data.bytes,sizeof(data));
}
void bits256_rmd160_sha256(uint8_t rmd160[20],bits256 data)
{
bits256 hash;
hash = bits256_sha256(data);
bits256_rmd160(rmd160,hash);
}
#ifdef ENABLE_RMDTEST #ifdef ENABLE_RMDTEST
int rmd160_test(void) int rmd160_test(void)
{ {

19
crypto777/iguana_utils.c

@ -538,6 +538,19 @@ static int _decreasing_uint64(const void *a,const void *b)
#undef uint64_b #undef uint64_b
} }
static int _decreasing_uint32(const void *a,const void *b)
{
#define uint32_a (*(uint32_t *)a)
#define uint32_b (*(uint32_t *)b)
if ( uint32_b > uint32_a )
return(1);
else if ( uint32_b < uint32_a )
return(-1);
return(0);
#undef uint32_a
#undef uint32_b
}
int32_t sortds(double *buf,uint32_t num,int32_t size) int32_t sortds(double *buf,uint32_t num,int32_t size)
{ {
qsort(buf,num,size,_increasing_double); qsort(buf,num,size,_increasing_double);
@ -556,6 +569,12 @@ int32_t revsort64s(uint64_t *buf,uint32_t num,int32_t size)
return(0); return(0);
} }
int32_t revsort32(uint32_t *buf,uint32_t num,int32_t size)
{
qsort(buf,num,size,_decreasing_uint32);
return(0);
}
/*int32_t iguana_sortbignum(void *buf,int32_t size,uint32_t num,int32_t structsize,int32_t dir) /*int32_t iguana_sortbignum(void *buf,int32_t size,uint32_t num,int32_t structsize,int32_t dir)
{ {
int32_t retval = 0; int32_t retval = 0;

10
gecko/gecko.c

@ -34,6 +34,7 @@
#include "../iguana/iguana777.h" #include "../iguana/iguana777.h"
#include "gecko_delayedPoW.c" #include "gecko_delayedPoW.c"
#include "gecko_mempool.c"
#include "gecko_miner.c" #include "gecko_miner.c"
#include "gecko_blocks.c" #include "gecko_blocks.c"
@ -483,6 +484,14 @@ char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *add
} else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}")); } else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}"));
} }
char *basilisk_respond_mempool(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 *symbol; struct iguana_info *virt;
if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 )
return(gecko_mempoolarrived(myinfo,virt,_addr,data,datalen,hash));
else return(clonestr("{\"error\":\"couldt find gecko chain\"}"));
}
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_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; char *symbol; struct iguana_info *virt;
@ -568,7 +577,6 @@ HASH_ARRAY_STRING(basilisk,newgeckochain,hash,vals,hexstr)
{ {
if ( basilisk_geckochain(myinfo,symbol,chainname,argvals) != 0 ) if ( basilisk_geckochain(myinfo,symbol,chainname,argvals) != 0 )
jaddstr(argvals,"status","active"); jaddstr(argvals,"status","active");
//free_json(argvals);
} else jaddstr(argvals,"error","couldnt initialize geckochain"); } else jaddstr(argvals,"error","couldnt initialize geckochain");
free(retstr); free(retstr);
return(jprint(argvals,1)); return(jprint(argvals,1));

17
gecko/gecko.h

@ -36,12 +36,20 @@ 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_sequence { struct hashstamp *stamps; int32_t lastupdate,maxstamps,numstamps,lasti,longestchain; };
struct gecko_sequences { struct gecko_sequence BTC,BTCD; }; 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_memtx
{
double feeperkb;
bits256 txid;
uint32_t ipbits;
int64_t txfee,inputsum,outputsum; int32_t pending,numinputs,numoutputs,datalen;
uint8_t data[];
};
struct gecko_mempool struct gecko_mempool
{ {
int32_t numtx; int32_t numtx; uint32_t ipbits;
struct gecko_mempooltx txs[100]; bits256 txids[0xffff];
struct gecko_memtx **txs;
}; };
struct gecko_chain struct gecko_chain
@ -66,7 +74,10 @@ void gecko_seqresult(struct supernet_info *myinfo,char *retstr);
int32_t gecko_sequpdate(char *symbol,uint32_t reftimestamp); 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_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_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2);
char *gecko_mempoolarrived(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_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); char *gecko_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *data,int32_t datalen,bits256 txid,cJSON *vals,char *signedtx);
struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct iguana_info *virt,int32_t *numotherp,uint32_t ipbits);
#endif #endif

100
gecko/gecko_blocks.c

@ -20,49 +20,61 @@ char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt
return(clonestr("{\"result\":\"gecko headers queued\"}")); return(clonestr("{\"result\":\"gecko headers queued\"}"));
} }
char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *serialized,int32_t datalen,bits256 txid) char *gecko_mempoolarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2)
{ {
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; int32_t i,j,numother,len = 0; struct gecko_mempool *otherpool; bits256 txid;
memset(&msg,0,sizeof(msg)); if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,(uint32_t)calc_ipbits(remoteaddr))) != 0 )
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); if ( numother > 0 )
vinstotal = voutstotal = 0; {
maxconf = virt->longestchain; for (i=0; i<numother; i++)
minconf = virt->chain->minconfirms; {
if ( (numvins= msg.tx_in) > 0 ) len += iguana_rwbignum(0,&data[len],sizeof(txid),txid.bytes);
{ for (j=0; j<otherpool->numtx; j++)
for (i=0; i<numvins; i++) if ( bits256_cmp(txid,otherpool->txids[j]) == 0 )
{ break;
if ( (unspentind= iguana_unspentindfind(virt,0,0,0,&value,&spentheight,msg.vins[i].prev_hash,msg.vins[i].prev_vout,virt->bundlescount-1)) != 0 ) if ( j == otherpool->numtx )
{ {
hdrsi = spentheight / virt->chain->bundlesize; otherpool->txids[otherpool->numtx++] = txid;
hdrsi_unspentind = ((uint64_t)hdrsi << 32) | unspentind; printf("if first time, submit request for txid\n");
if ( iguana_unspentavail(virt,hdrsi_unspentind,minconf,maxconf) != value ) }
{ }
printf("vin.%d already spent\n",i); }
return(clonestr("{\"error\":\"gecko tx has double spend\"}")); }
} return(clonestr("{\"result\":\"gecko mempool queued\"}"));
vinstotal += value; }
}
} void gecko_txidpurge(struct iguana_info *virt,bits256 txid)
} {
if ( (numvouts= msg.tx_out) > 0 ) struct gecko_mempool *pool; int32_t i,n; struct gecko_memtx *memtx;
for (i=0; i<numvouts; i++) if ( (pool= virt->mempool) != 0 && pool->txs != 0 && (n= pool->numtx) )
voutstotal += msg.vouts[i].value; {
if ( (txfee= (vinstotal - voutstotal)) < 0 ) for (i=0; i<n; i++)
return(clonestr("{\"error\":\"gecko tx has more spends than inputs\"}")); {
if ( txlen <= 0 ) if ( (memtx= pool->txs[i]) != 0 && bits256_cmp(txid,memtx->txid) == 0 )
return(clonestr("{\"error\":\"couldnt decode gecko tx\"}")); {
if ( (pool= virt->mempool) == 0 ) free(pool->txs[i]);
pool = virt->mempool = calloc(1,sizeof(*pool)); pool->txs[i] = pool->txs[--pool->numtx];
mtx = &pool->txs[pool->numtx]; }
memset(mtx,0,sizeof(*mtx)); }
mtx->txid = txid; }
mtx->txfee = txfee; if ( virt->RELAYNODE != 0 )
mtx->ipbits = (uint32_t)calc_ipbits(remoteaddr); {
mtx->rawtx = calloc(1,datalen*2 + 1); for (i=0; i<IGUANA_MAXRELAYS; i++)
init_hexbytes_noT(mtx->rawtx,serialized,datalen); {
return(clonestr("{\"result\":\"gecko tx queued\"}")); if ( (pool= virt->mempools[i]) != 0 && (n= pool->numtx) != 0 )
{
for (i=0; i<n; i++)
{
if ( bits256_cmp(txid,pool->txids[i]) == 0 )
{
pool->txids[i] = pool->txids[--pool->numtx];
memset(pool->txids[pool->numtx].bytes,0,sizeof(pool->txids[pool->numtx]));
}
}
}
}
}
} }
struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_block *block,int32_t origheight,int32_t depth) struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_block *block,int32_t origheight,int32_t depth)
@ -131,7 +143,7 @@ struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_
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) 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; struct iguana_peer *addr; int32_t i,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 ) 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); iguana_blockcopy(virt->chain->zcash,virt->chain->auxpow,virt,block,(struct iguana_block *)&txdata->zblock);
@ -156,6 +168,8 @@ int32_t gecko_hwmset(struct iguana_info *virt,struct iguana_txblock *txdata,stru
iguana_bundlepurgefiles(virt,prevbp); iguana_bundlepurgefiles(virt,prevbp);
iguana_savehdrs(virt); iguana_savehdrs(virt);
iguana_bundlevalidate(virt,prevbp,1); iguana_bundlevalidate(virt,prevbp,1);
for (i=0; i<block->RO.txn_count; i++)
gecko_txidpurge(virt,txarray[i].txid);
} }
} }
//printf("created block.%d [%d:%d] %d\n",block->height,bp!=0?bp->hdrsi:-1,block->height%virt->chain->bundlesize,bp->numsaved); //printf("created block.%d [%d:%d] %d\n",block->height,bp!=0?bp->hdrsi:-1,block->height%virt->chain->bundlesize,bp->numsaved);

293
gecko/gecko_mempool.c

@ -0,0 +1,293 @@
/******************************************************************************
* 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. *
* *
******************************************************************************/
// included from gecko.c
// struct gecko_memtx { bits256 txid; char *rawtx; int64_t txfee; int32_t pending; uint32_t ipbits; };
struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct iguana_info *virt,int32_t *numotherp,uint32_t ipbits)
{
int32_t j,firstz,numother; bits256 *othertxids; struct gecko_mempool *otherpool = 0;
othertxids = 0;
numother = firstz = 0;
for (j=0; j<myinfo->numrelays; j++)
{
if ( (otherpool= virt->mempools[j]) != 0 )
{
if ( otherpool->ipbits == ipbits )
{
othertxids = otherpool->txids;
numother = otherpool->numtx;
break;
}
} else firstz = j;
}
if ( j == myinfo->numrelays )
{
virt->mempools[firstz] = otherpool = calloc(1,sizeof(struct gecko_mempool));
otherpool->ipbits = (uint32_t)ipbits;
}
return(otherpool);
}
void gecko_mempool_sync(struct supernet_info *myinfo,struct iguana_info *virt,bits256 *reftxids,int32_t numtx)
{
int32_t i,j,k,n,num,numother; struct iguana_peer *addr; bits256 txid,*txids; struct gecko_mempool *pool,*otherpool;
if ( (pool= virt->mempool) == 0 )
return;
n = sqrt(myinfo->numrelays) + 2;
i = (myinfo->myaddr.myipbits % n);
txids = calloc(pool->numtx,sizeof(bits256));
for (; i<myinfo->numrelays; i+=n)
{
if ( (addr= iguana_peerfindipbits(virt,myinfo->relaybits[i],1)) != 0 )
{
if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,myinfo->relaybits[i])) != 0 )
{
for (j=num=0; j<pool->numtx; j++)
{
txid = reftxids[j];
if ( numother > 0 )
{
for (k=0; k<numother; k++)
if ( bits256_cmp(txid,otherpool->txids[k]) == 0 )
break;
if ( k != numother )
continue;
}
txids[num++] = txid;
}
if ( num > 0 )
basilisk_headers_send(myinfo,virt,addr,txids,num);
}
}
}
free(txids);
}
uint8_t *gecko_txdata(struct gecko_memtx *memtx)
{
return(&memtx->data[memtx->numoutputs * sizeof(int64_t) + memtx->numinputs * sizeof(bits256)]);
}
int64_t *gecko_valueptr(struct gecko_memtx *memtx,int32_t vout)
{
return((int64_t *)&memtx->data[memtx->numinputs * sizeof(bits256) + vout*sizeof(int64_t)]);
}
int32_t gecko_memtxcmp(struct gecko_memtx *memtxA,struct gecko_memtx *memtxB)
{
int32_t i,numdiff; int64_t valA,valB,diff;
if ( memtxA->numinputs == memtxB->numinputs && memtxA->numoutputs == memtxB->numoutputs )
{
for (i=0; i<memtxA->numinputs; i++)
{
if ( bits256_cmp(*(bits256 *)&memtxA->data[i * sizeof(bits256)],*(bits256 *)&memtxB->data[i * sizeof(bits256)]) != 0 )
return(-1 - 2*i);
}
for (i=numdiff=0; i<memtxA->numoutputs; i++)
{
valA = *gecko_valueptr(memtxA,i);
valB = *gecko_valueptr(memtxB,i);
if ( (diff= valA - valB) < 0 )
diff = -diff;
if ( diff > 100000 )
return(-1);
if ( valA != valB )
numdiff++;
}
if ( numdiff > 1 )
return(-memtxA->numinputs*2 - 2);
return(0);
}
return(-1);
}
struct gecko_memtx *gecko_unspentfind(struct gecko_memtx ***ptrpp,struct iguana_info *virt,bits256 txid)
{
struct gecko_mempool *pool; int32_t i; struct gecko_memtx *memtx;
if ( (pool= virt->mempool) != 0 )
{
for (i=0; i<pool->numtx; i++)
if ( (memtx= pool->txs[i]) != 0 && bits256_cmp(memtx->txid,txid) == 0 )
{
if ( ptrpp != 0 )
*ptrpp = &pool->txs[i];
return(memtx);
}
}
return(0);
}
struct gecko_memtx *gecko_mempool_txadd(struct supernet_info *myinfo,struct iguana_info *virt,char *rawtx,uint32_t senderbits)
{
struct gecko_memtx *spentmemtx,**ptrp,*memtx = 0; uint8_t *extraspace; char *str; struct iguana_msgtx msgtx; int32_t i,len,extralen = 65536; cJSON *retjson; int64_t *amountptr;
extraspace = calloc(1,extralen);
if ( (str= iguana_validaterawtx(myinfo,virt,&msgtx,extraspace,extralen,rawtx,1)) != 0 )
{
if ( (retjson= cJSON_Parse(str)) != 0 )
{
if ( jobj(retjson,"error") == 0 )
{
len = (int32_t)strlen(rawtx) >> 1;
memtx = calloc(1,sizeof(*memtx) + len + msgtx.numoutputs * sizeof(int64_t) + msgtx.numinputs * sizeof(bits256));
memtx->numinputs = msgtx.numinputs;
memtx->numoutputs = msgtx.numoutputs;
memtx->inputsum = msgtx.inputsum;
memtx->outputsum = msgtx.outputsum;
memtx->txfee = msgtx.txfee;
memtx->txid = msgtx.txid;
memtx->ipbits = senderbits;
memtx->datalen = len;
memtx->feeperkb = dstr(memtx->txfee) / (memtx->datalen / 1024.);
for (i=0; i<msgtx.numoutputs; i++)
*gecko_valueptr(memtx,i) = msgtx.vouts[i].value;
decode_hex(gecko_txdata(memtx),len,rawtx);
for (i=0; i<msgtx.numinputs; i++)
memcpy(&memtx->data[i * sizeof(bits256)],msgtx.vins[i].prev_hash.bytes,sizeof(bits256));
for (i=0; i<msgtx.numinputs; i++)
{
if ( (spentmemtx= gecko_unspentfind(&ptrp,virt->mempool,msgtx.vins[i].prev_hash)) != 0 )
{
amountptr = gecko_valueptr(spentmemtx,msgtx.vins[i].prev_vout);
if ( *amountptr < 0 )
{
if ( gecko_memtxcmp(spentmemtx,memtx) != 0 || memtx->txfee <= spentmemtx->txfee )
{
printf("already spent mempool error\n"); // check for replacment!
free(memtx);
}
else
{
printf("replace identical vins/vouts with higher txfee\n");
free(spentmemtx);
*ptrp = memtx;
}
memtx = 0;
free_json(retjson);
free(extraspace);
free(str);
return(0);
}
}
}
for (i=0; i<msgtx.numinputs; i++)
{
if ( (spentmemtx= gecko_unspentfind(0,virt->mempool,msgtx.vins[i].prev_hash)) != 0 )
{
amountptr = gecko_valueptr(spentmemtx,msgtx.vins[i].prev_vout);
*amountptr = -(*amountptr);
}
}
} else printf("gecko_mempool_txadd had error.(%s)\n",str);
free_json(retjson);
} else printf("gecko_mempool_txadd couldnt parse.(%s)\n",str);
free(str);
}
free(extraspace);
return(memtx);
}
char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *serialized,int32_t datalen,bits256 txid)
{
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 iguana_msgtx msg; char *rawtx; struct gecko_memtx *memtx;
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,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));
pool->txs = calloc(0xffff,sizeof(*pool->txs));
}
rawtx = calloc(1,datalen*2 + 1);
init_hexbytes_noT(rawtx,serialized,datalen);
if ( (memtx= gecko_mempool_txadd(myinfo,virt,rawtx,(uint32_t)calc_ipbits(remoteaddr))) != 0 )
{
for (i=0; i<pool->numtx; i++)
{
if ( memtx->feeperkb >= pool->txs[i]->feeperkb )
break;
}
pool->txs[pool->numtx++] = pool->txs[i];
pool->txs[i] = memtx;
for (i=0; i<pool->numtx; i++)
pool->txids[i] = pool->txs[i]->txid;
if ( myinfo->IAMRELAY != 0 )
gecko_mempool_sync(myinfo,virt,pool->txids,pool->numtx);
}
free(rawtx);
return(clonestr("{\"result\":\"gecko tx queued\"}"));
}
struct gecko_memtx **gecko_mempool_txptrs(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; struct gecko_memtx **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;
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];
pool->txs[i]->pending = height;
}
}
*rewardp = (reward + txfees);
if ( (*txn_countp= n) != 0 )
return(txptrs);
else return(0);
}

70
gecko/gecko_miner.c

@ -137,10 +137,9 @@ char *gecko_coinbasestr(struct supernet_info *myinfo,struct iguana_info *virt,bi
return(rawtx); 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,double expiration,uint8_t *minerpubkey,int64_t blockreward) char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_block *newblock,uint32_t *noncep,struct gecko_memtx **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; struct iguana_info *btcd; uint8_t serialized[sizeof(*newblock)],space[16384]; int32_t i,n,len,totaltxlen=0; char *coinbasestr,*blockstr=0; bits256 *txids=0,txspace[256],threshold; struct gecko_memtx *memtx;
//char str[65]; printf("prevblock.%s\n",bits256_str(str,newblock->RO.prev_block));
if ( (btcd= iguana_coinfind("BTCD")) == 0 ) if ( (btcd= iguana_coinfind("BTCD")) == 0 )
{ {
printf("basilisk needs BTCD\n"); printf("basilisk needs BTCD\n");
@ -155,17 +154,11 @@ char *gecko_block(struct supernet_info *myinfo,struct iguana_info *virt,struct i
{ {
for (i=0; i<txn_count; i++) for (i=0; i<txn_count; i++)
{ {
if ( (txdata= get_dataptr(BASILISK_HDROFFSET,&allocptr,&txlen,space,sizeof(space),txptrs[i])) == 0 ) if ( (memtx= txptrs[i]) != 0 )
{ {
printf("gecko_block error tx.%d\n",i); totaltxlen += memtx->datalen;
if ( txids != txspace ) txids[i + 1] = memtx->txid;
free(txids);
return(0);
} }
totaltxlen += txlen;
txids[i+1] = bits256_doublesha256(0,txdata,txlen);
if ( allocptr != 0 )
free(allocptr);
} }
} }
if ( (coinbasestr= gecko_coinbasestr(myinfo,virt,&txids[0],newblock->RO.timestamp,minerpubkey,blockreward,coinbase,coinbaselen,coinbasespend)) != 0 ) if ( (coinbasestr= gecko_coinbasestr(myinfo,virt,&txids[0],newblock->RO.timestamp,minerpubkey,blockreward,coinbase,coinbaselen,coinbasespend)) != 0 )
@ -194,8 +187,15 @@ char *gecko_block(struct supernet_info *myinfo,struct iguana_info *virt,struct i
init_hexbytes_noT(blockstr,serialized,n); init_hexbytes_noT(blockstr,serialized,n);
//printf("block.(%s) coinbase.(%s) lens.%ld\n",blockstr,coinbasestr,(strlen(blockstr)+strlen(coinbasestr))/2); //printf("block.(%s) coinbase.(%s) lens.%ld\n",blockstr,coinbasestr,(strlen(blockstr)+strlen(coinbasestr))/2);
strcat(blockstr,coinbasestr); strcat(blockstr,coinbasestr);
len = (int32_t)strlen(blockstr);
for (i=0; i<txn_count; i++) for (i=0; i<txn_count; i++)
strcat(blockstr,txptrs[i]); {
if ( (memtx= txptrs[i]) != 0 )
{
init_hexbytes_noT(&blockstr[len],gecko_txdata(memtx),memtx->datalen);
len += memtx->datalen << 1;
}
}
} }
free(coinbasestr); free(coinbasestr);
} }
@ -204,7 +204,7 @@ char *gecko_block(struct supernet_info *myinfo,struct iguana_info *virt,struct i
return(blockstr); 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,int32_t maxmillis,uint8_t *minerpubkey,int64_t blockreward) char *gecko_createblock(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,struct iguana_block *newblock,char *symbol,struct gecko_memtx **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; 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); //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); return(0);
} }
nonce = 0; nonce = 0;
return(gecko_block(myinfo,btcd,newblock,&nonce,txptrs,txn_count,coinbase,coinbaselen,btcdhash,expiration,minerpubkey,blockreward)); return(gecko_blockconstruct(myinfo,btcd,newblock,&nonce,txptrs,txn_count,coinbase,coinbaselen,btcdhash,expiration,minerpubkey,blockreward));
} else return(0); } else return(0);
} }
@ -275,40 +275,6 @@ cJSON *gecko_paymentsobj(struct supernet_info *myinfo,cJSON *txjson,cJSON *valso
return(txjson); return(txjson);
} }
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;
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) 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; uint8_t *data,space[16384],*allocptr=0; int32_t i,len,numranked=0; struct iguana_peers *peers; struct iguana_peer *addr;
@ -331,7 +297,7 @@ 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,uint8_t *minerpubkey33) 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; int64_t reward = 0; int32_t txn_count; char *blockstr,*space[256]; void **txptrs,*ptr; //struct iguana_bundle *bp; struct iguana_zblock newblock; uint32_t nBits; int64_t reward = 0; int32_t txn_count; char *blockstr,*space[256]; struct gecko_memtx **txptrs; void *ptr; //struct iguana_bundle *bp;
if ( virt->virtualchain == 0 ) if ( virt->virtualchain == 0 )
return; return;
memset(&newblock,0,sizeof(newblock)); memset(&newblock,0,sizeof(newblock));
@ -343,9 +309,9 @@ void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct ig
{ {
newblock.RO.bits = nBits; newblock.RO.bits = nBits;
//printf("mine.%s nBits.%x ht.%d\n",virt->symbol,nBits,newblock.height); //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); txptrs = gecko_mempool_txptrs(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); //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,(char **)txptrs,txn_count,maxmillis,minerpubkey33,reward)) != 0 ) if ( (blockstr= gecko_createblock(myinfo,btcd,virt->chain->isPoS,(void *)&newblock,virt->symbol,txptrs,txn_count,maxmillis,minerpubkey33,reward)) != 0 )
{ {
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)); 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); gecko_blocksubmit(myinfo,virt,blockstr,newblock.RO.hash2);

2
iguana/coins/btcd

@ -1 +1 @@
curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":18,\"endpend\":4,\"services\":129,\"maxpeers\":256,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631}" curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":18,\"endpend\":4,\"services\":129,\"maxpeers\":256,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,"rpc":14632}"

2
iguana/coins/genltc

@ -1,2 +1,2 @@
curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9334,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}"

2
iguana/coins/ltc

@ -1,2 +1,2 @@
curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":11,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9334,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":11,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}"

9
iguana/exchanges/bitcoin.c

@ -22,15 +22,6 @@ char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *meth
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params)); return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params));
} }
int32_t bitcoin_pubkeylen(const uint8_t *pubkey)
{
if ( pubkey[0] == 2 || pubkey[0] == 3 )
return(33);
else if ( pubkey[0] == 4 )
return(65);
else return(-1);
}
int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr)
{ {
bits256 hash; uint8_t *buf,_buf[25]; int32_t len; bits256 hash; uint8_t *buf,_buf[25]; int32_t len;

4
iguana/iguana777.c

@ -750,7 +750,7 @@ void iguana_coinloop(void *arg)
{ {
//fprintf(stderr,"check possible\n"); //fprintf(stderr,"check possible\n");
if ( coin->peers->numranked > 0 && (now % 60) == 0 ) if ( coin->peers->numranked > 0 && (now % 60) == 0 )
iguana_send_ping(coin,coin->peers->ranked[rand() % coin->peers->numranked]); iguana_send_ping(myinfo,coin,coin->peers->ranked[rand() % coin->peers->numranked]);
coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers
} }
} }
@ -759,7 +759,7 @@ void iguana_coinloop(void *arg)
if ( coin->MAXPEERS > 1 && coin->peers->numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible ) if ( coin->MAXPEERS > 1 && coin->peers->numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible )
{ {
if ( coin->peers->numranked > 0 && (now % 60) == 0 ) if ( coin->peers->numranked > 0 && (now % 60) == 0 )
iguana_send_ping(coin,coin->peers->ranked[rand() % coin->peers->numranked]); iguana_send_ping(myinfo,coin,coin->peers->ranked[rand() % coin->peers->numranked]);
coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers
} }
} }

2
iguana/iguana_accept.c

@ -306,7 +306,7 @@ int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t ma
int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2) 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,n,hdrsi,bundlei,bundlesize,firstvout,retval=-1; struct iguana_block *block; 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 ) if ( (firstvout= iguana_unspentindfind(coin,0,0,0,0,&height,hash2,0,coin->bundlescount-1,0)) != 0 )
{ {
bundlesize = coin->chain->bundlesize; bundlesize = coin->chain->bundlesize;
hdrsi = (height / bundlesize); hdrsi = (height / bundlesize);

1229
iguana/iguana_interpreter.c

File diff suppressed because it is too large

4
iguana/iguana_msg.c

@ -429,7 +429,7 @@ void iguana_gotping(struct iguana_info *coin,struct iguana_peer *addr,uint64_t n
iguana_supernet_ping(addr); iguana_supernet_ping(addr);
} }
int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr) int32_t iguana_send_ping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr)
{ {
int32_t len; uint64_t nonce; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)]; int32_t len; uint64_t nonce; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)];
if ( (nonce= addr->pingnonce) == 0 ) if ( (nonce= addr->pingnonce) == 0 )
@ -442,6 +442,8 @@ int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr)
iguana_queue_send(addr,0,serialized,"getaddr",0); iguana_queue_send(addr,0,serialized,"getaddr",0);
len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce); len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce);
iguana_supernet_ping(addr); iguana_supernet_ping(addr);
if ( myinfo->IAMRELAY != 0 )
basilisk_relays_send(myinfo,addr);
return(iguana_queue_send(addr,0,serialized,"ping",len)); return(iguana_queue_send(addr,0,serialized,"ping",len));
} }

63
iguana/iguana_payments.c

@ -237,7 +237,7 @@ cJSON *iguana_inputsjson(struct supernet_info *myinfo,struct iguana_info *coin,i
u = &U[unspentind]; u = &U[unspentind];
if ( (txidind= u->txidind) > 0 && txidind < rdata->numtxids ) if ( (txidind= u->txidind) > 0 && txidind < rdata->numtxids )
{ {
if ( iguana_unspentindfind(coin,coinaddr,spendscript,&spendlen,&amount,&height,T[txidind].txid,u->vout,coin->bundlescount-1) == unspentind && spendlen > 0 ) if ( iguana_unspentindfind(coin,coinaddr,spendscript,&spendlen,&amount,&height,T[txidind].txid,u->vout,coin->bundlescount-1,0) == unspentind && spendlen > 0 )
{ {
item = cJSON_CreateObject(); item = cJSON_CreateObject();
jaddbits256(item,"txid",T[txidind].txid); jaddbits256(item,"txid",T[txidind].txid);
@ -631,7 +631,7 @@ HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool)
if ( coin != 0 ) if ( coin != 0 )
{ {
minconf = (mempool != 0) ? 0 : 1; minconf = (mempool != 0) ? 0 : 1;
if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1)) != 0 ) if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) != 0 )
{ {
if ( height >= 0 && height < coin->longestchain && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 ) if ( height >= 0 && height < coin->longestchain && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 )
{ {
@ -816,19 +816,17 @@ HASH_AND_INT(bitcoinrpc,getrawtransaction,txid,verbose)
return(clonestr("{\"error\":\"cant find txid\"}")); return(clonestr("{\"error\":\"cant find txid\"}"));
} }
STRING_ARG(bitcoinrpc,validaterawtransaction,rawtx) char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool)
{ {
bits256 txid,signedtxid; struct iguana_msgtx msgtx; struct iguana_msgvin vin; cJSON *log,*vins,*txobj,*retjson; char *checkstr,*signedtx; int32_t i,len,maxsize,numinputs,complete,extralen=65536; struct vin_info *V; uint8_t *serialized,*serialized2,*extraspace; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; bits256 txid,signedtxid; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *checkstr,*signedtx; int32_t i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
inputsum = outputsum = numinputs = numoutputs = 0;
if ( rawtx != 0 && rawtx[0] != 0 && coin != 0 ) if ( rawtx != 0 && rawtx[0] != 0 && coin != 0 )
{ {
if ( (strlen(rawtx) & 1) != 0 ) if ( (strlen(rawtx) & 1) != 0 )
return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); return(clonestr("{\"error\":\"rawtx hex has odd length\"}"));
memset(&msgtx,0,sizeof(msgtx)); memset(msgtx,0,sizeof(*msgtx));
extraspace = calloc(1,extralen); if ( (txobj= bitcoin_hex2json(coin,&txid,msgtx,rawtx,extraspace,extralen,0)) != 0 )
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,rawtx,extraspace,extralen,0)) != 0 )
{ {
//printf("txobj.(%s)\n",jprint(txobj,0)); //printf("txobj.(%s)\n",jprint(txobj,0));
if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 )
@ -843,7 +841,7 @@ STRING_ARG(bitcoinrpc,validaterawtransaction,rawtx)
break; break;
jaddnum(retjson,"mismatch position",i); jaddnum(retjson,"mismatch position",i);
jadd(retjson,"origtx",txobj); jadd(retjson,"origtx",txobj);
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,checkstr,extraspace,extralen,0)) != 0 ) if ( (txobj= bitcoin_hex2json(coin,&txid,msgtx,checkstr,extraspace,extralen,0)) != 0 )
jadd(retjson,"checktx",txobj); jadd(retjson,"checktx",txobj);
free(checkstr); free(checkstr);
free(extraspace); free(extraspace);
@ -851,6 +849,15 @@ STRING_ARG(bitcoinrpc,validaterawtransaction,rawtx)
} }
free(checkstr); free(checkstr);
} }
if ( (vouts= jarray(&numoutputs,txobj,"vout")) > 0 )
{
struct iguana_msgvout vout; uint8_t voutdata[IGUANA_MAXSCRIPTSIZE];
for (i=0; i<numoutputs; i++)
{
if ( iguana_parsevoutobj(coin,voutdata,sizeof(voutdata),&vout,jitem(vouts,i)) > 0 )
outputsum += vout.value;
}
}
if ( (vins= jarray(&numinputs,txobj,"vin")) > 0 ) if ( (vins= jarray(&numinputs,txobj,"vin")) > 0 )
{ {
maxsize = (int32_t)strlen(rawtx); maxsize = (int32_t)strlen(rawtx);
@ -861,18 +868,19 @@ STRING_ARG(bitcoinrpc,validaterawtransaction,rawtx)
for (i=0; i<numinputs; i++) for (i=0; i<numinputs; i++)
{ {
len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize-len,&vin,jitem(vins,i),&V[i]); len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize-len,&vin,jitem(vins,i),&V[i]);
if ( (V[i].unspentind= iguana_unspentindfind(coin,V[i].coinaddr,V[i].spendscript,&V[i].spendlen,&V[i].amount,&V[i].height,msgtx.vins[i].prev_hash,msgtx.vins[i].prev_vout,coin->bundlescount-1)) > 0 ) if ( (V[i].unspentind= iguana_unspentindfind(coin,V[i].coinaddr,V[i].spendscript,&V[i].spendlen,&V[i].amount,&V[i].height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,mempool)) > 0 )
{ {
msgtx.vins[i].spendscript = V[i].spendscript; inputsum += V[i].amount;
msgtx.vins[i].spendlen = V[i].spendlen; msgtx->vins[i].spendscript = V[i].spendscript;
V[i].hashtype = iguana_vinscriptparse(coin,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx.vins[i].vinscript,msgtx.vins[i].scriptlen); msgtx->vins[i].spendlen = V[i].spendlen;
V[i].hashtype = iguana_vinscriptparse(coin,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen);
V[i].suffixlen = suffixlen; V[i].suffixlen = suffixlen;
memcpy(V[i].spendscript,msgtx.vins[i].spendscript,msgtx.vins[i].spendlen); memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen);
V[i].spendlen = msgtx.vins[i].spendlen; V[i].spendlen = msgtx->vins[i].spendlen;
//printf("V %.8f (%s) spendscript.[%d] scriptlen.%d\n",dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen); //printf("V %.8f (%s) spendscript.[%d] scriptlen.%d\n",dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen);
} }
} }
if ( (complete= bitcoin_verifyvins(coin,&signedtxid,&signedtx,&msgtx,serialized2,maxsize,V,1)) > 0 && signedtx != 0 ) if ( (complete= bitcoin_verifyvins(coin,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,1,0)) > 0 && signedtx != 0 )
{ {
log = cJSON_CreateArray(); log = cJSON_CreateArray();
if ( iguana_interpreter(coin,log,j64bits(txobj,"locktime"),V,numinputs) < 0 ) if ( iguana_interpreter(coin,log,j64bits(txobj,"locktime"),V,numinputs) < 0 )
@ -883,14 +891,29 @@ STRING_ARG(bitcoinrpc,validaterawtransaction,rawtx)
} }
jaddnum(retjson,"complete",complete); jaddnum(retjson,"complete",complete);
free(serialized), free(serialized2); free(serialized), free(serialized2);
free(extraspace);
} }
} }
//char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid));
} }
msgtx->inputsum = inputsum;
msgtx->numinputs = numinputs;
msgtx->outputsum = outputsum;
msgtx->numoutputs = numoutputs;
msgtx->txfee = (inputsum - outputsum);
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
STRING_ARG(bitcoinrpc,validaterawtransaction,rawtx)
{
uint8_t *extraspace; char *retstr; struct iguana_msgtx msgtx; int32_t extralen=65536;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
extraspace = calloc(1,extralen);
retstr = iguana_validaterawtx(myinfo,coin,&msgtx,extraspace,extralen,rawtx,0);
free(extraspace);
return(retstr);
}
STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx) STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx)
{ {
cJSON *txobj = 0; bits256 txid; uint8_t *extraspace; int32_t extralen = 65536; cJSON *txobj = 0; bits256 txid; uint8_t *extraspace; int32_t extralen = 65536;
@ -943,7 +966,7 @@ cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,c
spendlen = (int32_t)strlen(hexstr) >> 1; spendlen = (int32_t)strlen(hexstr) >> 1;
decode_hex(spendscript,spendlen,hexstr); decode_hex(spendscript,spendlen,hexstr);
} }
if ( (unspentind= iguana_unspentindfind(coin,coinaddr,spendscript,&spendlen,&satoshis,&height,txid,vout,coin->bundlescount-1)) > 0 ) if ( (unspentind= iguana_unspentindfind(coin,coinaddr,spendscript,&spendlen,&satoshis,&height,txid,vout,coin->bundlescount-1,0)) > 0 )
{ {
//printf("[%d] unspentind.%d (%s) spendlen.%d %.8f\n",height/coin->chain->bundlesize,unspentind,coinaddr,spendlen,dstr(satoshis)); //printf("[%d] unspentind.%d (%s) spendlen.%d %.8f\n",height/coin->chain->bundlesize,unspentind,coinaddr,spendlen,dstr(satoshis));
if ( coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) if ( coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 )
@ -1099,7 +1122,7 @@ INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array)
{ {
txid = jbits256(item,"txid"); txid = jbits256(item,"txid");
vout = jint(item,"vout"); vout = jint(item,"vout");
if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1)) != 0 ) if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) != 0 )
{ {
hdrsi = height / coin->chain->bundlesize; hdrsi = height / coin->chain->bundlesize;
iguana_utxofind(coin,hdrsi,unspentind,&RTspendflag,!flag); iguana_utxofind(coin,hdrsi,unspentind,&RTspendflag,!flag);

31
iguana/iguana_peers.c

@ -46,6 +46,31 @@ int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H)
return(len); return(len);
} }
struct iguana_peer *iguana_peeralive(struct iguana_peer *addr,int32_t needalive)
{
if ( needalive == 0 || (addr->usock >= 0 && addr->dead == 0) )
return(addr);
else return(0);
}
struct iguana_peer *iguana_peerfindipaddr(struct iguana_info *coin,char *ipaddr,int32_t needalive)
{
int32_t i;
for (i=0; i<IGUANA_MAXPEERS; i++)
if ( strcmp(ipaddr,coin->peers->active[i].ipaddr) == 0 )
return(iguana_peeralive(&coin->peers->active[i],needalive));
return(0);
}
struct iguana_peer *iguana_peerfindipbits(struct iguana_info *coin,uint32_t ipbits,int32_t needalive)
{
int32_t i;
for (i=0; i<IGUANA_MAXPEERS; i++)
if ( ipbits == coin->peers->active[i].ipbits )
return(iguana_peeralive(&coin->peers->active[i],needalive));
return(0);
}
struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint32_t ipbits,int32_t itemind) struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint32_t ipbits,int32_t itemind)
{ {
struct iguana_iAddr *ptr = 0; int32_t allocsize; char str[65]; struct OS_memspace *mem = 0; struct iguana_iAddr *ptr = 0; int32_t allocsize; char str[65]; struct OS_memspace *mem = 0;
@ -699,7 +724,7 @@ void iguana_startconnection(void *arg)
if ( coin->peers != 0 ) if ( coin->peers != 0 )
{ {
coin->peers->lastpeer = (uint32_t)time(NULL); coin->peers->lastpeer = (uint32_t)time(NULL);
for (i=n=0; i<coin->MAXPEERS; i++) for (i=n=0; i<IGUANA_MAXPEERS; i++)
if ( coin->peers->active[i].usock > 0 ) if ( coin->peers->active[i].usock > 0 )
n++; n++;
coin->peers->numconnected++; coin->peers->numconnected++;
@ -827,7 +852,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr)
{ {
if ( strcmp(ipaddr,"0.0.0.0") == 0 || strcmp(ipaddr,"127.0.0.1") == 0 ) if ( strcmp(ipaddr,"0.0.0.0") == 0 || strcmp(ipaddr,"127.0.0.1") == 0 )
return(0); return(0);
for (i=n=0; i<coin->MAXPEERS; i++) for (i=n=0; i<IGUANA_MAXPEERS; i++)
if ( strcmp(ipaddr,coin->peers->active[i].ipaddr) == 0 ) if ( strcmp(ipaddr,coin->peers->active[i].ipaddr) == 0 )
{ {
printf("%s possible peer.(%s) %x already there\n",coin->symbol,ipaddr,(uint32_t)coin->peers->active[i].ipbits); printf("%s possible peer.(%s) %x already there\n",coin->symbol,ipaddr,(uint32_t)coin->peers->active[i].ipbits);
@ -852,7 +877,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr)
//printf("check possible peer.(%s)\n",ipaddr); //printf("check possible peer.(%s)\n",ipaddr);
if ( iguana_peerslot(coin,(uint32_t)ipbits,0) != 0 ) if ( iguana_peerslot(coin,(uint32_t)ipbits,0) != 0 )
return((uint32_t)time(NULL)); return((uint32_t)time(NULL));
for (i=n=0; i<coin->MAXPEERS; i++) for (i=n=0; i<IGUANA_MAXPEERS; i++)
{ {
if ( strcmp(ipaddr,coin->peers->active[i].ipaddr) == 0 ) if ( strcmp(ipaddr,coin->peers->active[i].ipaddr) == 0 )
{ {

2
iguana/iguana_ramchain.c

@ -607,7 +607,7 @@ uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer
int64_t iguana_hashmemsize(int64_t numtxids,int64_t numunspents,int64_t numspends,int64_t numpkinds,int64_t numexternaltxids,int64_t scriptspace) int64_t iguana_hashmemsize(int64_t numtxids,int64_t numunspents,int64_t numspends,int64_t numpkinds,int64_t numexternaltxids,int64_t scriptspace)
{ {
int64_t allocsize = 0; int64_t allocsize = 0;
allocsize += 1.25 * (scriptspace + IGUANA_MAXSCRIPTSIZE + ((numtxids + numpkinds) * (sizeof(UT_hash_handle)*2)) + (((sizeof(struct iguana_account)) * 2 * numpkinds)) + (2 * numunspents * sizeof(struct iguana_spendvector))); allocsize += 1.5 * (scriptspace + IGUANA_MAXSCRIPTSIZE + ((numtxids + numpkinds) * (sizeof(UT_hash_handle)*2)) + (((sizeof(struct iguana_account)) * 2 * numpkinds)) + (2 * numunspents * sizeof(struct iguana_spendvector)));
if ( allocsize >= (1LL << 32) ) if ( allocsize >= (1LL << 32) )
{ {
printf("REALLY big hashmemsize %llu, truncate and hope for best\n",(long long)allocsize); printf("REALLY big hashmemsize %llu, truncate and hope for best\n",(long long)allocsize);

2
iguana/iguana_recv.c

@ -152,7 +152,7 @@ int32_t iguana_txidreq(struct iguana_info *coin,char **retstrp,bits256 txid)
coin->reqtxids[coin->numreqtxids++] = txid; coin->reqtxids[coin->numreqtxids++] = txid;
if ( coin->peers != 0 ) if ( coin->peers != 0 )
{ {
for (i=0; i<coin->MAXPEERS; i++) for (i=0; i<IGUANA_MAXPEERS; i++)
if ( coin->peers->active[i].usock >= 0 ) if ( coin->peers->active[i].usock >= 0 )
iguana_sendtxidreq(coin,coin->peers->ranked[i],txid); iguana_sendtxidreq(coin,coin->peers->ranked[i],txid);
} }

15
iguana/iguana_rpc.c

@ -23,7 +23,7 @@
char *sglue(GLUEARGS,char *agent,char *method) char *sglue(GLUEARGS,char *agent,char *method)
{ {
char *retstr,*rpcretstr,*walletstr; cJSON *retjson,*tmpjson,*result,*error,*wallet; int32_t i,j,len; char *retstr,*rpcretstr,*walletstr,checkstr[64]; cJSON *retjson,*tmpjson,*result,*error,*wallet; int32_t i,j,len; int64_t val;
if ( json == 0 ) if ( json == 0 )
json = cJSON_CreateObject(); json = cJSON_CreateObject();
//printf("sglue.(%s)\n",jprint(json,0)); //printf("sglue.(%s)\n",jprint(json,0));
@ -78,6 +78,17 @@ char *sglue(GLUEARGS,char *agent,char *method)
free(retstr); free(retstr);
return(rpcretstr); return(rpcretstr);
} }
else
{
val = atol(rpcretstr);
sprintf(checkstr,"%lld",(long long)val);
if ( strcmp(checkstr,rpcretstr) == 0 )
{
free_json(retjson);
free(retstr);
return(rpcretstr);
}
}
free(rpcretstr); free(rpcretstr);
} }
else if ( (error->type&0xff) != cJSON_NULL || (result->type&0xff) != cJSON_NULL ) else if ( (error->type&0xff) != cJSON_NULL || (result->type&0xff) != cJSON_NULL )
@ -682,6 +693,8 @@ char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,ch
} }
if ( coin == 0 && symbol[0] != 0 ) if ( coin == 0 && symbol[0] != 0 )
coin = iguana_coinfind(symbol); coin = iguana_coinfind(symbol);
if ( coin != 0 )
safecopy(symbol,coin->symbol,sizeof(symbol));
//printf("method.(%s) (%s) remote.(%s) symbol.(%s)\n",method,jprint(json,0),remoteaddr,symbol); //printf("method.(%s) (%s) remote.(%s) symbol.(%s)\n",method,jprint(json,0),remoteaddr,symbol);
if ( method != 0 && symbol[0] != 0 && (coin != 0 || (coin= iguana_coinfind(symbol)) != 0) ) if ( method != 0 && symbol[0] != 0 && (coin != 0 || (coin= iguana_coinfind(symbol)) != 0) )
{ {

126
iguana/iguana_secp.c

@ -31,6 +31,15 @@ SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc
#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 ) #define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 )
#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx); #define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx);
int32_t bitcoin_pubkeylen(const uint8_t *pubkey)
{
if ( pubkey[0] == 2 || pubkey[0] == 3 )
return(33);
else if ( pubkey[0] == 4 )
return(65);
else return(-1);
}
bits256 bitcoin_randkey(secp256k1_context *ctx) bits256 bitcoin_randkey(secp256k1_context *ctx)
{ {
int32_t i; bits256 privkey; int32_t i; bits256 privkey;
@ -39,7 +48,7 @@ bits256 bitcoin_randkey(secp256k1_context *ctx)
for (i=0; i<100; i++) for (i=0; i<100; i++)
{ {
privkey = rand256(0); privkey = rand256(0);
if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) > 0 ) if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) != 0 )
{ {
ENDSECP_ENSURE_CTX ENDSECP_ENSURE_CTX
return(privkey); return(privkey);
@ -62,7 +71,7 @@ bits256 bitcoin_pubkey33(secp256k1_context *ctx,uint8_t *data,bits256 privkey)
printf("bitcoin_sign illegal privkey\n"); printf("bitcoin_sign illegal privkey\n");
return(pubkey); return(pubkey);
} }
if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) > 0 ) if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) != 0 )
{ {
plen = 33; plen = 33;
secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED); secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED);
@ -74,6 +83,21 @@ bits256 bitcoin_pubkey33(secp256k1_context *ctx,uint8_t *data,bits256 privkey)
return(pubkey); return(pubkey);
} }
bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even)
{
bits256 pub256; uint8_t pubkey[33]; int32_t i;
for (i=0; i<100; i++)
{
*privkeyp = rand256(0);
pub256 = bitcoin_pubkey33(ctx,pubkey,*privkeyp);
if ( pubkey[0] == odd_even+2 )
return(pub256);
}
printf("bitcoin_pub256 couldnt generate pubkey.%d\n",odd_even+2);
memset(pub256.bytes,0,sizeof(pub256));
return(pub256);
}
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag) int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag)
{ {
int32_t fCompressed = 1; int32_t fCompressed = 1;
@ -87,17 +111,17 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256
printf("bitcoin_sign illegal privkey\n"); printf("bitcoin_sign illegal privkey\n");
return(-1); return(-1);
} }
if ( secp256k1_context_randomize(ctx,seed.bytes) > 0 ) if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 )
{ {
if ( recoverflag != 0 ) if ( recoverflag != 0 )
{ {
if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) > 0 ) if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 )
{ {
recid = -1; recid = -1;
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG); secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG);
if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) > 0 ) if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) != 0 )
{ {
if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) > 0 ) if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) != 0 )
{ {
if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 ) if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 )
{ {
@ -111,9 +135,9 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256
} }
else else
{ {
if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) > 0 ) if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 )
{ {
if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) > 0 ) if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 )
retval = (int32_t)siglen; retval = (int32_t)siglen;
} }
} }
@ -132,10 +156,10 @@ int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig65,bits256 mess
plen = (sig65[0] <= 31) ? 65 : 33; plen = (sig65[0] <= 31) ? 65 : 33;
secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig65 + 1,0); secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig65 + 1,0);
secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG); secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG);
if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) > 0 ) if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) != 0 )
{ {
secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED); secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED);
if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) > 0 ) if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) != 0 )
retval = 0; retval = 0;
else printf("secp256k1_ecdsa_verify error\n"); else printf("secp256k1_ecdsa_verify error\n");
} else printf("secp256k1_ecdsa_recover error\n"); } else printf("secp256k1_ecdsa_recover error\n");
@ -149,10 +173,10 @@ int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uin
int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG;
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) > 0 ) if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 )
{ {
secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen); secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen);
if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) > 0 ) if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) != 0 )
retval = 0; retval = 0;
} }
ENDSECP_ENSURE_CTX ENDSECP_ENSURE_CTX
@ -166,9 +190,9 @@ bits256 bitcoin_sharedsecret(void *ctx,bits256 privkey,uint8_t *pubkey,int32_t p
memset(shared.bytes,0,sizeof(shared)); memset(shared.bytes,0,sizeof(shared));
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) > 0 ) if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 )
{ {
if ( secp256k1_ecdh(ctx,shared.bytes,&PUB,privkey.bytes) > 0 ) if ( secp256k1_ecdh(ctx,shared.bytes,&PUB,privkey.bytes) != 0 )
retval = 0; retval = 0;
else memset(shared.bytes,0,sizeof(shared)); else memset(shared.bytes,0,sizeof(shared));
} }
@ -183,7 +207,7 @@ int32_t bitcoin_schnorr_sign(void *ctx,uint8_t *sig64,bits256 txhash2,bits256 pr
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
seed = rand256(0); seed = rand256(0);
if ( secp256k1_schnorr_sign(ctx,sig64,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,seed.bytes) > 0 ) if ( secp256k1_schnorr_sign(ctx,sig64,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,seed.bytes) != 0 )
retval = 0; retval = 0;
ENDSECP_ENSURE_CTX ENDSECP_ENSURE_CTX
} }
@ -195,9 +219,9 @@ int32_t bitcoin_schnorr_verify(void *ctx,uint8_t *sig64,bits256 txhash2,uint8_t
int32_t retval = -1; secp256k1_pubkey PUB; int32_t retval = -1; secp256k1_pubkey PUB;
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) > 0 ) if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 )
{ {
if ( secp256k1_schnorr_verify(ctx,sig64,txhash2.bytes,&PUB) > 0 ) if ( secp256k1_schnorr_verify(ctx,sig64,txhash2.bytes,&PUB) != 0 )
retval = 0; retval = 0;
} }
ENDSECP_ENSURE_CTX ENDSECP_ENSURE_CTX
@ -210,7 +234,7 @@ int32_t bitcoin_schnorr_recover(void *ctx,uint8_t *pubkey,uint8_t *sig64,bits256
int32_t retval = -1; secp256k1_pubkey PUB; size_t plen; int32_t retval = -1; secp256k1_pubkey PUB; size_t plen;
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( secp256k1_schnorr_recover(ctx,&PUB,sig64,txhash2.bytes) > 0 ) if ( secp256k1_schnorr_recover(ctx,&PUB,sig64,txhash2.bytes) != 0 )
{ {
plen = 33; plen = 33;
secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED); secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED);
@ -229,7 +253,7 @@ bits256 bitcoin_schnorr_noncepair(void *ctx,uint8_t *pubnonce,bits256 txhash2,bi
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
seed = rand256(0); seed = rand256(0);
if ( secp256k1_schnorr_generate_nonce_pair(ctx,&PUB,privnonce.bytes,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,seed.bytes) > 0 ) if ( secp256k1_schnorr_generate_nonce_pair(ctx,&PUB,privnonce.bytes,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,seed.bytes) != 0 )
{ {
plen = 33; plen = 33;
secp256k1_ec_pubkey_serialize(ctx,pubnonce,&plen,&PUB,SECP256K1_EC_COMPRESSED); secp256k1_ec_pubkey_serialize(ctx,pubnonce,&plen,&PUB,SECP256K1_EC_COMPRESSED);
@ -240,6 +264,50 @@ bits256 bitcoin_schnorr_noncepair(void *ctx,uint8_t *pubnonce,bits256 txhash2,bi
return(privnonce); return(privnonce);
} }
int32_t bitcoin_pubkey_combine(void *ctx,uint8_t *combined_pub,uint8_t *skipkey,bits256 *evenkeys,int32_t n,bits256 *oddkeys,int32_t m)
{
int32_t i,num,iter,max,retval = -1; uint8_t pubkey[33]; size_t plen; secp256k1_pubkey PUBall,*PUBptrs[256],PUBkeys[256];
SECP_ENSURE_CTX
{
if ( n+m > 0 && n+m < sizeof(PUBptrs)/sizeof(*PUBptrs) )
{
for (iter=num=0; iter<2; iter++)
{
if ( (max= (iter == 0) ? n : m) != 0 )
{
for (i=0; i<max; i++)
{
PUBptrs[num] = &PUBkeys[num];
pubkey[0] = 2 + iter;
memcpy(pubkey+1,((iter == 0) ? evenkeys : oddkeys)[i].bytes,32);
if ( skipkey != 0 && memcmp(pubkey,skipkey,33) == 0 )
{
//printf("skipkey.%d\n",i);
continue;
}
if ( secp256k1_ec_pubkey_parse(ctx,PUBptrs[num],pubkey,33) == 0 )
{
int32_t j; for (j=0; j<33; j++)
printf("%02x",pubkey[j]);
printf(" error parsing pubkey iter.%d num.%d i.%d\n",iter,num,i);
break;
}
num++;
}
}
}
if ( secp256k1_ec_pubkey_combine(ctx,&PUBall,(void *)PUBptrs,num) != 0 )
{
plen = 33;
secp256k1_ec_pubkey_serialize(ctx,combined_pub,&plen,&PUBall,SECP256K1_EC_COMPRESSED);
retval = 0;
}
}
ENDSECP_ENSURE_CTX
}
return(retval);
}
int32_t bitcoin_schnorr_partialsign(void *ctx,uint8_t *sig64,uint8_t *combined_pub,bits256 txhash2,bits256 privkey,bits256 privnonce,uint8_t *pubptrs[],int32_t n) // generate and exchange int32_t bitcoin_schnorr_partialsign(void *ctx,uint8_t *sig64,uint8_t *combined_pub,bits256 txhash2,bits256 privkey,bits256 privnonce,uint8_t *pubptrs[],int32_t n) // generate and exchange
{ {
int32_t bitcoin_pubkeylen(const uint8_t *pubkey); int32_t bitcoin_pubkeylen(const uint8_t *pubkey);
@ -250,13 +318,13 @@ int32_t bitcoin_schnorr_partialsign(void *ctx,uint8_t *sig64,uint8_t *combined_p
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
PUBptrs[i] = calloc(1,sizeof(secp256k1_pubkey)); PUBptrs[i] = calloc(1,sizeof(secp256k1_pubkey));
if ( secp256k1_ec_pubkey_parse(ctx,PUBptrs[i],pubptrs[i],bitcoin_pubkeylen(pubptrs[i])) == 0 ) if ( secp256k1_ec_pubkey_parse(ctx,PUBptrs[i],pubptrs[i],bitcoin_pubkeylen(pubptrs[i])) != 0 )
break; break;
} }
if ( n > 0 && secp256k1_ec_pubkey_combine(ctx,&PUBall,(void *)PUBptrs,n) > 0 ) if ( n > 0 && secp256k1_ec_pubkey_combine(ctx,&PUBall,(void *)PUBptrs,n) != 0 )
{ {
plen = 33; plen = 33;
if ( secp256k1_schnorr_partial_sign(ctx,sig64,txhash2.bytes,privkey.bytes,&PUBall,privnonce.bytes) > 0 ) if ( secp256k1_schnorr_partial_sign(ctx,sig64,txhash2.bytes,privkey.bytes,&PUBall,privnonce.bytes) != 0 )
{ {
secp256k1_ec_pubkey_serialize(ctx,combined_pub,&plen,&PUBall,SECP256K1_EC_COMPRESSED); secp256k1_ec_pubkey_serialize(ctx,combined_pub,&plen,&PUBall,SECP256K1_EC_COMPRESSED);
retval = 0; retval = 0;
@ -273,7 +341,7 @@ int32_t bitcoin_schnorr_combine(void *ctx,uint8_t *sig64,uint8_t *allpub,uint8_t
int32_t rc,retval = -1; int32_t rc,retval = -1;
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( (rc= secp256k1_schnorr_partial_combine(ctx,sig64,(void *)sigs,n)) > 0 ) if ( (rc= secp256k1_schnorr_partial_combine(ctx,sig64,(void *)sigs,n)) != 0 )
{ {
if ( bitcoin_schnorr_recover(ctx,allpub,sig64,txhash2) == 0 ) if ( bitcoin_schnorr_recover(ctx,allpub,sig64,txhash2) == 0 )
{ {
@ -291,7 +359,7 @@ int32_t bitcoin_pederson_commit(void *ctx,uint8_t *commit,bits256 blind,uint64_t
int32_t retval = -1; int32_t retval = -1;
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( secp256k1_pedersen_commit(ctx,commit,blind.bytes,value) > 0 ) if ( secp256k1_pedersen_commit(ctx,commit,blind.bytes,value) != 0 )
retval = 0; retval = 0;
ENDSECP_ENSURE_CTX ENDSECP_ENSURE_CTX
} }
@ -316,7 +384,7 @@ int32_t bitcoin_pederson_tally(void *ctx,uint8_t **commits,int32_t n,int32_t num
int32_t retval = -1; int32_t retval = -1;
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( secp256k1_pedersen_verify_tally(ctx,(void *)commits,numpos,(void *)&commits[numpos],n - numpos,excess) > 0 ) if ( secp256k1_pedersen_verify_tally(ctx,(void *)commits,numpos,(void *)&commits[numpos],n - numpos,excess) != 0 )
retval = 0; retval = 0;
ENDSECP_ENSURE_CTX ENDSECP_ENSURE_CTX
} }
@ -328,7 +396,7 @@ int32_t bitcoin_rangeproof_message(void *ctx,uint8_t *blind_out,uint8_t *message
int32_t outlen = 0,retval = -1; int32_t outlen = 0,retval = -1;
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( secp256k1_rangeproof_rewind(ctx,blind_out,valuep,message,&outlen,nonce.bytes,min_valuep,max_valuep,commit,proof,prooflen) > 0 ) if ( secp256k1_rangeproof_rewind(ctx,blind_out,valuep,message,&outlen,nonce.bytes,min_valuep,max_valuep,commit,proof,prooflen) != 0 )
retval = outlen; retval = outlen;
ENDSECP_ENSURE_CTX ENDSECP_ENSURE_CTX
} }
@ -339,11 +407,11 @@ uint64_t bitcoin_rangeverify(void *ctx,int32_t *exponentp,int32_t *mantissap,uin
{ {
uint64_t max_value,retval = 0; uint64_t max_value,retval = 0;
max_value = *min_valuep = *exponentp = *mantissap = 0; max_value = *min_valuep = *exponentp = *mantissap = 0;
if ( secp256k1_rangeproof_info(ctx,exponentp,mantissap,min_valuep,&max_value,proof,prooflen) > 0 ) if ( secp256k1_rangeproof_info(ctx,exponentp,mantissap,min_valuep,&max_value,proof,prooflen) != 0 )
{ {
if ( commit != 0 ) if ( commit != 0 )
{ {
if ( secp256k1_rangeproof_verify(ctx,min_valuep,&max_value,commit,proof,prooflen) > 0 ) if ( secp256k1_rangeproof_verify(ctx,min_valuep,&max_value,commit,proof,prooflen) != 0 )
retval = max_value; retval = max_value;
} else retval = max_value; } else retval = max_value;
} }
@ -355,7 +423,7 @@ int32_t bitcoin_rangeproof(void *ctx,uint8_t *proof,uint8_t *commit,bits256 blin
int32_t prooflen=0 ,retval = -1; int32_t prooflen=0 ,retval = -1;
SECP_ENSURE_CTX SECP_ENSURE_CTX
{ {
if ( secp256k1_rangeproof_sign(ctx,proof,&prooflen,min_value,commit,blind.bytes,nonce.bytes,exponent,min_bits,value) > 0 ) if ( secp256k1_rangeproof_sign(ctx,proof,&prooflen,min_value,commit,blind.bytes,nonce.bytes,exponent,min_bits,value) != 0 )
retval = prooflen; retval = prooflen;
ENDSECP_ENSURE_CTX ENDSECP_ENSURE_CTX
} }

16
iguana/iguana_sign.c

@ -127,10 +127,6 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin,bits256
int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V) int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V)
{ {
struct iguana_waddress *waddr; struct iguana_waccount *wacct; int32_t i,n,plen,len = 0; char *suffixstr,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; struct iguana_waddress *waddr; struct iguana_waccount *wacct; int32_t i,n,plen,len = 0; char *suffixstr,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0;
if ( serialized == 0 )
{
;
}
//printf("PARSEVIN.(%s) vin.%p\n",jprint(vinobj,0),vin); //printf("PARSEVIN.(%s) vin.%p\n",jprint(vinobj,0),vin);
if ( V == 0 ) if ( V == 0 )
memset(vin,0,sizeof(*vin)); memset(vin,0,sizeof(*vin));
@ -167,7 +163,7 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin
{ {
if ( vin->vinscript == 0 ) if ( vin->vinscript == 0 )
{ {
if ( (V->unspentind= iguana_unspentindfind(coin,V->coinaddr,V->spendscript,&V->spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1)) > 0 ) if ( (V->unspentind= iguana_unspentindfind(coin,V->coinaddr,V->spendscript,&V->spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1,0)) > 0 )
{ {
if ( V->coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,V->coinaddr)) != 0 ) if ( V->coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,V->coinaddr)) != 0 )
{ {
@ -645,7 +641,7 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m
return(len); return(len);
} }
int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,int32_t sighash) int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,int32_t sighash,int32_t signtx)
{ {
bits256 sigtxid; uint8_t *sig; struct vin_info *vp; char vpnstr[64]; int32_t complete=0,plen,j,vini=0,flag=0,siglen,numvouts,numsigs; bits256 sigtxid; uint8_t *sig; struct vin_info *vp; char vpnstr[64]; int32_t complete=0,plen,j,vini=0,flag=0,siglen,numvouts,numsigs;
numvouts = msgtx->tx_out; numvouts = msgtx->tx_out;
@ -663,7 +659,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **
{ {
sig = vp->signers[j].sig; sig = vp->signers[j].sig;
siglen = vp->signers[j].siglen; siglen = vp->signers[j].siglen;
if ( bits256_nonz(vp->signers[j].privkey) != 0 ) if ( signtx != 0 && bits256_nonz(vp->signers[j].privkey) != 0 )
{ {
siglen = bitcoin_sign(coin->ctx,coin->symbol,sig,sigtxid,vp->signers[j].privkey,0); siglen = bitcoin_sign(coin->ctx,coin->symbol,sig,sigtxid,vp->signers[j].privkey,0);
if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 )
@ -722,7 +718,7 @@ int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *c
len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msgtx->vins[i],jitem(vins,i),vp); len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msgtx->vins[i],jitem(vins,i),vp);
if ( msgtx->vins[i].spendscript == 0 ) if ( msgtx->vins[i].spendscript == 0 )
{ {
if ( (vp->unspentind= iguana_unspentindfind(coin,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1)) > 0 ) if ( (vp->unspentind= iguana_unspentindfind(coin,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,0)) > 0 )
{ {
msgtx->vins[i].spendscript = vp->spendscript; msgtx->vins[i].spendscript = vp->spendscript;
msgtx->vins[i].spendlen = vp->spendlen; msgtx->vins[i].spendlen = vp->spendlen;
@ -1032,7 +1028,7 @@ P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount
bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N); bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N);
bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen);
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
if ( bitcoin_verifyvins(active,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL) == 0 ) if ( bitcoin_verifyvins(active,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL,1) == 0 )
{ {
jaddstr(retjson,"result","msigtx"); jaddstr(retjson,"result","msigtx");
if ( signedtx != 0 ) if ( signedtx != 0 )
@ -1091,7 +1087,7 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf
} }
} }
iguana_vininfo_create(myinfo,coin,serialized2,maxsize,msgtx,vins,numinputs,V); iguana_vininfo_create(myinfo,coin,serialized2,maxsize,msgtx,vins,numinputs,V);
if ( (complete= bitcoin_verifyvins(coin,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL)) > 0 && signedtx != 0 ) if ( (complete= bitcoin_verifyvins(coin,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL,1)) > 0 && signedtx != 0 )
{ {
if ( iguana_interpreter(coin,0,j64bits(txobj,"locktime"),V,numinputs) < 0 ) if ( iguana_interpreter(coin,0,j64bits(txobj,"locktime"),V,numinputs) < 0 )
{ {

2
iguana/iguana_spendvectors.c

@ -203,7 +203,7 @@ struct iguana_bundle *iguana_fastexternalspent(struct iguana_info *coin,bits256
X = RAMCHAIN_PTR(rdata,Xoffset); X = RAMCHAIN_PTR(rdata,Xoffset);
//X = (void *)(long)((long)rdata + rdata->Xoffset); //X = (void *)(long)((long)rdata + rdata->Xoffset);
*prevhashp = prev_hash = X[ind]; *prevhashp = prev_hash = X[ind];
if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,prev_hash,prev_vout,spent_hdrsi-1)) != 0 ) if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,prev_hash,prev_vout,spent_hdrsi-1,0)) != 0 )
//if ( (firstvout= iguana_txidfastfind(coin,&height,prev_hash,spent_hdrsi-1)) >= 0 ) //if ( (firstvout= iguana_txidfastfind(coin,&height,prev_hash,spent_hdrsi-1)) >= 0 )
{ {
/*duration = (OS_milliseconds() - startmillis); /*duration = (OS_milliseconds() - startmillis);

2
iguana/iguana_txidfind.c

@ -653,7 +653,7 @@ double iguana_txidstatus(struct iguana_info *coin,bits256 txid)
int32_t height,firstvout,numranked; struct iguana_monitorinfo *ptr; char str[65]; int32_t height,firstvout,numranked; struct iguana_monitorinfo *ptr; char str[65];
if ( coin != 0 && coin->peers != 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 ) if ( (firstvout= iguana_unspentindfind(coin,0,0,0,0,&height,txid,0,coin->bundlescount-1,0)) != 0 )
{ {
if ( (ptr= iguana_monitorfind(coin,txid)) != 0 ) if ( (ptr= iguana_monitorfind(coin,txid)) != 0 )
memset(ptr,0,sizeof(*ptr)); memset(ptr,0,sizeof(*ptr));

27
iguana/iguana_unspents.c

@ -20,9 +20,9 @@
#include "iguana777.h" #include "iguana777.h"
#include "exchanges/bitcoin.h" #include "exchanges/bitcoin.h"
int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *spendlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi) int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *spendlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool)
{ {
struct iguana_txid *tp,TX; struct iguana_pkhash *P; struct iguana_unspent *U; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t RTspend; int32_t pkind,hdrsi,firstvout,spentheight,unspentind = -1; struct iguana_txid *tp,TX; struct gecko_memtx *memtx; struct iguana_pkhash *P; struct iguana_unspent *U; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t RTspend; int32_t pkind,hdrsi,firstvout,spentheight,flag=0,unspentind = -1;
if ( valuep != 0 ) if ( valuep != 0 )
*valuep = 0; *valuep = 0;
if ( coinaddr != 0 ) if ( coinaddr != 0 )
@ -35,12 +35,11 @@ int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *s
{ {
U = RAMCHAIN_PTR(rdata,Uoffset); U = RAMCHAIN_PTR(rdata,Uoffset);
P = RAMCHAIN_PTR(rdata,Poffset); P = RAMCHAIN_PTR(rdata,Poffset);
//U = (void *)(long)((long)rdata + rdata->Uoffset);
//P = (void *)(long)((long)rdata + rdata->Poffset);
pkind = U[unspentind].pkind; pkind = U[unspentind].pkind;
if ( pkind > 0 && pkind < rdata->numpkinds ) if ( pkind > 0 && pkind < rdata->numpkinds )
{ {
RTspend = 0; RTspend = 0;
flag++;
if ( iguana_spentflag(coin,&RTspend,&spentheight,&bp->ramchain,bp->hdrsi,unspentind,0,1,coin->longestchain,U[unspentind].value) == 0 ) //bp == coin->current ? &coin->RTramchain : if ( iguana_spentflag(coin,&RTspend,&spentheight,&bp->ramchain,bp->hdrsi,unspentind,0,1,coin->longestchain,U[unspentind].value) == 0 ) //bp == coin->current ? &coin->RTramchain :
{ {
if ( valuep != 0 ) if ( valuep != 0 )
@ -51,6 +50,22 @@ int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *s
} }
} }
} }
if ( flag == 0 && mempool != 0 )
{
if ( (memtx= gecko_unspentfind(0,coin,txid)) != 0 && vout < memtx->numoutputs )
{
if ( *gecko_valueptr(memtx,vout) > 0 )
{
*valuep = *gecko_valueptr(memtx,vout);
if ( spendlenp != 0 )
{
*spendlenp = 1;
spendscript = 0;
printf("mempool unspentind doesnt support scriptlenp yet\n");
}
}
}
}
return(unspentind); return(unspentind);
} }
@ -63,7 +78,7 @@ char *iguana_inputaddress(struct iguana_info *coin,char *coinaddr,int16_t *spent
{ {
txid = jbits256(vinobj,"txid"); txid = jbits256(vinobj,"txid");
vout = jint(vinobj,"vout"); vout = jint(vinobj,"vout");
if ( (checkind= iguana_unspentindfind(coin,coinaddr,0,0,0,&height,txid,vout,coin->bundlescount-1)) > 0 ) if ( (checkind= iguana_unspentindfind(coin,coinaddr,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) > 0 )
{ {
*spent_hdrsip = (height / coin->chain->bundlesize); *spent_hdrsip = (height / coin->chain->bundlesize);
*unspentindp = checkind; *unspentindp = checkind;
@ -116,7 +131,7 @@ cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,
if ( iguana_scriptget(coin,scriptstr,asmstr,sizeof(scriptstr),hdrsi,unspentind,T[up->txidind].txid,up->vout,rmd160,up->type,pubkey33) != 0 ) if ( iguana_scriptget(coin,scriptstr,asmstr,sizeof(scriptstr),hdrsi,unspentind,T[up->txidind].txid,up->vout,rmd160,up->type,pubkey33) != 0 )
jaddstr(item,"scriptPubKey",scriptstr); jaddstr(item,"scriptPubKey",scriptstr);
jaddnum(item,"amount",dstr(up->value)); jaddnum(item,"amount",dstr(up->value));
if ( (checkind= iguana_unspentindfind(coin,0,0,0,0,&height,T[up->txidind].txid,up->vout,coin->bundlescount-1)) != 0 ) if ( (checkind= iguana_unspentindfind(coin,0,0,0,0,&height,T[up->txidind].txid,up->vout,coin->bundlescount-1,0)) != 0 )
{ {
jaddnum(item,"confirmations",coin->blocks.hwmchain.height - height + 1); jaddnum(item,"confirmations",coin->blocks.hwmchain.height - height + 1);
jaddnum(item,"checkind",checkind); jaddnum(item,"checkind",checkind);

153
iguana/main.c

@ -1150,7 +1150,7 @@ void iguana_appletests(struct supernet_info *myinfo)
bitcoin_sharedsecret(myinfo->ctx,hash2,pubkey,33); bitcoin_sharedsecret(myinfo->ctx,hash2,pubkey,33);
printf("secp256k1 elapsed %.3f for %d iterations\n",OS_milliseconds() - startmillis,i); printf("secp256k1 elapsed %.3f for %d iterations\n",OS_milliseconds() - startmillis,i);
getchar();**/ getchar();**/
if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"protover\":70002,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":14631,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":64,\"endpend\":64,\"services\":129,\"maxpeers\":128,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0,myinfo->rpcport)) != 0 ) if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"protover\":70002,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":64,\"endpend\":64,\"services\":129,\"maxpeers\":128,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0,myinfo->rpcport)) != 0 )
{ {
free(str); free(str);
if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"portp2p\":8333,\"RELAY\":0,\"VALIDATE\":0,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"portp2p\":8333,\"RELAY\":0,\"VALIDATE\":0,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":64,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":4,\"poll\":100}"),0,myinfo->rpcport)) != 0 )
@ -1309,6 +1309,116 @@ int32_t iguana_isbigendian()
else return(-1); else return(-1);
} }
#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 )
#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx);
int32_t iguana_schnorr_peersign(void *ctx,uint8_t *allpub33,uint8_t *partialsig64,int32_t peeri,bits256 mypriv,bits256 privnonce,bits256 *nonces,int32_t n,bits256 msg256)
{
secp256k1_pubkey Rall,ALL,PUBS[256],*PUBptrs[256]; int32_t i,num,retval = -1; size_t plen; uint8_t pubkey[33];
pubkey[0] = 2;
SECP_ENSURE_CTX
{
for (i=num=0; i<n; i++)
{
plen = 33;
memcpy(pubkey+1,nonces[i].bytes,32);
if ( secp256k1_ec_pubkey_parse(ctx,&PUBS[i],pubkey,plen) == 0 )
printf("error extracting pubkey.%d of %d\n",i,n);
if ( i != peeri )
PUBptrs[num++] = &PUBS[i];
}
PUBptrs[num] = &PUBS[peeri];
if ( secp256k1_ec_pubkey_combine(ctx,&ALL,(void *)PUBptrs,num+1) != 0 )
{
plen = 33;
secp256k1_ec_pubkey_serialize(ctx,allpub33,&plen,&ALL,SECP256K1_EC_COMPRESSED);
//for (i=0; i<33; i++)
// printf("%02x",allpub33[i]);
//printf("\n");
} else printf("error combining ALL\n");
if ( secp256k1_ec_pubkey_combine(ctx,&Rall,(void *)PUBptrs,num) != 0 )
{
if ( secp256k1_schnorr_partial_sign(ctx,partialsig64,msg256.bytes,mypriv.bytes,&Rall,privnonce.bytes) == 0 )
printf("iguana_schnorr_peersign: err %d of num.%d\n",peeri,n);
else retval = 0;
} else printf("error parsing pubkey.%d\n",peeri);
ENDSECP_ENSURE_CTX
}
return(retval);
}
bits256 iguana_schnorr_noncepair(void *ctx,bits256 *pubkey,uint8_t odd_even,bits256 msg256,bits256 privkey,int32_t maxj)
{
bits256 privnonce; int32_t j; uint8_t pubkey33[33];
for (j=0; j<maxj; j++)
{
privnonce = bitcoin_schnorr_noncepair(ctx,pubkey33,msg256,privkey);
if ( pubkey33[0] == (odd_even + 2) )
{
memcpy(pubkey->bytes,pubkey33+1,32);
break;
}
}
if ( j == maxj )
{
printf("couldnt generate even noncepair\n");
exit(-1);
}
return(privnonce);
}
void iguana_schnorr(struct supernet_info *myinfo)
{
uint8_t allpubs[256][33],allpub[33],sig64s[256][64],sig64[64],*sigs[256]; bits256 msg256,privnonces[256],signers,privkeys[256],pubkeys[256],pubkeysB[256],nonces[256]; int32_t i,iter,n,k,maxj = 100;
OS_randombytes((void *)&n,sizeof(n));
srand(n);
n = 64;//(rand() % 200);
// generate onetime keypairs
for (i=0; i<n; i++)
pubkeys[i] = bitcoin_pub256(myinfo->ctx,&privkeys[i],0);
msg256 = rand256(0);
for (i=0; i<n; i++)
privnonces[i] = iguana_schnorr_noncepair(myinfo->ctx,&nonces[i],0,msg256,privkeys[i],maxj);
for (i=0; i<n; i++)
iguana_schnorr_peersign(myinfo->ctx,allpubs[i],sig64s[i],i,privkeys[i],privnonces[i],nonces,n,msg256);
for (iter=0; iter<1; iter++)
{
memset(signers.bytes,0,sizeof(signers));
for (i=k=0; i<n; i++)
{
if ( (rand() % 100) < 50 )
{
//printf("%d ",i);
sigs[k] = sig64s[i];
pubkeysB[k] = pubkeys[i];
k++;
SETBIT(signers.bytes,i);
}
}
if ( bitcoin_schnorr_combine(myinfo->ctx,sig64,allpub,sigs,k,msg256) < 0 )
printf("error combining k.%d sig64 iter.%d\n",k,iter);
else if ( bitcoin_schnorr_verify(myinfo->ctx,sig64,msg256,allpub,33) < 0 )
printf("error verifying combined sig k.%d\n",k);
else if ( 0 )
{
if ( bitcoin_pubkey_combine(myinfo->ctx,allpub,0,pubkeys,n,0,0) == 0 )
{
if ( memcmp(allpub,allpubs[0],33) != 0 )
{
printf("\n");
for (k=0; k<33; k++)
printf("%02x",allpubs[0][k]);
printf(" combined\n");
for (k=0; k<33; k++)
printf("%02x",allpub[k]);
printf(" allpub, ");
printf("allpub mismatch iter.%d i.%d n.%d\n",iter,i,n);
} else printf("validated iter.%d k.%d %llx\n",iter,k,(long long)signers.txid);
} //else printf("error combining\n");
} else printf("passed\n");
}
}
void iguana_main(void *arg) void iguana_main(void *arg)
{ {
int32_t usessl = 0, ismainnet = 1; struct supernet_info *myinfo; cJSON *argjson = 0; int32_t usessl = 0, ismainnet = 1; struct supernet_info *myinfo; cJSON *argjson = 0;
@ -1320,9 +1430,50 @@ void iguana_main(void *arg)
mycalloc(0,0,0); mycalloc(0,0,0);
if ( 0 ) if ( 0 )
iguana_signalsinit(); iguana_signalsinit();
if ( 0 )
{
int32_t i,max=10000000; FILE *fp; bits256 check,val,hash = rand256(0);
if ( (fp= fopen("/tmp/seeds2","rb")) != 0 )
{
fread(&check,1,sizeof(check),fp);
for (i=1; i<max; i++)
{
if ( (i % 1000000) == 0 )
fprintf(stderr,".");
fread(&val,1,sizeof(val),fp);
hash = bits256_sha256(val);
hash = bits256_sha256(hash);
if ( bits256_cmp(hash,check) != 0 )
printf("hash error at i.%d\n",i);
check = val;
}
printf("validated %d seeds\n",max);
getchar();
}
else if ( (fp= fopen("/tmp/seeds2","wb")) != 0 )
{
for (i=0; i<max; i++)
{
if ( (i % 1000000) == 0 )
fprintf(stderr,".");
hash = bits256_sha256(hash);
hash = bits256_sha256(hash);
fseek(fp,(max-i-1) * sizeof(bits256),SEEK_SET);
if ( fwrite(hash.bytes,1,sizeof(hash),fp) != sizeof(hash) )
printf("error writing hash[%d] i.%d\n",(max-i-1),i);
}
fclose(fp);
}
}
iguana_ensuredirs(); iguana_ensuredirs();
iguana_Qinit(); iguana_Qinit();
myinfo = SuperNET_MYINFO(0); myinfo = SuperNET_MYINFO(0);
if ( 0 )
{
int32_t i; for (i=0; i<10; i++)
iguana_schnorr(myinfo);
getchar();
}
myinfo->rpcport = IGUANA_RPCPORT; myinfo->rpcport = IGUANA_RPCPORT;
strcpy(myinfo->rpcsymbol,"BTCD"); strcpy(myinfo->rpcsymbol,"BTCD");
iguana_urlinit(myinfo,ismainnet,usessl); iguana_urlinit(myinfo,ismainnet,usessl);

1
iguana/ramchain_api.c

@ -171,6 +171,7 @@ ZERO_ARGS(bitcoinrpc,getbestblockhash)
ZERO_ARGS(bitcoinrpc,getblockcount) ZERO_ARGS(bitcoinrpc,getblockcount)
{ {
cJSON *retjson = cJSON_CreateObject(); cJSON *retjson = cJSON_CreateObject();
//printf("result %d\n",coin->blocks.hwmchain.height);
jaddnum(retjson,"result",coin->blocks.hwmchain.height); jaddnum(retjson,"result",coin->blocks.hwmchain.height);
return(jprint(retjson,1)); return(jprint(retjson,1));
} }

1
iguana/tests/getblock

@ -0,0 +1 @@
curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblock\",\"params\":[\"0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46\"]}"

1
iguana/tests/getblockcount

@ -0,0 +1 @@
curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblockcount\",\"params\":[]}"

1
iguana/tests/getblockhash

@ -0,0 +1 @@
curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblockhash\",\"params\":[0]}"

2
iguana/tests/new

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

19
includes/iguana_funcs.h

@ -401,10 +401,10 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int
int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr); int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr);
int32_t iguana_validated(struct iguana_info *coin); int32_t iguana_validated(struct iguana_info *coin);
void iguana_volatilesalloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t copyflag); void iguana_volatilesalloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t copyflag);
int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr); int32_t iguana_send_ping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr);
int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin); int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin);
uint32_t iguana_fastfindinit(struct iguana_info *coin); uint32_t iguana_fastfindinit(struct iguana_info *coin);
int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi); int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool);
int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,char *address); int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,char *address);
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag); int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag);
bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,char *str); bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,char *str);
@ -420,7 +420,8 @@ int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t
cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr); cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr);
char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript); char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript);
char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds); char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds);
int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,int32_t sighash); int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,int32_t sighash,int32_t signtx);
char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool);
int64_t iguana_fastfindcreate(struct iguana_info *coin); int64_t iguana_fastfindcreate(struct iguana_info *coin);
int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr);
int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight); int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight);
@ -506,6 +507,18 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,
int32_t iguana_ROallocsize(struct iguana_info *virt); int32_t iguana_ROallocsize(struct iguana_info *virt);
long iguana_bundlesload(struct supernet_info *myinfo,struct iguana_info *coin); long iguana_bundlesload(struct supernet_info *myinfo,struct iguana_info *coin);
void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin); void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin);
int32_t bitcoin_pubkey_combine(void *ctx,uint8_t *combined_pub,uint8_t *skipkey,bits256 *evenkeys,int32_t n,bits256 *oddkeys,int32_t m);
bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even);
bits256 bitcoin_schnorr_noncepair(void *ctx,uint8_t *pubnonce,bits256 txhash2,bits256 privkey);
int32_t bitcoin_schnorr_combine(void *ctx,uint8_t *sig64,uint8_t *allpub,uint8_t **sigs,int32_t n,bits256 txhash2);
int32_t bitcoin_schnorr_verify(void *ctx,uint8_t *sig64,bits256 txhash2,uint8_t *pubkey,int32_t plen);
int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj);
struct gecko_memtx *gecko_unspentfind(struct gecko_memtx ***ptrpp,struct iguana_info *virt,bits256 txid);
int64_t *gecko_valueptr(struct gecko_memtx *memtx,int32_t vout);
struct iguana_peer *iguana_peerfindipaddr(struct iguana_info *coin,char *ipaddr,int32_t needalive);
struct iguana_peer *iguana_peerfindipbits(struct iguana_info *coin,uint32_t ipbits,int32_t needalive);
int32_t basilisk_relays_send(struct supernet_info *myinfo,struct iguana_peer *addr);
int32_t basilisk_headers_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,bits256 *txids,int32_t num);
#include "../includes/iguana_api.h" #include "../includes/iguana_api.h"

9
includes/iguana_structs.h

@ -16,6 +16,7 @@
#ifndef H_IGUANASTRUCTS_H #ifndef H_IGUANASTRUCTS_H
#define H_IGUANASTRUCTS_H #define H_IGUANASTRUCTS_H
#define IGUANA_MAXRELAYS 64
struct iguana_thread struct iguana_thread
{ {
@ -136,7 +137,8 @@ struct iguana_msgtx
struct iguana_msgvin *vins; struct iguana_msgvin *vins;
struct iguana_msgvout *vouts; struct iguana_msgvout *vouts;
bits256 txid; bits256 txid;
int32_t allocsize,timestamp; int32_t allocsize,timestamp,numinputs,numoutputs;
int64_t inputsum,outputsum,txfee;
} __attribute__((packed)); } __attribute__((packed));
struct iguana_msgjoinsplit struct iguana_msgjoinsplit
@ -307,7 +309,7 @@ struct iguana_peer
char ipaddr[64],lastcommand[16],coinname[64],symbol[64]; char ipaddr[64],lastcommand[16],coinname[64],symbol[64];
uint64_t pingnonce,totalsent,totalrecv,ipbits; double pingtime,sendmillis,pingsum,getdatamillis; uint64_t pingnonce,totalsent,totalrecv,ipbits; double pingtime,sendmillis,pingsum,getdatamillis;
uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer,protover; uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer,protover;
int32_t supernet,basilisk,dead,addrind,usock,lastheight,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid,dirty[2],laggard,headerserror,lastsent; int32_t supernet,basilisk,dead,addrind,usock,lastheight,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid,dirty[2],laggard,headerserror,lastsent,isrelay;
double recvblocks,recvtotal; double recvblocks,recvtotal;
int64_t allocated,freed; int64_t allocated,freed;
bits256 RThashes[IGUANA_MAXBUNDLESIZE]; int32_t numRThashes; bits256 RThashes[IGUANA_MAXBUNDLESIZE]; int32_t numRThashes;
@ -414,7 +416,7 @@ struct iguana_info
double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num; double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num;
struct iguana_monitorinfo monitoring[256]; struct iguana_monitorinfo monitoring[256];
struct gecko_sequences SEQ; struct gecko_sequences SEQ;
struct iguana_blocks blocks; void *mempool; struct iguana_blocks blocks; void *mempool; void *mempools[IGUANA_MAXRELAYS];
}; };
struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
@ -468,6 +470,7 @@ struct supernet_info
void *ctx; void *ctx;
// compatibility // compatibility
bits256 pangea_category,instantdex_category; bits256 pangea_category,instantdex_category;
uint32_t relaybits[IGUANA_MAXRELAYS]; struct basilisk_relay relays[IGUANA_MAXRELAYS]; int32_t numrelays;
}; };
#endif #endif

Loading…
Cancel
Save