14 changed files with 6649 additions and 2767 deletions
File diff suppressed because it is too large
@ -0,0 +1,469 @@ |
|||
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2017 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_include.h
|
|||
// marketmaker
|
|||
//
|
|||
|
|||
#ifndef LP_INCLUDE_H |
|||
#define LP_INCLUDE_H |
|||
|
|||
#define BASILISK_DISABLEWAITTX |
|||
#define BASILISK_DISABLESENDTX |
|||
|
|||
#define BASILISK_DEFAULT_NUMCONFIRMS 5 |
|||
#define DEX_SLEEP 3 |
|||
#define BASILISK_DEXDURATION 300 |
|||
#define BASILISK_MSGDURATION 30 |
|||
#define BASILISK_AUCTION_DURATION 5 |
|||
|
|||
#define BASILISK_MAXFUTUREBLOCK 60 |
|||
#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2)) |
|||
|
|||
extern char GLOBAL_DBDIR[]; |
|||
|
|||
void *bitcoin_ctx(); |
|||
int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen); |
|||
int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen); |
|||
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag); |
|||
bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey); |
|||
bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even); |
|||
|
|||
char *bitcoin_base58encode(char *coinaddr,uint8_t *data,int32_t datalen); |
|||
int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr); |
|||
|
|||
#define IGUANA_MAXSCRIPTSIZE 10001 |
|||
#define IGUANA_SEQUENCEID_FINAL 0xfffffffe |
|||
|
|||
#define IGUANA_SCRIPT_NULL 0 |
|||
#define IGUANA_SCRIPT_76AC 1 |
|||
#define IGUANA_SCRIPT_76A988AC 2 |
|||
#define IGUANA_SCRIPT_P2SH 3 |
|||
#define IGUANA_SCRIPT_OPRETURN 4 |
|||
#define IGUANA_SCRIPT_3of3 5 |
|||
#define IGUANA_SCRIPT_2of3 6 |
|||
#define IGUANA_SCRIPT_1of3 7 |
|||
#define IGUANA_SCRIPT_2of2 8 |
|||
#define IGUANA_SCRIPT_1of2 9 |
|||
#define IGUANA_SCRIPT_MSIG 10 |
|||
#define IGUANA_SCRIPT_DATA 11 |
|||
#define IGUANA_SCRIPT_AC 12 |
|||
#define IGUANA_SCRIPT_1of1 13 |
|||
#define IGUANA_SCRIPT_STRANGE 15 |
|||
|
|||
#define BASILISK_TIMEOUT 3000 |
|||
#define BASILISK_MINFANOUT 8 |
|||
#define BASILISK_MAXFANOUT 64 |
|||
#define BASILISK_DEFAULTDIFF 0x1effffff |
|||
#define BASILISK_HDROFFSET ((int32_t)(sizeof(bits256)+sizeof(struct iguana_msghdr)+sizeof(uint32_t))) |
|||
|
|||
#define INSTANTDEX_DECKSIZE 1000 |
|||
#define INSTANTDEX_LOCKTIME (3600*2 + 300*2) |
|||
#define INSTANTDEX_INSURANCEDIV 777 |
|||
#define INSTANTDEX_PUBKEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" |
|||
#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" |
|||
#define JUMBLR_RMD160 "5177f8b427e5f47342a4b8ab5dac770815d4389e" |
|||
#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" |
|||
#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" |
|||
#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" |
|||
|
|||
struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; }; |
|||
|
|||
struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; }; |
|||
|
|||
struct iguana_msgtx |
|||
{ |
|||
uint32_t version,tx_in,tx_out,lock_time; |
|||
struct iguana_msgvin *vins; |
|||
struct iguana_msgvout *vouts; |
|||
bits256 txid; |
|||
int32_t allocsize,timestamp,numinputs,numoutputs; |
|||
int64_t inputsum,outputsum,txfee; |
|||
uint8_t *serialized; |
|||
}; |
|||
|
|||
struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; |
|||
|
|||
struct vin_info |
|||
{ |
|||
struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; |
|||
int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys,ignore_cltverr; |
|||
uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; |
|||
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE],userdata[IGUANA_MAXSCRIPTSIZE]; |
|||
}; |
|||
|
|||
struct basilisk_swapmessage |
|||
{ |
|||
bits256 srchash,desthash; |
|||
uint32_t crc32,msgbits,quoteid,datalen; |
|||
uint8_t *data; |
|||
}; |
|||
|
|||
struct basilisk_swap; |
|||
|
|||
struct basilisk_rawtxinfo |
|||
{ |
|||
char destaddr[64],coinstr[16]; |
|||
bits256 txid,signedtxid,actualtxid; |
|||
uint64_t amount,change,inputsum; |
|||
int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; |
|||
uint32_t locktime,crcs[2]; |
|||
uint8_t addrtype,pubkey33[33],rmd160[20]; |
|||
}; |
|||
|
|||
struct basilisk_request |
|||
{ |
|||
uint32_t requestid,timestamp,quoteid,quotetime; // 0 to 15
|
|||
uint64_t srcamount,unused; // 16 to 31
|
|||
bits256 srchash; // 32 to 63
|
|||
bits256 desthash; |
|||
char src[8],dest[8]; |
|||
uint64_t destamount; |
|||
int32_t optionhours,DEXselector; |
|||
}; |
|||
|
|||
struct basilisk_rawtx |
|||
{ |
|||
char name[32]; |
|||
struct iguana_msgtx msgtx; |
|||
struct basilisk_rawtxinfo I; |
|||
struct iguana_info *coin; |
|||
char vinstr[8192],p2shaddr[64]; |
|||
cJSON *vins; |
|||
bits256 utxotxid; int32_t utxovout; |
|||
uint8_t txbytes[16384],spendscript[512],redeemscript[1024],extraspace[4096],pubkey33[33]; |
|||
}; |
|||
|
|||
struct basilisk_swapinfo |
|||
{ |
|||
struct basilisk_request req; |
|||
char bobstr[64],alicestr[64]; |
|||
bits256 myhash,otherhash,orderhash; |
|||
uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration; |
|||
int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad; |
|||
uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance; |
|||
|
|||
bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; |
|||
uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2]; |
|||
int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate,pad2; |
|||
uint8_t secretAm[20],secretBn[20]; |
|||
uint8_t secretAm256[32],secretBn256[32]; |
|||
uint8_t userdata_aliceclaim[256],userdata_aliceclaimlen; |
|||
uint8_t userdata_alicereclaim[256],userdata_alicereclaimlen; |
|||
uint8_t userdata_alicespend[256],userdata_alicespendlen; |
|||
uint8_t userdata_bobspend[256],userdata_bobspendlen; |
|||
uint8_t userdata_bobreclaim[256],userdata_bobreclaimlen; |
|||
uint8_t userdata_bobrefund[256],userdata_bobrefundlen; |
|||
}; |
|||
|
|||
struct iguana_info |
|||
{ |
|||
uint64_t txfee,estimatedfee; |
|||
int32_t longestchain; |
|||
uint8_t pubtype,p2shtype,isPoS,wiftype; |
|||
char symbol[16],changeaddr[64]; |
|||
}; |
|||
|
|||
struct basilisk_swap |
|||
{ |
|||
void *ctx; struct iguana_info bobcoin,alicecoin; |
|||
void (*balancingtrade)(struct basilisk_swap *swap,int32_t iambob); |
|||
int32_t subsock,pushsock,connected,aliceunconf,depositunconf,paymentunconf; uint32_t lasttime,aborted; |
|||
FILE *fp; |
|||
bits256 persistent_privkey,persistent_pubkey; |
|||
struct basilisk_swapinfo I; |
|||
struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; |
|||
bits256 privkeys[INSTANTDEX_DECKSIZE]; |
|||
struct basilisk_swapmessage *messages; int32_t nummessages; |
|||
char Bdeposit[64],Bpayment[64]; |
|||
uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; |
|||
uint8_t persistent_pubkey33[33],pad[15],verifybuf[65536]; |
|||
|
|||
}; |
|||
|
|||
static struct bitcoin_opcode { UT_hash_handle hh; uint8_t opcode,flags,stackitems; int8_t extralen; } *OPTABLE; static char *OPCODES[0x100]; static int32_t OPCODELENS[0x100]; |
|||
|
|||
#define SIGHASH_ALL 1 |
|||
#define SIGHASH_NONE 2 |
|||
#define SIGHASH_SINGLE 3 |
|||
#define SIGHASH_ANYONECANPAY 0x80 |
|||
|
|||
#define SCRIPT_OP_NOP 0x00 |
|||
#define SCRIPT_OP_TRUE 0x51 |
|||
#define SCRIPT_OP_2 0x52 |
|||
#define SCRIPT_OP_3 0x53 |
|||
#define SCRIPT_OP_4 0x54 |
|||
#define SCRIPT_OP_IF 0x63 |
|||
#define SCRIPT_OP_ELSE 0x67 |
|||
#define SCRIPT_OP_RETURN 0x6a |
|||
#define SCRIPT_OP_DUP 0x76 |
|||
#define SCRIPT_OP_ENDIF 0x68 |
|||
#define SCRIPT_OP_DROP 0x75 |
|||
#define SCRIPT_OP_EQUALVERIFY 0x88 |
|||
#define SCRIPT_OP_SHA256 0xa8 |
|||
#define SCRIPT_OP_HASH160 0xa9 |
|||
|
|||
#define SCRIPT_OP_EQUAL 0x87 |
|||
#define SCRIPT_OP_CHECKSIG 0xac |
|||
#define SCRIPT_OP_CHECKMULTISIG 0xae |
|||
#define SCRIPT_OP_CHECKSEQUENCEVERIFY 0xb2 |
|||
#define SCRIPT_OP_CHECKLOCKTIMEVERIFY 0xb1 |
|||
#define IGUANA_OP_0 0x00 |
|||
#define IGUANA_OP_PUSHDATA1 0x4c |
|||
#define IGUANA_OP_PUSHDATA2 0x4d |
|||
#define IGUANA_OP_PUSHDATA4 0x4e |
|||
#define IGUANA_OP_1NEGATE 0x4f |
|||
#define IGUANA_OP_1 0x51 |
|||
#define IGUANA_OP_16 0x60 |
|||
#define IGUANA_OP_NOP 0x61 |
|||
#define IGUANA_OP_IF 0x63 |
|||
#define IGUANA_OP_NOTIF 0x64 |
|||
#define IGUANA_OP_ELSE 0x67 |
|||
#define IGUANA_OP_ENDIF 0x68 |
|||
#define IGUANA_OP_VERIFY 0x69 |
|||
#define IGUANA_OP_RETURN 0x6a |
|||
|
|||
#define IGUANA_OP_TOALTSTACK 0x6b |
|||
#define IGUANA_OP_FROMALTSTACK 0x6c |
|||
#define IGUANA_OP_2DROP 0x6d |
|||
#define IGUANA_OP_2DUP 0x6e |
|||
#define IGUANA_OP_3DUP 0x6f |
|||
#define IGUANA_OP_2OVER 0x70 |
|||
#define IGUANA_OP_2ROT 0x71 |
|||
#define IGUANA_OP_2SWAP 0x72 |
|||
#define IGUANA_OP_IFDUP 0x73 |
|||
#define IGUANA_OP_DEPTH 0x74 |
|||
#define IGUANA_OP_DROP 0x75 |
|||
#define IGUANA_OP_DUP 0x76 |
|||
#define IGUANA_OP_NIP 0x77 |
|||
#define IGUANA_OP_OVER 0x78 |
|||
#define IGUANA_OP_PICK 0x79 |
|||
#define IGUANA_OP_ROLL 0x7a |
|||
#define IGUANA_OP_ROT 0x7b |
|||
#define IGUANA_OP_SWAP 0x7c |
|||
#define IGUANA_OP_TUCK 0x7d |
|||
|
|||
#define IGUANA_OP_EQUAL 0x87 |
|||
#define IGUANA_OP_EQUALVERIFY 0x88 |
|||
|
|||
#define IGUANA_OP_1ADD 0x8b |
|||
#define IGUANA_OP_1SUB 0x8c |
|||
#define IGUANA_OP_NEGATE 0x8f |
|||
#define IGUANA_OP_ABS 0x90 |
|||
#define IGUANA_OP_NOT 0x91 |
|||
#define IGUANA_OP_0NOTEQUAL 0x92 |
|||
#define IGUANA_OP_ADD 0x93 |
|||
#define IGUANA_OP_SUB 0x94 |
|||
|
|||
#define IGUANA_OP_BOOLAND 0x9a |
|||
#define IGUANA_OP_BOOLOR 0x9b |
|||
#define IGUANA_OP_NUMEQUAL 0x9c |
|||
#define IGUANA_OP_NUMEQUALVERIFY 0x9d |
|||
#define IGUANA_OP_NUMNOTEQUAL 0x9e |
|||
#define IGUANA_OP_LESSTHAN 0x9f |
|||
#define IGUANA_OP_GREATERTHAN 0xa0 |
|||
#define IGUANA_OP_LESSTHANOREQUAL 0xa1 |
|||
#define IGUANA_OP_GREATERTHANOREQUAL 0xa2 |
|||
#define IGUANA_OP_MIN 0xa3 |
|||
#define IGUANA_OP_MAX 0xa4 |
|||
#define IGUANA_OP_WITHIN 0xa5 |
|||
|
|||
#define IGUANA_OP_RIPEMD160 0xa6 |
|||
#define IGUANA_OP_SHA1 0xa7 |
|||
#define IGUANA_OP_SHA256 0xa8 |
|||
#define IGUANA_OP_HASH160 0xa9 |
|||
#define IGUANA_OP_HASH256 0xaa |
|||
#define IGUANA_OP_CODESEPARATOR 0xab |
|||
#define IGUANA_OP_CHECKSIG 0xac |
|||
#define IGUANA_OP_CHECKSIGVERIFY 0xad |
|||
#define IGUANA_OP_CHECKMULTISIG 0xae |
|||
#define IGUANA_OP_CHECKMULTISIGVERIFY 0xaf |
|||
|
|||
#define IGUANA_OP_NOP1 0xb0 |
|||
#define IGUANA_OP_CHECKLOCKTIMEVERIFY 0xb1 |
|||
#define IGUANA_OP_CHECKSEQUENCEVERIFY 0xb2 |
|||
#define IGUANA_OP_NOP10 0xb9 |
|||
|
|||
#define IGUANA_OP_COMBINEPUBKEYS 0xc0 |
|||
#define IGUANA_OP_CHECKSCHNORR 0xc1 |
|||
#define IGUANA_OP_CHECKSCHNORRVERIFY 0xc2 |
|||
|
|||
// https://github.com/TierNolan/bips/blob/cpkv/bip-cprkv.mediawiki
|
|||
#define IGUANA_OP_CHECKPRIVATEKEY 0xc3 |
|||
#define IGUANA_OP_CHECKPRIVATEKEYVERIFY 0xc4 |
|||
|
|||
#define IGUANA_NOPFLAG 1 |
|||
#define IGUANA_ALWAYSILLEGAL 2 |
|||
#define IGUANA_EXECUTIONILLEGAL 4 |
|||
#define IGUANA_POSTVERIFY 8 |
|||
#define IGUANA_CRYPTOFLAG 16 |
|||
#define IGUANA_MATHFLAG 32 |
|||
#define IGUANA_CONTROLFLAG 64 |
|||
#define IGUANA_STACKFLAG 128 |
|||
|
|||
enum opcodetype |
|||
{ |
|||
// push value
|
|||
OP_0 = 0x00, |
|||
OP_FALSE = OP_0, |
|||
OP_PUSHDATA1 = 0x4c, |
|||
OP_PUSHDATA2 = 0x4d, |
|||
OP_PUSHDATA4 = 0x4e, |
|||
OP_1NEGATE = 0x4f, |
|||
OP_RESERVED = 0x50, |
|||
OP_1 = 0x51, |
|||
OP_TRUE=OP_1, |
|||
OP_2 = 0x52, |
|||
OP_3 = 0x53, |
|||
OP_4 = 0x54, |
|||
OP_5 = 0x55, |
|||
OP_6 = 0x56, |
|||
OP_7 = 0x57, |
|||
OP_8 = 0x58, |
|||
OP_9 = 0x59, |
|||
OP_10 = 0x5a, |
|||
OP_11 = 0x5b, |
|||
OP_12 = 0x5c, |
|||
OP_13 = 0x5d, |
|||
OP_14 = 0x5e, |
|||
OP_15 = 0x5f, |
|||
OP_16 = 0x60, |
|||
|
|||
// control
|
|||
OP_NOP = 0x61, |
|||
OP_VER = 0x62, |
|||
OP_IF = 0x63, |
|||
OP_NOTIF = 0x64, |
|||
OP_VERIF = 0x65, |
|||
OP_VERNOTIF = 0x66, |
|||
OP_ELSE = 0x67, |
|||
OP_ENDIF = 0x68, |
|||
OP_VERIFY = 0x69, |
|||
OP_RETURN = 0x6a, |
|||
|
|||
// stack ops
|
|||
OP_TOALTSTACK = 0x6b, |
|||
OP_FROMALTSTACK = 0x6c, |
|||
OP_2DROP = 0x6d, |
|||
OP_2DUP = 0x6e, |
|||
OP_3DUP = 0x6f, |
|||
OP_2OVER = 0x70, |
|||
OP_2ROT = 0x71, |
|||
OP_2SWAP = 0x72, |
|||
OP_IFDUP = 0x73, |
|||
OP_DEPTH = 0x74, |
|||
OP_DROP = 0x75, |
|||
OP_DUP = 0x76, |
|||
OP_NIP = 0x77, |
|||
OP_OVER = 0x78, |
|||
OP_PICK = 0x79, |
|||
OP_ROLL = 0x7a, |
|||
OP_ROT = 0x7b, |
|||
OP_SWAP = 0x7c, |
|||
OP_TUCK = 0x7d, |
|||
|
|||
// splice ops
|
|||
OP_CAT = 0x7e, |
|||
OP_SUBSTR = 0x7f, |
|||
OP_LEFT = 0x80, |
|||
OP_RIGHT = 0x81, |
|||
OP_SIZE = 0x82, |
|||
|
|||
// bit logic
|
|||
OP_INVERT = 0x83, |
|||
OP_AND = 0x84, |
|||
OP_OR = 0x85, |
|||
OP_XOR = 0x86, |
|||
OP_EQUAL = 0x87, |
|||
OP_EQUALVERIFY = 0x88, |
|||
OP_RESERVED1 = 0x89, |
|||
OP_RESERVED2 = 0x8a, |
|||
|
|||
// numeric
|
|||
OP_1ADD = 0x8b, |
|||
OP_1SUB = 0x8c, |
|||
OP_2MUL = 0x8d, |
|||
OP_2DIV = 0x8e, |
|||
OP_NEGATE = 0x8f, |
|||
OP_ABS = 0x90, |
|||
OP_NOT = 0x91, |
|||
OP_0NOTEQUAL = 0x92, |
|||
|
|||
OP_ADD = 0x93, |
|||
OP_SUB = 0x94, |
|||
OP_MUL = 0x95, |
|||
OP_DIV = 0x96, |
|||
OP_MOD = 0x97, |
|||
OP_LSHIFT = 0x98, |
|||
OP_RSHIFT = 0x99, |
|||
|
|||
OP_BOOLAND = 0x9a, |
|||
OP_BOOLOR = 0x9b, |
|||
OP_NUMEQUAL = 0x9c, |
|||
OP_NUMEQUALVERIFY = 0x9d, |
|||
OP_NUMNOTEQUAL = 0x9e, |
|||
OP_LESSTHAN = 0x9f, |
|||
OP_GREATERTHAN = 0xa0, |
|||
OP_LESSTHANOREQUAL = 0xa1, |
|||
OP_GREATERTHANOREQUAL = 0xa2, |
|||
OP_MIN = 0xa3, |
|||
OP_MAX = 0xa4, |
|||
|
|||
OP_WITHIN = 0xa5, |
|||
|
|||
// crypto
|
|||
OP_RIPEMD160 = 0xa6, |
|||
OP_SHA1 = 0xa7, |
|||
OP_SHA256 = 0xa8, |
|||
OP_HASH160 = 0xa9, |
|||
OP_HASH256 = 0xaa, |
|||
OP_CODESEPARATOR = 0xab, |
|||
OP_CHECKSIG = 0xac, |
|||
OP_CHECKSIGVERIFY = 0xad, |
|||
OP_CHECKMULTISIG = 0xae, |
|||
OP_CHECKMULTISIGVERIFY = 0xaf, |
|||
|
|||
// expansion
|
|||
OP_NOP1 = 0xb0, |
|||
OP_CHECKLOCKTIMEVERIFY = 0xb1, |
|||
OP_CHECKSEQUENCEVERIFY = 0xb2, |
|||
OP_NOP4 = 0xb3, |
|||
OP_NOP5 = 0xb4, |
|||
OP_NOP6 = 0xb5, |
|||
OP_NOP7 = 0xb6, |
|||
OP_NOP8 = 0xb7, |
|||
OP_NOP9 = 0xb8, |
|||
OP_NOP10 = 0xb9, |
|||
|
|||
OP_COMBINEPUBKEYS = 0xc0, |
|||
OP_CHECKSCHNORR = 0xc1, |
|||
OP_CHECKSCHNORRVERIFY = 0xc2, |
|||
OP_CHECKPRIVATEKEY = 0xc3, |
|||
OP_CHECKPRIVATEKEYVERIFY = 0xc4, |
|||
|
|||
// template matching params
|
|||
//OP_SMALLINTEGER = 0xfa,
|
|||
//OP_PUBKEYS = 0xfb,
|
|||
//OP_PUBKEYHASH = 0xfd,
|
|||
//OP_PUBKEY = 0xfe,
|
|||
|
|||
OP_INVALIDOPCODE = 0xff, |
|||
}; |
|||
void basilisk_dontforget_update(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx); |
|||
uint32_t basilisk_requestid(struct basilisk_request *rp); |
|||
uint32_t basilisk_quoteid(struct basilisk_request *rp); |
|||
|
|||
#endif |
@ -0,0 +1,307 @@ |
|||
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2017 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_network.c
|
|||
// marketmaker
|
|||
//
|
|||
|
|||
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp) |
|||
{ |
|||
/* char keystr[64],databuf[1024],pubkeystr[128],*retstr,*retstr2,*datastr,*pushaddr=0,*subaddr=0; cJSON *retjson,*addrjson; uint8_t data[512]; int32_t datalen,timeout,pushsock = -1,subsock = -1;
|
|||
if ( swap->connected == 1 ) |
|||
return; |
|||
if ( swap->pushsock < 0 && swap->subsock < 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 ) |
|||
{ |
|||
timeout = 1000; |
|||
nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)); |
|||
timeout = 1; |
|||
nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)); |
|||
nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); |
|||
swap->pushsock = pushsock; |
|||
swap->subsock = subsock; |
|||
} |
|||
if ( (subsock= swap->subsock) < 0 || (pushsock= swap->pushsock) < 0 ) |
|||
{ |
|||
printf("error getting nn_sockets\n"); |
|||
return; |
|||
} |
|||
sprintf(keystr,"%08x-%08x",swap->I.req.requestid,swap->I.req.quoteid); |
|||
if ( swap->connected == 0 && (retstr= _dex_kvsearch("KV",keystr)) != 0 ) |
|||
{ |
|||
if ( (retjson= cJSON_Parse(retstr)) != 0 ) |
|||
{ |
|||
if ( (datastr= jstr(retjson,"value")) != 0 ) |
|||
{ |
|||
datalen = (int32_t)strlen(datastr) >> 1; |
|||
decode_hex((uint8_t *)databuf,datalen,datastr); |
|||
if ( (addrjson= cJSON_Parse(databuf)) != 0 ) |
|||
{ |
|||
pushaddr = jstr(addrjson,"push"); |
|||
subaddr = jstr(addrjson,"sub"); |
|||
if ( pushaddr != 0 && subaddr != 0 ) |
|||
{ |
|||
printf("KV decoded (%s and %s) %d %d\n",pushaddr,subaddr,swap->pushsock,swap->subsock); |
|||
if ( nn_connect(swap->pushsock,pushaddr) >= 0 && nn_connect(swap->subsock,subaddr) >= 0 ) |
|||
swap->connected = 1; |
|||
} |
|||
free_json(addrjson); |
|||
} |
|||
} |
|||
free_json(retjson); |
|||
} |
|||
printf("KVsearch.(%s) -> (%s) connected.%d socks.(%d %d) amlp.%d\n",keystr,retstr,swap->connected,swap->pushsock,swap->subsock,amlp); |
|||
free(retstr); |
|||
} |
|||
printf("connected.%d amlp.%d subsock.%d pushsock.%d\n",swap->connected,amlp,subsock,pushsock); |
|||
if ( swap->connected <= 0 && amlp != 0 && subsock >= 0 && pushsock >= 0 ) |
|||
{ |
|||
if ( (retstr= _dex_psock("{}")) != 0 ) |
|||
{ |
|||
printf("psock returns.(%s)\n",retstr); |
|||
// {"result":"success","pushaddr":"tcp://5.9.102.210:30002","subaddr":"tcp://5.9.102.210:30003","randipbits":3606291758,"coin":"KMD","tag":"6952562460568228137"}
|
|||
if ( (retjson= cJSON_Parse(retstr)) != 0 ) |
|||
{ |
|||
pushaddr = jstr(retjson,"pushaddr"); |
|||
subaddr = jstr(retjson,"subaddr"); |
|||
if ( pushaddr != 0 && subaddr != 0 ) |
|||
{ |
|||
if ( nn_connect(pushsock,pushaddr) >= 0 ) |
|||
{ |
|||
printf("connected to %d pushaddr.(%s)\n",pushsock,pushaddr); |
|||
if ( nn_connect(subsock,subaddr) >= 0 ) |
|||
{ |
|||
swap->connected = 1; |
|||
init_hexbytes_noT(pubkeystr,myinfo->persistent_pubkey33,33); |
|||
sprintf((char *)data,"{\"push\":\"%s\",\"sub\":\"%s\",\"trade\":[\"%s\", %.8f, \"%s\", %.8f],\"pub\":\"%s\"}",pushaddr,subaddr,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),pubkeystr); |
|||
datalen = (int32_t)strlen((char *)data) + 1; |
|||
printf("datalen.%d (%s)\n",datalen,(char *)data); |
|||
init_hexbytes_noT(databuf,data,datalen); |
|||
printf("%s -> %s\n",keystr,databuf); |
|||
if ( (retstr2= _dex_kvupdate("KV",keystr,databuf,1)) != 0 ) |
|||
{ |
|||
printf("KVupdate.(%s)\n",retstr2); |
|||
free(retstr2); |
|||
} |
|||
} else printf("nn_connect error to %d subaddr.(%s)\n",subsock,subaddr); |
|||
} else printf("nn_connect error to %d pushaddr.(%s)\n",pushsock,pushaddr); |
|||
} |
|||
else printf("missing addr (%p) (%p) (%s)\n",pushaddr,subaddr,jprint(retjson,0)); |
|||
free_json(retjson); |
|||
} else printf("Error parsing psock.(%s)\n",retstr); |
|||
free(retstr); |
|||
} else printf("error issuing _dex_psock\n"); |
|||
}*/ |
|||
} |
|||
|
|||
char *nanomsg_tcpname(char *str,char *ipaddr,uint16_t port) |
|||
{ |
|||
sprintf(str,"tcp://%s:%u",ipaddr,port); |
|||
return(str); |
|||
} |
|||
|
|||
int32_t LP_send(int32_t sock,char *msg,int32_t freeflag) |
|||
{ |
|||
int32_t sentbytes,len,i; struct nn_pollfd pfd; |
|||
for (i=0; i<100; i++) |
|||
{ |
|||
pfd.fd = sock; |
|||
pfd.events = NN_POLLOUT; |
|||
if ( nn_poll(&pfd,1,100) > 0 ) |
|||
{ |
|||
len = (int32_t)strlen(msg) + 1; |
|||
if ( (sentbytes= nn_send(sock,msg,len,0)) != len ) |
|||
printf("LP_send sent %d instead of %d\n",sentbytes,len); |
|||
else printf("SENT.(%s)\n",msg); |
|||
if ( freeflag != 0 ) |
|||
free(msg); |
|||
return(sentbytes); |
|||
} |
|||
usleep(1000); |
|||
} |
|||
printf("error LP_send\n"); |
|||
return(-1); |
|||
} |
|||
|
|||
uint32_t LP_swapsend(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2]) |
|||
{ |
|||
uint8_t *buf; int32_t sentbytes,offset=0,i; |
|||
buf = malloc(datalen + sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2); |
|||
for (i=0; i<32; i++) |
|||
buf[offset++] = swap->I.myhash.bytes[i]; |
|||
for (i=0; i<32; i++) |
|||
buf[offset++] = swap->I.otherhash.bytes[i]; |
|||
offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); |
|||
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); |
|||
if ( datalen > 0 ) |
|||
memcpy(&buf[offset],data,datalen), offset += datalen; |
|||
if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset ) |
|||
{ |
|||
printf("sentbytes.%d vs offset.%d\n",sentbytes,offset); |
|||
if ( sentbytes < 0 ) |
|||
{ |
|||
if ( swap->pushsock >= 0 ) |
|||
nn_close(swap->pushsock), swap->pushsock = -1; //,
|
|||
if ( swap->subsock >= 0 ) //
|
|||
nn_close(swap->subsock), swap->subsock = -1; |
|||
swap->connected = swap->I.iambob != 0 ? -1 : 0; |
|||
swap->aborted = (uint32_t)time(NULL); |
|||
} |
|||
} |
|||
//else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data);
|
|||
free(buf); |
|||
return(nextbits); |
|||
} |
|||
|
|||
void basilisk_swap_sendabort(struct basilisk_swap *swap) |
|||
{ |
|||
uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0; |
|||
memset(buf,0,sizeof(buf)); |
|||
offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid); |
|||
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits); |
|||
if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset ) |
|||
{ |
|||
if ( sentbytes < 0 ) |
|||
{ |
|||
if ( swap->pushsock >= 0 ) //
|
|||
nn_close(swap->pushsock), swap->pushsock = -1; |
|||
if ( swap->subsock >= 0 ) //
|
|||
nn_close(swap->subsock), swap->subsock = -1; |
|||
swap->connected = 0; |
|||
} |
|||
} else printf("basilisk_swap_sendabort\n"); |
|||
} |
|||
|
|||
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp); |
|||
|
|||
void basilisk_swapgotdata(struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit) |
|||
{ |
|||
int32_t i; struct basilisk_swapmessage *mp; |
|||
for (i=0; i<swap->nummessages; i++) |
|||
if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 ) |
|||
return; |
|||
//printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data);
|
|||
swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1)); |
|||
mp = &swap->messages[swap->nummessages++]; |
|||
mp->crc32 = crc32; |
|||
mp->srchash = srchash; |
|||
mp->desthash = desthash; |
|||
mp->msgbits = msgbits; |
|||
mp->quoteid = quoteid; |
|||
mp->data = malloc(datalen); |
|||
mp->datalen = datalen; |
|||
memcpy(mp->data,data,datalen); |
|||
if ( reinit == 0 && swap->fp != 0 ) |
|||
{ |
|||
fwrite(mp,1,sizeof(*mp),swap->fp); |
|||
fwrite(data,1,datalen,swap->fp); |
|||
fflush(swap->fp); |
|||
} |
|||
} |
|||
|
|||
int32_t basilisk_swapget(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(void *ptr,uint8_t *data,int32_t datalen)) |
|||
{ |
|||
uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0; |
|||
while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,0)) >= 0 ) |
|||
{ |
|||
swap->lasttime = (uint32_t)time(NULL); |
|||
memset(srchash.bytes,0,sizeof(srchash)); |
|||
memset(desthash.bytes,0,sizeof(desthash)); |
|||
//printf("gotmsg.[%d] crc.%x\n",size,crc32);
|
|||
offset = 0; |
|||
for (i=0; i<32; i++) |
|||
srchash.bytes[i] = ptr[offset++]; |
|||
for (i=0; i<32; i++) |
|||
desthash.bytes[i] = ptr[offset++]; |
|||
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),"eid); |
|||
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits); |
|||
if ( size > offset ) |
|||
{ |
|||
crc32 = calc_crc32(0,&ptr[offset],size-offset); |
|||
if ( size > offset ) |
|||
{ |
|||
//printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset);
|
|||
basilisk_swapgotdata(swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0); |
|||
} |
|||
} |
|||
else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 ) |
|||
{ |
|||
if ( swap->aborted == 0 ) |
|||
{ |
|||
swap->aborted = (uint32_t)time(NULL); |
|||
printf("got abort signal from other side\n"); |
|||
} |
|||
} else printf("basilisk_swapget: got strange packet\n"); |
|||
if ( ptr != 0 ) |
|||
nn_freemsg(ptr), ptr = 0; |
|||
} |
|||
//char str[65],str2[65];
|
|||
for (i=0; i<swap->nummessages; i++) |
|||
{ |
|||
//printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash));
|
|||
if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 ) |
|||
{ |
|||
if ( swap->messages[i].msgbits == msgbits ) |
|||
{ |
|||
if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 ) |
|||
{ |
|||
printf("nothing received for a while from Bob, try new sockets\n"); |
|||
if ( swap->pushsock >= 0 ) //
|
|||
nn_close(swap->pushsock), swap->pushsock = -1; |
|||
if ( swap->subsock >= 0 ) //
|
|||
nn_close(swap->subsock), swap->subsock = -1; |
|||
swap->connected = 0; |
|||
basilisk_psockinit(swap,swap->I.iambob != 0); |
|||
} |
|||
mp = &swap->messages[i]; |
|||
if ( msgbits != 0x80000000 ) |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
if ( mp != 0 ) |
|||
retval = (*basilisk_verify_func)(swap,mp->data,mp->datalen); |
|||
//printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash));
|
|||
return(retval); |
|||
} |
|||
|
|||
int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp) |
|||
{ |
|||
int32_t keylen = 0; |
|||
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),channelp); |
|||
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),msgidp); |
|||
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*srchashp),srchashp->bytes); |
|||
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*desthashp),desthashp->bytes); |
|||
return(keylen); |
|||
} |
|||
|
|||
int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash) |
|||
{ |
|||
int32_t keylen = 0; |
|||
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel); |
|||
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid); |
|||
keylen += iguana_rwbignum(1,&key[keylen],sizeof(srchash),srchash.bytes); |
|||
keylen += iguana_rwbignum(1,&key[keylen],sizeof(desthash),desthash.bytes); |
|||
return(keylen); |
|||
} |
|||
|
|||
void LP_channelsend(bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen) |
|||
{ |
|||
int32_t keylen; uint8_t key[BASILISK_KEYSIZE]; //char *retstr;
|
|||
keylen = basilisk_messagekey(key,channel,msgid,srchash,desthash); |
|||
//if ( (retstr= _dex_reqsend(myinfo,"DEX",key,keylen,data,datalen)) != 0 )
|
|||
// free(retstr);
|
|||
} |
|||
|
@ -0,0 +1,505 @@ |
|||
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2017 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_rpc.c
|
|||
// marketmaker
|
|||
//
|
|||
|
|||
cJSON *basilisk_nullretjson(cJSON *retjson) |
|||
{ |
|||
char *outstr; |
|||
if ( retjson != 0 ) |
|||
{ |
|||
outstr = jprint(retjson,0); |
|||
if ( strcmp(outstr,"{}") == 0 ) |
|||
{ |
|||
free_json(retjson); |
|||
retjson = 0; |
|||
} |
|||
free(outstr); |
|||
} |
|||
return(retjson); |
|||
} |
|||
|
|||
void LP_unspentslock(char *symbol,cJSON *vins) |
|||
{ |
|||
|
|||
} |
|||
|
|||
void LP_unspents_mark(char *symbol,cJSON *vins) |
|||
{ |
|||
|
|||
} |
|||
|
|||
uint64_t LP_getestimatedfee(char *symbol) |
|||
{ |
|||
return(200); |
|||
} |
|||
|
|||
uint64_t LP_txfee(char *symbol) |
|||
{ |
|||
return(10000); |
|||
} |
|||
|
|||
char *dpow_validateaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *address) |
|||
{ |
|||
char buf[128],*retstr=0; |
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
sprintf(buf,"\"%s\"",address); |
|||
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"validateaddress",buf); |
|||
usleep(10000); |
|||
} |
|||
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) |
|||
{ |
|||
retstr = bitcoinrpc_validateaddress(myinfo,coin,0,0,address); |
|||
} |
|||
else |
|||
{ |
|||
return(0); |
|||
} |
|||
return(retstr); |
|||
} |
|||
|
|||
cJSON *dpow_gettxout(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid,int32_t vout) |
|||
{ |
|||
char buf[128],str[65],*retstr=0; cJSON *json = 0; |
|||
sprintf(buf,"\"%s\", %d",bits256_str(str,txid),vout); |
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"gettxout",buf); |
|||
usleep(10000); |
|||
} |
|||
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) |
|||
{ |
|||
printf("need to test following call\n"); |
|||
retstr = bitcoinrpc_gettxout(myinfo,coin,0,buf,txid,1,0); // untested
|
|||
} |
|||
else |
|||
{ |
|||
return(0); |
|||
} |
|||
if ( retstr != 0 ) |
|||
{ |
|||
json = cJSON_Parse(retstr); |
|||
free(retstr); |
|||
} |
|||
//printf("dpow_gettxout.(%s)\n",retstr);
|
|||
return(json); |
|||
} |
|||
|
|||
char *dpow_decoderawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx) |
|||
{ |
|||
char *retstr,*paramstr; cJSON *array; |
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
array = cJSON_CreateArray(); |
|||
jaddistr(array,rawtx); |
|||
paramstr = jprint(array,1); |
|||
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"decoderawtransaction",paramstr); |
|||
//printf("%s decoderawtransaction.(%s) <- (%s)\n",coin->symbol,retstr,paramstr);
|
|||
free(paramstr); |
|||
usleep(10000); |
|||
} |
|||
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) |
|||
{ |
|||
retstr = bitcoinrpc_decoderawtransaction(myinfo,coin,0,0,rawtx,1); |
|||
} |
|||
else |
|||
{ |
|||
return(0); |
|||
} |
|||
return(retstr); |
|||
} |
|||
|
|||
cJSON *dpow_gettransaction(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid) |
|||
{ |
|||
char buf[128],str[65],*retstr=0; cJSON *json = 0; |
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
sprintf(buf,"[\"%s\", 1]",bits256_str(str,txid)); |
|||
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",buf)) != 0 ) |
|||
{ |
|||
} |
|||
usleep(10000); |
|||
} |
|||
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) |
|||
{ |
|||
retstr = bitcoinrpc_getrawtransaction(myinfo,coin,0,0,txid,1); |
|||
} |
|||
else |
|||
{ |
|||
return(0); |
|||
} |
|||
if ( retstr != 0 ) |
|||
{ |
|||
json = cJSON_Parse(retstr); |
|||
free(retstr); |
|||
} |
|||
return(json); |
|||
} |
|||
|
|||
cJSON *dpow_listunspent(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) |
|||
{ |
|||
char buf[128],*retstr; cJSON *array,*json = 0; |
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
sprintf(buf,"0, 99999999, [\"%s\"]",coinaddr); |
|||
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",buf)) != 0 ) |
|||
{ |
|||
json = cJSON_Parse(retstr); |
|||
//printf("%s (%s) listunspent.(%s)\n",coin->symbol,buf,retstr);
|
|||
free(retstr); |
|||
} else printf("%s null retstr from (%s)n",coin->symbol,buf); |
|||
} |
|||
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) |
|||
{ |
|||
array = cJSON_CreateArray(); |
|||
jaddistr(array,coinaddr); |
|||
json = iguana_listunspents(myinfo,coin,array,1,coin->longestchain,""); |
|||
free_json(array); |
|||
} |
|||
else |
|||
{ |
|||
return(0); |
|||
} |
|||
return(json); |
|||
} |
|||
|
|||
cJSON *dpow_listtransactions(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,int32_t count,int32_t skip) |
|||
{ |
|||
char buf[128],*retstr; cJSON *json = 0; |
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
if ( count == 0 ) |
|||
count = 100; |
|||
sprintf(buf,"[\"%s\", %d, %d, true]",coinaddr,count,skip); |
|||
if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listtransactions",buf)) != 0 ) |
|||
{ |
|||
//printf("LIST.(%s)\n",retstr);
|
|||
json = cJSON_Parse(retstr); |
|||
free(retstr); |
|||
return(json); |
|||
} else printf("%s null retstr from (%s)n",coin->symbol,buf); |
|||
} |
|||
return(0); |
|||
} |
|||
|
|||
char *dpow_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *rawtx,cJSON *vins) |
|||
{ |
|||
cJSON *array,*privkeys,*item; char *wifstr,*str,*paramstr,*retstr; uint8_t script[256]; int32_t i,n,len,hashtype; struct vin_info V; struct iguana_waddress *waddr; struct iguana_waccount *wacct; |
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
array = cJSON_CreateArray(); |
|||
jaddistr(array,rawtx); |
|||
jaddi(array,jduplicate(vins)); |
|||
paramstr = jprint(array,1); |
|||
//printf("signrawtransaction\n");
|
|||
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"signrawtransaction",paramstr); |
|||
//printf("%s signrawtransaction.(%s) params.(%s)\n",coin->symbol,retstr,paramstr);
|
|||
free(paramstr); |
|||
usleep(10000); |
|||
return(retstr); |
|||
} |
|||
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) |
|||
{ |
|||
privkeys = cJSON_CreateArray(); |
|||
if ( (n= cJSON_GetArraySize(vins)) > 0 ) |
|||
{ |
|||
for (i=0; i<n; i++) |
|||
{ |
|||
wifstr = ""; |
|||
item = jitem(vins,i); |
|||
if ( (str= jstr(item,"scriptPubkey")) != 0 && is_hexstr(str,0) > 0 && strlen(str) < sizeof(script)*2 ) |
|||
{ |
|||
len = (int32_t)strlen(str) >> 1; |
|||
decode_hex(script,len,str); |
|||
V.spendlen = len; |
|||
memcpy(V.spendscript,script,len); |
|||
if ( (hashtype= _iguana_calcrmd160(coin,&V)) >= 0 && V.coinaddr[0] != 0 ) |
|||
{ |
|||
if ( (waddr= iguana_waddresssearch(myinfo,&wacct,V.coinaddr)) != 0 ) |
|||
{ |
|||
if ( bits256_nonz(waddr->privkey) != 0 ) |
|||
{ |
|||
if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) |
|||
{ |
|||
wifstr = waddr->wifstr; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
jaddistr(privkeys,wifstr); |
|||
} |
|||
} |
|||
retstr = bitcoinrpc_signrawtransaction(myinfo,coin,0,0,rawtx,vins,privkeys,"ALL"); |
|||
printf("call sign.(%s) vins.(%s) privs.(%s) -> (%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),retstr); |
|||
free_json(privkeys); |
|||
return(retstr); |
|||
} |
|||
else |
|||
{ |
|||
return(0); |
|||
} |
|||
} |
|||
|
|||
char *dpow_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx) |
|||
{ |
|||
bits256 txid; cJSON *json,*array; char *paramstr,*retstr; |
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
array = cJSON_CreateArray(); |
|||
jaddistr(array,signedtx); |
|||
paramstr = jprint(array,1); |
|||
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"sendrawtransaction",paramstr); |
|||
printf(">>>>>>>>>>> %s dpow_sendrawtransaction.(%s) -> (%s)\n",coin->symbol,paramstr,retstr); |
|||
free(paramstr); |
|||
return(retstr); |
|||
} |
|||
else if ( coin->FULLNODE > 0 || coin->VALIDATENODE > 0 ) |
|||
{ |
|||
txid = iguana_sendrawtransaction(myinfo,coin,signedtx); |
|||
json = cJSON_CreateObject(); |
|||
jaddbits256(json,"result",txid); |
|||
return(jprint(json,1)); |
|||
} |
|||
else |
|||
{ |
|||
return(0); |
|||
} |
|||
} |
|||
|
|||
char *LP_importaddress(char *symbol,char *address) |
|||
{ |
|||
char buf[1024],*retstr; cJSON *validatejson; int32_t isvalid=0,doneflag = 0; |
|||
if ( (retstr= LP_validateaddress(symbol,address)) != 0 ) |
|||
{ |
|||
if ( (validatejson= cJSON_Parse(retstr)) != 0 ) |
|||
{ |
|||
if ( (isvalid= is_cJSON_True(jobj(validatejson,"isvalid")) != 0) != 0 ) |
|||
{ |
|||
if ( is_cJSON_True(jobj(validatejson,"iswatchonly")) != 0 || is_cJSON_True(jobj(validatejson,"ismine")) != 0 ) |
|||
doneflag = 1; |
|||
} |
|||
free_json(validatejson); |
|||
} |
|||
free(retstr); |
|||
retstr = 0; |
|||
} |
|||
if ( isvalid == 0 ) |
|||
return(clonestr("{\"isvalid\":false}")); |
|||
update_alladdresses(myinfo,coin,address); |
|||
if ( doneflag != 0 ) |
|||
return(0); // success
|
|||
if ( coin->FULLNODE < 0 ) |
|||
{ |
|||
sprintf(buf,"[\"%s\", \"%s\", false]",address,address); |
|||
retstr = bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"importaddress",buf); |
|||
printf("%s importaddress.(%s) -> (%s)\n",coin->symbol,address,retstr); |
|||
return(retstr); |
|||
} |
|||
else return(0); |
|||
} |
|||
|
|||
char *LP_importaddress(char *symbol,char *coinaddr) |
|||
{ |
|||
return(0); |
|||
} |
|||
|
|||
char *LP_sendrawtransaction(char *symbol,char *signedtx) |
|||
{ |
|||
return(0); |
|||
} |
|||
|
|||
char *LP_signrawtx(char *symbol,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtxbytes,cJSON *privkeys,struct vin_info *V) |
|||
{ |
|||
return(0); |
|||
} |
|||
|
|||
cJSON *LP_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip) |
|||
{ |
|||
return(0); |
|||
} |
|||
|
|||
char *dex_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_t skip) |
|||
{ |
|||
return(0); |
|||
} |
|||
|
|||
bits256 LP_privkey(char *coinaddr) |
|||
{ |
|||
bits256 privkey; |
|||
return(privkey); |
|||
} |
|||
|
|||
bits256 LP_pubkey(bits256 privkey) |
|||
{ |
|||
bits256 pubkey; |
|||
pubkey = curve25519(privkey,curve25519_basepoint9()); |
|||
return(pubkey); |
|||
} |
|||
|
|||
cJSON *LP_swapgettxout(char *symbol,bits256 trigger,int32_t vout) |
|||
{ |
|||
cJSON *retjson=0; //char *retstr; struct iguana_info *coin;
|
|||
/*if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 )
|
|||
{ |
|||
if ( (retstr= dex_gettxout(0,0,0,trigger,symbol,vout)) != 0 ) |
|||
{ |
|||
//printf("dexgettxout.(%s)\n",retstr);
|
|||
retjson = cJSON_Parse(retstr); |
|||
free(retstr); |
|||
} |
|||
if ( 0 && strcmp("BTC",symbol) == 0 ) |
|||
printf("%s gettxout.(%s)\n",symbol,jprint(retjson,0)); |
|||
} |
|||
else |
|||
{ |
|||
retjson = dpow_gettxout(coin,trigger,vout); |
|||
//printf("need to verify passthru has this info\n");
|
|||
//printf("dpowgettxout.(%s)\n",jprint(retjson,0));
|
|||
}*/ |
|||
return(basilisk_nullretjson(retjson)); |
|||
} |
|||
|
|||
uint64_t LP_txvalue(char *symbol,bits256 txid,int32_t vout) |
|||
{ |
|||
uint64_t value = 0; |
|||
return(value); |
|||
} |
|||
|
|||
cJSON *LP_swapgettx(char *symbol,bits256 txid) |
|||
{ |
|||
cJSON *retjson=0; //char *retstr; struct iguana_info *coin;
|
|||
/*if ( ((coin= iguana_coinfind(symbol)) == 0 || coin->FULLNODE == 0) && iguana_isnotarychain(symbol) >= 0 )
|
|||
{ |
|||
if ( (retstr= dex_gettransaction(0,0,0,txid,symbol)) != 0 ) |
|||
{ |
|||
retjson = cJSON_Parse(retstr); |
|||
free(retstr); |
|||
} |
|||
//if ( strcmp("BTC",symbol) == 0 )
|
|||
// printf("%s gettx.(%s)\n",symbol,jprint(retjson,0));
|
|||
} else retjson = dpow_gettransaction(coin,txid);*/ |
|||
return(basilisk_nullretjson(retjson)); |
|||
} |
|||
|
|||
bits256 basilisk_swap_sendrawtransaction(char *txname,char *symbol,char *txbytes) |
|||
{ |
|||
char *retstr; bits256 txid; int32_t i,sentflag = 0; |
|||
memset(&txid,0,sizeof(txid)); |
|||
for (i=0; i<3; i++) |
|||
{ |
|||
if ( (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 ) |
|||
{ |
|||
if ( is_hexstr(retstr,0) == 64 ) |
|||
{ |
|||
decode_hex(txid.bytes,32,retstr); |
|||
sentflag = 1; |
|||
} |
|||
char str[65]; printf("[%s] %s RETSTR.(%s) %s.%s\n",txname,txbytes,retstr,symbol,bits256_str(str,txid)); |
|||
free(retstr); |
|||
} |
|||
if ( sentflag != 0 ) |
|||
break; |
|||
} |
|||
return(txid); |
|||
} |
|||
|
|||
bits256 LP_broadcast(char *name,char *symbol,uint8_t *data,int32_t datalen) |
|||
{ |
|||
bits256 txid; char *signedtx,*retstr; int32_t i; |
|||
memset(txid.bytes,0,sizeof(txid)); |
|||
if ( data != 0 && datalen != 0 ) |
|||
{ |
|||
char str[65]; |
|||
#ifdef BASILISK_DISABLESENDTX |
|||
txid = bits256_doublesha256(0,data,datalen); |
|||
printf("%s <- dont sendrawtransaction (%s)\n",name,bits256_str(str,txid)); |
|||
return(txid); |
|||
#endif |
|||
signedtx = malloc(datalen*2 + 1); |
|||
init_hexbytes_noT(signedtx,data,datalen); |
|||
for (i=0; i<3; i++) |
|||
{ |
|||
if ( (retstr= LP_sendrawtransaction(symbol,signedtx)) != 0 ) |
|||
{ |
|||
if ( is_hexstr(retstr,0) == 64 ) |
|||
{ |
|||
decode_hex(txid.bytes,32,retstr); |
|||
free(retstr); |
|||
printf("sendrawtransaction.%s %s.(%s)\n",name,symbol,bits256_str(str,txid)); |
|||
break; |
|||
} |
|||
else |
|||
{ |
|||
printf("sendrawtransaction.%s %s error.(%s)\n",name,symbol,retstr); |
|||
free(retstr); |
|||
} |
|||
} else printf("sendrawtransaction.%s %s got null return\n",name,symbol); |
|||
} |
|||
free(signedtx); |
|||
} |
|||
return(txid); |
|||
} |
|||
|
|||
int32_t basilisk_confirmsobj(cJSON *item) |
|||
{ |
|||
int32_t height,numconfirms; |
|||
height = jint(item,"height"); |
|||
numconfirms = jint(item,"numconfirms"); |
|||
if ( height > 0 && numconfirms >= 0 ) |
|||
return(numconfirms); |
|||
printf("basilisk_confirmsobj height.%d numconfirms.%d (%s)\n",height,numconfirms,jprint(item,0)); |
|||
return(-1); |
|||
} |
|||
|
|||
int32_t LP_numconfirms(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx) |
|||
{ |
|||
#ifdef BASILISK_DISABLEWAITTX |
|||
return(100); |
|||
#endif |
|||
/*cJSON *argjson,*valuearray=0; char *valstr; int32_t i,n,retval = -1;
|
|||
argjson = cJSON_CreateObject(); |
|||
jaddbits256(argjson,"txid",rawtx->I.actualtxid); |
|||
jaddnum(argjson,"vout",0); |
|||
jaddstr(argjson,"coin",rawtx->coin->symbol); |
|||
if ( (valstr= basilisk_value(rawtx->coin,0,0,swap->persistent_pubkey,argjson,0)) != 0 ) |
|||
{ |
|||
char str[65]; printf("basilisk_numconfirms required.%d %s %s valstr.(%s)\n",rawtx->I.numconfirms,rawtx->name,bits256_str(str,rawtx->I.actualtxid),valstr); |
|||
//basilisk_numconfirms required.0 alicespend 29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85 valstr.({"result":"success","numconfirms":0,"address":"1JGvZ67oTdM7kCya4J8kj1uErbSRAoq3wH","satoshis":"1413818","value":0.01413818,"height":462440,"txid":"29a2a6b4a61b1da82096d533c71b6762d61a82ca771a633269d97c0ccb94fe85","vout":0,"coin":"BTC"})
|
|||
|
|||
if ( (valuearray= cJSON_Parse(valstr)) != 0 ) |
|||
{ |
|||
if ( valstr[0] == '[' && is_cJSON_Array(valuearray) != 0 ) |
|||
{ |
|||
n = cJSON_GetArraySize(valuearray); |
|||
for (i=0; i<n; i++) |
|||
{ |
|||
printf("i.%d of n.%d\n",i,n); |
|||
if ( (retval= basilisk_confirmsobj(jitem(valuearray,i))) >= 0 ) |
|||
break; |
|||
} |
|||
} else retval = basilisk_confirmsobj(valuearray); |
|||
free_json(valuearray); |
|||
} else printf("parse error\n"); |
|||
free(valstr); |
|||
} |
|||
free_json(argjson); |
|||
printf("numconfirms.%d returned\n",retval); |
|||
return(retval);*/ |
|||
} |
@ -0,0 +1,186 @@ |
|||
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2017 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_secp.c
|
|||
// marketmaker
|
|||
//
|
|||
|
|||
|
|||
#include <ctype.h> |
|||
#include <string.h> |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include "../../includes/curve25519.h" |
|||
#include "../secp256k1/include/secp256k1.h" |
|||
#include "../secp256k1/include/secp256k1_ecdh.h" |
|||
#include "../secp256k1/include/secp256k1_schnorr.h" |
|||
#include "../secp256k1/include/secp256k1_rangeproof.h" |
|||
#include "../secp256k1/include/secp256k1_recovery.h" |
|||
|
|||
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; |
|||
|
|||
#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) |
|||
|
|||
#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 ) |
|||
#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx); |
|||
|
|||
void *bitcoin_ctx() |
|||
{ |
|||
void *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); |
|||
secp256k1_pedersen_context_initialize(ctx); |
|||
secp256k1_rangeproof_context_initialize(ctx); |
|||
return(ctx); |
|||
} |
|||
|
|||
bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey) |
|||
{ |
|||
size_t plen; bits256 pubkey; secp256k1_pubkey secppub; |
|||
memset(pubkey.bytes,0,sizeof(pubkey)); |
|||
SECP_ENSURE_CTX |
|||
{ |
|||
if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) |
|||
{ |
|||
//printf("bitcoin_sign illegal privkey\n");
|
|||
return(pubkey); |
|||
} |
|||
if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) != 0 ) |
|||
{ |
|||
plen = 33; |
|||
secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED); |
|||
if ( plen == 33 ) |
|||
memcpy(pubkey.bytes,data+1,sizeof(pubkey)); |
|||
} |
|||
ENDSECP_ENSURE_CTX |
|||
} |
|||
return(pubkey); |
|||
} |
|||
|
|||
bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even) |
|||
{ |
|||
bits256 pub256; uint8_t pubkey[33]; int32_t i; |
|||
for (i=0; i<100; i++) |
|||
{ |
|||
*privkeyp = rand256(0); |
|||
pub256 = bitcoin_pubkey33(ctx,pubkey,*privkeyp); |
|||
if ( pubkey[0] == odd_even+2 ) |
|||
return(pub256); |
|||
} |
|||
printf("bitcoin_pub256 couldnt generate pubkey.%d\n",odd_even+2); |
|||
memset(pub256.bytes,0,sizeof(pub256)); |
|||
return(pub256); |
|||
} |
|||
|
|||
int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag) |
|||
{ |
|||
int32_t fCompressed = 1; |
|||
secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; |
|||
seed = rand256(0); |
|||
extra_entropy = rand256(0); |
|||
SECP_ENSURE_CTX |
|||
{ |
|||
if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) |
|||
{ |
|||
//printf("bitcoin_sign illegal privkey\n");
|
|||
return(-1); |
|||
} |
|||
if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 ) |
|||
{ |
|||
if ( recoverflag != 0 ) |
|||
{ |
|||
if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 ) |
|||
{ |
|||
recid = -1; |
|||
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG); |
|||
if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) != 0 ) |
|||
{ |
|||
if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) != 0 ) |
|||
{ |
|||
if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 ) |
|||
{ |
|||
sig[0] = 27 + recid + (fCompressed != 0 ? 4 : 0); |
|||
retval = 64 + 1; |
|||
//size_t i,plen = 33; uint8_t pubkey[33];
|
|||
//secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&CHECKPUB,SECP256K1_EC_COMPRESSED);
|
|||
//for (i=0; i<33; i++)
|
|||
// printf("%02x",pubkey[i]);
|
|||
//printf(" bitcoin_sign's pubkey\n");
|
|||
|
|||
} //else printf("secpub mismatch\n");
|
|||
} else printf("pubkey create error\n"); |
|||
} //else printf("recover error\n");
|
|||
} else printf("secp256k1_ecdsa_sign_recoverable error\n"); |
|||
} |
|||
else |
|||
{ |
|||
if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 ) |
|||
{ |
|||
if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 ) |
|||
retval = (int32_t)siglen; |
|||
} |
|||
} |
|||
} |
|||
ENDSECP_ENSURE_CTX |
|||
} |
|||
return(retval); |
|||
} |
|||
|
|||
int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig,bits256 messagehash2,uint8_t *pubkey,size_t plen) |
|||
{ |
|||
int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; |
|||
pubkey[0] = 0; |
|||
SECP_ENSURE_CTX |
|||
{ |
|||
if ( plen == 0 ) |
|||
{ |
|||
plen = (sig[0] <= 31) ? 65 : 33; |
|||
sig++; |
|||
} |
|||
secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig,0); |
|||
secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG); |
|||
if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) != 0 ) |
|||
{ |
|||
plen = 33; |
|||
memset(pubkey,0,33); |
|||
secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED);//plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED);
|
|||
if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) != 0 ) |
|||
{ |
|||
retval = 0; |
|||
/*if ( pubkey[0] == 4 ) // experimentally looks like 04 is set
|
|||
pubkey[0] = 2; |
|||
else if ( pubkey[0] != 2 ) |
|||
pubkey[0] = 3;*/ |
|||
} else printf("secp256k1_ecdsa_verify error\n"); |
|||
} else printf("secp256k1_ecdsa_recover error\n"); |
|||
ENDSECP_ENSURE_CTX |
|||
} |
|||
return(retval); |
|||
} |
|||
|
|||
int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen) |
|||
{ |
|||
int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; |
|||
SECP_ENSURE_CTX |
|||
{ |
|||
if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 ) |
|||
{ |
|||
secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen); |
|||
if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) != 0 ) |
|||
retval = 0; |
|||
} |
|||
ENDSECP_ENSURE_CTX |
|||
} |
|||
return(retval); |
|||
} |
@ -0,0 +1,558 @@ |
|||
|
|||
/******************************************************************************
|
|||
* Copyright © 2014-2017 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_statemachine.c
|
|||
// marketmaker
|
|||
//
|
|||
|
|||
int32_t basilisk_process_swapverify(void *ptr,int32_t (*internal_func)(void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration) |
|||
{ |
|||
struct basilisk_swap *swap = ptr; |
|||
if ( internal_func != 0 ) |
|||
return((*internal_func)(swap,data,datalen)); |
|||
else return(0); |
|||
} |
|||
|
|||
|
|||
|
|||
int32_t basilisk_priviextract(struct iguana_info *coin,char *name,bits256 *destp,uint8_t secret160[20],bits256 srctxid,int32_t srcvout) |
|||
{ |
|||
/*bits256 txid; char str[65]; int32_t i,vini,scriptlen; uint8_t rmd160[20],scriptsig[IGUANA_MAXSCRIPTSIZE];
|
|||
memset(privkey.bytes,0,sizeof(privkey)); |
|||
// use dex_listtransactions!
|
|||
if ( (vini= iguana_vinifind(coin,&txid,srctxid,srcvout)) >= 0 ) |
|||
{ |
|||
if ( (scriptlen= iguana_scriptsigextract(coin,scriptsig,sizeof(scriptsig),txid,vini)) > 32 ) |
|||
{ |
|||
for (i=0; i<32; i++) |
|||
privkey.bytes[i] = scriptsig[scriptlen - 33 + i]; |
|||
revcalc_rmd160_sha256(rmd160,privkey);//.bytes,sizeof(privkey));
|
|||
if ( memcmp(secret160,rmd160,sizeof(rmd160)) == sizeof(rmd160) ) |
|||
{ |
|||
*destp = privkey; |
|||
printf("basilisk_priviextract found privi %s (%s)\n",name,bits256_str(str,privkey)); |
|||
return(0); |
|||
} |
|||
} |
|||
}*/ |
|||
return(-1); |
|||
} |
|||
int32_t basilisk_verify_privi(void *ptr,uint8_t *data,int32_t datalen); |
|||
|
|||
int32_t basilisk_privBn_extract(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) |
|||
{ |
|||
if ( basilisk_priviextract(&swap->bobcoin,"privBn",&swap->I.privBn,swap->I.secretBn,swap->bobrefund.I.actualtxid,0) == 0 ) |
|||
{ |
|||
printf("extracted privBn from blockchain\n"); |
|||
} |
|||
else if ( basilisk_swapget(swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) |
|||
{ |
|||
} |
|||
if ( bits256_nonz(swap->I.privBn) != 0 && swap->alicereclaim.I.datalen == 0 ) |
|||
{ |
|||
char str[65]; printf("got privBn.%s\n",bits256_str(str,swap->I.privBn)); |
|||
return(basilisk_alicepayment_spend(swap,&swap->alicereclaim)); |
|||
} |
|||
return(-1); |
|||
} |
|||
|
|||
int32_t basilisk_privAm_extract(struct basilisk_swap *swap) |
|||
{ |
|||
if ( basilisk_priviextract(&swap->bobcoin,"privAm",&swap->I.privAm,swap->I.secretAm,swap->bobpayment.I.actualtxid,0) == 0 ) |
|||
{ |
|||
printf("extracted privAm from blockchain\n"); |
|||
} |
|||
if ( bits256_nonz(swap->I.privAm) != 0 && swap->bobspend.I.datalen == 0 ) |
|||
{ |
|||
char str[65]; printf("got privAm.%s\n",bits256_str(str,swap->I.privAm)); |
|||
return(basilisk_alicepayment_spend(swap,&swap->bobspend)); |
|||
} |
|||
return(-1); |
|||
} |
|||
|
|||
int32_t basilisk_verify_otherstatebits(void *ptr,uint8_t *data,int32_t datalen) |
|||
{ |
|||
int32_t retval; struct basilisk_swap *swap = ptr; |
|||
if ( datalen == sizeof(swap->I.otherstatebits) ) |
|||
{ |
|||
retval = iguana_rwnum(0,data,sizeof(swap->I.otherstatebits),&swap->I.otherstatebits); |
|||
return(retval); |
|||
} else return(-1); |
|||
} |
|||
|
|||
int32_t basilisk_verify_statebits(void *ptr,uint8_t *data,int32_t datalen) |
|||
{ |
|||
int32_t retval = -1; uint32_t statebits; struct basilisk_swap *swap = ptr; |
|||
if ( datalen == sizeof(swap->I.statebits) ) |
|||
{ |
|||
retval = iguana_rwnum(0,data,sizeof(swap->I.statebits),&statebits); |
|||
if ( statebits != swap->I.statebits ) |
|||
{ |
|||
printf("statebits.%x != %x\n",statebits,swap->I.statebits); |
|||
return(-1); |
|||
} |
|||
} |
|||
return(retval); |
|||
} |
|||
|
|||
void basilisk_sendstate(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) |
|||
{ |
|||
int32_t datalen=0; |
|||
datalen = iguana_rwnum(1,data,sizeof(swap->I.statebits),&swap->I.statebits); |
|||
LP_swapsend(swap,0x80000000,data,datalen,0,0); |
|||
} |
|||
|
|||
int32_t basilisk_swapiteration(struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) |
|||
{ |
|||
int32_t j,datalen,retval = 0; uint32_t savestatebits=0,saveotherbits=0; |
|||
if ( swap->I.iambob != 0 ) |
|||
swap->I.statebits |= 0x80; |
|||
while ( swap->aborted == 0 && ((swap->I.otherstatebits & 0x80) == 0 || (swap->I.statebits & 0x80) == 0) && retval == 0 && time(NULL) < swap->I.expiration ) |
|||
{ |
|||
if ( swap->connected == 0 ) |
|||
basilisk_psockinit(swap,swap->I.iambob != 0); |
|||
printf("D r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); |
|||
if ( swap->I.iambob != 0 && (swap->I.statebits & 0x80) == 0 ) // wait for fee
|
|||
{ |
|||
if ( basilisk_swapget(swap,0x80,data,maxlen,basilisk_verify_otherfee) == 0 ) |
|||
{ |
|||
// verify and submit otherfee
|
|||
swap->I.statebits |= 0x80; |
|||
basilisk_sendstate(swap,data,maxlen); |
|||
} |
|||
} |
|||
else if ( swap->I.iambob == 0 ) |
|||
swap->I.statebits |= 0x80; |
|||
basilisk_sendstate(swap,data,maxlen); |
|||
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); |
|||
if ( (swap->I.otherstatebits & 0x80) != 0 && (swap->I.statebits & 0x80) != 0 ) |
|||
break; |
|||
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) |
|||
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); |
|||
savestatebits = swap->I.statebits; |
|||
saveotherbits = swap->I.otherstatebits; |
|||
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); |
|||
basilisk_sendstate(swap,data,maxlen); |
|||
if ( (swap->I.otherstatebits & 0x80) == 0 ) |
|||
LP_swapdata_rawtxsend(swap,0x80,data,maxlen,&swap->myfee,0x40,0); |
|||
} |
|||
basilisk_swap_saveupdate(swap); |
|||
while ( swap->aborted == 0 && retval == 0 && time(NULL) < swap->I.expiration ) // both sides have setup required data and paid txfee
|
|||
{ |
|||
basilisk_swap_saveupdate(swap); |
|||
if ( swap->connected == 0 ) |
|||
basilisk_psockinit(swap,swap->I.iambob != 0); |
|||
//if ( (rand() % 30) == 0 )
|
|||
printf("E r%u/q%u swapstate.%x otherstate.%x remaining %d\n",swap->I.req.requestid,swap->I.req.quoteid,swap->I.statebits,swap->I.otherstatebits,(int32_t)(swap->I.expiration-time(NULL))); |
|||
if ( swap->I.iambob != 0 ) |
|||
{ |
|||
//printf("BOB\n");
|
|||
if ( (swap->I.statebits & 0x100) == 0 ) |
|||
{ |
|||
printf("send bobdeposit\n"); |
|||
swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x200,data,maxlen,&swap->bobdeposit,0x100,0); |
|||
} |
|||
// [BLOCKING: altfound] make sure altpayment is confirmed and send payment
|
|||
else if ( (swap->I.statebits & 0x1000) == 0 ) |
|||
{ |
|||
printf("check alicepayment\n"); |
|||
if ( basilisk_swapget(swap,0x1000,data,maxlen,basilisk_verify_alicepaid) == 0 ) |
|||
{ |
|||
swap->I.statebits |= 0x1000; |
|||
printf("got alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); |
|||
} |
|||
} |
|||
else if ( (swap->I.statebits & 0x2000) == 0 ) |
|||
{ |
|||
if ( (swap->I.aliceconfirms == 0 && swap->aliceunconf != 0) || LP_numconfirms(swap,&swap->alicepayment) >= swap->I.aliceconfirms ) |
|||
{ |
|||
swap->I.statebits |= 0x2000; |
|||
printf("alicepayment confirmed\n"); |
|||
} |
|||
} |
|||
else if ( (swap->I.statebits & 0x4000) == 0 ) |
|||
{ |
|||
basilisk_bobscripts_set(swap,0,1); |
|||
printf("send bobpayment\n"); |
|||
swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x8000,data,maxlen,&swap->bobpayment,0x4000,0); |
|||
} |
|||
// [BLOCKING: privM] Bob waits for privAm either from Alice or alice blockchain
|
|||
else if ( (swap->I.statebits & 0xc0000) != 0xc0000 ) |
|||
{ |
|||
if ( basilisk_swapget(swap,0x40000,data,maxlen,basilisk_verify_privi) == 0 || basilisk_privAm_extract(swap) == 0 ) // divulges privAm
|
|||
{ |
|||
//printf("got privi spend alicepayment, dont divulge privBn until bobspend propagated\n");
|
|||
basilisk_alicepayment_spend(swap,&swap->bobspend); |
|||
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobspend,0x40000,1) == 0 ) |
|||
printf("Bob error spending alice payment\n"); |
|||
else |
|||
{ |
|||
tradebot_swap_balancingtrade(swap,1); |
|||
printf("Bob spends alicepayment aliceconfirms.%d\n",swap->I.aliceconfirms); |
|||
swap->I.statebits |= 0x40000; |
|||
if ( LP_numconfirms(swap,&swap->bobspend) >= swap->I.aliceconfirms ) |
|||
{ |
|||
printf("bobspend confirmed\n"); |
|||
swap->I.statebits |= 0x80000; |
|||
printf("Bob confirming spend of Alice's payment\n"); |
|||
sleep(DEX_SLEEP); |
|||
} |
|||
retval = 1; |
|||
} |
|||
} |
|||
} |
|||
if ( swap->bobpayment.I.locktime != 0 && time(NULL) > swap->bobpayment.I.locktime ) |
|||
{ |
|||
// submit reclaim of payment
|
|||
printf("bob reclaims bobpayment\n"); |
|||
swap->I.statebits |= (0x40000 | 0x80000); |
|||
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->bobreclaim,0,0) == 0 ) |
|||
printf("Bob error reclaiming own payment after alice timed out\n"); |
|||
else |
|||
{ |
|||
printf("Bob reclaimed own payment\n"); |
|||
while ( 0 && (swap->I.statebits & 0x100000) == 0 ) // why wait for own tx?
|
|||
{ |
|||
if ( LP_numconfirms(swap,&swap->bobreclaim) >= 1 ) |
|||
{ |
|||
printf("bobreclaim confirmed\n"); |
|||
swap->I.statebits |= 0x100000; |
|||
printf("Bob confirms reclain of payment\n"); |
|||
break; |
|||
} |
|||
} |
|||
retval = 1; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
//printf("ALICE\n");
|
|||
// [BLOCKING: depfound] Alice waits for deposit to confirm and sends altpayment
|
|||
if ( (swap->I.statebits & 0x200) == 0 ) |
|||
{ |
|||
printf("checkfor deposit\n"); |
|||
if ( basilisk_swapget(swap,0x200,data,maxlen,basilisk_verify_bobdeposit) == 0 ) |
|||
{ |
|||
// verify deposit and submit, set confirmed height
|
|||
printf("got bobdeposit\n"); |
|||
swap->I.statebits |= 0x200; |
|||
} else printf("no valid deposit\n"); |
|||
} |
|||
else if ( (swap->I.statebits & 0x400) == 0 ) |
|||
{ |
|||
if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->depositunconf != 0) || LP_numconfirms(swap,&swap->bobdeposit) >= swap->I.bobconfirms ) |
|||
{ |
|||
printf("bobdeposit confirmed\n"); |
|||
swap->I.statebits |= 0x400; |
|||
} |
|||
} |
|||
else if ( (swap->I.statebits & 0x800) == 0 ) |
|||
{ |
|||
printf("send alicepayment\n"); |
|||
swap->I.statebits |= LP_swapdata_rawtxsend(swap,0x1000,data,maxlen,&swap->alicepayment,0x800,0); |
|||
} |
|||
// [BLOCKING: payfound] make sure payment is confrmed and send in spend or see bob's reclaim and claim
|
|||
else if ( (swap->I.statebits & 0x8000) == 0 ) |
|||
{ |
|||
if ( basilisk_swapget(swap,0x8000,data,maxlen,basilisk_verify_bobpaid) == 0 ) |
|||
{ |
|||
printf("got bobpayment\n"); |
|||
tradebot_swap_balancingtrade(swap,0); |
|||
// verify payment and submit, set confirmed height
|
|||
swap->I.statebits |= 0x8000; |
|||
} |
|||
} |
|||
else if ( (swap->I.statebits & 0x10000) == 0 ) |
|||
{ |
|||
if ( basilisk_istrustedbob(swap) != 0 || (swap->I.bobconfirms == 0 && swap->paymentunconf != 0) || LP_numconfirms(swap,&swap->bobpayment) >= swap->I.bobconfirms ) |
|||
{ |
|||
printf("bobpayment confirmed\n"); |
|||
swap->I.statebits |= 0x10000; |
|||
} |
|||
} |
|||
else if ( (swap->I.statebits & 0x20000) == 0 ) |
|||
{ |
|||
printf("alicespend bobpayment\n"); |
|||
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->alicespend,0x20000,0) != 0 )//&& (swap->aliceunconf != 0 || basilisk_numconfirms(swap,&swap->alicespend) > 0) )
|
|||
{ |
|||
swap->I.statebits |= 0x20000; |
|||
} |
|||
} |
|||
else if ( (swap->I.statebits & 0x40000) == 0 ) |
|||
{ |
|||
int32_t numconfs; |
|||
if ( (numconfs= LP_numconfirms(swap,&swap->alicespend)) >= swap->I.bobconfirms ) |
|||
{ |
|||
for (j=datalen=0; j<32; j++) |
|||
data[datalen++] = swap->I.privAm.bytes[j]; |
|||
printf("send privAm %x\n",swap->I.statebits); |
|||
swap->I.statebits |= LP_swapsend(swap,0x40000,data,datalen,0x20000,swap->I.crcs_mypriv); |
|||
printf("Alice confirms spend of Bob's payment\n"); |
|||
retval = 1; |
|||
} else printf("alicespend numconfs.%d < %d\n",numconfs,swap->I.bobconfirms); |
|||
} |
|||
if ( swap->bobdeposit.I.locktime != 0 && time(NULL) > swap->bobdeposit.I.locktime ) |
|||
{ |
|||
printf("Alice claims deposit\n"); |
|||
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->aliceclaim,0,0) == 0 ) |
|||
printf("Alice couldnt claim deposit\n"); |
|||
else |
|||
{ |
|||
printf("Alice claimed deposit\n"); |
|||
retval = 1; |
|||
} |
|||
} |
|||
else if ( swap->aborted != 0 || basilisk_privBn_extract(swap,data,maxlen) == 0 ) |
|||
{ |
|||
printf("Alice reclaims her payment\n"); |
|||
swap->I.statebits |= 0x40000000; |
|||
if ( LP_swapdata_rawtxsend(swap,0,data,maxlen,&swap->alicereclaim,0x40000000,0) == 0 ) |
|||
printf("Alice error sending alicereclaim\n"); |
|||
else |
|||
{ |
|||
printf("Alice reclaimed her payment\n"); |
|||
retval = 1; |
|||
} |
|||
} |
|||
} |
|||
if ( (rand() % 30) == 0 ) |
|||
printf("finished swapstate.%x other.%x\n",swap->I.statebits,swap->I.otherstatebits); |
|||
if ( swap->I.statebits == savestatebits && swap->I.otherstatebits == saveotherbits ) |
|||
sleep(DEX_SLEEP + (swap->I.iambob == 0)*1); |
|||
savestatebits = swap->I.statebits; |
|||
saveotherbits = swap->I.otherstatebits; |
|||
basilisk_sendstate(swap,data,maxlen); |
|||
basilisk_swapget(swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); |
|||
} |
|||
return(retval); |
|||
} |
|||
|
|||
int32_t swapcompleted(struct basilisk_swap *swap) |
|||
{ |
|||
if ( swap->I.iambob != 0 ) |
|||
return(swap->I.bobspent); |
|||
else return(swap->I.alicespent); |
|||
} |
|||
|
|||
cJSON *swapjson(struct basilisk_swap *swap) |
|||
{ |
|||
cJSON *retjson = cJSON_CreateObject(); |
|||
return(retjson); |
|||
} |
|||
|
|||
int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp) |
|||
{ |
|||
int32_t len = 0; |
|||
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->requestid),&rp->requestid); |
|||
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->timestamp),&rp->timestamp); // must be 2nd
|
|||
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quoteid),&rp->quoteid); |
|||
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quotetime),&rp->quotetime); |
|||
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->optionhours),&rp->optionhours); |
|||
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->srcamount),&rp->srcamount); |
|||
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->unused),&rp->unused); |
|||
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->srchash),rp->srchash.bytes); |
|||
len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->desthash),rp->desthash.bytes); |
|||
len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->destamount),&rp->destamount); |
|||
if ( rwflag != 0 ) |
|||
{ |
|||
memcpy(&serialized[len],rp->src,sizeof(rp->src)), len += sizeof(rp->src); |
|||
memcpy(&serialized[len],rp->dest,sizeof(rp->dest)), len += sizeof(rp->dest); |
|||
} |
|||
else |
|||
{ |
|||
memcpy(rp->src,&serialized[len],sizeof(rp->src)), len += sizeof(rp->src); |
|||
memcpy(rp->dest,&serialized[len],sizeof(rp->dest)), len += sizeof(rp->dest); |
|||
} |
|||
//len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->DEXselector),&rp->DEXselector);
|
|||
//len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->extraspace),&rp->extraspace);
|
|||
if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) |
|||
printf(" basilisk_rwDEXquote.%d: quoteid.%u mismatch calc %u rp.%p\n",rwflag,rp->quoteid,basilisk_quoteid(rp),rp); |
|||
if ( basilisk_requestid(rp) != rp->requestid ) |
|||
printf(" basilisk_rwDEXquote.%d: requestid.%u mismatch calc %u rp.%p\n",rwflag,rp->requestid,basilisk_requestid(rp),rp); |
|||
return(len); |
|||
} |
|||
|
|||
struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson) |
|||
{ |
|||
uint32_t requestid,quoteid; |
|||
memset(rp,0,sizeof(*rp)); |
|||
rp->srchash = jbits256(reqjson,"srchash"); |
|||
rp->desthash = jbits256(reqjson,"desthash"); |
|||
rp->srcamount = j64bits(reqjson,"srcamount"); |
|||
//rp->minamount = j64bits(reqjson,"minamount");
|
|||
//rp->destamount = j64bits(reqjson,"destamount");
|
|||
rp->destamount = j64bits(reqjson,"destsatoshis"); |
|||
//printf("parse DESTSATOSHIS.%llu (%s)\n",(long long)rp->destamount,jprint(reqjson,0));
|
|||
requestid = juint(reqjson,"requestid"); |
|||
quoteid = juint(reqjson,"quoteid"); |
|||
//if ( jstr(reqjson,"relay") != 0 )
|
|||
// rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay"));
|
|||
rp->timestamp = juint(reqjson,"timestamp"); |
|||
rp->quotetime = juint(reqjson,"quotetime"); |
|||
safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src)); |
|||
safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest)); |
|||
if ( quoteid != 0 ) |
|||
{ |
|||
rp->quoteid = basilisk_quoteid(rp); |
|||
if ( quoteid != rp->quoteid ) |
|||
printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid); |
|||
} |
|||
rp->requestid = basilisk_requestid(rp); |
|||
if ( requestid != rp->requestid ) |
|||
{ |
|||
int32_t i; for (i=0; i<sizeof(*rp); i++) |
|||
printf("%02x",((uint8_t *)rp)[i]); |
|||
printf(" basilisk_parsejson.(%s) requestid.%u != %u error\n",jprint(reqjson,0),requestid,rp->requestid); |
|||
} |
|||
return(rp); |
|||
} |
|||
|
|||
cJSON *basilisk_requestjson(struct basilisk_request *rp) |
|||
{ |
|||
cJSON *item = cJSON_CreateObject(); |
|||
/*if ( rp->relaybits != 0 )
|
|||
{ |
|||
expand_ipbits(ipaddr,rp->relaybits); |
|||
jaddstr(item,"relay",ipaddr); |
|||
}*/ |
|||
jaddbits256(item,"srchash",rp->srchash); |
|||
if ( bits256_nonz(rp->desthash) != 0 ) |
|||
jaddbits256(item,"desthash",rp->desthash); |
|||
jaddstr(item,"src",rp->src); |
|||
if ( rp->srcamount != 0 ) |
|||
jadd64bits(item,"srcamount",rp->srcamount); |
|||
//if ( rp->minamount != 0 )
|
|||
// jadd64bits(item,"minamount",rp->minamount);
|
|||
jaddstr(item,"dest",rp->dest); |
|||
if ( rp->destamount != 0 ) |
|||
{ |
|||
//jadd64bits(item,"destamount",rp->destamount);
|
|||
jadd64bits(item,"destsatoshis",rp->destamount); |
|||
//printf("DESTSATOSHIS.%llu\n",(long long)rp->destamount);
|
|||
} |
|||
jaddnum(item,"quotetime",rp->quotetime); |
|||
jaddnum(item,"timestamp",rp->timestamp); |
|||
jaddnum(item,"requestid",rp->requestid); |
|||
jaddnum(item,"quoteid",rp->quoteid); |
|||
//jaddnum(item,"DEXselector",rp->DEXselector);
|
|||
jaddnum(item,"optionhours",rp->optionhours); |
|||
//jaddnum(item,"profit",(double)rp->profitmargin / 1000000.);
|
|||
if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) |
|||
printf("quoteid mismatch %u vs %u\n",basilisk_quoteid(rp),rp->quoteid); |
|||
if ( basilisk_requestid(rp) != rp->requestid ) |
|||
printf("requestid mismatch %u vs calc %u\n",rp->requestid,basilisk_requestid(rp)); |
|||
{ |
|||
int32_t i; struct basilisk_request R; |
|||
if ( basilisk_parsejson(&R,item) != 0 ) |
|||
{ |
|||
if ( memcmp(&R,rp,sizeof(*rp)-sizeof(uint32_t)) != 0 ) |
|||
{ |
|||
for (i=0; i<sizeof(*rp); i++) |
|||
printf("%02x",((uint8_t *)rp)[i]); |
|||
printf(" <- rp.%p\n",rp); |
|||
for (i=0; i<sizeof(R); i++) |
|||
printf("%02x",((uint8_t *)&R)[i]); |
|||
printf(" <- R mismatch\n"); |
|||
for (i=0; i<sizeof(R); i++) |
|||
if ( ((uint8_t *)rp)[i] != ((uint8_t *)&R)[i] ) |
|||
printf("(%02x %02x).%d ",((uint8_t *)rp)[i],((uint8_t *)&R)[i],i); |
|||
printf("mismatches\n"); |
|||
} //else printf("matched JSON conv %u %u\n",basilisk_requestid(&R),basilisk_requestid(rp));
|
|||
} |
|||
} |
|||
return(item); |
|||
} |
|||
|
|||
cJSON *basilisk_swapjson(struct basilisk_swap *swap) |
|||
{ |
|||
cJSON *item = cJSON_CreateObject(); |
|||
jaddnum(item,"requestid",swap->I.req.requestid); |
|||
jaddnum(item,"quoteid",swap->I.req.quoteid); |
|||
jaddnum(item,"state",swap->I.statebits); |
|||
jaddnum(item,"otherstate",swap->I.otherstatebits); |
|||
jadd(item,"request",basilisk_requestjson(&swap->I.req)); |
|||
return(item); |
|||
} |
|||
|
|||
#ifdef later |
|||
|
|||
cJSON *basilisk_privkeyarray(struct iguana_info *coin,cJSON *vins) |
|||
{ |
|||
cJSON *privkeyarray,*item,*sobj; struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],account[128],wifstr[64],str[65],typestr[64],*hexstr; uint8_t script[1024]; int32_t i,n,len,vout; bits256 txid,privkey; double bidasks[2]; |
|||
privkeyarray = cJSON_CreateArray(); |
|||
//printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr);
|
|||
if ( (n= cJSON_GetArraySize(vins)) > 0 ) |
|||
{ |
|||
for (i=0; i<n; i++) |
|||
{ |
|||
item = jitem(vins,i); |
|||
txid = jbits256(item,"txid"); |
|||
vout = jint(item,"vout"); |
|||
if ( bits256_nonz(txid) != 0 && vout >= 0 ) |
|||
{ |
|||
iguana_txidcategory(coin,account,coinaddr,txid,vout); |
|||
if ( coinaddr[0] == 0 && (sobj= jobj(item,"scriptPubKey")) != 0 && (hexstr= jstr(sobj,"hex")) != 0 && is_hexstr(hexstr,0) > 0 ) |
|||
{ |
|||
len = (int32_t)strlen(hexstr) >> 1; |
|||
if ( len < (sizeof(script) << 1) ) |
|||
{ |
|||
decode_hex(script,len,hexstr); |
|||
if ( len == 25 && script[0] == 0x76 && script[1] == 0xa9 && script[2] == 0x14 ) |
|||
bitcoin_address(coinaddr,coin->chain->pubtype,script+3,20); |
|||
} |
|||
} |
|||
if ( coinaddr[0] != 0 ) |
|||
{ |
|||
if ( (waddr= iguana_waddresssearch(&wacct,coinaddr)) != 0 ) |
|||
{ |
|||
bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype); |
|||
jaddistr(privkeyarray,waddr->wifstr); |
|||
} |
|||
else if ( smartaddress(typestr,bidasks,&privkey,coin->symbol,coinaddr) >= 0 ) |
|||
{ |
|||
bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); |
|||
jaddistr(privkeyarray,wifstr); |
|||
} |
|||
else printf("cant find (%s) in wallet\n",coinaddr); |
|||
} else printf("cant coinaddr from (%s).v%d\n",bits256_str(str,txid),vout); |
|||
} else printf("invalid txid/vout %d of %d\n",i,n); |
|||
} |
|||
} |
|||
return(privkeyarray); |
|||
} |
|||
|
|||
|
|||
#endif |
|||
|
|||
|
|||
/*void basilisk_swap_purge(struct basilisk_swap *swap)
|
|||
{ |
|||
int32_t i,n; |
|||
// while still in orderbook, wait
|
|||
//return;
|
|||
portable_mutex_lock(&myinfo->DEX_swapmutex); |
|||
n = myinfo->numswaps; |
|||
for (i=0; i<n; i++) |
|||
if ( myinfo->swaps[i] == swap ) |
|||
{ |
|||
myinfo->swaps[i] = myinfo->swaps[--myinfo->numswaps]; |
|||
myinfo->swaps[myinfo->numswaps] = 0; |
|||
basilisk_swap_finished(swap); |
|||
break; |
|||
} |
|||
portable_mutex_unlock(&myinfo->DEX_swapmutex); |
|||
}*/ |
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -1 +1,2 @@ |
|||
gcc -o marketmaker -I../crypto777 exchanges/mm.c ../crypto777/cJSON.c ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm |
|||
cd secp256k1; ./m_unix; cd .. |
|||
gcc -o marketmaker -I../crypto777 exchanges/mm.c mini-gmp.c secp256k1.o ../agents/libcrypto777.a -lnanomsg -lcurl -lpthread -lm |
|||
|
Loading…
Reference in new issue