@ -18,6 +18,35 @@
// LP_ordermatch.c
// LP_ordermatch.c
// marketmaker
// marketmaker
//
//
struct LP_quoteinfo LP_Alicequery ;
double LP_Alicemaxprice ;
uint32_t Alice_expiration ;
struct { uint64_t aliceid ; double bestprice ; } Bob_competition [ 512 ] ;
double LP_bob_competition ( uint64_t aliceid , double price )
{
int32_t i , firsti = - 1 ;
for ( i = 0 ; i < sizeof ( Bob_competition ) / sizeof ( * Bob_competition ) ; i + + )
{
if ( Bob_competition [ i ] . aliceid = = aliceid )
{
if ( price ! = 0. & & ( Bob_competition [ i ] . bestprice = = 0. | | price < Bob_competition [ i ] . bestprice ) )
{
Bob_competition [ i ] . bestprice = price ;
//printf("Bob competition aliceid.%llx <- bestprice %.8f\n",(long long)aliceid,price);
}
return ( Bob_competition [ i ] . bestprice ) ;
}
else if ( Bob_competition [ i ] . aliceid = = 0 )
firsti = i ;
}
if ( firsti < 0 )
firsti = ( rand ( ) % ( sizeof ( Bob_competition ) / sizeof ( * Bob_competition ) ) ) ;
Bob_competition [ firsti ] . aliceid = aliceid ;
Bob_competition [ firsti ] . bestprice = price ;
//printf("Bob competition aliceid.%llx %.8f\n",(long long)aliceid,price);
return ( price ) ;
}
uint64_t LP_txfeecalc ( struct iguana_info * coin , uint64_t txfee , int32_t txlen )
uint64_t LP_txfeecalc ( struct iguana_info * coin , uint64_t txfee , int32_t txlen )
{
{
@ -83,7 +112,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
{
{
if ( LP_iseligible ( & srcvalue , & srcvalue2 , 1 , qp - > srccoin , qp - > txid , qp - > vout , qp - > satoshis , qp - > txid2 , qp - > vout2 ) = = 0 )
if ( LP_iseligible ( & srcvalue , & srcvalue2 , 1 , qp - > srccoin , qp - > txid , qp - > vout , qp - > satoshis , qp - > txid2 , qp - > vout2 ) = = 0 )
{
{
printf ( " bob not eligible %s \n " , jprint ( LP_quotejson ( qp ) , 1 ) ) ;
printf ( " bob not eligible %s (%.8f %.8f) \n " , jprint ( LP_quotejson ( qp ) , 1 ) , dstr ( srcvalue ) , dstr ( srcvalue2 ) ) ;
return ( - 2 ) ;
return ( - 2 ) ;
}
}
if ( ( txout = LP_gettxout ( qp - > srccoin , qp - > coinaddr , qp - > txid , qp - > vout ) ) ! = 0 )
if ( ( txout = LP_gettxout ( qp - > srccoin , qp - > coinaddr , qp - > txid , qp - > vout ) ) ! = 0 )
@ -115,7 +144,7 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
{
{
if ( LP_iseligible ( & destvalue , & destvalue2 , 0 , qp - > destcoin , qp - > desttxid , qp - > destvout , qp - > destsatoshis , qp - > feetxid , qp - > feevout ) = = 0 )
if ( LP_iseligible ( & destvalue , & destvalue2 , 0 , qp - > destcoin , qp - > desttxid , qp - > destvout , qp - > destsatoshis , qp - > feetxid , qp - > feevout ) = = 0 )
{
{
char str [ 65 ] ; printf ( " alice not eligible (%.8f %.8f) %s/v%d \n " , dstr ( destvalue ) , dstr ( destvalue2 ) , bits256_str ( str , qp - > feetxid ) , qp - > feevout ) ;
char str [ 65 ] , str2 [ 65 ] ; printf ( " alice not eligible %.8f -> dest %.8f %.8f (%.8f %.8f) %s/v%d %s/v%d \n " , dstr ( qp - > satoshis ) , dstr ( qp - > destsatoshis ) , ( double ) qp - > destsatoshis / qp - > satoshis , dstr ( destvalue ) , dstr ( destvalue2 ) , bits256_str ( str , qp - > desttxid ) , qp - > destvout , bits256_str ( str2 , qp - > feetxid ) , qp - > feevout ) ;
return ( - 3 ) ;
return ( - 3 ) ;
}
}
if ( ( txout = LP_gettxout ( qp - > destcoin , qp - > destaddr , qp - > desttxid , qp - > destvout ) ) ! = 0 )
if ( ( txout = LP_gettxout ( qp - > destcoin , qp - > destaddr , qp - > desttxid , qp - > destvout ) ) ! = 0 )
@ -146,12 +175,12 @@ double LP_quote_validate(struct LP_utxoinfo *autxo,struct LP_utxoinfo *butxo,str
if ( strcmp ( autxo - > coinaddr , qp - > destaddr ) ! = 0 )
if ( strcmp ( autxo - > coinaddr , qp - > destaddr ) ! = 0 )
return ( - 10 ) ;
return ( - 10 ) ;
}
}
if ( autxo ! = 0 & & destvalue < 2 * qp - > desttxfee + qp - > destsatoshis )
if ( autxo ! = 0 & & destvalue < qp - > desttxfee + qp - > destsatoshis )
{
{
printf ( " destvalue %.8f destsatoshis %.8f is too small txfee %.8f? \n " , dstr ( destvalue ) , dstr ( qp - > destsatoshis ) , dstr ( qp - > desttxfee ) ) ;
printf ( " destvalue %.8f destsatoshis %.8f is too small txfee %.8f? \n " , dstr ( destvalue ) , dstr ( qp - > destsatoshis ) , dstr ( qp - > desttxfee ) ) ;
return ( - 11 ) ;
return ( - 11 ) ;
}
}
if ( butxo ! = 0 & & srcvalue < 2 * qp - > txfee + qp - > satoshis )
if ( butxo ! = 0 & & srcvalue < qp - > txfee + qp - > satoshis )
{
{
printf ( " srcvalue %.8f [%.8f] satoshis %.8f is too small txfee %.8f? \n " , dstr ( srcvalue ) , dstr ( srcvalue ) - dstr ( qp - > txfee + qp - > satoshis ) , dstr ( qp - > satoshis ) , dstr ( qp - > txfee ) ) ;
printf ( " srcvalue %.8f [%.8f] satoshis %.8f is too small txfee %.8f? \n " , dstr ( srcvalue ) , dstr ( srcvalue ) - dstr ( qp - > txfee + qp - > satoshis ) , dstr ( qp - > satoshis ) , dstr ( qp - > txfee ) ) ;
return ( - 33 ) ;
return ( - 33 ) ;
@ -246,7 +275,7 @@ int32_t LP_nearest_utxovalue(struct iguana_info *coin,char *coinaddr,struct LP_a
//printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight);
//printf("nearest i.%d target %.8f val %.8f dist %.8f mindist %.8f mini.%d spent.%d\n",i,dstr(targetval),dstr(up->U.value),dstr(dist),dstr(mindist),mini,up->spendheight);
if ( up - > spendheight < = 0 )
if ( up - > spendheight < = 0 )
{
{
if ( ( coin - > electrum = = 0 | | up - > SPV > 0 ) & & dist > = 0 & & dist < mindist )
if ( dist > = 0 & & dist < mindist ) //(coin->electrum == 0 || up->SPV > 0) &&
{
{
//printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini);
//printf("(%.8f %.8f %.8f).%d ",dstr(up->U.value),dstr(dist),dstr(mindist),mini);
mini = i ;
mini = i ;
@ -269,12 +298,13 @@ uint64_t LP_basesatoshis(double relvolume,double price,uint64_t txfee,uint64_t d
struct LP_utxoinfo * LP_address_utxopair ( int32_t iambob , struct LP_address_utxo * * utxos , int32_t max , struct iguana_info * coin , char * coinaddr , uint64_t txfee , double relvolume , double price , uint64_t desttxfee )
struct LP_utxoinfo * LP_address_utxopair ( int32_t iambob , struct LP_address_utxo * * utxos , int32_t max , struct iguana_info * coin , char * coinaddr , uint64_t txfee , double relvolume , double price , uint64_t desttxfee )
{
{
struct LP_address * ap ; uint64_t targetval , targetval2 ; int32_t m , mini ; struct LP_address_utxo * up , * up2 ; struct LP_utxoinfo * utxo = 0 ;
struct LP_address * ap ; uint64_t targetval , targetval2 ; int32_t m , mini ; struct LP_address_utxo * up , * up2 ; struct LP_utxoinfo * utxo = 0 ; //,*utmp;
targetval = LP_basesatoshis ( relvolume , price , txfee , desttxfee ) ;
targetval2 = ( targetval / 8 ) * 9 + 2 * txfee ;
if ( coin ! = 0 & & ( ap = LP_addressfind ( coin , coinaddr ) ) ! = 0 )
if ( coin ! = 0 & & ( ap = LP_addressfind ( coin , coinaddr ) ) ! = 0 )
{
{
if ( ( m = LP_address_utxo_ptrs ( coin , iambob , utxos , max , ap , coinaddr ) ) > 1 )
if ( ( m = LP_address_utxo_ptrs ( coin , iambob , utxos , max , ap , coinaddr ) ) > 1 )
{
{
targetval = LP_basesatoshis ( relvolume , price , txfee , desttxfee ) ;
if ( 0 )
if ( 0 )
{
{
int32_t i ;
int32_t i ;
@ -287,7 +317,6 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
{
{
up = utxos [ mini ] ;
up = utxos [ mini ] ;
utxos [ mini ] = 0 ;
utxos [ mini ] = 0 ;
targetval2 = ( targetval / 8 ) * 9 + 2 * txfee ;
//printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval);
//printf("found mini.%d %.8f for targetval %.8f -> targetval2 %.8f, ratio %.2f\n",mini,dstr(up->U.value),dstr(targetval),dstr(targetval2),(double)up->U.value/targetval);
if ( ( double ) up - > U . value / targetval < LP_MINVOL - 1 )
if ( ( double ) up - > U . value / targetval < LP_MINVOL - 1 )
@ -296,7 +325,7 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
{
{
if ( up ! = 0 & & ( up2 = utxos [ mini ] ) ! = 0 )
if ( up ! = 0 & & ( up2 = utxos [ mini ] ) ! = 0 )
{
{
if ( ( utxo = LP_utxoadd ( 1 , coin - > symbol , up - > U . txid , up - > U . vout , up - > U . value , up2 - > U . txid , up2 - > U . vout , up2 - > U . value , coinaddr , ap - > pubkey , G . gui , 0 ) ) ! = 0 )
if ( ( utxo = LP_utxoadd ( 1 , coin - > symbol , up - > U . txid , up - > U . vout , up - > U . value , up2 - > U . txid , up2 - > U . vout , up2 - > U . value , coinaddr , ap - > pubkey , G . gui , 0 , targetval ) ) ! = 0 )
{
{
utxo - > S . satoshis = targetval ;
utxo - > S . satoshis = targetval ;
char str [ 65 ] , str2 [ 65 ] ; printf ( " butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s \n " , utxo , dstr ( targetval ) , dstr ( up - > U . value ) , bits256_str ( str , utxo - > payment . txid ) , dstr ( targetval2 ) , dstr ( up2 - > U . value ) , bits256_str ( str2 , utxo - > deposit . txid ) ) ;
char str [ 65 ] , str2 [ 65 ] ; printf ( " butxo.%p targetval %.8f, found val %.8f %s | targetval2 %.8f val2 %.8f %s \n " , utxo , dstr ( targetval ) , dstr ( up - > U . value ) , bits256_str ( str , utxo - > payment . txid ) , dstr ( targetval2 ) , dstr ( up2 - > U . value ) , bits256_str ( str2 , utxo - > deposit . txid ) ) ;
@ -309,6 +338,15 @@ struct LP_utxoinfo *LP_address_utxopair(int32_t iambob,struct LP_address_utxo **
printf ( " targetval %.8f mini.%d \n " , dstr ( targetval ) , mini ) ;
printf ( " targetval %.8f mini.%d \n " , dstr ( targetval ) , mini ) ;
} //else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr);
} //else printf("no %s utxos pass LP_address_utxo_ptrs filter\n",coinaddr);
} else printf ( " couldnt find %s %s \n " , coin - > symbol , coinaddr ) ;
} else printf ( " couldnt find %s %s \n " , coin - > symbol , coinaddr ) ;
/*HASH_ITER(hh,G.LP_utxoinfos[iambob],utxo,utmp)
{
if ( LP_isavailable ( utxo ) ! = 0 & & utxo - > payment . value > = targetval & & targetval > = utxo - > payment . value / 2 & & utxo - > deposit . value > = targetval2 )
{
utxo - > S . satoshis = targetval ;
printf ( " backup method found utxo! \n " ) ;
return ( utxo ) ;
}
} */
return ( 0 ) ;
return ( 0 ) ;
}
}
@ -359,10 +397,14 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
privkey = LP_privkey ( utxo - > coinaddr , coin - > taddr ) ;
privkey = LP_privkey ( utxo - > coinaddr , coin - > taddr ) ;
if ( bits256_nonz ( privkey ) ! = 0 & & bits256_cmp ( G . LP_mypub25519 , qp - > srchash ) = = 0 ) //qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending &&
if ( bits256_nonz ( privkey ) ! = 0 & & bits256_cmp ( G . LP_mypub25519 , qp - > srchash ) = = 0 ) //qp->quotetime >= qp->timestamp-3 && qp->quotetime <= utxo->T.swappending &&
{
{
LP_requestinit ( & qp - > R , qp - > srchash , qp - > desthash , base , qp - > satoshis - qp - > txfee , rel , qp - > destsatoshis - qp - > desttxfee , qp - > timestamp , qp - > quotetime , DEXselector ) ;
if ( ( swap = LP_swapinit ( 1 , 0 , privkey , & qp - > R , qp ) ) = = 0 )
{
printf ( " cant initialize swap \n " ) ;
return ( - 1 ) ;
}
if ( ( pair = LP_nanobind ( ctx , pairstr ) ) > = 0 )
if ( ( pair = LP_nanobind ( ctx , pairstr ) ) > = 0 )
{
{
LP_requestinit ( & qp - > R , qp - > srchash , qp - > desthash , base , qp - > satoshis - 2 * qp - > txfee , rel , qp - > destsatoshis - 2 * qp - > desttxfee , qp - > timestamp , qp - > quotetime , DEXselector ) ;
swap = LP_swapinit ( 1 , 0 , privkey , & qp - > R , qp ) ;
swap - > N . pair = pair ;
swap - > N . pair = pair ;
utxo - > S . swap = swap ;
utxo - > S . swap = swap ;
swap - > utxo = utxo ;
swap - > utxo = utxo ;
@ -400,9 +442,6 @@ int32_t LP_connectstartbob(void *ctx,int32_t pubsock,struct LP_utxoinfo *utxo,cJ
return ( retval ) ;
return ( retval ) ;
}
}
struct LP_quoteinfo LP_Alicequery ;
double LP_Alicemaxprice ;
uint32_t Alice_expiration ;
char * LP_trade ( void * ctx , char * myipaddr , int32_t mypubsock , struct LP_quoteinfo * qp , double maxprice , int32_t timeout , int32_t duration , uint32_t tradeid )
char * LP_trade ( void * ctx , char * myipaddr , int32_t mypubsock , struct LP_quoteinfo * qp , double maxprice , int32_t timeout , int32_t duration , uint32_t tradeid )
{
{
struct LP_utxoinfo * aliceutxo ; double price ; //cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; struct basilisk_swap *swap;
struct LP_utxoinfo * aliceutxo ; double price ; //cJSON *bestitem=0; int32_t DEXselector=0; uint32_t expiration; double price; struct LP_pubkeyinfo *pubp; struct basilisk_swap *swap;
@ -412,6 +451,8 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q
return ( clonestr ( " { \" error \" : \" cant find alice utxopair \" } " ) ) ;
return ( clonestr ( " { \" error \" : \" cant find alice utxopair \" } " ) ) ;
}
}
price = 0. ;
price = 0. ;
memset ( qp - > txid . bytes , 0 , sizeof ( qp - > txid ) ) ;
qp - > txid2 = qp - > txid ;
qp - > aliceid = LP_aliceid_calc ( qp - > desttxid , qp - > destvout , qp - > feetxid , qp - > feevout ) ;
qp - > aliceid = LP_aliceid_calc ( qp - > desttxid , qp - > destvout , qp - > feetxid , qp - > feevout ) ;
qp - > tradeid = tradeid ;
qp - > tradeid = tradeid ;
LP_query ( ctx , myipaddr , mypubsock , " request " , qp ) ;
LP_query ( ctx , myipaddr , mypubsock , " request " , qp ) ;
@ -422,7 +463,7 @@ char *LP_trade(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo *q
int32_t LP_quotecmp ( struct LP_quoteinfo * qp , struct LP_quoteinfo * qp2 )
int32_t LP_quotecmp ( struct LP_quoteinfo * qp , struct LP_quoteinfo * qp2 )
{
{
if ( bits256_cmp ( qp - > srchash , qp2 - > srchash ) = = 0 & & bits256_cmp ( qp - > desthash , qp2 - > desthash ) = = 0 & & strcmp ( qp - > srccoin , qp2 - > srccoin ) = = 0 & & strcmp ( qp - > destcoin , qp2 - > destcoin ) = = 0 & & bits256_cmp ( qp - > desttxid , qp2 - > desttxid ) = = 0 & & qp - > destvout = = qp2 - > destvout & & bits256_cmp ( qp - > feetxid , qp2 - > feetxid ) = = 0 & & qp - > feevout = = qp2 - > feevout & & qp - > destsatoshis = = qp2 - > destsatoshis & & qp - > txfee > = qp2 - > txfee & & qp - > desttxfee = = qp2 - > desttxfee )
if ( bits256_cmp ( qp - > desthash , qp2 - > desthash ) = = 0 & & strcmp ( qp - > srccoin , qp2 - > srccoin ) = = 0 & & strcmp ( qp - > destcoin , qp2 - > destcoin ) = = 0 & & bits256_cmp ( qp - > desttxid , qp2 - > desttxid ) = = 0 & & qp - > destvout = = qp2 - > destvout & & bits256_cmp ( qp - > feetxid , qp2 - > feetxid ) = = 0 & & qp - > feevout = = qp2 - > feevout & & qp - > destsatoshis = = qp2 - > destsatoshis & & qp - > txfee > = qp2 - > txfee & & qp - > desttxfee = = qp2 - > desttxfee ) //bits256_cmp(qp->srchash,qp2->srchash) == 0 &&
return ( 0 ) ;
return ( 0 ) ;
else return ( - 1 ) ;
else return ( - 1 ) ;
}
}
@ -445,46 +486,52 @@ void LP_reserved(void *ctx,char *myipaddr,int32_t mypubsock,struct LP_quoteinfo
if ( LP_alice_eligible ( ) > 0 & & LP_quotecmp ( qp , & LP_Alicequery ) = = 0 )
if ( LP_alice_eligible ( ) > 0 & & LP_quotecmp ( qp , & LP_Alicequery ) = = 0 )
{
{
price = LP_pricecache ( qp , qp - > srccoin , qp - > destcoin , qp - > txid , qp - > vout ) ;
price = LP_pricecache ( qp , qp - > srccoin , qp - > destcoin , qp - > txid , qp - > vout ) ;
if ( LP_pricevalid ( price ) > 0 & & maxprice > SMALLVAL & & price < = maxprice )
if ( LP_pricevalid ( price ) > 0 & & maxprice > SMALLVAL & & price < = maxprice * 1.005 )
{
{
qp - > tradeid = LP_Alicequery . tradeid ;
qp - > tradeid = LP_Alicequery . tradeid ;
memset ( & LP_Alicequery , 0 , sizeof ( LP_Alicequery ) ) ;
memset ( & LP_Alicequery , 0 , sizeof ( LP_Alicequery ) ) ;
LP_Alicemaxprice = 0. ;
LP_Alicemaxprice = 0. ;
Alice_expiration = 0 ;
Alice_expiration = 0 ;
printf ( " send CONNECT \n " ) ;
LP_query ( ctx , myipaddr , mypubsock , " connect " , qp ) ;
LP_query ( ctx , myipaddr , mypubsock , " connect " , qp ) ;
}
} else printf ( " LP_reserved price %.8f vs maxprice %.8f \n " , price , maxprice * 1.005 ) ;
} else printf ( " reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f \n " , LP_alice_eligible ( ) , price , maxprice ) ;
} else printf ( " probably a timeout, reject reserved due to not eligible.%d or mismatched quote price %.8f vs maxprice %.8f\n " , LP_alice_eligible ( ) , price , maxprice ) ;
}
}
char * LP_connectedalice ( cJSON * argjson ) // alice
char * LP_connectedalice ( cJSON * argjson ) // alice
{
{
cJSON * retjson ; double bid , ask , price , qprice ; int32_t pairsock = - 1 ; char * pairstr ; int32_t DEXselector = 0 ; struct LP_utxoinfo * autxo , B , * butxo ; struct LP_quoteinfo Q ; struct basilisk_swap * swap ; struct iguana_info * coin ; //uint64_t value,value2;
cJSON * retjson ; double bid , ask , price , qprice ; int32_t pairsock = - 1 ; char * pairstr ; int32_t DEXselector = 0 ; struct LP_utxoinfo * autxo , B , * butxo ; struct LP_quoteinfo Q ; struct basilisk_swap * swap ; struct iguana_info * coin ; //uint64_t value,value2;
if ( LP_quoteparse ( & Q , argjson ) < 0 )
if ( LP_quoteparse ( & Q , argjson ) < 0 )
{
LP_aliceid ( Q . tradeid , Q . aliceid , " error0 " , 0 , 0 ) ;
clonestr ( " { \" error \" : \" cant parse quote \" } " ) ;
clonestr ( " { \" error \" : \" cant parse quote \" } " ) ;
}
if ( bits256_cmp ( Q . desthash , G . LP_mypub25519 ) ! = 0 )
if ( bits256_cmp ( Q . desthash , G . LP_mypub25519 ) ! = 0 )
return ( clonestr ( " { \" result \" , \" update stats \" } " ) ) ;
printf ( " CONNECTED.(%s) numpending.%d tradeid.%u \n " , jprint ( argjson , 0 ) , G . LP_pendingswaps , Q . tradeid ) ;
/*if ( LP_alice_eligible() == 0 || LP_quotecmp(&Q,&LP_Alicequery) != 0 )
{
{
printf ( " reject mismatched alice query \n " ) ;
LP_aliceid ( Q . tradeid , Q . aliceid , " error1 " , 0 , 0 ) ;
return ( clonestr ( " { \" error \" , \" mismatched alice query \" } " ) ) ;
return ( clonestr ( " { \" result \" , \" update stats \" } " ) ) ;
}
}
memset ( & LP_Alicequery , 0 , sizeof ( LP_Alicequery ) ) ;
printf ( " CONNECTED.(%s) numpending.%d tradeid.%u \n " , jprint ( argjson , 0 ) , G . LP_pendingswaps , Q . tradeid ) ;
LP_Alicemaxprice = 0. ;
Alice_expiration = 0 ; */
if ( ( autxo = LP_utxopairfind ( 0 , Q . desttxid , Q . destvout , Q . feetxid , Q . feevout ) ) = = 0 )
if ( ( autxo = LP_utxopairfind ( 0 , Q . desttxid , Q . destvout , Q . feetxid , Q . feevout ) ) = = 0 )
{
{
printf ( " cant find autxo \n " ) ;
printf ( " cant find autxo \n " ) ;
LP_aliceid ( Q . tradeid , Q . aliceid , " error2 " , 0 , 0 ) ;
return ( clonestr ( " { \" error \" : \" cant find autxo \" } " ) ) ;
return ( clonestr ( " { \" error \" : \" cant find autxo \" } " ) ) ;
}
}
if ( autxo - > S . swap ! = 0 )
if ( autxo - > S . swap ! = 0 )
{
printf ( " ignore duplicate swap \n " ) ;
LP_aliceid ( Q . tradeid , Q . aliceid , " error3 " , 0 , 0 ) ;
return ( clonestr ( " { \" error \" : \" ignore duplicate swap \" } " ) ) ;
return ( clonestr ( " { \" error \" : \" ignore duplicate swap \" } " ) ) ;
}
LP_aliceid ( Q . tradeid , Q . aliceid , " connected " , Q . R . requestid , Q . R . quoteid ) ;
butxo = & B ;
butxo = & B ;
memset ( butxo , 0 , sizeof ( * butxo ) ) ;
memset ( butxo , 0 , sizeof ( * butxo ) ) ;
LP_abutxo_set ( 0 , butxo , & Q ) ;
LP_abutxo_set ( 0 , butxo , & Q ) ;
if ( ( qprice = LP_quote_validate ( autxo , butxo , & Q , 0 ) ) < = SMALLVAL )
if ( ( qprice = LP_quote_validate ( autxo , butxo , & Q , 0 ) ) < = SMALLVAL )
{
{
LP_availableset ( autxo ) ;
LP_availableset ( autxo ) ;
LP_aliceid ( Q . tradeid , Q . aliceid , " error4 " , 0 , 0 ) ;
printf ( " quote validate error %.0f \n " , qprice ) ;
printf ( " quote validate error %.0f \n " , qprice ) ;
return ( clonestr ( " { \" error \" : \" quote validation error \" } " ) ) ;
return ( clonestr ( " { \" error \" : \" quote validation error \" } " ) ) ;
}
}
@ -492,29 +539,43 @@ char *LP_connectedalice(cJSON *argjson) // alice
{
{
printf ( " this node has no price for %s/%s (%.8f %.8f) \n " , Q . destcoin , Q . srccoin , bid , ask ) ;
printf ( " this node has no price for %s/%s (%.8f %.8f) \n " , Q . destcoin , Q . srccoin , bid , ask ) ;
LP_availableset ( autxo ) ;
LP_availableset ( autxo ) ;
LP_aliceid ( Q . tradeid , Q . aliceid , " error5 " , 0 , 0 ) ;
return ( clonestr ( " { \" error \" : \" no price set \" } " ) ) ;
return ( clonestr ( " { \" error \" : \" no price set \" } " ) ) ;
}
}
printf ( " %s/%s bid %.8f ask %.8f values %.8f %.8f \n " , Q . srccoin , Q . destcoin , bid , ask , dstr ( butxo - > payment . value ) , dstr ( butxo - > deposit . value ) ) ;
printf ( " %s/%s bid %.8f ask %.8f values %.8f %.8f \n " , Q . srccoin , Q . destcoin , bid , ask , dstr ( butxo - > payment . value ) , dstr ( butxo - > deposit . value ) ) ;
price = bid ;
price = bid ;
if ( ( coin = LP_coinfind ( Q . destcoin ) ) = = 0 )
if ( ( coin = LP_coinfind ( Q . destcoin ) ) = = 0 )
{
LP_aliceid ( Q . tradeid , Q . aliceid , " error6 " , 0 , 0 ) ;
return ( clonestr ( " { \" error \" : \" cant get alicecoin \" } " ) ) ;
return ( clonestr ( " { \" error \" : \" cant get alicecoin \" } " ) ) ;
}
Q . privkey = LP_privkey ( Q . destaddr , coin - > taddr ) ;
Q . privkey = LP_privkey ( Q . destaddr , coin - > taddr ) ;
if ( bits256_nonz ( Q . privkey ) ! = 0 ) //&& Q.quotetime >= Q.timestamp-3 )
if ( bits256_nonz ( Q . privkey ) ! = 0 ) //&& Q.quotetime >= Q.timestamp-3 )
{
{
retjson = cJSON_CreateObject ( ) ;
retjson = cJSON_CreateObject ( ) ;
LP_requestinit ( & Q . R , Q . srchash , Q . desthash , Q . srccoin , Q . satoshis - Q . txfee , Q . destcoin , Q . destsatoshis - Q . desttxfee , Q . timestamp , Q . quotetime , DEXselector ) ;
if ( ( swap = LP_swapinit ( 0 , 0 , Q . privkey , & Q . R , & Q ) ) = = 0 )
{
jaddstr ( retjson , " error " , " couldnt swapinit " ) ;
LP_availableset ( autxo ) ;
LP_aliceid ( Q . tradeid , Q . aliceid , " error7 " , Q . R . requestid , Q . R . quoteid ) ;
return ( jprint ( retjson , 1 ) ) ;
}
if ( ( pairstr = jstr ( argjson , " pair " ) ) = = 0 | | ( pairsock = nn_socket ( AF_SP , NN_PAIR ) ) < 0 )
if ( ( pairstr = jstr ( argjson , " pair " ) ) = = 0 | | ( pairsock = nn_socket ( AF_SP , NN_PAIR ) ) < 0 )
{
LP_aliceid ( Q . tradeid , Q . aliceid , " error8 " , Q . R . requestid , Q . R . quoteid ) ;
jaddstr ( retjson , " error " , " couldnt create pairsock " ) ;
jaddstr ( retjson , " error " , " couldnt create pairsock " ) ;
}
else if ( nn_connect ( pairsock , pairstr ) > = 0 )
else if ( nn_connect ( pairsock , pairstr ) > = 0 )
{
{
//timeout = 1;
//timeout = 1;
//nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
//nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
//nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
//nn_setsockopt(pairsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
LP_requestinit ( & Q . R , Q . srchash , Q . desthash , Q . srccoin , Q . satoshis - 2 * Q . txfee , Q . destcoin , Q . destsatoshis - 2 * Q . desttxfee , Q . timestamp , Q . quotetime , DEXselector ) ;
swap = LP_swapinit ( 0 , 0 , Q . privkey , & Q . R , & Q ) ;
swap - > tradeid = Q . tradeid ;
swap - > tradeid = Q . tradeid ;
swap - > N . pair = pairsock ;
swap - > N . pair = pairsock ;
autxo - > S . swap = swap ;
autxo - > S . swap = swap ;
swap - > utxo = autxo ;
swap - > utxo = autxo ;
LP_aliceid ( Q . tradeid , Q . aliceid , " started " , Q . R . requestid , Q . R . quoteid ) ;
printf ( " alice pairstr.(%s) pairsock.%d \n " , pairstr , pairsock ) ;
printf ( " alice pairstr.(%s) pairsock.%d \n " , pairstr , pairsock ) ;
if ( OS_thread_create ( malloc ( sizeof ( pthread_t ) ) , NULL , ( void * ) LP_aliceloop , ( void * ) swap ) = = 0 )
if ( OS_thread_create ( malloc ( sizeof ( pthread_t ) ) , NULL , ( void * ) LP_aliceloop , ( void * ) swap ) = = 0 )
{
{
@ -522,8 +583,18 @@ char *LP_connectedalice(cJSON *argjson) // alice
jaddstr ( retjson , " result " , " success " ) ;
jaddstr ( retjson , " result " , " success " ) ;
//jaddnum(retjson,"requestid",Q.R.requestid);
//jaddnum(retjson,"requestid",Q.R.requestid);
//jaddnum(retjson,"quoteid",Q.R.quoteid);
//jaddnum(retjson,"quoteid",Q.R.quoteid);
} else jaddstr ( retjson , " error " , " couldnt aliceloop " ) ;
}
} else printf ( " connect error %s \n " , nn_strerror ( nn_errno ( ) ) ) ;
else
{
LP_aliceid ( Q . tradeid , Q . aliceid , " error9 " , Q . R . requestid , Q . R . quoteid ) ;
jaddstr ( retjson , " error " , " couldnt aliceloop " ) ;
}
}
else
{
LP_aliceid ( Q . tradeid , Q . aliceid , " error10 " , Q . R . requestid , Q . R . quoteid ) ;
printf ( " connect error %s \n " , nn_strerror ( nn_errno ( ) ) ) ;
}
printf ( " connected result.(%s) \n " , jprint ( retjson , 0 ) ) ;
printf ( " connected result.(%s) \n " , jprint ( retjson , 0 ) ) ;
if ( jobj ( retjson , " error " ) ! = 0 )
if ( jobj ( retjson , " error " ) ! = 0 )
LP_availableset ( autxo ) ;
LP_availableset ( autxo ) ;
@ -532,6 +603,7 @@ char *LP_connectedalice(cJSON *argjson) // alice
else
else
{
{
LP_availableset ( autxo ) ;
LP_availableset ( autxo ) ;
LP_aliceid ( Q . tradeid , Q . aliceid , " error11 " , 0 , 0 ) ;
printf ( " no privkey found coin.%s %s taddr.%u \n " , Q . destcoin , Q . destaddr , coin - > taddr ) ;
printf ( " no privkey found coin.%s %s taddr.%u \n " , Q . destcoin , Q . destaddr , coin - > taddr ) ;
return ( clonestr ( " { \" error \" , \" no privkey \" } " ) ) ;
return ( clonestr ( " { \" error \" , \" no privkey \" } " ) ) ;
}
}
@ -594,21 +666,68 @@ int32_t LP_aliceonly(char *symbol)
else return ( 0 ) ;
else return ( 0 ) ;
}
}
int32_t LP_validSPV ( char * symbol , char * coinaddr , bits256 txid , int32_t vout )
{
struct electrum_info * ep , * backupep ; struct LP_address_utxo * up ; struct iguana_info * coin ;
coin = LP_coinfind ( symbol ) ;
if ( coin ! = 0 & & ( ep = coin - > electrum ) ! = 0 )
{
if ( ( up = LP_address_utxofind ( coin , coinaddr , txid , vout ) ) ! = 0 )
{
if ( up - > SPV < 0 )
return ( - 1 ) ;
if ( ( backupep = ep - > prev ) = = 0 )
backupep = ep ;
up - > SPV = LP_merkleproof ( coin , coinaddr , backupep , up - > U . txid , up - > U . height ) ;
if ( up - > SPV < = 0 )
return ( - 1 ) ;
}
}
return ( 0 ) ;
}
int32_t LP_tradecommand ( void * ctx , char * myipaddr , int32_t pubsock , cJSON * argjson , uint8_t * data , int32_t datalen )
int32_t LP_tradecommand ( void * ctx , char * myipaddr , int32_t pubsock , cJSON * argjson , uint8_t * data , int32_t datalen )
{
{
char * method , * msg , * retstr , str [ 65 ] ; int32_t DEXselector = 0 ; uint64_t value , value2 ; cJSON * retjson ; double qprice , price , bid , ask ; struct LP_utxoinfo A , B , * autxo , * butxo ; struct iguana_info * coin ; struct LP_address_utxo * utxos [ 1000 ] ; struct LP_quoteinfo Q ; int32_t retval = - 1 , max = ( int32_t ) ( sizeof ( utxos ) / sizeof ( * utxos ) ) ;
char * method , * msg , * retstr , str [ 65 ] ; int32_t DEXselector = 0 ; uint64_t aliceid , value , value2 ; cJSON * retjson ; double qprice , range , best price , price , bid , ask ; struct LP_utxoinfo A , B , * autxo , * butxo ; struct iguana_info * coin ; struct LP_address_utxo * utxos [ 1000 ] ; struct LP_quoteinfo Q ; int32_t r , r etval = - 1 , recalc , max = ( int32_t ) ( sizeof ( utxos ) / sizeof ( * utxos ) ) ;
if ( ( method = jstr ( argjson , " method " ) ) ! = 0 & & ( strcmp ( method , " reserved " ) = = 0 | | strcmp ( method , " connected " ) = = 0 | | strcmp ( method , " request " ) = = 0 | | strcmp ( method , " connect " ) = = 0 ) )
if ( ( method = jstr ( argjson , " method " ) ) ! = 0 & & ( strcmp ( method , " reserved " ) = = 0 | | strcmp ( method , " connected " ) = = 0 | | strcmp ( method , " request " ) = = 0 | | strcmp ( method , " connect " ) = = 0 ) )
{
{
// LP_checksig
// LP_checksig
LP_quoteparse ( & Q , argjson ) ;
LP_quoteparse ( & Q , argjson ) ;
LP_requestinit ( & Q . R , Q . srchash , Q . desthash , Q . srccoin , Q . satoshis - 2 * Q . txfee , Q . destcoin , Q . destsatoshis - 2 * Q . desttxfee , Q . timestamp , Q . quotetime , DEXselector ) ;
LP_requestinit ( & Q . R , Q . srchash , Q . desthash , Q . srccoin , Q . satoshis - Q . txfee , Q . destcoin , Q . destsatoshis - Q . desttxfee , Q . timestamp , Q . quotetime , DEXselector ) ;
LP_tradecommand_log ( argjson ) ;
LP_tradecommand_log ( argjson ) ;
//printf("LP_tradecommand: check received method %s aliceid.%llx\n",method,(long long)Q.aliceid);
//printf("LP_tradecommand: check received method %12 s aliceid.%16 llx %5s/%-5s %12.8f -> %12.8f price %12.8f \n",method,(long long)Q.aliceid,Q.srccoin,Q.destcoin,dstr(Q.satoshis),dstr(Q.destsatoshis),(double)Q.destsatoshis/Q.satoshis );
retval = 1 ;
retval = 1 ;
autxo = & A ;
butxo = & B ;
memset ( autxo , 0 , sizeof ( * autxo ) ) ;
memset ( butxo , 0 , sizeof ( * butxo ) ) ;
LP_abutxo_set ( autxo , butxo , & Q ) ;
aliceid = j64bits ( argjson , " aliceid " ) ;
qprice = jdouble ( argjson , " price " ) ;
if ( strcmp ( method , " reserved " ) = = 0 )
if ( strcmp ( method , " reserved " ) = = 0 )
{
{
bestprice = LP_bob_competition ( aliceid , qprice ) ;
//printf("aliceid.%llx price %.8f -> bestprice %.8f\n",(long long)aliceid,qprice,bestprice);
if ( LP_Alicemaxprice = = 0. )
return ( retval ) ;
if ( bits256_cmp ( G . LP_mypub25519 , Q . desthash ) = = 0 & & bits256_cmp ( G . LP_mypub25519 , Q . srchash ) ! = 0 & & LP_alice_eligible ( ) > 0 )
if ( bits256_cmp ( G . LP_mypub25519 , Q . desthash ) = = 0 & & bits256_cmp ( G . LP_mypub25519 , Q . srchash ) ! = 0 & & LP_alice_eligible ( ) > 0 )
{
{
if ( ( qprice = LP_quote_validate ( autxo , butxo , & Q , 0 ) ) < = SMALLVAL )
{
printf ( " reserved quote validate error %.0f \n " , qprice ) ;
return ( retval ) ;
}
if ( LP_validSPV ( Q . srccoin , Q . coinaddr , Q . txid , Q . vout ) < 0 )
{
printf ( " %s src %s failed SPV check \n " , Q . srccoin , bits256_str ( str , Q . txid ) ) ;
return ( retval ) ;
}
else if ( LP_validSPV ( Q . srccoin , Q . coinaddr , Q . txid2 , Q . vout2 ) < 0 )
{
printf ( " %s src2 %s failed SPV check \n " , Q . srccoin , bits256_str ( str , Q . txid2 ) ) ;
return ( retval ) ;
}
LP_aliceid ( Q . tradeid , Q . aliceid , " reserved " , 0 , 0 ) ;
printf ( " alice %s received RESERVED.(%s) \n " , bits256_str ( str , G . LP_mypub25519 ) , jprint ( argjson , 0 ) ) ;
printf ( " alice %s received RESERVED.(%s) \n " , bits256_str ( str , G . LP_mypub25519 ) , jprint ( argjson , 0 ) ) ;
if ( ( retstr = LP_quotereceived ( argjson ) ) ! = 0 )
if ( ( retstr = LP_quotereceived ( argjson ) ) ! = 0 )
free ( retstr ) ;
free ( retstr ) ;
@ -620,49 +739,101 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
{
{
if ( bits256_cmp ( G . LP_mypub25519 , Q . desthash ) = = 0 & & bits256_cmp ( G . LP_mypub25519 , Q . srchash ) ! = 0 )
if ( bits256_cmp ( G . LP_mypub25519 , Q . desthash ) = = 0 & & bits256_cmp ( G . LP_mypub25519 , Q . srchash ) ! = 0 )
{
{
if ( ( qprice = LP_quote_validate ( autxo , butxo , & Q , 0 ) ) < = SMALLVAL )
{
printf ( " quote validate error %.0f \n " , qprice ) ;
return ( retval ) ;
}
if ( LP_validSPV ( Q . srccoin , Q . coinaddr , Q . txid , Q . vout ) < 0 )
{
printf ( " %s src %s failed SPV check \n " , Q . srccoin , bits256_str ( str , Q . txid ) ) ;
return ( retval ) ;
}
else if ( LP_validSPV ( Q . srccoin , Q . coinaddr , Q . txid2 , Q . vout2 ) < 0 )
{
printf ( " %s src2 %s failed SPV check \n " , Q . srccoin , bits256_str ( str , Q . txid2 ) ) ;
return ( retval ) ;
}
//printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0));
//printf("alice %s received CONNECTED.(%s)\n",bits256_str(str,G.LP_mypub25519),jprint(argjson,0));
if ( ( retstr = LP_connectedalice ( argjson ) ) ! = 0 )
if ( ( retstr = LP_connectedalice ( argjson ) ) ! = 0 )
free ( retstr ) ;
free ( retstr ) ;
}
}
return ( retval ) ;
return ( retval ) ;
}
}
if ( bits256_cmp ( G . LP_mypub25519 , Q . srchash ) = = 0 & & bits256_cmp ( G . LP_mypub25519 , Q . desthash ) ! = 0 )
price = LP_myprice ( & bid , & ask , Q . srccoin , Q . destcoin ) ;
if ( ( coin = LP_coinfind ( Q . srccoin ) ) = = 0 | | price < = SMALLVAL | | ask < = SMALLVAL )
{
{
if ( ( coin = LP_coinfind ( Q . srccoin ) ) = = 0 | | ( price = LP_myprice ( & bid , & ask , Q . srccoin , Q . destcoin ) ) < = SMALLVAL | | ask < = SMALLVAL )
//printf("this node has no price for %s/%s\n",Q.srccoin,Q.destcoin);
return ( retval ) ;
}
price = ask ;
//printf("MYPRICE %s/%s %.8f\n",Q.srccoin,Q.destcoin,price);
if ( LP_validSPV ( Q . destcoin , Q . destaddr , Q . desttxid , Q . destvout ) < 0 )
{
{
printf ( " this node has no price for %s/%s \n " , Q . srccoin , Q . destcoin ) ;
printf ( " %s dest %s failed SPV check \n " , Q . dest coin, bits256_str ( str , Q . desttxid ) ) ;
return ( retval ) ;
return ( retval ) ;
}
}
/*if ( coin->electrum != 0 )
else if ( LP_validSPV ( Q . destcoin , Q . destaddr , Q . feetxid , Q . feevout ) < 0 )
{
{
printf ( " electrum can only be for alice \n " ) ;
printf ( " %s dexfee %s failed SPV check \n " , Q . destcoin , bits256_str ( str , Q . feetxid ) ) ;
return ( retval ) ;
return ( retval ) ;
} */
}
if ( LP_aliceonly ( Q . srccoin ) > 0 )
if ( LP_aliceonly ( Q . srccoin ) > 0 )
{
{
printf ( " { \" error \" : \" GAME can only be alice coin \" } \n " ) ;
printf ( " { \" error \" : \" GAME can only be alice coin \" } \n " ) ;
return ( retval ) ;
return ( retval ) ;
}
}
if ( strcmp ( Q . coinaddr , coin - > smartaddr ) ! = 0 )
{
printf ( " bob is patching Q.coinaddr %s mismatch != %s \n " , Q . coinaddr , coin - > smartaddr ) ;
strcpy ( Q . coinaddr , coin - > smartaddr ) ;
}
price = ask ;
autxo = & A ;
butxo = & B ;
memset ( autxo , 0 , sizeof ( * autxo ) ) ;
memset ( butxo , 0 , sizeof ( * butxo ) ) ;
LP_abutxo_set ( autxo , butxo , & Q ) ;
printf ( " utxopairfind \n " ) ;
if ( ( butxo = LP_utxopairfind ( 1 , Q . txid , Q . vout , Q . txid2 , Q . vout2 ) ) = = 0 )
butxo = & B ;
//LP_butxo_swapfields(butxo);
if ( strcmp ( method , " request " ) = = 0 )
if ( strcmp ( method , " request " ) = = 0 )
{
{
char str [ 65 ] , str2 [ 65 ] ;
char str [ 65 ] ; //,str2[65];
printf ( " request.(%s) \n " , jprint ( argjson , 0 ) ) ;
recalc = 0 ;
if ( 1 ) //LP_allocated(butxo->payment.txid,butxo->payment.vout) != 0 || LP_allocated(butxo->deposit.txid,butxo->deposit.vout) != 0 || (qprice= LP_quote_validate(autxo,butxo,&Q,1)) <= SMALLVAL )
if ( bits256_cmp ( Q . srchash , G . LP_mypub25519 ) ! = 0 | | strcmp ( butxo - > coinaddr , coin - > smartaddr ) ! = 0 | | bits256_nonz ( butxo - > payment . txid ) = = 0 | | bits256_nonz ( butxo - > deposit . txid ) = = 0 )
{
qprice = ( double ) Q . destsatoshis / Q . satoshis ;
strcpy ( Q . gui , G . gui ) ;
strcpy ( Q . coinaddr , coin - > smartaddr ) ;
strcpy ( butxo - > coinaddr , coin - > smartaddr ) ;
Q . srchash = G . LP_mypub25519 ;
memset ( & Q . txid , 0 , sizeof ( Q . txid ) ) ;
memset ( & Q . txid2 , 0 , sizeof ( Q . txid2 ) ) ;
Q . vout = Q . vout2 = - 1 ;
recalc = 1 ;
}
else if ( ( qprice = LP_quote_validate ( autxo , butxo , & Q , 1 ) ) < SMALLVAL )
recalc = 1 ;
else if ( price < qprice )
{
char tmp [ 64 ] ;
if ( bits256_nonz ( Q . txid ) ! = 0 )
LP_utxos_remove ( Q . txid , Q . vout ) ;
else recalc = 1 ;
if ( bits256_nonz ( Q . txid2 ) ! = 0 )
LP_utxos_remove ( Q . txid2 , Q . vout2 ) ;
else recalc = 1 ;
printf ( " price %.8f qprice %.8f \n " , price , qprice ) ;
if ( recalc = = 0 )
{
value = LP_txvalue ( tmp , Q . srccoin , Q . txid , Q . vout ) ;
value2 = LP_txvalue ( tmp , Q . srccoin , Q . txid2 , Q . vout2 ) ;
//printf("call LP_utxoadd.(%s) %.8f %.8f\n",Q.coinaddr,dstr(value),dstr(value2));
if ( ( butxo = LP_utxoadd ( 1 , coin - > symbol , Q . txid , Q . vout , value , Q . txid2 , Q . vout2 , value2 , Q . coinaddr , Q . srchash , G . gui , 0 , Q . satoshis ) ) = = 0 )
recalc = 1 ;
else if ( bits256_cmp ( Q . txid , butxo - > payment . txid ) ! = 0 | | Q . vout ! = butxo - > payment . vout | | bits256_cmp ( Q . txid2 , butxo - > deposit . txid ) ! = 0 | | Q . vout2 ! = butxo - > deposit . vout )
recalc = 1 ;
}
} else return ( retval ) ;
if ( qprice > price )
{
r = ( rand ( ) % 100 ) ;
range = ( qprice - price ) ;
printf ( " >>>>>>>>>>>>> price %.8f qprice %.8f r.%d range %.8f -> %.8f vs bestprice %.8f \n " , price , qprice , r , range , price + ( r * range ) / 100. , LP_bob_competition ( aliceid , price ) ) ;
price + = ( r * range ) / 100. ;
bestprice = LP_bob_competition ( aliceid , price ) ;
if ( price < bestprice + SMALLVAL )
return ( retval ) ;
} else return ( retval ) ;
//printf("recalc.%d address.(%s/%s) price %.8f request.(%s)\n",recalc,Q.coinaddr,coin->smartaddr,price,jprint(argjson,0));
if ( recalc ! = 0 )
{
{
LP_RTmetrics_update ( Q . srccoin , Q . destcoin ) ;
LP_RTmetrics_update ( Q . srccoin , Q . destcoin ) ;
if ( LP_RTmetrics_blacklisted ( Q . desthash ) > = 0 )
if ( LP_RTmetrics_blacklisted ( Q . desthash ) > = 0 )
@ -670,39 +841,38 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf ( " request from blacklisted %s, ignore \n " , bits256_str ( str , Q . desthash ) ) ;
printf ( " request from blacklisted %s, ignore \n " , bits256_str ( str , Q . desthash ) ) ;
return ( retval ) ;
return ( retval ) ;
}
}
printf ( " butxo.%p replace path %p %s, %p %s, %.8f \n " , butxo , LP_allocated ( butxo - > payment . txid , butxo - > payment . vout ) , bits256_str ( str , butxo - > payment . txid ) , LP_allocated ( butxo - > deposit . txid , butxo - > deposit . vout ) , bits256_str ( str2 , butxo - > deposit . txid ) , LP_quote_validate ( autxo , butxo , & Q , 1 ) ) ;
LP_listunspent_both ( Q . srccoin , Q . coinaddr , 0 ) ;
LP_listunspent_both ( Q . srccoin , Q . coinaddr , 0 ) ;
if ( ( butxo = LP_address_utxopair ( 1 , utxos , max , LP_coinfind ( Q . srccoin ) , Q . coinaddr , Q . txfee , dstr ( Q . destsatoshis ) , price , Q . desttxfee ) ) ! = 0 )
if ( ( butxo = LP_address_utxopair ( 1 , utxos , max , LP_coinfind ( Q . srccoin ) , Q . coinaddr , Q . txfee , dstr ( Q . destsatoshis ) , price , Q . desttxfee ) ) ! = 0 )
{
{
strcpy ( Q . gui , G . gui ) ;
strcpy ( Q . coinaddr , coin - > smartaddr ) ;
Q . srchash = G . LP_mypub25519 ;
Q . txid = butxo - > payment . txid ;
Q . txid = butxo - > payment . txid ;
Q . vout = butxo - > payment . vout ;
Q . vout = butxo - > payment . vout ;
Q . txid2 = butxo - > deposit . txid ;
Q . txid2 = butxo - > deposit . txid ;
Q . vout2 = butxo - > deposit . vout ;
Q . vout2 = butxo - > deposit . vout ;
printf ( " set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f \n " , butxo , bits256_str ( str , butxo - > payment . txid ) , butxo - > payment . vout , bits256_str ( str2 , butxo - > deposit . txid ) , butxo - > deposit . vout , dstr ( butxo - > payment . value ) , dstr ( butxo - > deposit . value ) , dstr ( butxo - > S . satoshis ) , dstr ( autxo - > S . satoshis ) ) ;
Q . satoshis = butxo - > S . satoshis ;
} else printf ( " cant find utxopair \n " ) ;
//printf("set butxo.%p %s/v%d %s/v%d %.8f %.8f -> bsat %.8f asat %.8f\n",butxo,bits256_str(str,butxo->payment.txid),butxo->payment.vout,bits256_str(str2,butxo->deposit.txid),butxo->deposit.vout,dstr(butxo->payment.value),dstr(butxo->deposit.value),dstr(butxo->S.satoshis),dstr(autxo->S.satoshis));
//LP_abutxo_set(0,butxo,&Q);
//LP_butxo_swapfields(butxo);
}
}
else
else
{
{
printf ( " other path %p %p %.8f \n " , LP_allocated ( butxo - > payment . txid , butxo - > payment . vout ) , LP_allocated ( butxo - > deposit . txid , butxo - > deposit . vout ) , LP_quote_validate ( autxo , butxo , & Q , 1 ) ) ;
//printf("cant find utxopair\n");
value = LP_txvalue ( Q . coinaddr , Q . srccoin , Q . txid , Q . vout ) ;
return ( retval ) ;
value2 = LP_txvalue ( Q . coinaddr , Q . srccoin , Q . txid2 , Q . vout2 ) ;
}
if ( ( butxo = LP_utxoadd ( 1 , coin - > symbol , Q . txid , Q . vout , value , Q . txid2 , Q . vout2 , value2 , Q . coinaddr , G . LP_mypub25519 , G . gui , 0 ) ) = = 0 )
}
printf ( " couldnt create bob's utxopair \n " ) ;
else printf ( " created butxo.(%s %s) \ n " ,bits256_str(str,butxo->payment.txid),bits256_str(str2,butxo->deposit.txid)) ;
}
}
else // "connect"
{
if ( bits256_cmp ( G . LP_mypub25519 , Q . srchash ) = = 0 & & bits256_cmp ( G . LP_mypub25519 , Q . desthash ) ! = 0 )
{
butxo = LP_utxopairfind ( 1 , Q . txid , Q . vout , Q . txid2 , Q . vout2 ) ; // better work!
} else return ( retval ) ;
}
}
if ( butxo = = 0 | | butxo = = & B )
if ( strcmp ( Q . coinaddr , coin - > smartaddr ) ! = 0 )
butxo = LP_utxopairfind ( 1 , Q . txid , Q . vout , Q . txid2 , Q . vout2 ) ;
if ( butxo = = 0 | | bits256_cmp ( Q . txid , butxo - > payment . txid ) ! = 0 | | bits256_cmp ( Q . txid2 , butxo - > deposit . txid ) ! = 0 )
{
{
printf ( " %s %s null butxo.%p case \n " , Q . srccoin , Q . coinaddr , butxo ) ;
printf ( " bob is patching Q.coinaddr %s mismatch != %s \n " , Q . coinaddr , coin - > smartaddr ) ;
value = LP_txvalue ( Q . coinaddr , Q . srccoin , Q . txid , Q . vout ) ;
strcpy ( Q . coinaddr , coin - > smartaddr ) ;
value2 = LP_txvalue ( Q . coinaddr , Q . srccoin , Q . txid2 , Q . vout2 ) ;
butxo = LP_utxoadd ( 1 , Q . srccoin , Q . txid , Q . vout , value , Q . txid2 , Q . vout2 , value2 , Q . coinaddr , Q . srchash , LP_gui , 0 ) ;
}
}
char str [ 65 ] , str2 [ 65 ] ; printf ( " butxo.%p (%s %s) TRADECOMMAND.(%s) \n " , butxo , butxo ! = 0 ? bits256_str ( str , butxo - > payment . txid ) : " " , butxo ! = 0 ? bits256_str ( str2 , butxo - > deposit . txid ) : " " , jprint ( argjson , 0 ) ) ;
if ( butxo = = 0 | | bits256_nonz ( butxo - > payment . txid ) = = 0 | | bits256_nonz ( butxo - > deposit . txid ) = = 0 | | butxo - > payment . vout < 0 | | butxo - > deposit . vout < 0 )
if ( butxo = = 0 | | bits256_nonz ( butxo - > payment . txid ) = = 0 | | bits256_nonz ( butxo - > deposit . txid ) = = 0 | | butxo - > payment . vout < 0 | | butxo - > deposit . vout < 0 )
{
{
char str [ 65 ] , str2 [ 65 ] ; printf ( " couldnt find bob utxos for autxo %s/v%d %s/v%d %.8f -> %.8f \n " , bits256_str ( str , Q . txid ) , Q . vout , bits256_str ( str2 , Q . txid2 ) , Q . vout2 , dstr ( Q . satoshis ) , dstr ( Q . destsatoshis ) ) ;
char str [ 65 ] , str2 [ 65 ] ; printf ( " couldnt find bob utxos for autxo %s/v%d %s/v%d %.8f -> %.8f \n " , bits256_str ( str , Q . txid ) , Q . vout , bits256_str ( str2 , Q . txid2 ) , Q . vout2 , dstr ( Q . satoshis ) , dstr ( Q . destsatoshis ) ) ;
@ -713,11 +883,12 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
printf ( " quote validate error %.0f \n " , qprice ) ;
printf ( " quote validate error %.0f \n " , qprice ) ;
return ( - 3 ) ;
return ( - 3 ) ;
}
}
if ( qprice < ( price - 0.00000001 ) * 0.9999 )
if ( qprice < ( ask - 0.00000001 ) * 0.998 )
{
{
printf ( " (%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s \n " , bid , ask , qprice , price , Q . srccoin , Q . destcoin ) ;
printf ( " (%.8f %.8f) quote price %.8f too low vs %.8f for %s/%s %.8f < %.8f \n " , bid , ask , qprice , price , Q . srccoin , Q . destcoin , qprice , ( ask - 0.00000001 ) * 0.998 ) ;
return ( - 4 ) ;
return ( retval ) ;
}
}
char str [ 65 ] , str2 [ 65 ] ; printf ( " butxo.%p (%s %s) TRADECOMMAND.(%s) \n " , butxo , butxo ! = 0 ? bits256_str ( str , butxo - > payment . txid ) : " " , butxo ! = 0 ? bits256_str ( str2 , butxo - > deposit . txid ) : " " , jprint ( argjson , 0 ) ) ;
if ( butxo - > S . swap = = 0 & & time ( NULL ) > butxo - > T . swappending )
if ( butxo - > S . swap = = 0 & & time ( NULL ) > butxo - > T . swappending )
butxo - > T . swappending = 0 ;
butxo - > T . swappending = 0 ;
if ( strcmp ( method , " request " ) = = 0 ) // bob needs apayment + fee tx's
if ( strcmp ( method , " request " ) = = 0 ) // bob needs apayment + fee tx's
@ -735,7 +906,7 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
jaddstr ( retjson , " method " , " reserved " ) ;
jaddstr ( retjson , " method " , " reserved " ) ;
msg = jprint ( retjson , 0 ) ;
msg = jprint ( retjson , 0 ) ;
butxo - > T . lasttime = ( uint32_t ) time ( NULL ) ;
butxo - > T . lasttime = ( uint32_t ) time ( NULL ) ;
printf ( " return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f \n (%s) \n " , butxo - > T . swappending , qprice , price , msg ) ;
printf ( " return after queued RESERVED: set swappending.%u accept qprice %.8f, min %.8f \n (%s) \n " , butxo - > T . swappending , qprice , ask , msg ) ;
// LP_addsig
// LP_addsig
//msg2 = clonestr(msg);
//msg2 = clonestr(msg);
LP_reserved_msg ( 1 , Q . srccoin , Q . destcoin , butxo - > S . otherpubkey , clonestr ( msg ) ) ;
LP_reserved_msg ( 1 , Q . srccoin , Q . destcoin , butxo - > S . otherpubkey , clonestr ( msg ) ) ;
@ -762,7 +933,6 @@ int32_t LP_tradecommand(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,
}
}
//LP_butxo_swapfields_set(butxo);
//LP_butxo_swapfields_set(butxo);
}
}
}
return ( retval ) ;
return ( retval ) ;
}
}
@ -770,6 +940,7 @@ struct LP_utxoinfo *LP_ordermatch_iter(struct LP_address_utxo **utxos,int32_t ma
{
{
uint64_t basesatoshis ; struct LP_utxoinfo * bestutxo ;
uint64_t basesatoshis ; struct LP_utxoinfo * bestutxo ;
basesatoshis = LP_basesatoshis ( dstr ( asatoshis ) , price , txfee , desttxfee ) ;
basesatoshis = LP_basesatoshis ( dstr ( asatoshis ) , price , txfee , desttxfee ) ;
//printf("basesatoshis %.8f price %.8f txfee %.8f desttxfee %.8f\n",dstr(basesatoshis),price,dstr(txfee),dstr(desttxfee));
if ( basesatoshis ! = 0 & & ( bestutxo = LP_address_utxopair ( 0 , utxos , max , basecoin , coinaddr , txfee , dstr ( basesatoshis ) * price , price , desttxfee ) ) ! = 0 )
if ( basesatoshis ! = 0 & & ( bestutxo = LP_address_utxopair ( 0 , utxos , max , basecoin , coinaddr , txfee , dstr ( basesatoshis ) * price , price , desttxfee ) ) ! = 0 )
{
{
bestutxo - > pubkey = pubkey ;
bestutxo - > pubkey = pubkey ;
@ -795,10 +966,10 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
return ( 0 ) ;
return ( 0 ) ;
if ( basecoin - > electrum = = 0 )
if ( basecoin - > electrum = = 0 )
max = 1000 ;
max = 1000 ;
else max = 40 ;
else max = LP_MAXDESIRED_UTXOS ;
utxos = calloc ( max , sizeof ( * utxos ) ) ;
utxos = calloc ( max , sizeof ( * utxos ) ) ;
LP_txfees ( & txfee , & desttxfee , base , autxo - > coin ) ;
LP_txfees ( & txfee , & desttxfee , base , autxo - > coin ) ;
//printf(" LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f\n",maxprice,dstr(autxo->S.satoshis),base,autxo->coin,dstr(txfee),dstr(desttxfee));
printf ( " LP_buyutxo maxprice %.8f relvol %.8f %s/%s %.8f %.8f \n " , maxprice , dstr ( autxo - > S . satoshis ) , base , autxo - > coin , dstr ( txfee ) , dstr ( desttxfee ) ) ;
if ( ( obookstr = LP_orderbook ( base , autxo - > coin , duration ) ) ! = 0 )
if ( ( obookstr = LP_orderbook ( base , autxo - > coin , duration ) ) ! = 0 )
{
{
if ( ( orderbook = cJSON_Parse ( obookstr ) ) ! = 0 )
if ( ( orderbook = cJSON_Parse ( obookstr ) ) ! = 0 )
@ -811,15 +982,15 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
{
{
item = jitem ( asks , i ) ;
item = jitem ( asks , i ) ;
price = jdouble ( item , " price " ) ;
price = jdouble ( item , " price " ) ;
if ( price / maxprice < .9 )
//if ( price < maxprice && price > maxprice*0.8)
price * = 1.025 ;
// price = price * 0.9 + 0.1 * maxprice;
else price * = 1.001 ;
//else price *= 1.005;
pubkey = jbits256 ( item , " pubkey " ) ;
pubkey = jbits256 ( item , " pubkey " ) ;
if ( bits256_nonz ( destpubkey ) ! = 0 & & bits256_cmp ( destpubkey , pubkey ) ! = 0 )
if ( bits256_nonz ( destpubkey ) ! = 0 & & bits256_cmp ( destpubkey , pubkey ) ! = 0 )
continue ;
continue ;
if ( LP_RTmetrics_blacklisted ( pubkey ) > = 0 )
if ( LP_RTmetrics_blacklisted ( pubkey ) > = 0 )
continue ;
continue ;
//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f\n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice);
//printf("[%d/%d] %s pubcmp %d price %.8f vs maxprice %.8f asatoshis %.8f \n",i,numasks,jprint(item,0),bits256_cmp(pubkey,G.LP_mypub25519),price,maxprice,dstr(autxo->S.satoshis) );
if ( LP_pricevalid ( price ) > 0 & & price < = maxprice )
if ( LP_pricevalid ( price ) > 0 & & price < = maxprice )
{
{
if ( bits256_nonz ( destpubkey ) = = 0 )
if ( bits256_nonz ( destpubkey ) = = 0 )
@ -835,10 +1006,9 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
bitcoin_address ( coinaddr , basecoin - > taddr , basecoin - > pubtype , pubp - > rmd160 , sizeof ( pubp - > rmd160 ) ) ;
bitcoin_address ( coinaddr , basecoin - > taddr , basecoin - > pubtype , pubp - > rmd160 , sizeof ( pubp - > rmd160 ) ) ;
asatoshis = autxo - > S . satoshis ;
asatoshis = autxo - > S . satoshis ;
LP_listunspent_query ( base , coinaddr ) ;
LP_listunspent_query ( base , coinaddr ) ;
//LP_listunspent_both(base,coinaddr,1);
for ( j = 0 ; j < maxiters ; j + + )
for ( j = 0 ; j < maxiters ; j + + )
{
{
if ( ( bestutxo = LP_ordermatch_iter ( utxos , max , ordermatchpricep , bestsatoshisp , bestdestsatoshisp , basecoin , coinaddr , asatoshis , price , txfee , desttxfee , pubp - > pubkey , gui ) ) ! = 0 )
if ( ( bestutxo = LP_ordermatch_iter ( utxos , max , ordermatchpricep , bestsatoshisp , bestdestsatoshisp , basecoin , coinaddr , asatoshis , max price* .999 , txfee , desttxfee , pubp - > pubkey , gui ) ) ! = 0 )
{
{
//printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee));
//printf("j.%d/%d ordermatch %.8f best satoshis %.8f destsatoshis %.8f txfees (%.8f %.8f)\n",j,maxiters,price,dstr(*bestsatoshisp),dstr(*bestdestsatoshisp),dstr(txfee),dstr(desttxfee));
break ;
break ;
@ -873,7 +1043,7 @@ struct LP_utxoinfo *LP_buyutxo(double *ordermatchpricep,int64_t *bestsatoshisp,i
char * LP_autobuy ( void * ctx , char * myipaddr , int32_t mypubsock , char * base , char * rel , double maxprice , double relvolume , int32_t timeout , int32_t duration , char * gui , uint32_t nonce , bits256 destpubkey , uint32_t tradeid )
char * LP_autobuy ( void * ctx , char * myipaddr , int32_t mypubsock , char * base , char * rel , double maxprice , double relvolume , int32_t timeout , int32_t duration , char * gui , uint32_t nonce , bits256 destpubkey , uint32_t tradeid )
{
{
uint64_t desttxfee , txfee ; uint32_t lastnonce ; int32_t i , maxiters , numpubs = 0 ; int64_t bestsatoshis = 0 , destsatoshis , bestdestsatoshis = 0 ; struct iguana_info * basecoin , * relcoin ; struct LP_utxoinfo * autxo , * bestutxo = 0 ; double qprice , ordermatchprice = 0. ; struct LP_quoteinfo Q ; bits256 pubkeys [ 100 ] ;
uint64_t desttxfee , txfee ; uint32_t lastnonce ; int32_t i , maxiters , numpubs = 0 ; int64_t bestsatoshis = 0 , destsatoshis , bestdestsatoshis = 0 ; struct iguana_info * basecoin , * relcoin ; struct LP_utxoinfo * autxo , B , * bestutxo = 0 ; double qprice , ordermatchprice = 0. ; struct LP_quoteinfo Q ; bits256 pubkeys [ 100 ] ;
basecoin = LP_coinfind ( base ) ;
basecoin = LP_coinfind ( base ) ;
relcoin = LP_coinfind ( rel ) ;
relcoin = LP_coinfind ( rel ) ;
if ( gui = = 0 )
if ( gui = = 0 )
@ -921,15 +1091,15 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
destsatoshis = SATOSHIDEN * relvolume ;
destsatoshis = SATOSHIDEN * relvolume ;
if ( ( autxo = LP_utxo_bestfit ( rel , destsatoshis + 2 * desttxfee ) ) = = 0 )
if ( ( autxo = LP_utxo_bestfit ( rel , destsatoshis + 2 * desttxfee ) ) = = 0 )
return ( clonestr ( " { \" error \" : \" cant find alice utxo that is big enough \" } " ) ) ;
return ( clonestr ( " { \" error \" : \" cant find alice utxo that is big enough \" } " ) ) ;
if ( destsatoshis - 2 * desttxfee < autxo - > S . satoshis )
if ( destsatoshis - desttxfee < autxo - > S . satoshis )
{
{
destsatoshis - = 2 * desttxfee ;
destsatoshis - = desttxfee ;
autxo - > S . satoshis = destsatoshis ;
autxo - > S . satoshis = destsatoshis ;
//printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis));
//printf("first path dest %.8f from %.8f\n",dstr(destsatoshis),dstr(autxo->S.satoshis));
}
}
else if ( autxo - > S . satoshis - 2 * desttxfee < destsatoshis )
else if ( autxo - > S . satoshis - desttxfee < destsatoshis )
{
{
autxo - > S . satoshis - = 2 * desttxfee ;
autxo - > S . satoshis - = desttxfee ;
destsatoshis = autxo - > S . satoshis ;
destsatoshis = autxo - > S . satoshis ;
printf ( " second path dest %.8f from %.8f \n " , dstr ( destsatoshis ) , dstr ( autxo - > S . satoshis ) ) ;
printf ( " second path dest %.8f from %.8f \n " , dstr ( destsatoshis ) , dstr ( autxo - > S . satoshis ) ) ;
}
}
@ -938,6 +1108,17 @@ char *LP_autobuy(void *ctx,char *myipaddr,int32_t mypubsock,char *base,char *rel
printf ( " destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13 \n " , dstr ( destsatoshis ) , dstr ( autxo - > payment . value ) ) ;
printf ( " destsatoshis %.8f vs utxo %.8f this would have triggered an quote error -13 \n " , dstr ( destsatoshis ) , dstr ( autxo - > payment . value ) ) ;
return ( clonestr ( " { \" error \" : \" cant find alice utxo that is small enough \" } " ) ) ;
return ( clonestr ( " { \" error \" : \" cant find alice utxo that is small enough \" } " ) ) ;
}
}
bestsatoshis = LP_basesatoshis ( dstr ( destsatoshis ) , maxprice , txfee , desttxfee ) ;
memset ( & B , 0 , sizeof ( B ) ) ;
strcpy ( B . coin , base ) ;
if ( LP_quoteinfoinit ( & Q , & B , rel , maxprice , bestsatoshis , destsatoshis ) < 0 )
return ( clonestr ( " { \" error \" : \" cant set ordermatch quote \" } " ) ) ;
if ( LP_quotedestinfo ( & Q , autxo - > payment . txid , autxo - > payment . vout , autxo - > fee . txid , autxo - > fee . vout , G . LP_mypub25519 , autxo - > coinaddr ) < 0 )
return ( clonestr ( " { \" error \" : \" cant set ordermatch quote info \" } " ) ) ;
int32_t changed ;
LP_mypriceset ( & changed , autxo - > coin , base , 1. / maxprice ) ;
return ( LP_trade ( ctx , myipaddr , mypubsock , & Q , maxprice , timeout , duration , tradeid ) ) ;
LP_RTmetrics_update ( base , rel ) ;
LP_RTmetrics_update ( base , rel ) ;
while ( 1 )
while ( 1 )
{
{