/******************************************************************************
* Copyright © 2014 - 2018 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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//
// LP_swap.c
// marketmaker
//
// included from basilisk.c
/* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271
https : //bitcointalk.org/index.php?topic=1364951
Tier Nolan ' s approach is followed with the following changes :
a ) instead of cutting 1000 keypairs , only INSTANTDEX_DECKSIZE are a
b ) instead of sending the entire 256 bits , it is truncated to 64 bits . With odds of collision being so low , it is dwarfed by the ~ 0.1 % insurance factor .
c ) D is set to ~ 100 x the insurance rate of 1 / 777 12.87 % + BTC amount
d ) insurance is added to Bob ' s payment , which is after the deposit and bailin
e ) BEFORE Bob broadcasts deposit , Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed
*/
/*
both fees are standard payments : OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG
Bob deposit :
OP_IF
< now + LOCKTIME * 2 > OP_CLTV OP_DROP < alice_pubA0 > OP_CHECKSIG
OP_ELSE
OP_HASH160 < hash ( bob_privN ) > OP_EQUALVERIFY < bob_pubB0 > OP_CHECKSIG
OP_ENDIF
Alice altpayment : OP_2 < alice_pubM > < bob_pubN > OP_2 OP_CHECKMULTISIG
Bob paytx :
OP_IF
< now + LOCKTIME > OP_CLTV OP_DROP < bob_pubB1 > OP_CHECKSIG
OP_ELSE
OP_HASH160 < hash ( alice_privM ) > OP_EQUALVERIFY < alice_pubA0 > OP_CHECKSIG
OP_ENDIF
Naming convention are pubAi are alice ' s pubkeys ( seems only pubA0 and not pubA1 )
pubBi are Bob ' s pubkeys
privN is Bob ' s privkey from the cut and choose deck as selected by Alice
privM is Alice ' s counterpart
pubN and pubM are the corresponding pubkeys for these chosen privkeys
Alice timeout event is triggered if INSTANTDEX_LOCKTIME elapses from the start of a FSM instance . Bob timeout event is triggered after INSTANTDEX_LOCKTIME * 2
Based on https : //gist.github.com/markblundeberg/7a932c98179de2190049f5823907c016 and to enable bob to spend alicepayment when alice does a claim for bob deposit, the scripts are changed to the following:
Bob deposit :
OP_IF
OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 < hash ( alice_privM ) > OP_EQUALVERIFY < now + INSTANTDEX_LOCKTIME * 2 > OP_CLTV OP_DROP < alice_pubA0 > OP_CHECKSIG
OP_ELSE
OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 < hash ( bob_privN ) > OP_EQUALVERIFY < bob_pubB0 > OP_CHECKSIG
OP_ENDIF
Bob paytx :
OP_IF
< now + INSTANTDEX_LOCKTIME > OP_CLTV OP_DROP < bob_pubB1 > OP_CHECKSIG
OP_ELSE
OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 < hash ( alice_privM ) > OP_EQUALVERIFY < alice_pubA0 > OP_CHECKSIG
OP_ENDIF
*/
/*
Bob sends bobdeposit and waits for alicepayment to confirm before sending bobpayment
Alice waits for bobdeposit to confirm and sends alicepayment
Alice spends bobpayment immediately divulging privAm
Bob spends alicepayment immediately after getting privAm and divulges privBn
Bob will spend bobdeposit after end of trade or INSTANTDEX_LOCKTIME , divulging privBn
Alice spends alicepayment as soon as privBn is seen
Bob will spend bobpayment after INSTANTDEX_LOCKTIME
Alice spends bobdeposit in 2 * INSTANTDEX_LOCKTIME
*/
//Bobdeposit includes a covered put option for alicecoin, duration INSTANTDEX_LOCKTIME
//alicepayment includes a covered call option for alicecoin, duration (2*INSTANTDEX_LOCKTIME - elapsed)
/* in case of following states, some funds remain unclaimable, but all identified cases are due to one or both sides not spending when they were the only eligible party:
Bob failed to claim deposit during exclusive period and since alice put in the claim , the alicepayment is unspendable . if alice is nice , she can send privAm to Bob .
Apaymentspent . ( 0000000000000000000000000000000000000000000000000000000000000000 ) alice .0 bob .0
paymentspent . ( f91da4e001360b95276448e7b01904d9ee4d15862c5af7f5c7a918df26030315 ) alice .0 bob .1
depositspent . ( f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add ) alice .1 bob .0
*/
# define TX_WAIT_TIMEOUT 1800 // hard to increase this without hitting protocol limits (2/4 hrs)
uint32_t LP_atomic_locktime ( char * base , char * rel )
{
if ( strcmp ( base , " BTC " ) = = 0 & & strcmp ( rel , " BTC " ) = = 0 )
return ( INSTANTDEX_LOCKTIME * 10 ) ;
else if ( LP_is_slowcoin ( base ) > 0 | | LP_is_slowcoin ( rel ) > 0 )
return ( INSTANTDEX_LOCKTIME * 4 ) ;
else return ( INSTANTDEX_LOCKTIME ) ;
}
void basilisk_rawtx_purge ( struct basilisk_rawtx * rawtx )
{
if ( rawtx - > vins ! = 0 )
free_json ( rawtx - > vins ) , rawtx - > vins = 0 ;
//if ( rawtx->txbytes != 0 )
// free(rawtx->txbytes), rawtx->txbytes = 0;
}
void basilisk_swap_finished ( struct basilisk_swap * swap )
{
/*int32_t i;
if ( swap - > utxo ! = 0 & & swap - > sentflag = = 0 )
{
LP_availableset ( swap - > utxo ) ;
swap - > utxo = 0 ;
//LP_butxo_swapfields_set(swap->utxo);
}
swap - > I . finished = ( uint32_t ) time ( NULL ) ; */
if ( swap - > I . finished = = 0 )
{
if ( swap - > I . iambob ! = 0 )
{
LP_availableset ( swap - > bobdeposit . utxotxid , swap - > bobdeposit . utxovout ) ;
LP_availableset ( swap - > bobpayment . utxotxid , swap - > bobpayment . utxovout ) ;
}
else
{
LP_availableset ( swap - > alicepayment . utxotxid , swap - > alicepayment . utxovout ) ;
LP_availableset ( swap - > myfee . utxotxid , swap - > myfee . utxovout ) ;
}
}
// save to permanent storage
basilisk_rawtx_purge ( & swap - > bobdeposit ) ;
basilisk_rawtx_purge ( & swap - > bobpayment ) ;
basilisk_rawtx_purge ( & swap - > alicepayment ) ;
basilisk_rawtx_purge ( & swap - > myfee ) ;
basilisk_rawtx_purge ( & swap - > otherfee ) ;
basilisk_rawtx_purge ( & swap - > aliceclaim ) ;
basilisk_rawtx_purge ( & swap - > alicespend ) ;
basilisk_rawtx_purge ( & swap - > bobreclaim ) ;
basilisk_rawtx_purge ( & swap - > bobspend ) ;
basilisk_rawtx_purge ( & swap - > bobrefund ) ;
basilisk_rawtx_purge ( & swap - > alicereclaim ) ;
/*for (i=0; i<swap->nummessages; i++)
if ( swap - > messages [ i ] . data ! = 0 )
free ( swap - > messages [ i ] . data ) , swap - > messages [ i ] . data = 0 ;
free ( swap - > messages ) , swap - > messages = 0 ;
swap - > nummessages = 0 ; */
if ( swap - > N . pair > = 0 )
nn_close ( swap - > N . pair ) , swap - > N . pair = - 1 ;
}
uint32_t basilisk_quoteid ( struct basilisk_request * rp )
{
struct basilisk_request R ;
R = * rp ;
R . unused = R . requestid = R . quoteid = R . DEXselector = 0 ;
return ( calc_crc32 ( 0 , ( void * ) & R , sizeof ( R ) ) ) ;
}
uint32_t basilisk_requestid ( struct basilisk_request * rp )
{
struct basilisk_request R ;
R = * rp ;
R . requestid = R . quoteid = R . quotetime = R . DEXselector = 0 ;
R . destamount = R . unused = 0 ;
memset ( R . desthash . bytes , 0 , sizeof ( R . desthash . bytes ) ) ;
if ( 0 )
{
int32_t i ;
for ( i = 0 ; i < sizeof ( R ) ; i + + )
printf ( " %02x " , ( ( uint8_t * ) & R ) [ i ] ) ;
printf ( " <- crc.%u \n " , calc_crc32 ( 0 , ( void * ) & R , sizeof ( R ) ) ) ;
char str [ 65 ] , str2 [ 65 ] ; printf ( " B REQUESTID: t.%u r.%u q.%u %s %.8f %s -> %s %.8f %s crc.%u q%u \n " , R . timestamp , R . requestid , R . quoteid , R . src , dstr ( R . srcamount ) , bits256_str ( str , R . srchash ) , R . dest , dstr ( R . destamount ) , bits256_str ( str2 , R . desthash ) , calc_crc32 ( 0 , ( void * ) & R , sizeof ( R ) ) , basilisk_quoteid ( & R ) ) ;
}
return ( calc_crc32 ( 0 , ( void * ) & R , sizeof ( R ) ) ) ;
}
int32_t LP_pubkeys_data ( struct basilisk_swap * swap , uint8_t * data , int32_t maxlen )
{
int32_t i , datalen = 0 ;
datalen + = iguana_rwnum ( 1 , & data [ datalen ] , sizeof ( swap - > I . req . requestid ) , & swap - > I . req . requestid ) ;
datalen + = iguana_rwnum ( 1 , & data [ datalen ] , sizeof ( swap - > I . req . quoteid ) , & swap - > I . req . quoteid ) ;
data [ datalen + + ] = swap - > I . aliceconfirms ;
data [ datalen + + ] = swap - > I . bobconfirms ;
data [ datalen + + ] = swap - > I . alicemaxconfirms ;
data [ datalen + + ] = swap - > I . bobmaxconfirms ;
data [ datalen + + ] = swap - > I . otheristrusted ;
for ( i = 0 ; i < 33 ; i + + )
data [ datalen + + ] = swap - > persistent_pubkey33 [ i ] ;
for ( i = 0 ; i < sizeof ( swap - > deck ) / sizeof ( swap - > deck [ 0 ] [ 0 ] ) ; i + + )
datalen + = iguana_rwnum ( 1 , & data [ datalen ] , sizeof ( swap - > deck [ i > > 1 ] [ i & 1 ] ) , & swap - > deck [ i > > 1 ] [ i & 1 ] ) ;
//printf("send >>>>>>>>> r.%u q.%u datalen.%d\n",swap->I.req.requestid,swap->I.req.quoteid,datalen);
return ( datalen ) ;
}
int32_t LP_pubkeys_verify ( struct basilisk_swap * swap , uint8_t * data , int32_t datalen )
{
uint32_t requestid , quoteid ; int32_t i , nonz = 0 , alicemaxconfirms , bobmaxconfirms , aliceconfirms , bobconfirms , len = 0 ; uint8_t other33 [ 33 ] ;
if ( datalen = = sizeof ( swap - > otherdeck ) + 38 + sizeof ( uint32_t ) * 2 )
{
len + = iguana_rwnum ( 0 , & data [ len ] , sizeof ( requestid ) , & requestid ) ;
len + = iguana_rwnum ( 0 , & data [ len ] , sizeof ( quoteid ) , & quoteid ) ;
if ( requestid ! = swap - > I . req . requestid | | quoteid ! = swap - > I . req . quoteid )
{
printf ( " SWAP requestid.%u quoteid.%u mismatch received r.%u q.%u \n " , swap - > I . req . requestid , swap - > I . req . quoteid , requestid , quoteid ) ;
return ( - 1 ) ;
}
aliceconfirms = data [ len + + ] ;
bobconfirms = data [ len + + ] ;
alicemaxconfirms = data [ len + + ] ;
bobmaxconfirms = data [ len + + ] ;
if ( aliceconfirms ! = swap - > I . aliceconfirms | | bobconfirms ! = swap - > I . bobconfirms )
{
printf ( " MISMATCHED required confirms me.(%d %d) vs (%d %d) max.(%d %d) othermax.(%d %d) \n " , swap - > I . aliceconfirms , swap - > I . bobconfirms , aliceconfirms , bobconfirms , swap - > I . alicemaxconfirms , swap - > I . bobmaxconfirms , alicemaxconfirms , bobmaxconfirms ) ;
if ( alicemaxconfirms > swap - > I . alicemaxconfirms )
alicemaxconfirms = swap - > I . alicemaxconfirms ;
if ( bobmaxconfirms > swap - > I . bobmaxconfirms )
bobmaxconfirms = swap - > I . bobmaxconfirms ;
if ( swap - > I . aliceconfirms < aliceconfirms )
swap - > I . aliceconfirms = aliceconfirms ;
if ( swap - > I . bobconfirms < bobconfirms )
swap - > I . bobconfirms = bobconfirms ;
if ( swap - > I . aliceconfirms > swap - > I . alicemaxconfirms | | swap - > I . bobconfirms > swap - > I . bobmaxconfirms )
{
printf ( " numconfirms (%d %d) exceeds max (%d %d) \n " , swap - > I . aliceconfirms , swap - > I . bobconfirms , swap - > I . alicemaxconfirms , swap - > I . bobmaxconfirms ) ;
return ( - 1 ) ;
}
}
if ( ( swap - > I . otherstrust = data [ len + + ] ) ! = 0 )
{
if ( swap - > I . otheristrusted ! = 0 )
{
swap - > I . aliceconfirms = swap - > I . bobconfirms = 0 ;
printf ( " mutually trusted swap, adjust required confirms to: alice.%d bob.%d \n " , swap - > I . aliceconfirms , swap - > I . bobconfirms ) ;
}
}
printf ( " NUMCONFIRMS for SWAP alice.%d bob.%d, otheristrusted.%d othertrusts.%d \n " , swap - > I . aliceconfirms , swap - > I . bobconfirms , swap - > I . otheristrusted , swap - > I . otherstrust ) ;
for ( i = 0 ; i < 33 ; i + + )
if ( ( other33 [ i ] = data [ len + + ] ) ! = 0 )
nonz + + ;
if ( nonz > 8 )
memcpy ( swap - > persistent_other33 , other33 , 33 ) ;
for ( i = 0 ; i < sizeof ( swap - > otherdeck ) / sizeof ( swap - > otherdeck [ 0 ] [ 0 ] ) ; i + + )
len + = iguana_rwnum ( 0 , & data [ len ] , sizeof ( swap - > otherdeck [ i > > 1 ] [ i & 1 ] ) , & swap - > otherdeck [ i > > 1 ] [ i & 1 ] ) ;
return ( 0 ) ;
}
printf ( " pubkeys verify size mismatch %d != %d \n " , datalen , ( int32_t ) ( sizeof ( swap - > otherdeck ) + 38 + sizeof ( uint32_t ) * 2 ) ) ;
return ( - 1 ) ;
}
int32_t LP_choosei_data ( struct basilisk_swap * swap , uint8_t * data , int32_t maxlen )
{
int32_t i , datalen ; //char str[65];
datalen = iguana_rwnum ( 1 , data , sizeof ( swap - > I . choosei ) , & swap - > I . choosei ) ;
if ( swap - > I . iambob ! = 0 )
{
for ( i = 0 ; i < 32 ; i + + )
data [ datalen + + ] = swap - > I . pubB0 . bytes [ i ] ;
for ( i = 0 ; i < 32 ; i + + )
data [ datalen + + ] = swap - > I . pubB1 . bytes [ i ] ;
//printf("SEND pubB0/1 %s\n",bits256_str(str,swap->I.pubB0));
}
else
{
for ( i = 0 ; i < 32 ; i + + )
data [ datalen + + ] = swap - > I . pubA0 . bytes [ i ] ;
for ( i = 0 ; i < 32 ; i + + )
data [ datalen + + ] = swap - > I . pubA1 . bytes [ i ] ;
//printf("SEND pubA0/1 %s\n",bits256_str(str,swap->I.pubA0));
}
return ( datalen ) ;
}
int32_t LP_choosei_verify ( struct basilisk_swap * swap , uint8_t * data , int32_t datalen )
{
int32_t otherchoosei = - 1 , i , len = 0 ; uint8_t pubkey33 [ 33 ] ;
if ( datalen = = sizeof ( otherchoosei ) + sizeof ( bits256 ) * 2 )
{
len + = iguana_rwnum ( 0 , data , sizeof ( otherchoosei ) , & otherchoosei ) ;
if ( otherchoosei > = 0 & & otherchoosei < INSTANTDEX_DECKSIZE )
{
swap - > I . otherchoosei = otherchoosei ;
if ( swap - > I . iambob ! = 0 )
{
for ( i = 0 ; i < 32 ; i + + )
swap - > I . pubA0 . bytes [ i ] = data [ len + + ] ;
for ( i = 0 ; i < 32 ; i + + )
swap - > I . pubA1 . bytes [ i ] = data [ len + + ] ;
//printf("GOT pubA0/1 %s\n",bits256_str(str,swap->I.pubA0));
swap - > I . privBn = swap - > privkeys [ swap - > I . otherchoosei ] ;
memset ( & swap - > privkeys [ swap - > I . otherchoosei ] , 0 , sizeof ( swap - > privkeys [ swap - > I . otherchoosei ] ) ) ;
revcalc_rmd160_sha256 ( swap - > I . secretBn , swap - > I . privBn ) ; //.bytes,sizeof(swap->privBn));
vcalc_sha256 ( 0 , swap - > I . secretBn256 , swap - > I . privBn . bytes , sizeof ( swap - > I . privBn ) ) ;
swap - > I . pubBn = bitcoin_pubkey33 ( swap - > ctx , pubkey33 , swap - > I . privBn ) ;
//printf("set privBn.%s %s\n",bits256_str(str,swap->I.privBn),bits256_str(str2,*(bits256 *)swap->I.secretBn256));
//basilisk_bobscripts_set(swap,1,1);
}
else
{
for ( i = 0 ; i < 32 ; i + + )
swap - > I . pubB0 . bytes [ i ] = data [ len + + ] ;
for ( i = 0 ; i < 32 ; i + + )
swap - > I . pubB1 . bytes [ i ] = data [ len + + ] ;
//printf("GOT pubB0/1 %s\n",bits256_str(str,swap->I.pubB0));
swap - > I . privAm = swap - > privkeys [ swap - > I . otherchoosei ] ;
memset ( & swap - > privkeys [ swap - > I . otherchoosei ] , 0 , sizeof ( swap - > privkeys [ swap - > I . otherchoosei ] ) ) ;
revcalc_rmd160_sha256 ( swap - > I . secretAm , swap - > I . privAm ) ; //.bytes,sizeof(swap->privAm));
vcalc_sha256 ( 0 , swap - > I . secretAm256 , swap - > I . privAm . bytes , sizeof ( swap - > I . privAm ) ) ;
swap - > I . pubAm = bitcoin_pubkey33 ( swap - > ctx , pubkey33 , swap - > I . privAm ) ;
//printf("set privAm.%s %s\n",bits256_str(str,swap->I.privAm),bits256_str(str2,*(bits256 *)swap->I.secretAm256));
swap - > bobdeposit . I . pubkey33 [ 0 ] = 2 ;
swap - > bobpayment . I . pubkey33 [ 0 ] = 2 ;
for ( i = 0 ; i < 32 ; i + + )
swap - > bobpayment . I . pubkey33 [ i + 1 ] = swap - > bobdeposit . I . pubkey33 [ i + 1 ] = swap - > I . pubA0 . bytes [ i ] ;
//printf("SET bobdeposit pubkey33.(02%s)\n",bits256_str(str,swap->I.pubA0));
//basilisk_bobscripts_set(swap,0);
}
return ( 0 ) ;
}
}
printf ( " illegal otherchoosei.%d datalen.%d vs %d \n " , otherchoosei , datalen , ( int32_t ) ( sizeof ( otherchoosei ) + sizeof ( bits256 ) * 2 ) ) ;
return ( - 1 ) ;
}
int32_t LP_mostprivs_data ( struct basilisk_swap * swap , uint8_t * data , int32_t maxlen )
{
int32_t i , j , datalen ;
datalen = 0 ;
for ( i = 0 ; i < sizeof ( swap - > privkeys ) / sizeof ( * swap - > privkeys ) ; i + + )
{
for ( j = 0 ; j < 32 ; j + + )
data [ datalen + + ] = ( i = = swap - > I . otherchoosei ) ? 0 : swap - > privkeys [ i ] . bytes [ j ] ;
}
if ( swap - > I . iambob ! = 0 )
{
for ( i = 0 ; i < 32 ; i + + )
data [ datalen + + ] = swap - > I . pubBn . bytes [ i ] ;
for ( i = 0 ; i < 20 ; i + + )
data [ datalen + + ] = swap - > I . secretBn [ i ] ;
for ( i = 0 ; i < 32 ; i + + )
data [ datalen + + ] = swap - > I . secretBn256 [ i ] ;
}
else
{
for ( i = 0 ; i < 32 ; i + + )
data [ datalen + + ] = swap - > I . pubAm . bytes [ i ] ;
for ( i = 0 ; i < 20 ; i + + )
data [ datalen + + ] = swap - > I . secretAm [ i ] ;
for ( i = 0 ; i < 32 ; i + + )
data [ datalen + + ] = swap - > I . secretAm256 [ i ] ;
}
return ( datalen ) ;
}
int32_t basilisk_verify_pubpair ( int32_t * wrongfirstbytep , struct basilisk_swap * swap , int32_t ind , uint8_t pub0 , bits256 pubi , uint64_t txid )
{
if ( pub0 ! = ( swap - > I . iambob ^ 1 ) + 0x02 )
{
( * wrongfirstbytep ) + + ;
printf ( " wrongfirstbyte[%d] %02x \n " , ind , pub0 ) ;
return ( - 1 ) ;
}
else if ( swap - > otherdeck [ ind ] [ 1 ] ! = pubi . txid )
{
printf ( " otherdeck[%d] priv ->pub mismatch %llx != %llx \n " , ind , ( long long ) swap - > otherdeck [ ind ] [ 1 ] , ( long long ) pubi . txid ) ;
return ( - 1 ) ;
}
else if ( swap - > otherdeck [ ind ] [ 0 ] ! = txid )
{
printf ( " otherdeck[%d] priv mismatch %llx != %llx \n " , ind , ( long long ) swap - > otherdeck [ ind ] [ 0 ] , ( long long ) txid ) ;
return ( - 1 ) ;
}
return ( 0 ) ;
}
int32_t basilisk_verify_privi ( void * ptr , uint8_t * data , int32_t datalen )
{
int32_t j , wrongfirstbyte , len = 0 ; bits256 privkey , pubi ; char str [ 65 ] , str2 [ 65 ] ; uint8_t secret160 [ 20 ] , pubkey33 [ 33 ] ; uint64_t txid ; struct basilisk_swap * swap = ptr ;
memset ( privkey . bytes , 0 , sizeof ( privkey ) ) ;
if ( datalen = = sizeof ( bits256 ) )
{
for ( j = 0 ; j < 32 ; j + + )
privkey . bytes [ j ] = data [ len + + ] ;
revcalc_rmd160_sha256 ( secret160 , privkey ) ; //.bytes,sizeof(privkey));
memcpy ( & txid , secret160 , sizeof ( txid ) ) ;
pubi = bitcoin_pubkey33 ( swap - > ctx , pubkey33 , privkey ) ;
if ( basilisk_verify_pubpair ( & wrongfirstbyte , swap , swap - > I . choosei , pubkey33 [ 0 ] , pubi , txid ) = = 0 )
{
if ( swap - > I . iambob ! = 0 )
{
swap - > I . privAm = privkey ;
vcalc_sha256 ( 0 , swap - > I . secretAm256 , privkey . bytes , sizeof ( privkey ) ) ;
printf ( " set privAm.%s %s \n " , bits256_str ( str , swap - > I . privAm ) , bits256_str ( str2 , * ( bits256 * ) swap - > I . secretAm256 ) ) ;
basilisk_bobscripts_set ( swap , 0 , 1 ) ;
}
else
{
swap - > I . privBn = privkey ;
vcalc_sha256 ( 0 , swap - > I . secretBn256 , privkey . bytes , sizeof ( privkey ) ) ;
printf ( " set privBn.%s %s \n " , bits256_str ( str , swap - > I . privBn ) , bits256_str ( str2 , * ( bits256 * ) swap - > I . secretBn256 ) ) ;
}
basilisk_dontforget_update ( swap , 0 ) ;
char str [ 65 ] ; printf ( " privi verified.(%s) \n " , bits256_str ( str , privkey ) ) ;
return ( 0 ) ;
} else printf ( " pubpair doesnt verify privi \n " ) ;
} else printf ( " verify privi size mismatch %d != %d \n " , datalen , ( int32_t ) sizeof ( bits256 ) ) ;
return ( - 1 ) ;
}
int32_t LP_mostprivs_verify ( struct basilisk_swap * swap , uint8_t * data , int32_t datalen )
{
int32_t i , j , wrongfirstbyte = 0 , errs = 0 , len = 0 ; bits256 otherpriv , pubi ; uint8_t secret160 [ 20 ] , otherpubkey [ 33 ] ; uint64_t txid ;
//printf("verify privkeys choosei.%d otherchoosei.%d datalen.%d vs %d\n",swap->choosei,swap->otherchoosei,datalen,(int32_t)sizeof(swap->privkeys)+20+32);
memset ( otherpriv . bytes , 0 , sizeof ( otherpriv ) ) ;
if ( swap - > I . cutverified = = 0 & & swap - > I . otherchoosei > = 0 & & datalen = = sizeof ( swap - > privkeys ) + 20 + 2 * 32 )
{
for ( i = errs = 0 ; i < sizeof ( swap - > privkeys ) / sizeof ( * swap - > privkeys ) ; i + + )
{
for ( j = 0 ; j < 32 ; j + + )
otherpriv . bytes [ j ] = data [ len + + ] ;
if ( i ! = swap - > I . choosei )
{
pubi = bitcoin_pubkey33 ( swap - > ctx , otherpubkey , otherpriv ) ;
revcalc_rmd160_sha256 ( secret160 , otherpriv ) ; //.bytes,sizeof(otherpriv));
memcpy ( & txid , secret160 , sizeof ( txid ) ) ;
errs + = basilisk_verify_pubpair ( & wrongfirstbyte , swap , i , otherpubkey [ 0 ] , pubi , txid ) ;
}
}
if ( errs = = 0 & & wrongfirstbyte = = 0 )
{
swap - > I . cutverified = 1 , printf ( " CUT VERIFIED \n " ) ;
if ( swap - > I . iambob ! = 0 )
{
for ( i = 0 ; i < 32 ; i + + )
swap - > I . pubAm . bytes [ i ] = data [ len + + ] ;
for ( i = 0 ; i < 20 ; i + + )
swap - > I . secretAm [ i ] = data [ len + + ] ;
for ( i = 0 ; i < 32 ; i + + )
swap - > I . secretAm256 [ i ] = data [ len + + ] ;
//basilisk_bobscripts_set(swap,1,1);
}
else
{
for ( i = 0 ; i < 32 ; i + + )
swap - > I . pubBn . bytes [ i ] = data [ len + + ] ;
for ( i = 0 ; i < 20 ; i + + )
swap - > I . secretBn [ i ] = data [ len + + ] ;
for ( i = 0 ; i < 32 ; i + + )
swap - > I . secretBn256 [ i ] = data [ len + + ] ;
//basilisk_bobscripts_set(swap,0);
}
} else printf ( " failed verification: wrong firstbyte.%d errs.%d \n " , wrongfirstbyte , errs ) ;
}
//printf("privkeys errs.%d wrongfirstbyte.%d\n",errs,wrongfirstbyte);
return ( errs ) ;
}
int32_t LP_waitfor ( int32_t pairsock , struct basilisk_swap * swap , int32_t timeout , int32_t ( * verify ) ( struct basilisk_swap * swap , uint8_t * data , int32_t datalen ) )
{
struct nn_pollfd pfd ; void * data ; int32_t datalen , retval = - 1 ; uint32_t expiration = ( uint32_t ) time ( NULL ) + timeout ;
while ( time ( NULL ) < expiration )
{
memset ( & pfd , 0 , sizeof ( pfd ) ) ;
pfd . fd = pairsock ;
pfd . events = NN_POLLIN ;
if ( nn_poll ( & pfd , 1 , 1 ) > 0 )
{
//printf("start wait\n");
if ( ( datalen = nn_recv ( pairsock , & data , NN_MSG , 0 ) ) > = 0 )
{
//printf("wait for got.%d\n",datalen);
retval = ( * verify ) ( swap , data , datalen ) ;
swap - > received = ( uint32_t ) time ( NULL ) ;
nn_freemsg ( data ) ;
//printf("retval.%d\n",retval);
return ( retval ) ;
} // else printf("error nn_recv\n");
}
}
printf ( " waitfor timedout aliceid.%llu requestid.%u quoteid.%u \n " , ( long long ) swap - > aliceid , swap - > I . req . requestid , swap - > I . req . quoteid ) ;
return ( retval ) ;
}
int32_t swap_nn_send ( int32_t sock , uint8_t * data , int32_t datalen , uint32_t flags , int32_t timeout )
{
struct nn_pollfd pfd ; int32_t i ;
for ( i = 0 ; i < timeout * 1000 ; i + + )
{
memset ( & pfd , 0 , sizeof ( pfd ) ) ;
pfd . fd = sock ;
pfd . events = NN_POLLOUT ;
if ( nn_poll ( & pfd , 1 , 1 ) > 0 )
return ( nn_send ( sock , data , datalen , flags ) ) ;
usleep ( 1000 ) ;
}
return ( - 1 ) ;
}
int32_t LP_waitsend ( char * statename , int32_t timeout , int32_t pairsock , struct basilisk_swap * swap , uint8_t * data , int32_t maxlen , int32_t ( * verify ) ( struct basilisk_swap * swap , uint8_t * data , int32_t datalen ) , int32_t ( * datagen ) ( struct basilisk_swap * swap , uint8_t * data , int32_t maxlen ) )
{
int32_t datalen , sendlen , retval = - 1 ;
//printf("waitsend.%s timeout.%d\n",statename,timeout);
if ( LP_waitfor ( pairsock , swap , timeout , verify ) = = 0 )
{
//printf("waited for %s\n",statename);
if ( ( datalen = ( * datagen ) ( swap , data , maxlen ) ) > 0 )
{
if ( ( sendlen = swap_nn_send ( pairsock , data , datalen , 0 , timeout ) ) = = datalen )
{
//printf("sent.%d after waitfor.%s\n",sendlen,statename);
retval = 0 ;
} else printf ( " send %s error \n " , statename ) ;
} else printf ( " %s datagen no data \n " , statename ) ;
} else printf ( " didnt get valid data after %d \n " , timeout ) ;
return ( retval ) ;
}
int32_t LP_sendwait ( char * statename , int32_t timeout , int32_t pairsock , struct basilisk_swap * swap , uint8_t * data , int32_t maxlen , int32_t ( * verify ) ( struct basilisk_swap * swap , uint8_t * data , int32_t datalen ) , int32_t ( * datagen ) ( struct basilisk_swap * swap , uint8_t * data , int32_t maxlen ) )
{
int32_t datalen , sendlen , retval = - 1 ;
//printf("sendwait.%s\n",statename);
if ( ( datalen = ( * datagen ) ( swap , data , maxlen ) ) > 0 )
{
//printf("generated %d for %s, timeout.%d\n",datalen,statename,timeout);
if ( ( sendlen = swap_nn_send ( pairsock , data , datalen , 0 , timeout ) ) = = datalen )
{
//printf("sendwait.%s sent %d\n",statename,sendlen);
if ( LP_waitfor ( pairsock , swap , timeout , verify ) = = 0 )
{
//printf("waited! sendwait.%s sent %d\n",statename,sendlen);
retval = 0 ;
} else printf ( " didnt get %s \n " , statename ) ;
} else printf ( " send %s error \n " , statename ) ;
} else printf ( " no datagen for %s \n " , statename ) ;
return ( retval ) ;
}
void LP_swapsfp_update ( uint32_t requestid , uint32_t quoteid )
{
static FILE * swapsfp ;
portable_mutex_lock ( & LP_listmutex ) ;
if ( swapsfp = = 0 )
{
char fname [ 512 ] ;
sprintf ( fname , " %s/SWAPS/list " , GLOBAL_DBDIR ) , OS_compatible_path ( fname ) ;
if ( ( swapsfp = fopen ( fname , " rb+ " ) ) = = 0 )
swapsfp = fopen ( fname , " wb+ " ) ;
else fseek ( swapsfp , 0 , SEEK_END ) ;
//printf("LIST fp.%p\n",swapsfp);
}
if ( swapsfp ! = 0 )
{
fwrite ( & requestid , 1 , sizeof ( requestid ) , swapsfp ) ;
fwrite ( & quoteid , 1 , sizeof ( quoteid ) , swapsfp ) ;
fflush ( swapsfp ) ;
}
portable_mutex_unlock ( & LP_listmutex ) ;
}
struct basilisk_rawtx * LP_swapdata_rawtx ( struct basilisk_swap * swap , uint8_t * data , int32_t maxlen , struct basilisk_rawtx * rawtx )
{
if ( rawtx - > I . datalen ! = 0 & & rawtx - > I . datalen < = maxlen )
{
memcpy ( data , rawtx - > txbytes , rawtx - > I . datalen ) ;
return ( rawtx ) ;
}
printf ( " swapdata rawtx has null txbytes \n " ) ;
return ( 0 ) ;
}
int32_t LP_rawtx_spendscript ( struct basilisk_swap * swap , int32_t height , struct basilisk_rawtx * rawtx , int32_t v , uint8_t * recvbuf , int32_t recvlen , int32_t suppress_pubkeys )
{
bits256 otherhash , myhash , txid ; int64_t txfee , val ; int32_t i , offset = 0 , datalen = 0 , retval = - 1 , hexlen , n ; uint8_t * data ; cJSON * txobj , * skey , * vouts , * vout ; char * hexstr , bobstr [ 65 ] , alicestr [ 65 ] , redeemaddr [ 64 ] , checkaddr [ 64 ] ; uint32_t quoteid , msgbits ; struct iguana_info * coin ;
LP_etomicsymbol ( bobstr , swap - > I . bobtomic , swap - > I . bobstr ) ;
LP_etomicsymbol ( alicestr , swap - > I . alicetomic , swap - > I . alicestr ) ;
if ( ( coin = LP_coinfind ( rawtx - > symbol ) ) = = 0 )
{
printf ( " LP_rawtx_spendscript couldnt find coin.(%s) \n " , rawtx - > symbol ) ;
return ( - 1 ) ;
}
for ( i = 0 ; i < 32 ; i + + )
otherhash . bytes [ i ] = recvbuf [ offset + + ] ;
for ( i = 0 ; i < 32 ; i + + )
myhash . bytes [ i ] = recvbuf [ offset + + ] ;
offset + = iguana_rwnum ( 0 , & recvbuf [ offset ] , sizeof ( quoteid ) , & quoteid ) ;
offset + = iguana_rwnum ( 0 , & recvbuf [ offset ] , sizeof ( msgbits ) , & msgbits ) ;
datalen = recvbuf [ offset + + ] ;
datalen + = ( int32_t ) recvbuf [ offset + + ] < < 8 ;
if ( datalen > 1024 )
{
printf ( " LP_rawtx_spendscript %s datalen.%d too big \n " , rawtx - > name , datalen ) ;
return ( - 1 ) ;
}
rawtx - > I . redeemlen = recvbuf [ offset + + ] ;
# ifndef NOTETOMIC
uint8arrayToHex ( rawtx - > I . ethTxid , & recvbuf [ offset ] , 32 ) ;
printf ( " ETH txid received: %s \n " , rawtx - > I . ethTxid ) ;
# endif
offset + = 32 ;
data = & recvbuf [ offset ] ;
if ( rawtx - > I . redeemlen > 0 & & rawtx - > I . redeemlen < 0x100 )
{
memcpy ( rawtx - > redeemscript , & data [ datalen ] , rawtx - > I . redeemlen ) ;
//for (i=0; i<rawtx->I.redeemlen; i++)
// printf("%02x",rawtx->redeemscript[i]);
bitcoin_address ( coin - > symbol , redeemaddr , coin - > taddr , coin - > p2shtype , rawtx - > redeemscript , rawtx - > I . redeemlen ) ;
//printf(" received redeemscript.(%s) %s taddr.%d\n",redeemaddr,coin->symbol,coin->taddr);
LP_swap_coinaddr ( coin , checkaddr , 0 , data , datalen , 0 ) ;
if ( strcmp ( redeemaddr , checkaddr ) ! = 0 )
{
printf ( " REDEEMADDR MISMATCH??? %s != %s \n " , redeemaddr , checkaddr ) ;
return ( - 1 ) ;
}
}
//printf("recvlen.%d datalen.%d redeemlen.%d\n",recvlen,datalen,rawtx->redeemlen);
if ( rawtx - > I . datalen = = 0 )
{
//for (i=0; i<datalen; i++)
// printf("%02x",data[i]);
//printf(" <- received\n");
memcpy ( rawtx - > txbytes , data , datalen ) ;
rawtx - > I . datalen = datalen ;
}
else if ( datalen ! = rawtx - > I . datalen | | memcmp ( rawtx - > txbytes , data , datalen ) ! = 0 )
{
for ( i = 0 ; i < rawtx - > I . datalen ; i + + )
printf ( " %02x " , rawtx - > txbytes [ i ] ) ;
printf ( " <- rawtx \n " ) ;
printf ( " %s rawtx data compare error, len %d vs %d <<<<<<<<<< warning \n " , rawtx - > name , rawtx - > I . datalen , datalen ) ;
return ( - 1 ) ;
}
if ( recvlen ! = datalen + rawtx - > I . redeemlen + 107 )
printf ( " RECVLEN %d != %d + %d \n " , recvlen , datalen , rawtx - > I . redeemlen ) ;
txid = bits256_calctxid ( coin - > symbol , data , datalen ) ;
//char str[65]; printf("rawtx.%s txid %s\n",rawtx->name,bits256_str(str,txid));
if ( bits256_cmp ( txid , rawtx - > I . actualtxid ) ! = 0 & & bits256_nonz ( rawtx - > I . actualtxid ) = = 0 )
rawtx - > I . actualtxid = txid ;
if ( ( txobj = bitcoin_data2json ( coin - > symbol , coin - > taddr , coin - > pubtype , coin - > p2shtype , coin - > isPoS , height , & rawtx - > I . signedtxid , & rawtx - > msgtx , rawtx - > extraspace , sizeof ( rawtx - > extraspace ) , data , datalen , 0 , suppress_pubkeys , coin - > zcash ) ) ! = 0 )
{
rawtx - > I . actualtxid = rawtx - > I . signedtxid ;
rawtx - > I . locktime = rawtx - > msgtx . lock_time ;
if ( ( vouts = jarray ( & n , txobj , " vout " ) ) ! = 0 & & v < n )
{
vout = jitem ( vouts , v ) ;
if ( strcmp ( " BTC " , coin - > symbol ) = = 0 & & rawtx = = & swap - > otherfee )
txfee = LP_MIN_TXFEE ;
else
{
if ( strcmp ( coin - > symbol , bobstr ) = = 0 )
txfee = swap - > I . Btxfee ;
else if ( strcmp ( coin - > symbol , alicestr ) = = 0 )
txfee = swap - > I . Atxfee ;
else txfee = LP_MIN_TXFEE ;
}
if ( rawtx - > I . amount > 2 * txfee )
val = rawtx - > I . amount - 2 * txfee ;
else val = 1 ;
if ( j64bits ( vout , " satoshis " ) > = val & & ( skey = jobj ( vout , " scriptPubKey " ) ) ! = 0 & & ( hexstr = jstr ( skey , " hex " ) ) ! = 0 )
{
if ( ( hexlen = ( int32_t ) strlen ( hexstr ) > > 1 ) < sizeof ( rawtx - > spendscript ) )
{
decode_hex ( rawtx - > spendscript , hexlen , hexstr ) ;
rawtx - > I . spendlen = hexlen ;
//if ( swap != 0 )
// basilisk_txlog(swap->myinfoptr,swap,rawtx,-1); // bobdeposit, bobpayment or alicepayment
retval = 0 ;
if ( rawtx = = & swap - > otherfee )
{
LP_swap_coinaddr ( coin , rawtx - > p2shaddr , 0 , data , datalen , 0 ) ;
//printf("got %s txid.%s (%s) -> %s\n",rawtx->name,bits256_str(str,rawtx->I.signedtxid),jprint(txobj,0),rawtx->p2shaddr);
} else bitcoin_address ( coin - > symbol , rawtx - > p2shaddr , coin - > taddr , coin - > p2shtype , rawtx - > spendscript , hexlen ) ;
}
} else printf ( " %s satoshis %.8f ERROR.(%s) txfees.[%.8f %.8f: %.8f] amount.%.8f -> %.8f \n " , rawtx - > name , dstr ( j64bits ( vout , " satoshis " ) ) , jprint ( txobj , 0 ) , dstr ( swap - > I . Atxfee ) , dstr ( swap - > I . Btxfee ) , dstr ( txfee ) , dstr ( rawtx - > I . amount ) , dstr ( rawtx - > I . amount ) - dstr ( txfee ) ) ;
}
free_json ( txobj ) ;
}
return ( retval ) ;
}
uint32_t LP_swapdata_rawtxsend ( int32_t pairsock , struct basilisk_swap * swap , uint32_t msgbits , uint8_t * data , int32_t maxlen , struct basilisk_rawtx * rawtx , uint32_t nextbits , int32_t suppress_swapsend )
{
uint8_t sendbuf [ 32768 ] ; int32_t sendlen , retval = - 1 ;
if ( LP_swapdata_rawtx ( swap , data , maxlen , rawtx ) ! = 0 )
{
if ( bits256_nonz ( rawtx - > I . signedtxid ) ! = 0 & & bits256_nonz ( rawtx - > I . actualtxid ) = = 0 )
{
basilisk_dontforget_update ( swap , rawtx ) ;
rawtx - > I . actualtxid = LP_broadcast_tx ( rawtx - > name , rawtx - > symbol , rawtx - > txbytes , rawtx - > I . datalen ) ;
if ( bits256_cmp ( rawtx - > I . actualtxid , rawtx - > I . signedtxid ) ! = 0 )
{
char str [ 65 ] , str2 [ 65 ] ;
printf ( " %s rawtxsend.[%d] %s vs %s \n " , rawtx - > name , rawtx - > I . datalen , bits256_str ( str , rawtx - > I . signedtxid ) , bits256_str ( str2 , rawtx - > I . actualtxid ) ) ;
if ( bits256_nonz ( rawtx - > I . signedtxid ) ! = 0 )
rawtx - > I . actualtxid = rawtx - > I . signedtxid ;
else rawtx - > I . signedtxid = rawtx - > I . actualtxid ;
}
if ( bits256_nonz ( rawtx - > I . actualtxid ) ! = 0 & & msgbits ! = 0 )
{
# ifndef NOTETOMIC
if ( swap - > I . bobtomic [ 0 ] ! = 0 | | swap - > I . alicetomic [ 0 ] ! = 0 )
{
char * ethTxId = sendEthTx ( swap , rawtx ) ;
if ( ethTxId ! = NULL ) {
strcpy ( rawtx - > I . ethTxid , ethTxId ) ;
free ( ethTxId ) ;
} else {
printf ( " Error sending ETH tx \n " ) ;
return ( - 1 ) ;
}
}
# endif
sendlen = 0 ;
sendbuf [ sendlen + + ] = rawtx - > I . datalen & 0xff ;
sendbuf [ sendlen + + ] = ( rawtx - > I . datalen > > 8 ) & 0xff ;
sendbuf [ sendlen + + ] = rawtx - > I . redeemlen ;
if ( rawtx - > I . ethTxid [ 0 ] ! = 0 & & strlen ( rawtx - > I . ethTxid ) = = 66 )
{
uint8_t ethTxidBytes [ 32 ] ;
// ETH txid always starts with 0x
decode_hex ( ethTxidBytes , 32 , rawtx - > I . ethTxid + 2 ) ;
memcpy ( & sendbuf [ sendlen ] , ethTxidBytes , 32 ) ;
}
else
{
// fill with zero bytes to always have fixed message size
memset ( & sendbuf [ sendlen ] , 0 , 32 ) ;
}
sendlen + = 32 ;
//int32_t z; for (z=0; z<rawtx->I.datalen; z++) printf("%02x",rawtx->txbytes[z]); printf(" >>>>>>> send.%d %s\n",rawtx->I.datalen,rawtx->name);
//printf("datalen.%d redeemlen.%d\n",rawtx->I.datalen,rawtx->I.redeemlen);
memcpy ( & sendbuf [ sendlen ] , rawtx - > txbytes , rawtx - > I . datalen ) , sendlen + = rawtx - > I . datalen ;
if ( rawtx - > I . redeemlen > 0 & & rawtx - > I . redeemlen < 0x100 )
{
memcpy ( & sendbuf [ sendlen ] , rawtx - > redeemscript , rawtx - > I . redeemlen ) ;
sendlen + = rawtx - > I . redeemlen ;
}
basilisk_dontforget_update ( swap , rawtx ) ;
//printf("sendlen.%d datalen.%d redeemlen.%d\n",sendlen,rawtx->datalen,rawtx->redeemlen);
if ( suppress_swapsend = = 0 )
{
retval = LP_swapsend ( pairsock , swap , msgbits , sendbuf , sendlen , nextbits , rawtx - > I . crcs ) ;
if ( LP_waitmempool ( rawtx - > symbol , rawtx - > I . destaddr , rawtx - > I . signedtxid , 0 , LP_SWAPSTEP_TIMEOUT * 10 ) < 0 )
{
char str [ 65 ] ; printf ( " failed to find %s %s %s in the mempool? \n " , rawtx - > name , rawtx - > I . destaddr , bits256_str ( str , rawtx - > I . actualtxid ) ) ;
retval = - 1 ;
}
return ( retval ) ;
}
else
{
printf ( " suppress swapsend %x \n " , msgbits ) ;
return ( 0 ) ;
}
}
}
return ( nextbits ) ;
} //else if ( swap->I.iambob == 0 )
printf ( " error from basilisk_swapdata_rawtx.%s %p len.%d \n " , rawtx - > name , rawtx - > txbytes , rawtx - > I . datalen ) ;
return ( 0 ) ;
}
uint32_t LP_swapwait ( uint32_t expiration , uint32_t requestid , uint32_t quoteid , int32_t duration , int32_t sleeptime )
{
char * retstr ; uint32_t finished = 0 ; cJSON * retjson = 0 ;
if ( sleeptime ! = 0 )
{
printf ( " wait %d:%d for SWAP.(r%u/q%u) to complete \n " , duration , sleeptime , requestid , quoteid ) ;
sleep ( sleeptime / 3 ) ;
}
while ( expiration = = 0 | | time ( NULL ) < expiration )
{
if ( ( retstr = basilisk_swapentry ( 0 , requestid , quoteid , 1 ) ) ! = 0 )
{
if ( ( retjson = cJSON_Parse ( retstr ) ) ! = 0 )
{
if ( jstr ( retjson , " status " ) ! = 0 & & strcmp ( jstr ( retjson , " status " ) , " finished " ) = = 0 )
{
finished = ( uint32_t ) time ( NULL ) ;
free ( retstr ) , retstr = 0 ;
break ;
}
else if ( expiration ! = 0 & & time ( NULL ) > expiration )
printf ( " NOT FINISHED.(%s) \n " , jprint ( retjson , 0 ) ) ;
free_json ( retjson ) , retjson = 0 ;
}
free ( retstr ) ;
}
if ( sleeptime ! = 0 )
sleep ( sleeptime ) ;
if ( duration < 0 )
break ;
}
if ( retjson ! = 0 )
{
free_json ( retjson ) ;
if ( ( retstr = basilisk_swapentry ( 0 , requestid , quoteid , 1 ) ) ! = 0 )
{
printf ( " \n >>>>>>>>>>>>>>>>>>>>>>>>> \n SWAP completed! %u-%u %s \n " , requestid , quoteid , retstr ) ;
free ( retstr ) ;
}
return ( finished ) ;
}
else
{
if ( expiration ! = 0 & & time ( NULL ) > expiration )
printf ( " \n SWAP did not complete! %u-%u %s \n " , requestid , quoteid , jprint ( retjson , 0 ) ) ;
if ( duration > 0 )
LP_pendswap_add ( expiration , requestid , quoteid ) ;
return ( 0 ) ;
}
}
int32_t LP_calc_waittimeout ( char * symbol )
{
int32_t waittimeout = TX_WAIT_TIMEOUT ;
if ( strcmp ( symbol , " BTC " ) = = 0 )
waittimeout * = 8 ;
else if ( LP_is_slowcoin ( symbol ) ! = 0 )
waittimeout * = 4 ;
return ( waittimeout ) ;
}
void LP_bobloop ( void * _swap )
{
uint8_t * data ; char bobstr [ 65 ] , alicestr [ 65 ] ; int32_t bobwaittimeout , alicewaittimeout , maxlen , m , n , err = 0 ; uint32_t expiration ; struct basilisk_swap * swap = _swap ;
G . LP_pendingswaps + + ;
//printf("start swap iambob\n");
LP_etomicsymbol ( bobstr , swap - > I . bobtomic , swap - > I . bobstr ) ;
LP_etomicsymbol ( alicestr , swap - > I . alicetomic , swap - > I . alicestr ) ;
maxlen = 1024 * 1024 + sizeof ( * swap ) ;
data = malloc ( maxlen ) ;
expiration = ( uint32_t ) time ( NULL ) + LP_SWAPSTEP_TIMEOUT ;
bobwaittimeout = LP_calc_waittimeout ( bobstr ) ;
alicewaittimeout = LP_calc_waittimeout ( alicestr ) ;
# ifndef NOTETOMIC
if ( swap - > I . bobtomic [ 0 ] ! = 0 | | swap - > I . alicetomic [ 0 ] ! = 0 ) {
int error = 0 ;
uint64_t eth_balance = getEthBalance ( swap - > I . etomicsrc , & error ) ;
if ( eth_balance < 500000 ) {
err = - 5000 , printf ( " Bob ETH balance too low, aborting swap! \n " ) ;
}
}
# endif
if ( swap ! = 0 & & err = = 0 )
{
if ( LP_waitsend ( " pubkeys " , 120 , swap - > N . pair , swap , data , maxlen , LP_pubkeys_verify , LP_pubkeys_data ) < 0 )
err = - 2000 , printf ( " error waitsend pubkeys \n " ) ;
else if ( LP_waitsend ( " choosei " , LP_SWAPSTEP_TIMEOUT , swap - > N . pair , swap , data , maxlen , LP_choosei_verify , LP_choosei_data ) < 0 )
err = - 2001 , printf ( " error waitsend choosei \n " ) ;
else if ( LP_waitsend ( " mostprivs " , LP_SWAPSTEP_TIMEOUT , swap - > N . pair , swap , data , maxlen , LP_mostprivs_verify , LP_mostprivs_data ) < 0 )
err = - 2002 , printf ( " error waitsend mostprivs \n " ) ;
else if ( basilisk_bobscripts_set ( swap , 1 , 1 ) < 0 )
err = - 2003 , printf ( " error bobscripts deposit \n " ) ;
else
{
swap - > bobrefund . utxovout = 0 ;
swap - > bobrefund . utxotxid = swap - > bobdeposit . I . signedtxid ;
basilisk_bobdeposit_refund ( swap , swap - > I . putduration ) ;
//printf("depositlen.%d\n",swap->bobdeposit.I.datalen);
//LP_swapsfp_update(&swap->I.req);
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
LP_unavailableset ( swap - > bobdeposit . utxotxid , swap - > bobdeposit . utxovout , ( uint32_t ) time ( NULL ) + 60 , swap - > I . otherhash ) ;
if ( LP_waitfor ( swap - > N . pair , swap , bobwaittimeout , LP_verify_otherfee ) < 0 )
{
err = - 2004 , printf ( " error waiting for alicefee \n " ) ;
}
if ( err = = 0 )
{
if ( LP_swapdata_rawtxsend ( swap - > N . pair , swap , 0x200 , data , maxlen , & swap - > bobdeposit , 0x100 , 0 ) = = 0 )
{
err = - 2005 , printf ( " error sending bobdeposit \n " ) ;
}
}
if ( err = = 0 ) {
LP_unavailableset ( swap - > bobpayment . utxotxid , swap - > bobpayment . utxovout , ( uint32_t ) time ( NULL ) + 60 , swap - > I . otherhash ) ;
m = swap - > I . bobconfirms ;
while ( ( n = LP_numconfirms ( bobstr , swap - > bobdeposit . I . destaddr , swap - > bobdeposit . I . signedtxid , 0 , 1 ) ) < m ) {
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
LP_unavailableset ( swap - > bobpayment . utxotxid , swap - > bobpayment . utxovout , ( uint32_t ) time ( NULL ) + 60 , swap - > I . otherhash ) ;
char str [ 65 ] ;
printf ( " %d wait for bobdeposit %s numconfs.%d %s %s \n " , n , swap - > bobdeposit . I . destaddr , m , bobstr , bits256_str ( str , swap - > bobdeposit . I . signedtxid ) ) ;
sleep ( 10 ) ;
}
printf ( " wait for alicepayment \n " ) ;
if ( LP_waitfor ( swap - > N . pair , swap , bobwaittimeout + alicewaittimeout , LP_verify_alicepayment ) < 0 ) {
err = - 2006 , printf ( " error waiting for alicepayment \n " ) ;
}
}
if ( err = = 0 )
{
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
if ( basilisk_bobscripts_set ( swap , 0 , 1 ) < 0 )
err = - 2007 , printf ( " error bobscripts payment \n " ) ;
else
{
m = swap - > I . aliceconfirms ;
LP_unavailableset ( swap - > bobpayment . utxotxid , swap - > bobpayment . utxovout , ( uint32_t ) time ( NULL ) + 60 , swap - > I . otherhash ) ;
while ( ( n = LP_numconfirms ( alicestr , swap - > alicepayment . I . destaddr , swap - > alicepayment . I . signedtxid , 0 , 1 ) ) < m ) // sync with alice
{
LP_unavailableset ( swap - > bobpayment . utxotxid , swap - > bobpayment . utxovout , ( uint32_t ) time ( NULL ) + 60 , swap - > I . otherhash ) ;
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
char str [ 65 ] ; printf ( " %d wait for alicepayment %s numconfs.%d %s %s \n " , n , swap - > alicepayment . I . destaddr , m , alicestr , bits256_str ( str , swap - > alicepayment . I . signedtxid ) ) ;
sleep ( 10 ) ;
}
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
if ( LP_swapdata_rawtxsend ( swap - > N . pair , swap , 0x8000 , data , maxlen , & swap - > bobpayment , 0x4000 , 0 ) = = 0 ) {
err = - 2008 , printf ( " error sending bobpayment \n " ) ;
}
//if ( LP_waitfor(swap->N.pair,swap,10,LP_verify_alicespend) < 0 )
// printf("error waiting for alicespend\n");
//swap->sentflag = 1;
swap - > bobreclaim . utxovout = 0 ;
swap - > bobreclaim . utxotxid = swap - > bobpayment . I . signedtxid ;
basilisk_bobpayment_reclaim ( swap , swap - > I . callduration ) ;
if ( swap - > N . pair > = 0 )
nn_close ( swap - > N . pair ) , swap - > N . pair = - 1 ;
}
}
}
} else printf ( " swap timed out \n " ) ;
LP_swap_endcritical = ( uint32_t ) time ( NULL ) ;
if ( err < 0 )
LP_failedmsg ( swap - > I . req . requestid , swap - > I . req . quoteid , err , swap - > uuidstr ) ;
if ( swap - > I . aliceconfirms > 0 )
sleep ( 13 ) ;
LP_pendswap_add ( swap - > I . expiration , swap - > I . req . requestid , swap - > I . req . quoteid ) ;
//swap->I.finished = LP_swapwait(swap->I.expiration,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*3,swap->I.aliceconfirms == 0 ? 3 : 30);
basilisk_swap_finished ( swap ) ;
free ( swap ) ;
free ( data ) ;
G . LP_pendingswaps - - ;
}
void LP_aliceloop ( void * _swap )
{
uint8_t * data ; char bobstr [ 65 ] , alicestr [ 65 ] ; int32_t bobwaittimeout , alicewaittimeout , maxlen , n , m , err = 0 ; uint32_t expiration ; struct basilisk_swap * swap = _swap ;
LP_alicequery_clear ( ) ;
G . LP_pendingswaps + + ;
LP_etomicsymbol ( bobstr , swap - > I . bobtomic , swap - > I . bobstr ) ;
LP_etomicsymbol ( alicestr , swap - > I . alicetomic , swap - > I . alicestr ) ;
maxlen = 1024 * 1024 + sizeof ( * swap ) ;
data = malloc ( maxlen ) ;
expiration = ( uint32_t ) time ( NULL ) + LP_SWAPSTEP_TIMEOUT ;
bobwaittimeout = LP_calc_waittimeout ( bobstr ) ;
alicewaittimeout = LP_calc_waittimeout ( alicestr ) ;
# ifndef NOTETOMIC
if ( swap - > I . bobtomic [ 0 ] ! = 0 | | swap - > I . alicetomic [ 0 ] ! = 0 ) {
int error = 0 ;
uint64_t eth_balance = getEthBalance ( swap - > I . etomicdest , & error ) ;
if ( eth_balance < 500000 ) {
err = - 5001 , printf ( " Alice ETH balance too low, aborting swap! \n " ) ;
}
}
# endif
if ( swap ! = 0 & & err = = 0 )
{
printf ( " start swap iamalice pair.%d \n " , swap - > N . pair ) ;
if ( LP_sendwait ( " pubkeys " , 120 , swap - > N . pair , swap , data , maxlen , LP_pubkeys_verify , LP_pubkeys_data ) < 0 )
err = - 1000 , printf ( " error LP_sendwait pubkeys \n " ) ;
else if ( LP_sendwait ( " choosei " , LP_SWAPSTEP_TIMEOUT , swap - > N . pair , swap , data , maxlen , LP_choosei_verify , LP_choosei_data ) < 0 )
err = - 1001 , printf ( " error LP_sendwait choosei \n " ) ;
else if ( LP_sendwait ( " mostprivs " , LP_SWAPSTEP_TIMEOUT , swap - > N . pair , swap , data , maxlen , LP_mostprivs_verify , LP_mostprivs_data ) < 0 )
err = - 1002 , printf ( " error LP_sendwait mostprivs \n " ) ;
else if ( basilisk_alicetxs ( swap - > N . pair , swap , data , maxlen ) ! = 0 )
err = - 1003 , printf ( " basilisk_alicetxs error \n " ) ;
else
{
//LP_swapsfp_update(&swap->I.req);
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
if ( LP_swapdata_rawtxsend ( swap - > N . pair , swap , 0x80 , data , maxlen , & swap - > myfee , 0x40 , 0 ) = = 0 )
err = - 1004 , printf ( " error sending alicefee \n " ) ;
else if ( LP_waitfor ( swap - > N . pair , swap , bobwaittimeout , LP_verify_bobdeposit ) < 0 )
err = - 1005 , printf ( " error waiting for bobdeposit \n " ) ;
else
{
m = swap - > I . bobconfirms ;
LP_unavailableset ( swap - > alicepayment . utxotxid , swap - > alicepayment . utxovout , ( uint32_t ) time ( NULL ) + 60 , swap - > I . otherhash ) ;
while ( ( n = LP_numconfirms ( bobstr , swap - > bobdeposit . I . destaddr , swap - > bobdeposit . I . signedtxid , 0 , 1 ) ) < m )
{
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
LP_unavailableset ( swap - > alicepayment . utxotxid , swap - > alicepayment . utxovout , ( uint32_t ) time ( NULL ) + 60 , swap - > I . otherhash ) ;
char str [ 65 ] ; printf ( " %d wait for bobdeposit %s numconfs.%d %s %s \n " , n , swap - > bobdeposit . I . destaddr , m , bobstr , bits256_str ( str , swap - > bobdeposit . I . signedtxid ) ) ;
sleep ( 10 ) ;
}
if ( LP_swapdata_rawtxsend ( swap - > N . pair , swap , 0x1000 , data , maxlen , & swap - > alicepayment , 0x800 , 0 ) = = 0 )
err = - 1006 , printf ( " error sending alicepayment \n " ) ;
else
{
m = swap - > I . aliceconfirms ;
while ( ( n = LP_numconfirms ( alicestr , swap - > alicepayment . I . destaddr , swap - > alicepayment . I . signedtxid , 0 , 1 ) ) < m )
{
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
char str [ 65 ] ; printf ( " %d wait for alicepayment %s numconfs.%d %s %s \n " , n , swap - > alicepayment . I . destaddr , m , alicestr , bits256_str ( str , swap - > alicepayment . I . signedtxid ) ) ;
sleep ( 10 ) ;
}
//swap->sentflag = 1;
LP_swap_critical = ( uint32_t ) time ( NULL ) ;
if ( LP_waitfor ( swap - > N . pair , swap , bobwaittimeout , LP_verify_bobpayment ) < 0 )
err = - 1007 , printf ( " error waiting for bobpayment \n " ) ;
else
{
LP_swap_endcritical = ( uint32_t ) time ( NULL ) ;
while ( ( n = LP_numconfirms ( bobstr , swap - > bobpayment . I . destaddr , swap - > bobpayment . I . signedtxid , 0 , 1 ) ) < swap - > I . bobconfirms )
{
char str [ 65 ] ; printf ( " %d wait for bobpayment %s numconfs.%d %s %s \n " , n , swap - > bobpayment . I . destaddr , swap - > I . bobconfirms , bobstr , bits256_str ( str , swap - > bobpayment . I . signedtxid ) ) ;
sleep ( 10 ) ;
}
char str [ 65 ] ; printf ( " %d waited for bobpayment %s numconfs.%d %s %s \n " , n , swap - > bobpayment . I . destaddr , swap - > I . bobconfirms , bobstr , bits256_str ( str , swap - > bobpayment . I . signedtxid ) ) ;
if ( swap - > N . pair > = 0 )
nn_close ( swap - > N . pair ) , swap - > N . pair = - 1 ;
}
}
}
}
}
LP_swap_endcritical = ( uint32_t ) time ( NULL ) ;
if ( err < 0 )
LP_failedmsg ( swap - > I . req . requestid , swap - > I . req . quoteid , err , swap - > uuidstr ) ;
if ( swap - > I . bobconfirms > 0 )
sleep ( 13 ) ;
LP_pendswap_add ( swap - > I . expiration , swap - > I . req . requestid , swap - > I . req . quoteid ) ;
//swap->I.finished = LP_swapwait(swap->I.expiration,swap->I.req.requestid,swap->I.req.quoteid,LP_atomic_locktime(swap->I.bobstr,swap->I.alicestr)*3,swap->I.aliceconfirms == 0 ? 3 : 30);
basilisk_swap_finished ( swap ) ;
free ( swap ) ;
free ( data ) ;
G . LP_pendingswaps - - ;
}
bits256 instantdex_derivekeypair ( void * ctx , bits256 * newprivp , uint8_t pubkey [ 33 ] , bits256 privkey , bits256 orderhash )
{
bits256 sharedsecret ;
sharedsecret = curve25519_shared ( privkey , orderhash ) ;
vcalc_sha256cat ( newprivp - > bytes , orderhash . bytes , sizeof ( orderhash ) , sharedsecret . bytes , sizeof ( sharedsecret ) ) ;
return ( bitcoin_pubkey33 ( ctx , pubkey , * newprivp ) ) ;
}
bits256 basilisk_revealkey ( bits256 privkey , bits256 pubkey )
{
return ( pubkey ) ;
}
int32_t instantdex_pubkeyargs ( struct basilisk_swap * swap , int32_t numpubs , bits256 privkey , bits256 hash , int32_t firstbyte )
{
char buf [ 3 ] ; int32_t i , n , m , len = 0 ; bits256 pubi , reveal ; uint64_t txid ; uint8_t secret160 [ 20 ] , pubkey [ 33 ] ;
sprintf ( buf , " %c0 " , ' A ' - 0x02 + firstbyte ) ;
if ( numpubs > 2 )
{
if ( swap - > I . numpubs + 2 > = numpubs )
return ( numpubs ) ;
//printf(">>>>>> start generating %s\n",buf);
}
for ( i = n = m = 0 ; i < numpubs * 100 & & n < numpubs ; i + + )
{
pubi = instantdex_derivekeypair ( swap - > ctx , & privkey , pubkey , privkey , hash ) ;
//printf("i.%d n.%d numpubs.%d %02x vs %02x\n",i,n,numpubs,pubkey[0],firstbyte);
if ( pubkey [ 0 ] ! = firstbyte )
continue ;
if ( n < 2 )
{
if ( bits256_nonz ( swap - > I . mypubs [ n ] ) = = 0 )
{
swap - > I . myprivs [ n ] = privkey ;
memcpy ( swap - > I . mypubs [ n ] . bytes , pubkey + 1 , sizeof ( bits256 ) ) ;
reveal = basilisk_revealkey ( privkey , swap - > I . mypubs [ n ] ) ;
if ( swap - > I . iambob ! = 0 )
{
if ( n = = 0 )
swap - > I . pubB0 = reveal ;
else if ( n = = 1 )
swap - > I . pubB1 = reveal ;
}
else if ( swap - > I . iambob = = 0 )
{
if ( n = = 0 )
swap - > I . pubA0 = reveal ;
else if ( n = = 1 )
swap - > I . pubA1 = reveal ;
}
}
}
if ( m < INSTANTDEX_DECKSIZE )
{
swap - > privkeys [ m ] = privkey ;
revcalc_rmd160_sha256 ( secret160 , privkey ) ; //.bytes,sizeof(privkey));
memcpy ( & txid , secret160 , sizeof ( txid ) ) ;
len + = iguana_rwnum ( 1 , ( uint8_t * ) & swap - > deck [ m ] [ 0 ] , sizeof ( txid ) , & txid ) ;
len + = iguana_rwnum ( 1 , ( uint8_t * ) & swap - > deck [ m ] [ 1 ] , sizeof ( pubi . txid ) , & pubi . txid ) ;
m + + ;
if ( m > swap - > I . numpubs )
swap - > I . numpubs = m ;
}
n + + ;
}
//if ( n > 2 || m > 2 )
// printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->I.numpubs);
return ( n ) ;
}
void basilisk_rawtx_setparms ( char * name , uint32_t quoteid , struct basilisk_rawtx * rawtx , struct iguana_info * coin , int32_t numconfirms , int32_t vintype , uint64_t satoshis , int32_t vouttype , uint8_t * pubkey33 , int32_t jumblrflag )
{
# ifdef BASILISK_DISABLEWAITTX
numconfirms = 0 ;
# endif
strcpy ( rawtx - > name , name ) ;
//printf("set coin.%s %s -> %s\n",coin->symbol,coin->smartaddr,name);
strcpy ( rawtx - > symbol , coin - > symbol ) ;
rawtx - > I . numconfirms = numconfirms ;
if ( ( rawtx - > I . amount = satoshis ) < LP_MIN_TXFEE )
rawtx - > I . amount = LP_MIN_TXFEE ;
rawtx - > I . vintype = vintype ; // 0 -> std, 2 -> 2of2, 3 -> spend bobpayment, 4 -> spend bobdeposit
rawtx - > I . vouttype = vouttype ; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit
if ( rawtx - > I . vouttype = = 0 )
{
if ( strcmp ( coin - > symbol , " BTC " ) = = 0 & & ( quoteid % 10 ) = = 0 )
decode_hex ( rawtx - > I . rmd160 , 20 , TIERNOLAN_RMD160 ) ;
else decode_hex ( rawtx - > I . rmd160 , 20 , INSTANTDEX_RMD160 ) ;
bitcoin_address ( coin - > symbol , rawtx - > I . destaddr , coin - > taddr , coin - > pubtype , rawtx - > I . rmd160 , 20 ) ;
}
if ( pubkey33 ! = 0 )
{
memcpy ( rawtx - > I . pubkey33 , pubkey33 , 33 ) ;
bitcoin_address ( coin - > symbol , rawtx - > I . destaddr , coin - > taddr , coin - > pubtype , rawtx - > I . pubkey33 , 33 ) ;
bitcoin_addr2rmd160 ( coin - > symbol , coin - > taddr , & rawtx - > I . addrtype , rawtx - > I . rmd160 , rawtx - > I . destaddr ) ;
}
if ( rawtx - > I . vouttype < = 1 & & rawtx - > I . destaddr [ 0 ] ! = 0 )
{
rawtx - > I . spendlen = bitcoin_standardspend ( rawtx - > spendscript , 0 , rawtx - > I . rmd160 ) ;
//printf("%s spendlen.%d %s <- %.8f\n",name,rawtx->I.spendlen,rawtx->I.destaddr,dstr(rawtx->I.amount));
} //else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->I.vouttype,rawtx->I.destaddr);
}
struct basilisk_swap * bitcoin_swapinit ( bits256 privkey , uint8_t * pubkey33 , bits256 pubkey25519 , struct basilisk_swap * swap , int32_t optionduration , uint32_t statebits , struct LP_quoteinfo * qp , int32_t dynamictrust )
{
//FILE *fp; char fname[512];
uint8_t * alicepub33 = 0 , * bobpub33 = 0 ; int32_t jumblrflag = - 2 , x = - 1 ; struct iguana_info * bobcoin , * alicecoin ; char bobstr [ 65 ] , alicestr [ 65 ] ;
strcpy ( swap - > I . etomicsrc , qp - > etomicsrc ) ;
strcpy ( swap - > I . etomicdest , qp - > etomicdest ) ;
strcpy ( swap - > I . bobstr , swap - > I . req . src ) ;
strcpy ( swap - > I . alicestr , swap - > I . req . dest ) ;
LP_etomicsymbol ( bobstr , swap - > I . bobtomic , swap - > I . bobstr ) ;
LP_etomicsymbol ( alicestr , swap - > I . alicetomic , swap - > I . alicestr ) ;
if ( ( alicecoin = LP_coinfind ( alicestr ) ) = = 0 )
{
printf ( " missing alicecoin src.%p dest.%p \n " , LP_coinfind ( alicestr ) , LP_coinfind ( bobstr ) ) ;
free ( swap ) ;
return ( 0 ) ;
}
if ( ( bobcoin = LP_coinfind ( bobstr ) ) = = 0 )
{
printf ( " missing bobcoin src.%p dest.%p \n " , LP_coinfind ( swap - > I . req . src ) , LP_coinfind ( swap - > I . req . dest ) ) ;
free ( swap ) ;
return ( 0 ) ;
}
if ( alicecoin = = 0 | | bobcoin = = 0 )
{
printf ( " couldnt find ETOMIC \n " ) ;
free ( swap ) ;
return ( 0 ) ;
}
if ( ( swap - > I . Atxfee = qp - > desttxfee ) < 0 )
{
printf ( " bitcoin_swapinit %s Atxfee %.8f rejected \n " , swap - > I . req . dest , dstr ( swap - > I . Atxfee ) ) ;
free ( swap ) ;
return ( 0 ) ;
}
if ( ( swap - > I . Btxfee = qp - > txfee ) < 0 )
{
printf ( " bitcoin_swapinit %s Btxfee %.8f rejected \n " , swap - > I . req . src , dstr ( swap - > I . Btxfee ) ) ;
free ( swap ) ;
return ( 0 ) ;
}
swap - > I . putduration = swap - > I . callduration = LP_atomic_locktime ( bobstr , alicestr ) ;
if ( optionduration < 0 )
swap - > I . putduration - = optionduration ;
else if ( optionduration > 0 )
swap - > I . callduration + = optionduration ;
if ( ( swap - > I . bobsatoshis = swap - > I . req . srcamount ) < = 0 )
{
printf ( " bitcoin_swapinit %s bobsatoshis %.8f rejected \n " , swap - > I . req . src , dstr ( swap - > I . bobsatoshis ) ) ;
free ( swap ) ;
return ( 0 ) ;
}
if ( ( swap - > I . alicesatoshis = swap - > I . req . destamount ) < = 0 )
{
printf ( " bitcoin_swapinit %s alicesatoshis %.8f rejected \n " , swap - > I . req . dest , dstr ( swap - > I . alicesatoshis ) ) ;
free ( swap ) ;
return ( 0 ) ;
}
# ifndef NOTETOMIC
if ( strcmp ( alicestr , " ETOMIC " ) = = 0 ) {
swap - > I . alicerealsat = swap - > I . alicesatoshis ;
swap - > I . alicesatoshis = 100000000 ;
}
if ( strcmp ( bobstr , " ETOMIC " ) = = 0 ) {
swap - > I . bobrealsat = swap - > I . bobsatoshis ;
swap - > I . bobsatoshis = 100000000 ;
}
# endif
if ( ( swap - > I . bobinsurance = ( swap - > I . bobsatoshis / INSTANTDEX_INSURANCEDIV ) ) < LP_MIN_TXFEE )
swap - > I . bobinsurance = LP_MIN_TXFEE ;
if ( ( swap - > I . aliceinsurance = ( swap - > I . alicesatoshis / INSTANTDEX_INSURANCEDIV ) ) < LP_MIN_TXFEE )
swap - > I . aliceinsurance = LP_MIN_TXFEE ;
swap - > I . started = qp - > timestamp ; //(uint32_t)time(NULL);
swap - > I . expiration = swap - > I . req . timestamp + swap - > I . putduration + swap - > I . callduration ;
OS_randombytes ( ( uint8_t * ) & swap - > I . choosei , sizeof ( swap - > I . choosei ) ) ;
if ( swap - > I . choosei < 0 )
swap - > I . choosei = - swap - > I . choosei ;
swap - > I . choosei % = INSTANTDEX_DECKSIZE ;
swap - > I . otherchoosei = - 1 ;
swap - > I . myhash = pubkey25519 ;
if ( statebits ! = 0 )
{
swap - > I . iambob = 0 ;
swap - > I . otherhash = swap - > I . req . desthash ;
swap - > I . aliceistrusted = 1 ;
if ( dynamictrust = = 0 & & LP_pubkey_istrusted ( swap - > I . req . srchash ) ! = 0 )
dynamictrust = 1 ;
swap - > I . otheristrusted = swap - > I . bobistrusted = dynamictrust ;
}
else
{
swap - > I . iambob = 1 ;
swap - > I . otherhash = swap - > I . req . srchash ;
swap - > I . bobistrusted = 1 ;
if ( dynamictrust = = 0 & & LP_pubkey_istrusted ( swap - > I . req . desthash ) ! = 0 )
dynamictrust = 1 ;
swap - > I . otheristrusted = swap - > I . aliceistrusted = dynamictrust ;
}
if ( bits256_nonz ( privkey ) = = 0 | | ( x = instantdex_pubkeyargs ( swap , 2 + INSTANTDEX_DECKSIZE , privkey , swap - > I . orderhash , 0x02 + swap - > I . iambob ) ) ! = 2 + INSTANTDEX_DECKSIZE )
{
char str [ 65 ] ; printf ( " couldnt generate privkeys %d %s \n " , x , bits256_str ( str , privkey ) ) ;
free ( swap ) ;
return ( 0 ) ;
}
if ( strcmp ( " BTC " , bobstr ) = = 0 )
{
swap - > I . bobconfirms = 1 ; //(1 + sqrt(dstr(swap->I.bobsatoshis) * .1));
swap - > I . aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS ;
}
else if ( strcmp ( " BTC " , alicestr ) = = 0 )
{
swap - > I . aliceconfirms = 1 ; //(1 + sqrt(dstr(swap->I.alicesatoshis) * .1));
swap - > I . bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS ;
}
else
{
swap - > I . bobconfirms = BASILISK_DEFAULT_NUMCONFIRMS ;
swap - > I . aliceconfirms = BASILISK_DEFAULT_NUMCONFIRMS ;
}
if ( bobcoin - > userconfirms > 0 )
swap - > I . bobconfirms = bobcoin - > userconfirms ;
if ( alicecoin - > userconfirms > 0 )
swap - > I . aliceconfirms = alicecoin - > userconfirms ;
if ( ( swap - > I . bobmaxconfirms = bobcoin - > maxconfirms ) = = 0 )
swap - > I . bobmaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS ;
if ( ( swap - > I . alicemaxconfirms = alicecoin - > maxconfirms ) = = 0 )
swap - > I . alicemaxconfirms = BASILISK_DEFAULT_MAXCONFIRMS ;
if ( swap - > I . bobconfirms > swap - > I . bobmaxconfirms )
swap - > I . bobconfirms = swap - > I . bobmaxconfirms ;
if ( swap - > I . aliceconfirms > swap - > I . alicemaxconfirms )
swap - > I . aliceconfirms = swap - > I . alicemaxconfirms ;
if ( bobcoin - > isassetchain ! = 0 ) {
if ( strcmp ( bobstr , " ETOMIC " ) ! = 0 ) {
swap - > I . bobconfirms = BASILISK_DEFAULT_MAXCONFIRMS / 2 ;
} else {
swap - > I . bobconfirms = 1 ;
}
}
if ( alicecoin - > isassetchain ! = 0 ) {
if ( strcmp ( alicestr , " ETOMIC " ) ! = 0 ) {
swap - > I . aliceconfirms = BASILISK_DEFAULT_MAXCONFIRMS / 2 ;
} else {
swap - > I . aliceconfirms = 1 ;
}
}
if ( strcmp ( " BAY " , swap - > I . req . src ) ! = 0 & & strcmp ( " BAY " , swap - > I . req . dest ) ! = 0 )
{
swap - > I . bobconfirms * = ! swap - > I . bobistrusted ;
swap - > I . aliceconfirms * = ! swap - > I . aliceistrusted ;
}
printf ( " >>>>>>>>>> jumblrflag.%d <<<<<<<<< r.%u q.%u, %.8f bobconfs.%d, %.8f aliceconfs.%d taddr.%d %d \n " , jumblrflag , swap - > I . req . requestid , swap - > I . req . quoteid , dstr ( swap - > I . bobsatoshis ) , swap - > I . bobconfirms , dstr ( swap - > I . alicesatoshis ) , swap - > I . aliceconfirms , bobcoin - > taddr , alicecoin - > taddr ) ;
if ( swap - > I . etomicsrc [ 0 ] ! = 0 | | swap - > I . etomicdest [ 0 ] ! = 0 )
printf ( " etomic src (%s %s) dest (%s %s) \n " , swap - > I . bobtomic , swap - > I . etomicsrc , swap - > I . alicetomic , swap - > I . etomicdest ) ;
if ( swap - > I . iambob ! = 0 )
{
basilisk_rawtx_setparms ( " myfee " , swap - > I . req . quoteid , & swap - > myfee , bobcoin , 0 , 0 , LP_DEXFEE ( swap - > I . bobsatoshis ) + 0 * bobcoin - > txfee , 0 , 0 , jumblrflag ) ;
basilisk_rawtx_setparms ( " otherfee " , swap - > I . req . quoteid , & swap - > otherfee , alicecoin , 0 , 0 , LP_DEXFEE ( swap - > I . alicesatoshis ) + 0 * alicecoin - > txfee , 0 , 0 , jumblrflag ) ;
bobpub33 = pubkey33 ;
}
else
{
basilisk_rawtx_setparms ( " otherfee " , swap - > I . req . quoteid , & swap - > otherfee , bobcoin , 0 , 0 , LP_DEXFEE ( swap - > I . bobsatoshis ) + 0 * bobcoin - > txfee , 0 , 0 , jumblrflag ) ;
basilisk_rawtx_setparms ( " myfee " , swap - > I . req . quoteid , & swap - > myfee , alicecoin , 0 , 0 , LP_DEXFEE ( swap - > I . alicesatoshis ) + 0 * alicecoin - > txfee , 0 , 0 , jumblrflag ) ;
alicepub33 = pubkey33 ;
}
swap - > myfee . I . locktime = swap - > I . started + 1 ;
swap - > otherfee . I . locktime = swap - > I . started + 1 ;
basilisk_rawtx_setparms ( " bobdeposit " , swap - > I . req . quoteid , & swap - > bobdeposit , bobcoin , swap - > I . bobconfirms , 0 , LP_DEPOSITSATOSHIS ( swap - > I . bobsatoshis ) + 2 * bobcoin - > txfee , 4 , 0 , jumblrflag ) ;
basilisk_rawtx_setparms ( " bobrefund " , swap - > I . req . quoteid , & swap - > bobrefund , bobcoin , 1 , 4 , LP_DEPOSITSATOSHIS ( swap - > I . bobsatoshis ) , 1 , bobpub33 , jumblrflag ) ;
swap - > bobrefund . I . suppress_pubkeys = 1 ;
basilisk_rawtx_setparms ( " aliceclaim " , swap - > I . req . quoteid , & swap - > aliceclaim , bobcoin , 1 , 4 , LP_DEPOSITSATOSHIS ( swap - > I . bobsatoshis ) , 1 , alicepub33 , jumblrflag ) ;
swap - > aliceclaim . I . suppress_pubkeys = 1 ;
swap - > aliceclaim . I . locktime = swap - > I . started + swap - > I . putduration + swap - > I . callduration + 1 ;
basilisk_rawtx_setparms ( " bobpayment " , swap - > I . req . quoteid , & swap - > bobpayment , bobcoin , swap - > I . bobconfirms , 0 , swap - > I . bobsatoshis + 2 * bobcoin - > txfee , 3 , 0 , jumblrflag ) ;
basilisk_rawtx_setparms ( " alicespend " , swap - > I . req . quoteid , & swap - > alicespend , bobcoin , swap - > I . bobconfirms , 3 , swap - > I . bobsatoshis , 1 , alicepub33 , jumblrflag ) ;
swap - > alicespend . I . suppress_pubkeys = 1 ;
basilisk_rawtx_setparms ( " bobreclaim " , swap - > I . req . quoteid , & swap - > bobreclaim , bobcoin , swap - > I . bobconfirms , 3 , swap - > I . bobsatoshis , 1 , bobpub33 , jumblrflag ) ;
swap - > bobreclaim . I . suppress_pubkeys = 1 ;
swap - > bobreclaim . I . locktime = swap - > I . started + swap - > I . putduration + 1 ;
basilisk_rawtx_setparms ( " alicepayment " , swap - > I . req . quoteid , & swap - > alicepayment , alicecoin , swap - > I . aliceconfirms , 0 , swap - > I . alicesatoshis + 2 * alicecoin - > txfee , 2 , 0 , jumblrflag ) ;
basilisk_rawtx_setparms ( " bobspend " , swap - > I . req . quoteid , & swap - > bobspend , alicecoin , swap - > I . aliceconfirms , 2 , swap - > I . alicesatoshis , 1 , bobpub33 , jumblrflag ) ;
swap - > bobspend . I . suppress_pubkeys = 1 ;
basilisk_rawtx_setparms ( " alicereclaim " , swap - > I . req . quoteid , & swap - > alicereclaim , alicecoin , swap - > I . aliceconfirms , 2 , swap - > I . alicesatoshis , 1 , alicepub33 , jumblrflag ) ;
swap - > alicereclaim . I . suppress_pubkeys = 1 ;
swap - > bobpayment . utxotxid = qp - > txid , swap - > bobpayment . utxovout = qp - > vout ;
swap - > bobdeposit . utxotxid = qp - > txid2 , swap - > bobdeposit . utxovout = qp - > vout2 ;
swap - > alicepayment . utxotxid = qp - > desttxid , swap - > alicepayment . utxovout = qp - > destvout ;
# ifndef NOTETOMIC
if ( strcmp ( alicestr , " ETOMIC " ) = = 0 ) {
swap - > alicepayment . I . eth_amount = swap - > I . alicerealsat ;
if ( swap - > I . iambob = = 1 ) {
swap - > otherfee . I . eth_amount = LP_DEXFEE ( swap - > I . alicerealsat ) ;
} else {
swap - > myfee . I . eth_amount = LP_DEXFEE ( swap - > I . alicerealsat ) ;
}
}
if ( strcmp ( bobstr , " ETOMIC " ) = = 0 ) {
swap - > bobpayment . I . eth_amount = swap - > I . bobrealsat ;
swap - > bobdeposit . I . eth_amount = LP_DEPOSITSATOSHIS ( swap - > I . bobrealsat ) ;
}
# endif
LP_mark_spent ( bobstr , qp - > txid , qp - > vout ) ;
LP_mark_spent ( bobstr , qp - > txid2 , qp - > vout2 ) ;
LP_mark_spent ( alicestr , qp - > desttxid , qp - > destvout ) ;
if ( swap - > I . iambob ! = 0 )
swap - > otherfee . utxotxid = qp - > feetxid , swap - > otherfee . utxovout = qp - > feevout ;
else
{
swap - > myfee . utxotxid = qp - > feetxid , swap - > myfee . utxovout = qp - > feevout ;
LP_mark_spent ( swap - > I . alicestr , qp - > feetxid , qp - > feevout ) ;
}
//char str[65],str2[65],str3[65]; printf("IAMBOB.%d %s %s %s [%s %s]\n",swap->I.iambob,bits256_str(str,qp->txid),bits256_str(str2,qp->txid2),bits256_str(str3,qp->feetxid),bobstr,alicestr);
return ( swap ) ;
}
struct basilisk_swap * LP_swapinit ( int32_t iambob , int32_t optionduration , bits256 privkey , struct basilisk_request * rp , struct LP_quoteinfo * qp , int32_t dynamictrust )
{
static void * ctx ;
struct basilisk_swap * swap ; bits256 pubkey25519 ; uint8_t pubkey33 [ 33 ] ;
if ( ctx = = 0 )
ctx = bitcoin_ctx ( ) ;
swap = calloc ( 1 , sizeof ( * swap ) ) ;
memcpy ( swap - > uuidstr , qp - > uuidstr , sizeof ( swap - > uuidstr ) ) ;
swap - > aliceid = LP_aliceid_calc ( qp - > desttxid , qp - > destvout , qp - > feetxid , qp - > feevout ) ;
swap - > I . req . quoteid = rp - > quoteid ;
swap - > ctx = ctx ;
vcalc_sha256 ( 0 , swap - > I . orderhash . bytes , ( uint8_t * ) rp , sizeof ( * rp ) ) ;
swap - > I . req = * rp ;
G . LP_skipstatus [ G . LP_numskips ] = ( ( uint64_t ) rp - > requestid < < 32 ) | rp - > quoteid ;
if ( G . LP_numskips < sizeof ( G . LP_skipstatus ) / sizeof ( * G . LP_skipstatus ) )
G . LP_numskips + + ;
//printf("LP_swapinit request.%u iambob.%d (%s/%s) quoteid.%u\n",rp->requestid,iambob,rp->src,rp->dest,rp->quoteid);
bitcoin_pubkey33 ( swap - > ctx , pubkey33 , privkey ) ;
pubkey25519 = curve25519 ( privkey , curve25519_basepoint9 ( ) ) ;
swap - > persistent_pubkey = pubkey25519 ;
swap - > persistent_privkey = privkey ;
memcpy ( swap - > persistent_pubkey33 , pubkey33 , 33 ) ;
calc_rmd160_sha256 ( swap - > changermd160 , pubkey33 , 33 ) ;
if ( bitcoin_swapinit ( privkey , pubkey33 , pubkey25519 , swap , optionduration , ! iambob , qp , dynamictrust ) = = 0 )
{
printf ( " error doing swapinit \n " ) ;
free ( swap ) ;
swap = 0 ;
}
return ( swap ) ;
}