From f44cd67e8298122cf4dea84cff3685696553fb74 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 19 Sep 2018 21:04:47 -1100 Subject: [PATCH] Prices stub --- src/cc/CCPrices.h | 9 +- src/cc/CCassets.h | 2 +- src/cc/CCassetsCore.cpp | 48 ++++- src/cc/CCassetstx.cpp | 4 +- src/cc/CCinclude.h | 4 +- src/cc/CCtx.cpp | 5 +- src/cc/assets.cpp | 4 +- src/cc/gateways.cpp | 26 ++- src/cc/prices.cpp | 401 ++++++++++++++++++++++++--------------- src/komodo_utils.h | 5 + src/rpcserver.cpp | 9 +- src/rpcserver.h | 7 + src/wallet/rpcwallet.cpp | 208 ++++++++++++++++++-- 13 files changed, 536 insertions(+), 196 deletions(-) diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 8b09e9267..d35823838 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -22,6 +22,13 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx); // CCcustom -UniValue PricesInfo(); +UniValue PricesList(); +UniValue PricesInfo(uint256 fundingtxid); +UniValue PricesStatus(uint64_t txfee,uint256 fundingtxid,uint256 bettxid); +std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletxid,uint64_t margin,uint64_t mode,uint256 longtoken,uint256 shorttoken,int32_t maxleverage,int64_t funding,std::vector pubkeys); +std::string PricesAddFunding(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,int64_t amount); +std::string PricesBet(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,int64_t amount,int32_t leverage); +std::string PricesFinish(uint64_t txfee,uint256 bettoken,uint256 fundingtxid,uint256 bettxid); + #endif diff --git a/src/cc/CCassets.h b/src/cc/CCassets.h index 9a0f2a0ea..afb3579cf 100644 --- a/src/cc/CCassets.h +++ b/src/cc/CCassets.h @@ -33,7 +33,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx CScript EncodeAssetCreateOpRet(uint8_t funcid,std::vector origpubkey,std::string name,std::string description); CScript EncodeAssetOpRet(uint8_t funcid,uint256 assetid,uint256 assetid2,int64_t price,std::vector origpubkey); bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector &origpubkey,std::string &name,std::string &description); -uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector &origpubkey); +uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector &origpubkey,uint256 &bettxid,int32_t &leverage); bool SetAssetOrigpubkey(std::vector &origpubkey,int64_t &price,const CTransaction &tx); int64_t IsAssetvout(int64_t &price,std::vector &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid); bool ValidateBidRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice); diff --git a/src/cc/CCassetsCore.cpp b/src/cc/CCassetsCore.cpp index 55a4ccdcb..cd2e267e1 100644 --- a/src/cc/CCassetsCore.cpp +++ b/src/cc/CCassetsCore.cpp @@ -274,7 +274,29 @@ bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector &or return(0); } -uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector &origpubkey) +CScript EncodeAssetOpRetExtra(uint8_t funcid,uint256 assetid,uint256 assetid2,uint256 bettxid,int32_t leverage) +{ + CScript opret; uint8_t evalcode = EVAL_ASSETS; + assetid = revuint256(assetid); + assetid2 = revuint256(assetid2); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << assetid << assetid2 << bettxid << leverage); + return(opret); +} + +uint8_t DecodeAssetOpRetExtra(CScript scriptPubKey,uint256 &assetid,uint256 &assetid2,uint256 &bettxid,int32_t leverage) +{ + std::vector vopret; uint8_t funcid=0,e,f; + GetOpReturnData(scriptPubKey, vopret); + if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> assetid2; ss >> bettxid; ss >> leverage) != 0 ) + { + assetid = revuint256(assetid); + assetid2 = revuint256(assetid2); + return(funcid); + } + return(0); +} + +uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector &origpubkey,uint256 &bettxid,int32_t &leverage) { std::vector vopret; uint8_t funcid=0,*script,e,f; GetOpReturnData(scriptPubKey, vopret); @@ -297,6 +319,14 @@ uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &a return(funcid); } break; + case 'T': + if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> assetid2; ss >> bettxid; ss >> leverage) != 0 ) + { + assetid = revuint256(assetid); + assetid2 = revuint256(assetid2); + return(funcid); + } + break; case 's': case 'b': case 'S': case 'B': if ( E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> assetid; ss >> price; ss >> origpubkey) != 0 ) { @@ -325,17 +355,17 @@ uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &a bool SetAssetOrigpubkey(std::vector &origpubkey,int64_t &price,const CTransaction &tx) { - uint256 assetid,assetid2; - if ( tx.vout.size() > 0 && DecodeAssetOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,assetid,assetid2,price,origpubkey) != 0 ) + uint256 assetid,assetid2,bettxid; int32_t leverage; + if ( tx.vout.size() > 0 && DecodeAssetOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,assetid,assetid2,price,origpubkey,bettxid,leverage) != 0 ) return(true); else return(false); } bool GetAssetorigaddrs(struct CCcontract_info *cp,char *CCaddr,char *destaddr,const CTransaction& tx) { - uint256 assetid,assetid2; int64_t price,nValue=0; int32_t n; uint8_t funcid; std::vector origpubkey; CScript script; + uint256 assetid,assetid2,bettxid; int32_t leverage; int64_t price,nValue=0; int32_t n; uint8_t funcid; std::vector origpubkey; CScript script; n = tx.vout.size(); - if ( n == 0 || (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 ) + if ( n == 0 || (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey,bettxid,leverage)) == 0 ) return(false); if ( GetCCaddress(cp,CCaddr,pubkey2pk(origpubkey)) != 0 && Getscriptaddress(destaddr,CScript() << origpubkey << OP_CHECKSIG) != 0 ) return(true); @@ -344,7 +374,7 @@ bool GetAssetorigaddrs(struct CCcontract_info *cp,char *CCaddr,char *destaddr,co int64_t IsAssetvout(int64_t &price,std::vector &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid) { - uint256 assetid,assetid2; int64_t nValue=0; int32_t n; uint8_t funcid; + uint256 assetid,assetid2,bettxid; int64_t nValue=0; int32_t n,leverage; uint8_t funcid; if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) // maybe check address too? { n = tx.vout.size(); @@ -352,7 +382,7 @@ int64_t IsAssetvout(int64_t &price,std::vector &origpubkey,const CTrans //fprintf(stderr,"CC vout v.%d of n.%d %.8f\n",v,n,(double)nValue/COIN); if ( v >= n-1 ) return(0); - if ( (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 ) + if ( (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey,bettxid,leverage)) == 0 ) { fprintf(stderr,"null decodeopret v.%d\n",v); return(0); @@ -414,7 +444,7 @@ int64_t AssetValidateCCvin(struct CCcontract_info *cp,Eval* eval,char *CCaddr,ch int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid) { - CTransaction vinTx; int64_t nValue; uint256 assetid,assetid2; uint8_t funcid; + CTransaction vinTx; int64_t nValue; int32_t leverage; uint256 assetid,assetid2,bettxid; uint8_t funcid; CCaddr[0] = origaddr[0] = 0; if ( (nValue= AssetValidateCCvin(cp,eval,CCaddr,origaddr,tx,1,vinTx)) == 0 ) return(0); @@ -423,7 +453,7 @@ int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmppr else { //fprintf(stderr,"have %.8f checking assetid origaddr.(%s)\n",(double)nValue/COIN,origaddr); - if ( vinTx.vout.size() > 0 && (funcid= DecodeAssetOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,assetid,assetid2,tmpprice,tmporigpubkey)) != 'b' && funcid != 'B' ) + if ( vinTx.vout.size() > 0 && (funcid= DecodeAssetOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,assetid,assetid2,tmpprice,tmporigpubkey,bettxid,leverage)) != 'b' && funcid != 'B' ) return eval->Invalid("invalid opreturn for buyvin"); else if ( refassetid != assetid ) return eval->Invalid("invalid assetid for buyvin"); diff --git a/src/cc/CCassetstx.cpp b/src/cc/CCassetstx.cpp index cbf40d603..63d1a1089 100644 --- a/src/cc/CCassetstx.cpp +++ b/src/cc/CCassetstx.cpp @@ -106,7 +106,7 @@ UniValue AssetList() UniValue AssetOrders(uint256 refassetid) { static uint256 zero; - int64_t price; uint256 txid,hashBlock,assetid,assetid2; std::vector origpubkey; CTransaction vintx; UniValue result(UniValue::VARR); std::vector > unspentOutputs; uint8_t funcid; char numstr[32],funcidstr[16],origaddr[64],assetidstr[65]; struct CCcontract_info *cp,C; + int64_t price; uint256 txid,hashBlock,assetid,assetid2,bettxid; std::vector origpubkey; CTransaction vintx; UniValue result(UniValue::VARR); std::vector > unspentOutputs; int32_t leverage; uint8_t funcid; char numstr[32],funcidstr[16],origaddr[64],assetidstr[65]; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_ASSETS); SetCCunspents(unspentOutputs,(char *)cp->unspendableCCaddr); for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) @@ -114,7 +114,7 @@ UniValue AssetOrders(uint256 refassetid) txid = it->first.txhash; if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { - if ( vintx.vout.size() > 0 && (funcid= DecodeAssetOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,assetid,assetid2,price,origpubkey)) != 0 ) + if ( vintx.vout.size() > 0 && (funcid= DecodeAssetOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,assetid,assetid2,price,origpubkey,bettxid,leverage)) != 0 ) { if ( refassetid != zero && assetid != refassetid ) { diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 4beb722a1..4059191a7 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -110,10 +110,12 @@ uint256 OraclesBatontxid(uint256 oracletxid,CPubKey pk); int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs); bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector &origpubkey,std::string &name,std::string &description); -uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector &origpubkey); +uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector &origpubkey,uint256 &bettxid,int32_t &leverage); uint8_t DecodeOraclesData(const CScript &scriptPubKey,uint256 &oracletxid,uint256 &batontxid,CPubKey &pk,std::vector &data); int32_t oracle_format(uint256 *hashp,int64_t *valp,char *str,uint8_t fmt,uint8_t *data,int32_t offset,int32_t datalen); CScript EncodeAssetOpRet(uint8_t funcid,uint256 assetid,uint256 assetid2,int64_t price,std::vector origpubkey); +CScript EncodeAssetOpRetExtra(uint8_t funcid,uint256 assetid,uint256 assetid2,uint256 bettxid,int32_t leverage); +uint8_t DecodeAssetOpRetExtra(CScript scriptPubKey,uint256 &assetid,uint256 &assetid2,uint256 &bettxid,int32_t leverage); // CCcustom CPubKey GetUnspendable(struct CCcontract_info *cp,uint8_t *unspendablepriv); diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index 50bb9616f..b26ca7cfd 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -250,14 +250,15 @@ int64_t CCfullsupply(uint256 tokenid) int64_t CCtoken_balance(char *coinaddr,uint256 tokenid) { - int64_t price,sum = 0; int32_t numvouts; CTransaction tx; uint256 assetid,assetid2,txid,hashBlock; std::vector origpubkey; std::vector > unspentOutputs; + int64_t price,sum = 0; int32_t numvouts; CTransaction tx; uint256 assetid,assetid2,txid,bettxid,hashBlock; std::vector origpubkey; int32_t leverage; + std::vector > unspentOutputs; SetCCunspents(unspentOutputs,coinaddr); for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { txid = it->first.txhash; if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 0 ) { - if ( DecodeAssetOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,assetid2,price,origpubkey) != 0 && assetid == tokenid ) + if ( DecodeAssetOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,assetid2,price,origpubkey,bettxid,leverage) != 0 && assetid == tokenid ) { sum += it->second.satoshis; } diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index e5a5af4e0..bf979a1e0 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -132,12 +132,12 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) { static uint256 zero; - CTxDestination address; CTransaction vinTx,createTx; uint256 hashBlock,assetid,assetid2; int32_t i,starti,numvins,numvouts,preventCCvins,preventCCvouts; int64_t remaining_price,nValue,assetoshis,outputs,inputs,tmpprice,totalunits,ignore; std::vector origpubkey,tmporigpubkey,ignorepubkey; uint8_t funcid; char destaddr[64],origaddr[64],CCaddr[64]; + CTxDestination address; CTransaction vinTx,createTx; uint256 bettxid,hashBlock,assetid,assetid2; int32_t i,starti,leverage,numvins,numvouts,preventCCvins,preventCCvouts; int64_t remaining_price,nValue,assetoshis,outputs,inputs,tmpprice,totalunits,ignore; std::vector origpubkey,tmporigpubkey,ignorepubkey; uint8_t funcid; char destaddr[64],origaddr[64],CCaddr[64]; numvins = tx.vin.size(); numvouts = tx.vout.size(); outputs = inputs = 0; preventCCvins = preventCCvouts = -1; - if ( (funcid= DecodeAssetOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,assetid2,remaining_price,origpubkey)) == 0 ) + if ( (funcid= DecodeAssetOpRet(tx.vout[numvouts-1].scriptPubKey,assetid,assetid2,remaining_price,origpubkey,bettxid,leverage)) == 0 ) return eval->Invalid("Invalid opreturn payload"); fprintf(stderr,"AssetValidate (%c)\n",funcid); if ( funcid != 'o' && funcid != 'x' && eval->GetTxUnconfirmed(assetid,createTx,hashBlock) == 0 ) diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index 23b600930..9146a864b 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -130,6 +130,11 @@ gatewayspending will display all pending withdraws and if it is done on one of the msigpubkeys, then it will queue it for processing ./c gatewayspending e6c99f79d4afb216aa8063658b4222edb773dd24bb0f8e91bd4ef341f3e47e5e KMD + + Implementation Issues: + When thinking about validation, it is clear that we cant use EVAL_ASSETS for the locked coins as there wont be any enforcement of the gateways locking. This means we need a way to transfer assets into gateways outputs and back. It seems a tokenconvert rpc will be needed and hopefully that will be enough to make it all work properly. + + */ @@ -433,19 +438,24 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t { CMutableTransaction mtx; CTransaction oracletx; uint8_t taddr,prefix,prefix2; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; struct CCcontract_info *cp,C; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply; char destaddr[64],coinaddr[64],str[65],*fstr; cp = CCinit(&C,EVAL_GATEWAYS); + if ( strcmp((char *)"KMD",coin.c_str()) == 0 ) + { + taddr = 0; + prefix = 60; + prefix2 = 85; + } + else + { + fprintf(stderr,"set taddr, prefix, prefix2 for %s\n",coin.c_str()); + taddr = 0; + prefix = 60; + prefix2 = 85; + } if ( N == 0 || N > 15 || M > N ) { fprintf(stderr,"illegal M.%d or N.%d\n",M,N); return(""); } - if ( strcmp((char *)"KMD",coin.c_str()) != 0 ) - { - fprintf(stderr,"only KMD supported for now\n"); - return(""); - } - taddr = 0; - prefix = 60; - prefix2 = 85; if ( pubkeys.size() != N ) { fprintf(stderr,"M.%d N.%d but pubkeys[%d]\n",M,N,(int32_t)pubkeys.size()); diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 1db14d1b9..49e87127a 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -28,7 +28,7 @@ Funds work like with dice, ie. there is a Prices plan that traders bet against. - PricesFunding oracletxid, priceaveraging, maxleverage, funding, longtoken, shorttoken, N [pubkeys] + PricesFunding oracletxid, margin, priceaveraging, maxleverage, funding, longtoken, shorttoken, N [pubkeys] PricesBet -> oracletxid start with 'L', leverage, funding, direction funds are locked into global CC address @@ -53,58 +53,35 @@ pricewin -> winnings from dealer funds, exposure token back to global address priceloss -> exposuretoken back to global address + exposure address, funds address */ // start of consensus code -int64_t IsPricesvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v) +int64_t PricesOraclePrice(int64_t &rektprice,uint64_t mode,uint256 oracletxid,std::vectorpubkeys,int32_t dir,int64_t amount,int32_t leverage) { - char destaddr[64]; - if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) - { - if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 ) - return(tx.vout[v].nValue); - } - return(0); + int64_t price; + // howto ensure price when block it confirms it not known + // get price from oracle + current chaintip + // normalize leveraged amount + if ( dir > 0 ) + rektprice = price * leverage / (leverage-1); + else rektprice = price * (leverage-1) / leverage; + return(price); } -bool PricesExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee) +CScript EncodePricesFundingOpRet(uint8_t funcid,CPubKey planpk,uint256 oracletxid,uint256 longtoken,uint256 shorttoken,int32_t millimargin,uint64_t mode,int32_t maxleverage,std::vector pubkeys) { - static uint256 zerohash; - CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis; - numvins = tx.vin.size(); - numvouts = tx.vout.size(); - for (i=0; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - //fprintf(stderr,"vini.%d check mempool\n",i); - if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) - return eval->Invalid("cant find vinTx"); - else - { - //fprintf(stderr,"vini.%d check hash and vout\n",i); - if ( hashBlock == zerohash ) - return eval->Invalid("cant Prices from mempool"); - if ( (assetoshis= IsPricesvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 ) - inputs += assetoshis; - } - } - } - for (i=0; iInvalid("mismatched inputs != outputs + txfee"); - } - else return(true); + CScript opret; + fprintf(stderr,"implement EncodePricesFundingOpRet\n"); + return(opret); +} + +uint8_t DecodePricesFundingOpRet(CScript scriptPubKey,CPubKey &planpk,uint256 &oracletxid,uint256 &longtoken,uint256 &shorttoken,int32_t &millimargin,uint64_t &mode,int32_t &maxleverage,std::vector &pubkeys,uint256 &bettoken) +{ + fprintf(stderr,"implement DecodePricesFundingOpRet\n"); + return(0); } bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx) @@ -148,20 +125,20 @@ bool PricesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx // helper functions for rpc calls in rpcwallet.cpp -int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs) +int64_t AddTokensInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,char *destaddr,uint256 tolenid,int64_t total,int32_t maxinputs) { - char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; + int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector origpubkey; CTransaction vintx; int32_t vout,n = 0; std::vector > unspentOutputs; - GetCCaddress(cp,coinaddr,pk); - SetCCunspents(unspentOutputs,coinaddr); + SetCCunspents(unspentOutputs,destaddr); for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) { txid = it->first.txhash; vout = (int32_t)it->first.index; - // no need to prevent dup - if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) + // need to prevent dup + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && vout < tx.vout.size() ) { - if ( (nValue= IsPricesvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(txid,vout) == 0 ) + // need to verify assetid + if ( (nValue= vintx.vout[vout].nValue)) > 10000 && myIsutxo_spentinmempool(txid,vout) == 0 ) { if ( total != 0 && maxinputs != 0 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); @@ -176,49 +153,18 @@ int64_t AddPricesInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub return(totalinputs); } -#ifdef later -UniValue PricesInfo(uint256 pricesid) -{ - UniValue result(UniValue::VOBJ); CPubKey pricepk; uint256 hashBlock,oracletxid; CTransaction vintx; int64_t minbet,maxbet,maxodds; uint64_t funding; char numstr[65]; struct CCcontract_info *cp,C; - if ( GetTransaction(pricesid,vintx,hashBlock,false) == 0 ) - { - fprintf(stderr,"cant find fundingtxid\n"); - ERR_RESULT("cant find fundingtxid"); - return(result); - } - if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,oracletxid,minbet,maxbet,maxodds) == 0 ) - { - fprintf(stderr,"fundingtxid isnt price creation txid\n"); - ERR_RESULT("fundingtxid isnt price creation txid"); - return(result); - } - result.push_back(Pair("result","success")); - result.push_back(Pair("pricesid",uint256_str(str,pricesid))); - result.push_back(Pair("oracletxid",uint256_str(str,oracletxid))); - sprintf(numstr,"%.8f",(double)minbet/COIN); - result.push_back(Pair("minbet",numstr)); - sprintf(numstr,"%.8f",(double)maxbet/COIN); - result.push_back(Pair("maxbet",numstr)); - result.push_back(Pair("maxodds",maxodds)); - cp = CCinit(&C,EVAL_PRICES); - pricepk = GetUnspendable(cp,0); - funding = PricePlanFunds(cp,pricepk,pricesid); - sprintf(numstr,"%.8f",(double)funding/COIN); - result.push_back(Pair("funding",numstr)); - return(result); -} - UniValue PricesList() { - UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; uint256 txid,hashBlock,oracletxid; CTransaction vintx; int64_t minbet,maxbet,maxodds; char str[65]; + UniValue result(UniValue::VARR); std::vector > addressIndex; struct CCcontract_info *cp,C; uint64_t mode; int32_t margin,maxleverage; std::vectorpubkeys; uint256 txid,hashBlock,oracletxid,longtoken,shorttoken,bettoken; CPubKey planpk,pricespk; char str[65]; CTransaction vintx; cp = CCinit(&C,EVAL_PRICES); + pricespk = GetUnspendable(cp,0); SetCCtxids(addressIndex,cp->normaladdr); for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { txid = it->first.txhash; if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { - if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,oracletxid,minbet,maxbet,maxodds) != 0 ) + if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' ) { result.push_back(uint256_str(str,txid)); } @@ -227,54 +173,165 @@ UniValue PricesList() return(result); } -// PricesFunding oracletxid, priceaveraging, maxleverage, funding, longtoken, shorttoken, N [pubkeys] - -std::string PricesCreateFunding(uint64_t txfee,uint256 oracletxid,uint64_t mode,uint256 longtoken,uint256 shorttoken,int32_t maxleverage,int64_t funding,CPubKey pubkeys) +// longtoken satoshis limits long exposure +// shorttoken satoshis limits short exposure +// both must be in the 1of2 CC address with its total supply +// bettoken +std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletxid,uint64_t margin,uint64_t mode,uint256 longtoken,uint256 shorttoken,int32_t maxleverage,int64_t funding,std::vector pubkeys) { - CMutableTransaction mtx; CPubKey mypk,pricespk; struct CCcontract_info *cp,C; + CMutableTransaction mtx; CTransaction oracletx; int64_t fullsupply,inputs,CCchange=0; uint256 hashBlock; char str[65],coinaddr[64],houseaddr[64]; CPubKey mypk,pricespk; int32_t i,N,numvouts; struct CCcontract_info *cp,C,*assetscp,C2; if ( funding < 100*COIN || maxleverage <= 0 || maxleverage > 10000 ) { CCerror = "invalid parameter error"; fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } - cp = CCinit(&C,EVAL_REWARDS); + cp = CCinit(&C,EVAL_PRICES); + assetscp = CCinit(&C2,EVAL_ASSETS); if ( txfee == 0 ) txfee = 10000; mypk = pubkey2pk(Mypubkey()); pricespk = GetUnspendable(cp,0); - // verify long and short assets - if ( AddNormalinputs(mtx,mypk,funding+3*txfee,60) > 0 ) + if ( (N= (int32_t)pubkeys.size()) || N > 15 ) { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,funding,pricepk)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(pricepk)) << OP_CHECKSIG)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesFundingOpRet('F',oracletxid,longtoken,shorttoken,funding,mode,maxleverage,pubkeys))); + fprintf(stderr,"too many pubkeys N.%d\n",N); + return(""); + } + for (i=0; i 0 ) + { + mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); + mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(pricespk)) << OP_CHECKSIG)); + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesFundingOpRet('F',mypk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken))); + } + else + { + CCerror = "cant find enough inputs"; + fprintf(stderr,"%s\n", CCerror.c_str() ); } - CCerror = "cant find enough inputs"; - fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } -std::string PricesAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount) +UniValue PricesInfo(uint256 fundingtxid) { - CMutableTransaction mtx; CScript fundingPubKey,scriptPubKey; CPubKey mypk,pricepk; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds; - if ( amount < 0 ) + UniValue result(UniValue::VOBJ),a(UniValue::VARR); CPubKey pricespk,planpk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction vintx; int64_t balance,supply,exposure; uint64_t funding,mode; int32_t i,margin,maxleverage; char numstr[65],houseaddr[64],exposureaddr[64]; struct CCcontract_info *cp,C,*assetscp,C2; + cp = CCinit(&C,EVAL_PRICES); + assetscp = CCinit(&C2,EVAL_ASSETS); + pricespk = GetUnspendable(cp,0); + if ( GetTransaction(fundingtxid,vintx,hashBlock,false) == 0 ) + { + fprintf(stderr,"cant find fundingtxid\n"); + ERR_RESULT("cant find fundingtxid"); + return(result); + } + if ( vintx.vout.size() > 0 && DecodePricesFundingOpRet(vintx.vout[vintx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' ) + { + result.push_back(Pair("result","success")); + result.push_back(Pair("fundingtxid",uint256_str(str,fundingtxid))); + result.push_back(Pair("bettoken",uint256_str(str,bettoken))); + result.push_back(Pair("oracletxid",uint256_str(str,oracletxid))); + sprintf(numstr,"%.3f",(double)margin/1000); + result.push_back(Pair("profitmargin",numstr)); + result.push_back(Pair("maxleverage",maxleverage)); + result.push_back(Pair("mode",(int64_t)mode)); + for (i=0; i 0 ) + fprintf(stderr,"cant find fundingtxid\n"); + ERR_RESULT("cant find fundingtxid"); + return(result); + } + if ( tx.vout.size() > 0 && DecodePricesFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' && bettoken == refbettoken ) + { + GetCCaddress1of2(houseaddr,assetscp,pricespk,planpk); + if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 ) { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,pricepk)); - mtx.vout.push_back(CTxOut(txfee,fundingPubKey)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesOpRet('E',sbits,fundingtxid,hentropy,zeroid))); + if ( (inputs= AddBetAssetInputs(assetscp,mtx,myaddr,bettoken,amount,60)) >= amount ) + { + mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,amount,pricespk,planpk)); + mtx.vout.push_back(CTxOut(txfee,CScript() << ParseHex(HexStr(planpk)) << OP_CHECKSIG)); + if ( inputs > amount+txfee ) + CCchange = (inputs - amount); + mtx.vout.push_back(MakeCCvout(assetscp->evalcode,CCchange,mypk)); + // add addr2 + return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeAssetOpRet('t',bettoken,zeroid,0,Mypubkey()))); + } + else + { + CCerror = "cant find enough bet inputs"; + fprintf(stderr,"%s\n", CCerror.c_str() ); + } } else { @@ -282,66 +339,106 @@ std::string PricesAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,in fprintf(stderr,"%s\n", CCerror.c_str() ); } } - else - { - CCerror = "only fund creator can add more funds (entropy)"; - fprintf(stderr,"%s\n", CCerror.c_str() ); - } return(""); } -std::string PricesBet(uint64_t txfee,uint256 pricesid,int64_t bet,int32_t odds) +std::string PricesBet(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount,int32_t leverage) { - CMutableTransaction mtx; CScript fundingPubKey; CPubKey mypk,pricepk; int64_t funding,minbet,maxbet,maxodds; struct CCcontract_info *cp,C; - if ( bet < 0 ) + CMutableTransaction mtx; struct CCcontract_info *cp,C,*asssetcp,C2; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,tokenid,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,inputs2,longexposure,netexposure,shortexposure,CCchange = 0,CCchange2 = 0; uint64_t funding,mode; int32_t dir,margin,maxleverage; char houseaddr[64],myaddr[64],exposureaddr[64]; + if ( amount < 0 ) { - CCerror = "bet must be positive"; - fprintf(stderr,"%s\n", CCerror.c_str() ); + amount = -amount; + dir = -1; + } else dir = 1; + cp = CCinit(&C,EVAL_PRICES); + assetscp = CCinit(&C2,EVAL_ASSETS); + if ( txfee == 0 ) + txfee = 10000; + mypk = pubkey2pk(Mypubkey()); + pricespk = GetUnspendable(cp,0); + GetCCaddress(myaddr,assetscp,mypk); + if ( GetTransaction(fundingtxid,tx,hashBlock,false) == 0 ) + { + fprintf(stderr,"cant find fundingtxid\n"); + ERR_RESULT("cant find fundingtxid"); return(""); } - if ( odds < 1 || odds > 9999 ) + if ( tx.vout.size() > 0 && DecodePricesFundingOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,planpk,oracletxid,longtoken,shorttoken,margin,mode,maxleverage,pubkeys,bettoken) == 'F' && bettoken == refbettoken ) { - CCerror = "odds must be between 1 and 9999"; - fprintf(stderr,"%s\n", CCerror.c_str() ); - return(""); - } - if ( (cp= Pricesinit(fundingPubKey,pricesid,&C,txfee,mypk,pricepk,minbet,maxbet,maxodds)) == 0 ) - return(""); - if ( bet < minbet || bet > maxbet || odds > maxodds ) - { - CCerror = strprintf("Price plan %s illegal bet %.8f: minbet %.8f maxbet %.8f or odds %d vs max.%d\n",planstr,(double)bet/COIN,(double)minbet/COIN,(double)maxbet/COIN,(int32_t)odds,(int32_t)maxodds); - fprintf(stderr,"%s\n", CCerror.c_str() ); - return(""); - } - if ( (funding= PricesPlanFunds(cp,pricepk,pricesid)) >= 2*bet*odds+txfee ) - { - if ( myIsutxo_spentinmempool(entropytxid,0) != 0 ) + if ( leverage > maxleverage || leverage < 1 ) { - CCerror = "entropy txid is spent"; - fprintf(stderr,"%s\n", CCerror.c_str() ); + fprintf(stderr,"illegal leverage\n"); return(""); } - if ( AddNormalinputs(mtx,mypk,bet+2*txfee+odds,60) > 0 ) + GetCCaddress1of2(houseaddr,assetscp,pricespk,planpk); + GetCCaddress1of2(exposureaddr,assetscp,pricespk,pricespk); + if ( dir < 0 ) + tokenid = shorttoken; + else tokenid = longtoken; + exposure = leverage * amount; + longexposure = CCtoken_balance(exposureaddr,longtoken); + shortexposure = CCtoken_balance(exposureaddr,shorttoken); + netexposure = (longexposure - shortexposure + exposure*dir); + if ( netexposure < 0 ) + netexposure = -netexposure; + balance = CCtoken_balance(myaddr,bettoken) / COIN; + if ( balance < netexposure*9/10 ) // 10% extra room for dynamically closed bets in wrong direction { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,entropyval,pricepk)); - mtx.vout.push_back(MakeCC1vout(cp->evalcode,bet,pricepk)); - mtx.vout.push_back(CTxOut(txfee+odds,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG)); - return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodePricesOpRet('B',pricesid))); - } else fprintf(stderr,"cant find enough normal inputs for %.8f, plan funding %.8f\n",(double)bet/COIN,(double)funding/COIN); + fprintf(stderr,"balance %lld < 90% netexposure %lld, refuse bet\n",(long long)balance,(long long)netexposure); + return(""); + } + if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 ) + { + if ( (inputs= AddTokensInputs(assetscp,mtx,houseaddr,tokenid,exposure,30)) >= exposure ) + { + if ( (inputs2= AddTokensInputs(assetscp,mtx,myaddr,bettoken,amount,30)) >= amount ) + { + mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,amount,pricespk,planpk)); + mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,exposure,pricespk,pricespk)); + if ( inputs > exposure+txfee ) + CCchange = (inputs - exposure); + if ( inputs2 > amount+txfee ) + CCchange2 = (inputs2 - amount); + mtx.vout.push_back(MakeCC1of2vout(assetscp->evalcode,CCchange,pricespk,planpk)); + mtx.vout.push_back(MakeCCvout(assetscp->evalcode,CCchange2,mypk)); + // add addr2 and addr3 + return(FinalizeCCTx(mask,assetscp,mtx,mypk,txfee,EncodeAssetOpRetExtra('T',tokenid,bettoken,bettxid,dir*leverage))); + } + else + { + fprintf(stderr,"cant find enough bettoken inputs\n"); + return(""); + } + } + else + { + fprintf(stderr,"cant find enough exposure inputs\n"); + return(""); + } + } + else + { + CCerror = "cant find enough inputsB"; + fprintf(stderr,"%s\n", CCerror.c_str() ); + } } - if ( entropyval == 0 && funding != 0 ) - CCerror = "cant find price entropy inputs"; - else CCerror = "cant find price input"; - fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } -std::string PricesBetFinish(int32_t *resultp,uint64_t txfee,uint256 pricesid,uint256 bettxid) +UniValue PricesStatus(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,uint256 bettxid) +{ + UniValue result(UniValue::VOBJ); + // get height of bettxid + // get price and rekt + // get current height and price + // what about if rekt in the past? + return(result); +} + +std::string PricesFinish(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,uint256 bettxid) { - *resultp = -1; - CCerror = "couldnt find bettx or entropytx"; - fprintf(stderr,"%s\n", CCerror.c_str() ); return(""); } -#endif + + diff --git a/src/komodo_utils.h b/src/komodo_utils.h index d98418c82..2441da83d 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1628,6 +1628,11 @@ void komodo_args(char *argv0) { int32_t komodo_baseid(char *origbase); extern int COINBASE_MATURITY; + if ( strcmp(ASSETCHAINS_SYMBOL,"KMD") == 0 ) + { + fprintf(stderr,"cant have assetchain named KMD\n"); + exit(0); + } if ( (port= komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL)) != 0 ) ASSETCHAINS_RPCPORT = port; else komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT + 1); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index d268ed7fa..77e53f7a1 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -398,7 +398,14 @@ static const CRPCCommand vRPCCommands[] = { "oracles", "oraclessamples", &oraclessamples, true }, /* Prices */ - { "prices", "pricesaddress", &pricesaddress, true }, + { "prices", "pricesaddress", &pricesaddress, true }, + { "prices", "priceslist", &priceslist, true }, + { "prices", "pricesinfo", &pricesinfo, true }, + { "prices", "pricescreate", &pricescreate, true }, + { "prices", "pricesaddfunding", &pricesaddfunding, true }, + { "prices", "pricesbet", &pricesbet, true }, + { "prices", "pricesstatus", &pricesstatus, true }, + { "prices", "pricesfinish", &pricesfinish, true }, /* Pegs */ { "pegs", "pegsaddress", &pegsaddress, true }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 1ebff82ef..e0c87756f 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -232,6 +232,13 @@ extern UniValue oraclessubscribe(const UniValue& params, bool fHelp); extern UniValue oraclesdata(const UniValue& params, bool fHelp); extern UniValue oraclessamples(const UniValue& params, bool fHelp); extern UniValue pricesaddress(const UniValue& params, bool fHelp); +extern UniValue priceslist(const UniValue& params, bool fHelp); +extern UniValue pricesinfo(const UniValue& params, bool fHelp); +extern UniValue pricescreate(const UniValue& params, bool fHelp); +extern UniValue pricesaddfunding(const UniValue& params, bool fHelp); +extern UniValue pricesbet(const UniValue& params, bool fHelp); +extern UniValue pricesstatus(const UniValue& params, bool fHelp); +extern UniValue pricesfinish(const UniValue& params, bool fHelp); extern UniValue pegsaddress(const UniValue& params, bool fHelp); extern UniValue triggersaddress(const UniValue& params, bool fHelp); extern UniValue paymentsaddress(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 44965db73..397c4f3c3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4896,7 +4896,7 @@ UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector destpubkey; CPubKey pk,pk2; char destaddr[64]; + UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C; std::vector destpubkey; CPubKey pk,pk2; char destaddr[64]; cp = CCinit(&C,EVAL_CHANNELS); if ( fHelp || params.size() != 1 ) throw runtime_error("channelsaddress destpubkey\n"); @@ -4927,23 +4927,25 @@ UniValue oraclesaddress(const UniValue& params, bool fHelp) UniValue pricesaddress(const UniValue& params, bool fHelp) { - struct CCcontract_info *cp,C; std::vector pubkey; + UniValue result(UniValue::VOBJ); struct CCcontract_info *cp,C,*assetscp,C2; std::vector pubkey; CPubKey mypk,pricespk; char myaddr[64],houseaddr[64],exposureaddr[64]; cp = CCinit(&C,EVAL_PRICES); + assetscp = CCinit(&C2,EVAL_PRICES); if ( fHelp || params.size() > 1 ) throw runtime_error("pricesaddress [pubkey]\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); if ( params.size() == 1 ) - { pubkey = ParseHex(params[0].get_str().c_str()); - char destaddr[64]; - GetCCaddress1of2(cp,destaddr,pubkey2pk(pubkey),pubkey2pk(pubkey)); - fprintf(stderr,"1of2 CC %s\n",destaddr); - cp->evalcode = EVAL_ASSETS; - GetCCaddress1of2(cp,destaddr,pubkey2pk(pubkey),pubkey2pk(pubkey)); - fprintf(stderr,"1of2 assets CC %s\n",destaddr); - } - return(CCaddress(cp,(char *)"Prices",pubkey)); + result = CCaddress(cp,(char *)"Prices",pubkey); + mypk = pubkey2pk(Mypubkey()); + pricespk = GetUnspendable(cp,0); + GetCCaddress(myaddr,assetscp,mypk); + GetCCaddress1of2(houseaddr,assetscp,pricespk,planpk); + GetCCaddress1of2(exposureaddr,assetscp,pricespk,pricespk); + result.push_back(Pair("myaddr",myaddr)); // for holding my asssets + result.push_back(Pair("houseaddr",houseaddr)); // globally accessible house assets + result.push_back(Pair("exposureaddr",exposureaddr)); // tracking of exposure + return(result); } UniValue pegsaddress(const UniValue& params, bool fHelp) @@ -5121,7 +5123,8 @@ UniValue channelsopen(const UniValue& params, bool fHelp) throw runtime_error("channelsopen destpubkey numpayments payment\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - LOCK(cs_main); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); destpub = ParseHex(params[0].get_str().c_str()); numpayments = atoi(params[1].get_str().c_str()); payment = atol(params[2].get_str().c_str()); @@ -5142,7 +5145,8 @@ UniValue channelsstop(const UniValue& params, bool fHelp) throw runtime_error("channelsstop destpubkey origtxid\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - LOCK(cs_main); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); destpub = ParseHex(params[0].get_str().c_str()); origtxid = Parseuint256((char *)params[1].get_str().c_str()); hex = ChannelStop(0,pubkey2pk(destpub),origtxid); @@ -5162,7 +5166,8 @@ UniValue channelspayment(const UniValue& params, bool fHelp) throw runtime_error("channelspayment prevtxid origtxid n amount\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - LOCK(cs_main); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); prevtxid = Parseuint256((char *)params[0].get_str().c_str()); origtxid = Parseuint256((char *)params[1].get_str().c_str()); n = atoi((char *)params[2].get_str().c_str()); @@ -5184,7 +5189,8 @@ UniValue channelscollect(const UniValue& params, bool fHelp) throw runtime_error("channelscollect paytxid origtxid n amount\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - LOCK(cs_main); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); paytxid = Parseuint256((char *)params[0].get_str().c_str()); origtxid = Parseuint256((char *)params[1].get_str().c_str()); n = atoi((char *)params[2].get_str().c_str()); @@ -5206,7 +5212,8 @@ UniValue channelsrefund(const UniValue& params, bool fHelp) throw runtime_error("channelsrefund stoptxid origtxid\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - LOCK(cs_main); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); stoptxid = Parseuint256((char *)params[0].get_str().c_str()); origtxid = Parseuint256((char *)params[1].get_str().c_str()); hex = ChannelRefund(0,stoptxid,origtxid); @@ -5428,6 +5435,8 @@ UniValue gatewaysbind(const UniValue& params, bool fHelp) throw runtime_error("gatewaysbind tokenid oracletxid coin tokensupply M N pubkey(s)\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); tokenid = Parseuint256((char *)params[0].get_str().c_str()); oracletxid = Parseuint256((char *)params[1].get_str().c_str()); coin = params[2].get_str(); @@ -5459,6 +5468,8 @@ UniValue gatewaysdeposit(const UniValue& params, bool fHelp) throw runtime_error("gatewaysdeposit bindtxid height coin cointxid claimvout deposithex proof destpub amount\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); bindtxid = Parseuint256((char *)params[0].get_str().c_str()); height = atoi((char *)params[1].get_str().c_str()); coin = params[2].get_str(); @@ -5486,6 +5497,8 @@ UniValue gatewaysclaim(const UniValue& params, bool fHelp) throw runtime_error("gatewaysclaim bindtxid coin deposittxid destpub amount\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); bindtxid = Parseuint256((char *)params[0].get_str().c_str()); coin = params[1].get_str(); deposittxid = Parseuint256((char *)params[2].get_str().c_str()); @@ -5507,6 +5520,8 @@ UniValue gatewayswithdraw(const UniValue& params, bool fHelp) throw runtime_error("gatewayswithdraw bindtxid coin withdrawpub amount\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); bindtxid = Parseuint256((char *)params[0].get_str().c_str()); coin = params[1].get_str(); withdrawpub = ParseHex(params[2].get_str()); @@ -5527,6 +5542,8 @@ UniValue gatewaysmarkdone(const UniValue& params, bool fHelp) throw runtime_error("gatewaysmarkdone withdrawtxid coin cointxid\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); withdrawtxid = Parseuint256((char *)params[0].get_str().c_str()); coin = params[1].get_str(); cointxid = Parseuint256((char *)params[2].get_str().c_str()); @@ -5558,6 +5575,8 @@ UniValue gatewaysmultisig(const UniValue& params, bool fHelp) throw runtime_error("gatewaysmultisig bindtxid coin withtxid txidaddr\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); bindtxid = Parseuint256((char *)params[0].get_str().c_str()); coin = params[1].get_str(); withtxid = Parseuint256((char *)params[2].get_str().c_str()); @@ -5598,6 +5617,8 @@ UniValue oraclesregister(const UniValue& params, bool fHelp) throw runtime_error("oraclesregister oracletxid datafee\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); txid = Parseuint256((char *)params[0].get_str().c_str()); datafee = atol((char *)params[1].get_str().c_str()); hex = OracleRegister(0,txid,datafee); @@ -5616,6 +5637,8 @@ UniValue oraclessubscribe(const UniValue& params, bool fHelp) throw runtime_error("oraclessubscribe oracletxid publisher amount\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); txid = Parseuint256((char *)params[0].get_str().c_str()); pubkey = ParseHex(params[1].get_str().c_str()); amount = atof((char *)params[2].get_str().c_str()) * COIN; @@ -5648,6 +5671,8 @@ UniValue oraclesdata(const UniValue& params, bool fHelp) throw runtime_error("oraclesdata oracletxid hexstr\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); txid = Parseuint256((char *)params[0].get_str().c_str()); data = ParseHex(params[1].get_str().c_str()); hex = OracleData(0,txid,data); @@ -5784,6 +5809,156 @@ UniValue faucetget(const UniValue& params, bool fHelp) return(result); } +UniValue priceslist(const UniValue& params, bool fHelp) +{ + if ( fHelp || params.size() > 0 ) + throw runtime_error("priceslist\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + return(PricesList()); +} + +UniValue pricesinfo(const UniValue& params, bool fHelp) +{ + uint256 fundingtxid; + if ( fHelp || params.size() != 1 ) + throw runtime_error("pricesinfo fundingtxid\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); + return(PricesInfo(fundingtxid)); +} + +UniValue pricescreate(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); uint64_t margin,mode; int32_t i,n,margin,maxleverage; std::string hex; uint256 oracletxid,longtoken,shorttoken,bettoken; std::vector pubkeys; std::vectorpubkey; + if ( fHelp || params.size() < 8 ) + throw runtime_error("pricescreate bettoken oracletxid margin mode longtoken shorttoken maxleverage funding N [pubkeys]\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); + bettoken = Parseuint256((char *)params[0].get_str().c_str()); + oracletxid = Parseuint256((char *)params[1].get_str().c_str()); + margin = atof(params[2].get_str().c_str()) * 1000; + mode = atol(params[3].get_str().c_str()); + longtoken = Parseuint256((char *)params[4].get_str().c_str()); + shorttoken = Parseuint256((char *)params[5].get_str().c_str()); + maxleverage = atol(params[6].get_str().c_str()); + funding = atof(params[7].get_str().c_str()) * COIN; + n = atoi(params[8].get_str().c_str()); + if ( n > 0 ) + { + for (i=0; i 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } + else + { + ERR_RESULT("couldnt create prices funding transaction"); + } + return(result); +} + +UniValue pricesaddfunding(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid,bettoken; int64_t amount; + if ( fHelp || params.size() != 3 ) + throw runtime_error("pricesaddfunding fundingtxid bettoken amount\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); + fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); + bettoken = Parseuint256((char *)params[1].get_str().c_str()); + amount = atof(params[2].get_str().c_str()) * COIN; + hex = PricesAddFunding(0,bettoken,fundingtxid,amount); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } + else + { + ERR_RESULT("couldnt create pricesaddfunding transaction"); + } + return(result); +} + +UniValue pricesbet(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); std::string hex; uint256 fundingtxid,bettoken; int64_t amount; int32_t leverage; + if ( fHelp || params.size() != 4 ) + throw runtime_error("pricesbet fundingtxid bettoken amount leverage\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); + fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); + bettoken = Parseuint256((char *)params[1].get_str().c_str()); + amount = atof(params[2].get_str().c_str()) * COIN; + leverage = atoi(params[3].get_str().c_str()); + hex = PricesBet(0,bettoken,fundingtxid,amount,leverage); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } + else + { + ERR_RESULT("couldnt create pricesbet transaction"); + } + return(result); +} + +UniValue pricesstatus(const UniValue& params, bool fHelp) +{ + uint256 fundingtxid,bettxid,bettoken; + if ( fHelp || params.size() != 3 ) + throw runtime_error("pricesstatus fundingtxid bettoken bettxid\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); + bettoken = Parseuint256((char *)params[1].get_str().c_str()); + bettxid = Parseuint256((char *)params[2].get_str().c_str()); + return(PricesStatus(0,bettoken,fundingtxid,bettxid)); +} + +UniValue pricesfinish(const UniValue& params, bool fHelp) +{ + UniValue result(UniValue::VOBJ); uint256 fundingtxid,bettxid,bettoken; std::string hex; + if ( fHelp || params.size() != 3 ) + throw runtime_error("pricesfinish fundingtxid bettoken bettxid\n"); + if ( ensure_CCrequirements() < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); + fundingtxid = Parseuint256((char *)params[0].get_str().c_str()); + bettoken = Parseuint256((char *)params[1].get_str().c_str()); + bettxid = Parseuint256((char *)params[2].get_str().c_str()); + hex = PricesFinish(0,bettoken,fundingtxid,bettxid); + if ( hex.size() > 0 ) + { + result.push_back(Pair("result", "success")); + result.push_back(Pair("hex", hex)); + } + else + { + ERR_RESULT("couldnt create pricesfinish transaction"); + } + return(result); +} + UniValue dicefund(const UniValue& params, bool fHelp) { UniValue result(UniValue::VOBJ); int64_t funds,minbet,maxbet,maxodds,timeoutblocks; std::string hex; char *name; @@ -5955,7 +6130,6 @@ UniValue dicestatus(const UniValue& params, bool fHelp) UniValue dicelist(const UniValue& params, bool fHelp) { - uint256 tokenid; if ( fHelp || params.size() > 0 ) throw runtime_error("dicelist\n"); if ( ensure_CCrequirements() < 0 )