Browse Source

Address utxo

etomic
jl777 7 years ago
parent
commit
728570e8f9
  1. 26
      iguana/exchanges/LP_include.h
  2. 28
      iguana/exchanges/LP_nativeDEX.c
  3. 64
      iguana/exchanges/LP_prices.c
  4. 24
      iguana/exchanges/LP_scan.c
  5. 54
      iguana/exchanges/LP_socket.c
  6. 5
      iguana/exchanges/LP_utxos.c

26
iguana/exchanges/LP_include.h

@ -176,20 +176,13 @@ struct LP_transaction
struct LP_outpoint outpoints[]; struct LP_outpoint outpoints[];
}; };
struct LP_address
{
UT_hash_handle hh;
int64_t balance;
char coinaddr[40];
};
struct iguana_info struct iguana_info
{ {
UT_hash_handle hh; UT_hash_handle hh;
portable_mutex_t txmutex; struct LP_transaction *transactions; struct LP_address *addresses; portable_mutex_t txmutex; struct LP_transaction *transactions; struct LP_address *addresses;
uint64_t txfee; uint64_t txfee;
int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport; int32_t longestchain,firstrefht,firstscanht,lastscanht,bussock,height; uint16_t busport;
uint32_t counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime; uint32_t counter,inactive,lastmempool,lastgetinfo,ratetime,heighttime,lastmonitor;
uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag; uint8_t pubtype,p2shtype,isPoS,wiftype,wiftaddr,taddr,noimportprivkey_flag;
char symbol[16],smartaddr[64],userpass[1024],serverport[128]; char symbol[16],smartaddr[64],userpass[1024],serverport[128];
// portfolio // portfolio
@ -223,6 +216,22 @@ struct LP_utxoinfo
char coin[16],coinaddr[64],spendscript[256],gui[16]; char coin[16],coinaddr[64],spendscript[256],gui[16];
}; };
struct LP_address_utxo
{
struct LP_address_utxo *next,*prev;
struct _LP_utxoinfo U;
uint32_t height,SPV,spentflag;
};
struct LP_address
{
UT_hash_handle hh;
struct LP_address_utxo *utxos;
int64_t balance;
uint32_t monitor;
char coinaddr[40];
};
struct LP_peerinfo struct LP_peerinfo
{ {
UT_hash_handle hh; UT_hash_handle hh;
@ -287,6 +296,7 @@ struct iguana_info *LP_coinfind(char *symbol);
int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32); int32_t LP_crc32find(int32_t *duplicatep,int32_t ind,uint32_t crc32);
char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price); char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *rel,double price);
uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee); uint64_t LP_txfeecalc(struct iguana_info *coin,uint64_t txfee);
struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr);
#endif #endif

28
iguana/exchanges/LP_nativeDEX.c

@ -23,9 +23,7 @@
// bittrex balancing // bittrex balancing
// detect port conflicts on enable // detect port conflicts on enable
// stats // stats
// PoW, JS // dynamic txid2 allocation
// verify actual pricing
// autoutxo, if < 10*txfee and > 10 utxo: combine smallest utxo into dexfee; autosplit if imbalanced
// unduplicated bugs: // unduplicated bugs:
// swap cancel should cleanly cancel // swap cancel should cleanly cancel
@ -421,10 +419,30 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int
} }
HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht
{ {
int32_t height; bits256 zero; int32_t height; bits256 zero; struct LP_address *ap,*atmp; struct LP_address_utxo *up;
//printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); //printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain);
if ( coin->inactive != 0 ) if ( coin->inactive != 0 || coin->electrum != 0 )
continue; continue;
if ( time(NULL) > coin->lastmonitor+60 )
{
portable_mutex_lock(&coin->txmutex);
HASH_ITER(hh,coin->addresses,ap,atmp)
{
if ( ap->monitor != 0 )
{
DL_FOREACH(ap->utxos,up)
{
if ( up->spentflag == 0 )
{
if ( LP_txvalue(0,coin->symbol,up->U.txid,up->U.vout) == 0 )
up->spentflag = (uint32_t)time(NULL);
}
}
}
}
portable_mutex_unlock(&coin->txmutex);
coin->lastmonitor = (uint32_t)time(NULL);
}
memset(zero.bytes,0,sizeof(zero)); memset(zero.bytes,0,sizeof(zero));
if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR ) if ( time(NULL) > coin->lastgetinfo+LP_GETINFO_INCR )
{ {

64
iguana/exchanges/LP_prices.c

@ -55,6 +55,69 @@ struct LP_pubkeyinfo
uint8_t rmd160[20]; uint8_t rmd160[20];
} *LP_pubkeyinfos; } *LP_pubkeyinfos;
struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr)
{
struct LP_address *ap;
HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap);
return(ap);
}
struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr)
{
struct LP_address *ap;
ap = calloc(1,sizeof(*ap));
safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr));
HASH_ADD_KEYPTR(hh,coin->addresses,ap->coinaddr,strlen(ap->coinaddr),ap);
return(ap);
}
struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr)
{
struct LP_address *ap;
if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 )
ap = _LP_addressadd(coin,coinaddr);
return(ap);
}
void LP_address_utxoadd(struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value)
{
struct LP_address *ap; struct LP_address_utxo *up;
portable_mutex_lock(&coin->txmutex);
if ( (ap= _LP_address(coin,coinaddr)) != 0 )
{
up = calloc(1,sizeof(*up));
up->U.txid = txid;
up->U.vout = vout;
up->U.value = value;
DL_APPEND(ap->utxos,up);
}
portable_mutex_unlock(&coin->txmutex);
}
void LP_address_monitor(struct LP_pubkeyinfo *pubp)
{
struct iguana_info *coin,*tmp; char coinaddr[64]; cJSON *retjson; struct LP_address *ap;
HASH_ITER(hh,LP_coins,coin,tmp)
{
bitcoin_address(coinaddr,coin->taddr,coin->pubtype,pubp->rmd160,sizeof(pubp->rmd160));
portable_mutex_lock(&coin->txmutex);
if ( (ap= _LP_address(coin,coinaddr)) != 0 )
{
ap->monitor = (uint32_t)time(NULL);
}
portable_mutex_unlock(&coin->txmutex);
if ( coin->electrum != 0 )
{
if ( (retjson= electrum_address_subscribe(coin->symbol,coin->electrum,0,coinaddr)) != 0 )
{
printf("%s MONITOR.(%s)\n",coin->symbol,coinaddr);
free_json(retjson);
}
}
}
}
int32_t LP_pricevalid(double price) int32_t LP_pricevalid(double price)
{ {
if ( price > SMALLVAL && isnan(price) == 0 && price < SATOSHIDEN ) if ( price > SMALLVAL && isnan(price) == 0 && price < SATOSHIDEN )
@ -229,6 +292,7 @@ void LP_prices_parse(cJSON *obj)
printf("%02x",pubp->rmd160[i]); printf("%02x",pubp->rmd160[i]);
char str[65]; printf(" -> rmd160.(%s) for %s\n",hexstr,bits256_str(str,pubkey)); char str[65]; printf(" -> rmd160.(%s) for %s\n",hexstr,bits256_str(str,pubkey));
memcpy(pubp->rmd160,rmd160,sizeof(pubp->rmd160)); memcpy(pubp->rmd160,rmd160,sizeof(pubp->rmd160));
LP_address_monitor(pubp);
} }
} }
if ( (timestamp= juint(obj,"timestamp")) > pubp->timestamp && (asks= jarray(&n,obj,"asks")) != 0 ) if ( (timestamp= juint(obj,"timestamp")) > pubp->timestamp && (asks= jarray(&n,obj,"asks")) != 0 )

24
iguana/exchanges/LP_scan.c

@ -19,30 +19,6 @@
// //
struct LP_address *_LP_addressfind(struct iguana_info *coin,char *coinaddr)
{
struct LP_address *ap;
HASH_FIND(hh,coin->addresses,coinaddr,strlen(coinaddr),ap);
return(ap);
}
struct LP_address *_LP_addressadd(struct iguana_info *coin,char *coinaddr)
{
struct LP_address *ap;
ap = calloc(1,sizeof(*ap));
safecopy(ap->coinaddr,coinaddr,sizeof(ap->coinaddr));
HASH_ADD_KEYPTR(hh,coin->addresses,ap->coinaddr,strlen(ap->coinaddr),ap);
return(ap);
}
struct LP_address *_LP_address(struct iguana_info *coin,char *coinaddr)
{
struct LP_address *ap;
if ( (ap= _LP_addressfind(coin,coinaddr)) == 0 )
ap = _LP_addressadd(coin,coinaddr);
return(ap);
}
struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid) struct LP_transaction *LP_transactionfind(struct iguana_info *coin,bits256 txid)
{ {
struct LP_transaction *tx; struct LP_transaction *tx;

54
iguana/exchanges/LP_socket.c

@ -321,6 +321,7 @@ cJSON *electrum_submit(char *symbol,struct electrum_info *ep,cJSON **retjsonp,ch
sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params); sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",ep->stratumid,method,params);
ep->buf[0] = 0; ep->buf[0] = 0;
sitem = (struct stritem *)queueitem(stratumreq); sitem = (struct stritem *)queueitem(stratumreq);
sitem->expiration = timeout;
sitem->DL.type = ep->stratumid++; sitem->DL.type = ep->stratumid++;
if ( retjsonp != 0 ) if ( retjsonp != 0 )
sitem->retptrp = (void **)retjsonp; sitem->retptrp = (void **)retjsonp;
@ -541,25 +542,33 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len)
} }
} }
idnum = juint(strjson,"id"); idnum = juint(strjson,"id");
//if ( 0 ) // crashes cipi's node //if ( 0 ) // crashes cipi's node likely due to mutex across threads
{ {
portable_mutex_lock(&ep->pendingQ.mutex); portable_mutex_lock(&ep->pendingQ.mutex);
if ( ep->pendingQ.list != 0 ) if ( ep->pendingQ.list != 0 )
{ {
DL_FOREACH(ep->pendingQ.list,item) DL_FOREACH(ep->pendingQ.list,item)
{ {
printf("idnum.%d\n",item->type); if ( item->type == 0xffffffff )
continue;
stritem = (struct stritem *)item; stritem = (struct stritem *)item;
if ( item->type == idnum ) if ( item->type == idnum )
{ {
printf("matched idnum.%d\n",idnum); printf("matched idnum.%d\n",idnum);
DL_DELETE(ep->pendingQ.list,item); item->type = 0xffffffff;
if ( stritem->retptrp != 0 )
{
*((cJSON **)stritem->retptrp) = strjson;
strjson = 0;
}
//DL_DELETE(ep->pendingQ.list,item);
break; break;
} }
if ( 0 && stritem->expiration < ep->lasttime ) if ( stritem->expiration < ep->lasttime )
{ {
printf("expired (%s)\n",stritem->str); printf("expired (%s)\n",stritem->str);
DL_DELETE(ep->pendingQ.list,item); item->type = 0xffffffff;
//DL_DELETE(ep->pendingQ.list,item);
if ( stritem->retptrp != 0 ) if ( stritem->retptrp != 0 )
{ {
errjson = cJSON_CreateObject(); errjson = cJSON_CreateObject();
@ -568,23 +577,10 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len)
*((cJSON **)stritem->retptrp) = errjson; *((cJSON **)stritem->retptrp) = errjson;
}; };
} }
item = 0;
} }
} }
portable_mutex_unlock(&ep->pendingQ.mutex); portable_mutex_unlock(&ep->pendingQ.mutex);
} }
if ( item != 0 )
{
// do callback
stritem = (struct stritem *)item;
//printf("callback.%p (%s) -> (%s)\n",strjson,stritem->str,jprint(strjson,0));
if ( stritem->retptrp != 0 )
{
*((cJSON **)stritem->retptrp) = strjson;
strjson = 0;
}
free(item);
}
if ( strjson != 0 ) if ( strjson != 0 )
free_json(strjson); free_json(strjson);
} }
@ -593,7 +589,7 @@ int32_t LP_recvfunc(struct electrum_info *ep,char *str,int32_t len)
void LP_dedicatedloop(void *arg) void LP_dedicatedloop(void *arg)
{ {
struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson; struct stritem *sitem; struct electrum_info *ep = arg; struct pollfd fds; int32_t i,len,flag,timeout = 10; struct iguana_info *coin; cJSON *retjson; struct stritem *sitem; struct queueitem *item = 0; struct electrum_info *ep = arg;
if ( (coin= LP_coinfind(ep->symbol)) != 0 ) if ( (coin= LP_coinfind(ep->symbol)) != 0 )
ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime; ep->heightp = &coin->height, ep->heighttimep = &coin->heighttime;
if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,0)) != 0 ) if ( (retjson= electrum_headers_subscribe(ep->symbol,ep,0)) != 0 )
@ -615,8 +611,26 @@ void LP_dedicatedloop(void *arg)
ep->sock = -1; ep->sock = -1;
break; break;
} }
if ( sitem->expiration != 0 )
sitem->expiration += (uint32_t)time(NULL);
else sitem->expiration = (uint32_t)time(NULL) + ELECTRUM_TIMEOUT;
//printf("SEND.(%s) to %s:%u\n",sitem->str,ep->ipaddr,ep->port); //printf("SEND.(%s) to %s:%u\n",sitem->str,ep->ipaddr,ep->port);
queue_enqueue("pendingQ",&ep->pendingQ,(struct queueitem *)sitem); //queue_enqueue("pendingQ",&ep->pendingQ,(struct queueitem *)sitem);
portable_mutex_lock(&ep->pendingQ.mutex);
if ( ep->pendingQ.list != 0 )
{
DL_FOREACH(ep->pendingQ.list,item)
{
if ( item->type == 0xffffffff )
{
printf("purge %s\n",((struct stritem *)item)->str);
DL_DELETE(ep->pendingQ.list,item);
free(item);
}
}
}
DL_APPEND(ep->pendingQ.list,&sitem->DL);
portable_mutex_unlock(&ep->pendingQ.mutex);
flag++; flag++;
} }
if ( flag == 0 ) if ( flag == 0 )

5
iguana/exchanges/LP_utxos.c

@ -642,6 +642,11 @@ struct LP_utxoinfo *LP_utxoadd(int32_t iambob,int32_t mypubsock,char *symbol,bit
if ( _LP_utxo2find(iambob,txid2,vout2) == 0 ) if ( _LP_utxo2find(iambob,txid2,vout2) == 0 )
HASH_ADD_KEYPTR(hh2,LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo); HASH_ADD_KEYPTR(hh2,LP_utxoinfos2[iambob],utxo->key2,sizeof(utxo->key2),utxo);
portable_mutex_unlock(&LP_utxomutex); portable_mutex_unlock(&LP_utxomutex);
if ( coin->electrum == 0 )
{
LP_address_utxoadd(coin,coinaddr,txid,vout,value);
LP_address_utxoadd(coin,coinaddr,txid2,vout2,value2);
}
if ( iambob != 0 ) if ( iambob != 0 )
{ {
if ( LP_mypeer != 0 ) if ( LP_mypeer != 0 )

Loading…
Cancel
Save