Browse Source

pin

release/v0.1
jl777 9 years ago
parent
commit
53473691ec
  1. 2
      InstantDEX/InstantDEX.c
  2. 2
      InstantDEX/exchange_trades.h
  3. 2
      InstantDEX/exchangeparse.h
  4. 2
      InstantDEX/exchanges/bitfinex.c
  5. 2
      InstantDEX/exchanges/bitstamp.c
  6. 2
      InstantDEX/exchanges/bittrex.c
  7. 2
      InstantDEX/exchanges/btc38.c
  8. 2
      InstantDEX/exchanges/btce.c
  9. 2
      InstantDEX/exchanges/coinbase.c
  10. 2
      InstantDEX/exchanges/huobi.c
  11. 2
      InstantDEX/exchanges/lakebtc.c
  12. 2
      InstantDEX/exchanges/okcoin.c
  13. 2
      InstantDEX/exchanges/poloniex.c
  14. 2
      InstantDEX/exchanges/quadriga.c
  15. 2
      InstantDEX/orderbooks.h
  16. 2
      crypto777/OS_nonportable.c
  17. 2
      crypto777/OS_portable.c
  18. 4
      crypto777/OS_portable.h
  19. 2
      crypto777/OS_time.c
  20. 2
      crypto777/SaM.c
  21. 31
      crypto777/bitcoind_RPC.c
  22. 2
      crypto777/cJSON.c
  23. 2
      crypto777/curve25519.c
  24. 2
      crypto777/iguana_OS.c
  25. 2
      crypto777/iguana_serdes.c
  26. 2
      crypto777/iguana_utils.c
  27. 2
      crypto777/ramcoder.c
  28. 5
      crypto777/tweetnacl.c
  29. 478
      iguana/SuperNET.c
  30. 3
      iguana/SuperNET.h
  31. 526
      iguana/cards777.c
  32. 2
      iguana/iguana.sources
  33. 2
      iguana/iguana777.c
  34. 3
      iguana/iguana777.h
  35. 2
      iguana/iguana_accept.c
  36. 2
      iguana/iguana_bitmap.c
  37. 2
      iguana/iguana_blocks.c
  38. 2
      iguana/iguana_bundles.c
  39. 2
      iguana/iguana_chains.c
  40. 2
      iguana/iguana_html.c
  41. 2
      iguana/iguana_init.c
  42. 155
      iguana/iguana_json.c
  43. 2
      iguana/iguana_msg.c
  44. 2
      iguana/iguana_peers.c
  45. 2
      iguana/iguana_pubkeys.c
  46. 2
      iguana/iguana_ramchain.c
  47. 2
      iguana/iguana_recv.c
  48. 2
      iguana/iguana_rpc.c
  49. 2
      iguana/iguana_tx.c
  50. 2
      iguana/iguana_wallet.c
  51. 3
      iguana/main.c
  52. 189
      iguana/pangea777.h
  53. 594
      iguana/pangea_api.c
  54. 1420
      iguana/pangea_fsm.c
  55. 970
      iguana/pangea_funds.c
  56. 487
      iguana/pangea_init.c
  57. 435
      iguana/pangea_network.c
  58. 644
      iguana/poker.c
  59. 2
      iguana/ramchain_api.c
  60. 2
      includes/iguana_api.h
  61. 52
      includes/iguana_apideclares.h
  62. 8
      includes/iguana_apidefs.h
  63. 6
      includes/iguana_apiundefs.h
  64. 3
      includes/tweetnacl.h

2
InstantDEX/InstantDEX.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchange_trades.h

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchangeparse.h

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/bitfinex.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/bitstamp.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/bittrex.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/btc38.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/btce.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/coinbase.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/huobi.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/lakebtc.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/okcoin.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/poloniex.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/exchanges/quadriga.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
InstantDEX/orderbooks.h

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
crypto777/OS_nonportable.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
crypto777/OS_portable.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

4
crypto777/OS_portable.h

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *
@ -243,6 +243,7 @@ void reverse_hexstr(char *str);
int32_t init_hexbytes_noT(char *hexbytes,uint8_t *message,long len);
uint16_t parse_ipaddr(char *ipaddr,char *ip_port);
int32_t bitweight(uint64_t x);
unsigned char _decode_hex(char *hex);
long _stripwhite(char *buf,int accept);
int32_t is_DST(int32_t datenum);
@ -335,6 +336,7 @@ int32_t btc_priv2pub(uint8_t pubkey[33],uint8_t privkey[32]);
extern char *Iguana_validcommands[];
extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY;
extern char NXTAPIURL[];
#endif

2
crypto777/OS_time.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
crypto777/SaM.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

31
crypto777/bitcoind_RPC.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *
@ -18,6 +18,7 @@
#include <curl/curl.h>
#include <curl/easy.h>
#define issue_curl(cmdstr) bitcoind_RPC(0,"curl",cmdstr,0,0,0)
// return data from the server
struct return_string {
@ -339,3 +340,31 @@ void curlhandle_free(void *curlhandle)
{
curl_easy_cleanup(curlhandle);
}
bits256 issue_getpubkey(int32_t *haspubkeyp,char *acct)
{
cJSON *json; bits256 pubkey; char cmd[4096],*jsonstr; struct destbuf pubkeystr;
sprintf(cmd,"%s?requestType=getAccountPublicKey&account=%s",NXTAPIURL,acct);
jsonstr = issue_curl(cmd);
pubkeystr.buf[0] = 0;
if ( haspubkeyp != 0 )
*haspubkeyp = 0;
memset(&pubkey,0,sizeof(pubkey));
if ( jsonstr != 0 )
{
printf("PUBKEYRPC.(%s)\n",jsonstr);
if ( (json = cJSON_Parse(jsonstr)) != 0 )
{
copy_cJSON(&pubkeystr,cJSON_GetObjectItem(json,"publicKey"));
free_json(json);
if ( strlen(pubkeystr.buf) == sizeof(pubkey)*2 )
{
if ( haspubkeyp != 0 )
*haspubkeyp = 1;
decode_hex(pubkey.bytes,sizeof(pubkey),pubkeystr.buf);
}
}
free(jsonstr);
}
return(pubkey);
}

2
crypto777/cJSON.c

@ -616,7 +616,7 @@ void cJSON_Minify(char *json)
// the following written by jl777
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
crypto777/curve25519.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
crypto777/iguana_OS.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
crypto777/iguana_serdes.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
crypto777/iguana_utils.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
crypto777/ramcoder.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

5
crypto777/tweetnacl.c

@ -456,6 +456,11 @@ int crypto_box_keypair(u8 *y,u8 *x)
return crypto_scalarmult_base(y,x);
}
int crypto_box_priv2pub(u8 *y,u8 *x)
{
return crypto_scalarmult_base(y,x);
}
int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x)
{
u8 s[32];

478
iguana/SuperNET.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *
@ -134,6 +134,24 @@ int32_t SuperNET_serialize(int32_t reverse,bits256 *senderpubp,uint64_t *senderb
return((int32_t)extra);
}
int32_t SuperNET_decode(uint64_t *senderbitsp,bits256 *sigp,uint32_t *timestampp,uint64_t *destbitsp,uint8_t *str,uint8_t *cipher,int32_t *lenp,uint8_t *myprivkey)
{
bits256 srcpubkey; uint8_t *nonce; int i,hdrlen,err=0,len = *lenp;
hdrlen = SuperNET_serialize(1,&srcpubkey,senderbitsp,sigp,timestampp,destbitsp,cipher);
cipher += hdrlen, len -= hdrlen;
if ( *destbitsp != 0 && *senderbitsp != 0 )
{
nonce = cipher;
cipher += crypto_box_NONCEBYTES, len -= crypto_box_NONCEBYTES;
printf("decode ptr.%p[%d]\n",cipher,len);
err = crypto_box_open((uint8_t *)str,cipher,len,nonce,srcpubkey.bytes,myprivkey);
for (i=0; i<len-crypto_box_ZEROBYTES; i++)
str[i] = str[i+crypto_box_ZEROBYTES];
*lenp = len - crypto_box_ZEROBYTES;
} else memcpy(str,cipher,len);
return(err);
}
uint8_t *SuperNET_encode(int32_t *cipherlenp,void *str,int32_t len,bits256 destpubkey,bits256 myprivkey,bits256 mypubkey,uint64_t senderbits,bits256 sig,uint32_t timestamp)
{
uint8_t *buf,*nonce,*origcipher,*cipher,*ptr; uint64_t destbits; int32_t totalsize,hdrlen;
@ -155,6 +173,7 @@ uint8_t *SuperNET_encode(int32_t *cipherlenp,void *str,int32_t len,bits256 destp
origcipher = cipher;
ptr = &cipher[sizeof(struct iguana_msghdr)];
hdrlen = SuperNET_serialize(0,&mypubkey,&senderbits,&sig,&timestamp,&destbits,ptr);
printf("hdrlen.%d sender.%llx dest.%llx\n",hdrlen,(long long)senderbits,(long long)destbits);
if ( senderbits != 0 )
totalsize += sizeof(sig);//, printf("totalsize.%d extra.%ld add %ld\n",totalsize-len,extra,(long)(sizeof(sig) + sizeof(timestamp)));
if ( destbits != 0 && senderbits != 0 )
@ -167,32 +186,25 @@ uint8_t *SuperNET_encode(int32_t *cipherlenp,void *str,int32_t len,bits256 destp
memset(cipher,0,len+crypto_box_ZEROBYTES);
memset(buf,0,crypto_box_ZEROBYTES);
memcpy(buf+crypto_box_ZEROBYTES,str,len);
printf("cryptobox.%p[%d]\n",cipher,len+crypto_box_ZEROBYTES);
crypto_box(cipher,buf,len+crypto_box_ZEROBYTES,nonce,destpubkey.bytes,myprivkey.bytes);
hdrlen += crypto_box_NONCEBYTES + crypto_box_ZEROBYTES;
}
else memcpy(&cipher[hdrlen],str,len);
if ( totalsize != len+hdrlen )
printf("unexpected totalsize.%d != len.%d + hdrlen.%d %d\n",totalsize,len,hdrlen,len+hdrlen);
free(buf);
*cipherlenp = totalsize;
return(origcipher);
}
int32_t SuperNET_decode(uint64_t *senderbitsp,bits256 *sigp,uint32_t *timestampp,uint64_t *destbitsp,uint8_t *str,uint8_t *cipher,int32_t *lenp,uint8_t *myprivkey)
{
bits256 srcpubkey; uint8_t *nonce; int i,hdrlen,err=0,len = *lenp;
hdrlen = SuperNET_serialize(1,&srcpubkey,senderbitsp,sigp,timestampp,destbitsp,cipher);
cipher += hdrlen, len -= hdrlen;
if ( *destbitsp != 0 && *senderbitsp != 0 )
{
nonce = cipher;
cipher += crypto_box_NONCEBYTES, len -= crypto_box_NONCEBYTES;
err = crypto_box_open((uint8_t *)str,cipher,len,nonce,srcpubkey.bytes,myprivkey);
for (i=0; i<len-crypto_box_ZEROBYTES; i++)
str[i] = str[i+crypto_box_ZEROBYTES];
*lenp = len - crypto_box_ZEROBYTES;
} else memcpy(str,cipher,len);
return(err);
bits256 checksig; uint32_t checkstamp; uint64_t checksender,checkbits; int32_t checklen;
checklen = totalsize;
if ( SuperNET_decode(&checksender,&checksig,&checkstamp,&checkbits,(void *)buf,ptr,&checklen,myprivkey.bytes) == 0 )
{
printf("decoded %u %llx checklen.%d\n",checkstamp,(long long)checkbits,checklen);
} else printf("encrypt/decrypt error\n");
printf("decoded %u %llx checklen.%d\n",checkstamp,(long long)checkbits,checklen);
}
free(buf);
return(origcipher);
}
int32_t SuperNET_decrypt(bits256 *senderpubp,uint64_t *senderbitsp,uint32_t *timestampp,bits256 mypriv,bits256 mypub,uint8_t *dest,int32_t maxlen,uint8_t *src,int32_t len)
@ -254,8 +266,7 @@ int32_t SuperNET_decrypt(bits256 *senderpubp,uint64_t *senderbitsp,uint32_t *tim
} //else printf("SIG VERIFIED newlen.%d (%llu -> %llu)\n",newlen,(long long)senderbits,(long long)destbits);
}
}
}
else printf("%llu: SuperNET_decrypt skip: decode_cipher error len.%d -> newlen.%d\n",(long long)acct777_nxt64bits(mypub),len,newlen);
} else printf("%llu: SuperNET_decrypt skip: decode_cipher error len.%d -> newlen.%d\n",(long long)acct777_nxt64bits(mypub),len,newlen);
free(buf);
return(newlen);
}
@ -270,7 +281,7 @@ int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,s
destbits = 0;
destpub = GENESIS_PUBKEY;
}
//printf("hostnet777_sendmsg dest.%llu destpub.%llx priv.%llx pub.%llx\n",(long long)destbits,(long long)destpub.txid,(long long)mypriv.txid,(long long)mypub.txid);
printf("SuperNET_sendmsg dest.%llu destpub.%llx priv.%llx pub.%llx\n",(long long)destbits,(long long)destpub.txid,(long long)mypriv.txid,(long long)mypub.txid);
memset(&sig,0,sizeof(sig));
if ( mypub.txid == 0 || mypriv.txid == 0 )
mypriv = curve25519_keypair(&mypub), sig.timestamp = (uint32_t)time(NULL);
@ -323,7 +334,7 @@ int32_t SuperNET_json2bits(char *myipaddr,bits256 persistent_priv,bits256 persis
checkc = SuperNET_checkc(persistent_priv,destpub,tag);
len += iguana_rwnum(1,&serialized[len],sizeof(checkc),&checkc);
agent = jstr(json,"agent"), method = jstr(json,"method");
if ( strcmp(agent,"SuperNET") == 0 && strcmp(method,"json2bits") == 0 )
if ( agent != 0 && method != 0 && strcmp(agent,"SuperNET") == 0 && strcmp(method,"json2bits") == 0 )
{
agent = jstr(json,"destagent");
method = jstr(json,"destmethod");
@ -346,9 +357,9 @@ int32_t SuperNET_json2bits(char *myipaddr,bits256 persistent_priv,bits256 persis
}
crc = calc_crc32(0,&serialized[sizeof(crc)],len - sizeof(crc));
iguana_rwnum(1,serialized,sizeof(crc),&crc);
int32_t i; for (i=0; i<len; i++)
printf("%02x ",serialized[i]);
printf("SEND[%d]\n",len);
//int32_t i; for (i=0; i<len; i++)
// printf("%02x ",serialized[i]);
//printf("SEND[%d]\n",len);
return(len);
}
@ -381,9 +392,9 @@ cJSON *SuperNET_bits2json(bits256 mypriv,bits256 mypub,struct iguana_peer *addr,
len += iguana_rwnum(0,&serialized[len],sizeof(checkc),&checkc);
len += iguana_rwnum(0,&serialized[len],sizeof(apinum),&apinum);
//printf("-> dest.%x myip.%x senderpub.%llx tag.%llu\n",destipbits,myipbits,(long long)senderpub.txid,(long long)tag);
int32_t i; for (i=0; i<len; i++)
printf("%02x ",serialized[i]);
printf("RECV[%d]\n",len);
//int32_t i; for (i=0; i<len; i++)
// printf("%02x ",serialized[i]);
//printf("RECV[%d]\n",len);
if ( SuperNET_num2API(agent,method,apinum) >= 0 )
{
jaddstr(json,"agent",agent);
@ -419,7 +430,7 @@ int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,c
space = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE);
datalen = SuperNET_json2bits(myinfo->ipaddr,myinfo->persistent_priv,myinfo->myaddr.persistent,&serialized[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE,addr->ipaddr,addr->pubkey,json);
printf("SUPERSEND.(%s) -> (%s) delaymillis.%d datalen.%d\n",jsonstr,addr->ipaddr,delaymillis,datalen);
if ( 0 )
if ( 1 )
qlen = iguana_queue_send(coin,addr,delaymillis,serialized,"SuperNET",datalen,0,0);
else qlen = SuperNET_sendmsg(myinfo,coin,addr,addr->pubkey,myinfo->privkey,myinfo->myaddr.pubkey,serialized,datalen,space,delaymillis);
free(serialized);
@ -659,3 +670,410 @@ char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *de
free(space);
return(retstr);
}
cJSON *SuperNET_peerarray(struct iguana_info *coin,int32_t max,int32_t supernetflag)
{
int32_t i,r,j,n = 0; struct iguana_peer *addr; cJSON *array = cJSON_CreateArray();
r = rand();
for (j=0; j<IGUANA_MAXPEERS; j++)
{
i = (r + j) % IGUANA_MAXPEERS;
addr = &coin->peers.active[i];
if ( addr->usock >= 0 && supernetflag == (addr->supernet != 0) )
{
jaddistr(array,addr->ipaddr);
if ( ++n >= max )
break;
}
}
if ( n == 0 )
{
free_json(array);
return(0);
}
return(array);
}
int32_t SuperNET_coinpeers(struct iguana_info *coin,cJSON *SNjson,cJSON *rawjson,int32_t max)
{
cJSON *array,*item;
if ( (array= SuperNET_peerarray(coin,max,1)) != 0 )
{
max -= cJSON_GetArraySize(array);
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jadd(item,"peers",array);
jaddi(SNjson,item);
}
if ( max > 0 && (array= SuperNET_peerarray(coin,max,0)) != 0 )
{
max -= cJSON_GetArraySize(array);
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jadd(item,"peers",array);
jaddi(rawjson,item);
}
return(max);
}
void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int32_t supernetflag)
{
int32_t i,j,m; cJSON *coinarray,*item; char *symbol,*ipaddr; struct iguana_info *ptr;
if ( array != 0 && n > 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(array,i)) != 0 && (symbol= jstr(item,"coin")) != 0 )
{
ptr = iguana_coinfind(symbol);
if ( (coinarray= jarray(&m,item,"peers")) != 0 )
{
for (j=0; j<m; j++)
{
if ( (ipaddr= jstr(jitem(coinarray,j),0)) != 0 )
SuperNET_remotepeer(myinfo,ptr,symbol,ipaddr,supernetflag);
else printf("no ipaddr[%d] of %d\n",j,m);
}
}
printf("parsed.%d %s.peers supernet.%d\n",m,symbol,supernetflag);
}
}
}
}
int32_t _SuperNET_cipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 destpub,bits256 srcpriv,uint8_t *buf)
{
memset(cipher,0,len+crypto_box_ZEROBYTES);
memset(buf,0,crypto_box_ZEROBYTES);
memcpy(buf+crypto_box_ZEROBYTES,message,len);
crypto_box(cipher,buf,len+crypto_box_ZEROBYTES,nonce,destpub.bytes,srcpriv.bytes);
return(len + crypto_box_ZEROBYTES);
}
uint8_t *_SuperNET_decipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 srcpub,bits256 mypriv)
{
int32_t err;
if ( (err= crypto_box_open(message,cipher,len,nonce,srcpub.bytes,mypriv.bytes)) == 0 )
{
message += crypto_box_ZEROBYTES;
len -= crypto_box_ZEROBYTES;
return(message);
}
return(0);
}
#include "../includes/iguana_apidefs.h"
HASH_ARG(SuperNET,priv2pub,privkey)
{
cJSON *retjson = cJSON_CreateObject(); bits256 pubkey;
crypto_box_priv2pub(pubkey.bytes,privkey.bytes);
jaddbits256(retjson,"result",pubkey);
return(jprint(retjson,1));
}
ZERO_ARGS(SuperNET,keypair)
{
cJSON *retjson = cJSON_CreateObject(); bits256 pubkey,privkey;
crypto_box_keypair(pubkey.bytes,privkey.bytes);
jaddstr(retjson,"result","generated keypair");
jaddbits256(retjson,"privkey",privkey);
jaddbits256(retjson,"pubkey",pubkey);
return(jprint(retjson,1));
}
TWOHASHES_AND_STRING(SuperNET,decipher,privkey,srcpubkey,cipherstr)
{
cJSON *retjson; char *retstr;
uint8_t *origptr,*cipher,*nonce,*deciphered,*message,space[8192],space2[sizeof(space)]; int len;
if ( bits256_nonz(privkey) == 0 )
privkey = GENESIS_PRIVKEY;
len = (int32_t)strlen(cipherstr)>>1;
if ( len < crypto_box_NONCEBYTES )
return(clonestr("{\"error\":\"cipher is too short\"}"));
if ( len > sizeof(space) )
{
cipher = calloc(1,len);
message = calloc(1,len);
}
else cipher = space, message = space2;
decode_hex(cipher,len,cipherstr);
origptr = cipher;
if ( bits256_nonz(srcpubkey) == 0 )
{
memcpy(srcpubkey.bytes,cipher,sizeof(srcpubkey));
//char str[65]; printf("use attached pubkey.(%s)\n",bits256_str(str,srcpubkey));
cipher += sizeof(srcpubkey);
len -= sizeof(srcpubkey);
}
nonce = cipher;
cipher += crypto_box_NONCEBYTES, len -= crypto_box_NONCEBYTES;
if ( (deciphered= _SuperNET_decipher(nonce,cipher,message,len,srcpubkey,privkey)) != 0 )
{
len -= crypto_box_ZEROBYTES;
deciphered[len] = 0;
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","deciphered message");
jaddstr(retjson,"message",(char *)deciphered);
retstr = jprint(retjson,1);
} else retstr = clonestr("{\"error\":\"couldnt decipher message\"}");
if ( origptr != space )
free(origptr);
if ( message != space2 )
free(message);
return(retstr);
}
TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message)
{
bits256 mypubkey; uint8_t *buf,*nonce,*cipher,*origptr,space[8192],space2[sizeof(space)];
cJSON *retjson; char *retstr,*hexstr; int32_t onetimeflag=0,allocsize,len;
len = (int32_t)strlen(message);
allocsize = (len + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES);
if ( bits256_nonz(destpubkey) == 0 )
{
destpubkey = GENESIS_PUBKEY;
onetimeflag = 2; // prevent any possible leakage of privkey by using known destpub
}
if ( bits256_nonz(privkey) == 0 )
onetimeflag = 1;
if ( onetimeflag != 0 )
{
crypto_box_keypair(mypubkey.bytes,privkey.bytes);
allocsize += sizeof(bits256);
}
if ( allocsize > sizeof(space) )
{
buf = calloc(1,allocsize);
cipher = calloc(1,allocsize);
} else buf = space, cipher = space2;
origptr = nonce = cipher;
if ( onetimeflag != 0 )
{
memcpy(cipher,mypubkey.bytes,sizeof(mypubkey));
nonce = &cipher[sizeof(mypubkey)];
}
OS_randombytes(nonce,crypto_box_NONCEBYTES);
cipher = &nonce[crypto_box_NONCEBYTES];
_SuperNET_cipher(nonce,cipher,(void *)message,len,destpubkey,privkey,buf);
if ( buf != space )
free(buf);
if ( allocsize > sizeof(space)/2 )
hexstr = calloc(1,(allocsize<<1)+1);
else hexstr = (void *)space;
init_hexbytes_noT(hexstr,origptr,allocsize);
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","ciphered message");
jaddstr(retjson,"message",message);
jaddstr(retjson,"cipher",hexstr);
init_hexbytes_noT(hexstr,nonce,crypto_box_NONCEBYTES);
jaddstr(retjson,"nonce",hexstr);
if ( onetimeflag != 0 )
{
jaddbits256(retjson,"onetime_privkey",privkey);
jaddbits256(retjson,"onetime_pubkey",mypubkey);
if ( onetimeflag == 2 )
jaddstr(retjson,"warning","onetime keypair was used to broadcast");
}
retstr = jprint(retjson,1);
if ( hexstr != (void *)space )
free(hexstr);
if ( origptr != space2 )
free(origptr);
return(retstr);
}
bits256 SuperNET_pindecipher(IGUANA_ARGS,char *pin,char *privcipher)
{
cJSON *testjson; char *mstr,*cstr; bits256 privkey,pinpriv,pinpub;
conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin));
if ( (cstr= SuperNET_decipher(IGUANA_CALLARGS,pinpriv,pinpub,privcipher)) != 0 )
{
if ( (testjson= cJSON_Parse(cstr)) != 0 )
{
if ( (mstr= jstr(testjson,"message")) != 0 && strlen(mstr) == sizeof(bits256)*2 )
{
decode_hex(privkey.bytes,sizeof(privkey),mstr);
} //else jaddstr(retjson,"error","invalid return from deciphering privcipher");
free_json(testjson);
}
free(cstr);
} //else jaddstr(retjson,"error","null return from deciphering privcipher");
return(privkey);
}
THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey)
{
uint8_t rmd160[20],pub[33],flag = 0; uint64_t nxt64bits; bits256 check,privkey,pubkey,pinpriv,pinpub;
char str2[41],wifbuf[64],addr[64],str[128],privcipher[512],*privcipherstr,*cstr; cJSON *retjson;
nxt64bits = conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase));
if ( showprivkey != 0 && strcmp(showprivkey,"yes") == 0 )
flag = 1;
privcipher[0] = 0;
conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin));
if ( (cstr= SuperNET_cipher(IGUANA_CALLARGS,pinpriv,pinpub,bits256_str(str,privkey))) != 0 )
{
if ( (retjson= cJSON_Parse(cstr)) != 0 )
{
if ( (privcipherstr= jstr(retjson,"cipher")) != 0 )
strcpy(privcipher,privcipherstr);
free_json(retjson);
}
free(cstr);
}
retjson = cJSON_CreateObject();
jaddstr(retjson,"privcipher",privcipher);
jaddbits256(retjson,"pubkey",pubkey);
RS_encode(str,nxt64bits);
jaddstr(retjson,"RS",str);
jadd64bits(retjson,"NXT",nxt64bits);
btc_priv2pub(pub,privkey.bytes);
init_hexbytes_noT(str,pub,33);
jaddstr(retjson,"btcpubkey",str);
calc_OP_HASH160(str2,rmd160,str);
jaddstr(retjson,"rmd160",str2);
if ( btc_coinaddr(addr,0,str) == 0 )
{
jaddstr(retjson,"BTC",addr);
btc_priv2wip(wifbuf,privkey.bytes,0x80);
if ( flag != 0 )
jaddstr(retjson,"BTCwif",wifbuf);
}
if ( btc_coinaddr(addr,60,str) == 0 )
{
jaddstr(retjson,"BTCD",addr);
btc_priv2wip(wifbuf,privkey.bytes,0xbc);
if ( flag != 0 )
jaddstr(retjson,"BTCDwif",wifbuf);
}
if ( flag != 0 )
jaddbits256(retjson,"privkey",privkey);
check = SuperNET_pindecipher(IGUANA_CALLARGS,pin,privcipher);
if ( memcmp(check.bytes,privkey.bytes,sizeof(check)) != 0 )
{
jaddbits256(retjson,"deciphered",check);
jaddstr(retjson,"error","cant recreate privkey from (pin + privcipher)");
}
else if ( flag != 0 )
jaddbits256(retjson,"deciphered",check);
if ( jobj(retjson,"error") == 0 )
jaddstr(retjson,"result","use pin and privcipher to access wallet");
return(jprint(retjson,1));
}
STRING_ARG(SuperNET,broadcastcipher,message)
{
bits256 zero;
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_cipher(IGUANA_CALLARGS,zero,zero,message));
}
STRING_ARG(SuperNET,broadcastdecipher,message)
{
bits256 zero;
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_decipher(IGUANA_CALLARGS,zero,zero,message));
}
HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message)
{
bits256 zero;
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_cipher(IGUANA_CALLARGS,zero,pubkey,message));
}
HASH_AND_STRING(SuperNET,multicastdecipher,privkey,cipherstr)
{
bits256 zero;
memset(zero.bytes,0,sizeof(zero));
return(SuperNET_decipher(IGUANA_CALLARGS,privkey,zero,cipherstr));
}
ZERO_ARGS(SuperNET,stop)
{
if ( remoteaddr == 0 || strncmp(remoteaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 )
{
iguana_exit();
return(clonestr("{\"result\":\"exit started\"}"));
} else return(clonestr("{\"error\":\"cant do a remote stop of this node\"}"));
}
TWO_ARRAYS(SuperNET,mypeers,supernet,rawpeers)
{
SuperNET_parsepeers(myinfo,supernet,cJSON_GetArraySize(supernet),1);
SuperNET_parsepeers(myinfo,rawpeers,cJSON_GetArraySize(rawpeers),0);
return(clonestr("{\"result\":\"peers parsed\"}"));
}
STRING_ARG(SuperNET,getpeers,activecoin)
{
int32_t i,max = 64;
cJSON *SNjson,*rawjson,*retjson = cJSON_CreateObject();
SNjson = cJSON_CreateArray();
rawjson = cJSON_CreateArray();
if ( coin != 0 )
max = SuperNET_coinpeers(coin,SNjson,rawjson,max);
else
{
for (i=0; i<IGUANA_MAXCOINS&&max>0; i++)
if ( Coins[i] != 0 )
max = SuperNET_coinpeers(Coins[i],SNjson,rawjson,max);
}
if ( max != 64 )
{
jaddstr(retjson,"agent","SuperNET");
jaddstr(retjson,"method","mypeers");
jadd(retjson,"supernet",SNjson);
jadd(retjson,"rawpeers",rawjson);
}
else
{
jaddstr(retjson,"error","no peers");
free_json(SNjson);
free_json(rawjson);
}
return(jprint(retjson,1));
}
TWOSTRINGS_AND_HASH_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,destpub,maxdelay,broadcast)
{
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"cant remote DHT\"}"));
else if ( is_hexstr(hexmsg,(int32_t)strlen(hexmsg)) <= 0 )
return(clonestr("{\"error\":\"message must be in hex\"}"));
return(SuperNET_DHTencode(myinfo,destip,destpub,hexmsg,maxdelay,broadcast));
}
HASH_AND_STRING(SuperNET,saveconf,wallethash,confjsonstr)
{
return(clonestr("{\"result\":\"saveconf here\"}"));
}
HASH_ARRAY_STRING(SuperNET,layer,mypriv,otherpubs,str)
{
return(clonestr("{\"result\":\"layer encrypt here\"}"));
}
THREE_STRINGS(SuperNET,announce,category,subcategory,message)
{
cJSON *argjson = cJSON_CreateObject(); int32_t len; char *hexmsg=0,*retstr = 0;
//SuperNET_ann(myinfo,category,subcategory,message);
if ( remoteaddr == 0 )
{
len = (int32_t)strlen(message);
if ( is_hexstr(message,len) == 0 )
{
}
else hexmsg = message;
retstr = SuperNET_DHTsend(myinfo,GENESIS_PUBKEY,hexmsg,0,1);
if ( hexmsg != message)
free(hexmsg);
}
return(jprint(argjson,1));
}
THREE_STRINGS(SuperNET,survey,category,subcategory,message)
{
return(clonestr("{\"result\":\"layer encrypt here\"}"));
}
#include "../includes/iguana_apiundefs.h"

3
iguana/SuperNET.h

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *
@ -118,6 +118,7 @@ char *SuperNET_DHTsend(struct supernet_info *myinfo,bits256 routehash,char *hexm
uint16_t SuperNET_API2num(char *agent,char *method);
int32_t SuperNET_num2API(char *agent,char *method,uint16_t num);
bits256 SuperNET_sharedseed(bits256 privkey,bits256 otherpub);
int32_t SuperNET_decrypt(bits256 *senderpubp,uint64_t *senderbitsp,uint32_t *timestampp,bits256 mypriv,bits256 mypub,uint8_t *dest,int32_t maxlen,uint8_t *src,int32_t len);
int32_t SuperNET_str2hex(uint8_t *hex,char *str);
void SuperNET_hex2str(char *str,uint8_t *hex,int32_t len);

526
iguana/cards777.c

@ -0,0 +1,526 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "pangea777.h"
bits256 cards777_initcrypt(bits256 data,bits256 privkey,bits256 pubkey,int32_t invert)
{
bits256 hash;
hash = curve25519_shared(privkey,pubkey);
if ( invert != 0 )
hash = crecip_donna(hash);
return(fmul_donna(data,hash));
}
bits256 cards777_cardpriv(bits256 playerpriv,bits256 *cardpubs,int32_t numcards,bits256 cipher)
{
bits256 cardpriv,checkpub; int32_t i;
for (i=0; i<numcards; i++)
{
cardpriv = cards777_initcrypt(cipher,playerpriv,cardpubs[i],1);
//printf("(%llx %llx) ",(long long)cardpriv.txid,(long long)curve25519_shared(playerpriv,cardpubs[i]).txid);
checkpub = curve25519(cardpriv,curve25519_basepoint9());
if ( memcmp(checkpub.bytes,cardpubs[i].bytes,sizeof(bits256)) == 0 )
{
//printf("%d ",cardpriv.bytes[1]);
//printf("decrypted card.%d %llx\n",cardpriv.bytes[1],(long long)cardpriv.txid);
return(cardpriv);
}
}
//printf("\nplayerpriv %llx cipher.%llx\n",(long long)playerpriv.txid,(long long)cipher.txid);
memset(cardpriv.bytes,0,sizeof(cardpriv));
return(cardpriv);
}
int32_t cards777_checkcard(bits256 *cardprivp,int32_t cardi,int32_t slot,int32_t destplayer,bits256 playerpriv,bits256 *cardpubs,int32_t numcards,bits256 card)
{
bits256 cardpriv;
cardpriv = cards777_cardpriv(playerpriv,cardpubs,numcards,card);
if ( cardpriv.txid != 0 )
{
if ( slot >= 0 && destplayer != slot )
printf(">>>>>>>>>>>> ERROR ");
if ( Debuglevel > 2 )
printf("slot.%d B DECODED cardi.%d destplayer.%d cardpriv.[%d]\n",slot,cardi,destplayer,cardpriv.bytes[1]);
*cardprivp = cardpriv;
return(cardpriv.bytes[1]);
}
memset(cardprivp,0,sizeof(*cardprivp));
return(-1);
}
int32_t cards777_validate(bits256 cardpriv,bits256 final,bits256 *cardpubs,int32_t numcards,bits256 *audit,int32_t numplayers,bits256 playerpub)
{
int32_t i; bits256 val,checkcard,ver;
val = final;
for (i=numplayers-1; i>0; i--)
{
val = fmul_donna(audit[i],val);
//if ( memcmp(tmp.bytes,audit[i-1].bytes,sizeof(tmp)) != 0 )
// printf("cards777_validate: mismatched audit[%d] %llx vs %llx %llx\n",i-1,(long long)tmp.txid,(long long)audit[i-1].txid,(long long)audit[i].txid);
}
checkcard = val;//fcontract(val);
if ( memcmp(checkcard.bytes,audit[0].bytes,sizeof(checkcard)) != 0 )
{
printf("cards777_validate: checkcard not validated %llx vs %llx numplayers.%d\n",(long long)checkcard.txid,(long long)audit[0].txid,numplayers);
return(-1);
}
ver = cards777_initcrypt(cardpriv,cardpriv,playerpub,0);
if ( memcmp(checkcard.bytes,ver.bytes,sizeof(checkcard)) != 0 )
{
printf("cards777_validate: ver not validated %llx vs %llx\n",(long long)checkcard.txid,(long long)ver.txid);
return(-1);
}
return(cardpriv.bytes[1]);
}
int32_t cards777_shuffle(bits256 *shuffled,bits256 *cards,int32_t numcards,int32_t N)
{
int32_t i,j,pos,nonz,permi[CARDS777_MAXCARDS],desti[CARDS777_MAXCARDS]; uint8_t x; uint64_t mask;
memset(desti,0,sizeof(desti));
for (i=0; i<numcards; i++)
desti[i] = i;
for (i=0; i<numcards; i++)
{
OS_randombytes(&x,1);
pos = (x % ((numcards-1-i) + 1));
//printf("%d ",pos);
permi[i] = desti[pos];
desti[pos] = desti[numcards-1 - i];
desti[numcards-1 - i] = -1;
}
//printf("pos\n");
for (mask=i=nonz=0; i<numcards; i++)
{
if ( 0 && Debuglevel > 2 )
printf("%d ",permi[i]);
mask |= (1LL << permi[i]);
for (j=0; j<N; j++,nonz++)
shuffled[nonz] = cards[permi[i]*N + j];//, printf("%llx ",(long long)shuffled[nonz].txid);
}
if ( Debuglevel > 2 )
printf("shuffled mask.%llx err.%llx\n",(long long)mask,(long long)(mask ^ ((1LL<<numcards)-1)));
return(0);
}
void cards777_layer(bits256 *layered,bits256 *xoverz,bits256 *incards,int32_t numcards,int32_t N)
{
int32_t i,k,nonz = 0; bits256 z_x;
for (i=nonz=0; i<numcards; i++)
{
for (k=0; k<N; k++,nonz++)
{
xoverz[nonz] = xoverz_donna(rand256(1));
z_x = crecip_donna(xoverz[nonz]);
layered[nonz] = fmul_donna(z_x,incards[nonz]);
//printf("{%llx -> %llx}.%d ",(long long)incards[nonz].txid,(long long)layered[nonz].txid,nonz);
}
//printf("card.%d\n",i);
}
}
int32_t cards777_calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,bits256 *xoverz,int32_t numcards,int32_t N)
{
int32_t size,j;
size = N * sizeof(bits256) * numcards;
calc_shares(allshares,(void *)xoverz,size,size,M,N,sharenrs); // PM &allshares[playerj * size] to playerJ
for (j=0; j<N; j++)
myshares[j] = &allshares[j * size];
return(size);
}
uint8_t *cards777_recover(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t numcards,int32_t N)
{
void *G; int32_t i,size; uint8_t *recover,recovernrs[255];
size = N * sizeof(bits256) * numcards;
if ( (recover= calloc(1,size)) == 0 )
{
printf("cards777_recover: unexpected out of memory error\n");
return(0);
}
memset(recovernrs,0,sizeof(recovernrs));
for (i=0; i<N; i++)
if ( shares[i] != 0 )
recovernrs[i] = sharenrs[i];
G = gfshare_ctx_init_dec(recovernrs,N,size);
for (i=0; i<N; i++)
if ( shares[i] != 0 )
gfshare_ctx_dec_giveshare(G,i,shares[i]);
gfshare_ctx_dec_newshares(G,recovernrs);
gfshare_ctx_dec_extract(G,recover);
gfshare_ctx_free(G);
return(recover);
}
bits256 cards777_pubkeys(bits256 *pubkeys,int32_t numcards,bits256 cmppubkey)
{
int32_t i; bits256 bp,pubkey,hash,check,prod;
memset(check.bytes,0,sizeof(check));
memset(bp.bytes,0,sizeof(bp)), bp.bytes[0] = 9;
prod = fmul_donna(bp,crecip_donna(bp));
for (i=0; i<numcards; i++)
{
pubkey = pubkeys[i];
vcalc_sha256(0,hash.bytes,pubkey.bytes,sizeof(pubkey));
hash.bytes[0] &= 0xf8, hash.bytes[31] &= 0x7f, hash.bytes[31] |= 64;
prod = fmul_donna(prod,hash);
}
check = prod;
if ( cmppubkey.txid != 0 )
{
if ( memcmp(check.bytes,cmppubkey.bytes,sizeof(check)) != 0 )
printf("cards777_pubkeys: mismatched pubkeys permicheck.%llx != prod.%llx\n",(long long)check.txid,(long long)pubkey.txid);
//else printf("pubkeys matched\n");
}
return(check);
}
bits256 cards777_initdeck(bits256 *cards,bits256 *cardpubs,int32_t numcards,int32_t N,bits256 *playerpubs,bits256 *playerprivs)
{
char buf[4096]; bits256 privkey,pubkey,hash, bp,prod; int32_t i,j,nonz,num = 0; uint64_t mask = 0;
bp = curve25519_basepoint9();
prod = crecip_donna(bp);
prod = fmul_donna(bp,prod);
if ( Debuglevel > 2 )
printf("card777_initdeck unit.%llx\n",(long long)prod.txid);
nonz = 0;
while ( mask != (1LL << numcards)-1 )
{
privkey = curve25519_keypair(&pubkey);
buf[0] = 0;
if ( (i=privkey.bytes[1]) < numcards && ((1LL << i) & mask) == 0 )
{
mask |= (1LL << i);
cardpubs[num] = pubkey;
if ( playerprivs != 0 )
sprintf(buf+strlen(buf),"%llx.",(long long)privkey.txid);
for (j=0; j<N; j++,nonz++)
{
cards[nonz] = cards777_initcrypt(privkey,privkey,playerpubs[j],0);
if ( playerprivs != 0 )
sprintf(buf+strlen(buf),"[%llx * %llx -> %llx] ",(long long)cards[nonz].txid,(long long)curve25519_shared(playerprivs[j],pubkey).txid,(long long)cards777_initcrypt(cards[nonz],playerprivs[j],pubkey,1).txid);
}
vcalc_sha256(0,hash.bytes,pubkey.bytes,sizeof(pubkey));
hash.bytes[0] &= 0xf8, hash.bytes[31] &= 0x7f, hash.bytes[31] |= 64;
prod = fmul_donna(prod,hash);
//printf("(%s) num.%d [%llx] %d prod.%llx\n",buf,num,(long long)mask ^ ((1LL << numcards)-1),i,(long long)prod.txid);
num++;
}
}
if ( playerprivs != 0 )
printf("\n%llx %llx playerprivs\n",(long long)playerprivs[0].txid,(long long)playerprivs[1].txid);
if ( 0 && Debuglevel > 2 )
{
for (i=0; i<numcards; i++)
printf("%d ",cards[i*N].bytes[1]);
printf("init order %llx (%llx %llx)\n",(long long)prod.txid,(long long)playerpubs[0].txid,(long long)playerpubs[1].txid);
}
return(prod);
}
uint8_t *cards777_encode(bits256 *encoded,bits256 *xoverz,uint8_t *allshares,uint8_t *myshares[],uint8_t sharenrs[255],int32_t M,bits256 *ciphers,int32_t numcards,int32_t N)
{
bits256 shuffled[CARDS777_MAXCARDS * CARDS777_MAXPLAYERS];
cards777_shuffle(shuffled,ciphers,numcards,N);
cards777_layer(encoded,xoverz,shuffled,numcards,N);
memset(sharenrs,0,255);
init_sharenrs(sharenrs,0,N,N);
cards777_calcmofn(allshares,myshares,sharenrs,M,xoverz,numcards,N);
memcpy(ciphers,shuffled,numcards * N * sizeof(bits256));
if ( 1 )
{
/*{
init_hexbytes_noT(nrs,dp->hand.sharenrs,dp->N);
if ( (nrs= jstr(json,"sharenrs")) != 0 )
decode_hex(dp->hand.sharenrs,(int32_t)strlen(nrs)>>1,nrs);
}*/
int32_t i,j,m,size; uint8_t *recover,*testshares[CARDS777_MAXPLAYERS],testnrs[255];
size = N * sizeof(bits256) * numcards;
for (j=0; j<1; j++)
{
memset(testnrs,0,sizeof(testnrs));
memset(testshares,0,sizeof(testshares));
m = (rand() % N) + 1;
if ( m < M )
m = M;
if ( init_sharenrs(testnrs,sharenrs,m,N) < 0 )
{
printf("iter.%d error init_sharenrs(m.%d of n.%d)\n",j,m,N);
return(0);
}
for (i=0; i<N; i++)
if ( testnrs[i] == sharenrs[i] )
testshares[i] = myshares[i];
if ( (recover= cards777_recover(testshares,sharenrs,M,numcards,N)) != 0 )
{
if ( memcmp(xoverz,recover,size) != 0 )
fprintf(stderr,"(ERROR m.%d M.%d N.%d)\n",m,M,N);
else fprintf(stderr,"reconstructed with m.%d M.%d N.%d\n",m,M,N);
free(recover);
} else printf("nullptr from cards777_recover\n");
}
}
return(allshares);
}
bits256 cards777_decode(bits256 *seedp,bits256 *xoverz,int32_t destplayer,bits256 cipher,bits256 *outcards,int32_t numcards,int32_t N)
{
int32_t i,ind;
memset(seedp->bytes,0,sizeof(*seedp));
for (i=0; i<numcards; i++)
{
ind = i*N + destplayer;
//printf("[%llx] ",(long long)outcards[ind].txid);
if ( memcmp(outcards[ind].bytes,cipher.bytes,32) == 0 )
{
*seedp = xoverz[ind];
cipher = fmul_donna(xoverz[ind],cipher);
//printf("matched %d -> %llx\n",i,(long long)cipher.txid);
return(cipher);
}
}
if ( i == numcards )
{
printf("decryption error %llx: destplayer.%d no match\n",(long long)cipher.txid,destplayer);
memset(cipher.bytes,0,sizeof(cipher));
//cipher = cards777_cardpriv(playerpriv,cardpubs,numcards,cipher);
}
return(cipher);
}
struct cards777_privdata *cards777_allocpriv(int32_t numcards,int32_t N)
{
struct cards777_privdata *priv;
if ( (priv= calloc(1,sizeof(*priv) + sizeof(bits256) * (2*((N * numcards * N) + (N * numcards))))) == 0 )
{
printf("cards777_allocpriv: unexpected out of memory error\n");
return(0);
}
priv->audits = &priv->data[0];
priv->outcards = &priv->audits[N * numcards * N];
priv->xoverz = &priv->outcards[N * numcards];
priv->allshares = (void *)&priv->xoverz[N * numcards]; // N*numcards*N
return(priv);
}
struct cards777_pubdata *cards777_allocpub(int32_t M,int32_t numcards,int32_t N)
{
struct cards777_pubdata *dp;
if ( (dp= calloc(1,sizeof(*dp) + sizeof(bits256) * ((numcards + 1) + (N * numcards)))) == 0 )
{
printf("cards777_allocpub: unexpected out of memory error\n");
return(0);
}
dp->M = M, dp->N = N, dp->numcards = numcards;
dp->hand.cardpubs = &dp->data[0];
dp->hand.final = &dp->hand.cardpubs[numcards + 1];
return(dp);
}
#ifdef notyet
int32_t cards777_testinit(struct hostnet777_server *srv,int32_t M,struct hostnet777_client **clients,int32_t N,int32_t numcards)
{
//static int64_t balances[9];
int32_t i; uint8_t sharenrs[255]; //,destplayer,cardibits256 *ciphers,cardpriv,card; uint64_t mask = 0;
struct cards777_pubdata *dp; //struct cards777_privdata *priv; struct pangea_info *sp;
if ( srv->num != N )
{
printf("srv->num.%d != N.%d\n",srv->num,N);
return(-1);
}
memset(sharenrs,0,sizeof(sharenrs));
init_sharenrs(sharenrs,0,N,N); // this needs to be done to start a hand
for (i=0; i<N; i++)
{
dp = srv->clients[i].pubdata = cards777_allocpub(M,numcards,N);
//sp = dp->table;
memcpy(dp->hand.sharenrs,sharenrs,dp->N);
/*for (j=0; j<N; j++)
sp->playerpubs[j] = srv->clients[j].pubkey;
for (j=0; j<N; j++)
{
balances[j] = 100;
dp->balances[j] = &balances[j];
}*/
printf("deprecated, need to init sp->\n");
//priv = srv->clients[i].privdata = cards777_allocpriv(numcards,N);
//priv->privkey = (i == 0) ? srv->H.privkey : clients[i]->H.privkey;
/*if ( i == 0 )
dp->checkprod = cards777_initdeck(priv->outcards,dp->cardpubs,numcards,N,dp->playerpubs), refdp = dp;
else memcpy(dp->cardpubs,refdp->cardpubs,sizeof(*dp->cardpubs) * numcards);*/
}
return(0);
/*priv = srv->clients[0].privdata;
ciphers = priv->outcards;
for (i=1; i<N; i++)
{
dp = srv->clients[i].pubdata;
priv = srv->clients[i].privdata;
cards777_encode(priv->outcards,priv->xoverz,priv->allshares,priv->myshares,dp->sharenrs,dp->M,ciphers,dp->numcards,dp->N);
ciphers = priv->outcards;
}
for (cardi=0; cardi<dp->numcards; cardi++)
{
for (destplayer=0; destplayer<dp->N; destplayer++)
{
priv = srv->clients[dp->N - 1].privdata;
card = priv->outcards[cardi*dp->N + destplayer];
for (i=N-1; i>=0; i--)
{
j = (i > 0) ? i : destplayer;
//printf("cardi.%d destplayer.%d i.%d j.%d\n",cardi,destplayer,i,j);
dp = srv->clients[j].pubdata;
priv = srv->clients[j].privdata;
cardpriv = cards777_cardpriv(priv->privkey,dp->cardpubs,dp->numcards,card);
if ( cardpriv.txid != 0 )
{
mask |= (1LL << cardpriv.bytes[1]);
if ( destplayer != j )
printf(">>>>>>>>>>>> ERROR ");
printf("i.%d j.%d A DECODED cardi.%d destplayer.%d cardpriv.[%d] mask.%llx\n",i,j,cardi,destplayer,cardpriv.bytes[1],(long long)mask);
break;
}
card = cards777_decode(priv->xoverz,destplayer,card,priv->outcards,dp->numcards,dp->N);
cardpriv = cards777_cardpriv(priv->privkey,dp->cardpubs,dp->numcards,card);
if ( cardpriv.txid != 0 )
{
mask |= (1LL << cardpriv.bytes[1]);
if ( destplayer != j )
printf(">>>>>>>>>>>> ERROR ");
printf("i.%d j.%d B DECODED cardi.%d destplayer.%d cardpriv.[%d] mask.%llx\n",i,j,cardi,destplayer,cardpriv.bytes[1],(long long)mask);
break;
}
}
}
printf("cardi.%d\n\n",cardi);
}*/
return(0);
}
void cards777_initid(struct hostnet777_id *id,bits256 pubkey,struct cards777_pubdata *dp,struct cards777_privdata *priv)
{
id->pubkey = pubkey;
id->nxt64bits = acct777_nxt64bits(pubkey);
id->pubdata = dp;
id->privdata = priv;
id->pmsock = -1;
}
void cards777_test()
{
int32_t i,j,vals[52][52]; bits256 keypairs[52][2],otherpairs[52][2],matrix[52][52]; char buf[512];
FILE *fp;
if ( (fp= fopen("/persistent/test","rb")) != 0 )
{
if ( fread(buf,6,1,fp) <= 0 )
printf("read error for /persistent/test\n");
buf[6] = 0;
printf("test exists (%s)\n",buf);
fclose(fp);
} else printf("testfile not present\n");
for (i=0; i<52; i++)
keypairs[i][0] = curve25519_keypair(&keypairs[i][1]);
for (j=0; j<52; j++)
otherpairs[j][0] = curve25519_keypair(&otherpairs[j][1]);
bits256 zmone;zmone = crecip_donna(keypairs[0][0]);
printf("DEBUG.%d %llx vs %llx | %llx -> %llx/%llx\n",Debuglevel,(long long)keypairs[0][0].txid,(long long)fcontract(fexpand(keypairs[0][0])).txid,(long long)zmone.txid,(long long)fexpand(fmul_donna(keypairs[0][0],zmone)).txid,(long long)fmul(fexpand(keypairs[0][0]),fexpand(zmone)).txid);
for (i=0; i<52; i++)
{break;
buf[0] = 0;
for (j=0; j<52; j++)
{
matrix[i][j] = fmul_donna(keypairs[j][1],otherpairs[i][1]);
vals[i][j] = matrix[i][j].bytes[1] % 52;
sprintf(buf+strlen(buf),"%d ",vals[i][j]);
}
printf("%s\n",buf);
}
struct hostnet777_server *srv; int32_t M,N = 9; //struct hostnet777_client **clients;
struct cards777_pubdata *dp; struct cards777_privdata *priv;
bits256 checkprod,cards[52],playerpubs[9],playerprivs[9];
//clients = calloc(N+1,sizeof(*clients));
if ( (srv= hostnet777_server(keypairs[0][0],keypairs[0][1],0,0,0,N)) == 0 )
{
printf("cant create hostnet777 server\n");
return;
}
M = (N >> 1) + 1;
for (i=0; i<N; i++)
{
cards777_initid(&srv->clients[i],keypairs[i][1],cards777_allocpub(M,52,N),cards777_allocpriv(52,N));
playerprivs[i] = keypairs[i][0];
playerpubs[i] = keypairs[i][1];
if ( i == 0 )
{
srv->H.privkey = keypairs[i][0];
srv->H.pubkey = keypairs[i][1];
}
else
{
}
}
dp = srv->clients[0].pubdata;
dp->N = N; dp->M = M; dp->numcards = 52;
checkprod = cards777_initdeck(cards,dp->hand.cardpubs,52,N,playerpubs,0);
printf("deck initialzed %llx\n",(long long)checkprod.txid);
uint8_t sharenrs[255]; uint64_t mask = 0; int32_t cardi,destplayer;
bits256 card,cardpriv,seed,*ciphers = cards;
for (i=1; i<N; i++)
{
dp = srv->clients[i].pubdata;
dp->N = N; dp->M = M; dp->numcards = 52;
priv = srv->clients[i].privdata;
cards777_encode(priv->outcards,priv->xoverz,priv->allshares,priv->myshares,sharenrs,dp->M,ciphers,dp->numcards,dp->N);
ciphers = priv->outcards;
}
printf("deck encrypted\n");
for (cardi=0; cardi<dp->numcards; cardi++)
{
for (destplayer=0; destplayer<dp->N; destplayer++)
{
priv = srv->clients[dp->N - 1].privdata;
card = priv->outcards[cardi*dp->N + destplayer];
for (i=N-1; i>=0; i--)
{
j = (i > 0) ? i : destplayer;
//printf("cardi.%d destplayer.%d i.%d j.%d\n",cardi,destplayer,i,j);
dp = srv->clients[j].pubdata;
priv = srv->clients[j].privdata;
cardpriv = cards777_cardpriv(keypairs[j][0],dp->hand.cardpubs,dp->numcards,card);
if ( cardpriv.txid != 0 )
{
mask |= (1LL << cardpriv.bytes[1]);
if ( destplayer != j )
printf(">>>>>>>>>>>> ERROR ");
printf("i.%d j.%d A DECODED cardi.%d destplayer.%d cardpriv.[%d] mask.%llx\n",i,j,cardi,destplayer,cardpriv.bytes[1],(long long)mask);
break;
}
card = cards777_decode(&seed,priv->xoverz,destplayer,card,priv->outcards,dp->numcards,dp->N);
cardpriv = cards777_cardpriv(keypairs[j][0],dp->hand.cardpubs,dp->numcards,card);
if ( cardpriv.txid != 0 )
{
mask |= (1LL << cardpriv.bytes[1]);
if ( destplayer != j )
printf(">>>>>>>>>>>> ERROR ");
printf("i.%d j.%d B DECODED cardi.%d destplayer.%d cardpriv.[%d] mask.%llx\n",i,j,cardi,destplayer,cardpriv.bytes[1],(long long)mask);
break;
}
}
}
printf("cardi.%d\n\n",cardi);
break;
}
}
#endif

2
iguana/iguana.sources

@ -1,3 +1,3 @@
#iguana_html.c
SOURCES := SuperNET.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c
SOURCES := SuperNET.c pangea_api.c pangea_fsm.c pangea_network.c pangea_init.c poker.c ramchain_api.c iguana_tx.c iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c main.c

2
iguana/iguana777.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

3
iguana/iguana777.h

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *
@ -695,6 +695,7 @@ int32_t iguana_pendingaccept(struct iguana_info *coin);
char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr);
void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t markflag);
cJSON *SuperNET_bits2json(bits256 mypriv,bits256 mypub,struct iguana_peer *addr,uint8_t *serialized,uint8_t *space,int32_t datalen,int32_t iscompressed);
int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis);
extern queue_t bundlesQ;

2
iguana/iguana_accept.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_bitmap.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_blocks.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_bundles.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_chains.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_html.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_init.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

155
iguana/iguana_json.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *
@ -99,9 +99,11 @@ cJSON *SuperNET_helpjson()
#define IGUANA_HELP_III(agent,name,val,val2,val3) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"int"),helpitem(#val3,"int")))
#define IGUANA_HELP_IAS(agent,name,val,obj,str) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#obj,"array"),helpitem(#str,"string")))
#define IGUANA_HELP_64A(agent,name,j64,obj) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#j64,"u64bits"),helpitem(#obj,"array")))
#define IGUANA_HELP_AA(agent,name,obj,obj2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#obj,"array"),helpitem(#obj2,"array")))
#define IGUANA_HELP_D(agent,name,amount) array = helpjson(IGUANA_ARGS,#agent,#name,helparray(cJSON_CreateArray(),helpitem(#amount,"float")))
#define IGUANA_HELP_H(agent,name,hash) array = helpjson(IGUANA_ARGS,#agent,#name,helparray(cJSON_CreateArray(),helpitem(#hash,"hash")))
#define IGUANA_HELP_HI(agent,name,hash,val) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#val,"int")))
#define IGUANA_HELP_HS(agent,name,hash,str) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#str,"str")))
#define IGUANA_HELP_HII(agent,name,hash,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#hash,"hash"),helpitem(#val,"int"),helpitem(#val2,"int")))
@ -143,9 +145,10 @@ cJSON *SuperNET_helpjson()
#define THREE_INTS IGUANA_HELP_III
#define TWOHASHES_AND_STRING IGUANA_HELP_HHS
#define HASH_ARRAY_STRING IGUANA_HELP_HAS
#define U64_AND_ARRAY IGUANA_HELP_64A
#define HASH_ARG IGUANA_HELP_H
#include "../includes/iguana_apideclares.h"
#undef IGUANA_ARGS
#include "../includes/iguana_apiundefs.h"
if ( array != 0 )
@ -318,133 +321,8 @@ cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly)
else return(array);
}
cJSON *SuperNET_peerarray(struct iguana_info *coin,int32_t max,int32_t supernetflag)
{
int32_t i,r,j,n = 0; struct iguana_peer *addr; cJSON *array = cJSON_CreateArray();
r = rand();
for (j=0; j<IGUANA_MAXPEERS; j++)
{
i = (r + j) % IGUANA_MAXPEERS;
addr = &coin->peers.active[i];
if ( addr->usock >= 0 && supernetflag == (addr->supernet != 0) )
{
jaddistr(array,addr->ipaddr);
if ( ++n >= max )
break;
}
}
if ( n == 0 )
{
free_json(array);
return(0);
}
return(array);
}
int32_t SuperNET_coinpeers(struct iguana_info *coin,cJSON *SNjson,cJSON *rawjson,int32_t max)
{
cJSON *array,*item;
if ( (array= SuperNET_peerarray(coin,max,1)) != 0 )
{
max -= cJSON_GetArraySize(array);
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jadd(item,"peers",array);
jaddi(SNjson,item);
}
if ( max > 0 && (array= SuperNET_peerarray(coin,max,0)) != 0 )
{
max -= cJSON_GetArraySize(array);
item = cJSON_CreateObject();
jaddstr(item,"coin",coin->symbol);
jadd(item,"peers",array);
jaddi(rawjson,item);
}
return(max);
}
void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int32_t supernetflag)
{
int32_t i,j,m; cJSON *coinarray,*item; char *symbol,*ipaddr; struct iguana_info *ptr;
if ( array != 0 && n > 0 )
{
for (i=0; i<n; i++)
{
if ( (item= jitem(array,i)) != 0 && (symbol= jstr(item,"coin")) != 0 )
{
ptr = iguana_coinfind(symbol);
if ( (coinarray= jarray(&m,item,"peers")) != 0 )
{
for (j=0; j<m; j++)
{
if ( (ipaddr= jstr(jitem(coinarray,j),0)) != 0 )
SuperNET_remotepeer(myinfo,ptr,symbol,ipaddr,supernetflag);
else printf("no ipaddr[%d] of %d\n",j,m);
}
}
printf("parsed.%d %s.peers supernet.%d\n",m,symbol,supernetflag);
}
}
}
}
#include "../includes/iguana_apidefs.h"
TWOSTRINGS_AND_HASH_AND_TWOINTS(SuperNET,DHT,message,destip,destpub,maxdelay,broadcast)
{
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"cant remote DHT\"}"));
else if ( is_hexstr(message,(int32_t)strlen(message)) <= 0 )
return(clonestr("{\"error\":\"message must be in hex\"}"));
return(SuperNET_DHTencode(myinfo,destip,destpub,message,maxdelay,broadcast));
}
ZERO_ARGS(SuperNET,stop)
{
if ( remoteaddr == 0 || strncmp(remoteaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 )
{
iguana_exit();
return(clonestr("{\"result\":\"exit started\"}"));
} else return(clonestr("{\"error\":\"cant do a remote stop of this node\"}"));
}
TWO_ARRAYS(SuperNET,mypeers,supernet,rawpeers)
{
SuperNET_parsepeers(myinfo,supernet,cJSON_GetArraySize(supernet),1);
SuperNET_parsepeers(myinfo,rawpeers,cJSON_GetArraySize(rawpeers),0);
return(clonestr("{\"result\":\"peers parsed\"}"));
}
STRING_ARG(SuperNET,getpeers,activecoin)
{
int32_t i,max = 64;
cJSON *SNjson,*rawjson,*retjson = cJSON_CreateObject();
SNjson = cJSON_CreateArray();
rawjson = cJSON_CreateArray();
if ( coin != 0 )
max = SuperNET_coinpeers(coin,SNjson,rawjson,max);
else
{
for (i=0; i<IGUANA_MAXCOINS&&max>0; i++)
if ( Coins[i] != 0 )
max = SuperNET_coinpeers(Coins[i],SNjson,rawjson,max);
}
if ( max != 64 )
{
jaddstr(retjson,"agent","SuperNET");
jaddstr(retjson,"method","mypeers");
jadd(retjson,"supernet",SNjson);
jadd(retjson,"rawpeers",rawjson);
}
else
{
jaddstr(retjson,"error","no peers");
free_json(SNjson);
free_json(rawjson);
}
return(jprint(retjson,1));
}
STRING_ARG(iguana,peers,activecoin)
{
if ( coin != 0 )
@ -670,22 +548,7 @@ TWO_STRINGS(SuperNET,html,agentform,htmlfile)
fclose(fp);
return(jprint(retjson,1));
}
ZERO_ARGS(SuperNET,saveconf)
{
return(clonestr("{\"result\":\"saveconf here\"}"));
}
HASH_ARRAY_STRING(SuperNET,layer,mypriv,otherpubs,str)
{
return(clonestr("{\"result\":\"layer encrypt here\"}"));
}
HASH_AND_STRING(SuperNET,sharepersistent,persistentpub,destip)
{
return(clonestr("{\"result\":\"share persistent here\"}"));
}
#undef IGUANA_ARGS
#include "../includes/iguana_apiundefs.h"
@ -720,10 +583,12 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agent,char *method,cJSO
#define IGUANA_DISPATCH_IA(agent,name,val,array) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,juint(json,#val),jobj(json,#array)))
#define IGUANA_DISPATCH_IAS(agent,name,val,array,str) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,juint(json,#val),jobj(json,#array),jstr(json,#str)))
#define IGUANA_DISPATCH_64A(agent,name,j64,array) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,j64bits(json,#j64),jobj(json,#array)))
#define IGUANA_DISPATCH_AA(agent,name,array,array2) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jobj(json,#array),jobj(json,#array2)))
#define IGUANA_DISPATCH_D(agent,name,amount) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jdouble(json,#amount)))
#define IGUANA_DISPATCH_H(agent,name,hash) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash)))
#define IGUANA_DISPATCH_HI(agent,name,hash,val) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),juint(json,#val)))
#define IGUANA_DISPATCH_HS(agent,name,hash,str) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),jstr(json,#str)))
#define IGUANA_DISPATCH_HII(agent,name,hash,val,val2) else if ( strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jbits256(json,#hash),juint(json,#val),juint(json,#val2)))
@ -765,9 +630,11 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agent,char *method,cJSO
#define THREE_INTS IGUANA_DISPATCH_III
#define TWOHASHES_AND_STRING IGUANA_DISPATCH_HHS
#define HASH_ARRAY_STRING IGUANA_DISPATCH_HAS
#define U64_AND_ARRAY IGUANA_DISPATCH_64A
#define HASH_ARG IGUANA_DISPATCH_H
#include "../includes/iguana_apideclares.h"
#undef IGUANA_ARGS
//#undef IGUANA_ARGS
#include "../includes/iguana_apiundefs.h"

2
iguana/iguana_msg.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_peers.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_pubkeys.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_ramchain.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_recv.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_rpc.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_tx.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
iguana/iguana_wallet.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

3
iguana/main.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *
@ -31,6 +31,7 @@ char *Iguana_validcommands[] =
"version", "verack", "getaddr", "addr", "inv", "getdata", "notfound", "getblocks", "getheaders", "headers", "tx", "block", "mempool", "ping", "pong",
"reject", "filterload", "filteradd", "filterclear", "merkleblock", "alert", ""
};
int32_t Showmode,Autofold,PANGEA_MAXTHREADS = 1;
struct iguana_info *Coins[IGUANA_MAXCOINS];
int32_t USE_JAY,FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel;

189
iguana/pangea777.h

@ -0,0 +1,189 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef PANGEA777_H
#define PANGEA777_H
#include "iguana777.h"
#define TEST_TRANSPORT "http://"
#define _PANGEA_MAXTHREADS 9
#define PANGEA_MINRAKE_MILLIS 5
#define PANGEA_USERTIMEOUT 60
#define PANGEA_MAX_HOSTRAKE 5
#define PANGEA_BTCMAXRAKE (SATOSHIDEN / 100)
#define PANGEA_MAXRAKE (3 * SATOSHIDEN)
#define PANGEA_HANDGAP 30
#define PANGEA_PAUSE 5
#define CARDS777_MAXCARDS 52
#define CARDS777_MAXPLAYERS 9
#define CARDS777_FOLD -1
#define CARDS777_START 1
#define CARDS777_ANTE 2
#define CARDS777_SMALLBLIND 3
#define CARDS777_BIGBLIND 4
#define CARDS777_CHECK 5
#define CARDS777_CALL 6
#define CARDS777_BET 7
#define CARDS777_RAISE 8
#define CARDS777_FULLRAISE 9
#define CARDS777_SENTCARDS 10
#define CARDS777_ALLIN 11
#define CARDS777_FACEUP 12
#define CARDS777_WINNINGS 13
#define CARDS777_RAKES 14
#define CARDS777_CHANGES 15
#define CARDS777_SNAPSHOT 16
struct cards777_handinfo
{
bits256 checkprod,*cardpubs,*final,community256[5],cards[CARDS777_MAXPLAYERS][2];
uint64_t othercardpubs[CARDS777_MAXPLAYERS];
int64_t havemasks[CARDS777_MAXPLAYERS],betsize,hostrake,pangearake,lastraise,bets[CARDS777_MAXPLAYERS],snapshot[CARDS777_MAXPLAYERS+1],won[CARDS777_MAXPLAYERS];
uint32_t starttime,handmask,lastbettor,startdecktime,betstarted,finished,encodestarted;
uint32_t cardi,userinput_starttime,handranks[CARDS777_MAXPLAYERS];
int8_t betstatus[CARDS777_MAXPLAYERS],actions[CARDS777_MAXPLAYERS],turnis[CARDS777_MAXPLAYERS];
uint8_t numactions,undergun,community[5],sharenrs[CARDS777_MAXPLAYERS][255],hands[CARDS777_MAXPLAYERS][7];
};
struct cards777_pubdata
{
int64_t snapshot[CARDS777_MAXPLAYERS];
uint64_t maxrake,hostrake,bigblind,ante,pangearake,summaries,mismatches;
uint32_t button,readymask,numhands,rakemillis,minbuyin,maxbuyin,summarysize;
void *table; struct cards777_handinfo hand;
char newhand[65536],coinstr[16]; uint8_t M,N,numcards,summary[65536]; bits256 data[];
};
struct cards777_privdata
{
bits256 holecards[2],*audits,*outcards,*xoverz;
//,*reconstructed[CARDS777_MAXPLAYERS],*mofn[CARDS777_MAXPLAYERS][CARDS777_MAXPLAYERS];
uint8_t *myshares[CARDS777_MAXPLAYERS],*allshares,hole[2],cardis[2],automuck,autofold;
bits256 data[];
};
extern int32_t Debuglevel;
bits256 xoverz_donna(bits256 a);
bits256 crecip_donna(bits256 a);
bits256 fmul_donna(bits256 a,bits256 b);
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 init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n);
struct pangea_info
{
uint32_t timestamp,numaddrs,minbuyin,maxbuyin;
int64_t balances[CARDS777_MAXPLAYERS]; uint8_t isbot[CARDS777_MAXPLAYERS]; bits256 playerpubs[CARDS777_MAXPLAYERS];
uint64_t basebits,bigblind,ante,addrs[CARDS777_MAXPLAYERS],active[CARDS777_MAXPLAYERS],tableid;
char btcpubkeystr[67],wipstr[64],coinstr[16],multisigaddr[64],scriptPubKey[128],redeemScript[4096];
uint8_t addrtype,p2shtype,wiftype,btcpub[33];
int32_t myslot,myind,numactive,buyinvouts[CARDS777_MAXPLAYERS]; uint64_t buyinamounts[CARDS777_MAXPLAYERS];
char buyintxids[CARDS777_MAXPLAYERS][128],coinaddrs[CARDS777_MAXPLAYERS][67],btcpubkeys[CARDS777_MAXPLAYERS][67];
struct pangea_thread *tp; struct cards777_privdata *priv; struct cards777_pubdata *dp;
} *TABLES[100];
//./BitcoinDarkd SuperNET '{"agent":"InstantDEX","method":"orderbook","exchange":"active","base":"NXT","rel":"BTC"}'
// ./SNapi "{\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"exchange\":\"pangea\",\"base\":\"NXT\"}"
// ./SNapi "{\"agent\":\"InstantDEX\",\"method\":\"placebid\",\"exchange\":\"pangea\",\"base\":\"NXT\"}"
struct pangeanet777_endpoint { char endpoint[128],transport[16],ipaddr[64]; uint16_t port; };
struct pangeanet777_id { bits256 pubkey; uint64_t nxt64bits; void *privdata,*pubdata; int32_t pmsock; uint32_t lastcontact; };
union pangeanet777 { struct pangeanet777_server *server; struct pangeanet777_client *client; };
struct pangeanet777_hdr
{
queue_t Q; bits256 privkey,pubkey;
void *privdata,*pubdata; uint64_t nxt64bits;//,recvhashes[64];
void (*pollfunc)(union pangeanet777 *hn);
uint32_t lastping; int32_t slot,done,state,ind;
};
struct pangeanet777_client { struct pangeanet777_hdr H; int32_t subsock; struct pangeanet777_id my; uint64_t balance,tableid; };
struct pangeanet777_server
{
struct pangeanet777_hdr H;
int32_t num,max,pubsock; struct pangeanet777_endpoint ep; //queue_t mailboxQ[CARDS777_MAXPLAYERS];
struct pangeanet777_id clients[];
};
struct pangea_thread
{
union pangeanet777 hn; uint64_t nxt64bits; int32_t threadid,ishost,M,N,numcards;
} *THREADS[_PANGEA_MAXTHREADS];
int32_t SuperNET_copybits(int32_t reverse,uint8_t *dest,uint8_t *src,int32_t len);
int32_t cardstr(char *cardstr,uint8_t card);
uint32_t set_handstr(char *handstr,uint8_t cards[7],int32_t verbose);
struct cards777_pubdata *cards777_allocpub(int32_t M,int32_t numcards,int32_t N);
struct cards777_privdata *cards777_allocpriv(int32_t numcards,int32_t N);
bits256 cards777_initdeck(bits256 *cards,bits256 *cardpubs,int32_t numcards,int32_t N,bits256 *playerpubs,bits256 *playerprivs);
bits256 cards777_pubkeys(bits256 *pubkeys,int32_t numcards,bits256 cmppubkey);
int32_t cards777_checkcard(bits256 *cardprivp,int32_t cardi,int32_t slot,int32_t destplayer,bits256 playerpriv,bits256 *cardpubs,int32_t numcards,bits256 card);
int32_t cards777_validate(bits256 cardpriv,bits256 final,bits256 *cardpubs,int32_t numcards,bits256 *audit,int32_t numplayers,bits256 playerpub);
bits256 cards777_decode(bits256 *seedp,bits256 *xoverz,int32_t destplayer,bits256 cipher,bits256 *outcards,int32_t numcards,int32_t N);
uint8_t *cards777_encode(bits256 *encoded,bits256 *xoverz,uint8_t *allshares,uint8_t *myshares[],uint8_t sharenrs[255],int32_t M,bits256 *ciphers,int32_t numcards,int32_t N);
int32_t pangea_search(struct pangea_info *sp,uint64_t nxt64bits);
int32_t pangea_tableaddr(struct cards777_pubdata *dp,uint64_t destbits);
struct pangea_info *pangea_find64(uint64_t tableid,uint64_t nxt64bits);
struct pangea_info *pangea_find(uint64_t tableid,int32_t threadid);
int32_t pangea_neworder(struct cards777_pubdata *dp,struct pangea_info *sp,uint64_t *active,int32_t numactive);
cJSON *pangea_tablestatus(struct pangea_info *sp);
void pangea_summary(union pangeanet777 *hn,struct cards777_pubdata *dp,uint8_t type,void *arg0,int32_t size0,void *arg1,int32_t size1);
void pangea_startbets(union pangeanet777 *hn,struct cards777_pubdata *dp,int32_t cardi);
void pangea_checkantes(union pangeanet777 *hn,struct cards777_pubdata *dp);
uint64_t pangea_bot(union pangeanet777 *hn,struct cards777_pubdata *dp,int32_t turni,int32_t cardi,uint64_t betsize);
char *pangea_dispsummary(struct pangea_info *sp,int32_t verbose,uint8_t *summary,int32_t summarysize,uint64_t tableid,int32_t handid,int32_t numplayers);
char *_pangea_input(uint64_t my64bits,uint64_t tableid,cJSON *json);
void pangea_finish(union pangeanet777 *hn,struct cards777_pubdata *dp);
void pangea_serverstate(union pangeanet777 *hn,struct cards777_pubdata *dp,struct cards777_privdata *priv);
int32_t pangea_anotherhand(void *hn,struct cards777_pubdata *dp,int32_t sleepflag);
void pangea_clearhand(struct cards777_pubdata *dp,struct cards777_handinfo *hand,struct cards777_privdata *priv);
void pangea_create_newtable(char *retbuf,struct pangea_info *sp,struct cards777_pubdata *dp,uint64_t *isbot);
void pangea_buyins(uint32_t *minbuyinp,uint32_t *maxbuyinp);
int32_t pangea_sidepots(int32_t dispflag,uint64_t sidepots[CARDS777_MAXPLAYERS][CARDS777_MAXPLAYERS],struct cards777_pubdata *dp,int64_t *bets);
int64_t pangea_splitpot(int64_t *won,uint64_t *pangearakep,uint64_t sidepot[CARDS777_MAXPLAYERS],union pangeanet777 *hn,int32_t rakemillis);
int32_t pangea_actives(int32_t *activej,struct cards777_pubdata *dp);
int32_t pangea_bet(union pangeanet777 *hn,struct cards777_pubdata *dp,int32_t player,int64_t bet,int32_t action);
uint64_t pangea_winnings(int32_t player,uint64_t *pangearakep,uint64_t *hostrakep,uint64_t total,int32_t numwinners,int32_t rakemillis,uint64_t maxrake);
int32_t _pangea_addfunds(union pangeanet777 *hn,cJSON *json,struct cards777_pubdata *dp,struct cards777_privdata *priv,uint8_t *data,int32_t datalen,int32_t senderind);
void _pangea_chat(uint64_t senderbits,void *buf,int32_t len,int32_t senderind);
void pangea_sendcmd(char *hex,union pangeanet777 *hn,char *cmdstr,int32_t destplayer,uint8_t *data,int32_t datalen,int32_t cardi,int32_t turni);
int32_t pangea_slotA(struct pangea_info *sp);
int32_t pangea_slotB(struct pangea_info *sp);
int32_t pangea_slot(struct pangea_info *sp,int32_t ind);
int32_t pangea_ind(struct pangea_info *sp,int32_t slot);
int32_t pangea_slot(struct pangea_info *sp,int32_t ind);
int32_t pangea_poll(uint64_t *senderbitsp,uint32_t *timestampp,union pangeanet777 *hn);
int32_t pangeanet777_register(struct pangeanet777_server *srv,bits256 clientpub,int32_t slot);
struct pangeanet777_client *pangeanet777_client(bits256 privkey,bits256 pubkey,char *srvendpoint,int32_t slot);
struct pangeanet777_server *pangeanet777_server(bits256 srvprivkey,bits256 srvpubkey,char *transport,char *ipaddr,uint16_t port,int32_t maxclients);
int32_t pangeanet777_idle(union pangeanet777 *hn);
void pangeanet777_msg(uint64_t destbits,bits256 destpub,union pangeanet777 *src,int32_t blindflag,char *jsonstr,int32_t len);
struct pangea_info *pangea_threadtables(int32_t *nump,int32_t threadid,uint64_t tableid);
extern int32_t Debuglevel,PANGEA_MAXTHREADS,Showmode,Autofold;
bits256 issue_getpubkey(int32_t *haspubkeyp,char *acct);
#endif

594
iguana/pangea_api.c

@ -0,0 +1,594 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "pangea777.h"
void pangea_sendcmd(char *hex,union pangeanet777 *hn,char *cmdstr,int32_t destplayer,uint8_t *data,int32_t datalen,int32_t cardi,int32_t turni)
{
int32_t n,hexlen,blindflag = 0; uint64_t destbits; bits256 destpub; cJSON *json; char hoststr[1024]; struct pangea_info *sp;
struct cards777_pubdata *dp = hn->client->H.pubdata;
hoststr[0] = 0;
sp = dp->table;
sprintf(hex,"{\"cmd\":\"%s\",\"turni\":%d,\"myslot\":%d,\"myind\":%d,\"cardi\":%d,\"dest\":%d,\"sender\":\"%llu\",\"timestamp\":\"%lu\",\"n\":%u,%s\"data\":\"",cmdstr,turni,hn->client->H.slot,pangea_ind(dp->table,hn->client->H.slot),cardi,destplayer,(long long)hn->client->H.nxt64bits,(long)time(NULL),datalen,hoststr);
n = (int32_t)strlen(hex);
if ( strcmp(cmdstr,"preflop") == 0 )
{
memcpy(&hex[n],data,datalen+1);
hexlen = (int32_t)strlen(hex)+1;
PNACL_message("P%d HEX.[] hexlen.%d n.%d\n",hn->server->H.slot,hexlen,datalen);
}
else if ( data != 0 && datalen != 0 )
init_hexbytes_noT(&hex[n],data,datalen);
strcat(hex,"\"}");
if ( (json= cJSON_Parse(hex)) == 0 )
{
PNACL_message("error creating json\n");
return;
}
free_json(json);
hexlen = (int32_t)strlen(hex)+1;
//PNACL_message("HEX.[%s] hexlen.%d n.%d\n",hex,hexlen,datalen);
if ( destplayer < 0 )//|| ((1LL << destplayer) & dp->pmworks) == 0 )
{
destbits = 0;
memset(destpub.bytes,0,sizeof(destpub));
//PNACL_message("T%d broadcasts %d\n",hn->client->H.slot,hexlen);
}
else
{
destpub = sp->playerpubs[pangea_slot(sp,destplayer)];
destbits = acct777_nxt64bits(destpub);
//PNACL_message("T%d sends %d to dest.%d\n",hn->client->H.slot,hexlen,destplayer);
}
pangeanet777_msg(destbits,destpub,hn,blindflag,hex,hexlen);
}
char *_pangea_status(uint64_t my64bits,uint64_t tableid,cJSON *json)
{
int32_t i,j,threadid = juint(json,"threadid"); struct pangea_info *sp; cJSON *item,*array=0,*retjson = 0;
if ( tableid != 0 )
{
if ( (sp= pangea_find(tableid,threadid)) != 0 )
{
if ( (item= pangea_tablestatus(sp)) != 0 )
{
retjson = cJSON_CreateObject();
jaddstr(retjson,"result","success");
jadd(retjson,"table",item);
return(jprint(retjson,1));
}
}
}
else
{
for (i=0; i<sizeof(TABLES)/sizeof(*TABLES); i++)
{
if ( (sp= TABLES[i]) != 0 )
{
for (j=0; j<sp->numaddrs; j++)
if ( sp->addrs[j] == my64bits )
{
if ( (item= pangea_tablestatus(sp)) != 0 )
{
if ( array == 0 )
array = cJSON_CreateArray();
jaddi(array,item);
}
break;
}
}
}
}
retjson = cJSON_CreateObject();
if ( array == 0 )
jaddstr(retjson,"error","no table status");
else
{
jaddstr(retjson,"result","success");
jadd(retjson,"tables",array);
}
jadd64bits(retjson,"nxtaddr",my64bits);
return(jprint(retjson,1));
}
/*int32_t pangea_idle(struct supernet_info *plugin)
{
int32_t i,n,m,pinggap = 1; uint64_t senderbits; uint32_t timestamp; struct pangea_thread *tp; union pangeanet777 *hn;
struct cards777_pubdata *dp; char hex[1024];
while ( 1 )
{
for (i=n=m=0; i<_PANGEA_MAXTHREADS; i++)
{
if ( (tp= THREADS[i]) != 0 )
{
hn = &tp->hn;
//PNACL_message("pangea idle player.%d\n",hn->client->H.slot);
if ( hn->client->H.done == 0 )
{
n++;
if ( pangeanet777_idle(hn) != 0 )
m++;
pangea_poll(&senderbits,&timestamp,hn);
dp = hn->client->H.pubdata;
if ( dp != 0 && hn->client->H.slot == pangea_slotA(dp->table) )
pinggap = 1;
if ( hn->client != 0 && dp != 0 )
{
if ( time(NULL) > hn->client->H.lastping + pinggap )
{
if ( 0 && (dp= hn->client->H.pubdata) != 0 )
{
pangea_sendcmd(hex,hn,"ping",-1,dp->hand.checkprod.bytes,sizeof(uint64_t),dp->hand.cardi,dp->hand.undergun);
hn->client->H.lastping = (uint32_t)time(NULL);
}
}
if ( dp->hand.handmask == ((1 << dp->N) - 1) && dp->hand.finished == 0 )//&& dp->hand.pangearake == 0 )
{
PNACL_message("P%d: all players folded or showed cards at %ld | rakemillis %d\n",hn->client->H.slot,(long)time(NULL),dp->rakemillis);
pangea_finish(hn,dp);
}
if ( hn->client->H.slot == pangea_slotA(dp->table) )
pangea_serverstate(hn,dp,hn->server->H.privdata);
}
}
}
}
if ( n == 0 )
break;
if ( m == 0 )
usleep(3000);
}
//for (i=0; i<_PANGEA_MAXTHREADS; i++)
// if ( THREADS[i] != 0 && Pangea_waiting != 0 )
// pangea_userpoll(&THREADS[i]->hn);
return(0);
}*/
char *_pangea_history(uint64_t my64bits,uint64_t tableid,cJSON *json)
{
struct pangea_info *sp;
if ( (sp= pangea_find64(tableid,my64bits)) != 0 && sp->dp != 0 )
{
if ( jobj(json,"handid") == 0 )
return(pangea_dispsummary(sp,juint(json,"verbose"),sp->dp->summary,sp->dp->summarysize,tableid,sp->dp->numhands-1,sp->dp->N));
else return(pangea_dispsummary(sp,juint(json,"verbose"),sp->dp->summary,sp->dp->summarysize,tableid,juint(json,"handid"),sp->dp->N));
}
return(clonestr("{\"error\":\"cant find tableid\"}"));
}
char *_pangea_buyin(uint64_t my64bits,uint64_t tableid,cJSON *json)
{
struct pangea_info *sp; uint32_t buyin,vout; uint64_t amount = 0; char hex[1024],jsonstr[1024],*txidstr,*destaddr;
if ( (sp= pangea_find64(tableid,my64bits)) != 0 && sp->dp != 0 && sp->tp != 0 && (amount= j64bits(json,"amount")) != 0 )
{
buyin = (uint32_t)(amount / sp->dp->bigblind);
PNACL_message("buyin.%u amount %.8f -> %.8f\n",buyin,dstr(amount),dstr(buyin * sp->bigblind));
if ( buyin >= sp->dp->minbuyin && buyin <= sp->dp->maxbuyin )
{
sp->balances[pangea_ind(sp,sp->myslot)] = amount;
if ( (txidstr= jstr(json,"txidstr")) != 0 && (destaddr= jstr(json,"msigaddr")) != 0 && strcmp(destaddr,sp->multisigaddr) == 0 )
{
vout = juint(json,"vout");
sprintf(jsonstr,"{\"txid\":\"%s\",\"vout\":%u,\"msig\":\"%s\",\"amount\":%.8f}",txidstr,vout,sp->multisigaddr,dstr(amount));
pangea_sendcmd(hex,&sp->tp->hn,"addfunds",-1,(void *)jsonstr,(int32_t)strlen(jsonstr)+1,pangea_ind(sp,sp->myslot),-1);
} else pangea_sendcmd(hex,&sp->tp->hn,"addfunds",-1,(void *)&amount,sizeof(amount),pangea_ind(sp,sp->myslot),-1);
//pangea_sendcmd(hex,&sp->tp->hn,"addfunds",0,(void *)&amount,sizeof(amount),pangea_ind(sp,sp->myslot),-1);
return(clonestr("{\"result\":\"buyin sent\"}"));
}
else
{
PNACL_message("buyin.%d vs (%d %d)\n",buyin,sp->dp->minbuyin,sp->dp->maxbuyin);
return(clonestr("{\"error\":\"buyin too small or too big\"}"));
}
}
return(clonestr("{\"error\":\"cant buyin unless you are part of the table\"}"));
}
char *_pangea_mode(uint64_t my64bits,uint64_t tableid,cJSON *json)
{
struct pangea_info *sp; char *chatstr,hex[8192]; int32_t i; uint64_t pm;
if ( jobj(json,"automuck") != 0 )
{
if ( tableid == 0 )
Showmode = juint(json,"automuck");
else if ( (sp= pangea_find64(tableid,my64bits)) != 0 && sp->priv != 0 )
sp->priv->automuck = juint(json,"automuck");
else return(clonestr("{\"error\":\"automuck not tableid or sp->priv\"}"));
return(clonestr("{\"result\":\"set automuck mode\"}"));
}
else if ( jobj(json,"autofold") != 0 )
{
if ( tableid == 0 )
Autofold = juint(json,"autofold");
else if ( (sp= pangea_find64(tableid,my64bits)) != 0 && sp->priv != 0 )
sp->priv->autofold = juint(json,"autofold");
else return(clonestr("{\"error\":\"autofold not tableid or sp->priv\"}"));
return(clonestr("{\"result\":\"set autofold mode\"}"));
}
else if ( (sp= pangea_find64(tableid,my64bits)) != 0 && (chatstr= jstr(json,"chat")) != 0 && strlen(chatstr) < 256 )
{
if ( 0 && (pm= j64bits(json,"pm")) != 0 )
{
for (i=0; i<sp->numaddrs; i++)
if ( sp->addrs[i] == pm )
break;
if ( i == sp->numaddrs )
return(clonestr("{\"error\":\"specified pm destination not at table\"}"));
} else i = -1;
pangea_sendcmd(hex,&sp->tp->hn,"chat",i,(void *)chatstr,(int32_t)strlen(chatstr)+1,pangea_ind(sp,sp->myslot),-1);
return(clonestr("{\"result\":\"chat message sent\"}"));
}
return(clonestr("{\"error\":\"unknown pangea mode\"}"));
}
void _pangea_chat(uint64_t senderbits,void *buf,int32_t len,int32_t senderind)
{
PNACL_message(">>>>>>>>>>> CHAT FROM.%d %llu: (%s)\n",senderind,(long long)senderbits,(char *)buf);
}
/*char *pangea_univ(uint8_t *mypriv,cJSON *json)
{
char *addrtypes[][3] = { {"BTC","0","80"}, {"LTC","48"}, {"BTCD","60","bc"}, {"DOGE","30"}, {"VRC","70"}, {"OPAL","115"}, {"BITS","25"} };
char *wipstr,*coin,*coinaddr,pubkeystr[67],rsaddr[64],destaddr[64],wifbuf[128]; uint8_t priv[32],pub[33],addrtype; int32_t i;
uint64_t nxt64bits; cJSON *retjson,*item;
PNACL_message("inside rosetta\n");
if ( (coin= jstr(json,"coin")) != 0 )
{
if ( (wipstr= jstr(json,"wif")) != 0 || (wipstr= jstr(json,"wip")) != 0 )
{
PNACL_message("got wip.(%s)\n",wipstr);
btc_wip2priv(priv,wipstr);
}
else if ( (coinaddr= jstr(json,"addr")) != 0 )
{
if ( getprivkey(priv,coin,coinaddr) < 0 )
return(clonestr("{\"error\":\"cant get privkey\"}"));
}
} else memcpy(priv,mypriv,sizeof(priv));
btc_priv2pub(pub,priv);
init_hexbytes_noT(pubkeystr,pub,33);
PNACL_message("pubkey.%s\n",pubkeystr);
retjson = cJSON_CreateObject();
jaddstr(retjson,"btcpubkey",pubkeystr);
for (i=0; i<sizeof(addrtypes)/sizeof(*addrtypes); i++)
{
if ( btc_coinaddr(destaddr,atoi(addrtypes[i][1]),pubkeystr) == 0 )
{
item = cJSON_CreateObject();
jaddstr(item,"addr",destaddr);
if ( addrtypes[i][2] != 0 )
{
decode_hex(&addrtype,1,addrtypes[i][2]);
btc_priv2wip(wifbuf,priv,addrtype);
jaddstr(item,"wif",wifbuf);
}
jadd(retjson,addrtypes[i][0],item);
}
}
nxt64bits = nxt_priv2addr(rsaddr,pubkeystr,priv);
item = cJSON_CreateObject();
jaddstr(item,"addressRS",rsaddr);
jadd64bits(item,"address",nxt64bits);
jaddstr(item,"pubkey",pubkeystr);
jadd(retjson,"NXT",item);
return(jprint(retjson,1));
}
*/
/*
else if ( strcmp(methodstr,"newtable") == 0 )
retstr = pangea_newtable(juint(json,"threadid"),json,plugin->nxt64bits,*(bits256 *)plugin->mypriv,*(bits256 *)plugin->mypub,plugin->transport,plugin->ipaddr,plugin->pangeaport,juint(json,"minbuyin"),juint(json,"maxbuyin"),juint(json,"rakemillis"));
else if ( sender == 0 || sender[0] == 0 )
{
if ( strcmp(methodstr,"start") == 0 )
{
strcpy(retbuf,"{\"result\":\"start issued\"}");
if ( (base= jstr(json,"base")) != 0 )
{
if ( (maxplayers= juint(json,"maxplayers")) < 2 )
maxplayers = 2;
else if ( maxplayers > CARDS777_MAXPLAYERS )
maxplayers = CARDS777_MAXPLAYERS;
if ( jstr(json,"resubmit") == 0 )
sprintf(retbuf,"{\"resubmit\":[{\"method\":\"start\"}, {\"bigblind\":\"%llu\"}, {\"ante\":\"%llu\"}, {\"rakemillis\":\"%u\"}, {\"maxplayers\":%d}, {\"minbuyin\":%d}, {\"maxbuyin\":%d}],\"pluginrequest\":\"SuperNET\",\"plugin\":\"InstantDEX\",\"method\":\"orderbook\",\"base\":\"%s\",\"exchange\":\"pangea\",\"allfields\":1}",(long long)j64bits(json,"bigblind"),(long long)j64bits(json,"ante"),juint(json,"rakemillis"),maxplayers,juint(json,"minbuyin"),juint(json,"maxbuyin"),jstr(json,"base")!=0?jstr(json,"base"):"BTCD");
else if ( pangea_start(plugin,retbuf,base,0,j64bits(json,"bigblind"),j64bits(json,"ante"),juint(json,"rakemillis"),maxplayers,juint(json,"minbuyin"),juint(json,"maxbuyin"),json) < 0 )
;
} else strcpy(retbuf,"{\"error\":\"no base specified\"}");
}
else if ( strcmp(methodstr,"status") == 0 )
retstr = pangea_status(plugin->nxt64bits,j64bits(json,"tableid"),json);
}
int32_t pangea_unzbuf(uint8_t *buf,char *hexstr,int32_t len)
{
int32_t i,j,len2;
for (len2=i=0; i<len; i+=2)
{
if ( hexstr[i] == 'Z' )
{
for (j=0; j<hexstr[i+1]-'A'; j++)
buf[len2++] = 0;
}
else buf[len2++] = _decode_hex(&hexstr[i]);
}
//char *tmp = calloc(1,len*2+1);
//init_hexbytes_noT(tmp,buf,len2);
//PostMessage("zlen %d to len2 %d\n",len,len2);
//free(tmp);
return(len2);
}
int32_t pangea_poll(uint64_t *senderbitsp,uint32_t *timestampp,union hostnet777 *hn)
{
char *jsonstr,*hexstr,*cmdstr; cJSON *json; struct cards777_privdata *priv; struct cards777_pubdata *dp; struct pangea_info *sp;
int32_t len,senderind,maxlen; uint8_t *buf;
*senderbitsp = 0;
dp = hn->client->H.pubdata, sp = dp->table;
priv = hn->client->H.privdata;
if ( hn == 0 || hn->client == 0 || dp == 0 || priv == 0 )
{
if ( Debuglevel > 2 )
PNACL_message("pangea_poll: null hn.%p %p dp.%p priv.%p\n",hn,hn!=0?hn->client:0,dp,priv);
return(-1);
}
maxlen = (int32_t)(sizeof(bits256) * dp->N*dp->N*dp->numcards);
if ( (buf= malloc(maxlen)) == 0 )
{
PNACL_message("pangea_poll: null buf\n");
return(-1);
}
if ( dp != 0 && priv != 0 && (jsonstr= queue_dequeue(&hn->client->H.Q,1)) != 0 )
{
//pangea_neworder(dp,dp->table,0,0);
//PNACL_message("player.%d GOT.(%s)\n",hn->client->H.slot,jsonstr);
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
*senderbitsp = j64bits(json,"sender");
if ( (senderind= juint(json,"myind")) < 0 || senderind >= dp->N )
{
PNACL_message("pangea_poll: illegal senderind.%d cardi.%d turni.%d (%s)\n",senderind,juint(json,"cardi"),juint(json,"turni"),jsonstr);
goto cleanup;
}
*timestampp = juint(json,"timestamp");
hn->client->H.state = juint(json,"state");
len = juint(json,"n");
cmdstr = jstr(json,"cmd");
if ( sp->myind < 0 )
{
// check for reactivation command
goto cleanup;
}
if ( cmdstr != 0 && strcmp(cmdstr,"preflop") == 0 )
{
if ( (hexstr= jstr(json,"data")) != 0 )
len = pangea_unzbuf(buf,hexstr,len);
}
else if ( (hexstr= jstr(json,"data")) != 0 && strlen(hexstr) == (len<<1) )
{
if ( len > maxlen )
{
PNACL_message("len too big for pangea_poll\n");
goto cleanup;
}
decode_hex(buf,len,hexstr);
} else if ( hexstr != 0 )
PNACL_message("len.%d vs hexlen.%ld (%s)\n",len,(long)(strlen(hexstr)>>1),hexstr);
if ( cmdstr != 0 )
{
if ( strcmp(cmdstr,"newhand") == 0 )
pangea_newhand(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"ping") == 0 )
pangea_ping(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"gotdeck") == 0 )
pangea_gotdeck(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"ready") == 0 )
pangea_ready(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"encoded") == 0 )
pangea_encoded(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"final") == 0 )
pangea_final(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"addfunds") == 0 )
pangea_addfunds(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"preflop") == 0 )
pangea_preflop(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"decoded") == 0 )
pangea_decoded(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"card") == 0 )
pangea_card(hn,json,dp,priv,buf,len,juint(json,"cardi"),senderind);
else if ( strcmp(cmdstr,"facedown") == 0 )
pangea_facedown(hn,json,dp,priv,buf,len,juint(json,"cardi"),senderind);
else if ( strcmp(cmdstr,"faceup") == 0 )
pangea_faceup(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"turn") == 0 )
pangea_turn(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"confirmturn") == 0 )
pangea_confirmturn(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"chat") == 0 )
pangea_chat(*senderbitsp,buf,len,senderind);
else if ( strcmp(cmdstr,"action") == 0 )
pangea_action(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"showdown") == 0 )
pangea_showdown(hn,json,dp,priv,buf,len,senderind);
else if ( strcmp(cmdstr,"summary") == 0 )
pangea_gotsummary(hn,json,dp,priv,buf,len,senderind);
}
cleanup:
free_json(json);
}
free_queueitem(jsonstr);
}
free(buf);
return(hn->client->H.state);
}*/
char *Pangea_bypass(uint64_t my64bits,uint8_t myprivkey[32],cJSON *json)
{
char *methodstr,*retstr = 0;
if ( (methodstr= jstr(json,"method")) != 0 )
{
if ( strcmp(methodstr,"turn") == 0 )
retstr = _pangea_input(my64bits,j64bits(json,"tableid"),json);
else if ( strcmp(methodstr,"status") == 0 )
retstr = _pangea_status(my64bits,j64bits(json,"tableid"),json);
else if ( strcmp(methodstr,"mode") == 0 )
retstr = _pangea_mode(my64bits,j64bits(json,"tableid"),json);
//else if ( strcmp(methodstr,"rosetta") == 0 )
// retstr = pangea_univ(myprivkey,json);
else if ( strcmp(methodstr,"buyin") == 0 )
retstr = _pangea_buyin(my64bits,j64bits(json,"tableid"),json);
else if ( strcmp(methodstr,"history") == 0 )
retstr = _pangea_history(my64bits,j64bits(json,"tableid"),json);
}
return(retstr);
}
#include "../includes/iguana_apidefs.h"
INT_AND_ARRAY(pangea,newhand,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,ping,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,gotdeck,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,ready,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,encoded,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,final,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,addedfunds,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,preflop,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,decoded,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,card,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,facedown,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,faceup,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,turn,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,confirmturn,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,chat,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,action,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,showdown,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
INT_AND_ARRAY(pangea,handsummary,senderind,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
//U64_AND_ARRAY(pangea,turn,tableid,args);
U64_AND_ARRAY(pangea,status,tableid,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
U64_AND_ARRAY(pangea,mode,tableid,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
U64_AND_ARRAY(pangea,buyin,tableid,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
U64_AND_ARRAY(pangea,history,tableid,args)
{
cJSON *retjson = cJSON_CreateObject();
return(jprint(retjson,1));
}
#undef IGUANA_ARGS
#include "../includes/iguana_apiundefs.h"

1420
iguana/pangea_fsm.c

File diff suppressed because it is too large

970
iguana/pangea_funds.c

@ -0,0 +1,970 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "pangea777.h"
char *pangea_typestr(uint8_t type)
{
static char err[64];
switch ( type )
{
case 0xff: return("fold");
case CARDS777_START: return("start");
case CARDS777_ANTE: return("ante");
case CARDS777_SMALLBLIND: return("smallblind");
case CARDS777_BIGBLIND: return("bigblind");
case CARDS777_CHECK: return("check");
case CARDS777_CALL: return("call");
case CARDS777_BET: return("bet");
case CARDS777_RAISE: return("raise");
case CARDS777_FULLRAISE: return("fullraise");
case CARDS777_SENTCARDS: return("sentcards");
case CARDS777_ALLIN: return("allin");
case CARDS777_FACEUP: return("faceup");
case CARDS777_WINNINGS: return("won");
case CARDS777_RAKES: return("rakes");
case CARDS777_CHANGES: return("changes");
case CARDS777_SNAPSHOT: return("snapshot");
}
sprintf(err,"unknown type.%d",type);
return(err);
}
cJSON *pangea_handitem(int32_t *cardip,cJSON **pitemp,uint8_t type,uint64_t valA,uint64_t *bits64p,bits256 card,int32_t numplayers)
{
int32_t cardi,n,i,rebuy,busted; char str[128],hexstr[65],cardpubs[(CARDS777_MAXCARDS+1)*64+1]; cJSON *item,*array,*pitem = 0;
item = cJSON_CreateObject();
*cardip = -1;
switch ( type )
{
case CARDS777_START:
jaddnum(item,"handid",valA);
init_hexbytes_noT(cardpubs,(void *)bits64p,(int32_t)((CARDS777_MAXCARDS+1) * sizeof(bits256)));
jaddstr(item,"cardpubs",cardpubs);
break;
case CARDS777_RAKES:
jaddnum(item,"hostrake",dstr(valA));
jaddnum(item,"pangearake",dstr(*bits64p));
break;
case CARDS777_SNAPSHOT:
jaddnum(item,"handid",valA);
array = cJSON_CreateArray();
for (i=0; i<CARDS777_MAXPLAYERS; i++)
{
if ( i < numplayers )
jaddinum(array,dstr(bits64p[i]));
else jaddinum(array,dstr(0));
}
jadd(item,"snapshot",array);
//printf("add snapshot for numplayers.%d\n",numplayers);
break;
case CARDS777_CHANGES:
n = (int32_t)(valA & 0xf);
busted = (int32_t)((valA>>4) & 0xffff);
rebuy = (int32_t)((valA>>20) & 0xffff);
if ( busted != 0 )
jaddnum(item,"busted",busted);
if ( rebuy != 0 )
jaddnum(item,"rebuy",rebuy);
array = cJSON_CreateArray();
for (i=0; i<n; i++)
jaddinum(array,dstr(bits64p[i]));
jadd(item,"balances",array);
break;
case CARDS777_WINNINGS:
if ( (int32_t)valA >= 0 && valA < numplayers )
jaddnum(item,"player",valA);
jaddnum(item,"won",dstr(*bits64p));
if ( pitem == 0 )
pitem = cJSON_CreateObject();
jaddnum(pitem,"won",dstr(*bits64p));
break;
case CARDS777_FACEUP:
*cardip = cardi = (int32_t)(valA >> 8);
if ( cardi >= 0 && cardi < 52 )
jaddnum(item,"cardi",cardi);
else printf("illegal cardi.%d valA.%llu\n",cardi,(long long)valA);
valA &= 0xff;
if ( (int32_t)valA >= 0 && valA < numplayers )
jaddnum(item,"player",valA);
else if ( valA == 0xff )
jaddnum(item,"community",cardi - numplayers*2);
cardstr(str,card.bytes[1]);
jaddnum(item,str,card.bytes[1]);
init_hexbytes_noT(hexstr,card.bytes,sizeof(card));
jaddstr(item,"privkey",hexstr);
break;
default:
if ( (int32_t)valA >= 0 && valA < numplayers )
jaddnum(item,"player",valA);
jaddstr(item,"action",pangea_typestr(type));
if ( pitem == 0 )
pitem = cJSON_CreateObject();
if ( *bits64p != 0 )
{
jaddnum(item,"bet",dstr(*bits64p));
jaddnum(pitem,pangea_typestr(type),dstr(*bits64p));
}
else jaddstr(pitem,"action",pangea_typestr(type));
break;
}
*pitemp = pitem;
return(item);
}
int32_t pangea_parsesummary(uint8_t *typep,uint64_t *valAp,uint64_t *bits64p,bits256 *cardp,uint8_t *summary,int32_t len)
{
int32_t handid; uint16_t cardi_player; uint32_t changes=0; uint8_t player;
*bits64p = 0;
memset(cardp,0,sizeof(*cardp));
len += SuperNET_copybits(1,&summary[len],(void *)typep,sizeof(*typep));
if ( *typep == 0 )
{
printf("len.%d type.%d [%d]\n",len,*typep,summary[len-1]);
return(-1);
}
if ( *typep == CARDS777_START || *typep == CARDS777_SNAPSHOT )
len += SuperNET_copybits(1,&summary[len],(void *)&handid,sizeof(handid)), *valAp = handid;
else if ( *typep == CARDS777_CHANGES )
len += SuperNET_copybits(1,&summary[len],(void *)&changes,sizeof(changes)), *valAp = changes;
else if ( *typep == CARDS777_RAKES )
len += SuperNET_copybits(1,&summary[len],(void *)valAp,sizeof(*valAp));
else if ( *typep == CARDS777_FACEUP )
len += SuperNET_copybits(1,&summary[len],(void *)&cardi_player,sizeof(cardi_player)), *valAp = cardi_player;
else len += SuperNET_copybits(1,&summary[len],(void *)&player,sizeof(player)), *valAp = player;
if ( *typep == CARDS777_FACEUP )
len += SuperNET_copybits(1,&summary[len],cardp->bytes,sizeof(*cardp));
else if ( *typep == CARDS777_START )
len += SuperNET_copybits(1,&summary[len],(void *)bits64p,sizeof(bits256)*(CARDS777_MAXCARDS+1));
else if ( *typep == CARDS777_SNAPSHOT )
len += SuperNET_copybits(1,&summary[len],(void *)bits64p,sizeof(*bits64p) * CARDS777_MAXPLAYERS);
else if ( *typep == CARDS777_CHANGES )
len += SuperNET_copybits(1,&summary[len],(void *)bits64p,sizeof(*bits64p) * (changes & 0xf));
else len += SuperNET_copybits(1,&summary[len],(void *)bits64p,sizeof(*bits64p));
return(len);
}
void pangea_summary(union pangeanet777 *hn,struct cards777_pubdata *dp,uint8_t type,void *arg0,int32_t size0,void *arg1,int32_t size1)
{
uint64_t valA,bits64[CARDS777_MAXPLAYERS + (CARDS777_MAXCARDS+1)*4]; bits256 card; uint8_t checktype; char *str;
cJSON *item,*pitem; int32_t len,cardi,startlen = dp->summarysize;
if ( type == 0 )
{
printf("type.0\n"); getchar();
}
//printf("summarysize.%d type.%d [%02x %02x]\n",dp->summarysize,type,*(uint8_t *)arg0,*(uint8_t *)arg1);
dp->summarysize += SuperNET_copybits(0,&dp->summary[dp->summarysize],(void *)&type,sizeof(type));
//printf("-> %d\n",dp->summary[dp->summarysize-1]);
dp->summarysize += SuperNET_copybits(0,&dp->summary[dp->summarysize],arg0,size0);
dp->summarysize += SuperNET_copybits(0,&dp->summary[dp->summarysize],arg1,size1);
//printf("startlen.%d summarysize.%d\n",startlen,dp->summarysize);
len = pangea_parsesummary(&checktype,&valA,bits64,&card,dp->summary,startlen);
if ( len != dp->summarysize || checktype != type || memcmp(&valA,arg0,size0) != 0 )
printf("pangea_summary parse error [%d] (%d vs %d) || (%d vs %d).%d || cmp.%d size0.%d size1.%d\n",startlen,len,dp->summarysize,checktype,type,dp->summary[startlen],memcmp(&valA,arg0,size0),size0,size1);
if ( card.txid != 0 && memcmp(card.bytes,arg1,sizeof(card)) != 0 )
printf("pangea_summary: parse error card mismatch %llx != %llx\n",(long long)card.txid,*(long long *)arg1);
else if ( card.txid == 0 && memcmp(arg1,bits64,size1) != 0 )
printf("pangea_summary: parse error bits64 %llx != %llx\n",(long long)bits64[0],*(long long *)arg0);
if ( 1 && hn->client->H.slot == pangea_slotA(dp->table) )
{
if ( (item= pangea_handitem(&cardi,&pitem,type,valA,bits64,card,dp->N)) != 0 )
{
str = jprint(item,1);
printf("ITEM.(%s)\n",str);
free(str);
}
if ( pitem != 0 )
{
str = jprint(pitem,1);
printf("PITEM.(%s)\n",str);
free(str);
}
}
if ( Debuglevel > 2 )//|| hn->client->H.slot == pangea_slotA(dp->table) )
printf("pangea_summary.%d %d | summarysize.%d crc.%u\n",type,*(uint8_t *)arg0,dp->summarysize,calc_crc32(0,dp->summary,dp->summarysize));
}
char *pangea_dispsummary(struct pangea_info *sp,int32_t verbose,uint8_t *summary,int32_t summarysize,uint64_t tableid,int32_t handid,int32_t numplayers)
{
int32_t i,cardi,n = 0,len = 0; uint8_t type; uint64_t valA,bits64[CARDS777_MAXPLAYERS + (CARDS777_MAXCARDS+1)*4]; bits256 card;
cJSON *item,*json,*all,*cardis[52],*players[CARDS777_MAXPLAYERS],*pitem,*array = cJSON_CreateArray();
all = cJSON_CreateArray();
memset(cardis,0,sizeof(cardis));
memset(players,0,sizeof(players));
for (i=0; i<numplayers; i++)
players[i] = cJSON_CreateArray();
while ( len < summarysize )
{
memset(bits64,0,sizeof(bits64));
len = pangea_parsesummary(&type,&valA,bits64,&card,summary,len);
if ( (item= pangea_handitem(&cardi,&pitem,type,valA,bits64,card,numplayers)) != 0 )
{
if ( cardi >= 0 && cardi < 52 )
{
//printf("cardis[%d] <- %p\n",cardi,item);
cardis[cardi] = item;
}
else jaddi(array,item);
item = 0;
}
if ( pitem != 0 )
{
jaddnum(pitem,"n",n), n++;
if ( (int32_t)valA >= 0 && valA < numplayers )
jaddi(players[valA],pitem);
else free_json(pitem), printf("illegal player.%llu\n",(long long)valA);
pitem = 0;
}
}
for (i=0; i<numplayers; i++)
jaddi(all,players[i]);
if ( verbose == 0 )
{
for (i=0; i<52; i++)
if ( cardis[i] != 0 )
free_json(cardis[i]);
free_json(array);
return(jprint(all,1));
}
else
{
json = cJSON_CreateObject();
if ( tableid != 0 )
jadd64bits(json,"tableid",tableid);
if ( 0 && sp != 0 )
{
//array = cJSON_CreateArray();
//for (i=0; i<sp->numactive; i++)
// jaddi64bits(array,sp->active[i]);
//jadd(json,"active",array);
for (i=0; i<sp->numactive; i++)
printf("%llu ",(long long)sp->active[i]);
printf("sp->numactive[%d]\n",sp->numactive);
}
jaddnum(json,"size",summarysize);
jaddnum(json,"handid",handid);
//jaddnum(json,"crc",_crc32(0,summary,summarysize));
jadd(json,"hand",array);
array = cJSON_CreateArray();
for (i=0; i<52; i++)
if ( cardis[i] != 0 )
jaddi(array,cardis[i]);
jadd(json,"cards",array);
//jadd(json,"players",all);
return(jprint(json,1));
}
}
void pangea_fold(union pangeanet777 *hn,struct cards777_pubdata *dp,int32_t player)
{
uint8_t tmp;
//printf("player.%d folded\n",player); //getchar();
dp->hand.handmask |= (1 << player);
dp->hand.betstatus[player] = CARDS777_FOLD;
dp->hand.actions[player] = CARDS777_FOLD;
tmp = player;
pangea_summary(hn,dp,CARDS777_FOLD,&tmp,sizeof(tmp),(void *)&dp->hand.bets[player],sizeof(dp->hand.bets[player]));
}
uint64_t pangea_totalbet(struct cards777_pubdata *dp)
{
int32_t j; uint64_t total;
for (total=j=0; j<dp->N; j++)
total += dp->hand.bets[j];
return(total);
}
int32_t pangea_actives(int32_t *activej,struct cards777_pubdata *dp)
{
int32_t i,n;
*activej = -1;
for (i=n=0; i<dp->N; i++)
{
if ( dp->hand.betstatus[i] != CARDS777_FOLD )
{
if ( *activej < 0 )
*activej = i;
n++;
}
}
return(n);
}
struct pangea_info *pangea_usertables(int32_t *nump,uint64_t my64bits,uint64_t tableid)
{
int32_t i,j,num = 0; struct pangea_info *sp,*retsp = 0;
*nump = 0;
for (i=0; i<sizeof(TABLES)/sizeof(*TABLES); i++)
{
if ( (sp= TABLES[i]) != 0 )
{
for (j=0; j<sp->numaddrs; j++)
if ( sp->addrs[j] == my64bits && (tableid == 0 || sp->tableid == tableid) )
{
if ( num++ == 0 )
{
retsp = sp;
break;
}
}
}
}
*nump = num;
return(retsp);
}
struct pangea_info *pangea_threadtables(int32_t *nump,int32_t threadid,uint64_t tableid)
{
int32_t i,j,num = 0; struct pangea_info *sp,*retsp = 0;
*nump = 0;
for (i=0; i<sizeof(TABLES)/sizeof(*TABLES); i++)
{
if ( (sp= TABLES[i]) != 0 )
{
for (j=0; j<sp->numaddrs; j++)
if ( sp->tp != 0 && sp->tp->threadid == threadid && (tableid == 0 || sp->tableid == tableid) )
{
if ( num++ == 0 )
{
retsp = sp;
break;
}
}
}
}
*nump = num;
return(retsp);
}
int32_t pangea_bet(union pangeanet777 *hn,struct cards777_pubdata *dp,int32_t player,int64_t bet,int32_t action)
{
uint64_t sum; uint8_t tmp; struct pangea_info *sp = dp->table;
player %= dp->N;
if ( Debuglevel > 2 )
printf("player.%d PANGEA_BET[%d] <- %.8f\n",hn->client->H.slot,player,dstr(bet));
if ( dp->hand.betstatus[player] == CARDS777_ALLIN )
return(CARDS777_ALLIN);
else if ( dp->hand.betstatus[player] == CARDS777_FOLD )
return(CARDS777_FOLD);
if ( bet > 0 && bet >= sp->balances[pangea_slot(sp,player)] )
{
bet = sp->balances[pangea_slot(sp,player)];
dp->hand.betstatus[player] = action = CARDS777_ALLIN;
}
else
{
if ( bet > dp->hand.betsize && bet > dp->hand.lastraise && bet < (dp->hand.lastraise<<1) )
{
printf("pangea_bet %.8f not double %.8f, clip to lastraise\n",dstr(bet),dstr(dp->hand.lastraise));
bet = dp->hand.lastraise;
action = CARDS777_RAISE;
}
}
sum = dp->hand.bets[player];
if ( sum+bet < dp->hand.betsize && action != CARDS777_ALLIN )
{
pangea_fold(hn,dp,player);
action = CARDS777_FOLD;
tmp = player;
if ( Debuglevel > 2 )
printf("player.%d betsize %.8f < hand.betsize %.8f FOLD\n",player,dstr(bet),dstr(dp->hand.betsize));
return(action);
}
else if ( bet >= 2*dp->hand.lastraise )
{
dp->hand.lastraise = bet;
dp->hand.numactions = 0;
if ( action == CARDS777_CHECK )
{
action = CARDS777_FULLRAISE; // allows all players to check/bet again
if ( Debuglevel > 2 )
printf("FULLRAISE by player.%d\n",player);
}
}
sum += bet;
if ( sum > dp->hand.betsize )
{
dp->hand.numactions = 0;
dp->hand.betsize = sum, dp->hand.lastbettor = player;
if ( sum > dp->hand.lastraise && action == CARDS777_ALLIN )
dp->hand.lastraise = sum;
else if ( action == CARDS777_CHECK )
action = CARDS777_BET;
}
if ( bet > 0 && action == CARDS777_CHECK )
action = CARDS777_CALL;
tmp = player;
pangea_summary(hn,dp,action,&tmp,sizeof(tmp),(void *)&bet,sizeof(bet));
sp->balances[pangea_slot(sp,player)] -= bet, dp->hand.bets[pangea_slot(sp,player)] += bet;
if ( Debuglevel > 2 )
printf("player.%d: player.%d BET %f -> balances %f bets %f\n",hn->client->H.slot,player,dstr(bet),dstr(sp->balances[pangea_slot(sp,player)]),dstr(dp->hand.bets[player]));
return(action);
}
void pangea_antes(union pangeanet777 *hn,struct cards777_pubdata *dp)
{
int32_t i,j,n,actives[CARDS777_MAXPLAYERS]; uint64_t threshold; int32_t handid; struct pangea_info *sp = dp->table;
for (i=0; i<sp->numaddrs; i++)
dp->snapshot[i] = sp->balances[i];
handid = dp->numhands - 1;
pangea_summary(hn,dp,CARDS777_SNAPSHOT,(void *)&handid,sizeof(handid),(void *)dp->snapshot,sizeof(uint64_t)*CARDS777_MAXPLAYERS);
for (i=0; i<dp->N; i++)
if ( sp->balances[pangea_slot(sp,i)] <= 0 )
pangea_fold(hn,dp,i);
if ( dp->ante != 0 )
{
for (i=0; i<dp->N; i++)
{
if ( i != dp->button && i != (dp->button+1) % dp->N )
{
if ( sp->balances[pangea_slot(sp,i)] < dp->ante )
pangea_fold(hn,dp,i);
else pangea_bet(hn,dp,i,dp->ante,CARDS777_ANTE);
}
}
}
memset(actives,0,sizeof(actives));
for (i=n=0; i<dp->N; i++)
{
j = (1 + dp->button + i) % dp->N;
if ( n == 0 )
threshold = (dp->bigblind >> 1) - 1;
else if ( n == 1 )
threshold = dp->bigblind - 1;
else threshold = 0;
if ( sp->balances[pangea_slot(sp,j)] > threshold )
{
//printf("active[%d] <- %d\n",n,j);
actives[n++] = j;
}
else pangea_fold(hn,dp,j);
}
if ( n < 2 )
{
printf("pangea_antes not enough players n.%d\n",n);
}
else
{
pangea_bet(hn,dp,actives[0],(dp->bigblind>>1),CARDS777_SMALLBLIND);
dp->button = (actives[0] + dp->N - 1) % dp->N;
pangea_bet(hn,dp,actives[1],dp->bigblind,CARDS777_BIGBLIND);
}
/*for (i=0; i<dp->N; i++)
{
j = (1 + dp->button + i) % dp->N;
if ( dp->balances[j] < (dp->bigblind >> 1) )
pangea_fold(hn,dp,j);
else
{
smallblindi = j;
pangea_bet(hn,dp,smallblindi,(dp->bigblind>>1),CARDS777_SMALLBLIND);
break;
}
}
for (i=0; i<dp->N; i++)
{
j = (1 + smallblindi + i) % dp->N;
if ( dp->balances[j] < dp->bigblind )
pangea_fold(hn,dp,j);
else
{
pangea_bet(hn,dp,j,dp->bigblind,CARDS777_BIGBLIND);
break;
}
}*/
if ( 0 )
{
for (i=0; i<dp->N; i++)
printf("%.8f ",dstr(dp->hand.bets[i]));
printf("antes\n");
}
}
void pangea_checkantes(union pangeanet777 *hn,struct cards777_pubdata *dp)
{
int32_t i;
for (i=0; i<dp->N; i++)
{
//printf("%.8f ",dstr(dp->balances[i]));
if ( dp->hand.bets[i] != 0 )
break;
}
if ( i == dp->N && dp->hand.checkprod.txid != 0 )
{
for (i=0; i<dp->N; i++)
if ( dp->hand.bets[i] != 0 )
break;
if ( i == dp->N )
{
//printf("i.%d vs N.%d call antes\n",i,dp->N);
pangea_antes(hn,dp);
} else printf("bets i.%d\n",i);
}
}
/*int32_t pangea_cashout(union pangeanet777 *hn,cJSON *json,struct cards777_pubdata *dp,struct cards777_privdata *priv,uint8_t *data,int32_t datalen,int32_t senderind)
{
return(0);
}*/
int32_t _pangea_addfunds(union pangeanet777 *hn,cJSON *json,struct cards777_pubdata *dp,struct cards777_privdata *priv,uint8_t *data,int32_t datalen,int32_t senderind)
{
char *txidstr,*destaddr; uint32_t vout; int32_t slot; uint64_t amount = 0; struct pangea_info *sp = dp->table;
slot = pangea_slot(sp,senderind);
if ( datalen == sizeof(amount) )
memcpy(&amount,data,sizeof(amount));
else
{
if ( (json= cJSON_Parse((void *)data)) != 0 )
{
amount = j64bits(json,"amount");
txidstr = jstr(json,"txidstr");
destaddr = jstr(json,"msigaddr");
vout = juint(json,"vout");
if ( txidstr != 0 && destaddr != 0 && amount > 0 && strcmp(destaddr,sp->multisigaddr) == 0 )
{
// of course need to verify on blockchain
strcpy(sp->buyintxids[slot],txidstr);
sp->buyinvouts[slot] = vout;
sp->buyinamounts[slot] = amount;
}
free_json(json);
}
}
if ( sp->balances[slot] == 0 )
sp->balances[slot] = amount;
pangea_checkantes(hn,dp);
printf("slot.%d: addfunds.%d <- %.8f total %.8f\n",hn->client->H.slot,senderind,dstr(amount),dstr(sp->balances[senderind]));
return(0);
}
uint64_t pangea_winnings(int32_t player,uint64_t *pangearakep,uint64_t *hostrakep,uint64_t total,int32_t numwinners,int32_t rakemillis,uint64_t maxrake)
{
uint64_t split,pangearake,rake;
if ( numwinners > 0 )
{
split = (total * (1000 - rakemillis)) / (1000 * numwinners);
pangearake = (total - split*numwinners);
if ( pangearake > maxrake )
{
pangearake = maxrake;
split = (total - pangearake) / numwinners;
pangearake = (total - split*numwinners);
}
}
else
{
split = 0;
pangearake = total;
}
if ( rakemillis > PANGEA_MINRAKE_MILLIS )
{
rake = (pangearake * (rakemillis - PANGEA_MINRAKE_MILLIS)) / rakemillis;
pangearake -= rake;
}
else rake = 0;
*hostrakep = rake;
*pangearakep = pangearake;
printf("\nP%d: rakemillis.%d total %.8f split %.8f rake %.8f pangearake %.8f\n",player,rakemillis,dstr(total),dstr(split),dstr(rake),dstr(pangearake));
return(split);
}
int32_t pangea_sidepots(int32_t dispflag,uint64_t sidepots[CARDS777_MAXPLAYERS][CARDS777_MAXPLAYERS],struct cards777_pubdata *dp,int64_t *bets)
{
int32_t i,j,nonz,n = 0; uint64_t bet,minbet = 0;
memset(sidepots,0,sizeof(uint64_t)*CARDS777_MAXPLAYERS*CARDS777_MAXPLAYERS);
for (j=0; j<dp->N; j++)
sidepots[0][j] = bets[j];
nonz = 1;
while ( nonz > 0 )
{
for (minbet=j=0; j<dp->N; j++)
{
if ( (bet= sidepots[n][j]) != 0 )
{
if ( dp->hand.betstatus[j] != CARDS777_FOLD )
{
if ( minbet == 0 || bet < minbet )
minbet = bet;
}
}
}
for (j=nonz=0; j<dp->N; j++)
{
if ( sidepots[n][j] > minbet && dp->hand.betstatus[j] != CARDS777_FOLD )
nonz++;
}
if ( nonz > 0 )
{
for (j=0; j<dp->N; j++)
{
if ( sidepots[n][j] > minbet )
{
sidepots[n+1][j] = (sidepots[n][j] - minbet);
sidepots[n][j] = minbet;
}
}
}
if ( ++n >= dp->N )
break;
}
if ( dispflag != 0 )
{
for (i=0; i<n; i++)
{
for (j=0; j<dp->N; j++)
printf("%.8f ",dstr(sidepots[i][j]));
printf("sidepot.%d of %d\n",i,n);
}
}
return(n);
}
int64_t pangea_splitpot(int64_t *won,uint64_t *pangearakep,uint64_t sidepot[CARDS777_MAXPLAYERS],union pangeanet777 *hn,int32_t rakemillis)
{
int32_t winners[CARDS777_MAXPLAYERS],j,n,numwinners = 0; uint32_t bestrank,rank; uint8_t tmp; struct pangea_info *sp;
uint64_t total = 0,bet,split,maxrake,rake=0,pangearake=0; char handstr[128],besthandstr[128]; struct cards777_pubdata *dp;
dp = hn->client->H.pubdata, sp = dp->table;
bestrank = 0;
besthandstr[0] = 0;
for (j=n=0; j<dp->N; j++)
{
if ( (bet= sidepot[j]) != 0 )
{
total += bet;
if ( dp->hand.betstatus[j] != CARDS777_FOLD )
{
if ( dp->hand.handranks[j] > bestrank )
{
bestrank = dp->hand.handranks[j];
set_handstr(besthandstr,dp->hand.hands[j],0);
//printf("set besthandstr.(%s)\n",besthandstr);
}
}
}
}
for (j=0; j<dp->N; j++)
{
if ( dp->hand.betstatus[j] != CARDS777_FOLD && sidepot[j] > 0 )
{
if ( dp->hand.handranks[j] == bestrank )
winners[numwinners++] = j;
rank = set_handstr(handstr,dp->hand.hands[j],0);
if ( handstr[strlen(handstr)-1] == ' ' )
handstr[strlen(handstr)-1] = 0;
//if ( hn->server->H.slot == 0 )
printf("(p%d %14s)",j,handstr[0]!=' '?handstr:handstr+1);
//printf("(%2d %2d).%d ",dp->hands[j][5],dp->hands[j][6],(int32_t)dp->balances[j]);
}
}
if ( numwinners == 0 )
printf("pangea_splitpot error: numwinners.0\n");
else
{
uint64_t maxrakes[CARDS777_MAXPLAYERS+1] = { 0, 0, 1, 2, 2, 3, 3, 3, 3, 3 }; // 2players 1BB, 3-4players, 2BB, 5+players 3BB
for (j=n=0; j<dp->N; j++)
if ( dp->hand.bets[j] > 0 )
n++;
if ( (maxrake= maxrakes[n] * dp->bigblind) > dp->maxrake )
{
maxrake = dp->maxrake;
if ( strcmp(dp->coinstr,"BTC") == 0 && maxrake < PANGEA_BTCMAXRAKE )
maxrake = PANGEA_BTCMAXRAKE;
else if ( maxrake < PANGEA_MAXRAKE )
maxrake = PANGEA_MAXRAKE;
}
split = pangea_winnings(pangea_ind(dp->table,hn->client->H.slot),&pangearake,&rake,total,numwinners,rakemillis,maxrake);
(*pangearakep) += pangearake;
for (j=0; j<numwinners; j++)
{
tmp = winners[j];
pangea_summary(hn,dp,CARDS777_WINNINGS,&tmp,sizeof(tmp),(void *)&split,sizeof(split));
sp->balances[pangea_slot(sp,winners[j])] += split;
won[winners[j]] += split;
}
if ( split*numwinners + rake + pangearake != total )
printf("pangea_split total error %.8f != split %.8f numwinners %d rake %.8f pangearake %.8f\n",dstr(total),dstr(split),numwinners,dstr(rake),dstr(pangearake));
//if ( hn->server->H.slot == 0 )
{
printf(" total %.8f split %.8f rake %.8f Prake %.8f hand.(%s) N%d winners ",dstr(total),dstr(split),dstr(rake),dstr(pangearake),besthandstr,dp->numhands);
for (j=0; j<numwinners; j++)
printf("%d ",pangea_slot(sp,winners[j]));
printf("\n");
}
}
return(rake);
}
uint64_t pangea_bot(union pangeanet777 *hn,struct cards777_pubdata *dp,int32_t turni,int32_t cardi,uint64_t betsize)
{
int32_t r,action=CARDS777_CHECK,n,activej; char hex[1024]; uint64_t threshold,total,sum,amount = 0; struct pangea_info *sp = dp->table;
sum = dp->hand.bets[pangea_ind(dp->table,hn->client->H.slot)];
action = 0;
n = pangea_actives(&activej,dp);
if ( (r = (rand() % 100)) < 1 )
amount = sp->balances[hn->client->H.slot], action = CARDS777_ALLIN;
else
{
if ( betsize == sum )
{
if ( r < 100/n )
{
amount = dp->hand.lastraise;
action = 1;
if ( (rand() % 100) < 10 )
amount <<= 1;
}
}
else if ( betsize > sum )
{
amount = (betsize - sum);
total = pangea_totalbet(dp);
threshold = (300 * amount)/(1 + total);
n++;
if ( r/n > threshold )
{
action = 1;
if ( r/n > 3*threshold && amount < dp->hand.lastraise*2 )
amount = dp->hand.lastraise * 2, action = 2;
//else if ( r/n > 10*threshold )
// amount = dp->balances[pangea_ind(dp->table,hn->client->H.slot)], action = CARDS777_ALLIN;
}
else if ( amount < sum/10 || amount <= SATOSHIDEN )
action = CARDS777_CALL;
else
{
//printf("amount %.8f, sum %.8f, betsize %.8f\n",dstr(amount),dstr(sum),dstr(betsize));
action = CARDS777_FOLD, amount = 0;
}
}
else printf("pangea_turn error betsize %.8f vs sum %.8f | slot.%d ind.%d\n",dstr(betsize),dstr(sum),hn->client->H.slot,pangea_ind(dp->table,hn->client->H.slot));
if ( amount > sp->balances[hn->client->H.slot] )
amount = sp->balances[hn->client->H.slot], action = CARDS777_ALLIN;
}
pangea_sendcmd(hex,hn,"action",-1,(void *)&amount,sizeof(amount),cardi,action);
printf("playerbot.%d got pangea_turn.%d for player.%d action.%d bet %.8f\n",hn->client->H.slot,cardi,turni,action,dstr(amount));
return(amount);
}
cJSON *pangea_handjson(struct cards777_handinfo *hand,uint8_t *holecards,int32_t isbot)
{
int32_t i,card; char cardAstr[8],cardBstr[8],pairstr[18],cstr[128]; cJSON *array,*json = cJSON_CreateObject();
array = cJSON_CreateArray();
cstr[0] = 0;
for (i=0; i<5; i++)
{
if ( (card= hand->community[i]) != 0xff )
{
jaddinum(array,card);
cardstr(&cstr[strlen(cstr)],card);
strcat(cstr," ");
}
}
jaddstr(json,"community",cstr);
jadd(json,"cards",array);
if ( (card= holecards[0]) != 0xff )
{
jaddnum(json,"cardA",card);
cardstr(cardAstr,holecards[0]);
} else cardAstr[0] = 0;
if ( (card= holecards[1]) != 0xff )
{
jaddnum(json,"cardB",card);
cardstr(cardBstr,holecards[1]);
} else cardBstr[0] = 0;
sprintf(pairstr,"%s %s",cardAstr,cardBstr);
jaddstr(json,"holecards",pairstr);
jaddnum(json,"betsize",dstr(hand->betsize));
jaddnum(json,"lastraise",dstr(hand->lastraise));
jaddnum(json,"lastbettor",hand->lastbettor);
jaddnum(json,"numactions",hand->numactions);
jaddnum(json,"undergun",hand->undergun);
jaddnum(json,"isbot",isbot);
jaddnum(json,"cardi",hand->cardi);
return(json);
}
char *pangea_statusstr(int32_t status)
{
if ( status == CARDS777_FOLD )
return("folded");
else if ( status == CARDS777_ALLIN )
return("ALLin");
else return("active");
}
int32_t pangea_countdown(struct cards777_pubdata *dp,int32_t player)
{
if ( dp->hand.undergun == player && dp->hand.userinput_starttime != 0 )
return((int32_t)(dp->hand.userinput_starttime + PANGEA_USERTIMEOUT - time(NULL)));
else return(-1);
}
cJSON *pangea_tablestatus(struct pangea_info *sp)
{
uint64_t sidepots[CARDS777_MAXPLAYERS][CARDS777_MAXPLAYERS],totals[CARDS777_MAXPLAYERS],sum; char *handhist;
int32_t i,n,j,countdown,iter; int64_t total; struct cards777_pubdata *dp; cJSON *bets,*item,*array,*json = cJSON_CreateObject();
jadd64bits(json,"tableid",sp->tableid);
jadd64bits(json,"myslot",sp->myslot);
jadd64bits(json,"myind",pangea_ind(sp,sp->myslot));
dp = sp->dp;
jaddstr(json,"tablemsig",sp->multisigaddr);
jaddnum(json,"minbuyin",dp->minbuyin);
jaddnum(json,"maxbuyin",dp->maxbuyin);
jaddnum(json,"button",dp->button);
jaddnum(json,"M",dp->M);
jaddnum(json,"N",dp->N);
jaddnum(json,"numcards",dp->numcards);
jaddnum(json,"numhands",dp->numhands);
jaddnum(json,"rake",(double)dp->rakemillis/10.);
jaddnum(json,"maxrake",dstr(dp->maxrake));
jaddnum(json,"hostrake",dstr(dp->hostrake));
jaddnum(json,"pangearake",dstr(dp->pangearake));
jaddnum(json,"bigblind",dstr(dp->bigblind));
jaddnum(json,"ante",dstr(dp->ante));
array = cJSON_CreateArray();
for (i=0; i<dp->N; i++)
jaddi64bits(array,sp->active[i]);
jadd(json,"addrs",array);
array = cJSON_CreateArray();
for (i=0; i<dp->N; i++)
jaddinum(array,dp->hand.turnis[i]);
jadd(json,"turns",array);
array = cJSON_CreateArray();
for (i=0; i<sp->numaddrs; i++)
jaddinum(array,dstr(sp->balances[i]));
jadd(json,"balances",array);
array = cJSON_CreateArray();
for (i=0; i<dp->N; i++)
jaddinum(array,dstr(dp->hand.snapshot[i]));
jadd(json,"snapshot",array);
array = cJSON_CreateArray();
for (i=0; i<dp->N; i++)
jaddistr(array,pangea_statusstr(dp->hand.betstatus[i]));
jadd(json,"status",array);
bets = cJSON_CreateArray();
for (total=i=0; i<dp->N; i++)
{
total += dp->hand.bets[i];
jaddinum(bets,dstr(dp->hand.bets[i]));
}
jadd(json,"bets",bets);
jaddnum(json,"totalbets",dstr(total));
for (iter=0; iter<2; iter++)
if ( (n= pangea_sidepots(0,sidepots,dp,iter == 0 ? dp->hand.snapshot : dp->hand.bets)) > 0 && n < dp->N )
{
array = cJSON_CreateArray();
for (i=0; i<n; i++)
{
item = cJSON_CreateArray();
for (sum=j=0; j<dp->N; j++)
jaddinum(item,dstr(sidepots[i][j])), sum += sidepots[i][j];
totals[i] = sum;
jaddi(array,item);
}
jadd(json,iter == 0 ? "pots" : "RTpots",array);
item = cJSON_CreateArray();
for (sum=i=0; i<n; i++)
jaddinum(item,dstr(totals[i])), sum += totals[i];
jadd(json,iter == 0 ? "potTotals" : "RTpotTotals",item);
jaddnum(json,iter == 0 ? "sum" : "RTsum",dstr(sum));
}
if ( sp->priv != 0 )
{
jadd64bits(json,"automuck",sp->priv->automuck);
jadd64bits(json,"autofold",sp->priv->autofold);
jadd(json,"hand",pangea_handjson(&dp->hand,sp->priv->hole,sp->isbot[sp->myslot]));
}
if ( (handhist= pangea_dispsummary(sp,0,dp->summary,dp->summarysize,sp->tableid,dp->numhands-1,dp->N)) != 0 )
{
if ( (item= cJSON_Parse(handhist)) != 0 )
jadd(json,"actions",item);
free(handhist);
}
if ( (countdown= pangea_countdown(dp,pangea_ind(sp,sp->myslot))) >= 0 )
jaddnum(json,"timeleft",countdown);
if ( dp->hand.finished != 0 )
{
item = cJSON_CreateObject();
jaddnum(item,"hostrake",dstr(dp->hand.hostrake));
jaddnum(item,"pangearake",dstr(dp->hand.pangearake));
array = cJSON_CreateArray();
for (i=0; i<dp->N; i++)
jaddinum(array,dstr(dp->hand.won[i]));
jadd(item,"won",array);
jadd(json,"summary",item);
}
return(json);
}
void pangea_playerprint(struct cards777_pubdata *dp,int32_t i,int32_t myind)
{
int32_t countdown; char str[8]; struct pangea_info *sp = dp->table;
if ( (countdown= pangea_countdown(dp,i)) >= 0 )
sprintf(str,"%2d",countdown);
else str[0] = 0;
printf("%d: %6s %12.8f %2s | %12.8f %s\n",i,pangea_statusstr(dp->hand.betstatus[i]),dstr(dp->hand.bets[i]),str,dstr(sp->balances[pangea_slot(sp,i)]),i == myind ? "<<<<<<<<<<<": "");
}
void pangea_statusprint(struct cards777_pubdata *dp,struct cards777_privdata *priv,int32_t myind)
{
int32_t i; char handstr[64]; uint8_t hand[7];
for (i=0; i<dp->N; i++)
pangea_playerprint(dp,i,myind);
handstr[0] = 0;
if ( dp->hand.community[0] != dp->hand.community[1] )
{
for (i=0; i<5; i++)
if ( (hand[i]= dp->hand.community[i]) == 0xff )
break;
if ( i == 5 )
{
if ( (hand[5]= priv->hole[0]) != 0xff && (hand[6]= priv->hole[1]) != 0xff )
set_handstr(handstr,hand,1);
}
}
printf("%s\n",handstr);
}
/*
if ( hn->server->H.slot == 0 )
{
char *pangea_cashout(char *coinstr,int32_t oldtx_format,uint64_t values[],char *txidstrs[],int32_t vouts[],int32_t numinputs,char *destaddrs[],char *destscripts[],uint64_t outputs[],int32_t n,char *scriptPubKey,char *redeemScript,char *wip,uint64_t txfee,char sigs[][256],int32_t numplayers,uint8_t *privkey,int32_t privkeyind,char *othersignedtx);
uint64_t values[1],txfee; char *othersignedtx,*rawtx,*txidstrs[1],*destaddrs[1],*destscripts[1],sigs[CARDS777_MAXPLAYERS][256]; int32_t vouts[1]; uint64_t outputs[1];
if ( strcmp(dp->coinstr,"BTC") == 0 )
{
txfee = SATOSHIDEN/10000;
values[0] = SATOSHIDEN / 5000, txidstrs[0] = "94cb2925d802c6c3695f0765767d892e13bd90ca256cc08ed5d85fd737bcc848", vouts[0] = 0;
outputs[0] = SATOSHIDEN / 5000 - txfee;
}
else
{
txfee = SATOSHIDEN/1000;
values[0] = SATOSHIDEN, txidstrs[0] = "af980e0cf15c028d571767935e9e78ff0ad3068ff1a2ae2ca62c723a75ed8a80", vouts[0] = 1;
outputs[0] = SATOSHIDEN - txfee;
}
destaddrs[0] = dp->multisigaddr, destscripts[0] = dp->scriptPubKey;
memset(sigs,0,sizeof(sigs));
othersignedtx = 0;
for (i=0; i<dp->N; i++)
{
rawtx = pangea_cashout(dp->coinstr,strcmp(dp->coinstr,"BTC") == 0,values,txidstrs,vouts,1,destaddrs,destscripts,outputs,1,dp->scriptPubKey,dp->redeemScript,priv->wipstr,txfee,sigs,dp->N,THREADS[i]->hn.client->H.privkey.bytes,i,othersignedtx);
if ( othersignedtx != 0 )
free(othersignedtx);
othersignedtx = rawtx;
}
}
*/

487
iguana/pangea_init.c

@ -0,0 +1,487 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "pangea777.h"
void pangea_buyins(uint32_t *minbuyinp,uint32_t *maxbuyinp)
{
if ( *minbuyinp == 0 && *maxbuyinp == 0 )
{
*minbuyinp = 100;
*maxbuyinp = 1000;
}
else
{
PNACL_message("minbuyin.%d maxbuyin.%d -> ",*minbuyinp,*maxbuyinp);
if ( *minbuyinp < 20 )
*minbuyinp = 20;
if ( *maxbuyinp < *minbuyinp )
*maxbuyinp = (*minbuyinp * 4);
if ( *maxbuyinp > 1000 )
*maxbuyinp = 1000;
if ( *minbuyinp > *maxbuyinp )
*minbuyinp = *maxbuyinp;
PNACL_message("(%d %d)\n",*minbuyinp,*maxbuyinp);
}
}
struct pangea_info *pangea_create(struct pangea_thread *tp,int32_t *createdflagp,char *base,uint32_t timestamp,uint64_t *addrs,int32_t numaddrs,uint64_t bigblind,uint64_t ante,uint64_t *isbot,uint32_t minbuyin,uint32_t maxbuyin,int32_t hostrake)
{
struct pangea_info *sp = 0; bits256 hash; int32_t i,j,numcards,firstslot = -1; struct cards777_privdata *priv; struct cards777_pubdata *dp; struct iguana_info *coin;
if ( createdflagp != 0 )
*createdflagp = 0;
for (i=0; i<numaddrs; i++)
PNACL_message("%llu ",(long long)addrs[i]);
PNACL_message("pangea_create numaddrs.%d\n",numaddrs);
for (i=0; i<numaddrs; i++)
{
if ( addrs[i] == tp->nxt64bits )
break;
}
if ( i == numaddrs )
{
PNACL_message("this node not in addrs\n");
return(0);
}
if ( numaddrs > 0 && (sp= calloc(1,sizeof(*sp))) != 0 )
{
sp->tp = tp;
numcards = CARDS777_MAXCARDS;
pangea_buyins(&minbuyin,&maxbuyin);
tp->numcards = numcards, tp->N = numaddrs;
sp->numactive = numaddrs;
sp->dp = dp = cards777_allocpub((numaddrs >> 1) + 1,numcards,numaddrs);
dp->minbuyin = minbuyin, dp->maxbuyin = maxbuyin;
sp->minbuyin = minbuyin, sp->maxbuyin = maxbuyin;
dp->rakemillis = hostrake;
if ( dp->rakemillis > PANGEA_MAX_HOSTRAKE )
dp->rakemillis = PANGEA_MAX_HOSTRAKE;
dp->rakemillis += PANGEA_MINRAKE_MILLIS;
if ( dp == 0 )
{
PNACL_message("pangea_create: unexpected out of memory pub\n");
return(0);
}
for (j=0; j<5; j++)
dp->hand.community[j] = 0xff;
memcpy(sp->addrs,addrs,numaddrs * sizeof(sp->addrs[0]));
for (j=0; j<numaddrs; j++)
{
//if ( balances != 0 )
// dp->balances[j] = balances[j];
//else dp->balances[j] = 100;
if ( isbot != 0 )
sp->isbot[j] = isbot[j];
sp->active[j] = addrs[j];
}
sp->priv = priv = cards777_allocpriv(numcards,numaddrs);
priv->hole[0] = priv->hole[1] = 0xff;
if ( priv == 0 )
{
PNACL_message("pangea_create: unexpected out of memory priv\n");
return(0);
}
priv->automuck = Showmode;
priv->autofold = Autofold;
btc_priv2pub(sp->btcpub,tp->hn.client->H.privkey.bytes);
init_hexbytes_noT(sp->btcpubkeystr,sp->btcpub,33);
strcpy(sp->coinstr,base);
strcpy(dp->coinstr,base);
if ( (coin= iguana_coinfind(base)) != 0 )
{
sp->addrtype = coin->chain->pubval;//coin777_addrtype(&sp->p2shtype,base);
sp->wiftype = coin->chain->wipval;//coin777_wiftype(base);
}
btc_priv2wip(sp->wipstr,tp->hn.client->H.privkey.bytes,sp->wiftype);
strcpy(sp->btcpubkeys[sp->myslot],sp->btcpubkeystr);
PNACL_message("T%d: Automuck.%d Autofold.%d rakemillis.%d btcpubkey.(%s) (%s) addrtype.%02x p2sh.%02x wif.%02x\n",tp->hn.client->H.slot,priv->automuck,priv->autofold,dp->rakemillis,sp->btcpubkeystr,dp->coinstr,sp->addrtype,sp->p2shtype,sp->wiftype);
if ( (sp->timestamp= timestamp) == 0 )
sp->timestamp = (uint32_t)time(NULL);
sp->numaddrs = sp->numactive = numaddrs;
sp->basebits = stringbits(base);
sp->bigblind = dp->bigblind = bigblind, sp->ante = dp->ante = ante;
vcalc_sha256(0,hash.bytes,(uint8_t *)sp,numaddrs * sizeof(sp->addrs[0]) + 4*sizeof(uint32_t) + 3*sizeof(uint64_t));
sp->tableid = hash.txid;
for (i=0; i<sizeof(TABLES)/sizeof(*TABLES); i++)
{
if ( TABLES[i] != 0 )
{
if ( sp->tableid == TABLES[i]->tableid && tp->threadid == TABLES[i]->tp->threadid )
{
PNACL_message("tableid %llu already exists!\n",(long long)sp->tableid);
free(sp);
return(TABLES[i]);
}
}
else if ( firstslot < 0 )
firstslot = i;
}
TABLES[firstslot] = sp;
if ( createdflagp != 0 )
*createdflagp = 1;
}
return(sp);
}
cJSON *pangea_ciphersjson(struct cards777_pubdata *dp,struct cards777_privdata *priv)
{
int32_t i,j,nonz = 0; char hexstr[65]; cJSON *array = cJSON_CreateArray();
for (i=0; i<dp->numcards; i++)
for (j=0; j<dp->N; j++,nonz++)
{
init_hexbytes_noT(hexstr,priv->outcards[nonz].bytes,sizeof(bits256));
jaddistr(array,hexstr);
}
return(array);
}
cJSON *pangea_playerpubs(bits256 *playerpubs,int32_t num)
{
int32_t i; char hexstr[65]; cJSON *array = cJSON_CreateArray();
for (i=0; i<num; i++)
{
init_hexbytes_noT(hexstr,playerpubs[i].bytes,sizeof(bits256));
//PNACL_message("(%llx-> %s) ",(long long)playerpubs[i].txid,hexstr);
jaddistr(array,hexstr);
}
//PNACL_message("playerpubs\n");
return(array);
}
cJSON *pangea_cardpubs(struct cards777_pubdata *dp)
{
int32_t i; char hexstr[65]; cJSON *array = cJSON_CreateArray();
for (i=0; i<dp->numcards; i++)
{
init_hexbytes_noT(hexstr,dp->hand.cardpubs[i].bytes,sizeof(bits256));
jaddistr(array,hexstr);
}
init_hexbytes_noT(hexstr,dp->hand.checkprod.bytes,sizeof(bits256));
jaddistr(array,hexstr);
return(array);
}
cJSON *pangea_sharenrs(uint8_t *sharenrs,int32_t n)
{
int32_t i; cJSON *array = cJSON_CreateArray();
for (i=0; i<n; i++)
jaddinum(array,sharenrs[i]);
return(array);
}
char *pangea_newtable(int32_t threadid,cJSON *json,uint64_t my64bits,bits256 privkey,bits256 pubkey,char *transport,char *ipaddr,uint16_t port,uint32_t minbuyin,uint32_t maxbuyin,int32_t hostrake)
{
int32_t createdflag,num,i,myind= -1; uint64_t tableid,addrs[CARDS777_MAXPLAYERS],isbot[CARDS777_MAXPLAYERS];
struct pangea_info *sp; cJSON *array; struct pangea_thread *tp=0; char *base,*str,*hexstr,*endpoint,hex[1024]; uint32_t timestamp;
struct cards777_pubdata *dp; struct pangeanet777_server *srv=0;
str = jprint(json,0);
PNACL_message("T%d NEWTABLE.(%s)\n",threadid,str);
free(str);
if ( (tableid= j64bits(json,"tableid")) != 0 && (base= jstr(json,"base")) != 0 && (timestamp= juint(json,"timestamp")) != 0 )
{
if ( (array= jarray(&num,json,"addrs")) == 0 || num < 2 || num > CARDS777_MAXPLAYERS )
{
PNACL_message("no address or illegal num.%d\n",num);
return(clonestr("{\"error\":\"no addrs or illegal numplayers\"}"));
}
for (i=0; i<num; i++)
{
addrs[i] = j64bits(jitem(array,i),0);
if ( addrs[i] == my64bits )
{
threadid = myind = i;
if ( (tp= THREADS[threadid]) == 0 )
{
THREADS[threadid] = tp = calloc(1,sizeof(*THREADS[threadid]));
if ( i == 0 )
{
if ( (srv= pangeanet777_server(privkey,pubkey,transport,ipaddr,port,num)) == 0 )
PNACL_message("cant create pangeanet777 server\n");
else
{
tp->hn.server = srv;
memcpy(srv->H.privkey.bytes,privkey.bytes,sizeof(bits256));
memcpy(srv->H.pubkey.bytes,pubkey.bytes,sizeof(bits256));
}
}
else
{
PANGEA_MAXTHREADS = 1;
if ( (endpoint= jstr(json,"pangea_endpoint")) != 0 )
{
if ( strncmp(endpoint,"tcp://127.0.0.1",strlen("tcp://127.0.0.1")) == 0 || strncmp(endpoint,"ws://127.0.0.1",strlen("ws://127.0.0.1")) == 0 )
{
PNACL_message("ILLEGAL pangea_endpoint.(%s)\n",endpoint);
return(clonestr("{\"error\":\"contact pangea host and tell them to add myipaddr to their SuperNET.conf\"}"));
}
if ( (tp->hn.client= pangeanet777_client(privkey,pubkey,endpoint,i)) == 0 )
{
memcpy(tp->hn.client->H.privkey.bytes,privkey.bytes,sizeof(bits256));
memcpy(tp->hn.client->H.pubkey.bytes,pubkey.bytes,sizeof(bits256));
}
}
}
tp->nxt64bits = my64bits;
}
}
}
if ( myind < 0 )
return(clonestr("{\"error\":\"this table is not for me\"}"));
/*if ( (array= jarray(&num,json,"balances")) == 0 )
{
PNACL_message("no balances or illegal num.%d\n",num);
return(clonestr("{\"error\":\"no balances or illegal numplayers\"}"));
}
for (i=0; i<num; i++)
balances[i] = j64bits(jitem(array,i),0);*/
if ( (array= jarray(&num,json,"isbot")) != 0 )
{
for (i=0; i<num; i++)
isbot[i] = j64bits(jitem(array,i),0);
}
else memset(isbot,0,sizeof(isbot));
PNACL_message("call pangea_create\n");
if ( (sp= pangea_create(tp,&createdflag,base,timestamp,addrs,num,j64bits(json,"bigblind"),j64bits(json,"ante"),isbot,minbuyin,maxbuyin,hostrake)) == 0 )
{
PNACL_message("cant create table.(%s) numaddrs.%d\n",base,num);
return(clonestr("{\"error\":\"cant create table\"}"));
}
PNACL_message("back from pangea_create\n");
dp = sp->dp; sp->myslot = sp->myind = myind;
dp->table = sp;
tp->numcards = dp->numcards, tp->N = dp->N, tp->M = dp->M;
if ( threadid == 0 )
{
tp->hn.server->clients[0].pubdata = dp;
tp->hn.server->clients[0].privdata = sp->priv;
tp->hn.server->H.pubdata = dp;
tp->hn.server->H.privdata = sp->priv;
}
else
{
tp->hn.client->my.pubdata = dp;
tp->hn.client->my.privdata = sp->priv;
tp->hn.client->H.pubdata = dp;
tp->hn.client->H.privdata = sp->priv;
if ( THREADS[0] != 0 )
{
THREADS[0]->hn.server->clients[threadid].pubdata = dp;
THREADS[0]->hn.server->clients[threadid].privdata = sp->priv;
}
}
if ( (array= jarray(&num,json,"playerpubs")) == 0 || num < 2 || num > CARDS777_MAXPLAYERS )
{
PNACL_message("no address or illegal num.%d\n",num);
return(clonestr("{\"error\":\"no addrs or illegal numplayers\"}"));
}
for (i=0; i<num; i++)
{
hexstr = jstr(jitem(array,i),0);
decode_hex(sp->playerpubs[i].bytes,sizeof(bits256),hexstr);
PNACL_message("set playerpubs.(%s) %llx\n",hexstr,(long long)sp->playerpubs[i].txid);
if ( sp->playerpubs[i].txid == 0 )
{
PNACL_message("player.%d has no NXT pubkey\n",i);
return(clonestr("{\"error\":\"not all players have published NXT pubkeys\"}"));
}
}
if ( myind >= 0 && createdflag != 0 && addrs[myind] == tp->nxt64bits )
{
memcpy(sp->addrs,addrs,sizeof(*addrs) * dp->N);
dp->readymask |= (1 << sp->myslot);
pangea_sendcmd(hex,&tp->hn,"ready",-1,sp->btcpub,sizeof(sp->btcpub),0,0);
return(clonestr("{\"result\":\"newtable created\"}"));
}
else if ( createdflag == 0 )
{
if ( sp->addrs[0] == tp->nxt64bits )
return(clonestr("{\"result\":\"this is my table\"}"));
else return(clonestr("{\"result\":\"table already exists\"}"));
}
}
return(clonestr("{\"error\":\"no tableid\"}"));
}
struct pangea_thread *pangea_threadinit(struct supernet_info *plugin,int32_t maxplayers)
{
/* struct pangea_thread *tp; struct pangeanet777_server *srv;
PANGEA_MAXTHREADS = 1;
THREADS[0] = tp = calloc(1,sizeof(*THREADS[0]));
if ( tp == 0 )
{
PNACL_message("pangea_threadinit: unexpected out of memory\n");
return(0);
}
tp->nxt64bits = plugin->nxt64bits;
if ( (srv= pangeanet777_server(*(bits256 *)plugin->mypriv,*(bits256 *)plugin->mypub,plugin->transport,plugin->ipaddr,plugin->pangeaport,9)) == 0 )
PNACL_message("cant create pangeanet777 server\n");
else
{
tp->hn.server = srv;
memcpy(srv->H.privkey.bytes,plugin->mypriv,sizeof(bits256));
memcpy(srv->H.pubkey.bytes,plugin->mypub,sizeof(bits256));
}
return(tp);*/
return(0);
}
void pangea_create_newtable(char *retbuf,struct pangea_info *sp,struct cards777_pubdata *dp,uint64_t *isbot)
{
char *addrstr,*ciphers,*playerpubs,*isbotstr;
isbotstr = jprint(addrs_jsonarray(isbot,dp->N),1);
//balancestr = jprint(addrs_jsonarray(balances,num),1);
addrstr = jprint(addrs_jsonarray(sp->addrs,dp->N),1);
ciphers = jprint(pangea_ciphersjson(dp,sp->priv),1);
playerpubs = jprint(pangea_playerpubs(sp->playerpubs,dp->N),1);
dp->readymask |= (1 << sp->myslot);
sprintf(retbuf,"{\"cmd\":\"newtable\",\"broadcast\":\"allnodes\",\"myind\":%d,\"pangea_endpoint\":\"%s\",\"plugin\":\"relay\",\"destplugin\":\"pangea\",\"method\":\"busdata\",\"submethod\":\"newtable\",\"my64bits\":\"%llu\",\"tableid\":\"%llu\",\"timestamp\":%u,\"M\":%d,\"N\":%d,\"base\":\"%s\",\"bigblind\":\"%llu\",\"minbuyin\":\"%d\",\"maxbuyin\":\"%u\",\"rakemillis\":\"%u\",\"ante\":\"%llu\",\"playerpubs\":%s,\"addrs\":%s,\"isbot\":%s}",sp->myslot,sp->tp->hn.server->ep.endpoint,(long long)sp->tp->nxt64bits,(long long)sp->tableid,sp->timestamp,dp->M,dp->N,sp->coinstr,(long long)sp->bigblind,dp->minbuyin,dp->maxbuyin,dp->rakemillis,(long long)sp->ante,playerpubs,addrstr,isbotstr); //\"pluginrequest\":\"SuperNET\",
PNACL_message("START.(%s)\n",retbuf);
//dp->pmworks |= (1 << sp->myind);
free(addrstr), free(ciphers), free(playerpubs), free(isbotstr);// free(balancestr);
}
int32_t pangea_start(struct supernet_info *plugin,char *retbuf,char *base,uint32_t timestamp,uint64_t bigblind,uint64_t ante,int32_t hostrake,int32_t maxplayers,uint32_t minbuyin,uint32_t maxbuyin,cJSON *json)
{
char destNXT[64]; struct pangea_thread *tp; struct cards777_pubdata *dp;
int32_t createdflag,addrtype,haspubkey,i,j,slot,n,myind=-1,r,num=0,threadid=0; uint64_t addrs[512],isbot[512],tmp;
struct pangea_info *sp; cJSON *bids,*walletitem,*item; struct iguana_info *coin;
memset(addrs,0,sizeof(addrs));
PNACL_message("pangea_start rakemillis.%d\n",hostrake);
//memset(balances,0,sizeof(balances));
pangea_buyins(&minbuyin,&maxbuyin);
if ( hostrake < 0 || hostrake > PANGEA_MAX_HOSTRAKE )
{
PNACL_message("illegal hostrake.%d\n",hostrake);
strcpy(retbuf,"{\"error\":\"illegal hostrake\"}");
return(-1);
}
if ( bigblind == 0 )
bigblind = SATOSHIDEN;
if ( (tp= THREADS[threadid]) == 0 )
{
pangea_threadinit(plugin,maxplayers);
if ( (tp=THREADS[0]) == 0 )
{
strcpy(retbuf,"{\"error\":\"uinitialized threadid\"}");
PNACL_message("%s\n",retbuf);
return(-1);
}
}
PNACL_message("mynxt64bits.%llu base.(%s) maxplayers.%d minbuyin.%u maxbuyin.%u\n",(long long)tp->nxt64bits,base,maxplayers,minbuyin,maxbuyin);
if ( base == 0 || base[0] == 0 || maxplayers < 2 || maxplayers > CARDS777_MAXPLAYERS )
{
sprintf(retbuf,"{\"error\":\"bad params\"}");
PNACL_message("%s\n",retbuf);
return(-1);
}
if ( (coin= iguana_coinfind(base)) != 0 )
addrtype = coin->chain->pubval;//coin777_addrtype(&p2shtype,base);
if ( (bids= jarray(&n,json,"bids")) != 0 )
{
PNACL_message("numbids.%d\n",n);
for (i=num=0; i<n; i++)
{
item = jitem(bids,i);
if ( (addrs[num]= j64bits(item,"offerNXT")) != 0 && (walletitem= jobj(item,"wallet")) != 0 )
{
if ( j64bits(walletitem,"bigblind") == bigblind && j64bits(walletitem,"ante") == ante && juint(walletitem,"rakemillis") == hostrake )
{
//balances[num] = j64bits(walletitem,"balance");
isbot[num] = juint(walletitem,"isbot");
PNACL_message("(i.%d %llu) ",i,(long long)addrs[num]);//,dstr(balances[num]));
for (j=0; j<num; j++)
if ( addrs[j] == addrs[num] )
break;
if ( j == num )
{
if ( addrs[num] == tp->nxt64bits )
myind = num;
PNACL_message("%llu ",(long long)addrs[num]);
num++;
}
}
else PNACL_message("%d: %llu mismatched walletitem bigblind %.8f ante %.8f rake %.1f%%\n",i,(long long)addrs[num],dstr(j64bits(walletitem,"bigblind")),dstr(j64bits(walletitem,"ante")),(double)juint(walletitem,"rakemillis")/10.);
}
}
}
PNACL_message("(%llu) pangea_start(%s) threadid.%d myind.%d num.%d maxplayers.%d\n",(long long)tp->nxt64bits,base,tp->threadid,myind,num,maxplayers);
if ( (i= myind) > 0 )
{
addrs[i] = addrs[0];
addrs[0] = tp->nxt64bits;
//tmp = balances[i];
//balances[i] = balances[0];
//balances[0] = tmp;
tmp = isbot[i];
isbot[i] = isbot[0];
isbot[0] = tmp;
i = 0;
strcpy(retbuf,"{\"error\":\"host needs to be locally started and the first entry in addrs\"}");
return(-1);
}
while ( num > maxplayers )
{
r = (rand() % (num-1));
PNACL_message("swap out %d of %d\n",r+1,num);
num--;
isbot[r + 1] = isbot[num];
//balances[r + 1] = balances[num];
addrs[r + 1] = addrs[num];
}
PNACL_message("pangea numplayers.%d\n",num);
if ( (sp= pangea_create(tp,&createdflag,base,timestamp,addrs,num,bigblind,ante,isbot,minbuyin,maxbuyin,hostrake)) == 0 )
{
PNACL_message("cant create table.(%s) numaddrs.%d\n",base,num);
strcpy(retbuf,"{\"error\":\"cant create table, make sure all players have published NXT pubkeys\"}");
return(-1);
}
PNACL_message("back from pangea_create\n");
dp = sp->dp, dp->table = sp;
sp->myslot = sp->myind = myind;
if ( createdflag != 0 && myind == 0 && addrs[myind] == tp->nxt64bits )
{
tp->numcards = dp->numcards, tp->N = dp->N, tp->M = dp->M;
PNACL_message("myind.%d: hostrake.%d\n",myind,dp->rakemillis);
dp->minbuyin = minbuyin, dp->maxbuyin = maxbuyin;
tp->hn.server->clients[myind].pubdata = dp;
tp->hn.server->clients[myind].privdata = sp->priv;
tp->hn.server->H.pubdata = dp;
tp->hn.server->H.privdata = sp->priv;
for (j=0; j<dp->N; j++)
{
if ( THREADS[j] != 0 )
sp->playerpubs[j] = THREADS[j]->hn.client->H.pubkey;
else
{
expand_nxt64bits(destNXT,addrs[j]);
sp->playerpubs[j] = issue_getpubkey(&haspubkey,destNXT);
if ( (slot= pangeanet777_register(THREADS[0]->hn.server,sp->playerpubs[j],-1)) != j )
PNACL_message("unexpected register slot.%d for j.%d\n",slot,j);
}
//PNACL_message("thread[%d] pub.%llx priv.%llx\n",j,(long long)dp->playerpubs[j].txid,(long long)THREADS[j]->hn.client->H.privkey.txid);
}
pangea_create_newtable(retbuf,sp,dp,isbot);
#ifdef BUNDLED
if ( 1 )
{
char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *destNXTaddr);
char *str; uint32_t nonce;
if ( (str= busdata_sync(&nonce,retbuf,"allnodes",0)) != 0 )
free(str);
}
#endif
}
return(0);
}

435
iguana/pangea_network.c

@ -0,0 +1,435 @@
/******************************************************************************
* Copyright © 2014-2016 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "pangea777.h"
struct pangeanet777_id *pangeanet777_find(struct pangeanet777_server *srv,bits256 senderpub)
{
int32_t i; uint64_t senderbits = acct777_nxt64bits(senderpub);
if ( srv->num > 0 )
{
for (i=0; i<srv->max; i++)
if ( srv->clients[i].nxt64bits == senderbits )
return(&srv->clients[i]);
}
return(0);
}
void pangeanet777_lastcontact(struct pangeanet777_server *srv,bits256 senderpub)
{
struct pangeanet777_id *ptr;
if ( (ptr= pangeanet777_find(srv,senderpub)) != 0 )
ptr->lastcontact = (uint32_t)time(NULL);
}
void pangeanet777_processmsg(uint64_t *destbitsp,bits256 *senderpubp,queue_t *Q,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t origlen,int32_t pmflag)
{
char *jsonstr = 0; bits256 sig; uint32_t timestamp; int32_t len; uint64_t senderbits; uint8_t *ptr=0; cJSON *json; long extra;
extra = sizeof(*senderpubp) + sizeof(*destbitsp) + sizeof(sig) + sizeof(senderbits) + sizeof(timestamp);
if ( (len= origlen) > extra )
{
//printf("got msglen.%d\n",origlen);
if ( (ptr= malloc(len*4 + 8192 + sizeof(struct queueitem) - extra)) == 0 )
{
printf("hostnet777_processmsg cant alloc queueitem\n");
return;
}
if ( (len= SuperNET_decrypt(senderpubp,&senderbits,&timestamp,mypriv,mypub,&ptr[sizeof(struct queueitem)],len*4,msg,len)) > 1 && len < len*4 )
{
jsonstr = (char *)&ptr[sizeof(struct queueitem)];
if ( (json= cJSON_Parse(jsonstr)) != 0 )
{
//printf("now.%lld vs millitime.%lld lag.%lld\n",(long long)now,(long long)millitime,(long long)(millitime - now));
if ( pmflag != 0 && juint(json,"timestamp") != timestamp && juint(json,"timestamp")+1 != timestamp )
printf("msg.(%s) timestamp.%u mismatch | now.%ld\n",jsonstr,timestamp,(long)time(NULL));
else if ( pmflag != 0 && j64bits(json,"sender") != senderbits )
printf("msg.(%ld) sender.%llu mismatch vs json.%llu\n",(long)strlen(jsonstr),(long long)senderbits,(long long)j64bits(json,"sender"));
else
{
//printf("%llu: QUEUE msg.%d\n",(long long)acct777_nxt64bits(mypub),len);
//if ( hostnet777_hashes(recvhashes,64,ptr,len) < 0 )
queue_enqueue("host777",Q,(void *)ptr,0);
ptr = 0;
}
free_json(json);
} else printf("parse error.(%s)\n",jsonstr);
} else printf("decrypt error len.%d origlen.%d\n",len,origlen);
} else printf("origlen.%d\n",origlen);
if ( ptr != 0 )
free(ptr);
}
int32_t pangeanet777_idle(union pangeanet777 *hn)
{
int32_t len,slot,sock,n = 0; bits256 senderpub,mypriv,mypub; uint64_t destbits; uint8_t *msg;
long extra = sizeof(bits256)+sizeof(uint64_t);
if ( (slot= hn->client->H.slot) != 0 )
{
mypriv = hn->client->H.privkey, mypub = hn->client->H.pubkey;
if ( (sock= hn->client->subsock) >= 0 && (len= nn_recv(sock,&msg,NN_MSG,0)) > extra )
{
SuperNET_copybits(1,msg,(void *)&destbits,sizeof(uint64_t));
//printf("client got pub len.%d\n",len);
if ( destbits == 0 || destbits == hn->client->H.nxt64bits )
pangeanet777_processmsg(&destbits,&senderpub,&hn->client->H.Q,mypriv,mypub,msg,len,0), n++;
nn_freemsg(msg);
} else if ( hn->client->H.pollfunc != 0 )
(*hn->client->H.pollfunc)(hn);
}
else
{
//printf("server idle %.0f\n",milliseconds());
mypriv = hn->server->H.privkey, mypub = hn->server->H.pubkey;
for (slot=1; slot<hn->server->num; slot++)
{
//printf("check ind.%d %.0f\n",ind,milliseconds());
if ( (sock= hn->server->clients[slot].pmsock) >= 0 && (len= nn_recv(sock,&msg,NN_MSG,0)) > extra )
{
//printf("server got pm[%d] %d\n",slot,len);
SuperNET_copybits(1,msg,(void *)&destbits,sizeof(uint64_t));
if ( destbits == 0 || destbits == hn->server->H.nxt64bits )
{
pangeanet777_processmsg(&destbits,&senderpub,&hn->server->H.Q,mypriv,mypub,msg,len,1);
pangeanet777_lastcontact(hn->server,senderpub);
}
printf("pangeanet777_idle: do the send here\n");
//pangeanet777_send(hn->server->pubsock,msg,len);
nn_freemsg(msg);
}
}
if ( hn->server->H.pollfunc != 0 )
(*hn->server->H.pollfunc)(hn);
}
return(n);
}
int32_t pangeanet777_replace(struct pangeanet777_server *srv,bits256 clientpub,int32_t slot)
{
char endpoint[128],buf[128]; uint64_t nxt64bits = acct777_nxt64bits(clientpub);
sprintf(endpoint,"%s://%s:%u",srv->ep.transport,srv->ep.ipaddr,srv->ep.port + slot + 1);
//sprintf(buf,"%s://127.0.0.1:%u",srv->ep.transport,srv->ep.port + slot + 1);
strcpy(buf,endpoint);
if ( srv->clients[slot].pmsock < 0 )
{
printf("pangeanet777_replace deal with getting new socket here\n");
//srv->clients[slot].pmsock = nn_createsocket(buf,1,"NN_PULL",NN_PULL,srv->ep.port + slot + 1,10,10);
}
printf("NN_PULL.%d for slot.%d\n",srv->clients[slot].pmsock,slot);
srv->clients[slot].pubkey = clientpub;
srv->clients[slot].nxt64bits = nxt64bits;
srv->clients[slot].lastcontact = (uint32_t)time(NULL);
return(srv->clients[slot].pmsock);
}
int32_t pangeanet777_register(struct pangeanet777_server *srv,bits256 clientpub,int32_t slot)
{
int32_t i,n; struct pangeanet777_id *ptr;
if ( slot < 0 )
{
if ( (ptr= pangeanet777_find(srv,clientpub)) != 0 )
{
slot = (int32_t)(((long)ptr - (long)srv->clients) / sizeof(*srv->clients));
//printf("pangea_register: deregister slot.%d\n",slot);
if ( ptr->pmsock >= 0 )
nn_shutdown(ptr->pmsock,0);
memset(ptr,0,sizeof(*ptr));
ptr->pmsock = -1;
srv->num--;
return(-1);
}
for (slot=1; slot<srv->max; slot++)
if ( srv->clients[slot].nxt64bits == 0 )
break;
}
if ( srv->num >= srv->max )
{
printf("pangea_register: cant register anymore num.%d vs max.%d\n",srv->num,srv->max);
return(-1);
}
if ( (ptr= pangeanet777_find(srv,clientpub)) != 0 )
{
printf("pangea_register: cant register duplicate %llu\n",(long long)acct777_nxt64bits(clientpub));
return((int32_t)(((long)ptr - (long)srv->clients) / sizeof(*srv->clients)));
}
if ( slot != srv->num )
{
printf("pangea_register: cant register slot.%d vs num.%d vs max.%d\n",slot,srv->num,srv->max);
return(-1);
}
pangeanet777_replace(srv,clientpub,slot);
srv->num++;
for (i=n=0; i<srv->max; i++)
if ( srv->clients[i].nxt64bits != 0 )
n++;
if ( n != srv->num )
{
printf("mismatched nonz nxt64bits n.%d vs %d\n",n,srv->num);
srv->num = n;
}
return(slot);
}
struct pangeanet777_client *pangeanet777_client(bits256 privkey,bits256 pubkey,char *srvendpoint,int32_t slot)
{
char endbuf[128],endbuf2[128]; uint16_t port; struct pangeanet777_client *ptr;
ptr = calloc(1,sizeof(*ptr));
ptr->H.slot = slot;
ptr->H.privkey = privkey, ptr->H.pubkey = ptr->my.pubkey = pubkey;
ptr->H.nxt64bits = ptr->my.nxt64bits = acct777_nxt64bits(pubkey);
ptr->my.lastcontact = (uint32_t)time(NULL);
strcpy(endbuf,srvendpoint);
endbuf[strlen(endbuf)-4] = 0;
port = atoi(&srvendpoint[strlen(endbuf)]);
sprintf(endbuf2,"%s%u",endbuf,port + 1 + slot);
printf("pangeanet777_client: deal with creating connections here\n");
//ptr->my.pmsock = nn_createsocket(endbuf2,0,"NN_PUSH",NN_PUSH,0,10,100);
printf("NN_PUSH %d from (%s) port.%d\n",ptr->my.pmsock,endbuf2,port+1+slot);
sprintf(endbuf2,"%s%u",endbuf,port);
//ptr->subsock = nn_createsocket(endbuf2,0,"NN_SUB",NN_SUB,0,10,100);
printf("SUB %d from (%s) port.%d\n",ptr->subsock,endbuf2,port);
nn_setsockopt(ptr->subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0);
//sprintf(endbuf2,"%s%u",endbuf,port);
//ptr->pushsock = nn_createsocket(endbuf2,0,"NN_PUSH",NN_PUSH,0,10,1);
//printf("PUSH %d to (%s)\n",ptr->pushsock,endbuf2);
return(ptr);
}
void pangeanet777_freeclient(struct pangeanet777_client *client)
{
client->H.done = 1;
if ( client->subsock >= 0 )
nn_shutdown(client->subsock,0);
//if ( client->pushsock >= 0 )
// nn_shutdown(client->pushsock,0);
if ( client->my.pmsock >= 0 )
nn_shutdown(client->my.pmsock,0);
}
void pangeanet777_freeserver(struct pangeanet777_server *srv)
{
int32_t ind;
srv->H.done = 1;
//if ( srv->pullsock >= 0 )
// nn_shutdown(srv->pullsock,0);
if ( srv->pubsock >= 0 )
nn_shutdown(srv->pubsock,0);
for (ind=1; ind<srv->max; ind++)
{
if ( srv->clients[ind].pmsock >= 0 )
nn_shutdown(srv->clients[ind].pmsock,0);
}
}
struct pangeanet777_server *pangeanet777_server(bits256 srvprivkey,bits256 srvpubkey,char *transport,char *ipaddr,uint16_t port,int32_t maxclients)
{
struct pangeanet777_server *srv; int32_t i; struct pangeanet777_endpoint *ep; char buf[128];
srv = calloc(1,sizeof(*srv) + maxclients*sizeof(struct pangeanet777_id));
srv->max = maxclients;
ep = &srv->ep;
if ( (ep->port= port) == 0 )
ep->port = port = 8000 + (rand() % 1000);
if ( transport == 0 || transport[0] == 0 )
transport = TEST_TRANSPORT;
if ( ipaddr == 0 || ipaddr[0] == 0 )
ipaddr = "127.0.0.1";
strcpy(ep->transport,transport), strcpy(ep->ipaddr,ipaddr);
for (i=0; i<maxclients; i++)
srv->clients[i].pmsock = -1;
srv->H.privkey = srvprivkey;
srv->H.pubkey = srv->clients[0].pubkey = srvpubkey;
srv->H.nxt64bits = srv->clients[0].nxt64bits = acct777_nxt64bits(srvpubkey);
sprintf(ep->endpoint,"%s://%s:%u",transport,ipaddr,port);
if ( strcmp(transport,"tcpmux") == 0 )
strcat(ep->endpoint,"/pangea");
//sprintf(buf,"%s://127.0.0.1:%u",transport,port);
strcpy(buf,ep->endpoint);
printf("pangeanet777_server: create socket here\n");
//srv->pubsock = nn_createsocket(buf,1,"NN_PUB",NN_PUB,port,10,100);
printf("PUB.%d to (%s) pangeaport.%d\n",srv->pubsock,ep->endpoint,port);
srv->num = 1;
return(srv);
}
void *pangeanet777_idler(union pangeanet777 *ptr)
{
while ( ptr->client->H.done == 0 )
{
if ( pangeanet777_idle(ptr) == 0 )
usleep(1000);
}
//printf("pangea_idler ind.%d done\n",ptr->client->H.slot);
sleep(1);
free(ptr);
return(0);
}
int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis);
#define pangeanet777_broadcast(mypriv,mypub,msg,len) SuperNET_sendmsg(myinfo,coin,addr,zeropoint,mypriv,mypub,msg,len,space,0)
#define pangeanet777_blindcast(msg,len) SuperNET_sendmsg(myinfo,coin,addr,zeropoint,zeropoint,zeropoint,msg,len,space,0)
#define pangeanet777_signedPM(destpub,mypriv,mypub,msg,len) SuperNET_sendmsg(myinfo,coin,addr,destpub,mypriv,mypub,msg,len,space,0)
#define pangeanet777_blindPM(destpub,msg,len) SuperNET_sendmsg(myinfo,coin,addr,destpub,zeropoint,zeropoint,msg,len,space,0)
void pangeanet777_msg(uint64_t destbits,bits256 destpub,union pangeanet777 *src,int32_t blindflag,char *jsonstr,int32_t len)
{
static bits256 zeropoint;
struct supernet_info *myinfo = SuperNET_MYINFO(0); uint8_t *space;
struct iguana_peer *addr = 0; struct iguana_info *coin = iguana_coinfind("BTCD");
if ( destbits == 0 )
{
//printf(">>>>>>>>> blind.%d broadcast from %llu, len.%d\n",blindflag,(long long)src->client->H.nxt64bits,len);
space = calloc(1,IGUANA_MAXPACKETSIZE);
if ( blindflag != 0 )
pangeanet777_blindcast((uint8_t *)jsonstr,len);
else pangeanet777_broadcast(src->client->H.privkey,src->client->H.pubkey,(uint8_t *)jsonstr,len);
free(space);
if ( src->server->H.slot == 0 )
queue_enqueue("loopback",&src->client->H.Q,queueitem(jsonstr),1);
}
else if ( destbits != src->client->H.nxt64bits )
{
//printf(">>>>>>>>> blind.%d PM from %llu to %llu\n",blindflag,(long long)src->client->H.nxt64bits,(long long)destbits);
space = calloc(1,IGUANA_MAXPACKETSIZE);
if ( blindflag != 0 )
pangeanet777_blindPM(destpub,(uint8_t *)jsonstr,len);
else pangeanet777_signedPM(destpub,src->client->H.privkey,src->client->H.pubkey,(uint8_t *)jsonstr,len);
free(space);
}
else queue_enqueue("loopback",&src->client->H.Q,queueitem(jsonstr),1);
}
int32_t pangea_search(struct pangea_info *sp,uint64_t nxt64bits)
{
int32_t i;
for (i=0; i<sp->numactive; i++)
if ( sp->active[i] == nxt64bits )
return(i);
for (i=0; i<sp->numactive; i++)
PNACL_message("%llu ",(long long)sp->active[i]);
PNACL_message("active[]\n");
for (i=0; i<sp->numaddrs; i++)
PNACL_message("%llu ",(long long)sp->addrs[i]);
PNACL_message("addrs[]\n");
PNACL_message("pangea_search: slot.%d ind.%d cant find %llu in active[%d]\n",sp->myslot,sp->myind,(long long)nxt64bits,sp->numactive);
return(-1);
}
int32_t pangea_tableaddr(struct cards777_pubdata *dp,uint64_t destbits)
{
int32_t i; struct pangea_info *sp;
if ( dp != 0 && (sp= dp->table) != 0 )
{
for (i=0; i<sp->numaddrs; i++)
if ( sp->addrs[i] == destbits )
return(i);
}
return(-1);
}
int32_t pangea_addplayer(struct cards777_pubdata *dp,struct pangea_info *sp,bits256 clientpub)
{
int32_t i,n,openslot = -1; uint64_t nxt64bits = acct777_nxt64bits(clientpub);
for (i=n=0; i<sp->numaddrs; i++)
{
if ( sp->addrs[i] == nxt64bits )
{
PNACL_message("pangea_addplayer: player %llu already in addrs[%d]\n",(long long)nxt64bits,i);
return(-1);
}
if ( sp->balances[i] <= 0 )
openslot = i;
}
if ( openslot < 0 || sp->numactive >= sp->numaddrs-1 )
{
PNACL_message("pangea_addplayer: no room to add %llu\n",(long long)nxt64bits);
return(-1);
}
dp->readymask &= ~(1 << openslot);
sp->addrs[openslot] = nxt64bits;
sp->playerpubs[openslot] = clientpub;
sp->active[sp->numactive++] = nxt64bits;
if ( sp->myslot == 0 )
{
uint64_t isbot[CARDS777_MAXPLAYERS]; char *retbuf = malloc(65536);
if ( retbuf != 0 )
{
pangeanet777_replace(sp->tp->hn.server,clientpub,openslot);
for (i=0; i<sp->numactive; i++)
isbot[i] = sp->isbot[i];
pangea_create_newtable(retbuf,sp,dp,isbot);
pangeanet777_msg(nxt64bits,clientpub,&sp->tp->hn,0,retbuf,(int32_t)strlen(retbuf)+1);
free(retbuf);
}
}
pangea_neworder(dp,sp,0,0);
return(n);
}
bits256 pangea_destpub(uint64_t destbits)
{
int32_t i,haspubkey; bits256 destpub; char destNXT[64];
memset(destpub.bytes,0,sizeof(destpub));
for (i=0; i<sizeof(TABLES)/sizeof(*TABLES); i++)
if ( TABLES[i] != 0 && TABLES[i]->tp->nxt64bits == destbits )
{
destpub = TABLES[i]->tp->hn.client->H.pubkey;
break;
}
if ( i == sizeof(TABLES)/sizeof(*TABLES) )
{
expand_nxt64bits(destNXT,destbits);
destpub = issue_getpubkey(&haspubkey,destNXT);
}
return(destpub);
}
struct pangea_info *pangea_find(uint64_t tableid,int32_t threadid)
{
int32_t i;
for (i=0; i<sizeof(TABLES)/sizeof(*TABLES); i++)
if ( TABLES[i] != 0 && tableid == TABLES[i]->tableid && (threadid < 0 || TABLES[i]->tp->threadid == threadid) )
return(TABLES[i]);
return(0);
}
struct pangea_info *pangea_find64(uint64_t tableid,uint64_t nxt64bits)
{
int32_t i,j;
for (i=0; i<sizeof(TABLES)/sizeof(*TABLES); i++)
{
if ( TABLES[i] != 0 && (tableid == 0 || tableid == TABLES[i]->tableid) && TABLES[i]->tp != 0 )
{
for (j=0; j<TABLES[i]->numaddrs; j++)
{
if ( TABLES[i]->addrs[j] == nxt64bits )
return(TABLES[i]);
}
}
}
return(0);
}
void pangea_free(struct pangea_info *sp)
{
int32_t i;
for (i=0; i<sizeof(TABLES)/sizeof(*TABLES); i++)
if ( TABLES[i] == sp )
{
TABLES[i] = 0;
break;
}
PNACL_message("PANGEA PURGE %llu\n",(long long)sp->tableid);
free(sp);
}

644
iguana/poker.c

@ -0,0 +1,644 @@
// from http://www.azillionmonkeys.com/qed/poker.zip
// shamelessly copied from azillionmonkeys. getting millions of evals per second!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
#define CLUB_SUIT (1)
#define DIAMOND_SUIT (2)
#define HEART_SUIT (4)
#define SPADE_SUIT (8)
#define RANK_SHL (27)
#define SUBR_SHL (13)
#define SUBR_SHLMASK ((1<<SUBR_SHL)-1)
#define STRAIGHT_FLUSH_SCORE (8 << RANK_SHL)
#define FOUR_KIND_SCORE (7 << RANK_SHL)
#define FULL_HOUSE_SCORE (6 << RANK_SHL)
#define FLUSH_SCORE (5 << RANK_SHL)
#define STRAIGHT_SCORE (4 << RANK_SHL)
#define THREE_KIND_SCORE (3 << RANK_SHL)
#define TWO_PAIR_SCORE (2 << RANK_SHL)
#define TWO_KIND_SCORE (1 << RANK_SHL)
#define ONE_PAIR_SCORE (TWO_KIND_SCORE)
typedef uint8_t u8;
typedef int8_t s8;
typedef uint32_t u32;
typedef int32_t s32;
typedef struct { int32_t len; u8 entry[52]; } CardPileType;
static char *handstrs[16] = { "high card", "one pair", "two pair", "three of a kind", "straight", "flush", "full house", "four of a kind", "straight flush", "err", "err", "err", "err", "err", "err", "err" };
static char *kickerstrs[16] = { "", "kickers", "kicker", "kickers", "high", "high", "full of", "kicker", "high", "err", "err", "err", "err", "err", "err", "err" };
static u32 CardValue[52] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
};
static u32 CardSuit[52] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
};
int32_t cardstr(char *cardstr,uint8_t card)
{
int32_t suit; char *cardc = "A234567890JQK",suitc[4] = { 'C', 'D', 'H', 'S' };
suit = card / 13;
card %= 13;
if ( card == 9 )
sprintf(cardstr,"10%c",suitc[suit]);
else sprintf(cardstr,"%c%c",cardc[card],suitc[suit]);
return(card);
}
static u32 CardSuitIdx[52] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
};
static u32 CardMask[52] = {
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000
};
static u32 FiveCardDrawScoreFast (u32 c0, u32 c1, u32 c2, u32 c3, u32 c4, u32 u)
{
u32 y,z,m1,m2,m3,m4;
// Test for single suitedness
u = u & (u - 1);
// Build masks of 1, 2, 3, and 4 of a kind.
m1 = c0 | c1;
m2 = c1 & c0;
m2 |= c2 & m1;
m1 |= c2;
m2 |= c3 & m1;
m1 |= c3;
m2 |= c4 & m1;
m1 |= c4;
if (m2 == 0) { // No pairs?
// Is the mask a sequence of 1 bits?
z = m1 & (m1 - 1);
z ^= m1;
y = (z << 5) - z;
// Deal with the bicycle/wheel 5,4,3,2,Ace straight
if (m1 == 0x100F) {
if (u != 0) return STRAIGHT_SCORE + 0xF;
return STRAIGHT_FLUSH_SCORE + 0xF;
}
if (y == m1) {
if (u != 0) return STRAIGHT_SCORE + m1;
return STRAIGHT_FLUSH_SCORE + m1;
}
if (u != 0) return m1; // Nothing
return FLUSH_SCORE + m1;
}
/*
// m1 = c0 | ... | c4
// m2 = (c0 & c1) | ((c0|c1) & c2) | ((c0|c1|c2) & c3) | ((c0|c1|c2|c3) & c4)
// m3 = mask of 3 or 4 of a kind.
// m4 = mask of 4 of a kind.
*/
m1 = c0 | c1;
m2 = c1 & c0;
m3 = c2 & m2;
m2 |= c2 & m1;
m1 |= c2;
m4 = c3 & m3;
m3 |= c3 & m2;
m2 |= c3 & m1;
m1 |= c3;
m4 |= c4 & m3;
m3 |= c4 & m2;
m2 |= c4 & m1;
m1 |= c4;
m1 &= ~m2;
if (m3 == 0) {
if ((m2 & (m2 - 1)) == 0)
return TWO_KIND_SCORE + (m2 << SUBR_SHL) + m1;
return TWO_PAIR_SCORE + (m2 << SUBR_SHL) + m1;
}
m2 &= ~m3;
if (m4 == 0) {
if (m2 == 0)
return THREE_KIND_SCORE + (m3 << SUBR_SHL) + m1;
return FULL_HOUSE_SCORE + (m3 << SUBR_SHL) + m2;
}
return FOUR_KIND_SCORE + (m4 << SUBR_SHL) + m1;
}
static u32 FiveCardDrawScore (const u8 * h)
{
u32 c0, c1, c2, c3, c4,u;
// Make suits powers of two.
u = CardSuit[h[0]];
u |= CardSuit[h[1]];
u |= CardSuit[h[2]];
u |= CardSuit[h[3]];
u |= CardSuit[h[4]];
// Make cards powers of two.
c0 = CardMask[h[0]];
c1 = CardMask[h[1]];
c2 = CardMask[h[2]];
c3 = CardMask[h[3]];
c4 = CardMask[h[4]];
return FiveCardDrawScoreFast (c0, c1, c2, c3, c4, u);
}
static u32 SevenCardDrawFlush (const u8 * h, const u32 c[7])
{
static s32 LG2TAB[9] = {-1, 0, 1, -1, 2, -1, -1, -1, 3};
u32 i,t,f[4]; s32 cc[4],s;
// Make suits powers of two.
// There is at most one flush in a 7 card hand. So up to 4 masks arecreated, each being the set of cards in one particular suit.
// As themasks are created a maximum countdown from 4 is tracked.
#if 0
s = (((((u32 *) h)[1])) * 5) & 0x00C0C0C0;
i = (((((u32 *) h)[0])) * 5) & 0xC0C0C0C0;
s = ((s * (1 + 64 + 4096)) >> 8) & 0x3F00;
i = ((i * (1 + 64 + 4096 + 262144)) >> 24) | s;
#endif
f[0] = f[1] = f[2] = f[3] = 0;
cc[0] = cc[1] = cc[2] = cc[3] = 4;
i = CardSuitIdx[h[0]];
f[i] = c[0]; cc[i]--;
i = CardSuitIdx[h[1]];
f[i] |= c[1]; cc[i]--;
i = CardSuitIdx[h[2]];
f[i] |= c[2]; cc[i]--;
i = CardSuitIdx[h[3]];
f[i] |= c[3]; cc[i]--;
i = CardSuitIdx[h[4]];
f[i] |= c[4]; cc[i]--;
i = CardSuitIdx[h[5]];
f[i] |= c[5]; cc[i]--;
i = CardSuitIdx[h[6]];
f[i] |= c[6]; cc[i]--;
// If any of the counts goes below 0, then that suit has at least 5 cards in it.
if (((cc[0] | cc[1]) | (cc[2] | cc[3])) < 0) {
// Map the negative count (of which there is at most 1) to the suit index.
s = (((cc[0] & 8) | (cc[1] & 16)) | ((cc[2] & 32) | (cc[3] & 64))) >> 3;
s = LG2TAB[s];
// Work out the top 5 cards, so that the proper flush is also known ...
t = f[s];
while (cc[s] < -1) {
t &= t - 1; // Rip off last bit.
cc[s]++;
}
// ... but also keep the low part so that all straight flushes can still be tested for.
return f[s] | (t << SUBR_SHL);
}
// 0 -> indicates there is no flush in the hand.
return 0;
}
#define SevenCardDrawFlushScore(f) (FLUSH_SCORE + ((f) >> SUBR_SHL))
u32 SevenCardDrawScore (const u8 * h)
{
u32 c[7],f, t, s, u, v,m1, m2, m3, m4;
c[0] = CardMask[h[0]];
c[1] = CardMask[h[1]];
c[2] = CardMask[h[2]];
c[3] = CardMask[h[3]];
c[4] = CardMask[h[4]];
c[5] = CardMask[h[5]];
c[6] = CardMask[h[6]];
// Work out flush mask always, since its only redundant in the case of a full house or 4 of a kind.
f = SevenCardDrawFlush (h, c);
// t is the full card mask
t = ((c[0] | c[1]) | (c[2] | c[3])) | (c[4] | c[5] | c[6]);
// If 7 cards are found in a row ...
s = t & (t - 1);
v = s ^ t;
u = (v << 7) - 1;
u &= ~(u >> 7);
// ... then work out the possible straight flush/bicycle, straight, and flush possibilities.
if ((u & t) == u) {
if (f) {
// Intersect the flush mask with the straight mask to try to figure out if we have a straight flush.
s = f & u;
u = s & (s - 1);
u ^= s;
u = (u << 7) - 1;
u &= ~(u >> 5);
t = u >> 1;
v = u >> 2;
if ((u & s) == u) return STRAIGHT_FLUSH_SCORE + u;
if ((t & s) == t) return STRAIGHT_FLUSH_SCORE + t;
if ((v & s) == v) return STRAIGHT_FLUSH_SCORE + v;
// Deal with possible bicycle/wheel 5,4,3,2,Ace straight flush
if ((0x100F & f) == 0x100F)
return STRAIGHT_FLUSH_SCORE + 0xF;
return SevenCardDrawFlushScore (f);
}
u &= ~(u >> 5);
return STRAIGHT_SCORE + u;
}
// If at most 6 cards are found in a row ...
u = (v << 6) - 1;
u &= ~(u >> 6);
if ((u & t) != u) {
u = s & (s - 1);
u ^= s;
u = (u << 6) - 1;
u &= ~(u >> 6);
}
// ... then work out the possible straight flush/bicycle, straight, and flush possibilities.
if ((u & t) == u) {
if (f) {
s = f & u;
u = s & (s - 1);
u ^= s;
u = (u << 6) - 1;
u &= ~(u >> 5);
t = u >> 1;
if ((u & s) == u) return STRAIGHT_FLUSH_SCORE + u;
if ((t & s) == t) return STRAIGHT_FLUSH_SCORE + t;
// Deal with possible bicycle/wheel 5,4,3,2,Ace straight flush
if ((0x100F & f) == 0x100F)
return STRAIGHT_FLUSH_SCORE + 0xF;
return SevenCardDrawFlushScore (f);
}
u &= ~(u >> 5);
return STRAIGHT_SCORE + u;
}
// If at most 5 cards are found in a row ...
u = (v << 5) - 1;
u &= ~(u >> 5);
if ((u & t) != u) {
v = s;
s = s & (s - 1);
v ^= s;
u = (v << 5) - 1;
u &= ~(u >> 5);
if ((u & t) != u) {
u = s & (s - 1);
s ^= u;
u = (s << 5) - 1;
u &= ~(u >> 5);
}
}
// ... then work out the possible straight flush/bicycle, straight, and flush possibilities.
if ((u & t) == u) {
if (f) {
s = f & u;
u = s & (s - 1);
u ^= s;
u = (u << 5) - 1;
u &= ~(u >> 5);
if ((u & s) == u) {
return STRAIGHT_FLUSH_SCORE + u;
}
// Deal with possible bicycle/wheel 5,4,3,2,Ace straight flush
if ((0x100F & f) == 0x100F)
return STRAIGHT_FLUSH_SCORE + 0xF;
return SevenCardDrawFlushScore (f);
}
u &= ~(u >> 5);
return STRAIGHT_SCORE + u;
}
// Deal with the bicycle/wheel 5,4,3,2,Ace straight
if ((0x100F & t) == 0x100F) {
if (f)
{
if ((0x100F & f) == 0x100F)
return STRAIGHT_FLUSH_SCORE + 0xF;
return SevenCardDrawFlushScore (f);
}
return STRAIGHT_SCORE + 0xF;
}
/*
// m1 = c0 | ... | c4
// m2 = (c0 & c1) | ((c0|c1) & c2) | ((c0|c1|c2) & c3) | ((c0|c1|c2|c3) & c4)
// m3 = mask of 3 or 4 of a kind.
// m4 = mask of 4 of a kind.
*/
m1 = c[0] | c[1];
m2 = c[1] & c[0];
m3 = c[2] & m2;
m2 |= c[2] & m1;
m1 |= c[2];
m4 = c[3] & m3;
m3 |= c[3] & m2;
m2 |= c[3] & m1;
m1 |= c[3];
m4 |= c[4] & m3;
m3 |= c[4] & m2;
m2 |= c[4] & m1;
m1 |= c[4];
m4 |= c[5] & m3;
m3 |= c[5] & m2;
m2 |= c[5] & m1;
m1 |= c[5];
m4 |= c[6] & m3;
m3 |= c[6] & m2;
m2 |= c[6] & m1;
m1 |= c[6];
// Make sure the m1 is just the mask of singleton cards.
m1 &= ~m2;
// No 3 or 4 of a kinds.
if (m3 == 0) {
if (f) {
return SevenCardDrawFlushScore (f);
}
if (m2) {
s = m2 & (m2 - 1);
if (s == 0) {
t = m1 & (m1 - 1);
t &= (t - 1);
return TWO_KIND_SCORE + (m2 << SUBR_SHL) + t;
}
v = m1;
t = s & (s - 1);
if (t) {
v |= m2 ^ s;
m2 = s;
} else {
v &= (v - 1);
}
v &= (v - 1);
return TWO_PAIR_SCORE + (m2 << SUBR_SHL) + v;
}
// Nothing -- just remove the two low cards.
m1 &= (m1 - 1);
m1 &= (m1 - 1);
return m1;
}
// 4 of a kind.
if (m4) {
m1 |= (m2 & ~m4);
while ((m2 = (m1 & (m1 - 1))) != 0) {
m1 = m2;
}
return FOUR_KIND_SCORE + (m4 << SUBR_SHL) + m1;
}
// 3 of a kind, but no other pair in the hand
if ((m2 & ~m3) == 0) {
t = m3 & (m3 - 1);
// Two 3 of a kinds => Full House
if (t)
return FULL_HOUSE_SCORE + (t << SUBR_SHL) + (m3 ^ t);
if (f)
return SevenCardDrawFlushScore (f);
// Just remove the two low cards, and score this as 3 of a kind.
m1 &= (m1 - 1);
m1 &= (m1 - 1);
return THREE_KIND_SCORE + (m3 << SUBR_SHL) + m1;
}
// 3 of a kind and a seperate 2 of a kind (full house.)
m2 &= ~m3;
t = m2 & (m2 - 1);
// If there are two 2 pairs in the hand, then pick the higher pair
if (!t) t = m2;
return FULL_HOUSE_SCORE + (m3 << SUBR_SHL) + t;
}
// Just a brute force 7 card draw ranking by picking each of the possible two cards to be skipped, and finding the score which is highest amongst the 21 possible 5 card sub-hands.
u32 SevenCardDrawScoreSlow (const u8 * h) {
s32 i, j, k;
u32 r, m;
u8 h2[5];
m = 0;
for (i=0; i < 6; i++) {
for (k=0; k < i; k++) {
h2[k] = h[k];
}
for (j=i+1; j < 7; j++) {
for (k=i+1; k < j; k++) {
h2[k-1] = h[k];
}
for (k=j+1; k < 7; k++) {
h2[k-2] = h[k];
}
r = FiveCardDrawScore (h2);
if (r > m) m = r;
}
}
return m;
}
// A correctly distributed (ignoring the problem of using "rand() % x") reshuffling of your cards.
static void Shuffle (CardPileType * c)
{
int32_t i, j, k; u8 t;
for (i = 0; i < (c->len - 1); i++)
{
k = (RAND_MAX / (c->len - i)) * (c->len - i);
do {
j = rand ();
} while (j >= k);
j = i + (j % (c->len - i));
t = c->entry[i];
c->entry[i] = c->entry[j];
c->entry[j] = t;
}
}
static int32_t Deal (CardPileType * h, CardPileType * d, int32_t n)
{
int32_t i;
for (i=0; i < n && d->len > 0; i++)
{
d->len--;
h->entry[ h->len ] = d->entry[ d->len ];
h->len++;
}
return i;
}
static void InitDeck (CardPileType * deck)
{
u8 i;
deck->len = 52;
for (i=0; i < 52; i++) deck->entry[i] = i;
}
static void DisplayCard (u8 c, char out[])
{
// char suitdisp[9] = { 0, 5, 4, 0, 3, 0, 0, 0, 6 };
static char suitdisp[9] = { 0, 'c', 'd', 0, 'h', 0, 0, 0, 's' };
char s[4];
s[0] = " 1 "[CardValue[c]];
s[1] = "234567890JQKA"[CardValue[c]];
s[2] = suitdisp[CardSuit[c]];
s[3] = '\0';
strcat (out, " ");
strcat (out, s);
}
void DisplayHand5 (const CardPileType * h) {
char out[128];
int i;
out[0] = '\0';
for (i=0; i < 5; i++) DisplayCard (h->entry[i], out);
sprintf (out + strlen (out), " => %08X\n", (int)FiveCardDrawScore (&h->entry[0]));
printf ("%s", out);
}
void set_cardstr(char *cardstr,uint32_t c)
{
/*static char suitdisp[9] = { 0, 'c', 'd', 0, 'h', 0, 0, 0, 's' };
cardstr[0] = " 1 "[CardValue[c % 13]];
cardstr[1] = "234567890JQKA"[CardValue[c % 13]];
cardstr[2] = suitdisp[CardSuit[c]];
cardstr[3] = '\0';*/
int32_t i,j=0;
c >>= 1;
for (i=12; i>=0; i--)
if ( ((1 << i) & c) != 0 )
{
cardstr[j++] = " 1 "[i];
cardstr[j++] = "234567890JQKA"[i];
cardstr[j++] = ' ';
}
cardstr[j++] = 0;
}
uint32_t set_handstr(char *handstr,uint8_t cards[7],int32_t verbose)
{
char cardstr[32],cardstr2[32],*kickerstr,*str; uint32_t score,i;
handstr[0] = 0;
if ( cards == 0 )
{
handstr[0] = 0;
printf("set_handstr: null cards??\n");
return(0);
}
for (i=0; i<7; i++)
if ( cards[i] < 0 || cards[i] >= 52 )
{
//printf("illegal card[%d] %d\n",i,cards[i]);
return(0);
}
score = SevenCardDrawScore (&cards[0]);
set_cardstr(cardstr,(score>>SUBR_SHL) & SUBR_SHLMASK);
set_cardstr(cardstr2,score & SUBR_SHLMASK);
kickerstr = kickerstrs[(score>>RANK_SHL)&15];
str = handstrs[(score>>RANK_SHL)&15];
if ( verbose != 0 )
{
if ( strcmp(kickerstr,"high") == 0 )
sprintf(handstr,"%c%c high %s",cardstr2[0],cardstr2[1],str);
else if ( strcmp(str,"full house") == 0 )
sprintf(handstr,"%c%c full of %c%c",cardstr[0],cardstr[1],cardstr2[0],cardstr2[1]);
else if ( strcmp(str,"three of a kind") == 0 )
sprintf(handstr,"set of %c%c with kickers %c%c %c%c",cardstr[0],cardstr[1],cardstr2[0],cardstr2[1],cardstr2[3],cardstr2[4]);
else if ( strcmp(str,"two pair") == 0 )
sprintf(handstr,"two pair %c%c and %c%c with %c%c kicker",cardstr[0],cardstr[1],cardstr[3],cardstr[4],cardstr2[0],cardstr2[1]);
else if ( strcmp(str,"one pair") == 0 )
sprintf(handstr,"pair of %c%c with %c%c kicker",cardstr[0],cardstr[1],cardstr2[0],cardstr2[1]);
else sprintf(handstr,"%s %s %s %s",str,cardstr,kickerstr,cardstr2);
}
else
{
if ( strcmp(kickerstr,"high") == 0 )
sprintf(handstr,"%c%c high %s",cardstr2[0],cardstr2[1],str);
else if ( strcmp(str,"full house") == 0 )
sprintf(handstr,"fullhouse %c%c %c%c",cardstr[0],cardstr[1],cardstr2[0],cardstr2[1]);
else if ( strcmp(str,"three of a kind") == 0 )
sprintf(handstr,"trip %c%c",cardstr[0],cardstr[1]);
else if ( strcmp(str,"two pair") == 0 )
sprintf(handstr,"two pairs %c%c %c%c",cardstr[0],cardstr[1],cardstr[3],cardstr[4]);
else if ( strcmp(str,"one pair") == 0 )
sprintf(handstr,"pair %c%c",cardstr[0],cardstr[1]);
else sprintf(handstr,"%s",cardstr2);
}
return(score);
}
void DisplayHand7(char *handstr,uint8_t *cards)
{
uint32_t x,y; int32_t i; char out[512];
out[0] = '\0';
for (i=0; i<7; i++)
DisplayCard (cards[i], out);
x = SevenCardDrawScore (cards);
y = SevenCardDrawScoreSlow (cards);
set_handstr(handstr,cards,1);
if ( x != y )
fprintf(stderr,"Error slow score %08x vs fast score %08x???\n",y,x);
sprintf (out + strlen (out), " => %08x %6d %6d -> (%s)",x,(x>>SUBR_SHL)&SUBR_SHLMASK,x&SUBR_SHLMASK,handstr);
printf("%s\n",out);
}
void poker_test()
{
char *_mbstr(double n);
CardPileType Deck,Hands[1000]; uint32_t c,starttime,score; uint64_t total,counter; char handstr[512]; uint8_t *cards;
//srand (0);
InitDeck (&Deck);
Shuffle (&Deck);
for (c=0; c<(sizeof(Hands)/sizeof(*Hands)); c++)
{
Deal (&Hands[c],&Deck,7);
DisplayHand7(handstr,Hands[c].entry);
Deal (&Deck,&Hands[c],7);
Shuffle(&Deck);
}
starttime = (uint32_t)time(NULL);
#ifndef _WIN32
while ( (uint32_t)time(NULL) == starttime )
usleep(100);
total = counter = 0;
while ( (uint32_t)time(NULL) < starttime+11 )
{
for (c=0; c<1000; c++,counter++)
{
cards = Hands[c % (sizeof(Hands)/sizeof(*Hands))].entry;
score = SevenCardDrawScore(cards);
total += score;
}
}
char *mbstr(char *str,double val);
char str[65]; printf("counter.%llu %s in 10 seconds: ave score %llx\n",(long long)counter,mbstr(str,counter),(long long)(total/counter));
#endif
}

2
iguana/ramchain_api.c

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *

2
includes/iguana_api.h

@ -18,7 +18,7 @@
#include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h"
#undef IGUANA_ARGS
//#undef IGUANA_ARGS
#include "../includes/iguana_apiundefs.h"

52
includes/iguana_apideclares.h

@ -1,5 +1,5 @@
/******************************************************************************
* Copyright © 2014-2015 The SuperNET Developers. *
* 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 *
@ -13,17 +13,61 @@
* *
******************************************************************************/
ZERO_ARGS(SuperNET,saveconf);
ZERO_ARGS(SuperNET,help);
TWO_STRINGS(SuperNET,html,agentform,htmlfile);
STRING_ARG(SuperNET,bitcoinrpc,setcoin);
TWOSTRINGS_AND_HASH_AND_TWOINTS(SuperNET,DHT,message,destip,destpub,maxdelay,broadcast);
TWOSTRINGS_AND_HASH_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,destpub,maxdelay,broadcast);
THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey);
ZERO_ARGS(SuperNET,keypair);
HASH_ARG(SuperNET,priv2pub,privkey);
TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message);
TWOHASHES_AND_STRING(SuperNET,decipher,privkey,srcpubkey,cipherstr);
STRING_ARG(SuperNET,broadcastcipher,message);
STRING_ARG(SuperNET,broadcastdecipher,message);
HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message);
HASH_AND_STRING(SuperNET,multicastdecipher,privkey,cipherstr);
ZERO_ARGS(SuperNET,keypair);
HASH_ARG(SuperNET,priv2pub,privkey);
THREE_STRINGS(SuperNET,announce,category,subcategory,message);
THREE_STRINGS(SuperNET,survey,category,subcategory,message);
STRING_ARG(SuperNET,getpeers,activecoin);
TWO_ARRAYS(SuperNET,mypeers,supernet,rawpeers);
ZERO_ARGS(SuperNET,stop);
HASH_AND_STRING(SuperNET,sharepersistent,persistentpub,destip);
HASH_AND_STRING(SuperNET,saveconf,wallethash,confjsonstr);
HASH_ARRAY_STRING(SuperNET,layer,mypriv,otherpubs,str);
INT_AND_ARRAY(pangea,newhand,senderind,args);
INT_AND_ARRAY(pangea,ping,senderind,args);
INT_AND_ARRAY(pangea,gotdeck,senderind,args);
INT_AND_ARRAY(pangea,ready,senderind,args);
INT_AND_ARRAY(pangea,encoded,senderind,args);
INT_AND_ARRAY(pangea,final,senderind,args);
INT_AND_ARRAY(pangea,addedfunds,senderind,args);
INT_AND_ARRAY(pangea,preflop,senderind,args);
INT_AND_ARRAY(pangea,decoded,senderind,args);
INT_AND_ARRAY(pangea,card,senderind,args);
INT_AND_ARRAY(pangea,facedown,senderind,args);
INT_AND_ARRAY(pangea,faceup,senderind,args);
INT_AND_ARRAY(pangea,turn,senderind,args);
INT_AND_ARRAY(pangea,confirmturn,senderind,args);
INT_AND_ARRAY(pangea,chat,senderind,args);
INT_AND_ARRAY(pangea,action,senderind,args);
INT_AND_ARRAY(pangea,showdown,senderind,args);
INT_AND_ARRAY(pangea,handsummary,senderind,args);
//U64_AND_ARRAY(pangea,turn,tableid,args);
U64_AND_ARRAY(pangea,status,tableid,args);
U64_AND_ARRAY(pangea,mode,tableid,args);
U64_AND_ARRAY(pangea,buyin,tableid,args);
U64_AND_ARRAY(pangea,history,tableid,args);
STRING_ARG(iguana,peers,activecoin);
STRING_AND_INT(iguana,maxpeers,activecoin,max);
STRING_ARG(iguana,getconnectioncount,activecoin);

8
includes/iguana_apidefs.h

@ -1,4 +1,5 @@
#define IGUANA_CALLARGS myinfo,coin,json,remoteaddr
#define IGUANA_ARGS struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr
#define IGUANA_CFUNC0(agent,name) char *agent ## _ ## name(IGUANA_ARGS)
#define IGUANA_CFUNC_S(agent,name,str) char *agent ## _ ## name(IGUANA_ARGS,char *str)
@ -6,6 +7,10 @@
#define IGUANA_CFUNC_SA(agent,name,str,array) char *agent ## _ ## name(IGUANA_ARGS,char *str,cJSON *array)
#define IGUANA_CFUNC_AA(agent,name,array,array2) char *agent ## _ ## name(IGUANA_ARGS,cJSON *array,cJSON *array2)
#define IGUANA_CFUNC_SAA(agent,name,str,array,array2) char *agent ## _ ## name(IGUANA_ARGS,char *str,cJSON *array,cJSON *array2)
#define IGUANA_CFUNC_64A(agent,name,j64,array) char *agent ## _ ## name(IGUANA_ARGS,uint64_t j64,cJSON *array)
#define IGUANA_CFUNC_IA(agent,name,val,array) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,cJSON *array)
#define IGUANA_CFUNC_IAS(agent,name,val,array,str) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,cJSON *array,char *str)
#define IGUANA_CFUNC_II(agent,name,val,val2) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,int32_t val2)
@ -21,6 +26,7 @@
#define IGUANA_CFUNC_SI(agent,name,str,val) char *agent ## _ ## name(IGUANA_ARGS,char *str,int32_t val)
#define IGUANA_CFUNC_SII(agent,name,str,val,val2) char *agent ## _ ## name(IGUANA_ARGS,char *str,int32_t val,int32_t val2)
#define IGUANA_CFUNC_HI(agent,name,hash,val) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,int32_t val)
#define IGUANA_CFUNC_H(agent,name,hash) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash)
#define IGUANA_CFUNC_HS(agent,name,hash,str) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,char *str)
#define IGUANA_CFUNC_HHS(agent,name,hash,hash2,str) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,bits256 hash2,char *str)
#define IGUANA_CFUNC_HAS(agent,name,hash,array,str) char *agent ## _ ## name(IGUANA_ARGS,bits256 hash,cJSON *array,char *str)
@ -61,3 +67,5 @@
#define TWOSTRINGS_AND_HASH_AND_TWOINTS IGUANA_CFUNC_SSHII
#define THREE_INTS IGUANA_CFUNC_III
#define HASH_ARRAY_STRING IGUANA_CFUNC_HAS
#define U64_AND_ARRAY IGUANA_CFUNC_64A
#define HASH_ARG IGUANA_CFUNC_H

6
includes/iguana_apiundefs.h

@ -28,3 +28,9 @@
#undef TWOSTRINGS_AND_HASH_AND_TWOINTS
#undef TWOHASHES_AND_STRING
#undef HASH_ARRAY_STRING
#undef U64_AND_ARRAY
#undef HASH_ARG
#undef IGUANA_ARGS
#undef IGUANA_CALLARGS

3
includes/tweetnacl.h

@ -22,6 +22,7 @@ extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const un
#define crypto_box crypto_box_curve25519xsalsa20poly1305
#define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open
#define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair
#define crypto_box_priv2pub crypto_box_curve25519xsalsa20poly1305_priv2pub
#define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm
#define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm
#define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm
@ -42,6 +43,7 @@ extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const un
extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *);
extern int crypto_box_curve25519xsalsa20poly1305_tweet_priv2pub(unsigned char *,unsigned char *);
extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *);
extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
@ -49,6 +51,7 @@ extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned cha
#define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet
#define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open
#define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair
#define crypto_box_curve25519xsalsa20poly1305_priv2pub crypto_box_curve25519xsalsa20poly1305_tweet_priv2pub
#define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm
#define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm
#define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm

Loading…
Cancel
Save